25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: bintrans_alpha.c,v 1.114 2005/03/22 09:12:04 debug Exp $ |
* $Id: bintrans_alpha.c,v 1.118 2005/04/18 22:30:31 debug Exp $ |
29 |
* |
* |
30 |
* Alpha specific code for dynamic binary translation. |
* Alpha specific code for dynamic binary translation. |
31 |
* |
* |
39 |
* a1..a5 17..21 5 |
* a1..a5 17..21 5 |
40 |
* t8..t11 22..25 4 |
* t8..t11 22..25 4 |
41 |
* |
* |
42 |
* These can be "mapped" to MIPS registers in the translated code, |
* These can be "mapped" to MIPS registers in the translated code, except a0 |
43 |
* except a0 which points to the cpu struct, and t0..t4 (or so) |
* which points to the cpu struct, and t0..t4 (or so) which are used by the |
44 |
* which are used by the translated code as temporaries. |
* translated code as temporaries. |
45 |
* |
* |
46 |
* 3 + 7 + 5 + 4 = 19 available registers. Of course, all (except |
* 3 + 7 + 5 + 4 = 19 available registers. Of course, all (except s0..s6) must |
47 |
* s0..s6) must be saved when calling external functions, such as |
* be saved when calling external functions, such as when calling tlbp and |
48 |
* when doing load/store. |
* other external functions. |
49 |
* |
* |
50 |
* Which are the 19 most commonly used MIPS registers? (This will |
* Which are the 19 most commonly used MIPS registers? (This will include the |
51 |
* include the pc, and the "current number of executed translated |
* pc, and the "current number of executed translated instructions.) |
|
* instructions.) |
|
52 |
* |
* |
53 |
* The current allocation is as follows: |
* The current allocation is as follows: |
54 |
* |
* |
243 |
0xa6730000, |
0xa6730000, |
244 |
|
|
245 |
/* NULL? Then return failure at once. */ |
/* NULL? Then return failure at once. */ |
246 |
/* bne a3, skip */ |
/* beq a3, return */ |
247 |
0xf6600003, |
0xe6600004, |
|
|
|
|
0x243f0000 | (BINTRANS_DONT_RUN_NEXT >> 16), /* ldah t0,256 */ |
|
|
0x44270407, /* or t0,t6,t6 */ |
|
|
0x6bfa8001, /* ret */ |
|
|
|
|
|
/* skip: */ |
|
248 |
|
|
249 |
/* 01 30 60 46 and a3,0x1,t0 */ |
/* 01 30 60 46 and a3,0x1,t0 */ |
250 |
0x46603001, |
0x46603001, |
259 |
/* 04 04 62 42 addq a3,t1,t3 */ |
/* 04 04 62 42 addq a3,t1,t3 */ |
260 |
0x42620404, |
0x42620404, |
261 |
|
|
262 |
0x6be50000 /* jmp (t4) */ |
0x6be50000, /* jmp (t4) */ |
263 |
|
|
264 |
|
/* return: */ |
265 |
|
0x243f0000 | (BINTRANS_DONT_RUN_NEXT >> 16), /* ldah t0,256 */ |
266 |
|
0x44270407, /* or t0,t6,t6 */ |
267 |
|
0x6bfa8001 /* ret */ |
268 |
}; |
}; |
269 |
|
|
270 |
static void (*bintrans_runchunk)(struct cpu *, unsigned char *); |
static void (*bintrans_runchunk)(struct cpu *, unsigned char *); |
2579 |
static void bintrans_backend_init(void) |
static void bintrans_backend_init(void) |
2580 |
{ |
{ |
2581 |
int size; |
int size; |
2582 |
uint32_t *p; |
uint32_t *p, *q; |
2583 |
|
|
2584 |
|
|
2585 |
/* "runchunk": */ |
/* "runchunk": */ |
2673 |
*p++ = 0x205f0000 | (N_SAFE_BINTRANS_LIMIT-1); /* lda t1,safe-1 */ |
*p++ = 0x205f0000 | (N_SAFE_BINTRANS_LIMIT-1); /* lda t1,safe-1 */ |
2674 |
|
|
2675 |
*p++ = 0x40e20da1; /* cmple t6,t1,t0 */ |
*p++ = 0x40e20da1; /* cmple t6,t1,t0 */ |
2676 |
*p++ = 0xf4200001; /* bne */ |
q = p; /* *q is updated later */ |
2677 |
*p++ = 0x6bfa8001; /* ret */ |
*p++ = 0xe4200001; /* beq ret (far below) */ |
2678 |
|
|
2679 |
*p++ = 0x40c01411; /* addq t5,0,a1 */ |
*p++ = 0x40c01411; /* addq t5,0,a1 */ |
2680 |
|
|
2702 |
*p++ = 0x205f0ffc; /* lda t1,0xffc */ |
*p++ = 0x205f0ffc; /* lda t1,0xffc */ |
2703 |
|
|
2704 |
/* |
/* |
2705 |
* a3 = tbl1[t3] (load entry from tbl1 (whic is a3)) |
* a3 = tbl1[t3] (load entry from tbl1 (which is a3)) |
2706 |
*/ |
*/ |
2707 |
*p++ = 0x42640413; /* addq a3,t3,a3 */ |
*p++ = 0x42640413; /* addq a3,t3,a3 */ |
2708 |
*p++ = 0x46220002; /* and a1,t1,t1 */ |
*p++ = 0x46220002; /* and a1,t1,t1 */ |
2726 |
*p++ = 0x40230401; /* addq t0,t2,t0 */ |
*p++ = 0x40230401; /* addq t0,t2,t0 */ |
2727 |
*p++ = 0x6be10000; /* jmp (t0) */ |
*p++ = 0x6be10000; /* jmp (t0) */ |
2728 |
|
|
2729 |
|
/* Now, update *q to point here: */ |
2730 |
|
*q = 0xe4200000 | (((size_t)p - (size_t)q)/4 - 1); /* beq ret */ |
2731 |
|
|
2732 |
/* Return to the main translation loop. */ |
/* Return to the main translation loop. */ |
2733 |
*p++ = 0x6bfa8001; /* ret */ |
*p++ = 0x6bfa8001; /* ret */ |
2734 |
} |
} |