diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/config/i386/i386-protos.h | 1 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 35 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 18 |
4 files changed, 61 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0bcfdb4..4c27343 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +Wed Feb 5 23:12:57 CET 2003 Jan Hubicka <jh@suse.cz> + + * i386-protos.h (x86_emit_floatuns): Declare. + * i386.c (x86_emit_floatuns): New global function. + * i386.md (floatunssisf2, floatunsdisf2, + floatunsdidf2): New patterns. + 2003-01-25 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz> * cfgloopmanip.c (force_single_succ_latches): Fix missindentation. diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index c5349a0..46493fd 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -189,6 +189,7 @@ extern void emit_i387_cw_initialization PARAMS ((rtx, rtx)); extern bool ix86_fp_jump_nontrivial_p PARAMS ((enum rtx_code)); extern void x86_order_regs_for_local_alloc PARAMS ((void)); extern void x86_function_profiler PARAMS ((FILE *, int)); +extern void x86_emit_floatuns PARAMS ((rtx [2])); #ifdef TREE_CODE diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 3f2deee..3a3a2f9 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -15337,4 +15337,39 @@ x86_extended_reg_mentioned_p (insn) return for_each_rtx (&PATTERN (insn), extended_reg_mentioned_1, NULL); } +/* Generate an unsigned DImode to FP conversion. This is the same code + optabs would emit if we didn't have TFmode patterns. */ + +void +x86_emit_floatuns (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 (); + i1 = gen_reg_rtx (Pmode); + f0 = gen_reg_rtx (mode); + + emit_cmp_and_jump_insns (in, const0_rtx, LT, const0_rtx, Pmode, 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); + + i0 = expand_simple_binop (Pmode, LSHIFTRT, in, const1_rtx, NULL, 1, OPTAB_DIRECT); + i1 = expand_simple_binop (Pmode, AND, in, const1_rtx, NULL, 1, OPTAB_DIRECT); + i0 = expand_simple_binop (Pmode, IOR, i0, i1, i0, 1, OPTAB_DIRECT); + expand_float (f0, i0, 0); + emit_insn (gen_rtx_SET (VOIDmode, out, gen_rtx_PLUS (mode, f0, f0))); + + emit_label (donelab); +} + #include "gt-i386.h" diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index a1eb241..875617d 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -4924,6 +4924,24 @@ ix86_free_from_memory (GET_MODE (operands[1])); DONE; }) + +(define_expand "floatunssisf2" + [(use (match_operand:SF 0 "register_operand" "")) + (use (match_operand:SI 1 "register_operand" ""))] + "TARGET_SSE && TARGET_SSE_MATH && !TARGET_64BIT" + "x86_emit_floatuns (operands); DONE;") + +(define_expand "floatunsdisf2" + [(use (match_operand:SF 0 "register_operand" "")) + (use (match_operand:DI 1 "register_operand" ""))] + "TARGET_SSE && TARGET_SSE_MATH && TARGET_64BIT" + "x86_emit_floatuns (operands); DONE;") + +(define_expand "floatunsdidf2" + [(use (match_operand:DF 0 "register_operand" "")) + (use (match_operand:DI 1 "register_operand" ""))] + "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_64BIT" + "x86_emit_floatuns (operands); DONE;") ;; Add instructions |