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 #if defined(TARGET_PPCSPE)
166 ppc_spr_t
*spr_cb
; /* Needed to check rights for mfspr/mtspr */
167 int singlestep_enabled
;
170 struct opc_handler_t
{
173 /* instruction type */
176 void (*handler
)(DisasContext
*ctx
);
177 #if defined(DO_PPC_STATISTICS)
178 const unsigned char *oname
;
183 static inline void gen_set_Rc0 (DisasContext
*ctx
)
185 #if defined(TARGET_PPC64)
194 static inline void gen_update_nip (DisasContext
*ctx
, target_ulong nip
)
196 #if defined(TARGET_PPC64)
198 gen_op_update_nip_64(nip
>> 32, nip
);
201 gen_op_update_nip(nip
);
204 #define RET_EXCP(ctx, excp, error) \
206 if ((ctx)->exception == EXCP_NONE) { \
207 gen_update_nip(ctx, (ctx)->nip); \
209 gen_op_raise_exception_err((excp), (error)); \
210 ctx->exception = (excp); \
213 #define RET_INVAL(ctx) \
214 RET_EXCP((ctx), EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_INVAL)
216 #define RET_PRIVOPC(ctx) \
217 RET_EXCP((ctx), EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_OPC)
219 #define RET_PRIVREG(ctx) \
220 RET_EXCP((ctx), EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_REG)
222 /* Stop translation */
223 static inline void RET_STOP (DisasContext
*ctx
)
225 gen_update_nip(ctx
, ctx
->nip
);
226 ctx
->exception
= EXCP_MTMSR
;
229 /* No need to update nip here, as execution flow will change */
230 static inline void RET_CHG_FLOW (DisasContext
*ctx
)
232 ctx
->exception
= EXCP_MTMSR
;
235 #define GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \
236 static void gen_##name (DisasContext *ctx); \
237 GEN_OPCODE(name, opc1, opc2, opc3, inval, type); \
238 static void gen_##name (DisasContext *ctx)
240 typedef struct opcode_t
{
241 unsigned char opc1
, opc2
, opc3
;
242 #if HOST_LONG_BITS == 64 /* Explicitely align to 64 bits */
243 unsigned char pad
[5];
245 unsigned char pad
[1];
247 opc_handler_t handler
;
248 const unsigned char *oname
;
251 /*** Instruction decoding ***/
252 #define EXTRACT_HELPER(name, shift, nb) \
253 static inline uint32_t name (uint32_t opcode) \
255 return (opcode >> (shift)) & ((1 << (nb)) - 1); \
258 #define EXTRACT_SHELPER(name, shift, nb) \
259 static inline int32_t name (uint32_t opcode) \
261 return (int16_t)((opcode >> (shift)) & ((1 << (nb)) - 1)); \
265 EXTRACT_HELPER(opc1
, 26, 6);
267 EXTRACT_HELPER(opc2
, 1, 5);
269 EXTRACT_HELPER(opc3
, 6, 5);
270 /* Update Cr0 flags */
271 EXTRACT_HELPER(Rc
, 0, 1);
273 EXTRACT_HELPER(rD
, 21, 5);
275 EXTRACT_HELPER(rS
, 21, 5);
277 EXTRACT_HELPER(rA
, 16, 5);
279 EXTRACT_HELPER(rB
, 11, 5);
281 EXTRACT_HELPER(rC
, 6, 5);
283 EXTRACT_HELPER(crfD
, 23, 3);
284 EXTRACT_HELPER(crfS
, 18, 3);
285 EXTRACT_HELPER(crbD
, 21, 5);
286 EXTRACT_HELPER(crbA
, 16, 5);
287 EXTRACT_HELPER(crbB
, 11, 5);
289 EXTRACT_HELPER(_SPR
, 11, 10);
290 static inline uint32_t SPR (uint32_t opcode
)
292 uint32_t sprn
= _SPR(opcode
);
294 return ((sprn
>> 5) & 0x1F) | ((sprn
& 0x1F) << 5);
296 /*** Get constants ***/
297 EXTRACT_HELPER(IMM
, 12, 8);
298 /* 16 bits signed immediate value */
299 EXTRACT_SHELPER(SIMM
, 0, 16);
300 /* 16 bits unsigned immediate value */
301 EXTRACT_HELPER(UIMM
, 0, 16);
303 EXTRACT_HELPER(NB
, 11, 5);
305 EXTRACT_HELPER(SH
, 11, 5);
307 EXTRACT_HELPER(MB
, 6, 5);
309 EXTRACT_HELPER(ME
, 1, 5);
311 EXTRACT_HELPER(TO
, 21, 5);
313 EXTRACT_HELPER(CRM
, 12, 8);
314 EXTRACT_HELPER(FM
, 17, 8);
315 EXTRACT_HELPER(SR
, 16, 4);
316 EXTRACT_HELPER(FPIMM
, 20, 4);
318 /*** Jump target decoding ***/
320 EXTRACT_SHELPER(d
, 0, 16);
321 /* Immediate address */
322 static inline target_ulong
LI (uint32_t opcode
)
324 return (opcode
>> 0) & 0x03FFFFFC;
327 static inline uint32_t BD (uint32_t opcode
)
329 return (opcode
>> 0) & 0xFFFC;
332 EXTRACT_HELPER(BO
, 21, 5);
333 EXTRACT_HELPER(BI
, 16, 5);
334 /* Absolute/relative address */
335 EXTRACT_HELPER(AA
, 1, 1);
337 EXTRACT_HELPER(LK
, 0, 1);
339 /* Create a mask between <start> and <end> bits */
340 static inline target_ulong
MASK (uint32_t start
, uint32_t end
)
344 #if defined(TARGET_PPC64)
345 if (likely(start
== 0)) {
346 ret
= (uint64_t)(-1ULL) << (63 - end
);
347 } else if (likely(end
== 63)) {
348 ret
= (uint64_t)(-1ULL) >> start
;
351 if (likely(start
== 0)) {
352 ret
= (uint32_t)(-1ULL) << (31 - end
);
353 } else if (likely(end
== 31)) {
354 ret
= (uint32_t)(-1ULL) >> start
;
358 ret
= (((target_ulong
)(-1ULL)) >> (start
)) ^
359 (((target_ulong
)(-1ULL) >> (end
)) >> 1);
360 if (unlikely(start
> end
))
367 #if HOST_LONG_BITS == 64
372 #if defined(__APPLE__)
373 #define OPCODES_SECTION \
374 __attribute__ ((section("__TEXT,__opcodes"), unused, aligned (OPC_ALIGN) ))
376 #define OPCODES_SECTION \
377 __attribute__ ((section(".opcodes"), unused, aligned (OPC_ALIGN) ))
380 #if defined(DO_PPC_STATISTICS)
381 #define GEN_OPCODE(name, op1, op2, op3, invl, _typ) \
382 OPCODES_SECTION opcode_t opc_##name = { \
390 .handler = &gen_##name, \
391 .oname = stringify(name), \
393 .oname = stringify(name), \
396 #define GEN_OPCODE(name, op1, op2, op3, invl, _typ) \
397 OPCODES_SECTION opcode_t opc_##name = { \
405 .handler = &gen_##name, \
407 .oname = stringify(name), \
411 #define GEN_OPCODE_MARK(name) \
412 OPCODES_SECTION opcode_t opc_##name = { \
418 .inval = 0x00000000, \
422 .oname = stringify(name), \
425 /* Start opcode list */
426 GEN_OPCODE_MARK(start
);
428 /* Invalid instruction */
429 GEN_HANDLER(invalid
, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE
)
434 static opc_handler_t invalid_handler
= {
437 .handler
= gen_invalid
,
440 /*** Integer arithmetic ***/
441 #define __GEN_INT_ARITH2(name, opc1, opc2, opc3, inval, type) \
442 GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \
444 gen_op_load_gpr_T0(rA(ctx->opcode)); \
445 gen_op_load_gpr_T1(rB(ctx->opcode)); \
447 gen_op_store_T0_gpr(rD(ctx->opcode)); \
448 if (unlikely(Rc(ctx->opcode) != 0)) \
452 #define __GEN_INT_ARITH2_O(name, opc1, opc2, opc3, inval, type) \
453 GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \
455 gen_op_load_gpr_T0(rA(ctx->opcode)); \
456 gen_op_load_gpr_T1(rB(ctx->opcode)); \
458 gen_op_store_T0_gpr(rD(ctx->opcode)); \
459 if (unlikely(Rc(ctx->opcode) != 0)) \
463 #define __GEN_INT_ARITH1(name, opc1, opc2, opc3, type) \
464 GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type) \
466 gen_op_load_gpr_T0(rA(ctx->opcode)); \
468 gen_op_store_T0_gpr(rD(ctx->opcode)); \
469 if (unlikely(Rc(ctx->opcode) != 0)) \
472 #define __GEN_INT_ARITH1_O(name, opc1, opc2, opc3, type) \
473 GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type) \
475 gen_op_load_gpr_T0(rA(ctx->opcode)); \
477 gen_op_store_T0_gpr(rD(ctx->opcode)); \
478 if (unlikely(Rc(ctx->opcode) != 0)) \
482 /* Two operands arithmetic functions */
483 #define GEN_INT_ARITH2(name, opc1, opc2, opc3, type) \
484 __GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000000, type) \
485 __GEN_INT_ARITH2_O(name##o, opc1, opc2, opc3 | 0x10, 0x00000000, type)
487 /* Two operands arithmetic functions with no overflow allowed */
488 #define GEN_INT_ARITHN(name, opc1, opc2, opc3, type) \
489 __GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000400, type)
491 /* One operand arithmetic functions */
492 #define GEN_INT_ARITH1(name, opc1, opc2, opc3, type) \
493 __GEN_INT_ARITH1(name, opc1, opc2, opc3, type) \
494 __GEN_INT_ARITH1_O(name##o, opc1, opc2, opc3 | 0x10, type)
496 #if defined(TARGET_PPC64)
497 #define __GEN_INT_ARITH2_64(name, opc1, opc2, opc3, inval, type) \
498 GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \
500 gen_op_load_gpr_T0(rA(ctx->opcode)); \
501 gen_op_load_gpr_T1(rB(ctx->opcode)); \
503 gen_op_##name##_64(); \
506 gen_op_store_T0_gpr(rD(ctx->opcode)); \
507 if (unlikely(Rc(ctx->opcode) != 0)) \
511 #define __GEN_INT_ARITH2_O_64(name, opc1, opc2, opc3, inval, type) \
512 GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \
514 gen_op_load_gpr_T0(rA(ctx->opcode)); \
515 gen_op_load_gpr_T1(rB(ctx->opcode)); \
517 gen_op_##name##_64(); \
520 gen_op_store_T0_gpr(rD(ctx->opcode)); \
521 if (unlikely(Rc(ctx->opcode) != 0)) \
525 #define __GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type) \
526 GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type) \
528 gen_op_load_gpr_T0(rA(ctx->opcode)); \
530 gen_op_##name##_64(); \
533 gen_op_store_T0_gpr(rD(ctx->opcode)); \
534 if (unlikely(Rc(ctx->opcode) != 0)) \
537 #define __GEN_INT_ARITH1_O_64(name, opc1, opc2, opc3, type) \
538 GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type) \
540 gen_op_load_gpr_T0(rA(ctx->opcode)); \
542 gen_op_##name##_64(); \
545 gen_op_store_T0_gpr(rD(ctx->opcode)); \
546 if (unlikely(Rc(ctx->opcode) != 0)) \
550 /* Two operands arithmetic functions */
551 #define GEN_INT_ARITH2_64(name, opc1, opc2, opc3, type) \
552 __GEN_INT_ARITH2_64(name, opc1, opc2, opc3, 0x00000000, type) \
553 __GEN_INT_ARITH2_O_64(name##o, opc1, opc2, opc3 | 0x10, 0x00000000, type)
555 /* Two operands arithmetic functions with no overflow allowed */
556 #define GEN_INT_ARITHN_64(name, opc1, opc2, opc3, type) \
557 __GEN_INT_ARITH2_64(name, opc1, opc2, opc3, 0x00000400, type)
559 /* One operand arithmetic functions */
560 #define GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type) \
561 __GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type) \
562 __GEN_INT_ARITH1_O_64(name##o, opc1, opc2, opc3 | 0x10, type)
564 #define GEN_INT_ARITH2_64 GEN_INT_ARITH2
565 #define GEN_INT_ARITHN_64 GEN_INT_ARITHN
566 #define GEN_INT_ARITH1_64 GEN_INT_ARITH1
569 /* add add. addo addo. */
570 static inline void gen_op_addo (void)
576 #if defined(TARGET_PPC64)
577 #define gen_op_add_64 gen_op_add
578 static inline void gen_op_addo_64 (void)
582 gen_op_check_addo_64();
585 GEN_INT_ARITH2_64 (add
, 0x1F, 0x0A, 0x08, PPC_INTEGER
);
586 /* addc addc. addco addco. */
587 static inline void gen_op_addc (void)
593 static inline void gen_op_addco (void)
600 #if defined(TARGET_PPC64)
601 static inline void gen_op_addc_64 (void)
605 gen_op_check_addc_64();
607 static inline void gen_op_addco_64 (void)
611 gen_op_check_addc_64();
612 gen_op_check_addo_64();
615 GEN_INT_ARITH2_64 (addc
, 0x1F, 0x0A, 0x00, PPC_INTEGER
);
616 /* adde adde. addeo addeo. */
617 static inline void gen_op_addeo (void)
623 #if defined(TARGET_PPC64)
624 static inline void gen_op_addeo_64 (void)
628 gen_op_check_addo_64();
631 GEN_INT_ARITH2_64 (adde
, 0x1F, 0x0A, 0x04, PPC_INTEGER
);
632 /* addme addme. addmeo addmeo. */
633 static inline void gen_op_addme (void)
638 #if defined(TARGET_PPC64)
639 static inline void gen_op_addme_64 (void)
645 GEN_INT_ARITH1_64 (addme
, 0x1F, 0x0A, 0x07, PPC_INTEGER
);
646 /* addze addze. addzeo addzeo. */
647 static inline void gen_op_addze (void)
653 static inline void gen_op_addzeo (void)
660 #if defined(TARGET_PPC64)
661 static inline void gen_op_addze_64 (void)
665 gen_op_check_addc_64();
667 static inline void gen_op_addzeo_64 (void)
671 gen_op_check_addc_64();
672 gen_op_check_addo_64();
675 GEN_INT_ARITH1_64 (addze
, 0x1F, 0x0A, 0x06, PPC_INTEGER
);
676 /* divw divw. divwo divwo. */
677 GEN_INT_ARITH2 (divw
, 0x1F, 0x0B, 0x0F, PPC_INTEGER
);
678 /* divwu divwu. divwuo divwuo. */
679 GEN_INT_ARITH2 (divwu
, 0x1F, 0x0B, 0x0E, PPC_INTEGER
);
681 GEN_INT_ARITHN (mulhw
, 0x1F, 0x0B, 0x02, PPC_INTEGER
);
683 GEN_INT_ARITHN (mulhwu
, 0x1F, 0x0B, 0x00, PPC_INTEGER
);
684 /* mullw mullw. mullwo mullwo. */
685 GEN_INT_ARITH2 (mullw
, 0x1F, 0x0B, 0x07, PPC_INTEGER
);
686 /* neg neg. nego nego. */
687 GEN_INT_ARITH1_64 (neg
, 0x1F, 0x08, 0x03, PPC_INTEGER
);
688 /* subf subf. subfo subfo. */
689 static inline void gen_op_subfo (void)
693 gen_op_check_subfo();
695 #if defined(TARGET_PPC64)
696 #define gen_op_subf_64 gen_op_subf
697 static inline void gen_op_subfo_64 (void)
701 gen_op_check_subfo_64();
704 GEN_INT_ARITH2_64 (subf
, 0x1F, 0x08, 0x01, PPC_INTEGER
);
705 /* subfc subfc. subfco subfco. */
706 static inline void gen_op_subfc (void)
709 gen_op_check_subfc();
711 static inline void gen_op_subfco (void)
715 gen_op_check_subfc();
716 gen_op_check_subfo();
718 #if defined(TARGET_PPC64)
719 static inline void gen_op_subfc_64 (void)
722 gen_op_check_subfc_64();
724 static inline void gen_op_subfco_64 (void)
728 gen_op_check_subfc_64();
729 gen_op_check_subfo_64();
732 GEN_INT_ARITH2_64 (subfc
, 0x1F, 0x08, 0x00, PPC_INTEGER
);
733 /* subfe subfe. subfeo subfeo. */
734 static inline void gen_op_subfeo (void)
738 gen_op_check_subfo();
740 #if defined(TARGET_PPC64)
741 #define gen_op_subfe_64 gen_op_subfe
742 static inline void gen_op_subfeo_64 (void)
746 gen_op_check_subfo_64();
749 GEN_INT_ARITH2_64 (subfe
, 0x1F, 0x08, 0x04, PPC_INTEGER
);
750 /* subfme subfme. subfmeo subfmeo. */
751 GEN_INT_ARITH1_64 (subfme
, 0x1F, 0x08, 0x07, PPC_INTEGER
);
752 /* subfze subfze. subfzeo subfzeo. */
753 GEN_INT_ARITH1_64 (subfze
, 0x1F, 0x08, 0x06, PPC_INTEGER
);
755 GEN_HANDLER(addi
, 0x0E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
757 target_long simm
= SIMM(ctx
->opcode
);
759 if (rA(ctx
->opcode
) == 0) {
763 gen_op_load_gpr_T0(rA(ctx
->opcode
));
764 if (likely(simm
!= 0))
767 gen_op_store_T0_gpr(rD(ctx
->opcode
));
770 GEN_HANDLER(addic
, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
772 target_long simm
= SIMM(ctx
->opcode
);
774 gen_op_load_gpr_T0(rA(ctx
->opcode
));
775 if (likely(simm
!= 0)) {
778 #if defined(TARGET_PPC64)
780 gen_op_check_addc_64();
785 gen_op_clear_xer_ca();
787 gen_op_store_T0_gpr(rD(ctx
->opcode
));
790 GEN_HANDLER(addic_
, 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
792 target_long simm
= SIMM(ctx
->opcode
);
794 gen_op_load_gpr_T0(rA(ctx
->opcode
));
795 if (likely(simm
!= 0)) {
798 #if defined(TARGET_PPC64)
800 gen_op_check_addc_64();
805 gen_op_store_T0_gpr(rD(ctx
->opcode
));
809 GEN_HANDLER(addis
, 0x0F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
811 target_long simm
= SIMM(ctx
->opcode
);
813 if (rA(ctx
->opcode
) == 0) {
815 gen_set_T0(simm
<< 16);
817 gen_op_load_gpr_T0(rA(ctx
->opcode
));
818 if (likely(simm
!= 0))
819 gen_op_addi(simm
<< 16);
821 gen_op_store_T0_gpr(rD(ctx
->opcode
));
824 GEN_HANDLER(mulli
, 0x07, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
826 gen_op_load_gpr_T0(rA(ctx
->opcode
));
827 gen_op_mulli(SIMM(ctx
->opcode
));
828 gen_op_store_T0_gpr(rD(ctx
->opcode
));
831 GEN_HANDLER(subfic
, 0x08, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
833 gen_op_load_gpr_T0(rA(ctx
->opcode
));
834 #if defined(TARGET_PPC64)
836 gen_op_subfic_64(SIMM(ctx
->opcode
));
839 gen_op_subfic(SIMM(ctx
->opcode
));
840 gen_op_store_T0_gpr(rD(ctx
->opcode
));
843 #if defined(TARGET_PPC64)
845 GEN_INT_ARITHN (mulhd
, 0x1F, 0x09, 0x02, PPC_INTEGER
);
847 GEN_INT_ARITHN (mulhdu
, 0x1F, 0x09, 0x00, PPC_INTEGER
);
848 /* mulld mulld. mulldo mulldo. */
849 GEN_INT_ARITH2 (mulld
, 0x1F, 0x09, 0x07, PPC_INTEGER
);
850 /* divd divd. divdo divdo. */
851 GEN_INT_ARITH2 (divd
, 0x1F, 0x09, 0x0F, PPC_INTEGER
);
852 /* divdu divdu. divduo divduo. */
853 GEN_INT_ARITH2 (divdu
, 0x1F, 0x09, 0x0E, PPC_INTEGER
);
856 /*** Integer comparison ***/
857 #if defined(TARGET_PPC64)
858 #define GEN_CMP(name, opc, type) \
859 GEN_HANDLER(name, 0x1F, 0x00, opc, 0x00400000, type) \
861 gen_op_load_gpr_T0(rA(ctx->opcode)); \
862 gen_op_load_gpr_T1(rB(ctx->opcode)); \
864 gen_op_##name##_64(); \
867 gen_op_store_T0_crf(crfD(ctx->opcode)); \
870 #define GEN_CMP(name, opc, type) \
871 GEN_HANDLER(name, 0x1F, 0x00, opc, 0x00400000, type) \
873 gen_op_load_gpr_T0(rA(ctx->opcode)); \
874 gen_op_load_gpr_T1(rB(ctx->opcode)); \
876 gen_op_store_T0_crf(crfD(ctx->opcode)); \
881 GEN_CMP(cmp
, 0x00, PPC_INTEGER
);
883 GEN_HANDLER(cmpi
, 0x0B, 0xFF, 0xFF, 0x00400000, PPC_INTEGER
)
885 gen_op_load_gpr_T0(rA(ctx
->opcode
));
886 #if defined(TARGET_PPC64)
888 gen_op_cmpi_64(SIMM(ctx
->opcode
));
891 gen_op_cmpi(SIMM(ctx
->opcode
));
892 gen_op_store_T0_crf(crfD(ctx
->opcode
));
895 GEN_CMP(cmpl
, 0x01, PPC_INTEGER
);
897 GEN_HANDLER(cmpli
, 0x0A, 0xFF, 0xFF, 0x00400000, PPC_INTEGER
)
899 gen_op_load_gpr_T0(rA(ctx
->opcode
));
900 #if defined(TARGET_PPC64)
902 gen_op_cmpli_64(UIMM(ctx
->opcode
));
905 gen_op_cmpli(UIMM(ctx
->opcode
));
906 gen_op_store_T0_crf(crfD(ctx
->opcode
));
909 /* isel (PowerPC 2.03 specification) */
910 GEN_HANDLER(isel
, 0x1F, 0x0F, 0x00, 0x00000001, PPC_203
)
912 uint32_t bi
= rC(ctx
->opcode
);
915 if (rA(ctx
->opcode
) == 0) {
918 gen_op_load_gpr_T1(rA(ctx
->opcode
));
920 gen_op_load_gpr_T2(rB(ctx
->opcode
));
921 mask
= 1 << (3 - (bi
& 0x03));
922 gen_op_load_crf_T0(bi
>> 2);
923 gen_op_test_true(mask
);
925 gen_op_store_T0_gpr(rD(ctx
->opcode
));
928 /*** Integer logical ***/
929 #define __GEN_LOGICAL2(name, opc2, opc3, type) \
930 GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000000, type) \
932 gen_op_load_gpr_T0(rS(ctx->opcode)); \
933 gen_op_load_gpr_T1(rB(ctx->opcode)); \
935 gen_op_store_T0_gpr(rA(ctx->opcode)); \
936 if (unlikely(Rc(ctx->opcode) != 0)) \
939 #define GEN_LOGICAL2(name, opc, type) \
940 __GEN_LOGICAL2(name, 0x1C, opc, type)
942 #define GEN_LOGICAL1(name, opc, type) \
943 GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, type) \
945 gen_op_load_gpr_T0(rS(ctx->opcode)); \
947 gen_op_store_T0_gpr(rA(ctx->opcode)); \
948 if (unlikely(Rc(ctx->opcode) != 0)) \
953 GEN_LOGICAL2(and, 0x00, PPC_INTEGER
);
955 GEN_LOGICAL2(andc
, 0x01, PPC_INTEGER
);
957 GEN_HANDLER(andi_
, 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
959 gen_op_load_gpr_T0(rS(ctx
->opcode
));
960 gen_op_andi_T0(UIMM(ctx
->opcode
));
961 gen_op_store_T0_gpr(rA(ctx
->opcode
));
965 GEN_HANDLER(andis_
, 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
967 gen_op_load_gpr_T0(rS(ctx
->opcode
));
968 gen_op_andi_T0(UIMM(ctx
->opcode
) << 16);
969 gen_op_store_T0_gpr(rA(ctx
->opcode
));
974 GEN_LOGICAL1(cntlzw
, 0x00, PPC_INTEGER
);
976 GEN_LOGICAL2(eqv
, 0x08, PPC_INTEGER
);
978 GEN_LOGICAL1(extsb
, 0x1D, PPC_INTEGER
);
980 GEN_LOGICAL1(extsh
, 0x1C, PPC_INTEGER
);
982 GEN_LOGICAL2(nand
, 0x0E, PPC_INTEGER
);
984 GEN_LOGICAL2(nor
, 0x03, PPC_INTEGER
);
987 GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER
)
991 rs
= rS(ctx
->opcode
);
992 ra
= rA(ctx
->opcode
);
993 rb
= rB(ctx
->opcode
);
994 /* Optimisation for mr. ri case */
995 if (rs
!= ra
|| rs
!= rb
) {
996 gen_op_load_gpr_T0(rs
);
998 gen_op_load_gpr_T1(rb
);
1001 gen_op_store_T0_gpr(ra
);
1002 if (unlikely(Rc(ctx
->opcode
) != 0))
1004 } else if (unlikely(Rc(ctx
->opcode
) != 0)) {
1005 gen_op_load_gpr_T0(rs
);
1011 GEN_LOGICAL2(orc
, 0x0C, PPC_INTEGER
);
1013 GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER
)
1015 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1016 /* Optimisation for "set to zero" case */
1017 if (rS(ctx
->opcode
) != rB(ctx
->opcode
)) {
1018 gen_op_load_gpr_T1(rB(ctx
->opcode
));
1023 gen_op_store_T0_gpr(rA(ctx
->opcode
));
1024 if (unlikely(Rc(ctx
->opcode
) != 0))
1028 GEN_HANDLER(ori
, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
1030 target_ulong uimm
= UIMM(ctx
->opcode
);
1032 if (rS(ctx
->opcode
) == rA(ctx
->opcode
) && uimm
== 0) {
1034 /* XXX: should handle special NOPs for POWER series */
1037 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1038 if (likely(uimm
!= 0))
1040 gen_op_store_T0_gpr(rA(ctx
->opcode
));
1043 GEN_HANDLER(oris
, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
1045 target_ulong uimm
= UIMM(ctx
->opcode
);
1047 if (rS(ctx
->opcode
) == rA(ctx
->opcode
) && uimm
== 0) {
1051 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1052 if (likely(uimm
!= 0))
1053 gen_op_ori(uimm
<< 16);
1054 gen_op_store_T0_gpr(rA(ctx
->opcode
));
1057 GEN_HANDLER(xori
, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
1059 target_ulong uimm
= UIMM(ctx
->opcode
);
1061 if (rS(ctx
->opcode
) == rA(ctx
->opcode
) && uimm
== 0) {
1065 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1066 if (likely(uimm
!= 0))
1068 gen_op_store_T0_gpr(rA(ctx
->opcode
));
1072 GEN_HANDLER(xoris
, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
1074 target_ulong uimm
= UIMM(ctx
->opcode
);
1076 if (rS(ctx
->opcode
) == rA(ctx
->opcode
) && uimm
== 0) {
1080 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1081 if (likely(uimm
!= 0))
1082 gen_op_xori(uimm
<< 16);
1083 gen_op_store_T0_gpr(rA(ctx
->opcode
));
1086 /* popcntb : PowerPC 2.03 specification */
1087 GEN_HANDLER(popcntb
, 0x1F, 0x03, 0x03, 0x0000F801, PPC_203
)
1089 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1090 #if defined(TARGET_PPC64)
1092 gen_op_popcntb_64();
1096 gen_op_store_T0_gpr(rA(ctx
->opcode
));
1099 #if defined(TARGET_PPC64)
1100 /* extsw & extsw. */
1101 GEN_LOGICAL1(extsw
, 0x1E, PPC_64B
);
1103 GEN_LOGICAL1(cntlzd
, 0x01, PPC_64B
);
1106 /*** Integer rotate ***/
1107 /* rlwimi & rlwimi. */
1108 GEN_HANDLER(rlwimi
, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
1111 uint32_t mb
, me
, sh
;
1113 mb
= MB(ctx
->opcode
);
1114 me
= ME(ctx
->opcode
);
1115 sh
= SH(ctx
->opcode
);
1116 if (likely(sh
== 0)) {
1117 if (likely(mb
== 0 && me
== 31)) {
1118 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1120 } else if (likely(mb
== 31 && me
== 0)) {
1121 gen_op_load_gpr_T0(rA(ctx
->opcode
));
1124 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1125 gen_op_load_gpr_T1(rA(ctx
->opcode
));
1128 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1129 gen_op_load_gpr_T1(rA(ctx
->opcode
));
1130 gen_op_rotli32_T0(SH(ctx
->opcode
));
1132 #if defined(TARGET_PPC64)
1136 mask
= MASK(mb
, me
);
1137 gen_op_andi_T0(mask
);
1138 gen_op_andi_T1(~mask
);
1141 gen_op_store_T0_gpr(rA(ctx
->opcode
));
1142 if (unlikely(Rc(ctx
->opcode
) != 0))
1145 /* rlwinm & rlwinm. */
1146 GEN_HANDLER(rlwinm
, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
1148 uint32_t mb
, me
, sh
;
1150 sh
= SH(ctx
->opcode
);
1151 mb
= MB(ctx
->opcode
);
1152 me
= ME(ctx
->opcode
);
1153 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1154 if (likely(sh
== 0)) {
1157 if (likely(mb
== 0)) {
1158 if (likely(me
== 31)) {
1159 gen_op_rotli32_T0(sh
);
1161 } else if (likely(me
== (31 - sh
))) {
1165 } else if (likely(me
== 31)) {
1166 if (likely(sh
== (32 - mb
))) {
1171 gen_op_rotli32_T0(sh
);
1173 #if defined(TARGET_PPC64)
1177 gen_op_andi_T0(MASK(mb
, me
));
1179 gen_op_store_T0_gpr(rA(ctx
->opcode
));
1180 if (unlikely(Rc(ctx
->opcode
) != 0))
1183 /* rlwnm & rlwnm. */
1184 GEN_HANDLER(rlwnm
, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
1188 mb
= MB(ctx
->opcode
);
1189 me
= ME(ctx
->opcode
);
1190 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1191 gen_op_load_gpr_T1(rB(ctx
->opcode
));
1192 gen_op_rotl32_T0_T1();
1193 if (unlikely(mb
!= 0 || me
!= 31)) {
1194 #if defined(TARGET_PPC64)
1198 gen_op_andi_T0(MASK(mb
, me
));
1200 gen_op_store_T0_gpr(rA(ctx
->opcode
));
1201 if (unlikely(Rc(ctx
->opcode
) != 0))
1205 #if defined(TARGET_PPC64)
1206 #define GEN_PPC64_R2(name, opc1, opc2) \
1207 GEN_HANDLER(name##0, opc1, opc2, 0xFF, 0x00000000, PPC_64B) \
1209 gen_##name(ctx, 0); \
1211 GEN_HANDLER(name##1, opc1, opc2 | 0x10, 0xFF, 0x00000000, PPC_64B) \
1213 gen_##name(ctx, 1); \
1215 #define GEN_PPC64_R4(name, opc1, opc2) \
1216 GEN_HANDLER(name##0, opc1, opc2, 0xFF, 0x00000000, PPC_64B) \
1218 gen_##name(ctx, 0, 0); \
1220 GEN_HANDLER(name##1, opc1, opc2 | 0x01, 0xFF, 0x00000000, PPC_64B) \
1222 gen_##name(ctx, 0, 1); \
1224 GEN_HANDLER(name##2, opc1, opc2 | 0x10, 0xFF, 0x00000000, PPC_64B) \
1226 gen_##name(ctx, 1, 0); \
1228 GEN_HANDLER(name##3, opc1, opc2 | 0x11, 0xFF, 0x00000000, PPC_64B) \
1230 gen_##name(ctx, 1, 1); \
1233 static inline void gen_rldinm (DisasContext
*ctx
, uint32_t mb
, uint32_t me
,
1236 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1237 if (likely(sh
== 0)) {
1240 if (likely(mb
== 0)) {
1241 if (likely(me
== 63)) {
1242 gen_op_rotli32_T0(sh
);
1244 } else if (likely(me
== (63 - sh
))) {
1248 } else if (likely(me
== 63)) {
1249 if (likely(sh
== (64 - mb
))) {
1254 gen_op_rotli64_T0(sh
);
1256 gen_op_andi_T0(MASK(mb
, me
));
1258 gen_op_store_T0_gpr(rA(ctx
->opcode
));
1259 if (unlikely(Rc(ctx
->opcode
) != 0))
1262 /* rldicl - rldicl. */
1263 static inline void gen_rldicl (DisasContext
*ctx
, int mbn
, int shn
)
1267 sh
= SH(ctx
->opcode
) | (shn
<< 5);
1268 mb
= MB(ctx
->opcode
) | (mbn
<< 5);
1269 gen_rldinm(ctx
, mb
, 63, sh
);
1271 GEN_PPC64_R4(rldicl
, 0x1E, 0x00);
1272 /* rldicr - rldicr. */
1273 static inline void gen_rldicr (DisasContext
*ctx
, int men
, int shn
)
1277 sh
= SH(ctx
->opcode
) | (shn
<< 5);
1278 me
= MB(ctx
->opcode
) | (men
<< 5);
1279 gen_rldinm(ctx
, 0, me
, sh
);
1281 GEN_PPC64_R4(rldicr
, 0x1E, 0x02);
1282 /* rldic - rldic. */
1283 static inline void gen_rldic (DisasContext
*ctx
, int mbn
, int shn
)
1287 sh
= SH(ctx
->opcode
) | (shn
<< 5);
1288 mb
= MB(ctx
->opcode
) | (mbn
<< 5);
1289 gen_rldinm(ctx
, mb
, 63 - sh
, sh
);
1291 GEN_PPC64_R4(rldic
, 0x1E, 0x04);
1293 static inline void gen_rldnm (DisasContext
*ctx
, uint32_t mb
, uint32_t me
)
1295 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1296 gen_op_load_gpr_T1(rB(ctx
->opcode
));
1297 gen_op_rotl64_T0_T1();
1298 if (unlikely(mb
!= 0 || me
!= 63)) {
1299 gen_op_andi_T0(MASK(mb
, me
));
1301 gen_op_store_T0_gpr(rA(ctx
->opcode
));
1302 if (unlikely(Rc(ctx
->opcode
) != 0))
1306 /* rldcl - rldcl. */
1307 static inline void gen_rldcl (DisasContext
*ctx
, int mbn
)
1311 mb
= MB(ctx
->opcode
) | (mbn
<< 5);
1312 gen_rldnm(ctx
, mb
, 63);
1314 GEN_PPC64_R2(rldcl
, 0x1E, 0x08)
1315 /* rldcr - rldcr. */
1316 static inline void gen_rldcr (DisasContext
*ctx
, int men
)
1320 me
= MB(ctx
->opcode
) | (men
<< 5);
1321 gen_rldnm(ctx
, 0, me
);
1323 GEN_PPC64_R2(rldcr
, 0x1E, 0x09)
1324 /* rldimi - rldimi. */
1325 static inline void gen_rldimi (DisasContext
*ctx
, int mbn
, int shn
)
1330 sh
= SH(ctx
->opcode
) | (shn
<< 5);
1331 mb
= MB(ctx
->opcode
) | (mbn
<< 5);
1332 if (likely(sh
== 0)) {
1333 if (likely(mb
== 0)) {
1334 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1336 } else if (likely(mb
== 63)) {
1337 gen_op_load_gpr_T0(rA(ctx
->opcode
));
1340 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1341 gen_op_load_gpr_T1(rA(ctx
->opcode
));
1344 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1345 gen_op_load_gpr_T1(rA(ctx
->opcode
));
1346 gen_op_rotli64_T0(SH(ctx
->opcode
));
1348 mask
= MASK(mb
, 63 - sh
);
1349 gen_op_andi_T0(mask
);
1350 gen_op_andi_T1(~mask
);
1353 gen_op_store_T0_gpr(rA(ctx
->opcode
));
1354 if (unlikely(Rc(ctx
->opcode
) != 0))
1357 GEN_PPC64_R4(rldimi
, 0x1E, 0x06)
1360 /*** Integer shift ***/
1362 __GEN_LOGICAL2(slw
, 0x18, 0x00, PPC_INTEGER
);
1364 __GEN_LOGICAL2(sraw
, 0x18, 0x18, PPC_INTEGER
);
1365 /* srawi & srawi. */
1366 GEN_HANDLER(srawi
, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER
)
1369 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1370 if (SH(ctx
->opcode
) != 0) {
1371 gen_op_move_T1_T0();
1372 mb
= 32 - SH(ctx
->opcode
);
1374 #if defined(TARGET_PPC64)
1378 gen_op_srawi(SH(ctx
->opcode
), MASK(mb
, me
));
1380 gen_op_store_T0_gpr(rA(ctx
->opcode
));
1381 if (unlikely(Rc(ctx
->opcode
) != 0))
1385 __GEN_LOGICAL2(srw
, 0x18, 0x10, PPC_INTEGER
);
1387 #if defined(TARGET_PPC64)
1389 __GEN_LOGICAL2(sld
, 0x1B, 0x00, PPC_64B
);
1391 __GEN_LOGICAL2(srad
, 0x1A, 0x18, PPC_64B
);
1392 /* sradi & sradi. */
1393 static inline void gen_sradi (DisasContext
*ctx
, int n
)
1398 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1399 sh
= SH(ctx
->opcode
) + (n
<< 5);
1401 gen_op_move_T1_T0();
1402 mb
= 64 - SH(ctx
->opcode
);
1404 mask
= MASK(mb
, me
);
1405 gen_op_sradi(sh
, mask
>> 32, mask
);
1407 gen_op_store_T0_gpr(rA(ctx
->opcode
));
1408 if (unlikely(Rc(ctx
->opcode
) != 0))
1411 GEN_HANDLER(sradi0
, 0x1F, 0x1A, 0x19, 0x00000000, PPC_64B
)
1415 GEN_HANDLER(sradi1
, 0x1F, 0x1B, 0x19, 0x00000000, PPC_64B
)
1420 __GEN_LOGICAL2(srd
, 0x1B, 0x10, PPC_64B
);
1423 /*** Floating-Point arithmetic ***/
1424 #define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat) \
1425 GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, PPC_FLOAT) \
1427 if (unlikely(!ctx->fpu_enabled)) { \
1428 RET_EXCP(ctx, EXCP_NO_FP, 0); \
1431 gen_op_reset_scrfx(); \
1432 gen_op_load_fpr_FT0(rA(ctx->opcode)); \
1433 gen_op_load_fpr_FT1(rC(ctx->opcode)); \
1434 gen_op_load_fpr_FT2(rB(ctx->opcode)); \
1439 gen_op_store_FT0_fpr(rD(ctx->opcode)); \
1440 if (unlikely(Rc(ctx->opcode) != 0)) \
1444 #define GEN_FLOAT_ACB(name, op2) \
1445 _GEN_FLOAT_ACB(name, name, 0x3F, op2, 0); \
1446 _GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1);
1448 #define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat) \
1449 GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT) \
1451 if (unlikely(!ctx->fpu_enabled)) { \
1452 RET_EXCP(ctx, EXCP_NO_FP, 0); \
1455 gen_op_reset_scrfx(); \
1456 gen_op_load_fpr_FT0(rA(ctx->opcode)); \
1457 gen_op_load_fpr_FT1(rB(ctx->opcode)); \
1462 gen_op_store_FT0_fpr(rD(ctx->opcode)); \
1463 if (unlikely(Rc(ctx->opcode) != 0)) \
1466 #define GEN_FLOAT_AB(name, op2, inval) \
1467 _GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0); \
1468 _GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1);
1470 #define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat) \
1471 GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT) \
1473 if (unlikely(!ctx->fpu_enabled)) { \
1474 RET_EXCP(ctx, EXCP_NO_FP, 0); \
1477 gen_op_reset_scrfx(); \
1478 gen_op_load_fpr_FT0(rA(ctx->opcode)); \
1479 gen_op_load_fpr_FT1(rC(ctx->opcode)); \
1484 gen_op_store_FT0_fpr(rD(ctx->opcode)); \
1485 if (unlikely(Rc(ctx->opcode) != 0)) \
1488 #define GEN_FLOAT_AC(name, op2, inval) \
1489 _GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0); \
1490 _GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1);
1492 #define GEN_FLOAT_B(name, op2, op3) \
1493 GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, PPC_FLOAT) \
1495 if (unlikely(!ctx->fpu_enabled)) { \
1496 RET_EXCP(ctx, EXCP_NO_FP, 0); \
1499 gen_op_reset_scrfx(); \
1500 gen_op_load_fpr_FT0(rB(ctx->opcode)); \
1502 gen_op_store_FT0_fpr(rD(ctx->opcode)); \
1503 if (unlikely(Rc(ctx->opcode) != 0)) \
1507 #define GEN_FLOAT_BS(name, op1, op2) \
1508 GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, PPC_FLOAT) \
1510 if (unlikely(!ctx->fpu_enabled)) { \
1511 RET_EXCP(ctx, EXCP_NO_FP, 0); \
1514 gen_op_reset_scrfx(); \
1515 gen_op_load_fpr_FT0(rB(ctx->opcode)); \
1517 gen_op_store_FT0_fpr(rD(ctx->opcode)); \
1518 if (unlikely(Rc(ctx->opcode) != 0)) \
1523 GEN_FLOAT_AB(add
, 0x15, 0x000007C0);
1525 GEN_FLOAT_AB(div
, 0x12, 0x000007C0);
1527 GEN_FLOAT_AC(mul
, 0x19, 0x0000F800);
1529 /* fres */ /* XXX: not in 601 */
1530 GEN_FLOAT_BS(res
, 0x3B, 0x18);
1532 /* frsqrte */ /* XXX: not in 601 */
1533 GEN_FLOAT_BS(rsqrte
, 0x3F, 0x1A);
1535 /* fsel */ /* XXX: not in 601 */
1536 _GEN_FLOAT_ACB(sel
, sel
, 0x3F, 0x17, 0);
1538 GEN_FLOAT_AB(sub
, 0x14, 0x000007C0);
1541 GEN_HANDLER(fsqrt
, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_OPT
)
1543 if (unlikely(!ctx
->fpu_enabled
)) {
1544 RET_EXCP(ctx
, EXCP_NO_FP
, 0);
1547 gen_op_reset_scrfx();
1548 gen_op_load_fpr_FT0(rB(ctx
->opcode
));
1550 gen_op_store_FT0_fpr(rD(ctx
->opcode
));
1551 if (unlikely(Rc(ctx
->opcode
) != 0))
1555 GEN_HANDLER(fsqrts
, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_OPT
)
1557 if (unlikely(!ctx
->fpu_enabled
)) {
1558 RET_EXCP(ctx
, EXCP_NO_FP
, 0);
1561 gen_op_reset_scrfx();
1562 gen_op_load_fpr_FT0(rB(ctx
->opcode
));
1565 gen_op_store_FT0_fpr(rD(ctx
->opcode
));
1566 if (unlikely(Rc(ctx
->opcode
) != 0))
1570 /*** Floating-Point multiply-and-add ***/
1571 /* fmadd - fmadds */
1572 GEN_FLOAT_ACB(madd
, 0x1D);
1573 /* fmsub - fmsubs */
1574 GEN_FLOAT_ACB(msub
, 0x1C);
1575 /* fnmadd - fnmadds */
1576 GEN_FLOAT_ACB(nmadd
, 0x1F);
1577 /* fnmsub - fnmsubs */
1578 GEN_FLOAT_ACB(nmsub
, 0x1E);
1580 /*** Floating-Point round & convert ***/
1582 GEN_FLOAT_B(ctiw
, 0x0E, 0x00);
1584 GEN_FLOAT_B(ctiwz
, 0x0F, 0x00);
1586 GEN_FLOAT_B(rsp
, 0x0C, 0x00);
1587 #if defined(TARGET_PPC64)
1589 GEN_FLOAT_B(cfid
, 0x0E, 0x1A);
1591 GEN_FLOAT_B(ctid
, 0x0E, 0x19);
1593 GEN_FLOAT_B(ctidz
, 0x0F, 0x19);
1596 /*** Floating-Point compare ***/
1598 GEN_HANDLER(fcmpo
, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT
)
1600 if (unlikely(!ctx
->fpu_enabled
)) {
1601 RET_EXCP(ctx
, EXCP_NO_FP
, 0);
1604 gen_op_reset_scrfx();
1605 gen_op_load_fpr_FT0(rA(ctx
->opcode
));
1606 gen_op_load_fpr_FT1(rB(ctx
->opcode
));
1608 gen_op_store_T0_crf(crfD(ctx
->opcode
));
1612 GEN_HANDLER(fcmpu
, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT
)
1614 if (unlikely(!ctx
->fpu_enabled
)) {
1615 RET_EXCP(ctx
, EXCP_NO_FP
, 0);
1618 gen_op_reset_scrfx();
1619 gen_op_load_fpr_FT0(rA(ctx
->opcode
));
1620 gen_op_load_fpr_FT1(rB(ctx
->opcode
));
1622 gen_op_store_T0_crf(crfD(ctx
->opcode
));
1625 /*** Floating-point move ***/
1627 GEN_FLOAT_B(abs
, 0x08, 0x08);
1630 GEN_HANDLER(fmr
, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT
)
1632 if (unlikely(!ctx
->fpu_enabled
)) {
1633 RET_EXCP(ctx
, EXCP_NO_FP
, 0);
1636 gen_op_reset_scrfx();
1637 gen_op_load_fpr_FT0(rB(ctx
->opcode
));
1638 gen_op_store_FT0_fpr(rD(ctx
->opcode
));
1639 if (unlikely(Rc(ctx
->opcode
) != 0))
1644 GEN_FLOAT_B(nabs
, 0x08, 0x04);
1646 GEN_FLOAT_B(neg
, 0x08, 0x01);
1648 /*** Floating-Point status & ctrl register ***/
1650 GEN_HANDLER(mcrfs
, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT
)
1652 if (unlikely(!ctx
->fpu_enabled
)) {
1653 RET_EXCP(ctx
, EXCP_NO_FP
, 0);
1656 gen_op_load_fpscr_T0(crfS(ctx
->opcode
));
1657 gen_op_store_T0_crf(crfD(ctx
->opcode
));
1658 gen_op_clear_fpscr(crfS(ctx
->opcode
));
1662 GEN_HANDLER(mffs
, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT
)
1664 if (unlikely(!ctx
->fpu_enabled
)) {
1665 RET_EXCP(ctx
, EXCP_NO_FP
, 0);
1668 gen_op_load_fpscr();
1669 gen_op_store_FT0_fpr(rD(ctx
->opcode
));
1670 if (unlikely(Rc(ctx
->opcode
) != 0))
1675 GEN_HANDLER(mtfsb0
, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT
)
1679 if (unlikely(!ctx
->fpu_enabled
)) {
1680 RET_EXCP(ctx
, EXCP_NO_FP
, 0);
1683 crb
= crbD(ctx
->opcode
) >> 2;
1684 gen_op_load_fpscr_T0(crb
);
1685 gen_op_andi_T0(~(1 << (crbD(ctx
->opcode
) & 0x03)));
1686 gen_op_store_T0_fpscr(crb
);
1687 if (unlikely(Rc(ctx
->opcode
) != 0))
1692 GEN_HANDLER(mtfsb1
, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT
)
1696 if (unlikely(!ctx
->fpu_enabled
)) {
1697 RET_EXCP(ctx
, EXCP_NO_FP
, 0);
1700 crb
= crbD(ctx
->opcode
) >> 2;
1701 gen_op_load_fpscr_T0(crb
);
1702 gen_op_ori(1 << (crbD(ctx
->opcode
) & 0x03));
1703 gen_op_store_T0_fpscr(crb
);
1704 if (unlikely(Rc(ctx
->opcode
) != 0))
1709 GEN_HANDLER(mtfsf
, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT
)
1711 if (unlikely(!ctx
->fpu_enabled
)) {
1712 RET_EXCP(ctx
, EXCP_NO_FP
, 0);
1715 gen_op_load_fpr_FT0(rB(ctx
->opcode
));
1716 gen_op_store_fpscr(FM(ctx
->opcode
));
1717 if (unlikely(Rc(ctx
->opcode
) != 0))
1722 GEN_HANDLER(mtfsfi
, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT
)
1724 if (unlikely(!ctx
->fpu_enabled
)) {
1725 RET_EXCP(ctx
, EXCP_NO_FP
, 0);
1728 gen_op_store_T0_fpscri(crbD(ctx
->opcode
) >> 2, FPIMM(ctx
->opcode
));
1729 if (unlikely(Rc(ctx
->opcode
) != 0))
1733 /*** Addressing modes ***/
1734 /* Register indirect with immediate index : EA = (rA|0) + SIMM */
1735 static inline void gen_addr_imm_index (DisasContext
*ctx
, int maskl
)
1737 target_long simm
= SIMM(ctx
->opcode
);
1741 if (rA(ctx
->opcode
) == 0) {
1744 gen_op_load_gpr_T0(rA(ctx
->opcode
));
1745 if (likely(simm
!= 0))
1750 static inline void gen_addr_reg_index (DisasContext
*ctx
)
1752 if (rA(ctx
->opcode
) == 0) {
1753 gen_op_load_gpr_T0(rB(ctx
->opcode
));
1755 gen_op_load_gpr_T0(rA(ctx
->opcode
));
1756 gen_op_load_gpr_T1(rB(ctx
->opcode
));
1761 static inline void gen_addr_register (DisasContext
*ctx
)
1763 if (rA(ctx
->opcode
) == 0) {
1766 gen_op_load_gpr_T0(rA(ctx
->opcode
));
1770 /*** Integer load ***/
1771 #define op_ldst(name) (*gen_op_##name[ctx->mem_idx])()
1772 #if defined(CONFIG_USER_ONLY)
1773 #if defined(TARGET_PPC64)
1774 #define OP_LD_TABLE(width) \
1775 static GenOpFunc *gen_op_l##width[] = { \
1776 &gen_op_l##width##_raw, \
1777 &gen_op_l##width##_le_raw, \
1778 &gen_op_l##width##_64_raw, \
1779 &gen_op_l##width##_le_64_raw, \
1781 #define OP_ST_TABLE(width) \
1782 static GenOpFunc *gen_op_st##width[] = { \
1783 &gen_op_st##width##_raw, \
1784 &gen_op_st##width##_le_raw, \
1785 &gen_op_st##width##_64_raw, \
1786 &gen_op_st##width##_le_64_raw, \
1788 /* Byte access routine are endian safe */
1789 #define gen_op_stb_le_64_raw gen_op_stb_64_raw
1790 #define gen_op_lbz_le_64_raw gen_op_lbz_64_raw
1792 #define OP_LD_TABLE(width) \
1793 static GenOpFunc *gen_op_l##width[] = { \
1794 &gen_op_l##width##_raw, \
1795 &gen_op_l##width##_le_raw, \
1797 #define OP_ST_TABLE(width) \
1798 static GenOpFunc *gen_op_st##width[] = { \
1799 &gen_op_st##width##_raw, \
1800 &gen_op_st##width##_le_raw, \
1803 /* Byte access routine are endian safe */
1804 #define gen_op_stb_le_raw gen_op_stb_raw
1805 #define gen_op_lbz_le_raw gen_op_lbz_raw
1807 #if defined(TARGET_PPC64)
1808 #define OP_LD_TABLE(width) \
1809 static GenOpFunc *gen_op_l##width[] = { \
1810 &gen_op_l##width##_user, \
1811 &gen_op_l##width##_le_user, \
1812 &gen_op_l##width##_kernel, \
1813 &gen_op_l##width##_le_kernel, \
1814 &gen_op_l##width##_64_user, \
1815 &gen_op_l##width##_le_64_user, \
1816 &gen_op_l##width##_64_kernel, \
1817 &gen_op_l##width##_le_64_kernel, \
1819 #define OP_ST_TABLE(width) \
1820 static GenOpFunc *gen_op_st##width[] = { \
1821 &gen_op_st##width##_user, \
1822 &gen_op_st##width##_le_user, \
1823 &gen_op_st##width##_kernel, \
1824 &gen_op_st##width##_le_kernel, \
1825 &gen_op_st##width##_64_user, \
1826 &gen_op_st##width##_le_64_user, \
1827 &gen_op_st##width##_64_kernel, \
1828 &gen_op_st##width##_le_64_kernel, \
1830 /* Byte access routine are endian safe */
1831 #define gen_op_stb_le_64_user gen_op_stb_64_user
1832 #define gen_op_lbz_le_64_user gen_op_lbz_64_user
1833 #define gen_op_stb_le_64_kernel gen_op_stb_64_kernel
1834 #define gen_op_lbz_le_64_kernel gen_op_lbz_64_kernel
1836 #define OP_LD_TABLE(width) \
1837 static GenOpFunc *gen_op_l##width[] = { \
1838 &gen_op_l##width##_user, \
1839 &gen_op_l##width##_le_user, \
1840 &gen_op_l##width##_kernel, \
1841 &gen_op_l##width##_le_kernel, \
1843 #define OP_ST_TABLE(width) \
1844 static GenOpFunc *gen_op_st##width[] = { \
1845 &gen_op_st##width##_user, \
1846 &gen_op_st##width##_le_user, \
1847 &gen_op_st##width##_kernel, \
1848 &gen_op_st##width##_le_kernel, \
1851 /* Byte access routine are endian safe */
1852 #define gen_op_stb_le_user gen_op_stb_user
1853 #define gen_op_lbz_le_user gen_op_lbz_user
1854 #define gen_op_stb_le_kernel gen_op_stb_kernel
1855 #define gen_op_lbz_le_kernel gen_op_lbz_kernel
1858 #define GEN_LD(width, opc, type) \
1859 GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, type) \
1861 gen_addr_imm_index(ctx, 0); \
1862 op_ldst(l##width); \
1863 gen_op_store_T1_gpr(rD(ctx->opcode)); \
1866 #define GEN_LDU(width, opc, type) \
1867 GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, type) \
1869 if (unlikely(rA(ctx->opcode) == 0 || \
1870 rA(ctx->opcode) == rD(ctx->opcode))) { \
1874 if (type == PPC_64B) \
1875 gen_addr_imm_index(ctx, 1); \
1877 gen_addr_imm_index(ctx, 0); \
1878 op_ldst(l##width); \
1879 gen_op_store_T1_gpr(rD(ctx->opcode)); \
1880 gen_op_store_T0_gpr(rA(ctx->opcode)); \
1883 #define GEN_LDUX(width, opc2, opc3, type) \
1884 GEN_HANDLER(l##width##ux, 0x1F, opc2, opc3, 0x00000001, type) \
1886 if (unlikely(rA(ctx->opcode) == 0 || \
1887 rA(ctx->opcode) == rD(ctx->opcode))) { \
1891 gen_addr_reg_index(ctx); \
1892 op_ldst(l##width); \
1893 gen_op_store_T1_gpr(rD(ctx->opcode)); \
1894 gen_op_store_T0_gpr(rA(ctx->opcode)); \
1897 #define GEN_LDX(width, opc2, opc3, type) \
1898 GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, type) \
1900 gen_addr_reg_index(ctx); \
1901 op_ldst(l##width); \
1902 gen_op_store_T1_gpr(rD(ctx->opcode)); \
1905 #define GEN_LDS(width, op, type) \
1906 OP_LD_TABLE(width); \
1907 GEN_LD(width, op | 0x20, type); \
1908 GEN_LDU(width, op | 0x21, type); \
1909 GEN_LDUX(width, 0x17, op | 0x01, type); \
1910 GEN_LDX(width, 0x17, op | 0x00, type)
1912 /* lbz lbzu lbzux lbzx */
1913 GEN_LDS(bz
, 0x02, PPC_INTEGER
);
1914 /* lha lhau lhaux lhax */
1915 GEN_LDS(ha
, 0x0A, PPC_INTEGER
);
1916 /* lhz lhzu lhzux lhzx */
1917 GEN_LDS(hz
, 0x08, PPC_INTEGER
);
1918 /* lwz lwzu lwzux lwzx */
1919 GEN_LDS(wz
, 0x00, PPC_INTEGER
);
1920 #if defined(TARGET_PPC64)
1924 GEN_LDUX(wa
, 0x15, 0x0B, PPC_64B
);
1926 GEN_LDX(wa
, 0x15, 0x0A, PPC_64B
);
1928 GEN_LDUX(d
, 0x15, 0x01, PPC_64B
);
1930 GEN_LDX(d
, 0x15, 0x00, PPC_64B
);
1931 GEN_HANDLER(ld
, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B
)
1933 if (Rc(ctx
->opcode
)) {
1934 if (unlikely(rA(ctx
->opcode
) == 0 ||
1935 rA(ctx
->opcode
) == rD(ctx
->opcode
))) {
1940 gen_addr_imm_index(ctx
, 1);
1941 if (ctx
->opcode
& 0x02) {
1942 /* lwa (lwau is undefined) */
1948 gen_op_store_T1_gpr(rD(ctx
->opcode
));
1949 if (Rc(ctx
->opcode
))
1950 gen_op_store_T0_gpr(rA(ctx
->opcode
));
1954 /*** Integer store ***/
1955 #define GEN_ST(width, opc, type) \
1956 GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, type) \
1958 gen_addr_imm_index(ctx, 0); \
1959 gen_op_load_gpr_T1(rS(ctx->opcode)); \
1960 op_ldst(st##width); \
1963 #define GEN_STU(width, opc, type) \
1964 GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, type) \
1966 if (unlikely(rA(ctx->opcode) == 0)) { \
1970 if (type == PPC_64B) \
1971 gen_addr_imm_index(ctx, 1); \
1973 gen_addr_imm_index(ctx, 0); \
1974 gen_op_load_gpr_T1(rS(ctx->opcode)); \
1975 op_ldst(st##width); \
1976 gen_op_store_T0_gpr(rA(ctx->opcode)); \
1979 #define GEN_STUX(width, opc2, opc3, type) \
1980 GEN_HANDLER(st##width##ux, 0x1F, opc2, opc3, 0x00000001, type) \
1982 if (unlikely(rA(ctx->opcode) == 0)) { \
1986 gen_addr_reg_index(ctx); \
1987 gen_op_load_gpr_T1(rS(ctx->opcode)); \
1988 op_ldst(st##width); \
1989 gen_op_store_T0_gpr(rA(ctx->opcode)); \
1992 #define GEN_STX(width, opc2, opc3, type) \
1993 GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, type) \
1995 gen_addr_reg_index(ctx); \
1996 gen_op_load_gpr_T1(rS(ctx->opcode)); \
1997 op_ldst(st##width); \
2000 #define GEN_STS(width, op, type) \
2001 OP_ST_TABLE(width); \
2002 GEN_ST(width, op | 0x20, type); \
2003 GEN_STU(width, op | 0x21, type); \
2004 GEN_STUX(width, 0x17, op | 0x01, type); \
2005 GEN_STX(width, 0x17, op | 0x00, type)
2007 /* stb stbu stbux stbx */
2008 GEN_STS(b
, 0x06, PPC_INTEGER
);
2009 /* sth sthu sthux sthx */
2010 GEN_STS(h
, 0x0C, PPC_INTEGER
);
2011 /* stw stwu stwux stwx */
2012 GEN_STS(w
, 0x04, PPC_INTEGER
);
2013 #if defined(TARGET_PPC64)
2015 GEN_STUX(d
, 0x15, 0x05, PPC_64B
);
2016 GEN_STX(d
, 0x15, 0x04, PPC_64B
);
2017 GEN_HANDLER(std
, 0x3E, 0xFF, 0xFF, 0x00000002, PPC_64B
)
2019 if (Rc(ctx
->opcode
)) {
2020 if (unlikely(rA(ctx
->opcode
) == 0)) {
2025 gen_addr_imm_index(ctx
, 1);
2026 gen_op_load_gpr_T1(rS(ctx
->opcode
));
2028 if (Rc(ctx
->opcode
))
2029 gen_op_store_T0_gpr(rA(ctx
->opcode
));
2032 /*** Integer load and store with byte reverse ***/
2035 GEN_LDX(hbr
, 0x16, 0x18, PPC_INTEGER
);
2038 GEN_LDX(wbr
, 0x16, 0x10, PPC_INTEGER
);
2041 GEN_STX(hbr
, 0x16, 0x1C, PPC_INTEGER
);
2044 GEN_STX(wbr
, 0x16, 0x14, PPC_INTEGER
);
2046 /*** Integer load and store multiple ***/
2047 #define op_ldstm(name, reg) (*gen_op_##name[ctx->mem_idx])(reg)
2048 #if defined(TARGET_PPC64)
2049 #if defined(CONFIG_USER_ONLY)
2050 static GenOpFunc1
*gen_op_lmw
[] = {
2054 &gen_op_lmw_le_64_raw
,
2056 static GenOpFunc1
*gen_op_stmw
[] = {
2057 &gen_op_stmw_64_raw
,
2058 &gen_op_stmw_le_64_raw
,
2061 static GenOpFunc1
*gen_op_lmw
[] = {
2063 &gen_op_lmw_le_user
,
2065 &gen_op_lmw_le_kernel
,
2066 &gen_op_lmw_64_user
,
2067 &gen_op_lmw_le_64_user
,
2068 &gen_op_lmw_64_kernel
,
2069 &gen_op_lmw_le_64_kernel
,
2071 static GenOpFunc1
*gen_op_stmw
[] = {
2073 &gen_op_stmw_le_user
,
2074 &gen_op_stmw_kernel
,
2075 &gen_op_stmw_le_kernel
,
2076 &gen_op_stmw_64_user
,
2077 &gen_op_stmw_le_64_user
,
2078 &gen_op_stmw_64_kernel
,
2079 &gen_op_stmw_le_64_kernel
,
2083 #if defined(CONFIG_USER_ONLY)
2084 static GenOpFunc1
*gen_op_lmw
[] = {
2088 static GenOpFunc1
*gen_op_stmw
[] = {
2090 &gen_op_stmw_le_raw
,
2093 static GenOpFunc1
*gen_op_lmw
[] = {
2095 &gen_op_lmw_le_user
,
2097 &gen_op_lmw_le_kernel
,
2099 static GenOpFunc1
*gen_op_stmw
[] = {
2101 &gen_op_stmw_le_user
,
2102 &gen_op_stmw_kernel
,
2103 &gen_op_stmw_le_kernel
,
2109 GEN_HANDLER(lmw
, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
2111 /* NIP cannot be restored if the memory exception comes from an helper */
2112 gen_update_nip(ctx
, ctx
->nip
- 4);
2113 gen_addr_imm_index(ctx
, 0);
2114 op_ldstm(lmw
, rD(ctx
->opcode
));
2118 GEN_HANDLER(stmw
, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
2120 /* NIP cannot be restored if the memory exception comes from an helper */
2121 gen_update_nip(ctx
, ctx
->nip
- 4);
2122 gen_addr_imm_index(ctx
, 0);
2123 op_ldstm(stmw
, rS(ctx
->opcode
));
2126 /*** Integer load and store strings ***/
2127 #define op_ldsts(name, start) (*gen_op_##name[ctx->mem_idx])(start)
2128 #define op_ldstsx(name, rd, ra, rb) (*gen_op_##name[ctx->mem_idx])(rd, ra, rb)
2129 #if defined(TARGET_PPC64)
2130 #if defined(CONFIG_USER_ONLY)
2131 static GenOpFunc1
*gen_op_lswi
[] = {
2133 &gen_op_lswi_le_raw
,
2134 &gen_op_lswi_64_raw
,
2135 &gen_op_lswi_le_64_raw
,
2137 static GenOpFunc3
*gen_op_lswx
[] = {
2139 &gen_op_lswx_le_raw
,
2140 &gen_op_lswx_64_raw
,
2141 &gen_op_lswx_le_64_raw
,
2143 static GenOpFunc1
*gen_op_stsw
[] = {
2145 &gen_op_stsw_le_raw
,
2146 &gen_op_stsw_64_raw
,
2147 &gen_op_stsw_le_64_raw
,
2150 static GenOpFunc1
*gen_op_lswi
[] = {
2152 &gen_op_lswi_le_user
,
2153 &gen_op_lswi_kernel
,
2154 &gen_op_lswi_le_kernel
,
2155 &gen_op_lswi_64_user
,
2156 &gen_op_lswi_le_64_user
,
2157 &gen_op_lswi_64_kernel
,
2158 &gen_op_lswi_le_64_kernel
,
2160 static GenOpFunc3
*gen_op_lswx
[] = {
2162 &gen_op_lswx_le_user
,
2163 &gen_op_lswx_kernel
,
2164 &gen_op_lswx_le_kernel
,
2165 &gen_op_lswx_64_user
,
2166 &gen_op_lswx_le_64_user
,
2167 &gen_op_lswx_64_kernel
,
2168 &gen_op_lswx_le_64_kernel
,
2170 static GenOpFunc1
*gen_op_stsw
[] = {
2172 &gen_op_stsw_le_user
,
2173 &gen_op_stsw_kernel
,
2174 &gen_op_stsw_le_kernel
,
2175 &gen_op_stsw_64_user
,
2176 &gen_op_stsw_le_64_user
,
2177 &gen_op_stsw_64_kernel
,
2178 &gen_op_stsw_le_64_kernel
,
2182 #if defined(CONFIG_USER_ONLY)
2183 static GenOpFunc1
*gen_op_lswi
[] = {
2185 &gen_op_lswi_le_raw
,
2187 static GenOpFunc3
*gen_op_lswx
[] = {
2189 &gen_op_lswx_le_raw
,
2191 static GenOpFunc1
*gen_op_stsw
[] = {
2193 &gen_op_stsw_le_raw
,
2196 static GenOpFunc1
*gen_op_lswi
[] = {
2198 &gen_op_lswi_le_user
,
2199 &gen_op_lswi_kernel
,
2200 &gen_op_lswi_le_kernel
,
2202 static GenOpFunc3
*gen_op_lswx
[] = {
2204 &gen_op_lswx_le_user
,
2205 &gen_op_lswx_kernel
,
2206 &gen_op_lswx_le_kernel
,
2208 static GenOpFunc1
*gen_op_stsw
[] = {
2210 &gen_op_stsw_le_user
,
2211 &gen_op_stsw_kernel
,
2212 &gen_op_stsw_le_kernel
,
2218 /* PowerPC32 specification says we must generate an exception if
2219 * rA is in the range of registers to be loaded.
2220 * In an other hand, IBM says this is valid, but rA won't be loaded.
2221 * For now, I'll follow the spec...
2223 GEN_HANDLER(lswi
, 0x1F, 0x15, 0x12, 0x00000001, PPC_INTEGER
)
2225 int nb
= NB(ctx
->opcode
);
2226 int start
= rD(ctx
->opcode
);
2227 int ra
= rA(ctx
->opcode
);
2233 if (unlikely(((start
+ nr
) > 32 &&
2234 start
<= ra
&& (start
+ nr
- 32) > ra
) ||
2235 ((start
+ nr
) <= 32 && start
<= ra
&& (start
+ nr
) > ra
))) {
2236 RET_EXCP(ctx
, EXCP_PROGRAM
, EXCP_INVAL
| EXCP_INVAL_LSWX
);
2239 /* NIP cannot be restored if the memory exception comes from an helper */
2240 gen_update_nip(ctx
, ctx
->nip
- 4);
2241 gen_addr_register(ctx
);
2243 op_ldsts(lswi
, start
);
2247 GEN_HANDLER(lswx
, 0x1F, 0x15, 0x10, 0x00000001, PPC_INTEGER
)
2249 int ra
= rA(ctx
->opcode
);
2250 int rb
= rB(ctx
->opcode
);
2252 /* NIP cannot be restored if the memory exception comes from an helper */
2253 gen_update_nip(ctx
, ctx
->nip
- 4);
2254 gen_addr_reg_index(ctx
);
2258 gen_op_load_xer_bc();
2259 op_ldstsx(lswx
, rD(ctx
->opcode
), ra
, rb
);
2263 GEN_HANDLER(stswi
, 0x1F, 0x15, 0x16, 0x00000001, PPC_INTEGER
)
2265 int nb
= NB(ctx
->opcode
);
2267 /* NIP cannot be restored if the memory exception comes from an helper */
2268 gen_update_nip(ctx
, ctx
->nip
- 4);
2269 gen_addr_register(ctx
);
2273 op_ldsts(stsw
, rS(ctx
->opcode
));
2277 GEN_HANDLER(stswx
, 0x1F, 0x15, 0x14, 0x00000001, PPC_INTEGER
)
2279 /* NIP cannot be restored if the memory exception comes from an helper */
2280 gen_update_nip(ctx
, ctx
->nip
- 4);
2281 gen_addr_reg_index(ctx
);
2282 gen_op_load_xer_bc();
2283 op_ldsts(stsw
, rS(ctx
->opcode
));
2286 /*** Memory synchronisation ***/
2288 GEN_HANDLER(eieio
, 0x1F, 0x16, 0x1A, 0x03FF0801, PPC_MEM_EIEIO
)
2293 GEN_HANDLER(isync
, 0x13, 0x16, 0x04, 0x03FF0801, PPC_MEM
)
2297 #define op_lwarx() (*gen_op_lwarx[ctx->mem_idx])()
2298 #define op_stwcx() (*gen_op_stwcx[ctx->mem_idx])()
2299 #if defined(TARGET_PPC64)
2300 #if defined(CONFIG_USER_ONLY)
2301 static GenOpFunc
*gen_op_lwarx
[] = {
2303 &gen_op_lwarx_le_raw
,
2304 &gen_op_lwarx_64_raw
,
2305 &gen_op_lwarx_le_64_raw
,
2307 static GenOpFunc
*gen_op_stwcx
[] = {
2309 &gen_op_stwcx_le_raw
,
2310 &gen_op_stwcx_64_raw
,
2311 &gen_op_stwcx_le_64_raw
,
2314 static GenOpFunc
*gen_op_lwarx
[] = {
2316 &gen_op_lwarx_le_user
,
2317 &gen_op_lwarx_kernel
,
2318 &gen_op_lwarx_le_kernel
,
2319 &gen_op_lwarx_64_user
,
2320 &gen_op_lwarx_le_64_user
,
2321 &gen_op_lwarx_64_kernel
,
2322 &gen_op_lwarx_le_64_kernel
,
2324 static GenOpFunc
*gen_op_stwcx
[] = {
2326 &gen_op_stwcx_le_user
,
2327 &gen_op_stwcx_kernel
,
2328 &gen_op_stwcx_le_kernel
,
2329 &gen_op_stwcx_64_user
,
2330 &gen_op_stwcx_le_64_user
,
2331 &gen_op_stwcx_64_kernel
,
2332 &gen_op_stwcx_le_64_kernel
,
2336 #if defined(CONFIG_USER_ONLY)
2337 static GenOpFunc
*gen_op_lwarx
[] = {
2339 &gen_op_lwarx_le_raw
,
2341 static GenOpFunc
*gen_op_stwcx
[] = {
2343 &gen_op_stwcx_le_raw
,
2346 static GenOpFunc
*gen_op_lwarx
[] = {
2348 &gen_op_lwarx_le_user
,
2349 &gen_op_lwarx_kernel
,
2350 &gen_op_lwarx_le_kernel
,
2352 static GenOpFunc
*gen_op_stwcx
[] = {
2354 &gen_op_stwcx_le_user
,
2355 &gen_op_stwcx_kernel
,
2356 &gen_op_stwcx_le_kernel
,
2362 GEN_HANDLER(lwarx
, 0x1F, 0x14, 0x00, 0x00000001, PPC_RES
)
2364 gen_addr_reg_index(ctx
);
2366 gen_op_store_T1_gpr(rD(ctx
->opcode
));
2370 GEN_HANDLER(stwcx_
, 0x1F, 0x16, 0x04, 0x00000000, PPC_RES
)
2372 gen_addr_reg_index(ctx
);
2373 gen_op_load_gpr_T1(rS(ctx
->opcode
));
2377 #if defined(TARGET_PPC64)
2378 #define op_ldarx() (*gen_op_ldarx[ctx->mem_idx])()
2379 #define op_stdcx() (*gen_op_stdcx[ctx->mem_idx])()
2380 #if defined(CONFIG_USER_ONLY)
2381 static GenOpFunc
*gen_op_ldarx
[] = {
2383 &gen_op_ldarx_le_raw
,
2384 &gen_op_ldarx_64_raw
,
2385 &gen_op_ldarx_le_64_raw
,
2387 static GenOpFunc
*gen_op_stdcx
[] = {
2389 &gen_op_stdcx_le_raw
,
2390 &gen_op_stdcx_64_raw
,
2391 &gen_op_stdcx_le_64_raw
,
2394 static GenOpFunc
*gen_op_ldarx
[] = {
2396 &gen_op_ldarx_le_user
,
2397 &gen_op_ldarx_kernel
,
2398 &gen_op_ldarx_le_kernel
,
2399 &gen_op_ldarx_64_user
,
2400 &gen_op_ldarx_le_64_user
,
2401 &gen_op_ldarx_64_kernel
,
2402 &gen_op_ldarx_le_64_kernel
,
2404 static GenOpFunc
*gen_op_stdcx
[] = {
2406 &gen_op_stdcx_le_user
,
2407 &gen_op_stdcx_kernel
,
2408 &gen_op_stdcx_le_kernel
,
2409 &gen_op_stdcx_64_user
,
2410 &gen_op_stdcx_le_64_user
,
2411 &gen_op_stdcx_64_kernel
,
2412 &gen_op_stdcx_le_64_kernel
,
2417 GEN_HANDLER(ldarx
, 0x1F, 0x14, 0x02, 0x00000001, PPC_RES
)
2419 gen_addr_reg_index(ctx
);
2421 gen_op_store_T1_gpr(rD(ctx
->opcode
));
2425 GEN_HANDLER(stdcx_
, 0x1F, 0x16, 0x06, 0x00000000, PPC_RES
)
2427 gen_addr_reg_index(ctx
);
2428 gen_op_load_gpr_T1(rS(ctx
->opcode
));
2431 #endif /* defined(TARGET_PPC64) */
2434 GEN_HANDLER(sync
, 0x1F, 0x16, 0x12, 0x03FF0801, PPC_MEM_SYNC
)
2438 /*** Floating-point load ***/
2439 #define GEN_LDF(width, opc) \
2440 GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
2442 if (unlikely(!ctx->fpu_enabled)) { \
2443 RET_EXCP(ctx, EXCP_NO_FP, 0); \
2446 gen_addr_imm_index(ctx, 0); \
2447 op_ldst(l##width); \
2448 gen_op_store_FT0_fpr(rD(ctx->opcode)); \
2451 #define GEN_LDUF(width, opc) \
2452 GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
2454 if (unlikely(!ctx->fpu_enabled)) { \
2455 RET_EXCP(ctx, EXCP_NO_FP, 0); \
2458 if (unlikely(rA(ctx->opcode) == 0)) { \
2462 gen_addr_imm_index(ctx, 0); \
2463 op_ldst(l##width); \
2464 gen_op_store_FT0_fpr(rD(ctx->opcode)); \
2465 gen_op_store_T0_gpr(rA(ctx->opcode)); \
2468 #define GEN_LDUXF(width, opc) \
2469 GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \
2471 if (unlikely(!ctx->fpu_enabled)) { \
2472 RET_EXCP(ctx, EXCP_NO_FP, 0); \
2475 if (unlikely(rA(ctx->opcode) == 0)) { \
2479 gen_addr_reg_index(ctx); \
2480 op_ldst(l##width); \
2481 gen_op_store_FT0_fpr(rD(ctx->opcode)); \
2482 gen_op_store_T0_gpr(rA(ctx->opcode)); \
2485 #define GEN_LDXF(width, opc2, opc3) \
2486 GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_FLOAT) \
2488 if (unlikely(!ctx->fpu_enabled)) { \
2489 RET_EXCP(ctx, EXCP_NO_FP, 0); \
2492 gen_addr_reg_index(ctx); \
2493 op_ldst(l##width); \
2494 gen_op_store_FT0_fpr(rD(ctx->opcode)); \
2497 #define GEN_LDFS(width, op) \
2498 OP_LD_TABLE(width); \
2499 GEN_LDF(width, op | 0x20); \
2500 GEN_LDUF(width, op | 0x21); \
2501 GEN_LDUXF(width, op | 0x01); \
2502 GEN_LDXF(width, 0x17, op | 0x00)
2504 /* lfd lfdu lfdux lfdx */
2506 /* lfs lfsu lfsux lfsx */
2509 /*** Floating-point store ***/
2510 #define GEN_STF(width, opc) \
2511 GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
2513 if (unlikely(!ctx->fpu_enabled)) { \
2514 RET_EXCP(ctx, EXCP_NO_FP, 0); \
2517 gen_addr_imm_index(ctx, 0); \
2518 gen_op_load_fpr_FT0(rS(ctx->opcode)); \
2519 op_ldst(st##width); \
2522 #define GEN_STUF(width, opc) \
2523 GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
2525 if (unlikely(!ctx->fpu_enabled)) { \
2526 RET_EXCP(ctx, EXCP_NO_FP, 0); \
2529 if (unlikely(rA(ctx->opcode) == 0)) { \
2533 gen_addr_imm_index(ctx, 0); \
2534 gen_op_load_fpr_FT0(rS(ctx->opcode)); \
2535 op_ldst(st##width); \
2536 gen_op_store_T0_gpr(rA(ctx->opcode)); \
2539 #define GEN_STUXF(width, opc) \
2540 GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \
2542 if (unlikely(!ctx->fpu_enabled)) { \
2543 RET_EXCP(ctx, EXCP_NO_FP, 0); \
2546 if (unlikely(rA(ctx->opcode) == 0)) { \
2550 gen_addr_reg_index(ctx); \
2551 gen_op_load_fpr_FT0(rS(ctx->opcode)); \
2552 op_ldst(st##width); \
2553 gen_op_store_T0_gpr(rA(ctx->opcode)); \
2556 #define GEN_STXF(width, opc2, opc3) \
2557 GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_FLOAT) \
2559 if (unlikely(!ctx->fpu_enabled)) { \
2560 RET_EXCP(ctx, EXCP_NO_FP, 0); \
2563 gen_addr_reg_index(ctx); \
2564 gen_op_load_fpr_FT0(rS(ctx->opcode)); \
2565 op_ldst(st##width); \
2568 #define GEN_STFS(width, op) \
2569 OP_ST_TABLE(width); \
2570 GEN_STF(width, op | 0x20); \
2571 GEN_STUF(width, op | 0x21); \
2572 GEN_STUXF(width, op | 0x01); \
2573 GEN_STXF(width, 0x17, op | 0x00)
2575 /* stfd stfdu stfdux stfdx */
2577 /* stfs stfsu stfsux stfsx */
2582 GEN_HANDLER(stfiwx
, 0x1F, 0x17, 0x1E, 0x00000001, PPC_FLOAT
)
2584 if (unlikely(!ctx
->fpu_enabled
)) {
2585 RET_EXCP(ctx
, EXCP_NO_FP
, 0);
2588 gen_addr_reg_index(ctx
);
2589 /* XXX: TODO: memcpy low order 32 bits of FRP(rs) into memory */
2595 static inline void gen_goto_tb(DisasContext
*ctx
, int n
, target_ulong dest
)
2597 TranslationBlock
*tb
;
2599 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
)) {
2601 gen_op_goto_tb0(TBPARAM(tb
));
2603 gen_op_goto_tb1(TBPARAM(tb
));
2605 #if defined(TARGET_PPC64)
2611 gen_op_set_T0((long)tb
+ n
);
2612 if (ctx
->singlestep_enabled
)
2617 #if defined(TARGET_PPC64)
2624 if (ctx
->singlestep_enabled
)
2631 GEN_HANDLER(b
, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW
)
2633 target_ulong li
, target
;
2635 /* sign extend LI */
2636 #if defined(TARGET_PPC64)
2638 li
= ((int64_t)LI(ctx
->opcode
) << 38) >> 38;
2641 li
= ((int32_t)LI(ctx
->opcode
) << 6) >> 6;
2642 if (likely(AA(ctx
->opcode
) == 0))
2643 target
= ctx
->nip
+ li
- 4;
2646 if (LK(ctx
->opcode
)) {
2647 #if defined(TARGET_PPC64)
2649 gen_op_setlr_64(ctx
->nip
>> 32, ctx
->nip
);
2652 gen_op_setlr(ctx
->nip
);
2654 gen_goto_tb(ctx
, 0, target
);
2655 ctx
->exception
= EXCP_BRANCH
;
2662 static inline void gen_bcond(DisasContext
*ctx
, int type
)
2664 target_ulong target
= 0;
2666 uint32_t bo
= BO(ctx
->opcode
);
2667 uint32_t bi
= BI(ctx
->opcode
);
2670 if ((bo
& 0x4) == 0)
2674 li
= (target_long
)((int16_t)(BD(ctx
->opcode
)));
2675 if (likely(AA(ctx
->opcode
) == 0)) {
2676 target
= ctx
->nip
+ li
- 4;
2682 gen_op_movl_T1_ctr();
2686 gen_op_movl_T1_lr();
2689 if (LK(ctx
->opcode
)) {
2690 #if defined(TARGET_PPC64)
2692 gen_op_setlr_64(ctx
->nip
>> 32, ctx
->nip
);
2695 gen_op_setlr(ctx
->nip
);
2698 /* No CR condition */
2701 #if defined(TARGET_PPC64)
2703 gen_op_test_ctr_64();
2709 #if defined(TARGET_PPC64)
2711 gen_op_test_ctrz_64();
2719 if (type
== BCOND_IM
) {
2720 gen_goto_tb(ctx
, 0, target
);
2722 #if defined(TARGET_PPC64)
2733 mask
= 1 << (3 - (bi
& 0x03));
2734 gen_op_load_crf_T0(bi
>> 2);
2738 #if defined(TARGET_PPC64)
2740 gen_op_test_ctr_true_64(mask
);
2743 gen_op_test_ctr_true(mask
);
2746 #if defined(TARGET_PPC64)
2748 gen_op_test_ctrz_true_64(mask
);
2751 gen_op_test_ctrz_true(mask
);
2756 gen_op_test_true(mask
);
2762 #if defined(TARGET_PPC64)
2764 gen_op_test_ctr_false_64(mask
);
2767 gen_op_test_ctr_false(mask
);
2770 #if defined(TARGET_PPC64)
2772 gen_op_test_ctrz_false_64(mask
);
2775 gen_op_test_ctrz_false(mask
);
2780 gen_op_test_false(mask
);
2785 if (type
== BCOND_IM
) {
2786 int l1
= gen_new_label();
2788 gen_goto_tb(ctx
, 0, target
);
2790 gen_goto_tb(ctx
, 1, ctx
->nip
);
2792 #if defined(TARGET_PPC64)
2794 gen_op_btest_T1_64(ctx
->nip
>> 32, ctx
->nip
);
2797 gen_op_btest_T1(ctx
->nip
);
2801 if (ctx
->singlestep_enabled
)
2804 ctx
->exception
= EXCP_BRANCH
;
2807 GEN_HANDLER(bc
, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW
)
2809 gen_bcond(ctx
, BCOND_IM
);
2812 GEN_HANDLER(bcctr
, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW
)
2814 gen_bcond(ctx
, BCOND_CTR
);
2817 GEN_HANDLER(bclr
, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW
)
2819 gen_bcond(ctx
, BCOND_LR
);
2822 /*** Condition register logical ***/
2823 #define GEN_CRLOGIC(op, opc) \
2824 GEN_HANDLER(cr##op, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER) \
2826 gen_op_load_crf_T0(crbA(ctx->opcode) >> 2); \
2827 gen_op_getbit_T0(3 - (crbA(ctx->opcode) & 0x03)); \
2828 gen_op_load_crf_T1(crbB(ctx->opcode) >> 2); \
2829 gen_op_getbit_T1(3 - (crbB(ctx->opcode) & 0x03)); \
2831 gen_op_load_crf_T1(crbD(ctx->opcode) >> 2); \
2832 gen_op_setcrfbit(~(1 << (3 - (crbD(ctx->opcode) & 0x03))), \
2833 3 - (crbD(ctx->opcode) & 0x03)); \
2834 gen_op_store_T1_crf(crbD(ctx->opcode) >> 2); \
2838 GEN_CRLOGIC(and, 0x08);
2840 GEN_CRLOGIC(andc
, 0x04);
2842 GEN_CRLOGIC(eqv
, 0x09);
2844 GEN_CRLOGIC(nand
, 0x07);
2846 GEN_CRLOGIC(nor
, 0x01);
2848 GEN_CRLOGIC(or, 0x0E);
2850 GEN_CRLOGIC(orc
, 0x0D);
2852 GEN_CRLOGIC(xor, 0x06);
2854 GEN_HANDLER(mcrf
, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER
)
2856 gen_op_load_crf_T0(crfS(ctx
->opcode
));
2857 gen_op_store_T0_crf(crfD(ctx
->opcode
));
2860 /*** System linkage ***/
2861 /* rfi (supervisor only) */
2862 GEN_HANDLER(rfi
, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW
)
2864 #if defined(CONFIG_USER_ONLY)
2867 /* Restore CPU state */
2868 if (unlikely(!ctx
->supervisor
)) {
2877 #if defined(TARGET_PPC64)
2878 GEN_HANDLER(rfid
, 0x13, 0x12, 0x00, 0x03FF8001, PPC_FLOW
)
2880 #if defined(CONFIG_USER_ONLY)
2883 /* Restore CPU state */
2884 if (unlikely(!ctx
->supervisor
)) {
2895 GEN_HANDLER(sc
, 0x11, 0xFF, 0xFF, 0x03FFFFFD, PPC_FLOW
)
2897 #if defined(CONFIG_USER_ONLY)
2898 RET_EXCP(ctx
, EXCP_SYSCALL_USER
, 0);
2900 RET_EXCP(ctx
, EXCP_SYSCALL
, 0);
2906 GEN_HANDLER(tw
, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW
)
2908 gen_op_load_gpr_T0(rA(ctx
->opcode
));
2909 gen_op_load_gpr_T1(rB(ctx
->opcode
));
2910 /* Update the nip since this might generate a trap exception */
2911 gen_update_nip(ctx
, ctx
->nip
);
2912 gen_op_tw(TO(ctx
->opcode
));
2916 GEN_HANDLER(twi
, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW
)
2918 gen_op_load_gpr_T0(rA(ctx
->opcode
));
2919 gen_set_T1(SIMM(ctx
->opcode
));
2920 /* Update the nip since this might generate a trap exception */
2921 gen_update_nip(ctx
, ctx
->nip
);
2922 gen_op_tw(TO(ctx
->opcode
));
2925 #if defined(TARGET_PPC64)
2927 GEN_HANDLER(td
, 0x1F, 0x04, 0x02, 0x00000001, PPC_64B
)
2929 gen_op_load_gpr_T0(rA(ctx
->opcode
));
2930 gen_op_load_gpr_T1(rB(ctx
->opcode
));
2931 /* Update the nip since this might generate a trap exception */
2932 gen_update_nip(ctx
, ctx
->nip
);
2933 gen_op_td(TO(ctx
->opcode
));
2937 GEN_HANDLER(tdi
, 0x02, 0xFF, 0xFF, 0x00000000, PPC_64B
)
2939 gen_op_load_gpr_T0(rA(ctx
->opcode
));
2940 gen_set_T1(SIMM(ctx
->opcode
));
2941 /* Update the nip since this might generate a trap exception */
2942 gen_update_nip(ctx
, ctx
->nip
);
2943 gen_op_td(TO(ctx
->opcode
));
2947 /*** Processor control ***/
2949 GEN_HANDLER(mcrxr
, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC
)
2951 gen_op_load_xer_cr();
2952 gen_op_store_T0_crf(crfD(ctx
->opcode
));
2953 gen_op_clear_xer_ov();
2954 gen_op_clear_xer_ca();
2958 GEN_HANDLER(mfcr
, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC
)
2962 if (likely(ctx
->opcode
& 0x00100000)) {
2963 crm
= CRM(ctx
->opcode
);
2964 if (likely((crm
^ (crm
- 1)) == 0)) {
2966 gen_op_load_cro(7 - crn
);
2971 gen_op_store_T0_gpr(rD(ctx
->opcode
));
2975 GEN_HANDLER(mfmsr
, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC
)
2977 #if defined(CONFIG_USER_ONLY)
2980 if (unlikely(!ctx
->supervisor
)) {
2985 gen_op_store_T0_gpr(rD(ctx
->opcode
));
2990 #define SPR_NOACCESS ((void *)(-1))
2992 static void spr_noaccess (void *opaque
, int sprn
)
2994 sprn
= ((sprn
>> 5) & 0x1F) | ((sprn
& 0x1F) << 5);
2995 printf("ERROR: try to access SPR %d !\n", sprn
);
2997 #define SPR_NOACCESS (&spr_noaccess)
3001 static inline void gen_op_mfspr (DisasContext
*ctx
)
3003 void (*read_cb
)(void *opaque
, int sprn
);
3004 uint32_t sprn
= SPR(ctx
->opcode
);
3006 #if !defined(CONFIG_USER_ONLY)
3007 if (ctx
->supervisor
)
3008 read_cb
= ctx
->spr_cb
[sprn
].oea_read
;
3011 read_cb
= ctx
->spr_cb
[sprn
].uea_read
;
3012 if (likely(read_cb
!= NULL
)) {
3013 if (likely(read_cb
!= SPR_NOACCESS
)) {
3014 (*read_cb
)(ctx
, sprn
);
3015 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3017 /* Privilege exception */
3019 fprintf(logfile
, "Trying to read priviledged spr %d %03x\n",
3022 printf("Trying to read priviledged spr %d %03x\n", sprn
, sprn
);
3028 fprintf(logfile
, "Trying to read invalid spr %d %03x\n",
3031 printf("Trying to read invalid spr %d %03x\n", sprn
, sprn
);
3032 RET_EXCP(ctx
, EXCP_PROGRAM
, EXCP_INVAL
| EXCP_INVAL_SPR
);
3036 GEN_HANDLER(mfspr
, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC
)
3042 GEN_HANDLER(mftb
, 0x1F, 0x13, 0x0B, 0x00000001, PPC_TB
)
3048 GEN_HANDLER(mtcrf
, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC
)
3052 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3053 crm
= CRM(ctx
->opcode
);
3054 if (likely((ctx
->opcode
& 0x00100000) || (crm
^ (crm
- 1)) == 0)) {
3056 gen_op_srli_T0(crn
* 4);
3057 gen_op_andi_T0(0xF);
3058 gen_op_store_cro(7 - crn
);
3060 gen_op_store_cr(crm
);
3065 #if defined(TARGET_PPC64)
3066 GEN_HANDLER(mtmsrd
, 0x1F, 0x12, 0x05, 0x001FF801, PPC_MISC
)
3068 #if defined(CONFIG_USER_ONLY)
3071 if (unlikely(!ctx
->supervisor
)) {
3075 gen_update_nip(ctx
, ctx
->nip
);
3076 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3078 /* Must stop the translation as machine state (may have) changed */
3084 GEN_HANDLER(mtmsr
, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC
)
3086 #if defined(CONFIG_USER_ONLY)
3089 if (unlikely(!ctx
->supervisor
)) {
3093 gen_update_nip(ctx
, ctx
->nip
);
3094 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3095 #if defined(TARGET_PPC64)
3097 gen_op_store_msr_32();
3101 /* Must stop the translation as machine state (may have) changed */
3107 GEN_HANDLER(mtspr
, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC
)
3109 void (*write_cb
)(void *opaque
, int sprn
);
3110 uint32_t sprn
= SPR(ctx
->opcode
);
3112 #if !defined(CONFIG_USER_ONLY)
3113 if (ctx
->supervisor
)
3114 write_cb
= ctx
->spr_cb
[sprn
].oea_write
;
3117 write_cb
= ctx
->spr_cb
[sprn
].uea_write
;
3118 if (likely(write_cb
!= NULL
)) {
3119 if (likely(write_cb
!= SPR_NOACCESS
)) {
3120 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3121 (*write_cb
)(ctx
, sprn
);
3123 /* Privilege exception */
3125 fprintf(logfile
, "Trying to write priviledged spr %d %03x\n",
3128 printf("Trying to write priviledged spr %d %03x\n", sprn
, sprn
);
3134 fprintf(logfile
, "Trying to write invalid spr %d %03x\n",
3137 printf("Trying to write invalid spr %d %03x\n", sprn
, sprn
);
3138 RET_EXCP(ctx
, EXCP_PROGRAM
, EXCP_INVAL
| EXCP_INVAL_SPR
);
3142 /*** Cache management ***/
3143 /* For now, all those will be implemented as nop:
3144 * this is valid, regarding the PowerPC specs...
3145 * We just have to flush tb while invalidating instruction cache lines...
3148 GEN_HANDLER(dcbf
, 0x1F, 0x16, 0x02, 0x03E00001, PPC_CACHE
)
3150 gen_addr_reg_index(ctx
);
3154 /* dcbi (Supervisor only) */
3155 GEN_HANDLER(dcbi
, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE
)
3157 #if defined(CONFIG_USER_ONLY)
3160 if (unlikely(!ctx
->supervisor
)) {
3164 gen_addr_reg_index(ctx
);
3165 /* XXX: specification says this should be treated as a store by the MMU */
3172 GEN_HANDLER(dcbst
, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE
)
3174 /* XXX: specification say this is treated as a load by the MMU */
3175 gen_addr_reg_index(ctx
);
3180 GEN_HANDLER(dcbt
, 0x1F, 0x16, 0x08, 0x03E00001, PPC_CACHE
)
3182 /* XXX: specification say this is treated as a load by the MMU
3183 * but does not generate any exception
3188 GEN_HANDLER(dcbtst
, 0x1F, 0x16, 0x07, 0x03E00001, PPC_CACHE
)
3190 /* XXX: specification say this is treated as a load by the MMU
3191 * but does not generate any exception
3196 #define op_dcbz() (*gen_op_dcbz[ctx->mem_idx])()
3197 #if defined(TARGET_PPC64)
3198 #if defined(CONFIG_USER_ONLY)
3199 static GenOpFunc
*gen_op_dcbz
[] = {
3202 &gen_op_dcbz_64_raw
,
3203 &gen_op_dcbz_64_raw
,
3206 static GenOpFunc
*gen_op_dcbz
[] = {
3209 &gen_op_dcbz_kernel
,
3210 &gen_op_dcbz_kernel
,
3211 &gen_op_dcbz_64_user
,
3212 &gen_op_dcbz_64_user
,
3213 &gen_op_dcbz_64_kernel
,
3214 &gen_op_dcbz_64_kernel
,
3218 #if defined(CONFIG_USER_ONLY)
3219 static GenOpFunc
*gen_op_dcbz
[] = {
3224 static GenOpFunc
*gen_op_dcbz
[] = {
3227 &gen_op_dcbz_kernel
,
3228 &gen_op_dcbz_kernel
,
3233 GEN_HANDLER(dcbz
, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE
)
3235 gen_addr_reg_index(ctx
);
3237 gen_op_check_reservation();
3241 #define op_icbi() (*gen_op_icbi[ctx->mem_idx])()
3242 #if defined(TARGET_PPC64)
3243 #if defined(CONFIG_USER_ONLY)
3244 static GenOpFunc
*gen_op_icbi
[] = {
3247 &gen_op_icbi_64_raw
,
3248 &gen_op_icbi_64_raw
,
3251 static GenOpFunc
*gen_op_icbi
[] = {
3254 &gen_op_icbi_kernel
,
3255 &gen_op_icbi_kernel
,
3256 &gen_op_icbi_64_user
,
3257 &gen_op_icbi_64_user
,
3258 &gen_op_icbi_64_kernel
,
3259 &gen_op_icbi_64_kernel
,
3263 #if defined(CONFIG_USER_ONLY)
3264 static GenOpFunc
*gen_op_icbi
[] = {
3269 static GenOpFunc
*gen_op_icbi
[] = {
3272 &gen_op_icbi_kernel
,
3273 &gen_op_icbi_kernel
,
3277 GEN_HANDLER(icbi
, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE
)
3279 /* NIP cannot be restored if the memory exception comes from an helper */
3280 gen_update_nip(ctx
, ctx
->nip
- 4);
3281 gen_addr_reg_index(ctx
);
3288 GEN_HANDLER(dcba
, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_OPT
)
3292 /*** Segment register manipulation ***/
3293 /* Supervisor only: */
3295 GEN_HANDLER(mfsr
, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT
)
3297 #if defined(CONFIG_USER_ONLY)
3300 if (unlikely(!ctx
->supervisor
)) {
3304 gen_op_set_T1(SR(ctx
->opcode
));
3306 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3311 GEN_HANDLER(mfsrin
, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT
)
3313 #if defined(CONFIG_USER_ONLY)
3316 if (unlikely(!ctx
->supervisor
)) {
3320 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3323 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3328 GEN_HANDLER(mtsr
, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT
)
3330 #if defined(CONFIG_USER_ONLY)
3333 if (unlikely(!ctx
->supervisor
)) {
3337 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3338 gen_op_set_T1(SR(ctx
->opcode
));
3345 GEN_HANDLER(mtsrin
, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT
)
3347 #if defined(CONFIG_USER_ONLY)
3350 if (unlikely(!ctx
->supervisor
)) {
3354 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3355 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3362 /*** Lookaside buffer management ***/
3363 /* Optional & supervisor only: */
3365 GEN_HANDLER(tlbia
, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA
)
3367 #if defined(CONFIG_USER_ONLY)
3370 if (unlikely(!ctx
->supervisor
)) {
3372 fprintf(logfile
, "%s: ! supervisor\n", __func__
);
3382 GEN_HANDLER(tlbie
, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE
)
3384 #if defined(CONFIG_USER_ONLY)
3387 if (unlikely(!ctx
->supervisor
)) {
3391 gen_op_load_gpr_T0(rB(ctx
->opcode
));
3392 #if defined(TARGET_PPC64)
3403 GEN_HANDLER(tlbsync
, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC
)
3405 #if defined(CONFIG_USER_ONLY)
3408 if (unlikely(!ctx
->supervisor
)) {
3412 /* This has no effect: it should ensure that all previous
3413 * tlbie have completed
3419 #if defined(TARGET_PPC64)
3421 GEN_HANDLER(slbia
, 0x1F, 0x12, 0x0F, 0x03FFFC01, PPC_SLBI
)
3423 #if defined(CONFIG_USER_ONLY)
3426 if (unlikely(!ctx
->supervisor
)) {
3428 fprintf(logfile
, "%s: ! supervisor\n", __func__
);
3438 GEN_HANDLER(slbie
, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI
)
3440 #if defined(CONFIG_USER_ONLY)
3443 if (unlikely(!ctx
->supervisor
)) {
3447 gen_op_load_gpr_T0(rB(ctx
->opcode
));
3454 /*** External control ***/
3456 #define op_eciwx() (*gen_op_eciwx[ctx->mem_idx])()
3457 #define op_ecowx() (*gen_op_ecowx[ctx->mem_idx])()
3458 #if defined(TARGET_PPC64)
3459 #if defined(CONFIG_USER_ONLY)
3460 static GenOpFunc
*gen_op_eciwx
[] = {
3462 &gen_op_eciwx_le_raw
,
3463 &gen_op_eciwx_64_raw
,
3464 &gen_op_eciwx_le_64_raw
,
3466 static GenOpFunc
*gen_op_ecowx
[] = {
3468 &gen_op_ecowx_le_raw
,
3469 &gen_op_ecowx_64_raw
,
3470 &gen_op_ecowx_le_64_raw
,
3473 static GenOpFunc
*gen_op_eciwx
[] = {
3475 &gen_op_eciwx_le_user
,
3476 &gen_op_eciwx_kernel
,
3477 &gen_op_eciwx_le_kernel
,
3478 &gen_op_eciwx_64_user
,
3479 &gen_op_eciwx_le_64_user
,
3480 &gen_op_eciwx_64_kernel
,
3481 &gen_op_eciwx_le_64_kernel
,
3483 static GenOpFunc
*gen_op_ecowx
[] = {
3485 &gen_op_ecowx_le_user
,
3486 &gen_op_ecowx_kernel
,
3487 &gen_op_ecowx_le_kernel
,
3488 &gen_op_ecowx_64_user
,
3489 &gen_op_ecowx_le_64_user
,
3490 &gen_op_ecowx_64_kernel
,
3491 &gen_op_ecowx_le_64_kernel
,
3495 #if defined(CONFIG_USER_ONLY)
3496 static GenOpFunc
*gen_op_eciwx
[] = {
3498 &gen_op_eciwx_le_raw
,
3500 static GenOpFunc
*gen_op_ecowx
[] = {
3502 &gen_op_ecowx_le_raw
,
3505 static GenOpFunc
*gen_op_eciwx
[] = {
3507 &gen_op_eciwx_le_user
,
3508 &gen_op_eciwx_kernel
,
3509 &gen_op_eciwx_le_kernel
,
3511 static GenOpFunc
*gen_op_ecowx
[] = {
3513 &gen_op_ecowx_le_user
,
3514 &gen_op_ecowx_kernel
,
3515 &gen_op_ecowx_le_kernel
,
3521 GEN_HANDLER(eciwx
, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN
)
3523 /* Should check EAR[E] & alignment ! */
3524 gen_addr_reg_index(ctx
);
3526 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3530 GEN_HANDLER(ecowx
, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN
)
3532 /* Should check EAR[E] & alignment ! */
3533 gen_addr_reg_index(ctx
);
3534 gen_op_load_gpr_T1(rS(ctx
->opcode
));
3538 /* PowerPC 601 specific instructions */
3540 GEN_HANDLER(abs
, 0x1F, 0x08, 0x0B, 0x0000F800, PPC_POWER_BR
)
3542 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3544 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3545 if (unlikely(Rc(ctx
->opcode
) != 0))
3550 GEN_HANDLER(abso
, 0x1F, 0x08, 0x1B, 0x0000F800, PPC_POWER_BR
)
3552 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3553 gen_op_POWER_abso();
3554 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3555 if (unlikely(Rc(ctx
->opcode
) != 0))
3560 GEN_HANDLER(clcs
, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR
) /* 601 ? */
3562 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3563 gen_op_POWER_clcs();
3564 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3568 GEN_HANDLER(div
, 0x1F, 0x0B, 0x0A, 0x00000000, PPC_POWER_BR
)
3570 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3571 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3573 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3574 if (unlikely(Rc(ctx
->opcode
) != 0))
3579 GEN_HANDLER(divo
, 0x1F, 0x0B, 0x1A, 0x00000000, PPC_POWER_BR
)
3581 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3582 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3583 gen_op_POWER_divo();
3584 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3585 if (unlikely(Rc(ctx
->opcode
) != 0))
3590 GEN_HANDLER(divs
, 0x1F, 0x0B, 0x0B, 0x00000000, PPC_POWER_BR
)
3592 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3593 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3594 gen_op_POWER_divs();
3595 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3596 if (unlikely(Rc(ctx
->opcode
) != 0))
3600 /* divso - divso. */
3601 GEN_HANDLER(divso
, 0x1F, 0x0B, 0x1B, 0x00000000, PPC_POWER_BR
)
3603 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3604 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3605 gen_op_POWER_divso();
3606 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3607 if (unlikely(Rc(ctx
->opcode
) != 0))
3612 GEN_HANDLER(doz
, 0x1F, 0x08, 0x08, 0x00000000, PPC_POWER_BR
)
3614 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3615 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3617 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3618 if (unlikely(Rc(ctx
->opcode
) != 0))
3623 GEN_HANDLER(dozo
, 0x1F, 0x08, 0x18, 0x00000000, PPC_POWER_BR
)
3625 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3626 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3627 gen_op_POWER_dozo();
3628 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3629 if (unlikely(Rc(ctx
->opcode
) != 0))
3634 GEN_HANDLER(dozi
, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR
)
3636 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3637 gen_op_set_T1(SIMM(ctx
->opcode
));
3639 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3642 /* As lscbx load from memory byte after byte, it's always endian safe */
3643 #define op_POWER_lscbx(start, ra, rb) \
3644 (*gen_op_POWER_lscbx[ctx->mem_idx])(start, ra, rb)
3645 #if defined(CONFIG_USER_ONLY)
3646 static GenOpFunc3
*gen_op_POWER_lscbx
[] = {
3647 &gen_op_POWER_lscbx_raw
,
3648 &gen_op_POWER_lscbx_raw
,
3651 static GenOpFunc3
*gen_op_POWER_lscbx
[] = {
3652 &gen_op_POWER_lscbx_user
,
3653 &gen_op_POWER_lscbx_user
,
3654 &gen_op_POWER_lscbx_kernel
,
3655 &gen_op_POWER_lscbx_kernel
,
3659 /* lscbx - lscbx. */
3660 GEN_HANDLER(lscbx
, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR
)
3662 int ra
= rA(ctx
->opcode
);
3663 int rb
= rB(ctx
->opcode
);
3665 gen_addr_reg_index(ctx
);
3669 /* NIP cannot be restored if the memory exception comes from an helper */
3670 gen_update_nip(ctx
, ctx
->nip
- 4);
3671 gen_op_load_xer_bc();
3672 gen_op_load_xer_cmp();
3673 op_POWER_lscbx(rD(ctx
->opcode
), ra
, rb
);
3674 gen_op_store_xer_bc();
3675 if (unlikely(Rc(ctx
->opcode
) != 0))
3679 /* maskg - maskg. */
3680 GEN_HANDLER(maskg
, 0x1F, 0x1D, 0x00, 0x00000000, PPC_POWER_BR
)
3682 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3683 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3684 gen_op_POWER_maskg();
3685 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3686 if (unlikely(Rc(ctx
->opcode
) != 0))
3690 /* maskir - maskir. */
3691 GEN_HANDLER(maskir
, 0x1F, 0x1D, 0x10, 0x00000000, PPC_POWER_BR
)
3693 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3694 gen_op_load_gpr_T1(rS(ctx
->opcode
));
3695 gen_op_load_gpr_T2(rB(ctx
->opcode
));
3696 gen_op_POWER_maskir();
3697 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3698 if (unlikely(Rc(ctx
->opcode
) != 0))
3703 GEN_HANDLER(mul
, 0x1F, 0x0B, 0x03, 0x00000000, PPC_POWER_BR
)
3705 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3706 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3708 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3709 if (unlikely(Rc(ctx
->opcode
) != 0))
3714 GEN_HANDLER(mulo
, 0x1F, 0x0B, 0x13, 0x00000000, PPC_POWER_BR
)
3716 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3717 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3718 gen_op_POWER_mulo();
3719 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3720 if (unlikely(Rc(ctx
->opcode
) != 0))
3725 GEN_HANDLER(nabs
, 0x1F, 0x08, 0x0F, 0x00000000, PPC_POWER_BR
)
3727 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3728 gen_op_POWER_nabs();
3729 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3730 if (unlikely(Rc(ctx
->opcode
) != 0))
3734 /* nabso - nabso. */
3735 GEN_HANDLER(nabso
, 0x1F, 0x08, 0x1F, 0x00000000, PPC_POWER_BR
)
3737 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3738 gen_op_POWER_nabso();
3739 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3740 if (unlikely(Rc(ctx
->opcode
) != 0))
3745 GEN_HANDLER(rlmi
, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR
)
3749 mb
= MB(ctx
->opcode
);
3750 me
= ME(ctx
->opcode
);
3751 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3752 gen_op_load_gpr_T1(rA(ctx
->opcode
));
3753 gen_op_load_gpr_T2(rB(ctx
->opcode
));
3754 gen_op_POWER_rlmi(MASK(mb
, me
), ~MASK(mb
, me
));
3755 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3756 if (unlikely(Rc(ctx
->opcode
) != 0))
3761 GEN_HANDLER(rrib
, 0x1F, 0x19, 0x10, 0x00000000, PPC_POWER_BR
)
3763 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3764 gen_op_load_gpr_T1(rA(ctx
->opcode
));
3765 gen_op_load_gpr_T2(rB(ctx
->opcode
));
3766 gen_op_POWER_rrib();
3767 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3768 if (unlikely(Rc(ctx
->opcode
) != 0))
3773 GEN_HANDLER(sle
, 0x1F, 0x19, 0x04, 0x00000000, PPC_POWER_BR
)
3775 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3776 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3778 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3779 if (unlikely(Rc(ctx
->opcode
) != 0))
3784 GEN_HANDLER(sleq
, 0x1F, 0x19, 0x06, 0x00000000, PPC_POWER_BR
)
3786 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3787 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3788 gen_op_POWER_sleq();
3789 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3790 if (unlikely(Rc(ctx
->opcode
) != 0))
3795 GEN_HANDLER(sliq
, 0x1F, 0x18, 0x05, 0x00000000, PPC_POWER_BR
)
3797 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3798 gen_op_set_T1(SH(ctx
->opcode
));
3800 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3801 if (unlikely(Rc(ctx
->opcode
) != 0))
3805 /* slliq - slliq. */
3806 GEN_HANDLER(slliq
, 0x1F, 0x18, 0x07, 0x00000000, PPC_POWER_BR
)
3808 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3809 gen_op_set_T1(SH(ctx
->opcode
));
3810 gen_op_POWER_sleq();
3811 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3812 if (unlikely(Rc(ctx
->opcode
) != 0))
3817 GEN_HANDLER(sllq
, 0x1F, 0x18, 0x06, 0x00000000, PPC_POWER_BR
)
3819 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3820 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3821 gen_op_POWER_sllq();
3822 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3823 if (unlikely(Rc(ctx
->opcode
) != 0))
3828 GEN_HANDLER(slq
, 0x1F, 0x18, 0x04, 0x00000000, PPC_POWER_BR
)
3830 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3831 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3833 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3834 if (unlikely(Rc(ctx
->opcode
) != 0))
3838 /* sraiq - sraiq. */
3839 GEN_HANDLER(sraiq
, 0x1F, 0x18, 0x1D, 0x00000000, PPC_POWER_BR
)
3841 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3842 gen_op_set_T1(SH(ctx
->opcode
));
3843 gen_op_POWER_sraq();
3844 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3845 if (unlikely(Rc(ctx
->opcode
) != 0))
3850 GEN_HANDLER(sraq
, 0x1F, 0x18, 0x1C, 0x00000000, PPC_POWER_BR
)
3852 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3853 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3854 gen_op_POWER_sraq();
3855 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3856 if (unlikely(Rc(ctx
->opcode
) != 0))
3861 GEN_HANDLER(sre
, 0x1F, 0x19, 0x14, 0x00000000, PPC_POWER_BR
)
3863 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3864 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3866 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3867 if (unlikely(Rc(ctx
->opcode
) != 0))
3872 GEN_HANDLER(srea
, 0x1F, 0x19, 0x1C, 0x00000000, PPC_POWER_BR
)
3874 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3875 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3876 gen_op_POWER_srea();
3877 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3878 if (unlikely(Rc(ctx
->opcode
) != 0))
3883 GEN_HANDLER(sreq
, 0x1F, 0x19, 0x16, 0x00000000, PPC_POWER_BR
)
3885 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3886 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3887 gen_op_POWER_sreq();
3888 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3889 if (unlikely(Rc(ctx
->opcode
) != 0))
3894 GEN_HANDLER(sriq
, 0x1F, 0x18, 0x15, 0x00000000, PPC_POWER_BR
)
3896 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3897 gen_op_set_T1(SH(ctx
->opcode
));
3899 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3900 if (unlikely(Rc(ctx
->opcode
) != 0))
3905 GEN_HANDLER(srliq
, 0x1F, 0x18, 0x17, 0x00000000, PPC_POWER_BR
)
3907 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3908 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3909 gen_op_set_T1(SH(ctx
->opcode
));
3910 gen_op_POWER_srlq();
3911 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3912 if (unlikely(Rc(ctx
->opcode
) != 0))
3917 GEN_HANDLER(srlq
, 0x1F, 0x18, 0x16, 0x00000000, PPC_POWER_BR
)
3919 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3920 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3921 gen_op_POWER_srlq();
3922 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3923 if (unlikely(Rc(ctx
->opcode
) != 0))
3928 GEN_HANDLER(srq
, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR
)
3930 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3931 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3933 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3934 if (unlikely(Rc(ctx
->opcode
) != 0))
3938 /* PowerPC 602 specific instructions */
3940 GEN_HANDLER(dsa
, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC
)
3947 GEN_HANDLER(esa
, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC
)
3954 GEN_HANDLER(mfrom
, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC
)
3956 #if defined(CONFIG_USER_ONLY)
3959 if (unlikely(!ctx
->supervisor
)) {
3963 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3965 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3969 /* 602 - 603 - G2 TLB management */
3971 GEN_HANDLER(tlbld
, 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB
)
3973 #if defined(CONFIG_USER_ONLY)
3976 if (unlikely(!ctx
->supervisor
)) {
3980 gen_op_load_gpr_T0(rB(ctx
->opcode
));
3987 GEN_HANDLER(tlbli
, 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB
)
3989 #if defined(CONFIG_USER_ONLY)
3992 if (unlikely(!ctx
->supervisor
)) {
3996 gen_op_load_gpr_T0(rB(ctx
->opcode
));
4002 /* POWER instructions not in PowerPC 601 */
4004 GEN_HANDLER(clf
, 0x1F, 0x16, 0x03, 0x03E00000, PPC_POWER
)
4006 /* Cache line flush: implemented as no-op */
4010 GEN_HANDLER(cli
, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER
)
4012 /* Cache line invalidate: priviledged and treated as no-op */
4013 #if defined(CONFIG_USER_ONLY)
4016 if (unlikely(!ctx
->supervisor
)) {
4024 GEN_HANDLER(dclst
, 0x1F, 0x16, 0x13, 0x03E00000, PPC_POWER
)
4026 /* Data cache line store: treated as no-op */
4029 GEN_HANDLER(mfsri
, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER
)
4031 #if defined(CONFIG_USER_ONLY)
4034 if (unlikely(!ctx
->supervisor
)) {
4038 int ra
= rA(ctx
->opcode
);
4039 int rd
= rD(ctx
->opcode
);
4041 gen_addr_reg_index(ctx
);
4042 gen_op_POWER_mfsri();
4043 gen_op_store_T0_gpr(rd
);
4044 if (ra
!= 0 && ra
!= rd
)
4045 gen_op_store_T1_gpr(ra
);
4049 GEN_HANDLER(rac
, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER
)
4051 #if defined(CONFIG_USER_ONLY)
4054 if (unlikely(!ctx
->supervisor
)) {
4058 gen_addr_reg_index(ctx
);
4060 gen_op_store_T0_gpr(rD(ctx
->opcode
));
4064 GEN_HANDLER(rfsvc
, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER
)
4066 #if defined(CONFIG_USER_ONLY)
4069 if (unlikely(!ctx
->supervisor
)) {
4073 gen_op_POWER_rfsvc();
4078 /* svc is not implemented for now */
4080 /* POWER2 specific instructions */
4081 /* Quad manipulation (load/store two floats at a time) */
4082 #define op_POWER2_lfq() (*gen_op_POWER2_lfq[ctx->mem_idx])()
4083 #define op_POWER2_stfq() (*gen_op_POWER2_stfq[ctx->mem_idx])()
4084 #if defined(CONFIG_USER_ONLY)
4085 static GenOpFunc
*gen_op_POWER2_lfq
[] = {
4086 &gen_op_POWER2_lfq_le_raw
,
4087 &gen_op_POWER2_lfq_raw
,
4089 static GenOpFunc
*gen_op_POWER2_stfq
[] = {
4090 &gen_op_POWER2_stfq_le_raw
,
4091 &gen_op_POWER2_stfq_raw
,
4094 static GenOpFunc
*gen_op_POWER2_lfq
[] = {
4095 &gen_op_POWER2_lfq_le_user
,
4096 &gen_op_POWER2_lfq_user
,
4097 &gen_op_POWER2_lfq_le_kernel
,
4098 &gen_op_POWER2_lfq_kernel
,
4100 static GenOpFunc
*gen_op_POWER2_stfq
[] = {
4101 &gen_op_POWER2_stfq_le_user
,
4102 &gen_op_POWER2_stfq_user
,
4103 &gen_op_POWER2_stfq_le_kernel
,
4104 &gen_op_POWER2_stfq_kernel
,
4109 GEN_HANDLER(lfq
, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2
)
4111 /* NIP cannot be restored if the memory exception comes from an helper */
4112 gen_update_nip(ctx
, ctx
->nip
- 4);
4113 gen_addr_imm_index(ctx
, 0);
4115 gen_op_store_FT0_fpr(rD(ctx
->opcode
));
4116 gen_op_store_FT1_fpr(rD(ctx
->opcode
) + 1);
4120 GEN_HANDLER(lfqu
, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2
)
4122 int ra
= rA(ctx
->opcode
);
4124 /* NIP cannot be restored if the memory exception comes from an helper */
4125 gen_update_nip(ctx
, ctx
->nip
- 4);
4126 gen_addr_imm_index(ctx
, 0);
4128 gen_op_store_FT0_fpr(rD(ctx
->opcode
));
4129 gen_op_store_FT1_fpr(rD(ctx
->opcode
) + 1);
4131 gen_op_store_T0_gpr(ra
);
4135 GEN_HANDLER(lfqux
, 0x1F, 0x17, 0x19, 0x00000001, PPC_POWER2
)
4137 int ra
= rA(ctx
->opcode
);
4139 /* NIP cannot be restored if the memory exception comes from an helper */
4140 gen_update_nip(ctx
, ctx
->nip
- 4);
4141 gen_addr_reg_index(ctx
);
4143 gen_op_store_FT0_fpr(rD(ctx
->opcode
));
4144 gen_op_store_FT1_fpr(rD(ctx
->opcode
) + 1);
4146 gen_op_store_T0_gpr(ra
);
4150 GEN_HANDLER(lfqx
, 0x1F, 0x17, 0x18, 0x00000001, PPC_POWER2
)
4152 /* NIP cannot be restored if the memory exception comes from an helper */
4153 gen_update_nip(ctx
, ctx
->nip
- 4);
4154 gen_addr_reg_index(ctx
);
4156 gen_op_store_FT0_fpr(rD(ctx
->opcode
));
4157 gen_op_store_FT1_fpr(rD(ctx
->opcode
) + 1);
4161 GEN_HANDLER(stfq
, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2
)
4163 /* NIP cannot be restored if the memory exception comes from an helper */
4164 gen_update_nip(ctx
, ctx
->nip
- 4);
4165 gen_addr_imm_index(ctx
, 0);
4166 gen_op_load_fpr_FT0(rS(ctx
->opcode
));
4167 gen_op_load_fpr_FT1(rS(ctx
->opcode
) + 1);
4172 GEN_HANDLER(stfqu
, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2
)
4174 int ra
= rA(ctx
->opcode
);
4176 /* NIP cannot be restored if the memory exception comes from an helper */
4177 gen_update_nip(ctx
, ctx
->nip
- 4);
4178 gen_addr_imm_index(ctx
, 0);
4179 gen_op_load_fpr_FT0(rS(ctx
->opcode
));
4180 gen_op_load_fpr_FT1(rS(ctx
->opcode
) + 1);
4183 gen_op_store_T0_gpr(ra
);
4187 GEN_HANDLER(stfqux
, 0x1F, 0x17, 0x1D, 0x00000001, PPC_POWER2
)
4189 int ra
= rA(ctx
->opcode
);
4191 /* NIP cannot be restored if the memory exception comes from an helper */
4192 gen_update_nip(ctx
, ctx
->nip
- 4);
4193 gen_addr_reg_index(ctx
);
4194 gen_op_load_fpr_FT0(rS(ctx
->opcode
));
4195 gen_op_load_fpr_FT1(rS(ctx
->opcode
) + 1);
4198 gen_op_store_T0_gpr(ra
);
4202 GEN_HANDLER(stfqx
, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2
)
4204 /* NIP cannot be restored if the memory exception comes from an helper */
4205 gen_update_nip(ctx
, ctx
->nip
- 4);
4206 gen_addr_reg_index(ctx
);
4207 gen_op_load_fpr_FT0(rS(ctx
->opcode
));
4208 gen_op_load_fpr_FT1(rS(ctx
->opcode
) + 1);
4212 /* BookE specific instructions */
4213 GEN_HANDLER(mfapidi
, 0x1F, 0x13, 0x08, 0x0000F801, PPC_BOOKE
)
4219 GEN_HANDLER(tlbiva
, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_BOOKE
)
4221 #if defined(CONFIG_USER_ONLY)
4224 if (unlikely(!ctx
->supervisor
)) {
4228 gen_addr_reg_index(ctx
);
4229 /* Use the same micro-ops as for tlbie */
4230 #if defined(TARGET_PPC64)
4240 /* All 405 MAC instructions are translated here */
4241 static inline void gen_405_mulladd_insn (DisasContext
*ctx
, int opc2
, int opc3
,
4242 int ra
, int rb
, int rt
, int Rc
)
4244 gen_op_load_gpr_T0(ra
);
4245 gen_op_load_gpr_T1(rb
);
4246 switch (opc3
& 0x0D) {
4248 /* macchw - macchw. - macchwo - macchwo. */
4249 /* macchws - macchws. - macchwso - macchwso. */
4250 /* nmacchw - nmacchw. - nmacchwo - nmacchwo. */
4251 /* nmacchws - nmacchws. - nmacchwso - nmacchwso. */
4252 /* mulchw - mulchw. */
4253 gen_op_405_mulchw();
4256 /* macchwu - macchwu. - macchwuo - macchwuo. */
4257 /* macchwsu - macchwsu. - macchwsuo - macchwsuo. */
4258 /* mulchwu - mulchwu. */
4259 gen_op_405_mulchwu();
4262 /* machhw - machhw. - machhwo - machhwo. */
4263 /* machhws - machhws. - machhwso - machhwso. */
4264 /* nmachhw - nmachhw. - nmachhwo - nmachhwo. */
4265 /* nmachhws - nmachhws. - nmachhwso - nmachhwso. */
4266 /* mulhhw - mulhhw. */
4267 gen_op_405_mulhhw();
4270 /* machhwu - machhwu. - machhwuo - machhwuo. */
4271 /* machhwsu - machhwsu. - machhwsuo - machhwsuo. */
4272 /* mulhhwu - mulhhwu. */
4273 gen_op_405_mulhhwu();
4276 /* maclhw - maclhw. - maclhwo - maclhwo. */
4277 /* maclhws - maclhws. - maclhwso - maclhwso. */
4278 /* nmaclhw - nmaclhw. - nmaclhwo - nmaclhwo. */
4279 /* nmaclhws - nmaclhws. - nmaclhwso - nmaclhwso. */
4280 /* mullhw - mullhw. */
4281 gen_op_405_mullhw();
4284 /* maclhwu - maclhwu. - maclhwuo - maclhwuo. */
4285 /* maclhwsu - maclhwsu. - maclhwsuo - maclhwsuo. */
4286 /* mullhwu - mullhwu. */
4287 gen_op_405_mullhwu();
4291 /* nmultiply-and-accumulate (0x0E) */
4295 /* (n)multiply-and-accumulate (0x0C - 0x0E) */
4296 gen_op_load_gpr_T2(rt
);
4297 gen_op_move_T1_T0();
4298 gen_op_405_add_T0_T2();
4301 /* Check overflow */
4303 gen_op_405_check_ov();
4305 gen_op_405_check_ovu();
4310 gen_op_405_check_sat();
4312 gen_op_405_check_satu();
4314 gen_op_store_T0_gpr(rt
);
4315 if (unlikely(Rc
) != 0) {
4321 #define GEN_MAC_HANDLER(name, opc2, opc3) \
4322 GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC) \
4324 gen_405_mulladd_insn(ctx, opc2, opc3, rA(ctx->opcode), rB(ctx->opcode), \
4325 rD(ctx->opcode), Rc(ctx->opcode)); \
4328 /* macchw - macchw. */
4329 GEN_MAC_HANDLER(macchw
, 0x0C, 0x05);
4330 /* macchwo - macchwo. */
4331 GEN_MAC_HANDLER(macchwo
, 0x0C, 0x15);
4332 /* macchws - macchws. */
4333 GEN_MAC_HANDLER(macchws
, 0x0C, 0x07);
4334 /* macchwso - macchwso. */
4335 GEN_MAC_HANDLER(macchwso
, 0x0C, 0x17);
4336 /* macchwsu - macchwsu. */
4337 GEN_MAC_HANDLER(macchwsu
, 0x0C, 0x06);
4338 /* macchwsuo - macchwsuo. */
4339 GEN_MAC_HANDLER(macchwsuo
, 0x0C, 0x16);
4340 /* macchwu - macchwu. */
4341 GEN_MAC_HANDLER(macchwu
, 0x0C, 0x04);
4342 /* macchwuo - macchwuo. */
4343 GEN_MAC_HANDLER(macchwuo
, 0x0C, 0x14);
4344 /* machhw - machhw. */
4345 GEN_MAC_HANDLER(machhw
, 0x0C, 0x01);
4346 /* machhwo - machhwo. */
4347 GEN_MAC_HANDLER(machhwo
, 0x0C, 0x11);
4348 /* machhws - machhws. */
4349 GEN_MAC_HANDLER(machhws
, 0x0C, 0x03);
4350 /* machhwso - machhwso. */
4351 GEN_MAC_HANDLER(machhwso
, 0x0C, 0x13);
4352 /* machhwsu - machhwsu. */
4353 GEN_MAC_HANDLER(machhwsu
, 0x0C, 0x02);
4354 /* machhwsuo - machhwsuo. */
4355 GEN_MAC_HANDLER(machhwsuo
, 0x0C, 0x12);
4356 /* machhwu - machhwu. */
4357 GEN_MAC_HANDLER(machhwu
, 0x0C, 0x00);
4358 /* machhwuo - machhwuo. */
4359 GEN_MAC_HANDLER(machhwuo
, 0x0C, 0x10);
4360 /* maclhw - maclhw. */
4361 GEN_MAC_HANDLER(maclhw
, 0x0C, 0x0D);
4362 /* maclhwo - maclhwo. */
4363 GEN_MAC_HANDLER(maclhwo
, 0x0C, 0x1D);
4364 /* maclhws - maclhws. */
4365 GEN_MAC_HANDLER(maclhws
, 0x0C, 0x0F);
4366 /* maclhwso - maclhwso. */
4367 GEN_MAC_HANDLER(maclhwso
, 0x0C, 0x1F);
4368 /* maclhwu - maclhwu. */
4369 GEN_MAC_HANDLER(maclhwu
, 0x0C, 0x0C);
4370 /* maclhwuo - maclhwuo. */
4371 GEN_MAC_HANDLER(maclhwuo
, 0x0C, 0x1C);
4372 /* maclhwsu - maclhwsu. */
4373 GEN_MAC_HANDLER(maclhwsu
, 0x0C, 0x0E);
4374 /* maclhwsuo - maclhwsuo. */
4375 GEN_MAC_HANDLER(maclhwsuo
, 0x0C, 0x1E);
4376 /* nmacchw - nmacchw. */
4377 GEN_MAC_HANDLER(nmacchw
, 0x0E, 0x05);
4378 /* nmacchwo - nmacchwo. */
4379 GEN_MAC_HANDLER(nmacchwo
, 0x0E, 0x15);
4380 /* nmacchws - nmacchws. */
4381 GEN_MAC_HANDLER(nmacchws
, 0x0E, 0x07);
4382 /* nmacchwso - nmacchwso. */
4383 GEN_MAC_HANDLER(nmacchwso
, 0x0E, 0x17);
4384 /* nmachhw - nmachhw. */
4385 GEN_MAC_HANDLER(nmachhw
, 0x0E, 0x01);
4386 /* nmachhwo - nmachhwo. */
4387 GEN_MAC_HANDLER(nmachhwo
, 0x0E, 0x11);
4388 /* nmachhws - nmachhws. */
4389 GEN_MAC_HANDLER(nmachhws
, 0x0E, 0x03);
4390 /* nmachhwso - nmachhwso. */
4391 GEN_MAC_HANDLER(nmachhwso
, 0x0E, 0x13);
4392 /* nmaclhw - nmaclhw. */
4393 GEN_MAC_HANDLER(nmaclhw
, 0x0E, 0x0D);
4394 /* nmaclhwo - nmaclhwo. */
4395 GEN_MAC_HANDLER(nmaclhwo
, 0x0E, 0x1D);
4396 /* nmaclhws - nmaclhws. */
4397 GEN_MAC_HANDLER(nmaclhws
, 0x0E, 0x0F);
4398 /* nmaclhwso - nmaclhwso. */
4399 GEN_MAC_HANDLER(nmaclhwso
, 0x0E, 0x1F);
4401 /* mulchw - mulchw. */
4402 GEN_MAC_HANDLER(mulchw
, 0x08, 0x05);
4403 /* mulchwu - mulchwu. */
4404 GEN_MAC_HANDLER(mulchwu
, 0x08, 0x04);
4405 /* mulhhw - mulhhw. */
4406 GEN_MAC_HANDLER(mulhhw
, 0x08, 0x01);
4407 /* mulhhwu - mulhhwu. */
4408 GEN_MAC_HANDLER(mulhhwu
, 0x08, 0x00);
4409 /* mullhw - mullhw. */
4410 GEN_MAC_HANDLER(mullhw
, 0x08, 0x0D);
4411 /* mullhwu - mullhwu. */
4412 GEN_MAC_HANDLER(mullhwu
, 0x08, 0x0C);
4415 GEN_HANDLER(mfdcr
, 0x1F, 0x03, 0x0A, 0x00000001, PPC_EMB_COMMON
)
4417 #if defined(CONFIG_USER_ONLY)
4420 uint32_t dcrn
= SPR(ctx
->opcode
);
4422 if (unlikely(!ctx
->supervisor
)) {
4426 gen_op_set_T0(dcrn
);
4428 gen_op_store_T0_gpr(rD(ctx
->opcode
));
4433 GEN_HANDLER(mtdcr
, 0x1F, 0x03, 0x0E, 0x00000001, PPC_EMB_COMMON
)
4435 #if defined(CONFIG_USER_ONLY)
4438 uint32_t dcrn
= SPR(ctx
->opcode
);
4440 if (unlikely(!ctx
->supervisor
)) {
4444 gen_op_set_T0(dcrn
);
4445 gen_op_load_gpr_T1(rS(ctx
->opcode
));
4451 GEN_HANDLER(mfdcrx
, 0x1F, 0x03, 0x08, 0x00000001, PPC_BOOKE
)
4453 #if defined(CONFIG_USER_ONLY)
4456 if (unlikely(!ctx
->supervisor
)) {
4460 gen_op_load_gpr_T0(rA(ctx
->opcode
));
4462 gen_op_store_T0_gpr(rD(ctx
->opcode
));
4467 GEN_HANDLER(mtdcrx
, 0x1F, 0x03, 0x0C, 0x00000001, PPC_BOOKE
)
4469 #if defined(CONFIG_USER_ONLY)
4472 if (unlikely(!ctx
->supervisor
)) {
4476 gen_op_load_gpr_T0(rA(ctx
->opcode
));
4477 gen_op_load_gpr_T1(rS(ctx
->opcode
));
4483 GEN_HANDLER(dccci
, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON
)
4485 #if defined(CONFIG_USER_ONLY)
4488 if (unlikely(!ctx
->supervisor
)) {
4492 /* interpreted as no-op */
4497 GEN_HANDLER(dcread
, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON
)
4499 #if defined(CONFIG_USER_ONLY)
4502 if (unlikely(!ctx
->supervisor
)) {
4506 gen_addr_reg_index(ctx
);
4508 gen_op_store_T0_gpr(rD(ctx
->opcode
));
4513 GEN_HANDLER(icbt_40x
, 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_SPEC
)
4515 /* interpreted as no-op */
4516 /* XXX: specification say this is treated as a load by the MMU
4517 * but does not generate any exception
4522 GEN_HANDLER(iccci
, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON
)
4524 #if defined(CONFIG_USER_ONLY)
4527 if (unlikely(!ctx
->supervisor
)) {
4531 /* interpreted as no-op */
4536 GEN_HANDLER(icread
, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON
)
4538 #if defined(CONFIG_USER_ONLY)
4541 if (unlikely(!ctx
->supervisor
)) {
4545 /* interpreted as no-op */
4549 /* rfci (supervisor only) */
4550 GEN_HANDLER(rfci_40x
, 0x13, 0x13, 0x01, 0x03FF8001, PPC_40x_EXCP
)
4552 #if defined(CONFIG_USER_ONLY)
4555 if (unlikely(!ctx
->supervisor
)) {
4559 /* Restore CPU state */
4565 GEN_HANDLER(rfci
, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE
)
4567 #if defined(CONFIG_USER_ONLY)
4570 if (unlikely(!ctx
->supervisor
)) {
4574 /* Restore CPU state */
4580 /* BookE specific */
4581 GEN_HANDLER(rfdi
, 0x13, 0x07, 0x01, 0x03FF8001, PPC_BOOKE
)
4583 #if defined(CONFIG_USER_ONLY)
4586 if (unlikely(!ctx
->supervisor
)) {
4590 /* Restore CPU state */
4596 GEN_HANDLER(rfmci
, 0x13, 0x06, 0x01, 0x03FF8001, PPC_BOOKE
)
4598 #if defined(CONFIG_USER_ONLY)
4601 if (unlikely(!ctx
->supervisor
)) {
4605 /* Restore CPU state */
4610 /* TLB management - PowerPC 405 implementation */
4612 GEN_HANDLER(tlbre
, 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_SPEC
)
4614 #if defined(CONFIG_USER_ONLY)
4617 if (unlikely(!ctx
->supervisor
)) {
4621 switch (rB(ctx
->opcode
)) {
4623 gen_op_load_gpr_T0(rA(ctx
->opcode
));
4624 gen_op_4xx_tlbre_hi();
4625 gen_op_store_T0_gpr(rD(ctx
->opcode
));
4628 gen_op_load_gpr_T0(rA(ctx
->opcode
));
4629 gen_op_4xx_tlbre_lo();
4630 gen_op_store_T0_gpr(rD(ctx
->opcode
));
4639 /* tlbsx - tlbsx. */
4640 GEN_HANDLER(tlbsx
, 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_SPEC
)
4642 #if defined(CONFIG_USER_ONLY)
4645 if (unlikely(!ctx
->supervisor
)) {
4649 gen_addr_reg_index(ctx
);
4650 if (Rc(ctx
->opcode
))
4651 gen_op_4xx_tlbsx_();
4654 gen_op_store_T0_gpr(rD(ctx
->opcode
));
4659 GEN_HANDLER(tlbwe
, 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_SPEC
)
4661 #if defined(CONFIG_USER_ONLY)
4664 if (unlikely(!ctx
->supervisor
)) {
4668 switch (rB(ctx
->opcode
)) {
4670 gen_op_load_gpr_T0(rA(ctx
->opcode
));
4671 gen_op_load_gpr_T1(rS(ctx
->opcode
));
4672 gen_op_4xx_tlbwe_hi();
4675 gen_op_load_gpr_T0(rA(ctx
->opcode
));
4676 gen_op_load_gpr_T1(rS(ctx
->opcode
));
4677 gen_op_4xx_tlbwe_lo();
4687 GEN_HANDLER(wrtee
, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_EMB_COMMON
)
4689 #if defined(CONFIG_USER_ONLY)
4692 if (unlikely(!ctx
->supervisor
)) {
4696 gen_op_load_gpr_T0(rD(ctx
->opcode
));
4698 RET_EXCP(ctx
, EXCP_MTMSR
, 0);
4703 GEN_HANDLER(wrteei
, 0x1F, 0x03, 0x05, 0x000EFC01, PPC_EMB_COMMON
)
4705 #if defined(CONFIG_USER_ONLY)
4708 if (unlikely(!ctx
->supervisor
)) {
4712 gen_op_set_T0(ctx
->opcode
& 0x00010000);
4714 RET_EXCP(ctx
, EXCP_MTMSR
, 0);
4718 /* PPC 440 specific instructions */
4720 GEN_HANDLER(dlmzb
, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC
)
4722 gen_op_load_gpr_T0(rS(ctx
->opcode
));
4723 gen_op_load_gpr_T1(rB(ctx
->opcode
));
4725 gen_op_store_T0_gpr(rA(ctx
->opcode
));
4726 gen_op_store_xer_bc();
4727 if (Rc(ctx
->opcode
)) {
4728 gen_op_440_dlmzb_update_Rc();
4729 gen_op_store_T0_crf(0);
4733 /* mbar replaces eieio on 440 */
4734 GEN_HANDLER(mbar
, 0x1F, 0x16, 0x13, 0x001FF801, PPC_BOOKE
)
4736 /* interpreted as no-op */
4739 /* msync replaces sync on 440 */
4740 GEN_HANDLER(msync
, 0x1F, 0x16, 0x12, 0x03FF0801, PPC_BOOKE
)
4742 /* interpreted as no-op */
4746 GEN_HANDLER(icbt_440
, 0x1F, 0x16, 0x00, 0x03E00001, PPC_BOOKE
)
4748 /* interpreted as no-op */
4749 /* XXX: specification say this is treated as a load by the MMU
4750 * but does not generate any exception
4754 #if defined(TARGET_PPCSPE)
4755 /*** SPE extension ***/
4757 /* Register moves */
4758 GEN32(gen_op_load_gpr64_T0
, gen_op_load_gpr64_T0_gpr
);
4759 GEN32(gen_op_load_gpr64_T1
, gen_op_load_gpr64_T1_gpr
);
4761 GEN32(gen_op_load_gpr64_T2
, gen_op_load_gpr64_T2_gpr
);
4764 GEN32(gen_op_store_T0_gpr64
, gen_op_store_T0_gpr64_gpr
);
4765 GEN32(gen_op_store_T1_gpr64
, gen_op_store_T1_gpr64_gpr
);
4767 GEN32(gen_op_store_T2_gpr64
, gen_op_store_T2_gpr64_gpr
);
4770 #define GEN_SPE(name0, name1, opc2, opc3, inval, type) \
4771 GEN_HANDLER(name0##_##name1, 0x04, opc2, opc3, inval, type) \
4773 if (Rc(ctx->opcode)) \
4779 /* Handler for undefined SPE opcodes */
4780 static inline void gen_speundef (DisasContext
*ctx
)
4785 /* SPE load and stores */
4786 static inline void gen_addr_spe_imm_index (DisasContext
*ctx
, int sh
)
4788 target_long simm
= rB(ctx
->opcode
);
4790 if (rA(ctx
->opcode
) == 0) {
4791 gen_set_T0(simm
<< sh
);
4793 gen_op_load_gpr_T0(rA(ctx
->opcode
));
4794 if (likely(simm
!= 0))
4795 gen_op_addi(simm
<< sh
);
4799 #define op_spe_ldst(name) (*gen_op_##name[ctx->mem_idx])()
4800 #if defined(CONFIG_USER_ONLY)
4801 #if defined(TARGET_PPC64)
4802 #define OP_SPE_LD_TABLE(name) \
4803 static GenOpFunc *gen_op_spe_l##name[] = { \
4804 &gen_op_spe_l##name##_raw, \
4805 &gen_op_spe_l##name##_le_raw, \
4806 &gen_op_spe_l##name##_64_raw, \
4807 &gen_op_spe_l##name##_le_64_raw, \
4809 #define OP_SPE_ST_TABLE(name) \
4810 static GenOpFunc *gen_op_spe_st##name[] = { \
4811 &gen_op_spe_st##name##_raw, \
4812 &gen_op_spe_st##name##_le_raw, \
4813 &gen_op_spe_st##name##_64_raw, \
4814 &gen_op_spe_st##name##_le_64_raw, \
4816 #else /* defined(TARGET_PPC64) */
4817 #define OP_SPE_LD_TABLE(name) \
4818 static GenOpFunc *gen_op_spe_l##name[] = { \
4819 &gen_op_spe_l##name##_raw, \
4820 &gen_op_spe_l##name##_le_raw, \
4822 #define OP_SPE_ST_TABLE(name) \
4823 static GenOpFunc *gen_op_spe_st##name[] = { \
4824 &gen_op_spe_st##name##_raw, \
4825 &gen_op_spe_st##name##_le_raw, \
4827 #endif /* defined(TARGET_PPC64) */
4828 #else /* defined(CONFIG_USER_ONLY) */
4829 #if defined(TARGET_PPC64)
4830 #define OP_SPE_LD_TABLE(name) \
4831 static GenOpFunc *gen_op_spe_l##name[] = { \
4832 &gen_op_spe_l##name##_user, \
4833 &gen_op_spe_l##name##_le_user, \
4834 &gen_op_spe_l##name##_kernel, \
4835 &gen_op_spe_l##name##_le_kernel, \
4836 &gen_op_spe_l##name##_64_user, \
4837 &gen_op_spe_l##name##_le_64_user, \
4838 &gen_op_spe_l##name##_64_kernel, \
4839 &gen_op_spe_l##name##_le_64_kernel, \
4841 #define OP_SPE_ST_TABLE(name) \
4842 static GenOpFunc *gen_op_spe_st##name[] = { \
4843 &gen_op_spe_st##name##_user, \
4844 &gen_op_spe_st##name##_le_user, \
4845 &gen_op_spe_st##name##_kernel, \
4846 &gen_op_spe_st##name##_le_kernel, \
4847 &gen_op_spe_st##name##_64_user, \
4848 &gen_op_spe_st##name##_le_64_user, \
4849 &gen_op_spe_st##name##_64_kernel, \
4850 &gen_op_spe_st##name##_le_64_kernel, \
4852 #else /* defined(TARGET_PPC64) */
4853 #define OP_SPE_LD_TABLE(name) \
4854 static GenOpFunc *gen_op_spe_l##name[] = { \
4855 &gen_op_spe_l##name##_user, \
4856 &gen_op_spe_l##name##_le_user, \
4857 &gen_op_spe_l##name##_kernel, \
4858 &gen_op_spe_l##name##_le_kernel, \
4860 #define OP_SPE_ST_TABLE(name) \
4861 static GenOpFunc *gen_op_spe_st##name[] = { \
4862 &gen_op_spe_st##name##_user, \
4863 &gen_op_spe_st##name##_le_user, \
4864 &gen_op_spe_st##name##_kernel, \
4865 &gen_op_spe_st##name##_le_kernel, \
4867 #endif /* defined(TARGET_PPC64) */
4868 #endif /* defined(CONFIG_USER_ONLY) */
4870 #define GEN_SPE_LD(name, sh) \
4871 static inline void gen_evl##name (DisasContext *ctx) \
4873 if (unlikely(!ctx->spe_enabled)) { \
4874 RET_EXCP(ctx, EXCP_NO_SPE, 0); \
4877 gen_addr_spe_imm_index(ctx, sh); \
4878 op_spe_ldst(spe_l##name); \
4879 gen_op_store_T1_gpr64(rD(ctx->opcode)); \
4882 #define GEN_SPE_LDX(name) \
4883 static inline void gen_evl##name##x (DisasContext *ctx) \
4885 if (unlikely(!ctx->spe_enabled)) { \
4886 RET_EXCP(ctx, EXCP_NO_SPE, 0); \
4889 gen_addr_reg_index(ctx); \
4890 op_spe_ldst(spe_l##name); \
4891 gen_op_store_T1_gpr64(rD(ctx->opcode)); \
4894 #define GEN_SPEOP_LD(name, sh) \
4895 OP_SPE_LD_TABLE(name); \
4896 GEN_SPE_LD(name, sh); \
4899 #define GEN_SPE_ST(name, sh) \
4900 static inline void gen_evst##name (DisasContext *ctx) \
4902 if (unlikely(!ctx->spe_enabled)) { \
4903 RET_EXCP(ctx, EXCP_NO_SPE, 0); \
4906 gen_addr_spe_imm_index(ctx, sh); \
4907 gen_op_load_gpr64_T1(rS(ctx->opcode)); \
4908 op_spe_ldst(spe_st##name); \
4911 #define GEN_SPE_STX(name) \
4912 static inline void gen_evst##name##x (DisasContext *ctx) \
4914 if (unlikely(!ctx->spe_enabled)) { \
4915 RET_EXCP(ctx, EXCP_NO_SPE, 0); \
4918 gen_addr_reg_index(ctx); \
4919 gen_op_load_gpr64_T1(rS(ctx->opcode)); \
4920 op_spe_ldst(spe_st##name); \
4923 #define GEN_SPEOP_ST(name, sh) \
4924 OP_SPE_ST_TABLE(name); \
4925 GEN_SPE_ST(name, sh); \
4928 #define GEN_SPEOP_LDST(name, sh) \
4929 GEN_SPEOP_LD(name, sh); \
4930 GEN_SPEOP_ST(name, sh)
4932 /* SPE arithmetic and logic */
4933 #define GEN_SPEOP_ARITH2(name) \
4934 static inline void gen_##name (DisasContext *ctx) \
4936 if (unlikely(!ctx->spe_enabled)) { \
4937 RET_EXCP(ctx, EXCP_NO_SPE, 0); \
4940 gen_op_load_gpr64_T0(rA(ctx->opcode)); \
4941 gen_op_load_gpr64_T1(rB(ctx->opcode)); \
4943 gen_op_store_T0_gpr64(rD(ctx->opcode)); \
4946 #define GEN_SPEOP_ARITH1(name) \
4947 static inline void gen_##name (DisasContext *ctx) \
4949 if (unlikely(!ctx->spe_enabled)) { \
4950 RET_EXCP(ctx, EXCP_NO_SPE, 0); \
4953 gen_op_load_gpr64_T0(rA(ctx->opcode)); \
4955 gen_op_store_T0_gpr64(rD(ctx->opcode)); \
4958 #define GEN_SPEOP_COMP(name) \
4959 static inline void gen_##name (DisasContext *ctx) \
4961 if (unlikely(!ctx->spe_enabled)) { \
4962 RET_EXCP(ctx, EXCP_NO_SPE, 0); \
4965 gen_op_load_gpr64_T0(rA(ctx->opcode)); \
4966 gen_op_load_gpr64_T1(rB(ctx->opcode)); \
4968 gen_op_store_T0_crf(crfD(ctx->opcode)); \
4972 GEN_SPEOP_ARITH2(evand
);
4973 GEN_SPEOP_ARITH2(evandc
);
4974 GEN_SPEOP_ARITH2(evxor
);
4975 GEN_SPEOP_ARITH2(evor
);
4976 GEN_SPEOP_ARITH2(evnor
);
4977 GEN_SPEOP_ARITH2(eveqv
);
4978 GEN_SPEOP_ARITH2(evorc
);
4979 GEN_SPEOP_ARITH2(evnand
);
4980 GEN_SPEOP_ARITH2(evsrwu
);
4981 GEN_SPEOP_ARITH2(evsrws
);
4982 GEN_SPEOP_ARITH2(evslw
);
4983 GEN_SPEOP_ARITH2(evrlw
);
4984 GEN_SPEOP_ARITH2(evmergehi
);
4985 GEN_SPEOP_ARITH2(evmergelo
);
4986 GEN_SPEOP_ARITH2(evmergehilo
);
4987 GEN_SPEOP_ARITH2(evmergelohi
);
4990 GEN_SPEOP_ARITH2(evaddw
);
4991 GEN_SPEOP_ARITH2(evsubfw
);
4992 GEN_SPEOP_ARITH1(evabs
);
4993 GEN_SPEOP_ARITH1(evneg
);
4994 GEN_SPEOP_ARITH1(evextsb
);
4995 GEN_SPEOP_ARITH1(evextsh
);
4996 GEN_SPEOP_ARITH1(evrndw
);
4997 GEN_SPEOP_ARITH1(evcntlzw
);
4998 GEN_SPEOP_ARITH1(evcntlsw
);
4999 static inline void gen_brinc (DisasContext
*ctx
)
5001 /* Note: brinc is usable even if SPE is disabled */
5002 gen_op_load_gpr64_T0(rA(ctx
->opcode
));
5003 gen_op_load_gpr64_T1(rB(ctx
->opcode
));
5005 gen_op_store_T0_gpr64(rD(ctx
->opcode
));
5008 #define GEN_SPEOP_ARITH_IMM2(name) \
5009 static inline void gen_##name##i (DisasContext *ctx) \
5011 if (unlikely(!ctx->spe_enabled)) { \
5012 RET_EXCP(ctx, EXCP_NO_SPE, 0); \
5015 gen_op_load_gpr64_T0(rB(ctx->opcode)); \
5016 gen_op_splatwi_T1_64(rA(ctx->opcode)); \
5018 gen_op_store_T0_gpr64(rD(ctx->opcode)); \
5021 #define GEN_SPEOP_LOGIC_IMM2(name) \
5022 static inline void gen_##name##i (DisasContext *ctx) \
5024 if (unlikely(!ctx->spe_enabled)) { \
5025 RET_EXCP(ctx, EXCP_NO_SPE, 0); \
5028 gen_op_load_gpr64_T0(rA(ctx->opcode)); \
5029 gen_op_splatwi_T1_64(rB(ctx->opcode)); \
5031 gen_op_store_T0_gpr64(rD(ctx->opcode)); \
5034 GEN_SPEOP_ARITH_IMM2(evaddw
);
5035 #define gen_evaddiw gen_evaddwi
5036 GEN_SPEOP_ARITH_IMM2(evsubfw
);
5037 #define gen_evsubifw gen_evsubfwi
5038 GEN_SPEOP_LOGIC_IMM2(evslw
);
5039 GEN_SPEOP_LOGIC_IMM2(evsrwu
);
5040 #define gen_evsrwis gen_evsrwsi
5041 GEN_SPEOP_LOGIC_IMM2(evsrws
);
5042 #define gen_evsrwiu gen_evsrwui
5043 GEN_SPEOP_LOGIC_IMM2(evrlw
);
5045 static inline void gen_evsplati (DisasContext
*ctx
)
5047 int32_t imm
= (int32_t)(rA(ctx
->opcode
) << 27) >> 27;
5049 gen_op_splatwi_T0_64(imm
);
5050 gen_op_store_T0_gpr64(rD(ctx
->opcode
));
5053 static inline void gen_evsplatfi (DisasContext
*ctx
)
5055 uint32_t imm
= rA(ctx
->opcode
) << 27;
5057 gen_op_splatwi_T0_64(imm
);
5058 gen_op_store_T0_gpr64(rD(ctx
->opcode
));
5062 GEN_SPEOP_COMP(evcmpgtu
);
5063 GEN_SPEOP_COMP(evcmpgts
);
5064 GEN_SPEOP_COMP(evcmpltu
);
5065 GEN_SPEOP_COMP(evcmplts
);
5066 GEN_SPEOP_COMP(evcmpeq
);
5068 GEN_SPE(evaddw
, speundef
, 0x00, 0x08, 0x00000000, PPC_SPE
); ////
5069 GEN_SPE(evaddiw
, speundef
, 0x01, 0x08, 0x00000000, PPC_SPE
);
5070 GEN_SPE(evsubfw
, speundef
, 0x02, 0x08, 0x00000000, PPC_SPE
); ////
5071 GEN_SPE(evsubifw
, speundef
, 0x03, 0x08, 0x00000000, PPC_SPE
);
5072 GEN_SPE(evabs
, evneg
, 0x04, 0x08, 0x0000F800, PPC_SPE
); ////
5073 GEN_SPE(evextsb
, evextsh
, 0x05, 0x08, 0x0000F800, PPC_SPE
); ////
5074 GEN_SPE(evrndw
, evcntlzw
, 0x06, 0x08, 0x0000F800, PPC_SPE
); ////
5075 GEN_SPE(evcntlsw
, brinc
, 0x07, 0x08, 0x00000000, PPC_SPE
); //
5076 GEN_SPE(speundef
, evand
, 0x08, 0x08, 0x00000000, PPC_SPE
); ////
5077 GEN_SPE(evandc
, speundef
, 0x09, 0x08, 0x00000000, PPC_SPE
); ////
5078 GEN_SPE(evxor
, evor
, 0x0B, 0x08, 0x00000000, PPC_SPE
); ////
5079 GEN_SPE(evnor
, eveqv
, 0x0C, 0x08, 0x00000000, PPC_SPE
); ////
5080 GEN_SPE(speundef
, evorc
, 0x0D, 0x08, 0x00000000, PPC_SPE
); ////
5081 GEN_SPE(evnand
, speundef
, 0x0F, 0x08, 0x00000000, PPC_SPE
); ////
5082 GEN_SPE(evsrwu
, evsrws
, 0x10, 0x08, 0x00000000, PPC_SPE
); ////
5083 GEN_SPE(evsrwiu
, evsrwis
, 0x11, 0x08, 0x00000000, PPC_SPE
);
5084 GEN_SPE(evslw
, speundef
, 0x12, 0x08, 0x00000000, PPC_SPE
); ////
5085 GEN_SPE(evslwi
, speundef
, 0x13, 0x08, 0x00000000, PPC_SPE
);
5086 GEN_SPE(evrlw
, evsplati
, 0x14, 0x08, 0x00000000, PPC_SPE
); //
5087 GEN_SPE(evrlwi
, evsplatfi
, 0x15, 0x08, 0x00000000, PPC_SPE
);
5088 GEN_SPE(evmergehi
, evmergelo
, 0x16, 0x08, 0x00000000, PPC_SPE
); ////
5089 GEN_SPE(evmergehilo
, evmergelohi
, 0x17, 0x08, 0x00000000, PPC_SPE
); ////
5090 GEN_SPE(evcmpgtu
, evcmpgts
, 0x18, 0x08, 0x00600000, PPC_SPE
); ////
5091 GEN_SPE(evcmpltu
, evcmplts
, 0x19, 0x08, 0x00600000, PPC_SPE
); ////
5092 GEN_SPE(evcmpeq
, speundef
, 0x1A, 0x08, 0x00600000, PPC_SPE
); ////
5094 static inline void gen_evsel (DisasContext
*ctx
)
5096 if (unlikely(!ctx
->spe_enabled
)) {
5097 RET_EXCP(ctx
, EXCP_NO_SPE
, 0);
5100 gen_op_load_crf_T0(ctx
->opcode
& 0x7);
5101 gen_op_load_gpr64_T0(rA(ctx
->opcode
));
5102 gen_op_load_gpr64_T1(rB(ctx
->opcode
));
5104 gen_op_store_T0_gpr64(rD(ctx
->opcode
));
5107 GEN_HANDLER(evsel0
, 0x04, 0x1c, 0x09, 0x00000000, PPC_SPE
)
5111 GEN_HANDLER(evsel1
, 0x04, 0x1d, 0x09, 0x00000000, PPC_SPE
)
5115 GEN_HANDLER(evsel2
, 0x04, 0x1e, 0x09, 0x00000000, PPC_SPE
)
5119 GEN_HANDLER(evsel3
, 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE
)
5124 /* Load and stores */
5125 #if defined(TARGET_PPC64)
5126 /* In that case, we already have 64 bits load & stores
5127 * so, spe_ldd is equivalent to ld and spe_std is equivalent to std
5129 #if defined(CONFIG_USER_ONLY)
5130 #define gen_op_spe_ldd_raw gen_op_ld_raw
5131 #define gen_op_spe_ldd_64_raw gen_op_ld_64_raw
5132 #define gen_op_spe_ldd_le_raw gen_op_ld_le_raw
5133 #define gen_op_spe_ldd_le_64_raw gen_op_ld_le_64_raw
5134 #define gen_op_spe_stdd_raw gen_op_ld_raw
5135 #define gen_op_spe_stdd_64_raw gen_op_std_64_raw
5136 #define gen_op_spe_stdd_le_raw gen_op_std_le_raw
5137 #define gen_op_spe_stdd_le_64_raw gen_op_std_le_64_raw
5138 #else /* defined(CONFIG_USER_ONLY) */
5139 #define gen_op_spe_ldd_kernel gen_op_ld_kernel
5140 #define gen_op_spe_ldd_64_kernel gen_op_ld_64_kernel
5141 #define gen_op_spe_ldd_le_kernel gen_op_ld_kernel
5142 #define gen_op_spe_ldd_le_64_kernel gen_op_ld_64_kernel
5143 #define gen_op_spe_ldd_user gen_op_ld_user
5144 #define gen_op_spe_ldd_64_user gen_op_ld_64_user
5145 #define gen_op_spe_ldd_le_user gen_op_ld_le_user
5146 #define gen_op_spe_ldd_le_64_user gen_op_ld_le_64_user
5147 #define gen_op_spe_stdd_kernel gen_op_std_kernel
5148 #define gen_op_spe_stdd_64_kernel gen_op_std_64_kernel
5149 #define gen_op_spe_stdd_le_kernel gen_op_std_kernel
5150 #define gen_op_spe_stdd_le_64_kernel gen_op_std_64_kernel
5151 #define gen_op_spe_stdd_user gen_op_std_user
5152 #define gen_op_spe_stdd_64_user gen_op_std_64_user
5153 #define gen_op_spe_stdd_le_user gen_op_std_le_user
5154 #define gen_op_spe_stdd_le_64_user gen_op_std_le_64_user
5155 #endif /* defined(CONFIG_USER_ONLY) */
5156 #endif /* defined(TARGET_PPC64) */
5157 GEN_SPEOP_LDST(dd
, 3);
5158 GEN_SPEOP_LDST(dw
, 3);
5159 GEN_SPEOP_LDST(dh
, 3);
5160 GEN_SPEOP_LDST(whe
, 2);
5161 GEN_SPEOP_LD(whou
, 2);
5162 GEN_SPEOP_LD(whos
, 2);
5163 GEN_SPEOP_ST(who
, 2);
5165 #if defined(TARGET_PPC64)
5166 /* In that case, spe_stwwo is equivalent to stw */
5167 #if defined(CONFIG_USER_ONLY)
5168 #define gen_op_spe_stwwo_raw gen_op_stw_raw
5169 #define gen_op_spe_stwwo_le_raw gen_op_stw_le_raw
5170 #define gen_op_spe_stwwo_64_raw gen_op_stw_64_raw
5171 #define gen_op_spe_stwwo_le_64_raw gen_op_stw_le_64_raw
5173 #define gen_op_spe_stwwo_user gen_op_stw_user
5174 #define gen_op_spe_stwwo_le_user gen_op_stw_le_user
5175 #define gen_op_spe_stwwo_64_user gen_op_stw_64_user
5176 #define gen_op_spe_stwwo_le_64_user gen_op_stw_le_64_user
5177 #define gen_op_spe_stwwo_kernel gen_op_stw_kernel
5178 #define gen_op_spe_stwwo_le_kernel gen_op_stw_le_kernel
5179 #define gen_op_spe_stwwo_64_kernel gen_op_stw_64_kernel
5180 #define gen_op_spe_stwwo_le_64_kernel gen_op_stw_le_64_kernel
5183 #define _GEN_OP_SPE_STWWE(suffix) \
5184 static inline void gen_op_spe_stwwe_##suffix (void) \
5186 gen_op_srli32_T1_64(); \
5187 gen_op_spe_stwwo_##suffix(); \
5189 #define _GEN_OP_SPE_STWWE_LE(suffix) \
5190 static inline void gen_op_spe_stwwe_le_##suffix (void) \
5192 gen_op_srli32_T1_64(); \
5193 gen_op_spe_stwwo_le_##suffix(); \
5195 #if defined(TARGET_PPC64)
5196 #define GEN_OP_SPE_STWWE(suffix) \
5197 _GEN_OP_SPE_STWWE(suffix); \
5198 _GEN_OP_SPE_STWWE_LE(suffix); \
5199 static inline void gen_op_spe_stwwe_64_##suffix (void) \
5201 gen_op_srli32_T1_64(); \
5202 gen_op_spe_stwwo_64_##suffix(); \
5204 static inline void gen_op_spe_stwwe_le_64_##suffix (void) \
5206 gen_op_srli32_T1_64(); \
5207 gen_op_spe_stwwo_le_64_##suffix(); \
5210 #define GEN_OP_SPE_STWWE(suffix) \
5211 _GEN_OP_SPE_STWWE(suffix); \
5212 _GEN_OP_SPE_STWWE_LE(suffix)
5214 #if defined(CONFIG_USER_ONLY)
5215 GEN_OP_SPE_STWWE(raw
);
5216 #else /* defined(CONFIG_USER_ONLY) */
5217 GEN_OP_SPE_STWWE(kernel
);
5218 GEN_OP_SPE_STWWE(user
);
5219 #endif /* defined(CONFIG_USER_ONLY) */
5220 GEN_SPEOP_ST(wwe
, 2);
5221 GEN_SPEOP_ST(wwo
, 2);
5223 #define GEN_SPE_LDSPLAT(name, op, suffix) \
5224 static inline void gen_op_spe_l##name##_##suffix (void) \
5226 gen_op_##op##_##suffix(); \
5227 gen_op_splatw_T1_64(); \
5230 #define GEN_OP_SPE_LHE(suffix) \
5231 static inline void gen_op_spe_lhe_##suffix (void) \
5233 gen_op_spe_lh_##suffix(); \
5234 gen_op_sli16_T1_64(); \
5237 #define GEN_OP_SPE_LHX(suffix) \
5238 static inline void gen_op_spe_lhx_##suffix (void) \
5240 gen_op_spe_lh_##suffix(); \
5241 gen_op_extsh_T1_64(); \
5244 #if defined(CONFIG_USER_ONLY)
5245 GEN_OP_SPE_LHE(raw
);
5246 GEN_SPE_LDSPLAT(hhesplat
, spe_lhe
, raw
);
5247 GEN_OP_SPE_LHE(le_raw
);
5248 GEN_SPE_LDSPLAT(hhesplat
, spe_lhe
, le_raw
);
5249 GEN_SPE_LDSPLAT(hhousplat
, spe_lh
, raw
);
5250 GEN_SPE_LDSPLAT(hhousplat
, spe_lh
, le_raw
);
5251 GEN_OP_SPE_LHX(raw
);
5252 GEN_SPE_LDSPLAT(hhossplat
, spe_lhx
, raw
);
5253 GEN_OP_SPE_LHX(le_raw
);
5254 GEN_SPE_LDSPLAT(hhossplat
, spe_lhx
, le_raw
);
5255 #if defined(TARGET_PPC64)
5256 GEN_OP_SPE_LHE(64_raw
);
5257 GEN_SPE_LDSPLAT(hhesplat
, spe_lhe
, 64_raw
);
5258 GEN_OP_SPE_LHE(le_64_raw
);
5259 GEN_SPE_LDSPLAT(hhesplat
, spe_lhe
, le_64_raw
);
5260 GEN_SPE_LDSPLAT(hhousplat
, spe_lh
, 64_raw
);
5261 GEN_SPE_LDSPLAT(hhousplat
, spe_lh
, le_64_raw
);
5262 GEN_OP_SPE_LHX(64_raw
);
5263 GEN_SPE_LDSPLAT(hhossplat
, spe_lhx
, 64_raw
);
5264 GEN_OP_SPE_LHX(le_64_raw
);
5265 GEN_SPE_LDSPLAT(hhossplat
, spe_lhx
, le_64_raw
);
5268 GEN_OP_SPE_LHE(kernel
);
5269 GEN_OP_SPE_LHE(user
);
5270 GEN_SPE_LDSPLAT(hhesplat
, spe_lhe
, kernel
);
5271 GEN_SPE_LDSPLAT(hhesplat
, spe_lhe
, user
);
5272 GEN_OP_SPE_LHE(le_kernel
);
5273 GEN_OP_SPE_LHE(le_user
);
5274 GEN_SPE_LDSPLAT(hhesplat
, spe_lhe
, le_kernel
);
5275 GEN_SPE_LDSPLAT(hhesplat
, spe_lhe
, le_user
);
5276 GEN_SPE_LDSPLAT(hhousplat
, spe_lh
, kernel
);
5277 GEN_SPE_LDSPLAT(hhousplat
, spe_lh
, user
);
5278 GEN_SPE_LDSPLAT(hhousplat
, spe_lh
, le_kernel
);
5279 GEN_SPE_LDSPLAT(hhousplat
, spe_lh
, le_user
);
5280 GEN_OP_SPE_LHX(kernel
);
5281 GEN_OP_SPE_LHX(user
);
5282 GEN_SPE_LDSPLAT(hhossplat
, spe_lhx
, kernel
);
5283 GEN_SPE_LDSPLAT(hhossplat
, spe_lhx
, user
);
5284 GEN_OP_SPE_LHX(le_kernel
);
5285 GEN_OP_SPE_LHX(le_user
);
5286 GEN_SPE_LDSPLAT(hhossplat
, spe_lhx
, le_kernel
);
5287 GEN_SPE_LDSPLAT(hhossplat
, spe_lhx
, le_user
);
5288 #if defined(TARGET_PPC64)
5289 GEN_OP_SPE_LHE(64_kernel
);
5290 GEN_OP_SPE_LHE(64_user
);
5291 GEN_SPE_LDSPLAT(hhesplat
, spe_lhe
, 64_kernel
);
5292 GEN_SPE_LDSPLAT(hhesplat
, spe_lhe
, 64_user
);
5293 GEN_OP_SPE_LHE(le_64_kernel
);
5294 GEN_OP_SPE_LHE(le_64_user
);
5295 GEN_SPE_LDSPLAT(hhesplat
, spe_lhe
, le_64_kernel
);
5296 GEN_SPE_LDSPLAT(hhesplat
, spe_lhe
, le_64_user
);
5297 GEN_SPE_LDSPLAT(hhousplat
, spe_lh
, 64_kernel
);
5298 GEN_SPE_LDSPLAT(hhousplat
, spe_lh
, 64_user
);
5299 GEN_SPE_LDSPLAT(hhousplat
, spe_lh
, le_64_kernel
);
5300 GEN_SPE_LDSPLAT(hhousplat
, spe_lh
, le_64_user
);
5301 GEN_OP_SPE_LHX(64_kernel
);
5302 GEN_OP_SPE_LHX(64_user
);
5303 GEN_SPE_LDSPLAT(hhossplat
, spe_lhx
, 64_kernel
);
5304 GEN_SPE_LDSPLAT(hhossplat
, spe_lhx
, 64_user
);
5305 GEN_OP_SPE_LHX(le_64_kernel
);
5306 GEN_OP_SPE_LHX(le_64_user
);
5307 GEN_SPE_LDSPLAT(hhossplat
, spe_lhx
, le_64_kernel
);
5308 GEN_SPE_LDSPLAT(hhossplat
, spe_lhx
, le_64_user
);
5311 GEN_SPEOP_LD(hhesplat
, 1);
5312 GEN_SPEOP_LD(hhousplat
, 1);
5313 GEN_SPEOP_LD(hhossplat
, 1);
5314 GEN_SPEOP_LD(wwsplat
, 2);
5315 GEN_SPEOP_LD(whsplat
, 2);
5317 GEN_SPE(evlddx
, evldd
, 0x00, 0x0C, 0x00000000, PPC_SPE
); //
5318 GEN_SPE(evldwx
, evldw
, 0x01, 0x0C, 0x00000000, PPC_SPE
); //
5319 GEN_SPE(evldhx
, evldh
, 0x02, 0x0C, 0x00000000, PPC_SPE
); //
5320 GEN_SPE(evlhhesplatx
, evlhhesplat
, 0x04, 0x0C, 0x00000000, PPC_SPE
); //
5321 GEN_SPE(evlhhousplatx
, evlhhousplat
, 0x06, 0x0C, 0x00000000, PPC_SPE
); //
5322 GEN_SPE(evlhhossplatx
, evlhhossplat
, 0x07, 0x0C, 0x00000000, PPC_SPE
); //
5323 GEN_SPE(evlwhex
, evlwhe
, 0x08, 0x0C, 0x00000000, PPC_SPE
); //
5324 GEN_SPE(evlwhoux
, evlwhou
, 0x0A, 0x0C, 0x00000000, PPC_SPE
); //
5325 GEN_SPE(evlwhosx
, evlwhos
, 0x0B, 0x0C, 0x00000000, PPC_SPE
); //
5326 GEN_SPE(evlwwsplatx
, evlwwsplat
, 0x0C, 0x0C, 0x00000000, PPC_SPE
); //
5327 GEN_SPE(evlwhsplatx
, evlwhsplat
, 0x0E, 0x0C, 0x00000000, PPC_SPE
); //
5328 GEN_SPE(evstddx
, evstdd
, 0x10, 0x0C, 0x00000000, PPC_SPE
); //
5329 GEN_SPE(evstdwx
, evstdw
, 0x11, 0x0C, 0x00000000, PPC_SPE
); //
5330 GEN_SPE(evstdhx
, evstdh
, 0x12, 0x0C, 0x00000000, PPC_SPE
); //
5331 GEN_SPE(evstwhex
, evstwhe
, 0x18, 0x0C, 0x00000000, PPC_SPE
); //
5332 GEN_SPE(evstwhox
, evstwho
, 0x1A, 0x0C, 0x00000000, PPC_SPE
); //
5333 GEN_SPE(evstwwex
, evstwwe
, 0x1C, 0x0C, 0x00000000, PPC_SPE
); //
5334 GEN_SPE(evstwwox
, evstwwo
, 0x1E, 0x0C, 0x00000000, PPC_SPE
); //
5336 /* Multiply and add - TODO */
5338 GEN_SPE(speundef
, evmhessf
, 0x01, 0x10, 0x00000000, PPC_SPE
);
5339 GEN_SPE(speundef
, evmhossf
, 0x03, 0x10, 0x00000000, PPC_SPE
);
5340 GEN_SPE(evmheumi
, evmhesmi
, 0x04, 0x10, 0x00000000, PPC_SPE
);
5341 GEN_SPE(speundef
, evmhesmf
, 0x05, 0x10, 0x00000000, PPC_SPE
);
5342 GEN_SPE(evmhoumi
, evmhosmi
, 0x06, 0x10, 0x00000000, PPC_SPE
);
5343 GEN_SPE(speundef
, evmhosmf
, 0x07, 0x10, 0x00000000, PPC_SPE
);
5344 GEN_SPE(speundef
, evmhessfa
, 0x11, 0x10, 0x00000000, PPC_SPE
);
5345 GEN_SPE(speundef
, evmhossfa
, 0x13, 0x10, 0x00000000, PPC_SPE
);
5346 GEN_SPE(evmheumia
, evmhesmia
, 0x14, 0x10, 0x00000000, PPC_SPE
);
5347 GEN_SPE(speundef
, evmhesmfa
, 0x15, 0x10, 0x00000000, PPC_SPE
);
5348 GEN_SPE(evmhoumia
, evmhosmia
, 0x16, 0x10, 0x00000000, PPC_SPE
);
5349 GEN_SPE(speundef
, evmhosmfa
, 0x17, 0x10, 0x00000000, PPC_SPE
);
5351 GEN_SPE(speundef
, evmwhssf
, 0x03, 0x11, 0x00000000, PPC_SPE
);
5352 GEN_SPE(evmwlumi
, speundef
, 0x04, 0x11, 0x00000000, PPC_SPE
);
5353 GEN_SPE(evmwhumi
, evmwhsmi
, 0x06, 0x11, 0x00000000, PPC_SPE
);
5354 GEN_SPE(speundef
, evmwhsmf
, 0x07, 0x11, 0x00000000, PPC_SPE
);
5355 GEN_SPE(speundef
, evmwssf
, 0x09, 0x11, 0x00000000, PPC_SPE
);
5356 GEN_SPE(evmwumi
, evmwsmi
, 0x0C, 0x11, 0x00000000, PPC_SPE
);
5357 GEN_SPE(speundef
, evmwsmf
, 0x0D, 0x11, 0x00000000, PPC_SPE
);
5358 GEN_SPE(speundef
, evmwhssfa
, 0x13, 0x11, 0x00000000, PPC_SPE
);
5359 GEN_SPE(evmwlumia
, speundef
, 0x14, 0x11, 0x00000000, PPC_SPE
);
5360 GEN_SPE(evmwhumia
, evmwhsmia
, 0x16, 0x11, 0x00000000, PPC_SPE
);
5361 GEN_SPE(speundef
, evmwhsmfa
, 0x17, 0x11, 0x00000000, PPC_SPE
);
5362 GEN_SPE(speundef
, evmwssfa
, 0x19, 0x11, 0x00000000, PPC_SPE
);
5363 GEN_SPE(evmwumia
, evmwsmia
, 0x1C, 0x11, 0x00000000, PPC_SPE
);
5364 GEN_SPE(speundef
, evmwsmfa
, 0x1D, 0x11, 0x00000000, PPC_SPE
);
5366 GEN_SPE(evadduiaaw
, evaddsiaaw
, 0x00, 0x13, 0x0000F800, PPC_SPE
);
5367 GEN_SPE(evsubfusiaaw
, evsubfssiaaw
, 0x01, 0x13, 0x0000F800, PPC_SPE
);
5368 GEN_SPE(evaddumiaaw
, evaddsmiaaw
, 0x04, 0x13, 0x0000F800, PPC_SPE
);
5369 GEN_SPE(evsubfumiaaw
, evsubfsmiaaw
, 0x05, 0x13, 0x0000F800, PPC_SPE
);
5370 GEN_SPE(evdivws
, evdivwu
, 0x06, 0x13, 0x00000000, PPC_SPE
);
5371 GEN_SPE(evmra
, speundef
, 0x07, 0x13, 0x0000F800, PPC_SPE
);
5373 GEN_SPE(evmheusiaaw
, evmhessiaaw
, 0x00, 0x14, 0x00000000, PPC_SPE
);
5374 GEN_SPE(speundef
, evmhessfaaw
, 0x01, 0x14, 0x00000000, PPC_SPE
);
5375 GEN_SPE(evmhousiaaw
, evmhossiaaw
, 0x02, 0x14, 0x00000000, PPC_SPE
);
5376 GEN_SPE(speundef
, evmhossfaaw
, 0x03, 0x14, 0x00000000, PPC_SPE
);
5377 GEN_SPE(evmheumiaaw
, evmhesmiaaw
, 0x04, 0x14, 0x00000000, PPC_SPE
);
5378 GEN_SPE(speundef
, evmhesmfaaw
, 0x05, 0x14, 0x00000000, PPC_SPE
);
5379 GEN_SPE(evmhoumiaaw
, evmhosmiaaw
, 0x06, 0x14, 0x00000000, PPC_SPE
);
5380 GEN_SPE(speundef
, evmhosmfaaw
, 0x07, 0x14, 0x00000000, PPC_SPE
);
5381 GEN_SPE(evmhegumiaa
, evmhegsmiaa
, 0x14, 0x14, 0x00000000, PPC_SPE
);
5382 GEN_SPE(speundef
, evmhegsmfaa
, 0x15, 0x14, 0x00000000, PPC_SPE
);
5383 GEN_SPE(evmhogumiaa
, evmhogsmiaa
, 0x16, 0x14, 0x00000000, PPC_SPE
);
5384 GEN_SPE(speundef
, evmhogsmfaa
, 0x17, 0x14, 0x00000000, PPC_SPE
);
5386 GEN_SPE(evmwlusiaaw
, evmwlssiaaw
, 0x00, 0x15, 0x00000000, PPC_SPE
);
5387 GEN_SPE(evmwlumiaaw
, evmwlsmiaaw
, 0x04, 0x15, 0x00000000, PPC_SPE
);
5388 GEN_SPE(speundef
, evmwssfaa
, 0x09, 0x15, 0x00000000, PPC_SPE
);
5389 GEN_SPE(evmwumiaa
, evmwsmiaa
, 0x0C, 0x15, 0x00000000, PPC_SPE
);
5390 GEN_SPE(speundef
, evmwsmfaa
, 0x0D, 0x15, 0x00000000, PPC_SPE
);
5392 GEN_SPE(evmheusianw
, evmhessianw
, 0x00, 0x16, 0x00000000, PPC_SPE
);
5393 GEN_SPE(speundef
, evmhessfanw
, 0x01, 0x16, 0x00000000, PPC_SPE
);
5394 GEN_SPE(evmhousianw
, evmhossianw
, 0x02, 0x16, 0x00000000, PPC_SPE
);
5395 GEN_SPE(speundef
, evmhossfanw
, 0x03, 0x16, 0x00000000, PPC_SPE
);
5396 GEN_SPE(evmheumianw
, evmhesmianw
, 0x04, 0x16, 0x00000000, PPC_SPE
);
5397 GEN_SPE(speundef
, evmhesmfanw
, 0x05, 0x16, 0x00000000, PPC_SPE
);
5398 GEN_SPE(evmhoumianw
, evmhosmianw
, 0x06, 0x16, 0x00000000, PPC_SPE
);
5399 GEN_SPE(speundef
, evmhosmfanw
, 0x07, 0x16, 0x00000000, PPC_SPE
);
5400 GEN_SPE(evmhegumian
, evmhegsmian
, 0x14, 0x16, 0x00000000, PPC_SPE
);
5401 GEN_SPE(speundef
, evmhegsmfan
, 0x15, 0x16, 0x00000000, PPC_SPE
);
5402 GEN_SPE(evmhigumian
, evmhigsmian
, 0x16, 0x16, 0x00000000, PPC_SPE
);
5403 GEN_SPE(speundef
, evmhogsmfan
, 0x17, 0x16, 0x00000000, PPC_SPE
);
5405 GEN_SPE(evmwlusianw
, evmwlssianw
, 0x00, 0x17, 0x00000000, PPC_SPE
);
5406 GEN_SPE(evmwlumianw
, evmwlsmianw
, 0x04, 0x17, 0x00000000, PPC_SPE
);
5407 GEN_SPE(speundef
, evmwssfan
, 0x09, 0x17, 0x00000000, PPC_SPE
);
5408 GEN_SPE(evmwumian
, evmwsmian
, 0x0C, 0x17, 0x00000000, PPC_SPE
);
5409 GEN_SPE(speundef
, evmwsmfan
, 0x0D, 0x17, 0x00000000, PPC_SPE
);
5412 /*** SPE floating-point extension ***/
5413 #define GEN_SPEFPUOP_CONV(name) \
5414 static inline void gen_##name (DisasContext *ctx) \
5416 gen_op_load_gpr64_T0(rB(ctx->opcode)); \
5418 gen_op_store_T0_gpr64(rD(ctx->opcode)); \
5421 /* Single precision floating-point vectors operations */
5423 GEN_SPEOP_ARITH2(evfsadd
);
5424 GEN_SPEOP_ARITH2(evfssub
);
5425 GEN_SPEOP_ARITH2(evfsmul
);
5426 GEN_SPEOP_ARITH2(evfsdiv
);
5427 GEN_SPEOP_ARITH1(evfsabs
);
5428 GEN_SPEOP_ARITH1(evfsnabs
);
5429 GEN_SPEOP_ARITH1(evfsneg
);
5431 GEN_SPEFPUOP_CONV(evfscfui
);
5432 GEN_SPEFPUOP_CONV(evfscfsi
);
5433 GEN_SPEFPUOP_CONV(evfscfuf
);
5434 GEN_SPEFPUOP_CONV(evfscfsf
);
5435 GEN_SPEFPUOP_CONV(evfsctui
);
5436 GEN_SPEFPUOP_CONV(evfsctsi
);
5437 GEN_SPEFPUOP_CONV(evfsctuf
);
5438 GEN_SPEFPUOP_CONV(evfsctsf
);
5439 GEN_SPEFPUOP_CONV(evfsctuiz
);
5440 GEN_SPEFPUOP_CONV(evfsctsiz
);
5442 GEN_SPEOP_COMP(evfscmpgt
);
5443 GEN_SPEOP_COMP(evfscmplt
);
5444 GEN_SPEOP_COMP(evfscmpeq
);
5445 GEN_SPEOP_COMP(evfststgt
);
5446 GEN_SPEOP_COMP(evfststlt
);
5447 GEN_SPEOP_COMP(evfststeq
);
5449 /* Opcodes definitions */
5450 GEN_SPE(evfsadd
, evfssub
, 0x00, 0x0A, 0x00000000, PPC_SPEFPU
); //
5451 GEN_SPE(evfsabs
, evfsnabs
, 0x02, 0x0A, 0x0000F800, PPC_SPEFPU
); //
5452 GEN_SPE(evfsneg
, speundef
, 0x03, 0x0A, 0x0000F800, PPC_SPEFPU
); //
5453 GEN_SPE(evfsmul
, evfsdiv
, 0x04, 0x0A, 0x00000000, PPC_SPEFPU
); //
5454 GEN_SPE(evfscmpgt
, evfscmplt
, 0x06, 0x0A, 0x00600000, PPC_SPEFPU
); //
5455 GEN_SPE(evfscmpeq
, speundef
, 0x07, 0x0A, 0x00600000, PPC_SPEFPU
); //
5456 GEN_SPE(evfscfui
, evfscfsi
, 0x08, 0x0A, 0x00180000, PPC_SPEFPU
); //
5457 GEN_SPE(evfscfuf
, evfscfsf
, 0x09, 0x0A, 0x00180000, PPC_SPEFPU
); //
5458 GEN_SPE(evfsctui
, evfsctsi
, 0x0A, 0x0A, 0x00180000, PPC_SPEFPU
); //
5459 GEN_SPE(evfsctuf
, evfsctsf
, 0x0B, 0x0A, 0x00180000, PPC_SPEFPU
); //
5460 GEN_SPE(evfsctuiz
, speundef
, 0x0C, 0x0A, 0x00180000, PPC_SPEFPU
); //
5461 GEN_SPE(evfsctsiz
, speundef
, 0x0D, 0x0A, 0x00180000, PPC_SPEFPU
); //
5462 GEN_SPE(evfststgt
, evfststlt
, 0x0E, 0x0A, 0x00600000, PPC_SPEFPU
); //
5463 GEN_SPE(evfststeq
, speundef
, 0x0F, 0x0A, 0x00600000, PPC_SPEFPU
); //
5465 /* Single precision floating-point operations */
5467 GEN_SPEOP_ARITH2(efsadd
);
5468 GEN_SPEOP_ARITH2(efssub
);
5469 GEN_SPEOP_ARITH2(efsmul
);
5470 GEN_SPEOP_ARITH2(efsdiv
);
5471 GEN_SPEOP_ARITH1(efsabs
);
5472 GEN_SPEOP_ARITH1(efsnabs
);
5473 GEN_SPEOP_ARITH1(efsneg
);
5475 GEN_SPEFPUOP_CONV(efscfui
);
5476 GEN_SPEFPUOP_CONV(efscfsi
);
5477 GEN_SPEFPUOP_CONV(efscfuf
);
5478 GEN_SPEFPUOP_CONV(efscfsf
);
5479 GEN_SPEFPUOP_CONV(efsctui
);
5480 GEN_SPEFPUOP_CONV(efsctsi
);
5481 GEN_SPEFPUOP_CONV(efsctuf
);
5482 GEN_SPEFPUOP_CONV(efsctsf
);
5483 GEN_SPEFPUOP_CONV(efsctuiz
);
5484 GEN_SPEFPUOP_CONV(efsctsiz
);
5485 GEN_SPEFPUOP_CONV(efscfd
);
5487 GEN_SPEOP_COMP(efscmpgt
);
5488 GEN_SPEOP_COMP(efscmplt
);
5489 GEN_SPEOP_COMP(efscmpeq
);
5490 GEN_SPEOP_COMP(efststgt
);
5491 GEN_SPEOP_COMP(efststlt
);
5492 GEN_SPEOP_COMP(efststeq
);
5494 /* Opcodes definitions */
5495 GEN_SPE(efsadd
, efssub
, 0x00, 0x0A, 0x00000000, PPC_SPEFPU
); //
5496 GEN_SPE(efsabs
, efsnabs
, 0x02, 0x0B, 0x0000F800, PPC_SPEFPU
); //
5497 GEN_SPE(efsneg
, speundef
, 0x03, 0x0B, 0x0000F800, PPC_SPEFPU
); //
5498 GEN_SPE(efsmul
, efsdiv
, 0x04, 0x0B, 0x00000000, PPC_SPEFPU
); //
5499 GEN_SPE(efscmpgt
, efscmplt
, 0x06, 0x0B, 0x00600000, PPC_SPEFPU
); //
5500 GEN_SPE(efscmpeq
, efscfd
, 0x07, 0x0B, 0x00600000, PPC_SPEFPU
); //
5501 GEN_SPE(efscfui
, efscfsi
, 0x08, 0x0B, 0x00180000, PPC_SPEFPU
); //
5502 GEN_SPE(efscfuf
, efscfsf
, 0x09, 0x0B, 0x00180000, PPC_SPEFPU
); //
5503 GEN_SPE(efsctui
, efsctsi
, 0x0A, 0x0B, 0x00180000, PPC_SPEFPU
); //
5504 GEN_SPE(efsctuf
, efsctsf
, 0x0B, 0x0B, 0x00180000, PPC_SPEFPU
); //
5505 GEN_SPE(efsctuiz
, efsctsiz
, 0x0C, 0x0B, 0x00180000, PPC_SPEFPU
); //
5506 GEN_SPE(efststgt
, efststlt
, 0x0E, 0x0B, 0x00600000, PPC_SPEFPU
); //
5507 GEN_SPE(efststeq
, speundef
, 0x0F, 0x0B, 0x00600000, PPC_SPEFPU
); //
5509 /* Double precision floating-point operations */
5511 GEN_SPEOP_ARITH2(efdadd
);
5512 GEN_SPEOP_ARITH2(efdsub
);
5513 GEN_SPEOP_ARITH2(efdmul
);
5514 GEN_SPEOP_ARITH2(efddiv
);
5515 GEN_SPEOP_ARITH1(efdabs
);
5516 GEN_SPEOP_ARITH1(efdnabs
);
5517 GEN_SPEOP_ARITH1(efdneg
);
5520 GEN_SPEFPUOP_CONV(efdcfui
);
5521 GEN_SPEFPUOP_CONV(efdcfsi
);
5522 GEN_SPEFPUOP_CONV(efdcfuf
);
5523 GEN_SPEFPUOP_CONV(efdcfsf
);
5524 GEN_SPEFPUOP_CONV(efdctui
);
5525 GEN_SPEFPUOP_CONV(efdctsi
);
5526 GEN_SPEFPUOP_CONV(efdctuf
);
5527 GEN_SPEFPUOP_CONV(efdctsf
);
5528 GEN_SPEFPUOP_CONV(efdctuiz
);
5529 GEN_SPEFPUOP_CONV(efdctsiz
);
5530 GEN_SPEFPUOP_CONV(efdcfs
);
5531 GEN_SPEFPUOP_CONV(efdcfuid
);
5532 GEN_SPEFPUOP_CONV(efdcfsid
);
5533 GEN_SPEFPUOP_CONV(efdctuidz
);
5534 GEN_SPEFPUOP_CONV(efdctsidz
);
5536 GEN_SPEOP_COMP(efdcmpgt
);
5537 GEN_SPEOP_COMP(efdcmplt
);
5538 GEN_SPEOP_COMP(efdcmpeq
);
5539 GEN_SPEOP_COMP(efdtstgt
);
5540 GEN_SPEOP_COMP(efdtstlt
);
5541 GEN_SPEOP_COMP(efdtsteq
);
5543 /* Opcodes definitions */
5544 GEN_SPE(efdadd
, efdsub
, 0x10, 0x0B, 0x00000000, PPC_SPEFPU
); //
5545 GEN_SPE(efdcfuid
, efdcfsid
, 0x11, 0x0B, 0x00180000, PPC_SPEFPU
); //
5546 GEN_SPE(efdabs
, efdnabs
, 0x12, 0x0B, 0x0000F800, PPC_SPEFPU
); //
5547 GEN_SPE(efdneg
, speundef
, 0x13, 0x0B, 0x0000F800, PPC_SPEFPU
); //
5548 GEN_SPE(efdmul
, efddiv
, 0x14, 0x0B, 0x00000000, PPC_SPEFPU
); //
5549 GEN_SPE(efdctuidz
, efdctsidz
, 0x15, 0x0B, 0x00180000, PPC_SPEFPU
); //
5550 GEN_SPE(efdcmpgt
, efdcmplt
, 0x16, 0x0B, 0x00600000, PPC_SPEFPU
); //
5551 GEN_SPE(efdcmpeq
, efdcfs
, 0x17, 0x0B, 0x00600000, PPC_SPEFPU
); //
5552 GEN_SPE(efdcfui
, efdcfsi
, 0x18, 0x0B, 0x00180000, PPC_SPEFPU
); //
5553 GEN_SPE(efdcfuf
, efdcfsf
, 0x19, 0x0B, 0x00180000, PPC_SPEFPU
); //
5554 GEN_SPE(efdctui
, efdctsi
, 0x1A, 0x0B, 0x00180000, PPC_SPEFPU
); //
5555 GEN_SPE(efdctuf
, efdctsf
, 0x1B, 0x0B, 0x00180000, PPC_SPEFPU
); //
5556 GEN_SPE(efdctuiz
, speundef
, 0x1C, 0x0B, 0x00180000, PPC_SPEFPU
); //
5557 GEN_SPE(efdctsiz
, speundef
, 0x1D, 0x0B, 0x00180000, PPC_SPEFPU
); //
5558 GEN_SPE(efdtstgt
, efdtstlt
, 0x1E, 0x0B, 0x00600000, PPC_SPEFPU
); //
5559 GEN_SPE(efdtsteq
, speundef
, 0x1F, 0x0B, 0x00600000, PPC_SPEFPU
); //
5562 /* End opcode list */
5563 GEN_OPCODE_MARK(end
);
5565 #include "translate_init.c"
5567 /*****************************************************************************/
5568 /* Misc PowerPC helpers */
5569 static inline uint32_t load_xer (CPUState
*env
)
5571 return (xer_so
<< XER_SO
) |
5572 (xer_ov
<< XER_OV
) |
5573 (xer_ca
<< XER_CA
) |
5574 (xer_bc
<< XER_BC
) |
5575 (xer_cmp
<< XER_CMP
);
5578 void cpu_dump_state(CPUState
*env
, FILE *f
,
5579 int (*cpu_fprintf
)(FILE *f
, const char *fmt
, ...),
5582 #if defined(TARGET_PPC64) || 1
5594 cpu_fprintf(f
, "NIP " ADDRX
" LR " ADDRX
" CTR " ADDRX
"\n",
5595 env
->nip
, env
->lr
, env
->ctr
);
5596 cpu_fprintf(f
, "MSR " REGX FILL
" XER %08x "
5597 #if !defined(NO_TIMER_DUMP)
5599 #if !defined(CONFIG_USER_ONLY)
5604 do_load_msr(env
), load_xer(env
)
5605 #if !defined(NO_TIMER_DUMP)
5606 , cpu_ppc_load_tbu(env
), cpu_ppc_load_tbl(env
)
5607 #if !defined(CONFIG_USER_ONLY)
5608 , cpu_ppc_load_decr(env
)
5612 for (i
= 0; i
< 32; i
++) {
5613 if ((i
& (RGPL
- 1)) == 0)
5614 cpu_fprintf(f
, "GPR%02d", i
);
5615 cpu_fprintf(f
, " " REGX
, env
->gpr
[i
]);
5616 if ((i
& (RGPL
- 1)) == (RGPL
- 1))
5617 cpu_fprintf(f
, "\n");
5619 cpu_fprintf(f
, "CR ");
5620 for (i
= 0; i
< 8; i
++)
5621 cpu_fprintf(f
, "%01x", env
->crf
[i
]);
5622 cpu_fprintf(f
, " [");
5623 for (i
= 0; i
< 8; i
++) {
5625 if (env
->crf
[i
] & 0x08)
5627 else if (env
->crf
[i
] & 0x04)
5629 else if (env
->crf
[i
] & 0x02)
5631 cpu_fprintf(f
, " %c%c", a
, env
->crf
[i
] & 0x01 ? 'O' : ' ');
5633 cpu_fprintf(f
, " ] " FILL
"RES " REGX
"\n", env
->reserve
);
5634 for (i
= 0; i
< 32; i
++) {
5635 if ((i
& (RFPL
- 1)) == 0)
5636 cpu_fprintf(f
, "FPR%02d", i
);
5637 cpu_fprintf(f
, " %016" PRIx64
, *((uint64_t *)&env
->fpr
[i
]));
5638 if ((i
& (RFPL
- 1)) == (RFPL
- 1))
5639 cpu_fprintf(f
, "\n");
5641 cpu_fprintf(f
, "SRR0 " REGX
" SRR1 " REGX
" " FILL FILL FILL
5643 env
->spr
[SPR_SRR0
], env
->spr
[SPR_SRR1
], env
->sdr1
);
5650 void cpu_dump_statistics (CPUState
*env
, FILE*f
,
5651 int (*cpu_fprintf
)(FILE *f
, const char *fmt
, ...),
5654 #if defined(DO_PPC_STATISTICS)
5655 opc_handler_t
**t1
, **t2
, **t3
, *handler
;
5659 for (op1
= 0; op1
< 64; op1
++) {
5661 if (is_indirect_opcode(handler
)) {
5662 t2
= ind_table(handler
);
5663 for (op2
= 0; op2
< 32; op2
++) {
5665 if (is_indirect_opcode(handler
)) {
5666 t3
= ind_table(handler
);
5667 for (op3
= 0; op3
< 32; op3
++) {
5669 if (handler
->count
== 0)
5671 cpu_fprintf(f
, "%02x %02x %02x (%02x %04d) %16s: "
5673 op1
, op2
, op3
, op1
, (op3
<< 5) | op2
,
5675 handler
->count
, handler
->count
);
5678 if (handler
->count
== 0)
5680 cpu_fprintf(f
, "%02x %02x (%02x %04d) %16s: "
5682 op1
, op2
, op1
, op2
, handler
->oname
,
5683 handler
->count
, handler
->count
);
5687 if (handler
->count
== 0)
5689 cpu_fprintf(f
, "%02x (%02x ) %16s: %016llx %lld\n",
5690 op1
, op1
, handler
->oname
,
5691 handler
->count
, handler
->count
);
5697 /*****************************************************************************/
5698 static inline int gen_intermediate_code_internal (CPUState
*env
,
5699 TranslationBlock
*tb
,
5702 DisasContext ctx
, *ctxp
= &ctx
;
5703 opc_handler_t
**table
, *handler
;
5704 target_ulong pc_start
;
5705 uint16_t *gen_opc_end
;
5709 gen_opc_ptr
= gen_opc_buf
;
5710 gen_opc_end
= gen_opc_buf
+ OPC_MAX_SIZE
;
5711 gen_opparam_ptr
= gen_opparam_buf
;
5715 ctx
.exception
= EXCP_NONE
;
5716 ctx
.spr_cb
= env
->spr_cb
;
5717 #if defined(CONFIG_USER_ONLY)
5718 ctx
.mem_idx
= msr_le
;
5719 #if defined(TARGET_PPC64)
5720 ctx
.mem_idx
|= msr_sf
<< 1;
5723 ctx
.supervisor
= 1 - msr_pr
;
5724 ctx
.mem_idx
= ((1 - msr_pr
) << 1) | msr_le
;
5725 #if defined(TARGET_PPC64)
5726 ctx
.mem_idx
|= msr_sf
<< 2;
5729 #if defined(TARGET_PPC64)
5730 ctx
.sf_mode
= msr_sf
;
5732 ctx
.fpu_enabled
= msr_fp
;
5733 #if defined(TARGET_PPCSPE)
5734 ctx
.spe_enabled
= msr_spe
;
5736 ctx
.singlestep_enabled
= env
->singlestep_enabled
;
5737 #if defined (DO_SINGLE_STEP) && 0
5738 /* Single step trace mode */
5741 /* Set env in case of segfault during code fetch */
5742 while (ctx
.exception
== EXCP_NONE
&& gen_opc_ptr
< gen_opc_end
) {
5743 if (unlikely(env
->nb_breakpoints
> 0)) {
5744 for (j
= 0; j
< env
->nb_breakpoints
; j
++) {
5745 if (env
->breakpoints
[j
] == ctx
.nip
) {
5746 gen_update_nip(&ctx
, ctx
.nip
);
5752 if (unlikely(search_pc
)) {
5753 j
= gen_opc_ptr
- gen_opc_buf
;
5757 gen_opc_instr_start
[lj
++] = 0;
5758 gen_opc_pc
[lj
] = ctx
.nip
;
5759 gen_opc_instr_start
[lj
] = 1;
5762 #if defined PPC_DEBUG_DISAS
5763 if (loglevel
& CPU_LOG_TB_IN_ASM
) {
5764 fprintf(logfile
, "----------------\n");
5765 fprintf(logfile
, "nip=" ADDRX
" super=%d ir=%d\n",
5766 ctx
.nip
, 1 - msr_pr
, msr_ir
);
5769 ctx
.opcode
= ldl_code(ctx
.nip
);
5771 ctx
.opcode
= ((ctx
.opcode
& 0xFF000000) >> 24) |
5772 ((ctx
.opcode
& 0x00FF0000) >> 8) |
5773 ((ctx
.opcode
& 0x0000FF00) << 8) |
5774 ((ctx
.opcode
& 0x000000FF) << 24);
5776 #if defined PPC_DEBUG_DISAS
5777 if (loglevel
& CPU_LOG_TB_IN_ASM
) {
5778 fprintf(logfile
, "translate opcode %08x (%02x %02x %02x) (%s)\n",
5779 ctx
.opcode
, opc1(ctx
.opcode
), opc2(ctx
.opcode
),
5780 opc3(ctx
.opcode
), msr_le
? "little" : "big");
5784 table
= env
->opcodes
;
5785 handler
= table
[opc1(ctx
.opcode
)];
5786 if (is_indirect_opcode(handler
)) {
5787 table
= ind_table(handler
);
5788 handler
= table
[opc2(ctx
.opcode
)];
5789 if (is_indirect_opcode(handler
)) {
5790 table
= ind_table(handler
);
5791 handler
= table
[opc3(ctx
.opcode
)];
5794 /* Is opcode *REALLY* valid ? */
5795 if (unlikely(handler
->handler
== &gen_invalid
)) {
5797 fprintf(logfile
, "invalid/unsupported opcode: "
5798 "%02x - %02x - %02x (%08x) 0x" ADDRX
" %d\n",
5799 opc1(ctx
.opcode
), opc2(ctx
.opcode
),
5800 opc3(ctx
.opcode
), ctx
.opcode
, ctx
.nip
- 4, msr_ir
);
5802 printf("invalid/unsupported opcode: "
5803 "%02x - %02x - %02x (%08x) 0x" ADDRX
" %d\n",
5804 opc1(ctx
.opcode
), opc2(ctx
.opcode
),
5805 opc3(ctx
.opcode
), ctx
.opcode
, ctx
.nip
- 4, msr_ir
);
5808 if (unlikely((ctx
.opcode
& handler
->inval
) != 0)) {
5810 fprintf(logfile
, "invalid bits: %08x for opcode: "
5811 "%02x -%02x - %02x (%08x) 0x" ADDRX
"\n",
5812 ctx
.opcode
& handler
->inval
, opc1(ctx
.opcode
),
5813 opc2(ctx
.opcode
), opc3(ctx
.opcode
),
5814 ctx
.opcode
, ctx
.nip
- 4);
5816 printf("invalid bits: %08x for opcode: "
5817 "%02x -%02x - %02x (%08x) 0x" ADDRX
"\n",
5818 ctx
.opcode
& handler
->inval
, opc1(ctx
.opcode
),
5819 opc2(ctx
.opcode
), opc3(ctx
.opcode
),
5820 ctx
.opcode
, ctx
.nip
- 4);
5826 (*(handler
->handler
))(&ctx
);
5827 #if defined(DO_PPC_STATISTICS)
5830 /* Check trace mode exceptions */
5831 if (unlikely((msr_be
&& ctx
.exception
== EXCP_BRANCH
) ||
5832 /* Check in single step trace mode
5833 * we need to stop except if:
5834 * - rfi, trap or syscall
5835 * - first instruction of an exception handler
5837 (msr_se
&& (ctx
.nip
< 0x100 ||
5839 (ctx
.nip
& 0xFC) != 0x04) &&
5840 ctx
.exception
!= EXCP_SYSCALL
&&
5841 ctx
.exception
!= EXCP_SYSCALL_USER
&&
5842 ctx
.exception
!= EXCP_TRAP
))) {
5843 RET_EXCP(ctxp
, EXCP_TRACE
, 0);
5845 /* if we reach a page boundary or are single stepping, stop
5848 if (unlikely(((ctx
.nip
& (TARGET_PAGE_SIZE
- 1)) == 0) ||
5849 (env
->singlestep_enabled
))) {
5852 #if defined (DO_SINGLE_STEP)
5856 if (ctx
.exception
== EXCP_NONE
) {
5857 gen_goto_tb(&ctx
, 0, ctx
.nip
);
5858 } else if (ctx
.exception
!= EXCP_BRANCH
) {
5860 /* Generate the return instruction */
5863 *gen_opc_ptr
= INDEX_op_end
;
5864 if (unlikely(search_pc
)) {
5865 j
= gen_opc_ptr
- gen_opc_buf
;
5868 gen_opc_instr_start
[lj
++] = 0;
5871 tb
->size
= ctx
.nip
- pc_start
;
5873 #if defined(DEBUG_DISAS)
5874 if (loglevel
& CPU_LOG_TB_CPU
) {
5875 fprintf(logfile
, "---------------- excp: %04x\n", ctx
.exception
);
5876 cpu_dump_state(env
, logfile
, fprintf
, 0);
5878 if (loglevel
& CPU_LOG_TB_IN_ASM
) {
5881 fprintf(logfile
, "IN: %s\n", lookup_symbol(pc_start
));
5882 target_disas(logfile
, pc_start
, ctx
.nip
- pc_start
, flags
);
5883 fprintf(logfile
, "\n");
5885 if (loglevel
& CPU_LOG_TB_OP
) {
5886 fprintf(logfile
, "OP:\n");
5887 dump_ops(gen_opc_buf
, gen_opparam_buf
);
5888 fprintf(logfile
, "\n");
5894 int gen_intermediate_code (CPUState
*env
, struct TranslationBlock
*tb
)
5896 return gen_intermediate_code_internal(env
, tb
, 0);
5899 int gen_intermediate_code_pc (CPUState
*env
, struct TranslationBlock
*tb
)
5901 return gen_intermediate_code_internal(env
, tb
, 1);