From 3a6994f86619b19fba631186acd6eede9d8c229e Mon Sep 17 00:00:00 2001 From: amylaar Date: Mon, 27 Mar 2006 14:11:14 +0000 Subject: [PATCH] 2006-03-27 Andrew Stubbs J"orn Rennecke * superh.opt: New file. * sh.c (boardtype, osruntime): Remove. * superh.h (SUBTARGET_OPTIONS): Remove. * config.gcc (sh*-superh-elf): Add sh/superh.opt to extra_options. * config.gcc (sh*-*-*): Don't use c-c ranges for tr. Quote sed arguments with ^ and/or []. * config.gcc (sh-*-*): Add quoting to account for quirk of Solaris /bin/sh. Replace == with = in enable_incomplete_targets test. * config/sh/superh.h (SUBTARGET_LINK_SPEC): Replace LITTLE_ENDIAN_BIT with MASK_LITTLE_ENDIAN. * config.gcc (sh*-superh-elf): Add sh/superh.h to tm_file. * config/sh/sh.opt: Added to some comments. * config/sh/superh.h: Removed some chaff. * config/sh/sh.opt: Add m4-[1234]00* options. * config/sh/sh.c (sh_handle_option): Likewise. * config/sh/t-sh (IC_EXTRA_PARTS, EXTRA_MULTILIB_PARTS): Define. (ic_invalidate_array_4-100.o): New rule. ($(T)libic_invalidate_array_4-100.a): Likewise. (ic_invalidate_array_4-200.o): Likewise. ($(T)libic_invalidate_array_4-200.a): Likewise. (ic_invalidate_array_4a.o): Likewise. ($(T)libic_invalidate_array_4a.a): Likewise. * config/sh/t-elf (EXTRA_MULTILIB_PARTS): Add IC_EXTRA_PARTS. * config/sh/embed-elf.h (LIBGCC_SPEC): Add clauses for m4-100*, m4-200*, and m4a*. * config/sh/crt1.asm: Merged in profiling code. * config/sh/superh.h (STARTFILE_SPEC): Override. * config/sh/t-superh: Override EXTRA_MULTILIB_PARTS. Add rules for $(T)crt1-mmu.o, $(T)gcrt1-mmu.o and $(T)gcrt1.o. * config.gcc (sh*-superh-elf): Add t-superh to tmake_file. * t-sh (MULTILIB_MATCHES): Add sh4-[1245]00* variants. * config/sh/t-superh: Removed now-redundant MULTILIB_OPTIONS / MULTILIB_DIRNAMES / MULTILIB_MATCHES settings. * sh.opt (mpretend-cmove): New option. * sh.h (OPERRIDE_OPTIONS): Switch it off if not TARGET_SH1. * sh.md (movsicc_t_false, movsicc_t_tru): New patterns. (movsicc): Add TARGET_PRETEND_CMOVE code. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@112421 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 49 +++++++++ gcc/config.gcc | 13 +-- gcc/config/sh/crt1.asm | 258 +++++++++++++++++++++++++++++++++++++------- gcc/config/sh/embed-elf.h | 5 + gcc/config/sh/lib1funcs.asm | 3 +- gcc/config/sh/sh.c | 15 +-- gcc/config/sh/sh.h | 2 + gcc/config/sh/sh.md | 61 ++++++++++- gcc/config/sh/sh.opt | 40 +++++++ gcc/config/sh/superh.h | 69 +++--------- gcc/config/sh/superh.opt | 10 ++ gcc/config/sh/t-elf | 2 +- gcc/config/sh/t-sh | 27 ++++- gcc/config/sh/t-superh | 21 ++-- 14 files changed, 450 insertions(+), 125 deletions(-) create mode 100644 gcc/config/sh/superh.opt rewrite gcc/config/sh/t-superh (100%) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 45cac9db874..7e1dea7a952 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,52 @@ +2006-03-27 Andrew Stubbs + J"orn Rennecke + + * superh.opt: New file. + * sh.c (boardtype, osruntime): Remove. + * superh.h (SUBTARGET_OPTIONS): Remove. + * config.gcc (sh*-superh-elf): Add sh/superh.opt to extra_options. + + * config.gcc (sh*-*-*): Don't use c-c ranges for tr. Quote sed + arguments with ^ and/or []. + + * config.gcc (sh-*-*): Add quoting to account for quirk of + Solaris /bin/sh. + Replace == with = in enable_incomplete_targets test. + + * config/sh/superh.h (SUBTARGET_LINK_SPEC): Replace LITTLE_ENDIAN_BIT + with MASK_LITTLE_ENDIAN. + + * config.gcc (sh*-superh-elf): Add sh/superh.h to tm_file. + * config/sh/sh.opt: Added to some comments. + * config/sh/superh.h: Removed some chaff. + + * config/sh/sh.opt: Add m4-[1234]00* options. + * config/sh/sh.c (sh_handle_option): Likewise. + * config/sh/t-sh (IC_EXTRA_PARTS, EXTRA_MULTILIB_PARTS): Define. + (ic_invalidate_array_4-100.o): New rule. + ($(T)libic_invalidate_array_4-100.a): Likewise. + (ic_invalidate_array_4-200.o): Likewise. + ($(T)libic_invalidate_array_4-200.a): Likewise. + (ic_invalidate_array_4a.o): Likewise. + ($(T)libic_invalidate_array_4a.a): Likewise. + * config/sh/t-elf (EXTRA_MULTILIB_PARTS): Add IC_EXTRA_PARTS. + * config/sh/embed-elf.h (LIBGCC_SPEC): Add clauses for m4-100*, + m4-200*, and m4a*. + * config/sh/crt1.asm: Merged in profiling code. + * config/sh/superh.h (STARTFILE_SPEC): Override. + * config/sh/t-superh: Override EXTRA_MULTILIB_PARTS. + Add rules for $(T)crt1-mmu.o, $(T)gcrt1-mmu.o and $(T)gcrt1.o. + * config.gcc (sh*-superh-elf): Add t-superh to tmake_file. + + * t-sh (MULTILIB_MATCHES): Add sh4-[1245]00* variants. + * config/sh/t-superh: Removed now-redundant MULTILIB_OPTIONS / + MULTILIB_DIRNAMES / MULTILIB_MATCHES settings. + + * sh.opt (mpretend-cmove): New option. + * sh.h (OPERRIDE_OPTIONS): Switch it off if not TARGET_SH1. + * sh.md (movsicc_t_false, movsicc_t_tru): New patterns. + (movsicc): Add TARGET_PRETEND_CMOVE code. + 2006-03-27 Andreas Krebbel * config/s390/s390-protos.h (s390_hard_regno_mode_ok, diff --git a/gcc/config.gcc b/gcc/config.gcc index 92dce31765e..96a547e1f13 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -1949,7 +1949,8 @@ sh-*-symbianelf* | sh[12346l]*-*-symbianelf* | \ with_libgloss=yes tm_file="${tm_file} sh/newlib.h" fi - tm_file="${tm_file} sh/embed-elf.h" ;; + tm_file="${tm_file} sh/embed-elf.h" + extra_options="${extra_options} sh/superh.opt" ;; *) if test x$with_newlib = xyes \ && test x$with_libgloss = xyes; then tm_file="${tm_file} sh/newlib.h" @@ -2048,9 +2049,9 @@ sh-*-symbianelf* | sh[12346l]*-*-symbianelf* | \ sh_multilibs="`echo $sh_multilibs|sed -e s/m4/sh4-nofpu/ -e s/,m4-[^,]*//g -e s/,m[23]e// -e s/m2a,m2a-single/m2a-nofpu/ -e s/m5-..m....,//g`" fi fi - target_cpu_default=SELECT_`echo ${sh_cpu_default}|tr a-z- A-Z_` + target_cpu_default=SELECT_`echo ${sh_cpu_default}|tr abcdefghijklmnopqrstuvwxyz- ABCDEFGHIJKLMNOPQRSTUVWXYZ_` tm_defines=${tm_defines}' SH_MULTILIB_CPU_DEFAULT=\"'`echo $sh_cpu_default|sed s/sh/m/`'\"' - sh_multilibs=`echo $sh_multilibs,$sh_cpu_default | sed -e 's/[ ,/][ ,]*/ /g' -e 's/ $//' -e s/^m/sh/ -e 's/ m/ sh/g' | tr A-Z_ a-z-` + sh_multilibs=`echo $sh_multilibs,$sh_cpu_default | sed -e 's/[ ,/][ ,]*/ /g' -e 's/ $//' -e 's/^m/sh/' -e 's/ m/ sh/g' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ_ abcdefghijklmnopqrstuvwxyz-` for sh_multilib in ${sh_multilibs}; do case ${sh_multilib} in sh1 | sh2 | sh2e | sh3 | sh3e | \ @@ -2061,7 +2062,7 @@ sh-*-symbianelf* | sh[12346l]*-*-symbianelf* | \ sh5-32media | sh5-32media-nofpu | \ sh5-compact | sh5-compact-nofpu) tmake_file="${tmake_file} sh/t-mlib-${sh_multilib}" - tm_defines="$tm_defines SUPPORT_`echo $sh_multilib|tr a-z- A-Z_`=1" + tm_defines="$tm_defines SUPPORT_`echo $sh_multilib|tr abcdefghijklmnopqrstuvwxyz- ABCDEFGHIJKLMNOPQRSTUVWXYZ_`=1" ;; *) echo "with_multilib_list=${sh_multilib} not supported." @@ -2069,7 +2070,7 @@ sh-*-symbianelf* | sh[12346l]*-*-symbianelf* | \ ;; esac done - if test x${enable_incomplete_targets} == xyes ; then + if test x${enable_incomplete_targets} = xyes ; then tm_defines="$tm_defines SUPPORT_SH1=1 SUPPORT_SH2E=1 SUPPORT_SH4=1 SUPPORT_SH4_SINGLE=1 SUPPORT_SH2A=1 SUPPORT_SH2A_SINGLE=1 SUPPORT_SH5_32MEDIA=1 SUPPORT_SH5_32MEDIA_NOFPU=1 SUPPORT_SH5_64MEDIA=1 SUPPORT_SH5_64MEDIA_NOFPU=1" fi use_fixproto=yes @@ -2855,7 +2856,7 @@ case "${target}" in sh[123456ble]-*-* | sh-*-*) supported_defaults="cpu" - case "`echo $with_cpu | tr A-Z_ a-z- | sed s/sh/m/`" in + case "`echo $with_cpu | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ_ abcdefghijklmnopqrstuvwxyz- | sed s/sh/m/`" in "" | m1 | m2 | m2e | m3 | m3e | m4 | m4-single | m4-single-only | m4-nofpu ) # OK ;; diff --git a/gcc/config/sh/crt1.asm b/gcc/config/sh/crt1.asm index bd309bb82e3..c110fa07427 100644 --- a/gcc/config/sh/crt1.asm +++ b/gcc/config/sh/crt1.asm @@ -688,6 +688,11 @@ __superh_trap_handler: .section .bss old_vbr: .long 0 +#ifdef PROFILE +profiling_enabled: + .long 0 +#endif + .section .text .global start @@ -764,6 +769,30 @@ set_sr: jsr @r0 nop +#ifdef PROFILE + ! arrange for exit to call _mcleanup (via stop_profiling) + mova stop_profiling,r0 + mov.l atexit_k,r1 + jsr @r1 + mov r0, r4 + + ! Call profiler startup code + mov.l monstartup_k, r0 + mov.l start_k, r4 + mov.l etext_k, r5 + jsr @r0 + nop + + ! enable profiling trap + ! until now any trap 33s will have been ignored + ! This means that all library functions called before this point + ! (directly or indirectly) may have the profiling trap at the start. + ! Therefore, only mcount itself may not have the extra header. + mov.l profiling_enabled_k2, r0 + mov #1, r1 + mov.l r1, @r0 +#endif /* PROFILE */ + ! call init mov.l init_k,r0 jsr @r0 @@ -780,6 +809,32 @@ set_sr: jsr @r0 nop + .balign 4 +#ifdef PROFILE +stop_profiling: + # stop mcount counting + mov.l profiling_enabled_k2, r0 + mov #0, r1 + mov.l r1, @r0 + + # call mcleanup + mov.l mcleanup_k, r0 + jmp @r0 + nop + + .balign 4 +mcleanup_k: + .long __mcleanup +monstartup_k: + .long ___monstartup +profiling_enabled_k2: + .long profiling_enabled +start_k: + .long _start +etext_k: + .long __etext +#endif /* PROFILE */ + .align 2 #if defined (__SH_FPU_ANY__) set_fpscr_k: @@ -818,10 +873,18 @@ sr_initial_rtos: rtos_start_fn: .long ___rtos_profiler_start_timer +#ifdef PROFILE +sr_initial_bare: + ! Privileged mode RB 1 BL 0. Keep BL 0 to allow default trap handlers to work. + ! For bare machine, we need to enable interrupts to get profiling working + .long 0x60000001 +#else + sr_initial_bare: ! Privileged mode RB 1 BL 0. Keep BL 0 to allow default trap handlers to work. ! Keep interrupts disabled - the application will enable as required. .long 0x600000f1 +#endif ! supplied for backward compatibility only, in case of linking ! code whose main() was compiled with an older version of GCC. @@ -849,6 +912,92 @@ vbr_start: .balign 256 vbr_100: + #ifdef PROFILE + ! Note on register usage. + ! we use r0..r3 as scratch in this code. If we are here due to a trapa for profiling + ! then this is OK as we are just before executing any function code. + ! The other r4..r7 we save explicityl on the stack + ! Remaining registers are saved by normal ABI conventions and we assert we do not + ! use floating point registers. + mov.l expevt_k1, r1 + mov.l @r1, r1 + mov.l event_mask, r0 + and r0,r1 + mov.l trapcode_k, r2 + cmp/eq r1,r2 + bt 1f + bra handler_100 ! if not a trapa, go to default handler + nop +1: + mov.l trapa_k, r0 + mov.l @r0, r0 + shlr2 r0 ! trapa code is shifted by 2. + cmp/eq #33, r0 + bt 2f + bra handler_100 + nop +2: + + ! If here then it looks like we have trap #33 + ! Now we need to call mcount with the following convention + ! Save and restore r4..r7 + mov.l r4,@-r15 + mov.l r5,@-r15 + mov.l r6,@-r15 + mov.l r7,@-r15 + sts.l pr,@-r15 + + ! r4 is frompc. + ! r5 is selfpc + ! r0 is the branch back address. + ! The code sequence emitted by gcc for the profiling trap is + ! .align 2 + ! trapa #33 + ! .align 2 + ! .long lab Where lab is planted by the compiler. This is the address + ! of a datum that needs to be incremented. + sts pr, r4 ! frompc + stc spc, r5 ! selfpc + mov #2, r2 + not r2, r2 ! pattern to align to 4 + and r2, r5 ! r5 now has aligned address +! add #4, r5 ! r5 now has address of address + mov r5, r2 ! Remember it. +! mov.l @r5, r5 ! r5 has value of lable (lab in above example) + add #8, r2 + ldc r2, spc ! our return address avoiding address word + + ! only call mcount if profiling is enabled + mov.l profiling_enabled_k, r0 + mov.l @r0, r0 + cmp/eq #0, r0 + bt 3f + ! call mcount + mov.l mcount_k, r2 + jsr @r2 + nop +3: + lds.l @r15+,pr + mov.l @r15+,r7 + mov.l @r15+,r6 + mov.l @r15+,r5 + mov.l @r15+,r4 + rte + nop + .balign 4 +event_mask: + .long 0xfff +trapcode_k: + .long 0x160 +expevt_k1: + .long 0xff000024 ! Address of expevt +trapa_k: + .long 0xff000020 +mcount_k: + .long __call_mcount +profiling_enabled_k: + .long profiling_enabled +#endif ! Non profiling case. handler_100: mov.l 2f, r0 ! load the old vbr setting (if any) @@ -899,13 +1048,12 @@ vbr_300: bra handler nop 1: ! there was a previous handler - chain them - add #0x7f, r0 ! 0x7f - add #0x7f, r0 ! 0xfe - add #0x7f, r0 ! 0x17d - add #0x7f, r0 ! 0x1fc - add #0x7f, r0 ! 0x27b - add #0x7f, r0 ! 0x2fa - add #0x6, r0 ! add 0x300 without corrupting another register + rotcr r0 + rotcr r0 + add #0x7f, r0 ! 0x1fc + add #0x41, r0 ! 0x300 + rotcl r0 + rotcl r0 ! Add 0x300 without corrupting another register jmp @r0 nop .balign 4 @@ -920,15 +1068,13 @@ vbr_400: ! Should be at vbr+0x400 ! no previous vbr - jump to own generic handler bt handler ! there was a previous handler - chain them - add #0x7f, r0 ! 0x7f - add #0x7f, r0 ! 0xfe - add #0x7f, r0 ! 0x17d - add #0x7f, r0 ! 0x1fc - add #0x7f, r0 ! 0x27b - add #0x7f, r0 ! 0x2fa - add #0x7f, r0 ! 0x379 - add #0x7f, r0 ! 0x3f8 - add #0x8, r0 ! add 0x400 without corrupting another register + rotcr r0 + rotcr r0 + add #0x7f, r0 ! 0x1fc + add #0x7f, r0 ! 0x3f8 + add #0x02, r0 ! 0x400 + rotcl r0 + rotcl r0 ! Add 0x400 without corrupting another register jmp @r0 nop .balign 4 @@ -965,17 +1111,13 @@ vbr_500: ! no previous vbr - jump to own generic handler bt handler ! there was a previous handler - chain them - add #0x7f, r0 ! 0x7f - add #0x7f, r0 ! 0xfe - add #0x7f, r0 ! 0x17d - add #0x7f, r0 ! 0x1fc - add #0x7f, r0 ! 0x27b - add #0x7f, r0 ! 0x2fa - add #0x7f, r0 ! 0x379 - add #0x7f, r0 ! 0x3f8 - add #0x7f, r0 ! 0x477 - add #0x7f, r0 ! 0x4f6 - add #0xa, r0 ! add 0x500 without corrupting another register + rotcr r0 + rotcr r0 + add #0x7f, r0 ! 0x1fc + add #0x7f, r0 ! 0x3f8 + add #0x42, r0 ! 0x500 + rotcl r0 + rotcl r0 ! Add 0x500 without corrupting another register jmp @r0 nop .balign 4 @@ -984,30 +1126,58 @@ vbr_500: .balign 256 vbr_600: - mov.l 2f, r0 ! load the old vbr setting (if any) +#ifdef PROFILE + ! Should be at vbr+0x600 + ! Now we are in the land of interrupts so need to save more state. + ! Save register state + mov.l interrupt_stack_k, r15 ! r15 has been saved to sgr. + mov.l r0,@-r15 + mov.l r1,@-r15 + mov.l r2,@-r15 + mov.l r3,@-r15 + mov.l r4,@-r15 + mov.l r5,@-r15 + mov.l r6,@-r15 + mov.l r7,@-r15 + sts.l pr,@-r15 + ! Pass interrupted pc to timer_handler as first parameter (r4). + stc spc, r4 + mov.l timer_handler_k, r0 + jsr @r0 + nop + lds.l @r15+,pr + mov.l @r15+,r7 + mov.l @r15+,r6 + mov.l @r15+,r5 + mov.l @r15+,r4 + mov.l @r15+,r3 + mov.l @r15+,r2 + mov.l @r15+,r1 + mov.l @r15+,r0 + stc sgr, r15 ! Restore r15, destroyed by this sequence. + rte + nop +#else + mov.l 2f, r0 ! Load the old vbr setting (if any). mov.l @r0, r0 cmp/eq #0, r0 ! no previous vbr - jump to own handler bt chandler ! there was a previous handler - chain them - add #0x7f, r0 ! 0x7f - add #0x7f, r0 ! 0xfe - add #0x7f, r0 ! 0x17d - add #0x7f, r0 ! 0x1fc - add #0x7f, r0 ! 0x27b - add #0x7f, r0 ! 0x2fa - add #0x7f, r0 ! 0x379 - add #0x7f, r0 ! 0x3f8 - add #0x7f, r0 ! 0x477 - add #0x7f, r0 ! 0x4f6 - add #0x7f, r0 ! 0x575 - add #0x7f, r0 ! 0x5f4 - add #0xc, r0 ! add 0x600 without corrupting another register + rotcr r0 + rotcr r0 + add #0x7f, r0 ! 0x1fc + add #0x7f, r0 ! 0x3f8 + add #0x7f, r0 ! 0x5f4 + add #0x03, r0 ! 0x600 + rotcl r0 + rotcl r0 ! Add 0x600 without corrupting another register jmp @r0 nop .balign 4 2: .long old_vbr +#endif /* PROFILE code */ chandler: mov.l expevt_k, r4 mov.l @r4, r4 ! r4 is value of expevt hence making this the return code @@ -1020,6 +1190,12 @@ limbo: bra limbo nop .balign 4 +#ifdef PROFILE +interrupt_stack_k: + .long __timer_stack ! The high end of the stack +timer_handler_k: + .long __profil_counter +#endif expevt_k: .long 0xff000024 ! Address of expevt chandler_k: diff --git a/gcc/config/sh/embed-elf.h b/gcc/config/sh/embed-elf.h index 2542c4c16bc..f8c0713ee65 100644 --- a/gcc/config/sh/embed-elf.h +++ b/gcc/config/sh/embed-elf.h @@ -24,3 +24,8 @@ Boston, MA 02110-1301, USA. */ #define USER_LABEL_PREFIX "_" #undef TARGET_POSIX_IO + +#define LIBGCC_SPEC "%{!shared: \ + %{m4-100*:-lic_invalidate_array_4-100} \ + %{m4-200*:-lic_invalidate_array_4-200} \ + %{m4a*:-lic_invalidate_array_4a}} -lgcc" diff --git a/gcc/config/sh/lib1funcs.asm b/gcc/config/sh/lib1funcs.asm index 7dfe73ed783..07292812abc 100644 --- a/gcc/config/sh/lib1funcs.asm +++ b/gcc/config/sh/lib1funcs.asm @@ -2141,7 +2141,8 @@ GLOBAL(ic_invalidate): #endif /* L_ic_invalidate */ #ifdef L_ic_invalidate_array -#if defined(__SH4A__) +#if defined(__SH4A__) || (defined (__FORCE_SH4A__) && (defined(__SH4_SINGLE__) || defined(__SH4__) || defined(__SH4_SINGLE_ONLY__) || (defined(__SH4_NOFPU__) && !defined(__SH5__)))) + .global GLOBAL(ic_invalidate_array) /* This is needed when an SH4 dso with trampolines is used on SH4A. */ .global GLOBAL(ic_invalidate_array) FUNC(GLOBAL(ic_invalidate_array)) diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index b4a4dd1956a..9f8415c9535 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -524,18 +524,26 @@ sh_handle_option (size_t code, const char *arg ATTRIBUTE_UNUSED, return true; case OPT_m4: + case OPT_m4_100: + case OPT_m4_200: target_flags = (target_flags & ~MASK_ARCH) | SELECT_SH4; return true; case OPT_m4_nofpu: + case OPT_m4_400: + case OPT_m4_500: target_flags = (target_flags & ~MASK_ARCH) | SELECT_SH4_NOFPU; return true; case OPT_m4_single: + case OPT_m4_100_single: + case OPT_m4_200_single: target_flags = (target_flags & ~MASK_ARCH) | SELECT_SH4_SINGLE; return true; case OPT_m4_single_only: + case OPT_m4_100_single_only: + case OPT_m4_200_single_only: target_flags = (target_flags & ~MASK_ARCH) | SELECT_SH4_SINGLE_ONLY; return true; @@ -10901,11 +10909,4 @@ sh_secondary_reload (bool in_p, rtx x, enum reg_class class, enum sh_divide_strategy_e sh_div_strategy = SH_DIV_STRATEGY_DEFAULT; -/* This defines the storage for the variable part of a -mboard= option. - It is only required when using the sh-superh-elf target */ -#ifdef _SUPERH_H -const char * boardtype = "7750p2"; -const char * osruntime = "bare"; -#endif - #include "gt-sh.h" diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h index 1b7ff5dbe2c..6e833ccedb7 100644 --- a/gcc/config/sh/sh.h +++ b/gcc/config/sh/sh.h @@ -654,6 +654,8 @@ do { \ else \ sh_div_strategy = SH_DIV_CALL_DIV1; \ } \ + if (!TARGET_SH1) \ + TARGET_PRETEND_CMOVE = 0; \ if (sh_divsi3_libfunc[0]) \ ; /* User supplied - leave it alone. */ \ else if (TARGET_DIVIDE_CALL_FP) \ diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md index 1c1357e0309..00d1de30046 100644 --- a/gcc/config/sh/sh.md +++ b/gcc/config/sh/sh.md @@ -1180,19 +1180,72 @@ DONE; }") +(define_insn "*movsicc_t_false" + [(set (match_operand:SI 0 "arith_reg_dest" "=r,r") + (if_then_else (eq (reg:SI T_REG) (const_int 0)) + (match_operand:SI 1 "general_movsrc_operand" "r,I08") + (match_operand:SI 2 "arith_reg_operand" "0,0")))] + "TARGET_PRETEND_CMOVE + && (arith_reg_operand (operands[1], SImode) + || (immediate_operand (operands[1], SImode) + && CONST_OK_FOR_I08 (INTVAL (operands[1]))))" + "bt 0f\;mov %1,%0\\n0:" + [(set_attr "type" "mt_group,arith") ;; poor approximation + (set_attr "length" "4")]) + +(define_insn "*movsicc_t_true" + [(set (match_operand:SI 0 "arith_reg_dest" "=r,r") + (if_then_else (ne (reg:SI T_REG) (const_int 0)) + (match_operand:SI 1 "general_movsrc_operand" "r,I08") + (match_operand:SI 2 "arith_reg_operand" "0,0")))] + "TARGET_PRETEND_CMOVE + && (arith_reg_operand (operands[1], SImode) + || (immediate_operand (operands[1], SImode) + && CONST_OK_FOR_I08 (INTVAL (operands[1]))))" + "bf 0f\;mov %1,%0\\n0:" + [(set_attr "type" "mt_group,arith") ;; poor approximation + (set_attr "length" "4")]) + (define_expand "movsicc" - [(set (match_operand:SI 0 "register_operand" "") + [(set (match_operand:SI 0 "arith_reg_dest" "") (if_then_else:SI (match_operand 1 "comparison_operator" "") - (match_operand:SI 2 "register_operand" "") - (match_operand:SI 3 "register_operand" "")))] - "TARGET_SHMEDIA" + (match_operand:SI 2 "arith_reg_or_0_operand" "") + (match_operand:SI 3 "arith_reg_operand" "")))] + "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE" " { if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE) && GET_MODE (sh_compare_op0) == SImode + && (TARGET_SHMEDIA + || (REG_P (sh_compare_op0) && REGNO (sh_compare_op0) == T_REG)) && sh_compare_op1 == const0_rtx) operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode, sh_compare_op0, sh_compare_op1); + else if (TARGET_PRETEND_CMOVE) + { + enum rtx_code code = GET_CODE (operands[1]); + enum rtx_code new_code = code; + rtx tmp; + + if (! currently_expanding_to_rtl) + FAIL; + switch (code) + { + case LT: case LE: case LEU: case LTU: + if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) != MODE_INT) + break; + case NE: + new_code = reverse_condition (code); + break; + case EQ: case GT: case GE: case GEU: case GTU: + break; + default: + FAIL; + } + tmp = prepare_scc_operands (new_code); + operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode, + tmp, const0_rtx); + } else { rtx tmp; diff --git a/gcc/config/sh/sh.opt b/gcc/config/sh/sh.opt index 9b072fef7cb..7f9a87e95d9 100644 --- a/gcc/config/sh/sh.opt +++ b/gcc/config/sh/sh.opt @@ -80,18 +80,52 @@ m4 Target RejectNegative Mask(SH4) Condition(SUPPORT_SH4) Generate SH4 code +m4-100 +Target RejectNegative Condition(SUPPORT_SH4) +Generate SH4-100 code + +m4-200 +Target RejectNegative Condition(SUPPORT_SH4) +Generate SH4-200 code + m4-nofpu Target RejectNegative Condition(SUPPORT_SH4_NOFPU) Generate SH4 FPU-less code +m4-400 +Target RejectNegative Condition(SUPPORT_SH4_NOFPU) +Generate code for SH4 400 series (MMU/FPU-less) +;; passes -isa=sh4-nommu-nofpu to the assembler. + +m4-500 +Target RejectNegative Condition(SUPPORT_SH4_NOFPU) +Generate code for SH4 500 series (FPU-less). +;; passes -isa=sh4-nofpu to the assembler. + m4-single Target RejectNegative Condition(SUPPORT_SH4_SINGLE) Generate default single-precision SH4 code +m4-100-single +Target RejectNegative Condition(SUPPORT_SH4_SINGLE) +Generate default single-precision SH4-100 code + +m4-200-single +Target RejectNegative Condition(SUPPORT_SH4_SINGLE) +Generate default single-precision SH4-200 code + m4-single-only Target RejectNegative Condition(SUPPORT_SH4_SINGLE_ONLY) Generate only single-precision SH4 code +m4-100-single-only +Target RejectNegative Condition(SUPPORT_SH4_SINGLE_ONLY) +Generate only single-precision SH4-100 code + +m4-200-single-only +Target RejectNegative Condition(SUPPORT_SH4_SINGLE_ONLY) +Generate only single-precision SH4-200 code + m4a Target RejectNegative Mask(SH4A) Condition(SUPPORT_SH4A) Generate SH4a code @@ -232,3 +266,9 @@ Cost to assume for a multiply insn musermode Target Report RejectNegative Mask(USERMODE) Generate library function call to invalidate instruction cache entries after fixing trampoline + +;; We might want to enable this by default for TARGET_HARD_SH4, because +;; zero-offset branches have zero latency. Needs some benchmarking. +mpretend-cmove +Target Var(TARGET_PRETEND_CMOVE) +Pretend a branch-around-a-move is a conditional move. diff --git a/gcc/config/sh/superh.h b/gcc/config/sh/superh.h index f4807d809ff..7ac96ef7734 100644 --- a/gcc/config/sh/superh.h +++ b/gcc/config/sh/superh.h @@ -1,5 +1,5 @@ /* Definitions of target machine for gcc for Super-H using sh-superh-elf. - Copyright (C) 2001 Free Software Foundation, Inc. + Copyright (C) 2001, 2006 Free Software Foundation, Inc. This file is part of GNU CC. @@ -20,9 +20,9 @@ Boston, MA 02110-1301, USA. */ /* This header file is used when the vendor name is set to 'superh'. - It configures the compiler for SH4 only and switches the default - endianess to little (although big endian is still available). - It also configures the spec file to the default board configuration + config.gcc already configured the compiler for SH4 only and switched + the default endianess to little (although big endian is still available). + This file configures the spec file to the default board configuration but in such a way that it can be overridden by a boardspecs file (using the -specs= option). This file is expected to disable the defaults and provide options --defsym _start and --defsym _stack @@ -39,57 +39,6 @@ Boston, MA 02110-1301, USA. */ #undef TARGET_VERSION #define TARGET_VERSION fprintf (stderr, " (SuperH SH special %s)", __DATE__); - -/* We override TARGET_PROCESSOR_SWITCHES in order to remove all the unrequired cpu options - and add options for all the SuperH CPU variants: - -m4-100 is an alias for -m4. - -m4-200 is an alias for -m4. - -m4-400 is an alias for -m4-nofpu and passes -isa=sh4-nommu-nofpu to the assembler. - -m4-500 is an alias for -m4-nofpu and passes -isa=sh4-nofpu to the assembler. */ -#undef TARGET_PROCESSOR_SWITCHES -#define TARGET_PROCESSOR_SWITCHES \ - {"4-500", TARGET_NONE, "SH4 500 series (FPU-less)" }, \ - {"4-500", SELECT_SH4_NOFPU, "" }, \ - {"4-400", TARGET_NONE, "SH4 400 series (MMU/FPU-less)" }, \ - {"4-400", SELECT_SH4_NOFPU, "" }, \ - {"4-200-single-only", TARGET_NONE, "SH4 200 series with double = float (SH3e ABI)" }, \ - {"4-200-single-only", SELECT_SH4_SINGLE_ONLY, "" }, \ - {"4-200-single", TARGET_NONE, "SH4 200 series with single precision pervading" }, \ - {"4-200-single", SELECT_SH4_SINGLE, "" }, \ - {"4-200-nofpu", TARGET_NONE, "SH4 200 series using soft floating point" }, \ - {"4-200-nofpu", SELECT_SH4_NOFPU, "" }, \ - {"4-200", TARGET_NONE, "SH4 200 series" }, \ - {"4-200", SELECT_SH4_NOFPU, "" }, \ - {"4-100-single-only", TARGET_NONE, "SH4 100 series with double = float (SH3e ABI)" }, \ - {"4-100-single-only", SELECT_SH4_SINGLE_ONLY, "" }, \ - {"4-100-single", TARGET_NONE, "SH4 100 series with single precision pervading" }, \ - {"4-100-single", SELECT_SH4_SINGLE, "" }, \ - {"4-100-nofpu", TARGET_NONE, "SH4 100 series using soft floating point" }, \ - {"4-100-nofpu", SELECT_SH4_NOFPU, "" }, \ - {"4-100", TARGET_NONE, "SH4 100 series" }, \ - {"4-100", SELECT_SH4_NOFPU, "" }, \ - {"4-single-only", TARGET_NONE, "Generic SH4 with double = float (SH3e ABI)" }, \ - {"4-single-only", SELECT_SH4_SINGLE_ONLY, "" }, \ - {"4-single", TARGET_NONE, "Generic SH4 with single precision pervading" }, \ - {"4-single", SELECT_SH4_SINGLE, "" }, \ - {"4-nofpu", TARGET_NONE, "Generic SH4 using soft floating point" }, \ - {"4-nofpu", SELECT_SH4_NOFPU, "" }, \ - {"4", TARGET_NONE, "Generic SH4 (default)" }, \ - {"4", SELECT_SH4, "" } - - -/* Provide the -mboard= option used by the boardspecs file */ -#undef SUBTARGET_OPTIONS -#define SUBTARGET_OPTIONS \ - { "board=", &boardtype, "Board name [and momory region].", 0 }, \ - { "runtime=", &osruntime, "Runtime name.", 0 }, \ - -/* These are required by the mboard= option and runtime= option - and are defined in sh.c but are not used anywhere */ -extern const char * boardtype; -extern const char * osruntime; - - /* Override the linker spec strings to use the new emulation The specstrings are concatenated as follows LINK_EMUL_PREFIX.(''|'32'|'64'|LINK_DEFAULT_CPU_EMUL).SUBTARGET_LINK_EMUL_SUFFIX @@ -103,7 +52,7 @@ extern const char * osruntime; /* Add the SUBTARGET_LINK_SPEC to add the board and runtime support and change the endianness */ #undef SUBTARGET_LINK_SPEC -#if TARGET_ENDIAN_DEFAULT == LITTLE_ENDIAN_BIT +#if TARGET_ENDIAN_DEFAULT == MASK_LITTLE_ENDIAN #define SUBTARGET_LINK_SPEC "%(board_link) %(ldruntime) %{ml|!mb:-EL}%{mb:-EB}" #else #define SUBTARGET_LINK_SPEC "%(board_link) %(ldruntime) %{ml:-EL}%{mb|!ml:-EB}" @@ -149,3 +98,11 @@ extern const char * osruntime; /* Override the LIB_SPEC to add the runtime support */ #undef LIB_SPEC #define LIB_SPEC "%{!shared:%{!symbolic:%(libruntime) -lc}} %{pg:-lprofile -lc}" + +/* Override STARTFILE_SPEC to add profiling and MMU support. */ +#undef STARTFILE_SPEC +#define STARTFILE_SPEC \ + "%{!shared: %{!m4-400*: %{pg:gcrt1-mmu.o%s}%{!pg:crt1-mmu.o%s}}} \ + %{!shared: %{m4-400*: %{pg:gcrt1.o%s}%{!pg:crt1.o%s}}} \ + crti.o%s \ + %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}" diff --git a/gcc/config/sh/superh.opt b/gcc/config/sh/superh.opt new file mode 100644 index 00000000000..b85abddaf8e --- /dev/null +++ b/gcc/config/sh/superh.opt @@ -0,0 +1,10 @@ +;; The -mboard and -mruntime options need only be accepted here, they are +;; actually processed by supplementary specs files. + +mboard= +Target RejectNegative Joined +Board name [and memory region]. + +mruntime= +Target RejectNegative Joined +Runtime name. diff --git a/gcc/config/sh/t-elf b/gcc/config/sh/t-elf index feccbb3490b..9d9454a7221 100644 --- a/gcc/config/sh/t-elf +++ b/gcc/config/sh/t-elf @@ -1,5 +1,5 @@ EXTRA_MULTILIB_PARTS= crt1.o crti.o crtn.o \ - crtbegin.o crtend.o crtbeginS.o crtendS.o + crtbegin.o crtend.o crtbeginS.o crtendS.o $(IC_EXTRA_PARTS) # Compile crtbeginS.o and crtendS.o with pic. CRTSTUFF_T_CFLAGS_S = -fPIC diff --git a/gcc/config/sh/t-sh b/gcc/config/sh/t-sh index 65cc1ec53e9..11fa6f306be 100644 --- a/gcc/config/sh/t-sh +++ b/gcc/config/sh/t-sh @@ -38,9 +38,11 @@ MULTILIB_DIRNAMES= # 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 m1,m2,m2a-nofpu \ - m2e,m3e,m4-single-only,m4a-single-only m2e,m2a-single-only \ - m4-single,m4a-single m4,m4a \ + for abi in m1,m2,m3,m4-nofpu,m4-400,m4-500,m4al,m4a-nofpu m1,m2,m2a-nofpu \ + m2e,m3e,m4-single-only,m4-100-single-only,m4-200-single-only,m4a-single-only \ + m2e,m2a-single-only \ + m4-single,m4-100-single,m4-200-single,m4a-single \ + m4,m4-100,m4-200,m4a \ m5-32media,m5-compact,m5-32media \ m5-32media-nofpu,m5-compact-nofpu,m5-32media-nofpu; do \ subst= ; \ @@ -72,6 +74,25 @@ 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 +IC_EXTRA_PARTS= libic_invalidate_array_4-100.a libic_invalidate_array_4-200.a \ +libic_invalidate_array_4a.a +EXTRA_MULTILIB_PARTS= $(IC_EXTRA_PARTS) + +$(T)ic_invalidate_array_4-100.o: $(srcdir)/config/sh/lib1funcs.asm $(GCC_PASSES) + $(GCC_FOR_TARGET) $(MULTILIB_CFLAGS) -c -o $(T)ic_invalidate_array_4-100.o -DL_ic_invalidate_array -DWAYS=1 -DWAY_SIZE=0x2000 -x assembler-with-cpp $(srcdir)/config/sh/lib1funcs.asm +$(T)libic_invalidate_array_4-100.a: $(T)ic_invalidate_array_4-100.o $(GCC_PASSES) + $(AR_CREATE_FOR_TARGET) $(T)ic_invalidate_array_4-100.a $(T)ic_invalidate_array_4-100.o + +$(T)ic_invalidate_array_4-200.o: $(srcdir)/config/sh/lib1funcs.asm $(GCC_PASSES) + $(GCC_FOR_TARGET) $(MULTILIB_CFLAGS) -c -o $(T)ic_invalidate_array_4-200.o -DL_ic_invalidate_array -DWAYS=2 -DWAY_SIZE=0x2000 -x assembler-with-cpp $(srcdir)/config/sh/lib1funcs.asm +$(T)libic_invalidate_array_4-200.a: $(T)ic_invalidate_array_4-200.o $(GCC_PASSES) + $(AR_CREATE_FOR_TARGET) $(T)ic_invalidate_array_4-200.a $(T)ic_invalidate_array_4-200.o + +$(T)ic_invalidate_array_4a.o: $(srcdir)/config/sh/lib1funcs.asm $(GCC_PASSES) + $(GCC_FOR_TARGET) $(MULTILIB_CFLAGS) -c -o $(T)ic_invalidate_array_4a.o -DL_ic_invalidate_array -D__FORCE_SH4A__ -x assembler-with-cpp $(srcdir)/config/sh/lib1funcs.asm +$(T)libic_invalidate_array_4a.a: $(T)ic_invalidate_array_4a.o $(GCC_PASSES) + $(AR_CREATE_FOR_TARGET) $(T)ic_invalidate_array_4a.a $(T)ic_invalidate_array_4a.o + # Local Variables: # mode: Makefile # End: diff --git a/gcc/config/sh/t-superh b/gcc/config/sh/t-superh dissimilarity index 100% index 35803caeb05..875f7529f24 100644 --- a/gcc/config/sh/t-superh +++ b/gcc/config/sh/t-superh @@ -1,6 +1,15 @@ -MULTILIB_OPTIONS= mb m4-nofpu/m4-single/m4-single-only -MULTILIB_DIRNAMES= -MULTILIB_MATCHES = m4=m4-100 m4-nofpu=m4-100-nofpu m4-single=m4-100-single m4-single-only=m4-100-single-only \ - m4=m4-200 m4-nofpu=m4-200-nofpu m4-single=m4-200-single m4-single-only=m4-200-single-only \ - m4-nofpu=m4-400 \ - m4-nofpu=m4-500 +EXTRA_MULTILIB_PARTS= crt1.o crti.o crtn.o \ + crtbegin.o crtend.o crtbeginS.o crtendS.o \ + crt1-mmu.o gcrt1-mmu.o gcrt1.o $(IC_EXTRA_PARTS) + +# Compile crt1-mmu.o as crt1.o with -DMMU_SUPPORT +$(T)crt1-mmu.o: $(srcdir)/config/sh/crt1.asm $(GCC_PASSES) + $(GCC_FOR_TARGET) $(MULTILIB_CFLAGS) -c -o $(T)crt1-mmu.o -DMMU_SUPPORT -x assembler-with-cpp $(srcdir)/config/sh/crt1.asm + +# Compile gcrt1-mmu.o as crt1-mmu.o with -DPROFILE +$(T)gcrt1-mmu.o: $(srcdir)/config/sh/crt1.asm $(GCC_PASSES) + $(GCC_FOR_TARGET) $(MULTILIB_CFLAGS) -c -o $(T)gcrt1-mmu.o -DPROFILE -DMMU_SUPPORT -x assembler-with-cpp $(srcdir)/config/sh/crt1.asm + +# For sh4-400: Compile gcrt1.o as crt1.o with -DPROFILE +$(T)gcrt1.o: $(srcdir)/config/sh/crt1.asm $(GCC_PASSES) + $(GCC_FOR_TARGET) $(MULTILIB_CFLAGS) -c -o $(T)gcrt1.o -DPROFILE -x assembler-with-cpp $(srcdir)/config/sh/crt1.asm -- 2.11.4.GIT