Changes in libcfa/src/concurrency/invoke.c [5715d43:9705ffe]
- File:
-
- 1 edited
-
libcfa/src/concurrency/invoke.c (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/invoke.c
r5715d43 r9705ffe 10 10 // Created On : Tue Jan 17 12:27:26 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Feb 9 16:37:42 201813 // Update Count : 512 // Last Modified On : Thu Aug 20 18:54:34 2020 13 // Update Count : 30 14 14 // 15 15 … … 29 29 // Called from the kernel when starting a coroutine or task so must switch back to user mode. 30 30 31 extern struct $coroutine * __cfactx_cor_active(void);32 31 extern struct $coroutine * __cfactx_cor_finish(void); 33 32 extern void __cfactx_cor_leave ( struct $coroutine * ); … … 36 35 extern void disable_interrupts() OPTIONAL_THREAD; 37 36 extern void enable_interrupts( __cfaabi_dbg_ctx_param ); 38 39 struct exception_context_t * this_exception_context() {40 return &__get_stack( __cfactx_cor_active() )->exception_context;41 }42 37 43 38 void __cfactx_invoke_coroutine( … … 114 109 115 110 struct FakeStack { 116 void *fixedRegisters[3]; // fixed registers ebx, edi, esi (popped on 1st uSwitch, values unimportant)117 void *rturn; // where to go on return from uSwitch118 void *dummyReturn; // fake return compiler would have pushed on call to uInvoke119 void *argument[3]; // for 16-byte ABI, 16-byte alignment starts here120 void *padding; // padding to force 16-byte alignment, as "base" is 16-byte aligned111 void *fixedRegisters[3]; // fixed registers ebx, edi, esi (popped on 1st uSwitch, values unimportant) 112 void *rturn; // where to go on return from uSwitch 113 void *dummyReturn; // fake return compiler would have pushed on call to uInvoke 114 void *argument[3]; // for 16-byte ABI, 16-byte alignment starts here 115 void *padding; // padding to force 16-byte alignment, as "base" is 16-byte aligned 121 116 }; 122 117 … … 127 122 128 123 fs->dummyReturn = NULL; 129 fs->argument[0] = main; // argument to invoke130 fs->argument[1] = this; // argument to invoke124 fs->argument[0] = main; // argument to invoke 125 fs->argument[1] = this; // argument to invoke 131 126 fs->rturn = invoke; 132 127 … … 134 129 135 130 struct FakeStack { 136 void *fixedRegisters[5]; // fixed registers rbx, r12, r13, r14, r15137 void *rturn; // where to go on return from uSwitch138 void *dummyReturn; // NULL return address to provide proper alignment131 void *fixedRegisters[5]; // fixed registers rbx, r12, r13, r14, r15 132 void *rturn; // where to go on return from uSwitch 133 void *dummyReturn; // NULL return address to provide proper alignment 139 134 }; 140 135 141 136 cor->context.SP = (char *)stack->base - sizeof( struct FakeStack ); 142 cor->context.FP = NULL; // terminate stack with NULL fp137 cor->context.FP = NULL; // terminate stack with NULL fp 143 138 144 139 struct FakeStack *fs = (struct FakeStack *)cor->context.SP; … … 146 141 fs->dummyReturn = NULL; 147 142 fs->rturn = __cfactx_invoke_stub; 148 fs->fixedRegisters[0] = main; 149 fs->fixedRegisters[1] = this; 143 fs->fixedRegisters[0] = main; // argument to invoke 144 fs->fixedRegisters[1] = this; // argument to invoke 150 145 fs->fixedRegisters[2] = invoke; 151 146 152 #elif defined( __ARM_ARCH ) 153 #error ARM needs to be upgrade to use two parameters like X86/X64 (A.K.A. : I broke this and do not know how to fix it) 154 // More details about the error: 155 // To avoid the thunk problem, I changed the invoke routine to pass the main explicitly 156 // instead of relying on an assertion. This effectively hoists any required thunk one level 157 // which was enough to get to global scope in most cases. 158 // This means that __cfactx_invoke_... now takes two parameters and the FakeStack needs 159 // to be adjusted as a consequence of that. 160 // I don't know how to do that for ARM, hence the #error 161 147 #elif defined( __ARM_ARCH_32 ) 148 #warning ARM needs to be upgrade to use two parameters like X86/X64 (A.K.A. : I broke this and do not know how to fix it) 162 149 struct FakeStack { 163 float fpRegs[16]; // floating point registers164 void * intRegs[9];// integer/pointer registers165 void * arg[2];// placeholder for this pointer150 float fpRegs[16]; // floating point registers 151 void * intRegs[9]; // integer/pointer registers 152 void * arg[2]; // placeholder for this pointer 166 153 }; 167 154 … … 175 162 fs->arg[1] = invoke; 176 163 164 #elif defined( __ARM_ARCH ) 165 struct FakeStack { 166 void * intRegs[12]; // x19-x30 integer registers 167 double fpRegs[8]; // v8-v15 floating point 168 }; 169 170 cor->context.SP = (char *)stack->base - sizeof( struct FakeStack ); 171 cor->context.FP = NULL; 172 173 struct FakeStack *fs = (struct FakeStack *)cor->context.SP; 174 175 fs->intRegs[0] = main; // argument to invoke x19 => x0 176 fs->intRegs[1] = this; // argument to invoke x20 => x1 177 fs->intRegs[2] = invoke; 178 //for ( intptr_t i = 3; i < 12; i += 1 ) fs->intRegs[i] = (void *)i; 179 fs->intRegs[11] = __cfactx_invoke_stub; // link register x30 => ret moves to pc 180 //for ( int i = 0; i < 8; i += 1 ) fs->fpRegs[i] = i + 12; 177 181 #else 178 182 #error uknown hardware architecture
Note:
See TracChangeset
for help on using the changeset viewer.