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