/[gxemul]/trunk/src/cpus/cpu_ppc_instr.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/cpus/cpu_ppc_instr.c

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

revision 14 by dpavlin, Mon Oct 8 16:18:51 2007 UTC revision 44 by dpavlin, Mon Oct 8 16:22:56 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2005  Anders Gavare.  All rights reserved.   *  Copyright (C) 2005-2007  Anders Gavare.  All rights reserved.
3   *   *
4   *  Redistribution and use in source and binary forms, with or without   *  Redistribution and use in source and binary forms, with or without
5   *  modification, are permitted provided that the following conditions are met:   *  modification, are permitted provided that the following conditions are met:
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: cpu_ppc_instr.c,v 1.18 2005/09/27 01:00:36 debug Exp $   *  $Id: cpu_ppc_instr.c,v 1.77 2007/06/28 13:36:47 debug Exp $
29   *   *
30   *  POWER/PowerPC instructions.   *  POWER/PowerPC instructions.
31   *   *
# Line 36  Line 36 
36   */   */
37    
38    
39  #define DOT(n) X(n ## _dot) { instr(n)(cpu,ic); \  #include "float_emul.h"
40    
41    
42    #define DOT0(n) X(n ## _dot) { instr(n)(cpu,ic); \
43            update_cr0(cpu, reg(ic->arg[0])); }
44    #define DOT1(n) X(n ## _dot) { instr(n)(cpu,ic); \
45          update_cr0(cpu, reg(ic->arg[1])); }          update_cr0(cpu, reg(ic->arg[1])); }
46    #define DOT2(n) X(n ## _dot) { instr(n)(cpu,ic); \
47            update_cr0(cpu, reg(ic->arg[2])); }
48    
49    #ifndef CHECK_FOR_FPU_EXCEPTION
50    #define CHECK_FOR_FPU_EXCEPTION { if (!(cpu->cd.ppc.msr & PPC_MSR_FP)) { \
51                    /*  Synchronize the PC, and cause an FPU exception:  */  \
52                    uint64_t low_pc = ((size_t)ic -                          \
53                        (size_t)cpu->cd.ppc.cur_ic_page)                     \
54                        / sizeof(struct ppc_instr_call);                     \
55                    cpu->pc = (cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) <<    \
56                        PPC_INSTR_ALIGNMENT_SHIFT)) + (low_pc <<             \
57                        PPC_INSTR_ALIGNMENT_SHIFT);                          \
58                    ppc_exception(cpu, PPC_EXCEPTION_FPU);                   \
59                    return; } }
60    #endif
61    
62    
63    
64  /*  /*
# Line 53  X(nop) Line 74  X(nop)
74   */   */
75  X(invalid)  X(invalid)
76  {  {
77          fatal("INTERNAL ERROR\n");          fatal("PPC: invalid(): INTERNAL ERROR\n");
78          exit(1);          exit(1);
79  }  }
80    
# Line 69  X(addi) Line 90  X(addi)
90  {  {
91          reg(ic->arg[2]) = reg(ic->arg[0]) + (int32_t)ic->arg[1];          reg(ic->arg[2]) = reg(ic->arg[0]) + (int32_t)ic->arg[1];
92  }  }
93    X(li)
94    {
95            reg(ic->arg[2]) = (int32_t)ic->arg[1];
96    }
97    X(li_0)
98    {
99            reg(ic->arg[2]) = 0;
100    }
101    
102    
103  /*  /*
# Line 98  X(addic) Line 127  X(addic)
127          /*  TODO/NOTE: Only for 32-bit mode, so far!  */          /*  TODO/NOTE: Only for 32-bit mode, so far!  */
128          uint64_t tmp = (uint32_t)reg(ic->arg[0]);          uint64_t tmp = (uint32_t)reg(ic->arg[0]);
129          uint64_t tmp2 = tmp;          uint64_t tmp2 = tmp;
130          cpu->cd.ppc.xer &= ~PPC_XER_CA;          cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
131          tmp2 += (uint32_t)ic->arg[1];          tmp2 += (uint32_t)ic->arg[1];
132          if ((tmp2 >> 32) != (tmp >> 32))          if ((tmp2 >> 32) != (tmp >> 32))
133                  cpu->cd.ppc.xer |= PPC_XER_CA;                  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
134          reg(ic->arg[2]) = (uint32_t)tmp2;          reg(ic->arg[2]) = (uint32_t)tmp2;
135  }  }
136    
# Line 116  X(addic) Line 145  X(addic)
145  X(subfic)  X(subfic)
146  {  {
147          MODE_uint_t tmp = (int64_t)(int32_t)ic->arg[1];          MODE_uint_t tmp = (int64_t)(int32_t)ic->arg[1];
148          cpu->cd.ppc.xer &= ~PPC_XER_CA;          cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
149          if (tmp >= reg(ic->arg[0]))          if (tmp >= reg(ic->arg[0]))
150                  cpu->cd.ppc.xer |= PPC_XER_CA;                  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
151          reg(ic->arg[2]) = tmp - reg(ic->arg[0]);          reg(ic->arg[2]) = tmp - reg(ic->arg[0]);
152  }  }
153    
# Line 135  X(addic_dot) Line 164  X(addic_dot)
164          /*  TODO/NOTE: Only for 32-bit mode, so far!  */          /*  TODO/NOTE: Only for 32-bit mode, so far!  */
165          uint64_t tmp = (uint32_t)reg(ic->arg[0]);          uint64_t tmp = (uint32_t)reg(ic->arg[0]);
166          uint64_t tmp2 = tmp;          uint64_t tmp2 = tmp;
167          cpu->cd.ppc.xer &= ~PPC_XER_CA;          cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
168          tmp2 += (uint32_t)ic->arg[1];          tmp2 += (uint32_t)ic->arg[1];
169          if ((tmp2 >> 32) != (tmp >> 32))          if ((tmp2 >> 32) != (tmp >> 32))
170                  cpu->cd.ppc.xer |= PPC_XER_CA;                  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
171          reg(ic->arg[2]) = (uint32_t)tmp2;          reg(ic->arg[2]) = (uint32_t)tmp2;
172          update_cr0(cpu, (uint32_t)tmp2);          update_cr0(cpu, (uint32_t)tmp2);
173  }  }
# Line 148  X(addic_dot) Line 177  X(addic_dot)
177   *  bclr:  Branch Conditional to Link Register   *  bclr:  Branch Conditional to Link Register
178   *   *
179   *  arg[0] = bo   *  arg[0] = bo
180   *  arg[1] = bi   *  arg[1] = 31 - bi
181   *  arg[2] = bh   *  arg[2] = bh
182   */   */
183  X(bclr)  X(bclr)
184  {  {
185          int bo = ic->arg[0], bi = ic->arg[1]  /* , bh = ic->arg[2]  */;          unsigned int bo = ic->arg[0], bi31m = ic->arg[1];
186          int ctr_ok, cond_ok;          int ctr_ok, cond_ok;
187          uint64_t old_pc = cpu->pc;          uint64_t old_pc = cpu->pc;
188          MODE_uint_t tmp, addr = cpu->cd.ppc.lr;          MODE_uint_t tmp, addr = cpu->cd.ppc.spr[SPR_LR];
189          if (!(bo & 4))          if (!(bo & 4))
190                  cpu->cd.ppc.ctr --;                  cpu->cd.ppc.spr[SPR_CTR] --;
191          ctr_ok = (bo >> 2) & 1;          ctr_ok = (bo >> 2) & 1;
192          tmp = cpu->cd.ppc.ctr;          tmp = cpu->cd.ppc.spr[SPR_CTR];
193          ctr_ok |= ( (tmp != 0) ^ ((bo >> 1) & 1) );          ctr_ok |= ( (tmp == 0) == ((bo >> 1) & 1) );
194          cond_ok = (bo >> 4) & 1;          cond_ok = (bo >> 4) & 1;
195          cond_ok |= ( ((bo >> 3) & 1) == ((cpu->cd.ppc.cr >> (31-bi)) & 1) );          cond_ok |= ( ((bo >> 3) & 1) == ((cpu->cd.ppc.cr >> bi31m) & 1) );
196          if (ctr_ok && cond_ok) {          if (ctr_ok && cond_ok) {
197                  uint64_t mask_within_page =                  uint64_t mask_within_page =
198                      ((PPC_IC_ENTRIES_PER_PAGE-1) << PPC_INSTR_ALIGNMENT_SHIFT)                      ((PPC_IC_ENTRIES_PER_PAGE-1) << PPC_INSTR_ALIGNMENT_SHIFT)
# Line 180  X(bclr) Line 209  X(bclr)
209                              PPC_INSTR_ALIGNMENT_SHIFT);                              PPC_INSTR_ALIGNMENT_SHIFT);
210                  } else {                  } else {
211                          /*  Find the new physical page and update pointers:  */                          /*  Find the new physical page and update pointers:  */
212                          DYNTRANS_PC_TO_POINTERS(cpu);                          quick_pc_to_pointers(cpu);
213                  }                  }
214          }          }
215  }  }
216    X(bclr_20)
217    {
218            cpu->pc = cpu->cd.ppc.spr[SPR_LR];
219            quick_pc_to_pointers(cpu);
220    }
221  X(bclr_l)  X(bclr_l)
222  {  {
223          uint64_t low_pc, old_pc = cpu->pc;          uint64_t low_pc, old_pc = cpu->pc;
224          int bo = ic->arg[0], bi = ic->arg[1]  /* , bh = ic->arg[2]  */;          unsigned int bo = ic->arg[0], bi31m = ic->arg[1]  /* ,bh = ic->arg[2]*/;
225          int ctr_ok, cond_ok;          int ctr_ok, cond_ok;
226          MODE_uint_t tmp, addr = cpu->cd.ppc.lr;          MODE_uint_t tmp, addr = cpu->cd.ppc.spr[SPR_LR];
227          if (!(bo & 4))          if (!(bo & 4))
228                  cpu->cd.ppc.ctr --;                  cpu->cd.ppc.spr[SPR_CTR] --;
229          ctr_ok = (bo >> 2) & 1;          ctr_ok = (bo >> 2) & 1;
230          tmp = cpu->cd.ppc.ctr;          tmp = cpu->cd.ppc.spr[SPR_CTR];
231          ctr_ok |= ( (tmp != 0) ^ ((bo >> 1) & 1) );          ctr_ok |= ( (tmp == 0) == ((bo >> 1) & 1) );
232          cond_ok = (bo >> 4) & 1;          cond_ok = (bo >> 4) & 1;
233          cond_ok |= ( ((bo >> 3) & 1) == ((cpu->cd.ppc.cr >> (31-bi)) & 1) );          cond_ok |= ( ((bo >> 3) & 1) == ((cpu->cd.ppc.cr >> bi31m) & 1) );
234    
235          /*  Calculate return PC:  */          /*  Calculate return PC:  */
236          low_pc = ((size_t)cpu->cd.ppc.next_ic - (size_t)          low_pc = ((size_t)ic - (size_t)
237              cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);              cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call) + 1;
238          cpu->cd.ppc.lr = cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2);          cpu->cd.ppc.spr[SPR_LR] = cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1)
239          cpu->cd.ppc.lr += (low_pc << 2);              << PPC_INSTR_ALIGNMENT_SHIFT);
240            cpu->cd.ppc.spr[SPR_LR] += (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
241    
242          if (ctr_ok && cond_ok) {          if (ctr_ok && cond_ok) {
243                  uint64_t mask_within_page =                  uint64_t mask_within_page =
# Line 222  X(bclr_l) Line 257  X(bclr_l)
257                              PPC_INSTR_ALIGNMENT_SHIFT);                              PPC_INSTR_ALIGNMENT_SHIFT);
258                  } else {                  } else {
259                          /*  Find the new physical page and update pointers:  */                          /*  Find the new physical page and update pointers:  */
260                          DYNTRANS_PC_TO_POINTERS(cpu);                          quick_pc_to_pointers(cpu);
261                  }                  }
262          }          }
263  }  }
# Line 232  X(bclr_l) Line 267  X(bclr_l)
267   *  bcctr:  Branch Conditional to Count register   *  bcctr:  Branch Conditional to Count register
268   *   *
269   *  arg[0] = bo   *  arg[0] = bo
270   *  arg[1] = bi   *  arg[1] = 31 - bi
271   *  arg[2] = bh   *  arg[2] = bh
272   */   */
273  X(bcctr)  X(bcctr)
274  {  {
275          int bo = ic->arg[0], bi = ic->arg[1]  /* , bh = ic->arg[2]  */;          unsigned int bo = ic->arg[0], bi31m = ic->arg[1];
276          uint64_t old_pc = cpu->pc;          uint64_t old_pc = cpu->pc;
277          MODE_uint_t addr = cpu->cd.ppc.ctr;          MODE_uint_t addr = cpu->cd.ppc.spr[SPR_CTR];
278          int cond_ok = (bo >> 4) & 1;          int cond_ok = (bo >> 4) & 1;
279          cond_ok |= ( ((bo >> 3) & 1) == ((cpu->cd.ppc.cr >> (31-bi)) & 1) );          cond_ok |= ( ((bo >> 3) & 1) == ((cpu->cd.ppc.cr >> bi31m) & 1) );
280          if (cond_ok) {          if (cond_ok) {
281                  uint64_t mask_within_page =                  uint64_t mask_within_page =
282                      ((PPC_IC_ENTRIES_PER_PAGE-1) << PPC_INSTR_ALIGNMENT_SHIFT)                      ((PPC_IC_ENTRIES_PER_PAGE-1) << PPC_INSTR_ALIGNMENT_SHIFT)
# Line 258  X(bcctr) Line 293  X(bcctr)
293                              PPC_INSTR_ALIGNMENT_SHIFT);                              PPC_INSTR_ALIGNMENT_SHIFT);
294                  } else {                  } else {
295                          /*  Find the new physical page and update pointers:  */                          /*  Find the new physical page and update pointers:  */
296                          DYNTRANS_PC_TO_POINTERS(cpu);                          quick_pc_to_pointers(cpu);
297                  }                  }
298          }          }
299  }  }
300  X(bcctr_l)  X(bcctr_l)
301  {  {
302          uint64_t low_pc, old_pc = cpu->pc;          uint64_t low_pc, old_pc = cpu->pc;
303          int bo = ic->arg[0], bi = ic->arg[1]  /* , bh = ic->arg[2]  */;          unsigned int bo = ic->arg[0], bi31m = ic->arg[1]  /*,bh = ic->arg[2] */;
304          MODE_uint_t addr = cpu->cd.ppc.ctr;          MODE_uint_t addr = cpu->cd.ppc.spr[SPR_CTR];
305          int cond_ok = (bo >> 4) & 1;          int cond_ok = (bo >> 4) & 1;
306          cond_ok |= ( ((bo >> 3) & 1) == ((cpu->cd.ppc.cr >> (31-bi)) & 1) );          cond_ok |= ( ((bo >> 3) & 1) == ((cpu->cd.ppc.cr >> bi31m) & 1) );
307    
308          /*  Calculate return PC:  */          /*  Calculate return PC:  */
309          low_pc = ((size_t)cpu->cd.ppc.next_ic - (size_t)          low_pc = ((size_t)ic - (size_t)
310              cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);              cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call) + 1;
311          cpu->cd.ppc.lr = cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2);          cpu->cd.ppc.spr[SPR_LR] = cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1)
312          cpu->cd.ppc.lr += (low_pc << 2);              << PPC_INSTR_ALIGNMENT_SHIFT);
313            cpu->cd.ppc.spr[SPR_LR] += (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
314    
315          if (cond_ok) {          if (cond_ok) {
316                  uint64_t mask_within_page =                  uint64_t mask_within_page =
# Line 292  X(bcctr_l) Line 328  X(bcctr_l)
328                              PPC_INSTR_ALIGNMENT_SHIFT);                              PPC_INSTR_ALIGNMENT_SHIFT);
329                  } else {                  } else {
330                          /*  Find the new physical page and update pointers:  */                          /*  Find the new physical page and update pointers:  */
331                          DYNTRANS_PC_TO_POINTERS(cpu);                          quick_pc_to_pointers(cpu);
332                  }                  }
333          }          }
334  }  }
# Line 301  X(bcctr_l) Line 337  X(bcctr_l)
337  /*  /*
338   *  b:  Branch (to a different translated page)   *  b:  Branch (to a different translated page)
339   *   *
340   *  arg[0] = relative offset (as an int32_t)   *  arg[0] = relative offset (as an int32_t) from start of page
341   */   */
342  X(b)  X(b)
343  {  {
344          uint64_t low_pc;          cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1) << PPC_INSTR_ALIGNMENT_SHIFT);
   
         /*  Calculate new PC from this instruction + arg[0]  */  
         low_pc = ((size_t)ic - (size_t)  
             cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);  
         cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2);  
         cpu->pc += (low_pc << 2);  
345          cpu->pc += (int32_t)ic->arg[0];          cpu->pc += (int32_t)ic->arg[0];
346    
347          /*  Find the new physical page and update the translation pointers:  */          /*  Find the new physical page and update the translation pointers:  */
348          DYNTRANS_PC_TO_POINTERS(cpu);          quick_pc_to_pointers(cpu);
349    }
350    X(ba)
351    {
352            cpu->pc = (int32_t)ic->arg[0];
353            quick_pc_to_pointers(cpu);
354  }  }
355    
356    
357  /*  /*
358   *  bc:  Branch Conditional (to a different translated page)   *  bc:  Branch Conditional (to a different translated page)
359   *   *
360   *  arg[0] = relative offset (as an int32_t)   *  arg[0] = relative offset (as an int32_t) from start of page
361   *  arg[1] = bo   *  arg[1] = bo
362   *  arg[2] = bi   *  arg[2] = 31-bi
363   */   */
364  X(bc)  X(bc)
365  {  {
366          MODE_uint_t tmp;          MODE_uint_t tmp;
367          int ctr_ok, cond_ok, bi = ic->arg[2], bo = ic->arg[1];          unsigned int ctr_ok, cond_ok, bi31m = ic->arg[2], bo = ic->arg[1];
368            if (!(bo & 4))
369                    cpu->cd.ppc.spr[SPR_CTR] --;
370            ctr_ok = (bo >> 2) & 1;
371            tmp = cpu->cd.ppc.spr[SPR_CTR];
372            ctr_ok |= ( (tmp == 0) == ((bo >> 1) & 1) );
373            cond_ok = (bo >> 4) & 1;
374            cond_ok |= ( ((bo >> 3) & 1) ==
375                ((cpu->cd.ppc.cr >> (bi31m)) & 1)  );
376            if (ctr_ok && cond_ok)
377                    instr(b)(cpu,ic);
378    }
379    X(bcl)
380    {
381            MODE_uint_t tmp;
382            unsigned int ctr_ok, cond_ok, bi31m = ic->arg[2], bo = ic->arg[1];
383            int low_pc;
384    
385            /*  Calculate LR:  */
386            low_pc = ((size_t)ic - (size_t)
387                cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call) + 1;
388            cpu->cd.ppc.spr[SPR_LR] = cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1)
389                << PPC_INSTR_ALIGNMENT_SHIFT);
390            cpu->cd.ppc.spr[SPR_LR] += (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
391    
392          if (!(bo & 4))          if (!(bo & 4))
393                  cpu->cd.ppc.ctr --;                  cpu->cd.ppc.spr[SPR_CTR] --;
394          ctr_ok = (bo >> 2) & 1;          ctr_ok = (bo >> 2) & 1;
395          tmp = cpu->cd.ppc.ctr;          tmp = cpu->cd.ppc.spr[SPR_CTR];
396          ctr_ok |= ( (tmp != 0) ^ ((bo >> 1) & 1) );          ctr_ok |= ( (tmp == 0) == ((bo >> 1) & 1) );
397          cond_ok = (bo >> 4) & 1;          cond_ok = (bo >> 4) & 1;
398          cond_ok |= ( ((bo >> 3) & 1) ==          cond_ok |= ( ((bo >> 3) & 1) ==
399              ((cpu->cd.ppc.cr >> (31-bi)) & 1)  );              ((cpu->cd.ppc.cr >> bi31m) & 1)  );
400          if (ctr_ok && cond_ok)          if (ctr_ok && cond_ok)
401                  instr(b)(cpu,ic);                  instr(b)(cpu,ic);
402  }  }
# Line 359  X(b_samepage) Line 418  X(b_samepage)
418   *   *
419   *  arg[0] = new ic ptr   *  arg[0] = new ic ptr
420   *  arg[1] = bo   *  arg[1] = bo
421   *  arg[2] = bi   *  arg[2] = 31-bi
422   */   */
423  X(bc_samepage)  X(bc_samepage)
424  {  {
425          MODE_uint_t tmp;          MODE_uint_t tmp;
426          int ctr_ok, cond_ok, bi = ic->arg[2], bo = ic->arg[1];          unsigned int ctr_ok, cond_ok, bi31m = ic->arg[2], bo = ic->arg[1];
427            if (!(bo & 4))
428                    cpu->cd.ppc.spr[SPR_CTR] --;
429            ctr_ok = (bo >> 2) & 1;
430            tmp = cpu->cd.ppc.spr[SPR_CTR];
431            ctr_ok |= ( (tmp == 0) == ((bo >> 1) & 1) );
432            cond_ok = (bo >> 4) & 1;
433            cond_ok |= ( ((bo >> 3) & 1) ==
434                ((cpu->cd.ppc.cr >> bi31m) & 1)  );
435            if (ctr_ok && cond_ok)
436                    cpu->cd.ppc.next_ic = (struct ppc_instr_call *) ic->arg[0];
437    }
438    X(bc_samepage_simple0)
439    {
440            int bi31m = ic->arg[2];
441            if (!((cpu->cd.ppc.cr >> bi31m) & 1))
442                    cpu->cd.ppc.next_ic = (struct ppc_instr_call *) ic->arg[0];
443    }
444    X(bc_samepage_simple1)
445    {
446            int bi31m = ic->arg[2];
447            if ((cpu->cd.ppc.cr >> bi31m) & 1)
448                    cpu->cd.ppc.next_ic = (struct ppc_instr_call *) ic->arg[0];
449    }
450    X(bcl_samepage)
451    {
452            MODE_uint_t tmp;
453            unsigned int ctr_ok, cond_ok, bi31m = ic->arg[2], bo = ic->arg[1];
454            int low_pc;
455    
456            /*  Calculate LR:  */
457            low_pc = ((size_t)ic - (size_t)
458                cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call) + 1;
459            cpu->cd.ppc.spr[SPR_LR] = cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1)
460                << PPC_INSTR_ALIGNMENT_SHIFT);
461            cpu->cd.ppc.spr[SPR_LR] += (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
462    
463          if (!(bo & 4))          if (!(bo & 4))
464                  cpu->cd.ppc.ctr --;                  cpu->cd.ppc.spr[SPR_CTR] --;
465          ctr_ok = (bo >> 2) & 1;          ctr_ok = (bo >> 2) & 1;
466          tmp = cpu->cd.ppc.ctr;          tmp = cpu->cd.ppc.spr[SPR_CTR];
467          ctr_ok |= ( (tmp != 0) ^ ((bo >> 1) & 1) );          ctr_ok |= ( (tmp == 0) == ((bo >> 1) & 1) );
468          cond_ok = (bo >> 4) & 1;          cond_ok = (bo >> 4) & 1;
469          cond_ok |= ( ((bo >> 3) & 1) ==          cond_ok |= ( ((bo >> 3) & 1) ==
470              ((cpu->cd.ppc.cr >> (31-bi)) & 1)  );              ((cpu->cd.ppc.cr >> bi31m) & 1)  );
471          if (ctr_ok && cond_ok)          if (ctr_ok && cond_ok)
472                  instr(b_samepage)(cpu,ic);                  cpu->cd.ppc.next_ic = (struct ppc_instr_call *) ic->arg[0];
473  }  }
474    
475    
476  /*  /*
477   *  bl:  Branch and Link (to a different translated page)   *  bl:  Branch and Link (to a different translated page)
478   *   *
479   *  arg[0] = relative offset (as an int32_t)   *  arg[0] = relative offset (as an int32_t) from start of page
480     *  arg[1] = lr offset (relative to start of current page)
481   */   */
482  X(bl)  X(bl)
483  {  {
484          uint32_t low_pc;          /*  Calculate LR and new PC:  */
485            cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1) << PPC_INSTR_ALIGNMENT_SHIFT);
486          /*  Calculate LR:  */          cpu->cd.ppc.spr[SPR_LR] = cpu->pc + ic->arg[1];
         low_pc = ((size_t)cpu->cd.ppc.next_ic - (size_t)  
             cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);  
         cpu->cd.ppc.lr = cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2);  
         cpu->cd.ppc.lr += (low_pc << 2);  
   
         /*  Calculate new PC from this instruction + arg[0]  */  
         low_pc = ((size_t)ic - (size_t)  
             cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);  
         cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2);  
         cpu->pc += (low_pc << 2);  
