diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a7939039d3b..43797c2c706 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2000-01-26 Richard Henderson + + * alpha.c (alpha_split_tfmode_pair): New. + * alpha-protos.h: Declare it. + * alpha.md (abstf2, negtf2): New. + (movtf insn): Add input G constraint. + (movtf splitter): Use alpha_split_tfmode_pair. + 2000-01-26 Kaveh R. Ghazi * i386/cygwin.h: PROTO -> PARAMS. diff --git a/gcc/config/alpha/alpha-protos.h b/gcc/config/alpha/alpha-protos.h index 693fa245bcc..fafe17b3e13 100644 --- a/gcc/config/alpha/alpha-protos.h +++ b/gcc/config/alpha/alpha-protos.h @@ -83,6 +83,7 @@ extern rtx alpha_emit_conditional_branch PARAMS ((enum rtx_code)); extern rtx alpha_emit_conditional_move PARAMS ((rtx, enum machine_mode)); extern void alpha_emit_xfloating_arith PARAMS ((enum rtx_code, rtx[])); extern void alpha_emit_xfloating_cvt PARAMS ((enum rtx_code, rtx[])); +extern void alpha_split_tfmode_pair PARAMS ((rtx[])); extern void alpha_expand_unaligned_load PARAMS ((rtx, rtx, HOST_WIDE_INT, HOST_WIDE_INT, int)); extern void alpha_expand_unaligned_store PARAMS ((rtx, rtx, HOST_WIDE_INT, diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index 23faed8d250..d4300334b16 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -2008,6 +2008,41 @@ alpha_emit_xfloating_cvt (code, operands) gen_rtx_fmt_e (code, GET_MODE (operands[0]), operands[1])); } + +void +alpha_split_tfmode_pair (operands) + rtx operands[4]; +{ + if (GET_CODE (operands[1]) == REG) + { + operands[3] = gen_rtx_REG (DImode, REGNO (operands[1]) + 1); + operands[2] = gen_rtx_REG (DImode, REGNO (operands[1])); + } + else if (GET_CODE (operands[1]) == MEM) + { + operands[3] = change_address (operands[1], DImode, + plus_constant (XEXP (operands[1], 0), 8)); + operands[2] = change_address (operands[1], DImode, NULL_RTX); + } + else if (operands[1] == CONST0_RTX (TFmode)) + operands[2] = operands[3] = const0_rtx; + else + abort (); + + if (GET_CODE (operands[0]) == REG) + { + operands[1] = gen_rtx_REG (DImode, REGNO (operands[0]) + 1); + operands[0] = gen_rtx_REG (DImode, REGNO (operands[0])); + } + else if (GET_CODE (operands[0]) == MEM) + { + operands[1] = change_address (operands[0], DImode, + plus_constant (XEXP (operands[0], 0), 8)); + operands[0] = change_address (operands[0], DImode, NULL_RTX); + } + else + abort (); +} /* Use ext[wlq][lh] as the Architecture Handbook describes for extracting unaligned data: diff --git a/gcc/config/alpha/alpha.md b/gcc/config/alpha/alpha.md index 2325483d02d..0202642f02f 100644 --- a/gcc/config/alpha/alpha.md +++ b/gcc/config/alpha/alpha.md @@ -1771,6 +1771,58 @@ "cpys $f31,%R1,%0" [(set_attr "type" "fcpys")]) +(define_expand "abstf2" + [(parallel [(set (match_operand:TF 0 "register_operand" "") + (neg:TF (match_operand:TF 1 "reg_or_fp0_operand" ""))) + (use (match_dup 2))])] + "TARGET_HAS_XFLOATING_LIBS" + " +{ +#if HOST_BITS_PER_WIDE_INT >= 64 + operands[2] = force_reg (DImode, GEN_INT (0x8000000000000000)); +#else + operands[2] = force_reg (DImode, immed_double_const (0, 0x80000000, DImode)); +#endif +}") + +(define_insn "" + [(set (match_operand:TF 0 "register_operand" "=r") + (abs:TF (match_operand:TF 1 "reg_or_fp0_operand" "rG"))) + (use (match_operand:DI 2 "register_operand" "=r"))] + "TARGET_HAS_XFLOATING_LIBS" + "#") + +(define_split + [(set (match_operand:TF 0 "register_operand" "") + (abs:TF (match_operand:TF 1 "reg_or_fp0_operand" ""))) + (use (match_operand:DI 4 "register_operand" ""))] + "reload_completed" + [(const_int 0)] + " +{ + int move; + rtx tmp; + + alpha_split_tfmode_pair (operands); + + move = 1; + if (rtx_equal_p (operands[0], operands[2])) + move = 0; + else if (rtx_equal_p (operands[0], operands[3])) + move = -1; + + if (move < 0) + emit_move_insn (operands[1], operands[3]); + + tmp = gen_rtx_NOT (DImode, operands[4]); + tmp = gen_rtx_AND (DImode, tmp, operands[2]); + emit_insn (gen_rtx_SET (VOIDmode, operands[0], tmp)); + + if (move > 0) + emit_move_insn (operands[1], operands[3]); + DONE; +}") + (define_insn "negsf2" [(set (match_operand:SF 0 "register_operand" "=f") (neg:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))] @@ -1785,6 +1837,55 @@ "cpysn %R1,%R1,%0" [(set_attr "type" "fadd")]) +(define_expand "negtf2" + [(parallel [(set (match_operand:TF 0 "register_operand" "") + (neg:TF (match_operand:TF 1 "reg_or_fp0_operand" ""))) + (use (match_dup 2))])] + "TARGET_HAS_XFLOATING_LIBS" + " +{ +#if HOST_BITS_PER_WIDE_INT >= 64 + operands[2] = force_reg (DImode, GEN_INT (0x8000000000000000)); +#else + operands[2] = force_reg (DImode, immed_double_const (0, 0x80000000, DImode)); +#endif +}") + +(define_insn "" + [(set (match_operand:TF 0 "register_operand" "=r") + (neg:TF (match_operand:TF 1 "reg_or_fp0_operand" "rG"))) + (use (match_operand:DI 2 "register_operand" "=r"))] + "TARGET_HAS_XFLOATING_LIBS" + "#") + +(define_split + [(set (match_operand:TF 0 "register_operand" "") + (neg:TF (match_operand:TF 1 "reg_or_fp0_operand" ""))) + (use (match_operand:DI 4 "register_operand" ""))] + "reload_completed" + [(const_int 0)] + " +{ + int move; + + alpha_split_tfmode_pair (operands); + + move = 1; + if (rtx_equal_p (operands[0], operands[2])) + move = 0; + else if (rtx_equal_p (operands[0], operands[3])) + move = -1; + + if (move < 0) + emit_move_insn (operands[1], operands[3]); + + emit_insn (gen_xordi3 (operands[0], operands[2], operands[4])); + + if (move > 0) + emit_move_insn (operands[1], operands[3]); + DONE; +}") + (define_insn "" [(set (match_operand:SF 0 "register_operand" "=&f") (plus:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG") @@ -4096,7 +4197,7 @@ ;; data between general registers until after reload. (define_insn "" [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o") - (match_operand:TF 1 "input_operand" "ro,r"))] + (match_operand:TF 1 "input_operand" "roG,r"))] "register_operand (operands[0], TFmode) || reg_or_fp0_operand (operands[1], TFmode)" "#") @@ -4109,30 +4210,7 @@ (set (match_dup 1) (match_dup 3))] " { - if (GET_CODE (operands[1]) == REG) - { - operands[3] = gen_rtx_REG (DImode, REGNO (operands[1]) + 1); - operands[2] = gen_rtx_REG (DImode, REGNO (operands[1])); - } - else if (GET_CODE (operands[1]) == MEM) - { - operands[3] = change_address (operands[1], DImode, - plus_constant (XEXP (operands[1], 0), 8)); - operands[2] = change_address (operands[1], DImode, NULL_RTX); - } - - if (GET_CODE (operands[0]) == REG) - { - operands[1] = gen_rtx_REG (DImode, REGNO (operands[0]) + 1); - operands[0] = gen_rtx_REG (DImode, REGNO (operands[0])); - } - else if (GET_CODE (operands[0]) == MEM) - { - operands[1] = change_address (operands[0], DImode, - plus_constant (XEXP (operands[0], 0), 8)); - operands[0] = change_address (operands[0], DImode, NULL_RTX); - } - + alpha_split_tfmode_pair (operands); if (rtx_equal_p (operands[0], operands[3])) { rtx tmp; @@ -4141,8 +4219,6 @@ } }") - - (define_expand "movsf" [(set (match_operand:SF 0 "nonimmediate_operand" "") (match_operand:SF 1 "general_operand" ""))]