static int s390_decompose_address (rtx, struct s390_address *);
static rtx get_thread_pointer (void);
static rtx legitimize_tls_address (rtx, rtx);
+static void print_shift_count_operand (FILE *, rtx);
static const char *get_some_local_dynamic_name (void);
static int get_some_local_dynamic_name_1 (rtx *, void *);
static int reg_used_in_mem_p (int, rtx);
return general_s_operand (op, mode, 1);
}
+/* Return true if OP a valid shift count operand.
+ OP is the current operation.
+ MODE is the current operation mode. */
+
+int
+shift_count_operand (rtx op, enum machine_mode mode)
+{
+ HOST_WIDE_INT offset = 0;
+
+ if (! check_mode (op, &mode))
+ return 0;
+
+ /* We can have an integer constant, an address register,
+ or a sum of the two. Note that reload already checks
+ that any register present is an address register, so
+ we just check for any register here. */
+ if (GET_CODE (op) == CONST_INT)
+ {
+ offset = INTVAL (op);
+ op = NULL_RTX;
+ }
+ if (op && GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 1)) == CONST_INT)
+ {
+ offset = INTVAL (XEXP (op, 1));
+ op = XEXP (op, 0);
+ }
+ while (op && GET_CODE (op) == SUBREG)
+ op = SUBREG_REG (op);
+ if (op && GET_CODE (op) != REG)
+ return 0;
+
+ /* Unfortunately we have to reject constants that are invalid
+ for an address, or else reload will get confused. */
+ if (!DISP_IN_RANGE (offset))
+ return 0;
+
+ return 1;
+}
+
/* Return true if DISP is a valid short displacement. */
static int
return 0;
break;
+ case 'Y':
+ return shift_count_operand (op, VOIDmode);
+
default:
return 0;
}
return orig_x;
}
+/* Output shift count operand OP to stdio stream FILE. */
+
+static void
+print_shift_count_operand (FILE *file, rtx op)
+{
+ HOST_WIDE_INT offset = 0;
+
+ /* We can have an integer constant, an address register,
+ or a sum of the two. */
+ if (GET_CODE (op) == CONST_INT)
+ {
+ offset = INTVAL (op);
+ op = NULL_RTX;
+ }
+ if (op && GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 1)) == CONST_INT)
+ {
+ offset = INTVAL (XEXP (op, 1));
+ op = XEXP (op, 0);
+ }
+ while (op && GET_CODE (op) == SUBREG)
+ op = SUBREG_REG (op);
+
+ /* Sanity check. */
+ if (op && (GET_CODE (op) != REG
+ || REGNO (op) >= FIRST_PSEUDO_REGISTER
+ || REGNO_REG_CLASS (REGNO (op)) != ADDR_REGS))
+ abort ();
+
+ /* Shift counts are truncated to the low six bits anyway. */
+ fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset & 63);
+ if (op)
+ fprintf (file, "(%s)", reg_names[REGNO (op)]);
+}
+
/* Locate some local-dynamic symbol still in use by this function
so that we can print its name in local-dynamic base patterns. */
'R': print only the base register of a memory reference.
'N': print the second word of a DImode operand.
'M': print the second word of a TImode operand.
+ 'Y': print shift count operand.
'b': print integer X as if it's an unsigned byte.
'x': print integer X as if it's an unsigned word.
else
abort ();
break;
+
+ case 'Y':
+ print_shift_count_operand (file, x);
+ return;
}
switch (GET_CODE (x))
;
(define_insn "rotldi3"
- [(set (match_operand:DI 0 "register_operand" "=d,d")
- (rotate:DI (match_operand:DI 1 "register_operand" "d,d")
- (match_operand:SI 2 "nonmemory_operand" "J,a")))]
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (rotate:DI (match_operand:DI 1 "register_operand" "d")
+ (match_operand:SI 2 "shift_count_operand" "Y")))]
"TARGET_64BIT"
- "@
- rllg\t%0,%1,%c2
- rllg\t%0,%1,0(%2)"
+ "rllg\t%0,%1,%Y2"
[(set_attr "op_type" "RSE")
(set_attr "atype" "reg")])
;
(define_insn "rotlsi3"
- [(set (match_operand:SI 0 "register_operand" "=d,d")
- (rotate:SI (match_operand:SI 1 "register_operand" "d,d")
- (match_operand:SI 2 "nonmemory_operand" "J,a")))]
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (rotate:SI (match_operand:SI 1 "register_operand" "d")
+ (match_operand:SI 2 "shift_count_operand" "Y")))]
"TARGET_CPU_ZARCH"
- "@
- rll\t%0,%1,%c2
- rll\t%0,%1,0(%2)"
+ "rll\t%0,%1,%Y2"
[(set_attr "op_type" "RSE")
(set_attr "atype" "reg")])
(define_expand "ashldi3"
[(set (match_operand:DI 0 "register_operand" "")
(ashift:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:SI 2 "nonmemory_operand" "")))]
+ (match_operand:SI 2 "shift_count_operand" "")))]
""
"")
(define_insn "*ashldi3_31"
- [(set (match_operand:DI 0 "register_operand" "=d,d")
- (ashift:DI (match_operand:DI 1 "register_operand" "0,0")
- (match_operand:SI 2 "nonmemory_operand" "J,a")))]
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (ashift:DI (match_operand:DI 1 "register_operand" "0")
+ (match_operand:SI 2 "shift_count_operand" "Y")))]
"!TARGET_64BIT"
- "@
- sldl\t%0,%c2
- sldl\t%0,0(%2)"
+ "sldl\t%0,%Y2"
[(set_attr "op_type" "RS")
(set_attr "atype" "reg")])
(define_insn "*ashldi3_64"
- [(set (match_operand:DI 0 "register_operand" "=d,d")
- (ashift:DI (match_operand:DI 1 "register_operand" "d,d")
- (match_operand:SI 2 "nonmemory_operand" "J,a")))]
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (ashift:DI (match_operand:DI 1 "register_operand" "d")
+ (match_operand:SI 2 "shift_count_operand" "Y")))]
"TARGET_64BIT"
- "@
- sllg\t%0,%1,%2
- sllg\t%0,%1,0(%2)"
+ "sllg\t%0,%1,%Y2"
[(set_attr "op_type" "RSE")
(set_attr "atype" "reg")])
[(parallel
[(set (match_operand:DI 0 "register_operand" "")
(ashiftrt:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:SI 2 "nonmemory_operand" "")))
+ (match_operand:SI 2 "shift_count_operand" "")))
(clobber (reg:CC 33))])]
""
"")
(define_insn "*ashrdi3_cc_31"
[(set (reg 33)
- (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
- (match_operand:SI 2 "nonmemory_operand" "J,a"))
+ (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
+ (match_operand:SI 2 "shift_count_operand" "Y"))
(const_int 0)))
- (set (match_operand:DI 0 "register_operand" "=d,d")
+ (set (match_operand:DI 0 "register_operand" "=d")
(ashiftrt:DI (match_dup 1) (match_dup 2)))]
"!TARGET_64BIT && s390_match_ccmode(insn, CCSmode)"
- "@
- srda\t%0,%c2
- srda\t%0,0(%2)"
+ "srda\t%0,%Y2"
[(set_attr "op_type" "RS")
(set_attr "atype" "reg")])
(define_insn "*ashrdi3_cconly_31"
[(set (reg 33)
- (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
- (match_operand:SI 2 "nonmemory_operand" "J,a"))
+ (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
+ (match_operand:SI 2 "shift_count_operand" "Y"))
(const_int 0)))
- (clobber (match_scratch:DI 0 "=d,d"))]
+ (clobber (match_scratch:DI 0 "=d"))]
"!TARGET_64BIT && s390_match_ccmode(insn, CCSmode)"
- "@
- srda\t%0,%c2
- srda\t%0,0(%2)"
+ "srda\t%0,%Y2"
[(set_attr "op_type" "RS")
(set_attr "atype" "reg")])
(define_insn "*ashrdi3_31"
- [(set (match_operand:DI 0 "register_operand" "=d,d")
- (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
- (match_operand:SI 2 "nonmemory_operand" "J,a")))
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
+ (match_operand:SI 2 "shift_count_operand" "Y")))
(clobber (reg:CC 33))]
"!TARGET_64BIT"
- "@
- srda\t%0,%c2
- srda\t%0,0(%2)"
+ "srda\t%0,%Y2"
[(set_attr "op_type" "RS")
(set_attr "atype" "reg")])
(define_insn "*ashrdi3_cc_64"
[(set (reg 33)
- (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "d,d")
- (match_operand:SI 2 "nonmemory_operand" "J,a"))
+ (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
+ (match_operand:SI 2 "shift_count_operand" "Y"))
(const_int 0)))
- (set (match_operand:DI 0 "register_operand" "=d,d")
+ (set (match_operand:DI 0 "register_operand" "=d")
(ashiftrt:DI (match_dup 1) (match_dup 2)))]
"s390_match_ccmode(insn, CCSmode) && TARGET_64BIT"
- "@
- srag\t%0,%1,%c2
- srag\t%0,%1,0(%2)"
+ "srag\t%0,%1,%Y2"
[(set_attr "op_type" "RSE")
(set_attr "atype" "reg")])
(define_insn "*ashrdi3_cconly_64"
[(set (reg 33)
- (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "d,d")
- (match_operand:SI 2 "nonmemory_operand" "J,a"))
+ (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
+ (match_operand:SI 2 "shift_count_operand" "Y"))
(const_int 0)))
- (clobber (match_scratch:DI 0 "=d,d"))]
+ (clobber (match_scratch:DI 0 "=d"))]
"s390_match_ccmode(insn, CCSmode) && TARGET_64BIT"
- "@
- srag\t%0,%1,%c2
- srag\t%0,%1,0(%2)"
+ "srag\t%0,%1,%Y2"
[(set_attr "op_type" "RSE")
(set_attr "atype" "reg")])
(define_insn "*ashrdi3_64"
- [(set (match_operand:DI 0 "register_operand" "=d,d")
- (ashiftrt:DI (match_operand:DI 1 "register_operand" "d,d")
- (match_operand:SI 2 "nonmemory_operand" "J,a")))
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
+ (match_operand:SI 2 "shift_count_operand" "Y")))
(clobber (reg:CC 33))]
"TARGET_64BIT"
- "@
- srag\t%0,%1,%c2
- srag\t%0,%1,0(%2)"
+ "srag\t%0,%1,%Y2"
[(set_attr "op_type" "RSE")
(set_attr "atype" "reg")])
;
(define_insn "ashlsi3"
- [(set (match_operand:SI 0 "register_operand" "=d,d")
- (ashift:SI (match_operand:SI 1 "register_operand" "0,0")
- (match_operand:SI 2 "nonmemory_operand" "J,a")))]
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (ashift:SI (match_operand:SI 1 "register_operand" "0")
+ (match_operand:SI 2 "shift_count_operand" "Y")))]
""
- "@
- sll\t%0,%c2
- sll\t%0,0(%2)"
+ "sll\t%0,%Y2"
[(set_attr "op_type" "RS")
(set_attr "atype" "reg")])
(define_insn "*ashrsi3_cc"
[(set (reg 33)
- (compare (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
- (match_operand:SI 2 "nonmemory_operand" "J,a"))
+ (compare (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
+ (match_operand:SI 2 "shift_count_operand" "Y"))
(const_int 0)))
- (set (match_operand:SI 0 "register_operand" "=d,d")
+ (set (match_operand:SI 0 "register_operand" "=d")
(ashiftrt:SI (match_dup 1) (match_dup 2)))]
"s390_match_ccmode(insn, CCSmode)"
- "@
- sra\t%0,%c2
- sra\t%0,0(%2)"
+ "sra\t%0,%Y2"
[(set_attr "op_type" "RS")
(set_attr "atype" "reg")])
(define_insn "*ashrsi3_cconly"
[(set (reg 33)
- (compare (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
- (match_operand:SI 2 "nonmemory_operand" "J,a"))
+ (compare (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
+ (match_operand:SI 2 "shift_count_operand" "Y"))
(const_int 0)))
- (clobber (match_scratch:SI 0 "=d,d"))]
+ (clobber (match_scratch:SI 0 "=d"))]
"s390_match_ccmode(insn, CCSmode)"
- "@
- sra\t%0,%c2
- sra\t%0,0(%2)"
+ "sra\t%0,%Y2"
[(set_attr "op_type" "RS")
(set_attr "atype" "reg")])
(define_insn "ashrsi3"
- [(set (match_operand:SI 0 "register_operand" "=d,d")
- (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
- (match_operand:SI 2 "nonmemory_operand" "J,a")))
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
+ (match_operand:SI 2 "shift_count_operand" "Y")))
(clobber (reg:CC 33))]
""
- "@
- sra\t%0,%c2
- sra\t%0,0(%2)"
+ "sra\t%0,%Y2"
[(set_attr "op_type" "RS")
(set_attr "atype" "reg")])
(define_expand "lshrdi3"
[(set (match_operand:DI 0 "register_operand" "")
(lshiftrt:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:SI 2 "nonmemory_operand" "")))]
+ (match_operand:SI 2 "shift_count_operand" "")))]
""
"")
(define_insn "*lshrdi3_31"
- [(set (match_operand:DI 0 "register_operand" "=d,d")
- (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
- (match_operand:SI 2 "nonmemory_operand" "J,a")))]
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
+ (match_operand:SI 2 "shift_count_operand" "Y")))]
"!TARGET_64BIT"
- "@
- srdl\t%0,%c2
- srdl\t%0,0(%2)"
- [(set_attr "op_type" "RS,RS")
+ "srdl\t%0,%Y2"
+ [(set_attr "op_type" "RS")
(set_attr "atype" "reg")])
(define_insn "*lshrdi3_64"
- [(set (match_operand:DI 0 "register_operand" "=d,d")
- (lshiftrt:DI (match_operand:DI 1 "register_operand" "d,d")
- (match_operand:SI 2 "nonmemory_operand" "J,a")))]
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
+ (match_operand:SI 2 "shift_count_operand" "Y")))]
"TARGET_64BIT"
- "@
- srlg\t%0,%1,%c2
- srlg\t%0,%1,0(%2)"
- [(set_attr "op_type" "RSE,RSE")
+ "srlg\t%0,%1,%Y2"
+ [(set_attr "op_type" "RSE")
(set_attr "atype" "reg")])
;
;
(define_insn "lshrsi3"
- [(set (match_operand:SI 0 "register_operand" "=d,d")
- (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
- (match_operand:SI 2 "nonmemory_operand" "J,a")))]
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
+ (match_operand:SI 2 "shift_count_operand" "Y")))]
""
- "@
- srl\t%0,%c2
- srl\t%0,0(%2)"
+ "srl\t%0,%Y2"
[(set_attr "op_type" "RS")
(set_attr "atype" "reg")])