summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog67
-rw-r--r--gcc/config.gcc13
-rw-r--r--gcc/config/sh/crt1.asm14
-rw-r--r--gcc/config/sh/elf.h4
-rw-r--r--gcc/config/sh/lib1funcs.asm13
-rw-r--r--gcc/config/sh/sh.c35
-rw-r--r--gcc/config/sh/sh.h119
-rw-r--r--gcc/config/sh/sh.md221
-rw-r--r--gcc/config/sh/t-mlib-sh2a1
-rw-r--r--gcc/config/sh/t-mlib-sh2a-nofpu1
-rw-r--r--gcc/config/sh/t-mlib-sh2a-single1
-rw-r--r--gcc/config/sh/t-mlib-sh2a-single-only1
-rw-r--r--gcc/config/sh/t-sh18
13 files changed, 394 insertions, 114 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f051f395a27..12ae194fe3a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,70 @@
+2004-07-29 Alexandre Oliva <aoliva@redhat.com>
+
+ Introduce sh2a support.
+ 2004-07-29 Alexandre Oliva <aoliva@redhat.com>
+ * config.gcc: Build multilibs for sh2a and sh2a-single by
+ default.
+ * config/sh/sh.h (SUPPORT_SH2A, SUPPORT_SH2A_SINGLE): Define by
+ default. Split their tests out of the corresponding SH4
+ multilibs.
+ * config/sh/t-sh (MULTILIB_MATCHES): Don't ever use SH4 or SH4a
+ multilibs for SH2a.
+ 2004-07-28 Alexandre Oliva <aoliva@redhat.com>
+ * config.gcc: Handle sh2a multilibs and cpu selection.
+ * config/sh/sh.h: Likewise. Handle sh2a command line flags.
+ * config/sh/t-mlib-sh2a: New.
+ * config/sh/t-mlib-sh2a-nofpu: New.
+ * config/sh/t-mlib-sh2a-single: New.
+ * config/sh/t-mlib-sh2a-single-only: New.
+ 2004-07-09 Nick Clifton <nickc@redhat.com>
+ Issue 43400
+ * config/sh/sh.h (DRIVER_SELF_SPECS): Issue an error message if
+ -ml and -m2a are used together.
+ 2004-03-23 DJ Delorie <dj@redhat.com>
+ * config/sh/sh.c (sh_builtin_saveregs): Use the double code only
+ when we have a double-sized FPU.
+ 2004-02-24 Corinna Vinschen <vinschen@redhat.com>
+ * config/sh/lib1funcs.asm (set_fpscr): Don't build if __SH2A_NOFPU__
+ is set.
+ * config/sh/elf.h (SUBTARGET_ASM_ISA_SPEC): Add cases for -msh2a-nofpu,
+ -msh2a-single and -msh2a-single-only
+ 2004-02-24 Corinna Vinschen <vinschen@redhat.com>
+ * config/sh/crt1.asm: Don't generate FPU instructions if __SH2A_NOFPU__
+ is set.
+ 2004-02-20 DJ Delorie <dj@delorie.com>
+ * config/sh/sh.md (movsf_i, movsf_ie, movsf, ble, bge): Disable for sh2a-nofpu.
+ 2004-02-20 Fred Fish <fnf@redhat.com>,
+ Corinna Vinschen <vinschen@redhat.com>
+ * config/sh/t-sh (MULTILIB_OPTIONS): Add 2a-nofpu.
+ (MULTILIB_EXCEPTIONS): Don't build littel-endian on sh2a.
+ 2004-02-18 DJ Delorie <dj@redhat.com>
+ * config/sh/sh.c (broken_move): Add support for movi20.
+ * config/sh/sh.h: Likewise.
+ (SHIFT_COUNT_TRUNCATED): Set for sh2a.
+ * config/sh/sh.md (udivsi3_sh2a): New.
+ (udivsi3): Call it.
+ (divsi3_sh2a): New.
+ (divsi3): Call it.
+ (mul_r): New.
+ (ashlsi3_sh2a): New.
+ (ashrsi3_sh2a): New.
+ (lshrsi3_sh2a): New.
+ (movsi_i): Disable for sh2a.
+ (movsi_ie): Add movi20.
+ (movsf_i, movsf_ie, movsf, ble, untyped_call): Explicitly enable
+ sh2a, for -m2a-nofpu mode.
+ 2004-02-13 DJ Delorie <dj@redhat.com>
+ * config/sh/lib1funcs.asm: Handle double vs single better.
+ * config/sh/sh.h: Likewise.
+ 2004-02-09 DJ Delorie <dj@redhat.com>
+ * config/sh/crt1.asm: Add support for sh2a.
+ * config/sh/elf.h: Likewise.
+ * config/sh/lib1funcs.asm: Likewise.
+ * config/sh/sh.c: Likewise.
+ * config/sh/sh.md: Likewise.
+ * config/sh/sh.h: Likewise.
+ * config/sh/t-sh: Likewise.
+
2004-07-28 Alexandre Oliva <aoliva@redhat.com>
* config/frv/frv.md (movqi_internal, movhi_internal,
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 1360b072a48..dadc454cd27 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -1757,6 +1757,10 @@ sh-*-symbianelf* | sh[12346l]*-*-symbianelf* | \
sh4* | sh-superh-*) sh_cpu_target=sh4 ;;
sh3e*) sh_cpu_target=sh3e ;;
sh*-*-netbsd* | sh3*) sh_cpu_target=sh3 ;;
+ sh2a_single_only*) sh_cpu_target=sh2a-single-only ;;
+ sh2a_single*) sh_cpu_target=sh2a-single ;;
+ sh2a_nofpu*) sh_cpu_target=sh2a-nofpu ;;
+ sh2a*) sh_cpu_target=sh2a ;;
sh2e*) sh_cpu_target=sh2e ;;
sh2*) sh_cpu_target=sh2 ;;
*) sh_cpu_target=sh1 ;;
@@ -1765,6 +1769,7 @@ sh-*-symbianelf* | sh[12346l]*-*-symbianelf* | \
case $sh_cpu_default in
sh5-64media-nofpu | sh5-64media | \
sh5-32media-nofpu | sh5-32media | sh5-compact-nofpu | sh5-compact | \
+ sh2a-single-only | sh2a-single | sh2a-nofpu | sh2a | \
sh4a-single-only | sh4a-single | sh4a-nofpu | sh4a | sh4al | \
sh4-single-only | sh4-single | sh4-nofpu | sh4 | \
sh3e | sh3 | sh2e | sh2 | sh1) ;;
@@ -1779,7 +1784,7 @@ sh-*-symbianelf* | sh[12346l]*-*-symbianelf* | \
sh-superh-*) sh_multilibs=m4,m4-single,m4-single-only,m4-nofpu ;;
sh*-*-linux*) sh_multilibs=m1,m3e,m4 ;;
sh*-*-netbsd*) sh_multilibs=m3,m3e,m4 ;;
- *) sh_multilibs=m1,m2,m2e,m4,m4-single,m4-single-only ;;
+ *) sh_multilibs=m1,m2,m2e,m4,m4-single,m4-single-only,m2a,m2a-single ;;
esac
fi
target_cpu_default=SELECT_`echo ${sh_cpu_default}|tr a-z- A-Z_`
@@ -1790,6 +1795,7 @@ sh-*-symbianelf* | sh[12346l]*-*-symbianelf* | \
sh1 | sh2 | sh2e | sh3 | sh3e | \
sh4 | sh4-single | sh4-single-only | sh4-nofpu | \
sh4a | sh4a-single | sh4a-single-only | sh4a-nofpu | sh4al | \
+ sh2a | sh2a-single | sh2a-single-only | sh2a-nofpu | \
sh5-64media | sh5-64media-nofpu | \
sh5-32media | sh5-32media-nofpu | \
sh5-compact | sh5-compact-nofpu)
@@ -1803,7 +1809,7 @@ sh-*-symbianelf* | sh[12346l]*-*-symbianelf* | \
esac
done
if test x${enable_incomplete_targets} == xyes ; then
- tm_defines="$tm_defines SUPPORT_SH1 SUPPORT_SH2E SUPPORT_SH4 SUPPORT_SH4_SINGLE SUPPORT_SH5_32MEDIA SUPPORT_SH5_32MEDIA_NOFPU SUPPORT_SH5_64MEDIA SUPPORT_SH5_64MEDIA_NOFPU"
+ tm_defines="$tm_defines SUPPORT_SH1 SUPPORT_SH2E SUPPORT_SH4 SUPPORT_SH4_SINGLE SUPPORT_SH2A SUPPORT_SH2A_SINGLE SUPPORT_SH5_32MEDIA SUPPORT_SH5_32MEDIA_NOFPU SUPPORT_SH5_64MEDIA SUPPORT_SH5_64MEDIA_NOFPU"
fi
use_fixproto=yes
;;
@@ -2483,12 +2489,15 @@ fi
"" | m1 | m2 | m2e | m3 | m3e | m4 | m4-single | m4-single-only | m4-nofpu )
# OK
;;
+ m2a | m2a-single | m2a-single-only | m2a-nofpu)
+ ;;
m4a | m4a-single | m4a-single-only | m4a-nofpu | m4al)
;;
*)
echo "Unknown CPU used in --with-cpu=$with_cpu, known values:" 1>&2
echo "m1 m2 m2e m3 m3e m4 m4-single m4-single-only m4-nofpu" 1>&2
echo "m4a m4a-single m4a-single-only m4a-nofpu m4al" 1>&2
+ echo "m2a m2a-single m2a-single-only m2a-nofpu" 1>&2
exit 1
;;
esac
diff --git a/gcc/config/sh/crt1.asm b/gcc/config/sh/crt1.asm
index af7d8ae3b95..f2c4e0d7beb 100644
--- a/gcc/config/sh/crt1.asm
+++ b/gcc/config/sh/crt1.asm
@@ -72,7 +72,7 @@ start:
LOAD_ADDR (___data, r26)
LOAD_ADDR (___rodata, r27)
-#if ! __SH4_NOFPU__
+#if ! __SH4_NOFPU__ && ! __SH2A_NOFPU__
#if __SH5__ == 32
pt/l ___set_fpscr, tr0
movi 0, r4
@@ -116,12 +116,14 @@ start_l:
cmp/ge r0,r1
bt start_l
-#if defined (__SH2E__) || defined (__SH3E__) || defined(__SH4_SINGLE__) || defined(__SH4__) || defined(__SH4_SINGLE_ONLY__)
+#if ! __SH2A_NOFPU__
+#if defined (__SH2E__) || defined (__SH2A__) || defined (__SH3E__) || defined(__SH4_SINGLE__) || defined(__SH4__) || defined(__SH4_SINGLE_ONLY__)
mov.l set_fpscr_k, r1
jsr @r1
mov #0,r4
lds r3,fpscr
-#endif /* defined (__SH2E__) || defined (__SH3E__) || defined(__SH4_SINGLE__) || defined(__SH4__) || defined(__SH4_SINGLE_ONLY__) */
+#endif /* defined (__SH2E__) || defined (__SH2A__) || defined (__SH3E__) || defined(__SH4_SINGLE__) || defined(__SH4__) || defined(__SH4_SINGLE_ONLY__) */
+#endif /* ! __SH2A_NOFPU__ */
! arrange for exit to call fini
mov.l atexit_k,r0
@@ -146,10 +148,12 @@ start_l:
nop
.align 2
-#if defined (__SH2E__) || defined (__SH3E__) || defined(__SH4_SINGLE__) || defined(__SH4__) || defined(__SH4_SINGLE_ONLY__)
+#if ! __SH2A_NOFPU__
+#if defined (__SH2E__) || defined (__SH2A__) || defined (__SH3E__) || defined(__SH4_SINGLE__) || defined(__SH4__) || defined(__SH4_SINGLE_ONLY__)
set_fpscr_k:
.long ___set_fpscr
-#endif /* defined (__SH2E__) || defined (__SH3E__) || defined(__SH4_SINGLE__) || defined(__SH4__) || defined(__SH4_SINGLE_ONLY__) */
+#endif /* defined (__SH2E__) || defined (__SH2A__) || defined (__SH3E__) || defined(__SH4_SINGLE__) || defined(__SH4__) || defined(__SH4_SINGLE_ONLY__) */
+#endif /* ! __SH2A_NOFPU__ */
stack_k:
.long _stack
diff --git a/gcc/config/sh/elf.h b/gcc/config/sh/elf.h
index 04c0c987fc3..d632bf7de20 100644
--- a/gcc/config/sh/elf.h
+++ b/gcc/config/sh/elf.h
@@ -58,6 +58,10 @@ Boston, MA 02111-1307, USA. */
#define ASM_SPEC SH_ASM_SPEC
#undef SUBTARGET_ASM_ISA_SPEC
#define SUBTARGET_ASM_ISA_SPEC "\
+%{m2a:--isa=sh2a} \
+%{m2a-single:--isa=sh2a} \
+%{m2a-single-only:--isa=sh2a} \
+%{m2a-nofpu:--isa=sh2a-nofpu} \
%{m5-compact*:--isa=SHcompact} %{m5-32media*:--isa=SHmedia --abi=32} \
%{m5-64media*:--isa=SHmedia --abi=64}" ASM_ISA_DEFAULT_SPEC
diff --git a/gcc/config/sh/lib1funcs.asm b/gcc/config/sh/lib1funcs.asm
index 239438fd06b..1dc354994b3 100644
--- a/gcc/config/sh/lib1funcs.asm
+++ b/gcc/config/sh/lib1funcs.asm
@@ -56,6 +56,11 @@ Boston, MA 02111-1307, USA. */
#define FMOVD_WORKS
#endif
+#ifdef __SH2A__
+#undef FMOVD_WORKS
+#define FMOVD_WORKS
+#endif
+
#if ! __SH5__
#ifdef L_ashiftrt
.global GLOBAL(ashiftrt_r4_0)
@@ -1936,7 +1941,8 @@ GLOBAL(moddi3):
#endif /* L_moddi3 */
#ifdef L_set_fpscr
-#if defined (__SH2E__) || defined (__SH3E__) || defined(__SH4_SINGLE__) || defined(__SH4__) || defined(__SH4_SINGLE_ONLY__) || __SH5__ == 32
+#if !defined (__SH2A_NOFPU__)
+#if defined (__SH2E__) || defined (__SH2A__) || defined (__SH3E__) || defined(__SH4_SINGLE__) || defined(__SH4__) || defined(__SH4_SINGLE_ONLY__) || __SH5__ == 32
#ifdef __SH5__
.mode SHcompact
#endif
@@ -1960,7 +1966,7 @@ GLOBAL(set_fpscr):
#ifndef FMOVD_WORKS
xor #16,r0
#endif
-#if defined(__SH4__)
+#if defined(__SH4__) || defined (__SH2A_DOUBLE__)
swap.w r0,r3
mov.l r3,@(4,r1)
#else /* defined (__SH2E__) || defined(__SH3E__) || defined(__SH4_SINGLE*__) */
@@ -1972,7 +1978,7 @@ GLOBAL(set_fpscr):
#else
xor #24,r0
#endif
-#if defined(__SH4__)
+#if defined(__SH4__) || defined (__SH2A_DOUBLE__)
swap.w r0,r2
rts
mov.l r2,@r1
@@ -2001,6 +2007,7 @@ LOCAL(set_fpscr_L1):
#endif /* ELF */
#endif /* NO_FPSCR_VALUES */
#endif /* SH2E / SH3E / SH4 */
+#endif /* __SH2A_NOFPU__ */
#endif /* L_set_fpscr */
#ifdef L_ic_invalidate
#if __SH5__ == 32
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 010e5dcadc3..b2c01302778 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -1111,7 +1111,7 @@ prepare_scc_operands (enum rtx_code code)
|| (TARGET_SH2E && GET_MODE_CLASS (mode) == MODE_FLOAT))
sh_compare_op1 = force_reg (mode, sh_compare_op1);
- if (TARGET_SH4 && GET_MODE_CLASS (mode) == MODE_FLOAT)
+ if ((TARGET_SH4 || TARGET_SH2A) && GET_MODE_CLASS (mode) == MODE_FLOAT)
(mode == SFmode ? emit_sf_insn : emit_df_insn)
(gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
gen_rtx_SET (VOIDmode, t_reg,
@@ -1156,7 +1156,7 @@ from_compare (rtx *operands, int code)
gen_rtx_REG (SImode, T_REG),
gen_rtx_fmt_ee (code, SImode,
sh_compare_op0, sh_compare_op1));
- if (TARGET_SH4 && GET_MODE_CLASS (mode) == MODE_FLOAT)
+ if ((TARGET_SH4 || TARGET_SH2A) && GET_MODE_CLASS (mode) == MODE_FLOAT)
{
insn = gen_rtx_PARALLEL (VOIDmode,
gen_rtvec (2, insn,
@@ -3066,6 +3066,10 @@ broken_move (rtx insn)
== SCRATCH))
&& GET_CODE (SET_DEST (pat)) == REG
&& FP_REGISTER_P (REGNO (SET_DEST (pat))))
+ && ! (TARGET_SH2A
+ && GET_MODE (SET_DEST (pat)) == SImode
+ && GET_CODE (SET_SRC (pat)) == CONST_INT
+ && CONST_OK_FOR_I20 (INTVAL (SET_SRC (pat))))
&& (GET_CODE (SET_SRC (pat)) != CONST_INT
|| ! CONST_OK_FOR_I08 (INTVAL (SET_SRC (pat)))))
return 1;
@@ -3810,6 +3814,10 @@ fixup_addr_diff_vecs (rtx first)
if (GET_CODE (x) == LABEL_REF && XEXP (x, 0) == vec_lab)
break;
}
+ /* FIXME: This is a bug in the optimizer, but it seems harmless
+ to just avoid panicing. */
+ if (!prev)
+ continue;
/* Emit the reference label of the braf where it belongs, right after
the casesi_jump_2 (i.e. braf). */
@@ -4786,8 +4794,12 @@ output_stack_adjust (int size, rtx reg, int epilogue_p,
{
HOST_WIDE_INT align = STACK_BOUNDARY / BITS_PER_UNIT;
+/* This test is bogus, as output_stack_adjust is used to re-align the
+ stack. */
+#if 0
if (size % align)
abort ();
+#endif
if (CONST_OK_FOR_ADD (size))
emit_fn (GEN_ADD3 (reg, reg, GEN_INT (size)));
@@ -4948,7 +4960,7 @@ push (int rn)
x = gen_push_fpul ();
else if (rn == FPSCR_REG)
x = gen_push_fpscr ();
- else if (TARGET_SH4 && TARGET_FMOVD && ! TARGET_FPU_SINGLE
+ else if ((TARGET_SH4 || TARGET_SH2A_DOUBLE) && TARGET_FMOVD && ! TARGET_FPU_SINGLE
&& FP_OR_XD_REGISTER_P (rn))
{
if (FP_REGISTER_P (rn) && (rn - FIRST_FP_REG) & 1)
@@ -4977,7 +4989,7 @@ pop (int rn)
x = gen_pop_fpul ();
else if (rn == FPSCR_REG)
x = gen_pop_fpscr ();
- else if (TARGET_SH4 && TARGET_FMOVD && ! TARGET_FPU_SINGLE
+ else if ((TARGET_SH4 || TARGET_SH2A_DOUBLE) && TARGET_FMOVD && ! TARGET_FPU_SINGLE
&& FP_OR_XD_REGISTER_P (rn))
{
if (FP_REGISTER_P (rn) && (rn - FIRST_FP_REG) & 1)
@@ -5095,11 +5107,11 @@ calc_live_regs (HARD_REG_SET *live_regs_mask)
interrupt_handler = sh_cfun_interrupt_handler_p ();
CLEAR_HARD_REG_SET (*live_regs_mask);
- if (TARGET_SH4 && TARGET_FMOVD && interrupt_handler
+ if ((TARGET_SH4 || TARGET_SH2A_DOUBLE) && TARGET_FMOVD && interrupt_handler
&& regs_ever_live[FPSCR_REG])
target_flags &= ~FPU_SINGLE_BIT;
/* If we can save a lot of saves by switching to double mode, do that. */
- else if (TARGET_SH4 && TARGET_FMOVD && TARGET_FPU_SINGLE)
+ else if ((TARGET_SH4 || TARGET_SH2A_DOUBLE) && TARGET_FMOVD && TARGET_FPU_SINGLE)
for (count = 0, reg = FIRST_FP_REG; reg <= LAST_FP_REG; reg += 2)
if (regs_ever_live[reg] && regs_ever_live[reg+1]
&& (! call_used_regs[reg] || (interrupt_handler && ! pragma_trapa))
@@ -5172,7 +5184,7 @@ calc_live_regs (HARD_REG_SET *live_regs_mask)
SET_HARD_REG_BIT (*live_regs_mask, reg);
count += GET_MODE_SIZE (REGISTER_NATURAL_MODE (reg));
- if ((TARGET_SH4 || TARGET_SH5) && TARGET_FMOVD
+ if ((TARGET_SH4 || TARGET_SH2A_DOUBLE || TARGET_SH5) && TARGET_FMOVD
&& GET_MODE_CLASS (REGISTER_NATURAL_MODE (reg)) == MODE_FLOAT)
{
if (FP_REGISTER_P (reg))
@@ -6194,7 +6206,7 @@ sh_builtin_saveregs (void)
emit_move_insn (fpregs, XEXP (regbuf, 0));
emit_insn (gen_addsi3 (fpregs, fpregs,
GEN_INT (n_floatregs * UNITS_PER_WORD)));
- if (TARGET_SH4)
+ if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
{
rtx mem;
for (regno = NPARM_REGS (DFmode) - 2; regno >= first_floatreg; regno -= 2)
@@ -6838,7 +6850,7 @@ sh_function_arg_advance (CUMULATIVE_ARGS *ca, enum machine_mode mode,
}
}
- if (! (TARGET_SH4 || ca->renesas_abi)
+ if (! ((TARGET_SH4 || TARGET_SH2A) || ca->renesas_abi)
|| PASS_IN_REG_P (*ca, mode, type))
(ca->arg_count[(int) GET_SH_ARG_CLASS (mode)]
= (ROUND_REG (*ca, mode)
@@ -7565,7 +7577,10 @@ tertiary_reload_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
int
fpscr_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
- return (GET_CODE (op) == REG && REGNO (op) == FPSCR_REG
+ return (GET_CODE (op) == REG
+ && (REGNO (op) == FPSCR_REG
+ || (REGNO (op) >= FIRST_PSEUDO_REGISTER
+ && !(reload_in_progress || reload_completed)))
&& GET_MODE (op) == PSImode);
}
diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h
index 71546facf9d..276bd1e1101 100644
--- a/gcc/config/sh/sh.h
+++ b/gcc/config/sh/sh.h
@@ -48,6 +48,13 @@ do { \
case PROCESSOR_SH2E: \
builtin_define ("__SH2E__"); \
break; \
+ case PROCESSOR_SH2A: \
+ builtin_define ("__SH2A__"); \
+ builtin_define (TARGET_SH2A_DOUBLE \
+ ? (TARGET_FPU_SINGLE ? "__SH2A_SINGLE__" : "__SH2A_DOUBLE__") \
+ : TARGET_FPU_ANY ? "__SH2A_SINGLE_ONLY__" \
+ : "__SH2A_NOFPU__"); \
+ break; \
case PROCESSOR_SH3: \
builtin_define ("__sh3__"); \
builtin_define ("__SH3__"); \
@@ -159,6 +166,8 @@ extern int target_flags;
#define LITTLE_ENDIAN_BIT (1<<29)
#define IEEE_BIT (1<<30)
#define SAVE_ALL_TR_BIT (1<<2)
+#define HARD_SH2A_BIT (1<<17)
+#define HARD_SH2A_DOUBLE_BIT (1<<18)
/* Nonzero if this is an ELF target - compile time only */
#define TARGET_ELF 0
@@ -178,6 +187,13 @@ extern int target_flags;
/* Nonzero if we should generate code using type 2E insns. */
#define TARGET_SH2E ((target_flags & SH_E_BIT) && TARGET_SH2)
+/* Nonzero if we should generate code using type 2A insns. */
+#define TARGET_SH2A (target_flags & HARD_SH2A_BIT)
+/* Nonzero if we should generate code using type 2A SF insns. */
+#define TARGET_SH2A_SINGLE ((target_flags & HARD_SH2A_BIT) && TARGET_SH2E)
+/* Nonzero if we should generate code using type 2A DF insns. */
+#define TARGET_SH2A_DOUBLE ((target_flags & HARD_SH2A_DOUBLE_BIT) && TARGET_SH2A)
+
/* Nonzero if we should generate code using type 3 insns. */
#define TARGET_SH3 (target_flags & SH3_BIT)
@@ -200,7 +216,7 @@ extern int target_flags;
#define TARGET_FPU_SINGLE (target_flags & FPU_SINGLE_BIT)
/* Nonzero if a double-precision FPU is available. */
-#define TARGET_FPU_DOUBLE (target_flags & SH4_BIT)
+#define TARGET_FPU_DOUBLE ((target_flags & SH4_BIT) || TARGET_SH2A_DOUBLE)
/* Nonzero if an FPU is available. */
#define TARGET_FPU_ANY (TARGET_SH2E || TARGET_FPU_DOUBLE)
@@ -290,11 +306,18 @@ extern int target_flags;
#define SUPPORT_SH2E
#define SUPPORT_SH4
#define SUPPORT_SH4_SINGLE
+#define SUPPORT_SH2A
+#define SUPPORT_SH2A_SINGLE
#endif
#define SELECT_SH1 (SH1_BIT)
#define SELECT_SH2 (SH2_BIT | SELECT_SH1)
#define SELECT_SH2E (SH_E_BIT | SH2_BIT | SH1_BIT | FPU_SINGLE_BIT)
+#define SELECT_SH2A (SH_E_BIT | HARD_SH2A_BIT | HARD_SH2A_DOUBLE_BIT | SH2_BIT | SH1_BIT)
+#define SELECT_SH2A_NOFPU (HARD_SH2A_BIT | SH2_BIT | SH1_BIT)
+#define SELECT_SH2A_SINGLE_ONLY (SH_E_BIT | HARD_SH2A_BIT | SH2_BIT | SH1_BIT | FPU_SINGLE_BIT)
+#define SELECT_SH2A_SINGLE (SH_E_BIT | HARD_SH2A_BIT | FPU_SINGLE_BIT \
+ | HARD_SH2A_DOUBLE_BIT | SH2_BIT | SH1_BIT)
#define SELECT_SH3 (SH3_BIT | SELECT_SH2)
#define SELECT_SH3E (SH_E_BIT | FPU_SINGLE_BIT | SELECT_SH3)
#define SELECT_SH4_NOFPU (HARD_SH4_BIT | SELECT_SH3)
@@ -328,6 +351,9 @@ extern int target_flags;
#ifndef SUPPORT_SH4AL
#define TARGET_SWITCH_SH4AL
#endif
+#ifndef SUPPORT_SH2A_NOFPU
+#define TARGET_SWITCH_SH2A_NOFPU
+#endif
#endif
#endif
#endif
@@ -342,6 +368,9 @@ extern int target_flags;
#ifndef SUPPORT_SH4A_SINGLE_ONLY
#define TARGET_SWITCH_SH4A_SINGLE_ONLY
#endif
+#ifndef SUPPORT_SH2A_SINGLE_ONLY
+#define TARGET_SWITCH_SH2A_SINGLE_ONLY
+#endif
#endif
#endif
@@ -359,6 +388,14 @@ extern int target_flags;
#endif
#endif
+#ifndef SUPPORT_SH2A
+#define TARGET_SWITCH_SH2A
+#endif
+
+#ifndef SUPPORT_SH2A_SINGLE
+#define TARGET_SWITCH_SH2A_SINGLE
+#endif
+
#ifndef SUPPORT_SH5_64MEDIA
#define TARGET_SWITCH_SH5_64MEDIA
#endif
@@ -377,6 +414,7 @@ extern int target_flags;
/* Reset all target-selection flags. */
#define TARGET_NONE -(SH1_BIT | SH2_BIT | SH3_BIT | SH_E_BIT | SH4_BIT \
+ | HARD_SH2A_BIT | HARD_SH2A_DOUBLE_BIT \
| SH4A_BIT | HARD_SH4_BIT | FPU_SINGLE_BIT | SH5_BIT)
#ifndef TARGET_SWITCH_SH1
@@ -394,6 +432,26 @@ extern int target_flags;
{"2e", TARGET_NONE, "" }, \
{"2e", SELECT_SH2E, "Generate SH2e code" },
#endif
+#ifndef TARGET_SWITCH_SH2A
+#define TARGET_SWITCH_SH2A \
+ {"2a", TARGET_NONE, "" }, \
+ {"2a", SELECT_SH2A, "Generate SH2a code" },
+#endif
+#ifndef TARGET_SWITCH_SH2A_SINGLE_ONLY
+#define TARGET_SWITCH_SH2A_SINGLE_ONLY \
+ {"2a-single-only", TARGET_NONE, "" }, \
+ {"2a-single-only", SELECT_SH2A_SINGLE_ONLY, "Generate only single-precision SH2a code" },
+#endif
+#ifndef TARGET_SWITCH_SH2A_SINGLE
+#define TARGET_SWITCH_SH2A_SINGLE \
+ {"2a-single", TARGET_NONE, "" }, \
+ {"2a-single", SELECT_SH2A_SINGLE, "Generate default single-precision SH2a code" },
+#endif
+#ifndef TARGET_SWITCH_SH2A_NOFPU
+#define TARGET_SWITCH_SH2A_NOFPU \
+ {"2a-nofpu", TARGET_NONE, "" }, \
+ {"2a-nofpu", SELECT_SH2A_NOFPU, "Generate SH2a FPU-less code" },
+#endif
#ifndef TARGET_SWITCH_SH3
#define TARGET_SWITCH_SH3 \
{"3", TARGET_NONE, "" }, \
@@ -477,6 +535,10 @@ extern int target_flags;
#define TARGET_SWITCHES \
{ TARGET_SWITCH_SH1 \
TARGET_SWITCH_SH2 \
+ TARGET_SWITCH_SH2A_SINGLE_ONLY \
+ TARGET_SWITCH_SH2A_SINGLE \
+ TARGET_SWITCH_SH2A_NOFPU \
+ TARGET_SWITCH_SH2A \
TARGET_SWITCH_SH2E \
TARGET_SWITCH_SH3 \
TARGET_SWITCH_SH3E \
@@ -612,6 +674,7 @@ extern int target_flags;
%(subtarget_link_emul_suffix) \
%{mrelax:-relax} %(subtarget_link_spec)"
+#define DRIVER_SELF_SPECS "%{m2a:%{ml:%eSH2a does not support little-endian}}"
#define OPTIMIZATION_OPTIONS(LEVEL,SIZE) \
do { \
if (LEVEL) \
@@ -640,6 +703,12 @@ do { \
sh_cpu = CPU_SH2; \
if (TARGET_SH2E) \
sh_cpu = CPU_SH2E; \
+ if (TARGET_SH2A) \
+ { \
+ sh_cpu = CPU_SH2A; \
+ if (TARGET_SH2A_DOUBLE) \
+ target_flags |= FMOVD_BIT; \
+ } \
if (TARGET_SH3) \
sh_cpu = CPU_SH3; \
if (TARGET_SH3E) \
@@ -1210,7 +1279,7 @@ extern char sh_additional_register_names[ADDREGNAMES_SIZE] \
: FP_REGISTER_P (REGNO) \
? ((MODE) == SFmode || (MODE) == SImode \
|| ((TARGET_SH2E || TARGET_SHMEDIA) && (MODE) == SCmode) \
- || (((TARGET_SH4 && (MODE) == DFmode) || (MODE) == DCmode \
+ || ((((TARGET_SH4 || TARGET_SH2A_DOUBLE) && (MODE) == DFmode) || (MODE) == DCmode \
|| (TARGET_SHMEDIA && ((MODE) == DFmode || (MODE) == DImode \
|| (MODE) == V2SFmode || (MODE) == TImode))) \
&& (((REGNO) - FIRST_FP_REG) & 1) == 0)) \
@@ -1552,7 +1621,7 @@ extern enum reg_class reg_class_from_letter[];
(((C) == 'L' || (C) == 'O' || (C) == 'D' || (C) == 'T' || (C) == 'U' \
|| (C) == 'Y' \
|| ((C) == 'I' \
- && (((STR)[1] != '0' && (STR)[1] != '1') \
+ && (((STR)[1] != '0' && (STR)[1] != '1' && (STR)[1] != '2') \
|| (STR)[2] < '0' || (STR)[2] > '9')) \
|| ((C) == 'B' && ((STR)[1] != 's' || (STR)[2] != 'c')) \
|| ((C) == 'J' && ((STR)[1] != '1' || (STR)[2] != '6')) \
@@ -1595,11 +1664,15 @@ extern enum reg_class reg_class_from_letter[];
&& ((HOST_WIDE_INT)(VALUE)) <= 511)
#define CONST_OK_FOR_I16(VALUE) (((HOST_WIDE_INT)(VALUE)) >= -32768 \
&& ((HOST_WIDE_INT)(VALUE)) <= 32767)
+#define CONST_OK_FOR_I20(VALUE) (((HOST_WIDE_INT)(VALUE)) >= -524288 \
+ && ((HOST_WIDE_INT)(VALUE)) <= 524287 \
+ && TARGET_SH2A)
#define CONST_OK_FOR_I(VALUE, STR) \
((STR)[1] == '0' && (STR)[2] == 6 ? CONST_OK_FOR_I06 (VALUE) \
: (STR)[1] == '0' && (STR)[2] == '8' ? CONST_OK_FOR_I08 (VALUE) \
: (STR)[1] == '1' && (STR)[2] == '0' ? CONST_OK_FOR_I10 (VALUE) \
: (STR)[1] == '1' && (STR)[2] == '6' ? CONST_OK_FOR_I16 (VALUE) \
+ : (STR)[1] == '2' && (STR)[2] == '0' ? CONST_OK_FOR_I20 (VALUE) \
: 0)
#define CONST_OK_FOR_J16(VALUE) \
@@ -1740,7 +1813,7 @@ extern enum reg_class reg_class_from_letter[];
#define NPARM_REGS(MODE) \
(TARGET_FPU_ANY && (MODE) == SFmode \
? (TARGET_SH5 ? 12 : 8) \
- : TARGET_SH4 && (GET_MODE_CLASS (MODE) == MODE_FLOAT \
+ : (TARGET_SH4 || TARGET_SH2A_DOUBLE) && (GET_MODE_CLASS (MODE) == MODE_FLOAT \
|| GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT) \
? (TARGET_SH5 ? 12 : 8) \
: (TARGET_SH5 ? 8 : 4))
@@ -1811,7 +1884,7 @@ extern enum reg_class reg_class_from_letter[];
#define BASE_ARG_REG(MODE) \
((TARGET_SH2E && ((MODE) == SFmode)) \
? FIRST_FP_PARM_REG \
- : TARGET_SH4 && (GET_MODE_CLASS (MODE) == MODE_FLOAT \
+ : (TARGET_SH4 || TARGET_SH2A_DOUBLE) && (GET_MODE_CLASS (MODE) == MODE_FLOAT \
|| GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT)\
? FIRST_FP_PARM_REG \
: FIRST_PARM_REG)
@@ -1998,7 +2071,7 @@ struct sh_args {
#define ROUND_REG(CUM, MODE) \
(((TARGET_ALIGN_DOUBLE \
- || (TARGET_SH4 && ((MODE) == DFmode || (MODE) == DCmode) \
+ || ((TARGET_SH4 || TARGET_SH2A_DOUBLE) && ((MODE) == DFmode || (MODE) == DCmode) \
&& (CUM).arg_count[(int) SH_ARG_FLOAT] < NPARM_REGS (MODE)))\
&& GET_MODE_UNIT_SIZE ((MODE)) > UNITS_PER_WORD) \
? ((CUM).arg_count[(int) GET_SH_ARG_CLASS (MODE)] \
@@ -2181,7 +2254,7 @@ struct sh_args {
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
((! TARGET_SH5 \
&& PASS_IN_REG_P ((CUM), (MODE), (TYPE)) \
- && ! TARGET_SH4 \
+ && ! (TARGET_SH4 || TARGET_SH2A_DOUBLE) \
&& (ROUND_REG ((CUM), (MODE)) \
+ ((MODE) != BLKmode \
? ROUND_ADVANCE (GET_MODE_SIZE (MODE)) \
@@ -2542,6 +2615,20 @@ struct sh_args {
((GET_MODE_SIZE(MODE)==8) && ((unsigned)INTVAL(X)<60) \
&& ! (INTVAL(X) & 3) && ! (TARGET_SH4 && (MODE) == DFmode))
+#undef MODE_DISP_OK_4
+#define MODE_DISP_OK_4(X,MODE) \
+((GET_MODE_SIZE (MODE) == 4 && (unsigned) INTVAL (X) < 64 \
+ && ! (INTVAL (X) & 3) && ! (TARGET_SH2E && (MODE) == SFmode)) \
+ || ((GET_MODE_SIZE(MODE)==4) && ((unsigned)INTVAL(X)<16383) \
+ && ! (INTVAL(X) & 3) && TARGET_SH2A))
+
+#undef MODE_DISP_OK_8
+#define MODE_DISP_OK_8(X,MODE) \
+(((GET_MODE_SIZE(MODE)==8) && ((unsigned)INTVAL(X)<60) \
+ && ! (INTVAL(X) & 3) && ! ((TARGET_SH4 || TARGET_SH2A) && (MODE) == DFmode)) \
+ || ((GET_MODE_SIZE(MODE)==8) && ((unsigned)INTVAL(X)<8192) \
+ && ! (INTVAL(X) & (TARGET_SH2A_DOUBLE ? 7 : 3)) && (TARGET_SH2A && (MODE) == DFmode)))
+
#define BASE_REGISTER_RTX_P(X) \
((GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X)) \
|| (GET_CODE (X) == SUBREG \
@@ -2615,7 +2702,7 @@ struct sh_args {
GO_IF_LEGITIMATE_INDEX ((MODE), xop1, LABEL); \
if (GET_MODE_SIZE (MODE) <= 4 \
|| (TARGET_SHMEDIA && GET_MODE_SIZE (MODE) <= 8) \
- || (TARGET_SH4 && TARGET_FMOVD && MODE == DFmode)) \
+ || ((TARGET_SH4 || TARGET_SH2A_DOUBLE) && TARGET_FMOVD && MODE == DFmode)) \
{ \
if (BASE_REGISTER_RTX_P (xop1) && INDEX_REGISTER_RTX_P (xop0))\
goto LABEL; \
@@ -2652,7 +2739,7 @@ struct sh_args {
&& GET_CODE (XEXP ((X), 1)) == CONST_INT \
&& BASE_REGISTER_RTX_P (XEXP ((X), 0)) \
&& ! TARGET_SHMEDIA \
- && ! (TARGET_SH4 && (MODE) == DFmode) \
+ && ! ((TARGET_SH4 || TARGET_SH2A_DOUBLE) && (MODE) == DFmode) \
&& ! (TARGET_SH2E && (MODE) == SFmode)) \
{ \
rtx index_rtx = XEXP ((X), 1); \
@@ -2708,6 +2795,13 @@ struct sh_args {
HOST_WIDE_INT offset = INTVAL (index_rtx), offset_base; \
rtx sum; \
\
+ if (TARGET_SH2A && (MODE) == DFmode && (offset & 0x7)) \
+ { \
+ push_reload (X, NULL_RTX, &X, NULL, \
+ BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, (OPNUM), \
+ (TYPE)); \
+ goto WIN; \
+ } \
if (TARGET_SH2E && MODE == SFmode) \
{ \
X = copy_rtx (X); \
@@ -2795,7 +2889,7 @@ struct sh_args {
/* Since the SH2e has only `float' support, it is desirable to make all
floating point types equivalent to `float'. */
-#define DOUBLE_TYPE_SIZE ((TARGET_SH2E && ! TARGET_SH4) ? 32 : 64)
+#define DOUBLE_TYPE_SIZE ((TARGET_SH2E && ! TARGET_SH4 && ! TARGET_SH2A_DOUBLE) ? 32 : 64)
/* 'char' is signed by default. */
#define DEFAULT_SIGNED_CHAR 1
@@ -2853,7 +2947,7 @@ struct sh_args {
However, the SH3 has hardware shifts that do not truncate exactly as gcc
expects - the sign bit is significant - so it appears that we need to
leave this zero for correct SH3 code. */
-#define SHIFT_COUNT_TRUNCATED (! TARGET_SH3)
+#define SHIFT_COUNT_TRUNCATED (! TARGET_SH3 && ! TARGET_SH2A)
/* All integers have the same format so truncation is easy. */
#define TRULY_NOOP_TRUNCATION(OUTPREC,INPREC) 1
@@ -3246,6 +3340,7 @@ enum processor_type {
PROCESSOR_SH1,
PROCESSOR_SH2,
PROCESSOR_SH2E,
+ PROCESSOR_SH2A,
PROCESSOR_SH3,
PROCESSOR_SH3E,
PROCESSOR_SH4,
@@ -3377,7 +3472,7 @@ extern int rtx_equal_function_value_matters;
#define NUM_MODES_FOR_MODE_SWITCHING { FP_MODE_NONE }
-#define OPTIMIZE_MODE_SWITCHING(ENTITY) TARGET_SH4
+#define OPTIMIZE_MODE_SWITCHING(ENTITY) (TARGET_SH4 || TARGET_SH2A_DOUBLE)
#define ACTUAL_NORMAL_MODE(ENTITY) \
(TARGET_FPU_SINGLE ? FP_MODE_SINGLE : FP_MODE_DOUBLE)
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index 77ba4d59d74..e825fae614b 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -161,7 +161,7 @@
;; Target CPU.
(define_attr "cpu"
- "sh1,sh2,sh2e,sh3,sh3e,sh4,sh4a,sh5"
+ "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
(const (symbol_ref "sh_cpu_attr")))
(define_attr "endian" "big,little"
@@ -1151,6 +1151,14 @@
""
[(set_attr "length" "0")])
+(define_insn "udivsi3_sh2a"
+ [(set (match_operand:SI 0 "arith_reg_operand" "=r")
+ (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
+ (match_operand:SI 2 "arith_reg_operand" "z")))]
+ "TARGET_SH2A"
+ "divu %2,%1"
+ [(set_attr "type" "arith")])
+
;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
;; hard register 0. If we used hard register 0, then the next instruction
;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
@@ -1287,6 +1295,13 @@
emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
DONE;
}
+ else if (TARGET_SH2A)
+ {
+ operands[1] = force_reg (SImode, operands[1]);
+ operands[2] = force_reg (SImode, operands[2]);
+ emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
+ DONE;
+ }
else if (TARGET_SH5)
{
emit_move_insn (operands[3],
@@ -1320,6 +1335,14 @@
DONE;
}")
+(define_insn "divsi3_sh2a"
+ [(set (match_operand:SI 0 "arith_reg_operand" "=r")
+ (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
+ (match_operand:SI 2 "arith_reg_operand" "z")))]
+ "TARGET_SH2A"
+ "divs %2,%1"
+ [(set_attr "type" "arith")])
+
(define_insn "divsi3_i1"
[(set (match_operand:SI 0 "register_operand" "=z")
(div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
@@ -1427,6 +1450,13 @@
else
last = gen_divsi3_i4 (operands[0], operands[3]);
}
+ else if (TARGET_SH2A)
+ {
+ operands[1] = force_reg (SImode, operands[1]);
+ operands[2] = force_reg (SImode, operands[2]);
+ emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
+ DONE;
+ }
else if (TARGET_SHMEDIA_FPU)
{
operands[1] = force_reg (SImode, operands[1]);
@@ -1585,6 +1615,14 @@
"TARGET_SH1"
"")
+(define_insn "mul_r"
+ [(set (match_operand:SI 0 "arith_reg_operand" "=r")
+ (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
+ (match_operand:SI 2 "arith_reg_operand" "z")))]
+ "TARGET_SH2A"
+ "mulr %2,%0"
+ [(set_attr "type" "dmpy")])
+
(define_insn "mul_l"
[(set (reg:SI MACL_REG)
(mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
@@ -2134,6 +2172,15 @@
;;
;; shift left
+(define_insn "ashlsi3_sh2a"
+ [(set (match_operand:SI 0 "arith_reg_operand" "=r")
+ (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
+ (match_operand:SI 2 "arith_reg_operand" "r")))]
+ "TARGET_SH2A"
+ "shad %2,%0"
+ [(set_attr "type" "arith")
+ (set_attr "length" "4")])
+
;; This pattern is used by init_expmed for computing the costs of shift
;; insns.
@@ -2269,6 +2316,15 @@
; arithmetic shift right
;
+(define_insn "ashrsi3_sh2a"
+ [(set (match_operand:SI 0 "arith_reg_operand" "=r")
+ (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
+ (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
+ "TARGET_SH2A"
+ "shad %2,%0"
+ [(set_attr "type" "dyn_shift")
+ (set_attr "length" "4")])
+
(define_insn "ashrsi3_k"
[(set (match_operand:SI 0 "arith_reg_operand" "=r")
(ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
@@ -2388,6 +2444,15 @@
;; logical shift right
+(define_insn "lshrsi3_sh2a"
+ [(set (match_operand:SI 0 "arith_reg_operand" "=r")
+ (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
+ (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
+ "TARGET_SH2A"
+ "shld %2,%0"
+ [(set_attr "type" "dyn_shift")
+ (set_attr "length" "4")])
+
(define_insn "lshrsi3_d"
[(set (match_operand:SI 0 "arith_reg_operand" "=r")
(lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
@@ -3307,6 +3372,7 @@
"Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
"TARGET_SH1
&& ! TARGET_SH2E
+ && ! TARGET_SH2A
&& (register_operand (operands[0], SImode)
|| register_operand (operands[1], SImode))"
"@
@@ -3336,15 +3402,16 @@
;; TARGET_FMOVD is in effect, and mode switching is done before reload.
(define_insn "movsi_ie"
[(set (match_operand:SI 0 "general_movdst_operand"
- "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
+ "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
(match_operand:SI 1 "general_movsrc_operand"
- "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
- "TARGET_SH2E
+ "Q,rI08,I20,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
+ "(TARGET_SH2E || TARGET_SH2A)
&& (register_operand (operands[0], SImode)
|| register_operand (operands[1], SImode))"
"@
mov.l %1,%0
mov %1,%0
+ movi20 %1,%0
cmp/pl %1
mov.l %1,%0
sts %1,%0
@@ -3366,9 +3433,9 @@
flds %1,fpul
fmov %1,%0
! move optimized away"
- [(set_attr "type" "pcload_si,move,*,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,load,store,pcload_si,gp_fpul,fpul_gp,fmove,fmove,fmove,nil")
- (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
- (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
+ [(set_attr "type" "pcload_si,move,move,*,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,load,store,pcload_si,gp_fpul,fpul_gp,fmove,fmove,fmove,nil")
+ (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
+ (set_attr "length" "*,*,4,*,4,*,*,*,4,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
(define_insn "movsi_i_lowpart"
[(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
@@ -4109,7 +4176,7 @@
[(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
(match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
"TARGET_SH1
- && (! TARGET_SH4 || reload_completed
+ && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
/* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
|| (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
|| (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
@@ -4130,7 +4197,7 @@
(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"))
(clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
- "TARGET_SH4
+ "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
&& (arith_reg_operand (operands[0], DFmode)
|| arith_reg_operand (operands[1], DFmode))"
"@
@@ -4148,8 +4215,8 @@
[(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (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 2) (const_int 6))
- (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (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))
(const_int 4)
(const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
;; We can't use 4-byte push/pop on SHcompact, so we have to
@@ -4178,7 +4245,7 @@
(match_operand:DF 1 "register_operand" ""))
(use (match_operand:PSI 2 "fpscr_operand" ""))
(clobber (match_scratch:SI 3 "=X"))]
- "TARGET_SH4 && reload_completed
+ "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
&& (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
[(const_int 0)]
"
@@ -4217,7 +4284,7 @@
(match_operand:DF 1 "general_movsrc_operand" ""))
(use (match_operand:PSI 2 "fpscr_operand" ""))
(clobber (match_scratch:SI 3 ""))]
- "TARGET_SH4
+ "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
&& reload_completed
&& true_regnum (operands[0]) < 16
&& true_regnum (operands[1]) < 16"
@@ -4290,7 +4357,7 @@
(match_operand:DF 1 "memory_operand" ""))
(use (match_operand:PSI 2 "fpscr_operand" ""))
(clobber (reg:SI R0_REG))]
- "TARGET_SH4 && reload_completed"
+ "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
[(parallel [(set (match_dup 0) (match_dup 1))
(use (match_dup 2))
(clobber (scratch:SI))])]
@@ -4347,7 +4414,7 @@
(mem:DF (match_operand:SI 1 "register_operand" "")))
(use (match_operand:PSI 2 "fpscr_operand" ""))
(clobber (match_scratch:SI 3 ""))]
- "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
+ "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
&& FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
&& find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
[(const_int 0)]
@@ -4373,7 +4440,7 @@
(match_operand:DF 1 "memory_operand" ""))
(use (match_operand:PSI 2 "fpscr_operand" ""))
(clobber (match_scratch:SI 3 ""))]
- "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
+ "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
&& FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
[(const_int 0)]
"
@@ -4414,7 +4481,7 @@
(match_operand:DF 1 "register_operand" ""))
(use (match_operand:PSI 2 "fpscr_operand" ""))
(clobber (match_scratch:SI 3 ""))]
- "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
+ "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
&& FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
[(const_int 0)]
"
@@ -4568,7 +4635,7 @@
emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
DONE;
}
- if (TARGET_SH4)
+ if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
{
emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
DONE;
@@ -4865,7 +4932,7 @@
! move optimized away"
[(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
(set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
- (set_attr "length" "*,*,*,*,4,*,*,*,*,*,2,2,2,4,2,2,2,2,0")
+ (set_attr "length" "*,*,*,*,4,4,4,*,*,*,2,2,2,4,2,2,2,2,0")
(set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
(const_string "single")
(const_string "none")))])
@@ -6473,7 +6540,7 @@
(const_int 0))
(match_operand 1 "" "")
(match_operand 2 "" "")])]
- "TARGET_SH2E || TARGET_SHMEDIA"
+ "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
"
{
int i;
@@ -8069,7 +8136,7 @@ mov.l\\t1f,r0\\n\\
(define_expand "fpu_switch0"
[(set (match_operand:SI 0 "" "") (match_dup 2))
(set (match_dup 1) (mem:PSI (match_dup 0)))]
- "TARGET_SH4"
+ "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
"
{
operands[1] = get_fpscr_rtx ();
@@ -8083,7 +8150,7 @@ mov.l\\t1f,r0\\n\\
[(set (match_operand:SI 0 "" "") (match_dup 2))
(set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
(set (match_dup 1) (mem:PSI (match_dup 3)))]
- "TARGET_SH4"
+ "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
"
{
operands[1] = get_fpscr_rtx ();
@@ -8097,7 +8164,7 @@ mov.l\\t1f,r0\\n\\
(define_expand "movpsi"
[(set (match_operand:PSI 0 "register_operand" "")
(match_operand:PSI 1 "general_movsrc_operand" ""))]
- "TARGET_SH4"
+ "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
"")
;; The c / m alternative is a fake to guide reload to load directly into
@@ -8131,7 +8198,7 @@ mov.l\\t1f,r0\\n\\
(define_split
[(set (reg:PSI FPSCR_REG)
(mem:PSI (match_operand:SI 0 "register_operand" "")))]
- "TARGET_SH4 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
+ "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
[(set (match_dup 0) (match_dup 0))]
"
{
@@ -8145,7 +8212,7 @@ mov.l\\t1f,r0\\n\\
(define_split
[(set (reg:PSI FPSCR_REG)
(mem:PSI (match_operand:SI 0 "register_operand" "")))]
- "TARGET_SH4"
+ "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
[(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
"
{
@@ -8165,7 +8232,7 @@ mov.l\\t1f,r0\\n\\
(define_insn "toggle_sz"
[(set (reg:PSI FPSCR_REG)
(xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
- "TARGET_SH4"
+ "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
"fschg"
[(set_attr "type" "fp") (set_attr "fp_set" "unknown")])
@@ -8323,7 +8390,7 @@ mov.l\\t1f,r0\\n\\
"TARGET_SH2E || TARGET_SHMEDIA_FPU"
"
{
- if (TARGET_SH4)
+ if (TARGET_SH4 || TARGET_SH2A_SINGLE)
expand_sf_binop (&gen_mulsf3_i4, operands);
else if (TARGET_SH2E)
emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
@@ -8353,7 +8420,7 @@ mov.l\\t1f,r0\\n\\
[(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
(mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
(match_operand:SF 2 "fp_arith_reg_operand" "f")))]
- "TARGET_SH2E && ! TARGET_SH4"
+ "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
"fmul %2,%0"
[(set_attr "type" "fp")])
@@ -8422,7 +8489,7 @@ mov.l\\t1f,r0\\n\\
"TARGET_SH2E || TARGET_SHMEDIA_FPU"
"
{
- if (TARGET_SH4)
+ if (TARGET_SH4 || TARGET_SH2A_SINGLE)
{
emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
DONE;
@@ -8440,7 +8507,7 @@ mov.l\\t1f,r0\\n\\
[(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
(float:SF (match_operand:SI 1 "fpul_operand" "y")))
(use (match_operand:PSI 2 "fpscr_operand" "c"))]
- "TARGET_SH4"
+ "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
"float %1,%0"
[(set_attr "type" "fp")
(set_attr "fp_mode" "single")])
@@ -8448,7 +8515,7 @@ mov.l\\t1f,r0\\n\\
(define_insn "*floatsisf2_ie"
[(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
(float:SF (match_operand:SI 1 "fpul_operand" "y")))]
- "TARGET_SH2E && ! TARGET_SH4"
+ "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
"float %1,%0"
[(set_attr "type" "fp")])
@@ -8465,7 +8532,7 @@ mov.l\\t1f,r0\\n\\
"TARGET_SH2E || TARGET_SHMEDIA_FPU"
"
{
- if (TARGET_SH4)
+ if (TARGET_SH4 || TARGET_SH2A_SINGLE)
{
emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
DONE;
@@ -8483,7 +8550,7 @@ mov.l\\t1f,r0\\n\\
[(set (match_operand:SI 0 "fpul_operand" "=y")
(fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
(use (match_operand:PSI 2 "fpscr_operand" "c"))]
- "TARGET_SH4"
+ "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
"ftrc %1,%0"
[(set_attr "type" "ftrc_s")
(set_attr "fp_mode" "single")])
@@ -8513,7 +8580,7 @@ mov.l\\t1f,r0\\n\\
(define_insn "*fixsfsi"
[(set (match_operand:SI 0 "fpul_operand" "=y")
(fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
- "TARGET_SH2E && ! TARGET_SH4"
+ "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
"ftrc %1,%0"
[(set_attr "type" "fp")])
@@ -8521,7 +8588,7 @@ mov.l\\t1f,r0\\n\\
[(set (reg:SI T_REG)
(gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
(match_operand:SF 1 "fp_arith_reg_operand" "f")))]
- "TARGET_SH2E && ! TARGET_SH4"
+ "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
"fcmp/gt %1,%0"
[(set_attr "type" "fp")
(set_attr "fp_mode" "single")])
@@ -8530,7 +8597,7 @@ mov.l\\t1f,r0\\n\\
[(set (reg:SI T_REG)
(eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
(match_operand:SF 1 "fp_arith_reg_operand" "f")))]
- "TARGET_SH2E && ! TARGET_SH4"
+ "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
"fcmp/eq %1,%0"
[(set_attr "type" "fp")
(set_attr "fp_mode" "single")])
@@ -8540,7 +8607,7 @@ mov.l\\t1f,r0\\n\\
(ior:SI (reg:SI T_REG)
(eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
(match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
- "TARGET_SH2E && TARGET_IEEE && ! TARGET_SH4"
+ "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
"* return output_ieee_ccmpeq (insn, operands);"
[(set_attr "length" "4")])
@@ -8550,7 +8617,7 @@ mov.l\\t1f,r0\\n\\
(gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
(match_operand:SF 1 "fp_arith_reg_operand" "f")))
(use (match_operand:PSI 2 "fpscr_operand" "c"))]
- "TARGET_SH4"
+ "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
"fcmp/gt %1,%0"
[(set_attr "type" "fp")
(set_attr "fp_mode" "single")])
@@ -8560,7 +8627,7 @@ mov.l\\t1f,r0\\n\\
(eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
(match_operand:SF 1 "fp_arith_reg_operand" "f")))
(use (match_operand:PSI 2 "fpscr_operand" "c"))]
- "TARGET_SH4"
+ "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
"fcmp/eq %1,%0"
[(set_attr "type" "fp")
(set_attr "fp_mode" "single")])
@@ -8571,7 +8638,7 @@ mov.l\\t1f,r0\\n\\
(eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
(match_operand:SF 1 "fp_arith_reg_operand" "f"))))
(use (match_operand:PSI 2 "fpscr_operand" "c"))]
- "TARGET_IEEE && TARGET_SH4"
+ "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
"* return output_ieee_ccmpeq (insn, operands);"
[(set_attr "length" "4")
(set_attr "fp_mode" "single")])
@@ -8822,10 +8889,10 @@ mov.l\\t1f,r0\\n\\
[(set (match_operand:DF 0 "fp_arith_reg_operand" "")
(plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
(match_operand:DF 2 "fp_arith_reg_operand" "")))]
- "TARGET_SH4 || TARGET_SHMEDIA_FPU"
+ "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
"
{
- if (TARGET_SH4)
+ if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
{
expand_df_binop (&gen_adddf3_i, operands);
DONE;
@@ -8845,7 +8912,7 @@ mov.l\\t1f,r0\\n\\
(plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
(match_operand:DF 2 "fp_arith_reg_operand" "f")))
(use (match_operand:PSI 3 "fpscr_operand" "c"))]
- "TARGET_SH4"
+ "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
"fadd %2,%0"
[(set_attr "type" "dfp_arith")
(set_attr "fp_mode" "double")])
@@ -8854,10 +8921,10 @@ mov.l\\t1f,r0\\n\\
[(set (match_operand:DF 0 "fp_arith_reg_operand" "")
(minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
(match_operand:DF 2 "fp_arith_reg_operand" "")))]
- "TARGET_SH4 || TARGET_SHMEDIA_FPU"
+ "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
"
{
- if (TARGET_SH4)
+ if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
{
expand_df_binop (&gen_subdf3_i, operands);
DONE;
@@ -8877,7 +8944,7 @@ mov.l\\t1f,r0\\n\\
(minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
(match_operand:DF 2 "fp_arith_reg_operand" "f")))
(use (match_operand:PSI 3 "fpscr_operand" "c"))]
- "TARGET_SH4"
+ "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
"fsub %2,%0"
[(set_attr "type" "dfp_arith")
(set_attr "fp_mode" "double")])
@@ -8886,10 +8953,10 @@ mov.l\\t1f,r0\\n\\
[(set (match_operand:DF 0 "fp_arith_reg_operand" "")
(mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
(match_operand:DF 2 "fp_arith_reg_operand" "")))]
- "TARGET_SH4 || TARGET_SHMEDIA_FPU"
+ "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
"
{
- if (TARGET_SH4)
+ if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
{
expand_df_binop (&gen_muldf3_i, operands);
DONE;
@@ -8909,7 +8976,7 @@ mov.l\\t1f,r0\\n\\
(mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
(match_operand:DF 2 "fp_arith_reg_operand" "f")))
(use (match_operand:PSI 3 "fpscr_operand" "c"))]
- "TARGET_SH4"
+ "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
"fmul %2,%0"
[(set_attr "type" "dfp_arith")
(set_attr "fp_mode" "double")])
@@ -8918,10 +8985,10 @@ mov.l\\t1f,r0\\n\\
[(set (match_operand:DF 0 "fp_arith_reg_operand" "")
(div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
(match_operand:DF 2 "fp_arith_reg_operand" "")))]
- "TARGET_SH4 || TARGET_SHMEDIA_FPU"
+ "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
"
{
- if (TARGET_SH4)
+ if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
{
expand_df_binop (&gen_divdf3_i, operands);
DONE;
@@ -8941,7 +9008,7 @@ mov.l\\t1f,r0\\n\\
(div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
(match_operand:DF 2 "fp_arith_reg_operand" "f")))
(use (match_operand:PSI 3 "fpscr_operand" "c"))]
- "TARGET_SH4"
+ "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
"fdiv %2,%0"
[(set_attr "type" "dfdiv")
(set_attr "fp_mode" "double")])
@@ -8956,10 +9023,10 @@ mov.l\\t1f,r0\\n\\
(define_expand "floatsidf2"
[(set (match_operand:DF 0 "fp_arith_reg_operand" "")
(float:DF (match_operand:SI 1 "fpul_operand" "")))]
- "TARGET_SH4 || TARGET_SHMEDIA_FPU"
+ "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
"
{
- if (TARGET_SH4)
+ if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
{
emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
get_fpscr_rtx ()));
@@ -8978,7 +9045,7 @@ mov.l\\t1f,r0\\n\\
[(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
(float:DF (match_operand:SI 1 "fpul_operand" "y")))
(use (match_operand:PSI 2 "fpscr_operand" "c"))]
- "TARGET_SH4"
+ "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
"float %1,%0"
[(set_attr "type" "dfp_conv")
(set_attr "fp_mode" "double")])
@@ -8993,10 +9060,10 @@ mov.l\\t1f,r0\\n\\
(define_expand "fix_truncdfsi2"
[(set (match_operand:SI 0 "fpul_operand" "")
(fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
- "TARGET_SH4 || TARGET_SHMEDIA_FPU"
+ "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
"
{
- if (TARGET_SH4)
+ if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
{
emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
get_fpscr_rtx ()));
@@ -9015,7 +9082,7 @@ mov.l\\t1f,r0\\n\\
[(set (match_operand:SI 0 "fpul_operand" "=y")
(fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
(use (match_operand:PSI 2 "fpscr_operand" "c"))]
- "TARGET_SH4"
+ "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
"ftrc %1,%0"
[(set_attr "type" "dfp_conv")
(set_attr "dfp_comp" "no")
@@ -9048,7 +9115,7 @@ mov.l\\t1f,r0\\n\\
(gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
(match_operand:DF 1 "arith_reg_operand" "f")))
(use (match_operand:PSI 2 "fpscr_operand" "c"))]
- "TARGET_SH4"
+ "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
"fcmp/gt %1,%0"
[(set_attr "type" "dfp_cmp")
(set_attr "fp_mode" "double")])
@@ -9058,7 +9125,7 @@ mov.l\\t1f,r0\\n\\
(eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
(match_operand:DF 1 "arith_reg_operand" "f")))
(use (match_operand:PSI 2 "fpscr_operand" "c"))]
- "TARGET_SH4"
+ "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
"fcmp/eq %1,%0"
[(set_attr "type" "dfp_cmp")
(set_attr "fp_mode" "double")])
@@ -9069,7 +9136,7 @@ mov.l\\t1f,r0\\n\\
(eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
(match_operand:DF 1 "arith_reg_operand" "f"))))
(use (match_operand:PSI 2 "fpscr_operand" "c"))]
- "TARGET_IEEE && TARGET_SH4"
+ "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
"* return output_ieee_ccmpeq (insn, operands);"
[(set_attr "length" "4")
(set_attr "fp_mode" "double")])
@@ -9110,7 +9177,7 @@ mov.l\\t1f,r0\\n\\
[(set (reg:SI T_REG)
(compare (match_operand:DF 0 "arith_operand" "")
(match_operand:DF 1 "arith_operand" "")))]
- "TARGET_SH4 || TARGET_SHMEDIA_FPU"
+ "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
"
{
sh_compare_op0 = operands[0];
@@ -9121,10 +9188,10 @@ mov.l\\t1f,r0\\n\\
(define_expand "negdf2"
[(set (match_operand:DF 0 "arith_reg_operand" "")
(neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
- "TARGET_SH4 || TARGET_SHMEDIA_FPU"
+ "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
"
{
- if (TARGET_SH4)
+ if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
{
expand_df_unop (&gen_negdf2_i, operands);
DONE;
@@ -9142,7 +9209,7 @@ mov.l\\t1f,r0\\n\\
[(set (match_operand:DF 0 "arith_reg_operand" "=f")
(neg:DF (match_operand:DF 1 "arith_reg_operand" "0")))
(use (match_operand:PSI 2 "fpscr_operand" "c"))]
- "TARGET_SH4"
+ "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
"fneg %0"
[(set_attr "type" "fmove")
(set_attr "fp_mode" "double")])
@@ -9150,10 +9217,10 @@ mov.l\\t1f,r0\\n\\
(define_expand "sqrtdf2"
[(set (match_operand:DF 0 "arith_reg_operand" "")
(sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
- "TARGET_SH4 || TARGET_SHMEDIA_FPU"
+ "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
"
{
- if (TARGET_SH4)
+ if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
{
expand_df_unop (&gen_sqrtdf2_i, operands);
DONE;
@@ -9171,7 +9238,7 @@ mov.l\\t1f,r0\\n\\
[(set (match_operand:DF 0 "arith_reg_operand" "=f")
(sqrt:DF (match_operand:DF 1 "arith_reg_operand" "0")))
(use (match_operand:PSI 2 "fpscr_operand" "c"))]
- "TARGET_SH4"
+ "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
"fsqrt %0"
[(set_attr "type" "dfdiv")
(set_attr "fp_mode" "double")])
@@ -9179,10 +9246,10 @@ mov.l\\t1f,r0\\n\\
(define_expand "absdf2"
[(set (match_operand:DF 0 "arith_reg_operand" "")
(abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
- "TARGET_SH4 || TARGET_SHMEDIA_FPU"
+ "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
"
{
- if (TARGET_SH4)
+ if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
{
expand_df_unop (&gen_absdf2_i, operands);
DONE;
@@ -9200,7 +9267,7 @@ mov.l\\t1f,r0\\n\\
[(set (match_operand:DF 0 "arith_reg_operand" "=f")
(abs:DF (match_operand:DF 1 "arith_reg_operand" "0")))
(use (match_operand:PSI 2 "fpscr_operand" "c"))]
- "TARGET_SH4"
+ "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
"fabs %0"
[(set_attr "type" "fmove")
(set_attr "fp_mode" "double")])
@@ -9208,10 +9275,10 @@ mov.l\\t1f,r0\\n\\
(define_expand "extendsfdf2"
[(set (match_operand:DF 0 "fp_arith_reg_operand" "")
(float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
- "TARGET_SH4 || TARGET_SHMEDIA_FPU"
+ "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
"
{
- if (TARGET_SH4)
+ if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
{
emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
get_fpscr_rtx ()));
@@ -9230,7 +9297,7 @@ mov.l\\t1f,r0\\n\\
[(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
(float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
(use (match_operand:PSI 2 "fpscr_operand" "c"))]
- "TARGET_SH4"
+ "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
"fcnvsd %1,%0"
[(set_attr "type" "fp")
(set_attr "fp_mode" "double")])
@@ -9238,10 +9305,10 @@ mov.l\\t1f,r0\\n\\
(define_expand "truncdfsf2"
[(set (match_operand:SF 0 "fpul_operand" "")
(float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
- "TARGET_SH4 || TARGET_SHMEDIA_FPU"
+ "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
"
{
- if (TARGET_SH4)
+ if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
{
emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
get_fpscr_rtx ()));
@@ -9260,7 +9327,7 @@ mov.l\\t1f,r0\\n\\
[(set (match_operand:SF 0 "fpul_operand" "=y")
(float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
(use (match_operand:PSI 2 "fpscr_operand" "c"))]
- "TARGET_SH4"
+ "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
"fcnvds %1,%0"
[(set_attr "type" "fp")
(set_attr "fp_mode" "double")])
diff --git a/gcc/config/sh/t-mlib-sh2a b/gcc/config/sh/t-mlib-sh2a
new file mode 100644
index 00000000000..e276ac99517
--- /dev/null
+++ b/gcc/config/sh/t-mlib-sh2a
@@ -0,0 +1 @@
+ML_sh2a=m2a/
diff --git a/gcc/config/sh/t-mlib-sh2a-nofpu b/gcc/config/sh/t-mlib-sh2a-nofpu
new file mode 100644
index 00000000000..a84874efcd0
--- /dev/null
+++ b/gcc/config/sh/t-mlib-sh2a-nofpu
@@ -0,0 +1 @@
+ML_sh2a_nofpu=m2a-nofpu/
diff --git a/gcc/config/sh/t-mlib-sh2a-single b/gcc/config/sh/t-mlib-sh2a-single
new file mode 100644
index 00000000000..b3432fa83a1
--- /dev/null
+++ b/gcc/config/sh/t-mlib-sh2a-single
@@ -0,0 +1 @@
+ML_sh2a_single=m2a-single/
diff --git a/gcc/config/sh/t-mlib-sh2a-single-only b/gcc/config/sh/t-mlib-sh2a-single-only
new file mode 100644
index 00000000000..e34afe2f219
--- /dev/null
+++ b/gcc/config/sh/t-mlib-sh2a-single-only
@@ -0,0 +1 @@
+ML_sh2a_single_only=m2a-single-only/
diff --git a/gcc/config/sh/t-sh b/gcc/config/sh/t-sh
index 97dd99bf101..3660d06aacf 100644
--- a/gcc/config/sh/t-sh
+++ b/gcc/config/sh/t-sh
@@ -22,15 +22,19 @@ fp-bit.c: $(srcdir)/config/fp-bit.c
cat $(srcdir)/config/fp-bit.c >> fp-bit.c
MULTILIB_ENDIAN = ml/mb
-MULTILIB_CPUS= $(ML_sh1)$(ML_sh2e)$(ML_sh2)$(ML_sh3e)$(ML_sh3)$(ML_sh4_nofpu)$(ML_sh4_single_only)$(ML_sh4_single)$(ML_sh4)$(ML_sh4a_nofpu)$(ML_sh4a_single_only)$(ML_sh4a_single)$(ML_sh4a)$(ML_m5_32media)$(ML_m5_32media_nofpu)$(ML_m5_compact)$(ML_m5_compact_nofpu)$(ML_m5_64media)$(ML_m5_64media_nofpu)
+MULTILIB_CPUS= $(ML_sh1)$(ML_sh2a)$(ML_sh2a_nofpu)$(ML_sh2a_single_only)$(ML_sh2a_single)$(ML_sh2e)$(ML_sh2)$(ML_sh3e)$(ML_sh3)$(ML_sh4_nofpu)$(ML_sh4_single_only)$(ML_sh4_single)$(ML_sh4)$(ML_sh4a_nofpu)$(ML_sh4a_single_only)$(ML_sh4a_single)$(ML_sh4a)$(ML_m5_32media)$(ML_m5_32media_nofpu)$(ML_m5_compact)$(ML_m5_compact_nofpu)$(ML_m5_64media)$(ML_m5_64media_nofpu)
MULTILIB_OPTIONS= $(MULTILIB_ENDIAN) $(MULTILIB_CPUS:/=)
MULTILIB_DIRNAMES=
-#MULTILIB_MATCHES = m2=m3 m2e=m3e m2=m4-nofpu
+
+# The separate entries for m2a-nofpu and m2a-single-only with
+# duplicate base libraries are there to make sure we don't ever use an
+# m4* multilib for m2a or vice-versa; they are not compatible. This
+# is why sh2a and sh2a-single need their own multilibs.
MULTILIB_MATCHES = $(shell \
multilibs="$(MULTILIB_OPTIONS)" ; \
- for abi in m1,m2,m3,m4-nofpu,m4al,m4a-nofpu \
- m2e,m3e,m4-single-only,m4a-single-only \
+ for abi in m1,m2,m3,m4-nofpu,m4al,m4a-nofpu m1,m2,m2a-nofpu \
+ m2e,m3e,m4-single-only,m4a-single-only m2e,m2a-single-only \
m4-single,m4a-single m4,m4a \
m5-32media,m5-compact,m5-32media \
m5-32media-nofpu,m5-compact-nofpu,m5-32media-nofpu; do \
@@ -45,7 +49,7 @@ MULTILIB_MATCHES = $(shell \
done)
# SH1 only supports big endian.
-MULTILIB_EXCEPTIONS = ml/m1
+MULTILIB_EXCEPTIONS = ml/m1 ml/m2a*
LIBGCC = stmp-multilib
INSTALL_LIBGCC = install-multilib
@@ -62,3 +66,7 @@ gt-sh.h : s-gtype ; @true
# These are not suitable for COFF.
# EXTRA_MULTILIB_PARTS= crt1.o crti.o crtn.o crtbegin.o crtend.o
+
+# Local Variables:
+# mode: Makefile
+# End: