diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2016-12-30 20:18:30 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2016-12-30 20:18:30 +0000 |
commit | bf462ad9e607db4fe8fe63f425fd363ebc740b56 (patch) | |
tree | 1d0ef410285dfa1a0873c19ab77560d5f94d690f /gnu/gcc | |
parent | 334371d02881053dd91927691c663dc4c19fe0fc (diff) |
Prevent scheduling from interfering with the epilogue instructions, as soon
as any of the stack or frame pointers are modified.
Allow narrower-than-register types to be kept in registers in wider modes,
as was the case with gcc 3.
This now seems to produce reliable code with -O1. -O2 is not safe yet.
Diffstat (limited to 'gnu/gcc')
-rw-r--r-- | gnu/gcc/gcc/config/m88k/m88k.c | 21 | ||||
-rw-r--r-- | gnu/gcc/gcc/config/m88k/m88k.h | 10 |
2 files changed, 29 insertions, 2 deletions
diff --git a/gnu/gcc/gcc/config/m88k/m88k.c b/gnu/gcc/gcc/config/m88k/m88k.c index fa9925c9083..a140773a843 100644 --- a/gnu/gcc/gcc/config/m88k/m88k.c +++ b/gnu/gcc/gcc/config/m88k/m88k.c @@ -115,6 +115,12 @@ static void m88k_output_file_start (void); #undef TARGET_PROMOTE_PROTOTYPES #define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true +#undef TARGET_PROMOTE_FUNCTION_ARGS +#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true + +#undef TARGET_PROMOTE_FUNCTION_RETURN +#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true + #undef TARGET_SETUP_INCOMING_VARARGS #define TARGET_SETUP_INCOMING_VARARGS m88k_setup_incoming_varargs @@ -1394,14 +1400,25 @@ void m88k_expand_epilogue (void) { if (frame_pointer_needed) - emit_add (stack_pointer_rtx, frame_pointer_rtx, -m88k_fp_offset); + { + emit_insn (gen_blockage ()); + emit_add (stack_pointer_rtx, frame_pointer_rtx, -m88k_fp_offset); + } if (nregs || nxregs) preserve_registers (m88k_fp_offset + 4, 0); if (m88k_stack_size) - emit_add (stack_pointer_rtx, stack_pointer_rtx, m88k_stack_size); + { + emit_insn (gen_blockage ()); + emit_add (stack_pointer_rtx, stack_pointer_rtx, m88k_stack_size); + } + /* This should not be necessary, but when there are several epilogues + in the function after the optimizer shuffles things around, the + extra epilogues will lack this extremely important instruction if + it is not explicitly generated. */ + emit_insn (gen_blockage ()); emit_insn (gen_indirect_jump (INCOMING_RETURN_ADDR_RTX)); } diff --git a/gnu/gcc/gcc/config/m88k/m88k.h b/gnu/gcc/gcc/config/m88k/m88k.h index 82f232a8688..da96462c89b 100644 --- a/gnu/gcc/gcc/config/m88k/m88k.h +++ b/gnu/gcc/gcc/config/m88k/m88k.h @@ -209,6 +209,16 @@ extern enum processor_type m88k_cpu; /* A bit-field declared as `int' forces `int' alignment for the struct. */ #define PCC_BITFIELD_TYPE_MATTERS 1 + +/* Define this macro if it is advisable to hold scalars in registers + in a wider mode than that declared by the program. In such cases, + the value is constrained to be within the bounds of the declared + type, but kept valid in the wider mode. The signedness of the + extension may differ from that of the type. */ +#define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE) \ + if (GET_MODE_CLASS (MODE) == MODE_INT \ + && GET_MODE_SIZE (MODE) < UNITS_PER_WORD) \ + (MODE) = SImode; /*** Register Usage ***/ |