/[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 19 by dpavlin, Mon Oct 8 16:19:11 2007 UTC revision 20 by dpavlin, Mon Oct 8 16:19:23 2007 UTC
# 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.44 2005/11/24 01:31:54 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    
50  /*  /*
# Line 53  X(nop) Line 60  X(nop)
60   */   */
61  X(invalid)  X(invalid)
62  {  {
63          fatal("INTERNAL ERROR\n");          fatal("PPC: invalid(): INTERNAL ERROR\n");
64          exit(1);          exit(1);
65  }  }
66    
# Line 98  X(addic) Line 105  X(addic)
105          /*  TODO/NOTE: Only for 32-bit mode, so far!  */          /*  TODO/NOTE: Only for 32-bit mode, so far!  */
106          uint64_t tmp = (uint32_t)reg(ic->arg[0]);          uint64_t tmp = (uint32_t)reg(ic->arg[0]);
107          uint64_t tmp2 = tmp;          uint64_t tmp2 = tmp;
108          cpu->cd.ppc.xer &= ~PPC_XER_CA;          cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
109          tmp2 += (uint32_t)ic->arg[1];          tmp2 += (uint32_t)ic->arg[1];
110          if ((tmp2 >> 32) != (tmp >> 32))          if ((tmp2 >> 32) != (tmp >> 32))
111                  cpu->cd.ppc.xer |= PPC_XER_CA;                  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
112          reg(ic->arg[2]) = (uint32_t)tmp2;          reg(ic->arg[2]) = (uint32_t)tmp2;
113  }  }
114    
# Line 116  X(addic) Line 123  X(addic)
123  X(subfic)  X(subfic)
124  {  {
125          MODE_uint_t tmp = (int64_t)(int32_t)ic->arg[1];          MODE_uint_t tmp = (int64_t)(int32_t)ic->arg[1];
126          cpu->cd.ppc.xer &= ~PPC_XER_CA;          cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
127          if (tmp >= reg(ic->arg[0]))          if (tmp >= reg(ic->arg[0]))
128                  cpu->cd.ppc.xer |= PPC_XER_CA;                  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
129          reg(ic->arg[2]) = tmp - reg(ic->arg[0]);          reg(ic->arg[2]) = tmp - reg(ic->arg[0]);
130  }  }
131    
# Line 135  X(addic_dot) Line 142  X(addic_dot)
142          /*  TODO/NOTE: Only for 32-bit mode, so far!  */          /*  TODO/NOTE: Only for 32-bit mode, so far!  */
143          uint64_t tmp = (uint32_t)reg(ic->arg[0]);          uint64_t tmp = (uint32_t)reg(ic->arg[0]);
144          uint64_t tmp2 = tmp;          uint64_t tmp2 = tmp;
145          cpu->cd.ppc.xer &= ~PPC_XER_CA;          cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
146          tmp2 += (uint32_t)ic->arg[1];          tmp2 += (uint32_t)ic->arg[1];
147          if ((tmp2 >> 32) != (tmp >> 32))          if ((tmp2 >> 32) != (tmp >> 32))
148                  cpu->cd.ppc.xer |= PPC_XER_CA;                  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
149          reg(ic->arg[2]) = (uint32_t)tmp2;          reg(ic->arg[2]) = (uint32_t)tmp2;
150          update_cr0(cpu, (uint32_t)tmp2);          update_cr0(cpu, (uint32_t)tmp2);
151  }  }
# Line 148  X(addic_dot) Line 155  X(addic_dot)
155   *  bclr:  Branch Conditional to Link Register   *  bclr:  Branch Conditional to Link Register
156   *   *
157   *  arg[0] = bo   *  arg[0] = bo
158   *  arg[1] = bi   *  arg[1] = 31 - bi
159   *  arg[2] = bh   *  arg[2] = bh
160   */   */
161  X(bclr)  X(bclr)
162  {  {
163          int bo = ic->arg[0], bi = ic->arg[1]  /* , bh = ic->arg[2]  */;          int bo = ic->arg[0], bi31m = ic->arg[1]  /* , bh = ic->arg[2]  */;
164          int ctr_ok, cond_ok;          int ctr_ok, cond_ok;
165          uint64_t old_pc = cpu->pc;          uint64_t old_pc = cpu->pc;
166          MODE_uint_t tmp, addr = cpu->cd.ppc.lr;          MODE_uint_t tmp, addr = cpu->cd.ppc.spr[SPR_LR];
167          if (!(bo & 4))          if (!(bo & 4))
168                  cpu->cd.ppc.ctr --;                  cpu->cd.ppc.spr[SPR_CTR] --;
169          ctr_ok = (bo >> 2) & 1;          ctr_ok = (bo >> 2) & 1;
170          tmp = cpu->cd.ppc.ctr;          tmp = cpu->cd.ppc.spr[SPR_CTR];
171          ctr_ok |= ( (tmp != 0) ^ ((bo >> 1) & 1) );          ctr_ok |= ( (tmp != 0) ^ ((bo >> 1) & 1) );
172          cond_ok = (bo >> 4) & 1;          cond_ok = (bo >> 4) & 1;
173          cond_ok |= ( ((bo >> 3) & 1) == ((cpu->cd.ppc.cr >> (31-bi)) & 1) );          cond_ok |= ( ((bo >> 3) & 1) == ((cpu->cd.ppc.cr >> bi31m) & 1) );
174          if (ctr_ok && cond_ok) {          if (ctr_ok && cond_ok) {
175                  uint64_t mask_within_page =                  uint64_t mask_within_page =
176                      ((PPC_IC_ENTRIES_PER_PAGE-1) << PPC_INSTR_ALIGNMENT_SHIFT)                      ((PPC_IC_ENTRIES_PER_PAGE-1) << PPC_INSTR_ALIGNMENT_SHIFT)
# Line 184  X(bclr) Line 191  X(bclr)
191                  }                  }
192          }          }
193  }  }
194    X(bclr_20)
195    {
196            cpu->pc = cpu->cd.ppc.spr[SPR_LR];
197            DYNTRANS_PC_TO_POINTERS(cpu);
198    }
199  X(bclr_l)  X(bclr_l)
200  {  {
201          uint64_t low_pc, old_pc = cpu->pc;          uint64_t low_pc, old_pc = cpu->pc;
202          int bo = ic->arg[0], bi = ic->arg[1]  /* , bh = ic->arg[2]  */;          int bo = ic->arg[0], bi31m = ic->arg[1]  /* , bh = ic->arg[2]  */;
203          int ctr_ok, cond_ok;          int ctr_ok, cond_ok;
204          MODE_uint_t tmp, addr = cpu->cd.ppc.lr;          MODE_uint_t tmp, addr = cpu->cd.ppc.spr[SPR_LR];
205          if (!(bo & 4))          if (!(bo & 4))
206                  cpu->cd.ppc.ctr --;                  cpu->cd.ppc.spr[SPR_CTR] --;
207          ctr_ok = (bo >> 2) & 1;          ctr_ok = (bo >> 2) & 1;
208          tmp = cpu->cd.ppc.ctr;          tmp = cpu->cd.ppc.spr[SPR_CTR];
209          ctr_ok |= ( (tmp != 0) ^ ((bo >> 1) & 1) );          ctr_ok |= ( (tmp != 0) ^ ((bo >> 1) & 1) );
210          cond_ok = (bo >> 4) & 1;          cond_ok = (bo >> 4) & 1;
211          cond_ok |= ( ((bo >> 3) & 1) == ((cpu->cd.ppc.cr >> (31-bi)) & 1) );          cond_ok |= ( ((bo >> 3) & 1) == ((cpu->cd.ppc.cr >> bi31m) & 1) );
212    
213          /*  Calculate return PC:  */          /*  Calculate return PC:  */
214          low_pc = ((size_t)cpu->cd.ppc.next_ic - (size_t)          low_pc = ((size_t)ic - (size_t)
215              cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);              cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call) + 1;
216          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) << 2);
217          cpu->cd.ppc.lr += (low_pc << 2);          cpu->cd.ppc.spr[SPR_LR] += (low_pc << 2);
218    
219          if (ctr_ok && cond_ok) {          if (ctr_ok && cond_ok) {
220                  uint64_t mask_within_page =                  uint64_t mask_within_page =
# Line 232  X(bclr_l) Line 244  X(bclr_l)
244   *  bcctr:  Branch Conditional to Count register   *  bcctr:  Branch Conditional to Count register
245   *   *
246   *  arg[0] = bo   *  arg[0] = bo
247   *  arg[1] = bi   *  arg[1] = 31 - bi
248   *  arg[2] = bh   *  arg[2] = bh
249   */   */
250  X(bcctr)  X(bcctr)
251  {  {
252          int bo = ic->arg[0], bi = ic->arg[1]  /* , bh = ic->arg[2]  */;          int bo = ic->arg[0], bi31m = ic->arg[1]  /* , bh = ic->arg[2]  */;
253          uint64_t old_pc = cpu->pc;          uint64_t old_pc = cpu->pc;
254          MODE_uint_t addr = cpu->cd.ppc.ctr;          MODE_uint_t addr = cpu->cd.ppc.spr[SPR_CTR];
255          int cond_ok = (bo >> 4) & 1;          int cond_ok = (bo >> 4) & 1;
256          cond_ok |= ( ((bo >> 3) & 1) == ((cpu->cd.ppc.cr >> (31-bi)) & 1) );          cond_ok |= ( ((bo >> 3) & 1) == ((cpu->cd.ppc.cr >> bi31m) & 1) );
257          if (cond_ok) {          if (cond_ok) {
258                  uint64_t mask_within_page =                  uint64_t mask_within_page =
259                      ((PPC_IC_ENTRIES_PER_PAGE-1) << PPC_INSTR_ALIGNMENT_SHIFT)                      ((PPC_IC_ENTRIES_PER_PAGE-1) << PPC_INSTR_ALIGNMENT_SHIFT)
# Line 265  X(bcctr) Line 277  X(bcctr)
277  X(bcctr_l)  X(bcctr_l)
278  {  {
279          uint64_t low_pc, old_pc = cpu->pc;          uint64_t low_pc, old_pc = cpu->pc;
280          int bo = ic->arg[0], bi = ic->arg[1]  /* , bh = ic->arg[2]  */;          int bo = ic->arg[0], bi31m = ic->arg[1]  /* , bh = ic->arg[2]  */;
281          MODE_uint_t addr = cpu->cd.ppc.ctr;          MODE_uint_t addr = cpu->cd.ppc.spr[SPR_CTR];
282          int cond_ok = (bo >> 4) & 1;          int cond_ok = (bo >> 4) & 1;
283          cond_ok |= ( ((bo >> 3) & 1) == ((cpu->cd.ppc.cr >> (31-bi)) & 1) );          cond_ok |= ( ((bo >> 3) & 1) == ((cpu->cd.ppc.cr >> bi31m) & 1) );
284    
285          /*  Calculate return PC:  */          /*  Calculate return PC:  */
286          low_pc = ((size_t)cpu->cd.ppc.next_ic - (size_t)          low_pc = ((size_t)ic - (size_t)
287              cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);              cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call) + 1;
288          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) << 2);
289          cpu->cd.ppc.lr += (low_pc << 2);          cpu->cd.ppc.spr[SPR_LR] += (low_pc << 2);
290    
291          if (cond_ok) {          if (cond_ok) {
292                  uint64_t mask_within_page =                  uint64_t mask_within_page =
# Line 317  X(b) Line 329  X(b)
329          /*  Find the new physical page and update the translation pointers:  */          /*  Find the new physical page and update the translation pointers:  */
330          DYNTRANS_PC_TO_POINTERS(cpu);          DYNTRANS_PC_TO_POINTERS(cpu);
331  }  }
332    X(ba)
333    {
334            cpu->pc = (int32_t)ic->arg[0];
335            DYNTRANS_PC_TO_POINTERS(cpu);
336    }
337    
338    
339  /*  /*
# Line 331  X(bc) Line 348  X(bc)
348          MODE_uint_t tmp;          MODE_uint_t tmp;
349          int ctr_ok, cond_ok, bi = ic->arg[2], bo = ic->arg[1];          int ctr_ok, cond_ok, bi = ic->arg[2], bo = ic->arg[1];
350          if (!(bo & 4))          if (!(bo & 4))
351                  cpu->cd.ppc.ctr --;                  cpu->cd.ppc.spr[SPR_CTR] --;
352          ctr_ok = (bo >> 2) & 1;          ctr_ok = (bo >> 2) & 1;
353          tmp = cpu->cd.ppc.ctr;          tmp = cpu->cd.ppc.spr[SPR_CTR];
354            ctr_ok |= ( (tmp != 0) ^ ((bo >> 1) & 1) );
355            cond_ok = (bo >> 4) & 1;
356            cond_ok |= ( ((bo >> 3) & 1) ==
357                ((cpu->cd.ppc.cr >> (31-bi)) & 1)  );
358            if (ctr_ok && cond_ok)
359                    instr(b)(cpu,ic);
360    }
361    X(bcl)
362    {
363            MODE_uint_t tmp;
364            int ctr_ok, cond_ok, bi = ic->arg[2], bo = ic->arg[1], low_pc;
365    
366            /*  Calculate LR:  */
367            low_pc = ((size_t)ic - (size_t)
368                cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call) + 1;
369            cpu->cd.ppc.spr[SPR_LR] = cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2);
370            cpu->cd.ppc.spr[SPR_LR] += (low_pc << 2);
371    
372            if (!(bo & 4))
373                    cpu->cd.ppc.spr[SPR_CTR] --;
374            ctr_ok = (bo >> 2) & 1;
375            tmp = cpu->cd.ppc.spr[SPR_CTR];
376          ctr_ok |= ( (tmp != 0) ^ ((bo >> 1) & 1) );          ctr_ok |= ( (tmp != 0) ^ ((bo >> 1) & 1) );
377          cond_ok = (bo >> 4) & 1;          cond_ok = (bo >> 4) & 1;
378          cond_ok |= ( ((bo >> 3) & 1) ==          cond_ok |= ( ((bo >> 3) & 1) ==
# Line 366  X(bc_samepage) Line 405  X(bc_samepage)
405          MODE_uint_t tmp;          MODE_uint_t tmp;
406          int ctr_ok, cond_ok, bi = ic->arg[2], bo = ic->arg[1];          int ctr_ok, cond_ok, bi = ic->arg[2], bo = ic->arg[1];
407          if (!(bo & 4))          if (!(bo & 4))
408                  cpu->cd.ppc.ctr --;                  cpu->cd.ppc.spr[SPR_CTR] --;
409          ctr_ok = (bo >> 2) & 1;          ctr_ok = (bo >> 2) & 1;
410          tmp = cpu->cd.ppc.ctr;          tmp = cpu->cd.ppc.spr[SPR_CTR];
411          ctr_ok |= ( (tmp != 0) ^ ((bo >> 1) & 1) );          ctr_ok |= ( (tmp != 0) ^ ((bo >> 1) & 1) );
412          cond_ok = (bo >> 4) & 1;          cond_ok = (bo >> 4) & 1;
413          cond_ok |= ( ((bo >> 3) & 1) ==          cond_ok |= ( ((bo >> 3) & 1) ==
414              ((cpu->cd.ppc.cr >> (31-bi)) & 1)  );              ((cpu->cd.ppc.cr >> (31-bi)) & 1)  );
415          if (ctr_ok && cond_ok)          if (ctr_ok && cond_ok)
416                  instr(b_samepage)(cpu,ic);                  cpu->cd.ppc.next_ic = (struct ppc_instr_call *) ic->arg[0];
417    }
418    X(bc_samepage_no_ctr)
419    {
420            int cond_ok, bi = ic->arg[2], bo = ic->arg[1];
421            cond_ok = (bo >> 4) & 1;
422            cond_ok |= ( ((bo >> 3) & 1) == ((cpu->cd.ppc.cr >> (31-bi)) & 1)  );
423            if (cond_ok)
424                    cpu->cd.ppc.next_ic = (struct ppc_instr_call *) ic->arg[0];
425    }
426    X(bcl_samepage)
427    {
428            MODE_uint_t tmp;
429            int ctr_ok, cond_ok, bi = ic->arg[2], bo = ic->arg[1], low_pc;
430    
431            /*  Calculate LR:  */
432            low_pc = ((size_t)ic - (size_t)
433                cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call) + 1;
434            cpu->cd.ppc.spr[SPR_LR] = cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2);
435            cpu->cd.ppc.spr[SPR_LR] += (low_pc << 2);
436    
437            if (!(bo & 4))
438                    cpu->cd.ppc.spr[SPR_CTR] --;
439            ctr_ok = (bo >> 2) & 1;
440            tmp = cpu->cd.ppc.spr[SPR_CTR];
441            ctr_ok |= ( (tmp != 0) ^ ((bo >> 1) & 1) );
442            cond_ok = (bo >> 4) & 1;
443            cond_ok |= ( ((bo >> 3) & 1) ==
444                ((cpu->cd.ppc.cr >> (31-bi)) & 1)  );
445            if (ctr_ok && cond_ok)
446                    cpu->cd.ppc.next_ic = (struct ppc_instr_call *) ic->arg[0];
447  }  }
448    
449    
# Line 388  X(bl) Line 457  X(bl)
457          uint32_t low_pc;          uint32_t low_pc;
458    
459          /*  Calculate LR:  */          /*  Calculate LR:  */
460          low_pc = ((size_t)cpu->cd.ppc.next_ic - (size_t)          low_pc = ((size_t)ic - (size_t)
461              cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);              cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call) + 1;
462          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) << 2);
463          cpu->cd.ppc.lr += (low_pc << 2);          cpu->cd.ppc.spr[SPR_LR] += (low_pc << 2);
464    
465          /*  Calculate new PC from this instruction + arg[0]  */          /*  Calculate new PC from this instruction + arg[0]  */
466          low_pc = ((size_t)ic - (size_t)          low_pc = ((size_t)ic - (size_t)
# Line 403  X(bl) Line 472  X(bl)
472          /*  Find the new physical page and update the translation pointers:  */          /*  Find the new physical page and update the translation pointers:  */
473          DYNTRANS_PC_TO_POINTERS(cpu);          DYNTRANS_PC_TO_POINTERS(cpu);
474  }  }
475    X(bla)
476    {
477            uint32_t low_pc = ((size_t)ic - (size_t)
478                cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call) + 1;
479            cpu->cd.ppc.spr[SPR_LR] = cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2);
480            cpu->cd.ppc.spr[SPR_LR] += (low_pc << 2);
481            cpu->pc = (int32_t)ic->arg[0];
482            DYNTRANS_PC_TO_POINTERS(cpu);
483    }
484    
485    
486  /*  /*
# Line 415  X(bl_trace) Line 493  X(bl_trace)
493          uint32_t low_pc;          uint32_t low_pc;
494    
495          /*  Calculate LR:  */          /*  Calculate LR:  */
496          low_pc = ((size_t)cpu->cd.ppc.next_ic - (size_t)          low_pc = ((size_t)ic - (size_t)
497              cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);              cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call) + 1;
498          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) << 2);
499          cpu->cd.ppc.lr += (low_pc << 2);          cpu->cd.ppc.spr[SPR_LR] += (low_pc << 2);
500    
501          /*  Calculate new PC from this instruction + arg[0]  */          /*  Calculate new PC from this instruction + arg[0]  */
502          low_pc = ((size_t)ic - (size_t)          low_pc = ((size_t)ic - (size_t)
# Line 432  X(bl_trace) Line 510  X(bl_trace)
510          /*  Find the new physical page and update the translation pointers:  */          /*  Find the new physical page and update the translation pointers:  */
511          DYNTRANS_PC_TO_POINTERS(cpu);          DYNTRANS_PC_TO_POINTERS(cpu);
512  }  }
513    X(bla_trace)
514    {
515            uint32_t low_pc = ((size_t)ic - (size_t)
516                cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call) + 1;
517            cpu->cd.ppc.spr[SPR_LR] = cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2);
518            cpu->cd.ppc.spr[SPR_LR] += (low_pc << 2);
519            cpu->pc = (int32_t)ic->arg[0];
520            cpu_functioncall_trace(cpu, cpu->pc);
521            DYNTRANS_PC_TO_POINTERS(cpu);
522    }
523    
524    
525  /*  /*
# Line 446  X(bl_samepage) Line 534  X(bl_samepage)
534          /*  Calculate LR:  */          /*  Calculate LR:  */
535          low_pc = ((size_t)ic - (size_t)          low_pc = ((size_t)ic - (size_t)
536              cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call) + 1;              cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call) + 1;
537          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) << 2);
538          cpu->cd.ppc.lr += (low_pc << 2);          cpu->cd.ppc.spr[SPR_LR] += (low_pc << 2);
539    
540          cpu->cd.ppc.next_ic = (struct ppc_instr_call *) ic->arg[0];          cpu->cd.ppc.next_ic = (struct ppc_instr_call *) ic->arg[0];
541  }  }
# Line 463  X(bl_samepage_trace) Line 551  X(bl_samepage_trace)
551          uint32_t low_pc;          uint32_t low_pc;
552    
553          /*  Calculate LR:  */          /*  Calculate LR:  */
554          low_pc = ((size_t)cpu->cd.ppc.next_ic - (size_t)          low_pc = ((size_t)ic - (size_t)
555              cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);              cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call) + 1;
556          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) << 2);
557          cpu->cd.ppc.lr += (low_pc << 2);          cpu->cd.ppc.spr[SPR_LR] += (low_pc << 2);
558    
559          cpu->cd.ppc.next_ic = (struct ppc_instr_call *) ic->arg[0];          cpu->cd.ppc.next_ic = (struct ppc_instr_call *) ic->arg[0];
560    
# Line 503  X(cntlzw) Line 591  X(cntlzw)
591   *   *
592   *  arg[0] = ptr to ra   *  arg[0] = ptr to ra
593   *  arg[1] = ptr to rb   *  arg[1] = ptr to rb
594   *  arg[2] = bf   *  arg[2] = 28 - 4*bf
595   */   */
596  X(cmpd)  X(cmpd)
597  {  {
598          int64_t tmp = reg(ic->arg[0]), tmp2 = reg(ic->arg[1]);          int64_t tmp = reg(ic->arg[0]), tmp2 = reg(ic->arg[1]);
599          int bf = ic->arg[2], c;          int bf_shift = ic->arg[2], c;
600          if (tmp < tmp2)          if (tmp < tmp2)
601                  c = 8;                  c = 8;
602          else if (tmp > tmp2)          else if (tmp > tmp2)
603                  c = 4;                  c = 4;
604          else          else
605                  c = 2;                  c = 2;
606          c |= ((cpu->cd.ppc.xer >> 31) & 1);  /*  SO bit, copied from XER  */          /*  SO bit, copied from XER  */
607          cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));          c |= ((cpu->cd.ppc.spr[SPR_XER] >> 31) & 1);
608          cpu->cd.ppc.cr |= (c << (28 - 4*bf));          cpu->cd.ppc.cr &= ~(0xf << bf_shift);
609            cpu->cd.ppc.cr |= (c << bf_shift);
610  }  }
611    
612    
# Line 526  X(cmpd) Line 615  X(cmpd)
615   *   *
616   *  arg[0] = ptr to ra   *  arg[0] = ptr to ra
617   *  arg[1] = ptr to rb   *  arg[1] = ptr to rb
618   *  arg[2] = bf   *  arg[2] = 28 - 4*bf
619   */   */
620  X(cmpld)  X(cmpld)
621  {  {
622          uint64_t tmp = reg(ic->arg[0]), tmp2 = reg(ic->arg[1]);          uint64_t tmp = reg(ic->arg[0]), tmp2 = reg(ic->arg[1]);
623          int bf = ic->arg[2], c;          int bf_shift = ic->arg[2], c;
624          if (tmp < tmp2)          if (tmp < tmp2)
625                  c = 8;                  c = 8;
626          else if (tmp > tmp2)          else if (tmp > tmp2)
627                  c = 4;                  c = 4;
628          else          else
629                  c = 2;                  c = 2;
630          c |= ((cpu->cd.ppc.xer >> 31) & 1);  /*  SO bit, copied from XER  */          /*  SO bit, copied from XER  */
631          cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));          c |= ((cpu->cd.ppc.spr[SPR_XER] >> 31) & 1);
632          cpu->cd.ppc.cr |= (c << (28 - 4*bf));          cpu->cd.ppc.cr &= ~(0xf << bf_shift);
633            cpu->cd.ppc.cr |= (c << bf_shift);
634  }  }
635    
636    
# Line 549  X(cmpld) Line 639  X(cmpld)
639   *   *
640   *  arg[0] = ptr to ra   *  arg[0] = ptr to ra
641   *  arg[1] = int32_t imm   *  arg[1] = int32_t imm
642   *  arg[2] = bf   *  arg[2] = 28 - 4*bf
643   */   */
644  X(cmpdi)  X(cmpdi)
645  {  {
646          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];
647          int bf = ic->arg[2], c;          int bf_shift = ic->arg[2], c;
648          if (tmp < imm)          if (tmp < imm)
649                  c = 8;                  c = 8;
650          else if (tmp > imm)          else if (tmp > imm)
651                  c = 4;                  c = 4;
652          else          else
653                  c = 2;                  c = 2;
654          c |= ((cpu->cd.ppc.xer >> 31) & 1);  /*  SO bit, copied from XER  */          /*  SO bit, copied from XER  */
655          cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));          c |= ((cpu->cd.ppc.spr[SPR_XER] >> 31) & 1);
656          cpu->cd.ppc.cr |= (c << (28 - 4*bf));          cpu->cd.ppc.cr &= ~(0xf << bf_shift);
657            cpu->cd.ppc.cr |= (c << bf_shift);
658  }  }
659    
660    
# Line 572  X(cmpdi) Line 663  X(cmpdi)
663   *   *
664   *  arg[0] = ptr to ra   *  arg[0] = ptr to ra
665   *  arg[1] = int32_t imm   *  arg[1] = int32_t imm
666   *  arg[2] = bf   *  arg[2] = 28 - 4*bf
667   */   */
668  X(cmpldi)  X(cmpldi)
669  {  {
670          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];
671          int bf = ic->arg[2], c;          int bf_shift = ic->arg[2], c;
672          if (tmp < imm)          if (tmp < imm)
673                  c = 8;                  c = 8;
674          else if (tmp > imm)          else if (tmp > imm)
675                  c = 4;                  c = 4;
676          else          else
677                  c = 2;                  c = 2;
678          c |= ((cpu->cd.ppc.xer >> 31) & 1);  /*  SO bit, copied from XER  */          /*  SO bit, copied from XER  */
679          cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));          c |= ((cpu->cd.ppc.spr[SPR_XER] >> 31) & 1);
680          cpu->cd.ppc.cr |= (c << (28 - 4*bf));          cpu->cd.ppc.cr &= ~(0xf << bf_shift);
681            cpu->cd.ppc.cr |= (c << bf_shift);
682  }  }
683    
684    
# Line 595  X(cmpldi) Line 687  X(cmpldi)
687   *   *
688   *  arg[0] = ptr to ra   *  arg[0] = ptr to ra
689   *  arg[1] = ptr to rb   *  arg[1] = ptr to rb
690   *  arg[2] = bf   *  arg[2] = 28 - 4*bf
691   */   */
692  X(cmpw)  X(cmpw)
693  {  {
694          int32_t tmp = reg(ic->arg[0]), tmp2 = reg(ic->arg[1]);          int32_t tmp = reg(ic->arg[0]), tmp2 = reg(ic->arg[1]);
695          int bf = ic->arg[2], c;          int bf_shift = ic->arg[2], c;
696          if (tmp < tmp2)          if (tmp < tmp2)
697                  c = 8;                  c = 8;
698          else if (tmp > tmp2)          else if (tmp > tmp2)
699                  c = 4;                  c = 4;
700          else          else
701                  c = 2;                  c = 2;
702          c |= ((cpu->cd.ppc.xer >> 31) & 1);  /*  SO bit, copied from XER  */          /*  SO bit, copied from XER  */
703          cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));          c |= ((cpu->cd.ppc.spr[SPR_XER] >> 31) & 1);
704          cpu->cd.ppc.cr |= (c << (28 - 4*bf));          cpu->cd.ppc.cr &= ~(0xf << bf_shift);
705            cpu->cd.ppc.cr |= (c << bf_shift);
706  }  }
707    
708    
# Line 618  X(cmpw) Line 711  X(cmpw)
711   *   *
712   *  arg[0] = ptr to ra   *  arg[0] = ptr to ra
713   *  arg[1] = ptr to rb   *  arg[1] = ptr to rb
714   *  arg[2] = bf   *  arg[2] = 28 - 4*bf
715   */   */
716  X(cmplw)  X(cmplw)
717  {  {
718          uint32_t tmp = reg(ic->arg[0]), tmp2 = reg(ic->arg[1]);          uint32_t tmp = reg(ic->arg[0]), tmp2 = reg(ic->arg[1]);
719          int bf = ic->arg[2], c;          int bf_shift = ic->arg[2], c;
720          if (tmp < tmp2)          if (tmp < tmp2)
721                  c = 8;                  c = 8;
722          else if (tmp > tmp2)          else if (tmp > tmp2)
723                  c = 4;                  c = 4;
724          else          else
725                  c = 2;                  c = 2;
726          c |= ((cpu->cd.ppc.xer >> 31) & 1);  /*  SO bit, copied from XER  */          /*  SO bit, copied from XER  */
727          cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));          c |= ((cpu->cd.ppc.spr[SPR_XER] >> 31) & 1);
728          cpu->cd.ppc.cr |= (c << (28 - 4*bf));          cpu->cd.ppc.cr &= ~(0xf << bf_shift);
729            cpu->cd.ppc.cr |= (c << bf_shift);
730  }  }
731    
732    
# Line 641  X(cmplw) Line 735  X(cmplw)
735   *   *
736   *  arg[0] = ptr to ra   *  arg[0] = ptr to ra
737   *  arg[1] = int32_t imm   *  arg[1] = int32_t imm
738   *  arg[2] = bf   *  arg[2] = 28 - 4*bf
739   */   */
740  X(cmpwi)  X(cmpwi)
741  {  {
742          int32_t tmp = reg(ic->arg[0]), imm = ic->arg[1];          int32_t tmp = reg(ic->arg[0]), imm = ic->arg[1];
743          int bf = ic->arg[2], c;          int bf_shift = ic->arg[2], c;
744          if (tmp < imm)          if (tmp < imm)
745                  c = 8;                  c = 8;
746          else if (tmp > imm)          else if (tmp > imm)
747                  c = 4;                  c = 4;
748          else          else
749                  c = 2;                  c = 2;
750          c |= ((cpu->cd.ppc.xer >> 31) & 1);  /*  SO bit, copied from XER  */          /*  SO bit, copied from XER  */
751          cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));          c |= ((cpu->cd.ppc.spr[SPR_XER] >> 31) & 1);
752          cpu->cd.ppc.cr |= (c << (28 - 4*bf));          cpu->cd.ppc.cr &= ~(0xf << bf_shift);
753            cpu->cd.ppc.cr |= (c << bf_shift);
754  }  }
755    
756    
# Line 664  X(cmpwi) Line 759  X(cmpwi)
759   *   *
760   *  arg[0] = ptr to ra   *  arg[0] = ptr to ra
761   *  arg[1] = int32_t imm   *  arg[1] = int32_t imm
762   *  arg[2] = bf   *  arg[2] = 28 - 4*bf
763   */   */
764  X(cmplwi)  X(cmplwi)
765  {  {
766          uint32_t tmp = reg(ic->arg[0]), imm = ic->arg[1];          uint32_t tmp = reg(ic->arg[0]), imm = ic->arg[1];
767          int bf = ic->arg[2], c;          int bf_shift = ic->arg[2], c;
768          if (tmp < imm)          if (tmp < imm)
769                  c = 8;                  c = 8;
770          else if (tmp > imm)          else if (tmp > imm)
771                  c = 4;                  c = 4;
772          else          else
773                  c = 2;                  c = 2;
774          c |= ((cpu->cd.ppc.xer >> 31) & 1);  /*  SO bit, copied from XER  */          /*  SO bit, copied from XER  */
775          cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));          c |= ((cpu->cd.ppc.spr[SPR_XER] >> 31) & 1);
776          cpu->cd.ppc.cr |= (c << (28 - 4*bf));          cpu->cd.ppc.cr &= ~(0xf << bf_shift);
777            cpu->cd.ppc.cr |= (c << bf_shift);
778  }  }
779    
780    
# Line 695  X(dcbz) Line 791  X(dcbz)
791          int cacheline_size = 1 << cpu->cd.ppc.cpu_type.dlinesize;          int cacheline_size = 1 << cpu->cd.ppc.cpu_type.dlinesize;
792          int cleared = 0;          int cleared = 0;
793    
794            /*  Synchronize the PC first:  */
795            cpu->pc = (cpu->pc & ~0xfff) + ic->arg[2];
796    
797          addr &= ~(cacheline_size - 1);          addr &= ~(cacheline_size - 1);
798          memset(cacheline, 0, sizeof(cacheline));          memset(cacheline, 0, sizeof(cacheline));
799    
800            /*  TODO: Don't use memory_rw() unless it is necessary.  */
801          while (cleared < cacheline_size) {          while (cleared < cacheline_size) {
802                  int to_clear = cacheline_size < sizeof(cacheline)?                  int to_clear = cacheline_size < sizeof(cacheline)?
803                      cacheline_size : sizeof(cacheline);                      cacheline_size : sizeof(cacheline);
804                  if (cpu->memory_rw(cpu, cpu->mem, addr, cacheline, to_clear,                  if (cpu->memory_rw(cpu, cpu->mem, addr, cacheline, to_clear,
805                      MEM_WRITE, CACHE_DATA) != MEMORY_ACCESS_OK) {                      MEM_WRITE, CACHE_DATA) != MEMORY_ACCESS_OK) {
806                          fatal("dcbz: error: TODO\n");                          /*  exception  */
807                          exit(1);                          return;
808                  }                  }
809    
810                  cleared += to_clear;                  cleared += to_clear;
# Line 714  X(dcbz) Line 814  X(dcbz)
814    
815    
816  /*  /*
817     *  mtfsf:  Copy FPR into the FPSCR.
818     *
819     *  arg[0] = ptr to frb
820     *  arg[1] = mask
821     */
822    X(mtfsf)
823    {
824            /*  Sync. PC in case of an exception:  */
825            uint64_t low_pc = ((size_t)ic - (size_t)
826                cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
827            cpu->pc = (cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2))
828                + (low_pc << 2);
829            if (!(cpu->cd.ppc.msr & PPC_MSR_FP)) {
830                    ppc_exception(cpu, PPC_EXCEPTION_FPU);
831                    return;
832            }
833    
834            cpu->cd.ppc.fpscr &= ~ic->arg[1];
835            cpu->cd.ppc.fpscr |= (ic->arg[1] & (*(uint64_t *)ic->arg[0]));
836    }
837    
838    
839    /*
840     *  mffs:  Copy FPSCR into a FPR.
841     *
842     *  arg[0] = ptr to frt
843     */
844    X(mffs)
845    {
846            /*  Sync. PC in case of an exception:  */
847            uint64_t low_pc = ((size_t)ic - (size_t)
848                cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
849            cpu->pc = (cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2)) + (low_pc<<2);
850            if (!(cpu->cd.ppc.msr & PPC_MSR_FP)) {
851                    ppc_exception(cpu, PPC_EXCEPTION_FPU);
852                    return;
853            }
854    
855            (*(uint64_t *)ic->arg[0]) = cpu->cd.ppc.fpscr;
856    }
857    
858    
859    /*
860   *  fmr:  Floating-point Move   *  fmr:  Floating-point Move
861   *   *
862   *  arg[0] = ptr to frb   *  arg[0] = ptr to frb
# Line 721  X(dcbz) Line 864  X(dcbz)
864   */   */
865  X(fmr)  X(fmr)
866  {  {
867            /*  Sync. PC in case of an exception:  */
868            uint64_t low_pc = ((size_t)ic - (size_t)
869                cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
870            cpu->pc = (cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2)) + (low_pc<<2);
871            if (!(cpu->cd.ppc.msr & PPC_MSR_FP)) {
872                    ppc_exception(cpu, PPC_EXCEPTION_FPU);
873                    return;
874            }
875    
876          *(uint64_t *)ic->arg[1] = *(uint64_t *)ic->arg[0];          *(uint64_t *)ic->arg[1] = *(uint64_t *)ic->arg[0];
877  }  }
878    
879    
880  /*  /*
881     *  fneg:  Floating-point Negate
882     *
883     *  arg[0] = ptr to frb
884     *  arg[1] = ptr to frt
885     */
886    X(fneg)
887    {
888            uint64_t v;
889    
890            /*  Sync. PC in case of an exception:  */
891            uint64_t low_pc = ((size_t)ic - (size_t)
892                cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
893            cpu->pc = (cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2)) + (low_pc<<2);
894            if (!(cpu->cd.ppc.msr & PPC_MSR_FP)) {
895                    ppc_exception(cpu, PPC_EXCEPTION_FPU);
896                    return;
897            }
898    
899            v = *(uint64_t *)ic->arg[0];
900            *(uint64_t *)ic->arg[1] = v ^ 0x8000000000000000ULL;
901    }
902    
903    
904    /*
905     *  fcmpu:  Floating-point Compare Unordered
906     *
907     *  arg[0] = 28 - 4*bf  (bitfield shift)
908     *  arg[1] = ptr to fra
909     *  arg[2] = ptr to frb
910     */
911    X(fcmpu)
912    {
913            struct ieee_float_value fra, frb;
914            int bf_shift = ic->arg[0], c = 0;
915    
916            /*  Sync. PC in case of an exception:  */
917            uint64_t low_pc = ((size_t)ic - (size_t)
918                cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
919            cpu->pc = (cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2)) + (low_pc<<2);
920            if (!(cpu->cd.ppc.msr & PPC_MSR_FP)) {
921                    ppc_exception(cpu, PPC_EXCEPTION_FPU);
922                    return;
923            }
924    
925            ieee_interpret_float_value(*(uint64_t *)ic->arg[1], &fra, IEEE_FMT_D);
926            ieee_interpret_float_value(*(uint64_t *)ic->arg[2], &frb, IEEE_FMT_D);
927            if (fra.nan | frb.nan) {
928                    c = 1;
929            } else {
930                    if (fra.f < frb.f)
931                            c = 8;
932                    else if (fra.f > frb.f)
933                            c = 4;
934                    else
935                            c = 2;
936            }
937            /*  TODO: Signaling vs Quiet NaN  */
938            cpu->cd.ppc.cr &= ~(0xf << bf_shift);
939            cpu->cd.ppc.cr |= ((c&0xe) << bf_shift);
940            cpu->cd.ppc.fpscr &= ~(PPC_FPSCR_FPCC | PPC_FPSCR_VXNAN);
941            cpu->cd.ppc.fpscr |= (c << PPC_FPSCR_FPCC_SHIFT);
942    }
943    
944    
945    /*
946     *  frsp:  Floating-point Round to Single Precision
947     *
948     *  arg[0] = ptr to frb
949     *  arg[1] = ptr to frt
950     */
951    X(frsp)
952    {
953            struct ieee_float_value frb;
954            float fl = 0.0;
955            int c = 0;
956    
957            /*  Sync. PC in case of an exception:  */
958            uint64_t low_pc = ((size_t)ic - (size_t)
959                cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
960            cpu->pc = (cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2)) + (low_pc<<2);
961            if (!(cpu->cd.ppc.msr & PPC_MSR_FP)) {
962                    ppc_exception(cpu, PPC_EXCEPTION_FPU);
963                    return;
964            }
965    
966            ieee_interpret_float_value(*(uint64_t *)ic->arg[0], &frb, IEEE_FMT_D);
967            if (frb.nan) {
968                    c = 1;
969            } else {
970                    fl = frb.f;
971                    if (fl < 0.0)
972                            c = 8;
973                    else if (fl > 0.0)
974                            c = 4;
975                    else
976                            c = 2;
977            }
978            /*  TODO: Signaling vs Quiet NaN  */
979            cpu->cd.ppc.fpscr &= ~(PPC_FPSCR_FPCC | PPC_FPSCR_VXNAN);
980            cpu->cd.ppc.fpscr |= (c << PPC_FPSCR_FPCC_SHIFT);
981            (*(uint64_t *)ic->arg[1]) =
982                ieee_store_float_value(fl, IEEE_FMT_D, frb.nan);
983    }
984    
985    
986    /*
987     *  fctiwz:  Floating-point Convert to Integer Word, Round to Zero
988     *
989     *  arg[0] = ptr to frb
990     *  arg[1] = ptr to frt
991     */
992    X(fctiwz)
993    {
994            struct ieee_float_value frb;
995            int32_t res = 0;
996    
997            /*  Sync. PC in case of an exception:  */
998            uint64_t low_pc = ((size_t)ic - (size_t)
999                cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
1000            cpu->pc = (cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2)) + (low_pc<<2);
1001            if (!(cpu->cd.ppc.msr & PPC_MSR_FP)) {
1002                    ppc_exception(cpu, PPC_EXCEPTION_FPU);
1003                    return;
1004            }
1005    
1006            ieee_interpret_float_value(*(uint64_t *)ic->arg[0], &frb, IEEE_FMT_D);
1007            if (!frb.nan) {
1008                    if (frb.f >= 2147483647.0)
1009                            res = 0x7fffffff;
1010                    else if (frb.f <= -2147483648.0)
1011                            res = 0x80000000;
1012                    else
1013                            res = frb.f;
1014            }
1015            *(uint64_t *)ic->arg[1] = (uint32_t)res;
1016    }
1017    
1018    
1019    /*
1020     *  fmul:  Floating-point Multiply
1021     *
1022     *  arg[0] = ptr to frt
1023     *  arg[1] = ptr to fra
1024     *  arg[2] = ptr to frc
1025     */
1026    X(fmul)
1027    {
1028            struct ieee_float_value fra;
1029            struct ieee_float_value frc;
1030            double result = 0.0;
1031            int c, nan = 0;
1032    
1033            /*  Sync. PC in case of an exception:  */
1034            uint64_t low_pc = ((size_t)ic - (size_t)
1035                cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
1036            cpu->pc = (cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2))
1037                + (low_pc << 2);
1038            if (!(cpu->cd.ppc.msr & PPC_MSR_FP)) {
1039                    ppc_exception(cpu, PPC_EXCEPTION_FPU);
1040                    return;
1041            }
1042    
1043            ieee_interpret_float_value(*(uint64_t *)ic->arg[1], &fra, IEEE_FMT_D);
1044            ieee_interpret_float_value(*(uint64_t *)ic->arg[2], &frc, IEEE_FMT_D);
1045            if (fra.nan || frc.nan)
1046                    nan = 1;
1047            else
1048                    result = fra.f * frc.f;
1049            if (nan)
1050                    c = 1;
1051            else {
1052                    if (result < 0.0)
1053                            c = 8;
1054                    else if (result > 0.0)
1055                            c = 4;
1056                    else
1057                            c = 2;
1058            }
1059            /*  TODO: Signaling vs Quiet NaN  */
1060            cpu->cd.ppc.fpscr &= ~(PPC_FPSCR_FPCC | PPC_FPSCR_VXNAN);
1061            cpu->cd.ppc.fpscr |= (c << PPC_FPSCR_FPCC_SHIFT);
1062    
1063            (*(uint64_t *)ic->arg[0]) =
1064                ieee_store_float_value(result, IEEE_FMT_D, nan);
1065    }
1066    X(fmuls)
1067    {
1068            /*  TODO  */
1069            instr(fmul)(cpu, ic);
1070    }
1071    
1072    
1073    /*
1074     *  fmadd:  Floating-point Multiply and Add
1075     *
1076     *  arg[0] = ptr to frt
1077     *  arg[1] = ptr to fra
1078     *  arg[2] = copy of the instruction word
1079     */
1080    X(fmadd)
1081    {
1082            uint32_t iw = ic->arg[2];
1083            int b = (iw >> 11) & 31, c = (iw >> 6) & 31;
1084            struct ieee_float_value fra;
1085            struct ieee_float_value frb;
1086            struct ieee_float_value frc;
1087            double result = 0.0;
1088            int nan = 0, cc;
1089    
1090            /*  Sync. PC in case of an exception:  */
1091            uint64_t low_pc = ((size_t)ic - (size_t)
1092                cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
1093            cpu->pc = (cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2))
1094                + (low_pc << 2);
1095            if (!(cpu->cd.ppc.msr & PPC_MSR_FP)) {
1096                    ppc_exception(cpu, PPC_EXCEPTION_FPU);
1097                    return;
1098            }
1099    
1100            ieee_interpret_float_value(*(uint64_t *)ic->arg[1], &fra, IEEE_FMT_D);
1101            ieee_interpret_float_value(cpu->cd.ppc.fpr[b], &frb, IEEE_FMT_D);
1102            ieee_interpret_float_value(cpu->cd.ppc.fpr[c], &frc, IEEE_FMT_D);
1103            if (fra.nan || frb.nan || frc.nan)
1104                    nan = 1;
1105            else
1106                    result = fra.f * frc.f + frb.f;
1107            if (nan)
1108                    cc = 1;
1109            else {
1110                    if (result < 0.0)
1111                            cc = 8;
1112                    else if (result > 0.0)
1113                            cc = 4;
1114                    else
1115                            cc = 2;
1116            }
1117            /*  TODO: Signaling vs Quiet NaN  */
1118            cpu->cd.ppc.fpscr &= ~(PPC_FPSCR_FPCC | PPC_FPSCR_VXNAN);
1119            cpu->cd.ppc.fpscr |= (cc << PPC_FPSCR_FPCC_SHIFT);
1120    
1121            (*(uint64_t *)ic->arg[0]) =
1122                ieee_store_float_value(result, IEEE_FMT_D, nan);
1123    }
1124    
1125    
1126    /*
1127     *  fmsub:  Floating-point Multiply and Sub
1128     *
1129     *  arg[0] = ptr to frt
1130     *  arg[1] = ptr to fra
1131     *  arg[2] = copy of the instruction word
1132     */
1133    X(fmsub)
1134    {
1135            uint32_t iw = ic->arg[2];
1136            int b = (iw >> 11) & 31, c = (iw >> 6) & 31;
1137            struct ieee_float_value fra;
1138            struct ieee_float_value frb;
1139            struct ieee_float_value frc;
1140            double result = 0.0;
1141            int nan = 0, cc;
1142    
1143            /*  Sync. PC in case of an exception:  */
1144            uint64_t low_pc = ((size_t)ic - (size_t)
1145                cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
1146            cpu->pc = (cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2))
1147                + (low_pc << 2);
1148            if (!(cpu->cd.ppc.msr & PPC_MSR_FP)) {
1149                    ppc_exception(cpu, PPC_EXCEPTION_FPU);
1150                    return;
1151            }
1152    
1153            ieee_interpret_float_value(*(uint64_t *)ic->arg[1], &fra, IEEE_FMT_D);
1154            ieee_interpret_float_value(cpu->cd.ppc.fpr[b], &frb, IEEE_FMT_D);
1155            ieee_interpret_float_value(cpu->cd.ppc.fpr[c], &frc, IEEE_FMT_D);
1156            if (fra.nan || frb.nan || frc.nan)
1157                    nan = 1;
1158            else
1159                    result = fra.f * frc.f - frb.f;
1160            if (nan)
1161                    cc = 1;
1162            else {
1163                    if (result < 0.0)
1164                            cc = 8;
1165                    else if (result > 0.0)
1166                            cc = 4;
1167                    else
1168                            cc = 2;
1169            }
1170            /*  TODO: Signaling vs Quiet NaN  */
1171            cpu->cd.ppc.fpscr &= ~(PPC_FPSCR_FPCC | PPC_FPSCR_VXNAN);
1172            cpu->cd.ppc.fpscr |= (cc << PPC_FPSCR_FPCC_SHIFT);
1173    
1174            (*(uint64_t *)ic->arg[0]) =
1175                ieee_store_float_value(result, IEEE_FMT_D, nan);
1176    }
1177    
1178    
1179    /*
1180     *  fadd, fsub, fdiv:  Various Floating-point operationgs
1181     *
1182     *  arg[0] = ptr to fra
1183     *  arg[1] = ptr to frb
1184     *  arg[2] = ptr to frt
1185     */
1186    X(fadd)
1187    {
1188            struct ieee_float_value fra;
1189            struct ieee_float_value frb;
1190            double result = 0.0;
1191            int nan = 0, c;
1192    
1193            /*  Sync. PC in case of an exception:  */
1194            uint64_t low_pc = ((size_t)ic - (size_t)
1195                cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
1196            cpu->pc = (cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2))
1197                + (low_pc << 2);
1198            if (!(cpu->cd.ppc.msr & PPC_MSR_FP)) {
1199                    ppc_exception(cpu, PPC_EXCEPTION_FPU);
1200                    return;
1201            }
1202    
1203            ieee_interpret_float_value(*(uint64_t *)ic->arg[0], &fra, IEEE_FMT_D);
1204            ieee_interpret_float_value(*(uint64_t *)ic->arg[1], &frb, IEEE_FMT_D);
1205            if (fra.nan || frb.nan)
1206                    nan = 1;
1207            else
1208                    result = fra.f + frb.f;
1209            if (nan)
1210                    c = 1;
1211            else {
1212                    if (result < 0.0)
1213                            c = 8;
1214                    else if (result > 0.0)
1215                            c = 4;
1216                    else
1217                            c = 2;
1218            }
1219            /*  TODO: Signaling vs Quiet NaN  */
1220            cpu->cd.ppc.fpscr &= ~(PPC_FPSCR_FPCC | PPC_FPSCR_VXNAN);
1221            cpu->cd.ppc.fpscr |= (c << PPC_FPSCR_FPCC_SHIFT);
1222    
1223            (*(uint64_t *)ic->arg[2]) =
1224                ieee_store_float_value(result, IEEE_FMT_D, nan);
1225    }
1226    X(fadds)
1227    {
1228            /*  TODO  */
1229            instr(fadd)(cpu, ic);
1230    }
1231    X(fsub)
1232    {
1233            struct ieee_float_value fra;
1234            struct ieee_float_value frb;
1235            double result = 0.0;
1236            int nan = 0, c;
1237    
1238            /*  Sync. PC in case of an exception:  */
1239            uint64_t low_pc = ((size_t)ic - (size_t)
1240                cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
1241            cpu->pc = (cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2)) + (low_pc<<2);
1242            if (!(cpu->cd.ppc.msr & PPC_MSR_FP)) {
1243                    ppc_exception(cpu, PPC_EXCEPTION_FPU);
1244                    return;
1245            }
1246    
1247            ieee_interpret_float_value(*(uint64_t *)ic->arg[0], &fra, IEEE_FMT_D);
1248            ieee_interpret_float_value(*(uint64_t *)ic->arg[1], &frb, IEEE_FMT_D);
1249            if (fra.nan || frb.nan)
1250                    nan = 1;
1251            else
1252                    result = fra.f - frb.f;
1253            if (nan)
1254                    c = 1;
1255            else {
1256                    if (result < 0.0)
1257                            c = 8;
1258                    else if (result > 0.0)
1259                            c = 4;
1260                    else
1261                            c = 2;
1262            }
1263            /*  TODO: Signaling vs Quiet NaN  */
1264            cpu->cd.ppc.fpscr &= ~(PPC_FPSCR_FPCC | PPC_FPSCR_VXNAN);
1265            cpu->cd.ppc.fpscr |= (c << PPC_FPSCR_FPCC_SHIFT);
1266    
1267            (*(uint64_t *)ic->arg[2]) =
1268                ieee_store_float_value(result, IEEE_FMT_D, nan);
1269    }
1270    X(fsubs)
1271    {
1272            /*  TODO  */
1273            instr(fsub)(cpu, ic);
1274    }
1275    X(fdiv)
1276    {
1277            struct ieee_float_value fra;
1278            struct ieee_float_value frb;
1279            double result = 0.0;
1280            int nan = 0, c;
1281    
1282            /*  Sync. PC in case of an exception:  */
1283            uint64_t low_pc = ((size_t)ic - (size_t)
1284                cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
1285            cpu->pc = (cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2)) + (low_pc<<2);
1286            if (!(cpu->cd.ppc.msr & PPC_MSR_FP)) {
1287                    ppc_exception(cpu, PPC_EXCEPTION_FPU);
1288                    return;
1289            }
1290    
1291            ieee_interpret_float_value(*(uint64_t *)ic->arg[0], &fra, IEEE_FMT_D);
1292            ieee_interpret_float_value(*(uint64_t *)ic->arg[1], &frb, IEEE_FMT_D);
1293            if (fra.nan || frb.nan || frb.f == 0)
1294                    nan = 1;
1295            else
1296                    result = fra.f / frb.f;
1297            if (nan)
1298                    c = 1;
1299            else {
1300                    if (result < 0.0)
1301                            c = 8;
1302                    else if (result > 0.0)
1303                            c = 4;
1304                    else
1305                            c = 2;
1306            }
1307            /*  TODO: Signaling vs Quiet NaN  */
1308            cpu->cd.ppc.fpscr &= ~(PPC_FPSCR_FPCC | PPC_FPSCR_VXNAN);
1309            cpu->cd.ppc.fpscr |= (c << PPC_FPSCR_FPCC_SHIFT);
1310    
1311            (*(uint64_t *)ic->arg[2]) =
1312                ieee_store_float_value(result, IEEE_FMT_D, nan);
1313    }
1314    X(fdivs)
1315    {
1316            /*  TODO  */
1317            instr(fdiv)(cpu, ic);
1318    }
1319    
1320    
1321    /*
1322   *  llsc: Load-linked and store conditional   *  llsc: Load-linked and store conditional
1323   *   *
1324   *  arg[0] = copy of the instruction word.   *  arg[0] = copy of the instruction word.
# Line 781  X(llsc) Line 1374  X(llsc)
1374                  cpu->cd.ppc.ll_addr = addr;                  cpu->cd.ppc.ll_addr = addr;
1375                  cpu->cd.ppc.ll_bit = 1;                  cpu->cd.ppc.ll_bit = 1;
1376          } else {          } else {
1377                  uint32_t old_so = cpu->cd.ppc.xer & PPC_XER_SO;                  uint32_t old_so = cpu->cd.ppc.spr[SPR_XER] & PPC_XER_SO;
1378                  if (!rc) {                  if (!rc) {
1379                          fatal("sc: rc-bit not set?\n");                          fatal("sc: rc-bit not set?\n");
1380                          exit(1);                          exit(1);
# Line 829  X(llsc) Line 1422  X(llsc)
1422  /*  /*
1423   *  mtsr:  Move To Segment Register   *  mtsr:  Move To Segment Register
1424   *   *
1425   *  arg[0] = segment register nr (0..15)   *  arg[0] = sr number, or for indirect mode: ptr to rb
1426   *  arg[1] = ptr to rt   *  arg[1] = ptr to rt
1427   */   */
1428  X(mtsr)  X(mtsr)
1429  {  {
1430          /*  TODO: This only works for 32-bit mode  */          /*  TODO: This only works for 32-bit mode  */
1431          cpu->cd.ppc.sr[ic->arg[0]] = reg(ic->arg[1]);          cpu->cd.ppc.sr[ic->arg[0]] = reg(ic->arg[1]);
1432    
1433            cpu->invalidate_translation_caches(cpu, 0, INVALIDATE_ALL);
1434    }
1435    X(mtsrin)
1436    {
1437            /*  TODO: This only works for 32-bit mode  */
1438            uint32_t sr_num = reg(ic->arg[0]) >> 28;
1439            cpu->cd.ppc.sr[sr_num] = reg(ic->arg[1]);
1440    
1441            cpu->invalidate_translation_caches(cpu, 0, INVALIDATE_ALL);
1442  }  }
1443    
1444    
1445  /*  /*
1446   *  mfsrin, mtsrin:  Move From/To Segment Register Indirect   *  mfsrin, mtsrin:  Move From/To Segment Register Indirect
1447   *   *
1448   *  arg[0] = ptr to rb   *  arg[0] = sr number, or for indirect mode: ptr to rb
1449   *  arg[1] = ptr to rt   *  arg[1] = ptr to rt
1450   */   */
1451  X(mfsrin)  X(mfsr)
1452  {  {
1453          /*  TODO: This only works for 32-bit mode  */          /*  TODO: This only works for 32-bit mode  */
1454          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];  
1455  }  }
1456  X(mtsrin)  X(mfsrin)
1457  {  {
1458          /*  TODO: This only works for 32-bit mode  */          /*  TODO: This only works for 32-bit mode  */
1459          uint32_t sr_num = reg(ic->arg[0]) >> 28;          uint32_t sr_num = reg(ic->arg[0]) >> 28;
1460          cpu->cd.ppc.sr[sr_num] = reg(ic->arg[1]);          reg(ic->arg[1]) = cpu->cd.ppc.sr[sr_num];
1461  }  }
1462    
1463    
# Line 886  X(rldicr) Line 1488  X(rldicr)
1488    
1489    
1490  /*  /*
1491   *  rlwinm:   *  rlwnm:
1492   *   *
1493   *  arg[0] = ptr to rs   *  arg[0] = ptr to ra
1494   *  arg[1] = ptr to ra   *  arg[1] = mask
1495   *  arg[2] = copy of the instruction word   *  arg[2] = copy of the instruction word
1496   */   */
1497  X(rlwinm)  X(rlwnm)
1498  {  {
1499          MODE_uint_t tmp = reg(ic->arg[0]), ra = 0;          uint32_t tmp, iword = ic->arg[2];
1500          uint32_t iword = ic->arg[2];          int rs = (iword >> 21) & 31;
1501          int sh, mb, me, rc;          int rb = (iword >> 11) & 31;
1502            int sh = cpu->cd.ppc.gpr[rb] & 0x1f;
1503            tmp = (uint32_t)cpu->cd.ppc.gpr[rs];
1504            tmp = (tmp << sh) | (tmp >> (32-sh));
1505            tmp &= (uint32_t)ic->arg[1];
1506            reg(ic->arg[0]) = tmp;
1507    }
1508    DOT0(rlwnm)
1509    
         sh = (iword >> 11) & 31;  
         mb = (iword >> 6) & 31;  
         me = (iword >> 1) & 31;    
         rc = iword & 1;  
1510    
1511          /*  TODO: Fix this, its performance is awful:  */  /*
1512          while (sh-- != 0) {   *  rlwinm:
1513                  int b = (tmp >> 31) & 1;   *
1514                  tmp = (tmp << 1) | b;   *  arg[0] = ptr to ra
1515          }   *  arg[1] = mask
1516          for (;;) {   *  arg[2] = copy of the instruction word
1517                  uint64_t mask;   */
1518                  mask = (uint64_t)1 << (31-mb);  X(rlwinm)
1519                  ra |= (tmp & mask);  {
1520                  if (mb == me)          uint32_t tmp, iword = ic->arg[2];
1521                          break;          int rs = (iword >> 21) & 31;
1522                  mb ++;          int sh = (iword >> 11) & 31;
1523                  if (mb == 32)          tmp = (uint32_t)cpu->cd.ppc.gpr[rs];
1524                          mb = 0;          tmp = (tmp << sh) | (tmp >> (32-sh));
1525          }          tmp &= (uint32_t)ic->arg[1];
1526          reg(ic->arg[1]) = ra;          reg(ic->arg[0]) = tmp;
         if (rc)  
                 update_cr0(cpu, ra);  
1527  }  }
1528    DOT0(rlwinm)
1529    
1530    
1531  /*  /*
# Line 935  X(rlwimi) Line 1539  X(rlwimi)
1539  {  {
1540          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]);
1541          uint32_t iword = ic->arg[2];          uint32_t iword = ic->arg[2];
1542          int sh, mb, me, rc;          int sh = (iword >> 11) & 31;
1543            int mb = (iword >> 6) & 31;
1544            int me = (iword >> 1) & 31;  
1545            int rc = iword & 1;
1546    
1547          sh = (iword >> 11) & 31;          tmp = (tmp << sh) | (tmp >> (32-sh));
         mb = (iword >> 6) & 31;  
         me = (iword >> 1) & 31;    
         rc = iword & 1;  
1548    
         /*  TODO: Fix this, its performance is awful:  */  
         while (sh-- != 0) {  
                 int b = (tmp >> 31) & 1;  
                 tmp = (tmp << 1) | b;  
         }  
