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