cpu_ppc_instr.cc Source File

Back to the index.

cpu_ppc_instr.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2012 Anders Gavare. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * 3. The name of the author may not be used to endorse or promote products
13  * derived from this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  *
28  * POWER/PowerPC instructions.
29  *
30  * Individual functions should keep track of cpu->n_translated_instrs.
31  * (If no instruction was executed, then it should be decreased. If, say, 4
32  * instructions were combined into one function and executed, then it should
33  * be increased by 3.)
34  */
35 
36 
37 #include "float_emul.h"
38 
39 
40 #define DOT0(n) X(n ## _dot) { instr(n)(cpu,ic); \
41  update_cr0(cpu, reg(ic->arg[0])); }
42 #define DOT1(n) X(n ## _dot) { instr(n)(cpu,ic); \
43  update_cr0(cpu, reg(ic->arg[1])); }
44 #define DOT2(n) X(n ## _dot) { instr(n)(cpu,ic); \
45  update_cr0(cpu, reg(ic->arg[2])); }
46 
47 #ifndef CHECK_FOR_FPU_EXCEPTION
48 #define CHECK_FOR_FPU_EXCEPTION { if (!(cpu->cd.ppc.msr & PPC_MSR_FP)) { \
49  /* Synchronize the PC, and cause an FPU exception: */ \
50  uint64_t low_pc = ((size_t)ic - \
51  (size_t)cpu->cd.ppc.cur_ic_page) \
52  / sizeof(struct ppc_instr_call); \
53  cpu->pc = (cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << \
54  PPC_INSTR_ALIGNMENT_SHIFT)) + (low_pc << \
55  PPC_INSTR_ALIGNMENT_SHIFT); \
56  ppc_exception(cpu, PPC_EXCEPTION_FPU); \
57  return; } }
58 #endif
59 
60 
61 
62 /*
63  * nop: Do nothing.
64  */
66 {
67 }
68 
69 
70 /*
71  * invalid: To catch bugs.
72  */
73 X(invalid)
74 {
75  fatal("PPC: invalid(): INTERNAL ERROR\n");
76  exit(1);
77 }
78 
79 
80 /*
81  * addi: Add immediate.
82  *
83  * arg[0] = pointer to source uint64_t
84  * arg[1] = immediate value (int32_t or larger)
85  * arg[2] = pointer to destination uint64_t
86  */
87 X(addi)
88 {
89  reg(ic->arg[2]) = reg(ic->arg[0]) + (int32_t)ic->arg[1];
90 }
91 X(li)
92 {
93  reg(ic->arg[2]) = (int32_t)ic->arg[1];
94 }
95 X(li_0)
96 {
97  reg(ic->arg[2]) = 0;
98 }
99 
100 
101 /*
102  * andi_dot: AND immediate, update CR.
103  *
104  * arg[0] = pointer to source uint64_t
105  * arg[1] = immediate value (uint32_t)
106  * arg[2] = pointer to destination uint64_t
107  */
108 X(andi_dot)
109 {
110  MODE_uint_t tmp = reg(ic->arg[0]) & (uint32_t)ic->arg[1];
111  reg(ic->arg[2]) = tmp;
112  update_cr0(cpu, tmp);
113 }
114 
115 
116 /*
117  * addic: Add immediate, Carry.
118  *
119  * arg[0] = pointer to source register
120  * arg[1] = immediate value (int32_t or larger)
121  * arg[2] = pointer to destination register
122  */
123 X(addic)
124 {
125  /* TODO/NOTE: Only for 32-bit mode, so far! */
126  uint64_t tmp = (uint32_t)reg(ic->arg[0]);
127  uint64_t tmp2 = tmp;
128  cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
129  tmp2 += (uint32_t)ic->arg[1];
130  if ((tmp2 >> 32) != (tmp >> 32))
132  reg(ic->arg[2]) = (uint32_t)tmp2;
133 }
134 
135 
136 /*
137  * subfic: Subtract from immediate, Carry.
138  *
139  * arg[0] = pointer to source uint64_t
140  * arg[1] = immediate value (int32_t or larger)
141  * arg[2] = pointer to destination uint64_t
142  */
143 X(subfic)
144 {
145  MODE_uint_t tmp = (int64_t)(int32_t)ic->arg[1];
146  cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
147  if (tmp >= reg(ic->arg[0]))
149  reg(ic->arg[2]) = tmp - reg(ic->arg[0]);
150 }
151 
152 
153 /*
154  * addic_dot: Add immediate, Carry.
155  *
156  * arg[0] = pointer to source uint64_t
157  * arg[1] = immediate value (int32_t or larger)
158  * arg[2] = pointer to destination uint64_t
159  */
160 X(addic_dot)
161 {
162  /* TODO/NOTE: Only for 32-bit mode, so far! */
163  uint64_t tmp = (uint32_t)reg(ic->arg[0]);
164  uint64_t tmp2 = tmp;
165  cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
166  tmp2 += (uint32_t)ic->arg[1];
167  if ((tmp2 >> 32) != (tmp >> 32))
169  reg(ic->arg[2]) = (uint32_t)tmp2;
170  update_cr0(cpu, (uint32_t)tmp2);
171 }
172 
173 
174 /*
175  * bclr: Branch Conditional to Link Register
176  *
177  * arg[0] = bo
178  * arg[1] = 31 - bi
179  * arg[2] = bh
180  */
181 X(bclr)
182 {
183  unsigned int bo = ic->arg[0], bi31m = ic->arg[1];
184  int ctr_ok, cond_ok;
185  uint64_t old_pc = cpu->pc;
186  MODE_uint_t tmp, addr = cpu->cd.ppc.spr[SPR_LR];
187  if (!(bo & 4))
188  cpu->cd.ppc.spr[SPR_CTR] --;
189  ctr_ok = (bo >> 2) & 1;
190  tmp = cpu->cd.ppc.spr[SPR_CTR];
191  ctr_ok |= ( (tmp == 0) == ((bo >> 1) & 1) );
192  cond_ok = (bo >> 4) & 1;
193  cond_ok |= ( ((bo >> 3) & 1) == ((cpu->cd.ppc.cr >> bi31m) & 1) );
194  if (ctr_ok && cond_ok) {
195  uint64_t mask_within_page =
197  | ((1 << PPC_INSTR_ALIGNMENT_SHIFT) - 1);
198  cpu->pc = addr & ~((1 << PPC_INSTR_ALIGNMENT_SHIFT) - 1);
199  /* TODO: trace in separate (duplicate) function? */
202  if ((old_pc & ~mask_within_page) ==
203  (cpu->pc & ~mask_within_page)) {
204  cpu->cd.ppc.next_ic =
205  cpu->cd.ppc.cur_ic_page +
206  ((cpu->pc & mask_within_page) >>
208  } else {
209  /* Find the new physical page and update pointers: */
211  }
212  }
213 }
214 X(bclr_20)
215 {
216  cpu->pc = cpu->cd.ppc.spr[SPR_LR];
218 }
219 X(bclr_l)
220 {
221  uint64_t low_pc, old_pc = cpu->pc;
222  unsigned int bo = ic->arg[0], bi31m = ic->arg[1] /* ,bh = ic->arg[2]*/;
223  int ctr_ok, cond_ok;
224  MODE_uint_t tmp, addr = cpu->cd.ppc.spr[SPR_LR];
225  if (!(bo & 4))
226  cpu->cd.ppc.spr[SPR_CTR] --;
227  ctr_ok = (bo >> 2) & 1;
228  tmp = cpu->cd.ppc.spr[SPR_CTR];
229  ctr_ok |= ( (tmp == 0) == ((bo >> 1) & 1) );
230  cond_ok = (bo >> 4) & 1;
231  cond_ok |= ( ((bo >> 3) & 1) == ((cpu->cd.ppc.cr >> bi31m) & 1) );
232 
233  /* Calculate return PC: */
234  low_pc = ((size_t)ic - (size_t)
235  cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call) + 1;
238  cpu->cd.ppc.spr[SPR_LR] += (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
239 
240  if (ctr_ok && cond_ok) {
241  uint64_t mask_within_page =
243  | ((1 << PPC_INSTR_ALIGNMENT_SHIFT) - 1);
244  cpu->pc = addr & ~((1 << PPC_INSTR_ALIGNMENT_SHIFT) - 1);
245  /* TODO: trace in separate (duplicate) function? */
250  if ((old_pc & ~mask_within_page) ==
251  (cpu->pc & ~mask_within_page)) {
252  cpu->cd.ppc.next_ic =
253  cpu->cd.ppc.cur_ic_page +
254  ((cpu->pc & mask_within_page) >>
256  } else {
257  /* Find the new physical page and update pointers: */
259  }
260  }
261 }
262 
263 
264 /*
265  * bcctr: Branch Conditional to Count register
266  *
267  * arg[0] = bo
268  * arg[1] = 31 - bi
269  * arg[2] = bh
270  */
271 X(bcctr)
272 {
273  unsigned int bo = ic->arg[0], bi31m = ic->arg[1];
274  uint64_t old_pc = cpu->pc;
276  int cond_ok = (bo >> 4) & 1;
277  cond_ok |= ( ((bo >> 3) & 1) == ((cpu->cd.ppc.cr >> bi31m) & 1) );
278  if (cond_ok) {
279  uint64_t mask_within_page =
281  | ((1 << PPC_INSTR_ALIGNMENT_SHIFT) - 1);
282  cpu->pc = addr & ~((1 << PPC_INSTR_ALIGNMENT_SHIFT) - 1);
283  /* TODO: trace in separate (duplicate) function? */
286  if ((old_pc & ~mask_within_page) ==
287  (cpu->pc & ~mask_within_page)) {
288  cpu->cd.ppc.next_ic =
289  cpu->cd.ppc.cur_ic_page +
290  ((cpu->pc & mask_within_page) >>
292  } else {
293  /* Find the new physical page and update pointers: */
295  }
296  }
297 }
298 X(bcctr_l)
299 {
300  uint64_t low_pc, old_pc = cpu->pc;
301  unsigned int bo = ic->arg[0], bi31m = ic->arg[1] /*,bh = ic->arg[2] */;
303  int cond_ok = (bo >> 4) & 1;
304  cond_ok |= ( ((bo >> 3) & 1) == ((cpu->cd.ppc.cr >> bi31m) & 1) );
305 
306  /* Calculate return PC: */
307  low_pc = ((size_t)ic - (size_t)
308  cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call) + 1;
311  cpu->cd.ppc.spr[SPR_LR] += (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
312 
313  if (cond_ok) {
314  uint64_t mask_within_page =
316  | ((1 << PPC_INSTR_ALIGNMENT_SHIFT) - 1);
317  cpu->pc = addr & ~((1 << PPC_INSTR_ALIGNMENT_SHIFT) - 1);
318  /* TODO: trace in separate (duplicate) function? */
321  if ((old_pc & ~mask_within_page) ==
322  (cpu->pc & ~mask_within_page)) {
323  cpu->cd.ppc.next_ic =
324  cpu->cd.ppc.cur_ic_page +
325  ((cpu->pc & mask_within_page) >>
327  } else {
328  /* Find the new physical page and update pointers: */
330  }
331  }
332 }
333 
334 
335 /*
336  * b: Branch (to a different translated page)
337  *
338  * arg[0] = relative offset (as an int32_t) from start of page
339  */
340 X(b)
341 {
343  cpu->pc += (int32_t)ic->arg[0];
344 
345  /* Find the new physical page and update the translation pointers: */
347 }
348 X(ba)
349 {
350  cpu->pc = (int32_t)ic->arg[0];
352 }
353 
354 
355 /*
356  * bc: Branch Conditional (to a different translated page)
357  *
358  * arg[0] = relative offset (as an int32_t) from start of page
359  * arg[1] = bo
360  * arg[2] = 31-bi
361  */
362 X(bc)
363 {
364  MODE_uint_t tmp;
365  unsigned int ctr_ok, cond_ok, bi31m = ic->arg[2], bo = ic->arg[1];
366  if (!(bo & 4))
367  cpu->cd.ppc.spr[SPR_CTR] --;
368  ctr_ok = (bo >> 2) & 1;
369  tmp = cpu->cd.ppc.spr[SPR_CTR];
370  ctr_ok |= ( (tmp == 0) == ((bo >> 1) & 1) );
371  cond_ok = (bo >> 4) & 1;
372  cond_ok |= ( ((bo >> 3) & 1) ==
373  ((cpu->cd.ppc.cr >> (bi31m)) & 1) );
374  if (ctr_ok && cond_ok)
375  instr(b)(cpu,ic);
376 }
377 X(bcl)
378 {
379  MODE_uint_t tmp;
380  unsigned int ctr_ok, cond_ok, bi31m = ic->arg[2], bo = ic->arg[1];
381  int low_pc;
382 
383  /* Calculate LR: */
384  low_pc = ((size_t)ic - (size_t)
385  cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call) + 1;
388  cpu->cd.ppc.spr[SPR_LR] += (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
389 
390  if (!(bo & 4))
391  cpu->cd.ppc.spr[SPR_CTR] --;
392  ctr_ok = (bo >> 2) & 1;
393  tmp = cpu->cd.ppc.spr[SPR_CTR];
394  ctr_ok |= ( (tmp == 0) == ((bo >> 1) & 1) );
395  cond_ok = (bo >> 4) & 1;
396  cond_ok |= ( ((bo >> 3) & 1) ==
397  ((cpu->cd.ppc.cr >> bi31m) & 1) );
398  if (ctr_ok && cond_ok)
399  instr(b)(cpu,ic);
400 }
401 
402 
403 /*
404  * b_samepage: Branch (to within the same translated page)
405  *
406  * arg[0] = pointer to new ppc_instr_call
407  */
408 X(b_samepage)
409 {
410  cpu->cd.ppc.next_ic = (struct ppc_instr_call *) ic->arg[0];
411 }
412 
413 
414 /*
415  * bc_samepage: Branch Conditional (to within the same page)
416  *
417  * arg[0] = new ic ptr
418  * arg[1] = bo
419  * arg[2] = 31-bi
420  */
421 X(bc_samepage)
422 {
423  MODE_uint_t tmp;
424  unsigned int ctr_ok, cond_ok, bi31m = ic->arg[2], bo = ic->arg[1];
425  if (!(bo & 4))
426  cpu->cd.ppc.spr[SPR_CTR] --;
427  ctr_ok = (bo >> 2) & 1;
428  tmp = cpu->cd.ppc.spr[SPR_CTR];
429  ctr_ok |= ( (tmp == 0) == ((bo >> 1) & 1) );
430  cond_ok = (bo >> 4) & 1;
431  cond_ok |= ( ((bo >> 3) & 1) ==
432  ((cpu->cd.ppc.cr >> bi31m) & 1) );
433  if (ctr_ok && cond_ok)
434  cpu->cd.ppc.next_ic = (struct ppc_instr_call *) ic->arg[0];
435 }
436 X(bc_samepage_simple0)
437 {
438  int bi31m = ic->arg[2];
439  if (!((cpu->cd.ppc.cr >> bi31m) & 1))
440  cpu->cd.ppc.next_ic = (struct ppc_instr_call *) ic->arg[0];
441 }
442 X(bc_samepage_simple1)
443 {
444  int bi31m = ic->arg[2];
445  if ((cpu->cd.ppc.cr >> bi31m) & 1)
446  cpu->cd.ppc.next_ic = (struct ppc_instr_call *) ic->arg[0];
447 }
448 X(bcl_samepage)
449 {
450  MODE_uint_t tmp;
451  unsigned int ctr_ok, cond_ok, bi31m = ic->arg[2], bo = ic->arg[1];
452  int low_pc;
453 
454  /* Calculate LR: */
455  low_pc = ((size_t)ic - (size_t)
456  cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call) + 1;
459  cpu->cd.ppc.spr[SPR_LR] += (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
460 
461  if (!(bo & 4))
462  cpu->cd.ppc.spr[SPR_CTR] --;
463  ctr_ok = (bo >> 2) & 1;
464  tmp = cpu->cd.ppc.spr[SPR_CTR];
465  ctr_ok |= ( (tmp == 0) == ((bo >> 1) & 1) );
466  cond_ok = (bo >> 4) & 1;
467  cond_ok |= ( ((bo >> 3) & 1) ==
468  ((cpu->cd.ppc.cr >> bi31m) & 1) );
469  if (ctr_ok && cond_ok)
470  cpu->cd.ppc.next_ic = (struct ppc_instr_call *) ic->arg[0];
471 }
472 
473 
474 /*
475  * bl: Branch and Link (to a different translated page)
476  *
477  * arg[0] = relative offset (as an int32_t) from start of page
478  * arg[1] = lr offset (relative to start of current page)
479  */
480 X(bl)
481 {
482  /* Calculate LR and new PC: */
484  cpu->cd.ppc.spr[SPR_LR] = cpu->pc + ic->arg[1];
485  cpu->pc += (int32_t)ic->arg[0];
486 
487  /* Find the new physical page and update the translation pointers: */
489 }
490 X(bla)
491 {
492  /* Calculate LR: */
494  << PPC_INSTR_ALIGNMENT_SHIFT)) + ic->arg[1];
495 
496  cpu->pc = (int32_t)ic->arg[0];
498 }
499 
500 
501 /*
502  * bl_trace: Branch and Link (to a different translated page) (with trace)
503  *
504  * arg[0] = relative offset (as an int32_t) from start of page
505  * arg[1] = lr offset (relative to start of current page)
506  */
507 X(bl_trace)
508 {
509  /* Calculate LR: */
511  << PPC_INSTR_ALIGNMENT_SHIFT)) + ic->arg[1];
512 
513  /* Calculate new PC from start of page + arg[0] */
515  cpu->pc += (int32_t)ic->arg[0];
516 
518 
519  /* Find the new physical page and update the translation pointers: */
521 }
522 X(bla_trace)
523 {
524  /* Calculate LR: */
526  << PPC_INSTR_ALIGNMENT_SHIFT)) + ic->arg[1];
527 
528  cpu->pc = (int32_t)ic->arg[0];
531 }
532 
533 
534 /*
535  * bl_samepage: Branch and Link (to within the same translated page)
536  *
537  * arg[0] = pointer to new ppc_instr_call
538  * arg[1] = lr offset (relative to start of current page)
539  */
540 X(bl_samepage)
541 {
542  /* Calculate LR: */
544  << PPC_INSTR_ALIGNMENT_SHIFT)) + ic->arg[1];
545 
546  cpu->cd.ppc.next_ic = (struct ppc_instr_call *) ic->arg[0];
547 }
548 
549 
550 /*
551  * bl_samepage_trace: Branch and Link (to within the same translated page)
552  *
553  * arg[0] = pointer to new ppc_instr_call
554  * arg[1] = lr offset (relative to start of current page)
555  */
556 X(bl_samepage_trace)
557 {
558  uint32_t low_pc;
559 
560  /* Calculate LR: */
562  << PPC_INSTR_ALIGNMENT_SHIFT)) + ic->arg[1];
563 
564  cpu->cd.ppc.next_ic = (struct ppc_instr_call *) ic->arg[0];
565 
566  /* Calculate new PC (for the trace) */
567  low_pc = ((size_t)cpu->cd.ppc.next_ic - (size_t)
568  cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
570  cpu->pc += (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
572 }
573 
574 
575 /*
576  * cntlzw: Count leading zeroes (32-bit word).
577  *
578  * arg[0] = ptr to rs
579  * arg[1] = ptr to ra
580  */
581 X(cntlzw)
582 {
583  uint32_t tmp = reg(ic->arg[0]);
584  int i;
585  for (i=0; i<32; i++) {
586  if (tmp & 0x80000000)
587  break;
588  tmp <<= 1;
589  }
590  reg(ic->arg[1]) = i;
591 }
592 
593 
594 /*
595  * cmpd: Compare Doubleword
596  *
597  * arg[0] = ptr to ra
598  * arg[1] = ptr to rb
599  * arg[2] = 28 - 4*bf
600  */
601 X(cmpd)
602 {
603  int64_t tmp = reg(ic->arg[0]), tmp2 = reg(ic->arg[1]);
604  int bf_shift = ic->arg[2], c;
605  if (tmp < tmp2)
606  c = 8;
607  else if (tmp > tmp2)
608  c = 4;
609  else
610  c = 2;
611  /* SO bit, copied from XER */
612  c |= ((cpu->cd.ppc.spr[SPR_XER] >> 31) & 1);
613  cpu->cd.ppc.cr &= ~(0xf << bf_shift);
614  cpu->cd.ppc.cr |= (c << bf_shift);
615 }
616 
617 
618 /*
619  * cmpld: Compare Doubleword, unsigned
620  *
621  * arg[0] = ptr to ra
622  * arg[1] = ptr to rb
623  * arg[2] = 28 - 4*bf
624  */
625 X(cmpld)
626 {
627  uint64_t tmp = reg(ic->arg[0]), tmp2 = reg(ic->arg[1]);
628  int bf_shift = ic->arg[2], c;
629  if (tmp < tmp2)
630  c = 8;
631  else if (tmp > tmp2)
632  c = 4;
633  else
634  c = 2;
635  /* SO bit, copied from XER */
636  c |= ((cpu->cd.ppc.spr[SPR_XER] >> 31) & 1);
637  cpu->cd.ppc.cr &= ~(0xf << bf_shift);
638  cpu->cd.ppc.cr |= (c << bf_shift);
639 }
640 
641 
642 /*
643  * cmpdi: Compare Doubleword immediate
644  *
645  * arg[0] = ptr to ra
646  * arg[1] = int32_t imm
647  * arg[2] = 28 - 4*bf
648  */
649 X(cmpdi)
650 {
651  int64_t tmp = reg(ic->arg[0]), imm = (int32_t)ic->arg[1];
652  int bf_shift = ic->arg[2], c;
653  if (tmp < imm)
654  c = 8;
655  else if (tmp > imm)
656  c = 4;
657  else
658  c = 2;
659  /* SO bit, copied from XER */
660  c |= ((cpu->cd.ppc.spr[SPR_XER] >> 31) & 1);
661  cpu->cd.ppc.cr &= ~(0xf << bf_shift);
662  cpu->cd.ppc.cr |= (c << bf_shift);
663 }
664 
665 
666 /*
667  * cmpldi: Compare Doubleword immediate, logical
668  *
669  * arg[0] = ptr to ra
670  * arg[1] = int32_t imm
671  * arg[2] = 28 - 4*bf
672  */
673 X(cmpldi)
674 {
675  uint64_t tmp = reg(ic->arg[0]), imm = (uint32_t)ic->arg[1];
676  int bf_shift = ic->arg[2], c;
677  if (tmp < imm)
678  c = 8;
679  else if (tmp > imm)
680  c = 4;
681  else
682  c = 2;
683  /* SO bit, copied from XER */
684  c |= ((cpu->cd.ppc.spr[SPR_XER] >> 31) & 1);
685  cpu->cd.ppc.cr &= ~(0xf << bf_shift);
686  cpu->cd.ppc.cr |= (c << bf_shift);
687 }
688 
689 
690 /*
691  * cmpw: Compare Word
692  *
693  * arg[0] = ptr to ra
694  * arg[1] = ptr to rb
695  * arg[2] = 28 - 4*bf
696  */
697 X(cmpw)
698 {
699  int32_t tmp = reg(ic->arg[0]), tmp2 = reg(ic->arg[1]);
700  int bf_shift = ic->arg[2], c;
701  if (tmp < tmp2)
702  c = 8;
703  else if (tmp > tmp2)
704  c = 4;
705  else
706  c = 2;
707  /* SO bit, copied from XER */
708  c |= ((cpu->cd.ppc.spr[SPR_XER] >> 31) & 1);
709  cpu->cd.ppc.cr &= ~(0xf << bf_shift);
710  cpu->cd.ppc.cr |= (c << bf_shift);
711 }
712 X(cmpw_cr0)
713 {
714  /* arg[2] is assumed to be 28 */
715  int32_t tmp = reg(ic->arg[0]), tmp2 = reg(ic->arg[1]);
716  cpu->cd.ppc.cr &= ~(0xf0000000);
717  if (tmp < tmp2)
718  cpu->cd.ppc.cr |= 0x80000000;
719  else if (tmp > tmp2)
720  cpu->cd.ppc.cr |= 0x40000000;
721  else
722  cpu->cd.ppc.cr |= 0x20000000;
723  cpu->cd.ppc.cr |= ((cpu->cd.ppc.spr[SPR_XER] >> 3) & 0x10000000);
724 }
725 
726 
727 /*
728  * cmplw: Compare Word, unsigned
729  *
730  * arg[0] = ptr to ra
731  * arg[1] = ptr to rb
732  * arg[2] = 28 - 4*bf
733  */
734 X(cmplw)
735 {
736  uint32_t tmp = reg(ic->arg[0]), tmp2 = reg(ic->arg[1]);
737  int bf_shift = ic->arg[2], c;
738  if (tmp < tmp2)
739  c = 8;
740  else if (tmp > tmp2)
741  c = 4;
742  else
743  c = 2;
744  /* SO bit, copied from XER */
745  c |= ((cpu->cd.ppc.spr[SPR_XER] >> 31) & 1);
746  cpu->cd.ppc.cr &= ~(0xf << bf_shift);
747  cpu->cd.ppc.cr |= (c << bf_shift);
748 }
749 
750 
751 /*
752  * cmpwi: Compare Word immediate
753  *
754  * arg[0] = ptr to ra
755  * arg[1] = int32_t imm
756  * arg[2] = 28 - 4*bf
757  */
758 X(cmpwi)
759 {
760  int32_t tmp = reg(ic->arg[0]), imm = ic->arg[1];
761  int bf_shift = ic->arg[2], c;
762  if (tmp < imm)
763  c = 8;
764  else if (tmp > imm)
765  c = 4;
766  else
767  c = 2;
768  /* SO bit, copied from XER */
769  c |= ((cpu->cd.ppc.spr[SPR_XER] >> 31) & 1);
770  cpu->cd.ppc.cr &= ~(0xf << bf_shift);
771  cpu->cd.ppc.cr |= (c << bf_shift);
772 }
773 X(cmpwi_cr0)
774 {
775  /* arg[2] is assumed to be 28 */
776  int32_t tmp = reg(ic->arg[0]), imm = ic->arg[1];
777  cpu->cd.ppc.cr &= ~(0xf0000000);
778  if (tmp < imm)
779  cpu->cd.ppc.cr |= 0x80000000;
780  else if (tmp > imm)
781  cpu->cd.ppc.cr |= 0x40000000;
782  else
783  cpu->cd.ppc.cr |= 0x20000000;
784  cpu->cd.ppc.cr |= ((cpu->cd.ppc.spr[SPR_XER] >> 3) & 0x10000000);
785 }
786 
787 
788 /*
789  * cmplwi: Compare Word immediate, logical
790  *
791  * arg[0] = ptr to ra
792  * arg[1] = int32_t imm
793  * arg[2] = 28 - 4*bf
794  */
795 X(cmplwi)
796 {
797  uint32_t tmp = reg(ic->arg[0]), imm = ic->arg[1];
798  int bf_shift = ic->arg[2], c;
799  if (tmp < imm)
800  c = 8;
801  else if (tmp > imm)
802  c = 4;
803  else
804  c = 2;
805  /* SO bit, copied from XER */
806  c |= ((cpu->cd.ppc.spr[SPR_XER] >> 31) & 1);
807  cpu->cd.ppc.cr &= ~(0xf << bf_shift);
808  cpu->cd.ppc.cr |= (c << bf_shift);
809 }
810 
811 
812 /*
813  * dcbz: Data-Cache Block Zero
814  *
815  * arg[0] = ptr to ra (or zero)
816  * arg[1] = ptr to rb
817  */
818 X(dcbz)
819 {
820  MODE_uint_t addr = reg(ic->arg[0]) + reg(ic->arg[1]);
821  unsigned char cacheline[128];
822  size_t cacheline_size = 1 << cpu->cd.ppc.cpu_type.dlinesize;
823  size_t cleared = 0;
824 
825  /* Synchronize the PC first: */
826  cpu->pc = (cpu->pc & ~0xfff) + ic->arg[2];
827 
828  addr &= ~(cacheline_size - 1);
829  memset(cacheline, 0, sizeof(cacheline));
830 
831  while (cleared < cacheline_size) {
832  int to_clear = cacheline_size < sizeof(cacheline)?
833  cacheline_size : sizeof(cacheline);
834 #ifdef MODE32
835  unsigned char *page = cpu->cd.ppc.host_store[addr >> 12];
836  if (page != NULL) {
837  memset(page + (addr & 0xfff), 0, to_clear);
838  } else
839 #endif
840  if (cpu->memory_rw(cpu, cpu->mem, addr, cacheline,
841  to_clear, MEM_WRITE, CACHE_DATA) != MEMORY_ACCESS_OK) {
842  /* exception */
843  return;
844  }
845 
846  cleared += to_clear;
847  addr += to_clear;
848  }
849 }
850 
851 
852 /*
853  * mtfsf: Copy FPR into the FPSCR.
854  *
855  * arg[0] = ptr to frb
856  * arg[1] = mask
857  */
858 X(mtfsf)
859 {
861  cpu->cd.ppc.fpscr &= ~ic->arg[1];
862  cpu->cd.ppc.fpscr |= (ic->arg[1] & (*(uint64_t *)ic->arg[0]));
863 }
864 
865 
866 /*
867  * mffs: Copy FPSCR into a FPR.
868  *
869  * arg[0] = ptr to frt
870  */
871 X(mffs)
872 {
874  (*(uint64_t *)ic->arg[0]) = cpu->cd.ppc.fpscr;
875 }
876 
877 
878 /*
879  * fmr: Floating-point Move
880  *
881  * arg[0] = ptr to frb
882  * arg[1] = ptr to frt
883  */
884 X(fmr)
885 {
886  /*
887  * This works like a normal register to register copy, but
888  * a) it can cause an FPU exception, and b) the move is always
889  * 64-bit, even when running in 32-bit mode.
890  */
892  *(uint64_t *)ic->arg[1] = *(uint64_t *)ic->arg[0];
893 }
894 
895 
896 /*
897  * fabs: Floating-point Absulute Value
898  *
899  * arg[0] = ptr to frb
900  * arg[1] = ptr to frt
901  */
902 X(fabs)
903 {
904  uint64_t v;
906  v = *(uint64_t *)ic->arg[0];
907  *(uint64_t *)ic->arg[1] = v & 0x7fffffffffffffffULL;
908 }
909 
910 
911 /*
912  * fneg: Floating-point Negate
913  *
914  * arg[0] = ptr to frb
915  * arg[1] = ptr to frt
916  */
917 X(fneg)
918 {
919  uint64_t v;
921  v = *(uint64_t *)ic->arg[0];
922  *(uint64_t *)ic->arg[1] = v ^ 0x8000000000000000ULL;
923 }
924 
925 
926 /*
927  * fcmpu: Floating-point Compare Unordered
928  *
929  * arg[0] = 28 - 4*bf (bitfield shift)
930  * arg[1] = ptr to fra
931  * arg[2] = ptr to frb
932  */
933 X(fcmpu)
934 {
935  struct ieee_float_value fra, frb;
936  int bf_shift = ic->arg[0], c = 0;
937 
939 
940  ieee_interpret_float_value(*(uint64_t *)ic->arg[1], &fra, IEEE_FMT_D);
941  ieee_interpret_float_value(*(uint64_t *)ic->arg[2], &frb, IEEE_FMT_D);
942  if (fra.nan | frb.nan) {
943  c = 1;
944  } else {
945  if (fra.f < frb.f)
946  c = 8;
947  else if (fra.f > frb.f)
948  c = 4;
949  else
950  c = 2;
951  }
952  /* TODO: Signaling vs Quiet NaN */
953  cpu->cd.ppc.cr &= ~(0xf << bf_shift);
954  cpu->cd.ppc.cr |= ((c&0xe) << bf_shift);
956  cpu->cd.ppc.fpscr |= (c << PPC_FPSCR_FPCC_SHIFT);
957 }
958 
959 
960 /*
961  * frsp: Floating-point Round to Single Precision
962  *
963  * arg[0] = ptr to frb
964  * arg[1] = ptr to frt
965  */
966 X(frsp)
967 {
968  struct ieee_float_value frb;
969  float fl = 0.0;
970  int c = 0;
971 
973 
974  ieee_interpret_float_value(*(uint64_t *)ic->arg[0], &frb, IEEE_FMT_D);
975  if (frb.nan) {
976  c = 1;
977  } else {
978  fl = frb.f;
979  if (fl < 0.0)
980  c = 8;
981  else if (fl > 0.0)
982  c = 4;
983  else
984  c = 2;
985  }
986  /* TODO: Signaling vs Quiet NaN */
988  cpu->cd.ppc.fpscr |= (c << PPC_FPSCR_FPCC_SHIFT);
989  (*(uint64_t *)ic->arg[1]) =
991 }
992 
993 
994 /*
995  * fctiwz: Floating-point Convert to Integer Word, Round to Zero
996  *
997  * arg[0] = ptr to frb
998  * arg[1] = ptr to frt
999  */
1000 X(fctiwz)
1001 {
1002  struct ieee_float_value frb;
1003  uint32_t res = 0;
1004 
1006 
1007  ieee_interpret_float_value(*(uint64_t *)ic->arg[0], &frb, IEEE_FMT_D);
1008  if (!frb.nan) {
1009  if (frb.f >= 2147483647.0)
1010  res = 0x7fffffff;
1011  else if (frb.f <= -2147483648.0)
1012  res = 0x80000000;
1013  else
1014  res = (int32_t) frb.f;
1015  }
1016 
1017  *(uint64_t *)ic->arg[1] = (uint32_t)res;
1018 }
1019 
1020 
1021 /*
1022  * fmul: Floating-point Multiply
1023  *
1024  * arg[0] = ptr to frt
1025  * arg[1] = ptr to fra
1026  * arg[2] = ptr to frc
1027  */
1028 X(fmul)
1029 {
1030  struct ieee_float_value fra;
1031  struct ieee_float_value frc;
1032  double result = 0.0;
1033  int c, nan = 0;
1034 
1036 
1037  ieee_interpret_float_value(*(uint64_t *)ic->arg[1], &fra, IEEE_FMT_D);
1038  ieee_interpret_float_value(*(uint64_t *)ic->arg[2], &frc, IEEE_FMT_D);
1039  if (fra.nan || frc.nan)
1040  nan = 1;
1041  else
1042  result = fra.f * frc.f;
1043  if (nan)
1044  c = 1;
1045  else {
1046  if (result < 0.0)
1047  c = 8;
1048  else if (result > 0.0)
1049  c = 4;
1050  else
1051  c = 2;
1052  }
1053  /* TODO: Signaling vs Quiet NaN */
1055  cpu->cd.ppc.fpscr |= (c << PPC_FPSCR_FPCC_SHIFT);
1056 
1057  (*(uint64_t *)ic->arg[0]) =
1058  ieee_store_float_value(result, IEEE_FMT_D, nan);
1059 }
1060 X(fmuls)
1061 {
1062  /* TODO */
1063  instr(fmul)(cpu, ic);
1064 }
1065 
1066 
1067 /*
1068  * fmadd: Floating-point Multiply and Add
1069  *
1070  * arg[0] = ptr to frt
1071  * arg[1] = ptr to fra
1072  * arg[2] = copy of the instruction word
1073  */
1074 X(fmadd)
1075 {
1076  uint32_t iw = ic->arg[2];
1077  int b = (iw >> 11) & 31, c = (iw >> 6) & 31;
1078  struct ieee_float_value fra;
1079  struct ieee_float_value frb;
1080  struct ieee_float_value frc;
1081  double result = 0.0;
1082  int nan = 0, cc;
1083 
1085 
1086  ieee_interpret_float_value(*(uint64_t *)ic->arg[1], &fra, IEEE_FMT_D);
1089  if (fra.nan || frb.nan || frc.nan)
1090  nan = 1;
1091  else
1092  result = fra.f * frc.f + frb.f;
1093  if (nan)
1094  cc = 1;
1095  else {
1096  if (result < 0.0)
1097  cc = 8;
1098  else if (result > 0.0)
1099  cc = 4;
1100  else
1101  cc = 2;
1102  }
1103  /* TODO: Signaling vs Quiet NaN */
1105  cpu->cd.ppc.fpscr |= (cc << PPC_FPSCR_FPCC_SHIFT);
1106 
1107  (*(uint64_t *)ic->arg[0]) =
1108  ieee_store_float_value(result, IEEE_FMT_D, nan);
1109 }
1110 
1111 
1112 /*
1113  * fmsub: Floating-point Multiply and Sub
1114  *
1115  * arg[0] = ptr to frt
1116  * arg[1] = ptr to fra
1117  * arg[2] = copy of the instruction word
1118  */
1119 X(fmsub)
1120 {
1121  uint32_t iw = ic->arg[2];
1122  int b = (iw >> 11) & 31, c = (iw >> 6) & 31;
1123  struct ieee_float_value fra;
1124  struct ieee_float_value frb;
1125  struct ieee_float_value frc;
1126  double result = 0.0;
1127  int nan = 0, cc;
1128 
1130 
1131  ieee_interpret_float_value(*(uint64_t *)ic->arg[1], &fra, IEEE_FMT_D);
1134  if (fra.nan || frb.nan || frc.nan)
1135  nan = 1;
1136  else
1137  result = fra.f * frc.f - frb.f;
1138  if (nan)
1139  cc = 1;
1140  else {
1141  if (result < 0.0)
1142  cc = 8;
1143  else if (result > 0.0)
1144  cc = 4;
1145  else
1146  cc = 2;
1147  }
1148  /* TODO: Signaling vs Quiet NaN */
1150  cpu->cd.ppc.fpscr |= (cc << PPC_FPSCR_FPCC_SHIFT);
1151 
1152  (*(uint64_t *)ic->arg[0]) =
1153  ieee_store_float_value(result, IEEE_FMT_D, nan);
1154 }
1155 
1156 
1157 /*
1158  * fadd, fsub, fdiv: Various Floating-point operationgs
1159  *
1160  * arg[0] = ptr to fra
1161  * arg[1] = ptr to frb
1162  * arg[2] = ptr to frt
1163  */
1164 X(fadd)
1165 {
1166  struct ieee_float_value fra;
1167  struct ieee_float_value frb;
1168  double result = 0.0;
1169  int nan = 0, c;
1170 
1172 
1173  ieee_interpret_float_value(*(uint64_t *)ic->arg[0], &fra, IEEE_FMT_D);
1174  ieee_interpret_float_value(*(uint64_t *)ic->arg[1], &frb, IEEE_FMT_D);
1175  if (fra.nan || frb.nan)
1176  nan = 1;
1177  else
1178  result = fra.f + frb.f;
1179  if (nan)
1180  c = 1;
1181  else {
1182  if (result < 0.0)
1183  c = 8;
1184  else if (result > 0.0)
1185  c = 4;
1186  else
1187  c = 2;
1188  }
1189  /* TODO: Signaling vs Quiet NaN */
1191  cpu->cd.ppc.fpscr |= (c << PPC_FPSCR_FPCC_SHIFT);
1192 
1193  (*(uint64_t *)ic->arg[2]) =
1194  ieee_store_float_value(result, IEEE_FMT_D, nan);
1195 }
1196 X(fadds)
1197 {
1198  /* TODO */
1199  instr(fadd)(cpu, ic);
1200 }
1201 X(fsub)
1202 {
1203  struct ieee_float_value fra;
1204  struct ieee_float_value frb;
1205  double result = 0.0;
1206  int nan = 0, c;
1207 
1209 
1210  ieee_interpret_float_value(*(uint64_t *)ic->arg[0], &fra, IEEE_FMT_D);
1211  ieee_interpret_float_value(*(uint64_t *)ic->arg[1], &frb, IEEE_FMT_D);
1212  if (fra.nan || frb.nan)
1213  nan = 1;
1214  else
1215  result = fra.f - frb.f;
1216  if (nan)
1217  c = 1;
1218  else {
1219  if (result < 0.0)
1220  c = 8;
1221  else if (result > 0.0)
1222  c = 4;
1223  else
1224  c = 2;
1225  }
1226  /* TODO: Signaling vs Quiet NaN */
1228  cpu->cd.ppc.fpscr |= (c << PPC_FPSCR_FPCC_SHIFT);
1229 
1230  (*(uint64_t *)ic->arg[2]) =
1231  ieee_store_float_value(result, IEEE_FMT_D, nan);
1232 }
1233 X(fsubs)
1234 {
1235  /* TODO */
1236  instr(fsub)(cpu, ic);
1237 }
1238 X(fdiv)
1239 {
1240  struct ieee_float_value fra;
1241  struct ieee_float_value frb;
1242  double result = 0.0;
1243  int nan = 0, c;
1244 
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 || frb.f == 0)
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 */
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(fdivs)
1271 {
1272  /* TODO */
1273  instr(fdiv)(cpu, ic);
1274 }
1275 
1276 
1277 /*
1278  * llsc: Load-linked and store conditional
1279  *
1280  * arg[0] = copy of the instruction word.
1281  */
1282 X(llsc)
1283 {
1284  int iw = ic->arg[0], len = 4, load = 0, xo = (iw >> 1) & 1023;
1285  int i, rc = iw & 1, rt, ra, rb;
1286  uint64_t addr = 0, value;
1287  unsigned char d[8];
1288 
1289  switch (xo) {
1290  case PPC_31_LDARX:
1291  len = 8;
1292  case PPC_31_LWARX:
1293  load = 1;
1294  break;
1295  case PPC_31_STDCX_DOT:
1296  len = 8;
1297  case PPC_31_STWCX_DOT:
1298  break;
1299  }
1300 
1301  rt = (iw >> 21) & 31;
1302  ra = (iw >> 16) & 31;
1303  rb = (iw >> 11) & 31;
1304 
1305  if (ra != 0)
1306  addr = cpu->cd.ppc.gpr[ra];
1307  addr += cpu->cd.ppc.gpr[rb];
1308 
1309  if (load) {
1310  if (rc) {
1311  fatal("ll: rc-bit set?\n");
1312  exit(1);
1313  }
1314  if (cpu->memory_rw(cpu, cpu->mem, addr, d, len,
1316  fatal("ll: error: TODO\n");
1317  exit(1);
1318  }
1319 
1320  value = 0;
1321  for (i=0; i<len; i++) {
1322  value <<= 8;
1323  if (cpu->byte_order == EMUL_BIG_ENDIAN)
1324  value |= d[i];
1325  else
1326  value |= d[len - 1 - i];
1327  }
1328 
1329  cpu->cd.ppc.gpr[rt] = value;
1330  cpu->cd.ppc.ll_addr = addr;
1331  cpu->cd.ppc.ll_bit = 1;
1332  } else {
1333  uint32_t old_so = cpu->cd.ppc.spr[SPR_XER] & PPC_XER_SO;
1334  if (!rc) {
1335  fatal("sc: rc-bit not set?\n");
1336  exit(1);
1337  }
1338 
1339  value = cpu->cd.ppc.gpr[rt];
1340 
1341  /* "If the store is performed, bits 0-2 of Condition
1342  Register Field 0 are set to 0b001, otherwise, they are
1343  set to 0b000. The SO bit of the XER is copied to to bit
1344  4 of Condition Register Field 0. */
1345  if (!cpu->cd.ppc.ll_bit || cpu->cd.ppc.ll_addr != addr) {
1346  cpu->cd.ppc.cr &= 0x0fffffff;
1347  if (old_so)
1348  cpu->cd.ppc.cr |= 0x10000000;
1349  cpu->cd.ppc.ll_bit = 0;
1350  return;
1351  }
1352 
1353  for (i=0; i<len; i++) {
1354  if (cpu->byte_order == EMUL_BIG_ENDIAN)
1355  d[len - 1 - i] = value >> (8*i);
1356  else
1357  d[i] = value >> (8*i);
1358  }
1359 
1360  if (cpu->memory_rw(cpu, cpu->mem, addr, d, len,
1362  fatal("sc: error: TODO\n");
1363  exit(1);
1364  }
1365 
1366  cpu->cd.ppc.cr &= 0x0fffffff;
1367  cpu->cd.ppc.cr |= 0x20000000; /* success! */
1368  if (old_so)
1369  cpu->cd.ppc.cr |= 0x10000000;
1370 
1371  /* Clear _all_ CPUs' ll_bits: */
1372  for (i=0; i<cpu->machine->ncpus; i++)
1373  cpu->machine->cpus[i]->cd.ppc.ll_bit = 0;
1374  }
1375 }
1376 
1377 
1378 /*
1379  * mtsr, mtsrin: Move To Segment Register [Indirect]
1380  *
1381  * arg[0] = sr number, or for indirect mode: ptr to rb
1382  * arg[1] = ptr to rt
1383  *
1384  * TODO: These only work for 32-bit mode!
1385  */
1386 X(mtsr)
1387 {
1388  int sr_num = ic->arg[0];
1389  uint32_t old = cpu->cd.ppc.sr[sr_num];
1390  cpu->cd.ppc.sr[sr_num] = reg(ic->arg[1]);
1391 
1392  if (cpu->cd.ppc.sr[sr_num] != old)
1393  cpu->invalidate_translation_caches(cpu, ic->arg[0] << 28,
1395 }
1396 X(mtsrin)
1397 {
1398  int sr_num = reg(ic->arg[0]) >> 28;
1399  uint32_t old = cpu->cd.ppc.sr[sr_num];
1400  cpu->cd.ppc.sr[sr_num] = reg(ic->arg[1]);
1401 
1402  if (cpu->cd.ppc.sr[sr_num] != old)
1403  cpu->invalidate_translation_caches(cpu, sr_num << 28,
1405 }
1406 
1407 
1408 /*
1409  * mfsrin, mtsrin: Move From/To Segment Register Indirect
1410  *
1411  * arg[0] = sr number, or for indirect mode: ptr to rb
1412  * arg[1] = ptr to rt
1413  */
1414 X(mfsr)
1415 {
1416  /* TODO: This only works for 32-bit mode */
1417  reg(ic->arg[1]) = cpu->cd.ppc.sr[ic->arg[0]];
1418 }
1419 X(mfsrin)
1420 {
1421  /* TODO: This only works for 32-bit mode */
1422  uint32_t sr_num = reg(ic->arg[0]) >> 28;
1423  reg(ic->arg[1]) = cpu->cd.ppc.sr[sr_num];
1424 }
1425 
1426 
1427 /*
1428  * rldicl:
1429  *
1430  * arg[0] = copy of the instruction word
1431  */
1432 X(rldicl)
1433 {
1434  int rs = (ic->arg[0] >> 21) & 31;
1435  int ra = (ic->arg[0] >> 16) & 31;
1436  int sh = ((ic->arg[0] >> 11) & 31) | ((ic->arg[0] & 2) << 4);
1437  int mb = ((ic->arg[0] >> 6) & 31) | (ic->arg[0] & 0x20);
1438  int rc = ic->arg[0] & 1;
1439  uint64_t tmp = cpu->cd.ppc.gpr[rs], tmp2;
1440  /* TODO: Fix this, its performance is awful: */
1441  while (sh-- != 0) {
1442  int b = (tmp >> 63) & 1;
1443  tmp = (tmp << 1) | b;
1444  }
1445  tmp2 = 0;
1446  while (mb <= 63) {
1447  tmp |= ((uint64_t)1 << (63-mb));
1448  mb ++;
1449  }
1450  cpu->cd.ppc.gpr[ra] = tmp & tmp2;
1451  if (rc)
1452  update_cr0(cpu, cpu->cd.ppc.gpr[ra]);
1453 }
1454 
1455 
1456 /*
1457  * rldicr:
1458  *
1459  * arg[0] = copy of the instruction word
1460  */
1461 X(rldicr)
1462 {
1463  int rs = (ic->arg[0] >> 21) & 31;
1464  int ra = (ic->arg[0] >> 16) & 31;
1465  int sh = ((ic->arg[0] >> 11) & 31) | ((ic->arg[0] & 2) << 4);
1466  int me = ((ic->arg[0] >> 6) & 31) | (ic->arg[0] & 0x20);
1467  int rc = ic->arg[0] & 1;
1468  uint64_t tmp = cpu->cd.ppc.gpr[rs];
1469  /* TODO: Fix this, its performance is awful: */
1470  while (sh-- != 0) {
1471  int b = (tmp >> 63) & 1;
1472  tmp = (tmp << 1) | b;
1473  }
1474  while (me++ < 63)
1475  tmp &= ~((uint64_t)1 << (63-me));
1476  cpu->cd.ppc.gpr[ra] = tmp;
1477  if (rc)
1478  update_cr0(cpu, tmp);
1479 }
1480 
1481 
1482 /*
1483  * rldimi:
1484  *
1485  * arg[0] = copy of the instruction word
1486  */
1487 X(rldimi)
1488 {
1489  uint32_t iw = ic->arg[0];
1490  int rs = (iw >> 21) & 31, ra = (iw >> 16) & 31;
1491  int sh = ((iw >> 11) & 31) | ((iw & 2) << 4);
1492  int mb = ((iw >> 6) & 31) | (iw & 0x20);
1493  int rc = ic->arg[0] & 1;
1494  int m;
1495  uint64_t tmp, s = cpu->cd.ppc.gpr[rs];
1496  /* TODO: Fix this, its performance is awful: */
1497  while (sh-- != 0) {
1498  int b = (s >> 63) & 1;
1499  s = (s << 1) | b;
1500  }
1501  m = mb; tmp = 0;
1502  do {
1503  tmp |= ((uint64_t)1 << (63-m));
1504  m ++;
1505  } while (m != 63 - sh);
1506  cpu->cd.ppc.gpr[ra] &= ~tmp;
1507  cpu->cd.ppc.gpr[ra] |= (tmp & s);
1508  if (rc)
1509  update_cr0(cpu, cpu->cd.ppc.gpr[ra]);
1510 }
1511 
1512 
1513 /*
1514  * rlwnm:
1515  *
1516  * arg[0] = ptr to ra
1517  * arg[1] = mask
1518  * arg[2] = copy of the instruction word
1519  */
1520 X(rlwnm)
1521 {
1522  uint32_t tmp, iword = ic->arg[2];
1523  int rs = (iword >> 21) & 31;
1524  int rb = (iword >> 11) & 31;
1525  int sh = cpu->cd.ppc.gpr[rb] & 0x1f;
1526  tmp = (uint32_t)cpu->cd.ppc.gpr[rs];
1527  tmp = (tmp << sh) | (tmp >> (32-sh));
1528  tmp &= (uint32_t)ic->arg[1];
1529  reg(ic->arg[0]) = tmp;
1530 }
1531 DOT0(rlwnm)
1532 
1533 
1534 /*
1535  * rlwinm:
1536  *
1537  * arg[0] = ptr to ra
1538  * arg[1] = mask
1539  * arg[2] = copy of the instruction word
1540  */
1541 X(rlwinm)
1542 {
1543  uint32_t tmp, iword = ic->arg[2];
1544  int rs = (iword >> 21) & 31;
1545  int sh = (iword >> 11) & 31;
1546  tmp = (uint32_t)cpu->cd.ppc.gpr[rs];
1547  tmp = (tmp << sh) | (tmp >> (32-sh));
1548  tmp &= (uint32_t)ic->arg[1];
1549  reg(ic->arg[0]) = tmp;
1550 }
1551 DOT0(rlwinm)
1552 
1553 
1554 /*
1555  * rlwimi:
1556  *
1557  * arg[0] = ptr to rs
1558  * arg[1] = ptr to ra
1559  * arg[2] = copy of the instruction word
1560  */
1561 X(rlwimi)
1562 {
1563  MODE_uint_t tmp = reg(ic->arg[0]), ra = reg(ic->arg[1]);
1564  uint32_t iword = ic->arg[2];
1565  int sh = (iword >> 11) & 31;
1566  int mb = (iword >> 6) & 31;
1567  int me = (iword >> 1) & 31;
1568  int rc = iword & 1;
1569 
1570  tmp = (tmp << sh) | (tmp >> (32-sh));
1571 
1572  for (;;) {
1573  uint64_t mask;
1574  mask = (uint64_t)1 << (31-mb);
1575  ra &= ~mask;
1576  ra |= (tmp & mask);
1577  if (mb == me)
1578  break;
1579  mb ++;
1580  if (mb == 32)
1581  mb = 0;
1582  }
1583  reg(ic->arg[1]) = ra;
1584  if (rc)
1585  update_cr0(cpu, ra);
1586 }
1587 
1588 
1589 /*
1590  * srawi:
1591  *
1592  * arg[0] = ptr to rs
1593  * arg[1] = ptr to ra
1594  * arg[2] = sh (shift amount)
1595  */
1596 X(srawi)
1597 {
1598  uint32_t tmp = reg(ic->arg[0]);
1599  int i = 0, j = 0, sh = ic->arg[2];
1600 
1601  cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
1602  if (tmp & 0x80000000)
1603  i = 1;
1604  while (sh-- > 0) {
1605  if (tmp & 1)
1606  j ++;
1607  tmp >>= 1;
1608  if (tmp & 0x40000000)
1609  tmp |= 0x80000000;
1610  }
1611  if (i && j>0)
1612  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
1613  reg(ic->arg[1]) = (int64_t)(int32_t)tmp;
1614 }
1615 DOT1(srawi)
1616 
1617 
1618 /*
1619  * mcrf: Move inside condition register
1620  *
1621  * arg[0] = 28-4*bf, arg[1] = 28-4*bfa
1622  */
1623 X(mcrf)
1624 {
1625  int bf_shift = ic->arg[0], bfa_shift = ic->arg[1];
1626  uint32_t tmp = (cpu->cd.ppc.cr >> bfa_shift) & 0xf;
1627  cpu->cd.ppc.cr &= ~(0xf << bf_shift);
1628  cpu->cd.ppc.cr |= (tmp << bf_shift);
1629 }
1630 
1631 
1632 /*
1633  * crand, crxor etc: Condition Register operations
1634  *
1635  * arg[0] = copy of the instruction word
1636  */
1637 X(crand) {
1638  uint32_t iword = ic->arg[0]; int bt = (iword >> 21) & 31;
1639  int ba = (iword >> 16) & 31, bb = (iword >> 11) & 31;
1640  ba = (cpu->cd.ppc.cr >> (31-ba)) & 1;
1641  bb = (cpu->cd.ppc.cr >> (31-bb)) & 1;
1642  cpu->cd.ppc.cr &= ~(1 << (31-bt));
1643  if (ba & bb)
1644  cpu->cd.ppc.cr |= (1 << (31-bt));
1645 }
1646 X(crandc) {
1647  uint32_t iword = ic->arg[0]; int bt = (iword >> 21) & 31;
1648  int ba = (iword >> 16) & 31, bb = (iword >> 11) & 31;
1649  ba = (cpu->cd.ppc.cr >> (31-ba)) & 1;
1650  bb = (cpu->cd.ppc.cr >> (31-bb)) & 1;
1651  cpu->cd.ppc.cr &= ~(1 << (31-bt));
1652  if (!(ba & bb))
1653  cpu->cd.ppc.cr |= (1 << (31-bt));
1654 }
1655 X(creqv) {
1656  uint32_t iword = ic->arg[0]; int bt = (iword >> 21) & 31;
1657  int ba = (iword >> 16) & 31, bb = (iword >> 11) & 31;
1658  ba = (cpu->cd.ppc.cr >> (31-ba)) & 1;
1659  bb = (cpu->cd.ppc.cr >> (31-bb)) & 1;
1660  cpu->cd.ppc.cr &= ~(1 << (31-bt));
1661  if (!(ba ^ bb))
1662  cpu->cd.ppc.cr |= (1 << (31-bt));
1663 }
1664 X(cror) {
1665  uint32_t iword = ic->arg[0]; int bt = (iword >> 21) & 31;
1666  int ba = (iword >> 16) & 31, bb = (iword >> 11) & 31;
1667  ba = (cpu->cd.ppc.cr >> (31-ba)) & 1;
1668  bb = (cpu->cd.ppc.cr >> (31-bb)) & 1;
1669  cpu->cd.ppc.cr &= ~(1 << (31-bt));
1670  if (ba | bb)
1671  cpu->cd.ppc.cr |= (1 << (31-bt));
1672 }
1673 X(crorc) {
1674  uint32_t iword = ic->arg[0]; int bt = (iword >> 21) & 31;
1675  int ba = (iword >> 16) & 31, bb = (iword >> 11) & 31;
1676  ba = (cpu->cd.ppc.cr >> (31-ba)) & 1;
1677  bb = (cpu->cd.ppc.cr >> (31-bb)) & 1;
1678  cpu->cd.ppc.cr &= ~(1 << (31-bt));
1679  if (!(ba | bb))
1680  cpu->cd.ppc.cr |= (1 << (31-bt));
1681 }
1682 X(crnor) {
1683  uint32_t iword = ic->arg[0]; int bt = (iword >> 21) & 31;
1684  int ba = (iword >> 16) & 31, bb = (iword >> 11) & 31;
1685  ba = (cpu->cd.ppc.cr >> (31-ba)) & 1;
1686  bb = (cpu->cd.ppc.cr >> (31-bb)) & 1;
1687  cpu->cd.ppc.cr &= ~(1 << (31-bt));
1688  if (!(ba | bb))
1689  cpu->cd.ppc.cr |= (1 << (31-bt));
1690 }
1691 X(crxor) {
1692  uint32_t iword = ic->arg[0]; int bt = (iword >> 21) & 31;
1693  int ba = (iword >> 16) & 31, bb = (iword >> 11) & 31;
1694  ba = (cpu->cd.ppc.cr >> (31-ba)) & 1;
1695  bb = (cpu->cd.ppc.cr >> (31-bb)) & 1;
1696  cpu->cd.ppc.cr &= ~(1 << (31-bt));
1697  if (ba ^ bb)
1698  cpu->cd.ppc.cr |= (1 << (31-bt));
1699 }
1700 
1701 
1702 /*
1703  * mfspr: Move from SPR
1704  *
1705  * arg[0] = pointer to destination register
1706  * arg[1] = pointer to source SPR
1707  */
1708 X(mfspr) {
1709  /* TODO: Check permission */
1710  reg(ic->arg[0]) = reg(ic->arg[1]);
1711 }
1712 X(mfspr_pmc1) {
1713  /*
1714  * TODO: This is a temporary hack to make NetBSD/ppc detect
1715  * a CPU of the correct (emulated) speed.
1716  */
1717  reg(ic->arg[0]) = cpu->machine->emulated_hz / 10;
1718 }
1719 X(mftb) {
1720  /* NOTE/TODO: This increments the time base (slowly) if it
1721  is being polled. */
1722  if (++cpu->cd.ppc.spr[SPR_TBL] == 0)
1723  cpu->cd.ppc.spr[SPR_TBU] ++;
1724  reg(ic->arg[0]) = cpu->cd.ppc.spr[SPR_TBL];
1725 }
1726 X(mftbu) {
1727  reg(ic->arg[0]) = cpu->cd.ppc.spr[SPR_TBU];
1728 }
1729 
1730 
1731 /*
1732  * mtspr: Move to SPR.
1733  *
1734  * arg[0] = pointer to source register
1735  * arg[1] = pointer to the SPR
1736  */
1737 X(mtspr) {
1738  /* TODO: Check permission */
1739  reg(ic->arg[1]) = reg(ic->arg[0]);
1740 }
1741 X(mtspr_sprg2) {
1742  if (cpu->cd.ppc.bits == 32) {
1743  // Ignore for now. FreeBSD/powerpc seems to write 0xffffffe0
1744  // here, and read it back. If it is non-zero, it assumes a 64-bit
1745  // cpu.
1746  } else {
1747  reg(ic->arg[1]) = reg(ic->arg[0]);
1748  }
1749 }
1750 X(mtlr) {
1751  cpu->cd.ppc.spr[SPR_LR] = reg(ic->arg[0]);
1752 }
1753 X(mtctr) {
1754  cpu->cd.ppc.spr[SPR_CTR] = reg(ic->arg[0]);
1755 }
1756 
1757 
1758 /*
1759  * rfi[d]: Return from Interrupt
1760  */
1761 X(rfi)
1762 {
1763  uint64_t tmp;
1764 
1765  reg_access_msr(cpu, &tmp, 0, 0);
1766  tmp &= ~0xffff;
1767  tmp |= (cpu->cd.ppc.spr[SPR_SRR1] & 0xffff);
1768  reg_access_msr(cpu, &tmp, 1, 0);
1769 
1770  cpu->pc = cpu->cd.ppc.spr[SPR_SRR0];
1772 }
1773 X(rfid)
1774 {
1775  uint64_t tmp, mask = 0x800000000000ff73ULL;
1776 
1777  reg_access_msr(cpu, &tmp, 0, 0);
1778  tmp &= ~mask;
1779  tmp |= (cpu->cd.ppc.spr[SPR_SRR1] & mask);
1780  reg_access_msr(cpu, &tmp, 1, 0);
1781 
1782  cpu->pc = cpu->cd.ppc.spr[SPR_SRR0];
1783  if (!(tmp & PPC_MSR_SF))
1784  cpu->pc = (uint32_t)cpu->pc;
1786 }
1787 
1788 
1789 /*
1790  * mfcr: Move From Condition Register
1791  *
1792  * arg[0] = pointer to destination register
1793  */
1794 X(mfcr)
1795 {
1796  reg(ic->arg[0]) = cpu->cd.ppc.cr;
1797 }
1798 
1799 
1800 /*
1801  * mfmsr: Move From MSR
1802  *
1803  * arg[0] = pointer to destination register
1804  */
1805 X(mfmsr)
1806 {
1807  reg_access_msr(cpu, (uint64_t*)ic->arg[0], 0, 0);
1808 }
1809 
1810 
1811 /*
1812  * mtmsr: Move To MSR
1813  *
1814  * arg[0] = pointer to source register
1815  * arg[1] = page offset of the next instruction
1816  * arg[2] = 0 for 32-bit (mtmsr), 1 for 64-bit (mtmsrd)
1817  */
1818 X(mtmsr)
1819 {
1820  MODE_uint_t old_pc;
1821  uint64_t x = reg(ic->arg[0]);
1822 
1823  /* TODO: check permission! */
1824 
1825  /* Synchronize the PC (pointing to _after_ this instruction) */
1826  cpu->pc = (cpu->pc & ~0xfff) + ic->arg[1];
1827  old_pc = cpu->pc;
1828 
1829  if (!ic->arg[2]) {
1830  uint64_t y;
1831  reg_access_msr(cpu, &y, 0, 0);
1832  x = (y & 0xffffffff00000000ULL) | (x & 0xffffffffULL);
1833  }
1834 
1835  reg_access_msr(cpu, &x, 1, 1);
1836 
1837  /*
1838  * Super-ugly hack: If the pc wasn't changed (i.e. if there was no
1839  * exception while accessing the msr), then we _decrease_ the PC by 4
1840  * again. This is because the next ic could be an end_of_page.
1841  */
1842  if ((MODE_uint_t)cpu->pc == old_pc)
1843  cpu->pc -= 4;
1844 }
1845 
1846 
1847 /*
1848  * wrteei: Write EE immediate (on PPC405GP)
1849  *
1850  * arg[0] = either 0 or 0x8000
1851  */
1852 X(wrteei)
1853 {
1854  /* TODO: check permission! */
1855  uint64_t x;
1856 
1857  /* Synchronize the PC (pointing to _after_ this instruction) */
1858  cpu->pc = (cpu->pc & ~0xfff) + ic->arg[1];
1859 
1860  reg_access_msr(cpu, &x, 0, 0);
1861  x = (x & ~0x8000) | ic->arg[0];
1862  reg_access_msr(cpu, &x, 1, 1);
1863 }
1864 
1865 
1866 /*
1867  * mtcrf: Move To Condition Register Fields
1868  *
1869  * arg[0] = pointer to source register
1870  */
1871 X(mtcrf)
1872 {
1873  cpu->cd.ppc.cr &= ~ic->arg[1];
1874  cpu->cd.ppc.cr |= (reg(ic->arg[0]) & ic->arg[1]);
1875 }
1876 
1877 
1878 /*
1879  * mulli: Multiply Low Immediate.
1880  *
1881  * arg[0] = pointer to source register ra
1882  * arg[1] = int32_t immediate
1883  * arg[2] = pointer to destination register rt
1884  */
1885 X(mulli)
1886 {
1887  reg(ic->arg[2]) = (uint32_t)(reg(ic->arg[0]) * (int32_t)ic->arg[1]);
1888 }
1889 
1890 
1891 /*
1892  * Load/Store Multiple:
1893  *
1894  * arg[0] = rs (or rt for loads) NOTE: not a pointer
1895  * arg[1] = ptr to ra
1896  * arg[2] = int32_t immediate offset
1897  */
1898 X(lmw) {
1899  MODE_uint_t addr = reg(ic->arg[1]) + (int32_t)ic->arg[2];
1900  unsigned char d[4];
1901  int rs = ic->arg[0];
1902 
1903  int low_pc = ((size_t)ic - (size_t)cpu->cd.ppc.cur_ic_page)
1904  / sizeof(struct ppc_instr_call);
1905  cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1)
1907  cpu->pc |= (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
1908 
1909  while (rs <= 31) {
1910  if (cpu->memory_rw(cpu, cpu->mem, addr, d, sizeof(d),
1912  /* exception */
1913  return;
1914  }
1915 
1916  if (cpu->byte_order == EMUL_BIG_ENDIAN)
1917  cpu->cd.ppc.gpr[rs] = (d[0] << 24) + (d[1] << 16)
1918  + (d[2] << 8) + d[3];
1919  else
1920  cpu->cd.ppc.gpr[rs] = (d[3] << 24) + (d[2] << 16)
1921  + (d[1] << 8) + d[0];
1922 
1923  rs ++;
1924  addr += sizeof(uint32_t);
1925  }
1926 }
1927 X(stmw) {
1928  MODE_uint_t addr = reg(ic->arg[1]) + (int32_t)ic->arg[2];
1929  unsigned char d[4];
1930  int rs = ic->arg[0];
1931 
1932  int low_pc = ((size_t)ic - (size_t)cpu->cd.ppc.cur_ic_page)
1933  / sizeof(struct ppc_instr_call);
1934  cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1)
1936  cpu->pc += (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
1937 
1938  while (rs <= 31) {
1939  uint32_t tmp = cpu->cd.ppc.gpr[rs];
1940  if (cpu->byte_order == EMUL_BIG_ENDIAN) {
1941  d[3] = tmp; d[2] = tmp >> 8;
1942  d[1] = tmp >> 16; d[0] = tmp >> 24;
1943  } else {
1944  d[0] = tmp; d[1] = tmp >> 8;
1945  d[2] = tmp >> 16; d[3] = tmp >> 24;
1946  }
1947  if (cpu->memory_rw(cpu, cpu->mem, addr, d, sizeof(d),
1949  /* exception */
1950  return;
1951  }
1952 
1953  rs ++;
1954  addr += sizeof(uint32_t);
1955  }
1956 }
1957 
1958 
1959 /*
1960  * Load/store string:
1961  *
1962  * arg[0] = rs (well, rt for lswi)
1963  * arg[1] = ptr to ra (or ptr to zero)
1964  * arg[2] = nb
1965  */
1966 X(lswi)
1967 {
1968  MODE_uint_t addr = reg(ic->arg[1]);
1969  int rt = ic->arg[0], nb = ic->arg[2];
1970  int sub = 0;
1971 
1972  int low_pc = ((size_t)ic - (size_t)cpu->cd.ppc.cur_ic_page)
1973  / sizeof(struct ppc_instr_call);
1974  cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1)
1976  cpu->pc += (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
1977 
1978  while (nb > 0) {
1979  unsigned char d;
1980  if (cpu->memory_rw(cpu, cpu->mem, addr, &d, 1,
1982  /* exception */
1983  return;
1984  }
1985 
1986  if (cpu->cd.ppc.mode == MODE_POWER && sub == 0)
1987  cpu->cd.ppc.gpr[rt] = 0;
1988  cpu->cd.ppc.gpr[rt] &= ~(0xff << (24-8*sub));
1989  cpu->cd.ppc.gpr[rt] |= (d << (24-8*sub));
1990  sub ++;
1991  if (sub == 4) {
1992  rt = (rt + 1) & 31;
1993  sub = 0;
1994  }
1995  addr ++;
1996  nb --;
1997  }
1998 }
1999 X(stswi)
2000 {
2001  MODE_uint_t addr = reg(ic->arg[1]);
2002  int rs = ic->arg[0], nb = ic->arg[2];
2003  uint32_t cur = cpu->cd.ppc.gpr[rs];
2004  int sub = 0;
2005 
2006  int low_pc = ((size_t)ic - (size_t)cpu->cd.ppc.cur_ic_page)
2007  / sizeof(struct ppc_instr_call);
2008  cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1)
2010  cpu->pc += (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
2011 
2012  while (nb > 0) {
2013  unsigned char d = cur >> 24;
2014  if (cpu->memory_rw(cpu, cpu->mem, addr, &d, 1,
2016  /* exception */
2017  return;
2018  }
2019  cur <<= 8;
2020  sub ++;
2021  if (sub == 4) {
2022  rs = (rs + 1) & 31;
2023  sub = 0;
2024  cur = cpu->cd.ppc.gpr[rs];
2025  }
2026  addr ++;
2027  nb --;
2028  }
2029 }
2030 
2031 
2032 /*
2033  * Shifts, and, or, xor, etc.
2034  *
2035  * arg[0] = pointer to source register rs
2036  * arg[1] = pointer to source register rb
2037  * arg[2] = pointer to destination register ra
2038  */
2039 X(extsb) {
2040 #ifdef MODE32
2041  reg(ic->arg[2]) = (int32_t)(int8_t)reg(ic->arg[0]);
2042 #else
2043  reg(ic->arg[2]) = (int64_t)(int8_t)reg(ic->arg[0]);
2044 #endif
2045 }
2046 DOT2(extsb)
2047 X(extsh) {
2048 #ifdef MODE32
2049  reg(ic->arg[2]) = (int32_t)(int16_t)reg(ic->arg[0]);
2050 #else
2051  reg(ic->arg[2]) = (int64_t)(int16_t)reg(ic->arg[0]);
2052 #endif
2053 }
2054 DOT2(extsh)
2055 X(extsw) {
2056 #ifdef MODE32
2057  fatal("TODO: extsw: invalid instruction\n");
2058 #else
2059  reg(ic->arg[2]) = (int64_t)(int32_t)reg(ic->arg[0]);
2060 #endif
2061 }
2062 DOT2(extsw)
2063 X(slw) { reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0])
2064  << (reg(ic->arg[1]) & 31); }
2065 DOT2(slw)
2066 X(sld) {int sa = reg(ic->arg[1]) & 127;
2067  if (sa >= 64) reg(ic->arg[2]) = 0;
2068  else reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0]) << (sa & 63); }
2069 DOT2(sld)
2070 X(sraw)
2071 {
2072  uint32_t tmp = reg(ic->arg[0]);
2073  int i = 0, j = 0, sh = reg(ic->arg[1]) & 31;
2074 
2075  cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2076  if (tmp & 0x80000000)
2077  i = 1;
2078  while (sh-- > 0) {
2079  if (tmp & 1)
2080  j ++;
2081  tmp >>= 1;
2082  if (tmp & 0x40000000)
2083  tmp |= 0x80000000;
2084  }
2085  if (i && j>0)
2086  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2087  reg(ic->arg[2]) = (int64_t)(int32_t)tmp;
2088 }
2089 DOT2(sraw)
2090 X(srw) { reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0])
2091  >> (reg(ic->arg[1]) & 31); }
2092 DOT2(srw)
2093 X(and) { reg(ic->arg[2]) = reg(ic->arg[0]) & reg(ic->arg[1]); }
2094 DOT2(and)
2095 X(nand) { reg(ic->arg[2]) = ~(reg(ic->arg[0]) & reg(ic->arg[1])); }
2096 DOT2(nand)
2097 X(andc) { reg(ic->arg[2]) = reg(ic->arg[0]) & (~reg(ic->arg[1])); }
2098 DOT2(andc)
2099 X(nor) { reg(ic->arg[2]) = ~(reg(ic->arg[0]) | reg(ic->arg[1])); }
2100 DOT2(nor)
2101 X(mr) { reg(ic->arg[2]) = reg(ic->arg[1]); }
2102 X(or) { reg(ic->arg[2]) = reg(ic->arg[0]) | reg(ic->arg[1]); }
2103 DOT2(or)
2104 X(orc) { reg(ic->arg[2]) = reg(ic->arg[0]) | (~reg(ic->arg[1])); }
2105 DOT2(orc)
2106 X(xor) { reg(ic->arg[2]) = reg(ic->arg[0]) ^ reg(ic->arg[1]); }
2107 DOT2(xor)
2108 X(eqv) { reg(ic->arg[2]) = ~(reg(ic->arg[0]) ^ reg(ic->arg[1])); }
2109 DOT2(eqv)
2110 
2111 
2112 /*
2113  * neg:
2114  *
2115  * arg[0] = pointer to source register ra
2116  * arg[1] = pointer to destination register rt
2117  */
2118 X(neg) { reg(ic->arg[1]) = -reg(ic->arg[0]); }
2119 DOT1(neg)
2120 
2121 
2122 /*
2123  * mullw, mulhw[u], divw[u]:
2124  *
2125  * arg[0] = pointer to source register ra
2126  * arg[1] = pointer to source register rb
2127  * arg[2] = pointer to destination register rt
2128  */
2129 X(mullw)
2130 {
2131  int32_t sum = (int32_t)reg(ic->arg[0]) * (int32_t)reg(ic->arg[1]);
2132  reg(ic->arg[2]) = (int32_t)sum;
2133 }
2134 DOT2(mullw)
2135 X(mulhw)
2136 {
2137  int64_t sum;
2138  sum = (int64_t)(int32_t)reg(ic->arg[0])
2139  * (int64_t)(int32_t)reg(ic->arg[1]);
2140  reg(ic->arg[2]) = sum >> 32;
2141 }
2142 DOT2(mulhw)
2143 X(mulhwu)
2144 {
2145  uint64_t sum;
2146  sum = (uint64_t)(uint32_t)reg(ic->arg[0])
2147  * (uint64_t)(uint32_t)reg(ic->arg[1]);
2148  reg(ic->arg[2]) = sum >> 32;
2149 }
2150 DOT2(mulhwu)
2151 X(divw)
2152 {
2153  int32_t a = reg(ic->arg[0]), b = reg(ic->arg[1]);
2154  int32_t sum;
2155  if (b == 0)
2156  sum = 0;
2157  else
2158  sum = a / b;
2159  reg(ic->arg[2]) = (uint32_t)sum;
2160 }
2161 DOT2(divw)
2162 X(divwu)
2163 {
2164  uint32_t a = reg(ic->arg[0]), b = reg(ic->arg[1]);
2165  uint32_t sum;
2166  if (b == 0)
2167  sum = 0;
2168  else
2169  sum = a / b;
2170  reg(ic->arg[2]) = sum;
2171 }
2172 DOT2(divwu)
2173 
2174 
2175 /*
2176  * add: Add.
2177  *
2178  * arg[0] = pointer to source register ra
2179  * arg[1] = pointer to source register rb
2180  * arg[2] = pointer to destination register rt
2181  */
2182 X(add) { reg(ic->arg[2]) = reg(ic->arg[0]) + reg(ic->arg[1]); }
2183 DOT2(add)
2184 
2185 
2186 /*
2187  * addc: Add carrying.
2188  *
2189  * arg[0] = pointer to source register ra
2190  * arg[1] = pointer to source register rb
2191  * arg[2] = pointer to destination register rt
2192  */
2193 X(addc)
2194 {
2195  /* TODO: this only works in 32-bit mode */
2196  uint64_t tmp = (uint32_t)reg(ic->arg[0]);
2197  uint64_t tmp2 = tmp;
2198  cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2199  tmp += (uint32_t)reg(ic->arg[1]);
2200  if ((tmp >> 32) != (tmp2 >> 32))
2201  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2202  reg(ic->arg[2]) = (uint32_t)tmp;
2203 }
2204 
2205 
2206 /*
2207  * adde: Add extended, etc.
2208  *
2209  * arg[0] = pointer to source register ra
2210  * arg[1] = pointer to source register rb
2211  * arg[2] = pointer to destination register rt
2212  */
2213 X(adde)
2214 {
2215  /* TODO: this only works in 32-bit mode */
2216  int old_ca = cpu->cd.ppc.spr[SPR_XER] & PPC_XER_CA;
2217  uint64_t tmp = (uint32_t)reg(ic->arg[0]);
2218  uint64_t tmp2 = tmp;
2219  cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2220  tmp += (uint32_t)reg(ic->arg[1]);
2221  if (old_ca)
2222  tmp ++;
2223  if ((tmp >> 32) != (tmp2 >> 32))
2224  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2225  reg(ic->arg[2]) = (uint32_t)tmp;
2226 }
2227 DOT2(adde)
2228 X(addme)
2229 {
2230  /* TODO: this only works in 32-bit mode */
2231  int old_ca = cpu->cd.ppc.spr[SPR_XER] & PPC_XER_CA;
2232  uint64_t tmp = (uint32_t)reg(ic->arg[0]);
2233  uint64_t tmp2 = tmp;
2234  cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2235  if (old_ca)
2236  tmp ++;
2237  tmp += 0xffffffffULL;
2238  if ((tmp >> 32) != (tmp2 >> 32))
2239  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2240  reg(ic->arg[2]) = (uint32_t)tmp;
2241 }
2242 DOT2(addme)
2243 X(addze)
2244 {
2245  /* TODO: this only works in 32-bit mode */
2246  int old_ca = cpu->cd.ppc.spr[SPR_XER] & PPC_XER_CA;
2247  uint64_t tmp = (uint32_t)reg(ic->arg[0]);
2248  uint64_t tmp2 = tmp;
2249  cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2250  if (old_ca)
2251  tmp ++;
2252  if ((tmp >> 32) != (tmp2 >> 32))
2253  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2254  reg(ic->arg[2]) = (uint32_t)tmp;
2255 }
2256 DOT2(addze)
2257 
2258 
2259 /*
2260  * subf: Subf, etc.
2261  *
2262  * arg[0] = pointer to source register ra
2263  * arg[1] = pointer to source register rb
2264  * arg[2] = pointer to destination register rt
2265  */
2266 X(subf)
2267 {
2268  reg(ic->arg[2]) = reg(ic->arg[1]) - reg(ic->arg[0]);
2269 }
2270 DOT2(subf)
2271 X(subfc)
2272 {
2273  cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2274  if (reg(ic->arg[1]) >= reg(ic->arg[0]))
2275  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2276  reg(ic->arg[2]) = reg(ic->arg[1]) - reg(ic->arg[0]);
2277 }
2278 DOT2(subfc)
2279 X(subfe)
2280 {
2281  int old_ca = (cpu->cd.ppc.spr[SPR_XER] & PPC_XER_CA)? 1 : 0;
2282  cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2283  if (reg(ic->arg[1]) == reg(ic->arg[0])) {
2284  if (old_ca)
2285  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2286  } else if (reg(ic->arg[1]) >= reg(ic->arg[0]))
2287  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2288 
2289  /*
2290  * TODO: The register value calculation should be correct,
2291  * but the CA bit calculation above is probably not.
2292  */
2293 
2294  reg(ic->arg[2]) = reg(ic->arg[1]) - reg(ic->arg[0]) - (old_ca? 0 : 1);
2295 }
2296 DOT2(subfe)
2297 X(subfme)
2298 {
2299  int old_ca = cpu->cd.ppc.spr[SPR_XER] & PPC_XER_CA;
2300  uint64_t tmp = (uint32_t)(~reg(ic->arg[0]));
2301  tmp += 0xffffffffULL;
2302  cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2303  if (old_ca)
2304  tmp ++;
2305  if ((tmp >> 32) != 0)
2306  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2307  reg(ic->arg[2]) = (uint32_t)tmp;
2308 }
2309 DOT2(subfme)
2310 X(subfze)
2311 {
2312  int old_ca = cpu->cd.ppc.spr[SPR_XER] & PPC_XER_CA;
2313  uint64_t tmp = (uint32_t)(~reg(ic->arg[0]));
2314  uint64_t tmp2 = tmp;
2315  cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2316  if (old_ca)
2317  tmp ++;
2318  if ((tmp >> 32) != (tmp2 >> 32))
2319  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2320  reg(ic->arg[2]) = (uint32_t)tmp;
2321 }
2322 DOT2(subfze)
2323 
2324 
2325 /*
2326  * ori, xori etc.:
2327  *
2328  * arg[0] = pointer to source uint64_t
2329  * arg[1] = immediate value (uint32_t or larger)
2330  * arg[2] = pointer to destination uint64_t
2331  */
2332 X(ori) { reg(ic->arg[2]) = reg(ic->arg[0]) | (uint32_t)ic->arg[1]; }
2333 X(xori) { reg(ic->arg[2]) = reg(ic->arg[0]) ^ (uint32_t)ic->arg[1]; }
2334 
2335 
2336 #include "tmp_ppc_loadstore.cc"
2337 
2338 
2339 /*
2340  * lfs, stfs: Load/Store Floating-point Single precision
2341  */
2342 X(lfs)
2343 {
2344  /* Sync. PC in case of an exception, and remember it: */
2345  uint64_t old_pc, low_pc = ((size_t)ic - (size_t)
2346  cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
2347  old_pc = cpu->pc = (cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) <<
2349  if (!(cpu->cd.ppc.msr & PPC_MSR_FP)) {
2351  return;
2352  }
2353 
2354  /* Perform a 32-bit load: */
2355 #ifdef MODE32
2356  ppc32_loadstore
2357 #else
2359 #endif
2360  [2 + 4 + 8](cpu, ic);
2361 
2362  if (old_pc == cpu->pc) {
2363  /* The load succeeded. Let's convert the value: */
2364  struct ieee_float_value val;
2365  (*(uint64_t *)ic->arg[0]) &= 0xffffffff;
2366  ieee_interpret_float_value(*(uint64_t *)ic->arg[0],
2367  &val, IEEE_FMT_S);
2368  (*(uint64_t *)ic->arg[0]) =
2370  }
2371 }
2372 X(lfsx)
2373 {
2374  /* Sync. PC in case of an exception, and remember it: */
2375  uint64_t old_pc, low_pc = ((size_t)ic - (size_t)
2376  cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
2377  old_pc = cpu->pc = (cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) <<
2379  if (!(cpu->cd.ppc.msr & PPC_MSR_FP)) {
2381  return;
2382  }
2383 
2384  /* Perform a 32-bit load: */
2385 #ifdef MODE32
2386  ppc32_loadstore_indexed
2387 #else
2389 #endif
2390  [2 + 4 + 8](cpu, ic);
2391 
2392  if (old_pc == cpu->pc) {
2393  /* The load succeeded. Let's convert the value: */
2394  struct ieee_float_value val;
2395  (*(uint64_t *)ic->arg[0]) &= 0xffffffff;
2396  ieee_interpret_float_value(*(uint64_t *)ic->arg[0],
2397  &val, IEEE_FMT_S);
2398  (*(uint64_t *)ic->arg[0]) =
2400  }
2401 }
2402 X(lfd)
2403 {
2405 
2406  /* Perform a 64-bit load: */
2407 #ifdef MODE32
2408  ppc32_loadstore
2409 #else
2411 #endif
2412  [3 + 4 + 8](cpu, ic);
2413 }
2414 X(lfdx)
2415 {
2417 
2418  /* Perform a 64-bit load: */
2419 #ifdef MODE32
2420  ppc32_loadstore_indexed
2421 #else
2423 #endif
2424  [3 + 4 + 8](cpu, ic);
2425 }
2426 X(stfs)
2427 {
2428  uint64_t *old_arg0 = (uint64_t *) ic->arg[0];
2429  struct ieee_float_value val;
2430  uint64_t tmp_val;
2431 
2433 
2434  ieee_interpret_float_value(*old_arg0, &val, IEEE_FMT_D);
2435  tmp_val = ieee_store_float_value(val.f, IEEE_FMT_S, val.nan);
2436 
2437  ic->arg[0] = (size_t)&tmp_val;
2438 
2439  /* Perform a 32-bit store: */
2440 #ifdef MODE32
2441  ppc32_loadstore
2442 #else
2444 #endif
2445  [2 + 4](cpu, ic);
2446 
2447  ic->arg[0] = (size_t)old_arg0;
2448 }
2449 X(stfsx)
2450 {
2451  uint64_t *old_arg0 = (uint64_t *)ic->arg[0];
2452  struct ieee_float_value val;
2453  uint64_t tmp_val;
2454 
2456 
2457  ieee_interpret_float_value(*old_arg0, &val, IEEE_FMT_D);
2458  tmp_val = ieee_store_float_value(val.f, IEEE_FMT_S, val.nan);
2459 
2460  ic->arg[0] = (size_t)&tmp_val;
2461 
2462  /* Perform a 32-bit store: */
2463 #ifdef MODE32
2464  ppc32_loadstore_indexed
2465 #else
2467 #endif
2468  [2 + 4](cpu, ic);
2469 
2470  ic->arg[0] = (size_t)old_arg0;
2471 }
2472 X(stfd)
2473 {
2475 
2476  /* Perform a 64-bit store: */
2477 #ifdef MODE32
2478  ppc32_loadstore
2479 #else
2481 #endif
2482  [3 + 4](cpu, ic);
2483 }
2484 X(stfdx)
2485 {
2487 
2488  /* Perform a 64-bit store: */
2489 #ifdef MODE32
2490  ppc32_loadstore_indexed
2491 #else
2493 #endif
2494  [3 + 4](cpu, ic);
2495 }
2496 
2497 
2498 /*
2499  * lvx, stvx: Vector (16-byte) load/store (slow implementation)
2500  *
2501  * arg[0] = v-register nr of rs
2502  * arg[1] = pointer to ra
2503  * arg[2] = pointer to rb
2504  */
2505 X(lvx)
2506 {
2507  MODE_uint_t addr = reg(ic->arg[1]) + reg(ic->arg[2]);
2508  uint8_t data[16];
2509  uint64_t hi, lo;
2510  int rs = ic->arg[0];
2511 
2512  if (cpu->memory_rw(cpu, cpu->mem, addr, data, sizeof(data),
2514  /* exception */
2515  return;
2516  }
2517 
2518  hi = ((uint64_t)data[0] << 56) +
2519  ((uint64_t)data[1] << 48) +
2520  ((uint64_t)data[2] << 40) +
2521  ((uint64_t)data[3] << 32) +
2522  ((uint64_t)data[4] << 24) +
2523  ((uint64_t)data[5] << 16) +
2524  ((uint64_t)data[6] << 8) +
2525  ((uint64_t)data[7]);
2526  lo = ((uint64_t)data[8] << 56) +
2527  ((uint64_t)data[9] << 48) +
2528  ((uint64_t)data[10] << 40) +
2529  ((uint64_t)data[11] << 32) +
2530  ((uint64_t)data[12] << 24) +
2531  ((uint64_t)data[13] << 16) +
2532  ((uint64_t)data[14] << 8) +
2533  ((uint64_t)data[15]);
2534 
2535  cpu->cd.ppc.vr_hi[rs] = hi; cpu->cd.ppc.vr_lo[rs] = lo;
2536 }
2537 X(stvx)
2538 {
2539  uint8_t data[16];
2540  MODE_uint_t addr = reg(ic->arg[1]) + reg(ic->arg[2]);
2541  int rs = ic->arg[0];
2542  uint64_t hi = cpu->cd.ppc.vr_hi[rs], lo = cpu->cd.ppc.vr_lo[rs];
2543 
2544  data[0] = hi >> 56;
2545  data[1] = hi >> 48;
2546  data[2] = hi >> 40;
2547  data[3] = hi >> 32;
2548  data[4] = hi >> 24;
2549  data[5] = hi >> 16;
2550  data[6] = hi >> 8;
2551  data[7] = hi;
2552  data[8] = lo >> 56;
2553  data[9] = lo >> 48;
2554  data[10] = lo >> 40;
2555  data[11] = lo >> 32;
2556  data[12] = lo >> 24;
2557  data[13] = lo >> 16;
2558  data[14] = lo >> 8;
2559  data[15] = lo;
2560 
2561  cpu->memory_rw(cpu, cpu->mem, addr, data,
2562  sizeof(data), MEM_WRITE, CACHE_DATA);
2563 }
2564 
2565 
2566 /*
2567  * vxor: Vector (16-byte) XOR
2568  *
2569  * arg[0] = v-register nr of source 1
2570  * arg[1] = v-register nr of source 2
2571  * arg[2] = v-register nr of destination
2572  */
2573 X(vxor)
2574 {
2575  cpu->cd.ppc.vr_hi[ic->arg[2]] =
2576  cpu->cd.ppc.vr_hi[ic->arg[0]] ^ cpu->cd.ppc.vr_hi[ic->arg[1]];
2577  cpu->cd.ppc.vr_lo[ic->arg[2]] =
2578  cpu->cd.ppc.vr_lo[ic->arg[0]] ^ cpu->cd.ppc.vr_lo[ic->arg[1]];
2579 }
2580 
2581 
2582 /*
2583  * tlbia: TLB invalidate all
2584  */
2585 X(tlbia)
2586 {
2587  fatal("[ tlbia ]\n");
2589 }
2590 
2591 
2592 /*
2593  * tlbie: TLB invalidate
2594  */
2595 X(tlbie)
2596 {
2597  /* fatal("[ tlbie ]\n"); */
2600 }
2601 
2602 
2603 /*
2604  * sc: Syscall.
2605  */
2606 X(sc)
2607 {
2608  /* Synchronize the PC (pointing to _after_ this instruction) */
2609  cpu->pc = (cpu->pc & ~0xfff) + ic->arg[1];
2610 
2612 
2613  /* This caused an update to the PC register, so there is no need
2614  to worry about the next instruction being an end_of_page. */
2615 }
2616 
2617 
2618 /*
2619  * openfirmware:
2620  */
2621 X(openfirmware)
2622 {
2623  of_emul(cpu);
2624  if (cpu->running == 0) {
2626  cpu->cd.ppc.next_ic = &nothing_call;
2628  }
2629 
2630  cpu->pc = cpu->cd.ppc.spr[SPR_LR];
2631  if (cpu->machine->show_trace_tree)
2633 
2635 }
2636 
2637 
2638 /*
2639  * tlbsx_dot: TLB scan
2640  */
2641 X(tlbsx_dot)
2642 {
2643  /* TODO */
2644  cpu->cd.ppc.cr &= ~(0xf0000000);
2645  cpu->cd.ppc.cr |= 0x20000000;
2646  cpu->cd.ppc.cr |= ((cpu->cd.ppc.spr[SPR_XER] >> 3) & 0x10000000);
2647 }
2648 
2649 
2650 /*
2651  * tlbli:
2652  */
2653 X(tlbli)
2654 {
2655  fatal("tlbli\n");
2657 }
2658 
2659 
2660 /*
2661  * tlbld:
2662  */
2663 X(tlbld)
2664 {
2665  /* MODE_uint_t vaddr = reg(ic->arg[0]);
2666  MODE_uint_t paddr = cpu->cd.ppc.spr[SPR_RPA]; */
2667 
2668  fatal("tlbld\n");
2670 }
2671 
2672 
2673 /*****************************************************************************/
2674 
2675 
2676 X(end_of_page)
2677 {
2678  /* Update the PC: (offset 0, but on the next page) */
2681 
2682  /* Find the new physical page and update the translation pointers: */
2684 
2685  /* end_of_page doesn't count as an executed instruction: */
2687 }
2688 
2689 
2690 /*****************************************************************************/
2691 
2692 
2693 /*
2694  * ppc_instr_to_be_translated():
2695  *
2696  * Translate an instruction word into a ppc_instr_call. ic is filled in with
2697  * valid data for the translated instruction, or a "nothing" instruction if
2698  * there was a translation failure. The newly translated instruction is then
2699  * executed.
2700  */
2701 X(to_be_translated)
2702 {
2703  uint64_t addr, low_pc, tmp_addr;
2704  uint32_t iword, mask;
2705  unsigned char *page;
2706  unsigned char ib[4];
2707  int main_opcode, rt, rs, ra, rb, rc, aa_bit, l_bit, lk_bit, spr, sh,
2708  xo, imm, load, size, update, zero, bf, bo, bi, bh, oe_bit, n64=0,
2709  bfa, fp, byterev, nb, mb, me;
2710  void (*samepage_function)(struct cpu *, struct ppc_instr_call *);
2711  void (*rc_f)(struct cpu *, struct ppc_instr_call *);
2712 
2713  /* Figure out the (virtual) address of the instruction: */
2714  low_pc = ((size_t)ic - (size_t)cpu->cd.ppc.cur_ic_page)
2715  / sizeof(struct ppc_instr_call);
2716  addr = cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1)
2718  addr += (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
2719  cpu->pc = addr;
2720  addr &= ~((1 << PPC_INSTR_ALIGNMENT_SHIFT) - 1);
2721 
2722  /* Read the instruction word from memory: */
2723 #ifdef MODE32
2724  page = cpu->cd.ppc.host_load[((uint32_t)addr) >> 12];
2725 #else
2726  {
2727  const uint32_t mask1 = (1 << DYNTRANS_L1N) - 1;
2728  const uint32_t mask2 = (1 << DYNTRANS_L2N) - 1;
2729  const uint32_t mask3 = (1 << DYNTRANS_L3N) - 1;
2730  uint32_t x1 = (addr >> (64-DYNTRANS_L1N)) & mask1;
2731  uint32_t x2 = (addr >> (64-DYNTRANS_L1N-DYNTRANS_L2N)) & mask2;
2732  uint32_t x3 = (addr >> (64-DYNTRANS_L1N-DYNTRANS_L2N-
2733  DYNTRANS_L3N)) & mask3;
2734  struct DYNTRANS_L2_64_TABLE *l2 = cpu->cd.ppc.l1_64[x1];
2735  struct DYNTRANS_L3_64_TABLE *l3 = l2->l3[x2];
2736  page = l3->host_load[x3];
2737  }
2738 #endif
2739 
2740  if (page != NULL) {
2741  /* fatal("TRANSLATION HIT!\n"); */
2742  memcpy(ib, page + (addr & 0xfff), sizeof(ib));
2743  } else {
2744  /* fatal("TRANSLATION MISS!\n"); */
2745  if (!cpu->memory_rw(cpu, cpu->mem, addr, ib,
2746  sizeof(ib), MEM_READ, CACHE_INSTRUCTION)) {
2747  fatal("PPC to_be_translated(): "
2748  "read failed: TODO\n");
2749  exit(1);
2750  /* goto bad; */
2751  }
2752  }
2753 
2754  {
2755  uint32_t *p = (uint32_t *) ib;
2756  iword = *p;
2757  iword = BE32_TO_HOST(iword);
2758  }
2759 
2760 #define DYNTRANS_TO_BE_TRANSLATED_HEAD
2761 #include "cpu_dyntrans.cc"
2762 #undef DYNTRANS_TO_BE_TRANSLATED_HEAD
2763 
2764 
2765  /*
2766  * Translate the instruction:
2767  */
2768 
2769  main_opcode = iword >> 26;
2770 
2771  switch (main_opcode) {
2772 
2773  case 0x04:
2774  if (iword == 0x12739cc4) {
2775  /* vxor v19,v19,v19 */
2776  ic->f = instr(vxor);
2777  ic->arg[0] = 19;
2778  ic->arg[1] = 19;
2779  ic->arg[2] = 19;
2780  } else {
2781  if (!cpu->translation_readahead)
2782  fatal("[ TODO: Unimplemented ALTIVEC, iword"
2783  " = 0x%08" PRIx32"x ]\n", iword);
2784  goto bad;
2785  }
2786  break;
2787 
2788  case PPC_HI6_MULLI:
2789  rt = (iword >> 21) & 31;
2790  ra = (iword >> 16) & 31;
2791  imm = (int16_t)(iword & 0xffff);
2792  ic->f = instr(mulli);
2793  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2794  ic->arg[1] = (ssize_t)imm;
2795  ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);
2796  break;
2797 
2798  case PPC_HI6_SUBFIC:
2799  rt = (iword >> 21) & 31;
2800  ra = (iword >> 16) & 31;
2801  imm = (int16_t)(iword & 0xffff);
2802  ic->f = instr(subfic);
2803  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2804  ic->arg[1] = (ssize_t)imm;
2805  ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);
2806  break;
2807 
2808  case PPC_HI6_CMPLI:
2809  case PPC_HI6_CMPI:
2810  bf = (iword >> 23) & 7;
2811  l_bit = (iword >> 21) & 1;
2812  ra = (iword >> 16) & 31;
2813  if (main_opcode == PPC_HI6_CMPLI) {
2814  imm = iword & 0xffff;
2815  if (l_bit)
2816  ic->f = instr(cmpldi);
2817  else
2818  ic->f = instr(cmplwi);
2819  } else {
2820  imm = (int16_t)(iword & 0xffff);
2821  if (l_bit)
2822  ic->f = instr(cmpdi);
2823  else {
2824  if (bf == 0)
2825  ic->f = instr(cmpwi_cr0);
2826  else
2827  ic->f = instr(cmpwi);
2828  }
2829  }
2830  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2831  ic->arg[1] = (ssize_t)imm;
2832  ic->arg[2] = 28 - 4 * bf;
2833  break;
2834 
2835  case PPC_HI6_ADDIC:
2836  case PPC_HI6_ADDIC_DOT:
2837  if (cpu->cd.ppc.bits == 64) {
2838  if (!cpu->translation_readahead)
2839  fatal("addic for 64-bit: TODO\n");
2840  goto bad;
2841  }
2842  rt = (iword >> 21) & 31;
2843  ra = (iword >> 16) & 31;
2844  imm = (int16_t)(iword & 0xffff);
2845  if (main_opcode == PPC_HI6_ADDIC)
2846  ic->f = instr(addic);
2847  else
2848  ic->f = instr(addic_dot);
2849  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2850  ic->arg[1] = imm;
2851  ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);
2852  break;
2853 
2854  case PPC_HI6_ADDI:
2855  case PPC_HI6_ADDIS:
2856  rt = (iword >> 21) & 31; ra = (iword >> 16) & 31;
2857  ic->f = instr(addi);
2858  if (ra == 0)
2859  ic->f = instr(li);
2860  else
2861  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2862  ic->arg[1] = (int16_t)(iword & 0xffff);
2863  if (main_opcode == PPC_HI6_ADDIS)
2864  ic->arg[1] <<= 16;
2865  if (ra == 0 && ic->arg[1] == 0)
2866  ic->f = instr(li_0);
2867  ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);
2868  break;
2869 
2870  case PPC_HI6_ANDI_DOT:
2871  case PPC_HI6_ANDIS_DOT:
2872  rs = (iword >> 21) & 31; ra = (iword >> 16) & 31;
2873  ic->f = instr(andi_dot);
2874  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
2875  ic->arg[1] = iword & 0xffff;
2876  if (main_opcode == PPC_HI6_ANDIS_DOT)
2877  ic->arg[1] <<= 16;
2878  ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2879  break;
2880 
2881  case PPC_HI6_ORI:
2882  case PPC_HI6_ORIS:
2883  case PPC_HI6_XORI:
2884  case PPC_HI6_XORIS:
2885  rs = (iword >> 21) & 31; ra = (iword >> 16) & 31;
2886  if (main_opcode == PPC_HI6_ORI ||
2887  main_opcode == PPC_HI6_ORIS)
2888  ic->f = instr(ori);
2889  else
2890  ic->f = instr(xori);
2891  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
2892  ic->arg[1] = iword & 0xffff;
2893  if (main_opcode == PPC_HI6_ORIS ||
2894  main_opcode == PPC_HI6_XORIS)
2895  ic->arg[1] <<= 16;
2896  ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2897  break;
2898 
2899  case PPC_HI6_LBZ:
2900  case PPC_HI6_LBZU:
2901  case PPC_HI6_LHZ:
2902  case PPC_HI6_LHZU:
2903  case PPC_HI6_LHA:
2904  case PPC_HI6_LHAU:
2905  case PPC_HI6_LWZ:
2906  case PPC_HI6_LWZU:
2907  case PPC_HI6_LD:
2908  case PPC_HI6_LFD:
2909  case PPC_HI6_LFS:
2910  case PPC_HI6_STB:
2911  case PPC_HI6_STBU:
2912  case PPC_HI6_STH:
2913  case PPC_HI6_STHU:
2914  case PPC_HI6_STW:
2915  case PPC_HI6_STWU:
2916  case PPC_HI6_STD:
2917  case PPC_HI6_STFD:
2918  case PPC_HI6_STFS:
2919  rs = (iword >> 21) & 31;
2920  ra = (iword >> 16) & 31;
2921  imm = (int16_t)iword;
2922  load = 0; zero = 1; size = 0; update = 0; fp = 0;
2923  ic->f = NULL;
2924  switch (main_opcode) {
2925  case PPC_HI6_LBZ: load=1; break;
2926  case PPC_HI6_LBZU: load=1; update=1; break;
2927  case PPC_HI6_LHA: load=1; size=1; zero=0; break;
2928  case PPC_HI6_LHAU: load=1; size=1; zero=0; update=1; break;
2929  case PPC_HI6_LHZ: load=1; size=1; break;
2930  case PPC_HI6_LHZU: load=1; size=1; update=1; break;
2931  case PPC_HI6_LWZ: load=1; size=2; break;
2932  case PPC_HI6_LWZU: load=1; size=2; update=1; break;
2933  case PPC_HI6_LD: load=1; size=3; break;
2934  case PPC_HI6_LFD: load=1; size=3; fp=1;ic->f=instr(lfd);break;
2935  case PPC_HI6_LFS: load=1; size=2; fp=1;ic->f=instr(lfs);break;
2936  case PPC_HI6_STB: break;
2937  case PPC_HI6_STBU: update=1; break;
2938  case PPC_HI6_STH: size=1; break;
2939  case PPC_HI6_STHU: size=1; update=1; break;
2940  case PPC_HI6_STW: size=2; break;
2941  case PPC_HI6_STWU: size=2; update=1; break;
2942  case PPC_HI6_STD: size=3; break;
2943  case PPC_HI6_STFD: size=3; fp=1; ic->f = instr(stfd); break;
2944  case PPC_HI6_STFS: size=2; fp=1; ic->f = instr(stfs); break;
2945  }
2946  if (ic->f == NULL) {
2947  ic->f =
2948 #ifdef MODE32
2949  ppc32_loadstore
2950 #else
2952 #endif
2953  [size + 4*zero + 8*load + (imm==0? 16 : 0)
2954  + 32*update];
2955  }
2956  if (ra == 0 && update) {
2957  if (!cpu->translation_readahead)
2958  fatal("TODO: ra=0 && update?\n");
2959  goto bad;
2960  }
2961  if (fp)
2962  ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rs]);
2963  else
2964  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
2965  if (ra == 0)
2966  ic->arg[1] = (size_t)(&cpu->cd.ppc.zero);
2967  else
2968  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2969  ic->arg[2] = (ssize_t)imm;
2970  break;
2971 
2972  case PPC_HI6_BC:
2973  aa_bit = (iword >> 1) & 1;
2974  lk_bit = iword & 1;
2975  bo = (iword >> 21) & 31;
2976  bi = (iword >> 16) & 31;
2977  tmp_addr = (int64_t)(int16_t)(iword & 0xfffc);
2978  if (aa_bit) {
2979  if (!cpu->translation_readahead)
2980  fatal("aa_bit: NOT YET\n");
2981  goto bad;
2982  }
2983  if (lk_bit) {
2984  ic->f = instr(bcl);
2985  samepage_function = instr(bcl_samepage);
2986  } else {
2987  ic->f = instr(bc);
2988  if ((bo & 0x14) == 0x04) {
2989  samepage_function = bo & 8?
2990  instr(bc_samepage_simple1) :
2991  instr(bc_samepage_simple0);
2992  } else
2993  samepage_function = instr(bc_samepage);
2994  }
2995  ic->arg[0] = (ssize_t)(tmp_addr + (addr & 0xffc));
2996  ic->arg[1] = bo;
2997  ic->arg[2] = 31-bi;
2998  /* Branches are calculated as cur PC + offset. */
2999  /* Special case: branch within the same page: */
3000  {
3001  uint64_t mask_within_page =
3002  ((PPC_IC_ENTRIES_PER_PAGE-1) << 2) | 3;
3003  uint64_t old_pc = addr;
3004  uint64_t new_pc = old_pc + (int32_t)tmp_addr;
3005  if ((old_pc & ~mask_within_page) ==
3006  (new_pc & ~mask_within_page)) {
3007  ic->f = samepage_function;
3008  ic->arg[0] = (size_t) (
3009  cpu->cd.ppc.cur_ic_page +
3010  ((new_pc & mask_within_page) >> 2));
3011  }
3012  }
3013  break;
3014 
3015  case PPC_HI6_SC:
3016  ic->arg[0] = (iword >> 5) & 0x7f;
3017  ic->arg[1] = (addr & 0xfff) + 4;
3018  if (iword == 0x44ee0002) {
3019  /* Special case/magic hack for OpenFirmware emul: */
3020  ic->f = instr(openfirmware);
3021  } else
3022  ic->f = instr(sc);
3023  break;
3024 
3025  case PPC_HI6_B:
3026  aa_bit = (iword & 2) >> 1;
3027  lk_bit = iword & 1;
3028  tmp_addr = (int64_t)(int32_t)((iword & 0x03fffffc) << 6);
3029  tmp_addr = (int64_t)tmp_addr >> 6;
3030  if (lk_bit) {
3031  if (cpu->machine->show_trace_tree) {
3032  ic->f = instr(bl_trace);
3033  samepage_function = instr(bl_samepage_trace);
3034  } else {
3035  ic->f = instr(bl);
3036  samepage_function = instr(bl_samepage);
3037  }
3038  } else {
3039  ic->f = instr(b);
3040  samepage_function = instr(b_samepage);
3041  }
3042  ic->arg[0] = (ssize_t)(tmp_addr + (addr & 0xffc));
3043  ic->arg[1] = (addr & 0xffc) + 4;
3044  /* Branches are calculated as cur PC + offset. */
3045  /* Special case: branch within the same page: */
3046  {
3047  uint64_t mask_within_page =
3048  ((PPC_IC_ENTRIES_PER_PAGE-1) << 2) | 3;
3049  uint64_t old_pc = addr;
3050  uint64_t new_pc = old_pc + (int32_t)tmp_addr;
3051  if ((old_pc & ~mask_within_page) ==
3052  (new_pc & ~mask_within_page)) {
3053  ic->f = samepage_function;
3054  ic->arg[0] = (size_t) (
3055  cpu->cd.ppc.cur_ic_page +
3056  ((new_pc & mask_within_page) >> 2));
3057  }
3058  }
3059  if (aa_bit) {
3060  if (lk_bit) {
3061  if (cpu->machine->show_trace_tree) {
3062  ic->f = instr(bla_trace);
3063  } else {
3064  ic->f = instr(bla);
3065  }
3066  } else {
3067  ic->f = instr(ba);
3068  }
3069  ic->arg[0] = (ssize_t)tmp_addr;
3070  }
3071  break;
3072 
3073  case PPC_HI6_19:
3074  xo = (iword >> 1) & 1023;
3075  switch (xo) {
3076 
3077  case PPC_19_BCLR:
3078  case PPC_19_BCCTR:
3079  bo = (iword >> 21) & 31;
3080  bi = (iword >> 16) & 31;
3081  bh = (iword >> 11) & 3;
3082  lk_bit = iword & 1;
3083  if (xo == PPC_19_BCLR) {
3084  if (lk_bit)
3085  ic->f = instr(bclr_l);
3086  else {
3087  ic->f = instr(bclr);
3088  if (!cpu->machine->show_trace_tree &&
3089  (bo & 0x14) == 0x14)
3090  ic->f = instr(bclr_20);
3091  }
3092  } else {
3093  if (!(bo & 4)) {
3094  if (!cpu->translation_readahead)
3095  fatal("TODO: bclr/bcctr "
3096  "bo bit 2 clear!\n");
3097  goto bad;
3098  }
3099  if (lk_bit)
3100  ic->f = instr(bcctr_l);
3101  else
3102  ic->f = instr(bcctr);
3103  }
3104  ic->arg[0] = bo;
3105  ic->arg[1] = 31 - bi;
3106  ic->arg[2] = bh;
3107  break;
3108 
3109  case PPC_19_ISYNC:
3110  /* TODO */
3111  ic->f = instr(nop);
3112  break;
3113 
3114  case PPC_19_RFI:
3115  ic->f = instr(rfi);
3116  break;
3117 
3118  case PPC_19_RFID:
3119  ic->f = instr(rfid);
3120  break;
3121 
3122  case PPC_19_MCRF:
3123  bf = (iword >> 23) & 7;
3124  bfa = (iword >> 18) & 7;
3125  ic->arg[0] = 28 - 4*bf;
3126  ic->arg[1] = 28 - 4*bfa;
3127  ic->f = instr(mcrf);
3128  break;
3129 
3130  case PPC_19_CRAND:
3131  case PPC_19_CRANDC:
3132  case PPC_19_CREQV:
3133  case PPC_19_CROR:
3134  case PPC_19_CRORC:
3135  case PPC_19_CRNOR:
3136  case PPC_19_CRXOR:
3137  switch (xo) {
3138  case PPC_19_CRAND: ic->f = instr(crand); break;
3139  case PPC_19_CRANDC: ic->f = instr(crandc); break;
3140  case PPC_19_CREQV: ic->f = instr(creqv); break;
3141  case PPC_19_CROR: ic->f = instr(cror); break;
3142  case PPC_19_CRORC: ic->f = instr(crorc); break;
3143  case PPC_19_CRNOR: ic->f = instr(crnor); break;
3144  case PPC_19_CRXOR: ic->f = instr(crxor); break;
3145  }
3146  ic->arg[0] = iword;
3147  break;
3148 
3149  default:goto bad;
3150  }
3151  break;
3152 
3153  case PPC_HI6_RLWNM:
3154  case PPC_HI6_RLWINM:
3155  ra = (iword >> 16) & 31;
3156  mb = (iword >> 6) & 31;
3157  me = (iword >> 1) & 31;
3158  rc = iword & 1;
3159  mask = 0;
3160  for (;;) {
3161  mask |= ((uint32_t)0x80000000 >> mb);
3162  if (mb == me)
3163  break;
3164  mb ++; mb &= 31;
3165  }
3166  switch (main_opcode) {
3167  case PPC_HI6_RLWNM:
3168  ic->f = rc? instr(rlwnm_dot) : instr(rlwnm); break;
3169  case PPC_HI6_RLWINM:
3170  ic->f = rc? instr(rlwinm_dot) : instr(rlwinm); break;
3171  }
3172  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3173  ic->arg[1] = mask;
3174  ic->arg[2] = (uint32_t)iword;
3175  break;
3176 
3177  case PPC_HI6_RLWIMI:
3178  rs = (iword >> 21) & 31;
3179  ra = (iword >> 16) & 31;
3180  ic->f = instr(rlwimi);
3181  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
3182  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3183  ic->arg[2] = (uint32_t)iword;
3184  break;
3185 
3186  case PPC_HI6_LMW:
3187  case PPC_HI6_STMW:
3188  /* NOTE: Loads use rt, not rs. */
3189  rs = (iword >> 21) & 31;
3190  ra = (iword >> 16) & 31;
3191  ic->arg[0] = rs;
3192  if (ra == 0)
3193  ic->arg[1] = (size_t)(&cpu->cd.ppc.zero);
3194  else
3195  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3196  ic->arg[2] = (int32_t)(int16_t)iword;
3197  switch (main_opcode) {
3198  case PPC_HI6_LMW:
3199  ic->f = instr(lmw);
3200  break;
3201  case PPC_HI6_STMW:
3202  ic->f = instr(stmw);
3203  break;
3204  }
3205  break;
3206 
3207  case PPC_HI6_30:
3208  xo = (iword >> 2) & 7;
3209  switch (xo) {
3210 
3211  case PPC_30_RLDICL:
3212  case PPC_30_RLDICR:
3213  case PPC_30_RLDIMI:
3214  switch (xo) {
3215  case PPC_30_RLDICL: ic->f = instr(rldicl); break;
3216  case PPC_30_RLDICR: ic->f = instr(rldicr); break;
3217  case PPC_30_RLDIMI: ic->f = instr(rldimi); break;
3218  }
3219  ic->arg[0] = iword;
3220  if (cpu->cd.ppc.bits == 32) {
3221  if (!cpu->translation_readahead)
3222  fatal("TODO: rld* in 32-bit mode?\n");
3223  goto bad;
3224  }
3225  break;
3226 
3227  default:goto bad;
3228  }
3229  break;
3230 
3231  case PPC_HI6_31:
3232  xo = (iword >> 1) & 1023;
3233  switch (xo) {
3234 
3235  case PPC_31_CMPL:
3236  case PPC_31_CMP:
3237  bf = (iword >> 23) & 7;
3238  l_bit = (iword >> 21) & 1;
3239  ra = (iword >> 16) & 31;
3240  rb = (iword >> 11) & 31;
3241  if (xo == PPC_31_CMPL) {
3242  if (l_bit)
3243  ic->f = instr(cmpld);
3244  else
3245  ic->f = instr(cmplw);
3246  } else {
3247  if (l_bit)
3248  ic->f = instr(cmpd);
3249  else {
3250  if (bf == 0)
3251  ic->f = instr(cmpw_cr0);
3252  else
3253  ic->f = instr(cmpw);
3254  }
3255  }
3256  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3257  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3258  ic->arg[2] = 28 - 4*bf;
3259  break;
3260 
3261  case PPC_31_CNTLZW:
3262  rs = (iword >> 21) & 31;
3263  ra = (iword >> 16) & 31;
3264  rc = iword & 1;
3265  if (rc) {
3266  if (!cpu->translation_readahead)
3267  fatal("TODO: rc\n");
3268  goto bad;
3269  }
3270  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
3271  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3272  ic->f = instr(cntlzw);
3273  break;
3274 
3275  case PPC_31_MFSPR:
3276  rt = (iword >> 21) & 31;
3277  spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
3278  debug_spr_usage(cpu->pc, spr);
3279  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rt]);
3280  ic->arg[1] = (size_t)(&cpu->cd.ppc.spr[spr]);
3281  switch (spr) {
3282  // Reuse SPR_TB* for TBR_TB*:
3283  case TBR_TBL: ic->f = instr(mftb); break;
3284  case TBR_TBU: ic->f = instr(mftbu); break;
3285  case SPR_PMC1: ic->f = instr(mfspr_pmc1); break;
3286  default: ic->f = instr(mfspr);
3287  }
3288  break;
3289 
3290  case PPC_31_MTSPR:
3291  rs = (iword >> 21) & 31;
3292  spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
3293  debug_spr_usage(cpu->pc, spr);
3294  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
3295  ic->arg[1] = (size_t)(&cpu->cd.ppc.spr[spr]);
3296  switch (spr) {
3297  case SPR_LR:
3298  ic->f = instr(mtlr);
3299  break;
3300  case SPR_CTR:
3301  ic->f = instr(mtctr);
3302  break;
3303  case SPR_SPRG2:
3304  ic->f = instr(mtspr_sprg2);
3305  break;
3306  default:ic->f = instr(mtspr);
3307  }
3308  break;
3309 
3310  case PPC_31_MFCR:
3311  rt = (iword >> 21) & 31;
3312  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rt]);
3313  ic->f = instr(mfcr);
3314  break;
3315 
3316  case PPC_31_MFMSR:
3317  rt = (iword >> 21) & 31;
3318  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rt]);
3319  ic->f = instr(mfmsr);
3320  break;
3321 
3322  case PPC_31_MTMSR:
3323  case PPC_31_MTMSRD:
3324  rs = (iword >> 21) & 31;
3325  l_bit = (iword >> 16) & 1;
3326  if (l_bit) {
3327  if (!cpu->translation_readahead)
3328  fatal("TODO: mtmsr l-bit\n");
3329  goto bad;
3330  }
3331  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
3332  ic->arg[1] = (addr & 0xfff) + 4;
3333  ic->arg[2] = xo == PPC_31_MTMSRD;
3334  ic->f = instr(mtmsr);
3335  break;
3336 
3337  case PPC_31_MTCRF:
3338  rs = (iword >> 21) & 31;
3339  {
3340  int i, fxm = (iword >> 12) & 255;
3341  uint32_t tmp = 0;
3342  for (i=0; i<8; i++, fxm <<= 1) {
3343  tmp <<= 4;
3344  if (fxm & 128)
3345  tmp |= 0xf;
3346  }
3347  ic->arg[1] = (uint32_t)tmp;
3348  }
3349  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
3350  ic->f = instr(mtcrf);
3351  break;
3352 
3353  case PPC_31_MFSRIN:
3354  case PPC_31_MTSRIN:
3355  rt = (iword >> 21) & 31;
3356  rb = (iword >> 11) & 31;
3357  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3358  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rt]);
3359  switch (xo) {
3360  case PPC_31_MFSRIN: ic->f = instr(mfsrin); break;
3361  case PPC_31_MTSRIN: ic->f = instr(mtsrin); break;
3362  }
3363  if (cpu->cd.ppc.bits == 64) {
3364  if (!cpu->translation_readahead)
3365  fatal("Not yet for 64-bit mode\n");
3366  goto bad;
3367  }
3368  break;
3369 
3370  case PPC_31_MFSR:
3371  case PPC_31_MTSR:
3372  rt = (iword >> 21) & 31;
3373  ic->arg[0] = (iword >> 16) & 15;
3374  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rt]);
3375  switch (xo) {
3376  case PPC_31_MFSR: ic->f = instr(mfsr); break;
3377  case PPC_31_MTSR: ic->f = instr(mtsr); break;
3378  }
3379  if (cpu->cd.ppc.bits == 64) {
3380  if (!cpu->translation_readahead)
3381  fatal("Not yet for 64-bit mode\n");
3382  goto bad;
3383  }
3384  break;
3385 
3386  case PPC_31_SRAWI:
3387  rs = (iword >> 21) & 31;
3388  ra = (iword >> 16) & 31;
3389  sh = (iword >> 11) & 31;
3390  rc = iword & 1;
3391  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
3392  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3393  ic->arg[2] = sh;
3394  if (rc)
3395  ic->f = instr(srawi_dot);
3396  else
3397  ic->f = instr(srawi);
3398  break;
3399 
3400  case PPC_31_SYNC:
3401  case PPC_31_DSSALL:
3402  case PPC_31_EIEIO:
3403  case PPC_31_DCBST:
3404  case PPC_31_DCBTST:
3405  case PPC_31_DCBF:
3406  case PPC_31_DCBT:
3407  case PPC_31_ICBI:
3408  ic->f = instr(nop);
3409  break;
3410 
3411  case PPC_31_DCBZ:
3412  ra = (iword >> 16) & 31;
3413  rb = (iword >> 11) & 31;
3414  if (ra == 0)
3415  ic->arg[0] = (size_t)(&cpu->cd.ppc.zero);
3416  else
3417  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3418  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3419  ic->arg[2] = addr & 0xfff;
3420  ic->f = instr(dcbz);
3421  break;
3422 
3423  case PPC_31_TLBIA:
3424  ic->f = instr(tlbia);
3425  break;
3426 
3427  case PPC_31_TLBSYNC:
3428  /* According to IBM, "Ensures that a tlbie and
3429  tlbia instruction executed by one processor has
3430  completed on all other processors.", which in
3431  GXemul means a nop :-) */
3432  ic->f = instr(nop);
3433  break;
3434 
3435  case PPC_31_TLBIE:
3436  /* TODO: POWER also uses ra? */
3437  rb = (iword >> 11) & 31;
3438  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3439  ic->f = instr(tlbie);
3440  break;
3441 
3442  case PPC_31_TLBLD: /* takes an arg */
3443  rb = (iword >> 11) & 31;
3444  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3445  ic->f = instr(tlbld);
3446  break;
3447 
3448  case PPC_31_TLBLI: /* takes an arg */
3449  rb = (iword >> 11) & 31;
3450  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3451  ic->f = instr(tlbli);
3452  break;
3453 
3454  case PPC_31_TLBSX_DOT:
3455  /* TODO */
3456  ic->f = instr(tlbsx_dot);
3457  break;
3458 
3459  case PPC_31_MFTB:
3460  rt = (iword >> 21) & 31;
3461  spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
3462  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rt]);
3463  switch (spr) {
3464  case 268: ic->f = instr(mftb); break;
3465  case 269: ic->f = instr(mftbu); break;
3466  default:if (!cpu->translation_readahead)
3467  fatal("mftb spr=%i?\n", spr);
3468  goto bad;
3469  }
3470  break;
3471 
3472  case PPC_31_NEG:
3473  rt = (iword >> 21) & 31;
3474  ra = (iword >> 16) & 31;
3475  rc = iword & 1;
3476  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3477  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rt]);
3478  if (rc)
3479  ic->f = instr(neg_dot);
3480  else
3481  ic->f = instr(neg);
3482  break;
3483 
3484  case PPC_31_LWARX:
3485  case PPC_31_LDARX:
3486  case PPC_31_STWCX_DOT:
3487  case PPC_31_STDCX_DOT:
3488  ic->arg[0] = iword;
3489  ic->f = instr(llsc);
3490  break;
3491 
3492  case PPC_31_LSWI:
3493  case PPC_31_STSWI:
3494  rs = (iword >> 21) & 31;
3495  ra = (iword >> 16) & 31;
3496  nb = (iword >> 11) & 31;
3497  ic->arg[0] = rs;
3498  if (ra == 0)
3499  ic->arg[1] = (size_t)(&cpu->cd.ppc.zero);
3500  else
3501  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3502  ic->arg[2] = nb == 0? 32 : nb;
3503  switch (xo) {
3504  case PPC_31_LSWI: ic->f = instr(lswi); break;
3505  case PPC_31_STSWI: ic->f = instr(stswi); break;
3506  }
3507  break;
3508 
3509  case PPC_31_WRTEEI:
3510  ic->arg[0] = iword & 0x8000;
3511  ic->f = instr(wrteei);
3512  break;
3513 
3514  case 0x1c3:
3515  fatal("[ mtdcr: TODO ]\n");
3516  ic->f = instr(nop);
3517  break;
3518 
3519  case PPC_31_LBZX:
3520  case PPC_31_LBZUX:
3521  case PPC_31_LHAX:
3522  case PPC_31_LHAUX:
3523  case PPC_31_LHZX:
3524  case PPC_31_LHZUX:
3525  case PPC_31_LWZX:
3526  case PPC_31_LWZUX:
3527  case PPC_31_LHBRX:
3528  case PPC_31_LWBRX:
3529  case PPC_31_LFDX:
3530  case PPC_31_LFSX:
3531  case PPC_31_STBX:
3532  case PPC_31_STBUX:
3533  case PPC_31_STHX:
3534  case PPC_31_STHUX:
3535  case PPC_31_STWX:
3536  case PPC_31_STWUX:
3537  case PPC_31_STDX:
3538  case PPC_31_STDUX:
3539  case PPC_31_STHBRX:
3540  case PPC_31_STWBRX:
3541  case PPC_31_STFDX:
3542  case PPC_31_STFSX:
3543  rs = (iword >> 21) & 31;
3544  ra = (iword >> 16) & 31;
3545  rb = (iword >> 11) & 31;
3546  if (ra == 0)
3547  ic->arg[1] = (size_t)(&cpu->cd.ppc.zero);
3548  else
3549  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3550  ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3551  load = 0; zero = 1; size = 0; update = 0;
3552  byterev = 0; fp = 0;
3553  ic->f = NULL;
3554  switch (xo) {
3555  case PPC_31_LBZX: load = 1; break;
3556  case PPC_31_LBZUX: load=update=1; break;
3557  case PPC_31_LHAX: size=1; load=1; zero=0; break;
3558  case PPC_31_LHAUX: size=1; load=update=1; zero=0; break;
3559  case PPC_31_LHZX: size=1; load=1; break;
3560  case PPC_31_LHZUX: size=1; load=update = 1; break;
3561  case PPC_31_LWZX: size=2; load=1; break;
3562  case PPC_31_LWZUX: size=2; load=update = 1; break;
3563  case PPC_31_LHBRX: size=1; load=1; byterev=1;
3564  ic->f = instr(lhbrx); break;
3565  case PPC_31_LWBRX: size=2; load=1; byterev=1;
3566  ic->f = instr(lwbrx); break;
3567  case PPC_31_LFDX: size=3; load=1; fp=1;
3568  ic->f = instr(lfdx); break;
3569  case PPC_31_LFSX: size=2; load=1; fp=1;
3570  ic->f = instr(lfsx); break;
3571  case PPC_31_STBX: break;
3572  case PPC_31_STBUX: update = 1; break;
3573  case PPC_31_STHX: size=1; break;
3574  case PPC_31_STHUX: size=1; update = 1; break;
3575  case PPC_31_STWX: size=2; break;
3576  case PPC_31_STWUX: size=2; update = 1; break;
3577  case PPC_31_STDX: size=3; break;
3578  case PPC_31_STDUX: size=3; update = 1; break;
3579  case PPC_31_STHBRX:size=1; byterev = 1;
3580  ic->f = instr(sthbrx); break;
3581  case PPC_31_STWBRX:size=2; byterev = 1;
3582  ic->f = instr(stwbrx); break;
3583  case PPC_31_STFDX: size=3; fp=1;
3584  ic->f = instr(stfdx); break;
3585  case PPC_31_STFSX: size=2; fp=1;
3586  ic->f = instr(stfsx); break;
3587  }
3588  if (fp)
3589  ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rs]);
3590  else
3591  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
3592  if (!byterev && ic->f == NULL) {
3593  ic->f =
3594 #ifdef MODE32
3595  ppc32_loadstore_indexed
3596 #else
3598 #endif
3599  [size + 4*zero + 8*load + 16*update];
3600  }
3601  if (ra == 0 && update) {
3602  if (!cpu->translation_readahead)
3603  fatal("TODO: ra=0 && update?\n");
3604  goto bad;
3605  }
3606  break;
3607 
3608  case PPC_31_EXTSB:
3609  case PPC_31_EXTSH:
3610  case PPC_31_EXTSW:
3611  case PPC_31_SLW:
3612  case PPC_31_SLD:
3613  case PPC_31_SRAW:
3614  case PPC_31_SRW:
3615  case PPC_31_AND:
3616  case PPC_31_NAND:
3617  case PPC_31_ANDC:
3618  case PPC_31_NOR:
3619  case PPC_31_OR:
3620  case PPC_31_ORC:
3621  case PPC_31_XOR:
3622  case PPC_31_EQV:
3623  rs = (iword >> 21) & 31;
3624  ra = (iword >> 16) & 31;
3625  rb = (iword >> 11) & 31;
3626  rc = iword & 1;
3627  rc_f = NULL;
3628  switch (xo) {
3629  case PPC_31_EXTSB:ic->f = instr(extsb);
3630  rc_f = instr(extsb_dot); break;
3631  case PPC_31_EXTSH:ic->f = instr(extsh);
3632  rc_f = instr(extsh_dot); break;
3633  case PPC_31_EXTSW:ic->f = instr(extsw);
3634  rc_f = instr(extsw_dot); break;
3635  case PPC_31_SLW: ic->f = instr(slw);
3636  rc_f = instr(slw_dot); break;
3637  case PPC_31_SLD: ic->f = instr(sld);
3638  rc_f = instr(sld_dot); break;
3639  case PPC_31_SRAW: ic->f = instr(sraw);
3640  rc_f = instr(sraw_dot); break;
3641  case PPC_31_SRW: ic->f = instr(srw);
3642  rc_f = instr(srw_dot); break;
3643  case PPC_31_AND: ic->f = instr(and);
3644  rc_f = instr(and_dot); break;
3645  case PPC_31_NAND: ic->f = instr(nand);
3646  rc_f = instr(nand_dot); break;
3647  case PPC_31_ANDC: ic->f = instr(andc);
3648  rc_f = instr(andc_dot); break;
3649  case PPC_31_NOR: ic->f = instr(nor);
3650  rc_f = instr(nor_dot); break;
3651  case PPC_31_OR: ic->f = rs == rb? instr(mr)
3652  : instr(or);
3653  rc_f = instr(or_dot); break;
3654  case PPC_31_ORC: ic->f = instr(orc);
3655  rc_f = instr(orc_dot); break;
3656  case PPC_31_XOR: ic->f = instr(xor);
3657  rc_f = instr(xor_dot); break;
3658  case PPC_31_EQV: ic->f = instr(eqv);
3659  rc_f = instr(eqv_dot); break;
3660  }
3661  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
3662  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3663  ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3664  if (rc)
3665  ic->f = rc_f;
3666  break;
3667 
3668  case PPC_31_MULLW:
3669  case PPC_31_MULHW:
3670  case PPC_31_MULHWU:
3671  case PPC_31_DIVW:
3672  case PPC_31_DIVWU:
3673  case PPC_31_ADD:
3674  case PPC_31_ADDC:
3675  case PPC_31_ADDE:
3676  case PPC_31_ADDME:
3677  case PPC_31_ADDZE:
3678  case PPC_31_SUBF:
3679  case PPC_31_SUBFC:
3680  case PPC_31_SUBFE:
3681  case PPC_31_SUBFME:
3682  case PPC_31_SUBFZE:
3683  rt = (iword >> 21) & 31;
3684  ra = (iword >> 16) & 31;
3685  rb = (iword >> 11) & 31;
3686  oe_bit = (iword >> 10) & 1;
3687  rc = iword & 1;
3688  if (oe_bit) {
3689  if (!cpu->translation_readahead)
3690  fatal("oe_bit not yet implemented\n");
3691  goto bad;
3692  }
3693  switch (xo) {
3694  case PPC_31_MULLW: ic->f = instr(mullw); break;
3695  case PPC_31_MULHW: ic->f = instr(mulhw); break;
3696  case PPC_31_MULHWU: ic->f = instr(mulhwu); break;
3697  case PPC_31_DIVW: ic->f = instr(divw); n64=1; break;
3698  case PPC_31_DIVWU: ic->f = instr(divwu); n64=1; break;
3699  case PPC_31_ADD: ic->f = instr(add); break;
3700  case PPC_31_ADDC: ic->f = instr(addc); n64=1; break;
3701  case PPC_31_ADDE: ic->f = instr(adde); n64=1; break;
3702  case PPC_31_ADDME: ic->f = instr(addme); n64=1; break;
3703  case PPC_31_ADDZE: ic->f = instr(addze); n64=1; break;
3704  case PPC_31_SUBF: ic->f = instr(subf); break;
3705  case PPC_31_SUBFC: ic->f = instr(subfc); break;
3706  case PPC_31_SUBFE: ic->f = instr(subfe); n64=1; break;
3707  case PPC_31_SUBFME: ic->f = instr(subfme); n64=1; break;
3708  case PPC_31_SUBFZE: ic->f = instr(subfze); n64=1;break;
3709  }
3710  if (rc) {
3711  switch (xo) {
3712  case PPC_31_ADD:
3713  ic->f = instr(add_dot); break;
3714  case PPC_31_ADDE:
3715  ic->f = instr(adde_dot); break;
3716  case PPC_31_ADDME:
3717  ic->f = instr(addme_dot); break;
3718  case PPC_31_ADDZE:
3719  ic->f = instr(addze_dot); break;
3720  case PPC_31_DIVW:
3721  ic->f = instr(divw_dot); break;
3722  case PPC_31_DIVWU:
3723  ic->f = instr(divwu_dot); break;
3724  case PPC_31_MULLW:
3725  ic->f = instr(mullw_dot); break;
3726  case PPC_31_MULHW:
3727  ic->f = instr(mulhw_dot); break;
3728  case PPC_31_MULHWU:
3729  ic->f = instr(mulhwu_dot); break;
3730  case PPC_31_SUBF:
3731  ic->f = instr(subf_dot); break;
3732  case PPC_31_SUBFC:
3733  ic->f = instr(subfc_dot); break;
3734  case PPC_31_SUBFE:
3735  ic->f = instr(subfe_dot); break;
3736  case PPC_31_SUBFME:
3737  ic->f = instr(subfme_dot); break;
3738  case PPC_31_SUBFZE:
3739  ic->f = instr(subfze_dot); break;
3740  default:if (!cpu->translation_readahead)
3741  fatal("RC bit not yet "
3742  "implemented\n");
3743  goto bad;
3744  }
3745  }
3746  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3747  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3748  ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);
3749  if (cpu->cd.ppc.bits == 64 && n64) {
3750  if (!cpu->translation_readahead)
3751  fatal("Not yet for 64-bit mode\n");
3752  goto bad;
3753  }
3754  break;
3755 
3756  case PPC_31_LVX:
3757  case PPC_31_LVXL:
3758  case PPC_31_STVX:
3759  case PPC_31_STVXL:
3760  load = 0;
3761  switch (xo) {
3762  case PPC_31_LVX:
3763  case PPC_31_LVXL:
3764  load = 1; break;
3765  }
3766  rs = (iword >> 21) & 31;
3767  ra = (iword >> 16) & 31;
3768  rb = (iword >> 11) & 31;
3769  ic->arg[0] = rs;
3770  if (ra == 0)
3771  ic->arg[1] = (size_t)(&cpu->cd.ppc.zero);
3772  else
3773  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3774  ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3775  ic->f = load? instr(lvx) : instr(stvx);
3776  break;
3777 
3778  default:goto bad;
3779  }
3780  break;
3781 
3782  case PPC_HI6_59:
3783  xo = (iword >> 1) & 1023;
3784  rt = (iword >> 21) & 31;
3785  ra = (iword >> 16) & 31;
3786  rb = (iword >> 11) & 31;
3787  rs = (iword >> 6) & 31; /* actually frc */
3788  rc = iword & 1;
3789 
3790  if (rc) {
3791  if (!cpu->translation_readahead)
3792  fatal("Floating point (59) "
3793  "with rc bit! TODO\n");
3794  goto bad;
3795  }
3796 
3797  /* NOTE: Some floating-point instructions are selected
3798  using only the lowest 5 bits, not all 10! */
3799  switch (xo & 31) {
3800  case PPC_59_FDIVS:
3801  case PPC_59_FSUBS:
3802  case PPC_59_FADDS:
3803  switch (xo & 31) {
3804  case PPC_59_FDIVS: ic->f = instr(fdivs); break;
3805  case PPC_59_FSUBS: ic->f = instr(fsubs); break;
3806  case PPC_59_FADDS: ic->f = instr(fadds); break;
3807  }
3808  ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[ra]);
3809  ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[rb]);
3810  ic->arg[2] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3811  break;
3812  case PPC_59_FMULS:
3813  ic->f = instr(fmuls);
3814  ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3815  ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[ra]);
3816  ic->arg[2] = (size_t)(&cpu->cd.ppc.fpr[rs]); /* frc */
3817  break;
3818  default:/* Use all 10 bits of xo: */
3819  switch (xo) {
3820  default:goto bad;
3821  }
3822  }
3823  break;
3824 
3825  case PPC_HI6_63:
3826  xo = (iword >> 1) & 1023;
3827  rt = (iword >> 21) & 31;
3828  ra = (iword >> 16) & 31;
3829  rb = (iword >> 11) & 31;
3830  rs = (iword >> 6) & 31; /* actually frc */
3831  rc = iword & 1;
3832 
3833  if (rc) {
3834  if (!cpu->translation_readahead)
3835  fatal("Floating point (63) "
3836  "with rc bit! TODO\n");
3837  goto bad;
3838  }
3839 
3840  /* NOTE: Some floating-point instructions are selected
3841  using only the lowest 5 bits, not all 10! */
3842  switch (xo & 31) {
3843  case PPC_63_FDIV:
3844  case PPC_63_FSUB:
3845  case PPC_63_FADD:
3846  switch (xo & 31) {
3847  case PPC_63_FDIV: ic->f = instr(fdiv); break;
3848  case PPC_63_FSUB: ic->f = instr(fsub); break;
3849  case PPC_63_FADD: ic->f = instr(fadd); break;
3850  }
3851  ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[ra]);
3852  ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[rb]);
3853  ic->arg[2] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3854  break;
3855  case PPC_63_FMUL:
3856  ic->f = instr(fmul);
3857  ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3858  ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[ra]);
3859  ic->arg[2] = (size_t)(&cpu->cd.ppc.fpr[rs]); /* frc */
3860  break;
3861  case PPC_63_FMSUB:
3862  case PPC_63_FMADD:
3863  switch (xo & 31) {
3864  case PPC_63_FMSUB: ic->f = instr(fmsub); break;
3865  case PPC_63_FMADD: ic->f = instr(fmadd); break;
3866  }
3867  ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3868  ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[ra]);
3869  ic->arg[2] = iword;
3870  break;
3871  default:/* Use all 10 bits of xo: */
3872  switch (xo) {
3873  case PPC_63_FCMPU:
3874  ic->f = instr(fcmpu);
3875  ic->arg[0] = 28 - 4*(rt >> 2);
3876  ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[ra]);
3877  ic->arg[2] = (size_t)(&cpu->cd.ppc.fpr[rb]);
3878  break;
3879  case PPC_63_FRSP:
3880  case PPC_63_FCTIWZ:
3881  case PPC_63_FNEG:
3882  case PPC_63_FABS:
3883  case PPC_63_FMR:
3884  switch (xo) {
3885  case PPC_63_FRSP: ic->f = instr(frsp); break;
3886  case PPC_63_FCTIWZ: ic->f = instr(fctiwz);break;
3887  case PPC_63_FNEG: ic->f = instr(fneg); break;
3888  case PPC_63_FABS: ic->f = instr(fabs); break;
3889  case PPC_63_FMR: ic->f = instr(fmr); break;
3890  }
3891  ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rb]);
3892  ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3893  break;
3894  case PPC_63_MFFS:
3895  ic->f = instr(mffs);
3896  ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3897  break;
3898  case PPC_63_MTFSF:
3899  ic->f = instr(mtfsf);
3900  ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rb]);
3901  ic->arg[1] = 0;
3902  for (bi=7; bi>=0; bi--) {
3903  ic->arg[1] <<= 8;
3904  if (iword & (1 << (17+bi)))
3905  ic->arg[1] |= 0xf;
3906  }
3907  break;
3908  default:goto bad;
3909  }
3910  }
3911  break;
3912 
3913  default:goto bad;
3914  }
3915 
3916 
3917 #define DYNTRANS_TO_BE_TRANSLATED_TAIL
3918 #include "cpu_dyntrans.cc"
3919 #undef DYNTRANS_TO_BE_TRANSLATED_TAIL
3920 }
3921 
#define IEEE_FMT_S
Definition: float_emul.h:43
#define PPC_31_ADDE
Definition: opcodes_ppc.h:109
void(* ppc_loadstore[64])(struct cpu *, struct ppc_instr_call *)
#define PPC_31_LBZX
Definition: opcodes_ppc.h:102
#define PPC_HI6_LHAU
Definition: opcodes_ppc.h:212
#define PPC_31_SUBFZE
Definition: opcodes_ppc.h:119
void fatal(const char *fmt,...)
Definition: main.cc:152
int emulated_hz
Definition: machine.h:165
#define PPC_HI6_19
Definition: opcodes_ppc.h:49
#define PPC_31_TLBIE
Definition: opcodes_ppc.h:135
#define PPC_HI6_XORI
Definition: opcodes_ppc.h:71
#define PPC_31_LWZUX
Definition: opcodes_ppc.h:95
#define PPC_31_LHAUX
Definition: opcodes_ppc.h:143
#define PPC_31_STHX
Definition: opcodes_ppc.h:144
#define PPC_HI6_LBZ
Definition: opcodes_ppc.h:203
#define SPR_TBL
Definition: ppc_spr.h:73
#define CACHE_DATA
Definition: memory.h:121
#define PPC_HI6_SC
Definition: opcodes_ppc.h:47
#define INVALIDATE_VADDR
Definition: cpu.h:480
#define PPC_31_STSWI
Definition: opcodes_ppc.h:178
uint64_t msr
Definition: cpu_ppc.h:130
#define MODE_uint_t
uint64_t spr[1024]
Definition: cpu_ppc.h:134
#define PPC_31_LFSX
Definition: opcodes_ppc.h:161
#define PPC_19_BCLR
Definition: opcodes_ppc.h:51
#define PPC_HI6_LWZ
Definition: opcodes_ppc.h:201
#define PPC_31_OR
Definition: opcodes_ppc.h:148
#define PPC_XER_SO
Definition: cpu_ppc.h:197
#define PPC_31_STWX
Definition: opcodes_ppc.h:114
#define INVALIDATE_ALL
Definition: cpu.h:478
#define PPC_31_STFDX
Definition: opcodes_ppc.h:179
page
void(* ppc_loadstore_indexed[32])(struct cpu *, struct ppc_instr_call *)
uint64_t vr_lo[PPC_NVRS]
Definition: cpu_ppc.h:128
#define PPC_31_SRAW
Definition: opcodes_ppc.h:185
void COMBINE() nop(struct cpu *cpu, struct mips_instr_call *ic, int low_addr)
struct arm_instr_call * ic
#define PPC_31_MTSR
Definition: opcodes_ppc.h:121
struct ppc_cpu ppc
Definition: cpu.h:444
#define PPC_31_SLW
Definition: opcodes_ppc.h:88
union cpu::@1 cd
#define PPC_19_CRAND
Definition: opcodes_ppc.h:60
#define BE32_TO_HOST(x)
Definition: misc.h:181
struct memory * mem
Definition: cpu.h:362
#define PPC_31_LHZUX
Definition: opcodes_ppc.h:136
#define PPC_30_RLDIMI
Definition: opcodes_ppc.h:78
#define PPC_HI6_ANDI_DOT
Definition: opcodes_ppc.h:73
#define PPC_31_MULHWU
Definition: opcodes_ppc.h:84
#define PPC_31_MFSR
Definition: opcodes_ppc.h:165
#define PPC_59_FMULS
Definition: opcodes_ppc.h:230
#define PPC_31_MTCRF
Definition: opcodes_ppc.h:110
#define PPC_31_LHAX
Definition: opcodes_ppc.h:139
#define PPC_HI6_CMPI
Definition: opcodes_ppc.h:41
#define PPC_19_CROR
Definition: opcodes_ppc.h:63
#define PPC_FPSCR_FPCC_SHIFT
Definition: cpu_ppc.h:182
struct machine * machine
Definition: cpu.h:328
#define PPC_31_ADDZE
Definition: opcodes_ppc.h:120
#define MEM_READ
Definition: memory.h:116
#define instr(n)
#define PPC_HI6_59
Definition: opcodes_ppc.h:226
#define PPC_31_NOR
Definition: opcodes_ppc.h:107
#define PPC_31_WRTEEI
Definition: opcodes_ppc.h:115
#define DYNTRANS_L2_64_TABLE
#define TBR_TBL
Definition: ppc_spr.h:500
#define PPC_19_MCRF
Definition: opcodes_ppc.h:50
#define PPC_31_TLBIA
Definition: opcodes_ppc.h:141
#define PPC_HI6_LHZU
Definition: opcodes_ppc.h:210
#define PPC_HI6_STMW
Definition: opcodes_ppc.h:216
#define PPC_31_CNTLZW
Definition: opcodes_ppc.h:89
void ieee_interpret_float_value(uint64_t x, struct ieee_float_value *fvp, int fmt)
Definition: float_emul.cc:49
#define PPC_31_SUBFME
Definition: opcodes_ppc.h:125
#define PPC_19_BCCTR
Definition: opcodes_ppc.h:64
uint64_t zero
Definition: cpu_ppc.h:120
#define PPC_FPSCR_FPCC
Definition: cpu_ppc.h:181
#define PPC_31_DCBZ
Definition: opcodes_ppc.h:200
#define PPC_HI6_ADDIS
Definition: opcodes_ppc.h:45
#define PPC_31_STWBRX
Definition: opcodes_ppc.h:174
#define PPC_63_FNEG
Definition: opcodes_ppc.h:244
#define PPC_XER_CA
Definition: cpu_ppc.h:199
#define reg(x)
#define SPR_SRR1
Definition: ppc_spr.h:57
#define PPC_63_FMSUB
Definition: opcodes_ppc.h:242
#define PPC_HI6_LD
Definition: opcodes_ppc.h:225
#define PPC_31_LVXL
Definition: opcodes_ppc.h:140
X(nop)
void COMBINE() ori(struct cpu *cpu, struct mips_instr_call *ic, int low_addr)
#define PPC_63_MFFS
Definition: opcodes_ppc.h:248
#define PPC_HI6_STWU
Definition: opcodes_ppc.h:206
#define PPC_31_DCBTST
Definition: opcodes_ppc.h:129
struct cpu ** cpus
Definition: machine.h:140
#define PPC_59_FDIVS
Definition: opcodes_ppc.h:227
#define SPR_CTR
Definition: ppc_spr.h:41
#define PPC_31_EXTSB
Definition: opcodes_ppc.h:192
void reg_access_msr(struct cpu *cpu, uint64_t *valuep, int writeflag, int check_for_interrupts)
Definition: cpu_ppc.cc:299
#define PPC_31_SRW
Definition: opcodes_ppc.h:162
#define PPC_31_MFCR
Definition: opcodes_ppc.h:85
#define PPC_HI6_STD
Definition: opcodes_ppc.h:233
#define PPC_HI6_B
Definition: opcodes_ppc.h:48
#define PPC_31_LSWI
Definition: opcodes_ppc.h:166
#define PPC_63_FADD
Definition: opcodes_ppc.h:240
int ncpus
Definition: machine.h:139
#define PPC_19_ISYNC
Definition: opcodes_ppc.h:57
#define PPC_31_AND
Definition: opcodes_ppc.h:91
#define PPC_HI6_STHU
Definition: opcodes_ppc.h:214
#define PPC_31_STHUX
Definition: opcodes_ppc.h:147
int debugger_n_steps_left_before_interaction
Definition: debugger.cc:73
#define PPC_31_MFTB
Definition: opcodes_ppc.h:142
int translation_readahead
Definition: cpu.h:424
#define PPC_31_NEG
Definition: opcodes_ppc.h:104
uint64_t pc
Definition: cpu.h:383
#define PPC_31_LVX
Definition: opcodes_ppc.h:103
#define PPC_30_RLDICL
Definition: opcodes_ppc.h:76
#define PPC_63_FSUB
Definition: opcodes_ppc.h:239
#define quick_pc_to_pointers(cpu)
uint32_t fpscr
Definition: cpu_ppc.h:123
#define PPC_31_MTMSRD
Definition: opcodes_ppc.h:116
#define PPC_HI6_CMPLI
Definition: opcodes_ppc.h:40
#define PPC_31_CMP
Definition: opcodes_ppc.h:80
#define PPC_31_MULHW
Definition: opcodes_ppc.h:98
#define PPC_31_MFSRIN
Definition: opcodes_ppc.h:173
#define PPC_HI6_SUBFIC
Definition: opcodes_ppc.h:38
#define PPC_HI6_STH
Definition: opcodes_ppc.h:213
#define SPR_LR
Definition: ppc_spr.h:40
#define PPC_31_LWBRX
Definition: opcodes_ppc.h:160
#define PPC_HI6_STFS
Definition: opcodes_ppc.h:221
#define PPC_HI6_STB
Definition: opcodes_ppc.h:207
uint64_t fpr[PPC_NFPRS]
Definition: cpu_ppc.h:125
#define DOT0(n)
#define PPC_63_MTFSF
Definition: opcodes_ppc.h:249
#define PPC_31_STWUX
Definition: opcodes_ppc.h:118
int(* memory_rw)(struct cpu *cpu, struct memory *mem, uint64_t vaddr, unsigned char *data, size_t len, int writeflag, int cache_flags)
Definition: cpu.h:365
#define PPC_31_LFDX
Definition: opcodes_ppc.h:168
#define DYNTRANS_L2N
#define PPC_31_MFMSR
Definition: opcodes_ppc.h:99
int bits
Definition: cpu_ppc.h:116
#define PPC_HI6_MULLI
Definition: opcodes_ppc.h:37
#define PPC_31_SLD
Definition: opcodes_ppc.h:90
#define PPC_19_CRNOR
Definition: opcodes_ppc.h:53
u_short data
Definition: siireg.h:79
#define PPC_31_TLBSYNC
Definition: opcodes_ppc.h:164
#define PPC_19_CRANDC
Definition: opcodes_ppc.h:56
#define MODE_POWER
Definition: cpu_ppc.h:40
#define PPC_HI6_RLWINM
Definition: opcodes_ppc.h:66
#define SPR_SRR0
Definition: ppc_spr.h:56
#define PPC_31_DSSALL
Definition: opcodes_ppc.h:186
#define SPR_PMC1
Definition: ppc_spr.h:270
#define PPC_30_RLDICR
Definition: opcodes_ppc.h:77
#define DOT1(n)
#define PPC_31_LDARX
Definition: opcodes_ppc.h:100
#define PPC_HI6_STFD
Definition: opcodes_ppc.h:223
#define PPC_HI6_ADDI
Definition: opcodes_ppc.h:44
#define PPC_31_DIVWU
Definition: opcodes_ppc.h:150
#define PPC_63_FRSP
Definition: opcodes_ppc.h:236
uint8_t running
Definition: cpu.h:353
#define PPC_HI6_ORI
Definition: opcodes_ppc.h:69
#define MEMORY_ACCESS_OK
Definition: memory.h:141
#define PPC_31_DCBF
Definition: opcodes_ppc.h:101
#define MEM_WRITE
Definition: memory.h:117
int mode
Definition: cpu_ppc.h:115
#define PPC_31_LWARX
Definition: opcodes_ppc.h:86
#define PPC_31_DIVW
Definition: opcodes_ppc.h:155
#define PPC_63_FABS
Definition: opcodes_ppc.h:247
#define PPC_HI6_LWZU
Definition: opcodes_ppc.h:202
#define DOT2(n)
uint32_t sr[16]
Definition: cpu_ppc.h:133
int of_emul(struct cpu *cpu)
Definition: of.cc:1078
#define SPR_XER
Definition: ppc_spr.h:37
#define PPC_HI6_LFS
Definition: opcodes_ppc.h:217
#define PPC_HI6_31
Definition: opcodes_ppc.h:79
int ll_bit
Definition: cpu_ppc.h:137
uint64_t vr_hi[PPC_NVRS]
Definition: cpu_ppc.h:127
#define PPC_31_NAND
Definition: opcodes_ppc.h:153
#define PPC_63_FDIV
Definition: opcodes_ppc.h:238
#define PPC_31_STFSX
Definition: opcodes_ppc.h:175
#define PPC_31_EIEIO
Definition: opcodes_ppc.h:188
#define PPC_HI6_ADDIC_DOT
Definition: opcodes_ppc.h:43
void cpu_functioncall_trace(struct cpu *cpu, uint64_t f)
Definition: cpu.cc:219
#define PPC_IC_ENTRIES_PER_PAGE
Definition: cpu_ppc.h:95
#define PPC_HI6_LMW
Definition: opcodes_ppc.h:215
uint32_t addr
#define PPC_31_STHBRX
Definition: opcodes_ppc.h:190
#define PPC_63_FMR
Definition: opcodes_ppc.h:245
#define PPC_31_ADD
Definition: opcodes_ppc.h:131
void cpu_functioncall_trace_return(struct cpu *cpu)
Definition: cpu.cc:275
#define PPC_31_SYNC
Definition: opcodes_ppc.h:167
void ppc_exception(struct cpu *cpu, int exception_nr)
Definition: cpu_ppc.cc:352
#define PPC_31_TLBLI
Definition: opcodes_ppc.h:199
#define PPC_31_MTSPR
Definition: opcodes_ppc.h:151
#define PPC_31_CMPL
Definition: opcodes_ppc.h:92
Definition: cpu.h:326
#define PPC_31_SUBFE
Definition: opcodes_ppc.h:108
#define PPC_19_CRORC
Definition: opcodes_ppc.h:62
#define PPC_63_FMUL
Definition: opcodes_ppc.h:241
#define DYNTRANS_L1N
Definition: cpu.h:222
#define PPC_MSR_SF
Definition: cpu_ppc.h:152
#define PPC_MSR_FP
Definition: cpu_ppc.h:161
#define PPC_19_CREQV
Definition: opcodes_ppc.h:61
#define PPC_63_FCTIWZ
Definition: opcodes_ppc.h:237
int n_translated_instrs
Definition: cpu.h:427
#define CACHE_INSTRUCTION
Definition: memory.h:122
#define PPC_31_MTMSR
Definition: opcodes_ppc.h:111
#define PPC_31_ADDC
Definition: opcodes_ppc.h:83
void load(FILE *fh, unsigned char *ptr, unsigned long sz)
#define PPC_31_DCBST
Definition: opcodes_ppc.h:94
uint64_t ieee_store_float_value(double nf, int fmt, int nan)
Definition: float_emul.cc:185
uint32_t cr
Definition: cpu_ppc.h:122
#define PPC_31_SUBFC
Definition: opcodes_ppc.h:82
#define PPC_31_LHZX
Definition: opcodes_ppc.h:133
#define PPC_HI6_ANDIS_DOT
Definition: opcodes_ppc.h:74
#define DYNTRANS_L3N
#define SPR_TBU
Definition: ppc_spr.h:74
#define PPC_31_LBZUX
Definition: opcodes_ppc.h:106
#define PPC_31_EQV
Definition: opcodes_ppc.h:134
#define PPC_31_STDUX
Definition: opcodes_ppc.h:117
#define PPC_INSTR_ALIGNMENT_SHIFT
Definition: cpu_ppc.h:93
#define PPC_31_SRAWI
Definition: opcodes_ppc.h:187
#define PPC_HI6_LHA
Definition: opcodes_ppc.h:211
#define PPC_EXCEPTION_FPU
Definition: cpu_ppc.h:192
#define PPC_31_ADDME
Definition: opcodes_ppc.h:126
#define PPC_31_SUBF
Definition: opcodes_ppc.h:93
#define PPC_31_MFSPR
Definition: opcodes_ppc.h:138
#define PPC_HI6_STBU
Definition: opcodes_ppc.h:208
#define PPC_31_DCBT
Definition: opcodes_ppc.h:132
#define PPC_HI6_BC
Definition: opcodes_ppc.h:46
#define PPC_63_FMADD
Definition: opcodes_ppc.h:243
#define PPC_31_TLBLD
Definition: opcodes_ppc.h:195
uint8_t byte_order
Definition: cpu.h:347
#define PPC_31_LHBRX
Definition: opcodes_ppc.h:184
#define PPC_31_STDCX_DOT
Definition: opcodes_ppc.h:122
#define PPC_HI6_LBZU
Definition: opcodes_ppc.h:204
#define PPC_31_STBX
Definition: opcodes_ppc.h:123
#define CHECK_FOR_FPU_EXCEPTION
#define PPC_31_ICBI
Definition: opcodes_ppc.h:196
#define PPC_HI6_LFD
Definition: opcodes_ppc.h:219
void update_cr0(struct cpu *cpu, uint64_t value)
Definition: cpu_ppc.cc:1833
#define PPC_FPSCR_VXNAN
Definition: cpu_ppc.h:179
addr & if(addr >=0x24 &&page !=NULL)
#define PPC_31_MTSRIN
Definition: opcodes_ppc.h:128
#define PPC_31_STVX
Definition: opcodes_ppc.h:124
#define PPC_HI6_63
Definition: opcodes_ppc.h:234
#define PPC_31_XOR
Definition: opcodes_ppc.h:137
#define PPC_HI6_STW
Definition: opcodes_ppc.h:205
#define PPC_59_FSUBS
Definition: opcodes_ppc.h:228
#define PPC_31_EXTSH
Definition: opcodes_ppc.h:191
#define PPC_HI6_30
Definition: opcodes_ppc.h:75
#define PPC_HI6_RLWNM
Definition: opcodes_ppc.h:68
#define PPC_19_RFI
Definition: opcodes_ppc.h:54
#define PPC_31_MULLW
Definition: opcodes_ppc.h:127
#define IEEE_FMT_D
Definition: float_emul.h:44
#define PPC_31_ORC
Definition: opcodes_ppc.h:145
#define PPC_31_STVXL
Definition: opcodes_ppc.h:154
#define PPC_HI6_ORIS
Definition: opcodes_ppc.h:70
#define TBR_TBU
Definition: ppc_spr.h:501
#define PPC_HI6_ADDIC
Definition: opcodes_ppc.h:42
#define PPC_EXCEPTION_SC
Definition: cpu_ppc.h:194
#define PPC_31_EXTSW
Definition: opcodes_ppc.h:197
#define PPC_19_RFID
Definition: opcodes_ppc.h:52
#define PPC_31_STBUX
Definition: opcodes_ppc.h:130
#define PPC_31_LWZX
Definition: opcodes_ppc.h:87
#define SPR_SPRG2
Definition: ppc_spr.h:65
#define DYNTRANS_L3_64_TABLE
#define PPC_63_FCMPU
Definition: opcodes_ppc.h:235
#define PPC_31_TLBSX_DOT
Definition: opcodes_ppc.h:189
#define PPC_HI6_XORIS
Definition: opcodes_ppc.h:72
#define PPC_31_ANDC
Definition: opcodes_ppc.h:96
#define PPC_31_STWCX_DOT
Definition: opcodes_ppc.h:113
int show_trace_tree
Definition: machine.h:164
#define PPC_HI6_LHZ
Definition: opcodes_ppc.h:209
uint64_t ll_addr
Definition: cpu_ppc.h:136
#define PPC_59_FADDS
Definition: opcodes_ppc.h:229
uint64_t gpr[PPC_NGPRS]
Definition: cpu_ppc.h:124
#define PPC_19_CRXOR
Definition: opcodes_ppc.h:58
struct ppc_cpu_type_def cpu_type
Definition: cpu_ppc.h:111
#define PPC_HI6_RLWIMI
Definition: opcodes_ppc.h:65
#define INVALIDATE_VADDR_UPPER4
Definition: cpu.h:481
void(* invalidate_translation_caches)(struct cpu *, uint64_t paddr, int flags)
Definition: cpu.h:374
#define EMUL_BIG_ENDIAN
Definition: misc.h:165
#define PPC_31_STDX
Definition: opcodes_ppc.h:112

Generated on Sun Sep 30 2018 16:05:18 for GXemul by doxygen 1.8.13