As icbi is not a priviledge instruction and is treated as a load by the MMU
[qemu/mini2440.git] / target-ppc / translate.c
blob82919a58753e34c9c17afb8c844ef0c543d96f83
1 /*
2 * PowerPC emulation for qemu: main translation routines.
3 *
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
20 #include <stdarg.h>
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <inttypes.h>
26 #include "cpu.h"
27 #include "exec-all.h"
28 #include "disas.h"
30 //#define DO_SINGLE_STEP
31 //#define PPC_DEBUG_DISAS
32 //#define DO_PPC_STATISTICS
34 #if defined(USE_DIRECT_JUMP)
35 #define TBPARAM(x)
36 #else
37 #define TBPARAM(x) (long)(x)
38 #endif
40 enum {
41 #define DEF(s, n, copy_size) INDEX_op_ ## s,
42 #include "opc.h"
43 #undef DEF
44 NB_OPS,
47 static uint16_t *gen_opc_ptr;
48 static uint32_t *gen_opparam_ptr;
50 #include "gen-op.h"
52 static inline void gen_set_T0 (target_ulong val)
54 #if defined(TARGET_PPC64)
55 if (val >> 32)
56 gen_op_set_T0_64(val >> 32, val);
57 else
58 #endif
59 gen_op_set_T0(val);
62 static inline void gen_set_T1 (target_ulong val)
64 #if defined(TARGET_PPC64)
65 if (val >> 32)
66 gen_op_set_T1_64(val >> 32, val);
67 else
68 #endif
69 gen_op_set_T1(val);
72 #define GEN8(func, NAME) \
73 static GenOpFunc *NAME ## _table [8] = { \
74 NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3, \
75 NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7, \
76 }; \
77 static inline void func(int n) \
78 { \
79 NAME ## _table[n](); \
82 #define GEN16(func, NAME) \
83 static GenOpFunc *NAME ## _table [16] = { \
84 NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3, \
85 NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7, \
86 NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11, \
87 NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15, \
88 }; \
89 static inline void func(int n) \
90 { \
91 NAME ## _table[n](); \
94 #define GEN32(func, NAME) \
95 static GenOpFunc *NAME ## _table [32] = { \
96 NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3, \
97 NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7, \
98 NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11, \
99 NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15, \
100 NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19, \
101 NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23, \
102 NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27, \
103 NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31, \
104 }; \
105 static inline void func(int n) \
107 NAME ## _table[n](); \
110 /* Condition register moves */
111 GEN8(gen_op_load_crf_T0, gen_op_load_crf_T0_crf);
112 GEN8(gen_op_load_crf_T1, gen_op_load_crf_T1_crf);
113 GEN8(gen_op_store_T0_crf, gen_op_store_T0_crf_crf);
114 GEN8(gen_op_store_T1_crf, gen_op_store_T1_crf_crf);
116 /* Floating point condition and status register moves */
117 GEN8(gen_op_load_fpscr_T0, gen_op_load_fpscr_T0_fpscr);
118 GEN8(gen_op_store_T0_fpscr, gen_op_store_T0_fpscr_fpscr);
119 GEN8(gen_op_clear_fpscr, gen_op_clear_fpscr_fpscr);
120 static inline void gen_op_store_T0_fpscri(int n, uint8_t param)
122 gen_op_set_T0(param);
123 gen_op_store_T0_fpscr(n);
126 /* General purpose registers moves */
127 GEN32(gen_op_load_gpr_T0, gen_op_load_gpr_T0_gpr);
128 GEN32(gen_op_load_gpr_T1, gen_op_load_gpr_T1_gpr);
129 GEN32(gen_op_load_gpr_T2, gen_op_load_gpr_T2_gpr);
131 GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr);
132 GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr);
133 #if 0 // unused
134 GEN32(gen_op_store_T2_gpr, gen_op_store_T2_gpr_gpr);
135 #endif
137 /* floating point registers moves */
138 GEN32(gen_op_load_fpr_FT0, gen_op_load_fpr_FT0_fpr);
139 GEN32(gen_op_load_fpr_FT1, gen_op_load_fpr_FT1_fpr);
140 GEN32(gen_op_load_fpr_FT2, gen_op_load_fpr_FT2_fpr);
141 GEN32(gen_op_store_FT0_fpr, gen_op_store_FT0_fpr_fpr);
142 GEN32(gen_op_store_FT1_fpr, gen_op_store_FT1_fpr_fpr);
143 #if 0 // unused
144 GEN32(gen_op_store_FT2_fpr, gen_op_store_FT2_fpr_fpr);
145 #endif
147 /* internal defines */
148 typedef struct DisasContext {
149 struct TranslationBlock *tb;
150 target_ulong nip;
151 uint32_t opcode;
152 uint32_t exception;
153 /* Routine used to access memory */
154 int mem_idx;
155 /* Translation flags */
156 #if !defined(CONFIG_USER_ONLY)
157 int supervisor;
158 #endif
159 #if defined(TARGET_PPC64)
160 int sf_mode;
161 #endif
162 int fpu_enabled;
163 ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
164 int singlestep_enabled;
165 } DisasContext;
167 struct opc_handler_t {
168 /* invalid bits */
169 uint32_t inval;
170 /* instruction type */
171 uint32_t type;
172 /* handler */
173 void (*handler)(DisasContext *ctx);
174 #if defined(DO_PPC_STATISTICS)
175 const unsigned char *oname;
176 uint64_t count;
177 #endif
180 static inline void gen_set_Rc0 (DisasContext *ctx)
182 #if defined(TARGET_PPC64)
183 if (ctx->sf_mode)
184 gen_op_cmpi_64(0);
185 else
186 #endif
187 gen_op_cmpi(0);
188 gen_op_set_Rc0();
191 static inline void gen_update_nip (DisasContext *ctx, target_ulong nip)
193 #if defined(TARGET_PPC64)
194 if (ctx->sf_mode)
195 gen_op_update_nip_64(nip >> 32, nip);
196 else
197 #endif
198 gen_op_update_nip(nip);
201 #define RET_EXCP(ctx, excp, error) \
202 do { \
203 if ((ctx)->exception == EXCP_NONE) { \
204 gen_update_nip(ctx, (ctx)->nip); \
206 gen_op_raise_exception_err((excp), (error)); \
207 ctx->exception = (excp); \
208 } while (0)
210 #define RET_INVAL(ctx) \
211 RET_EXCP((ctx), EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_INVAL)
213 #define RET_PRIVOPC(ctx) \
214 RET_EXCP((ctx), EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_OPC)
216 #define RET_PRIVREG(ctx) \
217 RET_EXCP((ctx), EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_REG)
219 /* Stop translation */
220 static inline void RET_STOP (DisasContext *ctx)
222 gen_update_nip(ctx, ctx->nip);
223 ctx->exception = EXCP_MTMSR;
226 /* No need to update nip here, as execution flow will change */
227 static inline void RET_CHG_FLOW (DisasContext *ctx)
229 ctx->exception = EXCP_MTMSR;
232 #define GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \
233 static void gen_##name (DisasContext *ctx); \
234 GEN_OPCODE(name, opc1, opc2, opc3, inval, type); \
235 static void gen_##name (DisasContext *ctx)
237 typedef struct opcode_t {
238 unsigned char opc1, opc2, opc3;
239 #if HOST_LONG_BITS == 64 /* Explicitely align to 64 bits */
240 unsigned char pad[5];
241 #else
242 unsigned char pad[1];
243 #endif
244 opc_handler_t handler;
245 const unsigned char *oname;
246 } opcode_t;
248 /*** Instruction decoding ***/
249 #define EXTRACT_HELPER(name, shift, nb) \
250 static inline uint32_t name (uint32_t opcode) \
252 return (opcode >> (shift)) & ((1 << (nb)) - 1); \
255 #define EXTRACT_SHELPER(name, shift, nb) \
256 static inline int32_t name (uint32_t opcode) \
258 return (int16_t)((opcode >> (shift)) & ((1 << (nb)) - 1)); \
261 /* Opcode part 1 */
262 EXTRACT_HELPER(opc1, 26, 6);
263 /* Opcode part 2 */
264 EXTRACT_HELPER(opc2, 1, 5);
265 /* Opcode part 3 */
266 EXTRACT_HELPER(opc3, 6, 5);
267 /* Update Cr0 flags */
268 EXTRACT_HELPER(Rc, 0, 1);
269 /* Destination */
270 EXTRACT_HELPER(rD, 21, 5);
271 /* Source */
272 EXTRACT_HELPER(rS, 21, 5);
273 /* First operand */
274 EXTRACT_HELPER(rA, 16, 5);
275 /* Second operand */
276 EXTRACT_HELPER(rB, 11, 5);
277 /* Third operand */
278 EXTRACT_HELPER(rC, 6, 5);
279 /*** Get CRn ***/
280 EXTRACT_HELPER(crfD, 23, 3);
281 EXTRACT_HELPER(crfS, 18, 3);
282 EXTRACT_HELPER(crbD, 21, 5);
283 EXTRACT_HELPER(crbA, 16, 5);
284 EXTRACT_HELPER(crbB, 11, 5);
285 /* SPR / TBL */
286 EXTRACT_HELPER(_SPR, 11, 10);
287 static inline uint32_t SPR (uint32_t opcode)
289 uint32_t sprn = _SPR(opcode);
291 return ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
293 /*** Get constants ***/
294 EXTRACT_HELPER(IMM, 12, 8);
295 /* 16 bits signed immediate value */
296 EXTRACT_SHELPER(SIMM, 0, 16);
297 /* 16 bits unsigned immediate value */
298 EXTRACT_HELPER(UIMM, 0, 16);
299 /* Bit count */
300 EXTRACT_HELPER(NB, 11, 5);
301 /* Shift count */
302 EXTRACT_HELPER(SH, 11, 5);
303 /* Mask start */
304 EXTRACT_HELPER(MB, 6, 5);
305 /* Mask end */
306 EXTRACT_HELPER(ME, 1, 5);
307 /* Trap operand */
308 EXTRACT_HELPER(TO, 21, 5);
310 EXTRACT_HELPER(CRM, 12, 8);
311 EXTRACT_HELPER(FM, 17, 8);
312 EXTRACT_HELPER(SR, 16, 4);
313 EXTRACT_HELPER(FPIMM, 20, 4);
315 /*** Jump target decoding ***/
316 /* Displacement */
317 EXTRACT_SHELPER(d, 0, 16);
318 /* Immediate address */
319 static inline target_ulong LI (uint32_t opcode)
321 return (opcode >> 0) & 0x03FFFFFC;
324 static inline uint32_t BD (uint32_t opcode)
326 return (opcode >> 0) & 0xFFFC;
329 EXTRACT_HELPER(BO, 21, 5);
330 EXTRACT_HELPER(BI, 16, 5);
331 /* Absolute/relative address */
332 EXTRACT_HELPER(AA, 1, 1);
333 /* Link */
334 EXTRACT_HELPER(LK, 0, 1);
336 /* Create a mask between <start> and <end> bits */
337 static inline target_ulong MASK (uint32_t start, uint32_t end)
339 target_ulong ret;
341 #if defined(TARGET_PPC64)
342 if (likely(start == 0)) {
343 ret = (uint64_t)(-1ULL) << (63 - end);
344 } else if (likely(end == 63)) {
345 ret = (uint64_t)(-1ULL) >> start;
347 #else
348 if (likely(start == 0)) {
349 ret = (uint32_t)(-1ULL) << (31 - end);
350 } else if (likely(end == 31)) {
351 ret = (uint32_t)(-1ULL) >> start;
353 #endif
354 else {
355 ret = (((target_ulong)(-1ULL)) >> (start)) ^
356 (((target_ulong)(-1ULL) >> (end)) >> 1);
357 if (unlikely(start > end))
358 return ~ret;
361 return ret;
364 #if HOST_LONG_BITS == 64
365 #define OPC_ALIGN 8
366 #else
367 #define OPC_ALIGN 4
368 #endif
369 #if defined(__APPLE__)
370 #define OPCODES_SECTION \
371 __attribute__ ((section("__TEXT,__opcodes"), unused, aligned (OPC_ALIGN) ))
372 #else
373 #define OPCODES_SECTION \
374 __attribute__ ((section(".opcodes"), unused, aligned (OPC_ALIGN) ))
375 #endif
377 #if defined(DO_PPC_STATISTICS)
378 #define GEN_OPCODE(name, op1, op2, op3, invl, _typ) \
379 OPCODES_SECTION opcode_t opc_##name = { \
380 .opc1 = op1, \
381 .opc2 = op2, \
382 .opc3 = op3, \
383 .pad = { 0, }, \
384 .handler = { \
385 .inval = invl, \
386 .type = _typ, \
387 .handler = &gen_##name, \
388 .oname = stringify(name), \
389 }, \
390 .oname = stringify(name), \
392 #else
393 #define GEN_OPCODE(name, op1, op2, op3, invl, _typ) \
394 OPCODES_SECTION opcode_t opc_##name = { \
395 .opc1 = op1, \
396 .opc2 = op2, \
397 .opc3 = op3, \
398 .pad = { 0, }, \
399 .handler = { \
400 .inval = invl, \
401 .type = _typ, \
402 .handler = &gen_##name, \
403 }, \
404 .oname = stringify(name), \
406 #endif
408 #define GEN_OPCODE_MARK(name) \
409 OPCODES_SECTION opcode_t opc_##name = { \
410 .opc1 = 0xFF, \
411 .opc2 = 0xFF, \
412 .opc3 = 0xFF, \
413 .pad = { 0, }, \
414 .handler = { \
415 .inval = 0x00000000, \
416 .type = 0x00, \
417 .handler = NULL, \
418 }, \
419 .oname = stringify(name), \
422 /* Start opcode list */
423 GEN_OPCODE_MARK(start);
425 /* Invalid instruction */
426 GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE)
428 RET_INVAL(ctx);
431 static opc_handler_t invalid_handler = {
432 .inval = 0xFFFFFFFF,
433 .type = PPC_NONE,
434 .handler = gen_invalid,
437 /*** Integer arithmetic ***/
438 #define __GEN_INT_ARITH2(name, opc1, opc2, opc3, inval, type) \
439 GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \
441 gen_op_load_gpr_T0(rA(ctx->opcode)); \
442 gen_op_load_gpr_T1(rB(ctx->opcode)); \
443 gen_op_##name(); \
444 gen_op_store_T0_gpr(rD(ctx->opcode)); \
445 if (unlikely(Rc(ctx->opcode) != 0)) \
446 gen_set_Rc0(ctx); \
449 #define __GEN_INT_ARITH2_O(name, opc1, opc2, opc3, inval, type) \
450 GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \
452 gen_op_load_gpr_T0(rA(ctx->opcode)); \
453 gen_op_load_gpr_T1(rB(ctx->opcode)); \
454 gen_op_##name(); \
455 gen_op_store_T0_gpr(rD(ctx->opcode)); \
456 if (unlikely(Rc(ctx->opcode) != 0)) \
457 gen_set_Rc0(ctx); \
460 #define __GEN_INT_ARITH1(name, opc1, opc2, opc3, type) \
461 GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type) \
463 gen_op_load_gpr_T0(rA(ctx->opcode)); \
464 gen_op_##name(); \
465 gen_op_store_T0_gpr(rD(ctx->opcode)); \
466 if (unlikely(Rc(ctx->opcode) != 0)) \
467 gen_set_Rc0(ctx); \
469 #define __GEN_INT_ARITH1_O(name, opc1, opc2, opc3, type) \
470 GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type) \
472 gen_op_load_gpr_T0(rA(ctx->opcode)); \
473 gen_op_##name(); \
474 gen_op_store_T0_gpr(rD(ctx->opcode)); \
475 if (unlikely(Rc(ctx->opcode) != 0)) \
476 gen_set_Rc0(ctx); \
479 /* Two operands arithmetic functions */
480 #define GEN_INT_ARITH2(name, opc1, opc2, opc3, type) \
481 __GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000000, type) \
482 __GEN_INT_ARITH2_O(name##o, opc1, opc2, opc3 | 0x10, 0x00000000, type)
484 /* Two operands arithmetic functions with no overflow allowed */
485 #define GEN_INT_ARITHN(name, opc1, opc2, opc3, type) \
486 __GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000400, type)
488 /* One operand arithmetic functions */
489 #define GEN_INT_ARITH1(name, opc1, opc2, opc3, type) \
490 __GEN_INT_ARITH1(name, opc1, opc2, opc3, type) \
491 __GEN_INT_ARITH1_O(name##o, opc1, opc2, opc3 | 0x10, type)
493 #if defined(TARGET_PPC64)
494 #define __GEN_INT_ARITH2_64(name, opc1, opc2, opc3, inval, type) \
495 GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \
497 gen_op_load_gpr_T0(rA(ctx->opcode)); \
498 gen_op_load_gpr_T1(rB(ctx->opcode)); \
499 if (ctx->sf_mode) \
500 gen_op_##name##_64(); \
501 else \
502 gen_op_##name(); \
503 gen_op_store_T0_gpr(rD(ctx->opcode)); \
504 if (unlikely(Rc(ctx->opcode) != 0)) \
505 gen_set_Rc0(ctx); \
508 #define __GEN_INT_ARITH2_O_64(name, opc1, opc2, opc3, inval, type) \
509 GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \
511 gen_op_load_gpr_T0(rA(ctx->opcode)); \
512 gen_op_load_gpr_T1(rB(ctx->opcode)); \
513 if (ctx->sf_mode) \
514 gen_op_##name##_64(); \
515 else \
516 gen_op_##name(); \
517 gen_op_store_T0_gpr(rD(ctx->opcode)); \
518 if (unlikely(Rc(ctx->opcode) != 0)) \
519 gen_set_Rc0(ctx); \
522 #define __GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type) \
523 GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type) \
525 gen_op_load_gpr_T0(rA(ctx->opcode)); \
526 if (ctx->sf_mode) \
527 gen_op_##name##_64(); \
528 else \
529 gen_op_##name(); \
530 gen_op_store_T0_gpr(rD(ctx->opcode)); \
531 if (unlikely(Rc(ctx->opcode) != 0)) \
532 gen_set_Rc0(ctx); \
534 #define __GEN_INT_ARITH1_O_64(name, opc1, opc2, opc3, type) \
535 GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type) \
537 gen_op_load_gpr_T0(rA(ctx->opcode)); \
538 if (ctx->sf_mode) \
539 gen_op_##name##_64(); \
540 else \
541 gen_op_##name(); \
542 gen_op_store_T0_gpr(rD(ctx->opcode)); \
543 if (unlikely(Rc(ctx->opcode) != 0)) \
544 gen_set_Rc0(ctx); \
547 /* Two operands arithmetic functions */
548 #define GEN_INT_ARITH2_64(name, opc1, opc2, opc3, type) \
549 __GEN_INT_ARITH2_64(name, opc1, opc2, opc3, 0x00000000, type) \
550 __GEN_INT_ARITH2_O_64(name##o, opc1, opc2, opc3 | 0x10, 0x00000000, type)
552 /* Two operands arithmetic functions with no overflow allowed */
553 #define GEN_INT_ARITHN_64(name, opc1, opc2, opc3, type) \
554 __GEN_INT_ARITH2_64(name, opc1, opc2, opc3, 0x00000400, type)
556 /* One operand arithmetic functions */
557 #define GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type) \
558 __GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type) \
559 __GEN_INT_ARITH1_O_64(name##o, opc1, opc2, opc3 | 0x10, type)
560 #else
561 #define GEN_INT_ARITH2_64 GEN_INT_ARITH2
562 #define GEN_INT_ARITHN_64 GEN_INT_ARITHN
563 #define GEN_INT_ARITH1_64 GEN_INT_ARITH1
564 #endif
566 /* add add. addo addo. */
567 static inline void gen_op_addo (void)
569 gen_op_move_T2_T0();
570 gen_op_add();
571 gen_op_check_addo();
573 #if defined(TARGET_PPC64)
574 #define gen_op_add_64 gen_op_add
575 static inline void gen_op_addo_64 (void)
577 gen_op_move_T2_T0();
578 gen_op_add();
579 gen_op_check_addo_64();
581 #endif
582 GEN_INT_ARITH2_64 (add, 0x1F, 0x0A, 0x08, PPC_INTEGER);
583 /* addc addc. addco addco. */
584 static inline void gen_op_addc (void)
586 gen_op_move_T2_T0();
587 gen_op_add();
588 gen_op_check_addc();
590 static inline void gen_op_addco (void)
592 gen_op_move_T2_T0();
593 gen_op_add();
594 gen_op_check_addc();
595 gen_op_check_addo();
597 #if defined(TARGET_PPC64)
598 static inline void gen_op_addc_64 (void)
600 gen_op_move_T2_T0();
601 gen_op_add();
602 gen_op_check_addc_64();
604 static inline void gen_op_addco_64 (void)
606 gen_op_move_T2_T0();
607 gen_op_add();
608 gen_op_check_addc_64();
609 gen_op_check_addo_64();
611 #endif
612 GEN_INT_ARITH2_64 (addc, 0x1F, 0x0A, 0x00, PPC_INTEGER);
613 /* adde adde. addeo addeo. */
614 static inline void gen_op_addeo (void)
616 gen_op_move_T2_T0();
617 gen_op_adde();
618 gen_op_check_addo();
620 #if defined(TARGET_PPC64)
621 static inline void gen_op_addeo_64 (void)
623 gen_op_move_T2_T0();
624 gen_op_adde_64();
625 gen_op_check_addo_64();
627 #endif
628 GEN_INT_ARITH2_64 (adde, 0x1F, 0x0A, 0x04, PPC_INTEGER);
629 /* addme addme. addmeo addmeo. */
630 static inline void gen_op_addme (void)
632 gen_op_move_T1_T0();
633 gen_op_add_me();
635 #if defined(TARGET_PPC64)
636 static inline void gen_op_addme_64 (void)
638 gen_op_move_T1_T0();
639 gen_op_add_me_64();
641 #endif
642 GEN_INT_ARITH1_64 (addme, 0x1F, 0x0A, 0x07, PPC_INTEGER);
643 /* addze addze. addzeo addzeo. */
644 static inline void gen_op_addze (void)
646 gen_op_move_T2_T0();
647 gen_op_add_ze();
648 gen_op_check_addc();
650 static inline void gen_op_addzeo (void)
652 gen_op_move_T2_T0();
653 gen_op_add_ze();
654 gen_op_check_addc();
655 gen_op_check_addo();
657 #if defined(TARGET_PPC64)
658 static inline void gen_op_addze_64 (void)
660 gen_op_move_T2_T0();
661 gen_op_add_ze();
662 gen_op_check_addc_64();
664 static inline void gen_op_addzeo_64 (void)
666 gen_op_move_T2_T0();
667 gen_op_add_ze();
668 gen_op_check_addc_64();
669 gen_op_check_addo_64();
671 #endif
672 GEN_INT_ARITH1_64 (addze, 0x1F, 0x0A, 0x06, PPC_INTEGER);
673 /* divw divw. divwo divwo. */
674 GEN_INT_ARITH2 (divw, 0x1F, 0x0B, 0x0F, PPC_INTEGER);
675 /* divwu divwu. divwuo divwuo. */
676 GEN_INT_ARITH2 (divwu, 0x1F, 0x0B, 0x0E, PPC_INTEGER);
677 /* mulhw mulhw. */
678 GEN_INT_ARITHN (mulhw, 0x1F, 0x0B, 0x02, PPC_INTEGER);
679 /* mulhwu mulhwu. */
680 GEN_INT_ARITHN (mulhwu, 0x1F, 0x0B, 0x00, PPC_INTEGER);
681 /* mullw mullw. mullwo mullwo. */
682 GEN_INT_ARITH2 (mullw, 0x1F, 0x0B, 0x07, PPC_INTEGER);
683 /* neg neg. nego nego. */
684 GEN_INT_ARITH1_64 (neg, 0x1F, 0x08, 0x03, PPC_INTEGER);
685 /* subf subf. subfo subfo. */
686 static inline void gen_op_subfo (void)
688 gen_op_move_T2_T0();
689 gen_op_subf();
690 gen_op_check_subfo();
692 #if defined(TARGET_PPC64)
693 #define gen_op_subf_64 gen_op_subf
694 static inline void gen_op_subfo_64 (void)
696 gen_op_move_T2_T0();
697 gen_op_subf();
698 gen_op_check_subfo_64();
700 #endif
701 GEN_INT_ARITH2_64 (subf, 0x1F, 0x08, 0x01, PPC_INTEGER);
702 /* subfc subfc. subfco subfco. */
703 static inline void gen_op_subfc (void)
705 gen_op_subf();
706 gen_op_check_subfc();
708 static inline void gen_op_subfco (void)
710 gen_op_move_T2_T0();
711 gen_op_subf();
712 gen_op_check_subfc();
713 gen_op_check_subfo();
715 #if defined(TARGET_PPC64)
716 static inline void gen_op_subfc_64 (void)
718 gen_op_subf();
719 gen_op_check_subfc_64();
721 static inline void gen_op_subfco_64 (void)
723 gen_op_move_T2_T0();
724 gen_op_subf();
725 gen_op_check_subfc_64();
726 gen_op_check_subfo_64();
728 #endif
729 GEN_INT_ARITH2_64 (subfc, 0x1F, 0x08, 0x00, PPC_INTEGER);
730 /* subfe subfe. subfeo subfeo. */
731 static inline void gen_op_subfeo (void)
733 gen_op_move_T2_T0();
734 gen_op_subfe();
735 gen_op_check_subfo();
737 #if defined(TARGET_PPC64)
738 #define gen_op_subfe_64 gen_op_subfe
739 static inline void gen_op_subfeo_64 (void)
741 gen_op_move_T2_T0();
742 gen_op_subfe_64();
743 gen_op_check_subfo_64();
745 #endif
746 GEN_INT_ARITH2_64 (subfe, 0x1F, 0x08, 0x04, PPC_INTEGER);
747 /* subfme subfme. subfmeo subfmeo. */
748 GEN_INT_ARITH1_64 (subfme, 0x1F, 0x08, 0x07, PPC_INTEGER);
749 /* subfze subfze. subfzeo subfzeo. */
750 GEN_INT_ARITH1_64 (subfze, 0x1F, 0x08, 0x06, PPC_INTEGER);
751 /* addi */
752 GEN_HANDLER(addi, 0x0E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
754 target_long simm = SIMM(ctx->opcode);
756 if (rA(ctx->opcode) == 0) {
757 /* li case */
758 gen_set_T0(simm);
759 } else {
760 gen_op_load_gpr_T0(rA(ctx->opcode));
761 if (likely(simm != 0))
762 gen_op_addi(simm);
764 gen_op_store_T0_gpr(rD(ctx->opcode));
766 /* addic */
767 GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
769 target_long simm = SIMM(ctx->opcode);
771 gen_op_load_gpr_T0(rA(ctx->opcode));
772 if (likely(simm != 0)) {
773 gen_op_move_T2_T0();
774 gen_op_addi(simm);
775 #if defined(TARGET_PPC64)
776 if (ctx->sf_mode)
777 gen_op_check_addc_64();
778 else
779 #endif
780 gen_op_check_addc();
782 gen_op_store_T0_gpr(rD(ctx->opcode));
784 /* addic. */
785 GEN_HANDLER(addic_, 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
787 target_long simm = SIMM(ctx->opcode);
789 gen_op_load_gpr_T0(rA(ctx->opcode));
790 if (likely(simm != 0)) {
791 gen_op_move_T2_T0();
792 gen_op_addi(simm);
793 #if defined(TARGET_PPC64)
794 if (ctx->sf_mode)
795 gen_op_check_addc_64();
796 else
797 #endif
798 gen_op_check_addc();
800 gen_op_store_T0_gpr(rD(ctx->opcode));
801 gen_set_Rc0(ctx);
803 /* addis */
804 GEN_HANDLER(addis, 0x0F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
806 target_long simm = SIMM(ctx->opcode);
808 if (rA(ctx->opcode) == 0) {
809 /* lis case */
810 gen_set_T0(simm << 16);
811 } else {
812 gen_op_load_gpr_T0(rA(ctx->opcode));
813 if (likely(simm != 0))
814 gen_op_addi(simm << 16);
816 gen_op_store_T0_gpr(rD(ctx->opcode));
818 /* mulli */
819 GEN_HANDLER(mulli, 0x07, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
821 gen_op_load_gpr_T0(rA(ctx->opcode));
822 gen_op_mulli(SIMM(ctx->opcode));
823 gen_op_store_T0_gpr(rD(ctx->opcode));
825 /* subfic */
826 GEN_HANDLER(subfic, 0x08, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
828 gen_op_load_gpr_T0(rA(ctx->opcode));
829 #if defined(TARGET_PPC64)
830 if (ctx->sf_mode)
831 gen_op_subfic_64(SIMM(ctx->opcode));
832 else
833 #endif
834 gen_op_subfic(SIMM(ctx->opcode));
835 gen_op_store_T0_gpr(rD(ctx->opcode));
838 #if defined(TARGET_PPC64)
839 /* mulhd mulhd. */
840 GEN_INT_ARITHN (mulhd, 0x1F, 0x09, 0x02, PPC_INTEGER);
841 /* mulhdu mulhdu. */
842 GEN_INT_ARITHN (mulhdu, 0x1F, 0x09, 0x00, PPC_INTEGER);
843 /* mulld mulld. mulldo mulldo. */
844 GEN_INT_ARITH2 (mulld, 0x1F, 0x09, 0x07, PPC_INTEGER);
845 /* divd divd. divdo divdo. */
846 GEN_INT_ARITH2 (divd, 0x1F, 0x09, 0x0F, PPC_INTEGER);
847 /* divdu divdu. divduo divduo. */
848 GEN_INT_ARITH2 (divdu, 0x1F, 0x09, 0x0E, PPC_INTEGER);
849 #endif
851 /*** Integer comparison ***/
852 #if defined(TARGET_PPC64)
853 #define GEN_CMP(name, opc, type) \
854 GEN_HANDLER(name, 0x1F, 0x00, opc, 0x00400000, type) \
856 gen_op_load_gpr_T0(rA(ctx->opcode)); \
857 gen_op_load_gpr_T1(rB(ctx->opcode)); \
858 if (ctx->sf_mode) \
859 gen_op_##name##_64(); \
860 else \
861 gen_op_##name(); \
862 gen_op_store_T0_crf(crfD(ctx->opcode)); \
864 #else
865 #define GEN_CMP(name, opc, type) \
866 GEN_HANDLER(name, 0x1F, 0x00, opc, 0x00400000, type) \
868 gen_op_load_gpr_T0(rA(ctx->opcode)); \
869 gen_op_load_gpr_T1(rB(ctx->opcode)); \
870 gen_op_##name(); \
871 gen_op_store_T0_crf(crfD(ctx->opcode)); \
873 #endif
875 /* cmp */
876 GEN_CMP(cmp, 0x00, PPC_INTEGER);
877 /* cmpi */
878 GEN_HANDLER(cmpi, 0x0B, 0xFF, 0xFF, 0x00400000, PPC_INTEGER)
880 gen_op_load_gpr_T0(rA(ctx->opcode));
881 #if defined(TARGET_PPC64)
882 if (ctx->sf_mode)
883 gen_op_cmpi_64(SIMM(ctx->opcode));
884 else
885 #endif
886 gen_op_cmpi(SIMM(ctx->opcode));
887 gen_op_store_T0_crf(crfD(ctx->opcode));
889 /* cmpl */
890 GEN_CMP(cmpl, 0x01, PPC_INTEGER);
891 /* cmpli */
892 GEN_HANDLER(cmpli, 0x0A, 0xFF, 0xFF, 0x00400000, PPC_INTEGER)
894 gen_op_load_gpr_T0(rA(ctx->opcode));
895 #if defined(TARGET_PPC64)
896 if (ctx->sf_mode)
897 gen_op_cmpli_64(UIMM(ctx->opcode));
898 else
899 #endif
900 gen_op_cmpli(UIMM(ctx->opcode));
901 gen_op_store_T0_crf(crfD(ctx->opcode));
904 /* isel (PowerPC 2.03 specification) */
905 GEN_HANDLER(isel, 0x1F, 0x0F, 0x00, 0x00000001, PPC_203)
907 uint32_t bi = rC(ctx->opcode);
908 uint32_t mask;
910 if (rA(ctx->opcode) == 0) {
911 gen_set_T0(0);
912 } else {
913 gen_op_load_gpr_T1(rA(ctx->opcode));
915 gen_op_load_gpr_T2(rB(ctx->opcode));
916 mask = 1 << (3 - (bi & 0x03));
917 gen_op_load_crf_T0(bi >> 2);
918 gen_op_test_true(mask);
919 gen_op_isel();
920 gen_op_store_T0_gpr(rD(ctx->opcode));
923 /*** Integer logical ***/
924 #define __GEN_LOGICAL2(name, opc2, opc3, type) \
925 GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000000, type) \
927 gen_op_load_gpr_T0(rS(ctx->opcode)); \
928 gen_op_load_gpr_T1(rB(ctx->opcode)); \
929 gen_op_##name(); \
930 gen_op_store_T0_gpr(rA(ctx->opcode)); \
931 if (unlikely(Rc(ctx->opcode) != 0)) \
932 gen_set_Rc0(ctx); \
934 #define GEN_LOGICAL2(name, opc, type) \
935 __GEN_LOGICAL2(name, 0x1C, opc, type)
937 #define GEN_LOGICAL1(name, opc, type) \
938 GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, type) \
940 gen_op_load_gpr_T0(rS(ctx->opcode)); \
941 gen_op_##name(); \
942 gen_op_store_T0_gpr(rA(ctx->opcode)); \
943 if (unlikely(Rc(ctx->opcode) != 0)) \
944 gen_set_Rc0(ctx); \
947 /* and & and. */
948 GEN_LOGICAL2(and, 0x00, PPC_INTEGER);
949 /* andc & andc. */
950 GEN_LOGICAL2(andc, 0x01, PPC_INTEGER);
951 /* andi. */
952 GEN_HANDLER(andi_, 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
954 gen_op_load_gpr_T0(rS(ctx->opcode));
955 gen_op_andi_T0(UIMM(ctx->opcode));
956 gen_op_store_T0_gpr(rA(ctx->opcode));
957 gen_set_Rc0(ctx);
959 /* andis. */
960 GEN_HANDLER(andis_, 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
962 gen_op_load_gpr_T0(rS(ctx->opcode));
963 gen_op_andi_T0(UIMM(ctx->opcode) << 16);
964 gen_op_store_T0_gpr(rA(ctx->opcode));
965 gen_set_Rc0(ctx);
968 /* cntlzw */
969 GEN_LOGICAL1(cntlzw, 0x00, PPC_INTEGER);
970 /* eqv & eqv. */
971 GEN_LOGICAL2(eqv, 0x08, PPC_INTEGER);
972 /* extsb & extsb. */
973 GEN_LOGICAL1(extsb, 0x1D, PPC_INTEGER);
974 /* extsh & extsh. */
975 GEN_LOGICAL1(extsh, 0x1C, PPC_INTEGER);
976 /* nand & nand. */
977 GEN_LOGICAL2(nand, 0x0E, PPC_INTEGER);
978 /* nor & nor. */
979 GEN_LOGICAL2(nor, 0x03, PPC_INTEGER);
981 /* or & or. */
982 GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER)
984 int rs, ra, rb;
986 rs = rS(ctx->opcode);
987 ra = rA(ctx->opcode);
988 rb = rB(ctx->opcode);
989 /* Optimisation for mr. ri case */
990 if (rs != ra || rs != rb) {
991 gen_op_load_gpr_T0(rs);
992 if (rs != rb) {
993 gen_op_load_gpr_T1(rb);
994 gen_op_or();
996 gen_op_store_T0_gpr(ra);
997 if (unlikely(Rc(ctx->opcode) != 0))
998 gen_set_Rc0(ctx);
999 } else if (unlikely(Rc(ctx->opcode) != 0)) {
1000 gen_op_load_gpr_T0(rs);
1001 gen_set_Rc0(ctx);
1005 /* orc & orc. */
1006 GEN_LOGICAL2(orc, 0x0C, PPC_INTEGER);
1007 /* xor & xor. */
1008 GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER)
1010 gen_op_load_gpr_T0(rS(ctx->opcode));
1011 /* Optimisation for "set to zero" case */
1012 if (rS(ctx->opcode) != rB(ctx->opcode)) {
1013 gen_op_load_gpr_T1(rB(ctx->opcode));
1014 gen_op_xor();
1015 } else {
1016 gen_op_reset_T0();
1018 gen_op_store_T0_gpr(rA(ctx->opcode));
1019 if (unlikely(Rc(ctx->opcode) != 0))
1020 gen_set_Rc0(ctx);
1022 /* ori */
1023 GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1025 target_ulong uimm = UIMM(ctx->opcode);
1027 if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1028 /* NOP */
1029 /* XXX: should handle special NOPs for POWER series */
1030 return;
1032 gen_op_load_gpr_T0(rS(ctx->opcode));
1033 if (likely(uimm != 0))
1034 gen_op_ori(uimm);
1035 gen_op_store_T0_gpr(rA(ctx->opcode));
1037 /* oris */
1038 GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1040 target_ulong uimm = UIMM(ctx->opcode);
1042 if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1043 /* NOP */
1044 return;
1046 gen_op_load_gpr_T0(rS(ctx->opcode));
1047 if (likely(uimm != 0))
1048 gen_op_ori(uimm << 16);
1049 gen_op_store_T0_gpr(rA(ctx->opcode));
1051 /* xori */
1052 GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1054 target_ulong uimm = UIMM(ctx->opcode);
1056 if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1057 /* NOP */
1058 return;
1060 gen_op_load_gpr_T0(rS(ctx->opcode));
1061 if (likely(uimm != 0))
1062 gen_op_xori(uimm);
1063 gen_op_store_T0_gpr(rA(ctx->opcode));
1066 /* xoris */
1067 GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1069 target_ulong uimm = UIMM(ctx->opcode);
1071 if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1072 /* NOP */
1073 return;
1075 gen_op_load_gpr_T0(rS(ctx->opcode));
1076 if (likely(uimm != 0))
1077 gen_op_xori(uimm << 16);
1078 gen_op_store_T0_gpr(rA(ctx->opcode));
1081 /* popcntb : PowerPC 2.03 specification */
1082 GEN_HANDLER(popcntb, 0x1F, 0x03, 0x03, 0x0000F801, PPC_203)
1084 gen_op_load_gpr_T0(rS(ctx->opcode));
1085 #if defined(TARGET_PPC64)
1086 if (ctx->sf_mode)
1087 gen_op_popcntb_64();
1088 else
1089 #endif
1090 gen_op_popcntb();
1091 gen_op_store_T0_gpr(rA(ctx->opcode));
1094 #if defined(TARGET_PPC64)
1095 /* extsw & extsw. */
1096 GEN_LOGICAL1(extsw, 0x1E, PPC_64B);
1097 /* cntlzd */
1098 GEN_LOGICAL1(cntlzd, 0x01, PPC_64B);
1099 #endif
1101 /*** Integer rotate ***/
1102 /* rlwimi & rlwimi. */
1103 GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1105 target_ulong mask;
1106 uint32_t mb, me, sh;
1107 int n;
1109 mb = MB(ctx->opcode);
1110 me = ME(ctx->opcode);
1111 sh = SH(ctx->opcode);
1112 n = me + 1 - mb;
1113 if (likely(sh == 0)) {
1114 if (likely(mb == 0 && me == 31)) {
1115 gen_op_load_gpr_T0(rS(ctx->opcode));
1116 goto do_store;
1117 } else if (likely(mb == 31 && me == 0)) {
1118 gen_op_load_gpr_T0(rA(ctx->opcode));
1119 goto do_store;
1121 gen_op_load_gpr_T0(rS(ctx->opcode));
1122 gen_op_load_gpr_T1(rA(ctx->opcode));
1123 goto do_mask;
1125 gen_op_load_gpr_T0(rS(ctx->opcode));
1126 gen_op_load_gpr_T1(rA(ctx->opcode));
1127 gen_op_rotli32_T0(SH(ctx->opcode));
1128 do_mask:
1129 #if defined(TARGET_PPC64)
1130 mb += 32;
1131 me += 32;
1132 #endif
1133 mask = MASK(mb, me);
1134 gen_op_andi_T0(mask);
1135 gen_op_andi_T1(~mask);
1136 gen_op_or();
1137 do_store:
1138 gen_op_store_T0_gpr(rA(ctx->opcode));
1139 if (unlikely(Rc(ctx->opcode) != 0))
1140 gen_set_Rc0(ctx);
1142 /* rlwinm & rlwinm. */
1143 GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1145 uint32_t mb, me, sh;
1147 sh = SH(ctx->opcode);
1148 mb = MB(ctx->opcode);
1149 me = ME(ctx->opcode);
1150 gen_op_load_gpr_T0(rS(ctx->opcode));
1151 if (likely(sh == 0)) {
1152 goto do_mask;
1154 if (likely(mb == 0)) {
1155 if (likely(me == 31)) {
1156 gen_op_rotli32_T0(sh);
1157 goto do_store;
1158 } else if (likely(me == (31 - sh))) {
1159 gen_op_sli_T0(sh);
1160 goto do_store;
1162 } else if (likely(me == 31)) {
1163 if (likely(sh == (32 - mb))) {
1164 gen_op_srli_T0(mb);
1165 goto do_store;
1168 gen_op_rotli32_T0(sh);
1169 do_mask:
1170 #if defined(TARGET_PPC64)
1171 mb += 32;
1172 me += 32;
1173 #endif
1174 gen_op_andi_T0(MASK(mb, me));
1175 do_store:
1176 gen_op_store_T0_gpr(rA(ctx->opcode));
1177 if (unlikely(Rc(ctx->opcode) != 0))
1178 gen_set_Rc0(ctx);
1180 /* rlwnm & rlwnm. */
1181 GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1183 uint32_t mb, me;
1185 mb = MB(ctx->opcode);
1186 me = ME(ctx->opcode);
1187 gen_op_load_gpr_T0(rS(ctx->opcode));
1188 gen_op_load_gpr_T1(rB(ctx->opcode));
1189 gen_op_rotl32_T0_T1();
1190 if (unlikely(mb != 0 || me != 31)) {
1191 #if defined(TARGET_PPC64)
1192 mb += 32;
1193 me += 32;
1194 #endif
1195 gen_op_andi_T0(MASK(mb, me));
1197 gen_op_store_T0_gpr(rA(ctx->opcode));
1198 if (unlikely(Rc(ctx->opcode) != 0))
1199 gen_set_Rc0(ctx);
1202 #if defined(TARGET_PPC64)
1203 #define GEN_PPC64_R2(name, opc1, opc2) \
1204 GEN_HANDLER(name##0, opc1, opc2, 0xFF, 0x00000000, PPC_64B) \
1206 gen_##name(ctx, 0); \
1208 GEN_HANDLER(name##1, opc1, opc2 | 0x10, 0xFF, 0x00000000, PPC_64B) \
1210 gen_##name(ctx, 1); \
1212 #define GEN_PPC64_R4(name, opc1, opc2) \
1213 GEN_HANDLER(name##0, opc1, opc2, 0xFF, 0x00000000, PPC_64B) \
1215 gen_##name(ctx, 0, 0); \
1217 GEN_HANDLER(name##1, opc1, opc2 | 0x01, 0xFF, 0x00000000, PPC_64B) \
1219 gen_##name(ctx, 0, 1); \
1221 GEN_HANDLER(name##2, opc1, opc2 | 0x10, 0xFF, 0x00000000, PPC_64B) \
1223 gen_##name(ctx, 1, 0); \
1225 GEN_HANDLER(name##3, opc1, opc2 | 0x11, 0xFF, 0x00000000, PPC_64B) \
1227 gen_##name(ctx, 1, 1); \
1229 /* rldicl - rldicl. */
1230 static inline void gen_rldicl (DisasContext *ctx, int mbn, int shn)
1232 int sh, mb;
1234 sh = SH(ctx->opcode) | (1 << shn);
1235 mb = (MB(ctx->opcode) << 1) | mbn;
1236 /* XXX: TODO */
1237 RET_INVAL(ctx);
1239 GEN_PPC64_R4(rldicl, 0x1E, 0x00)
1240 /* rldicr - rldicr. */
1241 static inline void gen_rldicr (DisasContext *ctx, int men, int shn)
1243 int sh, me;
1245 sh = SH(ctx->opcode) | (1 << shn);
1246 me = (MB(ctx->opcode) << 1) | men;
1247 /* XXX: TODO */
1248 RET_INVAL(ctx);
1250 GEN_PPC64_R4(rldicr, 0x1E, 0x02)
1251 /* rldic - rldic. */
1252 static inline void gen_rldic (DisasContext *ctx, int mbn, int shn)
1254 int sh, mb;
1256 sh = SH(ctx->opcode) | (1 << shn);
1257 mb = (MB(ctx->opcode) << 1) | mbn;
1258 /* XXX: TODO */
1259 RET_INVAL(ctx);
1261 GEN_PPC64_R4(rldic, 0x1E, 0x04)
1262 /* rldcl - rldcl. */
1263 static inline void gen_rldcl (DisasContext *ctx, int mbn)
1265 int mb;
1267 mb = (MB(ctx->opcode) << 1) | mbn;
1268 /* XXX: TODO */
1269 RET_INVAL(ctx);
1271 GEN_PPC64_R2(rldcl, 0x1E, 0x08)
1272 /* rldcr - rldcr. */
1273 static inline void gen_rldcr (DisasContext *ctx, int men)
1275 int me;
1277 me = (MB(ctx->opcode) << 1) | men;
1278 /* XXX: TODO */
1279 RET_INVAL(ctx);
1281 GEN_PPC64_R2(rldcr, 0x1E, 0x09)
1282 /* rldimi - rldimi. */
1283 static inline void gen_rldimi (DisasContext *ctx, int mbn, int shn)
1285 int sh, mb;
1287 sh = SH(ctx->opcode) | (1 << shn);
1288 mb = (MB(ctx->opcode) << 1) | mbn;
1289 /* XXX: TODO */
1290 RET_INVAL(ctx);
1292 GEN_PPC64_R4(rldimi, 0x1E, 0x06)
1293 #endif
1295 /*** Integer shift ***/
1296 /* slw & slw. */
1297 __GEN_LOGICAL2(slw, 0x18, 0x00, PPC_INTEGER);
1298 /* sraw & sraw. */
1299 __GEN_LOGICAL2(sraw, 0x18, 0x18, PPC_INTEGER);
1300 /* srawi & srawi. */
1301 GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER)
1303 int mb, me;
1304 gen_op_load_gpr_T0(rS(ctx->opcode));
1305 if (SH(ctx->opcode) != 0) {
1306 gen_op_move_T1_T0();
1307 mb = 32 - SH(ctx->opcode);
1308 me = 31;
1309 #if defined(TARGET_PPC64)
1310 mb += 32;
1311 me += 32;
1312 #endif
1313 gen_op_srawi(SH(ctx->opcode), MASK(mb, me));
1315 gen_op_store_T0_gpr(rA(ctx->opcode));
1316 if (unlikely(Rc(ctx->opcode) != 0))
1317 gen_set_Rc0(ctx);
1319 /* srw & srw. */
1320 __GEN_LOGICAL2(srw, 0x18, 0x10, PPC_INTEGER);
1322 #if defined(TARGET_PPC64)
1323 /* sld & sld. */
1324 __GEN_LOGICAL2(sld, 0x1B, 0x00, PPC_64B);
1325 /* srad & srad. */
1326 __GEN_LOGICAL2(srad, 0x1A, 0x18, PPC_64B);
1327 /* sradi & sradi. */
1328 static inline void gen_sradi (DisasContext *ctx, int n)
1330 uint64_t mask;
1331 int sh, mb, me;
1333 gen_op_load_gpr_T0(rS(ctx->opcode));
1334 sh = SH(ctx->opcode) + (n << 5);
1335 if (sh != 0) {
1336 gen_op_move_T1_T0();
1337 mb = 64 - SH(ctx->opcode);
1338 me = 63;
1339 mask = MASK(mb, me);
1340 gen_op_sradi(sh, mask >> 32, mask);
1342 gen_op_store_T0_gpr(rA(ctx->opcode));
1343 if (unlikely(Rc(ctx->opcode) != 0))
1344 gen_set_Rc0(ctx);
1346 GEN_HANDLER(sradi0, 0x1F, 0x1A, 0x19, 0x00000000, PPC_64B)
1348 gen_sradi(ctx, 0);
1350 GEN_HANDLER(sradi1, 0x1F, 0x1B, 0x19, 0x00000000, PPC_64B)
1352 gen_sradi(ctx, 1);
1354 /* srd & srd. */
1355 __GEN_LOGICAL2(srd, 0x1B, 0x10, PPC_64B);
1356 #endif
1358 /*** Floating-Point arithmetic ***/
1359 #define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat) \
1360 GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, PPC_FLOAT) \
1362 if (unlikely(!ctx->fpu_enabled)) { \
1363 RET_EXCP(ctx, EXCP_NO_FP, 0); \
1364 return; \
1366 gen_op_reset_scrfx(); \
1367 gen_op_load_fpr_FT0(rA(ctx->opcode)); \
1368 gen_op_load_fpr_FT1(rC(ctx->opcode)); \
1369 gen_op_load_fpr_FT2(rB(ctx->opcode)); \
1370 gen_op_f##op(); \
1371 if (isfloat) { \
1372 gen_op_frsp(); \
1374 gen_op_store_FT0_fpr(rD(ctx->opcode)); \
1375 if (unlikely(Rc(ctx->opcode) != 0)) \
1376 gen_op_set_Rc1(); \
1379 #define GEN_FLOAT_ACB(name, op2) \
1380 _GEN_FLOAT_ACB(name, name, 0x3F, op2, 0); \
1381 _GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1);
1383 #define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat) \
1384 GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT) \
1386 if (unlikely(!ctx->fpu_enabled)) { \
1387 RET_EXCP(ctx, EXCP_NO_FP, 0); \
1388 return; \
1390 gen_op_reset_scrfx(); \
1391 gen_op_load_fpr_FT0(rA(ctx->opcode)); \
1392 gen_op_load_fpr_FT1(rB(ctx->opcode)); \
1393 gen_op_f##op(); \
1394 if (isfloat) { \
1395 gen_op_frsp(); \
1397 gen_op_store_FT0_fpr(rD(ctx->opcode)); \
1398 if (unlikely(Rc(ctx->opcode) != 0)) \
1399 gen_op_set_Rc1(); \
1401 #define GEN_FLOAT_AB(name, op2, inval) \
1402 _GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0); \
1403 _GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1);
1405 #define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat) \
1406 GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT) \
1408 if (unlikely(!ctx->fpu_enabled)) { \
1409 RET_EXCP(ctx, EXCP_NO_FP, 0); \
1410 return; \
1412 gen_op_reset_scrfx(); \
1413 gen_op_load_fpr_FT0(rA(ctx->opcode)); \
1414 gen_op_load_fpr_FT1(rC(ctx->opcode)); \
1415 gen_op_f##op(); \
1416 if (isfloat) { \
1417 gen_op_frsp(); \
1419 gen_op_store_FT0_fpr(rD(ctx->opcode)); \
1420 if (unlikely(Rc(ctx->opcode) != 0)) \
1421 gen_op_set_Rc1(); \
1423 #define GEN_FLOAT_AC(name, op2, inval) \
1424 _GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0); \
1425 _GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1);
1427 #define GEN_FLOAT_B(name, op2, op3) \
1428 GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, PPC_FLOAT) \
1430 if (unlikely(!ctx->fpu_enabled)) { \
1431 RET_EXCP(ctx, EXCP_NO_FP, 0); \
1432 return; \
1434 gen_op_reset_scrfx(); \
1435 gen_op_load_fpr_FT0(rB(ctx->opcode)); \
1436 gen_op_f##name(); \
1437 gen_op_store_FT0_fpr(rD(ctx->opcode)); \
1438 if (unlikely(Rc(ctx->opcode) != 0)) \
1439 gen_op_set_Rc1(); \
1442 #define GEN_FLOAT_BS(name, op1, op2) \
1443 GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, PPC_FLOAT) \
1445 if (unlikely(!ctx->fpu_enabled)) { \
1446 RET_EXCP(ctx, EXCP_NO_FP, 0); \
1447 return; \
1449 gen_op_reset_scrfx(); \
1450 gen_op_load_fpr_FT0(rB(ctx->opcode)); \
1451 gen_op_f##name(); \
1452 gen_op_store_FT0_fpr(rD(ctx->opcode)); \
1453 if (unlikely(Rc(ctx->opcode) != 0)) \
1454 gen_op_set_Rc1(); \
1457 /* fadd - fadds */
1458 GEN_FLOAT_AB(add, 0x15, 0x000007C0);
1459 /* fdiv - fdivs */
1460 GEN_FLOAT_AB(div, 0x12, 0x000007C0);
1461 /* fmul - fmuls */
1462 GEN_FLOAT_AC(mul, 0x19, 0x0000F800);
1464 /* fres */ /* XXX: not in 601 */
1465 GEN_FLOAT_BS(res, 0x3B, 0x18);
1467 /* frsqrte */ /* XXX: not in 601 */
1468 GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A);
1470 /* fsel */ /* XXX: not in 601 */
1471 _GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0);
1472 /* fsub - fsubs */
1473 GEN_FLOAT_AB(sub, 0x14, 0x000007C0);
1474 /* Optional: */
1475 /* fsqrt */
1476 GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_OPT)
1478 if (unlikely(!ctx->fpu_enabled)) {
1479 RET_EXCP(ctx, EXCP_NO_FP, 0);
1480 return;
1482 gen_op_reset_scrfx();
1483 gen_op_load_fpr_FT0(rB(ctx->opcode));
1484 gen_op_fsqrt();
1485 gen_op_store_FT0_fpr(rD(ctx->opcode));
1486 if (unlikely(Rc(ctx->opcode) != 0))
1487 gen_op_set_Rc1();
1490 GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_OPT)
1492 if (unlikely(!ctx->fpu_enabled)) {
1493 RET_EXCP(ctx, EXCP_NO_FP, 0);
1494 return;
1496 gen_op_reset_scrfx();
1497 gen_op_load_fpr_FT0(rB(ctx->opcode));
1498 gen_op_fsqrt();
1499 gen_op_frsp();
1500 gen_op_store_FT0_fpr(rD(ctx->opcode));
1501 if (unlikely(Rc(ctx->opcode) != 0))
1502 gen_op_set_Rc1();
1505 /*** Floating-Point multiply-and-add ***/
1506 /* fmadd - fmadds */
1507 GEN_FLOAT_ACB(madd, 0x1D);
1508 /* fmsub - fmsubs */
1509 GEN_FLOAT_ACB(msub, 0x1C);
1510 /* fnmadd - fnmadds */
1511 GEN_FLOAT_ACB(nmadd, 0x1F);
1512 /* fnmsub - fnmsubs */
1513 GEN_FLOAT_ACB(nmsub, 0x1E);
1515 /*** Floating-Point round & convert ***/
1516 /* fctiw */
1517 GEN_FLOAT_B(ctiw, 0x0E, 0x00);
1518 /* fctiwz */
1519 GEN_FLOAT_B(ctiwz, 0x0F, 0x00);
1520 /* frsp */
1521 GEN_FLOAT_B(rsp, 0x0C, 0x00);
1523 /*** Floating-Point compare ***/
1524 /* fcmpo */
1525 GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT)
1527 if (unlikely(!ctx->fpu_enabled)) {
1528 RET_EXCP(ctx, EXCP_NO_FP, 0);
1529 return;
1531 gen_op_reset_scrfx();
1532 gen_op_load_fpr_FT0(rA(ctx->opcode));
1533 gen_op_load_fpr_FT1(rB(ctx->opcode));
1534 gen_op_fcmpo();
1535 gen_op_store_T0_crf(crfD(ctx->opcode));
1538 /* fcmpu */
1539 GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT)
1541 if (unlikely(!ctx->fpu_enabled)) {
1542 RET_EXCP(ctx, EXCP_NO_FP, 0);
1543 return;
1545 gen_op_reset_scrfx();
1546 gen_op_load_fpr_FT0(rA(ctx->opcode));
1547 gen_op_load_fpr_FT1(rB(ctx->opcode));
1548 gen_op_fcmpu();
1549 gen_op_store_T0_crf(crfD(ctx->opcode));
1552 /*** Floating-point move ***/
1553 /* fabs */
1554 GEN_FLOAT_B(abs, 0x08, 0x08);
1556 /* fmr - fmr. */
1557 GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT)
1559 if (unlikely(!ctx->fpu_enabled)) {
1560 RET_EXCP(ctx, EXCP_NO_FP, 0);
1561 return;
1563 gen_op_reset_scrfx();
1564 gen_op_load_fpr_FT0(rB(ctx->opcode));
1565 gen_op_store_FT0_fpr(rD(ctx->opcode));
1566 if (unlikely(Rc(ctx->opcode) != 0))
1567 gen_op_set_Rc1();
1570 /* fnabs */
1571 GEN_FLOAT_B(nabs, 0x08, 0x04);
1572 /* fneg */
1573 GEN_FLOAT_B(neg, 0x08, 0x01);
1575 /*** Floating-Point status & ctrl register ***/
1576 /* mcrfs */
1577 GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT)
1579 if (unlikely(!ctx->fpu_enabled)) {
1580 RET_EXCP(ctx, EXCP_NO_FP, 0);
1581 return;
1583 gen_op_load_fpscr_T0(crfS(ctx->opcode));
1584 gen_op_store_T0_crf(crfD(ctx->opcode));
1585 gen_op_clear_fpscr(crfS(ctx->opcode));
1588 /* mffs */
1589 GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT)
1591 if (unlikely(!ctx->fpu_enabled)) {
1592 RET_EXCP(ctx, EXCP_NO_FP, 0);
1593 return;
1595 gen_op_load_fpscr();
1596 gen_op_store_FT0_fpr(rD(ctx->opcode));
1597 if (unlikely(Rc(ctx->opcode) != 0))
1598 gen_op_set_Rc1();
1601 /* mtfsb0 */
1602 GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT)
1604 uint8_t crb;
1606 if (unlikely(!ctx->fpu_enabled)) {
1607 RET_EXCP(ctx, EXCP_NO_FP, 0);
1608 return;
1610 crb = crbD(ctx->opcode) >> 2;
1611 gen_op_load_fpscr_T0(crb);
1612 gen_op_andi_T0(~(1 << (crbD(ctx->opcode) & 0x03)));
1613 gen_op_store_T0_fpscr(crb);
1614 if (unlikely(Rc(ctx->opcode) != 0))
1615 gen_op_set_Rc1();
1618 /* mtfsb1 */
1619 GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT)
1621 uint8_t crb;
1623 if (unlikely(!ctx->fpu_enabled)) {
1624 RET_EXCP(ctx, EXCP_NO_FP, 0);
1625 return;
1627 crb = crbD(ctx->opcode) >> 2;
1628 gen_op_load_fpscr_T0(crb);
1629 gen_op_ori(1 << (crbD(ctx->opcode) & 0x03));
1630 gen_op_store_T0_fpscr(crb);
1631 if (unlikely(Rc(ctx->opcode) != 0))
1632 gen_op_set_Rc1();
1635 /* mtfsf */
1636 GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT)
1638 if (unlikely(!ctx->fpu_enabled)) {
1639 RET_EXCP(ctx, EXCP_NO_FP, 0);
1640 return;
1642 gen_op_load_fpr_FT0(rB(ctx->opcode));
1643 gen_op_store_fpscr(FM(ctx->opcode));
1644 if (unlikely(Rc(ctx->opcode) != 0))
1645 gen_op_set_Rc1();
1648 /* mtfsfi */
1649 GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT)
1651 if (unlikely(!ctx->fpu_enabled)) {
1652 RET_EXCP(ctx, EXCP_NO_FP, 0);
1653 return;
1655 gen_op_store_T0_fpscri(crbD(ctx->opcode) >> 2, FPIMM(ctx->opcode));
1656 if (unlikely(Rc(ctx->opcode) != 0))
1657 gen_op_set_Rc1();
1660 /*** Addressing modes ***/
1661 /* Register indirect with immediate index : EA = (rA|0) + SIMM */
1662 static inline void gen_addr_imm_index (DisasContext *ctx)
1664 target_long simm = SIMM(ctx->opcode);
1666 if (rA(ctx->opcode) == 0) {
1667 gen_set_T0(simm);
1668 } else {
1669 gen_op_load_gpr_T0(rA(ctx->opcode));
1670 if (likely(simm != 0))
1671 gen_op_addi(simm);
1675 static inline void gen_addr_reg_index (DisasContext *ctx)
1677 if (rA(ctx->opcode) == 0) {
1678 gen_op_load_gpr_T0(rB(ctx->opcode));
1679 } else {
1680 gen_op_load_gpr_T0(rA(ctx->opcode));
1681 gen_op_load_gpr_T1(rB(ctx->opcode));
1682 gen_op_add();
1686 static inline void gen_addr_register (DisasContext *ctx)
1688 if (rA(ctx->opcode) == 0) {
1689 gen_op_reset_T0();
1690 } else {
1691 gen_op_load_gpr_T0(rA(ctx->opcode));
1695 /*** Integer load ***/
1696 #define op_ldst(name) (*gen_op_##name[ctx->mem_idx])()
1697 #if defined(CONFIG_USER_ONLY)
1698 #if defined(TARGET_PPC64)
1699 #define OP_LD_TABLE(width) \
1700 static GenOpFunc *gen_op_l##width[] = { \
1701 &gen_op_l##width##_raw, \
1702 &gen_op_l##width##_le_raw, \
1703 &gen_op_l##width##_64_raw, \
1704 &gen_op_l##width##_le_64_raw, \
1706 #define OP_ST_TABLE(width) \
1707 static GenOpFunc *gen_op_st##width[] = { \
1708 &gen_op_st##width##_raw, \
1709 &gen_op_st##width##_le_raw, \
1710 &gen_op_st##width##_64_raw, \
1711 &gen_op_st##width##_le_64_raw, \
1713 /* Byte access routine are endian safe */
1714 #define gen_op_stb_le_64_raw gen_op_stb_64_raw
1715 #define gen_op_lbz_le_64_raw gen_op_lbz_64_raw
1716 #else
1717 #define OP_LD_TABLE(width) \
1718 static GenOpFunc *gen_op_l##width[] = { \
1719 &gen_op_l##width##_raw, \
1720 &gen_op_l##width##_le_raw, \
1722 #define OP_ST_TABLE(width) \
1723 static GenOpFunc *gen_op_st##width[] = { \
1724 &gen_op_st##width##_raw, \
1725 &gen_op_st##width##_le_raw, \
1727 #endif
1728 /* Byte access routine are endian safe */
1729 #define gen_op_stb_le_raw gen_op_stb_raw
1730 #define gen_op_lbz_le_raw gen_op_lbz_raw
1731 #else
1732 #if defined(TARGET_PPC64)
1733 #define OP_LD_TABLE(width) \
1734 static GenOpFunc *gen_op_l##width[] = { \
1735 &gen_op_l##width##_user, \
1736 &gen_op_l##width##_le_user, \
1737 &gen_op_l##width##_kernel, \
1738 &gen_op_l##width##_le_kernel, \
1739 &gen_op_l##width##_64_user, \
1740 &gen_op_l##width##_le_64_user, \
1741 &gen_op_l##width##_64_kernel, \
1742 &gen_op_l##width##_le_64_kernel, \
1744 #define OP_ST_TABLE(width) \
1745 static GenOpFunc *gen_op_st##width[] = { \
1746 &gen_op_st##width##_user, \
1747 &gen_op_st##width##_le_user, \
1748 &gen_op_st##width##_kernel, \
1749 &gen_op_st##width##_le_kernel, \
1750 &gen_op_st##width##_64_user, \
1751 &gen_op_st##width##_le_64_user, \
1752 &gen_op_st##width##_64_kernel, \
1753 &gen_op_st##width##_le_64_kernel, \
1755 /* Byte access routine are endian safe */
1756 #define gen_op_stb_le_64_user gen_op_stb_64_user
1757 #define gen_op_lbz_le_64_user gen_op_lbz_64_user
1758 #define gen_op_stb_le_64_kernel gen_op_stb_64_kernel
1759 #define gen_op_lbz_le_64_kernel gen_op_lbz_64_kernel
1760 #else
1761 #define OP_LD_TABLE(width) \
1762 static GenOpFunc *gen_op_l##width[] = { \
1763 &gen_op_l##width##_user, \
1764 &gen_op_l##width##_le_user, \
1765 &gen_op_l##width##_kernel, \
1766 &gen_op_l##width##_le_kernel, \
1768 #define OP_ST_TABLE(width) \
1769 static GenOpFunc *gen_op_st##width[] = { \
1770 &gen_op_st##width##_user, \
1771 &gen_op_st##width##_le_user, \
1772 &gen_op_st##width##_kernel, \
1773 &gen_op_st##width##_le_kernel, \
1775 #endif
1776 /* Byte access routine are endian safe */
1777 #define gen_op_stb_le_user gen_op_stb_user
1778 #define gen_op_lbz_le_user gen_op_lbz_user
1779 #define gen_op_stb_le_kernel gen_op_stb_kernel
1780 #define gen_op_lbz_le_kernel gen_op_lbz_kernel
1781 #endif
1783 #define GEN_LD(width, opc, type) \
1784 GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, type) \
1786 gen_addr_imm_index(ctx); \
1787 op_ldst(l##width); \
1788 gen_op_store_T1_gpr(rD(ctx->opcode)); \
1791 #define GEN_LDU(width, opc, type) \
1792 GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, type) \
1794 if (unlikely(rA(ctx->opcode) == 0 || \
1795 rA(ctx->opcode) == rD(ctx->opcode))) { \
1796 RET_INVAL(ctx); \
1797 return; \
1799 gen_addr_imm_index(ctx); \
1800 op_ldst(l##width); \
1801 gen_op_store_T1_gpr(rD(ctx->opcode)); \
1802 gen_op_store_T0_gpr(rA(ctx->opcode)); \
1805 #define GEN_LDUX(width, opc2, opc3, type) \
1806 GEN_HANDLER(l##width##ux, 0x1F, opc2, opc3, 0x00000001, type) \
1808 if (unlikely(rA(ctx->opcode) == 0 || \
1809 rA(ctx->opcode) == rD(ctx->opcode))) { \
1810 RET_INVAL(ctx); \
1811 return; \
1813 gen_addr_reg_index(ctx); \
1814 op_ldst(l##width); \
1815 gen_op_store_T1_gpr(rD(ctx->opcode)); \
1816 gen_op_store_T0_gpr(rA(ctx->opcode)); \
1819 #define GEN_LDX(width, opc2, opc3, type) \
1820 GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, type) \
1822 gen_addr_reg_index(ctx); \
1823 op_ldst(l##width); \
1824 gen_op_store_T1_gpr(rD(ctx->opcode)); \
1827 #define GEN_LDS(width, op, type) \
1828 OP_LD_TABLE(width); \
1829 GEN_LD(width, op | 0x20, type); \
1830 GEN_LDU(width, op | 0x21, type); \
1831 GEN_LDUX(width, 0x17, op | 0x01, type); \
1832 GEN_LDX(width, 0x17, op | 0x00, type)
1834 /* lbz lbzu lbzux lbzx */
1835 GEN_LDS(bz, 0x02, PPC_INTEGER);
1836 /* lha lhau lhaux lhax */
1837 GEN_LDS(ha, 0x0A, PPC_INTEGER);
1838 /* lhz lhzu lhzux lhzx */
1839 GEN_LDS(hz, 0x08, PPC_INTEGER);
1840 /* lwz lwzu lwzux lwzx */
1841 GEN_LDS(wz, 0x00, PPC_INTEGER);
1842 #if defined(TARGET_PPC64)
1843 OP_LD_TABLE(wa);
1844 OP_LD_TABLE(d);
1845 /* lwaux */
1846 GEN_LDUX(wa, 0x15, 0x0B, PPC_64B);
1847 /* lwax */
1848 GEN_LDX(wa, 0x15, 0x0A, PPC_64B);
1849 /* ldux */
1850 GEN_LDUX(d, 0x15, 0x01, PPC_64B);
1851 /* ldx */
1852 GEN_LDX(d, 0x15, 0x00, PPC_64B);
1853 GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B)
1855 if (Rc(ctx->opcode)) {
1856 if (unlikely(rA(ctx->opcode) == 0 ||
1857 rA(ctx->opcode) == rD(ctx->opcode))) {
1858 RET_INVAL(ctx);
1859 return;
1862 gen_addr_imm_index(ctx);
1863 if (ctx->opcode & 0x02) {
1864 /* lwa (lwau is undefined) */
1865 op_ldst(lwa);
1866 } else {
1867 /* ld - ldu */
1868 op_ldst(ld);
1870 gen_op_store_T1_gpr(rD(ctx->opcode));
1871 if (Rc(ctx->opcode))
1872 gen_op_store_T0_gpr(rA(ctx->opcode));
1874 #endif
1876 /*** Integer store ***/
1877 #define GEN_ST(width, opc, type) \
1878 GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, type) \
1880 gen_addr_imm_index(ctx); \
1881 gen_op_load_gpr_T1(rS(ctx->opcode)); \
1882 op_ldst(st##width); \
1885 #define GEN_STU(width, opc, type) \
1886 GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, type) \
1888 if (unlikely(rA(ctx->opcode) == 0)) { \
1889 RET_INVAL(ctx); \
1890 return; \
1892 gen_addr_imm_index(ctx); \
1893 gen_op_load_gpr_T1(rS(ctx->opcode)); \
1894 op_ldst(st##width); \
1895 gen_op_store_T0_gpr(rA(ctx->opcode)); \
1898 #define GEN_STUX(width, opc2, opc3, type) \
1899 GEN_HANDLER(st##width##ux, 0x1F, opc2, opc3, 0x00000001, type) \
1901 if (unlikely(rA(ctx->opcode) == 0)) { \
1902 RET_INVAL(ctx); \
1903 return; \
1905 gen_addr_reg_index(ctx); \
1906 gen_op_load_gpr_T1(rS(ctx->opcode)); \
1907 op_ldst(st##width); \
1908 gen_op_store_T0_gpr(rA(ctx->opcode)); \
1911 #define GEN_STX(width, opc2, opc3, type) \
1912 GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, type) \
1914 gen_addr_reg_index(ctx); \
1915 gen_op_load_gpr_T1(rS(ctx->opcode)); \
1916 op_ldst(st##width); \
1919 #define GEN_STS(width, op, type) \
1920 OP_ST_TABLE(width); \
1921 GEN_ST(width, op | 0x20, type); \
1922 GEN_STU(width, op | 0x21, type); \
1923 GEN_STUX(width, 0x17, op | 0x01, type); \
1924 GEN_STX(width, 0x17, op | 0x00, type)
1926 /* stb stbu stbux stbx */
1927 GEN_STS(b, 0x06, PPC_INTEGER);
1928 /* sth sthu sthux sthx */
1929 GEN_STS(h, 0x0C, PPC_INTEGER);
1930 /* stw stwu stwux stwx */
1931 GEN_STS(w, 0x04, PPC_INTEGER);
1932 #if defined(TARGET_PPC64)
1933 OP_ST_TABLE(d);
1934 GEN_STUX(d, 0x15, 0x01, PPC_64B);
1935 GEN_STX(d, 0x15, 0x00, PPC_64B);
1936 GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000002, PPC_64B)
1938 if (Rc(ctx->opcode)) {
1939 if (unlikely(rA(ctx->opcode) == 0)) {
1940 RET_INVAL(ctx);
1941 return;
1944 gen_addr_imm_index(ctx);
1945 gen_op_load_gpr_T1(rS(ctx->opcode));
1946 op_ldst(std);
1947 if (Rc(ctx->opcode))
1948 gen_op_store_T0_gpr(rA(ctx->opcode));
1950 #endif
1951 /*** Integer load and store with byte reverse ***/
1952 /* lhbrx */
1953 OP_LD_TABLE(hbr);
1954 GEN_LDX(hbr, 0x16, 0x18, PPC_INTEGER);
1955 /* lwbrx */
1956 OP_LD_TABLE(wbr);
1957 GEN_LDX(wbr, 0x16, 0x10, PPC_INTEGER);
1958 /* sthbrx */
1959 OP_ST_TABLE(hbr);
1960 GEN_STX(hbr, 0x16, 0x1C, PPC_INTEGER);
1961 /* stwbrx */
1962 OP_ST_TABLE(wbr);
1963 GEN_STX(wbr, 0x16, 0x14, PPC_INTEGER);
1965 /*** Integer load and store multiple ***/
1966 #define op_ldstm(name, reg) (*gen_op_##name[ctx->mem_idx])(reg)
1967 #if defined(TARGET_PPC64)
1968 #if defined(CONFIG_USER_ONLY)
1969 static GenOpFunc1 *gen_op_lmw[] = {
1970 &gen_op_lmw_raw,
1971 &gen_op_lmw_le_raw,
1972 &gen_op_lmw_64_raw,
1973 &gen_op_lmw_le_64_raw,
1975 static GenOpFunc1 *gen_op_stmw[] = {
1976 &gen_op_stmw_64_raw,
1977 &gen_op_stmw_le_64_raw,
1979 #else
1980 static GenOpFunc1 *gen_op_lmw[] = {
1981 &gen_op_lmw_user,
1982 &gen_op_lmw_le_user,
1983 &gen_op_lmw_kernel,
1984 &gen_op_lmw_le_kernel,
1985 &gen_op_lmw_64_user,
1986 &gen_op_lmw_le_64_user,
1987 &gen_op_lmw_64_kernel,
1988 &gen_op_lmw_le_64_kernel,
1990 static GenOpFunc1 *gen_op_stmw[] = {
1991 &gen_op_stmw_user,
1992 &gen_op_stmw_le_user,
1993 &gen_op_stmw_kernel,
1994 &gen_op_stmw_le_kernel,
1995 &gen_op_stmw_64_user,
1996 &gen_op_stmw_le_64_user,
1997 &gen_op_stmw_64_kernel,
1998 &gen_op_stmw_le_64_kernel,
2000 #endif
2001 #else
2002 #if defined(CONFIG_USER_ONLY)
2003 static GenOpFunc1 *gen_op_lmw[] = {
2004 &gen_op_lmw_raw,
2005 &gen_op_lmw_le_raw,
2007 static GenOpFunc1 *gen_op_stmw[] = {
2008 &gen_op_stmw_raw,
2009 &gen_op_stmw_le_raw,
2011 #else
2012 static GenOpFunc1 *gen_op_lmw[] = {
2013 &gen_op_lmw_user,
2014 &gen_op_lmw_le_user,
2015 &gen_op_lmw_kernel,
2016 &gen_op_lmw_le_kernel,
2018 static GenOpFunc1 *gen_op_stmw[] = {
2019 &gen_op_stmw_user,
2020 &gen_op_stmw_le_user,
2021 &gen_op_stmw_kernel,
2022 &gen_op_stmw_le_kernel,
2024 #endif
2025 #endif
2027 /* lmw */
2028 GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
2030 /* NIP cannot be restored if the memory exception comes from an helper */
2031 gen_update_nip(ctx, ctx->nip - 4);
2032 gen_addr_imm_index(ctx);
2033 op_ldstm(lmw, rD(ctx->opcode));
2036 /* stmw */
2037 GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
2039 /* NIP cannot be restored if the memory exception comes from an helper */
2040 gen_update_nip(ctx, ctx->nip - 4);
2041 gen_addr_imm_index(ctx);
2042 op_ldstm(stmw, rS(ctx->opcode));
2045 /*** Integer load and store strings ***/
2046 #define op_ldsts(name, start) (*gen_op_##name[ctx->mem_idx])(start)
2047 #define op_ldstsx(name, rd, ra, rb) (*gen_op_##name[ctx->mem_idx])(rd, ra, rb)
2048 #if defined(TARGET_PPC64)
2049 #if defined(CONFIG_USER_ONLY)
2050 static GenOpFunc1 *gen_op_lswi[] = {
2051 &gen_op_lswi_raw,
2052 &gen_op_lswi_le_raw,
2053 &gen_op_lswi_64_raw,
2054 &gen_op_lswi_le_64_raw,
2056 static GenOpFunc3 *gen_op_lswx[] = {
2057 &gen_op_lswx_raw,
2058 &gen_op_lswx_le_raw,
2059 &gen_op_lswx_64_raw,
2060 &gen_op_lswx_le_64_raw,
2062 static GenOpFunc1 *gen_op_stsw[] = {
2063 &gen_op_stsw_raw,
2064 &gen_op_stsw_le_raw,
2065 &gen_op_stsw_64_raw,
2066 &gen_op_stsw_le_64_raw,
2068 #else
2069 static GenOpFunc1 *gen_op_lswi[] = {
2070 &gen_op_lswi_user,
2071 &gen_op_lswi_le_user,
2072 &gen_op_lswi_kernel,
2073 &gen_op_lswi_le_kernel,
2074 &gen_op_lswi_64_user,
2075 &gen_op_lswi_le_64_user,
2076 &gen_op_lswi_64_kernel,
2077 &gen_op_lswi_le_64_kernel,
2079 static GenOpFunc3 *gen_op_lswx[] = {
2080 &gen_op_lswx_user,
2081 &gen_op_lswx_le_user,
2082 &gen_op_lswx_kernel,
2083 &gen_op_lswx_le_kernel,
2084 &gen_op_lswx_64_user,
2085 &gen_op_lswx_le_64_user,
2086 &gen_op_lswx_64_kernel,
2087 &gen_op_lswx_le_64_kernel,
2089 static GenOpFunc1 *gen_op_stsw[] = {
2090 &gen_op_stsw_user,
2091 &gen_op_stsw_le_user,
2092 &gen_op_stsw_kernel,
2093 &gen_op_stsw_le_kernel,
2094 &gen_op_stsw_64_user,
2095 &gen_op_stsw_le_64_user,
2096 &gen_op_stsw_64_kernel,
2097 &gen_op_stsw_le_64_kernel,
2099 #endif
2100 #else
2101 #if defined(CONFIG_USER_ONLY)
2102 static GenOpFunc1 *gen_op_lswi[] = {
2103 &gen_op_lswi_raw,
2104 &gen_op_lswi_le_raw,
2106 static GenOpFunc3 *gen_op_lswx[] = {
2107 &gen_op_lswx_raw,
2108 &gen_op_lswx_le_raw,
2110 static GenOpFunc1 *gen_op_stsw[] = {
2111 &gen_op_stsw_raw,
2112 &gen_op_stsw_le_raw,
2114 #else
2115 static GenOpFunc1 *gen_op_lswi[] = {
2116 &gen_op_lswi_user,
2117 &gen_op_lswi_le_user,
2118 &gen_op_lswi_kernel,
2119 &gen_op_lswi_le_kernel,
2121 static GenOpFunc3 *gen_op_lswx[] = {
2122 &gen_op_lswx_user,
2123 &gen_op_lswx_le_user,
2124 &gen_op_lswx_kernel,
2125 &gen_op_lswx_le_kernel,
2127 static GenOpFunc1 *gen_op_stsw[] = {
2128 &gen_op_stsw_user,
2129 &gen_op_stsw_le_user,
2130 &gen_op_stsw_kernel,
2131 &gen_op_stsw_le_kernel,
2133 #endif
2134 #endif
2136 /* lswi */
2137 /* PowerPC32 specification says we must generate an exception if
2138 * rA is in the range of registers to be loaded.
2139 * In an other hand, IBM says this is valid, but rA won't be loaded.
2140 * For now, I'll follow the spec...
2142 GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_INTEGER)
2144 int nb = NB(ctx->opcode);
2145 int start = rD(ctx->opcode);
2146 int ra = rA(ctx->opcode);
2147 int nr;
2149 if (nb == 0)
2150 nb = 32;
2151 nr = nb / 4;
2152 if (unlikely(((start + nr) > 32 &&
2153 start <= ra && (start + nr - 32) > ra) ||
2154 ((start + nr) <= 32 && start <= ra && (start + nr) > ra))) {
2155 RET_EXCP(ctx, EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_LSWX);
2156 return;
2158 /* NIP cannot be restored if the memory exception comes from an helper */
2159 gen_update_nip(ctx, ctx->nip - 4);
2160 gen_addr_register(ctx);
2161 gen_op_set_T1(nb);
2162 op_ldsts(lswi, start);
2165 /* lswx */
2166 GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_INTEGER)
2168 int ra = rA(ctx->opcode);
2169 int rb = rB(ctx->opcode);
2171 /* NIP cannot be restored if the memory exception comes from an helper */
2172 gen_update_nip(ctx, ctx->nip - 4);
2173 gen_addr_reg_index(ctx);
2174 if (ra == 0) {
2175 ra = rb;
2177 gen_op_load_xer_bc();
2178 op_ldstsx(lswx, rD(ctx->opcode), ra, rb);
2181 /* stswi */
2182 GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_INTEGER)
2184 int nb = NB(ctx->opcode);
2186 /* NIP cannot be restored if the memory exception comes from an helper */
2187 gen_update_nip(ctx, ctx->nip - 4);
2188 gen_addr_register(ctx);
2189 if (nb == 0)
2190 nb = 32;
2191 gen_op_set_T1(nb);
2192 op_ldsts(stsw, rS(ctx->opcode));
2195 /* stswx */
2196 GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_INTEGER)
2198 /* NIP cannot be restored if the memory exception comes from an helper */
2199 gen_update_nip(ctx, ctx->nip - 4);
2200 gen_addr_reg_index(ctx);
2201 gen_op_load_xer_bc();
2202 op_ldsts(stsw, rS(ctx->opcode));
2205 /*** Memory synchronisation ***/
2206 /* eieio */
2207 GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FF0801, PPC_MEM_EIEIO)
2211 /* isync */
2212 GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FF0801, PPC_MEM)
2216 #define op_lwarx() (*gen_op_lwarx[ctx->mem_idx])()
2217 #define op_stwcx() (*gen_op_stwcx[ctx->mem_idx])()
2218 #if defined(TARGET_PPC64)
2219 #if defined(CONFIG_USER_ONLY)
2220 static GenOpFunc *gen_op_lwarx[] = {
2221 &gen_op_lwarx_raw,
2222 &gen_op_lwarx_le_raw,
2223 &gen_op_lwarx_64_raw,
2224 &gen_op_lwarx_le_64_raw,
2226 static GenOpFunc *gen_op_stwcx[] = {
2227 &gen_op_stwcx_raw,
2228 &gen_op_stwcx_le_raw,
2229 &gen_op_stwcx_64_raw,
2230 &gen_op_stwcx_le_64_raw,
2232 #else
2233 static GenOpFunc *gen_op_lwarx[] = {
2234 &gen_op_lwarx_user,
2235 &gen_op_lwarx_le_user,
2236 &gen_op_lwarx_kernel,
2237 &gen_op_lwarx_le_kernel,
2238 &gen_op_lwarx_64_user,
2239 &gen_op_lwarx_le_64_user,
2240 &gen_op_lwarx_64_kernel,
2241 &gen_op_lwarx_le_64_kernel,
2243 static GenOpFunc *gen_op_stwcx[] = {
2244 &gen_op_stwcx_user,
2245 &gen_op_stwcx_le_user,
2246 &gen_op_stwcx_kernel,
2247 &gen_op_stwcx_le_kernel,
2248 &gen_op_stwcx_64_user,
2249 &gen_op_stwcx_le_64_user,
2250 &gen_op_stwcx_64_kernel,
2251 &gen_op_stwcx_le_64_kernel,
2253 #endif
2254 #else
2255 #if defined(CONFIG_USER_ONLY)
2256 static GenOpFunc *gen_op_lwarx[] = {
2257 &gen_op_lwarx_raw,
2258 &gen_op_lwarx_le_raw,
2260 static GenOpFunc *gen_op_stwcx[] = {
2261 &gen_op_stwcx_raw,
2262 &gen_op_stwcx_le_raw,
2264 #else
2265 static GenOpFunc *gen_op_lwarx[] = {
2266 &gen_op_lwarx_user,
2267 &gen_op_lwarx_le_user,
2268 &gen_op_lwarx_kernel,
2269 &gen_op_lwarx_le_kernel,
2271 static GenOpFunc *gen_op_stwcx[] = {
2272 &gen_op_stwcx_user,
2273 &gen_op_stwcx_le_user,
2274 &gen_op_stwcx_kernel,
2275 &gen_op_stwcx_le_kernel,
2277 #endif
2278 #endif
2280 /* lwarx */
2281 GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000001, PPC_RES)
2283 gen_addr_reg_index(ctx);
2284 op_lwarx();
2285 gen_op_store_T1_gpr(rD(ctx->opcode));
2288 /* stwcx. */
2289 GEN_HANDLER(stwcx_, 0x1F, 0x16, 0x04, 0x00000000, PPC_RES)
2291 gen_addr_reg_index(ctx);
2292 gen_op_load_gpr_T1(rS(ctx->opcode));
2293 op_stwcx();
2296 /* sync */
2297 GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x03FF0801, PPC_MEM_SYNC)
2301 /*** Floating-point load ***/
2302 #define GEN_LDF(width, opc) \
2303 GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
2305 if (unlikely(!ctx->fpu_enabled)) { \
2306 RET_EXCP(ctx, EXCP_NO_FP, 0); \
2307 return; \
2309 gen_addr_imm_index(ctx); \
2310 op_ldst(l##width); \
2311 gen_op_store_FT0_fpr(rD(ctx->opcode)); \
2314 #define GEN_LDUF(width, opc) \
2315 GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
2317 if (unlikely(!ctx->fpu_enabled)) { \
2318 RET_EXCP(ctx, EXCP_NO_FP, 0); \
2319 return; \
2321 if (unlikely(rA(ctx->opcode) == 0)) { \
2322 RET_INVAL(ctx); \
2323 return; \
2325 gen_addr_imm_index(ctx); \
2326 op_ldst(l##width); \
2327 gen_op_store_FT0_fpr(rD(ctx->opcode)); \
2328 gen_op_store_T0_gpr(rA(ctx->opcode)); \
2331 #define GEN_LDUXF(width, opc) \
2332 GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \
2334 if (unlikely(!ctx->fpu_enabled)) { \
2335 RET_EXCP(ctx, EXCP_NO_FP, 0); \
2336 return; \
2338 if (unlikely(rA(ctx->opcode) == 0)) { \
2339 RET_INVAL(ctx); \
2340 return; \
2342 gen_addr_reg_index(ctx); \
2343 op_ldst(l##width); \
2344 gen_op_store_FT0_fpr(rD(ctx->opcode)); \
2345 gen_op_store_T0_gpr(rA(ctx->opcode)); \
2348 #define GEN_LDXF(width, opc2, opc3) \
2349 GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_FLOAT) \
2351 if (unlikely(!ctx->fpu_enabled)) { \
2352 RET_EXCP(ctx, EXCP_NO_FP, 0); \
2353 return; \
2355 gen_addr_reg_index(ctx); \
2356 op_ldst(l##width); \
2357 gen_op_store_FT0_fpr(rD(ctx->opcode)); \
2360 #define GEN_LDFS(width, op) \
2361 OP_LD_TABLE(width); \
2362 GEN_LDF(width, op | 0x20); \
2363 GEN_LDUF(width, op | 0x21); \
2364 GEN_LDUXF(width, op | 0x01); \
2365 GEN_LDXF(width, 0x17, op | 0x00)
2367 /* lfd lfdu lfdux lfdx */
2368 GEN_LDFS(fd, 0x12);
2369 /* lfs lfsu lfsux lfsx */
2370 GEN_LDFS(fs, 0x10);
2372 /*** Floating-point store ***/
2373 #define GEN_STF(width, opc) \
2374 GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
2376 if (unlikely(!ctx->fpu_enabled)) { \
2377 RET_EXCP(ctx, EXCP_NO_FP, 0); \
2378 return; \
2380 gen_addr_imm_index(ctx); \
2381 gen_op_load_fpr_FT0(rS(ctx->opcode)); \
2382 op_ldst(st##width); \
2385 #define GEN_STUF(width, opc) \
2386 GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
2388 if (unlikely(!ctx->fpu_enabled)) { \
2389 RET_EXCP(ctx, EXCP_NO_FP, 0); \
2390 return; \
2392 if (unlikely(rA(ctx->opcode) == 0)) { \
2393 RET_INVAL(ctx); \
2394 return; \
2396 gen_addr_imm_index(ctx); \
2397 gen_op_load_fpr_FT0(rS(ctx->opcode)); \
2398 op_ldst(st##width); \
2399 gen_op_store_T0_gpr(rA(ctx->opcode)); \
2402 #define GEN_STUXF(width, opc) \
2403 GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \
2405 if (unlikely(!ctx->fpu_enabled)) { \
2406 RET_EXCP(ctx, EXCP_NO_FP, 0); \
2407 return; \
2409 if (unlikely(rA(ctx->opcode) == 0)) { \
2410 RET_INVAL(ctx); \
2411 return; \
2413 gen_addr_reg_index(ctx); \
2414 gen_op_load_fpr_FT0(rS(ctx->opcode)); \
2415 op_ldst(st##width); \
2416 gen_op_store_T0_gpr(rA(ctx->opcode)); \
2419 #define GEN_STXF(width, opc2, opc3) \
2420 GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_FLOAT) \
2422 if (unlikely(!ctx->fpu_enabled)) { \
2423 RET_EXCP(ctx, EXCP_NO_FP, 0); \
2424 return; \
2426 gen_addr_reg_index(ctx); \
2427 gen_op_load_fpr_FT0(rS(ctx->opcode)); \
2428 op_ldst(st##width); \
2431 #define GEN_STFS(width, op) \
2432 OP_ST_TABLE(width); \
2433 GEN_STF(width, op | 0x20); \
2434 GEN_STUF(width, op | 0x21); \
2435 GEN_STUXF(width, op | 0x01); \
2436 GEN_STXF(width, 0x17, op | 0x00)
2438 /* stfd stfdu stfdux stfdx */
2439 GEN_STFS(fd, 0x16);
2440 /* stfs stfsu stfsux stfsx */
2441 GEN_STFS(fs, 0x14);
2443 /* Optional: */
2444 /* stfiwx */
2445 GEN_HANDLER(stfiwx, 0x1F, 0x17, 0x1E, 0x00000001, PPC_FLOAT)
2447 if (unlikely(!ctx->fpu_enabled)) {
2448 RET_EXCP(ctx, EXCP_NO_FP, 0);
2449 return;
2451 gen_addr_reg_index(ctx);
2452 /* XXX: TODO: memcpy low order 32 bits of FRP(rs) into memory */
2453 RET_INVAL(ctx);
2456 /*** Branch ***/
2458 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2460 TranslationBlock *tb;
2461 tb = ctx->tb;
2462 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
2463 if (n == 0)
2464 gen_op_goto_tb0(TBPARAM(tb));
2465 else
2466 gen_op_goto_tb1(TBPARAM(tb));
2467 gen_set_T1(dest);
2468 #if defined(TARGET_PPC64)
2469 if (ctx->sf_mode)
2470 gen_op_b_T1_64();
2471 else
2472 #endif
2473 gen_op_b_T1();
2474 gen_op_set_T0((long)tb + n);
2475 if (ctx->singlestep_enabled)
2476 gen_op_debug();
2477 gen_op_exit_tb();
2478 } else {
2479 gen_set_T1(dest);
2480 #if defined(TARGET_PPC64)
2481 if (ctx->sf_mode)
2482 gen_op_b_T1_64();
2483 else
2484 #endif
2485 gen_op_b_T1();
2486 gen_op_reset_T0();
2487 if (ctx->singlestep_enabled)
2488 gen_op_debug();
2489 gen_op_exit_tb();
2493 /* b ba bl bla */
2494 GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
2496 target_ulong li, target;
2498 /* sign extend LI */
2499 #if defined(TARGET_PPC64)
2500 if (ctx->sf_mode)
2501 li = ((int64_t)LI(ctx->opcode) << 38) >> 38;
2502 else
2503 #endif
2504 li = ((int32_t)LI(ctx->opcode) << 6) >> 6;
2505 if (likely(AA(ctx->opcode) == 0))
2506 target = ctx->nip + li - 4;
2507 else
2508 target = li;
2509 if (LK(ctx->opcode)) {
2510 #if defined(TARGET_PPC64)
2511 if (ctx->sf_mode)
2512 gen_op_setlr_64(ctx->nip >> 32, ctx->nip);
2513 else
2514 #endif
2515 gen_op_setlr(ctx->nip);
2517 gen_goto_tb(ctx, 0, target);
2518 ctx->exception = EXCP_BRANCH;
2521 #define BCOND_IM 0
2522 #define BCOND_LR 1
2523 #define BCOND_CTR 2
2525 static inline void gen_bcond(DisasContext *ctx, int type)
2527 target_ulong target = 0;
2528 target_ulong li;
2529 uint32_t bo = BO(ctx->opcode);
2530 uint32_t bi = BI(ctx->opcode);
2531 uint32_t mask;
2533 if ((bo & 0x4) == 0)
2534 gen_op_dec_ctr();
2535 switch(type) {
2536 case BCOND_IM:
2537 li = (target_long)((int16_t)(BD(ctx->opcode)));
2538 if (likely(AA(ctx->opcode) == 0)) {
2539 target = ctx->nip + li - 4;
2540 } else {
2541 target = li;
2543 break;
2544 case BCOND_CTR:
2545 gen_op_movl_T1_ctr();
2546 break;
2547 default:
2548 case BCOND_LR:
2549 gen_op_movl_T1_lr();
2550 break;
2552 if (LK(ctx->opcode)) {
2553 #if defined(TARGET_PPC64)
2554 if (ctx->sf_mode)
2555 gen_op_setlr_64(ctx->nip >> 32, ctx->nip);
2556 else
2557 #endif
2558 gen_op_setlr(ctx->nip);
2560 if (bo & 0x10) {
2561 /* No CR condition */
2562 switch (bo & 0x6) {
2563 case 0:
2564 #if defined(TARGET_PPC64)
2565 if (ctx->sf_mode)
2566 gen_op_test_ctr_64();
2567 else
2568 #endif
2569 gen_op_test_ctr();
2570 break;
2571 case 2:
2572 #if defined(TARGET_PPC64)
2573 if (ctx->sf_mode)
2574 gen_op_test_ctrz_64();
2575 else
2576 #endif
2577 gen_op_test_ctrz();
2578 break;
2579 default:
2580 case 4:
2581 case 6:
2582 if (type == BCOND_IM) {
2583 gen_goto_tb(ctx, 0, target);
2584 } else {
2585 #if defined(TARGET_PPC64)
2586 if (ctx->sf_mode)
2587 gen_op_b_T1_64();
2588 else
2589 #endif
2590 gen_op_b_T1();
2591 gen_op_reset_T0();
2593 goto no_test;
2595 } else {
2596 mask = 1 << (3 - (bi & 0x03));
2597 gen_op_load_crf_T0(bi >> 2);
2598 if (bo & 0x8) {
2599 switch (bo & 0x6) {
2600 case 0:
2601 #if defined(TARGET_PPC64)
2602 if (ctx->sf_mode)
2603 gen_op_test_ctr_true_64(mask);
2604 else
2605 #endif
2606 gen_op_test_ctr_true(mask);
2607 break;
2608 case 2:
2609 #if defined(TARGET_PPC64)
2610 if (ctx->sf_mode)
2611 gen_op_test_ctrz_true_64(mask);
2612 else
2613 #endif
2614 gen_op_test_ctrz_true(mask);
2615 break;
2616 default:
2617 case 4:
2618 case 6:
2619 gen_op_test_true(mask);
2620 break;
2622 } else {
2623 switch (bo & 0x6) {
2624 case 0:
2625 #if defined(TARGET_PPC64)
2626 if (ctx->sf_mode)
2627 gen_op_test_ctr_false_64(mask);
2628 else
2629 #endif
2630 gen_op_test_ctr_false(mask);
2631 break;
2632 case 2:
2633 #if defined(TARGET_PPC64)
2634 if (ctx->sf_mode)
2635 gen_op_test_ctrz_false_64(mask);
2636 else
2637 #endif
2638 gen_op_test_ctrz_false(mask);
2639 break;
2640 default:
2641 case 4:
2642 case 6:
2643 gen_op_test_false(mask);
2644 break;
2648 if (type == BCOND_IM) {
2649 int l1 = gen_new_label();
2650 gen_op_jz_T0(l1);
2651 gen_goto_tb(ctx, 0, target);
2652 gen_set_label(l1);
2653 gen_goto_tb(ctx, 1, ctx->nip);
2654 } else {
2655 #if defined(TARGET_PPC64)
2656 if (ctx->sf_mode)
2657 gen_op_btest_T1_64(ctx->nip >> 32, ctx->nip);
2658 else
2659 #endif
2660 gen_op_btest_T1(ctx->nip);
2661 gen_op_reset_T0();
2663 no_test:
2664 if (ctx->singlestep_enabled)
2665 gen_op_debug();
2666 gen_op_exit_tb();
2667 ctx->exception = EXCP_BRANCH;
2670 GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
2672 gen_bcond(ctx, BCOND_IM);
2675 GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW)
2677 gen_bcond(ctx, BCOND_CTR);
2680 GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW)
2682 gen_bcond(ctx, BCOND_LR);
2685 /*** Condition register logical ***/
2686 #define GEN_CRLOGIC(op, opc) \
2687 GEN_HANDLER(cr##op, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER) \
2689 gen_op_load_crf_T0(crbA(ctx->opcode) >> 2); \
2690 gen_op_getbit_T0(3 - (crbA(ctx->opcode) & 0x03)); \
2691 gen_op_load_crf_T1(crbB(ctx->opcode) >> 2); \
2692 gen_op_getbit_T1(3 - (crbB(ctx->opcode) & 0x03)); \
2693 gen_op_##op(); \
2694 gen_op_load_crf_T1(crbD(ctx->opcode) >> 2); \
2695 gen_op_setcrfbit(~(1 << (3 - (crbD(ctx->opcode) & 0x03))), \
2696 3 - (crbD(ctx->opcode) & 0x03)); \
2697 gen_op_store_T1_crf(crbD(ctx->opcode) >> 2); \
2700 /* crand */
2701 GEN_CRLOGIC(and, 0x08);
2702 /* crandc */
2703 GEN_CRLOGIC(andc, 0x04);
2704 /* creqv */
2705 GEN_CRLOGIC(eqv, 0x09);
2706 /* crnand */
2707 GEN_CRLOGIC(nand, 0x07);
2708 /* crnor */
2709 GEN_CRLOGIC(nor, 0x01);
2710 /* cror */
2711 GEN_CRLOGIC(or, 0x0E);
2712 /* crorc */
2713 GEN_CRLOGIC(orc, 0x0D);
2714 /* crxor */
2715 GEN_CRLOGIC(xor, 0x06);
2716 /* mcrf */
2717 GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER)
2719 gen_op_load_crf_T0(crfS(ctx->opcode));
2720 gen_op_store_T0_crf(crfD(ctx->opcode));
2723 /*** System linkage ***/
2724 /* rfi (supervisor only) */
2725 GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW)
2727 #if defined(CONFIG_USER_ONLY)
2728 RET_PRIVOPC(ctx);
2729 #else
2730 /* Restore CPU state */
2731 if (unlikely(!ctx->supervisor)) {
2732 RET_PRIVOPC(ctx);
2733 return;
2735 #if defined(TARGET_PPC64)
2736 if (!ctx->sf_mode)
2737 gen_op_rfi_32();
2738 else
2739 #endif
2740 gen_op_rfi();
2741 RET_CHG_FLOW(ctx);
2742 #endif
2745 /* sc */
2746 GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFFFFD, PPC_FLOW)
2748 #if defined(CONFIG_USER_ONLY)
2749 RET_EXCP(ctx, EXCP_SYSCALL_USER, 0);
2750 #else
2751 RET_EXCP(ctx, EXCP_SYSCALL, 0);
2752 #endif
2755 /*** Trap ***/
2756 /* tw */
2757 GEN_HANDLER(tw, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW)
2759 gen_op_load_gpr_T0(rA(ctx->opcode));
2760 gen_op_load_gpr_T1(rB(ctx->opcode));
2761 /* Update the nip since this might generate a trap exception */
2762 gen_update_nip(ctx, ctx->nip);
2763 gen_op_tw(TO(ctx->opcode));
2766 /* twi */
2767 GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
2769 gen_op_load_gpr_T0(rA(ctx->opcode));
2770 gen_set_T1(SIMM(ctx->opcode));
2771 /* Update the nip since this might generate a trap exception */
2772 gen_update_nip(ctx, ctx->nip);
2773 gen_op_tw(TO(ctx->opcode));
2776 #if defined(TARGET_PPC64)
2777 /* td */
2778 GEN_HANDLER(td, 0x1F, 0x04, 0x02, 0x00000001, PPC_64B)
2780 gen_op_load_gpr_T0(rA(ctx->opcode));
2781 gen_op_load_gpr_T1(rB(ctx->opcode));
2782 /* Update the nip since this might generate a trap exception */
2783 gen_update_nip(ctx, ctx->nip);
2784 gen_op_td(TO(ctx->opcode));
2787 /* tdi */
2788 GEN_HANDLER(tdi, 0x02, 0xFF, 0xFF, 0x00000000, PPC_64B)
2790 gen_op_load_gpr_T0(rA(ctx->opcode));
2791 gen_set_T1(SIMM(ctx->opcode));
2792 /* Update the nip since this might generate a trap exception */
2793 gen_update_nip(ctx, ctx->nip);
2794 gen_op_td(TO(ctx->opcode));
2796 #endif
2798 /*** Processor control ***/
2799 /* mcrxr */
2800 GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC)
2802 gen_op_load_xer_cr();
2803 gen_op_store_T0_crf(crfD(ctx->opcode));
2804 gen_op_clear_xer_cr();
2807 /* mfcr */
2808 GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC)
2810 uint32_t crm, crn;
2812 if (likely(ctx->opcode & 0x00100000)) {
2813 crm = CRM(ctx->opcode);
2814 if (likely((crm ^ (crm - 1)) == 0)) {
2815 crn = ffs(crm);
2816 gen_op_load_cro(7 - crn);
2818 } else {
2819 gen_op_load_cr();
2821 gen_op_store_T0_gpr(rD(ctx->opcode));
2824 /* mfmsr */
2825 GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC)
2827 #if defined(CONFIG_USER_ONLY)
2828 RET_PRIVREG(ctx);
2829 #else
2830 if (unlikely(!ctx->supervisor)) {
2831 RET_PRIVREG(ctx);
2832 return;
2834 gen_op_load_msr();
2835 gen_op_store_T0_gpr(rD(ctx->opcode));
2836 #endif
2839 #if 0
2840 #define SPR_NOACCESS ((void *)(-1))
2841 #else
2842 static void spr_noaccess (void *opaque, int sprn)
2844 sprn = ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
2845 printf("ERROR: try to access SPR %d !\n", sprn);
2847 #define SPR_NOACCESS (&spr_noaccess)
2848 #endif
2850 /* mfspr */
2851 static inline void gen_op_mfspr (DisasContext *ctx)
2853 void (*read_cb)(void *opaque, int sprn);
2854 uint32_t sprn = SPR(ctx->opcode);
2856 #if !defined(CONFIG_USER_ONLY)
2857 if (ctx->supervisor)
2858 read_cb = ctx->spr_cb[sprn].oea_read;
2859 else
2860 #endif
2861 read_cb = ctx->spr_cb[sprn].uea_read;
2862 if (likely(read_cb != NULL)) {
2863 if (likely(read_cb != SPR_NOACCESS)) {
2864 (*read_cb)(ctx, sprn);
2865 gen_op_store_T0_gpr(rD(ctx->opcode));
2866 } else {
2867 /* Privilege exception */
2868 if (loglevel) {
2869 fprintf(logfile, "Trying to read priviledged spr %d %03x\n",
2870 sprn, sprn);
2872 printf("Trying to read priviledged spr %d %03x\n", sprn, sprn);
2873 RET_PRIVREG(ctx);
2875 } else {
2876 /* Not defined */
2877 if (loglevel) {
2878 fprintf(logfile, "Trying to read invalid spr %d %03x\n",
2879 sprn, sprn);
2881 printf("Trying to read invalid spr %d %03x\n", sprn, sprn);
2882 RET_EXCP(ctx, EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_SPR);
2886 GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC)
2888 gen_op_mfspr(ctx);
2891 /* mftb */
2892 GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_TB)
2894 gen_op_mfspr(ctx);
2897 /* mtcrf */
2898 GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC)
2900 uint32_t crm, crn;
2902 gen_op_load_gpr_T0(rS(ctx->opcode));
2903 crm = CRM(ctx->opcode);
2904 if (likely((ctx->opcode & 0x00100000) || (crm ^ (crm - 1)) == 0)) {
2905 crn = ffs(crm);
2906 gen_op_srli_T0(crn * 4);
2907 gen_op_andi_T0(0xF);
2908 gen_op_store_cro(7 - crn);
2909 } else {
2910 gen_op_store_cr(crm);
2914 /* mtmsr */
2915 GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC)
2917 #if defined(CONFIG_USER_ONLY)
2918 RET_PRIVREG(ctx);
2919 #else
2920 if (unlikely(!ctx->supervisor)) {
2921 RET_PRIVREG(ctx);
2922 return;
2924 gen_update_nip(ctx, ctx->nip);
2925 gen_op_load_gpr_T0(rS(ctx->opcode));
2926 #if defined(TARGET_PPC64)
2927 if (!ctx->sf_mode)
2928 gen_op_store_msr_32();
2929 else
2930 #endif
2931 gen_op_store_msr();
2932 /* Must stop the translation as machine state (may have) changed */
2933 RET_CHG_FLOW(ctx);
2934 #endif
2937 /* mtspr */
2938 GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC)
2940 void (*write_cb)(void *opaque, int sprn);
2941 uint32_t sprn = SPR(ctx->opcode);
2943 #if !defined(CONFIG_USER_ONLY)
2944 if (ctx->supervisor)
2945 write_cb = ctx->spr_cb[sprn].oea_write;
2946 else
2947 #endif
2948 write_cb = ctx->spr_cb[sprn].uea_write;
2949 if (likely(write_cb != NULL)) {
2950 if (likely(write_cb != SPR_NOACCESS)) {
2951 gen_op_load_gpr_T0(rS(ctx->opcode));
2952 (*write_cb)(ctx, sprn);
2953 } else {
2954 /* Privilege exception */
2955 if (loglevel) {
2956 fprintf(logfile, "Trying to write priviledged spr %d %03x\n",
2957 sprn, sprn);
2959 printf("Trying to write priviledged spr %d %03x\n", sprn, sprn);
2960 RET_PRIVREG(ctx);
2962 } else {
2963 /* Not defined */
2964 if (loglevel) {
2965 fprintf(logfile, "Trying to write invalid spr %d %03x\n",
2966 sprn, sprn);
2968 printf("Trying to write invalid spr %d %03x\n", sprn, sprn);
2969 RET_EXCP(ctx, EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_SPR);
2973 /*** Cache management ***/
2974 /* For now, all those will be implemented as nop:
2975 * this is valid, regarding the PowerPC specs...
2976 * We just have to flush tb while invalidating instruction cache lines...
2978 /* dcbf */
2979 GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03E00001, PPC_CACHE)
2981 gen_addr_reg_index(ctx);
2982 op_ldst(lbz);
2985 /* dcbi (Supervisor only) */
2986 GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE)
2988 #if defined(CONFIG_USER_ONLY)
2989 RET_PRIVOPC(ctx);
2990 #else
2991 if (unlikely(!ctx->supervisor)) {
2992 RET_PRIVOPC(ctx);
2993 return;
2995 gen_addr_reg_index(ctx);
2996 /* XXX: specification says this should be treated as a store by the MMU */
2997 //op_ldst(lbz);
2998 op_ldst(stb);
2999 #endif
3002 /* dcdst */
3003 GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE)
3005 /* XXX: specification say this is treated as a load by the MMU */
3006 gen_addr_reg_index(ctx);
3007 op_ldst(lbz);
3010 /* dcbt */
3011 GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x03E00001, PPC_CACHE)
3013 /* XXX: specification say this is treated as a load by the MMU
3014 * but does not generate any exception
3018 /* dcbtst */
3019 GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x03E00001, PPC_CACHE)
3021 /* XXX: specification say this is treated as a load by the MMU
3022 * but does not generate any exception
3026 /* dcbz */
3027 #define op_dcbz() (*gen_op_dcbz[ctx->mem_idx])()
3028 #if defined(TARGET_PPC64)
3029 #if defined(CONFIG_USER_ONLY)
3030 static GenOpFunc *gen_op_dcbz[] = {
3031 &gen_op_dcbz_raw,
3032 &gen_op_dcbz_raw,
3033 &gen_op_dcbz_64_raw,
3034 &gen_op_dcbz_64_raw,
3036 #else
3037 static GenOpFunc *gen_op_dcbz[] = {
3038 &gen_op_dcbz_user,
3039 &gen_op_dcbz_user,
3040 &gen_op_dcbz_kernel,
3041 &gen_op_dcbz_kernel,
3042 &gen_op_dcbz_64_user,
3043 &gen_op_dcbz_64_user,
3044 &gen_op_dcbz_64_kernel,
3045 &gen_op_dcbz_64_kernel,
3047 #endif
3048 #else
3049 #if defined(CONFIG_USER_ONLY)
3050 static GenOpFunc *gen_op_dcbz[] = {
3051 &gen_op_dcbz_raw,
3052 &gen_op_dcbz_raw,
3054 #else
3055 static GenOpFunc *gen_op_dcbz[] = {
3056 &gen_op_dcbz_user,
3057 &gen_op_dcbz_user,
3058 &gen_op_dcbz_kernel,
3059 &gen_op_dcbz_kernel,
3061 #endif
3062 #endif
3064 GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE)
3066 gen_addr_reg_index(ctx);
3067 op_dcbz();
3068 gen_op_check_reservation();
3071 /* icbi */
3072 #define op_icbi() (*gen_op_icbi[ctx->mem_idx])()
3073 #if defined(TARGET_PPC64)
3074 #if defined(CONFIG_USER_ONLY)
3075 static GenOpFunc *gen_op_icbi[] = {
3076 &gen_op_icbi_raw,
3077 &gen_op_icbi_raw,
3078 &gen_op_icbi_64_raw,
3079 &gen_op_icbi_64_raw,
3081 #else
3082 static GenOpFunc *gen_op_icbi[] = {
3083 &gen_op_icbi_user,
3084 &gen_op_icbi_user,
3085 &gen_op_icbi_kernel,
3086 &gen_op_icbi_kernel,
3087 &gen_op_icbi_64_user,
3088 &gen_op_icbi_64_user,
3089 &gen_op_icbi_64_kernel,
3090 &gen_op_icbi_64_kernel,
3092 #endif
3093 #else
3094 #if defined(CONFIG_USER_ONLY)
3095 static GenOpFunc *gen_op_icbi[] = {
3096 &gen_op_icbi_raw,
3097 &gen_op_icbi_raw,
3099 #else
3100 static GenOpFunc *gen_op_icbi[] = {
3101 &gen_op_icbi_user,
3102 &gen_op_icbi_user,
3103 &gen_op_icbi_kernel,
3104 &gen_op_icbi_kernel,
3106 #endif
3107 #endif
3108 GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE)
3110 /* NIP cannot be restored if the memory exception comes from an helper */
3111 gen_update_nip(ctx, ctx->nip - 4);
3112 gen_addr_reg_index(ctx);
3113 op_icbi();
3114 RET_STOP(ctx);
3117 /* Optional: */
3118 /* dcba */
3119 GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_OPT)
3123 /*** Segment register manipulation ***/
3124 /* Supervisor only: */
3125 /* mfsr */
3126 GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT)
3128 #if defined(CONFIG_USER_ONLY)
3129 RET_PRIVREG(ctx);
3130 #else
3131 if (unlikely(!ctx->supervisor)) {
3132 RET_PRIVREG(ctx);
3133 return;
3135 gen_op_set_T1(SR(ctx->opcode));
3136 gen_op_load_sr();
3137 gen_op_store_T0_gpr(rD(ctx->opcode));
3138 #endif
3141 /* mfsrin */
3142 GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT)
3144 #if defined(CONFIG_USER_ONLY)
3145 RET_PRIVREG(ctx);
3146 #else
3147 if (unlikely(!ctx->supervisor)) {
3148 RET_PRIVREG(ctx);
3149 return;
3151 gen_op_load_gpr_T1(rB(ctx->opcode));
3152 gen_op_srli_T1(28);
3153 gen_op_load_sr();
3154 gen_op_store_T0_gpr(rD(ctx->opcode));
3155 #endif
3158 /* mtsr */
3159 GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT)
3161 #if defined(CONFIG_USER_ONLY)
3162 RET_PRIVREG(ctx);
3163 #else
3164 if (unlikely(!ctx->supervisor)) {
3165 RET_PRIVREG(ctx);
3166 return;
3168 gen_op_load_gpr_T0(rS(ctx->opcode));
3169 gen_op_set_T1(SR(ctx->opcode));
3170 gen_op_store_sr();
3171 RET_STOP(ctx);
3172 #endif
3175 /* mtsrin */
3176 GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT)
3178 #if defined(CONFIG_USER_ONLY)
3179 RET_PRIVREG(ctx);
3180 #else
3181 if (unlikely(!ctx->supervisor)) {
3182 RET_PRIVREG(ctx);
3183 return;
3185 gen_op_load_gpr_T0(rS(ctx->opcode));
3186 gen_op_load_gpr_T1(rB(ctx->opcode));
3187 gen_op_srli_T1(28);
3188 gen_op_store_sr();
3189 RET_STOP(ctx);
3190 #endif
3193 /*** Lookaside buffer management ***/
3194 /* Optional & supervisor only: */
3195 /* tlbia */
3196 GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA)
3198 #if defined(CONFIG_USER_ONLY)
3199 RET_PRIVOPC(ctx);
3200 #else
3201 if (unlikely(!ctx->supervisor)) {
3202 if (loglevel)
3203 fprintf(logfile, "%s: ! supervisor\n", __func__);
3204 RET_PRIVOPC(ctx);
3205 return;
3207 gen_op_tlbia();
3208 RET_STOP(ctx);
3209 #endif
3212 /* tlbie */
3213 GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE)
3215 #if defined(CONFIG_USER_ONLY)
3216 RET_PRIVOPC(ctx);
3217 #else
3218 if (unlikely(!ctx->supervisor)) {
3219 RET_PRIVOPC(ctx);
3220 return;
3222 gen_op_load_gpr_T0(rB(ctx->opcode));
3223 #if defined(TARGET_PPC64)
3224 if (ctx->sf_mode)
3225 gen_op_tlbie_64();
3226 else
3227 #endif
3228 gen_op_tlbie();
3229 RET_STOP(ctx);
3230 #endif
3233 /* tlbsync */
3234 GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC)
3236 #if defined(CONFIG_USER_ONLY)
3237 RET_PRIVOPC(ctx);
3238 #else
3239 if (unlikely(!ctx->supervisor)) {
3240 RET_PRIVOPC(ctx);
3241 return;
3243 /* This has no effect: it should ensure that all previous
3244 * tlbie have completed
3246 RET_STOP(ctx);
3247 #endif
3250 /*** External control ***/
3251 /* Optional: */
3252 #define op_eciwx() (*gen_op_eciwx[ctx->mem_idx])()
3253 #define op_ecowx() (*gen_op_ecowx[ctx->mem_idx])()
3254 #if defined(TARGET_PPC64)
3255 #if defined(CONFIG_USER_ONLY)
3256 static GenOpFunc *gen_op_eciwx[] = {
3257 &gen_op_eciwx_raw,
3258 &gen_op_eciwx_le_raw,
3259 &gen_op_eciwx_64_raw,
3260 &gen_op_eciwx_le_64_raw,
3262 static GenOpFunc *gen_op_ecowx[] = {
3263 &gen_op_ecowx_raw,
3264 &gen_op_ecowx_le_raw,
3265 &gen_op_ecowx_64_raw,
3266 &gen_op_ecowx_le_64_raw,
3268 #else
3269 static GenOpFunc *gen_op_eciwx[] = {
3270 &gen_op_eciwx_user,
3271 &gen_op_eciwx_le_user,
3272 &gen_op_eciwx_kernel,
3273 &gen_op_eciwx_le_kernel,
3274 &gen_op_eciwx_64_user,
3275 &gen_op_eciwx_le_64_user,
3276 &gen_op_eciwx_64_kernel,
3277 &gen_op_eciwx_le_64_kernel,
3279 static GenOpFunc *gen_op_ecowx[] = {
3280 &gen_op_ecowx_user,
3281 &gen_op_ecowx_le_user,
3282 &gen_op_ecowx_kernel,
3283 &gen_op_ecowx_le_kernel,
3284 &gen_op_ecowx_64_user,
3285 &gen_op_ecowx_le_64_user,
3286 &gen_op_ecowx_64_kernel,
3287 &gen_op_ecowx_le_64_kernel,
3289 #endif
3290 #else
3291 #if defined(CONFIG_USER_ONLY)
3292 static GenOpFunc *gen_op_eciwx[] = {
3293 &gen_op_eciwx_raw,
3294 &gen_op_eciwx_le_raw,
3296 static GenOpFunc *gen_op_ecowx[] = {
3297 &gen_op_ecowx_raw,
3298 &gen_op_ecowx_le_raw,
3300 #else
3301 static GenOpFunc *gen_op_eciwx[] = {
3302 &gen_op_eciwx_user,
3303 &gen_op_eciwx_le_user,
3304 &gen_op_eciwx_kernel,
3305 &gen_op_eciwx_le_kernel,
3307 static GenOpFunc *gen_op_ecowx[] = {
3308 &gen_op_ecowx_user,
3309 &gen_op_ecowx_le_user,
3310 &gen_op_ecowx_kernel,
3311 &gen_op_ecowx_le_kernel,
3313 #endif
3314 #endif
3316 /* eciwx */
3317 GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN)
3319 /* Should check EAR[E] & alignment ! */
3320 gen_addr_reg_index(ctx);
3321 op_eciwx();
3322 gen_op_store_T0_gpr(rD(ctx->opcode));
3325 /* ecowx */
3326 GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN)
3328 /* Should check EAR[E] & alignment ! */
3329 gen_addr_reg_index(ctx);
3330 gen_op_load_gpr_T1(rS(ctx->opcode));
3331 op_ecowx();
3334 /* PowerPC 601 specific instructions */
3335 /* abs - abs. */
3336 GEN_HANDLER(abs, 0x1F, 0x08, 0x0B, 0x0000F800, PPC_POWER_BR)
3338 gen_op_load_gpr_T0(rA(ctx->opcode));
3339 gen_op_POWER_abs();
3340 gen_op_store_T0_gpr(rD(ctx->opcode));
3341 if (unlikely(Rc(ctx->opcode) != 0))
3342 gen_set_Rc0(ctx);
3345 /* abso - abso. */
3346 GEN_HANDLER(abso, 0x1F, 0x08, 0x1B, 0x0000F800, PPC_POWER_BR)
3348 gen_op_load_gpr_T0(rA(ctx->opcode));
3349 gen_op_POWER_abso();
3350 gen_op_store_T0_gpr(rD(ctx->opcode));
3351 if (unlikely(Rc(ctx->opcode) != 0))
3352 gen_set_Rc0(ctx);
3355 /* clcs */
3356 GEN_HANDLER(clcs, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR) /* 601 ? */
3358 gen_op_load_gpr_T0(rA(ctx->opcode));
3359 gen_op_POWER_clcs();
3360 gen_op_store_T0_gpr(rD(ctx->opcode));
3363 /* div - div. */
3364 GEN_HANDLER(div, 0x1F, 0x0B, 0x0A, 0x00000000, PPC_POWER_BR)
3366 gen_op_load_gpr_T0(rA(ctx->opcode));
3367 gen_op_load_gpr_T1(rB(ctx->opcode));
3368 gen_op_POWER_div();
3369 gen_op_store_T0_gpr(rD(ctx->opcode));
3370 if (unlikely(Rc(ctx->opcode) != 0))
3371 gen_set_Rc0(ctx);
3374 /* divo - divo. */
3375 GEN_HANDLER(divo, 0x1F, 0x0B, 0x1A, 0x00000000, PPC_POWER_BR)
3377 gen_op_load_gpr_T0(rA(ctx->opcode));
3378 gen_op_load_gpr_T1(rB(ctx->opcode));
3379 gen_op_POWER_divo();
3380 gen_op_store_T0_gpr(rD(ctx->opcode));
3381 if (unlikely(Rc(ctx->opcode) != 0))
3382 gen_set_Rc0(ctx);
3385 /* divs - divs. */
3386 GEN_HANDLER(divs, 0x1F, 0x0B, 0x0B, 0x00000000, PPC_POWER_BR)
3388 gen_op_load_gpr_T0(rA(ctx->opcode));
3389 gen_op_load_gpr_T1(rB(ctx->opcode));
3390 gen_op_POWER_divs();
3391 gen_op_store_T0_gpr(rD(ctx->opcode));
3392 if (unlikely(Rc(ctx->opcode) != 0))
3393 gen_set_Rc0(ctx);
3396 /* divso - divso. */
3397 GEN_HANDLER(divso, 0x1F, 0x0B, 0x1B, 0x00000000, PPC_POWER_BR)
3399 gen_op_load_gpr_T0(rA(ctx->opcode));
3400 gen_op_load_gpr_T1(rB(ctx->opcode));
3401 gen_op_POWER_divso();
3402 gen_op_store_T0_gpr(rD(ctx->opcode));
3403 if (unlikely(Rc(ctx->opcode) != 0))
3404 gen_set_Rc0(ctx);
3407 /* doz - doz. */
3408 GEN_HANDLER(doz, 0x1F, 0x08, 0x08, 0x00000000, PPC_POWER_BR)
3410 gen_op_load_gpr_T0(rA(ctx->opcode));
3411 gen_op_load_gpr_T1(rB(ctx->opcode));
3412 gen_op_POWER_doz();
3413 gen_op_store_T0_gpr(rD(ctx->opcode));
3414 if (unlikely(Rc(ctx->opcode) != 0))
3415 gen_set_Rc0(ctx);
3418 /* dozo - dozo. */
3419 GEN_HANDLER(dozo, 0x1F, 0x08, 0x18, 0x00000000, PPC_POWER_BR)
3421 gen_op_load_gpr_T0(rA(ctx->opcode));
3422 gen_op_load_gpr_T1(rB(ctx->opcode));
3423 gen_op_POWER_dozo();
3424 gen_op_store_T0_gpr(rD(ctx->opcode));
3425 if (unlikely(Rc(ctx->opcode) != 0))
3426 gen_set_Rc0(ctx);
3429 /* dozi */
3430 GEN_HANDLER(dozi, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
3432 gen_op_load_gpr_T0(rA(ctx->opcode));
3433 gen_op_set_T1(SIMM(ctx->opcode));
3434 gen_op_POWER_doz();
3435 gen_op_store_T0_gpr(rD(ctx->opcode));
3438 /* As lscbx load from memory byte after byte, it's always endian safe */
3439 #define op_POWER_lscbx(start, ra, rb) \
3440 (*gen_op_POWER_lscbx[ctx->mem_idx])(start, ra, rb)
3441 #if defined(CONFIG_USER_ONLY)
3442 static GenOpFunc3 *gen_op_POWER_lscbx[] = {
3443 &gen_op_POWER_lscbx_raw,
3444 &gen_op_POWER_lscbx_raw,
3446 #else
3447 static GenOpFunc3 *gen_op_POWER_lscbx[] = {
3448 &gen_op_POWER_lscbx_user,
3449 &gen_op_POWER_lscbx_user,
3450 &gen_op_POWER_lscbx_kernel,
3451 &gen_op_POWER_lscbx_kernel,
3453 #endif
3455 /* lscbx - lscbx. */
3456 GEN_HANDLER(lscbx, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR)
3458 int ra = rA(ctx->opcode);
3459 int rb = rB(ctx->opcode);
3461 gen_addr_reg_index(ctx);
3462 if (ra == 0) {
3463 ra = rb;
3465 /* NIP cannot be restored if the memory exception comes from an helper */
3466 gen_update_nip(ctx, ctx->nip - 4);
3467 gen_op_load_xer_bc();
3468 gen_op_load_xer_cmp();
3469 op_POWER_lscbx(rD(ctx->opcode), ra, rb);
3470 gen_op_store_xer_bc();
3471 if (unlikely(Rc(ctx->opcode) != 0))
3472 gen_set_Rc0(ctx);
3475 /* maskg - maskg. */
3476 GEN_HANDLER(maskg, 0x1F, 0x1D, 0x00, 0x00000000, PPC_POWER_BR)
3478 gen_op_load_gpr_T0(rS(ctx->opcode));
3479 gen_op_load_gpr_T1(rB(ctx->opcode));
3480 gen_op_POWER_maskg();
3481 gen_op_store_T0_gpr(rA(ctx->opcode));
3482 if (unlikely(Rc(ctx->opcode) != 0))
3483 gen_set_Rc0(ctx);
3486 /* maskir - maskir. */
3487 GEN_HANDLER(maskir, 0x1F, 0x1D, 0x10, 0x00000000, PPC_POWER_BR)
3489 gen_op_load_gpr_T0(rA(ctx->opcode));
3490 gen_op_load_gpr_T1(rS(ctx->opcode));
3491 gen_op_load_gpr_T2(rB(ctx->opcode));
3492 gen_op_POWER_maskir();
3493 gen_op_store_T0_gpr(rA(ctx->opcode));
3494 if (unlikely(Rc(ctx->opcode) != 0))
3495 gen_set_Rc0(ctx);
3498 /* mul - mul. */
3499 GEN_HANDLER(mul, 0x1F, 0x0B, 0x03, 0x00000000, PPC_POWER_BR)
3501 gen_op_load_gpr_T0(rA(ctx->opcode));
3502 gen_op_load_gpr_T1(rB(ctx->opcode));
3503 gen_op_POWER_mul();
3504 gen_op_store_T0_gpr(rD(ctx->opcode));
3505 if (unlikely(Rc(ctx->opcode) != 0))
3506 gen_set_Rc0(ctx);
3509 /* mulo - mulo. */
3510 GEN_HANDLER(mulo, 0x1F, 0x0B, 0x13, 0x00000000, PPC_POWER_BR)
3512 gen_op_load_gpr_T0(rA(ctx->opcode));
3513 gen_op_load_gpr_T1(rB(ctx->opcode));
3514 gen_op_POWER_mulo();
3515 gen_op_store_T0_gpr(rD(ctx->opcode));
3516 if (unlikely(Rc(ctx->opcode) != 0))
3517 gen_set_Rc0(ctx);
3520 /* nabs - nabs. */
3521 GEN_HANDLER(nabs, 0x1F, 0x08, 0x0F, 0x00000000, PPC_POWER_BR)
3523 gen_op_load_gpr_T0(rA(ctx->opcode));
3524 gen_op_POWER_nabs();
3525 gen_op_store_T0_gpr(rD(ctx->opcode));
3526 if (unlikely(Rc(ctx->opcode) != 0))
3527 gen_set_Rc0(ctx);
3530 /* nabso - nabso. */
3531 GEN_HANDLER(nabso, 0x1F, 0x08, 0x1F, 0x00000000, PPC_POWER_BR)
3533 gen_op_load_gpr_T0(rA(ctx->opcode));
3534 gen_op_POWER_nabso();
3535 gen_op_store_T0_gpr(rD(ctx->opcode));
3536 if (unlikely(Rc(ctx->opcode) != 0))
3537 gen_set_Rc0(ctx);
3540 /* rlmi - rlmi. */
3541 GEN_HANDLER(rlmi, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
3543 uint32_t mb, me;
3545 mb = MB(ctx->opcode);
3546 me = ME(ctx->opcode);
3547 gen_op_load_gpr_T0(rS(ctx->opcode));
3548 gen_op_load_gpr_T1(rA(ctx->opcode));
3549 gen_op_load_gpr_T2(rB(ctx->opcode));
3550 gen_op_POWER_rlmi(MASK(mb, me), ~MASK(mb, me));
3551 gen_op_store_T0_gpr(rA(ctx->opcode));
3552 if (unlikely(Rc(ctx->opcode) != 0))
3553 gen_set_Rc0(ctx);
3556 /* rrib - rrib. */
3557 GEN_HANDLER(rrib, 0x1F, 0x19, 0x10, 0x00000000, PPC_POWER_BR)
3559 gen_op_load_gpr_T0(rS(ctx->opcode));
3560 gen_op_load_gpr_T1(rA(ctx->opcode));
3561 gen_op_load_gpr_T2(rB(ctx->opcode));
3562 gen_op_POWER_rrib();
3563 gen_op_store_T0_gpr(rA(ctx->opcode));
3564 if (unlikely(Rc(ctx->opcode) != 0))
3565 gen_set_Rc0(ctx);
3568 /* sle - sle. */
3569 GEN_HANDLER(sle, 0x1F, 0x19, 0x04, 0x00000000, PPC_POWER_BR)
3571 gen_op_load_gpr_T0(rS(ctx->opcode));
3572 gen_op_load_gpr_T1(rB(ctx->opcode));
3573 gen_op_POWER_sle();
3574 gen_op_store_T0_gpr(rA(ctx->opcode));
3575 if (unlikely(Rc(ctx->opcode) != 0))
3576 gen_set_Rc0(ctx);
3579 /* sleq - sleq. */
3580 GEN_HANDLER(sleq, 0x1F, 0x19, 0x06, 0x00000000, PPC_POWER_BR)
3582 gen_op_load_gpr_T0(rS(ctx->opcode));
3583 gen_op_load_gpr_T1(rB(ctx->opcode));
3584 gen_op_POWER_sleq();
3585 gen_op_store_T0_gpr(rA(ctx->opcode));
3586 if (unlikely(Rc(ctx->opcode) != 0))
3587 gen_set_Rc0(ctx);
3590 /* sliq - sliq. */
3591 GEN_HANDLER(sliq, 0x1F, 0x18, 0x05, 0x00000000, PPC_POWER_BR)
3593 gen_op_load_gpr_T0(rS(ctx->opcode));
3594 gen_op_set_T1(SH(ctx->opcode));
3595 gen_op_POWER_sle();
3596 gen_op_store_T0_gpr(rA(ctx->opcode));
3597 if (unlikely(Rc(ctx->opcode) != 0))
3598 gen_set_Rc0(ctx);
3601 /* slliq - slliq. */
3602 GEN_HANDLER(slliq, 0x1F, 0x18, 0x07, 0x00000000, PPC_POWER_BR)
3604 gen_op_load_gpr_T0(rS(ctx->opcode));
3605 gen_op_set_T1(SH(ctx->opcode));
3606 gen_op_POWER_sleq();
3607 gen_op_store_T0_gpr(rA(ctx->opcode));
3608 if (unlikely(Rc(ctx->opcode) != 0))
3609 gen_set_Rc0(ctx);
3612 /* sllq - sllq. */
3613 GEN_HANDLER(sllq, 0x1F, 0x18, 0x06, 0x00000000, PPC_POWER_BR)
3615 gen_op_load_gpr_T0(rS(ctx->opcode));
3616 gen_op_load_gpr_T1(rB(ctx->opcode));
3617 gen_op_POWER_sllq();
3618 gen_op_store_T0_gpr(rA(ctx->opcode));
3619 if (unlikely(Rc(ctx->opcode) != 0))
3620 gen_set_Rc0(ctx);
3623 /* slq - slq. */
3624 GEN_HANDLER(slq, 0x1F, 0x18, 0x04, 0x00000000, PPC_POWER_BR)
3626 gen_op_load_gpr_T0(rS(ctx->opcode));
3627 gen_op_load_gpr_T1(rB(ctx->opcode));
3628 gen_op_POWER_slq();
3629 gen_op_store_T0_gpr(rA(ctx->opcode));
3630 if (unlikely(Rc(ctx->opcode) != 0))
3631 gen_set_Rc0(ctx);
3634 /* sraiq - sraiq. */
3635 GEN_HANDLER(sraiq, 0x1F, 0x18, 0x1D, 0x00000000, PPC_POWER_BR)
3637 gen_op_load_gpr_T0(rS(ctx->opcode));
3638 gen_op_set_T1(SH(ctx->opcode));
3639 gen_op_POWER_sraq();
3640 gen_op_store_T0_gpr(rA(ctx->opcode));
3641 if (unlikely(Rc(ctx->opcode) != 0))
3642 gen_set_Rc0(ctx);
3645 /* sraq - sraq. */
3646 GEN_HANDLER(sraq, 0x1F, 0x18, 0x1C, 0x00000000, PPC_POWER_BR)
3648 gen_op_load_gpr_T0(rS(ctx->opcode));
3649 gen_op_load_gpr_T1(rB(ctx->opcode));
3650 gen_op_POWER_sraq();
3651 gen_op_store_T0_gpr(rA(ctx->opcode));
3652 if (unlikely(Rc(ctx->opcode) != 0))
3653 gen_set_Rc0(ctx);
3656 /* sre - sre. */
3657 GEN_HANDLER(sre, 0x1F, 0x19, 0x14, 0x00000000, PPC_POWER_BR)
3659 gen_op_load_gpr_T0(rS(ctx->opcode));
3660 gen_op_load_gpr_T1(rB(ctx->opcode));
3661 gen_op_POWER_sre();
3662 gen_op_store_T0_gpr(rA(ctx->opcode));
3663 if (unlikely(Rc(ctx->opcode) != 0))
3664 gen_set_Rc0(ctx);
3667 /* srea - srea. */
3668 GEN_HANDLER(srea, 0x1F, 0x19, 0x1C, 0x00000000, PPC_POWER_BR)
3670 gen_op_load_gpr_T0(rS(ctx->opcode));
3671 gen_op_load_gpr_T1(rB(ctx->opcode));
3672 gen_op_POWER_srea();
3673 gen_op_store_T0_gpr(rA(ctx->opcode));
3674 if (unlikely(Rc(ctx->opcode) != 0))
3675 gen_set_Rc0(ctx);
3678 /* sreq */
3679 GEN_HANDLER(sreq, 0x1F, 0x19, 0x16, 0x00000000, PPC_POWER_BR)
3681 gen_op_load_gpr_T0(rS(ctx->opcode));
3682 gen_op_load_gpr_T1(rB(ctx->opcode));
3683 gen_op_POWER_sreq();
3684 gen_op_store_T0_gpr(rA(ctx->opcode));
3685 if (unlikely(Rc(ctx->opcode) != 0))
3686 gen_set_Rc0(ctx);
3689 /* sriq */
3690 GEN_HANDLER(sriq, 0x1F, 0x18, 0x15, 0x00000000, PPC_POWER_BR)
3692 gen_op_load_gpr_T0(rS(ctx->opcode));
3693 gen_op_set_T1(SH(ctx->opcode));
3694 gen_op_POWER_srq();
3695 gen_op_store_T0_gpr(rA(ctx->opcode));
3696 if (unlikely(Rc(ctx->opcode) != 0))
3697 gen_set_Rc0(ctx);
3700 /* srliq */
3701 GEN_HANDLER(srliq, 0x1F, 0x18, 0x17, 0x00000000, PPC_POWER_BR)
3703 gen_op_load_gpr_T0(rS(ctx->opcode));
3704 gen_op_load_gpr_T1(rB(ctx->opcode));
3705 gen_op_set_T1(SH(ctx->opcode));
3706 gen_op_POWER_srlq();
3707 gen_op_store_T0_gpr(rA(ctx->opcode));
3708 if (unlikely(Rc(ctx->opcode) != 0))
3709 gen_set_Rc0(ctx);
3712 /* srlq */
3713 GEN_HANDLER(srlq, 0x1F, 0x18, 0x16, 0x00000000, PPC_POWER_BR)
3715 gen_op_load_gpr_T0(rS(ctx->opcode));
3716 gen_op_load_gpr_T1(rB(ctx->opcode));
3717 gen_op_POWER_srlq();
3718 gen_op_store_T0_gpr(rA(ctx->opcode));
3719 if (unlikely(Rc(ctx->opcode) != 0))
3720 gen_set_Rc0(ctx);
3723 /* srq */
3724 GEN_HANDLER(srq, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR)
3726 gen_op_load_gpr_T0(rS(ctx->opcode));
3727 gen_op_load_gpr_T1(rB(ctx->opcode));
3728 gen_op_POWER_srq();
3729 gen_op_store_T0_gpr(rA(ctx->opcode));
3730 if (unlikely(Rc(ctx->opcode) != 0))
3731 gen_set_Rc0(ctx);
3734 /* PowerPC 602 specific instructions */
3735 /* dsa */
3736 GEN_HANDLER(dsa, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC)
3738 /* XXX: TODO */
3739 RET_INVAL(ctx);
3742 /* esa */
3743 GEN_HANDLER(esa, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC)
3745 /* XXX: TODO */
3746 RET_INVAL(ctx);
3749 /* mfrom */
3750 GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC)
3752 #if defined(CONFIG_USER_ONLY)
3753 RET_PRIVOPC(ctx);
3754 #else
3755 if (unlikely(!ctx->supervisor)) {
3756 RET_PRIVOPC(ctx);
3757 return;
3759 gen_op_load_gpr_T0(rA(ctx->opcode));
3760 gen_op_602_mfrom();
3761 gen_op_store_T0_gpr(rD(ctx->opcode));
3762 #endif
3765 /* 602 - 603 - G2 TLB management */
3766 /* tlbld */
3767 GEN_HANDLER(tlbld, 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB)
3769 #if defined(CONFIG_USER_ONLY)
3770 RET_PRIVOPC(ctx);
3771 #else
3772 if (unlikely(!ctx->supervisor)) {
3773 RET_PRIVOPC(ctx);
3774 return;
3776 gen_op_load_gpr_T0(rB(ctx->opcode));
3777 gen_op_6xx_tlbld();
3778 RET_STOP(ctx);
3779 #endif
3782 /* tlbli */
3783 GEN_HANDLER(tlbli, 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB)
3785 #if defined(CONFIG_USER_ONLY)
3786 RET_PRIVOPC(ctx);
3787 #else
3788 if (unlikely(!ctx->supervisor)) {
3789 RET_PRIVOPC(ctx);
3790 return;
3792 gen_op_load_gpr_T0(rB(ctx->opcode));
3793 gen_op_6xx_tlbli();
3794 RET_STOP(ctx);
3795 #endif
3798 /* POWER instructions not in PowerPC 601 */
3799 /* clf */
3800 GEN_HANDLER(clf, 0x1F, 0x16, 0x03, 0x03E00000, PPC_POWER)
3802 /* Cache line flush: implemented as no-op */
3805 /* cli */
3806 GEN_HANDLER(cli, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER)
3808 /* Cache line invalidate: priviledged and treated as no-op */
3809 #if defined(CONFIG_USER_ONLY)
3810 RET_PRIVOPC(ctx);
3811 #else
3812 if (unlikely(!ctx->supervisor)) {
3813 RET_PRIVOPC(ctx);
3814 return;
3816 #endif
3819 /* dclst */
3820 GEN_HANDLER(dclst, 0x1F, 0x16, 0x13, 0x03E00000, PPC_POWER)
3822 /* Data cache line store: treated as no-op */
3825 GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER)
3827 #if defined(CONFIG_USER_ONLY)
3828 RET_PRIVOPC(ctx);
3829 #else
3830 if (unlikely(!ctx->supervisor)) {
3831 RET_PRIVOPC(ctx);
3832 return;
3834 int ra = rA(ctx->opcode);
3835 int rd = rD(ctx->opcode);
3837 gen_addr_reg_index(ctx);
3838 gen_op_POWER_mfsri();
3839 gen_op_store_T0_gpr(rd);
3840 if (ra != 0 && ra != rd)
3841 gen_op_store_T1_gpr(ra);
3842 #endif
3845 GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER)
3847 #if defined(CONFIG_USER_ONLY)
3848 RET_PRIVOPC(ctx);
3849 #else
3850 if (unlikely(!ctx->supervisor)) {
3851 RET_PRIVOPC(ctx);
3852 return;
3854 gen_addr_reg_index(ctx);
3855 gen_op_POWER_rac();
3856 gen_op_store_T0_gpr(rD(ctx->opcode));
3857 #endif
3860 GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER)
3862 #if defined(CONFIG_USER_ONLY)
3863 RET_PRIVOPC(ctx);
3864 #else
3865 if (unlikely(!ctx->supervisor)) {
3866 RET_PRIVOPC(ctx);
3867 return;
3869 gen_op_POWER_rfsvc();
3870 RET_CHG_FLOW(ctx);
3871 #endif
3874 /* svc is not implemented for now */
3876 /* POWER2 specific instructions */
3877 /* Quad manipulation (load/store two floats at a time) */
3878 #define op_POWER2_lfq() (*gen_op_POWER2_lfq[ctx->mem_idx])()
3879 #define op_POWER2_stfq() (*gen_op_POWER2_stfq[ctx->mem_idx])()
3880 #if defined(CONFIG_USER_ONLY)
3881 static GenOpFunc *gen_op_POWER2_lfq[] = {
3882 &gen_op_POWER2_lfq_le_raw,
3883 &gen_op_POWER2_lfq_raw,
3885 static GenOpFunc *gen_op_POWER2_stfq[] = {
3886 &gen_op_POWER2_stfq_le_raw,
3887 &gen_op_POWER2_stfq_raw,
3889 #else
3890 static GenOpFunc *gen_op_POWER2_lfq[] = {
3891 &gen_op_POWER2_lfq_le_user,
3892 &gen_op_POWER2_lfq_user,
3893 &gen_op_POWER2_lfq_le_kernel,
3894 &gen_op_POWER2_lfq_kernel,
3896 static GenOpFunc *gen_op_POWER2_stfq[] = {
3897 &gen_op_POWER2_stfq_le_user,
3898 &gen_op_POWER2_stfq_user,
3899 &gen_op_POWER2_stfq_le_kernel,
3900 &gen_op_POWER2_stfq_kernel,
3902 #endif
3904 /* lfq */
3905 GEN_HANDLER(lfq, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
3907 /* NIP cannot be restored if the memory exception comes from an helper */
3908 gen_update_nip(ctx, ctx->nip - 4);
3909 gen_addr_imm_index(ctx);
3910 op_POWER2_lfq();
3911 gen_op_store_FT0_fpr(rD(ctx->opcode));
3912 gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
3915 /* lfqu */
3916 GEN_HANDLER(lfqu, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
3918 int ra = rA(ctx->opcode);
3920 /* NIP cannot be restored if the memory exception comes from an helper */
3921 gen_update_nip(ctx, ctx->nip - 4);
3922 gen_addr_imm_index(ctx);
3923 op_POWER2_lfq();
3924 gen_op_store_FT0_fpr(rD(ctx->opcode));
3925 gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
3926 if (ra != 0)
3927 gen_op_store_T0_gpr(ra);
3930 /* lfqux */
3931 GEN_HANDLER(lfqux, 0x1F, 0x17, 0x19, 0x00000001, PPC_POWER2)
3933 int ra = rA(ctx->opcode);
3935 /* NIP cannot be restored if the memory exception comes from an helper */
3936 gen_update_nip(ctx, ctx->nip - 4);
3937 gen_addr_reg_index(ctx);
3938 op_POWER2_lfq();
3939 gen_op_store_FT0_fpr(rD(ctx->opcode));
3940 gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
3941 if (ra != 0)
3942 gen_op_store_T0_gpr(ra);
3945 /* lfqx */
3946 GEN_HANDLER(lfqx, 0x1F, 0x17, 0x18, 0x00000001, PPC_POWER2)
3948 /* NIP cannot be restored if the memory exception comes from an helper */
3949 gen_update_nip(ctx, ctx->nip - 4);
3950 gen_addr_reg_index(ctx);
3951 op_POWER2_lfq();
3952 gen_op_store_FT0_fpr(rD(ctx->opcode));
3953 gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
3956 /* stfq */
3957 GEN_HANDLER(stfq, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
3959 /* NIP cannot be restored if the memory exception comes from an helper */
3960 gen_update_nip(ctx, ctx->nip - 4);
3961 gen_addr_imm_index(ctx);
3962 gen_op_load_fpr_FT0(rS(ctx->opcode));
3963 gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
3964 op_POWER2_stfq();
3967 /* stfqu */
3968 GEN_HANDLER(stfqu, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
3970 int ra = rA(ctx->opcode);
3972 /* NIP cannot be restored if the memory exception comes from an helper */
3973 gen_update_nip(ctx, ctx->nip - 4);
3974 gen_addr_imm_index(ctx);
3975 gen_op_load_fpr_FT0(rS(ctx->opcode));
3976 gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
3977 op_POWER2_stfq();
3978 if (ra != 0)
3979 gen_op_store_T0_gpr(ra);
3982 /* stfqux */
3983 GEN_HANDLER(stfqux, 0x1F, 0x17, 0x1D, 0x00000001, PPC_POWER2)
3985 int ra = rA(ctx->opcode);
3987 /* NIP cannot be restored if the memory exception comes from an helper */
3988 gen_update_nip(ctx, ctx->nip - 4);
3989 gen_addr_reg_index(ctx);
3990 gen_op_load_fpr_FT0(rS(ctx->opcode));
3991 gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
3992 op_POWER2_stfq();
3993 if (ra != 0)
3994 gen_op_store_T0_gpr(ra);
3997 /* stfqx */
3998 GEN_HANDLER(stfqx, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2)
4000 /* NIP cannot be restored if the memory exception comes from an helper */
4001 gen_update_nip(ctx, ctx->nip - 4);
4002 gen_addr_reg_index(ctx);
4003 gen_op_load_fpr_FT0(rS(ctx->opcode));
4004 gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4005 op_POWER2_stfq();
4008 /* BookE specific instructions */
4009 GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_BOOKE)
4011 /* XXX: TODO */
4012 RET_INVAL(ctx);
4015 GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_BOOKE)
4017 #if defined(CONFIG_USER_ONLY)
4018 RET_PRIVOPC(ctx);
4019 #else
4020 if (unlikely(!ctx->supervisor)) {
4021 RET_PRIVOPC(ctx);
4022 return;
4024 gen_addr_reg_index(ctx);
4025 /* Use the same micro-ops as for tlbie */
4026 #if defined(TARGET_PPC64)
4027 if (ctx->sf_mode)
4028 gen_op_tlbie_64();
4029 else
4030 #endif
4031 gen_op_tlbie();
4032 RET_STOP(ctx);
4033 #endif
4036 /* All 405 MAC instructions are translated here */
4037 static inline void gen_405_mulladd_insn (DisasContext *ctx, int opc2, int opc3,
4038 int ra, int rb, int rt, int Rc)
4040 gen_op_load_gpr_T0(ra);
4041 gen_op_load_gpr_T1(rb);
4042 switch (opc3 & 0x0D) {
4043 case 0x05:
4044 /* macchw - macchw. - macchwo - macchwo. */
4045 /* macchws - macchws. - macchwso - macchwso. */
4046 /* nmacchw - nmacchw. - nmacchwo - nmacchwo. */
4047 /* nmacchws - nmacchws. - nmacchwso - nmacchwso. */
4048 /* mulchw - mulchw. */
4049 gen_op_405_mulchw();
4050 break;
4051 case 0x04:
4052 /* macchwu - macchwu. - macchwuo - macchwuo. */
4053 /* macchwsu - macchwsu. - macchwsuo - macchwsuo. */
4054 /* mulchwu - mulchwu. */
4055 gen_op_405_mulchwu();
4056 break;
4057 case 0x01:
4058 /* machhw - machhw. - machhwo - machhwo. */
4059 /* machhws - machhws. - machhwso - machhwso. */
4060 /* nmachhw - nmachhw. - nmachhwo - nmachhwo. */
4061 /* nmachhws - nmachhws. - nmachhwso - nmachhwso. */
4062 /* mulhhw - mulhhw. */
4063 gen_op_405_mulhhw();
4064 break;
4065 case 0x00:
4066 /* machhwu - machhwu. - machhwuo - machhwuo. */
4067 /* machhwsu - machhwsu. - machhwsuo - machhwsuo. */
4068 /* mulhhwu - mulhhwu. */
4069 gen_op_405_mulhhwu();
4070 break;
4071 case 0x0D:
4072 /* maclhw - maclhw. - maclhwo - maclhwo. */
4073 /* maclhws - maclhws. - maclhwso - maclhwso. */
4074 /* nmaclhw - nmaclhw. - nmaclhwo - nmaclhwo. */
4075 /* nmaclhws - nmaclhws. - nmaclhwso - nmaclhwso. */
4076 /* mullhw - mullhw. */
4077 gen_op_405_mullhw();
4078 break;
4079 case 0x0C:
4080 /* maclhwu - maclhwu. - maclhwuo - maclhwuo. */
4081 /* maclhwsu - maclhwsu. - maclhwsuo - maclhwsuo. */
4082 /* mullhwu - mullhwu. */
4083 gen_op_405_mullhwu();
4084 break;
4086 if (opc2 & 0x02) {
4087 /* nmultiply-and-accumulate (0x0E) */
4088 gen_op_neg();
4090 if (opc2 & 0x04) {
4091 /* (n)multiply-and-accumulate (0x0C - 0x0E) */
4092 gen_op_load_gpr_T2(rt);
4093 gen_op_move_T1_T0();
4094 gen_op_405_add_T0_T2();
4096 if (opc3 & 0x10) {
4097 /* Check overflow */
4098 if (opc3 & 0x01)
4099 gen_op_405_check_ov();
4100 else
4101 gen_op_405_check_ovu();
4103 if (opc3 & 0x02) {
4104 /* Saturate */
4105 if (opc3 & 0x01)
4106 gen_op_405_check_sat();
4107 else
4108 gen_op_405_check_satu();
4110 gen_op_store_T0_gpr(rt);
4111 if (unlikely(Rc) != 0) {
4112 /* Update Rc0 */
4113 gen_set_Rc0(ctx);
4117 #define GEN_MAC_HANDLER(name, opc2, opc3) \
4118 GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC) \
4120 gen_405_mulladd_insn(ctx, opc2, opc3, rA(ctx->opcode), rB(ctx->opcode), \
4121 rD(ctx->opcode), Rc(ctx->opcode)); \
4124 /* macchw - macchw. */
4125 GEN_MAC_HANDLER(macchw, 0x0C, 0x05);
4126 /* macchwo - macchwo. */
4127 GEN_MAC_HANDLER(macchwo, 0x0C, 0x15);
4128 /* macchws - macchws. */
4129 GEN_MAC_HANDLER(macchws, 0x0C, 0x07);
4130 /* macchwso - macchwso. */
4131 GEN_MAC_HANDLER(macchwso, 0x0C, 0x17);
4132 /* macchwsu - macchwsu. */
4133 GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06);
4134 /* macchwsuo - macchwsuo. */
4135 GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16);
4136 /* macchwu - macchwu. */
4137 GEN_MAC_HANDLER(macchwu, 0x0C, 0x04);
4138 /* macchwuo - macchwuo. */
4139 GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14);
4140 /* machhw - machhw. */
4141 GEN_MAC_HANDLER(machhw, 0x0C, 0x01);
4142 /* machhwo - machhwo. */
4143 GEN_MAC_HANDLER(machhwo, 0x0C, 0x11);
4144 /* machhws - machhws. */
4145 GEN_MAC_HANDLER(machhws, 0x0C, 0x03);
4146 /* machhwso - machhwso. */
4147 GEN_MAC_HANDLER(machhwso, 0x0C, 0x13);
4148 /* machhwsu - machhwsu. */
4149 GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02);
4150 /* machhwsuo - machhwsuo. */
4151 GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12);
4152 /* machhwu - machhwu. */
4153 GEN_MAC_HANDLER(machhwu, 0x0C, 0x00);
4154 /* machhwuo - machhwuo. */
4155 GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10);
4156 /* maclhw - maclhw. */
4157 GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D);
4158 /* maclhwo - maclhwo. */
4159 GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D);
4160 /* maclhws - maclhws. */
4161 GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F);
4162 /* maclhwso - maclhwso. */
4163 GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F);
4164 /* maclhwu - maclhwu. */
4165 GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C);
4166 /* maclhwuo - maclhwuo. */
4167 GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C);
4168 /* maclhwsu - maclhwsu. */
4169 GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E);
4170 /* maclhwsuo - maclhwsuo. */
4171 GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E);
4172 /* nmacchw - nmacchw. */
4173 GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05);
4174 /* nmacchwo - nmacchwo. */
4175 GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15);
4176 /* nmacchws - nmacchws. */
4177 GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07);
4178 /* nmacchwso - nmacchwso. */
4179 GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17);
4180 /* nmachhw - nmachhw. */
4181 GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01);
4182 /* nmachhwo - nmachhwo. */
4183 GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11);
4184 /* nmachhws - nmachhws. */
4185 GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03);
4186 /* nmachhwso - nmachhwso. */
4187 GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13);
4188 /* nmaclhw - nmaclhw. */
4189 GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D);
4190 /* nmaclhwo - nmaclhwo. */
4191 GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D);
4192 /* nmaclhws - nmaclhws. */
4193 GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F);
4194 /* nmaclhwso - nmaclhwso. */
4195 GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F);
4197 /* mulchw - mulchw. */
4198 GEN_MAC_HANDLER(mulchw, 0x08, 0x05);
4199 /* mulchwu - mulchwu. */
4200 GEN_MAC_HANDLER(mulchwu, 0x08, 0x04);
4201 /* mulhhw - mulhhw. */
4202 GEN_MAC_HANDLER(mulhhw, 0x08, 0x01);
4203 /* mulhhwu - mulhhwu. */
4204 GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00);
4205 /* mullhw - mullhw. */
4206 GEN_MAC_HANDLER(mullhw, 0x08, 0x0D);
4207 /* mullhwu - mullhwu. */
4208 GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C);
4210 /* mfdcr */
4211 GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_EMB_COMMON)
4213 #if defined(CONFIG_USER_ONLY)
4214 RET_PRIVREG(ctx);
4215 #else
4216 uint32_t dcrn = SPR(ctx->opcode);
4218 if (unlikely(!ctx->supervisor)) {
4219 RET_PRIVREG(ctx);
4220 return;
4222 gen_op_4xx_load_dcr(dcrn);
4223 gen_op_store_T0_gpr(rD(ctx->opcode));
4224 #endif
4227 /* mtdcr */
4228 GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_EMB_COMMON)
4230 #if defined(CONFIG_USER_ONLY)
4231 RET_PRIVREG(ctx);
4232 #else
4233 uint32_t dcrn = SPR(ctx->opcode);
4235 if (unlikely(!ctx->supervisor)) {
4236 RET_PRIVREG(ctx);
4237 return;
4239 gen_op_load_gpr_T0(rS(ctx->opcode));
4240 gen_op_4xx_store_dcr(dcrn);
4241 #endif
4244 /* dccci */
4245 GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON)
4247 #if defined(CONFIG_USER_ONLY)
4248 RET_PRIVOPC(ctx);
4249 #else
4250 if (unlikely(!ctx->supervisor)) {
4251 RET_PRIVOPC(ctx);
4252 return;
4254 /* interpreted as no-op */
4255 #endif
4258 /* dcread */
4259 GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON)
4261 #if defined(CONFIG_USER_ONLY)
4262 RET_PRIVOPC(ctx);
4263 #else
4264 if (unlikely(!ctx->supervisor)) {
4265 RET_PRIVOPC(ctx);
4266 return;
4268 gen_addr_reg_index(ctx);
4269 op_ldst(lwz);
4270 gen_op_store_T0_gpr(rD(ctx->opcode));
4271 #endif
4274 /* icbt */
4275 GEN_HANDLER(icbt_40x, 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_SPEC)
4277 /* interpreted as no-op */
4278 /* XXX: specification say this is treated as a load by the MMU
4279 * but does not generate any exception
4283 /* iccci */
4284 GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON)
4286 #if defined(CONFIG_USER_ONLY)
4287 RET_PRIVOPC(ctx);
4288 #else
4289 if (unlikely(!ctx->supervisor)) {
4290 RET_PRIVOPC(ctx);
4291 return;
4293 /* interpreted as no-op */
4294 #endif
4297 /* icread */
4298 GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON)
4300 #if defined(CONFIG_USER_ONLY)
4301 RET_PRIVOPC(ctx);
4302 #else
4303 if (unlikely(!ctx->supervisor)) {
4304 RET_PRIVOPC(ctx);
4305 return;
4307 /* interpreted as no-op */
4308 #endif
4311 /* rfci (supervisor only) */
4312 GEN_HANDLER(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_EMB_COMMON)
4314 #if defined(CONFIG_USER_ONLY)
4315 RET_PRIVOPC(ctx);
4316 #else
4317 if (unlikely(!ctx->supervisor)) {
4318 RET_PRIVOPC(ctx);
4319 return;
4321 /* Restore CPU state */
4322 gen_op_4xx_rfci();
4323 RET_CHG_FLOW(ctx);
4324 #endif
4327 /* TLB management - PowerPC 405 implementation */
4328 /* tlbre */
4329 GEN_HANDLER(tlbre, 0x1F, 0x12, 0x1D, 0x00000001, PPC_EMB_COMMON)
4331 #if defined(CONFIG_USER_ONLY)
4332 RET_PRIVOPC(ctx);
4333 #else
4334 if (unlikely(!ctx->supervisor)) {
4335 RET_PRIVOPC(ctx);
4336 return;
4338 switch (rB(ctx->opcode)) {
4339 case 0:
4340 gen_op_load_gpr_T0(rA(ctx->opcode));
4341 gen_op_4xx_tlbre_hi();
4342 gen_op_store_T0_gpr(rD(ctx->opcode));
4343 break;
4344 case 1:
4345 gen_op_load_gpr_T0(rA(ctx->opcode));
4346 gen_op_4xx_tlbre_lo();
4347 gen_op_store_T0_gpr(rD(ctx->opcode));
4348 break;
4349 default:
4350 RET_INVAL(ctx);
4351 break;
4353 #endif
4356 /* tlbsx - tlbsx. */
4357 GEN_HANDLER(tlbsx, 0x1F, 0x12, 0x1C, 0x00000000, PPC_EMB_COMMON)
4359 #if defined(CONFIG_USER_ONLY)
4360 RET_PRIVOPC(ctx);
4361 #else
4362 if (unlikely(!ctx->supervisor)) {
4363 RET_PRIVOPC(ctx);
4364 return;
4366 gen_addr_reg_index(ctx);
4367 if (Rc(ctx->opcode))
4368 gen_op_4xx_tlbsx_();
4369 else
4370 gen_op_4xx_tlbsx();
4371 gen_op_store_T0_gpr(rD(ctx->opcode));
4372 #endif
4375 /* tlbwe */
4376 GEN_HANDLER(tlbwe, 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_SPEC)
4378 #if defined(CONFIG_USER_ONLY)
4379 RET_PRIVOPC(ctx);
4380 #else
4381 if (unlikely(!ctx->supervisor)) {
4382 RET_PRIVOPC(ctx);
4383 return;
4385 switch (rB(ctx->opcode)) {
4386 case 0:
4387 gen_op_load_gpr_T0(rA(ctx->opcode));
4388 gen_op_load_gpr_T1(rS(ctx->opcode));
4389 gen_op_4xx_tlbwe_hi();
4390 break;
4391 case 1:
4392 gen_op_load_gpr_T0(rA(ctx->opcode));
4393 gen_op_load_gpr_T1(rS(ctx->opcode));
4394 gen_op_4xx_tlbwe_lo();
4395 break;
4396 default:
4397 RET_INVAL(ctx);
4398 break;
4400 #endif
4403 /* wrtee */
4404 GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_EMB_COMMON)
4406 #if defined(CONFIG_USER_ONLY)
4407 RET_PRIVOPC(ctx);
4408 #else
4409 if (unlikely(!ctx->supervisor)) {
4410 RET_PRIVOPC(ctx);
4411 return;
4413 gen_op_load_gpr_T0(rD(ctx->opcode));
4414 gen_op_4xx_wrte();
4415 RET_EXCP(ctx, EXCP_MTMSR, 0);
4416 #endif
4419 /* wrteei */
4420 GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000EFC01, PPC_EMB_COMMON)
4422 #if defined(CONFIG_USER_ONLY)
4423 RET_PRIVOPC(ctx);
4424 #else
4425 if (unlikely(!ctx->supervisor)) {
4426 RET_PRIVOPC(ctx);
4427 return;
4429 gen_op_set_T0(ctx->opcode & 0x00010000);
4430 gen_op_4xx_wrte();
4431 RET_EXCP(ctx, EXCP_MTMSR, 0);
4432 #endif
4435 /* PPC 440 specific instructions */
4436 /* dlmzb */
4437 GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC)
4439 gen_op_load_gpr_T0(rS(ctx->opcode));
4440 gen_op_load_gpr_T1(rB(ctx->opcode));
4441 gen_op_440_dlmzb();
4442 gen_op_store_T0_gpr(rA(ctx->opcode));
4443 gen_op_store_xer_bc();
4444 if (Rc(ctx->opcode)) {
4445 gen_op_440_dlmzb_update_Rc();
4446 gen_op_store_T0_crf(0);
4450 /* mbar replaces eieio on 440 */
4451 GEN_HANDLER(mbar, 0x1F, 0x16, 0x13, 0x001FF801, PPC_BOOKE)
4453 /* interpreted as no-op */
4456 /* msync replaces sync on 440 */
4457 GEN_HANDLER(msync, 0x1F, 0x16, 0x12, 0x03FF0801, PPC_BOOKE)
4459 /* interpreted as no-op */
4462 /* icbt */
4463 GEN_HANDLER(icbt_440, 0x1F, 0x16, 0x00, 0x03E00001, PPC_BOOKE)
4465 /* interpreted as no-op */
4466 /* XXX: specification say this is treated as a load by the MMU
4467 * but does not generate any exception
4471 /* End opcode list */
4472 GEN_OPCODE_MARK(end);
4474 #include "translate_init.c"
4476 /*****************************************************************************/
4477 /* Misc PowerPC helpers */
4478 static inline uint32_t load_xer (CPUState *env)
4480 return (xer_so << XER_SO) |
4481 (xer_ov << XER_OV) |
4482 (xer_ca << XER_CA) |
4483 (xer_bc << XER_BC) |
4484 (xer_cmp << XER_CMP);
4487 void cpu_dump_state(CPUState *env, FILE *f,
4488 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
4489 int flags)
4491 #if defined(TARGET_PPC64) || 1
4492 #define FILL ""
4493 #define RGPL 4
4494 #define RFPL 4
4495 #else
4496 #define FILL " "
4497 #define RGPL 8
4498 #define RFPL 4
4499 #endif
4501 int i;
4503 cpu_fprintf(f, "NIP " REGX " LR " REGX " CTR " REGX "\n",
4504 env->nip, env->lr, env->ctr);
4505 cpu_fprintf(f, "MSR " REGX FILL " XER %08x "
4506 #if !defined(NO_TIMER_DUMP)
4507 "TB %08x %08x "
4508 #if !defined(CONFIG_USER_ONLY)
4509 "DECR %08x"
4510 #endif
4511 #endif
4512 "\n",
4513 do_load_msr(env), load_xer(env)
4514 #if !defined(NO_TIMER_DUMP)
4515 , cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
4516 #if !defined(CONFIG_USER_ONLY)
4517 , cpu_ppc_load_decr(env)
4518 #endif
4519 #endif
4521 for (i = 0; i < 32; i++) {
4522 if ((i & (RGPL - 1)) == 0)
4523 cpu_fprintf(f, "GPR%02d", i);
4524 cpu_fprintf(f, " " REGX, env->gpr[i]);
4525 if ((i & (RGPL - 1)) == (RGPL - 1))
4526 cpu_fprintf(f, "\n");
4528 cpu_fprintf(f, "CR ");
4529 for (i = 0; i < 8; i++)
4530 cpu_fprintf(f, "%01x", env->crf[i]);
4531 cpu_fprintf(f, " [");
4532 for (i = 0; i < 8; i++) {
4533 char a = '-';
4534 if (env->crf[i] & 0x08)
4535 a = 'L';
4536 else if (env->crf[i] & 0x04)
4537 a = 'G';
4538 else if (env->crf[i] & 0x02)
4539 a = 'E';
4540 cpu_fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
4542 cpu_fprintf(f, " ] " FILL "RES " REGX "\n", env->reserve);
4543 for (i = 0; i < 32; i++) {
4544 if ((i & (RFPL - 1)) == 0)
4545 cpu_fprintf(f, "FPR%02d", i);
4546 cpu_fprintf(f, " %016" PRIx64, *((uint64_t *)&env->fpr[i]));
4547 if ((i & (RFPL - 1)) == (RFPL - 1))
4548 cpu_fprintf(f, "\n");
4550 cpu_fprintf(f, "SRR0 " REGX " SRR1 " REGX " " FILL FILL FILL
4551 "SDR1 " REGX "\n",
4552 env->spr[SPR_SRR0], env->spr[SPR_SRR1], env->sdr1);
4554 #undef RGPL
4555 #undef RFPL
4556 #undef FILL
4559 void cpu_dump_statistics (CPUState *env, FILE*f,
4560 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
4561 int flags)
4563 #if defined(DO_PPC_STATISTICS)
4564 opc_handler_t **t1, **t2, **t3, *handler;
4565 int op1, op2, op3;
4567 t1 = env->opcodes;
4568 for (op1 = 0; op1 < 64; op1++) {
4569 handler = t1[op1];
4570 if (is_indirect_opcode(handler)) {
4571 t2 = ind_table(handler);
4572 for (op2 = 0; op2 < 32; op2++) {
4573 handler = t2[op2];
4574 if (is_indirect_opcode(handler)) {
4575 t3 = ind_table(handler);
4576 for (op3 = 0; op3 < 32; op3++) {
4577 handler = t3[op3];
4578 if (handler->count == 0)
4579 continue;
4580 cpu_fprintf(f, "%02x %02x %02x (%02x %04d) %16s: "
4581 "%016llx %lld\n",
4582 op1, op2, op3, op1, (op3 << 5) | op2,
4583 handler->oname,
4584 handler->count, handler->count);
4586 } else {
4587 if (handler->count == 0)
4588 continue;
4589 cpu_fprintf(f, "%02x %02x (%02x %04d) %16s: "
4590 "%016llx %lld\n",
4591 op1, op2, op1, op2, handler->oname,
4592 handler->count, handler->count);
4595 } else {
4596 if (handler->count == 0)
4597 continue;
4598 cpu_fprintf(f, "%02x (%02x ) %16s: %016llx %lld\n",
4599 op1, op1, handler->oname,
4600 handler->count, handler->count);
4603 #endif
4606 /*****************************************************************************/
4607 int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
4608 int search_pc)
4610 DisasContext ctx, *ctxp = &ctx;
4611 opc_handler_t **table, *handler;
4612 target_ulong pc_start;
4613 uint16_t *gen_opc_end;
4614 int j, lj = -1;
4616 pc_start = tb->pc;
4617 gen_opc_ptr = gen_opc_buf;
4618 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
4619 gen_opparam_ptr = gen_opparam_buf;
4620 nb_gen_labels = 0;
4621 ctx.nip = pc_start;
4622 ctx.tb = tb;
4623 ctx.exception = EXCP_NONE;
4624 ctx.spr_cb = env->spr_cb;
4625 #if defined(CONFIG_USER_ONLY)
4626 ctx.mem_idx = msr_le;
4627 #if defined(TARGET_PPC64)
4628 ctx.mem_idx |= msr_sf << 1;
4629 #endif
4630 #else
4631 ctx.supervisor = 1 - msr_pr;
4632 ctx.mem_idx = ((1 - msr_pr) << 1) | msr_le;
4633 #if defined(TARGET_PPC64)
4634 ctx.mem_idx |= msr_sf << 2;
4635 #endif
4636 #endif
4637 #if defined(TARGET_PPC64)
4638 ctx.sf_mode = msr_sf;
4639 #endif
4640 ctx.fpu_enabled = msr_fp;
4641 ctx.singlestep_enabled = env->singlestep_enabled;
4642 #if defined (DO_SINGLE_STEP) && 0
4643 /* Single step trace mode */
4644 msr_se = 1;
4645 #endif
4646 /* Set env in case of segfault during code fetch */
4647 while (ctx.exception == EXCP_NONE && gen_opc_ptr < gen_opc_end) {
4648 if (unlikely(env->nb_breakpoints > 0)) {
4649 for (j = 0; j < env->nb_breakpoints; j++) {
4650 if (env->breakpoints[j] == ctx.nip) {
4651 gen_update_nip(&ctx, ctx.nip);
4652 gen_op_debug();
4653 break;
4657 if (unlikely(search_pc)) {
4658 j = gen_opc_ptr - gen_opc_buf;
4659 if (lj < j) {
4660 lj++;
4661 while (lj < j)
4662 gen_opc_instr_start[lj++] = 0;
4663 gen_opc_pc[lj] = ctx.nip;
4664 gen_opc_instr_start[lj] = 1;
4667 #if defined PPC_DEBUG_DISAS
4668 if (loglevel & CPU_LOG_TB_IN_ASM) {
4669 fprintf(logfile, "----------------\n");
4670 fprintf(logfile, "nip=%08x super=%d ir=%d\n",
4671 ctx.nip, 1 - msr_pr, msr_ir);
4673 #endif
4674 ctx.opcode = ldl_code(ctx.nip);
4675 if (msr_le) {
4676 ctx.opcode = ((ctx.opcode & 0xFF000000) >> 24) |
4677 ((ctx.opcode & 0x00FF0000) >> 8) |
4678 ((ctx.opcode & 0x0000FF00) << 8) |
4679 ((ctx.opcode & 0x000000FF) << 24);
4681 #if defined PPC_DEBUG_DISAS
4682 if (loglevel & CPU_LOG_TB_IN_ASM) {
4683 fprintf(logfile, "translate opcode %08x (%02x %02x %02x) (%s)\n",
4684 ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
4685 opc3(ctx.opcode), msr_le ? "little" : "big");
4687 #endif
4688 ctx.nip += 4;
4689 table = env->opcodes;
4690 handler = table[opc1(ctx.opcode)];
4691 if (is_indirect_opcode(handler)) {
4692 table = ind_table(handler);
4693 handler = table[opc2(ctx.opcode)];
4694 if (is_indirect_opcode(handler)) {
4695 table = ind_table(handler);
4696 handler = table[opc3(ctx.opcode)];
4699 /* Is opcode *REALLY* valid ? */
4700 if (unlikely(handler->handler == &gen_invalid)) {
4701 if (loglevel > 0) {
4702 fprintf(logfile, "invalid/unsupported opcode: "
4703 "%02x - %02x - %02x (%08x) 0x" REGX " %d\n",
4704 opc1(ctx.opcode), opc2(ctx.opcode),
4705 opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, msr_ir);
4706 } else {
4707 printf("invalid/unsupported opcode: "
4708 "%02x - %02x - %02x (%08x) 0x" REGX " %d\n",
4709 opc1(ctx.opcode), opc2(ctx.opcode),
4710 opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, msr_ir);
4712 } else {
4713 if (unlikely((ctx.opcode & handler->inval) != 0)) {
4714 if (loglevel > 0) {
4715 fprintf(logfile, "invalid bits: %08x for opcode: "
4716 "%02x -%02x - %02x (%08x) " REGX "\n",
4717 ctx.opcode & handler->inval, opc1(ctx.opcode),
4718 opc2(ctx.opcode), opc3(ctx.opcode),
4719 ctx.opcode, ctx.nip - 4);
4720 } else {
4721 printf("invalid bits: %08x for opcode: "
4722 "%02x -%02x - %02x (%08x) " REGX "\n",
4723 ctx.opcode & handler->inval, opc1(ctx.opcode),
4724 opc2(ctx.opcode), opc3(ctx.opcode),
4725 ctx.opcode, ctx.nip - 4);
4727 RET_INVAL(ctxp);
4728 break;
4731 (*(handler->handler))(&ctx);
4732 #if defined(DO_PPC_STATISTICS)
4733 handler->count++;
4734 #endif
4735 /* Check trace mode exceptions */
4736 if (unlikely((msr_be && ctx.exception == EXCP_BRANCH) ||
4737 /* Check in single step trace mode
4738 * we need to stop except if:
4739 * - rfi, trap or syscall
4740 * - first instruction of an exception handler
4742 (msr_se && (ctx.nip < 0x100 ||
4743 ctx.nip > 0xF00 ||
4744 (ctx.nip & 0xFC) != 0x04) &&
4745 ctx.exception != EXCP_SYSCALL &&
4746 ctx.exception != EXCP_SYSCALL_USER &&
4747 ctx.exception != EXCP_TRAP))) {
4748 RET_EXCP(ctxp, EXCP_TRACE, 0);
4750 /* if we reach a page boundary or are single stepping, stop
4751 * generation
4753 if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
4754 (env->singlestep_enabled))) {
4755 break;
4757 #if defined (DO_SINGLE_STEP)
4758 break;
4759 #endif
4761 if (ctx.exception == EXCP_NONE) {
4762 gen_goto_tb(&ctx, 0, ctx.nip);
4763 } else if (ctx.exception != EXCP_BRANCH) {
4764 gen_op_reset_T0();
4765 /* Generate the return instruction */
4766 gen_op_exit_tb();
4768 *gen_opc_ptr = INDEX_op_end;
4769 if (unlikely(search_pc)) {
4770 j = gen_opc_ptr - gen_opc_buf;
4771 lj++;
4772 while (lj <= j)
4773 gen_opc_instr_start[lj++] = 0;
4774 tb->size = 0;
4775 } else {
4776 tb->size = ctx.nip - pc_start;
4778 #if defined(DEBUG_DISAS)
4779 if (loglevel & CPU_LOG_TB_CPU) {
4780 fprintf(logfile, "---------------- excp: %04x\n", ctx.exception);
4781 cpu_dump_state(env, logfile, fprintf, 0);
4783 if (loglevel & CPU_LOG_TB_IN_ASM) {
4784 int flags;
4785 flags = msr_le;
4786 fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
4787 target_disas(logfile, pc_start, ctx.nip - pc_start, flags);
4788 fprintf(logfile, "\n");
4790 if (loglevel & CPU_LOG_TB_OP) {
4791 fprintf(logfile, "OP:\n");
4792 dump_ops(gen_opc_buf, gen_opparam_buf);
4793 fprintf(logfile, "\n");
4795 #endif
4796 return 0;
4799 int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
4801 return gen_intermediate_code_internal(env, tb, 0);
4804 int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
4806 return gen_intermediate_code_internal(env, tb, 1);