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,8 +42,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see ...@@ -42,8 +42,8 @@ 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)
......
...@@ -5780,25 +5780,31 @@ label: ...@@ -5780,25 +5780,31 @@ label:
;; up pcloads, so we need usable length information for that. ;; up pcloads, so we need usable length information for that.
(define_insn "movdf_i4" (define_insn "movdf_i4"
[(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d") [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
(match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r")) (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
(use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c")) (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
(clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))] (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
"(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))
{ {
/* If we have to modify the stack pointer, the value that we have case REG:
read with post-increment might be modified by an interrupt, /* This is complicated. If the register is an arithmetic register
so write it back. */ we can just fall through to the REG+DISP case below. Otherwise
if (REGNO (addr) == STACK_POINTER_REGNUM) we have to use a combination of POST_INC and REG addressing... */
adjust = gen_push_e (reg0); if (! arith_reg_operand (operands[1], SFmode))
else {
adjust = gen_addsi3 (addr, addr, GEN_INT (-4)); XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
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));
addr = XEXP (addr, 0);
insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2])); emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
add_reg_note (insn, REG_INC, addr);
insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2])); /* If we have modified the stack pointer, the value that we have
if (adjust) read with post-increment might be modified by an interrupt,
emit_insn (adjust); so write it back. */
else if (REGNO (addr) == STACK_POINTER_REGNUM)
add_reg_note (insn, REG_INC, addr); emit_insn (gen_push_e (reg0));
else
emit_insn (gen_addsi3 (XEXP (operands[1], 0), XEXP (operands[1], 0), GEN_INT (-4)));
break;
}
/* Fall through. */
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]));
add_reg_note (insn, REG_INC, XEXP (addr, 0));
break;
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))
{ {
adjust = gen_addsi3 (addr, addr, GEN_INT (4)); case REG:
emit_insn_before (adjust, insn); /* This is complicated. If the register is an arithmetic register
XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr); 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))
{
emit_insn (gen_addsi3 (addr, addr, GEN_INT (4)));
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);
insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
add_reg_note (insn, REG_INC, XEXP (addr, 0));
break;
}
/* Fall through. */
case PLUS:
/* Since REG+DISP addressing has already been decided upon by gcc
we can rely upon it having chosen an arithmetic register as the
register component of the address. Just emit the lower numbered
register first, to the lower address, then the higher numbered
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 ();
} }
addr = XEXP (addr, 0);
if (! adjust)
add_reg_note (insn, REG_INC, addr);
insn = emit_insn (gen_movsf_ie (operands[0],
gen_rtx_REG (SFmode,
regno + !! TARGET_LITTLE_ENDIAN),
operands[2]));
add_reg_note (insn, REG_INC, addr);
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
......
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