/[gxemul]/trunk/src/cpus/cpu_ppc_instr.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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


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

  ViewVC Help
Powered by ViewVC 1.1.26