1549          for (;;) {          for (;;) {
1550                  uint64_t mask;                  uint64_t mask;
1551                  mask = (uint64_t)1 << (31-mb);                  mask = (uint64_t)1 << (31-mb);
# Line 976  X(srawi) Line 1575  X(srawi)
1575          uint32_t tmp = reg(ic->arg[0]);          uint32_t tmp = reg(ic->arg[0]);
1576          int i = 0, j = 0, sh = ic->arg[2];          int i = 0, j = 0, sh = ic->arg[2];
1577    
1578          cpu->cd.ppc.xer &= ~PPC_XER_CA;          cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
1579          if (tmp & 0x80000000)          if (tmp & 0x80000000)
1580                  i = 1;                  i = 1;
1581          while (sh-- > 0) {          while (sh-- > 0) {
# Line 987  X(srawi) Line 1586  X(srawi)
1586                          tmp |= 0x80000000;                          tmp |= 0x80000000;
1587          }          }
1588          if (i && j>0)          if (i && j>0)
1589                  cpu->cd.ppc.xer |= PPC_XER_CA;                  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
1590          reg(ic->arg[1]) = (int64_t)(int32_t)tmp;          reg(ic->arg[1]) = (int64_t)(int32_t)tmp;
1591  }  }
1592  DOT(srawi)  DOT1(srawi)
1593    
1594    
1595  /*  /*
1596   *  mcrf:  Move inside condition register   *  mcrf:  Move inside condition register
1597   *   *
1598   *  arg[0] = bf,  arg[1] = bfa   *  arg[0] = 28-4*bf,  arg[1] = 28-4*bfa
1599   */   */
1600  X(mcrf)  X(mcrf)
1601  {  {
1602          int bf = ic->arg[0], bfa = ic->arg[1];          int bf_shift = ic->arg[0], bfa_shift = ic->arg[1];
1603          uint32_t tmp = (cpu->cd.ppc.cr >> (28 - bfa*4)) & 0xf;          uint32_t tmp = (cpu->cd.ppc.cr >> bfa_shift) & 0xf;
1604          cpu->cd.ppc.cr &= ~(0xf << (28 - bf*4));          cpu->cd.ppc.cr &= ~(0xf << bf_shift);
1605          cpu->cd.ppc.cr |= (tmp << (28 - bf*4));          cpu->cd.ppc.cr |= (tmp << bf_shift);
1606  }  }
1607    
1608    
# Line 1048  X(cror) { Line 1647  X(cror) {
1647          if (ba | bb)          if (ba | bb)
1648                  cpu->cd.ppc.cr |= (1 << (31-bt));                  cpu->cd.ppc.cr |= (1 << (31-bt));
1649  }  }
1650    X(crnor) {
1651            uint32_t iword = ic->arg[0]; int bt = (iword >> 21) & 31;
1652            int ba = (iword >> 16) & 31, bb = (iword >> 11) & 31;
1653            ba = (cpu->cd.ppc.cr >> (31-ba)) & 1;
1654            bb = (cpu->cd.ppc.cr >> (31-bb)) & 1;
1655            cpu->cd.ppc.cr &= ~(1 << (31-bt));
1656            if (!(ba | bb))
1657                    cpu->cd.ppc.cr |= (1 << (31-bt));
1658    }
1659  X(crxor) {  X(crxor) {
1660          uint32_t iword = ic->arg[0]; int bt = (iword >> 21) & 31;          uint32_t iword = ic->arg[0]; int bt = (iword >> 21) & 31;
1661          int ba = (iword >> 16) & 31, bb = (iword >> 11) & 31;          int ba = (iword >> 16) & 31, bb = (iword >> 11) & 31;
# Line 1060  X(crxor) { Line 1668  X(crxor) {
1668    
1669    
1670  /*  /*
1671   *  mflr, etc:  Move from Link Register etc.   *  mfspr: Move from SPR
1672   *   *
1673   *  arg[0] = pointer to destination register   *  arg[0] = pointer to destination register
1674     *  arg[1] = pointer to source SPR
1675   */   */
1676  X(mflr) {       reg(ic->arg[0]) = cpu->cd.ppc.lr; }  X(mfspr) {
1677  X(mfctr) {      reg(ic->arg[0]) = cpu->cd.ppc.ctr; }          reg(ic->arg[0]) = reg(ic->arg[1]);
1678  X(mftb) {       reg(ic->arg[0]) = cpu->cd.ppc.tbl; }  }
1679  X(mftbu) {      reg(ic->arg[0]) = cpu->cd.ppc.tbu; }  X(mfspr_pmc1) {
1680  /*  TODO: Check privilege level for mfsprg*  */          /*
1681  X(mfsrr0) {     reg(ic->arg[0]) = cpu->cd.ppc.srr0; }           *  TODO: This is a temporary hack to make NetBSD/ppc detect
1682  X(mfsrr1) {     reg(ic->arg[0]) = cpu->cd.ppc.srr1; }           *  a CPU of the correct (emulated) speed.
1683  X(mfsdr1) {     reg(ic->arg[0]) = cpu->cd.ppc.sdr1; }           */
1684  X(mfdbsr) {     reg(ic->arg[0]) = cpu->cd.ppc.dbsr; }          reg(ic->arg[0]) = cpu->machine->emulated_hz / 10;
1685  X(mfhid1) {     reg(ic->arg[0]) = 0;  /*  TODO  */ }  }
1686  X(mfl2cr) {     reg(ic->arg[0]) = 0;  /*  TODO  */ }  X(mftb) {
1687  X(mfsprg0) {    reg(ic->arg[0]) = cpu->cd.ppc.sprg0; }          /*  NOTE/TODO: This increments the time base (slowly) if it
1688  X(mfsprg1) {    reg(ic->arg[0]) = cpu->cd.ppc.sprg1; }              is being polled.  */
1689  X(mfsprg2) {    reg(ic->arg[0]) = cpu->cd.ppc.sprg2; }          if (++cpu->cd.ppc.spr[SPR_TBL] == 0)
1690  X(mfsprg3) {    reg(ic->arg[0]) = cpu->cd.ppc.sprg3; }                  cpu->cd.ppc.spr[SPR_TBU] ++;
1691  X(mfpvr) {      reg(ic->arg[0]) = cpu->cd.ppc.pvr; }          reg(ic->arg[0]) = cpu->cd.ppc.spr[SPR_TBL];
1692  X(mfibatu) {    reg(ic->arg[0]) = cpu->cd.ppc.ibat_u[ic->arg[1]]; }  }
1693  X(mfibatl) {    reg(ic->arg[0]) = cpu->cd.ppc.ibat_l[ic->arg[1]]; }  X(mftbu) {
1694  X(mfdbatu) {    reg(ic->arg[0]) = cpu->cd.ppc.dbat_u[ic->arg[1]]; }          reg(ic->arg[0]) = cpu->cd.ppc.spr[SPR_TBU];
1695  X(mfdbatl) {    reg(ic->arg[0]) = cpu->cd.ppc.dbat_l[ic->arg[1]]; }  }
1696    
1697    
1698  /*  /*
1699   *  mtlr etc.:  Move to Link Register (or other special register)   *  mtspr: Move to SPR.
1700   *   *
1701   *  arg[0] = pointer to source register   *  arg[0] = pointer to source register
1702     *  arg[1] = pointer to the SPR
1703   */   */
1704  X(mtlr) {       cpu->cd.ppc.lr = reg(ic->arg[0]); }  X(mtspr) {
1705  X(mtctr) {      cpu->cd.ppc.ctr = reg(ic->arg[0]); }          reg(ic->arg[1]) = reg(ic->arg[0]);
1706  /*  TODO: Check privilege level for these:  */  }
 X(mtsrr0) {     cpu->cd.ppc.srr0 = reg(ic->arg[0]); }  
 X(mtsrr1) {     cpu->cd.ppc.srr1 = reg(ic->arg[0]); }  
 X(mtsdr1) {     cpu->cd.ppc.sdr1 = reg(ic->arg[0]); }  
 X(mtdbsr) {     cpu->cd.ppc.dbsr = reg(ic->arg[0]); }  
 X(mtsprg0) {    cpu->cd.ppc.sprg0 = reg(ic->arg[0]); }  
 X(mtsprg1) {    cpu->cd.ppc.sprg1 = reg(ic->arg[0]); }  
 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]); }  
