X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gcc%2Fconfig%2Fsparc%2Fsparc.md;h=d89f6f93b58b8e760a9c094728f3ddc429d5209a;hb=9d4dedaa7b3ddd81934489e200dc7a4b97836dbc;hp=aa9f9fb7b17a6fc6c909078965a5905a3ade2750;hpb=d5a9738b2f8a90a3f11c2d6003bc88db95349c22;p=gcc.git diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index aa9f9fb7b17..d89f6f93b58 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -53,16 +53,45 @@ (UNSPEC_FPACK32 41) (UNSPEC_FPACKFIX 42) (UNSPEC_FEXPAND 43) - (UNSPEC_FPMERGE 44) + (UNSPEC_MUL16AU 44) (UNSPEC_MUL16AL 45) (UNSPEC_MUL8UL 46) (UNSPEC_MULDUL 47) (UNSPEC_ALIGNDATA 48) - (UNSPEC_ALIGNADDR 49) + (UNSPEC_FCMP 49) (UNSPEC_PDIST 50) + (UNSPEC_EDGE8 51) + (UNSPEC_EDGE8L 52) + (UNSPEC_EDGE16 53) + (UNSPEC_EDGE16L 54) + (UNSPEC_EDGE32 55) + (UNSPEC_EDGE32L 56) + (UNSPEC_ARRAY8 57) + (UNSPEC_ARRAY16 58) + (UNSPEC_ARRAY32 59) (UNSPEC_SP_SET 60) (UNSPEC_SP_TEST 61) + + (UNSPEC_EDGE8N 70) + (UNSPEC_EDGE8LN 71) + (UNSPEC_EDGE16N 72) + (UNSPEC_EDGE16LN 73) + (UNSPEC_EDGE32N 74) + (UNSPEC_EDGE32LN 75) + (UNSPEC_BSHUFFLE 76) + (UNSPEC_CMASK8 77) + (UNSPEC_CMASK16 78) + (UNSPEC_CMASK32 79) + (UNSPEC_FCHKSM16 80) + (UNSPEC_PDISTN 81) + (UNSPEC_FUCMP 82) + (UNSPEC_FHADD 83) + (UNSPEC_FHSUB 84) + (UNSPEC_XMUL 85) + (UNSPEC_MUL8 86) + (UNSPEC_MUL8SU 87) + (UNSPEC_MULDSU 88) ]) (define_constants @@ -77,25 +106,106 @@ (UNSPECV_PROBE_STACK_RANGE 11) ]) +(define_constants + [(G0_REG 0) + (G1_REG 1) + (G2_REG 2) + (G3_REG 3) + (G4_REG 4) + (G5_REG 5) + (G6_REG 6) + (G7_REG 7) + (O0_REG 8) + (O1_REG 9) + (O2_REG 10) + (O3_REG 11) + (O4_REG 12) + (O5_REG 13) + (O6_REG 14) + (O7_REG 15) + (L0_REG 16) + (L1_REG 17) + (L2_REG 18) + (L3_REG 19) + (L4_REG 20) + (L5_REG 21) + (L6_REG 22) + (L7_REG 23) + (I0_REG 24) + (I1_REG 25) + (I2_REG 26) + (I3_REG 27) + (I4_REG 28) + (I5_REG 29) + (I6_REG 30) + (I7_REG 31) + (F0_REG 32) + (F1_REG 33) + (F2_REG 34) + (F3_REG 35) + (F4_REG 36) + (F5_REG 37) + (F6_REG 38) + (F7_REG 39) + (F8_REG 40) + (F9_REG 41) + (F10_REG 42) + (F11_REG 43) + (F12_REG 44) + (F13_REG 45) + (F14_REG 46) + (F15_REG 47) + (F16_REG 48) + (F17_REG 49) + (F18_REG 50) + (F19_REG 51) + (F20_REG 52) + (F21_REG 53) + (F22_REG 54) + (F23_REG 55) + (F24_REG 56) + (F25_REG 57) + (F26_REG 58) + (F27_REG 59) + (F28_REG 60) + (F29_REG 61) + (F30_REG 62) + (F31_REG 63) + (F32_REG 64) + (F34_REG 66) + (F36_REG 68) + (F38_REG 70) + (F40_REG 72) + (F42_REG 74) + (F44_REG 76) + (F46_REG 78) + (F48_REG 80) + (F50_REG 82) + (F52_REG 84) + (F54_REG 86) + (F56_REG 88) + (F58_REG 90) + (F60_REG 92) + (F62_REG 94) + (FCC0_REG 96) + (FCC1_REG 97) + (FCC2_REG 98) + (FCC3_REG 99) + (CC_REG 100) + (SFP_REG 101) + (GSR_REG 102) + ]) (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")]) (define_mode_iterator I [QI HI SI DI]) (define_mode_iterator F [SF DF TF]) -;; We don't define V1SI because SI should work just fine. -(define_mode_iterator V32 [SF V2HI V4QI]) -(define_mode_iterator V32I [SI V2HI V4QI]) - -(define_mode_iterator V64 [DF V2SI V4HI V8QI]) -(define_mode_iterator V64I [DI V2SI V4HI V8QI]) - ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding ;; constraint letter is 'e'. To avoid any confusion, 'e' is used instead of ;; 'f' for all DF/TFmode values, including those that are specific to the v8. - ;; Attribute for cpu type. ;; These must match the values for enum processor_type in sparc.h. (define_attr "cpu" @@ -115,7 +225,9 @@ ultrasparc, ultrasparc3, niagara, - niagara2" + niagara2, + niagara3, + niagara4" (const (symbol_ref "sparc_cpu_attr"))) ;; Attribute for the instruction set. @@ -140,7 +252,7 @@ fpcmp, fpmul,fpdivs,fpdivd, fpsqrts,fpsqrtd, - fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp, + fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,edge,edgen,gsr,array, cmove, ialuX, multi,savew,flushw,iflush,trap" @@ -164,7 +276,7 @@ (define_attr "calls_eh_return" "false,true" (symbol_ref "(crtl->calls_eh_return != 0 ? CALLS_EH_RETURN_TRUE : CALLS_EH_RETURN_FALSE)")) - + (define_attr "leaf_function" "false,true" (symbol_ref "(current_function_uses_only_leaf_regs != 0 ? LEAF_FUNCTION_TRUE : LEAF_FUNCTION_FALSE)")) @@ -173,6 +285,10 @@ (symbol_ref "(flag_delayed_branch != 0 ? DELAYED_BRANCH_TRUE : DELAYED_BRANCH_FALSE)")) +(define_attr "flat" "false,true" + (symbol_ref "(TARGET_FLAT != 0 + ? FLAT_TRUE : FLAT_FALSE)")) + ;; Length (in # of insns). ;; Beware that setting a length greater or equal to 3 for conditional branches ;; has a side-effect (see output_cbranch and output_v9branch). @@ -212,10 +328,10 @@ (eq_attr "branch_type" "fcc") (if_then_else (match_operand 0 "fcc0_register_operand" "") (if_then_else (eq_attr "empty_delay_slot" "true") - (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0)) + (if_then_else (not (match_test "TARGET_V9")) (const_int 3) (const_int 2)) - (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0)) + (if_then_else (not (match_test "TARGET_V9")) (const_int 2) (const_int 1))) (if_then_else (lt (pc) (match_dup 2)) @@ -366,7 +482,7 @@ ;; The compare DEFINE_INSNs. (define_insn "*cmpsi_insn" - [(set (reg:CC 100) + [(set (reg:CC CC_REG) (compare:CC (match_operand:SI 0 "register_operand" "r") (match_operand:SI 1 "arith_operand" "rI")))] "" @@ -374,7 +490,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmpdi_sp64" - [(set (reg:CCX 100) + [(set (reg:CCX CC_REG) (compare:CCX (match_operand:DI 0 "register_operand" "r") (match_operand:DI 1 "arith_operand" "rI")))] "TARGET_ARCH64" @@ -500,7 +616,7 @@ (match_operand:SI 2 "register_operand" ""))) (parallel [(set (match_operand:SI 0 "register_operand" "") (eq:SI (match_dup 3) (const_int 0))) - (clobber (reg:CC 100))])] + (clobber (reg:CC CC_REG))])] "" { operands[3] = gen_reg_rtx (SImode); }) @@ -519,7 +635,7 @@ (match_operand:SI 2 "register_operand" ""))) (parallel [(set (match_operand:SI 0 "register_operand" "") (ne:SI (match_dup 3) (const_int 0))) - (clobber (reg:CC 100))])] + (clobber (reg:CC CC_REG))])] "" { operands[3] = gen_reg_rtx (SImode); }) @@ -544,13 +660,13 @@ [(set (match_operand:SI 0 "register_operand" "=r") (ne:SI (match_operand:SI 1 "register_operand" "r") (const_int 0))) - (clobber (reg:CC 100))] + (clobber (reg:CC CC_REG))] "" "#" "" - [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1)) + [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1)) (const_int 0))) - (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))] + (set (match_dup 0) (ltu:SI (reg:CC CC_REG) (const_int 0)))] "" [(set_attr "length" "2")]) @@ -558,13 +674,13 @@ [(set (match_operand:SI 0 "register_operand" "=r") (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r") (const_int 0)))) - (clobber (reg:CC 100))] + (clobber (reg:CC CC_REG))] "" "#" "" - [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1)) + [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1)) (const_int 0))) - (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))] + (set (match_dup 0) (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))] "" [(set_attr "length" "2")]) @@ -572,16 +688,16 @@ [(set (match_operand:DI 0 "register_operand" "=r") (ne:DI (match_operand:SI 1 "register_operand" "r") (const_int 0))) - (clobber (reg:CC 100))] + (clobber (reg:CC CC_REG))] "TARGET_ARCH64" "#" "&& 1" - [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) + [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1)) (const_int 0))) (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0) (const_int 0)) - (ltu:SI (reg:CC_NOOV 100) + (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))] "" [(set_attr "length" "2")]) @@ -635,13 +751,13 @@ [(set (match_operand:SI 0 "register_operand" "=r") (eq:SI (match_operand:SI 1 "register_operand" "r") (const_int 0))) - (clobber (reg:CC 100))] + (clobber (reg:CC CC_REG))] "" "#" "" - [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1)) + [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1)) (const_int 0))) - (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))] + (set (match_dup 0) (geu:SI (reg:CC CC_REG) (const_int 0)))] "" [(set_attr "length" "2")]) @@ -649,13 +765,13 @@ [(set (match_operand:SI 0 "register_operand" "=r") (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r") (const_int 0)))) - (clobber (reg:CC 100))] + (clobber (reg:CC CC_REG))] "" "#" "" - [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1)) + [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1)) (const_int 0))) - (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))] + (set (match_dup 0) (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))] "" [(set_attr "length" "2")]) @@ -663,16 +779,16 @@ [(set (match_operand:DI 0 "register_operand" "=r") (eq:DI (match_operand:SI 1 "register_operand" "r") (const_int 0))) - (clobber (reg:CC 100))] + (clobber (reg:CC CC_REG))] "TARGET_ARCH64" "#" "&& 1" - [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) + [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1)) (const_int 0))) (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0) (const_int -1)) - (ltu:SI (reg:CC_NOOV 100) + (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))] "" [(set_attr "length" "2")]) @@ -731,13 +847,13 @@ (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r") (const_int 0)) (match_operand:SI 2 "register_operand" "r"))) - (clobber (reg:CC 100))] + (clobber (reg:CC CC_REG))] "" "#" "" - [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1)) + [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1)) (const_int 0))) - (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0)) + (set (match_dup 0) (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0)) (match_dup 2)))] "" [(set_attr "length" "2")]) @@ -747,14 +863,14 @@ (minus:SI (match_operand:SI 2 "register_operand" "r") (ne:SI (match_operand:SI 1 "register_operand" "r") (const_int 0)))) - (clobber (reg:CC 100))] + (clobber (reg:CC CC_REG))] "" "#" "" - [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1)) + [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1)) (const_int 0))) (set (match_dup 0) (minus:SI (match_dup 2) - (ltu:SI (reg:CC 100) (const_int 0))))] + (ltu:SI (reg:CC CC_REG) (const_int 0))))] "" [(set_attr "length" "2")]) @@ -763,13 +879,13 @@ (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r") (const_int 0)) (match_operand:SI 2 "register_operand" "r"))) - (clobber (reg:CC 100))] + (clobber (reg:CC CC_REG))] "" "#" "" - [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1)) + [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1)) (const_int 0))) - (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0)) + (set (match_dup 0) (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0)) (match_dup 2)))] "" [(set_attr "length" "2")]) @@ -779,14 +895,14 @@ (minus:SI (match_operand:SI 2 "register_operand" "r") (eq:SI (match_operand:SI 1 "register_operand" "r") (const_int 0)))) - (clobber (reg:CC 100))] + (clobber (reg:CC CC_REG))] "" "#" "" - [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1)) + [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1)) (const_int 0))) (set (match_dup 0) (minus:SI (match_dup 2) - (geu:SI (reg:CC 100) (const_int 0))))] + (geu:SI (reg:CC CC_REG) (const_int 0))))] "" [(set_attr "length" "2")]) @@ -796,14 +912,14 @@ (define_insn "*sltu_insn" [(set (match_operand:SI 0 "register_operand" "=r") - (ltu:SI (reg:CC 100) (const_int 0)))] + (ltu:SI (reg:CC CC_REG) (const_int 0)))] "" "addx\t%%g0, 0, %0" [(set_attr "type" "ialuX")]) (define_insn "*neg_sltu_insn" [(set (match_operand:SI 0 "register_operand" "=r") - (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))] + (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))] "" "subx\t%%g0, 0, %0" [(set_attr "type" "ialuX")]) @@ -811,7 +927,7 @@ ;; ??? Combine should canonicalize these next two to the same pattern. (define_insn "*neg_sltu_minus_x" [(set (match_operand:SI 0 "register_operand" "=r") - (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0))) + (minus:SI (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))) (match_operand:SI 1 "arith_operand" "rI")))] "" "subx\t%%g0, %1, %0" @@ -819,7 +935,7 @@ (define_insn "*neg_sltu_plus_x" [(set (match_operand:SI 0 "register_operand" "=r") - (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0)) + (neg:SI (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0)) (match_operand:SI 1 "arith_operand" "rI"))))] "" "subx\t%%g0, %1, %0" @@ -827,14 +943,14 @@ (define_insn "*sgeu_insn" [(set (match_operand:SI 0 "register_operand" "=r") - (geu:SI (reg:CC 100) (const_int 0)))] + (geu:SI (reg:CC CC_REG) (const_int 0)))] "" "subx\t%%g0, -1, %0" [(set_attr "type" "ialuX")]) (define_insn "*neg_sgeu_insn" [(set (match_operand:SI 0 "register_operand" "=r") - (neg:SI (geu:SI (reg:CC 100) (const_int 0))))] + (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))] "" "addx\t%%g0, -1, %0" [(set_attr "type" "ialuX")]) @@ -845,7 +961,7 @@ (define_insn "*sltu_plus_x" [(set (match_operand:SI 0 "register_operand" "=r") - (plus:SI (ltu:SI (reg:CC 100) (const_int 0)) + (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0)) (match_operand:SI 1 "arith_operand" "rI")))] "" "addx\t%%g0, %1, %0" @@ -853,7 +969,7 @@ (define_insn "*sltu_plus_x_plus_y" [(set (match_operand:SI 0 "register_operand" "=r") - (plus:SI (ltu:SI (reg:CC 100) (const_int 0)) + (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0)) (plus:SI (match_operand:SI 1 "arith_operand" "%r") (match_operand:SI 2 "arith_operand" "rI"))))] "" @@ -863,7 +979,7 @@ (define_insn "*x_minus_sltu" [(set (match_operand:SI 0 "register_operand" "=r") (minus:SI (match_operand:SI 1 "register_operand" "r") - (ltu:SI (reg:CC 100) (const_int 0))))] + (ltu:SI (reg:CC CC_REG) (const_int 0))))] "" "subx\t%1, 0, %0" [(set_attr "type" "ialuX")]) @@ -873,7 +989,7 @@ [(set (match_operand:SI 0 "register_operand" "=r") (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") (match_operand:SI 2 "arith_operand" "rI")) - (ltu:SI (reg:CC 100) (const_int 0))))] + (ltu:SI (reg:CC CC_REG) (const_int 0))))] "" "subx\t%r1, %2, %0" [(set_attr "type" "ialuX")]) @@ -881,7 +997,7 @@ (define_insn "*x_minus_sltu_plus_y" [(set (match_operand:SI 0 "register_operand" "=r") (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") - (plus:SI (ltu:SI (reg:CC 100) (const_int 0)) + (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0)) (match_operand:SI 2 "arith_operand" "rI"))))] "" "subx\t%r1, %2, %0" @@ -889,7 +1005,7 @@ (define_insn "*sgeu_plus_x" [(set (match_operand:SI 0 "register_operand" "=r") - (plus:SI (geu:SI (reg:CC 100) (const_int 0)) + (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0)) (match_operand:SI 1 "register_operand" "r")))] "" "subx\t%1, -1, %0" @@ -898,7 +1014,7 @@ (define_insn "*x_minus_sgeu" [(set (match_operand:SI 0 "register_operand" "=r") (minus:SI (match_operand:SI 1 "register_operand" "r") - (geu:SI (reg:CC 100) (const_int 0))))] + (geu:SI (reg:CC CC_REG) (const_int 0))))] "" "addx\t%1, -1, %0" [(set_attr "type" "ialuX")]) @@ -974,7 +1090,7 @@ (define_insn "*normal_branch" [(set (pc) (if_then_else (match_operator 0 "noov_compare_operator" - [(reg 100) (const_int 0)]) + [(reg CC_REG) (const_int 0)]) (label_ref (match_operand 1 "" "")) (pc)))] "" @@ -990,7 +1106,7 @@ (define_insn "*inverted_branch" [(set (pc) (if_then_else (match_operator 0 "noov_compare_operator" - [(reg 100) (const_int 0)]) + [(reg CC_REG) (const_int 0)]) (pc) (label_ref (match_operand 1 "" ""))))] "" @@ -1119,7 +1235,7 @@ (unspec:P [(match_operand:P 1 "symbolic_operand" "") (match_operand:P 2 "call_address_operand" "") (match_operand:P 3 "const_int_operand" "")] UNSPEC_LOAD_PCREL_SYM)) - (clobber (reg:P 15))] + (clobber (reg:P O7_REG))] "REGNO (operands[0]) == INTVAL (operands[3])" { if (flag_delayed_branch) @@ -1197,10 +1313,10 @@ }) (define_insn "*movsi_insn" - [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,!f,!f,!m,d") - (match_operand:SI 1 "input_operand" "rI,K,m,rJ,f,m,f,J"))] + [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,!f,!f,!m,d,d") + (match_operand:SI 1 "input_operand" "rI,K,m,rJ,f,m,f,J,P"))] "(register_operand (operands[0], SImode) - || register_or_zero_operand (operands[1], SImode))" + || register_or_zero_or_all_ones_operand (operands[1], SImode))" "@ mov\t%1, %0 sethi\t%%hi(%a1), %0 @@ -1209,8 +1325,9 @@ fmovs\t%1, %0 ld\t%1, %0 st\t%1, %0 - fzeros\t%0" - [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")]) + fzeros\t%0 + fones\t%0" + [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga,fga")]) (define_insn "*movsi_lo_sum" [(set (match_operand:SI 0 "register_operand" "=r") @@ -1399,11 +1516,11 @@ (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")]) (define_insn "*movdi_insn_sp64" - [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b") - (match_operand:DI 1 "input_operand" "rI,N,m,rJ,e,W,e,J"))] + [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b,b") + (match_operand:DI 1 "input_operand" "rI,N,m,rJ,e,W,e,J,P"))] "TARGET_ARCH64 && (register_operand (operands[0], DImode) - || register_or_zero_operand (operands[1], DImode))" + || register_or_zero_or_all_ones_operand (operands[1], DImode))" "@ mov\t%1, %0 sethi\t%%hi(%a1), %0 @@ -1412,9 +1529,10 @@ fmovd\t%1, %0 ldd\t%1, %0 std\t%1, %0 - fzero\t%0" - [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga") - (set_attr "fptype" "*,*,*,*,double,*,*,double")]) + fzero\t%0 + fone\t%0" + [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga,fga") + (set_attr "fptype" "*,*,*,*,double,*,*,double,double")]) (define_expand "movdi_pic_label_ref" [(set (match_dup 3) (high:DI @@ -1799,29 +1917,28 @@ }) -;; Floating point and vector move instructions +;; Floating point move instructions -;; Yes, you guessed it right, the former movsf expander. -(define_expand "mov" - [(set (match_operand:V32 0 "nonimmediate_operand" "") - (match_operand:V32 1 "general_operand" ""))] - "mode == SFmode || TARGET_VIS" +(define_expand "movsf" + [(set (match_operand:SF 0 "nonimmediate_operand" "") + (match_operand:SF 1 "general_operand" ""))] + "" { - if (sparc_expand_move (mode, operands)) + if (sparc_expand_move (SFmode, operands)) DONE; }) (define_insn "*movsf_insn" - [(set (match_operand:V32 0 "nonimmediate_operand" "=d,f,*r,*r,*r,f,*r,m,m") - (match_operand:V32 1 "input_operand" "GY,f,*rRY,Q,S,m,m,f,*rGY"))] + [(set (match_operand:SF 0 "nonimmediate_operand" "=d, d,f, *r,*r,*r,f,*r,m, m") + (match_operand:SF 1 "input_operand" "GY,ZC,f,*rRY, Q, S,m, m,f,*rGY"))] "TARGET_FPU - && (register_operand (operands[0], mode) - || register_or_zero_operand (operands[1], mode))" + && (register_operand (operands[0], SFmode) + || register_or_zero_or_all_ones_operand (operands[1], SFmode))" { if (GET_CODE (operands[1]) == CONST_DOUBLE - && (which_alternative == 2 - || which_alternative == 3 - || which_alternative == 4)) + && (which_alternative == 3 + || which_alternative == 4 + || which_alternative == 5)) { REAL_VALUE_TYPE r; long i; @@ -1836,24 +1953,26 @@ case 0: return "fzeros\t%0"; case 1: - return "fmovs\t%1, %0"; + return "fones\t%0"; case 2: - return "mov\t%1, %0"; + return "fmovs\t%1, %0"; case 3: - return "sethi\t%%hi(%a1), %0"; + return "mov\t%1, %0"; case 4: - return "#"; + return "sethi\t%%hi(%a1), %0"; case 5: + return "#"; case 6: - return "ld\t%1, %0"; case 7: + return "ld\t%1, %0"; case 8: + case 9: return "st\t%r1, %0"; default: gcc_unreachable (); } } - [(set_attr "type" "fga,fpmove,*,*,*,fpload,load,fpstore,store")]) + [(set_attr "type" "fga,fga,fpmove,*,*,*,fpload,load,fpstore,store")]) ;; Exactly the same as above, except that all `f' cases are deleted. ;; This is necessary to prevent reload from ever trying to use a `f' reg @@ -1935,20 +2054,19 @@ [(set (match_dup 0) (high:SF (match_dup 1))) (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))]) -;; Yes, you again guessed it right, the former movdf expander. -(define_expand "mov" - [(set (match_operand:V64 0 "nonimmediate_operand" "") - (match_operand:V64 1 "general_operand" ""))] - "mode == DFmode || TARGET_VIS" +(define_expand "movdf" + [(set (match_operand:DF 0 "nonimmediate_operand" "") + (match_operand:DF 1 "general_operand" ""))] + "" { - if (sparc_expand_move (mode, operands)) + if (sparc_expand_move (DFmode, operands)) DONE; }) ;; Be careful, fmovd does not exist when !v9. (define_insn "*movdf_insn_sp32" - [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o") - (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))] + [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e, *r, o, e,o") + (match_operand:DF 1 "input_operand" "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))] "TARGET_FPU && ! TARGET_V9 && (register_operand (operands[0], DFmode) @@ -1985,15 +2103,16 @@ ;; We have available v9 double floats but not 64-bit integer registers. (define_insn "*movdf_insn_sp32_v9" - [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,T,W,U,T,f,*r,o") - (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYDF,*rGYf"))] + [(set (match_operand:DF 0 "nonimmediate_operand" "=b, b,e, e, T,W,U,T, f, *r, o") + (match_operand:DF 1 "input_operand" "GY,ZC,e,W#F,GY,e,T,U,o#F,*roGYDF,*rGYf"))] "TARGET_FPU && TARGET_V9 && ! TARGET_ARCH64 - && (register_operand (operands[0], mode) - || register_or_zero_operand (operands[1], mode))" + && (register_operand (operands[0], DFmode) + || register_or_zero_or_all_ones_operand (operands[1], DFmode))" "@ fzero\t%0 + fone\t%0 fmovd\t%1, %0 ldd\t%1, %0 stx\t%r1, %0 @@ -2003,9 +2122,9 @@ # # #" - [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*") - (set_attr "length" "*,*,*,*,*,*,*,2,2,2") - (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")]) + [(set_attr "type" "fga,fga,fpmove,load,store,store,load,store,*,*,*") + (set_attr "length" "*,*,*,*,*,*,*,*,2,2,2") + (set_attr "fptype" "double,double,double,*,*,*,*,*,*,*,*")]) (define_insn "*movdf_insn_sp32_v9_no_fpu" [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o") @@ -2026,14 +2145,15 @@ ;; We have available both v9 double floats and 64-bit integer registers. (define_insn "*movdf_insn_sp64" - [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,W,*r,*r,m,*r") - (match_operand:V64 1 "input_operand" "GY,e,W#F,e,*rGY,m,*rGY,DF"))] + [(set (match_operand:DF 0 "nonimmediate_operand" "=b, b,e, e,W, *r,*r, m,*r") + (match_operand:DF 1 "input_operand" "GY,ZC,e,W#F,e,*rGY, m,*rGY,DF"))] "TARGET_FPU && TARGET_ARCH64 - && (register_operand (operands[0], mode) - || register_or_zero_operand (operands[1], mode))" + && (register_operand (operands[0], DFmode) + || register_or_zero_or_all_ones_operand (operands[1], DFmode))" "@ fzero\t%0 + fone\t%0 fmovd\t%1, %0 ldd\t%1, %0 std\t%1, %0 @@ -2041,9 +2161,9 @@ ldx\t%1, %0 stx\t%r1, %0 #" - [(set_attr "type" "fga,fpmove,load,store,*,load,store,*") - (set_attr "length" "*,*,*,*,*,*,*,2") - (set_attr "fptype" "double,double,*,*,*,*,*,*")]) + [(set_attr "type" "fga,fga,fpmove,load,store,*,load,store,*") + (set_attr "length" "*,*,*,*,*,*,*,*,2") + (set_attr "fptype" "double,double,double,*,*,*,*,*,*")]) (define_insn "*movdf_insn_sp64_no_fpu" [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m") @@ -2058,10 +2178,10 @@ stx\t%r1, %0" [(set_attr "type" "*,load,store")]) -;; This pattern builds V64mode constants in integer registers. +;; This pattern builds DFmode constants in integer registers. (define_split - [(set (match_operand:V64 0 "register_operand" "") - (match_operand:V64 1 "const_double_or_vector_operand" ""))] + [(set (match_operand:DF 0 "register_operand" "") + (match_operand:DF 1 "const_double_operand" ""))] "TARGET_FPU && (GET_CODE (operands[0]) == REG && REGNO (operands[0]) < 32) @@ -2115,8 +2235,8 @@ ;; careful when V9 but not ARCH64 because the integer ;; register DFmode cases must be handled. (define_split - [(set (match_operand:V64 0 "register_operand" "") - (match_operand:V64 1 "register_operand" ""))] + [(set (match_operand:DF 0 "register_operand" "") + (match_operand:DF 1 "register_operand" ""))] "(! TARGET_V9 || (! TARGET_ARCH64 && ((GET_CODE (operands[0]) == REG @@ -2131,18 +2251,11 @@ rtx set_src = operands[1]; rtx dest1, dest2; rtx src1, src2; - enum machine_mode half_mode; - /* We can be expanded for DFmode or integral vector modes. */ - if (mode == DFmode) - half_mode = SFmode; - else - half_mode = SImode; - - dest1 = gen_highpart (half_mode, set_dest); - dest2 = gen_lowpart (half_mode, set_dest); - src1 = gen_highpart (half_mode, set_src); - src2 = gen_lowpart (half_mode, set_src); + dest1 = gen_highpart (SFmode, set_dest); + dest2 = gen_lowpart (SFmode, set_dest); + src1 = gen_highpart (SFmode, set_src); + src2 = gen_lowpart (SFmode, set_src); /* Now emit using the real source and destination we found, swapping the order if we detect overlap. */ @@ -2160,8 +2273,8 @@ }) (define_split - [(set (match_operand:V64 0 "register_operand" "") - (match_operand:V64 1 "memory_operand" ""))] + [(set (match_operand:DF 0 "register_operand" "") + (match_operand:DF 1 "memory_operand" ""))] "reload_completed && ! TARGET_ARCH64 && (((REGNO (operands[0]) % 2) != 0) @@ -2169,34 +2282,27 @@ && offsettable_memref_p (operands[1])" [(clobber (const_int 0))] { - enum machine_mode half_mode; rtx word0, word1; - /* We can be expanded for DFmode or integral vector modes. */ - if (mode == DFmode) - half_mode = SFmode; - else - half_mode = SImode; - - word0 = adjust_address (operands[1], half_mode, 0); - word1 = adjust_address (operands[1], half_mode, 4); + word0 = adjust_address (operands[1], SFmode, 0); + word1 = adjust_address (operands[1], SFmode, 4); - if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1)) + if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1)) { - emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1); - emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0); + emit_move_insn_1 (gen_lowpart (SFmode, operands[0]), word1); + emit_move_insn_1 (gen_highpart (SFmode, operands[0]), word0); } else { - emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0); - emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1); + emit_move_insn_1 (gen_highpart (SFmode, operands[0]), word0); + emit_move_insn_1 (gen_lowpart (SFmode, operands[0]), word1); } DONE; }) (define_split - [(set (match_operand:V64 0 "memory_operand" "") - (match_operand:V64 1 "register_operand" ""))] + [(set (match_operand:DF 0 "memory_operand" "") + (match_operand:DF 1 "register_operand" ""))] "reload_completed && ! TARGET_ARCH64 && (((REGNO (operands[1]) % 2) != 0) @@ -2204,26 +2310,19 @@ && offsettable_memref_p (operands[0])" [(clobber (const_int 0))] { - enum machine_mode half_mode; rtx word0, word1; - /* We can be expanded for DFmode or integral vector modes. */ - if (mode == DFmode) - half_mode = SFmode; - else - half_mode = SImode; - - word0 = adjust_address (operands[0], half_mode, 0); - word1 = adjust_address (operands[0], half_mode, 4); + word0 = adjust_address (operands[0], SFmode, 0); + word1 = adjust_address (operands[0], SFmode, 4); - emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1])); - emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1])); + emit_move_insn_1 (word0, gen_highpart (SFmode, operands[1])); + emit_move_insn_1 (word1, gen_lowpart (SFmode, operands[1])); DONE; }) (define_split - [(set (match_operand:V64 0 "memory_operand" "") - (match_operand:V64 1 "const_zero_operand" ""))] + [(set (match_operand:DF 0 "memory_operand" "") + (match_operand:DF 1 "const_zero_operand" ""))] "reload_completed && (! TARGET_V9 || (! TARGET_ARCH64 @@ -2231,26 +2330,19 @@ && offsettable_memref_p (operands[0])" [(clobber (const_int 0))] { - enum machine_mode half_mode; rtx dest1, dest2; - /* We can be expanded for DFmode or integral vector modes. */ - if (mode == DFmode) - half_mode = SFmode; - else - half_mode = SImode; - - dest1 = adjust_address (operands[0], half_mode, 0); - dest2 = adjust_address (operands[0], half_mode, 4); + dest1 = adjust_address (operands[0], SFmode, 0); + dest2 = adjust_address (operands[0], SFmode, 4); - emit_move_insn_1 (dest1, CONST0_RTX (half_mode)); - emit_move_insn_1 (dest2, CONST0_RTX (half_mode)); + emit_move_insn_1 (dest1, CONST0_RTX (SFmode)); + emit_move_insn_1 (dest2, CONST0_RTX (SFmode)); DONE; }) (define_split - [(set (match_operand:V64 0 "register_operand" "") - (match_operand:V64 1 "const_zero_operand" ""))] + [(set (match_operand:DF 0 "register_operand" "") + (match_operand:DF 1 "const_zero_operand" ""))] "reload_completed && ! TARGET_ARCH64 && ((GET_CODE (operands[0]) == REG @@ -2260,20 +2352,13 @@ && REGNO (SUBREG_REG (operands[0])) < 32))" [(clobber (const_int 0))] { - enum machine_mode half_mode; rtx set_dest = operands[0]; rtx dest1, dest2; - /* We can be expanded for DFmode or integral vector modes. */ - if (mode == DFmode) - half_mode = SFmode; - else - half_mode = SImode; - - dest1 = gen_highpart (half_mode, set_dest); - dest2 = gen_lowpart (half_mode, set_dest); - emit_move_insn_1 (dest1, CONST0_RTX (half_mode)); - emit_move_insn_1 (dest2, CONST0_RTX (half_mode)); + dest1 = gen_highpart (SFmode, set_dest); + dest2 = gen_lowpart (SFmode, set_dest); + emit_move_insn_1 (dest1, CONST0_RTX (SFmode)); + emit_move_insn_1 (dest2, CONST0_RTX (SFmode)); DONE; }) @@ -2483,11 +2568,9 @@ (match_operand:I 3 "arith10_operand" "")))] "TARGET_V9 && !(mode == DImode && TARGET_ARCH32)" { - enum rtx_code code = GET_CODE (operands[1]); rtx cc_reg; - if (GET_MODE (XEXP (operands[1], 0)) == DImode - && ! TARGET_ARCH64) + if (GET_MODE (XEXP (operands[1], 0)) == DImode && !TARGET_ARCH64) FAIL; if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD) @@ -2498,12 +2581,14 @@ if (XEXP (operands[1], 1) == const0_rtx && GET_CODE (XEXP (operands[1], 0)) == REG && GET_MODE (XEXP (operands[1], 0)) == DImode - && v9_regcmp_p (code)) + && v9_regcmp_p (GET_CODE (operands[1]))) cc_reg = XEXP (operands[1], 0); else cc_reg = gen_compare_reg (operands[1]); - operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx); + operands[1] + = gen_rtx_fmt_ee (GET_CODE (operands[1]), GET_MODE (cc_reg), cc_reg, + const0_rtx); }) (define_expand "movcc" @@ -2513,11 +2598,9 @@ (match_operand:F 3 "register_operand" "")))] "TARGET_V9 && TARGET_FPU" { - enum rtx_code code = GET_CODE (operands[1]); rtx cc_reg; - if (GET_MODE (XEXP (operands[1], 0)) == DImode - && ! TARGET_ARCH64) + if (GET_MODE (XEXP (operands[1], 0)) == DImode && !TARGET_ARCH64) FAIL; if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD) @@ -2528,12 +2611,14 @@ if (XEXP (operands[1], 1) == const0_rtx && GET_CODE (XEXP (operands[1], 0)) == REG && GET_MODE (XEXP (operands[1], 0)) == DImode - && v9_regcmp_p (code)) + && v9_regcmp_p (GET_CODE (operands[1]))) cc_reg = XEXP (operands[1], 0); else cc_reg = gen_compare_reg (operands[1]); - operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx); + operands[1] + = gen_rtx_fmt_ee (GET_CODE (operands[1]), GET_MODE (cc_reg), cc_reg, + const0_rtx); }) ;; Conditional move define_insns @@ -2901,7 +2986,7 @@ ;; Simplify comparisons of extended values. (define_insn "*cmp_zero_extendqisi2" - [(set (reg:CC 100) + [(set (reg:CC CC_REG) (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r")) (const_int 0)))] "" @@ -2909,7 +2994,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_zero_qi" - [(set (reg:CC 100) + [(set (reg:CC CC_REG) (compare:CC (match_operand:QI 0 "register_operand" "r") (const_int 0)))] "" @@ -2917,7 +3002,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_zero_extendqisi2_set" - [(set (reg:CC 100) + [(set (reg:CC CC_REG) (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r")) (const_int 0))) (set (match_operand:SI 0 "register_operand" "=r") @@ -2927,7 +3012,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_zero_extendqisi2_andcc_set" - [(set (reg:CC 100) + [(set (reg:CC CC_REG) (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r") (const_int 255)) (const_int 0))) @@ -2938,7 +3023,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_zero_extendqidi2" - [(set (reg:CCX 100) + [(set (reg:CCX CC_REG) (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r")) (const_int 0)))] "TARGET_ARCH64" @@ -2946,7 +3031,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_zero_qi_sp64" - [(set (reg:CCX 100) + [(set (reg:CCX CC_REG) (compare:CCX (match_operand:QI 0 "register_operand" "r") (const_int 0)))] "TARGET_ARCH64" @@ -2954,7 +3039,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_zero_extendqidi2_set" - [(set (reg:CCX 100) + [(set (reg:CCX CC_REG) (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r")) (const_int 0))) (set (match_operand:DI 0 "register_operand" "=r") @@ -2964,7 +3049,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_zero_extendqidi2_andcc_set" - [(set (reg:CCX 100) + [(set (reg:CCX CC_REG) (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r") (const_int 255)) (const_int 0))) @@ -2977,7 +3062,7 @@ ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare. (define_insn "*cmp_siqi_trunc" - [(set (reg:CC 100) + [(set (reg:CC CC_REG) (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3) (const_int 0)))] "" @@ -2985,7 +3070,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_siqi_trunc_set" - [(set (reg:CC 100) + [(set (reg:CC CC_REG) (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3) (const_int 0))) (set (match_operand:QI 0 "register_operand" "=r") @@ -2995,7 +3080,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_diqi_trunc" - [(set (reg:CC 100) + [(set (reg:CC CC_REG) (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7) (const_int 0)))] "TARGET_ARCH64" @@ -3003,7 +3088,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_diqi_trunc_set" - [(set (reg:CC 100) + [(set (reg:CC CC_REG) (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7) (const_int 0))) (set (match_operand:QI 0 "register_operand" "=r") @@ -3204,7 +3289,7 @@ ;; because combine uses this as a canonical form. (define_insn "*cmp_zero_extract" - [(set (reg:CC 100) + [(set (reg:CC CC_REG) (compare:CC (zero_extract:SI (match_operand:SI 0 "register_operand" "r") (match_operand:SI 1 "small_int_operand" "I") @@ -3221,7 +3306,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_zero_extract_sp64" - [(set (reg:CCX 100) + [(set (reg:CCX CC_REG) (compare:CCX (zero_extract:DI (match_operand:DI 0 "register_operand" "r") (match_operand:SI 1 "small_int_operand" "I") @@ -3517,11 +3602,11 @@ [(set (match_operand:DI 0 "register_operand" "=r") (plus:DI (match_operand:DI 1 "arith_double_operand" "%r") (match_operand:DI 2 "arith_double_operand" "rHI"))) - (clobber (reg:CC 100))] + (clobber (reg:CC CC_REG))] "! TARGET_ARCH64" "#" "&& reload_completed" - [(parallel [(set (reg:CC_NOOV 100) + [(parallel [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (plus:SI (match_dup 4) (match_dup 5)) (const_int 0))) @@ -3530,7 +3615,7 @@ (set (match_dup 6) (plus:SI (plus:SI (match_dup 7) (match_dup 8)) - (ltu:SI (reg:CC_NOOV 100) (const_int 0))))] + (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))] { operands[3] = gen_lowpart (SImode, operands[0]); operands[4] = gen_lowpart (SImode, operands[1]); @@ -3556,7 +3641,7 @@ [(set (match_operand:SI 0 "register_operand" "=r") (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r") (match_operand:SI 2 "arith_operand" "rI")) - (ltu:SI (reg:CC_NOOV 100) (const_int 0))))] + (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))] "" "addx\t%1, %2, %0" [(set_attr "type" "ialuX")]) @@ -3566,12 +3651,12 @@ (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ") (match_operand:SI 2 "arith_operand" "rI")) - (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))] + (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))] "! TARGET_ARCH64" "#" "&& reload_completed" [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2)) - (ltu:SI (reg:CC_NOOV 100) (const_int 0)))) + (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))) (set (match_dup 4) (const_int 0))] "operands[3] = gen_lowpart (SImode, operands[0]); operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);" @@ -3581,7 +3666,7 @@ [(set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ") (match_operand:SI 2 "arith_operand" "rI")) - (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))] + (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))] "TARGET_ARCH64" "addx\t%r1, %2, %0" [(set_attr "type" "ialuX")]) @@ -3590,17 +3675,17 @@ [(set (match_operand:DI 0 "register_operand" "=r") (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) (match_operand:DI 2 "register_operand" "r"))) - (clobber (reg:CC 100))] + (clobber (reg:CC CC_REG))] "! TARGET_ARCH64" "#" "&& reload_completed" - [(parallel [(set (reg:CC_NOOV 100) + [(parallel [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1)) (const_int 0))) (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))]) (set (match_dup 6) (plus:SI (plus:SI (match_dup 4) (const_int 0)) - (ltu:SI (reg:CC_NOOV 100) (const_int 0))))] + (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))] "operands[3] = gen_lowpart (SImode, operands[2]); operands[4] = gen_highpart (SImode, operands[2]); operands[5] = gen_lowpart (SImode, operands[0]); @@ -3617,19 +3702,18 @@ sub\t%1, -%2, %0") (define_insn "addsi3" - [(set (match_operand:SI 0 "register_operand" "=r,r,d") - (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d") - (match_operand:SI 2 "arith_add_operand" "rI,O,d")))] + [(set (match_operand:SI 0 "register_operand" "=r,r") + (plus:SI (match_operand:SI 1 "register_operand" "%r,r") + (match_operand:SI 2 "arith_add_operand" "rI,O")))] "" "@ add\t%1, %2, %0 - sub\t%1, -%2, %0 - fpadd32s\t%1, %2, %0" - [(set_attr "type" "*,*,fga") - (set_attr "fptype" "*,*,single")]) + sub\t%1, -%2, %0" + [(set_attr "type" "*,*") + (set_attr "fptype" "*,*")]) (define_insn "*cmp_cc_plus" - [(set (reg:CC_NOOV 100) + [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r") (match_operand:SI 1 "arith_operand" "rI")) (const_int 0)))] @@ -3638,7 +3722,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_ccx_plus" - [(set (reg:CCX_NOOV 100) + [(set (reg:CCX_NOOV CC_REG) (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r") (match_operand:DI 1 "arith_operand" "rI")) (const_int 0)))] @@ -3647,7 +3731,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_cc_plus_set" - [(set (reg:CC_NOOV 100) + [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r") (match_operand:SI 2 "arith_operand" "rI")) (const_int 0))) @@ -3658,7 +3742,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_ccx_plus_set" - [(set (reg:CCX_NOOV 100) + [(set (reg:CCX_NOOV CC_REG) (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r") (match_operand:DI 2 "arith_operand" "rI")) (const_int 0))) @@ -3690,11 +3774,11 @@ [(set (match_operand:DI 0 "register_operand" "=r") (minus:DI (match_operand:DI 1 "register_operand" "r") (match_operand:DI 2 "arith_double_operand" "rHI"))) - (clobber (reg:CC 100))] + (clobber (reg:CC CC_REG))] "! TARGET_ARCH64" "#" "&& reload_completed" - [(parallel [(set (reg:CC_NOOV 100) + [(parallel [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (match_dup 4) (match_dup 5)) (const_int 0))) @@ -3703,7 +3787,7 @@ (set (match_dup 6) (minus:SI (minus:SI (match_dup 7) (match_dup 8)) - (ltu:SI (reg:CC_NOOV 100) (const_int 0))))] + (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))] { operands[3] = gen_lowpart (SImode, operands[0]); operands[4] = gen_lowpart (SImode, operands[1]); @@ -3729,7 +3813,7 @@ [(set (match_operand:SI 0 "register_operand" "=r") (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") (match_operand:SI 2 "arith_operand" "rI")) - (ltu:SI (reg:CC_NOOV 100) (const_int 0))))] + (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))] "" "subx\t%r1, %2, %0" [(set_attr "type" "ialuX")]) @@ -3738,7 +3822,7 @@ [(set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") (match_operand:SI 2 "arith_operand" "rI")) - (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))] + (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))] "TARGET_ARCH64" "subx\t%r1, %2, %0" [(set_attr "type" "ialuX")]) @@ -3747,12 +3831,12 @@ [(set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") (match_operand:SI 2 "arith_operand" "rI")) - (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))] + (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))] "! TARGET_ARCH64" "#" "&& reload_completed" [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2)) - (ltu:SI (reg:CC_NOOV 100) (const_int 0)))) + (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))) (set (match_dup 4) (const_int 0))] "operands[3] = gen_lowpart (SImode, operands[0]); operands[4] = gen_highpart (SImode, operands[0]);" @@ -3762,17 +3846,17 @@ [(set (match_operand:DI 0 "register_operand" "=r") (minus:DI (match_operand:DI 1 "register_operand" "r") (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))) - (clobber (reg:CC 100))] + (clobber (reg:CC CC_REG))] "! TARGET_ARCH64" "#" "&& reload_completed" - [(parallel [(set (reg:CC_NOOV 100) + [(parallel [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2)) (const_int 0))) (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))]) (set (match_dup 6) (minus:SI (minus:SI (match_dup 4) (const_int 0)) - (ltu:SI (reg:CC_NOOV 100) (const_int 0))))] + (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))] "operands[3] = gen_lowpart (SImode, operands[1]); operands[4] = gen_highpart (SImode, operands[1]); operands[5] = gen_lowpart (SImode, operands[0]); @@ -3789,19 +3873,18 @@ add\t%1, -%2, %0") (define_insn "subsi3" - [(set (match_operand:SI 0 "register_operand" "=r,r,d") - (minus:SI (match_operand:SI 1 "register_operand" "r,r,d") - (match_operand:SI 2 "arith_add_operand" "rI,O,d")))] + [(set (match_operand:SI 0 "register_operand" "=r,r") + (minus:SI (match_operand:SI 1 "register_operand" "r,r") + (match_operand:SI 2 "arith_add_operand" "rI,O")))] "" "@ sub\t%1, %2, %0 - add\t%1, -%2, %0 - fpsub32s\t%1, %2, %0" - [(set_attr "type" "*,*,fga") - (set_attr "fptype" "*,*,single")]) + add\t%1, -%2, %0" + [(set_attr "type" "*,*") + (set_attr "fptype" "*,*")]) (define_insn "*cmp_minus_cc" - [(set (reg:CC_NOOV 100) + [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ") (match_operand:SI 1 "arith_operand" "rI")) (const_int 0)))] @@ -3810,7 +3893,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_minus_ccx" - [(set (reg:CCX_NOOV 100) + [(set (reg:CCX_NOOV CC_REG) (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r") (match_operand:DI 1 "arith_operand" "rI")) (const_int 0)))] @@ -3819,7 +3902,7 @@ [(set_attr "type" "compare")]) (define_insn "cmp_minus_cc_set" - [(set (reg:CC_NOOV 100) + [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") (match_operand:SI 2 "arith_operand" "rI")) (const_int 0))) @@ -3830,7 +3913,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_minus_ccx_set" - [(set (reg:CCX_NOOV 100) + [(set (reg:CCX_NOOV CC_REG) (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r") (match_operand:DI 2 "arith_operand" "rI")) (const_int 0))) @@ -3884,37 +3967,12 @@ (clobber (match_scratch:SI 3 "=&h,X")) (clobber (match_scratch:SI 4 "=&h,X"))] "TARGET_V8PLUS" -{ - if (sparc_check_64 (operands[1], insn) <= 0) - output_asm_insn ("srl\t%L1, 0, %L1", operands); - if (which_alternative == 1) - output_asm_insn ("sllx\t%H1, 32, %H1", operands); - if (GET_CODE (operands[2]) == CONST_INT) - { - if (which_alternative == 1) - return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0"; - else - return "sllx\t%H1, 32, %3\n\tor\t%L1, %3, %3\n\tmulx\t%3, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"; - } - else if (rtx_equal_p (operands[1], operands[2])) - { - if (which_alternative == 1) - return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0"; - else - return "sllx\t%H1, 32, %3\n\tor\t%L1, %3, %3\n\tmulx\t%3, %3, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"; - } - if (sparc_check_64 (operands[2], insn) <= 0) - output_asm_insn ("srl\t%L2, 0, %L2", operands); - if (which_alternative == 1) - return "or\t%L1, %H1, %H1\n\tsllx\t%H2, 32, %L1\n\tor\t%L2, %L1, %L1\n\tmulx\t%H1, %L1, %L0\;srlx\t%L0, 32, %H0"; - else - return "sllx\t%H1, 32, %3\n\tsllx\t%H2, 32, %4\n\tor\t%L1, %3, %3\n\tor\t%L2, %4, %4\n\tmulx\t%3, %4, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"; -} + "* return output_v8plus_mult (insn, operands, \"mulx\");" [(set_attr "type" "multi") (set_attr "length" "9,8")]) (define_insn "*cmp_mul_set" - [(set (reg:CC 100) + [(set (reg:CC CC_REG) (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r") (match_operand:SI 2 "arith_operand" "rI")) (const_int 0))) @@ -4398,7 +4456,7 @@ [(set_attr "type" "idiv")]) (define_insn "*cmp_sdiv_cc_set" - [(set (reg:CC 100) + [(set (reg:CC CC_REG) (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r") (match_operand:SI 2 "arith_operand" "rI")) (const_int 0))) @@ -4489,7 +4547,7 @@ [(set_attr "type" "idiv")]) (define_insn "*cmp_udiv_cc_set" - [(set (reg:CC 100) + [(set (reg:CC CC_REG) (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r") (match_operand:SI 2 "arith_operand" "rI")) (const_int 0))) @@ -4548,46 +4606,33 @@ ;; We define DImode `and' so with DImode `not' we can get ;; DImode `andn'. Other combinations are possible. -(define_expand "and3" - [(set (match_operand:V64I 0 "register_operand" "") - (and:V64I (match_operand:V64I 1 "arith_double_operand" "") - (match_operand:V64I 2 "arith_double_operand" "")))] +(define_expand "anddi3" + [(set (match_operand:DI 0 "register_operand" "") + (and:DI (match_operand:DI 1 "arith_double_operand" "") + (match_operand:DI 2 "arith_double_operand" "")))] "" "") -(define_insn "*and3_sp32" - [(set (match_operand:V64I 0 "register_operand" "=r,b") - (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b") - (match_operand:V64I 2 "arith_double_operand" "rHI,b")))] +(define_insn "*anddi3_sp32" + [(set (match_operand:DI 0 "register_operand" "=r") + (and:DI (match_operand:DI 1 "arith_double_operand" "%r") + (match_operand:DI 2 "arith_double_operand" "rHI")))] "! TARGET_ARCH64" - "@ - # - fand\t%1, %2, %0" - [(set_attr "type" "*,fga") - (set_attr "length" "2,*") - (set_attr "fptype" "*,double")]) - -(define_insn "*and3_sp64" - [(set (match_operand:V64I 0 "register_operand" "=r,b") - (and:V64I (match_operand:V64I 1 "arith_operand" "%r,b") - (match_operand:V64I 2 "arith_operand" "rI,b")))] + "#") + +(define_insn "*anddi3_sp64" + [(set (match_operand:DI 0 "register_operand" "=r") + (and:DI (match_operand:DI 1 "arith_operand" "%r") + (match_operand:DI 2 "arith_operand" "rI")))] "TARGET_ARCH64" - "@ - and\t%1, %2, %0 - fand\t%1, %2, %0" - [(set_attr "type" "*,fga") - (set_attr "fptype" "*,double")]) + "and\t%1, %2, %0") -(define_insn "and3" - [(set (match_operand:V32I 0 "register_operand" "=r,d") - (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d") - (match_operand:V32I 2 "arith_operand" "rI,d")))] +(define_insn "andsi3" + [(set (match_operand:SI 0 "register_operand" "=r") + (and:SI (match_operand:SI 1 "arith_operand" "%r") + (match_operand:SI 2 "arith_operand" "rI")))] "" - "@ - and\t%1, %2, %0 - fands\t%1, %2, %0" - [(set_attr "type" "*,fga") - (set_attr "fptype" "*,single")]) + "and\t%1, %2, %0") (define_split [(set (match_operand:SI 0 "register_operand" "") @@ -4601,14 +4646,12 @@ operands[4] = GEN_INT (~INTVAL (operands[2])); }) -(define_insn_and_split "*and_not__sp32" - [(set (match_operand:V64I 0 "register_operand" "=r,b") - (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b")) - (match_operand:V64I 2 "register_operand" "r,b")))] +(define_insn_and_split "*and_not_di_sp32" + [(set (match_operand:DI 0 "register_operand" "=r") + (and:DI (not:DI (match_operand:DI 1 "register_operand" "%r")) + (match_operand:DI 2 "register_operand" "r")))] "! TARGET_ARCH64" - "@ - # - fandnot1\t%1, %2, %0" + "#" "&& reload_completed && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) < 32) @@ -4623,72 +4666,50 @@ operands[6] = gen_lowpart (SImode, operands[0]); operands[7] = gen_lowpart (SImode, operands[1]); operands[8] = gen_lowpart (SImode, operands[2]);" - [(set_attr "type" "*,fga") - (set_attr "length" "2,*") - (set_attr "fptype" "*,double")]) - -(define_insn "*and_not__sp64" - [(set (match_operand:V64I 0 "register_operand" "=r,b") - (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b")) - (match_operand:V64I 2 "register_operand" "r,b")))] + [(set_attr "length" "2")]) + +(define_insn "*and_not_di_sp64" + [(set (match_operand:DI 0 "register_operand" "=r") + (and:DI (not:DI (match_operand:DI 1 "register_operand" "%r")) + (match_operand:DI 2 "register_operand" "r")))] "TARGET_ARCH64" - "@ - andn\t%2, %1, %0 - fandnot1\t%1, %2, %0" - [(set_attr "type" "*,fga") - (set_attr "fptype" "*,double")]) + "andn\t%2, %1, %0") -(define_insn "*and_not_" - [(set (match_operand:V32I 0 "register_operand" "=r,d") - (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d")) - (match_operand:V32I 2 "register_operand" "r,d")))] +(define_insn "*and_not_si" + [(set (match_operand:SI 0 "register_operand" "=r") + (and:SI (not:SI (match_operand:SI 1 "register_operand" "%r")) + (match_operand:SI 2 "register_operand" "r")))] "" - "@ - andn\t%2, %1, %0 - fandnot1s\t%1, %2, %0" - [(set_attr "type" "*,fga") - (set_attr "fptype" "*,single")]) + "andn\t%2, %1, %0") -(define_expand "ior3" - [(set (match_operand:V64I 0 "register_operand" "") - (ior:V64I (match_operand:V64I 1 "arith_double_operand" "") - (match_operand:V64I 2 "arith_double_operand" "")))] +(define_expand "iordi3" + [(set (match_operand:DI 0 "register_operand" "") + (ior:DI (match_operand:DI 1 "arith_double_operand" "") + (match_operand:DI 2 "arith_double_operand" "")))] "" "") -(define_insn "*ior3_sp32" - [(set (match_operand:V64I 0 "register_operand" "=r,b") - (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b") - (match_operand:V64I 2 "arith_double_operand" "rHI,b")))] +(define_insn "*iordi3_sp32" + [(set (match_operand:DI 0 "register_operand" "=r") + (ior:DI (match_operand:DI 1 "arith_double_operand" "%r") + (match_operand:DI 2 "arith_double_operand" "rHI")))] "! TARGET_ARCH64" - "@ - # - for\t%1, %2, %0" - [(set_attr "type" "*,fga") - (set_attr "length" "2,*") - (set_attr "fptype" "*,double")]) - -(define_insn "*ior3_sp64" - [(set (match_operand:V64I 0 "register_operand" "=r,b") - (ior:V64I (match_operand:V64I 1 "arith_operand" "%r,b") - (match_operand:V64I 2 "arith_operand" "rI,b")))] + "#" + [(set_attr "length" "2")]) + +(define_insn "*iordi3_sp64" + [(set (match_operand:DI 0 "register_operand" "=r") + (ior:DI (match_operand:DI 1 "arith_operand" "%r") + (match_operand:DI 2 "arith_operand" "rI")))] "TARGET_ARCH64" - "@ - or\t%1, %2, %0 - for\t%1, %2, %0" - [(set_attr "type" "*,fga") - (set_attr "fptype" "*,double")]) + "or\t%1, %2, %0") -(define_insn "ior3" - [(set (match_operand:V32I 0 "register_operand" "=r,d") - (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d") - (match_operand:V32I 2 "arith_operand" "rI,d")))] +(define_insn "iorsi3" + [(set (match_operand:SI 0 "register_operand" "=r") + (ior:SI (match_operand:SI 1 "arith_operand" "%r") + (match_operand:SI 2 "arith_operand" "rI")))] "" - "@ - or\t%1, %2, %0 - fors\t%1, %2, %0" - [(set_attr "type" "*,fga") - (set_attr "fptype" "*,single")]) + "or\t%1, %2, %0") (define_split [(set (match_operand:SI 0 "register_operand" "") @@ -4702,14 +4723,12 @@ operands[4] = GEN_INT (~INTVAL (operands[2])); }) -(define_insn_and_split "*or_not__sp32" - [(set (match_operand:V64I 0 "register_operand" "=r,b") - (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b")) - (match_operand:V64I 2 "register_operand" "r,b")))] +(define_insn_and_split "*or_not_di_sp32" + [(set (match_operand:DI 0 "register_operand" "=r") + (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r")) + (match_operand:DI 2 "register_operand" "r")))] "! TARGET_ARCH64" - "@ - # - fornot1\t%1, %2, %0" + "#" "&& reload_completed && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) < 32) @@ -4724,72 +4743,50 @@ operands[6] = gen_lowpart (SImode, operands[0]); operands[7] = gen_lowpart (SImode, operands[1]); operands[8] = gen_lowpart (SImode, operands[2]);" - [(set_attr "type" "*,fga") - (set_attr "length" "2,*") - (set_attr "fptype" "*,double")]) - -(define_insn "*or_not__sp64" - [(set (match_operand:V64I 0 "register_operand" "=r,b") - (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b")) - (match_operand:V64I 2 "register_operand" "r,b")))] + [(set_attr "length" "2")]) + +(define_insn "*or_not_di_sp64" + [(set (match_operand:DI 0 "register_operand" "=r") + (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r")) + (match_operand:DI 2 "register_operand" "r")))] "TARGET_ARCH64" - "@ - orn\t%2, %1, %0 - fornot1\t%1, %2, %0" - [(set_attr "type" "*,fga") - (set_attr "fptype" "*,double")]) + "orn\t%2, %1, %0") -(define_insn "*or_not_" - [(set (match_operand:V32I 0 "register_operand" "=r,d") - (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d")) - (match_operand:V32I 2 "register_operand" "r,d")))] +(define_insn "*or_not_si" + [(set (match_operand:SI 0 "register_operand" "=r") + (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r")) + (match_operand:SI 2 "register_operand" "r")))] "" - "@ - orn\t%2, %1, %0 - fornot1s\t%1, %2, %0" - [(set_attr "type" "*,fga") - (set_attr "fptype" "*,single")]) + "orn\t%2, %1, %0") -(define_expand "xor3" - [(set (match_operand:V64I 0 "register_operand" "") - (xor:V64I (match_operand:V64I 1 "arith_double_operand" "") - (match_operand:V64I 2 "arith_double_operand" "")))] +(define_expand "xordi3" + [(set (match_operand:DI 0 "register_operand" "") + (xor:DI (match_operand:DI 1 "arith_double_operand" "") + (match_operand:DI 2 "arith_double_operand" "")))] "" "") -(define_insn "*xor3_sp32" - [(set (match_operand:V64I 0 "register_operand" "=r,b") - (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b") - (match_operand:V64I 2 "arith_double_operand" "rHI,b")))] +(define_insn "*xordi3_sp32" + [(set (match_operand:DI 0 "register_operand" "=r") + (xor:DI (match_operand:DI 1 "arith_double_operand" "%r") + (match_operand:DI 2 "arith_double_operand" "rHI")))] "! TARGET_ARCH64" - "@ - # - fxor\t%1, %2, %0" - [(set_attr "type" "*,fga") - (set_attr "length" "2,*") - (set_attr "fptype" "*,double")]) - -(define_insn "*xor3_sp64" - [(set (match_operand:V64I 0 "register_operand" "=r,b") - (xor:V64I (match_operand:V64I 1 "arith_operand" "%rJ,b") - (match_operand:V64I 2 "arith_operand" "rI,b")))] + "#" + [(set_attr "length" "2")]) + +(define_insn "*xordi3_sp64" + [(set (match_operand:DI 0 "register_operand" "=r") + (xor:DI (match_operand:DI 1 "arith_operand" "%rJ") + (match_operand:DI 2 "arith_operand" "rI")))] "TARGET_ARCH64" - "@ - xor\t%r1, %2, %0 - fxor\t%1, %2, %0" - [(set_attr "type" "*,fga") - (set_attr "fptype" "*,double")]) + "xor\t%r1, %2, %0") -(define_insn "xor3" - [(set (match_operand:V32I 0 "register_operand" "=r,d") - (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d") - (match_operand:V32I 2 "arith_operand" "rI,d")))] +(define_insn "xorsi3" + [(set (match_operand:SI 0 "register_operand" "=r") + (xor:SI (match_operand:SI 1 "arith_operand" "%rJ") + (match_operand:SI 2 "arith_operand" "rI")))] "" - "@ - xor\t%r1, %2, %0 - fxors\t%1, %2, %0" - [(set_attr "type" "*,fga") - (set_attr "fptype" "*,single")]) + "xor\t%r1, %2, %0") (define_split [(set (match_operand:SI 0 "register_operand" "") @@ -4817,10 +4814,10 @@ ;; Split DImode logical operations requiring two instructions. (define_split - [(set (match_operand:V64I 0 "register_operand" "") - (match_operator:V64I 1 "cc_arith_operator" ; AND, IOR, XOR - [(match_operand:V64I 2 "register_operand" "") - (match_operand:V64I 3 "arith_double_operand" "")]))] + [(set (match_operand:DI 0 "register_operand" "") + (match_operator:DI 1 "cc_arith_operator" ; AND, IOR, XOR + [(match_operand:DI 2 "register_operand" "") + (match_operand:DI 3 "arith_double_operand" "")]))] "! TARGET_ARCH64 && reload_completed && ((GET_CODE (operands[0]) == REG @@ -4836,7 +4833,7 @@ operands[6] = gen_highpart (SImode, operands[2]); operands[7] = gen_lowpart (SImode, operands[2]); #if HOST_BITS_PER_WIDE_INT == 32 - if (GET_CODE (operands[3]) == CONST_INT && mode == DImode) + if (GET_CODE (operands[3]) == CONST_INT) { if (INTVAL (operands[3]) < 0) operands[8] = constm1_rtx; @@ -4845,20 +4842,18 @@ } else #endif - operands[8] = gen_highpart_mode (SImode, mode, operands[3]); + operands[8] = gen_highpart_mode (SImode, DImode, operands[3]); operands[9] = gen_lowpart (SImode, operands[3]); }) ;; xnor patterns. Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b). ;; Combine now canonicalizes to the rightmost expression. -(define_insn_and_split "*xor_not__sp32" - [(set (match_operand:V64I 0 "register_operand" "=r,b") - (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b") - (match_operand:V64I 2 "register_operand" "r,b"))))] +(define_insn_and_split "*xor_not_di_sp32" + [(set (match_operand:DI 0 "register_operand" "=r") + (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r") + (match_operand:DI 2 "register_operand" "r"))))] "! TARGET_ARCH64" - "@ - # - fxnor\t%1, %2, %0" + "#" "&& reload_completed && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) < 32) @@ -4873,37 +4868,27 @@ operands[6] = gen_lowpart (SImode, operands[0]); operands[7] = gen_lowpart (SImode, operands[1]); operands[8] = gen_lowpart (SImode, operands[2]);" - [(set_attr "type" "*,fga") - (set_attr "length" "2,*") - (set_attr "fptype" "*,double")]) - -(define_insn "*xor_not__sp64" - [(set (match_operand:V64I 0 "register_operand" "=r,b") - (not:V64I (xor:V64I (match_operand:V64I 1 "register_or_zero_operand" "rJ,b") - (match_operand:V64I 2 "arith_operand" "rI,b"))))] + [(set_attr "length" "2")]) + +(define_insn "*xor_not_di_sp64" + [(set (match_operand:DI 0 "register_operand" "=r") + (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "rJ") + (match_operand:DI 2 "arith_operand" "rI"))))] "TARGET_ARCH64" - "@ - xnor\t%r1, %2, %0 - fxnor\t%1, %2, %0" - [(set_attr "type" "*,fga") - (set_attr "fptype" "*,double")]) + "xnor\t%r1, %2, %0") -(define_insn "*xor_not_" - [(set (match_operand:V32I 0 "register_operand" "=r,d") - (not:V32I (xor:V32I (match_operand:V32I 1 "register_or_zero_operand" "rJ,d") - (match_operand:V32I 2 "arith_operand" "rI,d"))))] +(define_insn "*xor_not_si" + [(set (match_operand:SI 0 "register_operand" "=r") + (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") + (match_operand:SI 2 "arith_operand" "rI"))))] "" - "@ - xnor\t%r1, %2, %0 - fxnors\t%1, %2, %0" - [(set_attr "type" "*,fga") - (set_attr "fptype" "*,single")]) + "xnor\t%r1, %2, %0") ;; These correspond to the above in the case where we also (or only) ;; want to set the condition code. (define_insn "*cmp_cc_arith_op" - [(set (reg:CC 100) + [(set (reg:CC CC_REG) (compare:CC (match_operator:SI 2 "cc_arith_operator" [(match_operand:SI 0 "arith_operand" "%r") @@ -4914,7 +4899,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_ccx_arith_op" - [(set (reg:CCX 100) + [(set (reg:CCX CC_REG) (compare:CCX (match_operator:DI 2 "cc_arith_operator" [(match_operand:DI 0 "arith_operand" "%r") @@ -4925,7 +4910,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_cc_arith_op_set" - [(set (reg:CC 100) + [(set (reg:CC CC_REG) (compare:CC (match_operator:SI 3 "cc_arith_operator" [(match_operand:SI 1 "arith_operand" "%r") @@ -4938,7 +4923,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_ccx_arith_op_set" - [(set (reg:CCX 100) + [(set (reg:CCX CC_REG) (compare:CCX (match_operator:DI 3 "cc_arith_operator" [(match_operand:DI 1 "arith_operand" "%r") @@ -4951,7 +4936,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_cc_xor_not" - [(set (reg:CC 100) + [(set (reg:CC CC_REG) (compare:CC (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ") (match_operand:SI 1 "arith_operand" "rI"))) @@ -4961,7 +4946,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_ccx_xor_not" - [(set (reg:CCX 100) + [(set (reg:CCX CC_REG) (compare:CCX (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ") (match_operand:DI 1 "arith_operand" "rI"))) @@ -4971,7 +4956,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_cc_xor_not_set" - [(set (reg:CC 100) + [(set (reg:CC CC_REG) (compare:CC (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ") (match_operand:SI 2 "arith_operand" "rI"))) @@ -4983,7 +4968,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_ccx_xor_not_set" - [(set (reg:CCX 100) + [(set (reg:CCX CC_REG) (compare:CCX (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ") (match_operand:DI 2 "arith_operand" "rI"))) @@ -4995,7 +4980,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_cc_arith_op_not" - [(set (reg:CC 100) + [(set (reg:CC CC_REG) (compare:CC (match_operator:SI 2 "cc_arith_not_operator" [(not:SI (match_operand:SI 0 "arith_operand" "rI")) @@ -5006,7 +4991,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_ccx_arith_op_not" - [(set (reg:CCX 100) + [(set (reg:CCX CC_REG) (compare:CCX (match_operator:DI 2 "cc_arith_not_operator" [(not:DI (match_operand:DI 0 "arith_operand" "rI")) @@ -5017,7 +5002,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_cc_arith_op_not_set" - [(set (reg:CC 100) + [(set (reg:CC CC_REG) (compare:CC (match_operator:SI 3 "cc_arith_not_operator" [(not:SI (match_operand:SI 1 "arith_operand" "rI")) @@ -5031,7 +5016,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_ccx_arith_op_not_set" - [(set (reg:CCX 100) + [(set (reg:CCX CC_REG) (compare:CCX (match_operator:DI 3 "cc_arith_not_operator" [(not:DI (match_operand:DI 1 "arith_operand" "rI")) @@ -5069,16 +5054,16 @@ (define_insn_and_split "*negdi2_sp32" [(set (match_operand:DI 0 "register_operand" "=r") (neg:DI (match_operand:DI 1 "register_operand" "r"))) - (clobber (reg:CC 100))] + (clobber (reg:CC CC_REG))] "! TARGET_ARCH64" "#" "&& reload_completed" - [(parallel [(set (reg:CC_NOOV 100) + [(parallel [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5)) (const_int 0))) (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))]) (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3)) - (ltu:SI (reg:CC 100) (const_int 0))))] + (ltu:SI (reg:CC CC_REG) (const_int 0))))] "operands[2] = gen_highpart (SImode, operands[0]); operands[3] = gen_highpart (SImode, operands[1]); operands[4] = gen_lowpart (SImode, operands[0]); @@ -5098,7 +5083,7 @@ "sub\t%%g0, %1, %0") (define_insn "*cmp_cc_neg" - [(set (reg:CC_NOOV 100) + [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI")) (const_int 0)))] "" @@ -5106,7 +5091,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_ccx_neg" - [(set (reg:CCX_NOOV 100) + [(set (reg:CCX_NOOV CC_REG) (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI")) (const_int 0)))] "TARGET_ARCH64" @@ -5114,7 +5099,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_cc_set_neg" - [(set (reg:CC_NOOV 100) + [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI")) (const_int 0))) (set (match_operand:SI 0 "register_operand" "=r") @@ -5124,7 +5109,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_ccx_set_neg" - [(set (reg:CCX_NOOV 100) + [(set (reg:CCX_NOOV CC_REG) (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI")) (const_int 0))) (set (match_operand:DI 0 "register_operand" "=r") @@ -5135,19 +5120,17 @@ ;; We cannot use the "not" pseudo insn because the Sun assembler ;; does not know how to make it work for constants. -(define_expand "one_cmpl2" - [(set (match_operand:V64I 0 "register_operand" "") - (not:V64I (match_operand:V64I 1 "register_operand" "")))] +(define_expand "one_cmpldi2" + [(set (match_operand:DI 0 "register_operand" "") + (not:DI (match_operand:DI 1 "register_operand" "")))] "" "") -(define_insn_and_split "*one_cmpl2_sp32" - [(set (match_operand:V64I 0 "register_operand" "=r,b") - (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))] +(define_insn_and_split "*one_cmpldi2_sp32" + [(set (match_operand:DI 0 "register_operand" "=r") + (not:DI (match_operand:DI 1 "register_operand" "r")))] "! TARGET_ARCH64" - "@ - # - fnot1\t%1, %0" + "#" "&& reload_completed && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) < 32) @@ -5160,32 +5143,22 @@ operands[3] = gen_highpart (SImode, operands[1]); operands[4] = gen_lowpart (SImode, operands[0]); operands[5] = gen_lowpart (SImode, operands[1]);" - [(set_attr "type" "*,fga") - (set_attr "length" "2,*") - (set_attr "fptype" "*,double")]) + [(set_attr "length" "2")]) -(define_insn "*one_cmpl2_sp64" - [(set (match_operand:V64I 0 "register_operand" "=r,b") - (not:V64I (match_operand:V64I 1 "arith_operand" "rI,b")))] +(define_insn "*one_cmpldi2_sp64" + [(set (match_operand:DI 0 "register_operand" "=r") + (not:DI (match_operand:DI 1 "arith_operand" "rI")))] "TARGET_ARCH64" - "@ - xnor\t%%g0, %1, %0 - fnot1\t%1, %0" - [(set_attr "type" "*,fga") - (set_attr "fptype" "*,double")]) + "xnor\t%%g0, %1, %0") -(define_insn "one_cmpl2" - [(set (match_operand:V32I 0 "register_operand" "=r,d") - (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))] +(define_insn "one_cmplsi2" + [(set (match_operand:SI 0 "register_operand" "=r") + (not:SI (match_operand:SI 1 "arith_operand" "rI")))] "" - "@ - xnor\t%%g0, %1, %0 - fnot1s\t%1, %0" - [(set_attr "type" "*,fga") - (set_attr "fptype" "*,single")]) + "xnor\t%%g0, %1, %0") (define_insn "*cmp_cc_not" - [(set (reg:CC 100) + [(set (reg:CC CC_REG) (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI")) (const_int 0)))] "" @@ -5193,7 +5166,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_ccx_not" - [(set (reg:CCX 100) + [(set (reg:CCX CC_REG) (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI")) (const_int 0)))] "TARGET_ARCH64" @@ -5201,7 +5174,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_cc_set_not" - [(set (reg:CC 100) + [(set (reg:CC CC_REG) (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI")) (const_int 0))) (set (match_operand:SI 0 "register_operand" "=r") @@ -5211,7 +5184,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_ccx_set_not" - [(set (reg:CCX 100) + [(set (reg:CCX CC_REG) (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI")) (const_int 0))) (set (match_operand:DI 0 "register_operand" "=r") @@ -5223,7 +5196,7 @@ (define_insn "*cmp_cc_set" [(set (match_operand:SI 0 "register_operand" "=r") (match_operand:SI 1 "register_operand" "r")) - (set (reg:CC 100) + (set (reg:CC CC_REG) (compare:CC (match_dup 1) (const_int 0)))] "" @@ -5233,7 +5206,7 @@ (define_insn "*cmp_ccx_set64" [(set (match_operand:DI 0 "register_operand" "=r") (match_operand:DI 1 "register_operand" "r")) - (set (reg:CCX 100) + (set (reg:CCX CC_REG) (compare:CCX (match_dup 1) (const_int 0)))] "TARGET_ARCH64" @@ -5339,6 +5312,78 @@ "fmuls\t%1, %2, %0" [(set_attr "type" "fpmul")]) +(define_insn "fmadf4" + [(set (match_operand:DF 0 "register_operand" "=e") + (fma:DF (match_operand:DF 1 "register_operand" "e") + (match_operand:DF 2 "register_operand" "e") + (match_operand:DF 3 "register_operand" "e")))] + "TARGET_FMAF" + "fmaddd\t%1, %2, %3, %0" + [(set_attr "type" "fpmul")]) + +(define_insn "fmsdf4" + [(set (match_operand:DF 0 "register_operand" "=e") + (fma:DF (match_operand:DF 1 "register_operand" "e") + (match_operand:DF 2 "register_operand" "e") + (neg:DF (match_operand:DF 3 "register_operand" "e"))))] + "TARGET_FMAF" + "fmsubd\t%1, %2, %3, %0" + [(set_attr "type" "fpmul")]) + +(define_insn "*nfmadf4" + [(set (match_operand:DF 0 "register_operand" "=e") + (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e") + (match_operand:DF 2 "register_operand" "e") + (match_operand:DF 3 "register_operand" "e"))))] + "TARGET_FMAF" + "fnmaddd\t%1, %2, %3, %0" + [(set_attr "type" "fpmul")]) + +(define_insn "*nfmsdf4" + [(set (match_operand:DF 0 "register_operand" "=e") + (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e") + (match_operand:DF 2 "register_operand" "e") + (neg:DF (match_operand:DF 3 "register_operand" "e")))))] + "TARGET_FMAF" + "fnmsubd\t%1, %2, %3, %0" + [(set_attr "type" "fpmul")]) + +(define_insn "fmasf4" + [(set (match_operand:SF 0 "register_operand" "=f") + (fma:SF (match_operand:SF 1 "register_operand" "f") + (match_operand:SF 2 "register_operand" "f") + (match_operand:SF 3 "register_operand" "f")))] + "TARGET_FMAF" + "fmadds\t%1, %2, %3, %0" + [(set_attr "type" "fpmul")]) + +(define_insn "fmssf4" + [(set (match_operand:SF 0 "register_operand" "=f") + (fma:SF (match_operand:SF 1 "register_operand" "f") + (match_operand:SF 2 "register_operand" "f") + (neg:SF (match_operand:SF 3 "register_operand" "f"))))] + "TARGET_FMAF" + "fmsubs\t%1, %2, %3, %0" + [(set_attr "type" "fpmul")]) + +(define_insn "*nfmasf4" + [(set (match_operand:SF 0 "register_operand" "=f") + (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f") + (match_operand:SF 2 "register_operand" "f") + (match_operand:SF 3 "register_operand" "f"))))] + "TARGET_FMAF" + "fnmadds\t%1, %2, %3, %0" + [(set_attr "type" "fpmul")]) + +(define_insn "*nfmssf4" + [(set (match_operand:SF 0 "register_operand" "=f") + (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f") + (match_operand:SF 2 "register_operand" "f") + (neg:SF (match_operand:SF 3 "register_operand" "f")))))] + "TARGET_FMAF" + "fnmsubs\t%1, %2, %3, %0" + [(set_attr "type" "fpmul")]) + (define_insn "*muldf3_extend" [(set (match_operand:DF 0 "register_operand" "=e") (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f")) @@ -5614,9 +5659,20 @@ operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); return "sll\t%1, %2, %0"; } - [(set (attr "type") - (if_then_else (match_operand 2 "const_one_operand" "") - (const_string "ialu") (const_string "shift")))]) + [(set_attr "type" "shift")]) + +(define_insn "*ashlsi3_extend" + [(set (match_operand:DI 0 "register_operand" "=r") + (zero_extend:DI + (ashift:SI (match_operand:SI 1 "register_operand" "r") + (match_operand:SI 2 "arith_operand" "rI"))))] + "TARGET_ARCH64" +{ + if (GET_CODE (operands[2]) == CONST_INT) + operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); + return "sll\t%1, %2, %0"; +} + [(set_attr "type" "shift")]) (define_expand "ashldi3" [(set (match_operand:DI 0 "register_operand" "=r") @@ -5643,9 +5699,7 @@ operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f); return "sllx\t%1, %2, %0"; } - [(set (attr "type") - (if_then_else (match_operand 2 "const_one_operand" "") - (const_string "ialu") (const_string "shift")))]) + [(set_attr "type" "shift")]) ;; XXX UGH! (define_insn "ashldi3_v8plus" @@ -5676,7 +5730,7 @@ ; (set_attr "length" "4")]) (define_insn "*cmp_cc_ashift_1" - [(set (reg:CC_NOOV 100) + [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r") (const_int 1)) (const_int 0)))] @@ -5685,7 +5739,7 @@ [(set_attr "type" "compare")]) (define_insn "*cmp_cc_set_ashift_1" - [(set (reg:CC_NOOV 100) + [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r") (const_int 1)) (const_int 0))) @@ -5780,10 +5834,23 @@ } [(set_attr "type" "shift")]) +(define_insn "*lshrsi3_extend0" + [(set (match_operand:DI 0 "register_operand" "=r") + (zero_extend:DI + (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") + (match_operand:SI 2 "arith_operand" "rI"))))] + "TARGET_ARCH64" + { + if (GET_CODE (operands[2]) == CONST_INT) + operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); + return "srl\t%1, %2, %0"; + } + [(set_attr "type" "shift")]) + ;; This handles the case where ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))), ;; but combiner "simplifies" it for us. -(define_insn "*lshrsi3_extend" +(define_insn "*lshrsi3_extend1" [(set (match_operand:DI 0 "register_operand" "=r") (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") (match_operand:SI 2 "arith_operand" "r")) 0) @@ -6022,7 +6089,7 @@ (define_insn "*call_address_sp32" [(call (mem:SI (match_operand:SI 0 "address_operand" "p")) (match_operand 1 "" "")) - (clobber (reg:SI 15))] + (clobber (reg:SI O7_REG))] ;;- Do not use operand 1 for most machines. "! TARGET_ARCH64" "call\t%a0, %1%#" @@ -6031,7 +6098,7 @@ (define_insn "*call_symbolic_sp32" [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s")) (match_operand 1 "" "")) - (clobber (reg:SI 15))] + (clobber (reg:SI O7_REG))] ;;- Do not use operand 1 for most machines. "! TARGET_ARCH64" "call\t%a0, %1%#" @@ -6040,7 +6107,7 @@ (define_insn "*call_address_sp64" [(call (mem:DI (match_operand:DI 0 "address_operand" "p")) (match_operand 1 "" "")) - (clobber (reg:DI 15))] + (clobber (reg:DI O7_REG))] ;;- Do not use operand 1 for most machines. "TARGET_ARCH64" "call\t%a0, %1%#" @@ -6049,7 +6116,7 @@ (define_insn "*call_symbolic_sp64" [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s")) (match_operand 1 "" "")) - (clobber (reg:DI 15))] + (clobber (reg:DI O7_REG))] ;;- Do not use operand 1 for most machines. "TARGET_ARCH64" "call\t%a0, %1%#" @@ -6061,7 +6128,7 @@ [(call (mem:SI (match_operand:SI 0 "address_operand" "p")) (match_operand 1 "" "")) (match_operand 2 "immediate_operand" "") - (clobber (reg:SI 15))] + (clobber (reg:SI O7_REG))] ;;- Do not use operand 1 for most machines. "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0" { @@ -6077,7 +6144,7 @@ [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s")) (match_operand 1 "" "")) (match_operand 2 "immediate_operand" "") - (clobber (reg:SI 15))] + (clobber (reg:SI O7_REG))] ;;- Do not use operand 1 for most machines. "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0" { @@ -6093,7 +6160,7 @@ [(call (mem:SI (match_operand:SI 0 "address_operand" "p")) (match_operand 1 "" "")) (match_operand 2 "immediate_operand" "") - (clobber (reg:SI 15))] + (clobber (reg:SI O7_REG))] ;;- Do not use operand 1 for most machines. "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0" "call\t%a0, %1\n\t nop\n\tnop" @@ -6106,7 +6173,7 @@ [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s")) (match_operand 1 "" "")) (match_operand 2 "immediate_operand" "") - (clobber (reg:SI 15))] + (clobber (reg:SI O7_REG))] ;;- Do not use operand 1 for most machines. "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0" "call\t%a0, %1\n\t nop\n\tnop" @@ -6144,7 +6211,7 @@ [(set (match_operand 0 "" "=rf") (call (mem:SI (match_operand:SI 1 "address_operand" "p")) (match_operand 2 "" ""))) - (clobber (reg:SI 15))] + (clobber (reg:SI O7_REG))] ;;- Do not use operand 2 for most machines. "! TARGET_ARCH64" "call\t%a1, %2%#" @@ -6154,7 +6221,7 @@ [(set (match_operand 0 "" "=rf") (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s")) (match_operand 2 "" ""))) - (clobber (reg:SI 15))] + (clobber (reg:SI O7_REG))] ;;- Do not use operand 2 for most machines. "! TARGET_ARCH64" "call\t%a1, %2%#" @@ -6164,7 +6231,7 @@ [(set (match_operand 0 "" "") (call (mem:DI (match_operand:DI 1 "address_operand" "p")) (match_operand 2 "" ""))) - (clobber (reg:DI 15))] + (clobber (reg:DI O7_REG))] ;;- Do not use operand 2 for most machines. "TARGET_ARCH64" "call\t%a1, %2%#" @@ -6174,7 +6241,7 @@ [(set (match_operand 0 "" "") (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s")) (match_operand 2 "" ""))) - (clobber (reg:DI 15))] + (clobber (reg:DI O7_REG))] ;;- Do not use operand 2 for most machines. "TARGET_ARCH64" "call\t%a1, %2%#" @@ -6265,24 +6332,21 @@ [(const_int 0)] "" { - sparc_expand_prologue (); + if (TARGET_FLAT) + sparc_flat_expand_prologue (); + else + sparc_expand_prologue (); DONE; }) -;; The "save register window" insn is modelled as follows so that the DWARF-2 -;; backend automatically emits the required call frame debugging information -;; while it is parsing it. Therefore, the pattern should not be modified -;; without first studying the impact of the changes on the debug info. -;; [(set (%fp) (%sp)) -;; (set (%sp) (unspec_volatile [(%sp) (-frame_size)] UNSPECV_SAVEW)) -;; (set (%i7) (%o7))] +;; The "register window save" insn is modelled as follows. The dwarf2 +;; information is manually added in emit_window_save. -(define_insn "save_register_window" - [(set (reg:P 30) (reg:P 14)) - (set (reg:P 14) (unspec_volatile:P [(reg:P 14) - (match_operand:P 0 "arith_operand" "rI")] UNSPECV_SAVEW)) - (set (reg:P 31) (reg:P 15))] - "" +(define_insn "window_save" + [(unspec_volatile + [(match_operand 0 "arith_operand" "rI")] + UNSPECV_SAVEW)] + "!TARGET_FLAT" "save\t%%sp, %0, %%sp" [(set_attr "type" "savew")]) @@ -6290,17 +6354,46 @@ [(return)] "" { - sparc_expand_epilogue (); + if (TARGET_FLAT) + sparc_flat_expand_epilogue (false); + else + sparc_expand_epilogue (false); }) (define_expand "sibcall_epilogue" [(return)] "" { - sparc_expand_epilogue (); + if (TARGET_FLAT) + sparc_flat_expand_epilogue (false); + else + sparc_expand_epilogue (false); + DONE; +}) + +(define_expand "eh_return" + [(use (match_operand 0 "general_operand" ""))] + "" +{ + emit_move_insn (gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM), operands[0]); + emit_jump_insn (gen_eh_return_internal ()); + emit_barrier (); DONE; }) +(define_insn_and_split "eh_return_internal" + [(eh_return)] + "" + "#" + "epilogue_completed" + [(return)] +{ + if (TARGET_FLAT) + sparc_flat_expand_epilogue (true); + else + sparc_expand_epilogue (true); +}) + (define_expand "return" [(return)] "sparc_can_use_return_insn_p ()" @@ -6312,16 +6405,19 @@ "* return output_return (insn);" [(set_attr "type" "return") (set (attr "length") - (cond [(eq_attr "leaf_function" "true") + (cond [(eq_attr "calls_eh_return" "true") + (if_then_else (eq_attr "delayed_branch" "true") + (if_then_else (ior (eq_attr "isa" "v9") + (eq_attr "flat" "true")) + (const_int 2) + (const_int 3)) + (if_then_else (eq_attr "flat" "true") + (const_int 3) + (const_int 4))) + (ior (eq_attr "leaf_function" "true") (eq_attr "flat" "true")) (if_then_else (eq_attr "empty_delay_slot" "true") (const_int 2) (const_int 1)) - (eq_attr "calls_eh_return" "true") - (if_then_else (eq_attr "delayed_branch" "true") - (if_then_else (eq_attr "isa" "v9") - (const_int 2) - (const_int 3)) - (const_int 4)) (eq_attr "empty_delay_slot" "true") (if_then_else (eq_attr "delayed_branch" "true") (const_int 2) @@ -6367,8 +6463,7 @@ if (! TARGET_ARCH64) { - rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs - ? 15 : 31)); + rtx rtnreg = gen_rtx_REG (SImode, RETURN_ADDR_REGNUM); rtx value = gen_reg_rtx (SImode); /* Fetch the instruction where we will return to and see if it's an unimp @@ -6449,7 +6544,7 @@ { operands[0] = adjust_address_nv (operands[0], Pmode, 0); operands[2] = adjust_address_nv (operands[0], Pmode, GET_MODE_SIZE (Pmode)); - operands[3] = gen_rtx_REG (Pmode, 31); /* %i7 */ + operands[3] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM); }) (define_expand "restore_stack_nonlocal" @@ -6474,7 +6569,8 @@ /* We need to flush all the register windows so that their contents will be re-synchronized by the restore insn of the target function. */ - emit_insn (gen_flush_register_windows ()); + if (!TARGET_FLAT) + emit_insn (gen_flush_register_windows ()); emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode))); emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx)); @@ -6575,57 +6671,178 @@ [(set_attr "type" "multi") (set_attr "length" "8")]) -;; ??? This should be a define expand, so that the extra instruction have -;; a chance of being optimized away. - -;; Disabled because none of the UltraSPARCs implement popc. The HAL R1 -;; does, but no one uses that and we don't have a switch for it. -; -;(define_insn "ffsdi2" -; [(set (match_operand:DI 0 "register_operand" "=&r") -; (ffs:DI (match_operand:DI 1 "register_operand" "r"))) -; (clobber (match_scratch:DI 2 "=&r"))] -; "TARGET_ARCH64" -; "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0" -; [(set_attr "type" "multi") -; (set_attr "length" "4")]) +(define_expand "popcountdi2" + [(set (match_operand:DI 0 "register_operand" "") + (popcount:DI (match_operand:DI 1 "register_operand" "")))] + "TARGET_POPC" +{ + if (! TARGET_ARCH64) + { + emit_insn (gen_popcountdi_v8plus (operands[0], operands[1])); + DONE; + } +}) +(define_insn "*popcountdi_sp64" + [(set (match_operand:DI 0 "register_operand" "=r") + (popcount:DI (match_operand:DI 1 "register_operand" "r")))] + "TARGET_POPC && TARGET_ARCH64" + "popc\t%1, %0") - -;; Peepholes go at the end. +(define_insn "popcountdi_v8plus" + [(set (match_operand:DI 0 "register_operand" "=r") + (popcount:DI (match_operand:DI 1 "register_operand" "r"))) + (clobber (match_scratch:SI 2 "=&h"))] + "TARGET_POPC && ! TARGET_ARCH64" +{ + if (sparc_check_64 (operands[1], insn) <= 0) + output_asm_insn ("srl\t%L1, 0, %L1", operands); + return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tpopc\t%2, %L0\n\tclr\t%H0"; +} + [(set_attr "type" "multi") + (set_attr "length" "5")]) -;; Optimize consecutive loads or stores into ldd and std when possible. -;; The conditions in which we do this are very restricted and are -;; explained in the code for {registers,memory}_ok_for_ldd functions. +(define_expand "popcountsi2" + [(set (match_dup 2) + (zero_extend:DI (match_operand:SI 1 "register_operand" ""))) + (set (match_operand:SI 0 "register_operand" "") + (truncate:SI (popcount:DI (match_dup 2))))] + "TARGET_POPC" +{ + if (! TARGET_ARCH64) + { + emit_insn (gen_popcountsi_v8plus (operands[0], operands[1])); + DONE; + } + else + operands[2] = gen_reg_rtx (DImode); +}) -(define_peephole2 - [(set (match_operand:SI 0 "memory_operand" "") - (const_int 0)) - (set (match_operand:SI 1 "memory_operand" "") - (const_int 0))] - "TARGET_V9 - && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)" - [(set (match_dup 0) - (const_int 0))] - "operands[0] = widen_memory_access (operands[0], DImode, 0);") +(define_insn "*popcountsi_sp64" + [(set (match_operand:SI 0 "register_operand" "=r") + (truncate:SI + (popcount:DI (match_operand:DI 1 "register_operand" "r"))))] + "TARGET_POPC && TARGET_ARCH64" + "popc\t%1, %0") -(define_peephole2 - [(set (match_operand:SI 0 "memory_operand" "") - (const_int 0)) - (set (match_operand:SI 1 "memory_operand" "") - (const_int 0))] - "TARGET_V9 - && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)" - [(set (match_dup 1) - (const_int 0))] - "operands[1] = widen_memory_access (operands[1], DImode, 0);") +(define_insn "popcountsi_v8plus" + [(set (match_operand:SI 0 "register_operand" "=r") + (popcount:SI (match_operand:SI 1 "register_operand" "r")))] + "TARGET_POPC && ! TARGET_ARCH64" +{ + if (sparc_check_64 (operands[1], insn) <= 0) + output_asm_insn ("srl\t%1, 0, %1", operands); + return "popc\t%1, %0"; +} + [(set_attr "type" "multi") + (set_attr "length" "2")]) -(define_peephole2 - [(set (match_operand:SI 0 "register_operand" "") - (match_operand:SI 1 "memory_operand" "")) - (set (match_operand:SI 2 "register_operand" "") - (match_operand:SI 3 "memory_operand" ""))] - "registers_ok_for_ldd_peep (operands[0], operands[2]) +(define_expand "clzdi2" + [(set (match_operand:DI 0 "register_operand" "") + (clz:DI (match_operand:DI 1 "register_operand" "")))] + "TARGET_VIS3" +{ + if (! TARGET_ARCH64) + { + emit_insn (gen_clzdi_v8plus (operands[0], operands[1])); + DONE; + } +}) + +(define_insn "*clzdi_sp64" + [(set (match_operand:DI 0 "register_operand" "=r") + (clz:DI (match_operand:DI 1 "register_operand" "r")))] + "TARGET_VIS3 && TARGET_ARCH64" + "lzd\t%1, %0") + +(define_insn "clzdi_v8plus" + [(set (match_operand:DI 0 "register_operand" "=r") + (clz:DI (match_operand:DI 1 "register_operand" "r"))) + (clobber (match_scratch:SI 2 "=&h"))] + "TARGET_VIS3 && ! TARGET_ARCH64" +{ + if (sparc_check_64 (operands[1], insn) <= 0) + output_asm_insn ("srl\t%L1, 0, %L1", operands); + return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tlzd\t%2, %L0\n\tclr\t%H0"; +} + [(set_attr "type" "multi") + (set_attr "length" "5")]) + +(define_expand "clzsi2" + [(set (match_dup 2) + (zero_extend:DI (match_operand:SI 1 "register_operand" ""))) + (set (match_dup 3) + (truncate:SI (clz:DI (match_dup 2)))) + (set (match_operand:SI 0 "register_operand" "") + (minus:SI (match_dup 3) (const_int 32)))] + "TARGET_VIS3" +{ + if (! TARGET_ARCH64) + { + emit_insn (gen_clzsi_v8plus (operands[0], operands[1])); + DONE; + } + else + { + operands[2] = gen_reg_rtx (DImode); + operands[3] = gen_reg_rtx (SImode); + } +}) + +(define_insn "*clzsi_sp64" + [(set (match_operand:SI 0 "register_operand" "=r") + (truncate:SI + (clz:DI (match_operand:DI 1 "register_operand" "r"))))] + "TARGET_VIS3 && TARGET_ARCH64" + "lzd\t%1, %0") + +(define_insn "clzsi_v8plus" + [(set (match_operand:SI 0 "register_operand" "=r") + (clz:SI (match_operand:SI 1 "register_operand" "r")))] + "TARGET_VIS3 && ! TARGET_ARCH64" +{ + if (sparc_check_64 (operands[1], insn) <= 0) + output_asm_insn ("srl\t%1, 0, %1", operands); + return "lzd\t%1, %0\n\tsub\t%0, 32, %0"; +} + [(set_attr "type" "multi") + (set_attr "length" "3")]) + + +;; Peepholes go at the end. + +;; Optimize consecutive loads or stores into ldd and std when possible. +;; The conditions in which we do this are very restricted and are +;; explained in the code for {registers,memory}_ok_for_ldd functions. + +(define_peephole2 + [(set (match_operand:SI 0 "memory_operand" "") + (const_int 0)) + (set (match_operand:SI 1 "memory_operand" "") + (const_int 0))] + "TARGET_V9 + && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)" + [(set (match_dup 0) + (const_int 0))] + "operands[0] = widen_memory_access (operands[0], DImode, 0);") + +(define_peephole2 + [(set (match_operand:SI 0 "memory_operand" "") + (const_int 0)) + (set (match_operand:SI 1 "memory_operand" "") + (const_int 0))] + "TARGET_V9 + && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)" + [(set (match_dup 1) + (const_int 0))] + "operands[1] = widen_memory_access (operands[1], DImode, 0);") + +(define_peephole2 + [(set (match_operand:SI 0 "register_operand" "") + (match_operand:SI 1 "memory_operand" "")) + (set (match_operand:SI 2 "register_operand" "") + (match_operand:SI 3 "memory_operand" ""))] + "registers_ok_for_ldd_peep (operands[0], operands[2]) && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])" [(set (match_dup 0) (match_dup 1))] @@ -6724,7 +6941,7 @@ (define_peephole2 [(set (match_operand:SI 0 "register_operand" "") (match_operand:SI 1 "register_operand" "")) - (set (reg:CC 100) + (set (reg:CC CC_REG) (compare:CC (match_operand:SI 2 "register_operand" "") (const_int 0)))] "(rtx_equal_p (operands[2], operands[0]) @@ -6732,14 +6949,14 @@ && ! SPARC_FP_REG_P (REGNO (operands[0])) && ! SPARC_FP_REG_P (REGNO (operands[1]))" [(parallel [(set (match_dup 0) (match_dup 1)) - (set (reg:CC 100) + (set (reg:CC CC_REG) (compare:CC (match_dup 1) (const_int 0)))])] "") (define_peephole2 [(set (match_operand:DI 0 "register_operand" "") (match_operand:DI 1 "register_operand" "")) - (set (reg:CCX 100) + (set (reg:CCX CC_REG) (compare:CCX (match_operand:DI 2 "register_operand" "") (const_int 0)))] "TARGET_ARCH64 @@ -6748,7 +6965,7 @@ && ! SPARC_FP_REG_P (REGNO (operands[0])) && ! SPARC_FP_REG_P (REGNO (operands[1]))" [(parallel [(set (match_dup 0) (match_dup 1)) - (set (reg:CCX 100) + (set (reg:CCX CC_REG) (compare:CCX (match_dup 1) (const_int 0)))])] "") @@ -6855,7 +7072,7 @@ (define_insn "" - [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC 100) (const_int 0)]) + [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC CC_REG) (const_int 0)]) (match_operand:SI 1 "arith_operand" "rM"))] "" { @@ -6867,7 +7084,7 @@ [(set_attr "type" "trap")]) (define_insn "" - [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX 100) (const_int 0)]) + [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX CC_REG) (const_int 0)]) (match_operand:SI 1 "arith_operand" "rM"))] "TARGET_V9" "t%C0\t%%xcc, %1" @@ -6915,7 +7132,7 @@ (match_operand 2 "tgd_symbolic_operand" "")] UNSPEC_TLSGD)) (match_operand 3 "" ""))) - (clobber (reg:SI 15))] + (clobber (reg:SI O7_REG))] "TARGET_TLS && TARGET_ARCH32" "call\t%a1, %%tgd_call(%a2)%#" [(set_attr "type" "call")]) @@ -6926,7 +7143,7 @@ (match_operand 2 "tgd_symbolic_operand" "")] UNSPEC_TLSGD)) (match_operand 3 "" ""))) - (clobber (reg:DI 15))] + (clobber (reg:DI O7_REG))] "TARGET_TLS && TARGET_ARCH64" "call\t%a1, %%tgd_call(%a2)%#" [(set_attr "type" "call")]) @@ -6965,7 +7182,7 @@ (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")] UNSPEC_TLSLDM)) (match_operand 2 "" ""))) - (clobber (reg:SI 15))] + (clobber (reg:SI O7_REG))] "TARGET_TLS && TARGET_ARCH32" "call\t%a1, %%tldm_call(%&)%#" [(set_attr "type" "call")]) @@ -6975,7 +7192,7 @@ (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")] UNSPEC_TLSLDM)) (match_operand 2 "" ""))) - (clobber (reg:DI 15))] + (clobber (reg:DI O7_REG))] "TARGET_TLS && TARGET_ARCH64" "call\t%a1, %%tldm_call(%&)%#" [(set_attr "type" "call")]) @@ -7506,7 +7723,7 @@ }) (define_insn "stack_protect_testsi" - [(set (reg:CC 100) + [(set (reg:CC CC_REG) (unspec:CC [(match_operand:SI 0 "memory_operand" "m") (match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_TEST)) @@ -7528,95 +7745,202 @@ [(set_attr "type" "multi") (set_attr "length" "4")]) - ;; Vector instructions. -(define_insn "addv2si3" - [(set (match_operand:V2SI 0 "register_operand" "=e") - (plus:V2SI (match_operand:V2SI 1 "register_operand" "e") - (match_operand:V2SI 2 "register_operand" "e")))] +(define_mode_iterator VM32 [V1SI V2HI V4QI]) +(define_mode_iterator VM64 [V1DI V2SI V4HI V8QI]) +(define_mode_iterator VMALL [V1SI V2HI V4QI V1DI V2SI V4HI V8QI]) + +(define_mode_attr vbits [(V2SI "32") (V4HI "16") (V1SI "32s") (V2HI "16s")]) +(define_mode_attr vconstr [(V1SI "f") (V2HI "f") (V4QI "f") + (V1DI "e") (V2SI "e") (V4HI "e") (V8QI "e")]) +(define_mode_attr vfptype [(V1SI "single") (V2HI "single") (V4QI "single") + (V1DI "double") (V2SI "double") (V4HI "double") + (V8QI "double")]) + +(define_expand "mov" + [(set (match_operand:VMALL 0 "nonimmediate_operand" "") + (match_operand:VMALL 1 "general_operand" ""))] "TARGET_VIS" - "fpadd32\t%1, %2, %0" - [(set_attr "type" "fga") - (set_attr "fptype" "double")]) +{ + if (sparc_expand_move (mode, operands)) + DONE; +}) -(define_insn "addv4hi3" - [(set (match_operand:V4HI 0 "register_operand" "=e") - (plus:V4HI (match_operand:V4HI 1 "register_operand" "e") - (match_operand:V4HI 2 "register_operand" "e")))] +(define_insn "*mov_insn" + [(set (match_operand:VM32 0 "nonimmediate_operand" "=f, f,f,f,m, m,r,m, r, r") + (match_operand:VM32 1 "input_operand" "GY,ZC,f,m,f,GY,m,r,GY,ZC"))] + "TARGET_VIS + && (register_operand (operands[0], mode) + || register_or_zero_or_all_ones_operand (operands[1], mode))" + "@ + fzeros\t%0 + fones\t%0 + fsrc1s\t%1, %0 + ld\t%1, %0 + st\t%1, %0 + st\t%r1, %0 + ld\t%1, %0 + st\t%1, %0 + mov\t0, %0 + mov\t-1, %0" + [(set_attr "type" "fga,fga,fga,fpload,fpstore,store,load,store,*,*")]) + +(define_insn "*mov_insn_sp64" + [(set (match_operand:VM64 0 "nonimmediate_operand" "=e, e,e,e,m, m,r,m, r, r") + (match_operand:VM64 1 "input_operand" "GY,ZC,e,m,e,GY,m,r,GY,ZC"))] + "TARGET_VIS + && TARGET_ARCH64 + && (register_operand (operands[0], mode) + || register_or_zero_or_all_ones_operand (operands[1], mode))" + "@ + fzero\t%0 + fone\t%0 + fsrc1\t%1, %0 + ldd\t%1, %0 + std\t%1, %0 + stx\t%r1, %0 + ldx\t%1, %0 + stx\t%1, %0 + mov\t0, %0 + mov\t-1, %0" + [(set_attr "type" "fga,fga,fga,fpload,fpstore,store,load,store,*,*")]) + +(define_insn "*mov_insn_sp32" + [(set (match_operand:VM64 0 "nonimmediate_operand" "=e, e,e,e,m, m,U,T,o, r, r") + (match_operand:VM64 1 "input_operand" "GY,ZC,e,m,e,GY,T,U,r,GY,ZC"))] + "TARGET_VIS + && ! TARGET_ARCH64 + && (register_operand (operands[0], mode) + || register_or_zero_or_all_ones_operand (operands[1], mode))" + "@ + fzero\t%0 + fone\t%0 + fsrc1\t%1, %0 + ldd\t%1, %0 + std\t%1, %0 + stx\t%r1, %0 + ldd\t%1, %0 + std\t%1, %0 + # + mov 0, %L0; mov 0, %H0 + mov -1, %L0; mov -1, %H0" + [(set_attr "type" "fga,fga,fga,fpload,fpstore,store,load,store,*,*,*") + (set_attr "length" "*,*,*,*,*,*,*,*,2,2,2")]) + +(define_split + [(set (match_operand:VM64 0 "memory_operand" "") + (match_operand:VM64 1 "register_operand" ""))] + "reload_completed + && TARGET_VIS + && ! TARGET_ARCH64 + && (((REGNO (operands[1]) % 2) != 0) + || ! mem_min_alignment (operands[0], 8)) + && offsettable_memref_p (operands[0])" + [(clobber (const_int 0))] +{ + rtx word0, word1; + + word0 = adjust_address (operands[0], SImode, 0); + word1 = adjust_address (operands[0], SImode, 4); + + emit_move_insn_1 (word0, gen_highpart (SImode, operands[1])); + emit_move_insn_1 (word1, gen_lowpart (SImode, operands[1])); + DONE; +}) + +(define_expand "vec_init" + [(match_operand:VMALL 0 "register_operand" "") + (match_operand:VMALL 1 "" "")] "TARGET_VIS" - "fpadd16\t%1, %2, %0" - [(set_attr "type" "fga") - (set_attr "fptype" "double")]) +{ + sparc_expand_vector_init (operands[0], operands[1]); + DONE; +}) -;; fpadd32s is emitted by the addsi3 pattern. +(define_code_iterator plusminus [plus minus]) +(define_code_attr plusminus_insn [(plus "add") (minus "sub")]) -(define_insn "addv2hi3" - [(set (match_operand:V2HI 0 "register_operand" "=f") - (plus:V2HI (match_operand:V2HI 1 "register_operand" "f") - (match_operand:V2HI 2 "register_operand" "f")))] +(define_mode_iterator VADDSUB [V1SI V2SI V2HI V4HI]) + +(define_insn "3" + [(set (match_operand:VADDSUB 0 "register_operand" "=") + (plusminus:VADDSUB (match_operand:VADDSUB 1 "register_operand" "") + (match_operand:VADDSUB 2 "register_operand" "")))] "TARGET_VIS" - "fpadd16s\t%1, %2, %0" + "fp\t%1, %2, %0" [(set_attr "type" "fga") - (set_attr "fptype" "single")]) - -(define_insn "subv2si3" - [(set (match_operand:V2SI 0 "register_operand" "=e") - (minus:V2SI (match_operand:V2SI 1 "register_operand" "e") - (match_operand:V2SI 2 "register_operand" "e")))] + (set_attr "fptype" "")]) + +(define_mode_iterator VL [V1SI V2HI V4QI V1DI V2SI V4HI V8QI]) +(define_mode_attr vlsuf [(V1SI "s") (V2HI "s") (V4QI "s") + (V1DI "") (V2SI "") (V4HI "") (V8QI "")]) +(define_code_iterator vlop [ior and xor]) +(define_code_attr vlinsn [(ior "or") (and "and") (xor "xor")]) +(define_code_attr vlninsn [(ior "nor") (and "nand") (xor "xnor")]) + +(define_insn "3" + [(set (match_operand:VL 0 "register_operand" "=") + (vlop:VL (match_operand:VL 1 "register_operand" "") + (match_operand:VL 2 "register_operand" "")))] "TARGET_VIS" - "fpsub32\t%1, %2, %0" + "f\t%1, %2, %0" [(set_attr "type" "fga") - (set_attr "fptype" "double")]) + (set_attr "fptype" "")]) -(define_insn "subv4hi3" - [(set (match_operand:V4HI 0 "register_operand" "=e") - (minus:V4HI (match_operand:V4HI 1 "register_operand" "e") - (match_operand:V4HI 2 "register_operand" "e")))] +(define_insn "*not_3" + [(set (match_operand:VL 0 "register_operand" "=") + (not:VL (vlop:VL (match_operand:VL 1 "register_operand" "") + (match_operand:VL 2 "register_operand" ""))))] "TARGET_VIS" - "fpsub16\t%1, %2, %0" + "f\t%1, %2, %0" [(set_attr "type" "fga") - (set_attr "fptype" "double")]) - -;; fpsub32s is emitted by the subsi3 pattern. + (set_attr "fptype" "")]) -(define_insn "subv2hi3" - [(set (match_operand:V2HI 0 "register_operand" "=f") - (minus:V2HI (match_operand:V2HI 1 "register_operand" "f") - (match_operand:V2HI 2 "register_operand" "f")))] +;; (ior (not (op1)) (not (op2))) is the canonical form of NAND. +(define_insn "*nand_vis" + [(set (match_operand:VL 0 "register_operand" "=") + (ior:VL (not:VL (match_operand:VL 1 "register_operand" "")) + (not:VL (match_operand:VL 2 "register_operand" ""))))] "TARGET_VIS" - "fpsub16s\t%1, %2, %0" + "fnand\t%1, %2, %0" [(set_attr "type" "fga") - (set_attr "fptype" "single")]) + (set_attr "fptype" "")]) -;; All other logical instructions have integer equivalents so they -;; are defined together. +(define_code_iterator vlnotop [ior and]) -;; (ior (not (op1)) (not (op2))) is the canonical form of NAND. +(define_insn "*_not1_vis" + [(set (match_operand:VL 0 "register_operand" "=") + (vlnotop:VL (not:VL (match_operand:VL 1 "register_operand" "")) + (match_operand:VL 2 "register_operand" "")))] + "TARGET_VIS" + "fnot1\t%1, %2, %0" + [(set_attr "type" "fga") + (set_attr "fptype" "")]) -(define_insn "*nand_vis" - [(set (match_operand:V64 0 "register_operand" "=e") - (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e")) - (not:V64 (match_operand:V64 2 "register_operand" "e"))))] +(define_insn "*_not2_vis" + [(set (match_operand:VL 0 "register_operand" "=") + (vlnotop:VL (match_operand:VL 1 "register_operand" "") + (not:VL (match_operand:VL 2 "register_operand" ""))))] "TARGET_VIS" - "fnand\t%1, %2, %0" + "fnot2\t%1, %2, %0" [(set_attr "type" "fga") - (set_attr "fptype" "double")]) + (set_attr "fptype" "")]) -(define_insn "*nand_vis" - [(set (match_operand:V32 0 "register_operand" "=f") - (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f")) - (not:V32 (match_operand:V32 2 "register_operand" "f"))))] +(define_insn "one_cmpl2" + [(set (match_operand:VL 0 "register_operand" "=") + (not:VL (match_operand:VL 1 "register_operand" "")))] "TARGET_VIS" - "fnands\t%1, %2, %0" + "fnot1\t%1, %0" [(set_attr "type" "fga") - (set_attr "fptype" "single")]) + (set_attr "fptype" "")]) ;; Hard to generate VIS instructions. We have builtins for these. (define_insn "fpack16_vis" [(set (match_operand:V4QI 0 "register_operand" "=f") - (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")] + (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e") + (reg:DI GSR_REG)] UNSPEC_FPACK16))] "TARGET_VIS" "fpack16\t%1, %0" @@ -7625,7 +7949,8 @@ (define_insn "fpackfix_vis" [(set (match_operand:V2HI 0 "register_operand" "=f") - (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")] + (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e") + (reg:DI GSR_REG)] UNSPEC_FPACKFIX))] "TARGET_VIS" "fpackfix\t%1, %0" @@ -7635,7 +7960,8 @@ (define_insn "fpack32_vis" [(set (match_operand:V8QI 0 "register_operand" "=e") (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e") - (match_operand:V8QI 2 "register_operand" "e")] + (match_operand:V8QI 2 "register_operand" "e") + (reg:DI GSR_REG)] UNSPEC_FPACK32))] "TARGET_VIS" "fpack32\t%1, %2, %0" @@ -7651,36 +7977,64 @@ [(set_attr "type" "fga") (set_attr "fptype" "double")]) -;; It may be possible to describe this operation as (1 indexed): -;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2))) -;; 1,5,10,14,19,23,28,32) -;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work -;; because vec_merge expects all the operands to be of the same type. (define_insn "fpmerge_vis" [(set (match_operand:V8QI 0 "register_operand" "=e") - (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f") - (match_operand:V4QI 2 "register_operand" "f")] - UNSPEC_FPMERGE))] + (vec_select:V8QI + (vec_concat:V8QI (match_operand:V4QI 1 "register_operand" "f") + (match_operand:V4QI 2 "register_operand" "f")) + (parallel [(const_int 0) (const_int 4) + (const_int 1) (const_int 5) + (const_int 2) (const_int 6) + (const_int 3) (const_int 7)])))] "TARGET_VIS" "fpmerge\t%1, %2, %0" [(set_attr "type" "fga") (set_attr "fptype" "double")]) +(define_insn "vec_interleave_lowv8qi" + [(set (match_operand:V8QI 0 "register_operand" "=e") + (vec_select:V8QI + (vec_concat:V16QI (match_operand:V8QI 1 "register_operand" "f") + (match_operand:V8QI 2 "register_operand" "f")) + (parallel [(const_int 0) (const_int 8) + (const_int 1) (const_int 9) + (const_int 2) (const_int 10) + (const_int 3) (const_int 11)])))] + "TARGET_VIS" + "fpmerge\t%L1, %L2, %0" + [(set_attr "type" "fga") + (set_attr "fptype" "double")]) + +(define_insn "vec_interleave_highv8qi" + [(set (match_operand:V8QI 0 "register_operand" "=e") + (vec_select:V8QI + (vec_concat:V16QI (match_operand:V8QI 1 "register_operand" "f") + (match_operand:V8QI 2 "register_operand" "f")) + (parallel [(const_int 4) (const_int 12) + (const_int 5) (const_int 13) + (const_int 6) (const_int 14) + (const_int 7) (const_int 15)])))] + "TARGET_VIS" + "fpmerge\t%H1, %H2, %0" + [(set_attr "type" "fga") + (set_attr "fptype" "double")]) + ;; Partitioned multiply instructions (define_insn "fmul8x16_vis" [(set (match_operand:V4HI 0 "register_operand" "=e") - (mult:V4HI (match_operand:V4QI 1 "register_operand" "f") - (match_operand:V4HI 2 "register_operand" "e")))] + (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f") + (match_operand:V4HI 2 "register_operand" "e")] + UNSPEC_MUL8))] "TARGET_VIS" "fmul8x16\t%1, %2, %0" [(set_attr "type" "fpmul") (set_attr "fptype" "double")]) -;; Only one of the following two insns can be a multiply. (define_insn "fmul8x16au_vis" [(set (match_operand:V4HI 0 "register_operand" "=e") - (mult:V4HI (match_operand:V4QI 1 "register_operand" "f") - (match_operand:V2HI 2 "register_operand" "f")))] + (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f") + (match_operand:V2HI 2 "register_operand" "f")] + UNSPEC_MUL16AU))] "TARGET_VIS" "fmul8x16au\t%1, %2, %0" [(set_attr "type" "fpmul") @@ -7696,11 +8050,11 @@ [(set_attr "type" "fpmul") (set_attr "fptype" "double")]) -;; Only one of the following two insns can be a multiply. (define_insn "fmul8sux16_vis" [(set (match_operand:V4HI 0 "register_operand" "=e") - (mult:V4HI (match_operand:V8QI 1 "register_operand" "e") - (match_operand:V4HI 2 "register_operand" "e")))] + (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e") + (match_operand:V4HI 2 "register_operand" "e")] + UNSPEC_MUL8SU))] "TARGET_VIS" "fmul8sux16\t%1, %2, %0" [(set_attr "type" "fpmul") @@ -7716,11 +8070,11 @@ [(set_attr "type" "fpmul") (set_attr "fptype" "double")]) -;; Only one of the following two insns can be a multiply. (define_insn "fmuld8sux16_vis" [(set (match_operand:V2SI 0 "register_operand" "=e") - (mult:V2SI (match_operand:V4QI 1 "register_operand" "f") - (match_operand:V2HI 2 "register_operand" "f")))] + (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f") + (match_operand:V2HI 2 "register_operand" "f")] + UNSPEC_MULDSU))] "TARGET_VIS" "fmuld8sux16\t%1, %2, %0" [(set_attr "type" "fpmul") @@ -7736,27 +8090,115 @@ [(set_attr "type" "fpmul") (set_attr "fptype" "double")]) +(define_expand "wrgsr_vis" + [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" ""))] + "TARGET_VIS" +{ + if (! TARGET_ARCH64) + { + emit_insn (gen_wrgsr_v8plus (operands[0])); + DONE; + } +}) + +(define_insn "*wrgsr_sp64" + [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "rI"))] + "TARGET_VIS && TARGET_ARCH64" + "wr\t%%g0, %0, %%gsr" + [(set_attr "type" "gsr")]) + +(define_insn "wrgsr_v8plus" + [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "I,r")) + (clobber (match_scratch:SI 1 "=X,&h"))] + "TARGET_VIS && ! TARGET_ARCH64" +{ + if (GET_CODE (operands[0]) == CONST_INT + || sparc_check_64 (operands[0], insn)) + return "wr\t%%g0, %0, %%gsr"; + + output_asm_insn("srl\t%L0, 0, %L0", operands); + return "sllx\t%H0, 32, %1\n\tor\t%L0, %1, %1\n\twr\t%%g0, %1, %%gsr"; +} + [(set_attr "type" "multi")]) + +(define_expand "rdgsr_vis" + [(set (match_operand:DI 0 "register_operand" "") (reg:DI GSR_REG))] + "TARGET_VIS" +{ + if (! TARGET_ARCH64) + { + emit_insn (gen_rdgsr_v8plus (operands[0])); + DONE; + } +}) + +(define_insn "*rdgsr_sp64" + [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))] + "TARGET_VIS && TARGET_ARCH64" + "rd\t%%gsr, %0" + [(set_attr "type" "gsr")]) + +(define_insn "rdgsr_v8plus" + [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG)) + (clobber (match_scratch:SI 1 "=&h"))] + "TARGET_VIS && ! TARGET_ARCH64" +{ + return "rd\t%%gsr, %1\n\tsrlx\t%1, 32, %H0\n\tmov %1, %L0"; +} + [(set_attr "type" "multi")]) + ;; Using faligndata only makes sense after an alignaddr since the choice of ;; bytes to take out of each operand is dependent on the results of the last ;; alignaddr. -(define_insn "faligndata_vis" - [(set (match_operand:V64I 0 "register_operand" "=e") - (unspec:V64I [(match_operand:V64I 1 "register_operand" "e") - (match_operand:V64I 2 "register_operand" "e")] +(define_insn "faligndata_vis" + [(set (match_operand:VM64 0 "register_operand" "=e") + (unspec:VM64 [(match_operand:VM64 1 "register_operand" "e") + (match_operand:VM64 2 "register_operand" "e") + (reg:DI GSR_REG)] UNSPEC_ALIGNDATA))] "TARGET_VIS" "faligndata\t%1, %2, %0" [(set_attr "type" "fga") (set_attr "fptype" "double")]) -(define_insn "alignaddr_vis" - [(set (match_operand:P 0 "register_operand" "=r") - (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ") - (match_operand:P 2 "register_or_zero_operand" "rJ")] - UNSPEC_ALIGNADDR))] +(define_insn "alignaddrsi_vis" + [(set (match_operand:SI 0 "register_operand" "=r") + (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") + (match_operand:SI 2 "register_or_zero_operand" "rJ"))) + (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0)) + (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] + "TARGET_VIS" + "alignaddr\t%r1, %r2, %0") + +(define_insn "alignaddrdi_vis" + [(set (match_operand:DI 0 "register_operand" "=r") + (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ") + (match_operand:DI 2 "register_or_zero_operand" "rJ"))) + (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0)) + (plus:DI (match_dup 1) (match_dup 2)))] "TARGET_VIS" "alignaddr\t%r1, %r2, %0") +(define_insn "alignaddrlsi_vis" + [(set (match_operand:SI 0 "register_operand" "=r") + (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") + (match_operand:SI 2 "register_or_zero_operand" "rJ"))) + (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0)) + (xor:DI (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))) + (const_int 7)))] + "TARGET_VIS" + "alignaddrl\t%r1, %r2, %0") + +(define_insn "alignaddrldi_vis" + [(set (match_operand:DI 0 "register_operand" "=r") + (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ") + (match_operand:DI 2 "register_or_zero_operand" "rJ"))) + (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0)) + (xor:DI (plus:DI (match_dup 1) (match_dup 2)) + (const_int 7)))] + "TARGET_VIS" + "alignaddrl\t%r1, %r2, %0") + (define_insn "pdist_vis" [(set (match_operand:DI 0 "register_operand" "=e") (unspec:DI [(match_operand:V8QI 1 "register_operand" "e") @@ -7768,4 +8210,578 @@ [(set_attr "type" "fga") (set_attr "fptype" "double")]) +;; Edge instructions produce condition codes equivalent to a 'subcc' +;; with the same operands. +(define_insn "edge8_vis" + [(set (reg:CC_NOOV CC_REG) + (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ") + (match_operand:P 2 "register_or_zero_operand" "rJ")) + (const_int 0))) + (set (match_operand:P 0 "register_operand" "=r") + (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8))] + "TARGET_VIS" + "edge8\t%r1, %r2, %0" + [(set_attr "type" "edge")]) + +(define_insn "edge8l_vis" + [(set (reg:CC_NOOV CC_REG) + (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ") + (match_operand:P 2 "register_or_zero_operand" "rJ")) + (const_int 0))) + (set (match_operand:P 0 "register_operand" "=r") + (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8L))] + "TARGET_VIS" + "edge8l\t%r1, %r2, %0" + [(set_attr "type" "edge")]) + +(define_insn "edge16_vis" + [(set (reg:CC_NOOV CC_REG) + (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ") + (match_operand:P 2 "register_or_zero_operand" "rJ")) + (const_int 0))) + (set (match_operand:P 0 "register_operand" "=r") + (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16))] + "TARGET_VIS" + "edge16\t%r1, %r2, %0" + [(set_attr "type" "edge")]) + +(define_insn "edge16l_vis" + [(set (reg:CC_NOOV CC_REG) + (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ") + (match_operand:P 2 "register_or_zero_operand" "rJ")) + (const_int 0))) + (set (match_operand:P 0 "register_operand" "=r") + (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16L))] + "TARGET_VIS" + "edge16l\t%r1, %r2, %0" + [(set_attr "type" "edge")]) + +(define_insn "edge32_vis" + [(set (reg:CC_NOOV CC_REG) + (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ") + (match_operand:P 2 "register_or_zero_operand" "rJ")) + (const_int 0))) + (set (match_operand:P 0 "register_operand" "=r") + (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32))] + "TARGET_VIS" + "edge32\t%r1, %r2, %0" + [(set_attr "type" "edge")]) + +(define_insn "edge32l_vis" + [(set (reg:CC_NOOV CC_REG) + (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ") + (match_operand:P 2 "register_or_zero_operand" "rJ")) + (const_int 0))) + (set (match_operand:P 0 "register_operand" "=r") + (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32L))] + "TARGET_VIS" + "edge32l\t%r1, %r2, %0" + [(set_attr "type" "edge")]) + +(define_code_iterator gcond [le ne gt eq]) +(define_mode_iterator GCM [V4HI V2SI]) +(define_mode_attr gcm_name [(V4HI "16") (V2SI "32")]) + +(define_insn "fcmp_vis" + [(set (match_operand:P 0 "register_operand" "=r") + (unspec:P [(gcond:GCM (match_operand:GCM 1 "register_operand" "e") + (match_operand:GCM 2 "register_operand" "e"))] + UNSPEC_FCMP))] + "TARGET_VIS" + "fcmp\t%1, %2, %0" + [(set_attr "type" "fpmul") + (set_attr "fptype" "double")]) + +(define_insn "array8_vis" + [(set (match_operand:P 0 "register_operand" "=r") + (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ") + (match_operand:P 2 "register_or_zero_operand" "rJ")] + UNSPEC_ARRAY8))] + "TARGET_VIS" + "array8\t%r1, %r2, %0" + [(set_attr "type" "array")]) + +(define_insn "array16_vis" + [(set (match_operand:P 0 "register_operand" "=r") + (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ") + (match_operand:P 2 "register_or_zero_operand" "rJ")] + UNSPEC_ARRAY16))] + "TARGET_VIS" + "array16\t%r1, %r2, %0" + [(set_attr "type" "array")]) + +(define_insn "array32_vis" + [(set (match_operand:P 0 "register_operand" "=r") + (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ") + (match_operand:P 2 "register_or_zero_operand" "rJ")] + UNSPEC_ARRAY32))] + "TARGET_VIS" + "array32\t%r1, %r2, %0" + [(set_attr "type" "array")]) + +(define_insn "bmaskdi_vis" + [(set (match_operand:DI 0 "register_operand" "=r") + (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ") + (match_operand:DI 2 "register_or_zero_operand" "rJ"))) + (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32)) + (plus:DI (match_dup 1) (match_dup 2)))] + "TARGET_VIS2" + "bmask\t%r1, %r2, %0" + [(set_attr "type" "array")]) + +(define_insn "bmasksi_vis" + [(set (match_operand:SI 0 "register_operand" "=r") + (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ") + (match_operand:SI 2 "register_or_zero_operand" "rJ"))) + (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32)) + (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] + "TARGET_VIS2" + "bmask\t%r1, %r2, %0" + [(set_attr "type" "array")]) + +(define_insn "bshuffle_vis" + [(set (match_operand:VM64 0 "register_operand" "=e") + (unspec:VM64 [(match_operand:VM64 1 "register_operand" "e") + (match_operand:VM64 2 "register_operand" "e") + (reg:DI GSR_REG)] + UNSPEC_BSHUFFLE))] + "TARGET_VIS2" + "bshuffle\t%1, %2, %0" + [(set_attr "type" "fga") + (set_attr "fptype" "double")]) + +;; The rtl expanders will happily convert constant permutations on other +;; modes down to V8QI. Rely on this to avoid the complexity of the byte +;; order of the permutation. +(define_expand "vec_perm_constv8qi" + [(match_operand:V8QI 0 "register_operand" "") + (match_operand:V8QI 1 "register_operand" "") + (match_operand:V8QI 2 "register_operand" "") + (match_operand:V8QI 3 "" "")] + "TARGET_VIS2" +{ + unsigned int i, mask; + rtx sel = operands[3]; + + for (i = mask = 0; i < 8; ++i) + mask |= (INTVAL (XVECEXP (sel, 0, i)) & 0xf) << (28 - i*4); + sel = force_reg (SImode, gen_int_mode (mask, SImode)); + + emit_insn (gen_bmasksi_vis (gen_reg_rtx (SImode), sel, const0_rtx)); + emit_insn (gen_bshufflev8qi_vis (operands[0], operands[1], operands[2])); + DONE; +}) + +;; Unlike constant permutation, we can vastly simplify the compression of +;; the 64-bit selector input to the 32-bit %gsr value by knowing what the +;; width of the input is. +(define_expand "vec_perm" + [(match_operand:VM64 0 "register_operand" "") + (match_operand:VM64 1 "register_operand" "") + (match_operand:VM64 2 "register_operand" "") + (match_operand:VM64 3 "register_operand" "")] + "TARGET_VIS2" +{ + sparc_expand_vec_perm_bmask (mode, operands[3]); + emit_insn (gen_bshuffle_vis (operands[0], operands[1], operands[2])); + DONE; +}) + +;; VIS 2.0 adds edge variants which do not set the condition codes +(define_insn "edge8n_vis" + [(set (match_operand:P 0 "register_operand" "=r") + (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ") + (match_operand:P 2 "register_or_zero_operand" "rJ")] + UNSPEC_EDGE8N))] + "TARGET_VIS2" + "edge8n\t%r1, %r2, %0" + [(set_attr "type" "edgen")]) + +(define_insn "edge8ln_vis" + [(set (match_operand:P 0 "register_operand" "=r") + (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ") + (match_operand:P 2 "register_or_zero_operand" "rJ")] + UNSPEC_EDGE8LN))] + "TARGET_VIS2" + "edge8ln\t%r1, %r2, %0" + [(set_attr "type" "edgen")]) + +(define_insn "edge16n_vis" + [(set (match_operand:P 0 "register_operand" "=r") + (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ") + (match_operand:P 2 "register_or_zero_operand" "rJ")] + UNSPEC_EDGE16N))] + "TARGET_VIS2" + "edge16n\t%r1, %r2, %0" + [(set_attr "type" "edgen")]) + +(define_insn "edge16ln_vis" + [(set (match_operand:P 0 "register_operand" "=r") + (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ") + (match_operand:P 2 "register_or_zero_operand" "rJ")] + UNSPEC_EDGE16LN))] + "TARGET_VIS2" + "edge16ln\t%r1, %r2, %0" + [(set_attr "type" "edgen")]) + +(define_insn "edge32n_vis" + [(set (match_operand:P 0 "register_operand" "=r") + (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ") + (match_operand:P 2 "register_or_zero_operand" "rJ")] + UNSPEC_EDGE32N))] + "TARGET_VIS2" + "edge32n\t%r1, %r2, %0" + [(set_attr "type" "edgen")]) + +(define_insn "edge32ln_vis" + [(set (match_operand:P 0 "register_operand" "=r") + (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ") + (match_operand:P 2 "register_or_zero_operand" "rJ")] + UNSPEC_EDGE32LN))] + "TARGET_VIS2" + "edge32ln\t%r1, %r2, %0" + [(set_attr "type" "edge")]) + +;; Conditional moves are possible via fcmpX --> cmaskX -> bshuffle +(define_insn "cmask8_vis" + [(set (reg:DI GSR_REG) + (unspec:DI [(match_operand:P 0 "register_operand" "r") + (reg:DI GSR_REG)] + UNSPEC_CMASK8))] + "TARGET_VIS3" + "cmask8\t%r0") + +(define_insn "cmask16_vis" + [(set (reg:DI GSR_REG) + (unspec:DI [(match_operand:P 0 "register_operand" "r") + (reg:DI GSR_REG)] + UNSPEC_CMASK16))] + "TARGET_VIS3" + "cmask16\t%r0") + +(define_insn "cmask32_vis" + [(set (reg:DI GSR_REG) + (unspec:DI [(match_operand:P 0 "register_operand" "r") + (reg:DI GSR_REG)] + UNSPEC_CMASK32))] + "TARGET_VIS3" + "cmask32\t%r0") + +(define_insn "fchksm16_vis" + [(set (match_operand:V4HI 0 "register_operand" "=e") + (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "e") + (match_operand:V4HI 2 "register_operand" "e")] + UNSPEC_FCHKSM16))] + "TARGET_VIS3" + "fchksm16\t%1, %2, %0") + +(define_code_iterator vis3_shift [ashift ss_ashift lshiftrt ashiftrt]) +(define_code_attr vis3_shift_insn + [(ashift "fsll") (ss_ashift "fslas") (lshiftrt "fsrl") (ashiftrt "fsra")]) +(define_code_attr vis3_shift_patname + [(ashift "ashl") (ss_ashift "ssashl") (lshiftrt "lshr") (ashiftrt "ashr")]) + +(define_insn "v3" + [(set (match_operand:GCM 0 "register_operand" "=") + (vis3_shift:GCM (match_operand:GCM 1 "register_operand" "") + (match_operand:GCM 2 "register_operand" "")))] + "TARGET_VIS3" + "\t%1, %2, %0") + +(define_insn "pdistn_vis" + [(set (match_operand:P 0 "register_operand" "=r") + (unspec:P [(match_operand:V8QI 1 "register_operand" "e") + (match_operand:V8QI 2 "register_operand" "e")] + UNSPEC_PDISTN))] + "TARGET_VIS3" + "pdistn\t%1, %2, %0") + +(define_insn "fmean16_vis" + [(set (match_operand:V4HI 0 "register_operand" "=e") + (truncate:V4HI + (lshiftrt:V4SI + (plus:V4SI + (plus:V4SI + (zero_extend:V4SI + (match_operand:V4HI 1 "register_operand" "e")) + (zero_extend:V4SI + (match_operand:V4HI 2 "register_operand" "e"))) + (const_vector:V4SI [(const_int 1) (const_int 1) + (const_int 1) (const_int 1)])) + (const_int 1))))] + "TARGET_VIS3" + "fmean16\t%1, %2, %0") + +(define_insn "fp64_vis" + [(set (match_operand:V1DI 0 "register_operand" "=e") + (plusminus:V1DI (match_operand:V1DI 1 "register_operand" "e") + (match_operand:V1DI 2 "register_operand" "e")))] + "TARGET_VIS3" + "fp64\t%1, %2, %0") + +(define_mode_iterator VASS [V4HI V2SI V2HI V1SI]) +(define_code_iterator vis3_addsub_ss [ss_plus ss_minus]) +(define_code_attr vis3_addsub_ss_insn + [(ss_plus "fpadds") (ss_minus "fpsubs")]) +(define_code_attr vis3_addsub_ss_patname + [(ss_plus "ssadd") (ss_minus "sssub")]) + +(define_insn "3" + [(set (match_operand:VASS 0 "register_operand" "=") + (vis3_addsub_ss:VASS (match_operand:VASS 1 "register_operand" "") + (match_operand:VASS 2 "register_operand" "")))] + "TARGET_VIS3" + "\t%1, %2, %0") + +(define_insn "fucmp8_vis" + [(set (match_operand:P 0 "register_operand" "=r") + (unspec:P [(gcond:V8QI (match_operand:V8QI 1 "register_operand" "e") + (match_operand:V8QI 2 "register_operand" "e"))] + UNSPEC_FUCMP))] + "TARGET_VIS3" + "fucmp8\t%1, %2, %0") + +(define_insn "*naddsf3" + [(set (match_operand:SF 0 "register_operand" "=f") + (neg:SF (plus:SF (match_operand:SF 1 "register_operand" "f") + (match_operand:SF 2 "register_operand" "f"))))] + "TARGET_VIS3" + "fnadds\t%1, %2, %0" + [(set_attr "type" "fp")]) + +(define_insn "*nadddf3" + [(set (match_operand:DF 0 "register_operand" "=e") + (neg:DF (plus:DF (match_operand:DF 1 "register_operand" "e") + (match_operand:DF 2 "register_operand" "e"))))] + "TARGET_VIS3" + "fnaddd\t%1, %2, %0" + [(set_attr "type" "fp") + (set_attr "fptype" "double")]) + +(define_insn "*nmulsf3" + [(set (match_operand:SF 0 "register_operand" "=f") + (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "f")) + (match_operand:SF 2 "register_operand" "f")))] + "TARGET_VIS3" + "fnmuls\t%1, %2, %0" + [(set_attr "type" "fpmul")]) + +(define_insn "*nmuldf3" + [(set (match_operand:DF 0 "register_operand" "=e") + (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "e")) + (match_operand:DF 2 "register_operand" "e")))] + "TARGET_VIS3" + "fnmuld\t%1, %2, %0" + [(set_attr "type" "fpmul") + (set_attr "fptype" "double")]) + +(define_insn "*nmuldf3_extend" + [(set (match_operand:DF 0 "register_operand" "=e") + (mult:DF (neg:DF (float_extend:DF + (match_operand:SF 1 "register_operand" "f"))) + (float_extend:DF + (match_operand:SF 2 "register_operand" "f"))))] + "TARGET_VIS3" + "fnsmuld\t%1, %2, %0" + [(set_attr "type" "fpmul") + (set_attr "fptype" "double")]) + +(define_insn "fhaddsf_vis" + [(set (match_operand:SF 0 "register_operand" "=f") + (unspec:SF [(match_operand:SF 1 "register_operand" "f") + (match_operand:SF 2 "register_operand" "f")] + UNSPEC_FHADD))] + "TARGET_VIS3" + "fhadds\t%1, %2, %0" + [(set_attr "type" "fp")]) + +(define_insn "fhadddf_vis" + [(set (match_operand:DF 0 "register_operand" "=f") + (unspec:DF [(match_operand:DF 1 "register_operand" "f") + (match_operand:DF 2 "register_operand" "f")] + UNSPEC_FHADD))] + "TARGET_VIS3" + "fhaddd\t%1, %2, %0" + [(set_attr "type" "fp") + (set_attr "fptype" "double")]) + +(define_insn "fhsubsf_vis" + [(set (match_operand:SF 0 "register_operand" "=f") + (unspec:SF [(match_operand:SF 1 "register_operand" "f") + (match_operand:SF 2 "register_operand" "f")] + UNSPEC_FHSUB))] + "TARGET_VIS3" + "fhsubs\t%1, %2, %0" + [(set_attr "type" "fp")]) + +(define_insn "fhsubdf_vis" + [(set (match_operand:DF 0 "register_operand" "=f") + (unspec:DF [(match_operand:DF 1 "register_operand" "f") + (match_operand:DF 2 "register_operand" "f")] + UNSPEC_FHSUB))] + "TARGET_VIS3" + "fhsubd\t%1, %2, %0" + [(set_attr "type" "fp") + (set_attr "fptype" "double")]) + +(define_insn "fnhaddsf_vis" + [(set (match_operand:SF 0 "register_operand" "=f") + (neg:SF (unspec:SF [(match_operand:SF 1 "register_operand" "f") + (match_operand:SF 2 "register_operand" "f")] + UNSPEC_FHADD)))] + "TARGET_VIS3" + "fnhadds\t%1, %2, %0" + [(set_attr "type" "fp")]) + +(define_insn "fnhadddf_vis" + [(set (match_operand:DF 0 "register_operand" "=f") + (neg:DF (unspec:DF [(match_operand:DF 1 "register_operand" "f") + (match_operand:DF 2 "register_operand" "f")] + UNSPEC_FHADD)))] + "TARGET_VIS3" + "fnhaddd\t%1, %2, %0" + [(set_attr "type" "fp") + (set_attr "fptype" "double")]) + +(define_expand "umulxhi_vis" + [(set (match_operand:DI 0 "register_operand" "") + (truncate:DI + (lshiftrt:TI + (mult:TI (zero_extend:TI + (match_operand:DI 1 "arith_operand" "")) + (zero_extend:TI + (match_operand:DI 2 "arith_operand" ""))) + (const_int 64))))] + "TARGET_VIS3" +{ + if (! TARGET_ARCH64) + { + emit_insn (gen_umulxhi_v8plus (operands[0], operands[1], operands[2])); + DONE; + } +}) + +(define_insn "*umulxhi_sp64" + [(set (match_operand:DI 0 "register_operand" "=r") + (truncate:DI + (lshiftrt:TI + (mult:TI (zero_extend:TI + (match_operand:DI 1 "arith_operand" "%r")) + (zero_extend:TI + (match_operand:DI 2 "arith_operand" "rI"))) + (const_int 64))))] + "TARGET_VIS3 && TARGET_ARCH64" + "umulxhi\t%1, %2, %0" + [(set_attr "type" "imul")]) + +(define_insn "umulxhi_v8plus" + [(set (match_operand:DI 0 "register_operand" "=r,h") + (truncate:DI + (lshiftrt:TI + (mult:TI (zero_extend:TI + (match_operand:DI 1 "arith_operand" "%r,0")) + (zero_extend:TI + (match_operand:DI 2 "arith_operand" "rI,rI"))) + (const_int 64)))) + (clobber (match_scratch:SI 3 "=&h,X")) + (clobber (match_scratch:SI 4 "=&h,X"))] + "TARGET_VIS3 && ! TARGET_ARCH64" + "* return output_v8plus_mult (insn, operands, \"umulxhi\");" + [(set_attr "type" "imul") + (set_attr "length" "9,8")]) + +(define_expand "xmulx_vis" + [(set (match_operand:DI 0 "register_operand" "") + (truncate:DI + (unspec:TI [(zero_extend:TI + (match_operand:DI 1 "arith_operand" "")) + (zero_extend:TI + (match_operand:DI 2 "arith_operand" ""))] + UNSPEC_XMUL)))] + "TARGET_VIS3" +{ + if (! TARGET_ARCH64) + { + emit_insn (gen_xmulx_v8plus (operands[0], operands[1], operands[2])); + DONE; + } +}) + +(define_insn "*xmulx_sp64" + [(set (match_operand:DI 0 "register_operand" "=r") + (truncate:DI + (unspec:TI [(zero_extend:TI + (match_operand:DI 1 "arith_operand" "%r")) + (zero_extend:TI + (match_operand:DI 2 "arith_operand" "rI"))] + UNSPEC_XMUL)))] + "TARGET_VIS3 && TARGET_ARCH64" + "xmulx\t%1, %2, %0" + [(set_attr "type" "imul")]) + +(define_insn "xmulx_v8plus" + [(set (match_operand:DI 0 "register_operand" "=r,h") + (truncate:DI + (unspec:TI [(zero_extend:TI + (match_operand:DI 1 "arith_operand" "%r,0")) + (zero_extend:TI + (match_operand:DI 2 "arith_operand" "rI,rI"))] + UNSPEC_XMUL))) + (clobber (match_scratch:SI 3 "=&h,X")) + (clobber (match_scratch:SI 4 "=&h,X"))] + "TARGET_VIS3 && ! TARGET_ARCH64" + "* return output_v8plus_mult (insn, operands, \"xmulx\");" + [(set_attr "type" "imul") + (set_attr "length" "9,8")]) + +(define_expand "xmulxhi_vis" + [(set (match_operand:DI 0 "register_operand" "") + (truncate:DI + (lshiftrt:TI + (unspec:TI [(zero_extend:TI + (match_operand:DI 1 "arith_operand" "")) + (zero_extend:TI + (match_operand:DI 2 "arith_operand" ""))] + UNSPEC_XMUL) + (const_int 64))))] + "TARGET_VIS3" +{ + if (! TARGET_ARCH64) + { + emit_insn (gen_xmulxhi_v8plus (operands[0], operands[1], operands[2])); + DONE; + } +}) + +(define_insn "*xmulxhi_sp64" + [(set (match_operand:DI 0 "register_operand" "=r") + (truncate:DI + (lshiftrt:TI + (unspec:TI [(zero_extend:TI + (match_operand:DI 1 "arith_operand" "%r")) + (zero_extend:TI + (match_operand:DI 2 "arith_operand" "rI"))] + UNSPEC_XMUL) + (const_int 64))))] + "TARGET_VIS3 && TARGET_ARCH64" + "xmulxhi\t%1, %2, %0" + [(set_attr "type" "imul")]) + +(define_insn "xmulxhi_v8plus" + [(set (match_operand:DI 0 "register_operand" "=r,h") + (truncate:DI + (lshiftrt:TI + (unspec:TI [(zero_extend:TI + (match_operand:DI 1 "arith_operand" "%r,0")) + (zero_extend:TI + (match_operand:DI 2 "arith_operand" "rI,rI"))] + UNSPEC_XMUL) + (const_int 64)))) + (clobber (match_scratch:SI 3 "=&h,X")) + (clobber (match_scratch:SI 4 "=&h,X"))] + "TARGET_VIS3 && !TARGET_ARCH64" + "* return output_v8plus_mult (insn, operands, \"xmulxhi\");" + [(set_attr "type" "imul") + (set_attr "length" "9,8")]) + (include "sync.md")