|
|
8178f7 |
2014-08-08 Richard Henderson <rth@redhat.com>
|
|
|
8178f7 |
|
|
|
8178f7 |
* config/aarch64/aarch64.c (aarch64_save_or_restore_fprs): Add
|
|
|
8178f7 |
cfi_ops argument, for restore put REG_CFA_RESTORE notes into
|
|
|
8178f7 |
*cfi_ops rather than on individual insns. Cleanup.
|
|
|
8178f7 |
(aarch64_save_or_restore_callee_save_registers): Likewise.
|
|
|
8178f7 |
(aarch64_expand_prologue): Adjust caller.
|
|
|
8178f7 |
(aarch64_expand_epilogue): Likewise. Cleanup. Emit queued cfi_ops
|
|
|
8178f7 |
on the stack restore insn.
|
|
|
8178f7 |
|
|
|
8178f7 |
--- gcc/config/aarch64/aarch64.c 2014-07-15 02:27:16.000000000 -0700
|
|
|
8178f7 |
+++ gcc/config/aarch64/aarch64.c 2014-08-21 12:52:44.190455860 -0700
|
|
|
8178f7 |
@@ -1603,24 +1603,23 @@ aarch64_register_saved_on_entry (int reg
|
|
|
8178f7 |
|
|
|
8178f7 |
static void
|
|
|
8178f7 |
aarch64_save_or_restore_fprs (int start_offset, int increment,
|
|
|
8178f7 |
- bool restore, rtx base_rtx)
|
|
|
8178f7 |
-
|
|
|
8178f7 |
+ bool restore, rtx base_rtx, rtx *cfi_ops)
|
|
|
8178f7 |
{
|
|
|
8178f7 |
unsigned regno;
|
|
|
8178f7 |
unsigned regno2;
|
|
|
8178f7 |
rtx insn;
|
|
|
8178f7 |
rtx (*gen_mem_ref)(enum machine_mode, rtx) = (frame_pointer_needed)? gen_frame_mem : gen_rtx_MEM;
|
|
|
8178f7 |
|
|
|
8178f7 |
-
|
|
|
8178f7 |
for (regno = V0_REGNUM; regno <= V31_REGNUM; regno++)
|
|
|
8178f7 |
{
|
|
|
8178f7 |
if (aarch64_register_saved_on_entry (regno))
|
|
|
8178f7 |
{
|
|
|
8178f7 |
- rtx mem;
|
|
|
8178f7 |
+ rtx mem, reg1;
|
|
|
8178f7 |
mem = gen_mem_ref (DFmode,
|
|
|
8178f7 |
plus_constant (Pmode,
|
|
|
8178f7 |
base_rtx,
|
|
|
8178f7 |
start_offset));
|
|
|
8178f7 |
+ reg1 = gen_rtx_REG (DFmode, regno);
|
|
|
8178f7 |
|
|
|
8178f7 |
for (regno2 = regno + 1;
|
|
|
8178f7 |
regno2 <= V31_REGNUM
|
|
|
8178f7 |
@@ -1632,54 +1631,51 @@ aarch64_save_or_restore_fprs (int start_
|
|
|
8178f7 |
if (regno2 <= V31_REGNUM &&
|
|
|
8178f7 |
aarch64_register_saved_on_entry (regno2))
|
|
|
8178f7 |
{
|
|
|
8178f7 |
- rtx mem2;
|
|
|
8178f7 |
+ rtx mem2, reg2;
|
|
|
8178f7 |
/* Next highest register to be saved. */
|
|
|
8178f7 |
mem2 = gen_mem_ref (DFmode,
|
|
|
8178f7 |
plus_constant
|
|
|
8178f7 |
(Pmode,
|
|
|
8178f7 |
base_rtx,
|
|
|
8178f7 |
start_offset + increment));
|
|
|
8178f7 |
+ reg2 = gen_rtx_REG (DFmode, regno2);
|
|
|
8178f7 |
+
|
|
|
8178f7 |
if (restore == false)
|
|
|
8178f7 |
{
|
|
|
8178f7 |
- insn = emit_insn
|
|
|
8178f7 |
- ( gen_store_pairdf (mem, gen_rtx_REG (DFmode, regno),
|
|
|
8178f7 |
- mem2, gen_rtx_REG (DFmode, regno2)));
|
|
|
8178f7 |
-
|
|
|
8178f7 |
+ insn = emit_insn (gen_store_pairdf (mem, reg1, mem2, reg2));
|
|
|
8178f7 |
+ /* The first part of a frame-related parallel insn
|
|
|
8178f7 |
+ is always assumed to be relevant to the frame
|
|
|
8178f7 |
+ calculations; subsequent parts, are only
|
|
|
8178f7 |
+ frame-related if explicitly marked. */
|
|
|
8178f7 |
+ RTX_FRAME_RELATED_P (XVECEXP (PATTERN (insn), 0, 1)) = 1;
|
|
|
8178f7 |
+ RTX_FRAME_RELATED_P (insn) = 1;
|
|
|
8178f7 |
}
|
|
|
8178f7 |
else
|
|
|
8178f7 |
{
|
|
|
8178f7 |
- insn = emit_insn
|
|
|
8178f7 |
- ( gen_load_pairdf (gen_rtx_REG (DFmode, regno), mem,
|
|
|
8178f7 |
- gen_rtx_REG (DFmode, regno2), mem2));
|
|
|
8178f7 |
-
|
|
|
8178f7 |
- add_reg_note (insn, REG_CFA_RESTORE, gen_rtx_REG (DFmode, regno));
|
|
|
8178f7 |
- add_reg_note (insn, REG_CFA_RESTORE, gen_rtx_REG (DFmode, regno2));
|
|
|
8178f7 |
+ emit_insn (gen_load_pairdf (reg1, mem, reg2, mem2));
|
|
|
8178f7 |
+ *cfi_ops = alloc_reg_note (REG_CFA_RESTORE, reg1, *cfi_ops);
|
|
|
8178f7 |
+ *cfi_ops = alloc_reg_note (REG_CFA_RESTORE, reg2, *cfi_ops);
|
|
|
8178f7 |
}
|
|
|
8178f7 |
|
|
|
8178f7 |
- /* The first part of a frame-related parallel insn
|
|
|
8178f7 |
- is always assumed to be relevant to the frame
|
|
|
8178f7 |
- calculations; subsequent parts, are only
|
|
|
8178f7 |
- frame-related if explicitly marked. */
|
|
|
8178f7 |
- RTX_FRAME_RELATED_P (XVECEXP (PATTERN (insn), 0,
|
|
|
8178f7 |
- 1)) = 1;
|
|
|
8178f7 |
regno = regno2;
|
|
|
8178f7 |
start_offset += increment * 2;
|
|
|
8178f7 |
}
|
|
|
8178f7 |
else
|
|
|
8178f7 |
{
|
|
|
8178f7 |
if (restore == false)
|
|
|
8178f7 |
- insn = emit_move_insn (mem, gen_rtx_REG (DFmode, regno));
|
|
|
8178f7 |
+ {
|
|
|
8178f7 |
+ insn = emit_move_insn (mem, reg1);
|
|
|
8178f7 |
+ RTX_FRAME_RELATED_P (insn) = 1;
|
|
|
8178f7 |
+ }
|
|
|
8178f7 |
else
|
|
|
8178f7 |
{
|
|
|
8178f7 |
- insn = emit_move_insn (gen_rtx_REG (DFmode, regno), mem);
|
|
|
8178f7 |
- add_reg_note (insn, REG_CFA_RESTORE, gen_rtx_REG (DImode, regno));
|
|
|
8178f7 |
+ emit_move_insn (reg1, mem);
|
|
|
8178f7 |
+ *cfi_ops = alloc_reg_note (REG_CFA_RESTORE, reg1, *cfi_ops);
|
|
|
8178f7 |
}
|
|
|
8178f7 |
start_offset += increment;
|
|
|
8178f7 |
}
|
|
|
8178f7 |
- RTX_FRAME_RELATED_P (insn) = 1;
|
|
|
8178f7 |
}
|
|
|
8178f7 |
}
|
|
|
8178f7 |
-
|
|
|
8178f7 |
}
|
|
|
8178f7 |
|
|
|
8178f7 |
|
|
|
8178f7 |
@@ -1687,13 +1683,14 @@ aarch64_save_or_restore_fprs (int start_
|
|
|
8178f7 |
restore's have to happen. */
|
|
|
8178f7 |
static void
|
|
|
8178f7 |
aarch64_save_or_restore_callee_save_registers (HOST_WIDE_INT offset,
|
|
|
8178f7 |
- bool restore)
|
|
|
8178f7 |
+ bool restore, rtx *cfi_ops)
|
|
|
8178f7 |
{
|
|
|
8178f7 |
rtx insn;
|
|
|
8178f7 |
rtx base_rtx = stack_pointer_rtx;
|
|
|
8178f7 |
HOST_WIDE_INT start_offset = offset;
|
|
|
8178f7 |
HOST_WIDE_INT increment = UNITS_PER_WORD;
|
|
|
8178f7 |
- rtx (*gen_mem_ref)(enum machine_mode, rtx) = (frame_pointer_needed)? gen_frame_mem : gen_rtx_MEM;
|
|
|
8178f7 |
+ rtx (*gen_mem_ref)(enum machine_mode, rtx)
|
|
|
8178f7 |
+ = (frame_pointer_needed)? gen_frame_mem : gen_rtx_MEM;
|
|
|
8178f7 |
unsigned limit = (frame_pointer_needed)? R28_REGNUM: R30_REGNUM;
|
|
|
8178f7 |
unsigned regno;
|
|
|
8178f7 |
unsigned regno2;
|
|
|
8178f7 |
@@ -1702,11 +1699,13 @@ aarch64_save_or_restore_callee_save_regi
|
|
|
8178f7 |
{
|
|
|
8178f7 |
if (aarch64_register_saved_on_entry (regno))
|
|
|
8178f7 |
{
|
|
|
8178f7 |
- rtx mem;
|
|
|
8178f7 |
+ rtx mem, reg1;
|
|
|
8178f7 |
+
|
|
|
8178f7 |
mem = gen_mem_ref (Pmode,
|
|
|
8178f7 |
plus_constant (Pmode,
|
|
|
8178f7 |
base_rtx,
|
|
|
8178f7 |
start_offset));
|
|
|
8178f7 |
+ reg1 = gen_rtx_REG (DImode, regno);
|
|
|
8178f7 |
|
|
|
8178f7 |
for (regno2 = regno + 1;
|
|
|
8178f7 |
regno2 <= limit
|
|
|
8178f7 |
@@ -1718,56 +1717,54 @@ aarch64_save_or_restore_callee_save_regi
|
|
|
8178f7 |
if (regno2 <= limit &&
|
|
|
8178f7 |
aarch64_register_saved_on_entry (regno2))
|
|
|
8178f7 |
{
|
|
|
8178f7 |
- rtx mem2;
|
|
|
8178f7 |
+ rtx mem2, reg2;
|
|
|
8178f7 |
/* Next highest register to be saved. */
|
|
|
8178f7 |
mem2 = gen_mem_ref (Pmode,
|
|
|
8178f7 |
plus_constant
|
|
|
8178f7 |
(Pmode,
|
|
|
8178f7 |
base_rtx,
|
|
|
8178f7 |
start_offset + increment));
|
|
|
8178f7 |
+ reg2 = gen_rtx_REG (DImode, regno2);
|
|
|
8178f7 |
+
|
|
|
8178f7 |
if (restore == false)
|
|
|
8178f7 |
{
|
|
|
8178f7 |
- insn = emit_insn
|
|
|
8178f7 |
- ( gen_store_pairdi (mem, gen_rtx_REG (DImode, regno),
|
|
|
8178f7 |
- mem2, gen_rtx_REG (DImode, regno2)));
|
|
|
8178f7 |
-
|
|
|
8178f7 |
+ insn = emit_insn (gen_store_pairdi (mem, reg1, mem2, reg2));
|
|
|
8178f7 |
+ /* The first part of a frame-related parallel insn
|
|
|
8178f7 |
+ is always assumed to be relevant to the frame
|
|
|
8178f7 |
+ calculations; subsequent parts, are only
|
|
|
8178f7 |
+ frame-related if explicitly marked. */
|
|
|
8178f7 |
+ RTX_FRAME_RELATED_P (XVECEXP (PATTERN (insn), 0, 1)) = 1;
|
|
|
8178f7 |
+ RTX_FRAME_RELATED_P (insn) = 1;
|
|
|
8178f7 |
}
|
|
|
8178f7 |
else
|
|
|
8178f7 |
{
|
|
|
8178f7 |
- insn = emit_insn
|
|
|
8178f7 |
- ( gen_load_pairdi (gen_rtx_REG (DImode, regno), mem,
|
|
|
8178f7 |
- gen_rtx_REG (DImode, regno2), mem2));
|
|
|
8178f7 |
-
|
|
|
8178f7 |
- add_reg_note (insn, REG_CFA_RESTORE, gen_rtx_REG (DImode, regno));
|
|
|
8178f7 |
- add_reg_note (insn, REG_CFA_RESTORE, gen_rtx_REG (DImode, regno2));
|
|
|
8178f7 |
+ emit_insn (gen_load_pairdi (reg1, mem, reg2, mem2));
|
|
|
8178f7 |
+ *cfi_ops = alloc_reg_note (REG_CFA_RESTORE, reg1, *cfi_ops);
|
|
|
8178f7 |
+ *cfi_ops = alloc_reg_note (REG_CFA_RESTORE, reg2, *cfi_ops);
|
|
|
8178f7 |
}
|
|
|
8178f7 |
|
|
|
8178f7 |
- /* The first part of a frame-related parallel insn
|
|
|
8178f7 |
- is always assumed to be relevant to the frame
|
|
|
8178f7 |
- calculations; subsequent parts, are only
|
|
|
8178f7 |
- frame-related if explicitly marked. */
|
|
|
8178f7 |
- RTX_FRAME_RELATED_P (XVECEXP (PATTERN (insn), 0,
|
|
|
8178f7 |
- 1)) = 1;
|
|
|
8178f7 |
regno = regno2;
|
|
|
8178f7 |
start_offset += increment * 2;
|
|
|
8178f7 |
}
|
|
|
8178f7 |
else
|
|
|
8178f7 |
{
|
|
|
8178f7 |
if (restore == false)
|
|
|
8178f7 |
- insn = emit_move_insn (mem, gen_rtx_REG (DImode, regno));
|
|
|
8178f7 |
+ {
|
|
|
8178f7 |
+ insn = emit_move_insn (mem, reg1);
|
|
|
8178f7 |
+ RTX_FRAME_RELATED_P (insn) = 1;
|
|
|
8178f7 |
+ }
|
|
|
8178f7 |
else
|
|
|
8178f7 |
{
|
|
|
8178f7 |
- insn = emit_move_insn (gen_rtx_REG (DImode, regno), mem);
|
|
|
8178f7 |
- add_reg_note (insn, REG_CFA_RESTORE, gen_rtx_REG (DImode, regno));
|
|
|
8178f7 |
+ emit_move_insn (reg1, mem);
|
|
|
8178f7 |
+ *cfi_ops = alloc_reg_note (REG_CFA_RESTORE, reg1, *cfi_ops);
|
|
|
8178f7 |
}
|
|
|
8178f7 |
start_offset += increment;
|
|
|
8178f7 |
}
|
|
|
8178f7 |
- RTX_FRAME_RELATED_P (insn) = 1;
|
|
|
8178f7 |
}
|
|
|
8178f7 |
}
|
|
|
8178f7 |
|
|
|
8178f7 |
- aarch64_save_or_restore_fprs (start_offset, increment, restore, base_rtx);
|
|
|
8178f7 |
-
|
|
|
8178f7 |
+ aarch64_save_or_restore_fprs (start_offset, increment, restore,
|
|
|
8178f7 |
+ base_rtx, cfi_ops);
|
|
|
8178f7 |
}
|
|
|
8178f7 |
|
|
|
8178f7 |
/* AArch64 stack frames generated by this compiler look like:
|
|
|
8178f7 |
@@ -1966,7 +1963,7 @@ aarch64_expand_prologue (void)
|
|
|
8178f7 |
}
|
|
|
8178f7 |
|
|
|
8178f7 |
aarch64_save_or_restore_callee_save_registers
|
|
|
8178f7 |
- (fp_offset + cfun->machine->frame.hardfp_offset, 0);
|
|
|
8178f7 |
+ (fp_offset + cfun->machine->frame.hardfp_offset, 0, NULL);
|
|
|
8178f7 |
}
|
|
|
8178f7 |
|
|
|
8178f7 |
/* when offset >= 512,
|
|
|
8178f7 |
@@ -1991,6 +1988,7 @@ aarch64_expand_epilogue (bool for_sibcal
|
|
|
8178f7 |
HOST_WIDE_INT fp_offset;
|
|
|
8178f7 |
rtx insn;
|
|
|
8178f7 |
rtx cfa_reg;
|
|
|
8178f7 |
+ rtx cfi_ops = NULL;
|
|
|
8178f7 |
|
|
|
8178f7 |
aarch64_layout_frame ();
|
|
|
8178f7 |
original_frame_size = get_frame_size () + cfun->machine->saved_varargs_size;
|
|
|
8178f7 |
@@ -2035,15 +2033,17 @@ aarch64_expand_epilogue (bool for_sibcal
|
|
|
8178f7 |
insn = emit_insn (gen_add3_insn (stack_pointer_rtx,
|
|
|
8178f7 |
hard_frame_pointer_rtx,
|
|
|
8178f7 |
GEN_INT (- fp_offset)));
|
|
|
8178f7 |
+ /* CFA should be calculated from the value of SP from now on. */
|
|
|
8178f7 |
+ add_reg_note (insn, REG_CFA_ADJUST_CFA,
|
|
|
8178f7 |
+ gen_rtx_SET (VOIDmode, stack_pointer_rtx,
|
|
|
8178f7 |
+ plus_constant (Pmode, hard_frame_pointer_rtx,
|
|
|
8178f7 |
+ -fp_offset)));
|
|
|
8178f7 |
RTX_FRAME_RELATED_P (insn) = 1;
|
|
|
8178f7 |
- /* As SP is set to (FP - fp_offset), according to the rules in
|
|
|
8178f7 |
- dwarf2cfi.c:dwarf2out_frame_debug_expr, CFA should be calculated
|
|
|
8178f7 |
- from the value of SP from now on. */
|
|
|
8178f7 |
cfa_reg = stack_pointer_rtx;
|
|
|
8178f7 |
}
|
|
|
8178f7 |
|
|
|
8178f7 |
aarch64_save_or_restore_callee_save_registers
|
|
|
8178f7 |
- (fp_offset + cfun->machine->frame.hardfp_offset, 1);
|
|
|
8178f7 |
+ (fp_offset + cfun->machine->frame.hardfp_offset, 1, &cfi_ops);
|
|
|
8178f7 |
|
|
|
8178f7 |
/* Restore the frame pointer and lr if the frame pointer is needed. */
|
|
|
8178f7 |
if (offset > 0)
|
|
|
8178f7 |
@@ -2051,6 +2051,8 @@ aarch64_expand_epilogue (bool for_sibcal
|
|
|
8178f7 |
if (frame_pointer_needed)
|
|
|
8178f7 |
{
|
|
|
8178f7 |
rtx mem_fp, mem_lr;
|
|
|
8178f7 |
+ rtx reg_fp = hard_frame_pointer_rtx;
|
|
|
8178f7 |
+ rtx reg_lr = gen_rtx_REG (DImode, LR_REGNUM);
|
|
|
8178f7 |
|
|
|
8178f7 |
if (fp_offset)
|
|
|
8178f7 |
{
|
|
|
8178f7 |
@@ -2063,52 +2065,36 @@ aarch64_expand_epilogue (bool for_sibcal
|
|
|
8178f7 |
stack_pointer_rtx,
|
|
|
8178f7 |
fp_offset
|
|
|
8178f7 |
+ UNITS_PER_WORD));
|
|
|
8178f7 |
- insn = emit_insn (gen_load_pairdi (hard_frame_pointer_rtx,
|
|
|
8178f7 |
- mem_fp,
|
|
|
8178f7 |
- gen_rtx_REG (DImode,
|
|
|
8178f7 |
- LR_REGNUM),
|
|
|
8178f7 |
- mem_lr));
|
|
|
8178f7 |
+ emit_insn (gen_load_pairdi (reg_fp, mem_fp, reg_lr, mem_lr));
|
|
|
8178f7 |
+
|
|
|
8178f7 |
+ insn = emit_insn (gen_add2_insn (stack_pointer_rtx,
|
|
|
8178f7 |
+ GEN_INT (offset)));
|
|
|
8178f7 |
}
|
|
|
8178f7 |
else
|
|
|
8178f7 |
{
|
|
|
8178f7 |
insn = emit_insn (gen_loadwb_pairdi_di
|
|
|
8178f7 |
- (stack_pointer_rtx,
|
|
|
8178f7 |
- stack_pointer_rtx,
|
|
|
8178f7 |
- hard_frame_pointer_rtx,
|
|
|
8178f7 |
- gen_rtx_REG (DImode, LR_REGNUM),
|
|
|
8178f7 |
- GEN_INT (offset),
|
|
|
8178f7 |
+ (stack_pointer_rtx, stack_pointer_rtx,
|
|
|
8178f7 |
+ reg_fp, reg_lr, GEN_INT (offset),
|
|
|
8178f7 |
GEN_INT (GET_MODE_SIZE (DImode) + offset)));
|
|
|
8178f7 |
- RTX_FRAME_RELATED_P (XVECEXP (PATTERN (insn), 0, 2)) = 1;
|
|
|
8178f7 |
- add_reg_note (insn, REG_CFA_ADJUST_CFA,
|
|
|
8178f7 |
- (gen_rtx_SET (Pmode, stack_pointer_rtx,
|
|
|
8178f7 |
- plus_constant (Pmode, cfa_reg,
|
|
|
8178f7 |
- offset))));
|
|
|
8178f7 |
- }
|
|
|
8178f7 |
-
|
|
|
8178f7 |
- /* The first part of a frame-related parallel insn
|
|
|
8178f7 |
- is always assumed to be relevant to the frame
|
|
|
8178f7 |
- calculations; subsequent parts, are only
|
|
|
8178f7 |
- frame-related if explicitly marked. */
|
|
|
8178f7 |
- RTX_FRAME_RELATED_P (XVECEXP (PATTERN (insn), 0, 1)) = 1;
|
|
|
8178f7 |
- RTX_FRAME_RELATED_P (insn) = 1;
|
|
|
8178f7 |
- add_reg_note (insn, REG_CFA_RESTORE, hard_frame_pointer_rtx);
|
|
|
8178f7 |
- add_reg_note (insn, REG_CFA_RESTORE,
|
|
|
8178f7 |
- gen_rtx_REG (DImode, LR_REGNUM));
|
|
|
8178f7 |
-
|
|
|
8178f7 |
- if (fp_offset)
|
|
|
8178f7 |
- {
|
|
|
8178f7 |
- insn = emit_insn (gen_add2_insn (stack_pointer_rtx,
|
|
|
8178f7 |
- GEN_INT (offset)));
|
|
|
8178f7 |
- RTX_FRAME_RELATED_P (insn) = 1;
|
|
|
8178f7 |
}
|
|
|
8178f7 |
+ cfi_ops = alloc_reg_note (REG_CFA_RESTORE, reg_fp, cfi_ops);
|
|
|
8178f7 |
+ cfi_ops = alloc_reg_note (REG_CFA_RESTORE, reg_lr, cfi_ops);
|
|
|
8178f7 |
}
|
|
|
8178f7 |
else
|
|
|
8178f7 |
{
|
|
|
8178f7 |
insn = emit_insn (gen_add2_insn (stack_pointer_rtx,
|
|
|
8178f7 |
GEN_INT (offset)));
|
|
|
8178f7 |
- RTX_FRAME_RELATED_P (insn) = 1;
|
|
|
8178f7 |
}
|
|
|
8178f7 |
+ cfi_ops = alloc_reg_note (REG_CFA_ADJUST_CFA,
|
|
|
8178f7 |
+ gen_rtx_SET (VOIDmode, stack_pointer_rtx,
|
|
|
8178f7 |
+ plus_constant (Pmode, cfa_reg,
|
|
|
8178f7 |
+ offset)),
|
|
|
8178f7 |
+ cfi_ops);
|
|
|
8178f7 |
+ REG_NOTES (insn) = cfi_ops;
|
|
|
8178f7 |
+ RTX_FRAME_RELATED_P (insn) = 1;
|
|
|
8178f7 |
}
|
|
|
8178f7 |
+ else
|
|
|
8178f7 |
+ gcc_assert (cfi_ops == NULL);
|
|
|
8178f7 |
|
|
|
8178f7 |
/* Stack adjustment for exception handler. */
|
|
|
8178f7 |
if (crtl->calls_eh_return)
|