1707    
1708    
1709  /*  /*
# Line 1115  X(rfi) Line 1713  X(rfi)
1713  {  {
1714          uint64_t tmp;          uint64_t tmp;
1715    
1716          reg_access_msr(cpu, &tmp, 0);          reg_access_msr(cpu, &tmp, 0, 0);
1717          tmp &= ~0xffff;          tmp &= ~0xffff;
1718          tmp |= (cpu->cd.ppc.srr1 & 0xffff);          tmp |= (cpu->cd.ppc.spr[SPR_SRR1] & 0xffff);
1719          reg_access_msr(cpu, &tmp, 1);          reg_access_msr(cpu, &tmp, 1, 0);
1720    
1721          cpu->pc = cpu->cd.ppc.srr0;          cpu->pc = cpu->cd.ppc.spr[SPR_SRR0];
1722          DYNTRANS_PC_TO_POINTERS(cpu);          DYNTRANS_PC_TO_POINTERS(cpu);
1723  }  }
1724    
# Line 1143  X(mfcr) Line 1741  X(mfcr)
1741   */   */
1742  X(mfmsr)  X(mfmsr)
1743  {  {
1744          reg_access_msr(cpu, (uint64_t*)ic->arg[0], 0);          reg_access_msr(cpu, (uint64_t*)ic->arg[0], 0, 0);
1745  }  }
1746    
1747    
# Line 1154  X(mfmsr) Line 1752  X(mfmsr)
1752   */   */
1753  X(mtmsr)  X(mtmsr)
1754  {  {
1755          reg_access_msr(cpu, (uint64_t*)ic->arg[0], 1);          /*  Synchronize the PC (pointing to _after_ this instruction)  */
1756            cpu->pc = (cpu->pc & ~0xfff) + ic->arg[1];
1757    
1758            reg_access_msr(cpu, (uint64_t*)ic->arg[0], 1, 1);
1759  }  }
1760    
1761    
# Line 1179  X(mtcrf) Line 1780  X(mtcrf)
1780   */   */
1781  X(mulli)  X(mulli)
1782  {  {
1783          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]);
1784  }  }
1785    
1786    
# Line 1193  X(mulli) Line 1794  X(mulli)
1794  X(lmw) {  X(lmw) {
1795          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];
1796          unsigned char d[4];          unsigned char d[4];
1797          int n_err = 0, rs = ic->arg[0];          int rs = ic->arg[0];
1798    
1799            int low_pc = ((size_t)ic - (size_t)cpu->cd.ppc.cur_ic_page)
1800                / sizeof(struct ppc_instr_call);
1801            cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1)
1802                << PPC_INSTR_ALIGNMENT_SHIFT);
1803            cpu->pc |= (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
1804    
1805          while (rs <= 31) {          while (rs <= 31) {
1806                  if (cpu->memory_rw(cpu, cpu->mem, addr, d, sizeof(d),                  if (cpu->memory_rw(cpu, cpu->mem, addr, d, sizeof(d),
1807                      MEM_READ, CACHE_DATA) != MEMORY_ACCESS_OK)                      MEM_READ, CACHE_DATA) != MEMORY_ACCESS_OK) {
1808                          n_err ++;                          /*  exception  */
1809                            return;
1810                    }
1811    
1812                  if (cpu->byte_order == EMUL_BIG_ENDIAN)                  if (cpu->byte_order == EMUL_BIG_ENDIAN)
1813                          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 1816  X(lmw) {
1816                          cpu->cd.ppc.gpr[rs] = (d[3] << 24) + (d[2] << 16)                          cpu->cd.ppc.gpr[rs] = (d[3] << 24) + (d[2] << 16)
1817                              + (d[1] << 8) + d[0];                              + (d[1] << 8) + d[0];
1818    
                 if (n_err > 0) {  
                         fatal("TODO: lmw: exception\n");  
                         exit(1);  
                 }  
   
1819                  rs ++;                  rs ++;
1820                  addr += sizeof(uint32_t);                  addr += sizeof(uint32_t);
1821          }          }
1822  }  }
1823  X(stmw) {  X(stmw) {
1824          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;  
1825          unsigned char d[4];          unsigned char d[4];
1826          int n_err = 0, rs = ic->arg[0];          int rs = ic->arg[0];
1827    
1828            int low_pc = ((size_t)ic - (size_t)cpu->cd.ppc.cur_ic_page)
1829                / sizeof(struct ppc_instr_call);
1830            cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1)
1831                << PPC_INSTR_ALIGNMENT_SHIFT);
1832            cpu->pc += (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
1833    
1834          while (rs <= 31) {          while (rs <= 31) {
1835                  tmp = cpu->cd.ppc.gpr[rs];                  uint32_t tmp = cpu->cd.ppc.gpr[rs];
1836                  if (cpu->byte_order == EMUL_BIG_ENDIAN) {                  if (cpu->byte_order == EMUL_BIG_ENDIAN) {
1837                          d[3] = tmp; d[2] = tmp >> 8;                          d[3] = tmp; d[2] = tmp >> 8;
1838                          d[1] = tmp >> 16; d[0] = tmp >> 24;                          d[1] = tmp >> 16; d[0] = tmp >> 24;
# Line 1232  X(stmw) { Line 1841  X(stmw) {
1841                          d[2] = tmp >> 16; d[3] = tmp >> 24;                          d[2] = tmp >> 16; d[3] = tmp >> 24;
1842                  }                  }
1843                  if (cpu->memory_rw(cpu, cpu->mem, addr, d, sizeof(d),                  if (cpu->memory_rw(cpu, cpu->mem, addr, d, sizeof(d),
1844                      MEM_WRITE, CACHE_DATA) != MEMORY_ACCESS_OK)                      MEM_WRITE, CACHE_DATA) != MEMORY_ACCESS_OK) {
1845                          n_err ++;                          /*  exception  */
1846                            return;
                 if (n_err > 0) {  
                         fatal("TODO: stmw: exception\n");  
                         exit(1);  
1847                  }                  }
1848    
1849                  rs ++;                  rs ++;
# Line 1247  X(stmw) { Line 1853  X(stmw) {
1853    
1854    
1855  /*  /*
1856     *  Load/store string:
1857     *
1858     *  arg[0] = rs   (well, rt for lswi)
1859     *  arg[1] = ptr to ra (or ptr to zero)
1860     *  arg[2] = nb
1861     */
1862    X(lswi)
1863    {
1864            MODE_uint_t addr = reg(ic->arg[1]);
1865            int rt = ic->arg[0], nb = ic->arg[2];
1866            int sub = 0;
1867    
1868            int low_pc = ((size_t)ic - (size_t)cpu->cd.ppc.cur_ic_page)
1869                / sizeof(struct ppc_instr_call);
1870            cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1)
1871                << PPC_INSTR_ALIGNMENT_SHIFT);
1872            cpu->pc += (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
1873    
1874            while (nb > 0) {
1875                    unsigned char d;
1876                    if (cpu->memory_rw(cpu, cpu->mem, addr, &d, 1,
1877                        MEM_READ, CACHE_DATA) != MEMORY_ACCESS_OK) {
1878                            /*  exception  */
1879                            return;
1880                    }
1881    
1882                    if (cpu->cd.ppc.mode == MODE_POWER && sub == 0)
1883                            cpu->cd.ppc.gpr[rt] = 0;
1884                    cpu->cd.ppc.gpr[rt] &= ~(0xff << (24-8*sub));
1885                    cpu->cd.ppc.gpr[rt] |= (d << (24-8*sub));
1886                    sub ++;
1887                    if (sub == 4) {
1888                            rt = (rt + 1) & 31;
1889                            sub = 0;
1890                    }
1891                    addr ++;
1892                    nb --;
1893            }
1894    }
1895    X(stswi)
1896    {
1897            MODE_uint_t addr = reg(ic->arg[1]);
1898            int rs = ic->arg[0], nb = ic->arg[2];
1899            uint32_t cur = cpu->cd.ppc.gpr[rs];
1900            int sub = 0;
1901    
1902            int low_pc = ((size_t)ic - (size_t)cpu->cd.ppc.cur_ic_page)
1903                / sizeof(struct ppc_instr_call);
1904            cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1)
1905                << PPC_INSTR_ALIGNMENT_SHIFT);
1906            cpu->pc += (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
1907    
1908            while (nb > 0) {
1909                    unsigned char d = cur >> 24;
1910                    if (cpu->memory_rw(cpu, cpu->mem, addr, &d, 1,
1911                        MEM_WRITE, CACHE_DATA) != MEMORY_ACCESS_OK) {
1912                            /*  exception  */
1913                            return;
1914                    }
1915                    cur <<= 8;
1916                    sub ++;
1917                    if (sub == 4) {
1918                            rs = (rs + 1) & 31;
1919                            sub = 0;
1920                            cur = cpu->cd.ppc.gpr[rs];
1921                    }
1922                    addr ++;
1923                    nb --;
1924            }
1925    }
1926    
1927    
1928    /*
1929   *  Shifts, and, or, xor, etc.   *  Shifts, and, or, xor, etc.
1930   *   *
1931   *  arg[0] = pointer to source register rs   *  arg[0] = pointer to source register rs
# Line 1260  X(extsb) { Line 1939  X(extsb) {
1939          reg(ic->arg[2]) = (int64_t)(int8_t)reg(ic->arg[0]);          reg(ic->arg[2]) = (int64_t)(int8_t)reg(ic->arg[0]);
1940  #endif  #endif
1941  }  }
1942  DOT(extsb)  DOT2(extsb)
1943  X(extsh) {  X(extsh) {
1944  #ifdef MODE32  #ifdef MODE32
1945          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 1947  X(extsh) {
1947          reg(ic->arg[2]) = (int64_t)(int16_t)reg(ic->arg[0]);          reg(ic->arg[2]) = (int64_t)(int16_t)reg(ic->arg[0]);
1948  #endif  #endif
1949  }  }
1950  DOT(extsh)  DOT2(extsh)
1951  X(extsw) {  X(extsw) {
1952  #ifdef MODE32  #ifdef MODE32
1953          fatal("TODO: extsw: invalid instruction\n"); exit(1);          fatal("TODO: extsw: invalid instruction\n"); exit(1);
# Line 1276  X(extsw) { Line 1955  X(extsw) {
1955          reg(ic->arg[2]) = (int64_t)(int32_t)reg(ic->arg[0]);          reg(ic->arg[2]) = (int64_t)(int32_t)reg(ic->arg[0]);
1956  #endif  #endif
1957  }  }
1958  DOT(extsw)  DOT2(extsw)
1959  X(slw) {        reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0])  X(slw) {        reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0])
1960                      << (reg(ic->arg[1]) & 63); }                      << (reg(ic->arg[1]) & 31); }
1961  DOT(slw)  DOT2(slw)
1962  X(sraw) {       reg(ic->arg[2]) =  X(sraw)
1963  #ifdef MODE32  {
1964                      (int32_t)          uint32_t tmp = reg(ic->arg[0]);
1965  #else          int i = 0, j = 0, sh = reg(ic->arg[1]) & 31;
1966                      (int64_t)  
1967  #endif          cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
1968                  reg(ic->arg[0]) >> (reg(ic->arg[1]) & 63); }          if (tmp & 0x80000000)
1969  DOT(sraw)                  i = 1;
1970            while (sh-- > 0) {
1971                    if (tmp & 1)
1972                            j ++;
1973                    tmp >>= 1;
1974                    if (tmp & 0x40000000)
1975                            tmp |= 0x80000000;
1976            }
1977            if (i && j>0)
1978                    cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
1979            reg(ic->arg[2]) = (int64_t)(int32_t)tmp;
1980    }
1981    DOT2(sraw)
1982  X(srw) {        reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0])  X(srw) {        reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0])
1983                      >> (reg(ic->arg[1]) & 63); }                      >> (reg(ic->arg[1]) & 31); }
1984  DOT(srw)  DOT2(srw)
1985  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]); }
1986  X(and_dot) {    reg(ic->arg[2]) = reg(ic->arg[0]) & reg(ic->arg[1]);  DOT2(and)
                 update_cr0(cpu, reg(ic->arg[2])); }  
1987  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])); }
1988  X(nand_dot) {   reg(ic->arg[2]) = ~(reg(ic->arg[0]) & reg(ic->arg[1]));  DOT2(nand)
                 update_cr0(cpu, reg(ic->arg[2])); }  
1989  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])); }
1990  X(andc_dot) {   reg(ic->arg[2]) = reg(ic->arg[0]) & (~reg(ic->arg[1]));  DOT2(andc)
                 update_cr0(cpu, reg(ic->arg[2])); }  
1991  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])); }
1992  X(nor_dot) {    reg(ic->arg[2]) = ~(reg(ic->arg[0]) | reg(ic->arg[1]));  DOT2(nor)
                 update_cr0(cpu, reg(ic->arg[2])); }  
1993  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]); }
1994  X(or_dot) {     reg(ic->arg[2]) = reg(ic->arg[0]) | reg(ic->arg[1]);  DOT2(or)
                 update_cr0(cpu, reg(ic->arg[2])); }  
1995  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])); }
1996  X(orc_dot) {    reg(ic->arg[2]) = reg(ic->arg[0]) | (~reg(ic->arg[1]));  DOT2(orc)
                 update_cr0(cpu, reg(ic->arg[2])); }  
1997  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]); }
1998  X(xor_dot) {    reg(ic->arg[2]) = reg(ic->arg[0]) ^ reg(ic->arg[1]);  DOT2(xor)
                 update_cr0(cpu, reg(ic->arg[2])); }  
1999    
2000    
2001  /*  /*
# Line 1321  X(xor_dot) {   reg(ic->arg[2]) = reg(ic->a Line 2005  X(xor_dot) {   reg(ic->arg[2]) = reg(ic->a
2005   *  arg[1] = pointer to destination register rt   *  arg[1] = pointer to destination register rt
2006   */   */
2007  X(neg) {        reg(ic->arg[1]) = -reg(ic->arg[0]); }  X(neg) {        reg(ic->arg[1]) = -reg(ic->arg[0]); }
2008  X(neg_dot) {    instr(neg)(cpu,ic); update_cr0(cpu, reg(ic->arg[1])); }  DOT1(neg)
2009    
2010    
2011  /*  /*
# Line 1336  X(mullw) Line 2020  X(mullw)
2020          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]);
2021          reg(ic->arg[2]) = (int32_t)sum;          reg(ic->arg[2]) = (int32_t)sum;
2022  }  }
2023    DOT2(mullw)
2024  X(mulhw)  X(mulhw)
2025  {  {
2026          int64_t sum;          int64_t sum;
# Line 1343  X(mulhw) Line 2028  X(mulhw)
2028              * (int64_t)(int32_t)reg(ic->arg[1]);              * (int64_t)(int32_t)reg(ic->arg[1]);
2029          reg(ic->arg[2]) = sum >> 32;          reg(ic->arg[2]) = sum >> 32;
2030  }  }
2031    DOT2(mulhw)
2032  X(mulhwu)  X(mulhwu)
2033  {  {
2034          uint64_t sum;          uint64_t sum;
# Line 1350  X(mulhwu) Line 2036  X(mulhwu)
2036              * (uint64_t)(uint32_t)reg(ic->arg[1]);              * (uint64_t)(uint32_t)reg(ic->arg[1]);
2037          reg(ic->arg[2]) = sum >> 32;          reg(ic->arg[2]) = sum >> 32;
2038  }  }
2039    DOT2(mulhwu)
2040  X(divw)  X(divw)
2041  {  {
2042          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 2047  X(divw)
2047                  sum = a / b;                  sum = a / b;
2048          reg(ic->arg[2]) = (uint32_t)sum;          reg(ic->arg[2]) = (uint32_t)sum;
2049  }  }
2050    DOT2(divw)
2051  X(divwu)  X(divwu)
2052  {  {
2053          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 2058  X(divwu)
2058                  sum = a / b;                  sum = a / b;
2059          reg(ic->arg[2]) = sum;          reg(ic->arg[2]) = sum;
2060  }  }
2061    DOT2(divwu)
2062    
2063    
2064  /*  /*
# Line 1380  X(divwu) Line 2069  X(divwu)
2069   *  arg[2] = pointer to destination register rt   *  arg[2] = pointer to destination register rt
2070   */   */
2071  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]); }
2072  X(add_dot) { instr(add)(cpu,ic); update_cr0(cpu, reg(ic->arg[2])); }  DOT2(add)
2073    
2074    
2075  /*  /*
# Line 1395  X(addc) Line 2084  X(addc)
2084          /*  TODO: this only works in 32-bit mode  */          /*  TODO: this only works in 32-bit mode  */
2085          uint64_t tmp = (uint32_t)reg(ic->arg[0]);          uint64_t tmp = (uint32_t)reg(ic->arg[0]);
2086          uint64_t tmp2 = tmp;          uint64_t tmp2 = tmp;
2087          cpu->cd.ppc.xer &= ~PPC_XER_CA;          cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2088          tmp += (uint32_t)reg(ic->arg[1]);          tmp += (uint32_t)reg(ic->arg[1]);
2089          if ((tmp >> 32) != (tmp2 >> 32))          if ((tmp >> 32) != (tmp2 >> 32))
2090                  cpu->cd.ppc.xer |= PPC_XER_CA;                  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2091          reg(ic->arg[2]) = (uint32_t)tmp;          reg(ic->arg[2]) = (uint32_t)tmp;
2092  }  }
2093    
# Line 1413  X(addc) Line 2102  X(addc)
2102  X(adde)  X(adde)
2103  {  {
2104          /*  TODO: this only works in 32-bit mode  */          /*  TODO: this only works in 32-bit mode  */
2105          int old_ca = cpu->cd.ppc.xer & PPC_XER_CA;          int old_ca = cpu->cd.ppc.spr[SPR_XER] & PPC_XER_CA;
2106          uint64_t tmp = (uint32_t)reg(ic->arg[0]);          uint64_t tmp = (uint32_t)reg(ic->arg[0]);
2107          uint64_t tmp2 = tmp;          uint64_t tmp2 = tmp;
2108          cpu->cd.ppc.xer &= ~PPC_XER_CA;          cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2109          tmp += (uint32_t)reg(ic->arg[1]);          tmp += (uint32_t)reg(ic->arg[1]);
2110          if (old_ca)          if (old_ca)
2111                  tmp ++;                  tmp ++;
2112          if ((tmp >> 32) != (tmp2 >> 32))          if ((tmp >> 32) != (tmp2 >> 32))
2113                  cpu->cd.ppc.xer |= PPC_XER_CA;                  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2114          reg(ic->arg[2]) = (uint32_t)tmp;          reg(ic->arg[2]) = (uint32_t)tmp;
2115  }  }
2116  X(adde_dot) { instr(adde)(cpu,ic); update_cr0(cpu, reg(ic->arg[2])); }  DOT2(adde)
2117  X(addme)  X(addme)
2118  {  {
2119          /*  TODO: this only works in 32-bit mode  */          /*  TODO: this only works in 32-bit mode  */
2120          int old_ca = cpu->cd.ppc.xer & PPC_XER_CA;          int old_ca = cpu->cd.ppc.spr[SPR_XER] & PPC_XER_CA;
2121          uint64_t tmp = (uint32_t)reg(ic->arg[0]);          uint64_t tmp = (uint32_t)reg(ic->arg[0]);
2122          uint64_t tmp2 = tmp;          uint64_t tmp2 = tmp;
2123          cpu->cd.ppc.xer &= ~PPC_XER_CA;          cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2124          if (old_ca)          if (old_ca)
2125                  tmp ++;                  tmp ++;
2126          tmp += 0xffffffffULL;          tmp += 0xffffffffULL;
2127          if ((tmp >> 32) != (tmp2 >> 32))          if ((tmp >> 32) != (tmp2 >> 32))
2128                  cpu->cd.ppc.xer |= PPC_XER_CA;                  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2129          reg(ic->arg[2]) = (uint32_t)tmp;          reg(ic->arg[2]) = (uint32_t)tmp;
2130  }  }
2131  X(addme_dot) { instr(addme)(cpu,ic); update_cr0(cpu, reg(ic->arg[2])); }  DOT2(addme)
2132  X(addze)  X(addze)
2133  {  {
2134          /*  TODO: this only works in 32-bit mode  */          /*  TODO: this only works in 32-bit mode  */
2135          int old_ca = cpu->cd.ppc.xer & PPC_XER_CA;          int old_ca = cpu->cd.ppc.spr[SPR_XER] & PPC_XER_CA;
2136          uint64_t tmp = (uint32_t)reg(ic->arg[0]);          uint64_t tmp = (uint32_t)reg(ic->arg[0]);
2137          uint64_t tmp2 = tmp;          uint64_t tmp2 = tmp;
2138          cpu->cd.ppc.xer &= ~PPC_XER_CA;          cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2139          if (old_ca)          if (old_ca)
2140                  tmp ++;                  tmp ++;
2141          if ((tmp >> 32) != (tmp2 >> 32))          if ((tmp >> 32) != (tmp2 >> 32))
2142                  cpu->cd.ppc.xer |= PPC_XER_CA;                  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2143          reg(ic->arg[2]) = (uint32_t)tmp;          reg(ic->arg[2]) = (uint32_t)tmp;
2144  }  }
2145  X(addze_dot) { instr(addze)(cpu,ic); update_cr0(cpu, reg(ic->arg[2])); }  DOT2(addze)
2146    
2147    
2148  /*  /*
# Line 1463  X(addze_dot) { instr(addze)(cpu,ic); upd Line 2152  X(addze_dot) { instr(addze)(cpu,ic); upd
2152   *  arg[1] = pointer to source register rb   *  arg[1] = pointer to source register rb
2153   *  arg[2] = pointer to destination register rt   *  arg[2] = pointer to destination register rt
2154   */   */
2155  X(subf) {       reg(ic->arg[2]) = reg(ic->arg[1]) - reg(ic->arg[0]); }  X(subf)
2156  X(subf_dot) {   instr(subf)(cpu,ic); update_cr0(cpu, reg(ic->arg[2])); }  {
2157            reg(ic->arg[2]) = reg(ic->arg[1]) - reg(ic->arg[0]);
2158    }
2159    DOT2(subf)
2160  X(subfc)  X(subfc)
2161  {  {
2162          cpu->cd.ppc.xer &= ~PPC_XER_CA;          cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2163          if (reg(ic->arg[1]) >= reg(ic->arg[0]))          if (reg(ic->arg[1]) >= reg(ic->arg[0]))
2164                  cpu->cd.ppc.xer |= PPC_XER_CA;                  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2165          reg(ic->arg[2]) = reg(ic->arg[1]) - reg(ic->arg[0]);          reg(ic->arg[2]) = reg(ic->arg[1]) - reg(ic->arg[0]);
2166  }  }
2167  X(subfc_dot) {  instr(subfc)(cpu,ic); update_cr0(cpu, reg(ic->arg[2])); }  DOT2(subfc)
2168  X(subfe)  X(subfe)
2169  {  {
2170          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;
2171          cpu->cd.ppc.xer &= ~PPC_XER_CA;          cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2172          if (reg(ic->arg[1]) == reg(ic->arg[0])) {          if (reg(ic->arg[1]) == reg(ic->arg[0])) {
2173                  if (old_ca)                  if (old_ca)
2174                          cpu->cd.ppc.xer |= PPC_XER_CA;                          cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2175          } else if (reg(ic->arg[1]) >= reg(ic->arg[0]))          } else if (reg(ic->arg[1]) >= reg(ic->arg[0]))
2176                  cpu->cd.ppc.xer |= PPC_XER_CA;                  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2177    
2178          /*          /*
2179           *  TODO: The register value calculation should be correct,           *  TODO: The register value calculation should be correct,
# Line 1490  X(subfe) Line 2182  X(subfe)
2182    
2183          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);
2184  }  }
2185  X(subfe_dot) {  instr(subfe)(cpu,ic); update_cr0(cpu, reg(ic->arg[2])); }  DOT2(subfe)
2186    X(subfme)
2187    {
2188            int old_ca = cpu->cd.ppc.spr[SPR_XER] & PPC_XER_CA;
2189            uint64_t tmp = (uint32_t)(~reg(ic->arg[0]));
2190            tmp += 0xffffffffULL;
2191            cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2192            if (old_ca)
2193                    tmp ++;
2194            if ((tmp >> 32) != 0)
2195                    cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2196            reg(ic->arg[2]) = (uint32_t)tmp;
2197    }
2198    DOT2(subfme)
2199  X(subfze)  X(subfze)
2200  {  {
2201          int old_ca = cpu->cd.ppc.xer & PPC_XER_CA;          int old_ca = cpu->cd.ppc.spr[SPR_XER] & PPC_XER_CA;
2202          uint64_t tmp = (uint32_t)(~reg(ic->arg[0]));          uint64_t tmp = (uint32_t)(~reg(ic->arg[0]));
2203          uint64_t tmp2 = tmp;          uint64_t tmp2 = tmp;
2204          cpu->cd.ppc.xer &= ~PPC_XER_CA;          cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2205          if (old_ca)          if (old_ca)
2206                  tmp ++;                  tmp ++;
2207          if ((tmp >> 32) != (tmp2 >> 32))          if ((tmp >> 32) != (tmp2 >> 32))
2208                  cpu->cd.ppc.xer |= PPC_XER_CA;                  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2209          reg(ic->arg[2]) = (uint32_t)tmp;          reg(ic->arg[2]) = (uint32_t)tmp;
2210  }  }
2211  X(subfze_dot) { instr(subfze)(cpu,ic); update_cr0(cpu, reg(ic->arg[2])); }  DOT2(subfze)
2212    
2213    
2214  /*  /*
# Line 1517  X(ori)  { reg(ic->arg[2]) = reg(ic->arg[ Line 2222  X(ori)  { reg(ic->arg[2]) = reg(ic->arg[
2222  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]; }
2223    
2224    
2225    #include "tmp_ppc_loadstore.c"
2226    
2227    
2228    /*
2229     *  lfs, stfs: Load/Store Floating-point Single precision
2230     */
2231    X(lfs)
2232    {
2233            /*  Sync. PC in case of an exception:  */
2234            uint64_t old_pc, low_pc = ((size_t)ic - (size_t)
2235                cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
2236            old_pc = cpu->pc = (cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2))
2237                + (low_pc << 2);
2238            if (!(cpu->cd.ppc.msr & PPC_MSR_FP)) {
2239                    ppc_exception(cpu, PPC_EXCEPTION_FPU);
2240                    return;
2241            }
2242    
2243            /*  Perform a 32-bit load:  */
2244    #ifdef MODE32
2245            ppc32_loadstore
2246    #else
2247            ppc_loadstore
2248    #endif
2249                [2 + 4 + 8](cpu, ic);
2250    
2251            if (old_pc == cpu->pc) {
2252                    /*  The load succeeded. Let's convert the value:  */
2253                    struct ieee_float_value val;
2254                    (*(uint64_t *)ic->arg[0]) &= 0xffffffff;
2255                    ieee_interpret_float_value(*(uint64_t *)ic->arg[0],
2256                        &val, IEEE_FMT_S);
2257                    (*(uint64_t *)ic->arg[0]) =
2258                        ieee_store_float_value(val.f, IEEE_FMT_D, val.nan);
2259            }
2260    }
2261    X(lfsx)
2262    {
2263            /*  Sync. PC in case of an exception:  */
2264            uint64_t old_pc, low_pc = ((size_t)ic - (size_t)
2265                cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
2266            old_pc = cpu->pc = (cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2))
2267                + (low_pc << 2);
2268            if (!(cpu->cd.ppc.msr & PPC_MSR_FP)) {
2269                    ppc_exception(cpu, PPC_EXCEPTION_FPU);
2270                    return;
2271            }
2272    
2273            /*  Perform a 32-bit load:  */
2274    #ifdef MODE32
2275            ppc32_loadstore_indexed
2276    #else
2277            ppc_loadstore_indexed
2278    #endif
2279                [2 + 4 + 8](cpu, ic);
2280    
2281            if (old_pc == cpu->pc) {
2282                    /*  The load succeeded. Let's convert the value:  */
2283                    struct ieee_float_value val;
2284                    (*(uint64_t *)ic->arg[0]) &= 0xffffffff;
2285                    ieee_interpret_float_value(*(uint64_t *)ic->arg[0],
2286                        &val, IEEE_FMT_S);
2287                    (*(uint64_t *)ic->arg[0]) =
2288                        ieee_store_float_value(val.f, IEEE_FMT_D, val.nan);
2289            }
2290    }
2291    X(lfd)
2292    {
2293            /*  Sync. PC in case of an exception:  */
2294            uint64_t low_pc = ((size_t)ic - (size_t)
2295                cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
2296            cpu->pc = (cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2)) + (low_pc<<2);
2297            if (!(cpu->cd.ppc.msr & PPC_MSR_FP)) {
2298                    ppc_exception(cpu, PPC_EXCEPTION_FPU);
2299                    return;
2300            }
2301    
2302            /*  Perform a 64-bit load:  */
2303    #ifdef MODE32
2304            ppc32_loadstore
2305    #else
2306            ppc_loadstore
2307    #endif
2308                [3 + 4 + 8](cpu, ic);
2309    }
2310    X(lfdx)
2311    {
2312            /*  Sync. PC in case of an exception:  */
2313            uint64_t low_pc = ((size_t)ic - (size_t)
2314                cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
2315            cpu->pc = (cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2)) + (low_pc<<2);
2316            if (!(cpu->cd.ppc.msr & PPC_MSR_FP)) {
2317                    ppc_exception(cpu, PPC_EXCEPTION_FPU);
2318                    return;
2319            }
2320            /*  Perform a 64-bit load:  */
2321    #ifdef MODE32
2322            ppc32_loadstore_indexed
2323    #else
2324            ppc_loadstore_indexed
2325    #endif
2326                [3 + 4 + 8](cpu, ic);
2327    }
2328    X(stfs)
2329    {
2330            uint64_t *old_arg0 = (void *)ic->arg[0];
2331            struct ieee_float_value val;
2332            uint64_t tmp_val;
2333    
2334            /*  Sync. PC in case of an exception:  */
2335            uint64_t low_pc = ((size_t)ic - (size_t)
2336                cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
2337            cpu->pc = (cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2)) + (low_pc<<2);
2338            if (!(cpu->cd.ppc.msr & PPC_MSR_FP)) {
2339                    ppc_exception(cpu, PPC_EXCEPTION_FPU);
2340                    return;
2341            }
2342    
2343            ieee_interpret_float_value(*old_arg0, &val, IEEE_FMT_D);
2344            tmp_val = ieee_store_float_value(val.f, IEEE_FMT_S, val.nan);
2345    
2346            ic->arg[0] = (size_t)&tmp_val;
2347    
2348            /*  Perform a 32-bit store:  */
2349    #ifdef MODE32
2350            ppc32_loadstore
2351    #else
2352            ppc_loadstore
2353    #endif
2354                [2 + 4](cpu, ic);
2355    
2356            ic->arg[0] = (size_t)old_arg0;
2357    }
2358    X(stfsx)
2359    {
2360            uint64_t *old_arg0 = (void *)ic->arg[0];
2361            struct ieee_float_value val;
2362            uint64_t tmp_val;
2363    
2364            /*  Sync. PC in case of an exception:  */
2365            uint64_t low_pc = ((size_t)ic - (size_t)
2366                cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
2367            cpu->pc = (cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2)) + (low_pc<<2);
2368            if (!(cpu->cd.ppc.msr & PPC_MSR_FP)) {
2369                    ppc_exception(cpu, PPC_EXCEPTION_FPU);
2370                    return;
2371            }
2372    
2373            ieee_interpret_float_value(*old_arg0, &val, IEEE_FMT_D);
2374            tmp_val = ieee_store_float_value(val.f, IEEE_FMT_S, val.nan);
2375    
2376            ic->arg[0] = (size_t)&tmp_val;
2377    
2378            /*  Perform a 32-bit store:  */
2379    #ifdef MODE32
2380            ppc32_loadstore_indexed
2381    #else
2382            ppc_loadstore_indexed
2383    #endif
2384                [2 + 4](cpu, ic);
2385    
2386            ic->arg[0] = (size_t)old_arg0;
2387    }
2388    X(stfd)
2389    {
2390            /*  Sync. PC in case of an exception:  */
2391            uint64_t low_pc = ((size_t)ic - (size_t)
2392                cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
2393            cpu->pc = (cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2)) + (low_pc<<2);
2394            if (!(cpu->cd.ppc.msr & PPC_MSR_FP)) {
2395                    ppc_exception(cpu, PPC_EXCEPTION_FPU);
2396                    return;
2397            }
2398            /*  Perform a 64-bit store:  */
2399    #ifdef MODE32
2400            ppc32_loadstore
2401    #else
2402            ppc_loadstore
2403    #endif
2404                [3 + 4](cpu, ic);
2405    }
2406    X(stfdx)
2407    {
2408            /*  Sync. PC in case of an exception:  */
2409            uint64_t low_pc = ((size_t)ic - (size_t)
2410                cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
2411            cpu->pc = (cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2)) + (low_pc<<2);
2412            if (!(cpu->cd.ppc.msr & PPC_MSR_FP)) {
2413                    ppc_exception(cpu, PPC_EXCEPTION_FPU);
2414                    return;
2415            }
2416            /*  Perform a 64-bit store:  */
2417    #ifdef MODE32
2418            ppc32_loadstore_indexed
2419    #else
2420            ppc_loadstore_indexed
2421    #endif
2422                [3 + 4](cpu, ic);
2423    }
2424    
2425    
2426    /*
2427     *  tlbia:  TLB invalidate all
2428     */
2429    X(tlbia)
2430    {
2431    printf("tlbia\n");
2432    exit(1);
2433            cpu->invalidate_translation_caches(cpu, 0, INVALIDATE_ALL);
2434    }
2435    
2436    
2437  /*  /*
2438   *  tlbie:  TLB invalidate   *  tlbie:  TLB invalidate
2439   */   */
2440  X(tlbie)  X(tlbie)
2441  {  {
2442          cpu->invalidate_translation_caches(cpu, 0, INVALIDATE_ALL);          cpu->invalidate_translation_caches(cpu, reg(ic->arg[0]),
2443                INVALIDATE_VADDR);
2444    }
2445    
2446    
2447    /*
2448     *  sc: Syscall.
2449     */
2450    X(sc)
2451    {
2452            /*  Synchronize the PC (pointing to _after_ this instruction)  */
2453            cpu->pc = (cpu->pc & ~0xfff) + ic->arg[1];
2454    
2455            ppc_exception(cpu, PPC_EXCEPTION_SC);
2456  }  }
2457    
2458    
# Line 1543  X(user_syscall) Line 2473  X(user_syscall)
2473  X(openfirmware)  X(openfirmware)
2474  {  {
2475          of_emul(cpu);          of_emul(cpu);
2476          cpu->pc = cpu->cd.ppc.lr;          cpu->pc = cpu->cd.ppc.spr[SPR_LR];
2477          if (cpu->machine->show_trace_tree)          if (cpu->machine->show_trace_tree)
2478                  cpu_functioncall_trace_return(cpu);                  cpu_functioncall_trace_return(cpu);
2479          DYNTRANS_PC_TO_POINTERS(cpu);          DYNTRANS_PC_TO_POINTERS(cpu);
2480  }  }
2481    
2482    
 #include "tmp_ppc_loadstore.c"  
   
   
 /*****************************************************************************/  
   
   
2483  /*  /*
2484   *  byte_fill_loop:   *  tlbli:
2485   *   */
2486   *  A byte-fill loop. Fills at most one page at a time. If the page was not  X(tlbli)
2487   *  in the host_store table, then the original sequence (beginning with  {
2488   *  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;  
 #ifdef MODE32  
         uint32_t addr;  
 #else  
         uint64_t addr;  
         fatal("byte_fill_loop: not for 64-bit mode yet\n");  
         exit(1);  
 #endif  
   
 restart_loop:  
         addr = reg(z);  
         /*  TODO: This only work with 32-bit addressing:  */  
         page = cpu->cd.ppc.host_store[addr >> 12];  
         if (page == NULL) {  
                 instr(cmpwi)(cpu, ic);  
                 return;  
         }  
   
         n = reg(y) + 1; ofs = addr & 0xfff; maxlen = 0x1000 - ofs;  
         if (n > maxlen)  
                 n = maxlen;  
   
         /*  fatal("FILL A: x=%i n=%i ofs=0x%x y=0x%x z=0x%x w=0x%x\n", x,  
             n, ofs, (int)reg(y), (int)reg(z), (int)reg(w));  */  
   
         memset(page + ofs, *w, n);  
   
         reg(z) = addr + n;  
         reg(y) -= n;  
2489    
         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;  
2490    
2491          cpu->n_translated_instrs --;  /*
2492          if ((int32_t)reg(y) > 0)   *  tlbld:
2493                  cpu->cd.ppc.next_ic = ic;   */
2494          else  X(tlbld)
2495                  cpu->cd.ppc.next_ic = &ic[5];  {
2496            /*  MODE_uint_t vaddr = reg(ic->arg[0]);
2497                MODE_uint_t paddr = cpu->cd.ppc.spr[SPR_RPA];  */
2498    
2499          /*  fatal("FILL B: x=%i n=%i ofs=0x%x y=0x%x z=0x%x w=0x%x\n", x, n,          /*  TODO?  */
             ofs, (int)reg(y), (int)reg(z), (int)reg(w));  */  
2500  }  }
2501    
2502    
# Line 1654  X(end_of_page) Line 2521  X(end_of_page)
2521    
2522    
2523  /*  /*
  *  ppc_combine_instructions():  
  *  
  *  Combine two or more instructions, if possible, into a single function call.  
  */  
 void COMBINE_INSTRUCTIONS(struct cpu *cpu, struct ppc_instr_call *ic,  
         uint32_t addr)  
 {  
         int n_back;  
         n_back = (addr >> PPC_INSTR_ALIGNMENT_SHIFT)  
             & (PPC_IC_ENTRIES_PER_PAGE-1);  
   
         if (n_back >= 4) {  
                 /*  
                  *  L:  cmpwi   crX,rY,0                ic[-4]  
                  *      stb     rW,0(rZ)                ic[-3]  
                  *      subi    rY,rY,1                 ic[-2]  
                  *      addi    rZ,rZ,1                 ic[-1]  
                  *      bc      12,4*X+1,L              ic[0]  
                  */  
                 if (ic[-4].f == instr(cmpwi) &&  
                     ic[-4].arg[0] == ic[-2].arg[0] && ic[-4].arg[1] == 0 &&  
   
                     ic[-3].f == instr(stb_0) &&  
                     ic[-3].arg[1] == ic[-1].arg[0] && ic[-3].arg[2] == 0 &&  
   
                     ic[-2].f == instr(addi) &&  
                     ic[-2].arg[0] == ic[-2].arg[2] && ic[-2].arg[1] == -1 &&  
   
                     ic[-1].f == instr(addi) &&  
                     ic[-1].arg[0] == ic[-1].arg[2] && ic[-1].arg[1] ==  1 &&  
   
                     ic[0].f == instr(bc_samepage) &&  
                     ic[0].arg[0] == (size_t)&ic[-4] &&  
                     ic[0].arg[1] == 12 && ic[0].arg[2] == 4*ic[-4].arg[2] + 1) {  
                         ic[-4].f = instr(byte_fill_loop);  
                         combined;  
                 }  
         }  
   
         /*  TODO: Combine forward as well  */  
 }  
   
   
 /*****************************************************************************/  
   
   
 /*  
2524   *  ppc_instr_to_be_translated():   *  ppc_instr_to_be_translated():
2525   *   *
2526   *  Translate an instruction word into an ppc_instr_call. ic is filled in with   *  Translate an instruction word into an ppc_instr_call. ic is filled in with
# Line 1711  void COMBINE_INSTRUCTIONS(struct cpu *cp Line 2531  void COMBINE_INSTRUCTIONS(struct cpu *cp
2531  X(to_be_translated)  X(to_be_translated)
2532  {  {
2533          uint64_t addr, low_pc, tmp_addr;          uint64_t addr, low_pc, tmp_addr;
2534          uint32_t iword;          uint32_t iword, mask;
2535          unsigned char *page;          unsigned char *page;
2536          unsigned char ib[4];          unsigned char ib[4];
2537          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,
2538              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,
2539              bfa, fp;              bfa, fp, byterev, nb, mb, me;
2540          void (*samepage_function)(struct cpu *, struct ppc_instr_call *);          void (*samepage_function)(struct cpu *, struct ppc_instr_call *);
2541          void (*rc_f)(struct cpu *, struct ppc_instr_call *);          void (*rc_f)(struct cpu *, struct ppc_instr_call *);
2542    
# Line 1739  X(to_be_translated) Line 2559  X(to_be_translated)
2559                  /*  fatal("TRANSLATION MISS!\n");  */                  /*  fatal("TRANSLATION MISS!\n");  */
2560                  if (!cpu->memory_rw(cpu, cpu->mem, addr, ib,                  if (!cpu->memory_rw(cpu, cpu->mem, addr, ib,
2561                      sizeof(ib), MEM_READ, CACHE_INSTRUCTION)) {                      sizeof(ib), MEM_READ, CACHE_INSTRUCTION)) {
2562                          fatal("to_be_translated(): "                          fatal("PPC to_be_translated(): "
2563                              "read failed: TODO\n");                              "read failed: TODO\n");
2564                          goto bad;                          exit(1);
2565                            /*  goto bad;  */
2566                  }                  }
2567          }          }
2568    
# Line 1811  X(to_be_translated) Line 2632  X(to_be_translated)
2632                  }                  }
2633                  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);                  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2634                  ic->arg[1] = (ssize_t)imm;                  ic->arg[1] = (ssize_t)imm;
2635                  ic->arg[2] = bf;                  ic->arg[2] = 28 - 4 * bf;
2636                  break;                  break;
2637    
2638          case PPC_HI6_ADDIC:          case PPC_HI6_ADDIC:
# Line 1828  X(to_be_translated) Line 2649  X(to_be_translated)
2649                  else                  else
2650                          ic->f = instr(addic_dot);                          ic->f = instr(addic_dot);
2651                  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);                  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2652                  ic->arg[1] = (ssize_t)imm;                  ic->arg[1] = imm;
2653                  ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);                  ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);
2654                  break;                  break;
2655    
# Line 1840  X(to_be_translated) Line 2661  X(to_be_translated)
2661                          ic->arg[0] = (size_t)(&cpu->cd.ppc.zero);                          ic->arg[0] = (size_t)(&cpu->cd.ppc.zero);
2662                  else                  else
2663                          ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);                          ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2664                  ic->arg[1] = (ssize_t)(int16_t)(iword & 0xffff);                  ic->arg[1] = (int16_t)(iword & 0xffff);
2665                  if (main_opcode == PPC_HI6_ADDIS)                  if (main_opcode == PPC_HI6_ADDIS)
2666                          ic->arg[1] <<= 16;                          ic->arg[1] <<= 16;
2667                  ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);                  ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);
# Line 1879  X(to_be_translated) Line 2700  X(to_be_translated)
2700          case PPC_HI6_LBZU:          case PPC_HI6_LBZU:
2701          case PPC_HI6_LHZ:          case PPC_HI6_LHZ:
2702          case PPC_HI6_LHZU:          case PPC_HI6_LHZU:
2703            case PPC_HI6_LHA:
2704            case PPC_HI6_LHAU:
2705          case PPC_HI6_LWZ:          case PPC_HI6_LWZ:
2706          case PPC_HI6_LWZU:          case PPC_HI6_LWZU:
2707          case PPC_HI6_LFD:          case PPC_HI6_LFD:
2708            case PPC_HI6_LFS:
2709          case PPC_HI6_STB:          case PPC_HI6_STB:
2710          case PPC_HI6_STBU:          case PPC_HI6_STBU:
2711          case PPC_HI6_STH:          case PPC_HI6_STH:
2712          case PPC_HI6_STHU:          case PPC_HI6_STHU:
2713          case PPC_HI6_STW:          case PPC_HI6_STW:
2714          case PPC_HI6_STWU:          case PPC_HI6_STWU:
2715            case PPC_HI6_STFD:
2716            case PPC_HI6_STFS:
2717                  rs = (iword >> 21) & 31;                  rs = (iword >> 21) & 31;
2718                  ra = (iword >> 16) & 31;                  ra = (iword >> 16) & 31;
2719                  imm = (int16_t)(iword & 0xffff);                  imm = (int16_t)iword;
2720                  load = 0; zero = 1; size = 0; update = 0; fp = 0;                  load = 0; zero = 1; size = 0; update = 0; fp = 0;
2721                    ic->f = NULL;
2722                  switch (main_opcode) {                  switch (main_opcode) {
2723                  case PPC_HI6_LBZ:  load = 1; break;                  case PPC_HI6_LBZ:  load=1; break;
2724                  case PPC_HI6_LBZU: load = 1; update = 1; break;                  case PPC_HI6_LBZU: load=1; update=1; break;
2725                  case PPC_HI6_LHZ:  load = 1; size = 1; break;                  case PPC_HI6_LHA:  load=1; size=1; zero=0; break;
2726                  case PPC_HI6_LHZU: load = 1; size = 1; update = 1; break;                  case PPC_HI6_LHAU: load=1; size=1; zero=0; update=1; break;
2727                  case PPC_HI6_LWZ:  load = 1; size = 2; break;                  case PPC_HI6_LHZ:  load=1; size=1; break;
2728                  case PPC_HI6_LWZU: load = 1; size = 2; update = 1; break;                  case PPC_HI6_LHZU: load=1; size=1; update=1; break;
2729                  case PPC_HI6_LFD:  load = 1; size = 3; fp = 1; break;                  case PPC_HI6_LWZ:  load=1; size=2; break;
2730                    case PPC_HI6_LWZU: load=1; size=2; update=1; break;
2731                    case PPC_HI6_LFD:  load=1; size=3; fp=1;ic->f=instr(lfd);break;
2732                    case PPC_HI6_LFS:  load=1; size=2; fp=1;ic->f=instr(lfs);break;
2733                  case PPC_HI6_STB:  break;                  case PPC_HI6_STB:  break;
2734                  case PPC_HI6_STBU: update = 1; break;                  case PPC_HI6_STBU: update=1; break;
2735                  case PPC_HI6_STH:  size = 1; break;                  case PPC_HI6_STH:  size=1; break;
2736                  case PPC_HI6_STHU: size = 1; update = 1; break;                  case PPC_HI6_STHU: size=1; update=1; break;
2737                  case PPC_HI6_STW:  size = 2; break;                  case PPC_HI6_STW:  size=2; break;
2738                  case PPC_HI6_STWU: size = 2; update = 1; break;                  case PPC_HI6_STWU: size=2; update=1; break;
2739                  }                  case PPC_HI6_STFD: size=3; fp=1; ic->f = instr(stfd); break;
2740                  if (fp) {                  case PPC_HI6_STFS: size=2; fp=1; ic->f = instr(stfs); break;
2741                          /*  Floating point:  */                  }
2742                          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:  */  
2743                          ic->f =                          ic->f =
2744  #ifdef MODE32  #ifdef MODE32
2745                              ppc32_loadstore                              ppc32_loadstore
# Line 1949  X(to_be_translated) Line 2770  X(to_be_translated)
2770                  bo = (iword >> 21) & 31;                  bo = (iword >> 21) & 31;
2771                  bi = (iword >> 16) & 31;                  bi = (iword >> 16) & 31;
2772                  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;  
                 }  
