/[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 34 by dpavlin, Mon Oct 8 16:21:17 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.73 2007/02/17 10:06:19 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]  /*,bh = ic->arg[2]*/;
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:  */
  *  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;  
2454  #ifdef MODE32  #ifdef MODE32
2455          uint32_t addr;          ppc32_loadstore
2456  #else  #else
2457          uint64_t addr;          ppc_loadstore
2458          fatal("byte_fill_loop: not for 64-bit mode yet\n");  #endif
2459          exit(1);              [3 + 4](cpu, ic);
2460    }
2461    X(stfdx)
2462    {
2463            CHECK_FOR_FPU_EXCEPTION;
2464    
2465            /*  Perform a 64-bit store:  */
2466    #ifdef MODE32
2467            ppc32_loadstore_indexed
2468    #else
2469            ppc_loadstore_indexed
2470  #endif  #endif
2471                [3 + 4](cpu, ic);
2472    }
2473    
2474    
2475    /*
2476     *  lvx, stvx:  Vector (16-byte) load/store  (slow implementation)
2477     *
2478     *  arg[0] = v-register nr of rs
2479     *  arg[1] = pointer to ra
2480     *  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  restart_loop:          if (cpu->memory_rw(cpu, cpu->mem, addr, data, sizeof(data),
2490          addr = reg(z);              MEM_READ, CACHE_DATA) != MEMORY_ACCESS_OK) {
2491          /*  TODO: This only work with 32-bit addressing:  */                  /*  exception  */
         page = cpu->cd.ppc.host_store[addr >> 12];  
         if (page == NULL) {  
                 instr(cmpwi)(cpu, ic);  
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    X(tlbsx_dot)
2632    {
2633            /*  TODO  */
2634            cpu->cd.ppc.cr &= ~(0xf0000000);
2635            cpu->cd.ppc.cr |= 0x20000000;
2636            cpu->cd.ppc.cr |= ((cpu->cd.ppc.spr[SPR_XER] >> 3) & 0x10000000);
2637    }
2638    
2639    
2640    /*
2641     *  tlbli:
2642   */   */
2643  void COMBINE_INSTRUCTIONS(struct cpu *cpu, struct ppc_instr_call *ic,  X(tlbli)
         uint32_t addr)  
2644  {  {
2645          int n_back;          fatal("tlbli\n");
2646          n_back = (addr >> PPC_INSTR_ALIGNMENT_SHIFT)          cpu->invalidate_translation_caches(cpu, 0, INVALIDATE_ALL);
2647              & (PPC_IC_ENTRIES_PER_PAGE-1);  }
2648    
         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 &&  
2649    
2650                      ic[-3].f == instr(stb_0) &&  /*
2651                      ic[-3].arg[1] == ic[-1].arg[0] && ic[-3].arg[2] == 0 &&   *  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[-2].f == instr(addi) &&          fatal("tlbld\n");
2659                      ic[-2].arg[0] == ic[-2].arg[2] && ic[-2].arg[1] == -1 &&          cpu->invalidate_translation_caches(cpu, 0, INVALIDATE_ALL);
2660    }
2661    
                     ic[-1].f == instr(addi) &&  
                     ic[-1].arg[0] == ic[-1].arg[2] && ic[-1].arg[1] ==  1 &&  
2662    
2663                      ic[0].f == instr(bc_samepage) &&  /*****************************************************************************/
2664                      ic[0].arg[0] == (size_t)&ic[-4] &&  
2665                      ic[0].arg[1] == 12 && ic[0].arg[2] == 4*ic[-4].arg[2] + 1) {  
2666                          ic[-4].f = instr(byte_fill_loop);  X(end_of_page)
2667                          combined;  {
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                            fatal("[ TODO: Unimplemented ALTIVEC, iword"
2770                                " = 0x%08"PRIx32"x ]\n", iword);
2771                            goto bad;
2772                    }
2773                    break;
2774    
2775          case PPC_HI6_MULLI:          case PPC_HI6_MULLI:
2776                  rt = (iword >> 21) & 31;                  rt = (iword >> 21) & 31;
2777                  ra = (iword >> 16) & 31;                  ra = (iword >> 16) & 31;
# Line 1806  X(to_be_translated) Line 2807  X(to_be_translated)
2807                          imm = (int16_t)(iword & 0xffff);                          imm = (int16_t)(iword & 0xffff);
2808                          if (l_bit)                          if (l_bit)
2809                                  ic->f = instr(cmpdi);                                  ic->f = instr(cmpdi);
2810                          else                          else {
2811                                  ic->f = instr(cmpwi);                                  if (bf == 0)
2812                                            ic->f = instr(cmpwi_cr0);
2813                                    else
2814                                            ic->f = instr(cmpwi);
2815                            }
2816                  }                  }
2817                  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);                  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2818                  ic->arg[1] = (ssize_t)imm;                  ic->arg[1] = (ssize_t)imm;
2819                  ic->arg[2] = bf;                  ic->arg[2] = 28 - 4 * bf;
2820                  break;                  break;
2821    
2822          case PPC_HI6_ADDIC:          case PPC_HI6_ADDIC:
# Line 1828  X(to_be_translated) Line 2833  X(to_be_translated)
2833                  else                  else
2834                          ic->f = instr(addic_dot);                          ic->f = instr(addic_dot);
2835                  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);                  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2836                  ic->arg[1] = (ssize_t)imm;                  ic->arg[1] = imm;
2837                  ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);                  ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);
2838                  break;                  break;
2839    
# Line 1837  X(to_be_translated) Line 2842  X(to_be_translated)
2842                  rt = (iword >> 21) & 31; ra = (iword >> 16) & 31;                  rt = (iword >> 21) & 31; ra = (iword >> 16) & 31;
2843                  ic->f = instr(addi);                  ic->f = instr(addi);
2844                  if (ra == 0)                  if (ra == 0)
2845                          ic->arg[0] = (size_t)(&cpu->cd.ppc.zero);                          ic->f = instr(li);
2846                  else                  else
2847                          ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);                          ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2848                  ic->arg[1] = (ssize_t)(int16_t)(iword & 0xffff);                  ic->arg[1] = (int16_t)(iword & 0xffff);
2849                  if (main_opcode == PPC_HI6_ADDIS)                  if (main_opcode == PPC_HI6_ADDIS)
2850                          ic->arg[1] <<= 16;                          ic->arg[1] <<= 16;
2851                    if (ra == 0 && ic->arg[1] == 0)
2852                            ic->f = instr(li_0);
2853                  ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);                  ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);
2854                  break;                  break;
2855    
# Line 1879  X(to_be_translated) Line 2886  X(to_be_translated)
2886          case PPC_HI6_LBZU:          case PPC_HI6_LBZU:
2887          case PPC_HI6_LHZ:          case PPC_HI6_LHZ:
2888          case PPC_HI6_LHZU:          case PPC_HI6_LHZU:
2889            case PPC_HI6_LHA:
2890            case PPC_HI6_LHAU:
2891          case PPC_HI6_LWZ:          case PPC_HI6_LWZ:
2892          case PPC_HI6_LWZU:          case PPC_HI6_LWZU:
2893            case PPC_HI6_LD:
2894          case PPC_HI6_LFD:          case PPC_HI6_LFD:
2895            case PPC_HI6_LFS:
2896          case PPC_HI6_STB:          case PPC_HI6_STB:
2897          case PPC_HI6_STBU:          case PPC_HI6_STBU:
2898          case PPC_HI6_STH:          case PPC_HI6_STH:
2899          case PPC_HI6_STHU:          case PPC_HI6_STHU:
2900          case PPC_HI6_STW:          case PPC_HI6_STW:
2901          case PPC_HI6_STWU:          case PPC_HI6_STWU:
2902            case PPC_HI6_STD:
2903            case PPC_HI6_STFD:
2904            case PPC_HI6_STFS:
2905                  rs = (iword >> 21) & 31;                  rs = (iword >> 21) & 31;
2906                  ra = (iword >> 16) & 31;                  ra = (iword >> 16) & 31;
2907                  imm = (int16_t)(iword & 0xffff);                  imm = (int16_t)iword;
2908                  load = 0; zero = 1; size = 0; update = 0; fp = 0;                  load = 0; zero = 1; size = 0; update = 0; fp = 0;
2909                    ic->f = NULL;
2910                  switch (main_opcode) {                  switch (main_opcode) {
2911                  case PPC_HI6_LBZ:  load = 1; break;                  case PPC_HI6_LBZ:  load=1; break;
2912                  case PPC_HI6_LBZU: load = 1; update = 1; break;                  case PPC_HI6_LBZU: load=1; update=1; break;
2913                  case PPC_HI6_LHZ:  load = 1; size = 1; break;                  case PPC_HI6_LHA:  load=1; size=1; zero=0; break;
2914                  case PPC_HI6_LHZU: load = 1; size = 1; update = 1; break;                  case PPC_HI6_LHAU: load=1; size=1; zero=0; update=1; break;
2915                  case PPC_HI6_LWZ:  load = 1; size = 2; break;                  case PPC_HI6_LHZ:  load=1; size=1; break;
2916                  case PPC_HI6_LWZU: load = 1; size = 2; update = 1; break;                  case PPC_HI6_LHZU: load=1; size=1; update=1; break;
2917                  case PPC_HI6_LFD:  load = 1; size = 3; fp = 1; break;                  case PPC_HI6_LWZ:  load=1; size=2; break;
2918                    case PPC_HI6_LWZU: load=1; size=2; update=1; break;
2919                    case PPC_HI6_LD:   load=1; size=3; break;
2920                    case PPC_HI6_LFD:  load=1; size=3; fp=1;ic->f=instr(lfd);break;
2921                    case PPC_HI6_LFS:  load=1; size=2; fp=1;ic->f=instr(lfs);break;
2922                  case PPC_HI6_STB:  break;                  case PPC_HI6_STB:  break;
2923                  case PPC_HI6_STBU: update = 1; break;                  case PPC_HI6_STBU: update=1; break;
2924                  case PPC_HI6_STH:  size = 1; break;                  case PPC_HI6_STH:  size=1; break;
2925                  case PPC_HI6_STHU: size = 1; update = 1; break;                  case PPC_HI6_STHU: size=1; update=1; break;
2926                  case PPC_HI6_STW:  size = 2; break;                  case PPC_HI6_STW:  size=2; break;
2927                  case PPC_HI6_STWU: size = 2; update = 1; break;                  case PPC_HI6_STWU: size=2; update=1; break;
2928                  }                  case PPC_HI6_STD:  size=3; break;
2929                  if (fp) {                  case PPC_HI6_STFD: size=3; fp=1; ic->f = instr(stfd); break;
2930                          /*  Floating point:  */                  case PPC_HI6_STFS: size=2; fp=1; ic->f = instr(stfs); break;
2931                          if (load && size == 3) {                  }
2932                                  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:  */  
2933                          ic->f =                          ic->f =
2934  #ifdef MODE32  #ifdef MODE32
2935                              ppc32_loadstore                              ppc32_loadstore
# Line 1949  X(to_be_translated) Line 2960  X(to_be_translated)
2960                  bo = (iword >> 21) & 31;                  bo = (iword >> 21) & 31;
2961                  bi = (iword >> 16) & 31;                  bi = (iword >> 16) & 31;
2962                  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;  
                 }  
2963                  if (aa_bit) {                  if (aa_bit) {
2964                          fatal("aa_bit: NOT YET\n");                          fatal("aa_bit: NOT YET\n");
2965                          goto bad;                          goto bad;
2966                  }                  }
2967                  ic->f = instr(bc);                  if (lk_bit) {
2968                  samepage_function = instr(bc_samepage);                          ic->f = instr(bcl);
2969                  ic->arg[0] = (ssize_t)tmp_addr;                          samepage_function = instr(bcl_samepage);
2970                    } else {
2971                            ic->f = instr(bc);
2972                            if ((bo & 0x14) == 0x04) {
2973                                    samepage_function = bo & 8?
2974                                        instr(bc_samepage_simple1) :
2975                                        instr(bc_samepage_simple0);
2976                            } else
2977                                    samepage_function = instr(bc_samepage);
2978                    }
2979                    ic->arg[0] = (ssize_t)(tmp_addr + (addr & 0xffc));
2980                  ic->arg[1] = bo;                  ic->arg[1] = bo;
2981                  ic->arg[2] = bi;                  ic->arg[2] = 31-bi;
2982                  /*  Branches are calculated as cur PC + offset.  */                  /*  Branches are calculated as cur PC + offset.  */
2983                  /*  Special case: branch within the same page:  */                  /*  Special case: branch within the same page:  */
2984                  {                  {
2985                          uint64_t mask_within_page =                          uint64_t mask_within_page =
2986                              ((PPC_IC_ENTRIES_PER_PAGE-1) << 2) | 3;                              ((PPC_IC_ENTRIES_PER_PAGE-1) << 2) | 3;
2987                          uint64_t old_pc = addr;                          uint64_t old_pc = addr;
2988                          uint64_t new_pc = old_pc + (int32_t)ic->arg[0];                          uint64_t new_pc = old_pc + (int32_t)tmp_addr;
2989                          if ((old_pc & ~mask_within_page) ==                          if ((old_pc & ~mask_within_page) ==
2990                              (new_pc & ~mask_within_page)) {                              (new_pc & ~mask_within_page)) {
2991                                  ic->f = samepage_function;                                  ic->f = samepage_function;
# Line 1981  X(to_be_translated) Line 2998  X(to_be_translated)
2998    
2999          case PPC_HI6_SC:          case PPC_HI6_SC:
3000                  ic->arg[0] = (iword >> 5) & 0x7f;                  ic->arg[0] = (iword >> 5) & 0x7f;
3001                    ic->arg[1] = (addr & 0xfff) + 4;
3002                  if (cpu->machine->userland_emul != NULL)                  if (cpu->machine->userland_emul != NULL)
3003                          ic->f = instr(user_syscall);                          ic->f = instr(user_syscall);
3004                  else {                  else if (iword == 0x44ee0002) {
3005                          /*  Special case/magic hack for OpenFirmware emul:  */                          /*  Special case/magic hack for OpenFirmware emul:  */
3006                          if (iword == 0x44ee0002) {                          ic->f = instr(openfirmware);
3007                                  ic->f = instr(openfirmware);                  } else
3008                                  break;                          ic->f = instr(sc);
                         }  
                         fatal("PPC non-userland SYSCALL: TODO\n");  
                         goto bad;  
                 }  
3009                  break;                  break;
3010    
3011          case PPC_HI6_B:          case PPC_HI6_B:
3012                  aa_bit = (iword & 2) >> 1;                  aa_bit = (iword & 2) >> 1;
3013                  lk_bit = iword & 1;                  lk_bit = iword & 1;
                 if (aa_bit) {  
                         fatal("aa_bit: NOT YET\n");  
                         goto bad;  
                 }  
3014                  tmp_addr = (int64_t)(int32_t)((iword & 0x03fffffc) << 6);                  tmp_addr = (int64_t)(int32_t)((iword & 0x03fffffc) << 6);
3015                  tmp_addr = (int64_t)tmp_addr >> 6;                  tmp_addr = (int64_t)tmp_addr >> 6;
3016                  if (lk_bit) {                  if (lk_bit) {
# Line 2015  X(to_be_translated) Line 3025  X(to_be_translated)
3025                          ic->f = instr(b);                          ic->f = instr(b);
3026                          samepage_function = instr(b_samepage);                          samepage_function = instr(b_samepage);
3027                  }                  }
3028                  ic->arg[0] = (ssize_t)tmp_addr;                  ic->arg[0] = (ssize_t)(tmp_addr + (addr & 0xffc));
3029                    ic->arg[1] = (addr & 0xffc) + 4;
3030                  /*  Branches are calculated as cur PC + offset.  */                  /*  Branches are calculated as cur PC + offset.  */
3031                  /*  Special case: branch within the same page:  */                  /*  Special case: branch within the same page:  */
3032                  {                  {
3033                          uint64_t mask_within_page =                          uint64_t mask_within_page =
3034                              ((PPC_IC_ENTRIES_PER_PAGE-1) << 2) | 3;                              ((PPC_IC_ENTRIES_PER_PAGE-1) << 2) | 3;
3035                          uint64_t old_pc = addr;                          uint64_t old_pc = addr;
3036                          uint64_t new_pc = old_pc + (int32_t)ic->arg[0];                          uint64_t new_pc = old_pc + (int32_t)tmp_addr;
3037                          if ((old_pc & ~mask_within_page) ==                          if ((old_pc & ~mask_within_page) ==
3038                              (new_pc & ~mask_within_page)) {                              (new_pc & ~mask_within_page)) {
3039                                  ic->f = samepage_function;                                  ic->f = samepage_function;
# Line 2031  X(to_be_translated) Line 3042  X(to_be_translated)
3042                                      ((new_pc & mask_within_page) >> 2));                                      ((new_pc & mask_within_page) >> 2));
3043                          }                          }
3044                  }                  }
3045                    if (aa_bit) {
3046                            if (lk_bit) {
3047                                    if (cpu->machine->show_trace_tree) {
3048                                            ic->f = instr(bla_trace);
3049                                    } else {
3050                                            ic->f = instr(bla);
3051                                    }
3052                            } else {
3053                                    ic->f = instr(ba);
3054                            }
3055                            ic->arg[0] = (ssize_t)tmp_addr;
3056                    }
3057                  break;                  break;
3058    
3059          case PPC_HI6_19:          case PPC_HI6_19:
# Line 2046  X(to_be_translated) Line 3069  X(to_be_translated)
3069                          if (xo == PPC_19_BCLR) {                          if (xo == PPC_19_BCLR) {
3070                                  if (lk_bit)                                  if (lk_bit)
3071                                          ic->f = instr(bclr_l);                                          ic->f = instr(bclr_l);
3072                                  else                                  else {
3073                                          ic->f = instr(bclr);                                          ic->f = instr(bclr);
3074                                            if (!cpu->machine->show_trace_tree &&
3075                                                (bo & 0x14) == 0x14)
3076                                                    ic->f = instr(bclr_20);
3077                                    }
3078                          } else {                          } else {
3079                                  if (lk_bit)                                  if (lk_bit)
3080                                          ic->f = instr(bcctr_l);                                          ic->f = instr(bcctr_l);
# Line 2055  X(to_be_translated) Line 3082  X(to_be_translated)
3082                                          ic->f = instr(bcctr);                                          ic->f = instr(bcctr);
3083                          }                          }
3084                          ic->arg[0] = bo;                          ic->arg[0] = bo;
3085                          ic->arg[1] = bi;                          ic->arg[1] = 31 - bi;
3086                          ic->arg[2] = bh;                          ic->arg[2] = bh;
3087                          break;                          break;
3088    
# Line 2068  X(to_be_translated) Line 3095  X(to_be_translated)
3095                          ic->f = instr(rfi);                          ic->f = instr(rfi);
3096                          break;                          break;
3097    
3098                    case PPC_19_RFID:
3099                            ic->f = instr(rfid);
3100                            break;
3101    
3102                  case PPC_19_MCRF:                  case PPC_19_MCRF:
3103                          bf = (iword >> 23) & 7;                          bf = (iword >> 23) & 7;
3104                          bfa = (iword >> 18) & 7;                          bfa = (iword >> 18) & 7;
3105                          ic->arg[0] = bf;                          ic->arg[0] = 28 - 4*bf;
3106                          ic->arg[1] = bfa;                          ic->arg[1] = 28 - 4*bfa;
3107                          ic->f = instr(mcrf);                          ic->f = instr(mcrf);
3108                          break;                          break;
3109    
# Line 2080  X(to_be_translated) Line 3111  X(to_be_translated)
3111                  case PPC_19_CRANDC:                  case PPC_19_CRANDC:
3112                  case PPC_19_CREQV:                  case PPC_19_CREQV:
3113                  case PPC_19_CROR:                  case PPC_19_CROR:
3114                    case PPC_19_CRORC:
3115                    case PPC_19_CRNOR:
3116                  case PPC_19_CRXOR:                  case PPC_19_CRXOR:
3117                          switch (xo) {                          switch (xo) {
3118                          case PPC_19_CRAND:  ic->f = instr(crand); break;                          case PPC_19_CRAND:  ic->f = instr(crand); break;
3119                          case PPC_19_CRANDC: ic->f = instr(crandc); break;                          case PPC_19_CRANDC: ic->f = instr(crandc); break;
3120                          case PPC_19_CREQV:  ic->f = instr(creqv); break;                          case PPC_19_CREQV:  ic->f = instr(creqv); break;
3121                          case PPC_19_CROR:   ic->f = instr(cror); break;                          case PPC_19_CROR:   ic->f = instr(cror); break;
3122                            case PPC_19_CRORC:  ic->f = instr(crorc); break;
3123                            case PPC_19_CRNOR:  ic->f = instr(crnor); break;
3124                          case PPC_19_CRXOR:  ic->f = instr(crxor); break;                          case PPC_19_CRXOR:  ic->f = instr(crxor); break;
3125                          }                          }
3126                          ic->arg[0] = iword;                          ic->arg[0] = iword;
# Line 2095  X(to_be_translated) Line 3130  X(to_be_translated)
3130                  }                  }
3131                  break;                  break;
3132    
3133          case PPC_HI6_RLWIMI:          case PPC_HI6_RLWNM:
3134          case PPC_HI6_RLWINM:          case PPC_HI6_RLWINM:
3135                    ra = (iword >> 16) & 31;
3136                    mb = (iword >> 6) & 31;
3137                    me = (iword >> 1) & 31;  
3138                    rc = iword & 1;
3139                    mask = 0;
3140                    for (;;) {
3141                            mask |= ((uint32_t)0x80000000 >> mb);
3142                            if (mb == me)
3143                                    break;
3144                            mb ++; mb &= 31;
3145                    }
3146                    switch (main_opcode) {
3147                    case PPC_HI6_RLWNM:
3148                            ic->f = rc? instr(rlwnm_dot) : instr(rlwnm); break;
3149                    case PPC_HI6_RLWINM:
3150                            ic->f = rc? instr(rlwinm_dot) : instr(rlwinm); break;
3151                    }
3152                    ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3153                    ic->arg[1] = mask;
3154                    ic->arg[2] = (uint32_t)iword;
3155                    break;
3156    
3157            case PPC_HI6_RLWIMI:
3158                  rs = (iword >> 21) & 31;                  rs = (iword >> 21) & 31;
3159                  ra = (iword >> 16) & 31;                  ra = (iword >> 16) & 31;
3160                  if (main_opcode == PPC_HI6_RLWIMI)                  ic->f = instr(rlwimi);
                         ic->f = instr(rlwimi);  
                 else  
                         ic->f = instr(rlwinm);  
3161                  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);                  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
3162                  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);                  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3163                  ic->arg[2] = (uint32_t)iword;                  ic->arg[2] = (uint32_t)iword;
# Line 2133  X(to_be_translated) Line 3188  X(to_be_translated)
3188                  xo = (iword >> 2) & 7;                  xo = (iword >> 2) & 7;
3189                  switch (xo) {                  switch (xo) {
3190    
3191                    case PPC_30_RLDICL:
3192                  case PPC_30_RLDICR:                  case PPC_30_RLDICR:
3193                          ic->f = instr(rldicr);                  case PPC_30_RLDIMI:
3194                            switch (xo) {
3195                            case PPC_30_RLDICL: ic->f = instr(rldicl); break;
3196                            case PPC_30_RLDICR: ic->f = instr(rldicr); break;
3197                            case PPC_30_RLDIMI: ic->f = instr(rldimi); break;
3198                            }
3199                          ic->arg[0] = iword;                          ic->arg[0] = iword;
3200                          if (cpu->cd.ppc.bits == 32) {                          if (cpu->cd.ppc.bits == 32) {
3201                                  fatal("TODO: rldicr in 32-bit mode?\n");                                  fatal("TODO: rld* in 32-bit mode?\n");
3202                                  goto bad;                                  goto bad;
3203                          }                          }
3204                          break;                          break;
# Line 2164  X(to_be_translated) Line 3225  X(to_be_translated)
3225                          } else {                          } else {
3226                                  if (l_bit)                                  if (l_bit)
3227                                          ic->f = instr(cmpd);                                          ic->f = instr(cmpd);
3228                                  else                                  else {
3229                                          ic->f = instr(cmpw);                                          if (bf == 0)
3230                                                    ic->f = instr(cmpw_cr0);
3231                                            else
3232                                                    ic->f = instr(cmpw);
3233                                    }
3234                          }                          }
3235                          ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);                          ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3236                          ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rb]);                          ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3237                          ic->arg[2] = bf;                          ic->arg[2] = 28 - 4*bf;
3238                          break;                          break;
3239    
3240                  case PPC_31_CNTLZW:                  case PPC_31_CNTLZW:
# Line 2188  X(to_be_translated) Line 3253  X(to_be_translated)
3253                  case PPC_31_MFSPR:                  case PPC_31_MFSPR:
3254                          rt = (iword >> 21) & 31;                          rt = (iword >> 21) & 31;
3255                          spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);                          spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
3256                            debug_spr_usage(cpu->pc, spr);
3257                          ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rt]);                          ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rt]);
3258                            ic->arg[1] = (size_t)(&cpu->cd.ppc.spr[spr]);
3259                          switch (spr) {                          switch (spr) {
3260                          case 8:   ic->f = instr(mflr); break;                          case SPR_PMC1:  ic->f = instr(mfspr_pmc1); break;
3261                          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;  
                                 }  
3262                          }                          }
3263                          break;                          break;
3264    
3265                  case PPC_31_MTSPR:                  case PPC_31_MTSPR:
3266                          rs = (iword >> 21) & 31;                          rs = (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[rs]);                          ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
3270                            ic->arg[1] = (size_t)(&cpu->cd.ppc.spr[spr]);
3271                          switch (spr) {                          switch (spr) {
3272                          case 8:   ic->f = instr(mtlr); break;                          case SPR_LR:
3273                          case 9:   ic->f = instr(mtctr); break;                                  ic->f = instr(mtlr);
3274                          case 25:  ic->f = instr(mtsdr1); break;                                  break;
3275                          case 26:  ic->f = instr(mtsrr0); break;                          case SPR_CTR:
3276                          case 27:  ic->f = instr(mtsrr1); break;                                  ic->f = instr(mtctr);
3277                          case 272: ic->f = instr(mtsprg0); break;                                  break;
3278                          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;  
                                 }  
3279                          }                          }
3280                          break;                          break;
3281    
# Line 2271  X(to_be_translated) Line 3292  X(to_be_translated)
3292                          break;                          break;
3293    
3294                  case PPC_31_MTMSR:                  case PPC_31_MTMSR:
3295                    case PPC_31_MTMSRD:
3296                          rs = (iword >> 21) & 31;                          rs = (iword >> 21) & 31;
3297                          l_bit = (iword >> 16) & 1;                          l_bit = (iword >> 16) & 1;
3298                          if (l_bit) {                          if (l_bit) {
# Line 2278  X(to_be_translated) Line 3300  X(to_be_translated)
3300                                  goto bad;                                  goto bad;
3301                          }                          }
3302                          ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);                          ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
3303                            ic->arg[1] = (addr & 0xfff) + 4;
3304                            ic->arg[2] = xo == PPC_31_MTMSRD;
3305                          ic->f = instr(mtmsr);                          ic->f = instr(mtmsr);
3306                          break;                          break;
3307    
# Line 2313  X(to_be_translated) Line 3337  X(to_be_translated)
3337                          }                          }
3338                          break;                          break;
3339    
3340                    case PPC_31_MFSR:
3341                  case PPC_31_MTSR:                  case PPC_31_MTSR:
3342                          rt = (iword >> 21) & 31;                          rt = (iword >> 21) & 31;
3343                          ic->arg[0] = (iword >> 16) & 15;                          ic->arg[0] = (iword >> 16) & 15;
3344                          ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rt]);                          ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rt]);
3345                          ic->f = instr(mtsr);                          switch (xo) {
3346                            case PPC_31_MFSR:   ic->f = instr(mfsr); break;
3347                            case PPC_31_MTSR:   ic->f = instr(mtsr); break;
3348                            }
3349                          if (cpu->cd.ppc.bits == 64) {                          if (cpu->cd.ppc.bits == 64) {
3350                                  fatal("Not yet for 64-bit mode\n");                                  fatal("Not yet for 64-bit mode\n");
3351                                  goto bad;                                  goto bad;
# Line 2339  X(to_be_translated) Line 3367  X(to_be_translated)
3367                          break;                          break;
3368    
3369                  case PPC_31_SYNC:                  case PPC_31_SYNC:
3370                  case PPC_31_TLBSYNC:                  case PPC_31_DSSALL:
3371                  case PPC_31_EIEIO:                  case PPC_31_EIEIO:
3372                  case PPC_31_DCBST:                  case PPC_31_DCBST:
3373                  case PPC_31_DCBTST:                  case PPC_31_DCBTST:
3374                  case PPC_31_DCBF:                  case PPC_31_DCBF:
3375                  case PPC_31_DCBT:                  case PPC_31_DCBT:
3376                  case PPC_31_ICBI:                  case PPC_31_ICBI:
                         /*  TODO  */  
3377                          ic->f = instr(nop);                          ic->f = instr(nop);
3378                          break;                          break;
3379    
# Line 2358  X(to_be_translated) Line 3385  X(to_be_translated)
3385                          else                          else
3386                                  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);                                  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3387                          ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rb]);                          ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3388                            ic->arg[2] = addr & 0xfff;
3389                          ic->f = instr(dcbz);                          ic->f = instr(dcbz);
3390                          break;                          break;
3391    
3392                    case PPC_31_TLBIA:
3393                            ic->f = instr(tlbia);
3394                            break;
3395    
3396                    case PPC_31_TLBSYNC:
3397                            /*  According to IBM, "Ensures that a tlbie and
3398                                tlbia instruction executed by one processor has
3399                                completed on all other processors.", which in
3400                                GXemul means a nop :-)  */
3401                            ic->f = instr(nop);
3402                            break;
3403    
3404                  case PPC_31_TLBIE:                  case PPC_31_TLBIE:
3405                          /*  TODO  */                          /*  TODO: POWER also uses ra?  */
3406                            rb = (iword >> 11) & 31;
3407                            ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3408                          ic->f = instr(tlbie);                          ic->f = instr(tlbie);
3409                          break;                          break;
3410    
3411                    case PPC_31_TLBLD:      /*  takes an arg  */
3412                            rb = (iword >> 11) & 31;
3413                            ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3414                            ic->f = instr(tlbld);
3415                            break;
3416    
3417                    case PPC_31_TLBLI:      /*  takes an arg  */
3418                            rb = (iword >> 11) & 31;
3419                            ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3420                            ic->f = instr(tlbli);
3421                            break;
3422    
3423                    case PPC_31_TLBSX_DOT:
3424                            /*  TODO  */
3425                            ic->f = instr(tlbsx_dot);
3426                            break;
3427    
3428                  case PPC_31_MFTB:                  case PPC_31_MFTB:
3429                          rt = (iword >> 21) & 31;                          rt = (iword >> 21) & 31;
3430                          spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);                          spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
# Line 2398  X(to_be_translated) Line 3457  X(to_be_translated)
3457                          ic->f = instr(llsc);                          ic->f = instr(llsc);
3458                          break;                          break;
3459    
3460                    case PPC_31_LSWI:
3461                    case PPC_31_STSWI:
3462                            rs = (iword >> 21) & 31;
3463                            ra = (iword >> 16) & 31;
3464                            nb = (iword >> 11) & 31;
3465                            ic->arg[0] = rs;
3466                            if (ra == 0)
3467                                    ic->arg[1] = (size_t)(&cpu->cd.ppc.zero);
3468                            else
3469                                    ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3470                            ic->arg[2] = nb == 0? 32 : nb;
3471                            switch (xo) {
3472                            case PPC_31_LSWI:  ic->f = instr(lswi); break;
3473                            case PPC_31_STSWI: ic->f = instr(stswi); break;
3474                            }
3475                            break;
3476    
3477                    case PPC_31_WRTEEI:
3478                            ic->arg[0] = iword & 0x8000;
3479                            ic->f = instr(wrteei);
3480                            break;
3481    
3482                    case 0x1c3:
3483                            fatal("[ mtdcr: TODO ]\n");
3484                            ic->f = instr(nop);
3485                            break;
3486    
3487                  case PPC_31_LBZX:                  case PPC_31_LBZX:
3488                  case PPC_31_LBZUX:                  case PPC_31_LBZUX:
3489                    case PPC_31_LHAX:
3490                    case PPC_31_LHAUX:
3491                  case PPC_31_LHZX:                  case PPC_31_LHZX:
3492                  case PPC_31_LHZUX:                  case PPC_31_LHZUX:
3493                  case PPC_31_LWZX:                  case PPC_31_LWZX:
3494                  case PPC_31_LWZUX:                  case PPC_31_LWZUX:
3495                    case PPC_31_LHBRX:
3496                    case PPC_31_LWBRX:
3497                    case PPC_31_LFDX:
3498                    case PPC_31_LFSX:
3499                  case PPC_31_STBX:                  case PPC_31_STBX:
3500                  case PPC_31_STBUX:                  case PPC_31_STBUX:
3501                  case PPC_31_STHX:                  case PPC_31_STHX:
# Line 2412  X(to_be_translated) Line 3504  X(to_be_translated)
3504                  case PPC_31_STWUX:                  case PPC_31_STWUX:
3505                  case PPC_31_STDX:                  case PPC_31_STDX:
3506                  case PPC_31_STDUX:                  case PPC_31_STDUX:
3507                    case PPC_31_STHBRX:
3508                    case PPC_31_STWBRX:
3509                    case PPC_31_STFDX:
3510                    case PPC_31_STFSX:
3511                          rs = (iword >> 21) & 31;                          rs = (iword >> 21) & 31;
3512                          ra = (iword >> 16) & 31;                          ra = (iword >> 16) & 31;
3513                          rb = (iword >> 11) & 31;                          rb = (iword >> 11) & 31;
                         ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);  
