Commit 7a61cf6f by Nick Clifton Committed by Nick Clifton

lib1funcs.h (FMOVD_WORKS): Only define if __FMOVD_ENABLED__ is defined.

        * config.sh/lib1funcs.h (FMOVD_WORKS): Only define if
        __FMOVD_ENABLED__ is defined.
        * config/sh/sh.h
        (TARGET_FMOVD): Provide a default definition.
        (MASK_FMOVD): Likewise.
        (TARGET_CPU_CPP_BUILTINS): Define
        __FMOVD_ENABLED__ if TARGET_FMOVD is true.
        * config/sh/sh.md (movdf_i4): For alternative 0 use either one or
        two fmov instructions depending upon whether TARGET_FMOVD is
        enabled.
        (split for DF load from memory into register): Also handle
        MEMs which consist of REG+DISP addressing.
        (split for DF store from register to memory): Likewise.
        (movsf_ie): Always use single fp_mode.
        * config/sh/sh.c (sh_override_options): Do not automatically
        enable TARGET_MOVD for the SH2A when supporting doubles - leave
        that to the -mfmovd command line switch.
        (broken_move): Do not restrict fldi test to only the SH4 and SH4A.
        (fldi_ok): Always allow.
        * config/sh/sh.opt (mfmovd): Remove this switch.
        * doc/invoke.texi (-mfmovd): Remove documentation of this switch.

Co-Authored-By: DJ Delorie <dj@redhat.com>

