/[gxemul]/upstream/0.3.5/src/cpu_ppc_instr.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /upstream/0.3.5/src/cpu_ppc_instr.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 13 - (show annotations)
Mon Oct 8 16:18:43 2007 UTC (16 years, 8 months ago) by dpavlin
File MIME type: text/plain
File size: 38974 byte(s)
0.3.5
1 /*
2 * Copyright (C) 2005 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 * $Id: cpu_ppc_instr.c,v 1.28 2005/08/14 23:44:22 debug Exp $
29 *
30 * POWER/PowerPC instructions.
31 *
32 * Individual functions should keep track of cpu->n_translated_instrs.
33 * (If no instruction was executed, then it should be decreased. If, say, 4
34 * instructions were combined into one function and executed, then it should
35 * be increased by 3.)
36 */
37
38
39 /*
40 * nop: Do nothing.
41 */
42 X(nop)
43 {
44 }
45
46
47 /*
48 * invalid: To catch bugs.
49 */
50 X(invalid)
51 {
52 fatal("INTERNAL ERROR\n");
53 exit(1);
54 }
55
56
57 /*
58 * addi: Add immediate.
59 *
60 * arg[0] = pointer to source uint64_t
61 * arg[1] = immediate value (int32_t or larger)
62 * arg[2] = pointer to destination uint64_t
63 */
64 X(addi)
65 {
66 reg(ic->arg[2]) = reg(ic->arg[0]) + (int32_t)ic->arg[1];
67 }
68
69
70 /*
71 * andi_dot: AND immediate, update CR.
72 *
73 * arg[0] = pointer to source uint64_t
74 * arg[1] = immediate value (uint32_t)
75 * arg[2] = pointer to destination uint64_t
76 */
77 X(andi_dot)
78 {
79 MODE_uint_t tmp = reg(ic->arg[0]) & (uint32_t)ic->arg[1];
80 reg(ic->arg[2]) = tmp;
81 update_cr0(cpu, tmp);
82 }
83
84
85 /*
86 * addic: Add immediate, Carry.
87 *
88 * arg[0] = pointer to source uint64_t
89 * arg[1] = immediate value (int32_t or larger)
90 * arg[2] = pointer to destination uint64_t
91 */
92 X(addic)
93 {
94 /* TODO/NOTE: Only for 32-bit mode, so far! */
95 uint64_t tmp = (int32_t)reg(ic->arg[0]);
96 uint64_t tmp2 = tmp;
97
98 tmp2 += (int32_t)ic->arg[1];
99
100 /* NOTE: CA is never cleared, just set. */
101 /* TODO: Is this correct? */
102 if ((tmp2 >> 32) != (tmp >> 32))
103 cpu->cd.ppc.xer |= PPC_XER_CA;
104
105 reg(ic->arg[2]) = (uint32_t)tmp2;
106 }
107
108
109 /*
110 * subfic: Subtract from immediate, Carry.
111 *
112 * arg[0] = pointer to source uint64_t
113 * arg[1] = immediate value (int32_t or larger)
114 * arg[2] = pointer to destination uint64_t
115 */
116 X(subfic)
117 {
118 /* TODO/NOTE: Only for 32-bit mode, so far! */
119 uint64_t tmp = (int32_t)(~reg(ic->arg[0]));
120 uint64_t tmp2 = tmp;
121
122 tmp2 += (int32_t)ic->arg[1] + 1;
123
124 /* NOTE: CA is never cleared, just set. TODO: Is this right? */
125 /* TODO: Is this correct? */
126 if ((tmp2 >> 32) != (tmp >> 32))
127 cpu->cd.ppc.xer |= PPC_XER_CA;
128
129 reg(ic->arg[2]) = (uint32_t)tmp2;
130 }
131
132
133 /*
134 * addic_dot: Add immediate, Carry.
135 *
136 * arg[0] = pointer to source uint64_t
137 * arg[1] = immediate value (int32_t or larger)
138 * arg[2] = pointer to destination uint64_t
139 */
140 X(addic_dot)
141 {
142 /* TODO/NOTE: Only for 32-bit mode, so far! */
143 uint64_t tmp = (uint32_t)reg(ic->arg[0]);
144 uint64_t tmp2 = tmp;
145
146 tmp2 += (int32_t)ic->arg[1];
147
148 /* NOTE: CA is never cleared, just set. */
149 /* TODO: Is this correct? */
150 if ((tmp2 >> 32) != (tmp >> 32))
151 cpu->cd.ppc.xer |= PPC_XER_CA;
152
153 reg(ic->arg[2]) = (uint32_t)tmp2;
154 update_cr0(cpu, tmp2);
155 }
156
157
158 /*
159 * bclr: Branch Conditional to Link Register
160 *
161 * arg[0] = bo
162 * arg[1] = bi
163 * arg[2] = bh
164 */
165 X(bclr)
166 {
167 int bo = ic->arg[0], bi = ic->arg[1] /* , bh = ic->arg[2] */;
168 int ctr_ok, cond_ok;
169 MODE_uint_t tmp, addr = cpu->cd.ppc.lr;
170 if (!(bo & 4))
171 cpu->cd.ppc.ctr --;
172 ctr_ok = (bo >> 2) & 1;
173 tmp = cpu->cd.ppc.ctr;
174 ctr_ok |= ( (tmp != 0) ^ ((bo >> 1) & 1) );
175 cond_ok = (bo >> 4) & 1;
176 cond_ok |= ( ((bo >> 3) & 1) == ((cpu->cd.ppc.cr >> (31-bi)) & 1) );
177 if (ctr_ok && cond_ok) {
178 if (cpu->machine->show_trace_tree)
179 cpu_functioncall_trace_return(cpu);
180 cpu->pc = addr & ~3;
181 /* Find the new physical page and update pointers: */
182 ppc_pc_to_pointers(cpu);
183 }
184 }
185
186
187 /*
188 * b: Branch (to a different translated page)
189 *
190 * arg[0] = relative offset (as an int32_t)
191 */
192 X(b)
193 {
194 uint64_t low_pc;
195
196 /* Calculate new PC from this instruction + arg[0] */
197 low_pc = ((size_t)ic - (size_t)
198 cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
199 cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2);
200 cpu->pc += (low_pc << 2);
201 cpu->pc += (int32_t)ic->arg[0];
202
203 /* Find the new physical page and update the translation pointers: */
204 ppc_pc_to_pointers(cpu);
205 }
206
207
208 /*
209 * bc: Branch Conditional (to a different translated page)
210 *
211 * arg[0] = relative offset (as an int32_t)
212 * arg[1] = bo
213 * arg[2] = bi
214 */
215 X(bc)
216 {
217 MODE_uint_t tmp;
218 int ctr_ok, cond_ok, bi = ic->arg[2], bo = ic->arg[1];
219 if (!(bo & 4))
220 cpu->cd.ppc.ctr --;
221 ctr_ok = (bo >> 2) & 1;
222 tmp = cpu->cd.ppc.ctr;
223 ctr_ok |= ( (tmp != 0) ^ ((bo >> 1) & 1) );
224 cond_ok = (bo >> 4) & 1;
225 cond_ok |= ( ((bo >> 3) & 1) ==
226 ((cpu->cd.ppc.cr >> (31-bi)) & 1) );
227 if (ctr_ok && cond_ok)
228 instr(b)(cpu,ic);
229 }
230
231
232 /*
233 * b_samepage: Branch (to within the same translated page)
234 *
235 * arg[0] = pointer to new ppc_instr_call
236 */
237 X(b_samepage)
238 {
239 cpu->cd.ppc.next_ic = (struct ppc_instr_call *) ic->arg[0];
240 }
241
242
243 /*
244 * bc_samepage: Branch Conditional (to within the same page)
245 *
246 * arg[0] = new ic ptr
247 * arg[1] = bo
248 * arg[2] = bi
249 */
250 X(bc_samepage)
251 {
252 MODE_uint_t tmp;
253 int ctr_ok, cond_ok, bi = ic->arg[2], bo = ic->arg[1];
254 if (!(bo & 4))
255 cpu->cd.ppc.ctr --;
256 ctr_ok = (bo >> 2) & 1;
257 tmp = cpu->cd.ppc.ctr;
258 ctr_ok |= ( (tmp != 0) ^ ((bo >> 1) & 1) );
259 cond_ok = (bo >> 4) & 1;
260 cond_ok |= ( ((bo >> 3) & 1) ==
261 ((cpu->cd.ppc.cr >> (31-bi)) & 1) );
262 if (ctr_ok && cond_ok)
263 instr(b_samepage)(cpu,ic);
264 }
265
266
267 /*
268 * bl: Branch and Link (to a different translated page)
269 *
270 * arg[0] = relative offset (as an int32_t)
271 */
272 X(bl)
273 {
274 uint32_t low_pc;
275
276 /* Calculate LR: */
277 low_pc = ((size_t)cpu->cd.ppc.next_ic - (size_t)
278 cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
279 cpu->cd.ppc.lr = cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2);
280 cpu->cd.ppc.lr += (low_pc << 2);
281
282 /* Calculate new PC from this instruction + arg[0] */
283 low_pc = ((size_t)ic - (size_t)
284 cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
285 cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2);
286 cpu->pc += (low_pc << 2);
287 cpu->pc += (int32_t)ic->arg[0];
288
289 /* Find the new physical page and update the translation pointers: */
290 ppc_pc_to_pointers(cpu);
291 }
292
293
294 /*
295 * bl_trace: Branch and Link (to a different translated page) (with trace)
296 *
297 * arg[0] = relative offset (as an int32_t)
298 */
299 X(bl_trace)
300 {
301 uint32_t low_pc;
302
303 /* Calculate LR: */
304 low_pc = ((size_t)cpu->cd.ppc.next_ic - (size_t)
305 cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
306 cpu->cd.ppc.lr = cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2);
307 cpu->cd.ppc.lr += (low_pc << 2);
308
309 /* Calculate new PC from this instruction + arg[0] */
310 low_pc = ((size_t)ic - (size_t)
311 cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
312 cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2);
313 cpu->pc += (low_pc << 2);
314 cpu->pc += (int32_t)ic->arg[0];
315
316 cpu_functioncall_trace(cpu, cpu->pc);
317
318 /* Find the new physical page and update the translation pointers: */
319 ppc_pc_to_pointers(cpu);
320 }
321
322
323 /*
324 * bl_samepage: Branch and Link (to within the same translated page)
325 *
326 * arg[0] = pointer to new ppc_instr_call
327 */
328 X(bl_samepage)
329 {
330 uint32_t low_pc;
331
332 /* Calculate LR: */
333 low_pc = ((size_t)cpu->cd.ppc.next_ic - (size_t)
334 cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
335 cpu->cd.ppc.lr = cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2);
336 cpu->cd.ppc.lr += (low_pc << 2);
337
338 cpu->cd.ppc.next_ic = (struct ppc_instr_call *) ic->arg[0];
339 }
340
341
342 /*
343 * bl_samepage_trace: Branch and Link (to within the same translated page)
344 *
345 * arg[0] = pointer to new ppc_instr_call
346 */
347 X(bl_samepage_trace)
348 {
349 uint32_t low_pc;
350
351 /* Calculate LR: */
352 low_pc = ((size_t)cpu->cd.ppc.next_ic - (size_t)
353 cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
354 cpu->cd.ppc.lr = cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2);
355 cpu->cd.ppc.lr += (low_pc << 2);
356
357 cpu->cd.ppc.next_ic = (struct ppc_instr_call *) ic->arg[0];
358
359 /* Calculate new PC (for the trace) */
360 low_pc = ((size_t)cpu->cd.ppc.next_ic - (size_t)
361 cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
362 cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2);
363 cpu->pc += (low_pc << 2);
364 cpu_functioncall_trace(cpu, cpu->pc);
365 }
366
367
368 /*
369 * cmpd: Compare Doubleword
370 *
371 * arg[0] = ptr to ra
372 * arg[1] = ptr to rb
373 * arg[2] = bf
374 */
375 X(cmpd)
376 {
377 int64_t tmp = reg(ic->arg[0]), tmp2 = reg(ic->arg[1]);
378 int bf = ic->arg[2], c;
379 if (tmp < tmp2)
380 c = 8;
381 else if (tmp > tmp2)
382 c = 4;
383 else
384 c = 2;
385 c |= ((cpu->cd.ppc.xer >> 31) & 1); /* SO bit, copied from XER */
386 cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));
387 cpu->cd.ppc.cr |= (c << (28 - 4*bf));
388 }
389
390
391 /*
392 * cmpld: Compare Doubleword, unsigned
393 *
394 * arg[0] = ptr to ra
395 * arg[1] = ptr to rb
396 * arg[2] = bf
397 */
398 X(cmpld)
399 {
400 uint64_t tmp = reg(ic->arg[0]), tmp2 = reg(ic->arg[1]);
401 int bf = ic->arg[2], c;
402 if (tmp < tmp2)
403 c = 8;
404 else if (tmp > tmp2)
405 c = 4;
406 else
407 c = 2;
408 c |= ((cpu->cd.ppc.xer >> 31) & 1); /* SO bit, copied from XER */
409 cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));
410 cpu->cd.ppc.cr |= (c << (28 - 4*bf));
411 }
412
413
414 /*
415 * cmpdi: Compare Doubleword immediate
416 *
417 * arg[0] = ptr to ra
418 * arg[1] = int32_t imm
419 * arg[2] = bf
420 */
421 X(cmpdi)
422 {
423 int64_t tmp = reg(ic->arg[0]), imm = (int32_t)ic->arg[1];
424 int bf = ic->arg[2], c;
425 if (tmp < imm)
426 c = 8;
427 else if (tmp > imm)
428 c = 4;
429 else
430 c = 2;
431 c |= ((cpu->cd.ppc.xer >> 31) & 1); /* SO bit, copied from XER */
432 cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));
433 cpu->cd.ppc.cr |= (c << (28 - 4*bf));
434 }
435
436
437 /*
438 * cmpldi: Compare Doubleword immediate, logical
439 *
440 * arg[0] = ptr to ra
441 * arg[1] = int32_t imm
442 * arg[2] = bf
443 */
444 X(cmpldi)
445 {
446 uint64_t tmp = reg(ic->arg[0]), imm = (uint32_t)ic->arg[1];
447 int bf = ic->arg[2], c;
448 if (tmp < imm)
449 c = 8;
450 else if (tmp > imm)
451 c = 4;
452 else
453 c = 2;
454 c |= ((cpu->cd.ppc.xer >> 31) & 1); /* SO bit, copied from XER */
455 cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));
456 cpu->cd.ppc.cr |= (c << (28 - 4*bf));
457 }
458
459
460 /*
461 * cmpw: Compare Word
462 *
463 * arg[0] = ptr to ra
464 * arg[1] = ptr to rb
465 * arg[2] = bf
466 */
467 X(cmpw)
468 {
469 int32_t tmp = reg(ic->arg[0]), tmp2 = reg(ic->arg[1]);
470 int bf = ic->arg[2], c;
471 if (tmp < tmp2)
472 c = 8;
473 else if (tmp > tmp2)
474 c = 4;
475 else
476 c = 2;
477 c |= ((cpu->cd.ppc.xer >> 31) & 1); /* SO bit, copied from XER */
478 cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));
479 cpu->cd.ppc.cr |= (c << (28 - 4*bf));
480 }
481
482
483 /*
484 * cmplw: Compare Word, unsigned
485 *
486 * arg[0] = ptr to ra
487 * arg[1] = ptr to rb
488 * arg[2] = bf
489 */
490 X(cmplw)
491 {
492 uint32_t tmp = reg(ic->arg[0]), tmp2 = reg(ic->arg[1]);
493 int bf = ic->arg[2], c;
494 if (tmp < tmp2)
495 c = 8;
496 else if (tmp > tmp2)
497 c = 4;
498 else
499 c = 2;
500 c |= ((cpu->cd.ppc.xer >> 31) & 1); /* SO bit, copied from XER */
501 cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));
502 cpu->cd.ppc.cr |= (c << (28 - 4*bf));
503 }
504
505
506 /*
507 * cmpwi: Compare Word immediate
508 *
509 * arg[0] = ptr to ra
510 * arg[1] = int32_t imm
511 * arg[2] = bf
512 */
513 X(cmpwi)
514 {
515 int32_t tmp = reg(ic->arg[0]), imm = ic->arg[1];
516 int bf = ic->arg[2], c;
517 if (tmp < imm)
518 c = 8;
519 else if (tmp > imm)
520 c = 4;
521 else
522 c = 2;
523 c |= ((cpu->cd.ppc.xer >> 31) & 1); /* SO bit, copied from XER */
524 cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));
525 cpu->cd.ppc.cr |= (c << (28 - 4*bf));
526 }
527
528
529 /*
530 * cmplwi: Compare Word immediate, logical
531 *
532 * arg[0] = ptr to ra
533 * arg[1] = int32_t imm
534 * arg[2] = bf
535 */
536 X(cmplwi)
537 {
538 uint32_t tmp = reg(ic->arg[0]), imm = ic->arg[1];
539 int bf = ic->arg[2], c;
540 if (tmp < imm)
541 c = 8;
542 else if (tmp > imm)
543 c = 4;
544 else
545 c = 2;
546 c |= ((cpu->cd.ppc.xer >> 31) & 1); /* SO bit, copied from XER */
547 cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));
548 cpu->cd.ppc.cr |= (c << (28 - 4*bf));
549 }
550
551
552 /*
553 * rlwinm:
554 *
555 * arg[0] = ptr to rs
556 * arg[1] = ptr to ra
557 * arg[2] = copy of the instruction word
558 */
559 X(rlwinm)
560 {
561 MODE_uint_t tmp = reg(ic->arg[0]), ra = 0;
562 uint32_t iword = ic->arg[2];
563 int sh, mb, me, rc;
564
565 sh = (iword >> 11) & 31;
566 mb = (iword >> 6) & 31;
567 me = (iword >> 1) & 31;
568 rc = iword & 1;
569
570 /* TODO: Fix this, its performance is awful: */
571 while (sh-- != 0) {
572 int b = (tmp >> 31) & 1;
573 tmp = (tmp << 1) | b;
574 }
575 for (;;) {
576 uint64_t mask;
577 mask = (uint64_t)1 << (31-mb);
578 ra |= (tmp & mask);
579 if (mb == me)
580 break;
581 mb ++;
582 if (mb == 32)
583 mb = 0;
584 }
585
586 reg(ic->arg[1]) = ra;
587 if (rc)
588 update_cr0(cpu, ra);
589 }
590
591
592 /*
593 * srawi:
594 *
595 * arg[0] = ptr to rs
596 * arg[1] = ptr to ra
597 * arg[2] = sh (shift amount)
598 */
599 X(srawi)
600 {
601 uint32_t tmp = reg(ic->arg[0]);
602 int i = 0, j = 0, sh = ic->arg[2];
603
604 cpu->cd.ppc.xer &= ~PPC_XER_CA;
605 if (tmp & 0x80000000)
606 i = 1;
607 while (sh-- > 0) {
608 if (tmp & 1)
609 j ++;
610 tmp >>= 1;
611 if (tmp & 0x40000000)
612 tmp |= 0x80000000;
613 }
614 if (i && j>0)
615 cpu->cd.ppc.xer |= PPC_XER_CA;
616 reg(ic->arg[1]) = (int64_t)(int32_t)tmp;
617 }
618 X(srawi_dot) { instr(srawi)(cpu,ic); update_cr0(cpu, reg(ic->arg[1])); }
619
620
621 /*
622 * crxor: Condition Register XOR
623 *
624 * arg[0] = copy of the instruction word
625 */
626 X(crxor)
627 {
628 uint32_t iword = ic->arg[0];
629 int bt = (iword >> 21) & 31;
630 int ba = (iword >> 16) & 31;
631 int bb = (iword >> 11) & 31;
632 ba = (cpu->cd.ppc.cr >> (31-ba)) & 1;
633 bb = (cpu->cd.ppc.cr >> (31-bb)) & 1;
634 cpu->cd.ppc.cr &= ~(1 << (31-bt));
635 if (ba ^ bb)
636 cpu->cd.ppc.cr |= (1 << (31-bt));
637 }
638
639
640 /*
641 * mflr, etc: Move from Link Register etc.
642 *
643 * arg[0] = pointer to destination register
644 */
645 X(mflr) { reg(ic->arg[0]) = cpu->cd.ppc.lr; }
646 /* TODO: Check privilege level for mfsprg* */
647 X(mfsprg0) { reg(ic->arg[0]) = cpu->cd.ppc.sprg0; }
648 X(mfsprg1) { reg(ic->arg[0]) = cpu->cd.ppc.sprg1; }
649 X(mfsprg2) { reg(ic->arg[0]) = cpu->cd.ppc.sprg2; }
650 X(mfsprg3) { reg(ic->arg[0]) = cpu->cd.ppc.sprg3; }
651
652
653 /*
654 * mtlr etc.: Move to Link Register (or other special register)
655 *
656 * arg[0] = pointer to source register
657 */
658 X(mtlr) { cpu->cd.ppc.lr = reg(ic->arg[0]); }
659 /* TODO: Check privilege level for mtsprg* */
660 X(mtsprg0) { cpu->cd.ppc.sprg0 = reg(ic->arg[0]); }
661 X(mtsprg1) { cpu->cd.ppc.sprg1 = reg(ic->arg[0]); }
662 X(mtsprg2) { cpu->cd.ppc.sprg2 = reg(ic->arg[0]); }
663 X(mtsprg3) { cpu->cd.ppc.sprg3 = reg(ic->arg[0]); }
664
665
666 /*
667 * mfcr: Move From Condition Register
668 *
669 * arg[0] = pointer to destination register
670 */
671 X(mfcr)
672 {
673 reg(ic->arg[0]) = cpu->cd.ppc.cr;
674 }
675
676
677 /*
678 * mfmsr: Move From MSR
679 *
680 * arg[0] = pointer to destination register
681 */
682 X(mfmsr)
683 {
684 reg_access_msr(cpu, (uint64_t*)ic->arg[0], 0);
685 }
686
687
688 /*
689 * mtmsr: Move To MSR
690 *
691 * arg[0] = pointer to source register
692 */
693 X(mtmsr)
694 {
695 reg_access_msr(cpu, (uint64_t*)ic->arg[0], 1);
696 }
697
698
699 /*
700 * mtcrf: Move To Condition Register Fields
701 *
702 * arg[0] = pointer to source register
703 */
704 X(mtcrf)
705 {
706 cpu->cd.ppc.cr &= ~ic->arg[1];
707 cpu->cd.ppc.cr |= (reg(ic->arg[0]) & ic->arg[1]);
708 }
709
710
711 /*
712 * mulli: Multiply Low Immediate.
713 *
714 * arg[0] = pointer to source register ra
715 * arg[1] = int32_t immediate
716 * arg[2] = pointer to destination register rt
717 */
718 X(mulli)
719 {
720 reg(ic->arg[2]) = (uint32_t)(reg(ic->arg[0]) * ic->arg[1]);
721 }
722
723
724 /*
725 * Shifts, and, or, xor, etc.
726 *
727 * arg[0] = pointer to source register rs
728 * arg[1] = pointer to source register rb
729 * arg[2] = pointer to destination register ra
730 */
731 X(slw) { reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0])
732 << (reg(ic->arg[1]) & 63); }
733 X(slw_dot) { reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0])
734 << (reg(ic->arg[1]) & 63);
735 update_cr0(cpu, reg(ic->arg[2])); }
736 X(sraw) { reg(ic->arg[2]) = (int64_t)reg(ic->arg[0])
737 >> (reg(ic->arg[1]) & 63); }
738 X(sraw_dot) { reg(ic->arg[2]) = (int64_t)reg(ic->arg[0])
739 >> (reg(ic->arg[1]) & 63);
740 update_cr0(cpu, reg(ic->arg[2])); }
741 X(and) { reg(ic->arg[2]) = reg(ic->arg[0]) & reg(ic->arg[1]); }
742 X(and_dot) { reg(ic->arg[2]) = reg(ic->arg[0]) & reg(ic->arg[1]);
743 update_cr0(cpu, reg(ic->arg[2])); }
744 X(andc) { reg(ic->arg[2]) = reg(ic->arg[0]) & (~reg(ic->arg[1])); }
745 X(andc_dot) { reg(ic->arg[2]) = reg(ic->arg[0]) & (~reg(ic->arg[1]));
746 update_cr0(cpu, reg(ic->arg[2])); }
747 X(nor) { reg(ic->arg[2]) = ~(reg(ic->arg[0]) | reg(ic->arg[1])); }
748 X(nor_dot) { reg(ic->arg[2]) = ~(reg(ic->arg[0]) | reg(ic->arg[1]));
749 update_cr0(cpu, reg(ic->arg[2])); }
750 X(or) { reg(ic->arg[2]) = reg(ic->arg[0]) | reg(ic->arg[1]); }
751 X(or_dot) { reg(ic->arg[2]) = reg(ic->arg[0]) | reg(ic->arg[1]);
752 update_cr0(cpu, reg(ic->arg[2])); }
753 X(orc) { reg(ic->arg[2]) = reg(ic->arg[0]) | (~reg(ic->arg[1])); }
754 X(orc_dot) { reg(ic->arg[2]) = reg(ic->arg[0]) | (~reg(ic->arg[1]));
755 update_cr0(cpu, reg(ic->arg[2])); }
756 X(xor) { reg(ic->arg[2]) = reg(ic->arg[0]) ^ reg(ic->arg[1]); }
757 X(xor_dot) { reg(ic->arg[2]) = reg(ic->arg[0]) ^ reg(ic->arg[1]);
758 update_cr0(cpu, reg(ic->arg[2])); }
759
760
761 /*
762 * neg:
763 *
764 * arg[0] = pointer to source register ra
765 * arg[1] = pointer to destination register rt
766 */
767 X(neg) { reg(ic->arg[1]) = ~reg(ic->arg[0]) + 1; }
768 X(neg_dot) { reg(ic->arg[1]) = ~reg(ic->arg[0]) + 1;
769 update_cr0(cpu, reg(ic->arg[1])); }
770
771
772 /*
773 * mullw, mulhw[u], divw[u]:
774 *
775 * arg[0] = pointer to source register ra
776 * arg[1] = pointer to source register rb
777 * arg[2] = pointer to destination register rt
778 */
779 X(mullw)
780 {
781 int32_t sum = (int32_t)reg(ic->arg[0]) * (int32_t)reg(ic->arg[1]);
782 reg(ic->arg[2]) = (int32_t)sum;
783 }
784 X(mulhw)
785 {
786 int64_t sum;
787 sum = (int64_t)(int32_t)reg(ic->arg[0])
788 * (int64_t)(int32_t)reg(ic->arg[1]);
789 reg(ic->arg[2]) = sum >> 32;
790 }
791 X(mulhwu)
792 {
793 uint64_t sum;
794 sum = (uint64_t)(uint32_t)reg(ic->arg[0])
795 * (uint64_t)(uint32_t)reg(ic->arg[1]);
796 reg(ic->arg[2]) = sum >> 32;
797 }
798 X(divw)
799 {
800 int32_t a = reg(ic->arg[0]), b = reg(ic->arg[1]);
801 int32_t sum;
802 if (b == 0)
803 sum = 0;
804 else
805 sum = a / b;
806 reg(ic->arg[2]) = (uint32_t)sum;
807 }
808 X(divwu)
809 {
810 uint32_t a = reg(ic->arg[0]), b = reg(ic->arg[1]);
811 uint32_t sum;
812 if (b == 0)
813 sum = 0;
814 else
815 sum = a / b;
816 reg(ic->arg[2]) = sum;
817 }
818
819
820 /*
821 * add: Add.
822 *
823 * arg[0] = pointer to source register ra
824 * arg[1] = pointer to source register rb
825 * arg[2] = pointer to destination register rt
826 */
827 X(add)
828 {
829 reg(ic->arg[2]) = reg(ic->arg[0]) + reg(ic->arg[1]);
830 }
831
832
833 /*
834 * addc: Add carrying.
835 *
836 * arg[0] = pointer to source register ra
837 * arg[1] = pointer to source register rb
838 * arg[2] = pointer to destination register rt
839 */
840 X(addc)
841 {
842 /* TODO: this only works in 32-bit mode */
843 uint64_t tmp = (uint32_t)reg(ic->arg[0]);
844 uint64_t tmp2 = tmp;
845 cpu->cd.ppc.xer &= PPC_XER_CA;
846 tmp += (uint32_t)reg(ic->arg[1]);
847 if ((tmp >> 32) == (tmp2 >> 32))
848 cpu->cd.ppc.xer |= PPC_XER_CA;
849 reg(ic->arg[2]) = (uint32_t)tmp;
850 }
851
852
853 /*
854 * adde: Add extended, etc.
855 *
856 * arg[0] = pointer to source register ra
857 * arg[1] = pointer to source register rb
858 * arg[2] = pointer to destination register rt
859 */
860 X(adde)
861 {
862 int old_ca = cpu->cd.ppc.xer & PPC_XER_CA;
863 uint64_t tmp = (uint32_t)reg(ic->arg[0]);
864 uint64_t tmp2 = tmp;
865 cpu->cd.ppc.xer &= PPC_XER_CA;
866 tmp += (uint32_t)reg(ic->arg[1]);
867 if (old_ca)
868 tmp ++;
869 if ((tmp >> 32) == (tmp2 >> 32))
870 cpu->cd.ppc.xer |= PPC_XER_CA;
871
872 reg(ic->arg[2]) = (uint32_t)tmp;
873 }
874 X(addze)
875 {
876 int old_ca = cpu->cd.ppc.xer & PPC_XER_CA;
877 uint64_t tmp = (uint32_t)reg(ic->arg[0]);
878 uint64_t tmp2 = tmp;
879 cpu->cd.ppc.xer &= PPC_XER_CA;
880 if (old_ca)
881 tmp ++;
882 if ((tmp >> 32) == (tmp2 >> 32))
883 cpu->cd.ppc.xer |= PPC_XER_CA;
884 reg(ic->arg[2]) = (uint32_t)tmp;
885 }
886
887
888 /*
889 * subf: Subf, etc.
890 *
891 * arg[0] = pointer to source register ra
892 * arg[1] = pointer to source register rb
893 * arg[2] = pointer to destination register rt
894 */
895 X(subf) { reg(ic->arg[2]) = ~reg(ic->arg[0]) + reg(ic->arg[1]) + 1; }
896 X(subfe)
897 {
898 int old_ca = cpu->cd.ppc.xer & PPC_XER_CA;
899 uint64_t tmp = (uint32_t)(~reg(ic->arg[0]));
900 uint64_t tmp2 = tmp;
901
902 cpu->cd.ppc.xer &= PPC_XER_CA;
903 tmp += (uint32_t)reg(ic->arg[1]);
904 if (old_ca)
905 tmp ++;
906 if ((tmp >> 32) == (tmp2 >> 32))
907 cpu->cd.ppc.xer |= PPC_XER_CA;
908 reg(ic->arg[2]) = (uint32_t)tmp;
909 }
910 X(subfze)
911 {
912 int old_ca = cpu->cd.ppc.xer & PPC_XER_CA;
913 uint64_t tmp = (uint32_t)(~reg(ic->arg[0]));
914 uint64_t tmp2 = tmp;
915 cpu->cd.ppc.xer &= PPC_XER_CA;
916 if (old_ca)
917 tmp ++;
918 if ((tmp >> 32) == (tmp2 >> 32))
919 cpu->cd.ppc.xer |= PPC_XER_CA;
920 reg(ic->arg[2]) = (uint32_t)tmp;
921 }
922
923
924 /*
925 * ori: OR immediate.
926 *
927 * arg[0] = pointer to source uint64_t
928 * arg[1] = immediate value (uint32_t or larger)
929 * arg[2] = pointer to destination uint64_t
930 */
931 X(ori)
932 {
933 reg(ic->arg[2]) = reg(ic->arg[0]) | (uint32_t)ic->arg[1];
934 }
935
936
937 /*
938 * user_syscall: Userland syscall.
939 *
940 * arg[0] = syscall "level" (usually 0)
941 */
942 X(user_syscall)
943 {
944 useremul_syscall(cpu, ic->arg[0]);
945 }
946
947
948 /*
949 * xori: XOR immediate.
950 *
951 * arg[0] = pointer to source uint64_t
952 * arg[1] = immediate value (uint32_t or larger)
953 * arg[2] = pointer to destination uint64_t
954 */
955 X(xori)
956 {
957 reg(ic->arg[2]) = reg(ic->arg[0]) ^ (uint32_t)ic->arg[1];
958 }
959
960
961 #include "tmp_ppc_loadstore.c"
962
963
964 /*****************************************************************************/
965
966
967 X(end_of_page)
968 {
969 /* Update the PC: (offset 0, but on the next page) */
970 cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2);
971 cpu->pc += (PPC_IC_ENTRIES_PER_PAGE << 2);
972
973 /* Find the new physical page and update the translation pointers: */
974 ppc_pc_to_pointers(cpu);
975
976 /* end_of_page doesn't count as an executed instruction: */
977 cpu->n_translated_instrs --;
978 }
979
980
981 /*****************************************************************************/
982
983
984 /*
985 * ppc_combine_instructions():
986 *
987 * Combine two or more instructions, if possible, into a single function call.
988 */
989 void COMBINE_INSTRUCTIONS(struct cpu *cpu, struct ppc_instr_call *ic,
990 uint32_t addr)
991 {
992 int n_back;
993 n_back = (addr >> 2) & (PPC_IC_ENTRIES_PER_PAGE-1);
994
995 if (n_back >= 1) {
996 /* TODO */
997 }
998
999 /* TODO: Combine forward as well */
1000 }
1001
1002
1003 /*****************************************************************************/
1004
1005
1006 /*
1007 * ppc_instr_to_be_translated():
1008 *
1009 * Translate an instruction word into an ppc_instr_call. ic is filled in with
1010 * valid data for the translated instruction, or a "nothing" instruction if
1011 * there was a translation failure. The newly translated instruction is then
1012 * executed.
1013 */
1014 X(to_be_translated)
1015 {
1016 uint64_t addr, low_pc, tmp_addr;
1017 uint32_t iword;
1018 unsigned char *page;
1019 unsigned char ib[4];
1020 int main_opcode, rt, rs, ra, rb, rc, aa_bit, l_bit, lk_bit, spr, sh,
1021 xo, imm, load, size, update, zero, bf, bo, bi, bh, oe_bit, n64=0;
1022 void (*samepage_function)(struct cpu *, struct ppc_instr_call *);
1023 void (*rc_f)(struct cpu *, struct ppc_instr_call *);
1024
1025 /* Figure out the (virtual) address of the instruction: */
1026 low_pc = ((size_t)ic - (size_t)cpu->cd.ppc.cur_ic_page)
1027 / sizeof(struct ppc_instr_call);
1028 addr = cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1)
1029 << PPC_INSTR_ALIGNMENT_SHIFT);
1030 addr += (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
1031 cpu->pc = addr;
1032 addr &= ~0x3;
1033
1034 /* Read the instruction word from memory: */
1035 page = cpu->cd.ppc.host_load[addr >> 12];
1036
1037 if (page != NULL) {
1038 /* fatal("TRANSLATION HIT!\n"); */
1039 memcpy(ib, page + (addr & 0xfff), sizeof(ib));
1040 } else {
1041 /* fatal("TRANSLATION MISS!\n"); */
1042 if (!cpu->memory_rw(cpu, cpu->mem, addr, ib,
1043 sizeof(ib), MEM_READ, CACHE_INSTRUCTION)) {
1044 fatal("to_be_translated(): "
1045 "read failed: TODO\n");
1046 goto bad;
1047 }
1048 }
1049
1050 iword = *((uint32_t *)&ib[0]);
1051
1052 #ifdef HOST_LITTLE_ENDIAN
1053 if (cpu->byte_order == EMUL_BIG_ENDIAN)
1054 #else
1055 if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
1056 #endif
1057 iword = ((iword & 0xff) << 24) |
1058 ((iword & 0xff00) << 8) |
1059 ((iword & 0xff0000) >> 8) |
1060 ((iword & 0xff000000) >> 24);
1061
1062
1063 #define DYNTRANS_TO_BE_TRANSLATED_HEAD
1064 #include "cpu_dyntrans.c"
1065 #undef DYNTRANS_TO_BE_TRANSLATED_HEAD
1066
1067
1068 /*
1069 * Translate the instruction:
1070 */
1071
1072 main_opcode = iword >> 26;
1073
1074 switch (main_opcode) {
1075
1076 case PPC_HI6_MULLI:
1077 rt = (iword >> 21) & 31;
1078 ra = (iword >> 16) & 31;
1079 imm = (int16_t)(iword & 0xffff);
1080 ic->f = instr(mulli);
1081 ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
1082 ic->arg[1] = (ssize_t)imm;
1083 ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);
1084 break;
1085
1086 case PPC_HI6_SUBFIC:
1087 rt = (iword >> 21) & 31;
1088 ra = (iword >> 16) & 31;
1089 imm = (int16_t)(iword & 0xffff);
1090 ic->f = instr(subfic);
1091 ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
1092 ic->arg[1] = (ssize_t)imm;
1093 ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);
1094 break;
1095
1096 case PPC_HI6_CMPLI:
1097 case PPC_HI6_CMPI:
1098 bf = (iword >> 23) & 7;
1099 l_bit = (iword >> 21) & 1;
1100 ra = (iword >> 16) & 31;
1101 if (main_opcode == PPC_HI6_CMPLI) {
1102 imm = iword & 0xffff;
1103 if (l_bit)
1104 ic->f = instr(cmpldi);
1105 else
1106 ic->f = instr(cmplwi);
1107 } else {
1108 imm = (int16_t)(iword & 0xffff);
1109 if (l_bit)
1110 ic->f = instr(cmpdi);
1111 else
1112 ic->f = instr(cmpwi);
1113 }
1114 ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
1115 ic->arg[1] = (ssize_t)imm;
1116 ic->arg[2] = bf;
1117 break;
1118
1119 case PPC_HI6_ADDIC:
1120 case PPC_HI6_ADDIC_DOT:
1121 if (cpu->cd.ppc.bits == 64) {
1122 fatal("addic for 64-bit: TODO\n");
1123 goto bad;
1124 }
1125 rt = (iword >> 21) & 31;
1126 ra = (iword >> 16) & 31;
1127 imm = (int16_t)(iword & 0xffff);
1128 if (main_opcode == PPC_HI6_ADDIC)
1129 ic->f = instr(addic);
1130 else
1131 ic->f = instr(addic_dot);
1132 ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
1133 ic->arg[1] = (ssize_t)imm;
1134 ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);
1135 break;
1136
1137 case PPC_HI6_ADDI:
1138 case PPC_HI6_ADDIS:
1139 rt = (iword >> 21) & 31; ra = (iword >> 16) & 31;
1140 ic->f = instr(addi);
1141 if (ra == 0)
1142 ic->arg[0] = (size_t)(&cpu->cd.ppc.zero);
1143 else
1144 ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
1145 ic->arg[1] = (ssize_t)(int16_t)(iword & 0xffff);
1146 if (main_opcode == PPC_HI6_ADDIS)
1147 ic->arg[1] <<= 16;
1148 ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);
1149 break;
1150
1151 case PPC_HI6_ANDI_DOT:
1152 case PPC_HI6_ANDIS_DOT:
1153 rs = (iword >> 21) & 31; ra = (iword >> 16) & 31;
1154 ic->f = instr(andi_dot);
1155 ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
1156 ic->arg[1] = iword & 0xffff;
1157 if (main_opcode == PPC_HI6_ANDIS_DOT)
1158 ic->arg[1] <<= 16;
1159 ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[ra]);
1160 break;
1161
1162 case PPC_HI6_ORI:
1163 case PPC_HI6_ORIS:
1164 case PPC_HI6_XORI:
1165 case PPC_HI6_XORIS:
1166 rs = (iword >> 21) & 31; ra = (iword >> 16) & 31;
1167 if (main_opcode == PPC_HI6_ORI ||
1168 main_opcode == PPC_HI6_ORIS)
1169 ic->f = instr(ori);
1170 else
1171 ic->f = instr(xori);
1172 ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
1173 ic->arg[1] = iword & 0xffff;
1174 if (main_opcode == PPC_HI6_ORIS ||
1175 main_opcode == PPC_HI6_XORIS)
1176 ic->arg[1] <<= 16;
1177 ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[ra]);
1178 break;
1179
1180 case PPC_HI6_LBZ:
1181 case PPC_HI6_LBZU:
1182 case PPC_HI6_LHZ:
1183 case PPC_HI6_LHZU:
1184 case PPC_HI6_LWZ:
1185 case PPC_HI6_LWZU:
1186 case PPC_HI6_STB:
1187 case PPC_HI6_STBU:
1188 case PPC_HI6_STH:
1189 case PPC_HI6_STHU:
1190 case PPC_HI6_STW:
1191 case PPC_HI6_STWU:
1192 rs = (iword >> 21) & 31;
1193 ra = (iword >> 16) & 31;
1194 imm = (int16_t)(iword & 0xffff);
1195 load = 0; zero = 1; size = 0; update = 0;
1196 switch (main_opcode) {
1197 case PPC_HI6_LBZ: load = 1; break;
1198 case PPC_HI6_LBZU: load = 1; update = 1; break;
1199 case PPC_HI6_LHZ: load = 1; size = 1; break;
1200 case PPC_HI6_LHZU: load = 1; size = 1; update = 1; break;
1201 case PPC_HI6_LWZ: load = 1; size = 2; break;
1202 case PPC_HI6_LWZU: load = 1; size = 2; update = 1; break;
1203 case PPC_HI6_STB: break;
1204 case PPC_HI6_STBU: update = 1; break;
1205 case PPC_HI6_STH: size = 1; break;
1206 case PPC_HI6_STHU: size = 1; update = 1; break;
1207 case PPC_HI6_STW: size = 2; break;
1208 case PPC_HI6_STWU: size = 2; update = 1; break;
1209 }
1210 ic->f =
1211 #ifdef MODE32
1212 ppc32_loadstore
1213 #else
1214 ppc_loadstore
1215 #endif
1216 [size + 4*zero + 8*load + (imm==0? 16 : 0) + 32*update];
1217
1218 if (ra == 0 && update) {
1219 fatal("TODO: ra=0 && update?\n");
1220 goto bad;
1221 }
1222 ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
1223 if (ra == 0)
1224 ic->arg[1] = (size_t)(&cpu->cd.ppc.zero);
1225 else
1226 ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
1227 ic->arg[2] = (ssize_t)imm;
1228 break;
1229
1230 case PPC_HI6_BC:
1231 aa_bit = (iword >> 1) & 1;
1232 lk_bit = iword & 1;
1233 bo = (iword >> 21) & 31;
1234 bi = (iword >> 16) & 31;
1235 tmp_addr = (int64_t)(int16_t)(iword & 0xfffc);
1236 if (lk_bit) {
1237 fatal("lk_bit: NOT YET\n");
1238 goto bad;
1239 }
1240 if (aa_bit) {
1241 fatal("aa_bit: NOT YET\n");
1242 goto bad;
1243 }
1244 ic->f = instr(bc);
1245 samepage_function = instr(bc_samepage);
1246 ic->arg[0] = (ssize_t)tmp_addr;
1247 ic->arg[1] = bo;
1248 ic->arg[2] = bi;
1249 /* Branches are calculated as cur PC + offset. */
1250 /* Special case: branch within the same page: */
1251 {
1252 uint64_t mask_within_page =
1253 ((PPC_IC_ENTRIES_PER_PAGE-1) << 2) | 3;
1254 uint64_t old_pc = addr;
1255 uint64_t new_pc = old_pc + (int32_t)ic->arg[0];
1256 if ((old_pc & ~mask_within_page) ==
1257 (new_pc & ~mask_within_page)) {
1258 ic->f = samepage_function;
1259 ic->arg[0] = (size_t) (
1260 cpu->cd.ppc.cur_ic_page +
1261 ((new_pc & mask_within_page) >> 2));
1262 }
1263 }
1264 break;
1265
1266 case PPC_HI6_SC:
1267 ic->arg[0] = (iword >> 5) & 0x7f;
1268 if (cpu->machine->userland_emul != NULL)
1269 ic->f = instr(user_syscall);
1270 else {
1271 fatal("PPC non-userland SYSCALL: TODO\n");
1272 goto bad;
1273 }
1274 break;
1275
1276 case PPC_HI6_B:
1277 aa_bit = (iword & 2) >> 1;
1278 lk_bit = iword & 1;
1279 if (aa_bit) {
1280 fatal("aa_bit: NOT YET\n");
1281 goto bad;
1282 }
1283 tmp_addr = (int64_t)(int32_t)((iword & 0x03fffffc) << 6);
1284 tmp_addr = (int64_t)tmp_addr >> 6;
1285 if (lk_bit) {
1286 if (cpu->machine->show_trace_tree) {
1287 ic->f = instr(bl_trace);
1288 samepage_function = instr(bl_samepage_trace);
1289 } else {
1290 ic->f = instr(bl);
1291 samepage_function = instr(bl_samepage);
1292 }
1293 } else {
1294 ic->f = instr(b);
1295 samepage_function = instr(b_samepage);
1296 }
1297 ic->arg[0] = (ssize_t)tmp_addr;
1298 /* Branches are calculated as cur PC + offset. */
1299 /* Special case: branch within the same page: */
1300 {
1301 uint64_t mask_within_page =
1302 ((PPC_IC_ENTRIES_PER_PAGE-1) << 2) | 3;
1303 uint64_t old_pc = addr;
1304 uint64_t new_pc = old_pc + (int32_t)ic->arg[0];
1305 if ((old_pc & ~mask_within_page) ==
1306 (new_pc & ~mask_within_page)) {
1307 ic->f = samepage_function;
1308 ic->arg[0] = (size_t) (
1309 cpu->cd.ppc.cur_ic_page +
1310 ((new_pc & mask_within_page) >> 2));
1311 }
1312 }
1313 break;
1314
1315 case PPC_HI6_19:
1316 xo = (iword >> 1) & 1023;
1317 switch (xo) {
1318
1319 case PPC_19_BCLR:
1320 bo = (iword >> 21) & 31;
1321 bi = (iword >> 16) & 31;
1322 bh = (iword >> 11) & 3;
1323 lk_bit = iword & 1;
1324 if (lk_bit) {
1325 fatal("TODO: bclr with l_bit set\n");
1326 goto bad;
1327 }
1328 ic->f = instr(bclr);
1329 ic->arg[0] = bo;
1330 ic->arg[1] = bi;
1331 ic->arg[2] = bh;
1332 break;
1333
1334 case PPC_19_ISYNC:
1335 /* TODO */
1336 ic->f = instr(nop);
1337 break;
1338
1339 case PPC_19_CRXOR:
1340 ic->f = instr(crxor);
1341 ic->arg[0] = iword;
1342 break;
1343
1344 default:goto bad;
1345 }
1346 break;
1347
1348 case PPC_HI6_RLWINM:
1349 rs = (iword >> 21) & 31;
1350 ra = (iword >> 16) & 31;
1351 ic->f = instr(rlwinm);
1352 ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
1353 ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
1354 ic->arg[2] = (uint32_t)iword;
1355 break;
1356
1357 case PPC_HI6_31:
1358 xo = (iword >> 1) & 1023;
1359 switch (xo) {
1360
1361 case PPC_31_CMPL:
1362 case PPC_31_CMP:
1363 bf = (iword >> 23) & 7;
1364 l_bit = (iword >> 21) & 1;
1365 ra = (iword >> 16) & 31;
1366 rb = (iword >> 11) & 31;
1367 if (xo == PPC_31_CMPL) {
1368 if (l_bit)
1369 ic->f = instr(cmpld);
1370 else
1371 ic->f = instr(cmplw);
1372 } else {
1373 if (l_bit)
1374 ic->f = instr(cmpd);
1375 else
1376 ic->f = instr(cmpw);
1377 }
1378 ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
1379 ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rb]);
1380 ic->arg[2] = bf;
1381 break;
1382
1383 case PPC_31_MFSPR:
1384 rt = (iword >> 21) & 31;
1385 spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
1386 ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rt]);
1387 switch (spr) {
1388 case 8: ic->f = instr(mflr); break;
1389 case 272: ic->f = instr(mfsprg0); break;
1390 case 273: ic->f = instr(mfsprg1); break;
1391 case 274: ic->f = instr(mfsprg2); break;
1392 case 275: ic->f = instr(mfsprg3); break;
1393 default:fatal("UNIMPLEMENTED spr %i\n", spr);
1394 goto bad;
1395 }
1396 break;
1397
1398 case PPC_31_MTSPR:
1399 rs = (iword >> 21) & 31;
1400 spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
1401 ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
1402 switch (spr) {
1403 case 8: ic->f = instr(mtlr); break;
1404 case 272: ic->f = instr(mtsprg0); break;
1405 case 273: ic->f = instr(mtsprg1); break;
1406 case 274: ic->f = instr(mtsprg2); break;
1407 case 275: ic->f = instr(mtsprg3); break;
1408 default:fatal("UNIMPLEMENTED spr %i\n", spr);
1409 goto bad;
1410 }
1411 break;
1412
1413 case PPC_31_MFCR:
1414 rt = (iword >> 21) & 31;
1415 ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rt]);
1416 ic->f = instr(mfcr);
1417 break;
1418
1419 case PPC_31_MFMSR:
1420 rt = (iword >> 21) & 31;
1421 ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rt]);
1422 ic->f = instr(mfmsr);
1423 break;
1424
1425 case PPC_31_MTMSR:
1426 rs = (iword >> 21) & 31;
1427 l_bit = (iword >> 16) & 1;
1428 if (l_bit) {
1429 fatal("TODO: mtmsr l-bit\n");
1430 goto bad;
1431 }
1432 ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
1433 ic->f = instr(mtmsr);
1434 break;
1435
1436 case PPC_31_MTCRF:
1437 rs = (iword >> 21) & 31;
1438 {
1439 int i, fxm = (iword >> 12) & 255;
1440 uint32_t tmp = 0;
1441 for (i=0; i<8; i++, fxm <<= 1) {
1442 tmp <<= 4;
1443 if (fxm & 128)
1444 tmp |= 0xf;
1445 }
1446 ic->arg[1] = (uint32_t)tmp;
1447 }
1448 ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
1449 ic->f = instr(mtcrf);
1450 break;
1451
1452 case PPC_31_SRAWI:
1453 rs = (iword >> 21) & 31;
1454 ra = (iword >> 16) & 31;
1455 sh = (iword >> 11) & 31;
1456 rc = iword & 1;
1457 ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
1458 ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
1459 ic->arg[2] = sh;
1460 if (rc)
1461 ic->f = instr(srawi_dot);
1462 else
1463 ic->f = instr(srawi);
1464 break;
1465
1466 case PPC_31_SYNC:
1467 case PPC_31_EIEIO:
1468 /* TODO */
1469 ic->f = instr(nop);
1470 break;
1471
1472 case PPC_31_NEG:
1473 rt = (iword >> 21) & 31;
1474 ra = (iword >> 16) & 31;
1475 rc = iword & 1;
1476 ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
1477 ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rt]);
1478 if (rc)
1479 ic->f = instr(neg_dot);
1480 else
1481 ic->f = instr(neg);
1482 break;
1483
1484 case PPC_31_LBZX:
1485 case PPC_31_LBZUX:
1486 case PPC_31_LHZX:
1487 case PPC_31_LHZUX:
1488 case PPC_31_LWZX:
1489 case PPC_31_LWZUX:
1490 case PPC_31_STBX:
1491 case PPC_31_STBUX:
1492 case PPC_31_STHX:
1493 case PPC_31_STHUX:
1494 case PPC_31_STWX:
1495 case PPC_31_STWUX:
1496 case PPC_31_STDX:
1497 case PPC_31_STDUX:
1498 rs = (iword >> 21) & 31;
1499 ra = (iword >> 16) & 31;
1500 rb = (iword >> 11) & 31;
1501 ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
1502 if (ra == 0)
1503 ic->arg[1] = (size_t)(&cpu->cd.ppc.zero);
1504 else
1505 ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
1506 ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rb]);
1507 load = 0; zero = 1; size = 0; update = 0;
1508 switch (xo) {
1509 case PPC_31_LBZX: load = 1; break;
1510 case PPC_31_LBZUX: load = update = 1; break;
1511 case PPC_31_LHZX: size = 1; load = 1; break;
1512 case PPC_31_LHZUX: size = 1; load = update = 1; break;
1513 case PPC_31_LWZX: size = 2; load = 1; break;
1514 case PPC_31_LWZUX: size = 2; load = update = 1; break;
1515 case PPC_31_STBX: break;
1516 case PPC_31_STBUX: update = 1; break;
1517 case PPC_31_STHX: size = 1; break;
1518 case PPC_31_STHUX: size = 1; update = 1; break;
1519 case PPC_31_STWX: size = 2; break;
1520 case PPC_31_STWUX: size = 2; update = 1; break;
1521 case PPC_31_STDX: size = 3; break;
1522 case PPC_31_STDUX: size = 3; update = 1; break;
1523 }
1524 ic->f =
1525 #ifdef MODE32
1526 ppc32_loadstore_indexed
1527 #else
1528 ppc_loadstore_indexed
1529 #endif
1530 [size + 4*zero + 8*load + 16*update];
1531 if (ra == 0 && update) {
1532 fatal("TODO: ra=0 && update?\n");
1533 goto bad;
1534 }
1535 break;
1536
1537 case PPC_31_SLW:
1538 case PPC_31_SRAW:
1539 case PPC_31_AND:
1540 case PPC_31_ANDC:
1541 case PPC_31_NOR:
1542 case PPC_31_OR:
1543 case PPC_31_ORC:
1544 case PPC_31_XOR:
1545 rs = (iword >> 21) & 31;
1546 ra = (iword >> 16) & 31;
1547 rb = (iword >> 11) & 31;
1548 rc = iword & 1;
1549 rc_f = NULL;
1550 switch (xo) {
1551 case PPC_31_SLW: ic->f = instr(slw);
1552 rc_f = instr(slw_dot); break;
1553 case PPC_31_SRAW: ic->f = instr(sraw);
1554 rc_f = instr(sraw_dot); break;
1555 case PPC_31_AND: ic->f = instr(and);
1556 rc_f = instr(and_dot); break;
1557 case PPC_31_ANDC: ic->f = instr(andc);
1558 rc_f = instr(andc_dot); break;
1559 case PPC_31_NOR: ic->f = instr(nor);
1560 rc_f = instr(nor_dot); break;
1561 case PPC_31_OR: ic->f = instr(or);
1562 rc_f = instr(or_dot); break;
1563 case PPC_31_ORC: ic->f = instr(orc);
1564 rc_f = instr(orc_dot); break;
1565 case PPC_31_XOR: ic->f = instr(xor);
1566 rc_f = instr(xor_dot); break;
1567 }
1568 ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
1569 ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rb]);
1570 ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[ra]);
1571 if (rc)
1572 ic->f = rc_f;
1573 break;
1574
1575 case PPC_31_MULLW:
1576 case PPC_31_MULHW:
1577 case PPC_31_MULHWU:
1578 case PPC_31_DIVW:
1579 case PPC_31_DIVWU:
1580 case PPC_31_ADD:
1581 case PPC_31_ADDC:
1582 case PPC_31_ADDE:
1583 case PPC_31_ADDZE:
1584 case PPC_31_SUBF:
1585 case PPC_31_SUBFE:
1586 case PPC_31_SUBFZE:
1587 rt = (iword >> 21) & 31;
1588 ra = (iword >> 16) & 31;
1589 rb = (iword >> 11) & 31;
1590 oe_bit = (iword >> 10) & 1;
1591 rc = iword & 1;
1592 if (rc) {
1593 fatal("RC bit not yet implemented\n");
1594 goto bad;
1595 }
1596 if (oe_bit) {
1597 fatal("oe_bit not yet implemented\n");
1598 goto bad;
1599 }
1600 switch (xo) {
1601 case PPC_31_MULLW: ic->f = instr(mullw); break;
1602 case PPC_31_MULHW: ic->f = instr(mulhw); break;
1603 case PPC_31_MULHWU: ic->f = instr(mulhwu); break;
1604 case PPC_31_DIVW: ic->f = instr(divw); n64=1; break;
1605 case PPC_31_DIVWU: ic->f = instr(divwu); n64=1; break;
1606 case PPC_31_ADD: ic->f = instr(add); break;
1607 case PPC_31_ADDC: ic->f = instr(addc); n64=1; break;
1608 case PPC_31_ADDE: ic->f = instr(adde); n64=1; break;
1609 case PPC_31_ADDZE: ic->f = instr(addze); n64=1; break;
1610 case PPC_31_SUBF: ic->f = instr(subf); break;
1611 case PPC_31_SUBFE: ic->f = instr(subfe); n64=1; break;
1612 case PPC_31_SUBFZE: ic->f = instr(subfze); n64=1;break;
1613 }
1614 ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
1615 ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rb]);
1616 ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);
1617 if (cpu->cd.ppc.bits == 64 && n64) {
1618 fatal("Not yet for 64-bit mode\n");
1619 goto bad;
1620 }
1621 break;
1622
1623 default:goto bad;
1624 }
1625 break;
1626
1627 default:goto bad;
1628 }
1629
1630
1631 #define DYNTRANS_TO_BE_TRANSLATED_TAIL
1632 #include "cpu_dyntrans.c"
1633 #undef DYNTRANS_TO_BE_TRANSLATED_TAIL
1634 }
1635

  ViewVC Help
Powered by ViewVC 1.1.26