2773                  if (aa_bit) {                  if (aa_bit) {
2774                          fatal("aa_bit: NOT YET\n");                          fatal("aa_bit: NOT YET\n");
2775                          goto bad;                          goto bad;
2776                  }                  }
2777                  ic->f = instr(bc);                  if (lk_bit) {
2778                  samepage_function = instr(bc_samepage);                          ic->f = instr(bcl);
2779                            samepage_function = instr(bcl_samepage);
2780                    } else {
2781                            ic->f = instr(bc);
2782                            if (bo & 4)
2783                                    samepage_function = instr(bc_samepage_no_ctr);
2784                            else
2785                                    samepage_function = instr(bc_samepage);
2786                    }
2787                  ic->arg[0] = (ssize_t)tmp_addr;                  ic->arg[0] = (ssize_t)tmp_addr;
2788                  ic->arg[1] = bo;                  ic->arg[1] = bo;
2789                  ic->arg[2] = bi;                  ic->arg[2] = bi;
# Line 1981  X(to_be_translated) Line 2806  X(to_be_translated)
2806    
2807          case PPC_HI6_SC:          case PPC_HI6_SC:
2808                  ic->arg[0] = (iword >> 5) & 0x7f;                  ic->arg[0] = (iword >> 5) & 0x7f;
2809                    ic->arg[1] = (addr & 0xfff) + 4;
2810                  if (cpu->machine->userland_emul != NULL)                  if (cpu->machine->userland_emul != NULL)
2811                          ic->f = instr(user_syscall);                          ic->f = instr(user_syscall);
2812                  else {                  else if (iword == 0x44ee0002) {
2813                          /*  Special case/magic hack for OpenFirmware emul:  */                          /*  Special case/magic hack for OpenFirmware emul:  */
2814                          if (iword == 0x44ee0002) {                          ic->f = instr(openfirmware);
2815                                  ic->f = instr(openfirmware);                  } else
2816                                  break;                          ic->f = instr(sc);
                         }  
                         fatal("PPC non-userland SYSCALL: TODO\n");  
                         goto bad;  
                 }  
