From 10789329789fbb5b87883fca029e745a06ded6a0 Mon Sep 17 00:00:00 2001 From: Jim Wilson Date: Thu, 15 Feb 2018 01:14:23 +0000 Subject: [PATCH] RISC-V: Change sp subtracts so prologue stores can compress. gcc/ * config/riscv/riscv.c (riscv_first_stack_step): Move locals after first SMALL_OPERAND check. New local min_second_step. Move assert to where locals are set. Add TARGET_RVC support. * config/riscv/riscv.h (C_SxSP_BITS, SWSP_REACH, SDSP_REACH): New. From-SVN: r257681 --- gcc/ChangeLog | 7 +++++++ gcc/config/riscv/riscv.c | 30 ++++++++++++++++++++++++------ gcc/config/riscv/riscv.h | 4 ++++ 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 29996a9abe0..7c30a1ed0db 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2018-02-14 Jim Wilson + + * config/riscv/riscv.c (riscv_first_stack_step): Move locals after + first SMALL_OPERAND check. New local min_second_step. Move assert + to where locals are set. Add TARGET_RVC support. + * config/riscv/riscv.h (C_SxSP_BITS, SWSP_REACH, SDSP_REACH): New. + 2018-02-14 Indu Bhagat * doc/invoke.texi: Correct -Wformat-overflow code sample. diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c index 4ef7a1774c4..c38f6c394d5 100644 --- a/gcc/config/riscv/riscv.c +++ b/gcc/config/riscv/riscv.c @@ -3495,25 +3495,43 @@ riscv_output_gpr_save (unsigned mask) /* For stack frames that can't be allocated with a single ADDI instruction, compute the best value to initially allocate. It must at a minimum - allocate enough space to spill the callee-saved registers. */ + allocate enough space to spill the callee-saved registers. If TARGET_RVC, + try to pick a value that will allow compression of the register saves + without adding extra instructions. */ static HOST_WIDE_INT riscv_first_stack_step (struct riscv_frame_info *frame) { - HOST_WIDE_INT min_first_step = frame->total_size - frame->fp_sp_offset; - HOST_WIDE_INT max_first_step = IMM_REACH / 2 - STACK_BOUNDARY / 8; - if (SMALL_OPERAND (frame->total_size)) return frame->total_size; + HOST_WIDE_INT min_first_step = frame->total_size - frame->fp_sp_offset; + HOST_WIDE_INT max_first_step = IMM_REACH / 2 - STACK_BOUNDARY / 8; + HOST_WIDE_INT min_second_step = frame->total_size - max_first_step; + gcc_assert (min_first_step <= max_first_step); + /* As an optimization, use the least-significant bits of the total frame size, so that the second adjustment step is just LUI + ADD. */ - if (!SMALL_OPERAND (frame->total_size - max_first_step) + if (!SMALL_OPERAND (min_second_step) && frame->total_size % IMM_REACH < IMM_REACH / 2 && frame->total_size % IMM_REACH >= min_first_step) return frame->total_size % IMM_REACH; - gcc_assert (min_first_step <= max_first_step); + if (TARGET_RVC) + { + /* If we need two subtracts, and one is small enough to allow compressed + loads and stores, then put that one first. */ + if (IN_RANGE (min_second_step, 0, + (TARGET_64BIT ? SDSP_REACH : SWSP_REACH))) + return MAX (min_second_step, min_first_step); + + /* If we need LUI + ADDI + ADD for the second adjustment step, then start + with the minimum first step, so that we can get compressed loads and + stores. */ + else if (!SMALL_OPERAND (min_second_step)) + return min_first_step; + } + return max_first_step; } diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h index 1c1c3431119..6144e267727 100644 --- a/gcc/config/riscv/riscv.h +++ b/gcc/config/riscv/riscv.h @@ -891,9 +891,13 @@ extern unsigned riscv_stack_boundary; #define SHIFT_RS1 15 #define SHIFT_IMM 20 #define IMM_BITS 12 +#define C_SxSP_BITS 6 #define IMM_REACH (1LL << IMM_BITS) #define CONST_HIGH_PART(VALUE) (((VALUE) + (IMM_REACH/2)) & ~(IMM_REACH-1)) #define CONST_LOW_PART(VALUE) ((VALUE) - CONST_HIGH_PART (VALUE)) +#define SWSP_REACH (4LL << C_SxSP_BITS) +#define SDSP_REACH (8LL << C_SxSP_BITS) + #endif /* ! GCC_RISCV_H */ -- 2.30.2