diff mbox

[committed] TILE-Gx: add float conversion patterns.

Message ID 201303260655.r2Q6tSiT017301@farm-0001.internal.tilera.com
State New
Headers show

Commit Message

Walter Lee March 26, 2013, 6:55 a.m. UTC
This patch adds patterns for floatsisf2, floatunssisf2, floatsidf2,
and floatunssidf2.

	* config/tilegx/tilegx.md (floatsisf2): New pattern.
        (floatunssisf2): New pattern.
        (floatsidf2): New pattern.
        (floatunssidf2): New pattern.
diff mbox

Patch

Index: gcc/config/tilegx/tilegx.md
===================================================================
--- gcc/config/tilegx/tilegx.md	(revision 197072)
+++ gcc/config/tilegx/tilegx.md	(working copy)
@@ -2129,6 +2129,108 @@ 
   ""
   "rotl\t%0, %r1, %r2")
 
+;; Integer to floating point conversions
+
+(define_expand "floatsisf2"
+  [(set (match_operand:SF 0 "register_operand" "")
+	(float:SI (match_operand:SI 1 "register_operand" "")))]
+  ""
+{
+  rtx result = gen_lowpart (DImode, operands[0]);
+  rtx a = operands[1];
+
+  rtx nega = gen_reg_rtx (SImode);
+  rtx exp = gen_reg_rtx (DImode);
+  rtx sign = gen_reg_rtx (DImode);
+  rtx abs = gen_reg_rtx (DImode);
+  rtx flags = gen_reg_rtx (DImode);
+  rtx tmp1 = gen_reg_rtx (DImode);
+  rtx tmp2 = gen_reg_rtx (DImode);
+
+  emit_move_insn (exp, GEN_INT (0x9e));
+
+  emit_insn (gen_negsi2 (nega, a));
+
+  emit_insn (gen_insn_cmplts_sisi (gen_lowpart (SImode, sign), a, const0_rtx));
+  emit_insn (gen_insn_cmoveqz (abs, gen_lowpart (DImode, nega), sign,
+			       gen_lowpart (DImode, a)));
+
+  emit_insn (gen_insn_bfins (tmp1, exp, sign, GEN_INT (10), GEN_INT (10)));
+  emit_insn (gen_insn_bfins (tmp2, tmp1, abs, GEN_INT (32), GEN_INT (63)));
+  emit_insn (gen_insn_fsingle_pack1 (flags, tmp2));
+  emit_insn (gen_insn_fsingle_pack2 (result, tmp2, flags));
+  DONE;
+})
+  
+(define_expand "floatunssisf2"
+  [(set (match_operand:SF 0 "register_operand" "")
+	(float:SI (match_operand:SI 1 "register_operand" "")))]
+  ""
+{
+  rtx result = gen_lowpart (DImode, operands[0]);
+  rtx a = operands[1];
+
+  rtx exp = gen_reg_rtx (DImode);
+  rtx flags = gen_reg_rtx (DImode);
+  rtx tmp = gen_reg_rtx (DImode);
+
+  emit_move_insn (exp, GEN_INT (0x9e));
+  emit_insn (gen_insn_bfins (tmp, exp, gen_lowpart (DImode, a),
+                             GEN_INT (32), GEN_INT (63)));
+  emit_insn (gen_insn_fsingle_pack1 (flags, tmp));
+  emit_insn (gen_insn_fsingle_pack2 (result, tmp, flags));
+  DONE;
+})
+
+(define_expand "floatsidf2"
+  [(set (match_operand:DF 0 "register_operand" "")
+	(float:SI (match_operand:SI 1 "register_operand" "")))]
+  ""
+{
+  rtx result = gen_lowpart (DImode, operands[0]);
+  rtx a = gen_lowpart (DImode, operands[1]);
+
+  rtx nega = gen_reg_rtx (DImode);
+  rtx exp = gen_reg_rtx (DImode);
+  rtx sign = gen_reg_rtx (DImode);
+  rtx abs = gen_reg_rtx (DImode);
+  rtx tmp1 = gen_reg_rtx (DImode);
+  rtx tmp2 = gen_reg_rtx (DImode);
+  rtx tmp3 = gen_reg_rtx (DImode);
+
+  emit_move_insn (exp, GEN_INT (0x21b00));
+
+  emit_insn (gen_negdi2 (nega, a));
+
+  emit_insn (gen_insn_cmplts_didi (sign, a, const0_rtx));
+  emit_insn (gen_insn_cmovnez (abs, a, sign, nega));
+
+  emit_insn (gen_ashldi3 (tmp1, abs, GEN_INT (4)));
+  emit_insn (gen_insn_bfins (tmp2, exp, sign, GEN_INT (20), GEN_INT (20)));
+  emit_insn (gen_insn_fdouble_pack1 (tmp3, tmp1, tmp2));
+  emit_insn (gen_insn_fdouble_pack2 (result, tmp3, tmp1, const0_rtx));
+  DONE;
+})
+  
+(define_expand "floatunssidf2"
+  [(set (match_operand:DF 0 "register_operand" "")
+	(float:SI (match_operand:SI 1 "register_operand" "")))]
+  ""
+{
+  rtx result = gen_lowpart (DImode, operands[0]);
+  rtx a = gen_lowpart (DImode, operands[1]);
+
+  rtx exp = gen_reg_rtx (DImode);
+  rtx tmp1 = gen_reg_rtx (DImode);
+  rtx tmp2 = gen_reg_rtx (DImode);
+
+  emit_move_insn (exp, GEN_INT (0x21b00));
+  emit_insn (gen_insn_bfins (tmp1, const0_rtx, a, GEN_INT (4), GEN_INT (35)));
+  emit_insn (gen_insn_fdouble_pack1 (tmp2, tmp1, exp));
+  emit_insn (gen_insn_fdouble_pack2 (result, tmp2, tmp1, const0_rtx));
+  DONE;
+})
+  
 
 ;;
 ;; Multiplies