487          cpu->pc += (int32_t)ic->arg[0];          cpu->pc += (int32_t)ic->arg[0];
488    
489          /*  Find the new physical page and update the translation pointers:  */          /*  Find the new physical page and update the translation pointers:  */
490          DYNTRANS_PC_TO_POINTERS(cpu);          quick_pc_to_pointers(cpu);
491    }
492    X(bla)
493    {
494            /*  Calculate LR:  */
495            cpu->cd.ppc.spr[SPR_LR] = (cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1)
496                << PPC_INSTR_ALIGNMENT_SHIFT)) + ic->arg[1];
497    
498            cpu->pc = (int32_t)ic->arg[0];
499            quick_pc_to_pointers(cpu);
500  }  }
501    
502    
503  /*  /*
504   *  bl_trace:  Branch and Link (to a different translated page)  (with trace)   *  bl_trace:  Branch and Link (to a different translated page)  (with trace)
505   *   *
506   *  arg[0] = relative offset (as an int32_t)   *  arg[0] = relative offset (as an int32_t) from start of page
507     *  arg[1] = lr offset (relative to start of current page)
508   */   */
509  X(bl_trace)  X(bl_trace)
510  {  {
         uint32_t low_pc;  
   
511          /*  Calculate LR:  */          /*  Calculate LR:  */
512          low_pc = ((size_t)cpu->cd.ppc.next_ic - (size_t)          cpu->cd.ppc.spr[SPR_LR] = (cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1)
513              cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);              << PPC_INSTR_ALIGNMENT_SHIFT)) + ic->arg[1];
         cpu->cd.ppc.lr = cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2);  
         cpu->cd.ppc.lr += (low_pc << 2);  
514    
515          /*  Calculate new PC from this instruction + arg[0]  */          /*  Calculate new PC from start of page + arg[0]  */
516          low_pc = ((size_t)ic - (size_t)          cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1) << PPC_INSTR_ALIGNMENT_SHIFT);
             cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);  
         cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2);  
         cpu->pc += (low_pc << 2);  
517          cpu->pc += (int32_t)ic->arg[0];          cpu->pc += (int32_t)ic->arg[0];
518    
519          cpu_functioncall_trace(cpu, cpu->pc);          cpu_functioncall_trace(cpu, cpu->pc);
520    
521          /*  Find the new physical page and update the translation pointers:  */          /*  Find the new physical page and update the translation pointers:  */
522          DYNTRANS_PC_TO_POINTERS(cpu);          quick_pc_to_pointers(cpu);
523    }
524    X(bla_trace)
525    {
526            /*  Calculate LR:  */
527            cpu->cd.ppc.spr[SPR_LR] = (cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1)
528                << PPC_INSTR_ALIGNMENT_SHIFT)) + ic->arg[1];
529    
530            cpu->pc = (int32_t)ic->arg[0];
531            cpu_functioncall_trace(cpu, cpu->pc);
532            quick_pc_to_pointers(cpu);
533  }  }
534    
535    
# Line 438  X(bl_trace) Line 537  X(bl_trace)
537   *  bl_samepage:  Branch and Link (to within the same translated page)   *  bl_samepage:  Branch and Link (to within the same translated page)
538   *   *
539   *  arg[0] = pointer to new ppc_instr_call   *  arg[0] = pointer to new ppc_instr_call
540     *  arg[1] = lr offset (relative to start of current page)
541   */   */
542  X(bl_samepage)  X(bl_samepage)
543  {  {
         uint32_t low_pc;  
   
544          /*  Calculate LR:  */          /*  Calculate LR:  */
545          low_pc = ((size_t)ic - (size_t)          cpu->cd.ppc.spr[SPR_LR] = (cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1)
546              cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call) + 1;              << PPC_INSTR_ALIGNMENT_SHIFT)) + ic->arg[1];
         cpu->cd.ppc.lr = cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2);  
         cpu->cd.ppc.lr += (low_pc << 2);  
547    
548          cpu->cd.ppc.next_ic = (struct ppc_instr_call *) ic->arg[0];          cpu->cd.ppc.next_ic = (struct ppc_instr_call *) ic->arg[0];
549  }  }
# Line 457  X(bl_samepage) Line 553  X(bl_samepage)
553   *  bl_samepage_trace:  Branch and Link (to within the same translated page)   *  bl_samepage_trace:  Branch and Link (to within the same translated page)
554   *   *
555   *  arg[0] = pointer to new ppc_instr_call   *  arg[0] = pointer to new ppc_instr_call
556     *  arg[1] = lr offset (relative to start of current page)
557   */   */
558  X(bl_samepage_trace)  X(bl_samepage_trace)
559  {  {
560          uint32_t low_pc;          uint32_t low_pc;
561    
562          /*  Calculate LR:  */          /*  Calculate LR:  */
563          low_pc = ((size_t)cpu->cd.ppc.next_ic - (size_t)          cpu->cd.ppc.spr[SPR_LR] = (cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1)
564              cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);              << PPC_INSTR_ALIGNMENT_SHIFT)) + ic->arg[1];
         cpu->cd.ppc.lr = cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2);  
         cpu->cd.ppc.lr += (low_pc << 2);  