2817                  break;                  break;
2818    
2819          case PPC_HI6_B:          case PPC_HI6_B:
2820                  aa_bit = (iword & 2) >> 1;                  aa_bit = (iword & 2) >> 1;
2821                  lk_bit = iword & 1;                  lk_bit = iword & 1;
                 if (aa_bit) {  
                         fatal("aa_bit: NOT YET\n");  
                         goto bad;  
                 }  
2822                  tmp_addr = (int64_t)(int32_t)((iword & 0x03fffffc) << 6);                  tmp_addr = (int64_t)(int32_t)((iword & 0x03fffffc) << 6);
2823                  tmp_addr = (int64_t)tmp_addr >> 6;                  tmp_addr = (int64_t)tmp_addr >> 6;
2824                  if (lk_bit) {                  if (lk_bit) {
# Line 2031  X(to_be_translated) Line 2849  X(to_be_translated)
2849                                      ((new_pc & mask_within_page) >> 2));                                      ((new_pc & mask_within_page) >> 2));
2850                          }                          }
2851                  }                  }
2852                    if (aa_bit) {
2853                            if (lk_bit) {
2854                                    if (cpu->machine->show_trace_tree) {
2855                                            ic->f = instr(bla_trace);
2856                                    } else {
2857                                            ic->f = instr(bla);
2858                                    }
2859                            } else {
2860                                    ic->f = instr(ba);
2861                            }
2862                            ic->arg[0] = (ssize_t)tmp_addr;
2863                    }
2864                  break;                  break;
2865    
2866          case PPC_HI6_19:          case PPC_HI6_19:
# Line 2046  X(to_be_translated) Line 2876  X(to_be_translated)
2876                          if (xo == PPC_19_BCLR) {                          if (xo == PPC_19_BCLR) {
2877                                  if (lk_bit)                                  if (lk_bit)
2878                                          ic->f = instr(bclr_l);                                          ic->f = instr(bclr_l);
2879                                  else                                  else {
2880                                          ic->f = instr(bclr);                                          ic->f = instr(bclr);
2881                                            if (!cpu->machine->show_trace_tree &&
2882                                                (bo & 0x14) == 0x14)
2883                                                    ic->f = instr(bclr_20);
2884                                    }
2885                          } else {                          } else {
2886                                  if (lk_bit)                                  if (lk_bit)
2887                                          ic->f = instr(bcctr_l);                                          ic->f = instr(bcctr_l);
# Line 2055  X(to_be_translated) Line 2889  X(to_be_translated)
2889                                          ic->f = instr(bcctr);                                          ic->f = instr(bcctr);
2890                          }                          }
2891                          ic->arg[0] = bo;                          ic->arg[0] = bo;
2892                          ic->arg[1] = bi;                          ic->arg[1] = 31 - bi;
2893                          ic->arg[2] = bh;                          ic->arg[2] = bh;
2894                          break;                          break;
2895    
# Line 2071  X(to_be_translated) Line 2905  X(to_be_translated)
2905                  case PPC_19_MCRF:                  case PPC_19_MCRF:
2906                          bf = (iword >> 23) & 7;                          bf = (iword >> 23) & 7;
2907                          bfa = (iword >> 18) & 7;                          bfa = (iword >> 18) & 7;
2908                          ic->arg[0] = bf;                          ic->arg[0] = 28 - 4*bf;
2909                          ic->arg[1] = bfa;                          ic->arg[1] = 28 - 4*bfa;
2910                          ic->f = instr(mcrf);                          ic->f = instr(mcrf);
2911                          break;                          break;
2912    
# Line 2080  X(to_be_translated) Line 2914  X(to_be_translated)
2914                  case PPC_19_CRANDC:                  case PPC_19_CRANDC:
2915                  case PPC_19_CREQV:                  case PPC_19_CREQV:
2916                  case PPC_19_CROR:                  case PPC_19_CROR:
2917                    case PPC_19_CRNOR:
2918                  case PPC_19_CRXOR:                  case PPC_19_CRXOR:
2919                          switch (xo) {                          switch (xo) {
2920                          case PPC_19_CRAND:  ic->f = instr(crand); break;                          case PPC_19_CRAND:  ic->f = instr(crand); break;
2921                          case PPC_19_CRANDC: ic->f = instr(crandc); break;                          case PPC_19_CRANDC: ic->f = instr(crandc); break;
2922                          case PPC_19_CREQV:  ic->f = instr(creqv); break;                          case PPC_19_CREQV:  ic->f = instr(creqv); break;
2923                          case PPC_19_CROR:   ic->f = instr(cror); break;                          case PPC_19_CROR:   ic->f = instr(cror); break;
2924                            case PPC_19_CRNOR:  ic->f = instr(crnor); break;
2925                          case PPC_19_CRXOR:  ic->f = instr(crxor); break;                          case PPC_19_CRXOR:  ic->f = instr(crxor); break;
2926                          }                          }
2927                          ic->arg[0] = iword;                          ic->arg[0] = iword;
# Line 2095  X(to_be_translated) Line 2931  X(to_be_translated)
2931                  }                  }
2932                  break;                  break;
2933    
2934          case PPC_HI6_RLWIMI:          case PPC_HI6_RLWNM:
2935          case PPC_HI6_RLWINM:          case PPC_HI6_RLWINM:
2936                    ra = (iword >> 16) & 31;
2937                    mb = (iword >> 6) & 31;
2938                    me = (iword >> 1) & 31;  
2939                    rc = iword & 1;
2940                    mask = 0;
2941                    for (;;) {
2942                            mask |= ((uint32_t)0x80000000 >> mb);
2943                            if (mb == me)
2944                                    break;
2945                            mb ++; mb &= 31;
2946                    }
2947                    switch (main_opcode) {
2948                    case PPC_HI6_RLWNM:
2949                            ic->f = rc? instr(rlwnm_dot) : instr(rlwnm); break;
2950                    case PPC_HI6_RLWINM:
2951                            ic->f = rc? instr(rlwinm_dot) : instr(rlwinm); break;
2952                    }
2953                    ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2954                    ic->arg[1] = mask;
2955                    ic->arg[2] = (uint32_t)iword;
2956                    break;
2957    
2958            case PPC_HI6_RLWIMI:
2959                  rs = (iword >> 21) & 31;                  rs = (iword >> 21) & 31;
2960                  ra = (iword >> 16) & 31;                  ra = (iword >> 16) & 31;
2961                  if (main_opcode == PPC_HI6_RLWIMI)                  ic->f = instr(rlwimi);
                         ic->f = instr(rlwimi);  
                 else  
                         ic->f = instr(rlwinm);  
