diff options
Diffstat (limited to 'gcc/config/arm/arm.cc')
-rw-r--r-- | gcc/config/arm/arm.cc | 42 |
1 files changed, 34 insertions, 8 deletions
diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc index b499cd2cfed..cb77efae0d9 100644 --- a/gcc/config/arm/arm.cc +++ b/gcc/config/arm/arm.cc @@ -22156,7 +22156,9 @@ emit_multi_reg_push (unsigned long mask, unsigned long dwarf_regs_mask) { if (mask & (1 << i)) { - reg = gen_rtx_REG (SImode, i); + rtx reg1 = reg = gen_rtx_REG (SImode, i); + if (arm_current_function_pac_enabled_p () && i == IP_REGNUM) + reg1 = gen_rtx_REG (SImode, RA_AUTH_CODE); XVECEXP (par, 0, 0) = gen_rtx_SET (gen_frame_mem @@ -22173,8 +22175,12 @@ emit_multi_reg_push (unsigned long mask, unsigned long dwarf_regs_mask) if (dwarf_regs_mask & (1 << i)) { + /* Only the first register in the multi push instruction is stored + to frame memory here. + Eg: push {r7 ,r8, ip, lr} + Only r7 is stored to frame memory here. */ tmp = gen_rtx_SET (gen_frame_mem (SImode, stack_pointer_rtx), - reg); + reg1); RTX_FRAME_RELATED_P (tmp) = 1; XVECEXP (dwarf, 0, dwarf_par_index++) = tmp; } @@ -22187,18 +22193,25 @@ emit_multi_reg_push (unsigned long mask, unsigned long dwarf_regs_mask) { if (mask & (1 << i)) { - reg = gen_rtx_REG (SImode, i); + rtx reg1 = reg = gen_rtx_REG (SImode, i); + if (arm_current_function_pac_enabled_p () && i == IP_REGNUM) + reg1 = gen_rtx_REG (SImode, RA_AUTH_CODE); XVECEXP (par, 0, j) = gen_rtx_USE (VOIDmode, reg); if (dwarf_regs_mask & (1 << i)) { + /* Except the first register in the multi push instruction all the + remaining registers are stored to frame memory here. + Eg: push {r7, r8, ip, lr} + r8, ip (ra_auth_code in case PACBTI enabled) and lr registers + are stored to frame memory here. */ tmp = gen_rtx_SET (gen_frame_mem (SImode, plus_constant (Pmode, stack_pointer_rtx, 4 * j)), - reg); + reg1); RTX_FRAME_RELATED_P (tmp) = 1; XVECEXP (dwarf, 0, dwarf_par_index++) = tmp; } @@ -22283,7 +22296,9 @@ arm_emit_multi_reg_pop (unsigned long saved_regs_mask) for (j = 0, i = 0; j < num_regs; i++) if (saved_regs_mask & (1 << i)) { - reg = gen_rtx_REG (SImode, i); + rtx reg1 = reg = gen_rtx_REG (SImode, i); + if (arm_current_function_pac_enabled_p () && i == IP_REGNUM) + reg1 = gen_rtx_REG (SImode, RA_AUTH_CODE); if ((num_regs == 1) && emit_update && !return_in_pc) { /* Emit single load with writeback. */ @@ -22291,7 +22306,7 @@ arm_emit_multi_reg_pop (unsigned long saved_regs_mask) gen_rtx_POST_INC (Pmode, stack_pointer_rtx)); tmp = emit_insn (gen_rtx_SET (reg, tmp)); - REG_NOTES (tmp) = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf); + REG_NOTES (tmp) = alloc_reg_note (REG_CFA_RESTORE, reg1, dwarf); return; } @@ -22305,7 +22320,7 @@ arm_emit_multi_reg_pop (unsigned long saved_regs_mask) /* We need to maintain a sequence for DWARF info too. As dwarf info should not have PC, skip PC. */ if (i != PC_REGNUM) - dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf); + dwarf = alloc_reg_note (REG_CFA_RESTORE, reg1, dwarf); j++; } @@ -25600,6 +25615,9 @@ arm_regno_class (int regno) if (IS_VPR_REGNUM (regno)) return VPR_REG; + if (IS_PAC_Pseudo_REGNUM (regno)) + return PAC_REG; + if (TARGET_THUMB1) { if (regno == STACK_POINTER_REGNUM) @@ -29571,6 +29589,9 @@ arm_dbx_register_number (unsigned int regno) if (IS_IWMMXT_REGNUM (regno)) return 112 + regno - FIRST_IWMMXT_REGNUM; + if (IS_PAC_Pseudo_REGNUM (regno)) + return 143; + return DWARF_FRAME_REGISTERS; } @@ -29664,7 +29685,7 @@ arm_unwind_emit_sequence (FILE * out_file, rtx p) gcc_assert (nregs); reg = REGNO (SET_SRC (XVECEXP (p, 0, 1))); - if (reg < 16) + if (reg < 16 || IS_PAC_Pseudo_REGNUM (reg)) { /* For -Os dummy registers can be pushed at the beginning to avoid separate stack pointer adjustment. */ @@ -29721,6 +29742,8 @@ arm_unwind_emit_sequence (FILE * out_file, rtx p) double precision register names. */ if (IS_VFP_REGNUM (reg)) asm_fprintf (out_file, "d%d", (reg - FIRST_VFP_REGNUM) / 2); + else if (IS_PAC_Pseudo_REGNUM (reg)) + asm_fprintf (asm_out_file, "ra_auth_code"); else asm_fprintf (out_file, "%r", reg); @@ -30588,6 +30611,9 @@ arm_conditional_register_usage (void) global_regs[ARM_HARD_FRAME_POINTER_REGNUM] = 1; } + if (TARGET_HAVE_PACBTI) + fixed_regs[RA_AUTH_CODE] = 0; + /* The Q and GE bits are only accessed via special ACLE patterns. */ CLEAR_HARD_REG_BIT (operand_reg_set, APSRQ_REGNUM); CLEAR_HARD_REG_BIT (operand_reg_set, APSRGE_REGNUM); |