565    
566          cpu->cd.ppc.next_ic = (struct ppc_instr_call *) ic->arg[0];          cpu->cd.ppc.next_ic = (struct ppc_instr_call *) ic->arg[0];
567    
568          /*  Calculate new PC (for the trace)  */          /*  Calculate new PC (for the trace)  */
569          low_pc = ((size_t)cpu->cd.ppc.next_ic - (size_t)          low_pc = ((size_t)cpu->cd.ppc.next_ic - (size_t)
570              cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);              cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
571          cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2);          cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1) << PPC_INSTR_ALIGNMENT_SHIFT);
572          cpu->pc += (low_pc << 2);          cpu->pc += (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
573          cpu_functioncall_trace(cpu, cpu->pc);          cpu_functioncall_trace(cpu, cpu->pc);
574  }  }
575    
# Line 503  X(cntlzw) Line 598  X(cntlzw)
598   *   *
599   *  arg[0] = ptr to ra   *  arg[0] = ptr to ra
600   *  arg[1] = ptr to rb   *  arg[1] = ptr to rb
601   *  arg[2] = bf   *  arg[2] = 28 - 4*bf
602   */   */
603  X(cmpd)  X(cmpd)
604  {  {
605          int64_t tmp = reg(ic->arg[0]), tmp2 = reg(ic->arg[1]);          int64_t tmp = reg(ic->arg[0]), tmp2 = reg(ic->arg[1]);
606          int bf = ic->arg[2], c;          int bf_shift = ic->arg[2], c;
607          if (tmp < tmp2)          if (tmp < tmp2)
608                  c = 8;                  c = 8;
609          else if (tmp > tmp2)          else if (tmp > tmp2)
610                  c = 4;                  c = 4;
611          else          else
612                  c = 2;                  c = 2;
613          c |= ((cpu->cd.ppc.xer >> 31) & 1);  /*  SO bit, copied from XER  */          /*  SO bit, copied from XER  */
614          cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));          c |= ((cpu->cd.ppc.spr[SPR_XER] >> 31) & 1);
615          cpu->cd.ppc.cr |= (c << (28 - 4*bf));          cpu->cd.ppc.cr &= ~(0xf << bf_shift);
616            cpu->cd.ppc.cr |= (c << bf_shift);
617  }  }
618    
619    
# Line 526  X(cmpd) Line 622  X(cmpd)
622   *   *
623   *  arg[0] = ptr to ra   *  arg[0] = ptr to ra
624   *  arg[1] = ptr to rb   *  arg[1] = ptr to rb
625   *  arg[2] = bf   *  arg[2] = 28 - 4*bf
626   */   */
627  X(cmpld)  X(cmpld)
628  {  {
629          uint64_t tmp = reg(ic->arg[0]), tmp2 = reg(ic->arg[1]);          uint64_t tmp = reg(ic->arg[0]), tmp2 = reg(ic->arg[1]);
630          int bf = ic->arg[2], c;          int bf_shift = ic->arg[2], c;
631          if (tmp < tmp2)          if (tmp < tmp2)
632                  c = 8;                  c = 8;
633          else if (tmp > tmp2)          else if (tmp > tmp2)
634                  c = 4;                  c = 4;
635          else          else
636                  c = 2;                  c = 2;
637          c |= ((cpu->cd.ppc.xer >> 31) & 1);  /*  SO bit, copied from XER  */          /*  SO bit, copied from XER  */
638          cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));          c |= ((cpu->cd.ppc.spr[SPR_XER] >> 31) & 1);
639          cpu->cd.ppc.cr |= (c << (28 - 4*bf));          cpu->cd.ppc.cr &= ~(0xf << bf_shift);
640            cpu->cd.ppc.cr |= (c << bf_shift);
641  }  }
642    
643    
# Line 549  X(cmpld) Line 646  X(cmpld)
646   *   *
647   *  arg[0] = ptr to ra   *  arg[0] = ptr to ra
648   *  arg[1] = int32_t imm   *  arg[1] = int32_t imm
649   *  arg[2] = bf   *  arg[2] = 28 - 4*bf
650   */   */
651  X(cmpdi)  X(cmpdi)
652  {  {
653          int64_t tmp = reg(ic->arg[0]), imm = (int32_t)ic->arg[1];          int64_t tmp = reg(ic->arg[0]), imm = (int32_t)ic->arg[1];
654          int bf = ic->arg[2], c;          int bf_shift = ic->arg[2], c;
655          if (tmp < imm)          if (tmp < imm)
656                  c = 8;                  c = 8;
657          else if (tmp > imm)          else if (tmp > imm)
658                  c = 4;                  c = 4;
659          else          else
660                  c = 2;                  c = 2;
661          c |= ((cpu->cd.ppc.xer >> 31) & 1);  /*  SO bit, copied from XER  */          /*  SO bit, copied from XER  */
662          cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));          c |= ((cpu->cd.ppc.spr[SPR_XER] >> 31) & 1);
663          cpu->cd.ppc.cr |= (c << (28 - 4*bf));          cpu->cd.ppc.cr &= ~(0xf << bf_shift);
664            cpu->cd.ppc.cr |= (c << bf_shift);
665  }  }
666    
667    
# Line 572  X(cmpdi) Line 670  X(cmpdi)
670   *   *
671   *  arg[0] = ptr to ra   *  arg[0] = ptr to ra
672   *  arg[1] = int32_t imm   *  arg[1] = int32_t imm
673   *  arg[2] = bf   *  arg[2] = 28 - 4*bf
674   */   */
675  X(cmpldi)  X(cmpldi)
676  {  {
677          uint64_t tmp = reg(ic->arg[0]), imm = (uint32_t)ic->arg[1];          uint64_t tmp = reg(ic->arg[0]), imm = (uint32_t)ic->arg[1];
678          int bf = ic->arg[2], c;          int bf_shift = ic->arg[2], c;
679          if (tmp < imm)          if (tmp < imm)
680                  c = 8;                  c = 8;
681          else if (tmp > imm)          else if (tmp > imm)
682                  c = 4;                  c = 4;
683          else          else
684                  c = 2;                  c = 2;
685          c |= ((cpu->cd.ppc.xer >> 31) & 1);  /*  SO bit, copied from XER  */          /*  SO bit, copied from XER  */
686          cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));          c |= ((cpu->cd.ppc.spr[SPR_XER] >> 31) & 1);
687          cpu->cd.ppc.cr |= (c << (28 - 4*bf));          cpu->cd.ppc.cr &= ~(0xf << bf_shift);
688            cpu->cd.ppc.cr |= (c << bf_shift);
689  }  }
690    
691    
# Line 595  X(cmpldi) Line 694  X(cmpldi)
694   *   *
695   *  arg[0] = ptr to ra   *  arg[0] = ptr to ra
696   *  arg[1] = ptr to rb   *  arg[1] = ptr to rb
697   *  arg[2] = bf   *  arg[2] = 28 - 4*bf
698   */   */
699  X(cmpw)  X(cmpw)
700  {  {
701          int32_t tmp = reg(ic->arg[0]), tmp2 = reg(ic->arg[1]);          int32_t tmp = reg(ic->arg[0]), tmp2 = reg(ic->arg[1]);
702          int bf = ic->arg[2], c;          int bf_shift = ic->arg[2], c;
703          if (tmp < tmp2)          if (tmp < tmp2)
704                  c = 8;                  c = 8;
705          else if (tmp > tmp2)          else if (tmp > tmp2)
706                  c = 4;                  c = 4;
707          else          else
708                  c = 2;                  c = 2;
709          c |= ((cpu->cd.ppc.xer >> 31) & 1);  /*  SO bit, copied from XER  */          /*  SO bit, copied from XER  */
710          cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));          c |= ((cpu->cd.ppc.spr[SPR_XER] >> 31) & 1);
711          cpu->cd.ppc.cr |= (c << (28 - 4*bf));          cpu->cd.ppc.cr &= ~(0xf << bf_shift);
712            cpu->cd.ppc.cr |= (c << bf_shift);
713    }
714    X(cmpw_cr0)
715    {
716            /*  arg[2] is assumed to be 28  */
717            int32_t tmp = reg(ic->arg[0]), tmp2 = reg(ic->arg[1]);
718            cpu->cd.ppc.cr &= ~(0xf0000000);
719            if (tmp < tmp2)
720                    cpu->cd.ppc.cr |= 0x80000000;
721            else if (tmp > tmp2)
722                    cpu->cd.ppc.cr |= 0x40000000;
723            else
724                    cpu->cd.ppc.cr |= 0x20000000;
725            cpu->cd.ppc.cr |= ((cpu->cd.ppc.spr[SPR_XER] >> 3) & 0x10000000);
726  }  }
727    
728    
# Line 618  X(cmpw) Line 731  X(cmpw)
731   *   *
732   *  arg[0] = ptr to ra   *  arg[0] = ptr to ra
733   *  arg[1] = ptr to rb   *  arg[1] = ptr to rb
734   *  arg[2] = bf   *  arg[2] = 28 - 4*bf
735   */   */
736  X(cmplw)  X(cmplw)
737  {  {
738          uint32_t tmp = reg(ic->arg[0]), tmp2 = reg(ic->arg[1]);          uint32_t tmp = reg(ic->arg[0]), tmp2 = reg(ic->arg[1]);
739          int bf = ic->arg[2], c;          int bf_shift = ic->arg[2], c;
740          if (tmp < tmp2)          if (tmp < tmp2)
741                  c = 8;                  c = 8;
742          else if (tmp > tmp2)          else if (tmp > tmp2)
743                  c = 4;                  c = 4;
744          else          else
745                  c = 2;                  c = 2;
746          c |= ((cpu->cd.ppc.xer >> 31) & 1);  /*  SO bit, copied from XER  */          /*  SO bit, copied from XER  */
747          cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));          c |= ((cpu->cd.ppc.spr[SPR_XER] >> 31) & 1);
748          cpu->cd.ppc.cr |= (c << (28 - 4*bf));          cpu->cd.ppc.cr &= ~(0xf << bf_shift);
749            cpu->cd.ppc.cr |= (c << bf_shift);
750  }  }
751    
752    
# Line 641  X(cmplw) Line 755  X(cmplw)
755   *   *
756   *  arg[0] = ptr to ra   *  arg[0] = ptr to ra
757   *  arg[1] = int32_t imm   *  arg[1] = int32_t imm
758   *  arg[2] = bf   *  arg[2] = 28 - 4*bf
759   */   */
760  X(cmpwi)  X(cmpwi)
761  {  {
762          int32_t tmp = reg(ic->arg[0]), imm = ic->arg[1];          int32_t tmp = reg(ic->arg[0]), imm = ic->arg[1];
763          int bf = ic->arg[2], c;          int bf_shift = ic->arg[2], c;
764          if (tmp < imm)          if (tmp < imm)
765                  c = 8;                  c = 8;
766          else if (tmp > imm)          else if (tmp > imm)
767                  c = 4;                  c = 4;
768          else          else
769                  c = 2;                  c = 2;
770          c |= ((cpu->cd.ppc.xer >> 31) & 1);  /*  SO bit, copied from XER  */          /*  SO bit, copied from XER  */
771          cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));          c |= ((cpu->cd.ppc.spr[SPR_XER] >> 31) & 1);
772          cpu->cd.ppc.cr |= (c << (28 - 4*bf));          cpu->cd.ppc.cr &= ~(0xf << bf_shift);
773            cpu->cd.ppc.cr |= (c << bf_shift);
774    }
775    X(cmpwi_cr0)
776    {
777            /*  arg[2] is assumed to be 28  */
778            int32_t tmp = reg(ic->arg[0]), imm = ic->arg[1];
779            cpu->cd.ppc.cr &= ~(0xf0000000);
780            if (tmp < imm)
781                    cpu->cd.ppc.cr |= 0x80000000;
782            else if (tmp > imm)
783                    cpu->cd.ppc.cr |= 0x40000000;
784            else
785                    cpu->cd.ppc.cr |= 0x20000000;
786            cpu->cd.ppc.cr |= ((cpu->cd.ppc.spr[SPR_XER] >> 3) & 0x10000000);
787  }  }
788    
789    
# Line 664  X(cmpwi) Line 792  X(cmpwi)
792   *   *
793   *  arg[0] = ptr to ra   *  arg[0] = ptr to ra
794   *  arg[1] = int32_t imm   *  arg[1] = int32_t imm
795   *  arg[2] = bf   *  arg[2] = 28 - 4*bf
796   */   */
797  X(cmplwi)  X(cmplwi)
798  {  {
799          uint32_t tmp = reg(ic->arg[0]), imm = ic->arg[1];          uint32_t tmp = reg(ic->arg[0]), imm = ic->arg[1];
800          int bf = ic->arg[2], c;          int bf_shift = ic->arg[2], c;
801          if (tmp < imm)          if (tmp < imm)
802                  c = 8;                  c = 8;
803          else if (tmp > imm)          else if (tmp > imm)
804                  c = 4;                  c = 4;
805          else          else
806                  c = 2;                  c = 2;
807          c |= ((cpu->cd.ppc.xer >> 31) & 1);  /*  SO bit, copied from XER  */          /*  SO bit, copied from XER  */
808          cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));          c |= ((cpu->cd.ppc.spr[SPR_XER] >> 31) & 1);
809          cpu->cd.ppc.cr |= (c << (28 - 4*bf));          cpu->cd.ppc.cr &= ~(0xf << bf_shift);
810            cpu->cd.ppc.cr |= (c << bf_shift);
811  }  }
812    
813    
# Line 692  X(dcbz) Line 821  X(dcbz)
821  {  {
822          MODE_uint_t addr = reg(ic->arg[0]) + reg(ic->arg[1]);          MODE_uint_t addr = reg(ic->arg[0]) + reg(ic->arg[1]);
823          unsigned char cacheline[128];          unsigned char cacheline[128];
824          int cacheline_size = 1 << cpu->cd.ppc.cpu_type.dlinesize;          size_t cacheline_size = 1 << cpu->cd.ppc.cpu_type.dlinesize;
825          int cleared = 0;          size_t cleared = 0;
826    
827            /*  Synchronize the PC first:  */
828            cpu->pc = (cpu->pc & ~0xfff) + ic->arg[2];
829    
830          addr &= ~(cacheline_size - 1);          addr &= ~(cacheline_size - 1);
831          memset(cacheline, 0, sizeof(cacheline));          memset(cacheline, 0, sizeof(cacheline));
# Line 701  X(dcbz) Line 833  X(dcbz)
833          while (cleared < cacheline_size) {          while (cleared < cacheline_size) {
834                  int to_clear = cacheline_size < sizeof(cacheline)?                  int to_clear = cacheline_size < sizeof(cacheline)?
835                      cacheline_size : sizeof(cacheline);                      cacheline_size : sizeof(cacheline);
836                  if (cpu->memory_rw(cpu, cpu->mem, addr, cacheline, to_clear,  #ifdef MODE32
837                      MEM_WRITE, CACHE_DATA) != MEMORY_ACCESS_OK) {                  unsigned char *page = cpu->cd.ppc.host_store[addr >> 12];
838                          fatal("dcbz: error: TODO\n");                  if (page != NULL) {
839                          exit(1);                          memset(page + (addr & 0xfff), 0, to_clear);
840                    } else
841    #endif
842                    if (cpu->memory_rw(cpu, cpu->mem, addr, cacheline,
843                        to_clear, MEM_WRITE, CACHE_DATA) != MEMORY_ACCESS_OK) {
844                            /*  exception  */
845                            return;
846                  }                  }
847    
848                  cleared += to_clear;                  cleared += to_clear;
# Line 714  X(dcbz) Line 852  X(dcbz)
852    
853    
854  /*  /*
855     *  mtfsf:  Copy FPR into the FPSCR.
856     *
857     *  arg[0] = ptr to frb
858     *  arg[1] = mask
859     */
860    X(mtfsf)
861    {
862            CHECK_FOR_FPU_EXCEPTION;
863            cpu->cd.ppc.fpscr &= ~ic->arg[1];
864            cpu->cd.ppc.fpscr |= (ic->arg[1] & (*(uint64_t *)ic->arg[0]));
865    }
866    
867    
868    /*
869     *  mffs:  Copy FPSCR into a FPR.
870     *
871     *  arg[0] = ptr to frt
872     */
873    X(mffs)
874    {
875            CHECK_FOR_FPU_EXCEPTION;
876            (*(uint64_t *)ic->arg[0]) = cpu->cd.ppc.fpscr;
877    }
878    
879    
880    /*
881   *  fmr:  Floating-point Move   *  fmr:  Floating-point Move
882   *   *
883   *  arg[0] = ptr to frb   *  arg[0] = ptr to frb
# Line 721  X(dcbz) Line 885  X(dcbz)
885   */   */
886  X(fmr)  X(fmr)
887  {  {
888            /*
889             *  This works like a normal register to register copy, but
890             *  a) it can cause an FPU exception, and b) the move is always
891             *  64-bit, even when running in 32-bit mode.
892             */
893            CHECK_FOR_FPU_EXCEPTION;
894          *(uint64_t *)ic->arg[1] = *(uint64_t *)ic->arg[0];          *(uint64_t *)ic->arg[1] = *(uint64_t *)ic->arg[0];
895  }  }
896    
897    
898  /*  /*
899     *  fneg:  Floating-point Negate
900     *
901     *  arg[0] = ptr to frb
902     *  arg[1] = ptr to frt
903     */
904    X(fneg)
905    {
906            uint64_t v;
907            CHECK_FOR_FPU_EXCEPTION;
908            v = *(uint64_t *)ic->arg[0];
909            *(uint64_t *)ic->arg[1] = v ^ 0x8000000000000000ULL;
910    }
911    
912    
913    /*
914     *  fcmpu:  Floating-point Compare Unordered
915     *
916     *  arg[0] = 28 - 4*bf  (bitfield shift)
917     *  arg[1] = ptr to fra
918     *  arg[2] = ptr to frb
919     */
920    X(fcmpu)
921    {
922            struct ieee_float_value fra, frb;
923            int bf_shift = ic->arg[0], c = 0;
924    
925            CHECK_FOR_FPU_EXCEPTION;
926    
927            ieee_interpret_float_value(*(uint64_t *)ic->arg[1], &fra, IEEE_FMT_D);
928            ieee_interpret_float_value(*(uint64_t *)ic->arg[2], &frb, IEEE_FMT_D);
929            if (fra.nan | frb.nan) {
930                    c = 1;
931            } else {
932                    if (fra.f < frb.f)
933                            c = 8;
934                    else if (fra.f > frb.f)
935                            c = 4;
936                    else
937                            c = 2;
938            }
939            /*  TODO: Signaling vs Quiet NaN  */
940            cpu->cd.ppc.cr &= ~(0xf << bf_shift);
941            cpu->cd.ppc.cr |= ((c&0xe) << bf_shift);
942            cpu->cd.ppc.fpscr &= ~(PPC_FPSCR_FPCC | PPC_FPSCR_VXNAN);
943            cpu->cd.ppc.fpscr |= (c << PPC_FPSCR_FPCC_SHIFT);
944    }
945    
946    
947    /*
948     *  frsp:  Floating-point Round to Single Precision
949     *
950     *  arg[0] = ptr to frb
951     *  arg[1] = ptr to frt
952     */
953    X(frsp)
954    {
955            struct ieee_float_value frb;
956            float fl = 0.0;
957            int c = 0;
958    
959            CHECK_FOR_FPU_EXCEPTION;
960    
961            ieee_interpret_float_value(*(uint64_t *)ic->arg[0], &frb, IEEE_FMT_D);
962            if (frb.nan) {
963                    c = 1;
964            } else {
965                    fl = frb.f;
966                    if (fl < 0.0)
967                            c = 8;
968                    else if (fl > 0.0)
969                            c = 4;
970                    else
971                            c = 2;
972            }
973            /*  TODO: Signaling vs Quiet NaN  */
974            cpu->cd.ppc.fpscr &= ~(PPC_FPSCR_FPCC | PPC_FPSCR_VXNAN);
975            cpu->cd.ppc.fpscr |= (c << PPC_FPSCR_FPCC_SHIFT);
976            (*(uint64_t *)ic->arg[1]) =
977                ieee_store_float_value(fl, IEEE_FMT_D, frb.nan);
978    }
979    
980    
981    /*
982     *  fctiwz:  Floating-point Convert to Integer Word, Round to Zero
983     *
984     *  arg[0] = ptr to frb
985     *  arg[1] = ptr to frt
986     */
987    X(fctiwz)
988    {
989            struct ieee_float_value frb;
990            uint32_t res = 0;
991    
992            CHECK_FOR_FPU_EXCEPTION;
993    
994            ieee_interpret_float_value(*(uint64_t *)ic->arg[0], &frb, IEEE_FMT_D);
995            if (!frb.nan) {
996                    if (frb.f >= 2147483647.0)
997                            res = 0x7fffffff;
998                    else if (frb.f <= -2147483648.0)
999                            res = 0x80000000;
1000                    else
1001                            res = frb.f;
1002            }
1003            *(uint64_t *)ic->arg[1] = (uint32_t)res;
1004    }
1005    
1006    
1007    /*
1008     *  fmul:  Floating-point Multiply
1009     *
1010     *  arg[0] = ptr to frt
1011     *  arg[1] = ptr to fra
1012     *  arg[2] = ptr to frc
1013     */
1014    X(fmul)
1015    {
1016            struct ieee_float_value fra;
1017            struct ieee_float_value frc;
1018            double result = 0.0;
1019            int c, nan = 0;
1020    
1021            CHECK_FOR_FPU_EXCEPTION;
1022    
1023            ieee_interpret_float_value(*(uint64_t *)ic->arg[1], &fra, IEEE_FMT_D);
1024            ieee_interpret_float_value(*(uint64_t *)ic->arg[2], &frc, IEEE_FMT_D);
1025            if (fra.nan || frc.nan)
1026                    nan = 1;
1027            else
1028                    result = fra.f * frc.f;
1029            if (nan)
1030                    c = 1;
1031            else {
1032                    if (result < 0.0)
1033                            c = 8;
1034                    else if (result > 0.0)
1035                            c = 4;
1036                    else
1037                            c = 2;
1038            }
1039            /*  TODO: Signaling vs Quiet NaN  */
1040            cpu->cd.ppc.fpscr &= ~(PPC_FPSCR_FPCC | PPC_FPSCR_VXNAN);
1041            cpu->cd.ppc.fpscr |= (c << PPC_FPSCR_FPCC_SHIFT);
1042    
1043            (*(uint64_t *)ic->arg[0]) =
1044                ieee_store_float_value(result, IEEE_FMT_D, nan);
1045    }
1046    X(fmuls)
1047    {
1048            /*  TODO  */
1049            instr(fmul)(cpu, ic);
1050    }
1051    
1052    
1053    /*
1054     *  fmadd:  Floating-point Multiply and Add
1055     *
1056     *  arg[0] = ptr to frt
1057     *  arg[1] = ptr to fra
1058     *  arg[2] = copy of the instruction word
1059     */
1060    X(fmadd)
1061    {
1062            uint32_t iw = ic->arg[2];
1063            int b = (iw >> 11) & 31, c = (iw >> 6) & 31;
1064            struct ieee_float_value fra;
1065            struct ieee_float_value frb;
1066            struct ieee_float_value frc;
1067            double result = 0.0;
1068            int nan = 0, cc;
1069    
1070            CHECK_FOR_FPU_EXCEPTION;
1071    
1072            ieee_interpret_float_value(*(uint64_t *)ic->arg[1], &fra, IEEE_FMT_D);
1073            ieee_interpret_float_value(cpu->cd.ppc.fpr[b], &frb, IEEE_FMT_D);
1074            ieee_interpret_float_value(cpu->cd.ppc.fpr[c], &frc, IEEE_FMT_D);
1075            if (fra.nan || frb.nan || frc.nan)
1076                    nan = 1;
1077            else
1078                    result = fra.f * frc.f + frb.f;
1079            if (nan)
1080                    cc = 1;
1081            else {
1082                    if (result < 0.0)
1083                            cc = 8;
1084                    else if (result > 0.0)
1085                            cc = 4;
1086                    else
1087                            cc = 2;
1088            }
1089            /*  TODO: Signaling vs Quiet NaN  */
1090            cpu->cd.ppc.fpscr &= ~(PPC_FPSCR_FPCC | PPC_FPSCR_VXNAN);
1091            cpu->cd.ppc.fpscr |= (cc << PPC_FPSCR_FPCC_SHIFT);
1092    
1093            (*(uint64_t *)ic->arg[0]) =
1094                ieee_store_float_value(result, IEEE_FMT_D, nan);
1095    }
1096    
1097    
1098    /*
1099     *  fmsub:  Floating-point Multiply and Sub
1100     *
1101     *  arg[0] = ptr to frt
1102     *  arg[1] = ptr to fra
1103     *  arg[2] = copy of the instruction word
1104     */
1105    X(fmsub)
1106    {
1107            uint32_t iw = ic->arg[2];
1108            int b = (iw >> 11) & 31, c = (iw >> 6) & 31;
1109            struct ieee_float_value fra;
1110            struct ieee_float_value frb;
1111            struct ieee_float_value frc;
1112            double result = 0.0;
1113            int nan = 0, cc;
1114    
1115            CHECK_FOR_FPU_EXCEPTION;
1116    
1117            ieee_interpret_float_value(*(uint64_t *)ic->arg[1], &fra, IEEE_FMT_D);
1118            ieee_interpret_float_value(cpu->cd.ppc.fpr[b], &frb, IEEE_FMT_D);
1119            ieee_interpret_float_value(cpu->cd.ppc.fpr[c], &frc, IEEE_FMT_D);
1120            if (fra.nan || frb.nan || frc.nan)
1121                    nan = 1;
1122            else
1123                    result = fra.f * frc.f - frb.f;
1124            if (nan)
1125                    cc = 1;
1126            else {
1127                    if (result < 0.0)
1128                            cc = 8;
1129                    else if (result > 0.0)
1130                            cc = 4;
1131                    else
1132                            cc = 2;
1133            }
1134            /*  TODO: Signaling vs Quiet NaN  */
1135            cpu->cd.ppc.fpscr &= ~(PPC_FPSCR_FPCC | PPC_FPSCR_VXNAN);
1136            cpu->cd.ppc.fpscr |= (cc << PPC_FPSCR_FPCC_SHIFT);
1137    
1138            (*(uint64_t *)ic->arg[0]) =
1139                ieee_store_float_value(result, IEEE_FMT_D, nan);
1140    }
1141    
1142    
1143    /*
1144     *  fadd, fsub, fdiv:  Various Floating-point operationgs
1145     *
1146     *  arg[0] = ptr to fra
1147     *  arg[1] = ptr to frb
1148     *  arg[2] = ptr to frt
1149     */
1150    X(fadd)
1151    {
1152            struct ieee_float_value fra;
1153            struct ieee_float_value frb;
1154            double result = 0.0;
1155            int nan = 0, c;
1156    
1157            CHECK_FOR_FPU_EXCEPTION;
1158    
1159            ieee_interpret_float_value(*(uint64_t *)ic->arg[0], &fra, IEEE_FMT_D);
1160            ieee_interpret_float_value(*(uint64_t *)ic->arg[1], &frb, IEEE_FMT_D);
1161            if (fra.nan || frb.nan)
1162                    nan = 1;
1163            else
1164                    result = fra.f + frb.f;
1165            if (nan)
1166                    c = 1;
1167            else {
1168                    if (result < 0.0)
1169                            c = 8;
1170                    else if (result > 0.0)
1171                            c = 4;
1172                    else
1173                            c = 2;
1174            }
1175            /*  TODO: Signaling vs Quiet NaN  */
1176            cpu->cd.ppc.fpscr &= ~(PPC_FPSCR_FPCC | PPC_FPSCR_VXNAN);
1177            cpu->cd.ppc.fpscr |= (c << PPC_FPSCR_FPCC_SHIFT);
1178    
1179            (*(uint64_t *)ic->arg[2]) =
1180                ieee_store_float_value(result, IEEE_FMT_D, nan);
1181    }
1182    X(fadds)
1183    {
1184            /*  TODO  */
1185            instr(fadd)(cpu, ic);
1186    }
1187    X(fsub)
1188    {
1189            struct ieee_float_value fra;
1190            struct ieee_float_value frb;
1191            double result = 0.0;
1192            int nan = 0, c;
1193    
1194            CHECK_FOR_FPU_EXCEPTION;
1195    
1196            ieee_interpret_float_value(*(uint64_t *)ic->arg[0], &fra, IEEE_FMT_D);
1197            ieee_interpret_float_value(*(uint64_t *)ic->arg[1], &frb, IEEE_FMT_D);
1198            if (fra.nan || frb.nan)
1199                    nan = 1;
1200            else
1201                    result = fra.f - frb.f;
1202            if (nan)
1203                    c = 1;
1204            else {
1205                    if (result < 0.0)
1206                            c = 8;
1207                    else if (result > 0.0)
1208                            c = 4;
1209                    else
1210                            c = 2;
1211            }
1212            /*  TODO: Signaling vs Quiet NaN  */
1213            cpu->cd.ppc.fpscr &= ~(PPC_FPSCR_FPCC | PPC_FPSCR_VXNAN);
1214            cpu->cd.ppc.fpscr |= (c << PPC_FPSCR_FPCC_SHIFT);
1215    
1216            (*(uint64_t *)ic->arg[2]) =
1217                ieee_store_float_value(result, IEEE_FMT_D, nan);
1218    }
1219    X(fsubs)
1220    {
1221            /*  TODO  */
1222            instr(fsub)(cpu, ic);
1223    }
1224    X(fdiv)
1225    {
1226            struct ieee_float_value fra;
1227            struct ieee_float_value frb;
1228            double result = 0.0;
1229            int nan = 0, c;
1230    
1231            CHECK_FOR_FPU_EXCEPTION;
1232    
1233            ieee_interpret_float_value(*(uint64_t *)ic->arg[0], &fra, IEEE_FMT_D);
1234            ieee_interpret_float_value(*(uint64_t *)ic->arg[1], &frb, IEEE_FMT_D);
1235            if (fra.nan || frb.nan || frb.f == 0)
1236                    nan = 1;
1237            else
1238                    result = fra.f / frb.f;
1239            if (nan)
1240                    c = 1;
1241            else {
1242                    if (result < 0.0)
1243                            c = 8;
1244                    else if (result > 0.0)
1245                            c = 4;
1246                    else
1247                            c = 2;
1248            }
1249            /*  TODO: Signaling vs Quiet NaN  */
1250            cpu->cd.ppc.fpscr &= ~(PPC_FPSCR_FPCC | PPC_FPSCR_VXNAN);
1251            cpu->cd.ppc.fpscr |= (c << PPC_FPSCR_FPCC_SHIFT);
1252    
1253            (*(uint64_t *)ic->arg[2]) =
1254                ieee_store_float_value(result, IEEE_FMT_D, nan);
1255    }
1256    X(fdivs)
1257    {
1258            /*  TODO  */
1259            instr(fdiv)(cpu, ic);
1260    }
1261    
1262    
1263    /*
1264   *  llsc: Load-linked and store conditional   *  llsc: Load-linked and store conditional
1265   *   *
1266   *  arg[0] = copy of the instruction word.   *  arg[0] = copy of the instruction word.
# Line 781  X(llsc) Line 1316  X(llsc)
1316                  cpu->cd.ppc.ll_addr = addr;                  cpu->cd.ppc.ll_addr = addr;
1317                  cpu->cd.ppc.ll_bit = 1;                  cpu->cd.ppc.ll_bit = 1;
1318          } else {          } else {
1319                  int old_so = cpu->cd.ppc.xer & PPC_XER_SO;                  uint32_t old_so = cpu->cd.ppc.spr[SPR_XER] & PPC_XER_SO;
1320                  if (!rc) {                  if (!rc) {
1321                          fatal("sc: rc-bit not set?\n");                          fatal("sc: rc-bit not set?\n");
1322                          exit(1);                          exit(1);
# Line 827  X(llsc) Line 1362  X(llsc)
1362    
1363    
1364  /*  /*
1365   *  mtsr:  Move To Segment Register   *  mtsr, mtsrin:  Move To Segment Register [Indirect]
1366   *   *
1367   *  arg[0] = segment register nr (0..15)   *  arg[0] = sr number, or for indirect mode: ptr to rb
1368   *  arg[1] = ptr to rt   *  arg[1] = ptr to rt
1369     *
1370     *  TODO: These only work for 32-bit mode!
1371   */   */
1372  X(mtsr)  X(mtsr)
1373  {  {
1374          /*  TODO: This only works for 32-bit mode  */          int sr_num = ic->arg[0];
1375          cpu->cd.ppc.sr[ic->arg[0]] = reg(ic->arg[1]);          uint32_t old = cpu->cd.ppc.sr[sr_num];
1376            cpu->cd.ppc.sr[sr_num] = reg(ic->arg[1]);
1377    
1378            if (cpu->cd.ppc.sr[sr_num] != old)
1379                    cpu->invalidate_translation_caches(cpu, ic->arg[0] << 28,
1380                        INVALIDATE_ALL | INVALIDATE_VADDR_UPPER4);
1381    }
1382    X(mtsrin)
1383    {
1384            int sr_num = reg(ic->arg[0]) >> 28;
1385            uint32_t old = cpu->cd.ppc.sr[sr_num];
1386            cpu->cd.ppc.sr[sr_num] = reg(ic->arg[1]);
1387    
1388            if (cpu->cd.ppc.sr[sr_num] != old)
1389                    cpu->invalidate_translation_caches(cpu, sr_num << 28,
1390                        INVALIDATE_ALL | INVALIDATE_VADDR_UPPER4);
1391  }  }
1392    
1393    
1394  /*  /*
1395   *  mfsrin, mtsrin:  Move From/To Segment Register Indirect   *  mfsrin, mtsrin:  Move From/To Segment Register Indirect
1396   *   *
1397   *  arg[0] = ptr to rb   *  arg[0] = sr number, or for indirect mode: ptr to rb
1398   *  arg[1] = ptr to rt   *  arg[1] = ptr to rt
1399   */   */
1400    X(mfsr)
1401    {
1402            /*  TODO: This only works for 32-bit mode  */
1403            reg(ic->arg[1]) = cpu->cd.ppc.sr[ic->arg[0]];
1404    }
1405  X(mfsrin)  X(mfsrin)
1406  {  {
1407          /*  TODO: This only works for 32-bit mode  */          /*  TODO: This only works for 32-bit mode  */
1408          uint32_t sr_num = reg(ic->arg[0]) >> 28;          uint32_t sr_num = reg(ic->arg[0]) >> 28;
1409          reg(ic->arg[1]) = cpu->cd.ppc.sr[sr_num];          reg(ic->arg[1]) = cpu->cd.ppc.sr[sr_num];
1410  }  }
1411  X(mtsrin)  
1412    
1413    /*
1414     *  rldicl:
1415     *
1416     *  arg[0] = copy of the instruction word
1417     */
1418    X(rldicl)
1419  {  {
1420          /*  TODO: This only works for 32-bit mode  */          int rs = (ic->arg[0] >> 21) & 31;
1421          uint32_t sr_num = reg(ic->arg[0]) >> 28;          int ra = (ic->arg[0] >> 16) & 31;
1422          cpu->cd.ppc.sr[sr_num] = reg(ic->arg[1]);          int sh = ((ic->arg[0] >> 11) & 31) | ((ic->arg[0] & 2) << 4);
1423            int mb = ((ic->arg[0] >> 6) & 31) | (ic->arg[0] & 0x20);
1424            int rc = ic->arg[0] & 1;
1425            uint64_t tmp = cpu->cd.ppc.gpr[rs], tmp2;
1426            /*  TODO: Fix this, its performance is awful:  */
1427            while (sh-- != 0) {
1428                    int b = (tmp >> 63) & 1;
1429                    tmp = (tmp << 1) | b;
1430            }
1431            tmp2 = 0;
1432            while (mb <= 63) {
1433                    tmp |= ((uint64_t)1 << (63-mb));
1434                    mb ++;
1435            }
1436            cpu->cd.ppc.gpr[ra] = tmp & tmp2;
1437            if (rc)
1438                    update_cr0(cpu, cpu->cd.ppc.gpr[ra]);
1439  }  }
1440    
1441    
# Line 886  X(rldicr) Line 1466  X(rldicr)
1466    
1467    
1468  /*  /*
1469   *  rlwinm:   *  rldimi:
1470   *   *
1471   *  arg[0] = ptr to rs   *  arg[0] = copy of the instruction word
  *  arg[1] = ptr to ra  
  *  arg[2] = copy of the instruction word  
1472   */   */
1473  X(rlwinm)  X(rldimi)
1474  {  {
1475          MODE_uint_t tmp = reg(ic->arg[0]), ra = 0;          uint32_t iw = ic->arg[0];
1476          uint32_t iword = ic->arg[2];          int rs = (iw >> 21) & 31, ra = (iw >> 16) & 31;
1477          int sh, mb, me, rc;          int sh = ((iw >> 11) & 31) | ((iw & 2) << 4);
1478            int mb = ((iw >> 6) & 31) | (iw & 0x20);
1479          sh = (iword >> 11) & 31;          int rc = ic->arg[0] & 1;
1480          mb = (iword >> 6) & 31;          int m;
1481          me = (iword >> 1) & 31;            uint64_t tmp, s = cpu->cd.ppc.gpr[rs];
         rc = iword & 1;  
   
1482          /*  TODO: Fix this, its performance is awful:  */          /*  TODO: Fix this, its performance is awful:  */
1483          while (sh-- != 0) {          while (sh-- != 0) {
1484                  int b = (tmp >> 31) & 1;                  int b = (s >> 63) & 1;
1485                  tmp = (tmp << 1) | b;                  s = (s << 1) | b;
         }  
         for (;;) {  
                 uint64_t mask;  
                 mask = (uint64_t)1 << (31-mb);  
                 ra |= (tmp & mask);  
                 if (mb == me)  
                         break;  
                 mb ++;  
                 if (mb == 32)  
                         mb = 0;  
1486          }          }
1487          reg(ic->arg[1]) = ra;          m = mb; tmp = 0;
1488            do {
1489                    tmp |= ((uint64_t)1 << (63-m));
1490                    m ++;
1491            } while (m != 63 - sh);
1492            cpu->cd.ppc.gpr[ra] &= ~tmp;
1493            cpu->cd.ppc.gpr[ra] |= (tmp & s);
1494          if (rc)          if (rc)
1495                  update_cr0(cpu, ra);                  update_cr0(cpu, cpu->cd.ppc.gpr[ra]);
1496    }
1497    
1498    
1499    /*
1500     *  rlwnm:
1501     *
1502     *  arg[0] = ptr to ra
1503     *  arg[1] = mask
1504     *  arg[2] = copy of the instruction word
1505     */
1506    X(rlwnm)
1507    {
1508            uint32_t tmp, iword = ic->arg[2];
1509            int rs = (iword >> 21) & 31;
1510            int rb = (iword >> 11) & 31;
1511            int sh = cpu->cd.ppc.gpr[rb] & 0x1f;
1512            tmp = (uint32_t)cpu->cd.ppc.gpr[rs];
1513            tmp = (tmp << sh) | (tmp >> (32-sh));
1514            tmp &= (uint32_t)ic->arg[1];
1515            reg(ic->arg[0]) = tmp;
1516    }
1517    DOT0(rlwnm)
1518    
1519    
1520    /*
1521     *  rlwinm:
1522     *
1523     *  arg[0] = ptr to ra
1524     *  arg[1] = mask
1525     *  arg[2] = copy of the instruction word
1526     */
1527    X(rlwinm)
1528    {
1529            uint32_t tmp, iword = ic->arg[2];
1530            int rs = (iword >> 21) & 31;
1531            int sh = (iword >> 11) & 31;
1532            tmp = (uint32_t)cpu->cd.ppc.gpr[rs];
1533            tmp = (tmp << sh) | (tmp >> (32-sh));
1534            tmp &= (uint32_t)ic->arg[1];
1535            reg(ic->arg[0]) = tmp;
1536  }  }
1537    DOT0(rlwinm)
1538    
1539    
1540  /*  /*
# Line 935  X(rlwimi) Line 1548  X(rlwimi)
1548  {  {
1549          MODE_uint_t tmp = reg(ic->arg[0]), ra = reg(ic->arg[1]);          MODE_uint_t tmp = reg(ic->arg[0]), ra = reg(ic->arg[1]);
1550          uint32_t iword = ic->arg[2];          uint32_t iword = ic->arg[2];
1551          int sh, mb, me, rc;          int sh = (iword >> 11) & 31;
1552            int mb = (iword >> 6) & 31;
1553            int me = (iword >> 1) & 31;  
1554            int rc = iword & 1;
1555    
1556          sh = (iword >> 11) & 31;          tmp = (tmp << sh) | (tmp >> (32-sh));
         mb = (iword >> 6) & 31;  
         me = (iword >> 1) & 31;    
         rc = iword & 1;  
1557    
         /*  TODO: Fix this, its performance is awful:  */  
         while (sh-- != 0) {  
                 int b = (tmp >> 31) & 1;  
                 tmp = (tmp << 1) | b;  
         }  
1558          for (;;) {          for (;;) {
1559                  uint64_t mask;                  uint64_t mask;
1560                  mask = (uint64_t)1 << (31-mb);                  mask = (uint64_t)1 << (31-mb);
# Line 976  X(srawi) Line 1584  X(srawi)
1584          uint32_t tmp = reg(ic->arg[0]);          uint32_t tmp = reg(ic->arg[0]);
1585          int i = 0, j = 0, sh = ic->arg[2];          int i = 0, j = 0, sh = ic->arg[2];
1586    
1587          cpu->cd.ppc.xer &= ~PPC_XER_CA;          cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
1588          if (tmp & 0x80000000)          if (tmp & 0x80000000)
1589                  i = 1;                  i = 1;
1590          while (sh-- > 0) {          while (sh-- > 0) {
# Line 987  X(srawi) Line 1595  X(srawi)
1595                          tmp |= 0x80000000;                          tmp |= 0x80000000;
1596          }          }
1597          if (i && j>0)          if (i && j>0)
1598                  cpu->cd.ppc.xer |= PPC_XER_CA;                  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
1599          reg(ic->arg[1]) = (int64_t)(int32_t)tmp;          reg(ic->arg[1]) = (int64_t)(int32_t)tmp;
1600  }  }
1601  DOT(srawi)  DOT1(srawi)
1602    
1603    
1604  /*  /*
1605   *  mcrf:  Move inside condition register   *  mcrf:  Move inside condition register
1606   *   *
1607   *  arg[0] = bf,  arg[1] = bfa   *  arg[0] = 28-4*bf,  arg[1] = 28-4*bfa
1608   */   */
1609  X(mcrf)  X(mcrf)
1610  {  {
1611          int bf = ic->arg[0], bfa = ic->arg[1];          int bf_shift = ic->arg[0], bfa_shift = ic->arg[1];
1612          uint32_t tmp = (cpu->cd.ppc.cr >> (28 - bfa*4)) & 0xf;          uint32_t tmp = (cpu->cd.ppc.cr >> bfa_shift) & 0xf;
1613          cpu->cd.ppc.cr &= ~(0xf << (28 - bf*4));          cpu->cd.ppc.cr &= ~(0xf << bf_shift);
1614          cpu->cd.ppc.cr |= (tmp << (28 - bf*4));          cpu->cd.ppc.cr |= (tmp << bf_shift);
1615  }  }
1616    
1617    
# Line 1048  X(cror) { Line 1656  X(cror) {
1656          if (ba | bb)          if (ba | bb)
1657                  cpu->cd.ppc.cr |= (1 << (31-bt));                  cpu->cd.ppc.cr |= (1 << (31-bt));
1658  }  }
1659    X(crorc) {
1660            uint32_t iword = ic->arg[0]; int bt = (iword >> 21) & 31;
1661            int ba = (iword >> 16) & 31, bb = (iword >> 11) & 31;
1662            ba = (cpu->cd.ppc.cr >> (31-ba)) & 1;
1663            bb = (cpu->cd.ppc.cr >> (31-bb)) & 1;
1664            cpu->cd.ppc.cr &= ~(1 << (31-bt));
1665            if (!(ba | bb))
1666                    cpu->cd.ppc.cr |= (1 << (31-bt));
1667    }
1668    X(crnor) {
1669            uint32_t iword = ic->arg[0]; int bt = (iword >> 21) & 31;
1670            int ba = (iword >> 16) & 31, bb = (iword >> 11) & 31;
1671            ba = (cpu->cd.ppc.cr >> (31-ba)) & 1;
1672            bb = (cpu->cd.ppc.cr >> (31-bb)) & 1;
1673            cpu->cd.ppc.cr &= ~(1 << (31-bt));
1674            if (!(ba | bb))
1675                    cpu->cd.ppc.cr |= (1 << (31-bt));
1676    }
1677  X(crxor) {  X(crxor) {
1678          uint32_t iword = ic->arg[0]; int bt = (iword >> 21) & 31;          uint32_t iword = ic->arg[0]; int bt = (iword >> 21) & 31;
1679          int ba = (iword >> 16) & 31, bb = (iword >> 11) & 31;          int ba = (iword >> 16) & 31, bb = (iword >> 11) & 31;
# Line 1060  X(crxor) { Line 1686  X(crxor) {
1686    
1687    
1688  /*  /*
1689   *  mflr, etc:  Move from Link Register etc.   *  mfspr: Move from SPR
1690   *   *
1691   *  arg[0] = pointer to destination register   *  arg[0] = pointer to destination register
1692     *  arg[1] = pointer to source SPR
1693   */   */
1694  X(mflr) {       reg(ic->arg[0]) = cpu->cd.ppc.lr; }  X(mfspr) {
1695  X(mfctr) {      reg(ic->arg[0]) = cpu->cd.ppc.ctr; }          /*  TODO: Check permission  */
1696  X(mftb) {       reg(ic->arg[0]) = cpu->cd.ppc.tbl; }          reg(ic->arg[0]) = reg(ic->arg[1]);
1697  X(mftbu) {      reg(ic->arg[0]) = cpu->cd.ppc.tbu; }  }
1698  /*  TODO: Check privilege level for mfsprg*  */  X(mfspr_pmc1) {
1699  X(mfsrr0) {     reg(ic->arg[0]) = cpu->cd.ppc.srr0; }          /*
1700  X(mfsrr1) {     reg(ic->arg[0]) = cpu->cd.ppc.srr1; }           *  TODO: This is a temporary hack to make NetBSD/ppc detect
1701  X(mfsdr1) {     reg(ic->arg[0]) = cpu->cd.ppc.sdr1; }           *  a CPU of the correct (emulated) speed.
1702  X(mfdbsr) {     reg(ic->arg[0]) = cpu->cd.ppc.dbsr; }           */
1703  X(mfhid1) {     reg(ic->arg[0]) = 0;  /*  TODO  */ }          reg(ic->arg[0]) = cpu->machine->emulated_hz / 10;
1704  X(mfl2cr) {     reg(ic->arg[0]) = 0;  /*  TODO  */ }  }
1705  X(mfsprg0) {    reg(ic->arg[0]) = cpu->cd.ppc.sprg0; }  X(mftb) {
1706  X(mfsprg1) {    reg(ic->arg[0]) = cpu->cd.ppc.sprg1; }          /*  NOTE/TODO: This increments the time base (slowly) if it
1707  X(mfsprg2) {    reg(ic->arg[0]) = cpu->cd.ppc.sprg2; }              is being polled.  */
1708  X(mfsprg3) {    reg(ic->arg[0]) = cpu->cd.ppc.sprg3; }          if (++cpu->cd.ppc.spr[SPR_TBL] == 0)
1709  X(mfpvr) {      reg(ic->arg[0]) = cpu->cd.ppc.pvr; }                  cpu->cd.ppc.spr[SPR_TBU] ++;
1710  X(mfibatu) {    reg(ic->arg[0]) = cpu->cd.ppc.ibat_u[ic->arg[1]]; }          reg(ic->arg[0]) = cpu->cd.ppc.spr[SPR_TBL];
1711  X(mfibatl) {    reg(ic->arg[0]) = cpu->cd.ppc.ibat_l[ic->arg[1]]; }  }
1712  X(mfdbatu) {    reg(ic->arg[0]) = cpu->cd.ppc.dbat_u[ic->arg[1]]; }  X(mftbu) {
1713  X(mfdbatl) {    reg(ic->arg[0]) = cpu->cd.ppc.dbat_l[ic->arg[1]]; }          reg(ic->arg[0]) = cpu->cd.ppc.spr[SPR_TBU];
1714    }
1715    
1716    
1717  /*  /*
1718   *  mtlr etc.:  Move to Link Register (or other special register)   *  mtspr: Move to SPR.
1719   *   *
1720   *  arg[0] = pointer to source register   *  arg[0] = pointer to source register
1721     *  arg[1] = pointer to the SPR
1722   */   */
1723  X(mtlr) {       cpu->cd.ppc.lr = reg(ic->arg[0]); }  X(mtspr) {
1724  X(mtctr) {      cpu->cd.ppc.ctr = reg(ic->arg[0]); }          /*  TODO: Check permission  */
1725  /*  TODO: Check privilege level for these:  */          reg(ic->arg[1]) = reg(ic->arg[0]);
1726  X(mtsrr0) {     cpu->cd.ppc.srr0 = reg(ic->arg[0]); }  }
1727  X(mtsrr1) {     cpu->cd.ppc.srr1 = reg(ic->arg[0]); }  X(mtlr) {
1728  X(mtsdr1) {     cpu->cd.ppc.sdr1 = reg(ic->arg[0]); }          cpu->cd.ppc.spr[SPR_LR] = reg(ic->arg[0]);
1729  X(mtdbsr) {     cpu->cd.ppc.dbsr = reg(ic->arg[0]); }  }
1730  X(mtsprg0) {    cpu->cd.ppc.sprg0 = reg(ic->arg[0]); }  X(mtctr) {
1731  X(mtsprg1) {    cpu->cd.ppc.sprg1 = reg(ic->arg[0]); }          cpu->cd.ppc.spr[SPR_CTR] = reg(ic->arg[0]);
1732  X(mtsprg2) {    cpu->cd.ppc.sprg2 = reg(ic->arg[0]); }  }
 X(mtsprg3) {    cpu->cd.ppc.sprg3 = reg(ic->arg[0]); }  
 X(mtibatu) {    cpu->cd.ppc.ibat_u[ic->arg[1]] = reg(ic->arg[0]); }  
 X(mtibatl) {    cpu->cd.ppc.ibat_l[ic->arg[1]] = reg(ic->arg[0]); }  
 X(mtdbatu) {    cpu->cd.ppc.dbat_u[ic->arg[1]] = reg(ic->arg[0]); }  
 X(mtdbatl) {    cpu->cd.ppc.dbat_l[ic->arg[1]] = reg(ic->arg[0]); }  
1733    
1734    
1735  /*  /*
1736   *  rfi:  Return from Interrupt   *  rfi[d]:  Return from Interrupt
1737   */   */
1738  X(rfi)  X(rfi)
1739  {  {
1740          uint64_t tmp;          uint64_t tmp;
1741    
1742          reg_access_msr(cpu, &tmp, 0);          reg_access_msr(cpu, &tmp, 0, 0);
1743          tmp &= ~0xffff;          tmp &= ~0xffff;
1744          tmp |= (cpu->cd.ppc.srr1 & 0xffff);          tmp |= (cpu->cd.ppc.spr[SPR_SRR1] & 0xffff);
1745          reg_access_msr(cpu, &tmp, 1);          reg_access_msr(cpu, &tmp, 1, 0);
1746    
1747            cpu->pc = cpu->cd.ppc.spr[SPR_SRR0];
1748            quick_pc_to_pointers(cpu);
1749    }
1750    X(rfid)
1751    {
1752            uint64_t tmp, mask = 0x800000000000ff73ULL;
1753    
1754            reg_access_msr(cpu, &tmp, 0, 0);
1755            tmp &= ~mask;
1756            tmp |= (cpu->cd.ppc.spr[SPR_SRR1] & mask);
1757            reg_access_msr(cpu, &tmp, 1, 0);
1758    
1759          cpu->pc = cpu->cd.ppc.srr0;          cpu->pc = cpu->cd.ppc.spr[SPR_SRR0];
1760          DYNTRANS_PC_TO_POINTERS(cpu);          if (!(tmp & PPC_MSR_SF))
1761                    cpu->pc = (uint32_t)cpu->pc;
1762            quick_pc_to_pointers(cpu);
1763  }  }
1764    
1765    
# Line 1143  X(mfcr) Line 1781  X(mfcr)
1781   */   */
1782  X(mfmsr)  X(mfmsr)
1783  {  {
1784          reg_access_msr(cpu, (uint64_t*)ic->arg[0], 0);          reg_access_msr(cpu, (uint64_t*)ic->arg[0], 0, 0);
1785  }  }
1786    
1787    
# Line 1151  X(mfmsr) Line 1789  X(mfmsr)
1789   *  mtmsr:  Move To MSR   *  mtmsr:  Move To MSR
1790   *   *
1791   *  arg[0] = pointer to source register   *  arg[0] = pointer to source register
1792     *  arg[1] = page offset of the next instruction
1793     *  arg[2] = 0 for 32-bit (mtmsr), 1 for 64-bit (mtmsrd)
1794   */   */
1795  X(mtmsr)  X(mtmsr)
1796  {  {
1797          reg_access_msr(cpu, (uint64_t*)ic->arg[0], 1);          MODE_uint_t old_pc;
1798            uint64_t x = reg(ic->arg[0]);
1799    
1800            /*  TODO: check permission!  */
1801    
1802            /*  Synchronize the PC (pointing to _after_ this instruction)  */
1803            cpu->pc = (cpu->pc & ~0xfff) + ic->arg[1];
1804            old_pc = cpu->pc;
1805    
1806            if (!ic->arg[2]) {
1807                    uint64_t y;
1808                    reg_access_msr(cpu, &y, 0, 0);
1809                    x = (y & 0xffffffff00000000ULL) | (x & 0xffffffffULL);
1810            }
1811    
1812            reg_access_msr(cpu, &x, 1, 1);
1813    
1814            /*
1815             *  Super-ugly hack:  If the pc wasn't changed (i.e. if there was no
1816             *  exception while accessing the msr), then we _decrease_ the PC by 4
1817             *  again. This is because the next ic could be an end_of_page.
1818             */
1819            if ((MODE_uint_t)cpu->pc == old_pc)
1820                    cpu->pc -= 4;
1821    }
1822    
1823    
1824    /*
1825     *  wrteei:  Write EE immediate  (on PPC405GP)
1826     *
1827     *  arg[0] = either 0 or 0x8000
1828     */
1829    X(wrteei)
1830    {
1831            /*  TODO: check permission!  */
1832            uint64_t x;
1833    
1834            /*  Synchronize the PC (pointing to _after_ this instruction)  */
1835            cpu->pc = (cpu->pc & ~0xfff) + ic->arg[1];
1836    
1837            reg_access_msr(cpu, &x, 0, 0);
1838            x = (x & ~0x8000) | ic->arg[0];
1839            reg_access_msr(cpu, &x, 1, 1);
1840  }  }
1841    
1842    
# Line 1179  X(mtcrf) Line 1861  X(mtcrf)
1861   */   */
1862  X(mulli)  X(mulli)
1863  {  {
1864          reg(ic->arg[2]) = (uint32_t)(reg(ic->arg[0]) * ic->arg[1]);          reg(ic->arg[2]) = (uint32_t)(reg(ic->arg[0]) * (int32_t)ic->arg[1]);
1865  }  }
1866    
1867    
# Line 1193  X(mulli) Line 1875  X(mulli)
1875  X(lmw) {  X(lmw) {
1876          MODE_uint_t addr = reg(ic->arg[1]) + (int32_t)ic->arg[2];          MODE_uint_t addr = reg(ic->arg[1]) + (int32_t)ic->arg[2];
1877          unsigned char d[4];          unsigned char d[4];
1878          int n_err = 0, rs = ic->arg[0];          int rs = ic->arg[0];
1879    
1880            int low_pc = ((size_t)ic - (size_t)cpu->cd.ppc.cur_ic_page)
1881                / sizeof(struct ppc_instr_call);
1882            cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1)
1883                << PPC_INSTR_ALIGNMENT_SHIFT);
1884            cpu->pc |= (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
1885    
1886          while (rs <= 31) {          while (rs <= 31) {
1887                  if (cpu->memory_rw(cpu, cpu->mem, addr, d, sizeof(d),                  if (cpu->memory_rw(cpu, cpu->mem, addr, d, sizeof(d),
1888                      MEM_READ, CACHE_DATA) != MEMORY_ACCESS_OK)                      MEM_READ, CACHE_DATA) != MEMORY_ACCESS_OK) {
1889                          n_err ++;                          /*  exception  */
1890                            return;
1891                    }
1892    
1893                  if (cpu->byte_order == EMUL_BIG_ENDIAN)                  if (cpu->byte_order == EMUL_BIG_ENDIAN)
1894                          cpu->cd.ppc.gpr[rs] = (d[0] << 24) + (d[1] << 16)                          cpu->cd.ppc.gpr[rs] = (d[0] << 24) + (d[1] << 16)
# Line 1207  X(lmw) { Line 1897  X(lmw) {
1897                          cpu->cd.ppc.gpr[rs] = (d[3] << 24) + (d[2] << 16)                          cpu->cd.ppc.gpr[rs] = (d[3] << 24) + (d[2] << 16)
1898                              + (d[1] << 8) + d[0];                              + (d[1] << 8) + d[0];
1899    
                 if (n_err > 0) {  
                         fatal("TODO: lmw: exception\n");  
                         exit(1);  
                 }  
   
1900                  rs ++;                  rs ++;
1901                  addr += sizeof(uint32_t);                  addr += sizeof(uint32_t);
1902          }          }
1903  }  }
1904  X(stmw) {  X(stmw) {
1905          MODE_uint_t addr = reg(ic->arg[1]) + (int32_t)ic->arg[2];          MODE_uint_t addr = reg(ic->arg[1]) + (int32_t)ic->arg[2];
         uint32_t tmp;  
1906          unsigned char d[4];          unsigned char d[4];
1907          int n_err = 0, rs = ic->arg[0];          int rs = ic->arg[0];
1908    
1909            int low_pc = ((size_t)ic - (size_t)cpu->cd.ppc.cur_ic_page)
1910                / sizeof(struct ppc_instr_call);
1911            cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1)
1912                << PPC_INSTR_ALIGNMENT_SHIFT);
1913            cpu->pc += (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
1914    
1915          while (rs <= 31) {          while (rs <= 31) {
1916                  tmp = cpu->cd.ppc.gpr[rs];                  uint32_t tmp = cpu->cd.ppc.gpr[rs];
1917                  if (cpu->byte_order == EMUL_BIG_ENDIAN) {                  if (cpu->byte_order == EMUL_BIG_ENDIAN) {
1918                          d[3] = tmp; d[2] = tmp >> 8;                          d[3] = tmp; d[2] = tmp >> 8;
1919                          d[1] = tmp >> 16; d[0] = tmp >> 24;                          d[1] = tmp >> 16; d[0] = tmp >> 24;
# Line 1232  X(stmw) { Line 1922  X(stmw) {
1922                          d[2] = tmp >> 16; d[3] = tmp >> 24;                          d[2] = tmp >> 16; d[3] = tmp >> 24;
1923                  }                  }
1924                  if (cpu->memory_rw(cpu, cpu->mem, addr, d, sizeof(d),                  if (cpu->memory_rw(cpu, cpu->mem, addr, d, sizeof(d),
1925                      MEM_WRITE, CACHE_DATA) != MEMORY_ACCESS_OK)                      MEM_WRITE, CACHE_DATA) != MEMORY_ACCESS_OK) {
1926                          n_err ++;                          /*  exception  */
1927                            return;
                 if (n_err > 0) {  
                         fatal("TODO: stmw: exception\n");  
                         exit(1);  
1928                  }                  }
1929    
1930                  rs ++;                  rs ++;
# Line 1247  X(stmw) { Line 1934  X(stmw) {
1934    
1935    
1936  /*  /*
1937     *  Load/store string:
1938     *
1939     *  arg[0] = rs   (well, rt for lswi)
1940     *  arg[1] = ptr to ra (or ptr to zero)
1941     *  arg[2] = nb
1942     */
1943    X(lswi)
1944    {
1945            MODE_uint_t addr = reg(ic->arg[1]);
1946            int rt = ic->arg[0], nb = ic->arg[2];
1947            int sub = 0;
1948    
1949            int low_pc = ((size_t)ic - (size_t)cpu->cd.ppc.cur_ic_page)
1950                / sizeof(struct ppc_instr_call);
1951            cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1)
1952                << PPC_INSTR_ALIGNMENT_SHIFT);
1953            cpu->pc += (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
1954    
1955            while (nb > 0) {
1956                    unsigned char d;
1957                    if (cpu->memory_rw(cpu, cpu->mem, addr, &d, 1,
1958                        MEM_READ, CACHE_DATA) != MEMORY_ACCESS_OK) {
1959                            /*  exception  */
1960                            return;
1961                    }
1962    
1963                    if (cpu->cd.ppc.mode == MODE_POWER && sub == 0)
1964                            cpu->cd.ppc.gpr[rt] = 0;
1965                    cpu->cd.ppc.gpr[rt] &= ~(0xff << (24-8*sub));
1966                    cpu->cd.ppc.gpr[rt] |= (d << (24-8*sub));
1967                    sub ++;
1968                    if (sub == 4) {
1969                            rt = (rt + 1) & 31;
1970                            sub = 0;
1971                    }
1972                    addr ++;
1973                    nb --;
1974            }
1975    }
1976    X(stswi)
1977    {
1978            MODE_uint_t addr = reg(ic->arg[1]);
1979            int rs = ic->arg[0], nb = ic->arg[2];
1980            uint32_t cur = cpu->cd.ppc.gpr[rs];
1981            int sub = 0;
1982    
1983            int low_pc = ((size_t)ic - (size_t)cpu->cd.ppc.cur_ic_page)
1984                / sizeof(struct ppc_instr_call);
1985            cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1)
1986                << PPC_INSTR_ALIGNMENT_SHIFT);
1987            cpu->pc += (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
1988    
1989            while (nb > 0) {
1990                    unsigned char d = cur >> 24;
1991                    if (cpu->memory_rw(cpu, cpu->mem, addr, &d, 1,
1992                        MEM_WRITE, CACHE_DATA) != MEMORY_ACCESS_OK) {
1993                            /*  exception  */
1994                            return;
1995                    }
1996                    cur <<= 8;
1997                    sub ++;
1998                    if (sub == 4) {
1999                            rs = (rs + 1) & 31;
2000                            sub = 0;
2001                            cur = cpu->cd.ppc.gpr[rs];
2002                    }
2003                    addr ++;
2004                    nb --;
2005            }
2006    }
2007    
2008    
2009    /*
2010   *  Shifts, and, or, xor, etc.   *  Shifts, and, or, xor, etc.
2011   *   *
2012   *  arg[0] = pointer to source register rs   *  arg[0] = pointer to source register rs
# Line 1260  X(extsb) { Line 2020  X(extsb) {
2020          reg(ic->arg[2]) = (int64_t)(int8_t)reg(ic->arg[0]);          reg(ic->arg[2]) = (int64_t)(int8_t)reg(ic->arg[0]);
2021  #endif  #endif
2022  }  }
2023  DOT(extsb)  DOT2(extsb)
2024  X(extsh) {  X(extsh) {
2025  #ifdef MODE32  #ifdef MODE32
2026          reg(ic->arg[2]) = (int32_t)(int16_t)reg(ic->arg[0]);          reg(ic->arg[2]) = (int32_t)(int16_t)reg(ic->arg[0]);
# Line 1268  X(extsh) { Line 2028  X(extsh) {
2028          reg(ic->arg[2]) = (int64_t)(int16_t)reg(ic->arg[0]);          reg(ic->arg[2]) = (int64_t)(int16_t)reg(ic->arg[0]);
2029  #endif  #endif
2030  }  }
2031  DOT(extsh)  DOT2(extsh)
2032  X(extsw) {  X(extsw) {
2033  #ifdef MODE32  #ifdef MODE32
2034          fatal("TODO: extsw: invalid instruction\n"); exit(1);          fatal("TODO: extsw: invalid instruction\n");
2035  #else  #else
2036          reg(ic->arg[2]) = (int64_t)(int32_t)reg(ic->arg[0]);          reg(ic->arg[2]) = (int64_t)(int32_t)reg(ic->arg[0]);
2037  #endif  #endif
2038  }  }
2039  DOT(extsw)  DOT2(extsw)
2040  X(slw) {        reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0])  X(slw) {        reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0])
2041                      << (reg(ic->arg[1]) & 63); }                      << (reg(ic->arg[1]) & 31); }
2042  DOT(slw)  DOT2(slw)
2043  X(sraw) {       reg(ic->arg[2]) =  X(sld) {int sa = reg(ic->arg[1]) & 127;
2044  #ifdef MODE32          if (sa >= 64)   reg(ic->arg[2]) = 0;
2045                      (int32_t)          else reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0]) << (sa & 63); }
2046  #else  DOT2(sld)
2047                      (int64_t)  X(sraw)
2048  #endif  {
2049                  reg(ic->arg[0]) >> (reg(ic->arg[1]) & 63); }          uint32_t tmp = reg(ic->arg[0]);
2050  DOT(sraw)          int i = 0, j = 0, sh = reg(ic->arg[1]) & 31;
2051    
2052            cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2053            if (tmp & 0x80000000)
2054                    i = 1;
2055            while (sh-- > 0) {
2056                    if (tmp & 1)
2057                            j ++;
2058                    tmp >>= 1;
2059                    if (tmp & 0x40000000)
2060                            tmp |= 0x80000000;
2061            }
2062            if (i && j>0)
2063                    cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2064            reg(ic->arg[2]) = (int64_t)(int32_t)tmp;
2065    }
2066    DOT2(sraw)
2067  X(srw) {        reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0])  X(srw) {        reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0])
2068                      >> (reg(ic->arg[1]) & 63); }                      >> (reg(ic->arg[1]) & 31); }
2069  DOT(srw)  DOT2(srw)
2070  X(and) {        reg(ic->arg[2]) = reg(ic->arg[0]) & reg(ic->arg[1]); }  X(and) {        reg(ic->arg[2]) = reg(ic->arg[0]) & reg(ic->arg[1]); }
2071  X(and_dot) {    reg(ic->arg[2]) = reg(ic->arg[0]) & reg(ic->arg[1]);  DOT2(and)
                 update_cr0(cpu, reg(ic->arg[2])); }  
2072  X(nand) {       reg(ic->arg[2]) = ~(reg(ic->arg[0]) & reg(ic->arg[1])); }  X(nand) {       reg(ic->arg[2]) = ~(reg(ic->arg[0]) & reg(ic->arg[1])); }
2073  X(nand_dot) {   reg(ic->arg[2]) = ~(reg(ic->arg[0]) & reg(ic->arg[1]));  DOT2(nand)
                 update_cr0(cpu, reg(ic->arg[2])); }  
2074  X(andc) {       reg(ic->arg[2]) = reg(ic->arg[0]) & (~reg(ic->arg[1])); }  X(andc) {       reg(ic->arg[2]) = reg(ic->arg[0]) & (~reg(ic->arg[1])); }
2075  X(andc_dot) {   reg(ic->arg[2]) = reg(ic->arg[0]) & (~reg(ic->arg[1]));  DOT2(andc)
                 update_cr0(cpu, reg(ic->arg[2])); }  
2076  X(nor) {        reg(ic->arg[2]) = ~(reg(ic->arg[0]) | reg(ic->arg[1])); }  X(nor) {        reg(ic->arg[2]) = ~(reg(ic->arg[0]) | reg(ic->arg[1])); }
2077  X(nor_dot) {    reg(ic->arg[2]) = ~(reg(ic->arg[0]) | reg(ic->arg[1]));  DOT2(nor)
2078                  update_cr0(cpu, reg(ic->arg[2])); }  X(mr) {         reg(ic->arg[2]) = reg(ic->arg[1]); }
2079  X(or) {         reg(ic->arg[2]) = reg(ic->arg[0]) | reg(ic->arg[1]); }  X(or) {         reg(ic->arg[2]) = reg(ic->arg[0]) | reg(ic->arg[1]); }
2080  X(or_dot) {     reg(ic->arg[2]) = reg(ic->arg[0]) | reg(ic->arg[1]);  DOT2(or)
                 update_cr0(cpu, reg(ic->arg[2])); }  
2081  X(orc) {        reg(ic->arg[2]) = reg(ic->arg[0]) | (~reg(ic->arg[1])); }  X(orc) {        reg(ic->arg[2]) = reg(ic->arg[0]) | (~reg(ic->arg[1])); }
2082  X(orc_dot) {    reg(ic->arg[2]) = reg(ic->arg[0]) | (~reg(ic->arg[1]));  DOT2(orc)
                 update_cr0(cpu, reg(ic->arg[2])); }  
2083  X(xor) {        reg(ic->arg[2]) = reg(ic->arg[0]) ^ reg(ic->arg[1]); }  X(xor) {        reg(ic->arg[2]) = reg(ic->arg[0]) ^ reg(ic->arg[1]); }
2084  X(xor_dot) {    reg(ic->arg[2]) = reg(ic->arg[0]) ^ reg(ic->arg[1]);  DOT2(xor)
2085                  update_cr0(cpu, reg(ic->arg[2])); }  X(eqv) {        reg(ic->arg[2]) = ~(reg(ic->arg[0]) ^ reg(ic->arg[1])); }
2086    DOT2(eqv)
2087    
2088    
2089  /*  /*
# Line 1321  X(xor_dot) {   reg(ic->arg[2]) = reg(ic->a Line 2093  X(xor_dot) {   reg(ic->arg[2]) = reg(ic->a
2093   *  arg[1] = pointer to destination register rt   *  arg[1] = pointer to destination register rt
2094   */   */
2095  X(neg) {        reg(ic->arg[1]) = -reg(ic->arg[0]); }  X(neg) {        reg(ic->arg[1]) = -reg(ic->arg[0]); }
2096  X(neg_dot) {    instr(neg)(cpu,ic); update_cr0(cpu, reg(ic->arg[1])); }  DOT1(neg)
2097    
2098    
2099  /*  /*
# Line 1336  X(mullw) Line 2108  X(mullw)
2108          int32_t sum = (int32_t)reg(ic->arg[0]) * (int32_t)reg(ic->arg[1]);          int32_t sum = (int32_t)reg(ic->arg[0]) * (int32_t)reg(ic->arg[1]);
2109          reg(ic->arg[2]) = (int32_t)sum;          reg(ic->arg[2]) = (int32_t)sum;
2110  }  }
2111    DOT2(mullw)
2112  X(mulhw)  X(mulhw)
2113  {  {
2114          int64_t sum;          int64_t sum;
# Line 1343  X(mulhw) Line 2116  X(mulhw)
2116              * (int64_t)(int32_t)reg(ic->arg[1]);              * (int64_t)(int32_t)reg(ic->arg[1]);
2117          reg(ic->arg[2]) = sum >> 32;          reg(ic->arg[2]) = sum >> 32;
2118  }  }
2119    DOT2(mulhw)
2120  X(mulhwu)  X(mulhwu)
2121  {  {
2122          uint64_t sum;          uint64_t sum;
# Line 1350  X(mulhwu) Line 2124  X(mulhwu)
2124              * (uint64_t)(uint32_t)reg(ic->arg[1]);              * (uint64_t)(uint32_t)reg(ic->arg[1]);
2125          reg(ic->arg[2]) = sum >> 32;          reg(ic->arg[2]) = sum >> 32;
2126  }  }
2127    DOT2(mulhwu)
2128  X(divw)  X(divw)
2129  {  {
2130          int32_t a = reg(ic->arg[0]), b = reg(ic->arg[1]);          int32_t a = reg(ic->arg[0]), b = reg(ic->arg[1]);
# Line 1360  X(divw) Line 2135  X(divw)
2135                  sum = a / b;                  sum = a / b;
2136          reg(ic->arg[2]) = (uint32_t)sum;          reg(ic->arg[2]) = (uint32_t)sum;
2137  }  }
2138    DOT2(divw)
2139  X(divwu)  X(divwu)
2140  {  {
2141          uint32_t a = reg(ic->arg[0]), b = reg(ic->arg[1]);          uint32_t a = reg(ic->arg[0]), b = reg(ic->arg[1]);
# Line 1370  X(divwu) Line 2146  X(divwu)
2146                  sum = a / b;                  sum = a / b;
2147          reg(ic->arg[2]) = sum;          reg(ic->arg[2]) = sum;
2148  }  }
2149    DOT2(divwu)
2150    
2151    
2152  /*  /*
# Line 1380  X(divwu) Line 2157  X(divwu)
2157   *  arg[2] = pointer to destination register rt   *  arg[2] = pointer to destination register rt
2158   */   */
2159  X(add)     { reg(ic->arg[2]) = reg(ic->arg[0]) + reg(ic->arg[1]); }  X(add)     { reg(ic->arg[2]) = reg(ic->arg[0]) + reg(ic->arg[1]); }
2160  X(add_dot) { instr(add)(cpu,ic); update_cr0(cpu, reg(ic->arg[2])); }  DOT2(add)
2161    
2162    
2163  /*  /*
# Line 1395  X(addc) Line 2172  X(addc)
2172          /*  TODO: this only works in 32-bit mode  */          /*  TODO: this only works in 32-bit mode  */
2173          uint64_t tmp = (uint32_t)reg(ic->arg[0]);          uint64_t tmp = (uint32_t)reg(ic->arg[0]);
2174          uint64_t tmp2 = tmp;          uint64_t tmp2 = tmp;
2175          cpu->cd.ppc.xer &= ~PPC_XER_CA;          cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2176          tmp += (uint32_t)reg(ic->arg[1]);          tmp += (uint32_t)reg(ic->arg[1]);
2177          if ((tmp >> 32) != (tmp2 >> 32))          if ((tmp >> 32) != (tmp2 >> 32))
2178                  cpu->cd.ppc.xer |= PPC_XER_CA;                  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2179          reg(ic->arg[2]) = (uint32_t)tmp;          reg(ic->arg[2]) = (uint32_t)tmp;
2180  }  }
2181    
# Line 1413  X(addc) Line 2190  X(addc)
2190  X(adde)  X(adde)
2191  {  {
2192          /*  TODO: this only works in 32-bit mode  */          /*  TODO: this only works in 32-bit mode  */
2193          int old_ca = cpu->cd.ppc.xer & PPC_XER_CA;          int old_ca = cpu->cd.ppc.spr[SPR_XER] & PPC_XER_CA;
2194          uint64_t tmp = (uint32_t)reg(ic->arg[0]);          uint64_t tmp = (uint32_t)reg(ic->arg[0]);
2195          uint64_t tmp2 = tmp;          uint64_t tmp2 = tmp;
2196          cpu->cd.ppc.xer &= ~PPC_XER_CA;          cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2197          tmp += (uint32_t)reg(ic->arg[1]);          tmp += (uint32_t)reg(ic->arg[1]);
2198          if (old_ca)          if (old_ca)
2199                  tmp ++;                  tmp ++;
2200          if ((tmp >> 32) != (tmp2 >> 32))          if ((tmp >> 32) != (tmp2 >> 32))
2201                  cpu->cd.ppc.xer |= PPC_XER_CA;                  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2202          reg(ic->arg[2]) = (uint32_t)tmp;          reg(ic->arg[2]) = (uint32_t)tmp;
2203  }  }
2204  X(adde_dot) { instr(adde)(cpu,ic); update_cr0(cpu, reg(ic->arg[2])); }  DOT2(adde)
2205  X(addme)  X(addme)
2206  {  {
2207          /*  TODO: this only works in 32-bit mode  */          /*  TODO: this only works in 32-bit mode  */
2208          int old_ca = cpu->cd.ppc.xer & PPC_XER_CA;          int old_ca = cpu->cd.ppc.spr[SPR_XER] & PPC_XER_CA;
2209          uint64_t tmp = (uint32_t)reg(ic->arg[0]);          uint64_t tmp = (uint32_t)reg(ic->arg[0]);
2210          uint64_t tmp2 = tmp;          uint64_t tmp2 = tmp;
2211          cpu->cd.ppc.xer &= ~PPC_XER_CA;          cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2212          if (old_ca)          if (old_ca)
2213                  tmp ++;                  tmp ++;
2214          tmp += 0xffffffffULL;          tmp += 0xffffffffULL;
2215          if ((tmp >> 32) != (tmp2 >> 32))          if ((tmp >> 32) != (tmp2 >> 32))
2216                  cpu->cd.ppc.xer |= PPC_XER_CA;                  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2217          reg(ic->arg[2]) = (uint32_t)tmp;          reg(ic->arg[2]) = (uint32_t)tmp;
2218  }  }
2219  X(addme_dot) { instr(addme)(cpu,ic); update_cr0(cpu, reg(ic->arg[2])); }  DOT2(addme)
2220  X(addze)  X(addze)
2221  {  {
2222          /*  TODO: this only works in 32-bit mode  */          /*  TODO: this only works in 32-bit mode  */
2223          int old_ca = cpu->cd.ppc.xer & PPC_XER_CA;          int old_ca = cpu->cd.ppc.spr[SPR_XER] & PPC_XER_CA;
2224          uint64_t tmp = (uint32_t)reg(ic->arg[0]);          uint64_t tmp = (uint32_t)reg(ic->arg[0]);
2225          uint64_t tmp2 = tmp;          uint64_t tmp2 = tmp;
2226          cpu->cd.ppc.xer &= ~PPC_XER_CA;          cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2227          if (old_ca)          if (old_ca)
2228                  tmp ++;                  tmp ++;
2229          if ((tmp >> 32) != (tmp2 >> 32))          if ((tmp >> 32) != (tmp2 >> 32))
2230                  cpu->cd.ppc.xer |= PPC_XER_CA;                  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2231          reg(ic->arg[2]) = (uint32_t)tmp;          reg(ic->arg[2]) = (uint32_t)tmp;
2232  }  }
2233  X(addze_dot) { instr(addze)(cpu,ic); update_cr0(cpu, reg(ic->arg[2])); }  DOT2(addze)
2234    
2235    
2236  /*  /*
# Line 1463  X(addze_dot) { instr(addze)(cpu,ic); upd Line 2240  X(addze_dot) { instr(addze)(cpu,ic); upd
2240   *  arg[1] = pointer to source register rb   *  arg[1] = pointer to source register rb
2241   *  arg[2] = pointer to destination register rt   *  arg[2] = pointer to destination register rt
2242   */   */
2243  X(subf) {       reg(ic->arg[2]) = reg(ic->arg[1]) - reg(ic->arg[0]); }  X(subf)
2244  X(subf_dot) {   instr(subf)(cpu,ic); update_cr0(cpu, reg(ic->arg[2])); }  {
2245            reg(ic->arg[2]) = reg(ic->arg[1]) - reg(ic->arg[0]);
2246    }
2247    DOT2(subf)
2248  X(subfc)  X(subfc)
2249  {  {
2250          cpu->cd.ppc.xer &= ~PPC_XER_CA;          cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2251          if (reg(ic->arg[1]) >= reg(ic->arg[0]))          if (reg(ic->arg[1]) >= reg(ic->arg[0]))
2252                  cpu->cd.ppc.xer |= PPC_XER_CA;                  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2253          reg(ic->arg[2]) = reg(ic->arg[1]) - reg(ic->arg[0]);          reg(ic->arg[2]) = reg(ic->arg[1]) - reg(ic->arg[0]);
2254  }  }
2255  X(subfc_dot) {  instr(subfc)(cpu,ic); update_cr0(cpu, reg(ic->arg[2])); }  DOT2(subfc)
2256  X(subfe)  X(subfe)
2257  {  {
2258          int old_ca = (cpu->cd.ppc.xer & PPC_XER_CA)? 1 : 0;          int old_ca = (cpu->cd.ppc.spr[SPR_XER] & PPC_XER_CA)? 1 : 0;
2259          cpu->cd.ppc.xer &= ~PPC_XER_CA;          cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2260          if (reg(ic->arg[1]) == reg(ic->arg[0])) {          if (reg(ic->arg[1]) == reg(ic->arg[0])) {
2261                  if (old_ca)                  if (old_ca)
2262                          cpu->cd.ppc.xer |= PPC_XER_CA;                          cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2263          } else if (reg(ic->arg[1]) >= reg(ic->arg[0]))          } else if (reg(ic->arg[1]) >= reg(ic->arg[0]))
2264                  cpu->cd.ppc.xer |= PPC_XER_CA;                  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2265    
2266          /*          /*
2267           *  TODO: The register value calculation should be correct,           *  TODO: The register value calculation should be correct,
# Line 1490  X(subfe) Line 2270  X(subfe)
2270    
2271          reg(ic->arg[2]) = reg(ic->arg[1]) - reg(ic->arg[0]) - (old_ca? 0 : 1);          reg(ic->arg[2]) = reg(ic->arg[1]) - reg(ic->arg[0]) - (old_ca? 0 : 1);
2272  }  }
2273  X(subfe_dot) {  instr(subfe)(cpu,ic); update_cr0(cpu, reg(ic->arg[2])); }  DOT2(subfe)
2274    X(subfme)
2275    {
2276            int old_ca = cpu->cd.ppc.spr[SPR_XER] & PPC_XER_CA;
2277            uint64_t tmp = (uint32_t)(~reg(ic->arg[0]));
2278            tmp += 0xffffffffULL;
2279            cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2280            if (old_ca)
2281                    tmp ++;
2282            if ((tmp >> 32) != 0)
2283                    cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2284            reg(ic->arg[2]) = (uint32_t)tmp;
2285    }
2286    DOT2(subfme)
2287  X(subfze)  X(subfze)
2288  {  {
2289          int old_ca = cpu->cd.ppc.xer & PPC_XER_CA;          int old_ca = cpu->cd.ppc.spr[SPR_XER] & PPC_XER_CA;
2290          uint64_t tmp = (uint32_t)(~reg(ic->arg[0]));          uint64_t tmp = (uint32_t)(~reg(ic->arg[0]));
2291          uint64_t tmp2 = tmp;          uint64_t tmp2 = tmp;
2292          cpu->cd.ppc.xer &= ~PPC_XER_CA;          cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2293          if (old_ca)          if (old_ca)
2294                  tmp ++;                  tmp ++;
2295          if ((tmp >> 32) != (tmp2 >> 32))          if ((tmp >> 32) != (tmp2 >> 32))
2296                  cpu->cd.ppc.xer |= PPC_XER_CA;                  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2297          reg(ic->arg[2]) = (uint32_t)tmp;          reg(ic->arg[2]) = (uint32_t)tmp;
2298  }  }
2299  X(subfze_dot) { instr(subfze)(cpu,ic); update_cr0(cpu, reg(ic->arg[2])); }  DOT2(subfze)
2300    
2301    
2302  /*  /*
# Line 1517  X(ori)  { reg(ic->arg[2]) = reg(ic->arg[ Line 2310  X(ori)  { reg(ic->arg[2]) = reg(ic->arg[
2310  X(xori) { reg(ic->arg[2]) = reg(ic->arg[0]) ^ (uint32_t)ic->arg[1]; }  X(xori) { reg(ic->arg[2]) = reg(ic->arg[0]) ^ (uint32_t)ic->arg[1]; }
2311    
2312    
2313    #include "tmp_ppc_loadstore.c"
2314    
2315    
2316  /*  /*
2317   *  tlbie:  TLB invalidate   *  lfs, stfs: Load/Store Floating-point Single precision
2318   */   */
2319  X(tlbie)  X(lfs)
2320  {  {
2321          cpu->invalidate_translation_caches_paddr(cpu, 0, INVALIDATE_ALL);          /*  Sync. PC in case of an exception, and remember it:  */
2322  }          uint64_t old_pc, low_pc = ((size_t)ic - (size_t)
2323                cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
2324            old_pc = cpu->pc = (cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) <<
2325                PPC_INSTR_ALIGNMENT_SHIFT)) + (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
2326            if (!(cpu->cd.ppc.msr & PPC_MSR_FP)) {
2327                    ppc_exception(cpu, PPC_EXCEPTION_FPU);
2328                    return;
2329            }
2330    
2331            /*  Perform a 32-bit load:  */
2332    #ifdef MODE32
2333            ppc32_loadstore
2334    #else
2335            ppc_loadstore
2336    #endif
2337                [2 + 4 + 8](cpu, ic);
2338    
2339  /*          if (old_pc == cpu->pc) {
2340   *  user_syscall:  Userland syscall.                  /*  The load succeeded. Let's convert the value:  */
2341   *                  struct ieee_float_value val;
2342   *  arg[0] = syscall "level" (usually 0)                  (*(uint64_t *)ic->arg[0]) &= 0xffffffff;
2343   */                  ieee_interpret_float_value(*(uint64_t *)ic->arg[0],
2344  X(user_syscall)                      &val, IEEE_FMT_S);
2345                    (*(uint64_t *)ic->arg[0]) =
2346                        ieee_store_float_value(val.f, IEEE_FMT_D, val.nan);
2347            }
2348    }
2349    X(lfsx)
2350  {  {
2351          useremul_syscall(cpu, ic->arg[0]);          /*  Sync. PC in case of an exception, and remember it:  */
2352            uint64_t old_pc, low_pc = ((size_t)ic - (size_t)
2353                cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
2354            old_pc = cpu->pc = (cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) <<
2355                PPC_INSTR_ALIGNMENT_SHIFT)) + (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
2356            if (!(cpu->cd.ppc.msr & PPC_MSR_FP)) {
2357                    ppc_exception(cpu, PPC_EXCEPTION_FPU);
2358                    return;
2359            }
2360    
2361            /*  Perform a 32-bit load:  */
2362    #ifdef MODE32
2363            ppc32_loadstore_indexed
2364    #else
2365            ppc_loadstore_indexed
2366    #endif
2367                [2 + 4 + 8](cpu, ic);
2368    
2369            if (old_pc == cpu->pc) {
2370                    /*  The load succeeded. Let's convert the value:  */
2371                    struct ieee_float_value val;
2372                    (*(uint64_t *)ic->arg[0]) &= 0xffffffff;
2373                    ieee_interpret_float_value(*(uint64_t *)ic->arg[0],
2374                        &val, IEEE_FMT_S);
2375                    (*(uint64_t *)ic->arg[0]) =
2376                        ieee_store_float_value(val.f, IEEE_FMT_D, val.nan);
2377            }
2378  }  }
2379    X(lfd)
2380    {
2381            CHECK_FOR_FPU_EXCEPTION;
2382    
2383            /*  Perform a 64-bit load:  */
2384    #ifdef MODE32
2385            ppc32_loadstore
2386    #else
2387            ppc_loadstore
2388    #endif
2389                [3 + 4 + 8](cpu, ic);
2390    }
2391    X(lfdx)
2392    {
2393            CHECK_FOR_FPU_EXCEPTION;
2394    
2395  /*          /*  Perform a 64-bit load:  */
2396   *  openfirmware:  #ifdef MODE32
2397   */          ppc32_loadstore_indexed
2398  X(openfirmware)  #else
2399            ppc_loadstore_indexed
2400    #endif
2401                [3 + 4 + 8](cpu, ic);
2402    }
2403    X(stfs)
2404  {  {
2405          of_emul(cpu);          uint64_t *old_arg0 = (void *)ic->arg[0];
2406          cpu->pc = cpu->cd.ppc.lr;          struct ieee_float_value val;
2407          if (cpu->machine->show_trace_tree)          uint64_t tmp_val;
2408                  cpu_functioncall_trace_return(cpu);  
2409          DYNTRANS_PC_TO_POINTERS(cpu);          CHECK_FOR_FPU_EXCEPTION;
2410    
2411            ieee_interpret_float_value(*old_arg0, &val, IEEE_FMT_D);
2412            tmp_val = ieee_store_float_value(val.f, IEEE_FMT_S, val.nan);
2413    
2414            ic->arg[0] = (size_t)&tmp_val;
2415    
2416            /*  Perform a 32-bit store:  */
2417    #ifdef MODE32
2418            ppc32_loadstore
2419    #else
2420            ppc_loadstore
2421    #endif
2422                [2 + 4](cpu, ic);
2423    
2424            ic->arg[0] = (size_t)old_arg0;
2425  }  }
2426    X(stfsx)
2427    {
2428            uint64_t *old_arg0 = (void *)ic->arg[0];
2429            struct ieee_float_value val;
2430            uint64_t tmp_val;
2431    
2432            CHECK_FOR_FPU_EXCEPTION;
2433    
2434  #include "tmp_ppc_loadstore.c"          ieee_interpret_float_value(*old_arg0, &val, IEEE_FMT_D);
2435            tmp_val = ieee_store_float_value(val.f, IEEE_FMT_S, val.nan);
2436    
2437            ic->arg[0] = (size_t)&tmp_val;
2438    
2439  /*****************************************************************************/          /*  Perform a 32-bit store:  */
2440    #ifdef MODE32
2441            ppc32_loadstore_indexed
2442    #else
2443            ppc_loadstore_indexed
2444    #endif
2445                [2 + 4](cpu, ic);
2446    
2447            ic->arg[0] = (size_t)old_arg0;
2448    }
2449    X(stfd)
2450    {
2451            CHECK_FOR_FPU_EXCEPTION;
2452    
2453            /*  Perform a 64-bit store:  */
2454    #ifdef MODE32
2455            ppc32_loadstore
2456    #else
2457            ppc_loadstore
2458    #endif
2459                [3 + 4](cpu, ic);
2460    }
2461    X(stfdx)
2462    {
2463            CHECK_FOR_FPU_EXCEPTION;
2464    
2465  /*          /*  Perform a 64-bit store:  */
  *  byte_fill_loop:  
  *  
  *  A byte-fill loop. Fills at most one page at a time. If the page was not  
  *  in the host_store table, then the original sequence (beginning with  
  *  cmpwi crX,rY,0) is executed instead.  
  *  
  *  L:  cmpwi   crX,rY,0                ic[0]  
  *      stb     rW,0(rZ)                ic[1]  
  *      subi    rY,rY,1                 ic[2]  
  *      addi    rZ,rZ,1                 ic[3]  
  *      bc      12,4*X+1,L              ic[4]  
  */  
 X(byte_fill_loop)  
 {  
         int max_pages_left = 5;  
         unsigned int x = ic[0].arg[2], n, ofs, maxlen, c;  
         uint64_t *y = (uint64_t *)ic[0].arg[0];  
         uint64_t *z = (uint64_t *)ic[1].arg[1];  
         uint64_t *w = (uint64_t *)ic[1].arg[0];  
         unsigned char *page;  
2466  #ifdef MODE32  #ifdef MODE32
2467          uint32_t addr;          ppc32_loadstore_indexed
2468  #else  #else
2469          uint64_t addr;          ppc_loadstore_indexed
         fatal("byte_fill_loop: not for 64-bit mode yet\n");  
         exit(1);  
2470  #endif  #endif
2471                [3 + 4](cpu, ic);
2472    }
2473    
2474    
2475  restart_loop:  /*
2476          addr = reg(z);   *  lvx, stvx:  Vector (16-byte) load/store  (slow implementation)
2477          /*  TODO: This only work with 32-bit addressing:  */   *
2478          page = cpu->cd.ppc.host_store[addr >> 12];   *  arg[0] = v-register nr of rs
2479          if (page == NULL) {   *  arg[1] = pointer to ra
2480                  instr(cmpwi)(cpu, ic);   *  arg[2] = pointer to rb
2481     */
2482    X(lvx)
2483    {
2484            MODE_uint_t addr = reg(ic->arg[1]) + reg(ic->arg[2]);
2485            uint8_t data[16];
2486            uint64_t hi, lo;
2487            int rs = ic->arg[0];
2488    
2489            if (cpu->memory_rw(cpu, cpu->mem, addr, data, sizeof(data),
2490                MEM_READ, CACHE_DATA) != MEMORY_ACCESS_OK) {
2491                    /*  exception  */
2492                  return;                  return;
2493          }          }
2494    
2495          n = reg(y) + 1; ofs = addr & 0xfff; maxlen = 0x1000 - ofs;          hi = ((uint64_t)data[0] << 56) +
2496          if (n > maxlen)               ((uint64_t)data[1] << 48) +
2497                  n = maxlen;               ((uint64_t)data[2] << 40) +
2498                 ((uint64_t)data[3] << 32) +
2499                 ((uint64_t)data[4] << 24) +
2500                 ((uint64_t)data[5] << 16) +
2501                 ((uint64_t)data[6] << 8) +
2502                 ((uint64_t)data[7]);
2503            lo = ((uint64_t)data[8] << 56) +
2504                 ((uint64_t)data[9] << 48) +
2505                 ((uint64_t)data[10] << 40) +
2506                 ((uint64_t)data[11] << 32) +
2507                 ((uint64_t)data[12] << 24) +
2508                 ((uint64_t)data[13] << 16) +
2509                 ((uint64_t)data[14] << 8) +
2510                 ((uint64_t)data[15]);
2511    
2512          /*  fatal("FILL A: x=%i n=%i ofs=0x%x y=0x%x z=0x%x w=0x%x\n", x,          cpu->cd.ppc.vr_hi[rs] = hi; cpu->cd.ppc.vr_lo[rs] = lo;
2513              n, ofs, (int)reg(y), (int)reg(z), (int)reg(w));  */  }
2514    X(stvx)
2515    {
2516            uint8_t data[16];
2517            MODE_uint_t addr = reg(ic->arg[1]) + reg(ic->arg[2]);
2518            int rs = ic->arg[0];
2519            uint64_t hi = cpu->cd.ppc.vr_hi[rs], lo = cpu->cd.ppc.vr_lo[rs];
2520    
2521          memset(page + ofs, *w, n);          data[0] = hi >> 56;
2522            data[1] = hi >> 48;
2523            data[2] = hi >> 40;
2524            data[3] = hi >> 32;
2525            data[4] = hi >> 24;
2526            data[5] = hi >> 16;
2527            data[6] = hi >> 8;
2528            data[7] = hi;
2529            data[8] = lo >> 56;
2530            data[9] = lo >> 48;
2531            data[10] = lo >> 40;
2532            data[11] = lo >> 32;
2533            data[12] = lo >> 24;
2534            data[13] = lo >> 16;
2535            data[14] = lo >> 8;
2536            data[15] = lo;
2537    
2538          reg(z) = addr + n;          cpu->memory_rw(cpu, cpu->mem, addr, data,
2539          reg(y) -= n;              sizeof(data), MEM_WRITE, CACHE_DATA);
2540    }
2541    
         if ((int32_t)reg(y) + 1 < 0)  
                 c = 8;  
         else if ((int32_t)reg(y) + 1 > 0)  
                 c = 4;  
         else  
                 c = 2;  
         c |= ((cpu->cd.ppc.xer >> 31) & 1);  /*  SO bit, copied from XER  */  
         cpu->cd.ppc.cr &= ~(0xf << (28 - 4*x));  
         cpu->cd.ppc.cr |= (c << (28 - 4*x));  
   
         cpu->n_translated_instrs += (5 * n);  
   
         if (max_pages_left-- > 0 &&  
             (int32_t)reg(y) > 0)  
                 goto restart_loop;  
2542    
2543          cpu->n_translated_instrs --;  /*
2544          if ((int32_t)reg(y) > 0)   *  vxor:  Vector (16-byte) XOR
2545                  cpu->cd.ppc.next_ic = ic;   *
2546          else   *  arg[0] = v-register nr of source 1
2547                  cpu->cd.ppc.next_ic = &ic[5];   *  arg[1] = v-register nr of source 2
2548     *  arg[2] = v-register nr of destination
2549     */
2550    X(vxor)
2551    {
2552            cpu->cd.ppc.vr_hi[ic->arg[2]] =
2553                cpu->cd.ppc.vr_hi[ic->arg[0]] ^ cpu->cd.ppc.vr_hi[ic->arg[1]];
2554            cpu->cd.ppc.vr_lo[ic->arg[2]] =
2555                cpu->cd.ppc.vr_lo[ic->arg[0]] ^ cpu->cd.ppc.vr_lo[ic->arg[1]];
2556    }
2557    
2558    
2559          /*  fatal("FILL B: x=%i n=%i ofs=0x%x y=0x%x z=0x%x w=0x%x\n", x, n,  /*
2560              ofs, (int)reg(y), (int)reg(z), (int)reg(w));  */   *  tlbia:  TLB invalidate all
2561     */
2562    X(tlbia)
2563    {
2564            fatal("[ tlbia ]\n");
2565            cpu->invalidate_translation_caches(cpu, 0, INVALIDATE_ALL);
2566  }  }
2567    
2568    
2569  /*****************************************************************************/  /*
2570     *  tlbie:  TLB invalidate
2571     */
2572    X(tlbie)
2573    {
2574            /*  fatal("[ tlbie ]\n");  */
2575            cpu->invalidate_translation_caches(cpu, reg(ic->arg[0]),
2576                INVALIDATE_VADDR);
2577    }
2578    
2579    
2580  X(end_of_page)  /*
2581     *  sc: Syscall.
2582     */
2583    X(sc)
2584  {  {
2585          /*  Update the PC:  (offset 0, but on the next page)  */          /*  Synchronize the PC (pointing to _after_ this instruction)  */
2586          cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2);          cpu->pc = (cpu->pc & ~0xfff) + ic->arg[1];
         cpu->pc += (PPC_IC_ENTRIES_PER_PAGE << 2);  
2587    
2588          /*  Find the new physical page and update the translation pointers:  */          ppc_exception(cpu, PPC_EXCEPTION_SC);
         DYNTRANS_PC_TO_POINTERS(cpu);  
2589    
2590          /*  end_of_page doesn't count as an executed instruction:  */          /*  This caused an update to the PC register, so there is no need
2591          cpu->n_translated_instrs --;              to worry about the next instruction being an end_of_page.  */
2592  }  }
2593    
2594    
2595  /*****************************************************************************/  /*
2596     *  user_syscall:  Userland syscall.
2597     *
2598     *  arg[0] = syscall "level" (usually 0)
2599     */
2600    X(user_syscall)
2601    {
2602            useremul_syscall(cpu, ic->arg[0]);
2603    
2604            if (!cpu->running) {
2605                    cpu->n_translated_instrs --;
2606                    cpu->cd.ppc.next_ic = &nothing_call;
2607            }
2608    }
2609    
2610    
2611  /*  /*
2612   *  ppc_combine_instructions():   *  openfirmware:
2613   *   */
2614   *  Combine two or more instructions, if possible, into a single function call.  X(openfirmware)
2615    {
2616            of_emul(cpu);
2617            if (cpu->running == 0) {
2618                    cpu->n_translated_instrs --;
2619                    cpu->cd.ppc.next_ic = &nothing_call;
2620            }
2621            cpu->pc = cpu->cd.ppc.spr[SPR_LR];
2622            if (cpu->machine->show_trace_tree)
2623                    cpu_functioncall_trace_return(cpu);
2624            quick_pc_to_pointers(cpu);
2625    }
2626    
2627    
2628    /*
2629     *  tlbsx_dot: TLB scan
2630   */   */
2631  void COMBINE_INSTRUCTIONS(struct cpu *cpu, struct ppc_instr_call *ic,  X(tlbsx_dot)
         uint32_t addr)  
2632  {  {
2633          int n_back;          /*  TODO  */
2634          n_back = (addr >> PPC_INSTR_ALIGNMENT_SHIFT)          cpu->cd.ppc.cr &= ~(0xf0000000);
2635              & (PPC_IC_ENTRIES_PER_PAGE-1);          cpu->cd.ppc.cr |= 0x20000000;
2636            cpu->cd.ppc.cr |= ((cpu->cd.ppc.spr[SPR_XER] >> 3) & 0x10000000);
2637    }
2638    
         if (n_back >= 4) {  
                 /*  
                  *  L:  cmpwi   crX,rY,0                ic[-4]  
                  *      stb     rW,0(rZ)                ic[-3]  
                  *      subi    rY,rY,1                 ic[-2]  
                  *      addi    rZ,rZ,1                 ic[-1]  
                  *      bc      12,4*X+1,L              ic[0]  
                  */  
                 if (ic[-4].f == instr(cmpwi) &&  
                     ic[-4].arg[0] == ic[-2].arg[0] && ic[-4].arg[1] == 0 &&  
2639    
2640                      ic[-3].f == instr(stb_0) &&  /*
2641                      ic[-3].arg[1] == ic[-1].arg[0] && ic[-3].arg[2] == 0 &&   *  tlbli:
2642     */
2643    X(tlbli)
2644    {
2645            fatal("tlbli\n");
2646            cpu->invalidate_translation_caches(cpu, 0, INVALIDATE_ALL);
2647    }
2648    
                     ic[-2].f == instr(addi) &&  
                     ic[-2].arg[0] == ic[-2].arg[2] && ic[-2].arg[1] == -1 &&  
2649    
2650                      ic[-1].f == instr(addi) &&  /*
2651                      ic[-1].arg[0] == ic[-1].arg[2] && ic[-1].arg[1] ==  1 &&   *  tlbld:
2652     */
2653    X(tlbld)
2654    {
2655            /*  MODE_uint_t vaddr = reg(ic->arg[0]);
2656                MODE_uint_t paddr = cpu->cd.ppc.spr[SPR_RPA];  */
2657    
2658                      ic[0].f == instr(bc_samepage) &&          fatal("tlbld\n");
2659                      ic[0].arg[0] == (size_t)&ic[-4] &&          cpu->invalidate_translation_caches(cpu, 0, INVALIDATE_ALL);
2660                      ic[0].arg[1] == 12 && ic[0].arg[2] == 4*ic[-4].arg[2] + 1) {  }
2661                          ic[-4].f = instr(byte_fill_loop);  
2662                          combined;  
2663                  }  /*****************************************************************************/
2664          }  
2665    
2666    X(end_of_page)
2667    {
2668            /*  Update the PC:  (offset 0, but on the next page)  */
2669            cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1) << PPC_INSTR_ALIGNMENT_SHIFT);
2670            cpu->pc += (PPC_IC_ENTRIES_PER_PAGE << PPC_INSTR_ALIGNMENT_SHIFT);
2671    
2672            /*  Find the new physical page and update the translation pointers:  */
2673            quick_pc_to_pointers(cpu);
2674    
2675          /*  TODO: Combine forward as well  */          /*  end_of_page doesn't count as an executed instruction:  */
2676            cpu->n_translated_instrs --;
2677  }  }
2678    
2679    
# Line 1703  void COMBINE_INSTRUCTIONS(struct cpu *cp Line 2683  void COMBINE_INSTRUCTIONS(struct cpu *cp
2683  /*  /*
2684   *  ppc_instr_to_be_translated():   *  ppc_instr_to_be_translated():
2685   *   *
2686   *  Translate an instruction word into an ppc_instr_call. ic is filled in with   *  Translate an instruction word into a ppc_instr_call. ic is filled in with
2687   *  valid data for the translated instruction, or a "nothing" instruction if   *  valid data for the translated instruction, or a "nothing" instruction if
2688   *  there was a translation failure. The newly translated instruction is then   *  there was a translation failure. The newly translated instruction is then
2689   *  executed.   *  executed.
# Line 1711  void COMBINE_INSTRUCTIONS(struct cpu *cp Line 2691  void COMBINE_INSTRUCTIONS(struct cpu *cp
2691  X(to_be_translated)  X(to_be_translated)
2692  {  {
2693          uint64_t addr, low_pc, tmp_addr;          uint64_t addr, low_pc, tmp_addr;
2694          uint32_t iword;          uint32_t iword, mask;
2695          unsigned char *page;          unsigned char *page;
2696          unsigned char ib[4];          unsigned char ib[4];
2697          int main_opcode, rt, rs, ra, rb, rc, aa_bit, l_bit, lk_bit, spr, sh,          int main_opcode, rt, rs, ra, rb, rc, aa_bit, l_bit, lk_bit, spr, sh,
2698              xo, imm, load, size, update, zero, bf, bo, bi, bh, oe_bit, n64=0,              xo, imm, load, size, update, zero, bf, bo, bi, bh, oe_bit, n64=0,
2699              bfa, fp;              bfa, fp, byterev, nb, mb, me;
2700          void (*samepage_function)(struct cpu *, struct ppc_instr_call *);          void (*samepage_function)(struct cpu *, struct ppc_instr_call *);
2701          void (*rc_f)(struct cpu *, struct ppc_instr_call *);          void (*rc_f)(struct cpu *, struct ppc_instr_call *);
2702    
# Line 1730  X(to_be_translated) Line 2710  X(to_be_translated)
2710          addr &= ~((1 << PPC_INSTR_ALIGNMENT_SHIFT) - 1);          addr &= ~((1 << PPC_INSTR_ALIGNMENT_SHIFT) - 1);
2711    
2712          /*  Read the instruction word from memory:  */          /*  Read the instruction word from memory:  */
2713          page = cpu->cd.ppc.host_load[addr >> 12];  #ifdef MODE32
2714            page = cpu->cd.ppc.host_load[((uint32_t)addr) >> 12];
2715    #else
2716            {
2717                    const uint32_t mask1 = (1 << DYNTRANS_L1N) - 1;
2718                    const uint32_t mask2 = (1 << DYNTRANS_L2N) - 1;
2719                    const uint32_t mask3 = (1 << DYNTRANS_L3N) - 1;
2720                    uint32_t x1 = (addr >> (64-DYNTRANS_L1N)) & mask1;
2721                    uint32_t x2 = (addr >> (64-DYNTRANS_L1N-DYNTRANS_L2N)) & mask2;
2722                    uint32_t x3 = (addr >> (64-DYNTRANS_L1N-DYNTRANS_L2N-
2723                        DYNTRANS_L3N)) & mask3;
2724                    struct DYNTRANS_L2_64_TABLE *l2 = cpu->cd.ppc.l1_64[x1];
2725                    struct DYNTRANS_L3_64_TABLE *l3 = l2->l3[x2];
2726                    page = l3->host_load[x3];
2727            }
2728    #endif
2729    
2730          if (page != NULL) {          if (page != NULL) {
2731                  /*  fatal("TRANSLATION HIT!\n");  */                  /*  fatal("TRANSLATION HIT!\n");  */
# Line 1739  X(to_be_translated) Line 2734  X(to_be_translated)
2734                  /*  fatal("TRANSLATION MISS!\n");  */                  /*  fatal("TRANSLATION MISS!\n");  */
2735                  if (!cpu->memory_rw(cpu, cpu->mem, addr, ib,                  if (!cpu->memory_rw(cpu, cpu->mem, addr, ib,
2736                      sizeof(ib), MEM_READ, CACHE_INSTRUCTION)) {                      sizeof(ib), MEM_READ, CACHE_INSTRUCTION)) {
2737                          fatal("to_be_translated(): "                          fatal("PPC to_be_translated(): "
2738                              "read failed: TODO\n");                              "read failed: TODO\n");
2739                          goto bad;                          exit(1);
2740                            /*  goto bad;  */
2741                  }                  }
2742          }          }
2743    
2744          iword = *((uint32_t *)&ib[0]);          iword = *((uint32_t *)&ib[0]);
2745            iword = BE32_TO_HOST(iword);
 #ifdef HOST_LITTLE_ENDIAN  
         if (cpu->byte_order == EMUL_BIG_ENDIAN)  
 #else  
         if (cpu->byte_order == EMUL_LITTLE_ENDIAN)  
 #endif  
                 iword = ((iword & 0xff) << 24) |  
                         ((iword & 0xff00) << 8) |  
                         ((iword & 0xff0000) >> 8) |  
                         ((iword & 0xff000000) >> 24);  
2746    
2747    
2748  #define DYNTRANS_TO_BE_TRANSLATED_HEAD  #define DYNTRANS_TO_BE_TRANSLATED_HEAD
# Line 1771  X(to_be_translated) Line 2758  X(to_be_translated)
2758    
2759          switch (main_opcode) {          switch (main_opcode) {
2760    
2761            case 0x04:
2762                    if (iword == 0x12739cc4) {
2763                            /*  vxor v19,v19,v19  */
2764                            ic->f = instr(vxor);
2765                            ic->arg[0] = 19;
2766                            ic->arg[1] = 19;
2767                            ic->arg[2] = 19;
2768                    } else {
2769                            if (!cpu->translation_readahead)
2770                                    fatal("[ TODO: Unimplemented ALTIVEC, iword"
2771                                        " = 0x%08"PRIx32"x ]\n", iword);
2772                            goto bad;
2773                    }
2774                    break;
2775    
2776          case PPC_HI6_MULLI:          case PPC_HI6_MULLI:
2777                  rt = (iword >> 21) & 31;                  rt = (iword >> 21) & 31;
2778                  ra = (iword >> 16) & 31;                  ra = (iword >> 16) & 31;
# Line 1806  X(to_be_translated) Line 2808  X(to_be_translated)
2808                          imm = (int16_t)(iword & 0xffff);                          imm = (int16_t)(iword & 0xffff);
2809                          if (l_bit)                          if (l_bit)
2810                                  ic->f = instr(cmpdi);                                  ic->f = instr(cmpdi);
2811                          else                          else {
2812                                  ic->f = instr(cmpwi);                                  if (bf == 0)
2813                                            ic->f = instr(cmpwi_cr0);
2814                                    else
2815                                            ic->f = instr(cmpwi);
2816                            }
2817                  }                  }
2818                  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);                  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2819                  ic->arg[1] = (ssize_t)imm;                  ic->arg[1] = (ssize_t)imm;
2820                  ic->arg[2] = bf;                  ic->arg[2] = 28 - 4 * bf;
2821                  break;                  break;
2822    
2823          case PPC_HI6_ADDIC:          case PPC_HI6_ADDIC:
2824          case PPC_HI6_ADDIC_DOT:          case PPC_HI6_ADDIC_DOT:
2825                  if (cpu->cd.ppc.bits == 64) {                  if (cpu->cd.ppc.bits == 64) {
2826                          fatal("addic for 64-bit: TODO\n");                          if (!cpu->translation_readahead)
2827                                    fatal("addic for 64-bit: TODO\n");
2828                          goto bad;                          goto bad;
2829                  }                  }
2830                  rt = (iword >> 21) & 31;                  rt = (iword >> 21) & 31;
# Line 1828  X(to_be_translated) Line 2835  X(to_be_translated)
2835                  else                  else
2836                          ic->f = instr(addic_dot);                          ic->f = instr(addic_dot);
2837                  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);                  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2838                  ic->arg[1] = (ssize_t)imm;                  ic->arg[1] = imm;
2839                  ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);                  ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);
2840                  break;                  break;
2841    
# Line 1837  X(to_be_translated) Line 2844  X(to_be_translated)
2844                  rt = (iword >> 21) & 31; ra = (iword >> 16) & 31;                  rt = (iword >> 21) & 31; ra = (iword >> 16) & 31;
2845                  ic->f = instr(addi);                  ic->f = instr(addi);
2846                  if (ra == 0)                  if (ra == 0)
2847                          ic->arg[0] = (size_t)(&cpu->cd.ppc.zero);                          ic->f = instr(li);
2848                  else                  else
2849                          ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);                          ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2850                  ic->arg[1] = (ssize_t)(int16_t)(iword & 0xffff);                  ic->arg[1] = (int16_t)(iword & 0xffff);
2851                  if (main_opcode == PPC_HI6_ADDIS)                  if (main_opcode == PPC_HI6_ADDIS)
2852                          ic->arg[1] <<= 16;                          ic->arg[1] <<= 16;
2853                    if (ra == 0 && ic->arg[1] == 0)
2854                            ic->f = instr(li_0);
2855                  ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);                  ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);
2856                  break;                  break;
2857    
# Line 1879  X(to_be_translated) Line 2888  X(to_be_translated)
2888          case PPC_HI6_LBZU:          case PPC_HI6_LBZU:
2889          case PPC_HI6_LHZ:          case PPC_HI6_LHZ:
2890          case PPC_HI6_LHZU:          case PPC_HI6_LHZU:
2891            case PPC_HI6_LHA:
2892            case PPC_HI6_LHAU:
2893          case PPC_HI6_LWZ:          case PPC_HI6_LWZ:
2894          case PPC_HI6_LWZU:          case PPC_HI6_LWZU:
2895            case PPC_HI6_LD:
2896          case PPC_HI6_LFD:          case PPC_HI6_LFD:
2897            case PPC_HI6_LFS:
2898          case PPC_HI6_STB:          case PPC_HI6_STB:
2899          case PPC_HI6_STBU:          case PPC_HI6_STBU:
2900          case PPC_HI6_STH:          case PPC_HI6_STH:
2901          case PPC_HI6_STHU:          case PPC_HI6_STHU:
2902          case PPC_HI6_STW:          case PPC_HI6_STW:
2903          case PPC_HI6_STWU:          case PPC_HI6_STWU:
2904            case PPC_HI6_STD:
2905            case PPC_HI6_STFD:
2906            case PPC_HI6_STFS:
2907                  rs = (iword >> 21) & 31;                  rs = (iword >> 21) & 31;
2908                  ra = (iword >> 16) & 31;                  ra = (iword >> 16) & 31;
2909                  imm = (int16_t)(iword & 0xffff);                  imm = (int16_t)iword;
2910                  load = 0; zero = 1; size = 0; update = 0; fp = 0;                  load = 0; zero = 1; size = 0; update = 0; fp = 0;
2911                    ic->f = NULL;
2912                  switch (main_opcode) {                  switch (main_opcode) {
2913                  case PPC_HI6_LBZ:  load = 1; break;                  case PPC_HI6_LBZ:  load=1; break;
2914                  case PPC_HI6_LBZU: load = 1; update = 1; break;                  case PPC_HI6_LBZU: load=1; update=1; break;
2915                  case PPC_HI6_LHZ:  load = 1; size = 1; break;                  case PPC_HI6_LHA:  load=1; size=1; zero=0; break;
2916                  case PPC_HI6_LHZU: load = 1; size = 1; update = 1; break;                  case PPC_HI6_LHAU: load=1; size=1; zero=0; update=1; break;
2917                  case PPC_HI6_LWZ:  load = 1; size = 2; break;                  case PPC_HI6_LHZ:  load=1; size=1; break;
2918                  case PPC_HI6_LWZU: load = 1; size = 2; update = 1; break;                  case PPC_HI6_LHZU: load=1; size=1; update=1; break;
2919                  case PPC_HI6_LFD:  load = 1; size = 3; fp = 1; break;                  case PPC_HI6_LWZ:  load=1; size=2; break;
2920                    case PPC_HI6_LWZU: load=1; size=2; update=1; break;
2921                    case PPC_HI6_LD:   load=1; size=3; break;
2922                    case PPC_HI6_LFD:  load=1; size=3; fp=1;ic->f=instr(lfd);break;
2923                    case PPC_HI6_LFS:  load=1; size=2; fp=1;ic->f=instr(lfs);break;
2924                  case PPC_HI6_STB:  break;                  case PPC_HI6_STB:  break;
2925                  case PPC_HI6_STBU: update = 1; break;                  case PPC_HI6_STBU: update=1; break;
2926                  case PPC_HI6_STH:  size = 1; break;                  case PPC_HI6_STH:  size=1; break;
2927                  case PPC_HI6_STHU: size = 1; update = 1; break;                  case PPC_HI6_STHU: size=1; update=1; break;
2928                  case PPC_HI6_STW:  size = 2; break;                  case PPC_HI6_STW:  size=2; break;
2929                  case PPC_HI6_STWU: size = 2; update = 1; break;                  case PPC_HI6_STWU: size=2; update=1; break;
2930                  }                  case PPC_HI6_STD:  size=3; break;
2931                  if (fp) {                  case PPC_HI6_STFD: size=3; fp=1; ic->f = instr(stfd); break;
2932                          /*  Floating point:  */                  case PPC_HI6_STFS: size=2; fp=1; ic->f = instr(stfs); break;
2933                          if (load && size == 3) {                  }
2934                                  fatal("TODO: ld is INCORRECT!\n");                  if (ic->f == NULL) {
                                 ic->f = instr(nop);  
                         } else {  
                                 /*  TODO  */  
                                 fatal("TODO: fdgasgd\n");  
                                 goto bad;  
                         }  
                 } else {  
                         /*  Integer load/store:  */  
2935                          ic->f =                          ic->f =
2936  #ifdef MODE32  #ifdef MODE32
2937                              ppc32_loadstore                              ppc32_loadstore
# Line 1929  X(to_be_translated) Line 2942  X(to_be_translated)
2942                              + 32*update];                              + 32*update];
2943                  }                  }
2944                  if (ra == 0 && update) {                  if (ra == 0 && update) {
2945                          fatal("TODO: ra=0 && update?\n");                          if (!cpu->translation_readahead)
2946                                    fatal("TODO: ra=0 && update?\n");
2947                          goto bad;                          goto bad;
2948                  }                  }
2949                  if (fp)                  if (fp)
# Line 1949  X(to_be_translated) Line 2963  X(to_be_translated)
2963                  bo = (iword >> 21) & 31;                  bo = (iword >> 21) & 31;
2964                  bi = (iword >> 16) & 31;                  bi = (iword >> 16) & 31;
2965                  tmp_addr = (int64_t)(int16_t)(iword & 0xfffc);                  tmp_addr = (int64_t)(int16_t)(iword & 0xfffc);
                 if (lk_bit) {  
                         fatal("lk_bit: NOT YET\n");  
                         goto bad;  
                 }  
