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;
40 typedef void (GenOpFunc)(void);
41 typedef void (GenOpFunc1)(long);
42 typedef void (GenOpFunc2)(long, long);
43 typedef void (GenOpFunc3)(long, long, long);
45 #define GEN8(func, NAME) \
46 static GenOpFunc *NAME ## _table [8] = {\
47 NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,\
48 NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,\
50 static inline void func(int n)\
55 #define GEN32(func, NAME) \
56 static GenOpFunc *NAME ## _table [32] = {\
57 NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,\
58 NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,\
59 NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11,\
60 NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,\
61 NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,\
62 NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,\
63 NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,\
64 NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,\
66 static inline void func(int n)\
71 GEN8(gen_op_load_crf_T0, gen_op_load_crf_T0_crf)
72 GEN8(gen_op_load_crf_T1, gen_op_load_crf_T1_crf)
73 GEN8(gen_op_store_T0_crf, gen_op_store_T0_crf_crf)
74 GEN8(gen_op_store_T1_crf, gen_op_store_T1_crf_crf)
76 /* Floating point condition and status register moves */
77 GEN8(gen_op_load_fpscr_T0, gen_op_load_fpscr_T0_fpscr);
78 GEN8(gen_op_store_T0_fpscr, gen_op_store_T0_fpscr_fpscr);
79 GEN8(gen_op_clear_fpscr, gen_op_clear_fpscr_fpscr);
80 static GenOpFunc1 *gen_op_store_T0_fpscri_fpscr_table[8] = {
81 &gen_op_store_T0_fpscri_fpscr0,
82 &gen_op_store_T0_fpscri_fpscr1,
83 &gen_op_store_T0_fpscri_fpscr2,
84 &gen_op_store_T0_fpscri_fpscr3,
85 &gen_op_store_T0_fpscri_fpscr4,
86 &gen_op_store_T0_fpscri_fpscr5,
87 &gen_op_store_T0_fpscri_fpscr6,
88 &gen_op_store_T0_fpscri_fpscr7,
90 static inline void gen_op_store_T0_fpscri(int n, uint8_t param)
92 (*gen_op_store_T0_fpscri_fpscr_table[n])(param);
95 GEN32(gen_op_load_gpr_T0, gen_op_load_gpr_T0_gpr)
96 GEN32(gen_op_load_gpr_T1, gen_op_load_gpr_T1_gpr)
97 GEN32(gen_op_load_gpr_T2, gen_op_load_gpr_T2_gpr)
99 GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr)
100 GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr)
101 GEN32(gen_op_store_T2_gpr, gen_op_store_T2_gpr_gpr)
103 /* floating point registers moves */
104 GEN32(gen_op_load_fpr_FT0, gen_op_load_fpr_FT0_fpr);
105 GEN32(gen_op_load_fpr_FT1, gen_op_load_fpr_FT1_fpr);
106 GEN32(gen_op_load_fpr_FT2, gen_op_load_fpr_FT2_fpr);
107 GEN32(gen_op_store_FT0_fpr, gen_op_store_FT0_fpr_fpr);
108 GEN32(gen_op_store_FT1_fpr, gen_op_store_FT1_fpr_fpr);
109 GEN32(gen_op_store_FT2_fpr, gen_op_store_FT2_fpr_fpr);
111 static uint8_t spr_access[1024 / 2];
113 /* internal defines */
114 typedef struct DisasContext {
115 struct TranslationBlock *tb;
125 typedef struct opc_handler_t {
129 void (*handler)(DisasContext *ctx);
132 #define SET_RETVAL(n) \
135 ctx->exception = (n); \
140 #define GET_RETVAL(func, __opcode) \
146 #define GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \
147 static void gen_##name (DisasContext *ctx); \
148 GEN_OPCODE(name, opc1, opc2, opc3, inval, type); \
149 static void gen_##name (DisasContext *ctx)
151 /* Instruction types */
153 PPC_INTEGER = 0x0001, /* CPU has integer operations instructions */
154 PPC_FLOAT = 0x0002, /* CPU has floating point operations instructions */
155 PPC_FLOW = 0x0004, /* CPU has flow control instructions */
156 PPC_MEM = 0x0008, /* CPU has virtual memory instructions */
157 PPC_MISC = 0x0010, /* CPU has spr/msr access instructions */
158 PPC_EXTERN = 0x0020, /* CPU has external control instructions */
159 PPC_SEGMENT = 0x0040, /* CPU has memory segment instructions */
162 typedef struct opcode_t {
163 unsigned char opc1, opc2, opc3;
165 opc_handler_t handler;
168 /* XXX: move that elsewhere */
169 extern FILE *logfile;
172 /* XXX: shouldn't stay all alone here ! */
173 static int reserve = 0;
175 /*** Instruction decoding ***/
176 #define EXTRACT_HELPER(name, shift, nb) \
177 static inline uint32_t name (uint32_t opcode) \
179 return (opcode >> (shift)) & ((1 << (nb)) - 1); \
182 #define EXTRACT_SHELPER(name, shift, nb) \
183 static inline int32_t name (uint32_t opcode) \
185 return s_ext16((opcode >> (shift)) & ((1 << (nb)) - 1)); \
189 EXTRACT_HELPER(opc1, 26, 6);
191 EXTRACT_HELPER(opc2, 1, 5);
193 EXTRACT_HELPER(opc3, 6, 5);
194 /* Update Cr0 flags */
195 EXTRACT_HELPER(Rc, 0, 1);
197 EXTRACT_HELPER(rD, 21, 5);
199 EXTRACT_HELPER(rS, 21, 5);
201 EXTRACT_HELPER(rA, 16, 5);
203 EXTRACT_HELPER(rB, 11, 5);
205 EXTRACT_HELPER(rC, 6, 5);
207 EXTRACT_HELPER(crfD, 23, 3);
208 EXTRACT_HELPER(crfS, 18, 3);
209 EXTRACT_HELPER(crbD, 21, 5);
210 EXTRACT_HELPER(crbA, 16, 5);
211 EXTRACT_HELPER(crbB, 11, 5);
213 EXTRACT_HELPER(SPR, 11, 10);
214 /*** Get constants ***/
215 EXTRACT_HELPER(IMM, 12, 8);
216 /* 16 bits signed immediate value */
217 EXTRACT_SHELPER(SIMM, 0, 16);
218 /* 16 bits unsigned immediate value */
219 EXTRACT_HELPER(UIMM, 0, 16);
221 EXTRACT_HELPER(NB, 11, 5);
223 EXTRACT_HELPER(SH, 11, 5);
225 EXTRACT_HELPER(MB, 6, 5);
227 EXTRACT_HELPER(ME, 1, 5);
229 EXTRACT_HELPER(TO, 21, 5);
231 EXTRACT_HELPER(CRM, 12, 8);
232 EXTRACT_HELPER(FM, 17, 8);
233 EXTRACT_HELPER(SR, 16, 4);
234 EXTRACT_HELPER(FPIMM, 20, 4);
236 /*** Jump target decoding ***/
238 EXTRACT_SHELPER(d, 0, 16);
239 /* Immediate address */
240 static inline uint32_t LI (uint32_t opcode)
242 return (opcode >> 0) & 0x03FFFFFC;
245 static inline uint32_t BD (uint32_t opcode)
247 return (opcode >> 0) & 0xFFFC;
250 EXTRACT_HELPER(BO, 21, 5);
251 EXTRACT_HELPER(BI, 16, 5);
252 /* Absolute/relative address */
253 EXTRACT_HELPER(AA, 1, 1);
255 EXTRACT_HELPER(LK, 0, 1);
257 /* Create a mask between <start> and <end> bits */
258 static inline uint32_t MASK (uint32_t start, uint32_t end)
262 ret = (((uint32_t)(-1)) >> (start)) ^ (((uint32_t)(-1) >> (end)) >> 1);
269 #define GEN_OPCODE(name, op1, op2, op3, invl, _typ) \
270 __attribute__ ((section(".opcodes"), unused)) \
271 static opcode_t opc_##name = { \
278 .handler = &gen_##name, \
282 #define GEN_OPCODE_MARK(name) \
283 __attribute__ ((section(".opcodes"), unused)) \
284 static opcode_t opc_##name = { \
290 .inval = 0x00000000, \
295 /* Start opcode list */
296 GEN_OPCODE_MARK(start);
298 /* Invalid instruction */
299 GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, 0)
301 /* Branch to next instruction to force nip update */
302 gen_op_b((uint32_t)ctx->nip);
303 SET_RETVAL(EXCP_INVAL);
306 static opc_handler_t invalid_handler = {
308 .handler = gen_invalid,
311 /*** Integer arithmetic ***/
312 #define __GEN_INT_ARITH2(name, opc1, opc2, opc3, inval) \
313 GEN_HANDLER(name, opc1, opc2, opc3, inval, PPC_INTEGER) \
315 gen_op_load_gpr_T0(rA(ctx->opcode)); \
316 gen_op_load_gpr_T1(rB(ctx->opcode)); \
318 if (Rc(ctx->opcode) != 0) \
320 gen_op_store_T0_gpr(rD(ctx->opcode)); \
324 #define __GEN_INT_ARITH2_O(name, opc1, opc2, opc3, inval) \
325 GEN_HANDLER(name, opc1, opc2, opc3, inval, PPC_INTEGER) \
327 gen_op_load_gpr_T0(rA(ctx->opcode)); \
328 gen_op_load_gpr_T1(rB(ctx->opcode)); \
330 if (Rc(ctx->opcode) != 0) \
331 gen_op_set_Rc0_ov(); \
332 gen_op_store_T0_gpr(rD(ctx->opcode)); \
336 #define __GEN_INT_ARITH1(name, opc1, opc2, opc3) \
337 GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, PPC_INTEGER) \
339 gen_op_load_gpr_T0(rA(ctx->opcode)); \
341 if (Rc(ctx->opcode) != 0) \
343 gen_op_store_T0_gpr(rD(ctx->opcode)); \
346 #define __GEN_INT_ARITH1_O(name, opc1, opc2, opc3) \
347 GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, PPC_INTEGER) \
349 gen_op_load_gpr_T0(rA(ctx->opcode)); \
351 if (Rc(ctx->opcode) != 0) \
352 gen_op_set_Rc0_ov(); \
353 gen_op_store_T0_gpr(rD(ctx->opcode)); \
357 /* Two operands arithmetic functions */
358 #define GEN_INT_ARITH2(name, opc1, opc2, opc3) \
359 __GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000000) \
360 __GEN_INT_ARITH2_O(name##o, opc1, opc2, opc3 | 0x10, 0x00000000)
362 /* Two operands arithmetic functions with no overflow allowed */
363 #define GEN_INT_ARITHN(name, opc1, opc2, opc3) \
364 __GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000400)
366 /* One operand arithmetic functions */
367 #define GEN_INT_ARITH1(name, opc1, opc2, opc3) \
368 __GEN_INT_ARITH1(name, opc1, opc2, opc3) \
369 __GEN_INT_ARITH1_O(name##o, opc1, opc2, opc3 | 0x10)
371 /* add add. addo addo. */
372 GEN_INT_ARITH2 (add, 0x1F, 0x0A, 0x08);
373 /* addc addc. addco addco. */
374 GEN_INT_ARITH2 (addc, 0x1F, 0x0A, 0x00);
375 /* adde adde. addeo addeo. */
376 GEN_INT_ARITH2 (adde, 0x1F, 0x0A, 0x04);
377 /* addme addme. addmeo addmeo. */
378 GEN_INT_ARITH1 (addme, 0x1F, 0x0A, 0x07);
379 /* addze addze. addzeo addzeo. */
380 GEN_INT_ARITH1 (addze, 0x1F, 0x0A, 0x06);
381 /* divw divw. divwo divwo. */
382 GEN_INT_ARITH2 (divw, 0x1F, 0x0B, 0x0F);
383 /* divwu divwu. divwuo divwuo. */
384 GEN_INT_ARITH2 (divwu, 0x1F, 0x0B, 0x0E);
386 GEN_INT_ARITHN (mulhw, 0x1F, 0x0B, 0x02);
388 GEN_INT_ARITHN (mulhwu, 0x1F, 0x0B, 0x00);
389 /* mullw mullw. mullwo mullwo. */
390 GEN_INT_ARITH2 (mullw, 0x1F, 0x0B, 0x07);
391 /* neg neg. nego nego. */
392 GEN_INT_ARITH1 (neg, 0x1F, 0x08, 0x03);
393 /* subf subf. subfo subfo. */
394 GEN_INT_ARITH2 (subf, 0x1F, 0x08, 0x01);
395 /* subfc subfc. subfco subfco. */
396 GEN_INT_ARITH2 (subfc, 0x1F, 0x08, 0x00);
397 /* subfe subfe. subfeo subfeo. */
398 GEN_INT_ARITH2 (subfe, 0x1F, 0x08, 0x04);
399 /* subfme subfme. subfmeo subfmeo. */
400 GEN_INT_ARITH1 (subfme, 0x1F, 0x08, 0x07);
401 /* subfze subfze. subfzeo subfzeo. */
402 GEN_INT_ARITH1 (subfze, 0x1F, 0x08, 0x06);
404 GEN_HANDLER(addi, 0x0E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
406 int32_t simm = SIMM(ctx->opcode);
408 if (rA(ctx->opcode) == 0) {
411 gen_op_load_gpr_T0(rA(ctx->opcode));
414 gen_op_store_T0_gpr(rD(ctx->opcode));
418 GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
420 gen_op_load_gpr_T0(rA(ctx->opcode));
421 gen_op_addic(SIMM(ctx->opcode));
422 gen_op_store_T0_gpr(rD(ctx->opcode));
426 GEN_HANDLER(addic_, 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
428 gen_op_load_gpr_T0(rA(ctx->opcode));
429 gen_op_addic(SIMM(ctx->opcode));
431 gen_op_store_T0_gpr(rD(ctx->opcode));
435 GEN_HANDLER(addis, 0x0F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
437 int32_t simm = SIMM(ctx->opcode);
439 if (rA(ctx->opcode) == 0) {
440 gen_op_set_T0(simm << 16);
442 gen_op_load_gpr_T0(rA(ctx->opcode));
443 gen_op_addi(simm << 16);
445 gen_op_store_T0_gpr(rD(ctx->opcode));
449 GEN_HANDLER(mulli, 0x07, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
451 gen_op_load_gpr_T0(rA(ctx->opcode));
452 gen_op_mulli(SIMM(ctx->opcode));
453 gen_op_store_T0_gpr(rD(ctx->opcode));
457 GEN_HANDLER(subfic, 0x08, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
459 gen_op_load_gpr_T0(rA(ctx->opcode));
460 gen_op_subfic(SIMM(ctx->opcode));
461 gen_op_store_T0_gpr(rD(ctx->opcode));
465 /*** Integer comparison ***/
466 #define GEN_CMP(name, opc) \
467 GEN_HANDLER(name, 0x1F, 0x00, opc, 0x00400000, PPC_INTEGER) \
469 gen_op_load_gpr_T0(rA(ctx->opcode)); \
470 gen_op_load_gpr_T1(rB(ctx->opcode)); \
472 gen_op_store_T0_crf(crfD(ctx->opcode)); \
479 GEN_HANDLER(cmpi, 0x0B, 0xFF, 0xFF, 0x00400000, PPC_INTEGER)
481 gen_op_load_gpr_T0(rA(ctx->opcode));
482 gen_op_cmpi(SIMM(ctx->opcode));
483 gen_op_store_T0_crf(crfD(ctx->opcode));
489 GEN_HANDLER(cmpli, 0x0A, 0xFF, 0xFF, 0x00400000, PPC_INTEGER)
491 gen_op_load_gpr_T0(rA(ctx->opcode));
492 gen_op_cmpli(UIMM(ctx->opcode));
493 gen_op_store_T0_crf(crfD(ctx->opcode));
497 /*** Integer logical ***/
498 #define __GEN_LOGICAL2(name, opc2, opc3) \
499 GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000000, PPC_INTEGER) \
501 gen_op_load_gpr_T0(rS(ctx->opcode)); \
502 gen_op_load_gpr_T1(rB(ctx->opcode)); \
504 if (Rc(ctx->opcode) != 0) \
506 gen_op_store_T0_gpr(rA(ctx->opcode)); \
509 #define GEN_LOGICAL2(name, opc) \
510 __GEN_LOGICAL2(name, 0x1C, opc)
512 #define GEN_LOGICAL1(name, opc) \
513 GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, PPC_INTEGER) \
515 gen_op_load_gpr_T0(rS(ctx->opcode)); \
517 if (Rc(ctx->opcode) != 0) \
519 gen_op_store_T0_gpr(rA(ctx->opcode)); \
524 GEN_LOGICAL2(and, 0x00);
526 GEN_LOGICAL2(andc, 0x01);
528 GEN_HANDLER(andi_, 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
530 gen_op_load_gpr_T0(rS(ctx->opcode));
531 gen_op_andi_(UIMM(ctx->opcode));
533 gen_op_store_T0_gpr(rA(ctx->opcode));
537 GEN_HANDLER(andis_, 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
539 gen_op_load_gpr_T0(rS(ctx->opcode));
540 gen_op_andi_(UIMM(ctx->opcode) << 16);
542 gen_op_store_T0_gpr(rA(ctx->opcode));
547 GEN_LOGICAL1(cntlzw, 0x00);
549 GEN_LOGICAL2(eqv, 0x08);
551 GEN_LOGICAL1(extsb, 0x1D);
553 GEN_LOGICAL1(extsh, 0x1C);
555 GEN_LOGICAL2(nand, 0x0E);
557 GEN_LOGICAL2(nor, 0x03);
559 GEN_LOGICAL2(or, 0x0D);
561 GEN_LOGICAL2(orc, 0x0C);
563 GEN_LOGICAL2(xor, 0x09);
565 GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
567 uint32_t uimm = UIMM(ctx->opcode);
571 if (rA(ctx->opcode) != rS(ctx->opcode)) {
572 gen_op_load_gpr_T0(rS(ctx->opcode));
573 gen_op_store_T0_gpr(rA(ctx->opcode));
578 gen_op_load_gpr_T0(rS(ctx->opcode));
580 gen_op_store_T0_gpr(rA(ctx->opcode));
585 GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
587 uint32_t uimm = UIMM(ctx->opcode);
591 if (rA(ctx->opcode) != rS(ctx->opcode)) {
592 gen_op_load_gpr_T0(rS(ctx->opcode));
593 gen_op_store_T0_gpr(rA(ctx->opcode));
598 gen_op_load_gpr_T0(rS(ctx->opcode));
599 gen_op_ori(uimm << 16);
600 gen_op_store_T0_gpr(rA(ctx->opcode));
605 GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
607 gen_op_load_gpr_T0(rS(ctx->opcode));
608 gen_op_xori(UIMM(ctx->opcode));
609 gen_op_store_T0_gpr(rA(ctx->opcode));
614 GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
616 gen_op_load_gpr_T0(rS(ctx->opcode));
617 gen_op_xori(UIMM(ctx->opcode) << 16);
618 gen_op_store_T0_gpr(rA(ctx->opcode));
622 /*** Integer rotate ***/
623 /* rlwimi & rlwimi. */
624 GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
628 mb = MB(ctx->opcode);
629 me = ME(ctx->opcode);
630 gen_op_load_gpr_T0(rS(ctx->opcode));
631 gen_op_load_gpr_T1(rA(ctx->opcode));
632 gen_op_rlwimi(SH(ctx->opcode), MASK(mb, me), ~MASK(mb, me));
633 if (Rc(ctx->opcode) != 0)
635 gen_op_store_T0_gpr(rA(ctx->opcode));
638 /* rlwinm & rlwinm. */
639 GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
643 sh = SH(ctx->opcode);
644 mb = MB(ctx->opcode);
645 me = ME(ctx->opcode);
646 gen_op_load_gpr_T0(rS(ctx->opcode));
648 fprintf(logfile, "%s sh=%u mb=%u me=%u MASK=0x%08x\n",
649 __func__, sh, mb, me, MASK(mb, me));
655 } else if (me == (31 - sh)) {
658 } else if (sh == 0) {
659 gen_op_andi_(MASK(0, me));
662 } else if (me == 31) {
663 if (sh == (32 - mb)) {
666 } else if (sh == 0) {
667 gen_op_andi_(MASK(mb, 31));
671 gen_op_rlwinm(sh, MASK(mb, me));
673 if (Rc(ctx->opcode) != 0)
675 gen_op_store_T0_gpr(rA(ctx->opcode));
679 GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
683 mb = MB(ctx->opcode);
684 me = ME(ctx->opcode);
685 gen_op_load_gpr_T0(rS(ctx->opcode));
686 gen_op_load_gpr_T1(rB(ctx->opcode));
687 if (mb == 0 && me == 31) {
691 gen_op_rlwnm(MASK(mb, me));
693 if (Rc(ctx->opcode) != 0)
695 gen_op_store_T0_gpr(rA(ctx->opcode));
699 /*** Integer shift ***/
701 __GEN_LOGICAL2(slw, 0x18, 0x00);
703 __GEN_LOGICAL2(sraw, 0x18, 0x18);
705 GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER)
707 gen_op_load_gpr_T0(rS(ctx->opcode));
708 gen_op_srawi(SH(ctx->opcode), MASK(32 - SH(ctx->opcode), 31));
709 if (Rc(ctx->opcode) != 0)
711 gen_op_store_T0_gpr(rA(ctx->opcode));
715 __GEN_LOGICAL2(srw, 0x18, 0x10);
717 /*** Floating-Point arithmetic ***/
719 GEN_HANDLER(fadd, 0x3F, 0x15, 0xFF, 0x000007C0, PPC_FLOAT)
721 SET_RETVAL(EXCP_INVAL);
725 GEN_HANDLER(fadds, 0x3B, 0x15, 0xFF, 0x000007C0, PPC_FLOAT)
727 SET_RETVAL(EXCP_INVAL);
731 GEN_HANDLER(fdiv, 0x3F, 0x12, 0xFF, 0x000007C0, PPC_FLOAT)
733 SET_RETVAL(EXCP_INVAL);
737 GEN_HANDLER(fdivs, 0x3B, 0x12, 0xFF, 0x000007C0, PPC_FLOAT)
739 SET_RETVAL(EXCP_INVAL);
743 GEN_HANDLER(fmul, 0x3F, 0x19, 0xFF, 0x0000F800, PPC_FLOAT)
745 SET_RETVAL(EXCP_INVAL);
749 GEN_HANDLER(fmuls, 0x3B, 0x19, 0xFF, 0x0000F800, PPC_FLOAT)
751 SET_RETVAL(EXCP_INVAL);
755 GEN_HANDLER(fres, 0x3B, 0x18, 0xFF, 0x001807C0, PPC_FLOAT)
757 SET_RETVAL(EXCP_INVAL);
761 GEN_HANDLER(frsqrte, 0x3F, 0x1A, 0xFF, 0x001807C0, PPC_FLOAT)
763 SET_RETVAL(EXCP_INVAL);
767 GEN_HANDLER(fsel, 0x3F, 0x17, 0xFF, 0x00000000, PPC_FLOAT)
769 SET_RETVAL(EXCP_INVAL);
773 GEN_HANDLER(fsub, 0x3F, 0x14, 0xFF, 0x000007C0, PPC_FLOAT)
775 SET_RETVAL(EXCP_INVAL);
779 GEN_HANDLER(fsubs, 0x3B, 0x14, 0xFF, 0x000007C0, PPC_FLOAT)
781 SET_RETVAL(EXCP_INVAL);
786 GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001807C0, PPC_FLOAT)
788 SET_RETVAL(EXCP_INVAL);
792 GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001807C0, PPC_FLOAT)
794 SET_RETVAL(EXCP_INVAL);
797 /*** Floating-Point multiply-and-add ***/
799 GEN_HANDLER(fmadd, 0x3F, 0x1D, 0xFF, 0x00000000, PPC_FLOAT)
801 SET_RETVAL(EXCP_INVAL);
805 GEN_HANDLER(fmadds, 0x3B, 0x1D, 0xFF, 0x00000000, PPC_FLOAT)
807 SET_RETVAL(EXCP_INVAL);
811 GEN_HANDLER(fmsub, 0x3F, 0x1C, 0xFF, 0x00000000, PPC_FLOAT)
813 SET_RETVAL(EXCP_INVAL);
817 GEN_HANDLER(fmsubs, 0x3B, 0x1C, 0xFF, 0x00000000, PPC_FLOAT)
819 SET_RETVAL(EXCP_INVAL);
823 GEN_HANDLER(fnmadd, 0x3F, 0x1F, 0xFF, 0x00000000, PPC_FLOAT)
825 SET_RETVAL(EXCP_INVAL);
829 GEN_HANDLER(fnmadds, 0x3B, 0x1F, 0xFF, 0x00000000, PPC_FLOAT)
831 SET_RETVAL(EXCP_INVAL);
835 GEN_HANDLER(fnmsub, 0x3F, 0x1E, 0xFF, 0x00000000, PPC_FLOAT)
837 SET_RETVAL(EXCP_INVAL);
841 GEN_HANDLER(fnmsubs, 0x3B, 0x1E, 0xFF, 0x00000000, PPC_FLOAT)
843 SET_RETVAL(EXCP_INVAL);
846 /*** Floating-Point round & convert ***/
848 GEN_HANDLER(fctiw, 0x3F, 0x0E, 0xFF, 0x001F0000, PPC_FLOAT)
850 SET_RETVAL(EXCP_INVAL);
854 GEN_HANDLER(fctiwz, 0x3F, 0x0F, 0xFF, 0x001F0000, PPC_FLOAT)
856 SET_RETVAL(EXCP_INVAL);
860 GEN_HANDLER(frsp, 0x3F, 0x0C, 0xFF, 0x001F0000, PPC_FLOAT)
862 SET_RETVAL(EXCP_INVAL);
865 /*** Floating-Point compare ***/
867 GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT)
869 SET_RETVAL(EXCP_INVAL);
873 GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT)
875 SET_RETVAL(EXCP_INVAL);
878 /*** Floating-Point status & ctrl register ***/
880 GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT)
882 gen_op_load_fpscr_T0(crfS(ctx->opcode));
883 gen_op_store_T0_crf(crfD(ctx->opcode));
884 gen_op_clear_fpscr(crfS(ctx->opcode));
889 GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT)
892 gen_op_store_FT0_fpr(rD(ctx->opcode));
899 GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT)
903 crb = crbD(ctx->opcode) >> 2;
904 gen_op_load_fpscr_T0(crb);
905 gen_op_andi_(~(1 << (crbD(ctx->opcode) & 0x03)));
906 gen_op_store_T0_fpscr(crb);
913 GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT)
917 crb = crbD(ctx->opcode) >> 2;
918 gen_op_load_fpscr_T0(crb);
919 gen_op_ori(1 << (crbD(ctx->opcode) & 0x03));
920 gen_op_store_T0_fpscr(crb);
927 GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT)
929 gen_op_load_fpr_FT0(rB(ctx->opcode));
930 gen_op_store_fpscr(FM(ctx->opcode));
937 GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT)
939 gen_op_store_T0_fpscri(crbD(ctx->opcode) >> 2, FPIMM(ctx->opcode));
945 /*** Integer load ***/
946 #define GEN_ILDZ(width, opc) \
947 GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) \
949 uint32_t simm = SIMM(ctx->opcode); \
950 if (rA(ctx->opcode) == 0) { \
951 gen_op_l##width##_z(simm); \
953 gen_op_load_gpr_T0(rA(ctx->opcode)); \
954 gen_op_l##width (simm); \
956 gen_op_store_T1_gpr(rD(ctx->opcode)); \
960 #define GEN_ILDZU(width, opc) \
961 GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) \
963 if (rA(ctx->opcode) == 0 || \
964 rA(ctx->opcode) == rD(ctx->opcode)) \
965 SET_RETVAL(EXCP_INVAL); \
966 gen_op_load_gpr_T0(rA(ctx->opcode)); \
967 gen_op_l##width(SIMM(ctx->opcode)); \
968 gen_op_store_T1_gpr(rD(ctx->opcode)); \
969 gen_op_store_T0_gpr(rA(ctx->opcode)); \
973 #define GEN_ILDZUX(width, opc) \
974 GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_INTEGER) \
976 if (rA(ctx->opcode) == 0 || \
977 rA(ctx->opcode) == rD(ctx->opcode)) \
978 SET_RETVAL(EXCP_INVAL); \
979 gen_op_load_gpr_T0(rA(ctx->opcode)); \
980 gen_op_load_gpr_T1(rB(ctx->opcode)); \
981 gen_op_l##width##x(); \
982 gen_op_store_T1_gpr(rD(ctx->opcode)); \
983 gen_op_store_T0_gpr(rA(ctx->opcode)); \
987 #define GEN_ILDZX(width, opc2, opc3) \
988 GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_INTEGER) \
990 if (rA(ctx->opcode) == 0) { \
991 gen_op_load_gpr_T0(rB(ctx->opcode)); \
992 gen_op_l##width##x_z(); \
994 gen_op_load_gpr_T0(rA(ctx->opcode)); \
995 gen_op_load_gpr_T1(rB(ctx->opcode)); \
996 gen_op_l##width##x(); \
998 gen_op_store_T1_gpr(rD(ctx->opcode)); \
1002 #define GEN_ILD(width, op) \
1003 GEN_ILDZ(width, op | 0x20) \
1004 GEN_ILDZU(width, op | 0x21) \
1005 GEN_ILDZUX(width, op | 0x01) \
1006 GEN_ILDZX(width, 0x17, op | 0x00)
1008 /* lbz lbzu lbzux lbzx */
1010 /* lha lhau lhaux lhax */
1012 /* lhz lhzu lhzux lhzx */
1014 /* lwz lwzu lwzux lwzx */
1017 /*** Integer store ***/
1018 #define GEN_IST(width, opc) \
1019 GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) \
1021 uint32_t simm = SIMM(ctx->opcode); \
1022 if (rA(ctx->opcode) == 0) { \
1023 gen_op_load_gpr_T0(rS(ctx->opcode)); \
1024 gen_op_st##width##_z(simm); \
1026 gen_op_load_gpr_T0(rA(ctx->opcode)); \
1027 gen_op_load_gpr_T1(rS(ctx->opcode)); \
1028 gen_op_st##width(simm); \
1033 #define GEN_ISTU(width, opc) \
1034 GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) \
1036 if (rA(ctx->opcode) == 0) \
1037 SET_RETVAL(EXCP_INVAL); \
1038 gen_op_load_gpr_T0(rA(ctx->opcode)); \
1039 gen_op_load_gpr_T1(rS(ctx->opcode)); \
1040 gen_op_st##width(SIMM(ctx->opcode)); \
1041 gen_op_store_T0_gpr(rA(ctx->opcode)); \
1045 #define GEN_ISTUX(width, opc) \
1046 GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_INTEGER) \
1048 if (rA(ctx->opcode) == 0) \
1049 SET_RETVAL(EXCP_INVAL); \
1050 gen_op_load_gpr_T0(rA(ctx->opcode)); \
1051 gen_op_load_gpr_T1(rB(ctx->opcode)); \
1052 gen_op_load_gpr_T2(rS(ctx->opcode)); \
1053 gen_op_st##width##x(); \
1054 gen_op_store_T0_gpr(rA(ctx->opcode)); \
1058 #define GEN_ISTX(width, opc2, opc3) \
1059 GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_INTEGER) \
1061 if (rA(ctx->opcode) == 0) { \
1062 gen_op_load_gpr_T0(rB(ctx->opcode)); \
1063 gen_op_load_gpr_T1(rS(ctx->opcode)); \
1064 gen_op_st##width##x_z(); \
1066 gen_op_load_gpr_T0(rA(ctx->opcode)); \
1067 gen_op_load_gpr_T1(rB(ctx->opcode)); \
1068 gen_op_load_gpr_T2(rS(ctx->opcode)); \
1069 gen_op_st##width##x(); \
1074 #define GEN_ISTO(width, opc) \
1075 GEN_IST(width, opc | 0x20) \
1076 GEN_ISTU(width, opc | 0x21) \
1077 GEN_ISTUX(width, opc | 0x01) \
1078 GEN_ISTX(width, 0x17, opc | 0x00)
1080 /* stb stbu stbux stbx */
1082 /* sth sthu sthux sthx */
1084 /* stw stwu stwux stwx */
1087 /*** Integer load and store with byte reverse ***/
1089 GEN_ILDZX(hbr, 0x16, 0x18);
1091 GEN_ILDZX(wbr, 0x16, 0x10);
1093 GEN_ISTX(hbr, 0x16, 0x1C);
1095 GEN_ISTX(wbr, 0x16, 0x14);
1097 /*** Integer load and store multiple ***/
1099 GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1101 if (rA(ctx->opcode) == 0) {
1104 gen_op_load_gpr_T0(rA(ctx->opcode));
1106 gen_op_lmw(rD(ctx->opcode), SIMM(ctx->opcode));
1111 GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1113 if (rA(ctx->opcode) == 0) {
1116 gen_op_load_gpr_T0(rA(ctx->opcode));
1118 gen_op_stmw(rS(ctx->opcode), SIMM(ctx->opcode));
1122 /*** Integer load and store strings ***/
1124 GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_INTEGER)
1126 int nb = NB(ctx->opcode);
1127 int start = rD(ctx->opcode);
1133 if ((start + nr) > 32) {
1134 /* handle wrap around r0 */
1135 if (rA(ctx->opcode) == 0) {
1138 gen_op_load_gpr_T0(rA(ctx->opcode));
1140 gen_op_lswi(start, 4 * (32 - start));
1141 nb -= 4 * (32 - start);
1144 if (rA(ctx->opcode) == 0) {
1147 gen_op_load_gpr_T0(rA(ctx->opcode));
1149 gen_op_lswi(start, nb);
1154 GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_INTEGER)
1156 gen_op_load_xer_bc();
1157 gen_op_load_gpr_T1(rB(ctx->opcode));
1158 if (rA(ctx->opcode) == 0) {
1161 gen_op_load_gpr_T2(rA(ctx->opcode));
1163 gen_op_lswx(rD(ctx->opcode));
1168 GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_INTEGER)
1170 int nb = NB(ctx->opcode);
1171 int start = rS(ctx->opcode);
1177 if ((start + nr) > 32) {
1178 /* handle wrap around r0 */
1179 if (rA(ctx->opcode) == 0) {
1182 gen_op_load_gpr_T0(rA(ctx->opcode));
1184 gen_op_stswi(start, 4 * (32 - start));
1185 nb -= 4 * (32 - start);
1188 if (rA(ctx->opcode) == 0) {
1191 gen_op_load_gpr_T0(rA(ctx->opcode));
1193 gen_op_stswi(start, nb);
1198 GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_INTEGER)
1200 gen_op_load_xer_bc();
1201 gen_op_load_gpr_T1(rB(ctx->opcode));
1202 if (rA(ctx->opcode) == 0) {
1205 gen_op_load_gpr_T2(rA(ctx->opcode));
1207 gen_op_stswx(rS(ctx->opcode));
1211 /*** Memory synchronisation ***/
1213 GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FF0801, PPC_MEM)
1215 /* Do a branch to next instruction */
1216 gen_op_b((uint32_t)ctx->nip);
1217 SET_RETVAL(EXCP_BRANCH);
1221 GEN_HANDLER(isync, 0x13, 0x16, 0xFF, 0x03FF0801, PPC_MEM)
1223 /* Do a branch to next instruction */
1224 gen_op_b((uint32_t)ctx->nip);
1225 SET_RETVAL(EXCP_BRANCH);
1229 GEN_HANDLER(lwarx, 0x1F, 0x14, 0xFF, 0x00000001, PPC_MEM)
1232 if (rA(ctx->opcode) == 0) {
1233 gen_op_load_gpr_T0(rB(ctx->opcode));
1236 gen_op_load_gpr_T0(rA(ctx->opcode));
1237 gen_op_load_gpr_T1(rB(ctx->opcode));
1240 gen_op_store_T1_gpr(rD(ctx->opcode));
1245 GEN_HANDLER(stwcx_, 0x1F, 0x16, 0x04, 0x00000000, PPC_MEM)
1250 if (rA(ctx->opcode) == 0) {
1251 gen_op_load_gpr_T0(rB(ctx->opcode));
1252 gen_op_load_gpr_T1(rS(ctx->opcode));
1255 gen_op_load_gpr_T0(rA(ctx->opcode));
1256 gen_op_load_gpr_T1(rB(ctx->opcode));
1257 gen_op_load_gpr_T2(rS(ctx->opcode));
1265 GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x03FF0801, PPC_MEM)
1267 /* Do a branch to next instruction */
1268 gen_op_b((uint32_t)ctx->nip);
1269 SET_RETVAL(EXCP_BRANCH);
1272 /*** Floating-point load ***/
1273 #define GEN_LF(width, opc) \
1274 GEN_HANDLER(lf##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
1276 uint32_t simm = SIMM(ctx->opcode); \
1277 if (rA(ctx->opcode) == 0) { \
1278 gen_op_lf##width##_z_FT0(simm); \
1280 gen_op_load_gpr_T0(rA(ctx->opcode)); \
1281 gen_op_lf##width##_FT0(simm); \
1283 gen_op_store_FT0_fpr(rD(ctx->opcode));\
1287 #define GEN_LFU(width, opc) \
1288 GEN_HANDLER(lf##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
1290 if (rA(ctx->opcode) == 0 || \
1291 rA(ctx->opcode) == rD(ctx->opcode)) \
1292 SET_RETVAL(EXCP_INVAL); \
1293 gen_op_load_gpr_T0(rA(ctx->opcode)); \
1294 gen_op_lf##width##_FT0(SIMM(ctx->opcode)); \
1295 gen_op_store_FT0_fpr(rD(ctx->opcode));\
1296 gen_op_store_T0_gpr(rA(ctx->opcode)); \
1300 #define GEN_LFUX(width, opc) \
1301 GEN_HANDLER(lf##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \
1303 if (rA(ctx->opcode) == 0 || \
1304 rA(ctx->opcode) == rD(ctx->opcode)) \
1305 SET_RETVAL(EXCP_INVAL); \
1306 gen_op_load_gpr_T0(rA(ctx->opcode)); \
1307 gen_op_load_gpr_T1(rB(ctx->opcode)); \
1308 gen_op_lf##width##x_FT0(); \
1309 gen_op_store_FT0_fpr(rD(ctx->opcode));\
1310 gen_op_store_T0_gpr(rA(ctx->opcode)); \
1314 #define GEN_LFX(width, opc) \
1315 GEN_HANDLER(lf##width##x, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \
1317 if (rA(ctx->opcode) == 0) { \
1318 gen_op_load_gpr_T0(rB(ctx->opcode)); \
1319 gen_op_lf##width##x_z_FT0(); \
1321 gen_op_load_gpr_T0(rA(ctx->opcode)); \
1322 gen_op_load_gpr_T1(rB(ctx->opcode)); \
1323 gen_op_lf##width##x_FT0(); \
1325 gen_op_store_FT0_fpr(rD(ctx->opcode));\
1329 #define GEN_LDF(width, opc) \
1330 GEN_LF(width, opc | 0x20) \
1331 GEN_LFU(width, opc | 0x21) \
1332 GEN_LFUX(width, opc | 0x01) \
1333 GEN_LFX(width, opc | 0x00)
1335 /* lfd lfdu lfdux lfdx */
1337 /* lfs lfsu lfsux lfsx */
1340 /*** Floating-point store ***/
1341 #define GEN_STF(width, opc) \
1342 GEN_HANDLER(stf##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
1344 uint32_t simm = SIMM(ctx->opcode); \
1345 gen_op_load_fpr_FT0(rS(ctx->opcode));\
1346 if (rA(ctx->opcode) == 0) { \
1347 gen_op_stf##width##_z_FT0(simm); \
1349 gen_op_load_gpr_T0(rA(ctx->opcode)); \
1350 gen_op_stf##width##_FT0(simm); \
1355 #define GEN_STFU(width, opc) \
1356 GEN_HANDLER(stf##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
1358 if (rA(ctx->opcode) == 0) \
1359 SET_RETVAL(EXCP_INVAL); \
1360 gen_op_load_gpr_T0(rA(ctx->opcode)); \
1361 gen_op_load_fpr_FT0(rS(ctx->opcode));\
1362 gen_op_stf##width##_FT0(SIMM(ctx->opcode)); \
1363 gen_op_store_T0_gpr(rA(ctx->opcode)); \
1367 #define GEN_STFUX(width, opc) \
1368 GEN_HANDLER(stf##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \
1370 if (rA(ctx->opcode) == 0) \
1371 SET_RETVAL(EXCP_INVAL); \
1372 gen_op_load_gpr_T0(rA(ctx->opcode)); \
1373 gen_op_load_gpr_T1(rB(ctx->opcode)); \
1374 gen_op_load_fpr_FT0(rS(ctx->opcode));\
1375 gen_op_stf##width##x_FT0(); \
1376 gen_op_store_T0_gpr(rA(ctx->opcode)); \
1380 #define GEN_STFX(width, opc) \
1381 GEN_HANDLER(stf##width##x, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \
1383 gen_op_load_fpr_FT0(rS(ctx->opcode));\
1384 if (rA(ctx->opcode) == 0) { \
1385 gen_op_load_gpr_T0(rB(ctx->opcode)); \
1386 gen_op_stf##width##x_z_FT0(); \
1388 gen_op_load_gpr_T0(rA(ctx->opcode)); \
1389 gen_op_load_gpr_T1(rB(ctx->opcode)); \
1390 gen_op_stf##width##x_FT0(); \
1395 #define GEN_STOF(width, opc) \
1396 GEN_STF(width, opc | 0x20) \
1397 GEN_STFU(width, opc | 0x21) \
1398 GEN_STFUX(width, opc | 0x01) \
1399 GEN_STFX(width, opc | 0x00)
1401 /* stfd stfdu stfdux stfdx */
1403 /* stfs stfsu stfsux stfsx */
1408 GEN_HANDLER(stfiwx, 0x1F, 0x17, 0x1E, 0x00000001, PPC_FLOAT)
1410 SET_RETVAL(EXCP_INVAL);
1413 /*** Floating-point move ***/
1415 GEN_HANDLER(fabs, 0x3F, 0x08, 0x08, 0x001F0000, PPC_FLOAT)
1417 SET_RETVAL(EXCP_INVAL);
1421 GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT)
1423 SET_RETVAL(EXCP_INVAL);
1427 GEN_HANDLER(fnabs, 0x3F, 0x08, 0x04, 0x001F0000, PPC_FLOAT)
1429 SET_RETVAL(EXCP_INVAL);
1433 GEN_HANDLER(fneg, 0x3F, 0x08, 0x01, 0x001F0000, PPC_FLOAT)
1435 SET_RETVAL(EXCP_INVAL);
1439 #define GEN_BCOND(name, opc1, opc2, opc3, prologue, \
1440 bl_ctr, b_ctr, bl_ctrz, b_ctrz, b, \
1441 bl_ctr_true, b_ctr_true, bl_ctrz_true, b_ctrz_true, bl_true, b_true, \
1442 bl_ctr_false, b_ctr_false, bl_ctrz_false, b_ctrz_false, bl_false, b_false) \
1443 GEN_HANDLER(name, opc1, opc2, opc3, 0x00000000, PPC_FLOW) \
1445 __attribute__ ((unused)) uint32_t target; \
1446 uint32_t bo = BO(ctx->opcode); \
1447 uint32_t bi = BI(ctx->opcode); \
1450 if ((bo & 0x4) == 0) \
1453 /* No CR condition */ \
1454 switch (bo & 0x6) { \
1456 if (LK(ctx->opcode)) { \
1463 if (LK(ctx->opcode)) { \
1472 if (LK(ctx->opcode)) \
1473 gen_op_load_lr((uint32_t)ctx->nip); \
1476 printf("ERROR: %s: unhandled ba case (%d)\n", __func__, bo); \
1477 SET_RETVAL(EXCP_INVAL); \
1481 mask = 1 << (3 - (bi & 0x03)); \
1482 gen_op_load_crf_T0(bi >> 2); \
1484 switch (bo & 0x6) { \
1486 if (LK(ctx->opcode)) { \
1493 if (LK(ctx->opcode)) { \
1501 if (LK(ctx->opcode)) { \
1508 printf("ERROR: %s: unhandled b case (%d)\n", __func__, bo); \
1509 SET_RETVAL(EXCP_INVAL); \
1513 switch (bo & 0x6) { \
1515 if (LK(ctx->opcode)) { \
1522 if (LK(ctx->opcode)) { \
1530 if (LK(ctx->opcode)) { \
1537 printf("ERROR: %s: unhandled bn case (%d)\n", __func__, bo); \
1538 SET_RETVAL(EXCP_INVAL); \
1543 SET_RETVAL(EXCP_BRANCH); \
1547 GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
1549 uint32_t li = s_ext24(LI(ctx->opcode)), target;
1551 if (AA(ctx->opcode) == 0)
1552 target = (uint32_t)ctx->nip + li - 4;
1554 target = s_ext24(LI(ctx->opcode));
1556 if (LK(ctx->opcode))
1557 gen_op_load_lr((uint32_t)ctx->nip);
1558 SET_RETVAL(EXCP_BRANCH);
1561 /* bc bca bcl bcla */
1562 GEN_BCOND(bc, 0x10, 0xFF, 0xFF,
1564 uint32_t li = s_ext16(BD(ctx->opcode));
1565 if (AA(ctx->opcode) == 0) {
1566 target = (uint32_t)ctx->nip + li - 4;
1571 gen_op_bl_ctr((uint32_t)ctx->nip, target),
1572 gen_op_b_ctr((uint32_t)ctx->nip, target),
1573 gen_op_bl_ctrz((uint32_t)ctx->nip, target),
1574 gen_op_b_ctrz((uint32_t)ctx->nip, target),
1576 gen_op_bl_ctr_true((uint32_t)ctx->nip, target, mask),
1577 gen_op_b_ctr_true((uint32_t)ctx->nip, target, mask),
1578 gen_op_bl_ctrz_true((uint32_t)ctx->nip, target, mask),
1579 gen_op_b_ctrz_true((uint32_t)ctx->nip, target, mask),
1580 gen_op_bl_true((uint32_t)ctx->nip, target, mask),
1581 gen_op_b_true((uint32_t)ctx->nip, target, mask),
1582 gen_op_bl_ctr_false((uint32_t)ctx->nip, target, mask),
1583 gen_op_b_ctr_false((uint32_t)ctx->nip, target, mask),
1584 gen_op_bl_ctrz_false((uint32_t)ctx->nip, target, mask),
1585 gen_op_b_ctrz_false((uint32_t)ctx->nip, target, mask),
1586 gen_op_bl_false((uint32_t)ctx->nip, target, mask),
1587 gen_op_b_false((uint32_t)ctx->nip, target, mask));
1590 GEN_BCOND(bcctr, 0x13, 0x10, 0x10, do { } while (0),
1591 gen_op_bctrl_ctr((uint32_t)ctx->nip),
1592 gen_op_bctr_ctr((uint32_t)ctx->nip),
1593 gen_op_bctrl_ctrz((uint32_t)ctx->nip),
1594 gen_op_bctr_ctrz((uint32_t)ctx->nip),
1596 gen_op_bctrl_ctr_true((uint32_t)ctx->nip, mask),
1597 gen_op_bctr_ctr_true((uint32_t)ctx->nip, mask),
1598 gen_op_bctrl_ctrz_true((uint32_t)ctx->nip, mask),
1599 gen_op_bctr_ctrz_true((uint32_t)ctx->nip, mask),
1600 gen_op_bctrl_true((uint32_t)ctx->nip, mask),
1601 gen_op_bctr_true((uint32_t)ctx->nip, mask),
1602 gen_op_bctrl_ctr_false((uint32_t)ctx->nip, mask),
1603 gen_op_bctr_ctr_false((uint32_t)ctx->nip, mask),
1604 gen_op_bctrl_ctrz_false((uint32_t)ctx->nip, mask),
1605 gen_op_bctr_ctrz_false((uint32_t)ctx->nip, mask),
1606 gen_op_bctrl_false((uint32_t)ctx->nip, mask),
1607 gen_op_bctr_false((uint32_t)ctx->nip, mask))
1610 GEN_BCOND(bclr, 0x13, 0x10, 0x00, do { } while (0),
1611 gen_op_blrl_ctr((uint32_t)ctx->nip),
1612 gen_op_blr_ctr((uint32_t)ctx->nip),
1613 gen_op_blrl_ctrz((uint32_t)ctx->nip),
1614 gen_op_blr_ctrz((uint32_t)ctx->nip),
1616 gen_op_blrl_ctr_true((uint32_t)ctx->nip, mask),
1617 gen_op_blr_ctr_true((uint32_t)ctx->nip, mask),
1618 gen_op_blrl_ctrz_true((uint32_t)ctx->nip, mask),
1619 gen_op_blr_ctrz_true((uint32_t)ctx->nip, mask),
1620 gen_op_blrl_true((uint32_t)ctx->nip, mask),
1621 gen_op_blr_true((uint32_t)ctx->nip, mask),
1622 gen_op_blrl_ctr_false((uint32_t)ctx->nip, mask),
1623 gen_op_blr_ctr_false((uint32_t)ctx->nip, mask),
1624 gen_op_blrl_ctrz_false((uint32_t)ctx->nip, mask),
1625 gen_op_blr_ctrz_false((uint32_t)ctx->nip, mask),
1626 gen_op_blrl_false((uint32_t)ctx->nip, mask),
1627 gen_op_blr_false((uint32_t)ctx->nip, mask))
1629 /*** Condition register logical ***/
1630 #define GEN_CRLOGIC(op, opc) \
1631 GEN_HANDLER(cr##op, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER) \
1633 gen_op_load_crf_T0(crbA(ctx->opcode) >> 2); \
1634 gen_op_getbit_T0(3 - (crbA(ctx->opcode) & 0x03)); \
1635 gen_op_load_crf_T1(crbB(ctx->opcode) >> 2); \
1636 gen_op_getbit_T1(3 - (crbB(ctx->opcode) & 0x03)); \
1638 gen_op_load_crf_T1(crbD(ctx->opcode) >> 2); \
1639 gen_op_setcrfbit(~(1 << (3 - (crbD(ctx->opcode) & 0x03))), \
1640 3 - (crbD(ctx->opcode) & 0x03)); \
1641 gen_op_store_T1_crf(crbD(ctx->opcode) >> 2); \
1646 GEN_CRLOGIC(and, 0x08)
1648 GEN_CRLOGIC(andc, 0x04)
1650 GEN_CRLOGIC(eqv, 0x09)
1652 GEN_CRLOGIC(nand, 0x07)
1654 GEN_CRLOGIC(nor, 0x01)
1656 GEN_CRLOGIC(or, 0x0E)
1658 GEN_CRLOGIC(orc, 0x0D)
1660 GEN_CRLOGIC(xor, 0x06)
1662 GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER)
1664 gen_op_load_crf_T0(crfS(ctx->opcode));
1665 gen_op_store_T0_crf(crfD(ctx->opcode));
1669 /*** System linkage ***/
1670 /* rfi (supervisor only) */
1671 GEN_HANDLER(rfi, 0x13, 0x12, 0xFF, 0x03FF8001, PPC_FLOW)
1673 SET_RETVAL(EXCP_INVAL);
1677 GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFFFFD, PPC_FLOW)
1679 gen_op_b((uint32_t)ctx->nip);
1680 SET_RETVAL(EXCP_SYSCALL);
1685 GEN_HANDLER(tw, 0x1F, 0x04, 0xFF, 0x00000001, PPC_FLOW)
1687 SET_RETVAL(EXCP_INVAL);
1691 GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
1693 SET_RETVAL(EXCP_INVAL);
1696 /*** Processor control ***/
1697 static inline int check_spr_access (int spr, int rw, int supervisor)
1699 uint32_t rights = spr_access[spr >> 1] >> (4 * (spr & 1));
1701 rights = rights >> (2 * supervisor);
1702 rights = rights >> rw;
1708 GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC)
1710 gen_op_load_xer_cr();
1711 gen_op_store_T0_crf(crfD(ctx->opcode));
1712 gen_op_clear_xer_cr();
1717 GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x001FF801, PPC_MISC)
1720 gen_op_store_T0_gpr(rD(ctx->opcode));
1725 GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC)
1727 if (!ctx->supervisor)
1728 SET_RETVAL(EXCP_PRIV);
1730 gen_op_store_T0_gpr(rD(ctx->opcode));
1735 GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC)
1737 uint32_t sprn = SPR(ctx->opcode);
1739 if (check_spr_access(sprn, 0, ctx->supervisor) == 0)
1740 SET_RETVAL(EXCP_PRIV);
1741 /* XXX: make this more generic */
1745 fprintf(logfile, "LOAD XER at %p\n", ctx->nip - 1);
1749 case SPR_ENCODE(268):
1750 /* We need to update the time base before reading it */
1751 gen_op_update_tb(ctx->tb_offset);
1754 case SPR_ENCODE(269):
1755 gen_op_update_tb(ctx->tb_offset);
1759 gen_op_load_spr(sprn);
1762 gen_op_store_T0_gpr(rD(ctx->opcode)); //
1767 GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MISC)
1769 uint32_t sprn = SPR(ctx->opcode);
1771 if (check_spr_access(sprn, 0, ctx->supervisor) == 0)
1772 SET_RETVAL(EXCP_PRIV);
1774 case SPR_ENCODE(268):
1775 /* We need to update the time base before reading it */
1776 gen_op_update_tb(ctx->tb_offset);
1779 case SPR_ENCODE(269):
1780 gen_op_update_tb(ctx->tb_offset);
1784 SET_RETVAL(EXCP_INVAL);
1791 GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00100801, PPC_MISC)
1793 gen_op_load_gpr_T0(rS(ctx->opcode));
1794 gen_op_store_cr(CRM(ctx->opcode));
1799 GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC)
1801 if (!ctx->supervisor)
1802 SET_RETVAL(EXCP_PRIV);
1803 gen_op_load_gpr_T0(rS(ctx->opcode));
1805 /* Must stop the translation as machine state (may have) changed */
1806 SET_RETVAL(EXCP_MTMSR);
1810 GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC)
1812 uint32_t sprn = SPR(ctx->opcode);
1814 if (check_spr_access(sprn, 1, ctx->supervisor) == 0)
1815 SET_RETVAL(EXCP_PRIV);
1816 gen_op_load_gpr_T0(rS(ctx->opcode));
1817 if (sprn == SPR_ENCODE(1)) {
1820 gen_op_store_spr(sprn);
1825 /*** Cache management ***/
1826 /* For now, all those will be implemented as nop:
1827 * this is valid, regarding the PowerPC specs...
1830 GEN_HANDLER(dcbf, 0x1F, 0x16, 0x17, 0x03E00001, PPC_MEM)
1835 /* dcbi (Supervisor only) */
1836 GEN_HANDLER(dcbi, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_MEM)
1842 GEN_HANDLER(dcbst, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_MEM)
1848 GEN_HANDLER(dcbt, 0x1F, 0x16, 0x01, 0x03E00001, PPC_MEM)
1854 GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x02, 0x03E00001, PPC_MEM)
1860 GEN_HANDLER(dcbz, 0x1F, 0x16, 0x08, 0x03E00001, PPC_MEM)
1862 if (rA(ctx->opcode) == 0) {
1863 gen_op_load_gpr_T0(rB(ctx->opcode));
1866 gen_op_load_gpr_T0(rA(ctx->opcode));
1867 gen_op_load_gpr_T1(rB(ctx->opcode));
1874 GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_MEM)
1876 if (rA(ctx->opcode) == 0) {
1877 gen_op_load_gpr_T0(rB(ctx->opcode));
1880 gen_op_load_gpr_T0(rA(ctx->opcode));
1881 gen_op_load_gpr_T1(rB(ctx->opcode));
1889 GEN_HANDLER(dcba, 0x1F, 0x16, 0x07, 0x03E00001, PPC_MEM)
1894 /*** Segment register manipulation ***/
1895 /* Supervisor only: */
1897 GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT)
1899 SET_RETVAL(EXCP_INVAL);
1903 GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x0010F001, PPC_SEGMENT)
1905 SET_RETVAL(EXCP_INVAL);
1909 GEN_HANDLER(mtsr, 0x1F, 0x12, 0x02, 0x0010F801, PPC_SEGMENT)
1911 SET_RETVAL(EXCP_INVAL);
1915 GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x0010F001, PPC_SEGMENT)
1917 SET_RETVAL(EXCP_INVAL);
1920 /*** Lookaside buffer management ***/
1921 /* Optional & supervisor only: */
1923 GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM)
1925 SET_RETVAL(EXCP_INVAL);
1929 GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF8001, PPC_MEM)
1931 SET_RETVAL(EXCP_INVAL);
1935 GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFFC01, PPC_MEM)
1937 SET_RETVAL(EXCP_INVAL);
1940 /*** External control ***/
1943 GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN)
1945 SET_RETVAL(EXCP_INVAL);
1949 GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN)
1951 SET_RETVAL(EXCP_INVAL);
1954 /* End opcode list */
1955 GEN_OPCODE_MARK(end);
1957 /*****************************************************************************/
1960 extern FILE *stderr;
1961 void free (void *p);
1962 int fflush (FILE *f);
1964 /* Main ppc opcodes table:
1965 * at init, all opcodes are invalids
1967 static opc_handler_t *ppc_opcodes[0x40];
1971 PPC_DIRECT = 0, /* Opcode routine */
1972 PPC_INDIRECT = 1, /* Indirect opcode table */
1975 static inline int is_indirect_opcode (void *handler)
1977 return ((unsigned long)handler & 0x03) == PPC_INDIRECT;
1980 static inline opc_handler_t **ind_table(void *handler)
1982 return (opc_handler_t **)((unsigned long)handler & ~3);
1985 /* Opcodes tables creation */
1986 static void fill_new_table (opc_handler_t **table, int len)
1990 for (i = 0; i < len; i++)
1991 table[i] = &invalid_handler;
1994 static int create_new_table (opc_handler_t **table, unsigned char idx)
1996 opc_handler_t **tmp;
1998 tmp = malloc(0x20 * sizeof(opc_handler_t));
2001 fill_new_table(tmp, 0x20);
2002 table[idx] = (opc_handler_t *)((unsigned long)tmp | PPC_INDIRECT);
2007 static int insert_in_table (opc_handler_t **table, unsigned char idx,
2008 opc_handler_t *handler)
2010 if (table[idx] != &invalid_handler)
2012 table[idx] = handler;
2017 static int register_direct_insn (unsigned char idx, opc_handler_t *handler)
2019 if (insert_in_table(ppc_opcodes, idx, handler) < 0) {
2020 fprintf(stderr, "*** ERROR: opcode %02x already assigned in main "
2021 "opcode table\n", idx);
2028 static int register_ind_in_table (opc_handler_t **table,
2029 unsigned char idx1, unsigned char idx2,
2030 opc_handler_t *handler)
2032 if (table[idx1] == &invalid_handler) {
2033 if (create_new_table(table, idx1) < 0) {
2034 fprintf(stderr, "*** ERROR: unable to create indirect table "
2035 "idx=%02x\n", idx1);
2039 if (!is_indirect_opcode(table[idx1])) {
2040 fprintf(stderr, "*** ERROR: idx %02x already assigned to a direct "
2045 if (handler != NULL &&
2046 insert_in_table(ind_table(table[idx1]), idx2, handler) < 0) {
2047 fprintf(stderr, "*** ERROR: opcode %02x already assigned in "
2048 "opcode table %02x\n", idx2, idx1);
2055 static int register_ind_insn (unsigned char idx1, unsigned char idx2,
2056 opc_handler_t *handler)
2060 ret = register_ind_in_table(ppc_opcodes, idx1, idx2, handler);
2065 static int register_dblind_insn (unsigned char idx1, unsigned char idx2,
2066 unsigned char idx3, opc_handler_t *handler)
2068 if (register_ind_in_table(ppc_opcodes, idx1, idx2, NULL) < 0) {
2069 fprintf(stderr, "*** ERROR: unable to join indirect table idx "
2070 "[%02x-%02x]\n", idx1, idx2);
2073 if (register_ind_in_table(ind_table(ppc_opcodes[idx1]), idx2, idx3,
2075 fprintf(stderr, "*** ERROR: unable to insert opcode "
2076 "[%02x-%02x-%02x]\n", idx1, idx2, idx3);
2083 static int register_insn (opcode_t *insn)
2085 if (insn->opc2 != 0xFF) {
2086 if (insn->opc3 != 0xFF) {
2087 if (register_dblind_insn(insn->opc1, insn->opc2, insn->opc3,
2088 &insn->handler) < 0)
2091 if (register_ind_insn(insn->opc1, insn->opc2, &insn->handler) < 0)
2095 if (register_direct_insn(insn->opc1, &insn->handler) < 0)
2102 static int test_opcode_table (opc_handler_t **table, int len)
2106 for (i = 0, count = 0; i < len; i++) {
2107 /* Consistency fixup */
2108 if (table[i] == NULL)
2109 table[i] = &invalid_handler;
2110 if (table[i] != &invalid_handler) {
2111 if (is_indirect_opcode(table[i])) {
2112 tmp = test_opcode_table(ind_table(table[i]), 0x20);
2115 table[i] = &invalid_handler;
2128 static void fix_opcode_tables (void)
2130 if (test_opcode_table(ppc_opcodes, 0x40) == 0)
2131 fprintf(stderr, "*** WARNING: no opcode defined !\n");
2134 #define SPR_RIGHTS(rw, priv) ((2 * (priv)) + (rw))
2135 #define SPR_UR SPR_RIGHTS(0, 0)
2136 #define SPR_UW SPR_RIGHTS(1, 0)
2137 #define SPR_SR SPR_RIGHTS(0, 1)
2138 #define SPR_SW SPR_RIGHTS(1, 1)
2140 #define spr_set_rights(spr, rights) \
2142 spr_access[(spr) >> 1] |= ((rights) << (4 * ((spr) & 1))); \
2145 static void init_spr_rights (void)
2148 spr_set_rights(SPR_ENCODE(1), SPR_UR | SPR_UW | SPR_SR | SPR_SW);
2150 spr_set_rights(SPR_ENCODE(8), SPR_UR | SPR_UW | SPR_SR | SPR_SW);
2152 spr_set_rights(SPR_ENCODE(9), SPR_UR | SPR_UW | SPR_SR | SPR_SW);
2154 spr_set_rights(SPR_ENCODE(268), SPR_UR | SPR_SR);
2156 spr_set_rights(SPR_ENCODE(269), SPR_UR | SPR_SR);
2157 /* DSISR (SPR 18) */
2158 spr_set_rights(SPR_ENCODE(18), SPR_SR | SPR_SW);
2160 spr_set_rights(SPR_ENCODE(19), SPR_SR | SPR_SW);
2162 spr_set_rights(SPR_ENCODE(22), SPR_SR | SPR_SW);
2164 spr_set_rights(SPR_ENCODE(25), SPR_SR | SPR_SW);
2165 /* SPRG0 (SPR 272) */
2166 spr_set_rights(SPR_ENCODE(272), SPR_SR | SPR_SW);
2167 /* SPRG1 (SPR 273) */
2168 spr_set_rights(SPR_ENCODE(273), SPR_SR | SPR_SW);
2169 /* SPRG2 (SPR 274) */
2170 spr_set_rights(SPR_ENCODE(274), SPR_SR | SPR_SW);
2171 /* SPRG3 (SPR 275) */
2172 spr_set_rights(SPR_ENCODE(275), SPR_SR | SPR_SW);
2174 spr_set_rights(SPR_ENCODE(281), SPR_SR | SPR_SW);
2176 spr_set_rights(SPR_ENCODE(282), SPR_SR | SPR_SW);
2177 /* IBAT0U (SPR 528) */
2178 spr_set_rights(SPR_ENCODE(528), SPR_SR | SPR_SW);
2179 /* IBAT0L (SPR 529) */
2180 spr_set_rights(SPR_ENCODE(529), SPR_SR | SPR_SW);
2181 /* IBAT1U (SPR 530) */
2182 spr_set_rights(SPR_ENCODE(530), SPR_SR | SPR_SW);
2183 /* IBAT1L (SPR 531) */
2184 spr_set_rights(SPR_ENCODE(531), SPR_SR | SPR_SW);
2185 /* IBAT2U (SPR 532) */
2186 spr_set_rights(SPR_ENCODE(532), SPR_SR | SPR_SW);
2187 /* IBAT2L (SPR 533) */
2188 spr_set_rights(SPR_ENCODE(533), SPR_SR | SPR_SW);
2189 /* IBAT3U (SPR 534) */
2190 spr_set_rights(SPR_ENCODE(534), SPR_SR | SPR_SW);
2191 /* IBAT3L (SPR 535) */
2192 spr_set_rights(SPR_ENCODE(535), SPR_SR | SPR_SW);
2193 /* DBAT0U (SPR 536) */
2194 spr_set_rights(SPR_ENCODE(536), SPR_SR | SPR_SW);
2195 /* DBAT0L (SPR 537) */
2196 spr_set_rights(SPR_ENCODE(537), SPR_SR | SPR_SW);
2197 /* DBAT1U (SPR 538) */
2198 spr_set_rights(SPR_ENCODE(538), SPR_SR | SPR_SW);
2199 /* DBAT1L (SPR 539) */
2200 spr_set_rights(SPR_ENCODE(539), SPR_SR | SPR_SW);
2201 /* DBAT2U (SPR 540) */
2202 spr_set_rights(SPR_ENCODE(540), SPR_SR | SPR_SW);
2203 /* DBAT2L (SPR 541) */
2204 spr_set_rights(SPR_ENCODE(541), SPR_SR | SPR_SW);
2205 /* DBAT3U (SPR 542) */
2206 spr_set_rights(SPR_ENCODE(542), SPR_SR | SPR_SW);
2207 /* DBAT3L (SPR 543) */
2208 spr_set_rights(SPR_ENCODE(543), SPR_SR | SPR_SW);
2209 /* DABR (SPR 1013) */
2210 spr_set_rights(SPR_ENCODE(1013), SPR_SR | SPR_SW);
2211 /* FPECR (SPR 1022) */
2212 spr_set_rights(SPR_ENCODE(1022), SPR_SR | SPR_SW);
2213 /* PIR (SPR 1023) */
2214 spr_set_rights(SPR_ENCODE(1023), SPR_SR | SPR_SW);
2216 spr_set_rights(SPR_ENCODE(287), SPR_SR);
2218 spr_set_rights(SPR_ENCODE(284), SPR_SW);
2220 spr_set_rights(SPR_ENCODE(285), SPR_SW);
2223 /* PPC "main stream" common instructions */
2224 #define PPC_COMMON (PPC_INTEGER | PPC_FLOAT | PPC_FLOW | PPC_MEM | \
2225 PPC_MISC | PPC_EXTERN | PPC_SEGMENT)
2227 typedef struct ppc_proc_t {
2232 typedef struct ppc_def_t {
2234 unsigned long pvr_mask;
2238 static ppc_proc_t ppc_proc_common = {
2239 .flags = PPC_COMMON,
2243 static ppc_def_t ppc_defs[] =
2248 .pvr_mask = 0x00000000,
2249 .proc = &ppc_proc_common,
2253 static int create_ppc_proc (unsigned long pvr)
2258 fill_new_table(ppc_opcodes, 0x40);
2259 for (i = 0; ; i++) {
2260 if ((ppc_defs[i].pvr & ppc_defs[i].pvr_mask) ==
2261 (pvr & ppc_defs[i].pvr_mask)) {
2262 flags = ppc_defs[i].proc->flags;
2267 for (opc = &opc_start + 1; opc != &opc_end; opc++) {
2268 if ((opc->type & flags) != 0)
2269 if (register_insn(opc) < 0) {
2270 fprintf(stderr, "*** ERROR initializing PPC instruction "
2271 "0x%02x 0x%02x 0x%02x\n", opc->opc1, opc->opc2,
2276 fix_opcode_tables();
2281 /*****************************************************************************/
2282 uint32_t do_load_xer (void);
2284 void cpu_ppc_dump_state(CPUPPCState *env, FILE *f, int flags)
2289 fprintf(logfile, "nip=0x%08x LR=0x%08x CTR=0x%08x XER=0x%08x\n",
2290 env->nip, env->LR, env->CTR, do_load_xer());
2291 for (i = 0; i < 32; i++) {
2293 fprintf(logfile, "GPR%02d:", i);
2294 fprintf(logfile, " %08x", env->gpr[i]);
2296 fprintf(logfile, "\n");
2298 fprintf(logfile, "CR: 0x");
2299 for (i = 0; i < 8; i++)
2300 fprintf(logfile, "%01x", env->crf[i]);
2301 fprintf(logfile, " [");
2302 for (i = 0; i < 8; i++) {
2305 if (env->crf[i] & 0x08)
2307 else if (env->crf[i] & 0x04)
2309 else if (env->crf[i] & 0x02)
2311 fprintf(logfile, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
2313 fprintf(logfile, " ] ");
2314 fprintf(logfile, "TB: 0x%08x %08x\n", env->spr[SPR_ENCODE(269)],
2315 env->spr[SPR_ENCODE(268)]);
2316 for (i = 0; i < 16; i++) {
2318 fprintf(logfile, "FPR%02d:", i);
2319 fprintf(logfile, " %016llx", *((uint64_t *)(&env->fpr[i])));
2321 fprintf(logfile, "\n");
2327 CPUPPCState *cpu_ppc_init(void)
2333 env = malloc(sizeof(CPUPPCState));
2336 memset(env, 0, sizeof(CPUPPCState));
2338 if (create_ppc_proc(0) < 0)
2345 void cpu_ppc_close(CPUPPCState *env)
2347 /* Should also remove all opcode tables... */
2351 int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
2355 opc_handler_t **table, *handler;
2357 uint16_t *gen_opc_end;
2362 gen_opc_ptr = gen_opc_buf;
2363 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
2364 gen_opparam_ptr = gen_opparam_buf;
2365 ctx.nip = (uint32_t *)pc_start;
2367 ctx.supervisor = msr_ip;
2371 while (ret == 0 && gen_opc_ptr < gen_opc_end) {
2374 fprintf(logfile, "Search PC...\n");
2375 j = gen_opc_ptr - gen_opc_buf;
2379 gen_opc_instr_start[lj++] = 0;
2380 gen_opc_pc[lj] = (uint32_t)ctx.nip;
2381 gen_opc_instr_start[lj] = 1;
2384 ctx.opcode = __be32_to_cpu(*ctx.nip);
2387 fprintf(logfile, "----------------\n");
2388 fprintf(logfile, "%p: translate opcode %08x\n",
2389 ctx.nip, ctx.opcode);
2393 table = ppc_opcodes;
2394 handler = table[opc1(ctx.opcode)];
2395 if (is_indirect_opcode(handler)) {
2396 table = ind_table(handler);
2397 handler = table[opc2(ctx.opcode)];
2398 if (is_indirect_opcode(handler)) {
2399 table = ind_table(handler);
2400 handler = table[opc3(ctx.opcode)];
2403 /* Is opcode *REALLY* valid ? */
2404 if ((ctx.opcode & handler->inval) != 0) {
2406 if (handler->handler == &gen_invalid) {
2407 fprintf(logfile, "invalid/unsupported opcode: "
2408 "%02x -%02x - %02x (%08x)\n", opc1(ctx.opcode),
2409 opc2(ctx.opcode), opc3(ctx.opcode), ctx.opcode);
2411 fprintf(logfile, "invalid bits: %08x for opcode: "
2412 "%02x -%02x - %02x (%p)\n",
2413 ctx.opcode & handler->inval, opc1(ctx.opcode),
2414 opc2(ctx.opcode), opc3(ctx.opcode),
2418 ret = GET_RETVAL(gen_invalid, ctx.opcode);
2420 ret = GET_RETVAL(*(handler->handler), ctx.opcode);
2423 #if defined (DO_SINGLE_STEP)
2427 #if defined (DO_STEP_FLUSH)
2430 /* We need to update the time base */
2432 gen_op_update_tb(ctx.tb_offset);
2433 /* If we are in step-by-step mode, do a branch to the next instruction
2434 * so the nip will be up-to-date
2436 #if defined (DO_SINGLE_STEP)
2438 gen_op_b((uint32_t)ctx.nip);
2442 /* If the exeption isn't a PPC one,
2445 if (ret != EXCP_BRANCH) {
2447 if ((ret & 0x2000) == 0)
2448 gen_op_raise_exception(ret);
2450 /* TO BE FIXED: T0 hasn't got a proper value, which makes tb_add_jump
2451 * do bad business and then qemu crashes !
2454 /* Generate the return instruction */
2456 *gen_opc_ptr = INDEX_op_end;
2458 tb->size = (uint32_t)ctx.nip - pc_start;
2461 // *gen_opc_ptr = INDEX_op_end;
2464 fprintf(logfile, "IN: %s\n", lookup_symbol((void *)pc_start));
2465 disas(logfile, (void *)pc_start, (uint32_t)ctx.nip - pc_start, 0, 0);
2466 fprintf(logfile, "\n");
2468 fprintf(logfile, "OP:\n");
2469 dump_ops(gen_opc_buf, gen_opparam_buf);
2470 fprintf(logfile, "\n");
2477 int gen_intermediate_code(CPUState *env, struct TranslationBlock *tb)
2479 return gen_intermediate_code_internal(env, tb, 0);
2482 int gen_intermediate_code_pc(CPUState *env, struct TranslationBlock *tb)
2484 return gen_intermediate_code_internal(env, tb, 1);