207 |
|
|
208 |
#endif /* CVM_X86 */ |
#endif /* CVM_X86 */ |
209 |
|
|
210 |
|
#ifdef CVM_X86_64 |
211 |
|
|
212 |
|
#define MD_HAS_2D_ARRAYS 1 |
213 |
|
|
214 |
|
/* |
215 |
|
* Check a 2D array access operation for exception conditions. |
216 |
|
*/ |
217 |
|
static void Check2DArrayAccess(MDUnroll *unroll, int reg, int reg2, int reg3, |
218 |
|
unsigned char *pc, unsigned char *label) |
219 |
|
{ |
220 |
|
#ifndef IL_USE_INTERRUPT_BASED_NULL_POINTER_CHECKS |
221 |
|
unsigned char *patch1; |
222 |
|
#endif |
223 |
|
unsigned char *patch2; |
224 |
|
unsigned char *patch3; |
225 |
|
|
226 |
|
fprintf(stderr, "%p %p\n", pc, label); |
227 |
|
|
228 |
|
#ifndef IL_USE_INTERRUPT_BASED_NULL_POINTER_CHECKS |
229 |
|
/* Check the array reference against NULL */ |
230 |
|
amd64_alu_reg_reg(unroll->out, X86_OR, reg, reg); |
231 |
|
patch1 = unroll->out; |
232 |
|
amd64_branch8(unroll->out, X86_CC_EQ, 0, 0); |
233 |
|
#endif |
234 |
|
|
235 |
|
/* |
236 |
|
a->data + (((i - a->bounds[0].lower) * a->bounds[0].multiplier) + |
237 |
|
(j - a->bounds[1].lower) * a->bounds[0].multiplier)) * a->elemSize) |
238 |
|
|
239 |
|
as follows |
240 |
|
|
241 |
|
i = i - a->bounds[0].lower |
242 |
|
j = j - a->bounds[1].lower |
243 |
|
i = i * a->bounds[0].multiplier |
244 |
|
j = j * a->bounds[1].multiplier |
245 |
|
i = i + j |
246 |
|
i = i * a->elemSize |
247 |
|
a = a->data |
248 |
|
a = a + i |
249 |
|
*/ |
250 |
|
|
251 |
|
/* Check the array bounds (all of which are ILInt32) */ |
252 |
|
amd64_alu_reg_membase_size(unroll->out, X86_SUB, reg2, reg, |
253 |
|
offsetof(System_MArray, bounds) |
254 |
|
+ offsetof(MArrayBounds, lower), |
255 |
|
4); /* i = i - a->bounds[0].lower */ |
256 |
|
|
257 |
|
amd64_alu_reg_membase_size(unroll->out, X86_CMP, reg2, reg, |
258 |
|
offsetof(System_MArray, bounds) |
259 |
|
+ offsetof(MArrayBounds, size), |
260 |
|
4); |
261 |
|
patch2 = unroll->out; |
262 |
|
amd64_branch32(unroll->out, X86_CC_LT, 0, 0); |
263 |
|
amd64_alu_reg_membase_size(unroll->out, X86_ADD, reg2, reg, |
264 |
|
offsetof(System_MArray, bounds) |
265 |
|
+ offsetof(MArrayBounds, lower), |
266 |
|
4); |
267 |
|
patch3 = unroll->out; |
268 |
|
amd64_jump8(unroll->out, 0); |
269 |
|
amd64_patch(patch2, unroll->out); |
270 |
|
|
271 |
|
amd64_alu_reg_membase_size(unroll->out, X86_SUB, reg3, reg, |
272 |
|
offsetof(System_MArray, bounds) |
273 |
|
+ sizeof(MArrayBounds) |
274 |
|
+ offsetof(MArrayBounds, lower), |
275 |
|
4); /* j = j - a->bounds[1].lower */ |
276 |
|
|
277 |
|
amd64_alu_reg_membase_size(unroll->out, X86_CMP, reg3, reg, |
278 |
|
offsetof(System_MArray, bounds) |
279 |
|
+ sizeof(MArrayBounds) |
280 |
|
+ offsetof(MArrayBounds, size), |
281 |
|
4); |
282 |
|
patch2 = unroll->out; |
283 |
|
amd64_branch32(unroll->out, X86_CC_LT, 0, 0); |
284 |
|
amd64_alu_reg_membase_size(unroll->out, X86_ADD, reg2, reg, |
285 |
|
offsetof(System_MArray, bounds) + |
286 |
|
offsetof(MArrayBounds, lower), |
287 |
|
4); |
288 |
|
amd64_alu_reg_membase_size(unroll->out, X86_ADD, reg3, reg, |
289 |
|
offsetof(System_MArray, bounds) |
290 |
|
+ sizeof(MArrayBounds) |
291 |
|
+ offsetof(MArrayBounds, lower), |
292 |
|
4); |
293 |
|
|
294 |
|
/* Re-execute the current instruction in the interpreter */ |
295 |
|
#ifndef IL_USE_INTERRUPT_BASED_NULL_POINTER_CHECKS |
296 |
|
amd64_patch(patch1, unroll->out); |
297 |
|
#endif |
298 |
|
amd64_patch(patch3, unroll->out); |
299 |
|
ReExecute(unroll, pc, label); |
300 |
|
|
301 |
|
/* Compute the address of the array element */ |
302 |
|
amd64_patch(patch2, unroll->out); |
303 |
|
|
304 |
|
amd64_imul_reg_membase_size(unroll->out, reg2, reg, |
305 |
|
offsetof(System_MArray, bounds) |
306 |
|
+ offsetof(MArrayBounds, multiplier), |
307 |
|
4); /* i = i * a->bounds[0].multiplier */ |
308 |
|
amd64_imul_reg_membase_size(unroll->out, reg3, reg, |
309 |
|
offsetof(System_MArray, bounds) |
310 |
|
+ sizeof(MArrayBounds) |
311 |
|
+ offsetof(MArrayBounds, multiplier), |
312 |
|
4); /* j = j * a->bounds[1].multiplier */ |
313 |
|
amd64_alu_reg_reg(unroll->out, X86_ADD, reg2, reg3); /* i = i + j */ |
314 |
|
amd64_imul_reg_membase_size(unroll->out, reg2, reg, |
315 |
|
offsetof(System_MArray, elemSize), |
316 |
|
4); /* i = i * a->elemSize */ |
317 |
|
amd64_mov_reg_membase(unroll->out, reg, reg, |
318 |
|
offsetof(System_MArray, data), |
319 |
|
8); /* a = a->data */ |
320 |
|
|
321 |
|
/* up-convert to 32 bit */ |
322 |
|
amd64_movsxd_reg_reg(unroll->out, reg2, reg2); |
323 |
|
amd64_alu_reg_reg(unroll->out, X86_ADD, reg, reg2); /* a = a + i */ |
324 |
|
} |
325 |
|
|
326 |
|
#endif /* CVM_X86_64 */ |
327 |
|
|
328 |
#ifdef CVM_ARM |
#ifdef CVM_ARM |
329 |
|
|
330 |
#define MD_HAS_2D_ARRAYS 1 |
#define MD_HAS_2D_ARRAYS 1 |
415 |
/* |
/* |
416 |
Algorithm of calc_address: |
Algorithm of calc_address: |
417 |
|
|
418 |
a + (((i - a->bounds[0].lower) * a->bounds[0].multiplier) + |
a->data + (((i - a->bounds[0].lower) * a->bounds[0].multiplier) + |
419 |
(j - a->bounds[1].lower) * a->bounds[0].multiplier)) * a->elemSize) |
(j - a->bounds[1].lower) * a->bounds[0].multiplier)) * a->elemSize) |
420 |
|
|
421 |
I've tried to pre-compute a->bounds into bounds (or MD_REG_PC) |
I've tried to pre-compute a->bounds into bounds (or MD_REG_PC) |