Changeset c5cbc099
- Timestamp:
- Aug 21, 2020, 7:45:51 AM (3 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 482fa08
- Parents:
- 636d115b
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/CtxSwitch-arm.S
r636d115b rc5cbc099 1 @ 32 bit ARM context switch 2 @ This function assumes that r9 has no special meaning on the platform it's 3 @ being built on. 4 @ If r9 is special, uncomment the following line and it will be left alone 1 // 2 // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo 3 // 4 // CtxSwitch-arm.S -- 5 // 6 // Author : Peter A. Buhr 7 // Created On : Sun Aug 16 07:50:13 2020 8 // Last Modified By : Peter A. Buhr 9 // Last Modified On : Thu Aug 20 18:43:51 2020 10 // Update Count : 24 11 // 5 12 6 @ #define R9_SPECIAL 13 // The context switch routine requires the initial the stack of a thread to 14 // look like the thread has saved its context in the normal manner. 7 15 8 #define PTR_BYTE 4 9 #define SP_OFFSET ( 0 * PTR_BYTE ) 10 #define FP_OFFSET ( 1 * PTR_BYTE ) 11 #define PC_OFFSET ( 2 * PTR_BYTE ) 16 // Offsets must synchronized with the __stack_context_t in invoke.h. 17 18 #define PTR_BYTE 8 19 #define SP_OFFSET ( 0 * PTR_BYTE ) 20 #define FP_OFFSET ( 1 * PTR_BYTE ) 21 22 // Context switch between coroutines/tasks. 23 // void __cfactx_switch( struct __stack_context_t * from, struct __stack_context_t * to ) ; 24 // Arguments "from" in register x0, "to" in register x1. 25 26 #define SAVE 20 * 8 27 28 .file "CtxSwitch-arm.S" 29 .text 30 .align 2 31 .global __cfactx_switch 32 .type __cfactx_switch, @function 33 __cfactx_switch: 34 35 sub sp, sp, #SAVE // push stack 36 37 // Save volatile GP registers x19-x30 on the stack. 38 39 stp x19, x20, [sp, #0x00] 40 stp x21, x22, [sp, #0x10] 41 stp x23, x24, [sp, #0x20] 42 stp x25, x26, [sp, #0x30] 43 stp x27, x28, [sp, #0x40] 44 stp x29, x30, [sp, #0x50] // x29 => fp 45 46 // Save volatile SIMD/FPU registers d8-d15 on the stack. 47 48 stp d8, d9, [sp, #0x60] 49 stp d10, d11, [sp, #0x70] 50 stp d12, d13, [sp, #0x80] 51 stp d14, d15, [sp, #0x90] 52 53 // Save old context in the "from" area. 54 55 mov x4, sp // cannot store sp directly 56 str x4, [x0, #SP_OFFSET] 57 str fp, [x0, #FP_OFFSET] 58 59 // Load new context from the "to" area. 60 61 ldr fp, [x1, #FP_OFFSET] 62 ldr x4, [x1, #SP_OFFSET] 63 mov sp, x4 // cannot store sp directly 64 65 // Load volatile GP registers x19-x30 from the stack. 66 67 ldp x19, x20, [sp, #0x00] 68 ldp x21, x22, [sp, #0x10] 69 ldp x23, x24, [sp, #0x20] 70 ldp x25, x26, [sp, #0x30] 71 ldp x27, x28, [sp, #0x40] 72 ldp x29, x30, [sp, #0x50] 73 74 // Load volatile SIMD/FPU registers d8-d15 from the stack. 75 76 ldp d8, d9, [sp, #0x60] 77 ldp d10, d11, [sp, #0x70] 78 ldp d12, d13, [sp, #0x80] 79 ldp d14, d15, [sp, #0x90] 80 81 add sp, sp, #SAVE // pop stack 82 ret // return to new thread (mov pc, x30) 83 84 .size __cfactx_switch, .-__cfactx_switch 85 .section .note.GNU-stack,"",%progbits // mark no executable stack needed 86 87 // Stub to create new stacks which can be context switched to 88 // void __cfactx_invoke_stub( void ); 12 89 13 90 .text 14 .align 2 15 .global __cfactx_switch 16 .type __cfactx_switch, %function 91 .align 2 92 .global __cfactx_invoke_stub 93 .type __cfactx_invoke_stub, @function 94 __cfactx_invoke_stub: 95 mov x0, x19 // load main as parameter 0 96 mov x1, x20 // load this as parameter 1 97 mov x30, x21 // load coroutine invoke routine 98 ret // and jmp to it (mov pc, x30) 99 .size __cfactx_invoke_stub, .-__cfactx_invoke_stub 17 100 18 __cfactx_switch: 19 @ save callee-saved registers: r4-r8, r10, r11, r13(sp) (plus r9 depending on platform specification) 20 @ I've seen reference to 31 registers on 64-bit, if this is the case, more need to be saved 21 @ save thread state registers: r14(lr) 22 @ r12(ip) is intra-procedure-call scratch register, does not need saving between function calls 23 24 #ifdef R9_SPECIAL 25 stmfd r13!, {r4-r8,r10,r11,r14} 26 #else 27 stmfd r13!, {r4-r11,r14} 28 #endif // R9_SPECIAL 29 30 @ save floating point registers: s16-s31 31 vstmdb r13!, {s16-s31} 32 33 @ save frame pointer and stack pointer to outgoing datastructure 34 str sp, [r0, #SP_OFFSET] 35 str fp, [r0, #FP_OFFSET] 36 37 @ restore frame pointer and stack pointer from incoming datastructure 38 ldr fp, [r1, #FP_OFFSET] 39 ldr sp, [r1, #SP_OFFSET] 40 41 @ restore floating point registers: s16-s31 42 vldm r13!, {s16-s31} 43 @ restore r14(lr) 44 @ restore 64-bit extra registers? 45 @ restore callee-saved registers: r4-r8, r10, r11, r13 46 47 #ifdef R9_SPECIAL 48 ldmfd r13!, {r4-r8,r10,r11,r15} 49 #else 50 ldmfd r13!, {r4-r11,r14} @ loading r14 back into r15 returns 51 52 mov r15, r14 53 #endif // R9_SPECIAL 54 55 .text 56 .align 2 57 .global __cfactx_invoke_stub 58 .type __cfactx_invoke_stub, %function 59 60 __cfactx_invoke_stub: 61 ldmfd r13!, {r0-r1} 62 mov r15, r1 101 // Local Variables: // 102 // mode: c // 103 // tab-width: 4 // 104 // End: //
Note: See TracChangeset
for help on using the changeset viewer.