1/* 2Copyright (c) 2009 Nick Clifton <nickc@redhat.com> 3 */ 4#include <picolibc.h> 5 6# setjmp/longjmp for Renesas RX. 7# 8# The jmpbuf looks like this: 9# 10# Register jmpbuf offset 11# R0 0x0 12# R1 0x4 13# R2 0x8 14# R3 0xc 15# R4 0x10 16# R5 0x14 17# R6 0x18 18# R7 0x1c 19# R8 0x20 20# R9 0x24 21# R10 0x28 22# R11 0x2c 23# R12 0x30 24# R13 0x34 25# R14 0x38 26# R15 0x3c 27# PC 0x40 28# 29# R1 contains the pointer to jmpbuf: 30# 31# int R1 = setjmp (jmp_buf R1) 32# void longjmp (jmp_buf R1, int R2) 33# 34# The ABI allows for R1-R5 to be clobbered by functions. We must be 35# careful to always leave the stack in a usable state in case an 36# interrupt happens. 37 38 .text 39 .global _setjmp 40 .type _setjmp, @function 41_setjmp: 42 mov.l r0, [r1] ; save all the general registers 43 mov.l r1, 0x4[r1] ; longjmp won't use this, but someone else might. 44 mov.l r2, 0x8[r1] 45 mov.l r3, 0xc[r1] 46 mov.l r4, 0x10[r1] 47 mov.l r5, 0x14[r1] 48 mov.l r6, 0x18[r1] 49 mov.l r7, 0x1c[r1] 50 mov.l r8, 0x20[r1] 51 mov.l r9, 0x24[r1] 52 mov.l r10, 0x28[r1] 53 mov.l r11, 0x2c[r1] 54 mov.l r12, 0x30[r1] 55 mov.l r13, 0x34[r1] 56 mov.l r14, 0x38[r1] 57 mov.l r15, 0x3c[r1] 58 mov.l [r0], r2 ; get return address off the stack 59 mov.l r2, 0x40[r1] ; PC 60 mov #0, r1 ; Return 0. 61 rts 62.Lend1: 63 .size _setjmp, .Lend1 - _setjmp 64 65 66 .global _longjmp 67 .type _longjmp, @function 68_longjmp: 69 tst r2, r2 ; Set the Z flag if r2 is 0. 70 stz #1, r2 ; If the Z flag was set put 1 into the return register. 71 mov r2, 4[r1] ; Put r2 (our return value) into the setjmp buffer as r1. 72 73 mov.l [r1], r0 ; Restore the stack - there's a slot for PC 74 mov.l 0x40[r1], r2 ; Get the saved PC 75 mov.l r2, [r0] ; Overwrite the old return address 76 77 mov.l 0x3c[r1], r15 78 mov.l 0x38[r1], r14 79 mov.l 0x34[r1], r13 80 mov.l 0x30[r1], r12 81 mov.l 0x2c[r1], r11 82 mov.l 0x28[r1], r10 83 mov.l 0x24[r1], r9 84 mov.l 0x20[r1], r8 85 mov.l 0x1c[r1], r7 86 mov.l 0x18[r1], r6 87 mov.l 0x14[r1], r5 88 mov.l 0x10[r1], r4 89 mov.l 0xc[r1], r3 90 mov.l 0x8[r1], r2 91 mov.l 0x4[r1], r1 ; This sets up the new return value 92 rts 93.Lend2: 94 .size _longjmp, .Lend2 - _longjmp 95