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
30 //#define DO_SINGLE_STEP
31 //#define PPC_DEBUG_DISAS
34 #define DEF(s, n, copy_size) INDEX_op_ ## s,
40 static uint16_t *gen_opc_ptr;
41 static uint32_t *gen_opparam_ptr;
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) \
52 NAME ## _table[n](); \
55 #define GEN16(func, NAME) \
56 static GenOpFunc *NAME ## _table [16] = { \
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, \
62 static inline void func(int n) \
64 NAME ## _table[n](); \
67 #define GEN32(func, NAME) \
68 static GenOpFunc *NAME ## _table [32] = { \
69 NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3, \
70 NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7, \
71 NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11, \
72 NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15, \
73 NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19, \
74 NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23, \
75 NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27, \
76 NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31, \
78 static inline void func(int n) \
80 NAME ## _table[n](); \
83 /* Condition register moves */
84 GEN8(gen_op_load_crf_T0, gen_op_load_crf_T0_crf);
85 GEN8(gen_op_load_crf_T1, gen_op_load_crf_T1_crf);
86 GEN8(gen_op_store_T0_crf, gen_op_store_T0_crf_crf);
87 GEN8(gen_op_store_T1_crf, gen_op_store_T1_crf_crf);
89 /* Floating point condition and status register moves */
90 GEN8(gen_op_load_fpscr_T0, gen_op_load_fpscr_T0_fpscr);
91 GEN8(gen_op_store_T0_fpscr, gen_op_store_T0_fpscr_fpscr);
92 GEN8(gen_op_clear_fpscr, gen_op_clear_fpscr_fpscr);
93 static GenOpFunc1 *gen_op_store_T0_fpscri_fpscr_table[8] = {
94 &gen_op_store_T0_fpscri_fpscr0,
95 &gen_op_store_T0_fpscri_fpscr1,
96 &gen_op_store_T0_fpscri_fpscr2,
97 &gen_op_store_T0_fpscri_fpscr3,
98 &gen_op_store_T0_fpscri_fpscr4,
99 &gen_op_store_T0_fpscri_fpscr5,
100 &gen_op_store_T0_fpscri_fpscr6,
101 &gen_op_store_T0_fpscri_fpscr7,
103 static inline void gen_op_store_T0_fpscri(int n, uint8_t param)
105 (*gen_op_store_T0_fpscri_fpscr_table[n])(param);
108 /* Segment register moves */
109 GEN16(gen_op_load_sr, gen_op_load_sr);
110 GEN16(gen_op_store_sr, gen_op_store_sr);
112 /* General purpose registers moves */
113 GEN32(gen_op_load_gpr_T0, gen_op_load_gpr_T0_gpr);
114 GEN32(gen_op_load_gpr_T1, gen_op_load_gpr_T1_gpr);
115 GEN32(gen_op_load_gpr_T2, gen_op_load_gpr_T2_gpr);
117 GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr);
118 GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr);
119 GEN32(gen_op_store_T2_gpr, gen_op_store_T2_gpr_gpr);
121 /* floating point registers moves */
122 GEN32(gen_op_load_fpr_FT0, gen_op_load_fpr_FT0_fpr);
123 GEN32(gen_op_load_fpr_FT1, gen_op_load_fpr_FT1_fpr);
124 GEN32(gen_op_load_fpr_FT2, gen_op_load_fpr_FT2_fpr);
125 GEN32(gen_op_store_FT0_fpr, gen_op_store_FT0_fpr_fpr);
126 GEN32(gen_op_store_FT1_fpr, gen_op_store_FT1_fpr_fpr);
127 GEN32(gen_op_store_FT2_fpr, gen_op_store_FT2_fpr_fpr);
129 static uint8_t spr_access[1024 / 2];
131 /* internal defines */
132 typedef struct DisasContext {
133 struct TranslationBlock *tb;
137 /* Routine used to access memory */
139 /* Translation flags */
140 #if !defined(CONFIG_USER_ONLY)
146 typedef struct opc_handler_t {
149 /* instruction type */
152 void (*handler)(DisasContext *ctx);
155 #define RET_EXCP(ctx, excp, error) \
157 if ((ctx)->exception == EXCP_NONE) { \
158 gen_op_update_nip((ctx)->nip); \
160 gen_op_raise_exception_err((excp), (error)); \
161 ctx->exception = (excp); \
164 #define RET_INVAL(ctx) \
165 RET_EXCP((ctx), EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_INVAL)
167 #define RET_PRIVOPC(ctx) \
168 RET_EXCP((ctx), EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_OPC)
170 #define RET_PRIVREG(ctx) \
171 RET_EXCP((ctx), EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_REG)
173 #define RET_MTMSR(ctx) \
174 RET_EXCP((ctx), EXCP_MTMSR, 0)
176 #define GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \
177 static void gen_##name (DisasContext *ctx); \
178 GEN_OPCODE(name, opc1, opc2, opc3, inval, type); \
179 static void gen_##name (DisasContext *ctx)
181 typedef struct opcode_t {
182 unsigned char opc1, opc2, opc3;
183 #if HOST_LONG_BITS == 64 /* Explicitely align to 64 bits */
184 unsigned char pad[5];
186 unsigned char pad[1];
188 opc_handler_t handler;
191 /*** Instruction decoding ***/
192 #define EXTRACT_HELPER(name, shift, nb) \
193 static inline uint32_t name (uint32_t opcode) \
195 return (opcode >> (shift)) & ((1 << (nb)) - 1); \
198 #define EXTRACT_SHELPER(name, shift, nb) \
199 static inline int32_t name (uint32_t opcode) \
201 return (int16_t)((opcode >> (shift)) & ((1 << (nb)) - 1)); \
205 EXTRACT_HELPER(opc1, 26, 6);
207 EXTRACT_HELPER(opc2, 1, 5);
209 EXTRACT_HELPER(opc3, 6, 5);
210 /* Update Cr0 flags */
211 EXTRACT_HELPER(Rc, 0, 1);
213 EXTRACT_HELPER(rD, 21, 5);
215 EXTRACT_HELPER(rS, 21, 5);
217 EXTRACT_HELPER(rA, 16, 5);
219 EXTRACT_HELPER(rB, 11, 5);
221 EXTRACT_HELPER(rC, 6, 5);
223 EXTRACT_HELPER(crfD, 23, 3);
224 EXTRACT_HELPER(crfS, 18, 3);
225 EXTRACT_HELPER(crbD, 21, 5);
226 EXTRACT_HELPER(crbA, 16, 5);
227 EXTRACT_HELPER(crbB, 11, 5);
229 EXTRACT_HELPER(SPR, 11, 10);
230 /*** Get constants ***/
231 EXTRACT_HELPER(IMM, 12, 8);
232 /* 16 bits signed immediate value */
233 EXTRACT_SHELPER(SIMM, 0, 16);
234 /* 16 bits unsigned immediate value */
235 EXTRACT_HELPER(UIMM, 0, 16);
237 EXTRACT_HELPER(NB, 11, 5);
239 EXTRACT_HELPER(SH, 11, 5);
241 EXTRACT_HELPER(MB, 6, 5);
243 EXTRACT_HELPER(ME, 1, 5);
245 EXTRACT_HELPER(TO, 21, 5);
247 EXTRACT_HELPER(CRM, 12, 8);
248 EXTRACT_HELPER(FM, 17, 8);
249 EXTRACT_HELPER(SR, 16, 4);
250 EXTRACT_HELPER(FPIMM, 20, 4);
252 /*** Jump target decoding ***/
254 EXTRACT_SHELPER(d, 0, 16);
255 /* Immediate address */
256 static inline uint32_t LI (uint32_t opcode)
258 return (opcode >> 0) & 0x03FFFFFC;
261 static inline uint32_t BD (uint32_t opcode)
263 return (opcode >> 0) & 0xFFFC;
266 EXTRACT_HELPER(BO, 21, 5);
267 EXTRACT_HELPER(BI, 16, 5);
268 /* Absolute/relative address */
269 EXTRACT_HELPER(AA, 1, 1);
271 EXTRACT_HELPER(LK, 0, 1);
273 /* Create a mask between <start> and <end> bits */
274 static inline uint32_t MASK (uint32_t start, uint32_t end)
278 ret = (((uint32_t)(-1)) >> (start)) ^ (((uint32_t)(-1) >> (end)) >> 1);
285 #if defined(__APPLE__)
286 #define OPCODES_SECTION \
287 __attribute__ ((section("__TEXT,__opcodes"), unused, aligned (8) ))
289 #define OPCODES_SECTION \
290 __attribute__ ((section(".opcodes"), unused, aligned (8) ))
293 #define GEN_OPCODE(name, op1, op2, op3, invl, _typ) \
294 OPCODES_SECTION opcode_t opc_##name = { \
302 .handler = &gen_##name, \
306 #define GEN_OPCODE_MARK(name) \
307 OPCODES_SECTION opcode_t opc_##name = { \
313 .inval = 0x00000000, \
319 /* Start opcode list */
320 GEN_OPCODE_MARK(start);
322 /* Invalid instruction */
323 GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE)
328 /* Special opcode to stop emulation */
329 GEN_HANDLER(stop, 0x06, 0x00, 0xFF, 0x03FFFFC1, PPC_COMMON)
331 RET_EXCP(ctx, EXCP_HLT, 0);
334 static opc_handler_t invalid_handler = {
337 .handler = gen_invalid,
340 /*** Integer arithmetic ***/
341 #define __GEN_INT_ARITH2(name, opc1, opc2, opc3, inval) \
342 GEN_HANDLER(name, opc1, opc2, opc3, inval, PPC_INTEGER) \
344 gen_op_load_gpr_T0(rA(ctx->opcode)); \
345 gen_op_load_gpr_T1(rB(ctx->opcode)); \
347 if (Rc(ctx->opcode) != 0) \
349 gen_op_store_T0_gpr(rD(ctx->opcode)); \
352 #define __GEN_INT_ARITH2_O(name, opc1, opc2, opc3, inval) \
353 GEN_HANDLER(name, opc1, opc2, opc3, inval, PPC_INTEGER) \
355 gen_op_load_gpr_T0(rA(ctx->opcode)); \
356 gen_op_load_gpr_T1(rB(ctx->opcode)); \
358 if (Rc(ctx->opcode) != 0) \
360 gen_op_store_T0_gpr(rD(ctx->opcode)); \
363 #define __GEN_INT_ARITH1(name, opc1, opc2, opc3) \
364 GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, PPC_INTEGER) \
366 gen_op_load_gpr_T0(rA(ctx->opcode)); \
368 if (Rc(ctx->opcode) != 0) \
370 gen_op_store_T0_gpr(rD(ctx->opcode)); \
372 #define __GEN_INT_ARITH1_O(name, opc1, opc2, opc3) \
373 GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, PPC_INTEGER) \
375 gen_op_load_gpr_T0(rA(ctx->opcode)); \
377 if (Rc(ctx->opcode) != 0) \
379 gen_op_store_T0_gpr(rD(ctx->opcode)); \
382 /* Two operands arithmetic functions */
383 #define GEN_INT_ARITH2(name, opc1, opc2, opc3) \
384 __GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000000) \
385 __GEN_INT_ARITH2_O(name##o, opc1, opc2, opc3 | 0x10, 0x00000000)
387 /* Two operands arithmetic functions with no overflow allowed */
388 #define GEN_INT_ARITHN(name, opc1, opc2, opc3) \
389 __GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000400)
391 /* One operand arithmetic functions */
392 #define GEN_INT_ARITH1(name, opc1, opc2, opc3) \
393 __GEN_INT_ARITH1(name, opc1, opc2, opc3) \
394 __GEN_INT_ARITH1_O(name##o, opc1, opc2, opc3 | 0x10)
396 /* add add. addo addo. */
397 GEN_INT_ARITH2 (add, 0x1F, 0x0A, 0x08);
398 /* addc addc. addco addco. */
399 GEN_INT_ARITH2 (addc, 0x1F, 0x0A, 0x00);
400 /* adde adde. addeo addeo. */
401 GEN_INT_ARITH2 (adde, 0x1F, 0x0A, 0x04);
402 /* addme addme. addmeo addmeo. */
403 GEN_INT_ARITH1 (addme, 0x1F, 0x0A, 0x07);
404 /* addze addze. addzeo addzeo. */
405 GEN_INT_ARITH1 (addze, 0x1F, 0x0A, 0x06);
406 /* divw divw. divwo divwo. */
407 GEN_INT_ARITH2 (divw, 0x1F, 0x0B, 0x0F);
408 /* divwu divwu. divwuo divwuo. */
409 GEN_INT_ARITH2 (divwu, 0x1F, 0x0B, 0x0E);
411 GEN_INT_ARITHN (mulhw, 0x1F, 0x0B, 0x02);
413 GEN_INT_ARITHN (mulhwu, 0x1F, 0x0B, 0x00);
414 /* mullw mullw. mullwo mullwo. */
415 GEN_INT_ARITH2 (mullw, 0x1F, 0x0B, 0x07);
416 /* neg neg. nego nego. */
417 GEN_INT_ARITH1 (neg, 0x1F, 0x08, 0x03);
418 /* subf subf. subfo subfo. */
419 GEN_INT_ARITH2 (subf, 0x1F, 0x08, 0x01);
420 /* subfc subfc. subfco subfco. */
421 GEN_INT_ARITH2 (subfc, 0x1F, 0x08, 0x00);
422 /* subfe subfe. subfeo subfeo. */
423 GEN_INT_ARITH2 (subfe, 0x1F, 0x08, 0x04);
424 /* subfme subfme. subfmeo subfmeo. */
425 GEN_INT_ARITH1 (subfme, 0x1F, 0x08, 0x07);
426 /* subfze subfze. subfzeo subfzeo. */
427 GEN_INT_ARITH1 (subfze, 0x1F, 0x08, 0x06);
429 GEN_HANDLER(addi, 0x0E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
431 int32_t simm = SIMM(ctx->opcode);
433 if (rA(ctx->opcode) == 0) {
436 gen_op_load_gpr_T0(rA(ctx->opcode));
439 gen_op_store_T0_gpr(rD(ctx->opcode));
442 GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
444 gen_op_load_gpr_T0(rA(ctx->opcode));
445 gen_op_addic(SIMM(ctx->opcode));
446 gen_op_store_T0_gpr(rD(ctx->opcode));
449 GEN_HANDLER(addic_, 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
451 gen_op_load_gpr_T0(rA(ctx->opcode));
452 gen_op_addic(SIMM(ctx->opcode));
454 gen_op_store_T0_gpr(rD(ctx->opcode));
457 GEN_HANDLER(addis, 0x0F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
459 int32_t simm = SIMM(ctx->opcode);
461 if (rA(ctx->opcode) == 0) {
462 gen_op_set_T0(simm << 16);
464 gen_op_load_gpr_T0(rA(ctx->opcode));
465 gen_op_addi(simm << 16);
467 gen_op_store_T0_gpr(rD(ctx->opcode));
470 GEN_HANDLER(mulli, 0x07, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
472 gen_op_load_gpr_T0(rA(ctx->opcode));
473 gen_op_mulli(SIMM(ctx->opcode));
474 gen_op_store_T0_gpr(rD(ctx->opcode));
477 GEN_HANDLER(subfic, 0x08, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
479 gen_op_load_gpr_T0(rA(ctx->opcode));
480 gen_op_subfic(SIMM(ctx->opcode));
481 gen_op_store_T0_gpr(rD(ctx->opcode));
484 /*** Integer comparison ***/
485 #define GEN_CMP(name, opc) \
486 GEN_HANDLER(name, 0x1F, 0x00, opc, 0x00400000, PPC_INTEGER) \
488 gen_op_load_gpr_T0(rA(ctx->opcode)); \
489 gen_op_load_gpr_T1(rB(ctx->opcode)); \
491 gen_op_store_T0_crf(crfD(ctx->opcode)); \
497 GEN_HANDLER(cmpi, 0x0B, 0xFF, 0xFF, 0x00400000, PPC_INTEGER)
499 gen_op_load_gpr_T0(rA(ctx->opcode));
500 gen_op_cmpi(SIMM(ctx->opcode));
501 gen_op_store_T0_crf(crfD(ctx->opcode));
506 GEN_HANDLER(cmpli, 0x0A, 0xFF, 0xFF, 0x00400000, PPC_INTEGER)
508 gen_op_load_gpr_T0(rA(ctx->opcode));
509 gen_op_cmpli(UIMM(ctx->opcode));
510 gen_op_store_T0_crf(crfD(ctx->opcode));
513 /*** Integer logical ***/
514 #define __GEN_LOGICAL2(name, opc2, opc3) \
515 GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000000, PPC_INTEGER) \
517 gen_op_load_gpr_T0(rS(ctx->opcode)); \
518 gen_op_load_gpr_T1(rB(ctx->opcode)); \
520 if (Rc(ctx->opcode) != 0) \
522 gen_op_store_T0_gpr(rA(ctx->opcode)); \
524 #define GEN_LOGICAL2(name, opc) \
525 __GEN_LOGICAL2(name, 0x1C, opc)
527 #define GEN_LOGICAL1(name, opc) \
528 GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, PPC_INTEGER) \
530 gen_op_load_gpr_T0(rS(ctx->opcode)); \
532 if (Rc(ctx->opcode) != 0) \
534 gen_op_store_T0_gpr(rA(ctx->opcode)); \
538 GEN_LOGICAL2(and, 0x00);
540 GEN_LOGICAL2(andc, 0x01);
542 GEN_HANDLER(andi_, 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
544 gen_op_load_gpr_T0(rS(ctx->opcode));
545 gen_op_andi_(UIMM(ctx->opcode));
547 gen_op_store_T0_gpr(rA(ctx->opcode));
550 GEN_HANDLER(andis_, 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
552 gen_op_load_gpr_T0(rS(ctx->opcode));
553 gen_op_andi_(UIMM(ctx->opcode) << 16);
555 gen_op_store_T0_gpr(rA(ctx->opcode));
559 GEN_LOGICAL1(cntlzw, 0x00);
561 GEN_LOGICAL2(eqv, 0x08);
563 GEN_LOGICAL1(extsb, 0x1D);
565 GEN_LOGICAL1(extsh, 0x1C);
567 GEN_LOGICAL2(nand, 0x0E);
569 GEN_LOGICAL2(nor, 0x03);
572 GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER)
574 gen_op_load_gpr_T0(rS(ctx->opcode));
575 /* Optimisation for mr case */
576 if (rS(ctx->opcode) != rB(ctx->opcode)) {
577 gen_op_load_gpr_T1(rB(ctx->opcode));
580 if (Rc(ctx->opcode) != 0)
582 gen_op_store_T0_gpr(rA(ctx->opcode));
586 GEN_LOGICAL2(orc, 0x0C);
588 GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER)
590 gen_op_load_gpr_T0(rS(ctx->opcode));
591 /* Optimisation for "set to zero" case */
592 if (rS(ctx->opcode) != rB(ctx->opcode)) {
593 gen_op_load_gpr_T1(rB(ctx->opcode));
598 if (Rc(ctx->opcode) != 0)
600 gen_op_store_T0_gpr(rA(ctx->opcode));
603 GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
605 uint32_t uimm = UIMM(ctx->opcode);
607 if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
611 gen_op_load_gpr_T0(rS(ctx->opcode));
614 gen_op_store_T0_gpr(rA(ctx->opcode));
617 GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
619 uint32_t uimm = UIMM(ctx->opcode);
621 if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
625 gen_op_load_gpr_T0(rS(ctx->opcode));
627 gen_op_ori(uimm << 16);
628 gen_op_store_T0_gpr(rA(ctx->opcode));
631 GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
633 uint32_t uimm = UIMM(ctx->opcode);
635 if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
639 gen_op_load_gpr_T0(rS(ctx->opcode));
642 gen_op_store_T0_gpr(rA(ctx->opcode));
646 GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
648 uint32_t uimm = UIMM(ctx->opcode);
650 if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
654 gen_op_load_gpr_T0(rS(ctx->opcode));
656 gen_op_xori(uimm << 16);
657 gen_op_store_T0_gpr(rA(ctx->opcode));
660 /*** Integer rotate ***/
661 /* rlwimi & rlwimi. */
662 GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
666 mb = MB(ctx->opcode);
667 me = ME(ctx->opcode);
668 gen_op_load_gpr_T0(rS(ctx->opcode));
669 gen_op_load_gpr_T1(rA(ctx->opcode));
670 gen_op_rlwimi(SH(ctx->opcode), MASK(mb, me), ~MASK(mb, me));
671 if (Rc(ctx->opcode) != 0)
673 gen_op_store_T0_gpr(rA(ctx->opcode));
675 /* rlwinm & rlwinm. */
676 GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
680 sh = SH(ctx->opcode);
681 mb = MB(ctx->opcode);
682 me = ME(ctx->opcode);
683 gen_op_load_gpr_T0(rS(ctx->opcode));
686 gen_op_andi_(MASK(mb, me));
695 } else if (me == (31 - sh)) {
700 } else if (me == 31) {
702 if (sh == (32 - mb)) {
708 gen_op_rlwinm(sh, MASK(mb, me));
710 if (Rc(ctx->opcode) != 0)
712 gen_op_store_T0_gpr(rA(ctx->opcode));
715 GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
719 mb = MB(ctx->opcode);
720 me = ME(ctx->opcode);
721 gen_op_load_gpr_T0(rS(ctx->opcode));
722 gen_op_load_gpr_T1(rB(ctx->opcode));
723 if (mb == 0 && me == 31) {
727 gen_op_rlwnm(MASK(mb, me));
729 if (Rc(ctx->opcode) != 0)
731 gen_op_store_T0_gpr(rA(ctx->opcode));
734 /*** Integer shift ***/
736 __GEN_LOGICAL2(slw, 0x18, 0x00);
738 __GEN_LOGICAL2(sraw, 0x18, 0x18);
740 GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER)
742 gen_op_load_gpr_T0(rS(ctx->opcode));
743 if (SH(ctx->opcode) != 0)
744 gen_op_srawi(SH(ctx->opcode), MASK(32 - SH(ctx->opcode), 31));
745 if (Rc(ctx->opcode) != 0)
747 gen_op_store_T0_gpr(rA(ctx->opcode));
750 __GEN_LOGICAL2(srw, 0x18, 0x10);
752 /*** Floating-Point arithmetic ***/
753 #define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat) \
754 GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, PPC_FLOAT) \
756 if (!ctx->fpu_enabled) { \
757 RET_EXCP(ctx, EXCP_NO_FP, 0); \
760 gen_op_reset_scrfx(); \
761 gen_op_load_fpr_FT0(rA(ctx->opcode)); \
762 gen_op_load_fpr_FT1(rC(ctx->opcode)); \
763 gen_op_load_fpr_FT2(rB(ctx->opcode)); \
768 gen_op_store_FT0_fpr(rD(ctx->opcode)); \
769 if (Rc(ctx->opcode)) \
773 #define GEN_FLOAT_ACB(name, op2) \
774 _GEN_FLOAT_ACB(name, name, 0x3F, op2, 0); \
775 _GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1);
777 #define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat) \
778 GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT) \
780 if (!ctx->fpu_enabled) { \
781 RET_EXCP(ctx, EXCP_NO_FP, 0); \
784 gen_op_reset_scrfx(); \
785 gen_op_load_fpr_FT0(rA(ctx->opcode)); \
786 gen_op_load_fpr_FT1(rB(ctx->opcode)); \
791 gen_op_store_FT0_fpr(rD(ctx->opcode)); \
792 if (Rc(ctx->opcode)) \
795 #define GEN_FLOAT_AB(name, op2, inval) \
796 _GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0); \
797 _GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1);
799 #define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat) \
800 GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT) \
802 if (!ctx->fpu_enabled) { \
803 RET_EXCP(ctx, EXCP_NO_FP, 0); \
806 gen_op_reset_scrfx(); \
807 gen_op_load_fpr_FT0(rA(ctx->opcode)); \
808 gen_op_load_fpr_FT1(rC(ctx->opcode)); \
813 gen_op_store_FT0_fpr(rD(ctx->opcode)); \
814 if (Rc(ctx->opcode)) \
817 #define GEN_FLOAT_AC(name, op2, inval) \
818 _GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0); \
819 _GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1);
821 #define GEN_FLOAT_B(name, op2, op3) \
822 GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, PPC_FLOAT) \
824 if (!ctx->fpu_enabled) { \
825 RET_EXCP(ctx, EXCP_NO_FP, 0); \
828 gen_op_reset_scrfx(); \
829 gen_op_load_fpr_FT0(rB(ctx->opcode)); \
831 gen_op_store_FT0_fpr(rD(ctx->opcode)); \
832 if (Rc(ctx->opcode)) \
836 #define GEN_FLOAT_BS(name, op1, op2) \
837 GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, PPC_FLOAT) \
839 if (!ctx->fpu_enabled) { \
840 RET_EXCP(ctx, EXCP_NO_FP, 0); \
843 gen_op_reset_scrfx(); \
844 gen_op_load_fpr_FT0(rB(ctx->opcode)); \
846 gen_op_store_FT0_fpr(rD(ctx->opcode)); \
847 if (Rc(ctx->opcode)) \
852 GEN_FLOAT_AB(add, 0x15, 0x000007C0);
854 GEN_FLOAT_AB(div, 0x12, 0x000007C0);
856 GEN_FLOAT_AC(mul, 0x19, 0x0000F800);
859 GEN_FLOAT_BS(res, 0x3B, 0x18);
862 GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A);
865 _GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0);
867 GEN_FLOAT_AB(sub, 0x14, 0x000007C0);
870 GEN_FLOAT_BS(sqrt, 0x3F, 0x16);
872 GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_OPT)
874 if (!ctx->fpu_enabled) {
875 RET_EXCP(ctx, EXCP_NO_FP, 0);
878 gen_op_reset_scrfx();
879 gen_op_load_fpr_FT0(rB(ctx->opcode));
882 gen_op_store_FT0_fpr(rD(ctx->opcode));
887 /*** Floating-Point multiply-and-add ***/
889 GEN_FLOAT_ACB(madd, 0x1D);
891 GEN_FLOAT_ACB(msub, 0x1C);
892 /* fnmadd - fnmadds */
893 GEN_FLOAT_ACB(nmadd, 0x1F);
894 /* fnmsub - fnmsubs */
895 GEN_FLOAT_ACB(nmsub, 0x1E);
897 /*** Floating-Point round & convert ***/
899 GEN_FLOAT_B(ctiw, 0x0E, 0x00);
901 GEN_FLOAT_B(ctiwz, 0x0F, 0x00);
903 GEN_FLOAT_B(rsp, 0x0C, 0x00);
905 /*** Floating-Point compare ***/
907 GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT)
909 if (!ctx->fpu_enabled) {
910 RET_EXCP(ctx, EXCP_NO_FP, 0);
913 gen_op_reset_scrfx();
914 gen_op_load_fpr_FT0(rA(ctx->opcode));
915 gen_op_load_fpr_FT1(rB(ctx->opcode));
917 gen_op_store_T0_crf(crfD(ctx->opcode));
921 GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT)
923 if (!ctx->fpu_enabled) {
924 RET_EXCP(ctx, EXCP_NO_FP, 0);
927 gen_op_reset_scrfx();
928 gen_op_load_fpr_FT0(rA(ctx->opcode));
929 gen_op_load_fpr_FT1(rB(ctx->opcode));
931 gen_op_store_T0_crf(crfD(ctx->opcode));
934 /*** Floating-point move ***/
936 GEN_FLOAT_B(abs, 0x08, 0x08);
939 GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT)
941 if (!ctx->fpu_enabled) {
942 RET_EXCP(ctx, EXCP_NO_FP, 0);
945 gen_op_reset_scrfx();
946 gen_op_load_fpr_FT0(rB(ctx->opcode));
947 gen_op_store_FT0_fpr(rD(ctx->opcode));
953 GEN_FLOAT_B(nabs, 0x08, 0x04);
955 GEN_FLOAT_B(neg, 0x08, 0x01);
957 /*** Floating-Point status & ctrl register ***/
959 GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT)
961 if (!ctx->fpu_enabled) {
962 RET_EXCP(ctx, EXCP_NO_FP, 0);
965 gen_op_load_fpscr_T0(crfS(ctx->opcode));
966 gen_op_store_T0_crf(crfD(ctx->opcode));
967 gen_op_clear_fpscr(crfS(ctx->opcode));
971 GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT)
973 if (!ctx->fpu_enabled) {
974 RET_EXCP(ctx, EXCP_NO_FP, 0);
978 gen_op_store_FT0_fpr(rD(ctx->opcode));
984 GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT)
988 if (!ctx->fpu_enabled) {
989 RET_EXCP(ctx, EXCP_NO_FP, 0);
992 crb = crbD(ctx->opcode) >> 2;
993 gen_op_load_fpscr_T0(crb);
994 gen_op_andi_(~(1 << (crbD(ctx->opcode) & 0x03)));
995 gen_op_store_T0_fpscr(crb);
1001 GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT)
1005 if (!ctx->fpu_enabled) {
1006 RET_EXCP(ctx, EXCP_NO_FP, 0);
1009 crb = crbD(ctx->opcode) >> 2;
1010 gen_op_load_fpscr_T0(crb);
1011 gen_op_ori(1 << (crbD(ctx->opcode) & 0x03));
1012 gen_op_store_T0_fpscr(crb);
1013 if (Rc(ctx->opcode))
1018 GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT)
1020 if (!ctx->fpu_enabled) {
1021 RET_EXCP(ctx, EXCP_NO_FP, 0);
1024 gen_op_load_fpr_FT0(rB(ctx->opcode));
1025 gen_op_store_fpscr(FM(ctx->opcode));
1026 if (Rc(ctx->opcode))
1031 GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT)
1033 if (!ctx->fpu_enabled) {
1034 RET_EXCP(ctx, EXCP_NO_FP, 0);
1037 gen_op_store_T0_fpscri(crbD(ctx->opcode) >> 2, FPIMM(ctx->opcode));
1038 if (Rc(ctx->opcode))
1042 /*** Integer load ***/
1043 #if defined(CONFIG_USER_ONLY)
1044 #define op_ldst(name) gen_op_##name##_raw()
1045 #define OP_LD_TABLE(width)
1046 #define OP_ST_TABLE(width)
1048 #define op_ldst(name) (*gen_op_##name[ctx->mem_idx])()
1049 #define OP_LD_TABLE(width) \
1050 static GenOpFunc *gen_op_l##width[] = { \
1051 &gen_op_l##width##_user, \
1052 &gen_op_l##width##_kernel, \
1054 #define OP_ST_TABLE(width) \
1055 static GenOpFunc *gen_op_st##width[] = { \
1056 &gen_op_st##width##_user, \
1057 &gen_op_st##width##_kernel, \
1061 #define GEN_LD(width, opc) \
1062 GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) \
1064 uint32_t simm = SIMM(ctx->opcode); \
1065 if (rA(ctx->opcode) == 0) { \
1066 gen_op_set_T0(simm); \
1068 gen_op_load_gpr_T0(rA(ctx->opcode)); \
1070 gen_op_addi(simm); \
1072 op_ldst(l##width); \
1073 gen_op_store_T1_gpr(rD(ctx->opcode)); \
1076 #define GEN_LDU(width, opc) \
1077 GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) \
1079 uint32_t simm = SIMM(ctx->opcode); \
1080 if (rA(ctx->opcode) == 0 || \
1081 rA(ctx->opcode) == rD(ctx->opcode)) { \
1085 gen_op_load_gpr_T0(rA(ctx->opcode)); \
1087 gen_op_addi(simm); \
1088 op_ldst(l##width); \
1089 gen_op_store_T1_gpr(rD(ctx->opcode)); \
1090 gen_op_store_T0_gpr(rA(ctx->opcode)); \
1093 #define GEN_LDUX(width, opc) \
1094 GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_INTEGER) \
1096 if (rA(ctx->opcode) == 0 || \
1097 rA(ctx->opcode) == rD(ctx->opcode)) { \
1101 gen_op_load_gpr_T0(rA(ctx->opcode)); \
1102 gen_op_load_gpr_T1(rB(ctx->opcode)); \
1104 op_ldst(l##width); \
1105 gen_op_store_T1_gpr(rD(ctx->opcode)); \
1106 gen_op_store_T0_gpr(rA(ctx->opcode)); \
1109 #define GEN_LDX(width, opc2, opc3) \
1110 GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_INTEGER) \
1112 if (rA(ctx->opcode) == 0) { \
1113 gen_op_load_gpr_T0(rB(ctx->opcode)); \
1115 gen_op_load_gpr_T0(rA(ctx->opcode)); \
1116 gen_op_load_gpr_T1(rB(ctx->opcode)); \
1119 op_ldst(l##width); \
1120 gen_op_store_T1_gpr(rD(ctx->opcode)); \
1123 #define GEN_LDS(width, op) \
1124 OP_LD_TABLE(width); \
1125 GEN_LD(width, op | 0x20); \
1126 GEN_LDU(width, op | 0x21); \
1127 GEN_LDUX(width, op | 0x01); \
1128 GEN_LDX(width, 0x17, op | 0x00)
1130 /* lbz lbzu lbzux lbzx */
1132 /* lha lhau lhaux lhax */
1134 /* lhz lhzu lhzux lhzx */
1136 /* lwz lwzu lwzux lwzx */
1139 /*** Integer store ***/
1140 #define GEN_ST(width, opc) \
1141 GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) \
1143 uint32_t simm = SIMM(ctx->opcode); \
1144 if (rA(ctx->opcode) == 0) { \
1145 gen_op_set_T0(simm); \
1147 gen_op_load_gpr_T0(rA(ctx->opcode)); \
1149 gen_op_addi(simm); \
1151 gen_op_load_gpr_T1(rS(ctx->opcode)); \
1152 op_ldst(st##width); \
1155 #define GEN_STU(width, opc) \
1156 GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) \
1158 uint32_t simm = SIMM(ctx->opcode); \
1159 if (rA(ctx->opcode) == 0) { \
1163 gen_op_load_gpr_T0(rA(ctx->opcode)); \
1165 gen_op_addi(simm); \
1166 gen_op_load_gpr_T1(rS(ctx->opcode)); \
1167 op_ldst(st##width); \
1168 gen_op_store_T0_gpr(rA(ctx->opcode)); \
1171 #define GEN_STUX(width, opc) \
1172 GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_INTEGER) \
1174 if (rA(ctx->opcode) == 0) { \
1178 gen_op_load_gpr_T0(rA(ctx->opcode)); \
1179 gen_op_load_gpr_T1(rB(ctx->opcode)); \
1181 gen_op_load_gpr_T1(rS(ctx->opcode)); \
1182 op_ldst(st##width); \
1183 gen_op_store_T0_gpr(rA(ctx->opcode)); \
1186 #define GEN_STX(width, opc2, opc3) \
1187 GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_INTEGER) \
1189 if (rA(ctx->opcode) == 0) { \
1190 gen_op_load_gpr_T0(rB(ctx->opcode)); \
1192 gen_op_load_gpr_T0(rA(ctx->opcode)); \
1193 gen_op_load_gpr_T1(rB(ctx->opcode)); \
1196 gen_op_load_gpr_T1(rS(ctx->opcode)); \
1197 op_ldst(st##width); \
1200 #define GEN_STS(width, op) \
1201 OP_ST_TABLE(width); \
1202 GEN_ST(width, op | 0x20); \
1203 GEN_STU(width, op | 0x21); \
1204 GEN_STUX(width, op | 0x01); \
1205 GEN_STX(width, 0x17, op | 0x00)
1207 /* stb stbu stbux stbx */
1209 /* sth sthu sthux sthx */
1211 /* stw stwu stwux stwx */
1214 /*** Integer load and store with byte reverse ***/
1217 GEN_LDX(hbr, 0x16, 0x18);
1220 GEN_LDX(wbr, 0x16, 0x10);
1223 GEN_STX(hbr, 0x16, 0x1C);
1226 GEN_STX(wbr, 0x16, 0x14);
1228 /*** Integer load and store multiple ***/
1229 #if defined(CONFIG_USER_ONLY)
1230 #define op_ldstm(name, reg) gen_op_##name##_raw(reg)
1232 #define op_ldstm(name, reg) (*gen_op_##name[ctx->mem_idx])(reg)
1233 static GenOpFunc1 *gen_op_lmw[] = {
1237 static GenOpFunc1 *gen_op_stmw[] = {
1239 &gen_op_stmw_kernel,
1244 GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1246 int simm = SIMM(ctx->opcode);
1248 if (rA(ctx->opcode) == 0) {
1249 gen_op_set_T0(simm);
1251 gen_op_load_gpr_T0(rA(ctx->opcode));
1255 op_ldstm(lmw, rD(ctx->opcode));
1259 GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1261 int simm = SIMM(ctx->opcode);
1263 if (rA(ctx->opcode) == 0) {
1264 gen_op_set_T0(simm);
1266 gen_op_load_gpr_T0(rA(ctx->opcode));
1270 op_ldstm(stmw, rS(ctx->opcode));
1273 /*** Integer load and store strings ***/
1274 #if defined(CONFIG_USER_ONLY)
1275 #define op_ldsts(name, start) gen_op_##name##_raw(start)
1276 #define op_ldstsx(name, rd, ra, rb) gen_op_##name##_raw(rd, ra, rb)
1278 #define op_ldsts(name, start) (*gen_op_##name[ctx->mem_idx])(start)
1279 #define op_ldstsx(name, rd, ra, rb) (*gen_op_##name[ctx->mem_idx])(rd, ra, rb)
1280 static GenOpFunc1 *gen_op_lswi[] = {
1282 &gen_op_lswi_kernel,
1284 static GenOpFunc3 *gen_op_lswx[] = {
1286 &gen_op_lswx_kernel,
1288 static GenOpFunc1 *gen_op_stsw[] = {
1290 &gen_op_stsw_kernel,
1295 /* PPC32 specification says we must generate an exception if
1296 * rA is in the range of registers to be loaded.
1297 * In an other hand, IBM says this is valid, but rA won't be loaded.
1298 * For now, I'll follow the spec...
1300 GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_INTEGER)
1302 int nb = NB(ctx->opcode);
1303 int start = rD(ctx->opcode);
1304 int ra = rA(ctx->opcode);
1310 if (((start + nr) > 32 && start <= ra && (start + nr - 32) > ra) ||
1311 ((start + nr) <= 32 && start <= ra && (start + nr) > ra)) {
1312 RET_EXCP(ctx, EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_LSWX);
1318 gen_op_load_gpr_T0(ra);
1321 op_ldsts(lswi, start);
1325 GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_INTEGER)
1327 int ra = rA(ctx->opcode);
1328 int rb = rB(ctx->opcode);
1331 gen_op_load_gpr_T0(rb);
1334 gen_op_load_gpr_T0(ra);
1335 gen_op_load_gpr_T1(rb);
1338 gen_op_load_xer_bc();
1339 op_ldstsx(lswx, rD(ctx->opcode), ra, rb);
1343 GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_INTEGER)
1345 int nb = NB(ctx->opcode);
1347 if (rA(ctx->opcode) == 0) {
1350 gen_op_load_gpr_T0(rA(ctx->opcode));
1355 op_ldsts(stsw, rS(ctx->opcode));
1359 GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_INTEGER)
1361 int ra = rA(ctx->opcode);
1364 gen_op_load_gpr_T0(rB(ctx->opcode));
1365 ra = rB(ctx->opcode);
1367 gen_op_load_gpr_T0(ra);
1368 gen_op_load_gpr_T1(rB(ctx->opcode));
1371 gen_op_load_xer_bc();
1372 op_ldsts(stsw, rS(ctx->opcode));
1375 /*** Memory synchronisation ***/
1377 GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FF0801, PPC_MEM)
1382 GEN_HANDLER(isync, 0x13, 0x16, 0xFF, 0x03FF0801, PPC_MEM)
1387 #if defined(CONFIG_USER_ONLY)
1388 #define op_lwarx() gen_op_lwarx_raw()
1389 #define op_stwcx() gen_op_stwcx_raw()
1391 #define op_lwarx() (*gen_op_lwarx[ctx->mem_idx])()
1392 static GenOpFunc *gen_op_lwarx[] = {
1394 &gen_op_lwarx_kernel,
1396 #define op_stwcx() (*gen_op_stwcx[ctx->mem_idx])()
1397 static GenOpFunc *gen_op_stwcx[] = {
1399 &gen_op_stwcx_kernel,
1403 GEN_HANDLER(lwarx, 0x1F, 0x14, 0xFF, 0x00000001, PPC_RES)
1405 if (rA(ctx->opcode) == 0) {
1406 gen_op_load_gpr_T0(rB(ctx->opcode));
1408 gen_op_load_gpr_T0(rA(ctx->opcode));
1409 gen_op_load_gpr_T1(rB(ctx->opcode));
1413 gen_op_store_T1_gpr(rD(ctx->opcode));
1417 GEN_HANDLER(stwcx_, 0x1F, 0x16, 0x04, 0x00000000, PPC_RES)
1419 if (rA(ctx->opcode) == 0) {
1420 gen_op_load_gpr_T0(rB(ctx->opcode));
1422 gen_op_load_gpr_T0(rA(ctx->opcode));
1423 gen_op_load_gpr_T1(rB(ctx->opcode));
1426 gen_op_load_gpr_T1(rS(ctx->opcode));
1431 GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x03FF0801, PPC_MEM)
1435 /*** Floating-point load ***/
1436 #define GEN_LDF(width, opc) \
1437 GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) \
1439 uint32_t simm = SIMM(ctx->opcode); \
1440 if (!ctx->fpu_enabled) { \
1441 RET_EXCP(ctx, EXCP_NO_FP, 0); \
1444 if (rA(ctx->opcode) == 0) { \
1445 gen_op_set_T0(simm); \
1447 gen_op_load_gpr_T0(rA(ctx->opcode)); \
1449 gen_op_addi(simm); \
1451 op_ldst(l##width); \
1452 gen_op_store_FT1_fpr(rD(ctx->opcode)); \
1455 #define GEN_LDUF(width, opc) \
1456 GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) \
1458 uint32_t simm = SIMM(ctx->opcode); \
1459 if (!ctx->fpu_enabled) { \
1460 RET_EXCP(ctx, EXCP_NO_FP, 0); \
1463 if (rA(ctx->opcode) == 0 || \
1464 rA(ctx->opcode) == rD(ctx->opcode)) { \
1468 gen_op_load_gpr_T0(rA(ctx->opcode)); \
1470 gen_op_addi(simm); \
1471 op_ldst(l##width); \
1472 gen_op_store_FT1_fpr(rD(ctx->opcode)); \
1473 gen_op_store_T0_gpr(rA(ctx->opcode)); \
1476 #define GEN_LDUXF(width, opc) \
1477 GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_INTEGER) \
1479 if (!ctx->fpu_enabled) { \
1480 RET_EXCP(ctx, EXCP_NO_FP, 0); \
1483 if (rA(ctx->opcode) == 0 || \
1484 rA(ctx->opcode) == rD(ctx->opcode)) { \
1488 gen_op_load_gpr_T0(rA(ctx->opcode)); \
1489 gen_op_load_gpr_T1(rB(ctx->opcode)); \
1491 op_ldst(l##width); \
1492 gen_op_store_FT1_fpr(rD(ctx->opcode)); \
1493 gen_op_store_T0_gpr(rA(ctx->opcode)); \
1496 #define GEN_LDXF(width, opc2, opc3) \
1497 GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_INTEGER) \
1499 if (!ctx->fpu_enabled) { \
1500 RET_EXCP(ctx, EXCP_NO_FP, 0); \
1503 if (rA(ctx->opcode) == 0) { \
1504 gen_op_load_gpr_T0(rB(ctx->opcode)); \
1506 gen_op_load_gpr_T0(rA(ctx->opcode)); \
1507 gen_op_load_gpr_T1(rB(ctx->opcode)); \
1510 op_ldst(l##width); \
1511 gen_op_store_FT1_fpr(rD(ctx->opcode)); \
1514 #define GEN_LDFS(width, op) \
1515 OP_LD_TABLE(width); \
1516 GEN_LDF(width, op | 0x20); \
1517 GEN_LDUF(width, op | 0x21); \
1518 GEN_LDUXF(width, op | 0x01); \
1519 GEN_LDXF(width, 0x17, op | 0x00)
1521 /* lfd lfdu lfdux lfdx */
1523 /* lfs lfsu lfsux lfsx */
1526 /*** Floating-point store ***/
1527 #define GEN_STF(width, opc) \
1528 GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) \
1530 uint32_t simm = SIMM(ctx->opcode); \
1531 if (!ctx->fpu_enabled) { \
1532 RET_EXCP(ctx, EXCP_NO_FP, 0); \
1535 if (rA(ctx->opcode) == 0) { \
1536 gen_op_set_T0(simm); \
1538 gen_op_load_gpr_T0(rA(ctx->opcode)); \
1540 gen_op_addi(simm); \
1542 gen_op_load_fpr_FT1(rS(ctx->opcode)); \
1543 op_ldst(st##width); \
1546 #define GEN_STUF(width, opc) \
1547 GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) \
1549 uint32_t simm = SIMM(ctx->opcode); \
1550 if (!ctx->fpu_enabled) { \
1551 RET_EXCP(ctx, EXCP_NO_FP, 0); \
1554 if (rA(ctx->opcode) == 0) { \
1558 gen_op_load_gpr_T0(rA(ctx->opcode)); \
1560 gen_op_addi(simm); \
1561 gen_op_load_fpr_FT1(rS(ctx->opcode)); \
1562 op_ldst(st##width); \
1563 gen_op_store_T0_gpr(rA(ctx->opcode)); \
1566 #define GEN_STUXF(width, opc) \
1567 GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_INTEGER) \
1569 if (!ctx->fpu_enabled) { \
1570 RET_EXCP(ctx, EXCP_NO_FP, 0); \
1573 if (rA(ctx->opcode) == 0) { \
1577 gen_op_load_gpr_T0(rA(ctx->opcode)); \
1578 gen_op_load_gpr_T1(rB(ctx->opcode)); \
1580 gen_op_load_fpr_FT1(rS(ctx->opcode)); \
1581 op_ldst(st##width); \
1582 gen_op_store_T0_gpr(rA(ctx->opcode)); \
1585 #define GEN_STXF(width, opc2, opc3) \
1586 GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_INTEGER) \
1588 if (!ctx->fpu_enabled) { \
1589 RET_EXCP(ctx, EXCP_NO_FP, 0); \
1592 if (rA(ctx->opcode) == 0) { \
1593 gen_op_load_gpr_T0(rB(ctx->opcode)); \
1595 gen_op_load_gpr_T0(rA(ctx->opcode)); \
1596 gen_op_load_gpr_T1(rB(ctx->opcode)); \
1599 gen_op_load_fpr_FT1(rS(ctx->opcode)); \
1600 op_ldst(st##width); \
1603 #define GEN_STFS(width, op) \
1604 OP_ST_TABLE(width); \
1605 GEN_STF(width, op | 0x20); \
1606 GEN_STUF(width, op | 0x21); \
1607 GEN_STUXF(width, op | 0x01); \
1608 GEN_STXF(width, 0x17, op | 0x00)
1610 /* stfd stfdu stfdux stfdx */
1612 /* stfs stfsu stfsux stfsx */
1617 GEN_HANDLER(stfiwx, 0x1F, 0x17, 0x1E, 0x00000001, PPC_FLOAT)
1619 if (!ctx->fpu_enabled) {
1620 RET_EXCP(ctx, EXCP_NO_FP, 0);
1629 GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
1631 uint32_t li, target;
1633 /* sign extend LI */
1634 li = ((int32_t)LI(ctx->opcode) << 6) >> 6;
1636 if (AA(ctx->opcode) == 0)
1637 target = ctx->nip + li - 4;
1640 if (LK(ctx->opcode)) {
1641 gen_op_setlr(ctx->nip);
1643 gen_op_b((long)ctx->tb, target);
1644 ctx->exception = EXCP_BRANCH;
1651 static inline void gen_bcond(DisasContext *ctx, int type)
1653 uint32_t target = 0;
1654 uint32_t bo = BO(ctx->opcode);
1655 uint32_t bi = BI(ctx->opcode);
1659 if ((bo & 0x4) == 0)
1663 li = (int32_t)((int16_t)(BD(ctx->opcode)));
1664 if (AA(ctx->opcode) == 0) {
1665 target = ctx->nip + li - 4;
1671 gen_op_movl_T1_ctr();
1675 gen_op_movl_T1_lr();
1678 if (LK(ctx->opcode)) {
1679 gen_op_setlr(ctx->nip);
1682 /* No CR condition */
1693 if (type == BCOND_IM) {
1694 gen_op_b((long)ctx->tb, target);
1701 mask = 1 << (3 - (bi & 0x03));
1702 gen_op_load_crf_T0(bi >> 2);
1706 gen_op_test_ctr_true(mask);
1709 gen_op_test_ctrz_true(mask);
1714 gen_op_test_true(mask);
1720 gen_op_test_ctr_false(mask);
1723 gen_op_test_ctrz_false(mask);
1728 gen_op_test_false(mask);
1733 if (type == BCOND_IM) {
1734 gen_op_btest((long)ctx->tb, target, ctx->nip);
1736 gen_op_btest_T1(ctx->nip);
1739 ctx->exception = EXCP_BRANCH;
1742 GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
1744 gen_bcond(ctx, BCOND_IM);
1747 GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW)
1749 gen_bcond(ctx, BCOND_CTR);
1752 GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW)
1754 gen_bcond(ctx, BCOND_LR);
1757 /*** Condition register logical ***/
1758 #define GEN_CRLOGIC(op, opc) \
1759 GEN_HANDLER(cr##op, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER) \
1761 gen_op_load_crf_T0(crbA(ctx->opcode) >> 2); \
1762 gen_op_getbit_T0(3 - (crbA(ctx->opcode) & 0x03)); \
1763 gen_op_load_crf_T1(crbB(ctx->opcode) >> 2); \
1764 gen_op_getbit_T1(3 - (crbB(ctx->opcode) & 0x03)); \
1766 gen_op_load_crf_T1(crbD(ctx->opcode) >> 2); \
1767 gen_op_setcrfbit(~(1 << (3 - (crbD(ctx->opcode) & 0x03))), \
1768 3 - (crbD(ctx->opcode) & 0x03)); \
1769 gen_op_store_T1_crf(crbD(ctx->opcode) >> 2); \
1773 GEN_CRLOGIC(and, 0x08)
1775 GEN_CRLOGIC(andc, 0x04)
1777 GEN_CRLOGIC(eqv, 0x09)
1779 GEN_CRLOGIC(nand, 0x07)
1781 GEN_CRLOGIC(nor, 0x01)
1783 GEN_CRLOGIC(or, 0x0E)
1785 GEN_CRLOGIC(orc, 0x0D)
1787 GEN_CRLOGIC(xor, 0x06)
1789 GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER)
1791 gen_op_load_crf_T0(crfS(ctx->opcode));
1792 gen_op_store_T0_crf(crfD(ctx->opcode));
1795 /*** System linkage ***/
1796 /* rfi (supervisor only) */
1797 GEN_HANDLER(rfi, 0x13, 0x12, 0xFF, 0x03FF8001, PPC_FLOW)
1799 #if defined(CONFIG_USER_ONLY)
1802 /* Restore CPU state */
1803 if (!ctx->supervisor) {
1808 RET_EXCP(ctx, EXCP_RFI, 0);
1813 GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFFFFD, PPC_FLOW)
1815 #if defined(CONFIG_USER_ONLY)
1816 RET_EXCP(ctx, EXCP_SYSCALL_USER, 0);
1818 RET_EXCP(ctx, EXCP_SYSCALL, 0);
1824 GEN_HANDLER(tw, 0x1F, 0x04, 0xFF, 0x00000001, PPC_FLOW)
1826 gen_op_load_gpr_T0(rA(ctx->opcode));
1827 gen_op_load_gpr_T1(rB(ctx->opcode));
1828 gen_op_tw(TO(ctx->opcode));
1832 GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
1834 gen_op_load_gpr_T0(rA(ctx->opcode));
1836 printf("%s: param=0x%04x T0=0x%04x\n", __func__,
1837 SIMM(ctx->opcode), TO(ctx->opcode));
1839 gen_op_twi(SIMM(ctx->opcode), TO(ctx->opcode));
1842 /*** Processor control ***/
1843 static inline int check_spr_access (int spr, int rw, int supervisor)
1845 uint32_t rights = spr_access[spr >> 1] >> (4 * (spr & 1));
1848 if (spr != LR && spr != CTR) {
1850 fprintf(logfile, "%s reg=%d s=%d rw=%d r=0x%02x 0x%02x\n", __func__,
1851 SPR_ENCODE(spr), supervisor, rw, rights,
1852 (rights >> ((2 * supervisor) + rw)) & 1);
1854 printf("%s reg=%d s=%d rw=%d r=0x%02x 0x%02x\n", __func__,
1855 SPR_ENCODE(spr), supervisor, rw, rights,
1856 (rights >> ((2 * supervisor) + rw)) & 1);
1862 rights = rights >> (2 * supervisor);
1863 rights = rights >> rw;
1869 GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC)
1871 gen_op_load_xer_cr();
1872 gen_op_store_T0_crf(crfD(ctx->opcode));
1873 gen_op_clear_xer_cr();
1877 GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x001FF801, PPC_MISC)
1880 gen_op_store_T0_gpr(rD(ctx->opcode));
1884 GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC)
1886 #if defined(CONFIG_USER_ONLY)
1889 if (!ctx->supervisor) {
1894 gen_op_store_T0_gpr(rD(ctx->opcode));
1899 GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC)
1901 uint32_t sprn = SPR(ctx->opcode);
1903 #if defined(CONFIG_USER_ONLY)
1904 switch (check_spr_access(sprn, 0, 0))
1906 switch (check_spr_access(sprn, 0, ctx->supervisor))
1910 RET_EXCP(ctx, EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_SPR);
1929 gen_op_load_ibat(0, 0);
1932 gen_op_load_ibat(0, 1);
1935 gen_op_load_ibat(0, 2);
1938 gen_op_load_ibat(0, 3);
1941 gen_op_load_ibat(0, 4);
1944 gen_op_load_ibat(0, 5);
1947 gen_op_load_ibat(0, 6);
1950 gen_op_load_ibat(0, 7);
1953 gen_op_load_ibat(1, 0);
1956 gen_op_load_ibat(1, 1);
1959 gen_op_load_ibat(1, 2);
1962 gen_op_load_ibat(1, 3);
1965 gen_op_load_ibat(1, 4);
1968 gen_op_load_ibat(1, 5);
1971 gen_op_load_ibat(1, 6);
1974 gen_op_load_ibat(1, 7);
1977 gen_op_load_dbat(0, 0);
1980 gen_op_load_dbat(0, 1);
1983 gen_op_load_dbat(0, 2);
1986 gen_op_load_dbat(0, 3);
1989 gen_op_load_dbat(0, 4);
1992 gen_op_load_dbat(0, 5);
1995 gen_op_load_dbat(0, 6);
1998 gen_op_load_dbat(0, 7);
2001 gen_op_load_dbat(1, 0);
2004 gen_op_load_dbat(1, 1);
2007 gen_op_load_dbat(1, 2);
2010 gen_op_load_dbat(1, 3);
2013 gen_op_load_dbat(1, 4);
2016 gen_op_load_dbat(1, 5);
2019 gen_op_load_dbat(1, 6);
2022 gen_op_load_dbat(1, 7);
2037 gen_op_load_spr(sprn);
2040 gen_op_store_T0_gpr(rD(ctx->opcode));
2044 GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MISC)
2046 uint32_t sprn = SPR(ctx->opcode);
2048 /* We need to update the time base before reading it */
2060 gen_op_store_T0_gpr(rD(ctx->opcode));
2064 GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00100801, PPC_MISC)
2066 gen_op_load_gpr_T0(rS(ctx->opcode));
2067 gen_op_store_cr(CRM(ctx->opcode));
2071 GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC)
2073 #if defined(CONFIG_USER_ONLY)
2076 if (!ctx->supervisor) {
2080 gen_op_load_gpr_T0(rS(ctx->opcode));
2082 /* Must stop the translation as machine state (may have) changed */
2088 GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC)
2090 uint32_t sprn = SPR(ctx->opcode);
2094 fprintf(logfile, "MTSPR %d src=%d (%d)\n", SPR_ENCODE(sprn),
2095 rS(ctx->opcode), sprn);
2098 #if defined(CONFIG_USER_ONLY)
2099 switch (check_spr_access(sprn, 1, 0))
2101 switch (check_spr_access(sprn, 1, ctx->supervisor))
2105 RET_EXCP(ctx, EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_SPR);
2113 gen_op_load_gpr_T0(rS(ctx->opcode));
2125 gen_op_store_ibat(0, 0);
2129 gen_op_store_ibat(0, 1);
2133 gen_op_store_ibat(0, 2);
2137 gen_op_store_ibat(0, 3);
2141 gen_op_store_ibat(0, 4);
2145 gen_op_store_ibat(0, 5);
2149 gen_op_store_ibat(0, 6);
2153 gen_op_store_ibat(0, 7);
2157 gen_op_store_ibat(1, 0);
2161 gen_op_store_ibat(1, 1);
2165 gen_op_store_ibat(1, 2);
2169 gen_op_store_ibat(1, 3);
2173 gen_op_store_ibat(1, 4);
2177 gen_op_store_ibat(1, 5);
2181 gen_op_store_ibat(1, 6);
2185 gen_op_store_ibat(1, 7);
2189 gen_op_store_dbat(0, 0);
2193 gen_op_store_dbat(0, 1);
2197 gen_op_store_dbat(0, 2);
2201 gen_op_store_dbat(0, 3);
2205 gen_op_store_dbat(0, 4);
2209 gen_op_store_dbat(0, 5);
2213 gen_op_store_dbat(0, 6);
2217 gen_op_store_dbat(0, 7);
2221 gen_op_store_dbat(1, 0);
2225 gen_op_store_dbat(1, 1);
2229 gen_op_store_dbat(1, 2);
2233 gen_op_store_dbat(1, 3);
2237 gen_op_store_dbat(1, 4);
2241 gen_op_store_dbat(1, 5);
2245 gen_op_store_dbat(1, 6);
2249 gen_op_store_dbat(1, 7);
2253 gen_op_store_sdr1();
2263 gen_op_store_decr();
2266 gen_op_store_spr(sprn);
2271 /*** Cache management ***/
2272 /* For now, all those will be implemented as nop:
2273 * this is valid, regarding the PowerPC specs...
2274 * We just have to flush tb while invalidating instruction cache lines...
2277 GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03E00001, PPC_CACHE)
2279 if (rA(ctx->opcode) == 0) {
2280 gen_op_load_gpr_T0(rB(ctx->opcode));
2282 gen_op_load_gpr_T0(rA(ctx->opcode));
2283 gen_op_load_gpr_T1(rB(ctx->opcode));
2289 /* dcbi (Supervisor only) */
2290 GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE)
2292 #if defined(CONFIG_USER_ONLY)
2295 if (!ctx->supervisor) {
2299 if (rA(ctx->opcode) == 0) {
2300 gen_op_load_gpr_T0(rB(ctx->opcode));
2302 gen_op_load_gpr_T0(rA(ctx->opcode));
2303 gen_op_load_gpr_T1(rB(ctx->opcode));
2312 GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE)
2314 if (rA(ctx->opcode) == 0) {
2315 gen_op_load_gpr_T0(rB(ctx->opcode));
2317 gen_op_load_gpr_T0(rA(ctx->opcode));
2318 gen_op_load_gpr_T1(rB(ctx->opcode));
2325 GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x03E00001, PPC_CACHE)
2330 GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x03E00001, PPC_CACHE)
2335 #if defined(CONFIG_USER_ONLY)
2336 #define op_dcbz() gen_op_dcbz_raw()
2338 #define op_dcbz() (*gen_op_dcbz[ctx->mem_idx])()
2339 static GenOpFunc *gen_op_dcbz[] = {
2341 &gen_op_dcbz_kernel,
2345 GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE)
2347 if (rA(ctx->opcode) == 0) {
2348 gen_op_load_gpr_T0(rB(ctx->opcode));
2350 gen_op_load_gpr_T0(rA(ctx->opcode));
2351 gen_op_load_gpr_T1(rB(ctx->opcode));
2355 gen_op_check_reservation();
2359 GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE)
2361 if (rA(ctx->opcode) == 0) {
2362 gen_op_load_gpr_T0(rB(ctx->opcode));
2364 gen_op_load_gpr_T0(rA(ctx->opcode));
2365 gen_op_load_gpr_T1(rB(ctx->opcode));
2373 GEN_HANDLER(dcba, 0x1F, 0x16, 0x07, 0x03E00001, PPC_CACHE_OPT)
2377 /*** Segment register manipulation ***/
2378 /* Supervisor only: */
2380 GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT)
2382 #if defined(CONFIG_USER_ONLY)
2385 if (!ctx->supervisor) {
2389 gen_op_load_sr(SR(ctx->opcode));
2390 gen_op_store_T0_gpr(rD(ctx->opcode));
2395 GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT)
2397 #if defined(CONFIG_USER_ONLY)
2400 if (!ctx->supervisor) {
2404 gen_op_load_gpr_T1(rB(ctx->opcode));
2406 gen_op_store_T0_gpr(rD(ctx->opcode));
2411 GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT)
2413 #if defined(CONFIG_USER_ONLY)
2416 if (!ctx->supervisor) {
2420 gen_op_load_gpr_T0(rS(ctx->opcode));
2421 gen_op_store_sr(SR(ctx->opcode));
2426 GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT)
2428 #if defined(CONFIG_USER_ONLY)
2431 if (!ctx->supervisor) {
2435 gen_op_load_gpr_T0(rS(ctx->opcode));
2436 gen_op_load_gpr_T1(rB(ctx->opcode));
2437 gen_op_store_srin();
2441 /*** Lookaside buffer management ***/
2442 /* Optional & supervisor only: */
2444 GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_OPT)
2446 #if defined(CONFIG_USER_ONLY)
2449 if (!ctx->supervisor) {
2451 fprintf(logfile, "%s: ! supervisor\n", __func__);
2461 GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM)
2463 #if defined(CONFIG_USER_ONLY)
2466 if (!ctx->supervisor) {
2470 gen_op_load_gpr_T0(rB(ctx->opcode));
2477 GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM)
2479 #if defined(CONFIG_USER_ONLY)
2482 if (!ctx->supervisor) {
2486 /* This has no effect: it should ensure that all previous
2487 * tlbie have completed
2493 /*** External control ***/
2496 #if defined(CONFIG_USER_ONLY)
2497 #define op_eciwx() gen_op_eciwx_raw()
2498 #define op_ecowx() gen_op_ecowx_raw()
2500 #define op_eciwx() (*gen_op_eciwx[ctx->mem_idx])()
2501 #define op_ecowx() (*gen_op_ecowx[ctx->mem_idx])()
2502 static GenOpFunc *gen_op_eciwx[] = {
2504 &gen_op_eciwx_kernel,
2506 static GenOpFunc *gen_op_ecowx[] = {
2508 &gen_op_ecowx_kernel,
2512 GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN)
2514 /* Should check EAR[E] & alignment ! */
2515 if (rA(ctx->opcode) == 0) {
2516 gen_op_load_gpr_T0(rB(ctx->opcode));
2518 gen_op_load_gpr_T0(rA(ctx->opcode));
2519 gen_op_load_gpr_T1(rB(ctx->opcode));
2523 gen_op_store_T0_gpr(rD(ctx->opcode));
2527 GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN)
2529 /* Should check EAR[E] & alignment ! */
2530 if (rA(ctx->opcode) == 0) {
2531 gen_op_load_gpr_T0(rB(ctx->opcode));
2533 gen_op_load_gpr_T0(rA(ctx->opcode));
2534 gen_op_load_gpr_T1(rB(ctx->opcode));
2537 gen_op_load_gpr_T2(rS(ctx->opcode));
2541 /* End opcode list */
2542 GEN_OPCODE_MARK(end);
2544 /*****************************************************************************/
2548 int fflush (FILE *stream);
2550 /* Main ppc opcodes table:
2551 * at init, all opcodes are invalids
2553 static opc_handler_t *ppc_opcodes[0x40];
2557 PPC_DIRECT = 0, /* Opcode routine */
2558 PPC_INDIRECT = 1, /* Indirect opcode table */
2561 static inline int is_indirect_opcode (void *handler)
2563 return ((unsigned long)handler & 0x03) == PPC_INDIRECT;
2566 static inline opc_handler_t **ind_table(void *handler)
2568 return (opc_handler_t **)((unsigned long)handler & ~3);
2571 /* Instruction table creation */
2572 /* Opcodes tables creation */
2573 static void fill_new_table (opc_handler_t **table, int len)
2577 for (i = 0; i < len; i++)
2578 table[i] = &invalid_handler;
2581 static int create_new_table (opc_handler_t **table, unsigned char idx)
2583 opc_handler_t **tmp;
2585 tmp = malloc(0x20 * sizeof(opc_handler_t));
2588 fill_new_table(tmp, 0x20);
2589 table[idx] = (opc_handler_t *)((unsigned long)tmp | PPC_INDIRECT);
2594 static int insert_in_table (opc_handler_t **table, unsigned char idx,
2595 opc_handler_t *handler)
2597 if (table[idx] != &invalid_handler)
2599 table[idx] = handler;
2604 static int register_direct_insn (opc_handler_t **ppc_opcodes,
2605 unsigned char idx, opc_handler_t *handler)
2607 if (insert_in_table(ppc_opcodes, idx, handler) < 0) {
2608 printf("*** ERROR: opcode %02x already assigned in main "
2609 "opcode table\n", idx);
2616 static int register_ind_in_table (opc_handler_t **table,
2617 unsigned char idx1, unsigned char idx2,
2618 opc_handler_t *handler)
2620 if (table[idx1] == &invalid_handler) {
2621 if (create_new_table(table, idx1) < 0) {
2622 printf("*** ERROR: unable to create indirect table "
2623 "idx=%02x\n", idx1);
2627 if (!is_indirect_opcode(table[idx1])) {
2628 printf("*** ERROR: idx %02x already assigned to a direct "
2633 if (handler != NULL &&
2634 insert_in_table(ind_table(table[idx1]), idx2, handler) < 0) {
2635 printf("*** ERROR: opcode %02x already assigned in "
2636 "opcode table %02x\n", idx2, idx1);
2643 static int register_ind_insn (opc_handler_t **ppc_opcodes,
2644 unsigned char idx1, unsigned char idx2,
2645 opc_handler_t *handler)
2649 ret = register_ind_in_table(ppc_opcodes, idx1, idx2, handler);
2654 static int register_dblind_insn (opc_handler_t **ppc_opcodes,
2655 unsigned char idx1, unsigned char idx2,
2656 unsigned char idx3, opc_handler_t *handler)
2658 if (register_ind_in_table(ppc_opcodes, idx1, idx2, NULL) < 0) {
2659 printf("*** ERROR: unable to join indirect table idx "
2660 "[%02x-%02x]\n", idx1, idx2);
2663 if (register_ind_in_table(ind_table(ppc_opcodes[idx1]), idx2, idx3,
2665 printf("*** ERROR: unable to insert opcode "
2666 "[%02x-%02x-%02x]\n", idx1, idx2, idx3);
2673 static int register_insn (opc_handler_t **ppc_opcodes, opcode_t *insn)
2675 if (insn->opc2 != 0xFF) {
2676 if (insn->opc3 != 0xFF) {
2677 if (register_dblind_insn(ppc_opcodes, insn->opc1, insn->opc2,
2678 insn->opc3, &insn->handler) < 0)
2681 if (register_ind_insn(ppc_opcodes, insn->opc1,
2682 insn->opc2, &insn->handler) < 0)
2686 if (register_direct_insn(ppc_opcodes, insn->opc1, &insn->handler) < 0)
2693 static int test_opcode_table (opc_handler_t **table, int len)
2697 for (i = 0, count = 0; i < len; i++) {
2698 /* Consistency fixup */
2699 if (table[i] == NULL)
2700 table[i] = &invalid_handler;
2701 if (table[i] != &invalid_handler) {
2702 if (is_indirect_opcode(table[i])) {
2703 tmp = test_opcode_table(ind_table(table[i]), 0x20);
2706 table[i] = &invalid_handler;
2719 static void fix_opcode_tables (opc_handler_t **ppc_opcodes)
2721 if (test_opcode_table(ppc_opcodes, 0x40) == 0)
2722 printf("*** WARNING: no opcode defined !\n");
2725 #define SPR_RIGHTS(rw, priv) (1 << ((2 * (priv)) + (rw)))
2726 #define SPR_UR SPR_RIGHTS(0, 0)
2727 #define SPR_UW SPR_RIGHTS(1, 0)
2728 #define SPR_SR SPR_RIGHTS(0, 1)
2729 #define SPR_SW SPR_RIGHTS(1, 1)
2731 #define spr_set_rights(spr, rights) \
2733 spr_access[(spr) >> 1] |= ((rights) << (4 * ((spr) & 1))); \
2736 static void init_spr_rights (uint32_t pvr)
2739 spr_set_rights(XER, SPR_UR | SPR_UW | SPR_SR | SPR_SW);
2741 spr_set_rights(LR, SPR_UR | SPR_UW | SPR_SR | SPR_SW);
2743 spr_set_rights(CTR, SPR_UR | SPR_UW | SPR_SR | SPR_SW);
2745 spr_set_rights(V_TBL, SPR_UR | SPR_SR);
2747 spr_set_rights(V_TBU, SPR_UR | SPR_SR);
2748 /* DSISR (SPR 18) */
2749 spr_set_rights(DSISR, SPR_SR | SPR_SW);
2751 spr_set_rights(DAR, SPR_SR | SPR_SW);
2753 spr_set_rights(DECR, SPR_SR | SPR_SW);
2755 spr_set_rights(SDR1, SPR_SR | SPR_SW);
2757 spr_set_rights(SRR0, SPR_SR | SPR_SW);
2759 spr_set_rights(SRR1, SPR_SR | SPR_SW);
2760 /* SPRG0 (SPR 272) */
2761 spr_set_rights(SPRG0, SPR_SR | SPR_SW);
2762 /* SPRG1 (SPR 273) */
2763 spr_set_rights(SPRG1, SPR_SR | SPR_SW);
2764 /* SPRG2 (SPR 274) */
2765 spr_set_rights(SPRG2, SPR_SR | SPR_SW);
2766 /* SPRG3 (SPR 275) */
2767 spr_set_rights(SPRG3, SPR_SR | SPR_SW);
2769 spr_set_rights(ASR, SPR_SR | SPR_SW);
2771 spr_set_rights(EAR, SPR_SR | SPR_SW);
2773 spr_set_rights(O_TBL, SPR_SW);
2775 spr_set_rights(O_TBU, SPR_SW);
2777 spr_set_rights(PVR, SPR_SR);
2778 /* IBAT0U (SPR 528) */
2779 spr_set_rights(IBAT0U, SPR_SR | SPR_SW);
2780 /* IBAT0L (SPR 529) */
2781 spr_set_rights(IBAT0L, SPR_SR | SPR_SW);
2782 /* IBAT1U (SPR 530) */
2783 spr_set_rights(IBAT1U, SPR_SR | SPR_SW);
2784 /* IBAT1L (SPR 531) */
2785 spr_set_rights(IBAT1L, SPR_SR | SPR_SW);
2786 /* IBAT2U (SPR 532) */
2787 spr_set_rights(IBAT2U, SPR_SR | SPR_SW);
2788 /* IBAT2L (SPR 533) */
2789 spr_set_rights(IBAT2L, SPR_SR | SPR_SW);
2790 /* IBAT3U (SPR 534) */
2791 spr_set_rights(IBAT3U, SPR_SR | SPR_SW);
2792 /* IBAT3L (SPR 535) */
2793 spr_set_rights(IBAT3L, SPR_SR | SPR_SW);
2794 /* DBAT0U (SPR 536) */
2795 spr_set_rights(DBAT0U, SPR_SR | SPR_SW);
2796 /* DBAT0L (SPR 537) */
2797 spr_set_rights(DBAT0L, SPR_SR | SPR_SW);
2798 /* DBAT1U (SPR 538) */
2799 spr_set_rights(DBAT1U, SPR_SR | SPR_SW);
2800 /* DBAT1L (SPR 539) */
2801 spr_set_rights(DBAT1L, SPR_SR | SPR_SW);
2802 /* DBAT2U (SPR 540) */
2803 spr_set_rights(DBAT2U, SPR_SR | SPR_SW);
2804 /* DBAT2L (SPR 541) */
2805 spr_set_rights(DBAT2L, SPR_SR | SPR_SW);
2806 /* DBAT3U (SPR 542) */
2807 spr_set_rights(DBAT3U, SPR_SR | SPR_SW);
2808 /* DBAT3L (SPR 543) */
2809 spr_set_rights(DBAT3L, SPR_SR | SPR_SW);
2810 /* FPECR (SPR 1022) */
2811 spr_set_rights(FPECR, SPR_SR | SPR_SW);
2812 /* Special registers for PPC 604 */
2813 if ((pvr & 0xFFFF0000) == 0x00040000) {
2815 spr_set_rights(IABR , SPR_SR | SPR_SW);
2816 /* DABR (SPR 1013) */
2817 spr_set_rights(DABR, SPR_SR | SPR_SW);
2819 spr_set_rights(HID0, SPR_SR | SPR_SW);
2821 spr_set_rights(PIR, SPR_SR | SPR_SW);
2823 spr_set_rights(PMC1, SPR_SR | SPR_SW);
2825 spr_set_rights(PMC2, SPR_SR | SPR_SW);
2827 spr_set_rights(MMCR0, SPR_SR | SPR_SW);
2829 spr_set_rights(SIA, SPR_SR | SPR_SW);
2831 spr_set_rights(SDA, SPR_SR | SPR_SW);
2833 /* Special registers for MPC740/745/750/755 (aka G3) & IBM 750 */
2834 if ((pvr & 0xFFFF0000) == 0x00080000 ||
2835 (pvr & 0xFFFF0000) == 0x70000000) {
2837 spr_set_rights(HID0, SPR_SR | SPR_SW);
2839 spr_set_rights(HID1, SPR_SR | SPR_SW);
2841 spr_set_rights(IABR, SPR_SR | SPR_SW);
2843 spr_set_rights(ICTC, SPR_SR | SPR_SW);
2845 spr_set_rights(L2CR, SPR_SR | SPR_SW);
2847 spr_set_rights(MMCR0, SPR_SR | SPR_SW);
2849 spr_set_rights(MMCR1, SPR_SR | SPR_SW);
2851 spr_set_rights(PMC1, SPR_SR | SPR_SW);
2853 spr_set_rights(PMC2, SPR_SR | SPR_SW);
2855 spr_set_rights(PMC3, SPR_SR | SPR_SW);
2857 spr_set_rights(PMC4, SPR_SR | SPR_SW);
2859 spr_set_rights(SIA, SPR_SR | SPR_SW);
2861 spr_set_rights(SDA, SPR_SR | SPR_SW);
2863 spr_set_rights(THRM1, SPR_SR | SPR_SW);
2865 spr_set_rights(THRM2, SPR_SR | SPR_SW);
2867 spr_set_rights(THRM3, SPR_SR | SPR_SW);
2869 spr_set_rights(UMMCR0, SPR_UR | SPR_UW);
2871 spr_set_rights(UMMCR1, SPR_UR | SPR_UW);
2873 spr_set_rights(UPMC1, SPR_UR | SPR_UW);
2875 spr_set_rights(UPMC2, SPR_UR | SPR_UW);
2877 spr_set_rights(UPMC3, SPR_UR | SPR_UW);
2879 spr_set_rights(UPMC4, SPR_UR | SPR_UW);
2881 spr_set_rights(USIA, SPR_UR | SPR_UW);
2883 /* MPC755 has special registers */
2884 if (pvr == 0x00083100) {
2886 spr_set_rights(SPRG4, SPR_SR | SPR_SW);
2888 spr_set_rights(SPRG5, SPR_SR | SPR_SW);
2890 spr_set_rights(SPRG6, SPR_SR | SPR_SW);
2892 spr_set_rights(SPRG7, SPR_SR | SPR_SW);
2894 spr_set_rights(IBAT4U, SPR_SR | SPR_SW);
2896 spr_set_rights(IBAT4L, SPR_SR | SPR_SW);
2898 spr_set_rights(IBAT5U, SPR_SR | SPR_SW);
2900 spr_set_rights(IBAT5L, SPR_SR | SPR_SW);
2902 spr_set_rights(IBAT6U, SPR_SR | SPR_SW);
2904 spr_set_rights(IBAT6L, SPR_SR | SPR_SW);
2906 spr_set_rights(IBAT7U, SPR_SR | SPR_SW);
2908 spr_set_rights(IBAT7L, SPR_SR | SPR_SW);
2910 spr_set_rights(DBAT4U, SPR_SR | SPR_SW);
2912 spr_set_rights(DBAT4L, SPR_SR | SPR_SW);
2914 spr_set_rights(DBAT5U, SPR_SR | SPR_SW);
2916 spr_set_rights(DBAT5L, SPR_SR | SPR_SW);
2918 spr_set_rights(DBAT6U, SPR_SR | SPR_SW);
2920 spr_set_rights(DBAT6L, SPR_SR | SPR_SW);
2922 spr_set_rights(DBAT7U, SPR_SR | SPR_SW);
2924 spr_set_rights(DBAT7L, SPR_SR | SPR_SW);
2926 spr_set_rights(DMISS, SPR_SR | SPR_SW);
2928 spr_set_rights(DCMP, SPR_SR | SPR_SW);
2930 spr_set_rights(DHASH1, SPR_SR | SPR_SW);
2932 spr_set_rights(DHASH2, SPR_SR | SPR_SW);
2934 spr_set_rights(IMISS, SPR_SR | SPR_SW);
2936 spr_set_rights(ICMP, SPR_SR | SPR_SW);
2938 spr_set_rights(RPA, SPR_SR | SPR_SW);
2940 spr_set_rights(HID2, SPR_SR | SPR_SW);
2942 spr_set_rights(L2PM, SPR_SR | SPR_SW);
2946 /*****************************************************************************/
2947 /* PPC "main stream" common instructions (no optional ones) */
2949 typedef struct ppc_proc_t {
2954 typedef struct ppc_def_t {
2956 unsigned long pvr_mask;
2960 static ppc_proc_t ppc_proc_common = {
2961 .flags = PPC_COMMON,
2965 static ppc_proc_t ppc_proc_G3 = {
2970 static ppc_def_t ppc_defs[] =
2972 /* MPC740/745/750/755 (G3) */
2975 .pvr_mask = 0xFFFF0000,
2976 .proc = &ppc_proc_G3,
2978 /* IBM 750FX (G3 embedded) */
2981 .pvr_mask = 0xFFFF0000,
2982 .proc = &ppc_proc_G3,
2984 /* Fallback (generic PPC) */
2987 .pvr_mask = 0x00000000,
2988 .proc = &ppc_proc_common,
2992 static int create_ppc_proc (opc_handler_t **ppc_opcodes, unsigned long pvr)
2994 opcode_t *opc, *start, *end;
2997 fill_new_table(ppc_opcodes, 0x40);
2998 for (i = 0; ; i++) {
2999 if ((ppc_defs[i].pvr & ppc_defs[i].pvr_mask) ==
3000 (pvr & ppc_defs[i].pvr_mask)) {
3001 flags = ppc_defs[i].proc->flags;
3006 if (&opc_start < &opc_end) {
3013 for (opc = start + 1; opc != end; opc++) {
3014 if ((opc->handler.type & flags) != 0)
3015 if (register_insn(ppc_opcodes, opc) < 0) {
3016 printf("*** ERROR initializing PPC instruction "
3017 "0x%02x 0x%02x 0x%02x\n", opc->opc1, opc->opc2,
3022 fix_opcode_tables(ppc_opcodes);
3028 /*****************************************************************************/
3029 /* Misc PPC helpers */
3031 void cpu_dump_state(CPUState *env, FILE *f,
3032 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
3037 cpu_fprintf(f, "nip=0x%08x LR=0x%08x CTR=0x%08x XER=0x%08x "
3038 "MSR=0x%08x\n", env->nip, env->lr, env->ctr,
3039 _load_xer(env), _load_msr(env));
3040 for (i = 0; i < 32; i++) {
3042 cpu_fprintf(f, "GPR%02d:", i);
3043 cpu_fprintf(f, " %08x", env->gpr[i]);
3045 cpu_fprintf(f, "\n");
3047 cpu_fprintf(f, "CR: 0x");
3048 for (i = 0; i < 8; i++)
3049 cpu_fprintf(f, "%01x", env->crf[i]);
3050 cpu_fprintf(f, " [");
3051 for (i = 0; i < 8; i++) {
3053 if (env->crf[i] & 0x08)
3055 else if (env->crf[i] & 0x04)
3057 else if (env->crf[i] & 0x02)
3059 cpu_fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
3061 cpu_fprintf(f, " ] ");
3062 cpu_fprintf(f, "TB: 0x%08x %08x\n", cpu_ppc_load_tbu(env),
3063 cpu_ppc_load_tbl(env));
3064 for (i = 0; i < 16; i++) {
3066 cpu_fprintf(f, "FPR%02d:", i);
3067 cpu_fprintf(f, " %016llx", *((uint64_t *)&env->fpr[i]));
3069 cpu_fprintf(f, "\n");
3071 cpu_fprintf(f, "SRR0 0x%08x SRR1 0x%08x DECR=0x%08x\n",
3072 env->spr[SRR0], env->spr[SRR1], cpu_ppc_load_decr(env));
3073 cpu_fprintf(f, "reservation 0x%08x\n", env->reserve);
3076 CPUPPCState *cpu_ppc_init(void)
3082 env = qemu_mallocz(sizeof(CPUPPCState));
3085 // env->spr[PVR] = 0; /* Basic PPC */
3086 env->spr[PVR] = 0x00080100; /* G3 CPU */
3087 // env->spr[PVR] = 0x00083100; /* MPC755 (G3 embedded) */
3088 // env->spr[PVR] = 0x00070100; /* IBM 750FX */
3090 #if defined (DO_SINGLE_STEP)
3091 /* Single step trace mode */
3094 msr_fp = 1; /* Allow floating point exceptions */
3095 msr_me = 1; /* Allow machine check exceptions */
3096 #if defined(CONFIG_USER_ONLY)
3098 cpu_ppc_register(env, 0x00080000);
3100 env->nip = 0xFFFFFFFC;
3102 cpu_single_env = env;
3106 int cpu_ppc_register (CPUPPCState *env, uint32_t pvr)
3108 env->spr[PVR] = pvr;
3109 if (create_ppc_proc(ppc_opcodes, env->spr[PVR]) < 0)
3111 init_spr_rights(env->spr[PVR]);
3116 void cpu_ppc_close(CPUPPCState *env)
3118 /* Should also remove all opcode tables... */
3122 /*****************************************************************************/
3123 int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
3126 DisasContext ctx, *ctxp = &ctx;
3127 opc_handler_t **table, *handler;
3128 target_ulong pc_start;
3129 uint16_t *gen_opc_end;
3133 gen_opc_ptr = gen_opc_buf;
3134 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
3135 gen_opparam_ptr = gen_opparam_buf;
3138 ctx.exception = EXCP_NONE;
3139 #if defined(CONFIG_USER_ONLY)
3142 ctx.supervisor = 1 - msr_pr;
3143 ctx.mem_idx = 1 - msr_pr;
3145 ctx.fpu_enabled = msr_fp;
3146 #if defined (DO_SINGLE_STEP)
3147 /* Single step trace mode */
3150 /* Set env in case of segfault during code fetch */
3151 while (ctx.exception == EXCP_NONE && gen_opc_ptr < gen_opc_end) {
3153 j = gen_opc_ptr - gen_opc_buf;
3157 gen_opc_instr_start[lj++] = 0;
3158 gen_opc_pc[lj] = ctx.nip;
3159 gen_opc_instr_start[lj] = 1;
3162 #if defined PPC_DEBUG_DISAS
3163 if (loglevel & CPU_LOG_TB_IN_ASM) {
3164 fprintf(logfile, "----------------\n");
3165 fprintf(logfile, "nip=%08x super=%d ir=%d\n",
3166 ctx.nip, 1 - msr_pr, msr_ir);
3169 ctx.opcode = ldl_code(ctx.nip);
3170 #if defined PPC_DEBUG_DISAS
3171 if (loglevel & CPU_LOG_TB_IN_ASM) {
3172 fprintf(logfile, "translate opcode %08x (%02x %02x %02x)\n",
3173 ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
3178 table = ppc_opcodes;
3179 handler = table[opc1(ctx.opcode)];
3180 if (is_indirect_opcode(handler)) {
3181 table = ind_table(handler);
3182 handler = table[opc2(ctx.opcode)];
3183 if (is_indirect_opcode(handler)) {
3184 table = ind_table(handler);
3185 handler = table[opc3(ctx.opcode)];
3188 /* Is opcode *REALLY* valid ? */
3189 if (handler->handler == &gen_invalid) {
3191 fprintf(logfile, "invalid/unsupported opcode: "
3192 "%02x - %02x - %02x (%08x) 0x%08x %d\n",
3193 opc1(ctx.opcode), opc2(ctx.opcode),
3194 opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, msr_ir);
3196 printf("invalid/unsupported opcode: "
3197 "%02x - %02x - %02x (%08x) 0x%08x %d\n",
3198 opc1(ctx.opcode), opc2(ctx.opcode),
3199 opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, msr_ir);
3202 if ((ctx.opcode & handler->inval) != 0) {
3204 fprintf(logfile, "invalid bits: %08x for opcode: "
3205 "%02x -%02x - %02x (0x%08x) (0x%08x)\n",
3206 ctx.opcode & handler->inval, opc1(ctx.opcode),
3207 opc2(ctx.opcode), opc3(ctx.opcode),
3208 ctx.opcode, ctx.nip - 4);
3210 printf("invalid bits: %08x for opcode: "
3211 "%02x -%02x - %02x (0x%08x) (0x%08x)\n",
3212 ctx.opcode & handler->inval, opc1(ctx.opcode),
3213 opc2(ctx.opcode), opc3(ctx.opcode),
3214 ctx.opcode, ctx.nip - 4);
3220 (*(handler->handler))(&ctx);
3221 /* Check trace mode exceptions */
3222 if ((msr_be && ctx.exception == EXCP_BRANCH) ||
3223 /* Check in single step trace mode
3224 * we need to stop except if:
3225 * - rfi, trap or syscall
3226 * - first instruction of an exception handler
3228 (msr_se && (ctx.nip < 0x100 ||
3230 (ctx.nip & 0xFC) != 0x04) &&
3231 ctx.exception != EXCP_SYSCALL && ctx.exception != EXCP_RFI &&
3232 ctx.exception != EXCP_TRAP)) {
3233 RET_EXCP(ctxp, EXCP_TRACE, 0);
3235 /* if we reach a page boundary, stop generation */
3236 if ((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) {
3237 RET_EXCP(ctxp, EXCP_BRANCH, 0);
3240 if (ctx.exception == EXCP_NONE) {
3241 gen_op_b((unsigned long)ctx.tb, ctx.nip);
3242 } else if (ctx.exception != EXCP_BRANCH) {
3246 /* TO BE FIXED: T0 hasn't got a proper value, which makes tb_add_jump
3247 * do bad business and then qemu crashes !
3251 /* Generate the return instruction */
3253 *gen_opc_ptr = INDEX_op_end;
3255 j = gen_opc_ptr - gen_opc_buf;
3258 gen_opc_instr_start[lj++] = 0;
3266 tb->size = ctx.nip - pc_start;
3269 if (loglevel & CPU_LOG_TB_CPU) {
3270 fprintf(logfile, "---------------- excp: %04x\n", ctx.exception);
3271 cpu_dump_state(env, logfile, fprintf, 0);
3273 if (loglevel & CPU_LOG_TB_IN_ASM) {
3274 fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
3275 target_disas(logfile, pc_start, ctx.nip - pc_start, 0);
3276 fprintf(logfile, "\n");
3278 if (loglevel & CPU_LOG_TB_OP) {
3279 fprintf(logfile, "OP:\n");
3280 dump_ops(gen_opc_buf, gen_opparam_buf);
3281 fprintf(logfile, "\n");
3287 int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
3289 return gen_intermediate_code_internal(env, tb, 0);
3292 int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
3294 return gen_intermediate_code_internal(env, tb, 1);