Home | History | Annotate | Line # | Download | only in sh
      1  1.1.1.11  mrg /* Copyright (C) 2000-2024 Free Software Foundation, Inc.
      2       1.1  mrg    This file was pretty much copied from newlib.
      3       1.1  mrg 
      4       1.1  mrg This file is part of GCC.
      5       1.1  mrg 
      6       1.1  mrg GCC is free software; you can redistribute it and/or modify it
      7       1.1  mrg under the terms of the GNU General Public License as published by the
      8       1.1  mrg Free Software Foundation; either version 3, or (at your option) any
      9       1.1  mrg later version.
     10       1.1  mrg 
     11       1.1  mrg GCC is distributed in the hope that it will be useful,
     12       1.1  mrg but WITHOUT ANY WARRANTY; without even the implied warranty of
     13       1.1  mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14       1.1  mrg General Public License for more details.
     15       1.1  mrg 
     16       1.1  mrg Under Section 7 of GPL version 3, you are granted additional
     17       1.1  mrg permissions described in the GCC Runtime Library Exception, version
     18       1.1  mrg 3.1, as published by the Free Software Foundation.
     19       1.1  mrg 
     20       1.1  mrg You should have received a copy of the GNU General Public License and
     21       1.1  mrg a copy of the GCC Runtime Library Exception along with this program;
     22       1.1  mrg see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     23       1.1  mrg <http://www.gnu.org/licenses/>.  */
     24       1.1  mrg 
     25   1.1.1.2  mrg #include "crt.h"
     26       1.1  mrg 
     27       1.1  mrg #ifdef MMU_SUPPORT
     28       1.1  mrg 	/* Section used for exception/timer interrupt stack area */
     29       1.1  mrg 	.section .data.vbr.stack,"aw"
     30       1.1  mrg 	.align 4
     31       1.1  mrg 	.global __ST_VBR
     32       1.1  mrg __ST_VBR:
     33       1.1  mrg 	.zero 1024 * 2          /* ; 2k for VBR handlers */
     34       1.1  mrg /* Label at the highest stack address where the stack grows from */
     35       1.1  mrg __timer_stack:
     36       1.1  mrg #endif /* MMU_SUPPORT */
     37       1.1  mrg 
     38       1.1  mrg 	/* ;----------------------------------------
     39       1.1  mrg 	Normal newlib crt1.S */
     40       1.1  mrg 
     41       1.1  mrg 	! make a place to keep any previous value of the vbr register
     42       1.1  mrg 	! this will only have a value if it has been set by redboot (for example)
     43       1.1  mrg 	.section .bss
     44       1.1  mrg old_vbr:
     45       1.1  mrg 	.long 0
     46       1.1  mrg #ifdef PROFILE
     47       1.1  mrg profiling_enabled:
     48       1.1  mrg 	.long 0
     49       1.1  mrg #endif
     50       1.1  mrg 
     51       1.1  mrg 
     52       1.1  mrg 	.section .text
     53       1.1  mrg 	.global	start
     54       1.1  mrg 	.import ___rtos_profiler_start_timer
     55       1.1  mrg 	.weak   ___rtos_profiler_start_timer
     56       1.1  mrg start:
     57       1.1  mrg 	mov.l	stack_k,r15
     58       1.1  mrg 
     59   1.1.1.2  mrg #if defined (__SH3__) || (defined (__SH_FPU_ANY__) && ! defined (__SH2E__) && ! defined (__SH2A__)) || defined (__SH4_NOFPU__)
     60       1.1  mrg #define VBR_SETUP
     61       1.1  mrg 	! before zeroing the bss ...
     62       1.1  mrg 	! if the vbr is already set to vbr_start then the program has been restarted
     63       1.1  mrg 	! (i.e. it is not the first time the program has been run since reset)
     64       1.1  mrg 	! reset the vbr to its old value before old_vbr (in bss) is wiped
     65       1.1  mrg 	! this ensures that the later code does not create a circular vbr chain
     66       1.1  mrg 	stc	vbr, r1
     67       1.1  mrg 	mov.l	vbr_start_k, r2
     68       1.1  mrg 	cmp/eq	r1, r2
     69       1.1  mrg 	bf	0f
     70       1.1  mrg 	! reset the old vbr value
     71       1.1  mrg 	mov.l	old_vbr_k, r1
     72       1.1  mrg 	mov.l	@r1, r2
     73       1.1  mrg 	ldc	r2, vbr
     74       1.1  mrg 0:
     75       1.1  mrg #endif /* VBR_SETUP */
     76       1.1  mrg 
     77       1.1  mrg 	! zero out bss
     78       1.1  mrg 	mov.l	edata_k,r0
     79       1.1  mrg 	mov.l	end_k,r1
     80       1.1  mrg 	mov	#0,r2
     81       1.1  mrg start_l:
     82       1.1  mrg 	mov.l	r2,@r0
     83       1.1  mrg 	add	#4,r0
     84       1.1  mrg 	cmp/ge	r0,r1
     85       1.1  mrg 	bt	start_l
     86       1.1  mrg 
     87       1.1  mrg #if defined (__SH_FPU_ANY__)
     88       1.1  mrg 	mov.l set_fpscr_k, r1
     89       1.1  mrg 	mov #4,r4
     90       1.1  mrg 	jsr @r1
     91       1.1  mrg 	shll16 r4	! Set DN bit (flush denormal inputs to zero)
     92       1.1  mrg 	lds r3,fpscr	! Switch to default precision
     93       1.1  mrg #endif /* defined (__SH_FPU_ANY__) */
     94       1.1  mrg 
     95       1.1  mrg #ifdef VBR_SETUP
     96       1.1  mrg 	! save the existing contents of the vbr
     97       1.1  mrg 	! there will only be a prior value when using something like redboot
     98       1.1  mrg 	! otherwise it will be zero
     99       1.1  mrg 	stc	vbr, r1
    100       1.1  mrg 	mov.l	old_vbr_k, r2
    101       1.1  mrg 	mov.l	r1, @r2
    102       1.1  mrg 	! setup vbr
    103       1.1  mrg 	mov.l	vbr_start_k, r1
    104       1.1  mrg 	ldc	r1,vbr
    105       1.1  mrg #endif /* VBR_SETUP */
    106       1.1  mrg 
    107       1.1  mrg 	! if an rtos is exporting a timer start fn,
    108       1.1  mrg 	! then pick up an SR which does not enable ints
    109       1.1  mrg 	! (the rtos will take care of this)
    110       1.1  mrg 	mov.l rtos_start_fn, r0
    111       1.1  mrg 	mov.l sr_initial_bare, r1
    112       1.1  mrg 	tst	r0, r0
    113       1.1  mrg 	bt	set_sr
    114       1.1  mrg 
    115       1.1  mrg 	mov.l sr_initial_rtos, r1
    116       1.1  mrg 
    117       1.1  mrg set_sr:
    118       1.1  mrg 	! Set status register (sr)
    119       1.1  mrg 	ldc	r1, sr
    120       1.1  mrg 
    121       1.1  mrg 	! arrange for exit to call fini
    122       1.1  mrg 	mov.l	atexit_k,r0
    123       1.1  mrg 	mov.l	fini_k,r4
    124       1.1  mrg 	jsr	@r0
    125       1.1  mrg 	nop
    126       1.1  mrg 
    127       1.1  mrg #ifdef PROFILE
    128       1.1  mrg 	! arrange for exit to call _mcleanup (via stop_profiling)
    129       1.1  mrg 	mova    stop_profiling,r0
    130       1.1  mrg 	mov.l   atexit_k,r1
    131       1.1  mrg 	jsr     @r1
    132       1.1  mrg 	mov	r0, r4
    133       1.1  mrg 
    134       1.1  mrg 	! Call profiler startup code
    135       1.1  mrg 	mov.l monstartup_k, r0
    136       1.1  mrg 	mov.l start_k, r4
    137       1.1  mrg 	mov.l etext_k, r5
    138       1.1  mrg 	jsr @r0
    139       1.1  mrg 	nop
    140       1.1  mrg 
    141       1.1  mrg 	! enable profiling trap
    142       1.1  mrg 	! until now any trap 33s will have been ignored
    143       1.1  mrg 	! This means that all library functions called before this point
    144       1.1  mrg 	! (directly or indirectly) may have the profiling trap at the start.
    145       1.1  mrg 	! Therefore, only mcount itself may not have the extra header.
    146       1.1  mrg 	mov.l	profiling_enabled_k2, r0
    147       1.1  mrg 	mov	#1, r1
    148       1.1  mrg 	mov.l	r1, @r0
    149       1.1  mrg #endif /* PROFILE */
    150       1.1  mrg 
    151       1.1  mrg 	! call init
    152       1.1  mrg 	mov.l	init_k,r0
    153       1.1  mrg 	jsr	@r0
    154       1.1  mrg 	nop
    155       1.1  mrg 
    156       1.1  mrg 	! call the mainline
    157       1.1  mrg 	mov.l	main_k,r0
    158       1.1  mrg 	jsr	@r0
    159       1.1  mrg 	nop
    160       1.1  mrg 
    161       1.1  mrg 	! call exit
    162       1.1  mrg 	mov	r0,r4
    163       1.1  mrg 	mov.l	exit_k,r0
    164       1.1  mrg 	jsr	@r0
    165       1.1  mrg 	nop
    166       1.1  mrg 
    167       1.1  mrg 		.balign 4
    168       1.1  mrg #ifdef PROFILE
    169       1.1  mrg stop_profiling:
    170       1.1  mrg 	# stop mcount counting
    171       1.1  mrg 	mov.l	profiling_enabled_k2, r0
    172       1.1  mrg 	mov	#0, r1
    173       1.1  mrg 	mov.l	r1, @r0
    174       1.1  mrg 
    175       1.1  mrg 	# call mcleanup
    176       1.1  mrg 	mov.l	mcleanup_k, r0
    177       1.1  mrg 	jmp	@r0
    178       1.1  mrg 	nop
    179       1.1  mrg 
    180       1.1  mrg 		.balign 4
    181       1.1  mrg mcleanup_k:
    182       1.1  mrg 	.long __mcleanup
    183       1.1  mrg monstartup_k:
    184       1.1  mrg 	.long ___monstartup
    185       1.1  mrg profiling_enabled_k2:
    186       1.1  mrg 	.long profiling_enabled
    187       1.1  mrg start_k:
    188       1.1  mrg 	.long _start
    189       1.1  mrg etext_k:
    190       1.1  mrg 	.long __etext
    191       1.1  mrg #endif /* PROFILE */
    192       1.1  mrg 
    193       1.1  mrg 	.align 2
    194       1.1  mrg #if defined (__SH_FPU_ANY__)
    195       1.1  mrg set_fpscr_k:
    196       1.1  mrg 	.long	___set_fpscr
    197       1.1  mrg #endif /*  defined (__SH_FPU_ANY__) */
    198       1.1  mrg 
    199       1.1  mrg stack_k:
    200       1.1  mrg 	.long	_stack
    201       1.1  mrg edata_k:
    202       1.1  mrg 	.long	_edata
    203       1.1  mrg end_k:
    204       1.1  mrg 	.long	_end
    205       1.1  mrg main_k:
    206       1.1  mrg 	.long	___setup_argv_and_call_main
    207       1.1  mrg exit_k:
    208       1.1  mrg 	.long	_exit
    209       1.1  mrg atexit_k:
    210       1.1  mrg 	.long	_atexit
    211       1.1  mrg init_k:
    212   1.1.1.2  mrg 	.long	GLOBAL(_init)
    213       1.1  mrg fini_k:
    214   1.1.1.2  mrg 	.long	GLOBAL(_fini)
    215       1.1  mrg #ifdef VBR_SETUP
    216       1.1  mrg old_vbr_k:
    217       1.1  mrg 	.long	old_vbr
    218       1.1  mrg vbr_start_k:
    219       1.1  mrg 	.long	vbr_start
    220       1.1  mrg #endif /* VBR_SETUP */
    221       1.1  mrg 
    222       1.1  mrg sr_initial_rtos:
    223       1.1  mrg 	! Privileged mode RB 1 BL 0. Keep BL 0 to allow default trap handlers to work.
    224       1.1  mrg 	! Whether profiling or not, keep interrupts masked,
    225       1.1  mrg 	! the RTOS will enable these if required.
    226       1.1  mrg 	.long 0x600000f1
    227       1.1  mrg 
    228       1.1  mrg rtos_start_fn:
    229       1.1  mrg 	.long ___rtos_profiler_start_timer
    230       1.1  mrg 
    231       1.1  mrg #ifdef PROFILE
    232       1.1  mrg sr_initial_bare:
    233       1.1  mrg 	! Privileged mode RB 1 BL 0. Keep BL 0 to allow default trap handlers to work.
    234       1.1  mrg 	! For bare machine, we need to enable interrupts to get profiling working
    235       1.1  mrg 	.long 0x60000001
    236       1.1  mrg #else
    237       1.1  mrg 
    238       1.1  mrg sr_initial_bare:
    239       1.1  mrg 	! Privileged mode RB 1 BL 0. Keep BL 0 to allow default trap handlers to work.
    240       1.1  mrg 	! Keep interrupts disabled - the application will enable as required.
    241       1.1  mrg 	.long 0x600000f1
    242       1.1  mrg #endif
    243       1.1  mrg 
    244       1.1  mrg 	! supplied for backward compatibility only, in case of linking
    245       1.1  mrg 	! code whose main() was compiled with an older version of GCC.
    246       1.1  mrg 	.global ___main
    247       1.1  mrg ___main:
    248       1.1  mrg 	rts
    249       1.1  mrg 	nop
    250       1.1  mrg #ifdef VBR_SETUP
    251       1.1  mrg ! Exception handlers
    252       1.1  mrg 	.section .text.vbr, "ax"
    253       1.1  mrg vbr_start:
    254       1.1  mrg 
    255       1.1  mrg 	.org 0x100
    256       1.1  mrg vbr_100:
    257       1.1  mrg #ifdef PROFILE
    258       1.1  mrg 	! Note on register usage.
    259       1.1  mrg 	! we use r0..r3 as scratch in this code. If we are here due to a trapa for profiling
    260       1.1  mrg 	! then this is OK as we are just before executing any function code.
    261       1.1  mrg 	! The other r4..r7 we save explicityl on the stack
    262       1.1  mrg 	! Remaining registers are saved by normal ABI conventions and we assert we do not
    263       1.1  mrg 	! use floating point registers.
    264       1.1  mrg 	mov.l expevt_k1, r1
    265       1.1  mrg 	mov.l @r1, r1
    266       1.1  mrg 	mov.l event_mask, r0
    267       1.1  mrg 	and r0,r1
    268       1.1  mrg 	mov.l trapcode_k, r2
    269       1.1  mrg 	cmp/eq r1,r2
    270       1.1  mrg 	bt 1f
    271       1.1  mrg 	bra handler_100   ! if not a trapa, go to default handler
    272       1.1  mrg 	nop
    273       1.1  mrg 1:
    274       1.1  mrg 	mov.l trapa_k, r0
    275       1.1  mrg 	mov.l @r0, r0
    276       1.1  mrg 	shlr2 r0      ! trapa code is shifted by 2.
    277       1.1  mrg 	cmp/eq #33, r0
    278       1.1  mrg 	bt 2f
    279       1.1  mrg 	bra handler_100
    280       1.1  mrg 	nop
    281       1.1  mrg 2:
    282       1.1  mrg 
    283       1.1  mrg 	! If here then it looks like we have trap #33
    284       1.1  mrg 	! Now we need to call mcount with the following convention
    285       1.1  mrg 	! Save and restore r4..r7
    286       1.1  mrg 	mov.l	r4,@-r15
    287       1.1  mrg 	mov.l	r5,@-r15
    288       1.1  mrg 	mov.l	r6,@-r15
    289       1.1  mrg 	mov.l	r7,@-r15
    290       1.1  mrg 	sts.l	pr,@-r15
    291       1.1  mrg 
    292       1.1  mrg 	! r4 is frompc.
    293       1.1  mrg 	! r5 is selfpc
    294       1.1  mrg 	! r0 is the branch back address.
    295       1.1  mrg 	! The code sequence emitted by gcc for the profiling trap is
    296       1.1  mrg 	! .align 2
    297       1.1  mrg 	! trapa #33
    298       1.1  mrg 	! .align 2
    299       1.1  mrg 	! .long lab Where lab is planted by the compiler. This is the address
    300       1.1  mrg 	! of a datum that needs to be incremented.
    301       1.1  mrg 	sts pr,  r4     ! frompc
    302       1.1  mrg 	stc spc, r5	! selfpc
    303       1.1  mrg 	mov #2, r2
    304       1.1  mrg 	not r2, r2      ! pattern to align to 4
    305       1.1  mrg 	and r2, r5      ! r5 now has aligned address
    306       1.1  mrg !	add #4, r5      ! r5 now has address of address
    307       1.1  mrg 	mov r5, r2      ! Remember it.
    308       1.1  mrg !	mov.l @r5, r5   ! r5 has value of lable (lab in above example)
    309       1.1  mrg 	add #8, r2
    310       1.1  mrg 	ldc r2, spc     ! our return address avoiding address word
    311       1.1  mrg 
    312       1.1  mrg 	! only call mcount if profiling is enabled
    313       1.1  mrg 	mov.l profiling_enabled_k, r0
    314       1.1  mrg 	mov.l @r0, r0
    315       1.1  mrg 	cmp/eq #0, r0
    316       1.1  mrg 	bt 3f
    317       1.1  mrg 	! call mcount
    318       1.1  mrg 	mov.l mcount_k, r2
    319       1.1  mrg 	jsr @r2
    320       1.1  mrg 	nop
    321       1.1  mrg 3:
    322       1.1  mrg 	lds.l @r15+,pr
    323       1.1  mrg 	mov.l @r15+,r7
    324       1.1  mrg 	mov.l @r15+,r6
    325       1.1  mrg 	mov.l @r15+,r5
    326       1.1  mrg 	mov.l @r15+,r4
    327       1.1  mrg 	rte
    328       1.1  mrg 	nop
    329       1.1  mrg 	.balign 4
    330       1.1  mrg event_mask:
    331       1.1  mrg 	.long 0xfff
    332       1.1  mrg trapcode_k:
    333       1.1  mrg 	.long 0x160
    334       1.1  mrg expevt_k1:
    335       1.1  mrg 	.long 0xff000024 ! Address of expevt
    336       1.1  mrg trapa_k:
    337       1.1  mrg 	.long 0xff000020
    338       1.1  mrg mcount_k:
    339       1.1  mrg 	.long __call_mcount
    340       1.1  mrg profiling_enabled_k:
    341       1.1  mrg 	.long profiling_enabled
    342       1.1  mrg #endif
    343       1.1  mrg 	! Non profiling case.
    344       1.1  mrg handler_100:
    345       1.1  mrg 	mov.l 2f, r0     ! load the old vbr setting (if any)
    346       1.1  mrg 	mov.l @r0, r0
    347       1.1  mrg 	cmp/eq #0, r0
    348       1.1  mrg 	bf 1f
    349       1.1  mrg 	! no previous vbr - jump to own generic handler
    350       1.1  mrg 	bra handler
    351       1.1  mrg 	nop
    352       1.1  mrg 1:	! there was a previous handler - chain them
    353       1.1  mrg 	add #0x7f, r0	 ! 0x7f
    354       1.1  mrg 	add #0x7f, r0	 ! 0xfe
    355       1.1  mrg 	add #0x2, r0     ! add 0x100 without corrupting another register
    356       1.1  mrg 	jmp @r0
    357       1.1  mrg 	nop
    358       1.1  mrg 	.balign 4
    359       1.1  mrg 2:
    360       1.1  mrg 	.long old_vbr
    361       1.1  mrg 
    362       1.1  mrg 	.org 0x400
    363       1.1  mrg vbr_400:	! Should be at vbr+0x400
    364       1.1  mrg 	mov.l 2f, r0     ! load the old vbr setting (if any)
    365       1.1  mrg 	mov.l @r0, r0
    366       1.1  mrg 	cmp/eq #0, r0
    367       1.1  mrg 	! no previous vbr - jump to own generic handler
    368       1.1  mrg 	bt handler
    369       1.1  mrg 	! there was a previous handler - chain them
    370       1.1  mrg 	rotcr r0
    371       1.1  mrg 	rotcr r0
    372       1.1  mrg 	add #0x7f, r0	 ! 0x1fc
    373       1.1  mrg 	add #0x7f, r0	 ! 0x3f8
    374       1.1  mrg 	add #0x02, r0	 ! 0x400
    375       1.1  mrg 	rotcl r0
    376       1.1  mrg 	rotcl r0	 ! Add 0x400 without corrupting another register
    377       1.1  mrg 	jmp @r0
    378       1.1  mrg 	nop
    379       1.1  mrg 	.balign 4
    380       1.1  mrg 2:
    381       1.1  mrg 	.long old_vbr
    382       1.1  mrg handler:
    383       1.1  mrg 	/* If the trap handler is there call it */
    384       1.1  mrg 	mov.l	superh_trap_handler_k, r0
    385       1.1  mrg 	cmp/eq	#0, r0       ! True if zero.
    386       1.1  mrg 	bf 3f
    387       1.1  mrg 	bra   chandler
    388       1.1  mrg 	nop
    389       1.1  mrg 3:
    390       1.1  mrg 	! Here handler available, call it.
    391       1.1  mrg 	/* Now call the trap handler with as much of the context unchanged as possible.
    392       1.1  mrg 	   Move trapping address into PR to make it look like the trap point */
    393       1.1  mrg 	stc spc, r1
    394       1.1  mrg 	lds r1, pr
    395       1.1  mrg 	mov.l expevt_k, r4
    396       1.1  mrg 	mov.l @r4, r4 ! r4 is value of expevt, first parameter.
    397       1.1  mrg 	mov r1, r5   ! Remember trapping pc.
    398       1.1  mrg 	mov r1, r6   ! Remember trapping pc.
    399       1.1  mrg 	mov.l chandler_k, r1
    400       1.1  mrg 	mov.l superh_trap_handler_k, r2
    401       1.1  mrg 	! jmp to trap handler to avoid disturbing pr.
    402       1.1  mrg 	jmp @r2
    403       1.1  mrg 	nop
    404       1.1  mrg 
    405       1.1  mrg 	.org 0x600
    406       1.1  mrg vbr_600:
    407       1.1  mrg #ifdef PROFILE
    408       1.1  mrg 	! Should be at vbr+0x600
    409       1.1  mrg 	! Now we are in the land of interrupts so need to save more state.
    410       1.1  mrg 	! Save register state
    411       1.1  mrg 	mov.l interrupt_stack_k, r15 ! r15 has been saved to sgr.
    412       1.1  mrg 	mov.l	r0,@-r15
    413       1.1  mrg 	mov.l	r1,@-r15
    414       1.1  mrg 	mov.l	r2,@-r15
    415       1.1  mrg 	mov.l	r3,@-r15
    416       1.1  mrg 	mov.l	r4,@-r15
    417       1.1  mrg 	mov.l	r5,@-r15
    418       1.1  mrg 	mov.l	r6,@-r15
    419       1.1  mrg 	mov.l	r7,@-r15
    420       1.1  mrg 	sts.l	pr,@-r15
    421       1.1  mrg 	sts.l	mach,@-r15
    422       1.1  mrg 	sts.l	macl,@-r15
    423       1.1  mrg #if defined(__SH_FPU_ANY__)
    424       1.1  mrg 	! Save fpul and fpscr, save fr0-fr7 in 64 bit mode
    425       1.1  mrg 	! and set the pervading precision for the timer_handler
    426       1.1  mrg 	mov	#0,r0
    427       1.1  mrg 	sts.l	fpul,@-r15
    428       1.1  mrg 	sts.l	fpscr,@-r15
    429       1.1  mrg 	lds	r0,fpscr	! Clear fpscr
    430       1.1  mrg 	fmov	fr0,@-r15
    431       1.1  mrg 	fmov	fr1,@-r15
    432       1.1  mrg 	fmov	fr2,@-r15
    433       1.1  mrg 	fmov	fr3,@-r15
    434       1.1  mrg 	mov.l	pervading_precision_k,r0
    435       1.1  mrg 	fmov	fr4,@-r15
    436       1.1  mrg 	fmov	fr5,@-r15
    437       1.1  mrg 	mov.l	@r0,r0
    438       1.1  mrg 	fmov	fr6,@-r15
    439       1.1  mrg 	fmov	fr7,@-r15
    440       1.1  mrg 	lds	r0,fpscr
    441       1.1  mrg #endif /* __SH_FPU_ANY__ */
    442       1.1  mrg 	! Pass interrupted pc to timer_handler as first parameter (r4).
    443       1.1  mrg 	stc    spc, r4
    444       1.1  mrg 	mov.l timer_handler_k, r0
    445       1.1  mrg 	jsr @r0
    446       1.1  mrg 	nop
    447       1.1  mrg #if defined(__SH_FPU_ANY__)
    448       1.1  mrg 	mov	#0,r0
    449       1.1  mrg 	lds	r0,fpscr	! Clear the fpscr
    450       1.1  mrg 	fmov	@r15+,fr7
    451       1.1  mrg 	fmov	@r15+,fr6
    452       1.1  mrg 	fmov	@r15+,fr5
    453       1.1  mrg 	fmov	@r15+,fr4
    454       1.1  mrg 	fmov	@r15+,fr3
    455       1.1  mrg 	fmov	@r15+,fr2
    456       1.1  mrg 	fmov	@r15+,fr1
    457       1.1  mrg 	fmov	@r15+,fr0
    458       1.1  mrg 	lds.l	@r15+,fpscr
    459       1.1  mrg 	lds.l	@r15+,fpul
    460       1.1  mrg #endif /* __SH_FPU_ANY__ */
    461       1.1  mrg 	lds.l @r15+,macl
    462       1.1  mrg 	lds.l @r15+,mach
    463       1.1  mrg 	lds.l @r15+,pr
    464       1.1  mrg 	mov.l @r15+,r7
    465       1.1  mrg 	mov.l @r15+,r6
    466       1.1  mrg 	mov.l @r15+,r5
    467       1.1  mrg 	mov.l @r15+,r4
    468       1.1  mrg 	mov.l @r15+,r3
    469       1.1  mrg 	mov.l @r15+,r2
    470       1.1  mrg 	mov.l @r15+,r1
    471       1.1  mrg 	mov.l @r15+,r0
    472       1.1  mrg 	stc sgr, r15    ! Restore r15, destroyed by this sequence.
    473       1.1  mrg 	rte
    474       1.1  mrg 	nop
    475       1.1  mrg #if defined(__SH_FPU_ANY__)
    476       1.1  mrg 	.balign 4
    477       1.1  mrg pervading_precision_k:
    478   1.1.1.2  mrg 	.long GLOBAL(__fpscr_values)+4
    479       1.1  mrg #endif
    480       1.1  mrg #else
    481       1.1  mrg 	mov.l 2f, r0     ! Load the old vbr setting (if any).
    482       1.1  mrg 	mov.l @r0, r0
    483       1.1  mrg 	cmp/eq #0, r0
    484       1.1  mrg 	! no previous vbr - jump to own handler
    485       1.1  mrg 	bt chandler
    486       1.1  mrg 	! there was a previous handler - chain them
    487       1.1  mrg 	rotcr r0
    488       1.1  mrg 	rotcr r0
    489       1.1  mrg 	add #0x7f, r0	 ! 0x1fc
    490       1.1  mrg 	add #0x7f, r0	 ! 0x3f8
    491       1.1  mrg 	add #0x7f, r0	 ! 0x5f4
    492       1.1  mrg 	add #0x03, r0	 ! 0x600
    493       1.1  mrg 	rotcl r0
    494       1.1  mrg 	rotcl r0	 ! Add 0x600 without corrupting another register
    495       1.1  mrg 	jmp @r0
    496       1.1  mrg 	nop
    497       1.1  mrg 	.balign 4
    498       1.1  mrg 2:
    499       1.1  mrg 	.long old_vbr
    500       1.1  mrg #endif	 /* PROFILE code */
    501       1.1  mrg chandler:
    502       1.1  mrg 	mov.l expevt_k, r4
    503       1.1  mrg 	mov.l @r4, r4 ! r4 is value of expevt hence making this the return code
    504       1.1  mrg 	mov.l handler_exit_k,r0
    505       1.1  mrg 	jsr   @r0
    506       1.1  mrg 	nop
    507       1.1  mrg 	! We should never return from _exit but in case we do we would enter the
    508       1.1  mrg 	! the following tight loop
    509       1.1  mrg limbo:
    510       1.1  mrg 	bra limbo
    511       1.1  mrg 	nop
    512       1.1  mrg 	.balign 4
    513       1.1  mrg #ifdef PROFILE
    514       1.1  mrg interrupt_stack_k:
    515       1.1  mrg 	.long __timer_stack	! The high end of the stack
    516       1.1  mrg timer_handler_k:
    517       1.1  mrg 	.long __profil_counter
    518       1.1  mrg #endif
    519       1.1  mrg expevt_k:
    520       1.1  mrg 	.long 0xff000024 ! Address of expevt
    521       1.1  mrg chandler_k:
    522       1.1  mrg 	.long chandler
    523       1.1  mrg superh_trap_handler_k:
    524       1.1  mrg 	.long	__superh_trap_handler
    525       1.1  mrg handler_exit_k:
    526       1.1  mrg 	.long _exit
    527       1.1  mrg 	.align 2
    528       1.1  mrg ! Simulated compile of trap handler.
    529       1.1  mrg 	.section	.debug_abbrev,"",@progbits
    530       1.1  mrg .Ldebug_abbrev0:
    531       1.1  mrg 	.section	.debug_info,"",@progbits
    532       1.1  mrg .Ldebug_info0:
    533       1.1  mrg 	.section	.debug_line,"",@progbits
    534       1.1  mrg .Ldebug_line0:
    535       1.1  mrg 	.text
    536       1.1  mrg .Ltext0:
    537       1.1  mrg 	.align 5
    538       1.1  mrg 	.type	__superh_trap_handler,@function
    539       1.1  mrg __superh_trap_handler:
    540       1.1  mrg .LFB1:
    541       1.1  mrg 	mov.l	r14,@-r15
    542       1.1  mrg .LCFI0:
    543       1.1  mrg 	add	#-4,r15
    544       1.1  mrg .LCFI1:
    545       1.1  mrg 	mov	r15,r14
    546       1.1  mrg .LCFI2:
    547       1.1  mrg 	mov.l	r4,@r14
    548       1.1  mrg 	lds	r1, pr
    549       1.1  mrg 	add	#4,r14
    550       1.1  mrg 	mov	r14,r15
    551       1.1  mrg 	mov.l	@r15+,r14
    552       1.1  mrg 	rts
    553       1.1  mrg 	nop
    554       1.1  mrg .LFE1:
    555       1.1  mrg .Lfe1:
    556       1.1  mrg 	.size	__superh_trap_handler,.Lfe1-__superh_trap_handler
    557       1.1  mrg 	.section	.debug_frame,"",@progbits
    558       1.1  mrg .Lframe0:
    559       1.1  mrg 	.ualong	.LECIE0-.LSCIE0
    560       1.1  mrg .LSCIE0:
    561       1.1  mrg 	.ualong	0xffffffff
    562       1.1  mrg 	.byte	0x1
    563       1.1  mrg 	.string	""
    564       1.1  mrg 	.uleb128 0x1
    565       1.1  mrg 	.sleb128 -4
    566       1.1  mrg 	.byte	0x11
    567       1.1  mrg 	.byte	0xc
    568       1.1  mrg 	.uleb128 0xf
    569       1.1  mrg 	.uleb128 0x0
    570       1.1  mrg 	.align 2
    571       1.1  mrg .LECIE0:
    572       1.1  mrg .LSFDE0:
    573       1.1  mrg 	.ualong	.LEFDE0-.LASFDE0
    574       1.1  mrg .LASFDE0:
    575       1.1  mrg 	.ualong	.Lframe0
    576       1.1  mrg 	.ualong	.LFB1
    577       1.1  mrg 	.ualong	.LFE1-.LFB1
    578       1.1  mrg 	.byte	0x4
    579       1.1  mrg 	.ualong	.LCFI0-.LFB1
    580       1.1  mrg 	.byte	0xe
    581       1.1  mrg 	.uleb128 0x4
    582       1.1  mrg 	.byte	0x4
    583       1.1  mrg 	.ualong	.LCFI1-.LCFI0
    584       1.1  mrg 	.byte	0xe
    585       1.1  mrg 	.uleb128 0x8
    586       1.1  mrg 	.byte	0x8e
    587       1.1  mrg 	.uleb128 0x1
    588       1.1  mrg 	.byte	0x4
    589       1.1  mrg 	.ualong	.LCFI2-.LCFI1
    590       1.1  mrg 	.byte	0xd
    591       1.1  mrg 	.uleb128 0xe
    592       1.1  mrg 	.align 2
    593       1.1  mrg .LEFDE0:
    594       1.1  mrg 	.text
    595       1.1  mrg .Letext0:
    596       1.1  mrg 	.section	.debug_info
    597       1.1  mrg 	.ualong	0xb3
    598       1.1  mrg 	.uaword	0x2
    599       1.1  mrg 	.ualong	.Ldebug_abbrev0
    600       1.1  mrg 	.byte	0x4
    601       1.1  mrg 	.uleb128 0x1
    602       1.1  mrg 	.ualong	.Ldebug_line0
    603       1.1  mrg 	.ualong	.Letext0
    604       1.1  mrg 	.ualong	.Ltext0
    605       1.1  mrg 	.string	"trap_handler.c"
    606       1.1  mrg 	.string	"xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    607       1.1  mrg 	.string	"GNU C 3.2 20020529 (experimental)"
    608       1.1  mrg 	.byte	0x1
    609       1.1  mrg 	.uleb128 0x2
    610       1.1  mrg 	.ualong	0xa6
    611       1.1  mrg 	.byte	0x1
    612       1.1  mrg 	.string	"_superh_trap_handler"
    613       1.1  mrg 	.byte	0x1
    614       1.1  mrg 	.byte	0x2
    615       1.1  mrg 	.byte	0x1
    616       1.1  mrg 	.ualong	.LFB1
    617       1.1  mrg 	.ualong	.LFE1
    618       1.1  mrg 	.byte	0x1
    619       1.1  mrg 	.byte	0x5e
    620       1.1  mrg 	.uleb128 0x3
    621       1.1  mrg 	.string	"trap_reason"
    622       1.1  mrg 	.byte	0x1
    623       1.1  mrg 	.byte	0x1
    624       1.1  mrg 	.ualong	0xa6
    625       1.1  mrg 	.byte	0x2
    626       1.1  mrg 	.byte	0x91
    627       1.1  mrg 	.sleb128 0
    628       1.1  mrg 	.byte	0x0
    629       1.1  mrg 	.uleb128 0x4
    630       1.1  mrg 	.string	"unsigned int"
    631       1.1  mrg 	.byte	0x4
    632       1.1  mrg 	.byte	0x7
    633       1.1  mrg 	.byte	0x0
    634       1.1  mrg 	.section	.debug_abbrev
    635       1.1  mrg 	.uleb128 0x1
    636       1.1  mrg 	.uleb128 0x11
    637       1.1  mrg 	.byte	0x1
    638       1.1  mrg 	.uleb128 0x10
    639       1.1  mrg 	.uleb128 0x6
    640       1.1  mrg 	.uleb128 0x12
    641       1.1  mrg 	.uleb128 0x1
    642       1.1  mrg 	.uleb128 0x11
    643       1.1  mrg 	.uleb128 0x1
    644       1.1  mrg 	.uleb128 0x3
    645       1.1  mrg 	.uleb128 0x8
    646       1.1  mrg 	.uleb128 0x1b
    647       1.1  mrg 	.uleb128 0x8
    648       1.1  mrg 	.uleb128 0x25
    649       1.1  mrg 	.uleb128 0x8
    650       1.1  mrg 	.uleb128 0x13
    651       1.1  mrg 	.uleb128 0xb
    652       1.1  mrg 	.byte	0x0
    653       1.1  mrg 	.byte	0x0
    654       1.1  mrg 	.uleb128 0x2
    655       1.1  mrg 	.uleb128 0x2e
    656       1.1  mrg 	.byte	0x1
    657       1.1  mrg 	.uleb128 0x1
    658       1.1  mrg 	.uleb128 0x13
    659       1.1  mrg 	.uleb128 0x3f
    660       1.1  mrg 	.uleb128 0xc
    661       1.1  mrg 	.uleb128 0x3
    662       1.1  mrg 	.uleb128 0x8
    663       1.1  mrg 	.uleb128 0x3a
    664       1.1  mrg 	.uleb128 0xb
    665       1.1  mrg 	.uleb128 0x3b
    666       1.1  mrg 	.uleb128 0xb
    667       1.1  mrg 	.uleb128 0x27
    668       1.1  mrg 	.uleb128 0xc
    669       1.1  mrg 	.uleb128 0x11
    670       1.1  mrg 	.uleb128 0x1
    671       1.1  mrg 	.uleb128 0x12
    672       1.1  mrg 	.uleb128 0x1
    673       1.1  mrg 	.uleb128 0x40
    674       1.1  mrg 	.uleb128 0xa
    675       1.1  mrg 	.byte	0x0
    676       1.1  mrg 	.byte	0x0
    677       1.1  mrg 	.uleb128 0x3
    678       1.1  mrg 	.uleb128 0x5
    679       1.1  mrg 	.byte	0x0
    680       1.1  mrg 	.uleb128 0x3
    681       1.1  mrg 	.uleb128 0x8
    682       1.1  mrg 	.uleb128 0x3a
    683       1.1  mrg 	.uleb128 0xb
    684       1.1  mrg 	.uleb128 0x3b
    685       1.1  mrg 	.uleb128 0xb
    686       1.1  mrg 	.uleb128 0x49
    687       1.1  mrg 	.uleb128 0x13
    688       1.1  mrg 	.uleb128 0x2
    689       1.1  mrg 	.uleb128 0xa
    690       1.1  mrg 	.byte	0x0
    691       1.1  mrg 	.byte	0x0
    692       1.1  mrg 	.uleb128 0x4
    693       1.1  mrg 	.uleb128 0x24
    694       1.1  mrg 	.byte	0x0
    695       1.1  mrg 	.uleb128 0x3
    696       1.1  mrg 	.uleb128 0x8
    697       1.1  mrg 	.uleb128 0xb
    698       1.1  mrg 	.uleb128 0xb
    699       1.1  mrg 	.uleb128 0x3e
    700       1.1  mrg 	.uleb128 0xb
    701       1.1  mrg 	.byte	0x0
    702       1.1  mrg 	.byte	0x0
    703       1.1  mrg 	.byte	0x0
    704       1.1  mrg 	.section	.debug_pubnames,"",@progbits
    705       1.1  mrg 	.ualong	0x27
    706       1.1  mrg 	.uaword	0x2
    707       1.1  mrg 	.ualong	.Ldebug_info0
    708       1.1  mrg 	.ualong	0xb7
    709       1.1  mrg 	.ualong	0x67
    710       1.1  mrg 	.string	"_superh_trap_handler"
    711       1.1  mrg 	.ualong	0x0
    712       1.1  mrg 	.section	.debug_aranges,"",@progbits
    713       1.1  mrg 	.ualong	0x1c
    714       1.1  mrg 	.uaword	0x2
    715       1.1  mrg 	.ualong	.Ldebug_info0
    716       1.1  mrg 	.byte	0x4
    717       1.1  mrg 	.byte	0x0
    718       1.1  mrg 	.uaword	0x0
    719       1.1  mrg 	.uaword	0x0
    720       1.1  mrg 	.ualong	.Ltext0
    721       1.1  mrg 	.ualong	.Letext0-.Ltext0
    722       1.1  mrg 	.ualong	0x0
    723       1.1  mrg 	.ualong	0x0
    724       1.1  mrg #endif /* VBR_SETUP */
    725