From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2098) id C6246385842E; Fri, 12 Aug 2022 20:01:45 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C6246385842E Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: SRINATH PARVATHANENI To: gcc-cvs@gcc.gnu.org Subject: [gcc(refs/vendors/ARM/heads/arm-12-pacbti)] [GCC][PATCH] arm: Add support for dwarf debug directives and pseudo hard-register for PAC feature. X-Act-Checkin: gcc X-Git-Author: Srinath Parvathaneni X-Git-Refname: refs/vendors/ARM/heads/arm-12-pacbti X-Git-Oldrev: 46ec5779591d4575156b23cb055d4d6695d887fa X-Git-Newrev: 5505e61abff7f4bc249435beaf12cc4946284cbe Message-Id: <20220812200145.C6246385842E@sourceware.org> Date: Fri, 12 Aug 2022 20:01:45 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 12 Aug 2022 20:01:45 -0000 https://gcc.gnu.org/g:5505e61abff7f4bc249435beaf12cc4946284cbe commit 5505e61abff7f4bc249435beaf12cc4946284cbe Author: Srinath Parvathaneni Date: Fri Aug 12 20:50:48 2022 +0100 [GCC][PATCH] arm: Add support for dwarf debug directives and pseudo hard-register for PAC feature. Hello, This patch teaches the DWARF support in gcc about RA_AUTH_CODE pseudo hard-register and also .save {ra_auth_code} and .cfi_offset ra_auth_code dwarf directives for the PAC feature in Armv8.1-M architecture. RA_AUTH_CODE register number is 107 and it's dwarf register number is 143. When compiled with " -march=armv8.1-m.main -mbranch-protection=pac-ret+leaf+bti -mthumb -mfloat-abi=soft -fasynchronous-unwind-tables -g -O2 -S" command line options, the assembly output after this patch looks like below: ... .cfi_startproc pacbti ip, lr, sp movs r1, #40 push {ip, lr} .save {ra_auth_code, lr} .cfi_def_cfa_offset 8 .cfi_offset 143, -8 .cfi_offset 14, -4 ... pop {ip, lr} .cfi_restore 14 .cfi_restore 143 .cfi_def_cfa_offset 0 movs r0, #0 aut ip, lr, sp bx lr .cfi_endproc ... This patch can be committed after the patch at https://gcc.gnu.org/pipermail/gcc-patches/2021-November/583407.html is committed. Regression tested on arm-none-eabi target and found no regressions. Ok for master? Regards, Srinath. gcc/ChangeLog: 2022-04-06 Srinath Parvathaneni * config/arm/aout.h (ra_auth_code): Add to enum. * config/arm/arm.cc (emit_multi_reg_push): Add RA_AUTH_CODE register to dwarf frame expression. (arm_emit_multi_reg_pop): Restore RA_AUTH_CODE register. (arm_expand_prologue): Mark as frame related insn. (arm_regno_class): Check for pac pseudo reigster. (arm_dbx_register_number): Assign ra_auth_code register number in dwarf. (arm_unwind_emit_sequence): Print .save directive with ra_auth_code register. (arm_conditional_register_usage): Mark ra_auth_code in fixed reigsters. * config/arm/arm.h (FIRST_PSEUDO_REGISTER): Modify. (IS_PAC_Pseudo_REGNUM): Define. (enum reg_class): Add PAC_REG entry. * config/arm/arm.md (RA_AUTH_CODE): Define. gcc/testsuite/ChangeLog: 2022-04-06 Srinath Parvathaneni * g++.target/arm/pac-1.C: New test. * gcc.target/arm/pac-9.c: Likewise. Diff: --- gcc/config/arm/aout.h | 3 ++- gcc/config/arm/arm.cc | 45 ++++++++++++++++++++++++++++++------ gcc/config/arm/arm.h | 19 ++++++++++----- gcc/config/arm/arm.md | 1 + gcc/testsuite/g++.target/arm/pac-1.C | 33 ++++++++++++++++++++++++++ gcc/testsuite/gcc.target/arm/pac-9.c | 21 +++++++++++++++++ 6 files changed, 108 insertions(+), 14 deletions(-) diff --git a/gcc/config/arm/aout.h b/gcc/config/arm/aout.h index b918ad3782f..ffeed45a678 100644 --- a/gcc/config/arm/aout.h +++ b/gcc/config/arm/aout.h @@ -74,7 +74,8 @@ "wr8", "wr9", "wr10", "wr11", \ "wr12", "wr13", "wr14", "wr15", \ "wcgr0", "wcgr1", "wcgr2", "wcgr3", \ - "cc", "vfpcc", "sfp", "afp", "apsrq", "apsrge", "p0" \ + "cc", "vfpcc", "sfp", "afp", "apsrq", "apsrge", "p0", \ + "ra_auth_code" \ } #endif diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc index b499cd2cfed..319bfb24c3f 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; } @@ -29692,6 +29713,11 @@ arm_unwind_emit_sequence (FILE * out_file, rtx p) reg_size = 8; fprintf (out_file, "\t.vsave {"); } + else if (IS_PAC_Pseudo_REGNUM (reg)) + { + reg_size = 4; + fprintf (out_file, "\t.save {"); + } else /* Unknown register type. */ gcc_unreachable (); @@ -29721,6 +29747,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 +30616,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); diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index 3495ab857ea..c7777706781 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -816,7 +816,8 @@ extern const int arm_arch_cde_coproc_bits[]; s16-s31 S VFP variable (aka d8-d15). vfpcc Not a real register. Represents the VFP condition code flags. - vpr Used to represent MVE VPR predication. */ + vpr Used to represent MVE VPR predication. + ra_auth_code Pseudo register to save PAC. */ /* The stack backtrace structure is as follows: fp points to here: | save code pointer | [fp] @@ -857,7 +858,7 @@ extern const int arm_arch_cde_coproc_bits[]; 1,1,1,1,1,1,1,1, \ 1,1,1,1, \ /* Specials. */ \ - 1,1,1,1,1,1,1 \ + 1,1,1,1,1,1,1,1 \ } /* 1 for registers not available across function calls. @@ -887,7 +888,7 @@ extern const int arm_arch_cde_coproc_bits[]; 1,1,1,1,1,1,1,1, \ 1,1,1,1, \ /* Specials. */ \ - 1,1,1,1,1,1,1 \ + 1,1,1,1,1,1,1,1 \ } #ifndef SUBTARGET_CONDITIONAL_REGISTER_USAGE @@ -1063,10 +1064,10 @@ extern const int arm_arch_cde_coproc_bits[]; && (LAST_VFP_REGNUM - (REGNUM) >= 2 * (N) - 1)) /* The number of hard registers is 16 ARM + 1 CC + 1 SFP + 1 AFP - + 1 APSRQ + 1 APSRGE + 1 VPR. */ + + 1 APSRQ + 1 APSRGE + 1 VPR + 1 Pseudo register to save PAC. */ /* Intel Wireless MMX Technology registers add 16 + 4 more. */ /* VFP (VFP3) adds 32 (64) + 1 VFPCC. */ -#define FIRST_PSEUDO_REGISTER 107 +#define FIRST_PSEUDO_REGISTER 108 #define DBX_REGISTER_NUMBER(REGNO) arm_dbx_register_number (REGNO) @@ -1253,12 +1254,15 @@ extern int arm_regs_in_sequence[]; CC_REGNUM, VFPCC_REGNUM, \ FRAME_POINTER_REGNUM, ARG_POINTER_REGNUM, \ SP_REGNUM, PC_REGNUM, APSRQ_REGNUM, \ - APSRGE_REGNUM, VPR_REGNUM \ + APSRGE_REGNUM, VPR_REGNUM, RA_AUTH_CODE \ } #define IS_VPR_REGNUM(REGNUM) \ ((REGNUM) == VPR_REGNUM) +#define IS_PAC_Pseudo_REGNUM(REGNUM) \ + ((REGNUM) == RA_AUTH_CODE) + /* Use different register alloc ordering for Thumb. */ #define ADJUST_REG_ALLOC_ORDER arm_order_regs_for_local_alloc () @@ -1297,6 +1301,7 @@ enum reg_class SFP_REG, AFP_REG, VPR_REG, + PAC_REG, GENERAL_AND_VPR_REGS, ALL_REGS, LIM_REG_CLASSES @@ -1327,6 +1332,7 @@ enum reg_class "SFP_REG", \ "AFP_REG", \ "VPR_REG", \ + "PAC_REG", \ "GENERAL_AND_VPR_REGS", \ "ALL_REGS" \ } @@ -1356,6 +1362,7 @@ enum reg_class { 0x00000000, 0x00000000, 0x00000000, 0x00000040 }, /* SFP_REG */ \ { 0x00000000, 0x00000000, 0x00000000, 0x00000080 }, /* AFP_REG */ \ { 0x00000000, 0x00000000, 0x00000000, 0x00000400 }, /* VPR_REG. */ \ + { 0x00000000, 0x00000000, 0x00000000, 0x00000800 }, /* PAC_REG. */ \ { 0x00005FFF, 0x00000000, 0x00000000, 0x00000400 }, /* GENERAL_AND_VPR_REGS. */ \ { 0xFFFF7FFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000040F } /* ALL_REGS. */ \ } diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 90c8c1d66f5..96079e7d760 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -42,6 +42,7 @@ (APSRQ_REGNUM 104) ; Q bit pseudo register (APSRGE_REGNUM 105) ; GE bits pseudo register (VPR_REGNUM 106) ; Vector Predication Register - MVE register. + (RA_AUTH_CODE 107) ; Pseudo register to save PAC. ] ) ;; 3rd operand to select_dominance_cc_mode diff --git a/gcc/testsuite/g++.target/arm/pac-1.C b/gcc/testsuite/g++.target/arm/pac-1.C new file mode 100644 index 00000000000..b447213ab4e --- /dev/null +++ b/gcc/testsuite/g++.target/arm/pac-1.C @@ -0,0 +1,33 @@ +/* Check that GCC does .save and .cfi_offset directives with RA_AUTH_CODE pseudo hard-register. */ +/* { dg-do compile } */ +/* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-marm" "-mcpu=*" } } */ +/* { dg-options "-march=armv8.1-m.main -mbranch-protection=pac-ret+leaf+bti -mthumb -mfloat-abi=soft --save-temps -g" } */ + +__attribute__((noinline)) void +fn1 (int a, int b, int c) +{ + if (a != b + c) + __builtin_abort (); + else + throw b+c; +} + +int main () +{ + int a = 120; + try + { + fn1 (a, 40, 80); + } + catch (int x) + { + if (x != a) + __builtin_abort (); + else + return 0; + } +} + +/* { dg-final { scan-assembler "\.save \{r7, ra_auth_code, lr\}" } } */ +/* { dg-final { scan-assembler "\.save \{r4, r7, ra_auth_code, lr\}" } } */ +/* { dg-final { scan-assembler "\.cfi_offset 143, \-8" } } */ diff --git a/gcc/testsuite/gcc.target/arm/pac-9.c b/gcc/testsuite/gcc.target/arm/pac-9.c new file mode 100644 index 00000000000..2a69db6e8e8 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/pac-9.c @@ -0,0 +1,21 @@ +/* Check that GCC does .save and .cfi_offset directives with RA_AUTH_CODE pseudo hard-register. */ +/* { dg-do compile } */ +/* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-marm" "-mcpu=*" } } */ +/* { dg-options "-march=armv8.1-m.main -mbranch-protection=pac-ret+leaf+bti -mthumb -mfloat-abi=soft -fasynchronous-unwind-tables --save-temps -g" } */ + +__attribute__((noinline)) void +fn1 (int a, int b, int c) +{ + if (a != b + c) + __builtin_abort (); +} + +int main () +{ + fn1 (40, 40, 80); + return 0; +} + +/* { dg-final { scan-assembler "\.save \{r7, ra_auth_code, lr\}" } } */ +/* { dg-final { scan-assembler "\.save \{r3, r7, ra_auth_code, lr\}" } } */ +/* { dg-final { scan-assembler "\.cfi_offset 143, \-8" } } */