/* An example TRAPA #32 handler for the Hitachi SH2.
/*
/*Stores current register values on the stack, then calls gdb_exception.
*/
asm("
.global _gdb_exception_32
_gdb_exception_32:
/* push the stack pointer and r14 */
mov.l r15, @-r15
mov.l r14, @-r15
/* the sh2 stacks the pc and sr automatically when performing a trap
/* exception, so we have to adjust the stack pointer value
we give to gdb to
/* account for this extra data. In other words, gdb wants to see the stack
/* pointer value as it was BEFORE the trap was taken, and not what its value
/* is right now. So, subtract eight (pc and sr are four bytes each) from the
/* sp value we just pushed onto the stack
*/
mov.l @(4,r15), r14
add #8, r14
mov.l r14, @(4,r15)
/* push other register values onto the stack */
mov.l r13, @-r15
mov.l r12, @-r15
mov.l r11, @-r15
mov.l
r10, @-r15
mov.l r9, @-r15
mov.l r8, @-r15
mov.l r7, @-r15
mov.l r6, @-r15
mov.l r5, @-r15
mov.l r4, @-r15
mov.l r3, @-r15
mov.l r2, @-r15
mov.l r1, @-r15
mov.l r0, @-r15
sts.l macl, @-r15
sts.l mach, @-r15
stc vbr, r7
stc gbr, r6
sts pr, r5
/* call gdb_exception, pass it exception=32 */
mov.l _gdb_exception_target, r1
jmp @r1
mov #32, r4
.align 2
_gdb_exception_target: .long _gdb_exception
");
/* An example on how to return control to an application from a debugging
/* stub, for the
Hitachi SH2.
/*
/* If this were written in C, the prototype would be:
/* void gdb_return_from_exception( gdb_sh2_registers_T registers );
/*
/* In general, we can simply pop registers off the stack in the same fashion
/* as gdb_exception_nn puts them on. However, usually the return stack pointer
/* isn't the same as ours, so if we pop r15 before we copy the pc and sr back
/* onto the return stack, we lose them.
*/
asm("
.global
_gdb_return_from_exception
_gdb_return_from_exception:
/* restore some registers */
lds r4, pr
ldc r5, gbr
ldc r6, vbr
lds r7, mach
lds.l @r15+, macl
mov.l @r15+, r0
mov.l @r15+, r1
mov.l @r15+, r2
mov.l @r15+, r3
mov.l @r15+, r4
mov.l @r15+, r5
mov.l @r15+, r6
mov.l @r15+, r7
mov.l @r15+, r8
mov.l @r15+, r9
mov.l @r15+, r10
mov.l @r15+, r11
mov.l @r15+, r12
/* pop pc, sr onto application's stack, not ours */
mov.l @(8,r15), r14
mov.l @(16,r15), r13
mov.l r13, @-r14
mov.l @(12,r15), r13
mov.l r13, @-r14
/*
finish restoring registers */
mov.l @r15+, r13
mov.l @r15+, r14
mov.l @r15, r15
/* adjust application's stack pointer to account for pc, sr */
add #-8, r15
/* ... and return to the application */
rte
nop
");
|