/[pearpc]/src/cpu/cpu_generic/ppc_opc.cc
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 /src/cpu/cpu_generic/ppc_opc.cc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (show annotations)
Wed Sep 5 17:11:21 2007 UTC (16 years, 6 months ago) by dpavlin
File size: 20142 byte(s)
import upstream CVS
1 /*
2 * PearPC
3 * ppc_opc.cc
4 *
5 * Copyright (C) 2003 Sebastian Biallas (sb@biallas.net)
6 * Copyright (C) 2004 Dainel Foesch (dfoesch@cs.nmsu.edu)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "debug/tracers.h"
23 #include "cpu/debug.h"
24 #include "io/pic/pic.h"
25 #include "info.h"
26 #include "ppc_cpu.h"
27 #include "ppc_exc.h"
28 #include "ppc_mmu.h"
29 #include "ppc_opc.h"
30 #include "ppc_dec.h"
31
32
33 void ppc_set_msr(uint32 newmsr)
34 {
35 /* if ((newmsr & MSR_EE) && !(gCPU.msr & MSR_EE)) {
36 if (pic_check_interrupt()) {
37 gCPU.exception_pending = true;
38 gCPU.ext_exception = true;
39 }
40 }*/
41 ppc_mmu_tlb_invalidate();
42 #ifndef PPC_CPU_ENABLE_SINGLESTEP
43 if (newmsr & MSR_SE) {
44 SINGLESTEP("");
45 PPC_CPU_WARN("MSR[SE] (singlestep enable) set, but compiled w/o SE support.\n");
46 }
47 #else
48 gCPU.singlestep_ignore = true;
49 #endif
50 if (newmsr & PPC_CPU_UNSUPPORTED_MSR_BITS) {
51 PPC_CPU_ERR("unsupported bits in MSR set: %08x @%08x\n", newmsr & PPC_CPU_UNSUPPORTED_MSR_BITS, gCPU.pc);
52 }
53 if (newmsr & MSR_POW) {
54 // doze();
55 newmsr &= ~MSR_POW;
56 }
57 gCPU.msr = newmsr;
58
59 }
60
61 /*
62 * bx Branch
63 * .435
64 */
65 void ppc_opc_bx()
66 {
67 uint32 li;
68 PPC_OPC_TEMPL_I(gCPU.current_opc, li);
69 if (!(gCPU.current_opc & PPC_OPC_AA)) {
70 li += gCPU.pc;
71 }
72 if (gCPU.current_opc & PPC_OPC_LK) {
73 gCPU.lr = gCPU.pc + 4;
74 }
75 gCPU.npc = li;
76 }
77
78 /*
79 * bcx Branch Conditional
80 * .436
81 */
82 void ppc_opc_bcx()
83 {
84 uint32 BO, BI, BD;
85 PPC_OPC_TEMPL_B(gCPU.current_opc, BO, BI, BD);
86 if (!(BO & 4)) {
87 gCPU.ctr--;
88 }
89 bool bo2 = (BO & 2);
90 bool bo8 = (BO & 8); // branch condition true
91 bool cr = (gCPU.cr & (1<<(31-BI)));
92 if (((BO & 4) || ((gCPU.ctr!=0) ^ bo2))
93 && ((BO & 16) || (!(cr ^ bo8)))) {
94 if (!(gCPU.current_opc & PPC_OPC_AA)) {
95 BD += gCPU.pc;
96 }
97 if (gCPU.current_opc & PPC_OPC_LK) {
98 gCPU.lr = gCPU.pc + 4;
99 }
100 gCPU.npc = BD;
101 }
102 }
103
104 /*
105 * bcctrx Branch Conditional to Count Register
106 * .438
107 */
108 void ppc_opc_bcctrx()
109 {
110 uint32 BO, BI, BD;
111 PPC_OPC_TEMPL_XL(gCPU.current_opc, BO, BI, BD);
112 PPC_OPC_ASSERT(BD==0);
113 PPC_OPC_ASSERT(!(BO & 2));
114 bool bo8 = (BO & 8);
115 bool cr = (gCPU.cr & (1<<(31-BI)));
116 if ((BO & 16) || (!(cr ^ bo8))) {
117 if (gCPU.current_opc & PPC_OPC_LK) {
118 gCPU.lr = gCPU.pc + 4;
119 }
120 gCPU.npc = gCPU.ctr & 0xfffffffc;
121 }
122 }
123 /*
124 * bclrx Branch Conditional to Link Register
125 * .440
126 */
127 void ppc_opc_bclrx()
128 {
129 uint32 BO, BI, BD;
130 PPC_OPC_TEMPL_XL(gCPU.current_opc, BO, BI, BD);
131 PPC_OPC_ASSERT(BD==0);
132 if (!(BO & 4)) {
133 gCPU.ctr--;
134 }
135 bool bo2 = (BO & 2);
136 bool bo8 = (BO & 8);
137 bool cr = (gCPU.cr & (1<<(31-BI)));
138 if (((BO & 4) || ((gCPU.ctr!=0) ^ bo2))
139 && ((BO & 16) || (!(cr ^ bo8)))) {
140 BD = gCPU.lr & 0xfffffffc;
141 if (gCPU.current_opc & PPC_OPC_LK) {
142 gCPU.lr = gCPU.pc + 4;
143 }
144 gCPU.npc = BD;
145 }
146 }
147
148 /*
149 * dcbf Data Cache Block Flush
150 * .458
151 */
152 void ppc_opc_dcbf()
153 {
154 // NO-OP
155 }
156 /*
157 * dcbi Data Cache Block Invalidate
158 * .460
159 */
160 void ppc_opc_dcbi()
161 {
162 if (gCPU.msr & MSR_PR) {
163 ppc_exception(PPC_EXC_PROGRAM, PPC_EXC_PROGRAM_PRIV);
164 return;
165 }
166 // FIXME: check addr
167 }
168 /*
169 * dcbst Data Cache Block Store
170 * .461
171 */
172 void ppc_opc_dcbst()
173 {
174 // NO-OP
175 }
176 /*
177 * dcbt Data Cache Block Touch
178 * .462
179 */
180 void ppc_opc_dcbt()
181 {
182 // NO-OP
183 }
184 /*
185 * dcbtst Data Cache Block Touch for Store
186 * .463
187 */
188 void ppc_opc_dcbtst()
189 {
190 // NO-OP
191 }
192 /*
193 * eciwx External Control In Word Indexed
194 * .474
195 */
196 void ppc_opc_eciwx()
197 {
198 PPC_OPC_ERR("eciwx unimplemented.\n");
199 }
200 /*
201 * ecowx External Control Out Word Indexed
202 * .476
203 */
204 void ppc_opc_ecowx()
205 {
206 PPC_OPC_ERR("ecowx unimplemented.\n");
207 }
208 /*
209 * eieio Enforce In-Order Execution of I/O
210 * .478
211 */
212 void ppc_opc_eieio()
213 {
214 // NO-OP
215 }
216
217 /*
218 * icbi Instruction Cache Block Invalidate
219 * .519
220 */
221 void ppc_opc_icbi()
222 {
223 // NO-OP
224 }
225
226 /*
227 * isync Instruction Synchronize
228 * .520
229 */
230 void ppc_opc_isync()
231 {
232 // NO-OP
233 }
234
235 static uint32 ppc_cmp_and_mask[8] = {
236 0xfffffff0,
237 0xffffff0f,
238 0xfffff0ff,
239 0xffff0fff,
240 0xfff0ffff,
241 0xff0fffff,
242 0xf0ffffff,
243 0x0fffffff,
244 };
245 /*
246 * mcrf Move Condition Register Field
247 * .561
248 */
249 void ppc_opc_mcrf()
250 {
251 uint32 crD, crS, bla;
252 PPC_OPC_TEMPL_X(gCPU.current_opc, crD, crS, bla);
253 // FIXME: bla == 0
254 crD>>=2;
255 crS>>=2;
256 crD = 7-crD;
257 crS = 7-crS;
258 uint32 c = (gCPU.cr>>(crS*4)) & 0xf;
259 gCPU.cr &= ppc_cmp_and_mask[crD];
260 gCPU.cr |= c<<(crD*4);
261 }
262 /*
263 * mcrfs Move to Condition Register from FPSCR
264 * .562
265 */
266 void ppc_opc_mcrfs()
267 {
268 PPC_OPC_ERR("mcrfs unimplemented.\n");
269 }
270 /*
271 * mcrxr Move to Condition Register from XER
272 * .563
273 */
274 void ppc_opc_mcrxr()
275 {
276 PPC_OPC_ERR("mcrxr unimplemented.\n");
277 }
278 /*
279 * mfcr Move from Condition Register
280 * .564
281 */
282 void ppc_opc_mfcr()
283 {
284 int rD, rA, rB;
285 PPC_OPC_TEMPL_X(gCPU.current_opc, rD, rA, rB);
286 PPC_OPC_ASSERT(rA==0 && rB==0);
287 gCPU.gpr[rD] = gCPU.cr;
288 }
289 /*
290 * mffs Move from FPSCR
291 * .565
292 */
293 void ppc_opc_mffsx()
294 {
295 int frD, rA, rB;
296 PPC_OPC_TEMPL_X(gCPU.current_opc, frD, rA, rB);
297 PPC_OPC_ASSERT(rA==0 && rB==0);
298 gCPU.fpr[frD] = gCPU.fpscr;
299 if (gCPU.current_opc & PPC_OPC_Rc) {
300 // update cr1 flags
301 PPC_OPC_ERR("mffs. unimplemented.\n");
302 }
303 }
304 /*
305 * mfmsr Move from Machine State Register
306 * .566
307 */
308 void ppc_opc_mfmsr()
309 {
310 if (gCPU.msr & MSR_PR) {
311 ppc_exception(PPC_EXC_PROGRAM, PPC_EXC_PROGRAM_PRIV);
312 return;
313 }
314 int rD, rA, rB;
315 PPC_OPC_TEMPL_X(gCPU.current_opc, rD, rA, rB);
316 PPC_OPC_ASSERT((rA == 0) && (rB == 0));
317 gCPU.gpr[rD] = gCPU.msr;
318 }
319 /*
320 * mfspr Move from Special-Purpose Register
321 * .567
322 */
323 void ppc_opc_mfspr()
324 {
325 int rD, spr1, spr2;
326 PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, spr1, spr2);
327 switch (spr2) {
328 case 0:
329 switch (spr1) {
330 case 1: gCPU.gpr[rD] = gCPU.xer; return;
331 case 8: gCPU.gpr[rD] = gCPU.lr; return;
332 case 9: gCPU.gpr[rD] = gCPU.ctr; return;
333 }
334 case 8: // altivec made this spr unpriviledged
335 if (spr1 == 0) {
336 gCPU.gpr[rD] = gCPU.vrsave;
337 return;
338 }
339 }
340 if (gCPU.msr & MSR_PR) {
341 ppc_exception(PPC_EXC_PROGRAM, PPC_EXC_PROGRAM_PRIV);
342 return;
343 }
344 switch (spr2) {
345 case 0:
346 switch (spr1) {
347 case 18: gCPU.gpr[rD] = gCPU.dsisr; return;
348 case 19: gCPU.gpr[rD] = gCPU.dar; return;
349 case 22: {
350 gCPU.dec = gCPU.pdec / TB_TO_PTB_FACTOR;
351 gCPU.gpr[rD] = gCPU.dec;
352 return;
353 }
354 case 25: gCPU.gpr[rD] = gCPU.sdr1; return;
355 case 26: gCPU.gpr[rD] = gCPU.srr[0]; return;
356 case 27: gCPU.gpr[rD] = gCPU.srr[1]; return;
357 }
358 break;
359 case 8:
360 switch (spr1) {
361 case 12: {
362 gCPU.tb = gCPU.ptb / TB_TO_PTB_FACTOR;
363 gCPU.gpr[rD] = gCPU.tb;
364 return;
365 }
366 case 13: {
367 gCPU.tb = gCPU.ptb / TB_TO_PTB_FACTOR;
368 gCPU.gpr[rD] = gCPU.tb >> 32;
369 return;
370 }
371 case 16: gCPU.gpr[rD] = gCPU.sprg[0]; return;
372 case 17: gCPU.gpr[rD] = gCPU.sprg[1]; return;
373 case 18: gCPU.gpr[rD] = gCPU.sprg[2]; return;
374 case 19: gCPU.gpr[rD] = gCPU.sprg[3]; return;
375 case 26: gCPU.gpr[rD] = gCPU.ear; return;
376 case 31: gCPU.gpr[rD] = gCPU.pvr; return;
377 }
378 break;
379 case 16:
380 switch (spr1) {
381 case 16: gCPU.gpr[rD] = gCPU.ibatu[0]; return;
382 case 17: gCPU.gpr[rD] = gCPU.ibatl[0]; return;
383 case 18: gCPU.gpr[rD] = gCPU.ibatu[1]; return;
384 case 19: gCPU.gpr[rD] = gCPU.ibatl[1]; return;
385 case 20: gCPU.gpr[rD] = gCPU.ibatu[2]; return;
386 case 21: gCPU.gpr[rD] = gCPU.ibatl[2]; return;
387 case 22: gCPU.gpr[rD] = gCPU.ibatu[3]; return;
388 case 23: gCPU.gpr[rD] = gCPU.ibatl[3]; return;
389 case 24: gCPU.gpr[rD] = gCPU.dbatu[0]; return;
390 case 25: gCPU.gpr[rD] = gCPU.dbatl[0]; return;
391 case 26: gCPU.gpr[rD] = gCPU.dbatu[1]; return;
392 case 27: gCPU.gpr[rD] = gCPU.dbatl[1]; return;
393 case 28: gCPU.gpr[rD] = gCPU.dbatu[2]; return;
394 case 29: gCPU.gpr[rD] = gCPU.dbatl[2]; return;
395 case 30: gCPU.gpr[rD] = gCPU.dbatu[3]; return;
396 case 31: gCPU.gpr[rD] = gCPU.dbatl[3]; return;
397 }
398 break;
399 case 29:
400 switch (spr1) {
401 case 16:
402 gCPU.gpr[rD] = 0;
403 return;
404 case 17:
405 gCPU.gpr[rD] = 0;
406 return;
407 case 18:
408 gCPU.gpr[rD] = 0;
409 return;
410 case 24:
411 gCPU.gpr[rD] = 0;
412 return;
413 case 25:
414 gCPU.gpr[rD] = 0;
415 return;
416 case 26:
417 gCPU.gpr[rD] = 0;
418 return;
419 case 28:
420 gCPU.gpr[rD] = 0;
421 return;
422 case 29:
423 gCPU.gpr[rD] = 0;
424 return;
425 case 30:
426 gCPU.gpr[rD] = 0;
427 return;
428 }
429 case 31:
430 switch (spr1) {
431 case 16:
432 // PPC_OPC_WARN("read from spr %d:%d (HID0) not supported!\n", spr1, spr2);
433 gCPU.gpr[rD] = gCPU.hid[0];
434 return;
435 case 17:
436 PPC_OPC_WARN("read from spr %d:%d (HID1) not supported!\n", spr1, spr2);
437 gCPU.gpr[rD] = gCPU.hid[1];
438 return;
439 case 18:
440 gCPU.gpr[rD] = 0;
441 return;
442 case 21:
443 gCPU.gpr[rD] = 0;
444 return;
445 case 22:
446 gCPU.gpr[rD] = 0;
447 return;
448 case 23:
449 gCPU.gpr[rD] = 0;
450 return;
451 case 25:
452 PPC_OPC_WARN("read from spr %d:%d (L2CR) not supported! (from %08x)\n", spr1, spr2, gCPU.pc);
453 gCPU.gpr[rD] = 0;
454 return;
455 case 27:
456 PPC_OPC_WARN("read from spr %d:%d (ICTC) not supported!\n", spr1, spr2);
457 gCPU.gpr[rD] = 0;
458 return;
459 case 28:
460 // PPC_OPC_WARN("read from spr %d:%d (THRM1) not supported!\n", spr1, spr2);
461 gCPU.gpr[rD] = 0;
462 return;
463 case 29:
464 // PPC_OPC_WARN("read from spr %d:%d (THRM2) not supported!\n", spr1, spr2);
465 gCPU.gpr[rD] = 0;
466 return;
467 case 30:
468 // PPC_OPC_WARN("read from spr %d:%d (THRM3) not supported!\n", spr1, spr2);
469 gCPU.gpr[rD] = 0;
470 return;
471 case 31:
472 // PPC_OPC_WARN("read from spr %d:%d (???) not supported!\n", spr1, spr2);
473 gCPU.gpr[rD] = 0;
474 return;
475 }
476 }
477 fprintf(stderr, "unknown mfspr: %i:%i\n", spr1, spr2);
478 SINGLESTEP("invalid mfspr\n");
479 }
480 /*
481 * mfsr Move from Segment Register
482 * .570
483 */
484 void ppc_opc_mfsr()
485 {
486 if (gCPU.msr & MSR_PR) {
487 ppc_exception(PPC_EXC_PROGRAM, PPC_EXC_PROGRAM_PRIV);
488 return;
489 }
490 int rD, SR, rB;
491 PPC_OPC_TEMPL_X(gCPU.current_opc, rD, SR, rB);
492 // FIXME: check insn
493 gCPU.gpr[rD] = gCPU.sr[SR & 0xf];
494 }
495 /*
496 * mfsrin Move from Segment Register Indirect
497 * .572
498 */
499 void ppc_opc_mfsrin()
500 {
501 if (gCPU.msr & MSR_PR) {
502 ppc_exception(PPC_EXC_PROGRAM, PPC_EXC_PROGRAM_PRIV);
503 return;
504 }
505 int rD, rA, rB;
506 PPC_OPC_TEMPL_X(gCPU.current_opc, rD, rA, rB);
507 // FIXME: check insn
508 gCPU.gpr[rD] = gCPU.sr[gCPU.gpr[rB] >> 28];
509 }
510 /*
511 * mftb Move from Time Base
512 * .574
513 */
514 void ppc_opc_mftb()
515 {
516 int rD, spr1, spr2;
517 PPC_OPC_TEMPL_X(gCPU.current_opc, rD, spr1, spr2);
518 switch (spr2) {
519 case 8:
520 switch (spr1) {
521 case 12: {
522 gCPU.tb = gCPU.ptb / TB_TO_PTB_FACTOR;
523 gCPU.gpr[rD] = gCPU.tb;
524 return;
525 }
526 case 13: {
527 gCPU.tb = gCPU.ptb / TB_TO_PTB_FACTOR;
528 gCPU.gpr[rD] = gCPU.tb >> 32;
529 return;
530 }
531 }
532 break;
533 }
534 SINGLESTEP("unknown mftb\n");
535 }
536 /*
537 * mtcrf Move to Condition Register Fields
538 * .576
539 */
540 void ppc_opc_mtcrf()
541 {
542
543 int rS;
544 uint32 crm;
545 uint32 CRM;
546 PPC_OPC_TEMPL_XFX(gCPU.current_opc, rS, crm);
547 CRM = ((crm&0x80)?0xf0000000:0)|((crm&0x40)?0x0f000000:0)|((crm&0x20)?0x00f00000:0)|((crm&0x10)?0x000f0000:0)|
548 ((crm&0x08)?0x0000f000:0)|((crm&0x04)?0x00000f00:0)|((crm&0x02)?0x000000f0:0)|((crm&0x01)?0x0000000f:0);
549 gCPU.cr = (gCPU.gpr[rS] & CRM) | (gCPU.cr & ~CRM);
550 }
551 /*
552 * mtfsb0x Move to FPSCR Bit 0
553 * .577
554 */
555 void ppc_opc_mtfsb0x()
556 {
557 int crbD, n1, n2;
558 PPC_OPC_TEMPL_X(gCPU.current_opc, crbD, n1, n2);
559 if (crbD != 1 && crbD != 2) {
560 gCPU.fpscr &= ~(1<<(31-crbD));
561 }
562 if (gCPU.current_opc & PPC_OPC_Rc) {
563 // update cr1 flags
564 PPC_OPC_ERR("mtfsb0. unimplemented.\n");
565 }
566 }
567 /*
568 * mtfsb1x Move to FPSCR Bit 1
569 * .578
570 */
571 void ppc_opc_mtfsb1x()
572 {
573 int crbD, n1, n2;
574 PPC_OPC_TEMPL_X(gCPU.current_opc, crbD, n1, n2);
575 if (crbD != 1 && crbD != 2) {
576 gCPU.fpscr |= 1<<(31-crbD);
577 }
578 if (gCPU.current_opc & PPC_OPC_Rc) {
579 // update cr1 flags
580 PPC_OPC_ERR("mtfsb1. unimplemented.\n");
581 }
582 }
583 /*
584 * mtfsfx Move to FPSCR Fields
585 * .579
586 */
587 void ppc_opc_mtfsfx()
588 {
589 int frB;
590 uint32 fm, FM;
591 PPC_OPC_TEMPL_XFL(gCPU.current_opc, frB, fm);
592 FM = ((fm&0x80)?0xf0000000:0)|((fm&0x40)?0x0f000000:0)|((fm&0x20)?0x00f00000:0)|((fm&0x10)?0x000f0000:0)|
593 ((fm&0x08)?0x0000f000:0)|((fm&0x04)?0x00000f00:0)|((fm&0x02)?0x000000f0:0)|((fm&0x01)?0x0000000f:0);
594 gCPU.fpscr = (gCPU.fpr[frB] & FM) | (gCPU.fpscr & ~FM);
595 if (gCPU.current_opc & PPC_OPC_Rc) {
596 // update cr1 flags
597 PPC_OPC_ERR("mtfsf. unimplemented.\n");
598 }
599 }
600 /*
601 * mtfsfix Move to FPSCR Field Immediate
602 * .580
603 */
604 void ppc_opc_mtfsfix()
605 {
606 int crfD, n1;
607 uint32 imm;
608 PPC_OPC_TEMPL_X(gCPU.current_opc, crfD, n1, imm);
609 crfD >>= 2;
610 imm >>= 1;
611 crfD = 7-crfD;
612 gCPU.fpscr &= ppc_cmp_and_mask[crfD];
613 gCPU.fpscr |= imm<<(crfD*4);
614 if (gCPU.current_opc & PPC_OPC_Rc) {
615 // update cr1 flags
616 PPC_OPC_ERR("mtfsfi. unimplemented.\n");
617 }
618 }
619 /*
620 * mtmsr Move to Machine State Register
621 * .581
622 */
623 void ppc_opc_mtmsr()
624 {
625 if (gCPU.msr & MSR_PR) {
626 ppc_exception(PPC_EXC_PROGRAM, PPC_EXC_PROGRAM_PRIV);
627 return;
628 }
629 int rS, rA, rB;
630 PPC_OPC_TEMPL_X(gCPU.current_opc, rS, rA, rB);
631 PPC_OPC_ASSERT((rA == 0) && (rB == 0));
632 ppc_set_msr(gCPU.gpr[rS]);
633 }
634 /*
635 * mtspr Move to Special-Purpose Register
636 * .584
637 */
638 void ppc_opc_mtspr()
639 {
640 int rS, spr1, spr2;
641 PPC_OPC_TEMPL_X(gCPU.current_opc, rS, spr1, spr2);
642 switch (spr2) {
643 case 0:
644 switch (spr1) {
645 case 1: gCPU.xer = gCPU.gpr[rS]; return;
646 case 8: gCPU.lr = gCPU.gpr[rS]; return;
647 case 9: gCPU.ctr = gCPU.gpr[rS]; return;
648 }
649 case 8: //altivec makes this register unpriviledged
650 if (spr1 == 0) {
651 gCPU.vrsave = gCPU.gpr[rS];
652 return;
653 }
654 }
655 if (gCPU.msr & MSR_PR) {
656 ppc_exception(PPC_EXC_PROGRAM, PPC_EXC_PROGRAM_PRIV);
657 return;
658 }
659 switch (spr2) {
660 case 0:
661 switch (spr1) {
662 /* case 18: gCPU.gpr[rD] = gCPU.dsisr; return;
663 case 19: gCPU.gpr[rD] = gCPU.dar; return;*/
664 case 22: {
665 gCPU.dec = gCPU.gpr[rS];
666 gCPU.pdec = gCPU.dec;
667 gCPU.pdec *= TB_TO_PTB_FACTOR;
668 return;
669 }
670 case 25:
671 if (!ppc_mmu_set_sdr1(gCPU.gpr[rS], true)) {
672 PPC_OPC_ERR("cannot set sdr1\n");
673 }
674 return;
675 case 26: gCPU.srr[0] = gCPU.gpr[rS]; return;
676 case 27: gCPU.srr[1] = gCPU.gpr[rS]; return;
677 }
678 break;
679 case 8:
680 switch (spr1) {
681 case 16: gCPU.sprg[0] = gCPU.gpr[rS]; return;
682 case 17: gCPU.sprg[1] = gCPU.gpr[rS]; return;
683 case 18: gCPU.sprg[2] = gCPU.gpr[rS]; return;
684 case 19: gCPU.sprg[3] = gCPU.gpr[rS]; return;
685 /* case 26: gCPU.gpr[rD] = gCPU.ear; return;
686 case 31: gCPU.gpr[rD] = gCPU.pvr; return;*/
687 }
688 break;
689 case 16:
690 switch (spr1) {
691 case 16:
692 gCPU.ibatu[0] = gCPU.gpr[rS];
693 gCPU.ibat_bl17[0] = ~(BATU_BL(gCPU.ibatu[0])<<17);
694 return;
695 case 17:
696 gCPU.ibatl[0] = gCPU.gpr[rS];
697 return;
698 case 18:
699 gCPU.ibatu[1] = gCPU.gpr[rS];
700 gCPU.ibat_bl17[1] = ~(BATU_BL(gCPU.ibatu[1])<<17);
701 return;
702 case 19:
703 gCPU.ibatl[1] = gCPU.gpr[rS];
704 return;
705 case 20:
706 gCPU.ibatu[2] = gCPU.gpr[rS];
707 gCPU.ibat_bl17[2] = ~(BATU_BL(gCPU.ibatu[2])<<17);
708 return;
709 case 21:
710 gCPU.ibatl[2] = gCPU.gpr[rS];
711 return;
712 case 22:
713 gCPU.ibatu[3] = gCPU.gpr[rS];
714 gCPU.ibat_bl17[3] = ~(BATU_BL(gCPU.ibatu[3])<<17);
715 return;
716 case 23:
717 gCPU.ibatl[3] = gCPU.gpr[rS];
718 return;
719 case 24:
720 gCPU.dbatu[0] = gCPU.gpr[rS];
721 gCPU.dbat_bl17[0] = ~(BATU_BL(gCPU.dbatu[0])<<17);
722 return;
723 case 25:
724 gCPU.dbatl[0] = gCPU.gpr[rS];
725 return;
726 case 26:
727 gCPU.dbatu[1] = gCPU.gpr[rS];
728 gCPU.dbat_bl17[1] = ~(BATU_BL(gCPU.dbatu[1])<<17);
729 return;
730 case 27:
731 gCPU.dbatl[1] = gCPU.gpr[rS];
732 return;
733 case 28:
734 gCPU.dbatu[2] = gCPU.gpr[rS];
735 gCPU.dbat_bl17[2] = ~(BATU_BL(gCPU.dbatu[2])<<17);
736 return;
737 case 29:
738 gCPU.dbatl[2] = gCPU.gpr[rS];
739 return;
740 case 30:
741 gCPU.dbatu[3] = gCPU.gpr[rS];
742 gCPU.dbat_bl17[3] = ~(BATU_BL(gCPU.dbatu[3])<<17);
743 return;
744 case 31:
745 gCPU.dbatl[3] = gCPU.gpr[rS];
746 return;
747 }
748 break;
749 case 29:
750 switch(spr1) {
751 case 17: return;
752 case 24: return;
753 case 25: return;
754 case 26: return;
755 }
756 case 31:
757 switch (spr1) {
758 case 16:
759 // PPC_OPC_WARN("write(%08x) to spr %d:%d (HID0) not supported! @%08x\n", gCPU.gpr[rS], spr1, spr2, gCPU.pc);
760 gCPU.hid[0] = gCPU.gpr[rS];
761 return;
762 case 17: return;
763 case 18:
764 PPC_OPC_ERR("write(%08x) to spr %d:%d (IABR) not supported!\n", gCPU.gpr[rS], spr1, spr2);
765 return;
766 case 21:
767 PPC_OPC_ERR("write(%08x) to spr %d:%d (DABR) not supported!\n", gCPU.gpr[rS], spr1, spr2);
768 return;
769 case 24:
770 PPC_OPC_WARN("write(%08x) to spr %d:%d (?) not supported!\n", gCPU.gpr[rS], spr1, spr2);
771 return;
772 case 27:
773 PPC_OPC_WARN("write(%08x) to spr %d:%d (ICTC) not supported!\n", gCPU.gpr[rS], spr1, spr2);
774 return;
775 case 28:
776 // PPC_OPC_WARN("write(%08x) to spr %d:%d (THRM1) not supported!\n", gCPU.gpr[rS], spr1, spr2);
777 return;
778 case 29:
779 // PPC_OPC_WARN("write(%08x) to spr %d:%d (THRM2) not supported!\n", gCPU.gpr[rS], spr1, spr2);
780 return;
781 case 30:
782 // PPC_OPC_WARN("write(%08x) to spr %d:%d (THRM3) not supported!\n", gCPU.gpr[rS], spr1, spr2);
783 return;
784 case 31: return;
785 }
786 }
787 fprintf(stderr, "unknown mtspr: %i:%i\n", spr1, spr2);
788 SINGLESTEP("unknown mtspr\n");
789 }
790 /*
791 * mtsr Move to Segment Register
792 * .587
793 */
794 void ppc_opc_mtsr()
795 {
796 if (gCPU.msr & MSR_PR) {
797 ppc_exception(PPC_EXC_PROGRAM, PPC_EXC_PROGRAM_PRIV);
798 return;
799 }
800 int rS, SR, rB;
801 PPC_OPC_TEMPL_X(gCPU.current_opc, rS, SR, rB);
802 // FIXME: check insn
803 gCPU.sr[SR & 0xf] = gCPU.gpr[rS];
804 }
805 /*
806 * mtsrin Move to Segment Register Indirect
807 * .591
808 */
809 void ppc_opc_mtsrin()
810 {
811 if (gCPU.msr & MSR_PR) {
812 ppc_exception(PPC_EXC_PROGRAM, PPC_EXC_PROGRAM_PRIV);
813 return;
814 }
815 int rS, rA, rB;
816 PPC_OPC_TEMPL_X(gCPU.current_opc, rS, rA, rB);
817 // FIXME: check insn
818 gCPU.sr[gCPU.gpr[rB] >> 28] = gCPU.gpr[rS];
819 }
820
821 /*
822 * rfi Return from Interrupt
823 * .607
824 */
825 void ppc_opc_rfi()
826 {
827 if (gCPU.msr & MSR_PR) {
828 ppc_exception(PPC_EXC_PROGRAM, PPC_EXC_PROGRAM_PRIV);
829 return;
830 }
831 ppc_set_msr(gCPU.srr[1] & MSR_RFI_SAVE_MASK);
832 gCPU.npc = gCPU.srr[0] & 0xfffffffc;
833 }
834
835 /*
836 * sc System Call
837 * .621
838 */
839 #include "io/graphic/gcard.h"
840 void ppc_opc_sc()
841 {
842 if (gCPU.gpr[3] == 0x113724fa && gCPU.gpr[4] == 0x77810f9b) {
843 gcard_osi(0);
844 return;
845 }
846 ppc_exception(PPC_EXC_SC);
847 }
848
849 /*
850 * sync Synchronize
851 * .672
852 */
853 void ppc_opc_sync()
854 {
855 // NO-OP
856 }
857
858 /*
859 * tlbie Translation Lookaside Buffer Invalidate Entry
860 * .676
861 */
862 void ppc_opc_tlbia()
863 {
864 if (gCPU.msr & MSR_PR) {
865 ppc_exception(PPC_EXC_PROGRAM, PPC_EXC_PROGRAM_PRIV);
866 return;
867 }
868 int rS, rA, rB;
869 PPC_OPC_TEMPL_X(gCPU.current_opc, rS, rA, rB);
870 // FIXME: check rS.. for 0
871 ppc_mmu_tlb_invalidate();
872 }
873
874 /*
875 * tlbie Translation Lookaside Buffer Invalidate All
876 * .676
877 */
878 void ppc_opc_tlbie()
879 {
880 if (gCPU.msr & MSR_PR) {
881 ppc_exception(PPC_EXC_PROGRAM, PPC_EXC_PROGRAM_PRIV);
882 return;
883 }
884 int rS, rA, rB;
885 PPC_OPC_TEMPL_X(gCPU.current_opc, rS, rA, rB);
886 // FIXME: check rS.. for 0
887 ppc_mmu_tlb_invalidate();
888 }
889
890 /*
891 * tlbsync Translation Lookaside Buffer Syncronize
892 * .677
893 */
894 void ppc_opc_tlbsync()
895 {
896 if (gCPU.msr & MSR_PR) {
897 ppc_exception(PPC_EXC_PROGRAM, PPC_EXC_PROGRAM_PRIV);
898 return;
899 }
900 int rS, rA, rB;
901 PPC_OPC_TEMPL_X(gCPU.current_opc, rS, rA, rB);
902 // FIXME: check rS.. for 0
903 ppc_mmu_tlb_invalidate();
904 }
905
906 /*
907 * tw Trap Word
908 * .678
909 */
910 void ppc_opc_tw()
911 {
912 int TO, rA, rB;
913 PPC_OPC_TEMPL_X(gCPU.current_opc, TO, rA, rB);
914 uint32 a = gCPU.gpr[rA];
915 uint32 b = gCPU.gpr[rB];
916 if (((TO & 16) && ((sint32)a < (sint32)b))
917 || ((TO & 8) && ((sint32)a > (sint32)b))
918 || ((TO & 4) && (a == b))
919 || ((TO & 2) && (a < b))
920 || ((TO & 1) && (a > b))) {
921 ppc_exception(PPC_EXC_PROGRAM, PPC_EXC_PROGRAM_TRAP);
922 }
923 }
924
925 /*
926 * twi Trap Word Immediate
927 * .679
928 */
929 void ppc_opc_twi()
930 {
931 int TO, rA;
932 uint32 imm;
933 PPC_OPC_TEMPL_D_SImm(gCPU.current_opc, TO, rA, imm);
934 uint32 a = gCPU.gpr[rA];
935 if (((TO & 16) && ((sint32)a < (sint32)imm))
936 || ((TO & 8) && ((sint32)a > (sint32)imm))
937 || ((TO & 4) && (a == imm))
938 || ((TO & 2) && (a < imm))
939 || ((TO & 1) && (a > imm))) {
940 ppc_exception(PPC_EXC_PROGRAM, PPC_EXC_PROGRAM_TRAP);
941 }
942 }
943
944 /* dcba Data Cache Block Allocate
945 * .???
946 */
947 void ppc_opc_dcba()
948 {
949 /* NO-OP */
950 }

  ViewVC Help
Powered by ViewVC 1.1.26