1 From a42f1f7028fa80961114dab58ec9e028fcf9f9bd Mon Sep 17 00:00:00 2001
2 From: Richard Lowe <richlowe@richlowe.net>
3 Date: Fri, 3 May 2019 00:56:45 +0000
4 Subject: i386: don't assert the FP is valid during epilogue
7 I did this, I think, to double check some assumptions. Unfortunately,
8 there is a case where the fp won't be valid here, despite us having
9 saved arguments. That where we're returning through an error handler
10 via __builtin_eh_return().
12 While here, make the code more readable and conventional.
14 gcc/config/i386/i386.cc | 68 +++++++++++++++++++----------------------
15 1 file changed, 32 insertions(+), 36 deletions(-)
17 diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
18 index 25ae3371a45f..6387a7206f63 100644
19 --- a/gcc/config/i386/i386.cc
20 +++ b/gcc/config/i386/i386.cc
21 @@ -7198,21 +7198,21 @@ static void
22 ix86_emit_save_regs (void)
25 + struct ix86_frame &frame = cfun->machine->frame;
31 - int nsaved = ix86_nsaved_args ();
32 int start = cfun->returns_struct;
34 - for (i = start; i < start + nsaved; i++)
35 + for (i = start; i < start + frame.nmsave_args; i++)
37 regno = x86_64_int_parameter_registers[i];
38 insn = emit_insn (gen_push (gen_rtx_REG (word_mode, regno)));
39 RTX_FRAME_RELATED_P (insn) = 1;
41 - if (nsaved % 2 != 0)
42 + if (frame.nmsave_args % 2 != 0)
43 pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
44 GEN_INT (-UNITS_PER_WORD), -1, false);
46 @@ -7303,22 +7303,21 @@ ix86_emit_save_reg_using_mov (machine_mode mode, unsigned int regno,
47 /* Emit code to save registers using MOV insns.
48 First register is stored at CFA - CFA_OFFSET. */
50 -ix86_emit_save_regs_using_mov (const struct ix86_frame *frame)
51 +ix86_emit_save_regs_using_mov (const struct ix86_frame &frame)
54 - HOST_WIDE_INT cfa_offset = frame->arg_save_offset;
55 + HOST_WIDE_INT cfa_offset = frame.arg_save_offset;
60 - int nsaved = ix86_nsaved_args ();
61 int start = cfun->returns_struct;
63 /* We deal with this twice? */
64 - if (nsaved % 2 != 0)
65 + if (frame.nmsave_args % 2 != 0)
66 cfa_offset -= UNITS_PER_WORD;
68 - for (i = start + nsaved - 1; i >= start; i--)
69 + for (i = start + frame.nmsave_args - 1; i >= start; i--)
71 regno = x86_64_int_parameter_registers[i];
72 ix86_emit_save_reg_using_mov(word_mode, regno, cfa_offset);
73 @@ -7326,7 +7325,7 @@ ix86_emit_save_regs_using_mov (const struct ix86_frame *frame)
77 - cfa_offset = frame->reg_save_offset;
78 + cfa_offset = frame.reg_save_offset;
80 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
81 if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true))
82 @@ -8723,7 +8722,7 @@ ix86_expand_prologue (void)
83 && (! TARGET_STACK_PROBE
84 || frame.stack_pointer_offset < CHECK_STACK_LIMIT))
86 - ix86_emit_save_regs_using_mov (&frame);
87 + ix86_emit_save_regs_using_mov (frame);
88 cfun->machine->red_zone_used = true;
89 int_registers_saved = true;
91 @@ -9023,7 +9022,7 @@ ix86_expand_prologue (void)
94 if (!int_registers_saved)
95 - ix86_emit_save_regs_using_mov (&frame);
96 + ix86_emit_save_regs_using_mov (frame);
97 if (!sse_registers_saved)
98 ix86_emit_save_sse_regs_using_mov (frame.sse_reg_save_offset);
99 else if (save_stub_call_needed)
100 @@ -9683,33 +9682,30 @@ ix86_expand_epilogue (int style)
101 ix86_emit_restore_regs_using_pop ();
104 - if (TARGET_SAVE_ARGS) {
106 - * For each saved argument, emit a restore note, to make sure it happens
107 - * correctly within the shrink wrapping (I think).
109 - * Note that 'restore' in this case merely means the rule is the same as
110 - * it was on function entry, not that we have actually done a register
111 - * restore (which of course, we haven't).
113 - * If we do not do this, the DWARF code will emit sufficient restores to
114 - * provide balance on its own initiative, which in the presence of
115 - * -fshrink-wrap may actually _introduce_ unbalance (whereby we only
116 - * .cfi_offset a register sometimes, but will always .cfi_restore it.
117 - * This will trip an assert.)
119 - int start = cfun->returns_struct;
120 - int nsaved = ix86_nsaved_args();
123 - for (i = start + nsaved - 1; i >= start; i--)
124 - queued_cfa_restores
125 - = alloc_reg_note (REG_CFA_RESTORE,
127 + * For each saved argument, emit a restore note, to make sure it happens
128 + * correctly within the shrink wrapping (I think).
130 + * Note that 'restore' in this case merely means the rule is the same as
131 + * it was on function entry, not that we have actually done a register
132 + * restore (which of course, we haven't).
134 + * If we do not do this, the DWARF code will emit sufficient restores to
135 + * provide balance on its own initiative, which in the presence of
136 + * -fshrink-wrap may actually _introduce_ unbalance (whereby we only
137 + * .cfi_offset a register sometimes, but will always .cfi_restore it.
138 + * This will trip an assert.)
140 + if (TARGET_SAVE_ARGS && frame.nmsave_args > 0) {
141 + int start = cfun->returns_struct;
144 + for (i = start + frame.nmsave_args - 1; i >= start; i--)
145 + queued_cfa_restores
146 + = alloc_reg_note (REG_CFA_RESTORE,
148 - x86_64_int_parameter_registers[i]),
149 + x86_64_int_parameter_registers[i]),
150 queued_cfa_restores);
152 - gcc_assert(m->fs.fp_valid);
155 /* If we used a stack pointer and haven't already got rid of it,