2966                  if (aa_bit) {                  if (aa_bit) {
2967                          fatal("aa_bit: NOT YET\n");                          if (!cpu->translation_readahead)
2968                                    fatal("aa_bit: NOT YET\n");
2969                          goto bad;                          goto bad;
2970                  }                  }
2971                  ic->f = instr(bc);                  if (lk_bit) {
2972                  samepage_function = instr(bc_samepage);                          ic->f = instr(bcl);
2973                  ic->arg[0] = (ssize_t)tmp_addr;                          samepage_function = instr(bcl_samepage);
2974                    } else {
2975                            ic->f = instr(bc);
2976                            if ((bo & 0x14) == 0x04) {
2977                                    samepage_function = bo & 8?
2978                                        instr(bc_samepage_simple1) :
2979                                        instr(bc_samepage_simple0);
2980                            } else
2981                                    samepage_function = instr(bc_samepage);
2982                    }
2983                    ic->arg[0] = (ssize_t)(tmp_addr + (addr & 0xffc));
2984                  ic->arg[1] = bo;                  ic->arg[1] = bo;
2985                  ic->arg[2] = bi;                  ic->arg[2] = 31-bi;
2986                  /*  Branches are calculated as cur PC + offset.  */                  /*  Branches are calculated as cur PC + offset.  */
2987                  /*  Special case: branch within the same page:  */                  /*  Special case: branch within the same page:  */
2988                  {                  {
2989                          uint64_t mask_within_page =                          uint64_t mask_within_page =
2990                              ((PPC_IC_ENTRIES_PER_PAGE-1) << 2) | 3;                              ((PPC_IC_ENTRIES_PER_PAGE-1) << 2) | 3;
2991                          uint64_t old_pc = addr;                          uint64_t old_pc = addr;
2992                          uint64_t new_pc = old_pc + (int32_t)ic->arg[0];                          uint64_t new_pc = old_pc + (int32_t)tmp_addr;
2993                          if ((old_pc & ~mask_within_page) ==                          if ((old_pc & ~mask_within_page) ==
2994                              (new_pc & ~mask_within_page)) {                              (new_pc & ~mask_within_page)) {
2995                                  ic->f = samepage_function;                                  ic->f = samepage_function;
# Line 1981  X(to_be_translated) Line 3002  X(to_be_translated)
3002    
3003          case PPC_HI6_SC:          case PPC_HI6_SC:
3004                  ic->arg[0] = (iword >> 5) & 0x7f;                  ic->arg[0] = (iword >> 5) & 0x7f;
3005                    ic->arg[1] = (addr & 0xfff) + 4;
3006                  if (cpu->machine->userland_emul != NULL)                  if (cpu->machine->userland_emul != NULL)
3007                          ic->f = instr(user_syscall);                          ic->f = instr(user_syscall);
3008                  else {                  else if (iword == 0x44ee0002) {
3009                          /*  Special case/magic hack for OpenFirmware emul:  */                          /*  Special case/magic hack for OpenFirmware emul:  */
3010                          if (iword == 0x44ee0002) {                          ic->f = instr(openfirmware);
3011                                  ic->f = instr(openfirmware);                  } else
3012                                  break;                          ic->f = instr(sc);
                         }  
                         fatal("PPC non-userland SYSCALL: TODO\n");  
                         goto bad;  
                 }  
3013                  break;                  break;
3014    
3015          case PPC_HI6_B:          case PPC_HI6_B:
3016                  aa_bit = (iword & 2) >> 1;                  aa_bit = (iword & 2) >> 1;
3017                  lk_bit = iword & 1;                  lk_bit = iword & 1;
                 if (aa_bit) {  
                         fatal("aa_bit: NOT YET\n");  
                         goto bad;  
                 }  
3018                  tmp_addr = (int64_t)(int32_t)((iword & 0x03fffffc) << 6);                  tmp_addr = (int64_t)(int32_t)((iword & 0x03fffffc) << 6);
3019                  tmp_addr = (int64_t)tmp_addr >> 6;                  tmp_addr = (int64_t)tmp_addr >> 6;
3020                  if (lk_bit) {                  if (lk_bit) {
# Line 2015  X(to_be_translated) Line 3029  X(to_be_translated)
3029                          ic->f = instr(b);                          ic->f = instr(b);
3030                          samepage_function = instr(b_samepage);                          samepage_function = instr(b_samepage);
3031                  }                  }
3032                  ic->arg[0] = (ssize_t)tmp_addr;                  ic->arg[0] = (ssize_t)(tmp_addr + (addr & 0xffc));
3033                    ic->arg[1] = (addr & 0xffc) + 4;
3034                  /*  Branches are calculated as cur PC + offset.  */                  /*  Branches are calculated as cur PC + offset.  */
3035                  /*  Special case: branch within the same page:  */                  /*  Special case: branch within the same page:  */
3036                  {                  {
3037                          uint64_t mask_within_page =                          uint64_t mask_within_page =
3038                              ((PPC_IC_ENTRIES_PER_PAGE-1) << 2) | 3;                              ((PPC_IC_ENTRIES_PER_PAGE-1) << 2) | 3;
3039                          uint64_t old_pc = addr;                          uint64_t old_pc = addr;
3040                          uint64_t new_pc = old_pc + (int32_t)ic->arg[0];                          uint64_t new_pc = old_pc + (int32_t)tmp_addr;
3041                          if ((old_pc & ~mask_within_page) ==                          if ((old_pc & ~mask_within_page) ==
3042                              (new_pc & ~mask_within_page)) {                              (new_pc & ~mask_within_page)) {
3043                                  ic->f = samepage_function;                                  ic->f = samepage_function;
# Line 2031  X(to_be_translated) Line 3046  X(to_be_translated)
3046                                      ((new_pc & mask_within_page) >> 2));                                      ((new_pc & mask_within_page) >> 2));
3047                          }                          }
3048                  }                  }
3049                    if (aa_bit) {
3050                            if (lk_bit) {
3051                                    if (cpu->machine->show_trace_tree) {
3052                                            ic->f = instr(bla_trace);
3053                                    } else {
3054                                            ic->f = instr(bla);
3055                                    }
3056                            } else {
3057                                    ic->f = instr(ba);
3058                            }
3059                            ic->arg[0] = (ssize_t)tmp_addr;
3060                    }
3061                  break;                  break;
3062    
3063          case PPC_HI6_19:          case PPC_HI6_19:
# Line 2046  X(to_be_translated) Line 3073  X(to_be_translated)
3073                          if (xo == PPC_19_BCLR) {                          if (xo == PPC_19_BCLR) {
3074                                  if (lk_bit)                                  if (lk_bit)
3075                                          ic->f = instr(bclr_l);                                          ic->f = instr(bclr_l);
3076                                  else                                  else {
3077                                          ic->f = instr(bclr);                                          ic->f = instr(bclr);
3078                                            if (!cpu->machine->show_trace_tree &&
3079                                                (bo & 0x14) == 0x14)
3080                                                    ic->f = instr(bclr_20);
3081                                    }
3082                          } else {                          } else {
3083                                    if (!(bo & 4)) {
3084                                            if (!cpu->translation_readahead)
3085                                                    fatal("TODO: bclr/bcctr "
3086                                                        "bo bit 2 clear!\n");
3087                                            goto bad;
3088                                    }
3089                                  if (lk_bit)                                  if (lk_bit)
3090                                          ic->f = instr(bcctr_l);                                          ic->f = instr(bcctr_l);
3091                                  else                                  else
3092                                          ic->f = instr(bcctr);                                          ic->f = instr(bcctr);
3093                          }                          }
3094                          ic->arg[0] = bo;                          ic->arg[0] = bo;
3095                          ic->arg[1] = bi;                          ic->arg[1] = 31 - bi;
3096                          ic->arg[2] = bh;                          ic->arg[2] = bh;
3097                          break;                          break;
3098    
# Line 2068  X(to_be_translated) Line 3105  X(to_be_translated)
3105                          ic->f = instr(rfi);                          ic->f = instr(rfi);
3106                          break;                          break;
3107    
3108                    case PPC_19_RFID:
3109                            ic->f = instr(rfid);
3110                            break;
3111    
3112                  case PPC_19_MCRF:                  case PPC_19_MCRF:
3113                          bf = (iword >> 23) & 7;                          bf = (iword >> 23) & 7;
3114                          bfa = (iword >> 18) & 7;                          bfa = (iword >> 18) & 7;
3115                          ic->arg[0] = bf;                          ic->arg[0] = 28 - 4*bf;
3116                          ic->arg[1] = bfa;                          ic->arg[1] = 28 - 4*bfa;
3117                          ic->f = instr(mcrf);                          ic->f = instr(mcrf);
3118                          break;                          break;
3119    
# Line 2080  X(to_be_translated) Line 3121  X(to_be_translated)
3121                  case PPC_19_CRANDC:                  case PPC_19_CRANDC:
3122                  case PPC_19_CREQV:                  case PPC_19_CREQV:
3123                  case PPC_19_CROR:                  case PPC_19_CROR:
3124                    case PPC_19_CRORC:
3125                    case PPC_19_CRNOR:
3126                  case PPC_19_CRXOR:                  case PPC_19_CRXOR:
3127                          switch (xo) {                          switch (xo) {
3128                          case PPC_19_CRAND:  ic->f = instr(crand); break;                          case PPC_19_CRAND:  ic->f = instr(crand); break;
3129                          case PPC_19_CRANDC: ic->f = instr(crandc); break;                          case PPC_19_CRANDC: ic->f = instr(crandc); break;
3130                          case PPC_19_CREQV:  ic->f = instr(creqv); break;                          case PPC_19_CREQV:  ic->f = instr(creqv); break;
3131                          case PPC_19_CROR:   ic->f = instr(cror); break;                          case PPC_19_CROR:   ic->f = instr(cror); break;
3132                            case PPC_19_CRORC:  ic->f = instr(crorc); break;
3133                            case PPC_19_CRNOR:  ic->f = instr(crnor); break;
3134                          case PPC_19_CRXOR:  ic->f = instr(crxor); break;                          case PPC_19_CRXOR:  ic->f = instr(crxor); break;
3135                          }                          }
3136                          ic->arg[0] = iword;                          ic->arg[0] = iword;
# Line 2095  X(to_be_translated) Line 3140  X(to_be_translated)
3140                  }                  }
3141                  break;                  break;
3142    
3143          case PPC_HI6_RLWIMI:          case PPC_HI6_RLWNM:
3144          case PPC_HI6_RLWINM:          case PPC_HI6_RLWINM:
3145                    ra = (iword >> 16) & 31;
3146                    mb = (iword >> 6) & 31;
3147                    me = (iword >> 1) & 31;  
3148                    rc = iword & 1;
3149                    mask = 0;
3150                    for (;;) {
3151                            mask |= ((uint32_t)0x80000000 >> mb);
3152                            if (mb == me)
3153                                    break;
3154                            mb ++; mb &= 31;
3155                    }
3156                    switch (main_opcode) {
3157                    case PPC_HI6_RLWNM:
3158                            ic->f = rc? instr(rlwnm_dot) : instr(rlwnm); break;
3159                    case PPC_HI6_RLWINM:
3160                            ic->f = rc? instr(rlwinm_dot) : instr(rlwinm); break;
3161                    }
3162                    ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3163                    ic->arg[1] = mask;
3164                    ic->arg[2] = (uint32_t)iword;
3165                    break;
3166    
3167            case PPC_HI6_RLWIMI:
3168                  rs = (iword >> 21) & 31;                  rs = (iword >> 21) & 31;
3169                  ra = (iword >> 16) & 31;                  ra = (iword >> 16) & 31;
3170                  if (main_opcode == PPC_HI6_RLWIMI)                  ic->f = instr(rlwimi);
                         ic->f = instr(rlwimi);  
                 else  
                         ic->f = instr(rlwinm);  
3171                  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);                  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
3172                  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);                  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3173                  ic->arg[2] = (uint32_t)iword;                  ic->arg[2] = (uint32_t)iword;
# Line 2133  X(to_be_translated) Line 3198  X(to_be_translated)
3198                  xo = (iword >> 2) & 7;                  xo = (iword >> 2) & 7;
3199                  switch (xo) {                  switch (xo) {
3200    
3201                    case PPC_30_RLDICL:
3202                  case PPC_30_RLDICR:                  case PPC_30_RLDICR:
3203                          ic->f = instr(rldicr);                  case PPC_30_RLDIMI:
3204                            switch (xo) {
3205                            case PPC_30_RLDICL: ic->f = instr(rldicl); break;
3206                            case PPC_30_RLDICR: ic->f = instr(rldicr); break;
3207                            case PPC_30_RLDIMI: ic->f = instr(rldimi); break;
3208                            }
3209                          ic->arg[0] = iword;                          ic->arg[0] = iword;
3210                          if (cpu->cd.ppc.bits == 32) {                          if (cpu->cd.ppc.bits == 32) {
3211                                  fatal("TODO: rldicr in 32-bit mode?\n");                                  if (!cpu->translation_readahead)
3212                                            fatal("TODO: rld* in 32-bit mode?\n");
3213                                  goto bad;                                  goto bad;
3214                          }                          }
3215                          break;                          break;
# Line 2164  X(to_be_translated) Line 3236  X(to_be_translated)
3236                          } else {                          } else {
3237                                  if (l_bit)                                  if (l_bit)
3238                                          ic->f = instr(cmpd);                                          ic->f = instr(cmpd);
3239                                  else                                  else {
3240                                          ic->f = instr(cmpw);                                          if (bf == 0)
3241                                                    ic->f = instr(cmpw_cr0);
3242                                            else
3243                                                    ic->f = instr(cmpw);
3244                                    }
3245                          }                          }
3246                          ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);                          ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3247                          ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rb]);                          ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3248                          ic->arg[2] = bf;                          ic->arg[2] = 28 - 4*bf;
3249                          break;                          break;
3250    
3251                  case PPC_31_CNTLZW:                  case PPC_31_CNTLZW:
# Line 2177  X(to_be_translated) Line 3253  X(to_be_translated)
3253                          ra = (iword >> 16) & 31;                          ra = (iword >> 16) & 31;
3254                          rc = iword & 1;                          rc = iword & 1;
3255                          if (rc) {                          if (rc) {
3256                                  fatal("TODO: rc\n");                                  if (!cpu->translation_readahead)
3257                                            fatal("TODO: rc\n");
3258                                  goto bad;                                  goto bad;
3259                          }                          }
3260                          ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);                          ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
# Line 2188  X(to_be_translated) Line 3265  X(to_be_translated)
3265                  case PPC_31_MFSPR:                  case PPC_31_MFSPR:
3266                          rt = (iword >> 21) & 31;                          rt = (iword >> 21) & 31;
3267                          spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);                          spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
3268                            debug_spr_usage(cpu->pc, spr);
3269                          ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rt]);                          ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rt]);
3270                            ic->arg[1] = (size_t)(&cpu->cd.ppc.spr[spr]);
3271                          switch (spr) {                          switch (spr) {
3272                          case 8:   ic->f = instr(mflr); break;                          case SPR_PMC1:  ic->f = instr(mfspr_pmc1); break;
3273                          case 9:   ic->f = instr(mfctr); break;                          default:        ic->f = instr(mfspr);
                         case 25:  ic->f = instr(mfsdr1); break;  
                         case 26:  ic->f = instr(mfsrr0); break;  
                         case 27:  ic->f = instr(mfsrr1); break;  
                         case 272: ic->f = instr(mfsprg0); break;  
                         case 273: ic->f = instr(mfsprg1); break;  
                         case 274: ic->f = instr(mfsprg2); break;  
                         case 275: ic->f = instr(mfsprg3); break;  
                         case 287: ic->f = instr(mfpvr); break;  
                         case 1008:ic->f = instr(mfdbsr); break;  
                         case 1009:ic->f = instr(mfhid1); break;  
                         case 1017:ic->f = instr(mfl2cr); break;  
                         default:if (spr >= 528 && spr < 544) {  
                                         if (spr & 1) {  
                                                 if (spr & 16)  
                                                         ic->f = instr(mfdbatl);  
                                                 else  
                                                         ic->f = instr(mfibatl);  
                                         } else {  
                                                 if (spr & 16)  
                                                         ic->f = instr(mfdbatu);  
                                                 else  
                                                         ic->f = instr(mfibatu);  
                                         }  
                                         ic->arg[1] = (spr >> 1) & 3;  
                                 } else {  
                                         fatal("UNIMPLEMENTED spr %i\n", spr);  
                                         goto bad;  
                                 }  
3274                          }                          }
3275                          break;                          break;
3276    
3277                  case PPC_31_MTSPR:                  case PPC_31_MTSPR:
3278                          rs = (iword >> 21) & 31;                          rs = (iword >> 21) & 31;
3279                          spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);                          spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
3280                            debug_spr_usage(cpu->pc, spr);
3281                          ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);                          ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
3282                            ic->arg[1] = (size_t)(&cpu->cd.ppc.spr[spr]);
3283                          switch (spr) {                          switch (spr) {
3284                          case 8:   ic->f = instr(mtlr); break;                          case SPR_LR:
3285                          case 9:   ic->f = instr(mtctr); break;                                  ic->f = instr(mtlr);
3286                          case 25:  ic->f = instr(mtsdr1); break;                                  break;
3287                          case 26:  ic->f = instr(mtsrr0); break;                          case SPR_CTR:
3288                          case 27:  ic->f = instr(mtsrr1); break;                                  ic->f = instr(mtctr);
3289                          case 272: ic->f = instr(mtsprg0); break;                                  break;
3290                          case 273: ic->f = instr(mtsprg1); break;                          default:ic->f = instr(mtspr);
                         case 274: ic->f = instr(mtsprg2); break;  
                         case 275: ic->f = instr(mtsprg3); break;  
                         case 1008:ic->f = instr(mtdbsr); break;  
                         default:if (spr >= 528 && spr < 544) {  
                                         if (spr & 1) {  
                                                 if (spr & 16)  
                                                         ic->f = instr(mtdbatl);  
                                                 else  
                                                         ic->f = instr(mtibatl);  
                                         } else {  
                                                 if (spr & 16)  
                                                         ic->f = instr(mtdbatu);  
                                                 else  
                                                         ic->f = instr(mtibatu);  
                                         }  
                                         ic->arg[1] = (spr >> 1) & 3;  
                                 } else {  
                                         fatal("UNIMPLEMENTED spr %i\n", spr);  
                                         goto bad;  
                                 }  
3291                          }                          }
3292                          break;                          break;
3293    
# Line 2271  X(to_be_translated) Line 3304  X(to_be_translated)
3304                          break;                          break;
3305    
3306                  case PPC_31_MTMSR:                  case PPC_31_MTMSR:
3307                    case PPC_31_MTMSRD:
3308                          rs = (iword >> 21) & 31;                          rs = (iword >> 21) & 31;
3309                          l_bit = (iword >> 16) & 1;                          l_bit = (iword >> 16) & 1;
3310                          if (l_bit) {                          if (l_bit) {
3311                                  fatal("TODO: mtmsr l-bit\n");                                  if (!cpu->translation_readahead)
3312                                            fatal("TODO: mtmsr l-bit\n");
3313                                  goto bad;                                  goto bad;
3314                          }                          }
3315                          ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);                          ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
3316                            ic->arg[1] = (addr & 0xfff) + 4;
3317                            ic->arg[2] = xo == PPC_31_MTMSRD;
3318                          ic->f = instr(mtmsr);                          ic->f = instr(mtmsr);
3319                          break;                          break;
3320    
# Line 2308  X(to_be_translated) Line 3345  X(to_be_translated)
3345                          case PPC_31_MTSRIN: ic->f = instr(mtsrin); break;                          case PPC_31_MTSRIN: ic->f = instr(mtsrin); break;
3346                          }                          }
3347                          if (cpu->cd.ppc.bits == 64) {                          if (cpu->cd.ppc.bits == 64) {
3348                                  fatal("Not yet for 64-bit mode\n");                                  if (!cpu->translation_readahead)
3349                                            fatal("Not yet for 64-bit mode\n");
3350                                  goto bad;                                  goto bad;
3351                          }                          }
3352                          break;                          break;
3353    
3354                    case PPC_31_MFSR:
3355                  case PPC_31_MTSR:                  case PPC_31_MTSR:
3356                          rt = (iword >> 21) & 31;                          rt = (iword >> 21) & 31;
3357                          ic->arg[0] = (iword >> 16) & 15;                          ic->arg[0] = (iword >> 16) & 15;
3358                          ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rt]);                          ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rt]);
3359                          ic->f = instr(mtsr);                          switch (xo) {
3360                            case PPC_31_MFSR:   ic->f = instr(mfsr); break;
3361                            case PPC_31_MTSR:   ic->f = instr(mtsr); break;
3362                            }
3363                          if (cpu->cd.ppc.bits == 64) {                          if (cpu->cd.ppc.bits == 64) {
3364                                  fatal("Not yet for 64-bit mode\n");                                  if (!cpu->translation_readahead)
3365                                            fatal("Not yet for 64-bit mode\n");
3366                                  goto bad;                                  goto bad;
3367                          }                          }
3368                          break;                          break;
# Line 2339  X(to_be_translated) Line 3382  X(to_be_translated)
3382                          break;                          break;
3383    
3384                  case PPC_31_SYNC:                  case PPC_31_SYNC:
3385                  case PPC_31_TLBSYNC:                  case PPC_31_DSSALL:
3386                  case PPC_31_EIEIO:                  case PPC_31_EIEIO:
3387                  case PPC_31_DCBST:                  case PPC_31_DCBST:
3388                  case PPC_31_DCBTST:                  case PPC_31_DCBTST:
3389                  case PPC_31_DCBF:                  case PPC_31_DCBF:
3390                  case PPC_31_DCBT:                  case PPC_31_DCBT:
3391                  case PPC_31_ICBI:                  case PPC_31_ICBI:
                         /*  TODO  */  
