diff options
author | Michael Meissner <meissner@linux.vnet.ibm.com> | 2010-11-09 21:44:19 +0000 |
---|---|---|
committer | Michael Meissner <meissner@gcc.gnu.org> | 2010-11-09 21:44:19 +0000 |
commit | 219225619219329ca995c78627a894224df58b3f (patch) | |
tree | 188dd25b42448ce9d4a19497d84bc0355c876a5b /gcc/config/rs6000/rs6000.c | |
parent | 9b999dc5ea45237cc7accead90a33e9c4a6893f5 (diff) | |
download | gcc-219225619219329ca995c78627a894224df58b3f.tar.gz |
Improve powerpc floating point rounding
From-SVN: r166510
Diffstat (limited to 'gcc/config/rs6000/rs6000.c')
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 84 |
1 files changed, 16 insertions, 68 deletions
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index eadc1222c44..e441c70bd9b 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -27230,82 +27230,30 @@ rs6000_address_for_fpconvert (rtx x) addr = XEXP (x, 0); if (! legitimate_indirect_address_p (addr, strict_p) && ! legitimate_indexed_address_p (addr, strict_p)) - x = replace_equiv_address (x, copy_addr_to_reg (addr)); - - return x; -} - -/* Expand 32-bit int -> floating point conversions. Return true if - successful. */ - -void -rs6000_expand_convert_si_to_sfdf (rtx dest, rtx src, bool unsigned_p) -{ - enum machine_mode dmode = GET_MODE (dest); - rtx (*func_si) (rtx, rtx, rtx, rtx); - rtx (*func_si_mem) (rtx, rtx); - rtx (*func_di) (rtx, rtx); - rtx reg, stack; - - gcc_assert (GET_MODE (src) == SImode); - - if (dmode == SFmode) { - if (unsigned_p) + if (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC) { - gcc_assert (TARGET_FCFIDUS && TARGET_LFIWZX); - func_si = gen_floatunssisf2_lfiwzx; - func_si_mem = gen_floatunssisf2_lfiwzx_mem; - func_di = gen_floatunsdisf2; + rtx reg = XEXP (addr, 0); + HOST_WIDE_INT size = GET_MODE_SIZE (GET_MODE (x)); + rtx size_rtx = GEN_INT ((GET_CODE (addr) == PRE_DEC) ? -size : size); + gcc_assert (REG_P (reg)); + emit_insn (gen_add3_insn (reg, reg, size_rtx)); + addr = reg; } - else + else if (GET_CODE (addr) == PRE_MODIFY) { - gcc_assert (TARGET_FCFIDS && TARGET_LFIWAX); - func_si = gen_floatsisf2_lfiwax; - func_si_mem = gen_floatsisf2_lfiwax_mem; - func_di = gen_floatdisf2; + rtx reg = XEXP (addr, 0); + rtx expr = XEXP (addr, 1); + gcc_assert (REG_P (reg)); + gcc_assert (GET_CODE (expr) == PLUS); + emit_insn (gen_add3_insn (reg, XEXP (expr, 0), XEXP (expr, 1))); + addr = reg; } - } - else if (dmode == DFmode) - { - if (unsigned_p) - { - gcc_assert (TARGET_FCFIDU && TARGET_LFIWZX); - func_si = gen_floatunssidf2_lfiwzx; - func_si_mem = gen_floatunssidf2_lfiwzx_mem; - func_di = gen_floatunsdidf2; - } - else - { - gcc_assert (TARGET_FCFID && TARGET_LFIWAX); - func_si = gen_floatsidf2_lfiwax; - func_si_mem = gen_floatsidf2_lfiwax_mem; - func_di = gen_floatdidf2; - } + x = replace_equiv_address (x, copy_addr_to_reg (addr)); } - else - gcc_unreachable (); - - if (MEM_P (src)) - { - src = rs6000_address_for_fpconvert (src); - emit_insn (func_si_mem (dest, src)); - } - else if (!TARGET_MFPGPR) - { - reg = gen_reg_rtx (DImode); - stack = rs6000_allocate_stack_temp (SImode, false, true); - emit_insn (func_si (dest, src, stack, reg)); - } - else - { - if (!REG_P (src)) - src = force_reg (SImode, src); - reg = convert_to_mode (DImode, src, unsigned_p); - emit_insn (func_di (dest, reg)); - } + return x; } #include "gt-rs6000.h" |