sparc.c (sparc_emit_floatunsdi): New.
authorRichard Henderson <rth@redhat.com>
Sun, 24 Mar 2002 02:23:47 +0000 (18:23 -0800)
committerRichard Henderson <rth@gcc.gnu.org>
Sun, 24 Mar 2002 02:23:47 +0000 (18:23 -0800)
        * config/sparc/sparc.c (sparc_emit_floatunsdi): New.
        * config/sparc/sparc-protos.h: Update.
        * config/sparc/sparc.md (floatunsdisf2, floatunsdidf2): New.

From-SVN: r51249

gcc/ChangeLog
gcc/config/sparc/sparc-protos.h
gcc/config/sparc/sparc.c
gcc/config/sparc/sparc.md

index ed88252a71d1471e1258bc3048ca0f4b8bbeea5d..5320d1305229946d869fa395397dc33532c14511 100644 (file)
@@ -1,3 +1,9 @@
+2002-03-23  Richard Henderson  <rth@redhat.com>
+
+       * 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  <rth@redhat.com>
 
        * config/sparc/gmon-sol2.c (internal_mcount): Assume either
index 682b7bdb8533e5e57c1b5bba4277eca01cae1f3c..269844eff7291e19a2cf4388344c87a40d113319 100644 (file)
@@ -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));
index a18046c16eb215983ff7dab97f4bc6451df69633..d1fbe2d1e0aba3b50a6473be10321831322b0c17 100644 (file)
@@ -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
index c203e4fa89208eabad641998415d07d67d3dfdaf..e1810f66a5c58791b8449980c40febdd14592035 100644 (file)
   [(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")))]
   [(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")))]