Commit f19a9af7 by Andreas Krebbel Committed by Ulrich Weigand

s390.md ("tmdi_reg", [...]): Insns now use multiple letter constraints.

2003-11-30  Andreas Krebbel  <krebbel1@de.ibm.com>

	* config/s390/s390.md ("tmdi_reg", "tmsi_reg", "*movdi_64", "*movdi_31",
	"iordi3"): Insns now use multiple letter constraints.
	("*movdi_lhi", "*movdi_lli", "*movdi_lay"): Insns deleted. They are now
	covered by "*movdi_64".
	("*movsi_lhi", "*movsi_lli", "*movsi_lay"): Insns deleted. They are now
	covered by "*movsi_zarch" and "*movsi_esa".
	("*movsi_zarch", "*movsi_!zarch"): New insns.
	("*llgt_sisi_split", "*llgt_didi_split"): Insns deleted. Now covered
	by "*andsi3_zarch" and "anddi3".
	("*anddi3_ni"): Insn merged with "anddi3".
	("*andsi3_ni"): Insn merged with "*andsi3_zarch".
	("*andsi3_zarch", "*andsi3_esa"): New insns.
	("*iordi3_oi"): Insn merged with "iordi3".
	("*iorsi3_oi"): Insn merged with "*iorsi3_zarch".
	("*iorsi3_zarch", "*iorsi3_esa"): New insns.

	* config/s390/s390.c (s390_single_qi, s390_single_hi): Functions
	merged to s390_single_part.
	(s390_single_part): New function.
	NOTE: Semantics have changed a bit. Now the value of the part must
	be different from the others to get a non-negative return value.
	(s390_extract_qi, s390_extract_hi): Functions merged to
	s390_extract_part.
	(s390_extract_part, s390_extra_constraint_str,
	s390_const_ok_for_constraint_p): New functions. The L constraint got a
	new meaning and the N constraint was added as a multiple letter
	constraint.
	(s390_extra_constraint): Function deleted.
	(print_operand): New output modifier 'i' and 'j' added.
	All uses of CONST_OK_FOR_LETTER_P were replaced by
	CONST_OK_FOR_CONSTRAINT_P.

	* config/s390/s390-protos.h: Function prototypes adapted.
	* doc/md.texi: Documentation for new constraint letters added.

