/[gxemul]/upstream/0.3.7/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

Contents of /upstream/0.3.7/src/cpus/cpu_ppc_instr.c

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.26