[NDS32] Emit stack push instructions for varargs at prologue stage and emit...
[NDS32] Emit stack push instructions for varargs at prologue stage and emit stack adjustment instructions for varargs at epilogue stage. -- Note that we do not need to handle it in v3push/v3pop prologue/epilogue expanding because we do not apply v3push/v3pop for variadic function. * config/nds32/nds32.c (nds32_expand_prologue): Emit stack push instructions for varargs implementation. (nds32_expand_epilogue): Emit stack adjustment instructions for varargs implementation. From-SVN: r214867
This commit is contained in:
parent
99575d60c8
commit
557430f169
2 changed files with 87 additions and 1 deletions
|
@ -1,3 +1,10 @@
|
|||
2014-09-03 Chung-Ju Wu <jasonwucj@gmail.com>
|
||||
|
||||
* config/nds32/nds32.c (nds32_expand_prologue): Emit stack push
|
||||
instructions for varargs implementation.
|
||||
(nds32_expand_epilogue): Emit stack adjustment instructions for
|
||||
varargs implementation.
|
||||
|
||||
2014-09-03 Chung-Ju Wu <jasonwucj@gmail.com>
|
||||
|
||||
* config/nds32/nds32.c (nds32_expand_prologue): Suppress fp-as-gp
|
||||
|
|
|
@ -2788,6 +2788,35 @@ nds32_expand_prologue (void)
|
|||
The result will be in cfun->machine. */
|
||||
nds32_compute_stack_frame ();
|
||||
|
||||
/* If this is a variadic function, first we need to push argument
|
||||
registers that hold the unnamed argument value. */
|
||||
if (cfun->machine->va_args_size != 0)
|
||||
{
|
||||
Rb = gen_rtx_REG (SImode, cfun->machine->va_args_first_regno);
|
||||
Re = gen_rtx_REG (SImode, cfun->machine->va_args_last_regno);
|
||||
/* No need to push $fp, $gp, or $lp, so use GEN_INT(0). */
|
||||
nds32_emit_stack_push_multiple (Rb, Re, GEN_INT (0));
|
||||
|
||||
/* We may also need to adjust stack pointer for padding bytes
|
||||
because varargs may cause $sp not 8-byte aligned. */
|
||||
if (cfun->machine->va_args_area_padding_bytes)
|
||||
{
|
||||
/* Generate sp adjustment instruction. */
|
||||
sp_adjust = cfun->machine->va_args_area_padding_bytes;
|
||||
sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
|
||||
stack_pointer_rtx,
|
||||
GEN_INT (-1 * sp_adjust));
|
||||
|
||||
/* Emit rtx into instructions list and receive INSN rtx form. */
|
||||
sp_adjust_insn = emit_insn (sp_adjust_insn);
|
||||
|
||||
/* The insn rtx 'sp_adjust_insn' will change frame layout.
|
||||
We need to use RTX_FRAME_RELATED_P so that GCC is able to
|
||||
generate CFI (Call Frame Information) stuff. */
|
||||
RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the function is 'naked',
|
||||
we do not have to generate prologue code fragment. */
|
||||
if (cfun->machine->naked_p)
|
||||
|
@ -2887,9 +2916,32 @@ nds32_expand_epilogue (void)
|
|||
emit_insn (gen_blockage ());
|
||||
|
||||
/* If the function is 'naked', we do not have to generate
|
||||
epilogue code fragment BUT 'ret' instruction. */
|
||||
epilogue code fragment BUT 'ret' instruction.
|
||||
However, if this function is also a variadic function,
|
||||
we need to create adjust stack pointer before 'ret' instruction. */
|
||||
if (cfun->machine->naked_p)
|
||||
{
|
||||
/* If this is a variadic function, we do not have to restore argument
|
||||
registers but need to adjust stack pointer back to previous stack
|
||||
frame location before return. */
|
||||
if (cfun->machine->va_args_size != 0)
|
||||
{
|
||||
/* Generate sp adjustment instruction.
|
||||
We need to consider padding bytes here. */
|
||||
sp_adjust = cfun->machine->va_args_size
|
||||
+ cfun->machine->va_args_area_padding_bytes;
|
||||
sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
|
||||
stack_pointer_rtx,
|
||||
GEN_INT (sp_adjust));
|
||||
/* Emit rtx into instructions list and receive INSN rtx form. */
|
||||
sp_adjust_insn = emit_insn (sp_adjust_insn);
|
||||
|
||||
/* The insn rtx 'sp_adjust_insn' will change frame layout.
|
||||
We need to use RTX_FRAME_RELATED_P so that GCC is able to
|
||||
generate CFI (Call Frame Information) stuff. */
|
||||
RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
|
||||
}
|
||||
|
||||
/* Generate return instruction by using
|
||||
unspec_volatile_func_return pattern.
|
||||
Make sure this instruction is after gen_blockage().
|
||||
|
@ -2916,6 +2968,9 @@ nds32_expand_epilogue (void)
|
|||
GEN_INT (-1 * sp_adjust));
|
||||
/* Emit rtx into instructions list and receive INSN rtx form. */
|
||||
sp_adjust_insn = emit_insn (sp_adjust_insn);
|
||||
|
||||
/* The insn rtx 'sp_adjust_insn' will change frame layout. */
|
||||
RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2944,6 +2999,9 @@ nds32_expand_epilogue (void)
|
|||
GEN_INT (sp_adjust));
|
||||
/* Emit rtx into instructions list and receive INSN rtx form. */
|
||||
sp_adjust_insn = emit_insn (sp_adjust_insn);
|
||||
|
||||
/* The insn rtx 'sp_adjust_insn' will change frame layout. */
|
||||
RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2972,6 +3030,27 @@ nds32_expand_epilogue (void)
|
|||
nds32_emit_stack_pop_multiple (Rb, Re, GEN_INT (en4_const));
|
||||
}
|
||||
|
||||
/* If this is a variadic function, we do not have to restore argument
|
||||
registers but need to adjust stack pointer back to previous stack
|
||||
frame location before return. */
|
||||
if (cfun->machine->va_args_size != 0)
|
||||
{
|
||||
/* Generate sp adjustment instruction.
|
||||
We need to consider padding bytes here. */
|
||||
sp_adjust = cfun->machine->va_args_size
|
||||
+ cfun->machine->va_args_area_padding_bytes;
|
||||
sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
|
||||
stack_pointer_rtx,
|
||||
GEN_INT (sp_adjust));
|
||||
/* Emit rtx into instructions list and receive INSN rtx form. */
|
||||
sp_adjust_insn = emit_insn (sp_adjust_insn);
|
||||
|
||||
/* The insn rtx 'sp_adjust_insn' will change frame layout.
|
||||
We need to use RTX_FRAME_RELATED_P so that GCC is able to
|
||||
generate CFI (Call Frame Information) stuff. */
|
||||
RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
|
||||
}
|
||||
|
||||
/* Generate return instruction by using
|
||||
unspec_volatile_func_return pattern. */
|
||||
emit_insn (gen_unspec_volatile_func_return ());
|
||||
|
|
Loading…
Add table
Reference in a new issue