From: Kevin O'Connor Date: Thu, 11 Jun 2009 02:44:06 +0000 (-0400) Subject: Add support for gcc v3.x compilers. X-Git-Url: http://wien.tomnetworks.com/gitweb/?p=seabios.git;a=commitdiff_plain;h=942d495dcd12801187076d12e5f7409e8a8aa661 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. --- diff --git a/Makefile b/Makefile index ff594e7..8cb6625 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 366e107..2856217 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 ad868f6..6db6b71 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 a004474..aa9e12d 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 1a67e37..a44b35d 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 1d33c94..23750cd 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 c354ec3..55f359f 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.