From-SVN: r149283
parent 83f63251
2009-07-06 Nick Clifton <nickc@redhat.com>
DJ Delorie <dj@redhat.com>
* config.sh/lib1funcs.h (FMOVD_WORKS): Only define if
__FMOVD_ENABLED__ is defined.
* config/sh/sh.h
(TARGET_FMOVD): Provide a default definition.
(MASK_FMOVD): Likewise.
(TARGET_CPU_CPP_BUILTINS): Define
__FMOVD_ENABLED__ if TARGET_FMOVD is true.
* config/sh/sh.md (movdf_i4): For alternative 0 use either one or
two fmov instructions depending upon whether TARGET_FMOVD is
enabled.
(split for DF load from memory into register): Also handle
MEMs which consist of REG+DISP addressing.
(split for DF store from register to memory): Likewise.
(movsf_ie): Always use single fp_mode.
* config/sh/sh.c (sh_override_options): Do not automatically
enable TARGET_MOVD for the SH2A when supporting doubles - leave
that to the -mfmovd command line switch.
(broken_move): Do not restrict fldi test to only the SH4 and SH4A.
(fldi_ok): Always allow.
* config/sh/sh.opt (mfmovd): Remove this switch.
* doc/invoke.texi (-mfmovd): Remove documentation of this switch.
2009-07-06 J"orn Rennecke <joern.rennecke@arc.com> 2009-07-06 J"orn Rennecke <joern.rennecke@arc.com>
Kaz Kojima <kkojima@gcc.gnu.org> Kaz Kojima <kkojima@gcc.gnu.org>
...@@ -372,6 +397,33 @@ ...@@ -372,6 +397,33 @@
* config/i386/i386.c (memory_address_length): Check existence of base * config/i386/i386.c (memory_address_length): Check existence of base
register before using it. register before using it.
2009-06-30 Nick Clifton <nickc@redhat.com>
DJ Delorie <dj@redhat.com>
* config.sh/lib1funcs.h (FMOVD_WORKS): Only define if
__FMOVD_ENABLED__ is defined.
* config/sh/sh.h
(TARGET_FMOVD): Provide a default definition.
(MASK_FMOVD): Likewise.
(TARGET_CPU_CPP_BUILTINS): Define
__FMOVD_ENABLED__ if TARGET_FMOVD is true.
* config/sh/sh.md (movdf_i4): For alternative 0 use either one or
two fmov instructions depending upon whether TARGET_FMOVD is
enabled.
(split for DF load from memory into register): Also handle
MEMs which consist of REG+DISP addressing.
(split for DF store from register to memory): Likewise.
* config/sh/sh.opt (mfmovd): Remove this switch.
* doc/invoke.texi (-mfmovd): Remove documentation of this switch.
* config/sh/sh.c (sh_override_options): Do not automatically
enable TARGET_MOVD for the SH2A when supporting doubles - leave
that to the -mfmovd command line switch.
* config/sh/sh.c (broken_move): Do not restrict fldi test to only
the SH4 and SH4A.
(fldi_ok): Always allow.
* config/sh/sh.md (movsf_ie): Always use single fp_mode.
2009-06-29 DJ Delorie <dj@redhat.com> 2009-06-29 DJ Delorie <dj@redhat.com>
* doc/install.texi (mep-x-elf): Correct chip's full name. * doc/install.texi (mep-x-elf): Correct chip's full name.
......
...@@ -42,7 +42,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see ...@@ -42,7 +42,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define ALIAS(X,Y) .global GLOBAL(X); .set GLOBAL(X),GLOBAL(Y) #define ALIAS(X,Y) .global GLOBAL(X); .set GLOBAL(X),GLOBAL(Y)
#ifdef __SH2A__ #if defined __SH2A__ && defined __FMOVD_ENABLED__
#undef FMOVD_WORKS #undef FMOVD_WORKS
#define FMOVD_WORKS #define FMOVD_WORKS
#endif #endif
......
...@@ -694,11 +694,7 @@ sh_override_options (void) ...@@ -694,11 +694,7 @@ sh_override_options (void)
if (TARGET_SH2E) if (TARGET_SH2E)
sh_cpu = PROCESSOR_SH2E; sh_cpu = PROCESSOR_SH2E;
if (TARGET_SH2A) if (TARGET_SH2A)
{
sh_cpu = PROCESSOR_SH2A; sh_cpu = PROCESSOR_SH2A;
if (TARGET_SH2A_DOUBLE)
target_flags |= MASK_FMOVD;
}
if (TARGET_SH3) if (TARGET_SH3)
sh_cpu = PROCESSOR_SH3; sh_cpu = PROCESSOR_SH3;
if (TARGET_SH3E) if (TARGET_SH3E)
...@@ -4208,14 +4204,13 @@ broken_move (rtx insn) ...@@ -4208,14 +4204,13 @@ broken_move (rtx insn)
&& GET_CODE (SET_SRC (pat)) == CONST_DOUBLE && GET_CODE (SET_SRC (pat)) == CONST_DOUBLE
&& (fp_zero_operand (SET_SRC (pat)) && (fp_zero_operand (SET_SRC (pat))
|| fp_one_operand (SET_SRC (pat))) || fp_one_operand (SET_SRC (pat)))
/* ??? If this is a -m4 or -m4-single compilation, in general /* In general we don't know the current setting of fpscr, so disable fldi.
we don't know the current setting of fpscr, so disable fldi.
There is an exception if this was a register-register move There is an exception if this was a register-register move
before reload - and hence it was ascertained that we have before reload - and hence it was ascertained that we have
single precision setting - and in a post-reload optimization single precision setting - and in a post-reload optimization
we changed this to do a constant load. In that case we changed this to do a constant load. In that case
we don't have an r0 clobber, hence we must use fldi. */ we don't have an r0 clobber, hence we must use fldi. */
&& (! TARGET_SH4 || TARGET_FMOVD && (TARGET_FMOVD
|| (GET_CODE (XEXP (XVECEXP (PATTERN (insn), 0, 2), 0)) || (GET_CODE (XEXP (XVECEXP (PATTERN (insn), 0, 2), 0))
== SCRATCH)) == SCRATCH))
&& REG_P (SET_DEST (pat)) && REG_P (SET_DEST (pat))
...@@ -8876,7 +8871,7 @@ fp_one_operand (rtx op) ...@@ -8876,7 +8871,7 @@ fp_one_operand (rtx op)
return REAL_VALUES_EQUAL (r, dconst1); return REAL_VALUES_EQUAL (r, dconst1);
} }
/* For -m4 and -m4-single-only, mode switching is used. If we are /* In general mode switching is used. If we are
compiling without -mfmovd, movsf_ie isn't taken into account for compiling without -mfmovd, movsf_ie isn't taken into account for
mode switching. We could check in machine_dependent_reorg for mode switching. We could check in machine_dependent_reorg for
cases where we know we are in single precision mode, but there is cases where we know we are in single precision mode, but there is
...@@ -8886,7 +8881,7 @@ fp_one_operand (rtx op) ...@@ -8886,7 +8881,7 @@ fp_one_operand (rtx op)
int int
fldi_ok (void) fldi_ok (void)
{ {
return ! TARGET_SH4 || TARGET_FMOVD || reload_completed; return 1;
} }
int int
......
...@@ -28,6 +28,11 @@ along with GCC; see the file COPYING3. If not see ...@@ -28,6 +28,11 @@ along with GCC; see the file COPYING3. If not see
#define TARGET_VERSION \ #define TARGET_VERSION \
fputs (" (Hitachi SH)", stderr); fputs (" (Hitachi SH)", stderr);
#ifndef TARGET_FMOVD
#define TARGET_FMOVD 0
#define MASK_FMOVD 0
#endif
/* Unfortunately, insn-attrtab.c doesn't include insn-codes.h. We can't /* Unfortunately, insn-attrtab.c doesn't include insn-codes.h. We can't
include it here, because bconfig.h is also included by gencodes.c . */ include it here, because bconfig.h is also included by gencodes.c . */
/* ??? No longer true. */ /* ??? No longer true. */
...@@ -91,6 +96,8 @@ do { \ ...@@ -91,6 +96,8 @@ do { \
builtin_define ("__SH_FPU_DOUBLE__"); \ builtin_define ("__SH_FPU_DOUBLE__"); \
if (TARGET_HITACHI) \ if (TARGET_HITACHI) \
builtin_define ("__HITACHI__"); \ builtin_define ("__HITACHI__"); \
if (TARGET_FMOVD) \
builtin_define ("__FMOVD_ENABLED__"); \
builtin_define (TARGET_LITTLE_ENDIAN \ builtin_define (TARGET_LITTLE_ENDIAN \
? "__LITTLE_ENDIAN__" : "__BIG_ENDIAN__"); \ ? "__LITTLE_ENDIAN__" : "__BIG_ENDIAN__"); \
} while (0) } while (0)
......
...@@ -5786,19 +5786,25 @@ label: ...@@ -5786,19 +5786,25 @@ label:
"(TARGET_SH4 || TARGET_SH2A_DOUBLE) "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
&& (arith_reg_operand (operands[0], DFmode) && (arith_reg_operand (operands[0], DFmode)
|| arith_reg_operand (operands[1], DFmode))" || arith_reg_operand (operands[1], DFmode))"
"@ {
fmov %1,%0 switch (which_alternative)
# {
# case 0:
fmov.d %1,%0 if (TARGET_FMOVD)
fmov.d %1,%0 return "fmov %1,%0";
# else if (REGNO (operands[0]) != REGNO (operands[1]) + 1)
# return "fmov %R1,%R0\n\tfmov %S1,%S0";
# else
# return "fmov %S1,%S0\n\tfmov %R1,%R0";
#" case 3:
case 4:
return "fmov.d %1,%0";
default:
return "#";
}
}
[(set_attr_alternative "length" [(set_attr_alternative "length"
[(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4)) [(if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 8))
(const_int 4) (const_int 4)
(if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6)) (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
(if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6)) (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
...@@ -6032,37 +6038,63 @@ label: ...@@ -6032,37 +6038,63 @@ label:
"(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
&& FP_OR_XD_REGISTER_P (true_regnum (operands[0]))" && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
[(const_int 0)] [(const_int 0)]
"
{ {
int regno = true_regnum (operands[0]); int regno = true_regnum (operands[0]);
rtx addr, insn, adjust = NULL_RTX; rtx addr, insn;
rtx mem2 = change_address (operands[1], SFmode, NULL_RTX); rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN); rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN); rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
operands[1] = copy_rtx (mem2); operands[1] = copy_rtx (mem2);
addr = XEXP (mem2, 0); addr = XEXP (mem2, 0);
if (GET_CODE (addr) != POST_INC)
switch (GET_CODE (addr))
{
case REG:
/* This is complicated. If the register is an arithmetic register
we can just fall through to the REG+DISP case below. Otherwise
we have to use a combination of POST_INC and REG addressing... */
if (! arith_reg_operand (operands[1], SFmode))
{ {
/* If we have to modify the stack pointer, the value that we have XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
add_reg_note (insn, REG_INC, XEXP (addr, 0));
emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
/* If we have modified the stack pointer, the value that we have
read with post-increment might be modified by an interrupt, read with post-increment might be modified by an interrupt,
so write it back. */ so write it back. */
if (REGNO (addr) == STACK_POINTER_REGNUM) if (REGNO (addr) == STACK_POINTER_REGNUM)
adjust = gen_push_e (reg0); emit_insn (gen_push_e (reg0));
else else
adjust = gen_addsi3 (addr, addr, GEN_INT (-4)); emit_insn (gen_addsi3 (XEXP (operands[1], 0), XEXP (operands[1], 0), GEN_INT (-4)));
XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr); break;
} }
addr = XEXP (addr, 0); /* Fall through. */
insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
add_reg_note (insn, REG_INC, addr); case PLUS:
emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
operands[1] = copy_rtx (operands[1]);
XEXP (operands[1], 0) = plus_constant (addr, 4);
emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
break;
case POST_INC:
insn = emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
add_reg_note (insn, REG_INC, XEXP (addr, 0));
insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2])); insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
if (adjust) add_reg_note (insn, REG_INC, XEXP (addr, 0));
emit_insn (adjust); break;
else
add_reg_note (insn, REG_INC, addr); default:
debug_rtx (addr);
gcc_unreachable ();
}
DONE; DONE;
}") })
(define_split (define_split
[(set (match_operand:DF 0 "memory_operand" "") [(set (match_operand:DF 0 "memory_operand" "")
...@@ -6072,35 +6104,70 @@ label: ...@@ -6072,35 +6104,70 @@ label:
"(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
&& FP_OR_XD_REGISTER_P (true_regnum (operands[1]))" && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
[(const_int 0)] [(const_int 0)]
"
{ {
int regno = true_regnum (operands[1]); int regno = true_regnum (operands[1]);
rtx insn, addr, adjust = NULL_RTX; rtx insn, addr;
rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
operands[0] = copy_rtx (operands[0]); operands[0] = copy_rtx (operands[0]);
PUT_MODE (operands[0], SFmode); PUT_MODE (operands[0], SFmode);
insn = emit_insn (gen_movsf_ie (operands[0],
gen_rtx_REG (SFmode,
regno + ! TARGET_LITTLE_ENDIAN),
operands[2]));
operands[0] = copy_rtx (operands[0]);
addr = XEXP (operands[0], 0); addr = XEXP (operands[0], 0);
if (GET_CODE (addr) != PRE_DEC)
switch (GET_CODE (addr))
{
case REG:
/* This is complicated. If the register is an arithmetic register
we can just fall through to the REG+DISP case below. Otherwise
we have to use a combination of REG and PRE_DEC addressing... */
if (! arith_reg_operand (operands[0], SFmode))
{ {
adjust = gen_addsi3 (addr, addr, GEN_INT (4)); emit_insn (gen_addsi3 (addr, addr, GEN_INT (4)));
emit_insn_before (adjust, insn); emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
operands[0] = copy_rtx (operands[0]);
XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr); XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
add_reg_note (insn, REG_INC, XEXP (addr, 0));
break;
} }
addr = XEXP (addr, 0); /* Fall through. */
if (! adjust)
add_reg_note (insn, REG_INC, addr); case PLUS:
insn = emit_insn (gen_movsf_ie (operands[0], /* Since REG+DISP addressing has already been decided upon by gcc
gen_rtx_REG (SFmode, we can rely upon it having chosen an arithmetic register as the
regno + !! TARGET_LITTLE_ENDIAN), register component of the address. Just emit the lower numbered
operands[2])); register first, to the lower address, then the higher numbered
add_reg_note (insn, REG_INC, addr); register to the higher address. */
emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
operands[0] = copy_rtx (operands[0]);
XEXP (operands[0], 0) = plus_constant (addr, 4);
emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
break;
case PRE_DEC:
/* This is easy. Output the word to go to the higher address
first (ie the word in the higher numbered register) then the
word to go to the lower address. */
insn = emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
add_reg_note (insn, REG_INC, XEXP (addr, 0));
insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
add_reg_note (insn, REG_INC, XEXP (addr, 0));
break;
default:
/* FAIL; */
debug_rtx (addr);
gcc_unreachable ();
}
DONE; DONE;
}") })
;; If the output is a register and the input is memory or a register, we have ;; If the output is a register and the input is memory or a register, we have
;; to be careful and see which word needs to be loaded first. ;; to be careful and see which word needs to be loaded first.
...@@ -6562,7 +6629,7 @@ label: ...@@ -6562,7 +6629,7 @@ label:
(const_int 0)]) (const_int 0)])
(set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes") (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
(const_string "single") (const_string "single")
(const_string "none")))]) (const_string "single")))])
(define_split (define_split
[(set (match_operand:SF 0 "register_operand" "") [(set (match_operand:SF 0 "register_operand" "")
......
...@@ -248,9 +248,6 @@ mfixed-range= ...@@ -248,9 +248,6 @@ mfixed-range=
Target RejectNegative Joined Var(sh_fixed_range_str) Target RejectNegative Joined Var(sh_fixed_range_str)
Specify range of registers to make fixed Specify range of registers to make fixed
mfmovd
Target RejectNegative Mask(FMOVD) Undocumented
mfused-madd mfused-madd
Target Var(TARGET_FMAC) Target Var(TARGET_FMAC)
Enable the use of the fused floating point multiply-accumulate operation Enable the use of the fused floating point multiply-accumulate operation
......
...@@ -795,7 +795,7 @@ See RS/6000 and PowerPC Options. ...@@ -795,7 +795,7 @@ See RS/6000 and PowerPC Options.
-m5-32media -m5-32media-nofpu @gol -m5-32media -m5-32media-nofpu @gol
-m5-compact -m5-compact-nofpu @gol -m5-compact -m5-compact-nofpu @gol
-mb -ml -mdalign -mrelax @gol -mb -ml -mdalign -mrelax @gol
-mbigtable -mfmovd -mhitachi -mrenesas -mno-renesas -mnomacsave @gol -mbigtable -mhitachi -mrenesas -mno-renesas -mnomacsave @gol
-mieee -mbitops -misize -minline-ic_invalidate -mpadstruct -mspace @gol -mieee -mbitops -misize -minline-ic_invalidate -mpadstruct -mspace @gol
-mprefergot -musermode -multcost=@var{number} -mdiv=@var{strategy} @gol -mprefergot -musermode -multcost=@var{number} -mdiv=@var{strategy} @gol
-mdivsi3_libfunc=@var{name} -mfixed-range=@var{register-range} @gol -mdivsi3_libfunc=@var{name} -mfixed-range=@var{register-range} @gol
...@@ -6376,7 +6376,6 @@ improve cache locality. ...@@ -6376,7 +6376,6 @@ improve cache locality.
Both optimizations need the @option{-fwhole-program} flag. Both optimizations need the @option{-fwhole-program} flag.
Transposing is enabled only if profiling information is available. Transposing is enabled only if profiling information is available.
@item -ftree-sink @item -ftree-sink
@opindex ftree-sink @opindex ftree-sink
Perform forward store motion on trees. This flag is Perform forward store motion on trees. This flag is
...@@ -12925,7 +12924,6 @@ register. The default for this option is 4, but note that there's a ...@@ -12925,7 +12924,6 @@ register. The default for this option is 4, but note that there's a
@end table @end table
@node MIPS Options @node MIPS Options
@subsection MIPS Options @subsection MIPS Options
@cindex MIPS options @cindex MIPS options
...@@ -15221,10 +15219,6 @@ Use 32-bit offsets in @code{switch} tables. The default is to use ...@@ -15221,10 +15219,6 @@ Use 32-bit offsets in @code{switch} tables. The default is to use
@opindex mbitops @opindex mbitops
Enable the use of bit manipulation instructions on SH2A. Enable the use of bit manipulation instructions on SH2A.
@item -mfmovd
@opindex mfmovd
Enable the use of the instruction @code{fmovd}.
@item -mhitachi @item -mhitachi
@opindex mhitachi @opindex mhitachi
Comply with the calling conventions defined by Renesas. Comply with the calling conventions defined by Renesas.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment