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:
parent
413580dc79
commit
b178305dfd
6 changed files with 108 additions and 8 deletions
|
@ -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
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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" "")))]
|
||||
|
|
|
@ -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.
|
||||
|
|
31
gcc/testsuite/gcc.dg/fixuns-trunc-1.c
Normal file
31
gcc/testsuite/gcc.dg/fixuns-trunc-1.c
Normal 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;
|
||||
}
|
Loading…
Add table
Reference in a new issue