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-2018 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]) = ieee_store_float_value(fl, IEEE_FMT_D);
990 }
991 
992 
993 /*
994  * fctiwz: Floating-point Convert to Integer Word, Round to Zero
995  *
996  * arg[0] = ptr to frb
997  * arg[1] = ptr to frt
998  */
999 X(fctiwz)
1000 {
1001  struct ieee_float_value frb;
1002  uint32_t res = 0;
1003 
1005 
1006  ieee_interpret_float_value(*(uint64_t *)ic->arg[0], &frb, IEEE_FMT_D);
1007  if (!frb.nan) {
1008  if (frb.f >= 2147483647.0)
1009  res = 0x7fffffff;
1010  else if (frb.f <= -2147483648.0)
1011  res = 0x80000000;
1012  else
1013  res = (int32_t) frb.f;
1014  }
1015 
1016  *(uint64_t *)ic->arg[1] = (uint32_t)res;
1017 }
1018 
1019 
1020 /*
1021  * fmul: Floating-point Multiply
1022  *
1023  * arg[0] = ptr to frt
1024  * arg[1] = ptr to fra
1025  * arg[2] = ptr to frc
1026  */
1027 X(fmul)
1028 {
1029  struct ieee_float_value fra;
1030  struct ieee_float_value frc;
1031  double result = 0.0;
1032  int c;
1033 
1035 
1036  ieee_interpret_float_value(*(uint64_t *)ic->arg[1], &fra, IEEE_FMT_D);
1037  ieee_interpret_float_value(*(uint64_t *)ic->arg[2], &frc, IEEE_FMT_D);
1038  result = fra.f * frc.f;
1039  if (isnan(result))
1040  c = 1;
1041  else {
1042  if (result < 0.0)
1043  c = 8;
1044  else if (result > 0.0)
1045  c = 4;
1046  else
1047  c = 2;
1048  }
1049  /* TODO: Signaling vs Quiet NaN */
1051  cpu->cd.ppc.fpscr |= (c << PPC_FPSCR_FPCC_SHIFT);
1052 
1053  (*(uint64_t *)ic->arg[0]) =
1055 }
1056 X(fmuls)
1057 {
1058  /* TODO */
1059  instr(fmul)(cpu, ic);
1060 }
1061 
1062 
1063 /*
1064  * fmadd: Floating-point Multiply and Add
1065  *
1066  * arg[0] = ptr to frt
1067  * arg[1] = ptr to fra
1068  * arg[2] = copy of the instruction word
1069  */
1070 X(fmadd)
1071 {
1072  uint32_t iw = ic->arg[2];
1073  int b = (iw >> 11) & 31, c = (iw >> 6) & 31;
1074  struct ieee_float_value fra;
1075  struct ieee_float_value frb;
1076  struct ieee_float_value frc;
1077  double result = 0.0;
1078  int cc;
1079 
1081 
1082  ieee_interpret_float_value(*(uint64_t *)ic->arg[1], &fra, IEEE_FMT_D);
1085  result = fra.f * frc.f + frb.f;
1086  if (isnan(result))
1087  cc = 1;
1088  else {
1089  if (result < 0.0)
1090  cc = 8;
1091  else if (result > 0.0)
1092  cc = 4;
1093  else
1094  cc = 2;
1095  }
1096  /* TODO: Signaling vs Quiet NaN */
1098  cpu->cd.ppc.fpscr |= (cc << PPC_FPSCR_FPCC_SHIFT);
1099 
1100  (*(uint64_t *)ic->arg[0]) =
1102 }
1103 
1104 
1105 /*
1106  * fmsub: Floating-point Multiply and Sub
1107  *
1108  * arg[0] = ptr to frt
1109  * arg[1] = ptr to fra
1110  * arg[2] = copy of the instruction word
1111  */
1112 X(fmsub)
1113 {
1114  uint32_t iw = ic->arg[2];
1115  int b = (iw >> 11) & 31, c = (iw >> 6) & 31;
1116  struct ieee_float_value fra;
1117  struct ieee_float_value frb;
1118  struct ieee_float_value frc;
1119  double result = 0.0;
1120  int cc;
1121 
1123 
1124  ieee_interpret_float_value(*(uint64_t *)ic->arg[1], &fra, IEEE_FMT_D);
1127  result = fra.f * frc.f - frb.f;
1128  if (isnan(result))
1129  cc = 1;
1130  else {
1131  if (result < 0.0)
1132  cc = 8;
1133  else if (result > 0.0)
1134  cc = 4;
1135  else
1136  cc = 2;
1137  }
1138  /* TODO: Signaling vs Quiet NaN */
1140  cpu->cd.ppc.fpscr |= (cc << PPC_FPSCR_FPCC_SHIFT);
1141 
1142  (*(uint64_t *)ic->arg[0]) =
1144 }
1145 
1146 
1147 /*
1148  * fadd, fsub, fdiv: Various Floating-point operationgs
1149  *
1150  * arg[0] = ptr to fra
1151  * arg[1] = ptr to frb
1152  * arg[2] = ptr to frt
1153  */
1154 X(fadd)
1155 {
1156  struct ieee_float_value fra;
1157  struct ieee_float_value frb;
1158  double result = 0.0;
1159  int c;
1160 
1162 
1163  ieee_interpret_float_value(*(uint64_t *)ic->arg[0], &fra, IEEE_FMT_D);
1164  ieee_interpret_float_value(*(uint64_t *)ic->arg[1], &frb, IEEE_FMT_D);
1165  result = fra.f + frb.f;
1166  if (isnan(result))
1167  c = 1;
1168  else {
1169  if (result < 0.0)
1170  c = 8;
1171  else if (result > 0.0)
1172  c = 4;
1173  else
1174  c = 2;
1175  }
1176  /* TODO: Signaling vs Quiet NaN */
1178  cpu->cd.ppc.fpscr |= (c << PPC_FPSCR_FPCC_SHIFT);
1179 
1180  (*(uint64_t *)ic->arg[2]) =
1182 }
1183 X(fadds)
1184 {
1185  /* TODO */
1186  instr(fadd)(cpu, ic);
1187 }
1188 X(fsub)
1189 {
1190  struct ieee_float_value fra;
1191  struct ieee_float_value frb;
1192  double result = 0.0;
1193  int c;
1194 
1196 
1197  ieee_interpret_float_value(*(uint64_t *)ic->arg[0], &fra, IEEE_FMT_D);
1198  ieee_interpret_float_value(*(uint64_t *)ic->arg[1], &frb, IEEE_FMT_D);
1199  result = fra.f - frb.f;
1200  if (isnan(result))
1201  c = 1;
1202  else {
1203  if (result < 0.0)
1204  c = 8;
1205  else if (result > 0.0)
1206  c = 4;
1207  else
1208  c = 2;
1209  }
1210  /* TODO: Signaling vs Quiet NaN */
1212  cpu->cd.ppc.fpscr |= (c << PPC_FPSCR_FPCC_SHIFT);
1213 
1214  (*(uint64_t *)ic->arg[2]) =
1216 }
1217 X(fsubs)
1218 {
1219  /* TODO */
1220  instr(fsub)(cpu, ic);
1221 }
1222 X(fdiv)
1223 {
1224  struct ieee_float_value fra;
1225  struct ieee_float_value frb;
1226  double result = 0.0;
1227  int c;
1228 
1230 
1231  ieee_interpret_float_value(*(uint64_t *)ic->arg[0], &fra, IEEE_FMT_D);
1232  ieee_interpret_float_value(*(uint64_t *)ic->arg[1], &frb, IEEE_FMT_D);
1233  result = fra.f / frb.f;
1234  if (isnan(result))
1235  c = 1;
1236  else {
1237  if (result < 0.0)
1238  c = 8;
1239  else if (result > 0.0)
1240  c = 4;
1241  else
1242  c = 2;
1243  }
1244  /* TODO: Signaling vs Quiet NaN */
1246  cpu->cd.ppc.fpscr |= (c << PPC_FPSCR_FPCC_SHIFT);
1247 
1248  (*(uint64_t *)ic->arg[2]) =
1250 }
1251 X(fdivs)
1252 {
1253  /* TODO */
1254  instr(fdiv)(cpu, ic);
1255 }
1256 
1257 
1258 /*
1259  * llsc: Load-linked and store conditional
1260  *
1261  * arg[0] = copy of the instruction word.
1262  */
1263 X(llsc)
1264 {
1265  int iw = ic->arg[0], len = 4, load = 0, xo = (iw >> 1) & 1023;
1266  int i, rc = iw & 1, rt, ra, rb;
1267  uint64_t addr = 0, value;
1268  unsigned char d[8];
1269 
1270  switch (xo) {
1271  case PPC_31_LDARX:
1272  len = 8;
1273  case PPC_31_LWARX:
1274  load = 1;
1275  break;
1276  case PPC_31_STDCX_DOT:
1277  len = 8;
1278  case PPC_31_STWCX_DOT:
1279  break;
1280  }
1281 
1282  rt = (iw >> 21) & 31;
1283  ra = (iw >> 16) & 31;
1284  rb = (iw >> 11) & 31;
1285 
1286  if (ra != 0)
1287  addr = cpu->cd.ppc.gpr[ra];
1288  addr += cpu->cd.ppc.gpr[rb];
1289 
1290  if (load) {
1291  if (rc) {
1292  fatal("ll: rc-bit set?\n");
1293  exit(1);
1294  }
1295  if (cpu->memory_rw(cpu, cpu->mem, addr, d, len,
1297  fatal("ll: error: TODO\n");
1298  exit(1);
1299  }
1300 
1301  value = 0;
1302  for (i=0; i<len; i++) {
1303  value <<= 8;
1304  if (cpu->byte_order == EMUL_BIG_ENDIAN)
1305  value |= d[i];
1306  else
1307  value |= d[len - 1 - i];
1308  }
1309 
1310  cpu->cd.ppc.gpr[rt] = value;
1311  cpu->cd.ppc.ll_addr = addr;
1312  cpu->cd.ppc.ll_bit = 1;
1313  } else {
1314  uint32_t old_so = cpu->cd.ppc.spr[SPR_XER] & PPC_XER_SO;
1315  if (!rc) {
1316  fatal("sc: rc-bit not set?\n");
1317  exit(1);
1318  }
1319 
1320  value = cpu->cd.ppc.gpr[rt];
1321 
1322  /* "If the store is performed, bits 0-2 of Condition
1323  Register Field 0 are set to 0b001, otherwise, they are
1324  set to 0b000. The SO bit of the XER is copied to to bit
1325  4 of Condition Register Field 0. */
1326  if (!cpu->cd.ppc.ll_bit || cpu->cd.ppc.ll_addr != addr) {
1327  cpu->cd.ppc.cr &= 0x0fffffff;
1328  if (old_so)
1329  cpu->cd.ppc.cr |= 0x10000000;
1330  cpu->cd.ppc.ll_bit = 0;
1331  return;
1332  }
1333 
1334  for (i=0; i<len; i++) {
1335  if (cpu->byte_order == EMUL_BIG_ENDIAN)
1336  d[len - 1 - i] = value >> (8*i);
1337  else
1338  d[i] = value >> (8*i);
1339  }
1340 
1341  if (cpu->memory_rw(cpu, cpu->mem, addr, d, len,
1343  fatal("sc: error: TODO\n");
1344  exit(1);
1345  }
1346 
1347  cpu->cd.ppc.cr &= 0x0fffffff;
1348  cpu->cd.ppc.cr |= 0x20000000; /* success! */
1349  if (old_so)
1350  cpu->cd.ppc.cr |= 0x10000000;
1351 
1352  /* Clear _all_ CPUs' ll_bits: */
1353  for (i=0; i<cpu->machine->ncpus; i++)
1354  cpu->machine->cpus[i]->cd.ppc.ll_bit = 0;
1355  }
1356 }
1357 
1358 
1359 /*
1360  * mtsr, mtsrin: Move To Segment Register [Indirect]
1361  *
1362  * arg[0] = sr number, or for indirect mode: ptr to rb
1363  * arg[1] = ptr to rt
1364  *
1365  * TODO: These only work for 32-bit mode!
1366  */
1367 X(mtsr)
1368 {
1369  int sr_num = ic->arg[0];
1370  uint32_t old = cpu->cd.ppc.sr[sr_num];
1371  cpu->cd.ppc.sr[sr_num] = reg(ic->arg[1]);
1372 
1373  if (cpu->cd.ppc.sr[sr_num] != old)
1374  cpu->invalidate_translation_caches(cpu, ic->arg[0] << 28,
1376 }
1377 X(mtsrin)
1378 {
1379  int sr_num = reg(ic->arg[0]) >> 28;
1380  uint32_t old = cpu->cd.ppc.sr[sr_num];
1381  cpu->cd.ppc.sr[sr_num] = reg(ic->arg[1]);
1382 
1383  if (cpu->cd.ppc.sr[sr_num] != old)
1384  cpu->invalidate_translation_caches(cpu, sr_num << 28,
1386 }
1387 
1388 
1389 /*
1390  * mfsrin, mtsrin: Move From/To Segment Register Indirect
1391  *
1392  * arg[0] = sr number, or for indirect mode: ptr to rb
1393  * arg[1] = ptr to rt
1394  */
1395 X(mfsr)
1396 {
1397  /* TODO: This only works for 32-bit mode */
1398  reg(ic->arg[1]) = cpu->cd.ppc.sr[ic->arg[0]];
1399 }
1400 X(mfsrin)
1401 {
1402  /* TODO: This only works for 32-bit mode */
1403  uint32_t sr_num = reg(ic->arg[0]) >> 28;
1404  reg(ic->arg[1]) = cpu->cd.ppc.sr[sr_num];
1405 }
1406 
1407 
1408 /*
1409  * rldicl:
1410  *
1411  * arg[0] = copy of the instruction word
1412  */
1413 X(rldicl)
1414 {
1415  int rs = (ic->arg[0] >> 21) & 31;
1416  int ra = (ic->arg[0] >> 16) & 31;
1417  int sh = ((ic->arg[0] >> 11) & 31) | ((ic->arg[0] & 2) << 4);
1418  int mb = ((ic->arg[0] >> 6) & 31) | (ic->arg[0] & 0x20);
1419  int rc = ic->arg[0] & 1;
1420  uint64_t tmp = cpu->cd.ppc.gpr[rs], tmp2;
1421  /* TODO: Fix this, its performance is awful: */
1422  while (sh-- != 0) {
1423  int b = (tmp >> 63) & 1;
1424  tmp = (tmp << 1) | b;
1425  }
1426  tmp2 = 0;
1427  while (mb <= 63) {
1428  tmp |= ((uint64_t)1 << (63-mb));
1429  mb ++;
1430  }
1431  cpu->cd.ppc.gpr[ra] = tmp & tmp2;
1432  if (rc)
1433  update_cr0(cpu, cpu->cd.ppc.gpr[ra]);
1434 }
1435 
1436 
1437 /*
1438  * rldicr:
1439  *
1440  * arg[0] = copy of the instruction word
1441  */
1442 X(rldicr)
1443 {
1444  int rs = (ic->arg[0] >> 21) & 31;
1445  int ra = (ic->arg[0] >> 16) & 31;
1446  int sh = ((ic->arg[0] >> 11) & 31) | ((ic->arg[0] & 2) << 4);
1447  int me = ((ic->arg[0] >> 6) & 31) | (ic->arg[0] & 0x20);
1448  int rc = ic->arg[0] & 1;
1449  uint64_t tmp = cpu->cd.ppc.gpr[rs];
1450  /* TODO: Fix this, its performance is awful: */
1451  while (sh-- != 0) {
1452  int b = (tmp >> 63) & 1;
1453  tmp = (tmp << 1) | b;
1454  }
1455  while (me++ < 63)
1456  tmp &= ~((uint64_t)1 << (63-me));
1457  cpu->cd.ppc.gpr[ra] = tmp;
1458  if (rc)
1459  update_cr0(cpu, tmp);
1460 }
1461 
1462 
1463 /*
1464  * rldimi:
1465  *
1466  * arg[0] = copy of the instruction word
1467  */
1468 X(rldimi)
1469 {
1470  uint32_t iw = ic->arg[0];
1471  int rs = (iw >> 21) & 31, ra = (iw >> 16) & 31;
1472  int sh = ((iw >> 11) & 31) | ((iw & 2) << 4);
1473  int mb = ((iw >> 6) & 31) | (iw & 0x20);
1474  int rc = ic->arg[0] & 1;
1475  int m;
1476  uint64_t tmp, s = cpu->cd.ppc.gpr[rs];
1477  /* TODO: Fix this, its performance is awful: */
1478  while (sh-- != 0) {
1479  int b = (s >> 63) & 1;
1480  s = (s << 1) | b;
1481  }
1482  m = mb; tmp = 0;
1483  do {
1484  tmp |= ((uint64_t)1 << (63-m));
1485  m ++;
1486  } while (m != 63 - sh);
1487  cpu->cd.ppc.gpr[ra] &= ~tmp;
1488  cpu->cd.ppc.gpr[ra] |= (tmp & s);
1489  if (rc)
1490  update_cr0(cpu, cpu->cd.ppc.gpr[ra]);
1491 }
1492 
1493 
1494 /*
1495  * rlwnm:
1496  *
1497  * arg[0] = ptr to ra
1498  * arg[1] = mask
1499  * arg[2] = copy of the instruction word
1500  */
1501 X(rlwnm)
1502 {
1503  uint32_t tmp, iword = ic->arg[2];
1504  int rs = (iword >> 21) & 31;
1505  int rb = (iword >> 11) & 31;
1506  int sh = cpu->cd.ppc.gpr[rb] & 0x1f;
1507  tmp = (uint32_t)cpu->cd.ppc.gpr[rs];
1508  tmp = (tmp << sh) | (tmp >> (32-sh));
1509  tmp &= (uint32_t)ic->arg[1];
1510  reg(ic->arg[0]) = tmp;
1511 }
1512 DOT0(rlwnm)
1513 
1514 
1515 /*
1516  * rlwinm:
1517  *
1518  * arg[0] = ptr to ra
1519  * arg[1] = mask
1520  * arg[2] = copy of the instruction word
1521  */
1522 X(rlwinm)
1523 {
1524  uint32_t tmp, iword = ic->arg[2];
1525  int rs = (iword >> 21) & 31;
1526  int sh = (iword >> 11) & 31;
1527  tmp = (uint32_t)cpu->cd.ppc.gpr[rs];
1528  tmp = (tmp << sh) | (tmp >> (32-sh));
1529  tmp &= (uint32_t)ic->arg[1];
1530  reg(ic->arg[0]) = tmp;
1531 }
1532 DOT0(rlwinm)
1533 
1534 
1535 /*
1536  * rlwimi:
1537  *
1538  * arg[0] = ptr to rs
1539  * arg[1] = ptr to ra
1540  * arg[2] = copy of the instruction word
1541  */
1542 X(rlwimi)
1543 {
1544  MODE_uint_t tmp = reg(ic->arg[0]), ra = reg(ic->arg[1]);
1545  uint32_t iword = ic->arg[2];
1546  int sh = (iword >> 11) & 31;
1547  int mb = (iword >> 6) & 31;
1548  int me = (iword >> 1) & 31;
1549  int rc = iword & 1;
1550 
1551  tmp = (tmp << sh) | (tmp >> (32-sh));
1552 
1553  for (;;) {
1554  uint64_t mask;
1555  mask = (uint64_t)1 << (31-mb);
1556  ra &= ~mask;
1557  ra |= (tmp & mask);
1558  if (mb == me)
1559  break;
1560  mb ++;
1561  if (mb == 32)
1562  mb = 0;
1563  }
1564  reg(ic->arg[1]) = ra;
1565  if (rc)
1566  update_cr0(cpu, ra);
1567 }
1568 
1569 
1570 /*
1571  * srawi:
1572  *
1573  * arg[0] = ptr to rs
1574  * arg[1] = ptr to ra
1575  * arg[2] = sh (shift amount)
1576  */
1577 X(srawi)
1578 {
1579  uint32_t tmp = reg(ic->arg[0]);
1580  int i = 0, j = 0, sh = ic->arg[2];
1581 
1582  cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
1583  if (tmp & 0x80000000)
1584  i = 1;
1585  while (sh-- > 0) {
1586  if (tmp & 1)
1587  j ++;
1588  tmp >>= 1;
1589  if (tmp & 0x40000000)
1590  tmp |= 0x80000000;
1591  }
1592  if (i && j>0)
1593  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
1594  reg(ic->arg[1]) = (int64_t)(int32_t)tmp;
1595 }
1596 DOT1(srawi)
1597 
1598 
1599 /*
1600  * mcrf: Move inside condition register
1601  *
1602  * arg[0] = 28-4*bf, arg[1] = 28-4*bfa
1603  */
1604 X(mcrf)
1605 {
1606  int bf_shift = ic->arg[0], bfa_shift = ic->arg[1];
1607  uint32_t tmp = (cpu->cd.ppc.cr >> bfa_shift) & 0xf;
1608  cpu->cd.ppc.cr &= ~(0xf << bf_shift);
1609  cpu->cd.ppc.cr |= (tmp << bf_shift);
1610 }
1611 
1612 
1613 /*
1614  * crand, crxor etc: Condition Register operations
1615  *
1616  * arg[0] = copy of the instruction word
1617  */
1618 X(crand) {
1619  uint32_t iword = ic->arg[0]; int bt = (iword >> 21) & 31;
1620  int ba = (iword >> 16) & 31, bb = (iword >> 11) & 31;
1621  ba = (cpu->cd.ppc.cr >> (31-ba)) & 1;
1622  bb = (cpu->cd.ppc.cr >> (31-bb)) & 1;
1623  cpu->cd.ppc.cr &= ~(1 << (31-bt));
1624  if (ba & bb)
1625  cpu->cd.ppc.cr |= (1 << (31-bt));
1626 }
1627 X(crandc) {
1628  uint32_t iword = ic->arg[0]; int bt = (iword >> 21) & 31;
1629  int ba = (iword >> 16) & 31, bb = (iword >> 11) & 31;
1630  ba = (cpu->cd.ppc.cr >> (31-ba)) & 1;
1631  bb = (cpu->cd.ppc.cr >> (31-bb)) & 1;
1632  cpu->cd.ppc.cr &= ~(1 << (31-bt));
1633  if (!(ba & bb))
1634  cpu->cd.ppc.cr |= (1 << (31-bt));
1635 }
1636 X(creqv) {
1637  uint32_t iword = ic->arg[0]; int bt = (iword >> 21) & 31;
1638  int ba = (iword >> 16) & 31, bb = (iword >> 11) & 31;
1639  ba = (cpu->cd.ppc.cr >> (31-ba)) & 1;
1640  bb = (cpu->cd.ppc.cr >> (31-bb)) & 1;
1641  cpu->cd.ppc.cr &= ~(1 << (31-bt));
1642  if (!(ba ^ bb))
1643  cpu->cd.ppc.cr |= (1 << (31-bt));
1644 }
1645 X(cror) {
1646  uint32_t iword = ic->arg[0]; int bt = (iword >> 21) & 31;
1647  int ba = (iword >> 16) & 31, bb = (iword >> 11) & 31;
1648  ba = (cpu->cd.ppc.cr >> (31-ba)) & 1;
1649  bb = (cpu->cd.ppc.cr >> (31-bb)) & 1;
1650  cpu->cd.ppc.cr &= ~(1 << (31-bt));
1651  if (ba | bb)
1652  cpu->cd.ppc.cr |= (1 << (31-bt));
1653 }
1654 X(crorc) {
1655  uint32_t iword = ic->arg[0]; int bt = (iword >> 21) & 31;
1656  int ba = (iword >> 16) & 31, bb = (iword >> 11) & 31;
1657  ba = (cpu->cd.ppc.cr >> (31-ba)) & 1;
1658  bb = (cpu->cd.ppc.cr >> (31-bb)) & 1;
1659  cpu->cd.ppc.cr &= ~(1 << (31-bt));
1660  if (!(ba | bb))
1661  cpu->cd.ppc.cr |= (1 << (31-bt));
1662 }
1663 X(crnor) {
1664  uint32_t iword = ic->arg[0]; int bt = (iword >> 21) & 31;
1665  int ba = (iword >> 16) & 31, bb = (iword >> 11) & 31;
1666  ba = (cpu->cd.ppc.cr >> (31-ba)) & 1;
1667  bb = (cpu->cd.ppc.cr >> (31-bb)) & 1;
1668  cpu->cd.ppc.cr &= ~(1 << (31-bt));
1669  if (!(ba | bb))
1670  cpu->cd.ppc.cr |= (1 << (31-bt));
1671 }
1672 X(crxor) {
1673  uint32_t iword = ic->arg[0]; int bt = (iword >> 21) & 31;
1674  int ba = (iword >> 16) & 31, bb = (iword >> 11) & 31;
1675  ba = (cpu->cd.ppc.cr >> (31-ba)) & 1;
1676  bb = (cpu->cd.ppc.cr >> (31-bb)) & 1;
1677  cpu->cd.ppc.cr &= ~(1 << (31-bt));
1678  if (ba ^ bb)
1679  cpu->cd.ppc.cr |= (1 << (31-bt));
1680 }
1681 
1682 
1683 /*
1684  * mfspr: Move from SPR
1685  *
1686  * arg[0] = pointer to destination register
1687  * arg[1] = pointer to source SPR
1688  */
1689 X(mfspr) {
1690  /* TODO: Check permission */
1691  reg(ic->arg[0]) = reg(ic->arg[1]);
1692 }
1693 X(mfspr_pmc1) {
1694  /*
1695  * TODO: This is a temporary hack to make NetBSD/ppc detect
1696  * a CPU of the correct (emulated) speed.
1697  */
1698  reg(ic->arg[0]) = cpu->machine->emulated_hz / 10;
1699 }
1700 X(mftb) {
1701  /* NOTE/TODO: This increments the time base (slowly) if it
1702  is being polled. */
1703  if (++cpu->cd.ppc.spr[SPR_TBL] == 0)
1704  cpu->cd.ppc.spr[SPR_TBU] ++;
1705  reg(ic->arg[0]) = cpu->cd.ppc.spr[SPR_TBL];
1706 }
1707 X(mftbu) {
1708  reg(ic->arg[0]) = cpu->cd.ppc.spr[SPR_TBU];
1709 }
1710 
1711 
1712 /*
1713  * mtspr: Move to SPR.
1714  *
1715  * arg[0] = pointer to source register
1716  * arg[1] = pointer to the SPR
1717  */
1718 X(mtspr) {
1719  /* TODO: Check permission */
1720  reg(ic->arg[1]) = reg(ic->arg[0]);
1721 }
1722 X(mtspr_sprg2) {
1723  if (cpu->cd.ppc.bits == 32) {
1724  // Ignore for now. FreeBSD/powerpc seems to write 0xffffffe0
1725  // here, and read it back. If it is non-zero, it assumes a 64-bit
1726  // cpu.
1727  } else {
1728  reg(ic->arg[1]) = reg(ic->arg[0]);
1729  }
1730 }
1731 X(mtlr) {
1732  cpu->cd.ppc.spr[SPR_LR] = reg(ic->arg[0]);
1733 }
1734 X(mtctr) {
1735  cpu->cd.ppc.spr[SPR_CTR] = reg(ic->arg[0]);
1736 }
1737 
1738 
1739 /*
1740  * rfi[d]: Return from Interrupt
1741  */
1742 X(rfi)
1743 {
1744  uint64_t tmp;
1745 
1746  reg_access_msr(cpu, &tmp, 0, 0);
1747  tmp &= ~0xffff;
1748  tmp |= (cpu->cd.ppc.spr[SPR_SRR1] & 0xffff);
1749  reg_access_msr(cpu, &tmp, 1, 0);
1750 
1751  cpu->pc = cpu->cd.ppc.spr[SPR_SRR0];
1753 }
1754 X(rfid)
1755 {
1756  uint64_t tmp, mask = 0x800000000000ff73ULL;
1757 
1758  reg_access_msr(cpu, &tmp, 0, 0);
1759  tmp &= ~mask;
1760  tmp |= (cpu->cd.ppc.spr[SPR_SRR1] & mask);
1761  reg_access_msr(cpu, &tmp, 1, 0);
1762 
1763  cpu->pc = cpu->cd.ppc.spr[SPR_SRR0];
1764  if (!(tmp & PPC_MSR_SF))
1765  cpu->pc = (uint32_t)cpu->pc;
1767 }
1768 
1769 
1770 /*
1771  * mfcr: Move From Condition Register
1772  *
1773  * arg[0] = pointer to destination register
1774  */
1775 X(mfcr)
1776 {
1777  reg(ic->arg[0]) = cpu->cd.ppc.cr;
1778 }
1779 
1780 
1781 /*
1782  * mfmsr: Move From MSR
1783  *
1784  * arg[0] = pointer to destination register
1785  */
1786 X(mfmsr)
1787 {
1788  reg_access_msr(cpu, (uint64_t*)ic->arg[0], 0, 0);
1789 }
1790 
1791 
1792 /*
1793  * mtmsr: Move To MSR
1794  *
1795  * arg[0] = pointer to source register
1796  * arg[1] = page offset of the next instruction
1797  * arg[2] = 0 for 32-bit (mtmsr), 1 for 64-bit (mtmsrd)
1798  */
1799 X(mtmsr)
1800 {
1801  MODE_uint_t old_pc;
1802  uint64_t x = reg(ic->arg[0]);
1803 
1804  /* TODO: check permission! */
1805 
1806  /* Synchronize the PC (pointing to _after_ this instruction) */
1807  cpu->pc = (cpu->pc & ~0xfff) + ic->arg[1];
1808  old_pc = cpu->pc;
1809 
1810  if (!ic->arg[2]) {
1811  uint64_t y;
1812  reg_access_msr(cpu, &y, 0, 0);
1813  x = (y & 0xffffffff00000000ULL) | (x & 0xffffffffULL);
1814  }
1815 
1816  reg_access_msr(cpu, &x, 1, 1);
1817 
1818  /*
1819  * Super-ugly hack: If the pc wasn't changed (i.e. if there was no
1820  * exception while accessing the msr), then we _decrease_ the PC by 4
1821  * again. This is because the next ic could be an end_of_page.
1822  */
1823  if ((MODE_uint_t)cpu->pc == old_pc)
1824  cpu->pc -= 4;
1825 }
1826 
1827 
1828 /*
1829  * wrteei: Write EE immediate (on PPC405GP)
1830  *
1831  * arg[0] = either 0 or 0x8000
1832  */
1833 X(wrteei)
1834 {
1835  /* TODO: check permission! */
1836  uint64_t x;
1837 
1838  /* Synchronize the PC (pointing to _after_ this instruction) */
1839  cpu->pc = (cpu->pc & ~0xfff) + ic->arg[1];
1840 
1841  reg_access_msr(cpu, &x, 0, 0);
1842  x = (x & ~0x8000) | ic->arg[0];
1843  reg_access_msr(cpu, &x, 1, 1);
1844 }
1845 
1846 
1847 /*
1848  * mtcrf: Move To Condition Register Fields
1849  *
1850  * arg[0] = pointer to source register
1851  */
1852 X(mtcrf)
1853 {
1854  cpu->cd.ppc.cr &= ~ic->arg[1];
1855  cpu->cd.ppc.cr |= (reg(ic->arg[0]) & ic->arg[1]);
1856 }
1857 
1858 
1859 /*
1860  * mulli: Multiply Low Immediate.
1861  *
1862  * arg[0] = pointer to source register ra
1863  * arg[1] = int32_t immediate
1864  * arg[2] = pointer to destination register rt
1865  */
1866 X(mulli)
1867 {
1868  reg(ic->arg[2]) = (uint32_t)(reg(ic->arg[0]) * (int32_t)ic->arg[1]);
1869 }
1870 
1871 
1872 /*
1873  * Load/Store Multiple:
1874  *
1875  * arg[0] = rs (or rt for loads) NOTE: not a pointer
1876  * arg[1] = ptr to ra
1877  * arg[2] = int32_t immediate offset
1878  */
1879 X(lmw) {
1880  MODE_uint_t addr = reg(ic->arg[1]) + (int32_t)ic->arg[2];
1881  unsigned char d[4];
1882  int rs = ic->arg[0];
1883 
1884  int low_pc = ((size_t)ic - (size_t)cpu->cd.ppc.cur_ic_page)
1885  / sizeof(struct ppc_instr_call);
1886  cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1)
1888  cpu->pc |= (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
1889 
1890  while (rs <= 31) {
1891  if (cpu->memory_rw(cpu, cpu->mem, addr, d, sizeof(d),
1893  /* exception */
1894  return;
1895  }
1896 
1897  if (cpu->byte_order == EMUL_BIG_ENDIAN)
1898  cpu->cd.ppc.gpr[rs] = (d[0] << 24) + (d[1] << 16)
1899  + (d[2] << 8) + d[3];
1900  else
1901  cpu->cd.ppc.gpr[rs] = (d[3] << 24) + (d[2] << 16)
1902  + (d[1] << 8) + d[0];
1903 
1904  rs ++;
1905  addr += sizeof(uint32_t);
1906  }
1907 }
1908 X(stmw) {
1909  MODE_uint_t addr = reg(ic->arg[1]) + (int32_t)ic->arg[2];
1910  unsigned char d[4];
1911  int rs = ic->arg[0];
1912 
1913  int low_pc = ((size_t)ic - (size_t)cpu->cd.ppc.cur_ic_page)
1914  / sizeof(struct ppc_instr_call);
1915  cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1)
1917  cpu->pc += (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
1918 
1919  while (rs <= 31) {
1920  uint32_t tmp = cpu->cd.ppc.gpr[rs];
1921  if (cpu->byte_order == EMUL_BIG_ENDIAN) {
1922  d[3] = tmp; d[2] = tmp >> 8;
1923  d[1] = tmp >> 16; d[0] = tmp >> 24;
1924  } else {
1925  d[0] = tmp; d[1] = tmp >> 8;
1926  d[2] = tmp >> 16; d[3] = tmp >> 24;
1927  }
1928  if (cpu->memory_rw(cpu, cpu->mem, addr, d, sizeof(d),
1930  /* exception */
1931  return;
1932  }
1933 
1934  rs ++;
1935  addr += sizeof(uint32_t);
1936  }
1937 }
1938 
1939 
1940 /*
1941  * Load/store string:
1942  *
1943  * arg[0] = rs (well, rt for lswi)
1944  * arg[1] = ptr to ra (or ptr to zero)
1945  * arg[2] = nb
1946  */
1947 X(lswi)
1948 {
1949  MODE_uint_t addr = reg(ic->arg[1]);
1950  int rt = ic->arg[0], nb = ic->arg[2];
1951  int sub = 0;
1952 
1953  int low_pc = ((size_t)ic - (size_t)cpu->cd.ppc.cur_ic_page)
1954  / sizeof(struct ppc_instr_call);
1955  cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1)
1957  cpu->pc += (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
1958 
1959  while (nb > 0) {
1960  unsigned char d;
1961  if (cpu->memory_rw(cpu, cpu->mem, addr, &d, 1,
1963  /* exception */
1964  return;
1965  }
1966 
1967  if (cpu->cd.ppc.mode == MODE_POWER && sub == 0)
1968  cpu->cd.ppc.gpr[rt] = 0;
1969  cpu->cd.ppc.gpr[rt] &= ~(0xff << (24-8*sub));
1970  cpu->cd.ppc.gpr[rt] |= (d << (24-8*sub));
1971  sub ++;
1972  if (sub == 4) {
1973  rt = (rt + 1) & 31;
1974  sub = 0;
1975  }
1976  addr ++;
1977  nb --;
1978  }
1979 }
1980 X(stswi)
1981 {
1982  MODE_uint_t addr = reg(ic->arg[1]);
1983  int rs = ic->arg[0], nb = ic->arg[2];
1984  uint32_t cur = cpu->cd.ppc.gpr[rs];
1985  int sub = 0;
1986 
1987  int low_pc = ((size_t)ic - (size_t)cpu->cd.ppc.cur_ic_page)
1988  / sizeof(struct ppc_instr_call);
1989  cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1)
1991  cpu->pc += (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
1992 
1993  while (nb > 0) {
1994  unsigned char d = cur >> 24;
1995  if (cpu->memory_rw(cpu, cpu->mem, addr, &d, 1,
1997  /* exception */
1998  return;
1999  }
2000  cur <<= 8;
2001  sub ++;
2002  if (sub == 4) {
2003  rs = (rs + 1) & 31;
2004  sub = 0;
2005  cur = cpu->cd.ppc.gpr[rs];
2006  }
2007  addr ++;
2008  nb --;
2009  }
2010 }
2011 
2012 
2013 /*
2014  * Shifts, and, or, xor, etc.
2015  *
2016  * arg[0] = pointer to source register rs
2017  * arg[1] = pointer to source register rb
2018  * arg[2] = pointer to destination register ra
2019  */
2020 X(extsb) {
2021 #ifdef MODE32
2022  reg(ic->arg[2]) = (int32_t)(int8_t)reg(ic->arg[0]);
2023 #else
2024  reg(ic->arg[2]) = (int64_t)(int8_t)reg(ic->arg[0]);
2025 #endif
2026 }
2027 DOT2(extsb)
2028 X(extsh) {
2029 #ifdef MODE32
2030  reg(ic->arg[2]) = (int32_t)(int16_t)reg(ic->arg[0]);
2031 #else
2032  reg(ic->arg[2]) = (int64_t)(int16_t)reg(ic->arg[0]);
2033 #endif
2034 }
2035 DOT2(extsh)
2036 X(extsw) {
2037 #ifdef MODE32
2038  fatal("TODO: extsw: invalid instruction\n");
2039 #else
2040  reg(ic->arg[2]) = (int64_t)(int32_t)reg(ic->arg[0]);
2041 #endif
2042 }
2043 DOT2(extsw)
2044 X(slw) { reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0])
2045  << (reg(ic->arg[1]) & 31); }
2046 DOT2(slw)
2047 X(sld) {int sa = reg(ic->arg[1]) & 127;
2048  if (sa >= 64) reg(ic->arg[2]) = 0;
2049  else reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0]) << (sa & 63); }
2050 DOT2(sld)
2051 X(sraw)
2052 {
2053  uint32_t tmp = reg(ic->arg[0]);
2054  int i = 0, j = 0, sh = reg(ic->arg[1]) & 31;
2055 
2056  cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2057  if (tmp & 0x80000000)
2058  i = 1;
2059  while (sh-- > 0) {
2060  if (tmp & 1)
2061  j ++;
2062  tmp >>= 1;
2063  if (tmp & 0x40000000)
2064  tmp |= 0x80000000;
2065  }
2066  if (i && j>0)
2067  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2068  reg(ic->arg[2]) = (int64_t)(int32_t)tmp;
2069 }
2070 DOT2(sraw)
2071 X(srw) { reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0])
2072  >> (reg(ic->arg[1]) & 31); }
2073 DOT2(srw)
2074 X(and) { reg(ic->arg[2]) = reg(ic->arg[0]) & reg(ic->arg[1]); }
2075 DOT2(and)
2076 X(nand) { reg(ic->arg[2]) = ~(reg(ic->arg[0]) & reg(ic->arg[1])); }
2077 DOT2(nand)
2078 X(andc) { reg(ic->arg[2]) = reg(ic->arg[0]) & (~reg(ic->arg[1])); }
2079 DOT2(andc)
2080 X(nor) { reg(ic->arg[2]) = ~(reg(ic->arg[0]) | reg(ic->arg[1])); }
2081 DOT2(nor)
2082 X(mr) { reg(ic->arg[2]) = reg(ic->arg[1]); }
2083 X(or) { reg(ic->arg[2]) = reg(ic->arg[0]) | reg(ic->arg[1]); }
2084 DOT2(or)
2085 X(orc) { reg(ic->arg[2]) = reg(ic->arg[0]) | (~reg(ic->arg[1])); }
2086 DOT2(orc)
2087 X(xor) { reg(ic->arg[2]) = reg(ic->arg[0]) ^ reg(ic->arg[1]); }
2088 DOT2(xor)
2089 X(eqv) { reg(ic->arg[2]) = ~(reg(ic->arg[0]) ^ reg(ic->arg[1])); }
2090 DOT2(eqv)
2091 
2092 
2093 /*
2094  * neg:
2095  *
2096  * arg[0] = pointer to source register ra
2097  * arg[1] = pointer to destination register rt
2098  */
2099 X(neg) { reg(ic->arg[1]) = -reg(ic->arg[0]); }
2100 DOT1(neg)
2101 
2102 
2103 /*
2104  * mullw, mulhw[u], divw[u]:
2105  *
2106  * arg[0] = pointer to source register ra
2107  * arg[1] = pointer to source register rb
2108  * arg[2] = pointer to destination register rt
2109  */
2110 X(mullw)
2111 {
2112  int32_t sum = (int32_t)reg(ic->arg[0]) * (int32_t)reg(ic->arg[1]);
2113  reg(ic->arg[2]) = (int32_t)sum;
2114 }
2115 DOT2(mullw)
2116 X(mulhw)
2117 {
2118  int64_t sum;
2119  sum = (int64_t)(int32_t)reg(ic->arg[0])
2120  * (int64_t)(int32_t)reg(ic->arg[1]);
2121  reg(ic->arg[2]) = sum >> 32;
2122 }
2123 DOT2(mulhw)
2124 X(mulhwu)
2125 {
2126  uint64_t sum;
2127  sum = (uint64_t)(uint32_t)reg(ic->arg[0])
2128  * (uint64_t)(uint32_t)reg(ic->arg[1]);
2129  reg(ic->arg[2]) = sum >> 32;
2130 }
2131 DOT2(mulhwu)
2132 X(divw)
2133 {
2134  int32_t a = reg(ic->arg[0]), b = reg(ic->arg[1]);
2135  int32_t sum;
2136  if (b == 0)
2137  sum = 0;
2138  else
2139  sum = a / b;
2140  reg(ic->arg[2]) = (uint32_t)sum;
2141 }
2142 DOT2(divw)
2143 X(divwu)
2144 {
2145  uint32_t a = reg(ic->arg[0]), b = reg(ic->arg[1]);
2146  uint32_t sum;
2147  if (b == 0)
2148  sum = 0;
2149  else
2150  sum = a / b;
2151  reg(ic->arg[2]) = sum;
2152 }
2153 DOT2(divwu)
2154 
2155 
2156 /*
2157  * add: Add.
2158  *
2159  * arg[0] = pointer to source register ra
2160  * arg[1] = pointer to source register rb
2161  * arg[2] = pointer to destination register rt
2162  */
2163 X(add) { reg(ic->arg[2]) = reg(ic->arg[0]) + reg(ic->arg[1]); }
2164 DOT2(add)
2165 
2166 
2167 /*
2168  * addc: Add carrying.
2169  *
2170  * arg[0] = pointer to source register ra
2171  * arg[1] = pointer to source register rb
2172  * arg[2] = pointer to destination register rt
2173  */
2174 X(addc)
2175 {
2176  /* TODO: this only works in 32-bit mode */
2177  uint64_t tmp = (uint32_t)reg(ic->arg[0]);
2178  uint64_t tmp2 = tmp;
2179  cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2180  tmp += (uint32_t)reg(ic->arg[1]);
2181  if ((tmp >> 32) != (tmp2 >> 32))
2182  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2183  reg(ic->arg[2]) = (uint32_t)tmp;
2184 }
2185 
2186 
2187 /*
2188  * adde: Add extended, etc.
2189  *
2190  * arg[0] = pointer to source register ra
2191  * arg[1] = pointer to source register rb
2192  * arg[2] = pointer to destination register rt
2193  */
2194 X(adde)
2195 {
2196  /* TODO: this only works in 32-bit mode */
2197  int old_ca = cpu->cd.ppc.spr[SPR_XER] & PPC_XER_CA;
2198  uint64_t tmp = (uint32_t)reg(ic->arg[0]);
2199  uint64_t tmp2 = tmp;
2200  cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2201  tmp += (uint32_t)reg(ic->arg[1]);
2202  if (old_ca)
2203  tmp ++;
2204  if ((tmp >> 32) != (tmp2 >> 32))
2205  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2206  reg(ic->arg[2]) = (uint32_t)tmp;
2207 }
2208 DOT2(adde)
2209 X(addme)
2210 {
2211  /* TODO: this only works in 32-bit mode */
2212  int old_ca = cpu->cd.ppc.spr[SPR_XER] & PPC_XER_CA;
2213  uint64_t tmp = (uint32_t)reg(ic->arg[0]);
2214  uint64_t tmp2 = tmp;
2215  cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2216  if (old_ca)
2217  tmp ++;
2218  tmp += 0xffffffffULL;
2219  if ((tmp >> 32) != (tmp2 >> 32))
2220  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2221  reg(ic->arg[2]) = (uint32_t)tmp;
2222 }
2223 DOT2(addme)
2224 X(addze)
2225 {
2226  /* TODO: this only works in 32-bit mode */
2227  int old_ca = cpu->cd.ppc.spr[SPR_XER] & PPC_XER_CA;
2228  uint64_t tmp = (uint32_t)reg(ic->arg[0]);
2229  uint64_t tmp2 = tmp;
2230  cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2231  if (old_ca)
2232  tmp ++;
2233  if ((tmp >> 32) != (tmp2 >> 32))
2234  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2235  reg(ic->arg[2]) = (uint32_t)tmp;
2236 }
2237 DOT2(addze)
2238 
2239 
2240 /*
2241  * subf: Subf, etc.
2242  *
2243  * arg[0] = pointer to source register ra
2244  * arg[1] = pointer to source register rb
2245  * arg[2] = pointer to destination register rt
2246  */
2247 X(subf)
2248 {
2249  reg(ic->arg[2]) = reg(ic->arg[1]) - reg(ic->arg[0]);
2250 }
2251 DOT2(subf)
2252 X(subfc)
2253 {
2254  cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2255  if (reg(ic->arg[1]) >= reg(ic->arg[0]))
2256  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2257  reg(ic->arg[2]) = reg(ic->arg[1]) - reg(ic->arg[0]);
2258 }
2259 DOT2(subfc)
2260 X(subfe)
2261 {
2262  int old_ca = (cpu->cd.ppc.spr[SPR_XER] & PPC_XER_CA)? 1 : 0;
2263  cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2264  if (reg(ic->arg[1]) == reg(ic->arg[0])) {
2265  if (old_ca)
2266  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2267  } else if (reg(ic->arg[1]) >= reg(ic->arg[0]))
2268  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2269 
2270  /*
2271  * TODO: The register value calculation should be correct,
2272  * but the CA bit calculation above is probably not.
2273  */
2274 
2275  reg(ic->arg[2]) = reg(ic->arg[1]) - reg(ic->arg[0]) - (old_ca? 0 : 1);
2276 }
2277 DOT2(subfe)
2278 X(subfme)
2279 {
2280  int old_ca = cpu->cd.ppc.spr[SPR_XER] & PPC_XER_CA;
2281  uint64_t tmp = (uint32_t)(~reg(ic->arg[0]));
2282  tmp += 0xffffffffULL;
2283  cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2284  if (old_ca)
2285  tmp ++;
2286  if ((tmp >> 32) != 0)
2287  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2288  reg(ic->arg[2]) = (uint32_t)tmp;
2289 }
2290 DOT2(subfme)
2291 X(subfze)
2292 {
2293  int old_ca = cpu->cd.ppc.spr[SPR_XER] & PPC_XER_CA;
2294  uint64_t tmp = (uint32_t)(~reg(ic->arg[0]));
2295  uint64_t tmp2 = tmp;
2296  cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2297  if (old_ca)
2298  tmp ++;
2299  if ((tmp >> 32) != (tmp2 >> 32))
2300  cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2301  reg(ic->arg[2]) = (uint32_t)tmp;
2302 }
2303 DOT2(subfze)
2304 
2305 
2306 /*
2307  * ori, xori etc.:
2308  *
2309  * arg[0] = pointer to source uint64_t
2310  * arg[1] = immediate value (uint32_t or larger)
2311  * arg[2] = pointer to destination uint64_t
2312  */
2313 X(ori) { reg(ic->arg[2]) = reg(ic->arg[0]) | (uint32_t)ic->arg[1]; }
2314 X(xori) { reg(ic->arg[2]) = reg(ic->arg[0]) ^ (uint32_t)ic->arg[1]; }
2315 
2316 
2317 #include "tmp_ppc_loadstore.cc"
2318 
2319 
2320 /*
2321  * lfs, stfs: Load/Store Floating-point Single precision
2322  */
2323 X(lfs)
2324 {
2325  /* Sync. PC in case of an exception, and remember it: */
2326  uint64_t old_pc, low_pc = ((size_t)ic - (size_t)
2327  cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
2328  old_pc = cpu->pc = (cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) <<
2330  if (!(cpu->cd.ppc.msr & PPC_MSR_FP)) {
2332  return;
2333  }
2334 
2335  /* Perform a 32-bit load: */
2336 #ifdef MODE32
2337  ppc32_loadstore
2338 #else
2340 #endif
2341  [2 + 4 + 8](cpu, ic);
2342 
2343  if (old_pc == cpu->pc) {
2344  /* The load succeeded. Let's convert the value: */
2345  struct ieee_float_value val;
2346  (*(uint64_t *)ic->arg[0]) &= 0xffffffff;
2347  ieee_interpret_float_value(*(uint64_t *)ic->arg[0],
2348  &val, IEEE_FMT_S);
2349  (*(uint64_t *)ic->arg[0]) =
2351  }
2352 }
2353 X(lfsx)
2354 {
2355  /* Sync. PC in case of an exception, and remember it: */
2356  uint64_t old_pc, low_pc = ((size_t)ic - (size_t)
2357  cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
2358  old_pc = cpu->pc = (cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) <<
2360  if (!(cpu->cd.ppc.msr & PPC_MSR_FP)) {
2362  return;
2363  }
2364 
2365  /* Perform a 32-bit load: */
2366 #ifdef MODE32
2367  ppc32_loadstore_indexed
2368 #else
2370 #endif
2371  [2 + 4 + 8](cpu, ic);
2372 
2373  if (old_pc == cpu->pc) {
2374  /* The load succeeded. Let's convert the value: */
2375  struct ieee_float_value val;
2376  (*(uint64_t *)ic->arg[0]) &= 0xffffffff;
2377  ieee_interpret_float_value(*(uint64_t *)ic->arg[0],
2378  &val, IEEE_FMT_S);
2379  (*(uint64_t *)ic->arg[0]) =
2381  }
2382 }
2383 X(lfd)
2384 {
2386 
2387  /* Perform a 64-bit load: */
2388 #ifdef MODE32
2389  ppc32_loadstore
2390 #else
2392 #endif
2393  [3 + 4 + 8](cpu, ic);
2394 }
2395 X(lfdx)
2396 {
2398 
2399  /* Perform a 64-bit load: */
2400 #ifdef MODE32
2401  ppc32_loadstore_indexed
2402 #else
2404 #endif
2405  [3 + 4 + 8](cpu, ic);
2406 }
2407 X(stfs)
2408 {
2409  uint64_t *old_arg0 = (uint64_t *) ic->arg[0];
2410  struct ieee_float_value val;
2411  uint64_t tmp_val;
2412 
2414 
2415  ieee_interpret_float_value(*old_arg0, &val, IEEE_FMT_D);
2416  tmp_val = ieee_store_float_value(val.f, IEEE_FMT_S);
2417 
2418  ic->arg[0] = (size_t)&tmp_val;
2419 
2420  /* Perform a 32-bit store: */
2421 #ifdef MODE32
2422  ppc32_loadstore
2423 #else
2425 #endif
2426  [2 + 4](cpu, ic);
2427 
2428  ic->arg[0] = (size_t)old_arg0;
2429 }
2430 X(stfsx)
2431 {
2432  uint64_t *old_arg0 = (uint64_t *)ic->arg[0];
2433  struct ieee_float_value val;
2434  uint64_t tmp_val;
2435 
2437 
2438  ieee_interpret_float_value(*old_arg0, &val, IEEE_FMT_D);
2439  tmp_val = ieee_store_float_value(val.f, IEEE_FMT_S);
2440 
2441  ic->arg[0] = (size_t)&tmp_val;
2442 
2443  /* Perform a 32-bit store: */
2444 #ifdef MODE32
2445  ppc32_loadstore_indexed
2446 #else
2448 #endif
2449  [2 + 4](cpu, ic);
2450 
2451  ic->arg[0] = (size_t)old_arg0;
2452 }
2453 X(stfd)
2454 {
2456 
2457  /* Perform a 64-bit store: */
2458 #ifdef MODE32
2459  ppc32_loadstore
2460 #else
2462 #endif
2463  [3 + 4](cpu, ic);
2464 }
2465 X(stfdx)
2466 {
2468 
2469  /* Perform a 64-bit store: */
2470 #ifdef MODE32
2471  ppc32_loadstore_indexed
2472 #else
2474 #endif
2475  [3 + 4](cpu, ic);
2476 }
2477 
2478 
2479 /*
2480  * lvx, stvx: Vector (16-byte) load/store (slow implementation)
2481  *
2482  * arg[0] = v-register nr of rs
2483  * arg[1] = pointer to ra
2484  * arg[2] = pointer to rb
2485  */
2486 X(lvx)
2487 {
2488  MODE_uint_t addr = reg(ic->arg[1]) + reg(ic->arg[2]);
2489  uint8_t data[16];
2490  uint64_t hi, lo;
2491  int rs = ic->arg[0];
2492 
2493  if (cpu->memory_rw(cpu, cpu->mem, addr, data, sizeof(data),
2495  /* exception */
2496  return;
2497  }
2498 
2499  hi = ((uint64_t)data[0] << 56) +
2500  ((uint64_t)data[1] << 48) +
2501  ((uint64_t)data[2] << 40) +
2502  ((uint64_t)data[3] << 32) +
2503  ((uint64_t)data[4] << 24) +
2504  ((uint64_t)data[5] << 16) +
2505  ((uint64_t)data[6] << 8) +
2506  ((uint64_t)data[7]);
2507  lo = ((uint64_t)data[8] << 56) +
2508  ((uint64_t)data[9] << 48) +
2509  ((uint64_t)data[10] << 40) +
2510  ((uint64_t)data[11] << 32) +
2511  ((uint64_t)data[12] << 24) +
2512  ((uint64_t)data[13] << 16) +
2513  ((uint64_t)data[14] << 8) +
2514  ((uint64_t)data[15]);
2515 
2516  cpu->cd.ppc.vr_hi[rs] = hi; cpu->cd.ppc.vr_lo[rs] = lo;
2517 }
2518 X(stvx)
2519 {
2520  uint8_t data[16];
2521  MODE_uint_t addr = reg(ic->arg[1]) + reg(ic->arg[2]);
2522  int rs = ic->arg[0];
2523  uint64_t hi = cpu->cd.ppc.vr_hi[rs], lo = cpu->cd.ppc.vr_lo[rs];
2524 
2525  data[0] = hi >> 56;
2526  data[1] = hi >> 48;
2527  data[2] = hi >> 40;
2528  data[3] = hi >> 32;
2529  data[4] = hi >> 24;
2530  data[5] = hi >> 16;
2531  data[6] = hi >> 8;
2532  data[7] = hi;
2533  data[8] = lo >> 56;
2534  data[9] = lo >> 48;
2535  data[10] = lo >> 40;
2536  data[11] = lo >> 32;
2537  data[12] = lo >> 24;
2538  data[13] = lo >> 16;
2539  data[14] = lo >> 8;
2540  data[15] = lo;
2541 
2542  cpu->memory_rw(cpu, cpu->mem, addr, data,
2543  sizeof(data), MEM_WRITE, CACHE_DATA);
2544 }
2545 
2546 
2547 /*
2548  * vxor: Vector (16-byte) XOR
2549  *
2550  * arg[0] = v-register nr of source 1
2551  * arg[1] = v-register nr of source 2
2552  * arg[2] = v-register nr of destination
2553  */
2554 X(vxor)
2555 {
2556  cpu->cd.ppc.vr_hi[ic->arg[2]] =
2557  cpu->cd.ppc.vr_hi[ic->arg[0]] ^ cpu->cd.ppc.vr_hi[ic->arg[1]];
2558  cpu->cd.ppc.vr_lo[ic->arg[2]] =
2559  cpu->cd.ppc.vr_lo[ic->arg[0]] ^ cpu->cd.ppc.vr_lo[ic->arg[1]];
2560 }
2561 
2562 
2563 /*
2564  * tlbia: TLB invalidate all
2565  */
2566 X(tlbia)
2567 {
2568  fatal("[ tlbia ]\n");
2570 }
2571 
2572 
2573 /*
2574  * tlbie: TLB invalidate
2575  */
2576 X(tlbie)
2577 {
2578  /* fatal("[ tlbie ]\n"); */
2581 }
2582 
2583 
2584 /*
2585  * sc: Syscall.
2586  */
2587 X(sc)
2588 {
2589  /* Synchronize the PC (pointing to _after_ this instruction) */
2590  cpu->pc = (cpu->pc & ~0xfff) + ic->arg[1];
2591 
2593 
2594  /* This caused an update to the PC register, so there is no need
2595  to worry about the next instruction being an end_of_page. */
2596 }
2597 
2598 
2599 /*
2600  * openfirmware:
2601  */
2602 X(openfirmware)
2603 {
2604  of_emul(cpu);
2605  if (cpu->running == 0) {
2607  cpu->cd.ppc.next_ic = &nothing_call;
2609  }
2610 
2611  cpu->pc = cpu->cd.ppc.spr[SPR_LR];
2612  if (cpu->machine->show_trace_tree)
2614 
2616 }
2617 
2618 
2619 /*
2620  * tlbsx_dot: TLB scan
2621  */
2622 X(tlbsx_dot)
2623 {
2624  /* TODO */
2625  cpu->cd.ppc.cr &= ~(0xf0000000);
2626  cpu->cd.ppc.cr |= 0x20000000;
2627  cpu->cd.ppc.cr |= ((cpu->cd.ppc.spr[SPR_XER] >> 3) & 0x10000000);
2628 }
2629 
2630 
2631 /*
2632  * tlbli:
2633  */
2634 X(tlbli)
2635 {
2636  fatal("tlbli\n");
2638 }
2639 
2640 
2641 /*
2642  * tlbld:
2643  */
2644 X(tlbld)
2645 {
2646  /* MODE_uint_t vaddr = reg(ic->arg[0]);
2647  MODE_uint_t paddr = cpu->cd.ppc.spr[SPR_RPA]; */
2648 
2649  fatal("tlbld\n");
2651 }
2652 
2653 
2654 /*****************************************************************************/
2655 
2656 
2657 X(end_of_page)
2658 {
2659  /* Update the PC: (offset 0, but on the next page) */
2662 
2663  /* Find the new physical page and update the translation pointers: */
2665 
2666  /* end_of_page doesn't count as an executed instruction: */
2668 }
2669 
2670 
2671 /*****************************************************************************/
2672 
2673 
2674 /*
2675  * ppc_instr_to_be_translated():
2676  *
2677  * Translate an instruction word into a ppc_instr_call. ic is filled in with
2678  * valid data for the translated instruction, or a "nothing" instruction if
2679  * there was a translation failure. The newly translated instruction is then
2680  * executed.
2681  */
2682 X(to_be_translated)
2683 {
2684  uint64_t addr, low_pc, tmp_addr;
2685  uint32_t iword, mask;
2686  unsigned char *page;
2687  unsigned char ib[4];
2688  int main_opcode, rt, rs, ra, rb, rc, aa_bit, l_bit, lk_bit, spr, sh,
2689  xo, imm, load, size, update, zero, bf, bo, bi, bh, oe_bit, n64=0,
2690  bfa, fp, byterev, nb, mb, me;
2691  void (*samepage_function)(struct cpu *, struct ppc_instr_call *);
2692  void (*rc_f)(struct cpu *, struct ppc_instr_call *);
2693 
2694  /* Figure out the (virtual) address of the instruction: */
2695  low_pc = ((size_t)ic - (size_t)cpu->cd.ppc.cur_ic_page)
2696  / sizeof(struct ppc_instr_call);
2697  addr = cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1)
2699  addr += (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
2700  cpu->pc = addr;
2701  addr &= ~((1 << PPC_INSTR_ALIGNMENT_SHIFT) - 1);
2702 
2703  /* Read the instruction word from memory: */
2704 #ifdef MODE32
2705  page = cpu->cd.ppc.host_load[((uint32_t)addr) >> 12];
2706 #else
2707  {
2708  const uint32_t mask1 = (1 << DYNTRANS_L1N) - 1;
2709  const uint32_t mask2 = (1 << DYNTRANS_L2N) - 1;
2710  const uint32_t mask3 = (1 << DYNTRANS_L3N) - 1;
2711  uint32_t x1 = (addr >> (64-DYNTRANS_L1N)) & mask1;
2712  uint32_t x2 = (addr >> (64-DYNTRANS_L1N-DYNTRANS_L2N)) & mask2;
2713  uint32_t x3 = (addr >> (64-DYNTRANS_L1N-DYNTRANS_L2N-
2714  DYNTRANS_L3N)) & mask3;
2715  struct DYNTRANS_L2_64_TABLE *l2 = cpu->cd.ppc.l1_64[x1];
2716  struct DYNTRANS_L3_64_TABLE *l3 = l2->l3[x2];
2717  page = l3->host_load[x3];
2718  }
2719 #endif
2720 
2721  if (page != NULL) {
2722  /* fatal("TRANSLATION HIT!\n"); */
2723  memcpy(ib, page + (addr & 0xfff), sizeof(ib));
2724  } else {
2725  /* fatal("TRANSLATION MISS!\n"); */
2726  if (!cpu->memory_rw(cpu, cpu->mem, addr, ib,
2727  sizeof(ib), MEM_READ, CACHE_INSTRUCTION)) {
2728  fatal("PPC to_be_translated(): "
2729  "read failed: TODO\n");
2730  exit(1);
2731  /* goto bad; */
2732  }
2733  }
2734 
2735  {
2736  uint32_t *p = (uint32_t *) ib;
2737  iword = *p;
2738  iword = BE32_TO_HOST(iword);
2739  }
2740 
2741 #define DYNTRANS_TO_BE_TRANSLATED_HEAD
2742 #include "cpu_dyntrans.cc"
2743 #undef DYNTRANS_TO_BE_TRANSLATED_HEAD
2744 
2745 
2746  /*
2747  * Translate the instruction:
2748  */
2749 
2750  main_opcode = iword >> 26;
2751 
2752  switch (main_opcode) {
2753 
2754  case 0x04:
2755  if (iword == 0x12739cc4) {
2756  /* vxor v19,v19,v19 */
2757  ic->f = instr(vxor);
2758  ic->arg[0] = 19;
2759  ic->arg[1] = 19;
2760  ic->arg[2] = 19;
2761  } else {
2762  if (!cpu->translation_readahead)
2763  fatal("[ TODO: Unimplemented ALTIVEC, iword"
2764  " = 0x%08" PRIx32"x ]\n", iword);
2765  goto bad;
2766  }
2767  break;
2768 
2769  case PPC_HI6_MULLI:
2770  rt = (iword >> 21) & 31;
2771  ra = (iword >> 16) & 31;
2772  imm = (int16_t)(iword & 0xffff);
2773  ic->f = instr(mulli);
2774  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2775  ic->arg[1] = (ssize_t)imm;
2776  ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);
2777  break;
2778 
2779  case PPC_HI6_SUBFIC:
2780  rt = (iword >> 21) & 31;
2781  ra = (iword >> 16) & 31;
2782  imm = (int16_t)(iword & 0xffff);
2783  ic->f = instr(subfic);
2784  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2785  ic->arg[1] = (ssize_t)imm;
2786  ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);
2787  break;
2788 
2789  case PPC_HI6_CMPLI:
2790  case PPC_HI6_CMPI:
2791  bf = (iword >> 23) & 7;
2792  l_bit = (iword >> 21) & 1;
2793  ra = (iword >> 16) & 31;
2794  if (main_opcode == PPC_HI6_CMPLI) {
2795  imm = iword & 0xffff;
2796  if (l_bit)
2797  ic->f = instr(cmpldi);
2798  else
2799  ic->f = instr(cmplwi);
2800  } else {
2801  imm = (int16_t)(iword & 0xffff);
2802  if (l_bit)
2803  ic->f = instr(cmpdi);
2804  else {
2805  if (bf == 0)
2806  ic->f = instr(cmpwi_cr0);
2807  else
2808  ic->f = instr(cmpwi);
2809  }
2810  }
2811  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2812  ic->arg[1] = (ssize_t)imm;
2813  ic->arg[2] = 28 - 4 * bf;
2814  break;
2815 
2816  case PPC_HI6_ADDIC:
2817  case PPC_HI6_ADDIC_DOT:
2818  if (cpu->cd.ppc.bits == 64) {
2819  if (!cpu->translation_readahead)
2820  fatal("addic for 64-bit: TODO\n");
2821  goto bad;
2822  }
2823  rt = (iword >> 21) & 31;
2824  ra = (iword >> 16) & 31;
2825  imm = (int16_t)(iword & 0xffff);
2826  if (main_opcode == PPC_HI6_ADDIC)
2827  ic->f = instr(addic);
2828  else
2829  ic->f = instr(addic_dot);
2830  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2831  ic->arg[1] = imm;
2832  ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);
2833  break;
2834 
2835  case PPC_HI6_ADDI:
2836  case PPC_HI6_ADDIS:
2837  rt = (iword >> 21) & 31; ra = (iword >> 16) & 31;
2838  ic->f = instr(addi);
2839  if (ra == 0)
2840  ic->f = instr(li);
2841  else
2842  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2843  ic->arg[1] = (int16_t)(iword & 0xffff);
2844  if (main_opcode == PPC_HI6_ADDIS)
2845  ic->arg[1] <<= 16;
2846  if (ra == 0 && ic->arg[1] == 0)
2847  ic->f = instr(li_0);
2848  ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);
2849  break;
2850 
2851  case PPC_HI6_ANDI_DOT:
2852  case PPC_HI6_ANDIS_DOT:
2853  rs = (iword >> 21) & 31; ra = (iword >> 16) & 31;
2854  ic->f = instr(andi_dot);
2855  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
2856  ic->arg[1] = iword & 0xffff;
2857  if (main_opcode == PPC_HI6_ANDIS_DOT)
2858  ic->arg[1] <<= 16;
2859  ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2860  break;
2861 
2862  case PPC_HI6_ORI:
2863  case PPC_HI6_ORIS:
2864  case PPC_HI6_XORI:
2865  case PPC_HI6_XORIS:
2866  rs = (iword >> 21) & 31; ra = (iword >> 16) & 31;
2867  if (main_opcode == PPC_HI6_ORI ||
2868  main_opcode == PPC_HI6_ORIS)
2869  ic->f = instr(ori);
2870  else
2871  ic->f = instr(xori);
2872  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
2873  ic->arg[1] = iword & 0xffff;
2874  if (main_opcode == PPC_HI6_ORIS ||
2875  main_opcode == PPC_HI6_XORIS)
2876  ic->arg[1] <<= 16;
2877  ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2878  break;
2879 
2880  case PPC_HI6_LBZ:
2881  case PPC_HI6_LBZU:
2882  case PPC_HI6_LHZ:
2883  case PPC_HI6_LHZU:
2884  case PPC_HI6_LHA:
2885  case PPC_HI6_LHAU:
2886  case PPC_HI6_LWZ:
2887  case PPC_HI6_LWZU:
2888  case PPC_HI6_LD:
2889  case PPC_HI6_LFD:
2890  case PPC_HI6_LFS:
2891  case PPC_HI6_STB:
2892  case PPC_HI6_STBU:
2893  case PPC_HI6_STH:
2894  case PPC_HI6_STHU:
2895  case PPC_HI6_STW:
2896  case PPC_HI6_STWU:
2897  case PPC_HI6_STD:
2898  case PPC_HI6_STFD:
2899  case PPC_HI6_STFS:
2900  rs = (iword >> 21) & 31;
2901  ra = (iword >> 16) & 31;
2902  imm = (int16_t)iword;
2903  load = 0; zero = 1; size = 0; update = 0; fp = 0;
2904  ic->f = NULL;
2905  switch (main_opcode) {
2906  case PPC_HI6_LBZ: load=1; break;
2907  case PPC_HI6_LBZU: load=1; update=1; break;
2908  case PPC_HI6_LHA: load=1; size=1; zero=0; break;
2909  case PPC_HI6_LHAU: load=1; size=1; zero=0; update=1; break;
2910  case PPC_HI6_LHZ: load=1; size=1; break;
2911  case PPC_HI6_LHZU: load=1; size=1; update=1; break;
2912  case PPC_HI6_LWZ: load=1; size=2; break;
2913  case PPC_HI6_LWZU: load=1; size=2; update=1; break;
2914  case PPC_HI6_LD: load=1; size=3; break;
2915  case PPC_HI6_LFD: load=1; size=3; fp=1;ic->f=instr(lfd);break;
2916  case PPC_HI6_LFS: load=1; size=2; fp=1;ic->f=instr(lfs);break;
2917  case PPC_HI6_STB: break;
2918  case PPC_HI6_STBU: update=1; break;
2919  case PPC_HI6_STH: size=1; break;
2920  case PPC_HI6_STHU: size=1; update=1; break;
2921  case PPC_HI6_STW: size=2; break;
2922  case PPC_HI6_STWU: size=2; update=1; break;
2923  case PPC_HI6_STD: size=3; break;
2924  case PPC_HI6_STFD: size=3; fp=1; ic->f = instr(stfd); break;
2925  case PPC_HI6_STFS: size=2; fp=1; ic->f = instr(stfs); break;
2926  }
2927  if (ic->f == NULL) {
2928  ic->f =
2929 #ifdef MODE32
2930  ppc32_loadstore
2931 #else
2933 #endif
2934  [size + 4*zero + 8*load + (imm==0? 16 : 0)
2935  + 32*update];
2936  }
2937  if (ra == 0 && update) {
2938  if (!cpu->translation_readahead)
2939  fatal("TODO: ra=0 && update?\n");
2940  goto bad;
2941  }
2942  if (fp)
2943  ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rs]);
2944  else
2945  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
2946  if (ra == 0)
2947  ic->arg[1] = (size_t)(&cpu->cd.ppc.zero);
2948  else
2949  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2950  ic->arg[2] = (ssize_t)imm;
2951  break;
2952 
2953  case PPC_HI6_BC:
2954  aa_bit = (iword >> 1) & 1;
2955  lk_bit = iword & 1;
2956  bo = (iword >> 21) & 31;
2957  bi = (iword >> 16) & 31;
2958  tmp_addr = (int64_t)(int16_t)(iword & 0xfffc);
2959  if (aa_bit) {
2960  if (!cpu->translation_readahead)
2961  fatal("aa_bit: NOT YET\n");
2962  goto bad;
2963  }
2964  if (lk_bit) {
2965  ic->f = instr(bcl);
2966  samepage_function = instr(bcl_samepage);
2967  } else {
2968  ic->f = instr(bc);
2969  if ((bo & 0x14) == 0x04) {
2970  samepage_function = bo & 8?
2971  instr(bc_samepage_simple1) :
2972  instr(bc_samepage_simple0);
2973  } else
2974  samepage_function = instr(bc_samepage);
2975  }
2976  ic->arg[0] = (ssize_t)(tmp_addr + (addr & 0xffc));
2977  ic->arg[1] = bo;
2978  ic->arg[2] = 31-bi;
2979  /* Branches are calculated as cur PC + offset. */
2980  /* Special case: branch within the same page: */
2981  {
2982  uint64_t mask_within_page =
2983  ((PPC_IC_ENTRIES_PER_PAGE-1) << 2) | 3;
2984  uint64_t old_pc = addr;
2985  uint64_t new_pc = old_pc + (int32_t)tmp_addr;
2986  if ((old_pc & ~mask_within_page) ==
2987  (new_pc & ~mask_within_page)) {
2988  ic->f = samepage_function;
2989  ic->arg[0] = (size_t) (
2990  cpu->cd.ppc.cur_ic_page +
2991  ((new_pc & mask_within_page) >> 2));
2992  }
2993  }
2994  break;
2995 
2996  case PPC_HI6_SC:
2997  ic->arg[0] = (iword >> 5) & 0x7f;
2998  ic->arg[1] = (addr & 0xfff) + 4;
2999  if (iword == 0x44ee0002) {
3000  /* Special case/magic hack for OpenFirmware emul: */
3001  ic->f = instr(openfirmware);
3002  } else
3003  ic->f = instr(sc);
3004  break;
3005 
3006  case PPC_HI6_B:
3007  aa_bit = (iword & 2) >> 1;
3008  lk_bit = iword & 1;
3009  tmp_addr = (int64_t)(int32_t)((iword & 0x03fffffc) << 6);
3010  tmp_addr = (int64_t)tmp_addr >> 6;
3011  if (lk_bit) {
3012  if (cpu->machine->show_trace_tree) {
3013  ic->f = instr(bl_trace);
3014  samepage_function = instr(bl_samepage_trace);
3015  } else {
3016  ic->f = instr(bl);
3017  samepage_function = instr(bl_samepage);
3018  }
3019  } else {
3020  ic->f = instr(b);
3021  samepage_function = instr(b_samepage);
3022  }
3023  ic->arg[0] = (ssize_t)(tmp_addr + (addr & 0xffc));
3024  ic->arg[1] = (addr & 0xffc) + 4;
3025  /* Branches are calculated as cur PC + offset. */
3026  /* Special case: branch within the same page: */
3027  {
3028  uint64_t mask_within_page =
3029  ((PPC_IC_ENTRIES_PER_PAGE-1) << 2) | 3;
3030  uint64_t old_pc = addr;
3031  uint64_t new_pc = old_pc + (int32_t)tmp_addr;
3032  if ((old_pc & ~mask_within_page) ==
3033  (new_pc & ~mask_within_page)) {
3034  ic->f = samepage_function;
3035  ic->arg[0] = (size_t) (
3036  cpu->cd.ppc.cur_ic_page +
3037  ((new_pc & mask_within_page) >> 2));
3038  }
3039  }
3040  if (aa_bit) {
3041  if (lk_bit) {
3042  if (cpu->machine->show_trace_tree) {
3043  ic->f = instr(bla_trace);
3044  } else {
3045  ic->f = instr(bla);
3046  }
3047  } else {
3048  ic->f = instr(ba);
3049  }
3050  ic->arg[0] = (ssize_t)tmp_addr;
3051  }
3052  break;
3053 
3054  case PPC_HI6_19:
3055  xo = (iword >> 1) & 1023;
3056  switch (xo) {
3057 
3058  case PPC_19_BCLR:
3059  case PPC_19_BCCTR:
3060  bo = (iword >> 21) & 31;
3061  bi = (iword >> 16) & 31;
3062  bh = (iword >> 11) & 3;
3063  lk_bit = iword & 1;
3064  if (xo == PPC_19_BCLR) {
3065  if (lk_bit)
3066  ic->f = instr(bclr_l);
3067  else {
3068  ic->f = instr(bclr);
3069  if (!cpu->machine->show_trace_tree &&
3070  (bo & 0x14) == 0x14)
3071  ic->f = instr(bclr_20);
3072  }
3073  } else {
3074  if (!(bo & 4)) {
3075  if (!cpu->translation_readahead)
3076  fatal("TODO: bclr/bcctr "
3077  "bo bit 2 clear!\n");
3078  goto bad;
3079  }
3080  if (lk_bit)
3081  ic->f = instr(bcctr_l);
3082  else
3083  ic->f = instr(bcctr);
3084  }
3085  ic->arg[0] = bo;
3086  ic->arg[1] = 31 - bi;
3087  ic->arg[2] = bh;
3088  break;
3089 
3090  case PPC_19_ISYNC:
3091  /* TODO */
3092  ic->f = instr(nop);
3093  break;
3094 
3095  case PPC_19_RFI:
3096  ic->f = instr(rfi);
3097  break;
3098 
3099  case PPC_19_RFID:
3100  ic->f = instr(rfid);
3101  break;
3102 
3103  case PPC_19_MCRF:
3104  bf = (iword >> 23) & 7;
3105  bfa = (iword >> 18) & 7;
3106  ic->arg[0] = 28 - 4*bf;
3107  ic->arg[1] = 28 - 4*bfa;
3108  ic->f = instr(mcrf);
3109  break;
3110 
3111  case PPC_19_CRAND:
3112  case PPC_19_CRANDC:
3113  case PPC_19_CREQV:
3114  case PPC_19_CROR:
3115  case PPC_19_CRORC:
3116  case PPC_19_CRNOR:
3117  case PPC_19_CRXOR:
3118  switch (xo) {
3119  case PPC_19_CRAND: ic->f = instr(crand); break;
3120  case PPC_19_CRANDC: ic->f = instr(crandc); break;
3121  case PPC_19_CREQV: ic->f = instr(creqv); break;
3122  case PPC_19_CROR: ic->f = instr(cror); break;
3123  case PPC_19_CRORC: ic->f = instr(crorc); break;
3124  case PPC_19_CRNOR: ic->f = instr(crnor); break;
3125  case PPC_19_CRXOR: ic->f = instr(crxor); break;
3126  }
3127  ic->arg[0] = iword;
3128  break;
3129 
3130  default:goto bad;
3131  }
3132  break;
3133 
3134  case PPC_HI6_RLWNM:
3135  case PPC_HI6_RLWINM:
3136  ra = (iword >> 16) & 31;
3137  mb = (iword >> 6) & 31;
3138  me = (iword >> 1) & 31;
3139  rc = iword & 1;
3140  mask = 0;
3141  for (;;) {
3142  mask |= ((uint32_t)0x80000000 >> mb);
3143  if (mb == me)
3144  break;
3145  mb ++; mb &= 31;
3146  }
3147  switch (main_opcode) {
3148  case PPC_HI6_RLWNM:
3149  ic->f = rc? instr(rlwnm_dot) : instr(rlwnm); break;
3150  case PPC_HI6_RLWINM:
3151  ic->f = rc? instr(rlwinm_dot) : instr(rlwinm); break;
3152  }
3153  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3154  ic->arg[1] = mask;
3155  ic->arg[2] = (uint32_t)iword;
3156  break;
3157 
3158  case PPC_HI6_RLWIMI:
3159  rs = (iword >> 21) & 31;
3160  ra = (iword >> 16) & 31;
3161  ic->f = instr(rlwimi);
3162  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
3163  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3164  ic->arg[2] = (uint32_t)iword;
3165  break;
3166 
3167  case PPC_HI6_LMW:
3168  case PPC_HI6_STMW:
3169  /* NOTE: Loads use rt, not rs. */
3170  rs = (iword >> 21) & 31;
3171  ra = (iword >> 16) & 31;
3172  ic->arg[0] = rs;
3173  if (ra == 0)
3174  ic->arg[1] = (size_t)(&cpu->cd.ppc.zero);
3175  else
3176  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3177  ic->arg[2] = (int32_t)(int16_t)iword;
3178  switch (main_opcode) {
3179  case PPC_HI6_LMW:
3180  ic->f = instr(lmw);
3181  break;
3182  case PPC_HI6_STMW:
3183  ic->f = instr(stmw);
3184  break;
3185  }
3186  break;
3187 
3188  case PPC_HI6_30:
3189  xo = (iword >> 2) & 7;
3190  switch (xo) {
3191 
3192  case PPC_30_RLDICL:
3193  case PPC_30_RLDICR:
3194  case PPC_30_RLDIMI:
3195  switch (xo) {
3196  case PPC_30_RLDICL: ic->f = instr(rldicl); break;
3197  case PPC_30_RLDICR: ic->f = instr(rldicr); break;
3198  case PPC_30_RLDIMI: ic->f = instr(rldimi); break;
3199  }
3200  ic->arg[0] = iword;
3201  if (cpu->cd.ppc.bits == 32) {
3202  if (!cpu->translation_readahead)
3203  fatal("TODO: rld* in 32-bit mode?\n");
3204  goto bad;
3205  }
3206  break;
3207 
3208  default:goto bad;
3209  }
3210  break;
3211 
3212  case PPC_HI6_31:
3213  xo = (iword >> 1) & 1023;
3214  switch (xo) {
3215 
3216  case PPC_31_CMPL:
3217  case PPC_31_CMP:
3218  bf = (iword >> 23) & 7;
3219  l_bit = (iword >> 21) & 1;
3220  ra = (iword >> 16) & 31;
3221  rb = (iword >> 11) & 31;
3222  if (xo == PPC_31_CMPL) {
3223  if (l_bit)
3224  ic->f = instr(cmpld);
3225  else
3226  ic->f = instr(cmplw);
3227  } else {
3228  if (l_bit)
3229  ic->f = instr(cmpd);
3230  else {
3231  if (bf == 0)
3232  ic->f = instr(cmpw_cr0);
3233  else
3234  ic->f = instr(cmpw);
3235  }
3236  }
3237  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3238  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3239  ic->arg[2] = 28 - 4*bf;
3240  break;
3241 
3242  case PPC_31_CNTLZW:
3243  rs = (iword >> 21) & 31;
3244  ra = (iword >> 16) & 31;
3245  rc = iword & 1;
3246  if (rc) {
3247  if (!cpu->translation_readahead)
3248  fatal("TODO: rc\n");
3249  goto bad;
3250  }
3251  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
3252  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3253  ic->f = instr(cntlzw);
3254  break;
3255 
3256  case PPC_31_MFSPR:
3257  rt = (iword >> 21) & 31;
3258  spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
3259  debug_spr_usage(cpu->pc, spr);
3260  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rt]);
3261  ic->arg[1] = (size_t)(&cpu->cd.ppc.spr[spr]);
3262  switch (spr) {
3263  // Reuse SPR_TB* for TBR_TB*:
3264  case TBR_TBL: ic->f = instr(mftb); break;
3265  case TBR_TBU: ic->f = instr(mftbu); break;
3266  case SPR_PMC1: ic->f = instr(mfspr_pmc1); break;
3267  default: ic->f = instr(mfspr);
3268  }
3269  break;
3270 
3271  case PPC_31_MTSPR:
3272  rs = (iword >> 21) & 31;
3273  spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
3274  debug_spr_usage(cpu->pc, spr);
3275  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
3276  ic->arg[1] = (size_t)(&cpu->cd.ppc.spr[spr]);
3277  switch (spr) {
3278  case SPR_LR:
3279  ic->f = instr(mtlr);
3280  break;
3281  case SPR_CTR:
3282  ic->f = instr(mtctr);
3283  break;
3284  case SPR_SPRG2:
3285  ic->f = instr(mtspr_sprg2);
3286  break;
3287  default:ic->f = instr(mtspr);
3288  }
3289  break;
3290 
3291  case PPC_31_MFCR:
3292  rt = (iword >> 21) & 31;
3293  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rt]);
3294  ic->f = instr(mfcr);
3295  break;
3296 
3297  case PPC_31_MFMSR:
3298  rt = (iword >> 21) & 31;
3299  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rt]);
3300  ic->f = instr(mfmsr);
3301  break;
3302 
3303  case PPC_31_MTMSR:
3304  case PPC_31_MTMSRD:
3305  rs = (iword >> 21) & 31;
3306  l_bit = (iword >> 16) & 1;
3307  if (l_bit) {
3308  if (!cpu->translation_readahead)
3309  fatal("TODO: mtmsr l-bit\n");
3310  goto bad;
3311  }
3312  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
3313  ic->arg[1] = (addr & 0xfff) + 4;
3314  ic->arg[2] = xo == PPC_31_MTMSRD;
3315  ic->f = instr(mtmsr);
3316  break;
3317 
3318  case PPC_31_MTCRF:
3319  rs = (iword >> 21) & 31;
3320  {
3321  int i, fxm = (iword >> 12) & 255;
3322  uint32_t tmp = 0;
3323  for (i=0; i<8; i++, fxm <<= 1) {
3324  tmp <<= 4;
3325  if (fxm & 128)
3326  tmp |= 0xf;
3327  }
3328  ic->arg[1] = (uint32_t)tmp;
3329  }
3330  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
3331  ic->f = instr(mtcrf);
3332  break;
3333 
3334  case PPC_31_MFSRIN:
3335  case PPC_31_MTSRIN:
3336  rt = (iword >> 21) & 31;
3337  rb = (iword >> 11) & 31;
3338  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3339  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rt]);
3340  switch (xo) {
3341  case PPC_31_MFSRIN: ic->f = instr(mfsrin); break;
3342  case PPC_31_MTSRIN: ic->f = instr(mtsrin); break;
3343  }
3344  if (cpu->cd.ppc.bits == 64) {
3345  if (!cpu->translation_readahead)
3346  fatal("Not yet for 64-bit mode\n");
3347  goto bad;
3348  }
3349  break;
3350 
3351  case PPC_31_MFSR:
3352  case PPC_31_MTSR:
3353  rt = (iword >> 21) & 31;
3354  ic->arg[0] = (iword >> 16) & 15;
3355  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rt]);
3356  switch (xo) {
3357  case PPC_31_MFSR: ic->f = instr(mfsr); break;
3358  case PPC_31_MTSR: ic->f = instr(mtsr); break;
3359  }
3360  if (cpu->cd.ppc.bits == 64) {
3361  if (!cpu->translation_readahead)
3362  fatal("Not yet for 64-bit mode\n");
3363  goto bad;
3364  }
3365  break;
3366 
3367  case PPC_31_SRAWI:
3368  rs = (iword >> 21) & 31;
3369  ra = (iword >> 16) & 31;
3370  sh = (iword >> 11) & 31;
3371  rc = iword & 1;
3372  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
3373  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3374  ic->arg[2] = sh;
3375  if (rc)
3376  ic->f = instr(srawi_dot);
3377  else
3378  ic->f = instr(srawi);
3379  break;
3380 
3381  case PPC_31_SYNC:
3382  case PPC_31_DSSALL:
3383  case PPC_31_EIEIO:
3384  case PPC_31_DCBST:
3385  case PPC_31_DCBTST:
3386  case PPC_31_DCBF:
3387  case PPC_31_DCBT:
3388  case PPC_31_ICBI:
3389  ic->f = instr(nop);
3390  break;
3391 
3392  case PPC_31_DCBZ:
3393  ra = (iword >> 16) & 31;
3394  rb = (iword >> 11) & 31;
3395  if (ra == 0)
3396  ic->arg[0] = (size_t)(&cpu->cd.ppc.zero);
3397  else
3398  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3399  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3400  ic->arg[2] = addr & 0xfff;
3401  ic->f = instr(dcbz);
3402  break;
3403 
3404  case PPC_31_TLBIA:
3405  ic->f = instr(tlbia);
3406  break;
3407 
3408  case PPC_31_TLBSYNC:
3409  /* According to IBM, "Ensures that a tlbie and
3410  tlbia instruction executed by one processor has
3411  completed on all other processors.", which in
3412  GXemul means a nop :-) */
3413  ic->f = instr(nop);
3414  break;
3415 
3416  case PPC_31_TLBIE:
3417  /* TODO: POWER also uses ra? */
3418  rb = (iword >> 11) & 31;
3419  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3420  ic->f = instr(tlbie);
3421  break;
3422 
3423  case PPC_31_TLBLD: /* takes an arg */
3424  rb = (iword >> 11) & 31;
3425  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3426  ic->f = instr(tlbld);
3427  break;
3428 
3429  case PPC_31_TLBLI: /* takes an arg */
3430  rb = (iword >> 11) & 31;
3431  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3432  ic->f = instr(tlbli);
3433  break;
3434 
3435  case PPC_31_TLBSX_DOT:
3436  /* TODO */
3437  ic->f = instr(tlbsx_dot);
3438  break;
3439 
3440  case PPC_31_MFTB:
3441  rt = (iword >> 21) & 31;
3442  spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
3443  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rt]);
3444  switch (spr) {
3445  case 268: ic->f = instr(mftb); break;
3446  case 269: ic->f = instr(mftbu); break;
3447  default:if (!cpu->translation_readahead)
3448  fatal("mftb spr=%i?\n", spr);
3449  goto bad;
3450  }
3451  break;
3452 
3453  case PPC_31_NEG:
3454  rt = (iword >> 21) & 31;
3455  ra = (iword >> 16) & 31;
3456  rc = iword & 1;
3457  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3458  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rt]);
3459  if (rc)
3460  ic->f = instr(neg_dot);
3461  else
3462  ic->f = instr(neg);
3463  break;
3464 
3465  case PPC_31_LWARX:
3466  case PPC_31_LDARX:
3467  case PPC_31_STWCX_DOT:
3468  case PPC_31_STDCX_DOT:
3469  ic->arg[0] = iword;
3470  ic->f = instr(llsc);
3471  break;
3472 
3473  case PPC_31_LSWI:
3474  case PPC_31_STSWI:
3475  rs = (iword >> 21) & 31;
3476  ra = (iword >> 16) & 31;
3477  nb = (iword >> 11) & 31;
3478  ic->arg[0] = rs;
3479  if (ra == 0)
3480  ic->arg[1] = (size_t)(&cpu->cd.ppc.zero);
3481  else
3482  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3483  ic->arg[2] = nb == 0? 32 : nb;
3484  switch (xo) {
3485  case PPC_31_LSWI: ic->f = instr(lswi); break;
3486  case PPC_31_STSWI: ic->f = instr(stswi); break;
3487  }
3488  break;
3489 
3490  case PPC_31_WRTEEI:
3491  ic->arg[0] = iword & 0x8000;
3492  ic->f = instr(wrteei);
3493  break;
3494 
3495  case 0x1c3:
3496  fatal("[ mtdcr: TODO ]\n");
3497  ic->f = instr(nop);
3498  break;
3499 
3500  case PPC_31_LBZX:
3501  case PPC_31_LBZUX:
3502  case PPC_31_LHAX:
3503  case PPC_31_LHAUX:
3504  case PPC_31_LHZX:
3505  case PPC_31_LHZUX:
3506  case PPC_31_LWZX:
3507  case PPC_31_LWZUX:
3508  case PPC_31_LHBRX:
3509  case PPC_31_LWBRX:
3510  case PPC_31_LFDX:
3511  case PPC_31_LFSX:
3512  case PPC_31_STBX:
3513  case PPC_31_STBUX:
3514  case PPC_31_STHX:
3515  case PPC_31_STHUX:
3516  case PPC_31_STWX:
3517  case PPC_31_STWUX:
3518  case PPC_31_STDX:
3519  case PPC_31_STDUX:
3520  case PPC_31_STHBRX:
3521  case PPC_31_STWBRX:
3522  case PPC_31_STFDX:
3523  case PPC_31_STFSX:
3524  rs = (iword >> 21) & 31;
3525  ra = (iword >> 16) & 31;
3526  rb = (iword >> 11) & 31;
3527  if (ra == 0)
3528  ic->arg[1] = (size_t)(&cpu->cd.ppc.zero);
3529  else
3530  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3531  ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3532  load = 0; zero = 1; size = 0; update = 0;
3533  byterev = 0; fp = 0;
3534  ic->f = NULL;
3535  switch (xo) {
3536  case PPC_31_LBZX: load = 1; break;
3537  case PPC_31_LBZUX: load=update=1; break;
3538  case PPC_31_LHAX: size=1; load=1; zero=0; break;
3539  case PPC_31_LHAUX: size=1; load=update=1; zero=0; break;
3540  case PPC_31_LHZX: size=1; load=1; break;
3541  case PPC_31_LHZUX: size=1; load=update = 1; break;
3542  case PPC_31_LWZX: size=2; load=1; break;
3543  case PPC_31_LWZUX: size=2; load=update = 1; break;
3544  case PPC_31_LHBRX: size=1; load=1; byterev=1;
3545  ic->f = instr(lhbrx); break;
3546  case PPC_31_LWBRX: size=2; load=1; byterev=1;
3547  ic->f = instr(lwbrx); break;
3548  case PPC_31_LFDX: size=3; load=1; fp=1;
3549  ic->f = instr(lfdx); break;
3550  case PPC_31_LFSX: size=2; load=1; fp=1;
3551  ic->f = instr(lfsx); break;
3552  case PPC_31_STBX: break;
3553  case PPC_31_STBUX: update = 1; break;
3554  case PPC_31_STHX: size=1; break;
3555  case PPC_31_STHUX: size=1; update = 1; break;
3556  case PPC_31_STWX: size=2; break;
3557  case PPC_31_STWUX: size=2; update = 1; break;
3558  case PPC_31_STDX: size=3; break;
3559  case PPC_31_STDUX: size=3; update = 1; break;
3560  case PPC_31_STHBRX:size=1; byterev = 1;
3561  ic->f = instr(sthbrx); break;
3562  case PPC_31_STWBRX:size=2; byterev = 1;
3563  ic->f = instr(stwbrx); break;
3564  case PPC_31_STFDX: size=3; fp=1;
3565  ic->f = instr(stfdx); break;
3566  case PPC_31_STFSX: size=2; fp=1;
3567  ic->f = instr(stfsx); break;
3568  }
3569  if (fp)
3570  ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rs]);
3571  else
3572  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
3573  if (!byterev && ic->f == NULL) {
3574  ic->f =
3575 #ifdef MODE32
3576  ppc32_loadstore_indexed
3577 #else
3579 #endif
3580  [size + 4*zero + 8*load + 16*update];
3581  }
3582  if (ra == 0 && update) {
3583  if (!cpu->translation_readahead)
3584  fatal("TODO: ra=0 && update?\n");
3585  goto bad;
3586  }
3587  break;
3588 
3589  case PPC_31_EXTSB:
3590  case PPC_31_EXTSH:
3591  case PPC_31_EXTSW:
3592  case PPC_31_SLW:
3593  case PPC_31_SLD:
3594  case PPC_31_SRAW:
3595  case PPC_31_SRW:
3596  case PPC_31_AND:
3597  case PPC_31_NAND:
3598  case PPC_31_ANDC:
3599  case PPC_31_NOR:
3600  case PPC_31_OR:
3601  case PPC_31_ORC:
3602  case PPC_31_XOR:
3603  case PPC_31_EQV:
3604  rs = (iword >> 21) & 31;
3605  ra = (iword >> 16) & 31;
3606  rb = (iword >> 11) & 31;
3607  rc = iword & 1;
3608  rc_f = NULL;
3609  switch (xo) {
3610  case PPC_31_EXTSB:ic->f = instr(extsb);
3611  rc_f = instr(extsb_dot); break;
3612  case PPC_31_EXTSH:ic->f = instr(extsh);
3613  rc_f = instr(extsh_dot); break;
3614  case PPC_31_EXTSW:ic->f = instr(extsw);
3615  rc_f = instr(extsw_dot); break;
3616  case PPC_31_SLW: ic->f = instr(slw);
3617  rc_f = instr(slw_dot); break;
3618  case PPC_31_SLD: ic->f = instr(sld);
3619  rc_f = instr(sld_dot); break;
3620  case PPC_31_SRAW: ic->f = instr(sraw);
3621  rc_f = instr(sraw_dot); break;
3622  case PPC_31_SRW: ic->f = instr(srw);
3623  rc_f = instr(srw_dot); break;
3624  case PPC_31_AND: ic->f = instr(and);
3625  rc_f = instr(and_dot); break;
3626  case PPC_31_NAND: ic->f = instr(nand);
3627  rc_f = instr(nand_dot); break;
3628  case PPC_31_ANDC: ic->f = instr(andc);
3629  rc_f = instr(andc_dot); break;
3630  case PPC_31_NOR: ic->f = instr(nor);
3631  rc_f = instr(nor_dot); break;
3632  case PPC_31_OR: ic->f = rs == rb? instr(mr)
3633  : instr(or);
3634  rc_f = instr(or_dot); break;
3635  case PPC_31_ORC: ic->f = instr(orc);
3636  rc_f = instr(orc_dot); break;
3637  case PPC_31_XOR: ic->f = instr(xor);
3638  rc_f = instr(xor_dot); break;
3639  case PPC_31_EQV: ic->f = instr(eqv);
3640  rc_f = instr(eqv_dot); break;
3641  }
3642  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
3643  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3644  ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3645  if (rc)
3646  ic->f = rc_f;
3647  break;
3648 
3649  case PPC_31_MULLW:
3650  case PPC_31_MULHW:
3651  case PPC_31_MULHWU:
3652  case PPC_31_DIVW:
3653  case PPC_31_DIVWU:
3654  case PPC_31_ADD:
3655  case PPC_31_ADDC:
3656  case PPC_31_ADDE:
3657  case PPC_31_ADDME:
3658  case PPC_31_ADDZE:
3659  case PPC_31_SUBF:
3660  case PPC_31_SUBFC:
3661  case PPC_31_SUBFE:
3662  case PPC_31_SUBFME:
3663  case PPC_31_SUBFZE:
3664  rt = (iword >> 21) & 31;
3665  ra = (iword >> 16) & 31;
3666  rb = (iword >> 11) & 31;
3667  oe_bit = (iword >> 10) & 1;
3668  rc = iword & 1;
3669  if (oe_bit) {
3670  if (!cpu->translation_readahead)
3671  fatal("oe_bit not yet implemented\n");
3672  goto bad;
3673  }
3674  switch (xo) {
3675  case PPC_31_MULLW: ic->f = instr(mullw); break;
3676  case PPC_31_MULHW: ic->f = instr(mulhw); break;
3677  case PPC_31_MULHWU: ic->f = instr(mulhwu); break;
3678  case PPC_31_DIVW: ic->f = instr(divw); n64=1; break;
3679  case PPC_31_DIVWU: ic->f = instr(divwu); n64=1; break;
3680  case PPC_31_ADD: ic->f = instr(add); break;
3681  case PPC_31_ADDC: ic->f = instr(addc); n64=1; break;
3682  case PPC_31_ADDE: ic->f = instr(adde); n64=1; break;
3683  case PPC_31_ADDME: ic->f = instr(addme); n64=1; break;
3684  case PPC_31_ADDZE: ic->f = instr(addze); n64=1; break;
3685  case PPC_31_SUBF: ic->f = instr(subf); break;
3686  case PPC_31_SUBFC: ic->f = instr(subfc); break;
3687  case PPC_31_SUBFE: ic->f = instr(subfe); n64=1; break;
3688  case PPC_31_SUBFME: ic->f = instr(subfme); n64=1; break;
3689  case PPC_31_SUBFZE: ic->f = instr(subfze); n64=1;break;
3690  }
3691  if (rc) {
3692  switch (xo) {
3693  case PPC_31_ADD:
3694  ic->f = instr(add_dot); break;
3695  case PPC_31_ADDE:
3696  ic->f = instr(adde_dot); break;
3697  case PPC_31_ADDME:
3698  ic->f = instr(addme_dot); break;
3699  case PPC_31_ADDZE:
3700  ic->f = instr(addze_dot); break;
3701  case PPC_31_DIVW:
3702  ic->f = instr(divw_dot); break;
3703  case PPC_31_DIVWU:
3704  ic->f = instr(divwu_dot); break;
3705  case PPC_31_MULLW:
3706  ic->f = instr(mullw_dot); break;
3707  case PPC_31_MULHW:
3708  ic->f = instr(mulhw_dot); break;
3709  case PPC_31_MULHWU:
3710  ic->f = instr(mulhwu_dot); break;
3711  case PPC_31_SUBF:
3712  ic->f = instr(subf_dot); break;
3713  case PPC_31_SUBFC:
3714  ic->f = instr(subfc_dot); break;
3715  case PPC_31_SUBFE:
3716  ic->f = instr(subfe_dot); break;
3717  case PPC_31_SUBFME:
3718  ic->f = instr(subfme_dot); break;
3719  case PPC_31_SUBFZE:
3720  ic->f = instr(subfze_dot); break;
3721  default:if (!cpu->translation_readahead)
3722  fatal("RC bit not yet "
3723  "implemented\n");
3724  goto bad;
3725  }
3726  }
3727  ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3728  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3729  ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);
3730  if (cpu->cd.ppc.bits == 64 && n64) {
3731  if (!cpu->translation_readahead)
3732  fatal("Not yet for 64-bit mode\n");
3733  goto bad;
3734  }
3735  break;
3736 
3737  case PPC_31_LVX:
3738  case PPC_31_LVXL:
3739  case PPC_31_STVX:
3740  case PPC_31_STVXL:
3741  load = 0;
3742  switch (xo) {
3743  case PPC_31_LVX:
3744  case PPC_31_LVXL:
3745  load = 1; break;
3746  }
3747  rs = (iword >> 21) & 31;
3748  ra = (iword >> 16) & 31;
3749  rb = (iword >> 11) & 31;
3750  ic->arg[0] = rs;
3751  if (ra == 0)
3752  ic->arg[1] = (size_t)(&cpu->cd.ppc.zero);
3753  else
3754  ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3755  ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3756  ic->f = load? instr(lvx) : instr(stvx);
3757  break;
3758 
3759  default:goto bad;
3760  }
3761  break;
3762 
3763  case PPC_HI6_59:
3764  xo = (iword >> 1) & 1023;
3765  rt = (iword >> 21) & 31;
3766  ra = (iword >> 16) & 31;
3767  rb = (iword >> 11) & 31;
3768  rs = (iword >> 6) & 31; /* actually frc */
3769  rc = iword & 1;
3770 
3771  if (rc) {
3772  if (!cpu->translation_readahead)
3773  fatal("Floating point (59) "
3774  "with rc bit! TODO\n");
3775  goto bad;
3776  }
3777 
3778  /* NOTE: Some floating-point instructions are selected
3779  using only the lowest 5 bits, not all 10! */
3780  switch (xo & 31) {
3781  case PPC_59_FDIVS:
3782  case PPC_59_FSUBS:
3783  case PPC_59_FADDS:
3784  switch (xo & 31) {
3785  case PPC_59_FDIVS: ic->f = instr(fdivs); break;
3786  case PPC_59_FSUBS: ic->f = instr(fsubs); break;
3787  case PPC_59_FADDS: ic->f = instr(fadds); break;
3788  }
3789  ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[ra]);
3790  ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[rb]);
3791  ic->arg[2] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3792  break;
3793  case PPC_59_FMULS:
3794  ic->f = instr(fmuls);
3795  ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3796  ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[ra]);
3797  ic->arg[2] = (size_t)(&cpu->cd.ppc.fpr[rs]); /* frc */
3798  break;
3799  default:/* Use all 10 bits of xo: */
3800  switch (xo) {
3801  default:goto bad;
3802  }
3803  }
3804  break;
3805 
3806  case PPC_HI6_63:
3807  xo = (iword >> 1) & 1023;
3808  rt = (iword >> 21) & 31;
3809  ra = (iword >> 16) & 31;
3810  rb = (iword >> 11) & 31;
3811  rs = (iword >> 6) & 31; /* actually frc */
3812  rc = iword & 1;
3813 
3814  if (rc) {
3815  if (!cpu->translation_readahead)
3816  fatal("Floating point (63) "
3817  "with rc bit! TODO\n");
3818  goto bad;
3819  }
3820 
3821  /* NOTE: Some floating-point instructions are selected
3822  using only the lowest 5 bits, not all 10! */
3823  switch (xo & 31) {
3824  case PPC_63_FDIV:
3825  case PPC_63_FSUB:
3826  case PPC_63_FADD:
3827  switch (xo & 31) {
3828  case PPC_63_FDIV: ic->f = instr(fdiv); break;
3829  case PPC_63_FSUB: ic->f = instr(fsub); break;
3830  case PPC_63_FADD: ic->f = instr(fadd); break;
3831  }
3832  ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[ra]);
3833  ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[rb]);
3834  ic->arg[2] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3835  break;
3836  case PPC_63_FMUL:
3837  ic->f = instr(fmul);
3838  ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3839  ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[ra]);
3840  ic->arg[2] = (size_t)(&cpu->cd.ppc.fpr[rs]); /* frc */
3841  break;
3842  case PPC_63_FMSUB:
3843  case PPC_63_FMADD:
3844  switch (xo & 31) {
3845  case PPC_63_FMSUB: ic->f = instr(fmsub); break;
3846  case PPC_63_FMADD: ic->f = instr(fmadd); break;
3847  }
3848  ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3849  ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[ra]);
3850  ic->arg[2] = iword;
3851  break;
3852  default:/* Use all 10 bits of xo: */
3853  switch (xo) {
3854  case PPC_63_FCMPU:
3855  ic->f = instr(fcmpu);
3856  ic->arg[0] = 28 - 4*(rt >> 2);
3857  ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[ra]);
3858  ic->arg[2] = (size_t)(&cpu->cd.ppc.fpr[rb]);
3859  break;
3860  case PPC_63_FRSP:
3861  case PPC_63_FCTIWZ:
3862  case PPC_63_FNEG:
3863  case PPC_63_FABS:
3864  case PPC_63_FMR:
3865  switch (xo) {
3866  case PPC_63_FRSP: ic->f = instr(frsp); break;
3867  case PPC_63_FCTIWZ: ic->f = instr(fctiwz);break;
3868  case PPC_63_FNEG: ic->f = instr(fneg); break;
3869  case PPC_63_FABS: ic->f = instr(fabs); break;
3870  case PPC_63_FMR: ic->f = instr(fmr); break;
3871  }
3872  ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rb]);
3873  ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3874  break;
3875  case PPC_63_MFFS:
3876  ic->f = instr(mffs);
3877  ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3878  break;
3879  case PPC_63_MTFSF:
3880  ic->f = instr(mtfsf);
3881  ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rb]);
3882  ic->arg[1] = 0;
3883  for (bi=7; bi>=0; bi--) {
3884  ic->arg[1] <<= 8;
3885  if (iword & (1 << (17+bi)))
3886  ic->arg[1] |= 0xf;
3887  }
3888  break;
3889  default:goto bad;
3890  }
3891  }
3892  break;
3893 
3894  default:goto bad;
3895  }
3896 
3897 
3898 #define DYNTRANS_TO_BE_TRANSLATED_TAIL
3899 #include "cpu_dyntrans.cc"
3900 #undef DYNTRANS_TO_BE_TRANSLATED_TAIL
3901 }
3902 
PPC_HI6_STHU
#define PPC_HI6_STHU
Definition: opcodes_ppc.h:214
PPC_63_MTFSF
#define PPC_63_MTFSF
Definition: opcodes_ppc.h:249
PPC_31_SLD
#define PPC_31_SLD
Definition: opcodes_ppc.h:90
PPC_31_STHUX
#define PPC_31_STHUX
Definition: opcodes_ppc.h:147
PPC_31_MTCRF
#define PPC_31_MTCRF
Definition: opcodes_ppc.h:110
data
u_short data
Definition: siireg.h:79
instr
#define instr(n)
Definition: tmp_alpha_head.cc:43
PPC_31_NEG
#define PPC_31_NEG
Definition: opcodes_ppc.h:104
PPC_HI6_BC
#define PPC_HI6_BC
Definition: opcodes_ppc.h:46
PPC_31_EIEIO
#define PPC_31_EIEIO
Definition: opcodes_ppc.h:188
PPC_19_CRORC
#define PPC_19_CRORC
Definition: opcodes_ppc.h:62
PPC_HI6_59
#define PPC_HI6_59
Definition: opcodes_ppc.h:226
DOT2
#define DOT2(n)
Definition: cpu_ppc_instr.cc:44
PPC_63_MFFS
#define PPC_63_MFFS
Definition: opcodes_ppc.h:248
PPC_31_DSSALL
#define PPC_31_DSSALL
Definition: opcodes_ppc.h:186
PPC_31_MULHW
#define PPC_31_MULHW
Definition: opcodes_ppc.h:98
PPC_19_CREQV
#define PPC_19_CREQV
Definition: opcodes_ppc.h:61
PPC_HI6_LMW
#define PPC_HI6_LMW
Definition: opcodes_ppc.h:215
PPC_63_FCTIWZ
#define PPC_63_FCTIWZ
Definition: opcodes_ppc.h:237
cpu_dyntrans.cc
PPC_63_FRSP
#define PPC_63_FRSP
Definition: opcodes_ppc.h:236
ppc_loadstore_indexed
void(* ppc_loadstore_indexed[32])(struct cpu *, struct ppc_instr_call *)
Definition: tmp_ppc_loadstore.cc:962
PPC_HI6_ORIS
#define PPC_HI6_ORIS
Definition: opcodes_ppc.h:70
PPC_HI6_STMW
#define PPC_HI6_STMW
Definition: opcodes_ppc.h:216
PPC_HI6_LFD
#define PPC_HI6_LFD
Definition: opcodes_ppc.h:219
cpu::running
uint8_t running
Definition: cpu.h:353
PPC_63_FADD
#define PPC_63_FADD
Definition: opcodes_ppc.h:240
PPC_HI6_STB
#define PPC_HI6_STB
Definition: opcodes_ppc.h:207
TBR_TBU
#define TBR_TBU
Definition: ppc_spr.h:497
PPC_HI6_LWZU
#define PPC_HI6_LWZU
Definition: opcodes_ppc.h:202
PPC_31_SUBFE
#define PPC_31_SUBFE
Definition: opcodes_ppc.h:108
PPC_31_SRAWI
#define PPC_31_SRAWI
Definition: opcodes_ppc.h:187
PPC_19_CRANDC
#define PPC_19_CRANDC
Definition: opcodes_ppc.h:56
PPC_XER_CA
#define PPC_XER_CA
Definition: cpu_ppc.h:199
PPC_31_LVX
#define PPC_31_LVX
Definition: opcodes_ppc.h:103
PPC_19_RFI
#define PPC_19_RFI
Definition: opcodes_ppc.h:54
ppc_cpu::ll_bit
int ll_bit
Definition: cpu_ppc.h:137
PPC_31_MFSPR
#define PPC_31_MFSPR
Definition: opcodes_ppc.h:138
PPC_31_DCBT
#define PPC_31_DCBT
Definition: opcodes_ppc.h:132
PPC_63_FSUB
#define PPC_63_FSUB
Definition: opcodes_ppc.h:239
machine::cpus
struct cpu ** cpus
Definition: machine.h:140
PPC_31_STDX
#define PPC_31_STDX
Definition: opcodes_ppc.h:112
PPC_31_STBX
#define PPC_31_STBX
Definition: opcodes_ppc.h:123
PPC_31_LDARX
#define PPC_31_LDARX
Definition: opcodes_ppc.h:100
cpu_functioncall_trace_return
void cpu_functioncall_trace_return(struct cpu *cpu)
Definition: cpu.cc:284
cpu::n_translated_instrs
int n_translated_instrs
Definition: cpu.h:430
PPC_31_ICBI
#define PPC_31_ICBI
Definition: opcodes_ppc.h:196
PPC_19_RFID
#define PPC_19_RFID
Definition: opcodes_ppc.h:52
PPC_31_DCBF
#define PPC_31_DCBF
Definition: opcodes_ppc.h:101
SPR_LR
#define SPR_LR
Definition: ppc_spr.h:40
PPC_63_FCMPU
#define PPC_63_FCMPU
Definition: opcodes_ppc.h:235
machine::show_trace_tree
int show_trace_tree
Definition: machine.h:164
PPC_31_TLBLI
#define PPC_31_TLBLI
Definition: opcodes_ppc.h:199
SPR_CTR
#define SPR_CTR
Definition: ppc_spr.h:41
if
addr & if(addr >=0x24 &&page !=NULL)
Definition: tmp_arm_multi.cc:56
PPC_HI6_STFS
#define PPC_HI6_STFS
Definition: opcodes_ppc.h:221
PPC_31_LSWI
#define PPC_31_LSWI
Definition: opcodes_ppc.h:166
ieee_interpret_float_value
void ieee_interpret_float_value(uint64_t x, struct ieee_float_value *fvp, int fmt)
Definition: float_emul.cc:49
PPC_31_SRW
#define PPC_31_SRW
Definition: opcodes_ppc.h:162
DYNTRANS_L1N
#define DYNTRANS_L1N
Definition: cpu.h:222
PPC_31_ADDME
#define PPC_31_ADDME
Definition: opcodes_ppc.h:126
of_emul
int of_emul(struct cpu *cpu)
Definition: of.cc:1078
PPC_31_LFDX
#define PPC_31_LFDX
Definition: opcodes_ppc.h:168
CHECK_FOR_FPU_EXCEPTION
#define CHECK_FOR_FPU_EXCEPTION
Definition: cpu_ppc_instr.cc:48
PPC_31_STSWI
#define PPC_31_STSWI
Definition: opcodes_ppc.h:178
PPC_31_NAND
#define PPC_31_NAND
Definition: opcodes_ppc.h:153
MEM_READ
#define MEM_READ
Definition: memory.h:116
cpu::byte_order
uint8_t byte_order
Definition: cpu.h:347
EMUL_BIG_ENDIAN
#define EMUL_BIG_ENDIAN
Definition: misc.h:165
cpu_functioncall_trace
void cpu_functioncall_trace(struct cpu *cpu, uint64_t f)
Definition: cpu.cc:228
PPC_30_RLDICR
#define PPC_30_RLDICR
Definition: opcodes_ppc.h:77
PPC_HI6_STFD
#define PPC_HI6_STFD
Definition: opcodes_ppc.h:223
PPC_31_DCBST
#define PPC_31_DCBST
Definition: opcodes_ppc.h:94
DOT0
#define DOT0(n)
Definition: cpu_ppc_instr.cc:40
INVALIDATE_VADDR_UPPER4
#define INVALIDATE_VADDR_UPPER4
Definition: cpu.h:484
SPR_TBU
#define SPR_TBU
Definition: ppc_spr.h:74
addr
uint32_t addr
Definition: tmp_arm_multi.cc:52
reg_access_msr
void reg_access_msr(struct cpu *cpu, uint64_t *valuep, int writeflag, int check_for_interrupts)
Definition: cpu_ppc.cc:299
PPC_HI6_LHAU
#define PPC_HI6_LHAU
Definition: opcodes_ppc.h:212
PPC_31_STVX
#define PPC_31_STVX
Definition: opcodes_ppc.h:124
PPC_HI6_63
#define PPC_HI6_63
Definition: opcodes_ppc.h:234
SPR_SRR0
#define SPR_SRR0
Definition: ppc_spr.h:56
IEEE_FMT_D
#define IEEE_FMT_D
Definition: float_emul.h:44
PPC_31_STDUX
#define PPC_31_STDUX
Definition: opcodes_ppc.h:117
PPC_31_ANDC
#define PPC_31_ANDC
Definition: opcodes_ppc.h:96
PPC_31_STWCX_DOT
#define PPC_31_STWCX_DOT
Definition: opcodes_ppc.h:113
SPR_PMC1
#define SPR_PMC1
Definition: ppc_spr.h:270
BE32_TO_HOST
#define BE32_TO_HOST(x)
Definition: misc.h:181
PPC_XER_SO
#define PPC_XER_SO
Definition: cpu_ppc.h:197
PPC_31_LHAUX
#define PPC_31_LHAUX
Definition: opcodes_ppc.h:143
PPC_HI6_RLWNM
#define PPC_HI6_RLWNM
Definition: opcodes_ppc.h:68
PPC_31_MFMSR
#define PPC_31_MFMSR
Definition: opcodes_ppc.h:99
ppc_cpu::msr
uint64_t msr
Definition: cpu_ppc.h:130
PPC_31_LFSX
#define PPC_31_LFSX
Definition: opcodes_ppc.h:161
PPC_19_CRAND
#define PPC_19_CRAND
Definition: opcodes_ppc.h:60
PPC_31_STFSX
#define PPC_31_STFSX
Definition: opcodes_ppc.h:175
MEM_WRITE
#define MEM_WRITE
Definition: memory.h:117
SPR_SPRG2
#define SPR_SPRG2
Definition: ppc_spr.h:65
PPC_HI6_RLWINM
#define PPC_HI6_RLWINM
Definition: opcodes_ppc.h:66
ppc_exception
void ppc_exception(struct cpu *cpu, int exception_nr)
Definition: cpu_ppc.cc:352
PPC_63_FDIV
#define PPC_63_FDIV
Definition: opcodes_ppc.h:238
PPC_63_FMADD
#define PPC_63_FMADD
Definition: opcodes_ppc.h:243
PPC_31_MTMSR
#define PPC_31_MTMSR
Definition: opcodes_ppc.h:111
PPC_FPSCR_FPCC_SHIFT
#define PPC_FPSCR_FPCC_SHIFT
Definition: cpu_ppc.h:182
PPC_63_FMR
#define PPC_63_FMR
Definition: opcodes_ppc.h:245
PPC_31_STBUX
#define PPC_31_STBUX
Definition: opcodes_ppc.h:130
PPC_31_DIVWU
#define PPC_31_DIVWU
Definition: opcodes_ppc.h:150
PPC_HI6_ADDIC
#define PPC_HI6_ADDIC
Definition: opcodes_ppc.h:42
PPC_HI6_ADDI
#define PPC_HI6_ADDI
Definition: opcodes_ppc.h:44
PPC_31_SYNC
#define PPC_31_SYNC
Definition: opcodes_ppc.h:167
ppc_cpu::vr_lo
uint64_t vr_lo[PPC_NVRS]
Definition: cpu_ppc.h:128
MEMORY_ACCESS_OK
#define MEMORY_ACCESS_OK
Definition: memory.h:141
PPC_HI6_STW
#define PPC_HI6_STW
Definition: opcodes_ppc.h:205
INVALIDATE_VADDR
#define INVALIDATE_VADDR
Definition: cpu.h:483
ppc_cpu::sr
uint32_t sr[16]
Definition: cpu_ppc.h:133
PPC_31_TLBIE
#define PPC_31_TLBIE
Definition: opcodes_ppc.h:135
ieee_store_float_value
uint64_t ieee_store_float_value(double nf, int fmt)
Definition: float_emul.cc:238
PPC_31_STHX
#define PPC_31_STHX
Definition: opcodes_ppc.h:144
PPC_HI6_LBZ
#define PPC_HI6_LBZ
Definition: opcodes_ppc.h:203
PPC_HI6_XORI
#define PPC_HI6_XORI
Definition: opcodes_ppc.h:71
PPC_31_EXTSH
#define PPC_31_EXTSH
Definition: opcodes_ppc.h:191
PPC_63_FMUL
#define PPC_63_FMUL
Definition: opcodes_ppc.h:241
fatal
void fatal(const char *fmt,...)
Definition: main.cc:152
SPR_TBL
#define SPR_TBL
Definition: ppc_spr.h:73
PPC_HI6_30
#define PPC_HI6_30
Definition: opcodes_ppc.h:75
PPC_HI6_ADDIS
#define PPC_HI6_ADDIS
Definition: opcodes_ppc.h:45
PPC_FPSCR_FPCC
#define PPC_FPSCR_FPCC
Definition: cpu_ppc.h:181
ppc_cpu::cr
uint32_t cr
Definition: cpu_ppc.h:122
PPC_31_MULLW
#define PPC_31_MULLW
Definition: opcodes_ppc.h:127
PPC_30_RLDIMI
#define PPC_30_RLDIMI
Definition: opcodes_ppc.h:78
PPC_HI6_ADDIC_DOT
#define PPC_HI6_ADDIC_DOT
Definition: opcodes_ppc.h:43
PPC_HI6_STBU
#define PPC_HI6_STBU
Definition: opcodes_ppc.h:208
TBR_TBL
#define TBR_TBL
Definition: ppc_spr.h:496
PPC_31_LHAX
#define PPC_31_LHAX
Definition: opcodes_ppc.h:139
DOT1
#define DOT1(n)
Definition: cpu_ppc_instr.cc:42
PPC_19_CROR
#define PPC_19_CROR
Definition: opcodes_ppc.h:63
PPC_HI6_LBZU
#define PPC_HI6_LBZU
Definition: opcodes_ppc.h:204
ppc_loadstore
void(* ppc_loadstore[64])(struct cpu *, struct ppc_instr_call *)
Definition: tmp_ppc_loadstore.cc:893
ieee_float_value::nan
int nan
Definition: float_emul.h:40
PPC_31_ADDZE
#define PPC_31_ADDZE
Definition: opcodes_ppc.h:120
PPC_31_ADD
#define PPC_31_ADD
Definition: opcodes_ppc.h:131
PPC_31_STFDX
#define PPC_31_STFDX
Definition: opcodes_ppc.h:179
cpu::cd
union cpu::@1 cd
page
page
Definition: tmp_arm_multi.cc:54
PPC_31_LWZX
#define PPC_31_LWZX
Definition: opcodes_ppc.h:87
PPC_HI6_ANDIS_DOT
#define PPC_HI6_ANDIS_DOT
Definition: opcodes_ppc.h:74
PPC_31_LHZX
#define PPC_31_LHZX
Definition: opcodes_ppc.h:133
PPC_31_MTSPR
#define PPC_31_MTSPR
Definition: opcodes_ppc.h:151
PPC_31_MTSRIN
#define PPC_31_MTSRIN
Definition: opcodes_ppc.h:128
PPC_59_FSUBS
#define PPC_59_FSUBS
Definition: opcodes_ppc.h:228
PPC_31_EQV
#define PPC_31_EQV
Definition: opcodes_ppc.h:134
ic
struct arm_instr_call * ic
Definition: tmp_arm_multi.cc:50
CACHE_INSTRUCTION
#define CACHE_INSTRUCTION
Definition: memory.h:122
PPC_31_TLBIA
#define PPC_31_TLBIA
Definition: opcodes_ppc.h:141
PPC_19_MCRF
#define PPC_19_MCRF
Definition: opcodes_ppc.h:50
update_cr0
void update_cr0(struct cpu *cpu, uint64_t value)
Definition: cpu_ppc.cc:1833
ieee_float_value
Definition: float_emul.h:38
PPC_19_BCCTR
#define PPC_19_BCCTR
Definition: opcodes_ppc.h:64
CACHE_DATA
#define CACHE_DATA
Definition: memory.h:121
PPC_59_FADDS
#define PPC_59_FADDS
Definition: opcodes_ppc.h:229
PPC_19_CRXOR
#define PPC_19_CRXOR
Definition: opcodes_ppc.h:58
PPC_19_ISYNC
#define PPC_19_ISYNC
Definition: opcodes_ppc.h:57
PPC_MSR_SF
#define PPC_MSR_SF
Definition: cpu_ppc.h:152
PPC_HI6_RLWIMI
#define PPC_HI6_RLWIMI
Definition: opcodes_ppc.h:65
PPC_31_STDCX_DOT
#define PPC_31_STDCX_DOT
Definition: opcodes_ppc.h:122
cpu::invalidate_translation_caches
void(* invalidate_translation_caches)(struct cpu *, uint64_t paddr, int flags)
Definition: cpu.h:377
INVALIDATE_ALL
#define INVALIDATE_ALL
Definition: cpu.h:481
PPC_30_RLDICL
#define PPC_30_RLDICL
Definition: opcodes_ppc.h:76
ppc_cpu::fpr
uint64_t fpr[PPC_NFPRS]
Definition: cpu_ppc.h:125
PPC_31_SUBFC
#define PPC_31_SUBFC
Definition: opcodes_ppc.h:82
PPC_31_ADDE
#define PPC_31_ADDE
Definition: opcodes_ppc.h:109
float_emul.h
DYNTRANS_L2N
#define DYNTRANS_L2N
Definition: tmp_alpha_head.cc:10
PPC_HI6_19
#define PPC_HI6_19
Definition: opcodes_ppc.h:49
PPC_31_CMP
#define PPC_31_CMP
Definition: opcodes_ppc.h:80
PPC_31_SUBF
#define PPC_31_SUBF
Definition: opcodes_ppc.h:93
PPC_HI6_STH
#define PPC_HI6_STH
Definition: opcodes_ppc.h:213
PPC_59_FDIVS
#define PPC_59_FDIVS
Definition: opcodes_ppc.h:227
cpu::ppc
struct ppc_cpu ppc
Definition: cpu.h:447
cpu::mem
struct memory * mem
Definition: cpu.h:362
PPC_HI6_B
#define PPC_HI6_B
Definition: opcodes_ppc.h:48
debugger_n_steps_left_before_interaction
int debugger_n_steps_left_before_interaction
Definition: debugger.cc:73
PPC_31_STWBRX
#define PPC_31_STWBRX
Definition: opcodes_ppc.h:174
PPC_63_FNEG
#define PPC_63_FNEG
Definition: opcodes_ppc.h:244
DYNTRANS_L3N
#define DYNTRANS_L3N
Definition: tmp_alpha_head.cc:11
PPC_59_FMULS
#define PPC_59_FMULS
Definition: opcodes_ppc.h:230
PPC_31_MFSR
#define PPC_31_MFSR
Definition: opcodes_ppc.h:165
MODE_POWER
#define MODE_POWER
Definition: cpu_ppc.h:40
ieee_float_value::f
double f
Definition: float_emul.h:39
cpu::machine
struct machine * machine
Definition: cpu.h:328
PPC_HI6_MULLI
#define PPC_HI6_MULLI
Definition: opcodes_ppc.h:37
PPC_63_FMSUB
#define PPC_63_FMSUB
Definition: opcodes_ppc.h:242
PPC_HI6_LD
#define PPC_HI6_LD
Definition: opcodes_ppc.h:225
IEEE_FMT_S
#define IEEE_FMT_S
Definition: float_emul.h:43
reg
#define reg(x)
Definition: tmp_alpha_tail.cc:53
ori
void COMBINE() ori(struct cpu *cpu, struct mips_instr_call *ic, int low_addr)
Definition: cpu_mips_instr.cc:3462
PPC_31_SUBFZE
#define PPC_31_SUBFZE
Definition: opcodes_ppc.h:119
ppc_cpu::fpscr
uint32_t fpscr
Definition: cpu_ppc.h:123
PPC_FPSCR_VXNAN
#define PPC_FPSCR_VXNAN
Definition: cpu_ppc.h:179
PPC_31_TLBSX_DOT
#define PPC_31_TLBSX_DOT
Definition: opcodes_ppc.h:189
SPR_XER
#define SPR_XER
Definition: ppc_spr.h:37
PPC_31_XOR
#define PPC_31_XOR
Definition: opcodes_ppc.h:137
nop
void COMBINE() nop(struct cpu *cpu, struct mips_instr_call *ic, int low_addr)
Definition: cpu_mips_instr.cc:3365
tmp_ppc_loadstore.cc
PPC_HI6_ORI
#define PPC_HI6_ORI
Definition: opcodes_ppc.h:69
PPC_31_MTMSRD
#define PPC_31_MTMSRD
Definition: opcodes_ppc.h:116
DYNTRANS_L3_64_TABLE
#define DYNTRANS_L3_64_TABLE
Definition: tmp_alpha_head.cc:16
PPC_31_CNTLZW
#define PPC_31_CNTLZW
Definition: opcodes_ppc.h:89
PPC_31_MFCR
#define PPC_31_MFCR
Definition: opcodes_ppc.h:85
ppc_cpu::ll_addr
uint64_t ll_addr
Definition: cpu_ppc.h:136
PPC_HI6_SC
#define PPC_HI6_SC
Definition: opcodes_ppc.h:47
PPC_HI6_STD
#define PPC_HI6_STD
Definition: opcodes_ppc.h:233
PPC_HI6_LHZ
#define PPC_HI6_LHZ
Definition: opcodes_ppc.h:209
PPC_31_DIVW
#define PPC_31_DIVW
Definition: opcodes_ppc.h:155
PPC_31_LWBRX
#define PPC_31_LWBRX
Definition: opcodes_ppc.h:160
PPC_31_MULHWU
#define PPC_31_MULHWU
Definition: opcodes_ppc.h:84
ppc_cpu::mode
int mode
Definition: cpu_ppc.h:115
SPR_SRR1
#define SPR_SRR1
Definition: ppc_spr.h:57
PPC_HI6_ANDI_DOT
#define PPC_HI6_ANDI_DOT
Definition: opcodes_ppc.h:73
PPC_31_ORC
#define PPC_31_ORC
Definition: opcodes_ppc.h:145
PPC_31_STVXL
#define PPC_31_STVXL
Definition: opcodes_ppc.h:154
PPC_31_OR
#define PPC_31_OR
Definition: opcodes_ppc.h:148
PPC_31_MFTB
#define PPC_31_MFTB
Definition: opcodes_ppc.h:142
PPC_31_EXTSW
#define PPC_31_EXTSW
Definition: opcodes_ppc.h:197
PPC_19_BCLR
#define PPC_19_BCLR
Definition: opcodes_ppc.h:51
PPC_HI6_CMPI
#define PPC_HI6_CMPI
Definition: opcodes_ppc.h:41
ppc_cpu::bits
int bits
Definition: cpu_ppc.h:116
PPC_31_LBZX
#define PPC_31_LBZX
Definition: opcodes_ppc.h:102
PPC_EXCEPTION_SC
#define PPC_EXCEPTION_SC
Definition: cpu_ppc.h:194
PPC_HI6_STWU
#define PPC_HI6_STWU
Definition: opcodes_ppc.h:206
PPC_HI6_XORIS
#define PPC_HI6_XORIS
Definition: opcodes_ppc.h:72
PPC_31_NOR
#define PPC_31_NOR
Definition: opcodes_ppc.h:107
machine::emulated_hz
int emulated_hz
Definition: machine.h:165
ppc_cpu::gpr
uint64_t gpr[PPC_NGPRS]
Definition: cpu_ppc.h:124
PPC_31_STHBRX
#define PPC_31_STHBRX
Definition: opcodes_ppc.h:190
PPC_31_EXTSB
#define PPC_31_EXTSB
Definition: opcodes_ppc.h:192
ppc_cpu::cpu_type
struct ppc_cpu_type_def cpu_type
Definition: cpu_ppc.h:111
quick_pc_to_pointers
#define quick_pc_to_pointers(cpu)
Definition: quick_pc_to_pointers.h:29
PPC_31_DCBZ
#define PPC_31_DCBZ
Definition: opcodes_ppc.h:200
PPC_31_LWARX
#define PPC_31_LWARX
Definition: opcodes_ppc.h:86
PPC_IC_ENTRIES_PER_PAGE
#define PPC_IC_ENTRIES_PER_PAGE
Definition: cpu_ppc.h:95
PPC_63_FABS
#define PPC_63_FABS
Definition: opcodes_ppc.h:247
PPC_31_CMPL
#define PPC_31_CMPL
Definition: opcodes_ppc.h:92
PPC_31_STWUX
#define PPC_31_STWUX
Definition: opcodes_ppc.h:118
PPC_31_TLBSYNC
#define PPC_31_TLBSYNC
Definition: opcodes_ppc.h:164
cpu::translation_readahead
int translation_readahead
Definition: cpu.h:427
PPC_HI6_31
#define PPC_HI6_31
Definition: opcodes_ppc.h:79
PPC_MSR_FP
#define PPC_MSR_FP
Definition: cpu_ppc.h:161
PPC_31_LVXL
#define PPC_31_LVXL
Definition: opcodes_ppc.h:140
PPC_31_STWX
#define PPC_31_STWX
Definition: opcodes_ppc.h:114
cpu
Definition: cpu.h:326
ppc_cpu::vr_hi
uint64_t vr_hi[PPC_NVRS]
Definition: cpu_ppc.h:127
ppc_cpu_type_def::dlinesize
int dlinesize
Definition: cpu_ppc.h:52
PPC_31_DCBTST
#define PPC_31_DCBTST
Definition: opcodes_ppc.h:129
PPC_31_MTSR
#define PPC_31_MTSR
Definition: opcodes_ppc.h:121
PPC_HI6_SUBFIC
#define PPC_HI6_SUBFIC
Definition: opcodes_ppc.h:38
PPC_HI6_LHZU
#define PPC_HI6_LHZU
Definition: opcodes_ppc.h:210
PPC_31_SUBFME
#define PPC_31_SUBFME
Definition: opcodes_ppc.h:125
ppc_cpu::spr
uint64_t spr[1024]
Definition: cpu_ppc.h:134
PPC_31_LWZUX
#define PPC_31_LWZUX
Definition: opcodes_ppc.h:95
DYNTRANS_L2_64_TABLE
#define DYNTRANS_L2_64_TABLE
Definition: tmp_alpha_head.cc:15
PPC_31_LHZUX
#define PPC_31_LHZUX
Definition: opcodes_ppc.h:136
PPC_INSTR_ALIGNMENT_SHIFT
#define PPC_INSTR_ALIGNMENT_SHIFT
Definition: cpu_ppc.h:93
cpu::memory_rw
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:368
PPC_EXCEPTION_FPU
#define PPC_EXCEPTION_FPU
Definition: cpu_ppc.h:192
PPC_31_AND
#define PPC_31_AND
Definition: opcodes_ppc.h:91
PPC_HI6_LHA
#define PPC_HI6_LHA
Definition: opcodes_ppc.h:211
load
void load(FILE *fh, unsigned char *ptr, unsigned long sz)
Definition: dreamcast_scramble.cc:33
PPC_HI6_LFS
#define PPC_HI6_LFS
Definition: opcodes_ppc.h:217
PPC_HI6_LWZ
#define PPC_HI6_LWZ
Definition: opcodes_ppc.h:201
PPC_19_CRNOR
#define PPC_19_CRNOR
Definition: opcodes_ppc.h:53
cpu::pc
uint64_t pc
Definition: cpu.h:386
PPC_31_TLBLD
#define PPC_31_TLBLD
Definition: opcodes_ppc.h:195
PPC_31_LHBRX
#define PPC_31_LHBRX
Definition: opcodes_ppc.h:184
PPC_31_ADDC
#define PPC_31_ADDC
Definition: opcodes_ppc.h:83
PPC_31_WRTEEI
#define PPC_31_WRTEEI
Definition: opcodes_ppc.h:115
MODE_uint_t
#define MODE_uint_t
Definition: tmp_alpha_tail.cc:54
ppc_cpu::zero
uint64_t zero
Definition: cpu_ppc.h:120
PPC_31_SLW
#define PPC_31_SLW
Definition: opcodes_ppc.h:88
PPC_31_MFSRIN
#define PPC_31_MFSRIN
Definition: opcodes_ppc.h:173
PPC_31_SRAW
#define PPC_31_SRAW
Definition: opcodes_ppc.h:185
PPC_HI6_CMPLI
#define PPC_HI6_CMPLI
Definition: opcodes_ppc.h:40
PPC_31_LBZUX
#define PPC_31_LBZUX
Definition: opcodes_ppc.h:106
machine::ncpus
int ncpus
Definition: machine.h:139
X
X(nop)
Definition: cpu_ppc_instr.cc:65

Generated on Tue Aug 25 2020 19:25:06 for GXemul by doxygen 1.8.18