t-spu-elf (LIB2FUNCS_EXCLUDE): Add _floattisf and _floatunstisf.
authorUlrich Weigand <uweigand@de.ibm.com>
Fri, 17 Dec 2010 14:10:02 +0000 (14:10 +0000)
committerUlrich Weigand <uweigand@gcc.gnu.org>
Fri, 17 Dec 2010 14:10:02 +0000 (14:10 +0000)
* config/spu/t-spu-elf (LIB2FUNCS_EXCLUDE): Add _floattisf and
_floatunstisf.
* config/spu/spu.md ("floattisf2"): New expander.
("floatunstisf2"): New insn pattern and splitter.
("cgt_ti_m1"): New insn pattern.

From-SVN: r167984

gcc/ChangeLog
gcc/config/spu/spu.md
gcc/config/spu/t-spu-elf

index 8aab810bd618382f7c60b759539b2e9b03b649ac..864cc63951461cfec8cf94e6481fc1b9bcac34ac 100644 (file)
@@ -1,3 +1,11 @@
+2010-12-17  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>
+
+       * config/spu/t-spu-elf (LIB2FUNCS_EXCLUDE): Add _floattisf and
+       _floatunstisf.
+       * config/spu/spu.md ("floattisf2"): New expander.
+       ("floatunstisf2"): New insn pattern and splitter.
+       ("cgt_ti_m1"): New insn pattern.
+
 2010-12-17  Bernd Schmidt  <bernds@codesourcery.com>
 
        * config/arm/arm.c (arm_select_cc_mode): Before calling
index 528a07cfd03c8917df5565332ad87c140840997f..c9bf3c828d54ac9862154caf57a684fdf23e6a0e 100644 (file)
     DONE;
   })
 
+(define_expand "floattisf2"
+  [(set (match_operand:SF 0 "register_operand" "")
+       (float:SF (match_operand:TI 1 "register_operand" "")))]
+  ""
+  {
+    rtx c0 = gen_reg_rtx (SImode);
+    rtx r0 = gen_reg_rtx (TImode);
+    rtx r1 = gen_reg_rtx (SFmode);
+    rtx r2 = gen_reg_rtx (SImode);
+    rtx setneg = gen_reg_rtx (SImode);
+    rtx isneg = gen_reg_rtx (SImode);
+    rtx neg = gen_reg_rtx (TImode);
+    rtx mask = gen_reg_rtx (TImode);
+
+    emit_move_insn (c0, GEN_INT (-0x80000000ll));
+
+    emit_insn (gen_negti2 (neg, operands[1]));
+    emit_insn (gen_cgt_ti_m1 (isneg, operands[1]));
+    emit_insn (gen_extend_compare (mask, isneg));
+    emit_insn (gen_selb (r0, neg, operands[1], mask));
+    emit_insn (gen_andc_si (setneg, c0, isneg));
+
+    emit_insn (gen_floatunstisf2 (r1, r0));
+
+    emit_insn (gen_iorsi3 (r2, gen_rtx_SUBREG (SImode, r1, 0), setneg));
+    emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, r2, 0));
+    DONE;
+  })
+
+(define_insn_and_split "floatunstisf2"
+  [(set (match_operand:SF 0 "register_operand" "=r")
+        (unsigned_float:SF (match_operand:TI 1 "register_operand" "r")))
+   (clobber (match_scratch:SF 2 "=r"))
+   (clobber (match_scratch:SF 3 "=r"))
+   (clobber (match_scratch:SF 4 "=r"))]
+  ""
+  "#"
+  "reload_completed"
+  [(set (match_dup:SF 0)
+        (unsigned_float:SF (match_dup:TI 1)))]
+  {
+    rtx op1_v4si = gen_rtx_REG (V4SImode, REGNO (operands[1]));
+    rtx op2_v4sf = gen_rtx_REG (V4SFmode, REGNO (operands[2]));
+    rtx op2_ti = gen_rtx_REG (TImode, REGNO (operands[2]));
+    rtx op3_ti = gen_rtx_REG (TImode, REGNO (operands[3]));
+
+    REAL_VALUE_TYPE scale;
+    real_2expN (&scale, 32, SFmode);
+
+    emit_insn (gen_floatunsv4siv4sf2 (op2_v4sf, op1_v4si));
+    emit_insn (gen_shlqby_ti (op3_ti, op2_ti, GEN_INT (4)));
+
+    emit_move_insn (operands[4],
+                   CONST_DOUBLE_FROM_REAL_VALUE (scale, SFmode));
+    emit_insn (gen_fmasf4 (operands[2],
+                          operands[2], operands[4], operands[3]));
+
+    emit_insn (gen_shlqby_ti (op3_ti, op3_ti, GEN_INT (4)));
+    emit_insn (gen_fmasf4 (operands[2],
+                          operands[2], operands[4], operands[3]));
+
+    emit_insn (gen_shlqby_ti (op3_ti, op3_ti, GEN_INT (4)));
+    emit_insn (gen_fmasf4 (operands[0],
+                          operands[2], operands[4], operands[3]));
+    DONE;
+  })
+
 ;; Do (double)(operands[1]+0x80000000u)-(double)0x80000000
 (define_expand "floatsidf2"
   [(set (match_operand:DF 0 "register_operand" "")
     DONE;
   })
 
+(define_insn "cgt_ti_m1" 
+  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
+       (gt:SI (match_operand:TI 1 "spu_reg_operand" "r")
+              (const_int -1)))]
+  ""
+  "cgti\t%0,%1,-1")
+
 (define_insn "cgt_ti"
   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
        (gt:SI (match_operand:TI 1 "spu_reg_operand" "r")
index 341a5aadee3d032e21574099e5d6c552751fd545..a131f64883b140911a415b9f44d25e56179c2f78 100644 (file)
@@ -26,8 +26,8 @@ TARGET_LIBGCC2_CFLAGS = -fPIC -mwarn-reloc -D__IN_LIBGCC2
 
 # We exclude those because the libgcc2.c default versions do not support
 # the SPU single-precision format (round towards zero).  We provide our
-# own versions below.
-LIB2FUNCS_EXCLUDE = _floatdisf _floatundisf
+# own versions below and/or via direct expansion.
+LIB2FUNCS_EXCLUDE = _floatdisf _floatundisf _floattisf _floatunstisf
 
 # We provide our own version of __divdf3 that performs better and has
 # better support for non-default rounding modes.