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_PPCSPE)
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 */
3029 fprintf(logfile, "Trying to read priviledged spr %d %03x\n",
3032 printf("Trying to read priviledged spr %d %03x\n", sprn, sprn);
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 */
3135 fprintf(logfile, "Trying to write priviledged spr %d %03x\n",
3138 printf("Trying to write priviledged spr %d %03x\n", sprn, sprn);
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_PPCSPE)
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_PPCSPE)
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)) {
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)) {
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);