diff options
author | Ulrich Weigand <uweigand@de.ibm.com> | 2001-09-29 22:56:14 +0000 |
---|---|---|
committer | Ulrich Weigand <uweigand@gcc.gnu.org> | 2001-09-29 22:56:14 +0000 |
commit | ba95698296f3733f461f9732b3be5c8dc20cee6a (patch) | |
tree | 78a147c5f5a1ff5ea621fbfe6e1fbe64a319a2bb | |
parent | 3d17d93d9fe5c1141c319158e756f6b9b6300f86 (diff) | |
download | gcc-ba95698296f3733f461f9732b3be5c8dc20cee6a.zip gcc-ba95698296f3733f461f9732b3be5c8dc20cee6a.tar.gz gcc-ba95698296f3733f461f9732b3be5c8dc20cee6a.tar.bz2 |
s390.h (EXTRA_CC_MODES): Add CCLmode.
* config/s390/s390.h (EXTRA_CC_MODES): Add CCLmode.
(SELECT_CC_MODE): Use s390_select_ccmode.
* config/s390/s390-protos.h (s390_select_ccmode): Add.
* config/s390/s390.c (s390_select_ccmode): New.
(s390_match_ccmode): Add CCLmode.
(s390_branch_condition_mask, s390_branch_condition_mnemonic): New.
(output_branch_condition, output_inverse_branch_condition): Removed.
(print_operand): Use s390_branch_condition_mnemonic.
* config/s390/s390.md (addsi3_cc, addsi3_cconly, addsi3_cconly2,
subsi3_cc, subsi3_cconly): Use logical instructions and CCLmode.
(bunordered, bordered, buneq, bungt, bunlt, bnuge, bunle, bltgt): New.
* config/s390/s390.c (check_and_change_labels): Preserve CC mode
when converting conditional branches to far branches.
* config/s390/s390.md (cmpstr_const, cmpstr_64, cmpstr_31, cmpint_si,
cmpint_di): Use CCSmode instead of CCUmode.
* config/s390/s390.c (legitimate_la_operand_p): New.
* config/s390/s390-protos.h (legitimate_la_operand_p): Add.
* config/s390/s390.md (movsi): Convert load address patterns to
arithmetic operations when necessary.
(addaddr_picR, addaddr_picL, addaddr_picN): Removed.
(do_la): Renamed to *do_la and use legitimate_la_operand_p.
(*do_la_reg_0): Don't use before reload.
* config/s390/s390.c (legitimize_address): Make more efficient
use of two-register addressing mode.
* config/s390/s390.c (s390_function_prologue): Fix incorrect prolog
with -mno-backchain in some corner cases.
* config/s390/s390.md (cmpsi_cct): Operands 0 and 1 do not commute.
From-SVN: r45891
-rw-r--r-- | gcc/ChangeLog | 35 | ||||
-rw-r--r-- | gcc/config/s390/s390-protos.h | 2 | ||||
-rw-r--r-- | gcc/config/s390/s390.c | 331 | ||||
-rw-r--r-- | gcc/config/s390/s390.h | 9 | ||||
-rw-r--r-- | gcc/config/s390/s390.md | 202 |
5 files changed, 412 insertions, 167 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8e5d182..c89d7c8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,38 @@ +2001-09-30 Ulrich Weigand <uweigand@de.ibm.com> + + * config/s390/s390.h (EXTRA_CC_MODES): Add CCLmode. + (SELECT_CC_MODE): Use s390_select_ccmode. + * config/s390/s390-protos.h (s390_select_ccmode): Add. + * config/s390/s390.c (s390_select_ccmode): New. + (s390_match_ccmode): Add CCLmode. + (s390_branch_condition_mask, s390_branch_condition_mnemonic): New. + (output_branch_condition, output_inverse_branch_condition): Removed. + (print_operand): Use s390_branch_condition_mnemonic. + * config/s390/s390.md (addsi3_cc, addsi3_cconly, addsi3_cconly2, + subsi3_cc, subsi3_cconly): Use logical instructions and CCLmode. + (bunordered, bordered, buneq, bungt, bunlt, bnuge, bunle, bltgt): New. + + * config/s390/s390.c (check_and_change_labels): Preserve CC mode + when converting conditional branches to far branches. + * config/s390/s390.md (cmpstr_const, cmpstr_64, cmpstr_31, cmpint_si, + cmpint_di): Use CCSmode instead of CCUmode. + + * config/s390/s390.c (legitimate_la_operand_p): New. + * config/s390/s390-protos.h (legitimate_la_operand_p): Add. + * config/s390/s390.md (movsi): Convert load address patterns to + arithmetic operations when necessary. + (addaddr_picR, addaddr_picL, addaddr_picN): Removed. + (do_la): Renamed to *do_la and use legitimate_la_operand_p. + (*do_la_reg_0): Don't use before reload. + + * config/s390/s390.c (legitimize_address): Make more efficient + use of two-register addressing mode. + + * config/s390/s390.c (s390_function_prologue): Fix incorrect prolog + with -mno-backchain in some corner cases. + + * config/s390/s390.md (cmpsi_cct): Operands 0 and 1 do not commute. + 2001-09-29 Alexandre Oliva <aoliva@redhat.com> * reload.c (find_reloads): Mark new USE insns with QImode. diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h index 7f16843..baee5a0 100644 --- a/gcc/config/s390/s390-protos.h +++ b/gcc/config/s390/s390-protos.h @@ -42,7 +42,9 @@ extern int load_multiple_operation PARAMS ((rtx, enum machine_mode)); extern int store_multiple_operation PARAMS ((rtx, enum machine_mode)); extern int s390_match_ccmode PARAMS ((rtx, enum machine_mode)); +extern enum machine_mode s390_select_ccmode PARAMS ((enum rtx_code, rtx, rtx)); extern int symbolic_reference_mentioned_p PARAMS ((rtx)); +extern int legitimate_la_operand_p PARAMS ((rtx)); extern int legitimate_pic_operand_p PARAMS ((rtx)); extern int legitimate_constant_p PARAMS ((rtx)); extern int legitimate_address_p PARAMS ((enum machine_mode, rtx, int)); diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index e4bc735..647a5fd 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -94,11 +94,11 @@ struct s390_address }; static int s390_match_ccmode_set PARAMS ((rtx, enum machine_mode)); +static int s390_branch_condition_mask PARAMS ((rtx)); +static const char *s390_branch_condition_mnemonic PARAMS ((rtx, int)); static int base_n_index_p PARAMS ((rtx)); static int check_mode PARAMS ((rtx, enum machine_mode *)); static int s390_decompose_address PARAMS ((rtx, struct s390_address *, int)); -static void output_branch_condition PARAMS ((FILE *, rtx)); -static void output_inverse_branch_condition PARAMS ((FILE *, rtx)); static int reg_used_in_mem_p PARAMS ((int, rtx)); static int addr_generation_dependency_p PARAMS ((rtx, rtx)); static int other_chunk PARAMS ((int *, int, int)); @@ -135,9 +135,6 @@ s390_match_ccmode_set (set, req_mode) set_mode = GET_MODE (SET_DEST (set)); switch (set_mode) { - case CCmode: - return 0; - case CCSmode: if (req_mode != CCSmode) return 0; @@ -146,6 +143,10 @@ s390_match_ccmode_set (set, req_mode) if (req_mode != CCUmode) return 0; break; + case CCLmode: + if (req_mode != CCLmode) + return 0; + break; case CCZmode: if (req_mode != CCSmode && req_mode != CCUmode && req_mode != CCTmode) return 0; @@ -184,6 +185,161 @@ s390_match_ccmode (insn, req_mode) return 1; } +/* Given a comparison code OP (EQ, NE, etc.) and the operands + OP0 and OP1 of a COMPARE, return the mode to be used for the + comparison. */ + +enum machine_mode +s390_select_ccmode (code, op0, op1) + enum rtx_code code; + rtx op0; + rtx op1; +{ + switch (code) + { + case EQ: + case NE: + if (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS + || GET_CODE (op1) == NEG) + return CCLmode; + + return CCZmode; + + case LE: + case LT: + case GE: + case GT: + case UNORDERED: + case ORDERED: + case UNEQ: + case UNLE: + case UNLT: + case UNGE: + case UNGT: + case LTGT: + return CCSmode; + + case LEU: + case LTU: + case GEU: + case GTU: + return CCUmode; + + default: + abort (); + } +} + +/* Return branch condition mask to implement a branch + specified by CODE. */ + +static int +s390_branch_condition_mask (code) + rtx code; +{ + const int CC0 = 1 << 3; + const int CC1 = 1 << 2; + const int CC2 = 1 << 1; + const int CC3 = 1 << 0; + + if (GET_CODE (XEXP (code, 0)) != REG + || REGNO (XEXP (code, 0)) != CC_REGNUM + || XEXP (code, 1) != const0_rtx) + abort (); + + switch (GET_MODE (XEXP (code, 0))) + { + case CCZmode: + switch (GET_CODE (code)) + { + case EQ: return CC0; + case NE: return CC1 | CC2 | CC3; + default: + abort (); + } + break; + + case CCLmode: + switch (GET_CODE (code)) + { + case EQ: return CC0 | CC2; + case NE: return CC1 | CC3; + case UNORDERED: return CC2 | CC3; /* carry */ + case ORDERED: return CC0 | CC1; /* no carry */ + default: + abort (); + } + break; + + case CCUmode: + switch (GET_CODE (code)) + { + case EQ: return CC0; + case NE: return CC1 | CC2 | CC3; + case LTU: return CC1; + case GTU: return CC2; + case LEU: return CC0 | CC1; + case GEU: return CC0 | CC2; + default: + abort (); + } + break; + + case CCSmode: + switch (GET_CODE (code)) + { + case EQ: return CC0; + case NE: return CC1 | CC2 | CC3; + case LT: return CC1; + case GT: return CC2; + case LE: return CC0 | CC1; + case GE: return CC0 | CC2; + case UNORDERED: return CC3; + case ORDERED: return CC0 | CC1 | CC2; + case UNEQ: return CC0 | CC3; + case UNLT: return CC1 | CC3; + case UNGT: return CC2 | CC3; + case UNLE: return CC0 | CC1 | CC3; + case UNGE: return CC0 | CC2 | CC3; + case LTGT: return CC1 | CC2; + default: + abort (); + } + + default: + abort (); + } +} + +/* If INV is false, return assembler mnemonic string to implement + a branch specified by CODE. If INV is true, return mnemonic + for the corresponding inverted branch. */ + +static const char * +s390_branch_condition_mnemonic (code, inv) + rtx code; + int inv; +{ + static const char *mnemonic[16] = + { + NULL, "o", "h", "nle", + "l", "nhe", "lh", "ne", + "e", "nlh", "he", "nl", + "le", "nh", "no", NULL + }; + + int mask = s390_branch_condition_mask (code); + + if (inv) + mask ^= 15; + + if (mask < 1 || mask > 14) + abort (); + + return mnemonic[mask]; +} + + /* Change optimizations to be performed, depending on the optimization level. @@ -887,6 +1043,40 @@ legitimate_address_p (mode, addr, strict) return s390_decompose_address (addr, NULL, strict); } +/* Return 1 if OP is a valid operand for the LA instruction. + In 31-bit, we need to prove that the result is used as an + address, as LA performs only a 31-bit addition. */ + +int +legitimate_la_operand_p (op) + register rtx op; +{ + struct s390_address addr; + if (!s390_decompose_address (op, &addr, FALSE)) + return FALSE; + + if (TARGET_64BIT) + return TRUE; + + /* Use of the base or stack pointer implies address. */ + + if (addr.base && GET_CODE (addr.base) == REG) + { + if (REGNO (addr.base) == BASE_REGISTER + || REGNO (addr.base) == STACK_POINTER_REGNUM) + return TRUE; + } + + if (addr.indx && GET_CODE (addr.indx) == REG) + { + if (REGNO (addr.indx) == BASE_REGISTER + || REGNO (addr.indx) == STACK_POINTER_REGNUM) + return TRUE; + } + + return FALSE; +} + /* Return a legitimate reference for ORIG (an address) using the register REG. If REG is 0, a new pseudo is generated. @@ -1199,87 +1389,52 @@ legitimize_address (x, oldx, mode) register rtx oldx ATTRIBUTE_UNUSED; enum machine_mode mode ATTRIBUTE_UNUSED; { - if (flag_pic && SYMBOLIC_CONST (x)) - return legitimize_pic_address (x, 0); - - return x; -} + rtx constant_term = const0_rtx; - -/* Output branch condition code of CODE in assembler - syntax to stdio stream FILE. */ - -static void -output_branch_condition (file, code) - FILE *file; - rtx code; -{ - switch (GET_CODE (code)) + if (flag_pic) { - case EQ: - fprintf (file, "e"); - break; - case NE: - fprintf (file, "ne"); - break; - case GT: - case GTU: - fprintf (file, "h"); - break; - case LT: - case LTU: - fprintf (file, "l"); - break; - case GE: - case GEU: - fprintf (file, "he"); - break; - case LE: - case LEU: - fprintf (file, "le"); - break; - default: - fatal_insn ("Unknown CC code", code); + if (SYMBOLIC_CONST (x) + || (GET_CODE (x) == PLUS + && (SYMBOLIC_CONST (XEXP (x, 0)) + || SYMBOLIC_CONST (XEXP (x, 1))))) + x = legitimize_pic_address (x, 0); + + if (legitimate_address_p (mode, x, FALSE)) + return x; } -} -/* Output the inverse of the branch condition code of CODE - in assembler syntax to stdio stream FILE. */ + x = eliminate_constant_term (x, &constant_term); -static void -output_inverse_branch_condition (file, code) - FILE *file; - rtx code; -{ - switch (GET_CODE (code)) + if (GET_CODE (x) == PLUS) { - case EQ: - fprintf (file, "ne"); - break; - case NE: - fprintf (file, "e"); - break; - case GT: - case GTU: - fprintf (file, "nh"); - break; - case LT: - case LTU: - fprintf (file, "nl"); - break; - case GE: - case GEU: - fprintf (file, "nhe"); - break; - case LE: - case LEU: - fprintf (file, "nle"); - break; - default: - fatal_insn ("Unknown CC code", code); + if (GET_CODE (XEXP (x, 0)) == REG) + { + register rtx temp = gen_reg_rtx (Pmode); + register rtx val = force_operand (XEXP (x, 1), temp); + if (val != temp) + emit_move_insn (temp, val); + + x = gen_rtx_PLUS (Pmode, XEXP (x, 0), temp); + } + + else if (GET_CODE (XEXP (x, 1)) == REG) + { + register rtx temp = gen_reg_rtx (Pmode); + register rtx val = force_operand (XEXP (x, 0), temp); + if (val != temp) + emit_move_insn (temp, val); + + x = gen_rtx_PLUS (Pmode, temp, XEXP (x, 1)); + } } + + if (constant_term != const0_rtx) + x = gen_rtx_PLUS (Pmode, x, constant_term); + + return x; } + /* Output symbolic constant X in assembler syntax to stdio stream FILE. */ @@ -1417,11 +1572,11 @@ print_operand (file, x, code) switch (code) { case 'C': - output_branch_condition (file, x); + fprintf (file, s390_branch_condition_mnemonic (x, FALSE)); return; case 'D': - output_inverse_branch_condition (file, x); + fprintf (file, s390_branch_condition_mnemonic (x, TRUE)); return; case 'Y': @@ -1806,7 +1961,7 @@ check_and_change_labels (insn, ltorg_uids) int *ltorg_uids; { rtx temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM); - rtx target, jump; + rtx target, jump, cjump; rtx pattern, tmp, body, label1; int addr0, addr1; @@ -1878,7 +2033,10 @@ check_and_change_labels (insn, ltorg_uids) } label1 = gen_label_rtx (); - emit_jump_insn_before (gen_icjump (label1, XEXP (body, 0)), insn); + cjump = gen_rtx_LABEL_REF (VOIDmode, label1); + cjump = gen_rtx_IF_THEN_ELSE (VOIDmode, XEXP (body, 0), pc_rtx, cjump); + cjump = gen_rtx_SET (VOIDmode, pc_rtx, cjump); + emit_jump_insn_before (cjump, insn); emit_insn_before (gen_movsi (temp_reg, target), insn); tmp = emit_jump_insn_before (gen_indirect_jump (jump), insn); INSN_ADDRESSES_NEW (emit_label_before (label1, insn), -1); @@ -1912,7 +2070,10 @@ check_and_change_labels (insn, ltorg_uids) } label1 = gen_label_rtx (); - emit_jump_insn_before (gen_cjump (label1, XEXP (body, 0)), insn); + cjump = gen_rtx_LABEL_REF (VOIDmode, label1); + cjump = gen_rtx_IF_THEN_ELSE (VOIDmode, XEXP (body, 0), cjump, pc_rtx); + cjump = gen_rtx_SET (VOIDmode, pc_rtx, cjump); + emit_jump_insn_before (cjump, insn); emit_insn_before (gen_movsi (temp_reg, target), insn); tmp = emit_jump_insn_before (gen_indirect_jump (jump), insn); INSN_ADDRESSES_NEW (emit_label_before (label1, insn), -1); @@ -2541,8 +2702,7 @@ s390_function_prologue (file, lsize) /* Decrement stack. */ - if (TARGET_BACKCHAIN || (STARTING_FRAME_OFFSET + - lsize + STACK_POINTER_OFFSET > 4095 + if (TARGET_BACKCHAIN || (frame_size + STACK_POINTER_OFFSET > 4095 || frame_pointer_needed || current_function_calls_alloca)) { @@ -2582,8 +2742,7 @@ s390_function_prologue (file, lsize) /* Generate backchain. */ - if (TARGET_BACKCHAIN || (STARTING_FRAME_OFFSET + - lsize + STACK_POINTER_OFFSET > 4095 + if (TARGET_BACKCHAIN || (frame_size + STACK_POINTER_OFFSET > 4095 || frame_pointer_needed || current_function_calls_alloca)) { diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h index d250f05..90ba647 100644 --- a/gcc/config/s390/s390.h +++ b/gcc/config/s390/s390.h @@ -1687,6 +1687,7 @@ do { \ #define EXTRA_CC_MODES \ CC (CCZmode, "CCZ") \ CC (CCAmode, "CCA") \ + CC (CCLmode, "CCL") \ CC (CCUmode, "CCU") \ CC (CCSmode, "CCS") \ CC (CCTmode, "CCT") @@ -1694,13 +1695,7 @@ do { \ /* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE, return the mode to be used for the comparison. */ -#define SELECT_CC_MODE(OP, X, Y) \ - ( (OP) == EQ || (OP) == NE ? CCZmode \ - : (OP) == LE || (OP) == LT || \ - (OP) == GE || (OP) == GT ? CCSmode \ - : (OP) == LEU || (OP) == LTU || \ - (OP) == GEU || (OP) == GTU ? CCUmode \ - : CCmode ) +#define SELECT_CC_MODE(OP, X, Y) s390_select_ccmode ((OP), (X), (Y)) /* Define the information needed to generate branch and scc insns. This is diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index 853ac9b..18e9c1c 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -369,7 +369,7 @@ (define_insn "*cmpsi_cct" [(set (reg 33) - (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "%d") + (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "d") (match_operand:SI 1 "const1_operand" "") (match_operand:SI 2 "immediate_operand" "I")) (const_int 0)))] @@ -856,6 +856,19 @@ if (flag_pic && SYMBOLIC_CONST (operands[1])) emit_pic_move (operands, SImode); + + /* expr.c tries to load an effective address using + force_reg. This fails because we don't have a + generic load_address pattern. Convert the move + to a proper arithmetic operation instead, unless + it is guaranteed to be OK. */ + if (GET_CODE (operands[1]) == PLUS + && !legitimate_la_operand_p (operands[1])) + { + operands[1] = force_operand (operands[1], operands[0]); + if (operands[1] == operands[0]) + DONE; + } }") (define_insn "*movsi" @@ -1835,8 +1848,8 @@ ; Compare a block that is less than 256 bytes in length. (define_insn "cmpstr_const" - [(set (reg:CCU 33) - (compare:CCU (match_operand:BLK 0 "s_operand" "oQ") + [(set (reg:CCS 33) + (compare:CCS (match_operand:BLK 0 "s_operand" "oQ") (match_operand:BLK 1 "s_operand" "oQ"))) (use (match_operand 2 "immediate_operand" "I"))] "(unsigned) INTVAL (operands[2]) < 256" @@ -1848,8 +1861,8 @@ ; Compare a block that is larger than 255 bytes in length. (define_insn "cmpstr_64" - [(set (reg:CCU 33) - (compare:CCU (mem:BLK (subreg:DI (match_operand:TI 0 "register_operand" "d") 0)) + [(set (reg:CCS 33) + (compare:CCS (mem:BLK (subreg:DI (match_operand:TI 0 "register_operand" "d") 0)) (mem:BLK (subreg:DI (match_operand:TI 1 "register_operand" "d") 0)))) (clobber (subreg:DI (match_dup 0) 0)) (clobber (subreg:DI (match_dup 0) 8)) @@ -1862,8 +1875,8 @@ (set_attr "type" "other")]) (define_insn "cmpstr_31" - [(set (reg:CCU 33) - (compare:CCU (mem:BLK (subreg:SI (match_operand:DI 0 "register_operand" "d") 0)) + [(set (reg:CCS 33) + (compare:CCS (mem:BLK (subreg:SI (match_operand:DI 0 "register_operand" "d") 0)) (mem:BLK (subreg:SI (match_operand:DI 1 "register_operand" "d") 0)))) (clobber (subreg:SI (match_dup 0) 0)) (clobber (subreg:SI (match_dup 0) 4)) @@ -1879,7 +1892,7 @@ (define_insn "cmpint_si" [(set (match_operand:SI 0 "register_operand" "=d") - (compare:SI (reg:CCU 33) (const_int 0)))] + (compare:SI (reg:CCS 33) (const_int 0)))] "" "* { @@ -1896,7 +1909,7 @@ (define_insn "cmpint_di" [(set (match_operand:DI 0 "register_operand" "=d") - (compare:DI (reg:CCU 33) (const_int 0)))] + (compare:DI (reg:CCS 33) (const_int 0)))] "TARGET_64BIT" "* { @@ -2907,76 +2920,44 @@ (set_attr "atype" "mem") (set_attr "type" "la")]) -(define_insn "*addaddr_picR" - [(set (match_operand:SI 0 "register_operand" "=d") - (plus:SI (match_operand:SI 1 "register_operand" "a") - (unspec:SI [(match_operand:SI 2 "register_operand" "a")] 101)))] - "" - "la\\t%0,0(%1,%2)" - [(set_attr "op_type" "RX") - (set_attr "atype" "mem") - (set_attr "type" "la")]) - -(define_insn "*addaddr_picL" - [(set (match_operand:SI 0 "register_operand" "=d") - (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "a")] 101) - (match_operand:SI 1 "register_operand" "a")))] - "" - "la\\t%0,0(%1,%2)" - [(set_attr "op_type" "RX") - (set_attr "atype" "mem") - (set_attr "type" "la")]) - -(define_insn "*addaddr_picN" - [(set (match_operand:SI 0 "register_operand" "=d") - (unspec:SI [(match_operand:SI 1 "register_operand" "a")] 101))] - "" - "la\\t%0,0(%1)" - [(set_attr "op_type" "RX") - (set_attr "atype" "mem") - (set_attr "type" "la")]) - (define_insn "*addsi3_cc" [(set (reg 33) - (compare (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0") - (match_operand:SI 2 "general_operand" "d,K,m")) + (compare (plus:SI (match_operand:SI 1 "register_operand" "%0,0") + (match_operand:SI 2 "nonimmediate_operand" "d,m")) (const_int 0))) - (set (match_operand:SI 0 "register_operand" "=d,d,d") + (set (match_operand:SI 0 "register_operand" "=d,d") (plus:SI (match_dup 1) (match_dup 2)))] - "s390_match_ccmode(insn, CCSmode)" + "s390_match_ccmode(insn, CCLmode)" "@ - ar\\t%0,%2 - ahi\\t%0,%h2 - a\\t%0,%2" - [(set_attr "op_type" "RR,RI,RX") - (set_attr "atype" "reg,reg,mem")]) + alr\\t%0,%2 + al\\t%0,%2" + [(set_attr "op_type" "RR,RX") + (set_attr "atype" "reg,mem")]) (define_insn "*addsi3_cconly" [(set (reg 33) - (compare (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0") - (match_operand:SI 2 "general_operand" "d,K,m")) + (compare (plus:SI (match_operand:SI 1 "register_operand" "%0,0") + (match_operand:SI 2 "general_operand" "d,m")) (const_int 0))) - (clobber (match_scratch:SI 0 "=d,d,d"))] - "s390_match_ccmode(insn, CCSmode)" + (clobber (match_scratch:SI 0 "=d,d"))] + "s390_match_ccmode(insn, CCLmode)" "@ - ar\\t%0,%2 - ahi\\t%0,%h2 - a\\t%0,%2" - [(set_attr "op_type" "RR,RI,RX") - (set_attr "atype" "reg,reg,mem")]) + alr\\t%0,%2 + al\\t%0,%2" + [(set_attr "op_type" "RR,RX") + (set_attr "atype" "reg,mem")]) (define_insn "*addsi3_cconly2" [(set (reg 33) - (compare (match_operand:SI 1 "register_operand" "%0,0,0") - (neg:SI (match_operand:SI 2 "general_operand" "d,K,m")))) - (clobber (match_scratch:SI 0 "=d,d,d"))] - "s390_match_ccmode(insn, CCSmode)" + (compare (match_operand:SI 1 "register_operand" "%0,0") + (neg:SI (match_operand:SI 2 "general_operand" "d,m")))) + (clobber (match_scratch:SI 0 "=d,d"))] + "s390_match_ccmode(insn, CCLmode)" "@ - ar\\t%0,%2 - ahi\\t%0,%h2 - a\\t%0,%2" - [(set_attr "op_type" "RR,RI,RX") - (set_attr "atype" "reg,reg,mem")]) + alr\\t%0,%2 + al\\t%0,%2" + [(set_attr "op_type" "RR,RX") + (set_attr "atype" "reg,mem")]) (define_insn "addsi3" [(set (match_operand:SI 0 "register_operand" "=d,d,d") @@ -2991,10 +2972,11 @@ [(set_attr "op_type" "RR,RI,RX") (set_attr "atype" "reg,reg,mem")]) -(define_insn "do_la" +(define_insn "*do_la" [(set (match_operand:SI 0 "register_operand" "=a") (match_operand:QI 1 "address_operand" "p"))] - "volatile_ok" + "reload_in_progress || reload_completed + || legitimate_la_operand_p (operands[1])" "la\\t%0,%a1" [(set_attr "op_type" "RX") (set_attr "atype" "mem") @@ -3004,7 +2986,7 @@ [(set (match_operand:SI 0 "register_operand" "=d") (plus:SI (match_operand:SI 1 "register_operand" "%0") (match_operand:SI 2 "register_operand" "d")))] - "" + "reload_in_progress || reload_completed" "brxle\\t%0,%2,.+4" [(set_attr "op_type" "RSI") (set_attr "atype" "reg")]) @@ -3220,10 +3202,10 @@ (const_int 0))) (set (match_operand:SI 0 "register_operand" "=d,d") (minus:SI (match_dup 1) (match_dup 2)))] - "s390_match_ccmode(insn, CCSmode)" + "s390_match_ccmode(insn, CCLmode)" "@ - sr\\t%0,%2 - s\\t%0,%2" + slr\\t%0,%2 + sl\\t%0,%2" [(set_attr "op_type" "RR,RX") (set_attr "atype" "reg,mem")]) @@ -3233,10 +3215,10 @@ (match_operand:SI 2 "general_operand" "d,m")) (const_int 0))) (clobber (match_scratch:SI 0 "=d,d"))] - "s390_match_ccmode(insn, CCSmode)" + "s390_match_ccmode(insn, CCLmode)" "@ - sr\\t%0,%2 - s\\t%0,%2" + slr\\t%0,%2 + sl\\t%0,%2" [(set_attr "op_type" "RR,RX") (set_attr "atype" "reg,mem")]) @@ -4945,6 +4927,78 @@ "" "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }") +(define_expand "bunordered" + [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2))) + (set (pc) + (if_then_else (unordered (reg:CCS 33) (const_int 0)) + (label_ref (match_operand 0 "" "")) + (pc)))] + "" + "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }") + +(define_expand "bordered" + [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2))) + (set (pc) + (if_then_else (ordered (reg:CCS 33) (const_int 0)) + (label_ref (match_operand 0 "" "")) + (pc)))] + "" + "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }") + +(define_expand "buneq" + [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2))) + (set (pc) + (if_then_else (uneq (reg:CCS 33) (const_int 0)) + (label_ref (match_operand 0 "" "")) + (pc)))] + "" + "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }") + +(define_expand "bungt" + [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2))) + (set (pc) + (if_then_else (ungt (reg:CCS 33) (const_int 0)) + (label_ref (match_operand 0 "" "")) + (pc)))] + "" + "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }") + +(define_expand "bunlt" + [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2))) + (set (pc) + (if_then_else (unlt (reg:CCS 33) (const_int 0)) + (label_ref (match_operand 0 "" "")) + (pc)))] + "" + "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }") + +(define_expand "bunge" + [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2))) + (set (pc) + (if_then_else (unge (reg:CCS 33) (const_int 0)) + (label_ref (match_operand 0 "" "")) + (pc)))] + "" + "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }") + +(define_expand "bunle" + [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2))) + (set (pc) + (if_then_else (unle (reg:CCS 33) (const_int 0)) + (label_ref (match_operand 0 "" "")) + (pc)))] + "" + "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }") + +(define_expand "bltgt" + [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2))) + (set (pc) + (if_then_else (ltgt (reg:CCS 33) (const_int 0)) + (label_ref (match_operand 0 "" "")) + (pc)))] + "" + "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }") + ;; ;;- Conditional jump instructions. |