2962                  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);                  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
2963                  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);                  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2964                  ic->arg[2] = (uint32_t)iword;                  ic->arg[2] = (uint32_t)iword;
# Line 2169  X(to_be_translated) Line 3025  X(to_be_translated)
3025                          }                          }
3026                          ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);                          ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3027                          ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rb]);                          ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3028                          ic->arg[2] = bf;                          ic->arg[2] = 28 - 4*bf;
3029                          break;                          break;
3030    
3031                  case PPC_31_CNTLZW:                  case PPC_31_CNTLZW:
# Line 2188  X(to_be_translated) Line 3044  X(to_be_translated)
3044                  case PPC_31_MFSPR:                  case PPC_31_MFSPR:
3045                          rt = (iword >> 21) & 31;                          rt = (iword >> 21) & 31;
3046                          spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);                          spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
3047                            debug_spr_usage(cpu->pc, spr);
3048                          ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rt]);                          ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rt]);
3049                            ic->arg[1] = (size_t)(&cpu->cd.ppc.spr[spr]);
3050                          switch (spr) {                          switch (spr) {
3051                          case 8:   ic->f = instr(mflr); break;                          case SPR_PMC1:  ic->f = instr(mfspr_pmc1); break;
3052                          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;  
                                 }  
3053                          }                          }
3054                          break;                          break;
3055    
3056                  case PPC_31_MTSPR:                  case PPC_31_MTSPR:
3057                          rs = (iword >> 21) & 31;                          rs = (iword >> 21) & 31;
3058                          spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);                          spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
3059                            debug_spr_usage(cpu->pc, spr);
3060                          ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);                          ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
3061                          switch (spr) {                          ic->arg[1] = (size_t)(&cpu->cd.ppc.spr[spr]);
3062                          case 8:   ic->f = instr(mtlr); break;                          ic->f = instr(mtspr);
                         case 9:   ic->f = instr(mtctr); break;  
                         case 25:  ic->f = instr(mtsdr1); break;  
                         case 26:  ic->f = instr(mtsrr0); break;  
                         case 27:  ic->f = instr(mtsrr1); break;  
                         case 272: ic->f = instr(mtsprg0); break;  
                         case 273: ic->f = instr(mtsprg1); break;  
                         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;  
                                 }  
                         }  
