/[gxemul]/trunk/src/cpus/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

Annotation of /trunk/src/cpus/cpu_ppc_instr.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 18 - (hide annotations)
Mon Oct 8 16:19:11 2007 UTC (16 years, 5 months ago) by dpavlin
File MIME type: text/plain
File size: 63816 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1004 2005/10/27 14:01:10 debug Exp $
20051011        Passing -A as the default boot arg for CATS (works fine with
                OpenBSD/cats).
20051012	Fixing the VGA cursor offset bug, and speeding up framebuffer
		redraws if character cells contain the same thing as during
		the last redraw.
20051013	Adding a slow strd ARM instruction hack.
20051017	Minor updates: Adding a dummy i80321 Verde controller (for
		XScale emulation), fixing the disassembly of the ARM "ldrd"
		instruction, adding "support" for less-than-4KB pages for ARM
		(by not adding them to translation tables).
20051020	Continuing on some HPCarm stuff. A NetBSD/hpcarm kernel prints
		some boot messages on an emulated Jornada 720.
		Making dev_ram work better with dyntrans (speeds up some things
		quite a bit).
20051021	Automatically generating some of the most common ARM load/store
		multiple instructions.
20051022	Better statistics gathering for the ARM load/store multiple.
		Various other dyntrans and device updates.
