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> 2003-11-30 Andreas Schwab <schwab@suse.de>
* Makefile.in ($(DESTDIR)$(infodir)/%.info): Fix missing semicolon. * Makefile.in ($(DESTDIR)$(infodir)/%.info): Fix missing semicolon.
......
...@@ -30,7 +30,8 @@ extern void s390_emit_epilogue (void); ...@@ -30,7 +30,8 @@ extern void s390_emit_epilogue (void);
extern void s390_function_profiler (FILE *, int); extern void s390_function_profiler (FILE *, int);
#ifdef RTX_CODE #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 const0_operand (rtx, enum machine_mode);
extern int consttable_operand (rtx, enum machine_mode); extern int consttable_operand (rtx, enum machine_mode);
extern int larl_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); ...@@ -40,10 +41,8 @@ extern int shift_count_operand (rtx, enum machine_mode);
extern int bras_sym_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 load_multiple_operation (rtx, enum machine_mode);
extern int store_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_single_part (rtx, enum machine_mode, enum machine_mode, int);
extern int s390_extract_hi (rtx, enum machine_mode, int); extern unsigned HOST_WIDE_INT s390_extract_part (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 bool s390_split_ok_p (rtx, rtx, enum machine_mode, int); extern bool s390_split_ok_p (rtx, rtx, enum machine_mode, int);
extern int tls_symbolic_operand (rtx); extern int tls_symbolic_operand (rtx);
......
...@@ -374,7 +374,7 @@ s390_select_ccmode (enum rtx_code code, rtx op0, rtx op1) ...@@ -374,7 +374,7 @@ s390_select_ccmode (enum rtx_code code, rtx op0, rtx op1)
case EQ: case EQ:
case NE: case NE:
if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 1)) == CONST_INT 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; return CCAPmode;
if ((GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS if ((GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS
|| GET_CODE (op1) == NEG) || GET_CODE (op1) == NEG)
...@@ -410,7 +410,7 @@ s390_select_ccmode (enum rtx_code code, rtx op0, rtx op1) ...@@ -410,7 +410,7 @@ s390_select_ccmode (enum rtx_code code, rtx op0, rtx op1)
case GE: case GE:
case GT: case GT:
if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 1)) == CONST_INT 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) if (INTVAL (XEXP((op0), 1)) < 0)
return CCANmode; return CCANmode;
...@@ -760,153 +760,60 @@ s390_branch_condition_mnemonic (rtx code, int inv) ...@@ -760,153 +760,60 @@ s390_branch_condition_mnemonic (rtx code, int inv)
return mnemonic[mask]; return mnemonic[mask];
} }
/* If OP is an integer constant of mode MODE with exactly one /* Return the part of op which has a value different from def.
HImode subpart unequal to DEF, return the number of that The size of the part is determined by mode.
subpart. As a special case, all HImode subparts of OP are Use this function only if you already know that op really
equal to DEF, return zero. Otherwise, return -1. */ contains such a part. */
int unsigned HOST_WIDE_INT
s390_single_hi (rtx op, enum machine_mode mode, int def) s390_extract_part (rtx op, enum machine_mode mode, int def)
{ {
if (GET_CODE (op) == CONST_INT)
{
unsigned HOST_WIDE_INT value = 0; unsigned HOST_WIDE_INT value = 0;
int n_parts = GET_MODE_SIZE (mode) / 2; int max_parts = HOST_BITS_PER_WIDE_INT / GET_MODE_BITSIZE (mode);
int i, part = -1; int part_bits = GET_MODE_BITSIZE (mode);
unsigned HOST_WIDE_INT part_mask = (1 << part_bits) - 1;
int i;
for (i = 0; i < n_parts; i++) for (i = 0; i < max_parts; i++)
{ {
if (i == 0) if (i == 0)
value = (unsigned HOST_WIDE_INT) INTVAL (op); value = (unsigned HOST_WIDE_INT) INTVAL (op);
else else
value >>= 16; value >>= part_bits;
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) if ((value & part_mask) != (def & part_mask))
{ return value & part_mask;
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;
if (part < HOST_BITS_PER_WIDE_INT / 16)
value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (op);
else
value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (op),
part -= HOST_BITS_PER_WIDE_INT / 16;
return ((value >> (16 * part)) & 0xffff);
} }
abort (); abort ();
} }
/* If OP is an integer constant of mode MODE with exactly one /* If OP is an integer constant of mode MODE with exactly one
QImode subpart unequal to DEF, return the number of that part of mode PART_MODE unequal to DEF, return the number of that
subpart. As a special case, all QImode subparts of OP are part. Otherwise, return -1. */
equal to DEF, return zero. Otherwise, return -1. */
int int
s390_single_qi (rtx op, enum machine_mode mode, int def) s390_single_part (rtx op,
enum machine_mode mode,
enum machine_mode part_mode,
int def)
{ {
if (GET_CODE (op) == CONST_INT)
{
unsigned HOST_WIDE_INT value = 0; unsigned HOST_WIDE_INT value = 0;
int n_parts = GET_MODE_SIZE (mode); 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; int i, part = -1;
for (i = 0; i < n_parts; i++) if (GET_CODE (op) != CONST_INT)
{
if (i == 0)
value = (unsigned HOST_WIDE_INT) INTVAL (op);
else
value >>= 8;
if ((value & 0xff) != (unsigned)(def & 0xff))
{
if (part != -1)
return -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++) for (i = 0; i < n_parts; i++)
{ {
if (i == 0) if (i == 0)
value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (op); value = (unsigned HOST_WIDE_INT) INTVAL (op);
else if (i == HOST_BITS_PER_WIDE_INT / 8)
value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (op);
else else
value >>= 8; value >>= GET_MODE_BITSIZE (part_mode);
if ((value & 0xff) != (unsigned)(def & 0xff)) if ((value & part_mask) != (def & part_mask))
{ {
if (part != -1) if (part != -1)
return -1; return -1;
...@@ -914,44 +821,7 @@ s390_single_qi (rtx op, enum machine_mode mode, int def) ...@@ -914,44 +821,7 @@ s390_single_qi (rtx op, enum machine_mode mode, int def)
part = i; part = i;
} }
} }
return part == -1 ? -1 : n_parts - 1 - part;
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);
else
value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (op),
part -= HOST_BITS_PER_WIDE_INT / 8;
return ((value >> (8 * part)) & 0xff);
}
abort ();
} }
/* Check whether we can (and want to) split a double-word /* Check whether we can (and want to) split a double-word
...@@ -1353,10 +1223,13 @@ s390_short_displacement (rtx disp) ...@@ -1353,10 +1223,13 @@ s390_short_displacement (rtx disp)
/* Return true if OP is a valid operand for a C constraint. */ /* Return true if OP is a valid operand for a C constraint. */
int int
s390_extra_constraint (rtx op, int c) s390_extra_constraint_str (rtx op, int c, const char * str)
{ {
struct s390_address addr; struct s390_address addr;
if (c != str[0])
abort ();
switch (c) switch (c)
{ {
case 'Q': case 'Q':
...@@ -1442,6 +1315,78 @@ s390_extra_constraint (rtx op, int c) ...@@ -1442,6 +1315,78 @@ s390_extra_constraint (rtx op, int c)
return 1; 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 /* Compute a (partial) cost for rtx X. Return true if the complete
cost has been computed, and false if subexpressions should be cost has been computed, and false if subexpressions should be
scanned. In either case, *TOTAL contains the cost result. */ scanned. In either case, *TOTAL contains the cost result. */
...@@ -1866,12 +1811,12 @@ legitimate_reload_constant_p (register rtx op) ...@@ -1866,12 +1811,12 @@ legitimate_reload_constant_p (register rtx op)
/* Accept l(g)hi operands. */ /* Accept l(g)hi operands. */
if (GET_CODE (op) == CONST_INT 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; return 1;
/* Accept lliXX operands. */ /* Accept lliXX operands. */
if (TARGET_ZARCH if (TARGET_ZARCH
&& s390_single_hi (op, DImode, 0) >= 0) && s390_single_part (op, DImode, HImode, 0) >= 0)
return 1; return 1;
/* Accept larl operands. */ /* Accept larl operands. */
...@@ -3493,7 +3438,9 @@ print_operand_address (FILE *file, rtx addr) ...@@ -3493,7 +3438,9 @@ print_operand_address (FILE *file, rtx addr)
'b': print integer X as if it's an unsigned byte. 'b': print integer X as if it's an unsigned byte.
'x': print integer X as if it's an unsigned word. '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 void
print_operand (FILE *file, rtx x, int code) print_operand (FILE *file, rtx x, int code)
...@@ -3609,6 +3556,12 @@ 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); fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0xffff);
else if (code == 'h') else if (code == 'h')
fprintf (file, HOST_WIDE_INT_PRINT_DEC, ((INTVAL (x) & 0xffff) ^ 0x8000) - 0x8000); 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 else
fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x)); fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
break; break;
...@@ -5694,7 +5647,7 @@ s390_emit_prologue (void) ...@@ -5694,7 +5647,7 @@ s390_emit_prologue (void)
} }
else 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); frame_off = force_const_mem (Pmode, frame_off);
insn = emit_insn (gen_add2_insn (stack_pointer_rtx, frame_off)); insn = emit_insn (gen_add2_insn (stack_pointer_rtx, frame_off));
...@@ -5889,7 +5842,7 @@ s390_emit_epilogue (void) ...@@ -5889,7 +5842,7 @@ s390_emit_epilogue (void)
} }
else 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); frame_off = force_const_mem (Pmode, frame_off);
insn = emit_insn (gen_add2_insn (frame_pointer, 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, ...@@ -6898,9 +6851,9 @@ s390_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
{ {
/* Setup literal pool pointer if required. */ /* Setup literal pool pointer if required. */
if ((!DISP_IN_RANGE (delta) 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) || (!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 (); op[5] = gen_label_rtx ();
output_asm_insn ("larl\t%4,%5", op); output_asm_insn ("larl\t%4,%5", op);
...@@ -6909,11 +6862,11 @@ s390_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED, ...@@ -6909,11 +6862,11 @@ s390_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
/* Add DELTA to this pointer. */ /* Add DELTA to this pointer. */
if (delta) 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); output_asm_insn ("la\t%1,%2(%1)", op);
else if (DISP_IN_RANGE (delta)) else if (DISP_IN_RANGE (delta))
output_asm_insn ("lay\t%1,%2(%1)", op); 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); output_asm_insn ("aghi\t%1,%2", op);
else else
{ {
...@@ -6930,7 +6883,7 @@ s390_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED, ...@@ -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 ("lg\t%4,0(%1)", op);
output_asm_insn ("ag\t%1,%3(%4)", 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 ("lghi\t%4,%3", op);
output_asm_insn ("ag\t%4,0(%1)", op); output_asm_insn ("ag\t%4,0(%1)", op);
...@@ -6973,9 +6926,9 @@ s390_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED, ...@@ -6973,9 +6926,9 @@ s390_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
/* Setup base pointer if required. */ /* Setup base pointer if required. */
if (!vcall_offset if (!vcall_offset
|| (!DISP_IN_RANGE (delta) || (!DISP_IN_RANGE (delta)
&& !CONST_OK_FOR_LETTER_P (delta, 'K')) && !CONST_OK_FOR_CONSTRAINT_P (delta, 'K', "K"))
|| (!DISP_IN_RANGE (delta) || (!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 (); op[5] = gen_label_rtx ();
output_asm_insn ("basr\t%4,0", op); output_asm_insn ("basr\t%4,0", op);
...@@ -6986,11 +6939,11 @@ s390_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED, ...@@ -6986,11 +6939,11 @@ s390_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
/* Add DELTA to this pointer. */ /* Add DELTA to this pointer. */
if (delta) 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); output_asm_insn ("la\t%1,%2(%1)", op);
else if (DISP_IN_RANGE (delta)) else if (DISP_IN_RANGE (delta))
output_asm_insn ("lay\t%1,%2(%1)", op); 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); output_asm_insn ("ahi\t%1,%2", op);
else else
{ {
...@@ -7002,7 +6955,7 @@ s390_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED, ...@@ -7002,7 +6955,7 @@ s390_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
/* Perform vcall adjustment. */ /* Perform vcall adjustment. */
if (vcall_offset) 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 ("lg\t%4,0(%1)", op);
output_asm_insn ("a\t%1,%3(%4)", op); output_asm_insn ("a\t%1,%3(%4)", op);
...@@ -7012,7 +6965,7 @@ s390_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED, ...@@ -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 ("lg\t%4,0(%1)", op);
output_asm_insn ("ay\t%1,%3(%4)", 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 ("lhi\t%4,%3", op);
output_asm_insn ("a\t%4,0(%1)", op); output_asm_insn ("a\t%4,0(%1)", op);
......
...@@ -536,21 +536,20 @@ extern const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER]; ...@@ -536,21 +536,20 @@ extern const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER];
(C) == 'd' ? GENERAL_REGS : \ (C) == 'd' ? GENERAL_REGS : \
(C) == 'f' ? FP_REGS : NO_REGS) (C) == 'f' ? FP_REGS : NO_REGS)
#define CONST_OK_FOR_LETTER_P(VALUE, C) \ #define CONST_OK_FOR_CONSTRAINT_P(VALUE, C, STR) \
((C) == 'I' ? (unsigned long) (VALUE) < 256 : \ s390_const_ok_for_constraint_p ((VALUE), (C), (STR))
(C) == 'J' ? (unsigned long) (VALUE) < 4096 : \
(C) == 'K' ? (VALUE) >= -32768 && (VALUE) < 32768 : \
(C) == 'L' ? (unsigned long) (VALUE) < 65536 : 0)
#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) \ #define EXTRA_CONSTRAINT_STR(OP, C, STR) \
s390_extra_constraint ((OP), (C)) s390_extra_constraint_str ((OP), (C), (STR))
#define EXTRA_MEMORY_CONSTRAINT(C, STR) \ #define EXTRA_MEMORY_CONSTRAINT(C, STR) \
((C) == 'Q' || (C) == 'R' || (C) == 'S' || (C) == 'T') ((C) == 'Q' || (C) == 'R' || (C) == 'S' || (C) == 'T')
#define EXTRA_ADDRESS_CONSTRAINT(C, STR) \ #define EXTRA_ADDRESS_CONSTRAINT(C, STR) \
((C) == 'U' || (C) == 'W' || (C) == 'Y') ((C) == 'U' || (C) == 'W' || (C) == 'Y')
#define CONSTRAINT_LEN(C, STR) \
((C) == 'N' ? 5 : DEFAULT_CONSTRAINT_LEN ((C), (STR)))
/* Stack layout and calling conventions. */ /* Stack layout and calling conventions. */
......
...@@ -28,17 +28,42 @@ ...@@ -28,17 +28,42 @@
;; I -- An 8-bit constant (0..255). ;; I -- An 8-bit constant (0..255).
;; J -- A 12-bit constant (0..4095). ;; J -- A 12-bit constant (0..4095).
;; K -- A 16-bit constant (-32768..32767). ;; K -- A 16-bit constant (-32768..32767).
;; Q -- A memory reference without index-register. ;; L -- Value appropriate as displacement.
;; S -- Valid operand for the LARL instruction. ;; (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. ;; Special formats used for outputting 390 instructions.
;; ;;
;; %b -- Print a constant byte integer. xy ;; %C: print opcode suffix for branch condition.
;; %h -- Print a signed 16-bit. wxyz ;; %D: print opcode suffix for inverse branch condition.
;; %N -- Print next register (second word of a DImode reg) or next word. ;; %J: print tls_load/tls_gdcall/tls_ldcall suffix
;; %M -- Print next register (second word of a TImode reg) or next word. ;; %O: print only the displacement of a memory reference.
;; %O -- Print the offset of a memory reference (PLUS (REG) (CONST_INT)). ;; %R: print only the base register of a memory reference.
;; %R -- Print the register of a memory reference (PLUS (REG) (CONST_INT)). ;; %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. ;; We have a special constraint for pattern matching.
;; ;;
...@@ -430,10 +455,10 @@ ...@@ -430,10 +455,10 @@
(match_operand:DI 1 "immediate_operand" "n,n")) (match_operand:DI 1 "immediate_operand" "n,n"))
(match_operand:DI 2 "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_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); int part = s390_single_part (operands[1], DImode, QImode, 0);
operands[1] = GEN_INT (s390_extract_qi (operands[1], DImode, part)); operands[1] = GEN_INT (s390_extract_part (operands[1], QImode, 0));
operands[0] = gen_rtx_MEM (QImode, operands[0] = gen_rtx_MEM (QImode,
plus_constant (XEXP (operands[0], 0), part)); plus_constant (XEXP (operands[0], 0), part));
...@@ -447,10 +472,10 @@ ...@@ -447,10 +472,10 @@
(match_operand:SI 1 "immediate_operand" "n,n")) (match_operand:SI 1 "immediate_operand" "n,n"))
(match_operand:SI 2 "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_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); int part = s390_single_part (operands[1], SImode, QImode, 0);
operands[1] = GEN_INT (s390_extract_qi (operands[1], SImode, part)); operands[1] = GEN_INT (s390_extract_part (operands[1], QImode, 0));
operands[0] = gen_rtx_MEM (QImode, operands[0] = gen_rtx_MEM (QImode,
plus_constant (XEXP (operands[0], 0), part)); plus_constant (XEXP (operands[0], 0), part));
...@@ -464,10 +489,10 @@ ...@@ -464,10 +489,10 @@
(match_operand:SI 1 "immediate_operand" "n,n")) (match_operand:SI 1 "immediate_operand" "n,n"))
(match_operand:SI 2 "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_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); int part = s390_single_part (operands[1], HImode, QImode, 0);
operands[1] = GEN_INT (s390_extract_qi (operands[1], HImode, part)); operands[1] = GEN_INT (s390_extract_part (operands[1], QImode, 0));
operands[0] = gen_rtx_MEM (QImode, operands[0] = gen_rtx_MEM (QImode,
plus_constant (XEXP (operands[0], 0), part)); plus_constant (XEXP (operands[0], 0), part));
...@@ -488,45 +513,30 @@ ...@@ -488,45 +513,30 @@
(define_insn "*tmdi_reg" (define_insn "*tmdi_reg"
[(set (reg 33) [(set (reg 33)
(compare (and:DI (match_operand:DI 0 "nonimmediate_operand" "d") (compare (and:DI (match_operand:DI 0 "nonimmediate_operand" "d,d,d,d")
(match_operand:DI 1 "immediate_operand" "n")) (match_operand:DI 1 "immediate_operand"
(match_operand:DI 2 "immediate_operand" "n")))] "N0HD0,N1HD0,N2HD0,N3HD0"))
(match_operand:DI 2 "immediate_operand" "n,n,n,n")))]
"TARGET_64BIT "TARGET_64BIT
&& s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 1)) && s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 1))
&& s390_single_hi (operands[1], DImode, 0) >= 0" && s390_single_part (operands[1], DImode, HImode, 0) >= 0"
{ "@
int part = s390_single_hi (operands[1], DImode, 0); tmhh\t%0,%i1
operands[1] = GEN_INT (s390_extract_hi (operands[1], DImode, part)); tmhl\t%0,%i1
tmlh\t%0,%i1
switch (part) tmll\t%0,%i1"
{
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 ();
}
}
[(set_attr "op_type" "RI")]) [(set_attr "op_type" "RI")])
(define_insn "*tmsi_reg" (define_insn "*tmsi_reg"
[(set (reg 33) [(set (reg 33)
(compare (and:SI (match_operand:SI 0 "nonimmediate_operand" "d") (compare (and:SI (match_operand:SI 0 "nonimmediate_operand" "d,d")
(match_operand:SI 1 "immediate_operand" "n")) (match_operand:SI 1 "immediate_operand" "N0HS0,N1HS0"))
(match_operand:SI 2 "immediate_operand" "n")))] (match_operand:SI 2 "immediate_operand" "n,n")))]
"s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 1)) "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 1))
&& s390_single_hi (operands[1], SImode, 0) >= 0" && s390_single_part (operands[1], SImode, HImode, 0) >= 0"
{ "@
int part = s390_single_hi (operands[1], SImode, 0); tmh\t%0,%i1
operands[1] = GEN_INT (s390_extract_hi (operands[1], SImode, part)); tml\t%0,%i1"
switch (part)
{
case 0: return "tmh\t%0,%x1";
case 1: return "tml\t%0,%x1";
default: abort ();
}
}
[(set_attr "op_type" "RI")]) [(set_attr "op_type" "RI")])
(define_insn "*tmhi_full" (define_insn "*tmhi_full"
...@@ -1039,47 +1049,6 @@ ...@@ -1039,47 +1049,6 @@
operands[1] = force_const_mem (DImode, operands[1]); 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" (define_insn "*movdi_larl"
[(set (match_operand:DI 0 "register_operand" "=d") [(set (match_operand:DI 0 "register_operand" "=d")
(match_operand:DI 1 "larl_operand" "X"))] (match_operand:DI 1 "larl_operand" "X"))]
...@@ -1090,10 +1059,18 @@ ...@@ -1090,10 +1059,18 @@
(set_attr "type" "larl")]) (set_attr "type" "larl")])
(define_insn "*movdi_64" (define_insn "*movdi_64"
[(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,m,!*f,!*f,!*f,!R,!T,?Q") [(set (match_operand:DI 0 "nonimmediate_operand"
(match_operand:DI 1 "general_operand" "d,m,d,*f,R,T,*f,*f,?Q"))] "=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" "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 lgr\t%0,%1
lg\t%0,%1 lg\t%0,%1
stg\t%1,%0 stg\t%1,%0
...@@ -1103,8 +1080,9 @@ ...@@ -1103,8 +1080,9 @@
std\t%1,%0 std\t%1,%0
stdy\t%1,%0 stdy\t%1,%0
mvc\t%O0(8,%R0),%1" mvc\t%O0(8,%R0),%1"
[(set_attr "op_type" "RRE,RXY,RXY,RR,RX,RXY,RX,RXY,SS") [(set_attr "op_type" "RI,RI,RI,RI,RI,RXY,RRE,RXY,RXY,RR,RX,RXY,RX,RXY,SS")
(set_attr "type" "lr,load,store,floadd,floadd,floadd,fstored,fstored,cs")]) (set_attr "type" "*,*,*,*,*,la,lr,load,store,floadd,floadd,floadd,
fstored,fstored,cs")])
(define_insn "*movdi_31" (define_insn "*movdi_31"
[(set (match_operand:DI 0 "nonimmediate_operand" "=d,Q,d,o,!*f,!*f,!*f,!R,!T,Q") [(set (match_operand:DI 0 "nonimmediate_operand" "=d,Q,d,o,!*f,!*f,!*f,!R,!T,Q")
...@@ -1224,43 +1202,6 @@ ...@@ -1224,43 +1202,6 @@
operands[1] = force_const_mem (SImode, operands[1]); 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" (define_insn "*movsi_larl"
[(set (match_operand:SI 0 "register_operand" "=d") [(set (match_operand:SI 0 "register_operand" "=d")
(match_operand:SI 1 "larl_operand" "X"))] (match_operand:SI 1 "larl_operand" "X"))]
...@@ -1270,11 +1211,17 @@ ...@@ -1270,11 +1211,17 @@
[(set_attr "op_type" "RIL") [(set_attr "op_type" "RIL")
(set_attr "type" "larl")]) (set_attr "type" "larl")])
(define_insn "*movsi" (define_insn "*movsi_zarch"
[(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,R,T,!*f,!*f,!*f,!R,!T,?Q") [(set (match_operand:SI 0 "nonimmediate_operand"
(match_operand:SI 1 "general_operand" "d,R,T,d,d,*f,R,T,*f,*f,?Q"))] "=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 lr\t%0,%1
l\t%0,%1 l\t%0,%1
ly\t%0,%1 ly\t%0,%1
...@@ -1286,8 +1233,24 @@ ...@@ -1286,8 +1233,24 @@
ste\t%1,%0 ste\t%1,%0
stey\t%1,%0 stey\t%1,%0
mvc\t%O0(4,%R0),%1" mvc\t%O0(4,%R0),%1"
[(set_attr "op_type" "RR,RX,RXY,RX,RXY,RR,RX,RXY,RX,RXY,SS") [(set_attr "op_type" "RI,RI,RI,RXY,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 "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 (define_peephole2
[(set (match_operand:SI 0 "register_operand" "") [(set (match_operand:SI 0 "register_operand" "")
...@@ -2503,14 +2466,12 @@ ...@@ -2503,14 +2466,12 @@
llgt\t%0,%1" llgt\t%0,%1"
[(set_attr "op_type" "RRE,RXE")]) [(set_attr "op_type" "RRE,RXE")])
(define_insn_and_split "*llgt_sisi_split" (define_split
[(set (match_operand:SI 0 "register_operand" "=d,d") [(set (match_operand:SI 0 "register_operand" "")
(and:SI (match_operand:SI 1 "nonimmediate_operand" "d,m") (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
(const_int 2147483647))) (const_int 2147483647)))
(clobber (reg:CC 33))] (clobber (reg:CC 33))]
"TARGET_64BIT" "TARGET_64BIT && reload_completed"
"#"
"&& reload_completed"
[(set (match_dup 0) [(set (match_dup 0)
(and:SI (match_dup 1) (and:SI (match_dup 1)
(const_int 2147483647)))] (const_int 2147483647)))]
...@@ -2526,14 +2487,12 @@ ...@@ -2526,14 +2487,12 @@
llgt\t%0,%N1" llgt\t%0,%N1"
[(set_attr "op_type" "RRE,RXE")]) [(set_attr "op_type" "RRE,RXE")])
(define_insn_and_split "*llgt_didi_split" (define_split
[(set (match_operand:DI 0 "register_operand" "=d,d") [(set (match_operand:DI 0 "register_operand" "")
(and:DI (match_operand:DI 1 "nonimmediate_operand" "d,o") (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
(const_int 2147483647))) (const_int 2147483647)))
(clobber (reg:CC 33))] (clobber (reg:CC 33))]
"TARGET_64BIT" "TARGET_64BIT && reload_completed"
"#"
"&& reload_completed"
[(set (match_dup 0) [(set (match_dup 0)
(and:DI (match_dup 1) (and:DI (match_dup 1)
(const_int 2147483647)))] (const_int 2147483647)))]
...@@ -3193,7 +3152,7 @@ ...@@ -3193,7 +3152,7 @@
(plus:DI (match_dup 1) (match_dup 2)))] (plus:DI (match_dup 1) (match_dup 2)))]
"TARGET_64BIT "TARGET_64BIT
&& s390_match_ccmode (insn, CCAmode) && 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" "aghi\t%0,%h2"
[(set_attr "op_type" "RI")]) [(set_attr "op_type" "RI")])
...@@ -3421,7 +3380,7 @@ ...@@ -3421,7 +3380,7 @@
(set (match_operand:SI 0 "register_operand" "=d") (set (match_operand:SI 0 "register_operand" "=d")
(plus:SI (match_dup 1) (match_dup 2)))] (plus:SI (match_dup 1) (match_dup 2)))]
"s390_match_ccmode (insn, CCAmode) "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" "ahi\t%0,%h2"
[(set_attr "op_type" "RI")]) [(set_attr "op_type" "RI")])
...@@ -5009,37 +4968,23 @@ ...@@ -5009,37 +4968,23 @@
ng\t%0,%2" ng\t%0,%2"
[(set_attr "op_type" "RRE,RXY")]) [(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" (define_insn "anddi3"
[(set (match_operand:DI 0 "register_operand" "=d,d") [(set (match_operand:DI 0 "register_operand" "=d,d,d,d,d,d,d,d")
(and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,o,0,0,0,0,0,0")
(match_operand:DI 2 "general_operand" "d,m"))) (match_operand:DI 2 "general_operand"
"M,M,N0HDF,N1HDF,N2HDF,N3HDF,d,m")))
(clobber (reg:CC 33))] (clobber (reg:CC 33))]
"TARGET_64BIT" "TARGET_64BIT"
"@ "@
#
#
nihh\t%0,%j2
nihl\t%0,%j2
nilh\t%0,%j2
nill\t%0,%j2
ngr\t%0,%2 ngr\t%0,%2
ng\t%0,%2" ng\t%0,%2"
[(set_attr "op_type" "RRE,RXY")]) [(set_attr "op_type" "RRE,RXE,RI,RI,RI,RI,RRE,RXY")])
(define_insn "*anddi3_ss" (define_insn "*anddi3_ss"
[(set (match_operand:DI 0 "s_operand" "=Q") [(set (match_operand:DI 0 "s_operand" "=Q")
...@@ -5090,36 +5035,41 @@ ...@@ -5090,36 +5035,41 @@
ny\t%0,%2" ny\t%0,%2"
[(set_attr "op_type" "RR,RX,RXY")]) [(set_attr "op_type" "RR,RX,RXY")])
(define_insn "*andsi3_ni" (define_expand "andsi3"
[(set (match_operand:SI 0 "register_operand" "=d") [(parallel
(and:SI (match_operand:SI 1 "nonimmediate_operand" "0") [(set (match_operand:SI 0 "register_operand" "")
(match_operand:SI 2 "immediate_operand" "n"))) (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
(clobber (reg:CC 33))] (match_operand:SI 2 "general_operand" "")))
"TARGET_ZARCH && s390_single_hi (operands[2], SImode, -1) >= 0" (clobber (reg:CC 33))])]
{ ""
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_insn "andsi3" (define_insn "*andsi3_zarch"
[(set (match_operand:SI 0 "register_operand" "=d,d,d") [(set (match_operand:SI 0 "register_operand" "=d,d,d,d,d,d,d")
(and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0") (and:SI (match_operand:SI 1 "nonimmediate_operand" "d,o,0,0,0,0,0")
(match_operand:SI 2 "general_operand" "d,R,T"))) (match_operand:SI 2 "general_operand" "M,M,N0HSF,N1HSF,d,R,T")))
(clobber (reg:CC 33))] (clobber (reg:CC 33))]
"" "TARGET_ZARCH"
"@ "@
#
#
nilh\t%0,%j2
nill\t%0,%j2
nr\t%0,%2 nr\t%0,%2
n\t%0,%2 n\t%0,%2
ny\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" (define_insn "*andsi3_ss"
[(set (match_operand:SI 0 "s_operand" "=Q") [(set (match_operand:SI 0 "s_operand" "=Q")
...@@ -5263,37 +5213,20 @@ ...@@ -5263,37 +5213,20 @@
og\t%0,%2" og\t%0,%2"
[(set_attr "op_type" "RRE,RXY")]) [(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" (define_insn "iordi3"
[(set (match_operand:DI 0 "register_operand" "=d,d") [(set (match_operand:DI 0 "register_operand" "=d,d,d,d,d,d")
(ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") (ior:DI (match_operand:DI 1 "nonimmediate_operand" "0,0,0,0,0,0")
(match_operand:DI 2 "general_operand" "d,m"))) (match_operand:DI 2 "general_operand" "N0HD0,N1HD0,N2HD0,N3HD0,d,m")))
(clobber (reg:CC 33))] (clobber (reg:CC 33))]
"TARGET_64BIT" "TARGET_64BIT"
"@ "@
oihh\t%0,%i2
oihl\t%0,%i2
oilh\t%0,%i2
oill\t%0,%i2
ogr\t%0,%2 ogr\t%0,%2
og\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" (define_insn "*iordi3_ss"
[(set (match_operand:DI 0 "s_operand" "=Q") [(set (match_operand:DI 0 "s_operand" "=Q")
...@@ -5344,36 +5277,39 @@ ...@@ -5344,36 +5277,39 @@
oy\t%0,%2" oy\t%0,%2"
[(set_attr "op_type" "RR,RX,RXY")]) [(set_attr "op_type" "RR,RX,RXY")])
(define_insn "*iorsi3_oi" (define_expand "iorsi3"
[(set (match_operand:SI 0 "register_operand" "=d") [(parallel
(ior:SI (match_operand:SI 1 "nonimmediate_operand" "0") [(set (match_operand:SI 0 "register_operand" "")
(match_operand:SI 2 "immediate_operand" "n"))) (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
(clobber (reg:CC 33))] (match_operand:SI 2 "general_operand" "")))
"TARGET_ZARCH && s390_single_hi (operands[2], SImode, 0) >= 0" (clobber (reg:CC 33))])]
{ ""
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_insn "iorsi3" (define_insn "iorsi3_zarch"
[(set (match_operand:SI 0 "register_operand" "=d,d,d") [(set (match_operand:SI 0 "register_operand" "=d,d,d,d,d")
(ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0") (ior:SI (match_operand:SI 1 "nonimmediate_operand" "0,0,0,0,0")
(match_operand:SI 2 "general_operand" "d,R,T"))) (match_operand:SI 2 "general_operand" "N0HS0,N1HS0,d,R,T")))
(clobber (reg:CC 33))] (clobber (reg:CC 33))]
"" "TARGET_ZARCH"
"@ "@
oilh\t%0,%i2
oill\t%0,%i2
or\t%0,%2 or\t%0,%2
o\t%0,%2 o\t%0,%2
oy\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" (define_insn "*iorsi3_ss"
[(set (match_operand:SI 0 "s_operand" "=Q") [(set (match_operand:SI 0 "s_operand" "=Q")
......
...@@ -2196,13 +2196,52 @@ Unsigned 12-bit constant (0--4095) ...@@ -2196,13 +2196,52 @@ Unsigned 12-bit constant (0--4095)
Signed 16-bit constant (@minus{}32768--32767) Signed 16-bit constant (@minus{}32768--32767)
@item L @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 @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 @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 @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