X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=gcc%2Fconfig%2Fsparc%2Fsparc.md;h=4787d515d06d361c0ac9f68747af3058526d43d1;hp=d1ebb24c25f5ee18620c7598cf421e8017762864;hb=a54de377a12a11a9caa31a26aae4f9efc681005a;hpb=0db4cb4173f8989e98990586932234c71b71288f diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index d1ebb24c25f..4787d515d06 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -28,6 +28,7 @@ [(UNSPEC_MOVE_PIC 0) (UNSPEC_UPDATE_RETURN 1) (UNSPEC_LOAD_PCREL_SYM 2) + (UNSPEC_FRAME_BLOCKAGE 3) (UNSPEC_MOVE_PIC_LABEL 5) (UNSPEC_SETH44 6) (UNSPEC_SETM44 7) @@ -41,6 +42,7 @@ (UNSPEC_MOVE_GOTDATA 19) (UNSPEC_MEMBAR 20) + (UNSPEC_ATOMIC 21) (UNSPEC_TLSGD 30) (UNSPEC_TLSLDM 31) @@ -97,7 +99,6 @@ (define_constants [(UNSPECV_BLOCKAGE 0) (UNSPECV_FLUSHW 1) - (UNSPECV_GOTO 2) (UNSPECV_FLUSH 4) (UNSPECV_SAVEW 6) (UNSPECV_CAS 8) @@ -656,7 +657,17 @@ (match_operand:DI 2 "register_operand" ""))) (set (match_operand:SI 0 "register_operand" "") (ne:SI (match_dup 3) (const_int 0)))] - "TARGET_ARCH64" + "TARGET_ARCH64 && ! TARGET_VIS3" + { operands[3] = gen_reg_rtx (DImode); }) + +(define_expand "snedi_special_vis3" + [(set (match_dup 3) + (xor:DI (match_operand:DI 1 "register_operand" "") + (match_operand:DI 2 "register_operand" ""))) + (parallel [(set (match_operand:SI 0 "register_operand" "") + (ne:SI (match_dup 3) (const_int 0))) + (clobber (reg:CCX CC_REG))])] + "TARGET_ARCH64 && TARGET_VIS3" { operands[3] = gen_reg_rtx (DImode); }) @@ -713,11 +724,27 @@ "" [(set_attr "length" "2")]) +(define_insn_and_split "*neg_snesi_sign_extend" + [(set (match_operand:DI 0 "register_operand" "=r") + (neg:DI (ne:DI (match_operand:SI 1 "register_operand" "r") + (const_int 0)))) + (clobber (reg:CC CC_REG))] + "TARGET_ARCH64" + "#" + "&& 1" + [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (const_int 0) + (match_dup 1)) + (const_int 0))) + (set (match_dup 0) (sign_extend:DI (neg:SI (ltu:SI (reg:CC CC_REG) + (const_int 0)))))] + "" + [(set_attr "length" "2")]) + (define_insn_and_split "*snedi_zero" [(set (match_operand:DI 0 "register_operand" "=&r") (ne:DI (match_operand:DI 1 "register_operand" "r") (const_int 0)))] - "TARGET_ARCH64" + "TARGET_ARCH64 && ! TARGET_VIS3" "#" "&& ! reg_overlap_mentioned_p (operands[1], operands[0])" [(set (match_dup 0) (const_int 0)) @@ -728,6 +755,20 @@ "" [(set_attr "length" "2")]) +(define_insn_and_split "*snedi_zero_vis3" + [(set (match_operand:DI 0 "register_operand" "=r") + (ne:DI (match_operand:DI 1 "register_operand" "r") + (const_int 0))) + (clobber (reg:CCX CC_REG))] + "TARGET_ARCH64 && TARGET_VIS3" + "#" + "" + [(set (reg:CCX_NOOV CC_REG) (compare:CCX_NOOV (neg:DI (match_dup 1)) + (const_int 0))) + (set (match_dup 0) (ltu:DI (reg:CCX CC_REG) (const_int 0)))] + "" + [(set_attr "length" "2")]) + (define_insn_and_split "*neg_snedi_zero" [(set (match_operand:DI 0 "register_operand" "=&r") (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r") @@ -747,7 +788,7 @@ [(set (match_operand:SI 0 "register_operand" "=&r") (ne:SI (match_operand:DI 1 "register_operand" "r") (const_int 0)))] - "TARGET_ARCH64" + "TARGET_ARCH64 && ! TARGET_VIS3" "#" "&& ! reg_overlap_mentioned_p (operands[1], operands[0])" [(set (match_dup 0) (const_int 0)) @@ -758,6 +799,20 @@ "" [(set_attr "length" "2")]) +(define_insn_and_split "*snedi_zero_trunc_vis3" + [(set (match_operand:SI 0 "register_operand" "=r") + (ne:SI (match_operand:DI 1 "register_operand" "r") + (const_int 0))) + (clobber (reg:CCX CC_REG))] + "TARGET_ARCH64 && TARGET_VIS3" + "#" + "" + [(set (reg:CCX_NOOV CC_REG) (compare:CCX_NOOV (neg:DI (match_dup 1)) + (const_int 0))) + (set (match_dup 0) (ltu:SI (reg:CCX CC_REG) (const_int 0)))] + "" + [(set_attr "length" "2")]) + (define_insn_and_split "*seqsi_zero" [(set (match_operand:SI 0 "register_operand" "=r") (eq:SI (match_operand:SI 1 "register_operand" "r") @@ -804,6 +859,21 @@ "" [(set_attr "length" "2")]) +(define_insn_and_split "*neg_seqsi_sign_extend" + [(set (match_operand:DI 0 "register_operand" "=r") + (neg:DI (eq:DI (match_operand:SI 1 "register_operand" "r") + (const_int 0)))) + (clobber (reg:CC CC_REG))] + "TARGET_ARCH64" + "#" + "&& 1" + [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1)) + (const_int 0))) + (set (match_dup 0) (sign_extend:DI (neg:SI (geu:SI (reg:CC CC_REG) + (const_int 0)))))] + "" + [(set_attr "length" "2")]) + (define_insn_and_split "*seqdi_zero" [(set (match_operand:DI 0 "register_operand" "=&r") (eq:DI (match_operand:DI 1 "register_operand" "r") @@ -928,6 +998,27 @@ "addx\t%%g0, 0, %0" [(set_attr "type" "ialuX")]) +(define_insn "*sltu_insn_vis3" + [(set (match_operand:DI 0 "register_operand" "=r") + (ltu:DI (reg:CCX CC_REG) (const_int 0)))] + "TARGET_ARCH64 && TARGET_VIS3" + "addxc\t%%g0, %%g0, %0" + [(set_attr "type" "ialuX")]) + +(define_insn "*sltu_insn_vis3_trunc" + [(set (match_operand:SI 0 "register_operand" "=r") + (ltu:SI (reg:CCX CC_REG) (const_int 0)))] + "TARGET_ARCH64 && TARGET_VIS3" + "addxc\t%%g0, %%g0, %0" + [(set_attr "type" "ialuX")]) + +(define_insn "*sltu_extend_sp64" + [(set (match_operand:DI 0 "register_operand" "=r") + (ltu:DI (reg:CC CC_REG) (const_int 0)))] + "TARGET_ARCH64" + "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 CC_REG) (const_int 0))))] @@ -935,6 +1026,13 @@ "subx\t%%g0, 0, %0" [(set_attr "type" "ialuX")]) +(define_insn "*neg_sltu_extend_sp64" + [(set (match_operand:DI 0 "register_operand" "=r") + (sign_extend:DI (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0)))))] + "TARGET_ARCH64" + "subx\t%%g0, 0, %0" + [(set_attr "type" "ialuX")]) + ;; ??? Combine should canonicalize these next two to the same pattern. (define_insn "*neg_sltu_minus_x" [(set (match_operand:SI 0 "register_operand" "=r") @@ -959,6 +1057,13 @@ "subx\t%%g0, -1, %0" [(set_attr "type" "ialuX")]) +(define_insn "*sgeu_extend_sp64" + [(set (match_operand:DI 0 "register_operand" "=r") + (geu:DI (reg:CC CC_REG) (const_int 0)))] + "TARGET_ARCH64" + "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 CC_REG) (const_int 0))))] @@ -966,6 +1071,13 @@ "addx\t%%g0, -1, %0" [(set_attr "type" "ialuX")]) +(define_insn "*neg_sgeu_extend_sp64" + [(set (match_operand:DI 0 "register_operand" "=r") + (sign_extend:DI (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0)))))] + "TARGET_ARCH64" + "addx\t%%g0, -1, %0" + [(set_attr "type" "ialuX")]) + ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in. ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode ;; versions for v9. @@ -1240,6 +1352,10 @@ ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic ;; value subject to a PC-relative relocation. Operand 2 is a helper function ;; that adds the PC value at the call point to register #(operand 3). +;; +;; Even on V9 we use this call sequence with a stub, instead of "rd %pc, ..." +;; because the RDPC instruction is extremely expensive and incurs a complete +;; instruction pipeline flush. (define_insn "load_pcrel_sym" [(set (match_operand:P 0 "register_operand" "=r") @@ -1930,8 +2046,8 @@ }) (define_insn "*movsf_insn" - [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,f, *r,*r,*r,*r, f, f,*r, m, m") - (match_operand:SF 1 "input_operand" "G,C,f,*rR, Q, S, f,*r, m, m, f,*rG"))] + [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,f, *r,*r,*r,*r, f,f,*r,m, m") + (match_operand:SF 1 "input_operand" "G,C,f,*rR, Q, S, f,*r,m, m,f,*rG"))] "(register_operand (operands[0], SFmode) || register_or_zero_or_all_ones_operand (operands[1], SFmode))" { @@ -2027,8 +2143,8 @@ }) (define_insn "*movdf_insn_sp32" - [(set (match_operand:DF 0 "nonimmediate_operand" "=b,b,e,e,*r, f, e,T,W,U,T, f, *r, o,o") - (match_operand:DF 1 "input_operand" "G,C,e,e, f,*r,W#F,G,e,T,U,o#F,*roGF,*rG,f"))] + [(set (match_operand:DF 0 "nonimmediate_operand" "=b,b,e,e,*r, f, e,T,W,U,T, f, *r, o,o") + (match_operand:DF 1 "input_operand" "G,C,e,e, f,*r,W#F,G,e,T,U,o#F,*roF,*rG,f"))] "! TARGET_ARCH64 && (register_operand (operands[0], DFmode) || register_or_zero_or_all_ones_operand (operands[1], DFmode))" @@ -2055,7 +2171,7 @@ (define_insn "*movdf_insn_sp64" [(set (match_operand:DF 0 "nonimmediate_operand" "=b,b,e,*r, e, e,W, *r,*r, m,*r") - (match_operand:DF 1 "input_operand" "G,C,e, e,*r,W#F,e,*rG, m,*rG, F"))] + (match_operand:DF 1 "input_operand" "G,C,e, e,*r,W#F,e,*rG, m,*rG, F"))] "TARGET_ARCH64 && (register_operand (operands[0], DFmode) || register_or_zero_or_all_ones_operand (operands[1], DFmode))" @@ -2080,9 +2196,8 @@ (define_split [(set (match_operand:DF 0 "register_operand" "") (match_operand:DF 1 "const_double_operand" ""))] - "TARGET_FPU - && (GET_CODE (operands[0]) == REG - && SPARC_INT_REG_P (REGNO (operands[0]))) + "REG_P (operands[0]) + && SPARC_INT_REG_P (REGNO (operands[0])) && ! const_zero_operand (operands[1], GET_MODE (operands[0])) && reload_completed" [(clobber (const_int 0))] @@ -2267,45 +2382,30 @@ }) (define_insn "*movtf_insn_sp32" - [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,U,r") - (match_operand:TF 1 "input_operand" "G,oe,GeUr,o,roG"))] - "TARGET_FPU - && ! TARGET_ARCH64 - && (register_operand (operands[0], TFmode) - || register_or_zero_operand (operands[1], TFmode))" - "#" - [(set_attr "length" "4")]) - -;; Exactly the same as above, except that all `e' cases are deleted. -;; This is necessary to prevent reload from ever trying to use a `e' reg -;; when -mno-fpu. - -(define_insn "*movtf_insn_sp32_no_fpu" - [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o") - (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))] - "! TARGET_FPU - && ! TARGET_ARCH64 + [(set (match_operand:TF 0 "nonimmediate_operand" "=b, e,o, o,U, r") + (match_operand:TF 1 "input_operand" " G,oe,e,rGU,o,roG"))] + "! TARGET_ARCH64 && (register_operand (operands[0], TFmode) || register_or_zero_operand (operands[1], TFmode))" "#" - [(set_attr "length" "4")]) + [(set_attr "length" "4,4,4,4,4,4") + (set_attr "cpu_feature" "fpu,fpu,fpu,*,*,*")]) (define_insn "*movtf_insn_sp64" - [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,r") - (match_operand:TF 1 "input_operand" "G,oe,Ger,roG"))] - "TARGET_FPU - && TARGET_ARCH64 + [(set (match_operand:TF 0 "nonimmediate_operand" "=b, e,o, o, r") + (match_operand:TF 1 "input_operand" "G,oe,e,rG,roG"))] + "TARGET_ARCH64 && ! TARGET_HARD_QUAD && (register_operand (operands[0], TFmode) || register_or_zero_operand (operands[1], TFmode))" "#" - [(set_attr "length" "2")]) + [(set_attr "length" "2,2,2,2,2") + (set_attr "cpu_feature" "fpu,fpu,fpu,*,*")]) (define_insn "*movtf_insn_sp64_hq" - [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m,o,r") - (match_operand:TF 1 "input_operand" "G,e,m,e,rG,roG"))] - "TARGET_FPU - && TARGET_ARCH64 + [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m, o, r") + (match_operand:TF 1 "input_operand" "G,e,m,e,rG,roG"))] + "TARGET_ARCH64 && TARGET_HARD_QUAD && (register_operand (operands[0], TFmode) || register_or_zero_operand (operands[1], TFmode))" @@ -2319,16 +2419,6 @@ [(set_attr "type" "*,fpmove,fpload,fpstore,*,*") (set_attr "length" "2,*,*,*,2,2")]) -(define_insn "*movtf_insn_sp64_no_fpu" - [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o") - (match_operand:TF 1 "input_operand" "orG,rG"))] - "! TARGET_FPU - && TARGET_ARCH64 - && (register_operand (operands[0], TFmode) - || register_or_zero_operand (operands[1], TFmode))" - "#" - [(set_attr "length" "2")]) - ;; Now all the splits to handle multi-insn TF mode moves. (define_split [(set (match_operand:TF 0 "register_operand" "") @@ -2456,6 +2546,9 @@ ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand ;; 3 contains the constant if one is present, but we handle either for ;; generality (sparc.c puts a constant in operand 2). +;; +;; Our instruction patterns, on the other hand, canonicalize such that +;; operand 3 must be the set destination. (define_expand "movcc" [(set (match_operand:I 0 "register_operand" "") @@ -2464,27 +2557,9 @@ (match_operand:I 3 "arith10_operand" "")))] "TARGET_V9 && !(mode == DImode && TARGET_ARCH32)" { - rtx cc_reg; - - if (GET_MODE (XEXP (operands[1], 0)) == DImode && !TARGET_ARCH64) + if (! sparc_expand_conditional_move (mode, operands)) FAIL; - - if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD) - operands[1] - = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1), - GET_CODE (operands[1])); - - if (XEXP (operands[1], 1) == const0_rtx - && GET_CODE (XEXP (operands[1], 0)) == REG - && GET_MODE (XEXP (operands[1], 0)) == DImode - && 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 (GET_CODE (operands[1]), GET_MODE (cc_reg), cc_reg, - const0_rtx); + DONE; }) (define_expand "movcc" @@ -2494,146 +2569,112 @@ (match_operand:F 3 "register_operand" "")))] "TARGET_V9 && TARGET_FPU" { - rtx cc_reg; - - if (GET_MODE (XEXP (operands[1], 0)) == DImode && !TARGET_ARCH64) + if (! sparc_expand_conditional_move (mode, operands)) FAIL; - - if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD) - operands[1] - = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1), - GET_CODE (operands[1])); - - if (XEXP (operands[1], 1) == const0_rtx - && GET_CODE (XEXP (operands[1], 0)) == REG - && GET_MODE (XEXP (operands[1], 0)) == DImode - && 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 (GET_CODE (operands[1]), GET_MODE (cc_reg), cc_reg, - const0_rtx); + DONE; }) ;; Conditional move define_insns (define_insn "*mov_cc_v9" - [(set (match_operand:I 0 "register_operand" "=r,r") + [(set (match_operand:I 0 "register_operand" "=r") (if_then_else:I (match_operator 1 "comparison_operator" - [(match_operand 2 "icc_or_fcc_register_operand" "X,X") + [(match_operand 2 "icc_or_fcc_register_operand" "X") (const_int 0)]) - (match_operand:I 3 "arith11_operand" "rL,0") - (match_operand:I 4 "arith11_operand" "0,rL")))] + (match_operand:I 3 "arith11_operand" "rL") + (match_operand:I 4 "register_operand" "0")))] "TARGET_V9 && !(mode == DImode && TARGET_ARCH32)" - "@ - mov%C1\t%x2, %3, %0 - mov%c1\t%x2, %4, %0" + "mov%C1\t%x2, %3, %0" [(set_attr "type" "cmove")]) (define_insn "*mov_cc_reg_sp64" - [(set (match_operand:I 0 "register_operand" "=r,r") + [(set (match_operand:I 0 "register_operand" "=r") (if_then_else:I (match_operator 1 "v9_register_compare_operator" - [(match_operand:DI 2 "register_operand" "r,r") + [(match_operand:DI 2 "register_operand" "r") (const_int 0)]) - (match_operand:I 3 "arith10_operand" "rM,0") - (match_operand:I 4 "arith10_operand" "0,rM")))] + (match_operand:I 3 "arith10_operand" "rM") + (match_operand:I 4 "register_operand" "0")))] "TARGET_ARCH64" - "@ - movr%D1\t%2, %r3, %0 - movr%d1\t%2, %r4, %0" + "movr%D1\t%2, %r3, %0" [(set_attr "type" "cmove")]) (define_insn "*movsf_cc_v9" - [(set (match_operand:SF 0 "register_operand" "=f,f") + [(set (match_operand:SF 0 "register_operand" "=f") (if_then_else:SF (match_operator 1 "comparison_operator" - [(match_operand 2 "icc_or_fcc_register_operand" "X,X") + [(match_operand 2 "icc_or_fcc_register_operand" "X") (const_int 0)]) - (match_operand:SF 3 "register_operand" "f,0") - (match_operand:SF 4 "register_operand" "0,f")))] + (match_operand:SF 3 "register_operand" "f") + (match_operand:SF 4 "register_operand" "0")))] "TARGET_V9 && TARGET_FPU" - "@ - fmovs%C1\t%x2, %3, %0 - fmovs%c1\t%x2, %4, %0" + "fmovs%C1\t%x2, %3, %0" [(set_attr "type" "fpcmove")]) (define_insn "*movsf_cc_reg_sp64" - [(set (match_operand:SF 0 "register_operand" "=f,f") + [(set (match_operand:SF 0 "register_operand" "=f") (if_then_else:SF (match_operator 1 "v9_register_compare_operator" - [(match_operand:DI 2 "register_operand" "r,r") + [(match_operand:DI 2 "register_operand" "r") (const_int 0)]) - (match_operand:SF 3 "register_operand" "f,0") - (match_operand:SF 4 "register_operand" "0,f")))] + (match_operand:SF 3 "register_operand" "f") + (match_operand:SF 4 "register_operand" "0")))] "TARGET_ARCH64 && TARGET_FPU" - "@ - fmovrs%D1\t%2, %3, %0 - fmovrs%d1\t%2, %4, %0" + "fmovrs%D1\t%2, %3, %0" [(set_attr "type" "fpcrmove")]) ;; Named because invoked by movtf_cc_v9 (define_insn "movdf_cc_v9" - [(set (match_operand:DF 0 "register_operand" "=e,e") + [(set (match_operand:DF 0 "register_operand" "=e") (if_then_else:DF (match_operator 1 "comparison_operator" - [(match_operand 2 "icc_or_fcc_register_operand" "X,X") + [(match_operand 2 "icc_or_fcc_register_operand" "X") (const_int 0)]) - (match_operand:DF 3 "register_operand" "e,0") - (match_operand:DF 4 "register_operand" "0,e")))] + (match_operand:DF 3 "register_operand" "e") + (match_operand:DF 4 "register_operand" "0")))] "TARGET_V9 && TARGET_FPU" - "@ - fmovd%C1\t%x2, %3, %0 - fmovd%c1\t%x2, %4, %0" + "fmovd%C1\t%x2, %3, %0" [(set_attr "type" "fpcmove") (set_attr "fptype" "double")]) ;; Named because invoked by movtf_cc_reg_sp64 (define_insn "movdf_cc_reg_sp64" - [(set (match_operand:DF 0 "register_operand" "=e,e") + [(set (match_operand:DF 0 "register_operand" "=e") (if_then_else:DF (match_operator 1 "v9_register_compare_operator" - [(match_operand:DI 2 "register_operand" "r,r") + [(match_operand:DI 2 "register_operand" "r") (const_int 0)]) - (match_operand:DF 3 "register_operand" "e,0") - (match_operand:DF 4 "register_operand" "0,e")))] + (match_operand:DF 3 "register_operand" "e") + (match_operand:DF 4 "register_operand" "0")))] "TARGET_ARCH64 && TARGET_FPU" - "@ - fmovrd%D1\t%2, %3, %0 - fmovrd%d1\t%2, %4, %0" + "fmovrd%D1\t%2, %3, %0" [(set_attr "type" "fpcrmove") (set_attr "fptype" "double")]) (define_insn "*movtf_cc_hq_v9" - [(set (match_operand:TF 0 "register_operand" "=e,e") + [(set (match_operand:TF 0 "register_operand" "=e") (if_then_else:TF (match_operator 1 "comparison_operator" - [(match_operand 2 "icc_or_fcc_register_operand" "X,X") + [(match_operand 2 "icc_or_fcc_register_operand" "X") (const_int 0)]) - (match_operand:TF 3 "register_operand" "e,0") - (match_operand:TF 4 "register_operand" "0,e")))] + (match_operand:TF 3 "register_operand" "e") + (match_operand:TF 4 "register_operand" "0")))] "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD" - "@ - fmovq%C1\t%x2, %3, %0 - fmovq%c1\t%x2, %4, %0" + "fmovq%C1\t%x2, %3, %0" [(set_attr "type" "fpcmove")]) (define_insn "*movtf_cc_reg_hq_sp64" - [(set (match_operand:TF 0 "register_operand" "=e,e") + [(set (match_operand:TF 0 "register_operand" "=e") (if_then_else:TF (match_operator 1 "v9_register_compare_operator" - [(match_operand:DI 2 "register_operand" "r,r") + [(match_operand:DI 2 "register_operand" "r") (const_int 0)]) - (match_operand:TF 3 "register_operand" "e,0") - (match_operand:TF 4 "register_operand" "0,e")))] + (match_operand:TF 3 "register_operand" "e") + (match_operand:TF 4 "register_operand" "0")))] "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD" - "@ - fmovrq%D1\t%2, %3, %0 - fmovrq%d1\t%2, %4, %0" + "fmovrq%D1\t%2, %3, %0" [(set_attr "type" "fpcrmove")]) (define_insn_and_split "*movtf_cc_v9" - [(set (match_operand:TF 0 "register_operand" "=e,e") + [(set (match_operand:TF 0 "register_operand" "=e") (if_then_else:TF (match_operator 1 "comparison_operator" - [(match_operand 2 "icc_or_fcc_register_operand" "X,X") + [(match_operand 2 "icc_or_fcc_register_operand" "X") (const_int 0)]) - (match_operand:TF 3 "register_operand" "e,0") - (match_operand:TF 4 "register_operand" "0,e")))] + (match_operand:TF 3 "register_operand" "e") + (match_operand:TF 4 "register_operand" "0")))] "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD" "#" "&& reload_completed" @@ -2641,42 +2682,35 @@ { rtx set_dest = operands[0]; rtx set_srca = operands[3]; - rtx set_srcb = operands[4]; - int third = rtx_equal_p (set_dest, set_srca); rtx dest1, dest2; - rtx srca1, srca2, srcb1, srcb2; + rtx srca1, srca2; dest1 = gen_df_reg (set_dest, 0); dest2 = gen_df_reg (set_dest, 1); srca1 = gen_df_reg (set_srca, 0); srca2 = gen_df_reg (set_srca, 1); - srcb1 = gen_df_reg (set_srcb, 0); - srcb2 = gen_df_reg (set_srcb, 1); - /* Now emit using the real source and destination we found, swapping - the order if we detect overlap. */ - if ((third && reg_overlap_mentioned_p (dest1, srcb2)) - || (!third && reg_overlap_mentioned_p (dest1, srca2))) + if (reg_overlap_mentioned_p (dest1, srca2)) { - emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2)); - emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1)); + emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, dest2)); + emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, dest1)); } else { - emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1)); - emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2)); + emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, dest1)); + emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, dest2)); } DONE; } [(set_attr "length" "2")]) (define_insn_and_split "*movtf_cc_reg_sp64" - [(set (match_operand:TF 0 "register_operand" "=e,e") + [(set (match_operand:TF 0 "register_operand" "=e") (if_then_else:TF (match_operator 1 "v9_register_compare_operator" - [(match_operand:DI 2 "register_operand" "r,r") + [(match_operand:DI 2 "register_operand" "r") (const_int 0)]) - (match_operand:TF 3 "register_operand" "e,0") - (match_operand:TF 4 "register_operand" "0,e")))] + (match_operand:TF 3 "register_operand" "e") + (match_operand:TF 4 "register_operand" "0")))] "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD" "#" "&& reload_completed" @@ -2684,30 +2718,23 @@ { rtx set_dest = operands[0]; rtx set_srca = operands[3]; - rtx set_srcb = operands[4]; - int third = rtx_equal_p (set_dest, set_srca); rtx dest1, dest2; - rtx srca1, srca2, srcb1, srcb2; + rtx srca1, srca2; dest1 = gen_df_reg (set_dest, 0); dest2 = gen_df_reg (set_dest, 1); srca1 = gen_df_reg (set_srca, 0); srca2 = gen_df_reg (set_srca, 1); - srcb1 = gen_df_reg (set_srcb, 0); - srcb2 = gen_df_reg (set_srcb, 1); - /* Now emit using the real source and destination we found, swapping - the order if we detect overlap. */ - if ((third && reg_overlap_mentioned_p (dest1, srcb2)) - || (!third && reg_overlap_mentioned_p (dest1, srca2))) + if (reg_overlap_mentioned_p (dest1, srca2)) { - emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2)); - emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1)); + emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, dest2)); + emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, dest1)); } else { - emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1)); - emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2)); + emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, dest1)); + emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, dest2)); } DONE; } @@ -3500,7 +3527,7 @@ }) (define_insn_and_split "*adddi3_insn_sp32" - [(set (match_operand:DI 0 "register_operand" "=r") + [(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 CC_REG))] @@ -3547,6 +3574,15 @@ "addx\t%1, %2, %0" [(set_attr "type" "ialuX")]) +(define_insn "addxc" + [(set (match_operand:DI 0 "register_operand" "=r") + (plus:DI (plus:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ") + (match_operand:DI 2 "register_or_zero_operand" "rJ")) + (ltu:DI (reg:CCX_NOOV CC_REG) (const_int 0))))] + "TARGET_ARCH64 && TARGET_VIS3" + "addxc\t%r1, %r2, %0" + [(set_attr "type" "ialuX")]) + (define_insn_and_split "*addx_extend_sp32" [(set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI (plus:SI (plus:SI @@ -3566,10 +3602,19 @@ (define_insn "*addx_extend_sp64" [(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")) + (match_operand:SI 2 "register_or_zero_operand" "rJ")) (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))] "TARGET_ARCH64" - "addx\t%r1, %2, %0" + "addx\t%r1, %r2, %0" + [(set_attr "type" "ialuX")]) + +(define_insn "*addxc_trunc_sp64_vis3" + [(set (match_operand:SI 0 "register_operand" "=r") + (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ") + (match_operand:SI 2 "register_or_zero_operand" "rJ")) + (ltu:SI (reg:CCX_NOOV CC_REG) (const_int 0))))] + "TARGET_ARCH64 && TARGET_VIS3" + "addxc\t%r1, %r2, %0" [(set_attr "type" "ialuX")]) (define_insn_and_split "*adddi3_extend_sp32" @@ -5609,7 +5654,7 @@ (match_operand:SI 2 "arith_operand" "rI,rI,rI"))) (clobber (match_scratch:SI 3 "=X,X,&h"))] "TARGET_V8PLUS" - "* return output_v8plus_shift (operands, insn, \"sllx\");" + "* return output_v8plus_shift (insn ,operands, \"sllx\");" [(set_attr "type" "multi") (set_attr "length" "5,5,6")]) @@ -5719,7 +5764,7 @@ (match_operand:SI 2 "arith_operand" "rI,rI,rI"))) (clobber (match_scratch:SI 3 "=X,X,&h"))] "TARGET_V8PLUS" - "* return output_v8plus_shift (operands, insn, \"srax\");" + "* return output_v8plus_shift (insn, operands, \"srax\");" [(set_attr "type" "multi") (set_attr "length" "5,5,6")]) @@ -5809,7 +5854,7 @@ (match_operand:SI 2 "arith_operand" "rI,rI,rI"))) (clobber (match_scratch:SI 3 "=X,X,&h"))] "TARGET_V8PLUS" - "* return output_v8plus_shift (operands, insn, \"srlx\");" + "* return output_v8plus_shift (insn, operands, \"srlx\");" [(set_attr "type" "multi") (set_attr "length" "5,5,6")]) @@ -6334,6 +6379,25 @@ "" [(set_attr "length" "0")]) +;; Do not schedule instructions accessing memory before this point. + +(define_expand "frame_blockage" + [(set (match_dup 0) + (unspec:BLK [(match_dup 1)] UNSPEC_FRAME_BLOCKAGE))] + "" +{ + operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); + MEM_VOLATILE_P (operands[0]) = 1; + operands[1] = stack_pointer_rtx; +}) + +(define_insn "*frame_blockage" + [(set (match_operand:BLK 0 "" "") + (unspec:BLK [(match_operand:P 1 "" "")] UNSPEC_FRAME_BLOCKAGE))] + "" + "" + [(set_attr "length" "0")]) + (define_expand "probe_stack" [(set (match_operand 0 "memory_operand" "") (const_int 0))] "" @@ -6463,6 +6527,7 @@ (match_operand 3 "memory_operand" "")] "" { + rtx i7 = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM); rtx r_label = copy_to_reg (operands[1]); rtx r_sp = adjust_address_nv (operands[2], Pmode, 0); rtx r_fp = operands[3]; @@ -6479,44 +6544,19 @@ /* Restore frame pointer for containing function. */ emit_move_insn (hard_frame_pointer_rtx, r_fp); emit_stack_restore (SAVE_NONLOCAL, r_sp); + emit_move_insn (i7, r_i7); /* USE of hard_frame_pointer_rtx added for consistency; not clear if really needed. */ emit_use (hard_frame_pointer_rtx); emit_use (stack_pointer_rtx); + emit_use (i7); - /* We need to smuggle the load of %i7 as it is a fixed register. */ - emit_jump_insn (gen_nonlocal_goto_internal (r_label, r_i7)); + emit_jump_insn (gen_indirect_jump (r_label)); emit_barrier (); DONE; }) -(define_insn "nonlocal_goto_internal" - [(unspec_volatile [(match_operand 0 "register_operand" "r") - (match_operand 1 "memory_operand" "m")] UNSPECV_GOTO)] - "GET_MODE (operands[0]) == Pmode && GET_MODE (operands[1]) == Pmode" -{ - if (flag_delayed_branch) - { - if (TARGET_ARCH64) - return "jmp\t%0\n\t ldx\t%1, %%i7"; - else - return "jmp\t%0\n\t ld\t%1, %%i7"; - } - else - { - if (TARGET_ARCH64) - return "ldx\t%1, %%i7\n\tjmp\t%0\n\t nop"; - else - return "ld\t%1, %%i7\n\tjmp\t%0\n\t nop"; - } -} - [(set (attr "type") (const_string "multi")) - (set (attr "length") - (if_then_else (eq_attr "delayed_branch" "true") - (const_int 2) - (const_int 3)))]) - (define_expand "builtin_setjmp_receiver" [(label_ref (match_operand 0 "" ""))] "flag_pic" @@ -7690,8 +7730,8 @@ (set_attr "cpu_feature" "vis,vis,vis,*,*,*,*,*,*,vis3,vis3")]) (define_insn "*mov_insn_sp64" - [(set (match_operand:VM64 0 "nonimmediate_operand" "=e,e,e,e,m,m,*r, m,*r, f,*r") - (match_operand:VM64 1 "input_operand" "Y,C,e,m,e,Y, m,*r, f,*r,*r"))] + [(set (match_operand:VM64 0 "nonimmediate_operand" "=e,e,e,e,m,m,*r, m,*r, e,*r") + (match_operand:VM64 1 "input_operand" "Y,C,e,m,e,Y, m,*r, e,*r,*r"))] "TARGET_VIS && TARGET_ARCH64 && (register_operand (operands[0], mode) @@ -8233,6 +8273,36 @@ [(set_attr "type" "fpmul") (set_attr "fptype" "double")]) +(define_expand "vcond" + [(match_operand:GCM 0 "register_operand" "") + (match_operand:GCM 1 "register_operand" "") + (match_operand:GCM 2 "register_operand" "") + (match_operator 3 "" + [(match_operand:GCM 4 "register_operand" "") + (match_operand:GCM 5 "register_operand" "")])] + "TARGET_VIS3" +{ + sparc_expand_vcond (mode, operands, + UNSPEC_CMASK, + UNSPEC_FCMP); + DONE; +}) + +(define_expand "vconduv8qiv8qi" + [(match_operand:V8QI 0 "register_operand" "") + (match_operand:V8QI 1 "register_operand" "") + (match_operand:V8QI 2 "register_operand" "") + (match_operator 3 "" + [(match_operand:V8QI 4 "register_operand" "") + (match_operand:V8QI 5 "register_operand" "")])] + "TARGET_VIS3" +{ + sparc_expand_vcond (V8QImode, operands, + UNSPEC_CMASK8, + UNSPEC_FUCMP); + DONE; +}) + (define_insn "array8_vis" [(set (match_operand:P 0 "register_operand" "=r") (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ") @@ -8386,7 +8456,7 @@ ;; 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") + (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ") (reg:DI GSR_REG)] UNSPEC_CMASK8))] "TARGET_VIS3" @@ -8394,7 +8464,7 @@ (define_insn "cmask16_vis" [(set (reg:DI GSR_REG) - (unspec:DI [(match_operand:P 0 "register_operand" "r") + (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ") (reg:DI GSR_REG)] UNSPEC_CMASK16))] "TARGET_VIS3" @@ -8402,7 +8472,7 @@ (define_insn "cmask32_vis" [(set (reg:DI GSR_REG) - (unspec:DI [(match_operand:P 0 "register_operand" "r") + (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ") (reg:DI GSR_REG)] UNSPEC_CMASK32))] "TARGET_VIS3"