xrandr: update to 1.5.3
[oi-userland.git] / components / developer / gcc-11 / patches / 0009-i386-Save-integer-passed-arguments-to-the-stack-to-a.patch
blob5a6b02c4dd7ed30478f37af154092d5000699762
1 From 9115575f021bc853091b1528fbae30b8b1abb821 Mon Sep 17 00:00:00 2001
2 From: Richard Lowe <richlowe@richlowe.net>
3 Date: Sat, 23 Jan 2016 22:14:56 -0500
4 Subject: i386: Save integer-passed arguments to the stack, to
5 aid debuggers.
6 MIME-Version: 1.0
7 Content-Type: text/plain; charset=UTF-8
8 Content-Transfer-Encoding: 8bit
10 Merged from 5.3 to 7.2 by: Aurélien Larcher
12 Originally implemented in:
13 commit 023cc9a4c9c698bed1f51d38eac850d327fc1146
14 Author: jsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>
15 Date: Wed Jun 29 23:51:34 2005 +0000
17 * gcc/dwarf2.h (DW_AT_SUN_amd64_parmdump): New.
18 * gcc/dwarf2out.c (gen_subprogram_die): Add this attribute.
19 * gcc/doc/invoke.texi (-msave-args): New x86-64 option.
20 * gcc/config/i386/i386.h (MASK_SAVE_ARGS, TARGET_SAVE_ARGS): New.
21 (TARGET_SWITCHES): Add -msave-args.
22 * gcc/config/i386/i386.c (struct ix86_frame): Add nmsave_args and
23 padding0.
24 (pro_epilogue_adjust_stack): Declare.
25 (ix86_nsaved_args): New.
26 (override_options, ix86_can_use_return_insn_p,
27 ix86_frame_pointer_required, ix86_compute_frame_layout,
28 ix86_emit_save_regs, ix86_emit_save_regs_using_mov,
29 ix86_expand_prologue, ix86_expand_epilogue): Handle -msave-args.
31 git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/csl-sol210-3_4-branch@101443 138bc75d-0d04-0410-961f-82ee72b054a4
32 ---
33 gcc/config/i386/i386-options.c | 3 +
34 gcc/config/i386/i386.c | 130 +++++++++++++++++-
35 gcc/config/i386/i386.h | 7 +
36 gcc/config/i386/i386.opt | 10 ++
37 gcc/doc/invoke.texi | 4 +
38 gcc/dwarf2out.c | 5 +
39 .../gcc.target/i386/msave-args-mov.c | 26 ++++
40 .../gcc.target/i386/msave-args-push.c | 26 ++++
41 include/dwarf2.def | 2 +
42 9 files changed, 206 insertions(+), 7 deletions(-)
43 create mode 100644 gcc/testsuite/gcc.target/i386/msave-args-mov.c
44 create mode 100644 gcc/testsuite/gcc.target/i386/msave-args-push.c
46 diff --git a/gcc/config/i386/i386-options.c b/gcc/config/i386/i386-options.c
47 index 18d2c0b9f99..9f9d1028eb7 100644
48 --- a/gcc/config/i386/i386-options.c
49 +++ b/gcc/config/i386/i386-options.c
50 @@ -2641,6 +2641,9 @@
51 &= ~((OPTION_MASK_ISA_BMI | OPTION_MASK_ISA_BMI2 | OPTION_MASK_ISA_TBM)
52 & ~opts->x_ix86_isa_flags_explicit);
54 + if (!TARGET_64BIT_P (opts->x_ix86_isa_flags) && TARGET_SAVE_ARGS)
55 + error ("-msave-args makes no sense in the 32-bit mode");
57 /* Validate -mpreferred-stack-boundary= value or default it to
58 PREFERRED_STACK_BOUNDARY_DEFAULT. */
59 ix86_preferred_stack_boundary = PREFERRED_STACK_BOUNDARY_DEFAULT;
60 diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
61 index 9d02aad9e13..cdd5633cb57 100644
62 --- a/gcc/config/i386/i386.c
63 +++ b/gcc/config/i386/i386.c
64 @@ -416,6 +416,9 @@
65 static bool ix86_can_inline_p (tree, tree);
66 static unsigned int ix86_minimum_incoming_stack_boundary (bool);
68 +static int ix86_nsaved_args (void);
69 +static rtx_def* pro_epilogue_adjust_stack (rtx, rtx, rtx, int, bool);
72 /* Whether -mtune= or -march= were specified */
73 int ix86_tune_defaulted;
74 @@ -5536,7 +5539,7 @@
76 struct ix86_frame &frame = cfun->machine->frame;
77 return (frame.stack_pointer_offset == UNITS_PER_WORD
78 - && (frame.nregs + frame.nsseregs) == 0);
79 + && (frame.nmsave_args + frame.nregs + frame.nsseregs) == 0);
82 /* Return stack frame size. get_frame_size () returns used stack slots
83 @@ -5573,6 +5576,9 @@
84 if (TARGET_32BIT_MS_ABI && cfun->calls_setjmp)
85 return true;
87 + if (TARGET_SAVE_ARGS)
88 + return true;
90 /* Win64 SEH, very large frames need a frame-pointer as maximum stack
91 allocation is 4GB. */
92 if (TARGET_64BIT_MS_ABI && ix86_get_frame_size () > SEH_MAX_FRAME_SIZE)
93 @@ -6413,6 +6419,7 @@
95 frame->nregs = ix86_nsaved_regs ();
96 frame->nsseregs = ix86_nsaved_sseregs ();
97 + frame->nmsave_args = ix86_nsaved_args ();
99 /* 64-bit MS ABI seem to require stack alignment to be always 16,
100 except for function prologues, leaf functions and when the defult
101 @@ -6494,7 +6501,8 @@
104 frame->save_regs_using_mov
105 - = TARGET_PROLOGUE_USING_MOVE && m->use_fast_prologue_epilogue;
106 + = TARGET_FORCE_SAVE_REGS_USING_MOV ||
107 + (TARGET_PROLOGUE_USING_MOVE && m->use_fast_prologue_epilogue);
109 /* Skip return address and error code in exception handler. */
110 offset = INCOMING_FRAME_SP_OFFSET;
111 @@ -6511,6 +6519,13 @@
112 /* The traditional frame pointer location is at the top of the frame. */
113 frame->hard_frame_pointer_offset = offset;
115 + if (TARGET_SAVE_ARGS)
117 + offset += frame->nmsave_args * UNITS_PER_WORD;
118 + offset += (frame->nmsave_args % 2) * UNITS_PER_WORD;
120 + frame->arg_save_offset = offset;
122 /* Register save area */
123 offset += frame->nregs * UNITS_PER_WORD;
124 frame->reg_save_offset = offset;
125 @@ -6644,7 +6659,7 @@
126 /* Size prologue needs to allocate. */
127 to_allocate = offset - frame->sse_reg_save_offset;
129 - if ((!to_allocate && frame->nregs <= 1)
130 + if ((!TARGET_SAVE_ARGS && !to_allocate && frame->nregs <= 1)
131 || (TARGET_64BIT && to_allocate >= HOST_WIDE_INT_C (0x80000000))
132 /* If static stack checking is enabled and done with probes,
133 the registers need to be saved before allocating the frame. */
134 @@ -6666,7 +6681,11 @@
136 frame->red_zone_size = to_allocate;
137 if (frame->save_regs_using_mov)
139 frame->red_zone_size += frame->nregs * UNITS_PER_WORD;
140 + frame->red_zone_size += frame->nmsave_args * UNITS_PER_WORD;
141 + frame->red_zone_size += (frame->nmsave_args % 2) * UNITS_PER_WORD;
143 if (frame->red_zone_size > RED_ZONE_SIZE - RED_ZONE_RESERVE)
144 frame->red_zone_size = RED_ZONE_SIZE - RED_ZONE_RESERVE;
146 @@ -6724,6 +6743,22 @@
147 else
148 frame->hard_frame_pointer_offset = frame->hfp_save_offset;
151 + if (getenv("DEBUG_FRAME_STUFF") != NULL)
153 + printf("nmsave_args: %d\n", frame->nmsave_args);
154 + printf("nsseregs: %d\n", frame->nsseregs);
155 + printf("nregs: %d\n", frame->nregs);
157 + printf("frame_pointer_offset: %llx\n", frame->frame_pointer_offset);
158 + printf("hard_frame_pointer_offset: %llx\n", frame->hard_frame_pointer_offset);
159 + printf("stack_pointer_offset: %llx\n", frame->stack_pointer_offset);
160 + printf("hfp_save_offset: %llx\n", frame->hfp_save_offset);
161 + printf("arg_save_offset: %llx\n", frame->arg_save_offset);
162 + printf("reg_save_offset: %llx\n", frame->reg_save_offset);
163 + printf("sse_reg_save_offset: %llx\n", frame->sse_reg_save_offset);
168 /* This is semi-inlined memory_address_length, but simplified
169 @@ -6939,6 +6974,23 @@
170 unsigned int regno;
171 rtx_insn *insn;
173 + if (TARGET_SAVE_ARGS)
175 + int i;
176 + int nsaved = ix86_nsaved_args ();
177 + int start = cfun->returns_struct;
179 + for (i = start; i < start + nsaved; i++)
181 + regno = x86_64_int_parameter_registers[i];
182 + insn = emit_insn (gen_push (gen_rtx_REG (word_mode, regno)));
183 + RTX_FRAME_RELATED_P (insn) = 1;
185 + if (nsaved % 2 != 0)
186 + pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
187 + GEN_INT (-UNITS_PER_WORD), -1, false);
190 for (regno = FIRST_PSEUDO_REGISTER - 1; regno-- > 0; )
191 if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true))
193 @@ -7025,9 +7077,30 @@
194 /* Emit code to save registers using MOV insns.
195 First register is stored at CFA - CFA_OFFSET. */
196 static void
197 -ix86_emit_save_regs_using_mov (HOST_WIDE_INT cfa_offset)
198 +ix86_emit_save_regs_using_mov (const struct ix86_frame *frame)
200 unsigned int regno;
201 + HOST_WIDE_INT cfa_offset = frame->arg_save_offset;
203 + if (TARGET_SAVE_ARGS)
205 + int i;
206 + int nsaved = ix86_nsaved_args ();
207 + int start = cfun->returns_struct;
209 + /* We deal with this twice? */
210 + if (nsaved % 2 != 0)
211 + cfa_offset -= UNITS_PER_WORD;
213 + for (i = start + nsaved - 1; i >= start; i--)
215 + regno = x86_64_int_parameter_registers[i];
216 + ix86_emit_save_reg_using_mov(word_mode, regno, cfa_offset);
217 + cfa_offset -= UNITS_PER_WORD;
221 + cfa_offset = frame->reg_save_offset;
223 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
224 if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true))
225 @@ -8372,7 +8445,7 @@
229 - int_registers_saved = (frame.nregs == 0);
230 + int_registers_saved = (frame.nregs == 0 && frame.nmsave_args == 0);
231 sse_registers_saved = (frame.nsseregs == 0);
232 save_stub_call_needed = (m->call_ms2sysv);
233 gcc_assert (sse_registers_saved || !save_stub_call_needed);
234 @@ -8414,7 +8487,7 @@
235 && (! TARGET_STACK_PROBE
236 || frame.stack_pointer_offset < CHECK_STACK_LIMIT))
238 - ix86_emit_save_regs_using_mov (frame.reg_save_offset);
239 + ix86_emit_save_regs_using_mov (&frame);
240 cfun->machine->red_zone_used = true;
241 int_registers_saved = true;
243 @@ -8711,7 +8784,7 @@
246 if (!int_registers_saved)
247 - ix86_emit_save_regs_using_mov (frame.reg_save_offset);
248 + ix86_emit_save_regs_using_mov (&frame);
249 if (!sse_registers_saved)
250 ix86_emit_save_sse_regs_using_mov (frame.sse_reg_save_offset);
251 else if (save_stub_call_needed)
252 @@ -8746,6 +8819,7 @@
253 relative to the value of the stack pointer at the end of the function
254 prologue, and moving instructions that access redzone area via frame
255 pointer inside push sequence violates this assumption. */
256 + /* XXX: We may wish to do this when SAVE_ARGS in general */
257 if (frame_pointer_needed && frame.red_zone_size)
258 emit_insn (gen_memory_blockage ());
260 @@ -9130,6 +9204,7 @@
262 /* See the comment about red zone and frame
263 pointer usage in ix86_expand_prologue. */
264 + /* XXX: We may wish to do this when SAVE_ARGS in general */
265 if (frame_pointer_needed && frame.red_zone_size)
266 emit_insn (gen_memory_blockage ());
268 @@ -9366,6 +9441,35 @@
269 ix86_emit_restore_regs_using_pop ();
272 + if (TARGET_SAVE_ARGS) {
273 + /*
274 + * For each saved argument, emit a restore note, to make sure it happens
275 + * correctly within the shrink wrapping (I think).
277 + * Note that 'restore' in this case merely means the rule is the same as
278 + * it was on function entry, not that we have actually done a register
279 + * restore (which of course, we haven't).
281 + * If we do not do this, the DWARF code will emit sufficient restores to
282 + * provide balance on its own initiative, which in the presence of
283 + * -fshrink-wrap may actually _introduce_ unbalance (whereby we only
284 + * .cfi_offset a register sometimes, but will always .cfi_restore it.
285 + * This will trip an assert.)
286 + */
287 + int start = cfun->returns_struct;
288 + int nsaved = ix86_nsaved_args();
289 + int i;
291 + for (i = start + nsaved - 1; i >= start; i--)
292 + queued_cfa_restores
293 + = alloc_reg_note (REG_CFA_RESTORE,
294 + gen_rtx_REG(Pmode,
295 + x86_64_int_parameter_registers[i]),
296 + queued_cfa_restores);
298 + gcc_assert(m->fs.fp_valid);
301 /* If we used a stack pointer and haven't already got rid of it,
302 then do so now. */
303 if (m->fs.fp_valid)
304 @@ -10458,6 +10562,18 @@
305 return !ix86_legitimate_constant_p (mode, x);
308 +/* Return number of arguments to be saved on the stack with
309 + -msave-args. */
311 +static int
312 +ix86_nsaved_args (void)
314 + if (TARGET_SAVE_ARGS)
315 + return crtl->args.info.regno - cfun->returns_struct;
316 + else
317 + return 0;
320 /* Nonzero if the symbol is marked as dllimport, or as stub-variable,
321 otherwise zero. */
323 diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
324 index 5583ec6881a..eebf9b9670d 100644
325 --- a/gcc/config/i386/i386.h
326 +++ b/gcc/config/i386/i386.h
327 --- i386.h.~1~ 2022-04-21 10:59:17.000000000 +0000
328 +++ i386.h 2022-05-19 11:15:00.066584226 +0000
329 @@ -2726,6 +2726,11 @@
331 saved frame pointer if frame_pointer_needed
332 <- HARD_FRAME_POINTER
334 + [-msave-args] <- arg_save_offset
336 + [saveargs padding]
338 [saved regs]
339 <- reg_save_offset
340 [padding0]
341 @@ -2759,6 +2764,7 @@
343 struct GTY(()) ix86_frame
345 + int nmsave_args;
346 int nsseregs;
347 int nregs;
348 int va_arg_size;
349 @@ -2770,6 +2776,7 @@
350 HOST_WIDE_INT hard_frame_pointer_offset;
351 HOST_WIDE_INT stack_pointer_offset;
352 HOST_WIDE_INT hfp_save_offset;
353 + HOST_WIDE_INT arg_save_offset;
354 HOST_WIDE_INT reg_save_offset;
355 HOST_WIDE_INT stack_realign_allocate;
356 HOST_WIDE_INT stack_realign_offset;
357 diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt
358 index c781fdc8278..af7e920a67c 100644
359 --- a/gcc/config/i386/i386.opt
360 +++ b/gcc/config/i386/i386.opt
361 @@ -514,6 +514,16 @@ mtls-direct-seg-refs
362 Target Mask(TLS_DIRECT_SEG_REFS)
363 Use direct references against %gs when accessing tls data.
365 +msave-args
366 +Target Mask(SAVE_ARGS)
367 +Save integer arguments on the stack at function entry.
369 +mforce-save-regs-using-mov
370 +Target Mask(FORCE_SAVE_REGS_USING_MOV)
371 +Save registers using push in function prologues. This is intentionally
372 +undocumented and used for msave-args testing.
375 mtune=
376 Target RejectNegative Negative(mtune=) Joined Var(ix86_tune_string)
377 Schedule code for given CPU.
378 diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
379 index 4f265aeead0..33facd6e594 100644
380 --- a/gcc/doc/invoke.texi
381 +++ b/gcc/doc/invoke.texi
382 @@ -18083,6 +18083,10 @@
383 @option{-mcmodel=large} option is incompatible with @option{-mabi=ilp32},
384 @option{-fpic} and @option{-fPIC}.
386 +@item -msave-args
387 +@opindex msave-args
388 +Save integer-sized arguments on the stack on function entry.
390 @item -mstrict-align
391 @itemx -mno-strict-align
392 @opindex mstrict-align
393 diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
394 index 7606371296e..de12e492bb3 100644
395 --- a/gcc/dwarf2out.c
396 +++ b/gcc/dwarf2out.c
397 @@ -23648,6 +23648,11 @@
398 /* Add the calling convention attribute if requested. */
399 add_calling_convention_attribute (subr_die, decl);
401 +#ifdef TARGET_SAVE_ARGS
402 + if (declaration && TARGET_SAVE_ARGS)
403 + add_AT_flag (subr_die, DW_AT_SUN_amd64_parmdump, 1);
404 +#endif
406 /* Output Dwarf info for all of the stuff within the body of the function
407 (if it has one - it may be just a declaration).
409 diff --git a/gcc/testsuite/gcc.target/i386/msave-args-mov.c b/gcc/testsuite/gcc.target/i386/msave-args-mov.c
410 new file mode 100644
411 index 00000000000..a2ca76752a9
412 --- /dev/null
413 +++ b/gcc/testsuite/gcc.target/i386/msave-args-mov.c
414 @@ -0,0 +1,26 @@
415 +/* { dg-do run { target { { i?86-*-solaris2.* } && lp64 } } } */
416 +/* { dg-options "-msave-args -mforce-save-regs-using-mov -save-temps" } */
418 +#include <stdio.h>
420 +void t(int, int, int, int, int) __attribute__ ((noinline));
422 +int
423 +main(int argc, char **argv)
425 + t(1, 2, 3, 4, 5);
426 + return (0);
429 +void
430 +t(int a, int b, int c, int d, int e)
432 + printf("%d %d %d %d %d", a, b, c, d, e);
435 +/* { dg-final { scan-assembler "movq\t%rdi, -8\\(%rbp\\)" } } */
436 +/* { dg-final { scan-assembler "movq\t%rsi, -16\\(%rbp\\)" } } */
437 +/* { dg-final { scan-assembler "movq\t%rdx, -24\\(%rbp\\)" } } */
438 +/* { dg-final { scan-assembler "movq\t%rcx, -32\\(%rbp\\)" } } */
439 +/* { dg-final { scan-assembler "movq\t%r8, -40\\(%rbp\\)" } } */
440 +/* { dg-final { cleanup-saved-temps } } */
441 diff --git a/gcc/testsuite/gcc.target/i386/msave-args-push.c b/gcc/testsuite/gcc.target/i386/msave-args-push.c
442 new file mode 100644
443 index 00000000000..fbe053dadc8
444 --- /dev/null
445 +++ b/gcc/testsuite/gcc.target/i386/msave-args-push.c
446 @@ -0,0 +1,26 @@
447 +/* { dg-do run { target { { i?86-*-solaris2.* } && lp64 } } } */
448 +/* { dg-options "-msave-args -save-temps " } */
450 +#include <stdio.h>
452 +void t(int, int, int, int, int) __attribute__ ((noinline));
454 +int
455 +main(int argc, char **argv)
457 + t(1, 2, 3, 4, 5);
458 + return (0);
461 +void
462 +t(int a, int b, int c, int d, int e)
464 + printf("%d %d %d %d %d", a, b, c, d, e);
467 +/* { dg-final { scan-assembler "pushq\t%rdi" } } */
468 +/* { dg-final { scan-assembler "pushq\t%rsi" } } */
469 +/* { dg-final { scan-assembler "pushq\t%rdx" } } */
470 +/* { dg-final { scan-assembler "pushq\t%rcx" } } */
471 +/* { dg-final { scan-assembler "pushq\t%r8" } } */
472 +/* { dg-final { cleanup-saved-temps } } */
473 diff --git a/include/dwarf2.def b/include/dwarf2.def
474 index 1ae6e1df298..17e32b3400a 100644
475 --- a/include/dwarf2.def
476 +++ b/include/dwarf2.def
477 @@ -467,6 +467,8 @@ DW_TAG (DW_AT_GNU_denominator, 0x2304)
478 /* Biased integer extension.
479 See https://gcc.gnu.org/wiki/DW_AT_GNU_bias . */
480 DW_TAG (DW_AT_GNU_bias, 0x2305)
481 +/* Sun extension. */
482 +DW_AT (DW_AT_SUN_amd64_parmdump, 0x2224)
483 /* UPC extension. */
484 DW_AT (DW_AT_upc_threads_scaled, 0x3210)
485 /* PGI (STMicroelectronics) extensions. */