Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/concurrency/invoke.c

    r5715d43 r9705ffe  
    1010// Created On       : Tue Jan 17 12:27:26 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Feb  9 16:37:42 2018
    13 // Update Count     : 5
     12// Last Modified On : Thu Aug 20 18:54:34 2020
     13// Update Count     : 30
    1414//
    1515
     
    2929// Called from the kernel when starting a coroutine or task so must switch back to user mode.
    3030
    31 extern struct $coroutine * __cfactx_cor_active(void);
    3231extern struct $coroutine * __cfactx_cor_finish(void);
    3332extern void __cfactx_cor_leave ( struct $coroutine * );
     
    3635extern void disable_interrupts() OPTIONAL_THREAD;
    3736extern 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 }
    4237
    4338void __cfactx_invoke_coroutine(
     
    114109
    115110        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 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
     111            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
    121116        };
    122117
     
    127122
    128123        fs->dummyReturn = NULL;
    129         fs->argument[0] = main;     // argument to invoke
    130         fs->argument[1] = this;     // argument to invoke
     124        fs->argument[0] = main;                                                         // argument to invoke
     125        fs->argument[1] = this;                                                         // argument to invoke
    131126        fs->rturn = invoke;
    132127
     
    134129
    135130        struct FakeStack {
    136                 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
     131                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
    139134        };
    140135
    141136        cor->context.SP = (char *)stack->base - sizeof( struct FakeStack );
    142         cor->context.FP = NULL;         // terminate stack with NULL fp
     137        cor->context.FP = NULL;                                                         // terminate stack with NULL fp
    143138
    144139        struct FakeStack *fs = (struct FakeStack *)cor->context.SP;
     
    146141        fs->dummyReturn = NULL;
    147142        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
    150145        fs->fixedRegisters[2] = invoke;
    151146
    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)
    162149        struct FakeStack {
    163                 float fpRegs[16];                       // floating point registers
    164                 void *intRegs[9];                       // integer/pointer registers
    165                 void *arg[2];                           // placeholder for this pointer
     150                float fpRegs[16];                                                               // floating point registers
     151                void * intRegs[9];                                                              // integer/pointer registers
     152                void * arg[2];                                                                  // placeholder for this pointer
    166153        };
    167154
     
    175162        fs->arg[1] = invoke;
    176163
     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;
    177181#else
    178182        #error uknown hardware architecture
Note: See TracChangeset for help on using the changeset viewer.