sparc-protos.h (sparc_emit_floatunsdi): Add 'mode'.

* config/sparc/sparc-protos.h (sparc_emit_floatunsdi): Add 'mode'.
	(sparc_emit_fixunsdi): New prototype.
	* config/sparc/sparc.c (sparc_emit_floatunsdi): Use 'mode' argument.
	(sparc_emit_fixunsdi): New function.
	* config/sparc/sparc.md (floatunsdisf2): Use 'general_operand' for
	operand 1.  Pass SFmode to sparc_emit_floatunsdi.
	(floatunsdidf2): Use 'general_operand' for operand 1.  Pass DFmode
	to sparc_emit_floatunsdi.
	(fixuns_truncsfdi2): New expander.
	(fixuns_truncdfdi2): Likewise.

From-SVN: r78511
This commit is contained in:
Eric Botcazou 2004-02-26 19:40:41 +01:00 committed by Eric Botcazou
parent 413580dc79
commit b178305dfd
6 changed files with 108 additions and 8 deletions

View file

@ -1,3 +1,16 @@
2004-02-26 Eric Botcazou <ebotcazou@act-europe.fr>
* config/sparc/sparc-protos.h (sparc_emit_floatunsdi): Add 'mode'.
(sparc_emit_fixunsdi): New prototype.
* config/sparc/sparc.c (sparc_emit_floatunsdi): Use 'mode' argument.
(sparc_emit_fixunsdi): New function.
* config/sparc/sparc.md (floatunsdisf2): Use 'general_operand' for
operand 1. Pass SFmode to sparc_emit_floatunsdi.
(floatunsdidf2): Use 'general_operand' for operand 1. Pass DFmode
to sparc_emit_floatunsdi.
(fixuns_truncsfdi2): New expander.
(fixuns_truncdfdi2): Likewise.
2004-02-26 Alan Modra <amodra@bigpond.net.au>
* gcse.c (delete_null_pointer_checks_1): Do not delete CC setter

View file

@ -63,7 +63,8 @@ extern enum machine_mode select_cc_mode (enum rtx_code, rtx, rtx);
/* Define the function that build the compare insn for scc and bcc. */
extern rtx gen_compare_reg (enum rtx_code code, rtx, rtx);
extern void sparc_emit_float_lib_cmp (rtx, rtx, enum rtx_code);
extern void sparc_emit_floatunsdi (rtx [2]);
extern void sparc_emit_floatunsdi (rtx [2], enum machine_mode);
extern void sparc_emit_fixunsdi (rtx [2], enum machine_mode);
extern void emit_tfmode_binop (enum rtx_code, rtx *);
extern void emit_tfmode_unop (enum rtx_code, rtx *);
extern void emit_tfmode_cvt (enum rtx_code, rtx *);

View file