3063                          break;                          break;
3064    
3065                  case PPC_31_MFCR:                  case PPC_31_MFCR:
# Line 2278  X(to_be_translated) Line 3082  X(to_be_translated)
3082                                  goto bad;                                  goto bad;
3083                          }                          }
3084                          ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);                          ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
3085                            ic->arg[1] = (addr & 0xfff) + 4;
3086                          ic->f = instr(mtmsr);                          ic->f = instr(mtmsr);
3087                          break;                          break;
3088    
# Line 2313  X(to_be_translated) Line 3118  X(to_be_translated)
3118                          }                          }
3119                          break;                          break;
3120    
3121                    case PPC_31_MFSR:
3122                  case PPC_31_MTSR:                  case PPC_31_MTSR:
3123                          rt = (iword >> 21) & 31;                          rt = (iword >> 21) & 31;
3124                          ic->arg[0] = (iword >> 16) & 15;                          ic->arg[0] = (iword >> 16) & 15;
3125                          ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rt]);                          ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rt]);
3126                          ic->f = instr(mtsr);                          switch (xo) {
3127                            case PPC_31_MFSR:   ic->f = instr(mfsr); break;
3128                            case PPC_31_MTSR:   ic->f = instr(mtsr); break;
3129                            }
3130                          if (cpu->cd.ppc.bits == 64) {                          if (cpu->cd.ppc.bits == 64) {
3131                                  fatal("Not yet for 64-bit mode\n");                                  fatal("Not yet for 64-bit mode\n");
3132                                  goto bad;                                  goto bad;
# Line 2339  X(to_be_translated) Line 3148  X(to_be_translated)
3148                          break;                          break;
3149    
3150                  case PPC_31_SYNC:                  case PPC_31_SYNC:
                 case PPC_31_TLBSYNC:  
3151                  case PPC_31_EIEIO:                  case PPC_31_EIEIO:
3152                  case PPC_31_DCBST:                  case PPC_31_DCBST:
3153                  case PPC_31_DCBTST:                  case PPC_31_DCBTST:
3154                  case PPC_31_DCBF:                  case PPC_31_DCBF:
3155                  case PPC_31_DCBT:                  case PPC_31_DCBT:
3156                  case PPC_31_ICBI:                  case PPC_31_ICBI:
                         /*  TODO  */  
3157                          ic->f = instr(nop);                          ic->f = instr(nop);
3158                          break;                          break;
3159    
# Line 2358  X(to_be_translated) Line 3165  X(to_be_translated)
3165                          else                          else
3166                                  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);                                  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3167                          ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rb]);                          ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3168                            ic->arg[2] = addr & 0xfff;
3169                          ic->f = instr(dcbz);                          ic->f = instr(dcbz);
3170                          break;                          break;
3171    
3172                    case PPC_31_TLBIA:
3173                            ic->f = instr(tlbia);
3174                            break;
3175    
3176                    case PPC_31_TLBSYNC:
3177                            /*  According to IBM, "Ensures that a tlbie and
3178                                tlbia instruction executed by one processor has
3179                                completed on all other processors.", which in
3180                                GXemul means a nop :-)  */
3181                            ic->f = instr(nop);
3182                            break;
3183    
3184                  case PPC_31_TLBIE:                  case PPC_31_TLBIE:
3185                          /*  TODO  */                          /*  TODO: POWER also uses ra?  */
3186                            rb = (iword >> 11) & 31;
3187                            ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3188                          ic->f = instr(tlbie);                          ic->f = instr(tlbie);
3189                          break;                          break;
3190    
3191                    case PPC_31_TLBLD:      /*  takes an arg  */
3192                            rb = (iword >> 11) & 31;
3193                            ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3194                            ic->f = instr(tlbld);
3195                            break;
3196    
3197                    case PPC_31_TLBLI:      /*  takes an arg  */
3198                            rb = (iword >> 11) & 31;
3199                            ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3200                            ic->f = instr(tlbli);
3201                            break;
3202    
3203                  case PPC_31_MFTB:                  case PPC_31_MFTB:
3204                          rt = (iword >> 21) & 31;                          rt = (iword >> 21) & 31;
3205                          spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);                          spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
# Line 2398  X(to_be_translated) Line 3232  X(to_be_translated)
3232                          ic->f = instr(llsc);                          ic->f = instr(llsc);
3233                          break;                          break;
3234    
3235                    case PPC_31_LSWI:
3236                    case PPC_31_STSWI:
3237                            rs = (iword >> 21) & 31;
3238                            ra = (iword >> 16) & 31;
3239                            nb = (iword >> 11) & 31;
3240                            ic->arg[0] = rs;
3241                            if (ra == 0)
3242                                    ic->arg[1] = (size_t)(&cpu->cd.ppc.zero);
3243                            else
3244                                    ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3245                            ic->arg[2] = nb == 0? 32 : nb;
3246                            switch (xo) {
3247                            case PPC_31_LSWI:  ic->f = instr(lswi); break;
3248                            case PPC_31_STSWI: ic->f = instr(stswi); break;
3249                            }
3250                            break;
3251    
3252                    case 0x1c3:
3253                            fatal("[ mtdcr: TODO ]\n");
3254                            ic->f = instr(nop);
3255                            break;
3256    
3257                  case PPC_31_LBZX:                  case PPC_31_LBZX:
3258                  case PPC_31_LBZUX:                  case PPC_31_LBZUX:
3259                    case PPC_31_LHAX:
3260                    case PPC_31_LHAUX:
3261                  case PPC_31_LHZX:                  case PPC_31_LHZX:
3262                  case PPC_31_LHZUX:                  case PPC_31_LHZUX:
3263                  case PPC_31_LWZX:                  case PPC_31_LWZX:
3264                  case PPC_31_LWZUX:                  case PPC_31_LWZUX:
3265                    case PPC_31_LHBRX:
3266                    case PPC_31_LWBRX:
3267                    case PPC_31_LFDX:
3268                    case PPC_31_LFSX:
3269                  case PPC_31_STBX:                  case PPC_31_STBX:
3270                  case PPC_31_STBUX:                  case PPC_31_STBUX:
3271                  case PPC_31_STHX:                  case PPC_31_STHX:
# Line 2412  X(to_be_translated) Line 3274  X(to_be_translated)
3274                  case PPC_31_STWUX:                  case PPC_31_STWUX:
3275                  case PPC_31_STDX:                  case PPC_31_STDX:
3276                  case PPC_31_STDUX:                  case PPC_31_STDUX:
3277                    case PPC_31_STHBRX:
3278                    case PPC_31_STWBRX:
3279                    case PPC_31_STFDX:
3280                    case PPC_31_STFSX:
3281                          rs = (iword >> 21) & 31;                          rs = (iword >> 21) & 31;
3282                          ra = (iword >> 16) & 31;                          ra = (iword >> 16) & 31;
3283                          rb = (iword >> 11) & 31;                          rb = (iword >> 11) & 31;
                         ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);  