3392                          ic->f = instr(nop);                          ic->f = instr(nop);
3393                          break;                          break;
3394    
# Line 2358  X(to_be_translated) Line 3400  X(to_be_translated)
3400                          else                          else
3401                                  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);                                  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3402                          ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rb]);                          ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3403                            ic->arg[2] = addr & 0xfff;
3404                          ic->f = instr(dcbz);                          ic->f = instr(dcbz);
3405                          break;                          break;
3406    
3407                    case PPC_31_TLBIA:
3408                            ic->f = instr(tlbia);
3409                            break;
3410    
3411                    case PPC_31_TLBSYNC:
3412                            /*  According to IBM, "Ensures that a tlbie and
3413                                tlbia instruction executed by one processor has
3414                                completed on all other processors.", which in
3415                                GXemul means a nop :-)  */
3416                            ic->f = instr(nop);
3417                            break;
3418    
3419                  case PPC_31_TLBIE:                  case PPC_31_TLBIE:
3420                          /*  TODO  */                          /*  TODO: POWER also uses ra?  */
3421                            rb = (iword >> 11) & 31;
3422                            ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3423                          ic->f = instr(tlbie);                          ic->f = instr(tlbie);
3424                          break;                          break;
3425    
3426                    case PPC_31_TLBLD:      /*  takes an arg  */
3427                            rb = (iword >> 11) & 31;
3428                            ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3429                            ic->f = instr(tlbld);
3430                            break;
3431    
3432                    case PPC_31_TLBLI:      /*  takes an arg  */
3433                            rb = (iword >> 11) & 31;
3434                            ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3435                            ic->f = instr(tlbli);
3436                            break;
3437    
3438                    case PPC_31_TLBSX_DOT:
3439                            /*  TODO  */
3440                            ic->f = instr(tlbsx_dot);
3441                            break;
3442    
3443                  case PPC_31_MFTB:                  case PPC_31_MFTB:
3444                          rt = (iword >> 21) & 31;                          rt = (iword >> 21) & 31;
3445                          spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);                          spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
# Line 2373  X(to_be_translated) Line 3447  X(to_be_translated)
3447                          switch (spr) {                          switch (spr) {
3448                          case 268: ic->f = instr(mftb); break;                          case 268: ic->f = instr(mftb); break;
3449                          case 269: ic->f = instr(mftbu); break;                          case 269: ic->f = instr(mftbu); break;
3450                          default:fatal("mftb spr=%i?\n", spr);                          default:if (!cpu->translation_readahead)
3451                                            fatal("mftb spr=%i?\n", spr);
3452                                  goto bad;                                  goto bad;
3453                          }                          }
3454                          break;                          break;
# Line 2398  X(to_be_translated) Line 3473  X(to_be_translated)
3473                          ic->f = instr(llsc);                          ic->f = instr(llsc);
3474                          break;                          break;
3475    
3476                    case PPC_31_LSWI:
3477                    case PPC_31_STSWI:
3478                            rs = (iword >> 21) & 31;
3479                            ra = (iword >> 16) & 31;
3480                            nb = (iword >> 11) & 31;
3481                            ic->arg[0] = rs;
3482                            if (ra == 0)
3483                                    ic->arg[1] = (size_t)(&cpu->cd.ppc.zero);
3484                            else
3485                                    ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3486                            ic->arg[2] = nb == 0? 32 : nb;
3487                            switch (xo) {
3488                            case PPC_31_LSWI:  ic->f = instr(lswi); break;
3489                            case PPC_31_STSWI: ic->f = instr(stswi); break;
3490                            }
3491                            break;
3492    
3493                    case PPC_31_WRTEEI:
3494                            ic->arg[0] = iword & 0x8000;
3495                            ic->f = instr(wrteei);
3496                            break;
3497    
3498                    case 0x1c3:
3499                            fatal("[ mtdcr: TODO ]\n");
3500                            ic->f = instr(nop);
3501                            break;
3502    
3503                  case PPC_31_LBZX:                  case PPC_31_LBZX:
3504                  case PPC_31_LBZUX:                  case PPC_31_LBZUX:
3505                    case PPC_31_LHAX:
3506                    case PPC_31_LHAUX:
3507                  case PPC_31_LHZX:                  case PPC_31_LHZX:
3508                  case PPC_31_LHZUX:                  case PPC_31_LHZUX:
3509                  case PPC_31_LWZX:                  case PPC_31_LWZX:
3510                  case PPC_31_LWZUX:                  case PPC_31_LWZUX:
3511                    case PPC_31_LHBRX:
3512                    case PPC_31_LWBRX:
3513                    case PPC_31_LFDX:
3514                    case PPC_31_LFSX:
3515                  case PPC_31_STBX:                  case PPC_31_STBX:
3516                  case PPC_31_STBUX:                  case PPC_31_STBUX:
3517                  case PPC_31_STHX:                  case PPC_31_STHX:
# Line 2412  X(to_be_translated) Line 3520  X(to_be_translated)
3520                  case PPC_31_STWUX:                  case PPC_31_STWUX:
3521                  case PPC_31_STDX:                  case PPC_31_STDX:
3522                  case PPC_31_STDUX:                  case PPC_31_STDUX:
3523                    case PPC_31_STHBRX:
3524                    case PPC_31_STWBRX:
3525                    case PPC_31_STFDX:
3526                    case PPC_31_STFSX:
3527                          rs = (iword >> 21) & 31;                          rs = (iword >> 21) & 31;
3528                          ra = (iword >> 16) & 31;                          ra = (iword >> 16) & 31;
3529                          rb = (iword >> 11) & 31;                          rb = (iword >> 11) & 31;
                         ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);  
