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
This commit is contained in:
parent
37170829c2
commit
efc601240c
@ -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.
|
||||
|
@ -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])"
|
||||
"<load>\t%0,%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])"
|
||||
"<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" ""))))]
|
||||
"USE_LOAD_ADDRESS_MACRO (operands[1])"
|
||||
"<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")
|
||||
(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"
|
||||
[(set (attr "length") (const_int 8))])
|
||||
|
||||
(define_insn "*local_pic_load<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"
|
||||
[(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"
|
||||
"<SUBX:load>u\t%0,%1"
|
||||
[(set (attr "length") (const_int 8))])
|
||||
|
||||
(define_insn "*local_pic_storedi<mode>"
|
||||
;; 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: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))])
|
||||
|
||||
;; ??? 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: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_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))])
|
||||
|
||||
;; Simplify PIC stores to static variables.
|
||||
;; These should go away once we figure out how to emit auipc discretely.
|
||||
|
||||
(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:DI 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_storesi<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"
|
||||
[(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))])
|
||||
|
@ -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. */
|
||||
|
@ -269,9 +269,6 @@
|
||||
;; 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")])
|
||||
|
||||
@ -282,6 +279,9 @@
|
||||
(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")])
|
||||
@ -289,9 +289,19 @@
|
||||
;; 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")])
|
||||
|
Loading…
Reference in New Issue
Block a user