aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2009-06-10 22:44:06 -0400
committerKevin O'Connor <kevin@koconnor.net>2009-06-10 22:44:06 -0400
commit942d495dcd12801187076d12e5f7409e8a8aa661 (patch)
treec3853d4ab5409811752c1af6b0292d4e78165f9b
parentc0693941fdb5118164a8161316fdf8e9ebb499d2 (diff)
downloadseabios-942d495dcd12801187076d12e5f7409e8a8aa661.tar.gz
Add support for gcc v3.x compilers.
Suppress __attribute__((externally_visible)) when no -fwhole-program Add switch hack for compilers without -fno-jump-tables Define memcpy() function (for compilers without -minline-all-stringops). Define call16_simpint as a macro (a param needs to be inlined). Make sure s3_resume is only defined in 32bit mode.
-rw-r--r--Makefile6
-rw-r--r--src/optionroms.c2
-rw-r--r--src/resume.c2
-rw-r--r--src/types.h10
-rw-r--r--src/util.c39
-rw-r--r--src/util.h21
-rwxr-xr-xtools/test-gcc.sh7
7 files changed, 53 insertions, 34 deletions
diff --git a/Makefile b/Makefile
index ff594e7c..8cb66259 100644
--- a/Makefile
+++ b/Makefile
@@ -22,7 +22,8 @@ cc-option = $(shell if test -z "`$(1) $(2) -S -o /dev/null -xc \
# Default compiler flags
COMMONCFLAGS = -Wall -Os -MD -m32 -march=i386 -mregparm=3 \
-mpreferred-stack-boundary=2 -mrtd -freg-struct-return \
- -ffreestanding -fwhole-program -fomit-frame-pointer \
+ $(call cc-option,$(CC),-fwhole-program -DWHOLE_PROGRAM,) \
+ -ffreestanding -fomit-frame-pointer \
-fno-delete-null-pointer-checks -Wno-strict-aliasing \
-ffunction-sections -fdata-sections \
-minline-all-stringops
@@ -31,7 +32,8 @@ COMMONCFLAGS += $(call cc-option,$(CC),-fno-stack-protector,)
COMMONCFLAGS += $(call cc-option,$(CC),-fno-stack-protector-all,)
override CFLAGS = $(COMMONCFLAGS) -g -DMODE16=0
-CFLAGS16INC = $(COMMONCFLAGS) -DMODE16=1 -fno-jump-tables -fno-defer-pop \
+CFLAGS16INC = $(COMMONCFLAGS) -DMODE16=1 -fno-defer-pop \
+ $(call cc-option,$(CC),-fno-jump-tables,-DMANUAL_NO_JUMP_TABLE) \
$(call cc-option,$(CC),-fno-tree-switch-conversion,) \
$(call cc-option,$(CC),--param large-stack-frame=4,)
CFLAGS16 = $(CFLAGS16INC) -g
diff --git a/src/optionroms.c b/src/optionroms.c
index 366e1077..2856217a 100644
--- a/src/optionroms.c
+++ b/src/optionroms.c
@@ -171,7 +171,7 @@ copy_rom(struct rom_header *rom)
}
dprintf(4, "Copying option rom (size %d) from %p to %x\n"
, romsize, rom, next_rom);
- memcpy4((void*)next_rom, rom, romsize);
+ memcpy((void*)next_rom, rom, romsize);
return (struct rom_header *)next_rom;
}
diff --git a/src/resume.c b/src/resume.c
index ad868f62..6db6b714 100644
--- a/src/resume.c
+++ b/src/resume.c
@@ -94,6 +94,7 @@ handle_resume(u8 status)
panic("Unimplemented shutdown status: %02x\n", status);
}
+#if MODE16==0
void VISIBLE32
s3_resume()
{
@@ -123,6 +124,7 @@ s3_resume()
}
call16big(&br);
}
+#endif
// Ughh - some older gcc compilers have a bug which causes VISIBLE32
// functions to not be exported as global variables.
diff --git a/src/types.h b/src/types.h
index a004474e..aa9e12d0 100644
--- a/src/types.h
+++ b/src/types.h
@@ -21,7 +21,15 @@ union u64_u32_u {
u64 val;
};
-#define __VISIBLE __attribute__((externally_visible))
+#ifdef MANUAL_NO_JUMP_TABLE
+# define default case 775324556: asm(""); default
+#endif
+
+#ifdef WHOLE_PROGRAM
+# define __VISIBLE __attribute__((externally_visible))
+#else
+# define __VISIBLE
+#endif
#define UNIQSEC __FILE__ "." __stringify(__LINE__)
diff --git a/src/util.c b/src/util.c
index 1a67e370..a44b35d4 100644
--- a/src/util.c
+++ b/src/util.c
@@ -52,25 +52,6 @@ __call16_int(struct bregs *callregs, u16 offset)
call16(callregs);
}
-inline void
-call16_simpint(int nr, u32 *eax, u32 *flags)
-{
- extern void __force_link_error__call16_simpint_only_in_16bit_mode();
- if (!MODE16)
- __force_link_error__call16_simpint_only_in_16bit_mode();
-
- asm volatile(
- "stc\n"
- "int %2\n"
- "pushfl\n"
- "popl %1\n"
- "cli\n"
- "cld"
- : "+a"(*eax), "=r"(*flags)
- : "i"(nr)
- : "cc", "memory");
-}
-
// Switch to the extra stack in ebda and call a function.
inline u32
stack_hop(u32 eax, u32 edx, u32 ecx, void *func)
@@ -204,15 +185,27 @@ memcpy_far(u16 d_seg, void *d_far, u16 s_seg, const void *s_far, size_t len)
: "cc", "memory");
}
-// Memcpy that uses 4-byte accesses
-void
-memcpy4(void *d1, const void *s1, size_t len)
+void *
+#undef memcpy
+memcpy(void *d1, const void *s1, size_t len)
+#define memcpy __builtin_memcpy
{
+ void *d = d1;
+ if (((u32)d1 | (u32)s1 | len) & 3) {
+ // non-aligned memcpy
+ asm volatile(
+ "rep movsb (%%esi),%%es:(%%edi)"
+ : "+c"(len), "+S"(s1), "+D"(d)
+ : : "cc", "memory");
+ return d1;
+ }
+ // Common case - use 4-byte copy
len /= 4;
asm volatile(
"rep movsl (%%esi),%%es:(%%edi)"
- : "+c"(len), "+S"(s1), "+D"(d1)
+ : "+c"(len), "+S"(s1), "+D"(d)
: : "cc", "memory");
+ return d1;
}
void *
diff --git a/src/util.h b/src/util.h
index 1d33c947..23750cd4 100644
--- a/src/util.h
+++ b/src/util.h
@@ -65,6 +65,23 @@ static inline u64 rdtscll(void)
return val;
}
+#define call16_simpint(nr, peax, pflags) do { \
+ extern void __force_link_error__call16_simpint_only_in_16bit_mode(); \
+ if (!MODE16) \
+ __force_link_error__call16_simpint_only_in_16bit_mode(); \
+ \
+ asm volatile( \
+ "stc\n" \
+ "int %2\n" \
+ "pushfl\n" \
+ "popl %1\n" \
+ "cli\n" \
+ "cld" \
+ : "+a"(*peax), "=r"(*pflags) \
+ : "i"(nr) \
+ : "cc", "memory"); \
+ } while (0)
+
// util.c
inline u32 stack_hop(u32 eax, u32 edx, u32 ecx, void *func);
u8 checksum_far(u16 buf_seg, void *buf_far, u32 len);
@@ -75,8 +92,7 @@ int strcmp(const char *s1, const char *s2);
inline void memset_far(u16 d_seg, void *d_far, u8 c, size_t len);
inline void memset16_far(u16 d_seg, void *d_far, u16 c, size_t len);
void *memset(void *s, int c, size_t n);
-void memcpy4(void *d1, const void *s1, size_t len);
-#define memcpy(d1, s1, len) __builtin_memcpy((d1), (s1), (len))
+#define memcpy __builtin_memcpy
inline void memcpy_far(u16 d_seg, void *d_far
, u16 s_seg, const void *s_far, size_t len);
void *memmove(void *d, const void *s, size_t len);
@@ -89,7 +105,6 @@ inline void __call16_int(struct bregs *callregs, u16 offset);
extern void irq_trampoline_ ##nr (); \
__call16_int((callregs), (u32)&irq_trampoline_ ##nr ); \
} while (0)
-inline void call16_simpint(int nr, u32 *eax, u32 *flags);
void usleep(u32 usec);
int get_keystroke(int msec);
diff --git a/tools/test-gcc.sh b/tools/test-gcc.sh
index c354ec3d..55f359fa 100755
--- a/tools/test-gcc.sh
+++ b/tools/test-gcc.sh
@@ -11,10 +11,9 @@ TMPFILE3o=out/tmp_testcompile3.o
# Test for "-fwhole-program"
$CC -fwhole-program -S -o /dev/null -xc /dev/null > /dev/null 2>&1
if [ $? -ne 0 ]; then
- echo "This version of gcc does not support -fwhole-program." > /dev/fd/2
- echo "Please upgrade to gcc v4.1 or later" > /dev/fd/2
- echo -1
- exit 1
+ echo " Working around no -fwhole-program" > /dev/fd/2
+ echo 1
+ exit 0
fi
# Test if "visible" variables are marked global.