20051023	Various minor updates.
20051024	Continuing; minor device and dyntrans fine-tuning. Adding the
		first "reasonable" instruction combination hacks for ARM (the
		cores of NetBSD/cats' memset and memcpy).
20051025	Fixing a dyntrans-related bug in dev_vga. Also changing the
		dyntrans low/high access notification to only be updated on
		writes, not reads. Hopefully it will be enough. (dev_vga in
		charcell mode now seems to work correctly with both reads and
		writes.)
		Experimenting with gathering dyntrans statistics (which parts
		of emulated RAM that are actually executed), and adding
		instruction combination hacks for cache cleaning and a part of
		NetBSD's scanc() function.
20051026	Adding a bitmap for ARM emulation which indicates if a page is
		(specifically) user accessible; loads and stores with the t-
		flag set can now use the translation arrays, which results in
		a measurable speedup.
20051027	Dyntrans updates; adding an extra bitmap array for 32-bit
		emulation modes, speeding up the check whether a physical page
		has any code translations or not (O(n) -> O(1)). Doing a
		similar reduction of O(n) to O(1) by avoiding the scan through
		the translation entries on a translation update (32-bit mode
		only).
		Various other minor hacks.
20051029	Quick release, without any testing at all.

==============  RELEASE 0.3.6.2  ==============


1 dpavlin 14 /*
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 dpavlin 18 * $Id: cpu_ppc_instr.c,v 1.20 2005/10/27 14:01:13 debug Exp $
29 dpavlin 14 *
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     #define DOT(n) X(n ## _dot) { instr(n)(cpu,ic); \
40     update_cr0(cpu, reg(ic->arg[1])); }
41    
42    
43     /*
44     * nop: Do nothing.
45     */
46     X(nop)
47     {
48     }
49    
50    
51     /*
52     * invalid: To catch bugs.
53     */
54     X(invalid)
55     {
56     fatal("INTERNAL ERROR\n");
57     exit(1);
58     }
59    
60    
61     /*
62     * addi: Add immediate.
63     *
64     * arg[0] = pointer to source uint64_t
65     * arg[1] = immediate value (int32_t or larger)
66     * arg[2] = pointer to destination uint64_t
67     */
68     X(addi)
69     {
70     reg(ic->arg[2]) = reg(ic->arg[0]) + (int32_t)ic->arg[1];
71     }
72    
73    
74     /*
75     * andi_dot: AND immediate, update CR.
76     *
77     * arg[0] = pointer to source uint64_t
78     * arg[1] = immediate value (uint32_t)
79     * arg[2] = pointer to destination uint64_t
80     */
81     X(andi_dot)
82     {
83     MODE_uint_t tmp = reg(ic->arg[0]) & (uint32_t)ic->arg[1];
84     reg(ic->arg[2]) = tmp;
85     update_cr0(cpu, tmp);
86     }
87    
88    
89     /*
90     * addic: Add immediate, Carry.
91     *
92     * arg[0] = pointer to source register
93     * arg[1] = immediate value (int32_t or larger)
94     * arg[2] = pointer to destination register
95     */
96     X(addic)
97     {
98     /* TODO/NOTE: Only for 32-bit mode, so far! */
99     uint64_t tmp = (uint32_t)reg(ic->arg[0]);
100     uint64_t tmp2 = tmp;
101     cpu->cd.ppc.xer &= ~PPC_XER_CA;
102     tmp2 += (uint32_t)ic->arg[1];
103     if ((tmp2 >> 32) != (tmp >> 32))
104     cpu->cd.ppc.xer |= PPC_XER_CA;
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     MODE_uint_t tmp = (int64_t)(int32_t)ic->arg[1];
119     cpu->cd.ppc.xer &= ~PPC_XER_CA;
120     if (tmp >= reg(ic->arg[0]))
121     cpu->cd.ppc.xer |= PPC_XER_CA;
122     reg(ic->arg[2]) = tmp - reg(ic->arg[0]);
123     }
124    
125    
126     /*
127     * addic_dot: Add immediate, Carry.
128     *
129     * arg[0] = pointer to source uint64_t
130     * arg[1] = immediate value (int32_t or larger)
131     * arg[2] = pointer to destination uint64_t
132     */
133     X(addic_dot)
134     {
135     /* TODO/NOTE: Only for 32-bit mode, so far! */
136     uint64_t tmp = (uint32_t)reg(ic->arg[0]);
137     uint64_t tmp2 = tmp;
138     cpu->cd.ppc.xer &= ~PPC_XER_CA;
139     tmp2 += (uint32_t)ic->arg[1];
140     if ((tmp2 >> 32) != (tmp >> 32))
141     cpu->cd.ppc.xer |= PPC_XER_CA;
142     reg(ic->arg[2]) = (uint32_t)tmp2;
143     update_cr0(cpu, (uint32_t)tmp2);
144     }
145    
146    
147     /*
148     * bclr: Branch Conditional to Link Register
149     *
150     * arg[0] = bo
151     * arg[1] = bi
152     * arg[2] = bh
153     */
154     X(bclr)
155     {
156     int bo = ic->arg[0], bi = ic->arg[1] /* , bh = ic->arg[2] */;
157     int ctr_ok, cond_ok;
158     uint64_t old_pc = cpu->pc;
159     MODE_uint_t tmp, addr = cpu->cd.ppc.lr;
160     if (!(bo & 4))
161     cpu->cd.ppc.ctr --;
162     ctr_ok = (bo >> 2) & 1;
163     tmp = cpu->cd.ppc.ctr;
164     ctr_ok |= ( (tmp != 0) ^ ((bo >> 1) & 1) );
165     cond_ok = (bo >> 4) & 1;
166     cond_ok |= ( ((bo >> 3) & 1) == ((cpu->cd.ppc.cr >> (31-bi)) & 1) );
167     if (ctr_ok && cond_ok) {
168     uint64_t mask_within_page =
169     ((PPC_IC_ENTRIES_PER_PAGE-1) << PPC_INSTR_ALIGNMENT_SHIFT)
170     | ((1 << PPC_INSTR_ALIGNMENT_SHIFT) - 1);
171     cpu->pc = addr & ~((1 << PPC_INSTR_ALIGNMENT_SHIFT) - 1);
172     /* TODO: trace in separate (duplicate) function? */
173     if (cpu->machine->show_trace_tree)
174     cpu_functioncall_trace_return(cpu);
175     if ((old_pc & ~mask_within_page) ==
176     (cpu->pc & ~mask_within_page)) {
177     cpu->cd.ppc.next_ic =
178     cpu->cd.ppc.cur_ic_page +
179     ((cpu->pc & mask_within_page) >>
180     PPC_INSTR_ALIGNMENT_SHIFT);
181     } else {
182     /* Find the new physical page and update pointers: */
183     DYNTRANS_PC_TO_POINTERS(cpu);
184     }
185     }
186     }
187     X(bclr_l)
188     {
189     uint64_t low_pc, old_pc = cpu->pc;
190     int bo = ic->arg[0], bi = ic->arg[1] /* , bh = ic->arg[2] */;
191     int ctr_ok, cond_ok;
192     MODE_uint_t tmp, addr = cpu->cd.ppc.lr;
193     if (!(bo & 4))
194     cpu->cd.ppc.ctr --;
195     ctr_ok = (bo >> 2) & 1;
196     tmp = cpu->cd.ppc.ctr;
197     ctr_ok |= ( (tmp != 0) ^ ((bo >> 1) & 1) );
198     cond_ok = (bo >> 4) & 1;
199     cond_ok |= ( ((bo >> 3) & 1) == ((cpu->cd.ppc.cr >> (31-bi)) & 1) );
200    
201     /* Calculate return PC: */
202     low_pc = ((size_t)cpu->cd.ppc.next_ic - (size_t)
203     cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
204     cpu->cd.ppc.lr = cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2);
205     cpu->cd.ppc.lr += (low_pc << 2);
206    
207     if (ctr_ok && cond_ok) {
208     uint64_t mask_within_page =
209     ((PPC_IC_ENTRIES_PER_PAGE-1) << PPC_INSTR_ALIGNMENT_SHIFT)
210     | ((1 << PPC_INSTR_ALIGNMENT_SHIFT) - 1);
211     cpu->pc = addr & ~((1 << PPC_INSTR_ALIGNMENT_SHIFT) - 1);
212     /* TODO: trace in separate (duplicate) function? */
213     if (cpu->machine->show_trace_tree)
214     cpu_functioncall_trace_return(cpu);
215     if (cpu->machine->show_trace_tree)
216     cpu_functioncall_trace(cpu, cpu->pc);
217     if ((old_pc & ~mask_within_page) ==
218     (cpu->pc & ~mask_within_page)) {
219     cpu->cd.ppc.next_ic =
220     cpu->cd.ppc.cur_ic_page +
221     ((cpu->pc & mask_within_page) >>
222     PPC_INSTR_ALIGNMENT_SHIFT);
223     } else {
224     /* Find the new physical page and update pointers: */
225     DYNTRANS_PC_TO_POINTERS(cpu);
226     }
227     }
228     }
229    
230    
231     /*
232     * bcctr: Branch Conditional to Count register
233     *
234     * arg[0] = bo
235     * arg[1] = bi
236     * arg[2] = bh
237     */
238     X(bcctr)
239     {
240     int bo = ic->arg[0], bi = ic->arg[1] /* , bh = ic->arg[2] */;
241     uint64_t old_pc = cpu->pc;
242     MODE_uint_t addr = cpu->cd.ppc.ctr;
243     int cond_ok = (bo >> 4) & 1;
244     cond_ok |= ( ((bo >> 3) & 1) == ((cpu->cd.ppc.cr >> (31-bi)) & 1) );
245     if (cond_ok) {
246     uint64_t mask_within_page =
247     ((PPC_IC_ENTRIES_PER_PAGE-1) << PPC_INSTR_ALIGNMENT_SHIFT)
248     | ((1 << PPC_INSTR_ALIGNMENT_SHIFT) - 1);
249     cpu->pc = addr & ~((1 << PPC_INSTR_ALIGNMENT_SHIFT) - 1);
250     /* TODO: trace in separate (duplicate) function? */
251     if (cpu->machine->show_trace_tree)
252     cpu_functioncall_trace_return(cpu);
253     if ((old_pc & ~mask_within_page) ==
254     (cpu->pc & ~mask_within_page)) {
255     cpu->cd.ppc.next_ic =
256     cpu->cd.ppc.cur_ic_page +
257     ((cpu->pc & mask_within_page) >>
258     PPC_INSTR_ALIGNMENT_SHIFT);
259     } else {
260     /* Find the new physical page and update pointers: */
261     DYNTRANS_PC_TO_POINTERS(cpu);
262     }
263     }
264     }
265     X(bcctr_l)
266     {
267     uint64_t low_pc, old_pc = cpu->pc;
268     int bo = ic->arg[0], bi = ic->arg[1] /* , bh = ic->arg[2] */;
269     MODE_uint_t addr = cpu->cd.ppc.ctr;
270     int cond_ok = (bo >> 4) & 1;
271     cond_ok |= ( ((bo >> 3) & 1) == ((cpu->cd.ppc.cr >> (31-bi)) & 1) );
272    
273     /* Calculate return PC: */
274     low_pc = ((size_t)cpu->cd.ppc.next_ic - (size_t)
275     cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
276     cpu->cd.ppc.lr = cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2);
277     cpu->cd.ppc.lr += (low_pc << 2);
278    
279     if (cond_ok) {
280     uint64_t mask_within_page =
281     ((PPC_IC_ENTRIES_PER_PAGE-1) << PPC_INSTR_ALIGNMENT_SHIFT)
282     | ((1 << PPC_INSTR_ALIGNMENT_SHIFT) - 1);
283     cpu->pc = addr & ~((1 << PPC_INSTR_ALIGNMENT_SHIFT) - 1);
284     /* TODO: trace in separate (duplicate) function? */
285     if (cpu->machine->show_trace_tree)
286     cpu_functioncall_trace(cpu, cpu->pc);
287     if ((old_pc & ~mask_within_page) ==
288     (cpu->pc & ~mask_within_page)) {
289     cpu->cd.ppc.next_ic =
290     cpu->cd.ppc.cur_ic_page +
291     ((cpu->pc & mask_within_page) >>
292     PPC_INSTR_ALIGNMENT_SHIFT);
293     } else {
294     /* Find the new physical page and update pointers: */
295     DYNTRANS_PC_TO_POINTERS(cpu);
296     }
297     }
298     }
299    
300    
301     /*
302     * b: Branch (to a different translated page)
303     *
304     * arg[0] = relative offset (as an int32_t)
305     */
306     X(b)
307     {
308     uint64_t low_pc;
309    
310     /* Calculate new PC from this instruction + arg[0] */
311     low_pc = ((size_t)ic - (size_t)
312     cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
313     cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2);
314     cpu->pc += (low_pc << 2);
315     cpu->pc += (int32_t)ic->arg[0];
316    
317     /* Find the new physical page and update the translation pointers: */
318     DYNTRANS_PC_TO_POINTERS(cpu);
319     }
320    
321    
322     /*
323     * bc: Branch Conditional (to a different translated page)
324     *
325     * arg[0] = relative offset (as an int32_t)
326     * arg[1] = bo
327     * arg[2] = bi
328     */
329     X(bc)
330     {
331     MODE_uint_t tmp;
332     int ctr_ok, cond_ok, bi = ic->arg[2], bo = ic->arg[1];
333     if (!(bo & 4))
334     cpu->cd.ppc.ctr --;
335     ctr_ok = (bo >> 2) & 1;
336     tmp = cpu->cd.ppc.ctr;
337     ctr_ok |= ( (tmp != 0) ^ ((bo >> 1) & 1) );
338     cond_ok = (bo >> 4) & 1;
339     cond_ok |= ( ((bo >> 3) & 1) ==
340     ((cpu->cd.ppc.cr >> (31-bi)) & 1) );
341     if (ctr_ok && cond_ok)
342     instr(b)(cpu,ic);
343     }
344    
345    
346     /*
347     * b_samepage: Branch (to within the same translated page)
348     *
349     * arg[0] = pointer to new ppc_instr_call
350     */
351     X(b_samepage)
352     {
353     cpu->cd.ppc.next_ic = (struct ppc_instr_call *) ic->arg[0];
354     }
355    
356    
357     /*
358     * bc_samepage: Branch Conditional (to within the same page)
359     *
360     * arg[0] = new ic ptr
361     * arg[1] = bo
362     * arg[2] = bi
363     */
364     X(bc_samepage)
365     {
366     MODE_uint_t tmp;
367     int ctr_ok, cond_ok, bi = ic->arg[2], bo = ic->arg[1];
368     if (!(bo & 4))
369     cpu->cd.ppc.ctr --;
370     ctr_ok = (bo >> 2) & 1;
371     tmp = cpu->cd.ppc.ctr;
372     ctr_ok |= ( (tmp != 0) ^ ((bo >> 1) & 1) );
373     cond_ok = (bo >> 4) & 1;
374     cond_ok |= ( ((bo >> 3) & 1) ==
375     ((cpu->cd.ppc.cr >> (31-bi)) & 1) );
376     if (ctr_ok && cond_ok)
377     instr(b_samepage)(cpu,ic);
378     }
379    
380    
381     /*
382     * bl: Branch and Link (to a different translated page)
383     *
384     * arg[0] = relative offset (as an int32_t)
385     */
386     X(bl)
387     {
388     uint32_t low_pc;
389    
390     /* Calculate LR: */
391     low_pc = ((size_t)cpu->cd.ppc.next_ic - (size_t)
392     cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
393     cpu->cd.ppc.lr = cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2);
394     cpu->cd.ppc.lr += (low_pc << 2);
395    
396     /* Calculate new PC from this instruction + arg[0] */
397     low_pc = ((size_t)ic - (size_t)
398     cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
399     cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2);
400     cpu->pc += (low_pc << 2);
401     cpu->pc += (int32_t)ic->arg[0];
402    
403     /* Find the new physical page and update the translation pointers: */
404     DYNTRANS_PC_TO_POINTERS(cpu);
405     }
406    
407    
408     /*
409     * bl_trace: Branch and Link (to a different translated page) (with trace)
410     *
411     * arg[0] = relative offset (as an int32_t)
412     */
413     X(bl_trace)
414     {
415     uint32_t low_pc;
416    
417     /* Calculate LR: */
418     low_pc = ((size_t)cpu->cd.ppc.next_ic - (size_t)
419     cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
420     cpu->cd.ppc.lr = cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2);
421     cpu->cd.ppc.lr += (low_pc << 2);
422    
423     /* Calculate new PC from this instruction + arg[0] */
424     low_pc = ((size_t)ic - (size_t)
425     cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
426     cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2);
427     cpu->pc += (low_pc << 2);
428     cpu->pc += (int32_t)ic->arg[0];
429    
430     cpu_functioncall_trace(cpu, cpu->pc);
431    
432     /* Find the new physical page and update the translation pointers: */
433     DYNTRANS_PC_TO_POINTERS(cpu);
434     }
435    
436    
437     /*
438     * bl_samepage: Branch and Link (to within the same translated page)
439     *
440     * arg[0] = pointer to new ppc_instr_call
441     */
442     X(bl_samepage)
443     {
444     uint32_t low_pc;
445    
446     /* Calculate LR: */
447     low_pc = ((size_t)ic - (size_t)
448     cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call) + 1;
449     cpu->cd.ppc.lr = cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2);
450     cpu->cd.ppc.lr += (low_pc << 2);
451    
452     cpu->cd.ppc.next_ic = (struct ppc_instr_call *) ic->arg[0];
453     }
454    
455    
456     /*
457     * bl_samepage_trace: Branch and Link (to within the same translated page)
458     *
459     * arg[0] = pointer to new ppc_instr_call
460     */
461     X(bl_samepage_trace)
462     {
463     uint32_t low_pc;
464    
465     /* Calculate LR: */
466     low_pc = ((size_t)cpu->cd.ppc.next_ic - (size_t)
467     cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
468     cpu->cd.ppc.lr = cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2);
469     cpu->cd.ppc.lr += (low_pc << 2);
470    
471     cpu->cd.ppc.next_ic = (struct ppc_instr_call *) ic->arg[0];
472    
473     /* Calculate new PC (for the trace) */
474     low_pc = ((size_t)cpu->cd.ppc.next_ic - (size_t)
475     cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
476     cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2);
477     cpu->pc += (low_pc << 2);
478     cpu_functioncall_trace(cpu, cpu->pc);
479     }
480    
481    
482     /*
483     * cntlzw: Count leading zeroes (32-bit word).
484     *
485     * arg[0] = ptr to rs
486     * arg[1] = ptr to ra
487     */
488     X(cntlzw)
489     {
490     uint32_t tmp = reg(ic->arg[0]);
491     int i;
492     for (i=0; i<32; i++) {
493     if (tmp & 0x80000000)
494     break;
495     tmp <<= 1;
496     }
497     reg(ic->arg[1]) = i;
498     }
499    
500    
501     /*
502     * cmpd: Compare Doubleword
503     *
504     * arg[0] = ptr to ra
505     * arg[1] = ptr to rb
506     * arg[2] = bf
507     */
508     X(cmpd)
509     {
510     int64_t tmp = reg(ic->arg[0]), tmp2 = reg(ic->arg[1]);
511     int bf = ic->arg[2], c;
512     if (tmp < tmp2)
513     c = 8;
514     else if (tmp > tmp2)
515     c = 4;
516     else
517     c = 2;
518     c |= ((cpu->cd.ppc.xer >> 31) & 1); /* SO bit, copied from XER */
519     cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));
520     cpu->cd.ppc.cr |= (c << (28 - 4*bf));
521     }
522    
523    
524     /*
525     * cmpld: Compare Doubleword, unsigned
526     *
527     * arg[0] = ptr to ra
528     * arg[1] = ptr to rb
529     * arg[2] = bf
530     */
531     X(cmpld)
532     {
533     uint64_t tmp = reg(ic->arg[0]), tmp2 = reg(ic->arg[1]);
534     int bf = ic->arg[2], c;
535     if (tmp < tmp2)
536     c = 8;
537     else if (tmp > tmp2)
538     c = 4;
539     else
540     c = 2;
541     c |= ((cpu->cd.ppc.xer >> 31) & 1); /* SO bit, copied from XER */
542     cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));
543     cpu->cd.ppc.cr |= (c << (28 - 4*bf));
544     }
545    
546    
547     /*
548     * cmpdi: Compare Doubleword immediate
549     *
550     * arg[0] = ptr to ra
551     * arg[1] = int32_t imm
552     * arg[2] = bf
553     */
554     X(cmpdi)
555     {
556     int64_t tmp = reg(ic->arg[0]), imm = (int32_t)ic->arg[1];
557     int bf = ic->arg[2], c;
558     if (tmp < imm)
559     c = 8;
560     else if (tmp > imm)
561     c = 4;
562     else
563     c = 2;
564     c |= ((cpu->cd.ppc.xer >> 31) & 1); /* SO bit, copied from XER */
565     cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));
566     cpu->cd.ppc.cr |= (c << (28 - 4*bf));
567     }
568    
569    
570     /*
571     * cmpldi: Compare Doubleword immediate, logical
572     *
573     * arg[0] = ptr to ra
574     * arg[1] = int32_t imm
575     * arg[2] = bf
576     */
577     X(cmpldi)
578     {
579     uint64_t tmp = reg(ic->arg[0]), imm = (uint32_t)ic->arg[1];
580     int bf = ic->arg[2], c;
581     if (tmp < imm)
582     c = 8;
583     else if (tmp > imm)
584     c = 4;
585     else
586     c = 2;
587     c |= ((cpu->cd.ppc.xer >> 31) & 1); /* SO bit, copied from XER */
588     cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));
589     cpu->cd.ppc.cr |= (c << (28 - 4*bf));
590     }
591    
592    
593     /*
594     * cmpw: Compare Word
595     *
596     * arg[0] = ptr to ra
597     * arg[1] = ptr to rb
598     * arg[2] = bf
599     */
600     X(cmpw)
601     {
602     int32_t tmp = reg(ic->arg[0]), tmp2 = reg(ic->arg[1]);
603     int bf = ic->arg[2], c;
604     if (tmp < tmp2)
605     c = 8;
606     else if (tmp > tmp2)
607     c = 4;
608     else
609     c = 2;
610     c |= ((cpu->cd.ppc.xer >> 31) & 1); /* SO bit, copied from XER */
611     cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));
612     cpu->cd.ppc.cr |= (c << (28 - 4*bf));
613     }
614    
615    
616     /*
617     * cmplw: Compare Word, unsigned
618     *
619     * arg[0] = ptr to ra
620     * arg[1] = ptr to rb
621     * arg[2] = bf
622     */
623     X(cmplw)
624     {
625     uint32_t tmp = reg(ic->arg[0]), tmp2 = reg(ic->arg[1]);
626     int bf = ic->arg[2], c;
627     if (tmp < tmp2)
628     c = 8;
629     else if (tmp > tmp2)
630     c = 4;
631     else
632     c = 2;
633     c |= ((cpu->cd.ppc.xer >> 31) & 1); /* SO bit, copied from XER */
634     cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));
635     cpu->cd.ppc.cr |= (c << (28 - 4*bf));
636     }
637    
638    
639     /*
640     * cmpwi: Compare Word immediate
641     *
642     * arg[0] = ptr to ra
643     * arg[1] = int32_t imm
644     * arg[2] = bf
645     */
646     X(cmpwi)
647     {
648     int32_t tmp = reg(ic->arg[0]), imm = ic->arg[1];
649     int bf = ic->arg[2], c;
650     if (tmp < imm)
651     c = 8;
652     else if (tmp > imm)
653     c = 4;
654     else
655     c = 2;
656     c |= ((cpu->cd.ppc.xer >> 31) & 1); /* SO bit, copied from XER */
657     cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));
658     cpu->cd.ppc.cr |= (c << (28 - 4*bf));
659     }
660    
661    
662     /*
663     * cmplwi: Compare Word immediate, logical
664     *
665     * arg[0] = ptr to ra
666     * arg[1] = int32_t imm
667     * arg[2] = bf
668     */
669     X(cmplwi)
670     {
671     uint32_t tmp = reg(ic->arg[0]), imm = ic->arg[1];
672     int bf = ic->arg[2], c;
673     if (tmp < imm)
674     c = 8;
675     else if (tmp > imm)
676     c = 4;
677     else
678     c = 2;
679     c |= ((cpu->cd.ppc.xer >> 31) & 1); /* SO bit, copied from XER */
680     cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));
681     cpu->cd.ppc.cr |= (c << (28 - 4*bf));
682     }
683    
684    
685     /*
686     * dcbz: Data-Cache Block Zero
687     *
688     * arg[0] = ptr to ra (or zero)
689     * arg[1] = ptr to rb
690     */
691     X(dcbz)
692     {
693     MODE_uint_t addr = reg(ic->arg[0]) + reg(ic->arg[1]);
694     unsigned char cacheline[128];
695     int cacheline_size = 1 << cpu->cd.ppc.cpu_type.dlinesize;
696     int cleared = 0;
697    
698     addr &= ~(cacheline_size - 1);
699     memset(cacheline, 0, sizeof(cacheline));
700    
701     while (cleared < cacheline_size) {
702     int to_clear = cacheline_size < sizeof(cacheline)?
703     cacheline_size : sizeof(cacheline);
704     if (cpu->memory_rw(cpu, cpu->mem, addr, cacheline, to_clear,
705     MEM_WRITE, CACHE_DATA) != MEMORY_ACCESS_OK) {
706     fatal("dcbz: error: TODO\n");
707     exit(1);
708     }
709    
710     cleared += to_clear;
711     addr += to_clear;
712     }
713     }
714    
715    
716     /*
717     * fmr: Floating-point Move
718     *
719     * arg[0] = ptr to frb
720     * arg[1] = ptr to frt
721     */
722     X(fmr)
723     {
724     *(uint64_t *)ic->arg[1] = *(uint64_t *)ic->arg[0];
725     }
726    
727    
728     /*
729     * llsc: Load-linked and store conditional
730     *
731     * arg[0] = copy of the instruction word.
732     */
733     X(llsc)
734     {
735     int iw = ic->arg[0], len = 4, load = 0, xo = (iw >> 1) & 1023;
736     int i, rc = iw & 1, rt, ra, rb;
737     uint64_t addr = 0, value;
738     unsigned char d[8];
739    
740     switch (xo) {
741     case PPC_31_LDARX:
742     len = 8;
743     case PPC_31_LWARX:
744     load = 1;
745     break;
746     case PPC_31_STDCX_DOT:
747     len = 8;
748     case PPC_31_STWCX_DOT:
749     break;
750     }
751    
752     rt = (iw >> 21) & 31;
753     ra = (iw >> 16) & 31;
754     rb = (iw >> 11) & 31;
755    
756     if (ra != 0)
757     addr = cpu->cd.ppc.gpr[ra];
758     addr += cpu->cd.ppc.gpr[rb];
759    
760     if (load) {
761     if (rc) {
762     fatal("ll: rc-bit set?\n");
763     exit(1);
764     }
765     if (cpu->memory_rw(cpu, cpu->mem, addr, d, len,
766     MEM_READ, CACHE_DATA) != MEMORY_ACCESS_OK) {
767     fatal("ll: error: TODO\n");
768     exit(1);
769     }
770    
771     value = 0;
772     for (i=0; i<len; i++) {
773     value <<= 8;
774     if (cpu->byte_order == EMUL_BIG_ENDIAN)
775     value |= d[i];
776     else
777     value |= d[len - 1 - i];
778     }
779    
780     cpu->cd.ppc.gpr[rt] = value;
781     cpu->cd.ppc.ll_addr = addr;
782     cpu->cd.ppc.ll_bit = 1;
783     } else {
784 dpavlin 18 uint32_t old_so = cpu->cd.ppc.xer & PPC_XER_SO;
785 dpavlin 14 if (!rc) {
786     fatal("sc: rc-bit not set?\n");
787     exit(1);
788     }
789    
790     value = cpu->cd.ppc.gpr[rt];
791    
792     /* "If the store is performed, bits 0-2 of Condition
793     Register Field 0 are set to 0b001, otherwise, they are
794     set to 0b000. The SO bit of the XER is copied to to bit
795     4 of Condition Register Field 0. */
796     if (!cpu->cd.ppc.ll_bit || cpu->cd.ppc.ll_addr != addr) {
797     cpu->cd.ppc.cr &= 0x0fffffff;
798     if (old_so)
799     cpu->cd.ppc.cr |= 0x10000000;
800     cpu->cd.ppc.ll_bit = 0;
801     return;
802     }
803    
804     for (i=0; i<len; i++) {
805     if (cpu->byte_order == EMUL_BIG_ENDIAN)
806     d[len - 1 - i] = value >> (8*i);
807     else
808     d[i] = value >> (8*i);
809     }
810    
811     if (cpu->memory_rw(cpu, cpu->mem, addr, d, len,
812     MEM_WRITE, CACHE_DATA) != MEMORY_ACCESS_OK) {
813     fatal("sc: error: TODO\n");
814     exit(1);
815     }
816    
817     cpu->cd.ppc.cr &= 0x0fffffff;
818     cpu->cd.ppc.cr |= 0x20000000; /* success! */
819     if (old_so)
820     cpu->cd.ppc.cr |= 0x10000000;
821    
822     /* Clear _all_ CPUs' ll_bits: */
823     for (i=0; i<cpu->machine->ncpus; i++)
824     cpu->machine->cpus[i]->cd.ppc.ll_bit = 0;
825     }
826     }
827    
828    
829     /*
830     * mtsr: Move To Segment Register
831     *
832     * arg[0] = segment register nr (0..15)
833     * arg[1] = ptr to rt
834     */
835     X(mtsr)
836     {
837     /* TODO: This only works for 32-bit mode */
838     cpu->cd.ppc.sr[ic->arg[0]] = reg(ic->arg[1]);
839     }
840    
841    
842     /*
843     * mfsrin, mtsrin: Move From/To Segment Register Indirect
844     *
845     * arg[0] = ptr to rb
846     * arg[1] = ptr to rt
847     */
848     X(mfsrin)
849     {
850     /* TODO: This only works for 32-bit mode */
851     uint32_t sr_num = reg(ic->arg[0]) >> 28;
852     reg(ic->arg[1]) = cpu->cd.ppc.sr[sr_num];
853     }
854     X(mtsrin)
855     {
856     /* TODO: This only works for 32-bit mode */
857     uint32_t sr_num = reg(ic->arg[0]) >> 28;
858     cpu->cd.ppc.sr[sr_num] = reg(ic->arg[1]);
859     }
860    
861    
862     /*
863     * rldicr:
864     *
865     * arg[0] = copy of the instruction word
866     */
867     X(rldicr)
868     {
869     int rs = (ic->arg[0] >> 21) & 31;
870     int ra = (ic->arg[0] >> 16) & 31;
871     int sh = ((ic->arg[0] >> 11) & 31) | ((ic->arg[0] & 2) << 4);
872     int me = ((ic->arg[0] >> 6) & 31) | (ic->arg[0] & 0x20);
873     int rc = ic->arg[0] & 1;
874     uint64_t tmp = cpu->cd.ppc.gpr[rs];
875     /* TODO: Fix this, its performance is awful: */
876     while (sh-- != 0) {
877     int b = (tmp >> 63) & 1;
878     tmp = (tmp << 1) | b;
879     }
880     while (me++ < 63)
881     tmp &= ~((uint64_t)1 << (63-me));
882     cpu->cd.ppc.gpr[ra] = tmp;
883     if (rc)
884     update_cr0(cpu, tmp);
885     }
886    
887    
888     /*
889     * rlwinm:
890     *
891     * arg[0] = ptr to rs
892     * arg[1] = ptr to ra
893     * arg[2] = copy of the instruction word
894     */
895     X(rlwinm)
896     {
897     MODE_uint_t tmp = reg(ic->arg[0]), ra = 0;
898     uint32_t iword = ic->arg[2];
899     int sh, mb, me, rc;
900    
901     sh = (iword >> 11) & 31;
902     mb = (iword >> 6) & 31;
903     me = (iword >> 1) & 31;
904     rc = iword & 1;
905    
906     /* TODO: Fix this, its performance is awful: */
907     while (sh-- != 0) {
908     int b = (tmp >> 31) & 1;
909     tmp = (tmp << 1) | b;
910     }
911     for (;;) {
912     uint64_t mask;
913     mask = (uint64_t)1 << (31-mb);
914     ra |= (tmp & mask);
915     if (mb == me)
916     break;
917     mb ++;
918     if (mb == 32)
919     mb = 0;
920     }
921     reg(ic->arg[1]) = ra;
922     if (rc)
923     update_cr0(cpu, ra);
924     }
925    
926    
927     /*
928     * rlwimi:
929     *
930     * arg[0] = ptr to rs
931     * arg[1] = ptr to ra
932     * arg[2] = copy of the instruction word
933     */
934     X(rlwimi)
935     {
936     MODE_uint_t tmp = reg(ic->arg[0]), ra = reg(ic->arg[1]);
937     uint32_t iword = ic->arg[2];
938     int sh, mb, me, rc;
939    
940     sh = (iword >> 11) & 31;
941     mb = (iword >> 6) & 31;
942     me = (iword >> 1) & 31;
943     rc = iword & 1;
944    
945     /* TODO: Fix this, its performance is awful: */
946     while (sh-- != 0) {
947     int b = (tmp >> 31) & 1;
948     tmp = (tmp << 1) | b;
949     }
950     for (;;) {
951     uint64_t mask;
952     mask = (uint64_t)1 << (31-mb);
953     ra &= ~mask;
954     ra |= (tmp & mask);
955     if (mb == me)
956     break;
957     mb ++;
958     if (mb == 32)
959     mb = 0;
960     }
961     reg(ic->arg[1]) = ra;
962     if (rc)
963     update_cr0(cpu, ra);
964     }
965    
966    
967     /*
968     * srawi:
969     *
970     * arg[0] = ptr to rs
971     * arg[1] = ptr to ra
972     * arg[2] = sh (shift amount)
973     */
974     X(srawi)
975     {
976     uint32_t tmp = reg(ic->arg[0]);
977     int i = 0, j = 0, sh = ic->arg[2];
978    
979     cpu->cd.ppc.xer &= ~PPC_XER_CA;
980     if (tmp & 0x80000000)
981     i = 1;
982     while (sh-- > 0) {
983     if (tmp & 1)
984     j ++;
985     tmp >>= 1;
986     if (tmp & 0x40000000)
987     tmp |= 0x80000000;
988     }
989     if (i && j>0)
990     cpu->cd.ppc.xer |= PPC_XER_CA;
991     reg(ic->arg[1]) = (int64_t)(int32_t)tmp;
992     }
993     DOT(srawi)
994    
995    
996     /*
997     * mcrf: Move inside condition register
998     *
999     * arg[0] = bf, arg[1] = bfa
1000     */
1001     X(mcrf)
1002     {
1003     int bf = ic->arg[0], bfa = ic->arg[1];
1004     uint32_t tmp = (cpu->cd.ppc.cr >> (28 - bfa*4)) & 0xf;
1005     cpu->cd.ppc.cr &= ~(0xf << (28 - bf*4));
1006     cpu->cd.ppc.cr |= (tmp << (28 - bf*4));
1007     }
1008    
1009    
1010     /*
1011     * crand, crxor etc: Condition Register operations
1012     *
1013     * arg[0] = copy of the instruction word
1014     */
1015     X(crand) {
1016     uint32_t iword = ic->arg[0]; int bt = (iword >> 21) & 31;
1017     int ba = (iword >> 16) & 31, bb = (iword >> 11) & 31;
1018     ba = (cpu->cd.ppc.cr >> (31-ba)) & 1;
1019     bb = (cpu->cd.ppc.cr >> (31-bb)) & 1;
1020     cpu->cd.ppc.cr &= ~(1 << (31-bt));
1021     if (ba & bb)
1022     cpu->cd.ppc.cr |= (1 << (31-bt));
1023     }
1024     X(crandc) {
1025     uint32_t iword = ic->arg[0]; int bt = (iword >> 21) & 31;
1026     int ba = (iword >> 16) & 31, bb = (iword >> 11) & 31;
1027     ba = (cpu->cd.ppc.cr >> (31-ba)) & 1;
1028     bb = (cpu->cd.ppc.cr >> (31-bb)) & 1;
1029     cpu->cd.ppc.cr &= ~(1 << (31-bt));
1030     if (!(ba & bb))
1031     cpu->cd.ppc.cr |= (1 << (31-bt));
1032     }
1033     X(creqv) {
1034     uint32_t iword = ic->arg[0]; int bt = (iword >> 21) & 31;
1035     int ba = (iword >> 16) & 31, bb = (iword >> 11) & 31;
1036     ba = (cpu->cd.ppc.cr >> (31-ba)) & 1;
1037     bb = (cpu->cd.ppc.cr >> (31-bb)) & 1;
1038     cpu->cd.ppc.cr &= ~(1 << (31-bt));
1039     if (!(ba ^ bb))
1040     cpu->cd.ppc.cr |= (1 << (31-bt));
1041     }
1042     X(cror) {
1043     uint32_t iword = ic->arg[0]; int bt = (iword >> 21) & 31;
1044     int ba = (iword >> 16) & 31, bb = (iword >> 11) & 31;
1045     ba = (cpu->cd.ppc.cr >> (31-ba)) & 1;
1046     bb = (cpu->cd.ppc.cr >> (31-bb)) & 1;
1047     cpu->cd.ppc.cr &= ~(1 << (31-bt));
1048     if (ba | bb)
1049     cpu->cd.ppc.cr |= (1 << (31-bt));
1050     }
1051     X(crxor) {
1052     uint32_t iword = ic->arg[0]; int bt = (iword >> 21) & 31;
1053     int ba = (iword >> 16) & 31, bb = (iword >> 11) & 31;
1054     ba = (cpu->cd.ppc.cr >> (31-ba)) & 1;
1055     bb = (cpu->cd.ppc.cr >> (31-bb)) & 1;
1056     cpu->cd.ppc.cr &= ~(1 << (31-bt));
1057     if (ba ^ bb)
1058     cpu->cd.ppc.cr |= (1 << (31-bt));
1059     }
1060    
1061    
1062     /*
1063     * mflr, etc: Move from Link Register etc.
1064     *
1065     * arg[0] = pointer to destination register
1066     */
1067     X(mflr) { reg(ic->arg[0]) = cpu->cd.ppc.lr; }
1068     X(mfctr) { reg(ic->arg[0]) = cpu->cd.ppc.ctr; }
1069     X(mftb) { reg(ic->arg[0]) = cpu->cd.ppc.tbl; }
1070     X(mftbu) { reg(ic->arg[0]) = cpu->cd.ppc.tbu; }
1071     /* TODO: Check privilege level for mfsprg* */
1072     X(mfsrr0) { reg(ic->arg[0]) = cpu->cd.ppc.srr0; }
1073     X(mfsrr1) { reg(ic->arg[0]) = cpu->cd.ppc.srr1; }
1074     X(mfsdr1) { reg(ic->arg[0]) = cpu->cd.ppc.sdr1; }
1075     X(mfdbsr) { reg(ic->arg[0]) = cpu->cd.ppc.dbsr; }
1076     X(mfhid1) { reg(ic->arg[0]) = 0; /* TODO */ }
1077     X(mfl2cr) { reg(ic->arg[0]) = 0; /* TODO */ }
1078     X(mfsprg0) { reg(ic->arg[0]) = cpu->cd.ppc.sprg0; }
1079     X(mfsprg1) { reg(ic->arg[0]) = cpu->cd.ppc.sprg1; }
1080     X(mfsprg2) { reg(ic->arg[0]) = cpu->cd.ppc.sprg2; }
1081     X(mfsprg3) { reg(ic->arg[0]) = cpu->cd.ppc.sprg3; }
1082     X(mfpvr) { reg(ic->arg[0]) = cpu->cd.ppc.pvr; }
1083     X(mfibatu) { reg(ic->arg[0]) = cpu->cd.ppc.ibat_u[ic->arg[1]]; }
1084     X(mfibatl) { reg(ic->arg[0]) = cpu->cd.ppc.ibat_l[ic->arg[1]]; }
1085     X(mfdbatu) { reg(ic->arg[0]) = cpu->cd.ppc.dbat_u[ic->arg[1]]; }
1086     X(mfdbatl) { reg(ic->arg[0]) = cpu->cd.ppc.dbat_l[ic->arg[1]]; }
1087    
1088    
1089     /*
1090     * mtlr etc.: Move to Link Register (or other special register)
1091     *
1092     * arg[0] = pointer to source register
1093     */
1094     X(mtlr) { cpu->cd.ppc.lr = reg(ic->arg[0]); }
1095     X(mtctr) { cpu->cd.ppc.ctr = reg(ic->arg[0]); }
1096     /* TODO: Check privilege level for these: */
1097     X(mtsrr0) { cpu->cd.ppc.srr0 = reg(ic->arg[0]); }
1098     X(mtsrr1) { cpu->cd.ppc.srr1 = reg(ic->arg[0]); }
1099     X(mtsdr1) { cpu->cd.ppc.sdr1 = reg(ic->arg[0]); }
1100     X(mtdbsr) { cpu->cd.ppc.dbsr = reg(ic->arg[0]); }
1101     X(mtsprg0) { cpu->cd.ppc.sprg0 = reg(ic->arg[0]); }
1102     X(mtsprg1) { cpu->cd.ppc.sprg1 = reg(ic->arg[0]); }
1103     X(mtsprg2) { cpu->cd.ppc.sprg2 = reg(ic->arg[0]); }
1104     X(mtsprg3) { cpu->cd.ppc.sprg3 = reg(ic->arg[0]); }
1105     X(mtibatu) { cpu->cd.ppc.ibat_u[ic->arg[1]] = reg(ic->arg[0]); }
1106     X(mtibatl) { cpu->cd.ppc.ibat_l[ic->arg[1]] = reg(ic->arg[0]); }
1107     X(mtdbatu) { cpu->cd.ppc.dbat_u[ic->arg[1]] = reg(ic->arg[0]); }
1108     X(mtdbatl) { cpu->cd.ppc.dbat_l[ic->arg[1]] = reg(ic->arg[0]); }
1109    
1110    
1111     /*
1112     * rfi: Return from Interrupt
1113     */
1114     X(rfi)
1115     {
1116     uint64_t tmp;
1117    
1118     reg_access_msr(cpu, &tmp, 0);
1119     tmp &= ~0xffff;
1120     tmp |= (cpu->cd.ppc.srr1 & 0xffff);
1121     reg_access_msr(cpu, &tmp, 1);
1122    
1123     cpu->pc = cpu->cd.ppc.srr0;
1124     DYNTRANS_PC_TO_POINTERS(cpu);
1125     }
1126    
1127    
1128     /*
1129     * mfcr: Move From Condition Register
1130     *
1131     * arg[0] = pointer to destination register
1132     */
1133     X(mfcr)
1134     {
1135     reg(ic->arg[0]) = cpu->cd.ppc.cr;
1136     }
1137    
1138    
1139     /*
1140     * mfmsr: Move From MSR
1141     *
1142     * arg[0] = pointer to destination register
1143     */
1144     X(mfmsr)
1145     {
1146     reg_access_msr(cpu, (uint64_t*)ic->arg[0], 0);
1147     }
1148    
1149    
1150     /*
1151     * mtmsr: Move To MSR
1152     *
1153     * arg[0] = pointer to source register
1154     */
1155     X(mtmsr)
1156     {
1157     reg_access_msr(cpu, (uint64_t*)ic->arg[0], 1);
1158     }
1159    
1160    
1161     /*
1162     * mtcrf: Move To Condition Register Fields
1163     *
1164     * arg[0] = pointer to source register
1165     */
1166     X(mtcrf)
1167     {
1168     cpu->cd.ppc.cr &= ~ic->arg[1];
1169     cpu->cd.ppc.cr |= (reg(ic->arg[0]) & ic->arg[1]);
1170     }
1171    
1172    
1173     /*
1174     * mulli: Multiply Low Immediate.
1175     *
1176     * arg[0] = pointer to source register ra
1177     * arg[1] = int32_t immediate
1178     * arg[2] = pointer to destination register rt
1179     */
1180     X(mulli)
1181     {
1182     reg(ic->arg[2]) = (uint32_t)(reg(ic->arg[0]) * ic->arg[1]);
1183     }
1184    
1185    
1186     /*
1187     * Load/Store Multiple:
1188     *
1189     * arg[0] = rs (or rt for loads) NOTE: not a pointer
1190     * arg[1] = ptr to ra
1191     * arg[2] = int32_t immediate offset
1192     */
1193     X(lmw) {
1194     MODE_uint_t addr = reg(ic->arg[1]) + (int32_t)ic->arg[2];
1195     unsigned char d[4];
1196     int n_err = 0, rs = ic->arg[0];
1197    
1198     while (rs <= 31) {
1199     if (cpu->memory_rw(cpu, cpu->mem, addr, d, sizeof(d),
1200     MEM_READ, CACHE_DATA) != MEMORY_ACCESS_OK)
1201     n_err ++;
1202    
1203     if (cpu->byte_order == EMUL_BIG_ENDIAN)
1204     cpu->cd.ppc.gpr[rs] = (d[0] << 24) + (d[1] << 16)
1205     + (d[2] << 8) + d[3];
1206     else
1207     cpu->cd.ppc.gpr[rs] = (d[3] << 24) + (d[2] << 16)
1208     + (d[1] << 8) + d[0];
1209    
1210     if (n_err > 0) {
1211     fatal("TODO: lmw: exception\n");
1212     exit(1);
1213     }
1214    
1215     rs ++;
1216     addr += sizeof(uint32_t);
1217     }
1218     }
1219     X(stmw) {
1220     MODE_uint_t addr = reg(ic->arg[1]) + (int32_t)ic->arg[2];
1221     uint32_t tmp;
1222     unsigned char d[4];
1223     int n_err = 0, rs = ic->arg[0];
1224    
1225     while (rs <= 31) {
1226     tmp = cpu->cd.ppc.gpr[rs];
1227     if (cpu->byte_order == EMUL_BIG_ENDIAN) {
1228     d[3] = tmp; d[2] = tmp >> 8;
1229     d[1] = tmp >> 16; d[0] = tmp >> 24;
1230     } else {
1231     d[0] = tmp; d[1] = tmp >> 8;
1232     d[2] = tmp >> 16; d[3] = tmp >> 24;
1233     }
1234     if (cpu->memory_rw(cpu, cpu->mem, addr, d, sizeof(d),
1235     MEM_WRITE, CACHE_DATA) != MEMORY_ACCESS_OK)
1236     n_err ++;
1237    
1238     if (n_err > 0) {
1239     fatal("TODO: stmw: exception\n");
1240     exit(1);
1241     }
1242    
1243     rs ++;
1244     addr += sizeof(uint32_t);
1245     }
1246     }
1247    
1248    
1249     /*
1250     * Shifts, and, or, xor, etc.
1251     *
1252     * arg[0] = pointer to source register rs
1253     * arg[1] = pointer to source register rb
1254     * arg[2] = pointer to destination register ra
1255     */
1256     X(extsb) {
1257     #ifdef MODE32
1258     reg(ic->arg[2]) = (int32_t)(int8_t)reg(ic->arg[0]);
1259     #else
1260     reg(ic->arg[2]) = (int64_t)(int8_t)reg(ic->arg[0]);
1261     #endif
1262     }
1263     DOT(extsb)
1264     X(extsh) {
1265     #ifdef MODE32
1266     reg(ic->arg[2]) = (int32_t)(int16_t)reg(ic->arg[0]);
1267     #else
1268     reg(ic->arg[2]) = (int64_t)(int16_t)reg(ic->arg[0]);
1269     #endif
1270     }
1271     DOT(extsh)
1272     X(extsw) {
1273     #ifdef MODE32
1274     fatal("TODO: extsw: invalid instruction\n"); exit(1);
1275     #else
1276     reg(ic->arg[2]) = (int64_t)(int32_t)reg(ic->arg[0]);
1277     #endif
1278     }
1279     DOT(extsw)
1280     X(slw) { reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0])
1281     << (reg(ic->arg[1]) & 63); }
1282     DOT(slw)
1283     X(sraw) { reg(ic->arg[2]) =
1284     #ifdef MODE32
1285     (int32_t)
1286     #else
1287     (int64_t)
1288     #endif
1289     reg(ic->arg[0]) >> (reg(ic->arg[1]) & 63); }
1290     DOT(sraw)
1291     X(srw) { reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0])
1292     >> (reg(ic->arg[1]) & 63); }
1293     DOT(srw)
1294     X(and) { reg(ic->arg[2]) = reg(ic->arg[0]) & reg(ic->arg[1]); }
1295     X(and_dot) { reg(ic->arg[2]) = reg(ic->arg[0]) & reg(ic->arg[1]);
1296     update_cr0(cpu, reg(ic->arg[2])); }
1297     X(nand) { reg(ic->arg[2]) = ~(reg(ic->arg[0]) & reg(ic->arg[1])); }
1298     X(nand_dot) { reg(ic->arg[2]) = ~(reg(ic->arg[0]) & reg(ic->arg[1]));
1299     update_cr0(cpu, reg(ic->arg[2])); }
1300     X(andc) { reg(ic->arg[2]) = reg(ic->arg[0]) & (~reg(ic->arg[1])); }
1301     X(andc_dot) { reg(ic->arg[2]) = reg(ic->arg[0]) & (~reg(ic->arg[1]));
1302     update_cr0(cpu, reg(ic->arg[2])); }
1303     X(nor) { reg(ic->arg[2]) = ~(reg(ic->arg[0]) | reg(ic->arg[1])); }
1304     X(nor_dot) { reg(ic->arg[2]) = ~(reg(ic->arg[0]) | reg(ic->arg[1]));
1305     update_cr0(cpu, reg(ic->arg[2])); }
1306     X(or) { reg(ic->arg[2]) = reg(ic->arg[0]) | reg(ic->arg[1]); }
1307     X(or_dot) { reg(ic->arg[2]) = reg(ic->arg[0]) | reg(ic->arg[1]);
1308     update_cr0(cpu, reg(ic->arg[2])); }
1309     X(orc) { reg(ic->arg[2]) = reg(ic->arg[0]) | (~reg(ic->arg[1])); }
1310     X(orc_dot) { reg(ic->arg[2]) = reg(ic->arg[0]) | (~reg(ic->arg[1]));
1311     update_cr0(cpu, reg(ic->arg[2])); }
1312     X(xor) { reg(ic->arg[2]) = reg(ic->arg[0]) ^ reg(ic->arg[1]); }
1313     X(xor_dot) { reg(ic->arg[2]) = reg(ic->arg[0]) ^ reg(ic->arg[1]);
1314     update_cr0(cpu, reg(ic->arg[2])); }
1315    
1316    
1317     /*
1318     * neg:
1319     *
1320     * arg[0] = pointer to source register ra
1321     * arg[1] = pointer to destination register rt
1322     */
1323     X(neg) { reg(ic->arg[1]) = -reg(ic->arg[0]); }
1324     X(neg_dot) { instr(neg)(cpu,ic); update_cr0(cpu, reg(ic->arg[1])); }
1325    
1326    
1327     /*
1328     * mullw, mulhw[u], divw[u]:
1329     *
1330     * arg[0] = pointer to source register ra
1331     * arg[1] = pointer to source register rb
1332     * arg[2] = pointer to destination register rt
1333     */
1334     X(mullw)
1335     {
1336     int32_t sum = (int32_t)reg(ic->arg[0]) * (int32_t)reg(ic->arg[1]);
1337     reg(ic->arg[2]) = (int32_t)sum;
1338     }
1339     X(mulhw)
1340     {
1341     int64_t sum;
1342     sum = (int64_t)(int32_t)reg(ic->arg[0])
1343     * (int64_t)(int32_t)reg(ic->arg[1]);
1344     reg(ic->arg[2]) = sum >> 32;
1345     }
1346     X(mulhwu)
1347     {
1348     uint64_t sum;
1349     sum = (uint64_t)(uint32_t)reg(ic->arg[0])
1350     * (uint64_t)(uint32_t)reg(ic->arg[1]);
1351     reg(ic->arg[2]) = sum >> 32;
1352     }
1353     X(divw)
1354     {
1355     int32_t a = reg(ic->arg[0]), b = reg(ic->arg[1]);
1356     int32_t sum;
1357     if (b == 0)
1358     sum = 0;
1359     else
1360     sum = a / b;
1361     reg(ic->arg[2]) = (uint32_t)sum;
1362     }
1363     X(divwu)
1364     {
1365     uint32_t a = reg(ic->arg[0]), b = reg(ic->arg[1]);
1366     uint32_t sum;
1367     if (b == 0)
1368     sum = 0;
1369     else
1370     sum = a / b;
1371     reg(ic->arg[2]) = sum;
1372     }
1373    
1374    
1375     /*
1376     * add: Add.
1377     *
1378     * arg[0] = pointer to source register ra
1379     * arg[1] = pointer to source register rb
1380     * arg[2] = pointer to destination register rt
1381     */
1382     X(add) { reg(ic->arg[2]) = reg(ic->arg[0]) + reg(ic->arg[1]); }
1383     X(add_dot) { instr(add)(cpu,ic); update_cr0(cpu, reg(ic->arg[2])); }
1384    
1385    
1386     /*
1387     * addc: Add carrying.
1388     *
1389     * arg[0] = pointer to source register ra
1390     * arg[1] = pointer to source register rb
1391     * arg[2] = pointer to destination register rt
1392     */
1393     X(addc)
1394     {
1395     /* TODO: this only works in 32-bit mode */
1396     uint64_t tmp = (uint32_t)reg(ic->arg[0]);
1397     uint64_t tmp2 = tmp;
1398     cpu->cd.ppc.xer &= ~PPC_XER_CA;
1399     tmp += (uint32_t)reg(ic->arg[1]);
1400     if ((tmp >> 32) != (tmp2 >> 32))
1401     cpu->cd.ppc.xer |= PPC_XER_CA;
1402     reg(ic->arg[2]) = (uint32_t)tmp;
1403     }
1404    
1405    
1406     /*
1407     * adde: Add extended, etc.
1408     *
1409     * arg[0] = pointer to source register ra
1410     * arg[1] = pointer to source register rb
1411     * arg[2] = pointer to destination register rt
1412     */
1413     X(adde)
1414     {
1415     /* TODO: this only works in 32-bit mode */
1416     int old_ca = cpu->cd.ppc.xer & PPC_XER_CA;
1417     uint64_t tmp = (uint32_t)reg(ic->arg[0]);
1418     uint64_t tmp2 = tmp;
1419     cpu->cd.ppc.xer &= ~PPC_XER_CA;
1420     tmp += (uint32_t)reg(ic->arg[1]);
1421     if (old_ca)
1422     tmp ++;
1423     if ((tmp >> 32) != (tmp2 >> 32))
1424     cpu->cd.ppc.xer |= PPC_XER_CA;
1425     reg(ic->arg[2]) = (uint32_t)tmp;
1426     }
1427     X(adde_dot) { instr(adde)(cpu,ic); update_cr0(cpu, reg(ic->arg[2])); }
1428     X(addme)
1429     {
1430     /* TODO: this only works in 32-bit mode */
1431     int old_ca = cpu->cd.ppc.xer & PPC_XER_CA;
1432     uint64_t tmp = (uint32_t)reg(ic->arg[0]);
1433     uint64_t tmp2 = tmp;
1434     cpu->cd.ppc.xer &= ~PPC_XER_CA;
1435     if (old_ca)
1436     tmp ++;
1437     tmp += 0xffffffffULL;
1438     if ((tmp >> 32) != (tmp2 >> 32))
1439     cpu->cd.ppc.xer |= PPC_XER_CA;
1440     reg(ic->arg[2]) = (uint32_t)tmp;
1441     }
1442     X(addme_dot) { instr(addme)(cpu,ic); update_cr0(cpu, reg(ic->arg[2])); }
1443     X(addze)
1444     {
1445     /* TODO: this only works in 32-bit mode */
1446     int old_ca = cpu->cd.ppc.xer & PPC_XER_CA;
1447     uint64_t tmp = (uint32_t)reg(ic->arg[0]);
1448     uint64_t tmp2 = tmp;
1449     cpu->cd.ppc.xer &= ~PPC_XER_CA;
1450     if (old_ca)
1451     tmp ++;
1452     if ((tmp >> 32) != (tmp2 >> 32))
1453     cpu->cd.ppc.xer |= PPC_XER_CA;
1454     reg(ic->arg[2]) = (uint32_t)tmp;
1455     }
1456     X(addze_dot) { instr(addze)(cpu,ic); update_cr0(cpu, reg(ic->arg[2])); }
1457    
1458    
1459     /*
1460     * subf: Subf, etc.
1461     *
1462     * arg[0] = pointer to source register ra
1463     * arg[1] = pointer to source register rb
1464     * arg[2] = pointer to destination register rt
1465     */
1466     X(subf) { reg(ic->arg[2]) = reg(ic->arg[1]) - reg(ic->arg[0]); }
1467     X(subf_dot) { instr(subf)(cpu,ic); update_cr0(cpu, reg(ic->arg[2])); }
1468     X(subfc)
1469     {
1470     cpu->cd.ppc.xer &= ~PPC_XER_CA;
1471     if (reg(ic->arg[1]) >= reg(ic->arg[0]))
1472     cpu->cd.ppc.xer |= PPC_XER_CA;
1473     reg(ic->arg[2]) = reg(ic->arg[1]) - reg(ic->arg[0]);
1474     }
1475     X(subfc_dot) { instr(subfc)(cpu,ic); update_cr0(cpu, reg(ic->arg[2])); }
1476     X(subfe)
1477     {
1478     int old_ca = (cpu->cd.ppc.xer & PPC_XER_CA)? 1 : 0;
1479     cpu->cd.ppc.xer &= ~PPC_XER_CA;
1480     if (reg(ic->arg[1]) == reg(ic->arg[0])) {
1481     if (old_ca)
1482     cpu->cd.ppc.xer |= PPC_XER_CA;
1483     } else if (reg(ic->arg[1]) >= reg(ic->arg[0]))
1484     cpu->cd.ppc.xer |= PPC_XER_CA;
1485    
1486     /*
1487     * TODO: The register value calculation should be correct,
1488     * but the CA bit calculation above is probably not.
1489     */
1490    
1491     reg(ic->arg[2]) = reg(ic->arg[1]) - reg(ic->arg[0]) - (old_ca? 0 : 1);
1492     }
1493     X(subfe_dot) { instr(subfe)(cpu,ic); update_cr0(cpu, reg(ic->arg[2])); }
1494     X(subfze)
1495     {
1496     int old_ca = cpu->cd.ppc.xer & PPC_XER_CA;
1497     uint64_t tmp = (uint32_t)(~reg(ic->arg[0]));
1498     uint64_t tmp2 = tmp;
1499     cpu->cd.ppc.xer &= ~PPC_XER_CA;
1500     if (old_ca)
1501     tmp ++;
1502     if ((tmp >> 32) != (tmp2 >> 32))
1503     cpu->cd.ppc.xer |= PPC_XER_CA;
1504     reg(ic->arg[2]) = (uint32_t)tmp;
1505     }
1506     X(subfze_dot) { instr(subfze)(cpu,ic); update_cr0(cpu, reg(ic->arg[2])); }
1507    
1508    
1509     /*
1510     * ori, xori etc.:
1511     *
1512     * arg[0] = pointer to source uint64_t
1513     * arg[1] = immediate value (uint32_t or larger)
1514     * arg[2] = pointer to destination uint64_t
1515     */
1516     X(ori) { reg(ic->arg[2]) = reg(ic->arg[0]) | (uint32_t)ic->arg[1]; }
1517     X(xori) { reg(ic->arg[2]) = reg(ic->arg[0]) ^ (uint32_t)ic->arg[1]; }
1518    
1519    
1520     /*
1521     * tlbie: TLB invalidate
1522     */
1523     X(tlbie)
1524     {
1525 dpavlin 18 cpu->invalidate_translation_caches(cpu, 0, INVALIDATE_ALL);
1526 dpavlin 14 }
1527    
1528    
1529     /*
1530     * user_syscall: Userland syscall.
1531     *
1532     * arg[0] = syscall "level" (usually 0)
1533     */
1534     X(user_syscall)
1535     {
1536     useremul_syscall(cpu, ic->arg[0]);
1537     }
1538    
1539    
1540     /*
1541     * openfirmware:
1542     */
1543     X(openfirmware)
1544     {
1545     of_emul(cpu);
1546     cpu->pc = cpu->cd.ppc.lr;
1547     if (cpu->machine->show_trace_tree)
1548     cpu_functioncall_trace_return(cpu);
1549     DYNTRANS_PC_TO_POINTERS(cpu);
1550     }
1551    
1552    
1553     #include "tmp_ppc_loadstore.c"
1554    
1555    
1556     /*****************************************************************************/
1557    
1558    
1559     /*
1560     * byte_fill_loop:
1561     *
1562     * A byte-fill loop. Fills at most one page at a time. If the page was not
1563     * in the host_store table, then the original sequence (beginning with
1564     * cmpwi crX,rY,0) is executed instead.
1565     *
1566     * L: cmpwi crX,rY,0 ic[0]
1567     * stb rW,0(rZ) ic[1]
1568     * subi rY,rY,1 ic[2]
1569     * addi rZ,rZ,1 ic[3]
1570     * bc 12,4*X+1,L ic[4]
1571     */
1572     X(byte_fill_loop)
1573     {
1574     int max_pages_left = 5;
1575     unsigned int x = ic[0].arg[2], n, ofs, maxlen, c;
1576     uint64_t *y = (uint64_t *)ic[0].arg[0];
1577     uint64_t *z = (uint64_t *)ic[1].arg[1];
1578     uint64_t *w = (uint64_t *)ic[1].arg[0];
1579     unsigned char *page;
1580     #ifdef MODE32
1581     uint32_t addr;
1582     #else
1583     uint64_t addr;
1584     fatal("byte_fill_loop: not for 64-bit mode yet\n");
1585     exit(1);
1586     #endif
1587    
1588     restart_loop:
1589     addr = reg(z);
1590     /* TODO: This only work with 32-bit addressing: */
1591     page = cpu->cd.ppc.host_store[addr >> 12];
1592     if (page == NULL) {
1593     instr(cmpwi)(cpu, ic);
1594     return;
1595     }
1596    
1597     n = reg(y) + 1; ofs = addr & 0xfff; maxlen = 0x1000 - ofs;
1598     if (n > maxlen)
1599     n = maxlen;
1600    
1601     /* fatal("FILL A: x=%i n=%i ofs=0x%x y=0x%x z=0x%x w=0x%x\n", x,
1602     n, ofs, (int)reg(y), (int)reg(z), (int)reg(w)); */
1603    
1604     memset(page + ofs, *w, n);
1605    
1606     reg(z) = addr + n;
1607     reg(y) -= n;
1608    
1609     if ((int32_t)reg(y) + 1 < 0)
1610     c = 8;
1611     else if ((int32_t)reg(y) + 1 > 0)
1612     c = 4;
1613     else
1614     c = 2;
1615     c |= ((cpu->cd.ppc.xer >> 31) & 1); /* SO bit, copied from XER */
1616     cpu->cd.ppc.cr &= ~(0xf << (28 - 4*x));
1617     cpu->cd.ppc.cr |= (c << (28 - 4*x));
1618    
1619     cpu->n_translated_instrs += (5 * n);
1620    
1621     if (max_pages_left-- > 0 &&
1622     (int32_t)reg(y) > 0)
1623     goto restart_loop;
1624    
1625     cpu->n_translated_instrs --;
1626     if ((int32_t)reg(y) > 0)
1627     cpu->cd.ppc.next_ic = ic;
1628     else
1629     cpu->cd.ppc.next_ic = &ic[5];
1630    
1631     /* fatal("FILL B: x=%i n=%i ofs=0x%x y=0x%x z=0x%x w=0x%x\n", x, n,
1632     ofs, (int)reg(y), (int)reg(z), (int)reg(w)); */
1633     }
1634    
1635    
1636     /*****************************************************************************/
1637    
1638    
1639     X(end_of_page)
1640     {
1641     /* Update the PC: (offset 0, but on the next page) */
1642     cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2);
1643     cpu->pc += (PPC_IC_ENTRIES_PER_PAGE << 2);
1644    
1645     /* Find the new physical page and update the translation pointers: */
1646     DYNTRANS_PC_TO_POINTERS(cpu);
1647    
1648     /* end_of_page doesn't count as an executed instruction: */
1649     cpu->n_translated_instrs --;
1650     }
1651    
1652    
1653     /*****************************************************************************/
1654    
1655    
1656     /*
1657     * ppc_combine_instructions():
1658     *
1659     * Combine two or more instructions, if possible, into a single function call.
1660     */
1661     void COMBINE_INSTRUCTIONS(struct cpu *cpu, struct ppc_instr_call *ic,
1662     uint32_t addr)
1663     {
1664     int n_back;
1665     n_back = (addr >> PPC_INSTR_ALIGNMENT_SHIFT)
1666     & (PPC_IC_ENTRIES_PER_PAGE-1);
1667    
1668     if (n_back >= 4) {
1669     /*
1670     * L: cmpwi crX,rY,0 ic[-4]
1671     * stb rW,0(rZ) ic[-3]
1672     * subi rY,rY,1 ic[-2]
1673     * addi rZ,rZ,1 ic[-1]
1674     * bc 12,4*X+1,L ic[0]
1675     */
1676     if (ic[-4].f == instr(cmpwi) &&
1677     ic[-4].arg[0] == ic[-2].arg[0] && ic[-4].arg[1] == 0 &&
1678    
1679     ic[-3].f == instr(stb_0) &&
1680     ic[-3].arg[1] == ic[-1].arg[0] && ic[-3].arg[2] == 0 &&
1681    
1682     ic[-2].f == instr(addi) &&
1683     ic[-2].arg[0] == ic[-2].arg[2] && ic[-2].arg[1] == -1 &&
1684    
1685     ic[-1].f == instr(addi) &&
1686     ic[-1].arg[0] == ic[-1].arg[2] && ic[-1].arg[1] == 1 &&
1687    
1688     ic[0].f == instr(bc_samepage) &&
1689     ic[0].arg[0] == (size_t)&ic[-4] &&
1690     ic[0].arg[1] == 12 && ic[0].arg[2] == 4*ic[-4].arg[2] + 1) {
1691     ic[-4].f = instr(byte_fill_loop);
1692     combined;
1693     }
1694     }
1695    
1696     /* TODO: Combine forward as well */
1697     }
1698    
1699    
1700     /*****************************************************************************/
1701    
1702    
1703     /*
1704     * ppc_instr_to_be_translated():
1705     *
1706     * Translate an instruction word into an ppc_instr_call. ic is filled in with
1707     * valid data for the translated instruction, or a "nothing" instruction if
1708     * there was a translation failure. The newly translated instruction is then
1709     * executed.
1710     */
1711     X(to_be_translated)
1712     {
1713     uint64_t addr, low_pc, tmp_addr;
1714     uint32_t iword;
1715     unsigned char *page;
1716     unsigned char ib[4];
1717     int main_opcode, rt, rs, ra, rb, rc, aa_bit, l_bit, lk_bit, spr, sh,
1718     xo, imm, load, size, update, zero, bf, bo, bi, bh, oe_bit, n64=0,
1719     bfa, fp;
1720     void (*samepage_function)(struct cpu *, struct ppc_instr_call *);
1721     void (*rc_f)(struct cpu *, struct ppc_instr_call *);
1722    
1723     /* Figure out the (virtual) address of the instruction: */
1724     low_pc = ((size_t)ic - (size_t)cpu->cd.ppc.cur_ic_page)
1725     / sizeof(struct ppc_instr_call);
1726     addr = cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1)
1727     << PPC_INSTR_ALIGNMENT_SHIFT);
1728     addr += (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
1729     cpu->pc = addr;
1730     addr &= ~((1 << PPC_INSTR_ALIGNMENT_SHIFT) - 1);
1731    
1732     /* Read the instruction word from memory: */
1733     page = cpu->cd.ppc.host_load[addr >> 12];
1734    
1735     if (page != NULL) {
1736     /* fatal("TRANSLATION HIT!\n"); */
1737     memcpy(ib, page + (addr & 0xfff), sizeof(ib));
1738     } else {
1739     /* fatal("TRANSLATION MISS!\n"); */
1740     if (!cpu->memory_rw(cpu, cpu->mem, addr, ib,
1741     sizeof(ib), MEM_READ, CACHE_INSTRUCTION)) {
1742     fatal("to_be_translated(): "
1743     "read failed: TODO\n");
1744     goto bad;
1745     }
1746     }
1747    
1748     iword = *((uint32_t *)&ib[0]);
1749    
1750     #ifdef HOST_LITTLE_ENDIAN
1751     if (cpu->byte_order == EMUL_BIG_ENDIAN)
1752     #else
1753     if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
1754     #endif
1755     iword = ((iword & 0xff) << 24) |
1756     ((iword & 0xff00) << 8) |
1757     ((iword & 0xff0000) >> 8) |
1758     ((iword & 0xff000000) >> 24);
1759    
1760    
1761     #define DYNTRANS_TO_BE_TRANSLATED_HEAD
1762     #include "cpu_dyntrans.c"
1763     #undef DYNTRANS_TO_BE_TRANSLATED_HEAD
1764    
1765    
1766     /*
1767     * Translate the instruction:
1768     */
1769    
1770     main_opcode = iword >> 26;
1771    
1772     switch (main_opcode) {
1773    
1774     case PPC_HI6_MULLI:
1775     rt = (iword >> 21) & 31;
1776     ra = (iword >> 16) & 31;
1777     imm = (int16_t)(iword & 0xffff);
1778     ic->f = instr(mulli);
1779     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
1780     ic->arg[1] = (ssize_t)imm;
1781     ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);
1782     break;
1783    
1784     case PPC_HI6_SUBFIC:
1785     rt = (iword >> 21) & 31;
1786     ra = (iword >> 16) & 31;
1787     imm = (int16_t)(iword & 0xffff);
1788     ic->f = instr(subfic);
1789     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
1790     ic->arg[1] = (ssize_t)imm;
1791     ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);
1792     break;
1793    
1794     case PPC_HI6_CMPLI:
1795     case PPC_HI6_CMPI:
1796     bf = (iword >> 23) & 7;
1797     l_bit = (iword >> 21) & 1;
1798     ra = (iword >> 16) & 31;
1799     if (main_opcode == PPC_HI6_CMPLI) {
1800     imm = iword & 0xffff;
1801     if (l_bit)
1802     ic->f = instr(cmpldi);
1803     else
1804     ic->f = instr(cmplwi);
1805     } else {
1806     imm = (int16_t)(iword & 0xffff);
1807     if (l_bit)
1808     ic->f = instr(cmpdi);
1809     else
1810     ic->f = instr(cmpwi);
1811     }
1812     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
1813     ic->arg[1] = (ssize_t)imm;
1814     ic->arg[2] = bf;
1815     break;
1816    
1817     case PPC_HI6_ADDIC:
1818     case PPC_HI6_ADDIC_DOT:
1819     if (cpu->cd.ppc.bits == 64) {
1820     fatal("addic for 64-bit: TODO\n");
1821     goto bad;
1822     }
1823     rt = (iword >> 21) & 31;
1824     ra = (iword >> 16) & 31;
1825     imm = (int16_t)(iword & 0xffff);
1826     if (main_opcode == PPC_HI6_ADDIC)
1827     ic->f = instr(addic);
1828     else
1829     ic->f = instr(addic_dot);
1830     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
1831     ic->arg[1] = (ssize_t)imm;
1832     ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);
1833     break;
1834    
1835     case PPC_HI6_ADDI:
1836     case PPC_HI6_ADDIS:
1837     rt = (iword >> 21) & 31; ra = (iword >> 16) & 31;
1838     ic->f = instr(addi);
1839     if (ra == 0)
1840     ic->arg[0] = (size_t)(&cpu->cd.ppc.zero);
1841     else
1842     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
1843     ic->arg[1] = (ssize_t)(int16_t)(iword & 0xffff);
1844     if (main_opcode == PPC_HI6_ADDIS)
1845     ic->arg[1] <<= 16;
1846     ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);
1847     break;
1848    
1849     case PPC_HI6_ANDI_DOT:
1850     case PPC_HI6_ANDIS_DOT:
1851     rs = (iword >> 21) & 31; ra = (iword >> 16) & 31;
1852     ic->f = instr(andi_dot);
1853     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
1854     ic->arg[1] = iword & 0xffff;
1855     if (main_opcode == PPC_HI6_ANDIS_DOT)
1856     ic->arg[1] <<= 16;
1857     ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[ra]);
1858     break;
1859    
1860     case PPC_HI6_ORI:
1861     case PPC_HI6_ORIS:
1862     case PPC_HI6_XORI:
1863     case PPC_HI6_XORIS:
1864     rs = (iword >> 21) & 31; ra = (iword >> 16) & 31;
1865     if (main_opcode == PPC_HI6_ORI ||
1866     main_opcode == PPC_HI6_ORIS)
1867     ic->f = instr(ori);
1868     else
1869     ic->f = instr(xori);
1870     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
1871     ic->arg[1] = iword & 0xffff;
1872     if (main_opcode == PPC_HI6_ORIS ||
1873     main_opcode == PPC_HI6_XORIS)
1874     ic->arg[1] <<= 16;
1875     ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[ra]);
1876     break;
1877    
1878     case PPC_HI6_LBZ:
1879     case PPC_HI6_LBZU:
1880     case PPC_HI6_LHZ:
1881     case PPC_HI6_LHZU:
1882     case PPC_HI6_LWZ:
1883     case PPC_HI6_LWZU:
1884     case PPC_HI6_LFD:
1885     case PPC_HI6_STB:
1886     case PPC_HI6_STBU:
1887     case PPC_HI6_STH:
1888     case PPC_HI6_STHU:
1889     case PPC_HI6_STW:
1890     case PPC_HI6_STWU:
1891     rs = (iword >> 21) & 31;
1892     ra = (iword >> 16) & 31;
1893     imm = (int16_t)(iword & 0xffff);
1894     load = 0; zero = 1; size = 0; update = 0; fp = 0;
1895     switch (main_opcode) {
1896     case PPC_HI6_LBZ: load = 1; break;
1897     case PPC_HI6_LBZU: load = 1; update = 1; break;
1898     case PPC_HI6_LHZ: load = 1; size = 1; break;
1899     case PPC_HI6_LHZU: load = 1; size = 1; update = 1; break;
1900     case PPC_HI6_LWZ: load = 1; size = 2; break;
1901     case PPC_HI6_LWZU: load = 1; size = 2; update = 1; break;
1902     case PPC_HI6_LFD: load = 1; size = 3; fp = 1; break;
1903     case PPC_HI6_STB: break;
1904     case PPC_HI6_STBU: update = 1; break;
1905     case PPC_HI6_STH: size = 1; break;
1906     case PPC_HI6_STHU: size = 1; update = 1; break;
1907     case PPC_HI6_STW: size = 2; break;
1908     case PPC_HI6_STWU: size = 2; update = 1; break;
1909     }
1910     if (fp) {
1911     /* Floating point: */
1912     if (load && size == 3) {
1913     fatal("TODO: ld is INCORRECT!\n");
1914     ic->f = instr(nop);
1915     } else {
1916     /* TODO */
1917     fatal("TODO: fdgasgd\n");
1918     goto bad;
1919     }
1920     } else {
1921     /* Integer load/store: */
1922     ic->f =
1923     #ifdef MODE32
1924     ppc32_loadstore
1925     #else
1926     ppc_loadstore
1927     #endif
1928     [size + 4*zero + 8*load + (imm==0? 16 : 0)
1929     + 32*update];
1930     }
1931     if (ra == 0 && update) {
1932     fatal("TODO: ra=0 && update?\n");
1933     goto bad;
1934     }
1935     if (fp)
1936     ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rs]);
1937     else
1938     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
1939     if (ra == 0)
1940     ic->arg[1] = (size_t)(&cpu->cd.ppc.zero);
1941     else
1942     ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
1943     ic->arg[2] = (ssize_t)imm;
1944     break;
1945    
1946     case PPC_HI6_BC:
1947     aa_bit = (iword >> 1) & 1;
1948     lk_bit = iword & 1;
1949     bo = (iword >> 21) & 31;
1950     bi = (iword >> 16) & 31;
1951     tmp_addr = (int64_t)(int16_t)(iword & 0xfffc);
1952     if (lk_bit) {
1953     fatal("lk_bit: NOT YET\n");
1954     goto bad;
1955     }
1956     if (aa_bit) {
1957     fatal("aa_bit: NOT YET\n");
1958     goto bad;
1959     }
1960     ic->f = instr(bc);
1961     samepage_function = instr(bc_samepage);
1962     ic->arg[0] = (ssize_t)tmp_addr;
1963     ic->arg[1] = bo;
1964     ic->arg[2] = bi;
1965     /* Branches are calculated as cur PC + offset. */
1966     /* Special case: branch within the same page: */
1967     {
1968     uint64_t mask_within_page =
1969     ((PPC_IC_ENTRIES_PER_PAGE-1) << 2) | 3;
1970     uint64_t old_pc = addr;
1971     uint64_t new_pc = old_pc + (int32_t)ic->arg[0];
1972     if ((old_pc & ~mask_within_page) ==
1973     (new_pc & ~mask_within_page)) {
1974     ic->f = samepage_function;
1975     ic->arg[0] = (size_t) (
1976     cpu->cd.ppc.cur_ic_page +
1977     ((new_pc & mask_within_page) >> 2));
1978     }
1979     }
1980     break;
1981    
1982     case PPC_HI6_SC:
1983     ic->arg[0] = (iword >> 5) & 0x7f;
1984     if (cpu->machine->userland_emul != NULL)
1985     ic->f = instr(user_syscall);
1986     else {
1987     /* Special case/magic hack for OpenFirmware emul: */
1988     if (iword == 0x44ee0002) {
1989     ic->f = instr(openfirmware);
1990     break;
1991     }
1992     fatal("PPC non-userland SYSCALL: TODO\n");
1993     goto bad;
1994     }
1995     break;
1996    
1997     case PPC_HI6_B:
1998     aa_bit = (iword & 2) >> 1;
1999     lk_bit = iword & 1;
2000     if (aa_bit) {
2001     fatal("aa_bit: NOT YET\n");
2002     goto bad;
2003     }
2004     tmp_addr = (int64_t)(int32_t)((iword & 0x03fffffc) << 6);
2005     tmp_addr = (int64_t)tmp_addr >> 6;
2006     if (lk_bit) {
2007     if (cpu->machine->show_trace_tree) {
2008     ic->f = instr(bl_trace);
2009     samepage_function = instr(bl_samepage_trace);
2010     } else {
2011     ic->f = instr(bl);
2012     samepage_function = instr(bl_samepage);
2013     }
2014     } else {
2015     ic->f = instr(b);
2016     samepage_function = instr(b_samepage);
2017     }
2018     ic->arg[0] = (ssize_t)tmp_addr;
2019     /* Branches are calculated as cur PC + offset. */
2020     /* Special case: branch within the same page: */
2021     {
2022     uint64_t mask_within_page =
2023     ((PPC_IC_ENTRIES_PER_PAGE-1) << 2) | 3;
2024     uint64_t old_pc = addr;
2025     uint64_t new_pc = old_pc + (int32_t)ic->arg[0];
2026     if ((old_pc & ~mask_within_page) ==
2027     (new_pc & ~mask_within_page)) {
2028     ic->f = samepage_function;
2029     ic->arg[0] = (size_t) (
2030     cpu->cd.ppc.cur_ic_page +
2031     ((new_pc & mask_within_page) >> 2));
2032     }
2033     }
2034     break;
2035    
2036     case PPC_HI6_19:
2037     xo = (iword >> 1) & 1023;
2038     switch (xo) {
2039    
2040     case PPC_19_BCLR:
2041     case PPC_19_BCCTR:
2042     bo = (iword >> 21) & 31;
2043     bi = (iword >> 16) & 31;
2044     bh = (iword >> 11) & 3;
2045     lk_bit = iword & 1;
2046     if (xo == PPC_19_BCLR) {
2047     if (lk_bit)
2048     ic->f = instr(bclr_l);
2049     else
2050     ic->f = instr(bclr);
2051     } else {
2052     if (lk_bit)
2053     ic->f = instr(bcctr_l);
2054     else
2055     ic->f = instr(bcctr);
2056     }
2057     ic->arg[0] = bo;
2058     ic->arg[1] = bi;
2059     ic->arg[2] = bh;
2060     break;
2061    
2062     case PPC_19_ISYNC:
2063     /* TODO */
2064     ic->f = instr(nop);
2065     break;
2066    
2067     case PPC_19_RFI:
2068     ic->f = instr(rfi);
2069     break;
2070    
2071     case PPC_19_MCRF:
2072     bf = (iword >> 23) & 7;
2073     bfa = (iword >> 18) & 7;
2074     ic->arg[0] = bf;
2075     ic->arg[1] = bfa;
2076     ic->f = instr(mcrf);
2077     break;
2078    
2079     case PPC_19_CRAND:
2080     case PPC_19_CRANDC:
2081     case PPC_19_CREQV:
2082     case PPC_19_CROR:
2083     case PPC_19_CRXOR:
2084     switch (xo) {
2085     case PPC_19_CRAND: ic->f = instr(crand); break;
2086     case PPC_19_CRANDC: ic->f = instr(crandc); break;
2087     case PPC_19_CREQV: ic->f = instr(creqv); break;
2088     case PPC_19_CROR: ic->f = instr(cror); break;
2089     case PPC_19_CRXOR: ic->f = instr(crxor); break;
2090     }
2091     ic->arg[0] = iword;
2092     break;
2093    
2094     default:goto bad;
2095     }
2096     break;
2097    
2098     case PPC_HI6_RLWIMI:
2099     case PPC_HI6_RLWINM:
2100     rs = (iword >> 21) & 31;
2101     ra = (iword >> 16) & 31;
2102     if (main_opcode == PPC_HI6_RLWIMI)
2103     ic->f = instr(rlwimi);
2104     else
2105     ic->f = instr(rlwinm);
2106     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
2107     ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2108     ic->arg[2] = (uint32_t)iword;
2109     break;
2110    
2111     case PPC_HI6_LMW:
2112     case PPC_HI6_STMW:
2113     /* NOTE: Loads use rt, not rs. */
2114     rs = (iword >> 21) & 31;
2115     ra = (iword >> 16) & 31;
2116     ic->arg[0] = rs;
2117     if (ra == 0)
2118     ic->arg[1] = (size_t)(&cpu->cd.ppc.zero);
2119     else
2120     ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2121     ic->arg[2] = (int32_t)(int16_t)iword;
2122     switch (main_opcode) {
2123     case PPC_HI6_LMW:
2124     ic->f = instr(lmw);
2125     break;
2126     case PPC_HI6_STMW:
2127     ic->f = instr(stmw);
2128     break;
2129     }
2130     break;
2131    
2132     case PPC_HI6_30:
2133     xo = (iword >> 2) & 7;
2134     switch (xo) {
2135    
2136     case PPC_30_RLDICR:
2137     ic->f = instr(rldicr);
2138     ic->arg[0] = iword;
2139     if (cpu->cd.ppc.bits == 32) {
2140     fatal("TODO: rldicr in 32-bit mode?\n");
2141     goto bad;
2142     }
2143     break;
2144    
2145     default:goto bad;
2146     }
2147     break;
2148    
2149     case PPC_HI6_31:
2150     xo = (iword >> 1) & 1023;
2151     switch (xo) {
2152    
2153     case PPC_31_CMPL:
2154     case PPC_31_CMP:
2155     bf = (iword >> 23) & 7;
2156     l_bit = (iword >> 21) & 1;
2157     ra = (iword >> 16) & 31;
2158     rb = (iword >> 11) & 31;
2159     if (xo == PPC_31_CMPL) {
2160     if (l_bit)
2161     ic->f = instr(cmpld);
2162     else
2163     ic->f = instr(cmplw);
2164     } else {
2165     if (l_bit)
2166     ic->f = instr(cmpd);
2167     else
2168     ic->f = instr(cmpw);
2169     }
2170     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2171     ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rb]);
2172     ic->arg[2] = bf;
2173     break;
2174    
2175     case PPC_31_CNTLZW:
2176     rs = (iword >> 21) & 31;
2177     ra = (iword >> 16) & 31;
2178     rc = iword & 1;
2179     if (rc) {
2180     fatal("TODO: rc\n");
2181     goto bad;
2182     }
2183     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
2184     ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2185     ic->f = instr(cntlzw);
2186     break;
2187    
2188     case PPC_31_MFSPR:
2189     rt = (iword >> 21) & 31;
2190     spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
2191     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rt]);
2192     switch (spr) {
2193     case 8: ic->f = instr(mflr); break;
2194     case 9: ic->f = instr(mfctr); break;
2195     case 25: ic->f = instr(mfsdr1); break;
2196     case 26: ic->f = instr(mfsrr0); break;
2197     case 27: ic->f = instr(mfsrr1); break;
2198     case 272: ic->f = instr(mfsprg0); break;
2199     case 273: ic->f = instr(mfsprg1); break;
2200     case 274: ic->f = instr(mfsprg2); break;
2201     case 275: ic->f = instr(mfsprg3); break;
2202     case 287: ic->f = instr(mfpvr); break;
2203     case 1008:ic->f = instr(mfdbsr); break;
2204     case 1009:ic->f = instr(mfhid1); break;
2205     case 1017:ic->f = instr(mfl2cr); break;
2206     default:if (spr >= 528 && spr < 544) {
2207     if (spr & 1) {
2208     if (spr & 16)
2209     ic->f = instr(mfdbatl);
2210     else
2211     ic->f = instr(mfibatl);
2212     } else {
2213     if (spr & 16)
2214     ic->f = instr(mfdbatu);
2215     else
2216     ic->f = instr(mfibatu);
2217     }
2218     ic->arg[1] = (spr >> 1) & 3;
2219     } else {
2220     fatal("UNIMPLEMENTED spr %i\n", spr);
2221     goto bad;
2222     }
2223     }
2224     break;
2225    
2226     case PPC_31_MTSPR:
2227     rs = (iword >> 21) & 31;
2228     spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
2229     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
2230     switch (spr) {
2231     case 8: ic->f = instr(mtlr); break;
2232     case 9: ic->f = instr(mtctr); break;
2233     case 25: ic->f = instr(mtsdr1); break;
2234     case 26: ic->f = instr(mtsrr0); break;
2235     case 27: ic->f = instr(mtsrr1); break;
2236     case 272: ic->f = instr(mtsprg0); break;
2237     case 273: ic->f = instr(mtsprg1); break;
2238     case 274: ic->f = instr(mtsprg2); break;
2239     case 275: ic->f = instr(mtsprg3); break;
2240     case 1008:ic->f = instr(mtdbsr); break;
2241     default:if (spr >= 528 && spr < 544) {
2242     if (spr & 1) {
2243     if (spr & 16)
2244     ic->f = instr(mtdbatl);
2245     else
2246     ic->f = instr(mtibatl);
2247     } else {
2248     if (spr & 16)
2249     ic->f = instr(mtdbatu);
2250     else
2251     ic->f = instr(mtibatu);
2252     }
2253     ic->arg[1] = (spr >> 1) & 3;
2254     } else {
2255     fatal("UNIMPLEMENTED spr %i\n", spr);
2256     goto bad;
2257     }
2258     }
2259     break;
2260    
2261     case PPC_31_MFCR:
2262     rt = (iword >> 21) & 31;
2263     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rt]);
2264     ic->f = instr(mfcr);
2265     break;
2266    
2267     case PPC_31_MFMSR:
2268     rt = (iword >> 21) & 31;
2269     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rt]);
2270     ic->f = instr(mfmsr);
2271     break;
2272    
2273     case PPC_31_MTMSR:
2274     rs = (iword >> 21) & 31;
2275     l_bit = (iword >> 16) & 1;
2276     if (l_bit) {
2277     fatal("TODO: mtmsr l-bit\n");
2278     goto bad;
2279     }
2280     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
2281     ic->f = instr(mtmsr);
2282     break;
2283    
2284     case PPC_31_MTCRF:
2285     rs = (iword >> 21) & 31;
2286     {
2287     int i, fxm = (iword >> 12) & 255;
2288     uint32_t tmp = 0;
2289     for (i=0; i<8; i++, fxm <<= 1) {
2290     tmp <<= 4;
2291     if (fxm & 128)
2292     tmp |= 0xf;
2293     }
2294     ic->arg[1] = (uint32_t)tmp;
2295     }
2296     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
2297     ic->f = instr(mtcrf);
2298     break;
2299    
2300     case PPC_31_MFSRIN:
2301     case PPC_31_MTSRIN:
2302     rt = (iword >> 21) & 31;
2303     rb = (iword >> 11) & 31;
2304     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rb]);
2305     ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rt]);
2306     switch (xo) {
2307     case PPC_31_MFSRIN: ic->f = instr(mfsrin); break;
2308     case PPC_31_MTSRIN: ic->f = instr(mtsrin); break;
2309     }
2310     if (cpu->cd.ppc.bits == 64) {
2311     fatal("Not yet for 64-bit mode\n");
2312     goto bad;
2313     }
2314     break;
2315    
2316     case PPC_31_MTSR:
2317     rt = (iword >> 21) & 31;
2318     ic->arg[0] = (iword >> 16) & 15;
2319     ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rt]);
2320     ic->f = instr(mtsr);
2321     if (cpu->cd.ppc.bits == 64) {
2322     fatal("Not yet for 64-bit mode\n");
2323     goto bad;
2324     }
2325     break;
2326    
2327     case PPC_31_SRAWI:
2328     rs = (iword >> 21) & 31;
2329     ra = (iword >> 16) & 31;
2330     sh = (iword >> 11) & 31;
2331     rc = iword & 1;
2332     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
2333     ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2334     ic->arg[2] = sh;
2335     if (rc)
2336     ic->f = instr(srawi_dot);
2337     else
2338     ic->f = instr(srawi);
2339     break;
2340    
2341     case PPC_31_SYNC:
2342     case PPC_31_TLBSYNC:
2343     case PPC_31_EIEIO:
2344     case PPC_31_DCBST:
2345     case PPC_31_DCBTST:
2346     case PPC_31_DCBF:
2347     case PPC_31_DCBT:
2348     case PPC_31_ICBI:
2349     /* TODO */
2350     ic->f = instr(nop);
2351     break;
2352    
2353     case PPC_31_DCBZ:
2354     ra = (iword >> 16) & 31;
2355     rb = (iword >> 11) & 31;
2356     if (ra == 0)
2357     ic->arg[0] = (size_t)(&cpu->cd.ppc.zero);
2358     else
2359     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2360     ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rb]);
2361     ic->f = instr(dcbz);
2362     break;
2363    
2364     case PPC_31_TLBIE:
2365     /* TODO */
2366     ic->f = instr(tlbie);
2367     break;
2368    
2369     case PPC_31_MFTB:
2370     rt = (iword >> 21) & 31;
2371     spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
2372     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rt]);
2373     switch (spr) {
2374     case 268: ic->f = instr(mftb); break;
2375     case 269: ic->f = instr(mftbu); break;
2376     default:fatal("mftb spr=%i?\n", spr);
2377     goto bad;
2378     }
2379     break;
2380    
2381     case PPC_31_NEG:
2382     rt = (iword >> 21) & 31;
2383     ra = (iword >> 16) & 31;
2384     rc = iword & 1;
2385     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2386     ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rt]);
2387     if (rc)
2388     ic->f = instr(neg_dot);
2389     else
2390     ic->f = instr(neg);
2391     break;
2392    
2393     case PPC_31_LWARX:
2394     case PPC_31_LDARX:
2395     case PPC_31_STWCX_DOT:
2396     case PPC_31_STDCX_DOT:
2397     ic->arg[0] = iword;
2398     ic->f = instr(llsc);
2399     break;
2400    
2401     case PPC_31_LBZX:
2402     case PPC_31_LBZUX:
2403     case PPC_31_LHZX:
2404     case PPC_31_LHZUX:
2405     case PPC_31_LWZX:
2406     case PPC_31_LWZUX:
2407     case PPC_31_STBX:
2408     case PPC_31_STBUX:
2409     case PPC_31_STHX:
2410     case PPC_31_STHUX:
2411     case PPC_31_STWX:
2412     case PPC_31_STWUX:
2413     case PPC_31_STDX:
2414     case PPC_31_STDUX:
2415     rs = (iword >> 21) & 31;
2416     ra = (iword >> 16) & 31;
2417     rb = (iword >> 11) & 31;
2418     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
2419     if (ra == 0)
2420     ic->arg[1] = (size_t)(&cpu->cd.ppc.zero);
2421     else
2422     ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2423     ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rb]);
2424     load = 0; zero = 1; size = 0; update = 0;
2425     switch (xo) {
2426     case PPC_31_LBZX: load = 1; break;
2427     case PPC_31_LBZUX: load = update = 1; break;
2428     case PPC_31_LHZX: size = 1; load = 1; break;
2429     case PPC_31_LHZUX: size = 1; load = update = 1; break;
2430     case PPC_31_LWZX: size = 2; load = 1; break;
2431     case PPC_31_LWZUX: size = 2; load = update = 1; break;
2432     case PPC_31_STBX: break;
2433     case PPC_31_STBUX: update = 1; break;
2434     case PPC_31_STHX: size = 1; break;
2435     case PPC_31_STHUX: size = 1; update = 1; break;
2436     case PPC_31_STWX: size = 2; break;
2437     case PPC_31_STWUX: size = 2; update = 1; break;
2438     case PPC_31_STDX: size = 3; break;
2439     case PPC_31_STDUX: size = 3; update = 1; break;
2440     }
2441     ic->f =
2442     #ifdef MODE32
2443     ppc32_loadstore_indexed
2444     #else
2445     ppc_loadstore_indexed
2446     #endif
2447     [size + 4*zero + 8*load + 16*update];
2448     if (ra == 0 && update) {
2449     fatal("TODO: ra=0 && update?\n");
2450     goto bad;
2451     }
2452     break;
2453    
2454     case PPC_31_EXTSB:
2455     case PPC_31_EXTSH:
2456     case PPC_31_EXTSW:
2457     case PPC_31_SLW:
2458     case PPC_31_SRAW:
2459     case PPC_31_SRW:
2460     case PPC_31_AND:
2461     case PPC_31_NAND:
2462     case PPC_31_ANDC:
2463     case PPC_31_NOR:
2464     case PPC_31_OR:
2465     case PPC_31_ORC:
2466     case PPC_31_XOR:
2467     rs = (iword >> 21) & 31;
2468     ra = (iword >> 16) & 31;
2469     rb = (iword >> 11) & 31;
2470     rc = iword & 1;
2471     rc_f = NULL;
2472     switch (xo) {
2473     case PPC_31_EXTSB:ic->f = instr(extsb);
2474     rc_f = instr(extsb_dot); break;
2475     case PPC_31_EXTSH:ic->f = instr(extsh);
2476     rc_f = instr(extsh_dot); break;
2477     case PPC_31_EXTSW:ic->f = instr(extsw);
2478     rc_f = instr(extsw_dot); break;
2479     case PPC_31_SLW: ic->f = instr(slw);
2480     rc_f = instr(slw_dot); break;
2481     case PPC_31_SRAW: ic->f = instr(sraw);
2482     rc_f = instr(sraw_dot); break;
2483     case PPC_31_SRW: ic->f = instr(srw);
2484     rc_f = instr(srw_dot); break;
2485     case PPC_31_AND: ic->f = instr(and);
2486     rc_f = instr(and_dot); break;
2487     case PPC_31_NAND: ic->f = instr(nand);
2488     rc_f = instr(nand_dot); break;
2489     case PPC_31_ANDC: ic->f = instr(andc);
2490     rc_f = instr(andc_dot); break;
2491     case PPC_31_NOR: ic->f = instr(nor);
2492     rc_f = instr(nor_dot); break;
2493     case PPC_31_OR: ic->f = instr(or);
2494     rc_f = instr(or_dot); break;
2495     case PPC_31_ORC: ic->f = instr(orc);
2496     rc_f = instr(orc_dot); break;
2497     case PPC_31_XOR: ic->f = instr(xor);
2498     rc_f = instr(xor_dot); break;
2499     }
2500     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
2501     ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rb]);
2502     ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2503     if (rc)
2504     ic->f = rc_f;
2505     break;
2506    
2507     case PPC_31_MULLW:
2508     case PPC_31_MULHW:
2509     case PPC_31_MULHWU:
2510     case PPC_31_DIVW:
2511     case PPC_31_DIVWU:
2512     case PPC_31_ADD:
2513     case PPC_31_ADDC:
2514     case PPC_31_ADDE:
2515     case PPC_31_ADDME:
2516     case PPC_31_ADDZE:
2517     case PPC_31_SUBF:
2518     case PPC_31_SUBFC:
2519     case PPC_31_SUBFE:
2520     case PPC_31_SUBFZE:
2521     rt = (iword >> 21) & 31;
2522     ra = (iword >> 16) & 31;
2523     rb = (iword >> 11) & 31;
2524     oe_bit = (iword >> 10) & 1;
2525     rc = iword & 1;
2526     if (oe_bit) {
2527     fatal("oe_bit not yet implemented\n");
2528     goto bad;
2529     }
2530     switch (xo) {
2531     case PPC_31_MULLW: ic->f = instr(mullw); break;
2532     case PPC_31_MULHW: ic->f = instr(mulhw); break;
2533     case PPC_31_MULHWU: ic->f = instr(mulhwu); break;
2534     case PPC_31_DIVW: ic->f = instr(divw); n64=1; break;
2535     case PPC_31_DIVWU: ic->f = instr(divwu); n64=1; break;
2536     case PPC_31_ADD: ic->f = instr(add); break;
2537     case PPC_31_ADDC: ic->f = instr(addc); n64=1; break;
2538     case PPC_31_ADDE: ic->f = instr(adde); n64=1; break;
2539     case PPC_31_ADDME: ic->f = instr(addme); n64=1; break;
2540     case PPC_31_ADDZE: ic->f = instr(addze); n64=1; break;
2541     case PPC_31_SUBF: ic->f = instr(subf); break;
2542     case PPC_31_SUBFC: ic->f = instr(subfc); break;
2543     case PPC_31_SUBFE: ic->f = instr(subfe); n64=1; break;
2544     case PPC_31_SUBFZE: ic->f = instr(subfze); n64=1;break;
2545     }
2546     if (rc) {
2547     switch (xo) {
2548     case PPC_31_ADD:
2549     ic->f = instr(add_dot); break;
2550     case PPC_31_ADDE:
2551     ic->f = instr(adde_dot); break;
2552     case PPC_31_ADDME:
2553     ic->f = instr(addme_dot); break;
2554     case PPC_31_ADDZE:
2555     ic->f = instr(addze_dot); break;
2556     case PPC_31_SUBF:
2557     ic->f = instr(subf_dot); break;
2558     case PPC_31_SUBFC:
2559     ic->f = instr(subfc_dot); break;
2560     case PPC_31_SUBFE:
2561     ic->f = instr(subfe_dot); break;
2562     case PPC_31_SUBFZE:
2563     ic->f = instr(subfze_dot); break;
2564     default:fatal("RC bit not yet implemented\n");
2565     goto bad;
2566     }
2567     }
2568     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2569     ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rb]);
2570     ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);
2571     if (cpu->cd.ppc.bits == 64 && n64) {
2572     fatal("Not yet for 64-bit mode\n");
2573     goto bad;
2574     }
2575     break;
2576    
2577     default:goto bad;
2578     }
2579     break;
2580    
2581     case PPC_HI6_63:
2582     xo = (iword >> 1) & 1023;
2583     rt = (iword >> 21) & 31;
2584     ra = (iword >> 16) & 31;
2585     rb = (iword >> 11) & 31;
2586     rc = iword & 1;
2587    
2588     switch (xo) {
2589    
2590     case PPC_63_FMR:
2591     if (rc) {
2592     fatal("FMR with rc-bit: TODO\n");
2593     goto bad;
2594     }
2595     ic->f = instr(fmr);
2596     ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rb]);
2597     ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[rt]);
2598     break;
2599    
2600     default:goto bad;
2601     }
2602     break;
2603    
2604     default:goto bad;
2605     }
2606    
2607    
2608     #define DYNTRANS_TO_BE_TRANSLATED_TAIL
2609     #include "cpu_dyntrans.c"
2610     #undef DYNTRANS_TO_BE_TRANSLATED_TAIL
2611     }
2612    

  ViewVC Help
Powered by ViewVC 1.1.26