github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/runtime/asm_avr.S (about) 1 .section .text.tinygo_scanCurrentStack 2 .global tinygo_scanCurrentStack 3 .type tinygo_scanCurrentStack, %function 4 tinygo_scanCurrentStack: 5 // Save callee-saved registers. 6 push r29 // Y 7 push r28 // Y 8 push r17 9 push r16 10 push r15 11 push r14 12 push r13 13 push r12 14 push r11 15 push r10 16 push r9 17 push r8 18 push r7 19 push r6 20 push r5 21 push r4 22 push r3 23 push r2 24 25 // Scan the stack. 26 in r24, 0x3d; SPL 27 in r25, 0x3e; SPH 28 #if __AVR_ARCH__ == 2 || __AVR_ARCH__ == 25 29 rcall tinygo_scanstack 30 #else 31 call tinygo_scanstack 32 #endif 33 34 // Restore callee-saved registers. 35 pop r2 36 pop r3 37 pop r4 38 pop r5 39 pop r6 40 pop r7 41 pop r8 42 pop r9 43 pop r10 44 pop r11 45 pop r12 46 pop r13 47 pop r14 48 pop r15 49 pop r16 50 pop r17 51 pop r28 // Y 52 pop r29 // Y 53 54 55 .section .text.tinygo_longjmp 56 .global tinygo_longjmp 57 tinygo_longjmp: 58 ; Move the *DeferFrame pointer to the X register. 59 mov r26, r24 60 mov r27, r25 61 62 ; Load the stack pointer 63 ld r24, X+ 64 ld r25, X+ 65 66 ; Switch to the given stack pointer. 67 in r0, 0x3f ; SREG 68 cli ; disable interrupts 69 out 0x3d, r24 ; SPL 70 out 0x3f, r0 ; re-enable interrupts (with one instruction delay) 71 out 0x3e, r25 ; SPH 72 73 ; Load the new PC 74 ld r30, X+ 75 ld r31, X+ 76 77 ; Load the new Y register 78 ld r28, X+ 79 ld r29, X+ 80 81 ; Jump to the PC (stored in the Z register) 82 icall