/[gxemul]/trunk/src/bintrans_alpha.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/src/bintrans_alpha.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2 by dpavlin, Mon Oct 8 16:17:48 2007 UTC revision 10 by dpavlin, Mon Oct 8 16:18:27 2007 UTC
# Line 25  Line 25 
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.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   *   *
# Line 39  Line 39 
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   *   *
# Line 197  static void bintrans_host_cacheinvalidat Line 196  static void bintrans_host_cacheinvalidat
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 *);
# Line 228  static uint32_t bintrans_alpha_loadstore Line 227  static uint32_t bintrans_alpha_loadstore
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    
# Line 244  static uint32_t bintrans_alpha_loadstore Line 246  static uint32_t bintrans_alpha_loadstore
246          0xa6730000,          0xa6730000,
247    
248          /*  NULL? Then return failure at once.  */          /*  NULL? Then return failure at once.  */
249          /*  bne a3, skip  */          /*  beq a3, return  */
250          0xf6600003,          0xe6600002,
251    
252            /*  The rest of the load/store code was written with t3 as the address.  */
253    
254            /*  Add the offset within the page:  */
255            /*  04 04 62 42     addq    a3,t1,t3  */
256            0x42620404,
257    
258            0x6be50000,             /*  jmp (t4)  */
259    
260            /*  return:  */
261          0x243f0000 | (BINTRANS_DONT_RUN_NEXT >> 16),    /*  ldah  t0,256  */          0x243f0000 | (BINTRANS_DONT_RUN_NEXT >> 16),    /*  ldah  t0,256  */
262          0x44270407,                                     /*  or      t0,t6,t6  */          0x44270407,                                     /*  or      t0,t6,t6  */
263          0x6bfa8001,                                     /*  ret  */          0x6bfa8001                                      /*  ret  */
264    };
265    
266          /*  skip:  */  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          /*  01 30 60 46     and     a3,0x1,t0  */          /*
284          0x46603001,           *  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          /*  Get rid of the lowest bit:  */          /*  04 00 82 44     and     t3,t1,t3  */
292          /*  33 05 61 42     subq    a3,t0,a3  */          0x44820004,
293          0x42610533,  
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    
# Line 266  static uint32_t bintrans_alpha_loadstore Line 322  static uint32_t bintrans_alpha_loadstore
322          /*  04 04 62 42     addq    a3,t1,t3  */          /*  04 04 62 42     addq    a3,t1,t3  */
323          0x42620404,          0x42620404,
324    
325          0x6be50000              /*  jmp (t4)  */          0x6be50000,             /*  jmp (t4)  */
326    
327            /*  return:  */
328            0x243f0000 | (BINTRANS_DONT_RUN_NEXT >> 16),    /*  ldah  t0,256  */
329            0x44270407,                                     /*  or      t0,t6,t6  */
330            0x6bfa8001                                      /*  ret  */
331  };  };
332    
333  static void (*bintrans_runchunk)(struct cpu *, unsigned char *);  static void (*bintrans_runchunk)(struct cpu *, unsigned char *);
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  /*  /*
# Line 1438  static int bintrans_write_instruction__l Line 1502  static int bintrans_write_instruction__l
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
# Line 1480  static int bintrans_write_instruction__l Line 1533  static int bintrans_write_instruction__l
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    
# Line 1488  static int bintrans_write_instruction__l Line 1544  static int bintrans_write_instruction__l
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    
# Line 2581  static int bintrans_write_instruction__t Line 2626  static int bintrans_write_instruction__t
2626  static void bintrans_backend_init(void)  static void bintrans_backend_init(void)
2627  {  {
2628          int size;          int size;
2629          uint32_t *p;          uint32_t *p, *q;
2630    
2631    
2632          /*  "runchunk":  */          /*  "runchunk":  */
# Line 2675  static void bintrans_backend_init(void) Line 2720  static void bintrans_backend_init(void)
2720          *p++ = 0x205f0000 | (N_SAFE_BINTRANS_LIMIT-1);  /*  lda t1,safe-1 */          *p++ = 0x205f0000 | (N_SAFE_BINTRANS_LIMIT-1);  /*  lda t1,safe-1 */
2721    
2722          *p++ = 0x40e20da1;              /*  cmple t6,t1,t0  */          *p++ = 0x40e20da1;              /*  cmple t6,t1,t0  */
2723          *p++ = 0xf4200001;              /*  bne  */          q = p;  /*  *q is updated later  */
2724          *p++ = 0x6bfa8001;              /*  ret  */          *p++ = 0xe4200001;              /*  beq ret (far below)  */
2725    
2726          *p++ = 0x40c01411;              /*  addq t5,0,a1  */          *p++ = 0x40c01411;              /*  addq t5,0,a1  */
2727    
# Line 2704  static void bintrans_backend_init(void) Line 2749  static void bintrans_backend_init(void)
2749          *p++ = 0x205f0ffc;      /*  lda     t1,0xffc  */          *p++ = 0x205f0ffc;      /*  lda     t1,0xffc  */
2750    
2751          /*          /*
2752           *  a3 = tbl1[t3]  (load entry from tbl1 (whic is a3))           *  a3 = tbl1[t3]  (load entry from tbl1 (which is a3))
2753           */           */
2754          *p++ = 0x42640413;      /*  addq    a3,t3,a3  */          *p++ = 0x42640413;      /*  addq    a3,t3,a3  */
2755          *p++ = 0x46220002;      /*  and     a1,t1,t1  */          *p++ = 0x46220002;      /*  and     a1,t1,t1  */
# Line 2728  static void bintrans_backend_init(void) Line 2773  static void bintrans_backend_init(void)
2773          *p++ = 0x40230401;      /*  addq t0,t2,t0  */          *p++ = 0x40230401;      /*  addq t0,t2,t0  */
2774          *p++ = 0x6be10000;      /*  jmp (t0)  */          *p++ = 0x6be10000;      /*  jmp (t0)  */
2775    
2776            /*  Now, update *q to point here:  */
2777            *q = 0xe4200000 | (((size_t)p - (size_t)q)/4 - 1);      /*  beq ret  */
2778    
2779          /*  Return to the main translation loop.  */          /*  Return to the main translation loop.  */
2780          *p++ = 0x6bfa8001;              /*  ret  */          *p++ = 0x6bfa8001;              /*  ret  */
2781  }  }

Legend:
Removed from v.2  
changed lines
  Added in v.10

  ViewVC Help
Powered by ViewVC 1.1.26