| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: sljitNativeARM_64.c,v 1.4 2019/01/20 23:14:16 alnsn Exp $ */ | | 1 | /* $NetBSD: sljitNativeARM_64.c,v 1.4.4.1 2024/04/18 15:24:21 martin Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Stack-less Just-In-Time compiler | | 4 | * Stack-less Just-In-Time compiler |
5 | * | | 5 | * |
6 | * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. | | 6 | * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. |
7 | * | | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without modification, are | | 8 | * Redistribution and use in source and binary forms, with or without modification, are |
9 | * permitted provided that the following conditions are met: | | 9 | * permitted provided that the following conditions are met: |
10 | * | | 10 | * |
11 | * 1. Redistributions of source code must retain the above copyright notice, this list of | | 11 | * 1. Redistributions of source code must retain the above copyright notice, this list of |
12 | * conditions and the following disclaimer. | | 12 | * conditions and the following disclaimer. |
13 | * | | 13 | * |
14 | * 2. Redistributions in binary form must reproduce the above copyright notice, this list | | 14 | * 2. Redistributions in binary form must reproduce the above copyright notice, this list |
| @@ -1069,27 +1069,28 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit | | | @@ -1069,27 +1069,28 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit |
1069 | sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) | | 1069 | sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) |
1070 | { | | 1070 | { |
1071 | sljit_s32 i, tmp, offs, prev, saved_regs_size; | | 1071 | sljit_s32 i, tmp, offs, prev, saved_regs_size; |
1072 | | | 1072 | |
1073 | CHECK_ERROR(); | | 1073 | CHECK_ERROR(); |
1074 | CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); | | 1074 | CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); |
1075 | set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); | | 1075 | set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); |
1076 | | | 1076 | |
1077 | saved_regs_size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 0); | | 1077 | saved_regs_size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 0); |
1078 | local_size += saved_regs_size + SLJIT_LOCALS_OFFSET; | | 1078 | local_size += saved_regs_size + SLJIT_LOCALS_OFFSET; |
1079 | local_size = (local_size + 15) & ~0xf; | | 1079 | local_size = (local_size + 15) & ~0xf; |
1080 | compiler->local_size = local_size; | | 1080 | compiler->local_size = local_size; |
1081 | | | 1081 | |
1082 | if (local_size <= (63 * sizeof(sljit_sw))) { | | 1082 | SLJIT_ASSERT(local_size >= 0); |
| | | 1083 | if ((size_t)local_size <= (63 * sizeof(sljit_sw))) { |
1083 | FAIL_IF(push_inst(compiler, STP_PRE | 29 | RT2(TMP_LR) | | 1084 | FAIL_IF(push_inst(compiler, STP_PRE | 29 | RT2(TMP_LR) |
1084 | | RN(TMP_SP) | ((-(local_size >> 3) & 0x7f) << 15))); | | 1085 | | RN(TMP_SP) | ((-(local_size >> 3) & 0x7f) << 15))); |
1085 | FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RN(TMP_SP) | (0 << 10))); | | 1086 | FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RN(TMP_SP) | (0 << 10))); |
1086 | offs = (local_size - saved_regs_size) << (15 - 3); | | 1087 | offs = (local_size - saved_regs_size) << (15 - 3); |
1087 | } else { | | 1088 | } else { |
1088 | offs = 0 << 15; | | 1089 | offs = 0 << 15; |
1089 | if (saved_regs_size & 0x8) { | | 1090 | if (saved_regs_size & 0x8) { |
1090 | offs = 1 << 15; | | 1091 | offs = 1 << 15; |
1091 | saved_regs_size += sizeof(sljit_sw); | | 1092 | saved_regs_size += sizeof(sljit_sw); |
1092 | } | | 1093 | } |
1093 | local_size -= saved_regs_size + SLJIT_LOCALS_OFFSET; | | 1094 | local_size -= saved_regs_size + SLJIT_LOCALS_OFFSET; |
1094 | if (saved_regs_size > 0) | | 1095 | if (saved_regs_size > 0) |
1095 | FAIL_IF(push_inst(compiler, SUBI | RD(TMP_SP) | RN(TMP_SP) | (saved_regs_size << 10))); | | 1096 | FAIL_IF(push_inst(compiler, SUBI | RD(TMP_SP) | RN(TMP_SP) | (saved_regs_size << 10))); |
| @@ -1119,27 +1120,28 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit | | | @@ -1119,27 +1120,28 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit |
1119 | continue; | | 1120 | continue; |
1120 | } | | 1121 | } |
1121 | FAIL_IF(push_inst(compiler, STRI | RT(i) | RN(TMP_SP) | (offs >> 5))); | | 1122 | FAIL_IF(push_inst(compiler, STRI | RT(i) | RN(TMP_SP) | (offs >> 5))); |
1122 | offs += 1 << 15; | | 1123 | offs += 1 << 15; |
1123 | continue; | | 1124 | continue; |
1124 | } | | 1125 | } |
1125 | FAIL_IF(push_inst(compiler, STP | RT(prev) | RT2(i) | RN(TMP_SP) | offs)); | | 1126 | FAIL_IF(push_inst(compiler, STP | RT(prev) | RT2(i) | RN(TMP_SP) | offs)); |
1126 | offs += 2 << 15; | | 1127 | offs += 2 << 15; |
1127 | prev = -1; | | 1128 | prev = -1; |
1128 | } | | 1129 | } |
1129 | | | 1130 | |
1130 | SLJIT_ASSERT(prev == -1); | | 1131 | SLJIT_ASSERT(prev == -1); |
1131 | | | 1132 | |
1132 | if (compiler->local_size > (63 * sizeof(sljit_sw))) { | | 1133 | SLJIT_ASSERT(compiler->local_size >= 0); |
| | | 1134 | if ((size_t)compiler->local_size > (63 * sizeof(sljit_sw))) { |
1133 | /* The local_size is already adjusted by the saved registers. */ | | 1135 | /* The local_size is already adjusted by the saved registers. */ |
1134 | if (local_size > 0xfff) { | | 1136 | if (local_size > 0xfff) { |
1135 | FAIL_IF(push_inst(compiler, SUBI | RD(TMP_SP) | RN(TMP_SP) | ((local_size >> 12) << 10) | (1 << 22))); | | 1137 | FAIL_IF(push_inst(compiler, SUBI | RD(TMP_SP) | RN(TMP_SP) | ((local_size >> 12) << 10) | (1 << 22))); |
1136 | local_size &= 0xfff; | | 1138 | local_size &= 0xfff; |
1137 | } | | 1139 | } |
1138 | if (local_size) | | 1140 | if (local_size) |
1139 | FAIL_IF(push_inst(compiler, SUBI | RD(TMP_SP) | RN(TMP_SP) | (local_size << 10))); | | 1141 | FAIL_IF(push_inst(compiler, SUBI | RD(TMP_SP) | RN(TMP_SP) | (local_size << 10))); |
1140 | FAIL_IF(push_inst(compiler, STP_PRE | 29 | RT2(TMP_LR) | | 1142 | FAIL_IF(push_inst(compiler, STP_PRE | 29 | RT2(TMP_LR) |
1141 | | RN(TMP_SP) | ((-(16 >> 3) & 0x7f) << 15))); | | 1143 | | RN(TMP_SP) | ((-(16 >> 3) & 0x7f) << 15))); |
1142 | FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RN(TMP_SP) | (0 << 10))); | | 1144 | FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RN(TMP_SP) | (0 << 10))); |
1143 | } | | 1145 | } |
1144 | | | 1146 | |
1145 | if (args >= 1) | | 1147 | if (args >= 1) |
| @@ -1169,27 +1171,28 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit | | | @@ -1169,27 +1171,28 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit |
1169 | SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw) | | 1171 | SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw) |
1170 | { | | 1172 | { |
1171 | sljit_s32 local_size; | | 1173 | sljit_s32 local_size; |
1172 | sljit_s32 i, tmp, offs, prev, saved_regs_size; | | 1174 | sljit_s32 i, tmp, offs, prev, saved_regs_size; |
1173 | | | 1175 | |
1174 | CHECK_ERROR(); | | 1176 | CHECK_ERROR(); |
1175 | CHECK(check_sljit_emit_return(compiler, op, src, srcw)); | | 1177 | CHECK(check_sljit_emit_return(compiler, op, src, srcw)); |
1176 | | | 1178 | |
1177 | FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); | | 1179 | FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); |
1178 | | | 1180 | |
1179 | local_size = compiler->local_size; | | 1181 | local_size = compiler->local_size; |
1180 | | | 1182 | |
1181 | saved_regs_size = GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 0); | | 1183 | saved_regs_size = GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 0); |
1182 | if (local_size <= (63 * sizeof(sljit_sw))) | | 1184 | SLJIT_ASSERT(local_size >= 0); |
| | | 1185 | if ((size_t)local_size <= (63 * sizeof(sljit_sw))) |
1183 | offs = (local_size - saved_regs_size) << (15 - 3); | | 1186 | offs = (local_size - saved_regs_size) << (15 - 3); |
1184 | else { | | 1187 | else { |
1185 | FAIL_IF(push_inst(compiler, LDP_PST | 29 | RT2(TMP_LR) | | 1188 | FAIL_IF(push_inst(compiler, LDP_PST | 29 | RT2(TMP_LR) |
1186 | | RN(TMP_SP) | (((16 >> 3) & 0x7f) << 15))); | | 1189 | | RN(TMP_SP) | (((16 >> 3) & 0x7f) << 15))); |
1187 | offs = 0 << 15; | | 1190 | offs = 0 << 15; |
1188 | if (saved_regs_size & 0x8) { | | 1191 | if (saved_regs_size & 0x8) { |
1189 | offs = 1 << 15; | | 1192 | offs = 1 << 15; |
1190 | saved_regs_size += sizeof(sljit_sw); | | 1193 | saved_regs_size += sizeof(sljit_sw); |
1191 | } | | 1194 | } |
1192 | local_size -= saved_regs_size + SLJIT_LOCALS_OFFSET; | | 1195 | local_size -= saved_regs_size + SLJIT_LOCALS_OFFSET; |
1193 | if (local_size > 0xfff) { | | 1196 | if (local_size > 0xfff) { |
1194 | FAIL_IF(push_inst(compiler, ADDI | RD(TMP_SP) | RN(TMP_SP) | ((local_size >> 12) << 10) | (1 << 22))); | | 1197 | FAIL_IF(push_inst(compiler, ADDI | RD(TMP_SP) | RN(TMP_SP) | ((local_size >> 12) << 10) | (1 << 22))); |
1195 | local_size &= 0xfff; | | 1198 | local_size &= 0xfff; |
| @@ -1222,27 +1225,28 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit | | | @@ -1222,27 +1225,28 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit |
1222 | continue; | | 1225 | continue; |
1223 | } | | 1226 | } |
1224 | FAIL_IF(push_inst(compiler, LDRI | RT(i) | RN(TMP_SP) | (offs >> 5))); | | 1227 | FAIL_IF(push_inst(compiler, LDRI | RT(i) | RN(TMP_SP) | (offs >> 5))); |
1225 | offs += 1 << 15; | | 1228 | offs += 1 << 15; |
1226 | continue; | | 1229 | continue; |
1227 | } | | 1230 | } |
1228 | FAIL_IF(push_inst(compiler, LDP | RT(prev) | RT2(i) | RN(TMP_SP) | offs)); | | 1231 | FAIL_IF(push_inst(compiler, LDP | RT(prev) | RT2(i) | RN(TMP_SP) | offs)); |
1229 | offs += 2 << 15; | | 1232 | offs += 2 << 15; |
1230 | prev = -1; | | 1233 | prev = -1; |
1231 | } | | 1234 | } |
1232 | | | 1235 | |
1233 | SLJIT_ASSERT(prev == -1); | | 1236 | SLJIT_ASSERT(prev == -1); |
1234 | | | 1237 | |
1235 | if (compiler->local_size <= (63 * sizeof(sljit_sw))) { | | 1238 | SLJIT_ASSERT(compiler->local_size >= 0); |
| | | 1239 | if ((size_t)compiler->local_size <= (63 * sizeof(sljit_sw))) { |
1236 | FAIL_IF(push_inst(compiler, LDP_PST | 29 | RT2(TMP_LR) | | 1240 | FAIL_IF(push_inst(compiler, LDP_PST | 29 | RT2(TMP_LR) |
1237 | | RN(TMP_SP) | (((local_size >> 3) & 0x7f) << 15))); | | 1241 | | RN(TMP_SP) | (((local_size >> 3) & 0x7f) << 15))); |
1238 | } else if (saved_regs_size > 0) { | | 1242 | } else if (saved_regs_size > 0) { |
1239 | FAIL_IF(push_inst(compiler, ADDI | RD(TMP_SP) | RN(TMP_SP) | (saved_regs_size << 10))); | | 1243 | FAIL_IF(push_inst(compiler, ADDI | RD(TMP_SP) | RN(TMP_SP) | (saved_regs_size << 10))); |
1240 | } | | 1244 | } |
1241 | | | 1245 | |
1242 | FAIL_IF(push_inst(compiler, RET | RN(TMP_LR))); | | 1246 | FAIL_IF(push_inst(compiler, RET | RN(TMP_LR))); |
1243 | return SLJIT_SUCCESS; | | 1247 | return SLJIT_SUCCESS; |
1244 | } | | 1248 | } |
1245 | | | 1249 | |
1246 | /* --------------------------------------------------------------------- */ | | 1250 | /* --------------------------------------------------------------------- */ |
1247 | /* Operators */ | | 1251 | /* Operators */ |
1248 | /* --------------------------------------------------------------------- */ | | 1252 | /* --------------------------------------------------------------------- */ |