summaryrefslogtreecommitdiff
path: root/gnu/gcc
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2016-12-30 20:18:30 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2016-12-30 20:18:30 +0000
commitbf462ad9e607db4fe8fe63f425fd363ebc740b56 (patch)
tree1d0ef410285dfa1a0873c19ab77560d5f94d690f /gnu/gcc
parent334371d02881053dd91927691c663dc4c19fe0fc (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.c21
-rw-r--r--gnu/gcc/gcc/config/m88k/m88k.h10
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 ***/