From-SVN: r74061
parent 11816ba2
2003-11-30 Andreas Krebbel <krebbel1@de.ibm.com>
* config/s390/s390.md ("tmdi_reg", "tmsi_reg", "*movdi_64", "*movdi_31",
"iordi3"): Insns now use multiple letter constraints.
("*movdi_lhi", "*movdi_lli", "*movdi_lay"): Insns deleted. They are now
covered by "*movdi_64".
("*movsi_lhi", "*movsi_lli", "*movsi_lay"): Insns deleted. They are now
covered by "*movsi_zarch" and "*movsi_esa".
("*movsi_zarch", "*movsi_!zarch"): New insns.
("*llgt_sisi_split", "*llgt_didi_split"): Insns deleted. Now covered
by "*andsi3_zarch" and "anddi3".
("*anddi3_ni"): Insn merged with "anddi3".
("*andsi3_ni"): Insn merged with "*andsi3_zarch".
("*andsi3_zarch", "*andsi3_esa"): New insns.
("*iordi3_oi"): Insn merged with "iordi3".
("*iorsi3_oi"): Insn merged with "*iorsi3_zarch".
("*iorsi3_zarch", "*iorsi3_esa"): New insns.
* config/s390/s390.c (s390_single_qi, s390_single_hi): Functions
merged to s390_single_part.
(s390_single_part): New function.
NOTE: Semantics have changed a bit. Now the value of the part must
be different from the others to get a non-negative return value.
(s390_extract_qi, s390_extract_hi): Functions merged to
s390_extract_part.
(s390_extract_part, s390_extra_constraint_str,
s390_const_ok_for_constraint_p): New functions. The L constraint got a
new meaning and the N constraint was added as a multiple letter
constraint.
(s390_extra_constraint): Function deleted.
(print_operand): New output modifier 'i' and 'j' added.
All uses of CONST_OK_FOR_LETTER_P were replaced by
CONST_OK_FOR_CONSTRAINT_P.
* config/s390/s390-protos.h: Function prototypes adapted.
* doc/md.texi: Documentation for new constraint letters added.
2003-11-30 Andreas Schwab <schwab@suse.de>
* Makefile.in ($(DESTDIR)$(infodir)/%.info): Fix missing semicolon.
......
......@@ -30,7 +30,8 @@ extern void s390_emit_epilogue (void);
extern void s390_function_profiler (FILE *, int);
#ifdef RTX_CODE
extern int s390_extra_constraint (rtx, int);
extern int s390_extra_constraint_str (rtx, int, const char *);
extern int s390_const_ok_for_constraint_p (HOST_WIDE_INT, int, const char *);
extern int const0_operand (rtx, enum machine_mode);
extern int consttable_operand (rtx, enum machine_mode);
extern int larl_operand (rtx, enum machine_mode);
......@@ -40,10 +41,8 @@ extern int shift_count_operand (rtx, enum machine_mode);
extern int bras_sym_operand (rtx, enum machine_mode);
extern int load_multiple_operation (rtx, enum machine_mode);
extern int store_multiple_operation (rtx, enum machine_mode);
extern int s390_single_hi (rtx, enum machine_mode, int);
extern int s390_extract_hi (rtx, enum machine_mode, int);
extern int s390_single_qi (rtx, enum machine_mode, int);
extern int s390_extract_qi (rtx, enum machine_mode, int);
extern int s390_single_part (rtx, enum machine_mode, enum machine_mode, int);
extern unsigned HOST_WIDE_INT s390_extract_part (rtx, enum machine_mode, int);
extern bool s390_split_ok_p (rtx, rtx, enum machine_mode, int);
extern int tls_symbolic_operand (rtx);
......
......@@ -374,7 +374,7 @@ s390_select_ccmode (enum rtx_code code, rtx op0, rtx op1)
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)
......@@ -410,7 +410,7 @@ s390_select_ccmode (enum rtx_code code, rtx op0, rtx op1)
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;
......@@ -760,198 +760,68 @@ s390_branch_condition_mnemonic (rtx code, int inv)
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
......@@ -1353,10 +1223,13 @@ s390_short_displacement (rtx disp)
/* 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':
......@@ -1442,6 +1315,78 @@ s390_extra_constraint (rtx op, int c)
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. */
......@@ -1866,12 +1811,12 @@ legitimate_reload_constant_p (register rtx op)
/* 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. */
......@@ -3493,7 +3438,9 @@ print_operand_address (FILE *file, rtx addr)
'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)
......@@ -3609,6 +3556,12 @@ 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;
......@@ -5694,7 +5647,7 @@ s390_emit_prologue (void)
}
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));
......@@ -5889,7 +5842,7 @@ s390_emit_epilogue (void)
}
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));
......@@ -6898,9 +6851,9 @@ s390_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
{
/* 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);
......@@ -6909,11 +6862,11 @@ s390_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
/* 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
{
......@@ -6930,7 +6883,7 @@ s390_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
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);
......@@ -6973,9 +6926,9 @@ s390_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
/* 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);
......@@ -6986,11 +6939,11 @@ s390_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
/* 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
{
......@@ -7002,7 +6955,7 @@ s390_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
/* 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);
......@@ -7012,7 +6965,7 @@ s390_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
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);
......
......@@ -536,21 +536,20 @@ extern const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER];
(C) == 'd' ? GENERAL_REGS : \
(C) == 'f' ? FP_REGS : NO_REGS)
#define CONST_OK_FOR_LETTER_P(VALUE, C) \
((C) == 'I' ? (unsigned long) (VALUE) < 256 : \
(C) == 'J' ? (unsigned long) (VALUE) < 4096 : \
(C) == 'K' ? (VALUE) >= -32768 && (VALUE) < 32768 : \
(C) == 'L' ? (unsigned long) (VALUE) < 65536 : 0)
#define CONST_OK_FOR_CONSTRAINT_P(VALUE, C, STR) \
s390_const_ok_for_constraint_p ((VALUE), (C), (STR))
#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) 1
#define CONST_DOUBLE_OK_FOR_CONSTRAINT_P(VALUE, C, STR) 1
#define EXTRA_CONSTRAINT(OP, C) \
s390_extra_constraint ((OP), (C))
#define EXTRA_CONSTRAINT_STR(OP, C, STR) \
s390_extra_constraint_str ((OP), (C), (STR))
#define EXTRA_MEMORY_CONSTRAINT(C, STR) \
((C) == 'Q' || (C) == 'R' || (C) == 'S' || (C) == 'T')
#define EXTRA_ADDRESS_CONSTRAINT(C, STR) \
((C) == 'U' || (C) == 'W' || (C) == 'Y')
#define CONSTRAINT_LEN(C, STR) \
((C) == 'N' ? 5 : DEFAULT_CONSTRAINT_LEN ((C), (STR)))
/* Stack layout and calling conventions. */
......
......@@ -28,17 +28,42 @@
;; 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.
;;
......@@ -430,10 +455,10 @@
(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));
......@@ -447,10 +472,10 @@
(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));
......@@ -464,10 +489,10 @@
(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));
......@@ -488,45 +513,30 @@
(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"
......@@ -1039,47 +1049,6 @@
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"))]
......@@ -1090,10 +1059,18 @@
(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
......@@ -1103,8 +1080,9 @@
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")
......@@ -1224,43 +1202,6 @@
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"))]
......@@ -1270,11 +1211,17 @@
[(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
......@@ -1286,8 +1233,24 @@
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" "")
......@@ -2503,14 +2466,12 @@
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)))]
......@@ -2526,14 +2487,12 @@
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)))]
......@@ -3193,7 +3152,7 @@
(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")])
......@@ -3421,7 +3380,7 @@
(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")])
......@@ -5009,37 +4968,23 @@
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")
......@@ -5090,36 +5035,41 @@
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")
......@@ -5263,37 +5213,20 @@
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")
......@@ -5344,36 +5277,39 @@
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")
......
......@@ -2196,13 +2196,52 @@ Unsigned 12-bit constant (0--4095)
Signed 16-bit constant (@minus{}32768--32767)
@item L
Unsigned 16-bit constant (0--65535)
Value appropriate as displacement.
@table @code
@item (0..4095)
for short displacement
@item (-524288..524287)
for long displacement
@end table
@item M
Constant integer with a value of 0x7fffffff.
@item N
Multiple letter constraint followed by 4 parameter letters.
@table @code
@item 0..9:
number of the part counting from most to least significant
@item H,Q:
mode of the part
@item D,S,H:
mode of the containing operand
@item 0,F:
value of the other parts (F - all bits set)
@end table
The constraint matches if the specified part of a constant
has a value different from it's other parts.
@item Q
Memory reference without index register
Memory reference without index register and with short displacement.
@item R
Memory reference with index register and short displacement.
@item S
Symbolic constant suitable for use with the @code{larl} instruction
Memory reference without index register but with long displacement.
@item T
Memory reference with index register and long displacement.
@item U
Pointer with short displacement.
@item W
Pointer with long displacement.
@item Y
Shift count operand.
@end table
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment