From 0a7cb71d302afd717e4338040f66f059c7811a9f Mon Sep 17 00:00:00 2001 From: thopre01 Date: Wed, 22 Nov 2017 13:32:21 +0000 Subject: [PATCH] [ARM] Use bitmap to control cmse_nonsecure_call register clearing As part of r253256, cmse_nonsecure_entry_clear_before_return has been rewritten to use auto_sbitmap instead of an integer bitfield to control which register needs to be cleared. This commit continues this work in cmse_nonsecure_call_clear_caller_saved. 2017-11-22 Thomas Preud'homme gcc/ * config/arm/arm.c (cmse_nonsecure_call_clear_caller_saved): Use auto_sbitap instead of integer bitfield to control register needing clearing. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@255055 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 6 ++++++ gcc/config/arm/arm.c | 46 ++++++++++++++++++++++++++++++---------------- 2 files changed, 36 insertions(+), 16 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e4936c695ba..8cefff5ad2e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2017-11-22 Thomas Preud'homme + + * config/arm/arm.c (cmse_nonsecure_call_clear_caller_saved): Use + auto_sbitap instead of integer bitfield to control register needing + clearing. + 2017-11-22 Jakub Jelinek PR tree-optimization/83044 diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 1c2f8fa8f80..36f35573c88 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -17008,10 +17008,11 @@ cmse_nonsecure_call_clear_caller_saved (void) FOR_BB_INSNS (bb, insn) { - uint64_t to_clear_mask, float_mask; + unsigned address_regnum, regno, maxregno = + TARGET_HARD_FLOAT_ABI ? D7_VFP_REGNUM : NUM_ARG_REGS - 1; + auto_sbitmap to_clear_bitmap (maxregno + 1); rtx_insn *seq; rtx pat, call, unspec, reg, cleared_reg, tmp; - unsigned int regno, maxregno; rtx address; CUMULATIVE_ARGS args_so_far_v; cumulative_args_t args_so_far; @@ -17042,18 +17043,21 @@ cmse_nonsecure_call_clear_caller_saved (void) continue; /* Determine the caller-saved registers we need to clear. */ - to_clear_mask = (1LL << (NUM_ARG_REGS)) - 1; - maxregno = NUM_ARG_REGS - 1; + bitmap_clear (to_clear_bitmap); + bitmap_set_range (to_clear_bitmap, R0_REGNUM, NUM_ARG_REGS); + /* Only look at the caller-saved floating point registers in case of -mfloat-abi=hard. For -mfloat-abi=softfp we will be using the lazy store and loads which clear both caller- and callee-saved registers. */ if (TARGET_HARD_FLOAT_ABI) { - float_mask = (1LL << (D7_VFP_REGNUM + 1)) - 1; - float_mask &= ~((1LL << FIRST_VFP_REGNUM) - 1); - to_clear_mask |= float_mask; - maxregno = D7_VFP_REGNUM; + auto_sbitmap float_bitmap (maxregno + 1); + + bitmap_clear (float_bitmap); + bitmap_set_range (float_bitmap, FIRST_VFP_REGNUM, + D7_VFP_REGNUM - FIRST_VFP_REGNUM + 1); + bitmap_ior (to_clear_bitmap, to_clear_bitmap, float_bitmap); } /* Make sure the register used to hold the function address is not @@ -17061,7 +17065,9 @@ cmse_nonsecure_call_clear_caller_saved (void) address = RTVEC_ELT (XVEC (unspec, 0), 0); gcc_assert (MEM_P (address)); gcc_assert (REG_P (XEXP (address, 0))); - to_clear_mask &= ~(1LL << REGNO (XEXP (address, 0))); + address_regnum = REGNO (XEXP (address, 0)); + if (address_regnum < R0_REGNUM + NUM_ARG_REGS) + bitmap_clear_bit (to_clear_bitmap, address_regnum); /* Set basic block of call insn so that df rescan is performed on insns inserted here. */ @@ -17082,6 +17088,7 @@ cmse_nonsecure_call_clear_caller_saved (void) FOREACH_FUNCTION_ARGS (fntype, arg_type, args_iter) { rtx arg_rtx; + uint64_t to_clear_args_mask; machine_mode arg_mode = TYPE_MODE (arg_type); if (VOID_TYPE_P (arg_type)) @@ -17094,10 +17101,18 @@ cmse_nonsecure_call_clear_caller_saved (void) arg_rtx = arm_function_arg (args_so_far, arg_mode, arg_type, true); gcc_assert (REG_P (arg_rtx)); - to_clear_mask - &= ~compute_not_to_clear_mask (arg_type, arg_rtx, - REGNO (arg_rtx), - padding_bits_to_clear_ptr); + to_clear_args_mask + = compute_not_to_clear_mask (arg_type, arg_rtx, + REGNO (arg_rtx), + padding_bits_to_clear_ptr); + if (to_clear_args_mask) + { + for (regno = R0_REGNUM; regno <= maxregno; regno++) + { + if (to_clear_args_mask & (1ULL << regno)) + bitmap_clear_bit (to_clear_bitmap, regno); + } + } first_param = false; } @@ -17156,7 +17171,7 @@ cmse_nonsecure_call_clear_caller_saved (void) call. */ for (regno = R0_REGNUM; regno <= maxregno; regno++) { - if (!(to_clear_mask & (1LL << regno))) + if (!bitmap_bit_p (to_clear_bitmap, regno)) continue; /* If regno is an even vfp register and its successor is also to @@ -17165,7 +17180,7 @@ cmse_nonsecure_call_clear_caller_saved (void) { if (TARGET_VFP_DOUBLE && VFP_REGNO_OK_FOR_DOUBLE (regno) - && to_clear_mask & (1LL << (regno + 1))) + && bitmap_bit_p (to_clear_bitmap, (regno + 1))) emit_move_insn (gen_rtx_REG (DFmode, regno++), CONST0_RTX (DFmode)); else @@ -17179,7 +17194,6 @@ cmse_nonsecure_call_clear_caller_saved (void) seq = get_insns (); end_sequence (); emit_insn_before (seq, insn); - } } } -- 2.11.4.GIT