From f19a9af7e12657d431363e301fc31aec7d507684 Mon Sep 17 00:00:00 2001 From: Andreas Krebbel Date: Sun, 30 Nov 2003 15:51:36 +0000 Subject: [PATCH] s390.md ("tmdi_reg", [...]): Insns now use multiple letter constraints. 2003-11-30 Andreas Krebbel * 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 --- gcc/ChangeLog | 37 +++ gcc/config/s390/s390-protos.h | 9 +- gcc/config/s390/s390.c | 349 ++++++++++++-------------- gcc/config/s390/s390.h | 15 +- gcc/config/s390/s390.md | 444 +++++++++++++++------------------- gcc/doc/md.texi | 45 +++- 6 files changed, 431 insertions(+), 468 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9a7c5beedb7..2b9a4a93332 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,40 @@ +2003-11-30 Andreas Krebbel + + * 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 * Makefile.in ($(DESTDIR)$(infodir)/%.info): Fix missing semicolon. diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h index 1ab6b0933f1..c45ff4dcd0f 100644 --- a/gcc/config/s390/s390-protos.h +++ b/gcc/config/s390/s390-protos.h @@ -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); diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index c83316baf12..ef9c2130f12 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -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); diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h index e3eaf915604..cbe02d657f8 100644 --- a/gcc/config/s390/s390.h +++ b/gcc/config/s390/s390.h @@ -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. */ diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index 8b949830568..2b79f75f751 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -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") diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index ce59a0fd5ed..5e3618f78b3 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -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 -- 2.30.2