[m-dev.] partial fix for gcc 4.{123}.
Paul Bone
pbone at csse.unimelb.edu.au
Tue Oct 6 14:55:36 AEDT 2009
Here's the patch for the GCC problems.
I havn't been able to test it on gcc 4.4, I don't have that on my system (yet).
It will only work for x86_64 at the moment.
It works for the trivial tests I've tried, but won't bootstrap.
Thanks.
Index: runtime/mercury_goto.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_goto.h,v
retrieving revision 1.50
diff -u -p -b -r1.50 mercury_goto.h
--- runtime/mercury_goto.h 12 Jun 2007 06:06:33 -0000 1.50
+++ runtime/mercury_goto.h 30 Sep 2009 04:10:29 -0000
@@ -321,6 +321,7 @@
** instruction on entry to the procedure to set up the right gp value.
*/
#define MR_ASM_JUMP(address) \
+ MR_PRETEND_FAKE_REGISTERS_INPUT; \
__asm__("bis %0, %0, $27\n\t" \
: : "r"(address) : "$27"); \
goto *(address)
@@ -371,16 +372,19 @@
*/
#if defined(__i386__)
#define MR_ASM_JUMP(label) \
+ MR_PRETEND_FAKE_REGISTERS_INPUT; \
{ register int stack_pointer __asm__("esp"); \
__asm__("" : : "g"(stack_pointer)); } \
goto *(label)
#elif defined(__x86_64__)
#define MR_ASM_JUMP(label) \
+ MR_PRETEND_FAKE_REGISTERS_INPUT; \
{ register int stack_pointer __asm__("rsp"); \
__asm__("" : : "g"(stack_pointer)); } \
goto *(label)
#elif defined(__mc68000__)
#define MR_ASM_JUMP(label) \
+ MR_PRETEND_FAKE_REGISTERS_INPUT; \
{ register int stack_pointer __asm__("sp"); \
__asm__("" : : "g"(stack_pointer)); } \
goto *(label)
@@ -670,7 +674,9 @@
** MR_ASM_ENTRY, MR_ASM_STATIC_ENTRY, or MR_ASM_LOCAL_ENTRY.
*/
#ifndef MR_ASM_JUMP
-#define MR_ASM_JUMP(address) goto *(address)
+#define MR_ASM_JUMP(address) \
+ MR_PRETEND_FAKE_REGISTERS_INPUT; \
+ goto *(address)
#endif
/*---------------------------------------------------------------------------*/
@@ -778,7 +784,7 @@
** with versions of gcc before version 4.
*/
#define MR_PRETEND_REGS_ARE_USED \
- __asm__ __volatile("":::"memory")
+ __asm__ __volatile__("": : : MR_callee_saved_register_clobbers, "memory")
/*
Explanation:
__asm__
@@ -794,6 +800,42 @@
)
*/
+ #if MR_NUM_REAL_REGS > 0
+ #define MR_PRETEND_FAKE_REGISTERS_OUTPUT \
+ __asm__ __volatile__("": MR_fake_register_outputs :)
+ #else
+ #define MR_PRETEND_FAKE_REGSITERS_OUTPUT
+ #endif
+ /*
+ Explanation:
+ __asm__
+ __volatile__ Don't optimize this asm away.
+ (
+ "" Empty assembler code.
+ : MR_fake_register_outputs A list of real Mercury abstract machine
+ register outputs.
+ : No inputs.
+ )
+ */
+
+ #if MR_NUM_REAL_REGS > 0
+ #define MR_PRETEND_FAKE_REGISTERS_INPUT \
+ __asm__ __volatile__("": : MR_fake_register_inputs)
+ #else
+ #define MR_PRETEND_FAKE_REGISTERS_INPUT
+ #endif
+ /*
+ Explanation:
+ __asm__
+ __volatile__ Don't optimize this asm away.
+ (
+ "" Empty assembler code.
+ :
+ : MR_fake_register_inputs A list of real Mercury abstract machine
+ register inputs.
+ )
+ */
+
/*
** Since we're jumping into and out of the middle of functions,
** we need to make sure that gcc thinks that (1) the function's address
@@ -851,18 +893,20 @@
#define MR_define_extern_entry(label) MR_declare_entry(label)
#define MR_define_entry(label) \
MR_ASM_ENTRY(label) \
+ MR_PRETEND_FAKE_REGISTERS_OUTPUT; \
+ MR_PRETEND_REGS_ARE_USED; \
} \
label: \
MR_PRETEND_ADDRESS_IS_USED(&&MR_entry(label)); \
- { \
- MR_PRETEND_REGS_ARE_USED;
+ {
#define MR_define_static(label) \
MR_ASM_STATIC_ENTRY(label) \
+ MR_PRETEND_FAKE_REGISTERS_OUTPUT; \
+ MR_PRETEND_REGS_ARE_USED; \
} \
label: \
MR_PRETEND_ADDRESS_IS_USED(&&MR_entry(label)); \
- { \
- MR_PRETEND_REGS_ARE_USED;
+ {
/*
** The MR_PRETEND_ADDRESS_IS_USED macro is necessary to
** prevent an over-zealous gcc from optimizing away `label'
@@ -902,11 +946,13 @@
#define MR_define_entry(label) \
} \
MR_entry(label): \
+ MR_PRETEND_FAKE_REGISTERS_OUTPUT; \
label: \
{
#define MR_define_static(label) \
} \
MR_entry(label): \
+ MR_PRETEND_FAKE_REGISTERS_OUTPUT; \
label: \
{
#define MR_init_entry(label) \
@@ -964,6 +1010,7 @@
#define MR_GOTO_LOCAL(label) MR_GOTO_LABEL(label)
#define MR_GOTO_LABEL(label) do { \
MR_debuggoto(MR_LABEL(label)); \
+ MR_PRETEND_FAKE_REGISTERS_INPUT; \
goto label; \
} while(0)
Index: runtime/machdeps/x86_64_regs.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/machdeps/x86_64_regs.h,v
retrieving revision 1.2
diff -u -p -b -r1.2 x86_64_regs.h
--- runtime/machdeps/x86_64_regs.h 2 Aug 2006 06:48:56 -0000 1.2
+++ runtime/machdeps/x86_64_regs.h 26 Sep 2009 09:37:27 -0000
@@ -42,6 +42,24 @@ register MR_Word MR_mr3 __asm__("r15");
#define MR_real_reg_number_mr2 r14
#define MR_real_reg_number_mr3 r15
+/*
+** A list of outputs suitable for GCC's inline assembler syntax. This is used
+** when we want to ensure that GCC doesn't schedule instructions that read
+** these registers too early.
+*/
+#define MR_fake_register_outputs \
+ "=g"(MR_mr0), "=g"(MR_mr1), "=g"(MR_mr2), "=g"(MR_mr3)
+#define MR_fake_register_inputs \
+ "g"(MR_mr0), "g"(MR_mr1), "g"(MR_mr2), "g"(MR_mr3)
+
+/*
+** We also mark registers not mapped to abstract machine registers as
+** clobbered, this prevents GCC 4.{234} from scheduling moves into these
+** registers in the prelude of the function.
+*/
+#define MR_callee_saved_register_clobbers \
+ "rax", "rbx", "rcx", "rdx", "rsi", "rdi", "r8", "r9", "r10", "r11"
+
#define MR_save_regs_to_mem(save_area) ( \
save_area[0] = MR_mr0, \
save_area[1] = MR_mr1, \
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 489 bytes
Desc: Digital signature
URL: <http://lists.mercurylang.org/archives/developers/attachments/20091006/e89161b6/attachment.sig>
More information about the developers
mailing list