Rewrite pic.md to improve medany and pic code size.
authorJim Wilson <jimw@sifive.com>
Wed, 29 Aug 2018 02:20:44 +0000 (02:20 +0000)
committerJim Wilson <wilson@gcc.gnu.org>
Wed, 29 Aug 2018 02:20:44 +0000 (19:20 -0700)
gcc/
* config/riscv/pic.md: Rewrite.
* config/riscv/riscv.c (riscv_address_insns): Return cost of 3 for
invalid address.
* config/riscv/riscv.md (ZERO_EXTEND_LOAD): Delete.
(SOFTF, default_load, softload, softstore): New.

From-SVN: r263943

gcc/ChangeLog
gcc/config/riscv/pic.md
gcc/config/riscv/riscv.c
gcc/config/riscv/riscv.md

index 8d35df7e96a423614966fc7c44050e6fed932179..c41507662dddf8cd2bdbc4f8fed495eb1b5467a9 100644 (file)
@@ -1,3 +1,11 @@
+2018-08-28  Jim Wilson  <jimw@sifive.com>
+
+       * config/riscv/pic.md: Rewrite.
+       * config/riscv/riscv.c (riscv_address_insns): Return cost of 3 for
+       invalid address.
+       * config/riscv/riscv.md (ZERO_EXTEND_LOAD): Delete.
+       (SOFTF, default_load, softload, softstore): New.
+
 2018-08-28  Jeff Law  <law@redhat.com>
 
        * fold-const.c (fold_binary_loc): Remove recently added assert.
index a4a9732656cf64b82500a2c7a2aff74dd7c69cee..942502058e0b923d5f541edba434373ede4b7258 100644 (file)
 ;; Simplify PIC loads to static variables.
 ;; These should go away once we figure out how to emit auipc discretely.
 
-(define_insn "*local_pic_load_s<mode>"
+(define_insn "*local_pic_load<mode>"
   [(set (match_operand:ANYI 0 "register_operand" "=r")
-       (sign_extend:ANYI (mem:ANYI (match_operand 1 "absolute_symbolic_operand" ""))))]
+       (mem:ANYI (match_operand 1 "absolute_symbolic_operand" "")))]
+  "USE_LOAD_ADDRESS_MACRO (operands[1])"
+  "<default_load>\t%0,%1"
+  [(set (attr "length") (const_int 8))])
+
+(define_insn "*local_pic_load_s<mode>"
+  [(set (match_operand:SUPERQI 0 "register_operand" "=r")
+       (sign_extend:SUPERQI (mem:SUBX (match_operand 1 "absolute_symbolic_operand" ""))))]
   "USE_LOAD_ADDRESS_MACRO (operands[1])"
-  "<load>\t%0,%1"
+  "<SUBX:load>\t%0,%1"
   [(set (attr "length") (const_int 8))])
 
 (define_insn "*local_pic_load_u<mode>"
-  [(set (match_operand:ZERO_EXTEND_LOAD 0 "register_operand" "=r")
-       (zero_extend:ZERO_EXTEND_LOAD (mem:ZERO_EXTEND_LOAD (match_operand 1 "absolute_symbolic_operand" ""))))]
+  [(set (match_operand:SUPERQI 0 "register_operand" "=r")
+       (zero_extend:SUPERQI (mem:SUBX (match_operand 1 "absolute_symbolic_operand" ""))))]
   "USE_LOAD_ADDRESS_MACRO (operands[1])"
-  "<load>u\t%0,%1"
+  "<SUBX:load>u\t%0,%1"
   [(set (attr "length") (const_int 8))])
 