3284                          if (ra == 0)                          if (ra == 0)
3285                                  ic->arg[1] = (size_t)(&cpu->cd.ppc.zero);                                  ic->arg[1] = (size_t)(&cpu->cd.ppc.zero);
3286                          else                          else
3287                                  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);                                  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3288                          ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rb]);                          ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3289                          load = 0; zero = 1; size = 0; update = 0;                          load = 0; zero = 1; size = 0; update = 0;
3290                            byterev = 0; fp = 0;
3291                            ic->f = NULL;
3292                          switch (xo) {                          switch (xo) {
3293                          case PPC_31_LBZX:  load = 1; break;                          case PPC_31_LBZX:  load = 1; break;
3294                          case PPC_31_LBZUX: load = update = 1; break;                          case PPC_31_LBZUX: load=update=1; break;
3295                          case PPC_31_LHZX:  size = 1; load = 1; break;                          case PPC_31_LHAX:  size=1; load=1; zero=0; break;
3296                          case PPC_31_LHZUX: size = 1; load = update = 1; break;                          case PPC_31_LHAUX: size=1; load=update=1; zero=0; break;
3297                          case PPC_31_LWZX:  size = 2; load = 1; break;                          case PPC_31_LHZX:  size=1; load=1; break;
3298                          case PPC_31_LWZUX: size = 2; load = update = 1; break;                          case PPC_31_LHZUX: size=1; load=update = 1; break;
3299                            case PPC_31_LWZX:  size=2; load=1; break;
3300                            case PPC_31_LWZUX: size=2; load=update = 1; break;
3301                            case PPC_31_LHBRX: size=1; load=1; byterev=1;
3302                                               ic->f = instr(lhbrx); break;
3303                            case PPC_31_LWBRX: size=2; load=1; byterev=1;
3304                                               ic->f = instr(lwbrx); break;
3305                            case PPC_31_LFDX:  size=3; load=1; fp=1;
3306                                               ic->f = instr(lfdx); break;
3307                            case PPC_31_LFSX:  size=2; load=1; fp=1;
3308                                               ic->f = instr(lfsx); break;
3309                          case PPC_31_STBX:  break;                          case PPC_31_STBX:  break;
3310                          case PPC_31_STBUX: update = 1; break;                          case PPC_31_STBUX: update = 1; break;
3311                          case PPC_31_STHX:  size = 1; break;                          case PPC_31_STHX:  size=1; break;
3312                          case PPC_31_STHUX: size = 1; update = 1; break;                          case PPC_31_STHUX: size=1; update = 1; break;
3313                          case PPC_31_STWX:  size = 2; break;                          case PPC_31_STWX:  size=2; break;
3314                          case PPC_31_STWUX: size = 2; update = 1; break;                          case PPC_31_STWUX: size=2; update = 1; break;
3315                          case PPC_31_STDX:  size = 3; break;                          case PPC_31_STDX:  size=3; break;
3316                          case PPC_31_STDUX: size = 3; update = 1; break;                          case PPC_31_STDUX: size=3; update = 1; break;
3317                            case PPC_31_STHBRX:size=1; byterev = 1;
3318                                               ic->f = instr(sthbrx); break;
3319                            case PPC_31_STWBRX:size=2; byterev = 1;
3320                                               ic->f = instr(stwbrx); break;
3321                            case PPC_31_STFDX: size=3; fp=1;
3322                                               ic->f = instr(stfdx); break;
3323                            case PPC_31_STFSX: size=2; fp=1;
3324                                               ic->f = instr(stfsx); break;
3325                          }                          }
3326                          ic->f =                          if (fp)
3327                                    ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rs]);
3328                            else
3329                                    ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
3330                            if (!byterev && ic->f == NULL) {
3331                                    ic->f =
3332  #ifdef MODE32  #ifdef MODE32
3333                              ppc32_loadstore_indexed                                      ppc32_loadstore_indexed
3334  #else  #else
3335                              ppc_loadstore_indexed                                      ppc_loadstore_indexed
3336  #endif  #endif
3337                              [size + 4*zero + 8*load + 16*update];                                      [size + 4*zero + 8*load + 16*update];
3338                            }
3339                          if (ra == 0 && update) {                          if (ra == 0 && update) {
3340                                  fatal("TODO: ra=0 && update?\n");                                  fatal("TODO: ra=0 && update?\n");
3341                                  goto bad;                                  goto bad;
# Line 2517  X(to_be_translated) Line 3408  X(to_be_translated)
3408                  case PPC_31_SUBF:                  case PPC_31_SUBF:
3409                  case PPC_31_SUBFC:                  case PPC_31_SUBFC:
3410                  case PPC_31_SUBFE:                  case PPC_31_SUBFE:
3411                    case PPC_31_SUBFME:
3412                  case PPC_31_SUBFZE:                  case PPC_31_SUBFZE:
3413                          rt = (iword >> 21) & 31;                          rt = (iword >> 21) & 31;
3414                          ra = (iword >> 16) & 31;                          ra = (iword >> 16) & 31;
# Line 2541  X(to_be_translated) Line 3433  X(to_be_translated)
3433                          case PPC_31_SUBF:   ic->f = instr(subf); break;                          case PPC_31_SUBF:   ic->f = instr(subf); break;
3434                          case PPC_31_SUBFC:  ic->f = instr(subfc); break;                          case PPC_31_SUBFC:  ic->f = instr(subfc); break;
3435                          case PPC_31_SUBFE:  ic->f = instr(subfe); n64=1; break;                          case PPC_31_SUBFE:  ic->f = instr(subfe); n64=1; break;
3436                            case PPC_31_SUBFME: ic->f = instr(subfme); n64=1; break;
3437                          case PPC_31_SUBFZE: ic->f = instr(subfze); n64=1;break;                          case PPC_31_SUBFZE: ic->f = instr(subfze); n64=1;break;
3438                          }                          }
3439                          if (rc) {                          if (rc) {
# Line 2553  X(to_be_translated) Line 3446  X(to_be_translated)
3446                                          ic->f = instr(addme_dot); break;                                          ic->f = instr(addme_dot); break;
3447                                  case PPC_31_ADDZE:                                  case PPC_31_ADDZE:
3448                                          ic->f = instr(addze_dot); break;                                          ic->f = instr(addze_dot); break;
3449                                    case PPC_31_DIVW:
3450                                            ic->f = instr(divw_dot); break;
3451                                    case PPC_31_DIVWU:
3452                                            ic->f = instr(divwu_dot); break;
3453                                    case PPC_31_MULLW:
3454                                            ic->f = instr(mullw_dot); break;
3455                                    case PPC_31_MULHW:
3456                                            ic->f = instr(mulhw_dot); break;
3457                                    case PPC_31_MULHWU:
3458                                            ic->f = instr(mulhwu_dot); break;
3459                                  case PPC_31_SUBF:                                  case PPC_31_SUBF:
3460                                          ic->f = instr(subf_dot); break;                                          ic->f = instr(subf_dot); break;
3461                                  case PPC_31_SUBFC:                                  case PPC_31_SUBFC:
3462                                          ic->f = instr(subfc_dot); break;                                          ic->f = instr(subfc_dot); break;
3463                                  case PPC_31_SUBFE:                                  case PPC_31_SUBFE:
3464                                          ic->f = instr(subfe_dot); break;                                          ic->f = instr(subfe_dot); break;
3465                                    case PPC_31_SUBFME:
3466                                            ic->f = instr(subfme_dot); break;
3467                                  case PPC_31_SUBFZE:                                  case PPC_31_SUBFZE:
3468                                          ic->f = instr(subfze_dot); break;                                          ic->f = instr(subfze_dot); break;
3469                                  default:fatal("RC bit not yet implemented\n");                                  default:fatal("RC bit not yet implemented\n");
# Line 2578  X(to_be_translated) Line 3483  X(to_be_translated)
3483                  }                  }
3484                  break;                  break;
3485    
3486          case PPC_HI6_63:          case PPC_HI6_59:
3487                  xo = (iword >> 1) & 1023;                  xo = (iword >>  1) & 1023;
3488                  rt = (iword >> 21) & 31;                  rt = (iword >> 21) & 31;
3489                  ra = (iword >> 16) & 31;                  ra = (iword >> 16) & 31;
3490                  rb = (iword >> 11) & 31;                  rb = (iword >> 11) & 31;
3491                    rs = (iword >>  6) & 31;        /*  actually frc  */
3492                  rc = iword & 1;                  rc = iword & 1;
3493    
3494                  switch (xo) {                  if (rc) {
3495                            fatal("Floating point (59) with rc bit! TODO\n");
3496                            goto bad;
3497                    }
3498    
3499                  case PPC_63_FMR:                  /*  NOTE: Some floating-point instructions are selected
3500                          if (rc) {                      using only the lowest 5 bits, not all 10!  */
3501                                  fatal("FMR with rc-bit: TODO\n");                  switch (xo & 31) {
3502                                  goto bad;                  case PPC_59_FDIVS:
3503                          }                  case PPC_59_FSUBS:
3504                          ic->f = instr(fmr);                  case PPC_59_FADDS:
3505                          ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rb]);                          switch (xo & 31) {
3506                          ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[rt]);                          case PPC_59_FDIVS: ic->f = instr(fdivs); break;
3507                            case PPC_59_FSUBS: ic->f = instr(fsubs); break;
3508                            case PPC_59_FADDS: ic->f = instr(fadds); break;
3509                            }
3510                            ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[ra]);
3511                            ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[rb]);
3512                            ic->arg[2] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3513                            break;
3514                    case PPC_59_FMULS:
3515                            ic->f = instr(fmuls);
3516                            ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3517                            ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[ra]);
3518                            ic->arg[2] = (size_t)(&cpu->cd.ppc.fpr[rs]); /* frc */
3519                          break;                          break;
3520                    default:/*  Use all 10 bits of xo:  */
3521                            switch (xo) {
3522                            default:goto bad;
3523                            }
3524                    }
3525                    break;
3526    
3527                  default:goto bad;          case PPC_HI6_63:
3528                    xo = (iword >>  1) & 1023;
3529                    rt = (iword >> 21) & 31;
3530                    ra = (iword >> 16) & 31;
3531                    rb = (iword >> 11) & 31;
3532                    rs = (iword >>  6) & 31;        /*  actually frc  */
3533                    rc = iword & 1;
3534    
3535                    if (rc) {
3536                            fatal("Floating point (63) with rc bit! TODO\n");
3537                            goto bad;
3538                    }
3539    
3540                    /*  NOTE: Some floating-point instructions are selected
3541                        using only the lowest 5 bits, not all 10!  */
3542                    switch (xo & 31) {
3543                    case PPC_63_FDIV:
3544                    case PPC_63_FSUB:
3545                    case PPC_63_FADD:
3546                            switch (xo & 31) {
3547                            case PPC_63_FDIV: ic->f = instr(fdiv); break;
3548                            case PPC_63_FSUB: ic->f = instr(fsub); break;
3549                            case PPC_63_FADD: ic->f = instr(fadd); break;
3550                            }
3551                            ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[ra]);
3552                            ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[rb]);
3553                            ic->arg[2] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3554                            break;
3555                    case PPC_63_FMUL:
3556                            ic->f = instr(fmul);
3557                            ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3558                            ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[ra]);
3559                            ic->arg[2] = (size_t)(&cpu->cd.ppc.fpr[rs]); /* frc */
3560                            break;
3561                    case PPC_63_FMSUB:
3562                    case PPC_63_FMADD:
3563                            switch (xo & 31) {
3564                            case PPC_63_FMSUB: ic->f = instr(fmsub); break;
3565                            case PPC_63_FMADD: ic->f = instr(fmadd); break;
3566                            }
3567                            ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3568                            ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[ra]);
3569                            ic->arg[2] = iword;
3570                            break;
3571                    default:/*  Use all 10 bits of xo:  */
3572                            switch (xo) {
3573                            case PPC_63_FCMPU:
3574                                    ic->f = instr(fcmpu);
3575                                    ic->arg[0] = 28 - 4*(rt >> 2);
3576                                    ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[ra]);
3577                                    ic->arg[2] = (size_t)(&cpu->cd.ppc.fpr[rb]);
3578                                    break;
3579                            case PPC_63_FRSP:
3580                            case PPC_63_FCTIWZ:
3581                            case PPC_63_FNEG:
3582                            case PPC_63_FMR:
3583                                    switch (xo) {
3584                                    case PPC_63_FRSP:   ic->f = instr(frsp); break;
3585                                    case PPC_63_FCTIWZ: ic->f = instr(fctiwz);break;
3586                                    case PPC_63_FNEG:   ic->f = instr(fneg); break;
3587                                    case PPC_63_FMR:    ic->f = instr(fmr); break;
3588                                    }
3589                                    ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rb]);
3590                                    ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3591                                    break;
3592                            case PPC_63_MFFS:
3593                                    ic->f = instr(mffs);
3594                                    ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3595                                    break;
3596                            case PPC_63_MTFSF:
3597                                    ic->f = instr(mtfsf);
3598                                    ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rb]);
3599                                    ic->arg[1] = 0;
3600                                    for (bi=7; bi>=0; bi--) {
3601                                            ic->arg[1] <<= 8;
3602                                            if (iword & (1 << (17+bi)))
3603                                                    ic->arg[1] |= 0xf;
3604                                    }
3605                                    break;
3606                            default:goto bad;
3607                            }
3608                  }                  }
3609                  break;                  break;
3610    

Legend:
Removed from v.19  
changed lines
  Added in v.20

  ViewVC Help
Powered by ViewVC 1.1.26