Changes in libcfa/src/concurrency/invoke.c [9705ffe:5715d43]
- File:
-
- 1 edited
-
libcfa/src/concurrency/invoke.c (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/invoke.c
r9705ffe r5715d43 10 10 // Created On : Tue Jan 17 12:27:26 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Aug 20 18:54:34 202013 // Update Count : 3012 // Last Modified On : Fri Feb 9 16:37:42 2018 13 // Update Count : 5 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); 31 32 extern struct $coroutine * __cfactx_cor_finish(void); 32 33 extern void __cfactx_cor_leave ( struct $coroutine * ); … … 35 36 extern void disable_interrupts() OPTIONAL_THREAD; 36 37 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 } 37 42 38 43 void __cfactx_invoke_coroutine( … … 109 114 110 115 struct FakeStack { 111 void *fixedRegisters[3]; // fixed registers ebx, edi, esi (popped on 1st uSwitch, values unimportant)112 void *rturn; // where to go on return from uSwitch113 void *dummyReturn; // fake return compiler would have pushed on call to uInvoke114 void *argument[3]; // for 16-byte ABI, 16-byte alignment starts here115 void *padding; // padding to force 16-byte alignment, as "base" is 16-byte aligned116 void *fixedRegisters[3]; // fixed registers ebx, edi, esi (popped on 1st uSwitch, values unimportant) 117 void *rturn; // where to go on return from uSwitch 118 void *dummyReturn; // fake return compiler would have pushed on call to uInvoke 119 void *argument[3]; // for 16-byte ABI, 16-byte alignment starts here 120 void *padding; // padding to force 16-byte alignment, as "base" is 16-byte aligned 116 121 }; 117 122 … … 122 127 123 128 fs->dummyReturn = NULL; 124 fs->argument[0] = main; // argument to invoke125 fs->argument[1] = this; // argument to invoke129 fs->argument[0] = main; // argument to invoke 130 fs->argument[1] = this; // argument to invoke 126 131 fs->rturn = invoke; 127 132 … … 129 134 130 135 struct FakeStack { 131 void *fixedRegisters[5]; // fixed registers rbx, r12, r13, r14, r15132 void *rturn; // where to go on return from uSwitch133 void *dummyReturn; // NULL return address to provide proper alignment136 void *fixedRegisters[5]; // fixed registers rbx, r12, r13, r14, r15 137 void *rturn; // where to go on return from uSwitch 138 void *dummyReturn; // NULL return address to provide proper alignment 134 139 }; 135 140 136 141 cor->context.SP = (char *)stack->base - sizeof( struct FakeStack ); 137 cor->context.FP = NULL; // terminate stack with NULL fp142 cor->context.FP = NULL; // terminate stack with NULL fp 138 143 139 144 struct FakeStack *fs = (struct FakeStack *)cor->context.SP; … … 141 146 fs->dummyReturn = NULL; 142 147 fs->rturn = __cfactx_invoke_stub; 143 fs->fixedRegisters[0] = main; // argument to invoke144 fs->fixedRegisters[1] = this; // argument to invoke148 fs->fixedRegisters[0] = main; 149 fs->fixedRegisters[1] = this; 145 150 fs->fixedRegisters[2] = invoke; 146 151 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) 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 149 162 struct FakeStack { 150 float fpRegs[16]; // floating point registers151 void * intRegs[9];// integer/pointer registers152 void * arg[2];// placeholder for this pointer163 float fpRegs[16]; // floating point registers 164 void *intRegs[9]; // integer/pointer registers 165 void *arg[2]; // placeholder for this pointer 153 166 }; 154 167 … … 162 175 fs->arg[1] = invoke; 163 176 164 #elif defined( __ARM_ARCH )165 struct FakeStack {166 void * intRegs[12]; // x19-x30 integer registers167 double fpRegs[8]; // v8-v15 floating point168 };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 => x0176 fs->intRegs[1] = this; // argument to invoke x20 => x1177 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 pc180 //for ( int i = 0; i < 8; i += 1 ) fs->fpRegs[i] = i + 12;181 177 #else 182 178 #error uknown hardware architecture
Note:
See TracChangeset
for help on using the changeset viewer.