3514                          if (ra == 0)                          if (ra == 0)
3515                                  ic->arg[1] = (size_t)(&cpu->cd.ppc.zero);                                  ic->arg[1] = (size_t)(&cpu->cd.ppc.zero);
3516                          else                          else
3517                                  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);                                  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3518                          ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rb]);                          ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3519                          load = 0; zero = 1; size = 0; update = 0;                          load = 0; zero = 1; size = 0; update = 0;
3520                            byterev = 0; fp = 0;
3521                            ic->f = NULL;
3522                          switch (xo) {                          switch (xo) {
3523                          case PPC_31_LBZX:  load = 1; break;                          case PPC_31_LBZX:  load = 1; break;
3524                          case PPC_31_LBZUX: load = update = 1; break;                          case PPC_31_LBZUX: load=update=1; break;
3525                          case PPC_31_LHZX:  size = 1; load = 1; break;                          case PPC_31_LHAX:  size=1; load=1; zero=0; break;
3526                          case PPC_31_LHZUX: size = 1; load = update = 1; break;                          case PPC_31_LHAUX: size=1; load=update=1; zero=0; break;
3527                          case PPC_31_LWZX:  size = 2; load = 1; break;                          case PPC_31_LHZX:  size=1; load=1; break;
3528                          case PPC_31_LWZUX: size = 2; load = update = 1; break;                          case PPC_31_LHZUX: size=1; load=update = 1; break;
3529                            case PPC_31_LWZX:  size=2; load=1; break;
3530                            case PPC_31_LWZUX: size=2; load=update = 1; break;
3531                            case PPC_31_LHBRX: size=1; load=1; byterev=1;
3532                                               ic->f = instr(lhbrx); break;
3533                            case PPC_31_LWBRX: size=2; load=1; byterev=1;
3534                                               ic->f = instr(lwbrx); break;
3535                            case PPC_31_LFDX:  size=3; load=1; fp=1;
3536                                               ic->f = instr(lfdx); break;
3537                            case PPC_31_LFSX:  size=2; load=1; fp=1;
3538                                               ic->f = instr(lfsx); break;
3539                          case PPC_31_STBX:  break;                          case PPC_31_STBX:  break;
3540                          case PPC_31_STBUX: update = 1; break;                          case PPC_31_STBUX: update = 1; break;
3541                          case PPC_31_STHX:  size = 1; break;                          case PPC_31_STHX:  size=1; break;
3542                          case PPC_31_STHUX: size = 1; update = 1; break;                          case PPC_31_STHUX: size=1; update = 1; break;
3543                          case PPC_31_STWX:  size = 2; break;                          case PPC_31_STWX:  size=2; break;
3544                          case PPC_31_STWUX: size = 2; update = 1; break;                          case PPC_31_STWUX: size=2; update = 1; break;
3545                          case PPC_31_STDX:  size = 3; break;                          case PPC_31_STDX:  size=3; break;
3546                          case PPC_31_STDUX: size = 3; update = 1; break;                          case PPC_31_STDUX: size=3; update = 1; break;
3547                            case PPC_31_STHBRX:size=1; byterev = 1;
3548                                               ic->f = instr(sthbrx); break;
3549                            case PPC_31_STWBRX:size=2; byterev = 1;
3550                                               ic->f = instr(stwbrx); break;
3551                            case PPC_31_STFDX: size=3; fp=1;
3552                                               ic->f = instr(stfdx); break;
3553                            case PPC_31_STFSX: size=2; fp=1;
3554                                               ic->f = instr(stfsx); break;
3555                          }                          }
3556                          ic->f =                          if (fp)
3557                                    ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rs]);
3558                            else
3559                                    ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
3560                            if (!byterev && ic->f == NULL) {
3561                                    ic->f =
3562  #ifdef MODE32  #ifdef MODE32
3563                              ppc32_loadstore_indexed                                      ppc32_loadstore_indexed
3564  #else  #else
3565                              ppc_loadstore_indexed                                      ppc_loadstore_indexed
3566  #endif  #endif
3567                              [size + 4*zero + 8*load + 16*update];                                      [size + 4*zero + 8*load + 16*update];
3568                            }
3569                          if (ra == 0 && update) {                          if (ra == 0 && update) {
3570                                  fatal("TODO: ra=0 && update?\n");                                  fatal("TODO: ra=0 && update?\n");
3571                                  goto bad;                                  goto bad;
# Line 2455  X(to_be_translated) Line 3576  X(to_be_translated)
3576                  case PPC_31_EXTSH:                  case PPC_31_EXTSH:
3577                  case PPC_31_EXTSW:                  case PPC_31_EXTSW:
3578                  case PPC_31_SLW:                  case PPC_31_SLW:
3579                    case PPC_31_SLD:
3580                  case PPC_31_SRAW:                  case PPC_31_SRAW:
3581                  case PPC_31_SRW:                  case PPC_31_SRW:
3582                  case PPC_31_AND:                  case PPC_31_AND:
# Line 2464  X(to_be_translated) Line 3586  X(to_be_translated)
3586                  case PPC_31_OR:                  case PPC_31_OR:
3587                  case PPC_31_ORC:                  case PPC_31_ORC:
3588                  case PPC_31_XOR:                  case PPC_31_XOR:
3589                    case PPC_31_EQV:
3590                          rs = (iword >> 21) & 31;                          rs = (iword >> 21) & 31;
3591                          ra = (iword >> 16) & 31;                          ra = (iword >> 16) & 31;
3592                          rb = (iword >> 11) & 31;                          rb = (iword >> 11) & 31;
# Line 2478  X(to_be_translated) Line 3601  X(to_be_translated)
3601                                            rc_f  = instr(extsw_dot); break;                                            rc_f  = instr(extsw_dot); break;
3602                          case PPC_31_SLW:  ic->f = instr(slw);                          case PPC_31_SLW:  ic->f = instr(slw);
3603                                            rc_f  = instr(slw_dot); break;                                            rc_f  = instr(slw_dot); break;
3604                            case PPC_31_SLD:  ic->f = instr(sld);
3605                                              rc_f  = instr(sld_dot); break;
3606                          case PPC_31_SRAW: ic->f = instr(sraw);                          case PPC_31_SRAW: ic->f = instr(sraw);
3607                                            rc_f  = instr(sraw_dot); break;                                            rc_f  = instr(sraw_dot); break;
3608                          case PPC_31_SRW:  ic->f = instr(srw);                          case PPC_31_SRW:  ic->f = instr(srw);
# Line 2490  X(to_be_translated) Line 3615  X(to_be_translated)
3615                                            rc_f  = instr(andc_dot); break;                                            rc_f  = instr(andc_dot); break;
3616                          case PPC_31_NOR:  ic->f = instr(nor);                          case PPC_31_NOR:  ic->f = instr(nor);
3617                                            rc_f  = instr(nor_dot); break;                                            rc_f  = instr(nor_dot); break;
3618                          case PPC_31_OR:   ic->f = instr(or);                          case PPC_31_OR:   ic->f = rs == rb? instr(mr)
3619                                                    : instr(or);
3620                                            rc_f  = instr(or_dot); break;                                            rc_f  = instr(or_dot); break;
3621                          case PPC_31_ORC:  ic->f = instr(orc);                          case PPC_31_ORC:  ic->f = instr(orc);
3622                                            rc_f  = instr(orc_dot); break;                                            rc_f  = instr(orc_dot); break;
3623                          case PPC_31_XOR:  ic->f = instr(xor);                          case PPC_31_XOR:  ic->f = instr(xor);
3624                                            rc_f  = instr(xor_dot); break;                                            rc_f  = instr(xor_dot); break;
3625                            case PPC_31_EQV:  ic->f = instr(eqv);
3626                                              rc_f  = instr(eqv_dot); break;
3627                          }                          }
3628                          ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);                          ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
3629                          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 3645  X(to_be_translated)
3645                  case PPC_31_SUBF:                  case PPC_31_SUBF:
3646                  case PPC_31_SUBFC:                  case PPC_31_SUBFC:
3647                  case PPC_31_SUBFE:                  case PPC_31_SUBFE:
3648                    case PPC_31_SUBFME:
3649                  case PPC_31_SUBFZE:                  case PPC_31_SUBFZE:
3650                          rt = (iword >> 21) & 31;                          rt = (iword >> 21) & 31;
3651                          ra = (iword >> 16) & 31;                          ra = (iword >> 16) & 31;
# Line 2541  X(to_be_translated) Line 3670  X(to_be_translated)
3670                          case PPC_31_SUBF:   ic->f = instr(subf); break;                          case PPC_31_SUBF:   ic->f = instr(subf); break;
3671                          case PPC_31_SUBFC:  ic->f = instr(subfc); break;                          case PPC_31_SUBFC:  ic->f = instr(subfc); break;
3672                          case PPC_31_SUBFE:  ic->f = instr(subfe); n64=1; break;                          case PPC_31_SUBFE:  ic->f = instr(subfe); n64=1; break;
3673                            case PPC_31_SUBFME: ic->f = instr(subfme); n64=1; break;
3674                          case PPC_31_SUBFZE: ic->f = instr(subfze); n64=1;break;                          case PPC_31_SUBFZE: ic->f = instr(subfze); n64=1;break;
3675                          }                          }
3676                          if (rc) {                          if (rc) {
# Line 2553  X(to_be_translated) Line 3683  X(to_be_translated)
3683                                          ic->f = instr(addme_dot); break;                                          ic->f = instr(addme_dot); break;
3684                                  case PPC_31_ADDZE:                                  case PPC_31_ADDZE:
3685                                          ic->f = instr(addze_dot); break;                                          ic->f = instr(addze_dot); break;
3686                                    case PPC_31_DIVW:
3687                                            ic->f = instr(divw_dot); break;
3688                                    case PPC_31_DIVWU:
3689                                            ic->f = instr(divwu_dot); break;
3690                                    case PPC_31_MULLW:
3691                                            ic->f = instr(mullw_dot); break;
3692                                    case PPC_31_MULHW:
3693                                            ic->f = instr(mulhw_dot); break;
3694                                    case PPC_31_MULHWU:
3695                                            ic->f = instr(mulhwu_dot); break;
3696                                  case PPC_31_SUBF:                                  case PPC_31_SUBF:
3697                                          ic->f = instr(subf_dot); break;                                          ic->f = instr(subf_dot); break;
3698                                  case PPC_31_SUBFC:                                  case PPC_31_SUBFC:
3699                                          ic->f = instr(subfc_dot); break;                                          ic->f = instr(subfc_dot); break;
3700                                  case PPC_31_SUBFE:                                  case PPC_31_SUBFE:
3701                                          ic->f = instr(subfe_dot); break;                                          ic->f = instr(subfe_dot); break;
3702                                    case PPC_31_SUBFME:
3703                                            ic->f = instr(subfme_dot); break;
3704                                  case PPC_31_SUBFZE:                                  case PPC_31_SUBFZE:
3705                                          ic->f = instr(subfze_dot); break;                                          ic->f = instr(subfze_dot); break;
3706                                  default:fatal("RC bit not yet implemented\n");                                  default:fatal("RC bit not yet implemented\n");
# Line 2574  X(to_be_translated) Line 3716  X(to_be_translated)
3716                          }                          }
3717                          break;                          break;
3718    
3719                    case PPC_31_LVX:
3720                    case PPC_31_LVXL:
3721                    case PPC_31_STVX:
3722                    case PPC_31_STVXL:
3723                            load = 0;
3724                            switch (xo) {
3725                            case PPC_31_LVX:
3726                            case PPC_31_LVXL:
3727                                    load = 1; break;
3728                            }
3729                            rs = (iword >> 21) & 31;
3730                            ra = (iword >> 16) & 31;
3731                            rb = (iword >> 11) & 31;
3732                            ic->arg[0] = rs;
3733                            if (ra == 0)
3734                                    ic->arg[1] = (size_t)(&cpu->cd.ppc.zero);
3735                            else
3736                                    ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3737                            ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3738                            ic->f = load? instr(lvx) : instr(stvx);
3739                            break;
3740    
3741                  default:goto bad;                  default:goto bad;
3742                  }                  }
3743                  break;                  break;
3744    
3745          case PPC_HI6_63:          case PPC_HI6_59:
3746                  xo = (iword >> 1) & 1023;                  xo = (iword >>  1) & 1023;
3747                  rt = (iword >> 21) & 31;                  rt = (iword >> 21) & 31;
3748                  ra = (iword >> 16) & 31;                  ra = (iword >> 16) & 31;
3749                  rb = (iword >> 11) & 31;                  rb = (iword >> 11) & 31;
3750                    rs = (iword >>  6) & 31;        /*  actually frc  */
3751                  rc = iword & 1;                  rc = iword & 1;
3752    
3753                  switch (xo) {                  if (rc) {
3754                            fatal("Floating point (59) with rc bit! TODO\n");
3755                            goto bad;
3756                    }
3757    
3758                  case PPC_63_FMR:                  /*  NOTE: Some floating-point instructions are selected
3759                          if (rc) {                      using only the lowest 5 bits, not all 10!  */
3760                                  fatal("FMR with rc-bit: TODO\n");                  switch (xo & 31) {
3761                                  goto bad;                  case PPC_59_FDIVS:
3762                          }                  case PPC_59_FSUBS:
3763                          ic->f = instr(fmr);                  case PPC_59_FADDS:
3764                          ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rb]);                          switch (xo & 31) {
3765                          ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[rt]);                          case PPC_59_FDIVS: ic->f = instr(fdivs); break;
3766                            case PPC_59_FSUBS: ic->f = instr(fsubs); break;
3767                            case PPC_59_FADDS: ic->f = instr(fadds); break;
3768                            }
3769                            ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[ra]);
3770                            ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[rb]);
3771                            ic->arg[2] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3772                            break;
3773                    case PPC_59_FMULS:
3774                            ic->f = instr(fmuls);
3775                            ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3776                            ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[ra]);
3777                            ic->arg[2] = (size_t)(&cpu->cd.ppc.fpr[rs]); /* frc */
3778                          break;                          break;
3779                    default:/*  Use all 10 bits of xo:  */
3780                            switch (xo) {
3781                            default:goto bad;
3782                            }
3783                    }
3784                    break;
3785    
3786                  default:goto bad;          case PPC_HI6_63:
3787                    xo = (iword >>  1) & 1023;
3788                    rt = (iword >> 21) & 31;
3789                    ra = (iword >> 16) & 31;
3790                    rb = (iword >> 11) & 31;
3791                    rs = (iword >>  6) & 31;        /*  actually frc  */
3792                    rc = iword & 1;
3793    
3794                    if (rc) {
3795                            fatal("Floating point (63) with rc bit! TODO\n");
3796                            goto bad;
3797                    }
3798    
3799                    /*  NOTE: Some floating-point instructions are selected
3800                        using only the lowest 5 bits, not all 10!  */
3801                    switch (xo & 31) {
3802                    case PPC_63_FDIV:
3803                    case PPC_63_FSUB:
3804                    case PPC_63_FADD:
3805                            switch (xo & 31) {
3806                            case PPC_63_FDIV: ic->f = instr(fdiv); break;
3807                            case PPC_63_FSUB: ic->f = instr(fsub); break;
3808                            case PPC_63_FADD: ic->f = instr(fadd); break;
3809                            }
3810                            ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[ra]);
3811                            ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[rb]);
3812                            ic->arg[2] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3813                            break;
3814                    case PPC_63_FMUL:
3815                            ic->f = instr(fmul);
3816                            ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3817                            ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[ra]);
3818                            ic->arg[2] = (size_t)(&cpu->cd.ppc.fpr[rs]); /* frc */
3819                            break;
3820                    case PPC_63_FMSUB:
3821                    case PPC_63_FMADD:
3822                            switch (xo & 31) {
3823                            case PPC_63_FMSUB: ic->f = instr(fmsub); break;
3824                            case PPC_63_FMADD: ic->f = instr(fmadd); break;
3825                            }
3826                            ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3827                            ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[ra]);
3828                            ic->arg[2] = iword;
3829                            break;
3830                    default:/*  Use all 10 bits of xo:  */
3831                            switch (xo) {
3832                            case PPC_63_FCMPU:
3833                                    ic->f = instr(fcmpu);
3834                                    ic->arg[0] = 28 - 4*(rt >> 2);
3835                                    ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[ra]);
3836                                    ic->arg[2] = (size_t)(&cpu->cd.ppc.fpr[rb]);
3837                                    break;
3838                            case PPC_63_FRSP:
3839                            case PPC_63_FCTIWZ:
3840                            case PPC_63_FNEG:
3841                            case PPC_63_FMR:
3842                                    switch (xo) {
3843                                    case PPC_63_FRSP:   ic->f = instr(frsp); break;
3844                                    case PPC_63_FCTIWZ: ic->f = instr(fctiwz);break;
3845                                    case PPC_63_FNEG:   ic->f = instr(fneg); break;
3846                                    case PPC_63_FMR:    ic->f = instr(fmr); break;
3847                                    }
3848                                    ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rb]);
3849                                    ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3850                                    break;
3851                            case PPC_63_MFFS:
3852                                    ic->f = instr(mffs);
3853                                    ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3854                                    break;
3855                            case PPC_63_MTFSF:
3856                                    ic->f = instr(mtfsf);
3857                                    ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rb]);
3858                                    ic->arg[1] = 0;
3859                                    for (bi=7; bi>=0; bi--) {
3860                                            ic->arg[1] <<= 8;
3861                                            if (iword & (1 << (17+bi)))
3862                                                    ic->arg[1] |= 0xf;
3863                                    }
3864                                    break;
3865                            default:goto bad;
3866                            }
3867                  }                  }
3868                  break;                  break;
3869    

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

  ViewVC Help
Powered by ViewVC 1.1.26