Introduce sh2a support.
authorAlexandre Oliva <aoliva@redhat.com>
Thu, 29 Jul 2004 06:10:03 +0000 (06:10 +0000)
committerAlexandre Oliva <aoliva@gcc.gnu.org>
Thu, 29 Jul 2004 06:10:03 +0000 (06:10 +0000)
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.

From-SVN: r85286

13 files changed:
gcc/ChangeLog
gcc/config.gcc
gcc/config/sh/crt1.asm
gcc/config/sh/elf.h
gcc/config/sh/lib1funcs.asm
gcc/config/sh/sh.c
gcc/config/sh/sh.h
gcc/config/sh/sh.md
gcc/config/sh/t-mlib-sh2a [new file with mode: 0644]
gcc/config/sh/t-mlib-sh2a-nofpu [new file with mode: 0644]
gcc/config/sh/t-mlib-sh2a-single [new file with mode: 0644]
gcc/config/sh/t-mlib-sh2a-single-only [new file with mode: 0644]
gcc/config/sh/t-sh

index f051f395a27c7c8c324f6c998de3169376a44675..12ae194fe3ad3668120938316b03207b86e7452a 100644 (file)
@@ -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,
index 1360b072a487c6fa47a98003f1023987a4f32d5d..dadc454cd271db56b2a29769ebfa3377bb640388 100644 (file)
@@ -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
index af7d8ae3b95c31734942a030787b7f5571857707..f2c4e0d7bebc7843f5fd0979d03158171b561d2b 100644 (file)
@@ -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  
index 04c0c987fc33b87bc707cbb7181c1c75fb43c621..d632bf7de2020d9a9e155f449cb3828a2fcd2954 100644 (file)
@@ -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
 
index 239438fd06b37711fadfd5619c41bca2974e3a79..1dc354994b3a29c886e3b25c02e7072896f38d8e 100644 (file)
@@ -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
index 010e5dcadc3498b89d44cc5faf92034463a78e36..b2c01302778129d25e8edf29bf41a93c6ef3ff23 100644 (file)
@@ -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);
 }
 
index 71546facf9d95a17344165822589edb9cc8dde14..276bd1e11012077d546104a387f031a89e73e37e 100644 (file)
@@ -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)
index 77ba4d59d74982cce6a1fdf47b95ef1a1fbd5b97..e825fae614b8b3e4eb92160f25a000e84c08a967 100644 (file)
 ;; 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"
   ""
   [(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
       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],
   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)))
       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]);
   "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")
 ;;
 ;; 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.
 
 ; 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")
 
 ;; 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")
         "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))"
   "@
 ;; 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
        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"))
   [(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))
        (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))"
   "@
      [(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
        (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)]
   "
        (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"
        (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))])]
        (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)]
        (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)]
   "
        (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)]
   "
        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;
        ! 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")))])
                    (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 (file)
index 0000000..e276ac9
--- /dev/null
@@ -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 (file)
index 0000000..a84874e
--- /dev/null
@@ -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 (file)
index 0000000..b3432fa
--- /dev/null
@@ -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 (file)
index 0000000..e34afe2
--- /dev/null
@@ -0,0 +1 @@
+ML_sh2a_single_only=m2a-single-only/
index 97dd99bf10131420a07a89f268f7b56441d3841b..3660d06aacfaeec3dcf5fcc041101bc19d6b8ddb 100644 (file)
@@ -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: