/[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 18 by dpavlin, Mon Oct 8 16:19:11 2007 UTC revision 22 by dpavlin, Mon Oct 8 16:19:37 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2005  Anders Gavare.  All rights reserved.   *  Copyright (C) 2005-2006  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.20 2005/10/27 14:01:13 debug Exp $   *  $Id: cpu_ppc_instr.c,v 1.59 2006/02/09 22:40:27 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            int32_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                  uint32_t 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(mfsrin)  X(mfsr)
1401  {  {
1402          /*  TODO: This only works for 32-bit mode  */          /*  TODO: This only works for 32-bit mode  */
1403          uint32_t sr_num = reg(ic->arg[0]) >> 28;          reg(ic->arg[1]) = cpu->cd.ppc.sr[ic->arg[0]];
         reg(ic->arg[1]) = cpu->cd.ppc.sr[sr_num];  
1404  }  }
1405  X(mtsrin)  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          cpu->cd.ppc.sr[sr_num] = reg(ic->arg[1]);          reg(ic->arg[1]) = cpu->cd.ppc.sr[sr_num];
1410  }  }
1411    
1412    
# Line 886  X(rldicr) Line 1437  X(rldicr)
1437    
1438    
1439  /*  /*
1440   *  rlwinm:   *  rlwnm:
1441   *   *
1442   *  arg[0] = ptr to rs   *  arg[0] = ptr to ra
1443   *  arg[1] = ptr to ra   *  arg[1] = mask
1444   *  arg[2] = copy of the instruction word   *  arg[2] = copy of the instruction word
1445   */   */
1446  X(rlwinm)  X(rlwnm)
1447  {  {
1448          MODE_uint_t tmp = reg(ic->arg[0]), ra = 0;          uint32_t tmp, iword = ic->arg[2];
1449          uint32_t iword = ic->arg[2];          int rs = (iword >> 21) & 31;
1450          int sh, mb, me, rc;          int rb = (iword >> 11) & 31;
1451            int sh = cpu->cd.ppc.gpr[rb] & 0x1f;
1452            tmp = (uint32_t)cpu->cd.ppc.gpr[rs];
1453            tmp = (tmp << sh) | (tmp >> (32-sh));
1454            tmp &= (uint32_t)ic->arg[1];
1455            reg(ic->arg[0]) = tmp;
1456    }
1457    DOT0(rlwnm)
1458    
         sh = (iword >> 11) & 31;  
         mb = (iword >> 6) & 31;  
         me = (iword >> 1) & 31;    
         rc = iword & 1;  
1459    
1460          /*  TODO: Fix this, its performance is awful:  */  /*
1461          while (sh-- != 0) {   *  rlwinm:
1462                  int b = (tmp >> 31) & 1;   *
1463                  tmp = (tmp << 1) | b;   *  arg[0] = ptr to ra
1464          }   *  arg[1] = mask
1465          for (;;) {   *  arg[2] = copy of the instruction word
1466                  uint64_t mask;   */
1467                  mask = (uint64_t)1 << (31-mb);  X(rlwinm)
1468                  ra |= (tmp & mask);  {
1469                  if (mb == me)          uint32_t tmp, iword = ic->arg[2];
1470                          break;          int rs = (iword >> 21) & 31;
1471                  mb ++;          int sh = (iword >> 11) & 31;
1472                  if (mb == 32)          tmp = (uint32_t)cpu->cd.ppc.gpr[rs];
1473                          mb = 0;          tmp = (tmp << sh) | (tmp >> (32-sh));
1474          }          tmp &= (uint32_t)ic->arg[1];
1475          reg(ic->arg[1]) = ra;          reg(ic->arg[0]) = tmp;
         if (rc)  
                 update_cr0(cpu, ra);  
1476  }  }
1477    DOT0(rlwinm)
1478    
1479    
1480  /*  /*
# Line 935  X(rlwimi) Line 1488  X(rlwimi)
1488  {  {
1489          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]);
1490          uint32_t iword = ic->arg[2];          uint32_t iword = ic->arg[2];
1491          int sh, mb, me, rc;          int sh = (iword >> 11) & 31;
1492            int mb = (iword >> 6) & 31;
1493            int me = (iword >> 1) & 31;  
1494            int rc = iword & 1;
1495    
1496          sh = (iword >> 11) & 31;          tmp = (tmp << sh) | (tmp >> (32-sh));
         mb = (iword >> 6) & 31;  
         me = (iword >> 1) & 31;    
         rc = iword & 1;  
1497    
         /*  TODO: Fix this, its performance is awful:  */  
         while (sh-- != 0) {  
                 int b = (tmp >> 31) & 1;  
                 tmp = (tmp << 1) | b;  
         }  
1498          for (;;) {          for (;;) {
1499                  uint64_t mask;                  uint64_t mask;
1500                  mask = (uint64_t)1 << (31-mb);                  mask = (uint64_t)1 << (31-mb);
# Line 976  X(srawi) Line 1524  X(srawi)
1524          uint32_t tmp = reg(ic->arg[0]);          uint32_t tmp = reg(ic->arg[0]);
1525          int i = 0, j = 0, sh = ic->arg[2];          int i = 0, j = 0, sh = ic->arg[2];
1526    
1527          cpu->cd.ppc.xer &= ~PPC_XER_CA;          cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
1528          if (tmp & 0x80000000)          if (tmp & 0x80000000)
1529                  i = 1;                  i = 1;
1530          while (sh-- > 0) {          while (sh-- > 0) {
# Line 987  X(srawi) Line 1535  X(srawi)
1535                          tmp |= 0x80000000;                          tmp |= 0x80000000;
1536          }          }
1537          if (i && j>0)          if (i && j>0)
1538                  cpu->cd.ppc.xer |= PPC_XER_CA;                  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
1539          reg(ic->arg[1]) = (int64_t)(int32_t)tmp;          reg(ic->arg[1]) = (int64_t)(int32_t)tmp;
1540  }  }
1541  DOT(srawi)  DOT1(srawi)
1542    
1543    
1544  /*  /*
1545   *  mcrf:  Move inside condition register   *  mcrf:  Move inside condition register
1546   *   *
1547   *  arg[0] = bf,  arg[1] = bfa   *  arg[0] = 28-4*bf,  arg[1] = 28-4*bfa
1548   */   */
1549  X(mcrf)  X(mcrf)
1550  {  {
1551          int bf = ic->arg[0], bfa = ic->arg[1];          int bf_shift = ic->arg[0], bfa_shift = ic->arg[1];
1552          uint32_t tmp = (cpu->cd.ppc.cr >> (28 - bfa*4)) & 0xf;          uint32_t tmp = (cpu->cd.ppc.cr >> bfa_shift) & 0xf;
1553          cpu->cd.ppc.cr &= ~(0xf << (28 - bf*4));          cpu->cd.ppc.cr &= ~(0xf << bf_shift);
1554          cpu->cd.ppc.cr |= (tmp << (28 - bf*4));          cpu->cd.ppc.cr |= (tmp << bf_shift);
1555  }  }
1556    
1557    
# Line 1048  X(cror) { Line 1596  X(cror) {
1596          if (ba | bb)          if (ba | bb)
1597                  cpu->cd.ppc.cr |= (1 << (31-bt));                  cpu->cd.ppc.cr |= (1 << (31-bt));
1598  }  }
1599    X(crorc) {
1600            uint32_t iword = ic->arg[0]; int bt = (iword >> 21) & 31;
1601            int ba = (iword >> 16) & 31, bb = (iword >> 11) & 31;
1602            ba = (cpu->cd.ppc.cr >> (31-ba)) & 1;
1603            bb = (cpu->cd.ppc.cr >> (31-bb)) & 1;
1604            cpu->cd.ppc.cr &= ~(1 << (31-bt));
1605            if (!(ba | bb))
1606                    cpu->cd.ppc.cr |= (1 << (31-bt));
1607    }
1608    X(crnor) {
1609            uint32_t iword = ic->arg[0]; int bt = (iword >> 21) & 31;
1610            int ba = (iword >> 16) & 31, bb = (iword >> 11) & 31;
1611            ba = (cpu->cd.ppc.cr >> (31-ba)) & 1;
1612            bb = (cpu->cd.ppc.cr >> (31-bb)) & 1;
1613            cpu->cd.ppc.cr &= ~(1 << (31-bt));
1614            if (!(ba | bb))
1615                    cpu->cd.ppc.cr |= (1 << (31-bt));
1616    }
1617  X(crxor) {  X(crxor) {
1618          uint32_t iword = ic->arg[0]; int bt = (iword >> 21) & 31;          uint32_t iword = ic->arg[0]; int bt = (iword >> 21) & 31;
1619          int ba = (iword >> 16) & 31, bb = (iword >> 11) & 31;          int ba = (iword >> 16) & 31, bb = (iword >> 11) & 31;
# Line 1060  X(crxor) { Line 1626  X(crxor) {
1626    
1627    
1628  /*  /*
1629   *  mflr, etc:  Move from Link Register etc.   *  mfspr: Move from SPR
1630   *   *
1631   *  arg[0] = pointer to destination register   *  arg[0] = pointer to destination register
1632     *  arg[1] = pointer to source SPR
1633   */   */
1634  X(mflr) {       reg(ic->arg[0]) = cpu->cd.ppc.lr; }  X(mfspr) {
1635  X(mfctr) {      reg(ic->arg[0]) = cpu->cd.ppc.ctr; }          /*  TODO: Check permission  */
1636  X(mftb) {       reg(ic->arg[0]) = cpu->cd.ppc.tbl; }          reg(ic->arg[0]) = reg(ic->arg[1]);
1637  X(mftbu) {      reg(ic->arg[0]) = cpu->cd.ppc.tbu; }  }
1638  /*  TODO: Check privilege level for mfsprg*  */  X(mfspr_pmc1) {
1639  X(mfsrr0) {     reg(ic->arg[0]) = cpu->cd.ppc.srr0; }          /*
1640  X(mfsrr1) {     reg(ic->arg[0]) = cpu->cd.ppc.srr1; }           *  TODO: This is a temporary hack to make NetBSD/ppc detect
1641  X(mfsdr1) {     reg(ic->arg[0]) = cpu->cd.ppc.sdr1; }           *  a CPU of the correct (emulated) speed.
1642  X(mfdbsr) {     reg(ic->arg[0]) = cpu->cd.ppc.dbsr; }           */
1643  X(mfhid1) {     reg(ic->arg[0]) = 0;  /*  TODO  */ }          reg(ic->arg[0]) = cpu->machine->emulated_hz / 10;
1644  X(mfl2cr) {     reg(ic->arg[0]) = 0;  /*  TODO  */ }  }
1645  X(mfsprg0) {    reg(ic->arg[0]) = cpu->cd.ppc.sprg0; }  X(mftb) {
1646  X(mfsprg1) {    reg(ic->arg[0]) = cpu->cd.ppc.sprg1; }          /*  NOTE/TODO: This increments the time base (slowly) if it
1647  X(mfsprg2) {    reg(ic->arg[0]) = cpu->cd.ppc.sprg2; }              is being polled.  */
1648  X(mfsprg3) {    reg(ic->arg[0]) = cpu->cd.ppc.sprg3; }          if (++cpu->cd.ppc.spr[SPR_TBL] == 0)
1649  X(mfpvr) {      reg(ic->arg[0]) = cpu->cd.ppc.pvr; }                  cpu->cd.ppc.spr[SPR_TBU] ++;
1650  X(mfibatu) {    reg(ic->arg[0]) = cpu->cd.ppc.ibat_u[ic->arg[1]]; }          reg(ic->arg[0]) = cpu->cd.ppc.spr[SPR_TBL];
1651  X(mfibatl) {    reg(ic->arg[0]) = cpu->cd.ppc.ibat_l[ic->arg[1]]; }  }
1652  X(mfdbatu) {    reg(ic->arg[0]) = cpu->cd.ppc.dbat_u[ic->arg[1]]; }  X(mftbu) {
1653  X(mfdbatl) {    reg(ic->arg[0]) = cpu->cd.ppc.dbat_l[ic->arg[1]]; }          reg(ic->arg[0]) = cpu->cd.ppc.spr[SPR_TBU];
1654    }
1655    
1656    
1657  /*  /*
1658   *  mtlr etc.:  Move to Link Register (or other special register)   *  mtspr: Move to SPR.
1659   *   *
1660   *  arg[0] = pointer to source register   *  arg[0] = pointer to source register
1661     *  arg[1] = pointer to the SPR
1662   */   */
1663  X(mtlr) {       cpu->cd.ppc.lr = reg(ic->arg[0]); }  X(mtspr) {
1664  X(mtctr) {      cpu->cd.ppc.ctr = reg(ic->arg[0]); }          /*  TODO: Check permission  */
1665  /*  TODO: Check privilege level for these:  */          reg(ic->arg[1]) = reg(ic->arg[0]);
1666  X(mtsrr0) {     cpu->cd.ppc.srr0 = reg(ic->arg[0]); }  }
1667  X(mtsrr1) {     cpu->cd.ppc.srr1 = reg(ic->arg[0]); }  X(mtlr) {
1668  X(mtsdr1) {     cpu->cd.ppc.sdr1 = reg(ic->arg[0]); }          cpu->cd.ppc.spr[SPR_LR] = reg(ic->arg[0]);
1669  X(mtdbsr) {     cpu->cd.ppc.dbsr = reg(ic->arg[0]); }  }
1670  X(mtsprg0) {    cpu->cd.ppc.sprg0 = reg(ic->arg[0]); }  X(mtctr) {
1671  X(mtsprg1) {    cpu->cd.ppc.sprg1 = reg(ic->arg[0]); }          cpu->cd.ppc.spr[SPR_CTR] = reg(ic->arg[0]);
1672  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]); }  
1673    
1674    
1675  /*  /*
# Line 1115  X(rfi) Line 1679  X(rfi)
1679  {  {
1680          uint64_t tmp;          uint64_t tmp;
1681    
1682          reg_access_msr(cpu, &tmp, 0);          reg_access_msr(cpu, &tmp, 0, 0);
1683          tmp &= ~0xffff;          tmp &= ~0xffff;
1684          tmp |= (cpu->cd.ppc.srr1 & 0xffff);          tmp |= (cpu->cd.ppc.spr[SPR_SRR1] & 0xffff);
1685          reg_access_msr(cpu, &tmp, 1);          reg_access_msr(cpu, &tmp, 1, 0);
1686    
1687          cpu->pc = cpu->cd.ppc.srr0;          cpu->pc = cpu->cd.ppc.spr[SPR_SRR0];
1688          DYNTRANS_PC_TO_POINTERS(cpu);          quick_pc_to_pointers(cpu);
1689  }  }
1690    
1691    
# Line 1143  X(mfcr) Line 1707  X(mfcr)
1707   */   */
1708  X(mfmsr)  X(mfmsr)
1709  {  {
1710          reg_access_msr(cpu, (uint64_t*)ic->arg[0], 0);          reg_access_msr(cpu, (uint64_t*)ic->arg[0], 0, 0);
1711  }  }
1712    
1713    
# Line 1154  X(mfmsr) Line 1718  X(mfmsr)
1718   */   */
1719  X(mtmsr)  X(mtmsr)
1720  {  {
1721          reg_access_msr(cpu, (uint64_t*)ic->arg[0], 1);          MODE_uint_t old_pc;
1722    
1723            /*  TODO: check permission!  */
1724    
1725            /*  Synchronize the PC (pointing to _after_ this instruction)  */
1726            cpu->pc = (cpu->pc & ~0xfff) + ic->arg[1];
1727            old_pc = cpu->pc;
1728    
1729            reg_access_msr(cpu, (uint64_t*)ic->arg[0], 1, 1);
1730    
1731            /*
1732             *  Super-ugly hack:  If the pc wasn't changed (i.e. if there was no
1733             *  exception while accessing the msr), then we _decrease_ the PC by 4
1734             *  again. This is because the next ic could be an end_of_page.
1735             */
1736            if ((MODE_uint_t)cpu->pc == old_pc)
1737                    cpu->pc -= 4;
1738    }
1739    
1740    
1741    /*
1742     *  wrteei:  Write EE immediate  (on PPC405GP)
1743     *
1744     *  arg[0] = either 0 or 0x8000
1745     */
1746    X(wrteei)
1747    {
1748            /*  TODO: check permission!  */
1749            uint64_t x;
1750    
1751            /*  Synchronize the PC (pointing to _after_ this instruction)  */
1752            cpu->pc = (cpu->pc & ~0xfff) + ic->arg[1];
1753    
1754            reg_access_msr(cpu, &x, 0, 0);
1755            x = (x & ~0x8000) | ic->arg[0];
1756            reg_access_msr(cpu, &x, 1, 1);
1757  }  }
1758    
1759    
# Line 1179  X(mtcrf) Line 1778  X(mtcrf)
1778   */   */
1779  X(mulli)  X(mulli)
1780  {  {
1781          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]);
1782  }  }
1783    
1784    
# Line 1193  X(mulli) Line 1792  X(mulli)
1792  X(lmw) {  X(lmw) {
1793          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];
1794          unsigned char d[4];          unsigned char d[4];
1795          int n_err = 0, rs = ic->arg[0];          int rs = ic->arg[0];
1796    
1797            int low_pc = ((size_t)ic - (size_t)cpu->cd.ppc.cur_ic_page)
1798                / sizeof(struct ppc_instr_call);
1799            cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1)
1800                << PPC_INSTR_ALIGNMENT_SHIFT);
1801            cpu->pc |= (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
1802    
1803          while (rs <= 31) {          while (rs <= 31) {
1804                  if (cpu->memory_rw(cpu, cpu->mem, addr, d, sizeof(d),                  if (cpu->memory_rw(cpu, cpu->mem, addr, d, sizeof(d),
1805                      MEM_READ, CACHE_DATA) != MEMORY_ACCESS_OK)                      MEM_READ, CACHE_DATA) != MEMORY_ACCESS_OK) {
1806                          n_err ++;                          /*  exception  */
1807                            return;
1808                    }
1809    
1810                  if (cpu->byte_order == EMUL_BIG_ENDIAN)                  if (cpu->byte_order == EMUL_BIG_ENDIAN)
1811                          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 1814  X(lmw) {
1814                          cpu->cd.ppc.gpr[rs] = (d[3] << 24) + (d[2] << 16)                          cpu->cd.ppc.gpr[rs] = (d[3] << 24) + (d[2] << 16)
1815                              + (d[1] << 8) + d[0];                              + (d[1] << 8) + d[0];
1816    
                 if (n_err > 0) {  
                         fatal("TODO: lmw: exception\n");  
                         exit(1);  
                 }  
   
1817                  rs ++;                  rs ++;
1818                  addr += sizeof(uint32_t);                  addr += sizeof(uint32_t);
1819          }          }
1820  }  }
1821  X(stmw) {  X(stmw) {
1822          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;  
1823          unsigned char d[4];          unsigned char d[4];
1824          int n_err = 0, rs = ic->arg[0];          int rs = ic->arg[0];
1825    
1826            int low_pc = ((size_t)ic - (size_t)cpu->cd.ppc.cur_ic_page)
1827                / sizeof(struct ppc_instr_call);
1828            cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1)
1829                << PPC_INSTR_ALIGNMENT_SHIFT);
1830            cpu->pc += (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
1831    
1832          while (rs <= 31) {          while (rs <= 31) {
1833                  tmp = cpu->cd.ppc.gpr[rs];                  uint32_t tmp = cpu->cd.ppc.gpr[rs];
1834                  if (cpu->byte_order == EMUL_BIG_ENDIAN) {                  if (cpu->byte_order == EMUL_BIG_ENDIAN) {
1835                          d[3] = tmp; d[2] = tmp >> 8;                          d[3] = tmp; d[2] = tmp >> 8;
1836                          d[1] = tmp >> 16; d[0] = tmp >> 24;                          d[1] = tmp >> 16; d[0] = tmp >> 24;
# Line 1232  X(stmw) { Line 1839  X(stmw) {
1839                          d[2] = tmp >> 16; d[3] = tmp >> 24;                          d[2] = tmp >> 16; d[3] = tmp >> 24;
1840                  }                  }
1841                  if (cpu->memory_rw(cpu, cpu->mem, addr, d, sizeof(d),                  if (cpu->memory_rw(cpu, cpu->mem, addr, d, sizeof(d),
1842                      MEM_WRITE, CACHE_DATA) != MEMORY_ACCESS_OK)                      MEM_WRITE, CACHE_DATA) != MEMORY_ACCESS_OK) {
1843                          n_err ++;                          /*  exception  */
1844                            return;
                 if (n_err > 0) {  
                         fatal("TODO: stmw: exception\n");  
                         exit(1);  
1845                  }                  }
1846    
1847                  rs ++;                  rs ++;
# Line 1247  X(stmw) { Line 1851  X(stmw) {
1851    
1852    
1853  /*  /*
1854     *  Load/store string:
1855     *
1856     *  arg[0] = rs   (well, rt for lswi)
1857     *  arg[1] = ptr to ra (or ptr to zero)
1858     *  arg[2] = nb
1859     */
1860    X(lswi)
1861    {
1862            MODE_uint_t addr = reg(ic->arg[1]);
1863            int rt = ic->arg[0], nb = ic->arg[2];
1864            int sub = 0;
1865    
1866            int low_pc = ((size_t)ic - (size_t)cpu->cd.ppc.cur_ic_page)
1867                / sizeof(struct ppc_instr_call);
1868            cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1)
1869                << PPC_INSTR_ALIGNMENT_SHIFT);
1870            cpu->pc += (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
1871    
1872            while (nb > 0) {
1873                    unsigned char d;
1874                    if (cpu->memory_rw(cpu, cpu->mem, addr, &d, 1,
1875                        MEM_READ, CACHE_DATA) != MEMORY_ACCESS_OK) {
1876                            /*  exception  */
1877                            return;
1878                    }
1879    
1880                    if (cpu->cd.ppc.mode == MODE_POWER && sub == 0)
1881                            cpu->cd.ppc.gpr[rt] = 0;
1882                    cpu->cd.ppc.gpr[rt] &= ~(0xff << (24-8*sub));
1883                    cpu->cd.ppc.gpr[rt] |= (d << (24-8*sub));
1884                    sub ++;
1885                    if (sub == 4) {
1886                            rt = (rt + 1) & 31;
1887                            sub = 0;
1888                    }
1889                    addr ++;
1890                    nb --;
1891            }
1892    }
1893    X(stswi)
1894    {
1895            MODE_uint_t addr = reg(ic->arg[1]);
1896            int rs = ic->arg[0], nb = ic->arg[2];
1897            uint32_t cur = cpu->cd.ppc.gpr[rs];
1898            int sub = 0;
1899    
1900            int low_pc = ((size_t)ic - (size_t)cpu->cd.ppc.cur_ic_page)
1901                / sizeof(struct ppc_instr_call);
1902            cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1)
1903                << PPC_INSTR_ALIGNMENT_SHIFT);
1904            cpu->pc += (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
1905    
1906            while (nb > 0) {
1907                    unsigned char d = cur >> 24;
1908                    if (cpu->memory_rw(cpu, cpu->mem, addr, &d, 1,
1909                        MEM_WRITE, CACHE_DATA) != MEMORY_ACCESS_OK) {
1910                            /*  exception  */
1911                            return;
1912                    }
1913                    cur <<= 8;
1914                    sub ++;
1915                    if (sub == 4) {
1916                            rs = (rs + 1) & 31;
1917                            sub = 0;
1918                            cur = cpu->cd.ppc.gpr[rs];
1919                    }
1920                    addr ++;
1921                    nb --;
1922            }
1923    }
1924    
1925    
1926    /*
1927   *  Shifts, and, or, xor, etc.   *  Shifts, and, or, xor, etc.
1928   *   *
1929   *  arg[0] = pointer to source register rs   *  arg[0] = pointer to source register rs
# Line 1260  X(extsb) { Line 1937  X(extsb) {
1937          reg(ic->arg[2]) = (int64_t)(int8_t)reg(ic->arg[0]);          reg(ic->arg[2]) = (int64_t)(int8_t)reg(ic->arg[0]);
1938  #endif  #endif
1939  }  }
1940  DOT(extsb)  DOT2(extsb)
1941  X(extsh) {  X(extsh) {
1942  #ifdef MODE32  #ifdef MODE32
1943          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 1945  X(extsh) {
1945          reg(ic->arg[2]) = (int64_t)(int16_t)reg(ic->arg[0]);          reg(ic->arg[2]) = (int64_t)(int16_t)reg(ic->arg[0]);
1946  #endif  #endif
1947  }  }
1948  DOT(extsh)  DOT2(extsh)
1949  X(extsw) {  X(extsw) {
1950  #ifdef MODE32  #ifdef MODE32
1951          fatal("TODO: extsw: invalid instruction\n"); exit(1);          fatal("TODO: extsw: invalid instruction\n"); exit(1);
# Line 1276  X(extsw) { Line 1953  X(extsw) {
1953          reg(ic->arg[2]) = (int64_t)(int32_t)reg(ic->arg[0]);          reg(ic->arg[2]) = (int64_t)(int32_t)reg(ic->arg[0]);
1954  #endif  #endif
1955  }  }
1956  DOT(extsw)  DOT2(extsw)
1957  X(slw) {        reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0])  X(slw) {        reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0])
1958                      << (reg(ic->arg[1]) & 63); }                      << (reg(ic->arg[1]) & 31); }
1959  DOT(slw)  DOT2(slw)
1960  X(sraw) {       reg(ic->arg[2]) =  X(sraw)
1961  #ifdef MODE32  {
1962                      (int32_t)          uint32_t tmp = reg(ic->arg[0]);
1963  #else          int i = 0, j = 0, sh = reg(ic->arg[1]) & 31;
1964                      (int64_t)  
1965  #endif          cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
1966                  reg(ic->arg[0]) >> (reg(ic->arg[1]) & 63); }          if (tmp & 0x80000000)
1967  DOT(sraw)                  i = 1;
1968            while (sh-- > 0) {
1969                    if (tmp & 1)
1970                            j ++;
1971                    tmp >>= 1;
1972                    if (tmp & 0x40000000)
1973                            tmp |= 0x80000000;
1974            }
1975            if (i && j>0)
1976                    cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
1977            reg(ic->arg[2]) = (int64_t)(int32_t)tmp;
1978    }
1979    DOT2(sraw)
1980  X(srw) {        reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0])  X(srw) {        reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0])
1981                      >> (reg(ic->arg[1]) & 63); }                      >> (reg(ic->arg[1]) & 31); }
1982  DOT(srw)  DOT2(srw)
1983  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]); }
1984  X(and_dot) {    reg(ic->arg[2]) = reg(ic->arg[0]) & reg(ic->arg[1]);  DOT2(and)
                 update_cr0(cpu, reg(ic->arg[2])); }  
1985  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])); }
1986  X(nand_dot) {   reg(ic->arg[2]) = ~(reg(ic->arg[0]) & reg(ic->arg[1]));  DOT2(nand)
                 update_cr0(cpu, reg(ic->arg[2])); }  
1987  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])); }
1988  X(andc_dot) {   reg(ic->arg[2]) = reg(ic->arg[0]) & (~reg(ic->arg[1]));  DOT2(andc)
                 update_cr0(cpu, reg(ic->arg[2])); }  
1989  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])); }
1990  X(nor_dot) {    reg(ic->arg[2]) = ~(reg(ic->arg[0]) | reg(ic->arg[1]));  DOT2(nor)
1991                  update_cr0(cpu, reg(ic->arg[2])); }  X(mr) {         reg(ic->arg[2]) = reg(ic->arg[1]); }
1992  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]); }
1993  X(or_dot) {     reg(ic->arg[2]) = reg(ic->arg[0]) | reg(ic->arg[1]);  DOT2(or)
                 update_cr0(cpu, reg(ic->arg[2])); }  
1994  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])); }
1995  X(orc_dot) {    reg(ic->arg[2]) = reg(ic->arg[0]) | (~reg(ic->arg[1]));  DOT2(orc)
                 update_cr0(cpu, reg(ic->arg[2])); }  
1996  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]); }
1997  X(xor_dot) {    reg(ic->arg[2]) = reg(ic->arg[0]) ^ reg(ic->arg[1]);  DOT2(xor)
                 update_cr0(cpu, reg(ic->arg[2])); }  
1998    
1999    
2000  /*  /*
# Line 1321  X(xor_dot) {   reg(ic->arg[2]) = reg(ic->a Line 2004  X(xor_dot) {   reg(ic->arg[2]) = reg(ic->a
2004   *  arg[1] = pointer to destination register rt   *  arg[1] = pointer to destination register rt
2005   */   */
2006  X(neg) {        reg(ic->arg[1]) = -reg(ic->arg[0]); }  X(neg) {        reg(ic->arg[1]) = -reg(ic->arg[0]); }
2007  X(neg_dot) {    instr(neg)(cpu,ic); update_cr0(cpu, reg(ic->arg[1])); }  DOT1(neg)
2008    
2009    
2010  /*  /*
# Line 1336  X(mullw) Line 2019  X(mullw)
2019          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]);
2020          reg(ic->arg[2]) = (int32_t)sum;          reg(ic->arg[2]) = (int32_t)sum;
2021  }  }
2022    DOT2(mullw)
2023  X(mulhw)  X(mulhw)
2024  {  {
2025          int64_t sum;          int64_t sum;
# Line 1343  X(mulhw) Line 2027  X(mulhw)
2027              * (int64_t)(int32_t)reg(ic->arg[1]);              * (int64_t)(int32_t)reg(ic->arg[1]);
2028          reg(ic->arg[2]) = sum >> 32;          reg(ic->arg[2]) = sum >> 32;
2029  }  }
2030    DOT2(mulhw)
2031  X(mulhwu)  X(mulhwu)
2032  {  {
2033          uint64_t sum;          uint64_t sum;
# Line 1350  X(mulhwu) Line 2035  X(mulhwu)
2035              * (uint64_t)(uint32_t)reg(ic->arg[1]);              * (uint64_t)(uint32_t)reg(ic->arg[1]);
2036          reg(ic->arg[2]) = sum >> 32;          reg(ic->arg[2]) = sum >> 32;
2037  }  }
2038    DOT2(mulhwu)
2039  X(divw)  X(divw)
2040  {  {
2041          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 2046  X(divw)
2046                  sum = a / b;                  sum = a / b;
2047          reg(ic->arg[2]) = (uint32_t)sum;          reg(ic->arg[2]) = (uint32_t)sum;
2048  }  }
2049    DOT2(divw)
2050  X(divwu)  X(divwu)
2051  {  {
2052          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 2057  X(divwu)
2057                  sum = a / b;                  sum = a / b;
2058          reg(ic->arg[2]) = sum;          reg(ic->arg[2]) = sum;
2059  }  }
2060    DOT2(divwu)
2061    
2062    
2063  /*  /*
# Line 1380  X(divwu) Line 2068  X(divwu)
2068   *  arg[2] = pointer to destination register rt   *  arg[2] = pointer to destination register rt
2069   */   */
2070  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]); }
2071  X(add_dot) { instr(add)(cpu,ic); update_cr0(cpu, reg(ic->arg[2])); }  DOT2(add)
2072    
2073    
2074  /*  /*
# Line 1395  X(addc) Line 2083  X(addc)
2083          /*  TODO: this only works in 32-bit mode  */          /*  TODO: this only works in 32-bit mode  */
2084          uint64_t tmp = (uint32_t)reg(ic->arg[0]);          uint64_t tmp = (uint32_t)reg(ic->arg[0]);
2085          uint64_t tmp2 = tmp;          uint64_t tmp2 = tmp;
2086          cpu->cd.ppc.xer &= ~PPC_XER_CA;          cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2087          tmp += (uint32_t)reg(ic->arg[1]);          tmp += (uint32_t)reg(ic->arg[1]);
2088          if ((tmp >> 32) != (tmp2 >> 32))          if ((tmp >> 32) != (tmp2 >> 32))
2089                  cpu->cd.ppc.xer |= PPC_XER_CA;                  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2090          reg(ic->arg[2]) = (uint32_t)tmp;          reg(ic->arg[2]) = (uint32_t)tmp;
2091  }  }
2092    
# Line 1413  X(addc) Line 2101  X(addc)
2101  X(adde)  X(adde)
2102  {  {
2103          /*  TODO: this only works in 32-bit mode  */          /*  TODO: this only works in 32-bit mode  */
2104          int old_ca = cpu->cd.ppc.xer & PPC_XER_CA;          int old_ca = cpu->cd.ppc.spr[SPR_XER] & PPC_XER_CA;
2105          uint64_t tmp = (uint32_t)reg(ic->arg[0]);          uint64_t tmp = (uint32_t)reg(ic->arg[0]);
2106          uint64_t tmp2 = tmp;          uint64_t tmp2 = tmp;
2107          cpu->cd.ppc.xer &= ~PPC_XER_CA;          cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2108          tmp += (uint32_t)reg(ic->arg[1]);          tmp += (uint32_t)reg(ic->arg[1]);
2109          if (old_ca)          if (old_ca)
2110                  tmp ++;                  tmp ++;
2111          if ((tmp >> 32) != (tmp2 >> 32))          if ((tmp >> 32) != (tmp2 >> 32))
2112                  cpu->cd.ppc.xer |= PPC_XER_CA;                  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2113          reg(ic->arg[2]) = (uint32_t)tmp;          reg(ic->arg[2]) = (uint32_t)tmp;
2114  }  }
2115  X(adde_dot) { instr(adde)(cpu,ic); update_cr0(cpu, reg(ic->arg[2])); }  DOT2(adde)
2116  X(addme)  X(addme)
2117  {  {
2118          /*  TODO: this only works in 32-bit mode  */          /*  TODO: this only works in 32-bit mode  */
2119          int old_ca = cpu->cd.ppc.xer & PPC_XER_CA;          int old_ca = cpu->cd.ppc.spr[SPR_XER] & PPC_XER_CA;
2120          uint64_t tmp = (uint32_t)reg(ic->arg[0]);          uint64_t tmp = (uint32_t)reg(ic->arg[0]);
2121          uint64_t tmp2 = tmp;          uint64_t tmp2 = tmp;
2122          cpu->cd.ppc.xer &= ~PPC_XER_CA;          cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2123          if (old_ca)          if (old_ca)
2124                  tmp ++;                  tmp ++;
2125          tmp += 0xffffffffULL;          tmp += 0xffffffffULL;
2126          if ((tmp >> 32) != (tmp2 >> 32))          if ((tmp >> 32) != (tmp2 >> 32))
2127                  cpu->cd.ppc.xer |= PPC_XER_CA;                  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2128          reg(ic->arg[2]) = (uint32_t)tmp;          reg(ic->arg[2]) = (uint32_t)tmp;
2129  }  }
2130  X(addme_dot) { instr(addme)(cpu,ic); update_cr0(cpu, reg(ic->arg[2])); }  DOT2(addme)
2131  X(addze)  X(addze)
2132  {  {
2133          /*  TODO: this only works in 32-bit mode  */          /*  TODO: this only works in 32-bit mode  */
2134          int old_ca = cpu->cd.ppc.xer & PPC_XER_CA;          int old_ca = cpu->cd.ppc.spr[SPR_XER] & PPC_XER_CA;
2135          uint64_t tmp = (uint32_t)reg(ic->arg[0]);          uint64_t tmp = (uint32_t)reg(ic->arg[0]);
2136          uint64_t tmp2 = tmp;          uint64_t tmp2 = tmp;
2137          cpu->cd.ppc.xer &= ~PPC_XER_CA;          cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2138          if (old_ca)          if (old_ca)
2139                  tmp ++;                  tmp ++;
2140          if ((tmp >> 32) != (tmp2 >> 32))          if ((tmp >> 32) != (tmp2 >> 32))
2141                  cpu->cd.ppc.xer |= PPC_XER_CA;                  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2142          reg(ic->arg[2]) = (uint32_t)tmp;          reg(ic->arg[2]) = (uint32_t)tmp;
2143  }  }
2144  X(addze_dot) { instr(addze)(cpu,ic); update_cr0(cpu, reg(ic->arg[2])); }  DOT2(addze)
2145    
2146    
2147  /*  /*
# Line 1463  X(addze_dot) { instr(addze)(cpu,ic); upd Line 2151  X(addze_dot) { instr(addze)(cpu,ic); upd
2151   *  arg[1] = pointer to source register rb   *  arg[1] = pointer to source register rb
2152   *  arg[2] = pointer to destination register rt   *  arg[2] = pointer to destination register rt
2153   */   */
2154  X(subf) {       reg(ic->arg[2]) = reg(ic->arg[1]) - reg(ic->arg[0]); }  X(subf)
2155  X(subf_dot) {   instr(subf)(cpu,ic); update_cr0(cpu, reg(ic->arg[2])); }  {
2156            reg(ic->arg[2]) = reg(ic->arg[1]) - reg(ic->arg[0]);
2157    }
2158    DOT2(subf)
2159  X(subfc)  X(subfc)
2160  {  {
2161          cpu->cd.ppc.xer &= ~PPC_XER_CA;          cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2162          if (reg(ic->arg[1]) >= reg(ic->arg[0]))          if (reg(ic->arg[1]) >= reg(ic->arg[0]))
2163                  cpu->cd.ppc.xer |= PPC_XER_CA;                  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2164          reg(ic->arg[2]) = reg(ic->arg[1]) - reg(ic->arg[0]);          reg(ic->arg[2]) = reg(ic->arg[1]) - reg(ic->arg[0]);
2165  }  }
2166  X(subfc_dot) {  instr(subfc)(cpu,ic); update_cr0(cpu, reg(ic->arg[2])); }  DOT2(subfc)
2167  X(subfe)  X(subfe)
2168  {  {
2169          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;
2170          cpu->cd.ppc.xer &= ~PPC_XER_CA;          cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2171          if (reg(ic->arg[1]) == reg(ic->arg[0])) {          if (reg(ic->arg[1]) == reg(ic->arg[0])) {
2172                  if (old_ca)                  if (old_ca)
2173                          cpu->cd.ppc.xer |= PPC_XER_CA;                          cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2174          } else if (reg(ic->arg[1]) >= reg(ic->arg[0]))          } else if (reg(ic->arg[1]) >= reg(ic->arg[0]))
2175                  cpu->cd.ppc.xer |= PPC_XER_CA;                  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2176    
2177          /*          /*
2178           *  TODO: The register value calculation should be correct,           *  TODO: The register value calculation should be correct,
# Line 1490  X(subfe) Line 2181  X(subfe)
2181    
2182          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);
2183  }  }
2184  X(subfe_dot) {  instr(subfe)(cpu,ic); update_cr0(cpu, reg(ic->arg[2])); }  DOT2(subfe)
2185    X(subfme)
2186    {
2187            int old_ca = cpu->cd.ppc.spr[SPR_XER] & PPC_XER_CA;
2188            uint64_t tmp = (uint32_t)(~reg(ic->arg[0]));
2189            tmp += 0xffffffffULL;
2190            cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2191            if (old_ca)
2192                    tmp ++;
2193            if ((tmp >> 32) != 0)
2194                    cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2195            reg(ic->arg[2]) = (uint32_t)tmp;
2196    }
2197    DOT2(subfme)
2198  X(subfze)  X(subfze)
2199  {  {
2200          int old_ca = cpu->cd.ppc.xer & PPC_XER_CA;          int old_ca = cpu->cd.ppc.spr[SPR_XER] & PPC_XER_CA;
2201          uint64_t tmp = (uint32_t)(~reg(ic->arg[0]));          uint64_t tmp = (uint32_t)(~reg(ic->arg[0]));
2202          uint64_t tmp2 = tmp;          uint64_t tmp2 = tmp;
2203          cpu->cd.ppc.xer &= ~PPC_XER_CA;          cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2204          if (old_ca)          if (old_ca)
2205                  tmp ++;                  tmp ++;
2206          if ((tmp >> 32) != (tmp2 >> 32))          if ((tmp >> 32) != (tmp2 >> 32))
2207                  cpu->cd.ppc.xer |= PPC_XER_CA;                  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2208          reg(ic->arg[2]) = (uint32_t)tmp;          reg(ic->arg[2]) = (uint32_t)tmp;
2209  }  }
2210  X(subfze_dot) { instr(subfze)(cpu,ic); update_cr0(cpu, reg(ic->arg[2])); }  DOT2(subfze)
2211    
2212    
2213  /*  /*
# Line 1517  X(ori)  { reg(ic->arg[2]) = reg(ic->arg[ Line 2221  X(ori)  { reg(ic->arg[2]) = reg(ic->arg[
2221  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]; }
2222    
2223    
2224    #include "tmp_ppc_loadstore.c"
2225    
2226    
2227  /*  /*
2228   *  tlbie:  TLB invalidate   *  lfs, stfs: Load/Store Floating-point Single precision
2229   */   */
2230  X(tlbie)  X(lfs)
2231  {  {
2232          cpu->invalidate_translation_caches(cpu, 0, INVALIDATE_ALL);          /*  Sync. PC in case of an exception, and remember it:  */
2233  }          uint64_t old_pc, low_pc = ((size_t)ic - (size_t)
2234                cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
2235            old_pc = cpu->pc = (cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) <<
2236                PPC_INSTR_ALIGNMENT_SHIFT)) + (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
2237            if (!(cpu->cd.ppc.msr & PPC_MSR_FP)) {
2238                    ppc_exception(cpu, PPC_EXCEPTION_FPU);
2239                    return;
2240            }
2241    
2242            /*  Perform a 32-bit load:  */
2243    #ifdef MODE32
2244            ppc32_loadstore
2245    #else
2246            ppc_loadstore
2247    #endif
2248                [2 + 4 + 8](cpu, ic);
2249    
2250  /*          if (old_pc == cpu->pc) {
2251   *  user_syscall:  Userland syscall.                  /*  The load succeeded. Let's convert the value:  */
2252   *                  struct ieee_float_value val;
2253   *  arg[0] = syscall "level" (usually 0)                  (*(uint64_t *)ic->arg[0]) &= 0xffffffff;
2254   */                  ieee_interpret_float_value(*(uint64_t *)ic->arg[0],
2255  X(user_syscall)                      &val, IEEE_FMT_S);
2256                    (*(uint64_t *)ic->arg[0]) =
2257                        ieee_store_float_value(val.f, IEEE_FMT_D, val.nan);
2258            }
2259    }
2260    X(lfsx)
2261  {  {
2262          useremul_syscall(cpu, ic->arg[0]);          /*  Sync. PC in case of an exception, and remember it:  */
2263            uint64_t old_pc, low_pc = ((size_t)ic - (size_t)
2264                cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
2265            old_pc = cpu->pc = (cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) <<
2266                PPC_INSTR_ALIGNMENT_SHIFT)) + (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
2267            if (!(cpu->cd.ppc.msr & PPC_MSR_FP)) {
2268                    ppc_exception(cpu, PPC_EXCEPTION_FPU);
2269                    return;
2270            }
2271    
2272            /*  Perform a 32-bit load:  */
2273    #ifdef MODE32
2274            ppc32_loadstore_indexed
2275    #else
2276            ppc_loadstore_indexed
2277    #endif
2278                [2 + 4 + 8](cpu, ic);
2279    
2280            if (old_pc == cpu->pc) {
2281                    /*  The load succeeded. Let's convert the value:  */
2282                    struct ieee_float_value val;
2283                    (*(uint64_t *)ic->arg[0]) &= 0xffffffff;
2284                    ieee_interpret_float_value(*(uint64_t *)ic->arg[0],
2285                        &val, IEEE_FMT_S);
2286                    (*(uint64_t *)ic->arg[0]) =
2287                        ieee_store_float_value(val.f, IEEE_FMT_D, val.nan);
2288            }
2289  }  }
2290    X(lfd)
2291    {
2292            CHECK_FOR_FPU_EXCEPTION;
2293    
2294            /*  Perform a 64-bit load:  */
2295    #ifdef MODE32
2296            ppc32_loadstore
2297    #else
2298            ppc_loadstore
2299    #endif
2300                [3 + 4 + 8](cpu, ic);
2301    }
2302    X(lfdx)
2303    {
2304            CHECK_FOR_FPU_EXCEPTION;
2305    
2306  /*          /*  Perform a 64-bit load:  */
2307   *  openfirmware:  #ifdef MODE32
2308   */          ppc32_loadstore_indexed
2309  X(openfirmware)  #else
2310            ppc_loadstore_indexed
2311    #endif
2312                [3 + 4 + 8](cpu, ic);
2313    }
2314    X(stfs)
2315  {  {
2316          of_emul(cpu);          uint64_t *old_arg0 = (void *)ic->arg[0];
2317          cpu->pc = cpu->cd.ppc.lr;          struct ieee_float_value val;
2318          if (cpu->machine->show_trace_tree)          uint64_t tmp_val;
2319                  cpu_functioncall_trace_return(cpu);  
2320          DYNTRANS_PC_TO_POINTERS(cpu);          CHECK_FOR_FPU_EXCEPTION;
2321    
2322            ieee_interpret_float_value(*old_arg0, &val, IEEE_FMT_D);
2323            tmp_val = ieee_store_float_value(val.f, IEEE_FMT_S, val.nan);
2324    
2325            ic->arg[0] = (size_t)&tmp_val;
2326    
2327            /*  Perform a 32-bit store:  */
2328    #ifdef MODE32
2329            ppc32_loadstore
2330    #else
2331            ppc_loadstore
2332    #endif
2333                [2 + 4](cpu, ic);
2334    
2335            ic->arg[0] = (size_t)old_arg0;
2336  }  }
2337    X(stfsx)
2338    {
2339            uint64_t *old_arg0 = (void *)ic->arg[0];
2340            struct ieee_float_value val;
2341            uint64_t tmp_val;
2342    
2343            CHECK_FOR_FPU_EXCEPTION;
2344    
2345  #include "tmp_ppc_loadstore.c"          ieee_interpret_float_value(*old_arg0, &val, IEEE_FMT_D);
2346            tmp_val = ieee_store_float_value(val.f, IEEE_FMT_S, val.nan);
2347    
2348            ic->arg[0] = (size_t)&tmp_val;
2349    
2350  /*****************************************************************************/          /*  Perform a 32-bit store:  */
2351    #ifdef MODE32
2352            ppc32_loadstore_indexed
2353    #else
2354            ppc_loadstore_indexed
2355    #endif
2356                [2 + 4](cpu, ic);
2357    
2358            ic->arg[0] = (size_t)old_arg0;
2359    }
2360    X(stfd)
2361    {
2362            CHECK_FOR_FPU_EXCEPTION;
2363    
2364  /*          /*  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;  
2365  #ifdef MODE32  #ifdef MODE32
2366          uint32_t addr;          ppc32_loadstore
2367  #else  #else
2368          uint64_t addr;          ppc_loadstore
         fatal("byte_fill_loop: not for 64-bit mode yet\n");  
         exit(1);  
2369  #endif  #endif
2370                [3 + 4](cpu, ic);
2371    }
2372    X(stfdx)
2373    {
2374            CHECK_FOR_FPU_EXCEPTION;
2375    
2376  restart_loop:          /*  Perform a 64-bit store:  */
2377          addr = reg(z);  #ifdef MODE32
2378          /*  TODO: This only work with 32-bit addressing:  */          ppc32_loadstore_indexed
2379          page = cpu->cd.ppc.host_store[addr >> 12];  #else
2380          if (page == NULL) {          ppc_loadstore_indexed
2381                  instr(cmpwi)(cpu, ic);  #endif
2382                  return;              [3 + 4](cpu, ic);
2383          }  }
2384    
         n = reg(y) + 1; ofs = addr & 0xfff; maxlen = 0x1000 - ofs;  
         if (n > maxlen)  
                 n = maxlen;  
2385    
2386          /*  fatal("FILL A: x=%i n=%i ofs=0x%x y=0x%x z=0x%x w=0x%x\n", x,  /*
2387              n, ofs, (int)reg(y), (int)reg(z), (int)reg(w));  */   *  tlbia:  TLB invalidate all
2388     */
2389    X(tlbia)
2390    {
2391            printf("[ tlbia ]\n");
2392            cpu->invalidate_translation_caches(cpu, 0, INVALIDATE_ALL);
2393    }
2394    
         memset(page + ofs, *w, n);  
2395    
2396          reg(z) = addr + n;  /*
2397          reg(y) -= n;   *  tlbie:  TLB invalidate
2398     */
2399    X(tlbie)
2400    {
2401            cpu->invalidate_translation_caches(cpu, reg(ic->arg[0]),
2402                INVALIDATE_VADDR);
2403    }
2404    
         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;  
2405    
2406          cpu->n_translated_instrs --;  /*
2407          if ((int32_t)reg(y) > 0)   *  sc: Syscall.
2408                  cpu->cd.ppc.next_ic = ic;   */
2409          else  X(sc)
2410                  cpu->cd.ppc.next_ic = &ic[5];  {
2411            /*  Synchronize the PC (pointing to _after_ this instruction)  */
2412            cpu->pc = (cpu->pc & ~0xfff) + ic->arg[1];
2413    
2414          /*  fatal("FILL B: x=%i n=%i ofs=0x%x y=0x%x z=0x%x w=0x%x\n", x, n,          ppc_exception(cpu, PPC_EXCEPTION_SC);
2415              ofs, (int)reg(y), (int)reg(z), (int)reg(w));  */  
2416            /*  This caused an update to the PC register, so there is no need
2417                to worry about the next instruction being an end_of_page.  */
2418  }  }
2419    
2420    
2421  /*****************************************************************************/  /*
2422     *  user_syscall:  Userland syscall.
2423     *
2424     *  arg[0] = syscall "level" (usually 0)
2425     */
2426    X(user_syscall)
2427    {
2428            useremul_syscall(cpu, ic->arg[0]);
2429    }
2430    
2431    
2432  X(end_of_page)  /*
2433     *  openfirmware:
2434     */
2435    X(openfirmware)
2436  {  {
2437          /*  Update the PC:  (offset 0, but on the next page)  */          of_emul(cpu);
2438          cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2);          if (cpu->running == 0) {
2439          cpu->pc += (PPC_IC_ENTRIES_PER_PAGE << 2);                  cpu->running_translated = 0;
2440            }
2441            cpu->pc = cpu->cd.ppc.spr[SPR_LR];
2442            if (cpu->machine->show_trace_tree)
2443                    cpu_functioncall_trace_return(cpu);
2444            quick_pc_to_pointers(cpu);
2445    }
2446    
         /*  Find the new physical page and update the translation pointers:  */  
         DYNTRANS_PC_TO_POINTERS(cpu);  
