25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: bintrans_alpha.c,v 1.118 2005/04/18 22:30:31 debug Exp $ |
* $Id: bintrans_alpha.c,v 1.119 2005/06/22 10:12:25 debug Exp $ |
29 |
* |
* |
30 |
* Alpha specific code for dynamic binary translation. |
* Alpha specific code for dynamic binary translation. |
31 |
* |
* |
196 |
#define ofs_cb (((size_t)&dummy_cpu.cd.mips.chunk_base_address) - (size_t)&dummy_cpu) |
#define ofs_cb (((size_t)&dummy_cpu.cd.mips.chunk_base_address) - (size_t)&dummy_cpu) |
197 |
|
|
198 |
|
|
199 |
static uint32_t bintrans_alpha_loadstore_32bit[19] = { |
static uint32_t bintrans_alpha_load_32bit[18] = { |
200 |
/* |
/* |
201 |
* t1 = 1023; |
* t1 = 1023; |
202 |
* t2 = ((a1 >> 22) & t1) * sizeof(void *); |
* t2 = ((a1 >> 22) & t1) * sizeof(void *); |
227 |
/* 00 00 72 a6 ldq a3,0(a2) */ |
/* 00 00 72 a6 ldq a3,0(a2) */ |
228 |
0xa6720000, |
0xa6720000, |
229 |
|
|
230 |
|
/* 24 37 80 48 sll t3,0x1,t3 */ |
231 |
|
0x48803724, |
232 |
|
|
233 |
/* ff 0f 5f 20 lda t1,4095 */ |
/* ff 0f 5f 20 lda t1,4095 */ |
234 |
0x205f0fff, |
0x205f0fff, |
235 |
|
|
247 |
|
|
248 |
/* NULL? Then return failure at once. */ |
/* NULL? Then return failure at once. */ |
249 |
/* beq a3, return */ |
/* beq a3, return */ |
250 |
0xe6600004, |
0xe6600002, |
251 |
|
|
252 |
/* 01 30 60 46 and a3,0x1,t0 */ |
/* The rest of the load/store code was written with t3 as the address. */ |
|
0x46603001, |
|
253 |
|
|
254 |
/* Get rid of the lowest bit: */ |
/* Add the offset within the page: */ |
255 |
/* 33 05 61 42 subq a3,t0,a3 */ |
/* 04 04 62 42 addq a3,t1,t3 */ |
256 |
0x42610533, |
0x42620404, |
257 |
|
|
258 |
|
0x6be50000, /* jmp (t4) */ |
259 |
|
|
260 |
|
/* return: */ |
261 |
|
0x243f0000 | (BINTRANS_DONT_RUN_NEXT >> 16), /* ldah t0,256 */ |
262 |
|
0x44270407, /* or t0,t6,t6 */ |
263 |
|
0x6bfa8001 /* ret */ |
264 |
|
}; |
265 |
|
|
266 |
|
static uint32_t bintrans_alpha_store_32bit[18] = { |
267 |
|
/* |
268 |
|
* t1 = 1023; |
269 |
|
* t2 = ((a1 >> 22) & t1) * sizeof(void *); |
270 |
|
* t3 = ((a1 >> 12) & t1) * sizeof(void *); |
271 |
|
* t1 = a1 & 4095; |
272 |
|
* |
273 |
|
* f8 1f 5f 20 lda t1,1023 * 8 |
274 |
|
* 83 76 22 4a srl a1,19,t2 |
275 |
|
* 84 36 21 4a srl a1, 9,t3 |
276 |
|
* 03 00 62 44 and t2,t1,t2 |
277 |
|
*/ |
278 |
|
0x205f1ff8, |
279 |
|
0x4a227683, |
280 |
|
0x4a213684, |
281 |
|
0x44620003, |
282 |
|
|
283 |
|
/* |
284 |
|
* t10 is vaddr_to_hostaddr_table0 |
285 |
|
* |
286 |
|
* a3 = tbl0[t2] (load entry from tbl0) |
287 |
|
* 12 04 03 43 addq t10,t2,a2 |
288 |
|
*/ |
289 |
|
0x43030412, |
290 |
|
|
291 |
|
/* 04 00 82 44 and t3,t1,t3 */ |
292 |
|
0x44820004, |
293 |
|
|
294 |
|
/* 00 00 72 a6 ldq a3,0(a2) */ |
295 |
|
0xa6720000, |
296 |
|
|
297 |
|
/* 24 37 80 48 sll t3,0x1,t3 */ |
298 |
|
0x48803724, |
299 |
|
|
300 |
|
/* ff 0f 5f 20 lda t1,4095 */ |
301 |
|
0x205f0fff, |
302 |
|
|
303 |
|
/* |
304 |
|
* a3 = tbl1[t3] (load entry from tbl1 (which is a3)) |
305 |
|
* 13 04 64 42 addq a3,t3,a3 |
306 |
|
*/ |
307 |
|
0x42640413, |
308 |
|
|
309 |
|
/* 02 00 22 46 and a1,t1,t1 */ |
310 |
|
0x46220002, |
311 |
|
|
312 |
|
/* 00 00 73 a6 ldq a3,8(a3) */ |
313 |
|
0xa6730008, |
314 |
|
|
315 |
|
/* NULL? Then return failure at once. */ |
316 |
|
/* beq a3, return */ |
317 |
|
0xe6600002, |
318 |
|
|
319 |
/* The rest of the load/store code was written with t3 as the address. */ |
/* The rest of the load/store code was written with t3 as the address. */ |
320 |
|
|
334 |
|
|
335 |
static void (*bintrans_jump_to_32bit_pc)(struct cpu *); |
static void (*bintrans_jump_to_32bit_pc)(struct cpu *); |
336 |
|
|
337 |
static void (*bintrans_loadstore_32bit) |
static void (*bintrans_load_32bit) |
338 |
(struct cpu *) = (void *)bintrans_alpha_loadstore_32bit; |
(struct cpu *) = (void *)bintrans_alpha_load_32bit; |
339 |
|
|
340 |
|
static void (*bintrans_store_32bit) |
341 |
|
(struct cpu *) = (void *)bintrans_alpha_store_32bit; |
342 |
|
|
343 |
|
|
344 |
/* |
/* |
1502 |
if (mem->bintrans_32bit_only) { |
if (mem->bintrans_32bit_only) { |
1503 |
/* Special case for 32-bit addressing: */ |
/* Special case for 32-bit addressing: */ |
1504 |
|
|
1505 |
ofs = ((size_t)&dummy_cpu.cd.mips.bintrans_loadstore_32bit) - (size_t)&dummy_cpu; |
if (load) |
1506 |
|
ofs = ((size_t)&dummy_cpu.cd.mips.bintrans_load_32bit) - (size_t)&dummy_cpu; |
1507 |
|
else |
1508 |
|
ofs = ((size_t)&dummy_cpu.cd.mips.bintrans_store_32bit) - (size_t)&dummy_cpu; |
1509 |
/* ldq t12,bintrans_loadstore_32bit(a0) */ |
/* ldq t12,bintrans_loadstore_32bit(a0) */ |
1510 |
*a++ = ofs; *a++ = ofs >> 8; *a++ = 0x70; *a++ = 0xa7; |
*a++ = ofs; *a++ = ofs >> 8; *a++ = 0x70; *a++ = 0xa7; |
1511 |
|
|
1512 |
/* jsr t4,(t12),<after> */ |
/* jsr t4,(t12),<after> */ |
1513 |
*a++ = 0x00; *a++ = 0x40; *a++ = 0xbb; *a++ = 0x68; |
*a++ = 0x00; *a++ = 0x40; *a++ = 0xbb; *a++ = 0x68; |
1514 |
|
|
1515 |
/* |
/* Now: a3 = host page, t3 = address of host load/store */ |
|
* Now: |
|
|
* a3 = host page |
|
|
* t0 = 0 for readonly pages, 1 for read/write pages |
|
|
* t3 = address of host load/store |
|
|
*/ |
|
|
|
|
|
/* If this is a store, then the lowest bit must be set: */ |
|
|
if (!load) { |
|
|
/* 01 00 20 f4 bne t0,<okzzz> */ |
|
|
fail = a; |
|
|
*a++ = 0x01; *a++ = 0x00; *a++ = 0x20; *a++ = 0xf4; |
|
|
bintrans_write_chunkreturn_fail(&a); |
|
|
*fail = ((size_t)a - (size_t)fail - 4) / 4; |
|
|
} |
|
1516 |
} else { |
} else { |
1517 |
/* |
/* |
1518 |
* If the highest 33 bits of the address are either all ones |
* If the highest 33 bits of the address are either all ones |
1533 |
generic64bitA = a; |
generic64bitA = a; |
1534 |
*a++ = 0x04; *a++ = 0x00; *a++ = 0xe0; *a++ = 0xc3; /* br <generic> */ |
*a++ = 0x04; *a++ = 0x00; *a++ = 0xe0; *a++ = 0xc3; /* br <generic> */ |
1535 |
|
|
1536 |
ofs = ((size_t)&dummy_cpu.cd.mips.bintrans_loadstore_32bit) - (size_t)&dummy_cpu; |
if (load) |
1537 |
|
ofs = ((size_t)&dummy_cpu.cd.mips.bintrans_load_32bit) - (size_t)&dummy_cpu; |
1538 |
|
else |
1539 |
|
ofs = ((size_t)&dummy_cpu.cd.mips.bintrans_store_32bit) - (size_t)&dummy_cpu; |
1540 |
/* ldq t12,bintrans_loadstore_32bit(a0) */ |
/* ldq t12,bintrans_loadstore_32bit(a0) */ |
1541 |
*a++ = ofs; *a++ = ofs >> 8; *a++ = 0x70; *a++ = 0xa7; |
*a++ = ofs; *a++ = ofs >> 8; *a++ = 0x70; *a++ = 0xa7; |
1542 |
|
|
1544 |
*a++ = 0x00; *a++ = 0x40; *a++ = 0xbb; *a++ = 0x68; |
*a++ = 0x00; *a++ = 0x40; *a++ = 0xbb; *a++ = 0x68; |
1545 |
|
|
1546 |
/* |
/* |
1547 |
* Now: |
* Now: a3 = host page |
1548 |
* a3 = host page (or NULL if not found) |
* t3 = (potential) address of host load/store |
|
* t0 = 0 for readonly pages, 1 for read/write pages |
|
|
* t3 = (potential) address of host load/store |
|
1549 |
*/ |
*/ |
1550 |
|
|
|
/* If this is a store, then the lowest bit must be set: */ |
|
|
if (!load) { |
|
|
/* 01 00 20 f4 bne t0,<okzzz> */ |
|
|
fail = a; |
|
|
*a++ = 0x01; *a++ = 0x00; *a++ = 0x20; *a++ = 0xf4; |
|
|
bintrans_write_chunkreturn_fail(&a); |
|
|
*fail = ((size_t)a - (size_t)fail - 4) / 4; |
|
|
} |
|
|
|
|
1551 |
doloadstore = a; |
doloadstore = a; |
1552 |
*a++ = 0x01; *a++ = 0x00; *a++ = 0xe0; *a++ = 0xc3; |
*a++ = 0x01; *a++ = 0x00; *a++ = 0xe0; *a++ = 0xc3; |
1553 |
|
|