2 * PPC emulation for qemu: main translation routines.
4 * Copyright (c) 2003 Jocelyn Mayer
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #include "dyngen-exec.h"
25 //#define DO_SINGLE_STEP
26 //#define DO_STEP_FLUSH
29 #define DEF(s, n, copy_size) INDEX_op_ ## s,
35 static uint16_t *gen_opc_ptr;
36 static uint32_t *gen_opparam_ptr;
41 static uint8_t spr_access[1024 / 2];
43 /* internal defines */
44 typedef struct DisasContext {
45 struct TranslationBlock *tb;
55 typedef struct opc_handler_t {
59 void (*handler)(DisasContext *ctx);
62 #define SET_RETVAL(n) \
65 ctx->exception = (n); \
70 #define GET_RETVAL(func, __opcode) \
76 #define GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \
77 static void gen_##name (DisasContext *ctx); \
78 GEN_OPCODE(name, opc1, opc2, opc3, inval, type); \
79 static void gen_##name (DisasContext *ctx)
81 /* Instruction types */
83 PPC_INTEGER = 0x0001, /* CPU has integer operations instructions */
84 PPC_FLOAT = 0x0002, /* CPU has floating point operations instructions */
85 PPC_FLOW = 0x0004, /* CPU has flow control instructions */
86 PPC_MEM = 0x0008, /* CPU has virtual memory instructions */
87 PPC_MISC = 0x0010, /* CPU has spr/msr access instructions */
88 PPC_EXTERN = 0x0020, /* CPU has external control instructions */
89 PPC_SEGMENT = 0x0040, /* CPU has memory segment instructions */
92 typedef struct opcode_t {
93 unsigned char opc1, opc2, opc3;
95 opc_handler_t handler;
98 /* XXX: move that elsewhere */
102 /* XXX: shouldn't stay all alone here ! */
103 static int reserve = 0;
105 /*** Instruction decoding ***/
106 #define EXTRACT_HELPER(name, shift, nb) \
107 static inline uint32_t name (uint32_t opcode) \
109 return (opcode >> (shift)) & ((1 << (nb)) - 1); \
112 #define EXTRACT_SHELPER(name, shift, nb) \
113 static inline int32_t name (uint32_t opcode) \
115 return s_ext16((opcode >> (shift)) & ((1 << (nb)) - 1)); \
119 EXTRACT_HELPER(opc1, 26, 6);
121 EXTRACT_HELPER(opc2, 1, 5);
123 EXTRACT_HELPER(opc3, 6, 5);
124 /* Update Cr0 flags */
125 EXTRACT_HELPER(Rc, 0, 1);
127 EXTRACT_HELPER(rD, 21, 5);
129 EXTRACT_HELPER(rS, 21, 5);
131 EXTRACT_HELPER(rA, 16, 5);
133 EXTRACT_HELPER(rB, 11, 5);
135 EXTRACT_HELPER(rC, 6, 5);
137 EXTRACT_HELPER(crfD, 23, 3);
138 EXTRACT_HELPER(crfS, 18, 3);
139 EXTRACT_HELPER(crbD, 21, 5);
140 EXTRACT_HELPER(crbA, 16, 5);
141 EXTRACT_HELPER(crbB, 11, 5);
143 EXTRACT_HELPER(SPR, 11, 10);
144 /*** Get constants ***/
145 EXTRACT_HELPER(IMM, 12, 8);
146 /* 16 bits signed immediate value */
147 EXTRACT_SHELPER(SIMM, 0, 16);
148 /* 16 bits unsigned immediate value */
149 EXTRACT_HELPER(UIMM, 0, 16);
151 EXTRACT_HELPER(NB, 11, 5);
153 EXTRACT_HELPER(SH, 11, 5);
155 EXTRACT_HELPER(MB, 6, 5);
157 EXTRACT_HELPER(ME, 1, 5);
159 EXTRACT_HELPER(CRM, 12, 8);
160 EXTRACT_HELPER(FM, 17, 8);
161 EXTRACT_HELPER(SR, 16, 4);
162 /*** Jump target decoding ***/
164 EXTRACT_SHELPER(d, 0, 16);
165 /* Immediate address */
166 static inline uint32_t LI (uint32_t opcode)
168 return (opcode >> 0) & 0x03FFFFFC;
171 static inline uint32_t BD (uint32_t opcode)
173 return (opcode >> 0) & 0xFFFC;
176 EXTRACT_HELPER(BO, 21, 5);
177 EXTRACT_HELPER(BI, 16, 5);
178 /* Absolute/relative address */
179 EXTRACT_HELPER(AA, 1, 1);
181 EXTRACT_HELPER(LK, 0, 1);
183 /* Create a mask between <start> and <end> bits */
184 static inline uint32_t MASK (uint32_t start, uint32_t end)
188 ret = (((uint32_t)(-1)) >> (start)) ^ (((uint32_t)(-1) >> (end)) >> 1);
195 #define GEN_OPCODE(name, op1, op2, op3, invl, _typ) \
196 __attribute__ ((section(".opcodes"), unused)) \
197 static opcode_t opc_##name = { \
204 .handler = &gen_##name, \
208 #define GEN_OPCODE_MARK(name) \
209 __attribute__ ((section(".opcodes"), unused)) \
210 static opcode_t opc_##name = { \
216 .inval = 0x00000000, \
221 /* Start opcode list */
222 GEN_OPCODE_MARK(start);
224 /* Invalid instruction */
225 GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, 0)
227 /* Branch to next instruction to force nip update */
228 gen_op_b((uint32_t)ctx->nip);
229 SET_RETVAL(EXCP_INVAL);
232 static opc_handler_t invalid_handler = {
234 .handler = gen_invalid,
237 /*** Integer arithmetic ***/
238 #define __GEN_INT_ARITH2(name, opc1, opc2, opc3, inval) \
239 GEN_HANDLER(name, opc1, opc2, opc3, inval, PPC_INTEGER) \
241 gen_op_load_gpr_T0(rA(ctx->opcode)); \
242 gen_op_load_gpr_T1(rB(ctx->opcode)); \
244 if (Rc(ctx->opcode) != 0) \
246 gen_op_store_T0_gpr(rD(ctx->opcode)); \
250 #define __GEN_INT_ARITH2_O(name, opc1, opc2, opc3, inval) \
251 GEN_HANDLER(name, opc1, opc2, opc3, inval, PPC_INTEGER) \
253 gen_op_load_gpr_T0(rA(ctx->opcode)); \
254 gen_op_load_gpr_T1(rB(ctx->opcode)); \
256 if (Rc(ctx->opcode) != 0) \
257 gen_op_set_Rc0_ov(); \
258 gen_op_store_T0_gpr(rD(ctx->opcode)); \
262 #define __GEN_INT_ARITH1(name, opc1, opc2, opc3) \
263 GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, PPC_INTEGER) \
265 gen_op_load_gpr_T0(rA(ctx->opcode)); \
267 if (Rc(ctx->opcode) != 0) \
269 gen_op_store_T0_gpr(rD(ctx->opcode)); \
272 #define __GEN_INT_ARITH1_O(name, opc1, opc2, opc3) \
273 GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, PPC_INTEGER) \
275 gen_op_load_gpr_T0(rA(ctx->opcode)); \
277 if (Rc(ctx->opcode) != 0) \
278 gen_op_set_Rc0_ov(); \
279 gen_op_store_T0_gpr(rD(ctx->opcode)); \
283 /* Two operands arithmetic functions */
284 #define GEN_INT_ARITH2(name, opc1, opc2, opc3) \
285 __GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000000) \
286 __GEN_INT_ARITH2_O(name##o, opc1, opc2, opc3 | 0x10, 0x00000000)
288 /* Two operands arithmetic functions with no overflow allowed */
289 #define GEN_INT_ARITHN(name, opc1, opc2, opc3) \
290 __GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000400)
292 /* One operand arithmetic functions */
293 #define GEN_INT_ARITH1(name, opc1, opc2, opc3) \
294 __GEN_INT_ARITH1(name, opc1, opc2, opc3) \
295 __GEN_INT_ARITH1_O(name##o, opc1, opc2, opc3 | 0x10)
297 /* add add. addo addo. */
298 GEN_INT_ARITH2 (add, 0x1F, 0x0A, 0x08);
299 /* addc addc. addco addco. */
300 GEN_INT_ARITH2 (addc, 0x1F, 0x0A, 0x00);
301 /* adde adde. addeo addeo. */
302 GEN_INT_ARITH2 (adde, 0x1F, 0x0A, 0x04);
303 /* addme addme. addmeo addmeo. */
304 GEN_INT_ARITH1 (addme, 0x1F, 0x0A, 0x07);
305 /* addze addze. addzeo addzeo. */
306 GEN_INT_ARITH1 (addze, 0x1F, 0x0A, 0x06);
307 /* divw divw. divwo divwo. */
308 GEN_INT_ARITH2 (divw, 0x1F, 0x0B, 0x0F);
309 /* divwu divwu. divwuo divwuo. */
310 GEN_INT_ARITH2 (divwu, 0x1F, 0x0B, 0x0E);
312 GEN_INT_ARITHN (mulhw, 0x1F, 0x0B, 0x02);
314 GEN_INT_ARITHN (mulhwu, 0x1F, 0x0B, 0x00);
315 /* mullw mullw. mullwo mullwo. */
316 GEN_INT_ARITH2 (mullw, 0x1F, 0x0B, 0x07);
317 /* neg neg. nego nego. */
318 GEN_INT_ARITH1 (neg, 0x1F, 0x08, 0x03);
319 /* subf subf. subfo subfo. */
320 GEN_INT_ARITH2 (subf, 0x1F, 0x08, 0x01);
321 /* subfc subfc. subfco subfco. */
322 GEN_INT_ARITH2 (subfc, 0x1F, 0x08, 0x00);
323 /* subfe subfe. subfeo subfeo. */
324 GEN_INT_ARITH2 (subfe, 0x1F, 0x08, 0x04);
325 /* subfme subfme. subfmeo subfmeo. */
326 GEN_INT_ARITH1 (subfme, 0x1F, 0x08, 0x07);
327 /* subfze subfze. subfzeo subfzeo. */
328 GEN_INT_ARITH1 (subfze, 0x1F, 0x08, 0x06);
330 GEN_HANDLER(addi, 0x0E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
332 int32_t simm = SIMM(ctx->opcode);
334 if (rA(ctx->opcode) == 0) {
337 gen_op_load_gpr_T0(rA(ctx->opcode));
340 gen_op_store_T0_gpr(rD(ctx->opcode));
344 GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
346 gen_op_load_gpr_T0(rA(ctx->opcode));
347 gen_op_addic(SIMM(ctx->opcode));
348 gen_op_store_T0_gpr(rD(ctx->opcode));
352 GEN_HANDLER(addic_, 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
354 gen_op_load_gpr_T0(rA(ctx->opcode));
355 gen_op_addic(SIMM(ctx->opcode));
357 gen_op_store_T0_gpr(rD(ctx->opcode));
361 GEN_HANDLER(addis, 0x0F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
363 int32_t simm = SIMM(ctx->opcode);
365 if (rA(ctx->opcode) == 0) {
366 gen_op_set_T0(simm << 16);
368 gen_op_load_gpr_T0(rA(ctx->opcode));
369 gen_op_addi(simm << 16);
371 gen_op_store_T0_gpr(rD(ctx->opcode));
375 GEN_HANDLER(mulli, 0x07, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
377 gen_op_load_gpr_T0(rA(ctx->opcode));
378 gen_op_mulli(SIMM(ctx->opcode));
379 gen_op_store_T0_gpr(rD(ctx->opcode));
383 GEN_HANDLER(subfic, 0x08, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
385 gen_op_load_gpr_T0(rA(ctx->opcode));
386 gen_op_subfic(SIMM(ctx->opcode));
387 gen_op_store_T0_gpr(rD(ctx->opcode));
391 /*** Integer comparison ***/
392 #define GEN_CMP(name, opc) \
393 GEN_HANDLER(name, 0x1F, 0x00, opc, 0x00400000, PPC_INTEGER) \
395 gen_op_load_gpr_T0(rA(ctx->opcode)); \
396 gen_op_load_gpr_T1(rB(ctx->opcode)); \
398 gen_op_store_T0_crf(crfD(ctx->opcode)); \
405 GEN_HANDLER(cmpi, 0x0B, 0xFF, 0xFF, 0x00400000, PPC_INTEGER)
407 gen_op_load_gpr_T0(rA(ctx->opcode));
408 gen_op_cmpi(SIMM(ctx->opcode));
409 gen_op_store_T0_crf(crfD(ctx->opcode));
415 GEN_HANDLER(cmpli, 0x0A, 0xFF, 0xFF, 0x00400000, PPC_INTEGER)
417 gen_op_load_gpr_T0(rA(ctx->opcode));
418 gen_op_cmpli(UIMM(ctx->opcode));
419 gen_op_store_T0_crf(crfD(ctx->opcode));
423 /*** Integer logical ***/
424 #define __GEN_LOGICAL2(name, opc2, opc3) \
425 GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000000, PPC_INTEGER) \
427 gen_op_load_gpr_T0(rS(ctx->opcode)); \
428 gen_op_load_gpr_T1(rB(ctx->opcode)); \
430 if (Rc(ctx->opcode) != 0) \
432 gen_op_store_T0_gpr(rA(ctx->opcode)); \
435 #define GEN_LOGICAL2(name, opc) \
436 __GEN_LOGICAL2(name, 0x1C, opc)
438 #define GEN_LOGICAL1(name, opc) \
439 GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, PPC_INTEGER) \
441 gen_op_load_gpr_T0(rS(ctx->opcode)); \
443 if (Rc(ctx->opcode) != 0) \
445 gen_op_store_T0_gpr(rA(ctx->opcode)); \
450 GEN_LOGICAL2(and, 0x00);
452 GEN_LOGICAL2(andc, 0x01);
454 GEN_HANDLER(andi_, 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
456 gen_op_load_gpr_T0(rS(ctx->opcode));
457 gen_op_andi_(UIMM(ctx->opcode));
459 gen_op_store_T0_gpr(rA(ctx->opcode));
463 GEN_HANDLER(andis_, 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
465 gen_op_load_gpr_T0(rS(ctx->opcode));
466 gen_op_andi_(UIMM(ctx->opcode) << 16);
468 gen_op_store_T0_gpr(rA(ctx->opcode));
473 GEN_LOGICAL1(cntlzw, 0x00);
475 GEN_LOGICAL2(eqv, 0x08);
477 GEN_LOGICAL1(extsb, 0x1D);
479 GEN_LOGICAL1(extsh, 0x1C);
481 GEN_LOGICAL2(nand, 0x0E);
483 GEN_LOGICAL2(nor, 0x03);
485 GEN_LOGICAL2(or, 0x0D);
487 GEN_LOGICAL2(orc, 0x0C);
489 GEN_LOGICAL2(xor, 0x09);
491 GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
493 uint32_t uimm = UIMM(ctx->opcode);
497 if (rA(ctx->opcode) != rS(ctx->opcode)) {
498 gen_op_load_gpr_T0(rS(ctx->opcode));
499 gen_op_store_T0_gpr(rA(ctx->opcode));
504 gen_op_load_gpr_T0(rS(ctx->opcode));
506 gen_op_store_T0_gpr(rA(ctx->opcode));
511 GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
513 uint32_t uimm = UIMM(ctx->opcode);
517 if (rA(ctx->opcode) != rS(ctx->opcode)) {
518 gen_op_load_gpr_T0(rS(ctx->opcode));
519 gen_op_store_T0_gpr(rA(ctx->opcode));
524 gen_op_load_gpr_T0(rS(ctx->opcode));
525 gen_op_ori(uimm << 16);
526 gen_op_store_T0_gpr(rA(ctx->opcode));
531 GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
533 gen_op_load_gpr_T0(rS(ctx->opcode));
534 gen_op_xori(UIMM(ctx->opcode));
535 gen_op_store_T0_gpr(rA(ctx->opcode));
540 GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
542 gen_op_load_gpr_T0(rS(ctx->opcode));
543 gen_op_xori(UIMM(ctx->opcode) << 16);
544 gen_op_store_T0_gpr(rA(ctx->opcode));
548 /*** Integer rotate ***/
549 /* rlwimi & rlwimi. */
550 GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
554 mb = MB(ctx->opcode);
555 me = ME(ctx->opcode);
556 gen_op_load_gpr_T0(rS(ctx->opcode));
557 gen_op_rlwimi(SH(ctx->opcode), MASK(mb, me), ~MASK(mb, me));
558 if (Rc(ctx->opcode) != 0)
560 gen_op_store_T0_gpr(rA(ctx->opcode));
563 /* rlwinm & rlwinm. */
564 GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
568 sh = SH(ctx->opcode);
569 mb = MB(ctx->opcode);
570 me = ME(ctx->opcode);
571 gen_op_load_gpr_T0(rS(ctx->opcode));
573 fprintf(logfile, "%s sh=%u mb=%u me=%u MASK=0x%08x\n",
574 __func__, sh, mb, me, MASK(mb, me));
580 } else if (me == (31 - sh)) {
583 } else if (sh == 0) {
584 gen_op_andi_(MASK(0, me));
587 } else if (me == 31) {
588 if (sh == (32 - mb)) {
591 } else if (sh == 0) {
592 gen_op_andi_(MASK(mb, 31));
596 gen_op_rlwinm(sh, MASK(mb, me));
598 if (Rc(ctx->opcode) != 0)
600 gen_op_store_T0_gpr(rA(ctx->opcode));
604 GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
608 mb = MB(ctx->opcode);
609 me = ME(ctx->opcode);
610 gen_op_load_gpr_T0(rS(ctx->opcode));
611 gen_op_load_gpr_T1(rB(ctx->opcode));
612 if (mb == 0 && me == 31) {
616 gen_op_rlwnm(MASK(mb, me));
618 if (Rc(ctx->opcode) != 0)
620 gen_op_store_T0_gpr(rA(ctx->opcode));
624 /*** Integer shift ***/
626 __GEN_LOGICAL2(slw, 0x18, 0x00);
628 __GEN_LOGICAL2(sraw, 0x18, 0x18);
630 GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER)
632 gen_op_load_gpr_T0(rS(ctx->opcode));
633 gen_op_srawi(SH(ctx->opcode), MASK(32 - SH(ctx->opcode), 31));
634 if (Rc(ctx->opcode) != 0)
636 gen_op_store_T0_gpr(rA(ctx->opcode));
640 __GEN_LOGICAL2(srw, 0x18, 0x10);
642 /*** Floating-Point arithmetic ***/
644 GEN_HANDLER(fadd, 0x3F, 0x15, 0xFF, 0x000007C0, PPC_FLOAT)
646 SET_RETVAL(EXCP_INVAL);
650 GEN_HANDLER(fadds, 0x3B, 0x15, 0xFF, 0x000007C0, PPC_FLOAT)
652 SET_RETVAL(EXCP_INVAL);
656 GEN_HANDLER(fdiv, 0x3F, 0x12, 0xFF, 0x000007C0, PPC_FLOAT)
658 SET_RETVAL(EXCP_INVAL);
662 GEN_HANDLER(fdivs, 0x3B, 0x12, 0xFF, 0x000007C0, PPC_FLOAT)
664 SET_RETVAL(EXCP_INVAL);
668 GEN_HANDLER(fmul, 0x3F, 0x19, 0xFF, 0x0000F800, PPC_FLOAT)
670 SET_RETVAL(EXCP_INVAL);
674 GEN_HANDLER(fmuls, 0x3B, 0x19, 0xFF, 0x0000F800, PPC_FLOAT)
676 SET_RETVAL(EXCP_INVAL);
680 GEN_HANDLER(fres, 0x3B, 0x18, 0xFF, 0x001807C0, PPC_FLOAT)
682 SET_RETVAL(EXCP_INVAL);
686 GEN_HANDLER(frsqrte, 0x3F, 0x1A, 0xFF, 0x001807C0, PPC_FLOAT)
688 SET_RETVAL(EXCP_INVAL);
692 GEN_HANDLER(fsel, 0x3F, 0x17, 0xFF, 0x00000000, PPC_FLOAT)
694 SET_RETVAL(EXCP_INVAL);
698 GEN_HANDLER(fsub, 0x3F, 0x14, 0xFF, 0x000007C0, PPC_FLOAT)
700 SET_RETVAL(EXCP_INVAL);
704 GEN_HANDLER(fsubs, 0x3B, 0x14, 0xFF, 0x000007C0, PPC_FLOAT)
706 SET_RETVAL(EXCP_INVAL);
711 GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001807C0, PPC_FLOAT)
713 SET_RETVAL(EXCP_INVAL);
717 GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001807C0, PPC_FLOAT)
719 SET_RETVAL(EXCP_INVAL);
722 /*** Floating-Point multiply-and-add ***/
724 GEN_HANDLER(fmadd, 0x3F, 0x1D, 0xFF, 0x00000000, PPC_FLOAT)
726 SET_RETVAL(EXCP_INVAL);
730 GEN_HANDLER(fmadds, 0x3B, 0x1D, 0xFF, 0x00000000, PPC_FLOAT)
732 SET_RETVAL(EXCP_INVAL);
736 GEN_HANDLER(fmsub, 0x3F, 0x1C, 0xFF, 0x00000000, PPC_FLOAT)
738 SET_RETVAL(EXCP_INVAL);
742 GEN_HANDLER(fmsubs, 0x3B, 0x1C, 0xFF, 0x00000000, PPC_FLOAT)
744 SET_RETVAL(EXCP_INVAL);
748 GEN_HANDLER(fnmadd, 0x3F, 0x1F, 0xFF, 0x00000000, PPC_FLOAT)
750 SET_RETVAL(EXCP_INVAL);
754 GEN_HANDLER(fnmadds, 0x3B, 0x1F, 0xFF, 0x00000000, PPC_FLOAT)
756 SET_RETVAL(EXCP_INVAL);
760 GEN_HANDLER(fnmsub, 0x3F, 0x1E, 0xFF, 0x00000000, PPC_FLOAT)
762 SET_RETVAL(EXCP_INVAL);
766 GEN_HANDLER(fnmsubs, 0x3B, 0x1E, 0xFF, 0x00000000, PPC_FLOAT)
768 SET_RETVAL(EXCP_INVAL);
771 /*** Floating-Point round & convert ***/
773 GEN_HANDLER(fctiw, 0x3F, 0x0E, 0xFF, 0x001F0000, PPC_FLOAT)
775 SET_RETVAL(EXCP_INVAL);
779 GEN_HANDLER(fctiwz, 0x3F, 0x0F, 0xFF, 0x001F0000, PPC_FLOAT)
781 SET_RETVAL(EXCP_INVAL);
785 GEN_HANDLER(frsp, 0x3F, 0x0C, 0xFF, 0x001F0000, PPC_FLOAT)
787 SET_RETVAL(EXCP_INVAL);
790 /*** Floating-Point compare ***/
792 GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT)
794 SET_RETVAL(EXCP_INVAL);
798 GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT)
800 SET_RETVAL(EXCP_INVAL);
803 /*** Floating-Point status & ctrl register ***/
805 GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT)
807 SET_RETVAL(EXCP_INVAL);
811 GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT)
813 gen_op_load_fpscr(rD(ctx->opcode));
814 if (Rc(ctx->opcode)) {
821 GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT)
823 SET_RETVAL(EXCP_INVAL);
827 GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT)
829 SET_RETVAL(EXCP_INVAL);
833 GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT)
835 gen_op_store_fpscr(FM(ctx->opcode), rB(ctx->opcode));
836 if (Rc(ctx->opcode)) {
843 GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT)
845 SET_RETVAL(EXCP_INVAL);
848 /*** Integer load ***/
849 #define GEN_ILDZ(width, opc) \
850 GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) \
852 uint32_t simm = SIMM(ctx->opcode); \
853 if (rA(ctx->opcode) == 0) { \
854 gen_op_l##width##_z(simm); \
856 gen_op_load_gpr_T0(rA(ctx->opcode)); \
857 gen_op_l##width (simm); \
859 gen_op_store_T1_gpr(rD(ctx->opcode)); \
863 #define GEN_ILDZU(width, opc) \
864 GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) \
866 if (rA(ctx->opcode) == 0 || \
867 rA(ctx->opcode) == rD(ctx->opcode)) \
868 SET_RETVAL(EXCP_INVAL); \
869 gen_op_load_gpr_T0(rA(ctx->opcode)); \
870 gen_op_l##width(SIMM(ctx->opcode)); \
871 gen_op_store_T1_gpr(rD(ctx->opcode)); \
872 gen_op_store_T0_gpr(rA(ctx->opcode)); \
876 #define GEN_ILDZUX(width, opc) \
877 GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_INTEGER) \
879 if (rA(ctx->opcode) == 0 || \
880 rA(ctx->opcode) == rD(ctx->opcode)) \
881 SET_RETVAL(EXCP_INVAL); \
882 gen_op_load_gpr_T0(rA(ctx->opcode)); \
883 gen_op_load_gpr_T1(rB(ctx->opcode)); \
884 gen_op_l##width##x(); \
885 gen_op_store_T1_gpr(rD(ctx->opcode)); \
886 gen_op_store_T0_gpr(rA(ctx->opcode)); \
890 #define GEN_ILDZX(width, opc2, opc3) \
891 GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_INTEGER) \
893 if (rA(ctx->opcode) == 0) { \
894 gen_op_load_gpr_T0(rB(ctx->opcode)); \
895 gen_op_l##width##x_z(); \
897 gen_op_load_gpr_T0(rA(ctx->opcode)); \
898 gen_op_load_gpr_T1(rB(ctx->opcode)); \
899 gen_op_l##width##x(); \
901 gen_op_store_T1_gpr(rD(ctx->opcode)); \
905 #define GEN_ILD(width, op) \
906 GEN_ILDZ(width, op | 0x20) \
907 GEN_ILDZU(width, op | 0x21) \
908 GEN_ILDZUX(width, op | 0x01) \
909 GEN_ILDZX(width, 0x17, op | 0x00)
911 /* lbz lbzu lbzux lbzx */
913 /* lha lhau lhaux lhax */
915 /* lhz lhzu lhzux lhzx */
917 /* lwz lwzu lwzux lwzx */
920 /*** Integer store ***/
921 #define GEN_IST(width, opc) \
922 GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) \
924 uint32_t simm = SIMM(ctx->opcode); \
925 if (rA(ctx->opcode) == 0) { \
926 gen_op_load_gpr_T0(rS(ctx->opcode)); \
927 gen_op_st##width##_z(simm); \
929 gen_op_load_gpr_T0(rA(ctx->opcode)); \
930 gen_op_load_gpr_T1(rS(ctx->opcode)); \
931 gen_op_st##width(simm); \
936 #define GEN_ISTU(width, opc) \
937 GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) \
939 if (rA(ctx->opcode) == 0) \
940 SET_RETVAL(EXCP_INVAL); \
941 gen_op_load_gpr_T0(rA(ctx->opcode)); \
942 gen_op_load_gpr_T1(rS(ctx->opcode)); \
943 gen_op_st##width(SIMM(ctx->opcode)); \
944 gen_op_store_T0_gpr(rA(ctx->opcode)); \
948 #define GEN_ISTUX(width, opc) \
949 GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_INTEGER) \
951 if (rA(ctx->opcode) == 0) \
952 SET_RETVAL(EXCP_INVAL); \
953 gen_op_load_gpr_T0(rA(ctx->opcode)); \
954 gen_op_load_gpr_T1(rB(ctx->opcode)); \
955 gen_op_load_gpr_T2(rS(ctx->opcode)); \
956 gen_op_st##width##x(); \
957 gen_op_store_T0_gpr(rA(ctx->opcode)); \
961 #define GEN_ISTX(width, opc2, opc3) \
962 GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_INTEGER) \
964 if (rA(ctx->opcode) == 0) { \
965 gen_op_load_gpr_T0(rB(ctx->opcode)); \
966 gen_op_load_gpr_T1(rS(ctx->opcode)); \
967 gen_op_st##width##x_z(); \
969 gen_op_load_gpr_T0(rA(ctx->opcode)); \
970 gen_op_load_gpr_T1(rB(ctx->opcode)); \
971 gen_op_load_gpr_T2(rS(ctx->opcode)); \
972 gen_op_st##width##x(); \
977 #define GEN_ISTO(width, opc) \
978 GEN_IST(width, opc | 0x20) \
979 GEN_ISTU(width, opc | 0x21) \
980 GEN_ISTUX(width, opc | 0x01) \
981 GEN_ISTX(width, 0x17, opc | 0x00)
983 /* stb stbu stbux stbx */
985 /* sth sthu sthux sthx */
987 /* stw stwu stwux stwx */
990 /*** Integer load and store with byte reverse ***/
992 GEN_ILDZX(hbr, 0x16, 0x18);
994 GEN_ILDZX(wbr, 0x16, 0x10);
996 GEN_ISTX(hbr, 0x16, 0x1C);
998 GEN_ISTX(wbr, 0x16, 0x14);
1000 /*** Integer load and store multiple ***/
1002 GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1004 if (rA(ctx->opcode) == 0) {
1007 gen_op_load_gpr_T0(rA(ctx->opcode));
1009 gen_op_lmw(rD(ctx->opcode), SIMM(ctx->opcode));
1014 GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1016 if (rA(ctx->opcode) == 0) {
1019 gen_op_load_gpr_T0(rA(ctx->opcode));
1021 gen_op_stmw(rS(ctx->opcode), SIMM(ctx->opcode));
1025 /*** Integer load and store strings ***/
1027 GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_INTEGER)
1029 int nb = NB(ctx->opcode);
1030 int start = rD(ctx->opcode);
1036 if ((start + nr) > 32) {
1037 /* handle wrap around r0 */
1038 if (rA(ctx->opcode) == 0) {
1041 gen_op_load_gpr_T0(rA(ctx->opcode));
1043 gen_op_lswi(start, 4 * (32 - start));
1044 nb -= 4 * (32 - start);
1047 if (rA(ctx->opcode) == 0) {
1050 gen_op_load_gpr_T0(rA(ctx->opcode));
1052 gen_op_lswi(start, nb);
1057 GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_INTEGER)
1059 gen_op_load_xer_bc();
1060 gen_op_load_gpr_T1(rB(ctx->opcode));
1061 if (rA(ctx->opcode) == 0) {
1064 gen_op_load_gpr_T2(rA(ctx->opcode));
1066 gen_op_lswx(rD(ctx->opcode));
1071 GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_INTEGER)
1073 int nb = NB(ctx->opcode);
1074 int start = rS(ctx->opcode);
1080 if ((start + nr) > 32) {
1081 /* handle wrap around r0 */
1082 if (rA(ctx->opcode) == 0) {
1085 gen_op_load_gpr_T0(rA(ctx->opcode));
1087 gen_op_stswi(start, 4 * (32 - start));
1088 nb -= 4 * (32 - start);
1091 if (rA(ctx->opcode) == 0) {
1094 gen_op_load_gpr_T0(rA(ctx->opcode));
1096 gen_op_stswi(start, nb);
1101 GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_INTEGER)
1103 gen_op_load_xer_bc();
1104 gen_op_load_gpr_T1(rB(ctx->opcode));
1105 if (rA(ctx->opcode) == 0) {
1108 gen_op_load_gpr_T2(rA(ctx->opcode));
1110 gen_op_stswx(rS(ctx->opcode));
1114 /*** Memory synchronisation ***/
1116 GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FF0801, PPC_MEM)
1118 /* Do a branch to next instruction */
1119 gen_op_b((uint32_t)ctx->nip);
1120 SET_RETVAL(EXCP_BRANCH);
1124 GEN_HANDLER(isync, 0x13, 0x16, 0xFF, 0x03FF0801, PPC_MEM)
1126 /* Do a branch to next instruction */
1127 gen_op_b((uint32_t)ctx->nip);
1128 SET_RETVAL(EXCP_BRANCH);
1132 GEN_HANDLER(lwarx, 0x1F, 0x14, 0xFF, 0x00000001, PPC_MEM)
1135 if (rA(ctx->opcode) == 0) {
1136 gen_op_load_gpr_T0(rB(ctx->opcode));
1138 gen_op_set_reservation();
1140 gen_op_load_gpr_T0(rA(ctx->opcode));
1141 gen_op_load_gpr_T1(rB(ctx->opcode));
1143 gen_op_set_reservation();
1145 gen_op_store_T1_gpr(rD(ctx->opcode));
1150 GEN_HANDLER(stwcx_, 0x1F, 0x16, 0x04, 0x00000000, PPC_MEM)
1155 if (rA(ctx->opcode) == 0) {
1156 gen_op_load_gpr_T0(rB(ctx->opcode));
1157 gen_op_load_gpr_T1(rS(ctx->opcode));
1160 gen_op_load_gpr_T0(rA(ctx->opcode));
1161 gen_op_load_gpr_T1(rB(ctx->opcode));
1162 gen_op_load_gpr_T2(rS(ctx->opcode));
1166 gen_op_reset_reservation();
1172 GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x03FF0801, PPC_MEM)
1174 /* Do a branch to next instruction */
1175 gen_op_b((uint32_t)ctx->nip);
1176 SET_RETVAL(EXCP_BRANCH);
1179 /*** Floating-point load ***/
1180 #define GEN_LF(width, opc) \
1181 GEN_HANDLER(lf##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
1183 uint32_t simm = SIMM(ctx->opcode); \
1184 if (rA(ctx->opcode) == 0) { \
1185 gen_op_lf##width##_z(simm, rD(ctx->opcode)); \
1187 gen_op_load_gpr_T0(rA(ctx->opcode)); \
1188 gen_op_lf##width(simm, rD(ctx->opcode)); \
1193 #define GEN_LFU(width, opc) \
1194 GEN_HANDLER(lf##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
1196 if (rA(ctx->opcode) == 0 || \
1197 rA(ctx->opcode) == rD(ctx->opcode)) \
1198 SET_RETVAL(EXCP_INVAL); \
1199 gen_op_load_gpr_T0(rA(ctx->opcode)); \
1200 gen_op_lf##width(SIMM(ctx->opcode), rD(ctx->opcode)); \
1201 gen_op_store_T0_gpr(rA(ctx->opcode)); \
1205 #define GEN_LFUX(width, opc) \
1206 GEN_HANDLER(lf##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \
1208 if (rA(ctx->opcode) == 0 || \
1209 rA(ctx->opcode) == rD(ctx->opcode)) \
1210 SET_RETVAL(EXCP_INVAL); \
1211 gen_op_load_gpr_T0(rA(ctx->opcode)); \
1212 gen_op_load_gpr_T1(rB(ctx->opcode)); \
1213 gen_op_lf##width##x(rD(ctx->opcode)); \
1214 gen_op_store_T0_gpr(rA(ctx->opcode)); \
1218 #define GEN_LFX(width, opc) \
1219 GEN_HANDLER(lf##width##x, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \
1221 if (rA(ctx->opcode) == 0) { \
1222 gen_op_load_gpr_T0(rB(ctx->opcode)); \
1223 gen_op_lf##width##x_z(rD(ctx->opcode)); \
1225 gen_op_load_gpr_T0(rA(ctx->opcode)); \
1226 gen_op_load_gpr_T1(rB(ctx->opcode)); \
1227 gen_op_lf##width##x(rD(ctx->opcode)); \
1232 #define GEN_LDF(width, opc) \
1233 GEN_LF(width, opc | 0x20) \
1234 GEN_LFU(width, opc | 0x21) \
1235 GEN_LFUX(width, opc | 0x01) \
1236 GEN_LFX(width, opc | 0x00)
1238 /* lfd lfdu lfdux lfdx */
1240 /* lfs lfsu lfsux lfsx */
1241 #define gen_op_lfs_z(a, b)
1242 #define gen_op_lfs(a, b)
1243 #define gen_op_lfsx_z(a)
1244 #define gen_op_lfsx(a)
1247 /*** Floating-point store ***/
1248 #define GEN_STF(width, opc) \
1249 GEN_HANDLER(stf##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
1251 uint32_t simm = SIMM(ctx->opcode); \
1252 if (rA(ctx->opcode) == 0) { \
1253 gen_op_stf##width##_z(simm, rS(ctx->opcode)); \
1255 gen_op_load_gpr_T0(rA(ctx->opcode)); \
1256 gen_op_stf##width(simm, rS(ctx->opcode)); \
1261 #define GEN_STFU(width, opc) \
1262 GEN_HANDLER(stf##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
1264 if (rA(ctx->opcode) == 0) \
1265 SET_RETVAL(EXCP_INVAL); \
1266 gen_op_load_gpr_T0(rA(ctx->opcode)); \
1267 gen_op_stf##width(SIMM(ctx->opcode), rS(ctx->opcode)); \
1268 gen_op_store_T0_gpr(rA(ctx->opcode)); \
1272 #define GEN_STFUX(width, opc) \
1273 GEN_HANDLER(stf##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \
1275 if (rA(ctx->opcode) == 0) \
1276 SET_RETVAL(EXCP_INVAL); \
1277 gen_op_load_gpr_T0(rA(ctx->opcode)); \
1278 gen_op_load_gpr_T1(rB(ctx->opcode)); \
1279 gen_op_stf##width##x(rS(ctx->opcode)); \
1280 gen_op_store_T0_gpr(rA(ctx->opcode)); \
1284 #define GEN_STFX(width, opc) \
1285 GEN_HANDLER(stf##width##x, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \
1287 if (rA(ctx->opcode) == 0) { \
1288 gen_op_load_gpr_T0(rB(ctx->opcode)); \
1289 gen_op_stf##width##x_z(rS(ctx->opcode)); \
1291 gen_op_load_gpr_T0(rA(ctx->opcode)); \
1292 gen_op_load_gpr_T1(rB(ctx->opcode)); \
1293 gen_op_stf##width##x(rS(ctx->opcode)); \
1298 #define GEN_STOF(width, opc) \
1299 GEN_STF(width, opc | 0x20) \
1300 GEN_STFU(width, opc | 0x21) \
1301 GEN_STFUX(width, opc | 0x01) \
1302 GEN_STFX(width, opc | 0x00)
1304 /* stfd stfdu stfdux stfdx */
1306 /* stfs stfsu stfsux stfsx */
1307 #define gen_op_stfs_z(a, b)
1308 #define gen_op_stfs(a, b)
1309 #define gen_op_stfsx_z(a)
1310 #define gen_op_stfsx(a)
1315 GEN_HANDLER(stfiwx, 0x1F, 0x17, 0x1E, 0x00000001, PPC_FLOAT)
1317 SET_RETVAL(EXCP_INVAL);
1320 /*** Floating-point move ***/
1322 GEN_HANDLER(fabs, 0x3F, 0x08, 0x08, 0x001F0000, PPC_FLOAT)
1324 SET_RETVAL(EXCP_INVAL);
1328 GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT)
1330 SET_RETVAL(EXCP_INVAL);
1334 GEN_HANDLER(fnabs, 0x3F, 0x08, 0x04, 0x001F0000, PPC_FLOAT)
1336 SET_RETVAL(EXCP_INVAL);
1340 GEN_HANDLER(fneg, 0x3F, 0x08, 0x01, 0x001F0000, PPC_FLOAT)
1342 SET_RETVAL(EXCP_INVAL);
1346 #define GEN_BCOND(name, opc1, opc2, opc3, prologue, \
1347 bl_ctr, b_ctr, bl_ctrz, b_ctrz, b, \
1348 bl_ctr_true, b_ctr_true, bl_ctrz_true, b_ctrz_true, bl_true, b_true, \
1349 bl_ctr_false, b_ctr_false, bl_ctrz_false, b_ctrz_false, bl_false, b_false) \
1350 GEN_HANDLER(name, opc1, opc2, opc3, 0x00000000, PPC_FLOW) \
1352 __attribute__ ((unused)) uint32_t target; \
1353 uint32_t bo = BO(ctx->opcode); \
1354 uint32_t bi = BI(ctx->opcode); \
1357 if ((bo & 0x4) == 0) \
1360 /* No CR condition */ \
1361 switch (bo & 0x6) { \
1363 if (LK(ctx->opcode)) { \
1370 if (LK(ctx->opcode)) { \
1379 if (LK(ctx->opcode)) \
1380 gen_op_load_lr((uint32_t)ctx->nip); \
1383 printf("ERROR: %s: unhandled ba case (%d)\n", __func__, bo); \
1384 SET_RETVAL(EXCP_INVAL); \
1388 mask = 1 << (3 - (bi & 0x03)); \
1389 gen_op_load_crf_T0(bi >> 2); \
1391 switch (bo & 0x6) { \
1393 if (LK(ctx->opcode)) { \
1400 if (LK(ctx->opcode)) { \
1408 if (LK(ctx->opcode)) { \
1415 printf("ERROR: %s: unhandled b case (%d)\n", __func__, bo); \
1416 SET_RETVAL(EXCP_INVAL); \
1420 switch (bo & 0x6) { \
1422 if (LK(ctx->opcode)) { \
1429 if (LK(ctx->opcode)) { \
1437 if (LK(ctx->opcode)) { \
1444 printf("ERROR: %s: unhandled bn case (%d)\n", __func__, bo); \
1445 SET_RETVAL(EXCP_INVAL); \
1450 SET_RETVAL(EXCP_BRANCH); \
1454 GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
1456 uint32_t li = s_ext24(LI(ctx->opcode)), target;
1458 if (AA(ctx->opcode) == 0)
1459 target = (uint32_t)ctx->nip + li - 4;
1461 target = s_ext24(LI(ctx->opcode));
1463 if (LK(ctx->opcode))
1464 gen_op_load_lr((uint32_t)ctx->nip);
1465 SET_RETVAL(EXCP_BRANCH);
1468 /* bc bca bcl bcla */
1469 GEN_BCOND(bc, 0x10, 0xFF, 0xFF,
1471 uint32_t li = s_ext16(BD(ctx->opcode));
1472 if (AA(ctx->opcode) == 0) {
1473 target = (uint32_t)ctx->nip + li - 4;
1478 gen_op_bl_ctr((uint32_t)ctx->nip, target),
1479 gen_op_b_ctr((uint32_t)ctx->nip, target),
1480 gen_op_bl_ctrz((uint32_t)ctx->nip, target),
1481 gen_op_b_ctrz((uint32_t)ctx->nip, target),
1483 gen_op_bl_ctr_true((uint32_t)ctx->nip, target, mask),
1484 gen_op_b_ctr_true((uint32_t)ctx->nip, target, mask),
1485 gen_op_bl_ctrz_true((uint32_t)ctx->nip, target, mask),
1486 gen_op_b_ctrz_true((uint32_t)ctx->nip, target, mask),
1487 gen_op_bl_true((uint32_t)ctx->nip, target, mask),
1488 gen_op_b_true((uint32_t)ctx->nip, target, mask),
1489 gen_op_bl_ctr_false((uint32_t)ctx->nip, target, mask),
1490 gen_op_b_ctr_false((uint32_t)ctx->nip, target, mask),
1491 gen_op_bl_ctrz_false((uint32_t)ctx->nip, target, mask),
1492 gen_op_b_ctrz_false((uint32_t)ctx->nip, target, mask),
1493 gen_op_bl_false((uint32_t)ctx->nip, target, mask),
1494 gen_op_b_false((uint32_t)ctx->nip, target, mask));
1497 GEN_BCOND(bcctr, 0x13, 0x10, 0x10, do { } while (0),
1498 gen_op_bctrl_ctr((uint32_t)ctx->nip),
1499 gen_op_bctr_ctr((uint32_t)ctx->nip),
1500 gen_op_bctrl_ctrz((uint32_t)ctx->nip),
1501 gen_op_bctr_ctrz((uint32_t)ctx->nip),
1503 gen_op_bctrl_ctr_true((uint32_t)ctx->nip, mask),
1504 gen_op_bctr_ctr_true((uint32_t)ctx->nip, mask),
1505 gen_op_bctrl_ctrz_true((uint32_t)ctx->nip, mask),
1506 gen_op_bctr_ctrz_true((uint32_t)ctx->nip, mask),
1507 gen_op_bctrl_true((uint32_t)ctx->nip, mask),
1508 gen_op_bctr_true((uint32_t)ctx->nip, mask),
1509 gen_op_bctrl_ctr_false((uint32_t)ctx->nip, mask),
1510 gen_op_bctr_ctr_false((uint32_t)ctx->nip, mask),
1511 gen_op_bctrl_ctrz_false((uint32_t)ctx->nip, mask),
1512 gen_op_bctr_ctrz_false((uint32_t)ctx->nip, mask),
1513 gen_op_bctrl_false((uint32_t)ctx->nip, mask),
1514 gen_op_bctr_false((uint32_t)ctx->nip, mask))
1517 GEN_BCOND(bclr, 0x13, 0x10, 0x00, do { } while (0),
1518 gen_op_blrl_ctr((uint32_t)ctx->nip),
1519 gen_op_blr_ctr((uint32_t)ctx->nip),
1520 gen_op_blrl_ctrz((uint32_t)ctx->nip),
1521 gen_op_blr_ctrz((uint32_t)ctx->nip),
1523 gen_op_blrl_ctr_true((uint32_t)ctx->nip, mask),
1524 gen_op_blr_ctr_true((uint32_t)ctx->nip, mask),
1525 gen_op_blrl_ctrz_true((uint32_t)ctx->nip, mask),
1526 gen_op_blr_ctrz_true((uint32_t)ctx->nip, mask),
1527 gen_op_blrl_true((uint32_t)ctx->nip, mask),
1528 gen_op_blr_true((uint32_t)ctx->nip, mask),
1529 gen_op_blrl_ctr_false((uint32_t)ctx->nip, mask),
1530 gen_op_blr_ctr_false((uint32_t)ctx->nip, mask),
1531 gen_op_blrl_ctrz_false((uint32_t)ctx->nip, mask),
1532 gen_op_blr_ctrz_false((uint32_t)ctx->nip, mask),
1533 gen_op_blrl_false((uint32_t)ctx->nip, mask),
1534 gen_op_blr_false((uint32_t)ctx->nip, mask))
1536 /*** Condition register logical ***/
1537 #define GEN_CRLOGIC(op, opc) \
1538 GEN_HANDLER(cr##op, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER) \
1540 gen_op_load_crf_T0(crbA(ctx->opcode) >> 2); \
1541 gen_op_getbit_T0(3 - (crbA(ctx->opcode) & 0x03)); \
1542 gen_op_load_crf_T1(crbB(ctx->opcode) >> 2); \
1543 gen_op_getbit_T1(3 - (crbB(ctx->opcode) & 0x03)); \
1545 gen_op_load_crf_T1(crbD(ctx->opcode) >> 2); \
1546 gen_op_setcrfbit(~(1 << (3 - (crbD(ctx->opcode) & 0x03))), \
1547 3 - (crbD(ctx->opcode) & 0x03)); \
1548 gen_op_store_T1_crf(crbD(ctx->opcode) >> 2); \
1553 GEN_CRLOGIC(and, 0x08)
1555 GEN_CRLOGIC(andc, 0x04)
1557 GEN_CRLOGIC(eqv, 0x09)
1559 GEN_CRLOGIC(nand, 0x07)
1561 GEN_CRLOGIC(nor, 0x01)
1563 GEN_CRLOGIC(or, 0x0E)
1565 GEN_CRLOGIC(orc, 0x0D)
1567 GEN_CRLOGIC(xor, 0x06)
1569 GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER)
1571 gen_op_load_crf_T0(crfS(ctx->opcode));
1572 gen_op_store_T0_crf(crfD(ctx->opcode));
1576 /*** System linkage ***/
1577 /* rfi (supervisor only) */
1578 GEN_HANDLER(rfi, 0x13, 0x12, 0xFF, 0x03FF8001, PPC_FLOW)
1580 SET_RETVAL(EXCP_INVAL);
1584 GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFFFFD, PPC_FLOW)
1586 gen_op_b((uint32_t)ctx->nip);
1587 SET_RETVAL(EXCP_SYSCALL);
1592 GEN_HANDLER(tw, 0x1F, 0x04, 0xFF, 0x00000001, PPC_FLOW)
1594 SET_RETVAL(EXCP_INVAL);
1598 GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
1600 SET_RETVAL(EXCP_INVAL);
1603 /*** Processor control ***/
1604 static inline int check_spr_access (int spr, int rw, int supervisor)
1606 uint32_t rights = spr_access[spr >> 1] >> (4 * (spr & 1));
1608 rights = rights >> (2 * supervisor);
1609 rights = rights >> rw;
1615 GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC)
1617 gen_op_load_xer_cr();
1618 gen_op_store_T0_crf(crfD(ctx->opcode));
1619 gen_op_clear_xer_cr();
1624 GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x001FF801, PPC_MISC)
1627 gen_op_store_T0_gpr(rD(ctx->opcode));
1632 GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC)
1634 if (!ctx->supervisor)
1635 SET_RETVAL(EXCP_PRIV);
1637 gen_op_store_T0_gpr(rD(ctx->opcode));
1642 GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC)
1644 uint32_t sprn = SPR(ctx->opcode);
1646 if (check_spr_access(sprn, 0, ctx->supervisor) == 0)
1647 SET_RETVAL(EXCP_PRIV);
1648 /* XXX: make this more generic */
1652 fprintf(logfile, "LOAD XER at %p\n", ctx->nip - 1);
1656 case SPR_ENCODE(268):
1657 /* We need to update the time base before reading it */
1658 gen_op_update_tb(ctx->tb_offset);
1661 case SPR_ENCODE(269):
1662 gen_op_update_tb(ctx->tb_offset);
1666 gen_op_load_spr(sprn);
1669 gen_op_store_T0_gpr(rD(ctx->opcode)); //
1674 GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MISC)
1676 uint32_t sprn = SPR(ctx->opcode);
1678 if (check_spr_access(sprn, 0, ctx->supervisor) == 0)
1679 SET_RETVAL(EXCP_PRIV);
1681 case SPR_ENCODE(268):
1682 /* We need to update the time base before reading it */
1683 gen_op_update_tb(ctx->tb_offset);
1686 case SPR_ENCODE(269):
1687 gen_op_update_tb(ctx->tb_offset);
1691 SET_RETVAL(EXCP_INVAL);
1698 GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00100801, PPC_MISC)
1700 gen_op_load_gpr_T0(rS(ctx->opcode));
1701 gen_op_store_cr(CRM(ctx->opcode));
1706 GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC)
1708 if (!ctx->supervisor)
1709 SET_RETVAL(EXCP_PRIV);
1710 gen_op_load_gpr_T0(rS(ctx->opcode));
1712 /* Must stop the translation as machine state (may have) changed */
1713 SET_RETVAL(EXCP_MTMSR);
1717 GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC)
1719 uint32_t sprn = SPR(ctx->opcode);
1721 if (check_spr_access(sprn, 1, ctx->supervisor) == 0)
1722 SET_RETVAL(EXCP_PRIV);
1723 gen_op_load_gpr_T0(rS(ctx->opcode));
1724 if (sprn == SPR_ENCODE(1)) {
1727 gen_op_store_spr(sprn);
1732 /*** Cache management ***/
1733 /* For now, all those will be implemented as nop:
1734 * this is valid, regarding the PowerPC specs...
1737 GEN_HANDLER(dcbf, 0x1F, 0x16, 0x17, 0x03E00001, PPC_MEM)
1742 /* dcbi (Supervisor only) */
1743 GEN_HANDLER(dcbi, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_MEM)
1749 GEN_HANDLER(dcbst, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_MEM)
1755 GEN_HANDLER(dcbt, 0x1F, 0x16, 0x01, 0x03E00001, PPC_MEM)
1761 GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x02, 0x03E00001, PPC_MEM)
1767 GEN_HANDLER(dcbz, 0x1F, 0x16, 0x08, 0x03E00001, PPC_MEM)
1773 GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_MEM)
1780 GEN_HANDLER(dcba, 0x1F, 0x16, 0x07, 0x03E00001, PPC_MEM)
1785 /*** Segment register manipulation ***/
1786 /* Supervisor only: */
1788 GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT)
1790 SET_RETVAL(EXCP_INVAL);
1794 GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x0010F001, PPC_SEGMENT)
1796 SET_RETVAL(EXCP_INVAL);
1800 GEN_HANDLER(mtsr, 0x1F, 0x12, 0x02, 0x0010F801, PPC_SEGMENT)
1802 SET_RETVAL(EXCP_INVAL);
1806 GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x0010F001, PPC_SEGMENT)
1808 SET_RETVAL(EXCP_INVAL);
1811 /*** Lookaside buffer management ***/
1812 /* Optional & supervisor only: */
1814 GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM)
1816 SET_RETVAL(EXCP_INVAL);
1820 GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF8001, PPC_MEM)
1822 SET_RETVAL(EXCP_INVAL);
1826 GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFFC01, PPC_MEM)
1828 SET_RETVAL(EXCP_INVAL);
1831 /*** External control ***/
1834 GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN)
1836 SET_RETVAL(EXCP_INVAL);
1840 GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN)
1842 SET_RETVAL(EXCP_INVAL);
1845 /* End opcode list */
1846 GEN_OPCODE_MARK(end);
1848 /*****************************************************************************/
1851 extern FILE *stderr;
1852 void free (void *p);
1853 int fflush (FILE *f);
1855 /* Main ppc opcodes table:
1856 * at init, all opcodes are invalids
1858 static opc_handler_t *ppc_opcodes[0x40];
1862 PPC_DIRECT = 0, /* Opcode routine */
1863 PPC_INDIRECT = 1, /* Indirect opcode table */
1866 static inline int is_indirect_opcode (void *handler)
1868 return ((unsigned long)handler & 0x03) == PPC_INDIRECT;
1871 static inline opc_handler_t **ind_table(void *handler)
1873 return (opc_handler_t **)((unsigned long)handler & ~3);
1876 /* Opcodes tables creation */
1877 static void fill_new_table (opc_handler_t **table, int len)
1881 for (i = 0; i < len; i++)
1882 table[i] = &invalid_handler;
1885 static int create_new_table (opc_handler_t **table, unsigned char idx)
1887 opc_handler_t **tmp;
1889 tmp = malloc(0x20 * sizeof(opc_handler_t));
1892 fill_new_table(tmp, 0x20);
1893 table[idx] = (opc_handler_t *)((unsigned long)tmp | PPC_INDIRECT);
1898 static int insert_in_table (opc_handler_t **table, unsigned char idx,
1899 opc_handler_t *handler)
1901 if (table[idx] != &invalid_handler)
1903 table[idx] = handler;
1908 static int register_direct_insn (unsigned char idx, opc_handler_t *handler)
1910 if (insert_in_table(ppc_opcodes, idx, handler) < 0) {
1911 fprintf(stderr, "*** ERROR: opcode %02x already assigned in main "
1912 "opcode table\n", idx);
1919 static int register_ind_in_table (opc_handler_t **table,
1920 unsigned char idx1, unsigned char idx2,
1921 opc_handler_t *handler)
1923 if (table[idx1] == &invalid_handler) {
1924 if (create_new_table(table, idx1) < 0) {
1925 fprintf(stderr, "*** ERROR: unable to create indirect table "
1926 "idx=%02x\n", idx1);
1930 if (!is_indirect_opcode(table[idx1])) {
1931 fprintf(stderr, "*** ERROR: idx %02x already assigned to a direct "
1936 if (handler != NULL &&
1937 insert_in_table(ind_table(table[idx1]), idx2, handler) < 0) {
1938 fprintf(stderr, "*** ERROR: opcode %02x already assigned in "
1939 "opcode table %02x\n", idx2, idx1);
1946 static int register_ind_insn (unsigned char idx1, unsigned char idx2,
1947 opc_handler_t *handler)
1951 ret = register_ind_in_table(ppc_opcodes, idx1, idx2, handler);
1956 static int register_dblind_insn (unsigned char idx1, unsigned char idx2,
1957 unsigned char idx3, opc_handler_t *handler)
1959 if (register_ind_in_table(ppc_opcodes, idx1, idx2, NULL) < 0) {
1960 fprintf(stderr, "*** ERROR: unable to join indirect table idx "
1961 "[%02x-%02x]\n", idx1, idx2);
1964 if (register_ind_in_table(ind_table(ppc_opcodes[idx1]), idx2, idx3,
1966 fprintf(stderr, "*** ERROR: unable to insert opcode "
1967 "[%02x-%02x-%02x]\n", idx1, idx2, idx3);
1974 static int register_insn (opcode_t *insn)
1976 if (insn->opc2 != 0xFF) {
1977 if (insn->opc3 != 0xFF) {
1978 if (register_dblind_insn(insn->opc1, insn->opc2, insn->opc3,
1979 &insn->handler) < 0)
1982 if (register_ind_insn(insn->opc1, insn->opc2, &insn->handler) < 0)
1986 if (register_direct_insn(insn->opc1, &insn->handler) < 0)
1993 static int test_opcode_table (opc_handler_t **table, int len)
1997 for (i = 0, count = 0; i < len; i++) {
1998 /* Consistency fixup */
1999 if (table[i] == NULL)
2000 table[i] = &invalid_handler;
2001 if (table[i] != &invalid_handler) {
2002 if (is_indirect_opcode(table[i])) {
2003 tmp = test_opcode_table(ind_table(table[i]), 0x20);
2006 table[i] = &invalid_handler;
2019 static void fix_opcode_tables (void)
2021 if (test_opcode_table(ppc_opcodes, 0x40) == 0)
2022 fprintf(stderr, "*** WARNING: no opcode defined !\n");
2025 #define SPR_RIGHTS(rw, priv) ((2 * (priv)) + (rw))
2026 #define SPR_UR SPR_RIGHTS(0, 0)
2027 #define SPR_UW SPR_RIGHTS(1, 0)
2028 #define SPR_SR SPR_RIGHTS(0, 1)
2029 #define SPR_SW SPR_RIGHTS(1, 1)
2031 #define spr_set_rights(spr, rights) \
2033 spr_access[(spr) >> 1] |= ((rights) << (4 * ((spr) & 1))); \
2036 static void init_spr_rights (void)
2039 spr_set_rights(SPR_ENCODE(1), SPR_UR | SPR_UW | SPR_SR | SPR_SW);
2041 spr_set_rights(SPR_ENCODE(8), SPR_UR | SPR_UW | SPR_SR | SPR_SW);
2043 spr_set_rights(SPR_ENCODE(9), SPR_UR | SPR_UW | SPR_SR | SPR_SW);
2045 spr_set_rights(SPR_ENCODE(268), SPR_UR | SPR_SR);
2047 spr_set_rights(SPR_ENCODE(269), SPR_UR | SPR_SR);
2048 /* DSISR (SPR 18) */
2049 spr_set_rights(SPR_ENCODE(18), SPR_SR | SPR_SW);
2051 spr_set_rights(SPR_ENCODE(19), SPR_SR | SPR_SW);
2053 spr_set_rights(SPR_ENCODE(22), SPR_SR | SPR_SW);
2055 spr_set_rights(SPR_ENCODE(25), SPR_SR | SPR_SW);
2056 /* SPRG0 (SPR 272) */
2057 spr_set_rights(SPR_ENCODE(272), SPR_SR | SPR_SW);
2058 /* SPRG1 (SPR 273) */
2059 spr_set_rights(SPR_ENCODE(273), SPR_SR | SPR_SW);
2060 /* SPRG2 (SPR 274) */
2061 spr_set_rights(SPR_ENCODE(274), SPR_SR | SPR_SW);
2062 /* SPRG3 (SPR 275) */
2063 spr_set_rights(SPR_ENCODE(275), SPR_SR | SPR_SW);
2065 spr_set_rights(SPR_ENCODE(281), SPR_SR | SPR_SW);
2067 spr_set_rights(SPR_ENCODE(282), SPR_SR | SPR_SW);
2068 /* IBAT0U (SPR 528) */
2069 spr_set_rights(SPR_ENCODE(528), SPR_SR | SPR_SW);
2070 /* IBAT0L (SPR 529) */
2071 spr_set_rights(SPR_ENCODE(529), SPR_SR | SPR_SW);
2072 /* IBAT1U (SPR 530) */
2073 spr_set_rights(SPR_ENCODE(530), SPR_SR | SPR_SW);
2074 /* IBAT1L (SPR 531) */
2075 spr_set_rights(SPR_ENCODE(531), SPR_SR | SPR_SW);
2076 /* IBAT2U (SPR 532) */
2077 spr_set_rights(SPR_ENCODE(532), SPR_SR | SPR_SW);
2078 /* IBAT2L (SPR 533) */
2079 spr_set_rights(SPR_ENCODE(533), SPR_SR | SPR_SW);
2080 /* IBAT3U (SPR 534) */
2081 spr_set_rights(SPR_ENCODE(534), SPR_SR | SPR_SW);
2082 /* IBAT3L (SPR 535) */
2083 spr_set_rights(SPR_ENCODE(535), SPR_SR | SPR_SW);
2084 /* DBAT0U (SPR 536) */
2085 spr_set_rights(SPR_ENCODE(536), SPR_SR | SPR_SW);
2086 /* DBAT0L (SPR 537) */
2087 spr_set_rights(SPR_ENCODE(537), SPR_SR | SPR_SW);
2088 /* DBAT1U (SPR 538) */
2089 spr_set_rights(SPR_ENCODE(538), SPR_SR | SPR_SW);
2090 /* DBAT1L (SPR 539) */
2091 spr_set_rights(SPR_ENCODE(539), SPR_SR | SPR_SW);
2092 /* DBAT2U (SPR 540) */
2093 spr_set_rights(SPR_ENCODE(540), SPR_SR | SPR_SW);
2094 /* DBAT2L (SPR 541) */
2095 spr_set_rights(SPR_ENCODE(541), SPR_SR | SPR_SW);
2096 /* DBAT3U (SPR 542) */
2097 spr_set_rights(SPR_ENCODE(542), SPR_SR | SPR_SW);
2098 /* DBAT3L (SPR 543) */
2099 spr_set_rights(SPR_ENCODE(543), SPR_SR | SPR_SW);
2100 /* DABR (SPR 1013) */
2101 spr_set_rights(SPR_ENCODE(1013), SPR_SR | SPR_SW);
2102 /* FPECR (SPR 1022) */
2103 spr_set_rights(SPR_ENCODE(1022), SPR_SR | SPR_SW);
2104 /* PIR (SPR 1023) */
2105 spr_set_rights(SPR_ENCODE(1023), SPR_SR | SPR_SW);
2107 spr_set_rights(SPR_ENCODE(287), SPR_SR);
2109 spr_set_rights(SPR_ENCODE(284), SPR_SW);
2111 spr_set_rights(SPR_ENCODE(285), SPR_SW);
2114 /* PPC "main stream" common instructions */
2115 #define PPC_COMMON (PPC_INTEGER | PPC_FLOAT | PPC_FLOW | PPC_MEM | \
2116 PPC_MISC | PPC_EXTERN | PPC_SEGMENT)
2118 typedef struct ppc_proc_t {
2123 typedef struct ppc_def_t {
2125 unsigned long pvr_mask;
2129 static ppc_proc_t ppc_proc_common = {
2130 .flags = PPC_COMMON,
2134 static ppc_def_t ppc_defs[] =
2139 .pvr_mask = 0x00000000,
2140 .proc = &ppc_proc_common,
2144 static int create_ppc_proc (unsigned long pvr)
2149 fill_new_table(ppc_opcodes, 0x40);
2150 for (i = 0; ; i++) {
2151 if ((ppc_defs[i].pvr & ppc_defs[i].pvr_mask) ==
2152 (pvr & ppc_defs[i].pvr_mask)) {
2153 flags = ppc_defs[i].proc->flags;
2158 for (opc = &opc_start + 1; opc != &opc_end; opc++) {
2159 if ((opc->type & flags) != 0)
2160 if (register_insn(opc) < 0) {
2161 fprintf(stderr, "*** ERROR initializing PPC instruction "
2162 "0x%02x 0x%02x 0x%02x\n", opc->opc1, opc->opc2,
2167 fix_opcode_tables();
2172 /*****************************************************************************/
2173 uint32_t do_load_xer (void);
2175 void cpu_ppc_dump_state(CPUPPCState *env, FILE *f, int flags)
2180 fprintf(logfile, "nip=0x%08x LR=0x%08x CTR=0x%08x XER=0x%08x\n",
2181 env->nip, env->LR, env->CTR, do_load_xer());
2182 for (i = 0; i < 32; i++) {
2184 fprintf(logfile, "GPR%02d:", i);
2185 fprintf(logfile, " %08x", env->gpr[i]);
2187 fprintf(logfile, "\n");
2189 fprintf(logfile, "CR: 0x");
2190 for (i = 0; i < 8; i++)
2191 fprintf(logfile, "%01x", env->crf[i]);
2192 fprintf(logfile, " [");
2193 for (i = 0; i < 8; i++) {
2196 if (env->crf[i] & 0x08)
2198 else if (env->crf[i] & 0x04)
2200 else if (env->crf[i] & 0x02)
2202 fprintf(logfile, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
2204 fprintf(logfile, " ] ");
2205 fprintf(logfile, "TB: 0x%08x %08x\n", env->spr[SPR_ENCODE(269)],
2206 env->spr[SPR_ENCODE(268)]);
2207 for (i = 0; i < 16; i++) {
2209 fprintf(logfile, "FPR%02d:", i);
2210 fprintf(logfile, " %016llx", env->fpr[i]);
2212 fprintf(logfile, "\n");
2218 CPUPPCState *cpu_ppc_init(void)
2224 env = malloc(sizeof(CPUPPCState));
2227 memset(env, 0, sizeof(CPUPPCState));
2229 if (create_ppc_proc(0) < 0)
2236 void cpu_ppc_close(CPUPPCState *env)
2238 /* Should also remove all opcode tables... */
2242 int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
2246 opc_handler_t **table, *handler;
2248 uint16_t *gen_opc_end;
2253 gen_opc_ptr = gen_opc_buf;
2254 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
2255 gen_opparam_ptr = gen_opparam_buf;
2256 ctx.nip = (uint32_t *)pc_start;
2258 ctx.supervisor = msr_ip;
2262 while (ret == 0 && gen_opc_ptr < gen_opc_end) {
2265 fprintf(logfile, "Search PC...\n");
2266 j = gen_opc_ptr - gen_opc_buf;
2270 gen_opc_instr_start[lj++] = 0;
2271 gen_opc_pc[lj] = (uint32_t)ctx.nip;
2272 gen_opc_instr_start[lj] = 1;
2275 ctx.opcode = __be32_to_cpu(*ctx.nip);
2278 fprintf(logfile, "----------------\n");
2279 fprintf(logfile, "%p: translate opcode %08x\n",
2280 ctx.nip, ctx.opcode);
2284 table = ppc_opcodes;
2285 handler = table[opc1(ctx.opcode)];
2286 if (is_indirect_opcode(handler)) {
2287 table = ind_table(handler);
2288 handler = table[opc2(ctx.opcode)];
2289 if (is_indirect_opcode(handler)) {
2290 table = ind_table(handler);
2291 handler = table[opc3(ctx.opcode)];
2294 /* Is opcode *REALLY* valid ? */
2295 if ((ctx.opcode & handler->inval) != 0) {
2297 if (handler->handler == &gen_invalid) {
2298 fprintf(logfile, "invalid/unsupported opcode: "
2299 "%02x -%02x - %02x (%08x)\n", opc1(ctx.opcode),
2300 opc2(ctx.opcode), opc3(ctx.opcode), ctx.opcode);
2302 fprintf(logfile, "invalid bits: %08x for opcode: "
2303 "%02x -%02x - %02x (%p)\n",
2304 ctx.opcode & handler->inval, opc1(ctx.opcode),
2305 opc2(ctx.opcode), opc3(ctx.opcode),
2309 ret = GET_RETVAL(gen_invalid, ctx.opcode);
2311 ret = GET_RETVAL(*(handler->handler), ctx.opcode);
2314 #if defined (DO_SINGLE_STEP)
2318 #if defined (DO_STEP_FLUSH)
2321 /* We need to update the time base */
2323 gen_op_update_tb(ctx.tb_offset);
2324 /* If we are in step-by-step mode, do a branch to the next instruction
2325 * so the nip will be up-to-date
2327 #if defined (DO_SINGLE_STEP)
2329 gen_op_b((uint32_t)ctx.nip);
2333 /* If the exeption isn't a PPC one,
2336 if (ret != EXCP_BRANCH) {
2338 if ((ret & 0x2000) == 0)
2339 gen_op_raise_exception(ret);
2341 /* TO BE FIXED: T0 hasn't got a proper value, which makes tb_add_jump
2342 * do bad business and then qemu crashes !
2345 /* Generate the return instruction */
2347 *gen_opc_ptr = INDEX_op_end;
2349 tb->size = (uint32_t)ctx.nip - pc_start;
2352 // *gen_opc_ptr = INDEX_op_end;
2355 fprintf(logfile, "IN: %s\n", lookup_symbol((void *)pc_start));
2356 disas(logfile, (void *)pc_start, (uint32_t)ctx.nip - pc_start, 0, 0);
2357 fprintf(logfile, "\n");
2359 fprintf(logfile, "OP:\n");
2360 dump_ops(gen_opc_buf, gen_opparam_buf);
2361 fprintf(logfile, "\n");
2368 int gen_intermediate_code(CPUState *env, struct TranslationBlock *tb)
2370 return gen_intermediate_code_internal(env, tb, 0);
2373 int gen_intermediate_code_pc(CPUState *env, struct TranslationBlock *tb)
2375 return gen_intermediate_code_internal(env, tb, 1);