diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/buildvm_arm.dasc | 110 |
1 files changed, 107 insertions, 3 deletions
diff --git a/src/buildvm_arm.dasc b/src/buildvm_arm.dasc index 9814e93e..650aa31c 100644 --- a/src/buildvm_arm.dasc +++ b/src/buildvm_arm.dasc | |||
| @@ -1014,11 +1014,67 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 1014 | break; | 1014 | break; |
| 1015 | 1015 | ||
| 1016 | case BC_RET: | 1016 | case BC_RET: |
| 1017 | | // RA = results*8, RC = nresults+1 | ||
| 1018 | | ldr PC, [BASE, FRAME_PC] | ||
| 1019 | | lsl RC, RC, #3 | ||
| 1020 | | add RA, BASE, RA | ||
| 1021 | | str RC, SAVE_MULTRES | ||
| 1022 | |1: | ||
| 1023 | | ands CARG1, PC, #FRAME_TYPE | ||
| 1024 | | eor CARG2, PC, #FRAME_VARG | ||
| 1025 | | ldreq INS, [PC, #-4] | ||
| 1026 | | bne ->BC_RETV2_Z | ||
| 1027 | | | ||
| 1028 | |->BC_RET_Z: | ||
| 1029 | | // BASE = base, RA = resultptr, RC = (nresults+1)*8, PC = return | ||
| 1017 | | NYI | 1030 | | NYI |
| 1031 | | | ||
| 1032 | |->BC_RETV1_Z: // Non-standard return case. | ||
| 1033 | | add RA, BASE, RA | ||
| 1034 | |->BC_RETV2_Z: | ||
| 1035 | | tst CARG2, #FRAME_TYPEP | ||
| 1036 | | bne ->vm_return | ||
| 1037 | | // Return from vararg function: relocate BASE down. | ||
| 1038 | | sub BASE, BASE, CARG2 | ||
| 1039 | | ldr PC, [BASE, FRAME_PC] | ||
| 1040 | | b <1 | ||
| 1018 | break; | 1041 | break; |
| 1019 | 1042 | ||
| 1020 | case BC_RET0: case BC_RET1: | 1043 | case BC_RET0: case BC_RET1: |
| 1021 | | NYI | 1044 | | // RA = results*8, RC = nresults+1 |
| 1045 | | ldr PC, [BASE, FRAME_PC] | ||
| 1046 | | lsl RC, RC, #3 | ||
| 1047 | | str RC, SAVE_MULTRES | ||
| 1048 | | ands CARG1, PC, #FRAME_TYPE | ||
| 1049 | | eor CARG2, PC, #FRAME_VARG | ||
| 1050 | | ldreq INS, [PC, #-4] | ||
| 1051 | | bne ->BC_RETV1_Z | ||
| 1052 | if (op == BC_RET1) { | ||
| 1053 | | ldrd CARG12, [BASE, RA] | ||
| 1054 | } | ||
| 1055 | | sub CARG4, BASE, #8 | ||
| 1056 | | decode_RA8 RA, INS | ||
| 1057 | if (op == BC_RET1) { | ||
| 1058 | | strd CARG12, [CARG4] | ||
| 1059 | } | ||
| 1060 | | sub BASE, CARG4, RA | ||
| 1061 | | decode_RB8 RB, INS | ||
| 1062 | | ldr LFUNC:CARG1, [BASE, FRAME_FUNC] | ||
| 1063 | |5: | ||
| 1064 | | cmp RB, RC | ||
| 1065 | | bhi >6 | ||
| 1066 | | ldr CARG2, LFUNC:CARG1->field_pc | ||
| 1067 | | ins_next1 | ||
| 1068 | | ins_next2 | ||
| 1069 | | ldr KBASE, [CARG2, #PC2PROTO(k)] | ||
| 1070 | | ins_next3 | ||
| 1071 | | | ||
| 1072 | |6: // Fill up results with nil. | ||
| 1073 | | sub CARG2, CARG4, #4 | ||
| 1074 | | mvn CARG3, #~LJ_TNIL | ||
| 1075 | | str CARG3, [CARG2, RC] | ||
| 1076 | | add RC, RC, #8 | ||
| 1077 | | b <5 | ||
| 1022 | break; | 1078 | break; |
| 1023 | 1079 | ||
| 1024 | /* -- Loops and branches ------------------------------------------------ */ | 1080 | /* -- Loops and branches ------------------------------------------------ */ |
| @@ -1089,7 +1145,28 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 1089 | break; | 1145 | break; |
| 1090 | #endif | 1146 | #endif |
| 1091 | case BC_IFUNCF: | 1147 | case BC_IFUNCF: |
| 1092 | | NYI | 1148 | | // BASE = new base, RA = BASE+framesize*8, CARG3 = LFUNC, RC = nargs*8 |
| 1149 | | ldr CARG1, L->maxstack | ||
| 1150 | | ldrb CARG2, [PC, #-4+PC2PROTO(numparams)] | ||
| 1151 | | ldr KBASE, [PC, #-4+PC2PROTO(k)] | ||
| 1152 | | cmp RA, CARG1 | ||
| 1153 | | bhi ->vm_growstack_l | ||
| 1154 | | ins_next1 | ||
| 1155 | | ins_next2 | ||
| 1156 | |2: | ||
| 1157 | | cmp NARGS8:RC, CARG2, lsl #3 // Check for missing parameters. | ||
| 1158 | | ble >3 | ||
| 1159 | if (op == BC_JFUNCF) { | ||
| 1160 | | NYI | ||
| 1161 | } else { | ||
| 1162 | | ins_next3 | ||
| 1163 | } | ||
| 1164 | | | ||
| 1165 | |3: // Clear missing parameters. | ||
| 1166 | | mvn CARG1, #~LJ_TNIL | ||
| 1167 | | str CARG1, [BASE, NARGS8:RC] | ||
| 1168 | | add NARGS8:RC, NARGS8:RC, #8 | ||
| 1169 | | b <2 | ||
| 1093 | break; | 1170 | break; |
| 1094 | 1171 | ||
| 1095 | case BC_JFUNCV: | 1172 | case BC_JFUNCV: |
| @@ -1100,7 +1177,34 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 1100 | break; /* NYI: compiled vararg functions. */ | 1177 | break; /* NYI: compiled vararg functions. */ |
| 1101 | 1178 | ||
| 1102 | case BC_IFUNCV: | 1179 | case BC_IFUNCV: |
| 1103 | | NYI | 1180 | | // BASE = new base, RA = BASE+framesize*8, CARG3 = LFUNC, RC = nargs*8 |
| 1181 | | ldr CARG1, L->maxstack | ||
| 1182 | | add CARG4, BASE, RC | ||
| 1183 | | add RA, RA, RC | ||
| 1184 | | str LFUNC:CARG3, [CARG4] // Store copy of LFUNC. | ||
| 1185 | | add CARG2, RC, #8+FRAME_VARG | ||
| 1186 | | ldr KBASE, [PC, #-4+PC2PROTO(k)] | ||
| 1187 | | cmp RA, CARG1 | ||
| 1188 | | str CARG2, [CARG4, #4] // Store delta + FRAME_VARG. | ||
| 1189 | | bhs ->vm_growstack_l | ||
| 1190 | | ldrb RB, [PC, #-4+PC2PROTO(numparams)] | ||
| 1191 | | mov RA, BASE | ||
| 1192 | | mov RC, CARG4 | ||
| 1193 | | cmp RB, #0 | ||
| 1194 | | add BASE, CARG4, #8 | ||
| 1195 | | beq >3 | ||
| 1196 | | mvn CARG3, #~LJ_TNIL | ||
| 1197 | |1: | ||
| 1198 | | cmp RA, RC // Less args than parameters? | ||
| 1199 | | ldrdlo CARG12, [RA], #8 | ||
| 1200 | | mvnhs CARG2, CARG3 | ||
| 1201 | | strlo CARG3, [RA, #-4] // Clear old fixarg slot (help the GC). | ||
| 1202 | |2: | ||
| 1203 | | subs RB, RB, #1 | ||
| 1204 | | strd CARG12, [CARG4, #8]! | ||
| 1205 | | bne <1 | ||
| 1206 | |3: | ||
| 1207 | | ins_next | ||
| 1104 | break; | 1208 | break; |
| 1105 | 1209 | ||
| 1106 | case BC_FUNCC: | 1210 | case BC_FUNCC: |