2447    
2448          /*  end_of_page doesn't count as an executed instruction:  */  /*
2449          cpu->n_translated_instrs --;   *  tlbsx_dot: TLB scan
2450     */
2451    X(tlbsx_dot)
2452    {
2453            /*  TODO  */
2454            cpu->cd.ppc.cr &= ~(0xf0000000);
2455            cpu->cd.ppc.cr |= 0x20000000;
2456            cpu->cd.ppc.cr |= ((cpu->cd.ppc.spr[SPR_XER] >> 3) & 0x10000000);
2457  }  }
2458    
2459    
2460  /*****************************************************************************/  /*
2461     *  tlbli:
2462     */
2463    X(tlbli)
2464    {
2465            fatal("tlbli\n");
2466            cpu->invalidate_translation_caches(cpu, 0, INVALIDATE_ALL);
2467    }
2468    
2469    
2470  /*  /*
2471   *  ppc_combine_instructions():   *  tlbld:
  *  
  *  Combine two or more instructions, if possible, into a single function call.  
2472   */   */
2473  void COMBINE_INSTRUCTIONS(struct cpu *cpu, struct ppc_instr_call *ic,  X(tlbld)
         uint32_t addr)  
2474  {  {
2475          int n_back;          /*  MODE_uint_t vaddr = reg(ic->arg[0]);
2476          n_back = (addr >> PPC_INSTR_ALIGNMENT_SHIFT)              MODE_uint_t paddr = cpu->cd.ppc.spr[SPR_RPA];  */
             & (PPC_IC_ENTRIES_PER_PAGE-1);  
2477    
2478          if (n_back >= 4) {          fatal("tlbld\n");
2479                  /*          cpu->invalidate_translation_caches(cpu, 0, INVALIDATE_ALL);
2480                   *  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 &&  
2481    
                     ic[-3].f == instr(stb_0) &&  
                     ic[-3].arg[1] == ic[-1].arg[0] && ic[-3].arg[2] == 0 &&  
2482    
2483                      ic[-2].f == instr(addi) &&  /*****************************************************************************/
                     ic[-2].arg[0] == ic[-2].arg[2] && ic[-2].arg[1] == -1 &&  
2484    
                     ic[-1].f == instr(addi) &&  
                     ic[-1].arg[0] == ic[-1].arg[2] && ic[-1].arg[1] ==  1 &&  
2485    
2486                      ic[0].f == instr(bc_samepage) &&  X(end_of_page)
2487                      ic[0].arg[0] == (size_t)&ic[-4] &&  {
2488                      ic[0].arg[1] == 12 && ic[0].arg[2] == 4*ic[-4].arg[2] + 1) {          /*  Update the PC:  (offset 0, but on the next page)  */
2489                          ic[-4].f = instr(byte_fill_loop);          cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1) << PPC_INSTR_ALIGNMENT_SHIFT);
2490                          combined;          cpu->pc += (PPC_IC_ENTRIES_PER_PAGE << PPC_INSTR_ALIGNMENT_SHIFT);
                 }  
         }  
2491    
2492          /*  TODO: Combine forward as well  */          /*  Find the new physical page and update the translation pointers:  */
2493            quick_pc_to_pointers(cpu);
2494    
2495            /*  end_of_page doesn't count as an executed instruction:  */
2496            cpu->n_translated_instrs --;
2497  }  }
2498    
2499    
# Line 1711  void COMBINE_INSTRUCTIONS(struct cpu *cp Line 2511  void COMBINE_INSTRUCTIONS(struct cpu *cp
2511  X(to_be_translated)  X(to_be_translated)
2512  {  {
2513          uint64_t addr, low_pc, tmp_addr;          uint64_t addr, low_pc, tmp_addr;
2514          uint32_t iword;          uint32_t iword, mask;
2515          unsigned char *page;          unsigned char *page;
2516          unsigned char ib[4];          unsigned char ib[4];
2517    #ifdef DYNTRANS_BACKEND
2518            int simple = 0;
2519    #endif
2520          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,
2521              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,
2522              bfa, fp;              bfa, fp, byterev, nb, mb, me;
2523          void (*samepage_function)(struct cpu *, struct ppc_instr_call *);          void (*samepage_function)(struct cpu *, struct ppc_instr_call *);
2524          void (*rc_f)(struct cpu *, struct ppc_instr_call *);          void (*rc_f)(struct cpu *, struct ppc_instr_call *);
2525    
# Line 1739  X(to_be_translated) Line 2542  X(to_be_translated)
2542                  /*  fatal("TRANSLATION MISS!\n");  */                  /*  fatal("TRANSLATION MISS!\n");  */
2543                  if (!cpu->memory_rw(cpu, cpu->mem, addr, ib,                  if (!cpu->memory_rw(cpu, cpu->mem, addr, ib,
2544                      sizeof(ib), MEM_READ, CACHE_INSTRUCTION)) {                      sizeof(ib), MEM_READ, CACHE_INSTRUCTION)) {
2545                          fatal("to_be_translated(): "                          fatal("PPC to_be_translated(): "
2546                              "read failed: TODO\n");                              "read failed: TODO\n");
2547                          goto bad;                          exit(1);
2548                            /*  goto bad;  */
2549                  }                  }
2550          }          }
2551    
2552          iword = *((uint32_t *)&ib[0]);          iword = *((uint32_t *)&ib[0]);
2553            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);  
2554    
2555    
2556  #define DYNTRANS_TO_BE_TRANSLATED_HEAD  #define DYNTRANS_TO_BE_TRANSLATED_HEAD
# Line 1771  X(to_be_translated) Line 2566  X(to_be_translated)
2566    
2567          switch (main_opcode) {          switch (main_opcode) {
2568    
2569            case 0x04:
2570                    fatal("[ TODO: ALTIVEC ]\n");
2571                    ic->f = instr(nop);
2572                    break;
2573    
2574          case PPC_HI6_MULLI:          case PPC_HI6_MULLI:
2575                  rt = (iword >> 21) & 31;                  rt = (iword >> 21) & 31;
2576                  ra = (iword >> 16) & 31;                  ra = (iword >> 16) & 31;
# Line 1806  X(to_be_translated) Line 2606  X(to_be_translated)
2606                          imm = (int16_t)(iword & 0xffff);                          imm = (int16_t)(iword & 0xffff);
2607                          if (l_bit)                          if (l_bit)
2608                                  ic->f = instr(cmpdi);                                  ic->f = instr(cmpdi);
2609                          else                          else {
2610                                  ic->f = instr(cmpwi);                                  if (bf == 0)
2611                                            ic->f = instr(cmpwi_cr0);
2612                                    else
2613                                            ic->f = instr(cmpwi);
2614                            }
2615                  }                  }
2616                  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);                  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2617                  ic->arg[1] = (ssize_t)imm;                  ic->arg[1] = (ssize_t)imm;
2618                  ic->arg[2] = bf;                  ic->arg[2] = 28 - 4 * bf;
2619                  break;                  break;
2620    
2621          case PPC_HI6_ADDIC:          case PPC_HI6_ADDIC:
# Line 1828  X(to_be_translated) Line 2632  X(to_be_translated)
2632                  else                  else
2633                          ic->f = instr(addic_dot);                          ic->f = instr(addic_dot);
2634                  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);                  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2635                  ic->arg[1] = (ssize_t)imm;                  ic->arg[1] = imm;
2636                  ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);                  ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);
2637                  break;                  break;
2638    
# Line 1837  X(to_be_translated) Line 2641  X(to_be_translated)
2641                  rt = (iword >> 21) & 31; ra = (iword >> 16) & 31;                  rt = (iword >> 21) & 31; ra = (iword >> 16) & 31;
2642                  ic->f = instr(addi);                  ic->f = instr(addi);
2643                  if (ra == 0)                  if (ra == 0)
2644                          ic->arg[0] = (size_t)(&cpu->cd.ppc.zero);                          ic->f = instr(li);
2645                  else                  else
2646                          ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);                          ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2647                  ic->arg[1] = (ssize_t)(int16_t)(iword & 0xffff);                  ic->arg[1] = (int16_t)(iword & 0xffff);
2648                  if (main_opcode == PPC_HI6_ADDIS)                  if (main_opcode == PPC_HI6_ADDIS)
2649                          ic->arg[1] <<= 16;                          ic->arg[1] <<= 16;
2650                    if (ra == 0 && ic->arg[1] == 0)
2651                            ic->f = instr(li_0);
2652                  ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);                  ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);
2653                  break;                  break;
2654    
# Line 1879  X(to_be_translated) Line 2685  X(to_be_translated)
2685          case PPC_HI6_LBZU:          case PPC_HI6_LBZU:
2686          case PPC_HI6_LHZ:          case PPC_HI6_LHZ:
2687          case PPC_HI6_LHZU:          case PPC_HI6_LHZU:
2688            case PPC_HI6_LHA:
2689            case PPC_HI6_LHAU:
2690          case PPC_HI6_LWZ:          case PPC_HI6_LWZ:
2691          case PPC_HI6_LWZU:          case PPC_HI6_LWZU:
2692          case PPC_HI6_LFD:          case PPC_HI6_LFD:
2693            case PPC_HI6_LFS:
2694          case PPC_HI6_STB:          case PPC_HI6_STB:
2695          case PPC_HI6_STBU:          case PPC_HI6_STBU:
2696          case PPC_HI6_STH:          case PPC_HI6_STH:
2697          case PPC_HI6_STHU:          case PPC_HI6_STHU:
2698          case PPC_HI6_STW:          case PPC_HI6_STW:
2699          case PPC_HI6_STWU:          case PPC_HI6_STWU:
2700            case PPC_HI6_STFD:
2701            case PPC_HI6_STFS:
2702                  rs = (iword >> 21) & 31;                  rs = (iword >> 21) & 31;
2703                  ra = (iword >> 16) & 31;                  ra = (iword >> 16) & 31;
2704                  imm = (int16_t)(iword & 0xffff);                  imm = (int16_t)iword;
2705                  load = 0; zero = 1; size = 0; update = 0; fp = 0;                  load = 0; zero = 1; size = 0; update = 0; fp = 0;
2706                    ic->f = NULL;
2707                  switch (main_opcode) {                  switch (main_opcode) {
2708                  case PPC_HI6_LBZ:  load = 1; break;                  case PPC_HI6_LBZ:  load=1; break;
2709                  case PPC_HI6_LBZU: load = 1; update = 1; break;                  case PPC_HI6_LBZU: load=1; update=1; break;
2710                  case PPC_HI6_LHZ:  load = 1; size = 1; break;                  case PPC_HI6_LHA:  load=1; size=1; zero=0; break;
2711                  case PPC_HI6_LHZU: load = 1; size = 1; update = 1; break;                  case PPC_HI6_LHAU: load=1; size=1; zero=0; update=1; break;
2712                  case PPC_HI6_LWZ:  load = 1; size = 2; break;                  case PPC_HI6_LHZ:  load=1; size=1; break;
2713                  case PPC_HI6_LWZU: load = 1; size = 2; update = 1; break;                  case PPC_HI6_LHZU: load=1; size=1; update=1; break;
2714                  case PPC_HI6_LFD:  load = 1; size = 3; fp = 1; break;                  case PPC_HI6_LWZ:  load=1; size=2; break;
2715                    case PPC_HI6_LWZU: load=1; size=2; update=1; break;
2716                    case PPC_HI6_LFD:  load=1; size=3; fp=1;ic->f=instr(lfd);break;
2717                    case PPC_HI6_LFS:  load=1; size=2; fp=1;ic->f=instr(lfs);break;
2718                  case PPC_HI6_STB:  break;                  case PPC_HI6_STB:  break;
2719                  case PPC_HI6_STBU: update = 1; break;                  case PPC_HI6_STBU: update=1; break;
2720                  case PPC_HI6_STH:  size = 1; break;                  case PPC_HI6_STH:  size=1; break;
2721                  case PPC_HI6_STHU: size = 1; update = 1; break;                  case PPC_HI6_STHU: size=1; update=1; break;
2722                  case PPC_HI6_STW:  size = 2; break;                  case PPC_HI6_STW:  size=2; break;
2723                  case PPC_HI6_STWU: size = 2; update = 1; break;                  case PPC_HI6_STWU: size=2; update=1; break;
2724                  }                  case PPC_HI6_STFD: size=3; fp=1; ic->f = instr(stfd); break;
2725                  if (fp) {                  case PPC_HI6_STFS: size=2; fp=1; ic->f = instr(stfs); break;
2726                          /*  Floating point:  */                  }
2727                          if (load && size == 3) {                  if (ic->f == NULL) {
                                 fatal("TODO: ld is INCORRECT!\n");  
                                 ic->f = instr(nop);  
                         } else {  
                                 /*  TODO  */  
                                 fatal("TODO: fdgasgd\n");  
                                 goto bad;  
                         }  
                 } else {  
                         /*  Integer load/store:  */  
2728                          ic->f =                          ic->f =
2729  #ifdef MODE32  #ifdef MODE32
2730                              ppc32_loadstore                              ppc32_loadstore
# Line 1949  X(to_be_translated) Line 2755  X(to_be_translated)
2755                  bo = (iword >> 21) & 31;                  bo = (iword >> 21) & 31;
2756                  bi = (iword >> 16) & 31;                  bi = (iword >> 16) & 31;
2757                  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;  
                 }  
2758                  if (aa_bit) {                  if (aa_bit) {
2759                          fatal("aa_bit: NOT YET\n");                          fatal("aa_bit: NOT YET\n");
2760                          goto bad;                          goto bad;
2761                  }                  }
2762                  ic->f = instr(bc);                  if (lk_bit) {
2763                  samepage_function = instr(bc_samepage);                          ic->f = instr(bcl);
2764                  ic->arg[0] = (ssize_t)tmp_addr;                          samepage_function = instr(bcl_samepage);
2765                    } else {
2766                            ic->f = instr(bc);
2767                            if ((bo & 0x14) == 0x04) {
2768                                    samepage_function = bo & 8?
2769                                        instr(bc_samepage_simple1) :
2770                                        instr(bc_samepage_simple0);
2771                            } else
2772                                    samepage_function = instr(bc_samepage);
2773                    }
2774                    ic->arg[0] = (ssize_t)(tmp_addr + (addr & 0xffc));
2775                  ic->arg[1] = bo;                  ic->arg[1] = bo;
2776                  ic->arg[2] = bi;                  ic->arg[2] = 31-bi;
2777                  /*  Branches are calculated as cur PC + offset.  */                  /*  Branches are calculated as cur PC + offset.  */
2778                  /*  Special case: branch within the same page:  */                  /*  Special case: branch within the same page:  */
2779                  {                  {
2780                          uint64_t mask_within_page =                          uint64_t mask_within_page =
2781                              ((PPC_IC_ENTRIES_PER_PAGE-1) << 2) | 3;                              ((PPC_IC_ENTRIES_PER_PAGE-1) << 2) | 3;
2782                          uint64_t old_pc = addr;                          uint64_t old_pc = addr;
2783                          uint64_t new_pc = old_pc + (int32_t)ic->arg[0];                          uint64_t new_pc = old_pc + (int32_t)tmp_addr;
2784                          if ((old_pc & ~mask_within_page) ==                          if ((old_pc & ~mask_within_page) ==
2785                              (new_pc & ~mask_within_page)) {                              (new_pc & ~mask_within_page)) {
2786                                  ic->f = samepage_function;                                  ic->f = samepage_function;
# Line 1981  X(to_be_translated) Line 2793  X(to_be_translated)
2793    
2794          case PPC_HI6_SC:          case PPC_HI6_SC:
2795                  ic->arg[0] = (iword >> 5) & 0x7f;                  ic->arg[0] = (iword >> 5) & 0x7f;
2796                    ic->arg[1] = (addr & 0xfff) + 4;
2797                  if (cpu->machine->userland_emul != NULL)                  if (cpu->machine->userland_emul != NULL)
2798                          ic->f = instr(user_syscall);                          ic->f = instr(user_syscall);
2799                  else {                  else if (iword == 0x44ee0002) {
2800                          /*  Special case/magic hack for OpenFirmware emul:  */                          /*  Special case/magic hack for OpenFirmware emul:  */
2801                          if (iword == 0x44ee0002) {                          ic->f = instr(openfirmware);
2802                                  ic->f = instr(openfirmware);                  } else
2803                                  break;                          ic->f = instr(sc);
                         }  
                         fatal("PPC non-userland SYSCALL: TODO\n");  
                         goto bad;  
                 }  
2804                  break;                  break;
2805    
2806          case PPC_HI6_B:          case PPC_HI6_B:
2807                  aa_bit = (iword & 2) >> 1;                  aa_bit = (iword & 2) >> 1;
2808                  lk_bit = iword & 1;                  lk_bit = iword & 1;
                 if (aa_bit) {  
                         fatal("aa_bit: NOT YET\n");  
                         goto bad;  
                 }  
2809                  tmp_addr = (int64_t)(int32_t)((iword & 0x03fffffc) << 6);                  tmp_addr = (int64_t)(int32_t)((iword & 0x03fffffc) << 6);
2810                  tmp_addr = (int64_t)tmp_addr >> 6;                  tmp_addr = (int64_t)tmp_addr >> 6;
2811                  if (lk_bit) {                  if (lk_bit) {
# Line 2015  X(to_be_translated) Line 2820  X(to_be_translated)
2820                          ic->f = instr(b);                          ic->f = instr(b);
2821                          samepage_function = instr(b_samepage);                          samepage_function = instr(b_samepage);
2822                  }                  }
2823                  ic->arg[0] = (ssize_t)tmp_addr;                  ic->arg[0] = (ssize_t)(tmp_addr + (addr & 0xffc));
2824                    ic->arg[1] = (addr & 0xffc) + 4;
2825                  /*  Branches are calculated as cur PC + offset.  */                  /*  Branches are calculated as cur PC + offset.  */
2826                  /*  Special case: branch within the same page:  */                  /*  Special case: branch within the same page:  */
2827                  {                  {
2828                          uint64_t mask_within_page =                          uint64_t mask_within_page =
2829                              ((PPC_IC_ENTRIES_PER_PAGE-1) << 2) | 3;                              ((PPC_IC_ENTRIES_PER_PAGE-1) << 2) | 3;
2830                          uint64_t old_pc = addr;                          uint64_t old_pc = addr;
2831                          uint64_t new_pc = old_pc + (int32_t)ic->arg[0];                          uint64_t new_pc = old_pc + (int32_t)tmp_addr;
2832                          if ((old_pc & ~mask_within_page) ==                          if ((old_pc & ~mask_within_page) ==
2833                              (new_pc & ~mask_within_page)) {                              (new_pc & ~mask_within_page)) {
2834                                  ic->f = samepage_function;                                  ic->f = samepage_function;
# Line 2031  X(to_be_translated) Line 2837  X(to_be_translated)
2837                                      ((new_pc & mask_within_page) >> 2));                                      ((new_pc & mask_within_page) >> 2));
2838                          }                          }
2839                  }                  }
2840                    if (aa_bit) {
2841                            if (lk_bit) {
2842                                    if (cpu->machine->show_trace_tree) {
2843                                            ic->f = instr(bla_trace);
2844                                    } else {
2845                                            ic->f = instr(bla);
2846                                    }
2847                            } else {
2848                                    ic->f = instr(ba);
2849                            }
2850                            ic->arg[0] = (ssize_t)tmp_addr;
2851                    }
2852                  break;                  break;
2853    
2854          case PPC_HI6_19:          case PPC_HI6_19:
# Line 2046  X(to_be_translated) Line 2864  X(to_be_translated)
2864                          if (xo == PPC_19_BCLR) {                          if (xo == PPC_19_BCLR) {
2865                                  if (lk_bit)                                  if (lk_bit)
2866                                          ic->f = instr(bclr_l);                                          ic->f = instr(bclr_l);
2867                                  else                                  else {
2868                                          ic->f = instr(bclr);                                          ic->f = instr(bclr);
2869                                            if (!cpu->machine->show_trace_tree &&
2870                                                (bo & 0x14) == 0x14)
2871                                                    ic->f = instr(bclr_20);
2872                                    }
2873                          } else {                          } else {
2874                                  if (lk_bit)                                  if (lk_bit)
2875                                          ic->f = instr(bcctr_l);                                          ic->f = instr(bcctr_l);
# Line 2055  X(to_be_translated) Line 2877  X(to_be_translated)
2877                                          ic->f = instr(bcctr);                                          ic->f = instr(bcctr);
2878                          }                          }
2879                          ic->arg[0] = bo;                          ic->arg[0] = bo;
2880                          ic->arg[1] = bi;                          ic->arg[1] = 31 - bi;
2881                          ic->arg[2] = bh;                          ic->arg[2] = bh;
2882                          break;                          break;
2883    
# Line 2071  X(to_be_translated) Line 2893  X(to_be_translated)
2893                  case PPC_19_MCRF:                  case PPC_19_MCRF:
2894                          bf = (iword >> 23) & 7;                          bf = (iword >> 23) & 7;
2895                          bfa = (iword >> 18) & 7;                          bfa = (iword >> 18) & 7;
2896                          ic->arg[0] = bf;                          ic->arg[0] = 28 - 4*bf;
2897                          ic->arg[1] = bfa;                          ic->arg[1] = 28 - 4*bfa;
2898                          ic->f = instr(mcrf);                          ic->f = instr(mcrf);
2899                          break;                          break;
2900    
# Line 2080  X(to_be_translated) Line 2902  X(to_be_translated)
2902                  case PPC_19_CRANDC:                  case PPC_19_CRANDC:
2903                  case PPC_19_CREQV:                  case PPC_19_CREQV:
2904                  case PPC_19_CROR:                  case PPC_19_CROR:
2905                    case PPC_19_CRORC:
2906                    case PPC_19_CRNOR:
2907                  case PPC_19_CRXOR:                  case PPC_19_CRXOR:
2908                          switch (xo) {                          switch (xo) {
2909                          case PPC_19_CRAND:  ic->f = instr(crand); break;                          case PPC_19_CRAND:  ic->f = instr(crand); break;
2910                          case PPC_19_CRANDC: ic->f = instr(crandc); break;                          case PPC_19_CRANDC: ic->f = instr(crandc); break;
2911                          case PPC_19_CREQV:  ic->f = instr(creqv); break;                          case PPC_19_CREQV:  ic->f = instr(creqv); break;
2912                          case PPC_19_CROR:   ic->f = instr(cror); break;                          case PPC_19_CROR:   ic->f = instr(cror); break;
2913                            case PPC_19_CRORC:  ic->f = instr(crorc); break;
2914                            case PPC_19_CRNOR:  ic->f = instr(crnor); break;
2915                          case PPC_19_CRXOR:  ic->f = instr(crxor); break;                          case PPC_19_CRXOR:  ic->f = instr(crxor); break;
2916                          }                          }
2917                          ic->arg[0] = iword;                          ic->arg[0] = iword;
# Line 2095  X(to_be_translated) Line 2921  X(to_be_translated)
2921                  }                  }
2922                  break;                  break;
2923    
2924          case PPC_HI6_RLWIMI:          case PPC_HI6_RLWNM:
2925          case PPC_HI6_RLWINM:          case PPC_HI6_RLWINM:
2926                    ra = (iword >> 16) & 31;
2927                    mb = (iword >> 6) & 31;
2928                    me = (iword >> 1) & 31;  
2929                    rc = iword & 1;
2930                    mask = 0;
2931                    for (;;) {
2932                            mask |= ((uint32_t)0x80000000 >> mb);
2933                            if (mb == me)
2934                                    break;
2935                            mb ++; mb &= 31;
2936                    }
2937                    switch (main_opcode) {
2938                    case PPC_HI6_RLWNM:
2939                            ic->f = rc? instr(rlwnm_dot) : instr(rlwnm); break;
2940                    case PPC_HI6_RLWINM:
2941                            ic->f = rc? instr(rlwinm_dot) : instr(rlwinm); break;
2942                    }
2943                    ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2944                    ic->arg[1] = mask;
2945                    ic->arg[2] = (uint32_t)iword;
2946                    break;
2947    
2948            case PPC_HI6_RLWIMI:
2949                  rs = (iword >> 21) & 31;                  rs = (iword >> 21) & 31;
2950                  ra = (iword >> 16) & 31;                  ra = (iword >> 16) & 31;
2951                  if (main_opcode == PPC_HI6_RLWIMI)                  ic->f = instr(rlwimi);
                         ic->f = instr(rlwimi);  
                 else  
                         ic->f = instr(rlwinm);  
2952                  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);                  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
2953                  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);                  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2954                  ic->arg[2] = (uint32_t)iword;                  ic->arg[2] = (uint32_t)iword;
# Line 2164  X(to_be_translated) Line 3010  X(to_be_translated)
3010                          } else {                          } else {
3011                                  if (l_bit)                                  if (l_bit)
3012                                          ic->f = instr(cmpd);                                          ic->f = instr(cmpd);
3013                                  else                                  else {
3014                                          ic->f = instr(cmpw);                                          if (bf == 0)
3015                                                    ic->f = instr(cmpw_cr0);
3016                                            else
3017                                                    ic->f = instr(cmpw);
3018                                    }
3019                          }                          }
3020                          ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);                          ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3021                          ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rb]);                          ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3022                          ic->arg[2] = bf;                          ic->arg[2] = 28 - 4*bf;
3023                          break;                          break;
3024    
3025                  case PPC_31_CNTLZW:                  case PPC_31_CNTLZW:
# Line 2188  X(to_be_translated) Line 3038  X(to_be_translated)
3038                  case PPC_31_MFSPR:                  case PPC_31_MFSPR:
3039                          rt = (iword >> 21) & 31;                          rt = (iword >> 21) & 31;
3040                          spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);                          spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
3041                            debug_spr_usage(cpu->pc, spr);
3042                          ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rt]);                          ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rt]);
3043                            ic->arg[1] = (size_t)(&cpu->cd.ppc.spr[spr]);
3044                          switch (spr) {                          switch (spr) {
3045                          case 8:   ic->f = instr(mflr); break;                          case SPR_PMC1:  ic->f = instr(mfspr_pmc1); break;
3046                          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;  
                                 }  
3047                          }                          }
3048                          break;                          break;
3049    
3050                  case PPC_31_MTSPR:                  case PPC_31_MTSPR:
3051                          rs = (iword >> 21) & 31;                          rs = (iword >> 21) & 31;
3052                          spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);                          spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
3053                            debug_spr_usage(cpu->pc, spr);
3054                          ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);                          ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
3055                            ic->arg[1] = (size_t)(&cpu->cd.ppc.spr[spr]);
3056                          switch (spr) {                          switch (spr) {
3057                          case 8:   ic->f = instr(mtlr); break;                          case SPR_LR:
3058                          case 9:   ic->f = instr(mtctr); break;                                  ic->f = instr(mtlr);
3059                          case 25:  ic->f = instr(mtsdr1); break;                                  break;
3060                          case 26:  ic->f = instr(mtsrr0); break;                          case SPR_CTR:
3061                          case 27:  ic->f = instr(mtsrr1); break;                                  ic->f = instr(mtctr);
3062                          case 272: ic->f = instr(mtsprg0); break;                                  break;
3063                          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;  
                                 }  
3064                          }                          }
3065                          break;                          break;
3066    
# Line 2278  X(to_be_translated) Line 3084  X(to_be_translated)
3084                                  goto bad;                                  goto bad;
3085                          }                          }
3086                          ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);                          ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
3087                            ic->arg[1] = (addr & 0xfff) + 4;
3088                          ic->f = instr(mtmsr);                          ic->f = instr(mtmsr);
3089                          break;                          break;
3090    
# Line 2313  X(to_be_translated) Line 3120  X(to_be_translated)
3120                          }                          }
3121                          break;                          break;
3122    
3123                    case PPC_31_MFSR:
3124                  case PPC_31_MTSR:                  case PPC_31_MTSR:
3125                          rt = (iword >> 21) & 31;                          rt = (iword >> 21) & 31;
3126                          ic->arg[0] = (iword >> 16) & 15;                          ic->arg[0] = (iword >> 16) & 15;
3127                          ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rt]);                          ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rt]);
3128                          ic->f = instr(mtsr);                          switch (xo) {
3129                            case PPC_31_MFSR:   ic->f = instr(mfsr); break;
3130                            case PPC_31_MTSR:   ic->f = instr(mtsr); break;
3131                            }
3132                          if (cpu->cd.ppc.bits == 64) {                          if (cpu->cd.ppc.bits == 64) {
3133                                  fatal("Not yet for 64-bit mode\n");                                  fatal("Not yet for 64-bit mode\n");
3134                                  goto bad;                                  goto bad;
# Line 2339  X(to_be_translated) Line 3150  X(to_be_translated)
3150                          break;                          break;
3151    
3152                  case PPC_31_SYNC:                  case PPC_31_SYNC:
                 case PPC_31_TLBSYNC:  
3153                  case PPC_31_EIEIO:                  case PPC_31_EIEIO:
3154                  case PPC_31_DCBST:                  case PPC_31_DCBST:
3155                  case PPC_31_DCBTST:                  case PPC_31_DCBTST:
3156                  case PPC_31_DCBF:                  case PPC_31_DCBF:
3157                  case PPC_31_DCBT:                  case PPC_31_DCBT:
3158                  case PPC_31_ICBI:                  case PPC_31_ICBI:
                         /*  TODO  */  
3159                          ic->f = instr(nop);                          ic->f = instr(nop);
3160                          break;                          break;
3161    
# Line 2358  X(to_be_translated) Line 3167  X(to_be_translated)
3167                          else                          else
3168                                  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);                                  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3169                          ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rb]);                          ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3170                            ic->arg[2] = addr & 0xfff;
3171                          ic->f = instr(dcbz);                          ic->f = instr(dcbz);
3172                          break;                          break;
3173    
3174                    case PPC_31_TLBIA:
3175                            ic->f = instr(tlbia);
3176                            break;
3177    
3178                    case PPC_31_TLBSYNC:
3179                            /*  According to IBM, "Ensures that a tlbie and
3180                                tlbia instruction executed by one processor has
3181                                completed on all other processors.", which in
3182                                GXemul means a nop :-)  */
3183                            ic->f = instr(nop);
3184                            break;
3185    
3186                  case PPC_31_TLBIE:                  case PPC_31_TLBIE:
3187                          /*  TODO  */                          /*  TODO: POWER also uses ra?  */
3188                            rb = (iword >> 11) & 31;
3189                            ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3190                          ic->f = instr(tlbie);                          ic->f = instr(tlbie);
3191                          break;                          break;
3192    
3193                    case PPC_31_TLBLD:      /*  takes an arg  */
3194                            rb = (iword >> 11) & 31;
3195                            ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3196                            ic->f = instr(tlbld);
3197                            break;
3198    
3199                    case PPC_31_TLBLI:      /*  takes an arg  */
3200                            rb = (iword >> 11) & 31;
3201                            ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3202                            ic->f = instr(tlbli);
3203                            break;
3204    
3205                    case PPC_31_TLBSX_DOT:
3206                            /*  TODO  */
3207                            ic->f = instr(tlbsx_dot);
3208                            break;
3209    
3210                  case PPC_31_MFTB:                  case PPC_31_MFTB:
3211                          rt = (iword >> 21) & 31;                          rt = (iword >> 21) & 31;
3212                          spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);                          spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
# Line 2398  X(to_be_translated) Line 3239  X(to_be_translated)
3239                          ic->f = instr(llsc);                          ic->f = instr(llsc);
3240                          break;                          break;
3241    
3242                    case PPC_31_LSWI:
3243                    case PPC_31_STSWI:
3244                            rs = (iword >> 21) & 31;
3245                            ra = (iword >> 16) & 31;
3246                            nb = (iword >> 11) & 31;
3247                            ic->arg[0] = rs;
3248                            if (ra == 0)
3249                                    ic->arg[1] = (size_t)(&cpu->cd.ppc.zero);
3250                            else
3251                                    ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3252                            ic->arg[2] = nb == 0? 32 : nb;
3253                            switch (xo) {
3254                            case PPC_31_LSWI:  ic->f = instr(lswi); break;
3255                            case PPC_31_STSWI: ic->f = instr(stswi); break;
3256                            }
3257                            break;
3258    
3259                    case PPC_31_WRTEEI:
3260                            ic->arg[0] = iword & 0x8000;
3261                            ic->f = instr(wrteei);
3262                            break;
3263    
3264                    case 0x1c3:
3265                            fatal("[ mtdcr: TODO ]\n");
3266                            ic->f = instr(nop);
3267                            break;
3268    
3269                  case PPC_31_LBZX:                  case PPC_31_LBZX:
3270                  case PPC_31_LBZUX:                  case PPC_31_LBZUX:
3271                    case PPC_31_LHAX:
3272                    case PPC_31_LHAUX:
3273                  case PPC_31_LHZX:                  case PPC_31_LHZX:
3274                  case PPC_31_LHZUX:                  case PPC_31_LHZUX:
3275                  case PPC_31_LWZX:                  case PPC_31_LWZX:
3276                  case PPC_31_LWZUX:                  case PPC_31_LWZUX:
3277                    case PPC_31_LHBRX:
3278                    case PPC_31_LWBRX:
3279                    case PPC_31_LFDX:
3280                    case PPC_31_LFSX:
3281                  case PPC_31_STBX:                  case PPC_31_STBX:
3282                  case PPC_31_STBUX:                  case PPC_31_STBUX:
3283                  case PPC_31_STHX:                  case PPC_31_STHX:
# Line 2412  X(to_be_translated) Line 3286  X(to_be_translated)
3286                  case PPC_31_STWUX:                  case PPC_31_STWUX:
3287                  case PPC_31_STDX:                  case PPC_31_STDX:
3288                  case PPC_31_STDUX:                  case PPC_31_STDUX:
3289                    case PPC_31_STHBRX:
3290                    case PPC_31_STWBRX:
3291                    case PPC_31_STFDX:
3292                    case PPC_31_STFSX:
3293                          rs = (iword >> 21) & 31;                          rs = (iword >> 21) & 31;
3294                          ra = (iword >> 16) & 31;                          ra = (iword >> 16) & 31;
3295                          rb = (iword >> 11) & 31;                          rb = (iword >> 11) & 31;
                         ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);  
