return FALSE;
}
+/* Return 1 if OP is a valid operand for the LA instruction,
+ and we prefer to use LA over addition to compute it.
+ If STRICT is true, only accept operands that will never
+ change to something we cannot recognize as preferred. */
+
+int
+preferred_la_operand_p (op, strict)
+ register rtx op;
+ int strict;
+{
+ struct s390_address addr;
+ if (!s390_decompose_address (op, &addr))
+ return FALSE;
+
+ if (!TARGET_64BIT && !addr.pointer)
+ return FALSE;
+
+ if (addr.pointer)
+ return TRUE;
+
+ if (!strict)
+ if ((addr.base && REG_P (addr.base) && REG_POINTER (addr.base))
+ || (addr.indx && REG_P (addr.indx) && REG_POINTER (addr.indx)))
+ return TRUE;
+
+ return FALSE;
+}
+
/* Emit a forced load-address operation to load SRC into DST.
This will use the LOAD ADDRESS instruction even in situations
where legitimate_la_operand_p (SRC) returns false. */
; adddi3 instruction pattern(s).
;
-(define_insn "addaddr_esame"
- [(set (match_operand:DI 0 "register_operand" "=a,a")
- (plus:DI (match_operand:DI 1 "register_operand" "%a,a")
- (match_operand:DI 2 "nonmemory_operand" "J,a")))]
- "TARGET_64BIT && (((REGNO (operands[1]) == STACK_POINTER_REGNUM ) ||
- (REGNO (operands[1]) == BASE_REGISTER)) &&
- (GET_CODE (operands[2]) == REG ||
- CONST_OK_FOR_LETTER_P (INTVAL (operands[2]),'J')))"
- "@
- la\\t%0,%c2(,%1)
- la\\t%0,0(%1,%2)"
- [(set_attr "op_type" "RX")
- (set_attr "atype" "mem")
- (set_attr "type" "la")])
+(define_insn "*la_64_cc"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (match_operand:QI 1 "address_operand" "p"))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT
+ && preferred_la_operand_p (operands[1], 1)"
+ "#"
+ [(set_attr "op_type" "RX")
+ (set_attr "atype" "mem")
+ (set_attr "type" "la")])
+
+(define_split
+ [(set (match_operand:DI 0 "register_operand" "")
+ (match_operand:QI 1 "address_operand" ""))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT && reload_completed
+ && preferred_la_operand_p (operands[1], 0)"
+ [(set (match_dup 0) (match_dup 1))])
(define_insn "*adddi3_sign"
[(set (match_operand:DI 0 "register_operand" "=d,d")
; addsi3 instruction pattern(s).
;
-(define_insn "*la_ccclobber"
+(define_insn "*la_31_cc"
[(set (match_operand:SI 0 "register_operand" "=d")
(match_operand:QI 1 "address_operand" "p"))
(clobber (reg:CC 33))]
- "legitimate_la_operand_p (operands[1])"
- "la\\t%0,%a1"
- [(set_attr "op_type" "RX")
- (set_attr "atype" "mem")
- (set_attr "type" "la")])
+ "!TARGET_64BIT
+ && preferred_la_operand_p (operands[1], 1)"
+ "#"
+ [(set_attr "op_type" "RX")
+ (set_attr "atype" "mem")
+ (set_attr "type" "la")])
+
+(define_split
+ [(set (match_operand:SI 0 "register_operand" "")
+ (match_operand:QI 1 "address_operand" ""))
+ (clobber (reg:CC 33))]
+ "!TARGET_64BIT && reload_completed
+ && preferred_la_operand_p (operands[1], 0)"
+ [(set (match_dup 0) (match_dup 1))])
(define_insn "*addsi3_imm_cc"
[(set (reg 33)
(define_insn "*la_31"
[(set (match_operand:SI 0 "register_operand" "=d")
(match_operand:QI 1 "address_operand" "p"))]
- "legitimate_la_operand_p (operands[1])"
+ "!TARGET_64BIT && legitimate_la_operand_p (operands[1])"
+ "la\\t%0,%a1"
+ [(set_attr "op_type" "RX")
+ (set_attr "atype" "mem")
+ (set_attr "type" "la")])
+
+(define_insn "*la_31_and"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (and:SI (match_operand:QI 1 "address_operand" "p")
+ (const_int 2147483647)))]
+ "!TARGET_64BIT"
"la\\t%0,%a1"
[(set_attr "op_type" "RX")
(set_attr "atype" "mem")
(set_attr "type" "la")])
+(define_insn_and_split "*la_31_and_cc"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (and:SI (match_operand:QI 1 "address_operand" "p")
+ (const_int 2147483647)))
+ (clobber (reg:CC 33))]
+ "!TARGET_64BIT"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 0)
+ (and:SI (match_dup 1) (const_int 2147483647)))]
+ ""
+ [(set_attr "op_type" "RX")
+ (set_attr "atype" "mem")
+ (set_attr "type" "la")])
+
(define_insn "force_la_31"
[(set (match_operand:SI 0 "register_operand" "=d")
(match_operand:QI 1 "address_operand" "p"))