aboutsummaryrefslogtreecommitdiff
path: root/src/buildvm_x86.dasc
diff options
context:
space:
mode:
authorMike Pall <mike>2009-12-19 17:25:54 +0100
committerMike Pall <mike>2009-12-19 17:25:54 +0100
commita1d4d05f2ce7ed3c8ab0978ffb3b6055ceaaa7eb (patch)
tree2e4d8193f8db8e814692e947e38f063afb4c583a /src/buildvm_x86.dasc
parented8d86bf665fbeba28350da1ad8f981b7348a26a (diff)
downloadluajit-a1d4d05f2ce7ed3c8ab0978ffb3b6055ceaaa7eb.tar.gz
luajit-a1d4d05f2ce7ed3c8ab0978ffb3b6055ceaaa7eb.tar.bz2
luajit-a1d4d05f2ce7ed3c8ab0978ffb3b6055ceaaa7eb.zip
Adapt most outbound calls in interpreter to x64 calling conventions.
Diffstat (limited to 'src/buildvm_x86.dasc')
-rw-r--r--src/buildvm_x86.dasc236
1 files changed, 204 insertions, 32 deletions
diff --git a/src/buildvm_x86.dasc b/src/buildvm_x86.dasc
index 02fe461b..960afa1d 100644
--- a/src/buildvm_x86.dasc
+++ b/src/buildvm_x86.dasc
@@ -55,6 +55,8 @@
55|.define CARG2d, edx 55|.define CARG2d, edx
56|.define CARG3d, r8d 56|.define CARG3d, r8d
57|.define CARG4d, r9d 57|.define CARG4d, r9d
58|.define FCARG1, CARG1d // Upwards compatible to x86 fastcall.
59|.define FCARG2, CARG2d
58|.else 60|.else
59|.define CARG1, rsi // x64/POSIX C call arguments. 61|.define CARG1, rsi // x64/POSIX C call arguments.
60|.define CARG2, rdi 62|.define CARG2, rdi
@@ -68,6 +70,8 @@
68|.define CARG4d, ecx 70|.define CARG4d, ecx
69|.define CARG5d, r8d 71|.define CARG5d, r8d
70|.define CARG6d, r9d 72|.define CARG6d, r9d
73|.define FCARG1, CARG1d // Simulate x86 fastcall.
74|.define FCARG2, CARG2d
71|.endif 75|.endif
72| 76|
73|// Type definitions. Some of these are only used for documentation. 77|// Type definitions. Some of these are only used for documentation.
@@ -154,7 +158,7 @@
154| pop rbx; pop rsi; pop rdi; pop rbp 158| pop rbx; pop rsi; pop rdi; pop rbp
155|.endmacro 159|.endmacro
156| 160|
157|.define UNUSED1, aword [rsp+dword*26] 161|.define SAVE_CFRAME, aword [rsp+aword*13]
158|.define SAVE_PC, dword [rsp+dword*25] 162|.define SAVE_PC, dword [rsp+dword*25]
159|.define SAVE_L, dword [rsp+dword*24] 163|.define SAVE_L, dword [rsp+dword*24]
160|.define SAVE_ERRF, dword [rsp+dword*23] 164|.define SAVE_ERRF, dword [rsp+dword*23]
@@ -167,7 +171,7 @@
167|.define SAVE_R3, aword [rsp+aword*7] 171|.define SAVE_R3, aword [rsp+aword*7]
168|.define SAVE_R2, aword [rsp+aword*6] 172|.define SAVE_R2, aword [rsp+aword*6]
169|.define SAVE_R1, aword [rsp+aword*5] //<-- rsp after register saves. 173|.define SAVE_R1, aword [rsp+aword*5] //<-- rsp after register saves.
170|.define SAVE_CFRAME, aword [rsp+aword*4] 174|.define ARG5, aword [rsp+aword*4]
171|.define CSAVE_4, aword [rsp+aword*3] 175|.define CSAVE_4, aword [rsp+aword*3]
172|.define CSAVE_3, aword [rsp+aword*2] 176|.define CSAVE_3, aword [rsp+aword*2]
173|.define CSAVE_2, aword [rsp+aword*1] 177|.define CSAVE_2, aword [rsp+aword*1]
@@ -175,8 +179,9 @@
175|//----- 16 byte aligned, ^^^ 32 byte register save area, owned by callee 179|//----- 16 byte aligned, ^^^ 32 byte register save area, owned by callee
176| 180|
177|// TMPQ overlaps TMP1/TMP2. NRESULTS overlaps TMP2 (and TMPQ). 181|// TMPQ overlaps TMP1/TMP2. NRESULTS overlaps TMP2 (and TMPQ).
178|.define TMPQ, qword [rsp] 182|.define TMPQ, qword [rsp+aword*10]
179|.define NRESULTS, TMP2 183|.define NRESULTS, TMP2
184|.define ARG5d, dword [rsp+aword*4]
180| 185|
181|//----------------------------------------------------------------------- 186|//-----------------------------------------------------------------------
182|.else // x64/POSIX stack layout 187|.else // x64/POSIX stack layout
@@ -869,12 +874,20 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
869 | movzx RB, PC_RB // Reload TValue *t from RB. 874 | movzx RB, PC_RB // Reload TValue *t from RB.
870 | lea RB, [BASE+RB*8] 875 | lea RB, [BASE+RB*8]
871 |2: 876 |2:
877 |.if X64
878 | mov L:CARG1d, SAVE_L
879 | mov L:CARG1d->base, BASE // Caveat: CARG2d/CARG3d may be BASE.
880 | mov CARG2d, RB
881 | mov CARG3d, RC
882 | mov L:RB, L:CARG1d
883 |.else
872 | mov ARG2, RB 884 | mov ARG2, RB
873 | mov L:RB, SAVE_L 885 | mov L:RB, SAVE_L
874 | mov ARG3, RC 886 | mov ARG3, RC
875 | mov ARG1, L:RB 887 | mov ARG1, L:RB
876 | mov SAVE_PC, PC
877 | mov L:RB->base, BASE 888 | mov L:RB->base, BASE
889 |.endif
890 | mov SAVE_PC, PC
878 | call extern lj_meta_tget // (lua_State *L, TValue *o, TValue *k) 891 | call extern lj_meta_tget // (lua_State *L, TValue *o, TValue *k)
879 | // TValue * (finished) or NULL (metamethod) returned in eax (RC). 892 | // TValue * (finished) or NULL (metamethod) returned in eax (RC).
880 | mov BASE, L:RB->base 893 | mov BASE, L:RB->base
@@ -927,12 +940,20 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
927 | movzx RB, PC_RB // Reload TValue *t from RB. 940 | movzx RB, PC_RB // Reload TValue *t from RB.
928 | lea RB, [BASE+RB*8] 941 | lea RB, [BASE+RB*8]
929 |2: 942 |2:
943 |.if X64
944 | mov L:CARG1d, SAVE_L
945 | mov L:CARG1d->base, BASE // Caveat: CARG2d/CARG3d may be BASE.
946 | mov CARG2d, RB
947 | mov CARG3d, RC
948 | mov L:RB, L:CARG1d
949 |.else
930 | mov ARG2, RB 950 | mov ARG2, RB
931 | mov L:RB, SAVE_L 951 | mov L:RB, SAVE_L
932 | mov ARG3, RC 952 | mov ARG3, RC
933 | mov ARG1, L:RB 953 | mov ARG1, L:RB
934 | mov SAVE_PC, PC
935 | mov L:RB->base, BASE 954 | mov L:RB->base, BASE
955 |.endif
956 | mov SAVE_PC, PC
936 | call extern lj_meta_tset // (lua_State *L, TValue *o, TValue *k) 957 | call extern lj_meta_tset // (lua_State *L, TValue *o, TValue *k)
937 | // TValue * (finished) or NULL (metamethod) returned in eax (RC). 958 | // TValue * (finished) or NULL (metamethod) returned in eax (RC).
938 | mov BASE, L:RB->base 959 | mov BASE, L:RB->base
@@ -965,6 +986,19 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
965 |//-- Comparison metamethods --------------------------------------------- 986 |//-- Comparison metamethods ---------------------------------------------
966 | 987 |
967 |->vmeta_comp: 988 |->vmeta_comp:
989 |.if X64
990 | mov L:RB, SAVE_L
991 | mov L:RB->base, BASE // Caveat: CARG2d/CARG3d == BASE.
992 |.if X64WIN
993 | lea CARG3d, [BASE+RD*8]
994 | lea CARG2d, [BASE+RA*8]
995 |.else
996 | lea CARG2d, [BASE+RA*8]
997 | lea CARG3d, [BASE+RD*8]
998 |.endif
999 | mov CARG1d, L:RB // Caveat: CARG1d/CARG4d == RA.
1000 | movzx CARG4d, PC_OP
1001 |.else
968 | movzx RB, PC_OP 1002 | movzx RB, PC_OP
969 | lea RD, [BASE+RD*8] 1003 | lea RD, [BASE+RD*8]
970 | lea RA, [BASE+RA*8] 1004 | lea RA, [BASE+RA*8]
@@ -973,8 +1007,9 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
973 | mov ARG3, RD 1007 | mov ARG3, RD
974 | mov ARG2, RA 1008 | mov ARG2, RA
975 | mov ARG1, L:RB 1009 | mov ARG1, L:RB
976 | mov SAVE_PC, PC
977 | mov L:RB->base, BASE 1010 | mov L:RB->base, BASE
1011 |.endif
1012 | mov SAVE_PC, PC
978 | call extern lj_meta_comp // (lua_State *L, TValue *o1, *o2, int op) 1013 | call extern lj_meta_comp // (lua_State *L, TValue *o1, *o2, int op)
979 | // 0/1 or TValue * (metamethod) returned in eax (RC). 1014 | // 0/1 or TValue * (metamethod) returned in eax (RC).
980 |3: 1015 |3:
@@ -1001,14 +1036,30 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
1001 | jmp <4 1036 | jmp <4
1002 | 1037 |
1003 |->vmeta_equal: 1038 |->vmeta_equal:
1039 | sub PC, 4
1040 |.if X64WIN
1041 | mov CARG3d, RD
1042 | mov CARG4d, RB
1043 | mov L:RB, SAVE_L
1044 | mov L:RB->base, BASE // Caveat: CARG2d == BASE.
1045 | mov CARG2d, RA
1046 | mov CARG1d, L:RB // Caveat: CARG1d == RA.
1047 |.elif X64
1048 | mov CARG2d, RA
1049 | mov CARG4d, RB // Caveat: CARG4d == RA.
1050 | mov L:RB, SAVE_L
1051 | mov L:RB->base, BASE // Caveat: CARG3d == BASE.
1052 | mov CARG3d, RD
1053 | mov CARG1d, L:RB
1054 |.else
1004 | mov ARG4, RB 1055 | mov ARG4, RB
1005 | mov L:RB, SAVE_L 1056 | mov L:RB, SAVE_L
1006 | sub PC, 4
1007 | mov ARG3, RD 1057 | mov ARG3, RD
1008 | mov ARG2, RA 1058 | mov ARG2, RA
1009 | mov ARG1, L:RB 1059 | mov ARG1, L:RB
1010 | mov SAVE_PC, PC
1011 | mov L:RB->base, BASE 1060 | mov L:RB->base, BASE
1061 |.endif
1062 | mov SAVE_PC, PC
1012 | call extern lj_meta_equal // (lua_State *L, GCobj *o1, *o2, int ne) 1063 | call extern lj_meta_equal // (lua_State *L, GCobj *o1, *o2, int ne)
1013 | // 0/1 or TValue * (metamethod) returned in eax (RC). 1064 | // 0/1 or TValue * (metamethod) returned in eax (RC).
1014 | jmp <3 1065 | jmp <3
@@ -1036,6 +1087,24 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
1036 | lea RB, [BASE+RB*8] 1087 | lea RB, [BASE+RB*8]
1037 |2: 1088 |2:
1038 | lea RA, [BASE+RA*8] 1089 | lea RA, [BASE+RA*8]
1090 |.if X64WIN
1091 | mov CARG3d, RB
1092 | mov CARG4d, RC
1093 | movzx RC, PC_OP
1094 | mov ARG5d, RC
1095 | mov L:RB, SAVE_L
1096 | mov L:RB->base, BASE // Caveat: CARG2d == BASE.
1097 | mov CARG2d, RA
1098 | mov CARG1d, L:RB // Caveat: CARG1d == RA.
1099 |.elif X64
1100 | movzx CARG5d, PC_OP
1101 | mov CARG2d, RA
1102 | mov CARG4d, RC // Caveat: CARG4d == RA.
1103 | mov L:CARG1d, SAVE_L
1104 | mov L:CARG1d->base, BASE // Caveat: CARG3d == BASE.
1105 | mov CARG3d, RB
1106 | mov L:RB, L:CARG1d
1107 |.else
1039 | mov ARG3, RB 1108 | mov ARG3, RB
1040 | mov L:RB, SAVE_L 1109 | mov L:RB, SAVE_L
1041 | mov ARG4, RC 1110 | mov ARG4, RC
@@ -1043,8 +1112,9 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
1043 | mov ARG2, RA 1112 | mov ARG2, RA
1044 | mov ARG5, RC 1113 | mov ARG5, RC
1045 | mov ARG1, L:RB 1114 | mov ARG1, L:RB
1046 | mov SAVE_PC, PC
1047 | mov L:RB->base, BASE 1115 | mov L:RB->base, BASE
1116 |.endif
1117 | mov SAVE_PC, PC
1048 | call extern lj_meta_arith // (lua_State *L, TValue *ra,*rb,*rc, BCReg op) 1118 | call extern lj_meta_arith // (lua_State *L, TValue *ra,*rb,*rc, BCReg op)
1049 | // NULL (finished) or TValue * (metamethod) returned in eax (RC). 1119 | // NULL (finished) or TValue * (metamethod) returned in eax (RC).
1050 | mov BASE, L:RB->base 1120 | mov BASE, L:RB->base
@@ -1065,12 +1135,19 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
1065 | jmp aword LFUNC:RB->gate 1135 | jmp aword LFUNC:RB->gate
1066 | 1136 |
1067 |->vmeta_len: 1137 |->vmeta_len:
1138 |.if X64
1139 | mov L:RB, SAVE_L
1140 | mov L:RB->base, BASE // Caveat: CARG2d may be BASE.
1141 | lea CARG2d, [BASE+RD*8]
1142 | mov CARG1d, L:RB
1143 |.else
1068 | lea RD, [BASE+RD*8] 1144 | lea RD, [BASE+RD*8]
1069 | mov L:RB, SAVE_L 1145 | mov L:RB, SAVE_L
1070 | mov ARG2, RD 1146 | mov ARG2, RD
1071 | mov ARG1, L:RB 1147 | mov ARG1, L:RB
1072 | mov SAVE_PC, PC
1073 | mov L:RB->base, BASE 1148 | mov L:RB->base, BASE
1149 |.endif
1150 | mov SAVE_PC, PC
1074 | call extern lj_meta_len // (lua_State *L, TValue *o) 1151 | call extern lj_meta_len // (lua_State *L, TValue *o)
1075 | // TValue * (metamethod) returned in eax (RC). 1152 | // TValue * (metamethod) returned in eax (RC).
1076 | mov BASE, L:RB->base 1153 | mov BASE, L:RB->base
@@ -1083,13 +1160,21 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
1083 | mov TMP2, RA // Save RA, RC for us. 1160 | mov TMP2, RA // Save RA, RC for us.
1084 | mov TMP1, NARGS:RC 1161 | mov TMP1, NARGS:RC
1085 | sub RA, 8 1162 | sub RA, 8
1163 |.if X64
1164 | mov L:RB, SAVE_L
1165 | mov L:RB->base, BASE // Caveat: CARG2d/CARG3d may be BASE.
1166 | mov CARG2d, RA
1167 | lea CARG3d, [RA+NARGS:RC*8]
1168 | mov CARG1d, L:RB // Caveat: CARG1d may be RA.
1169 |.else
1086 | lea RC, [RA+NARGS:RC*8] 1170 | lea RC, [RA+NARGS:RC*8]
1087 | mov L:RB, SAVE_L 1171 | mov L:RB, SAVE_L
1088 | mov ARG2, RA 1172 | mov ARG2, RA
1089 | mov ARG3, RC 1173 | mov ARG3, RC
1090 | mov ARG1, L:RB 1174 | mov ARG1, L:RB
1091 | mov SAVE_PC, PC
1092 | mov L:RB->base, BASE // This is the callers base! 1175 | mov L:RB->base, BASE // This is the callers base!
1176 |.endif
1177 | mov SAVE_PC, PC
1093 | call extern lj_meta_call // (lua_State *L, TValue *func, TValue *top) 1178 | call extern lj_meta_call // (lua_State *L, TValue *func, TValue *top)
1094 | mov BASE, L:RB->base 1179 | mov BASE, L:RB->base
1095 | mov RA, TMP2 1180 | mov RA, TMP2
@@ -1104,11 +1189,18 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
1104 |//-- Argument coercion for 'for' statement ------------------------------ 1189 |//-- Argument coercion for 'for' statement ------------------------------
1105 | 1190 |
1106 |->vmeta_for: 1191 |->vmeta_for:
1192 |.if X64
1193 | mov L:RB, SAVE_L
1194 | mov L:RB->base, BASE // Caveat: CARG2d may be BASE.
1195 | mov CARG2d, RA
1196 | mov CARG1d, L:RB // Caveat: CARG1d may be RA.
1197 |.else
1107 | mov L:RB, SAVE_L 1198 | mov L:RB, SAVE_L
1108 | mov ARG2, RA 1199 | mov ARG2, RA
1109 | mov ARG1, L:RB 1200 | mov ARG1, L:RB
1110 | mov SAVE_PC, PC
1111 | mov L:RB->base, BASE 1201 | mov L:RB->base, BASE
1202 |.endif
1203 | mov SAVE_PC, PC
1112 | call extern lj_meta_for // (lua_State *L, TValue *base) 1204 | call extern lj_meta_for // (lua_State *L, TValue *base)
1113 | mov BASE, L:RB->base 1205 | mov BASE, L:RB->base
1114 | mov RC, [PC-4] 1206 | mov RC, [PC-4]
@@ -1184,7 +1276,7 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
1184 | mov [RA-8], RB 1276 | mov [RA-8], RB
1185 | sub RD, 2 1277 | sub RD, 2
1186 | jz >2 1278 | jz >2
1187 | mov ARG1, RA 1279 | mov TMP1, RA
1188 |1: 1280 |1:
1189 | add RA, 8 1281 | add RA, 8
1190 | mov RB, [RA+4] 1282 | mov RB, [RA+4]
@@ -1193,7 +1285,7 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
1193 | mov [RA-8], RB 1285 | mov [RA-8], RB
1194 | sub RD, 1 1286 | sub RD, 1
1195 | jnz <1 1287 | jnz <1
1196 | mov RA, ARG1 1288 | mov RA, TMP1
1197 |2: 1289 |2:
1198 | mov RD, NRESULTS 1290 | mov RD, NRESULTS
1199 | jmp ->fff_res_ 1291 | jmp ->fff_res_
@@ -1230,7 +1322,7 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
1230 | mov STR:RC, [DISPATCH+DISPATCH_GL(mmname)+4*MM_metatable] 1322 | mov STR:RC, [DISPATCH+DISPATCH_GL(mmname)+4*MM_metatable]
1231 | mov dword [RA-4], LJ_TTAB // Store metatable as default result. 1323 | mov dword [RA-4], LJ_TTAB // Store metatable as default result.
1232 | mov [RA-8], TAB:RB 1324 | mov [RA-8], TAB:RB
1233 | mov ARG1, RA // Save result pointer. 1325 | mov TMP1, RA // Save result pointer.
1234 | mov RA, TAB:RB->hmask 1326 | mov RA, TAB:RB->hmask
1235 | and RA, STR:RC->hash 1327 | and RA, STR:RC->hash
1236 | imul RA, #NODE 1328 | imul RA, #NODE
@@ -1249,7 +1341,7 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
1249 | mov RB, [RA+4] 1341 | mov RB, [RA+4]
1250 | cmp RB, LJ_TNIL; je ->fff_res1 // Dito for nil value. 1342 | cmp RB, LJ_TNIL; je ->fff_res1 // Dito for nil value.
1251 | mov RC, [RA] 1343 | mov RC, [RA]
1252 | mov RA, ARG1 // Restore result pointer. 1344 | mov RA, TMP1 // Restore result pointer.
1253 | mov [RA-4], RB // Return value of mt.__metatable. 1345 | mov [RA-4], RB // Return value of mt.__metatable.
1254 | mov [RA-8], RC 1346 | mov [RA-8], RC
1255 | jmp ->fff_res1 1347 | jmp ->fff_res1
@@ -1282,6 +1374,13 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
1282 | 1374 |
1283 |.ffunc_2 rawget 1375 |.ffunc_2 rawget
1284 | cmp dword [RA+4], LJ_TTAB; jne ->fff_fallback 1376 | cmp dword [RA+4], LJ_TTAB; jne ->fff_fallback
1377 |.if X64
1378 | mov TMP1, BASE // Save BASE and RA.
1379 | mov RB, RA
1380 | mov CARG2d, [RA]
1381 | lea CARG3d, [RA+8]
1382 | mov CARG1d, SAVE_L // Caveat: CARG1d may be RA.
1383 |.else
1285 | mov TAB:RC, [RA] 1384 | mov TAB:RC, [RA]
1286 | mov L:RB, SAVE_L 1385 | mov L:RB, SAVE_L
1287 | mov ARG2, TAB:RC 1386 | mov ARG2, TAB:RC
@@ -1290,6 +1389,7 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
1290 | mov TMP1, BASE // Save BASE and RA. 1389 | mov TMP1, BASE // Save BASE and RA.
1291 | add RA, 8 1390 | add RA, 8
1292 | mov ARG3, RA 1391 | mov ARG3, RA
1392 |.endif
1293 | call extern lj_tab_get // (lua_State *L, GCtab *t, cTValue *key) 1393 | call extern lj_tab_get // (lua_State *L, GCtab *t, cTValue *key)
1294 | // cTValue * returned in eax (RC). 1394 | // cTValue * returned in eax (RC).
1295 | mov RA, RB 1395 | mov RA, RB
@@ -1327,13 +1427,13 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
1327 | mov L:RB->base, RA // Add frame since C call can throw. 1427 | mov L:RB->base, RA // Add frame since C call can throw.
1328 | mov [RA-4], PC 1428 | mov [RA-4], PC
1329 | mov SAVE_PC, PC // Redundant (but a defined value). 1429 | mov SAVE_PC, PC // Redundant (but a defined value).
1330 | mov ARG3, BASE // Save BASE. 1430 | mov TMP1, BASE // Save BASE.
1331 | mov FCARG2, RA // Caveat: FCARG2 == BASE 1431 | mov FCARG2, RA // Caveat: FCARG2 == BASE
1332 | mov L:FCARG1, L:RB // Caveat: FCARG1 == RA 1432 | mov L:FCARG1, L:RB // Caveat: FCARG1 == RA
1333 | call extern lj_str_fromnum@8 // (lua_State *L, lua_Number *np) 1433 | call extern lj_str_fromnum@8 // (lua_State *L, lua_Number *np)
1334 | // GCstr returned in eax (RC). 1434 | // GCstr returned in eax (RC).
1335 | mov RA, L:RB->base 1435 | mov RA, L:RB->base
1336 | mov BASE, ARG3 1436 | mov BASE, TMP1
1337 | jmp <2 1437 | jmp <2
1338 | 1438 |
1339 |//-- Base library: iterators ------------------------------------------- 1439 |//-- Base library: iterators -------------------------------------------
@@ -1342,16 +1442,26 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
1342 | je >2 // Missing 2nd arg? 1442 | je >2 // Missing 2nd arg?
1343 |1: 1443 |1:
1344 | cmp dword [RA+4], LJ_TTAB; jne ->fff_fallback 1444 | cmp dword [RA+4], LJ_TTAB; jne ->fff_fallback
1445 |.if X64
1446 | mov CARG2d, [RA]
1447 | mov L:RB, SAVE_L
1448 | mov L:RB->base, RA // Add frame since C call can throw.
1449 | mov [RA-4], PC
1450 | mov TMP1, BASE // Save BASE.
1451 | lea CARG3d, [RA+8]
1452 | mov CARG1d, L:RB // Caveat: CARG1d may be RA.
1453 |.else
1345 | mov TAB:RB, [RA] 1454 | mov TAB:RB, [RA]
1346 | mov ARG2, TAB:RB 1455 | mov ARG2, TAB:RB
1347 | mov L:RB, SAVE_L 1456 | mov L:RB, SAVE_L
1348 | mov ARG1, L:RB 1457 | mov ARG1, L:RB
1349 | mov L:RB->base, RA // Add frame since C call can throw. 1458 | mov L:RB->base, RA // Add frame since C call can throw.
1350 | mov [RA-4], PC 1459 | mov [RA-4], PC
1351 | mov SAVE_PC, PC // Redundant (but a defined value).
1352 | mov TMP1, BASE // Save BASE. 1460 | mov TMP1, BASE // Save BASE.
1353 | add RA, 8 1461 | add RA, 8
1354 | mov ARG3, RA 1462 | mov ARG3, RA
1463 |.endif
1464 | mov SAVE_PC, PC // Redundant (but a defined value).
1355 | call extern lj_tab_next // (lua_State *L, GCtab *t, TValue *key) 1465 | call extern lj_tab_next // (lua_State *L, GCtab *t, TValue *key)
1356 | // Flag returned in eax (RC). 1466 | // Flag returned in eax (RC).
1357 | mov RA, L:RB->base 1467 | mov RA, L:RB->base
@@ -1390,7 +1500,7 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
1390 | fld qword [RA+8] 1500 | fld qword [RA+8]
1391 | fld1 1501 | fld1
1392 | faddp st1 1502 | faddp st1
1393 | fist ARG2 1503 | fist ARG2 // Caveat: used in getinth call, too.
1394 | fstp qword [RA-8] 1504 | fstp qword [RA-8]
1395 | mov TAB:RB, [RA] 1505 | mov TAB:RB, [RA]
1396 | mov RC, ARG2 1506 | mov RC, ARG2
@@ -1406,13 +1516,17 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
1406 | jmp ->fff_res2 1516 | jmp ->fff_res2
1407 |2: // Check for empty hash part first. Otherwise call C function. 1517 |2: // Check for empty hash part first. Otherwise call C function.
1408 | cmp dword TAB:RB->hmask, 0; je ->fff_res0 1518 | cmp dword TAB:RB->hmask, 0; je ->fff_res0
1519 |.if X64
1520 | mov CARG1d, TAB:RB
1521 |.else
1409 | mov ARG1, TAB:RB 1522 | mov ARG1, TAB:RB
1410 | mov ARG3, BASE // Save BASE and RA. 1523 |.endif
1524 | mov TMP1, BASE // Save BASE and RA.
1411 | mov RB, RA 1525 | mov RB, RA
1412 | call extern lj_tab_getinth // (GCtab *t, int32_t key) 1526 | call extern lj_tab_getinth // (GCtab *t, int32_t key)
1413 | // cTValue * or NULL returned in eax (RC). 1527 | // cTValue * or NULL returned in eax (RC).
1414 | mov RA, RB 1528 | mov RA, RB
1415 | mov BASE, ARG3 1529 | mov BASE, TMP1
1416 | test RC, RC 1530 | test RC, RC
1417 | jnz <1 1531 | jnz <1
1418 |->fff_res0: 1532 |->fff_res0:
@@ -1481,14 +1595,22 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
1481 |.endif 1595 |.endif
1482 | mov [RA-4], PC 1596 | mov [RA-4], PC
1483 | mov SAVE_PC, PC 1597 | mov SAVE_PC, PC
1598 |.if X64
1599 | mov TMP1, L:RB
1600 |.else
1484 | mov ARG1, L:RB 1601 | mov ARG1, L:RB
1602 |.endif
1485 |.if resume 1603 |.if resume
1486 | cmp dword [RA+4], LJ_TTHREAD; jne <9 1604 | cmp dword [RA+4], LJ_TTHREAD; jne <9
1487 |.endif 1605 |.endif
1488 | cmp aword L:RB->cframe, 0; jne <9 1606 | cmp aword L:RB->cframe, 0; jne <9
1489 | cmp byte L:RB->status, LUA_YIELD; ja <9 1607 | cmp byte L:RB->status, LUA_YIELD; ja <9
1490 | mov PC, L:RB->top 1608 | mov PC, L:RB->top
1609 |.if X64
1610 | mov TMP2, PC
1611 |.else
1491 | mov ARG2, PC 1612 | mov ARG2, PC
1613 |.endif
1492 | je >1 // Status != LUA_YIELD (i.e. 0)? 1614 | je >1 // Status != LUA_YIELD (i.e. 0)?
1493 | cmp PC, L:RB->base; je <9 // Check for presence of initial func. 1615 | cmp PC, L:RB->base; je <9 // Check for presence of initial func.
1494 |1: 1616 |1:
@@ -1506,7 +1628,11 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
1506 | add RA, 8 // Keep resumed thread in stack for GC. 1628 | add RA, 8 // Keep resumed thread in stack for GC.
1507 |.endif 1629 |.endif
1508 | mov L:RB->top, RA 1630 | mov L:RB->top, RA
1631 |.if X64
1632 | mov RB, TMP2
1633 |.else
1509 | mov RB, ARG2 1634 | mov RB, ARG2
1635 |.endif
1510 |.if resume 1636 |.if resume
1511 | lea RA, [RA+NARGS:RC*8-24] // RA = end of source for stack move. 1637 | lea RA, [RA+NARGS:RC*8-24] // RA = end of source for stack move.
1512 |.else 1638 |.else
@@ -1525,14 +1651,23 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
1525 | cmp PC, RB 1651 | cmp PC, RB
1526 | jne <2 1652 | jne <2
1527 |3: 1653 |3:
1654 |.if X64
1655 | mov CARG1d, TMP1
1656 | mov CARG2d, TMP2
1657 |.else
1528 | xor RA, RA 1658 | xor RA, RA
1529 | mov ARG4, RA 1659 | mov ARG4, RA
1530 | mov ARG3, RA 1660 | mov ARG3, RA
1661 |.endif
1531 | call ->vm_resume // (lua_State *L, TValue *base, 0, 0) 1662 | call ->vm_resume // (lua_State *L, TValue *base, 0, 0)
1532 | set_vmstate INTERP 1663 | set_vmstate INTERP
1533 | 1664 |
1534 | mov L:RB, SAVE_L 1665 | mov L:RB, SAVE_L
1666 |.if X64
1667 | mov L:PC, TMP1
1668 |.else
1535 | mov L:PC, ARG1 // The callee doesn't modify SAVE_L. 1669 | mov L:PC, ARG1 // The callee doesn't modify SAVE_L.
1670 |.endif
1536 | mov BASE, L:RB->base 1671 | mov BASE, L:RB->base
1537 | cmp eax, LUA_YIELD 1672 | cmp eax, LUA_YIELD
1538 | ja >8 1673 | ja >8
@@ -1590,8 +1725,13 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
1590 | mov RD, 1+2 // nresults+1 = 1 + false + error. 1725 | mov RD, 1+2 // nresults+1 = 1 + false + error.
1591 | jmp <7 1726 | jmp <7
1592 |.else 1727 |.else
1728 |.if X64
1729 | mov CARG2d, L:PC
1730 | mov CARG1d, L:RB
1731 |.else
1593 | mov ARG2, L:PC 1732 | mov ARG2, L:PC
1594 | mov ARG1, L:RB 1733 | mov ARG1, L:RB
1734 |.endif
1595 | call extern lj_ffh_coroutine_wrap_err // (lua_State *L, lua_State *co) 1735 | call extern lj_ffh_coroutine_wrap_err // (lua_State *L, lua_State *co)
1596 | // Error function does not return. 1736 | // Error function does not return.
1597 |.endif 1737 |.endif
@@ -1599,8 +1739,13 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
1599 |9: // Handle stack expansion on return from yield. 1739 |9: // Handle stack expansion on return from yield.
1600 | mov L:RA, ARG1 // The callee doesn't modify SAVE_L. 1740 | mov L:RA, ARG1 // The callee doesn't modify SAVE_L.
1601 | mov L:RA->top, KBASE // Undo coroutine stack clearing. 1741 | mov L:RA->top, KBASE // Undo coroutine stack clearing.
1742 |.if X64
1743 | mov CARG2d, PC
1744 | mov CARG1d, L:RB
1745 |.else
1602 | mov ARG2, PC 1746 | mov ARG2, PC
1603 | mov ARG1, L:RB 1747 | mov ARG1, L:RB
1748 |.endif
1604 | call extern lj_state_growstack // (lua_State *L, int n) 1749 | call extern lj_state_growstack // (lua_State *L, int n)
1605 | mov BASE, L:RB->base 1750 | mov BASE, L:RB->base
1606 | jmp <4 // Retry the stack move. 1751 | jmp <4 // Retry the stack move.
@@ -1617,8 +1762,8 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
1617 | mov L:RB->base, RA 1762 | mov L:RB->base, RA
1618 | lea RC, [RA+NARGS:RC*8-8] 1763 | lea RC, [RA+NARGS:RC*8-8]
1619 | mov L:RB->top, RC 1764 | mov L:RB->top, RC
1620 | xor eax, eax 1765 | xor RD, RD
1621 | mov aword L:RB->cframe, eax 1766 | mov aword L:RB->cframe, RDa
1622 | mov al, LUA_YIELD 1767 | mov al, LUA_YIELD
1623 | mov byte L:RB->status, al 1768 | mov byte L:RB->status, al
1624 | jmp ->vm_leave_unw 1769 | jmp ->vm_leave_unw
@@ -1706,7 +1851,7 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
1706 | cmp RB, 0x00200000; jb >4 1851 | cmp RB, 0x00200000; jb >4
1707 |1: 1852 |1:
1708 | shr RB, 21; sub RB, RC // Extract and unbias exponent. 1853 | shr RB, 21; sub RB, RC // Extract and unbias exponent.
1709 | mov ARG1, RB; fild ARG1 1854 | mov TMP1, RB; fild TMP1
1710 | mov RB, [RA-4] 1855 | mov RB, [RA-4]
1711 | and RB, 0x800fffff // Mask off exponent. 1856 | and RB, 0x800fffff // Mask off exponent.
1712 | or RB, 0x3fe00000 // Put mantissa in range [0.5,1) or 0. 1857 | or RB, 0x3fe00000 // Put mantissa in range [0.5,1) or 0.
@@ -1719,7 +1864,7 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
1719 | fldz; jmp <2 1864 | fldz; jmp <2
1720 |4: // Handle denormals by multiplying with 2^54 and adjusting the bias. 1865 |4: // Handle denormals by multiplying with 2^54 and adjusting the bias.
1721 | fld qword [RA] 1866 | fld qword [RA]
1722 | mov ARG1, 0x5a800000; fmul ARG1 // x = x*2^54 1867 | mov TMP1, 0x5a800000; fmul TMP1 // x = x*2^54
1723 | fstp qword [RA-8] 1868 | fstp qword [RA-8]
1724 | mov RB, [RA-4]; mov RC, 1076; shl RB, 1; jmp <1 1869 | mov RB, [RA-4]; mov RC, 1076; shl RB, 1; jmp <1
1725 | 1870 |
@@ -1786,8 +1931,8 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
1786 | cmp dword STR:RB->len, 1 1931 | cmp dword STR:RB->len, 1
1787 | jb ->fff_res0 // Return no results for empty string. 1932 | jb ->fff_res0 // Return no results for empty string.
1788 | movzx RB, byte STR:RB[1] 1933 | movzx RB, byte STR:RB[1]
1789 | mov ARG1, RB 1934 | mov TMP1, RB
1790 | fild ARG1 1935 | fild TMP1
1791 | jmp ->fff_resn 1936 | jmp ->fff_resn
1792 | 1937 |
1793 |.ffunc string_char // Only handle the 1-arg case here. 1938 |.ffunc string_char // Only handle the 1-arg case here.
@@ -1956,14 +2101,14 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
1956 | 2101 |
1957 |.ffunc_1 table_getn 2102 |.ffunc_1 table_getn
1958 | cmp dword [RA+4], LJ_TTAB; jne ->fff_fallback 2103 | cmp dword [RA+4], LJ_TTAB; jne ->fff_fallback
1959 | mov ARG2, BASE // Save RA and BASE. 2104 | mov TMP1, BASE // Save RA and BASE.
1960 | mov RB, RA 2105 | mov RB, RA
1961 | mov TAB:FCARG1, [RA] // Caveat: FCARG1 == RA 2106 | mov TAB:FCARG1, [RA] // Caveat: FCARG1 == RA
1962 | call extern lj_tab_len@4 // LJ_FASTCALL (GCtab *t) 2107 | call extern lj_tab_len@4 // LJ_FASTCALL (GCtab *t)
1963 | // Length of table returned in eax (RC). 2108 | // Length of table returned in eax (RC).
1964 | mov ARG1, RC 2109 | mov ARG1, RC
1965 | mov RA, RB // Restore RA and BASE. 2110 | mov RA, RB // Restore RA and BASE.
1966 | mov BASE, ARG2 2111 | mov BASE, TMP1
1967 | fild ARG1 2112 | fild ARG1
1968 | jmp ->fff_resn 2113 | jmp ->fff_resn
1969 | 2114 |
@@ -2106,7 +2251,11 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
2106 | mov SAVE_PC, PC // Redundant (but a defined value). 2251 | mov SAVE_PC, PC // Redundant (but a defined value).
2107 | mov L:RB->base, RA 2252 | mov L:RB->base, RA
2108 | lea RC, [RA+NARGS:RC*8-8] 2253 | lea RC, [RA+NARGS:RC*8-8]
2254 |.if X64
2255 | mov CARG1d, L:RB
2256 |.else
2109 | mov ARG1, L:RB 2257 | mov ARG1, L:RB
2258 |.endif
2110 | mov L:RB->top, RC 2259 | mov L:RB->top, RC
2111 | call extern lj_gc_step // (lua_State *L) 2260 | call extern lj_gc_step // (lua_State *L)
2112 | mov RA, L:RB->base 2261 | mov RA, L:RB->base
@@ -2152,12 +2301,20 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
2152 | test RDL, LUA_MASKLINE 2301 | test RDL, LUA_MASKLINE
2153 | jz >5 2302 | jz >5
2154 |1: 2303 |1:
2304 |.if X64
2305 | mov L:RB, SAVE_L
2306 | mov L:RB->base, BASE // Caveat: CARG2d/CARG3d may be BASE.
2307 | mov CARG3d, NRESULTS // Dynamic top for *M instructions.
2308 | mov CARG2d, PC
2309 | mov CARG1d, L:RB
2310 |.else
2155 | mov L:RB, SAVE_L 2311 | mov L:RB, SAVE_L
2156 | mov RD, NRESULTS // Dynamic top for *M instructions. 2312 | mov RD, NRESULTS // Dynamic top for *M instructions.
2157 | mov ARG3, RD 2313 | mov ARG3, RD
2158 | mov L:RB->base, BASE 2314 | mov L:RB->base, BASE
2159 | mov ARG2, PC 2315 | mov ARG2, PC
2160 | mov ARG1, L:RB 2316 | mov ARG1, L:RB
2317 |.endif
2161 | // SAVE_PC must hold the _previous_ PC. The callee updates it with PC. 2318 | // SAVE_PC must hold the _previous_ PC. The callee updates it with PC.
2162 | call extern lj_dispatch_ins // (lua_State *L, BCIns *pc, int nres) 2319 | call extern lj_dispatch_ins // (lua_State *L, BCIns *pc, int nres)
2163 |4: 2320 |4:
@@ -2171,12 +2328,17 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
2171 |->vm_hotloop: // Hot loop counter underflow. 2328 |->vm_hotloop: // Hot loop counter underflow.
2172#if LJ_HASJIT 2329#if LJ_HASJIT
2173 | mov L:RB, SAVE_L 2330 | mov L:RB, SAVE_L
2331 | mov L:RB->base, BASE
2332 |.if X64
2333 | mov CARG2d, PC
2334 | lea CARG1d, [DISPATCH+GG_DISP2J]
2335 |.else
2174 | lea RA, [DISPATCH+GG_DISP2J] 2336 | lea RA, [DISPATCH+GG_DISP2J]
2175 | mov ARG2, PC 2337 | mov ARG2, PC
2176 | mov ARG1, RA 2338 | mov ARG1, RA
2339 |.endif
2177 | mov [DISPATCH+DISPATCH_J(L)], L:RB 2340 | mov [DISPATCH+DISPATCH_J(L)], L:RB
2178 | mov SAVE_PC, PC 2341 | mov SAVE_PC, PC
2179 | mov L:RB->base, BASE
2180 | call extern lj_trace_hot // (jit_State *J, const BCIns *pc) 2342 | call extern lj_trace_hot // (jit_State *J, const BCIns *pc)
2181 | jmp <4 2343 | jmp <4
2182#endif 2344#endif
@@ -2184,12 +2346,17 @@ static void build_subroutines(BuildCtx *ctx, int cmov)
2184 |->vm_hotcall: // Hot call counter underflow. 2346 |->vm_hotcall: // Hot call counter underflow.
2185#if LJ_HASJIT 2347#if LJ_HASJIT
2186 | mov L:RB, SAVE_L 2348 | mov L:RB, SAVE_L
2349 | mov L:RB->base, BASE
2350 |.if X64
2351 | mov CARG2d, PC
2352 | lea CARG1d, [DISPATCH+GG_DISP2J]
2353 |.else
2187 | lea RA, [DISPATCH+GG_DISP2J] 2354 | lea RA, [DISPATCH+GG_DISP2J]
2188 | mov ARG2, PC 2355 | mov ARG2, PC
2189 | mov ARG1, RA 2356 | mov ARG1, RA
2357 |.endif
2190 | mov [DISPATCH+DISPATCH_J(L)], L:RB 2358 | mov [DISPATCH+DISPATCH_J(L)], L:RB
2191 | mov SAVE_PC, PC 2359 | mov SAVE_PC, PC
2192 | mov L:RB->base, BASE
2193 | call extern lj_trace_hot // (jit_State *J, const BCIns *pc) 2360 | call extern lj_trace_hot // (jit_State *J, const BCIns *pc)
2194 | mov BASE, L:RB->base 2361 | mov BASE, L:RB->base
2195 | // Dispatch the first instruction and optionally record it. 2362 | // Dispatch the first instruction and optionally record it.
@@ -2900,7 +3067,12 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop, int cmov)
2900 | test byte GCOBJ:RA->gch.marked, LJ_GC_WHITES // iswhite(v) 3067 | test byte GCOBJ:RA->gch.marked, LJ_GC_WHITES // iswhite(v)
2901 | jz <1 3068 | jz <1
2902 | // Crossed a write barrier. Move the barrier forward. 3069 | // Crossed a write barrier. Move the barrier forward.
3070 |.if X64 and not X64WIN
3071 | mov FCARG2, RB
3072 | mov RB, BASE // Save BASE.
3073 |.else
2903 | xchg FCARG2, RB // Save BASE (FCARG2 == BASE). 3074 | xchg FCARG2, RB // Save BASE (FCARG2 == BASE).
3075 |.endif
2904 | lea GL:FCARG1, [DISPATCH+GG_DISP2G] 3076 | lea GL:FCARG1, [DISPATCH+GG_DISP2G]
2905 | call extern lj_gc_barrieruv@8 // (global_State *g, TValue *tv) 3077 | call extern lj_gc_barrieruv@8 // (global_State *g, TValue *tv)
2906 | mov BASE, RB // Restore BASE. 3078 | mov BASE, RB // Restore BASE.