3296                          if (ra == 0)                          if (ra == 0)
3297                                  ic->arg[1] = (size_t)(&cpu->cd.ppc.zero);                                  ic->arg[1] = (size_t)(&cpu->cd.ppc.zero);
3298                          else                          else
3299                                  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);                                  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3300                          ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rb]);                          ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3301                          load = 0; zero = 1; size = 0; update = 0;                          load = 0; zero = 1; size = 0; update = 0;
3302                            byterev = 0; fp = 0;
3303                            ic->f = NULL;
3304                          switch (xo) {                          switch (xo) {
3305                          case PPC_31_LBZX:  load = 1; break;                          case PPC_31_LBZX:  load = 1; break;
3306                          case PPC_31_LBZUX: load = update = 1; break;                          case PPC_31_LBZUX: load=update=1; break;
3307                          case PPC_31_LHZX:  size = 1; load = 1; break;                          case PPC_31_LHAX:  size=1; load=1; zero=0; break;
3308                          case PPC_31_LHZUX: size = 1; load = update = 1; break;                          case PPC_31_LHAUX: size=1; load=update=1; zero=0; break;
3309                          case PPC_31_LWZX:  size = 2; load = 1; break;                          case PPC_31_LHZX:  size=1; load=1; break;
3310                          case PPC_31_LWZUX: size = 2; load = update = 1; break;                          case PPC_31_LHZUX: size=1; load=update = 1; break;
3311                            case PPC_31_LWZX:  size=2; load=1; break;
3312                            case PPC_31_LWZUX: size=2; load=update = 1; break;
3313                            case PPC_31_LHBRX: size=1; load=1; byterev=1;
3314                                               ic->f = instr(lhbrx); break;
3315                            case PPC_31_LWBRX: size=2; load=1; byterev=1;
3316                                               ic->f = instr(lwbrx); break;
3317                            case PPC_31_LFDX:  size=3; load=1; fp=1;
3318                                               ic->f = instr(lfdx); break;
3319                            case PPC_31_LFSX:  size=2; load=1; fp=1;
3320                                               ic->f = instr(lfsx); break;
3321                          case PPC_31_STBX:  break;                          case PPC_31_STBX:  break;
3322                          case PPC_31_STBUX: update = 1; break;                          case PPC_31_STBUX: update = 1; break;
3323                          case PPC_31_STHX:  size = 1; break;                          case PPC_31_STHX:  size=1; break;
3324                          case PPC_31_STHUX: size = 1; update = 1; break;                          case PPC_31_STHUX: size=1; update = 1; break;
3325                          case PPC_31_STWX:  size = 2; break;                          case PPC_31_STWX:  size=2; break;
3326                          case PPC_31_STWUX: size = 2; update = 1; break;                          case PPC_31_STWUX: size=2; update = 1; break;
3327                          case PPC_31_STDX:  size = 3; break;                          case PPC_31_STDX:  size=3; break;
3328                          case PPC_31_STDUX: size = 3; update = 1; break;                          case PPC_31_STDUX: size=3; update = 1; break;
3329                            case PPC_31_STHBRX:size=1; byterev = 1;
3330                                               ic->f = instr(sthbrx); break;
3331                            case PPC_31_STWBRX:size=2; byterev = 1;
3332                                               ic->f = instr(stwbrx); break;
3333                            case PPC_31_STFDX: size=3; fp=1;
3334                                               ic->f = instr(stfdx); break;
3335                            case PPC_31_STFSX: size=2; fp=1;
3336                                               ic->f = instr(stfsx); break;
3337                          }                          }
3338                          ic->f =                          if (fp)
3339                                    ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rs]);
3340                            else
3341                                    ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
3342                            if (!byterev && ic->f == NULL) {
3343                                    ic->f =
3344  #ifdef MODE32  #ifdef MODE32
3345                              ppc32_loadstore_indexed                                      ppc32_loadstore_indexed
3346  #else  #else
3347                              ppc_loadstore_indexed                                      ppc_loadstore_indexed
3348  #endif  #endif
3349                              [size + 4*zero + 8*load + 16*update];                                      [size + 4*zero + 8*load + 16*update];
3350                            }
3351                          if (ra == 0 && update) {                          if (ra == 0 && update) {
3352                                  fatal("TODO: ra=0 && update?\n");                                  fatal("TODO: ra=0 && update?\n");
3353                                  goto bad;                                  goto bad;
# Line 2490  X(to_be_translated) Line 3393  X(to_be_translated)
3393                                            rc_f  = instr(andc_dot); break;                                            rc_f  = instr(andc_dot); break;
3394                          case PPC_31_NOR:  ic->f = instr(nor);                          case PPC_31_NOR:  ic->f = instr(nor);
3395                                            rc_f  = instr(nor_dot); break;                                            rc_f  = instr(nor_dot); break;
3396                          case PPC_31_OR:   ic->f = instr(or);                          case PPC_31_OR:   ic->f = rs == rb? instr(mr)
3397                                                    : instr(or);
3398                                            rc_f  = instr(or_dot); break;                                            rc_f  = instr(or_dot); break;
3399                          case PPC_31_ORC:  ic->f = instr(orc);                          case PPC_31_ORC:  ic->f = instr(orc);
3400                                            rc_f  = instr(orc_dot); break;                                            rc_f  = instr(orc_dot); break;
# Line 2517  X(to_be_translated) Line 3421  X(to_be_translated)
3421                  case PPC_31_SUBF:                  case PPC_31_SUBF:
3422                  case PPC_31_SUBFC:                  case PPC_31_SUBFC:
3423                  case PPC_31_SUBFE:                  case PPC_31_SUBFE:
3424                    case PPC_31_SUBFME:
3425                  case PPC_31_SUBFZE:                  case PPC_31_SUBFZE:
3426                          rt = (iword >> 21) & 31;                          rt = (iword >> 21) & 31;
3427                          ra = (iword >> 16) & 31;                          ra = (iword >> 16) & 31;
# Line 2541  X(to_be_translated) Line 3446  X(to_be_translated)
3446                          case PPC_31_SUBF:   ic->f = instr(subf); break;                          case PPC_31_SUBF:   ic->f = instr(subf); break;
3447                          case PPC_31_SUBFC:  ic->f = instr(subfc); break;                          case PPC_31_SUBFC:  ic->f = instr(subfc); break;
3448                          case PPC_31_SUBFE:  ic->f = instr(subfe); n64=1; break;                          case PPC_31_SUBFE:  ic->f = instr(subfe); n64=1; break;
3449                            case PPC_31_SUBFME: ic->f = instr(subfme); n64=1; break;
3450                          case PPC_31_SUBFZE: ic->f = instr(subfze); n64=1;break;                          case PPC_31_SUBFZE: ic->f = instr(subfze); n64=1;break;
3451                          }                          }
3452                          if (rc) {                          if (rc) {
# Line 2553  X(to_be_translated) Line 3459  X(to_be_translated)
3459                                          ic->f = instr(addme_dot); break;                                          ic->f = instr(addme_dot); break;
3460                                  case PPC_31_ADDZE:                                  case PPC_31_ADDZE:
3461                                          ic->f = instr(addze_dot); break;                                          ic->f = instr(addze_dot); break;
3462                                    case PPC_31_DIVW:
3463                                            ic->f = instr(divw_dot); break;
3464                                    case PPC_31_DIVWU:
3465                                            ic->f = instr(divwu_dot); break;
3466                                    case PPC_31_MULLW:
3467                                            ic->f = instr(mullw_dot); break;
3468                                    case PPC_31_MULHW:
3469                                            ic->f = instr(mulhw_dot); break;
3470                                    case PPC_31_MULHWU:
3471                                            ic->f = instr(mulhwu_dot); break;
3472                                  case PPC_31_SUBF:                                  case PPC_31_SUBF:
3473                                          ic->f = instr(subf_dot); break;                                          ic->f = instr(subf_dot); break;
3474                                  case PPC_31_SUBFC:                                  case PPC_31_SUBFC:
3475                                          ic->f = instr(subfc_dot); break;                                          ic->f = instr(subfc_dot); break;
3476                                  case PPC_31_SUBFE:                                  case PPC_31_SUBFE:
3477                                          ic->f = instr(subfe_dot); break;                                          ic->f = instr(subfe_dot); break;
3478                                    case PPC_31_SUBFME:
3479                                            ic->f = instr(subfme_dot); break;
3480                                  case PPC_31_SUBFZE:                                  case PPC_31_SUBFZE:
3481                                          ic->f = instr(subfze_dot); break;                                          ic->f = instr(subfze_dot); break;
3482                                  default:fatal("RC bit not yet implemented\n");                                  default:fatal("RC bit not yet implemented\n");
# Line 2574  X(to_be_translated) Line 3492  X(to_be_translated)
3492                          }                          }
3493                          break;                          break;
3494    
3495                    case 359:
3496                            fatal("[ TODO: 359 ]\n");
3497                            ic->f = instr(nop);
3498                            break;
3499                    case PPC_31_LVX:
3500                            fatal("[ TODO: lvx ]\n");
3501                            ic->f = instr(nop);
3502                            break;
3503                    case PPC_31_STVX:
3504                            fatal("[ TODO: stvx ]\n");
3505                            ic->f = instr(nop);
3506                            break;
3507                    case PPC_31_STVXL:
3508                            fatal("[ TODO: stvxl ]\n");
3509                            ic->f = instr(nop);
3510                            break;
3511    
3512                  default:goto bad;                  default:goto bad;
3513                  }                  }
3514                  break;                  break;
3515    
3516          case PPC_HI6_63:          case PPC_HI6_59:
3517                  xo = (iword >> 1) & 1023;                  xo = (iword >>  1) & 1023;
3518                  rt = (iword >> 21) & 31;                  rt = (iword >> 21) & 31;
3519                  ra = (iword >> 16) & 31;                  ra = (iword >> 16) & 31;
3520                  rb = (iword >> 11) & 31;                  rb = (iword >> 11) & 31;
3521                    rs = (iword >>  6) & 31;        /*  actually frc  */
3522                  rc = iword & 1;                  rc = iword & 1;
3523    
3524                  switch (xo) {                  if (rc) {
3525                            fatal("Floating point (59) with rc bit! TODO\n");
3526                            goto bad;
3527                    }
3528    
3529                  case PPC_63_FMR:                  /*  NOTE: Some floating-point instructions are selected
3530                          if (rc) {                      using only the lowest 5 bits, not all 10!  */
3531                                  fatal("FMR with rc-bit: TODO\n");                  switch (xo & 31) {
3532                                  goto bad;                  case PPC_59_FDIVS:
3533                          }                  case PPC_59_FSUBS:
3534                          ic->f = instr(fmr);                  case PPC_59_FADDS:
3535                          ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rb]);                          switch (xo & 31) {
3536                          ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[rt]);                          case PPC_59_FDIVS: ic->f = instr(fdivs); break;
3537                            case PPC_59_FSUBS: ic->f = instr(fsubs); break;
3538                            case PPC_59_FADDS: ic->f = instr(fadds); break;
3539                            }
3540                            ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[ra]);
3541                            ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[rb]);
3542                            ic->arg[2] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3543                            break;
3544                    case PPC_59_FMULS:
3545                            ic->f = instr(fmuls);
3546                            ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3547                            ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[ra]);
3548                            ic->arg[2] = (size_t)(&cpu->cd.ppc.fpr[rs]); /* frc */
3549                          break;                          break;
3550                    default:/*  Use all 10 bits of xo:  */
3551                            switch (xo) {
3552                            default:goto bad;
3553                            }
3554                    }
3555                    break;
3556    
3557                  default:goto bad;          case PPC_HI6_63:
3558                    xo = (iword >>  1) & 1023;
3559                    rt = (iword >> 21) & 31;
3560                    ra = (iword >> 16) & 31;
3561                    rb = (iword >> 11) & 31;
3562                    rs = (iword >>  6) & 31;        /*  actually frc  */
3563                    rc = iword & 1;
3564    
3565                    if (rc) {
3566                            fatal("Floating point (63) with rc bit! TODO\n");
3567                            goto bad;
3568                    }
3569    
3570                    /*  NOTE: Some floating-point instructions are selected
3571                        using only the lowest 5 bits, not all 10!  */
3572                    switch (xo & 31) {
3573                    case PPC_63_FDIV:
3574                    case PPC_63_FSUB:
3575                    case PPC_63_FADD:
3576                            switch (xo & 31) {
3577                            case PPC_63_FDIV: ic->f = instr(fdiv); break;
3578                            case PPC_63_FSUB: ic->f = instr(fsub); break;
3579                            case PPC_63_FADD: ic->f = instr(fadd); break;
3580                            }
3581                            ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[ra]);
3582                            ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[rb]);
3583                            ic->arg[2] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3584                            break;
3585                    case PPC_63_FMUL:
3586                            ic->f = instr(fmul);
3587                            ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3588                            ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[ra]);
3589                            ic->arg[2] = (size_t)(&cpu->cd.ppc.fpr[rs]); /* frc */
3590                            break;
3591                    case PPC_63_FMSUB:
3592                    case PPC_63_FMADD:
3593                            switch (xo & 31) {
3594                            case PPC_63_FMSUB: ic->f = instr(fmsub); break;
3595                            case PPC_63_FMADD: ic->f = instr(fmadd); break;
3596                            }
3597                            ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3598                            ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[ra]);
3599                            ic->arg[2] = iword;
3600                            break;
3601                    default:/*  Use all 10 bits of xo:  */
3602                            switch (xo) {
3603                            case PPC_63_FCMPU:
3604                                    ic->f = instr(fcmpu);
3605                                    ic->arg[0] = 28 - 4*(rt >> 2);
3606                                    ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[ra]);
3607                                    ic->arg[2] = (size_t)(&cpu->cd.ppc.fpr[rb]);
3608                                    break;
3609                            case PPC_63_FRSP:
3610                            case PPC_63_FCTIWZ:
3611                            case PPC_63_FNEG:
3612                            case PPC_63_FMR:
3613                                    switch (xo) {
3614                                    case PPC_63_FRSP:   ic->f = instr(frsp); break;
3615                                    case PPC_63_FCTIWZ: ic->f = instr(fctiwz);break;
3616                                    case PPC_63_FNEG:   ic->f = instr(fneg); break;
3617                                    case PPC_63_FMR:    ic->f = instr(fmr); break;
3618                                    }
3619                                    ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rb]);
3620                                    ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3621                                    break;
3622                            case PPC_63_MFFS:
3623                                    ic->f = instr(mffs);
3624                                    ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3625                                    break;
3626                            case PPC_63_MTFSF:
3627                                    ic->f = instr(mtfsf);
3628                                    ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rb]);
3629                                    ic->arg[1] = 0;
3630                                    for (bi=7; bi>=0; bi--) {
3631                                            ic->arg[1] <<= 8;
3632                                            if (iword & (1 << (17+bi)))
3633                                                    ic->arg[1] |= 0xf;
3634                                    }
3635                                    break;
3636                            default:goto bad;
3637                            }
3638                  }                  }
3639                  break;                  break;
3640    

Legend:
Removed from v.18  
changed lines
  Added in v.22

  ViewVC Help
Powered by ViewVC 1.1.26