-(define_insn "*local_pic_load<mode>"
-  [(set (match_operand:ANYF 0 "register_operand" "=f")
+;; We can support ANYF loads into X register if there is no double support
+;; or if the target is 64-bit.
+
+(define_insn "*local_pic_load<ANYF:mode>"
+  [(set (match_operand:ANYF 0 "register_operand" "=f,*r")
        (mem:ANYF (match_operand 1 "absolute_symbolic_operand" "")))
-   (clobber (match_scratch:DI 2 "=r"))]
-  "TARGET_HARD_FLOAT && TARGET_64BIT && USE_LOAD_ADDRESS_MACRO (operands[1])"
-  "<load>\t%0,%1,%2"
+   (clobber (match_scratch:P 2 "=r,X"))]
+  "TARGET_HARD_FLOAT && USE_LOAD_ADDRESS_MACRO (operands[1])
+   && (!TARGET_DOUBLE_FLOAT || TARGET_64BIT)"
+  "@
+   <ANYF:load>\t%0,%1,%2
+   <softload>\t%0,%1"
   [(set (attr "length") (const_int 8))])
 
-(define_insn "*local_pic_load<mode>"
+;; ??? For a 32-bit target with double float, a DF load into a X reg isn't
+;; supported.  ld is not valid in that case.  Punt for now.  Maybe add a split
+;; for this later.
+
+(define_insn "*local_pic_load_32d<ANYF:mode>"
   [(set (match_operand:ANYF 0 "register_operand" "=f")
        (mem:ANYF (match_operand 1 "absolute_symbolic_operand" "")))
-   (clobber (match_scratch:SI 2 "=r"))]
-  "TARGET_HARD_FLOAT && !TARGET_64BIT && USE_LOAD_ADDRESS_MACRO (operands[1])"
-  "<load>\t%0,%1,%2"
+   (clobber (match_scratch:P 2 "=r"))]
+  "TARGET_HARD_FLOAT && USE_LOAD_ADDRESS_MACRO (operands[1])
+   && (TARGET_DOUBLE_FLOAT && !TARGET_64BIT)"
+  "<ANYF:load>\t%0,%1,%2"
   [(set (attr "length") (const_int 8))])
 
-(define_insn "*local_pic_loadu<mode>"
-  [(set (match_operand:SUPERQI 0 "register_operand" "=r")
-       (zero_extend:SUPERQI (mem:SUBX (match_operand 1 "absolute_symbolic_operand" ""))))]
-  "USE_LOAD_ADDRESS_MACRO (operands[1])"
-  "<load>u\t%0,%1"
+(define_insn "*local_pic_load_sf<mode>"
+  [(set (match_operand:SOFTF 0 "register_operand" "=r")
+       (mem:SOFTF (match_operand 1 "absolute_symbolic_operand" "")))]
+  "!TARGET_HARD_FLOAT && USE_LOAD_ADDRESS_MACRO (operands[1])"
+  "<softload>\t%0,%1"
   [(set (attr "length") (const_int 8))])
 
-(define_insn "*local_pic_storedi<mode>"
-  [(set (mem:ANYI (match_operand 0 "absolute_symbolic_operand" ""))
-       (match_operand:ANYI 1 "reg_or_0_operand" "rJ"))
-   (clobber (match_scratch:DI 2 "=&r"))]
-  "TARGET_64BIT && USE_LOAD_ADDRESS_MACRO (operands[0])"
-  "<store>\t%z1,%0,%2"
-  [(set (attr "length") (const_int 8))])
+;; Simplify PIC stores to static variables.
+;; These should go away once we figure out how to emit auipc discretely.
 
-(define_insn "*local_pic_storesi<mode>"
+(define_insn "*local_pic_store<ANYI:mode>"
   [(set (mem:ANYI (match_operand 0 "absolute_symbolic_operand" ""))
        (match_operand:ANYI 1 "reg_or_0_operand" "rJ"))
-   (clobber (match_scratch:SI 2 "=&r"))]
-  "!TARGET_64BIT && USE_LOAD_ADDRESS_MACRO (operands[0])"
-  "<store>\t%z1,%0,%2"
+   (clobber (match_scratch:P 2 "=&r"))]
+  "USE_LOAD_ADDRESS_MACRO (operands[0])"
+  "<ANYI:store>\t%z1,%0,%2"
   [(set (attr "length") (const_int 8))])
 
-(define_insn "*local_pic_storedi<mode>"
+(define_insn "*local_pic_store<ANYF:mode>"
   [(set (mem:ANYF (match_operand 0 "absolute_symbolic_operand" ""))
-       (match_operand:ANYF 1 "register_operand" "f"))
-   (clobber (match_scratch:DI 2 "=r"))]
-  "TARGET_HARD_FLOAT && TARGET_64BIT && USE_LOAD_ADDRESS_MACRO (operands[0])"
-  "<store>\t%1,%0,%2"
+       (match_operand:ANYF 1 "register_operand" "f,*r"))
+   (clobber (match_scratch:P 2 "=r,&r"))]
+  "TARGET_HARD_FLOAT && USE_LOAD_ADDRESS_MACRO (operands[0])
+   && (!TARGET_DOUBLE_FLOAT || TARGET_64BIT)"
+  "@
+   <ANYF:store>\t%1,%0,%2
+   <softstore>\t%1,%0,%2"
   [(set (attr "length") (const_int 8))])
 
-(define_insn "*local_pic_storesi<mode>"
-  [(set (mem:ANYF (match_operand 0 "absolute_symbolic_operand" ""))
-       (match_operand:ANYF 1 "register_operand" "f"))
-   (clobber (match_scratch:SI 2 "=r"))]
-  "TARGET_HARD_FLOAT && !TARGET_64BIT && USE_LOAD_ADDRESS_MACRO (operands[0])"
-  "<store>\t%1,%0,%2"
+;; ??? For a 32-bit target with double float, a DF store from a X reg isn't
+;; supported.  sd is not valid in that case.  Punt for now.  Maybe add a split
+;; for this later.
+
+(define_insn "*local_pic_store_32d<ANYF:mode>"
+  [(set (match_operand:ANYF 0 "register_operand" "=f")
+       (mem:ANYF (match_operand 1 "absolute_symbolic_operand" "")))
+   (clobber (match_scratch:P 2 "=r"))]
+  "TARGET_HARD_FLOAT && USE_LOAD_ADDRESS_MACRO (operands[1])
+   && (TARGET_DOUBLE_FLOAT && !TARGET_64BIT)"
+  "<ANYF:store>\t%1,%0,%2"
+  [(set (attr "length") (const_int 8))])
+
+(define_insn "*local_pic_store_sf<SOFTF:mode>"
+  [(set (mem:SOFTF (match_operand 0 "absolute_symbolic_operand" ""))
+       (match_operand:SOFTF 1 "register_operand" "r"))
+   (clobber (match_scratch:P 2 "=&r"))]
+  "!TARGET_HARD_FLOAT && USE_LOAD_ADDRESS_MACRO (operands[0])"
+  "<softstore>\t%1,%0,%2"
   [(set (attr "length") (const_int 8))])
index 69e70feaf33bab1da3ca6bc22b322eefe2dad08c..9d6d981a42aab86912dbfde787cf95404a2da39e 100644 (file)
@@ -802,7 +802,13 @@ riscv_address_insns (rtx x, machine_mode mode, bool might_split_p)
   int n = 1;
 
   if (!riscv_classify_address (&addr, x, mode, false))
-    return 0;
+    {
+      /* This could be a pattern from the pic.md file.  In which case we want
+        this address to always have a cost of 3 to make it as expensive as the
+        most expensive symbol.  This prevents constant propagation from
+        preferring symbols over register plus offset.  */
+      return 3;
+    }
 
   /* BLKmode is used for single unaligned loads and stores and should
      not count as a multiword mode. */
index 613af9d79e47070c6e6ac4e161983b744df680c1..95fbb282c7cccdff33e9c629388239903f8c142e 100644 (file)
 ;; Iterator for QImode extension patterns.
 (define_mode_iterator SUPERQI [HI SI (DI "TARGET_64BIT")])
 
-;; Iterator for extending loads.
-(define_mode_iterator ZERO_EXTEND_LOAD [QI HI (SI "TARGET_64BIT")])
-
 ;; Iterator for hardware integer modes narrower than XLEN.
 (define_mode_iterator SUBX [QI HI (SI "TARGET_64BIT")])
 
 (define_mode_iterator ANYF [(SF "TARGET_HARD_FLOAT")
                            (DF "TARGET_DOUBLE_FLOAT")])
 
+;; Iterator for floating-point modes that can be loaded into X registers.
+(define_mode_iterator SOFTF [SF (DF "TARGET_64BIT")])
+
 ;; This attribute gives the length suffix for a sign- or zero-extension
 ;; instruction.
 (define_mode_attr size [(QI "b") (HI "h")])
 ;; Mode attributes for loads.
 (define_mode_attr load [(QI "lb") (HI "lh") (SI "lw") (DI "ld") (SF "flw") (DF "fld")])
 
+;; Instruction names for integer loads that aren't explicitly sign or zero
+;; extended.  See riscv_output_move and LOAD_EXTEND_OP.
+(define_mode_attr default_load [(QI "lbu") (HI "lhu") (SI "lw") (DI "ld")])
+
+;; Mode attribute for FP loads into integer registers.
+(define_mode_attr softload [(SF "lw") (DF "ld")])
+
 ;; Instruction names for stores.
 (define_mode_attr store [(QI "sb") (HI "sh") (SI "sw") (DI "sd") (SF "fsw") (DF "fsd")])
 
+;; Instruction names for FP stores from integer registers.
+(define_mode_attr softstore [(SF "sw") (DF "sd")])
+
 ;; This attribute gives the best constraint to use for registers of
 ;; a given mode.
 (define_mode_attr reg [(SI "d") (DI "d") (CC "d")])