diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ed88252a71d..5320d130522 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2002-03-23 Richard Henderson + + * config/sparc/sparc.c (sparc_emit_floatunsdi): New. + * config/sparc/sparc-protos.h: Update. + * config/sparc/sparc.md (floatunsdisf2, floatunsdidf2): New. + 2002-03-23 Richard Henderson * config/sparc/gmon-sol2.c (internal_mcount): Assume either diff --git a/gcc/config/sparc/sparc-protos.h b/gcc/config/sparc/sparc-protos.h index 682b7bdb853..269844eff72 100644 --- a/gcc/config/sparc/sparc-protos.h +++ b/gcc/config/sparc/sparc-protos.h @@ -74,6 +74,7 @@ extern enum machine_mode select_cc_mode PARAMS ((enum rtx_code, rtx, rtx)); /* Define the function that build the compare insn for scc and bcc. */ extern rtx gen_compare_reg PARAMS ((enum rtx_code code, rtx, rtx)); extern void sparc_emit_float_lib_cmp PARAMS ((rtx, rtx, enum rtx_code)); +extern void sparc_emit_floatunsdi PARAMS ((rtx [2])); /* This function handles all v9 scc insns */ extern int gen_v9_scc PARAMS ((enum rtx_code, rtx *)); extern void sparc_initialize_trampoline PARAMS ((rtx, rtx, rtx)); diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index a18046c16eb..d1fbe2d1e0a 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -5420,6 +5420,42 @@ sparc_emit_float_lib_cmp (x, y, comparison) } } +/* Generate an unsigned DImode to FP conversion. This is the same code + optabs would emit if we didn't have TFmode patterns. */ + +void +sparc_emit_floatunsdi (operands) + rtx operands[2]; +{ + rtx neglab, donelab, i0, i1, f0, in, out; + enum machine_mode mode; + + out = operands[0]; + in = force_reg (DImode, operands[1]); + mode = GET_MODE (out); + neglab = gen_label_rtx (); + donelab = gen_label_rtx (); + i0 = gen_reg_rtx (DImode); + i1 = gen_reg_rtx (DImode); + f0 = gen_reg_rtx (mode); + + emit_cmp_and_jump_insns (in, const0_rtx, LT, const0_rtx, DImode, 0, neglab); + + emit_insn (gen_rtx_SET (VOIDmode, out, gen_rtx_FLOAT (mode, in))); + emit_jump_insn (gen_jump (donelab)); + emit_barrier (); + + emit_label (neglab); + + emit_insn (gen_lshrdi3 (i0, in, const1_rtx)); + emit_insn (gen_anddi3 (i1, in, const1_rtx)); + emit_insn (gen_iordi3 (i0, i0, i1)); + emit_insn (gen_rtx_SET (VOIDmode, f0, gen_rtx_FLOAT (mode, i0))); + emit_insn (gen_rtx_SET (VOIDmode, out, gen_rtx_PLUS (mode, f0, f0))); + + emit_label (donelab); +} + /* Return the string to output a conditional branch to LABEL, testing register REG. LABEL is the operand number of the label; REG is the operand number of the reg. OP is the conditional expression. The mode diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index c203e4fa892..e1810f66a5c 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -5243,6 +5243,12 @@ [(set_attr "type" "fp") (set_attr "fptype" "double")]) +(define_expand "floatunsdisf2" + [(use (match_operand:SF 0 "register_operand" "")) + (use (match_operand:DI 1 "register_operand" ""))] + "TARGET_ARCH64 && TARGET_FPU" + "sparc_emit_floatunsdi (operands); DONE;") + (define_insn "floatdidf2" [(set (match_operand:DF 0 "register_operand" "=e") (float:DF (match_operand:DI 1 "register_operand" "e")))] @@ -5251,6 +5257,12 @@ [(set_attr "type" "fp") (set_attr "fptype" "double")]) +(define_expand "floatunsdidf2" + [(use (match_operand:DF 0 "register_operand" "")) + (use (match_operand:DI 1 "register_operand" ""))] + "TARGET_ARCH64 && TARGET_FPU" + "sparc_emit_floatunsdi (operands); DONE;") + (define_expand "floatditf2" [(set (match_operand:TF 0 "register_operand" "=e") (float:TF (match_operand:DI 1 "register_operand" "e")))]