90 lines
1.9 KiB
ArmAsm
90 lines
1.9 KiB
ArmAsm
# setjmp/longjmp for Renesas RX.
|
|
#
|
|
# The jmpbuf looks like this:
|
|
#
|
|
# Register jmpbuf offset
|
|
# R0 0x0
|
|
# R1 0x4
|
|
# R2 0x8
|
|
# R3 0xc
|
|
# R4 0x10
|
|
# R5 0x14
|
|
# R6 0x18
|
|
# R7 0x1c
|
|
# R8 0x20
|
|
# R9 0x24
|
|
# R10 0x28
|
|
# R11 0x2c
|
|
# R12 0x30
|
|
# R13 0x34
|
|
# R14 0x38
|
|
# R15 0x3c
|
|
# PC 0x40
|
|
#
|
|
# R1 contains the pointer to jmpbuf:
|
|
#
|
|
# int R1 = setjmp (jmp_buf R1)
|
|
# void longjmp (jmp_buf R1, int R2)
|
|
#
|
|
# The ABI allows for R1-R5 to be clobbered by functions. We must be
|
|
# careful to always leave the stack in a usable state in case an
|
|
# interrupt happens.
|
|
|
|
.text
|
|
.global _setjmp
|
|
.type _setjmp, @function
|
|
_setjmp:
|
|
mov.l r0, [r1] ; save all the general registers
|
|
mov.l r1, 0x4[r1] ; longjmp won't use this, but someone else might.
|
|
mov.l r2, 0x8[r1]
|
|
mov.l r3, 0xc[r1]
|
|
mov.l r4, 0x10[r1]
|
|
mov.l r5, 0x14[r1]
|
|
mov.l r6, 0x18[r1]
|
|
mov.l r7, 0x1c[r1]
|
|
mov.l r8, 0x20[r1]
|
|
mov.l r9, 0x24[r1]
|
|
mov.l r10, 0x28[r1]
|
|
mov.l r11, 0x2c[r1]
|
|
mov.l r12, 0x30[r1]
|
|
mov.l r13, 0x34[r1]
|
|
mov.l r14, 0x38[r1]
|
|
mov.l r15, 0x3c[r1]
|
|
mov.l [r0], r2 ; get return address off the stack
|
|
mov.l r2, 0x40[r1] ; PC
|
|
mov #0, r1 ; Return 0.
|
|
rts
|
|
.Lend1:
|
|
.size _setjmp, .Lend1 - _setjmp
|
|
|
|
|
|
.global _longjmp
|
|
.type _longjmp, @function
|
|
_longjmp:
|
|
tst r2, r2 ; Set the Z flag if r2 is 0.
|
|
stz #1, r2 ; If the Z flag was set put 1 into the return register.
|
|
mov r2, 4[r1] ; Put r2 (our return value) into the setjmp buffer as r1.
|
|
|
|
mov.l [r1], r0 ; Restore the stack - there's a slot for PC
|
|
mov.l 0x40[r1], r2 ; Get the saved PC
|
|
mov.l r2, [r0] ; Overwrite the old return address
|
|
|
|
mov.l 0x3c[r1], r15
|
|
mov.l 0x38[r1], r14
|
|
mov.l 0x34[r1], r13
|
|
mov.l 0x30[r1], r12
|
|
mov.l 0x2c[r1], r11
|
|
mov.l 0x28[r1], r10
|
|
mov.l 0x24[r1], r9
|
|
mov.l 0x20[r1], r8
|
|
mov.l 0x1c[r1], r7
|
|
mov.l 0x18[r1], r6
|
|
mov.l 0x14[r1], r5
|
|
mov.l 0x10[r1], r4
|
|
mov.l 0xc[r1], r3
|
|
mov.l 0x8[r1], r2
|
|
mov.l 0x4[r1], r1 ; This sets up the new return value
|
|
rts
|
|
.Lend2:
|
|
.size _longjmp, .Lend2 - _longjmp
|