2 * PowerPC emulation for qemu: main translation routines.
4 * Copyright (c) 2003-2007 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
32 //#define DO_PPC_STATISTICS
34 #if defined(USE_DIRECT_JUMP)
37 #define TBPARAM(x) (long)(x)
41 #define DEF(s, n, copy_size) INDEX_op_ ## s,
47 static uint16_t *gen_opc_ptr
;
48 static uint32_t *gen_opparam_ptr
;
52 static inline void gen_set_T0 (target_ulong val
)
54 #if defined(TARGET_PPC64)
56 gen_op_set_T0_64(val
>> 32, val
);
62 static inline void gen_set_T1 (target_ulong val
)
64 #if defined(TARGET_PPC64)
66 gen_op_set_T1_64(val
>> 32, val
);
72 #define GEN8(func, NAME) \
73 static GenOpFunc *NAME ## _table [8] = { \
74 NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3, \
75 NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7, \
77 static inline void func(int n) \
79 NAME ## _table[n](); \
82 #define GEN16(func, NAME) \
83 static GenOpFunc *NAME ## _table [16] = { \
84 NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3, \
85 NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7, \
86 NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11, \
87 NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15, \
89 static inline void func(int n) \
91 NAME ## _table[n](); \
94 #define GEN32(func, NAME) \
95 static GenOpFunc *NAME ## _table [32] = { \
96 NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3, \
97 NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7, \
98 NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11, \
99 NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15, \
100 NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19, \
101 NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23, \
102 NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27, \
103 NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31, \
105 static inline void func(int n) \
107 NAME ## _table[n](); \
110 /* Condition register moves */
111 GEN8(gen_op_load_crf_T0
, gen_op_load_crf_T0_crf
);
112 GEN8(gen_op_load_crf_T1
, gen_op_load_crf_T1_crf
);
113 GEN8(gen_op_store_T0_crf
, gen_op_store_T0_crf_crf
);
114 GEN8(gen_op_store_T1_crf
, gen_op_store_T1_crf_crf
);
116 /* Floating point condition and status register moves */
117 GEN8(gen_op_load_fpscr_T0
, gen_op_load_fpscr_T0_fpscr
);
118 GEN8(gen_op_store_T0_fpscr
, gen_op_store_T0_fpscr_fpscr
);
119 GEN8(gen_op_clear_fpscr
, gen_op_clear_fpscr_fpscr
);
120 static inline void gen_op_store_T0_fpscri(int n
, uint8_t param
)
122 gen_op_set_T0(param
);
123 gen_op_store_T0_fpscr(n
);
126 /* General purpose registers moves */
127 GEN32(gen_op_load_gpr_T0
, gen_op_load_gpr_T0_gpr
);
128 GEN32(gen_op_load_gpr_T1
, gen_op_load_gpr_T1_gpr
);
129 GEN32(gen_op_load_gpr_T2
, gen_op_load_gpr_T2_gpr
);
131 GEN32(gen_op_store_T0_gpr
, gen_op_store_T0_gpr_gpr
);
132 GEN32(gen_op_store_T1_gpr
, gen_op_store_T1_gpr_gpr
);
134 GEN32(gen_op_store_T2_gpr
, gen_op_store_T2_gpr_gpr
);
137 /* floating point registers moves */
138 GEN32(gen_op_load_fpr_FT0
, gen_op_load_fpr_FT0_fpr
);
139 GEN32(gen_op_load_fpr_FT1
, gen_op_load_fpr_FT1_fpr
);
140 GEN32(gen_op_load_fpr_FT2
, gen_op_load_fpr_FT2_fpr
);
141 GEN32(gen_op_store_FT0_fpr
, gen_op_store_FT0_fpr_fpr
);
142 GEN32(gen_op_store_FT1_fpr
, gen_op_store_FT1_fpr_fpr
);
144 GEN32(gen_op_store_FT2_fpr
, gen_op_store_FT2_fpr_fpr
);
147 /* internal defines */
148 typedef struct DisasContext
{
149 struct TranslationBlock
*tb
;
153 /* Routine used to access memory */
155 /* Translation flags */
156 #if !defined(CONFIG_USER_ONLY)
159 #if defined(TARGET_PPC64)
163 ppc_spr_t
*spr_cb
; /* Needed to check rights for mfspr/mtspr */
164 int singlestep_enabled
;
167 struct opc_handler_t
{
170 /* instruction type */
173 void (*handler
)(DisasContext
*ctx
);
174 #if defined(DO_PPC_STATISTICS)
175 const unsigned char *oname
;
180 static inline void gen_set_Rc0 (DisasContext
*ctx
)
182 #if defined(TARGET_PPC64)
191 static inline void gen_update_nip (DisasContext
*ctx
, target_ulong nip
)
193 #if defined(TARGET_PPC64)
195 gen_op_update_nip_64(nip
>> 32, nip
);
198 gen_op_update_nip(nip
);
201 #define RET_EXCP(ctx, excp, error) \
203 if ((ctx)->exception == EXCP_NONE) { \
204 gen_update_nip(ctx, (ctx)->nip); \
206 gen_op_raise_exception_err((excp), (error)); \
207 ctx->exception = (excp); \
210 #define RET_INVAL(ctx) \
211 RET_EXCP((ctx), EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_INVAL)
213 #define RET_PRIVOPC(ctx) \
214 RET_EXCP((ctx), EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_OPC)
216 #define RET_PRIVREG(ctx) \
217 RET_EXCP((ctx), EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_REG)
219 /* Stop translation */
220 static inline void RET_STOP (DisasContext
*ctx
)
222 gen_update_nip(ctx
, ctx
->nip
);
223 ctx
->exception
= EXCP_MTMSR
;
226 /* No need to update nip here, as execution flow will change */
227 static inline void RET_CHG_FLOW (DisasContext
*ctx
)
229 ctx
->exception
= EXCP_MTMSR
;
232 #define GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \
233 static void gen_##name (DisasContext *ctx); \
234 GEN_OPCODE(name, opc1, opc2, opc3, inval, type); \
235 static void gen_##name (DisasContext *ctx)
237 typedef struct opcode_t
{
238 unsigned char opc1
, opc2
, opc3
;
239 #if HOST_LONG_BITS == 64 /* Explicitely align to 64 bits */
240 unsigned char pad
[5];
242 unsigned char pad
[1];
244 opc_handler_t handler
;
245 const unsigned char *oname
;
248 /*** Instruction decoding ***/
249 #define EXTRACT_HELPER(name, shift, nb) \
250 static inline uint32_t name (uint32_t opcode) \
252 return (opcode >> (shift)) & ((1 << (nb)) - 1); \
255 #define EXTRACT_SHELPER(name, shift, nb) \
256 static inline int32_t name (uint32_t opcode) \
258 return (int16_t)((opcode >> (shift)) & ((1 << (nb)) - 1)); \
262 EXTRACT_HELPER(opc1
, 26, 6);
264 EXTRACT_HELPER(opc2
, 1, 5);
266 EXTRACT_HELPER(opc3
, 6, 5);
267 /* Update Cr0 flags */
268 EXTRACT_HELPER(Rc
, 0, 1);
270 EXTRACT_HELPER(rD
, 21, 5);
272 EXTRACT_HELPER(rS
, 21, 5);
274 EXTRACT_HELPER(rA
, 16, 5);
276 EXTRACT_HELPER(rB
, 11, 5);
278 EXTRACT_HELPER(rC
, 6, 5);
280 EXTRACT_HELPER(crfD
, 23, 3);
281 EXTRACT_HELPER(crfS
, 18, 3);
282 EXTRACT_HELPER(crbD
, 21, 5);
283 EXTRACT_HELPER(crbA
, 16, 5);
284 EXTRACT_HELPER(crbB
, 11, 5);
286 EXTRACT_HELPER(_SPR
, 11, 10);
287 static inline uint32_t SPR (uint32_t opcode
)
289 uint32_t sprn
= _SPR(opcode
);
291 return ((sprn
>> 5) & 0x1F) | ((sprn
& 0x1F) << 5);
293 /*** Get constants ***/
294 EXTRACT_HELPER(IMM
, 12, 8);
295 /* 16 bits signed immediate value */
296 EXTRACT_SHELPER(SIMM
, 0, 16);
297 /* 16 bits unsigned immediate value */
298 EXTRACT_HELPER(UIMM
, 0, 16);
300 EXTRACT_HELPER(NB
, 11, 5);
302 EXTRACT_HELPER(SH
, 11, 5);
304 EXTRACT_HELPER(MB
, 6, 5);
306 EXTRACT_HELPER(ME
, 1, 5);
308 EXTRACT_HELPER(TO
, 21, 5);
310 EXTRACT_HELPER(CRM
, 12, 8);
311 EXTRACT_HELPER(FM
, 17, 8);
312 EXTRACT_HELPER(SR
, 16, 4);
313 EXTRACT_HELPER(FPIMM
, 20, 4);
315 /*** Jump target decoding ***/
317 EXTRACT_SHELPER(d
, 0, 16);
318 /* Immediate address */
319 static inline target_ulong
LI (uint32_t opcode
)
321 return (opcode
>> 0) & 0x03FFFFFC;
324 static inline uint32_t BD (uint32_t opcode
)
326 return (opcode
>> 0) & 0xFFFC;
329 EXTRACT_HELPER(BO
, 21, 5);
330 EXTRACT_HELPER(BI
, 16, 5);
331 /* Absolute/relative address */
332 EXTRACT_HELPER(AA
, 1, 1);
334 EXTRACT_HELPER(LK
, 0, 1);
336 /* Create a mask between <start> and <end> bits */
337 static inline target_ulong
MASK (uint32_t start
, uint32_t end
)
341 #if defined(TARGET_PPC64)
342 if (likely(start
== 0)) {
343 ret
= (uint64_t)(-1ULL) << (63 - end
);
344 } else if (likely(end
== 63)) {
345 ret
= (uint64_t)(-1ULL) >> start
;
348 if (likely(start
== 0)) {
349 ret
= (uint32_t)(-1ULL) << (31 - end
);
350 } else if (likely(end
== 31)) {
351 ret
= (uint32_t)(-1ULL) >> start
;
355 ret
= (((target_ulong
)(-1ULL)) >> (start
)) ^
356 (((target_ulong
)(-1ULL) >> (end
)) >> 1);
357 if (unlikely(start
> end
))
364 #if HOST_LONG_BITS == 64
369 #if defined(__APPLE__)
370 #define OPCODES_SECTION \
371 __attribute__ ((section("__TEXT,__opcodes"), unused, aligned (OPC_ALIGN) ))
373 #define OPCODES_SECTION \
374 __attribute__ ((section(".opcodes"), unused, aligned (OPC_ALIGN) ))
377 #if defined(DO_PPC_STATISTICS)
378 #define GEN_OPCODE(name, op1, op2, op3, invl, _typ) \
379 OPCODES_SECTION opcode_t opc_##name = { \
387 .handler = &gen_##name, \
388 .oname = stringify(name), \
390 .oname = stringify(name), \
393 #define GEN_OPCODE(name, op1, op2, op3, invl, _typ) \
394 OPCODES_SECTION opcode_t opc_##name = { \
402 .handler = &gen_##name, \
404 .oname = stringify(name), \
408 #define GEN_OPCODE_MARK(name) \
409 OPCODES_SECTION opcode_t opc_##name = { \
415 .inval = 0x00000000, \
419 .oname = stringify(name), \
422 /* Start opcode list */
423 GEN_OPCODE_MARK(start
);
425 /* Invalid instruction */
426 GEN_HANDLER(invalid
, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE
)
431 static opc_handler_t invalid_handler
= {
434 .handler
= gen_invalid
,
437 /*** Integer arithmetic ***/
438 #define __GEN_INT_ARITH2(name, opc1, opc2, opc3, inval, type) \
439 GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \
441 gen_op_load_gpr_T0(rA(ctx->opcode)); \
442 gen_op_load_gpr_T1(rB(ctx->opcode)); \
444 gen_op_store_T0_gpr(rD(ctx->opcode)); \
445 if (unlikely(Rc(ctx->opcode) != 0)) \
449 #define __GEN_INT_ARITH2_O(name, opc1, opc2, opc3, inval, type) \
450 GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \
452 gen_op_load_gpr_T0(rA(ctx->opcode)); \
453 gen_op_load_gpr_T1(rB(ctx->opcode)); \
455 gen_op_store_T0_gpr(rD(ctx->opcode)); \
456 if (unlikely(Rc(ctx->opcode) != 0)) \
460 #define __GEN_INT_ARITH1(name, opc1, opc2, opc3, type) \
461 GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type) \
463 gen_op_load_gpr_T0(rA(ctx->opcode)); \
465 gen_op_store_T0_gpr(rD(ctx->opcode)); \
466 if (unlikely(Rc(ctx->opcode) != 0)) \
469 #define __GEN_INT_ARITH1_O(name, opc1, opc2, opc3, type) \
470 GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type) \
472 gen_op_load_gpr_T0(rA(ctx->opcode)); \
474 gen_op_store_T0_gpr(rD(ctx->opcode)); \
475 if (unlikely(Rc(ctx->opcode) != 0)) \
479 /* Two operands arithmetic functions */
480 #define GEN_INT_ARITH2(name, opc1, opc2, opc3, type) \
481 __GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000000, type) \
482 __GEN_INT_ARITH2_O(name##o, opc1, opc2, opc3 | 0x10, 0x00000000, type)
484 /* Two operands arithmetic functions with no overflow allowed */
485 #define GEN_INT_ARITHN(name, opc1, opc2, opc3, type) \
486 __GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000400, type)
488 /* One operand arithmetic functions */
489 #define GEN_INT_ARITH1(name, opc1, opc2, opc3, type) \
490 __GEN_INT_ARITH1(name, opc1, opc2, opc3, type) \
491 __GEN_INT_ARITH1_O(name##o, opc1, opc2, opc3 | 0x10, type)
493 #if defined(TARGET_PPC64)
494 #define __GEN_INT_ARITH2_64(name, opc1, opc2, opc3, inval, type) \
495 GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \
497 gen_op_load_gpr_T0(rA(ctx->opcode)); \
498 gen_op_load_gpr_T1(rB(ctx->opcode)); \
500 gen_op_##name##_64(); \
503 gen_op_store_T0_gpr(rD(ctx->opcode)); \
504 if (unlikely(Rc(ctx->opcode) != 0)) \
508 #define __GEN_INT_ARITH2_O_64(name, opc1, opc2, opc3, inval, type) \
509 GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \
511 gen_op_load_gpr_T0(rA(ctx->opcode)); \
512 gen_op_load_gpr_T1(rB(ctx->opcode)); \
514 gen_op_##name##_64(); \
517 gen_op_store_T0_gpr(rD(ctx->opcode)); \
518 if (unlikely(Rc(ctx->opcode) != 0)) \
522 #define __GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type) \
523 GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type) \
525 gen_op_load_gpr_T0(rA(ctx->opcode)); \
527 gen_op_##name##_64(); \
530 gen_op_store_T0_gpr(rD(ctx->opcode)); \
531 if (unlikely(Rc(ctx->opcode) != 0)) \
534 #define __GEN_INT_ARITH1_O_64(name, opc1, opc2, opc3, type) \
535 GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type) \
537 gen_op_load_gpr_T0(rA(ctx->opcode)); \
539 gen_op_##name##_64(); \
542 gen_op_store_T0_gpr(rD(ctx->opcode)); \
543 if (unlikely(Rc(ctx->opcode) != 0)) \
547 /* Two operands arithmetic functions */
548 #define GEN_INT_ARITH2_64(name, opc1, opc2, opc3, type) \
549 __GEN_INT_ARITH2_64(name, opc1, opc2, opc3, 0x00000000, type) \
550 __GEN_INT_ARITH2_O_64(name##o, opc1, opc2, opc3 | 0x10, 0x00000000, type)
552 /* Two operands arithmetic functions with no overflow allowed */
553 #define GEN_INT_ARITHN_64(name, opc1, opc2, opc3, type) \
554 __GEN_INT_ARITH2_64(name, opc1, opc2, opc3, 0x00000400, type)
556 /* One operand arithmetic functions */
557 #define GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type) \
558 __GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type) \
559 __GEN_INT_ARITH1_O_64(name##o, opc1, opc2, opc3 | 0x10, type)
561 #define GEN_INT_ARITH2_64 GEN_INT_ARITH2
562 #define GEN_INT_ARITHN_64 GEN_INT_ARITHN
563 #define GEN_INT_ARITH1_64 GEN_INT_ARITH1
566 /* add add. addo addo. */
567 static inline void gen_op_addo (void)
573 #if defined(TARGET_PPC64)
574 #define gen_op_add_64 gen_op_add
575 static inline void gen_op_addo_64 (void)
579 gen_op_check_addo_64();
582 GEN_INT_ARITH2_64 (add
, 0x1F, 0x0A, 0x08, PPC_INTEGER
);
583 /* addc addc. addco addco. */
584 static inline void gen_op_addc (void)
590 static inline void gen_op_addco (void)
597 #if defined(TARGET_PPC64)
598 static inline void gen_op_addc_64 (void)
602 gen_op_check_addc_64();
604 static inline void gen_op_addco_64 (void)
608 gen_op_check_addc_64();
609 gen_op_check_addo_64();
612 GEN_INT_ARITH2_64 (addc
, 0x1F, 0x0A, 0x00, PPC_INTEGER
);
613 /* adde adde. addeo addeo. */
614 static inline void gen_op_addeo (void)
620 #if defined(TARGET_PPC64)
621 static inline void gen_op_addeo_64 (void)
625 gen_op_check_addo_64();
628 GEN_INT_ARITH2_64 (adde
, 0x1F, 0x0A, 0x04, PPC_INTEGER
);
629 /* addme addme. addmeo addmeo. */
630 static inline void gen_op_addme (void)
635 #if defined(TARGET_PPC64)
636 static inline void gen_op_addme_64 (void)
642 GEN_INT_ARITH1_64 (addme
, 0x1F, 0x0A, 0x07, PPC_INTEGER
);
643 /* addze addze. addzeo addzeo. */
644 static inline void gen_op_addze (void)
650 static inline void gen_op_addzeo (void)
657 #if defined(TARGET_PPC64)
658 static inline void gen_op_addze_64 (void)
662 gen_op_check_addc_64();
664 static inline void gen_op_addzeo_64 (void)
668 gen_op_check_addc_64();
669 gen_op_check_addo_64();
672 GEN_INT_ARITH1_64 (addze
, 0x1F, 0x0A, 0x06, PPC_INTEGER
);
673 /* divw divw. divwo divwo. */
674 GEN_INT_ARITH2 (divw
, 0x1F, 0x0B, 0x0F, PPC_INTEGER
);
675 /* divwu divwu. divwuo divwuo. */
676 GEN_INT_ARITH2 (divwu
, 0x1F, 0x0B, 0x0E, PPC_INTEGER
);
678 GEN_INT_ARITHN (mulhw
, 0x1F, 0x0B, 0x02, PPC_INTEGER
);
680 GEN_INT_ARITHN (mulhwu
, 0x1F, 0x0B, 0x00, PPC_INTEGER
);
681 /* mullw mullw. mullwo mullwo. */
682 GEN_INT_ARITH2 (mullw
, 0x1F, 0x0B, 0x07, PPC_INTEGER
);
683 /* neg neg. nego nego. */
684 GEN_INT_ARITH1_64 (neg
, 0x1F, 0x08, 0x03, PPC_INTEGER
);
685 /* subf subf. subfo subfo. */
686 static inline void gen_op_subfo (void)
690 gen_op_check_subfo();
692 #if defined(TARGET_PPC64)
693 #define gen_op_subf_64 gen_op_subf
694 static inline void gen_op_subfo_64 (void)
698 gen_op_check_subfo_64();
701 GEN_INT_ARITH2_64 (subf
, 0x1F, 0x08, 0x01, PPC_INTEGER
);
702 /* subfc subfc. subfco subfco. */
703 static inline void gen_op_subfc (void)
706 gen_op_check_subfc();
708 static inline void gen_op_subfco (void)
712 gen_op_check_subfc();
713 gen_op_check_subfo();
715 #if defined(TARGET_PPC64)
716 static inline void gen_op_subfc_64 (void)
719 gen_op_check_subfc_64();
721 static inline void gen_op_subfco_64 (void)
725 gen_op_check_subfc_64();
726 gen_op_check_subfo_64();
729 GEN_INT_ARITH2_64 (subfc
, 0x1F, 0x08, 0x00, PPC_INTEGER
);
730 /* subfe subfe. subfeo subfeo. */
731 static inline void gen_op_subfeo (void)
735 gen_op_check_subfo();
737 #if defined(TARGET_PPC64)
738 #define gen_op_subfe_64 gen_op_subfe
739 static inline void gen_op_subfeo_64 (void)
743 gen_op_check_subfo_64();
746 GEN_INT_ARITH2_64 (subfe
, 0x1F, 0x08, 0x04, PPC_INTEGER
);
747 /* subfme subfme. subfmeo subfmeo. */
748 GEN_INT_ARITH1_64 (subfme
, 0x1F, 0x08, 0x07, PPC_INTEGER
);
749 /* subfze subfze. subfzeo subfzeo. */
750 GEN_INT_ARITH1_64 (subfze
, 0x1F, 0x08, 0x06, PPC_INTEGER
);
752 GEN_HANDLER(addi
, 0x0E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
754 target_long simm
= SIMM(ctx
->opcode
);
756 if (rA(ctx
->opcode
) == 0) {
760 gen_op_load_gpr_T0(rA(ctx
->opcode
));
761 if (likely(simm
!= 0))
764 gen_op_store_T0_gpr(rD(ctx
->opcode
));
767 GEN_HANDLER(addic
, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
769 target_long simm
= SIMM(ctx
->opcode
);
771 gen_op_load_gpr_T0(rA(ctx
->opcode
));
772 if (likely(simm
!= 0)) {
775 #if defined(TARGET_PPC64)
777 gen_op_check_addc_64();
782 gen_op_store_T0_gpr(rD(ctx
->opcode
));
785 GEN_HANDLER(addic_
, 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
787 target_long simm
= SIMM(ctx
->opcode
);
789 gen_op_load_gpr_T0(rA(ctx
->opcode
));
790 if (likely(simm
!= 0)) {
793 #if defined(TARGET_PPC64)
795 gen_op_check_addc_64();
800 gen_op_store_T0_gpr(rD(ctx
->opcode
));
804 GEN_HANDLER(addis
, 0x0F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
806 target_long simm
= SIMM(ctx
->opcode
);
808 if (rA(ctx
->opcode
) == 0) {
810 gen_set_T0(simm
<< 16);
812 gen_op_load_gpr_T0(rA(ctx
->opcode
));
813 if (likely(simm
!= 0))
814 gen_op_addi(simm
<< 16);
816 gen_op_store_T0_gpr(rD(ctx
->opcode
));
819 GEN_HANDLER(mulli
, 0x07, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
821 gen_op_load_gpr_T0(rA(ctx
->opcode
));
822 gen_op_mulli(SIMM(ctx
->opcode
));
823 gen_op_store_T0_gpr(rD(ctx
->opcode
));
826 GEN_HANDLER(subfic
, 0x08, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
828 gen_op_load_gpr_T0(rA(ctx
->opcode
));
829 #if defined(TARGET_PPC64)
831 gen_op_subfic_64(SIMM(ctx
->opcode
));
834 gen_op_subfic(SIMM(ctx
->opcode
));
835 gen_op_store_T0_gpr(rD(ctx
->opcode
));
838 #if defined(TARGET_PPC64)
840 GEN_INT_ARITHN (mulhd
, 0x1F, 0x09, 0x02, PPC_INTEGER
);
842 GEN_INT_ARITHN (mulhdu
, 0x1F, 0x09, 0x00, PPC_INTEGER
);
843 /* mulld mulld. mulldo mulldo. */
844 GEN_INT_ARITH2 (mulld
, 0x1F, 0x09, 0x07, PPC_INTEGER
);
845 /* divd divd. divdo divdo. */
846 GEN_INT_ARITH2 (divd
, 0x1F, 0x09, 0x0F, PPC_INTEGER
);
847 /* divdu divdu. divduo divduo. */
848 GEN_INT_ARITH2 (divdu
, 0x1F, 0x09, 0x0E, PPC_INTEGER
);
851 /*** Integer comparison ***/
852 #if defined(TARGET_PPC64)
853 #define GEN_CMP(name, opc, type) \
854 GEN_HANDLER(name, 0x1F, 0x00, opc, 0x00400000, type) \
856 gen_op_load_gpr_T0(rA(ctx->opcode)); \
857 gen_op_load_gpr_T1(rB(ctx->opcode)); \
859 gen_op_##name##_64(); \
862 gen_op_store_T0_crf(crfD(ctx->opcode)); \
865 #define GEN_CMP(name, opc, type) \
866 GEN_HANDLER(name, 0x1F, 0x00, opc, 0x00400000, type) \
868 gen_op_load_gpr_T0(rA(ctx->opcode)); \
869 gen_op_load_gpr_T1(rB(ctx->opcode)); \
871 gen_op_store_T0_crf(crfD(ctx->opcode)); \
876 GEN_CMP(cmp
, 0x00, PPC_INTEGER
);
878 GEN_HANDLER(cmpi
, 0x0B, 0xFF, 0xFF, 0x00400000, PPC_INTEGER
)
880 gen_op_load_gpr_T0(rA(ctx
->opcode
));
881 #if defined(TARGET_PPC64)
883 gen_op_cmpi_64(SIMM(ctx
->opcode
));
886 gen_op_cmpi(SIMM(ctx
->opcode
));
887 gen_op_store_T0_crf(crfD(ctx
->opcode
));
890 GEN_CMP(cmpl
, 0x01, PPC_INTEGER
);
892 GEN_HANDLER(cmpli
, 0x0A, 0xFF, 0xFF, 0x00400000, PPC_INTEGER
)
894 gen_op_load_gpr_T0(rA(ctx
->opcode
));
895 #if defined(TARGET_PPC64)
897 gen_op_cmpli_64(UIMM(ctx
->opcode
));
900 gen_op_cmpli(UIMM(ctx
->opcode
));
901 gen_op_store_T0_crf(crfD(ctx
->opcode
));
904 /* isel (PowerPC 2.03 specification) */
905 GEN_HANDLER(isel
, 0x1F, 0x0F, 0x00, 0x00000001, PPC_203
)
907 uint32_t bi
= rC(ctx
->opcode
);
910 if (rA(ctx
->opcode
) == 0) {
913 gen_op_load_gpr_T1(rA(ctx
->opcode
));
915 gen_op_load_gpr_T2(rB(ctx
->opcode
));
916 mask
= 1 << (3 - (bi
& 0x03));
917 gen_op_load_crf_T0(bi
>> 2);
918 gen_op_test_true(mask
);
920 gen_op_store_T0_gpr(rD(ctx
->opcode
));
923 /*** Integer logical ***/
924 #define __GEN_LOGICAL2(name, opc2, opc3, type) \
925 GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000000, type) \
927 gen_op_load_gpr_T0(rS(ctx->opcode)); \
928 gen_op_load_gpr_T1(rB(ctx->opcode)); \
930 gen_op_store_T0_gpr(rA(ctx->opcode)); \
931 if (unlikely(Rc(ctx->opcode) != 0)) \
934 #define GEN_LOGICAL2(name, opc, type) \
935 __GEN_LOGICAL2(name, 0x1C, opc, type)
937 #define GEN_LOGICAL1(name, opc, type) \
938 GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, type) \
940 gen_op_load_gpr_T0(rS(ctx->opcode)); \
942 gen_op_store_T0_gpr(rA(ctx->opcode)); \
943 if (unlikely(Rc(ctx->opcode) != 0)) \
948 GEN_LOGICAL2(and, 0x00, PPC_INTEGER
);
950 GEN_LOGICAL2(andc
, 0x01, PPC_INTEGER
);
952 GEN_HANDLER(andi_
, 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
954 gen_op_load_gpr_T0(rS(ctx
->opcode
));
955 gen_op_andi_T0(UIMM(ctx
->opcode
));
956 gen_op_store_T0_gpr(rA(ctx
->opcode
));
960 GEN_HANDLER(andis_
, 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
962 gen_op_load_gpr_T0(rS(ctx
->opcode
));
963 gen_op_andi_T0(UIMM(ctx
->opcode
) << 16);
964 gen_op_store_T0_gpr(rA(ctx
->opcode
));
969 GEN_LOGICAL1(cntlzw
, 0x00, PPC_INTEGER
);
971 GEN_LOGICAL2(eqv
, 0x08, PPC_INTEGER
);
973 GEN_LOGICAL1(extsb
, 0x1D, PPC_INTEGER
);
975 GEN_LOGICAL1(extsh
, 0x1C, PPC_INTEGER
);
977 GEN_LOGICAL2(nand
, 0x0E, PPC_INTEGER
);
979 GEN_LOGICAL2(nor
, 0x03, PPC_INTEGER
);
982 GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER
)
986 rs
= rS(ctx
->opcode
);
987 ra
= rA(ctx
->opcode
);
988 rb
= rB(ctx
->opcode
);
989 /* Optimisation for mr. ri case */
990 if (rs
!= ra
|| rs
!= rb
) {
991 gen_op_load_gpr_T0(rs
);
993 gen_op_load_gpr_T1(rb
);
996 gen_op_store_T0_gpr(ra
);
997 if (unlikely(Rc(ctx
->opcode
) != 0))
999 } else if (unlikely(Rc(ctx
->opcode
) != 0)) {
1000 gen_op_load_gpr_T0(rs
);
1006 GEN_LOGICAL2(orc
, 0x0C, PPC_INTEGER
);
1008 GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER
)
1010 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1011 /* Optimisation for "set to zero" case */
1012 if (rS(ctx
->opcode
) != rB(ctx
->opcode
)) {
1013 gen_op_load_gpr_T1(rB(ctx
->opcode
));
1018 gen_op_store_T0_gpr(rA(ctx
->opcode
));
1019 if (unlikely(Rc(ctx
->opcode
) != 0))
1023 GEN_HANDLER(ori
, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
1025 target_ulong uimm
= UIMM(ctx
->opcode
);
1027 if (rS(ctx
->opcode
) == rA(ctx
->opcode
) && uimm
== 0) {
1029 /* XXX: should handle special NOPs for POWER series */
1032 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1033 if (likely(uimm
!= 0))
1035 gen_op_store_T0_gpr(rA(ctx
->opcode
));
1038 GEN_HANDLER(oris
, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
1040 target_ulong uimm
= UIMM(ctx
->opcode
);
1042 if (rS(ctx
->opcode
) == rA(ctx
->opcode
) && uimm
== 0) {
1046 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1047 if (likely(uimm
!= 0))
1048 gen_op_ori(uimm
<< 16);
1049 gen_op_store_T0_gpr(rA(ctx
->opcode
));
1052 GEN_HANDLER(xori
, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
1054 target_ulong uimm
= UIMM(ctx
->opcode
);
1056 if (rS(ctx
->opcode
) == rA(ctx
->opcode
) && uimm
== 0) {
1060 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1061 if (likely(uimm
!= 0))
1063 gen_op_store_T0_gpr(rA(ctx
->opcode
));
1067 GEN_HANDLER(xoris
, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
1069 target_ulong uimm
= UIMM(ctx
->opcode
);
1071 if (rS(ctx
->opcode
) == rA(ctx
->opcode
) && uimm
== 0) {
1075 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1076 if (likely(uimm
!= 0))
1077 gen_op_xori(uimm
<< 16);
1078 gen_op_store_T0_gpr(rA(ctx
->opcode
));
1081 /* popcntb : PowerPC 2.03 specification */
1082 GEN_HANDLER(popcntb
, 0x1F, 0x03, 0x03, 0x0000F801, PPC_203
)
1084 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1085 #if defined(TARGET_PPC64)
1087 gen_op_popcntb_64();
1091 gen_op_store_T0_gpr(rA(ctx
->opcode
));
1094 #if defined(TARGET_PPC64)
1095 /* extsw & extsw. */
1096 GEN_LOGICAL1(extsw
, 0x1E, PPC_64B
);
1098 GEN_LOGICAL1(cntlzd
, 0x01, PPC_64B
);
1101 /*** Integer rotate ***/
1102 /* rlwimi & rlwimi. */
1103 GEN_HANDLER(rlwimi
, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
1106 uint32_t mb
, me
, sh
;
1109 mb
= MB(ctx
->opcode
);
1110 me
= ME(ctx
->opcode
);
1111 sh
= SH(ctx
->opcode
);
1113 if (likely(sh
== 0)) {
1114 if (likely(mb
== 0 && me
== 31)) {
1115 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1117 } else if (likely(mb
== 31 && me
== 0)) {
1118 gen_op_load_gpr_T0(rA(ctx
->opcode
));
1121 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1122 gen_op_load_gpr_T1(rA(ctx
->opcode
));
1125 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1126 gen_op_load_gpr_T1(rA(ctx
->opcode
));
1127 gen_op_rotli32_T0(SH(ctx
->opcode
));
1129 #if defined(TARGET_PPC64)
1133 mask
= MASK(mb
, me
);
1134 gen_op_andi_T0(mask
);
1135 gen_op_andi_T1(~mask
);
1138 gen_op_store_T0_gpr(rA(ctx
->opcode
));
1139 if (unlikely(Rc(ctx
->opcode
) != 0))
1142 /* rlwinm & rlwinm. */
1143 GEN_HANDLER(rlwinm
, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
1145 uint32_t mb
, me
, sh
;
1147 sh
= SH(ctx
->opcode
);
1148 mb
= MB(ctx
->opcode
);
1149 me
= ME(ctx
->opcode
);
1150 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1151 if (likely(sh
== 0)) {
1154 if (likely(mb
== 0)) {
1155 if (likely(me
== 31)) {
1156 gen_op_rotli32_T0(sh
);
1158 } else if (likely(me
== (31 - sh
))) {
1162 } else if (likely(me
== 31)) {
1163 if (likely(sh
== (32 - mb
))) {
1168 gen_op_rotli32_T0(sh
);
1170 #if defined(TARGET_PPC64)
1174 gen_op_andi_T0(MASK(mb
, me
));
1176 gen_op_store_T0_gpr(rA(ctx
->opcode
));
1177 if (unlikely(Rc(ctx
->opcode
) != 0))
1180 /* rlwnm & rlwnm. */
1181 GEN_HANDLER(rlwnm
, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
1185 mb
= MB(ctx
->opcode
);
1186 me
= ME(ctx
->opcode
);
1187 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1188 gen_op_load_gpr_T1(rB(ctx
->opcode
));
1189 gen_op_rotl32_T0_T1();
1190 if (unlikely(mb
!= 0 || me
!= 31)) {
1191 #if defined(TARGET_PPC64)
1195 gen_op_andi_T0(MASK(mb
, me
));
1197 gen_op_store_T0_gpr(rA(ctx
->opcode
));
1198 if (unlikely(Rc(ctx
->opcode
) != 0))
1202 #if defined(TARGET_PPC64)
1203 #define GEN_PPC64_R2(name, opc1, opc2) \
1204 GEN_HANDLER(name##0, opc1, opc2, 0xFF, 0x00000000, PPC_64B) \
1206 gen_##name(ctx, 0); \
1208 GEN_HANDLER(name##1, opc1, opc2 | 0x10, 0xFF, 0x00000000, PPC_64B) \
1210 gen_##name(ctx, 1); \
1212 #define GEN_PPC64_R4(name, opc1, opc2) \
1213 GEN_HANDLER(name##0, opc1, opc2, 0xFF, 0x00000000, PPC_64B) \
1215 gen_##name(ctx, 0, 0); \
1217 GEN_HANDLER(name##1, opc1, opc2 | 0x01, 0xFF, 0x00000000, PPC_64B) \
1219 gen_##name(ctx, 0, 1); \
1221 GEN_HANDLER(name##2, opc1, opc2 | 0x10, 0xFF, 0x00000000, PPC_64B) \
1223 gen_##name(ctx, 1, 0); \
1225 GEN_HANDLER(name##3, opc1, opc2 | 0x11, 0xFF, 0x00000000, PPC_64B) \
1227 gen_##name(ctx, 1, 1); \
1229 /* rldicl - rldicl. */
1230 static inline void gen_rldicl (DisasContext
*ctx
, int mbn
, int shn
)
1234 sh
= SH(ctx
->opcode
) | (1 << shn
);
1235 mb
= (MB(ctx
->opcode
) << 1) | mbn
;
1239 GEN_PPC64_R4(rldicl
, 0x1E, 0x00)
1240 /* rldicr - rldicr. */
1241 static inline void gen_rldicr (DisasContext
*ctx
, int men
, int shn
)
1245 sh
= SH(ctx
->opcode
) | (1 << shn
);
1246 me
= (MB(ctx
->opcode
) << 1) | men
;
1250 GEN_PPC64_R4(rldicr
, 0x1E, 0x02)
1251 /* rldic - rldic. */
1252 static inline void gen_rldic (DisasContext
*ctx
, int mbn
, int shn
)
1256 sh
= SH(ctx
->opcode
) | (1 << shn
);
1257 mb
= (MB(ctx
->opcode
) << 1) | mbn
;
1261 GEN_PPC64_R4(rldic
, 0x1E, 0x04)
1262 /* rldcl - rldcl. */
1263 static inline void gen_rldcl (DisasContext
*ctx
, int mbn
)
1267 mb
= (MB(ctx
->opcode
) << 1) | mbn
;
1271 GEN_PPC64_R2(rldcl
, 0x1E, 0x08)
1272 /* rldcr - rldcr. */
1273 static inline void gen_rldcr (DisasContext
*ctx
, int men
)
1277 me
= (MB(ctx
->opcode
) << 1) | men
;
1281 GEN_PPC64_R2(rldcr
, 0x1E, 0x09)
1282 /* rldimi - rldimi. */
1283 static inline void gen_rldimi (DisasContext
*ctx
, int mbn
, int shn
)
1287 sh
= SH(ctx
->opcode
) | (1 << shn
);
1288 mb
= (MB(ctx
->opcode
) << 1) | mbn
;
1292 GEN_PPC64_R4(rldimi
, 0x1E, 0x06)
1295 /*** Integer shift ***/
1297 __GEN_LOGICAL2(slw
, 0x18, 0x00, PPC_INTEGER
);
1299 __GEN_LOGICAL2(sraw
, 0x18, 0x18, PPC_INTEGER
);
1300 /* srawi & srawi. */
1301 GEN_HANDLER(srawi
, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER
)
1304 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1305 if (SH(ctx
->opcode
) != 0) {
1306 gen_op_move_T1_T0();
1307 mb
= 32 - SH(ctx
->opcode
);
1309 #if defined(TARGET_PPC64)
1313 gen_op_srawi(SH(ctx
->opcode
), MASK(mb
, me
));
1315 gen_op_store_T0_gpr(rA(ctx
->opcode
));
1316 if (unlikely(Rc(ctx
->opcode
) != 0))
1320 __GEN_LOGICAL2(srw
, 0x18, 0x10, PPC_INTEGER
);
1322 #if defined(TARGET_PPC64)
1324 __GEN_LOGICAL2(sld
, 0x1B, 0x00, PPC_64B
);
1326 __GEN_LOGICAL2(srad
, 0x1A, 0x18, PPC_64B
);
1327 /* sradi & sradi. */
1328 static inline void gen_sradi (DisasContext
*ctx
, int n
)
1333 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1334 sh
= SH(ctx
->opcode
) + (n
<< 5);
1336 gen_op_move_T1_T0();
1337 mb
= 64 - SH(ctx
->opcode
);
1339 mask
= MASK(mb
, me
);
1340 gen_op_sradi(sh
, mask
>> 32, mask
);
1342 gen_op_store_T0_gpr(rA(ctx
->opcode
));
1343 if (unlikely(Rc(ctx
->opcode
) != 0))
1346 GEN_HANDLER(sradi0
, 0x1F, 0x1A, 0x19, 0x00000000, PPC_64B
)
1350 GEN_HANDLER(sradi1
, 0x1F, 0x1B, 0x19, 0x00000000, PPC_64B
)
1355 __GEN_LOGICAL2(srd
, 0x1B, 0x10, PPC_64B
);
1358 /*** Floating-Point arithmetic ***/
1359 #define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat) \
1360 GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, PPC_FLOAT) \
1362 if (unlikely(!ctx->fpu_enabled)) { \
1363 RET_EXCP(ctx, EXCP_NO_FP, 0); \
1366 gen_op_reset_scrfx(); \
1367 gen_op_load_fpr_FT0(rA(ctx->opcode)); \
1368 gen_op_load_fpr_FT1(rC(ctx->opcode)); \
1369 gen_op_load_fpr_FT2(rB(ctx->opcode)); \
1374 gen_op_store_FT0_fpr(rD(ctx->opcode)); \
1375 if (unlikely(Rc(ctx->opcode) != 0)) \
1379 #define GEN_FLOAT_ACB(name, op2) \
1380 _GEN_FLOAT_ACB(name, name, 0x3F, op2, 0); \
1381 _GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1);
1383 #define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat) \
1384 GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT) \
1386 if (unlikely(!ctx->fpu_enabled)) { \
1387 RET_EXCP(ctx, EXCP_NO_FP, 0); \
1390 gen_op_reset_scrfx(); \
1391 gen_op_load_fpr_FT0(rA(ctx->opcode)); \
1392 gen_op_load_fpr_FT1(rB(ctx->opcode)); \
1397 gen_op_store_FT0_fpr(rD(ctx->opcode)); \
1398 if (unlikely(Rc(ctx->opcode) != 0)) \
1401 #define GEN_FLOAT_AB(name, op2, inval) \
1402 _GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0); \
1403 _GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1);
1405 #define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat) \
1406 GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT) \
1408 if (unlikely(!ctx->fpu_enabled)) { \
1409 RET_EXCP(ctx, EXCP_NO_FP, 0); \
1412 gen_op_reset_scrfx(); \
1413 gen_op_load_fpr_FT0(rA(ctx->opcode)); \
1414 gen_op_load_fpr_FT1(rC(ctx->opcode)); \
1419 gen_op_store_FT0_fpr(rD(ctx->opcode)); \
1420 if (unlikely(Rc(ctx->opcode) != 0)) \
1423 #define GEN_FLOAT_AC(name, op2, inval) \
1424 _GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0); \
1425 _GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1);
1427 #define GEN_FLOAT_B(name, op2, op3) \
1428 GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, PPC_FLOAT) \
1430 if (unlikely(!ctx->fpu_enabled)) { \
1431 RET_EXCP(ctx, EXCP_NO_FP, 0); \
1434 gen_op_reset_scrfx(); \
1435 gen_op_load_fpr_FT0(rB(ctx->opcode)); \
1437 gen_op_store_FT0_fpr(rD(ctx->opcode)); \
1438 if (unlikely(Rc(ctx->opcode) != 0)) \
1442 #define GEN_FLOAT_BS(name, op1, op2) \
1443 GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, PPC_FLOAT) \
1445 if (unlikely(!ctx->fpu_enabled)) { \
1446 RET_EXCP(ctx, EXCP_NO_FP, 0); \
1449 gen_op_reset_scrfx(); \
1450 gen_op_load_fpr_FT0(rB(ctx->opcode)); \
1452 gen_op_store_FT0_fpr(rD(ctx->opcode)); \
1453 if (unlikely(Rc(ctx->opcode) != 0)) \
1458 GEN_FLOAT_AB(add
, 0x15, 0x000007C0);
1460 GEN_FLOAT_AB(div
, 0x12, 0x000007C0);
1462 GEN_FLOAT_AC(mul
, 0x19, 0x0000F800);
1464 /* fres */ /* XXX: not in 601 */
1465 GEN_FLOAT_BS(res
, 0x3B, 0x18);
1467 /* frsqrte */ /* XXX: not in 601 */
1468 GEN_FLOAT_BS(rsqrte
, 0x3F, 0x1A);
1470 /* fsel */ /* XXX: not in 601 */
1471 _GEN_FLOAT_ACB(sel
, sel
, 0x3F, 0x17, 0);
1473 GEN_FLOAT_AB(sub
, 0x14, 0x000007C0);
1476 GEN_HANDLER(fsqrt
, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_OPT
)
1478 if (unlikely(!ctx
->fpu_enabled
)) {
1479 RET_EXCP(ctx
, EXCP_NO_FP
, 0);
1482 gen_op_reset_scrfx();
1483 gen_op_load_fpr_FT0(rB(ctx
->opcode
));
1485 gen_op_store_FT0_fpr(rD(ctx
->opcode
));
1486 if (unlikely(Rc(ctx
->opcode
) != 0))
1490 GEN_HANDLER(fsqrts
, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_OPT
)
1492 if (unlikely(!ctx
->fpu_enabled
)) {
1493 RET_EXCP(ctx
, EXCP_NO_FP
, 0);
1496 gen_op_reset_scrfx();
1497 gen_op_load_fpr_FT0(rB(ctx
->opcode
));
1500 gen_op_store_FT0_fpr(rD(ctx
->opcode
));
1501 if (unlikely(Rc(ctx
->opcode
) != 0))
1505 /*** Floating-Point multiply-and-add ***/
1506 /* fmadd - fmadds */
1507 GEN_FLOAT_ACB(madd
, 0x1D);
1508 /* fmsub - fmsubs */
1509 GEN_FLOAT_ACB(msub
, 0x1C);
1510 /* fnmadd - fnmadds */
1511 GEN_FLOAT_ACB(nmadd
, 0x1F);
1512 /* fnmsub - fnmsubs */
1513 GEN_FLOAT_ACB(nmsub
, 0x1E);
1515 /*** Floating-Point round & convert ***/
1517 GEN_FLOAT_B(ctiw
, 0x0E, 0x00);
1519 GEN_FLOAT_B(ctiwz
, 0x0F, 0x00);
1521 GEN_FLOAT_B(rsp
, 0x0C, 0x00);
1523 /*** Floating-Point compare ***/
1525 GEN_HANDLER(fcmpo
, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT
)
1527 if (unlikely(!ctx
->fpu_enabled
)) {
1528 RET_EXCP(ctx
, EXCP_NO_FP
, 0);
1531 gen_op_reset_scrfx();
1532 gen_op_load_fpr_FT0(rA(ctx
->opcode
));
1533 gen_op_load_fpr_FT1(rB(ctx
->opcode
));
1535 gen_op_store_T0_crf(crfD(ctx
->opcode
));
1539 GEN_HANDLER(fcmpu
, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT
)
1541 if (unlikely(!ctx
->fpu_enabled
)) {
1542 RET_EXCP(ctx
, EXCP_NO_FP
, 0);
1545 gen_op_reset_scrfx();
1546 gen_op_load_fpr_FT0(rA(ctx
->opcode
));
1547 gen_op_load_fpr_FT1(rB(ctx
->opcode
));
1549 gen_op_store_T0_crf(crfD(ctx
->opcode
));
1552 /*** Floating-point move ***/
1554 GEN_FLOAT_B(abs
, 0x08, 0x08);
1557 GEN_HANDLER(fmr
, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT
)
1559 if (unlikely(!ctx
->fpu_enabled
)) {
1560 RET_EXCP(ctx
, EXCP_NO_FP
, 0);
1563 gen_op_reset_scrfx();
1564 gen_op_load_fpr_FT0(rB(ctx
->opcode
));
1565 gen_op_store_FT0_fpr(rD(ctx
->opcode
));
1566 if (unlikely(Rc(ctx
->opcode
) != 0))
1571 GEN_FLOAT_B(nabs
, 0x08, 0x04);
1573 GEN_FLOAT_B(neg
, 0x08, 0x01);
1575 /*** Floating-Point status & ctrl register ***/
1577 GEN_HANDLER(mcrfs
, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT
)
1579 if (unlikely(!ctx
->fpu_enabled
)) {
1580 RET_EXCP(ctx
, EXCP_NO_FP
, 0);
1583 gen_op_load_fpscr_T0(crfS(ctx
->opcode
));
1584 gen_op_store_T0_crf(crfD(ctx
->opcode
));
1585 gen_op_clear_fpscr(crfS(ctx
->opcode
));
1589 GEN_HANDLER(mffs
, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT
)
1591 if (unlikely(!ctx
->fpu_enabled
)) {
1592 RET_EXCP(ctx
, EXCP_NO_FP
, 0);
1595 gen_op_load_fpscr();
1596 gen_op_store_FT0_fpr(rD(ctx
->opcode
));
1597 if (unlikely(Rc(ctx
->opcode
) != 0))
1602 GEN_HANDLER(mtfsb0
, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT
)
1606 if (unlikely(!ctx
->fpu_enabled
)) {
1607 RET_EXCP(ctx
, EXCP_NO_FP
, 0);
1610 crb
= crbD(ctx
->opcode
) >> 2;
1611 gen_op_load_fpscr_T0(crb
);
1612 gen_op_andi_T0(~(1 << (crbD(ctx
->opcode
) & 0x03)));
1613 gen_op_store_T0_fpscr(crb
);
1614 if (unlikely(Rc(ctx
->opcode
) != 0))
1619 GEN_HANDLER(mtfsb1
, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT
)
1623 if (unlikely(!ctx
->fpu_enabled
)) {
1624 RET_EXCP(ctx
, EXCP_NO_FP
, 0);
1627 crb
= crbD(ctx
->opcode
) >> 2;
1628 gen_op_load_fpscr_T0(crb
);
1629 gen_op_ori(1 << (crbD(ctx
->opcode
) & 0x03));
1630 gen_op_store_T0_fpscr(crb
);
1631 if (unlikely(Rc(ctx
->opcode
) != 0))
1636 GEN_HANDLER(mtfsf
, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT
)
1638 if (unlikely(!ctx
->fpu_enabled
)) {
1639 RET_EXCP(ctx
, EXCP_NO_FP
, 0);
1642 gen_op_load_fpr_FT0(rB(ctx
->opcode
));
1643 gen_op_store_fpscr(FM(ctx
->opcode
));
1644 if (unlikely(Rc(ctx
->opcode
) != 0))
1649 GEN_HANDLER(mtfsfi
, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT
)
1651 if (unlikely(!ctx
->fpu_enabled
)) {
1652 RET_EXCP(ctx
, EXCP_NO_FP
, 0);
1655 gen_op_store_T0_fpscri(crbD(ctx
->opcode
) >> 2, FPIMM(ctx
->opcode
));
1656 if (unlikely(Rc(ctx
->opcode
) != 0))
1660 /*** Addressing modes ***/
1661 /* Register indirect with immediate index : EA = (rA|0) + SIMM */
1662 static inline void gen_addr_imm_index (DisasContext
*ctx
)
1664 target_long simm
= SIMM(ctx
->opcode
);
1666 if (rA(ctx
->opcode
) == 0) {
1669 gen_op_load_gpr_T0(rA(ctx
->opcode
));
1670 if (likely(simm
!= 0))
1675 static inline void gen_addr_reg_index (DisasContext
*ctx
)
1677 if (rA(ctx
->opcode
) == 0) {
1678 gen_op_load_gpr_T0(rB(ctx
->opcode
));
1680 gen_op_load_gpr_T0(rA(ctx
->opcode
));
1681 gen_op_load_gpr_T1(rB(ctx
->opcode
));
1686 static inline void gen_addr_register (DisasContext
*ctx
)
1688 if (rA(ctx
->opcode
) == 0) {
1691 gen_op_load_gpr_T0(rA(ctx
->opcode
));
1695 /*** Integer load ***/
1696 #define op_ldst(name) (*gen_op_##name[ctx->mem_idx])()
1697 #if defined(CONFIG_USER_ONLY)
1698 #if defined(TARGET_PPC64)
1699 #define OP_LD_TABLE(width) \
1700 static GenOpFunc *gen_op_l##width[] = { \
1701 &gen_op_l##width##_raw, \
1702 &gen_op_l##width##_le_raw, \
1703 &gen_op_l##width##_64_raw, \
1704 &gen_op_l##width##_le_64_raw, \
1706 #define OP_ST_TABLE(width) \
1707 static GenOpFunc *gen_op_st##width[] = { \
1708 &gen_op_st##width##_raw, \
1709 &gen_op_st##width##_le_raw, \
1710 &gen_op_st##width##_64_raw, \
1711 &gen_op_st##width##_le_64_raw, \
1713 /* Byte access routine are endian safe */
1714 #define gen_op_stb_le_64_raw gen_op_stb_64_raw
1715 #define gen_op_lbz_le_64_raw gen_op_lbz_64_raw
1717 #define OP_LD_TABLE(width) \
1718 static GenOpFunc *gen_op_l##width[] = { \
1719 &gen_op_l##width##_raw, \
1720 &gen_op_l##width##_le_raw, \
1722 #define OP_ST_TABLE(width) \
1723 static GenOpFunc *gen_op_st##width[] = { \
1724 &gen_op_st##width##_raw, \
1725 &gen_op_st##width##_le_raw, \
1728 /* Byte access routine are endian safe */
1729 #define gen_op_stb_le_raw gen_op_stb_raw
1730 #define gen_op_lbz_le_raw gen_op_lbz_raw
1732 #if defined(TARGET_PPC64)
1733 #define OP_LD_TABLE(width) \
1734 static GenOpFunc *gen_op_l##width[] = { \
1735 &gen_op_l##width##_user, \
1736 &gen_op_l##width##_le_user, \
1737 &gen_op_l##width##_kernel, \
1738 &gen_op_l##width##_le_kernel, \
1739 &gen_op_l##width##_64_user, \
1740 &gen_op_l##width##_le_64_user, \
1741 &gen_op_l##width##_64_kernel, \
1742 &gen_op_l##width##_le_64_kernel, \
1744 #define OP_ST_TABLE(width) \
1745 static GenOpFunc *gen_op_st##width[] = { \
1746 &gen_op_st##width##_user, \
1747 &gen_op_st##width##_le_user, \
1748 &gen_op_st##width##_kernel, \
1749 &gen_op_st##width##_le_kernel, \
1750 &gen_op_st##width##_64_user, \
1751 &gen_op_st##width##_le_64_user, \
1752 &gen_op_st##width##_64_kernel, \
1753 &gen_op_st##width##_le_64_kernel, \
1755 /* Byte access routine are endian safe */
1756 #define gen_op_stb_le_64_user gen_op_stb_64_user
1757 #define gen_op_lbz_le_64_user gen_op_lbz_64_user
1758 #define gen_op_stb_le_64_kernel gen_op_stb_64_kernel
1759 #define gen_op_lbz_le_64_kernel gen_op_lbz_64_kernel
1761 #define OP_LD_TABLE(width) \
1762 static GenOpFunc *gen_op_l##width[] = { \
1763 &gen_op_l##width##_user, \
1764 &gen_op_l##width##_le_user, \
1765 &gen_op_l##width##_kernel, \
1766 &gen_op_l##width##_le_kernel, \
1768 #define OP_ST_TABLE(width) \
1769 static GenOpFunc *gen_op_st##width[] = { \
1770 &gen_op_st##width##_user, \
1771 &gen_op_st##width##_le_user, \
1772 &gen_op_st##width##_kernel, \
1773 &gen_op_st##width##_le_kernel, \
1776 /* Byte access routine are endian safe */
1777 #define gen_op_stb_le_user gen_op_stb_user
1778 #define gen_op_lbz_le_user gen_op_lbz_user
1779 #define gen_op_stb_le_kernel gen_op_stb_kernel
1780 #define gen_op_lbz_le_kernel gen_op_lbz_kernel
1783 #define GEN_LD(width, opc, type) \
1784 GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, type) \
1786 gen_addr_imm_index(ctx); \
1787 op_ldst(l##width); \
1788 gen_op_store_T1_gpr(rD(ctx->opcode)); \
1791 #define GEN_LDU(width, opc, type) \
1792 GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, type) \
1794 if (unlikely(rA(ctx->opcode) == 0 || \
1795 rA(ctx->opcode) == rD(ctx->opcode))) { \
1799 gen_addr_imm_index(ctx); \
1800 op_ldst(l##width); \
1801 gen_op_store_T1_gpr(rD(ctx->opcode)); \
1802 gen_op_store_T0_gpr(rA(ctx->opcode)); \
1805 #define GEN_LDUX(width, opc2, opc3, type) \
1806 GEN_HANDLER(l##width##ux, 0x1F, opc2, opc3, 0x00000001, type) \
1808 if (unlikely(rA(ctx->opcode) == 0 || \
1809 rA(ctx->opcode) == rD(ctx->opcode))) { \
1813 gen_addr_reg_index(ctx); \
1814 op_ldst(l##width); \
1815 gen_op_store_T1_gpr(rD(ctx->opcode)); \
1816 gen_op_store_T0_gpr(rA(ctx->opcode)); \
1819 #define GEN_LDX(width, opc2, opc3, type) \
1820 GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, type) \
1822 gen_addr_reg_index(ctx); \
1823 op_ldst(l##width); \
1824 gen_op_store_T1_gpr(rD(ctx->opcode)); \
1827 #define GEN_LDS(width, op, type) \
1828 OP_LD_TABLE(width); \
1829 GEN_LD(width, op | 0x20, type); \
1830 GEN_LDU(width, op | 0x21, type); \
1831 GEN_LDUX(width, 0x17, op | 0x01, type); \
1832 GEN_LDX(width, 0x17, op | 0x00, type)
1834 /* lbz lbzu lbzux lbzx */
1835 GEN_LDS(bz
, 0x02, PPC_INTEGER
);
1836 /* lha lhau lhaux lhax */
1837 GEN_LDS(ha
, 0x0A, PPC_INTEGER
);
1838 /* lhz lhzu lhzux lhzx */
1839 GEN_LDS(hz
, 0x08, PPC_INTEGER
);
1840 /* lwz lwzu lwzux lwzx */
1841 GEN_LDS(wz
, 0x00, PPC_INTEGER
);
1842 #if defined(TARGET_PPC64)
1846 GEN_LDUX(wa
, 0x15, 0x0B, PPC_64B
);
1848 GEN_LDX(wa
, 0x15, 0x0A, PPC_64B
);
1850 GEN_LDUX(d
, 0x15, 0x01, PPC_64B
);
1852 GEN_LDX(d
, 0x15, 0x00, PPC_64B
);
1853 GEN_HANDLER(ld
, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B
)
1855 if (Rc(ctx
->opcode
)) {
1856 if (unlikely(rA(ctx
->opcode
) == 0 ||
1857 rA(ctx
->opcode
) == rD(ctx
->opcode
))) {
1862 gen_addr_imm_index(ctx
);
1863 if (ctx
->opcode
& 0x02) {
1864 /* lwa (lwau is undefined) */
1870 gen_op_store_T1_gpr(rD(ctx
->opcode
));
1871 if (Rc(ctx
->opcode
))
1872 gen_op_store_T0_gpr(rA(ctx
->opcode
));
1876 /*** Integer store ***/
1877 #define GEN_ST(width, opc, type) \
1878 GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, type) \
1880 gen_addr_imm_index(ctx); \
1881 gen_op_load_gpr_T1(rS(ctx->opcode)); \
1882 op_ldst(st##width); \
1885 #define GEN_STU(width, opc, type) \
1886 GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, type) \
1888 if (unlikely(rA(ctx->opcode) == 0)) { \
1892 gen_addr_imm_index(ctx); \
1893 gen_op_load_gpr_T1(rS(ctx->opcode)); \
1894 op_ldst(st##width); \
1895 gen_op_store_T0_gpr(rA(ctx->opcode)); \
1898 #define GEN_STUX(width, opc2, opc3, type) \
1899 GEN_HANDLER(st##width##ux, 0x1F, opc2, opc3, 0x00000001, type) \
1901 if (unlikely(rA(ctx->opcode) == 0)) { \
1905 gen_addr_reg_index(ctx); \
1906 gen_op_load_gpr_T1(rS(ctx->opcode)); \
1907 op_ldst(st##width); \
1908 gen_op_store_T0_gpr(rA(ctx->opcode)); \
1911 #define GEN_STX(width, opc2, opc3, type) \
1912 GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, type) \
1914 gen_addr_reg_index(ctx); \
1915 gen_op_load_gpr_T1(rS(ctx->opcode)); \
1916 op_ldst(st##width); \
1919 #define GEN_STS(width, op, type) \
1920 OP_ST_TABLE(width); \
1921 GEN_ST(width, op | 0x20, type); \
1922 GEN_STU(width, op | 0x21, type); \
1923 GEN_STUX(width, 0x17, op | 0x01, type); \
1924 GEN_STX(width, 0x17, op | 0x00, type)
1926 /* stb stbu stbux stbx */
1927 GEN_STS(b
, 0x06, PPC_INTEGER
);
1928 /* sth sthu sthux sthx */
1929 GEN_STS(h
, 0x0C, PPC_INTEGER
);
1930 /* stw stwu stwux stwx */
1931 GEN_STS(w
, 0x04, PPC_INTEGER
);
1932 #if defined(TARGET_PPC64)
1934 GEN_STUX(d
, 0x15, 0x01, PPC_64B
);
1935 GEN_STX(d
, 0x15, 0x00, PPC_64B
);
1936 GEN_HANDLER(std
, 0x3E, 0xFF, 0xFF, 0x00000002, PPC_64B
)
1938 if (Rc(ctx
->opcode
)) {
1939 if (unlikely(rA(ctx
->opcode
) == 0)) {
1944 gen_addr_imm_index(ctx
);
1945 gen_op_load_gpr_T1(rS(ctx
->opcode
));
1947 if (Rc(ctx
->opcode
))
1948 gen_op_store_T0_gpr(rA(ctx
->opcode
));
1951 /*** Integer load and store with byte reverse ***/
1954 GEN_LDX(hbr
, 0x16, 0x18, PPC_INTEGER
);
1957 GEN_LDX(wbr
, 0x16, 0x10, PPC_INTEGER
);
1960 GEN_STX(hbr
, 0x16, 0x1C, PPC_INTEGER
);
1963 GEN_STX(wbr
, 0x16, 0x14, PPC_INTEGER
);
1965 /*** Integer load and store multiple ***/
1966 #define op_ldstm(name, reg) (*gen_op_##name[ctx->mem_idx])(reg)
1967 #if defined(TARGET_PPC64)
1968 #if defined(CONFIG_USER_ONLY)
1969 static GenOpFunc1
*gen_op_lmw
[] = {
1973 &gen_op_lmw_le_64_raw
,
1975 static GenOpFunc1
*gen_op_stmw
[] = {
1976 &gen_op_stmw_64_raw
,
1977 &gen_op_stmw_le_64_raw
,
1980 static GenOpFunc1
*gen_op_lmw
[] = {
1982 &gen_op_lmw_le_user
,
1984 &gen_op_lmw_le_kernel
,
1985 &gen_op_lmw_64_user
,
1986 &gen_op_lmw_le_64_user
,
1987 &gen_op_lmw_64_kernel
,
1988 &gen_op_lmw_le_64_kernel
,
1990 static GenOpFunc1
*gen_op_stmw
[] = {
1992 &gen_op_stmw_le_user
,
1993 &gen_op_stmw_kernel
,
1994 &gen_op_stmw_le_kernel
,
1995 &gen_op_stmw_64_user
,
1996 &gen_op_stmw_le_64_user
,
1997 &gen_op_stmw_64_kernel
,
1998 &gen_op_stmw_le_64_kernel
,
2002 #if defined(CONFIG_USER_ONLY)
2003 static GenOpFunc1
*gen_op_lmw
[] = {
2007 static GenOpFunc1
*gen_op_stmw
[] = {
2009 &gen_op_stmw_le_raw
,
2012 static GenOpFunc1
*gen_op_lmw
[] = {
2014 &gen_op_lmw_le_user
,
2016 &gen_op_lmw_le_kernel
,
2018 static GenOpFunc1
*gen_op_stmw
[] = {
2020 &gen_op_stmw_le_user
,
2021 &gen_op_stmw_kernel
,
2022 &gen_op_stmw_le_kernel
,
2028 GEN_HANDLER(lmw
, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
2030 /* NIP cannot be restored if the memory exception comes from an helper */
2031 gen_update_nip(ctx
, ctx
->nip
- 4);
2032 gen_addr_imm_index(ctx
);
2033 op_ldstm(lmw
, rD(ctx
->opcode
));
2037 GEN_HANDLER(stmw
, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
2039 /* NIP cannot be restored if the memory exception comes from an helper */
2040 gen_update_nip(ctx
, ctx
->nip
- 4);
2041 gen_addr_imm_index(ctx
);
2042 op_ldstm(stmw
, rS(ctx
->opcode
));
2045 /*** Integer load and store strings ***/
2046 #define op_ldsts(name, start) (*gen_op_##name[ctx->mem_idx])(start)
2047 #define op_ldstsx(name, rd, ra, rb) (*gen_op_##name[ctx->mem_idx])(rd, ra, rb)
2048 #if defined(TARGET_PPC64)
2049 #if defined(CONFIG_USER_ONLY)
2050 static GenOpFunc1
*gen_op_lswi
[] = {
2052 &gen_op_lswi_le_raw
,
2053 &gen_op_lswi_64_raw
,
2054 &gen_op_lswi_le_64_raw
,
2056 static GenOpFunc3
*gen_op_lswx
[] = {
2058 &gen_op_lswx_le_raw
,
2059 &gen_op_lswx_64_raw
,
2060 &gen_op_lswx_le_64_raw
,
2062 static GenOpFunc1
*gen_op_stsw
[] = {
2064 &gen_op_stsw_le_raw
,
2065 &gen_op_stsw_64_raw
,
2066 &gen_op_stsw_le_64_raw
,
2069 static GenOpFunc1
*gen_op_lswi
[] = {
2071 &gen_op_lswi_le_user
,
2072 &gen_op_lswi_kernel
,
2073 &gen_op_lswi_le_kernel
,
2074 &gen_op_lswi_64_user
,
2075 &gen_op_lswi_le_64_user
,
2076 &gen_op_lswi_64_kernel
,
2077 &gen_op_lswi_le_64_kernel
,
2079 static GenOpFunc3
*gen_op_lswx
[] = {
2081 &gen_op_lswx_le_user
,
2082 &gen_op_lswx_kernel
,
2083 &gen_op_lswx_le_kernel
,
2084 &gen_op_lswx_64_user
,
2085 &gen_op_lswx_le_64_user
,
2086 &gen_op_lswx_64_kernel
,
2087 &gen_op_lswx_le_64_kernel
,
2089 static GenOpFunc1
*gen_op_stsw
[] = {
2091 &gen_op_stsw_le_user
,
2092 &gen_op_stsw_kernel
,
2093 &gen_op_stsw_le_kernel
,
2094 &gen_op_stsw_64_user
,
2095 &gen_op_stsw_le_64_user
,
2096 &gen_op_stsw_64_kernel
,
2097 &gen_op_stsw_le_64_kernel
,
2101 #if defined(CONFIG_USER_ONLY)
2102 static GenOpFunc1
*gen_op_lswi
[] = {
2104 &gen_op_lswi_le_raw
,
2106 static GenOpFunc3
*gen_op_lswx
[] = {
2108 &gen_op_lswx_le_raw
,
2110 static GenOpFunc1
*gen_op_stsw
[] = {
2112 &gen_op_stsw_le_raw
,
2115 static GenOpFunc1
*gen_op_lswi
[] = {
2117 &gen_op_lswi_le_user
,
2118 &gen_op_lswi_kernel
,
2119 &gen_op_lswi_le_kernel
,
2121 static GenOpFunc3
*gen_op_lswx
[] = {
2123 &gen_op_lswx_le_user
,
2124 &gen_op_lswx_kernel
,
2125 &gen_op_lswx_le_kernel
,
2127 static GenOpFunc1
*gen_op_stsw
[] = {
2129 &gen_op_stsw_le_user
,
2130 &gen_op_stsw_kernel
,
2131 &gen_op_stsw_le_kernel
,
2137 /* PowerPC32 specification says we must generate an exception if
2138 * rA is in the range of registers to be loaded.
2139 * In an other hand, IBM says this is valid, but rA won't be loaded.
2140 * For now, I'll follow the spec...
2142 GEN_HANDLER(lswi
, 0x1F, 0x15, 0x12, 0x00000001, PPC_INTEGER
)
2144 int nb
= NB(ctx
->opcode
);
2145 int start
= rD(ctx
->opcode
);
2146 int ra
= rA(ctx
->opcode
);
2152 if (unlikely(((start
+ nr
) > 32 &&
2153 start
<= ra
&& (start
+ nr
- 32) > ra
) ||
2154 ((start
+ nr
) <= 32 && start
<= ra
&& (start
+ nr
) > ra
))) {
2155 RET_EXCP(ctx
, EXCP_PROGRAM
, EXCP_INVAL
| EXCP_INVAL_LSWX
);
2158 /* NIP cannot be restored if the memory exception comes from an helper */
2159 gen_update_nip(ctx
, ctx
->nip
- 4);
2160 gen_addr_register(ctx
);
2162 op_ldsts(lswi
, start
);
2166 GEN_HANDLER(lswx
, 0x1F, 0x15, 0x10, 0x00000001, PPC_INTEGER
)
2168 int ra
= rA(ctx
->opcode
);
2169 int rb
= rB(ctx
->opcode
);
2171 /* NIP cannot be restored if the memory exception comes from an helper */
2172 gen_update_nip(ctx
, ctx
->nip
- 4);
2173 gen_addr_reg_index(ctx
);
2177 gen_op_load_xer_bc();
2178 op_ldstsx(lswx
, rD(ctx
->opcode
), ra
, rb
);
2182 GEN_HANDLER(stswi
, 0x1F, 0x15, 0x16, 0x00000001, PPC_INTEGER
)
2184 int nb
= NB(ctx
->opcode
);
2186 /* NIP cannot be restored if the memory exception comes from an helper */
2187 gen_update_nip(ctx
, ctx
->nip
- 4);
2188 gen_addr_register(ctx
);
2192 op_ldsts(stsw
, rS(ctx
->opcode
));
2196 GEN_HANDLER(stswx
, 0x1F, 0x15, 0x14, 0x00000001, PPC_INTEGER
)
2198 /* NIP cannot be restored if the memory exception comes from an helper */
2199 gen_update_nip(ctx
, ctx
->nip
- 4);
2200 gen_addr_reg_index(ctx
);
2201 gen_op_load_xer_bc();
2202 op_ldsts(stsw
, rS(ctx
->opcode
));
2205 /*** Memory synchronisation ***/
2207 GEN_HANDLER(eieio
, 0x1F, 0x16, 0x1A, 0x03FF0801, PPC_MEM_EIEIO
)
2212 GEN_HANDLER(isync
, 0x13, 0x16, 0x04, 0x03FF0801, PPC_MEM
)
2216 #define op_lwarx() (*gen_op_lwarx[ctx->mem_idx])()
2217 #define op_stwcx() (*gen_op_stwcx[ctx->mem_idx])()
2218 #if defined(TARGET_PPC64)
2219 #if defined(CONFIG_USER_ONLY)
2220 static GenOpFunc
*gen_op_lwarx
[] = {
2222 &gen_op_lwarx_le_raw
,
2223 &gen_op_lwarx_64_raw
,
2224 &gen_op_lwarx_le_64_raw
,
2226 static GenOpFunc
*gen_op_stwcx
[] = {
2228 &gen_op_stwcx_le_raw
,
2229 &gen_op_stwcx_64_raw
,
2230 &gen_op_stwcx_le_64_raw
,
2233 static GenOpFunc
*gen_op_lwarx
[] = {
2235 &gen_op_lwarx_le_user
,
2236 &gen_op_lwarx_kernel
,
2237 &gen_op_lwarx_le_kernel
,
2238 &gen_op_lwarx_64_user
,
2239 &gen_op_lwarx_le_64_user
,
2240 &gen_op_lwarx_64_kernel
,
2241 &gen_op_lwarx_le_64_kernel
,
2243 static GenOpFunc
*gen_op_stwcx
[] = {
2245 &gen_op_stwcx_le_user
,
2246 &gen_op_stwcx_kernel
,
2247 &gen_op_stwcx_le_kernel
,
2248 &gen_op_stwcx_64_user
,
2249 &gen_op_stwcx_le_64_user
,
2250 &gen_op_stwcx_64_kernel
,
2251 &gen_op_stwcx_le_64_kernel
,
2255 #if defined(CONFIG_USER_ONLY)
2256 static GenOpFunc
*gen_op_lwarx
[] = {
2258 &gen_op_lwarx_le_raw
,
2260 static GenOpFunc
*gen_op_stwcx
[] = {
2262 &gen_op_stwcx_le_raw
,
2265 static GenOpFunc
*gen_op_lwarx
[] = {
2267 &gen_op_lwarx_le_user
,
2268 &gen_op_lwarx_kernel
,
2269 &gen_op_lwarx_le_kernel
,
2271 static GenOpFunc
*gen_op_stwcx
[] = {
2273 &gen_op_stwcx_le_user
,
2274 &gen_op_stwcx_kernel
,
2275 &gen_op_stwcx_le_kernel
,
2281 GEN_HANDLER(lwarx
, 0x1F, 0x14, 0x00, 0x00000001, PPC_RES
)
2283 gen_addr_reg_index(ctx
);
2285 gen_op_store_T1_gpr(rD(ctx
->opcode
));
2289 GEN_HANDLER(stwcx_
, 0x1F, 0x16, 0x04, 0x00000000, PPC_RES
)
2291 gen_addr_reg_index(ctx
);
2292 gen_op_load_gpr_T1(rS(ctx
->opcode
));
2297 GEN_HANDLER(sync
, 0x1F, 0x16, 0x12, 0x03FF0801, PPC_MEM_SYNC
)
2301 /*** Floating-point load ***/
2302 #define GEN_LDF(width, opc) \
2303 GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
2305 if (unlikely(!ctx->fpu_enabled)) { \
2306 RET_EXCP(ctx, EXCP_NO_FP, 0); \
2309 gen_addr_imm_index(ctx); \
2310 op_ldst(l##width); \
2311 gen_op_store_FT0_fpr(rD(ctx->opcode)); \
2314 #define GEN_LDUF(width, opc) \
2315 GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
2317 if (unlikely(!ctx->fpu_enabled)) { \
2318 RET_EXCP(ctx, EXCP_NO_FP, 0); \
2321 if (unlikely(rA(ctx->opcode) == 0)) { \
2325 gen_addr_imm_index(ctx); \
2326 op_ldst(l##width); \
2327 gen_op_store_FT0_fpr(rD(ctx->opcode)); \
2328 gen_op_store_T0_gpr(rA(ctx->opcode)); \
2331 #define GEN_LDUXF(width, opc) \
2332 GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \
2334 if (unlikely(!ctx->fpu_enabled)) { \
2335 RET_EXCP(ctx, EXCP_NO_FP, 0); \
2338 if (unlikely(rA(ctx->opcode) == 0)) { \
2342 gen_addr_reg_index(ctx); \
2343 op_ldst(l##width); \
2344 gen_op_store_FT0_fpr(rD(ctx->opcode)); \
2345 gen_op_store_T0_gpr(rA(ctx->opcode)); \
2348 #define GEN_LDXF(width, opc2, opc3) \
2349 GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_FLOAT) \
2351 if (unlikely(!ctx->fpu_enabled)) { \
2352 RET_EXCP(ctx, EXCP_NO_FP, 0); \
2355 gen_addr_reg_index(ctx); \
2356 op_ldst(l##width); \
2357 gen_op_store_FT0_fpr(rD(ctx->opcode)); \
2360 #define GEN_LDFS(width, op) \
2361 OP_LD_TABLE(width); \
2362 GEN_LDF(width, op | 0x20); \
2363 GEN_LDUF(width, op | 0x21); \
2364 GEN_LDUXF(width, op | 0x01); \
2365 GEN_LDXF(width, 0x17, op | 0x00)
2367 /* lfd lfdu lfdux lfdx */
2369 /* lfs lfsu lfsux lfsx */
2372 /*** Floating-point store ***/
2373 #define GEN_STF(width, opc) \
2374 GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
2376 if (unlikely(!ctx->fpu_enabled)) { \
2377 RET_EXCP(ctx, EXCP_NO_FP, 0); \
2380 gen_addr_imm_index(ctx); \
2381 gen_op_load_fpr_FT0(rS(ctx->opcode)); \
2382 op_ldst(st##width); \
2385 #define GEN_STUF(width, opc) \
2386 GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
2388 if (unlikely(!ctx->fpu_enabled)) { \
2389 RET_EXCP(ctx, EXCP_NO_FP, 0); \
2392 if (unlikely(rA(ctx->opcode) == 0)) { \
2396 gen_addr_imm_index(ctx); \
2397 gen_op_load_fpr_FT0(rS(ctx->opcode)); \
2398 op_ldst(st##width); \
2399 gen_op_store_T0_gpr(rA(ctx->opcode)); \
2402 #define GEN_STUXF(width, opc) \
2403 GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \
2405 if (unlikely(!ctx->fpu_enabled)) { \
2406 RET_EXCP(ctx, EXCP_NO_FP, 0); \
2409 if (unlikely(rA(ctx->opcode) == 0)) { \
2413 gen_addr_reg_index(ctx); \
2414 gen_op_load_fpr_FT0(rS(ctx->opcode)); \
2415 op_ldst(st##width); \
2416 gen_op_store_T0_gpr(rA(ctx->opcode)); \
2419 #define GEN_STXF(width, opc2, opc3) \
2420 GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_FLOAT) \
2422 if (unlikely(!ctx->fpu_enabled)) { \
2423 RET_EXCP(ctx, EXCP_NO_FP, 0); \
2426 gen_addr_reg_index(ctx); \
2427 gen_op_load_fpr_FT0(rS(ctx->opcode)); \
2428 op_ldst(st##width); \
2431 #define GEN_STFS(width, op) \
2432 OP_ST_TABLE(width); \
2433 GEN_STF(width, op | 0x20); \
2434 GEN_STUF(width, op | 0x21); \
2435 GEN_STUXF(width, op | 0x01); \
2436 GEN_STXF(width, 0x17, op | 0x00)
2438 /* stfd stfdu stfdux stfdx */
2440 /* stfs stfsu stfsux stfsx */
2445 GEN_HANDLER(stfiwx
, 0x1F, 0x17, 0x1E, 0x00000001, PPC_FLOAT
)
2447 if (unlikely(!ctx
->fpu_enabled
)) {
2448 RET_EXCP(ctx
, EXCP_NO_FP
, 0);
2451 gen_addr_reg_index(ctx
);
2452 /* XXX: TODO: memcpy low order 32 bits of FRP(rs) into memory */
2458 static inline void gen_goto_tb(DisasContext
*ctx
, int n
, target_ulong dest
)
2460 TranslationBlock
*tb
;
2462 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
)) {
2464 gen_op_goto_tb0(TBPARAM(tb
));
2466 gen_op_goto_tb1(TBPARAM(tb
));
2468 #if defined(TARGET_PPC64)
2474 gen_op_set_T0((long)tb
+ n
);
2475 if (ctx
->singlestep_enabled
)
2480 #if defined(TARGET_PPC64)
2487 if (ctx
->singlestep_enabled
)
2494 GEN_HANDLER(b
, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW
)
2496 target_ulong li
, target
;
2498 /* sign extend LI */
2499 #if defined(TARGET_PPC64)
2501 li
= ((int64_t)LI(ctx
->opcode
) << 38) >> 38;
2504 li
= ((int32_t)LI(ctx
->opcode
) << 6) >> 6;
2505 if (likely(AA(ctx
->opcode
) == 0))
2506 target
= ctx
->nip
+ li
- 4;
2509 if (LK(ctx
->opcode
)) {
2510 #if defined(TARGET_PPC64)
2512 gen_op_setlr_64(ctx
->nip
>> 32, ctx
->nip
);
2515 gen_op_setlr(ctx
->nip
);
2517 gen_goto_tb(ctx
, 0, target
);
2518 ctx
->exception
= EXCP_BRANCH
;
2525 static inline void gen_bcond(DisasContext
*ctx
, int type
)
2527 target_ulong target
= 0;
2529 uint32_t bo
= BO(ctx
->opcode
);
2530 uint32_t bi
= BI(ctx
->opcode
);
2533 if ((bo
& 0x4) == 0)
2537 li
= (target_long
)((int16_t)(BD(ctx
->opcode
)));
2538 if (likely(AA(ctx
->opcode
) == 0)) {
2539 target
= ctx
->nip
+ li
- 4;
2545 gen_op_movl_T1_ctr();
2549 gen_op_movl_T1_lr();
2552 if (LK(ctx
->opcode
)) {
2553 #if defined(TARGET_PPC64)
2555 gen_op_setlr_64(ctx
->nip
>> 32, ctx
->nip
);
2558 gen_op_setlr(ctx
->nip
);
2561 /* No CR condition */
2564 #if defined(TARGET_PPC64)
2566 gen_op_test_ctr_64();
2572 #if defined(TARGET_PPC64)
2574 gen_op_test_ctrz_64();
2582 if (type
== BCOND_IM
) {
2583 gen_goto_tb(ctx
, 0, target
);
2585 #if defined(TARGET_PPC64)
2596 mask
= 1 << (3 - (bi
& 0x03));
2597 gen_op_load_crf_T0(bi
>> 2);
2601 #if defined(TARGET_PPC64)
2603 gen_op_test_ctr_true_64(mask
);
2606 gen_op_test_ctr_true(mask
);
2609 #if defined(TARGET_PPC64)
2611 gen_op_test_ctrz_true_64(mask
);
2614 gen_op_test_ctrz_true(mask
);
2619 gen_op_test_true(mask
);
2625 #if defined(TARGET_PPC64)
2627 gen_op_test_ctr_false_64(mask
);
2630 gen_op_test_ctr_false(mask
);
2633 #if defined(TARGET_PPC64)
2635 gen_op_test_ctrz_false_64(mask
);
2638 gen_op_test_ctrz_false(mask
);
2643 gen_op_test_false(mask
);
2648 if (type
== BCOND_IM
) {
2649 int l1
= gen_new_label();
2651 gen_goto_tb(ctx
, 0, target
);
2653 gen_goto_tb(ctx
, 1, ctx
->nip
);
2655 #if defined(TARGET_PPC64)
2657 gen_op_btest_T1_64(ctx
->nip
>> 32, ctx
->nip
);
2660 gen_op_btest_T1(ctx
->nip
);
2664 if (ctx
->singlestep_enabled
)
2667 ctx
->exception
= EXCP_BRANCH
;
2670 GEN_HANDLER(bc
, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW
)
2672 gen_bcond(ctx
, BCOND_IM
);
2675 GEN_HANDLER(bcctr
, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW
)
2677 gen_bcond(ctx
, BCOND_CTR
);
2680 GEN_HANDLER(bclr
, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW
)
2682 gen_bcond(ctx
, BCOND_LR
);
2685 /*** Condition register logical ***/
2686 #define GEN_CRLOGIC(op, opc) \
2687 GEN_HANDLER(cr##op, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER) \
2689 gen_op_load_crf_T0(crbA(ctx->opcode) >> 2); \
2690 gen_op_getbit_T0(3 - (crbA(ctx->opcode) & 0x03)); \
2691 gen_op_load_crf_T1(crbB(ctx->opcode) >> 2); \
2692 gen_op_getbit_T1(3 - (crbB(ctx->opcode) & 0x03)); \
2694 gen_op_load_crf_T1(crbD(ctx->opcode) >> 2); \
2695 gen_op_setcrfbit(~(1 << (3 - (crbD(ctx->opcode) & 0x03))), \
2696 3 - (crbD(ctx->opcode) & 0x03)); \
2697 gen_op_store_T1_crf(crbD(ctx->opcode) >> 2); \
2701 GEN_CRLOGIC(and, 0x08);
2703 GEN_CRLOGIC(andc
, 0x04);
2705 GEN_CRLOGIC(eqv
, 0x09);
2707 GEN_CRLOGIC(nand
, 0x07);
2709 GEN_CRLOGIC(nor
, 0x01);
2711 GEN_CRLOGIC(or, 0x0E);
2713 GEN_CRLOGIC(orc
, 0x0D);
2715 GEN_CRLOGIC(xor, 0x06);
2717 GEN_HANDLER(mcrf
, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER
)
2719 gen_op_load_crf_T0(crfS(ctx
->opcode
));
2720 gen_op_store_T0_crf(crfD(ctx
->opcode
));
2723 /*** System linkage ***/
2724 /* rfi (supervisor only) */
2725 GEN_HANDLER(rfi
, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW
)
2727 #if defined(CONFIG_USER_ONLY)
2730 /* Restore CPU state */
2731 if (unlikely(!ctx
->supervisor
)) {
2735 #if defined(TARGET_PPC64)
2746 GEN_HANDLER(sc
, 0x11, 0xFF, 0xFF, 0x03FFFFFD, PPC_FLOW
)
2748 #if defined(CONFIG_USER_ONLY)
2749 RET_EXCP(ctx
, EXCP_SYSCALL_USER
, 0);
2751 RET_EXCP(ctx
, EXCP_SYSCALL
, 0);
2757 GEN_HANDLER(tw
, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW
)
2759 gen_op_load_gpr_T0(rA(ctx
->opcode
));
2760 gen_op_load_gpr_T1(rB(ctx
->opcode
));
2761 /* Update the nip since this might generate a trap exception */
2762 gen_update_nip(ctx
, ctx
->nip
);
2763 gen_op_tw(TO(ctx
->opcode
));
2767 GEN_HANDLER(twi
, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW
)
2769 gen_op_load_gpr_T0(rA(ctx
->opcode
));
2770 gen_set_T1(SIMM(ctx
->opcode
));
2771 /* Update the nip since this might generate a trap exception */
2772 gen_update_nip(ctx
, ctx
->nip
);
2773 gen_op_tw(TO(ctx
->opcode
));
2776 #if defined(TARGET_PPC64)
2778 GEN_HANDLER(td
, 0x1F, 0x04, 0x02, 0x00000001, PPC_64B
)
2780 gen_op_load_gpr_T0(rA(ctx
->opcode
));
2781 gen_op_load_gpr_T1(rB(ctx
->opcode
));
2782 /* Update the nip since this might generate a trap exception */
2783 gen_update_nip(ctx
, ctx
->nip
);
2784 gen_op_td(TO(ctx
->opcode
));
2788 GEN_HANDLER(tdi
, 0x02, 0xFF, 0xFF, 0x00000000, PPC_64B
)
2790 gen_op_load_gpr_T0(rA(ctx
->opcode
));
2791 gen_set_T1(SIMM(ctx
->opcode
));
2792 /* Update the nip since this might generate a trap exception */
2793 gen_update_nip(ctx
, ctx
->nip
);
2794 gen_op_td(TO(ctx
->opcode
));
2798 /*** Processor control ***/
2800 GEN_HANDLER(mcrxr
, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC
)
2802 gen_op_load_xer_cr();
2803 gen_op_store_T0_crf(crfD(ctx
->opcode
));
2804 gen_op_clear_xer_cr();
2808 GEN_HANDLER(mfcr
, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC
)
2812 if (likely(ctx
->opcode
& 0x00100000)) {
2813 crm
= CRM(ctx
->opcode
);
2814 if (likely((crm
^ (crm
- 1)) == 0)) {
2816 gen_op_load_cro(7 - crn
);
2821 gen_op_store_T0_gpr(rD(ctx
->opcode
));
2825 GEN_HANDLER(mfmsr
, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC
)
2827 #if defined(CONFIG_USER_ONLY)
2830 if (unlikely(!ctx
->supervisor
)) {
2835 gen_op_store_T0_gpr(rD(ctx
->opcode
));
2840 #define SPR_NOACCESS ((void *)(-1))
2842 static void spr_noaccess (void *opaque
, int sprn
)
2844 sprn
= ((sprn
>> 5) & 0x1F) | ((sprn
& 0x1F) << 5);
2845 printf("ERROR: try to access SPR %d !\n", sprn
);
2847 #define SPR_NOACCESS (&spr_noaccess)
2851 static inline void gen_op_mfspr (DisasContext
*ctx
)
2853 void (*read_cb
)(void *opaque
, int sprn
);
2854 uint32_t sprn
= SPR(ctx
->opcode
);
2856 #if !defined(CONFIG_USER_ONLY)
2857 if (ctx
->supervisor
)
2858 read_cb
= ctx
->spr_cb
[sprn
].oea_read
;
2861 read_cb
= ctx
->spr_cb
[sprn
].uea_read
;
2862 if (likely(read_cb
!= NULL
)) {
2863 if (likely(read_cb
!= SPR_NOACCESS
)) {
2864 (*read_cb
)(ctx
, sprn
);
2865 gen_op_store_T0_gpr(rD(ctx
->opcode
));
2867 /* Privilege exception */
2869 fprintf(logfile
, "Trying to read priviledged spr %d %03x\n",
2872 printf("Trying to read priviledged spr %d %03x\n", sprn
, sprn
);
2878 fprintf(logfile
, "Trying to read invalid spr %d %03x\n",
2881 printf("Trying to read invalid spr %d %03x\n", sprn
, sprn
);
2882 RET_EXCP(ctx
, EXCP_PROGRAM
, EXCP_INVAL
| EXCP_INVAL_SPR
);
2886 GEN_HANDLER(mfspr
, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC
)
2892 GEN_HANDLER(mftb
, 0x1F, 0x13, 0x0B, 0x00000001, PPC_TB
)
2898 GEN_HANDLER(mtcrf
, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC
)
2902 gen_op_load_gpr_T0(rS(ctx
->opcode
));
2903 crm
= CRM(ctx
->opcode
);
2904 if (likely((ctx
->opcode
& 0x00100000) || (crm
^ (crm
- 1)) == 0)) {
2906 gen_op_srli_T0(crn
* 4);
2907 gen_op_andi_T0(0xF);
2908 gen_op_store_cro(7 - crn
);
2910 gen_op_store_cr(crm
);
2915 GEN_HANDLER(mtmsr
, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC
)
2917 #if defined(CONFIG_USER_ONLY)
2920 if (unlikely(!ctx
->supervisor
)) {
2924 gen_update_nip(ctx
, ctx
->nip
);
2925 gen_op_load_gpr_T0(rS(ctx
->opcode
));
2926 #if defined(TARGET_PPC64)
2928 gen_op_store_msr_32();
2932 /* Must stop the translation as machine state (may have) changed */
2938 GEN_HANDLER(mtspr
, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC
)
2940 void (*write_cb
)(void *opaque
, int sprn
);
2941 uint32_t sprn
= SPR(ctx
->opcode
);
2943 #if !defined(CONFIG_USER_ONLY)
2944 if (ctx
->supervisor
)
2945 write_cb
= ctx
->spr_cb
[sprn
].oea_write
;
2948 write_cb
= ctx
->spr_cb
[sprn
].uea_write
;
2949 if (likely(write_cb
!= NULL
)) {
2950 if (likely(write_cb
!= SPR_NOACCESS
)) {
2951 gen_op_load_gpr_T0(rS(ctx
->opcode
));
2952 (*write_cb
)(ctx
, sprn
);
2954 /* Privilege exception */
2956 fprintf(logfile
, "Trying to write priviledged spr %d %03x\n",
2959 printf("Trying to write priviledged spr %d %03x\n", sprn
, sprn
);
2965 fprintf(logfile
, "Trying to write invalid spr %d %03x\n",
2968 printf("Trying to write invalid spr %d %03x\n", sprn
, sprn
);
2969 RET_EXCP(ctx
, EXCP_PROGRAM
, EXCP_INVAL
| EXCP_INVAL_SPR
);
2973 /*** Cache management ***/
2974 /* For now, all those will be implemented as nop:
2975 * this is valid, regarding the PowerPC specs...
2976 * We just have to flush tb while invalidating instruction cache lines...
2979 GEN_HANDLER(dcbf
, 0x1F, 0x16, 0x02, 0x03E00001, PPC_CACHE
)
2981 gen_addr_reg_index(ctx
);
2985 /* dcbi (Supervisor only) */
2986 GEN_HANDLER(dcbi
, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE
)
2988 #if defined(CONFIG_USER_ONLY)
2991 if (unlikely(!ctx
->supervisor
)) {
2995 gen_addr_reg_index(ctx
);
2996 /* XXX: specification says this should be treated as a store by the MMU */
3003 GEN_HANDLER(dcbst
, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE
)
3005 /* XXX: specification say this is treated as a load by the MMU */
3006 gen_addr_reg_index(ctx
);
3011 GEN_HANDLER(dcbt
, 0x1F, 0x16, 0x08, 0x03E00001, PPC_CACHE
)
3013 /* XXX: specification say this is treated as a load by the MMU
3014 * but does not generate any exception
3019 GEN_HANDLER(dcbtst
, 0x1F, 0x16, 0x07, 0x03E00001, PPC_CACHE
)
3021 /* XXX: specification say this is treated as a load by the MMU
3022 * but does not generate any exception
3027 #define op_dcbz() (*gen_op_dcbz[ctx->mem_idx])()
3028 #if defined(TARGET_PPC64)
3029 #if defined(CONFIG_USER_ONLY)
3030 static GenOpFunc
*gen_op_dcbz
[] = {
3033 &gen_op_dcbz_64_raw
,
3034 &gen_op_dcbz_64_raw
,
3037 static GenOpFunc
*gen_op_dcbz
[] = {
3040 &gen_op_dcbz_kernel
,
3041 &gen_op_dcbz_kernel
,
3042 &gen_op_dcbz_64_user
,
3043 &gen_op_dcbz_64_user
,
3044 &gen_op_dcbz_64_kernel
,
3045 &gen_op_dcbz_64_kernel
,
3049 #if defined(CONFIG_USER_ONLY)
3050 static GenOpFunc
*gen_op_dcbz
[] = {
3055 static GenOpFunc
*gen_op_dcbz
[] = {
3058 &gen_op_dcbz_kernel
,
3059 &gen_op_dcbz_kernel
,
3064 GEN_HANDLER(dcbz
, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE
)
3066 gen_addr_reg_index(ctx
);
3068 gen_op_check_reservation();
3072 #define op_icbi() (*gen_op_icbi[ctx->mem_idx])()
3073 #if defined(TARGET_PPC64)
3074 #if defined(CONFIG_USER_ONLY)
3075 static GenOpFunc
*gen_op_icbi
[] = {
3078 &gen_op_icbi_64_raw
,
3079 &gen_op_icbi_64_raw
,
3082 static GenOpFunc
*gen_op_icbi
[] = {
3085 &gen_op_icbi_kernel
,
3086 &gen_op_icbi_kernel
,
3087 &gen_op_icbi_64_user
,
3088 &gen_op_icbi_64_user
,
3089 &gen_op_icbi_64_kernel
,
3090 &gen_op_icbi_64_kernel
,
3094 #if defined(CONFIG_USER_ONLY)
3095 static GenOpFunc
*gen_op_icbi
[] = {
3100 static GenOpFunc
*gen_op_icbi
[] = {
3103 &gen_op_icbi_kernel
,
3104 &gen_op_icbi_kernel
,
3108 GEN_HANDLER(icbi
, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE
)
3110 /* NIP cannot be restored if the memory exception comes from an helper */
3111 gen_update_nip(ctx
, ctx
->nip
- 4);
3112 gen_addr_reg_index(ctx
);
3119 GEN_HANDLER(dcba
, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_OPT
)
3123 /*** Segment register manipulation ***/
3124 /* Supervisor only: */
3126 GEN_HANDLER(mfsr
, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT
)
3128 #if defined(CONFIG_USER_ONLY)
3131 if (unlikely(!ctx
->supervisor
)) {
3135 gen_op_set_T1(SR(ctx
->opcode
));
3137 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3142 GEN_HANDLER(mfsrin
, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT
)
3144 #if defined(CONFIG_USER_ONLY)
3147 if (unlikely(!ctx
->supervisor
)) {
3151 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3154 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3159 GEN_HANDLER(mtsr
, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT
)
3161 #if defined(CONFIG_USER_ONLY)
3164 if (unlikely(!ctx
->supervisor
)) {
3168 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3169 gen_op_set_T1(SR(ctx
->opcode
));
3176 GEN_HANDLER(mtsrin
, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT
)
3178 #if defined(CONFIG_USER_ONLY)
3181 if (unlikely(!ctx
->supervisor
)) {
3185 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3186 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3193 /*** Lookaside buffer management ***/
3194 /* Optional & supervisor only: */
3196 GEN_HANDLER(tlbia
, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA
)
3198 #if defined(CONFIG_USER_ONLY)
3201 if (unlikely(!ctx
->supervisor
)) {
3203 fprintf(logfile
, "%s: ! supervisor\n", __func__
);
3213 GEN_HANDLER(tlbie
, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE
)
3215 #if defined(CONFIG_USER_ONLY)
3218 if (unlikely(!ctx
->supervisor
)) {
3222 gen_op_load_gpr_T0(rB(ctx
->opcode
));
3223 #if defined(TARGET_PPC64)
3234 GEN_HANDLER(tlbsync
, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC
)
3236 #if defined(CONFIG_USER_ONLY)
3239 if (unlikely(!ctx
->supervisor
)) {
3243 /* This has no effect: it should ensure that all previous
3244 * tlbie have completed
3250 /*** External control ***/
3252 #define op_eciwx() (*gen_op_eciwx[ctx->mem_idx])()
3253 #define op_ecowx() (*gen_op_ecowx[ctx->mem_idx])()
3254 #if defined(TARGET_PPC64)
3255 #if defined(CONFIG_USER_ONLY)
3256 static GenOpFunc
*gen_op_eciwx
[] = {
3258 &gen_op_eciwx_le_raw
,
3259 &gen_op_eciwx_64_raw
,
3260 &gen_op_eciwx_le_64_raw
,
3262 static GenOpFunc
*gen_op_ecowx
[] = {
3264 &gen_op_ecowx_le_raw
,
3265 &gen_op_ecowx_64_raw
,
3266 &gen_op_ecowx_le_64_raw
,
3269 static GenOpFunc
*gen_op_eciwx
[] = {
3271 &gen_op_eciwx_le_user
,
3272 &gen_op_eciwx_kernel
,
3273 &gen_op_eciwx_le_kernel
,
3274 &gen_op_eciwx_64_user
,
3275 &gen_op_eciwx_le_64_user
,
3276 &gen_op_eciwx_64_kernel
,
3277 &gen_op_eciwx_le_64_kernel
,
3279 static GenOpFunc
*gen_op_ecowx
[] = {
3281 &gen_op_ecowx_le_user
,
3282 &gen_op_ecowx_kernel
,
3283 &gen_op_ecowx_le_kernel
,
3284 &gen_op_ecowx_64_user
,
3285 &gen_op_ecowx_le_64_user
,
3286 &gen_op_ecowx_64_kernel
,
3287 &gen_op_ecowx_le_64_kernel
,
3291 #if defined(CONFIG_USER_ONLY)
3292 static GenOpFunc
*gen_op_eciwx
[] = {
3294 &gen_op_eciwx_le_raw
,
3296 static GenOpFunc
*gen_op_ecowx
[] = {
3298 &gen_op_ecowx_le_raw
,
3301 static GenOpFunc
*gen_op_eciwx
[] = {
3303 &gen_op_eciwx_le_user
,
3304 &gen_op_eciwx_kernel
,
3305 &gen_op_eciwx_le_kernel
,
3307 static GenOpFunc
*gen_op_ecowx
[] = {
3309 &gen_op_ecowx_le_user
,
3310 &gen_op_ecowx_kernel
,
3311 &gen_op_ecowx_le_kernel
,
3317 GEN_HANDLER(eciwx
, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN
)
3319 /* Should check EAR[E] & alignment ! */
3320 gen_addr_reg_index(ctx
);
3322 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3326 GEN_HANDLER(ecowx
, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN
)
3328 /* Should check EAR[E] & alignment ! */
3329 gen_addr_reg_index(ctx
);
3330 gen_op_load_gpr_T1(rS(ctx
->opcode
));
3334 /* PowerPC 601 specific instructions */
3336 GEN_HANDLER(abs
, 0x1F, 0x08, 0x0B, 0x0000F800, PPC_POWER_BR
)
3338 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3340 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3341 if (unlikely(Rc(ctx
->opcode
) != 0))
3346 GEN_HANDLER(abso
, 0x1F, 0x08, 0x1B, 0x0000F800, PPC_POWER_BR
)
3348 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3349 gen_op_POWER_abso();
3350 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3351 if (unlikely(Rc(ctx
->opcode
) != 0))
3356 GEN_HANDLER(clcs
, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR
) /* 601 ? */
3358 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3359 gen_op_POWER_clcs();
3360 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3364 GEN_HANDLER(div
, 0x1F, 0x0B, 0x0A, 0x00000000, PPC_POWER_BR
)
3366 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3367 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3369 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3370 if (unlikely(Rc(ctx
->opcode
) != 0))
3375 GEN_HANDLER(divo
, 0x1F, 0x0B, 0x1A, 0x00000000, PPC_POWER_BR
)
3377 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3378 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3379 gen_op_POWER_divo();
3380 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3381 if (unlikely(Rc(ctx
->opcode
) != 0))
3386 GEN_HANDLER(divs
, 0x1F, 0x0B, 0x0B, 0x00000000, PPC_POWER_BR
)
3388 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3389 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3390 gen_op_POWER_divs();
3391 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3392 if (unlikely(Rc(ctx
->opcode
) != 0))
3396 /* divso - divso. */
3397 GEN_HANDLER(divso
, 0x1F, 0x0B, 0x1B, 0x00000000, PPC_POWER_BR
)
3399 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3400 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3401 gen_op_POWER_divso();
3402 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3403 if (unlikely(Rc(ctx
->opcode
) != 0))
3408 GEN_HANDLER(doz
, 0x1F, 0x08, 0x08, 0x00000000, PPC_POWER_BR
)
3410 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3411 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3413 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3414 if (unlikely(Rc(ctx
->opcode
) != 0))
3419 GEN_HANDLER(dozo
, 0x1F, 0x08, 0x18, 0x00000000, PPC_POWER_BR
)
3421 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3422 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3423 gen_op_POWER_dozo();
3424 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3425 if (unlikely(Rc(ctx
->opcode
) != 0))
3430 GEN_HANDLER(dozi
, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR
)
3432 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3433 gen_op_set_T1(SIMM(ctx
->opcode
));
3435 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3438 /* As lscbx load from memory byte after byte, it's always endian safe */
3439 #define op_POWER_lscbx(start, ra, rb) \
3440 (*gen_op_POWER_lscbx[ctx->mem_idx])(start, ra, rb)
3441 #if defined(CONFIG_USER_ONLY)
3442 static GenOpFunc3
*gen_op_POWER_lscbx
[] = {
3443 &gen_op_POWER_lscbx_raw
,
3444 &gen_op_POWER_lscbx_raw
,
3447 static GenOpFunc3
*gen_op_POWER_lscbx
[] = {
3448 &gen_op_POWER_lscbx_user
,
3449 &gen_op_POWER_lscbx_user
,
3450 &gen_op_POWER_lscbx_kernel
,
3451 &gen_op_POWER_lscbx_kernel
,
3455 /* lscbx - lscbx. */
3456 GEN_HANDLER(lscbx
, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR
)
3458 int ra
= rA(ctx
->opcode
);
3459 int rb
= rB(ctx
->opcode
);
3461 gen_addr_reg_index(ctx
);
3465 /* NIP cannot be restored if the memory exception comes from an helper */
3466 gen_update_nip(ctx
, ctx
->nip
- 4);
3467 gen_op_load_xer_bc();
3468 gen_op_load_xer_cmp();
3469 op_POWER_lscbx(rD(ctx
->opcode
), ra
, rb
);
3470 gen_op_store_xer_bc();
3471 if (unlikely(Rc(ctx
->opcode
) != 0))
3475 /* maskg - maskg. */
3476 GEN_HANDLER(maskg
, 0x1F, 0x1D, 0x00, 0x00000000, PPC_POWER_BR
)
3478 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3479 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3480 gen_op_POWER_maskg();
3481 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3482 if (unlikely(Rc(ctx
->opcode
) != 0))
3486 /* maskir - maskir. */
3487 GEN_HANDLER(maskir
, 0x1F, 0x1D, 0x10, 0x00000000, PPC_POWER_BR
)
3489 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3490 gen_op_load_gpr_T1(rS(ctx
->opcode
));
3491 gen_op_load_gpr_T2(rB(ctx
->opcode
));
3492 gen_op_POWER_maskir();
3493 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3494 if (unlikely(Rc(ctx
->opcode
) != 0))
3499 GEN_HANDLER(mul
, 0x1F, 0x0B, 0x03, 0x00000000, PPC_POWER_BR
)
3501 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3502 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3504 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3505 if (unlikely(Rc(ctx
->opcode
) != 0))
3510 GEN_HANDLER(mulo
, 0x1F, 0x0B, 0x13, 0x00000000, PPC_POWER_BR
)
3512 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3513 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3514 gen_op_POWER_mulo();
3515 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3516 if (unlikely(Rc(ctx
->opcode
) != 0))
3521 GEN_HANDLER(nabs
, 0x1F, 0x08, 0x0F, 0x00000000, PPC_POWER_BR
)
3523 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3524 gen_op_POWER_nabs();
3525 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3526 if (unlikely(Rc(ctx
->opcode
) != 0))
3530 /* nabso - nabso. */
3531 GEN_HANDLER(nabso
, 0x1F, 0x08, 0x1F, 0x00000000, PPC_POWER_BR
)
3533 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3534 gen_op_POWER_nabso();
3535 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3536 if (unlikely(Rc(ctx
->opcode
) != 0))
3541 GEN_HANDLER(rlmi
, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR
)
3545 mb
= MB(ctx
->opcode
);
3546 me
= ME(ctx
->opcode
);
3547 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3548 gen_op_load_gpr_T1(rA(ctx
->opcode
));
3549 gen_op_load_gpr_T2(rB(ctx
->opcode
));
3550 gen_op_POWER_rlmi(MASK(mb
, me
), ~MASK(mb
, me
));
3551 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3552 if (unlikely(Rc(ctx
->opcode
) != 0))
3557 GEN_HANDLER(rrib
, 0x1F, 0x19, 0x10, 0x00000000, PPC_POWER_BR
)
3559 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3560 gen_op_load_gpr_T1(rA(ctx
->opcode
));
3561 gen_op_load_gpr_T2(rB(ctx
->opcode
));
3562 gen_op_POWER_rrib();
3563 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3564 if (unlikely(Rc(ctx
->opcode
) != 0))
3569 GEN_HANDLER(sle
, 0x1F, 0x19, 0x04, 0x00000000, PPC_POWER_BR
)
3571 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3572 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3574 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3575 if (unlikely(Rc(ctx
->opcode
) != 0))
3580 GEN_HANDLER(sleq
, 0x1F, 0x19, 0x06, 0x00000000, PPC_POWER_BR
)
3582 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3583 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3584 gen_op_POWER_sleq();
3585 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3586 if (unlikely(Rc(ctx
->opcode
) != 0))
3591 GEN_HANDLER(sliq
, 0x1F, 0x18, 0x05, 0x00000000, PPC_POWER_BR
)
3593 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3594 gen_op_set_T1(SH(ctx
->opcode
));
3596 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3597 if (unlikely(Rc(ctx
->opcode
) != 0))
3601 /* slliq - slliq. */
3602 GEN_HANDLER(slliq
, 0x1F, 0x18, 0x07, 0x00000000, PPC_POWER_BR
)
3604 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3605 gen_op_set_T1(SH(ctx
->opcode
));
3606 gen_op_POWER_sleq();
3607 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3608 if (unlikely(Rc(ctx
->opcode
) != 0))
3613 GEN_HANDLER(sllq
, 0x1F, 0x18, 0x06, 0x00000000, PPC_POWER_BR
)
3615 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3616 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3617 gen_op_POWER_sllq();
3618 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3619 if (unlikely(Rc(ctx
->opcode
) != 0))
3624 GEN_HANDLER(slq
, 0x1F, 0x18, 0x04, 0x00000000, PPC_POWER_BR
)
3626 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3627 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3629 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3630 if (unlikely(Rc(ctx
->opcode
) != 0))
3634 /* sraiq - sraiq. */
3635 GEN_HANDLER(sraiq
, 0x1F, 0x18, 0x1D, 0x00000000, PPC_POWER_BR
)
3637 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3638 gen_op_set_T1(SH(ctx
->opcode
));
3639 gen_op_POWER_sraq();
3640 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3641 if (unlikely(Rc(ctx
->opcode
) != 0))
3646 GEN_HANDLER(sraq
, 0x1F, 0x18, 0x1C, 0x00000000, PPC_POWER_BR
)
3648 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3649 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3650 gen_op_POWER_sraq();
3651 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3652 if (unlikely(Rc(ctx
->opcode
) != 0))
3657 GEN_HANDLER(sre
, 0x1F, 0x19, 0x14, 0x00000000, PPC_POWER_BR
)
3659 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3660 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3662 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3663 if (unlikely(Rc(ctx
->opcode
) != 0))
3668 GEN_HANDLER(srea
, 0x1F, 0x19, 0x1C, 0x00000000, PPC_POWER_BR
)
3670 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3671 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3672 gen_op_POWER_srea();
3673 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3674 if (unlikely(Rc(ctx
->opcode
) != 0))
3679 GEN_HANDLER(sreq
, 0x1F, 0x19, 0x16, 0x00000000, PPC_POWER_BR
)
3681 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3682 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3683 gen_op_POWER_sreq();
3684 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3685 if (unlikely(Rc(ctx
->opcode
) != 0))
3690 GEN_HANDLER(sriq
, 0x1F, 0x18, 0x15, 0x00000000, PPC_POWER_BR
)
3692 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3693 gen_op_set_T1(SH(ctx
->opcode
));
3695 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3696 if (unlikely(Rc(ctx
->opcode
) != 0))
3701 GEN_HANDLER(srliq
, 0x1F, 0x18, 0x17, 0x00000000, PPC_POWER_BR
)
3703 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3704 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3705 gen_op_set_T1(SH(ctx
->opcode
));
3706 gen_op_POWER_srlq();
3707 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3708 if (unlikely(Rc(ctx
->opcode
) != 0))
3713 GEN_HANDLER(srlq
, 0x1F, 0x18, 0x16, 0x00000000, PPC_POWER_BR
)
3715 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3716 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3717 gen_op_POWER_srlq();
3718 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3719 if (unlikely(Rc(ctx
->opcode
) != 0))
3724 GEN_HANDLER(srq
, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR
)
3726 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3727 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3729 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3730 if (unlikely(Rc(ctx
->opcode
) != 0))
3734 /* PowerPC 602 specific instructions */
3736 GEN_HANDLER(dsa
, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC
)
3743 GEN_HANDLER(esa
, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC
)
3750 GEN_HANDLER(mfrom
, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC
)
3752 #if defined(CONFIG_USER_ONLY)
3755 if (unlikely(!ctx
->supervisor
)) {
3759 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3761 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3765 /* 602 - 603 - G2 TLB management */
3767 GEN_HANDLER(tlbld
, 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB
)
3769 #if defined(CONFIG_USER_ONLY)
3772 if (unlikely(!ctx
->supervisor
)) {
3776 gen_op_load_gpr_T0(rB(ctx
->opcode
));
3783 GEN_HANDLER(tlbli
, 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB
)
3785 #if defined(CONFIG_USER_ONLY)
3788 if (unlikely(!ctx
->supervisor
)) {
3792 gen_op_load_gpr_T0(rB(ctx
->opcode
));
3798 /* POWER instructions not in PowerPC 601 */
3800 GEN_HANDLER(clf
, 0x1F, 0x16, 0x03, 0x03E00000, PPC_POWER
)
3802 /* Cache line flush: implemented as no-op */
3806 GEN_HANDLER(cli
, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER
)
3808 /* Cache line invalidate: priviledged and treated as no-op */
3809 #if defined(CONFIG_USER_ONLY)
3812 if (unlikely(!ctx
->supervisor
)) {
3820 GEN_HANDLER(dclst
, 0x1F, 0x16, 0x13, 0x03E00000, PPC_POWER
)
3822 /* Data cache line store: treated as no-op */
3825 GEN_HANDLER(mfsri
, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER
)
3827 #if defined(CONFIG_USER_ONLY)
3830 if (unlikely(!ctx
->supervisor
)) {
3834 int ra
= rA(ctx
->opcode
);
3835 int rd
= rD(ctx
->opcode
);
3837 gen_addr_reg_index(ctx
);
3838 gen_op_POWER_mfsri();
3839 gen_op_store_T0_gpr(rd
);
3840 if (ra
!= 0 && ra
!= rd
)
3841 gen_op_store_T1_gpr(ra
);
3845 GEN_HANDLER(rac
, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER
)
3847 #if defined(CONFIG_USER_ONLY)
3850 if (unlikely(!ctx
->supervisor
)) {
3854 gen_addr_reg_index(ctx
);
3856 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3860 GEN_HANDLER(rfsvc
, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER
)
3862 #if defined(CONFIG_USER_ONLY)
3865 if (unlikely(!ctx
->supervisor
)) {
3869 gen_op_POWER_rfsvc();
3874 /* svc is not implemented for now */
3876 /* POWER2 specific instructions */
3877 /* Quad manipulation (load/store two floats at a time) */
3878 #define op_POWER2_lfq() (*gen_op_POWER2_lfq[ctx->mem_idx])()
3879 #define op_POWER2_stfq() (*gen_op_POWER2_stfq[ctx->mem_idx])()
3880 #if defined(CONFIG_USER_ONLY)
3881 static GenOpFunc
*gen_op_POWER2_lfq
[] = {
3882 &gen_op_POWER2_lfq_le_raw
,
3883 &gen_op_POWER2_lfq_raw
,
3885 static GenOpFunc
*gen_op_POWER2_stfq
[] = {
3886 &gen_op_POWER2_stfq_le_raw
,
3887 &gen_op_POWER2_stfq_raw
,
3890 static GenOpFunc
*gen_op_POWER2_lfq
[] = {
3891 &gen_op_POWER2_lfq_le_user
,
3892 &gen_op_POWER2_lfq_user
,
3893 &gen_op_POWER2_lfq_le_kernel
,
3894 &gen_op_POWER2_lfq_kernel
,
3896 static GenOpFunc
*gen_op_POWER2_stfq
[] = {
3897 &gen_op_POWER2_stfq_le_user
,
3898 &gen_op_POWER2_stfq_user
,
3899 &gen_op_POWER2_stfq_le_kernel
,
3900 &gen_op_POWER2_stfq_kernel
,
3905 GEN_HANDLER(lfq
, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2
)
3907 /* NIP cannot be restored if the memory exception comes from an helper */
3908 gen_update_nip(ctx
, ctx
->nip
- 4);
3909 gen_addr_imm_index(ctx
);
3911 gen_op_store_FT0_fpr(rD(ctx
->opcode
));
3912 gen_op_store_FT1_fpr(rD(ctx
->opcode
) + 1);
3916 GEN_HANDLER(lfqu
, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2
)
3918 int ra
= rA(ctx
->opcode
);
3920 /* NIP cannot be restored if the memory exception comes from an helper */
3921 gen_update_nip(ctx
, ctx
->nip
- 4);
3922 gen_addr_imm_index(ctx
);
3924 gen_op_store_FT0_fpr(rD(ctx
->opcode
));
3925 gen_op_store_FT1_fpr(rD(ctx
->opcode
) + 1);
3927 gen_op_store_T0_gpr(ra
);
3931 GEN_HANDLER(lfqux
, 0x1F, 0x17, 0x19, 0x00000001, PPC_POWER2
)
3933 int ra
= rA(ctx
->opcode
);
3935 /* NIP cannot be restored if the memory exception comes from an helper */
3936 gen_update_nip(ctx
, ctx
->nip
- 4);
3937 gen_addr_reg_index(ctx
);
3939 gen_op_store_FT0_fpr(rD(ctx
->opcode
));
3940 gen_op_store_FT1_fpr(rD(ctx
->opcode
) + 1);
3942 gen_op_store_T0_gpr(ra
);
3946 GEN_HANDLER(lfqx
, 0x1F, 0x17, 0x18, 0x00000001, PPC_POWER2
)
3948 /* NIP cannot be restored if the memory exception comes from an helper */
3949 gen_update_nip(ctx
, ctx
->nip
- 4);
3950 gen_addr_reg_index(ctx
);
3952 gen_op_store_FT0_fpr(rD(ctx
->opcode
));
3953 gen_op_store_FT1_fpr(rD(ctx
->opcode
) + 1);
3957 GEN_HANDLER(stfq
, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2
)
3959 /* NIP cannot be restored if the memory exception comes from an helper */
3960 gen_update_nip(ctx
, ctx
->nip
- 4);
3961 gen_addr_imm_index(ctx
);
3962 gen_op_load_fpr_FT0(rS(ctx
->opcode
));
3963 gen_op_load_fpr_FT1(rS(ctx
->opcode
) + 1);
3968 GEN_HANDLER(stfqu
, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2
)
3970 int ra
= rA(ctx
->opcode
);
3972 /* NIP cannot be restored if the memory exception comes from an helper */
3973 gen_update_nip(ctx
, ctx
->nip
- 4);
3974 gen_addr_imm_index(ctx
);
3975 gen_op_load_fpr_FT0(rS(ctx
->opcode
));
3976 gen_op_load_fpr_FT1(rS(ctx
->opcode
) + 1);
3979 gen_op_store_T0_gpr(ra
);
3983 GEN_HANDLER(stfqux
, 0x1F, 0x17, 0x1D, 0x00000001, PPC_POWER2
)
3985 int ra
= rA(ctx
->opcode
);
3987 /* NIP cannot be restored if the memory exception comes from an helper */
3988 gen_update_nip(ctx
, ctx
->nip
- 4);
3989 gen_addr_reg_index(ctx
);
3990 gen_op_load_fpr_FT0(rS(ctx
->opcode
));
3991 gen_op_load_fpr_FT1(rS(ctx
->opcode
) + 1);
3994 gen_op_store_T0_gpr(ra
);
3998 GEN_HANDLER(stfqx
, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2
)
4000 /* NIP cannot be restored if the memory exception comes from an helper */
4001 gen_update_nip(ctx
, ctx
->nip
- 4);
4002 gen_addr_reg_index(ctx
);
4003 gen_op_load_fpr_FT0(rS(ctx
->opcode
));
4004 gen_op_load_fpr_FT1(rS(ctx
->opcode
) + 1);
4008 /* BookE specific instructions */
4009 GEN_HANDLER(mfapidi
, 0x1F, 0x13, 0x08, 0x0000F801, PPC_BOOKE
)
4015 GEN_HANDLER(tlbiva
, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_BOOKE
)
4017 #if defined(CONFIG_USER_ONLY)
4020 if (unlikely(!ctx
->supervisor
)) {
4024 gen_addr_reg_index(ctx
);
4025 /* Use the same micro-ops as for tlbie */
4026 #if defined(TARGET_PPC64)
4036 /* All 405 MAC instructions are translated here */
4037 static inline void gen_405_mulladd_insn (DisasContext
*ctx
, int opc2
, int opc3
,
4038 int ra
, int rb
, int rt
, int Rc
)
4040 gen_op_load_gpr_T0(ra
);
4041 gen_op_load_gpr_T1(rb
);
4042 switch (opc3
& 0x0D) {
4044 /* macchw - macchw. - macchwo - macchwo. */
4045 /* macchws - macchws. - macchwso - macchwso. */
4046 /* nmacchw - nmacchw. - nmacchwo - nmacchwo. */
4047 /* nmacchws - nmacchws. - nmacchwso - nmacchwso. */
4048 /* mulchw - mulchw. */
4049 gen_op_405_mulchw();
4052 /* macchwu - macchwu. - macchwuo - macchwuo. */
4053 /* macchwsu - macchwsu. - macchwsuo - macchwsuo. */
4054 /* mulchwu - mulchwu. */
4055 gen_op_405_mulchwu();
4058 /* machhw - machhw. - machhwo - machhwo. */
4059 /* machhws - machhws. - machhwso - machhwso. */
4060 /* nmachhw - nmachhw. - nmachhwo - nmachhwo. */
4061 /* nmachhws - nmachhws. - nmachhwso - nmachhwso. */
4062 /* mulhhw - mulhhw. */
4063 gen_op_405_mulhhw();
4066 /* machhwu - machhwu. - machhwuo - machhwuo. */
4067 /* machhwsu - machhwsu. - machhwsuo - machhwsuo. */
4068 /* mulhhwu - mulhhwu. */
4069 gen_op_405_mulhhwu();
4072 /* maclhw - maclhw. - maclhwo - maclhwo. */
4073 /* maclhws - maclhws. - maclhwso - maclhwso. */
4074 /* nmaclhw - nmaclhw. - nmaclhwo - nmaclhwo. */
4075 /* nmaclhws - nmaclhws. - nmaclhwso - nmaclhwso. */
4076 /* mullhw - mullhw. */
4077 gen_op_405_mullhw();
4080 /* maclhwu - maclhwu. - maclhwuo - maclhwuo. */
4081 /* maclhwsu - maclhwsu. - maclhwsuo - maclhwsuo. */
4082 /* mullhwu - mullhwu. */
4083 gen_op_405_mullhwu();
4087 /* nmultiply-and-accumulate (0x0E) */
4091 /* (n)multiply-and-accumulate (0x0C - 0x0E) */
4092 gen_op_load_gpr_T2(rt
);
4093 gen_op_move_T1_T0();
4094 gen_op_405_add_T0_T2();
4097 /* Check overflow */
4099 gen_op_405_check_ov();
4101 gen_op_405_check_ovu();
4106 gen_op_405_check_sat();
4108 gen_op_405_check_satu();
4110 gen_op_store_T0_gpr(rt
);
4111 if (unlikely(Rc
) != 0) {
4117 #define GEN_MAC_HANDLER(name, opc2, opc3) \
4118 GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC) \
4120 gen_405_mulladd_insn(ctx, opc2, opc3, rA(ctx->opcode), rB(ctx->opcode), \
4121 rD(ctx->opcode), Rc(ctx->opcode)); \
4124 /* macchw - macchw. */
4125 GEN_MAC_HANDLER(macchw
, 0x0C, 0x05);
4126 /* macchwo - macchwo. */
4127 GEN_MAC_HANDLER(macchwo
, 0x0C, 0x15);
4128 /* macchws - macchws. */
4129 GEN_MAC_HANDLER(macchws
, 0x0C, 0x07);
4130 /* macchwso - macchwso. */
4131 GEN_MAC_HANDLER(macchwso
, 0x0C, 0x17);
4132 /* macchwsu - macchwsu. */
4133 GEN_MAC_HANDLER(macchwsu
, 0x0C, 0x06);
4134 /* macchwsuo - macchwsuo. */
4135 GEN_MAC_HANDLER(macchwsuo
, 0x0C, 0x16);
4136 /* macchwu - macchwu. */
4137 GEN_MAC_HANDLER(macchwu
, 0x0C, 0x04);
4138 /* macchwuo - macchwuo. */
4139 GEN_MAC_HANDLER(macchwuo
, 0x0C, 0x14);
4140 /* machhw - machhw. */
4141 GEN_MAC_HANDLER(machhw
, 0x0C, 0x01);
4142 /* machhwo - machhwo. */
4143 GEN_MAC_HANDLER(machhwo
, 0x0C, 0x11);
4144 /* machhws - machhws. */
4145 GEN_MAC_HANDLER(machhws
, 0x0C, 0x03);
4146 /* machhwso - machhwso. */
4147 GEN_MAC_HANDLER(machhwso
, 0x0C, 0x13);
4148 /* machhwsu - machhwsu. */
4149 GEN_MAC_HANDLER(machhwsu
, 0x0C, 0x02);
4150 /* machhwsuo - machhwsuo. */
4151 GEN_MAC_HANDLER(machhwsuo
, 0x0C, 0x12);
4152 /* machhwu - machhwu. */
4153 GEN_MAC_HANDLER(machhwu
, 0x0C, 0x00);
4154 /* machhwuo - machhwuo. */
4155 GEN_MAC_HANDLER(machhwuo
, 0x0C, 0x10);
4156 /* maclhw - maclhw. */
4157 GEN_MAC_HANDLER(maclhw
, 0x0C, 0x0D);
4158 /* maclhwo - maclhwo. */
4159 GEN_MAC_HANDLER(maclhwo
, 0x0C, 0x1D);
4160 /* maclhws - maclhws. */
4161 GEN_MAC_HANDLER(maclhws
, 0x0C, 0x0F);
4162 /* maclhwso - maclhwso. */
4163 GEN_MAC_HANDLER(maclhwso
, 0x0C, 0x1F);
4164 /* maclhwu - maclhwu. */
4165 GEN_MAC_HANDLER(maclhwu
, 0x0C, 0x0C);
4166 /* maclhwuo - maclhwuo. */
4167 GEN_MAC_HANDLER(maclhwuo
, 0x0C, 0x1C);
4168 /* maclhwsu - maclhwsu. */
4169 GEN_MAC_HANDLER(maclhwsu
, 0x0C, 0x0E);
4170 /* maclhwsuo - maclhwsuo. */
4171 GEN_MAC_HANDLER(maclhwsuo
, 0x0C, 0x1E);
4172 /* nmacchw - nmacchw. */
4173 GEN_MAC_HANDLER(nmacchw
, 0x0E, 0x05);
4174 /* nmacchwo - nmacchwo. */
4175 GEN_MAC_HANDLER(nmacchwo
, 0x0E, 0x15);
4176 /* nmacchws - nmacchws. */
4177 GEN_MAC_HANDLER(nmacchws
, 0x0E, 0x07);
4178 /* nmacchwso - nmacchwso. */
4179 GEN_MAC_HANDLER(nmacchwso
, 0x0E, 0x17);
4180 /* nmachhw - nmachhw. */
4181 GEN_MAC_HANDLER(nmachhw
, 0x0E, 0x01);
4182 /* nmachhwo - nmachhwo. */
4183 GEN_MAC_HANDLER(nmachhwo
, 0x0E, 0x11);
4184 /* nmachhws - nmachhws. */
4185 GEN_MAC_HANDLER(nmachhws
, 0x0E, 0x03);
4186 /* nmachhwso - nmachhwso. */
4187 GEN_MAC_HANDLER(nmachhwso
, 0x0E, 0x13);
4188 /* nmaclhw - nmaclhw. */
4189 GEN_MAC_HANDLER(nmaclhw
, 0x0E, 0x0D);
4190 /* nmaclhwo - nmaclhwo. */
4191 GEN_MAC_HANDLER(nmaclhwo
, 0x0E, 0x1D);
4192 /* nmaclhws - nmaclhws. */
4193 GEN_MAC_HANDLER(nmaclhws
, 0x0E, 0x0F);
4194 /* nmaclhwso - nmaclhwso. */
4195 GEN_MAC_HANDLER(nmaclhwso
, 0x0E, 0x1F);
4197 /* mulchw - mulchw. */
4198 GEN_MAC_HANDLER(mulchw
, 0x08, 0x05);
4199 /* mulchwu - mulchwu. */
4200 GEN_MAC_HANDLER(mulchwu
, 0x08, 0x04);
4201 /* mulhhw - mulhhw. */
4202 GEN_MAC_HANDLER(mulhhw
, 0x08, 0x01);
4203 /* mulhhwu - mulhhwu. */
4204 GEN_MAC_HANDLER(mulhhwu
, 0x08, 0x00);
4205 /* mullhw - mullhw. */
4206 GEN_MAC_HANDLER(mullhw
, 0x08, 0x0D);
4207 /* mullhwu - mullhwu. */
4208 GEN_MAC_HANDLER(mullhwu
, 0x08, 0x0C);
4211 GEN_HANDLER(mfdcr
, 0x1F, 0x03, 0x0A, 0x00000001, PPC_EMB_COMMON
)
4213 #if defined(CONFIG_USER_ONLY)
4216 uint32_t dcrn
= SPR(ctx
->opcode
);
4218 if (unlikely(!ctx
->supervisor
)) {
4222 gen_op_4xx_load_dcr(dcrn
);
4223 gen_op_store_T0_gpr(rD(ctx
->opcode
));
4228 GEN_HANDLER(mtdcr
, 0x1F, 0x03, 0x0E, 0x00000001, PPC_EMB_COMMON
)
4230 #if defined(CONFIG_USER_ONLY)
4233 uint32_t dcrn
= SPR(ctx
->opcode
);
4235 if (unlikely(!ctx
->supervisor
)) {
4239 gen_op_load_gpr_T0(rS(ctx
->opcode
));
4240 gen_op_4xx_store_dcr(dcrn
);
4245 GEN_HANDLER(dccci
, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON
)
4247 #if defined(CONFIG_USER_ONLY)
4250 if (unlikely(!ctx
->supervisor
)) {
4254 /* interpreted as no-op */
4259 GEN_HANDLER(dcread
, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON
)
4261 #if defined(CONFIG_USER_ONLY)
4264 if (unlikely(!ctx
->supervisor
)) {
4268 gen_addr_reg_index(ctx
);
4270 gen_op_store_T0_gpr(rD(ctx
->opcode
));
4275 GEN_HANDLER(icbt_40x
, 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_SPEC
)
4277 /* interpreted as no-op */
4278 /* XXX: specification say this is treated as a load by the MMU
4279 * but does not generate any exception
4284 GEN_HANDLER(iccci
, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON
)
4286 #if defined(CONFIG_USER_ONLY)
4289 if (unlikely(!ctx
->supervisor
)) {
4293 /* interpreted as no-op */
4298 GEN_HANDLER(icread
, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON
)
4300 #if defined(CONFIG_USER_ONLY)
4303 if (unlikely(!ctx
->supervisor
)) {
4307 /* interpreted as no-op */
4311 /* rfci (supervisor only) */
4312 GEN_HANDLER(rfci
, 0x13, 0x13, 0x01, 0x03FF8001, PPC_EMB_COMMON
)
4314 #if defined(CONFIG_USER_ONLY)
4317 if (unlikely(!ctx
->supervisor
)) {
4321 /* Restore CPU state */
4327 /* TLB management - PowerPC 405 implementation */
4329 GEN_HANDLER(tlbre
, 0x1F, 0x12, 0x1D, 0x00000001, PPC_EMB_COMMON
)
4331 #if defined(CONFIG_USER_ONLY)
4334 if (unlikely(!ctx
->supervisor
)) {
4338 switch (rB(ctx
->opcode
)) {
4340 gen_op_load_gpr_T0(rA(ctx
->opcode
));
4341 gen_op_4xx_tlbre_hi();
4342 gen_op_store_T0_gpr(rD(ctx
->opcode
));
4345 gen_op_load_gpr_T0(rA(ctx
->opcode
));
4346 gen_op_4xx_tlbre_lo();
4347 gen_op_store_T0_gpr(rD(ctx
->opcode
));
4356 /* tlbsx - tlbsx. */
4357 GEN_HANDLER(tlbsx
, 0x1F, 0x12, 0x1C, 0x00000000, PPC_EMB_COMMON
)
4359 #if defined(CONFIG_USER_ONLY)
4362 if (unlikely(!ctx
->supervisor
)) {
4366 gen_addr_reg_index(ctx
);
4367 if (Rc(ctx
->opcode
))
4368 gen_op_4xx_tlbsx_();
4371 gen_op_store_T0_gpr(rD(ctx
->opcode
));
4376 GEN_HANDLER(tlbwe
, 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_SPEC
)
4378 #if defined(CONFIG_USER_ONLY)
4381 if (unlikely(!ctx
->supervisor
)) {
4385 switch (rB(ctx
->opcode
)) {
4387 gen_op_load_gpr_T0(rA(ctx
->opcode
));
4388 gen_op_load_gpr_T1(rS(ctx
->opcode
));
4389 gen_op_4xx_tlbwe_hi();
4392 gen_op_load_gpr_T0(rA(ctx
->opcode
));
4393 gen_op_load_gpr_T1(rS(ctx
->opcode
));
4394 gen_op_4xx_tlbwe_lo();
4404 GEN_HANDLER(wrtee
, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_EMB_COMMON
)
4406 #if defined(CONFIG_USER_ONLY)
4409 if (unlikely(!ctx
->supervisor
)) {
4413 gen_op_load_gpr_T0(rD(ctx
->opcode
));
4415 RET_EXCP(ctx
, EXCP_MTMSR
, 0);
4420 GEN_HANDLER(wrteei
, 0x1F, 0x03, 0x05, 0x000EFC01, PPC_EMB_COMMON
)
4422 #if defined(CONFIG_USER_ONLY)
4425 if (unlikely(!ctx
->supervisor
)) {
4429 gen_op_set_T0(ctx
->opcode
& 0x00010000);
4431 RET_EXCP(ctx
, EXCP_MTMSR
, 0);
4435 /* PPC 440 specific instructions */
4437 GEN_HANDLER(dlmzb
, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC
)
4439 gen_op_load_gpr_T0(rS(ctx
->opcode
));
4440 gen_op_load_gpr_T1(rB(ctx
->opcode
));
4442 gen_op_store_T0_gpr(rA(ctx
->opcode
));
4443 gen_op_store_xer_bc();
4444 if (Rc(ctx
->opcode
)) {
4445 gen_op_440_dlmzb_update_Rc();
4446 gen_op_store_T0_crf(0);
4450 /* mbar replaces eieio on 440 */
4451 GEN_HANDLER(mbar
, 0x1F, 0x16, 0x13, 0x001FF801, PPC_BOOKE
)
4453 /* interpreted as no-op */
4456 /* msync replaces sync on 440 */
4457 GEN_HANDLER(msync
, 0x1F, 0x16, 0x12, 0x03FF0801, PPC_BOOKE
)
4459 /* interpreted as no-op */
4463 GEN_HANDLER(icbt_440
, 0x1F, 0x16, 0x00, 0x03E00001, PPC_BOOKE
)
4465 /* interpreted as no-op */
4466 /* XXX: specification say this is treated as a load by the MMU
4467 * but does not generate any exception
4471 /* End opcode list */
4472 GEN_OPCODE_MARK(end
);
4474 #include "translate_init.c"
4476 /*****************************************************************************/
4477 /* Misc PowerPC helpers */
4478 static inline uint32_t load_xer (CPUState
*env
)
4480 return (xer_so
<< XER_SO
) |
4481 (xer_ov
<< XER_OV
) |
4482 (xer_ca
<< XER_CA
) |
4483 (xer_bc
<< XER_BC
) |
4484 (xer_cmp
<< XER_CMP
);
4487 void cpu_dump_state(CPUState
*env
, FILE *f
,
4488 int (*cpu_fprintf
)(FILE *f
, const char *fmt
, ...),
4491 #if defined(TARGET_PPC64) || 1
4503 cpu_fprintf(f
, "NIP " REGX
" LR " REGX
" CTR " REGX
"\n",
4504 env
->nip
, env
->lr
, env
->ctr
);
4505 cpu_fprintf(f
, "MSR " REGX FILL
" XER %08x "
4506 #if !defined(NO_TIMER_DUMP)
4508 #if !defined(CONFIG_USER_ONLY)
4513 do_load_msr(env
), load_xer(env
)
4514 #if !defined(NO_TIMER_DUMP)
4515 , cpu_ppc_load_tbu(env
), cpu_ppc_load_tbl(env
)
4516 #if !defined(CONFIG_USER_ONLY)
4517 , cpu_ppc_load_decr(env
)
4521 for (i
= 0; i
< 32; i
++) {
4522 if ((i
& (RGPL
- 1)) == 0)
4523 cpu_fprintf(f
, "GPR%02d", i
);
4524 cpu_fprintf(f
, " " REGX
, env
->gpr
[i
]);
4525 if ((i
& (RGPL
- 1)) == (RGPL
- 1))
4526 cpu_fprintf(f
, "\n");
4528 cpu_fprintf(f
, "CR ");
4529 for (i
= 0; i
< 8; i
++)
4530 cpu_fprintf(f
, "%01x", env
->crf
[i
]);
4531 cpu_fprintf(f
, " [");
4532 for (i
= 0; i
< 8; i
++) {
4534 if (env
->crf
[i
] & 0x08)
4536 else if (env
->crf
[i
] & 0x04)
4538 else if (env
->crf
[i
] & 0x02)
4540 cpu_fprintf(f
, " %c%c", a
, env
->crf
[i
] & 0x01 ? 'O' : ' ');
4542 cpu_fprintf(f
, " ] " FILL
"RES " REGX
"\n", env
->reserve
);
4543 for (i
= 0; i
< 32; i
++) {
4544 if ((i
& (RFPL
- 1)) == 0)
4545 cpu_fprintf(f
, "FPR%02d", i
);
4546 cpu_fprintf(f
, " %016" PRIx64
, *((uint64_t *)&env
->fpr
[i
]));
4547 if ((i
& (RFPL
- 1)) == (RFPL
- 1))
4548 cpu_fprintf(f
, "\n");
4550 cpu_fprintf(f
, "SRR0 " REGX
" SRR1 " REGX
" " FILL FILL FILL
4552 env
->spr
[SPR_SRR0
], env
->spr
[SPR_SRR1
], env
->sdr1
);
4559 void cpu_dump_statistics (CPUState
*env
, FILE*f
,
4560 int (*cpu_fprintf
)(FILE *f
, const char *fmt
, ...),
4563 #if defined(DO_PPC_STATISTICS)
4564 opc_handler_t
**t1
, **t2
, **t3
, *handler
;
4568 for (op1
= 0; op1
< 64; op1
++) {
4570 if (is_indirect_opcode(handler
)) {
4571 t2
= ind_table(handler
);
4572 for (op2
= 0; op2
< 32; op2
++) {
4574 if (is_indirect_opcode(handler
)) {
4575 t3
= ind_table(handler
);
4576 for (op3
= 0; op3
< 32; op3
++) {
4578 if (handler
->count
== 0)
4580 cpu_fprintf(f
, "%02x %02x %02x (%02x %04d) %16s: "
4582 op1
, op2
, op3
, op1
, (op3
<< 5) | op2
,
4584 handler
->count
, handler
->count
);
4587 if (handler
->count
== 0)
4589 cpu_fprintf(f
, "%02x %02x (%02x %04d) %16s: "
4591 op1
, op2
, op1
, op2
, handler
->oname
,
4592 handler
->count
, handler
->count
);
4596 if (handler
->count
== 0)
4598 cpu_fprintf(f
, "%02x (%02x ) %16s: %016llx %lld\n",
4599 op1
, op1
, handler
->oname
,
4600 handler
->count
, handler
->count
);
4606 /*****************************************************************************/
4607 int gen_intermediate_code_internal (CPUState
*env
, TranslationBlock
*tb
,
4610 DisasContext ctx
, *ctxp
= &ctx
;
4611 opc_handler_t
**table
, *handler
;
4612 target_ulong pc_start
;
4613 uint16_t *gen_opc_end
;
4617 gen_opc_ptr
= gen_opc_buf
;
4618 gen_opc_end
= gen_opc_buf
+ OPC_MAX_SIZE
;
4619 gen_opparam_ptr
= gen_opparam_buf
;
4623 ctx
.exception
= EXCP_NONE
;
4624 ctx
.spr_cb
= env
->spr_cb
;
4625 #if defined(CONFIG_USER_ONLY)
4626 ctx
.mem_idx
= msr_le
;
4627 #if defined(TARGET_PPC64)
4628 ctx
.mem_idx
|= msr_sf
<< 1;
4631 ctx
.supervisor
= 1 - msr_pr
;
4632 ctx
.mem_idx
= ((1 - msr_pr
) << 1) | msr_le
;
4633 #if defined(TARGET_PPC64)
4634 ctx
.mem_idx
|= msr_sf
<< 2;
4637 #if defined(TARGET_PPC64)
4638 ctx
.sf_mode
= msr_sf
;
4640 ctx
.fpu_enabled
= msr_fp
;
4641 ctx
.singlestep_enabled
= env
->singlestep_enabled
;
4642 #if defined (DO_SINGLE_STEP) && 0
4643 /* Single step trace mode */
4646 /* Set env in case of segfault during code fetch */
4647 while (ctx
.exception
== EXCP_NONE
&& gen_opc_ptr
< gen_opc_end
) {
4648 if (unlikely(env
->nb_breakpoints
> 0)) {
4649 for (j
= 0; j
< env
->nb_breakpoints
; j
++) {
4650 if (env
->breakpoints
[j
] == ctx
.nip
) {
4651 gen_update_nip(&ctx
, ctx
.nip
);
4657 if (unlikely(search_pc
)) {
4658 j
= gen_opc_ptr
- gen_opc_buf
;
4662 gen_opc_instr_start
[lj
++] = 0;
4663 gen_opc_pc
[lj
] = ctx
.nip
;
4664 gen_opc_instr_start
[lj
] = 1;
4667 #if defined PPC_DEBUG_DISAS
4668 if (loglevel
& CPU_LOG_TB_IN_ASM
) {
4669 fprintf(logfile
, "----------------\n");
4670 fprintf(logfile
, "nip=%08x super=%d ir=%d\n",
4671 ctx
.nip
, 1 - msr_pr
, msr_ir
);
4674 ctx
.opcode
= ldl_code(ctx
.nip
);
4676 ctx
.opcode
= ((ctx
.opcode
& 0xFF000000) >> 24) |
4677 ((ctx
.opcode
& 0x00FF0000) >> 8) |
4678 ((ctx
.opcode
& 0x0000FF00) << 8) |
4679 ((ctx
.opcode
& 0x000000FF) << 24);
4681 #if defined PPC_DEBUG_DISAS
4682 if (loglevel
& CPU_LOG_TB_IN_ASM
) {
4683 fprintf(logfile
, "translate opcode %08x (%02x %02x %02x) (%s)\n",
4684 ctx
.opcode
, opc1(ctx
.opcode
), opc2(ctx
.opcode
),
4685 opc3(ctx
.opcode
), msr_le
? "little" : "big");
4689 table
= env
->opcodes
;
4690 handler
= table
[opc1(ctx
.opcode
)];
4691 if (is_indirect_opcode(handler
)) {
4692 table
= ind_table(handler
);
4693 handler
= table
[opc2(ctx
.opcode
)];
4694 if (is_indirect_opcode(handler
)) {
4695 table
= ind_table(handler
);
4696 handler
= table
[opc3(ctx
.opcode
)];
4699 /* Is opcode *REALLY* valid ? */
4700 if (unlikely(handler
->handler
== &gen_invalid
)) {
4702 fprintf(logfile
, "invalid/unsupported opcode: "
4703 "%02x - %02x - %02x (%08x) 0x" REGX
" %d\n",
4704 opc1(ctx
.opcode
), opc2(ctx
.opcode
),
4705 opc3(ctx
.opcode
), ctx
.opcode
, ctx
.nip
- 4, msr_ir
);
4707 printf("invalid/unsupported opcode: "
4708 "%02x - %02x - %02x (%08x) 0x" REGX
" %d\n",
4709 opc1(ctx
.opcode
), opc2(ctx
.opcode
),
4710 opc3(ctx
.opcode
), ctx
.opcode
, ctx
.nip
- 4, msr_ir
);
4713 if (unlikely((ctx
.opcode
& handler
->inval
) != 0)) {
4715 fprintf(logfile
, "invalid bits: %08x for opcode: "
4716 "%02x -%02x - %02x (%08x) " REGX
"\n",
4717 ctx
.opcode
& handler
->inval
, opc1(ctx
.opcode
),
4718 opc2(ctx
.opcode
), opc3(ctx
.opcode
),
4719 ctx
.opcode
, ctx
.nip
- 4);
4721 printf("invalid bits: %08x for opcode: "
4722 "%02x -%02x - %02x (%08x) " REGX
"\n",
4723 ctx
.opcode
& handler
->inval
, opc1(ctx
.opcode
),
4724 opc2(ctx
.opcode
), opc3(ctx
.opcode
),
4725 ctx
.opcode
, ctx
.nip
- 4);
4731 (*(handler
->handler
))(&ctx
);
4732 #if defined(DO_PPC_STATISTICS)
4735 /* Check trace mode exceptions */
4736 if (unlikely((msr_be
&& ctx
.exception
== EXCP_BRANCH
) ||
4737 /* Check in single step trace mode
4738 * we need to stop except if:
4739 * - rfi, trap or syscall
4740 * - first instruction of an exception handler
4742 (msr_se
&& (ctx
.nip
< 0x100 ||
4744 (ctx
.nip
& 0xFC) != 0x04) &&
4745 ctx
.exception
!= EXCP_SYSCALL
&&
4746 ctx
.exception
!= EXCP_SYSCALL_USER
&&
4747 ctx
.exception
!= EXCP_TRAP
))) {
4748 RET_EXCP(ctxp
, EXCP_TRACE
, 0);
4750 /* if we reach a page boundary or are single stepping, stop
4753 if (unlikely(((ctx
.nip
& (TARGET_PAGE_SIZE
- 1)) == 0) ||
4754 (env
->singlestep_enabled
))) {
4757 #if defined (DO_SINGLE_STEP)
4761 if (ctx
.exception
== EXCP_NONE
) {
4762 gen_goto_tb(&ctx
, 0, ctx
.nip
);
4763 } else if (ctx
.exception
!= EXCP_BRANCH
) {
4765 /* Generate the return instruction */
4768 *gen_opc_ptr
= INDEX_op_end
;
4769 if (unlikely(search_pc
)) {
4770 j
= gen_opc_ptr
- gen_opc_buf
;
4773 gen_opc_instr_start
[lj
++] = 0;
4776 tb
->size
= ctx
.nip
- pc_start
;
4778 #if defined(DEBUG_DISAS)
4779 if (loglevel
& CPU_LOG_TB_CPU
) {
4780 fprintf(logfile
, "---------------- excp: %04x\n", ctx
.exception
);
4781 cpu_dump_state(env
, logfile
, fprintf
, 0);
4783 if (loglevel
& CPU_LOG_TB_IN_ASM
) {
4786 fprintf(logfile
, "IN: %s\n", lookup_symbol(pc_start
));
4787 target_disas(logfile
, pc_start
, ctx
.nip
- pc_start
, flags
);
4788 fprintf(logfile
, "\n");
4790 if (loglevel
& CPU_LOG_TB_OP
) {
4791 fprintf(logfile
, "OP:\n");
4792 dump_ops(gen_opc_buf
, gen_opparam_buf
);
4793 fprintf(logfile
, "\n");
4799 int gen_intermediate_code (CPUState
*env
, struct TranslationBlock
*tb
)
4801 return gen_intermediate_code_internal(env
, tb
, 0);
4804 int gen_intermediate_code_pc (CPUState
*env
, struct TranslationBlock
*tb
)
4806 return gen_intermediate_code_internal(env
, tb
, 1);