# 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
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
}
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;
}
panic("Unimplemented shutdown status: %02x\n", status);
}
+#if MODE16==0
void VISIBLE32
s3_resume()
{
}
call16big(&br);
}
+#endif
// Ughh - some older gcc compilers have a bug which causes VISIBLE32
// functions to not be exported as global variables.
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__)
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)
: "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 *
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);
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);
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);
# 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.