/[gxemul]/upstream/0.4.4/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 /upstream/0.4.4/src/cpus/cpu_ppc_instr.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 35 - (hide annotations)
Mon Oct 8 16:21:26 2007 UTC (16 years, 7 months ago) by dpavlin
File MIME type: text/plain
File size: 91889 byte(s)
0.4.4
1 dpavlin 14 /*
2 dpavlin 34 * Copyright (C) 2005-2007 Anders Gavare. All rights reserved.
3 dpavlin 14 *
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 34 * $Id: cpu_ppc_instr.c,v 1.73 2007/02/17 10:06:19 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 dpavlin 20 #include "float_emul.h"
40    
41    
42     #define DOT0(n) X(n ## _dot) { instr(n)(cpu,ic); \
43     update_cr0(cpu, reg(ic->arg[0])); }
44     #define DOT1(n) X(n ## _dot) { instr(n)(cpu,ic); \
45 dpavlin 14 update_cr0(cpu, reg(ic->arg[1])); }
46 dpavlin 20 #define DOT2(n) X(n ## _dot) { instr(n)(cpu,ic); \
47     update_cr0(cpu, reg(ic->arg[2])); }
48 dpavlin 14
49 dpavlin 22 #ifndef CHECK_FOR_FPU_EXCEPTION
50     #define CHECK_FOR_FPU_EXCEPTION { if (!(cpu->cd.ppc.msr & PPC_MSR_FP)) { \
51     /* Synchronize the PC, and cause an FPU exception: */ \
52     uint64_t low_pc = ((size_t)ic - \
53     (size_t)cpu->cd.ppc.cur_ic_page) \
54     / sizeof(struct ppc_instr_call); \
55     cpu->pc = (cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << \
56     PPC_INSTR_ALIGNMENT_SHIFT)) + (low_pc << \
57     PPC_INSTR_ALIGNMENT_SHIFT); \
58     ppc_exception(cpu, PPC_EXCEPTION_FPU); \
59     return; } }
60     #endif
61 dpavlin 14
62 dpavlin 22
63    
64 dpavlin 14 /*
65     * nop: Do nothing.
66     */
67     X(nop)
68     {
69     }
70    
71    
72     /*
73     * invalid: To catch bugs.
74     */
75     X(invalid)
76     {
77 dpavlin 20 fatal("PPC: invalid(): INTERNAL ERROR\n");
78 dpavlin 14 exit(1);
79     }
80    
81    
82     /*
83     * addi: Add immediate.
84     *
85     * arg[0] = pointer to source uint64_t
86     * arg[1] = immediate value (int32_t or larger)
87     * arg[2] = pointer to destination uint64_t
88     */
89     X(addi)
90     {
91     reg(ic->arg[2]) = reg(ic->arg[0]) + (int32_t)ic->arg[1];
92     }
93 dpavlin 22 X(li)
94     {
95     reg(ic->arg[2]) = (int32_t)ic->arg[1];
96     }
97     X(li_0)
98     {
99     reg(ic->arg[2]) = 0;
100     }
101 dpavlin 14
102    
103     /*
104     * andi_dot: AND immediate, update CR.
105     *
106     * arg[0] = pointer to source uint64_t
107     * arg[1] = immediate value (uint32_t)
108     * arg[2] = pointer to destination uint64_t
109     */
110     X(andi_dot)
111     {
112     MODE_uint_t tmp = reg(ic->arg[0]) & (uint32_t)ic->arg[1];
113     reg(ic->arg[2]) = tmp;
114     update_cr0(cpu, tmp);
115     }
116    
117    
118     /*
119     * addic: Add immediate, Carry.
120     *
121     * arg[0] = pointer to source register
122     * arg[1] = immediate value (int32_t or larger)
123     * arg[2] = pointer to destination register
124     */
125     X(addic)
126     {
127     /* TODO/NOTE: Only for 32-bit mode, so far! */
128     uint64_t tmp = (uint32_t)reg(ic->arg[0]);
129     uint64_t tmp2 = tmp;
130 dpavlin 20 cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
131 dpavlin 14 tmp2 += (uint32_t)ic->arg[1];
132     if ((tmp2 >> 32) != (tmp >> 32))
133 dpavlin 20 cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
134 dpavlin 14 reg(ic->arg[2]) = (uint32_t)tmp2;
135     }
136    
137    
138     /*
139     * subfic: Subtract from immediate, Carry.
140     *
141     * arg[0] = pointer to source uint64_t
142     * arg[1] = immediate value (int32_t or larger)
143     * arg[2] = pointer to destination uint64_t
144     */
145     X(subfic)
146     {
147     MODE_uint_t tmp = (int64_t)(int32_t)ic->arg[1];
148 dpavlin 20 cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
149 dpavlin 14 if (tmp >= reg(ic->arg[0]))
150 dpavlin 20 cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
151 dpavlin 14 reg(ic->arg[2]) = tmp - reg(ic->arg[0]);
152     }
153    
154    
155     /*
156     * addic_dot: Add immediate, Carry.
157     *
158     * arg[0] = pointer to source uint64_t
159     * arg[1] = immediate value (int32_t or larger)
160     * arg[2] = pointer to destination uint64_t
161     */
162     X(addic_dot)
163     {
164     /* TODO/NOTE: Only for 32-bit mode, so far! */
165     uint64_t tmp = (uint32_t)reg(ic->arg[0]);
166     uint64_t tmp2 = tmp;
167 dpavlin 20 cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
168 dpavlin 14 tmp2 += (uint32_t)ic->arg[1];
169     if ((tmp2 >> 32) != (tmp >> 32))
170 dpavlin 20 cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
171 dpavlin 14 reg(ic->arg[2]) = (uint32_t)tmp2;
172     update_cr0(cpu, (uint32_t)tmp2);
173     }
174    
175    
176     /*
177     * bclr: Branch Conditional to Link Register
178     *
179     * arg[0] = bo
180 dpavlin 20 * arg[1] = 31 - bi
181 dpavlin 14 * arg[2] = bh
182     */
183     X(bclr)
184     {
185 dpavlin 22 unsigned int bo = ic->arg[0], bi31m = ic->arg[1];
186 dpavlin 14 int ctr_ok, cond_ok;
187     uint64_t old_pc = cpu->pc;
188 dpavlin 20 MODE_uint_t tmp, addr = cpu->cd.ppc.spr[SPR_LR];
189 dpavlin 14 if (!(bo & 4))
190 dpavlin 20 cpu->cd.ppc.spr[SPR_CTR] --;
191 dpavlin 14 ctr_ok = (bo >> 2) & 1;
192 dpavlin 20 tmp = cpu->cd.ppc.spr[SPR_CTR];
193 dpavlin 14 ctr_ok |= ( (tmp != 0) ^ ((bo >> 1) & 1) );
194     cond_ok = (bo >> 4) & 1;
195 dpavlin 20 cond_ok |= ( ((bo >> 3) & 1) == ((cpu->cd.ppc.cr >> bi31m) & 1) );
196 dpavlin 14 if (ctr_ok && cond_ok) {
197     uint64_t mask_within_page =
198     ((PPC_IC_ENTRIES_PER_PAGE-1) << PPC_INSTR_ALIGNMENT_SHIFT)
199     | ((1 << PPC_INSTR_ALIGNMENT_SHIFT) - 1);
200     cpu->pc = addr & ~((1 << PPC_INSTR_ALIGNMENT_SHIFT) - 1);
201     /* TODO: trace in separate (duplicate) function? */
202     if (cpu->machine->show_trace_tree)
203     cpu_functioncall_trace_return(cpu);
204     if ((old_pc & ~mask_within_page) ==
205     (cpu->pc & ~mask_within_page)) {
206     cpu->cd.ppc.next_ic =
207     cpu->cd.ppc.cur_ic_page +
208     ((cpu->pc & mask_within_page) >>
209     PPC_INSTR_ALIGNMENT_SHIFT);
210     } else {
211     /* Find the new physical page and update pointers: */
212 dpavlin 22 quick_pc_to_pointers(cpu);
213 dpavlin 14 }
214     }
215     }
216 dpavlin 20 X(bclr_20)
217     {
218     cpu->pc = cpu->cd.ppc.spr[SPR_LR];
219 dpavlin 22 quick_pc_to_pointers(cpu);
220 dpavlin 20 }
221 dpavlin 14 X(bclr_l)
222     {
223     uint64_t low_pc, old_pc = cpu->pc;
224 dpavlin 22 unsigned int bo = ic->arg[0], bi31m = ic->arg[1] /* ,bh = ic->arg[2]*/;
225 dpavlin 14 int ctr_ok, cond_ok;
226 dpavlin 20 MODE_uint_t tmp, addr = cpu->cd.ppc.spr[SPR_LR];
227 dpavlin 14 if (!(bo & 4))
228 dpavlin 20 cpu->cd.ppc.spr[SPR_CTR] --;
229 dpavlin 14 ctr_ok = (bo >> 2) & 1;
230 dpavlin 20 tmp = cpu->cd.ppc.spr[SPR_CTR];
231 dpavlin 14 ctr_ok |= ( (tmp != 0) ^ ((bo >> 1) & 1) );
232     cond_ok = (bo >> 4) & 1;
233 dpavlin 20 cond_ok |= ( ((bo >> 3) & 1) == ((cpu->cd.ppc.cr >> bi31m) & 1) );
234 dpavlin 14
235     /* Calculate return PC: */
236 dpavlin 20 low_pc = ((size_t)ic - (size_t)
237     cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call) + 1;
238 dpavlin 22 cpu->cd.ppc.spr[SPR_LR] = cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1)
239     << PPC_INSTR_ALIGNMENT_SHIFT);
240     cpu->cd.ppc.spr[SPR_LR] += (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
241 dpavlin 14
242     if (ctr_ok && cond_ok) {
243     uint64_t mask_within_page =
244     ((PPC_IC_ENTRIES_PER_PAGE-1) << PPC_INSTR_ALIGNMENT_SHIFT)
245     | ((1 << PPC_INSTR_ALIGNMENT_SHIFT) - 1);
246     cpu->pc = addr & ~((1 << PPC_INSTR_ALIGNMENT_SHIFT) - 1);
247     /* TODO: trace in separate (duplicate) function? */
248     if (cpu->machine->show_trace_tree)
249     cpu_functioncall_trace_return(cpu);
250     if (cpu->machine->show_trace_tree)
251     cpu_functioncall_trace(cpu, cpu->pc);
252     if ((old_pc & ~mask_within_page) ==
253     (cpu->pc & ~mask_within_page)) {
254     cpu->cd.ppc.next_ic =
255     cpu->cd.ppc.cur_ic_page +
256     ((cpu->pc & mask_within_page) >>
257     PPC_INSTR_ALIGNMENT_SHIFT);
258     } else {
259     /* Find the new physical page and update pointers: */
260 dpavlin 22 quick_pc_to_pointers(cpu);
261 dpavlin 14 }
262     }
263     }
264    
265    
266     /*
267     * bcctr: Branch Conditional to Count register
268     *
269     * arg[0] = bo
270 dpavlin 20 * arg[1] = 31 - bi
271 dpavlin 14 * arg[2] = bh
272     */
273     X(bcctr)
274     {
275 dpavlin 22 unsigned int bo = ic->arg[0], bi31m = ic->arg[1] /*,bh = ic->arg[2]*/;
276 dpavlin 14 uint64_t old_pc = cpu->pc;
277 dpavlin 20 MODE_uint_t addr = cpu->cd.ppc.spr[SPR_CTR];
278 dpavlin 14 int cond_ok = (bo >> 4) & 1;
279 dpavlin 20 cond_ok |= ( ((bo >> 3) & 1) == ((cpu->cd.ppc.cr >> bi31m) & 1) );
280 dpavlin 14 if (cond_ok) {
281     uint64_t mask_within_page =
282     ((PPC_IC_ENTRIES_PER_PAGE-1) << PPC_INSTR_ALIGNMENT_SHIFT)
283     | ((1 << PPC_INSTR_ALIGNMENT_SHIFT) - 1);
284     cpu->pc = addr & ~((1 << PPC_INSTR_ALIGNMENT_SHIFT) - 1);
285     /* TODO: trace in separate (duplicate) function? */
286     if (cpu->machine->show_trace_tree)
287     cpu_functioncall_trace_return(cpu);
288     if ((old_pc & ~mask_within_page) ==
289     (cpu->pc & ~mask_within_page)) {
290     cpu->cd.ppc.next_ic =
291     cpu->cd.ppc.cur_ic_page +
292     ((cpu->pc & mask_within_page) >>
293     PPC_INSTR_ALIGNMENT_SHIFT);
294     } else {
295     /* Find the new physical page and update pointers: */
296 dpavlin 22 quick_pc_to_pointers(cpu);
297 dpavlin 14 }
298     }
299     }
300     X(bcctr_l)
301     {
302     uint64_t low_pc, old_pc = cpu->pc;
303 dpavlin 22 unsigned int bo = ic->arg[0], bi31m = ic->arg[1] /*,bh = ic->arg[2] */;
304 dpavlin 20 MODE_uint_t addr = cpu->cd.ppc.spr[SPR_CTR];
305 dpavlin 14 int cond_ok = (bo >> 4) & 1;
306 dpavlin 20 cond_ok |= ( ((bo >> 3) & 1) == ((cpu->cd.ppc.cr >> bi31m) & 1) );
307 dpavlin 14
308     /* Calculate return PC: */
309 dpavlin 20 low_pc = ((size_t)ic - (size_t)
310     cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call) + 1;
311 dpavlin 22 cpu->cd.ppc.spr[SPR_LR] = cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1)
312     << PPC_INSTR_ALIGNMENT_SHIFT);
313     cpu->cd.ppc.spr[SPR_LR] += (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
314 dpavlin 14
315     if (cond_ok) {
316     uint64_t mask_within_page =
317     ((PPC_IC_ENTRIES_PER_PAGE-1) << PPC_INSTR_ALIGNMENT_SHIFT)
318     | ((1 << PPC_INSTR_ALIGNMENT_SHIFT) - 1);
319     cpu->pc = addr & ~((1 << PPC_INSTR_ALIGNMENT_SHIFT) - 1);
320     /* TODO: trace in separate (duplicate) function? */
321     if (cpu->machine->show_trace_tree)
322     cpu_functioncall_trace(cpu, cpu->pc);
323     if ((old_pc & ~mask_within_page) ==
324     (cpu->pc & ~mask_within_page)) {
325     cpu->cd.ppc.next_ic =
326     cpu->cd.ppc.cur_ic_page +
327     ((cpu->pc & mask_within_page) >>
328     PPC_INSTR_ALIGNMENT_SHIFT);
329     } else {
330     /* Find the new physical page and update pointers: */
331 dpavlin 22 quick_pc_to_pointers(cpu);
332 dpavlin 14 }
333     }
334     }
335    
336    
337     /*
338     * b: Branch (to a different translated page)
339     *
340 dpavlin 22 * arg[0] = relative offset (as an int32_t) from start of page
341 dpavlin 14 */
342     X(b)
343     {
344 dpavlin 22 cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1) << PPC_INSTR_ALIGNMENT_SHIFT);
345 dpavlin 14 cpu->pc += (int32_t)ic->arg[0];
346    
347     /* Find the new physical page and update the translation pointers: */
348 dpavlin 22 quick_pc_to_pointers(cpu);
349 dpavlin 14 }
350 dpavlin 20 X(ba)
351     {
352     cpu->pc = (int32_t)ic->arg[0];
353 dpavlin 22 quick_pc_to_pointers(cpu);
354 dpavlin 20 }
355 dpavlin 14
356    
357     /*
358     * bc: Branch Conditional (to a different translated page)
359     *
360 dpavlin 22 * arg[0] = relative offset (as an int32_t) from start of page
361 dpavlin 14 * arg[1] = bo
362 dpavlin 22 * arg[2] = 31-bi
363 dpavlin 14 */
364     X(bc)
365     {
366     MODE_uint_t tmp;
367 dpavlin 22 unsigned int ctr_ok, cond_ok, bi31m = ic->arg[2], bo = ic->arg[1];
368 dpavlin 14 if (!(bo & 4))
369 dpavlin 20 cpu->cd.ppc.spr[SPR_CTR] --;
370 dpavlin 14 ctr_ok = (bo >> 2) & 1;
371 dpavlin 20 tmp = cpu->cd.ppc.spr[SPR_CTR];
372 dpavlin 14 ctr_ok |= ( (tmp != 0) ^ ((bo >> 1) & 1) );
373     cond_ok = (bo >> 4) & 1;
374     cond_ok |= ( ((bo >> 3) & 1) ==
375 dpavlin 22 ((cpu->cd.ppc.cr >> (bi31m)) & 1) );
376 dpavlin 14 if (ctr_ok && cond_ok)
377     instr(b)(cpu,ic);
378     }
379 dpavlin 20 X(bcl)
380     {
381     MODE_uint_t tmp;
382 dpavlin 22 unsigned int ctr_ok, cond_ok, bi31m = ic->arg[2], bo = ic->arg[1];
383     int low_pc;
384 dpavlin 14
385 dpavlin 20 /* Calculate LR: */
386     low_pc = ((size_t)ic - (size_t)
387     cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call) + 1;
388 dpavlin 22 cpu->cd.ppc.spr[SPR_LR] = cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1)
389     << PPC_INSTR_ALIGNMENT_SHIFT);
390     cpu->cd.ppc.spr[SPR_LR] += (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
391 dpavlin 14
392 dpavlin 20 if (!(bo & 4))
393     cpu->cd.ppc.spr[SPR_CTR] --;
394     ctr_ok = (bo >> 2) & 1;
395     tmp = cpu->cd.ppc.spr[SPR_CTR];
396     ctr_ok |= ( (tmp != 0) ^ ((bo >> 1) & 1) );
397     cond_ok = (bo >> 4) & 1;
398     cond_ok |= ( ((bo >> 3) & 1) ==
399 dpavlin 22 ((cpu->cd.ppc.cr >> bi31m) & 1) );
400 dpavlin 20 if (ctr_ok && cond_ok)
401     instr(b)(cpu,ic);
402     }
403    
404    
405 dpavlin 14 /*
406     * b_samepage: Branch (to within the same translated page)
407     *
408     * arg[0] = pointer to new ppc_instr_call
409     */
410     X(b_samepage)
411     {
412     cpu->cd.ppc.next_ic = (struct ppc_instr_call *) ic->arg[0];
413     }
414    
415    
416     /*
417     * bc_samepage: Branch Conditional (to within the same page)
418     *
419     * arg[0] = new ic ptr
420     * arg[1] = bo
421 dpavlin 22 * arg[2] = 31-bi
422 dpavlin 14 */
423     X(bc_samepage)
424     {
425     MODE_uint_t tmp;
426 dpavlin 22 unsigned int ctr_ok, cond_ok, bi31m = ic->arg[2], bo = ic->arg[1];
427 dpavlin 14 if (!(bo & 4))
428 dpavlin 20 cpu->cd.ppc.spr[SPR_CTR] --;
429 dpavlin 14 ctr_ok = (bo >> 2) & 1;
430 dpavlin 20 tmp = cpu->cd.ppc.spr[SPR_CTR];
431 dpavlin 14 ctr_ok |= ( (tmp != 0) ^ ((bo >> 1) & 1) );
432     cond_ok = (bo >> 4) & 1;
433     cond_ok |= ( ((bo >> 3) & 1) ==
434 dpavlin 22 ((cpu->cd.ppc.cr >> bi31m) & 1) );
435 dpavlin 14 if (ctr_ok && cond_ok)
436 dpavlin 20 cpu->cd.ppc.next_ic = (struct ppc_instr_call *) ic->arg[0];
437 dpavlin 14 }
438 dpavlin 22 X(bc_samepage_simple0)
439 dpavlin 20 {
440 dpavlin 22 int bi31m = ic->arg[2];
441     if (!((cpu->cd.ppc.cr >> bi31m) & 1))
442 dpavlin 20 cpu->cd.ppc.next_ic = (struct ppc_instr_call *) ic->arg[0];
443     }
444 dpavlin 22 X(bc_samepage_simple1)
445     {
446     int bi31m = ic->arg[2];
447     if ((cpu->cd.ppc.cr >> bi31m) & 1)
448     cpu->cd.ppc.next_ic = (struct ppc_instr_call *) ic->arg[0];
449     }
450 dpavlin 20 X(bcl_samepage)
451     {
452     MODE_uint_t tmp;
453 dpavlin 22 unsigned int ctr_ok, cond_ok, bi31m = ic->arg[2], bo = ic->arg[1];
454     int low_pc;
455 dpavlin 14
456 dpavlin 20 /* Calculate LR: */
457     low_pc = ((size_t)ic - (size_t)
458     cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call) + 1;
459 dpavlin 22 cpu->cd.ppc.spr[SPR_LR] = cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1)
460     << PPC_INSTR_ALIGNMENT_SHIFT);
461     cpu->cd.ppc.spr[SPR_LR] += (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
462 dpavlin 14
463 dpavlin 20 if (!(bo & 4))
464     cpu->cd.ppc.spr[SPR_CTR] --;
465     ctr_ok = (bo >> 2) & 1;
466     tmp = cpu->cd.ppc.spr[SPR_CTR];
467     ctr_ok |= ( (tmp != 0) ^ ((bo >> 1) & 1) );
468     cond_ok = (bo >> 4) & 1;
469     cond_ok |= ( ((bo >> 3) & 1) ==
470 dpavlin 22 ((cpu->cd.ppc.cr >> bi31m) & 1) );
471 dpavlin 20 if (ctr_ok && cond_ok)
472     cpu->cd.ppc.next_ic = (struct ppc_instr_call *) ic->arg[0];
473     }
474    
475    
476 dpavlin 14 /*
477     * bl: Branch and Link (to a different translated page)
478     *
479 dpavlin 22 * arg[0] = relative offset (as an int32_t) from start of page
480     * arg[1] = lr offset (relative to start of current page)
481 dpavlin 14 */
482     X(bl)
483     {
484 dpavlin 22 /* Calculate LR and new PC: */
485     cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1) << PPC_INSTR_ALIGNMENT_SHIFT);
486     cpu->cd.ppc.spr[SPR_LR] = cpu->pc + ic->arg[1];
487 dpavlin 14 cpu->pc += (int32_t)ic->arg[0];
488    
489     /* Find the new physical page and update the translation pointers: */
490 dpavlin 22 quick_pc_to_pointers(cpu);
491 dpavlin 14 }
492 dpavlin 20 X(bla)
493     {
494 dpavlin 22 /* Calculate LR: */
495     cpu->cd.ppc.spr[SPR_LR] = (cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1)
496     << PPC_INSTR_ALIGNMENT_SHIFT)) + ic->arg[1];
497    
498 dpavlin 20 cpu->pc = (int32_t)ic->arg[0];
499 dpavlin 22 quick_pc_to_pointers(cpu);
500 dpavlin 20 }
501 dpavlin 14
502    
503     /*
504     * bl_trace: Branch and Link (to a different translated page) (with trace)
505     *
506 dpavlin 22 * arg[0] = relative offset (as an int32_t) from start of page
507     * arg[1] = lr offset (relative to start of current page)
508 dpavlin 14 */
509     X(bl_trace)
510     {
511     /* Calculate LR: */
512 dpavlin 22 cpu->cd.ppc.spr[SPR_LR] = (cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1)
513     << PPC_INSTR_ALIGNMENT_SHIFT)) + ic->arg[1];
514 dpavlin 14
515 dpavlin 22 /* Calculate new PC from start of page + arg[0] */
516     cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1) << PPC_INSTR_ALIGNMENT_SHIFT);
517 dpavlin 14 cpu->pc += (int32_t)ic->arg[0];
518    
519     cpu_functioncall_trace(cpu, cpu->pc);
520    
521     /* Find the new physical page and update the translation pointers: */
522 dpavlin 22 quick_pc_to_pointers(cpu);
523 dpavlin 14 }
524 dpavlin 20 X(bla_trace)
525     {
526 dpavlin 22 /* Calculate LR: */
527     cpu->cd.ppc.spr[SPR_LR] = (cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1)
528     << PPC_INSTR_ALIGNMENT_SHIFT)) + ic->arg[1];
529    
530 dpavlin 20 cpu->pc = (int32_t)ic->arg[0];
531     cpu_functioncall_trace(cpu, cpu->pc);
532 dpavlin 22 quick_pc_to_pointers(cpu);
533 dpavlin 20 }
534 dpavlin 14
535    
536     /*
537     * bl_samepage: Branch and Link (to within the same translated page)
538     *
539     * arg[0] = pointer to new ppc_instr_call
540 dpavlin 22 * arg[1] = lr offset (relative to start of current page)
541 dpavlin 14 */
542     X(bl_samepage)
543     {
544     /* Calculate LR: */
545 dpavlin 22 cpu->cd.ppc.spr[SPR_LR] = (cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1)
546     << PPC_INSTR_ALIGNMENT_SHIFT)) + ic->arg[1];
547 dpavlin 14
548     cpu->cd.ppc.next_ic = (struct ppc_instr_call *) ic->arg[0];
549     }
550    
551    
552     /*
553     * bl_samepage_trace: Branch and Link (to within the same translated page)
554     *
555     * arg[0] = pointer to new ppc_instr_call
556 dpavlin 22 * arg[1] = lr offset (relative to start of current page)
557 dpavlin 14 */
558     X(bl_samepage_trace)
559     {
560     uint32_t low_pc;
561    
562     /* Calculate LR: */
563 dpavlin 22 cpu->cd.ppc.spr[SPR_LR] = (cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1)
564     << PPC_INSTR_ALIGNMENT_SHIFT)) + ic->arg[1];
565 dpavlin 14
566     cpu->cd.ppc.next_ic = (struct ppc_instr_call *) ic->arg[0];
567    
568     /* Calculate new PC (for the trace) */
569     low_pc = ((size_t)cpu->cd.ppc.next_ic - (size_t)
570     cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
571 dpavlin 22 cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1) << PPC_INSTR_ALIGNMENT_SHIFT);
572     cpu->pc += (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
573 dpavlin 14 cpu_functioncall_trace(cpu, cpu->pc);
574     }
575    
576    
577     /*
578     * cntlzw: Count leading zeroes (32-bit word).
579     *
580     * arg[0] = ptr to rs
581     * arg[1] = ptr to ra
582     */
583     X(cntlzw)
584     {
585     uint32_t tmp = reg(ic->arg[0]);
586     int i;
587     for (i=0; i<32; i++) {
588     if (tmp & 0x80000000)
589     break;
590     tmp <<= 1;
591     }
592     reg(ic->arg[1]) = i;
593     }
594    
595    
596     /*
597     * cmpd: Compare Doubleword
598     *
599     * arg[0] = ptr to ra
600     * arg[1] = ptr to rb
601 dpavlin 20 * arg[2] = 28 - 4*bf
602 dpavlin 14 */
603     X(cmpd)
604     {
605     int64_t tmp = reg(ic->arg[0]), tmp2 = reg(ic->arg[1]);
606 dpavlin 20 int bf_shift = ic->arg[2], c;
607 dpavlin 14 if (tmp < tmp2)
608     c = 8;
609     else if (tmp > tmp2)
610     c = 4;
611     else
612     c = 2;
613 dpavlin 20 /* SO bit, copied from XER */
614     c |= ((cpu->cd.ppc.spr[SPR_XER] >> 31) & 1);
615     cpu->cd.ppc.cr &= ~(0xf << bf_shift);
616     cpu->cd.ppc.cr |= (c << bf_shift);
617 dpavlin 14 }
618    
619    
620     /*
621     * cmpld: Compare Doubleword, unsigned
622     *
623     * arg[0] = ptr to ra
624     * arg[1] = ptr to rb
625 dpavlin 20 * arg[2] = 28 - 4*bf
626 dpavlin 14 */
627     X(cmpld)
628     {
629     uint64_t tmp = reg(ic->arg[0]), tmp2 = reg(ic->arg[1]);
630 dpavlin 20 int bf_shift = ic->arg[2], c;
631 dpavlin 14 if (tmp < tmp2)
632     c = 8;
633     else if (tmp > tmp2)
634     c = 4;
635     else
636     c = 2;
637 dpavlin 20 /* SO bit, copied from XER */
638     c |= ((cpu->cd.ppc.spr[SPR_XER] >> 31) & 1);
639     cpu->cd.ppc.cr &= ~(0xf << bf_shift);
640     cpu->cd.ppc.cr |= (c << bf_shift);
641 dpavlin 14 }
642    
643    
644     /*
645     * cmpdi: Compare Doubleword immediate
646     *
647     * arg[0] = ptr to ra
648     * arg[1] = int32_t imm
649 dpavlin 20 * arg[2] = 28 - 4*bf
650 dpavlin 14 */
651     X(cmpdi)
652     {
653     int64_t tmp = reg(ic->arg[0]), imm = (int32_t)ic->arg[1];
654 dpavlin 20 int bf_shift = ic->arg[2], c;
655 dpavlin 14 if (tmp < imm)
656     c = 8;
657     else if (tmp > imm)
658     c = 4;
659     else
660     c = 2;
661 dpavlin 20 /* SO bit, copied from XER */
662     c |= ((cpu->cd.ppc.spr[SPR_XER] >> 31) & 1);
663     cpu->cd.ppc.cr &= ~(0xf << bf_shift);
664     cpu->cd.ppc.cr |= (c << bf_shift);
665 dpavlin 14 }
666    
667    
668     /*
669     * cmpldi: Compare Doubleword immediate, logical
670     *
671     * arg[0] = ptr to ra
672     * arg[1] = int32_t imm
673 dpavlin 20 * arg[2] = 28 - 4*bf
674 dpavlin 14 */
675     X(cmpldi)
676     {
677     uint64_t tmp = reg(ic->arg[0]), imm = (uint32_t)ic->arg[1];
678 dpavlin 20 int bf_shift = ic->arg[2], c;
679 dpavlin 14 if (tmp < imm)
680     c = 8;
681     else if (tmp > imm)
682     c = 4;
683     else
684     c = 2;
685 dpavlin 20 /* SO bit, copied from XER */
686     c |= ((cpu->cd.ppc.spr[SPR_XER] >> 31) & 1);
687     cpu->cd.ppc.cr &= ~(0xf << bf_shift);
688     cpu->cd.ppc.cr |= (c << bf_shift);
689 dpavlin 14 }
690    
691    
692     /*
693     * cmpw: Compare Word
694     *
695     * arg[0] = ptr to ra
696     * arg[1] = ptr to rb
697 dpavlin 20 * arg[2] = 28 - 4*bf
698 dpavlin 14 */
699     X(cmpw)
700     {
701     int32_t tmp = reg(ic->arg[0]), tmp2 = reg(ic->arg[1]);
702 dpavlin 20 int bf_shift = ic->arg[2], c;
703 dpavlin 14 if (tmp < tmp2)
704     c = 8;
705     else if (tmp > tmp2)
706     c = 4;
707     else
708     c = 2;
709 dpavlin 20 /* SO bit, copied from XER */
710     c |= ((cpu->cd.ppc.spr[SPR_XER] >> 31) & 1);
711     cpu->cd.ppc.cr &= ~(0xf << bf_shift);
712     cpu->cd.ppc.cr |= (c << bf_shift);
713 dpavlin 14 }
714 dpavlin 22 X(cmpw_cr0)
715     {
716     /* arg[2] is assumed to be 28 */
717     int32_t tmp = reg(ic->arg[0]), tmp2 = reg(ic->arg[1]);
718     cpu->cd.ppc.cr &= ~(0xf0000000);
719     if (tmp < tmp2)
720     cpu->cd.ppc.cr |= 0x80000000;
721     else if (tmp > tmp2)
722     cpu->cd.ppc.cr |= 0x40000000;
723     else
724     cpu->cd.ppc.cr |= 0x20000000;
725     cpu->cd.ppc.cr |= ((cpu->cd.ppc.spr[SPR_XER] >> 3) & 0x10000000);
726     }
727 dpavlin 14
728    
729     /*
730     * cmplw: Compare Word, unsigned
731     *
732     * arg[0] = ptr to ra
733     * arg[1] = ptr to rb
734 dpavlin 20 * arg[2] = 28 - 4*bf
735 dpavlin 14 */
736     X(cmplw)
737     {
738     uint32_t tmp = reg(ic->arg[0]), tmp2 = reg(ic->arg[1]);
739 dpavlin 20 int bf_shift = ic->arg[2], c;
740 dpavlin 14 if (tmp < tmp2)
741     c = 8;
742     else if (tmp > tmp2)
743     c = 4;
744     else
745     c = 2;
746 dpavlin 20 /* SO bit, copied from XER */
747     c |= ((cpu->cd.ppc.spr[SPR_XER] >> 31) & 1);
748     cpu->cd.ppc.cr &= ~(0xf << bf_shift);
749     cpu->cd.ppc.cr |= (c << bf_shift);
750 dpavlin 14 }
751    
752    
753     /*
754     * cmpwi: Compare Word immediate
755     *
756     * arg[0] = ptr to ra
757     * arg[1] = int32_t imm
758 dpavlin 20 * arg[2] = 28 - 4*bf
759 dpavlin 14 */
760     X(cmpwi)
761     {
762     int32_t tmp = reg(ic->arg[0]), imm = ic->arg[1];
763 dpavlin 20 int bf_shift = ic->arg[2], c;
764 dpavlin 14 if (tmp < imm)
765     c = 8;
766     else if (tmp > imm)
767     c = 4;
768     else
769     c = 2;
770 dpavlin 20 /* SO bit, copied from XER */
771     c |= ((cpu->cd.ppc.spr[SPR_XER] >> 31) & 1);
772     cpu->cd.ppc.cr &= ~(0xf << bf_shift);
773     cpu->cd.ppc.cr |= (c << bf_shift);
774 dpavlin 14 }
775 dpavlin 22 X(cmpwi_cr0)
776     {
777     /* arg[2] is assumed to be 28 */
778     int32_t tmp = reg(ic->arg[0]), imm = ic->arg[1];
779     cpu->cd.ppc.cr &= ~(0xf0000000);
780     if (tmp < imm)
781     cpu->cd.ppc.cr |= 0x80000000;
782     else if (tmp > imm)
783     cpu->cd.ppc.cr |= 0x40000000;
784     else
785     cpu->cd.ppc.cr |= 0x20000000;
786     cpu->cd.ppc.cr |= ((cpu->cd.ppc.spr[SPR_XER] >> 3) & 0x10000000);
787     }
788 dpavlin 14
789    
790     /*
791     * cmplwi: Compare Word immediate, logical
792     *
793     * arg[0] = ptr to ra
794     * arg[1] = int32_t imm
795 dpavlin 20 * arg[2] = 28 - 4*bf
796 dpavlin 14 */
797     X(cmplwi)
798     {
799     uint32_t tmp = reg(ic->arg[0]), imm = ic->arg[1];
800 dpavlin 20 int bf_shift = ic->arg[2], c;
801 dpavlin 14 if (tmp < imm)
802     c = 8;
803     else if (tmp > imm)
804     c = 4;
805     else
806     c = 2;
807 dpavlin 20 /* SO bit, copied from XER */
808     c |= ((cpu->cd.ppc.spr[SPR_XER] >> 31) & 1);
809     cpu->cd.ppc.cr &= ~(0xf << bf_shift);
810     cpu->cd.ppc.cr |= (c << bf_shift);
811 dpavlin 14 }
812    
813    
814     /*
815     * dcbz: Data-Cache Block Zero
816     *
817     * arg[0] = ptr to ra (or zero)
818     * arg[1] = ptr to rb
819     */
820     X(dcbz)
821     {
822     MODE_uint_t addr = reg(ic->arg[0]) + reg(ic->arg[1]);
823     unsigned char cacheline[128];
824 dpavlin 22 size_t cacheline_size = 1 << cpu->cd.ppc.cpu_type.dlinesize;
825     size_t cleared = 0;
826 dpavlin 14
827 dpavlin 20 /* Synchronize the PC first: */
828     cpu->pc = (cpu->pc & ~0xfff) + ic->arg[2];
829    
830 dpavlin 14 addr &= ~(cacheline_size - 1);
831     memset(cacheline, 0, sizeof(cacheline));
832    
833     while (cleared < cacheline_size) {
834     int to_clear = cacheline_size < sizeof(cacheline)?
835     cacheline_size : sizeof(cacheline);
836 dpavlin 22 #ifdef MODE32
837     unsigned char *page = cpu->cd.ppc.host_store[addr >> 12];
838     if (page != NULL) {
839     memset(page + (addr & 0xfff), 0, to_clear);
840     } else
841     #endif
842     if (cpu->memory_rw(cpu, cpu->mem, addr, cacheline,
843     to_clear, MEM_WRITE, CACHE_DATA) != MEMORY_ACCESS_OK) {
844 dpavlin 20 /* exception */
845     return;
846 dpavlin 14 }
847    
848     cleared += to_clear;
849     addr += to_clear;
850     }
851     }
852    
853    
854     /*
855 dpavlin 20 * mtfsf: Copy FPR into the FPSCR.
856     *
857     * arg[0] = ptr to frb
858     * arg[1] = mask
859     */
860     X(mtfsf)
861     {
862 dpavlin 22 CHECK_FOR_FPU_EXCEPTION;
863 dpavlin 20 cpu->cd.ppc.fpscr &= ~ic->arg[1];
864     cpu->cd.ppc.fpscr |= (ic->arg[1] & (*(uint64_t *)ic->arg[0]));
865     }
866    
867    
868     /*
869     * mffs: Copy FPSCR into a FPR.
870     *
871     * arg[0] = ptr to frt
872     */
873     X(mffs)
874     {
875 dpavlin 22 CHECK_FOR_FPU_EXCEPTION;
876 dpavlin 20 (*(uint64_t *)ic->arg[0]) = cpu->cd.ppc.fpscr;
877     }
878    
879    
880     /*
881 dpavlin 14 * fmr: Floating-point Move
882     *
883     * arg[0] = ptr to frb
884     * arg[1] = ptr to frt
885     */
886     X(fmr)
887     {
888 dpavlin 22 /*
889     * This works like a normal register to register copy, but
890     * a) it can cause an FPU exception, and b) the move is always
891     * 64-bit, even when running in 32-bit mode.
892     */
893     CHECK_FOR_FPU_EXCEPTION;
894 dpavlin 14 *(uint64_t *)ic->arg[1] = *(uint64_t *)ic->arg[0];
895     }
896    
897    
898     /*
899 dpavlin 20 * fneg: Floating-point Negate
900     *
901     * arg[0] = ptr to frb
902     * arg[1] = ptr to frt
903     */
904     X(fneg)
905     {
906     uint64_t v;
907 dpavlin 22 CHECK_FOR_FPU_EXCEPTION;
908 dpavlin 20 v = *(uint64_t *)ic->arg[0];
909     *(uint64_t *)ic->arg[1] = v ^ 0x8000000000000000ULL;
910     }
911    
912    
913     /*
914     * fcmpu: Floating-point Compare Unordered
915     *
916     * arg[0] = 28 - 4*bf (bitfield shift)
917     * arg[1] = ptr to fra
918     * arg[2] = ptr to frb
919     */
920     X(fcmpu)
921     {
922     struct ieee_float_value fra, frb;
923     int bf_shift = ic->arg[0], c = 0;
924    
925 dpavlin 22 CHECK_FOR_FPU_EXCEPTION;
926 dpavlin 20
927     ieee_interpret_float_value(*(uint64_t *)ic->arg[1], &fra, IEEE_FMT_D);
928     ieee_interpret_float_value(*(uint64_t *)ic->arg[2], &frb, IEEE_FMT_D);
929     if (fra.nan | frb.nan) {
930     c = 1;
931     } else {
932     if (fra.f < frb.f)
933     c = 8;
934     else if (fra.f > frb.f)
935     c = 4;
936     else
937     c = 2;
938     }
939     /* TODO: Signaling vs Quiet NaN */
940     cpu->cd.ppc.cr &= ~(0xf << bf_shift);
941     cpu->cd.ppc.cr |= ((c&0xe) << bf_shift);
942     cpu->cd.ppc.fpscr &= ~(PPC_FPSCR_FPCC | PPC_FPSCR_VXNAN);
943     cpu->cd.ppc.fpscr |= (c << PPC_FPSCR_FPCC_SHIFT);
944     }
945    
946    
947     /*
948     * frsp: Floating-point Round to Single Precision
949     *
950     * arg[0] = ptr to frb
951     * arg[1] = ptr to frt
952     */
953     X(frsp)
954     {
955     struct ieee_float_value frb;
956     float fl = 0.0;
957     int c = 0;
958    
959 dpavlin 22 CHECK_FOR_FPU_EXCEPTION;
960 dpavlin 20
961     ieee_interpret_float_value(*(uint64_t *)ic->arg[0], &frb, IEEE_FMT_D);
962     if (frb.nan) {
963     c = 1;
964     } else {
965     fl = frb.f;
966     if (fl < 0.0)
967     c = 8;
968     else if (fl > 0.0)
969     c = 4;
970     else
971     c = 2;
972     }
973     /* TODO: Signaling vs Quiet NaN */
974     cpu->cd.ppc.fpscr &= ~(PPC_FPSCR_FPCC | PPC_FPSCR_VXNAN);
975     cpu->cd.ppc.fpscr |= (c << PPC_FPSCR_FPCC_SHIFT);
976     (*(uint64_t *)ic->arg[1]) =
977     ieee_store_float_value(fl, IEEE_FMT_D, frb.nan);
978     }
979    
980    
981     /*
982     * fctiwz: Floating-point Convert to Integer Word, Round to Zero
983     *
984     * arg[0] = ptr to frb
985     * arg[1] = ptr to frt
986     */
987     X(fctiwz)
988     {
989     struct ieee_float_value frb;
990 dpavlin 24 uint32_t res = 0;
991 dpavlin 20
992 dpavlin 22 CHECK_FOR_FPU_EXCEPTION;
993 dpavlin 20
994     ieee_interpret_float_value(*(uint64_t *)ic->arg[0], &frb, IEEE_FMT_D);
995     if (!frb.nan) {
996     if (frb.f >= 2147483647.0)
997     res = 0x7fffffff;
998     else if (frb.f <= -2147483648.0)
999     res = 0x80000000;
1000     else
1001     res = frb.f;
1002     }
1003     *(uint64_t *)ic->arg[1] = (uint32_t)res;
1004     }
1005    
1006    
1007     /*
1008     * fmul: Floating-point Multiply
1009     *
1010     * arg[0] = ptr to frt
1011     * arg[1] = ptr to fra
1012     * arg[2] = ptr to frc
1013     */
1014     X(fmul)
1015     {
1016     struct ieee_float_value fra;
1017     struct ieee_float_value frc;
1018     double result = 0.0;
1019     int c, nan = 0;
1020    
1021 dpavlin 22 CHECK_FOR_FPU_EXCEPTION;
1022 dpavlin 20
1023     ieee_interpret_float_value(*(uint64_t *)ic->arg[1], &fra, IEEE_FMT_D);
1024     ieee_interpret_float_value(*(uint64_t *)ic->arg[2], &frc, IEEE_FMT_D);
1025     if (fra.nan || frc.nan)
1026     nan = 1;
1027     else
1028     result = fra.f * frc.f;
1029     if (nan)
1030     c = 1;
1031     else {
1032     if (result < 0.0)
1033     c = 8;
1034     else if (result > 0.0)
1035     c = 4;
1036     else
1037     c = 2;
1038     }
1039     /* TODO: Signaling vs Quiet NaN */
1040     cpu->cd.ppc.fpscr &= ~(PPC_FPSCR_FPCC | PPC_FPSCR_VXNAN);
1041     cpu->cd.ppc.fpscr |= (c << PPC_FPSCR_FPCC_SHIFT);
1042    
1043     (*(uint64_t *)ic->arg[0]) =
1044     ieee_store_float_value(result, IEEE_FMT_D, nan);
1045     }
1046     X(fmuls)
1047     {
1048     /* TODO */
1049     instr(fmul)(cpu, ic);
1050     }
1051    
1052    
1053     /*
1054     * fmadd: Floating-point Multiply and Add
1055     *
1056     * arg[0] = ptr to frt
1057     * arg[1] = ptr to fra
1058     * arg[2] = copy of the instruction word
1059     */
1060     X(fmadd)
1061     {
1062     uint32_t iw = ic->arg[2];
1063     int b = (iw >> 11) & 31, c = (iw >> 6) & 31;
1064     struct ieee_float_value fra;
1065     struct ieee_float_value frb;
1066     struct ieee_float_value frc;
1067     double result = 0.0;
1068     int nan = 0, cc;
1069    
1070 dpavlin 22 CHECK_FOR_FPU_EXCEPTION;
1071 dpavlin 20
1072     ieee_interpret_float_value(*(uint64_t *)ic->arg[1], &fra, IEEE_FMT_D);
1073     ieee_interpret_float_value(cpu->cd.ppc.fpr[b], &frb, IEEE_FMT_D);
1074     ieee_interpret_float_value(cpu->cd.ppc.fpr[c], &frc, IEEE_FMT_D);
1075     if (fra.nan || frb.nan || frc.nan)
1076     nan = 1;
1077     else
1078     result = fra.f * frc.f + frb.f;
1079     if (nan)
1080     cc = 1;
1081     else {
1082     if (result < 0.0)
1083     cc = 8;
1084     else if (result > 0.0)
1085     cc = 4;
1086     else
1087     cc = 2;
1088     }
1089     /* TODO: Signaling vs Quiet NaN */
1090     cpu->cd.ppc.fpscr &= ~(PPC_FPSCR_FPCC | PPC_FPSCR_VXNAN);
1091     cpu->cd.ppc.fpscr |= (cc << PPC_FPSCR_FPCC_SHIFT);
1092    
1093     (*(uint64_t *)ic->arg[0]) =
1094     ieee_store_float_value(result, IEEE_FMT_D, nan);
1095     }
1096    
1097    
1098     /*
1099     * fmsub: Floating-point Multiply and Sub
1100     *
1101     * arg[0] = ptr to frt
1102     * arg[1] = ptr to fra
1103     * arg[2] = copy of the instruction word
1104     */
1105     X(fmsub)
1106     {
1107     uint32_t iw = ic->arg[2];
1108     int b = (iw >> 11) & 31, c = (iw >> 6) & 31;
1109     struct ieee_float_value fra;
1110     struct ieee_float_value frb;
1111     struct ieee_float_value frc;
1112     double result = 0.0;
1113     int nan = 0, cc;
1114    
1115 dpavlin 22 CHECK_FOR_FPU_EXCEPTION;
1116 dpavlin 20
1117     ieee_interpret_float_value(*(uint64_t *)ic->arg[1], &fra, IEEE_FMT_D);
1118     ieee_interpret_float_value(cpu->cd.ppc.fpr[b], &frb, IEEE_FMT_D);
1119     ieee_interpret_float_value(cpu->cd.ppc.fpr[c], &frc, IEEE_FMT_D);
1120     if (fra.nan || frb.nan || frc.nan)
1121     nan = 1;
1122     else
1123     result = fra.f * frc.f - frb.f;
1124     if (nan)
1125     cc = 1;
1126     else {
1127     if (result < 0.0)
1128     cc = 8;
1129     else if (result > 0.0)
1130     cc = 4;
1131     else
1132     cc = 2;
1133     }
1134     /* TODO: Signaling vs Quiet NaN */
1135     cpu->cd.ppc.fpscr &= ~(PPC_FPSCR_FPCC | PPC_FPSCR_VXNAN);
1136     cpu->cd.ppc.fpscr |= (cc << PPC_FPSCR_FPCC_SHIFT);
1137    
1138     (*(uint64_t *)ic->arg[0]) =
1139     ieee_store_float_value(result, IEEE_FMT_D, nan);
1140     }
1141    
1142    
1143     /*
1144     * fadd, fsub, fdiv: Various Floating-point operationgs
1145     *
1146     * arg[0] = ptr to fra
1147     * arg[1] = ptr to frb
1148     * arg[2] = ptr to frt
1149     */
1150     X(fadd)
1151     {
1152     struct ieee_float_value fra;
1153     struct ieee_float_value frb;
1154     double result = 0.0;
1155     int nan = 0, c;
1156    
1157 dpavlin 22 CHECK_FOR_FPU_EXCEPTION;
1158 dpavlin 20
1159     ieee_interpret_float_value(*(uint64_t *)ic->arg[0], &fra, IEEE_FMT_D);
1160     ieee_interpret_float_value(*(uint64_t *)ic->arg[1], &frb, IEEE_FMT_D);
1161     if (fra.nan || frb.nan)
1162     nan = 1;
1163     else
1164     result = fra.f + frb.f;
1165     if (nan)
1166     c = 1;
1167     else {
1168     if (result < 0.0)
1169     c = 8;
1170     else if (result > 0.0)
1171     c = 4;
1172     else
1173     c = 2;
1174     }
1175     /* TODO: Signaling vs Quiet NaN */
1176     cpu->cd.ppc.fpscr &= ~(PPC_FPSCR_FPCC | PPC_FPSCR_VXNAN);
1177     cpu->cd.ppc.fpscr |= (c << PPC_FPSCR_FPCC_SHIFT);
1178    
1179     (*(uint64_t *)ic->arg[2]) =
1180     ieee_store_float_value(result, IEEE_FMT_D, nan);
1181     }
1182     X(fadds)
1183     {
1184     /* TODO */
1185     instr(fadd)(cpu, ic);
1186     }
1187     X(fsub)
1188     {
1189     struct ieee_float_value fra;
1190     struct ieee_float_value frb;
1191     double result = 0.0;
1192     int nan = 0, c;
1193    
1194 dpavlin 22 CHECK_FOR_FPU_EXCEPTION;
1195 dpavlin 20
1196     ieee_interpret_float_value(*(uint64_t *)ic->arg[0], &fra, IEEE_FMT_D);
1197     ieee_interpret_float_value(*(uint64_t *)ic->arg[1], &frb, IEEE_FMT_D);
1198     if (fra.nan || frb.nan)
1199     nan = 1;
1200     else
1201     result = fra.f - frb.f;
1202     if (nan)
1203     c = 1;
1204     else {
1205     if (result < 0.0)
1206     c = 8;
1207     else if (result > 0.0)
1208     c = 4;
1209     else
1210     c = 2;
1211     }
1212     /* TODO: Signaling vs Quiet NaN */
1213     cpu->cd.ppc.fpscr &= ~(PPC_FPSCR_FPCC | PPC_FPSCR_VXNAN);
1214     cpu->cd.ppc.fpscr |= (c << PPC_FPSCR_FPCC_SHIFT);
1215    
1216     (*(uint64_t *)ic->arg[2]) =
1217     ieee_store_float_value(result, IEEE_FMT_D, nan);
1218     }
1219     X(fsubs)
1220     {
1221     /* TODO */
1222     instr(fsub)(cpu, ic);
1223     }
1224     X(fdiv)
1225     {
1226     struct ieee_float_value fra;
1227     struct ieee_float_value frb;
1228     double result = 0.0;
1229     int nan = 0, c;
1230    
1231 dpavlin 22 CHECK_FOR_FPU_EXCEPTION;
1232 dpavlin 20
1233     ieee_interpret_float_value(*(uint64_t *)ic->arg[0], &fra, IEEE_FMT_D);
1234     ieee_interpret_float_value(*(uint64_t *)ic->arg[1], &frb, IEEE_FMT_D);
1235     if (fra.nan || frb.nan || frb.f == 0)
1236     nan = 1;
1237     else
1238     result = fra.f / frb.f;
1239     if (nan)
1240     c = 1;
1241     else {
1242     if (result < 0.0)
1243     c = 8;
1244     else if (result > 0.0)
1245     c = 4;
1246     else
1247     c = 2;
1248     }
1249     /* TODO: Signaling vs Quiet NaN */
1250     cpu->cd.ppc.fpscr &= ~(PPC_FPSCR_FPCC | PPC_FPSCR_VXNAN);
1251     cpu->cd.ppc.fpscr |= (c << PPC_FPSCR_FPCC_SHIFT);
1252    
1253     (*(uint64_t *)ic->arg[2]) =
1254     ieee_store_float_value(result, IEEE_FMT_D, nan);
1255     }
1256     X(fdivs)
1257     {
1258     /* TODO */
1259     instr(fdiv)(cpu, ic);
1260     }
1261    
1262    
1263     /*
1264 dpavlin 14 * llsc: Load-linked and store conditional
1265     *
1266     * arg[0] = copy of the instruction word.
1267     */
1268     X(llsc)
1269     {
1270     int iw = ic->arg[0], len = 4, load = 0, xo = (iw >> 1) & 1023;
1271     int i, rc = iw & 1, rt, ra, rb;
1272     uint64_t addr = 0, value;
1273     unsigned char d[8];
1274    
1275     switch (xo) {
1276     case PPC_31_LDARX:
1277     len = 8;
1278     case PPC_31_LWARX:
1279     load = 1;
1280     break;
1281     case PPC_31_STDCX_DOT:
1282     len = 8;
1283     case PPC_31_STWCX_DOT:
1284     break;
1285     }
1286    
1287     rt = (iw >> 21) & 31;
1288     ra = (iw >> 16) & 31;
1289     rb = (iw >> 11) & 31;
1290    
1291     if (ra != 0)
1292     addr = cpu->cd.ppc.gpr[ra];
1293     addr += cpu->cd.ppc.gpr[rb];
1294    
1295     if (load) {
1296     if (rc) {
1297     fatal("ll: rc-bit set?\n");
1298     exit(1);
1299     }
1300     if (cpu->memory_rw(cpu, cpu->mem, addr, d, len,
1301     MEM_READ, CACHE_DATA) != MEMORY_ACCESS_OK) {
1302     fatal("ll: error: TODO\n");
1303     exit(1);
1304     }
1305    
1306     value = 0;
1307     for (i=0; i<len; i++) {
1308     value <<= 8;
1309     if (cpu->byte_order == EMUL_BIG_ENDIAN)
1310     value |= d[i];
1311     else
1312     value |= d[len - 1 - i];
1313     }
1314    
1315     cpu->cd.ppc.gpr[rt] = value;
1316     cpu->cd.ppc.ll_addr = addr;
1317     cpu->cd.ppc.ll_bit = 1;
1318     } else {
1319 dpavlin 20 uint32_t old_so = cpu->cd.ppc.spr[SPR_XER] & PPC_XER_SO;
1320 dpavlin 14 if (!rc) {
1321     fatal("sc: rc-bit not set?\n");
1322     exit(1);
1323     }
1324    
1325     value = cpu->cd.ppc.gpr[rt];
1326    
1327     /* "If the store is performed, bits 0-2 of Condition
1328     Register Field 0 are set to 0b001, otherwise, they are
1329     set to 0b000. The SO bit of the XER is copied to to bit
1330     4 of Condition Register Field 0. */
1331     if (!cpu->cd.ppc.ll_bit || cpu->cd.ppc.ll_addr != addr) {
1332     cpu->cd.ppc.cr &= 0x0fffffff;
1333     if (old_so)
1334     cpu->cd.ppc.cr |= 0x10000000;
1335     cpu->cd.ppc.ll_bit = 0;
1336     return;
1337     }
1338    
1339     for (i=0; i<len; i++) {
1340     if (cpu->byte_order == EMUL_BIG_ENDIAN)
1341     d[len - 1 - i] = value >> (8*i);
1342     else
1343     d[i] = value >> (8*i);
1344     }
1345    
1346     if (cpu->memory_rw(cpu, cpu->mem, addr, d, len,
1347     MEM_WRITE, CACHE_DATA) != MEMORY_ACCESS_OK) {
1348     fatal("sc: error: TODO\n");
1349     exit(1);
1350     }
1351    
1352     cpu->cd.ppc.cr &= 0x0fffffff;
1353     cpu->cd.ppc.cr |= 0x20000000; /* success! */
1354     if (old_so)
1355     cpu->cd.ppc.cr |= 0x10000000;
1356    
1357     /* Clear _all_ CPUs' ll_bits: */
1358     for (i=0; i<cpu->machine->ncpus; i++)
1359     cpu->machine->cpus[i]->cd.ppc.ll_bit = 0;
1360     }
1361     }
1362    
1363    
1364     /*
1365 dpavlin 22 * mtsr, mtsrin: Move To Segment Register [Indirect]
1366 dpavlin 14 *
1367 dpavlin 20 * arg[0] = sr number, or for indirect mode: ptr to rb
1368 dpavlin 14 * arg[1] = ptr to rt
1369 dpavlin 22 *
1370     * TODO: These only work for 32-bit mode!
1371 dpavlin 14 */
1372     X(mtsr)
1373     {
1374 dpavlin 22 int sr_num = ic->arg[0];
1375     uint32_t old = cpu->cd.ppc.sr[sr_num];
1376     cpu->cd.ppc.sr[sr_num] = reg(ic->arg[1]);
1377 dpavlin 20
1378 dpavlin 22 if (cpu->cd.ppc.sr[sr_num] != old)
1379     cpu->invalidate_translation_caches(cpu, ic->arg[0] << 28,
1380     INVALIDATE_ALL | INVALIDATE_VADDR_UPPER4);
1381 dpavlin 14 }
1382 dpavlin 20 X(mtsrin)
1383     {
1384 dpavlin 22 int sr_num = reg(ic->arg[0]) >> 28;
1385     uint32_t old = cpu->cd.ppc.sr[sr_num];
1386 dpavlin 20 cpu->cd.ppc.sr[sr_num] = reg(ic->arg[1]);
1387 dpavlin 14
1388 dpavlin 22 if (cpu->cd.ppc.sr[sr_num] != old)
1389     cpu->invalidate_translation_caches(cpu, sr_num << 28,
1390     INVALIDATE_ALL | INVALIDATE_VADDR_UPPER4);
1391 dpavlin 20 }
1392 dpavlin 14
1393 dpavlin 20
1394 dpavlin 14 /*
1395     * mfsrin, mtsrin: Move From/To Segment Register Indirect
1396     *
1397 dpavlin 20 * arg[0] = sr number, or for indirect mode: ptr to rb
1398 dpavlin 14 * arg[1] = ptr to rt
1399     */
1400 dpavlin 20 X(mfsr)
1401 dpavlin 14 {
1402     /* TODO: This only works for 32-bit mode */
1403 dpavlin 20 reg(ic->arg[1]) = cpu->cd.ppc.sr[ic->arg[0]];
1404 dpavlin 14 }
1405 dpavlin 20 X(mfsrin)
1406 dpavlin 14 {
1407     /* TODO: This only works for 32-bit mode */
1408     uint32_t sr_num = reg(ic->arg[0]) >> 28;
1409 dpavlin 20 reg(ic->arg[1]) = cpu->cd.ppc.sr[sr_num];
1410 dpavlin 14 }
1411    
1412    
1413     /*
1414 dpavlin 24 * rldicl:
1415     *
1416     * arg[0] = copy of the instruction word
1417     */
1418     X(rldicl)
1419     {
1420     int rs = (ic->arg[0] >> 21) & 31;
1421     int ra = (ic->arg[0] >> 16) & 31;
1422     int sh = ((ic->arg[0] >> 11) & 31) | ((ic->arg[0] & 2) << 4);
1423     int mb = ((ic->arg[0] >> 6) & 31) | (ic->arg[0] & 0x20);
1424     int rc = ic->arg[0] & 1;
1425     uint64_t tmp = cpu->cd.ppc.gpr[rs], tmp2;
1426     /* TODO: Fix this, its performance is awful: */
1427     while (sh-- != 0) {
1428     int b = (tmp >> 63) & 1;
1429     tmp = (tmp << 1) | b;
1430     }
1431     tmp2 = 0;
1432     while (mb <= 63) {
1433     tmp |= ((uint64_t)1 << (63-mb));
1434     mb ++;
1435     }
1436     cpu->cd.ppc.gpr[ra] = tmp & tmp2;
1437     if (rc)
1438     update_cr0(cpu, cpu->cd.ppc.gpr[ra]);
1439     }
1440    
1441    
1442     /*
1443 dpavlin 14 * rldicr:
1444     *
1445     * arg[0] = copy of the instruction word
1446     */
1447     X(rldicr)
1448     {
1449     int rs = (ic->arg[0] >> 21) & 31;
1450     int ra = (ic->arg[0] >> 16) & 31;
1451     int sh = ((ic->arg[0] >> 11) & 31) | ((ic->arg[0] & 2) << 4);
1452     int me = ((ic->arg[0] >> 6) & 31) | (ic->arg[0] & 0x20);
1453     int rc = ic->arg[0] & 1;
1454     uint64_t tmp = cpu->cd.ppc.gpr[rs];
1455     /* TODO: Fix this, its performance is awful: */
1456     while (sh-- != 0) {
1457     int b = (tmp >> 63) & 1;
1458     tmp = (tmp << 1) | b;
1459     }
1460     while (me++ < 63)
1461     tmp &= ~((uint64_t)1 << (63-me));
1462     cpu->cd.ppc.gpr[ra] = tmp;
1463     if (rc)
1464     update_cr0(cpu, tmp);
1465     }
1466    
1467    
1468     /*
1469 dpavlin 24 * rldimi:
1470     *
1471     * arg[0] = copy of the instruction word
1472     */
1473     X(rldimi)
1474     {
1475     uint32_t iw = ic->arg[0];
1476     int rs = (iw >> 21) & 31, ra = (iw >> 16) & 31;
1477     int sh = ((iw >> 11) & 31) | ((iw & 2) << 4);
1478     int mb = ((iw >> 6) & 31) | (iw & 0x20);
1479     int rc = ic->arg[0] & 1;
1480     int m;
1481     uint64_t tmp, s = cpu->cd.ppc.gpr[rs];
1482     /* TODO: Fix this, its performance is awful: */
1483     while (sh-- != 0) {
1484     int b = (s >> 63) & 1;
1485     s = (s << 1) | b;
1486     }
1487     m = mb; tmp = 0;
1488     do {
1489     tmp |= ((uint64_t)1 << (63-m));
1490     m ++;
1491     } while (m != 63 - sh);
1492     cpu->cd.ppc.gpr[ra] &= ~tmp;
1493     cpu->cd.ppc.gpr[ra] |= (tmp & s);
1494     if (rc)
1495     update_cr0(cpu, cpu->cd.ppc.gpr[ra]);
1496     }
1497    
1498    
1499     /*
1500 dpavlin 20 * rlwnm:
1501     *
1502     * arg[0] = ptr to ra
1503     * arg[1] = mask
1504     * arg[2] = copy of the instruction word
1505     */
1506     X(rlwnm)
1507     {
1508     uint32_t tmp, iword = ic->arg[2];
1509     int rs = (iword >> 21) & 31;
1510     int rb = (iword >> 11) & 31;
1511     int sh = cpu->cd.ppc.gpr[rb] & 0x1f;
1512     tmp = (uint32_t)cpu->cd.ppc.gpr[rs];
1513     tmp = (tmp << sh) | (tmp >> (32-sh));
1514     tmp &= (uint32_t)ic->arg[1];
1515     reg(ic->arg[0]) = tmp;
1516     }
1517     DOT0(rlwnm)
1518    
1519    
1520     /*
1521 dpavlin 14 * rlwinm:
1522     *
1523 dpavlin 20 * arg[0] = ptr to ra
1524     * arg[1] = mask
1525 dpavlin 14 * arg[2] = copy of the instruction word
1526     */
1527     X(rlwinm)
1528     {
1529 dpavlin 20 uint32_t tmp, iword = ic->arg[2];
1530     int rs = (iword >> 21) & 31;
1531     int sh = (iword >> 11) & 31;
1532     tmp = (uint32_t)cpu->cd.ppc.gpr[rs];
1533     tmp = (tmp << sh) | (tmp >> (32-sh));
1534     tmp &= (uint32_t)ic->arg[1];
1535     reg(ic->arg[0]) = tmp;
1536 dpavlin 14 }
1537 dpavlin 20 DOT0(rlwinm)
1538 dpavlin 14
1539    
1540     /*
1541     * rlwimi:
1542     *
1543     * arg[0] = ptr to rs
1544     * arg[1] = ptr to ra
1545     * arg[2] = copy of the instruction word
1546     */
1547     X(rlwimi)
1548     {
1549     MODE_uint_t tmp = reg(ic->arg[0]), ra = reg(ic->arg[1]);
1550     uint32_t iword = ic->arg[2];
1551 dpavlin 20 int sh = (iword >> 11) & 31;
1552     int mb = (iword >> 6) & 31;
1553     int me = (iword >> 1) & 31;
1554     int rc = iword & 1;
1555 dpavlin 14
1556 dpavlin 20 tmp = (tmp << sh) | (tmp >> (32-sh));
1557 dpavlin 14
1558     for (;;) {
1559     uint64_t mask;
1560     mask = (uint64_t)1 << (31-mb);
1561     ra &= ~mask;
1562     ra |= (tmp & mask);
1563     if (mb == me)
1564     break;
1565     mb ++;
1566     if (mb == 32)
1567     mb = 0;
1568     }
1569     reg(ic->arg[1]) = ra;
1570     if (rc)
1571     update_cr0(cpu, ra);
1572     }
1573    
1574    
1575     /*
1576     * srawi:
1577     *
1578     * arg[0] = ptr to rs
1579     * arg[1] = ptr to ra
1580     * arg[2] = sh (shift amount)
1581     */
1582     X(srawi)
1583     {
1584     uint32_t tmp = reg(ic->arg[0]);
1585     int i = 0, j = 0, sh = ic->arg[2];
1586    
1587 dpavlin 20 cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
1588 dpavlin 14 if (tmp & 0x80000000)
1589     i = 1;
1590     while (sh-- > 0) {
1591     if (tmp & 1)
1592     j ++;
1593     tmp >>= 1;
1594     if (tmp & 0x40000000)
1595     tmp |= 0x80000000;
1596     }
1597     if (i && j>0)
1598 dpavlin 20 cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
1599 dpavlin 14 reg(ic->arg[1]) = (int64_t)(int32_t)tmp;
1600     }
1601 dpavlin 20 DOT1(srawi)
1602 dpavlin 14
1603    
1604     /*
1605     * mcrf: Move inside condition register
1606     *
1607 dpavlin 20 * arg[0] = 28-4*bf, arg[1] = 28-4*bfa
1608 dpavlin 14 */
1609     X(mcrf)
1610     {
1611 dpavlin 20 int bf_shift = ic->arg[0], bfa_shift = ic->arg[1];
1612     uint32_t tmp = (cpu->cd.ppc.cr >> bfa_shift) & 0xf;
1613     cpu->cd.ppc.cr &= ~(0xf << bf_shift);
1614     cpu->cd.ppc.cr |= (tmp << bf_shift);
1615 dpavlin 14 }
1616    
1617    
1618     /*
1619     * crand, crxor etc: Condition Register operations
1620     *
1621     * arg[0] = copy of the instruction word
1622     */
1623     X(crand) {
1624     uint32_t iword = ic->arg[0]; int bt = (iword >> 21) & 31;
1625     int ba = (iword >> 16) & 31, bb = (iword >> 11) & 31;
1626     ba = (cpu->cd.ppc.cr >> (31-ba)) & 1;
1627     bb = (cpu->cd.ppc.cr >> (31-bb)) & 1;
1628     cpu->cd.ppc.cr &= ~(1 << (31-bt));
1629     if (ba & bb)
1630     cpu->cd.ppc.cr |= (1 << (31-bt));
1631     }
1632     X(crandc) {
1633     uint32_t iword = ic->arg[0]; int bt = (iword >> 21) & 31;
1634     int ba = (iword >> 16) & 31, bb = (iword >> 11) & 31;
1635     ba = (cpu->cd.ppc.cr >> (31-ba)) & 1;
1636     bb = (cpu->cd.ppc.cr >> (31-bb)) & 1;
1637     cpu->cd.ppc.cr &= ~(1 << (31-bt));
1638     if (!(ba & bb))
1639     cpu->cd.ppc.cr |= (1 << (31-bt));
1640     }
1641     X(creqv) {
1642     uint32_t iword = ic->arg[0]; int bt = (iword >> 21) & 31;
1643     int ba = (iword >> 16) & 31, bb = (iword >> 11) & 31;
1644     ba = (cpu->cd.ppc.cr >> (31-ba)) & 1;
1645     bb = (cpu->cd.ppc.cr >> (31-bb)) & 1;
1646     cpu->cd.ppc.cr &= ~(1 << (31-bt));
1647     if (!(ba ^ bb))
1648     cpu->cd.ppc.cr |= (1 << (31-bt));
1649     }
1650     X(cror) {
1651     uint32_t iword = ic->arg[0]; int bt = (iword >> 21) & 31;
1652     int ba = (iword >> 16) & 31, bb = (iword >> 11) & 31;
1653     ba = (cpu->cd.ppc.cr >> (31-ba)) & 1;
1654     bb = (cpu->cd.ppc.cr >> (31-bb)) & 1;
1655     cpu->cd.ppc.cr &= ~(1 << (31-bt));
1656     if (ba | bb)
1657     cpu->cd.ppc.cr |= (1 << (31-bt));
1658     }
1659 dpavlin 22 X(crorc) {
1660     uint32_t iword = ic->arg[0]; int bt = (iword >> 21) & 31;
1661     int ba = (iword >> 16) & 31, bb = (iword >> 11) & 31;
1662     ba = (cpu->cd.ppc.cr >> (31-ba)) & 1;
1663     bb = (cpu->cd.ppc.cr >> (31-bb)) & 1;
1664     cpu->cd.ppc.cr &= ~(1 << (31-bt));
1665     if (!(ba | bb))
1666     cpu->cd.ppc.cr |= (1 << (31-bt));
1667     }
1668 dpavlin 20 X(crnor) {
1669     uint32_t iword = ic->arg[0]; int bt = (iword >> 21) & 31;
1670     int ba = (iword >> 16) & 31, bb = (iword >> 11) & 31;
1671     ba = (cpu->cd.ppc.cr >> (31-ba)) & 1;
1672     bb = (cpu->cd.ppc.cr >> (31-bb)) & 1;
1673     cpu->cd.ppc.cr &= ~(1 << (31-bt));
1674     if (!(ba | bb))
1675     cpu->cd.ppc.cr |= (1 << (31-bt));
1676     }
1677 dpavlin 14 X(crxor) {
1678     uint32_t iword = ic->arg[0]; int bt = (iword >> 21) & 31;
1679     int ba = (iword >> 16) & 31, bb = (iword >> 11) & 31;
1680     ba = (cpu->cd.ppc.cr >> (31-ba)) & 1;
1681     bb = (cpu->cd.ppc.cr >> (31-bb)) & 1;
1682     cpu->cd.ppc.cr &= ~(1 << (31-bt));
1683     if (ba ^ bb)
1684     cpu->cd.ppc.cr |= (1 << (31-bt));
1685     }
1686    
1687    
1688     /*
1689 dpavlin 20 * mfspr: Move from SPR
1690 dpavlin 14 *
1691     * arg[0] = pointer to destination register
1692 dpavlin 20 * arg[1] = pointer to source SPR
1693 dpavlin 14 */
1694 dpavlin 20 X(mfspr) {
1695 dpavlin 22 /* TODO: Check permission */
1696 dpavlin 20 reg(ic->arg[0]) = reg(ic->arg[1]);
1697     }
1698     X(mfspr_pmc1) {
1699     /*
1700     * TODO: This is a temporary hack to make NetBSD/ppc detect
1701     * a CPU of the correct (emulated) speed.
1702     */
1703     reg(ic->arg[0]) = cpu->machine->emulated_hz / 10;
1704     }
1705     X(mftb) {
1706     /* NOTE/TODO: This increments the time base (slowly) if it
1707     is being polled. */
1708     if (++cpu->cd.ppc.spr[SPR_TBL] == 0)
1709     cpu->cd.ppc.spr[SPR_TBU] ++;
1710     reg(ic->arg[0]) = cpu->cd.ppc.spr[SPR_TBL];
1711     }
1712     X(mftbu) {
1713     reg(ic->arg[0]) = cpu->cd.ppc.spr[SPR_TBU];
1714     }
1715 dpavlin 14
1716    
1717     /*
1718 dpavlin 20 * mtspr: Move to SPR.
1719 dpavlin 14 *
1720     * arg[0] = pointer to source register
1721 dpavlin 20 * arg[1] = pointer to the SPR
1722 dpavlin 14 */
1723 dpavlin 20 X(mtspr) {
1724 dpavlin 22 /* TODO: Check permission */
1725 dpavlin 20 reg(ic->arg[1]) = reg(ic->arg[0]);
1726     }
1727 dpavlin 22 X(mtlr) {
1728     cpu->cd.ppc.spr[SPR_LR] = reg(ic->arg[0]);
1729     }
1730     X(mtctr) {
1731     cpu->cd.ppc.spr[SPR_CTR] = reg(ic->arg[0]);
1732     }
1733 dpavlin 14
1734    
1735     /*
1736 dpavlin 24 * rfi[d]: Return from Interrupt
1737 dpavlin 14 */
1738     X(rfi)
1739     {
1740     uint64_t tmp;
1741    
1742 dpavlin 20 reg_access_msr(cpu, &tmp, 0, 0);
1743 dpavlin 14 tmp &= ~0xffff;
1744 dpavlin 20 tmp |= (cpu->cd.ppc.spr[SPR_SRR1] & 0xffff);
1745     reg_access_msr(cpu, &tmp, 1, 0);
1746 dpavlin 14
1747 dpavlin 20 cpu->pc = cpu->cd.ppc.spr[SPR_SRR0];
1748 dpavlin 22 quick_pc_to_pointers(cpu);
1749 dpavlin 14 }
1750 dpavlin 24 X(rfid)
1751     {
1752     uint64_t tmp, mask = 0x800000000000ff73ULL;
1753 dpavlin 14
1754 dpavlin 24 reg_access_msr(cpu, &tmp, 0, 0);
1755     tmp &= ~mask;
1756     tmp |= (cpu->cd.ppc.spr[SPR_SRR1] & mask);
1757     reg_access_msr(cpu, &tmp, 1, 0);
1758 dpavlin 14
1759 dpavlin 24 cpu->pc = cpu->cd.ppc.spr[SPR_SRR0];
1760     if (!(tmp & PPC_MSR_SF))
1761     cpu->pc = (uint32_t)cpu->pc;
1762     quick_pc_to_pointers(cpu);
1763     }
1764    
1765    
1766 dpavlin 14 /*
1767     * mfcr: Move From Condition Register
1768     *
1769     * arg[0] = pointer to destination register
1770     */
1771     X(mfcr)
1772     {
1773     reg(ic->arg[0]) = cpu->cd.ppc.cr;
1774     }
1775    
1776    
1777     /*
1778     * mfmsr: Move From MSR
1779     *
1780     * arg[0] = pointer to destination register
1781     */
1782     X(mfmsr)
1783     {
1784 dpavlin 20 reg_access_msr(cpu, (uint64_t*)ic->arg[0], 0, 0);
1785 dpavlin 14 }
1786    
1787    
1788     /*
1789     * mtmsr: Move To MSR
1790     *
1791     * arg[0] = pointer to source register
1792 dpavlin 24 * arg[1] = page offset of the next instruction
1793     * arg[2] = 0 for 32-bit (mtmsr), 1 for 64-bit (mtmsrd)
1794 dpavlin 14 */
1795     X(mtmsr)
1796     {
1797 dpavlin 22 MODE_uint_t old_pc;
1798 dpavlin 24 uint64_t x = reg(ic->arg[0]);
1799 dpavlin 22
1800     /* TODO: check permission! */
1801    
1802 dpavlin 20 /* Synchronize the PC (pointing to _after_ this instruction) */
1803     cpu->pc = (cpu->pc & ~0xfff) + ic->arg[1];
1804 dpavlin 22 old_pc = cpu->pc;
1805 dpavlin 20
1806 dpavlin 24 if (!ic->arg[2]) {
1807     uint64_t y;
1808     reg_access_msr(cpu, &y, 0, 0);
1809     x = (y & 0xffffffff00000000ULL) | (x & 0xffffffffULL);
1810     }
1811 dpavlin 22
1812 dpavlin 24 reg_access_msr(cpu, &x, 1, 1);
1813    
1814 dpavlin 22 /*
1815     * Super-ugly hack: If the pc wasn't changed (i.e. if there was no
1816     * exception while accessing the msr), then we _decrease_ the PC by 4
1817     * again. This is because the next ic could be an end_of_page.
1818     */
1819     if ((MODE_uint_t)cpu->pc == old_pc)
1820     cpu->pc -= 4;
1821 dpavlin 14 }
1822    
1823    
1824     /*
1825 dpavlin 22 * wrteei: Write EE immediate (on PPC405GP)
1826     *
1827     * arg[0] = either 0 or 0x8000
1828     */
1829     X(wrteei)
1830     {
1831     /* TODO: check permission! */
1832     uint64_t x;
1833    
1834     /* Synchronize the PC (pointing to _after_ this instruction) */
1835     cpu->pc = (cpu->pc & ~0xfff) + ic->arg[1];
1836    
1837     reg_access_msr(cpu, &x, 0, 0);
1838     x = (x & ~0x8000) | ic->arg[0];
1839     reg_access_msr(cpu, &x, 1, 1);
1840     }
1841    
1842    
1843     /*
1844 dpavlin 14 * mtcrf: Move To Condition Register Fields
1845     *
1846     * arg[0] = pointer to source register
1847     */
1848     X(mtcrf)
1849     {
1850     cpu->cd.ppc.cr &= ~ic->arg[1];
1851     cpu->cd.ppc.cr |= (reg(ic->arg[0]) & ic->arg[1]);
1852     }
1853    
1854    
1855     /*
1856     * mulli: Multiply Low Immediate.
1857     *
1858     * arg[0] = pointer to source register ra
1859     * arg[1] = int32_t immediate
1860     * arg[2] = pointer to destination register rt
1861     */
1862     X(mulli)
1863     {
1864 dpavlin 20 reg(ic->arg[2]) = (uint32_t)(reg(ic->arg[0]) * (int32_t)ic->arg[1]);
1865 dpavlin 14 }
1866    
1867    
1868     /*
1869     * Load/Store Multiple:
1870     *
1871     * arg[0] = rs (or rt for loads) NOTE: not a pointer
1872     * arg[1] = ptr to ra
1873     * arg[2] = int32_t immediate offset
1874     */
1875     X(lmw) {
1876     MODE_uint_t addr = reg(ic->arg[1]) + (int32_t)ic->arg[2];
1877     unsigned char d[4];
1878 dpavlin 20 int rs = ic->arg[0];
1879 dpavlin 14
1880 dpavlin 20 int low_pc = ((size_t)ic - (size_t)cpu->cd.ppc.cur_ic_page)
1881     / sizeof(struct ppc_instr_call);
1882     cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1)
1883     << PPC_INSTR_ALIGNMENT_SHIFT);
1884     cpu->pc |= (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
1885    
1886 dpavlin 14 while (rs <= 31) {
1887     if (cpu->memory_rw(cpu, cpu->mem, addr, d, sizeof(d),
1888 dpavlin 20 MEM_READ, CACHE_DATA) != MEMORY_ACCESS_OK) {
1889     /* exception */
1890     return;
1891     }
1892 dpavlin 14
1893     if (cpu->byte_order == EMUL_BIG_ENDIAN)
1894     cpu->cd.ppc.gpr[rs] = (d[0] << 24) + (d[1] << 16)
1895     + (d[2] << 8) + d[3];
1896     else
1897     cpu->cd.ppc.gpr[rs] = (d[3] << 24) + (d[2] << 16)
1898     + (d[1] << 8) + d[0];
1899    
1900     rs ++;
1901     addr += sizeof(uint32_t);
1902     }
1903     }
1904     X(stmw) {
1905     MODE_uint_t addr = reg(ic->arg[1]) + (int32_t)ic->arg[2];
1906     unsigned char d[4];
1907 dpavlin 20 int rs = ic->arg[0];
1908 dpavlin 14
1909 dpavlin 20 int low_pc = ((size_t)ic - (size_t)cpu->cd.ppc.cur_ic_page)
1910     / sizeof(struct ppc_instr_call);
1911     cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1)
1912     << PPC_INSTR_ALIGNMENT_SHIFT);
1913     cpu->pc += (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
1914    
1915 dpavlin 14 while (rs <= 31) {
1916 dpavlin 20 uint32_t tmp = cpu->cd.ppc.gpr[rs];
1917 dpavlin 14 if (cpu->byte_order == EMUL_BIG_ENDIAN) {
1918     d[3] = tmp; d[2] = tmp >> 8;
1919     d[1] = tmp >> 16; d[0] = tmp >> 24;
1920     } else {
1921     d[0] = tmp; d[1] = tmp >> 8;
1922     d[2] = tmp >> 16; d[3] = tmp >> 24;
1923     }
1924     if (cpu->memory_rw(cpu, cpu->mem, addr, d, sizeof(d),
1925 dpavlin 20 MEM_WRITE, CACHE_DATA) != MEMORY_ACCESS_OK) {
1926     /* exception */
1927     return;
1928 dpavlin 14 }
1929    
1930     rs ++;
1931     addr += sizeof(uint32_t);
1932     }
1933     }
1934    
1935    
1936     /*
1937 dpavlin 20 * Load/store string:
1938     *
1939     * arg[0] = rs (well, rt for lswi)
1940     * arg[1] = ptr to ra (or ptr to zero)
1941     * arg[2] = nb
1942     */
1943     X(lswi)
1944     {
1945     MODE_uint_t addr = reg(ic->arg[1]);
1946     int rt = ic->arg[0], nb = ic->arg[2];
1947     int sub = 0;
1948    
1949     int low_pc = ((size_t)ic - (size_t)cpu->cd.ppc.cur_ic_page)
1950     / sizeof(struct ppc_instr_call);
1951     cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1)
1952     << PPC_INSTR_ALIGNMENT_SHIFT);
1953     cpu->pc += (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
1954    
1955     while (nb > 0) {
1956     unsigned char d;
1957     if (cpu->memory_rw(cpu, cpu->mem, addr, &d, 1,
1958     MEM_READ, CACHE_DATA) != MEMORY_ACCESS_OK) {
1959     /* exception */
1960     return;
1961     }
1962    
1963     if (cpu->cd.ppc.mode == MODE_POWER && sub == 0)
1964     cpu->cd.ppc.gpr[rt] = 0;
1965     cpu->cd.ppc.gpr[rt] &= ~(0xff << (24-8*sub));
1966     cpu->cd.ppc.gpr[rt] |= (d << (24-8*sub));
1967     sub ++;
1968     if (sub == 4) {
1969     rt = (rt + 1) & 31;
1970     sub = 0;
1971     }
1972     addr ++;
1973     nb --;
1974     }
1975     }
1976     X(stswi)
1977     {
1978     MODE_uint_t addr = reg(ic->arg[1]);
1979     int rs = ic->arg[0], nb = ic->arg[2];
1980     uint32_t cur = cpu->cd.ppc.gpr[rs];
1981     int sub = 0;
1982    
1983     int low_pc = ((size_t)ic - (size_t)cpu->cd.ppc.cur_ic_page)
1984     / sizeof(struct ppc_instr_call);
1985     cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1)
1986     << PPC_INSTR_ALIGNMENT_SHIFT);
1987     cpu->pc += (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
1988    
1989     while (nb > 0) {
1990     unsigned char d = cur >> 24;
1991     if (cpu->memory_rw(cpu, cpu->mem, addr, &d, 1,
1992     MEM_WRITE, CACHE_DATA) != MEMORY_ACCESS_OK) {
1993     /* exception */
1994     return;
1995     }
1996     cur <<= 8;
1997     sub ++;
1998     if (sub == 4) {
1999     rs = (rs + 1) & 31;
2000     sub = 0;
2001     cur = cpu->cd.ppc.gpr[rs];
2002     }
2003     addr ++;
2004     nb --;
2005     }
2006     }
2007    
2008    
2009     /*
2010 dpavlin 14 * Shifts, and, or, xor, etc.
2011     *
2012     * arg[0] = pointer to source register rs
2013     * arg[1] = pointer to source register rb
2014     * arg[2] = pointer to destination register ra
2015     */
2016     X(extsb) {
2017     #ifdef MODE32
2018     reg(ic->arg[2]) = (int32_t)(int8_t)reg(ic->arg[0]);
2019     #else
2020     reg(ic->arg[2]) = (int64_t)(int8_t)reg(ic->arg[0]);
2021     #endif
2022     }
2023 dpavlin 20 DOT2(extsb)
2024 dpavlin 14 X(extsh) {
2025     #ifdef MODE32
2026     reg(ic->arg[2]) = (int32_t)(int16_t)reg(ic->arg[0]);
2027     #else
2028     reg(ic->arg[2]) = (int64_t)(int16_t)reg(ic->arg[0]);
2029     #endif
2030     }
2031 dpavlin 20 DOT2(extsh)
2032 dpavlin 14 X(extsw) {
2033     #ifdef MODE32
2034 dpavlin 24 fatal("TODO: extsw: invalid instruction\n");
2035 dpavlin 14 #else
2036     reg(ic->arg[2]) = (int64_t)(int32_t)reg(ic->arg[0]);
2037     #endif
2038     }
2039 dpavlin 20 DOT2(extsw)
2040 dpavlin 14 X(slw) { reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0])
2041 dpavlin 20 << (reg(ic->arg[1]) & 31); }
2042     DOT2(slw)
2043 dpavlin 24 X(sld) {int sa = reg(ic->arg[1]) & 127;
2044     if (sa >= 64) reg(ic->arg[2]) = 0;
2045     else reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0]) << (sa & 63); }
2046     DOT2(sld)
2047 dpavlin 20 X(sraw)
2048     {
2049     uint32_t tmp = reg(ic->arg[0]);
2050     int i = 0, j = 0, sh = reg(ic->arg[1]) & 31;
2051    
2052     cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2053     if (tmp & 0x80000000)
2054     i = 1;
2055     while (sh-- > 0) {
2056     if (tmp & 1)
2057     j ++;
2058     tmp >>= 1;
2059     if (tmp & 0x40000000)
2060     tmp |= 0x80000000;
2061     }
2062     if (i && j>0)
2063     cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2064     reg(ic->arg[2]) = (int64_t)(int32_t)tmp;
2065     }
2066     DOT2(sraw)
2067 dpavlin 14 X(srw) { reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0])
2068 dpavlin 20 >> (reg(ic->arg[1]) & 31); }
2069     DOT2(srw)
2070 dpavlin 14 X(and) { reg(ic->arg[2]) = reg(ic->arg[0]) & reg(ic->arg[1]); }
2071 dpavlin 20 DOT2(and)
2072 dpavlin 14 X(nand) { reg(ic->arg[2]) = ~(reg(ic->arg[0]) & reg(ic->arg[1])); }
2073 dpavlin 20 DOT2(nand)
2074 dpavlin 14 X(andc) { reg(ic->arg[2]) = reg(ic->arg[0]) & (~reg(ic->arg[1])); }
2075 dpavlin 20 DOT2(andc)
2076 dpavlin 14 X(nor) { reg(ic->arg[2]) = ~(reg(ic->arg[0]) | reg(ic->arg[1])); }
2077 dpavlin 20 DOT2(nor)
2078 dpavlin 22 X(mr) { reg(ic->arg[2]) = reg(ic->arg[1]); }
2079 dpavlin 14 X(or) { reg(ic->arg[2]) = reg(ic->arg[0]) | reg(ic->arg[1]); }
2080 dpavlin 20 DOT2(or)
2081 dpavlin 14 X(orc) { reg(ic->arg[2]) = reg(ic->arg[0]) | (~reg(ic->arg[1])); }
2082 dpavlin 20 DOT2(orc)
2083 dpavlin 14 X(xor) { reg(ic->arg[2]) = reg(ic->arg[0]) ^ reg(ic->arg[1]); }
2084 dpavlin 20 DOT2(xor)
2085 dpavlin 24 X(eqv) { reg(ic->arg[2]) = ~(reg(ic->arg[0]) ^ reg(ic->arg[1])); }
2086     DOT2(eqv)
2087 dpavlin 14
2088    
2089     /*
2090     * neg:
2091     *
2092     * arg[0] = pointer to source register ra
2093     * arg[1] = pointer to destination register rt
2094     */
2095     X(neg) { reg(ic->arg[1]) = -reg(ic->arg[0]); }
2096 dpavlin 20 DOT1(neg)
2097 dpavlin 14
2098    
2099     /*
2100     * mullw, mulhw[u], divw[u]:
2101     *
2102     * arg[0] = pointer to source register ra
2103     * arg[1] = pointer to source register rb
2104     * arg[2] = pointer to destination register rt
2105     */
2106     X(mullw)
2107     {
2108     int32_t sum = (int32_t)reg(ic->arg[0]) * (int32_t)reg(ic->arg[1]);
2109     reg(ic->arg[2]) = (int32_t)sum;
2110     }
2111 dpavlin 20 DOT2(mullw)
2112 dpavlin 14 X(mulhw)
2113     {
2114     int64_t sum;
2115     sum = (int64_t)(int32_t)reg(ic->arg[0])
2116     * (int64_t)(int32_t)reg(ic->arg[1]);
2117     reg(ic->arg[2]) = sum >> 32;
2118     }
2119 dpavlin 20 DOT2(mulhw)
2120 dpavlin 14 X(mulhwu)
2121     {
2122     uint64_t sum;
2123     sum = (uint64_t)(uint32_t)reg(ic->arg[0])
2124     * (uint64_t)(uint32_t)reg(ic->arg[1]);
2125     reg(ic->arg[2]) = sum >> 32;
2126     }
2127 dpavlin 20 DOT2(mulhwu)
2128 dpavlin 14 X(divw)
2129     {
2130     int32_t a = reg(ic->arg[0]), b = reg(ic->arg[1]);
2131     int32_t sum;
2132     if (b == 0)
2133     sum = 0;
2134     else
2135     sum = a / b;
2136     reg(ic->arg[2]) = (uint32_t)sum;
2137     }
2138 dpavlin 20 DOT2(divw)
2139 dpavlin 14 X(divwu)
2140     {
2141     uint32_t a = reg(ic->arg[0]), b = reg(ic->arg[1]);
2142     uint32_t sum;
2143     if (b == 0)
2144     sum = 0;
2145     else
2146     sum = a / b;
2147     reg(ic->arg[2]) = sum;
2148     }
2149 dpavlin 20 DOT2(divwu)
2150 dpavlin 14
2151    
2152     /*
2153     * add: Add.
2154     *
2155     * arg[0] = pointer to source register ra
2156     * arg[1] = pointer to source register rb
2157     * arg[2] = pointer to destination register rt
2158     */
2159     X(add) { reg(ic->arg[2]) = reg(ic->arg[0]) + reg(ic->arg[1]); }
2160 dpavlin 20 DOT2(add)
2161 dpavlin 14
2162    
2163     /*
2164     * addc: Add carrying.
2165     *
2166     * arg[0] = pointer to source register ra
2167     * arg[1] = pointer to source register rb
2168     * arg[2] = pointer to destination register rt
2169     */
2170     X(addc)
2171     {
2172     /* TODO: this only works in 32-bit mode */
2173     uint64_t tmp = (uint32_t)reg(ic->arg[0]);
2174     uint64_t tmp2 = tmp;
2175 dpavlin 20 cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2176 dpavlin 14 tmp += (uint32_t)reg(ic->arg[1]);
2177     if ((tmp >> 32) != (tmp2 >> 32))
2178 dpavlin 20 cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2179 dpavlin 14 reg(ic->arg[2]) = (uint32_t)tmp;
2180     }
2181    
2182    
2183     /*
2184     * adde: Add extended, etc.
2185     *
2186     * arg[0] = pointer to source register ra
2187     * arg[1] = pointer to source register rb
2188     * arg[2] = pointer to destination register rt
2189     */
2190     X(adde)
2191     {
2192     /* TODO: this only works in 32-bit mode */
2193 dpavlin 20 int old_ca = cpu->cd.ppc.spr[SPR_XER] & PPC_XER_CA;
2194 dpavlin 14 uint64_t tmp = (uint32_t)reg(ic->arg[0]);
2195     uint64_t tmp2 = tmp;
2196 dpavlin 20 cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2197 dpavlin 14 tmp += (uint32_t)reg(ic->arg[1]);
2198     if (old_ca)
2199     tmp ++;
2200     if ((tmp >> 32) != (tmp2 >> 32))
2201 dpavlin 20 cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2202 dpavlin 14 reg(ic->arg[2]) = (uint32_t)tmp;
2203     }
2204 dpavlin 20 DOT2(adde)
2205 dpavlin 14 X(addme)
2206     {
2207     /* TODO: this only works in 32-bit mode */
2208 dpavlin 20 int old_ca = cpu->cd.ppc.spr[SPR_XER] & PPC_XER_CA;
2209 dpavlin 14 uint64_t tmp = (uint32_t)reg(ic->arg[0]);
2210     uint64_t tmp2 = tmp;
2211 dpavlin 20 cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2212 dpavlin 14 if (old_ca)
2213     tmp ++;
2214     tmp += 0xffffffffULL;
2215     if ((tmp >> 32) != (tmp2 >> 32))
2216 dpavlin 20 cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2217 dpavlin 14 reg(ic->arg[2]) = (uint32_t)tmp;
2218     }
2219 dpavlin 20 DOT2(addme)
2220 dpavlin 14 X(addze)
2221     {
2222     /* TODO: this only works in 32-bit mode */
2223 dpavlin 20 int old_ca = cpu->cd.ppc.spr[SPR_XER] & PPC_XER_CA;
2224 dpavlin 14 uint64_t tmp = (uint32_t)reg(ic->arg[0]);
2225     uint64_t tmp2 = tmp;
2226 dpavlin 20 cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2227 dpavlin 14 if (old_ca)
2228     tmp ++;
2229     if ((tmp >> 32) != (tmp2 >> 32))
2230 dpavlin 20 cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2231 dpavlin 14 reg(ic->arg[2]) = (uint32_t)tmp;
2232     }
2233 dpavlin 20 DOT2(addze)
2234 dpavlin 14
2235    
2236     /*
2237     * subf: Subf, etc.
2238     *
2239     * arg[0] = pointer to source register ra
2240     * arg[1] = pointer to source register rb
2241     * arg[2] = pointer to destination register rt
2242     */
2243 dpavlin 20 X(subf)
2244     {
2245     reg(ic->arg[2]) = reg(ic->arg[1]) - reg(ic->arg[0]);
2246     }
2247     DOT2(subf)
2248 dpavlin 14 X(subfc)
2249     {
2250 dpavlin 20 cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2251 dpavlin 14 if (reg(ic->arg[1]) >= reg(ic->arg[0]))
2252 dpavlin 20 cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2253 dpavlin 14 reg(ic->arg[2]) = reg(ic->arg[1]) - reg(ic->arg[0]);
2254     }
2255 dpavlin 20 DOT2(subfc)
2256 dpavlin 14 X(subfe)
2257     {
2258 dpavlin 20 int old_ca = (cpu->cd.ppc.spr[SPR_XER] & PPC_XER_CA)? 1 : 0;
2259     cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2260 dpavlin 14 if (reg(ic->arg[1]) == reg(ic->arg[0])) {
2261     if (old_ca)
2262 dpavlin 20 cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2263 dpavlin 14 } else if (reg(ic->arg[1]) >= reg(ic->arg[0]))
2264 dpavlin 20 cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2265 dpavlin 14
2266     /*
2267     * TODO: The register value calculation should be correct,
2268     * but the CA bit calculation above is probably not.
2269     */
2270    
2271     reg(ic->arg[2]) = reg(ic->arg[1]) - reg(ic->arg[0]) - (old_ca? 0 : 1);
2272     }
2273 dpavlin 20 DOT2(subfe)
2274     X(subfme)
2275     {
2276     int old_ca = cpu->cd.ppc.spr[SPR_XER] & PPC_XER_CA;
2277     uint64_t tmp = (uint32_t)(~reg(ic->arg[0]));
2278     tmp += 0xffffffffULL;
2279     cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2280     if (old_ca)
2281     tmp ++;
2282     if ((tmp >> 32) != 0)
2283     cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2284     reg(ic->arg[2]) = (uint32_t)tmp;
2285     }
2286     DOT2(subfme)
2287 dpavlin 14 X(subfze)
2288     {
2289 dpavlin 20 int old_ca = cpu->cd.ppc.spr[SPR_XER] & PPC_XER_CA;
2290 dpavlin 14 uint64_t tmp = (uint32_t)(~reg(ic->arg[0]));
2291     uint64_t tmp2 = tmp;
2292 dpavlin 20 cpu->cd.ppc.spr[SPR_XER] &= ~PPC_XER_CA;
2293 dpavlin 14 if (old_ca)
2294     tmp ++;
2295     if ((tmp >> 32) != (tmp2 >> 32))
2296 dpavlin 20 cpu->cd.ppc.spr[SPR_XER] |= PPC_XER_CA;
2297 dpavlin 14 reg(ic->arg[2]) = (uint32_t)tmp;
2298     }
2299 dpavlin 20 DOT2(subfze)
2300 dpavlin 14
2301    
2302     /*
2303     * ori, xori etc.:
2304     *
2305     * arg[0] = pointer to source uint64_t
2306     * arg[1] = immediate value (uint32_t or larger)
2307     * arg[2] = pointer to destination uint64_t
2308     */
2309     X(ori) { reg(ic->arg[2]) = reg(ic->arg[0]) | (uint32_t)ic->arg[1]; }
2310     X(xori) { reg(ic->arg[2]) = reg(ic->arg[0]) ^ (uint32_t)ic->arg[1]; }
2311    
2312    
2313 dpavlin 20 #include "tmp_ppc_loadstore.c"
2314    
2315    
2316 dpavlin 14 /*
2317 dpavlin 20 * lfs, stfs: Load/Store Floating-point Single precision
2318     */
2319     X(lfs)
2320     {
2321 dpavlin 22 /* Sync. PC in case of an exception, and remember it: */
2322 dpavlin 20 uint64_t old_pc, low_pc = ((size_t)ic - (size_t)
2323     cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
2324 dpavlin 22 old_pc = cpu->pc = (cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) <<
2325     PPC_INSTR_ALIGNMENT_SHIFT)) + (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
2326 dpavlin 20 if (!(cpu->cd.ppc.msr & PPC_MSR_FP)) {
2327     ppc_exception(cpu, PPC_EXCEPTION_FPU);
2328     return;
2329     }
2330    
2331     /* Perform a 32-bit load: */
2332     #ifdef MODE32
2333     ppc32_loadstore
2334     #else
2335     ppc_loadstore
2336     #endif
2337     [2 + 4 + 8](cpu, ic);
2338    
2339     if (old_pc == cpu->pc) {
2340     /* The load succeeded. Let's convert the value: */
2341     struct ieee_float_value val;
2342     (*(uint64_t *)ic->arg[0]) &= 0xffffffff;
2343     ieee_interpret_float_value(*(uint64_t *)ic->arg[0],
2344     &val, IEEE_FMT_S);
2345     (*(uint64_t *)ic->arg[0]) =
2346     ieee_store_float_value(val.f, IEEE_FMT_D, val.nan);
2347     }
2348     }
2349     X(lfsx)
2350     {
2351 dpavlin 22 /* Sync. PC in case of an exception, and remember it: */
2352 dpavlin 20 uint64_t old_pc, low_pc = ((size_t)ic - (size_t)
2353     cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
2354 dpavlin 22 old_pc = cpu->pc = (cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) <<
2355     PPC_INSTR_ALIGNMENT_SHIFT)) + (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
2356 dpavlin 20 if (!(cpu->cd.ppc.msr & PPC_MSR_FP)) {
2357     ppc_exception(cpu, PPC_EXCEPTION_FPU);
2358     return;
2359     }
2360    
2361     /* Perform a 32-bit load: */
2362     #ifdef MODE32
2363     ppc32_loadstore_indexed
2364     #else
2365     ppc_loadstore_indexed
2366     #endif
2367     [2 + 4 + 8](cpu, ic);
2368    
2369     if (old_pc == cpu->pc) {
2370     /* The load succeeded. Let's convert the value: */
2371     struct ieee_float_value val;
2372     (*(uint64_t *)ic->arg[0]) &= 0xffffffff;
2373     ieee_interpret_float_value(*(uint64_t *)ic->arg[0],
2374     &val, IEEE_FMT_S);
2375     (*(uint64_t *)ic->arg[0]) =
2376     ieee_store_float_value(val.f, IEEE_FMT_D, val.nan);
2377     }
2378     }
2379     X(lfd)
2380     {
2381 dpavlin 22 CHECK_FOR_FPU_EXCEPTION;
2382 dpavlin 20
2383     /* Perform a 64-bit load: */
2384     #ifdef MODE32
2385     ppc32_loadstore
2386     #else
2387     ppc_loadstore
2388     #endif
2389     [3 + 4 + 8](cpu, ic);
2390     }
2391     X(lfdx)
2392     {
2393 dpavlin 22 CHECK_FOR_FPU_EXCEPTION;
2394    
2395 dpavlin 20 /* Perform a 64-bit load: */
2396     #ifdef MODE32
2397     ppc32_loadstore_indexed
2398     #else
2399     ppc_loadstore_indexed
2400     #endif
2401     [3 + 4 + 8](cpu, ic);
2402     }
2403     X(stfs)
2404     {
2405     uint64_t *old_arg0 = (void *)ic->arg[0];
2406     struct ieee_float_value val;
2407     uint64_t tmp_val;
2408    
2409 dpavlin 22 CHECK_FOR_FPU_EXCEPTION;
2410 dpavlin 20
2411     ieee_interpret_float_value(*old_arg0, &val, IEEE_FMT_D);
2412     tmp_val = ieee_store_float_value(val.f, IEEE_FMT_S, val.nan);
2413    
2414     ic->arg[0] = (size_t)&tmp_val;
2415    
2416     /* Perform a 32-bit store: */
2417     #ifdef MODE32
2418     ppc32_loadstore
2419     #else
2420     ppc_loadstore
2421     #endif
2422     [2 + 4](cpu, ic);
2423    
2424     ic->arg[0] = (size_t)old_arg0;
2425     }
2426     X(stfsx)
2427     {
2428     uint64_t *old_arg0 = (void *)ic->arg[0];
2429     struct ieee_float_value val;
2430     uint64_t tmp_val;
2431    
2432 dpavlin 22 CHECK_FOR_FPU_EXCEPTION;
2433 dpavlin 20
2434     ieee_interpret_float_value(*old_arg0, &val, IEEE_FMT_D);
2435     tmp_val = ieee_store_float_value(val.f, IEEE_FMT_S, val.nan);
2436    
2437     ic->arg[0] = (size_t)&tmp_val;
2438    
2439     /* Perform a 32-bit store: */
2440     #ifdef MODE32
2441     ppc32_loadstore_indexed
2442     #else
2443     ppc_loadstore_indexed
2444     #endif
2445     [2 + 4](cpu, ic);
2446    
2447     ic->arg[0] = (size_t)old_arg0;
2448     }
2449     X(stfd)
2450     {
2451 dpavlin 22 CHECK_FOR_FPU_EXCEPTION;
2452    
2453 dpavlin 20 /* Perform a 64-bit store: */
2454     #ifdef MODE32
2455     ppc32_loadstore
2456     #else
2457     ppc_loadstore
2458     #endif
2459     [3 + 4](cpu, ic);
2460     }
2461     X(stfdx)
2462     {
2463 dpavlin 22 CHECK_FOR_FPU_EXCEPTION;
2464    
2465 dpavlin 20 /* Perform a 64-bit store: */
2466     #ifdef MODE32
2467     ppc32_loadstore_indexed
2468     #else
2469     ppc_loadstore_indexed
2470     #endif
2471     [3 + 4](cpu, ic);
2472     }
2473    
2474    
2475     /*
2476 dpavlin 34 * lvx, stvx: Vector (16-byte) load/store (slow implementation)
2477     *
2478     * arg[0] = v-register nr of rs
2479     * arg[1] = pointer to ra
2480     * arg[2] = pointer to rb
2481     */
2482     X(lvx)
2483     {
2484     MODE_uint_t addr = reg(ic->arg[1]) + reg(ic->arg[2]);
2485     uint8_t data[16];
2486     uint64_t hi, lo;
2487     int rs = ic->arg[0];
2488    
2489     if (cpu->memory_rw(cpu, cpu->mem, addr, data, sizeof(data),
2490     MEM_READ, CACHE_DATA) != MEMORY_ACCESS_OK) {
2491     /* exception */
2492     return;
2493     }
2494    
2495     hi = ((uint64_t)data[0] << 56) +
2496     ((uint64_t)data[1] << 48) +
2497     ((uint64_t)data[2] << 40) +
2498     ((uint64_t)data[3] << 32) +
2499     ((uint64_t)data[4] << 24) +
2500     ((uint64_t)data[5] << 16) +
2501     ((uint64_t)data[6] << 8) +
2502     ((uint64_t)data[7]);
2503     lo = ((uint64_t)data[8] << 56) +
2504     ((uint64_t)data[9] << 48) +
2505     ((uint64_t)data[10] << 40) +
2506     ((uint64_t)data[11] << 32) +
2507     ((uint64_t)data[12] << 24) +
2508     ((uint64_t)data[13] << 16) +
2509     ((uint64_t)data[14] << 8) +
2510     ((uint64_t)data[15]);
2511    
2512     cpu->cd.ppc.vr_hi[rs] = hi; cpu->cd.ppc.vr_lo[rs] = lo;
2513     }
2514     X(stvx)
2515     {
2516     uint8_t data[16];
2517     MODE_uint_t addr = reg(ic->arg[1]) + reg(ic->arg[2]);
2518     int rs = ic->arg[0];
2519     uint64_t hi = cpu->cd.ppc.vr_hi[rs], lo = cpu->cd.ppc.vr_lo[rs];
2520    
2521     data[0] = hi >> 56;
2522     data[1] = hi >> 48;
2523     data[2] = hi >> 40;
2524     data[3] = hi >> 32;
2525     data[4] = hi >> 24;
2526     data[5] = hi >> 16;
2527     data[6] = hi >> 8;
2528     data[7] = hi;
2529     data[8] = lo >> 56;
2530     data[9] = lo >> 48;
2531     data[10] = lo >> 40;
2532     data[11] = lo >> 32;
2533     data[12] = lo >> 24;
2534     data[13] = lo >> 16;
2535     data[14] = lo >> 8;
2536     data[15] = lo;
2537    
2538     cpu->memory_rw(cpu, cpu->mem, addr, data,
2539     sizeof(data), MEM_WRITE, CACHE_DATA);
2540     }
2541    
2542    
2543     /*
2544     * vxor: Vector (16-byte) XOR
2545     *
2546     * arg[0] = v-register nr of source 1
2547     * arg[1] = v-register nr of source 2
2548     * arg[2] = v-register nr of destination
2549     */
2550     X(vxor)
2551     {
2552     cpu->cd.ppc.vr_hi[ic->arg[2]] =
2553     cpu->cd.ppc.vr_hi[ic->arg[0]] ^ cpu->cd.ppc.vr_hi[ic->arg[1]];
2554     cpu->cd.ppc.vr_lo[ic->arg[2]] =
2555     cpu->cd.ppc.vr_lo[ic->arg[0]] ^ cpu->cd.ppc.vr_lo[ic->arg[1]];
2556     }
2557    
2558    
2559     /*
2560 dpavlin 20 * tlbia: TLB invalidate all
2561     */
2562     X(tlbia)
2563     {
2564 dpavlin 24 fatal("[ tlbia ]\n");
2565 dpavlin 20 cpu->invalidate_translation_caches(cpu, 0, INVALIDATE_ALL);
2566     }
2567    
2568    
2569     /*
2570 dpavlin 14 * tlbie: TLB invalidate
2571     */
2572     X(tlbie)
2573     {
2574 dpavlin 24 /* fatal("[ tlbie ]\n"); */
2575 dpavlin 20 cpu->invalidate_translation_caches(cpu, reg(ic->arg[0]),
2576     INVALIDATE_VADDR);
2577 dpavlin 14 }
2578    
2579    
2580     /*
2581 dpavlin 20 * sc: Syscall.
2582     */
2583     X(sc)
2584     {
2585     /* Synchronize the PC (pointing to _after_ this instruction) */
2586     cpu->pc = (cpu->pc & ~0xfff) + ic->arg[1];
2587    
2588     ppc_exception(cpu, PPC_EXCEPTION_SC);
2589 dpavlin 22
2590     /* This caused an update to the PC register, so there is no need
2591     to worry about the next instruction being an end_of_page. */
2592 dpavlin 20 }
2593    
2594    
2595     /*
2596 dpavlin 14 * user_syscall: Userland syscall.
2597     *
2598     * arg[0] = syscall "level" (usually 0)
2599     */
2600     X(user_syscall)
2601     {
2602     useremul_syscall(cpu, ic->arg[0]);
2603 dpavlin 24
2604     if (!cpu->running) {
2605     cpu->n_translated_instrs --;
2606     cpu->cd.ppc.next_ic = &nothing_call;
2607     }
2608 dpavlin 14 }
2609    
2610    
2611     /*
2612     * openfirmware:
2613     */
2614     X(openfirmware)
2615     {
2616     of_emul(cpu);
2617 dpavlin 22 if (cpu->running == 0) {
2618 dpavlin 30 cpu->n_translated_instrs --;
2619     cpu->cd.ppc.next_ic = &nothing_call;
2620 dpavlin 22 }
2621 dpavlin 20 cpu->pc = cpu->cd.ppc.spr[SPR_LR];
2622 dpavlin 14 if (cpu->machine->show_trace_tree)
2623     cpu_functioncall_trace_return(cpu);
2624 dpavlin 22 quick_pc_to_pointers(cpu);
2625 dpavlin 14 }
2626    
2627    
2628 dpavlin 20 /*
2629 dpavlin 22 * tlbsx_dot: TLB scan
2630     */
2631     X(tlbsx_dot)
2632     {
2633     /* TODO */
2634     cpu->cd.ppc.cr &= ~(0xf0000000);
2635     cpu->cd.ppc.cr |= 0x20000000;
2636     cpu->cd.ppc.cr |= ((cpu->cd.ppc.spr[SPR_XER] >> 3) & 0x10000000);
2637     }
2638    
2639    
2640     /*
2641 dpavlin 20 * tlbli:
2642     */
2643     X(tlbli)
2644     {
2645 dpavlin 22 fatal("tlbli\n");
2646     cpu->invalidate_translation_caches(cpu, 0, INVALIDATE_ALL);
2647 dpavlin 20 }
2648 dpavlin 14
2649    
2650     /*
2651 dpavlin 20 * tlbld:
2652 dpavlin 14 */
2653 dpavlin 20 X(tlbld)
2654 dpavlin 14 {
2655 dpavlin 20 /* MODE_uint_t vaddr = reg(ic->arg[0]);
2656     MODE_uint_t paddr = cpu->cd.ppc.spr[SPR_RPA]; */
2657 dpavlin 14
2658 dpavlin 22 fatal("tlbld\n");
2659     cpu->invalidate_translation_caches(cpu, 0, INVALIDATE_ALL);
2660 dpavlin 14 }
2661    
2662    
2663     /*****************************************************************************/
2664    
2665    
2666     X(end_of_page)
2667     {
2668     /* Update the PC: (offset 0, but on the next page) */
2669 dpavlin 22 cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1) << PPC_INSTR_ALIGNMENT_SHIFT);
2670     cpu->pc += (PPC_IC_ENTRIES_PER_PAGE << PPC_INSTR_ALIGNMENT_SHIFT);
2671 dpavlin 14
2672     /* Find the new physical page and update the translation pointers: */
2673 dpavlin 22 quick_pc_to_pointers(cpu);
2674 dpavlin 14
2675     /* end_of_page doesn't count as an executed instruction: */
2676     cpu->n_translated_instrs --;
2677     }
2678    
2679    
2680     /*****************************************************************************/
2681    
2682    
2683     /*
2684     * ppc_instr_to_be_translated():
2685     *
2686 dpavlin 24 * Translate an instruction word into a ppc_instr_call. ic is filled in with
2687 dpavlin 14 * valid data for the translated instruction, or a "nothing" instruction if
2688     * there was a translation failure. The newly translated instruction is then
2689     * executed.
2690     */
2691     X(to_be_translated)
2692     {
2693     uint64_t addr, low_pc, tmp_addr;
2694 dpavlin 20 uint32_t iword, mask;
2695 dpavlin 14 unsigned char *page;
2696     unsigned char ib[4];
2697     int main_opcode, rt, rs, ra, rb, rc, aa_bit, l_bit, lk_bit, spr, sh,
2698     xo, imm, load, size, update, zero, bf, bo, bi, bh, oe_bit, n64=0,
2699 dpavlin 20 bfa, fp, byterev, nb, mb, me;
2700 dpavlin 14 void (*samepage_function)(struct cpu *, struct ppc_instr_call *);
2701     void (*rc_f)(struct cpu *, struct ppc_instr_call *);
2702    
2703     /* Figure out the (virtual) address of the instruction: */
2704     low_pc = ((size_t)ic - (size_t)cpu->cd.ppc.cur_ic_page)
2705     / sizeof(struct ppc_instr_call);
2706     addr = cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1)
2707     << PPC_INSTR_ALIGNMENT_SHIFT);
2708     addr += (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
2709     cpu->pc = addr;
2710     addr &= ~((1 << PPC_INSTR_ALIGNMENT_SHIFT) - 1);
2711    
2712     /* Read the instruction word from memory: */
2713 dpavlin 24 #ifdef MODE32
2714     page = cpu->cd.ppc.host_load[((uint32_t)addr) >> 12];
2715     #else
2716     {
2717     const uint32_t mask1 = (1 << DYNTRANS_L1N) - 1;
2718     const uint32_t mask2 = (1 << DYNTRANS_L2N) - 1;
2719     const uint32_t mask3 = (1 << DYNTRANS_L3N) - 1;
2720     uint32_t x1 = (addr >> (64-DYNTRANS_L1N)) & mask1;
2721     uint32_t x2 = (addr >> (64-DYNTRANS_L1N-DYNTRANS_L2N)) & mask2;
2722     uint32_t x3 = (addr >> (64-DYNTRANS_L1N-DYNTRANS_L2N-
2723     DYNTRANS_L3N)) & mask3;
2724     struct DYNTRANS_L2_64_TABLE *l2 = cpu->cd.ppc.l1_64[x1];
2725     struct DYNTRANS_L3_64_TABLE *l3 = l2->l3[x2];
2726     page = l3->host_load[x3];
2727     }
2728     #endif
2729 dpavlin 14
2730     if (page != NULL) {
2731     /* fatal("TRANSLATION HIT!\n"); */
2732     memcpy(ib, page + (addr & 0xfff), sizeof(ib));
2733     } else {
2734     /* fatal("TRANSLATION MISS!\n"); */
2735     if (!cpu->memory_rw(cpu, cpu->mem, addr, ib,
2736     sizeof(ib), MEM_READ, CACHE_INSTRUCTION)) {
2737 dpavlin 20 fatal("PPC to_be_translated(): "
2738 dpavlin 14 "read failed: TODO\n");
2739 dpavlin 20 exit(1);
2740     /* goto bad; */
2741 dpavlin 14 }
2742     }
2743    
2744     iword = *((uint32_t *)&ib[0]);
2745 dpavlin 22 iword = BE32_TO_HOST(iword);
2746 dpavlin 14
2747    
2748     #define DYNTRANS_TO_BE_TRANSLATED_HEAD
2749     #include "cpu_dyntrans.c"
2750     #undef DYNTRANS_TO_BE_TRANSLATED_HEAD
2751    
2752    
2753     /*
2754     * Translate the instruction:
2755     */
2756    
2757     main_opcode = iword >> 26;
2758    
2759     switch (main_opcode) {
2760    
2761 dpavlin 22 case 0x04:
2762 dpavlin 34 if (iword == 0x12739cc4) {
2763     /* vxor v19,v19,v19 */
2764     ic->f = instr(vxor);
2765     ic->arg[0] = 19;
2766     ic->arg[1] = 19;
2767     ic->arg[2] = 19;
2768     } else {
2769     fatal("[ TODO: Unimplemented ALTIVEC, iword"
2770     " = 0x%08"PRIx32"x ]\n", iword);
2771     goto bad;
2772     }
2773 dpavlin 22 break;
2774    
2775 dpavlin 14 case PPC_HI6_MULLI:
2776     rt = (iword >> 21) & 31;
2777     ra = (iword >> 16) & 31;
2778     imm = (int16_t)(iword & 0xffff);
2779     ic->f = instr(mulli);
2780     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2781     ic->arg[1] = (ssize_t)imm;
2782     ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);
2783     break;
2784    
2785     case PPC_HI6_SUBFIC:
2786     rt = (iword >> 21) & 31;
2787     ra = (iword >> 16) & 31;
2788     imm = (int16_t)(iword & 0xffff);
2789     ic->f = instr(subfic);
2790     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2791     ic->arg[1] = (ssize_t)imm;
2792     ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);
2793     break;
2794    
2795     case PPC_HI6_CMPLI:
2796     case PPC_HI6_CMPI:
2797     bf = (iword >> 23) & 7;
2798     l_bit = (iword >> 21) & 1;
2799     ra = (iword >> 16) & 31;
2800     if (main_opcode == PPC_HI6_CMPLI) {
2801     imm = iword & 0xffff;
2802     if (l_bit)
2803     ic->f = instr(cmpldi);
2804     else
2805     ic->f = instr(cmplwi);
2806     } else {
2807     imm = (int16_t)(iword & 0xffff);
2808     if (l_bit)
2809     ic->f = instr(cmpdi);
2810 dpavlin 22 else {
2811     if (bf == 0)
2812     ic->f = instr(cmpwi_cr0);
2813     else
2814     ic->f = instr(cmpwi);
2815     }
2816 dpavlin 14 }
2817     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2818     ic->arg[1] = (ssize_t)imm;
2819 dpavlin 20 ic->arg[2] = 28 - 4 * bf;
2820 dpavlin 14 break;
2821    
2822     case PPC_HI6_ADDIC:
2823     case PPC_HI6_ADDIC_DOT:
2824     if (cpu->cd.ppc.bits == 64) {
2825     fatal("addic for 64-bit: TODO\n");
2826     goto bad;
2827     }
2828     rt = (iword >> 21) & 31;
2829     ra = (iword >> 16) & 31;
2830     imm = (int16_t)(iword & 0xffff);
2831     if (main_opcode == PPC_HI6_ADDIC)
2832     ic->f = instr(addic);
2833     else
2834     ic->f = instr(addic_dot);
2835     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2836 dpavlin 20 ic->arg[1] = imm;
2837 dpavlin 14 ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);
2838     break;
2839    
2840     case PPC_HI6_ADDI:
2841     case PPC_HI6_ADDIS:
2842     rt = (iword >> 21) & 31; ra = (iword >> 16) & 31;
2843     ic->f = instr(addi);
2844     if (ra == 0)
2845 dpavlin 22 ic->f = instr(li);
2846 dpavlin 14 else
2847     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2848 dpavlin 20 ic->arg[1] = (int16_t)(iword & 0xffff);
2849 dpavlin 14 if (main_opcode == PPC_HI6_ADDIS)
2850     ic->arg[1] <<= 16;
2851 dpavlin 22 if (ra == 0 && ic->arg[1] == 0)
2852     ic->f = instr(li_0);
2853 dpavlin 14 ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);
2854     break;
2855    
2856     case PPC_HI6_ANDI_DOT:
2857     case PPC_HI6_ANDIS_DOT:
2858     rs = (iword >> 21) & 31; ra = (iword >> 16) & 31;
2859     ic->f = instr(andi_dot);
2860     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
2861     ic->arg[1] = iword & 0xffff;
2862     if (main_opcode == PPC_HI6_ANDIS_DOT)
2863     ic->arg[1] <<= 16;
2864     ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2865     break;
2866    
2867     case PPC_HI6_ORI:
2868     case PPC_HI6_ORIS:
2869     case PPC_HI6_XORI:
2870     case PPC_HI6_XORIS:
2871     rs = (iword >> 21) & 31; ra = (iword >> 16) & 31;
2872     if (main_opcode == PPC_HI6_ORI ||
2873     main_opcode == PPC_HI6_ORIS)
2874     ic->f = instr(ori);
2875     else
2876     ic->f = instr(xori);
2877     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
2878     ic->arg[1] = iword & 0xffff;
2879     if (main_opcode == PPC_HI6_ORIS ||
2880     main_opcode == PPC_HI6_XORIS)
2881     ic->arg[1] <<= 16;
2882     ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2883     break;
2884    
2885     case PPC_HI6_LBZ:
2886     case PPC_HI6_LBZU:
2887     case PPC_HI6_LHZ:
2888     case PPC_HI6_LHZU:
2889 dpavlin 20 case PPC_HI6_LHA:
2890     case PPC_HI6_LHAU:
2891 dpavlin 14 case PPC_HI6_LWZ:
2892     case PPC_HI6_LWZU:
2893 dpavlin 24 case PPC_HI6_LD:
2894 dpavlin 14 case PPC_HI6_LFD:
2895 dpavlin 20 case PPC_HI6_LFS:
2896 dpavlin 14 case PPC_HI6_STB:
2897     case PPC_HI6_STBU:
2898     case PPC_HI6_STH:
2899     case PPC_HI6_STHU:
2900     case PPC_HI6_STW:
2901     case PPC_HI6_STWU:
2902 dpavlin 24 case PPC_HI6_STD:
2903 dpavlin 20 case PPC_HI6_STFD:
2904     case PPC_HI6_STFS:
2905 dpavlin 14 rs = (iword >> 21) & 31;
2906     ra = (iword >> 16) & 31;
2907 dpavlin 20 imm = (int16_t)iword;
2908 dpavlin 14 load = 0; zero = 1; size = 0; update = 0; fp = 0;
2909 dpavlin 20 ic->f = NULL;
2910 dpavlin 14 switch (main_opcode) {
2911 dpavlin 20 case PPC_HI6_LBZ: load=1; break;
2912     case PPC_HI6_LBZU: load=1; update=1; break;
2913     case PPC_HI6_LHA: load=1; size=1; zero=0; break;
2914     case PPC_HI6_LHAU: load=1; size=1; zero=0; update=1; break;
2915     case PPC_HI6_LHZ: load=1; size=1; break;
2916     case PPC_HI6_LHZU: load=1; size=1; update=1; break;
2917     case PPC_HI6_LWZ: load=1; size=2; break;
2918     case PPC_HI6_LWZU: load=1; size=2; update=1; break;
2919 dpavlin 24 case PPC_HI6_LD: load=1; size=3; break;
2920 dpavlin 20 case PPC_HI6_LFD: load=1; size=3; fp=1;ic->f=instr(lfd);break;
2921     case PPC_HI6_LFS: load=1; size=2; fp=1;ic->f=instr(lfs);break;
2922 dpavlin 14 case PPC_HI6_STB: break;
2923 dpavlin 20 case PPC_HI6_STBU: update=1; break;
2924     case PPC_HI6_STH: size=1; break;
2925     case PPC_HI6_STHU: size=1; update=1; break;
2926     case PPC_HI6_STW: size=2; break;
2927     case PPC_HI6_STWU: size=2; update=1; break;
2928 dpavlin 24 case PPC_HI6_STD: size=3; break;
2929 dpavlin 20 case PPC_HI6_STFD: size=3; fp=1; ic->f = instr(stfd); break;
2930     case PPC_HI6_STFS: size=2; fp=1; ic->f = instr(stfs); break;
2931 dpavlin 14 }
2932 dpavlin 20 if (ic->f == NULL) {
2933 dpavlin 14 ic->f =
2934     #ifdef MODE32
2935     ppc32_loadstore
2936     #else
2937     ppc_loadstore
2938     #endif
2939     [size + 4*zero + 8*load + (imm==0? 16 : 0)
2940     + 32*update];
2941     }
2942     if (ra == 0 && update) {
2943     fatal("TODO: ra=0 && update?\n");
2944     goto bad;
2945     }
2946     if (fp)
2947     ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rs]);
2948     else
2949     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
2950     if (ra == 0)
2951     ic->arg[1] = (size_t)(&cpu->cd.ppc.zero);
2952     else
2953     ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
2954     ic->arg[2] = (ssize_t)imm;
2955     break;
2956    
2957     case PPC_HI6_BC:
2958     aa_bit = (iword >> 1) & 1;
2959     lk_bit = iword & 1;
2960     bo = (iword >> 21) & 31;
2961     bi = (iword >> 16) & 31;
2962     tmp_addr = (int64_t)(int16_t)(iword & 0xfffc);
2963     if (aa_bit) {
2964     fatal("aa_bit: NOT YET\n");
2965     goto bad;
2966     }
2967 dpavlin 20 if (lk_bit) {
2968     ic->f = instr(bcl);
2969     samepage_function = instr(bcl_samepage);
2970     } else {
2971     ic->f = instr(bc);
2972 dpavlin 22 if ((bo & 0x14) == 0x04) {
2973     samepage_function = bo & 8?
2974     instr(bc_samepage_simple1) :
2975     instr(bc_samepage_simple0);
2976     } else
2977 dpavlin 20 samepage_function = instr(bc_samepage);
2978     }
2979 dpavlin 22 ic->arg[0] = (ssize_t)(tmp_addr + (addr & 0xffc));
2980 dpavlin 14 ic->arg[1] = bo;
2981 dpavlin 22 ic->arg[2] = 31-bi;
2982 dpavlin 14 /* Branches are calculated as cur PC + offset. */
2983     /* Special case: branch within the same page: */
2984     {
2985     uint64_t mask_within_page =
2986     ((PPC_IC_ENTRIES_PER_PAGE-1) << 2) | 3;
2987     uint64_t old_pc = addr;
2988 dpavlin 22 uint64_t new_pc = old_pc + (int32_t)tmp_addr;
2989 dpavlin 14 if ((old_pc & ~mask_within_page) ==
2990     (new_pc & ~mask_within_page)) {
2991     ic->f = samepage_function;
2992     ic->arg[0] = (size_t) (
2993     cpu->cd.ppc.cur_ic_page +
2994     ((new_pc & mask_within_page) >> 2));
2995     }
2996     }
2997     break;
2998    
2999     case PPC_HI6_SC:
3000     ic->arg[0] = (iword >> 5) & 0x7f;
3001 dpavlin 20 ic->arg[1] = (addr & 0xfff) + 4;
3002 dpavlin 14 if (cpu->machine->userland_emul != NULL)
3003     ic->f = instr(user_syscall);
3004 dpavlin 20 else if (iword == 0x44ee0002) {
3005 dpavlin 14 /* Special case/magic hack for OpenFirmware emul: */
3006 dpavlin 20 ic->f = instr(openfirmware);
3007     } else
3008     ic->f = instr(sc);
3009 dpavlin 14 break;
3010    
3011     case PPC_HI6_B:
3012     aa_bit = (iword & 2) >> 1;
3013     lk_bit = iword & 1;
3014     tmp_addr = (int64_t)(int32_t)((iword & 0x03fffffc) << 6);
3015     tmp_addr = (int64_t)tmp_addr >> 6;
3016     if (lk_bit) {
3017     if (cpu->machine->show_trace_tree) {
3018     ic->f = instr(bl_trace);
3019     samepage_function = instr(bl_samepage_trace);
3020     } else {
3021     ic->f = instr(bl);
3022     samepage_function = instr(bl_samepage);
3023     }
3024     } else {
3025     ic->f = instr(b);
3026     samepage_function = instr(b_samepage);
3027     }
3028 dpavlin 22 ic->arg[0] = (ssize_t)(tmp_addr + (addr & 0xffc));
3029     ic->arg[1] = (addr & 0xffc) + 4;
3030 dpavlin 14 /* Branches are calculated as cur PC + offset. */
3031     /* Special case: branch within the same page: */
3032     {
3033     uint64_t mask_within_page =
3034     ((PPC_IC_ENTRIES_PER_PAGE-1) << 2) | 3;
3035     uint64_t old_pc = addr;
3036 dpavlin 22 uint64_t new_pc = old_pc + (int32_t)tmp_addr;
3037 dpavlin 14 if ((old_pc & ~mask_within_page) ==
3038     (new_pc & ~mask_within_page)) {
3039     ic->f = samepage_function;
3040     ic->arg[0] = (size_t) (
3041     cpu->cd.ppc.cur_ic_page +
3042     ((new_pc & mask_within_page) >> 2));
3043     }
3044     }
3045 dpavlin 20 if (aa_bit) {
3046     if (lk_bit) {
3047     if (cpu->machine->show_trace_tree) {
3048     ic->f = instr(bla_trace);
3049     } else {
3050     ic->f = instr(bla);
3051     }
3052     } else {
3053     ic->f = instr(ba);
3054     }
3055     ic->arg[0] = (ssize_t)tmp_addr;
3056     }
3057 dpavlin 14 break;
3058    
3059     case PPC_HI6_19:
3060     xo = (iword >> 1) & 1023;
3061     switch (xo) {
3062    
3063     case PPC_19_BCLR:
3064     case PPC_19_BCCTR:
3065     bo = (iword >> 21) & 31;
3066     bi = (iword >> 16) & 31;
3067     bh = (iword >> 11) & 3;
3068     lk_bit = iword & 1;
3069     if (xo == PPC_19_BCLR) {
3070     if (lk_bit)
3071     ic->f = instr(bclr_l);
3072 dpavlin 20 else {
3073 dpavlin 14 ic->f = instr(bclr);
3074 dpavlin 20 if (!cpu->machine->show_trace_tree &&
3075     (bo & 0x14) == 0x14)
3076     ic->f = instr(bclr_20);
3077     }
3078 dpavlin 14 } else {
3079     if (lk_bit)
3080     ic->f = instr(bcctr_l);
3081     else
3082     ic->f = instr(bcctr);
3083     }
3084     ic->arg[0] = bo;
3085 dpavlin 20 ic->arg[1] = 31 - bi;
3086 dpavlin 14 ic->arg[2] = bh;
3087     break;
3088    
3089     case PPC_19_ISYNC:
3090     /* TODO */
3091     ic->f = instr(nop);
3092     break;
3093    
3094     case PPC_19_RFI:
3095     ic->f = instr(rfi);
3096     break;
3097    
3098 dpavlin 24 case PPC_19_RFID:
3099     ic->f = instr(rfid);
3100     break;
3101    
3102 dpavlin 14 case PPC_19_MCRF:
3103     bf = (iword >> 23) & 7;
3104     bfa = (iword >> 18) & 7;
3105 dpavlin 20 ic->arg[0] = 28 - 4*bf;
3106     ic->arg[1] = 28 - 4*bfa;
3107 dpavlin 14 ic->f = instr(mcrf);
3108     break;
3109    
3110     case PPC_19_CRAND:
3111     case PPC_19_CRANDC:
3112     case PPC_19_CREQV:
3113     case PPC_19_CROR:
3114 dpavlin 22 case PPC_19_CRORC:
3115 dpavlin 20 case PPC_19_CRNOR:
3116 dpavlin 14 case PPC_19_CRXOR:
3117     switch (xo) {
3118     case PPC_19_CRAND: ic->f = instr(crand); break;
3119     case PPC_19_CRANDC: ic->f = instr(crandc); break;
3120     case PPC_19_CREQV: ic->f = instr(creqv); break;
3121     case PPC_19_CROR: ic->f = instr(cror); break;
3122 dpavlin 22 case PPC_19_CRORC: ic->f = instr(crorc); break;
3123 dpavlin 20 case PPC_19_CRNOR: ic->f = instr(crnor); break;
3124 dpavlin 14 case PPC_19_CRXOR: ic->f = instr(crxor); break;
3125     }
3126     ic->arg[0] = iword;
3127     break;
3128    
3129     default:goto bad;
3130     }
3131     break;
3132    
3133 dpavlin 20 case PPC_HI6_RLWNM:
3134     case PPC_HI6_RLWINM:
3135     ra = (iword >> 16) & 31;
3136     mb = (iword >> 6) & 31;
3137     me = (iword >> 1) & 31;
3138     rc = iword & 1;
3139     mask = 0;
3140     for (;;) {
3141     mask |= ((uint32_t)0x80000000 >> mb);
3142     if (mb == me)
3143     break;
3144     mb ++; mb &= 31;
3145     }
3146     switch (main_opcode) {
3147     case PPC_HI6_RLWNM:
3148     ic->f = rc? instr(rlwnm_dot) : instr(rlwnm); break;
3149     case PPC_HI6_RLWINM:
3150     ic->f = rc? instr(rlwinm_dot) : instr(rlwinm); break;
3151     }
3152     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3153     ic->arg[1] = mask;
3154     ic->arg[2] = (uint32_t)iword;
3155     break;
3156    
3157 dpavlin 14 case PPC_HI6_RLWIMI:
3158     rs = (iword >> 21) & 31;
3159     ra = (iword >> 16) & 31;
3160 dpavlin 20 ic->f = instr(rlwimi);
3161 dpavlin 14 ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
3162     ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3163     ic->arg[2] = (uint32_t)iword;
3164     break;
3165    
3166     case PPC_HI6_LMW:
3167     case PPC_HI6_STMW:
3168     /* NOTE: Loads use rt, not rs. */
3169     rs = (iword >> 21) & 31;
3170     ra = (iword >> 16) & 31;
3171     ic->arg[0] = rs;
3172     if (ra == 0)
3173     ic->arg[1] = (size_t)(&cpu->cd.ppc.zero);
3174     else
3175     ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3176     ic->arg[2] = (int32_t)(int16_t)iword;
3177     switch (main_opcode) {
3178     case PPC_HI6_LMW:
3179     ic->f = instr(lmw);
3180     break;
3181     case PPC_HI6_STMW:
3182     ic->f = instr(stmw);
3183     break;
3184     }
3185     break;
3186    
3187     case PPC_HI6_30:
3188     xo = (iword >> 2) & 7;
3189     switch (xo) {
3190    
3191 dpavlin 24 case PPC_30_RLDICL:
3192 dpavlin 14 case PPC_30_RLDICR:
3193 dpavlin 24 case PPC_30_RLDIMI:
3194     switch (xo) {
3195     case PPC_30_RLDICL: ic->f = instr(rldicl); break;
3196     case PPC_30_RLDICR: ic->f = instr(rldicr); break;
3197     case PPC_30_RLDIMI: ic->f = instr(rldimi); break;
3198     }
3199 dpavlin 14 ic->arg[0] = iword;
3200     if (cpu->cd.ppc.bits == 32) {
3201 dpavlin 24 fatal("TODO: rld* in 32-bit mode?\n");
3202 dpavlin 14 goto bad;
3203     }
3204     break;
3205    
3206     default:goto bad;
3207     }
3208     break;
3209    
3210     case PPC_HI6_31:
3211     xo = (iword >> 1) & 1023;
3212     switch (xo) {
3213    
3214     case PPC_31_CMPL:
3215     case PPC_31_CMP:
3216     bf = (iword >> 23) & 7;
3217     l_bit = (iword >> 21) & 1;
3218     ra = (iword >> 16) & 31;
3219     rb = (iword >> 11) & 31;
3220     if (xo == PPC_31_CMPL) {
3221     if (l_bit)
3222     ic->f = instr(cmpld);
3223     else
3224     ic->f = instr(cmplw);
3225     } else {
3226     if (l_bit)
3227     ic->f = instr(cmpd);
3228 dpavlin 22 else {
3229     if (bf == 0)
3230     ic->f = instr(cmpw_cr0);
3231     else
3232     ic->f = instr(cmpw);
3233     }
3234 dpavlin 14 }
3235     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3236     ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3237 dpavlin 20 ic->arg[2] = 28 - 4*bf;
3238 dpavlin 14 break;
3239    
3240     case PPC_31_CNTLZW:
3241     rs = (iword >> 21) & 31;
3242     ra = (iword >> 16) & 31;
3243     rc = iword & 1;
3244     if (rc) {
3245     fatal("TODO: rc\n");
3246     goto bad;
3247     }
3248     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
3249     ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3250     ic->f = instr(cntlzw);
3251     break;
3252    
3253     case PPC_31_MFSPR:
3254     rt = (iword >> 21) & 31;
3255     spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
3256 dpavlin 20 debug_spr_usage(cpu->pc, spr);
3257 dpavlin 14 ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rt]);
3258 dpavlin 20 ic->arg[1] = (size_t)(&cpu->cd.ppc.spr[spr]);
3259 dpavlin 14 switch (spr) {
3260 dpavlin 20 case SPR_PMC1: ic->f = instr(mfspr_pmc1); break;
3261     default: ic->f = instr(mfspr);
3262 dpavlin 14 }
3263     break;
3264    
3265     case PPC_31_MTSPR:
3266     rs = (iword >> 21) & 31;
3267     spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
3268 dpavlin 20 debug_spr_usage(cpu->pc, spr);
3269 dpavlin 14 ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
3270 dpavlin 20 ic->arg[1] = (size_t)(&cpu->cd.ppc.spr[spr]);
3271 dpavlin 22 switch (spr) {
3272     case SPR_LR:
3273     ic->f = instr(mtlr);
3274     break;
3275     case SPR_CTR:
3276     ic->f = instr(mtctr);
3277     break;
3278     default:ic->f = instr(mtspr);
3279     }
3280 dpavlin 14 break;
3281    
3282     case PPC_31_MFCR:
3283     rt = (iword >> 21) & 31;
3284     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rt]);
3285     ic->f = instr(mfcr);
3286     break;
3287    
3288     case PPC_31_MFMSR:
3289     rt = (iword >> 21) & 31;
3290     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rt]);
3291     ic->f = instr(mfmsr);
3292     break;
3293    
3294     case PPC_31_MTMSR:
3295 dpavlin 24 case PPC_31_MTMSRD:
3296 dpavlin 14 rs = (iword >> 21) & 31;
3297     l_bit = (iword >> 16) & 1;
3298     if (l_bit) {
3299     fatal("TODO: mtmsr l-bit\n");
3300     goto bad;
3301     }
3302     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
3303 dpavlin 20 ic->arg[1] = (addr & 0xfff) + 4;
3304 dpavlin 24 ic->arg[2] = xo == PPC_31_MTMSRD;
3305 dpavlin 14 ic->f = instr(mtmsr);
3306     break;
3307    
3308     case PPC_31_MTCRF:
3309     rs = (iword >> 21) & 31;
3310     {
3311     int i, fxm = (iword >> 12) & 255;
3312     uint32_t tmp = 0;
3313     for (i=0; i<8; i++, fxm <<= 1) {
3314     tmp <<= 4;
3315     if (fxm & 128)
3316     tmp |= 0xf;
3317     }
3318     ic->arg[1] = (uint32_t)tmp;
3319     }
3320     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
3321     ic->f = instr(mtcrf);
3322     break;
3323    
3324     case PPC_31_MFSRIN:
3325     case PPC_31_MTSRIN:
3326     rt = (iword >> 21) & 31;
3327     rb = (iword >> 11) & 31;
3328     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3329     ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rt]);
3330     switch (xo) {
3331     case PPC_31_MFSRIN: ic->f = instr(mfsrin); break;
3332     case PPC_31_MTSRIN: ic->f = instr(mtsrin); break;
3333     }
3334     if (cpu->cd.ppc.bits == 64) {
3335     fatal("Not yet for 64-bit mode\n");
3336     goto bad;
3337     }
3338     break;
3339    
3340 dpavlin 20 case PPC_31_MFSR:
3341 dpavlin 14 case PPC_31_MTSR:
3342     rt = (iword >> 21) & 31;
3343     ic->arg[0] = (iword >> 16) & 15;
3344     ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rt]);
3345 dpavlin 20 switch (xo) {
3346     case PPC_31_MFSR: ic->f = instr(mfsr); break;
3347     case PPC_31_MTSR: ic->f = instr(mtsr); break;
3348     }
3349 dpavlin 14 if (cpu->cd.ppc.bits == 64) {
3350     fatal("Not yet for 64-bit mode\n");
3351     goto bad;
3352     }
3353     break;
3354    
3355     case PPC_31_SRAWI:
3356     rs = (iword >> 21) & 31;
3357     ra = (iword >> 16) & 31;
3358     sh = (iword >> 11) & 31;
3359     rc = iword & 1;
3360     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
3361     ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3362     ic->arg[2] = sh;
3363     if (rc)
3364     ic->f = instr(srawi_dot);
3365     else
3366     ic->f = instr(srawi);
3367     break;
3368    
3369     case PPC_31_SYNC:
3370 dpavlin 24 case PPC_31_DSSALL:
3371 dpavlin 14 case PPC_31_EIEIO:
3372     case PPC_31_DCBST:
3373     case PPC_31_DCBTST:
3374     case PPC_31_DCBF:
3375     case PPC_31_DCBT:
3376     case PPC_31_ICBI:
3377     ic->f = instr(nop);
3378     break;
3379    
3380     case PPC_31_DCBZ:
3381     ra = (iword >> 16) & 31;
3382     rb = (iword >> 11) & 31;
3383     if (ra == 0)
3384     ic->arg[0] = (size_t)(&cpu->cd.ppc.zero);
3385     else
3386     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3387     ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3388 dpavlin 20 ic->arg[2] = addr & 0xfff;
3389 dpavlin 14 ic->f = instr(dcbz);
3390     break;
3391    
3392 dpavlin 20 case PPC_31_TLBIA:
3393     ic->f = instr(tlbia);
3394     break;
3395    
3396     case PPC_31_TLBSYNC:
3397     /* According to IBM, "Ensures that a tlbie and
3398     tlbia instruction executed by one processor has
3399     completed on all other processors.", which in
3400     GXemul means a nop :-) */
3401     ic->f = instr(nop);
3402     break;
3403    
3404 dpavlin 14 case PPC_31_TLBIE:
3405 dpavlin 20 /* TODO: POWER also uses ra? */
3406     rb = (iword >> 11) & 31;
3407     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3408 dpavlin 14 ic->f = instr(tlbie);
3409     break;
3410    
3411 dpavlin 20 case PPC_31_TLBLD: /* takes an arg */
3412     rb = (iword >> 11) & 31;
3413     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3414     ic->f = instr(tlbld);
3415     break;
3416    
3417     case PPC_31_TLBLI: /* takes an arg */
3418     rb = (iword >> 11) & 31;
3419     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3420     ic->f = instr(tlbli);
3421     break;
3422    
3423 dpavlin 22 case PPC_31_TLBSX_DOT:
3424     /* TODO */
3425     ic->f = instr(tlbsx_dot);
3426     break;
3427    
3428 dpavlin 14 case PPC_31_MFTB:
3429     rt = (iword >> 21) & 31;
3430     spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
3431     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rt]);
3432     switch (spr) {
3433     case 268: ic->f = instr(mftb); break;
3434     case 269: ic->f = instr(mftbu); break;
3435     default:fatal("mftb spr=%i?\n", spr);
3436     goto bad;
3437     }
3438     break;
3439    
3440     case PPC_31_NEG:
3441     rt = (iword >> 21) & 31;
3442     ra = (iword >> 16) & 31;
3443     rc = iword & 1;
3444     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3445     ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rt]);
3446     if (rc)
3447     ic->f = instr(neg_dot);
3448     else
3449     ic->f = instr(neg);
3450     break;
3451    
3452     case PPC_31_LWARX:
3453     case PPC_31_LDARX:
3454     case PPC_31_STWCX_DOT:
3455     case PPC_31_STDCX_DOT:
3456     ic->arg[0] = iword;
3457     ic->f = instr(llsc);
3458     break;
3459    
3460 dpavlin 20 case PPC_31_LSWI:
3461     case PPC_31_STSWI:
3462     rs = (iword >> 21) & 31;
3463     ra = (iword >> 16) & 31;
3464     nb = (iword >> 11) & 31;
3465     ic->arg[0] = rs;
3466     if (ra == 0)
3467     ic->arg[1] = (size_t)(&cpu->cd.ppc.zero);
3468     else
3469     ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3470     ic->arg[2] = nb == 0? 32 : nb;
3471     switch (xo) {
3472     case PPC_31_LSWI: ic->f = instr(lswi); break;
3473     case PPC_31_STSWI: ic->f = instr(stswi); break;
3474     }
3475     break;
3476    
3477 dpavlin 22 case PPC_31_WRTEEI:
3478     ic->arg[0] = iword & 0x8000;
3479     ic->f = instr(wrteei);
3480     break;
3481    
3482 dpavlin 20 case 0x1c3:
3483     fatal("[ mtdcr: TODO ]\n");
3484     ic->f = instr(nop);
3485     break;
3486    
3487 dpavlin 14 case PPC_31_LBZX:
3488     case PPC_31_LBZUX:
3489 dpavlin 20 case PPC_31_LHAX:
3490     case PPC_31_LHAUX:
3491 dpavlin 14 case PPC_31_LHZX:
3492     case PPC_31_LHZUX:
3493     case PPC_31_LWZX:
3494     case PPC_31_LWZUX:
3495 dpavlin 20 case PPC_31_LHBRX:
3496     case PPC_31_LWBRX:
3497     case PPC_31_LFDX:
3498     case PPC_31_LFSX:
3499 dpavlin 14 case PPC_31_STBX:
3500     case PPC_31_STBUX:
3501     case PPC_31_STHX:
3502     case PPC_31_STHUX:
3503     case PPC_31_STWX:
3504     case PPC_31_STWUX:
3505     case PPC_31_STDX:
3506     case PPC_31_STDUX:
3507 dpavlin 20 case PPC_31_STHBRX:
3508     case PPC_31_STWBRX:
3509     case PPC_31_STFDX:
3510     case PPC_31_STFSX:
3511 dpavlin 14 rs = (iword >> 21) & 31;
3512     ra = (iword >> 16) & 31;
3513     rb = (iword >> 11) & 31;
3514     if (ra == 0)
3515     ic->arg[1] = (size_t)(&cpu->cd.ppc.zero);
3516     else
3517     ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3518     ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3519     load = 0; zero = 1; size = 0; update = 0;
3520 dpavlin 20 byterev = 0; fp = 0;
3521     ic->f = NULL;
3522 dpavlin 14 switch (xo) {
3523     case PPC_31_LBZX: load = 1; break;
3524 dpavlin 20 case PPC_31_LBZUX: load=update=1; break;
3525     case PPC_31_LHAX: size=1; load=1; zero=0; break;
3526     case PPC_31_LHAUX: size=1; load=update=1; zero=0; break;
3527     case PPC_31_LHZX: size=1; load=1; break;
3528     case PPC_31_LHZUX: size=1; load=update = 1; break;
3529     case PPC_31_LWZX: size=2; load=1; break;
3530     case PPC_31_LWZUX: size=2; load=update = 1; break;
3531     case PPC_31_LHBRX: size=1; load=1; byterev=1;
3532     ic->f = instr(lhbrx); break;
3533     case PPC_31_LWBRX: size=2; load=1; byterev=1;
3534     ic->f = instr(lwbrx); break;
3535     case PPC_31_LFDX: size=3; load=1; fp=1;
3536     ic->f = instr(lfdx); break;
3537     case PPC_31_LFSX: size=2; load=1; fp=1;
3538     ic->f = instr(lfsx); break;
3539 dpavlin 14 case PPC_31_STBX: break;
3540     case PPC_31_STBUX: update = 1; break;
3541 dpavlin 20 case PPC_31_STHX: size=1; break;
3542     case PPC_31_STHUX: size=1; update = 1; break;
3543     case PPC_31_STWX: size=2; break;
3544     case PPC_31_STWUX: size=2; update = 1; break;
3545     case PPC_31_STDX: size=3; break;
3546     case PPC_31_STDUX: size=3; update = 1; break;
3547     case PPC_31_STHBRX:size=1; byterev = 1;
3548     ic->f = instr(sthbrx); break;
3549     case PPC_31_STWBRX:size=2; byterev = 1;
3550     ic->f = instr(stwbrx); break;
3551     case PPC_31_STFDX: size=3; fp=1;
3552     ic->f = instr(stfdx); break;
3553     case PPC_31_STFSX: size=2; fp=1;
3554     ic->f = instr(stfsx); break;
3555 dpavlin 14 }
3556 dpavlin 20 if (fp)
3557     ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rs]);
3558     else
3559     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
3560     if (!byterev && ic->f == NULL) {
3561     ic->f =
3562 dpavlin 14 #ifdef MODE32
3563 dpavlin 20 ppc32_loadstore_indexed
3564 dpavlin 14 #else
3565 dpavlin 20 ppc_loadstore_indexed
3566 dpavlin 14 #endif
3567 dpavlin 20 [size + 4*zero + 8*load + 16*update];
3568     }
3569 dpavlin 14 if (ra == 0 && update) {
3570     fatal("TODO: ra=0 && update?\n");
3571     goto bad;
3572     }
3573     break;
3574    
3575     case PPC_31_EXTSB:
3576     case PPC_31_EXTSH:
3577     case PPC_31_EXTSW:
3578     case PPC_31_SLW:
3579 dpavlin 24 case PPC_31_SLD:
3580 dpavlin 14 case PPC_31_SRAW:
3581     case PPC_31_SRW:
3582     case PPC_31_AND:
3583     case PPC_31_NAND:
3584     case PPC_31_ANDC:
3585     case PPC_31_NOR:
3586     case PPC_31_OR:
3587     case PPC_31_ORC:
3588     case PPC_31_XOR:
3589 dpavlin 24 case PPC_31_EQV:
3590 dpavlin 14 rs = (iword >> 21) & 31;
3591     ra = (iword >> 16) & 31;
3592     rb = (iword >> 11) & 31;
3593     rc = iword & 1;
3594     rc_f = NULL;
3595     switch (xo) {
3596     case PPC_31_EXTSB:ic->f = instr(extsb);
3597     rc_f = instr(extsb_dot); break;
3598     case PPC_31_EXTSH:ic->f = instr(extsh);
3599     rc_f = instr(extsh_dot); break;
3600     case PPC_31_EXTSW:ic->f = instr(extsw);
3601     rc_f = instr(extsw_dot); break;
3602     case PPC_31_SLW: ic->f = instr(slw);
3603     rc_f = instr(slw_dot); break;
3604 dpavlin 24 case PPC_31_SLD: ic->f = instr(sld);
3605     rc_f = instr(sld_dot); break;
3606 dpavlin 14 case PPC_31_SRAW: ic->f = instr(sraw);
3607     rc_f = instr(sraw_dot); break;
3608     case PPC_31_SRW: ic->f = instr(srw);
3609     rc_f = instr(srw_dot); break;
3610     case PPC_31_AND: ic->f = instr(and);
3611     rc_f = instr(and_dot); break;
3612     case PPC_31_NAND: ic->f = instr(nand);
3613     rc_f = instr(nand_dot); break;
3614     case PPC_31_ANDC: ic->f = instr(andc);
3615     rc_f = instr(andc_dot); break;
3616     case PPC_31_NOR: ic->f = instr(nor);
3617     rc_f = instr(nor_dot); break;
3618 dpavlin 22 case PPC_31_OR: ic->f = rs == rb? instr(mr)
3619     : instr(or);
3620 dpavlin 14 rc_f = instr(or_dot); break;
3621     case PPC_31_ORC: ic->f = instr(orc);
3622     rc_f = instr(orc_dot); break;
3623     case PPC_31_XOR: ic->f = instr(xor);
3624     rc_f = instr(xor_dot); break;
3625 dpavlin 24 case PPC_31_EQV: ic->f = instr(eqv);
3626     rc_f = instr(eqv_dot); break;
3627 dpavlin 14 }
3628     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
3629     ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3630     ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3631     if (rc)
3632     ic->f = rc_f;
3633     break;
3634    
3635     case PPC_31_MULLW:
3636     case PPC_31_MULHW:
3637     case PPC_31_MULHWU:
3638     case PPC_31_DIVW:
3639     case PPC_31_DIVWU:
3640     case PPC_31_ADD:
3641     case PPC_31_ADDC:
3642     case PPC_31_ADDE:
3643     case PPC_31_ADDME:
3644     case PPC_31_ADDZE:
3645     case PPC_31_SUBF:
3646     case PPC_31_SUBFC:
3647     case PPC_31_SUBFE:
3648 dpavlin 20 case PPC_31_SUBFME:
3649 dpavlin 14 case PPC_31_SUBFZE:
3650     rt = (iword >> 21) & 31;
3651     ra = (iword >> 16) & 31;
3652     rb = (iword >> 11) & 31;
3653     oe_bit = (iword >> 10) & 1;
3654     rc = iword & 1;
3655     if (oe_bit) {
3656     fatal("oe_bit not yet implemented\n");
3657     goto bad;
3658     }
3659     switch (xo) {
3660     case PPC_31_MULLW: ic->f = instr(mullw); break;
3661     case PPC_31_MULHW: ic->f = instr(mulhw); break;
3662     case PPC_31_MULHWU: ic->f = instr(mulhwu); break;
3663     case PPC_31_DIVW: ic->f = instr(divw); n64=1; break;
3664     case PPC_31_DIVWU: ic->f = instr(divwu); n64=1; break;
3665     case PPC_31_ADD: ic->f = instr(add); break;
3666     case PPC_31_ADDC: ic->f = instr(addc); n64=1; break;
3667     case PPC_31_ADDE: ic->f = instr(adde); n64=1; break;
3668     case PPC_31_ADDME: ic->f = instr(addme); n64=1; break;
3669     case PPC_31_ADDZE: ic->f = instr(addze); n64=1; break;
3670     case PPC_31_SUBF: ic->f = instr(subf); break;
3671     case PPC_31_SUBFC: ic->f = instr(subfc); break;
3672     case PPC_31_SUBFE: ic->f = instr(subfe); n64=1; break;
3673 dpavlin 20 case PPC_31_SUBFME: ic->f = instr(subfme); n64=1; break;
3674 dpavlin 14 case PPC_31_SUBFZE: ic->f = instr(subfze); n64=1;break;
3675     }
3676     if (rc) {
3677     switch (xo) {
3678     case PPC_31_ADD:
3679     ic->f = instr(add_dot); break;
3680     case PPC_31_ADDE:
3681     ic->f = instr(adde_dot); break;
3682     case PPC_31_ADDME:
3683     ic->f = instr(addme_dot); break;
3684     case PPC_31_ADDZE:
3685     ic->f = instr(addze_dot); break;
3686 dpavlin 20 case PPC_31_DIVW:
3687     ic->f = instr(divw_dot); break;
3688     case PPC_31_DIVWU:
3689     ic->f = instr(divwu_dot); break;
3690     case PPC_31_MULLW:
3691     ic->f = instr(mullw_dot); break;
3692     case PPC_31_MULHW:
3693     ic->f = instr(mulhw_dot); break;
3694     case PPC_31_MULHWU:
3695     ic->f = instr(mulhwu_dot); break;
3696 dpavlin 14 case PPC_31_SUBF:
3697     ic->f = instr(subf_dot); break;
3698     case PPC_31_SUBFC:
3699     ic->f = instr(subfc_dot); break;
3700     case PPC_31_SUBFE:
3701     ic->f = instr(subfe_dot); break;
3702 dpavlin 20 case PPC_31_SUBFME:
3703     ic->f = instr(subfme_dot); break;
3704 dpavlin 14 case PPC_31_SUBFZE:
3705     ic->f = instr(subfze_dot); break;
3706     default:fatal("RC bit not yet implemented\n");
3707     goto bad;
3708     }
3709     }
3710     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3711     ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3712     ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);
3713     if (cpu->cd.ppc.bits == 64 && n64) {
3714     fatal("Not yet for 64-bit mode\n");
3715     goto bad;
3716     }
3717     break;
3718    
3719 dpavlin 22 case PPC_31_LVX:
3720 dpavlin 24 case PPC_31_LVXL:
3721 dpavlin 22 case PPC_31_STVX:
3722     case PPC_31_STVXL:
3723 dpavlin 24 load = 0;
3724     switch (xo) {
3725     case PPC_31_LVX:
3726     case PPC_31_LVXL:
3727     load = 1; break;
3728     }
3729     rs = (iword >> 21) & 31;
3730     ra = (iword >> 16) & 31;
3731     rb = (iword >> 11) & 31;
3732 dpavlin 34 ic->arg[0] = rs;
3733 dpavlin 24 if (ra == 0)
3734     ic->arg[1] = (size_t)(&cpu->cd.ppc.zero);
3735     else
3736     ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
3737     ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rb]);
3738 dpavlin 34 ic->f = load? instr(lvx) : instr(stvx);
3739 dpavlin 22 break;
3740    
3741 dpavlin 14 default:goto bad;
3742     }
3743     break;
3744    
3745 dpavlin 20 case PPC_HI6_59:
3746     xo = (iword >> 1) & 1023;
3747 dpavlin 14 rt = (iword >> 21) & 31;
3748     ra = (iword >> 16) & 31;
3749     rb = (iword >> 11) & 31;
3750 dpavlin 20 rs = (iword >> 6) & 31; /* actually frc */
3751 dpavlin 14 rc = iword & 1;
3752    
3753 dpavlin 20 if (rc) {
3754     fatal("Floating point (59) with rc bit! TODO\n");
3755     goto bad;
3756     }
3757 dpavlin 14
3758 dpavlin 20 /* NOTE: Some floating-point instructions are selected
3759     using only the lowest 5 bits, not all 10! */
3760     switch (xo & 31) {
3761     case PPC_59_FDIVS:
3762     case PPC_59_FSUBS:
3763     case PPC_59_FADDS:
3764     switch (xo & 31) {
3765     case PPC_59_FDIVS: ic->f = instr(fdivs); break;
3766     case PPC_59_FSUBS: ic->f = instr(fsubs); break;
3767     case PPC_59_FADDS: ic->f = instr(fadds); break;
3768 dpavlin 14 }
3769 dpavlin 20 ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[ra]);
3770     ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[rb]);
3771     ic->arg[2] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3772 dpavlin 14 break;
3773 dpavlin 20 case PPC_59_FMULS:
3774     ic->f = instr(fmuls);
3775     ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3776     ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[ra]);
3777     ic->arg[2] = (size_t)(&cpu->cd.ppc.fpr[rs]); /* frc */
3778     break;
3779     default:/* Use all 10 bits of xo: */
3780     switch (xo) {
3781     default:goto bad;
3782     }
3783     }
3784     break;
3785 dpavlin 14
3786 dpavlin 20 case PPC_HI6_63:
3787     xo = (iword >> 1) & 1023;
3788     rt = (iword >> 21) & 31;
3789     ra = (iword >> 16) & 31;
3790     rb = (iword >> 11) & 31;
3791     rs = (iword >> 6) & 31; /* actually frc */
3792     rc = iword & 1;
3793    
3794     if (rc) {
3795     fatal("Floating point (63) with rc bit! TODO\n");
3796     goto bad;
3797 dpavlin 14 }
3798 dpavlin 20
3799     /* NOTE: Some floating-point instructions are selected
3800     using only the lowest 5 bits, not all 10! */
3801     switch (xo & 31) {
3802     case PPC_63_FDIV:
3803     case PPC_63_FSUB:
3804     case PPC_63_FADD:
3805     switch (xo & 31) {
3806     case PPC_63_FDIV: ic->f = instr(fdiv); break;
3807     case PPC_63_FSUB: ic->f = instr(fsub); break;
3808     case PPC_63_FADD: ic->f = instr(fadd); break;
3809     }
3810     ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[ra]);
3811     ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[rb]);
3812     ic->arg[2] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3813     break;
3814     case PPC_63_FMUL:
3815     ic->f = instr(fmul);
3816     ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3817     ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[ra]);
3818     ic->arg[2] = (size_t)(&cpu->cd.ppc.fpr[rs]); /* frc */
3819     break;
3820     case PPC_63_FMSUB:
3821     case PPC_63_FMADD:
3822     switch (xo & 31) {
3823     case PPC_63_FMSUB: ic->f = instr(fmsub); break;
3824     case PPC_63_FMADD: ic->f = instr(fmadd); break;
3825     }
3826     ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3827     ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[ra]);
3828     ic->arg[2] = iword;
3829     break;
3830     default:/* Use all 10 bits of xo: */
3831     switch (xo) {
3832     case PPC_63_FCMPU:
3833     ic->f = instr(fcmpu);
3834     ic->arg[0] = 28 - 4*(rt >> 2);
3835     ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[ra]);
3836     ic->arg[2] = (size_t)(&cpu->cd.ppc.fpr[rb]);
3837     break;
3838     case PPC_63_FRSP:
3839     case PPC_63_FCTIWZ:
3840     case PPC_63_FNEG:
3841     case PPC_63_FMR:
3842     switch (xo) {
3843     case PPC_63_FRSP: ic->f = instr(frsp); break;
3844     case PPC_63_FCTIWZ: ic->f = instr(fctiwz);break;
3845     case PPC_63_FNEG: ic->f = instr(fneg); break;
3846     case PPC_63_FMR: ic->f = instr(fmr); break;
3847     }
3848     ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rb]);
3849     ic->arg[1] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3850     break;
3851     case PPC_63_MFFS:
3852     ic->f = instr(mffs);
3853     ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rt]);
3854     break;
3855     case PPC_63_MTFSF:
3856     ic->f = instr(mtfsf);
3857     ic->arg[0] = (size_t)(&cpu->cd.ppc.fpr[rb]);
3858     ic->arg[1] = 0;
3859     for (bi=7; bi>=0; bi--) {
3860     ic->arg[1] <<= 8;
3861     if (iword & (1 << (17+bi)))
3862     ic->arg[1] |= 0xf;
3863     }
3864     break;
3865     default:goto bad;
3866     }
3867     }
3868 dpavlin 14 break;
3869    
3870     default:goto bad;
3871     }
3872    
3873    
3874     #define DYNTRANS_TO_BE_TRANSLATED_TAIL
3875     #include "cpu_dyntrans.c"
3876     #undef DYNTRANS_TO_BE_TRANSLATED_TAIL
3877     }
3878    

  ViewVC Help
Powered by ViewVC 1.1.26