/[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

Annotation of /src/cpu/cpu_generic/ppc_opc.cc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (hide annotations)
Wed Sep 5 17:11:21 2007 UTC (16 years, 7 months ago) by dpavlin
File size: 20142 byte(s)
import upstream CVS
1 dpavlin 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