case EQ:
case NE:
if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 1)) == CONST_INT
- && CONST_OK_FOR_LETTER_P (INTVAL (XEXP (op0, 1)), 'K'))
+ && CONST_OK_FOR_CONSTRAINT_P (INTVAL (XEXP (op0, 1)), 'K', "K"))
return CCAPmode;
if ((GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS
|| GET_CODE (op1) == NEG)
case GE:
case GT:
if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 1)) == CONST_INT
- && CONST_OK_FOR_LETTER_P (INTVAL (XEXP (op0, 1)), 'K'))
+ && CONST_OK_FOR_CONSTRAINT_P (INTVAL (XEXP (op0, 1)), 'K', "K"))
{
if (INTVAL (XEXP((op0), 1)) < 0)
return CCANmode;
return mnemonic[mask];
}
-/* If OP is an integer constant of mode MODE with exactly one
- HImode subpart unequal to DEF, return the number of that
- subpart. As a special case, all HImode subparts of OP are
- equal to DEF, return zero. Otherwise, return -1. */
+/* Return the part of op which has a value different from def.
+ The size of the part is determined by mode.
+ Use this function only if you already know that op really
+ contains such a part. */
-int
-s390_single_hi (rtx op, enum machine_mode mode, int def)
+unsigned HOST_WIDE_INT
+s390_extract_part (rtx op, enum machine_mode mode, int def)
{
- if (GET_CODE (op) == CONST_INT)
- {
- unsigned HOST_WIDE_INT value = 0;
- int n_parts = GET_MODE_SIZE (mode) / 2;
- int i, part = -1;
-
- for (i = 0; i < n_parts; i++)
- {
- if (i == 0)
- value = (unsigned HOST_WIDE_INT) INTVAL (op);
- else
- value >>= 16;
-
- if ((value & 0xffff) != (unsigned)(def & 0xffff))
- {
- if (part != -1)
- return -1;
- else
- part = i;
- }
- }
-
- return part == -1 ? 0 : (n_parts - 1 - part);
- }
-
- else if (GET_CODE (op) == CONST_DOUBLE
- && GET_MODE (op) == VOIDmode)
- {
- unsigned HOST_WIDE_INT value = 0;
- int n_parts = GET_MODE_SIZE (mode) / 2;
- int i, part = -1;
-
- for (i = 0; i < n_parts; i++)
- {
- if (i == 0)
- value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (op);
- else if (i == HOST_BITS_PER_WIDE_INT / 16)
- value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (op);
- else
- value >>= 16;
-
- if ((value & 0xffff) != (unsigned)(def & 0xffff))
- {
- if (part != -1)
- return -1;
- else
- part = i;
- }
- }
-
- return part == -1 ? 0 : (n_parts - 1 - part);
- }
-
- return -1;
-}
-
-/* Extract the HImode part number PART from integer
- constant OP of mode MODE. */
-
-int
-s390_extract_hi (rtx op, enum machine_mode mode, int part)
-{
- int n_parts = GET_MODE_SIZE (mode) / 2;
- if (part < 0 || part >= n_parts)
- abort();
- else
- part = n_parts - 1 - part;
-
- if (GET_CODE (op) == CONST_INT)
- {
- unsigned HOST_WIDE_INT value = (unsigned HOST_WIDE_INT) INTVAL (op);
- return ((value >> (16 * part)) & 0xffff);
- }
- else if (GET_CODE (op) == CONST_DOUBLE
- && GET_MODE (op) == VOIDmode)
+ unsigned HOST_WIDE_INT value = 0;
+ int max_parts = HOST_BITS_PER_WIDE_INT / GET_MODE_BITSIZE (mode);
+ int part_bits = GET_MODE_BITSIZE (mode);
+ unsigned HOST_WIDE_INT part_mask = (1 << part_bits) - 1;
+ int i;
+
+ for (i = 0; i < max_parts; i++)
{
- unsigned HOST_WIDE_INT value;
- if (part < HOST_BITS_PER_WIDE_INT / 16)
- value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (op);
+ if (i == 0)
+ value = (unsigned HOST_WIDE_INT) INTVAL (op);
else
- value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (op),
- part -= HOST_BITS_PER_WIDE_INT / 16;
-
- return ((value >> (16 * part)) & 0xffff);
+ value >>= part_bits;
+
+ if ((value & part_mask) != (def & part_mask))
+ return value & part_mask;
}
-
+
abort ();
}
/* If OP is an integer constant of mode MODE with exactly one
- QImode subpart unequal to DEF, return the number of that
- subpart. As a special case, all QImode subparts of OP are
- equal to DEF, return zero. Otherwise, return -1. */
+ part of mode PART_MODE unequal to DEF, return the number of that
+ part. Otherwise, return -1. */
int
-s390_single_qi (rtx op, enum machine_mode mode, int def)
-{
- if (GET_CODE (op) == CONST_INT)
- {
- unsigned HOST_WIDE_INT value = 0;
- int n_parts = GET_MODE_SIZE (mode);
- int i, part = -1;
-
- for (i = 0; i < n_parts; i++)
- {
- if (i == 0)
- value = (unsigned HOST_WIDE_INT) INTVAL (op);
- else
- value >>= 8;
-
- if ((value & 0xff) != (unsigned)(def & 0xff))
- {
- if (part != -1)
- return -1;
- else
- part = i;
- }
- }
-
- return part == -1 ? 0 : (n_parts - 1 - part);
- }
-
- else if (GET_CODE (op) == CONST_DOUBLE
- && GET_MODE (op) == VOIDmode)
- {
- unsigned HOST_WIDE_INT value = 0;
- int n_parts = GET_MODE_SIZE (mode);
- int i, part = -1;
-
- for (i = 0; i < n_parts; i++)
- {
- if (i == 0)
- value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (op);
- else if (i == HOST_BITS_PER_WIDE_INT / 8)
- value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (op);
- else
- value >>= 8;
-
- if ((value & 0xff) != (unsigned)(def & 0xff))
- {
- if (part != -1)
- return -1;
- else
- part = i;
- }
- }
-
- return part == -1 ? 0 : (n_parts - 1 - part);
- }
-
- return -1;
-}
-
-/* Extract the QImode part number PART from integer
- constant OP of mode MODE. */
-
-int
-s390_extract_qi (rtx op, enum machine_mode mode, int part)
-{
- int n_parts = GET_MODE_SIZE (mode);
- if (part < 0 || part >= n_parts)
- abort();
- else
- part = n_parts - 1 - part;
-
- if (GET_CODE (op) == CONST_INT)
- {
- unsigned HOST_WIDE_INT value = (unsigned HOST_WIDE_INT) INTVAL (op);
- return ((value >> (8 * part)) & 0xff);
- }
- else if (GET_CODE (op) == CONST_DOUBLE
- && GET_MODE (op) == VOIDmode)
- {
- unsigned HOST_WIDE_INT value;
- if (part < HOST_BITS_PER_WIDE_INT / 8)
- value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (op);
+s390_single_part (rtx op,
+ enum machine_mode mode,
+ enum machine_mode part_mode,
+ int def)
+{
+ unsigned HOST_WIDE_INT value = 0;
+ int n_parts = GET_MODE_SIZE (mode) / GET_MODE_SIZE (part_mode);
+ unsigned HOST_WIDE_INT part_mask = (1 << GET_MODE_BITSIZE (part_mode)) - 1;
+ int i, part = -1;
+
+ if (GET_CODE (op) != CONST_INT)
+ return -1;
+
+ for (i = 0; i < n_parts; i++)
+ {
+ if (i == 0)
+ value = (unsigned HOST_WIDE_INT) INTVAL (op);
else
- value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (op),
- part -= HOST_BITS_PER_WIDE_INT / 8;
-
- return ((value >> (8 * part)) & 0xff);
+ value >>= GET_MODE_BITSIZE (part_mode);
+
+ if ((value & part_mask) != (def & part_mask))
+ {
+ if (part != -1)
+ return -1;
+ else
+ part = i;
+ }
}
-
- abort ();
+ return part == -1 ? -1 : n_parts - 1 - part;
}
/* Check whether we can (and want to) split a double-word
/* Return true if OP is a valid operand for a C constraint. */
int
-s390_extra_constraint (rtx op, int c)
+s390_extra_constraint_str (rtx op, int c, const char * str)
{
struct s390_address addr;
+ if (c != str[0])
+ abort ();
+
switch (c)
{
case 'Q':
return 1;
}
+/* Return true if VALUE matches the constraint STR. */
+
+int
+s390_const_ok_for_constraint_p (HOST_WIDE_INT value,
+ int c,
+ const char * str)
+{
+ enum machine_mode mode, part_mode;
+ int def;
+ unsigned char part;
+
+ if (c != str[0])
+ abort ();
+
+ switch (str[0])
+ {
+ case 'I':
+ return (unsigned int)value < 256;
+
+ case 'J':
+ return (unsigned int)value < 4096;
+
+ case 'K':
+ return value >= -32768 && value < 32768;
+
+ case 'L':
+ return (TARGET_LONG_DISPLACEMENT ?
+ (value >= -524288 && value <= 524287)
+ : (value >= 0 && value <= 4095));
+ case 'M':
+ return value == 2147483647;
+
+ case 'N':
+ part = str[1] - '0';
+
+ switch (str[2])
+ {
+ case 'H': part_mode = HImode; break;
+ case 'Q': part_mode = QImode; break;
+ default: return 0;
+ }
+
+ switch (str[3])
+ {
+ case 'H': mode = HImode; break;
+ case 'S': mode = SImode; break;
+ case 'D': mode = DImode; break;
+ default: return 0;
+ }
+
+ switch (str[4])
+ {
+ case '0': def = 0; break;
+ case 'F': def = -1; break;
+ default: return 0;
+ }
+
+ if (GET_MODE_SIZE (mode) <= GET_MODE_SIZE (part_mode))
+ return 0;
+
+ if (s390_single_part (GEN_INT (value), mode, part_mode, def) != part)
+ return 0;
+
+ break;
+
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
/* Compute a (partial) cost for rtx X. Return true if the complete
cost has been computed, and false if subexpressions should be
scanned. In either case, *TOTAL contains the cost result. */
/* Accept l(g)hi operands. */
if (GET_CODE (op) == CONST_INT
- && CONST_OK_FOR_LETTER_P (INTVAL (op), 'K'))
+ && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), 'K', "K"))
return 1;
/* Accept lliXX operands. */
if (TARGET_ZARCH
- && s390_single_hi (op, DImode, 0) >= 0)
+ && s390_single_part (op, DImode, HImode, 0) >= 0)
return 1;
/* Accept larl operands. */
'b': print integer X as if it's an unsigned byte.
'x': print integer X as if it's an unsigned word.
- 'h': print integer X as if it's a signed word. */
+ 'h': print integer X as if it's a signed word.
+ 'i': print the first nonzero HImode part of X.
+ 'j': print the first HImode part unequal to 0xffff of X. */
void
print_operand (FILE *file, rtx x, int code)
fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0xffff);
else if (code == 'h')
fprintf (file, HOST_WIDE_INT_PRINT_DEC, ((INTVAL (x) & 0xffff) ^ 0x8000) - 0x8000);
+ else if (code == 'i')
+ fprintf (file, HOST_WIDE_INT_PRINT_DEC,
+ s390_extract_part (x, HImode, 0));
+ else if (code == 'j')
+ fprintf (file, HOST_WIDE_INT_PRINT_DEC,
+ s390_extract_part (x, HImode, -1));
else
fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
break;
}
else
{
- if (!CONST_OK_FOR_LETTER_P (INTVAL (frame_off), 'K'))
+ if (!CONST_OK_FOR_CONSTRAINT_P (INTVAL (frame_off), 'K', "K"))
frame_off = force_const_mem (Pmode, frame_off);
insn = emit_insn (gen_add2_insn (stack_pointer_rtx, frame_off));
}
else
{
- if (!CONST_OK_FOR_LETTER_P (INTVAL (frame_off), 'K'))
+ if (!CONST_OK_FOR_CONSTRAINT_P (INTVAL (frame_off), 'K', "K"))
frame_off = force_const_mem (Pmode, frame_off);
insn = emit_insn (gen_add2_insn (frame_pointer, frame_off));
{
/* Setup literal pool pointer if required. */
if ((!DISP_IN_RANGE (delta)
- && !CONST_OK_FOR_LETTER_P (delta, 'K'))
+ && !CONST_OK_FOR_CONSTRAINT_P (delta, 'K', "K"))
|| (!DISP_IN_RANGE (vcall_offset)
- && !CONST_OK_FOR_LETTER_P (vcall_offset, 'K')))
+ && !CONST_OK_FOR_CONSTRAINT_P (vcall_offset, 'K', "K")))
{
op[5] = gen_label_rtx ();
output_asm_insn ("larl\t%4,%5", op);
/* Add DELTA to this pointer. */
if (delta)
{
- if (CONST_OK_FOR_LETTER_P (delta, 'J'))
+ if (CONST_OK_FOR_CONSTRAINT_P (delta, 'J', "J"))
output_asm_insn ("la\t%1,%2(%1)", op);
else if (DISP_IN_RANGE (delta))
output_asm_insn ("lay\t%1,%2(%1)", op);
- else if (CONST_OK_FOR_LETTER_P (delta, 'K'))
+ else if (CONST_OK_FOR_CONSTRAINT_P (delta, 'K', "K"))
output_asm_insn ("aghi\t%1,%2", op);
else
{
output_asm_insn ("lg\t%4,0(%1)", op);
output_asm_insn ("ag\t%1,%3(%4)", op);
}
- else if (CONST_OK_FOR_LETTER_P (vcall_offset, 'K'))
+ else if (CONST_OK_FOR_CONSTRAINT_P (vcall_offset, 'K', "K"))
{
output_asm_insn ("lghi\t%4,%3", op);
output_asm_insn ("ag\t%4,0(%1)", op);
/* Setup base pointer if required. */
if (!vcall_offset
|| (!DISP_IN_RANGE (delta)
- && !CONST_OK_FOR_LETTER_P (delta, 'K'))
+ && !CONST_OK_FOR_CONSTRAINT_P (delta, 'K', "K"))
|| (!DISP_IN_RANGE (delta)
- && !CONST_OK_FOR_LETTER_P (vcall_offset, 'K')))
+ && !CONST_OK_FOR_CONSTRAINT_P (vcall_offset, 'K', "K")))
{
op[5] = gen_label_rtx ();
output_asm_insn ("basr\t%4,0", op);
/* Add DELTA to this pointer. */
if (delta)
{
- if (CONST_OK_FOR_LETTER_P (delta, 'J'))
+ if (CONST_OK_FOR_CONSTRAINT_P (delta, 'J', "J"))
output_asm_insn ("la\t%1,%2(%1)", op);
else if (DISP_IN_RANGE (delta))
output_asm_insn ("lay\t%1,%2(%1)", op);
- else if (CONST_OK_FOR_LETTER_P (delta, 'K'))
+ else if (CONST_OK_FOR_CONSTRAINT_P (delta, 'K', "K"))
output_asm_insn ("ahi\t%1,%2", op);
else
{
/* Perform vcall adjustment. */
if (vcall_offset)
{
- if (CONST_OK_FOR_LETTER_P (vcall_offset, 'J'))
+ if (CONST_OK_FOR_CONSTRAINT_P (vcall_offset, 'J', "J"))
{
output_asm_insn ("lg\t%4,0(%1)", op);
output_asm_insn ("a\t%1,%3(%4)", op);
output_asm_insn ("lg\t%4,0(%1)", op);
output_asm_insn ("ay\t%1,%3(%4)", op);
}
- else if (CONST_OK_FOR_LETTER_P (vcall_offset, 'K'))
+ else if (CONST_OK_FOR_CONSTRAINT_P (vcall_offset, 'K', "K"))
{
output_asm_insn ("lhi\t%4,%3", op);
output_asm_insn ("a\t%4,0(%1)", op);
;; I -- An 8-bit constant (0..255).
;; J -- A 12-bit constant (0..4095).
;; K -- A 16-bit constant (-32768..32767).
-;; Q -- A memory reference without index-register.
-;; S -- Valid operand for the LARL instruction.
+;; L -- Value appropriate as displacement.
+;; (0..4095) for short displacement
+;; (-524288..524287) for long displacement
+;; M -- Constant integer with a value of 0x7fffffff.
+;; N -- Multiple letter constraint followed by 4 parameter letters.
+;; 0..9: number of the part counting from most to least significant
+;; H,Q: mode of the part
+;; D,S,H: mode of the containing operand
+;; 0,F: value of the other parts (F - all bits set)
+;;
+;; The constraint matches if the specified part of a constant
+;; has a value different from its other parts.
+;; Q -- Memory reference without index register and with short displacement.
+;; R -- Memory reference with index register and short displacement.
+;; S -- Memory reference without index register but with long displacement.
+;; T -- Memory reference with index register and long displacement.
+;; U -- Pointer with short displacement.
+;; W -- Pointer with long displacement.
+;; Y -- Shift count operand.
;;
;; Special formats used for outputting 390 instructions.
;;
-;; %b -- Print a constant byte integer. xy
-;; %h -- Print a signed 16-bit. wxyz
-;; %N -- Print next register (second word of a DImode reg) or next word.
-;; %M -- Print next register (second word of a TImode reg) or next word.
-;; %O -- Print the offset of a memory reference (PLUS (REG) (CONST_INT)).
-;; %R -- Print the register of a memory reference (PLUS (REG) (CONST_INT)).
+;; %C: print opcode suffix for branch condition.
+;; %D: print opcode suffix for inverse branch condition.
+;; %J: print tls_load/tls_gdcall/tls_ldcall suffix
+;; %O: print only the displacement of a memory reference.
+;; %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.
+
+;; %b: print integer X as if it's an unsigned byte.
+;; %x: print integer X as if it's an unsigned word.
+;; %h: print integer X as if it's a signed word.
+;; %i: print the first nonzero HImode part of X
+;; %j: print the first HImode part unequal to 0xffff of X
+
;;
;; We have a special constraint for pattern matching.
;;
(match_operand:DI 1 "immediate_operand" "n,n"))
(match_operand:DI 2 "immediate_operand" "n,n")))]
"s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0))
- && s390_single_qi (operands[1], DImode, 0) >= 0"
+ && s390_single_part (operands[1], DImode, QImode, 0) >= 0"
{
- int part = s390_single_qi (operands[1], DImode, 0);
- operands[1] = GEN_INT (s390_extract_qi (operands[1], DImode, part));
+ int part = s390_single_part (operands[1], DImode, QImode, 0);
+ operands[1] = GEN_INT (s390_extract_part (operands[1], QImode, 0));
operands[0] = gen_rtx_MEM (QImode,
plus_constant (XEXP (operands[0], 0), part));
(match_operand:SI 1 "immediate_operand" "n,n"))
(match_operand:SI 2 "immediate_operand" "n,n")))]
"s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0))
- && s390_single_qi (operands[1], SImode, 0) >= 0"
+ && s390_single_part (operands[1], SImode, QImode, 0) >= 0"
{
- int part = s390_single_qi (operands[1], SImode, 0);
- operands[1] = GEN_INT (s390_extract_qi (operands[1], SImode, part));
+ int part = s390_single_part (operands[1], SImode, QImode, 0);
+ operands[1] = GEN_INT (s390_extract_part (operands[1], QImode, 0));
operands[0] = gen_rtx_MEM (QImode,
plus_constant (XEXP (operands[0], 0), part));
(match_operand:SI 1 "immediate_operand" "n,n"))
(match_operand:SI 2 "immediate_operand" "n,n")))]
"s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0))
- && s390_single_qi (operands[1], HImode, 0) >= 0"
+ && s390_single_part (operands[1], HImode, QImode, 0) >= 0"
{
- int part = s390_single_qi (operands[1], HImode, 0);
- operands[1] = GEN_INT (s390_extract_qi (operands[1], HImode, part));
+ int part = s390_single_part (operands[1], HImode, QImode, 0);
+ operands[1] = GEN_INT (s390_extract_part (operands[1], QImode, 0));
operands[0] = gen_rtx_MEM (QImode,
plus_constant (XEXP (operands[0], 0), part));
(define_insn "*tmdi_reg"
[(set (reg 33)
- (compare (and:DI (match_operand:DI 0 "nonimmediate_operand" "d")
- (match_operand:DI 1 "immediate_operand" "n"))
- (match_operand:DI 2 "immediate_operand" "n")))]
+ (compare (and:DI (match_operand:DI 0 "nonimmediate_operand" "d,d,d,d")
+ (match_operand:DI 1 "immediate_operand"
+ "N0HD0,N1HD0,N2HD0,N3HD0"))
+ (match_operand:DI 2 "immediate_operand" "n,n,n,n")))]
"TARGET_64BIT
&& s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 1))
- && s390_single_hi (operands[1], DImode, 0) >= 0"
-{
- int part = s390_single_hi (operands[1], DImode, 0);
- operands[1] = GEN_INT (s390_extract_hi (operands[1], DImode, part));
-
- switch (part)
- {
- case 0: return "tmhh\t%0,%x1";
- case 1: return "tmhl\t%0,%x1";
- case 2: return "tmlh\t%0,%x1";
- case 3: return "tmll\t%0,%x1";
- default: abort ();
- }
-}
+ && s390_single_part (operands[1], DImode, HImode, 0) >= 0"
+ "@
+ tmhh\t%0,%i1
+ tmhl\t%0,%i1
+ tmlh\t%0,%i1
+ tmll\t%0,%i1"
[(set_attr "op_type" "RI")])
(define_insn "*tmsi_reg"
[(set (reg 33)
- (compare (and:SI (match_operand:SI 0 "nonimmediate_operand" "d")
- (match_operand:SI 1 "immediate_operand" "n"))
- (match_operand:SI 2 "immediate_operand" "n")))]
+ (compare (and:SI (match_operand:SI 0 "nonimmediate_operand" "d,d")
+ (match_operand:SI 1 "immediate_operand" "N0HS0,N1HS0"))
+ (match_operand:SI 2 "immediate_operand" "n,n")))]
"s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 1))
- && s390_single_hi (operands[1], SImode, 0) >= 0"
-{
- int part = s390_single_hi (operands[1], SImode, 0);
- operands[1] = GEN_INT (s390_extract_hi (operands[1], SImode, part));
-
- switch (part)
- {
- case 0: return "tmh\t%0,%x1";
- case 1: return "tml\t%0,%x1";
- default: abort ();
- }
-}
+ && s390_single_part (operands[1], SImode, HImode, 0) >= 0"
+ "@
+ tmh\t%0,%i1
+ tml\t%0,%i1"
[(set_attr "op_type" "RI")])
(define_insn "*tmhi_full"
operands[1] = force_const_mem (DImode, operands[1]);
})
-(define_insn "*movdi_lhi"
- [(set (match_operand:DI 0 "register_operand" "=d")
- (match_operand:DI 1 "immediate_operand" "K"))]
- "TARGET_64BIT
- && GET_CODE (operands[1]) == CONST_INT
- && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')
- && !FP_REG_P (operands[0])"
- "lghi\t%0,%h1"
- [(set_attr "op_type" "RI")])
-
-(define_insn "*movdi_lli"
- [(set (match_operand:DI 0 "register_operand" "=d")
- (match_operand:DI 1 "immediate_operand" "n"))]
- "TARGET_64BIT && s390_single_hi (operands[1], DImode, 0) >= 0
- && !FP_REG_P (operands[0])"
-{
- int part = s390_single_hi (operands[1], DImode, 0);
- operands[1] = GEN_INT (s390_extract_hi (operands[1], DImode, part));
-
- switch (part)
- {
- case 0: return "llihh\t%0,%x1";
- case 1: return "llihl\t%0,%x1";
- case 2: return "llilh\t%0,%x1";
- case 3: return "llill\t%0,%x1";
- default: abort ();
- }
-}
- [(set_attr "op_type" "RI")])
-
-(define_insn "*movdi_lay"
- [(set (match_operand:DI 0 "register_operand" "=d")
- (match_operand:DI 1 "address_operand" "p"))]
- "TARGET_64BIT
- && TARGET_LONG_DISPLACEMENT
- && GET_CODE (operands[1]) == CONST_INT
- && !FP_REG_P (operands[0])"
- "lay\t%0,%a1"
- [(set_attr "op_type" "RXY")
- (set_attr "type" "la")])
-
(define_insn "*movdi_larl"
[(set (match_operand:DI 0 "register_operand" "=d")
(match_operand:DI 1 "larl_operand" "X"))]
(set_attr "type" "larl")])
(define_insn "*movdi_64"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,m,!*f,!*f,!*f,!R,!T,?Q")
- (match_operand:DI 1 "general_operand" "d,m,d,*f,R,T,*f,*f,?Q"))]
+ [(set (match_operand:DI 0 "nonimmediate_operand"
+ "=d,d,d,d,d,d,d,d,m,!*f,!*f,!*f,!R,!T,?Q")
+ (match_operand:DI 1 "general_operand"
+ "K,N0HD0,N1HD0,N2HD0,N3HD0,L,d,m,d,*f,R,T,*f,*f,?Q"))]
"TARGET_64BIT"
"@
+ lghi\t%0,%h1
+ llihh\t%0,%i1
+ llihl\t%0,%i1
+ llilh\t%0,%i1
+ llill\t%0,%i1
+ lay\t%0,%a1
lgr\t%0,%1
lg\t%0,%1
stg\t%1,%0
std\t%1,%0
stdy\t%1,%0
mvc\t%O0(8,%R0),%1"
- [(set_attr "op_type" "RRE,RXY,RXY,RR,RX,RXY,RX,RXY,SS")
- (set_attr "type" "lr,load,store,floadd,floadd,floadd,fstored,fstored,cs")])
+ [(set_attr "op_type" "RI,RI,RI,RI,RI,RXY,RRE,RXY,RXY,RR,RX,RXY,RX,RXY,SS")
+ (set_attr "type" "*,*,*,*,*,la,lr,load,store,floadd,floadd,floadd,
+ fstored,fstored,cs")])
(define_insn "*movdi_31"
[(set (match_operand:DI 0 "nonimmediate_operand" "=d,Q,d,o,!*f,!*f,!*f,!R,!T,Q")
operands[1] = force_const_mem (SImode, operands[1]);
})
-(define_insn "*movsi_lhi"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (match_operand:SI 1 "immediate_operand" "K"))]
- "GET_CODE (operands[1]) == CONST_INT
- && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')
- && !FP_REG_P (operands[0])"
- "lhi\t%0,%h1"
- [(set_attr "op_type" "RI")])
-
-(define_insn "*movsi_lli"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (match_operand:SI 1 "immediate_operand" "n"))]
- "TARGET_ZARCH && s390_single_hi (operands[1], SImode, 0) >= 0
- && !FP_REG_P (operands[0])"
-{
- int part = s390_single_hi (operands[1], SImode, 0);
- operands[1] = GEN_INT (s390_extract_hi (operands[1], SImode, part));
-
- switch (part)
- {
- case 0: return "llilh\t%0,%x1";
- case 1: return "llill\t%0,%x1";
- default: abort ();
- }
-}
- [(set_attr "op_type" "RI")])
-
-(define_insn "*movsi_lay"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (match_operand:SI 1 "address_operand" "p"))]
- "TARGET_LONG_DISPLACEMENT
- && GET_CODE (operands[1]) == CONST_INT
- && !FP_REG_P (operands[0])"
- "lay\t%0,%a1"
- [(set_attr "op_type" "RXY")
- (set_attr "type" "la")])
-
(define_insn "*movsi_larl"
[(set (match_operand:SI 0 "register_operand" "=d")
(match_operand:SI 1 "larl_operand" "X"))]
[(set_attr "op_type" "RIL")
(set_attr "type" "larl")])
-(define_insn "*movsi"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,R,T,!*f,!*f,!*f,!R,!T,?Q")
- (match_operand:SI 1 "general_operand" "d,R,T,d,d,*f,R,T,*f,*f,?Q"))]
- ""
+(define_insn "*movsi_zarch"
+ [(set (match_operand:SI 0 "nonimmediate_operand"
+ "=d,d,d,d,d,d,d,R,T,!*f,!*f,!*f,!R,!T,?Q")
+ (match_operand:SI 1 "general_operand"
+ "K,N0HS0,N1HS0,L,d,R,T,d,d,*f,R,T,*f,*f,?Q"))]
+ "TARGET_ZARCH"
"@
+ lhi\t%0,%h1
+ llilh\t%0,%i1
+ llill\t%0,%i1
+ lay\t%0,%a1
lr\t%0,%1
l\t%0,%1
ly\t%0,%1
ste\t%1,%0
stey\t%1,%0
mvc\t%O0(4,%R0),%1"
- [(set_attr "op_type" "RR,RX,RXY,RX,RXY,RR,RX,RXY,RX,RXY,SS")
- (set_attr "type" "lr,load,load,store,store,floads,floads,floads,fstores,fstores,cs")])
+ [(set_attr "op_type" "RI,RI,RI,RXY,RR,RX,RXY,RX,RXY,RR,RX,RXY,RX,RXY,SS")
+ (set_attr "type" "*,*,*,la,lr,load,load,store,store,floads,floads,floads,fstores,fstores,cs")])
+
+(define_insn "*movsi_esa"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,R,!*f,!*f,!R,?Q")
+ (match_operand:SI 1 "general_operand" "K,d,R,d,*f,R,*f,?Q"))]
+ "!TARGET_ZARCH"
+ "@
+ lhi\t%0,%h1
+ lr\t%0,%1
+ l\t%0,%1
+ st\t%1,%0
+ ler\t%0,%1
+ le\t%0,%1
+ ste\t%1,%0
+ mvc\t%O0(4,%R0),%1"
+ [(set_attr "op_type" "RI,RR,RX,RX,RR,RX,RX,SS")
+ (set_attr "type" "*,lr,load,store,floads,floads,fstores,cs")])
(define_peephole2
[(set (match_operand:SI 0 "register_operand" "")
llgt\t%0,%1"
[(set_attr "op_type" "RRE,RXE")])
-(define_insn_and_split "*llgt_sisi_split"
- [(set (match_operand:SI 0 "register_operand" "=d,d")
- (and:SI (match_operand:SI 1 "nonimmediate_operand" "d,m")
+(define_split
+ [(set (match_operand:SI 0 "register_operand" "")
+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
(const_int 2147483647)))
(clobber (reg:CC 33))]
- "TARGET_64BIT"
- "#"
- "&& reload_completed"
+ "TARGET_64BIT && reload_completed"
[(set (match_dup 0)
(and:SI (match_dup 1)
(const_int 2147483647)))]
llgt\t%0,%N1"
[(set_attr "op_type" "RRE,RXE")])
-(define_insn_and_split "*llgt_didi_split"
- [(set (match_operand:DI 0 "register_operand" "=d,d")
- (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,o")
+(define_split
+ [(set (match_operand:DI 0 "register_operand" "")
+ (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
(const_int 2147483647)))
(clobber (reg:CC 33))]
- "TARGET_64BIT"
- "#"
- "&& reload_completed"
+ "TARGET_64BIT && reload_completed"
[(set (match_dup 0)
(and:DI (match_dup 1)
(const_int 2147483647)))]
(plus:DI (match_dup 1) (match_dup 2)))]
"TARGET_64BIT
&& s390_match_ccmode (insn, CCAmode)
- && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
+ && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'K', \"K\")"
"aghi\t%0,%h2"
[(set_attr "op_type" "RI")])
(set (match_operand:SI 0 "register_operand" "=d")
(plus:SI (match_dup 1) (match_dup 2)))]
"s390_match_ccmode (insn, CCAmode)
- && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
+ && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'K', \"K\")"
"ahi\t%0,%h2"
[(set_attr "op_type" "RI")])
ng\t%0,%2"
[(set_attr "op_type" "RRE,RXY")])
-(define_insn "*anddi3_ni"
- [(set (match_operand:DI 0 "register_operand" "=d")
- (and:DI (match_operand:DI 1 "nonimmediate_operand" "0")
- (match_operand:DI 2 "immediate_operand" "n")))
- (clobber (reg:CC 33))]
- "TARGET_64BIT && s390_single_hi (operands[2], DImode, -1) >= 0"
-{
- int part = s390_single_hi (operands[2], DImode, -1);
- operands[2] = GEN_INT (s390_extract_hi (operands[2], DImode, part));
-
- switch (part)
- {
- case 0: return "nihh\t%0,%x2";
- case 1: return "nihl\t%0,%x2";
- case 2: return "nilh\t%0,%x2";
- case 3: return "nill\t%0,%x2";
- default: abort ();
- }
-}
- [(set_attr "op_type" "RI")])
-
(define_insn "anddi3"
- [(set (match_operand:DI 0 "register_operand" "=d,d")
- (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
- (match_operand:DI 2 "general_operand" "d,m")))
- (clobber (reg:CC 33))]
- "TARGET_64BIT"
- "@
- ngr\t%0,%2
- ng\t%0,%2"
- [(set_attr "op_type" "RRE,RXY")])
+ [(set (match_operand:DI 0 "register_operand" "=d,d,d,d,d,d,d,d")
+ (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,o,0,0,0,0,0,0")
+ (match_operand:DI 2 "general_operand"
+ "M,M,N0HDF,N1HDF,N2HDF,N3HDF,d,m")))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "@
+ #
+ #
+ nihh\t%0,%j2
+ nihl\t%0,%j2
+ nilh\t%0,%j2
+ nill\t%0,%j2
+ ngr\t%0,%2
+ ng\t%0,%2"
+ [(set_attr "op_type" "RRE,RXE,RI,RI,RI,RI,RRE,RXY")])
(define_insn "*anddi3_ss"
[(set (match_operand:DI 0 "s_operand" "=Q")
ny\t%0,%2"
[(set_attr "op_type" "RR,RX,RXY")])
-(define_insn "*andsi3_ni"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (and:SI (match_operand:SI 1 "nonimmediate_operand" "0")
- (match_operand:SI 2 "immediate_operand" "n")))
- (clobber (reg:CC 33))]
- "TARGET_ZARCH && s390_single_hi (operands[2], SImode, -1) >= 0"
-{
- int part = s390_single_hi (operands[2], SImode, -1);
- operands[2] = GEN_INT (s390_extract_hi (operands[2], SImode, part));
-
- switch (part)
- {
- case 0: return "nilh\t%0,%x2";
- case 1: return "nill\t%0,%x2";
- default: abort ();
- }
-}
- [(set_attr "op_type" "RI")])
+(define_expand "andsi3"
+ [(parallel
+ [(set (match_operand:SI 0 "register_operand" "")
+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
+ (match_operand:SI 2 "general_operand" "")))
+ (clobber (reg:CC 33))])]
+ ""
+ "")
-(define_insn "andsi3"
- [(set (match_operand:SI 0 "register_operand" "=d,d,d")
- (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0")
- (match_operand:SI 2 "general_operand" "d,R,T")))
+(define_insn "*andsi3_zarch"
+ [(set (match_operand:SI 0 "register_operand" "=d,d,d,d,d,d,d")
+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "d,o,0,0,0,0,0")
+ (match_operand:SI 2 "general_operand" "M,M,N0HSF,N1HSF,d,R,T")))
(clobber (reg:CC 33))]
- ""
+ "TARGET_ZARCH"
"@
+ #
+ #
+ nilh\t%0,%j2
+ nill\t%0,%j2
nr\t%0,%2
n\t%0,%2
ny\t%0,%2"
- [(set_attr "op_type" "RR,RX,RXY")])
+ [(set_attr "op_type" "RRE,RXE,RI,RI,RR,RX,RXY")])
+
+(define_insn "*andsi3_esa"
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
+ (match_operand:SI 2 "general_operand" "d,R")))
+ (clobber (reg:CC 33))]
+ "!TARGET_ZARCH"
+ "@
+ nr\t%0,%2
+ n\t%0,%2"
+ [(set_attr "op_type" "RR,RX")])
(define_insn "*andsi3_ss"
[(set (match_operand:SI 0 "s_operand" "=Q")
og\t%0,%2"
[(set_attr "op_type" "RRE,RXY")])
-(define_insn "*iordi3_oi"
- [(set (match_operand:DI 0 "register_operand" "=d")
- (ior:DI (match_operand:DI 1 "nonimmediate_operand" "0")
- (match_operand:DI 2 "immediate_operand" "n")))
- (clobber (reg:CC 33))]
- "TARGET_64BIT && s390_single_hi (operands[2], DImode, 0) >= 0"
-{
- int part = s390_single_hi (operands[2], DImode, 0);
- operands[2] = GEN_INT (s390_extract_hi (operands[2], DImode, part));
-
- switch (part)
- {
- case 0: return "oihh\t%0,%x2";
- case 1: return "oihl\t%0,%x2";
- case 2: return "oilh\t%0,%x2";
- case 3: return "oill\t%0,%x2";
- default: abort ();
- }
-}
- [(set_attr "op_type" "RI")])
-
(define_insn "iordi3"
- [(set (match_operand:DI 0 "register_operand" "=d,d")
- (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
- (match_operand:DI 2 "general_operand" "d,m")))
+ [(set (match_operand:DI 0 "register_operand" "=d,d,d,d,d,d")
+ (ior:DI (match_operand:DI 1 "nonimmediate_operand" "0,0,0,0,0,0")
+ (match_operand:DI 2 "general_operand" "N0HD0,N1HD0,N2HD0,N3HD0,d,m")))
(clobber (reg:CC 33))]
"TARGET_64BIT"
"@
+ oihh\t%0,%i2
+ oihl\t%0,%i2
+ oilh\t%0,%i2
+ oill\t%0,%i2
ogr\t%0,%2
og\t%0,%2"
- [(set_attr "op_type" "RRE,RXY")])
+ [(set_attr "op_type" "RI,RI,RI,RI,RRE,RXY")])
(define_insn "*iordi3_ss"
[(set (match_operand:DI 0 "s_operand" "=Q")
oy\t%0,%2"
[(set_attr "op_type" "RR,RX,RXY")])
-(define_insn "*iorsi3_oi"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (ior:SI (match_operand:SI 1 "nonimmediate_operand" "0")
- (match_operand:SI 2 "immediate_operand" "n")))
- (clobber (reg:CC 33))]
- "TARGET_ZARCH && s390_single_hi (operands[2], SImode, 0) >= 0"
-{
- int part = s390_single_hi (operands[2], SImode, 0);
- operands[2] = GEN_INT (s390_extract_hi (operands[2], SImode, part));
-
- switch (part)
- {
- case 0: return "oilh\t%0,%x2";
- case 1: return "oill\t%0,%x2";
- default: abort ();
- }
-}
- [(set_attr "op_type" "RI")])
+(define_expand "iorsi3"
+ [(parallel
+ [(set (match_operand:SI 0 "register_operand" "")
+ (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
+ (match_operand:SI 2 "general_operand" "")))
+ (clobber (reg:CC 33))])]
+ ""
+ "")
-(define_insn "iorsi3"
- [(set (match_operand:SI 0 "register_operand" "=d,d,d")
- (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0")
- (match_operand:SI 2 "general_operand" "d,R,T")))
+(define_insn "iorsi3_zarch"
+ [(set (match_operand:SI 0 "register_operand" "=d,d,d,d,d")
+ (ior:SI (match_operand:SI 1 "nonimmediate_operand" "0,0,0,0,0")
+ (match_operand:SI 2 "general_operand" "N0HS0,N1HS0,d,R,T")))
(clobber (reg:CC 33))]
- ""
+ "TARGET_ZARCH"
"@
+ oilh\t%0,%i2
+ oill\t%0,%i2
or\t%0,%2
o\t%0,%2
oy\t%0,%2"
- [(set_attr "op_type" "RR,RX,RXY")])
+ [(set_attr "op_type" "RI,RI,RR,RX,RXY")])
+
+(define_insn "iorsi3_esa"
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (ior:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
+ (match_operand:SI 2 "general_operand" "d,R")))
+ (clobber (reg:CC 33))]
+ "!TARGET_ZARCH"
+ "@
+ or\t%0,%2
+ o\t%0,%2"
+ [(set_attr "op_type" "RR,RX")])
(define_insn "*iorsi3_ss"
[(set (match_operand:SI 0 "s_operand" "=Q")