diff options
Diffstat (limited to 'contrib/gcc/config/s390/s390.md')
-rw-r--r-- | contrib/gcc/config/s390/s390.md | 3328 |
1 files changed, 1864 insertions, 1464 deletions
diff --git a/contrib/gcc/config/s390/s390.md b/contrib/gcc/config/s390/s390.md index 2742638..8178516 100644 --- a/contrib/gcc/config/s390/s390.md +++ b/contrib/gcc/config/s390/s390.md @@ -1,5 +1,5 @@ ;;- Machine description for GNU compiler -- S/390 / zSeries version. -;; Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. +;; Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. ;; Contributed by Hartmut Penner (hpenner@de.ibm.com) and ;; Ulrich Weigand (uweigand@de.ibm.com). ;; This file is part of GNU CC. @@ -44,6 +44,34 @@ ;; s_operand -- Matches a valid S operand in a RS, SI or SS type instruction. ;; +;; +;; UNSPEC usage +;; + +(define_constants + [; TLS relocation specifiers + (UNSPEC_TLSGD 500) + (UNSPEC_TLSLDM 501) + (UNSPEC_NTPOFF 502) + (UNSPEC_DTPOFF 503) + (UNSPEC_GOTNTPOFF 504) + (UNSPEC_INDNTPOFF 505) + + ; TLS support + (UNSPEC_TP 510) + (UNSPEC_TLSLDM_NTPOFF 511) + (UNSPEC_TLS_LOAD 512) + ]) + +;; +;; UNSPEC_VOLATILE usage +;; + +(define_constants + [; TLS support + (UNSPECV_SET_TP 500) + ]) + ;; Define an insn type attribute. This is used in function unit delay ;; computations. @@ -191,30 +219,6 @@ DONE; }") -;(define_expand "cmphi" -; [(set (reg:CC 33) -; (compare:CC (match_operand:HI 0 "register_operand" "") -; (match_operand:HI 1 "general_operand" "")))] -; "" -; " -;{ -; s390_compare_op0 = operands[0]; -; s390_compare_op1 = operands[1]; -; DONE; -;}") - -;(define_expand "cmpqi" -; [(set (reg:CC 33) -; (compare:CC (match_operand:QI 0 "register_operand" "") -; (match_operand:QI 1 "general_operand" "")))] -; "" -; " -;{ -; s390_compare_op0 = operands[0]; -; s390_compare_op1 = operands[1]; -; DONE; -;}") - (define_expand "cmpdf" [(set (reg:CC 33) (compare:CC (match_operand:DF 0 "register_operand" "") @@ -240,9 +244,9 @@ }") -; DI instructions +; Test-under-Mask (zero_extract) instructions -(define_insn "*cmpdi_tm2" +(define_insn "*tmdi_ext" [(set (reg 33) (compare (zero_extract:DI (match_operand:DI 0 "register_operand" "d") (match_operand:DI 1 "const_int_operand" "n") @@ -272,35 +276,63 @@ }" [(set_attr "op_type" "RI")]) -(define_insn "*cmpdi_tm_reg" +(define_insn "*tmsi_ext" [(set (reg 33) - (compare (and:DI (match_operand:DI 0 "register_operand" "%d") - (match_operand:DI 1 "immediate_operand" "n")) + (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "d") + (match_operand:SI 1 "const_int_operand" "n") + (match_operand:SI 2 "const_int_operand" "n")) (const_int 0)))] - "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT - && s390_single_hi (operands[1], DImode, 0) >= 0" + "s390_match_ccmode(insn, CCTmode) + && INTVAL (operands[1]) >= 1 && INTVAL (operands[2]) >= 0 + && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32 + && (INTVAL (operands[1]) + INTVAL (operands[2]) - 1) >> 4 + == INTVAL (operands[2]) >> 4" "* { - int part = s390_single_hi (operands[1], DImode, 0); - operands[1] = GEN_INT (s390_extract_hi (operands[1], DImode, part)); + int part = INTVAL (operands[2]) >> 4; + int block = (1 << INTVAL (operands[1])) - 1; + int shift = 16 - INTVAL (operands[1]) - (INTVAL (operands[2]) & 15); + + operands[2] = GEN_INT (block << shift); 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\"; + case 0: return \"tmh\\t%0,%x2\"; + case 1: return \"tml\\t%0,%x2\"; default: abort (); } }" [(set_attr "op_type" "RI")]) -(define_insn "*cmpdi_tm_mem" +(define_insn "*tmqi_ext" [(set (reg 33) - (compare (and:DI (match_operand:DI 0 "s_operand" "%Qo") - (match_operand:DI 1 "immediate_operand" "n")) + (compare (zero_extract:SI (match_operand:QI 0 "memory_operand" "Q") + (match_operand:SI 1 "const_int_operand" "n") + (match_operand:SI 2 "const_int_operand" "n")) (const_int 0)))] - "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT + "s390_match_ccmode(insn, CCTmode) + && INTVAL (operands[1]) >= 1 && INTVAL (operands[2]) >= 0 + && INTVAL (operands[1]) + INTVAL (operands[2]) <= 8" + "* +{ + int block = (1 << INTVAL (operands[1])) - 1; + int shift = 8 - INTVAL (operands[1]) - INTVAL (operands[2]); + + operands[2] = GEN_INT (block << shift); + return \"tm\\t%0,%b2\"; +}" + [(set_attr "op_type" "SI") + (set_attr "atype" "mem")]) + +; Test-under-Mask instructions + +(define_insn "*tmdi_mem" + [(set (reg 33) + (compare (and:DI (match_operand:DI 0 "memory_operand" "Q") + (match_operand:DI 1 "immediate_operand" "n")) + (match_operand:DI 2 "immediate_operand" "n")))] + "TARGET_64BIT + && s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0)) && s390_single_qi (operands[1], DImode, 0) >= 0" "* { @@ -314,100 +346,84 @@ [(set_attr "op_type" "SI") (set_attr "atype" "mem")]) -(define_insn "*ltgr" +(define_insn "*tmsi_mem" [(set (reg 33) - (compare (match_operand:DI 0 "register_operand" "d") - (match_operand:DI 1 "const0_operand" ""))) - (set (match_operand:DI 2 "register_operand" "=d") - (match_dup 0))] - "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT" - "ltgr\\t%2,%0" - [(set_attr "op_type" "RRE")]) + (compare (and:SI (match_operand:SI 0 "memory_operand" "Q") + (match_operand:SI 1 "immediate_operand" "n")) + (match_operand:SI 2 "immediate_operand" "n")))] + "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0)) + && s390_single_qi (operands[1], SImode, 0) >= 0" + "* +{ + int part = s390_single_qi (operands[1], SImode, 0); + operands[1] = GEN_INT (s390_extract_qi (operands[1], SImode, part)); -(define_insn "*cmpdi_ccs_0_64" - [(set (reg 33) - (compare (match_operand:DI 0 "register_operand" "d") - (match_operand:DI 1 "const0_operand" "")))] - "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT" - "ltgr\\t%0,%0" - [(set_attr "op_type" "RRE")]) + operands[0] = gen_rtx_MEM (QImode, + plus_constant (XEXP (operands[0], 0), part)); + return \"tm\\t%0,%b1\"; +}" + [(set_attr "op_type" "SI") + (set_attr "atype" "mem")]) -(define_insn "*cmpdi_ccs_0_31" +(define_insn "*tmhi_mem" [(set (reg 33) - (compare (match_operand:DI 0 "register_operand" "d") - (match_operand:DI 1 "const0_operand" "")))] - "s390_match_ccmode(insn, CCSmode)" - "srda\\t%0,0" - [(set_attr "op_type" "RS")]) + (compare (and:SI (subreg:SI (match_operand:HI 0 "memory_operand" "Q") 0) + (match_operand:SI 1 "immediate_operand" "n")) + (match_operand:SI 2 "immediate_operand" "n")))] + "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0)) + && s390_single_qi (operands[1], HImode, 0) >= 0" + "* +{ + int part = s390_single_qi (operands[1], HImode, 0); + operands[1] = GEN_INT (s390_extract_qi (operands[1], HImode, part)); -(define_insn "*cmpdi_ccs" - [(set (reg 33) - (compare (match_operand:DI 0 "register_operand" "d,d,d") - (match_operand:DI 1 "general_operand" "d,K,m")))] - "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT" - "@ - cgr\\t%0,%1 - cghi\\t%0,%c1 - cg\\t%0,%1" - [(set_attr "op_type" "RRE,RI,RXE") - (set_attr "atype" "reg,reg,mem")]) - -(define_insn "*cmpdi_ccu" - [(set (reg 33) - (compare (match_operand:DI 0 "register_operand" "d,d") - (match_operand:DI 1 "general_operand" "d,m")))] - "s390_match_ccmode(insn, CCUmode) && TARGET_64BIT" - "@ - clgr\\t%0,%1 - clg\\t%0,%1" - [(set_attr "op_type" "RRE,RXE") - (set_attr "atype" "reg,mem")]) + operands[0] = gen_rtx_MEM (QImode, + plus_constant (XEXP (operands[0], 0), part)); + return \"tm\\t%0,%b1\"; +}" + [(set_attr "op_type" "SI") + (set_attr "atype" "mem")]) -(define_insn "*cmpdi_ccu_mem" +(define_insn "*tmqi_mem" [(set (reg 33) - (compare (match_operand:DI 0 "s_operand" "oQ") - (match_operand:DI 1 "s_imm_operand" "oQ")))] - "s390_match_ccmode(insn, CCUmode)" - "clc\\t%O0(8,%R0),%1" - [(set_attr "op_type" "SS") + (compare (and:SI (subreg:SI (match_operand:QI 0 "memory_operand" "Q") 0) + (match_operand:SI 1 "immediate_operand" "n")) + (match_operand:SI 2 "immediate_operand" "n")))] + "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0))" + "tm\\t%0,%b1" + [(set_attr "op_type" "SI") (set_attr "atype" "mem")]) -; SI instructions - -(define_insn "*cmpsi_tm2" +(define_insn "*tmdi_reg" [(set (reg 33) - (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "d") - (match_operand:SI 1 "const_int_operand" "n") - (match_operand:SI 2 "const_int_operand" "n")) - (const_int 0)))] - "s390_match_ccmode(insn, CCTmode) - && INTVAL (operands[1]) >= 1 && INTVAL (operands[2]) >= 0 - && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32 - && (INTVAL (operands[1]) + INTVAL (operands[2]) - 1) >> 4 - == INTVAL (operands[2]) >> 4" + (compare (and:DI (match_operand:DI 0 "nonimmediate_operand" "d") + (match_operand:DI 1 "immediate_operand" "n")) + (match_operand:DI 2 "immediate_operand" "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 = INTVAL (operands[2]) >> 4; - int block = (1 << INTVAL (operands[1])) - 1; - int shift = 16 - INTVAL (operands[1]) - (INTVAL (operands[2]) & 15); - - operands[2] = GEN_INT (block << shift); + 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 \"tmh\\t%0,%x2\"; - case 1: return \"tml\\t%0,%x2\"; + 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")]) -(define_insn "*cmpsi_tm_reg" +(define_insn "*tmsi_reg" [(set (reg 33) - (compare (and:SI (match_operand:SI 0 "register_operand" "%d") + (compare (and:SI (match_operand:SI 0 "nonimmediate_operand" "d") (match_operand:SI 1 "immediate_operand" "n")) - (const_int 0)))] - "s390_match_ccmode(insn, CCTmode) + (match_operand:SI 2 "immediate_operand" "n")))] + "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 1)) && s390_single_hi (operands[1], SImode, 0) >= 0" "* { @@ -423,57 +439,88 @@ }" [(set_attr "op_type" "RI")]) -(define_insn "*cmpsi_tm_mem" +(define_insn "*tmhi_full" [(set (reg 33) - (compare (and:SI (match_operand:SI 0 "s_operand" "%Qo") - (match_operand:SI 1 "immediate_operand" "n")) - (const_int 0)))] - "s390_match_ccmode(insn, CCTmode) - && s390_single_qi (operands[1], SImode, 0) >= 0" - "* -{ - int part = s390_single_qi (operands[1], SImode, 0); - operands[1] = GEN_INT (s390_extract_qi (operands[1], SImode, part)); + (compare (match_operand:HI 0 "register_operand" "d") + (match_operand:HI 1 "immediate_operand" "n")))] + "s390_match_ccmode (insn, s390_tm_ccmode (GEN_INT (-1), operands[1], 1))" + "tml\\t%0,65535" + [(set_attr "op_type" "RX")]) + +(define_insn "*tmqi_full" + [(set (reg 33) + (compare (match_operand:QI 0 "register_operand" "d") + (match_operand:QI 1 "immediate_operand" "n")))] + "s390_match_ccmode (insn, s390_tm_ccmode (GEN_INT (-1), operands[1], 1))" + "tml\\t%0,255" + [(set_attr "op_type" "RI")]) - operands[0] = gen_rtx_MEM (QImode, - plus_constant (XEXP (operands[0], 0), part)); - return \"tm\\t%0,%b1\"; -}" - [(set_attr "op_type" "SI") - (set_attr "atype" "mem")]) -(define_insn "*ltr" +; Load-and-Test instructions + +(define_insn "*tstdi_sign" [(set (reg 33) - (compare (match_operand:SI 0 "register_operand" "d") - (match_operand:SI 1 "const0_operand" ""))) - (set (match_operand:SI 2 "register_operand" "=d") + (compare (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 0 "register_operand" "d") 0) + (const_int 32)) (const_int 32)) + (match_operand:DI 1 "const0_operand" ""))) + (set (match_operand:DI 2 "register_operand" "=d") + (sign_extend:DI (match_dup 0)))] + "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT" + "ltgfr\\t%2,%0" + [(set_attr "op_type" "RRE")]) + +(define_insn "*tstdi" + [(set (reg 33) + (compare (match_operand:DI 0 "register_operand" "d") + (match_operand:DI 1 "const0_operand" ""))) + (set (match_operand:DI 2 "register_operand" "=d") (match_dup 0))] - "s390_match_ccmode(insn, CCSmode)" - "ltr\\t%2,%0" - [(set_attr "op_type" "RR")]) + "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT" + "ltgr\\t%2,%0" + [(set_attr "op_type" "RRE")]) -(define_insn "*icm15" +(define_insn "*tstdi_cconly" [(set (reg 33) - (compare (match_operand:SI 0 "s_operand" "Qo") + (compare (match_operand:DI 0 "register_operand" "d") + (match_operand:DI 1 "const0_operand" "")))] + "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT" + "ltgr\\t%0,%0" + [(set_attr "op_type" "RRE")]) + +(define_insn "*tstdi_cconly_31" + [(set (reg 33) + (compare (match_operand:DI 0 "register_operand" "d") + (match_operand:DI 1 "const0_operand" "")))] + "s390_match_ccmode(insn, CCSmode) && !TARGET_64BIT" + "srda\\t%0,0" + [(set_attr "op_type" "RS")]) + +(define_insn "*tstsi" + [(set (reg 33) + (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q") (match_operand:SI 1 "const0_operand" ""))) - (set (match_operand:SI 2 "register_operand" "=d") + (set (match_operand:SI 2 "register_operand" "=d,d") (match_dup 0))] "s390_match_ccmode(insn, CCSmode)" - "icm\\t%2,15,%0" - [(set_attr "op_type" "RS") - (set_attr "atype" "mem")]) + "@ + ltr\\t%2,%0 + icm\\t%2,15,%0" + [(set_attr "op_type" "RR,RS") + (set_attr "atype" "reg,mem")]) -(define_insn "*icm15_cconly" +(define_insn "*tstsi_cconly" [(set (reg 33) - (compare (match_operand:SI 0 "s_operand" "Qo") + (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q") (match_operand:SI 1 "const0_operand" ""))) - (clobber (match_scratch:SI 2 "=d"))] + (clobber (match_scratch:SI 2 "=X,d"))] "s390_match_ccmode(insn, CCSmode)" - "icm\\t%2,15,%0" - [(set_attr "op_type" "RS") - (set_attr "atype" "mem")]) + "@ + ltr\\t%0,%0 + icm\\t%2,15,%0" + [(set_attr "op_type" "RR,RS") + (set_attr "atype" "reg,mem")]) -(define_insn "*cmpsi_ccs_0" +(define_insn "*tstsi_cconly2" [(set (reg 33) (compare (match_operand:SI 0 "register_operand" "d") (match_operand:SI 1 "const0_operand" "")))] @@ -481,72 +528,34 @@ "ltr\\t%0,%0" [(set_attr "op_type" "RR")]) -(define_insn "*cmpsidi_ccs" - [(set (reg 33) - (compare (match_operand:SI 0 "register_operand" "d") - (sign_extend:SI (match_operand:HI 1 "memory_operand" "m"))))] - "s390_match_ccmode(insn, CCSmode)" - "ch\\t%0,%1" - [(set_attr "op_type" "RR") - (set_attr "atype" "mem")]) - -(define_insn "*cmpsi_ccs" - [(set (reg 33) - (compare (match_operand:SI 0 "register_operand" "d,d,d") - (match_operand:SI 1 "general_operand" "d,K,m")))] - "s390_match_ccmode(insn, CCSmode)" - "@ - cr\\t%0,%1 - chi\\t%0,%c1 - c\\t%0,%1" - [(set_attr "op_type" "RR,RI,RX") - (set_attr "atype" "reg,reg,mem")]) - -(define_insn "*cmpsi_ccu" +(define_insn "*tsthiCCT" [(set (reg 33) - (compare (match_operand:SI 0 "register_operand" "d,d") - (match_operand:SI 1 "general_operand" "d,m")))] - "s390_match_ccmode(insn, CCUmode)" + (compare (match_operand:HI 0 "nonimmediate_operand" "?Q,d") + (match_operand:HI 1 "const0_operand" ""))) + (set (match_operand:HI 2 "register_operand" "=d,0") + (match_dup 0))] + "s390_match_ccmode(insn, CCTmode)" "@ - clr\\t%0,%1 - cl\\t%0,%1" - [(set_attr "op_type" "RR,RX") - (set_attr "atype" "reg,mem")]) + icm\\t%2,3,%0 + tml\\t%0,65535" + [(set_attr "op_type" "RS,RI") + (set_attr "atype" "mem,reg")]) -(define_insn "*cmpsi_ccu_mem" +(define_insn "*tsthiCCT_cconly" [(set (reg 33) - (compare (match_operand:SI 0 "s_operand" "oQ") - (match_operand:SI 1 "s_imm_operand" "oQ")))] - "s390_match_ccmode(insn, CCUmode)" - "clc\\t%O0(4,%R0),%1" - [(set_attr "op_type" "SS") - (set_attr "atype" "mem")]) - - -; HI instructions - -(define_insn "*cmphi_tm_sub" - [(set (reg 33) - (compare (and:SI (subreg:SI (match_operand:HI 0 "s_operand" "%Qo") 0) - (match_operand:SI 1 "immediate_operand" "n")) - (const_int 0)))] - "s390_match_ccmode(insn, CCTmode) - && s390_single_qi (operands[1], HImode, 0) >= 0" - "* -{ - int part = s390_single_qi (operands[1], HImode, 0); - operands[1] = GEN_INT (s390_extract_qi (operands[1], HImode, part)); - - operands[0] = gen_rtx_MEM (QImode, - plus_constant (XEXP (operands[0], 0), part)); - return \"tm\\t%0,%b1\"; -}" - [(set_attr "op_type" "SI") - (set_attr "atype" "mem")]) + (compare (match_operand:HI 0 "nonimmediate_operand" "Q,d") + (match_operand:HI 1 "const0_operand" ""))) + (clobber (match_scratch:HI 2 "=d,X"))] + "s390_match_ccmode(insn, CCTmode)" + "@ + icm\\t%2,3,%0 + tml\\t%0,65535" + [(set_attr "op_type" "RS,RI") + (set_attr "atype" "mem,reg")]) -(define_insn "*icm3" +(define_insn "*tsthi" [(set (reg 33) - (compare (match_operand:HI 0 "s_operand" "Qo") + (compare (match_operand:HI 0 "s_operand" "Q") (match_operand:HI 1 "const0_operand" ""))) (set (match_operand:HI 2 "register_operand" "=d") (match_dup 0))] @@ -555,17 +564,9 @@ [(set_attr "op_type" "RS") (set_attr "atype" "mem")]) -(define_insn "*cmphi_cct_0" +(define_insn "*tsthi_cconly" [(set (reg 33) - (compare (match_operand:HI 0 "register_operand" "d") - (match_operand:HI 1 "const0_operand" "")))] - "s390_match_ccmode(insn, CCTmode)" - "tml\\t%0,65535" - [(set_attr "op_type" "RX")]) - -(define_insn "*cmphi_ccs_0" - [(set (reg 33) - (compare (match_operand:HI 0 "s_operand" "Qo") + (compare (match_operand:HI 0 "s_operand" "Q") (match_operand:HI 1 "const0_operand" ""))) (clobber (match_scratch:HI 2 "=d"))] "s390_match_ccmode(insn, CCSmode)" @@ -573,141 +574,192 @@ [(set_attr "op_type" "RS") (set_attr "atype" "mem")]) -(define_insn "*cmphi_ccu" +(define_insn "*tstqiCCT" [(set (reg 33) - (compare (match_operand:HI 0 "register_operand" "d") - (match_operand:HI 1 "s_imm_operand" "Qo")))] - "s390_match_ccmode(insn, CCUmode)" - "clm\\t%0,3,%1" + (compare (match_operand:QI 0 "nonimmediate_operand" "?Q,d") + (match_operand:QI 1 "const0_operand" ""))) + (set (match_operand:QI 2 "register_operand" "=d,0") + (match_dup 0))] + "s390_match_ccmode(insn, CCTmode)" + "@ + icm\\t%2,1,%0 + tml\\t%0,255" + [(set_attr "op_type" "RS,RI") + (set_attr "atype" "mem,reg")]) + +(define_insn "*tstqiCCT_cconly" + [(set (reg 33) + (compare (match_operand:QI 0 "nonimmediate_operand" "?Q,d") + (match_operand:QI 1 "const0_operand" "")))] + "s390_match_ccmode(insn, CCTmode)" + "@ + cli\\t%0,0 + tml\\t%0,255" + [(set_attr "op_type" "SI,RI") + (set_attr "atype" "mem,reg")]) + +(define_insn "*tstqi" + [(set (reg 33) + (compare (match_operand:QI 0 "s_operand" "Q") + (match_operand:QI 1 "const0_operand" ""))) + (set (match_operand:QI 2 "register_operand" "=d") + (match_dup 0))] + "s390_match_ccmode(insn, CCSmode)" + "icm\\t%2,1,%0" [(set_attr "op_type" "RS") (set_attr "atype" "mem")]) -(define_insn "*cmphi_ccu_mem" +(define_insn "*tstqi_cconly" [(set (reg 33) - (compare (match_operand:HI 0 "s_operand" "oQ") - (match_operand:HI 1 "s_imm_operand" "oQ")))] - "s390_match_ccmode(insn, CCUmode)" - "clc\\t%O0(2,%R0),%1" - [(set_attr "op_type" "SS") + (compare (match_operand:QI 0 "s_operand" "Q") + (match_operand:QI 1 "const0_operand" ""))) + (clobber (match_scratch:QI 2 "=d"))] + "s390_match_ccmode(insn, CCSmode)" + "icm\\t%2,1,%0" + [(set_attr "op_type" "RS") (set_attr "atype" "mem")]) -; QI instructions +; Compare (signed) instructions -(define_insn "*cmpqi_tm2" +(define_insn "*cmpdi_ccs_sign" [(set (reg 33) - (compare (zero_extract:SI (match_operand:QI 0 "s_operand" "Qo") - (match_operand:SI 1 "const_int_operand" "n") - (match_operand:SI 2 "const_int_operand" "n")) - (const_int 0)))] - "s390_match_ccmode(insn, CCTmode) - && INTVAL (operands[1]) >= 1 && INTVAL (operands[2]) >= 0 - && INTVAL (operands[1]) + INTVAL (operands[2]) <= 8" - "* -{ - int block = (1 << INTVAL (operands[1])) - 1; - int shift = 8 - INTVAL (operands[1]) - INTVAL (operands[2]); - - operands[2] = GEN_INT (block << shift); - return \"tm\\t%0,%b2\"; -}" - [(set_attr "op_type" "SI") - (set_attr "atype" "mem")]) - -(define_insn "*cmpqi_tm" - [(set (reg 33) - (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%d,Q") - (match_operand:QI 1 "immediate_operand" "n,n")) - (const_int 0)))] - "s390_match_ccmode(insn, CCTmode)" + (compare (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,m")) + (match_operand:DI 0 "register_operand" "d,d")))] + "s390_match_ccmode(insn, CCSRmode) && TARGET_64BIT" "@ - tml\\t%0,%b1 - tm\\t%0,%b1" - [(set_attr "op_type" "RI,SI") + cgfr\\t%0,%1 + cgf\\t%0,%1" + [(set_attr "op_type" "RRE,RXE") (set_attr "atype" "reg,mem")]) -(define_insn "*cmpqi_tm_sub" +(define_insn "*cmpdi_ccs" [(set (reg 33) - (compare (and:SI (subreg:SI (match_operand:QI 0 "s_operand" "%Qo") 0) - (match_operand:SI 1 "immediate_operand" "n")) - (const_int 0)))] - "s390_match_ccmode(insn, CCTmode)" - "tm\\t%0,%b1" - [(set_attr "op_type" "SI") + (compare (match_operand:DI 0 "register_operand" "d,d,d") + (match_operand:DI 1 "general_operand" "d,K,m")))] + "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT" + "@ + cgr\\t%0,%1 + cghi\\t%0,%c1 + cg\\t%0,%1" + [(set_attr "op_type" "RRE,RI,RXE") + (set_attr "atype" "reg,reg,mem")]) + +(define_insn "*cmpsi_ccs_sign" + [(set (reg 33) + (compare (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")) + (match_operand:SI 0 "register_operand" "d")))] + "s390_match_ccmode(insn, CCSRmode)" + "ch\\t%0,%1" + [(set_attr "op_type" "RX") (set_attr "atype" "mem")]) -(define_insn "*icm1" +(define_insn "*cmpsi_ccs" [(set (reg 33) - (compare (match_operand:QI 0 "s_operand" "Qo") - (match_operand:QI 1 "const0_operand" ""))) - (set (match_operand:QI 2 "register_operand" "=d") - (match_dup 0))] + (compare (match_operand:SI 0 "register_operand" "d,d,d") + (match_operand:SI 1 "general_operand" "d,K,m")))] "s390_match_ccmode(insn, CCSmode)" - "icm\\t%2,1,%0" - [(set_attr "op_type" "RS") - (set_attr "atype" "mem")]) + "@ + cr\\t%0,%1 + chi\\t%0,%c1 + c\\t%0,%1" + [(set_attr "op_type" "RR,RI,RX") + (set_attr "atype" "reg,reg,mem")]) + -(define_insn "*tm_0" +; Compare (unsigned) instructions + +(define_insn "*cmpdi_ccu_zero" [(set (reg 33) - (compare (zero_extend:SI (and:QI (match_operand:QI 0 "s_operand" "Qo") - (match_operand:QI 1 "immediate_operand" ""))) - (const_int 0)))] - "s390_match_ccmode(insn, CCTmode) && - INTVAL(operands[1]) >= 0 && INTVAL(operands[1]) < 256" - "tm\\t%0,%1" - [(set_attr "op_type" "RI") - (set_attr "atype" "mem")]) + (compare (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,m")) + (match_operand:DI 0 "register_operand" "d,d")))] + "s390_match_ccmode(insn, CCURmode) && TARGET_64BIT" + "@ + clgfr\\t%0,%1 + clgf\\t%0,%1" + [(set_attr "op_type" "RRE,RXE") + (set_attr "atype" "reg,mem")]) -(define_insn "*cmpqi_cct_0" +(define_insn "*cmpdi_ccu" [(set (reg 33) - (compare (match_operand:QI 0 "register_operand" "d") - (match_operand:QI 1 "const0_operand" "")))] - "s390_match_ccmode(insn, CCTmode)" - "tml\\t%0,255" - [(set_attr "op_type" "RI")]) + (compare (match_operand:DI 0 "register_operand" "d,d") + (match_operand:DI 1 "general_operand" "d,m")))] + "s390_match_ccmode(insn, CCUmode) && TARGET_64BIT" + "@ + clgr\\t%0,%1 + clg\\t%0,%1" + [(set_attr "op_type" "RRE,RXE") + (set_attr "atype" "reg,mem")]) -(define_insn "*cmpqi_ccs_0" +(define_insn "*cmpsi_ccu" [(set (reg 33) - (compare (match_operand:QI 0 "s_operand" "Qo") - (match_operand:QI 1 "const0_operand" ""))) - (clobber (match_scratch:QI 2 "=d"))] - "s390_match_ccmode(insn, CCSmode)" - "icm\\t%2,1,%0" - [(set_attr "op_type" "RS") - (set_attr "atype" "mem")]) + (compare (match_operand:SI 0 "register_operand" "d,d") + (match_operand:SI 1 "general_operand" "d,m")))] + "s390_match_ccmode(insn, CCUmode)" + "@ + clr\\t%0,%1 + cl\\t%0,%1" + [(set_attr "op_type" "RR,RX") + (set_attr "atype" "reg,mem")]) -(define_insn "*cmpqi_ccu_0" +(define_insn "*cmphi_ccu" [(set (reg 33) - (compare (match_operand:QI 0 "s_operand" "Qo") - (match_operand:QI 1 "const0_operand" "")))] + (compare (match_operand:HI 0 "register_operand" "d") + (match_operand:HI 1 "s_imm_operand" "Q")))] "s390_match_ccmode(insn, CCUmode)" - "cli\\t%0,0" - [(set_attr "op_type" "SI") + "clm\\t%0,3,%1" + [(set_attr "op_type" "RS") (set_attr "atype" "mem")]) (define_insn "*cmpqi_ccu" [(set (reg 33) (compare (match_operand:QI 0 "register_operand" "d") - (match_operand:QI 1 "s_imm_operand" "Qo")))] + (match_operand:QI 1 "s_imm_operand" "Q")))] "s390_match_ccmode(insn, CCUmode)" "clm\\t%0,1,%1" [(set_attr "op_type" "RS") (set_attr "atype" "mem")]) -(define_insn "*cmpqi_ccu_immed" +(define_insn "*cli" [(set (reg 33) - (compare (match_operand:QI 0 "s_operand" "Qo") - (match_operand:QI 1 "const_int_operand" "n")))] - "s390_match_ccmode(insn, CCUmode) && - INTVAL(operands[1]) >= 0 && INTVAL(operands[1]) < 256" - "cli\\t%0,%1" + (compare (match_operand:QI 0 "memory_operand" "Q") + (match_operand:QI 1 "immediate_operand" "n")))] + "s390_match_ccmode (insn, CCUmode)" + "cli\\t%0,%b1" [(set_attr "op_type" "SI") (set_attr "atype" "mem")]) +(define_insn "*cmpdi_ccu_mem" + [(set (reg 33) + (compare (match_operand:DI 0 "s_operand" "Q") + (match_operand:DI 1 "s_imm_operand" "Q")))] + "s390_match_ccmode(insn, CCUmode)" + "clc\\t%O0(8,%R0),%1" + [(set_attr "op_type" "SS") + (set_attr "atype" "mem")]) + +(define_insn "*cmpsi_ccu_mem" + [(set (reg 33) + (compare (match_operand:SI 0 "s_operand" "Q") + (match_operand:SI 1 "s_imm_operand" "Q")))] + "s390_match_ccmode(insn, CCUmode)" + "clc\\t%O0(4,%R0),%1" + [(set_attr "op_type" "SS") + (set_attr "atype" "mem")]) + +(define_insn "*cmphi_ccu_mem" + [(set (reg 33) + (compare (match_operand:HI 0 "s_operand" "Q") + (match_operand:HI 1 "s_imm_operand" "Q")))] + "s390_match_ccmode(insn, CCUmode)" + "clc\\t%O0(2,%R0),%1" + [(set_attr "op_type" "SS") + (set_attr "atype" "mem")]) + (define_insn "*cmpqi_ccu_mem" [(set (reg 33) - (compare (match_operand:QI 0 "s_operand" "oQ") - (match_operand:QI 1 "s_imm_operand" "oQ")))] + (compare (match_operand:QI 0 "s_operand" "Q") + (match_operand:QI 1 "s_imm_operand" "Q")))] "s390_match_ccmode(insn, CCUmode)" "clc\\t%O0(1,%R0),%1" [(set_attr "op_type" "SS") @@ -804,94 +856,91 @@ ; movti instruction pattern(s). ; -(define_insn "*movti_ss" - [(set (match_operand:TI 0 "s_operand" "=Qo") - (match_operand:TI 1 "s_imm_operand" "Qo"))] - "" - "mvc\\t%O0(16,%R0),%1" - [(set_attr "op_type" "SS") - (set_attr "atype" "mem")]) - (define_insn "movti" - [(set (match_operand:TI 0 "nonimmediate_operand" "=d,Q,d,m") - (match_operand:TI 1 "general_operand" "Q,d,dKm,d"))] + [(set (match_operand:TI 0 "nonimmediate_operand" "=d,Q,d,o,Q") + (match_operand:TI 1 "general_operand" "Q,d,dKm,d,Q"))] "TARGET_64BIT" "@ lmg\\t%0,%N0,%1 stmg\\t%1,%N1,%0 # - #" - [(set_attr "op_type" "RSE,RSE,NN,NN") + # + mvc\\t%O0(16,%R0),%1" + [(set_attr "op_type" "RSE,RSE,NN,NN,SS") (set_attr "atype" "mem")]) (define_split [(set (match_operand:TI 0 "nonimmediate_operand" "") (match_operand:TI 1 "general_operand" ""))] "TARGET_64BIT && reload_completed - && !s_operand (operands[0], VOIDmode) - && !s_operand (operands[1], VOIDmode) - && (register_operand (operands[0], VOIDmode) - || register_operand (operands[1], VOIDmode)) - && (!register_operand (operands[0], VOIDmode) - || !reg_overlap_mentioned_p (operand_subword (operands[0], 0, 0, TImode), - operands[1]) - || !reg_overlap_mentioned_p (operand_subword (operands[0], 1, 0, TImode), - operands[1]))" + && s390_split_ok_p (operands[0], operands[1], TImode, 0)" [(set (match_dup 2) (match_dup 4)) (set (match_dup 3) (match_dup 5))] - " { - if (!register_operand (operands[0], VOIDmode) - || !reg_overlap_mentioned_p (operand_subword (operands[0], 0, 0, TImode), - operands[1])) - { - operands[2] = operand_subword (operands[0], 0, 0, TImode); - operands[3] = operand_subword (operands[0], 1, 0, TImode); - operands[4] = operand_subword (operands[1], 0, 0, TImode); - operands[5] = operand_subword (operands[1], 1, 0, TImode); - } - else - { - operands[2] = operand_subword (operands[0], 1, 0, TImode); - operands[3] = operand_subword (operands[0], 0, 0, TImode); - operands[4] = operand_subword (operands[1], 1, 0, TImode); - operands[5] = operand_subword (operands[1], 0, 0, TImode); - } -}") + operands[2] = operand_subword (operands[0], 0, 0, TImode); + operands[3] = operand_subword (operands[0], 1, 0, TImode); + operands[4] = operand_subword (operands[1], 0, 0, TImode); + operands[5] = operand_subword (operands[1], 1, 0, TImode); +}) + +(define_split + [(set (match_operand:TI 0 "nonimmediate_operand" "") + (match_operand:TI 1 "general_operand" ""))] + "TARGET_64BIT && reload_completed + && s390_split_ok_p (operands[0], operands[1], TImode, 1)" + [(set (match_dup 2) (match_dup 4)) + (set (match_dup 3) (match_dup 5))] +{ + operands[2] = operand_subword (operands[0], 1, 0, TImode); + operands[3] = operand_subword (operands[0], 0, 0, TImode); + operands[4] = operand_subword (operands[1], 1, 0, TImode); + operands[5] = operand_subword (operands[1], 0, 0, TImode); +}) (define_split [(set (match_operand:TI 0 "register_operand" "") (match_operand:TI 1 "memory_operand" ""))] "TARGET_64BIT && reload_completed && !s_operand (operands[1], VOIDmode)" - [(set (match_dup 2) (match_dup 3)) - (set (match_dup 0) (mem:TI (match_dup 2)))] - "operands[2] = operand_subword (operands[0], 1, 0, TImode); - operands[3] = legitimize_la_operand (XEXP (operands[1], 0));") + [(set (match_dup 0) (match_dup 1))] +{ + rtx addr = operand_subword (operands[0], 1, 0, TImode); + s390_load_address (addr, XEXP (operands[1], 0)); + operands[1] = replace_equiv_address (operands[1], addr); +}) + +(define_expand "reload_outti" + [(parallel [(match_operand:TI 0 "memory_operand" "") + (match_operand:TI 1 "register_operand" "d") + (match_operand:DI 2 "register_operand" "=&a")])] + "TARGET_64BIT" +{ + s390_load_address (operands[2], XEXP (operands[0], 0)); + operands[0] = replace_equiv_address (operands[0], operands[2]); + emit_move_insn (operands[0], operands[1]); + DONE; +}) ; ; movdi instruction pattern(s). ; -;; If generating PIC code and operands[1] is a symbolic CONST, emit a -;; move to get the address of the symbolic object from the GOT. - (define_expand "movdi" [(set (match_operand:DI 0 "general_operand" "") (match_operand:DI 1 "general_operand" ""))] "" " { - /* Handle PIC symbolic constants. */ - if (TARGET_64BIT && flag_pic && SYMBOLIC_CONST (operands[1])) - emit_pic_move (operands, DImode); + /* Handle symbolic constants. */ + if (TARGET_64BIT && SYMBOLIC_CONST (operands[1])) + emit_symbolic_move (operands); /* During and after reload, we need to force constants to the literal pool ourselves, if necessary. */ if ((reload_in_progress || reload_completed) && CONSTANT_P (operands[1]) && (!legitimate_reload_constant_p (operands[1]) - || fp_operand (operands[0], VOIDmode))) + || FP_REG_P (operands[0]))) operands[1] = force_const_mem (DImode, operands[1]); }") @@ -901,7 +950,7 @@ "TARGET_64BIT && GET_CODE (operands[1]) == CONST_INT && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K') - && !fp_operand (operands[0], VOIDmode)" + && !FP_REG_P (operands[0])" "lghi\\t%0,%h1" [(set_attr "op_type" "RI") (set_attr "atype" "reg")]) @@ -910,7 +959,7 @@ [(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_operand (operands[0], VOIDmode)" + && !FP_REG_P (operands[0])" "* { int part = s390_single_hi (operands[1], DImode, 0); @@ -932,23 +981,15 @@ [(set (match_operand:DI 0 "register_operand" "=d") (match_operand:DI 1 "larl_operand" "X"))] "TARGET_64BIT - && !fp_operand (operands[0], VOIDmode)" + && !FP_REG_P (operands[0])" "larl\\t%0,%1" [(set_attr "op_type" "RIL") (set_attr "atype" "reg") (set_attr "type" "la")]) -(define_insn "*movdi_ss" - [(set (match_operand:DI 0 "s_operand" "=Qo") - (match_operand:DI 1 "s_imm_operand" "Qo"))] - "" - "mvc\\t%O0(8,%R0),%1" - [(set_attr "op_type" "SS") - (set_attr "atype" "mem")]) - (define_insn "*movdi_64" - [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,m,!*f,!*f,!m") - (match_operand:DI 1 "general_operand" "d,m,d,*f,m,*f"))] + [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,m,!*f,!*f,!m,?Q") + (match_operand:DI 1 "general_operand" "d,m,d,*f,m,*f,?Q"))] "TARGET_64BIT" "@ lgr\\t%0,%1 @@ -956,13 +997,14 @@ stg\\t%1,%0 ldr\\t%0,%1 ld\\t%0,%1 - std\\t%1,%0" - [(set_attr "op_type" "RRE,RXE,RXE,RR,RX,RX") - (set_attr "atype" "reg,mem,mem,reg,mem,mem")]) + std\\t%1,%0 + mvc\\t%O0(8,%R0),%1" + [(set_attr "op_type" "RRE,RXE,RXE,RR,RX,RX,SS") + (set_attr "atype" "reg,mem,mem,reg,mem,mem,mem")]) (define_insn "*movdi_31" - [(set (match_operand:DI 0 "nonimmediate_operand" "=d,Q,d,m,!*f,!*f,!m") - (match_operand:DI 1 "general_operand" "Q,d,dKm,d,*f,m,*f"))] + [(set (match_operand:DI 0 "nonimmediate_operand" "=d,Q,d,o,!*f,!*f,!m,Q") + (match_operand:DI 1 "general_operand" "Q,d,dKm,d,*f,m,*f,Q"))] "!TARGET_64BIT" "@ lm\\t%0,%N0,%1 @@ -971,75 +1013,89 @@ # ldr\\t%0,%1 ld\\t%0,%1 - std\\t%1,%0" - [(set_attr "op_type" "RS,RS,NN,NN,RR,RX,RX") - (set_attr "atype" "mem,mem,*,*,reg,mem,mem")]) + std\\t%1,%0 + mvc\\t%O0(8,%R0),%1" + [(set_attr "op_type" "RS,RS,NN,NN,RR,RX,RX,SS") + (set_attr "atype" "mem,mem,*,*,reg,mem,mem,mem")]) (define_split [(set (match_operand:DI 0 "nonimmediate_operand" "") (match_operand:DI 1 "general_operand" ""))] "!TARGET_64BIT && reload_completed - && !fp_operand (operands[0], VOIDmode) - && !fp_operand (operands[1], VOIDmode) - && !s_operand (operands[0], VOIDmode) - && !s_operand (operands[1], VOIDmode) - && (register_operand (operands[0], VOIDmode) - || register_operand (operands[1], VOIDmode)) - && (!register_operand (operands[0], VOIDmode) - || !reg_overlap_mentioned_p (operand_subword (operands[0], 0, 0, DImode), - operands[1]) - || !reg_overlap_mentioned_p (operand_subword (operands[0], 1, 0, DImode), - operands[1]))" + && s390_split_ok_p (operands[0], operands[1], DImode, 0)" [(set (match_dup 2) (match_dup 4)) (set (match_dup 3) (match_dup 5))] - " { - if (!register_operand (operands[0], VOIDmode) - || !reg_overlap_mentioned_p (operand_subword (operands[0], 0, 0, DImode), - operands[1])) - { - operands[2] = operand_subword (operands[0], 0, 0, DImode); - operands[3] = operand_subword (operands[0], 1, 0, DImode); - operands[4] = operand_subword (operands[1], 0, 0, DImode); - operands[5] = operand_subword (operands[1], 1, 0, DImode); - } - else - { - operands[2] = operand_subword (operands[0], 1, 0, DImode); - operands[3] = operand_subword (operands[0], 0, 0, DImode); - operands[4] = operand_subword (operands[1], 1, 0, DImode); - operands[5] = operand_subword (operands[1], 0, 0, DImode); - } -}") + operands[2] = operand_subword (operands[0], 0, 0, DImode); + operands[3] = operand_subword (operands[0], 1, 0, DImode); + operands[4] = operand_subword (operands[1], 0, 0, DImode); + operands[5] = operand_subword (operands[1], 1, 0, DImode); +}) + +(define_split + [(set (match_operand:DI 0 "nonimmediate_operand" "") + (match_operand:DI 1 "general_operand" ""))] + "!TARGET_64BIT && reload_completed + && s390_split_ok_p (operands[0], operands[1], DImode, 1)" + [(set (match_dup 2) (match_dup 4)) + (set (match_dup 3) (match_dup 5))] +{ + operands[2] = operand_subword (operands[0], 1, 0, DImode); + operands[3] = operand_subword (operands[0], 0, 0, DImode); + operands[4] = operand_subword (operands[1], 1, 0, DImode); + operands[5] = operand_subword (operands[1], 0, 0, DImode); +}) (define_split [(set (match_operand:DI 0 "register_operand" "") (match_operand:DI 1 "memory_operand" ""))] "!TARGET_64BIT && reload_completed - && !fp_operand (operands[0], VOIDmode) - && !fp_operand (operands[1], VOIDmode) + && !FP_REG_P (operands[0]) && !s_operand (operands[1], VOIDmode)" - [(set (match_dup 2) (match_dup 3)) - (set (match_dup 0) (mem:DI (match_dup 2)))] - "operands[2] = operand_subword (operands[0], 1, 0, DImode); - operands[3] = legitimize_la_operand (XEXP (operands[1], 0));") + [(set (match_dup 0) (match_dup 1))] +{ + rtx addr = operand_subword (operands[0], 1, 0, DImode); + s390_load_address (addr, XEXP (operands[1], 0)); + operands[1] = replace_equiv_address (operands[1], addr); +}) + +(define_expand "reload_outdi" + [(parallel [(match_operand:DI 0 "memory_operand" "") + (match_operand:DI 1 "register_operand" "d") + (match_operand:SI 2 "register_operand" "=&a")])] + "!TARGET_64BIT" +{ + s390_load_address (operands[2], XEXP (operands[0], 0)); + operands[0] = replace_equiv_address (operands[0], operands[2]); + emit_move_insn (operands[0], operands[1]); + DONE; +}) + +(define_peephole2 + [(set (match_operand:DI 0 "register_operand" "") + (mem:DI (match_operand 1 "address_operand" "")))] + "TARGET_64BIT + && !FP_REG_P (operands[0]) + && GET_CODE (operands[1]) == SYMBOL_REF + && CONSTANT_POOL_ADDRESS_P (operands[1]) + && get_pool_mode (operands[1]) == DImode + && legitimate_reload_constant_p (get_pool_constant (operands[1]))" + [(set (match_dup 0) (match_dup 2))] + "operands[2] = get_pool_constant (operands[1]);") ; ; movsi instruction pattern(s). ; -;; If generating PIC code and operands[1] is a symbolic CONST, emit a -;; move to get the address of the symbolic object from the GOT. - (define_expand "movsi" [(set (match_operand:SI 0 "general_operand" "") (match_operand:SI 1 "general_operand" ""))] "" " { - /* Handle PIC symbolic constants. */ - if (!TARGET_64BIT && flag_pic && SYMBOLIC_CONST (operands[1])) - emit_pic_move (operands, SImode); + /* Handle symbolic constants. */ + if (!TARGET_64BIT && SYMBOLIC_CONST (operands[1])) + emit_symbolic_move (operands); /* expr.c tries to load an effective address using force_reg. This fails because we don't have a @@ -1059,7 +1115,7 @@ if ((reload_in_progress || reload_completed) && CONSTANT_P (operands[1]) && (!legitimate_reload_constant_p (operands[1]) - || fp_operand (operands[0], VOIDmode))) + || FP_REG_P (operands[0]))) operands[1] = force_const_mem (SImode, operands[1]); }") @@ -1068,7 +1124,7 @@ (match_operand:SI 1 "immediate_operand" "K"))] "GET_CODE (operands[1]) == CONST_INT && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K') - && !fp_operand (operands[0], VOIDmode)" + && !FP_REG_P (operands[0])" "lhi\\t%0,%h1" [(set_attr "op_type" "RI")]) @@ -1076,7 +1132,7 @@ [(set (match_operand:SI 0 "register_operand" "=d") (match_operand:SI 1 "immediate_operand" "n"))] "TARGET_64BIT && s390_single_hi (operands[1], SImode, 0) >= 0 - && !fp_operand (operands[0], VOIDmode)" + && !FP_REG_P (operands[0])" "* { int part = s390_single_hi (operands[1], SImode, 0); @@ -1091,17 +1147,9 @@ }" [(set_attr "op_type" "RI")]) -(define_insn "*movsi_ss" - [(set (match_operand:SI 0 "s_operand" "=Qo") - (match_operand:SI 1 "s_imm_operand" "Qo"))] - "" - "mvc\\t%O0(4,%R0),%1" - [(set_attr "op_type" "SS") - (set_attr "atype" "mem")]) - (define_insn "*movsi" - [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,m,!*f,!*f,!m") - (match_operand:SI 1 "general_operand" "d,m,d,*f,m,*f"))] + [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,m,!*f,!*f,!m,?Q") + (match_operand:SI 1 "general_operand" "d,m,d,*f,m,*f,?Q"))] "" "@ lr\\t%0,%1 @@ -1109,62 +1157,94 @@ st\\t%1,%0 ler\\t%0,%1 le\\t%0,%1 - ste\\t%1,%0" - [(set_attr "op_type" "RR,RX,RX,RR,RX,RX") - (set_attr "atype" "reg,mem,mem,reg,mem,mem")]) + ste\\t%1,%0 + mvc\\t%O0(4,%R0),%1" + [(set_attr "op_type" "RR,RX,RX,RR,RX,RX,SS") + (set_attr "atype" "reg,mem,mem,reg,mem,mem,mem")]) +(define_peephole2 + [(set (match_operand:SI 0 "register_operand" "") + (mem:SI (match_operand 1 "address_operand" "")))] + "!FP_REG_P (operands[0]) + && GET_CODE (operands[1]) == SYMBOL_REF + && CONSTANT_POOL_ADDRESS_P (operands[1]) + && get_pool_mode (operands[1]) == SImode + && legitimate_reload_constant_p (get_pool_constant (operands[1]))" + [(set (match_dup 0) (match_dup 2))] + "operands[2] = get_pool_constant (operands[1]);") ; ; movhi instruction pattern(s). ; (define_insn "movhi" - [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m") - (match_operand:HI 1 "general_operand" "d,n,m,d"))] + [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m,?Q") + (match_operand:HI 1 "general_operand" "d,n,m,d,?Q"))] "" "@ lr\\t%0,%1 lhi\\t%0,%h1 lh\\t%0,%1 - sth\\t%1,%0" - [(set_attr "op_type" "RR,RI,RX,RX") - (set_attr "atype" "reg,reg,mem,mem")]) + sth\\t%1,%0 + mvc\\t%O0(2,%R0),%1" + [(set_attr "op_type" "RR,RI,RX,RX,SS") + (set_attr "atype" "reg,reg,mem,mem,mem")]) +(define_peephole2 + [(set (match_operand:HI 0 "register_operand" "") + (mem:HI (match_operand 1 "address_operand" "")))] + "GET_CODE (operands[1]) == SYMBOL_REF + && CONSTANT_POOL_ADDRESS_P (operands[1]) + && get_pool_mode (operands[1]) == HImode + && GET_CODE (get_pool_constant (operands[1])) == CONST_INT" + [(set (match_dup 0) (match_dup 2))] + "operands[2] = get_pool_constant (operands[1]);") ; ; movqi instruction pattern(s). ; (define_insn "movqi_64" - [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,Q") - (match_operand:QI 1 "general_operand" "d,n,m,d,n"))] + [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,Q,?Q") + (match_operand:QI 1 "general_operand" "d,n,m,d,n,?Q"))] "TARGET_64BIT" "@ lr\\t%0,%1 lhi\\t%0,%b1 llgc\\t%0,%1 stc\\t%1,%0 - mvi\\t%0,%b1" - [(set_attr "op_type" "RR,RI,RXE,RX,SI") - (set_attr "atype" "reg,reg,mem,mem,mem")]) + mvi\\t%0,%b1 + mvc\\t%O0(1,%R0),%1" + [(set_attr "op_type" "RR,RI,RXE,RX,SI,SS") + (set_attr "atype" "reg,reg,mem,mem,mem,mem")]) (define_insn "movqi" - [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,Q") - (match_operand:QI 1 "general_operand" "d,n,m,d,n"))] + [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,Q,?Q") + (match_operand:QI 1 "general_operand" "d,n,m,d,n,?Q"))] "" "@ lr\\t%0,%1 lhi\\t%0,%b1 ic\\t%0,%1 stc\\t%1,%0 - mvi\\t%0,%b1" - [(set_attr "op_type" "RR,RI,RX,RX,SI") - (set_attr "atype" "reg,reg,mem,mem,mem")]) + mvi\\t%0,%b1 + mvc\\t%O0(1,%R0),%1" + [(set_attr "op_type" "RR,RI,RX,RX,SI,SS") + (set_attr "atype" "reg,reg,mem,mem,mem,mem")]) +(define_peephole2 + [(set (match_operand:QI 0 "nonimmediate_operand" "") + (mem:QI (match_operand 1 "address_operand" "")))] + "GET_CODE (operands[1]) == SYMBOL_REF + && CONSTANT_POOL_ADDRESS_P (operands[1]) + && get_pool_mode (operands[1]) == QImode + && GET_CODE (get_pool_constant (operands[1])) == CONST_INT" + [(set (match_dup 0) (match_dup 2))] + "operands[2] = get_pool_constant (operands[1]);") ; -; moveqstrictqi instruction pattern(s). +; movstrictqi instruction pattern(s). ; (define_insn "*movstrictqi" @@ -1181,7 +1261,7 @@ (define_insn "*movstricthi" [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d")) - (match_operand:HI 1 "s_imm_operand" "Qo")) + (match_operand:HI 1 "s_imm_operand" "Q")) (clobber (reg:CC 33))] "" "icm\\t%0,3,%1" @@ -1193,7 +1273,7 @@ ; movstrictsi instruction pattern(s). ; -(define_insn "movestrictsi" +(define_insn "movstrictsi" [(set (strict_low_part (match_operand:SI 0 "register_operand" "+d,d")) (match_operand:SI 1 "general_operand" "d,m"))] "TARGET_64BIT" @@ -1221,17 +1301,9 @@ operands[1] = force_const_mem (DFmode, operands[1]); }") -(define_insn "*movdf_ss" - [(set (match_operand:DF 0 "s_operand" "=Qo") - (match_operand:DF 1 "s_imm_operand" "Qo"))] - "" - "mvc\\t%O0(8,%R0),%1" - [(set_attr "op_type" "SS") - (set_attr "atype" "mem")]) - (define_insn "*movdf_64" - [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,m,d,d,m") - (match_operand:DF 1 "general_operand" "f,m,f,d,m,d"))] + [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,m,d,d,m,?Q") + (match_operand:DF 1 "general_operand" "f,m,f,d,m,d,?Q"))] "TARGET_64BIT" "@ ldr\\t%0,%1 @@ -1239,13 +1311,14 @@ std\\t%1,%0 lgr\\t%0,%1 lg\\t%0,%1 - stg\\t%1,%0" - [(set_attr "op_type" "RR,RX,RX,RRE,RXE,RXE") - (set_attr "atype" "reg,mem,mem,reg,mem,mem")]) + stg\\t%1,%0 + mvc\\t%O0(8,%R0),%1" + [(set_attr "op_type" "RR,RX,RX,RRE,RXE,RXE,SS") + (set_attr "atype" "reg,mem,mem,reg,mem,mem,mem")]) (define_insn "*movdf_31" - [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,m,d,Q,d,m") - (match_operand:DF 1 "general_operand" "f,m,f,Q,d,dKm,d"))] + [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,m,d,Q,d,o,Q") + (match_operand:DF 1 "general_operand" "f,m,f,Q,d,dKm,d,Q"))] "!TARGET_64BIT" "@ ldr\\t%0,%1 @@ -1254,58 +1327,63 @@ lm\\t%0,%N0,%1 stm\\t%1,%N1,%0 # - #" - [(set_attr "op_type" "RR,RX,RX,RS,RS,NN,NN") - (set_attr "atype" "reg,mem,mem,mem,mem,*,*")]) + # + mvc\\t%O0(8,%R0),%1" + [(set_attr "op_type" "RR,RX,RX,RS,RS,NN,NN,SS") + (set_attr "atype" "reg,mem,mem,mem,mem,*,*,mem")]) (define_split [(set (match_operand:DF 0 "nonimmediate_operand" "") (match_operand:DF 1 "general_operand" ""))] "!TARGET_64BIT && reload_completed - && !fp_operand (operands[0], VOIDmode) - && !fp_operand (operands[1], VOIDmode) - && !s_operand (operands[0], VOIDmode) - && !s_operand (operands[1], VOIDmode) - && (register_operand (operands[0], VOIDmode) - || register_operand (operands[1], VOIDmode)) - && (!register_operand (operands[0], VOIDmode) - || !reg_overlap_mentioned_p (operand_subword (operands[0], 0, 0, DFmode), - operands[1]) - || !reg_overlap_mentioned_p (operand_subword (operands[0], 1, 0, DFmode), - operands[1]))" + && s390_split_ok_p (operands[0], operands[1], DFmode, 0)" [(set (match_dup 2) (match_dup 4)) (set (match_dup 3) (match_dup 5))] - " { - if (!register_operand (operands[0], VOIDmode) - || !reg_overlap_mentioned_p (operand_subword (operands[0], 0, 0, DFmode), - operands[1])) - { - operands[2] = operand_subword (operands[0], 0, 0, DFmode); - operands[3] = operand_subword (operands[0], 1, 0, DFmode); - operands[4] = operand_subword (operands[1], 0, 0, DFmode); - operands[5] = operand_subword (operands[1], 1, 0, DFmode); - } - else - { - operands[2] = operand_subword (operands[0], 1, 0, DFmode); - operands[3] = operand_subword (operands[0], 0, 0, DFmode); - operands[4] = operand_subword (operands[1], 1, 0, DFmode); - operands[5] = operand_subword (operands[1], 0, 0, DFmode); - } -}") + operands[2] = operand_subword (operands[0], 0, 0, DFmode); + operands[3] = operand_subword (operands[0], 1, 0, DFmode); + operands[4] = operand_subword (operands[1], 0, 0, DFmode); + operands[5] = operand_subword (operands[1], 1, 0, DFmode); +}) + +(define_split + [(set (match_operand:DF 0 "nonimmediate_operand" "") + (match_operand:DF 1 "general_operand" ""))] + "!TARGET_64BIT && reload_completed + && s390_split_ok_p (operands[0], operands[1], DFmode, 1)" + [(set (match_dup 2) (match_dup 4)) + (set (match_dup 3) (match_dup 5))] +{ + operands[2] = operand_subword (operands[0], 1, 0, DFmode); + operands[3] = operand_subword (operands[0], 0, 0, DFmode); + operands[4] = operand_subword (operands[1], 1, 0, DFmode); + operands[5] = operand_subword (operands[1], 0, 0, DFmode); +}) (define_split [(set (match_operand:DF 0 "register_operand" "") (match_operand:DF 1 "memory_operand" ""))] "!TARGET_64BIT && reload_completed - && !fp_operand (operands[0], VOIDmode) - && !fp_operand (operands[1], VOIDmode) + && !FP_REG_P (operands[0]) && !s_operand (operands[1], VOIDmode)" - [(set (match_dup 2) (match_dup 3)) - (set (match_dup 0) (mem:DI (match_dup 2)))] - "operands[2] = operand_subword (operands[0], 1, 0, DFmode); - operands[3] = legitimize_la_operand (XEXP (operands[1], 0));") + [(set (match_dup 0) (match_dup 1))] +{ + rtx addr = operand_subword (operands[0], 1, 0, DFmode); + s390_load_address (addr, XEXP (operands[1], 0)); + operands[1] = replace_equiv_address (operands[1], addr); +}) + +(define_expand "reload_outdf" + [(parallel [(match_operand:DF 0 "memory_operand" "") + (match_operand:DF 1 "register_operand" "d") + (match_operand:SI 2 "register_operand" "=&a")])] + "!TARGET_64BIT" +{ + s390_load_address (operands[2], XEXP (operands[0], 0)); + operands[0] = replace_equiv_address (operands[0], operands[2]); + emit_move_insn (operands[0], operands[1]); + DONE; +}) ; ; movsf instruction pattern(s). @@ -1324,17 +1402,9 @@ operands[1] = force_const_mem (SFmode, operands[1]); }") -(define_insn "*movsf_ss" - [(set (match_operand:SF 0 "s_operand" "=Qo") - (match_operand:SF 1 "s_imm_operand" "Qo"))] - "" - "mvc\\t%O0(4,%R0),%1" - [(set_attr "op_type" "SS") - (set_attr "atype" "mem")]) - (define_insn "*movsf" - [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,m,d,d,m") - (match_operand:SF 1 "general_operand" "f,m,f,d,m,d"))] + [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,m,d,d,m,?Q") + (match_operand:SF 1 "general_operand" "f,m,f,d,m,d,?Q"))] "" "@ ler\\t%0,%1 @@ -1342,9 +1412,10 @@ ste\\t%1,%0 lr\\t%0,%1 l\\t%0,%1 - st\\t%1,%0" - [(set_attr "op_type" "RR,RX,RX,RR,RX,RX") - (set_attr "atype" "reg,mem,mem,reg,mem,mem")]) + st\\t%1,%0 + mvc\\t%O0(4,%R0),%1" + [(set_attr "op_type" "RR,RX,RX,RR,RX,RX,SS") + (set_attr "atype" "reg,mem,mem,reg,mem,mem,mem")]) ; ; load_multiple pattern(s). @@ -1413,7 +1484,7 @@ (define_insn "*load_multiple_di" [(match_parallel 0 "load_multiple_operation" [(set (match_operand:DI 1 "register_operand" "=r") - (match_operand:DI 2 "s_operand" "oQ"))])] + (match_operand:DI 2 "s_operand" "Q"))])] "" "* { @@ -1432,7 +1503,7 @@ (define_insn "*load_multiple_si" [(match_parallel 0 "load_multiple_operation" [(set (match_operand:SI 1 "register_operand" "=r") - (match_operand:SI 2 "s_operand" "oQ"))])] + (match_operand:SI 2 "s_operand" "Q"))])] "" "* { @@ -1516,7 +1587,7 @@ (define_insn "*store_multiple_di" [(match_parallel 0 "store_multiple_operation" - [(set (match_operand:DI 1 "s_operand" "=oQ") + [(set (match_operand:DI 1 "s_operand" "=Q") (match_operand:DI 2 "register_operand" "r"))])] "" "* @@ -1536,7 +1607,7 @@ (define_insn "*store_multiple_si" [(match_parallel 0 "store_multiple_operation" - [(set (match_operand:SI 1 "s_operand" "=oQ") + [(set (match_operand:SI 1 "s_operand" "=Q") (match_operand:SI 2 "register_operand" "r"))])] "" "* @@ -1558,172 +1629,31 @@ ;; ; -; movstrdi instruction pattern(s). +; movstrM instruction pattern(s). ; (define_expand "movstrdi" - [(set (match_operand:BLK 0 "general_operand" "") - (match_operand:BLK 1 "general_operand" "")) - (use (match_operand:DI 2 "general_operand" "")) - (match_operand 3 "" "")] - "TARGET_64BIT" - " -{ - rtx addr0, addr1; - - addr0 = force_operand (XEXP (operands[0], 0), NULL_RTX); - addr1 = force_operand (XEXP (operands[1], 0), NULL_RTX); - - if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) <= 256) - { - operands[0] = change_address (operands[0], VOIDmode, addr0); - operands[1] = change_address (operands[1], VOIDmode, addr1); - operands[2] = GEN_INT (INTVAL (operands[2]) - 1); - - emit_insn (gen_movstrdi_short (operands[0], operands[1], operands[2])); - DONE; - } - else - { - if (TARGET_MVCLE) - { - /* implementation suggested by Richard Henderson <rth@cygnus.com> */ - rtx reg0 = gen_reg_rtx (TImode); - rtx reg1 = gen_reg_rtx (TImode); - rtx len = operands[2]; - - if (! CONSTANT_P (len)) - len = force_reg (DImode, len); - - /* Load up the address+length pairs. */ - - emit_move_insn (gen_highpart (DImode, reg0), addr0); - emit_move_insn (gen_lowpart (DImode, reg0), len); - - emit_move_insn (gen_highpart (DImode, reg1), addr1); - emit_move_insn (gen_lowpart (DImode, reg1), len); - - /* MOVE */ - emit_insn (gen_movstrdi_64 (reg0, reg1, reg0, reg1)); - DONE; - } - else - { - rtx label1 = gen_label_rtx (); - rtx label2 = gen_label_rtx (); - rtx reg0, reg1, len, blocks; - - reg0 = gen_reg_rtx (DImode); - reg1 = gen_reg_rtx (DImode); - len = gen_reg_rtx (DImode); - blocks = gen_reg_rtx (DImode); - - emit_move_insn (len, operands[2]); - emit_insn (gen_cmpdi (len, const0_rtx)); - emit_jump_insn (gen_beq (label1)); - emit_move_insn (reg0, addr0); - emit_move_insn (reg1, addr1); - emit_insn (gen_adddi3 (len, len, constm1_rtx)); - emit_insn (gen_ashrdi3 (blocks, len, GEN_INT (8))); - emit_insn (gen_cmpdi (blocks, const0_rtx)); - emit_jump_insn (gen_beq (label2)); - emit_insn (gen_movstrdi_long (reg0, reg1, reg0, reg1, blocks, blocks)); - emit_label (label2); - operands[0] = change_address (operands[0], VOIDmode, reg0); - operands[1] = change_address (operands[1], VOIDmode, reg1); - emit_insn (gen_movstrdi_short (operands[0], operands[1], len)); - emit_label (label1); - DONE; - } - } -}") - -; -; movstrsi instruction pattern(s). -; + [(set (match_operand:BLK 0 "memory_operand" "") + (match_operand:BLK 1 "memory_operand" "")) + (use (match_operand:DI 2 "general_operand" "")) + (match_operand 3 "" "")] + "TARGET_64BIT" + "s390_expand_movstr (operands[0], operands[1], operands[2]); DONE;") (define_expand "movstrsi" - [(set (match_operand:BLK 0 "general_operand" "") - (match_operand:BLK 1 "general_operand" "")) - (use (match_operand:SI 2 "general_operand" "")) - (match_operand 3 "" "")] - "!TARGET_64BIT" - " -{ - rtx addr0 = force_operand (XEXP (operands[0], 0), NULL_RTX); - rtx addr1 = force_operand (XEXP (operands[1], 0), NULL_RTX); - - if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) <= 256) - { - operands[0] = change_address (operands[0], VOIDmode, addr0); - operands[1] = change_address (operands[1], VOIDmode, addr1); - operands[2] = GEN_INT (INTVAL (operands[2]) - 1); - - emit_insn (gen_movstrsi_short (operands[0], operands[1], operands[2])); - DONE; - } - else - { - if (TARGET_MVCLE) - { - /* implementation suggested by Richard Henderson <rth@cygnus.com> */ - rtx reg0 = gen_reg_rtx (DImode); - rtx reg1 = gen_reg_rtx (DImode); - rtx len = operands[2]; - - - if (! CONSTANT_P (len)) - len = force_reg (SImode, len); - - /* Load up the address+length pairs. */ - - emit_move_insn (gen_highpart (SImode, reg0), addr0); - emit_move_insn (gen_lowpart (SImode, reg0), len); - - emit_move_insn (gen_highpart (SImode, reg1), addr1); - emit_move_insn (gen_lowpart (SImode, reg1), len); - - /* MOVE */ - emit_insn (gen_movstrsi_31 (reg0, reg1, reg0, reg1)); - DONE; - } - else - { - rtx label1 = gen_label_rtx (); - rtx label2 = gen_label_rtx (); - rtx reg0, reg1, len, blocks; - - reg0 = gen_reg_rtx (SImode); - reg1 = gen_reg_rtx (SImode); - len = gen_reg_rtx (SImode); - blocks = gen_reg_rtx (SImode); - - emit_move_insn (len, operands[2]); - emit_insn (gen_cmpsi (len, const0_rtx)); - emit_jump_insn (gen_beq (label1)); - emit_move_insn (reg0, addr0); - emit_move_insn (reg1, addr1); - emit_insn (gen_addsi3 (len, len, constm1_rtx)); - emit_insn (gen_ashrsi3 (blocks, len, GEN_INT (8))); - emit_insn (gen_cmpsi (blocks, const0_rtx)); - emit_jump_insn (gen_beq (label2)); - emit_insn (gen_movstrsi_long (reg0, reg1, reg0, reg1, blocks, blocks)); - emit_label (label2); - operands[0] = change_address (operands[0], VOIDmode, reg0); - operands[1] = change_address (operands[1], VOIDmode, reg1); - emit_insn (gen_movstrsi_short (operands[0], operands[1], len)); - emit_label (label1); - DONE; - } - } -}") + [(set (match_operand:BLK 0 "memory_operand" "") + (match_operand:BLK 1 "memory_operand" "")) + (use (match_operand:SI 2 "general_operand" "")) + (match_operand 3 "" "")] + "" + "s390_expand_movstr (operands[0], operands[1], operands[2]); DONE;") ; Move a block that is up to 256 bytes in length. ; The block length is taken as (operands[2] % 256) + 1. -(define_insn "movstrdi_short" - [(set (match_operand:BLK 0 "s_operand" "=oQ,oQ") - (match_operand:BLK 1 "s_operand" "oQ,oQ")) +(define_insn "movstr_short_64" + [(set (match_operand:BLK 0 "memory_operand" "=Q,Q") + (match_operand:BLK 1 "memory_operand" "Q,Q")) (use (match_operand:DI 2 "nonmemory_operand" "n,a")) (clobber (match_scratch:DI 3 "=X,&a"))] "TARGET_64BIT" @@ -1744,12 +1674,13 @@ } }" [(set_attr "op_type" "SS,NN") + (set_attr "type" "cs,cs") (set_attr "atype" "mem,mem") (set_attr "length" "*,14")]) -(define_insn "movstrsi_short" - [(set (match_operand:BLK 0 "s_operand" "=oQ,oQ") - (match_operand:BLK 1 "s_operand" "oQ,oQ")) +(define_insn "movstr_short_31" + [(set (match_operand:BLK 0 "memory_operand" "=Q,Q") + (match_operand:BLK 1 "memory_operand" "Q,Q")) (use (match_operand:SI 2 "nonmemory_operand" "n,a")) (clobber (match_scratch:SI 3 "=X,&a"))] "!TARGET_64BIT" @@ -1770,64 +1701,13 @@ } }" [(set_attr "op_type" "SS,NN") + (set_attr "type" "cs,cs") (set_attr "atype" "mem,mem") (set_attr "length" "*,14")]) -; Move a block that is a multiple of 256 bytes in length +; Move a block of arbitrary length. -(define_insn "movstrdi_long" - [(set (match_operand:DI 4 "register_operand" "=d") - (const_int 0)) - (set (match_operand:DI 0 "register_operand" "=a") - (plus:DI (match_operand:DI 2 "register_operand" "0") - (ashift:DI (match_operand:DI 5 "register_operand" "4") - (const_int 8)))) - (set (match_operand:DI 1 "register_operand" "=a") - (plus:DI (match_operand:DI 3 "register_operand" "1") - (ashift:DI (match_dup 5) (const_int 8)))) - (set (mem:BLK (match_dup 2)) - (mem:BLK (match_dup 3))) - (use (match_dup 5))] - "TARGET_64BIT" - "* -{ - output_asm_insn (\"mvc\\t0(256,%0),0(%1)\", operands); - output_asm_insn (\"la\\t%0,256(%0)\", operands); - output_asm_insn (\"la\\t%1,256(%1)\", operands); - return \"brct\\t%4,.-14\"; -}" - [(set_attr "op_type" "NN") - (set_attr "atype" "mem") - (set_attr "length" "18")]) - -(define_insn "movstrsi_long" - [(set (match_operand:SI 4 "register_operand" "=d") - (const_int 0)) - (set (match_operand:SI 0 "register_operand" "=a") - (plus:SI (match_operand:SI 2 "register_operand" "0") - (ashift:SI (match_operand:SI 5 "register_operand" "4") - (const_int 8)))) - (set (match_operand:SI 1 "register_operand" "=a") - (plus:SI (match_operand:SI 3 "register_operand" "1") - (ashift:SI (match_dup 5) (const_int 8)))) - (set (mem:BLK (match_dup 2)) - (mem:BLK (match_dup 3))) - (use (match_dup 5))] - "!TARGET_64BIT" - "* -{ - output_asm_insn (\"mvc\\t0(256,%0),0(%1)\", operands); - output_asm_insn (\"la\\t%0,256(%0)\", operands); - output_asm_insn (\"la\\t%1,256(%1)\", operands); - return \"brct\\t%4,.-14\"; -}" - [(set_attr "op_type" "NN") - (set_attr "atype" "mem") - (set_attr "length" "18")]) - -; Move a block that is larger than 255 bytes in length. - -(define_insn "movstrdi_64" +(define_insn "movstr_long_64" [(set (match_operand:TI 0 "register_operand" "=d") (ashift:TI (plus:TI (match_operand:TI 2 "register_operand" "0") (lshiftrt:TI (match_dup 2) (const_int 64))) @@ -1842,10 +1722,11 @@ "TARGET_64BIT" "mvcle\\t%0,%1,0\;jo\\t.-4" [(set_attr "op_type" "NN") + (set_attr "type" "vs") (set_attr "atype" "mem") (set_attr "length" "8")]) -(define_insn "movstrsi_31" +(define_insn "movstr_long_31" [(set (match_operand:DI 0 "register_operand" "=d") (ashift:DI (plus:DI (match_operand:DI 2 "register_operand" "0") (lshiftrt:DI (match_dup 2) (const_int 32))) @@ -1859,112 +1740,93 @@ (clobber (reg:CC 33))] "!TARGET_64BIT" "mvcle\\t%0,%1,0\;jo\\t.-4" - [(set_attr "op_type" "NN") - (set_attr "atype" "mem") - (set_attr "length" "8")]) + [(set_attr "op_type" "NN") + (set_attr "type" "vs") + (set_attr "atype" "mem") + (set_attr "length" "8")]) ; -; clrstrdi instruction pattern(s). +; clrstrM instruction pattern(s). ; (define_expand "clrstrdi" - [(set (match_operand:BLK 0 "general_operand" "") + [(set (match_operand:BLK 0 "memory_operand" "") (const_int 0)) (use (match_operand:DI 1 "general_operand" "")) (match_operand 2 "" "")] "TARGET_64BIT" - " -{ - rtx addr = force_operand (XEXP (operands[0], 0), NULL_RTX); - - operands[0] = change_address (operands[0], VOIDmode, addr); - - if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 256) - { - emit_insn (gen_clrstrsico (operands[0], operands[1])); - DONE; - } - else - { - rtx reg0 = gen_reg_rtx (TImode); - rtx reg1 = gen_reg_rtx (TImode); - rtx len = operands[1]; - - if (! CONSTANT_P (len)) - len = force_reg (DImode, len); - - /* Load up the address+length pairs. */ - - emit_move_insn (gen_highpart (DImode, reg0), addr); - emit_move_insn (gen_lowpart (DImode, reg0), len); - - emit_move_insn (gen_lowpart (DImode, reg1), const0_rtx); - - /* Clear! */ - emit_insn (gen_clrstrsi_64 (reg0, reg1, reg0)); - DONE; - } -}") - -; -; clrstrsi instruction pattern(s). -; + "s390_expand_clrstr (operands[0], operands[1]); DONE;") (define_expand "clrstrsi" - [(set (match_operand:BLK 0 "general_operand" "") + [(set (match_operand:BLK 0 "memory_operand" "") (const_int 0)) (use (match_operand:SI 1 "general_operand" "")) (match_operand 2 "" "")] - "!TARGET_64BIT" - " -{ - rtx addr = force_operand (XEXP (operands[0], 0), NULL_RTX); - - operands[0] = change_address (operands[0], VOIDmode, addr); - - if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 256) - { - emit_insn (gen_clrstrsico (operands[0], operands[1])); - DONE; - } - else - { - rtx reg0 = gen_reg_rtx (DImode); - rtx reg1 = gen_reg_rtx (DImode); - rtx len = operands[1]; - - if (! CONSTANT_P (len)) - len = force_reg (SImode, len); + "" + "s390_expand_clrstr (operands[0], operands[1]); DONE;") - /* Load up the address+length pairs. */ +; Clear a block that is up to 256 bytes in length. +; The block length is taken as (operands[2] % 256) + 1. - emit_move_insn (gen_highpart (SImode, reg0), addr); - emit_move_insn (gen_lowpart (SImode, reg0), len); +(define_insn "clrstr_short_64" + [(set (match_operand:BLK 0 "memory_operand" "=Q,Q") + (const_int 0)) + (use (match_operand:DI 1 "nonmemory_operand" "n,a")) + (clobber (match_scratch:DI 2 "=X,&a")) + (clobber (reg:CC 33))] + "TARGET_64BIT" + "* +{ + switch (which_alternative) + { + case 0: + return \"xc\\t%O0(%b1+1,%R0),%0\"; - emit_move_insn (gen_lowpart (SImode, reg1), const0_rtx); - - /* CLear! */ - emit_insn (gen_clrstrsi_31 (reg0, reg1, reg0)); - DONE; - } -}") + case 1: + output_asm_insn (\"bras\\t%2,.+10\", operands); + output_asm_insn (\"xc\\t%O0(1,%R0),%0\", operands); + return \"ex\\t%1,0(%2)\"; -; Clear memory with length less than 256 bytes + default: + abort (); + } +}" + [(set_attr "op_type" "SS,NN") + (set_attr "type" "cs,cs") + (set_attr "atype" "mem,mem") + (set_attr "length" "*,14")]) -(define_insn "clrstrsico" - [(set (match_operand:BLK 0 "s_operand" "=Qo") +(define_insn "clrstr_short_31" + [(set (match_operand:BLK 0 "memory_operand" "=Q,Q") (const_int 0)) - (use (match_operand 1 "immediate_operand" "I")) + (use (match_operand:SI 1 "nonmemory_operand" "n,a")) + (clobber (match_scratch:SI 2 "=X,&a")) (clobber (reg:CC 33))] - "" - "xc\\t%O0(%1,%R0),%0" - [(set_attr "op_type" "RS") - (set_attr "type" "cs") - (set_attr "atype" "mem")]) + "!TARGET_64BIT" + "* +{ + switch (which_alternative) + { + case 0: + return \"xc\\t%O0(%b1+1,%R0),%0\"; + + case 1: + output_asm_insn (\"bras\\t%2,.+10\", operands); + output_asm_insn (\"xc\\t%O0(1,%R0),%0\", operands); + return \"ex\\t%1,0(%2)\"; + + default: + abort (); + } +}" + [(set_attr "op_type" "SS,NN") + (set_attr "type" "cs,cs") + (set_attr "atype" "mem,mem") + (set_attr "length" "*,14")]) -; Clear memory with length greater 256 bytes or lenght not constant +; Clear a block of arbitrary length. -(define_insn "clrstrsi_64" +(define_insn "clrstr_long_64" [(set (match_operand:TI 0 "register_operand" "=d") (ashift:TI (plus:TI (match_operand:TI 2 "register_operand" "0") (lshiftrt:TI (match_dup 2) (const_int 64))) @@ -1980,7 +1842,7 @@ (set_attr "type" "vs") (set_attr "length" "8")]) -(define_insn "clrstrsi_31" +(define_insn "clrstr_long_31" [(set (match_operand:DI 0 "register_operand" "=d") (ashift:DI (plus:DI (match_operand:DI 2 "register_operand" "0") (lshiftrt:DI (match_dup 2) (const_int 32))) @@ -1997,171 +1859,112 @@ (set_attr "length" "8")]) ; -; cmpstrdi instruction pattern(s). +; cmpstrM instruction pattern(s). ; (define_expand "cmpstrdi" - [(set (match_operand:DI 0 "register_operand" "") - (compare:DI (match_operand:BLK 1 "s_operand" "") - (match_operand:BLK 2 "s_operand" "") ) ) - (use (match_operand:DI 3 "general_operand" "")) - (use (match_operand:DI 4 "" ""))] - "TARGET_64BIT" - " -{ - rtx addr0, addr1; + [(set (match_operand:DI 0 "register_operand" "") + (compare:DI (match_operand:BLK 1 "memory_operand" "") + (match_operand:BLK 2 "memory_operand" "") ) ) + (use (match_operand:DI 3 "general_operand" "")) + (use (match_operand:DI 4 "" ""))] + "TARGET_64BIT" + "s390_expand_cmpstr (operands[0], operands[1], + operands[2], operands[3]); DONE;") - /* for pre/post increment */ - operands[1] = protect_from_queue (operands[1], 0); - operands[2] = protect_from_queue (operands[2], 0); - operands[3] = protect_from_queue (operands[3], 0); +(define_expand "cmpstrsi" + [(set (match_operand:SI 0 "register_operand" "") + (compare:SI (match_operand:BLK 1 "memory_operand" "") + (match_operand:BLK 2 "memory_operand" "") ) ) + (use (match_operand:SI 3 "general_operand" "")) + (use (match_operand:SI 4 "" ""))] + "" + "s390_expand_cmpstr (operands[0], operands[1], + operands[2], operands[3]); DONE;") - addr0 = force_operand (XEXP (operands[1], 0), NULL_RTX); - addr1 = force_operand (XEXP (operands[2], 0), NULL_RTX); +; Compare a block that is up to 256 bytes in length. +; The block length is taken as (operands[2] % 256) + 1. - if (GET_CODE (operands[3]) == CONST_INT && INTVAL (operands[3]) < 256) +(define_insn "cmpstr_short_64" + [(set (reg:CCS 33) + (compare:CCS (match_operand:BLK 0 "memory_operand" "=Q,Q") + (match_operand:BLK 1 "memory_operand" "Q,Q"))) + (use (match_operand:DI 2 "nonmemory_operand" "n,a")) + (clobber (match_scratch:DI 3 "=X,&a"))] + "TARGET_64BIT" + "* +{ + switch (which_alternative) { - if (INTVAL (operands[3]) == 0) { - emit_move_insn (operands[0], operands[3]); - DONE; - } - - operands[1] = change_address (operands[1], VOIDmode, addr0); - operands[2] = change_address (operands[2], VOIDmode, addr1); - - emit_insn (gen_cmpstr_const (operands[1], operands[2], operands[3])); - emit_insn (gen_cmpint_di (operands[0])); - DONE; - } - else - { - /* implementation suggested by Richard Henderson <rth@cygnus.com> */ - rtx reg0 = gen_reg_rtx (TImode); - rtx reg1 = gen_reg_rtx (TImode); - rtx len = operands[3]; - - if (! CONSTANT_P (len)) - len = force_reg (DImode, len); - - /* Load up the address+length pairs. */ - emit_move_insn (gen_highpart (DImode, reg0), addr0); - emit_move_insn (gen_lowpart (DImode, reg0), len); + case 0: + return \"clc\\t%O0(%b2+1,%R0),%1\"; - emit_move_insn (gen_highpart (DImode, reg1), addr1); - emit_move_insn (gen_lowpart (DImode, reg1), len); + case 1: + output_asm_insn (\"bras\\t%3,.+10\", operands); + output_asm_insn (\"clc\\t%O0(1,%R0),%1\", operands); + return \"ex\\t%2,0(%3)\"; - /* Compare! */ - emit_insn (gen_cmpstr_64 (reg0, reg1, reg0, reg1)); - emit_insn (gen_cmpint_di (operands[0])); - DONE; + default: + abort (); } -}") - -; -; cmpstrsi instruction pattern(s). -; +}" + [(set_attr "op_type" "SS,NN") + (set_attr "type" "cs,cs") + (set_attr "atype" "mem,mem") + (set_attr "length" "*,14")]) -(define_expand "cmpstrsi" - [(set (match_operand:SI 0 "register_operand" "") - (compare:SI (match_operand:BLK 1 "s_operand" "") - (match_operand:BLK 2 "s_operand" "") ) ) - (use (match_operand:SI 3 "general_operand" "")) - (use (match_operand:SI 4 "" ""))] - "" - " +(define_insn "cmpstr_short_31" + [(set (reg:CCS 33) + (compare:CCS (match_operand:BLK 0 "memory_operand" "=Q,Q") + (match_operand:BLK 1 "memory_operand" "Q,Q"))) + (use (match_operand:SI 2 "nonmemory_operand" "n,a")) + (clobber (match_scratch:SI 3 "=X,&a"))] + "!TARGET_64BIT" + "* { - rtx addr0, addr1; - - /* for pre/post increment */ - operands[1] = protect_from_queue (operands[1], 0); - operands[2] = protect_from_queue (operands[2], 0); - operands[3] = protect_from_queue (operands[3], 0); - - addr0 = force_operand (XEXP (operands[1], 0), NULL_RTX); - addr1 = force_operand (XEXP (operands[2], 0), NULL_RTX); - - if (GET_CODE (operands[3]) == CONST_INT && INTVAL (operands[3]) < 256) + switch (which_alternative) { - if (INTVAL (operands[3]) == 0) { - emit_move_insn (operands[0], operands[3]); - DONE; - } - - operands[1] = change_address (operands[1], VOIDmode, addr0); - operands[2] = change_address (operands[2], VOIDmode, addr1); - - emit_insn (gen_cmpstr_const (operands[1], operands[2], operands[3])); - emit_insn (gen_cmpint_si (operands[0])); - DONE; - } - else - { - /* implementation suggested by Richard Henderson <rth@cygnus.com> */ - rtx reg0, reg1; - rtx len = operands[3]; - - if (TARGET_64BIT) - { - reg0 = gen_reg_rtx (TImode); - reg1 = gen_reg_rtx (TImode); - } - else - { - reg0 = gen_reg_rtx (DImode); - reg1 = gen_reg_rtx (DImode); - } - - /* Load up the address+length pairs. */ - emit_move_insn (gen_highpart (Pmode, reg0), addr0); - convert_move (gen_lowpart (Pmode, reg0), len, 1); - - emit_move_insn (gen_highpart (Pmode, reg1), addr1); - convert_move (gen_lowpart (Pmode, reg1), len, 1); + case 0: + return \"clc\\t%O0(%b2+1,%R0),%1\"; - /* Compare! */ - if (TARGET_64BIT) - emit_insn (gen_cmpstr_64 (reg0, reg1, reg0, reg1)); - else - emit_insn (gen_cmpstr_31 (reg0, reg1, reg0, reg1)); + case 1: + output_asm_insn (\"bras\\t%3,.+10\", operands); + output_asm_insn (\"clc\\t%O0(1,%R0),%1\", operands); + return \"ex\\t%2,0(%3)\"; - emit_insn (gen_cmpint_si (operands[0])); - DONE; + default: + abort (); } -}") - -; Compare a block that is less than 256 bytes in length. - -(define_insn "cmpstr_const" - [(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" - "clc\\t%O0(%c2,%R0),%1" - [(set_attr "op_type" "SS") - (set_attr "atype" "mem") - (set_attr "type" "cs")]) +}" + [(set_attr "op_type" "SS,NN") + (set_attr "type" "cs,cs") + (set_attr "atype" "mem,mem") + (set_attr "length" "*,14")]) -; Compare a block that is larger than 255 bytes in length. +; Compare a block of arbitrary length. -(define_insn "cmpstr_64" +(define_insn "cmpstr_long_64" [(clobber (match_operand:TI 0 "register_operand" "=d")) (clobber (match_operand:TI 1 "register_operand" "=d")) (set (reg:CCS 33) (compare:CCS (mem:BLK (subreg:DI (match_operand:TI 2 "register_operand" "0") 0)) - (mem:BLK (subreg:DI (match_operand:TI 3 "register_operand" "1") 0))))] + (mem:BLK (subreg:DI (match_operand:TI 3 "register_operand" "1") 0)))) + (use (match_dup 2)) + (use (match_dup 3))] "TARGET_64BIT" "clcl\\t%0,%1" [(set_attr "op_type" "RR") (set_attr "atype" "mem") (set_attr "type" "vs")]) -(define_insn "cmpstr_31" +(define_insn "cmpstr_long_31" [(clobber (match_operand:DI 0 "register_operand" "=d")) (clobber (match_operand:DI 1 "register_operand" "=d")) (set (reg:CCS 33) (compare:CCS (mem:BLK (subreg:SI (match_operand:DI 2 "register_operand" "0") 0)) - (mem:BLK (subreg:SI (match_operand:DI 3 "register_operand" "1") 0))))] + (mem:BLK (subreg:SI (match_operand:DI 3 "register_operand" "1") 0)))) + (use (match_dup 2)) + (use (match_dup 3))] "!TARGET_64BIT" "clcl\\t%0,%1" [(set_attr "op_type" "RR") @@ -2211,7 +2014,7 @@ (define_insn "*sethighqisi" [(set (match_operand:SI 0 "register_operand" "=d") - (unspec:SI [(match_operand:QI 1 "s_operand" "Qo")] 10)) + (unspec:SI [(match_operand:QI 1 "s_operand" "Q")] 10)) (clobber (reg:CC 33))] "" "icm\\t%0,8,%1" @@ -2220,7 +2023,7 @@ (define_insn "*sethighhisi" [(set (match_operand:SI 0 "register_operand" "=d") - (unspec:SI [(match_operand:HI 1 "s_operand" "Qo")] 10)) + (unspec:SI [(match_operand:HI 1 "s_operand" "Q")] 10)) (clobber (reg:CC 33))] "" "icm\\t%0,12,%1" @@ -2229,7 +2032,7 @@ (define_insn "*sethighqidi_64" [(set (match_operand:DI 0 "register_operand" "=d") - (unspec:DI [(match_operand:QI 1 "s_operand" "Qo")] 10)) + (unspec:DI [(match_operand:QI 1 "s_operand" "Q")] 10)) (clobber (reg:CC 33))] "TARGET_64BIT" "icmh\\t%0,8,%1" @@ -2238,20 +2041,23 @@ (define_insn "*sethighqidi_31" [(set (match_operand:DI 0 "register_operand" "=d") - (unspec:DI [(match_operand:QI 1 "s_operand" "Qo")] 10)) + (unspec:DI [(match_operand:QI 1 "s_operand" "Q")] 10)) (clobber (reg:CC 33))] "!TARGET_64BIT" "icm\\t%0,8,%1" [(set_attr "op_type" "RS") (set_attr "atype" "mem")]) -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (zero_extract:SI (match_operand:QI 1 "s_operand" "") - (match_operand 2 "const_int_operand" "") - (const_int 0)))] - "!TARGET_64BIT && !reload_completed +(define_insn_and_split "*extractqi" + [(set (match_operand:SI 0 "register_operand" "=d") + (zero_extract:SI (match_operand:QI 1 "s_operand" "Q") + (match_operand 2 "const_int_operand" "n") + (const_int 0))) + (clobber (reg:CC 33))] + "!TARGET_64BIT && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 8" + "#" + "&& reload_completed" [(parallel [(set (match_dup 0) (unspec:SI [(match_dup 1)] 10)) (clobber (reg:CC 33))]) @@ -2260,15 +2066,19 @@ { operands[2] = GEN_INT (32 - INTVAL (operands[2])); operands[1] = change_address (operands[1], QImode, 0); -}") +}" + [(set_attr "atype" "mem")]) -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (zero_extract:SI (match_operand:QI 1 "s_operand" "") - (match_operand 2 "const_int_operand" "") - (const_int 0)))] - "!TARGET_64BIT && !reload_completed +(define_insn_and_split "*extracthi" + [(set (match_operand:SI 0 "register_operand" "=d") + (zero_extract:SI (match_operand:QI 1 "s_operand" "Q") + (match_operand 2 "const_int_operand" "n") + (const_int 0))) + (clobber (reg:CC 33))] + "!TARGET_64BIT && INTVAL (operands[2]) >= 8 && INTVAL (operands[2]) < 16" + "#" + "&& reload_completed" [(parallel [(set (match_dup 0) (unspec:SI [(match_dup 1)] 10)) (clobber (reg:CC 33))]) @@ -2277,7 +2087,8 @@ { operands[2] = GEN_INT (32 - INTVAL (operands[2])); operands[1] = change_address (operands[1], HImode, 0); -}") +}" + [(set_attr "atype" "mem")]) ; ; extendsidi2 instruction pattern(s). @@ -2566,6 +2377,20 @@ "llgh\\t%0,%1" [(set_attr "op_type" "RXE") (set_attr "atype" "mem")]) + +(define_insn_and_split "*zero_extendhisi2_31" + [(set (match_operand:SI 0 "register_operand" "=&d") + (zero_extend:SI (match_operand:HI 1 "memory_operand" "Q"))) + (clobber (reg:CC 33))] + "!TARGET_64BIT" + "#" + "&& reload_completed" + [(set (match_dup 0) (const_int 0)) + (parallel + [(set (strict_low_part (match_dup 2)) (match_dup 1)) + (clobber (reg:CC 33))])] + "operands[2] = gen_lowpart (HImode, operands[0]);" + [(set_attr "atype" "mem")]) ; ; zero_extendqisi2 instruction pattern(s). @@ -2590,6 +2415,17 @@ "llgc\\t%0,%1" [(set_attr "op_type" "RXE") (set_attr "atype" "mem")]) + +(define_insn_and_split "*zero_extendqisi2_31" + [(set (match_operand:SI 0 "register_operand" "=&d") + (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))] + "!TARGET_64BIT" + "#" + "&& reload_completed" + [(set (match_dup 0) (const_int 0)) + (set (strict_low_part (match_dup 2)) (match_dup 1))] + "operands[2] = gen_lowpart (QImode, operands[0]);" + [(set_attr "atype" "mem")]) ; ; zero_extendqihi2 instruction pattern(s). @@ -2609,13 +2445,24 @@ (define_insn "*zero_extendqihi2_64" [(set (match_operand:HI 0 "register_operand" "=d") - (zero_extend:HI (match_operand:QI 1 "memory_operand" "m"))) - (clobber (reg:CC 33))] + (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))] "TARGET_64BIT" "llgc\\t%0,%1" [(set_attr "op_type" "RXE") (set_attr "atype" "mem")]) +(define_insn_and_split "*zero_extendqihi2_31" + [(set (match_operand:HI 0 "register_operand" "=&d") + (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))] + "!TARGET_64BIT" + "#" + "&& reload_completed" + [(set (match_dup 0) (const_int 0)) + (set (strict_low_part (match_dup 2)) (match_dup 1))] + "operands[2] = gen_lowpart (QImode, operands[0]);" + [(set_attr "atype" "mem")]) + + ; ; fixuns_truncdfdi2 and fix_truncdfsi2 instruction pattern(s). ; @@ -3062,24 +2909,113 @@ ; adddi3 instruction pattern(s). ; -(define_insn "addaddr_esame" - [(set (match_operand:DI 0 "register_operand" "=a,a") - (plus:DI (match_operand:DI 1 "register_operand" "%a,a") - (match_operand:DI 2 "nonmemory_operand" "J,a")))] - "TARGET_64BIT && (((REGNO (operands[1]) == STACK_POINTER_REGNUM ) || - (REGNO (operands[1]) == BASE_REGISTER)) && - (GET_CODE (operands[2]) == REG || - CONST_OK_FOR_LETTER_P (INTVAL (operands[2]),'J')))" +(define_insn "*adddi3_sign" + [(set (match_operand:DI 0 "register_operand" "=d,d") + (plus:DI (sign_extend:DI (match_operand:SI 2 "general_operand" "d,m")) + (match_operand:DI 1 "register_operand" "0,0"))) + (clobber (reg:CC 33))] + "TARGET_64BIT" "@ - la\\t%0,%c2(,%1) - la\\t%0,0(%1,%2)" - [(set_attr "op_type" "RX") - (set_attr "atype" "mem") - (set_attr "type" "la")]) + agfr\\t%0,%2 + agf\\t%0,%2" + [(set_attr "op_type" "RRE,RXE") + (set_attr "atype" "reg,mem")]) + +(define_insn "*adddi3_zero_cc" + [(set (reg 33) + (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m")) + (match_operand:DI 1 "register_operand" "0,0")) + (const_int 0))) + (set (match_operand:DI 0 "register_operand" "=d,d") + (plus:DI (zero_extend:DI (match_dup 2)) (match_dup 1)))] + "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT" + "@ + algfr\\t%0,%2 + algf\\t%0,%2" + [(set_attr "op_type" "RRE,RXE") + (set_attr "atype" "reg,mem")]) -(define_insn "adddi3_64" +(define_insn "*adddi3_zero_cconly" + [(set (reg 33) + (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m")) + (match_operand:DI 1 "register_operand" "0,0")) + (const_int 0))) + (clobber (match_scratch:DI 0 "=d,d"))] + "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT" + "@ + algfr\\t%0,%2 + algf\\t%0,%2" + [(set_attr "op_type" "RRE,RXE") + (set_attr "atype" "reg,mem")]) + +(define_insn "*adddi3_zero" + [(set (match_operand:DI 0 "register_operand" "=d,d") + (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m")) + (match_operand:DI 1 "register_operand" "0,0"))) + (clobber (reg:CC 33))] + "TARGET_64BIT" + "@ + algfr\\t%0,%2 + algf\\t%0,%2" + [(set_attr "op_type" "RRE,RXE") + (set_attr "atype" "reg,mem")]) + +(define_insn "*adddi3_imm_cc" + [(set (reg 33) + (compare (plus:DI (match_operand:DI 1 "nonimmediate_operand" "0") + (match_operand:DI 2 "const_int_operand" "K")) + (const_int 0))) + (set (match_operand:DI 0 "register_operand" "=d") + (plus:DI (match_dup 1) (match_dup 2)))] + "TARGET_64BIT + && s390_match_ccmode (insn, CCAmode) + && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')" + "aghi\\t%0,%h2" + [(set_attr "op_type" "RI") + (set_attr "atype" "reg")]) + +(define_insn "*adddi3_cc" + [(set (reg 33) + (compare (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") + (match_operand:DI 2 "general_operand" "d,m")) + (const_int 0))) + (set (match_operand:DI 0 "register_operand" "=d,d") + (plus:DI (match_dup 1) (match_dup 2)))] + "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT" + "@ + algr\\t%0,%2 + alg\\t%0,%2" + [(set_attr "op_type" "RRE,RXE") + (set_attr "atype" "reg,mem")]) + +(define_insn "*adddi3_cconly" + [(set (reg 33) + (compare (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") + (match_operand:DI 2 "general_operand" "d,m")) + (const_int 0))) + (clobber (match_scratch:DI 0 "=d,d"))] + "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT" + "@ + algr\\t%0,%2 + alg\\t%0,%2" + [(set_attr "op_type" "RRE,RXE") + (set_attr "atype" "reg,mem")]) + +(define_insn "*adddi3_cconly2" + [(set (reg 33) + (compare (match_operand:DI 1 "nonimmediate_operand" "%0,0") + (neg:SI (match_operand:DI 2 "general_operand" "d,m")))) + (clobber (match_scratch:DI 0 "=d,d"))] + "s390_match_ccmode(insn, CCLmode) && TARGET_64BIT" + "@ + algr\\t%0,%2 + alg\\t%0,%2" + [(set_attr "op_type" "RRE,RXE") + (set_attr "atype" "reg,mem")]) + +(define_insn "*adddi3_64" [(set (match_operand:DI 0 "register_operand" "=d,d,d") - (plus:DI (match_operand:DI 1 "register_operand" "%0,0,0") + (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0") (match_operand:DI 2 "general_operand" "d,K,m") ) ) (clobber (reg:CC 33))] "TARGET_64BIT" @@ -3090,51 +3026,47 @@ [(set_attr "op_type" "RRE,RI,RXE") (set_attr "atype" "reg,reg,mem")]) -(define_insn "adddi3_31" - [(set (match_operand:DI 0 "register_operand" "=d,d") - (plus:DI (match_operand:DI 1 "register_operand" "0,0") - (match_operand:DI 2 "general_operand" "d,m") ) ) +(define_insn_and_split "*adddi3_31" + [(set (match_operand:DI 0 "register_operand" "=&d") + (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0") + (match_operand:DI 2 "general_operand" "do") ) ) (clobber (reg:CC 33))] "!TARGET_64BIT" - "* -{ - switch (which_alternative) - { - case 0: /* d <- d */ - output_asm_insn (\"ar\\t%0,%2\", operands); - output_asm_insn (\"alr\\t%N0,%N2\", operands); - break; - - case 1: /* d <- m */ - output_asm_insn (\"a\\t%0,%2\", operands); - output_asm_insn (\"al\\t%N0,%N2\", operands); - break; - - default: - abort (); - } - - output_asm_insn (\"brc\\t12,.+8\", operands); - return \"ahi\\t%0,1\"; -}" - [(set_attr "op_type" "NN,NN") - (set_attr "atype" "reg,mem") - (set_attr "type" "o2,o2") - (set_attr "length" "12,16")]) + "#" + "&& reload_completed" + [(parallel + [(set (match_dup 3) (plus:SI (match_dup 4) (match_dup 5))) + (clobber (reg:CC 33))]) + (parallel + [(set (reg:CCL1 33) + (compare:CCL1 (plus:SI (match_dup 7) (match_dup 8)) + (match_dup 7))) + (set (match_dup 6) (plus:SI (match_dup 7) (match_dup 8)))]) + (set (pc) + (if_then_else (ltu (reg:CCL1 33) (const_int 0)) + (pc) + (label_ref (match_dup 9)))) + (parallel + [(set (match_dup 3) (plus:SI (match_dup 3) (const_int 1))) + (clobber (reg:CC 33))]) + (match_dup 9)] + "operands[3] = operand_subword (operands[0], 0, 0, DImode); + operands[4] = operand_subword (operands[1], 0, 0, DImode); + operands[5] = operand_subword (operands[2], 0, 0, DImode); + operands[6] = operand_subword (operands[0], 1, 0, DImode); + operands[7] = operand_subword (operands[1], 1, 0, DImode); + operands[8] = operand_subword (operands[2], 1, 0, DImode); + operands[9] = gen_label_rtx ();" + [(set_attr "op_type" "NN")]) (define_expand "adddi3" - [(set (match_operand:DI 0 "register_operand" "") - (plus:DI (match_operand:DI 1 "register_operand" "") - (match_operand:DI 2 "general_operand" "")))] + [(parallel + [(set (match_operand:DI 0 "register_operand" "") + (plus:DI (match_operand:DI 1 "nonimmediate_operand" "") + (match_operand:DI 2 "general_operand" ""))) + (clobber (reg:CC 33))])] "" - " -{ - if (TARGET_64BIT) - emit_insn(gen_adddi3_64 (operands[0],operands[1],operands[2])); - else - emit_insn(gen_adddi3_31 (operands[0],operands[1],operands[2])); - DONE; -}") + "") (define_insn "*la_64" [(set (match_operand:DI 0 "register_operand" "=d") @@ -3145,10 +3077,36 @@ (set_attr "atype" "mem") (set_attr "type" "la")]) +(define_peephole2 + [(parallel + [(set (match_operand:DI 0 "register_operand" "") + (match_operand:QI 1 "address_operand" "")) + (clobber (reg:CC 33))])] + "TARGET_64BIT + && strict_memory_address_p (VOIDmode, operands[1]) + && preferred_la_operand_p (operands[1])" + [(set (match_dup 0) (match_dup 1))] + "") + +(define_peephole2 + [(set (match_operand:DI 0 "register_operand" "") + (match_operand:DI 1 "register_operand" "")) + (parallel + [(set (match_dup 0) + (plus:DI (match_dup 0) + (match_operand:DI 2 "nonmemory_operand" ""))) + (clobber (reg:CC 33))])] + "TARGET_64BIT + && !reg_overlap_mentioned_p (operands[0], operands[2]) + && strict_memory_address_p (VOIDmode, gen_rtx_PLUS (DImode, operands[1], operands[2])) + && preferred_la_operand_p (gen_rtx_PLUS (DImode, operands[1], operands[2]))" + [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))] + "") + (define_expand "reload_indi" [(parallel [(match_operand:DI 0 "register_operand" "=a") (match_operand:DI 1 "s390_plus_operand" "") - (match_operand:TI 2 "register_operand" "=&a")])] + (match_operand:DI 2 "register_operand" "=&a")])] "TARGET_64BIT" " { @@ -3161,24 +3119,81 @@ ; addsi3 instruction pattern(s). ; -(define_insn "*la_ccclobber" - [(set (match_operand:SI 0 "register_operand" "=d") - (match_operand:QI 1 "address_operand" "p")) - (clobber (reg:CC 33))] - "legitimate_la_operand_p (operands[1])" - "la\\t%0,%a1" - [(set_attr "op_type" "RX") - (set_attr "atype" "mem") - (set_attr "type" "la")]) +(define_insn "*addsi3_imm_cc" + [(set (reg 33) + (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "0") + (match_operand:SI 2 "const_int_operand" "K")) + (const_int 0))) + (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')" + "ahi\\t%0,%h2" + [(set_attr "op_type" "RI") + (set_attr "atype" "reg")]) + +(define_insn "*addsi3_carry1_cc" + [(set (reg 33) + (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") + (match_operand:SI 2 "general_operand" "d,m")) + (match_dup 1))) + (set (match_operand:SI 0 "register_operand" "=d,d") + (plus:SI (match_dup 1) (match_dup 2)))] + "s390_match_ccmode (insn, CCL1mode)" + "@ + alr\\t%0,%2 + al\\t%0,%2" + [(set_attr "op_type" "RR,RX") + (set_attr "atype" "reg,mem")]) + +(define_insn "*addsi3_carry1_cconly" + [(set (reg 33) + (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") + (match_operand:SI 2 "general_operand" "d,m")) + (match_dup 1))) + (clobber (match_scratch:SI 0 "=d,d"))] + "s390_match_ccmode (insn, CCL1mode)" + "@ + alr\\t%0,%2 + al\\t%0,%2" + [(set_attr "op_type" "RR,RX") + (set_attr "atype" "reg,mem")]) + +(define_insn "*addsi3_carry2_cc" + [(set (reg 33) + (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") + (match_operand:SI 2 "general_operand" "d,m")) + (match_dup 2))) + (set (match_operand:SI 0 "register_operand" "=d,d") + (plus:SI (match_dup 1) (match_dup 2)))] + "s390_match_ccmode (insn, CCL1mode)" + "@ + alr\\t%0,%2 + al\\t%0,%2" + [(set_attr "op_type" "RR,RX") + (set_attr "atype" "reg,mem")]) + +(define_insn "*addsi3_carry2_cconly" + [(set (reg 33) + (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") + (match_operand:SI 2 "general_operand" "d,m")) + (match_dup 2))) + (clobber (match_scratch:SI 0 "=d,d"))] + "s390_match_ccmode (insn, CCL1mode)" + "@ + alr\\t%0,%2 + al\\t%0,%2" + [(set_attr "op_type" "RR,RX") + (set_attr "atype" "reg,mem")]) (define_insn "*addsi3_cc" [(set (reg 33) - (compare (plus:SI (match_operand:SI 1 "register_operand" "%0,0") - (match_operand:SI 2 "nonimmediate_operand" "d,m")) + (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") + (match_operand:SI 2 "general_operand" "d,m")) (const_int 0))) (set (match_operand:SI 0 "register_operand" "=d,d") (plus:SI (match_dup 1) (match_dup 2)))] - "s390_match_ccmode(insn, CCLmode)" + "s390_match_ccmode (insn, CCLmode)" "@ alr\\t%0,%2 al\\t%0,%2" @@ -3187,11 +3202,11 @@ (define_insn "*addsi3_cconly" [(set (reg 33) - (compare (plus:SI (match_operand:SI 1 "register_operand" "%0,0") + (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") (match_operand:SI 2 "general_operand" "d,m")) (const_int 0))) (clobber (match_scratch:SI 0 "=d,d"))] - "s390_match_ccmode(insn, CCLmode)" + "s390_match_ccmode (insn, CCLmode)" "@ alr\\t%0,%2 al\\t%0,%2" @@ -3200,7 +3215,7 @@ (define_insn "*addsi3_cconly2" [(set (reg 33) - (compare (match_operand:SI 1 "register_operand" "%0,0") + (compare (match_operand:SI 1 "nonimmediate_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)" @@ -3210,9 +3225,29 @@ [(set_attr "op_type" "RR,RX") (set_attr "atype" "reg,mem")]) +(define_insn "*addsi3_sign" + [(set (match_operand:SI 0 "register_operand" "=d") + (plus:SI (match_operand:SI 1 "register_operand" "0") + (sign_extend:SI (match_operand:HI 2 "memory_operand" "m")))) + (clobber (reg:CC 33))] + "" + "ah\\t%0,%2" + [(set_attr "op_type" "RX") + (set_attr "atype" "mem")]) + +(define_insn "*addsi3_sub" + [(set (match_operand:SI 0 "register_operand" "=d") + (plus:SI (match_operand:SI 1 "register_operand" "0") + (subreg:SI (match_operand:HI 2 "memory_operand" "m") 0))) + (clobber (reg:CC 33))] + "" + "ah\\t%0,%2" + [(set_attr "op_type" "RX") + (set_attr "atype" "mem")]) + (define_insn "addsi3" [(set (match_operand:SI 0 "register_operand" "=d,d,d") - (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0") + (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0") (match_operand:SI 2 "general_operand" "d,K,m"))) (clobber (reg:CC 33))] "" @@ -3223,23 +3258,71 @@ [(set_attr "op_type" "RR,RI,RX") (set_attr "atype" "reg,reg,mem")]) -(define_insn "*addsi3_inv" - [(set (match_operand:SI 0 "register_operand" "=d,d,d") - (plus:SI (match_operand:SI 1 "general_operand" "%d,K,m") - (match_operand:SI 2 "register_operand" "0,0,0"))) +(define_insn "*la_31" + [(set (match_operand:SI 0 "register_operand" "=d") + (match_operand:QI 1 "address_operand" "p"))] + "!TARGET_64BIT && legitimate_la_operand_p (operands[1])" + "la\\t%0,%a1" + [(set_attr "op_type" "RX") + (set_attr "atype" "mem") + (set_attr "type" "la")]) + +(define_peephole2 + [(parallel + [(set (match_operand:SI 0 "register_operand" "") + (match_operand:QI 1 "address_operand" "")) + (clobber (reg:CC 33))])] + "!TARGET_64BIT + && strict_memory_address_p (VOIDmode, operands[1]) + && preferred_la_operand_p (operands[1])" + [(set (match_dup 0) (match_dup 1))] + "") + +(define_peephole2 + [(set (match_operand:SI 0 "register_operand" "") + (match_operand:SI 1 "register_operand" "")) + (parallel + [(set (match_dup 0) + (plus:SI (match_dup 0) + (match_operand:SI 2 "nonmemory_operand" ""))) + (clobber (reg:CC 33))])] + "!TARGET_64BIT + && !reg_overlap_mentioned_p (operands[0], operands[2]) + && strict_memory_address_p (VOIDmode, gen_rtx_PLUS (SImode, operands[1], operands[2])) + && preferred_la_operand_p (gen_rtx_PLUS (SImode, operands[1], operands[2]))" + [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))] + "") + +(define_insn "*la_31_and" + [(set (match_operand:SI 0 "register_operand" "=d") + (and:SI (match_operand:QI 1 "address_operand" "p") + (const_int 2147483647)))] + "!TARGET_64BIT" + "la\\t%0,%a1" + [(set_attr "op_type" "RX") + (set_attr "atype" "mem") + (set_attr "type" "la")]) + +(define_insn_and_split "*la_31_and_cc" + [(set (match_operand:SI 0 "register_operand" "=d") + (and:SI (match_operand:QI 1 "address_operand" "p") + (const_int 2147483647))) (clobber (reg:CC 33))] + "!TARGET_64BIT" + "#" + "&& reload_completed" + [(set (match_dup 0) + (and:SI (match_dup 1) (const_int 2147483647)))] "" - "@ - ar\\t%0,%1 - ahi\\t%0,%h1 - a\\t%0,%1" - [(set_attr "op_type" "RR,RI,RX") - (set_attr "atype" "reg,reg,mem")]) + [(set_attr "op_type" "RX") + (set_attr "atype" "mem") + (set_attr "type" "la")]) -(define_insn "*la_31" +(define_insn "force_la_31" [(set (match_operand:SI 0 "register_operand" "=d") - (match_operand:QI 1 "address_operand" "p"))] - "legitimate_la_operand_p (operands[1])" + (match_operand:QI 1 "address_operand" "p")) + (use (const_int 0))] + "!TARGET_64BIT" "la\\t%0,%a1" [(set_attr "op_type" "RX") (set_attr "atype" "mem") @@ -3248,7 +3331,7 @@ (define_expand "reload_insi" [(parallel [(match_operand:SI 0 "register_operand" "=a") (match_operand:SI 1 "s390_plus_operand" "") - (match_operand:DI 2 "register_operand" "=&a")])] + (match_operand:SI 2 "register_operand" "=&a")])] "!TARGET_64BIT" " { @@ -3258,48 +3341,13 @@ ; -; addhi3 instruction pattern(s). -; - -(define_insn "addhi3" - [(set (match_operand:HI 0 "register_operand" "=d,d,d") - (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0") - (match_operand:HI 2 "general_operand" "d,K,m"))) - (clobber (reg:CC 33))] - "" - "@ - ar\\t%0,%2 - ahi\\t%0,%h2 - ah\\t%0,%2" - [(set_attr "op_type" "RR,RI,RX") - (set_attr "atype" "reg,reg,mem")]) - - -; -; addqi3 instruction pattern(s). -; - -(define_insn "addqi3" - [(set (match_operand:QI 0 "register_operand" "=d,d") - (plus:QI (match_operand:QI 1 "register_operand" "%0,0") - (match_operand:QI 2 "general_operand" "a,n"))) - (clobber (reg:CC 33))] - "" - "@ - ar\\t%0,%2 - ahi\\t%0,%h2" - [(set_attr "op_type" "RX,RX") - (set_attr "atype" "reg,mem")]) - - -; ; adddf3 instruction pattern(s). ; (define_expand "adddf3" [(parallel [(set (match_operand:DF 0 "register_operand" "=f,f") - (plus:DF (match_operand:DF 1 "register_operand" "%0,0") + (plus:DF (match_operand:DF 1 "nonimmediate_operand" "%0,0") (match_operand:DF 2 "general_operand" "f,m"))) (clobber (reg:CC 33))])] "TARGET_HARD_FLOAT" @@ -3307,7 +3355,7 @@ (define_insn "*adddf3" [(set (match_operand:DF 0 "register_operand" "=f,f") - (plus:DF (match_operand:DF 1 "register_operand" "%0,0") + (plus:DF (match_operand:DF 1 "nonimmediate_operand" "%0,0") (match_operand:DF 2 "general_operand" "f,m"))) (clobber (reg:CC 33))] "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" @@ -3319,7 +3367,7 @@ (define_insn "*adddf3_ibm" [(set (match_operand:DF 0 "register_operand" "=f,f") - (plus:DF (match_operand:DF 1 "register_operand" "%0,0") + (plus:DF (match_operand:DF 1 "nonimmediate_operand" "%0,0") (match_operand:DF 2 "general_operand" "f,m"))) (clobber (reg:CC 33))] "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" @@ -3336,7 +3384,7 @@ (define_expand "addsf3" [(parallel [(set (match_operand:SF 0 "register_operand" "=f,f") - (plus:SF (match_operand:SF 1 "register_operand" "%0,0") + (plus:SF (match_operand:SF 1 "nonimmediate_operand" "%0,0") (match_operand:SF 2 "general_operand" "f,m"))) (clobber (reg:CC 33))])] "TARGET_HARD_FLOAT" @@ -3344,7 +3392,7 @@ (define_insn "*addsf3" [(set (match_operand:SF 0 "register_operand" "=f,f") - (plus:SF (match_operand:SF 1 "register_operand" "%0,0") + (plus:SF (match_operand:SF 1 "nonimmediate_operand" "%0,0") (match_operand:SF 2 "general_operand" "f,m"))) (clobber (reg:CC 33))] "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" @@ -3356,7 +3404,7 @@ (define_insn "*addsf3" [(set (match_operand:SF 0 "register_operand" "=f,f") - (plus:SF (match_operand:SF 1 "register_operand" "%0,0") + (plus:SF (match_operand:SF 1 "nonimmediate_operand" "%0,0") (match_operand:SF 2 "general_operand" "f,m"))) (clobber (reg:CC 33))] "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" @@ -3375,6 +3423,84 @@ ; subdi3 instruction pattern(s). ; +(define_insn "*subdi3_sign" + [(set (match_operand:DI 0 "register_operand" "=d,d") + (minus:DI (match_operand:DI 1 "register_operand" "0,0") + (sign_extend:DI (match_operand:SI 2 "general_operand" "d,m")))) + (clobber (reg:CC 33))] + "TARGET_64BIT" + "@ + sgfr\\t%0,%2 + sgf\\t%0,%2" + [(set_attr "op_type" "RRE,RXE") + (set_attr "atype" "reg,mem")]) + +(define_insn "*subdi3_zero_cc" + [(set (reg 33) + (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0") + (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m"))) + (const_int 0))) + (set (match_operand:DI 0 "register_operand" "=d,d") + (minus:DI (match_dup 1) (zero_extend:DI (match_dup 2))))] + "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT" + "@ + slgfr\\t%0,%2 + slgf\\t%0,%2" + [(set_attr "op_type" "RRE,RXE") + (set_attr "atype" "reg,mem")]) + +(define_insn "*subdi3_zero_cconly" + [(set (reg 33) + (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0") + (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m"))) + (const_int 0))) + (clobber (match_scratch:DI 0 "=d,d"))] + "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT" + "@ + slgfr\\t%0,%2 + slgf\\t%0,%2" + [(set_attr "op_type" "RRE,RXE") + (set_attr "atype" "reg,mem")]) + +(define_insn "*subdi3_zero" + [(set (match_operand:DI 0 "register_operand" "=d,d") + (minus:DI (match_operand:DI 1 "register_operand" "0,0") + (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m")))) + (clobber (reg:CC 33))] + "TARGET_64BIT" + "@ + slgfr\\t%0,%2 + slgf\\t%0,%2" + [(set_attr "op_type" "RRE,RXE") + (set_attr "atype" "reg,mem")]) + +(define_insn "*subdi3_cc" + [(set (reg 33) + (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0") + (match_operand:DI 2 "general_operand" "d,m")) + (const_int 0))) + (set (match_operand:DI 0 "register_operand" "=d,d") + (minus:DI (match_dup 1) (match_dup 2)))] + "s390_match_ccmode (insn, CCLmode)" + "@ + slgr\\t%0,%2 + slg\\t%0,%2" + [(set_attr "op_type" "RRE,RXE") + (set_attr "atype" "reg,mem")]) + +(define_insn "*subdi3_cconly" + [(set (reg 33) + (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0") + (match_operand:DI 2 "general_operand" "d,m")) + (const_int 0))) + (clobber (match_scratch:DI 0 "=d,d"))] + "s390_match_ccmode (insn, CCLmode)" + "@ + slgr\\t%0,%2 + slg\\t%0,%2" + [(set_attr "op_type" "RRE,RXE") + (set_attr "atype" "reg,mem")]) + (define_insn "*subdi3_64" [(set (match_operand:DI 0 "register_operand" "=d,d") (minus:DI (match_operand:DI 1 "register_operand" "0,0") @@ -3387,41 +3513,79 @@ [(set_attr "op_type" "RRE,RRE") (set_attr "atype" "reg,mem")]) -(define_insn "subdi3" - [(set (match_operand:DI 0 "register_operand" "=d,d") - (minus:DI (match_operand:DI 1 "register_operand" "0,0") - (match_operand:DI 2 "general_operand" "d,m"))) +(define_insn_and_split "*subdi3_31" + [(set (match_operand:DI 0 "register_operand" "=&d") + (minus:DI (match_operand:DI 1 "register_operand" "0") + (match_operand:DI 2 "general_operand" "do") ) ) (clobber (reg:CC 33))] + "!TARGET_64BIT" + "#" + "&& reload_completed" + [(parallel + [(set (match_dup 3) (minus:SI (match_dup 4) (match_dup 5))) + (clobber (reg:CC 33))]) + (parallel + [(set (reg:CCL2 33) + (compare:CCL2 (minus:SI (match_dup 7) (match_dup 8)) + (match_dup 7))) + (set (match_dup 6) (minus:SI (match_dup 7) (match_dup 8)))]) + (set (pc) + (if_then_else (gtu (reg:CCL2 33) (const_int 0)) + (pc) + (label_ref (match_dup 9)))) + (parallel + [(set (match_dup 3) (plus:SI (match_dup 3) (const_int -1))) + (clobber (reg:CC 33))]) + (match_dup 9)] + "operands[3] = operand_subword (operands[0], 0, 0, DImode); + operands[4] = operand_subword (operands[1], 0, 0, DImode); + operands[5] = operand_subword (operands[2], 0, 0, DImode); + operands[6] = operand_subword (operands[0], 1, 0, DImode); + operands[7] = operand_subword (operands[1], 1, 0, DImode); + operands[8] = operand_subword (operands[2], 1, 0, DImode); + operands[9] = gen_label_rtx ();" + [(set_attr "op_type" "NN")]) + +(define_expand "subdi3" + [(parallel + [(set (match_operand:DI 0 "register_operand" "") + (minus:DI (match_operand:DI 1 "register_operand" "") + (match_operand:DI 2 "general_operand" ""))) + (clobber (reg:CC 33))])] "" - "* -{ - switch (which_alternative) - { - case 0: /* d <- d */ - output_asm_insn (\"sr\\t%0,%2\", operands); - output_asm_insn (\"slr\\t%N0,%N2\", operands); - break; - case 1: /* d <- m */ - output_asm_insn (\"s\\t%0,%2\", operands); - output_asm_insn (\"sl\\t%N0,%N2\", operands); - break; - - default: - abort (); - } - - output_asm_insn (\"brc\\t11,.+8\", operands); - return \"ahi\\t%0,-1\"; -}" - [(set_attr "op_type" "NN,NN") - (set_attr "atype" "reg,mem") - (set_attr "type" "other,other") - (set_attr "length" "12,16")]) + "") ; ; subsi3 instruction pattern(s). ; +(define_insn "*subsi3_borrow_cc" + [(set (reg 33) + (compare (minus:SI (match_operand:SI 1 "register_operand" "0,0") + (match_operand:SI 2 "general_operand" "d,m")) + (match_dup 1))) + (set (match_operand:SI 0 "register_operand" "=d,d") + (minus:SI (match_dup 1) (match_dup 2)))] + "s390_match_ccmode(insn, CCL2mode)" + "@ + slr\\t%0,%2 + sl\\t%0,%2" + [(set_attr "op_type" "RR,RX") + (set_attr "atype" "reg,mem")]) + +(define_insn "*subsi3_borrow_cconly" + [(set (reg 33) + (compare (minus:SI (match_operand:SI 1 "register_operand" "0,0") + (match_operand:SI 2 "general_operand" "d,m")) + (match_dup 1))) + (clobber (match_scratch:SI 0 "=d,d"))] + "s390_match_ccmode(insn, CCL2mode)" + "@ + slr\\t%0,%2 + sl\\t%0,%2" + [(set_attr "op_type" "RR,RX") + (set_attr "atype" "reg,mem")]) + (define_insn "*subsi3_cc" [(set (reg 33) (compare (minus:SI (match_operand:SI 1 "register_operand" "0,0") @@ -3449,6 +3613,26 @@ [(set_attr "op_type" "RR,RX") (set_attr "atype" "reg,mem")]) +(define_insn "*subsi3_sign" + [(set (match_operand:SI 0 "register_operand" "=d") + (minus:SI (match_operand:SI 1 "register_operand" "0") + (sign_extend:SI (match_operand:HI 2 "memory_operand" "m")))) + (clobber (reg:CC 33))] + "" + "sh\\t%0,%2" + [(set_attr "op_type" "RX") + (set_attr "atype" "mem")]) + +(define_insn "*subsi3_sub" + [(set (match_operand:SI 0 "register_operand" "=d") + (minus:SI (match_operand:SI 1 "register_operand" "0") + (subreg:SI (match_operand:HI 2 "memory_operand" "m") 0))) + (clobber (reg:CC 33))] + "" + "sh\\t%0,%2" + [(set_attr "op_type" "RX") + (set_attr "atype" "mem")]) + (define_insn "subsi3" [(set (match_operand:SI 0 "register_operand" "=d,d") (minus:SI (match_operand:SI 1 "register_operand" "0,0") @@ -3461,34 +3645,6 @@ [(set_attr "op_type" "RR,RX") (set_attr "atype" "reg,mem")]) -; -; subhi3 instruction pattern(s). -; - -(define_insn "subhi3" - [(set (match_operand:HI 0 "register_operand" "=d,d") - (minus:HI (match_operand:HI 1 "register_operand" "0,0") - (match_operand:HI 2 "general_operand" "d,m"))) - (clobber (reg:CC 33))] - "" - "@ - sr\\t%0,%2 - sh\\t%0,%2" - [(set_attr "op_type" "RR,RX") - (set_attr "atype" "reg,mem")]) - -; -; subqi3 instruction pattern(s). -; - -(define_insn "subqi3" - [(set (match_operand:QI 0 "register_operand" "=d") - (minus:QI (match_operand:QI 1 "register_operand" "0") - (match_operand:QI 2 "register_operand" "d"))) - (clobber (reg:CC 33))] - "" - "sr\\t%0,%2" - [(set_attr "op_type" "RR")]) ; ; subdf3 instruction pattern(s). @@ -3573,17 +3729,29 @@ ; muldi3 instruction pattern(s). ; +(define_insn "*muldi3_sign" + [(set (match_operand:DI 0 "register_operand" "=d,d") + (mult:DI (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "d,m")) + (match_operand:DI 1 "register_operand" "0,0")))] + "TARGET_64BIT" + "@ + msgfr\\t%0,%2 + msgf\\t%0,%2" + [(set_attr "op_type" "RRE,RXE") + (set_attr "atype" "reg,mem") + (set_attr "type" "imul")]) + + (define_insn "muldi3" [(set (match_operand:DI 0 "register_operand" "=d,d,d") - (mult:DI (match_operand:DI 1 "register_operand" "%0,0,0") - (match_operand:DI 2 "general_operand" "d,K,m"))) - (clobber (reg:CC 33))] + (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0") + (match_operand:DI 2 "general_operand" "d,K,m")))] "TARGET_64BIT" "@ msgr\\t%0,%2 mghi\\t%0,%h2 msg\\t%0,%2" - [(set_attr "op_type" "RRE,RI,RX") + [(set_attr "op_type" "RRE,RI,RXE") (set_attr "atype" "reg,reg,mem") (set_attr "type" "imul")]) @@ -3593,9 +3761,8 @@ (define_insn "mulsi3" [(set (match_operand:SI 0 "register_operand" "=d,d,d") - (mult:SI (match_operand:SI 1 "register_operand" "%0,0,0") - (match_operand:SI 2 "general_operand" "d,K,m"))) - (clobber (reg:CC 33))] + (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0") + (match_operand:SI 2 "general_operand" "d,K,m")))] "" "@ msr\\t%0,%2 @@ -3611,7 +3778,7 @@ (define_expand "mulsidi3" [(set (match_operand:DI 0 "register_operand" "") - (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "")) + (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")) (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" ""))))] "!TARGET_64BIT" " @@ -3635,8 +3802,7 @@ (mult:DI (sign_extend:DI (truncate:SI (match_operand:DI 1 "register_operand" "0,0"))) (sign_extend:DI - (match_operand:SI 2 "nonimmediate_operand" "d,m")))) - (clobber (reg:CC 33))] + (match_operand:SI 2 "nonimmediate_operand" "d,m"))))] "!TARGET_64BIT" "@ mr\\t%0,%2 @@ -3652,7 +3818,7 @@ (define_expand "muldf3" [(parallel [(set (match_operand:DF 0 "register_operand" "=f,f") - (mult:DF (match_operand:DF 1 "register_operand" "%0,0") + (mult:DF (match_operand:DF 1 "nonimmediate_operand" "%0,0") (match_operand:DF 2 "general_operand" "f,m"))) (clobber (reg:CC 33))])] "TARGET_HARD_FLOAT" @@ -3660,7 +3826,7 @@ (define_insn "*muldf3" [(set (match_operand:DF 0 "register_operand" "=f,f") - (mult:DF (match_operand:DF 1 "register_operand" "%0,0") + (mult:DF (match_operand:DF 1 "nonimmediate_operand" "%0,0") (match_operand:DF 2 "general_operand" "f,m"))) (clobber (reg:CC 33))] "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" @@ -3673,7 +3839,7 @@ (define_insn "*muldf3_ibm" [(set (match_operand:DF 0 "register_operand" "=f,f") - (mult:DF (match_operand:DF 1 "register_operand" "%0,0") + (mult:DF (match_operand:DF 1 "nonimmediate_operand" "%0,0") (match_operand:DF 2 "general_operand" "f,m"))) (clobber (reg:CC 33))] "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" @@ -3691,7 +3857,7 @@ (define_expand "mulsf3" [(parallel [(set (match_operand:SF 0 "register_operand" "=f,f") - (mult:SF (match_operand:SF 1 "register_operand" "%0,0") + (mult:SF (match_operand:SF 1 "nonimmediate_operand" "%0,0") (match_operand:SF 2 "general_operand" "f,m"))) (clobber (reg:CC 33))])] "TARGET_HARD_FLOAT" @@ -3699,7 +3865,7 @@ (define_insn "*mulsf3" [(set (match_operand:SF 0 "register_operand" "=f,f") - (mult:SF (match_operand:SF 1 "register_operand" "%0,0") + (mult:SF (match_operand:SF 1 "nonimmediate_operand" "%0,0") (match_operand:SF 2 "general_operand" "f,m"))) (clobber (reg:CC 33))] "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" @@ -3712,7 +3878,7 @@ (define_insn "*mulsf3_ibm" [(set (match_operand:SF 0 "register_operand" "=f,f") - (mult:SF (match_operand:SF 1 "register_operand" "%0,0") + (mult:SF (match_operand:SF 1 "nonimmediate_operand" "%0,0") (match_operand:SF 2 "general_operand" "f,m"))) (clobber (reg:CC 33))] "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" @@ -4211,7 +4377,7 @@ (define_insn "*anddi3_cc" [(set (reg 33) - (compare (and:DI (match_operand:DI 1 "register_operand" "%0,0") + (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") (match_operand:DI 2 "general_operand" "d,m")) (const_int 0))) (set (match_operand:DI 0 "register_operand" "=d,d") @@ -4225,7 +4391,7 @@ (define_insn "*anddi3_cconly" [(set (reg 33) - (compare (and:DI (match_operand:DI 1 "register_operand" "%0,0") + (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") (match_operand:DI 2 "general_operand" "d,m")) (const_int 0))) (clobber (match_scratch:DI 0 "=d,d"))] @@ -4238,7 +4404,7 @@ (define_insn "*anddi3_ni" [(set (match_operand:DI 0 "register_operand" "=d") - (and:DI (match_operand:DI 1 "register_operand" "%0") + (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" @@ -4261,7 +4427,7 @@ (define_insn "anddi3" [(set (match_operand:DI 0 "register_operand" "=d,d") - (and:DI (match_operand:DI 1 "register_operand" "%0,0") + (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") (match_operand:DI 2 "general_operand" "d,m"))) (clobber (reg:CC 33))] "TARGET_64BIT" @@ -4272,9 +4438,9 @@ (set_attr "atype" "reg,mem")]) (define_insn "*anddi3_ss" - [(set (match_operand:DI 0 "s_operand" "=Qo") + [(set (match_operand:DI 0 "s_operand" "=Q") (and:DI (match_dup 0) - (match_operand:DI 1 "s_imm_operand" "Qo"))) + (match_operand:DI 1 "s_imm_operand" "Q"))) (clobber (reg:CC 33))] "" "nc\\t%O0(8,%R0),%1" @@ -4282,8 +4448,8 @@ (set_attr "atype" "mem")]) (define_insn "*anddi3_ss_inv" - [(set (match_operand:DI 0 "s_operand" "=Qo") - (and:DI (match_operand:DI 1 "s_imm_operand" "Qo") + [(set (match_operand:DI 0 "s_operand" "=Q") + (and:DI (match_operand:DI 1 "s_imm_operand" "Q") (match_dup 0))) (clobber (reg:CC 33))] "" @@ -4297,7 +4463,7 @@ (define_insn "*andsi3_cc" [(set (reg 33) - (compare (and:SI (match_operand:SI 1 "register_operand" "%0,0") + (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") (match_operand:SI 2 "general_operand" "d,m")) (const_int 0))) (set (match_operand:SI 0 "register_operand" "=d,d") @@ -4311,7 +4477,7 @@ (define_insn "*andsi3_cconly" [(set (reg 33) - (compare (and:SI (match_operand:SI 1 "register_operand" "%0,0") + (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") (match_operand:SI 2 "general_operand" "d,m")) (const_int 0))) (clobber (match_scratch:SI 0 "=d,d"))] @@ -4324,7 +4490,7 @@ (define_insn "*andsi3_ni" [(set (match_operand:SI 0 "register_operand" "=d") - (and:SI (match_operand:SI 1 "register_operand" "%0") + (and:SI (match_operand:SI 1 "nonimmediate_operand" "0") (match_operand:SI 2 "immediate_operand" "n"))) (clobber (reg:CC 33))] "TARGET_64BIT && s390_single_hi (operands[2], SImode, -1) >= 0" @@ -4345,7 +4511,7 @@ (define_insn "andsi3" [(set (match_operand:SI 0 "register_operand" "=d,d") - (and:SI (match_operand:SI 1 "register_operand" "%0,0") + (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") (match_operand:SI 2 "general_operand" "d,m"))) (clobber (reg:CC 33))] "" @@ -4356,9 +4522,9 @@ (set_attr "atype" "reg,mem")]) (define_insn "*andsi3_ss" - [(set (match_operand:SI 0 "s_operand" "=Qo") + [(set (match_operand:SI 0 "s_operand" "=Q") (and:SI (match_dup 0) - (match_operand:SI 1 "s_imm_operand" "Qo"))) + (match_operand:SI 1 "s_imm_operand" "Q"))) (clobber (reg:CC 33))] "" "nc\\t%O0(4,%R0),%1" @@ -4366,8 +4532,8 @@ (set_attr "atype" "mem")]) (define_insn "*andsi3_ss_inv" - [(set (match_operand:SI 0 "s_operand" "=Qo") - (and:SI (match_operand:SI 1 "s_imm_operand" "Qo") + [(set (match_operand:SI 0 "s_operand" "=Q") + (and:SI (match_operand:SI 1 "s_imm_operand" "Q") (match_dup 0))) (clobber (reg:CC 33))] "" @@ -4402,9 +4568,9 @@ (set_attr "atype" "reg")]) (define_insn "*andhi3_ss" - [(set (match_operand:HI 0 "s_operand" "=Qo") + [(set (match_operand:HI 0 "s_operand" "=Q") (and:HI (match_dup 0) - (match_operand:HI 1 "s_imm_operand" "Qo"))) + (match_operand:HI 1 "s_imm_operand" "Q"))) (clobber (reg:CC 33))] "" "nc\\t%O0(2,%R0),%1" @@ -4412,8 +4578,8 @@ (set_attr "atype" "mem")]) (define_insn "*andhi3_ss_inv" - [(set (match_operand:HI 0 "s_operand" "=Qo") - (and:HI (match_operand:HI 1 "s_imm_operand" "Qo") + [(set (match_operand:HI 0 "s_operand" "=Q") + (and:HI (match_operand:HI 1 "s_imm_operand" "Q") (match_dup 0))) (clobber (reg:CC 33))] "" @@ -4448,9 +4614,9 @@ (set_attr "atype" "reg")]) (define_insn "*andqi3_ss" - [(set (match_operand:QI 0 "s_operand" "=Qo,Qo") + [(set (match_operand:QI 0 "s_operand" "=Q,Q") (and:QI (match_dup 0) - (match_operand:QI 1 "s_imm_operand" "n,Qo"))) + (match_operand:QI 1 "s_imm_operand" "n,Q"))) (clobber (reg:CC 33))] "" "@ @@ -4460,8 +4626,8 @@ (set_attr "atype" "mem")]) (define_insn "*andqi3_ss_inv" - [(set (match_operand:QI 0 "s_operand" "=Qo,Qo") - (and:QI (match_operand:QI 1 "s_imm_operand" "n,Qo") + [(set (match_operand:QI 0 "s_operand" "=Q,Q") + (and:QI (match_operand:QI 1 "s_imm_operand" "n,Q") (match_dup 0))) (clobber (reg:CC 33))] "" @@ -4482,7 +4648,7 @@ (define_insn "*iordi3_cc" [(set (reg 33) - (compare (ior:DI (match_operand:DI 1 "register_operand" "%0,0") + (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") (match_operand:DI 2 "general_operand" "d,m")) (const_int 0))) (set (match_operand:DI 0 "register_operand" "=d,d") @@ -4496,7 +4662,7 @@ (define_insn "*iordi3_cconly" [(set (reg 33) - (compare (ior:DI (match_operand:DI 1 "register_operand" "%0,0") + (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") (match_operand:DI 2 "general_operand" "d,m")) (const_int 0))) (clobber (match_scratch:DI 0 "=d,d"))] @@ -4509,7 +4675,7 @@ (define_insn "*iordi3_oi" [(set (match_operand:DI 0 "register_operand" "=d") - (ior:DI (match_operand:DI 1 "register_operand" "%0") + (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" @@ -4532,7 +4698,7 @@ (define_insn "iordi3" [(set (match_operand:DI 0 "register_operand" "=d,d") - (ior:DI (match_operand:DI 1 "register_operand" "%0,0") + (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") (match_operand:DI 2 "general_operand" "d,m"))) (clobber (reg:CC 33))] "TARGET_64BIT" @@ -4543,9 +4709,9 @@ (set_attr "atype" "reg,mem")]) (define_insn "*iordi3_ss" - [(set (match_operand:DI 0 "s_operand" "=Qo") + [(set (match_operand:DI 0 "s_operand" "=Q") (ior:DI (match_dup 0) - (match_operand:DI 1 "s_imm_operand" "Qo"))) + (match_operand:DI 1 "s_imm_operand" "Q"))) (clobber (reg:CC 33))] "" "oc\\t%O0(8,%R0),%1" @@ -4553,8 +4719,8 @@ (set_attr "atype" "mem")]) (define_insn "*iordi3_ss_inv" - [(set (match_operand:DI 0 "s_operand" "=Qo") - (ior:DI (match_operand:DI 1 "s_imm_operand" "Qo") + [(set (match_operand:DI 0 "s_operand" "=Q") + (ior:DI (match_operand:DI 1 "s_imm_operand" "Q") (match_dup 0))) (clobber (reg:CC 33))] "" @@ -4568,7 +4734,7 @@ (define_insn "*iorsi3_cc" [(set (reg 33) - (compare (ior:SI (match_operand:SI 1 "register_operand" "%0,0") + (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") (match_operand:SI 2 "general_operand" "d,m")) (const_int 0))) (set (match_operand:SI 0 "register_operand" "=d,d") @@ -4582,7 +4748,7 @@ (define_insn "*iorsi3_cconly" [(set (reg 33) - (compare (ior:SI (match_operand:SI 1 "register_operand" "%0,0") + (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") (match_operand:SI 2 "general_operand" "d,m")) (const_int 0))) (clobber (match_scratch:SI 0 "=d,d"))] @@ -4595,7 +4761,7 @@ (define_insn "*iorsi3_oi" [(set (match_operand:SI 0 "register_operand" "=d") - (ior:SI (match_operand:SI 1 "register_operand" "%0") + (ior:SI (match_operand:SI 1 "nonimmediate_operand" "0") (match_operand:SI 2 "immediate_operand" "n"))) (clobber (reg:CC 33))] "TARGET_64BIT && s390_single_hi (operands[2], SImode, 0) >= 0" @@ -4616,7 +4782,7 @@ (define_insn "iorsi3" [(set (match_operand:SI 0 "register_operand" "=d,d") - (ior:SI (match_operand:SI 1 "register_operand" "%0,0") + (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") (match_operand:SI 2 "general_operand" "d,m"))) (clobber (reg:CC 33))] "" @@ -4627,9 +4793,9 @@ (set_attr "atype" "reg,mem")]) (define_insn "*iorsi3_ss" - [(set (match_operand:SI 0 "s_operand" "=Qo") + [(set (match_operand:SI 0 "s_operand" "=Q") (ior:SI (match_dup 0) - (match_operand:SI 1 "s_imm_operand" "Qo"))) + (match_operand:SI 1 "s_imm_operand" "Q"))) (clobber (reg:CC 33))] "" "oc\\t%O0(4,%R0),%1" @@ -4637,8 +4803,8 @@ (set_attr "atype" "mem")]) (define_insn "*iorsi3_ss_inv" - [(set (match_operand:SI 0 "s_operand" "=Qo") - (ior:SI (match_operand:SI 1 "s_imm_operand" "Qo") + [(set (match_operand:SI 0 "s_operand" "=Q") + (ior:SI (match_operand:SI 1 "s_imm_operand" "Q") (match_dup 0))) (clobber (reg:CC 33))] "" @@ -4673,9 +4839,9 @@ (set_attr "atype" "reg")]) (define_insn "*iorhi3_ss" - [(set (match_operand:HI 0 "s_operand" "=Qo") + [(set (match_operand:HI 0 "s_operand" "=Q") (ior:HI (match_dup 0) - (match_operand:HI 1 "s_imm_operand" "Qo"))) + (match_operand:HI 1 "s_imm_operand" "Q"))) (clobber (reg:CC 33))] "" "oc\\t%O0(2,%R0),%1" @@ -4683,8 +4849,8 @@ (set_attr "atype" "mem")]) (define_insn "*iorhi3_ss_inv" - [(set (match_operand:HI 0 "s_operand" "=Qo") - (ior:HI (match_operand:HI 1 "s_imm_operand" "Qo") + [(set (match_operand:HI 0 "s_operand" "=Q") + (ior:HI (match_operand:HI 1 "s_imm_operand" "Q") (match_dup 0))) (clobber (reg:CC 33))] "" @@ -4719,9 +4885,9 @@ (set_attr "atype" "reg")]) (define_insn "*iorqi3_ss" - [(set (match_operand:QI 0 "s_operand" "=Qo,Qo") + [(set (match_operand:QI 0 "s_operand" "=Q,Q") (ior:QI (match_dup 0) - (match_operand:QI 1 "s_imm_operand" "n,Qo"))) + (match_operand:QI 1 "s_imm_operand" "n,Q"))) (clobber (reg:CC 33))] "" "@ @@ -4731,8 +4897,8 @@ (set_attr "atype" "reg,mem")]) (define_insn "*iorqi3_ss_inv" - [(set (match_operand:QI 0 "s_operand" "=Qo,Qo") - (ior:QI (match_operand:QI 1 "s_imm_operand" "n,Qo") + [(set (match_operand:QI 0 "s_operand" "=Q,Q") + (ior:QI (match_operand:QI 1 "s_imm_operand" "n,Q") (match_dup 0))) (clobber (reg:CC 33))] "" @@ -4753,7 +4919,7 @@ (define_insn "*xordi3_cc" [(set (reg 33) - (compare (xor:DI (match_operand:DI 1 "register_operand" "%0,0") + (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") (match_operand:DI 2 "general_operand" "d,m")) (const_int 0))) (set (match_operand:DI 0 "register_operand" "=d,d") @@ -4767,7 +4933,7 @@ (define_insn "*xordi3_cconly" [(set (reg 33) - (compare (xor:DI (match_operand:DI 1 "register_operand" "%0,0") + (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") (match_operand:DI 2 "general_operand" "d,m")) (const_int 0))) (clobber (match_scratch:DI 0 "=d,d"))] @@ -4780,7 +4946,7 @@ (define_insn "xordi3" [(set (match_operand:DI 0 "register_operand" "=d,d") - (xor:DI (match_operand:DI 1 "register_operand" "%0,0") + (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") (match_operand:DI 2 "general_operand" "d,m"))) (clobber (reg:CC 33))] "TARGET_64BIT" @@ -4791,9 +4957,9 @@ (set_attr "atype" "reg,mem")]) (define_insn "*xordi3_ss" - [(set (match_operand:DI 0 "s_operand" "=Qo") + [(set (match_operand:DI 0 "s_operand" "=Q") (xor:DI (match_dup 0) - (match_operand:DI 1 "s_imm_operand" "Qo"))) + (match_operand:DI 1 "s_imm_operand" "Q"))) (clobber (reg:CC 33))] "" "xc\\t%O0(8,%R0),%1" @@ -4801,8 +4967,8 @@ (set_attr "atype" "mem")]) (define_insn "*xordi3_ss_inv" - [(set (match_operand:DI 0 "s_operand" "=Qo") - (xor:DI (match_operand:DI 1 "s_imm_operand" "Qo") + [(set (match_operand:DI 0 "s_operand" "=Q") + (xor:DI (match_operand:DI 1 "s_imm_operand" "Q") (match_dup 0))) (clobber (reg:CC 33))] "" @@ -4816,7 +4982,7 @@ (define_insn "*xorsi3_cc" [(set (reg 33) - (compare (xor:SI (match_operand:SI 1 "register_operand" "%0,0") + (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") (match_operand:SI 2 "general_operand" "d,m")) (const_int 0))) (set (match_operand:SI 0 "register_operand" "=d,d") @@ -4830,7 +4996,7 @@ (define_insn "*xorsi3_cconly" [(set (reg 33) - (compare (xor:SI (match_operand:SI 1 "register_operand" "%0,0") + (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") (match_operand:SI 2 "general_operand" "d,m")) (const_int 0))) (clobber (match_scratch:SI 0 "=d,d"))] @@ -4843,7 +5009,7 @@ (define_insn "xorsi3" [(set (match_operand:SI 0 "register_operand" "=d,d") - (xor:SI (match_operand:SI 1 "register_operand" "%0,0") + (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") (match_operand:SI 2 "general_operand" "d,m"))) (clobber (reg:CC 33))] "" @@ -4854,9 +5020,9 @@ (set_attr "atype" "reg,mem")]) (define_insn "*xorsi3_ss" - [(set (match_operand:SI 0 "s_operand" "=Qo") + [(set (match_operand:SI 0 "s_operand" "=Q") (xor:SI (match_dup 0) - (match_operand:SI 1 "s_imm_operand" "Qo"))) + (match_operand:SI 1 "s_imm_operand" "Q"))) (clobber (reg:CC 33))] "" "xc\\t%O0(4,%R0),%1" @@ -4864,8 +5030,8 @@ (set_attr "atype" "mem")]) (define_insn "*xorsi3_ss_inv" - [(set (match_operand:SI 0 "s_operand" "=Qo") - (xor:SI (match_operand:SI 1 "s_imm_operand" "Qo") + [(set (match_operand:SI 0 "s_operand" "=Q") + (xor:SI (match_operand:SI 1 "s_imm_operand" "Q") (match_dup 0))) (clobber (reg:CC 33))] "" @@ -4888,9 +5054,9 @@ (set_attr "atype" "reg")]) (define_insn "*xorhi3_ss" - [(set (match_operand:HI 0 "s_operand" "=Qo") + [(set (match_operand:HI 0 "s_operand" "=Q") (xor:HI (match_dup 0) - (match_operand:HI 1 "s_imm_operand" "Qo"))) + (match_operand:HI 1 "s_imm_operand" "Q"))) (clobber (reg:CC 33))] "" "xc\\t%O0(2,%R0),%1" @@ -4898,8 +5064,8 @@ (set_attr "atype" "mem")]) (define_insn "*xorhi3_ss_inv" - [(set (match_operand:HI 0 "s_operand" "=Qo") - (xor:HI (match_operand:HI 1 "s_imm_operand" "Qo") + [(set (match_operand:HI 0 "s_operand" "=Q") + (xor:HI (match_operand:HI 1 "s_imm_operand" "Q") (match_dup 0))) (clobber (reg:CC 33))] "" @@ -4922,9 +5088,9 @@ (set_attr "atype" "reg")]) (define_insn "*xorqi3_ss" - [(set (match_operand:QI 0 "s_operand" "=Qo,Qo") + [(set (match_operand:QI 0 "s_operand" "=Q,Q") (xor:QI (match_dup 0) - (match_operand:QI 1 "s_imm_operand" "n,Qo"))) + (match_operand:QI 1 "s_imm_operand" "n,Q"))) (clobber (reg:CC 33))] "" "@ @@ -4934,8 +5100,8 @@ (set_attr "atype" "mem")]) (define_insn "*xorqi3_ss_inv" - [(set (match_operand:QI 0 "s_operand" "=Qo,Qo") - (xor:QI (match_operand:QI 1 "s_imm_operand" "n,Qo") + [(set (match_operand:QI 0 "s_operand" "=Q,Q") + (xor:QI (match_operand:QI 1 "s_imm_operand" "n,Q") (match_dup 0))) (clobber (reg:CC 33))] "" @@ -5682,9 +5848,6 @@ (const_int 4) (ne (symbol_ref "TARGET_64BIT") (const_int 0)) (const_int 6) - (ne (symbol_ref "s390_pool_overflow") (const_int 0)) - (if_then_else (eq (symbol_ref "flag_pic") (const_int 0)) - (const_int 12) (const_int 14)) (eq (symbol_ref "flag_pic") (const_int 0)) (const_int 6)] (const_int 8)))]) @@ -5734,9 +5897,6 @@ (const_int 4) (ne (symbol_ref "TARGET_64BIT") (const_int 0)) (const_int 6) - (ne (symbol_ref "s390_pool_overflow") (const_int 0)) - (if_then_else (eq (symbol_ref "flag_pic") (const_int 0)) - (const_int 12) (const_int 14)) (eq (symbol_ref "flag_pic") (const_int 0)) (const_int 6)] (const_int 8)))]) @@ -5759,54 +5919,217 @@ (const_string "RR") (const_string "RX"))) (set_attr "atype" "mem")]) +;; +;;- Trap instructions. +;; + +(define_insn "trap" + [(trap_if (const_int 1) (const_int 0))] + "" + "j\\t.+2" + [(set_attr "op_type" "RX")]) + +(define_expand "conditional_trap" + [(set (match_dup 2) (match_dup 3)) + (trap_if (match_operator 0 "comparison_operator" + [(match_dup 2) (const_int 0)]) + (match_operand:SI 1 "general_operand" ""))] + "" + " +{ + enum machine_mode ccmode; + + if (operands[1] != const0_rtx) FAIL; + + ccmode = s390_select_ccmode (GET_CODE (operands[0]), + s390_compare_op0, s390_compare_op1); + operands[2] = gen_rtx_REG (ccmode, 33); + operands[3] = gen_rtx_COMPARE (ccmode, s390_compare_op0, s390_compare_op1); +}") + +(define_insn "*trap" + [(trap_if (match_operator 0 "comparison_operator" [(reg 33) (const_int 0)]) + (const_int 0))] + "" + "j%C0\\t.+2"; + [(set_attr "op_type" "RX")]) ;; -;;- Subtract one and jump if not zero. +;;- Loop instructions. ;; +;; This is all complicated by the fact that since this is a jump insn +;; we must handle our own output reloads. + +(define_expand "doloop_end" + [(use (match_operand 0 "" "")) ; loop pseudo + (use (match_operand 1 "" "")) ; iterations; zero if unknown + (use (match_operand 2 "" "")) ; max iterations + (use (match_operand 3 "" "")) ; loop level + (use (match_operand 4 "" ""))] ; label + "" + " +{ + if (GET_MODE (operands[0]) == SImode) + emit_jump_insn (gen_doloop_si (operands[4], operands[0], operands[0])); + else if (GET_MODE (operands[0]) == DImode && TARGET_64BIT) + emit_jump_insn (gen_doloop_di (operands[4], operands[0], operands[0])); + else + FAIL; -;(define_expand "decrement_and_branch_on_count" -; [(use (match_operand 0 "register_operand" "")) -; (use (label_ref (match_operand 1 "" "")))] -; "" -; " -;{ -;/* if (TARGET_64BIT) -; emit_jump_insn (gen_brctdi (operands[0], operands[1])); -; else */ -; emit_jump_insn (gen_brctsi (operands[0], operands[1])); -; DONE; -;}") -; -;(define_insn "brctsi" -; [(set (pc) -; (if_then_else -; (ne (match_operand:SI 0 "register_operand" "+a") -; (const_int 1)) -; (label_ref (match_operand 1 "" "")) -; (pc))) -; (set (match_dup 0) -; (plus:SI (match_dup 0) (const_int -1)))] -; "" -; "brct\\t%0,%l1" -; [(set_attr "op_type" "RI") -; (set_attr "type" "branch")] -;) -; -;(define_insn "ibrctsi" -; [(set (pc) -; (if_then_else -; (eq (match_operand:SI 0 "register_operand" "+a") -; (const_int 1)) -; (pc) -; (label_ref (match_operand 1 "" "")))) -; (set (match_dup 0) -; (plus:SI (match_dup 0) (const_int -1)))] -; "" -; "brct\\t%0,%l1" -; [(set_attr "op_type" "RI") -; (set_attr "type" "branch")] -;) + DONE; +}") + +(define_insn "doloop_si" + [(set (pc) + (if_then_else + (ne (match_operand:SI 1 "register_operand" "d,d") + (const_int 1)) + (label_ref (match_operand 0 "" "")) + (pc))) + (set (match_operand:SI 2 "register_operand" "=1,?*m*d") + (plus:SI (match_dup 1) (const_int -1))) + (clobber (match_scratch:SI 3 "=X,&d")) + (clobber (reg:CC 33))] + "" + "* +{ + if (which_alternative != 0) + return \"#\"; + else if (get_attr_length (insn) == 4) + return \"brct\\t%1,%l0\"; + else + abort (); +}" + [(set_attr "op_type" "RI") + (set (attr "length") + (cond [(lt (abs (minus (pc) (match_dup 0))) (const_int 60000)) + (const_int 4) + (ne (symbol_ref "TARGET_64BIT") (const_int 0)) + (const_int 10) + (eq (symbol_ref "flag_pic") (const_int 0)) + (const_int 6)] (const_int 8)))]) + +(define_insn "*doloop_si_long" + [(set (pc) + (if_then_else + (ne (match_operand:SI 1 "register_operand" "d,d") + (const_int 1)) + (match_operand 0 "address_operand" "p,p") + (pc))) + (set (match_operand:SI 2 "register_operand" "=1,?*m*d") + (plus:SI (match_dup 1) (const_int -1))) + (clobber (match_scratch:SI 3 "=X,&d")) + (clobber (reg:CC 33))] + "" + "* +{ + if (get_attr_op_type (insn) == OP_TYPE_RR) + return \"bctr\\t%1,%0\"; + else + return \"bct\\t%1,%a0\"; +}" + [(set (attr "op_type") + (if_then_else (match_operand 0 "register_operand" "") + (const_string "RR") (const_string "RX"))) + (set_attr "atype" "mem")]) + +(define_split + [(set (pc) + (if_then_else (ne (match_operand:SI 1 "register_operand" "") + (const_int 1)) + (match_operand 0 "" "") + (pc))) + (set (match_operand:SI 2 "nonimmediate_operand" "") + (plus:SI (match_dup 1) (const_int -1))) + (clobber (match_scratch:SI 3 "")) + (clobber (reg:CC 33))] + "reload_completed + && (! REG_P (operands[2]) + || ! rtx_equal_p (operands[1], operands[2]))" + [(set (match_dup 3) (match_dup 1)) + (parallel [(set (reg:CCAN 33) + (compare:CCAN (plus:SI (match_dup 3) (const_int -1)) + (const_int 0))) + (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))]) + (set (match_dup 2) (match_dup 3)) + (set (pc) (if_then_else (ne (reg:CCAN 33) (const_int 0)) + (match_dup 0) + (pc)))] + "") + +(define_insn "doloop_di" + [(set (pc) + (if_then_else + (ne (match_operand:DI 1 "register_operand" "d,d") + (const_int 1)) + (label_ref (match_operand 0 "" "")) + (pc))) + (set (match_operand:DI 2 "register_operand" "=1,?*m*r") + (plus:DI (match_dup 1) (const_int -1))) + (clobber (match_scratch:DI 3 "=X,&d")) + (clobber (reg:CC 33))] + "TARGET_64BIT" + "* +{ + if (which_alternative != 0) + return \"#\"; + else if (get_attr_length (insn) == 4) + return \"brctg\\t%1,%l0\"; + else + abort (); +}" + [(set_attr "op_type" "RI") + (set (attr "length") + (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000)) + (const_int 4) (const_int 12)))]) + +(define_insn "*doloop_di_long" + [(set (pc) + (if_then_else + (ne (match_operand:DI 1 "register_operand" "d,d") + (const_int 1)) + (match_operand 0 "address_operand" "p,p") + (pc))) + (set (match_operand:DI 2 "register_operand" "=1,?*m*d") + (plus:DI (match_dup 1) (const_int -1))) + (clobber (match_scratch:DI 3 "=X,&d")) + (clobber (reg:CC 33))] + "" + "* +{ + if (get_attr_op_type (insn) == OP_TYPE_RRE) + return \"bctgr\\t%1,%0\"; + else + return \"bctg\\t%1,%a0\"; +}" + [(set (attr "op_type") + (if_then_else (match_operand 0 "register_operand" "") + (const_string "RRE") (const_string "RXE"))) + (set_attr "atype" "mem")]) +(define_split + [(set (pc) + (if_then_else (ne (match_operand:DI 1 "register_operand" "") + (const_int 1)) + (match_operand 0 "" "") + (pc))) + (set (match_operand:DI 2 "nonimmediate_operand" "") + (plus:DI (match_dup 1) (const_int -1))) + (clobber (match_scratch:DI 3 "")) + (clobber (reg:CC 33))] + "reload_completed + && (! REG_P (operands[2]) + || ! rtx_equal_p (operands[1], operands[2]))" + [(set (match_dup 3) (match_dup 1)) + (parallel [(set (reg:CCAN 33) + (compare:CCAN (plus:DI (match_dup 3) (const_int -1)) + (const_int 0))) + (set (match_dup 3) (plus:DI (match_dup 3) (const_int -1)))]) + (set (match_dup 2) (match_dup 3)) + (set (pc) (if_then_else (ne (reg:CCAN 33) (const_int 0)) + (match_dup 0) + (pc)))] + "") ;; ;;- Unconditional jump instructions. @@ -5961,7 +6284,8 @@ [(unspec_volatile [(const_int 0)] 0)] "" "" - [(set_attr "type" "none")]) + [(set_attr "type" "none") + (set_attr "length" "0")]) @@ -6014,10 +6338,7 @@ compiler doesn't know about it, because the PLT glue code uses it. In 64-bit, this is not necessary. */ if (plt_call && !TARGET_64BIT) - { - current_function_uses_pic_offset_table = 1; - use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx); - } + use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx); DONE; }") @@ -6139,10 +6460,7 @@ compiler doesn't know about it, because the PLT glue code uses it. In 64-bit, this is not necessary. */ if (plt_call && !TARGET_64BIT) - { - current_function_uses_pic_offset_table = 1; - use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx); - } + use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx); DONE; }") @@ -6218,6 +6536,192 @@ (set_attr "type" "jsr") (set_attr "atype" "mem")]) +;; +;;- Thread-local storage support. +;; + +(define_insn "get_tp_64" + [(set (match_operand:DI 0 "nonimmediate_operand" "=??d,Q") + (unspec:DI [(const_int 0)] UNSPEC_TP))] + "TARGET_64BIT" + "@ + ear\\t%0,%%a0\;sllg\\t%0,%0,32\;ear\\t%0,%%a1 + stam\\t%%a0,%%a1,%0" + [(set_attr "op_type" "NN,RS") + (set_attr "atype" "reg,mem") + (set_attr "type" "o3,*") + (set_attr "length" "14,*")]) + +(define_insn "get_tp_31" + [(set (match_operand:SI 0 "nonimmediate_operand" "=d,Q") + (unspec:SI [(const_int 0)] UNSPEC_TP))] + "!TARGET_64BIT" + "@ + ear\\t%0,%%a0 + stam\\t%%a0,%%a0,%0" + [(set_attr "op_type" "RRE,RS") + (set_attr "atype" "reg,mem")]) + +(define_insn "set_tp_64" + [(unspec_volatile [(match_operand:DI 0 "general_operand" "??d,Q")] UNSPECV_SET_TP) + (clobber (match_scratch:SI 1 "=d,X"))] + "TARGET_64BIT" + "@ + sar\\t%%a1,%0\;srlg\\t%1,%0,32\;sar\\t%%a0,%1 + lam\\t%%a0,%%a1,%0" + [(set_attr "op_type" "NN,RS") + (set_attr "atype" "reg,mem") + (set_attr "type" "o3,*") + (set_attr "length" "14,*")]) + +(define_insn "set_tp_31" + [(unspec_volatile [(match_operand:SI 0 "general_operand" "d,Q")] UNSPECV_SET_TP)] + "!TARGET_64BIT" + "@ + sar\\t%%a0,%0 + lam\\t%%a0,%%a0,%0" + [(set_attr "op_type" "RRE,RS") + (set_attr "atype" "reg,mem")]) + +(define_insn "*tls_load_64" + [(set (match_operand:DI 0 "register_operand" "=d") + (unspec:DI [(match_operand:DI 1 "memory_operand" "m") + (match_operand:DI 2 "" "")] + UNSPEC_TLS_LOAD))] + "TARGET_64BIT" + "lg\\t%0,%1%J2" + [(set_attr "op_type" "RXE") + (set_attr "atype" "mem")]) + +(define_insn "*tls_load_31" + [(set (match_operand:SI 0 "register_operand" "=d") + (unspec:SI [(match_operand:SI 1 "memory_operand" "m") + (match_operand:SI 2 "" "")] + UNSPEC_TLS_LOAD))] + "!TARGET_64BIT" + "l\\t%0,%1%J2" + [(set_attr "op_type" "RX") + (set_attr "atype" "mem")]) + +(define_expand "call_value_tls" + [(set (match_operand 0 "" "") + (call (const_int 0) (const_int 0))) + (use (match_operand 1 "" ""))] + "" + " +{ + rtx insn, sym; + + if (!flag_pic) + abort (); + + sym = s390_tls_get_offset (); + sym = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym), 113); + sym = gen_rtx_CONST (Pmode, sym); + + /* Unless we can use the bras(l) insn, force the + routine address into a register. */ + if (!TARGET_SMALL_EXEC && !TARGET_64BIT) + { + rtx target = gen_reg_rtx (Pmode); + emit_move_insn (target, sym); + sym = target; + } + + sym = gen_rtx_MEM (QImode, sym); + + /* Emit insn. */ + insn = emit_call_insn ( + gen_call_value_tls_exp (operands[0], sym, const0_rtx, + gen_rtx_REG (Pmode, RETURN_REGNUM), + operands[1])); + + /* The calling convention of __tls_get_offset uses the + GOT register implicitly. */ + use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx); + use_reg (&CALL_INSN_FUNCTION_USAGE (insn), operands[0]); + CONST_OR_PURE_CALL_P (insn) = 1; + + DONE; +}") + +(define_expand "call_value_tls_exp" + [(parallel [(set (match_operand 0 "" "") + (call (match_operand 1 "" "") + (match_operand 2 "" ""))) + (clobber (match_operand 3 "" "")) + (use (match_operand 4 "" ""))])] + "" + "") + +(define_insn "brasl_tls" + [(set (match_operand 0 "register_operand" "=df") + (call (mem:QI (match_operand:DI 1 "bras_sym_operand" "X")) + (match_operand:SI 2 "const_int_operand" "n"))) + (clobber (match_operand:DI 3 "register_operand" "=r")) + (use (match_operand:DI 4 "" ""))] + "TARGET_64BIT" + "brasl\\t%3,%1%J4" + [(set_attr "op_type" "RIL") + (set_attr "type" "jsr")]) + +(define_insn "bras_tls" + [(set (match_operand 0 "register_operand" "=df") + (call (mem:QI (match_operand:SI 1 "bras_sym_operand" "X")) + (match_operand:SI 2 "const_int_operand" "n"))) + (clobber (match_operand:SI 3 "register_operand" "=r")) + (use (match_operand:SI 4 "" ""))] + "TARGET_SMALL_EXEC" + "bras\\t%3,%1%J4" + [(set_attr "op_type" "RI") + (set_attr "type" "jsr")]) + +(define_insn "basr_tls_64" + [(set (match_operand 0 "register_operand" "=df") + (call (mem:QI (match_operand:DI 1 "register_operand" "a")) + (match_operand:SI 2 "const_int_operand" "n"))) + (clobber (match_operand:DI 3 "register_operand" "=r")) + (use (match_operand:DI 4 "" ""))] + "TARGET_64BIT" + "basr\\t%3,%1%J4" + [(set_attr "op_type" "RR") + (set_attr "type" "jsr")]) + +(define_insn "basr_tls_31" + [(set (match_operand 0 "register_operand" "=df") + (call (mem:QI (match_operand:SI 1 "register_operand" "a")) + (match_operand:SI 2 "const_int_operand" "n"))) + (clobber (match_operand:SI 3 "register_operand" "=r")) + (use (match_operand:SI 4 "" ""))] + "!TARGET_64BIT" + "basr\\t%3,%1%J4" + [(set_attr "op_type" "RR") + (set_attr "type" "jsr") + (set_attr "atype" "mem")]) + +(define_insn "bas_tls_64" + [(set (match_operand 0 "register_operand" "=df") + (call (mem:QI (match_operand:QI 1 "address_operand" "p")) + (match_operand:SI 2 "const_int_operand" "n"))) + (clobber (match_operand:DI 3 "register_operand" "=r")) + (use (match_operand:DI 4 "" ""))] + "TARGET_64BIT" + "bas\\t%3,%a1%J4" + [(set_attr "op_type" "RX") + (set_attr "type" "jsr") + (set_attr "atype" "mem")]) + +(define_insn "bas_tls_31" + [(set (match_operand 0 "register_operand" "=df") + (call (mem:QI (match_operand:QI 1 "address_operand" "p")) + (match_operand:SI 2 "const_int_operand" "n"))) + (clobber (match_operand:SI 3 "register_operand" "=r")) + (use (match_operand:SI 4 "" ""))] + "!TARGET_64BIT" + "bas\\t%3,%a1%J4" + [(set_attr "op_type" "RX") + (set_attr "type" "jsr") + (set_attr "atype" "mem")]) ;; ;;- Miscellaneous instructions. @@ -6505,7 +7009,7 @@ [(set_attr "op_type" "NN") (set_attr "length" "0")]) -(define_insn "reload_base" +(define_insn "reload_base_31" [(set (match_operand:SI 0 "register_operand" "=a") (unspec:SI [(label_ref (match_operand 1 "" ""))] 210))] "!TARGET_64BIT" @@ -6514,15 +7018,29 @@ (set_attr "type" "la") (set_attr "length" "6")]) -(define_insn "reload_base2" +(define_insn "reload_base_64" + [(set (match_operand:DI 0 "register_operand" "=a") + (unspec:DI [(label_ref (match_operand 1 "" ""))] 210))] + "TARGET_64BIT" + "larl\\t%0,%1" + [(set_attr "op_type" "RIL") + (set_attr "type" "la")]) + +(define_insn "reload_anchor" [(set (match_operand:SI 0 "register_operand" "=a") - (unspec:SI [(label_ref (match_operand 1 "" ""))] 211))] + (unspec:SI [(match_operand:SI 1 "register_operand" "a")] 211))] "!TARGET_64BIT" - "la\\t%0,%1-.(%0)" + "l\\t%0,0(%1)\;la\\t%0,0(%0,%1)" [(set_attr "op_type" "NN") (set_attr "type" "la") - (set_attr "length" "4")]) + (set_attr "length" "8")]) +(define_insn "pool" + [(unspec_volatile [(match_operand 0 "const_int_operand" "n")] 220)] + "" + "* abort ();" + [(set_attr "op_type" "NN") + (set (attr "length") (symbol_ref "INTVAL (operands[0])"))]) ;; ;; Insns related to generating the function prologue and epilogue. @@ -6566,162 +7084,44 @@ (set_attr "type" "jsr") (set_attr "atype" "mem")]) - -(define_insn "lit" - [(set (reg 13) (pc)) - (unspec_volatile [(const_int 0)] 200)] +(define_insn "literal_pool_31" + [(unspec_volatile [(const_int 0)] 300) + (set (match_operand:SI 0 "register_operand" "=a") + (label_ref (match_operand 1 "" ""))) + (use (label_ref (match_operand 2 "" "")))] "" - "* { - s390_output_constant_pool (asm_out_file); - return \"\"; -}" - [(set_attr "op_type" "NN") - (set_attr "type" "integer")]) - - -;; -;; Peephole optimization patterns. -;; - -(define_peephole - [(set (match_operand:SI 0 "memory_operand" "m") - (match_operand:SI 1 "register_operand" "d")) - (set (match_dup 1) - (match_dup 0))] - "" - "st\\t%1,%0") - -(define_peephole - [(set (match_operand:SI 0 "memory_operand" "m") - (match_operand:SI 1 "register_operand" "d")) - (set (match_dup 0) - (match_dup 1))] - "" - "st\\t%1,%0") - -(define_peephole - [(set (match_operand:SI 0 "register_operand" "") - (match_operand:SI 1 "register_operand" "")) - (parallel - [(set (match_dup 0) - (plus:SI (match_dup 0) - (match_operand:SI 2 "immediate_operand" ""))) - (clobber (reg:CC 33))])] - "(REGNO (operands[0]) == STACK_POINTER_REGNUM || - REGNO (operands[1]) == STACK_POINTER_REGNUM || - REGNO (operands[0]) == BASE_REGISTER || - REGNO (operands[1]) == BASE_REGISTER) && - INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 4096" - "la\\t%0,%c2(%1)") - -; -; peepholes for fast char instructions -; - -;(define_peephole -; [(set (match_operand:QI 0 "register_operand" "d") -; (match_operand:QI 1 "s_operand" "Q")) -; (set (match_operand:SI 2 "register_operand" "0") -; (zero_extend:SI (match_dup 0)))] -; "REGNO(operands[0]) == REGNO(operands[2])" -; "icm\\t%0,8,%1\;srl\\t%0,24") - -;(define_peephole -; [(set (match_operand:QI 0 "register_operand" "d") -; (match_operand:QI 1 "s_operand" "Q")) -; (set (match_operand:SI 2 "register_operand" "0") -; (sign_extend:SI (match_dup 0)))] -; "REGNO(operands[0]) == REGNO(operands[2])" -; "icm\\t%0,8,%1\;sra\\t%0,24") - -(define_peephole - [(set (match_operand:QI 0 "register_operand" "d") - (match_operand:QI 1 "immediate_operand" "J")) - (set (match_operand:SI 2 "register_operand" "0" ) - (sign_extend:SI (match_dup 0) ) )] - "REGNO(operands[0]) == REGNO(operands[2])" - "lhi\\t%0,%h1") - -; -; peepholes for fast short instructions -; - -;(define_peephole -; [(set (match_operand:HI 0 "register_operand" "d") -; (match_operand:HI 1 "s_operand" "Q")) -; (set (match_operand:SI 2 "register_operand" "0" ) -; (zero_extend:SI (match_dup 0)))] -; "REGNO(operands[0]) == REGNO(operands[2])" -; "icm\\t%0,12,%1\;srl\\t%0,16") - -(define_peephole - [(set (match_operand:HI 0 "register_operand" "d") - (match_operand:HI 1 "memory_operand" "m")) - (set (match_operand:SI 2 "register_operand" "0" ) - (sign_extend:SI (match_dup 0)))] - "REGNO(operands[0]) == REGNO(operands[2])" - "lh\\t%0,%1") - -(define_peephole - [(set (match_operand:HI 0 "register_operand" "d") - (match_operand:HI 1 "immediate_operand" "K")) - (set (match_operand:SI 2 "register_operand" "0" ) - (sign_extend:SI (match_dup 0) ) )] - "REGNO(operands[0]) == REGNO(operands[2])" - "lhi\\t%0,%h1") - -; -; peepholes for divide instructions -; - -(define_peephole - [(set (match_operand:DI 0 "register_operand" "d") - (match_operand:DI 1 "memory_operand" "m")) - (set (match_dup 0) - (lshiftrt:DI (match_dup 0) - (match_operand:SI 2 "immediate_operand" "J"))) - (set (match_dup 0) - (div:SI (match_dup 0) - (match_operand:SI 3 "nonimmediate_operand" "g"))) - (set (match_dup 1) - (match_dup 0))] - "" - "* -{ - output_asm_insn (\"l\\t%0,%1\", operands); - output_asm_insn (\"srdl\\t%0,%b2\", operands); - - if (REG_P (operands[3])) - output_asm_insn (\"dr\\t%0,%3\", operands); - else - output_asm_insn (\"d\\t%0,%3\", operands); + if (s390_nr_constants) + { + output_asm_insn ("bras\\t%0,%2", operands); + s390_output_constant_pool (operands[1], operands[2]); + } + else if (flag_pic) + { + /* We need the anchor label in any case. */ + ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", + CODE_LABEL_NUMBER (operands[1])); + } - return \"st\\t%N0,%N1\"; -}") + return ""; +} + [(set_attr "op_type" "NN") + (set_attr "type" "la")]) -(define_peephole - [(set (match_operand:DI 0 "register_operand" "d") - (match_operand:DI 1 "memory_operand" "m")) - (set (match_dup 0) - (lshiftrt:DI (match_dup 0) - (match_operand:SI 2 "immediate_operand" "J"))) - (set (match_dup 0) - (mod:SI (match_dup 0) - (match_operand:SI 3 "nonimmediate_operand" "g"))) - (set (match_dup 1) - (match_dup 0))] +(define_insn "literal_pool_64" + [(unspec_volatile [(const_int 0)] 300) + (set (match_operand:DI 0 "register_operand" "=a") + (label_ref (match_operand 1 "" ""))) + (use (label_ref (match_operand 2 "" "")))] "" - "* { - output_asm_insn (\"l\\t%0,%1\", operands); - output_asm_insn (\"srdl\\t%0,%b2\", operands); - - if (REG_P (operands[3])) - output_asm_insn (\"dr\\t%0,%3\", operands); - else - output_asm_insn (\"d\\t%0,%3\", operands); - - return \"st\\t%0,%1\"; -}") + if (s390_nr_constants) + { + output_asm_insn ("larl\\t%0,%1", operands); + s390_output_constant_pool (operands[1], operands[2]); + } + return ""; +} + [(set_attr "op_type" "NN") + (set_attr "type" "la")]) |