RISC-V: Change sp subtracts so prologue stores can compress.
authorJim Wilson <jimw@sifive.com>
Thu, 15 Feb 2018 01:14:23 +0000 (01:14 +0000)
committerJim Wilson <wilson@gcc.gnu.org>
Thu, 15 Feb 2018 01:14:23 +0000 (17:14 -0800)
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
gcc/config/riscv/riscv.c
gcc/config/riscv/riscv.h

index 29996a9abe072e7598bdaa91e8829cc04a3c510a..7c30a1ed0db63a761b0805d9247b5c4dd0532638 100644 (file)
@@ -1,3 +1,10 @@
+2018-02-14  Jim Wilson  <jimw@sifive.com>
+
+       * 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  <indu.bhagat@oracle.com>
 
        * doc/invoke.texi: Correct -Wformat-overflow code sample.
index 4ef7a1774c4bba25c1da7b3c552f89c48b4f8bbb..c38f6c394d54057fd6a6058e438bc5d565e49709 100644 (file)
@@ -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;
 }
 
index 1c1c3431119d49b8f5eb6e46f3f4c60306b958df..6144e267727731215c67e4a504528b0e48373ad7 100644 (file)
@@ -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 */