@ -6419,14 +6419,12 @@ sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison)
optabs would emit if we didn't have TFmode patterns. */
void
sparc_emit_floatunsdi (rtx *operands)
sparc_emit_floatunsdi (rtx *operands, enum machine_mode mode)
{
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);
@ -6450,6 +6448,47 @@ sparc_emit_floatunsdi (rtx *operands)
emit_label (donelab);
}
/* Generate an FP to unsigned DImode conversion. This is the same code
optabs would emit if we didn't have TFmode patterns. */
void
sparc_emit_fixunsdi (rtx *operands, enum machine_mode mode)
{
rtx neglab, donelab, i0, i1, f0, in, out, limit;
out = operands[0];
in = force_reg (mode, operands[1]);
neglab = gen_label_rtx ();
donelab = gen_label_rtx ();
i0 = gen_reg_rtx (DImode);
i1 = gen_reg_rtx (DImode);
limit = gen_reg_rtx (mode);
f0 = gen_reg_rtx (mode);
emit_move_insn (limit,
CONST_DOUBLE_FROM_REAL_VALUE (
REAL_VALUE_ATOF ("9223372036854775808.0", mode), mode));
emit_cmp_and_jump_insns (in, limit, GE, NULL_RTX, mode, 0, neglab);
emit_insn (gen_rtx_SET (VOIDmode,
out,
gen_rtx_FIX (DImode, gen_rtx_FIX (mode, in))));
emit_jump_insn (gen_jump (donelab));
emit_barrier ();
emit_label (neglab);
emit_insn (gen_rtx_SET (VOIDmode, f0, gen_rtx_MINUS (mode, in, limit)));
emit_insn (gen_rtx_SET (VOIDmode,
i0,
gen_rtx_FIX (DImode, gen_rtx_FIX (mode, f0))));
emit_insn (gen_movdi (i1, const1_rtx));
emit_insn (gen_ashldi3 (i1, i1, GEN_INT (63)));
emit_insn (gen_xordi3 (out, i0, i1));
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

View file

@ -4662,9 +4662,9 @@
(define_expand "floatunsdisf2"
[(use (match_operand:SF 0 "register_operand" ""))
(use (match_operand:DI 1 "register_operand" ""))]
(use (match_operand:DI 1 "general_operand" ""))]
"TARGET_ARCH64 && TARGET_FPU"
"sparc_emit_floatunsdi (operands); DONE;")
"sparc_emit_floatunsdi (operands, SFmode); DONE;")
(define_insn "floatdidf2"
[(set (match_operand:DF 0 "register_operand" "=e")
@ -4676,9 +4676,9 @@
(define_expand "floatunsdidf2"
[(use (match_operand:DF 0 "register_operand" ""))
(use (match_operand:DI 1 "register_operand" ""))]
(use (match_operand:DI 1 "general_operand" ""))]
"TARGET_ARCH64 && TARGET_FPU"
"sparc_emit_floatunsdi (operands); DONE;")
"sparc_emit_floatunsdi (operands, DFmode); DONE;")
(define_expand "floatditf2"
[(set (match_operand:TF 0 "nonimmediate_operand" "")
@ -4747,6 +4747,12 @@
[(set_attr "type" "fp")
(set_attr "fptype" "double")])
(define_expand "fixuns_truncsfdi2"
[(use (match_operand:DI 0 "register_operand" ""))
(use (match_operand:SF 1 "general_operand" ""))]
"TARGET_ARCH64 && TARGET_FPU"
"sparc_emit_fixunsdi (operands, SFmode); DONE;")
(define_insn "fix_truncdfdi2"
[(set (match_operand:DI 0 "register_operand" "=e")
(fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
@ -4755,6 +4761,12 @@
[(set_attr "type" "fp")
(set_attr "fptype" "double")])
(define_expand "fixuns_truncdfdi2"
[(use (match_operand:DI 0 "register_operand" ""))
(use (match_operand:DF 1 "general_operand" ""))]
"TARGET_ARCH64 && TARGET_FPU"
"sparc_emit_fixunsdi (operands, DFmode); DONE;")
(define_expand "fix_trunctfdi2"
[(set (match_operand:DI 0 "register_operand" "")
(fix:DI (match_operand:TF 1 "general_operand" "")))]

View file

@ -1,3 +1,7 @@
2004-02-26 Eric Botcazou <ebotcazou@act-europe.fr>
* gcc.dg/fixuns-trunc-1.c: New test.
2004-02-26 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
* gcc.dg/builtins-config.h: Use #elif.

View file

@ -0,0 +1,31 @@
/* { dg-do run } */
/* { dg-options "-std=c99" } */
unsigned long foo(double d)
{
return (unsigned long) d;
}
extern void abort(void);
int main(void)
{
double d;
unsigned long l;
#ifdef __LP64__
d = 9223372036854775808.7;
l = 1LL << 63;
if (foo(d) != l)
abort();
#endif
d = 122485.2;
l = 122485;
if (foo(d) != l)
abort();
return 0;
}