diff options
| author | Mike Pall <mike> | 2011-04-16 23:26:11 +0200 |
|---|---|---|
| committer | Mike Pall <mike> | 2011-04-16 23:26:11 +0200 |
| commit | fc4021427964de06b6ba445172c7345a208a725d (patch) | |
| tree | 7b0a20871699088f9b61234850f111464f37db6b | |
| parent | 5f08a50506d47813edacd78b688af31da4bc4ce2 (diff) | |
| download | luajit-fc4021427964de06b6ba445172c7345a208a725d.tar.gz luajit-fc4021427964de06b6ba445172c7345a208a725d.tar.bz2 luajit-fc4021427964de06b6ba445172c7345a208a725d.zip | |
ARM: Add coroutine.resume/wrap_aux/yield() fast functions.
| -rw-r--r-- | src/buildvm_arm.dasc | 149 |
1 files changed, 146 insertions, 3 deletions
diff --git a/src/buildvm_arm.dasc b/src/buildvm_arm.dasc index bfa5c4ff..3e3fb23c 100644 --- a/src/buildvm_arm.dasc +++ b/src/buildvm_arm.dasc | |||
| @@ -367,7 +367,40 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 367 | |//----------------------------------------------------------------------- | 367 | |//----------------------------------------------------------------------- |
| 368 | | | 368 | | |
| 369 | |->vm_resume: // Setup C frame and resume thread. | 369 | |->vm_resume: // Setup C frame and resume thread. |
| 370 | | NYI | 370 | | // (lua_State *L, TValue *base, int nres1 = 0, ptrdiff_t ef = 0) |
| 371 | | saveregs | ||
| 372 | | mov L, CARG1 | ||
| 373 | | ldr DISPATCH, L:CARG1->glref // Setup pointer to dispatch table. | ||
| 374 | | mov BASE, CARG2 | ||
| 375 | | add DISPATCH, DISPATCH, #GG_G2DISP | ||
| 376 | | str L, SAVE_L | ||
| 377 | | mov PC, #FRAME_CP | ||
| 378 | | str CARG3, SAVE_NRES | ||
| 379 | | add CARG2, sp, #CFRAME_RESUME | ||
| 380 | | ldrb CARG1, L->status | ||
| 381 | | str CARG3, SAVE_ERRF | ||
| 382 | | str CARG2, L->cframe | ||
| 383 | | str CARG3, SAVE_CFRAME | ||
| 384 | | cmp CARG1, #0 | ||
| 385 | | str L, SAVE_PC // Any value outside of bytecode is ok. | ||
| 386 | | beq >3 | ||
| 387 | | | ||
| 388 | | // Resume after yield (like a return). | ||
| 389 | | mov RA, BASE | ||
| 390 | | ldr BASE, L->base | ||
| 391 | | ldr CARG1, L->top | ||
| 392 | | mov MASKR8, #255 | ||
| 393 | | strb CARG3, L->status | ||
| 394 | | sub RC, CARG1, BASE | ||
| 395 | | ldr PC, [BASE, FRAME_PC] | ||
| 396 | | lsl MASKR8, MASKR8, #3 // MASKR8 = 255*8. | ||
| 397 | | mv_vmstate CARG2, INTERP | ||
| 398 | | add RC, RC, #8 | ||
| 399 | | ands CARG1, PC, #FRAME_TYPE | ||
| 400 | | st_vmstate CARG2 | ||
| 401 | | str RC, SAVE_MULTRES | ||
| 402 | | beq ->BC_RET_Z | ||
| 403 | | b ->vm_return | ||
| 371 | | | 404 | | |
| 372 | |->vm_pcall: // Setup protected C frame and enter VM. | 405 | |->vm_pcall: // Setup protected C frame and enter VM. |
| 373 | | // (lua_State *L, TValue *base, int nres1, ptrdiff_t ef) | 406 | | // (lua_State *L, TValue *base, int nres1, ptrdiff_t ef) |
| @@ -1046,17 +1079,127 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 1046 | |.macro coroutine_resume_wrap, resume | 1079 | |.macro coroutine_resume_wrap, resume |
| 1047 | |.if resume | 1080 | |.if resume |
| 1048 | |.ffunc_1 coroutine_resume | 1081 | |.ffunc_1 coroutine_resume |
| 1082 | | checktp CARG2, LJ_TTHREAD | ||
| 1083 | | bne ->fff_fallback | ||
| 1049 | |.else | 1084 | |.else |
| 1050 | |.ffunc coroutine_wrap_aux | 1085 | |.ffunc coroutine_wrap_aux |
| 1086 | | ldr L:CARG1, CFUNC:CARG3->upvalue[0].gcr | ||
| 1051 | |.endif | 1087 | |.endif |
| 1052 | | NYI | 1088 | | ldr PC, [BASE, FRAME_PC] |
| 1089 | | str BASE, L->base | ||
| 1090 | | ldr CARG2, L:CARG1->top | ||
| 1091 | | ldrb RA, L:CARG1->status | ||
| 1092 | | ldr RB, L:CARG1->base | ||
| 1093 | | add CARG3, CARG2, NARGS8:RC | ||
| 1094 | | add CARG4, CARG2, RA | ||
| 1095 | | str PC, SAVE_PC | ||
| 1096 | | cmp CARG4, RB | ||
| 1097 | | beq ->fff_fallback | ||
| 1098 | | ldr CARG4, L:CARG1->maxstack | ||
| 1099 | | ldr RB, L:CARG1->cframe | ||
| 1100 | | cmp RA, #LUA_YIELD | ||
| 1101 | | cmpls CARG3, CARG4 | ||
| 1102 | | cmpls RB, #0 | ||
| 1103 | | bhi ->fff_fallback | ||
| 1104 | |1: | ||
| 1105 | |.if resume | ||
| 1106 | | sub CARG3, CARG3, #8 // Keep resumed thread in stack for GC. | ||
| 1107 | | add BASE, BASE, #8 | ||
| 1108 | | sub NARGS8:RC, NARGS8:RC, #8 | ||
| 1109 | |.endif | ||
| 1110 | | str CARG3, L:CARG1->top | ||
| 1111 | | str BASE, L->top | ||
| 1112 | |2: // Move args to coroutine. | ||
| 1113 | | ldrd CARG34, [BASE, RB] | ||
| 1114 | | cmp RB, NARGS8:RC | ||
| 1115 | | strdne CARG34, [CARG2, RB] | ||
| 1116 | | add RB, RB, #8 | ||
| 1117 | | bne <2 | ||
| 1118 | | | ||
| 1119 | | mov CARG3, #0 | ||
| 1120 | | mov L:RA, L:CARG1 | ||
| 1121 | | mov CARG4, #0 | ||
| 1122 | | bl ->vm_resume // (lua_State *L, TValue *base, 0, 0) | ||
| 1123 | | // Returns thread status. | ||
| 1124 | |4: | ||
| 1125 | | ldr CARG3, L:RA->base | ||
| 1126 | | mv_vmstate CARG2, INTERP | ||
| 1127 | | ldr CARG4, L:RA->top | ||
| 1128 | | st_vmstate CARG2 | ||
| 1129 | | cmp CRET1, #LUA_YIELD | ||
| 1130 | | ldr BASE, L->base | ||
| 1131 | | bhi >8 | ||
| 1132 | | subs RC, CARG4, CARG3 | ||
| 1133 | | ldr CARG1, L->maxstack | ||
| 1134 | | add CARG2, BASE, RC | ||
| 1135 | | beq >6 // No results? | ||
| 1136 | | cmp CARG2, CARG1 | ||
| 1137 | | mov RB, #0 | ||
| 1138 | | bhi >9 // Need to grow stack? | ||
| 1139 | | | ||
| 1140 | | sub CARG4, RC, #8 | ||
| 1141 | | str CARG3, L:RA->top // Clear coroutine stack. | ||
| 1142 | |5: // Move results from coroutine. | ||
| 1143 | | ldrd CARG12, [CARG3, RB] | ||
| 1144 | | cmp RB, CARG4 | ||
| 1145 | | strd CARG12, [BASE, RB] | ||
| 1146 | | add RB, RB, #8 | ||
| 1147 | | bne <5 | ||
| 1148 | |6: | ||
| 1149 | |.if resume | ||
| 1150 | | mvn CARG3, #~LJ_TTRUE | ||
| 1151 | | add RC, RC, #16 | ||
| 1152 | |7: | ||
| 1153 | | str CARG3, [BASE, #-4] // Prepend true/false to results. | ||
| 1154 | | sub RA, BASE, #8 | ||
| 1155 | |.else | ||
| 1156 | | mov RA, BASE | ||
| 1157 | | add RC, RC, #8 | ||
| 1158 | |.endif | ||
| 1159 | | ands CARG1, PC, #FRAME_TYPE | ||
| 1160 | | str PC, SAVE_PC | ||
| 1161 | | str RC, SAVE_MULTRES | ||
| 1162 | | beq ->BC_RET_Z | ||
| 1163 | | b ->vm_return | ||
| 1164 | | | ||
| 1165 | |8: // Coroutine returned with error (at co->top-1). | ||
| 1166 | |.if resume | ||
| 1167 | | ldrd CARG12, [CARG4, #-8]! | ||
| 1168 | | mvn CARG3, #~LJ_TFALSE | ||
| 1169 | | mov RC, #(2+1)*8 | ||
| 1170 | | str CARG4, L:RA->top // Remove error from coroutine stack. | ||
| 1171 | | strd CARG12, [BASE] // Copy error message. | ||
| 1172 | | b <7 | ||
| 1173 | |.else | ||
| 1174 | | mov CARG1, L | ||
| 1175 | | mov CARG2, L:RA | ||
| 1176 | | bl extern lj_ffh_coroutine_wrap_err // (lua_State *L, lua_State *co) | ||
| 1177 | | // Never returns. | ||
| 1178 | |.endif | ||
| 1179 | | | ||
| 1180 | |9: // Handle stack expansion on return from yield. | ||
| 1181 | | mov CARG1, L | ||
| 1182 | | lsr CARG2, RC, #3 | ||
| 1183 | | bl extern lj_state_growstack // (lua_State *L, int n) | ||
| 1184 | | mov CRET1, #0 | ||
| 1185 | | b <4 | ||
| 1053 | |.endmacro | 1186 | |.endmacro |
| 1054 | | | 1187 | | |
| 1055 | | coroutine_resume_wrap 1 // coroutine.resume | 1188 | | coroutine_resume_wrap 1 // coroutine.resume |
| 1056 | | coroutine_resume_wrap 0 // coroutine.wrap | 1189 | | coroutine_resume_wrap 0 // coroutine.wrap |
| 1057 | | | 1190 | | |
| 1058 | |.ffunc coroutine_yield | 1191 | |.ffunc coroutine_yield |
| 1059 | | NYI | 1192 | | ldr CARG1, L->cframe |
| 1193 | | add CARG2, BASE, NARGS8:RC | ||
| 1194 | | str BASE, L->base | ||
| 1195 | | tst CARG1, #CFRAME_RESUME | ||
| 1196 | | str CARG2, L->top | ||
| 1197 | | mov CRET1, #LUA_YIELD | ||
| 1198 | | mov CARG3, #0 | ||
| 1199 | | beq ->fff_fallback | ||
| 1200 | | str CARG3, L->cframe | ||
| 1201 | | strb CRET1, L->status | ||
| 1202 | | b ->vm_leave_unw | ||
| 1060 | | | 1203 | | |
| 1061 | |//-- Math library ------------------------------------------------------- | 1204 | |//-- Math library ------------------------------------------------------- |
| 1062 | | | 1205 | | |
