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 DEBUG_MEMORY_ACCESSES
33 //#define DO_PPC_STATISTICS
35 #if defined(USE_DIRECT_JUMP)
38 #define TBPARAM(x) (long)(x)
42 #define DEF(s, n, copy_size) INDEX_op_ ## s,
48 static uint16_t *gen_opc_ptr
;
49 static uint32_t *gen_opparam_ptr
;
53 static inline void gen_set_T0 (target_ulong val
)
55 #if defined(TARGET_PPC64)
57 gen_op_set_T0_64(val
>> 32, val
);
63 static inline void gen_set_T1 (target_ulong val
)
65 #if defined(TARGET_PPC64)
67 gen_op_set_T1_64(val
>> 32, val
);
73 #define GEN8(func, NAME) \
74 static GenOpFunc *NAME ## _table [8] = { \
75 NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3, \
76 NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7, \
78 static inline void func(int n) \
80 NAME ## _table[n](); \
83 #define GEN16(func, NAME) \
84 static GenOpFunc *NAME ## _table [16] = { \
85 NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3, \
86 NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7, \
87 NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11, \
88 NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15, \
90 static inline void func(int n) \
92 NAME ## _table[n](); \
95 #define GEN32(func, NAME) \
96 static GenOpFunc *NAME ## _table [32] = { \
97 NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3, \
98 NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7, \
99 NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11, \
100 NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15, \
101 NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19, \
102 NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23, \
103 NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27, \
104 NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31, \
106 static inline void func(int n) \
108 NAME ## _table[n](); \
111 /* Condition register moves */
112 GEN8(gen_op_load_crf_T0
, gen_op_load_crf_T0_crf
);
113 GEN8(gen_op_load_crf_T1
, gen_op_load_crf_T1_crf
);
114 GEN8(gen_op_store_T0_crf
, gen_op_store_T0_crf_crf
);
115 GEN8(gen_op_store_T1_crf
, gen_op_store_T1_crf_crf
);
117 /* Floating point condition and status register moves */
118 GEN8(gen_op_load_fpscr_T0
, gen_op_load_fpscr_T0_fpscr
);
119 GEN8(gen_op_store_T0_fpscr
, gen_op_store_T0_fpscr_fpscr
);
120 GEN8(gen_op_clear_fpscr
, gen_op_clear_fpscr_fpscr
);
121 static inline void gen_op_store_T0_fpscri(int n
, uint8_t param
)
123 gen_op_set_T0(param
);
124 gen_op_store_T0_fpscr(n
);
127 /* General purpose registers moves */
128 GEN32(gen_op_load_gpr_T0
, gen_op_load_gpr_T0_gpr
);
129 GEN32(gen_op_load_gpr_T1
, gen_op_load_gpr_T1_gpr
);
130 GEN32(gen_op_load_gpr_T2
, gen_op_load_gpr_T2_gpr
);
132 GEN32(gen_op_store_T0_gpr
, gen_op_store_T0_gpr_gpr
);
133 GEN32(gen_op_store_T1_gpr
, gen_op_store_T1_gpr_gpr
);
135 GEN32(gen_op_store_T2_gpr
, gen_op_store_T2_gpr_gpr
);
138 /* floating point registers moves */
139 GEN32(gen_op_load_fpr_FT0
, gen_op_load_fpr_FT0_fpr
);
140 GEN32(gen_op_load_fpr_FT1
, gen_op_load_fpr_FT1_fpr
);
141 GEN32(gen_op_load_fpr_FT2
, gen_op_load_fpr_FT2_fpr
);
142 GEN32(gen_op_store_FT0_fpr
, gen_op_store_FT0_fpr_fpr
);
143 GEN32(gen_op_store_FT1_fpr
, gen_op_store_FT1_fpr_fpr
);
145 GEN32(gen_op_store_FT2_fpr
, gen_op_store_FT2_fpr_fpr
);
148 /* internal defines */
149 typedef struct DisasContext
{
150 struct TranslationBlock
*tb
;
154 /* Routine used to access memory */
156 /* Translation flags */
157 #if !defined(CONFIG_USER_ONLY)
160 #if defined(TARGET_PPC64)
164 #if defined(TARGET_PPCEMB)
167 ppc_spr_t
*spr_cb
; /* Needed to check rights for mfspr/mtspr */
168 int singlestep_enabled
;
171 struct opc_handler_t
{
174 /* instruction type */
177 void (*handler
)(DisasContext
*ctx
);
178 #if defined(DO_PPC_STATISTICS)
179 const unsigned char *oname
;
184 static inline void gen_set_Rc0 (DisasContext
*ctx
)
186 #if defined(TARGET_PPC64)
195 static inline void gen_update_nip (DisasContext
*ctx
, target_ulong nip
)
197 #if defined(TARGET_PPC64)
199 gen_op_update_nip_64(nip
>> 32, nip
);
202 gen_op_update_nip(nip
);
205 #define RET_EXCP(ctx, excp, error) \
207 if ((ctx)->exception == EXCP_NONE) { \
208 gen_update_nip(ctx, (ctx)->nip); \
210 gen_op_raise_exception_err((excp), (error)); \
211 ctx->exception = (excp); \
214 #define RET_INVAL(ctx) \
215 RET_EXCP((ctx), EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_INVAL)
217 #define RET_PRIVOPC(ctx) \
218 RET_EXCP((ctx), EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_OPC)
220 #define RET_PRIVREG(ctx) \
221 RET_EXCP((ctx), EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_REG)
223 /* Stop translation */
224 static inline void RET_STOP (DisasContext
*ctx
)
226 gen_update_nip(ctx
, ctx
->nip
);
227 ctx
->exception
= EXCP_MTMSR
;
230 /* No need to update nip here, as execution flow will change */
231 static inline void RET_CHG_FLOW (DisasContext
*ctx
)
233 ctx
->exception
= EXCP_MTMSR
;
236 #define GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \
237 static void gen_##name (DisasContext *ctx); \
238 GEN_OPCODE(name, opc1, opc2, opc3, inval, type); \
239 static void gen_##name (DisasContext *ctx)
241 typedef struct opcode_t
{
242 unsigned char opc1
, opc2
, opc3
;
243 #if HOST_LONG_BITS == 64 /* Explicitely align to 64 bits */
244 unsigned char pad
[5];
246 unsigned char pad
[1];
248 opc_handler_t handler
;
249 const unsigned char *oname
;
252 /*** Instruction decoding ***/
253 #define EXTRACT_HELPER(name, shift, nb) \
254 static inline uint32_t name (uint32_t opcode) \
256 return (opcode >> (shift)) & ((1 << (nb)) - 1); \
259 #define EXTRACT_SHELPER(name, shift, nb) \
260 static inline int32_t name (uint32_t opcode) \
262 return (int16_t)((opcode >> (shift)) & ((1 << (nb)) - 1)); \
266 EXTRACT_HELPER(opc1
, 26, 6);
268 EXTRACT_HELPER(opc2
, 1, 5);
270 EXTRACT_HELPER(opc3
, 6, 5);
271 /* Update Cr0 flags */
272 EXTRACT_HELPER(Rc
, 0, 1);
274 EXTRACT_HELPER(rD
, 21, 5);
276 EXTRACT_HELPER(rS
, 21, 5);
278 EXTRACT_HELPER(rA
, 16, 5);
280 EXTRACT_HELPER(rB
, 11, 5);
282 EXTRACT_HELPER(rC
, 6, 5);
284 EXTRACT_HELPER(crfD
, 23, 3);
285 EXTRACT_HELPER(crfS
, 18, 3);
286 EXTRACT_HELPER(crbD
, 21, 5);
287 EXTRACT_HELPER(crbA
, 16, 5);
288 EXTRACT_HELPER(crbB
, 11, 5);
290 EXTRACT_HELPER(_SPR
, 11, 10);
291 static inline uint32_t SPR (uint32_t opcode
)
293 uint32_t sprn
= _SPR(opcode
);
295 return ((sprn
>> 5) & 0x1F) | ((sprn
& 0x1F) << 5);
297 /*** Get constants ***/
298 EXTRACT_HELPER(IMM
, 12, 8);
299 /* 16 bits signed immediate value */
300 EXTRACT_SHELPER(SIMM
, 0, 16);
301 /* 16 bits unsigned immediate value */
302 EXTRACT_HELPER(UIMM
, 0, 16);
304 EXTRACT_HELPER(NB
, 11, 5);
306 EXTRACT_HELPER(SH
, 11, 5);
308 EXTRACT_HELPER(MB
, 6, 5);
310 EXTRACT_HELPER(ME
, 1, 5);
312 EXTRACT_HELPER(TO
, 21, 5);
314 EXTRACT_HELPER(CRM
, 12, 8);
315 EXTRACT_HELPER(FM
, 17, 8);
316 EXTRACT_HELPER(SR
, 16, 4);
317 EXTRACT_HELPER(FPIMM
, 20, 4);
319 /*** Jump target decoding ***/
321 EXTRACT_SHELPER(d
, 0, 16);
322 /* Immediate address */
323 static inline target_ulong
LI (uint32_t opcode
)
325 return (opcode
>> 0) & 0x03FFFFFC;
328 static inline uint32_t BD (uint32_t opcode
)
330 return (opcode
>> 0) & 0xFFFC;
333 EXTRACT_HELPER(BO
, 21, 5);
334 EXTRACT_HELPER(BI
, 16, 5);
335 /* Absolute/relative address */
336 EXTRACT_HELPER(AA
, 1, 1);
338 EXTRACT_HELPER(LK
, 0, 1);
340 /* Create a mask between <start> and <end> bits */
341 static inline target_ulong
MASK (uint32_t start
, uint32_t end
)
345 #if defined(TARGET_PPC64)
346 if (likely(start
== 0)) {
347 ret
= (uint64_t)(-1ULL) << (63 - end
);
348 } else if (likely(end
== 63)) {
349 ret
= (uint64_t)(-1ULL) >> start
;
352 if (likely(start
== 0)) {
353 ret
= (uint32_t)(-1ULL) << (31 - end
);
354 } else if (likely(end
== 31)) {
355 ret
= (uint32_t)(-1ULL) >> start
;
359 ret
= (((target_ulong
)(-1ULL)) >> (start
)) ^
360 (((target_ulong
)(-1ULL) >> (end
)) >> 1);
361 if (unlikely(start
> end
))
368 #if HOST_LONG_BITS == 64
373 #if defined(__APPLE__)
374 #define OPCODES_SECTION \
375 __attribute__ ((section("__TEXT,__opcodes"), unused, aligned (OPC_ALIGN) ))
377 #define OPCODES_SECTION \
378 __attribute__ ((section(".opcodes"), unused, aligned (OPC_ALIGN) ))
381 #if defined(DO_PPC_STATISTICS)
382 #define GEN_OPCODE(name, op1, op2, op3, invl, _typ) \
383 OPCODES_SECTION opcode_t opc_##name = { \
391 .handler = &gen_##name, \
392 .oname = stringify(name), \
394 .oname = stringify(name), \
397 #define GEN_OPCODE(name, op1, op2, op3, invl, _typ) \
398 OPCODES_SECTION opcode_t opc_##name = { \
406 .handler = &gen_##name, \
408 .oname = stringify(name), \
412 #define GEN_OPCODE_MARK(name) \
413 OPCODES_SECTION opcode_t opc_##name = { \
419 .inval = 0x00000000, \
423 .oname = stringify(name), \
426 /* Start opcode list */
427 GEN_OPCODE_MARK(start
);
429 /* Invalid instruction */
430 GEN_HANDLER(invalid
, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE
)
435 static opc_handler_t invalid_handler
= {
438 .handler
= gen_invalid
,
441 /*** Integer arithmetic ***/
442 #define __GEN_INT_ARITH2(name, opc1, opc2, opc3, inval, type) \
443 GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \
445 gen_op_load_gpr_T0(rA(ctx->opcode)); \
446 gen_op_load_gpr_T1(rB(ctx->opcode)); \
448 gen_op_store_T0_gpr(rD(ctx->opcode)); \
449 if (unlikely(Rc(ctx->opcode) != 0)) \
453 #define __GEN_INT_ARITH2_O(name, opc1, opc2, opc3, inval, type) \
454 GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \
456 gen_op_load_gpr_T0(rA(ctx->opcode)); \
457 gen_op_load_gpr_T1(rB(ctx->opcode)); \
459 gen_op_store_T0_gpr(rD(ctx->opcode)); \
460 if (unlikely(Rc(ctx->opcode) != 0)) \
464 #define __GEN_INT_ARITH1(name, opc1, opc2, opc3, type) \
465 GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type) \
467 gen_op_load_gpr_T0(rA(ctx->opcode)); \
469 gen_op_store_T0_gpr(rD(ctx->opcode)); \
470 if (unlikely(Rc(ctx->opcode) != 0)) \
473 #define __GEN_INT_ARITH1_O(name, opc1, opc2, opc3, type) \
474 GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type) \
476 gen_op_load_gpr_T0(rA(ctx->opcode)); \
478 gen_op_store_T0_gpr(rD(ctx->opcode)); \
479 if (unlikely(Rc(ctx->opcode) != 0)) \
483 /* Two operands arithmetic functions */
484 #define GEN_INT_ARITH2(name, opc1, opc2, opc3, type) \
485 __GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000000, type) \
486 __GEN_INT_ARITH2_O(name##o, opc1, opc2, opc3 | 0x10, 0x00000000, type)
488 /* Two operands arithmetic functions with no overflow allowed */
489 #define GEN_INT_ARITHN(name, opc1, opc2, opc3, type) \
490 __GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000400, type)
492 /* One operand arithmetic functions */
493 #define GEN_INT_ARITH1(name, opc1, opc2, opc3, type) \
494 __GEN_INT_ARITH1(name, opc1, opc2, opc3, type) \
495 __GEN_INT_ARITH1_O(name##o, opc1, opc2, opc3 | 0x10, type)
497 #if defined(TARGET_PPC64)
498 #define __GEN_INT_ARITH2_64(name, opc1, opc2, opc3, inval, type) \
499 GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \
501 gen_op_load_gpr_T0(rA(ctx->opcode)); \
502 gen_op_load_gpr_T1(rB(ctx->opcode)); \
504 gen_op_##name##_64(); \
507 gen_op_store_T0_gpr(rD(ctx->opcode)); \
508 if (unlikely(Rc(ctx->opcode) != 0)) \
512 #define __GEN_INT_ARITH2_O_64(name, opc1, opc2, opc3, inval, type) \
513 GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \
515 gen_op_load_gpr_T0(rA(ctx->opcode)); \
516 gen_op_load_gpr_T1(rB(ctx->opcode)); \
518 gen_op_##name##_64(); \
521 gen_op_store_T0_gpr(rD(ctx->opcode)); \
522 if (unlikely(Rc(ctx->opcode) != 0)) \
526 #define __GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type) \
527 GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type) \
529 gen_op_load_gpr_T0(rA(ctx->opcode)); \
531 gen_op_##name##_64(); \
534 gen_op_store_T0_gpr(rD(ctx->opcode)); \
535 if (unlikely(Rc(ctx->opcode) != 0)) \
538 #define __GEN_INT_ARITH1_O_64(name, opc1, opc2, opc3, type) \
539 GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type) \
541 gen_op_load_gpr_T0(rA(ctx->opcode)); \
543 gen_op_##name##_64(); \
546 gen_op_store_T0_gpr(rD(ctx->opcode)); \
547 if (unlikely(Rc(ctx->opcode) != 0)) \
551 /* Two operands arithmetic functions */
552 #define GEN_INT_ARITH2_64(name, opc1, opc2, opc3, type) \
553 __GEN_INT_ARITH2_64(name, opc1, opc2, opc3, 0x00000000, type) \
554 __GEN_INT_ARITH2_O_64(name##o, opc1, opc2, opc3 | 0x10, 0x00000000, type)
556 /* Two operands arithmetic functions with no overflow allowed */
557 #define GEN_INT_ARITHN_64(name, opc1, opc2, opc3, type) \
558 __GEN_INT_ARITH2_64(name, opc1, opc2, opc3, 0x00000400, type)
560 /* One operand arithmetic functions */
561 #define GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type) \
562 __GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type) \
563 __GEN_INT_ARITH1_O_64(name##o, opc1, opc2, opc3 | 0x10, type)
565 #define GEN_INT_ARITH2_64 GEN_INT_ARITH2
566 #define GEN_INT_ARITHN_64 GEN_INT_ARITHN
567 #define GEN_INT_ARITH1_64 GEN_INT_ARITH1
570 /* add add. addo addo. */
571 static inline void gen_op_addo (void)
577 #if defined(TARGET_PPC64)
578 #define gen_op_add_64 gen_op_add
579 static inline void gen_op_addo_64 (void)
583 gen_op_check_addo_64();
586 GEN_INT_ARITH2_64 (add
, 0x1F, 0x0A, 0x08, PPC_INTEGER
);
587 /* addc addc. addco addco. */
588 static inline void gen_op_addc (void)
594 static inline void gen_op_addco (void)
601 #if defined(TARGET_PPC64)
602 static inline void gen_op_addc_64 (void)
606 gen_op_check_addc_64();
608 static inline void gen_op_addco_64 (void)
612 gen_op_check_addc_64();
613 gen_op_check_addo_64();
616 GEN_INT_ARITH2_64 (addc
, 0x1F, 0x0A, 0x00, PPC_INTEGER
);
617 /* adde adde. addeo addeo. */
618 static inline void gen_op_addeo (void)
624 #if defined(TARGET_PPC64)
625 static inline void gen_op_addeo_64 (void)
629 gen_op_check_addo_64();
632 GEN_INT_ARITH2_64 (adde
, 0x1F, 0x0A, 0x04, PPC_INTEGER
);
633 /* addme addme. addmeo addmeo. */
634 static inline void gen_op_addme (void)
639 #if defined(TARGET_PPC64)
640 static inline void gen_op_addme_64 (void)
646 GEN_INT_ARITH1_64 (addme
, 0x1F, 0x0A, 0x07, PPC_INTEGER
);
647 /* addze addze. addzeo addzeo. */
648 static inline void gen_op_addze (void)
654 static inline void gen_op_addzeo (void)
661 #if defined(TARGET_PPC64)
662 static inline void gen_op_addze_64 (void)
666 gen_op_check_addc_64();
668 static inline void gen_op_addzeo_64 (void)
672 gen_op_check_addc_64();
673 gen_op_check_addo_64();
676 GEN_INT_ARITH1_64 (addze
, 0x1F, 0x0A, 0x06, PPC_INTEGER
);
677 /* divw divw. divwo divwo. */
678 GEN_INT_ARITH2 (divw
, 0x1F, 0x0B, 0x0F, PPC_INTEGER
);
679 /* divwu divwu. divwuo divwuo. */
680 GEN_INT_ARITH2 (divwu
, 0x1F, 0x0B, 0x0E, PPC_INTEGER
);
682 GEN_INT_ARITHN (mulhw
, 0x1F, 0x0B, 0x02, PPC_INTEGER
);
684 GEN_INT_ARITHN (mulhwu
, 0x1F, 0x0B, 0x00, PPC_INTEGER
);
685 /* mullw mullw. mullwo mullwo. */
686 GEN_INT_ARITH2 (mullw
, 0x1F, 0x0B, 0x07, PPC_INTEGER
);
687 /* neg neg. nego nego. */
688 GEN_INT_ARITH1_64 (neg
, 0x1F, 0x08, 0x03, PPC_INTEGER
);
689 /* subf subf. subfo subfo. */
690 static inline void gen_op_subfo (void)
694 gen_op_check_subfo();
696 #if defined(TARGET_PPC64)
697 #define gen_op_subf_64 gen_op_subf
698 static inline void gen_op_subfo_64 (void)
702 gen_op_check_subfo_64();
705 GEN_INT_ARITH2_64 (subf
, 0x1F, 0x08, 0x01, PPC_INTEGER
);
706 /* subfc subfc. subfco subfco. */
707 static inline void gen_op_subfc (void)
710 gen_op_check_subfc();
712 static inline void gen_op_subfco (void)
716 gen_op_check_subfc();
717 gen_op_check_subfo();
719 #if defined(TARGET_PPC64)
720 static inline void gen_op_subfc_64 (void)
723 gen_op_check_subfc_64();
725 static inline void gen_op_subfco_64 (void)
729 gen_op_check_subfc_64();
730 gen_op_check_subfo_64();
733 GEN_INT_ARITH2_64 (subfc
, 0x1F, 0x08, 0x00, PPC_INTEGER
);
734 /* subfe subfe. subfeo subfeo. */
735 static inline void gen_op_subfeo (void)
739 gen_op_check_subfo();
741 #if defined(TARGET_PPC64)
742 #define gen_op_subfe_64 gen_op_subfe
743 static inline void gen_op_subfeo_64 (void)
747 gen_op_check_subfo_64();
750 GEN_INT_ARITH2_64 (subfe
, 0x1F, 0x08, 0x04, PPC_INTEGER
);
751 /* subfme subfme. subfmeo subfmeo. */
752 GEN_INT_ARITH1_64 (subfme
, 0x1F, 0x08, 0x07, PPC_INTEGER
);
753 /* subfze subfze. subfzeo subfzeo. */
754 GEN_INT_ARITH1_64 (subfze
, 0x1F, 0x08, 0x06, PPC_INTEGER
);
756 GEN_HANDLER(addi
, 0x0E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
758 target_long simm
= SIMM(ctx
->opcode
);
760 if (rA(ctx
->opcode
) == 0) {
764 gen_op_load_gpr_T0(rA(ctx
->opcode
));
765 if (likely(simm
!= 0))
768 gen_op_store_T0_gpr(rD(ctx
->opcode
));
771 GEN_HANDLER(addic
, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
773 target_long simm
= SIMM(ctx
->opcode
);
775 gen_op_load_gpr_T0(rA(ctx
->opcode
));
776 if (likely(simm
!= 0)) {
779 #if defined(TARGET_PPC64)
781 gen_op_check_addc_64();
786 gen_op_clear_xer_ca();
788 gen_op_store_T0_gpr(rD(ctx
->opcode
));
791 GEN_HANDLER(addic_
, 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
793 target_long simm
= SIMM(ctx
->opcode
);
795 gen_op_load_gpr_T0(rA(ctx
->opcode
));
796 if (likely(simm
!= 0)) {
799 #if defined(TARGET_PPC64)
801 gen_op_check_addc_64();
806 gen_op_store_T0_gpr(rD(ctx
->opcode
));
810 GEN_HANDLER(addis
, 0x0F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
812 target_long simm
= SIMM(ctx
->opcode
);
814 if (rA(ctx
->opcode
) == 0) {
816 gen_set_T0(simm
<< 16);
818 gen_op_load_gpr_T0(rA(ctx
->opcode
));
819 if (likely(simm
!= 0))
820 gen_op_addi(simm
<< 16);
822 gen_op_store_T0_gpr(rD(ctx
->opcode
));
825 GEN_HANDLER(mulli
, 0x07, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
827 gen_op_load_gpr_T0(rA(ctx
->opcode
));
828 gen_op_mulli(SIMM(ctx
->opcode
));
829 gen_op_store_T0_gpr(rD(ctx
->opcode
));
832 GEN_HANDLER(subfic
, 0x08, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
834 gen_op_load_gpr_T0(rA(ctx
->opcode
));
835 #if defined(TARGET_PPC64)
837 gen_op_subfic_64(SIMM(ctx
->opcode
));
840 gen_op_subfic(SIMM(ctx
->opcode
));
841 gen_op_store_T0_gpr(rD(ctx
->opcode
));
844 #if defined(TARGET_PPC64)
846 GEN_INT_ARITHN (mulhd
, 0x1F, 0x09, 0x02, PPC_INTEGER
);
848 GEN_INT_ARITHN (mulhdu
, 0x1F, 0x09, 0x00, PPC_INTEGER
);
849 /* mulld mulld. mulldo mulldo. */
850 GEN_INT_ARITH2 (mulld
, 0x1F, 0x09, 0x07, PPC_INTEGER
);
851 /* divd divd. divdo divdo. */
852 GEN_INT_ARITH2 (divd
, 0x1F, 0x09, 0x0F, PPC_INTEGER
);
853 /* divdu divdu. divduo divduo. */
854 GEN_INT_ARITH2 (divdu
, 0x1F, 0x09, 0x0E, PPC_INTEGER
);
857 /*** Integer comparison ***/
858 #if defined(TARGET_PPC64)
859 #define GEN_CMP(name, opc, type) \
860 GEN_HANDLER(name, 0x1F, 0x00, opc, 0x00400000, type) \
862 gen_op_load_gpr_T0(rA(ctx->opcode)); \
863 gen_op_load_gpr_T1(rB(ctx->opcode)); \
865 gen_op_##name##_64(); \
868 gen_op_store_T0_crf(crfD(ctx->opcode)); \
871 #define GEN_CMP(name, opc, type) \
872 GEN_HANDLER(name, 0x1F, 0x00, opc, 0x00400000, type) \
874 gen_op_load_gpr_T0(rA(ctx->opcode)); \
875 gen_op_load_gpr_T1(rB(ctx->opcode)); \
877 gen_op_store_T0_crf(crfD(ctx->opcode)); \
882 GEN_CMP(cmp
, 0x00, PPC_INTEGER
);
884 GEN_HANDLER(cmpi
, 0x0B, 0xFF, 0xFF, 0x00400000, PPC_INTEGER
)
886 gen_op_load_gpr_T0(rA(ctx
->opcode
));
887 #if defined(TARGET_PPC64)
889 gen_op_cmpi_64(SIMM(ctx
->opcode
));
892 gen_op_cmpi(SIMM(ctx
->opcode
));
893 gen_op_store_T0_crf(crfD(ctx
->opcode
));
896 GEN_CMP(cmpl
, 0x01, PPC_INTEGER
);
898 GEN_HANDLER(cmpli
, 0x0A, 0xFF, 0xFF, 0x00400000, PPC_INTEGER
)
900 gen_op_load_gpr_T0(rA(ctx
->opcode
));
901 #if defined(TARGET_PPC64)
903 gen_op_cmpli_64(UIMM(ctx
->opcode
));
906 gen_op_cmpli(UIMM(ctx
->opcode
));
907 gen_op_store_T0_crf(crfD(ctx
->opcode
));
910 /* isel (PowerPC 2.03 specification) */
911 GEN_HANDLER(isel
, 0x1F, 0x0F, 0x00, 0x00000001, PPC_203
)
913 uint32_t bi
= rC(ctx
->opcode
);
916 if (rA(ctx
->opcode
) == 0) {
919 gen_op_load_gpr_T1(rA(ctx
->opcode
));
921 gen_op_load_gpr_T2(rB(ctx
->opcode
));
922 mask
= 1 << (3 - (bi
& 0x03));
923 gen_op_load_crf_T0(bi
>> 2);
924 gen_op_test_true(mask
);
926 gen_op_store_T0_gpr(rD(ctx
->opcode
));
929 /*** Integer logical ***/
930 #define __GEN_LOGICAL2(name, opc2, opc3, type) \
931 GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000000, type) \
933 gen_op_load_gpr_T0(rS(ctx->opcode)); \
934 gen_op_load_gpr_T1(rB(ctx->opcode)); \
936 gen_op_store_T0_gpr(rA(ctx->opcode)); \
937 if (unlikely(Rc(ctx->opcode) != 0)) \
940 #define GEN_LOGICAL2(name, opc, type) \
941 __GEN_LOGICAL2(name, 0x1C, opc, type)
943 #define GEN_LOGICAL1(name, opc, type) \
944 GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, type) \
946 gen_op_load_gpr_T0(rS(ctx->opcode)); \
948 gen_op_store_T0_gpr(rA(ctx->opcode)); \
949 if (unlikely(Rc(ctx->opcode) != 0)) \
954 GEN_LOGICAL2(and, 0x00, PPC_INTEGER
);
956 GEN_LOGICAL2(andc
, 0x01, PPC_INTEGER
);
958 GEN_HANDLER(andi_
, 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
960 gen_op_load_gpr_T0(rS(ctx
->opcode
));
961 gen_op_andi_T0(UIMM(ctx
->opcode
));
962 gen_op_store_T0_gpr(rA(ctx
->opcode
));
966 GEN_HANDLER(andis_
, 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
968 gen_op_load_gpr_T0(rS(ctx
->opcode
));
969 gen_op_andi_T0(UIMM(ctx
->opcode
) << 16);
970 gen_op_store_T0_gpr(rA(ctx
->opcode
));
975 GEN_LOGICAL1(cntlzw
, 0x00, PPC_INTEGER
);
977 GEN_LOGICAL2(eqv
, 0x08, PPC_INTEGER
);
979 GEN_LOGICAL1(extsb
, 0x1D, PPC_INTEGER
);
981 GEN_LOGICAL1(extsh
, 0x1C, PPC_INTEGER
);
983 GEN_LOGICAL2(nand
, 0x0E, PPC_INTEGER
);
985 GEN_LOGICAL2(nor
, 0x03, PPC_INTEGER
);
988 GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER
)
992 rs
= rS(ctx
->opcode
);
993 ra
= rA(ctx
->opcode
);
994 rb
= rB(ctx
->opcode
);
995 /* Optimisation for mr. ri case */
996 if (rs
!= ra
|| rs
!= rb
) {
997 gen_op_load_gpr_T0(rs
);
999 gen_op_load_gpr_T1(rb
);
1002 gen_op_store_T0_gpr(ra
);
1003 if (unlikely(Rc(ctx
->opcode
) != 0))
1005 } else if (unlikely(Rc(ctx
->opcode
) != 0)) {
1006 gen_op_load_gpr_T0(rs
);
1012 GEN_LOGICAL2(orc
, 0x0C, PPC_INTEGER
);
1014 GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER
)
1016 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1017 /* Optimisation for "set to zero" case */
1018 if (rS(ctx
->opcode
) != rB(ctx
->opcode
)) {
1019 gen_op_load_gpr_T1(rB(ctx
->opcode
));
1024 gen_op_store_T0_gpr(rA(ctx
->opcode
));
1025 if (unlikely(Rc(ctx
->opcode
) != 0))
1029 GEN_HANDLER(ori
, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
1031 target_ulong uimm
= UIMM(ctx
->opcode
);
1033 if (rS(ctx
->opcode
) == rA(ctx
->opcode
) && uimm
== 0) {
1035 /* XXX: should handle special NOPs for POWER series */
1038 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1039 if (likely(uimm
!= 0))
1041 gen_op_store_T0_gpr(rA(ctx
->opcode
));
1044 GEN_HANDLER(oris
, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
1046 target_ulong uimm
= UIMM(ctx
->opcode
);
1048 if (rS(ctx
->opcode
) == rA(ctx
->opcode
) && uimm
== 0) {
1052 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1053 if (likely(uimm
!= 0))
1054 gen_op_ori(uimm
<< 16);
1055 gen_op_store_T0_gpr(rA(ctx
->opcode
));
1058 GEN_HANDLER(xori
, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
1060 target_ulong uimm
= UIMM(ctx
->opcode
);
1062 if (rS(ctx
->opcode
) == rA(ctx
->opcode
) && uimm
== 0) {
1066 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1067 if (likely(uimm
!= 0))
1069 gen_op_store_T0_gpr(rA(ctx
->opcode
));
1073 GEN_HANDLER(xoris
, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
1075 target_ulong uimm
= UIMM(ctx
->opcode
);
1077 if (rS(ctx
->opcode
) == rA(ctx
->opcode
) && uimm
== 0) {
1081 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1082 if (likely(uimm
!= 0))
1083 gen_op_xori(uimm
<< 16);
1084 gen_op_store_T0_gpr(rA(ctx
->opcode
));
1087 /* popcntb : PowerPC 2.03 specification */
1088 GEN_HANDLER(popcntb
, 0x1F, 0x03, 0x03, 0x0000F801, PPC_203
)
1090 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1091 #if defined(TARGET_PPC64)
1093 gen_op_popcntb_64();
1097 gen_op_store_T0_gpr(rA(ctx
->opcode
));
1100 #if defined(TARGET_PPC64)
1101 /* extsw & extsw. */
1102 GEN_LOGICAL1(extsw
, 0x1E, PPC_64B
);
1104 GEN_LOGICAL1(cntlzd
, 0x01, PPC_64B
);
1107 /*** Integer rotate ***/
1108 /* rlwimi & rlwimi. */
1109 GEN_HANDLER(rlwimi
, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
1112 uint32_t mb
, me
, sh
;
1114 mb
= MB(ctx
->opcode
);
1115 me
= ME(ctx
->opcode
);
1116 sh
= SH(ctx
->opcode
);
1117 if (likely(sh
== 0)) {
1118 if (likely(mb
== 0 && me
== 31)) {
1119 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1121 } else if (likely(mb
== 31 && me
== 0)) {
1122 gen_op_load_gpr_T0(rA(ctx
->opcode
));
1125 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1126 gen_op_load_gpr_T1(rA(ctx
->opcode
));
1129 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1130 gen_op_load_gpr_T1(rA(ctx
->opcode
));
1131 gen_op_rotli32_T0(SH(ctx
->opcode
));
1133 #if defined(TARGET_PPC64)
1137 mask
= MASK(mb
, me
);
1138 gen_op_andi_T0(mask
);
1139 gen_op_andi_T1(~mask
);
1142 gen_op_store_T0_gpr(rA(ctx
->opcode
));
1143 if (unlikely(Rc(ctx
->opcode
) != 0))
1146 /* rlwinm & rlwinm. */
1147 GEN_HANDLER(rlwinm
, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
1149 uint32_t mb
, me
, sh
;
1151 sh
= SH(ctx
->opcode
);
1152 mb
= MB(ctx
->opcode
);
1153 me
= ME(ctx
->opcode
);
1154 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1155 if (likely(sh
== 0)) {
1158 if (likely(mb
== 0)) {
1159 if (likely(me
== 31)) {
1160 gen_op_rotli32_T0(sh
);
1162 } else if (likely(me
== (31 - sh
))) {
1166 } else if (likely(me
== 31)) {
1167 if (likely(sh
== (32 - mb
))) {
1172 gen_op_rotli32_T0(sh
);
1174 #if defined(TARGET_PPC64)
1178 gen_op_andi_T0(MASK(mb
, me
));
1180 gen_op_store_T0_gpr(rA(ctx
->opcode
));
1181 if (unlikely(Rc(ctx
->opcode
) != 0))
1184 /* rlwnm & rlwnm. */
1185 GEN_HANDLER(rlwnm
, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
1189 mb
= MB(ctx
->opcode
);
1190 me
= ME(ctx
->opcode
);
1191 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1192 gen_op_load_gpr_T1(rB(ctx
->opcode
));
1193 gen_op_rotl32_T0_T1();
1194 if (unlikely(mb
!= 0 || me
!= 31)) {
1195 #if defined(TARGET_PPC64)
1199 gen_op_andi_T0(MASK(mb
, me
));
1201 gen_op_store_T0_gpr(rA(ctx
->opcode
));
1202 if (unlikely(Rc(ctx
->opcode
) != 0))
1206 #if defined(TARGET_PPC64)
1207 #define GEN_PPC64_R2(name, opc1, opc2) \
1208 GEN_HANDLER(name##0, opc1, opc2, 0xFF, 0x00000000, PPC_64B) \
1210 gen_##name(ctx, 0); \
1212 GEN_HANDLER(name##1, opc1, opc2 | 0x10, 0xFF, 0x00000000, PPC_64B) \
1214 gen_##name(ctx, 1); \
1216 #define GEN_PPC64_R4(name, opc1, opc2) \
1217 GEN_HANDLER(name##0, opc1, opc2, 0xFF, 0x00000000, PPC_64B) \
1219 gen_##name(ctx, 0, 0); \
1221 GEN_HANDLER(name##1, opc1, opc2 | 0x01, 0xFF, 0x00000000, PPC_64B) \
1223 gen_##name(ctx, 0, 1); \
1225 GEN_HANDLER(name##2, opc1, opc2 | 0x10, 0xFF, 0x00000000, PPC_64B) \
1227 gen_##name(ctx, 1, 0); \
1229 GEN_HANDLER(name##3, opc1, opc2 | 0x11, 0xFF, 0x00000000, PPC_64B) \
1231 gen_##name(ctx, 1, 1); \
1234 static inline void gen_rldinm (DisasContext
*ctx
, uint32_t mb
, uint32_t me
,
1237 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1238 if (likely(sh
== 0)) {
1241 if (likely(mb
== 0)) {
1242 if (likely(me
== 63)) {
1243 gen_op_rotli32_T0(sh
);
1245 } else if (likely(me
== (63 - sh
))) {
1249 } else if (likely(me
== 63)) {
1250 if (likely(sh
== (64 - mb
))) {
1255 gen_op_rotli64_T0(sh
);
1257 gen_op_andi_T0(MASK(mb
, me
));
1259 gen_op_store_T0_gpr(rA(ctx
->opcode
));
1260 if (unlikely(Rc(ctx
->opcode
) != 0))
1263 /* rldicl - rldicl. */
1264 static inline void gen_rldicl (DisasContext
*ctx
, int mbn
, int shn
)
1268 sh
= SH(ctx
->opcode
) | (shn
<< 5);
1269 mb
= MB(ctx
->opcode
) | (mbn
<< 5);
1270 gen_rldinm(ctx
, mb
, 63, sh
);
1272 GEN_PPC64_R4(rldicl
, 0x1E, 0x00);
1273 /* rldicr - rldicr. */
1274 static inline void gen_rldicr (DisasContext
*ctx
, int men
, int shn
)
1278 sh
= SH(ctx
->opcode
) | (shn
<< 5);
1279 me
= MB(ctx
->opcode
) | (men
<< 5);
1280 gen_rldinm(ctx
, 0, me
, sh
);
1282 GEN_PPC64_R4(rldicr
, 0x1E, 0x02);
1283 /* rldic - rldic. */
1284 static inline void gen_rldic (DisasContext
*ctx
, int mbn
, int shn
)
1288 sh
= SH(ctx
->opcode
) | (shn
<< 5);
1289 mb
= MB(ctx
->opcode
) | (mbn
<< 5);
1290 gen_rldinm(ctx
, mb
, 63 - sh
, sh
);
1292 GEN_PPC64_R4(rldic
, 0x1E, 0x04);
1294 static inline void gen_rldnm (DisasContext
*ctx
, uint32_t mb
, uint32_t me
)
1296 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1297 gen_op_load_gpr_T1(rB(ctx
->opcode
));
1298 gen_op_rotl64_T0_T1();
1299 if (unlikely(mb
!= 0 || me
!= 63)) {
1300 gen_op_andi_T0(MASK(mb
, me
));
1302 gen_op_store_T0_gpr(rA(ctx
->opcode
));
1303 if (unlikely(Rc(ctx
->opcode
) != 0))
1307 /* rldcl - rldcl. */
1308 static inline void gen_rldcl (DisasContext
*ctx
, int mbn
)
1312 mb
= MB(ctx
->opcode
) | (mbn
<< 5);
1313 gen_rldnm(ctx
, mb
, 63);
1315 GEN_PPC64_R2(rldcl
, 0x1E, 0x08)
1316 /* rldcr - rldcr. */
1317 static inline void gen_rldcr (DisasContext
*ctx
, int men
)
1321 me
= MB(ctx
->opcode
) | (men
<< 5);
1322 gen_rldnm(ctx
, 0, me
);
1324 GEN_PPC64_R2(rldcr
, 0x1E, 0x09)
1325 /* rldimi - rldimi. */
1326 static inline void gen_rldimi (DisasContext
*ctx
, int mbn
, int shn
)
1331 sh
= SH(ctx
->opcode
) | (shn
<< 5);
1332 mb
= MB(ctx
->opcode
) | (mbn
<< 5);
1333 if (likely(sh
== 0)) {
1334 if (likely(mb
== 0)) {
1335 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1337 } else if (likely(mb
== 63)) {
1338 gen_op_load_gpr_T0(rA(ctx
->opcode
));
1341 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1342 gen_op_load_gpr_T1(rA(ctx
->opcode
));
1345 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1346 gen_op_load_gpr_T1(rA(ctx
->opcode
));
1347 gen_op_rotli64_T0(SH(ctx
->opcode
));
1349 mask
= MASK(mb
, 63 - sh
);
1350 gen_op_andi_T0(mask
);
1351 gen_op_andi_T1(~mask
);
1354 gen_op_store_T0_gpr(rA(ctx
->opcode
));
1355 if (unlikely(Rc(ctx
->opcode
) != 0))
1358 GEN_PPC64_R4(rldimi
, 0x1E, 0x06)
1361 /*** Integer shift ***/
1363 __GEN_LOGICAL2(slw
, 0x18, 0x00, PPC_INTEGER
);
1365 __GEN_LOGICAL2(sraw
, 0x18, 0x18, PPC_INTEGER
);
1366 /* srawi & srawi. */
1367 GEN_HANDLER(srawi
, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER
)
1370 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1371 if (SH(ctx
->opcode
) != 0) {
1372 gen_op_move_T1_T0();
1373 mb
= 32 - SH(ctx
->opcode
);
1375 #if defined(TARGET_PPC64)
1379 gen_op_srawi(SH(ctx
->opcode
), MASK(mb
, me
));
1381 gen_op_store_T0_gpr(rA(ctx
->opcode
));
1382 if (unlikely(Rc(ctx
->opcode
) != 0))
1386 __GEN_LOGICAL2(srw
, 0x18, 0x10, PPC_INTEGER
);
1388 #if defined(TARGET_PPC64)
1390 __GEN_LOGICAL2(sld
, 0x1B, 0x00, PPC_64B
);
1392 __GEN_LOGICAL2(srad
, 0x1A, 0x18, PPC_64B
);
1393 /* sradi & sradi. */
1394 static inline void gen_sradi (DisasContext
*ctx
, int n
)
1399 gen_op_load_gpr_T0(rS(ctx
->opcode
));
1400 sh
= SH(ctx
->opcode
) + (n
<< 5);
1402 gen_op_move_T1_T0();
1403 mb
= 64 - SH(ctx
->opcode
);
1405 mask
= MASK(mb
, me
);
1406 gen_op_sradi(sh
, mask
>> 32, mask
);
1408 gen_op_store_T0_gpr(rA(ctx
->opcode
));
1409 if (unlikely(Rc(ctx
->opcode
) != 0))
1412 GEN_HANDLER(sradi0
, 0x1F, 0x1A, 0x19, 0x00000000, PPC_64B
)
1416 GEN_HANDLER(sradi1
, 0x1F, 0x1B, 0x19, 0x00000000, PPC_64B
)
1421 __GEN_LOGICAL2(srd
, 0x1B, 0x10, PPC_64B
);
1424 /*** Floating-Point arithmetic ***/
1425 #define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat) \
1426 GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, PPC_FLOAT) \
1428 if (unlikely(!ctx->fpu_enabled)) { \
1429 RET_EXCP(ctx, EXCP_NO_FP, 0); \
1432 gen_op_reset_scrfx(); \
1433 gen_op_load_fpr_FT0(rA(ctx->opcode)); \
1434 gen_op_load_fpr_FT1(rC(ctx->opcode)); \
1435 gen_op_load_fpr_FT2(rB(ctx->opcode)); \
1440 gen_op_store_FT0_fpr(rD(ctx->opcode)); \
1441 if (unlikely(Rc(ctx->opcode) != 0)) \
1445 #define GEN_FLOAT_ACB(name, op2) \
1446 _GEN_FLOAT_ACB(name, name, 0x3F, op2, 0); \
1447 _GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1);
1449 #define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat) \
1450 GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT) \
1452 if (unlikely(!ctx->fpu_enabled)) { \
1453 RET_EXCP(ctx, EXCP_NO_FP, 0); \
1456 gen_op_reset_scrfx(); \
1457 gen_op_load_fpr_FT0(rA(ctx->opcode)); \
1458 gen_op_load_fpr_FT1(rB(ctx->opcode)); \
1463 gen_op_store_FT0_fpr(rD(ctx->opcode)); \
1464 if (unlikely(Rc(ctx->opcode) != 0)) \
1467 #define GEN_FLOAT_AB(name, op2, inval) \
1468 _GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0); \
1469 _GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1);
1471 #define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat) \
1472 GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT) \
1474 if (unlikely(!ctx->fpu_enabled)) { \
1475 RET_EXCP(ctx, EXCP_NO_FP, 0); \
1478 gen_op_reset_scrfx(); \
1479 gen_op_load_fpr_FT0(rA(ctx->opcode)); \
1480 gen_op_load_fpr_FT1(rC(ctx->opcode)); \
1485 gen_op_store_FT0_fpr(rD(ctx->opcode)); \
1486 if (unlikely(Rc(ctx->opcode) != 0)) \
1489 #define GEN_FLOAT_AC(name, op2, inval) \
1490 _GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0); \
1491 _GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1);
1493 #define GEN_FLOAT_B(name, op2, op3) \
1494 GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, PPC_FLOAT) \
1496 if (unlikely(!ctx->fpu_enabled)) { \
1497 RET_EXCP(ctx, EXCP_NO_FP, 0); \
1500 gen_op_reset_scrfx(); \
1501 gen_op_load_fpr_FT0(rB(ctx->opcode)); \
1503 gen_op_store_FT0_fpr(rD(ctx->opcode)); \
1504 if (unlikely(Rc(ctx->opcode) != 0)) \
1508 #define GEN_FLOAT_BS(name, op1, op2) \
1509 GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, PPC_FLOAT) \
1511 if (unlikely(!ctx->fpu_enabled)) { \
1512 RET_EXCP(ctx, EXCP_NO_FP, 0); \
1515 gen_op_reset_scrfx(); \
1516 gen_op_load_fpr_FT0(rB(ctx->opcode)); \
1518 gen_op_store_FT0_fpr(rD(ctx->opcode)); \
1519 if (unlikely(Rc(ctx->opcode) != 0)) \
1524 GEN_FLOAT_AB(add
, 0x15, 0x000007C0);
1526 GEN_FLOAT_AB(div
, 0x12, 0x000007C0);
1528 GEN_FLOAT_AC(mul
, 0x19, 0x0000F800);
1530 /* fres */ /* XXX: not in 601 */
1531 GEN_FLOAT_BS(res
, 0x3B, 0x18);
1533 /* frsqrte */ /* XXX: not in 601 */
1534 GEN_FLOAT_BS(rsqrte
, 0x3F, 0x1A);
1536 /* fsel */ /* XXX: not in 601 */
1537 _GEN_FLOAT_ACB(sel
, sel
, 0x3F, 0x17, 0);
1539 GEN_FLOAT_AB(sub
, 0x14, 0x000007C0);
1542 GEN_HANDLER(fsqrt
, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_OPT
)
1544 if (unlikely(!ctx
->fpu_enabled
)) {
1545 RET_EXCP(ctx
, EXCP_NO_FP
, 0);
1548 gen_op_reset_scrfx();
1549 gen_op_load_fpr_FT0(rB(ctx
->opcode
));
1551 gen_op_store_FT0_fpr(rD(ctx
->opcode
));
1552 if (unlikely(Rc(ctx
->opcode
) != 0))
1556 GEN_HANDLER(fsqrts
, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_OPT
)
1558 if (unlikely(!ctx
->fpu_enabled
)) {
1559 RET_EXCP(ctx
, EXCP_NO_FP
, 0);
1562 gen_op_reset_scrfx();
1563 gen_op_load_fpr_FT0(rB(ctx
->opcode
));
1566 gen_op_store_FT0_fpr(rD(ctx
->opcode
));
1567 if (unlikely(Rc(ctx
->opcode
) != 0))
1571 /*** Floating-Point multiply-and-add ***/
1572 /* fmadd - fmadds */
1573 GEN_FLOAT_ACB(madd
, 0x1D);
1574 /* fmsub - fmsubs */
1575 GEN_FLOAT_ACB(msub
, 0x1C);
1576 /* fnmadd - fnmadds */
1577 GEN_FLOAT_ACB(nmadd
, 0x1F);
1578 /* fnmsub - fnmsubs */
1579 GEN_FLOAT_ACB(nmsub
, 0x1E);
1581 /*** Floating-Point round & convert ***/
1583 GEN_FLOAT_B(ctiw
, 0x0E, 0x00);
1585 GEN_FLOAT_B(ctiwz
, 0x0F, 0x00);
1587 GEN_FLOAT_B(rsp
, 0x0C, 0x00);
1588 #if defined(TARGET_PPC64)
1590 GEN_FLOAT_B(cfid
, 0x0E, 0x1A);
1592 GEN_FLOAT_B(ctid
, 0x0E, 0x19);
1594 GEN_FLOAT_B(ctidz
, 0x0F, 0x19);
1597 /*** Floating-Point compare ***/
1599 GEN_HANDLER(fcmpo
, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT
)
1601 if (unlikely(!ctx
->fpu_enabled
)) {
1602 RET_EXCP(ctx
, EXCP_NO_FP
, 0);
1605 gen_op_reset_scrfx();
1606 gen_op_load_fpr_FT0(rA(ctx
->opcode
));
1607 gen_op_load_fpr_FT1(rB(ctx
->opcode
));
1609 gen_op_store_T0_crf(crfD(ctx
->opcode
));
1613 GEN_HANDLER(fcmpu
, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT
)
1615 if (unlikely(!ctx
->fpu_enabled
)) {
1616 RET_EXCP(ctx
, EXCP_NO_FP
, 0);
1619 gen_op_reset_scrfx();
1620 gen_op_load_fpr_FT0(rA(ctx
->opcode
));
1621 gen_op_load_fpr_FT1(rB(ctx
->opcode
));
1623 gen_op_store_T0_crf(crfD(ctx
->opcode
));
1626 /*** Floating-point move ***/
1628 GEN_FLOAT_B(abs
, 0x08, 0x08);
1631 GEN_HANDLER(fmr
, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT
)
1633 if (unlikely(!ctx
->fpu_enabled
)) {
1634 RET_EXCP(ctx
, EXCP_NO_FP
, 0);
1637 gen_op_reset_scrfx();
1638 gen_op_load_fpr_FT0(rB(ctx
->opcode
));
1639 gen_op_store_FT0_fpr(rD(ctx
->opcode
));
1640 if (unlikely(Rc(ctx
->opcode
) != 0))
1645 GEN_FLOAT_B(nabs
, 0x08, 0x04);
1647 GEN_FLOAT_B(neg
, 0x08, 0x01);
1649 /*** Floating-Point status & ctrl register ***/
1651 GEN_HANDLER(mcrfs
, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT
)
1653 if (unlikely(!ctx
->fpu_enabled
)) {
1654 RET_EXCP(ctx
, EXCP_NO_FP
, 0);
1657 gen_op_load_fpscr_T0(crfS(ctx
->opcode
));
1658 gen_op_store_T0_crf(crfD(ctx
->opcode
));
1659 gen_op_clear_fpscr(crfS(ctx
->opcode
));
1663 GEN_HANDLER(mffs
, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT
)
1665 if (unlikely(!ctx
->fpu_enabled
)) {
1666 RET_EXCP(ctx
, EXCP_NO_FP
, 0);
1669 gen_op_load_fpscr();
1670 gen_op_store_FT0_fpr(rD(ctx
->opcode
));
1671 if (unlikely(Rc(ctx
->opcode
) != 0))
1676 GEN_HANDLER(mtfsb0
, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT
)
1680 if (unlikely(!ctx
->fpu_enabled
)) {
1681 RET_EXCP(ctx
, EXCP_NO_FP
, 0);
1684 crb
= crbD(ctx
->opcode
) >> 2;
1685 gen_op_load_fpscr_T0(crb
);
1686 gen_op_andi_T0(~(1 << (crbD(ctx
->opcode
) & 0x03)));
1687 gen_op_store_T0_fpscr(crb
);
1688 if (unlikely(Rc(ctx
->opcode
) != 0))
1693 GEN_HANDLER(mtfsb1
, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT
)
1697 if (unlikely(!ctx
->fpu_enabled
)) {
1698 RET_EXCP(ctx
, EXCP_NO_FP
, 0);
1701 crb
= crbD(ctx
->opcode
) >> 2;
1702 gen_op_load_fpscr_T0(crb
);
1703 gen_op_ori(1 << (crbD(ctx
->opcode
) & 0x03));
1704 gen_op_store_T0_fpscr(crb
);
1705 if (unlikely(Rc(ctx
->opcode
) != 0))
1710 GEN_HANDLER(mtfsf
, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT
)
1712 if (unlikely(!ctx
->fpu_enabled
)) {
1713 RET_EXCP(ctx
, EXCP_NO_FP
, 0);
1716 gen_op_load_fpr_FT0(rB(ctx
->opcode
));
1717 gen_op_store_fpscr(FM(ctx
->opcode
));
1718 if (unlikely(Rc(ctx
->opcode
) != 0))
1723 GEN_HANDLER(mtfsfi
, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT
)
1725 if (unlikely(!ctx
->fpu_enabled
)) {
1726 RET_EXCP(ctx
, EXCP_NO_FP
, 0);
1729 gen_op_store_T0_fpscri(crbD(ctx
->opcode
) >> 2, FPIMM(ctx
->opcode
));
1730 if (unlikely(Rc(ctx
->opcode
) != 0))
1734 /*** Addressing modes ***/
1735 /* Register indirect with immediate index : EA = (rA|0) + SIMM */
1736 static inline void gen_addr_imm_index (DisasContext
*ctx
, int maskl
)
1738 target_long simm
= SIMM(ctx
->opcode
);
1742 if (rA(ctx
->opcode
) == 0) {
1745 gen_op_load_gpr_T0(rA(ctx
->opcode
));
1746 if (likely(simm
!= 0))
1749 #ifdef DEBUG_MEMORY_ACCESSES
1750 gen_op_print_mem_EA();
1754 static inline void gen_addr_reg_index (DisasContext
*ctx
)
1756 if (rA(ctx
->opcode
) == 0) {
1757 gen_op_load_gpr_T0(rB(ctx
->opcode
));
1759 gen_op_load_gpr_T0(rA(ctx
->opcode
));
1760 gen_op_load_gpr_T1(rB(ctx
->opcode
));
1763 #ifdef DEBUG_MEMORY_ACCESSES
1764 gen_op_print_mem_EA();
1768 static inline void gen_addr_register (DisasContext
*ctx
)
1770 if (rA(ctx
->opcode
) == 0) {
1773 gen_op_load_gpr_T0(rA(ctx
->opcode
));
1775 #ifdef DEBUG_MEMORY_ACCESSES
1776 gen_op_print_mem_EA();
1780 /*** Integer load ***/
1781 #define op_ldst(name) (*gen_op_##name[ctx->mem_idx])()
1782 #if defined(CONFIG_USER_ONLY)
1783 #if defined(TARGET_PPC64)
1784 #define OP_LD_TABLE(width) \
1785 static GenOpFunc *gen_op_l##width[] = { \
1786 &gen_op_l##width##_raw, \
1787 &gen_op_l##width##_le_raw, \
1788 &gen_op_l##width##_64_raw, \
1789 &gen_op_l##width##_le_64_raw, \
1791 #define OP_ST_TABLE(width) \
1792 static GenOpFunc *gen_op_st##width[] = { \
1793 &gen_op_st##width##_raw, \
1794 &gen_op_st##width##_le_raw, \
1795 &gen_op_st##width##_64_raw, \
1796 &gen_op_st##width##_le_64_raw, \
1798 /* Byte access routine are endian safe */
1799 #define gen_op_stb_le_64_raw gen_op_stb_64_raw
1800 #define gen_op_lbz_le_64_raw gen_op_lbz_64_raw
1802 #define OP_LD_TABLE(width) \
1803 static GenOpFunc *gen_op_l##width[] = { \
1804 &gen_op_l##width##_raw, \
1805 &gen_op_l##width##_le_raw, \
1807 #define OP_ST_TABLE(width) \
1808 static GenOpFunc *gen_op_st##width[] = { \
1809 &gen_op_st##width##_raw, \
1810 &gen_op_st##width##_le_raw, \
1813 /* Byte access routine are endian safe */
1814 #define gen_op_stb_le_raw gen_op_stb_raw
1815 #define gen_op_lbz_le_raw gen_op_lbz_raw
1817 #if defined(TARGET_PPC64)
1818 #define OP_LD_TABLE(width) \
1819 static GenOpFunc *gen_op_l##width[] = { \
1820 &gen_op_l##width##_user, \
1821 &gen_op_l##width##_le_user, \
1822 &gen_op_l##width##_kernel, \
1823 &gen_op_l##width##_le_kernel, \
1824 &gen_op_l##width##_64_user, \
1825 &gen_op_l##width##_le_64_user, \
1826 &gen_op_l##width##_64_kernel, \
1827 &gen_op_l##width##_le_64_kernel, \
1829 #define OP_ST_TABLE(width) \
1830 static GenOpFunc *gen_op_st##width[] = { \
1831 &gen_op_st##width##_user, \
1832 &gen_op_st##width##_le_user, \
1833 &gen_op_st##width##_kernel, \
1834 &gen_op_st##width##_le_kernel, \
1835 &gen_op_st##width##_64_user, \
1836 &gen_op_st##width##_le_64_user, \
1837 &gen_op_st##width##_64_kernel, \
1838 &gen_op_st##width##_le_64_kernel, \
1840 /* Byte access routine are endian safe */
1841 #define gen_op_stb_le_64_user gen_op_stb_64_user
1842 #define gen_op_lbz_le_64_user gen_op_lbz_64_user
1843 #define gen_op_stb_le_64_kernel gen_op_stb_64_kernel
1844 #define gen_op_lbz_le_64_kernel gen_op_lbz_64_kernel
1846 #define OP_LD_TABLE(width) \
1847 static GenOpFunc *gen_op_l##width[] = { \
1848 &gen_op_l##width##_user, \
1849 &gen_op_l##width##_le_user, \
1850 &gen_op_l##width##_kernel, \
1851 &gen_op_l##width##_le_kernel, \
1853 #define OP_ST_TABLE(width) \
1854 static GenOpFunc *gen_op_st##width[] = { \
1855 &gen_op_st##width##_user, \
1856 &gen_op_st##width##_le_user, \
1857 &gen_op_st##width##_kernel, \
1858 &gen_op_st##width##_le_kernel, \
1861 /* Byte access routine are endian safe */
1862 #define gen_op_stb_le_user gen_op_stb_user
1863 #define gen_op_lbz_le_user gen_op_lbz_user
1864 #define gen_op_stb_le_kernel gen_op_stb_kernel
1865 #define gen_op_lbz_le_kernel gen_op_lbz_kernel
1868 #define GEN_LD(width, opc, type) \
1869 GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, type) \
1871 gen_addr_imm_index(ctx, 0); \
1872 op_ldst(l##width); \
1873 gen_op_store_T1_gpr(rD(ctx->opcode)); \
1876 #define GEN_LDU(width, opc, type) \
1877 GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, type) \
1879 if (unlikely(rA(ctx->opcode) == 0 || \
1880 rA(ctx->opcode) == rD(ctx->opcode))) { \
1884 if (type == PPC_64B) \
1885 gen_addr_imm_index(ctx, 1); \
1887 gen_addr_imm_index(ctx, 0); \
1888 op_ldst(l##width); \
1889 gen_op_store_T1_gpr(rD(ctx->opcode)); \
1890 gen_op_store_T0_gpr(rA(ctx->opcode)); \
1893 #define GEN_LDUX(width, opc2, opc3, type) \
1894 GEN_HANDLER(l##width##ux, 0x1F, opc2, opc3, 0x00000001, type) \
1896 if (unlikely(rA(ctx->opcode) == 0 || \
1897 rA(ctx->opcode) == rD(ctx->opcode))) { \
1901 gen_addr_reg_index(ctx); \
1902 op_ldst(l##width); \
1903 gen_op_store_T1_gpr(rD(ctx->opcode)); \
1904 gen_op_store_T0_gpr(rA(ctx->opcode)); \
1907 #define GEN_LDX(width, opc2, opc3, type) \
1908 GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, type) \
1910 gen_addr_reg_index(ctx); \
1911 op_ldst(l##width); \
1912 gen_op_store_T1_gpr(rD(ctx->opcode)); \
1915 #define GEN_LDS(width, op, type) \
1916 OP_LD_TABLE(width); \
1917 GEN_LD(width, op | 0x20, type); \
1918 GEN_LDU(width, op | 0x21, type); \
1919 GEN_LDUX(width, 0x17, op | 0x01, type); \
1920 GEN_LDX(width, 0x17, op | 0x00, type)
1922 /* lbz lbzu lbzux lbzx */
1923 GEN_LDS(bz
, 0x02, PPC_INTEGER
);
1924 /* lha lhau lhaux lhax */
1925 GEN_LDS(ha
, 0x0A, PPC_INTEGER
);
1926 /* lhz lhzu lhzux lhzx */
1927 GEN_LDS(hz
, 0x08, PPC_INTEGER
);
1928 /* lwz lwzu lwzux lwzx */
1929 GEN_LDS(wz
, 0x00, PPC_INTEGER
);
1930 #if defined(TARGET_PPC64)
1934 GEN_LDUX(wa
, 0x15, 0x0B, PPC_64B
);
1936 GEN_LDX(wa
, 0x15, 0x0A, PPC_64B
);
1938 GEN_LDUX(d
, 0x15, 0x01, PPC_64B
);
1940 GEN_LDX(d
, 0x15, 0x00, PPC_64B
);
1941 GEN_HANDLER(ld
, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B
)
1943 if (Rc(ctx
->opcode
)) {
1944 if (unlikely(rA(ctx
->opcode
) == 0 ||
1945 rA(ctx
->opcode
) == rD(ctx
->opcode
))) {
1950 gen_addr_imm_index(ctx
, 1);
1951 if (ctx
->opcode
& 0x02) {
1952 /* lwa (lwau is undefined) */
1958 gen_op_store_T1_gpr(rD(ctx
->opcode
));
1959 if (Rc(ctx
->opcode
))
1960 gen_op_store_T0_gpr(rA(ctx
->opcode
));
1964 /*** Integer store ***/
1965 #define GEN_ST(width, opc, type) \
1966 GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, type) \
1968 gen_addr_imm_index(ctx, 0); \
1969 gen_op_load_gpr_T1(rS(ctx->opcode)); \
1970 op_ldst(st##width); \
1973 #define GEN_STU(width, opc, type) \
1974 GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, type) \
1976 if (unlikely(rA(ctx->opcode) == 0)) { \
1980 if (type == PPC_64B) \
1981 gen_addr_imm_index(ctx, 1); \
1983 gen_addr_imm_index(ctx, 0); \
1984 gen_op_load_gpr_T1(rS(ctx->opcode)); \
1985 op_ldst(st##width); \
1986 gen_op_store_T0_gpr(rA(ctx->opcode)); \
1989 #define GEN_STUX(width, opc2, opc3, type) \
1990 GEN_HANDLER(st##width##ux, 0x1F, opc2, opc3, 0x00000001, type) \
1992 if (unlikely(rA(ctx->opcode) == 0)) { \
1996 gen_addr_reg_index(ctx); \
1997 gen_op_load_gpr_T1(rS(ctx->opcode)); \
1998 op_ldst(st##width); \
1999 gen_op_store_T0_gpr(rA(ctx->opcode)); \
2002 #define GEN_STX(width, opc2, opc3, type) \
2003 GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, type) \
2005 gen_addr_reg_index(ctx); \
2006 gen_op_load_gpr_T1(rS(ctx->opcode)); \
2007 op_ldst(st##width); \
2010 #define GEN_STS(width, op, type) \
2011 OP_ST_TABLE(width); \
2012 GEN_ST(width, op | 0x20, type); \
2013 GEN_STU(width, op | 0x21, type); \
2014 GEN_STUX(width, 0x17, op | 0x01, type); \
2015 GEN_STX(width, 0x17, op | 0x00, type)
2017 /* stb stbu stbux stbx */
2018 GEN_STS(b
, 0x06, PPC_INTEGER
);
2019 /* sth sthu sthux sthx */
2020 GEN_STS(h
, 0x0C, PPC_INTEGER
);
2021 /* stw stwu stwux stwx */
2022 GEN_STS(w
, 0x04, PPC_INTEGER
);
2023 #if defined(TARGET_PPC64)
2025 GEN_STUX(d
, 0x15, 0x05, PPC_64B
);
2026 GEN_STX(d
, 0x15, 0x04, PPC_64B
);
2027 GEN_HANDLER(std
, 0x3E, 0xFF, 0xFF, 0x00000002, PPC_64B
)
2029 if (Rc(ctx
->opcode
)) {
2030 if (unlikely(rA(ctx
->opcode
) == 0)) {
2035 gen_addr_imm_index(ctx
, 1);
2036 gen_op_load_gpr_T1(rS(ctx
->opcode
));
2038 if (Rc(ctx
->opcode
))
2039 gen_op_store_T0_gpr(rA(ctx
->opcode
));
2042 /*** Integer load and store with byte reverse ***/
2045 GEN_LDX(hbr
, 0x16, 0x18, PPC_INTEGER
);
2048 GEN_LDX(wbr
, 0x16, 0x10, PPC_INTEGER
);
2051 GEN_STX(hbr
, 0x16, 0x1C, PPC_INTEGER
);
2054 GEN_STX(wbr
, 0x16, 0x14, PPC_INTEGER
);
2056 /*** Integer load and store multiple ***/
2057 #define op_ldstm(name, reg) (*gen_op_##name[ctx->mem_idx])(reg)
2058 #if defined(TARGET_PPC64)
2059 #if defined(CONFIG_USER_ONLY)
2060 static GenOpFunc1
*gen_op_lmw
[] = {
2064 &gen_op_lmw_le_64_raw
,
2066 static GenOpFunc1
*gen_op_stmw
[] = {
2067 &gen_op_stmw_64_raw
,
2068 &gen_op_stmw_le_64_raw
,
2071 static GenOpFunc1
*gen_op_lmw
[] = {
2073 &gen_op_lmw_le_user
,
2075 &gen_op_lmw_le_kernel
,
2076 &gen_op_lmw_64_user
,
2077 &gen_op_lmw_le_64_user
,
2078 &gen_op_lmw_64_kernel
,
2079 &gen_op_lmw_le_64_kernel
,
2081 static GenOpFunc1
*gen_op_stmw
[] = {
2083 &gen_op_stmw_le_user
,
2084 &gen_op_stmw_kernel
,
2085 &gen_op_stmw_le_kernel
,
2086 &gen_op_stmw_64_user
,
2087 &gen_op_stmw_le_64_user
,
2088 &gen_op_stmw_64_kernel
,
2089 &gen_op_stmw_le_64_kernel
,
2093 #if defined(CONFIG_USER_ONLY)
2094 static GenOpFunc1
*gen_op_lmw
[] = {
2098 static GenOpFunc1
*gen_op_stmw
[] = {
2100 &gen_op_stmw_le_raw
,
2103 static GenOpFunc1
*gen_op_lmw
[] = {
2105 &gen_op_lmw_le_user
,
2107 &gen_op_lmw_le_kernel
,
2109 static GenOpFunc1
*gen_op_stmw
[] = {
2111 &gen_op_stmw_le_user
,
2112 &gen_op_stmw_kernel
,
2113 &gen_op_stmw_le_kernel
,
2119 GEN_HANDLER(lmw
, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
2121 /* NIP cannot be restored if the memory exception comes from an helper */
2122 gen_update_nip(ctx
, ctx
->nip
- 4);
2123 gen_addr_imm_index(ctx
, 0);
2124 op_ldstm(lmw
, rD(ctx
->opcode
));
2128 GEN_HANDLER(stmw
, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER
)
2130 /* NIP cannot be restored if the memory exception comes from an helper */
2131 gen_update_nip(ctx
, ctx
->nip
- 4);
2132 gen_addr_imm_index(ctx
, 0);
2133 op_ldstm(stmw
, rS(ctx
->opcode
));
2136 /*** Integer load and store strings ***/
2137 #define op_ldsts(name, start) (*gen_op_##name[ctx->mem_idx])(start)
2138 #define op_ldstsx(name, rd, ra, rb) (*gen_op_##name[ctx->mem_idx])(rd, ra, rb)
2139 #if defined(TARGET_PPC64)
2140 #if defined(CONFIG_USER_ONLY)
2141 static GenOpFunc1
*gen_op_lswi
[] = {
2143 &gen_op_lswi_le_raw
,
2144 &gen_op_lswi_64_raw
,
2145 &gen_op_lswi_le_64_raw
,
2147 static GenOpFunc3
*gen_op_lswx
[] = {
2149 &gen_op_lswx_le_raw
,
2150 &gen_op_lswx_64_raw
,
2151 &gen_op_lswx_le_64_raw
,
2153 static GenOpFunc1
*gen_op_stsw
[] = {
2155 &gen_op_stsw_le_raw
,
2156 &gen_op_stsw_64_raw
,
2157 &gen_op_stsw_le_64_raw
,
2160 static GenOpFunc1
*gen_op_lswi
[] = {
2162 &gen_op_lswi_le_user
,
2163 &gen_op_lswi_kernel
,
2164 &gen_op_lswi_le_kernel
,
2165 &gen_op_lswi_64_user
,
2166 &gen_op_lswi_le_64_user
,
2167 &gen_op_lswi_64_kernel
,
2168 &gen_op_lswi_le_64_kernel
,
2170 static GenOpFunc3
*gen_op_lswx
[] = {
2172 &gen_op_lswx_le_user
,
2173 &gen_op_lswx_kernel
,
2174 &gen_op_lswx_le_kernel
,
2175 &gen_op_lswx_64_user
,
2176 &gen_op_lswx_le_64_user
,
2177 &gen_op_lswx_64_kernel
,
2178 &gen_op_lswx_le_64_kernel
,
2180 static GenOpFunc1
*gen_op_stsw
[] = {
2182 &gen_op_stsw_le_user
,
2183 &gen_op_stsw_kernel
,
2184 &gen_op_stsw_le_kernel
,
2185 &gen_op_stsw_64_user
,
2186 &gen_op_stsw_le_64_user
,
2187 &gen_op_stsw_64_kernel
,
2188 &gen_op_stsw_le_64_kernel
,
2192 #if defined(CONFIG_USER_ONLY)
2193 static GenOpFunc1
*gen_op_lswi
[] = {
2195 &gen_op_lswi_le_raw
,
2197 static GenOpFunc3
*gen_op_lswx
[] = {
2199 &gen_op_lswx_le_raw
,
2201 static GenOpFunc1
*gen_op_stsw
[] = {
2203 &gen_op_stsw_le_raw
,
2206 static GenOpFunc1
*gen_op_lswi
[] = {
2208 &gen_op_lswi_le_user
,
2209 &gen_op_lswi_kernel
,
2210 &gen_op_lswi_le_kernel
,
2212 static GenOpFunc3
*gen_op_lswx
[] = {
2214 &gen_op_lswx_le_user
,
2215 &gen_op_lswx_kernel
,
2216 &gen_op_lswx_le_kernel
,
2218 static GenOpFunc1
*gen_op_stsw
[] = {
2220 &gen_op_stsw_le_user
,
2221 &gen_op_stsw_kernel
,
2222 &gen_op_stsw_le_kernel
,
2228 /* PowerPC32 specification says we must generate an exception if
2229 * rA is in the range of registers to be loaded.
2230 * In an other hand, IBM says this is valid, but rA won't be loaded.
2231 * For now, I'll follow the spec...
2233 GEN_HANDLER(lswi
, 0x1F, 0x15, 0x12, 0x00000001, PPC_INTEGER
)
2235 int nb
= NB(ctx
->opcode
);
2236 int start
= rD(ctx
->opcode
);
2237 int ra
= rA(ctx
->opcode
);
2243 if (unlikely(((start
+ nr
) > 32 &&
2244 start
<= ra
&& (start
+ nr
- 32) > ra
) ||
2245 ((start
+ nr
) <= 32 && start
<= ra
&& (start
+ nr
) > ra
))) {
2246 RET_EXCP(ctx
, EXCP_PROGRAM
, EXCP_INVAL
| EXCP_INVAL_LSWX
);
2249 /* NIP cannot be restored if the memory exception comes from an helper */
2250 gen_update_nip(ctx
, ctx
->nip
- 4);
2251 gen_addr_register(ctx
);
2253 op_ldsts(lswi
, start
);
2257 GEN_HANDLER(lswx
, 0x1F, 0x15, 0x10, 0x00000001, PPC_INTEGER
)
2259 int ra
= rA(ctx
->opcode
);
2260 int rb
= rB(ctx
->opcode
);
2262 /* NIP cannot be restored if the memory exception comes from an helper */
2263 gen_update_nip(ctx
, ctx
->nip
- 4);
2264 gen_addr_reg_index(ctx
);
2268 gen_op_load_xer_bc();
2269 op_ldstsx(lswx
, rD(ctx
->opcode
), ra
, rb
);
2273 GEN_HANDLER(stswi
, 0x1F, 0x15, 0x16, 0x00000001, PPC_INTEGER
)
2275 int nb
= NB(ctx
->opcode
);
2277 /* NIP cannot be restored if the memory exception comes from an helper */
2278 gen_update_nip(ctx
, ctx
->nip
- 4);
2279 gen_addr_register(ctx
);
2283 op_ldsts(stsw
, rS(ctx
->opcode
));
2287 GEN_HANDLER(stswx
, 0x1F, 0x15, 0x14, 0x00000001, PPC_INTEGER
)
2289 /* NIP cannot be restored if the memory exception comes from an helper */
2290 gen_update_nip(ctx
, ctx
->nip
- 4);
2291 gen_addr_reg_index(ctx
);
2292 gen_op_load_xer_bc();
2293 op_ldsts(stsw
, rS(ctx
->opcode
));
2296 /*** Memory synchronisation ***/
2298 GEN_HANDLER(eieio
, 0x1F, 0x16, 0x1A, 0x03FF0801, PPC_MEM_EIEIO
)
2303 GEN_HANDLER(isync
, 0x13, 0x16, 0x04, 0x03FF0801, PPC_MEM
)
2307 #define op_lwarx() (*gen_op_lwarx[ctx->mem_idx])()
2308 #define op_stwcx() (*gen_op_stwcx[ctx->mem_idx])()
2309 #if defined(TARGET_PPC64)
2310 #if defined(CONFIG_USER_ONLY)
2311 static GenOpFunc
*gen_op_lwarx
[] = {
2313 &gen_op_lwarx_le_raw
,
2314 &gen_op_lwarx_64_raw
,
2315 &gen_op_lwarx_le_64_raw
,
2317 static GenOpFunc
*gen_op_stwcx
[] = {
2319 &gen_op_stwcx_le_raw
,
2320 &gen_op_stwcx_64_raw
,
2321 &gen_op_stwcx_le_64_raw
,
2324 static GenOpFunc
*gen_op_lwarx
[] = {
2326 &gen_op_lwarx_le_user
,
2327 &gen_op_lwarx_kernel
,
2328 &gen_op_lwarx_le_kernel
,
2329 &gen_op_lwarx_64_user
,
2330 &gen_op_lwarx_le_64_user
,
2331 &gen_op_lwarx_64_kernel
,
2332 &gen_op_lwarx_le_64_kernel
,
2334 static GenOpFunc
*gen_op_stwcx
[] = {
2336 &gen_op_stwcx_le_user
,
2337 &gen_op_stwcx_kernel
,
2338 &gen_op_stwcx_le_kernel
,
2339 &gen_op_stwcx_64_user
,
2340 &gen_op_stwcx_le_64_user
,
2341 &gen_op_stwcx_64_kernel
,
2342 &gen_op_stwcx_le_64_kernel
,
2346 #if defined(CONFIG_USER_ONLY)
2347 static GenOpFunc
*gen_op_lwarx
[] = {
2349 &gen_op_lwarx_le_raw
,
2351 static GenOpFunc
*gen_op_stwcx
[] = {
2353 &gen_op_stwcx_le_raw
,
2356 static GenOpFunc
*gen_op_lwarx
[] = {
2358 &gen_op_lwarx_le_user
,
2359 &gen_op_lwarx_kernel
,
2360 &gen_op_lwarx_le_kernel
,
2362 static GenOpFunc
*gen_op_stwcx
[] = {
2364 &gen_op_stwcx_le_user
,
2365 &gen_op_stwcx_kernel
,
2366 &gen_op_stwcx_le_kernel
,
2372 GEN_HANDLER(lwarx
, 0x1F, 0x14, 0x00, 0x00000001, PPC_RES
)
2374 gen_addr_reg_index(ctx
);
2376 gen_op_store_T1_gpr(rD(ctx
->opcode
));
2380 GEN_HANDLER(stwcx_
, 0x1F, 0x16, 0x04, 0x00000000, PPC_RES
)
2382 gen_addr_reg_index(ctx
);
2383 gen_op_load_gpr_T1(rS(ctx
->opcode
));
2387 #if defined(TARGET_PPC64)
2388 #define op_ldarx() (*gen_op_ldarx[ctx->mem_idx])()
2389 #define op_stdcx() (*gen_op_stdcx[ctx->mem_idx])()
2390 #if defined(CONFIG_USER_ONLY)
2391 static GenOpFunc
*gen_op_ldarx
[] = {
2393 &gen_op_ldarx_le_raw
,
2394 &gen_op_ldarx_64_raw
,
2395 &gen_op_ldarx_le_64_raw
,
2397 static GenOpFunc
*gen_op_stdcx
[] = {
2399 &gen_op_stdcx_le_raw
,
2400 &gen_op_stdcx_64_raw
,
2401 &gen_op_stdcx_le_64_raw
,
2404 static GenOpFunc
*gen_op_ldarx
[] = {
2406 &gen_op_ldarx_le_user
,
2407 &gen_op_ldarx_kernel
,
2408 &gen_op_ldarx_le_kernel
,
2409 &gen_op_ldarx_64_user
,
2410 &gen_op_ldarx_le_64_user
,
2411 &gen_op_ldarx_64_kernel
,
2412 &gen_op_ldarx_le_64_kernel
,
2414 static GenOpFunc
*gen_op_stdcx
[] = {
2416 &gen_op_stdcx_le_user
,
2417 &gen_op_stdcx_kernel
,
2418 &gen_op_stdcx_le_kernel
,
2419 &gen_op_stdcx_64_user
,
2420 &gen_op_stdcx_le_64_user
,
2421 &gen_op_stdcx_64_kernel
,
2422 &gen_op_stdcx_le_64_kernel
,
2427 GEN_HANDLER(ldarx
, 0x1F, 0x14, 0x02, 0x00000001, PPC_RES
)
2429 gen_addr_reg_index(ctx
);
2431 gen_op_store_T1_gpr(rD(ctx
->opcode
));
2435 GEN_HANDLER(stdcx_
, 0x1F, 0x16, 0x06, 0x00000000, PPC_RES
)
2437 gen_addr_reg_index(ctx
);
2438 gen_op_load_gpr_T1(rS(ctx
->opcode
));
2441 #endif /* defined(TARGET_PPC64) */
2444 GEN_HANDLER(sync
, 0x1F, 0x16, 0x12, 0x03FF0801, PPC_MEM_SYNC
)
2448 /*** Floating-point load ***/
2449 #define GEN_LDF(width, opc) \
2450 GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
2452 if (unlikely(!ctx->fpu_enabled)) { \
2453 RET_EXCP(ctx, EXCP_NO_FP, 0); \
2456 gen_addr_imm_index(ctx, 0); \
2457 op_ldst(l##width); \
2458 gen_op_store_FT0_fpr(rD(ctx->opcode)); \
2461 #define GEN_LDUF(width, opc) \
2462 GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
2464 if (unlikely(!ctx->fpu_enabled)) { \
2465 RET_EXCP(ctx, EXCP_NO_FP, 0); \
2468 if (unlikely(rA(ctx->opcode) == 0)) { \
2472 gen_addr_imm_index(ctx, 0); \
2473 op_ldst(l##width); \
2474 gen_op_store_FT0_fpr(rD(ctx->opcode)); \
2475 gen_op_store_T0_gpr(rA(ctx->opcode)); \
2478 #define GEN_LDUXF(width, opc) \
2479 GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \
2481 if (unlikely(!ctx->fpu_enabled)) { \
2482 RET_EXCP(ctx, EXCP_NO_FP, 0); \
2485 if (unlikely(rA(ctx->opcode) == 0)) { \
2489 gen_addr_reg_index(ctx); \
2490 op_ldst(l##width); \
2491 gen_op_store_FT0_fpr(rD(ctx->opcode)); \
2492 gen_op_store_T0_gpr(rA(ctx->opcode)); \
2495 #define GEN_LDXF(width, opc2, opc3) \
2496 GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_FLOAT) \
2498 if (unlikely(!ctx->fpu_enabled)) { \
2499 RET_EXCP(ctx, EXCP_NO_FP, 0); \
2502 gen_addr_reg_index(ctx); \
2503 op_ldst(l##width); \
2504 gen_op_store_FT0_fpr(rD(ctx->opcode)); \
2507 #define GEN_LDFS(width, op) \
2508 OP_LD_TABLE(width); \
2509 GEN_LDF(width, op | 0x20); \
2510 GEN_LDUF(width, op | 0x21); \
2511 GEN_LDUXF(width, op | 0x01); \
2512 GEN_LDXF(width, 0x17, op | 0x00)
2514 /* lfd lfdu lfdux lfdx */
2516 /* lfs lfsu lfsux lfsx */
2519 /*** Floating-point store ***/
2520 #define GEN_STF(width, opc) \
2521 GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
2523 if (unlikely(!ctx->fpu_enabled)) { \
2524 RET_EXCP(ctx, EXCP_NO_FP, 0); \
2527 gen_addr_imm_index(ctx, 0); \
2528 gen_op_load_fpr_FT0(rS(ctx->opcode)); \
2529 op_ldst(st##width); \
2532 #define GEN_STUF(width, opc) \
2533 GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
2535 if (unlikely(!ctx->fpu_enabled)) { \
2536 RET_EXCP(ctx, EXCP_NO_FP, 0); \
2539 if (unlikely(rA(ctx->opcode) == 0)) { \
2543 gen_addr_imm_index(ctx, 0); \
2544 gen_op_load_fpr_FT0(rS(ctx->opcode)); \
2545 op_ldst(st##width); \
2546 gen_op_store_T0_gpr(rA(ctx->opcode)); \
2549 #define GEN_STUXF(width, opc) \
2550 GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \
2552 if (unlikely(!ctx->fpu_enabled)) { \
2553 RET_EXCP(ctx, EXCP_NO_FP, 0); \
2556 if (unlikely(rA(ctx->opcode) == 0)) { \
2560 gen_addr_reg_index(ctx); \
2561 gen_op_load_fpr_FT0(rS(ctx->opcode)); \
2562 op_ldst(st##width); \
2563 gen_op_store_T0_gpr(rA(ctx->opcode)); \
2566 #define GEN_STXF(width, opc2, opc3) \
2567 GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_FLOAT) \
2569 if (unlikely(!ctx->fpu_enabled)) { \
2570 RET_EXCP(ctx, EXCP_NO_FP, 0); \
2573 gen_addr_reg_index(ctx); \
2574 gen_op_load_fpr_FT0(rS(ctx->opcode)); \
2575 op_ldst(st##width); \
2578 #define GEN_STFS(width, op) \
2579 OP_ST_TABLE(width); \
2580 GEN_STF(width, op | 0x20); \
2581 GEN_STUF(width, op | 0x21); \
2582 GEN_STUXF(width, op | 0x01); \
2583 GEN_STXF(width, 0x17, op | 0x00)
2585 /* stfd stfdu stfdux stfdx */
2587 /* stfs stfsu stfsux stfsx */
2592 GEN_HANDLER(stfiwx
, 0x1F, 0x17, 0x1E, 0x00000001, PPC_FLOAT
)
2594 if (unlikely(!ctx
->fpu_enabled
)) {
2595 RET_EXCP(ctx
, EXCP_NO_FP
, 0);
2598 gen_addr_reg_index(ctx
);
2599 /* XXX: TODO: memcpy low order 32 bits of FRP(rs) into memory */
2605 static inline void gen_goto_tb(DisasContext
*ctx
, int n
, target_ulong dest
)
2607 TranslationBlock
*tb
;
2609 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
)) {
2611 gen_op_goto_tb0(TBPARAM(tb
));
2613 gen_op_goto_tb1(TBPARAM(tb
));
2615 #if defined(TARGET_PPC64)
2621 gen_op_set_T0((long)tb
+ n
);
2622 if (ctx
->singlestep_enabled
)
2627 #if defined(TARGET_PPC64)
2634 if (ctx
->singlestep_enabled
)
2641 GEN_HANDLER(b
, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW
)
2643 target_ulong li
, target
;
2645 /* sign extend LI */
2646 #if defined(TARGET_PPC64)
2648 li
= ((int64_t)LI(ctx
->opcode
) << 38) >> 38;
2651 li
= ((int32_t)LI(ctx
->opcode
) << 6) >> 6;
2652 if (likely(AA(ctx
->opcode
) == 0))
2653 target
= ctx
->nip
+ li
- 4;
2656 if (LK(ctx
->opcode
)) {
2657 #if defined(TARGET_PPC64)
2659 gen_op_setlr_64(ctx
->nip
>> 32, ctx
->nip
);
2662 gen_op_setlr(ctx
->nip
);
2664 gen_goto_tb(ctx
, 0, target
);
2665 ctx
->exception
= EXCP_BRANCH
;
2672 static inline void gen_bcond(DisasContext
*ctx
, int type
)
2674 target_ulong target
= 0;
2676 uint32_t bo
= BO(ctx
->opcode
);
2677 uint32_t bi
= BI(ctx
->opcode
);
2680 if ((bo
& 0x4) == 0)
2684 li
= (target_long
)((int16_t)(BD(ctx
->opcode
)));
2685 if (likely(AA(ctx
->opcode
) == 0)) {
2686 target
= ctx
->nip
+ li
- 4;
2692 gen_op_movl_T1_ctr();
2696 gen_op_movl_T1_lr();
2699 if (LK(ctx
->opcode
)) {
2700 #if defined(TARGET_PPC64)
2702 gen_op_setlr_64(ctx
->nip
>> 32, ctx
->nip
);
2705 gen_op_setlr(ctx
->nip
);
2708 /* No CR condition */
2711 #if defined(TARGET_PPC64)
2713 gen_op_test_ctr_64();
2719 #if defined(TARGET_PPC64)
2721 gen_op_test_ctrz_64();
2729 if (type
== BCOND_IM
) {
2730 gen_goto_tb(ctx
, 0, target
);
2732 #if defined(TARGET_PPC64)
2743 mask
= 1 << (3 - (bi
& 0x03));
2744 gen_op_load_crf_T0(bi
>> 2);
2748 #if defined(TARGET_PPC64)
2750 gen_op_test_ctr_true_64(mask
);
2753 gen_op_test_ctr_true(mask
);
2756 #if defined(TARGET_PPC64)
2758 gen_op_test_ctrz_true_64(mask
);
2761 gen_op_test_ctrz_true(mask
);
2766 gen_op_test_true(mask
);
2772 #if defined(TARGET_PPC64)
2774 gen_op_test_ctr_false_64(mask
);
2777 gen_op_test_ctr_false(mask
);
2780 #if defined(TARGET_PPC64)
2782 gen_op_test_ctrz_false_64(mask
);
2785 gen_op_test_ctrz_false(mask
);
2790 gen_op_test_false(mask
);
2795 if (type
== BCOND_IM
) {
2796 int l1
= gen_new_label();
2798 gen_goto_tb(ctx
, 0, target
);
2800 gen_goto_tb(ctx
, 1, ctx
->nip
);
2802 #if defined(TARGET_PPC64)
2804 gen_op_btest_T1_64(ctx
->nip
>> 32, ctx
->nip
);
2807 gen_op_btest_T1(ctx
->nip
);
2810 if (ctx
->singlestep_enabled
)
2814 ctx
->exception
= EXCP_BRANCH
;
2817 GEN_HANDLER(bc
, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW
)
2819 gen_bcond(ctx
, BCOND_IM
);
2822 GEN_HANDLER(bcctr
, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW
)
2824 gen_bcond(ctx
, BCOND_CTR
);
2827 GEN_HANDLER(bclr
, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW
)
2829 gen_bcond(ctx
, BCOND_LR
);
2832 /*** Condition register logical ***/
2833 #define GEN_CRLOGIC(op, opc) \
2834 GEN_HANDLER(cr##op, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER) \
2836 gen_op_load_crf_T0(crbA(ctx->opcode) >> 2); \
2837 gen_op_getbit_T0(3 - (crbA(ctx->opcode) & 0x03)); \
2838 gen_op_load_crf_T1(crbB(ctx->opcode) >> 2); \
2839 gen_op_getbit_T1(3 - (crbB(ctx->opcode) & 0x03)); \
2841 gen_op_load_crf_T1(crbD(ctx->opcode) >> 2); \
2842 gen_op_setcrfbit(~(1 << (3 - (crbD(ctx->opcode) & 0x03))), \
2843 3 - (crbD(ctx->opcode) & 0x03)); \
2844 gen_op_store_T1_crf(crbD(ctx->opcode) >> 2); \
2848 GEN_CRLOGIC(and, 0x08);
2850 GEN_CRLOGIC(andc
, 0x04);
2852 GEN_CRLOGIC(eqv
, 0x09);
2854 GEN_CRLOGIC(nand
, 0x07);
2856 GEN_CRLOGIC(nor
, 0x01);
2858 GEN_CRLOGIC(or, 0x0E);
2860 GEN_CRLOGIC(orc
, 0x0D);
2862 GEN_CRLOGIC(xor, 0x06);
2864 GEN_HANDLER(mcrf
, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER
)
2866 gen_op_load_crf_T0(crfS(ctx
->opcode
));
2867 gen_op_store_T0_crf(crfD(ctx
->opcode
));
2870 /*** System linkage ***/
2871 /* rfi (supervisor only) */
2872 GEN_HANDLER(rfi
, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW
)
2874 #if defined(CONFIG_USER_ONLY)
2877 /* Restore CPU state */
2878 if (unlikely(!ctx
->supervisor
)) {
2887 #if defined(TARGET_PPC64)
2888 GEN_HANDLER(rfid
, 0x13, 0x12, 0x00, 0x03FF8001, PPC_FLOW
)
2890 #if defined(CONFIG_USER_ONLY)
2893 /* Restore CPU state */
2894 if (unlikely(!ctx
->supervisor
)) {
2905 GEN_HANDLER(sc
, 0x11, 0xFF, 0xFF, 0x03FFFFFD, PPC_FLOW
)
2907 #if defined(CONFIG_USER_ONLY)
2908 RET_EXCP(ctx
, EXCP_SYSCALL_USER
, 0);
2910 RET_EXCP(ctx
, EXCP_SYSCALL
, 0);
2916 GEN_HANDLER(tw
, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW
)
2918 gen_op_load_gpr_T0(rA(ctx
->opcode
));
2919 gen_op_load_gpr_T1(rB(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
));
2926 GEN_HANDLER(twi
, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW
)
2928 gen_op_load_gpr_T0(rA(ctx
->opcode
));
2929 gen_set_T1(SIMM(ctx
->opcode
));
2930 /* Update the nip since this might generate a trap exception */
2931 gen_update_nip(ctx
, ctx
->nip
);
2932 gen_op_tw(TO(ctx
->opcode
));
2935 #if defined(TARGET_PPC64)
2937 GEN_HANDLER(td
, 0x1F, 0x04, 0x02, 0x00000001, PPC_64B
)
2939 gen_op_load_gpr_T0(rA(ctx
->opcode
));
2940 gen_op_load_gpr_T1(rB(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 GEN_HANDLER(tdi
, 0x02, 0xFF, 0xFF, 0x00000000, PPC_64B
)
2949 gen_op_load_gpr_T0(rA(ctx
->opcode
));
2950 gen_set_T1(SIMM(ctx
->opcode
));
2951 /* Update the nip since this might generate a trap exception */
2952 gen_update_nip(ctx
, ctx
->nip
);
2953 gen_op_td(TO(ctx
->opcode
));
2957 /*** Processor control ***/
2959 GEN_HANDLER(mcrxr
, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC
)
2961 gen_op_load_xer_cr();
2962 gen_op_store_T0_crf(crfD(ctx
->opcode
));
2963 gen_op_clear_xer_ov();
2964 gen_op_clear_xer_ca();
2968 GEN_HANDLER(mfcr
, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC
)
2972 if (likely(ctx
->opcode
& 0x00100000)) {
2973 crm
= CRM(ctx
->opcode
);
2974 if (likely((crm
^ (crm
- 1)) == 0)) {
2976 gen_op_load_cro(7 - crn
);
2981 gen_op_store_T0_gpr(rD(ctx
->opcode
));
2985 GEN_HANDLER(mfmsr
, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC
)
2987 #if defined(CONFIG_USER_ONLY)
2990 if (unlikely(!ctx
->supervisor
)) {
2995 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3000 #define SPR_NOACCESS ((void *)(-1))
3002 static void spr_noaccess (void *opaque
, int sprn
)
3004 sprn
= ((sprn
>> 5) & 0x1F) | ((sprn
& 0x1F) << 5);
3005 printf("ERROR: try to access SPR %d !\n", sprn
);
3007 #define SPR_NOACCESS (&spr_noaccess)
3011 static inline void gen_op_mfspr (DisasContext
*ctx
)
3013 void (*read_cb
)(void *opaque
, int sprn
);
3014 uint32_t sprn
= SPR(ctx
->opcode
);
3016 #if !defined(CONFIG_USER_ONLY)
3017 if (ctx
->supervisor
)
3018 read_cb
= ctx
->spr_cb
[sprn
].oea_read
;
3021 read_cb
= ctx
->spr_cb
[sprn
].uea_read
;
3022 if (likely(read_cb
!= NULL
)) {
3023 if (likely(read_cb
!= SPR_NOACCESS
)) {
3024 (*read_cb
)(ctx
, sprn
);
3025 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3027 /* Privilege exception */
3028 if (loglevel
!= 0) {
3029 fprintf(logfile
, "Trying to read priviledged spr %d %03x\n",
3032 printf("Trying to read priviledged spr %d %03x\n", sprn
, sprn
);
3037 if (loglevel
!= 0) {
3038 fprintf(logfile
, "Trying to read invalid spr %d %03x\n",
3041 printf("Trying to read invalid spr %d %03x\n", sprn
, sprn
);
3042 RET_EXCP(ctx
, EXCP_PROGRAM
, EXCP_INVAL
| EXCP_INVAL_SPR
);
3046 GEN_HANDLER(mfspr
, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC
)
3052 GEN_HANDLER(mftb
, 0x1F, 0x13, 0x0B, 0x00000001, PPC_TB
)
3058 GEN_HANDLER(mtcrf
, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC
)
3062 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3063 crm
= CRM(ctx
->opcode
);
3064 if (likely((ctx
->opcode
& 0x00100000) || (crm
^ (crm
- 1)) == 0)) {
3066 gen_op_srli_T0(crn
* 4);
3067 gen_op_andi_T0(0xF);
3068 gen_op_store_cro(7 - crn
);
3070 gen_op_store_cr(crm
);
3075 #if defined(TARGET_PPC64)
3076 GEN_HANDLER(mtmsrd
, 0x1F, 0x12, 0x05, 0x001FF801, PPC_MISC
)
3078 #if defined(CONFIG_USER_ONLY)
3081 if (unlikely(!ctx
->supervisor
)) {
3085 gen_update_nip(ctx
, ctx
->nip
);
3086 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3088 /* Must stop the translation as machine state (may have) changed */
3094 GEN_HANDLER(mtmsr
, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC
)
3096 #if defined(CONFIG_USER_ONLY)
3099 if (unlikely(!ctx
->supervisor
)) {
3103 gen_update_nip(ctx
, ctx
->nip
);
3104 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3105 #if defined(TARGET_PPC64)
3107 gen_op_store_msr_32();
3111 /* Must stop the translation as machine state (may have) changed */
3117 GEN_HANDLER(mtspr
, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC
)
3119 void (*write_cb
)(void *opaque
, int sprn
);
3120 uint32_t sprn
= SPR(ctx
->opcode
);
3122 #if !defined(CONFIG_USER_ONLY)
3123 if (ctx
->supervisor
)
3124 write_cb
= ctx
->spr_cb
[sprn
].oea_write
;
3127 write_cb
= ctx
->spr_cb
[sprn
].uea_write
;
3128 if (likely(write_cb
!= NULL
)) {
3129 if (likely(write_cb
!= SPR_NOACCESS
)) {
3130 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3131 (*write_cb
)(ctx
, sprn
);
3133 /* Privilege exception */
3134 if (loglevel
!= 0) {
3135 fprintf(logfile
, "Trying to write priviledged spr %d %03x\n",
3138 printf("Trying to write priviledged spr %d %03x\n", sprn
, sprn
);
3143 if (loglevel
!= 0) {
3144 fprintf(logfile
, "Trying to write invalid spr %d %03x\n",
3147 printf("Trying to write invalid spr %d %03x\n", sprn
, sprn
);
3148 RET_EXCP(ctx
, EXCP_PROGRAM
, EXCP_INVAL
| EXCP_INVAL_SPR
);
3152 /*** Cache management ***/
3153 /* For now, all those will be implemented as nop:
3154 * this is valid, regarding the PowerPC specs...
3155 * We just have to flush tb while invalidating instruction cache lines...
3158 GEN_HANDLER(dcbf
, 0x1F, 0x16, 0x02, 0x03E00001, PPC_CACHE
)
3160 gen_addr_reg_index(ctx
);
3164 /* dcbi (Supervisor only) */
3165 GEN_HANDLER(dcbi
, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE
)
3167 #if defined(CONFIG_USER_ONLY)
3170 if (unlikely(!ctx
->supervisor
)) {
3174 gen_addr_reg_index(ctx
);
3175 /* XXX: specification says this should be treated as a store by the MMU */
3182 GEN_HANDLER(dcbst
, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE
)
3184 /* XXX: specification say this is treated as a load by the MMU */
3185 gen_addr_reg_index(ctx
);
3190 GEN_HANDLER(dcbt
, 0x1F, 0x16, 0x08, 0x03E00001, PPC_CACHE
)
3192 /* XXX: specification say this is treated as a load by the MMU
3193 * but does not generate any exception
3198 GEN_HANDLER(dcbtst
, 0x1F, 0x16, 0x07, 0x03E00001, PPC_CACHE
)
3200 /* XXX: specification say this is treated as a load by the MMU
3201 * but does not generate any exception
3206 #define op_dcbz() (*gen_op_dcbz[ctx->mem_idx])()
3207 #if defined(TARGET_PPC64)
3208 #if defined(CONFIG_USER_ONLY)
3209 static GenOpFunc
*gen_op_dcbz
[] = {
3212 &gen_op_dcbz_64_raw
,
3213 &gen_op_dcbz_64_raw
,
3216 static GenOpFunc
*gen_op_dcbz
[] = {
3219 &gen_op_dcbz_kernel
,
3220 &gen_op_dcbz_kernel
,
3221 &gen_op_dcbz_64_user
,
3222 &gen_op_dcbz_64_user
,
3223 &gen_op_dcbz_64_kernel
,
3224 &gen_op_dcbz_64_kernel
,
3228 #if defined(CONFIG_USER_ONLY)
3229 static GenOpFunc
*gen_op_dcbz
[] = {
3234 static GenOpFunc
*gen_op_dcbz
[] = {
3237 &gen_op_dcbz_kernel
,
3238 &gen_op_dcbz_kernel
,
3243 GEN_HANDLER(dcbz
, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE
)
3245 gen_addr_reg_index(ctx
);
3247 gen_op_check_reservation();
3251 #define op_icbi() (*gen_op_icbi[ctx->mem_idx])()
3252 #if defined(TARGET_PPC64)
3253 #if defined(CONFIG_USER_ONLY)
3254 static GenOpFunc
*gen_op_icbi
[] = {
3257 &gen_op_icbi_64_raw
,
3258 &gen_op_icbi_64_raw
,
3261 static GenOpFunc
*gen_op_icbi
[] = {
3264 &gen_op_icbi_kernel
,
3265 &gen_op_icbi_kernel
,
3266 &gen_op_icbi_64_user
,
3267 &gen_op_icbi_64_user
,
3268 &gen_op_icbi_64_kernel
,
3269 &gen_op_icbi_64_kernel
,
3273 #if defined(CONFIG_USER_ONLY)
3274 static GenOpFunc
*gen_op_icbi
[] = {
3279 static GenOpFunc
*gen_op_icbi
[] = {
3282 &gen_op_icbi_kernel
,
3283 &gen_op_icbi_kernel
,
3287 GEN_HANDLER(icbi
, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE
)
3289 /* NIP cannot be restored if the memory exception comes from an helper */
3290 gen_update_nip(ctx
, ctx
->nip
- 4);
3291 gen_addr_reg_index(ctx
);
3298 GEN_HANDLER(dcba
, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_OPT
)
3302 /*** Segment register manipulation ***/
3303 /* Supervisor only: */
3305 GEN_HANDLER(mfsr
, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT
)
3307 #if defined(CONFIG_USER_ONLY)
3310 if (unlikely(!ctx
->supervisor
)) {
3314 gen_op_set_T1(SR(ctx
->opcode
));
3316 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3321 GEN_HANDLER(mfsrin
, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT
)
3323 #if defined(CONFIG_USER_ONLY)
3326 if (unlikely(!ctx
->supervisor
)) {
3330 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3333 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3338 GEN_HANDLER(mtsr
, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT
)
3340 #if defined(CONFIG_USER_ONLY)
3343 if (unlikely(!ctx
->supervisor
)) {
3347 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3348 gen_op_set_T1(SR(ctx
->opcode
));
3355 GEN_HANDLER(mtsrin
, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT
)
3357 #if defined(CONFIG_USER_ONLY)
3360 if (unlikely(!ctx
->supervisor
)) {
3364 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3365 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3372 /*** Lookaside buffer management ***/
3373 /* Optional & supervisor only: */
3375 GEN_HANDLER(tlbia
, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA
)
3377 #if defined(CONFIG_USER_ONLY)
3380 if (unlikely(!ctx
->supervisor
)) {
3382 fprintf(logfile
, "%s: ! supervisor\n", __func__
);
3392 GEN_HANDLER(tlbie
, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE
)
3394 #if defined(CONFIG_USER_ONLY)
3397 if (unlikely(!ctx
->supervisor
)) {
3401 gen_op_load_gpr_T0(rB(ctx
->opcode
));
3402 #if defined(TARGET_PPC64)
3413 GEN_HANDLER(tlbsync
, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC
)
3415 #if defined(CONFIG_USER_ONLY)
3418 if (unlikely(!ctx
->supervisor
)) {
3422 /* This has no effect: it should ensure that all previous
3423 * tlbie have completed
3429 #if defined(TARGET_PPC64)
3431 GEN_HANDLER(slbia
, 0x1F, 0x12, 0x0F, 0x03FFFC01, PPC_SLBI
)
3433 #if defined(CONFIG_USER_ONLY)
3436 if (unlikely(!ctx
->supervisor
)) {
3438 fprintf(logfile
, "%s: ! supervisor\n", __func__
);
3448 GEN_HANDLER(slbie
, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI
)
3450 #if defined(CONFIG_USER_ONLY)
3453 if (unlikely(!ctx
->supervisor
)) {
3457 gen_op_load_gpr_T0(rB(ctx
->opcode
));
3464 /*** External control ***/
3466 #define op_eciwx() (*gen_op_eciwx[ctx->mem_idx])()
3467 #define op_ecowx() (*gen_op_ecowx[ctx->mem_idx])()
3468 #if defined(TARGET_PPC64)
3469 #if defined(CONFIG_USER_ONLY)
3470 static GenOpFunc
*gen_op_eciwx
[] = {
3472 &gen_op_eciwx_le_raw
,
3473 &gen_op_eciwx_64_raw
,
3474 &gen_op_eciwx_le_64_raw
,
3476 static GenOpFunc
*gen_op_ecowx
[] = {
3478 &gen_op_ecowx_le_raw
,
3479 &gen_op_ecowx_64_raw
,
3480 &gen_op_ecowx_le_64_raw
,
3483 static GenOpFunc
*gen_op_eciwx
[] = {
3485 &gen_op_eciwx_le_user
,
3486 &gen_op_eciwx_kernel
,
3487 &gen_op_eciwx_le_kernel
,
3488 &gen_op_eciwx_64_user
,
3489 &gen_op_eciwx_le_64_user
,
3490 &gen_op_eciwx_64_kernel
,
3491 &gen_op_eciwx_le_64_kernel
,
3493 static GenOpFunc
*gen_op_ecowx
[] = {
3495 &gen_op_ecowx_le_user
,
3496 &gen_op_ecowx_kernel
,
3497 &gen_op_ecowx_le_kernel
,
3498 &gen_op_ecowx_64_user
,
3499 &gen_op_ecowx_le_64_user
,
3500 &gen_op_ecowx_64_kernel
,
3501 &gen_op_ecowx_le_64_kernel
,
3505 #if defined(CONFIG_USER_ONLY)
3506 static GenOpFunc
*gen_op_eciwx
[] = {
3508 &gen_op_eciwx_le_raw
,
3510 static GenOpFunc
*gen_op_ecowx
[] = {
3512 &gen_op_ecowx_le_raw
,
3515 static GenOpFunc
*gen_op_eciwx
[] = {
3517 &gen_op_eciwx_le_user
,
3518 &gen_op_eciwx_kernel
,
3519 &gen_op_eciwx_le_kernel
,
3521 static GenOpFunc
*gen_op_ecowx
[] = {
3523 &gen_op_ecowx_le_user
,
3524 &gen_op_ecowx_kernel
,
3525 &gen_op_ecowx_le_kernel
,
3531 GEN_HANDLER(eciwx
, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN
)
3533 /* Should check EAR[E] & alignment ! */
3534 gen_addr_reg_index(ctx
);
3536 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3540 GEN_HANDLER(ecowx
, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN
)
3542 /* Should check EAR[E] & alignment ! */
3543 gen_addr_reg_index(ctx
);
3544 gen_op_load_gpr_T1(rS(ctx
->opcode
));
3548 /* PowerPC 601 specific instructions */
3550 GEN_HANDLER(abs
, 0x1F, 0x08, 0x0B, 0x0000F800, PPC_POWER_BR
)
3552 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3554 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3555 if (unlikely(Rc(ctx
->opcode
) != 0))
3560 GEN_HANDLER(abso
, 0x1F, 0x08, 0x1B, 0x0000F800, PPC_POWER_BR
)
3562 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3563 gen_op_POWER_abso();
3564 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3565 if (unlikely(Rc(ctx
->opcode
) != 0))
3570 GEN_HANDLER(clcs
, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR
) /* 601 ? */
3572 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3573 gen_op_POWER_clcs();
3574 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3578 GEN_HANDLER(div
, 0x1F, 0x0B, 0x0A, 0x00000000, PPC_POWER_BR
)
3580 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3581 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3583 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3584 if (unlikely(Rc(ctx
->opcode
) != 0))
3589 GEN_HANDLER(divo
, 0x1F, 0x0B, 0x1A, 0x00000000, PPC_POWER_BR
)
3591 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3592 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3593 gen_op_POWER_divo();
3594 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3595 if (unlikely(Rc(ctx
->opcode
) != 0))
3600 GEN_HANDLER(divs
, 0x1F, 0x0B, 0x0B, 0x00000000, PPC_POWER_BR
)
3602 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3603 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3604 gen_op_POWER_divs();
3605 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3606 if (unlikely(Rc(ctx
->opcode
) != 0))
3610 /* divso - divso. */
3611 GEN_HANDLER(divso
, 0x1F, 0x0B, 0x1B, 0x00000000, PPC_POWER_BR
)
3613 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3614 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3615 gen_op_POWER_divso();
3616 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3617 if (unlikely(Rc(ctx
->opcode
) != 0))
3622 GEN_HANDLER(doz
, 0x1F, 0x08, 0x08, 0x00000000, PPC_POWER_BR
)
3624 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3625 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3627 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3628 if (unlikely(Rc(ctx
->opcode
) != 0))
3633 GEN_HANDLER(dozo
, 0x1F, 0x08, 0x18, 0x00000000, PPC_POWER_BR
)
3635 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3636 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3637 gen_op_POWER_dozo();
3638 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3639 if (unlikely(Rc(ctx
->opcode
) != 0))
3644 GEN_HANDLER(dozi
, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR
)
3646 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3647 gen_op_set_T1(SIMM(ctx
->opcode
));
3649 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3652 /* As lscbx load from memory byte after byte, it's always endian safe */
3653 #define op_POWER_lscbx(start, ra, rb) \
3654 (*gen_op_POWER_lscbx[ctx->mem_idx])(start, ra, rb)
3655 #if defined(CONFIG_USER_ONLY)
3656 static GenOpFunc3
*gen_op_POWER_lscbx
[] = {
3657 &gen_op_POWER_lscbx_raw
,
3658 &gen_op_POWER_lscbx_raw
,
3661 static GenOpFunc3
*gen_op_POWER_lscbx
[] = {
3662 &gen_op_POWER_lscbx_user
,
3663 &gen_op_POWER_lscbx_user
,
3664 &gen_op_POWER_lscbx_kernel
,
3665 &gen_op_POWER_lscbx_kernel
,
3669 /* lscbx - lscbx. */
3670 GEN_HANDLER(lscbx
, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR
)
3672 int ra
= rA(ctx
->opcode
);
3673 int rb
= rB(ctx
->opcode
);
3675 gen_addr_reg_index(ctx
);
3679 /* NIP cannot be restored if the memory exception comes from an helper */
3680 gen_update_nip(ctx
, ctx
->nip
- 4);
3681 gen_op_load_xer_bc();
3682 gen_op_load_xer_cmp();
3683 op_POWER_lscbx(rD(ctx
->opcode
), ra
, rb
);
3684 gen_op_store_xer_bc();
3685 if (unlikely(Rc(ctx
->opcode
) != 0))
3689 /* maskg - maskg. */
3690 GEN_HANDLER(maskg
, 0x1F, 0x1D, 0x00, 0x00000000, PPC_POWER_BR
)
3692 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3693 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3694 gen_op_POWER_maskg();
3695 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3696 if (unlikely(Rc(ctx
->opcode
) != 0))
3700 /* maskir - maskir. */
3701 GEN_HANDLER(maskir
, 0x1F, 0x1D, 0x10, 0x00000000, PPC_POWER_BR
)
3703 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3704 gen_op_load_gpr_T1(rS(ctx
->opcode
));
3705 gen_op_load_gpr_T2(rB(ctx
->opcode
));
3706 gen_op_POWER_maskir();
3707 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3708 if (unlikely(Rc(ctx
->opcode
) != 0))
3713 GEN_HANDLER(mul
, 0x1F, 0x0B, 0x03, 0x00000000, PPC_POWER_BR
)
3715 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3716 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3718 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3719 if (unlikely(Rc(ctx
->opcode
) != 0))
3724 GEN_HANDLER(mulo
, 0x1F, 0x0B, 0x13, 0x00000000, PPC_POWER_BR
)
3726 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3727 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3728 gen_op_POWER_mulo();
3729 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3730 if (unlikely(Rc(ctx
->opcode
) != 0))
3735 GEN_HANDLER(nabs
, 0x1F, 0x08, 0x0F, 0x00000000, PPC_POWER_BR
)
3737 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3738 gen_op_POWER_nabs();
3739 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3740 if (unlikely(Rc(ctx
->opcode
) != 0))
3744 /* nabso - nabso. */
3745 GEN_HANDLER(nabso
, 0x1F, 0x08, 0x1F, 0x00000000, PPC_POWER_BR
)
3747 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3748 gen_op_POWER_nabso();
3749 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3750 if (unlikely(Rc(ctx
->opcode
) != 0))
3755 GEN_HANDLER(rlmi
, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR
)
3759 mb
= MB(ctx
->opcode
);
3760 me
= ME(ctx
->opcode
);
3761 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3762 gen_op_load_gpr_T1(rA(ctx
->opcode
));
3763 gen_op_load_gpr_T2(rB(ctx
->opcode
));
3764 gen_op_POWER_rlmi(MASK(mb
, me
), ~MASK(mb
, me
));
3765 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3766 if (unlikely(Rc(ctx
->opcode
) != 0))
3771 GEN_HANDLER(rrib
, 0x1F, 0x19, 0x10, 0x00000000, PPC_POWER_BR
)
3773 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3774 gen_op_load_gpr_T1(rA(ctx
->opcode
));
3775 gen_op_load_gpr_T2(rB(ctx
->opcode
));
3776 gen_op_POWER_rrib();
3777 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3778 if (unlikely(Rc(ctx
->opcode
) != 0))
3783 GEN_HANDLER(sle
, 0x1F, 0x19, 0x04, 0x00000000, PPC_POWER_BR
)
3785 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3786 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3788 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3789 if (unlikely(Rc(ctx
->opcode
) != 0))
3794 GEN_HANDLER(sleq
, 0x1F, 0x19, 0x06, 0x00000000, PPC_POWER_BR
)
3796 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3797 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3798 gen_op_POWER_sleq();
3799 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3800 if (unlikely(Rc(ctx
->opcode
) != 0))
3805 GEN_HANDLER(sliq
, 0x1F, 0x18, 0x05, 0x00000000, PPC_POWER_BR
)
3807 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3808 gen_op_set_T1(SH(ctx
->opcode
));
3810 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3811 if (unlikely(Rc(ctx
->opcode
) != 0))
3815 /* slliq - slliq. */
3816 GEN_HANDLER(slliq
, 0x1F, 0x18, 0x07, 0x00000000, PPC_POWER_BR
)
3818 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3819 gen_op_set_T1(SH(ctx
->opcode
));
3820 gen_op_POWER_sleq();
3821 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3822 if (unlikely(Rc(ctx
->opcode
) != 0))
3827 GEN_HANDLER(sllq
, 0x1F, 0x18, 0x06, 0x00000000, PPC_POWER_BR
)
3829 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3830 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3831 gen_op_POWER_sllq();
3832 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3833 if (unlikely(Rc(ctx
->opcode
) != 0))
3838 GEN_HANDLER(slq
, 0x1F, 0x18, 0x04, 0x00000000, PPC_POWER_BR
)
3840 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3841 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3843 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3844 if (unlikely(Rc(ctx
->opcode
) != 0))
3848 /* sraiq - sraiq. */
3849 GEN_HANDLER(sraiq
, 0x1F, 0x18, 0x1D, 0x00000000, PPC_POWER_BR
)
3851 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3852 gen_op_set_T1(SH(ctx
->opcode
));
3853 gen_op_POWER_sraq();
3854 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3855 if (unlikely(Rc(ctx
->opcode
) != 0))
3860 GEN_HANDLER(sraq
, 0x1F, 0x18, 0x1C, 0x00000000, PPC_POWER_BR
)
3862 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3863 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3864 gen_op_POWER_sraq();
3865 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3866 if (unlikely(Rc(ctx
->opcode
) != 0))
3871 GEN_HANDLER(sre
, 0x1F, 0x19, 0x14, 0x00000000, PPC_POWER_BR
)
3873 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3874 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3876 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3877 if (unlikely(Rc(ctx
->opcode
) != 0))
3882 GEN_HANDLER(srea
, 0x1F, 0x19, 0x1C, 0x00000000, PPC_POWER_BR
)
3884 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3885 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3886 gen_op_POWER_srea();
3887 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3888 if (unlikely(Rc(ctx
->opcode
) != 0))
3893 GEN_HANDLER(sreq
, 0x1F, 0x19, 0x16, 0x00000000, PPC_POWER_BR
)
3895 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3896 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3897 gen_op_POWER_sreq();
3898 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3899 if (unlikely(Rc(ctx
->opcode
) != 0))
3904 GEN_HANDLER(sriq
, 0x1F, 0x18, 0x15, 0x00000000, PPC_POWER_BR
)
3906 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3907 gen_op_set_T1(SH(ctx
->opcode
));
3909 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3910 if (unlikely(Rc(ctx
->opcode
) != 0))
3915 GEN_HANDLER(srliq
, 0x1F, 0x18, 0x17, 0x00000000, PPC_POWER_BR
)
3917 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3918 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3919 gen_op_set_T1(SH(ctx
->opcode
));
3920 gen_op_POWER_srlq();
3921 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3922 if (unlikely(Rc(ctx
->opcode
) != 0))
3927 GEN_HANDLER(srlq
, 0x1F, 0x18, 0x16, 0x00000000, PPC_POWER_BR
)
3929 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3930 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3931 gen_op_POWER_srlq();
3932 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3933 if (unlikely(Rc(ctx
->opcode
) != 0))
3938 GEN_HANDLER(srq
, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR
)
3940 gen_op_load_gpr_T0(rS(ctx
->opcode
));
3941 gen_op_load_gpr_T1(rB(ctx
->opcode
));
3943 gen_op_store_T0_gpr(rA(ctx
->opcode
));
3944 if (unlikely(Rc(ctx
->opcode
) != 0))
3948 /* PowerPC 602 specific instructions */
3950 GEN_HANDLER(dsa
, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC
)
3957 GEN_HANDLER(esa
, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC
)
3964 GEN_HANDLER(mfrom
, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC
)
3966 #if defined(CONFIG_USER_ONLY)
3969 if (unlikely(!ctx
->supervisor
)) {
3973 gen_op_load_gpr_T0(rA(ctx
->opcode
));
3975 gen_op_store_T0_gpr(rD(ctx
->opcode
));
3979 /* 602 - 603 - G2 TLB management */
3981 GEN_HANDLER(tlbld
, 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB
)
3983 #if defined(CONFIG_USER_ONLY)
3986 if (unlikely(!ctx
->supervisor
)) {
3990 gen_op_load_gpr_T0(rB(ctx
->opcode
));
3997 GEN_HANDLER(tlbli
, 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB
)
3999 #if defined(CONFIG_USER_ONLY)
4002 if (unlikely(!ctx
->supervisor
)) {
4006 gen_op_load_gpr_T0(rB(ctx
->opcode
));
4012 /* POWER instructions not in PowerPC 601 */
4014 GEN_HANDLER(clf
, 0x1F, 0x16, 0x03, 0x03E00000, PPC_POWER
)
4016 /* Cache line flush: implemented as no-op */
4020 GEN_HANDLER(cli
, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER
)
4022 /* Cache line invalidate: priviledged and treated as no-op */
4023 #if defined(CONFIG_USER_ONLY)
4026 if (unlikely(!ctx
->supervisor
)) {
4034 GEN_HANDLER(dclst
, 0x1F, 0x16, 0x13, 0x03E00000, PPC_POWER
)
4036 /* Data cache line store: treated as no-op */
4039 GEN_HANDLER(mfsri
, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER
)
4041 #if defined(CONFIG_USER_ONLY)
4044 if (unlikely(!ctx
->supervisor
)) {
4048 int ra
= rA(ctx
->opcode
);
4049 int rd
= rD(ctx
->opcode
);
4051 gen_addr_reg_index(ctx
);
4052 gen_op_POWER_mfsri();
4053 gen_op_store_T0_gpr(rd
);
4054 if (ra
!= 0 && ra
!= rd
)
4055 gen_op_store_T1_gpr(ra
);
4059 GEN_HANDLER(rac
, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER
)
4061 #if defined(CONFIG_USER_ONLY)
4064 if (unlikely(!ctx
->supervisor
)) {
4068 gen_addr_reg_index(ctx
);
4070 gen_op_store_T0_gpr(rD(ctx
->opcode
));
4074 GEN_HANDLER(rfsvc
, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER
)
4076 #if defined(CONFIG_USER_ONLY)
4079 if (unlikely(!ctx
->supervisor
)) {
4083 gen_op_POWER_rfsvc();
4088 /* svc is not implemented for now */
4090 /* POWER2 specific instructions */
4091 /* Quad manipulation (load/store two floats at a time) */
4092 #define op_POWER2_lfq() (*gen_op_POWER2_lfq[ctx->mem_idx])()
4093 #define op_POWER2_stfq() (*gen_op_POWER2_stfq[ctx->mem_idx])()
4094 #if defined(CONFIG_USER_ONLY)
4095 static GenOpFunc
*gen_op_POWER2_lfq
[] = {
4096 &gen_op_POWER2_lfq_le_raw
,
4097 &gen_op_POWER2_lfq_raw
,
4099 static GenOpFunc
*gen_op_POWER2_stfq
[] = {
4100 &gen_op_POWER2_stfq_le_raw
,
4101 &gen_op_POWER2_stfq_raw
,
4104 static GenOpFunc
*gen_op_POWER2_lfq
[] = {
4105 &gen_op_POWER2_lfq_le_user
,
4106 &gen_op_POWER2_lfq_user
,
4107 &gen_op_POWER2_lfq_le_kernel
,
4108 &gen_op_POWER2_lfq_kernel
,
4110 static GenOpFunc
*gen_op_POWER2_stfq
[] = {
4111 &gen_op_POWER2_stfq_le_user
,
4112 &gen_op_POWER2_stfq_user
,
4113 &gen_op_POWER2_stfq_le_kernel
,
4114 &gen_op_POWER2_stfq_kernel
,
4119 GEN_HANDLER(lfq
, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2
)
4121 /* NIP cannot be restored if the memory exception comes from an helper */
4122 gen_update_nip(ctx
, ctx
->nip
- 4);
4123 gen_addr_imm_index(ctx
, 0);
4125 gen_op_store_FT0_fpr(rD(ctx
->opcode
));
4126 gen_op_store_FT1_fpr(rD(ctx
->opcode
) + 1);
4130 GEN_HANDLER(lfqu
, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2
)
4132 int ra
= rA(ctx
->opcode
);
4134 /* NIP cannot be restored if the memory exception comes from an helper */
4135 gen_update_nip(ctx
, ctx
->nip
- 4);
4136 gen_addr_imm_index(ctx
, 0);
4138 gen_op_store_FT0_fpr(rD(ctx
->opcode
));
4139 gen_op_store_FT1_fpr(rD(ctx
->opcode
) + 1);
4141 gen_op_store_T0_gpr(ra
);
4145 GEN_HANDLER(lfqux
, 0x1F, 0x17, 0x19, 0x00000001, PPC_POWER2
)
4147 int ra
= rA(ctx
->opcode
);
4149 /* NIP cannot be restored if the memory exception comes from an helper */
4150 gen_update_nip(ctx
, ctx
->nip
- 4);
4151 gen_addr_reg_index(ctx
);
4153 gen_op_store_FT0_fpr(rD(ctx
->opcode
));
4154 gen_op_store_FT1_fpr(rD(ctx
->opcode
) + 1);
4156 gen_op_store_T0_gpr(ra
);
4160 GEN_HANDLER(lfqx
, 0x1F, 0x17, 0x18, 0x00000001, PPC_POWER2
)
4162 /* NIP cannot be restored if the memory exception comes from an helper */
4163 gen_update_nip(ctx
, ctx
->nip
- 4);
4164 gen_addr_reg_index(ctx
);
4166 gen_op_store_FT0_fpr(rD(ctx
->opcode
));
4167 gen_op_store_FT1_fpr(rD(ctx
->opcode
) + 1);
4171 GEN_HANDLER(stfq
, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2
)
4173 /* NIP cannot be restored if the memory exception comes from an helper */
4174 gen_update_nip(ctx
, ctx
->nip
- 4);
4175 gen_addr_imm_index(ctx
, 0);
4176 gen_op_load_fpr_FT0(rS(ctx
->opcode
));
4177 gen_op_load_fpr_FT1(rS(ctx
->opcode
) + 1);
4182 GEN_HANDLER(stfqu
, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2
)
4184 int ra
= rA(ctx
->opcode
);
4186 /* NIP cannot be restored if the memory exception comes from an helper */
4187 gen_update_nip(ctx
, ctx
->nip
- 4);
4188 gen_addr_imm_index(ctx
, 0);
4189 gen_op_load_fpr_FT0(rS(ctx
->opcode
));
4190 gen_op_load_fpr_FT1(rS(ctx
->opcode
) + 1);
4193 gen_op_store_T0_gpr(ra
);
4197 GEN_HANDLER(stfqux
, 0x1F, 0x17, 0x1D, 0x00000001, PPC_POWER2
)
4199 int ra
= rA(ctx
->opcode
);
4201 /* NIP cannot be restored if the memory exception comes from an helper */
4202 gen_update_nip(ctx
, ctx
->nip
- 4);
4203 gen_addr_reg_index(ctx
);
4204 gen_op_load_fpr_FT0(rS(ctx
->opcode
));
4205 gen_op_load_fpr_FT1(rS(ctx
->opcode
) + 1);
4208 gen_op_store_T0_gpr(ra
);
4212 GEN_HANDLER(stfqx
, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2
)
4214 /* NIP cannot be restored if the memory exception comes from an helper */
4215 gen_update_nip(ctx
, ctx
->nip
- 4);
4216 gen_addr_reg_index(ctx
);
4217 gen_op_load_fpr_FT0(rS(ctx
->opcode
));
4218 gen_op_load_fpr_FT1(rS(ctx
->opcode
) + 1);
4222 /* BookE specific instructions */
4223 GEN_HANDLER(mfapidi
, 0x1F, 0x13, 0x08, 0x0000F801, PPC_BOOKE
)
4229 GEN_HANDLER(tlbiva
, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_BOOKE
)
4231 #if defined(CONFIG_USER_ONLY)
4234 if (unlikely(!ctx
->supervisor
)) {
4238 gen_addr_reg_index(ctx
);
4239 /* Use the same micro-ops as for tlbie */
4240 #if defined(TARGET_PPC64)
4250 /* All 405 MAC instructions are translated here */
4251 static inline void gen_405_mulladd_insn (DisasContext
*ctx
, int opc2
, int opc3
,
4252 int ra
, int rb
, int rt
, int Rc
)
4254 gen_op_load_gpr_T0(ra
);
4255 gen_op_load_gpr_T1(rb
);
4256 switch (opc3
& 0x0D) {
4258 /* macchw - macchw. - macchwo - macchwo. */
4259 /* macchws - macchws. - macchwso - macchwso. */
4260 /* nmacchw - nmacchw. - nmacchwo - nmacchwo. */
4261 /* nmacchws - nmacchws. - nmacchwso - nmacchwso. */
4262 /* mulchw - mulchw. */
4263 gen_op_405_mulchw();
4266 /* macchwu - macchwu. - macchwuo - macchwuo. */
4267 /* macchwsu - macchwsu. - macchwsuo - macchwsuo. */
4268 /* mulchwu - mulchwu. */
4269 gen_op_405_mulchwu();
4272 /* machhw - machhw. - machhwo - machhwo. */
4273 /* machhws - machhws. - machhwso - machhwso. */
4274 /* nmachhw - nmachhw. - nmachhwo - nmachhwo. */
4275 /* nmachhws - nmachhws. - nmachhwso - nmachhwso. */
4276 /* mulhhw - mulhhw. */
4277 gen_op_405_mulhhw();
4280 /* machhwu - machhwu. - machhwuo - machhwuo. */
4281 /* machhwsu - machhwsu. - machhwsuo - machhwsuo. */
4282 /* mulhhwu - mulhhwu. */
4283 gen_op_405_mulhhwu();
4286 /* maclhw - maclhw. - maclhwo - maclhwo. */
4287 /* maclhws - maclhws. - maclhwso - maclhwso. */
4288 /* nmaclhw - nmaclhw. - nmaclhwo - nmaclhwo. */
4289 /* nmaclhws - nmaclhws. - nmaclhwso - nmaclhwso. */
4290 /* mullhw - mullhw. */
4291 gen_op_405_mullhw();
4294 /* maclhwu - maclhwu. - maclhwuo - maclhwuo. */
4295 /* maclhwsu - maclhwsu. - maclhwsuo - maclhwsuo. */
4296 /* mullhwu - mullhwu. */
4297 gen_op_405_mullhwu();
4301 /* nmultiply-and-accumulate (0x0E) */
4305 /* (n)multiply-and-accumulate (0x0C - 0x0E) */
4306 gen_op_load_gpr_T2(rt
);
4307 gen_op_move_T1_T0();
4308 gen_op_405_add_T0_T2();
4311 /* Check overflow */
4313 gen_op_405_check_ov();
4315 gen_op_405_check_ovu();
4320 gen_op_405_check_sat();
4322 gen_op_405_check_satu();
4324 gen_op_store_T0_gpr(rt
);
4325 if (unlikely(Rc
) != 0) {
4331 #define GEN_MAC_HANDLER(name, opc2, opc3) \
4332 GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC) \
4334 gen_405_mulladd_insn(ctx, opc2, opc3, rA(ctx->opcode), rB(ctx->opcode), \
4335 rD(ctx->opcode), Rc(ctx->opcode)); \
4338 /* macchw - macchw. */
4339 GEN_MAC_HANDLER(macchw
, 0x0C, 0x05);
4340 /* macchwo - macchwo. */
4341 GEN_MAC_HANDLER(macchwo
, 0x0C, 0x15);
4342 /* macchws - macchws. */
4343 GEN_MAC_HANDLER(macchws
, 0x0C, 0x07);
4344 /* macchwso - macchwso. */
4345 GEN_MAC_HANDLER(macchwso
, 0x0C, 0x17);
4346 /* macchwsu - macchwsu. */
4347 GEN_MAC_HANDLER(macchwsu
, 0x0C, 0x06);
4348 /* macchwsuo - macchwsuo. */
4349 GEN_MAC_HANDLER(macchwsuo
, 0x0C, 0x16);
4350 /* macchwu - macchwu. */
4351 GEN_MAC_HANDLER(macchwu
, 0x0C, 0x04);
4352 /* macchwuo - macchwuo. */
4353 GEN_MAC_HANDLER(macchwuo
, 0x0C, 0x14);
4354 /* machhw - machhw. */
4355 GEN_MAC_HANDLER(machhw
, 0x0C, 0x01);
4356 /* machhwo - machhwo. */
4357 GEN_MAC_HANDLER(machhwo
, 0x0C, 0x11);
4358 /* machhws - machhws. */
4359 GEN_MAC_HANDLER(machhws
, 0x0C, 0x03);
4360 /* machhwso - machhwso. */
4361 GEN_MAC_HANDLER(machhwso
, 0x0C, 0x13);
4362 /* machhwsu - machhwsu. */
4363 GEN_MAC_HANDLER(machhwsu
, 0x0C, 0x02);
4364 /* machhwsuo - machhwsuo. */
4365 GEN_MAC_HANDLER(machhwsuo
, 0x0C, 0x12);
4366 /* machhwu - machhwu. */
4367 GEN_MAC_HANDLER(machhwu
, 0x0C, 0x00);
4368 /* machhwuo - machhwuo. */
4369 GEN_MAC_HANDLER(machhwuo
, 0x0C, 0x10);
4370 /* maclhw - maclhw. */
4371 GEN_MAC_HANDLER(maclhw
, 0x0C, 0x0D);
4372 /* maclhwo - maclhwo. */
4373 GEN_MAC_HANDLER(maclhwo
, 0x0C, 0x1D);
4374 /* maclhws - maclhws. */
4375 GEN_MAC_HANDLER(maclhws
, 0x0C, 0x0F);
4376 /* maclhwso - maclhwso. */
4377 GEN_MAC_HANDLER(maclhwso
, 0x0C, 0x1F);
4378 /* maclhwu - maclhwu. */
4379 GEN_MAC_HANDLER(maclhwu
, 0x0C, 0x0C);
4380 /* maclhwuo - maclhwuo. */
4381 GEN_MAC_HANDLER(maclhwuo
, 0x0C, 0x1C);
4382 /* maclhwsu - maclhwsu. */
4383 GEN_MAC_HANDLER(maclhwsu
, 0x0C, 0x0E);
4384 /* maclhwsuo - maclhwsuo. */
4385 GEN_MAC_HANDLER(maclhwsuo
, 0x0C, 0x1E);
4386 /* nmacchw - nmacchw. */
4387 GEN_MAC_HANDLER(nmacchw
, 0x0E, 0x05);
4388 /* nmacchwo - nmacchwo. */
4389 GEN_MAC_HANDLER(nmacchwo
, 0x0E, 0x15);
4390 /* nmacchws - nmacchws. */
4391 GEN_MAC_HANDLER(nmacchws
, 0x0E, 0x07);
4392 /* nmacchwso - nmacchwso. */
4393 GEN_MAC_HANDLER(nmacchwso
, 0x0E, 0x17);
4394 /* nmachhw - nmachhw. */
4395 GEN_MAC_HANDLER(nmachhw
, 0x0E, 0x01);
4396 /* nmachhwo - nmachhwo. */
4397 GEN_MAC_HANDLER(nmachhwo
, 0x0E, 0x11);
4398 /* nmachhws - nmachhws. */
4399 GEN_MAC_HANDLER(nmachhws
, 0x0E, 0x03);
4400 /* nmachhwso - nmachhwso. */
4401 GEN_MAC_HANDLER(nmachhwso
, 0x0E, 0x13);
4402 /* nmaclhw - nmaclhw. */
4403 GEN_MAC_HANDLER(nmaclhw
, 0x0E, 0x0D);
4404 /* nmaclhwo - nmaclhwo. */
4405 GEN_MAC_HANDLER(nmaclhwo
, 0x0E, 0x1D);
4406 /* nmaclhws - nmaclhws. */
4407 GEN_MAC_HANDLER(nmaclhws
, 0x0E, 0x0F);
4408 /* nmaclhwso - nmaclhwso. */
4409 GEN_MAC_HANDLER(nmaclhwso
, 0x0E, 0x1F);
4411 /* mulchw - mulchw. */
4412 GEN_MAC_HANDLER(mulchw
, 0x08, 0x05);
4413 /* mulchwu - mulchwu. */
4414 GEN_MAC_HANDLER(mulchwu
, 0x08, 0x04);
4415 /* mulhhw - mulhhw. */
4416 GEN_MAC_HANDLER(mulhhw
, 0x08, 0x01);
4417 /* mulhhwu - mulhhwu. */
4418 GEN_MAC_HANDLER(mulhhwu
, 0x08, 0x00);
4419 /* mullhw - mullhw. */
4420 GEN_MAC_HANDLER(mullhw
, 0x08, 0x0D);
4421 /* mullhwu - mullhwu. */
4422 GEN_MAC_HANDLER(mullhwu
, 0x08, 0x0C);
4425 GEN_HANDLER(mfdcr
, 0x1F, 0x03, 0x0A, 0x00000001, PPC_EMB_COMMON
)
4427 #if defined(CONFIG_USER_ONLY)
4430 uint32_t dcrn
= SPR(ctx
->opcode
);
4432 if (unlikely(!ctx
->supervisor
)) {
4436 gen_op_set_T0(dcrn
);
4438 gen_op_store_T0_gpr(rD(ctx
->opcode
));
4443 GEN_HANDLER(mtdcr
, 0x1F, 0x03, 0x0E, 0x00000001, PPC_EMB_COMMON
)
4445 #if defined(CONFIG_USER_ONLY)
4448 uint32_t dcrn
= SPR(ctx
->opcode
);
4450 if (unlikely(!ctx
->supervisor
)) {
4454 gen_op_set_T0(dcrn
);
4455 gen_op_load_gpr_T1(rS(ctx
->opcode
));
4461 GEN_HANDLER(mfdcrx
, 0x1F, 0x03, 0x08, 0x00000001, PPC_BOOKE
)
4463 #if defined(CONFIG_USER_ONLY)
4466 if (unlikely(!ctx
->supervisor
)) {
4470 gen_op_load_gpr_T0(rA(ctx
->opcode
));
4472 gen_op_store_T0_gpr(rD(ctx
->opcode
));
4477 GEN_HANDLER(mtdcrx
, 0x1F, 0x03, 0x0C, 0x00000001, PPC_BOOKE
)
4479 #if defined(CONFIG_USER_ONLY)
4482 if (unlikely(!ctx
->supervisor
)) {
4486 gen_op_load_gpr_T0(rA(ctx
->opcode
));
4487 gen_op_load_gpr_T1(rS(ctx
->opcode
));
4493 GEN_HANDLER(dccci
, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON
)
4495 #if defined(CONFIG_USER_ONLY)
4498 if (unlikely(!ctx
->supervisor
)) {
4502 /* interpreted as no-op */
4507 GEN_HANDLER(dcread
, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON
)
4509 #if defined(CONFIG_USER_ONLY)
4512 if (unlikely(!ctx
->supervisor
)) {
4516 gen_addr_reg_index(ctx
);
4518 gen_op_store_T0_gpr(rD(ctx
->opcode
));
4523 GEN_HANDLER(icbt_40x
, 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_SPEC
)
4525 /* interpreted as no-op */
4526 /* XXX: specification say this is treated as a load by the MMU
4527 * but does not generate any exception
4532 GEN_HANDLER(iccci
, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON
)
4534 #if defined(CONFIG_USER_ONLY)
4537 if (unlikely(!ctx
->supervisor
)) {
4541 /* interpreted as no-op */
4546 GEN_HANDLER(icread
, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON
)
4548 #if defined(CONFIG_USER_ONLY)
4551 if (unlikely(!ctx
->supervisor
)) {
4555 /* interpreted as no-op */
4559 /* rfci (supervisor only) */
4560 GEN_HANDLER(rfci_40x
, 0x13, 0x13, 0x01, 0x03FF8001, PPC_40x_EXCP
)
4562 #if defined(CONFIG_USER_ONLY)
4565 if (unlikely(!ctx
->supervisor
)) {
4569 /* Restore CPU state */
4575 GEN_HANDLER(rfci
, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE
)
4577 #if defined(CONFIG_USER_ONLY)
4580 if (unlikely(!ctx
->supervisor
)) {
4584 /* Restore CPU state */
4590 /* BookE specific */
4591 GEN_HANDLER(rfdi
, 0x13, 0x07, 0x01, 0x03FF8001, PPC_BOOKE
)
4593 #if defined(CONFIG_USER_ONLY)
4596 if (unlikely(!ctx
->supervisor
)) {
4600 /* Restore CPU state */
4606 GEN_HANDLER(rfmci
, 0x13, 0x06, 0x01, 0x03FF8001, PPC_BOOKE
)
4608 #if defined(CONFIG_USER_ONLY)
4611 if (unlikely(!ctx
->supervisor
)) {
4615 /* Restore CPU state */
4620 /* TLB management - PowerPC 405 implementation */
4622 GEN_HANDLER(tlbre
, 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_SPEC
)
4624 #if defined(CONFIG_USER_ONLY)
4627 if (unlikely(!ctx
->supervisor
)) {
4631 switch (rB(ctx
->opcode
)) {
4633 gen_op_load_gpr_T0(rA(ctx
->opcode
));
4634 gen_op_4xx_tlbre_hi();
4635 gen_op_store_T0_gpr(rD(ctx
->opcode
));
4638 gen_op_load_gpr_T0(rA(ctx
->opcode
));
4639 gen_op_4xx_tlbre_lo();
4640 gen_op_store_T0_gpr(rD(ctx
->opcode
));
4649 /* tlbsx - tlbsx. */
4650 GEN_HANDLER(tlbsx
, 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_SPEC
)
4652 #if defined(CONFIG_USER_ONLY)
4655 if (unlikely(!ctx
->supervisor
)) {
4659 gen_addr_reg_index(ctx
);
4660 if (Rc(ctx
->opcode
))
4661 gen_op_4xx_tlbsx_();
4664 gen_op_store_T0_gpr(rD(ctx
->opcode
));
4669 GEN_HANDLER(tlbwe
, 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_SPEC
)
4671 #if defined(CONFIG_USER_ONLY)
4674 if (unlikely(!ctx
->supervisor
)) {
4678 switch (rB(ctx
->opcode
)) {
4680 gen_op_load_gpr_T0(rA(ctx
->opcode
));
4681 gen_op_load_gpr_T1(rS(ctx
->opcode
));
4682 gen_op_4xx_tlbwe_hi();
4685 gen_op_load_gpr_T0(rA(ctx
->opcode
));
4686 gen_op_load_gpr_T1(rS(ctx
->opcode
));
4687 gen_op_4xx_tlbwe_lo();
4697 GEN_HANDLER(wrtee
, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_EMB_COMMON
)
4699 #if defined(CONFIG_USER_ONLY)
4702 if (unlikely(!ctx
->supervisor
)) {
4706 gen_op_load_gpr_T0(rD(ctx
->opcode
));
4708 RET_EXCP(ctx
, EXCP_MTMSR
, 0);
4713 GEN_HANDLER(wrteei
, 0x1F, 0x03, 0x05, 0x000EFC01, PPC_EMB_COMMON
)
4715 #if defined(CONFIG_USER_ONLY)
4718 if (unlikely(!ctx
->supervisor
)) {
4722 gen_op_set_T0(ctx
->opcode
& 0x00010000);
4724 RET_EXCP(ctx
, EXCP_MTMSR
, 0);
4728 /* PowerPC 440 specific instructions */
4730 GEN_HANDLER(dlmzb
, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC
)
4732 gen_op_load_gpr_T0(rS(ctx
->opcode
));
4733 gen_op_load_gpr_T1(rB(ctx
->opcode
));
4735 gen_op_store_T0_gpr(rA(ctx
->opcode
));
4736 gen_op_store_xer_bc();
4737 if (Rc(ctx
->opcode
)) {
4738 gen_op_440_dlmzb_update_Rc();
4739 gen_op_store_T0_crf(0);
4743 /* mbar replaces eieio on 440 */
4744 GEN_HANDLER(mbar
, 0x1F, 0x16, 0x13, 0x001FF801, PPC_BOOKE
)
4746 /* interpreted as no-op */
4749 /* msync replaces sync on 440 */
4750 GEN_HANDLER(msync
, 0x1F, 0x16, 0x12, 0x03FF0801, PPC_BOOKE
)
4752 /* interpreted as no-op */
4756 GEN_HANDLER(icbt_440
, 0x1F, 0x16, 0x00, 0x03E00001, PPC_BOOKE
)
4758 /* interpreted as no-op */
4759 /* XXX: specification say this is treated as a load by the MMU
4760 * but does not generate any exception
4764 #if defined(TARGET_PPCEMB)
4765 /*** SPE extension ***/
4767 /* Register moves */
4768 GEN32(gen_op_load_gpr64_T0
, gen_op_load_gpr64_T0_gpr
);
4769 GEN32(gen_op_load_gpr64_T1
, gen_op_load_gpr64_T1_gpr
);
4771 GEN32(gen_op_load_gpr64_T2
, gen_op_load_gpr64_T2_gpr
);
4774 GEN32(gen_op_store_T0_gpr64
, gen_op_store_T0_gpr64_gpr
);
4775 GEN32(gen_op_store_T1_gpr64
, gen_op_store_T1_gpr64_gpr
);
4777 GEN32(gen_op_store_T2_gpr64
, gen_op_store_T2_gpr64_gpr
);
4780 #define GEN_SPE(name0, name1, opc2, opc3, inval, type) \
4781 GEN_HANDLER(name0##_##name1, 0x04, opc2, opc3, inval, type) \
4783 if (Rc(ctx->opcode)) \
4789 /* Handler for undefined SPE opcodes */
4790 static inline void gen_speundef (DisasContext
*ctx
)
4795 /* SPE load and stores */
4796 static inline void gen_addr_spe_imm_index (DisasContext
*ctx
, int sh
)
4798 target_long simm
= rB(ctx
->opcode
);
4800 if (rA(ctx
->opcode
) == 0) {
4801 gen_set_T0(simm
<< sh
);
4803 gen_op_load_gpr_T0(rA(ctx
->opcode
));
4804 if (likely(simm
!= 0))
4805 gen_op_addi(simm
<< sh
);
4809 #define op_spe_ldst(name) (*gen_op_##name[ctx->mem_idx])()
4810 #if defined(CONFIG_USER_ONLY)
4811 #if defined(TARGET_PPC64)
4812 #define OP_SPE_LD_TABLE(name) \
4813 static GenOpFunc *gen_op_spe_l##name[] = { \
4814 &gen_op_spe_l##name##_raw, \
4815 &gen_op_spe_l##name##_le_raw, \
4816 &gen_op_spe_l##name##_64_raw, \
4817 &gen_op_spe_l##name##_le_64_raw, \
4819 #define OP_SPE_ST_TABLE(name) \
4820 static GenOpFunc *gen_op_spe_st##name[] = { \
4821 &gen_op_spe_st##name##_raw, \
4822 &gen_op_spe_st##name##_le_raw, \
4823 &gen_op_spe_st##name##_64_raw, \
4824 &gen_op_spe_st##name##_le_64_raw, \
4826 #else /* defined(TARGET_PPC64) */
4827 #define OP_SPE_LD_TABLE(name) \
4828 static GenOpFunc *gen_op_spe_l##name[] = { \
4829 &gen_op_spe_l##name##_raw, \
4830 &gen_op_spe_l##name##_le_raw, \
4832 #define OP_SPE_ST_TABLE(name) \
4833 static GenOpFunc *gen_op_spe_st##name[] = { \
4834 &gen_op_spe_st##name##_raw, \
4835 &gen_op_spe_st##name##_le_raw, \
4837 #endif /* defined(TARGET_PPC64) */
4838 #else /* defined(CONFIG_USER_ONLY) */
4839 #if defined(TARGET_PPC64)
4840 #define OP_SPE_LD_TABLE(name) \
4841 static GenOpFunc *gen_op_spe_l##name[] = { \
4842 &gen_op_spe_l##name##_user, \
4843 &gen_op_spe_l##name##_le_user, \
4844 &gen_op_spe_l##name##_kernel, \
4845 &gen_op_spe_l##name##_le_kernel, \
4846 &gen_op_spe_l##name##_64_user, \
4847 &gen_op_spe_l##name##_le_64_user, \
4848 &gen_op_spe_l##name##_64_kernel, \
4849 &gen_op_spe_l##name##_le_64_kernel, \
4851 #define OP_SPE_ST_TABLE(name) \
4852 static GenOpFunc *gen_op_spe_st##name[] = { \
4853 &gen_op_spe_st##name##_user, \
4854 &gen_op_spe_st##name##_le_user, \
4855 &gen_op_spe_st##name##_kernel, \
4856 &gen_op_spe_st##name##_le_kernel, \
4857 &gen_op_spe_st##name##_64_user, \
4858 &gen_op_spe_st##name##_le_64_user, \
4859 &gen_op_spe_st##name##_64_kernel, \
4860 &gen_op_spe_st##name##_le_64_kernel, \
4862 #else /* defined(TARGET_PPC64) */
4863 #define OP_SPE_LD_TABLE(name) \
4864 static GenOpFunc *gen_op_spe_l##name[] = { \
4865 &gen_op_spe_l##name##_user, \
4866 &gen_op_spe_l##name##_le_user, \
4867 &gen_op_spe_l##name##_kernel, \
4868 &gen_op_spe_l##name##_le_kernel, \
4870 #define OP_SPE_ST_TABLE(name) \
4871 static GenOpFunc *gen_op_spe_st##name[] = { \
4872 &gen_op_spe_st##name##_user, \
4873 &gen_op_spe_st##name##_le_user, \
4874 &gen_op_spe_st##name##_kernel, \
4875 &gen_op_spe_st##name##_le_kernel, \
4877 #endif /* defined(TARGET_PPC64) */
4878 #endif /* defined(CONFIG_USER_ONLY) */
4880 #define GEN_SPE_LD(name, sh) \
4881 static inline void gen_evl##name (DisasContext *ctx) \
4883 if (unlikely(!ctx->spe_enabled)) { \
4884 RET_EXCP(ctx, EXCP_NO_SPE, 0); \
4887 gen_addr_spe_imm_index(ctx, sh); \
4888 op_spe_ldst(spe_l##name); \
4889 gen_op_store_T1_gpr64(rD(ctx->opcode)); \
4892 #define GEN_SPE_LDX(name) \
4893 static inline void gen_evl##name##x (DisasContext *ctx) \
4895 if (unlikely(!ctx->spe_enabled)) { \
4896 RET_EXCP(ctx, EXCP_NO_SPE, 0); \
4899 gen_addr_reg_index(ctx); \
4900 op_spe_ldst(spe_l##name); \
4901 gen_op_store_T1_gpr64(rD(ctx->opcode)); \
4904 #define GEN_SPEOP_LD(name, sh) \
4905 OP_SPE_LD_TABLE(name); \
4906 GEN_SPE_LD(name, sh); \
4909 #define GEN_SPE_ST(name, sh) \
4910 static inline void gen_evst##name (DisasContext *ctx) \
4912 if (unlikely(!ctx->spe_enabled)) { \
4913 RET_EXCP(ctx, EXCP_NO_SPE, 0); \
4916 gen_addr_spe_imm_index(ctx, sh); \
4917 gen_op_load_gpr64_T1(rS(ctx->opcode)); \
4918 op_spe_ldst(spe_st##name); \
4921 #define GEN_SPE_STX(name) \
4922 static inline void gen_evst##name##x (DisasContext *ctx) \
4924 if (unlikely(!ctx->spe_enabled)) { \
4925 RET_EXCP(ctx, EXCP_NO_SPE, 0); \
4928 gen_addr_reg_index(ctx); \
4929 gen_op_load_gpr64_T1(rS(ctx->opcode)); \
4930 op_spe_ldst(spe_st##name); \
4933 #define GEN_SPEOP_ST(name, sh) \
4934 OP_SPE_ST_TABLE(name); \
4935 GEN_SPE_ST(name, sh); \
4938 #define GEN_SPEOP_LDST(name, sh) \
4939 GEN_SPEOP_LD(name, sh); \
4940 GEN_SPEOP_ST(name, sh)
4942 /* SPE arithmetic and logic */
4943 #define GEN_SPEOP_ARITH2(name) \
4944 static inline void gen_##name (DisasContext *ctx) \
4946 if (unlikely(!ctx->spe_enabled)) { \
4947 RET_EXCP(ctx, EXCP_NO_SPE, 0); \
4950 gen_op_load_gpr64_T0(rA(ctx->opcode)); \
4951 gen_op_load_gpr64_T1(rB(ctx->opcode)); \
4953 gen_op_store_T0_gpr64(rD(ctx->opcode)); \
4956 #define GEN_SPEOP_ARITH1(name) \
4957 static inline void gen_##name (DisasContext *ctx) \
4959 if (unlikely(!ctx->spe_enabled)) { \
4960 RET_EXCP(ctx, EXCP_NO_SPE, 0); \
4963 gen_op_load_gpr64_T0(rA(ctx->opcode)); \
4965 gen_op_store_T0_gpr64(rD(ctx->opcode)); \
4968 #define GEN_SPEOP_COMP(name) \
4969 static inline void gen_##name (DisasContext *ctx) \
4971 if (unlikely(!ctx->spe_enabled)) { \
4972 RET_EXCP(ctx, EXCP_NO_SPE, 0); \
4975 gen_op_load_gpr64_T0(rA(ctx->opcode)); \
4976 gen_op_load_gpr64_T1(rB(ctx->opcode)); \
4978 gen_op_store_T0_crf(crfD(ctx->opcode)); \
4982 GEN_SPEOP_ARITH2(evand
);
4983 GEN_SPEOP_ARITH2(evandc
);
4984 GEN_SPEOP_ARITH2(evxor
);
4985 GEN_SPEOP_ARITH2(evor
);
4986 GEN_SPEOP_ARITH2(evnor
);
4987 GEN_SPEOP_ARITH2(eveqv
);
4988 GEN_SPEOP_ARITH2(evorc
);
4989 GEN_SPEOP_ARITH2(evnand
);
4990 GEN_SPEOP_ARITH2(evsrwu
);
4991 GEN_SPEOP_ARITH2(evsrws
);
4992 GEN_SPEOP_ARITH2(evslw
);
4993 GEN_SPEOP_ARITH2(evrlw
);
4994 GEN_SPEOP_ARITH2(evmergehi
);
4995 GEN_SPEOP_ARITH2(evmergelo
);
4996 GEN_SPEOP_ARITH2(evmergehilo
);
4997 GEN_SPEOP_ARITH2(evmergelohi
);
5000 GEN_SPEOP_ARITH2(evaddw
);
5001 GEN_SPEOP_ARITH2(evsubfw
);
5002 GEN_SPEOP_ARITH1(evabs
);
5003 GEN_SPEOP_ARITH1(evneg
);
5004 GEN_SPEOP_ARITH1(evextsb
);
5005 GEN_SPEOP_ARITH1(evextsh
);
5006 GEN_SPEOP_ARITH1(evrndw
);
5007 GEN_SPEOP_ARITH1(evcntlzw
);
5008 GEN_SPEOP_ARITH1(evcntlsw
);
5009 static inline void gen_brinc (DisasContext
*ctx
)
5011 /* Note: brinc is usable even if SPE is disabled */
5012 gen_op_load_gpr64_T0(rA(ctx
->opcode
));
5013 gen_op_load_gpr64_T1(rB(ctx
->opcode
));
5015 gen_op_store_T0_gpr64(rD(ctx
->opcode
));
5018 #define GEN_SPEOP_ARITH_IMM2(name) \
5019 static inline void gen_##name##i (DisasContext *ctx) \
5021 if (unlikely(!ctx->spe_enabled)) { \
5022 RET_EXCP(ctx, EXCP_NO_SPE, 0); \
5025 gen_op_load_gpr64_T0(rB(ctx->opcode)); \
5026 gen_op_splatwi_T1_64(rA(ctx->opcode)); \
5028 gen_op_store_T0_gpr64(rD(ctx->opcode)); \
5031 #define GEN_SPEOP_LOGIC_IMM2(name) \
5032 static inline void gen_##name##i (DisasContext *ctx) \
5034 if (unlikely(!ctx->spe_enabled)) { \
5035 RET_EXCP(ctx, EXCP_NO_SPE, 0); \
5038 gen_op_load_gpr64_T0(rA(ctx->opcode)); \
5039 gen_op_splatwi_T1_64(rB(ctx->opcode)); \
5041 gen_op_store_T0_gpr64(rD(ctx->opcode)); \
5044 GEN_SPEOP_ARITH_IMM2(evaddw
);
5045 #define gen_evaddiw gen_evaddwi
5046 GEN_SPEOP_ARITH_IMM2(evsubfw
);
5047 #define gen_evsubifw gen_evsubfwi
5048 GEN_SPEOP_LOGIC_IMM2(evslw
);
5049 GEN_SPEOP_LOGIC_IMM2(evsrwu
);
5050 #define gen_evsrwis gen_evsrwsi
5051 GEN_SPEOP_LOGIC_IMM2(evsrws
);
5052 #define gen_evsrwiu gen_evsrwui
5053 GEN_SPEOP_LOGIC_IMM2(evrlw
);
5055 static inline void gen_evsplati (DisasContext
*ctx
)
5057 int32_t imm
= (int32_t)(rA(ctx
->opcode
) << 27) >> 27;
5059 gen_op_splatwi_T0_64(imm
);
5060 gen_op_store_T0_gpr64(rD(ctx
->opcode
));
5063 static inline void gen_evsplatfi (DisasContext
*ctx
)
5065 uint32_t imm
= rA(ctx
->opcode
) << 27;
5067 gen_op_splatwi_T0_64(imm
);
5068 gen_op_store_T0_gpr64(rD(ctx
->opcode
));
5072 GEN_SPEOP_COMP(evcmpgtu
);
5073 GEN_SPEOP_COMP(evcmpgts
);
5074 GEN_SPEOP_COMP(evcmpltu
);
5075 GEN_SPEOP_COMP(evcmplts
);
5076 GEN_SPEOP_COMP(evcmpeq
);
5078 GEN_SPE(evaddw
, speundef
, 0x00, 0x08, 0x00000000, PPC_SPE
); ////
5079 GEN_SPE(evaddiw
, speundef
, 0x01, 0x08, 0x00000000, PPC_SPE
);
5080 GEN_SPE(evsubfw
, speundef
, 0x02, 0x08, 0x00000000, PPC_SPE
); ////
5081 GEN_SPE(evsubifw
, speundef
, 0x03, 0x08, 0x00000000, PPC_SPE
);
5082 GEN_SPE(evabs
, evneg
, 0x04, 0x08, 0x0000F800, PPC_SPE
); ////
5083 GEN_SPE(evextsb
, evextsh
, 0x05, 0x08, 0x0000F800, PPC_SPE
); ////
5084 GEN_SPE(evrndw
, evcntlzw
, 0x06, 0x08, 0x0000F800, PPC_SPE
); ////
5085 GEN_SPE(evcntlsw
, brinc
, 0x07, 0x08, 0x00000000, PPC_SPE
); //
5086 GEN_SPE(speundef
, evand
, 0x08, 0x08, 0x00000000, PPC_SPE
); ////
5087 GEN_SPE(evandc
, speundef
, 0x09, 0x08, 0x00000000, PPC_SPE
); ////
5088 GEN_SPE(evxor
, evor
, 0x0B, 0x08, 0x00000000, PPC_SPE
); ////
5089 GEN_SPE(evnor
, eveqv
, 0x0C, 0x08, 0x00000000, PPC_SPE
); ////
5090 GEN_SPE(speundef
, evorc
, 0x0D, 0x08, 0x00000000, PPC_SPE
); ////
5091 GEN_SPE(evnand
, speundef
, 0x0F, 0x08, 0x00000000, PPC_SPE
); ////
5092 GEN_SPE(evsrwu
, evsrws
, 0x10, 0x08, 0x00000000, PPC_SPE
); ////
5093 GEN_SPE(evsrwiu
, evsrwis
, 0x11, 0x08, 0x00000000, PPC_SPE
);
5094 GEN_SPE(evslw
, speundef
, 0x12, 0x08, 0x00000000, PPC_SPE
); ////
5095 GEN_SPE(evslwi
, speundef
, 0x13, 0x08, 0x00000000, PPC_SPE
);
5096 GEN_SPE(evrlw
, evsplati
, 0x14, 0x08, 0x00000000, PPC_SPE
); //
5097 GEN_SPE(evrlwi
, evsplatfi
, 0x15, 0x08, 0x00000000, PPC_SPE
);
5098 GEN_SPE(evmergehi
, evmergelo
, 0x16, 0x08, 0x00000000, PPC_SPE
); ////
5099 GEN_SPE(evmergehilo
, evmergelohi
, 0x17, 0x08, 0x00000000, PPC_SPE
); ////
5100 GEN_SPE(evcmpgtu
, evcmpgts
, 0x18, 0x08, 0x00600000, PPC_SPE
); ////
5101 GEN_SPE(evcmpltu
, evcmplts
, 0x19, 0x08, 0x00600000, PPC_SPE
); ////
5102 GEN_SPE(evcmpeq
, speundef
, 0x1A, 0x08, 0x00600000, PPC_SPE
); ////
5104 static inline void gen_evsel (DisasContext
*ctx
)
5106 if (unlikely(!ctx
->spe_enabled
)) {
5107 RET_EXCP(ctx
, EXCP_NO_SPE
, 0);
5110 gen_op_load_crf_T0(ctx
->opcode
& 0x7);
5111 gen_op_load_gpr64_T0(rA(ctx
->opcode
));
5112 gen_op_load_gpr64_T1(rB(ctx
->opcode
));
5114 gen_op_store_T0_gpr64(rD(ctx
->opcode
));
5117 GEN_HANDLER(evsel0
, 0x04, 0x1c, 0x09, 0x00000000, PPC_SPE
)
5121 GEN_HANDLER(evsel1
, 0x04, 0x1d, 0x09, 0x00000000, PPC_SPE
)
5125 GEN_HANDLER(evsel2
, 0x04, 0x1e, 0x09, 0x00000000, PPC_SPE
)
5129 GEN_HANDLER(evsel3
, 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE
)
5134 /* Load and stores */
5135 #if defined(TARGET_PPC64)
5136 /* In that case, we already have 64 bits load & stores
5137 * so, spe_ldd is equivalent to ld and spe_std is equivalent to std
5139 #if defined(CONFIG_USER_ONLY)
5140 #define gen_op_spe_ldd_raw gen_op_ld_raw
5141 #define gen_op_spe_ldd_64_raw gen_op_ld_64_raw
5142 #define gen_op_spe_ldd_le_raw gen_op_ld_le_raw
5143 #define gen_op_spe_ldd_le_64_raw gen_op_ld_le_64_raw
5144 #define gen_op_spe_stdd_raw gen_op_ld_raw
5145 #define gen_op_spe_stdd_64_raw gen_op_std_64_raw
5146 #define gen_op_spe_stdd_le_raw gen_op_std_le_raw
5147 #define gen_op_spe_stdd_le_64_raw gen_op_std_le_64_raw
5148 #else /* defined(CONFIG_USER_ONLY) */
5149 #define gen_op_spe_ldd_kernel gen_op_ld_kernel
5150 #define gen_op_spe_ldd_64_kernel gen_op_ld_64_kernel
5151 #define gen_op_spe_ldd_le_kernel gen_op_ld_kernel
5152 #define gen_op_spe_ldd_le_64_kernel gen_op_ld_64_kernel
5153 #define gen_op_spe_ldd_user gen_op_ld_user
5154 #define gen_op_spe_ldd_64_user gen_op_ld_64_user
5155 #define gen_op_spe_ldd_le_user gen_op_ld_le_user
5156 #define gen_op_spe_ldd_le_64_user gen_op_ld_le_64_user
5157 #define gen_op_spe_stdd_kernel gen_op_std_kernel
5158 #define gen_op_spe_stdd_64_kernel gen_op_std_64_kernel
5159 #define gen_op_spe_stdd_le_kernel gen_op_std_kernel
5160 #define gen_op_spe_stdd_le_64_kernel gen_op_std_64_kernel
5161 #define gen_op_spe_stdd_user gen_op_std_user
5162 #define gen_op_spe_stdd_64_user gen_op_std_64_user
5163 #define gen_op_spe_stdd_le_user gen_op_std_le_user
5164 #define gen_op_spe_stdd_le_64_user gen_op_std_le_64_user
5165 #endif /* defined(CONFIG_USER_ONLY) */
5166 #endif /* defined(TARGET_PPC64) */
5167 GEN_SPEOP_LDST(dd
, 3);
5168 GEN_SPEOP_LDST(dw
, 3);
5169 GEN_SPEOP_LDST(dh
, 3);
5170 GEN_SPEOP_LDST(whe
, 2);
5171 GEN_SPEOP_LD(whou
, 2);
5172 GEN_SPEOP_LD(whos
, 2);
5173 GEN_SPEOP_ST(who
, 2);
5175 #if defined(TARGET_PPC64)
5176 /* In that case, spe_stwwo is equivalent to stw */
5177 #if defined(CONFIG_USER_ONLY)
5178 #define gen_op_spe_stwwo_raw gen_op_stw_raw
5179 #define gen_op_spe_stwwo_le_raw gen_op_stw_le_raw
5180 #define gen_op_spe_stwwo_64_raw gen_op_stw_64_raw
5181 #define gen_op_spe_stwwo_le_64_raw gen_op_stw_le_64_raw
5183 #define gen_op_spe_stwwo_user gen_op_stw_user
5184 #define gen_op_spe_stwwo_le_user gen_op_stw_le_user
5185 #define gen_op_spe_stwwo_64_user gen_op_stw_64_user
5186 #define gen_op_spe_stwwo_le_64_user gen_op_stw_le_64_user
5187 #define gen_op_spe_stwwo_kernel gen_op_stw_kernel
5188 #define gen_op_spe_stwwo_le_kernel gen_op_stw_le_kernel
5189 #define gen_op_spe_stwwo_64_kernel gen_op_stw_64_kernel
5190 #define gen_op_spe_stwwo_le_64_kernel gen_op_stw_le_64_kernel
5193 #define _GEN_OP_SPE_STWWE(suffix) \
5194 static inline void gen_op_spe_stwwe_##suffix (void) \
5196 gen_op_srli32_T1_64(); \
5197 gen_op_spe_stwwo_##suffix(); \
5199 #define _GEN_OP_SPE_STWWE_LE(suffix) \
5200 static inline void gen_op_spe_stwwe_le_##suffix (void) \
5202 gen_op_srli32_T1_64(); \
5203 gen_op_spe_stwwo_le_##suffix(); \
5205 #if defined(TARGET_PPC64)
5206 #define GEN_OP_SPE_STWWE(suffix) \
5207 _GEN_OP_SPE_STWWE(suffix); \
5208 _GEN_OP_SPE_STWWE_LE(suffix); \
5209 static inline void gen_op_spe_stwwe_64_##suffix (void) \
5211 gen_op_srli32_T1_64(); \
5212 gen_op_spe_stwwo_64_##suffix(); \
5214 static inline void gen_op_spe_stwwe_le_64_##suffix (void) \
5216 gen_op_srli32_T1_64(); \
5217 gen_op_spe_stwwo_le_64_##suffix(); \
5220 #define GEN_OP_SPE_STWWE(suffix) \
5221 _GEN_OP_SPE_STWWE(suffix); \
5222 _GEN_OP_SPE_STWWE_LE(suffix)
5224 #if defined(CONFIG_USER_ONLY)
5225 GEN_OP_SPE_STWWE(raw
);
5226 #else /* defined(CONFIG_USER_ONLY) */
5227 GEN_OP_SPE_STWWE(kernel
);
5228 GEN_OP_SPE_STWWE(user
);
5229 #endif /* defined(CONFIG_USER_ONLY) */
5230 GEN_SPEOP_ST(wwe
, 2);
5231 GEN_SPEOP_ST(wwo
, 2);
5233 #define GEN_SPE_LDSPLAT(name, op, suffix) \
5234 static inline void gen_op_spe_l##name##_##suffix (void) \
5236 gen_op_##op##_##suffix(); \
5237 gen_op_splatw_T1_64(); \
5240 #define GEN_OP_SPE_LHE(suffix) \
5241 static inline void gen_op_spe_lhe_##suffix (void) \
5243 gen_op_spe_lh_##suffix(); \
5244 gen_op_sli16_T1_64(); \
5247 #define GEN_OP_SPE_LHX(suffix) \
5248 static inline void gen_op_spe_lhx_##suffix (void) \
5250 gen_op_spe_lh_##suffix(); \
5251 gen_op_extsh_T1_64(); \
5254 #if defined(CONFIG_USER_ONLY)
5255 GEN_OP_SPE_LHE(raw
);
5256 GEN_SPE_LDSPLAT(hhesplat
, spe_lhe
, raw
);
5257 GEN_OP_SPE_LHE(le_raw
);
5258 GEN_SPE_LDSPLAT(hhesplat
, spe_lhe
, le_raw
);
5259 GEN_SPE_LDSPLAT(hhousplat
, spe_lh
, raw
);
5260 GEN_SPE_LDSPLAT(hhousplat
, spe_lh
, le_raw
);
5261 GEN_OP_SPE_LHX(raw
);
5262 GEN_SPE_LDSPLAT(hhossplat
, spe_lhx
, raw
);
5263 GEN_OP_SPE_LHX(le_raw
);
5264 GEN_SPE_LDSPLAT(hhossplat
, spe_lhx
, le_raw
);
5265 #if defined(TARGET_PPC64)
5266 GEN_OP_SPE_LHE(64_raw
);
5267 GEN_SPE_LDSPLAT(hhesplat
, spe_lhe
, 64_raw
);
5268 GEN_OP_SPE_LHE(le_64_raw
);
5269 GEN_SPE_LDSPLAT(hhesplat
, spe_lhe
, le_64_raw
);
5270 GEN_SPE_LDSPLAT(hhousplat
, spe_lh
, 64_raw
);
5271 GEN_SPE_LDSPLAT(hhousplat
, spe_lh
, le_64_raw
);
5272 GEN_OP_SPE_LHX(64_raw
);
5273 GEN_SPE_LDSPLAT(hhossplat
, spe_lhx
, 64_raw
);
5274 GEN_OP_SPE_LHX(le_64_raw
);
5275 GEN_SPE_LDSPLAT(hhossplat
, spe_lhx
, le_64_raw
);
5278 GEN_OP_SPE_LHE(kernel
);
5279 GEN_OP_SPE_LHE(user
);
5280 GEN_SPE_LDSPLAT(hhesplat
, spe_lhe
, kernel
);
5281 GEN_SPE_LDSPLAT(hhesplat
, spe_lhe
, user
);
5282 GEN_OP_SPE_LHE(le_kernel
);
5283 GEN_OP_SPE_LHE(le_user
);
5284 GEN_SPE_LDSPLAT(hhesplat
, spe_lhe
, le_kernel
);
5285 GEN_SPE_LDSPLAT(hhesplat
, spe_lhe
, le_user
);
5286 GEN_SPE_LDSPLAT(hhousplat
, spe_lh
, kernel
);
5287 GEN_SPE_LDSPLAT(hhousplat
, spe_lh
, user
);
5288 GEN_SPE_LDSPLAT(hhousplat
, spe_lh
, le_kernel
);
5289 GEN_SPE_LDSPLAT(hhousplat
, spe_lh
, le_user
);
5290 GEN_OP_SPE_LHX(kernel
);
5291 GEN_OP_SPE_LHX(user
);
5292 GEN_SPE_LDSPLAT(hhossplat
, spe_lhx
, kernel
);
5293 GEN_SPE_LDSPLAT(hhossplat
, spe_lhx
, user
);
5294 GEN_OP_SPE_LHX(le_kernel
);
5295 GEN_OP_SPE_LHX(le_user
);
5296 GEN_SPE_LDSPLAT(hhossplat
, spe_lhx
, le_kernel
);
5297 GEN_SPE_LDSPLAT(hhossplat
, spe_lhx
, le_user
);
5298 #if defined(TARGET_PPC64)
5299 GEN_OP_SPE_LHE(64_kernel
);
5300 GEN_OP_SPE_LHE(64_user
);
5301 GEN_SPE_LDSPLAT(hhesplat
, spe_lhe
, 64_kernel
);
5302 GEN_SPE_LDSPLAT(hhesplat
, spe_lhe
, 64_user
);
5303 GEN_OP_SPE_LHE(le_64_kernel
);
5304 GEN_OP_SPE_LHE(le_64_user
);
5305 GEN_SPE_LDSPLAT(hhesplat
, spe_lhe
, le_64_kernel
);
5306 GEN_SPE_LDSPLAT(hhesplat
, spe_lhe
, le_64_user
);
5307 GEN_SPE_LDSPLAT(hhousplat
, spe_lh
, 64_kernel
);
5308 GEN_SPE_LDSPLAT(hhousplat
, spe_lh
, 64_user
);
5309 GEN_SPE_LDSPLAT(hhousplat
, spe_lh
, le_64_kernel
);
5310 GEN_SPE_LDSPLAT(hhousplat
, spe_lh
, le_64_user
);
5311 GEN_OP_SPE_LHX(64_kernel
);
5312 GEN_OP_SPE_LHX(64_user
);
5313 GEN_SPE_LDSPLAT(hhossplat
, spe_lhx
, 64_kernel
);
5314 GEN_SPE_LDSPLAT(hhossplat
, spe_lhx
, 64_user
);
5315 GEN_OP_SPE_LHX(le_64_kernel
);
5316 GEN_OP_SPE_LHX(le_64_user
);
5317 GEN_SPE_LDSPLAT(hhossplat
, spe_lhx
, le_64_kernel
);
5318 GEN_SPE_LDSPLAT(hhossplat
, spe_lhx
, le_64_user
);
5321 GEN_SPEOP_LD(hhesplat
, 1);
5322 GEN_SPEOP_LD(hhousplat
, 1);
5323 GEN_SPEOP_LD(hhossplat
, 1);
5324 GEN_SPEOP_LD(wwsplat
, 2);
5325 GEN_SPEOP_LD(whsplat
, 2);
5327 GEN_SPE(evlddx
, evldd
, 0x00, 0x0C, 0x00000000, PPC_SPE
); //
5328 GEN_SPE(evldwx
, evldw
, 0x01, 0x0C, 0x00000000, PPC_SPE
); //
5329 GEN_SPE(evldhx
, evldh
, 0x02, 0x0C, 0x00000000, PPC_SPE
); //
5330 GEN_SPE(evlhhesplatx
, evlhhesplat
, 0x04, 0x0C, 0x00000000, PPC_SPE
); //
5331 GEN_SPE(evlhhousplatx
, evlhhousplat
, 0x06, 0x0C, 0x00000000, PPC_SPE
); //
5332 GEN_SPE(evlhhossplatx
, evlhhossplat
, 0x07, 0x0C, 0x00000000, PPC_SPE
); //
5333 GEN_SPE(evlwhex
, evlwhe
, 0x08, 0x0C, 0x00000000, PPC_SPE
); //
5334 GEN_SPE(evlwhoux
, evlwhou
, 0x0A, 0x0C, 0x00000000, PPC_SPE
); //
5335 GEN_SPE(evlwhosx
, evlwhos
, 0x0B, 0x0C, 0x00000000, PPC_SPE
); //
5336 GEN_SPE(evlwwsplatx
, evlwwsplat
, 0x0C, 0x0C, 0x00000000, PPC_SPE
); //
5337 GEN_SPE(evlwhsplatx
, evlwhsplat
, 0x0E, 0x0C, 0x00000000, PPC_SPE
); //
5338 GEN_SPE(evstddx
, evstdd
, 0x10, 0x0C, 0x00000000, PPC_SPE
); //
5339 GEN_SPE(evstdwx
, evstdw
, 0x11, 0x0C, 0x00000000, PPC_SPE
); //
5340 GEN_SPE(evstdhx
, evstdh
, 0x12, 0x0C, 0x00000000, PPC_SPE
); //
5341 GEN_SPE(evstwhex
, evstwhe
, 0x18, 0x0C, 0x00000000, PPC_SPE
); //
5342 GEN_SPE(evstwhox
, evstwho
, 0x1A, 0x0C, 0x00000000, PPC_SPE
); //
5343 GEN_SPE(evstwwex
, evstwwe
, 0x1C, 0x0C, 0x00000000, PPC_SPE
); //
5344 GEN_SPE(evstwwox
, evstwwo
, 0x1E, 0x0C, 0x00000000, PPC_SPE
); //
5346 /* Multiply and add - TODO */
5348 GEN_SPE(speundef
, evmhessf
, 0x01, 0x10, 0x00000000, PPC_SPE
);
5349 GEN_SPE(speundef
, evmhossf
, 0x03, 0x10, 0x00000000, PPC_SPE
);
5350 GEN_SPE(evmheumi
, evmhesmi
, 0x04, 0x10, 0x00000000, PPC_SPE
);
5351 GEN_SPE(speundef
, evmhesmf
, 0x05, 0x10, 0x00000000, PPC_SPE
);
5352 GEN_SPE(evmhoumi
, evmhosmi
, 0x06, 0x10, 0x00000000, PPC_SPE
);
5353 GEN_SPE(speundef
, evmhosmf
, 0x07, 0x10, 0x00000000, PPC_SPE
);
5354 GEN_SPE(speundef
, evmhessfa
, 0x11, 0x10, 0x00000000, PPC_SPE
);
5355 GEN_SPE(speundef
, evmhossfa
, 0x13, 0x10, 0x00000000, PPC_SPE
);
5356 GEN_SPE(evmheumia
, evmhesmia
, 0x14, 0x10, 0x00000000, PPC_SPE
);
5357 GEN_SPE(speundef
, evmhesmfa
, 0x15, 0x10, 0x00000000, PPC_SPE
);
5358 GEN_SPE(evmhoumia
, evmhosmia
, 0x16, 0x10, 0x00000000, PPC_SPE
);
5359 GEN_SPE(speundef
, evmhosmfa
, 0x17, 0x10, 0x00000000, PPC_SPE
);
5361 GEN_SPE(speundef
, evmwhssf
, 0x03, 0x11, 0x00000000, PPC_SPE
);
5362 GEN_SPE(evmwlumi
, speundef
, 0x04, 0x11, 0x00000000, PPC_SPE
);
5363 GEN_SPE(evmwhumi
, evmwhsmi
, 0x06, 0x11, 0x00000000, PPC_SPE
);
5364 GEN_SPE(speundef
, evmwhsmf
, 0x07, 0x11, 0x00000000, PPC_SPE
);
5365 GEN_SPE(speundef
, evmwssf
, 0x09, 0x11, 0x00000000, PPC_SPE
);
5366 GEN_SPE(evmwumi
, evmwsmi
, 0x0C, 0x11, 0x00000000, PPC_SPE
);
5367 GEN_SPE(speundef
, evmwsmf
, 0x0D, 0x11, 0x00000000, PPC_SPE
);
5368 GEN_SPE(speundef
, evmwhssfa
, 0x13, 0x11, 0x00000000, PPC_SPE
);
5369 GEN_SPE(evmwlumia
, speundef
, 0x14, 0x11, 0x00000000, PPC_SPE
);
5370 GEN_SPE(evmwhumia
, evmwhsmia
, 0x16, 0x11, 0x00000000, PPC_SPE
);
5371 GEN_SPE(speundef
, evmwhsmfa
, 0x17, 0x11, 0x00000000, PPC_SPE
);
5372 GEN_SPE(speundef
, evmwssfa
, 0x19, 0x11, 0x00000000, PPC_SPE
);
5373 GEN_SPE(evmwumia
, evmwsmia
, 0x1C, 0x11, 0x00000000, PPC_SPE
);
5374 GEN_SPE(speundef
, evmwsmfa
, 0x1D, 0x11, 0x00000000, PPC_SPE
);
5376 GEN_SPE(evadduiaaw
, evaddsiaaw
, 0x00, 0x13, 0x0000F800, PPC_SPE
);
5377 GEN_SPE(evsubfusiaaw
, evsubfssiaaw
, 0x01, 0x13, 0x0000F800, PPC_SPE
);
5378 GEN_SPE(evaddumiaaw
, evaddsmiaaw
, 0x04, 0x13, 0x0000F800, PPC_SPE
);
5379 GEN_SPE(evsubfumiaaw
, evsubfsmiaaw
, 0x05, 0x13, 0x0000F800, PPC_SPE
);
5380 GEN_SPE(evdivws
, evdivwu
, 0x06, 0x13, 0x00000000, PPC_SPE
);
5381 GEN_SPE(evmra
, speundef
, 0x07, 0x13, 0x0000F800, PPC_SPE
);
5383 GEN_SPE(evmheusiaaw
, evmhessiaaw
, 0x00, 0x14, 0x00000000, PPC_SPE
);
5384 GEN_SPE(speundef
, evmhessfaaw
, 0x01, 0x14, 0x00000000, PPC_SPE
);
5385 GEN_SPE(evmhousiaaw
, evmhossiaaw
, 0x02, 0x14, 0x00000000, PPC_SPE
);
5386 GEN_SPE(speundef
, evmhossfaaw
, 0x03, 0x14, 0x00000000, PPC_SPE
);
5387 GEN_SPE(evmheumiaaw
, evmhesmiaaw
, 0x04, 0x14, 0x00000000, PPC_SPE
);
5388 GEN_SPE(speundef
, evmhesmfaaw
, 0x05, 0x14, 0x00000000, PPC_SPE
);
5389 GEN_SPE(evmhoumiaaw
, evmhosmiaaw
, 0x06, 0x14, 0x00000000, PPC_SPE
);
5390 GEN_SPE(speundef
, evmhosmfaaw
, 0x07, 0x14, 0x00000000, PPC_SPE
);
5391 GEN_SPE(evmhegumiaa
, evmhegsmiaa
, 0x14, 0x14, 0x00000000, PPC_SPE
);
5392 GEN_SPE(speundef
, evmhegsmfaa
, 0x15, 0x14, 0x00000000, PPC_SPE
);
5393 GEN_SPE(evmhogumiaa
, evmhogsmiaa
, 0x16, 0x14, 0x00000000, PPC_SPE
);
5394 GEN_SPE(speundef
, evmhogsmfaa
, 0x17, 0x14, 0x00000000, PPC_SPE
);
5396 GEN_SPE(evmwlusiaaw
, evmwlssiaaw
, 0x00, 0x15, 0x00000000, PPC_SPE
);
5397 GEN_SPE(evmwlumiaaw
, evmwlsmiaaw
, 0x04, 0x15, 0x00000000, PPC_SPE
);
5398 GEN_SPE(speundef
, evmwssfaa
, 0x09, 0x15, 0x00000000, PPC_SPE
);
5399 GEN_SPE(evmwumiaa
, evmwsmiaa
, 0x0C, 0x15, 0x00000000, PPC_SPE
);
5400 GEN_SPE(speundef
, evmwsmfaa
, 0x0D, 0x15, 0x00000000, PPC_SPE
);
5402 GEN_SPE(evmheusianw
, evmhessianw
, 0x00, 0x16, 0x00000000, PPC_SPE
);
5403 GEN_SPE(speundef
, evmhessfanw
, 0x01, 0x16, 0x00000000, PPC_SPE
);
5404 GEN_SPE(evmhousianw
, evmhossianw
, 0x02, 0x16, 0x00000000, PPC_SPE
);
5405 GEN_SPE(speundef
, evmhossfanw
, 0x03, 0x16, 0x00000000, PPC_SPE
);
5406 GEN_SPE(evmheumianw
, evmhesmianw
, 0x04, 0x16, 0x00000000, PPC_SPE
);
5407 GEN_SPE(speundef
, evmhesmfanw
, 0x05, 0x16, 0x00000000, PPC_SPE
);
5408 GEN_SPE(evmhoumianw
, evmhosmianw
, 0x06, 0x16, 0x00000000, PPC_SPE
);
5409 GEN_SPE(speundef
, evmhosmfanw
, 0x07, 0x16, 0x00000000, PPC_SPE
);
5410 GEN_SPE(evmhegumian
, evmhegsmian
, 0x14, 0x16, 0x00000000, PPC_SPE
);
5411 GEN_SPE(speundef
, evmhegsmfan
, 0x15, 0x16, 0x00000000, PPC_SPE
);
5412 GEN_SPE(evmhigumian
, evmhigsmian
, 0x16, 0x16, 0x00000000, PPC_SPE
);
5413 GEN_SPE(speundef
, evmhogsmfan
, 0x17, 0x16, 0x00000000, PPC_SPE
);
5415 GEN_SPE(evmwlusianw
, evmwlssianw
, 0x00, 0x17, 0x00000000, PPC_SPE
);
5416 GEN_SPE(evmwlumianw
, evmwlsmianw
, 0x04, 0x17, 0x00000000, PPC_SPE
);
5417 GEN_SPE(speundef
, evmwssfan
, 0x09, 0x17, 0x00000000, PPC_SPE
);
5418 GEN_SPE(evmwumian
, evmwsmian
, 0x0C, 0x17, 0x00000000, PPC_SPE
);
5419 GEN_SPE(speundef
, evmwsmfan
, 0x0D, 0x17, 0x00000000, PPC_SPE
);
5422 /*** SPE floating-point extension ***/
5423 #define GEN_SPEFPUOP_CONV(name) \
5424 static inline void gen_##name (DisasContext *ctx) \
5426 gen_op_load_gpr64_T0(rB(ctx->opcode)); \
5428 gen_op_store_T0_gpr64(rD(ctx->opcode)); \
5431 /* Single precision floating-point vectors operations */
5433 GEN_SPEOP_ARITH2(evfsadd
);
5434 GEN_SPEOP_ARITH2(evfssub
);
5435 GEN_SPEOP_ARITH2(evfsmul
);
5436 GEN_SPEOP_ARITH2(evfsdiv
);
5437 GEN_SPEOP_ARITH1(evfsabs
);
5438 GEN_SPEOP_ARITH1(evfsnabs
);
5439 GEN_SPEOP_ARITH1(evfsneg
);
5441 GEN_SPEFPUOP_CONV(evfscfui
);
5442 GEN_SPEFPUOP_CONV(evfscfsi
);
5443 GEN_SPEFPUOP_CONV(evfscfuf
);
5444 GEN_SPEFPUOP_CONV(evfscfsf
);
5445 GEN_SPEFPUOP_CONV(evfsctui
);
5446 GEN_SPEFPUOP_CONV(evfsctsi
);
5447 GEN_SPEFPUOP_CONV(evfsctuf
);
5448 GEN_SPEFPUOP_CONV(evfsctsf
);
5449 GEN_SPEFPUOP_CONV(evfsctuiz
);
5450 GEN_SPEFPUOP_CONV(evfsctsiz
);
5452 GEN_SPEOP_COMP(evfscmpgt
);
5453 GEN_SPEOP_COMP(evfscmplt
);
5454 GEN_SPEOP_COMP(evfscmpeq
);
5455 GEN_SPEOP_COMP(evfststgt
);
5456 GEN_SPEOP_COMP(evfststlt
);
5457 GEN_SPEOP_COMP(evfststeq
);
5459 /* Opcodes definitions */
5460 GEN_SPE(evfsadd
, evfssub
, 0x00, 0x0A, 0x00000000, PPC_SPEFPU
); //
5461 GEN_SPE(evfsabs
, evfsnabs
, 0x02, 0x0A, 0x0000F800, PPC_SPEFPU
); //
5462 GEN_SPE(evfsneg
, speundef
, 0x03, 0x0A, 0x0000F800, PPC_SPEFPU
); //
5463 GEN_SPE(evfsmul
, evfsdiv
, 0x04, 0x0A, 0x00000000, PPC_SPEFPU
); //
5464 GEN_SPE(evfscmpgt
, evfscmplt
, 0x06, 0x0A, 0x00600000, PPC_SPEFPU
); //
5465 GEN_SPE(evfscmpeq
, speundef
, 0x07, 0x0A, 0x00600000, PPC_SPEFPU
); //
5466 GEN_SPE(evfscfui
, evfscfsi
, 0x08, 0x0A, 0x00180000, PPC_SPEFPU
); //
5467 GEN_SPE(evfscfuf
, evfscfsf
, 0x09, 0x0A, 0x00180000, PPC_SPEFPU
); //
5468 GEN_SPE(evfsctui
, evfsctsi
, 0x0A, 0x0A, 0x00180000, PPC_SPEFPU
); //
5469 GEN_SPE(evfsctuf
, evfsctsf
, 0x0B, 0x0A, 0x00180000, PPC_SPEFPU
); //
5470 GEN_SPE(evfsctuiz
, speundef
, 0x0C, 0x0A, 0x00180000, PPC_SPEFPU
); //
5471 GEN_SPE(evfsctsiz
, speundef
, 0x0D, 0x0A, 0x00180000, PPC_SPEFPU
); //
5472 GEN_SPE(evfststgt
, evfststlt
, 0x0E, 0x0A, 0x00600000, PPC_SPEFPU
); //
5473 GEN_SPE(evfststeq
, speundef
, 0x0F, 0x0A, 0x00600000, PPC_SPEFPU
); //
5475 /* Single precision floating-point operations */
5477 GEN_SPEOP_ARITH2(efsadd
);
5478 GEN_SPEOP_ARITH2(efssub
);
5479 GEN_SPEOP_ARITH2(efsmul
);
5480 GEN_SPEOP_ARITH2(efsdiv
);
5481 GEN_SPEOP_ARITH1(efsabs
);
5482 GEN_SPEOP_ARITH1(efsnabs
);
5483 GEN_SPEOP_ARITH1(efsneg
);
5485 GEN_SPEFPUOP_CONV(efscfui
);
5486 GEN_SPEFPUOP_CONV(efscfsi
);
5487 GEN_SPEFPUOP_CONV(efscfuf
);
5488 GEN_SPEFPUOP_CONV(efscfsf
);
5489 GEN_SPEFPUOP_CONV(efsctui
);
5490 GEN_SPEFPUOP_CONV(efsctsi
);
5491 GEN_SPEFPUOP_CONV(efsctuf
);
5492 GEN_SPEFPUOP_CONV(efsctsf
);
5493 GEN_SPEFPUOP_CONV(efsctuiz
);
5494 GEN_SPEFPUOP_CONV(efsctsiz
);
5495 GEN_SPEFPUOP_CONV(efscfd
);
5497 GEN_SPEOP_COMP(efscmpgt
);
5498 GEN_SPEOP_COMP(efscmplt
);
5499 GEN_SPEOP_COMP(efscmpeq
);
5500 GEN_SPEOP_COMP(efststgt
);
5501 GEN_SPEOP_COMP(efststlt
);
5502 GEN_SPEOP_COMP(efststeq
);
5504 /* Opcodes definitions */
5505 GEN_SPE(efsadd
, efssub
, 0x00, 0x0A, 0x00000000, PPC_SPEFPU
); //
5506 GEN_SPE(efsabs
, efsnabs
, 0x02, 0x0B, 0x0000F800, PPC_SPEFPU
); //
5507 GEN_SPE(efsneg
, speundef
, 0x03, 0x0B, 0x0000F800, PPC_SPEFPU
); //
5508 GEN_SPE(efsmul
, efsdiv
, 0x04, 0x0B, 0x00000000, PPC_SPEFPU
); //
5509 GEN_SPE(efscmpgt
, efscmplt
, 0x06, 0x0B, 0x00600000, PPC_SPEFPU
); //
5510 GEN_SPE(efscmpeq
, efscfd
, 0x07, 0x0B, 0x00600000, PPC_SPEFPU
); //
5511 GEN_SPE(efscfui
, efscfsi
, 0x08, 0x0B, 0x00180000, PPC_SPEFPU
); //
5512 GEN_SPE(efscfuf
, efscfsf
, 0x09, 0x0B, 0x00180000, PPC_SPEFPU
); //
5513 GEN_SPE(efsctui
, efsctsi
, 0x0A, 0x0B, 0x00180000, PPC_SPEFPU
); //
5514 GEN_SPE(efsctuf
, efsctsf
, 0x0B, 0x0B, 0x00180000, PPC_SPEFPU
); //
5515 GEN_SPE(efsctuiz
, efsctsiz
, 0x0C, 0x0B, 0x00180000, PPC_SPEFPU
); //
5516 GEN_SPE(efststgt
, efststlt
, 0x0E, 0x0B, 0x00600000, PPC_SPEFPU
); //
5517 GEN_SPE(efststeq
, speundef
, 0x0F, 0x0B, 0x00600000, PPC_SPEFPU
); //
5519 /* Double precision floating-point operations */
5521 GEN_SPEOP_ARITH2(efdadd
);
5522 GEN_SPEOP_ARITH2(efdsub
);
5523 GEN_SPEOP_ARITH2(efdmul
);
5524 GEN_SPEOP_ARITH2(efddiv
);
5525 GEN_SPEOP_ARITH1(efdabs
);
5526 GEN_SPEOP_ARITH1(efdnabs
);
5527 GEN_SPEOP_ARITH1(efdneg
);
5530 GEN_SPEFPUOP_CONV(efdcfui
);
5531 GEN_SPEFPUOP_CONV(efdcfsi
);
5532 GEN_SPEFPUOP_CONV(efdcfuf
);
5533 GEN_SPEFPUOP_CONV(efdcfsf
);
5534 GEN_SPEFPUOP_CONV(efdctui
);
5535 GEN_SPEFPUOP_CONV(efdctsi
);
5536 GEN_SPEFPUOP_CONV(efdctuf
);
5537 GEN_SPEFPUOP_CONV(efdctsf
);
5538 GEN_SPEFPUOP_CONV(efdctuiz
);
5539 GEN_SPEFPUOP_CONV(efdctsiz
);
5540 GEN_SPEFPUOP_CONV(efdcfs
);
5541 GEN_SPEFPUOP_CONV(efdcfuid
);
5542 GEN_SPEFPUOP_CONV(efdcfsid
);
5543 GEN_SPEFPUOP_CONV(efdctuidz
);
5544 GEN_SPEFPUOP_CONV(efdctsidz
);
5546 GEN_SPEOP_COMP(efdcmpgt
);
5547 GEN_SPEOP_COMP(efdcmplt
);
5548 GEN_SPEOP_COMP(efdcmpeq
);
5549 GEN_SPEOP_COMP(efdtstgt
);
5550 GEN_SPEOP_COMP(efdtstlt
);
5551 GEN_SPEOP_COMP(efdtsteq
);
5553 /* Opcodes definitions */
5554 GEN_SPE(efdadd
, efdsub
, 0x10, 0x0B, 0x00000000, PPC_SPEFPU
); //
5555 GEN_SPE(efdcfuid
, efdcfsid
, 0x11, 0x0B, 0x00180000, PPC_SPEFPU
); //
5556 GEN_SPE(efdabs
, efdnabs
, 0x12, 0x0B, 0x0000F800, PPC_SPEFPU
); //
5557 GEN_SPE(efdneg
, speundef
, 0x13, 0x0B, 0x0000F800, PPC_SPEFPU
); //
5558 GEN_SPE(efdmul
, efddiv
, 0x14, 0x0B, 0x00000000, PPC_SPEFPU
); //
5559 GEN_SPE(efdctuidz
, efdctsidz
, 0x15, 0x0B, 0x00180000, PPC_SPEFPU
); //
5560 GEN_SPE(efdcmpgt
, efdcmplt
, 0x16, 0x0B, 0x00600000, PPC_SPEFPU
); //
5561 GEN_SPE(efdcmpeq
, efdcfs
, 0x17, 0x0B, 0x00600000, PPC_SPEFPU
); //
5562 GEN_SPE(efdcfui
, efdcfsi
, 0x18, 0x0B, 0x00180000, PPC_SPEFPU
); //
5563 GEN_SPE(efdcfuf
, efdcfsf
, 0x19, 0x0B, 0x00180000, PPC_SPEFPU
); //
5564 GEN_SPE(efdctui
, efdctsi
, 0x1A, 0x0B, 0x00180000, PPC_SPEFPU
); //
5565 GEN_SPE(efdctuf
, efdctsf
, 0x1B, 0x0B, 0x00180000, PPC_SPEFPU
); //
5566 GEN_SPE(efdctuiz
, speundef
, 0x1C, 0x0B, 0x00180000, PPC_SPEFPU
); //
5567 GEN_SPE(efdctsiz
, speundef
, 0x1D, 0x0B, 0x00180000, PPC_SPEFPU
); //
5568 GEN_SPE(efdtstgt
, efdtstlt
, 0x1E, 0x0B, 0x00600000, PPC_SPEFPU
); //
5569 GEN_SPE(efdtsteq
, speundef
, 0x1F, 0x0B, 0x00600000, PPC_SPEFPU
); //
5572 /* End opcode list */
5573 GEN_OPCODE_MARK(end
);
5575 #include "translate_init.c"
5577 /*****************************************************************************/
5578 /* Misc PowerPC helpers */
5579 static inline uint32_t load_xer (CPUState
*env
)
5581 return (xer_so
<< XER_SO
) |
5582 (xer_ov
<< XER_OV
) |
5583 (xer_ca
<< XER_CA
) |
5584 (xer_bc
<< XER_BC
) |
5585 (xer_cmp
<< XER_CMP
);
5588 void cpu_dump_state(CPUState
*env
, FILE *f
,
5589 int (*cpu_fprintf
)(FILE *f
, const char *fmt
, ...),
5592 #if defined(TARGET_PPC64) || 1
5604 cpu_fprintf(f
, "NIP " ADDRX
" LR " ADDRX
" CTR " ADDRX
"\n",
5605 env
->nip
, env
->lr
, env
->ctr
);
5606 cpu_fprintf(f
, "MSR " REGX FILL
" XER %08x "
5607 #if !defined(NO_TIMER_DUMP)
5609 #if !defined(CONFIG_USER_ONLY)
5614 do_load_msr(env
), load_xer(env
)
5615 #if !defined(NO_TIMER_DUMP)
5616 , cpu_ppc_load_tbu(env
), cpu_ppc_load_tbl(env
)
5617 #if !defined(CONFIG_USER_ONLY)
5618 , cpu_ppc_load_decr(env
)
5622 for (i
= 0; i
< 32; i
++) {
5623 if ((i
& (RGPL
- 1)) == 0)
5624 cpu_fprintf(f
, "GPR%02d", i
);
5625 cpu_fprintf(f
, " " REGX
, env
->gpr
[i
]);
5626 if ((i
& (RGPL
- 1)) == (RGPL
- 1))
5627 cpu_fprintf(f
, "\n");
5629 cpu_fprintf(f
, "CR ");
5630 for (i
= 0; i
< 8; i
++)
5631 cpu_fprintf(f
, "%01x", env
->crf
[i
]);
5632 cpu_fprintf(f
, " [");
5633 for (i
= 0; i
< 8; i
++) {
5635 if (env
->crf
[i
] & 0x08)
5637 else if (env
->crf
[i
] & 0x04)
5639 else if (env
->crf
[i
] & 0x02)
5641 cpu_fprintf(f
, " %c%c", a
, env
->crf
[i
] & 0x01 ? 'O' : ' ');
5643 cpu_fprintf(f
, " ] " FILL
"RES " REGX
"\n", env
->reserve
);
5644 for (i
= 0; i
< 32; i
++) {
5645 if ((i
& (RFPL
- 1)) == 0)
5646 cpu_fprintf(f
, "FPR%02d", i
);
5647 cpu_fprintf(f
, " %016" PRIx64
, *((uint64_t *)&env
->fpr
[i
]));
5648 if ((i
& (RFPL
- 1)) == (RFPL
- 1))
5649 cpu_fprintf(f
, "\n");
5651 cpu_fprintf(f
, "SRR0 " REGX
" SRR1 " REGX
" " FILL FILL FILL
5653 env
->spr
[SPR_SRR0
], env
->spr
[SPR_SRR1
], env
->sdr1
);
5660 void cpu_dump_statistics (CPUState
*env
, FILE*f
,
5661 int (*cpu_fprintf
)(FILE *f
, const char *fmt
, ...),
5664 #if defined(DO_PPC_STATISTICS)
5665 opc_handler_t
**t1
, **t2
, **t3
, *handler
;
5669 for (op1
= 0; op1
< 64; op1
++) {
5671 if (is_indirect_opcode(handler
)) {
5672 t2
= ind_table(handler
);
5673 for (op2
= 0; op2
< 32; op2
++) {
5675 if (is_indirect_opcode(handler
)) {
5676 t3
= ind_table(handler
);
5677 for (op3
= 0; op3
< 32; op3
++) {
5679 if (handler
->count
== 0)
5681 cpu_fprintf(f
, "%02x %02x %02x (%02x %04d) %16s: "
5683 op1
, op2
, op3
, op1
, (op3
<< 5) | op2
,
5685 handler
->count
, handler
->count
);
5688 if (handler
->count
== 0)
5690 cpu_fprintf(f
, "%02x %02x (%02x %04d) %16s: "
5692 op1
, op2
, op1
, op2
, handler
->oname
,
5693 handler
->count
, handler
->count
);
5697 if (handler
->count
== 0)
5699 cpu_fprintf(f
, "%02x (%02x ) %16s: %016llx %lld\n",
5700 op1
, op1
, handler
->oname
,
5701 handler
->count
, handler
->count
);
5707 /*****************************************************************************/
5708 static inline int gen_intermediate_code_internal (CPUState
*env
,
5709 TranslationBlock
*tb
,
5712 DisasContext ctx
, *ctxp
= &ctx
;
5713 opc_handler_t
**table
, *handler
;
5714 target_ulong pc_start
;
5715 uint16_t *gen_opc_end
;
5719 gen_opc_ptr
= gen_opc_buf
;
5720 gen_opc_end
= gen_opc_buf
+ OPC_MAX_SIZE
;
5721 gen_opparam_ptr
= gen_opparam_buf
;
5725 ctx
.exception
= EXCP_NONE
;
5726 ctx
.spr_cb
= env
->spr_cb
;
5727 #if defined(CONFIG_USER_ONLY)
5728 ctx
.mem_idx
= msr_le
;
5729 #if defined(TARGET_PPC64)
5730 ctx
.mem_idx
|= msr_sf
<< 1;
5733 ctx
.supervisor
= 1 - msr_pr
;
5734 ctx
.mem_idx
= ((1 - msr_pr
) << 1) | msr_le
;
5735 #if defined(TARGET_PPC64)
5736 ctx
.mem_idx
|= msr_sf
<< 2;
5739 #if defined(TARGET_PPC64)
5740 ctx
.sf_mode
= msr_sf
;
5742 ctx
.fpu_enabled
= msr_fp
;
5743 #if defined(TARGET_PPCEMB)
5744 ctx
.spe_enabled
= msr_spe
;
5746 ctx
.singlestep_enabled
= env
->singlestep_enabled
;
5747 #if defined (DO_SINGLE_STEP) && 0
5748 /* Single step trace mode */
5751 /* Set env in case of segfault during code fetch */
5752 while (ctx
.exception
== EXCP_NONE
&& gen_opc_ptr
< gen_opc_end
) {
5753 if (unlikely(env
->nb_breakpoints
> 0)) {
5754 for (j
= 0; j
< env
->nb_breakpoints
; j
++) {
5755 if (env
->breakpoints
[j
] == ctx
.nip
) {
5756 gen_update_nip(&ctx
, ctx
.nip
);
5762 if (unlikely(search_pc
)) {
5763 j
= gen_opc_ptr
- gen_opc_buf
;
5767 gen_opc_instr_start
[lj
++] = 0;
5768 gen_opc_pc
[lj
] = ctx
.nip
;
5769 gen_opc_instr_start
[lj
] = 1;
5772 #if defined PPC_DEBUG_DISAS
5773 if (loglevel
& CPU_LOG_TB_IN_ASM
) {
5774 fprintf(logfile
, "----------------\n");
5775 fprintf(logfile
, "nip=" ADDRX
" super=%d ir=%d\n",
5776 ctx
.nip
, 1 - msr_pr
, msr_ir
);
5779 ctx
.opcode
= ldl_code(ctx
.nip
);
5781 ctx
.opcode
= ((ctx
.opcode
& 0xFF000000) >> 24) |
5782 ((ctx
.opcode
& 0x00FF0000) >> 8) |
5783 ((ctx
.opcode
& 0x0000FF00) << 8) |
5784 ((ctx
.opcode
& 0x000000FF) << 24);
5786 #if defined PPC_DEBUG_DISAS
5787 if (loglevel
& CPU_LOG_TB_IN_ASM
) {
5788 fprintf(logfile
, "translate opcode %08x (%02x %02x %02x) (%s)\n",
5789 ctx
.opcode
, opc1(ctx
.opcode
), opc2(ctx
.opcode
),
5790 opc3(ctx
.opcode
), msr_le
? "little" : "big");
5794 table
= env
->opcodes
;
5795 handler
= table
[opc1(ctx
.opcode
)];
5796 if (is_indirect_opcode(handler
)) {
5797 table
= ind_table(handler
);
5798 handler
= table
[opc2(ctx
.opcode
)];
5799 if (is_indirect_opcode(handler
)) {
5800 table
= ind_table(handler
);
5801 handler
= table
[opc3(ctx
.opcode
)];
5804 /* Is opcode *REALLY* valid ? */
5805 if (unlikely(handler
->handler
== &gen_invalid
)) {
5806 if (loglevel
!= 0) {
5807 fprintf(logfile
, "invalid/unsupported opcode: "
5808 "%02x - %02x - %02x (%08x) 0x" ADDRX
" %d\n",
5809 opc1(ctx
.opcode
), opc2(ctx
.opcode
),
5810 opc3(ctx
.opcode
), ctx
.opcode
, ctx
.nip
- 4, msr_ir
);
5812 printf("invalid/unsupported opcode: "
5813 "%02x - %02x - %02x (%08x) 0x" ADDRX
" %d\n",
5814 opc1(ctx
.opcode
), opc2(ctx
.opcode
),
5815 opc3(ctx
.opcode
), ctx
.opcode
, ctx
.nip
- 4, msr_ir
);
5818 if (unlikely((ctx
.opcode
& handler
->inval
) != 0)) {
5819 if (loglevel
!= 0) {
5820 fprintf(logfile
, "invalid bits: %08x for opcode: "
5821 "%02x -%02x - %02x (%08x) 0x" ADDRX
"\n",
5822 ctx
.opcode
& handler
->inval
, opc1(ctx
.opcode
),
5823 opc2(ctx
.opcode
), opc3(ctx
.opcode
),
5824 ctx
.opcode
, ctx
.nip
- 4);
5826 printf("invalid bits: %08x for opcode: "
5827 "%02x -%02x - %02x (%08x) 0x" ADDRX
"\n",
5828 ctx
.opcode
& handler
->inval
, opc1(ctx
.opcode
),
5829 opc2(ctx
.opcode
), opc3(ctx
.opcode
),
5830 ctx
.opcode
, ctx
.nip
- 4);
5836 (*(handler
->handler
))(&ctx
);
5837 #if defined(DO_PPC_STATISTICS)
5840 /* Check trace mode exceptions */
5841 #if 0 // XXX: buggy on embedded PowerPC
5842 if (unlikely((msr_be
&& ctx
.exception
== EXCP_BRANCH
) ||
5843 /* Check in single step trace mode
5844 * we need to stop except if:
5845 * - rfi, trap or syscall
5846 * - first instruction of an exception handler
5848 (msr_se
&& (ctx
.nip
< 0x100 ||
5850 (ctx
.nip
& 0xFC) != 0x04) &&
5851 ctx
.exception
!= EXCP_SYSCALL
&&
5852 ctx
.exception
!= EXCP_SYSCALL_USER
&&
5853 ctx
.exception
!= EXCP_TRAP
))) {
5854 RET_EXCP(ctxp
, EXCP_TRACE
, 0);
5857 /* if we reach a page boundary or are single stepping, stop
5860 if (unlikely(((ctx
.nip
& (TARGET_PAGE_SIZE
- 1)) == 0) ||
5861 (env
->singlestep_enabled
))) {
5864 #if defined (DO_SINGLE_STEP)
5868 if (ctx
.exception
== EXCP_NONE
) {
5869 gen_goto_tb(&ctx
, 0, ctx
.nip
);
5870 } else if (ctx
.exception
!= EXCP_BRANCH
) {
5872 /* Generate the return instruction */
5875 *gen_opc_ptr
= INDEX_op_end
;
5876 if (unlikely(search_pc
)) {
5877 j
= gen_opc_ptr
- gen_opc_buf
;
5880 gen_opc_instr_start
[lj
++] = 0;
5883 tb
->size
= ctx
.nip
- pc_start
;
5885 #if defined(DEBUG_DISAS)
5886 if (loglevel
& CPU_LOG_TB_CPU
) {
5887 fprintf(logfile
, "---------------- excp: %04x\n", ctx
.exception
);
5888 cpu_dump_state(env
, logfile
, fprintf
, 0);
5890 if (loglevel
& CPU_LOG_TB_IN_ASM
) {
5893 fprintf(logfile
, "IN: %s\n", lookup_symbol(pc_start
));
5894 target_disas(logfile
, pc_start
, ctx
.nip
- pc_start
, flags
);
5895 fprintf(logfile
, "\n");
5897 if (loglevel
& CPU_LOG_TB_OP
) {
5898 fprintf(logfile
, "OP:\n");
5899 dump_ops(gen_opc_buf
, gen_opparam_buf
);
5900 fprintf(logfile
, "\n");
5906 int gen_intermediate_code (CPUState
*env
, struct TranslationBlock
*tb
)
5908 return gen_intermediate_code_internal(env
, tb
, 0);
5911 int gen_intermediate_code_pc (CPUState
*env
, struct TranslationBlock
*tb
)
5913 return gen_intermediate_code_internal(env
, tb
, 1);