aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/s390/s390.md
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/s390/s390.md')
-rw-r--r--gcc/config/s390/s390.md202
1 files changed, 128 insertions, 74 deletions
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index 853ac9b..18e9c1c 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -369,7 +369,7 @@
(define_insn "*cmpsi_cct"
[(set (reg 33)
- (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "%d")
+ (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "d")
(match_operand:SI 1 "const1_operand" "")
(match_operand:SI 2 "immediate_operand" "I"))
(const_int 0)))]
@@ -856,6 +856,19 @@
if (flag_pic && SYMBOLIC_CONST (operands[1]))
emit_pic_move (operands, SImode);
+
+ /* expr.c tries to load an effective address using
+ force_reg. This fails because we don't have a
+ generic load_address pattern. Convert the move
+ to a proper arithmetic operation instead, unless
+ it is guaranteed to be OK. */
+ if (GET_CODE (operands[1]) == PLUS
+ && !legitimate_la_operand_p (operands[1]))
+ {
+ operands[1] = force_operand (operands[1], operands[0]);
+ if (operands[1] == operands[0])
+ DONE;
+ }
}")
(define_insn "*movsi"
@@ -1835,8 +1848,8 @@
; Compare a block that is less than 256 bytes in length.
(define_insn "cmpstr_const"
- [(set (reg:CCU 33)
- (compare:CCU (match_operand:BLK 0 "s_operand" "oQ")
+ [(set (reg:CCS 33)
+ (compare:CCS (match_operand:BLK 0 "s_operand" "oQ")
(match_operand:BLK 1 "s_operand" "oQ")))
(use (match_operand 2 "immediate_operand" "I"))]
"(unsigned) INTVAL (operands[2]) < 256"
@@ -1848,8 +1861,8 @@
; Compare a block that is larger than 255 bytes in length.
(define_insn "cmpstr_64"
- [(set (reg:CCU 33)
- (compare:CCU (mem:BLK (subreg:DI (match_operand:TI 0 "register_operand" "d") 0))
+ [(set (reg:CCS 33)
+ (compare:CCS (mem:BLK (subreg:DI (match_operand:TI 0 "register_operand" "d") 0))
(mem:BLK (subreg:DI (match_operand:TI 1 "register_operand" "d") 0))))
(clobber (subreg:DI (match_dup 0) 0))
(clobber (subreg:DI (match_dup 0) 8))
@@ -1862,8 +1875,8 @@
(set_attr "type" "other")])
(define_insn "cmpstr_31"
- [(set (reg:CCU 33)
- (compare:CCU (mem:BLK (subreg:SI (match_operand:DI 0 "register_operand" "d") 0))
+ [(set (reg:CCS 33)
+ (compare:CCS (mem:BLK (subreg:SI (match_operand:DI 0 "register_operand" "d") 0))
(mem:BLK (subreg:SI (match_operand:DI 1 "register_operand" "d") 0))))
(clobber (subreg:SI (match_dup 0) 0))
(clobber (subreg:SI (match_dup 0) 4))
@@ -1879,7 +1892,7 @@
(define_insn "cmpint_si"
[(set (match_operand:SI 0 "register_operand" "=d")
- (compare:SI (reg:CCU 33) (const_int 0)))]
+ (compare:SI (reg:CCS 33) (const_int 0)))]
""
"*
{
@@ -1896,7 +1909,7 @@
(define_insn "cmpint_di"
[(set (match_operand:DI 0 "register_operand" "=d")
- (compare:DI (reg:CCU 33) (const_int 0)))]
+ (compare:DI (reg:CCS 33) (const_int 0)))]
"TARGET_64BIT"
"*
{
@@ -2907,76 +2920,44 @@
(set_attr "atype" "mem")
(set_attr "type" "la")])
-(define_insn "*addaddr_picR"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (plus:SI (match_operand:SI 1 "register_operand" "a")
- (unspec:SI [(match_operand:SI 2 "register_operand" "a")] 101)))]
- ""
- "la\\t%0,0(%1,%2)"
- [(set_attr "op_type" "RX")
- (set_attr "atype" "mem")
- (set_attr "type" "la")])
-
-(define_insn "*addaddr_picL"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "a")] 101)
- (match_operand:SI 1 "register_operand" "a")))]
- ""
- "la\\t%0,0(%1,%2)"
- [(set_attr "op_type" "RX")
- (set_attr "atype" "mem")
- (set_attr "type" "la")])
-
-(define_insn "*addaddr_picN"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (unspec:SI [(match_operand:SI 1 "register_operand" "a")] 101))]
- ""
- "la\\t%0,0(%1)"
- [(set_attr "op_type" "RX")
- (set_attr "atype" "mem")
- (set_attr "type" "la")])
-
(define_insn "*addsi3_cc"
[(set (reg 33)
- (compare (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0")
- (match_operand:SI 2 "general_operand" "d,K,m"))
+ (compare (plus:SI (match_operand:SI 1 "register_operand" "%0,0")
+ (match_operand:SI 2 "nonimmediate_operand" "d,m"))
(const_int 0)))
- (set (match_operand:SI 0 "register_operand" "=d,d,d")
+ (set (match_operand:SI 0 "register_operand" "=d,d")
(plus:SI (match_dup 1) (match_dup 2)))]
- "s390_match_ccmode(insn, CCSmode)"
+ "s390_match_ccmode(insn, CCLmode)"
"@
- ar\\t%0,%2
- ahi\\t%0,%h2
- a\\t%0,%2"
- [(set_attr "op_type" "RR,RI,RX")
- (set_attr "atype" "reg,reg,mem")])
+ alr\\t%0,%2
+ al\\t%0,%2"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "atype" "reg,mem")])
(define_insn "*addsi3_cconly"
[(set (reg 33)
- (compare (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0")
- (match_operand:SI 2 "general_operand" "d,K,m"))
+ (compare (plus:SI (match_operand:SI 1 "register_operand" "%0,0")
+ (match_operand:SI 2 "general_operand" "d,m"))
(const_int 0)))
- (clobber (match_scratch:SI 0 "=d,d,d"))]
- "s390_match_ccmode(insn, CCSmode)"
+ (clobber (match_scratch:SI 0 "=d,d"))]
+ "s390_match_ccmode(insn, CCLmode)"
"@
- ar\\t%0,%2
- ahi\\t%0,%h2
- a\\t%0,%2"
- [(set_attr "op_type" "RR,RI,RX")
- (set_attr "atype" "reg,reg,mem")])
+ alr\\t%0,%2
+ al\\t%0,%2"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "atype" "reg,mem")])
(define_insn "*addsi3_cconly2"
[(set (reg 33)
- (compare (match_operand:SI 1 "register_operand" "%0,0,0")
- (neg:SI (match_operand:SI 2 "general_operand" "d,K,m"))))
- (clobber (match_scratch:SI 0 "=d,d,d"))]
- "s390_match_ccmode(insn, CCSmode)"
+ (compare (match_operand:SI 1 "register_operand" "%0,0")
+ (neg:SI (match_operand:SI 2 "general_operand" "d,m"))))
+ (clobber (match_scratch:SI 0 "=d,d"))]
+ "s390_match_ccmode(insn, CCLmode)"
"@
- ar\\t%0,%2
- ahi\\t%0,%h2
- a\\t%0,%2"
- [(set_attr "op_type" "RR,RI,RX")
- (set_attr "atype" "reg,reg,mem")])
+ alr\\t%0,%2
+ al\\t%0,%2"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "atype" "reg,mem")])
(define_insn "addsi3"
[(set (match_operand:SI 0 "register_operand" "=d,d,d")
@@ -2991,10 +2972,11 @@
[(set_attr "op_type" "RR,RI,RX")
(set_attr "atype" "reg,reg,mem")])
-(define_insn "do_la"
+(define_insn "*do_la"
[(set (match_operand:SI 0 "register_operand" "=a")
(match_operand:QI 1 "address_operand" "p"))]
- "volatile_ok"
+ "reload_in_progress || reload_completed
+ || legitimate_la_operand_p (operands[1])"
"la\\t%0,%a1"
[(set_attr "op_type" "RX")
(set_attr "atype" "mem")
@@ -3004,7 +2986,7 @@
[(set (match_operand:SI 0 "register_operand" "=d")
(plus:SI (match_operand:SI 1 "register_operand" "%0")
(match_operand:SI 2 "register_operand" "d")))]
- ""
+ "reload_in_progress || reload_completed"
"brxle\\t%0,%2,.+4"
[(set_attr "op_type" "RSI")
(set_attr "atype" "reg")])
@@ -3220,10 +3202,10 @@
(const_int 0)))
(set (match_operand:SI 0 "register_operand" "=d,d")
(minus:SI (match_dup 1) (match_dup 2)))]
- "s390_match_ccmode(insn, CCSmode)"
+ "s390_match_ccmode(insn, CCLmode)"
"@
- sr\\t%0,%2
- s\\t%0,%2"
+ slr\\t%0,%2
+ sl\\t%0,%2"
[(set_attr "op_type" "RR,RX")
(set_attr "atype" "reg,mem")])
@@ -3233,10 +3215,10 @@
(match_operand:SI 2 "general_operand" "d,m"))
(const_int 0)))
(clobber (match_scratch:SI 0 "=d,d"))]
- "s390_match_ccmode(insn, CCSmode)"
+ "s390_match_ccmode(insn, CCLmode)"
"@
- sr\\t%0,%2
- s\\t%0,%2"
+ slr\\t%0,%2
+ sl\\t%0,%2"
[(set_attr "op_type" "RR,RX")
(set_attr "atype" "reg,mem")])
@@ -4945,6 +4927,78 @@
""
"{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+(define_expand "bunordered"
+ [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
+ (set (pc)
+ (if_then_else (unordered (reg:CCS 33) (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+
+(define_expand "bordered"
+ [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
+ (set (pc)
+ (if_then_else (ordered (reg:CCS 33) (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+
+(define_expand "buneq"
+ [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
+ (set (pc)
+ (if_then_else (uneq (reg:CCS 33) (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+
+(define_expand "bungt"
+ [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
+ (set (pc)
+ (if_then_else (ungt (reg:CCS 33) (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+
+(define_expand "bunlt"
+ [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
+ (set (pc)
+ (if_then_else (unlt (reg:CCS 33) (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+
+(define_expand "bunge"
+ [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
+ (set (pc)
+ (if_then_else (unge (reg:CCS 33) (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+
+(define_expand "bunle"
+ [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
+ (set (pc)
+ (if_then_else (unle (reg:CCS 33) (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+
+(define_expand "bltgt"
+ [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
+ (set (pc)
+ (if_then_else (ltgt (reg:CCS 33) (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+
;;
;;- Conditional jump instructions.