3530                          if (ra == 0)                          if (ra == 0)
3531                                  ic->arg[1] = (size_t)(&cpu->cd.ppc.zero);                                  ic->arg[1] = (size_t)(&cpu->cd.ppc.zero);
3532                          else                          else
3533                                  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);                                  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3534                          ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rb]);                          ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3535                          load = 0; zero = 1; size = 0; update = 0;                          load = 0; zero = 1; size = 0; update = 0;
3536                            byterev = 0; fp = 0;
3537                            ic->f = NULL;
3538                          switch (xo) {                          switch (xo) {
3539                          case PPC_31_LBZX:  load = 1; break;                          case PPC_31_LBZX:  load = 1; break;
3540                          case PPC_31_LBZUX: load = update = 1; break;                          case PPC_31_LBZUX: load=update=1; break;
3541                          case PPC_31_LHZX:  size = 1; load = 1; break;                          case PPC_31_LHAX:  size=1; load=1; zero=0; break;
3542                          case PPC_31_LHZUX: size = 1; load = update = 1; break;                          case PPC_31_LHAUX: size=1; load=update=1; zero=0; break;
3543                          case PPC_31_LWZX:  size = 2; load = 1; break;                          case PPC_31_LHZX:  size=1; load=1; break;
3544                          case PPC_31_LWZUX: size = 2; load = update = 1; break;                          case PPC_31_LHZUX: size=1; load=update = 1; break;
3545                            case PPC_31_LWZX:  size=2; load=1; break;
3546                            case PPC_31_LWZUX: size=2; load=update = 1; break;
3547                            case PPC_31_LHBRX: size=1; load=1; byterev=1;
3548                                               ic->f = instr(lhbrx); break;
3549                            case PPC_31_LWBRX: size=2; load=1; byterev=1;
3550                                               ic->f = instr(lwbrx); break;
3551                            case PPC_31_LFDX:  size=3; load=1; fp=1;
3552                                               ic->f = instr(lfdx); break;
3553                            case PPC_31_LFSX:  size=2; load=1; fp=1;
3554                                               ic->f = instr(lfsx); break;
3555                          case PPC_31_STBX:  break;                          case PPC_31_STBX:  break;
3556                          case PPC_31_STBUX: update = 1; break;                          case PPC_31_STBUX: update = 1; break;
3557                          case PPC_31_STHX:  size = 1; break;                          case PPC_31_STHX:  size=1; break;
3558                          case PPC_31_STHUX: size = 1; update = 1; break;                          case PPC_31_STHUX: size=1; update = 1; break;
3559                          case PPC_31_STWX:  size = 2; break;                          case PPC_31_STWX:  size=2; break;
3560                          case PPC_31_STWUX: size = 2; update = 1; break;                          case PPC_31_STWUX: size=2; update = 1; break;
3561                          case PPC_31_STDX:  size = 3; break;                          case PPC_31_STDX:  size=3; break;
3562                          case PPC_31_STDUX: size = 3; update = 1; break;                          case PPC_31_STDUX: size=3; update = 1; break;
3563                            case PPC_31_STHBRX:size=1; byterev = 1;
3564                                               ic->f = instr(sthbrx); break;
3565                            case PPC_31_STWBRX:size=2; byterev = 1;
3566                                               ic->f = instr(stwbrx); break;
3567                            case PPC_31_STFDX: size=3; fp=1;
3568                                               ic->f = instr(stfdx); break;
3569                            case PPC_31_STFSX: size=2; fp=1;
3570                                               ic->f = instr(stfsx); break;
3571                          }                          }
3572                          ic->f =                          if (fp)
3573                                    ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rs]);
3574                            else
3575                                    ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
3576                            if (!byterev && ic->f == NULL) {
3577                                    ic->f =
3578  #ifdef MODE32  #ifdef MODE32
3579                              ppc32_loadstore_indexed                                      ppc32_loadstore_indexed
3580  #else  #else
3581                              ppc_loadstore_indexed                                      ppc_loadstore_indexed
3582  #endif  #endif
3583                              [size + 4*zero + 8*load + 16*update];                                      [size + 4*zero + 8*load + 16*update];
3584                            }
3585                          if (ra == 0 && update) {                          if (ra == 0 && update) {
3586                                  fatal("TODO: ra=0 && update?\n");                                  if (!cpu->translation_readahead)
3587                                            fatal("TODO: ra=0 && update?\n");
3588                                  goto bad;                                  goto bad;
3589                          }                          }
3590                          break;                          break;
# Line 2455  X(to_be_translated) Line 3593  X(to_be_translated)
3593                  case PPC_31_EXTSH:                  case PPC_31_EXTSH:
3594                  case PPC_31_EXTSW:                  case PPC_31_EXTSW:
3595                  case PPC_31_SLW:                  case PPC_31_SLW:
3596                    case PPC_31_SLD:
3597                  case PPC_31_SRAW:                  case PPC_31_SRAW:
3598                  case PPC_31_SRW:                  case PPC_31_SRW:
3599                  case PPC_31_AND:                  case PPC_31_AND:
# Line 2464  X(to_be_translated) Line 3603  X(to_be_translated)
3603                  case PPC_31_OR:                  case PPC_31_OR:
3604                  case PPC_31_ORC:                  case PPC_31_ORC:
3605                  case PPC_31_XOR:                  case PPC_31_XOR:
3606                    case PPC_31_EQV:
3607                          rs = (iword >> 21) & 31;                          rs = (iword >> 21) & 31;
3608                          ra = (iword >> 16) & 31;                          ra = (iword >> 16) & 31;
3609                          rb = (iword >> 11) & 31;                          rb = (iword >> 11) & 31;
# Line 2478  X(to_be_translated) Line 3618  X(to_be_translated)
3618                                            rc_f  = instr(extsw_dot); break;                                            rc_f  = instr(extsw_dot); break;
3619                          case PPC_31_SLW:  ic->f = instr(slw);                          case PPC_31_SLW:  ic->f = instr(slw);
3620                                            rc_f  = instr(slw_dot); break;                                            rc_f  = instr(slw_dot); break;
3621                            case PPC_31_SLD:  ic->f = instr(sld);
3622                                              rc_f  = instr(sld_dot); break;
3623                          case PPC_31_SRAW: ic->f = instr(sraw);                          case PPC_31_SRAW: ic->f = instr(sraw);
3624                                            rc_f  = instr(sraw_dot); break;                                            rc_f  = instr(sraw_dot); break;
3625                          case PPC_31_SRW:  ic->f = instr(srw);                          case PPC_31_SRW:  ic->f = instr(srw);
# Line 2490  X(to_be_translated) Line 3632  X(to_be_translated)
3632                                            rc_f  = instr(andc_dot); break;                                            rc_f  = instr(andc_dot); break;
3633                          case PPC_31_NOR:  ic->f = instr(nor);                          case PPC_31_NOR:  ic->f = instr(nor);
3634                                            rc_f  = instr(nor_dot); break;                                            rc_f  = instr(nor_dot); break;
3635                          case PPC_31_OR:   ic->f = instr(or);                          case PPC_31_OR:   ic->f = rs == rb? instr(mr)
3636                                                    : instr(or);
3637                                            rc_f  = instr(or_dot); break;                                            rc_f  = instr(or_dot); break;
3638                          case PPC_31_ORC:  ic->f = instr(orc);                          case PPC_31_ORC:  ic->f = instr(orc);
3639                                            rc_f  = instr(orc_dot); break;                                            rc_f  = instr(orc_dot); break;
3640                          case PPC_31_XOR:  ic->f = instr(xor);                          case PPC_31_XOR:  ic->f = instr(xor);
3641                                            rc_f  = instr(xor_dot); break;                                            rc_f  = instr(xor_dot); break;
3642                            case PPC_31_EQV:  ic->f = instr(eqv);
3643                                              rc_f  = instr(eqv_dot); break;
3644                          }                          }
3645                          ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);                          ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
3646                          ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rb]);                          ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rb]);
# Line 2517  X(to_be_translated) Line 3662  X(to_be_translated)
3662                  case PPC_31_SUBF:                  case PPC_31_SUBF:
3663                  case PPC_31_SUBFC:                  case PPC_31_SUBFC:
3664                  case PPC_31_SUBFE:                  case PPC_31_SUBFE:
3665                    case PPC_31_SUBFME:
3666                  case PPC_31_SUBFZE:                  case PPC_31_SUBFZE:
3667                          rt = (iword >> 21) & 31;                          rt = (iword >> 21) & 31;
3668                          ra = (iword >> 16) & 31;                          ra = (iword >> 16) & 31;
# Line 2524  X(to_be_translated) Line 3670  X(to_be_translated)
3670                          oe_bit = (iword >> 10) & 1;                          oe_bit = (iword >> 10) & 1;
3671                          rc = iword & 1;                          rc = iword & 1;
3672                          if (oe_bit) {                          if (oe_bit) {
3673                                  fatal("oe_bit not yet implemented\n");                                  if (!cpu->translation_readahead)
3674                                            fatal("oe_bit not yet implemented\n");
3675                                  goto bad;                                  goto bad;
3676                          }                          }
3677                          switch (xo) {                          switch (xo) {
# Line 2541  X(to_be_translated) Line 3688  X(to_be_translated)
3688                          case PPC_31_SUBF:   ic->f = instr(subf); break;                          case PPC_31_SUBF:   ic->f = instr(subf); break;
3689                          case PPC_31_SUBFC:  ic->f = instr(subfc); break;                          case PPC_31_SUBFC:  ic->f = instr(subfc); break;
3690                          case PPC_31_SUBFE:  ic->f = instr(subfe); n64=1; break;                          case PPC_31_SUBFE:  ic->f = instr(subfe); n64=1; break;
3691                            case PPC_31_SUBFME: ic->f = instr(subfme); n64=1; break;
3692                          case PPC_31_SUBFZE: ic->f = instr(subfze); n64=1;break;                          case PPC_31_SUBFZE: ic->f = instr(subfze); n64=1;break;
3693                          }                          }
3694                          if (rc) {                          if (rc) {
# Line 2553  X(to_be_translated) Line 3701  X(to_be_translated)
3701                                          ic->f = instr(addme_dot); break;                                          ic->f = instr(addme_dot); break;
3702                                  case PPC_31_ADDZE:                                  case PPC_31_ADDZE:
3703                                          ic->f = instr(addze_dot); break;                                          ic->f = instr(addze_dot); break;
3704                                    case PPC_31_DIVW:
3705                                            ic->f = instr(divw_dot); break;
3706                                    case PPC_31_DIVWU:
3707                                            ic->f = instr(divwu_dot); break;
3708                                    case PPC_31_MULLW:
3709                                            ic->f = instr(mullw_dot); break;
3710                                    case PPC_31_MULHW:
3711                                            ic->f = instr(mulhw_dot); break;
3712                                    case PPC_31_MULHWU:
3713                                            ic->f = instr(mulhwu_dot); break;
3714                                  case PPC_31_SUBF:                                  case PPC_31_SUBF:
3715                                          ic->f = instr(subf_dot); break;                                          ic->f = instr(subf_dot); break;
3716                                  case PPC_31_SUBFC:                                  case PPC_31_SUBFC:
3717                                          ic->f = instr(subfc_dot); break;                                          ic->f = instr(subfc_dot); break;
3718                                  case PPC_31_SUBFE:                                  case PPC_31_SUBFE:
3719                                          ic->f = instr(subfe_dot); break;                                          ic->f = instr(subfe_dot); break;
3720                                    case PPC_31_SUBFME:
3721                                            ic->f = instr(subfme_dot); break;
3722                                  case PPC_31_SUBFZE:                                  case PPC_31_SUBFZE:
3723                                          ic->f = instr(subfze_dot); break;                                          ic->f = instr(subfze_dot); break;
3724                                  default:fatal("RC bit not yet implemented\n");                                  default:if (!cpu->translation_readahead)
3725                                                    fatal("RC bit not yet "
3726                                                        "implemented\n");
3727                                          goto bad;                                          goto bad;
3728                                  }                                  }
3729                          }                          }
# Line 2569  X(to_be_translated) Line 3731  X(to_be_translated)
3731                          ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rb]);                          ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3732                          ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);                          ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);
3733                          if (cpu->cd.ppc.bits == 64 && n64) {                          if (cpu->cd.ppc.bits == 64 && n64) {
3734                                  fatal("Not yet for 64-bit mode\n");                                  if (!cpu->translation_readahead)
3735                                            fatal("Not yet for 64-bit mode\n");
3736                                  goto bad;                                  goto bad;
3737                          }                          }
3738                          break;                          break;
3739    
3740                    case PPC_31_LVX:
3741                    case PPC_31_LVXL:
3742                    case PPC_31_STVX:
3743                    case PPC_31_STVXL:
3744                            load = 0;
3745                            switch (xo) {
3746                            case PPC_31_LVX:
3747                            case PPC_31_LVXL:
3748                                    load = 1; break;
3749                            }
3750                            rs = (iword >> 21) & 31;
3751                            ra = (iword >> 16) & 31;
3752                            rb = (iword >> 11) & 31;
3753                            ic->arg[0] = rs;
3754                            if (ra == 0)
3755                                    ic->arg[1] = (size_t)(&cpu->cd.ppc.zero);
3756                            else
3757                                    ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3758                            ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3759                            ic->f = load? instr(lvx) : instr(stvx);
3760                            break;
3761    
3762                  default:goto bad;                  default:goto bad;
3763                  }                  }
3764                  break;                  break;
3765    
3766          case PPC_HI6_63:          case PPC_HI6_59:
3767                  xo = (iword >> 1) & 1023;                  xo = (iword >>  1) & 1023;
3768                  rt = (iword >> 21) & 31;                  rt = (iword >> 21) & 31;
3769                  ra = (iword >> 16) & 31;                  ra = (iword >> 16) & 31;
3770                  rb = (iword >> 11) & 31;                  rb = (iword >> 11) & 31;
3771                    rs = (iword >>  6) & 31;        /*  actually frc  */
3772                  rc = iword & 1;                  rc = iword & 1;
3773    
3774                  switch (xo) {                  if (rc) {
3775                            if (!cpu->translation_readahead)
3776                                    fatal("Floating point (59) "
3777                                        "with rc bit! TODO\n");
3778                            goto bad;
3779                    }
3780    
3781                  case PPC_63_FMR:                  /*  NOTE: Some floating-point instructions are selected
3782                          if (rc) {                      using only the lowest 5 bits, not all 10!  */
3783                                  fatal("FMR with rc-bit: TODO\n");                  switch (xo & 31) {
3784                                  goto bad;                  case PPC_59_FDIVS:
3785                          }                  case PPC_59_FSUBS:
3786                          ic->f = instr(fmr);                  case PPC_59_FADDS:
3787                          ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rb]);                          switch (xo & 31) {
3788                          ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[rt]);                          case PPC_59_FDIVS: ic->f = instr(fdivs); break;
3789                            case PPC_59_FSUBS: ic->f = instr(fsubs); break;
3790                            case PPC_59_FADDS: ic->f = instr(fadds); break;
3791                            }
3792                            ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[ra]);
3793                            ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[rb]);
3794                            ic->arg[2] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3795                            break;
3796                    case PPC_59_FMULS:
3797                            ic->f = instr(fmuls);
3798                            ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3799                            ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[ra]);
3800                            ic->arg[2] = (size_t)(&cpu->cd.ppc.fpr[rs]); /* frc */
3801                          break;                          break;
3802                    default:/*  Use all 10 bits of xo:  */
3803                            switch (xo) {
3804                            default:goto bad;
3805                            }
3806                    }
3807                    break;
3808    
3809                  default:goto bad;          case PPC_HI6_63:
3810                    xo = (iword >>  1) & 1023;
3811                    rt = (iword >> 21) & 31;
3812                    ra = (iword >> 16) & 31;
3813                    rb = (iword >> 11) & 31;
3814                    rs = (iword >>  6) & 31;        /*  actually frc  */
3815                    rc = iword & 1;
3816    
3817                    if (rc) {
3818                            if (!cpu->translation_readahead)
3819                                    fatal("Floating point (63) "
3820                                        "with rc bit! TODO\n");
3821                            goto bad;
3822                    }
3823    
3824                    /*  NOTE: Some floating-point instructions are selected
3825                        using only the lowest 5 bits, not all 10!  */
3826                    switch (xo & 31) {
3827                    case PPC_63_FDIV:
3828                    case PPC_63_FSUB:
3829                    case PPC_63_FADD:
3830                            switch (xo & 31) {
3831                            case PPC_63_FDIV: ic->f = instr(fdiv); break;
3832                            case PPC_63_FSUB: ic->f = instr(fsub); break;
3833                            case PPC_63_FADD: ic->f = instr(fadd); break;
3834                            }
3835                            ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[ra]);
3836                            ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[rb]);
3837                            ic->arg[2] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3838                            break;
3839                    case PPC_63_FMUL:
3840                            ic->f = instr(fmul);
3841                            ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3842                            ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[ra]);
3843                            ic->arg[2] = (size_t)(&cpu->cd.ppc.fpr[rs]); /* frc */
3844                            break;
3845                    case PPC_63_FMSUB:
3846                    case PPC_63_FMADD:
3847                            switch (xo & 31) {
3848                            case PPC_63_FMSUB: ic->f = instr(fmsub); break;
3849                            case PPC_63_FMADD: ic->f = instr(fmadd); break;
3850                            }
3851                            ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3852                            ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[ra]);
3853                            ic->arg[2] = iword;
3854                            break;
3855                    default:/*  Use all 10 bits of xo:  */
3856                            switch (xo) {
3857                            case PPC_63_FCMPU:
3858                                    ic->f = instr(fcmpu);
3859                                    ic->arg[0] = 28 - 4*(rt >> 2);
3860                                    ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[ra]);
3861                                    ic->arg[2] = (size_t)(&cpu->cd.ppc.fpr[rb]);
3862                                    break;
3863                            case PPC_63_FRSP:
3864                            case PPC_63_FCTIWZ:
3865                            case PPC_63_FNEG:
3866                            case PPC_63_FMR:
3867                                    switch (xo) {
3868                                    case PPC_63_FRSP:   ic->f = instr(frsp); break;
3869                                    case PPC_63_FCTIWZ: ic->f = instr(fctiwz);break;
3870                                    case PPC_63_FNEG:   ic->f = instr(fneg); break;
3871                                    case PPC_63_FMR:    ic->f = instr(fmr); break;
3872                                    }
3873                                    ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rb]);
3874                                    ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3875                                    break;
3876                            case PPC_63_MFFS:
3877                                    ic->f = instr(mffs);
3878                                    ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3879                                    break;
3880                            case PPC_63_MTFSF:
3881                                    ic->f = instr(mtfsf);
3882                                    ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rb]);
3883                                    ic->arg[1] = 0;
3884                                    for (bi=7; bi>=0; bi--) {
3885                                            ic->arg[1] <<= 8;
3886                                            if (iword & (1 << (17+bi)))
3887                                                    ic->arg[1] |= 0xf;
3888                                    }
3889                                    break;
3890                            default:goto bad;
3891                            }
3892                  }                  }
3893                  break;                  break;
3894    

Legend:
Removed from v.14  
changed lines
  Added in v.44

  ViewVC Help
Powered by ViewVC 1.1.26