summaryrefslogtreecommitdiff
path: root/gcc/config/riscv/pic.md
diff options
context:
space:
mode:
authorJim Wilson <jimw@sifive.com>2018-08-29 02:20:44 +0000
committerJim Wilson <wilson@gcc.gnu.org>2018-08-28 19:20:44 -0700
commitefc601240c12628df7ec467ac07a322306f80b71 (patch)
tree4cd1f1a4e8967308b9b118520ee811f34b07354e /gcc/config/riscv/pic.md
parent37170829c2147718dca6c561172b44cee701c45c (diff)
downloadgcc-efc601240c12628df7ec467ac07a322306f80b71.tar.gz
Rewrite pic.md to improve medany and pic code size.
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
Diffstat (limited to 'gcc/config/riscv/pic.md')
-rw-r--r--gcc/config/riscv/pic.md113
1 files changed, 71 insertions, 42 deletions
diff --git a/gcc/config/riscv/pic.md b/gcc/config/riscv/pic.md
index a4a9732656c..942502058e0 100644
--- a/gcc/config/riscv/pic.md
+++ b/gcc/config/riscv/pic.md
@@ -22,71 +22,100 @@
;; 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))])