]> Git Repo - qemu.git/blob - target-ppc/translate.c
Synchronize with latest PowerPC ISA VEA:
[qemu.git] / target-ppc / translate.c
1 /*
2  *  PowerPC emulation for qemu: main translation routines.
3  *
4  *  Copyright (c) 2003-2007 Jocelyn Mayer
5  *
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.
10  *
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.
15  *
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
19  */
20 #include <stdarg.h>
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <inttypes.h>
25
26 #include "cpu.h"
27 #include "exec-all.h"
28 #include "disas.h"
29
30 /* Include definitions for instructions classes and implementations flags */
31 //#define DO_SINGLE_STEP
32 //#define PPC_DEBUG_DISAS
33 //#define DEBUG_MEMORY_ACCESSES
34 //#define DO_PPC_STATISTICS
35
36 /*****************************************************************************/
37 /* Code translation helpers                                                  */
38 #if defined(USE_DIRECT_JUMP)
39 #define TBPARAM(x)
40 #else
41 #define TBPARAM(x) (long)(x)
42 #endif
43
44 enum {
45 #define DEF(s, n, copy_size) INDEX_op_ ## s,
46 #include "opc.h"
47 #undef DEF
48     NB_OPS,
49 };
50
51 static uint16_t *gen_opc_ptr;
52 static uint32_t *gen_opparam_ptr;
53
54 #include "gen-op.h"
55
56 static inline void gen_set_T0 (target_ulong val)
57 {
58 #if defined(TARGET_PPC64)
59     if (val >> 32)
60         gen_op_set_T0_64(val >> 32, val);
61     else
62 #endif
63         gen_op_set_T0(val);
64 }
65
66 static inline void gen_set_T1 (target_ulong val)
67 {
68 #if defined(TARGET_PPC64)
69     if (val >> 32)
70         gen_op_set_T1_64(val >> 32, val);
71     else
72 #endif
73         gen_op_set_T1(val);
74 }
75
76 #define GEN8(func, NAME)                                                      \
77 static GenOpFunc *NAME ## _table [8] = {                                      \
78 NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
79 NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
80 };                                                                            \
81 static inline void func(int n)                                                \
82 {                                                                             \
83     NAME ## _table[n]();                                                      \
84 }
85
86 #define GEN16(func, NAME)                                                     \
87 static GenOpFunc *NAME ## _table [16] = {                                     \
88 NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
89 NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
90 NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11,                                 \
91 NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
92 };                                                                            \
93 static inline void func(int n)                                                \
94 {                                                                             \
95     NAME ## _table[n]();                                                      \
96 }
97
98 #define GEN32(func, NAME)                                                     \
99 static GenOpFunc *NAME ## _table [32] = {                                     \
100 NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
101 NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
102 NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11,                                 \
103 NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
104 NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,                               \
105 NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,                               \
106 NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,                               \
107 NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,                               \
108 };                                                                            \
109 static inline void func(int n)                                                \
110 {                                                                             \
111     NAME ## _table[n]();                                                      \
112 }
113
114 /* Condition register moves */
115 GEN8(gen_op_load_crf_T0, gen_op_load_crf_T0_crf);
116 GEN8(gen_op_load_crf_T1, gen_op_load_crf_T1_crf);
117 GEN8(gen_op_store_T0_crf, gen_op_store_T0_crf_crf);
118 GEN8(gen_op_store_T1_crf, gen_op_store_T1_crf_crf);
119
120 /* Floating point condition and status register moves */
121 GEN8(gen_op_load_fpscr_T0, gen_op_load_fpscr_T0_fpscr);
122 GEN8(gen_op_store_T0_fpscr, gen_op_store_T0_fpscr_fpscr);
123 GEN8(gen_op_clear_fpscr, gen_op_clear_fpscr_fpscr);
124 static inline void gen_op_store_T0_fpscri (int n, uint8_t param)
125 {
126     gen_op_set_T0(param);
127     gen_op_store_T0_fpscr(n);
128 }
129
130 /* General purpose registers moves */
131 GEN32(gen_op_load_gpr_T0, gen_op_load_gpr_T0_gpr);
132 GEN32(gen_op_load_gpr_T1, gen_op_load_gpr_T1_gpr);
133 GEN32(gen_op_load_gpr_T2, gen_op_load_gpr_T2_gpr);
134
135 GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr);
136 GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr);
137 #if 0 // unused
138 GEN32(gen_op_store_T2_gpr, gen_op_store_T2_gpr_gpr);
139 #endif
140
141 /* floating point registers moves */
142 GEN32(gen_op_load_fpr_FT0, gen_op_load_fpr_FT0_fpr);
143 GEN32(gen_op_load_fpr_FT1, gen_op_load_fpr_FT1_fpr);
144 GEN32(gen_op_load_fpr_FT2, gen_op_load_fpr_FT2_fpr);
145 GEN32(gen_op_store_FT0_fpr, gen_op_store_FT0_fpr_fpr);
146 GEN32(gen_op_store_FT1_fpr, gen_op_store_FT1_fpr_fpr);
147 #if 0 // unused
148 GEN32(gen_op_store_FT2_fpr, gen_op_store_FT2_fpr_fpr);
149 #endif
150
151 /* internal defines */
152 typedef struct DisasContext {
153     struct TranslationBlock *tb;
154     target_ulong nip;
155     uint32_t opcode;
156     uint32_t exception;
157     /* Routine used to access memory */
158     int mem_idx;
159     /* Translation flags */
160 #if !defined(CONFIG_USER_ONLY)
161     int supervisor;
162 #endif
163 #if defined(TARGET_PPC64)
164     int sf_mode;
165 #endif
166     int fpu_enabled;
167 #if defined(TARGET_PPCEMB)
168     int spe_enabled;
169 #endif
170     ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
171     int singlestep_enabled;
172 } DisasContext;
173
174 struct opc_handler_t {
175     /* invalid bits */
176     uint32_t inval;
177     /* instruction type */
178     uint64_t type;
179     /* handler */
180     void (*handler)(DisasContext *ctx);
181 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
182     const unsigned char *oname;
183 #endif
184 #if defined(DO_PPC_STATISTICS)
185     uint64_t count;
186 #endif
187 };
188
189 static inline void gen_set_Rc0 (DisasContext *ctx)
190 {
191 #if defined(TARGET_PPC64)
192     if (ctx->sf_mode)
193         gen_op_cmpi_64(0);
194     else
195 #endif
196         gen_op_cmpi(0);
197     gen_op_set_Rc0();
198 }
199
200 static inline void gen_update_nip (DisasContext *ctx, target_ulong nip)
201 {
202 #if defined(TARGET_PPC64)
203     if (ctx->sf_mode)
204         gen_op_update_nip_64(nip >> 32, nip);
205     else
206 #endif
207         gen_op_update_nip(nip);
208 }
209
210 #define GEN_EXCP(ctx, excp, error)                                            \
211 do {                                                                          \
212     if ((ctx)->exception == POWERPC_EXCP_NONE) {                              \
213         gen_update_nip(ctx, (ctx)->nip);                                      \
214     }                                                                         \
215     gen_op_raise_exception_err((excp), (error));                              \
216     ctx->exception = (excp);                                                  \
217 } while (0)
218
219 #define GEN_EXCP_INVAL(ctx)                                                   \
220 GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM,                                         \
221          POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL)
222
223 #define GEN_EXCP_PRIVOPC(ctx)                                                 \
224 GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM,                                         \
225          POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_OPC)
226
227 #define GEN_EXCP_PRIVREG(ctx)                                                 \
228 GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM,                                         \
229          POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_REG)
230
231 #define GEN_EXCP_NO_FP(ctx)                                                   \
232 GEN_EXCP(ctx, POWERPC_EXCP_FPU, 0)
233
234 #define GEN_EXCP_NO_AP(ctx)                                                   \
235 GEN_EXCP(ctx, POWERPC_EXCP_APU, 0)
236
237 /* Stop translation */
238 static inline void GEN_STOP (DisasContext *ctx)
239 {
240     gen_update_nip(ctx, ctx->nip);
241     ctx->exception = POWERPC_EXCP_STOP;
242 }
243
244 /* No need to update nip here, as execution flow will change */
245 static inline void GEN_SYNC (DisasContext *ctx)
246 {
247     ctx->exception = POWERPC_EXCP_SYNC;
248 }
249
250 #define GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                      \
251 static void gen_##name (DisasContext *ctx);                                   \
252 GEN_OPCODE(name, opc1, opc2, opc3, inval, type);                              \
253 static void gen_##name (DisasContext *ctx)
254
255 typedef struct opcode_t {
256     unsigned char opc1, opc2, opc3;
257 #if HOST_LONG_BITS == 64 /* Explicitely align to 64 bits */
258     unsigned char pad[5];
259 #else
260     unsigned char pad[1];
261 #endif
262     opc_handler_t handler;
263     const unsigned char *oname;
264 } opcode_t;
265
266 /*****************************************************************************/
267 /***                           Instruction decoding                        ***/
268 #define EXTRACT_HELPER(name, shift, nb)                                       \
269 static inline uint32_t name (uint32_t opcode)                                 \
270 {                                                                             \
271     return (opcode >> (shift)) & ((1 << (nb)) - 1);                           \
272 }
273
274 #define EXTRACT_SHELPER(name, shift, nb)                                      \
275 static inline int32_t name (uint32_t opcode)                                  \
276 {                                                                             \
277     return (int16_t)((opcode >> (shift)) & ((1 << (nb)) - 1));                \
278 }
279
280 /* Opcode part 1 */
281 EXTRACT_HELPER(opc1, 26, 6);
282 /* Opcode part 2 */
283 EXTRACT_HELPER(opc2, 1, 5);
284 /* Opcode part 3 */
285 EXTRACT_HELPER(opc3, 6, 5);
286 /* Update Cr0 flags */
287 EXTRACT_HELPER(Rc, 0, 1);
288 /* Destination */
289 EXTRACT_HELPER(rD, 21, 5);
290 /* Source */
291 EXTRACT_HELPER(rS, 21, 5);
292 /* First operand */
293 EXTRACT_HELPER(rA, 16, 5);
294 /* Second operand */
295 EXTRACT_HELPER(rB, 11, 5);
296 /* Third operand */
297 EXTRACT_HELPER(rC, 6, 5);
298 /***                               Get CRn                                 ***/
299 EXTRACT_HELPER(crfD, 23, 3);
300 EXTRACT_HELPER(crfS, 18, 3);
301 EXTRACT_HELPER(crbD, 21, 5);
302 EXTRACT_HELPER(crbA, 16, 5);
303 EXTRACT_HELPER(crbB, 11, 5);
304 /* SPR / TBL */
305 EXTRACT_HELPER(_SPR, 11, 10);
306 static inline uint32_t SPR (uint32_t opcode)
307 {
308     uint32_t sprn = _SPR(opcode);
309
310     return ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
311 }
312 /***                              Get constants                            ***/
313 EXTRACT_HELPER(IMM, 12, 8);
314 /* 16 bits signed immediate value */
315 EXTRACT_SHELPER(SIMM, 0, 16);
316 /* 16 bits unsigned immediate value */
317 EXTRACT_HELPER(UIMM, 0, 16);
318 /* Bit count */
319 EXTRACT_HELPER(NB, 11, 5);
320 /* Shift count */
321 EXTRACT_HELPER(SH, 11, 5);
322 /* Mask start */
323 EXTRACT_HELPER(MB, 6, 5);
324 /* Mask end */
325 EXTRACT_HELPER(ME, 1, 5);
326 /* Trap operand */
327 EXTRACT_HELPER(TO, 21, 5);
328
329 EXTRACT_HELPER(CRM, 12, 8);
330 EXTRACT_HELPER(FM, 17, 8);
331 EXTRACT_HELPER(SR, 16, 4);
332 EXTRACT_HELPER(FPIMM, 20, 4);
333
334 /***                            Jump target decoding                       ***/
335 /* Displacement */
336 EXTRACT_SHELPER(d, 0, 16);
337 /* Immediate address */
338 static inline target_ulong LI (uint32_t opcode)
339 {
340     return (opcode >> 0) & 0x03FFFFFC;
341 }
342
343 static inline uint32_t BD (uint32_t opcode)
344 {
345     return (opcode >> 0) & 0xFFFC;
346 }
347
348 EXTRACT_HELPER(BO, 21, 5);
349 EXTRACT_HELPER(BI, 16, 5);
350 /* Absolute/relative address */
351 EXTRACT_HELPER(AA, 1, 1);
352 /* Link */
353 EXTRACT_HELPER(LK, 0, 1);
354
355 /* Create a mask between <start> and <end> bits */
356 static inline target_ulong MASK (uint32_t start, uint32_t end)
357 {
358     target_ulong ret;
359
360 #if defined(TARGET_PPC64)
361     if (likely(start == 0)) {
362         ret = (uint64_t)(-1ULL) << (63 - end);
363     } else if (likely(end == 63)) {
364         ret = (uint64_t)(-1ULL) >> start;
365     }
366 #else
367     if (likely(start == 0)) {
368         ret = (uint32_t)(-1ULL) << (31  - end);
369     } else if (likely(end == 31)) {
370         ret = (uint32_t)(-1ULL) >> start;
371     }
372 #endif
373     else {
374         ret = (((target_ulong)(-1ULL)) >> (start)) ^
375             (((target_ulong)(-1ULL) >> (end)) >> 1);
376         if (unlikely(start > end))
377             return ~ret;
378     }
379
380     return ret;
381 }
382
383 /*****************************************************************************/
384 /* PowerPC Instructions types definitions                                    */
385 enum {
386     PPC_NONE          = 0x0000000000000000ULL,
387     /* integer operations instructions                  */
388     /* flow control instructions                        */
389     /* virtual memory instructions                      */
390     /* ld/st with reservation instructions              */
391     /* cache control instructions                       */
392     /* spr/msr access instructions                      */
393     PPC_INSNS_BASE    = 0x0000000000000001ULL,
394 #define PPC_INTEGER PPC_INSNS_BASE
395 #define PPC_FLOW    PPC_INSNS_BASE
396 #define PPC_MEM     PPC_INSNS_BASE
397 #define PPC_RES     PPC_INSNS_BASE
398 #define PPC_CACHE   PPC_INSNS_BASE
399 #define PPC_MISC    PPC_INSNS_BASE
400     /* Optional floating point instructions             */
401     PPC_FLOAT         = 0x0000000000000002ULL,
402     PPC_FLOAT_FSQRT   = 0x0000000000000004ULL,
403     PPC_FLOAT_FRES    = 0x0000000000000008ULL,
404     PPC_FLOAT_FRSQRTE = 0x0000000000000010ULL,
405     PPC_FLOAT_FSEL    = 0x0000000000000020ULL,
406     PPC_FLOAT_STFIWX  = 0x0000000000000040ULL,
407     /* external control instructions                    */
408     PPC_EXTERN        = 0x0000000000000080ULL,
409     /* segment register access instructions             */
410     PPC_SEGMENT       = 0x0000000000000100ULL,
411     /* Optional cache control instruction               */
412     PPC_CACHE_DCBA    = 0x0000000000000200ULL,
413     /* Optional memory control instructions             */
414     PPC_MEM_TLBIA     = 0x0000000000000400ULL,
415     PPC_MEM_TLBIE     = 0x0000000000000800ULL,
416     PPC_MEM_TLBSYNC   = 0x0000000000001000ULL,
417     /* eieio & sync                                     */
418     PPC_MEM_SYNC      = 0x0000000000002000ULL,
419     /* PowerPC 6xx TLB management instructions          */
420     PPC_6xx_TLB       = 0x0000000000004000ULL,
421     /* Altivec support                                  */
422     PPC_ALTIVEC       = 0x0000000000008000ULL,
423     /* Time base mftb instruction                       */
424     PPC_MFTB          = 0x0000000000010000ULL,
425     /* Embedded PowerPC dedicated instructions          */
426     PPC_EMB_COMMON    = 0x0000000000020000ULL,
427     /* PowerPC 40x exception model                      */
428     PPC_40x_EXCP      = 0x0000000000040000ULL,
429     /* PowerPC 40x TLB management instructions          */
430     PPC_40x_TLB       = 0x0000000000080000ULL,
431     /* PowerPC 405 Mac instructions                     */
432     PPC_405_MAC       = 0x0000000000100000ULL,
433     /* PowerPC 440 specific instructions                */
434     PPC_440_SPEC      = 0x0000000000200000ULL,
435     /* Power-to-PowerPC bridge (601)                    */
436     PPC_POWER_BR      = 0x0000000000400000ULL,
437     /* PowerPC 602 specific */
438     PPC_602_SPEC      = 0x0000000000800000ULL,
439     /* Deprecated instructions                          */
440     /* Original POWER instruction set                   */
441     PPC_POWER         = 0x0000000001000000ULL,
442     /* POWER2 instruction set extension                 */
443     PPC_POWER2        = 0x0000000002000000ULL,
444     /* Power RTC support */
445     PPC_POWER_RTC     = 0x0000000004000000ULL,
446     /* 64 bits PowerPC instructions                     */
447     /* 64 bits PowerPC instruction set                  */
448     PPC_64B           = 0x0000000008000000ULL,
449     /* 64 bits hypervisor extensions                    */
450     PPC_64H           = 0x0000000010000000ULL,
451     /* 64 bits PowerPC "bridge" features                */
452     PPC_64_BRIDGE     = 0x0000000020000000ULL,
453     /* BookE (embedded) PowerPC specification           */
454     PPC_BOOKE         = 0x0000000040000000ULL,
455     /* eieio                                            */
456     PPC_MEM_EIEIO     = 0x0000000080000000ULL,
457     /* e500 vector instructions                         */
458     PPC_E500_VECTOR   = 0x0000000100000000ULL,
459     /* PowerPC 4xx dedicated instructions               */
460     PPC_4xx_COMMON    = 0x0000000200000000ULL,
461     /* PowerPC 2.03 specification extensions            */
462     PPC_203           = 0x0000000400000000ULL,
463     /* PowerPC 2.03 SPE extension                       */
464     PPC_SPE           = 0x0000000800000000ULL,
465     /* PowerPC 2.03 SPE floating-point extension        */
466     PPC_SPEFPU        = 0x0000001000000000ULL,
467     /* SLB management                                   */
468     PPC_SLBI          = 0x0000002000000000ULL,
469     /* PowerPC 40x ibct instructions                    */
470     PPC_40x_ICBT      = 0x0000004000000000ULL,
471     /* PowerPC 74xx TLB management instructions         */
472     PPC_74xx_TLB      = 0x0000008000000000ULL,
473     /* More BookE (embedded) instructions...            */
474     PPC_BOOKE_EXT     = 0x0000010000000000ULL,
475     /* rfmci is not implemented in all BookE PowerPC    */
476     PPC_RFMCI         = 0x0000020000000000ULL,
477     /* user-mode DCR access, implemented in PowerPC 460 */
478     PPC_DCRUX         = 0x0000040000000000ULL,
479     /* New floating-point extensions (PowerPC 2.0x)     */
480     PPC_FLOAT_EXT     = 0x0000080000000000ULL,
481     /* New wait instruction (PowerPC 2.0x)              */
482     PPC_WAIT          = 0x0000100000000000ULL,
483 };
484
485 /*****************************************************************************/
486 /* PowerPC instructions table                                                */
487 #if HOST_LONG_BITS == 64
488 #define OPC_ALIGN 8
489 #else
490 #define OPC_ALIGN 4
491 #endif
492 #if defined(__APPLE__)
493 #define OPCODES_SECTION                                                       \
494     __attribute__ ((section("__TEXT,__opcodes"), unused, aligned (OPC_ALIGN) ))
495 #else
496 #define OPCODES_SECTION                                                       \
497     __attribute__ ((section(".opcodes"), unused, aligned (OPC_ALIGN) ))
498 #endif
499
500 #if defined(DO_PPC_STATISTICS)
501 #define GEN_OPCODE(name, op1, op2, op3, invl, _typ)                           \
502 OPCODES_SECTION opcode_t opc_##name = {                                       \
503     .opc1 = op1,                                                              \
504     .opc2 = op2,                                                              \
505     .opc3 = op3,                                                              \
506     .pad  = { 0, },                                                           \
507     .handler = {                                                              \
508         .inval   = invl,                                                      \
509         .type = _typ,                                                         \
510         .handler = &gen_##name,                                               \
511         .oname = stringify(name),                                             \
512     },                                                                        \
513     .oname = stringify(name),                                                 \
514 }
515 #else
516 #define GEN_OPCODE(name, op1, op2, op3, invl, _typ)                           \
517 OPCODES_SECTION opcode_t opc_##name = {                                       \
518     .opc1 = op1,                                                              \
519     .opc2 = op2,                                                              \
520     .opc3 = op3,                                                              \
521     .pad  = { 0, },                                                           \
522     .handler = {                                                              \
523         .inval   = invl,                                                      \
524         .type = _typ,                                                         \
525         .handler = &gen_##name,                                               \
526     },                                                                        \
527     .oname = stringify(name),                                                 \
528 }
529 #endif
530
531 #define GEN_OPCODE_MARK(name)                                                 \
532 OPCODES_SECTION opcode_t opc_##name = {                                       \
533     .opc1 = 0xFF,                                                             \
534     .opc2 = 0xFF,                                                             \
535     .opc3 = 0xFF,                                                             \
536     .pad  = { 0, },                                                           \
537     .handler = {                                                              \
538         .inval   = 0x00000000,                                                \
539         .type = 0x00,                                                         \
540         .handler = NULL,                                                      \
541     },                                                                        \
542     .oname = stringify(name),                                                 \
543 }
544
545 /* Start opcode list */
546 GEN_OPCODE_MARK(start);
547
548 /* Invalid instruction */
549 GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE)
550 {
551     GEN_EXCP_INVAL(ctx);
552 }
553
554 static opc_handler_t invalid_handler = {
555     .inval   = 0xFFFFFFFF,
556     .type    = PPC_NONE,
557     .handler = gen_invalid,
558 };
559
560 /***                           Integer arithmetic                          ***/
561 #define __GEN_INT_ARITH2(name, opc1, opc2, opc3, inval, type)                 \
562 GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
563 {                                                                             \
564     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
565     gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
566     gen_op_##name();                                                          \
567     gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
568     if (unlikely(Rc(ctx->opcode) != 0))                                       \
569         gen_set_Rc0(ctx);                                                     \
570 }
571
572 #define __GEN_INT_ARITH2_O(name, opc1, opc2, opc3, inval, type)               \
573 GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
574 {                                                                             \
575     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
576     gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
577     gen_op_##name();                                                          \
578     gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
579     if (unlikely(Rc(ctx->opcode) != 0))                                       \
580         gen_set_Rc0(ctx);                                                     \
581 }
582
583 #define __GEN_INT_ARITH1(name, opc1, opc2, opc3, type)                        \
584 GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
585 {                                                                             \
586     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
587     gen_op_##name();                                                          \
588     gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
589     if (unlikely(Rc(ctx->opcode) != 0))                                       \
590         gen_set_Rc0(ctx);                                                     \
591 }
592 #define __GEN_INT_ARITH1_O(name, opc1, opc2, opc3, type)                      \
593 GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
594 {                                                                             \
595     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
596     gen_op_##name();                                                          \
597     gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
598     if (unlikely(Rc(ctx->opcode) != 0))                                       \
599         gen_set_Rc0(ctx);                                                     \
600 }
601
602 /* Two operands arithmetic functions */
603 #define GEN_INT_ARITH2(name, opc1, opc2, opc3, type)                          \
604 __GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000000, type)                    \
605 __GEN_INT_ARITH2_O(name##o, opc1, opc2, opc3 | 0x10, 0x00000000, type)
606
607 /* Two operands arithmetic functions with no overflow allowed */
608 #define GEN_INT_ARITHN(name, opc1, opc2, opc3, type)                          \
609 __GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000400, type)
610
611 /* One operand arithmetic functions */
612 #define GEN_INT_ARITH1(name, opc1, opc2, opc3, type)                          \
613 __GEN_INT_ARITH1(name, opc1, opc2, opc3, type)                                \
614 __GEN_INT_ARITH1_O(name##o, opc1, opc2, opc3 | 0x10, type)
615
616 #if defined(TARGET_PPC64)
617 #define __GEN_INT_ARITH2_64(name, opc1, opc2, opc3, inval, type)              \
618 GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
619 {                                                                             \
620     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
621     gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
622     if (ctx->sf_mode)                                                         \
623         gen_op_##name##_64();                                                 \
624     else                                                                      \
625         gen_op_##name();                                                      \
626     gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
627     if (unlikely(Rc(ctx->opcode) != 0))                                       \
628         gen_set_Rc0(ctx);                                                     \
629 }
630
631 #define __GEN_INT_ARITH2_O_64(name, opc1, opc2, opc3, inval, type)            \
632 GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
633 {                                                                             \
634     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
635     gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
636     if (ctx->sf_mode)                                                         \
637         gen_op_##name##_64();                                                 \
638     else                                                                      \
639         gen_op_##name();                                                      \
640     gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
641     if (unlikely(Rc(ctx->opcode) != 0))                                       \
642         gen_set_Rc0(ctx);                                                     \
643 }
644
645 #define __GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type)                     \
646 GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
647 {                                                                             \
648     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
649     if (ctx->sf_mode)                                                         \
650         gen_op_##name##_64();                                                 \
651     else                                                                      \
652         gen_op_##name();                                                      \
653     gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
654     if (unlikely(Rc(ctx->opcode) != 0))                                       \
655         gen_set_Rc0(ctx);                                                     \
656 }
657 #define __GEN_INT_ARITH1_O_64(name, opc1, opc2, opc3, type)                   \
658 GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
659 {                                                                             \
660     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
661     if (ctx->sf_mode)                                                         \
662         gen_op_##name##_64();                                                 \
663     else                                                                      \
664         gen_op_##name();                                                      \
665     gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
666     if (unlikely(Rc(ctx->opcode) != 0))                                       \
667         gen_set_Rc0(ctx);                                                     \
668 }
669
670 /* Two operands arithmetic functions */
671 #define GEN_INT_ARITH2_64(name, opc1, opc2, opc3, type)                       \
672 __GEN_INT_ARITH2_64(name, opc1, opc2, opc3, 0x00000000, type)                 \
673 __GEN_INT_ARITH2_O_64(name##o, opc1, opc2, opc3 | 0x10, 0x00000000, type)
674
675 /* Two operands arithmetic functions with no overflow allowed */
676 #define GEN_INT_ARITHN_64(name, opc1, opc2, opc3, type)                       \
677 __GEN_INT_ARITH2_64(name, opc1, opc2, opc3, 0x00000400, type)
678
679 /* One operand arithmetic functions */
680 #define GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type)                       \
681 __GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type)                             \
682 __GEN_INT_ARITH1_O_64(name##o, opc1, opc2, opc3 | 0x10, type)
683 #else
684 #define GEN_INT_ARITH2_64 GEN_INT_ARITH2
685 #define GEN_INT_ARITHN_64 GEN_INT_ARITHN
686 #define GEN_INT_ARITH1_64 GEN_INT_ARITH1
687 #endif
688
689 /* add    add.    addo    addo.    */
690 static inline void gen_op_addo (void)
691 {
692     gen_op_move_T2_T0();
693     gen_op_add();
694     gen_op_check_addo();
695 }
696 #if defined(TARGET_PPC64)
697 #define gen_op_add_64 gen_op_add
698 static inline void gen_op_addo_64 (void)
699 {
700     gen_op_move_T2_T0();
701     gen_op_add();
702     gen_op_check_addo_64();
703 }
704 #endif
705 GEN_INT_ARITH2_64 (add,    0x1F, 0x0A, 0x08, PPC_INTEGER);
706 /* addc   addc.   addco   addco.   */
707 static inline void gen_op_addc (void)
708 {
709     gen_op_move_T2_T0();
710     gen_op_add();
711     gen_op_check_addc();
712 }
713 static inline void gen_op_addco (void)
714 {
715     gen_op_move_T2_T0();
716     gen_op_add();
717     gen_op_check_addc();
718     gen_op_check_addo();
719 }
720 #if defined(TARGET_PPC64)
721 static inline void gen_op_addc_64 (void)
722 {
723     gen_op_move_T2_T0();
724     gen_op_add();
725     gen_op_check_addc_64();
726 }
727 static inline void gen_op_addco_64 (void)
728 {
729     gen_op_move_T2_T0();
730     gen_op_add();
731     gen_op_check_addc_64();
732     gen_op_check_addo_64();
733 }
734 #endif
735 GEN_INT_ARITH2_64 (addc,   0x1F, 0x0A, 0x00, PPC_INTEGER);
736 /* adde   adde.   addeo   addeo.   */
737 static inline void gen_op_addeo (void)
738 {
739     gen_op_move_T2_T0();
740     gen_op_adde();
741     gen_op_check_addo();
742 }
743 #if defined(TARGET_PPC64)
744 static inline void gen_op_addeo_64 (void)
745 {
746     gen_op_move_T2_T0();
747     gen_op_adde_64();
748     gen_op_check_addo_64();
749 }
750 #endif
751 GEN_INT_ARITH2_64 (adde,   0x1F, 0x0A, 0x04, PPC_INTEGER);
752 /* addme  addme.  addmeo  addmeo.  */
753 static inline void gen_op_addme (void)
754 {
755     gen_op_move_T1_T0();
756     gen_op_add_me();
757 }
758 #if defined(TARGET_PPC64)
759 static inline void gen_op_addme_64 (void)
760 {
761     gen_op_move_T1_T0();
762     gen_op_add_me_64();
763 }
764 #endif
765 GEN_INT_ARITH1_64 (addme,  0x1F, 0x0A, 0x07, PPC_INTEGER);
766 /* addze  addze.  addzeo  addzeo.  */
767 static inline void gen_op_addze (void)
768 {
769     gen_op_move_T2_T0();
770     gen_op_add_ze();
771     gen_op_check_addc();
772 }
773 static inline void gen_op_addzeo (void)
774 {
775     gen_op_move_T2_T0();
776     gen_op_add_ze();
777     gen_op_check_addc();
778     gen_op_check_addo();
779 }
780 #if defined(TARGET_PPC64)
781 static inline void gen_op_addze_64 (void)
782 {
783     gen_op_move_T2_T0();
784     gen_op_add_ze();
785     gen_op_check_addc_64();
786 }
787 static inline void gen_op_addzeo_64 (void)
788 {
789     gen_op_move_T2_T0();
790     gen_op_add_ze();
791     gen_op_check_addc_64();
792     gen_op_check_addo_64();
793 }
794 #endif
795 GEN_INT_ARITH1_64 (addze,  0x1F, 0x0A, 0x06, PPC_INTEGER);
796 /* divw   divw.   divwo   divwo.   */
797 GEN_INT_ARITH2 (divw,   0x1F, 0x0B, 0x0F, PPC_INTEGER);
798 /* divwu  divwu.  divwuo  divwuo.  */
799 GEN_INT_ARITH2 (divwu,  0x1F, 0x0B, 0x0E, PPC_INTEGER);
800 /* mulhw  mulhw.                   */
801 GEN_INT_ARITHN (mulhw,  0x1F, 0x0B, 0x02, PPC_INTEGER);
802 /* mulhwu mulhwu.                  */
803 GEN_INT_ARITHN (mulhwu, 0x1F, 0x0B, 0x00, PPC_INTEGER);
804 /* mullw  mullw.  mullwo  mullwo.  */
805 GEN_INT_ARITH2 (mullw,  0x1F, 0x0B, 0x07, PPC_INTEGER);
806 /* neg    neg.    nego    nego.    */
807 GEN_INT_ARITH1_64 (neg,    0x1F, 0x08, 0x03, PPC_INTEGER);
808 /* subf   subf.   subfo   subfo.   */
809 static inline void gen_op_subfo (void)
810 {
811     gen_op_move_T2_T0();
812     gen_op_subf();
813     gen_op_check_subfo();
814 }
815 #if defined(TARGET_PPC64)
816 #define gen_op_subf_64 gen_op_subf
817 static inline void gen_op_subfo_64 (void)
818 {
819     gen_op_move_T2_T0();
820     gen_op_subf();
821     gen_op_check_subfo_64();
822 }
823 #endif
824 GEN_INT_ARITH2_64 (subf,   0x1F, 0x08, 0x01, PPC_INTEGER);
825 /* subfc  subfc.  subfco  subfco.  */
826 static inline void gen_op_subfc (void)
827 {
828     gen_op_subf();
829     gen_op_check_subfc();
830 }
831 static inline void gen_op_subfco (void)
832 {
833     gen_op_move_T2_T0();
834     gen_op_subf();
835     gen_op_check_subfc();
836     gen_op_check_subfo();
837 }
838 #if defined(TARGET_PPC64)
839 static inline void gen_op_subfc_64 (void)
840 {
841     gen_op_subf();
842     gen_op_check_subfc_64();
843 }
844 static inline void gen_op_subfco_64 (void)
845 {
846     gen_op_move_T2_T0();
847     gen_op_subf();
848     gen_op_check_subfc_64();
849     gen_op_check_subfo_64();
850 }
851 #endif
852 GEN_INT_ARITH2_64 (subfc,  0x1F, 0x08, 0x00, PPC_INTEGER);
853 /* subfe  subfe.  subfeo  subfeo.  */
854 static inline void gen_op_subfeo (void)
855 {
856     gen_op_move_T2_T0();
857     gen_op_subfe();
858     gen_op_check_subfo();
859 }
860 #if defined(TARGET_PPC64)
861 #define gen_op_subfe_64 gen_op_subfe
862 static inline void gen_op_subfeo_64 (void)
863 {
864     gen_op_move_T2_T0();
865     gen_op_subfe_64();
866     gen_op_check_subfo_64();
867 }
868 #endif
869 GEN_INT_ARITH2_64 (subfe,  0x1F, 0x08, 0x04, PPC_INTEGER);
870 /* subfme subfme. subfmeo subfmeo. */
871 GEN_INT_ARITH1_64 (subfme, 0x1F, 0x08, 0x07, PPC_INTEGER);
872 /* subfze subfze. subfzeo subfzeo. */
873 GEN_INT_ARITH1_64 (subfze, 0x1F, 0x08, 0x06, PPC_INTEGER);
874 /* addi */
875 GEN_HANDLER(addi, 0x0E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
876 {
877     target_long simm = SIMM(ctx->opcode);
878
879     if (rA(ctx->opcode) == 0) {
880         /* li case */
881         gen_set_T0(simm);
882     } else {
883         gen_op_load_gpr_T0(rA(ctx->opcode));
884         if (likely(simm != 0))
885             gen_op_addi(simm);
886     }
887     gen_op_store_T0_gpr(rD(ctx->opcode));
888 }
889 /* addic */
890 GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
891 {
892     target_long simm = SIMM(ctx->opcode);
893
894     gen_op_load_gpr_T0(rA(ctx->opcode));
895     if (likely(simm != 0)) {
896         gen_op_move_T2_T0();
897         gen_op_addi(simm);
898 #if defined(TARGET_PPC64)
899         if (ctx->sf_mode)
900             gen_op_check_addc_64();
901         else
902 #endif
903             gen_op_check_addc();
904     } else {
905         gen_op_clear_xer_ca();
906     }
907     gen_op_store_T0_gpr(rD(ctx->opcode));
908 }
909 /* addic. */
910 GEN_HANDLER(addic_, 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
911 {
912     target_long simm = SIMM(ctx->opcode);
913
914     gen_op_load_gpr_T0(rA(ctx->opcode));
915     if (likely(simm != 0)) {
916         gen_op_move_T2_T0();
917         gen_op_addi(simm);
918 #if defined(TARGET_PPC64)
919         if (ctx->sf_mode)
920             gen_op_check_addc_64();
921         else
922 #endif
923             gen_op_check_addc();
924     } else {
925         gen_op_clear_xer_ca();
926     }
927     gen_op_store_T0_gpr(rD(ctx->opcode));
928     gen_set_Rc0(ctx);
929 }
930 /* addis */
931 GEN_HANDLER(addis, 0x0F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
932 {
933     target_long simm = SIMM(ctx->opcode);
934
935     if (rA(ctx->opcode) == 0) {
936         /* lis case */
937         gen_set_T0(simm << 16);
938     } else {
939         gen_op_load_gpr_T0(rA(ctx->opcode));
940         if (likely(simm != 0))
941             gen_op_addi(simm << 16);
942     }
943     gen_op_store_T0_gpr(rD(ctx->opcode));
944 }
945 /* mulli */
946 GEN_HANDLER(mulli, 0x07, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
947 {
948     gen_op_load_gpr_T0(rA(ctx->opcode));
949     gen_op_mulli(SIMM(ctx->opcode));
950     gen_op_store_T0_gpr(rD(ctx->opcode));
951 }
952 /* subfic */
953 GEN_HANDLER(subfic, 0x08, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
954 {
955     gen_op_load_gpr_T0(rA(ctx->opcode));
956 #if defined(TARGET_PPC64)
957     if (ctx->sf_mode)
958         gen_op_subfic_64(SIMM(ctx->opcode));
959     else
960 #endif
961         gen_op_subfic(SIMM(ctx->opcode));
962     gen_op_store_T0_gpr(rD(ctx->opcode));
963 }
964
965 #if defined(TARGET_PPC64)
966 /* mulhd  mulhd.                   */
967 GEN_INT_ARITHN (mulhd,  0x1F, 0x09, 0x02, PPC_64B);
968 /* mulhdu mulhdu.                  */
969 GEN_INT_ARITHN (mulhdu, 0x1F, 0x09, 0x00, PPC_64B);
970 /* mulld  mulld.  mulldo  mulldo.  */
971 GEN_INT_ARITH2 (mulld,  0x1F, 0x09, 0x07, PPC_64B);
972 /* divd   divd.   divdo   divdo.   */
973 GEN_INT_ARITH2 (divd,   0x1F, 0x09, 0x0F, PPC_64B);
974 /* divdu  divdu.  divduo  divduo.  */
975 GEN_INT_ARITH2 (divdu,  0x1F, 0x09, 0x0E, PPC_64B);
976 #endif
977
978 /***                           Integer comparison                          ***/
979 #if defined(TARGET_PPC64)
980 #define GEN_CMP(name, opc, type)                                              \
981 GEN_HANDLER(name, 0x1F, 0x00, opc, 0x00400000, type)                          \
982 {                                                                             \
983     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
984     gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
985     if (ctx->sf_mode && (ctx->opcode & 0x00200000))                           \
986         gen_op_##name##_64();                                                 \
987     else                                                                      \
988         gen_op_##name();                                                      \
989     gen_op_store_T0_crf(crfD(ctx->opcode));                                   \
990 }
991 #else
992 #define GEN_CMP(name, opc, type)                                              \
993 GEN_HANDLER(name, 0x1F, 0x00, opc, 0x00400000, type)                          \
994 {                                                                             \
995     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
996     gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
997     gen_op_##name();                                                          \
998     gen_op_store_T0_crf(crfD(ctx->opcode));                                   \
999 }
1000 #endif
1001
1002 /* cmp */
1003 GEN_CMP(cmp, 0x00, PPC_INTEGER);
1004 /* cmpi */
1005 GEN_HANDLER(cmpi, 0x0B, 0xFF, 0xFF, 0x00400000, PPC_INTEGER)
1006 {
1007     gen_op_load_gpr_T0(rA(ctx->opcode));
1008 #if defined(TARGET_PPC64)
1009     if (ctx->sf_mode && (ctx->opcode & 0x00200000))
1010         gen_op_cmpi_64(SIMM(ctx->opcode));
1011     else
1012 #endif
1013         gen_op_cmpi(SIMM(ctx->opcode));
1014     gen_op_store_T0_crf(crfD(ctx->opcode));
1015 }
1016 /* cmpl */
1017 GEN_CMP(cmpl, 0x01, PPC_INTEGER);
1018 /* cmpli */
1019 GEN_HANDLER(cmpli, 0x0A, 0xFF, 0xFF, 0x00400000, PPC_INTEGER)
1020 {
1021     gen_op_load_gpr_T0(rA(ctx->opcode));
1022 #if defined(TARGET_PPC64)
1023     if (ctx->sf_mode && (ctx->opcode & 0x00200000))
1024         gen_op_cmpli_64(UIMM(ctx->opcode));
1025     else
1026 #endif
1027         gen_op_cmpli(UIMM(ctx->opcode));
1028     gen_op_store_T0_crf(crfD(ctx->opcode));
1029 }
1030
1031 /* isel (PowerPC 2.03 specification) */
1032 GEN_HANDLER(isel, 0x1F, 0x0F, 0x00, 0x00000001, PPC_203)
1033 {
1034     uint32_t bi = rC(ctx->opcode);
1035     uint32_t mask;
1036
1037     if (rA(ctx->opcode) == 0) {
1038         gen_set_T0(0);
1039     } else {
1040         gen_op_load_gpr_T1(rA(ctx->opcode));
1041     }
1042     gen_op_load_gpr_T2(rB(ctx->opcode));
1043     mask = 1 << (3 - (bi & 0x03));
1044     gen_op_load_crf_T0(bi >> 2);
1045     gen_op_test_true(mask);
1046     gen_op_isel();
1047     gen_op_store_T0_gpr(rD(ctx->opcode));
1048 }
1049
1050 /***                            Integer logical                            ***/
1051 #define __GEN_LOGICAL2(name, opc2, opc3, type)                                \
1052 GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000000, type)                         \
1053 {                                                                             \
1054     gen_op_load_gpr_T0(rS(ctx->opcode));                                      \
1055     gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
1056     gen_op_##name();                                                          \
1057     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1058     if (unlikely(Rc(ctx->opcode) != 0))                                       \
1059         gen_set_Rc0(ctx);                                                     \
1060 }
1061 #define GEN_LOGICAL2(name, opc, type)                                         \
1062 __GEN_LOGICAL2(name, 0x1C, opc, type)
1063
1064 #define GEN_LOGICAL1(name, opc, type)                                         \
1065 GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, type)                          \
1066 {                                                                             \
1067     gen_op_load_gpr_T0(rS(ctx->opcode));                                      \
1068     gen_op_##name();                                                          \
1069     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1070     if (unlikely(Rc(ctx->opcode) != 0))                                       \
1071         gen_set_Rc0(ctx);                                                     \
1072 }
1073
1074 /* and & and. */
1075 GEN_LOGICAL2(and, 0x00, PPC_INTEGER);
1076 /* andc & andc. */
1077 GEN_LOGICAL2(andc, 0x01, PPC_INTEGER);
1078 /* andi. */
1079 GEN_HANDLER(andi_, 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1080 {
1081     gen_op_load_gpr_T0(rS(ctx->opcode));
1082     gen_op_andi_T0(UIMM(ctx->opcode));
1083     gen_op_store_T0_gpr(rA(ctx->opcode));
1084     gen_set_Rc0(ctx);
1085 }
1086 /* andis. */
1087 GEN_HANDLER(andis_, 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1088 {
1089     gen_op_load_gpr_T0(rS(ctx->opcode));
1090     gen_op_andi_T0(UIMM(ctx->opcode) << 16);
1091     gen_op_store_T0_gpr(rA(ctx->opcode));
1092     gen_set_Rc0(ctx);
1093 }
1094
1095 /* cntlzw */
1096 GEN_LOGICAL1(cntlzw, 0x00, PPC_INTEGER);
1097 /* eqv & eqv. */
1098 GEN_LOGICAL2(eqv, 0x08, PPC_INTEGER);
1099 /* extsb & extsb. */
1100 GEN_LOGICAL1(extsb, 0x1D, PPC_INTEGER);
1101 /* extsh & extsh. */
1102 GEN_LOGICAL1(extsh, 0x1C, PPC_INTEGER);
1103 /* nand & nand. */
1104 GEN_LOGICAL2(nand, 0x0E, PPC_INTEGER);
1105 /* nor & nor. */
1106 GEN_LOGICAL2(nor, 0x03, PPC_INTEGER);
1107
1108 /* or & or. */
1109 GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER)
1110 {
1111     int rs, ra, rb;
1112
1113     rs = rS(ctx->opcode);
1114     ra = rA(ctx->opcode);
1115     rb = rB(ctx->opcode);
1116     /* Optimisation for mr. ri case */
1117     if (rs != ra || rs != rb) {
1118         gen_op_load_gpr_T0(rs);
1119         if (rs != rb) {
1120             gen_op_load_gpr_T1(rb);
1121             gen_op_or();
1122         }
1123         gen_op_store_T0_gpr(ra);
1124         if (unlikely(Rc(ctx->opcode) != 0))
1125             gen_set_Rc0(ctx);
1126     } else if (unlikely(Rc(ctx->opcode) != 0)) {
1127         gen_op_load_gpr_T0(rs);
1128         gen_set_Rc0(ctx);
1129 #if defined(TARGET_PPC64)
1130     } else {
1131         switch (rs) {
1132         case 1:
1133             /* Set process priority to low */
1134             gen_op_store_pri(2);
1135             break;
1136         case 6:
1137             /* Set process priority to medium-low */
1138             gen_op_store_pri(3);
1139             break;
1140         case 2:
1141             /* Set process priority to normal */
1142             gen_op_store_pri(4);
1143             break;
1144         default:
1145             /* nop */
1146             break;
1147         }
1148 #endif
1149     }
1150 }
1151
1152 /* orc & orc. */
1153 GEN_LOGICAL2(orc, 0x0C, PPC_INTEGER);
1154 /* xor & xor. */
1155 GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER)
1156 {
1157     gen_op_load_gpr_T0(rS(ctx->opcode));
1158     /* Optimisation for "set to zero" case */
1159     if (rS(ctx->opcode) != rB(ctx->opcode)) {
1160         gen_op_load_gpr_T1(rB(ctx->opcode));
1161         gen_op_xor();
1162     } else {
1163         gen_op_reset_T0();
1164     }
1165     gen_op_store_T0_gpr(rA(ctx->opcode));
1166     if (unlikely(Rc(ctx->opcode) != 0))
1167         gen_set_Rc0(ctx);
1168 }
1169 /* ori */
1170 GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1171 {
1172     target_ulong uimm = UIMM(ctx->opcode);
1173
1174     if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1175         /* NOP */
1176         /* XXX: should handle special NOPs for POWER series */
1177         return;
1178     }
1179     gen_op_load_gpr_T0(rS(ctx->opcode));
1180     if (likely(uimm != 0))
1181         gen_op_ori(uimm);
1182     gen_op_store_T0_gpr(rA(ctx->opcode));
1183 }
1184 /* oris */
1185 GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1186 {
1187     target_ulong uimm = UIMM(ctx->opcode);
1188
1189     if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1190         /* NOP */
1191         return;
1192     }
1193     gen_op_load_gpr_T0(rS(ctx->opcode));
1194     if (likely(uimm != 0))
1195         gen_op_ori(uimm << 16);
1196     gen_op_store_T0_gpr(rA(ctx->opcode));
1197 }
1198 /* xori */
1199 GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1200 {
1201     target_ulong uimm = UIMM(ctx->opcode);
1202
1203     if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1204         /* NOP */
1205         return;
1206     }
1207     gen_op_load_gpr_T0(rS(ctx->opcode));
1208     if (likely(uimm != 0))
1209         gen_op_xori(uimm);
1210     gen_op_store_T0_gpr(rA(ctx->opcode));
1211 }
1212
1213 /* xoris */
1214 GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1215 {
1216     target_ulong uimm = UIMM(ctx->opcode);
1217
1218     if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1219         /* NOP */
1220         return;
1221     }
1222     gen_op_load_gpr_T0(rS(ctx->opcode));
1223     if (likely(uimm != 0))
1224         gen_op_xori(uimm << 16);
1225     gen_op_store_T0_gpr(rA(ctx->opcode));
1226 }
1227
1228 /* popcntb : PowerPC 2.03 specification */
1229 GEN_HANDLER(popcntb, 0x1F, 0x03, 0x03, 0x0000F801, PPC_203)
1230 {
1231     gen_op_load_gpr_T0(rS(ctx->opcode));
1232 #if defined(TARGET_PPC64)
1233     if (ctx->sf_mode)
1234         gen_op_popcntb_64();
1235     else
1236 #endif
1237         gen_op_popcntb();
1238     gen_op_store_T0_gpr(rA(ctx->opcode));
1239 }
1240
1241 #if defined(TARGET_PPC64)
1242 /* extsw & extsw. */
1243 GEN_LOGICAL1(extsw, 0x1E, PPC_64B);
1244 /* cntlzd */
1245 GEN_LOGICAL1(cntlzd, 0x01, PPC_64B);
1246 #endif
1247
1248 /***                             Integer rotate                            ***/
1249 /* rlwimi & rlwimi. */
1250 GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1251 {
1252     target_ulong mask;
1253     uint32_t mb, me, sh;
1254
1255     mb = MB(ctx->opcode);
1256     me = ME(ctx->opcode);
1257     sh = SH(ctx->opcode);
1258     if (likely(sh == 0)) {
1259         if (likely(mb == 0 && me == 31)) {
1260             gen_op_load_gpr_T0(rS(ctx->opcode));
1261             goto do_store;
1262         } else if (likely(mb == 31 && me == 0)) {
1263             gen_op_load_gpr_T0(rA(ctx->opcode));
1264             goto do_store;
1265         }
1266         gen_op_load_gpr_T0(rS(ctx->opcode));
1267         gen_op_load_gpr_T1(rA(ctx->opcode));
1268         goto do_mask;
1269     }
1270     gen_op_load_gpr_T0(rS(ctx->opcode));
1271     gen_op_load_gpr_T1(rA(ctx->opcode));
1272     gen_op_rotli32_T0(SH(ctx->opcode));
1273  do_mask:
1274 #if defined(TARGET_PPC64)
1275     mb += 32;
1276     me += 32;
1277 #endif
1278     mask = MASK(mb, me);
1279     gen_op_andi_T0(mask);
1280     gen_op_andi_T1(~mask);
1281     gen_op_or();
1282  do_store:
1283     gen_op_store_T0_gpr(rA(ctx->opcode));
1284     if (unlikely(Rc(ctx->opcode) != 0))
1285         gen_set_Rc0(ctx);
1286 }
1287 /* rlwinm & rlwinm. */
1288 GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1289 {
1290     uint32_t mb, me, sh;
1291
1292     sh = SH(ctx->opcode);
1293     mb = MB(ctx->opcode);
1294     me = ME(ctx->opcode);
1295     gen_op_load_gpr_T0(rS(ctx->opcode));
1296     if (likely(sh == 0)) {
1297         goto do_mask;
1298     }
1299     if (likely(mb == 0)) {
1300         if (likely(me == 31)) {
1301             gen_op_rotli32_T0(sh);
1302             goto do_store;
1303         } else if (likely(me == (31 - sh))) {
1304             gen_op_sli_T0(sh);
1305             goto do_store;
1306         }
1307     } else if (likely(me == 31)) {
1308         if (likely(sh == (32 - mb))) {
1309             gen_op_srli_T0(mb);
1310             goto do_store;
1311         }
1312     }
1313     gen_op_rotli32_T0(sh);
1314  do_mask:
1315 #if defined(TARGET_PPC64)
1316     mb += 32;
1317     me += 32;
1318 #endif
1319     gen_op_andi_T0(MASK(mb, me));
1320  do_store:
1321     gen_op_store_T0_gpr(rA(ctx->opcode));
1322     if (unlikely(Rc(ctx->opcode) != 0))
1323         gen_set_Rc0(ctx);
1324 }
1325 /* rlwnm & rlwnm. */
1326 GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1327 {
1328     uint32_t mb, me;
1329
1330     mb = MB(ctx->opcode);
1331     me = ME(ctx->opcode);
1332     gen_op_load_gpr_T0(rS(ctx->opcode));
1333     gen_op_load_gpr_T1(rB(ctx->opcode));
1334     gen_op_rotl32_T0_T1();
1335     if (unlikely(mb != 0 || me != 31)) {
1336 #if defined(TARGET_PPC64)
1337         mb += 32;
1338         me += 32;
1339 #endif
1340         gen_op_andi_T0(MASK(mb, me));
1341     }
1342     gen_op_store_T0_gpr(rA(ctx->opcode));
1343     if (unlikely(Rc(ctx->opcode) != 0))
1344         gen_set_Rc0(ctx);
1345 }
1346
1347 #if defined(TARGET_PPC64)
1348 #define GEN_PPC64_R2(name, opc1, opc2)                                        \
1349 GEN_HANDLER(name##0, opc1, opc2, 0xFF, 0x00000000, PPC_64B)                   \
1350 {                                                                             \
1351     gen_##name(ctx, 0);                                                       \
1352 }                                                                             \
1353 GEN_HANDLER(name##1, opc1, opc2 | 0x10, 0xFF, 0x00000000, PPC_64B)            \
1354 {                                                                             \
1355     gen_##name(ctx, 1);                                                       \
1356 }
1357 #define GEN_PPC64_R4(name, opc1, opc2)                                        \
1358 GEN_HANDLER(name##0, opc1, opc2, 0xFF, 0x00000000, PPC_64B)                   \
1359 {                                                                             \
1360     gen_##name(ctx, 0, 0);                                                    \
1361 }                                                                             \
1362 GEN_HANDLER(name##1, opc1, opc2 | 0x01, 0xFF, 0x00000000, PPC_64B)            \
1363 {                                                                             \
1364     gen_##name(ctx, 0, 1);                                                    \
1365 }                                                                             \
1366 GEN_HANDLER(name##2, opc1, opc2 | 0x10, 0xFF, 0x00000000, PPC_64B)            \
1367 {                                                                             \
1368     gen_##name(ctx, 1, 0);                                                    \
1369 }                                                                             \
1370 GEN_HANDLER(name##3, opc1, opc2 | 0x11, 0xFF, 0x00000000, PPC_64B)            \
1371 {                                                                             \
1372     gen_##name(ctx, 1, 1);                                                    \
1373 }
1374
1375 static inline void gen_andi_T0_64 (DisasContext *ctx, uint64_t mask)
1376 {
1377     if (mask >> 32)
1378         gen_op_andi_T0_64(mask >> 32, mask & 0xFFFFFFFF);
1379     else
1380         gen_op_andi_T0(mask);
1381 }
1382
1383 static inline void gen_andi_T1_64 (DisasContext *ctx, uint64_t mask)
1384 {
1385     if (mask >> 32)
1386         gen_op_andi_T1_64(mask >> 32, mask & 0xFFFFFFFF);
1387     else
1388         gen_op_andi_T1(mask);
1389 }
1390
1391 static inline void gen_rldinm (DisasContext *ctx, uint32_t mb, uint32_t me,
1392                                uint32_t sh)
1393 {
1394     gen_op_load_gpr_T0(rS(ctx->opcode));
1395     if (likely(sh == 0)) {
1396         goto do_mask;
1397     }
1398     if (likely(mb == 0)) {
1399         if (likely(me == 63)) {
1400             gen_op_rotli64_T0(sh);
1401             goto do_store;
1402         } else if (likely(me == (63 - sh))) {
1403             gen_op_sli_T0(sh);
1404             goto do_store;
1405         }
1406     } else if (likely(me == 63)) {
1407         if (likely(sh == (64 - mb))) {
1408             gen_op_srli_T0_64(mb);
1409             goto do_store;
1410         }
1411     }
1412     gen_op_rotli64_T0(sh);
1413  do_mask:
1414     gen_andi_T0_64(ctx, MASK(mb, me));
1415  do_store:
1416     gen_op_store_T0_gpr(rA(ctx->opcode));
1417     if (unlikely(Rc(ctx->opcode) != 0))
1418         gen_set_Rc0(ctx);
1419 }
1420 /* rldicl - rldicl. */
1421 static inline void gen_rldicl (DisasContext *ctx, int mbn, int shn)
1422 {
1423     uint32_t sh, mb;
1424
1425     sh = SH(ctx->opcode) | (shn << 5);
1426     mb = MB(ctx->opcode) | (mbn << 5);
1427     gen_rldinm(ctx, mb, 63, sh);
1428 }
1429 GEN_PPC64_R4(rldicl, 0x1E, 0x00);
1430 /* rldicr - rldicr. */
1431 static inline void gen_rldicr (DisasContext *ctx, int men, int shn)
1432 {
1433     uint32_t sh, me;
1434
1435     sh = SH(ctx->opcode) | (shn << 5);
1436     me = MB(ctx->opcode) | (men << 5);
1437     gen_rldinm(ctx, 0, me, sh);
1438 }
1439 GEN_PPC64_R4(rldicr, 0x1E, 0x02);
1440 /* rldic - rldic. */
1441 static inline void gen_rldic (DisasContext *ctx, int mbn, int shn)
1442 {
1443     uint32_t sh, mb;
1444
1445     sh = SH(ctx->opcode) | (shn << 5);
1446     mb = MB(ctx->opcode) | (mbn << 5);
1447     gen_rldinm(ctx, mb, 63 - sh, sh);
1448 }
1449 GEN_PPC64_R4(rldic, 0x1E, 0x04);
1450
1451 static inline void gen_rldnm (DisasContext *ctx, uint32_t mb, uint32_t me)
1452 {
1453     gen_op_load_gpr_T0(rS(ctx->opcode));
1454     gen_op_load_gpr_T1(rB(ctx->opcode));
1455     gen_op_rotl64_T0_T1();
1456     if (unlikely(mb != 0 || me != 63)) {
1457         gen_andi_T0_64(ctx, MASK(mb, me));
1458     }
1459     gen_op_store_T0_gpr(rA(ctx->opcode));
1460     if (unlikely(Rc(ctx->opcode) != 0))
1461         gen_set_Rc0(ctx);
1462 }
1463
1464 /* rldcl - rldcl. */
1465 static inline void gen_rldcl (DisasContext *ctx, int mbn)
1466 {
1467     uint32_t mb;
1468
1469     mb = MB(ctx->opcode) | (mbn << 5);
1470     gen_rldnm(ctx, mb, 63);
1471 }
1472 GEN_PPC64_R2(rldcl, 0x1E, 0x08);
1473 /* rldcr - rldcr. */
1474 static inline void gen_rldcr (DisasContext *ctx, int men)
1475 {
1476     uint32_t me;
1477
1478     me = MB(ctx->opcode) | (men << 5);
1479     gen_rldnm(ctx, 0, me);
1480 }
1481 GEN_PPC64_R2(rldcr, 0x1E, 0x09);
1482 /* rldimi - rldimi. */
1483 static inline void gen_rldimi (DisasContext *ctx, int mbn, int shn)
1484 {
1485     uint64_t mask;
1486     uint32_t sh, mb;
1487
1488     sh = SH(ctx->opcode) | (shn << 5);
1489     mb = MB(ctx->opcode) | (mbn << 5);
1490     if (likely(sh == 0)) {
1491         if (likely(mb == 0)) {
1492             gen_op_load_gpr_T0(rS(ctx->opcode));
1493             goto do_store;
1494         } else if (likely(mb == 63)) {
1495             gen_op_load_gpr_T0(rA(ctx->opcode));
1496             goto do_store;
1497         }
1498         gen_op_load_gpr_T0(rS(ctx->opcode));
1499         gen_op_load_gpr_T1(rA(ctx->opcode));
1500         goto do_mask;
1501     }
1502     gen_op_load_gpr_T0(rS(ctx->opcode));
1503     gen_op_load_gpr_T1(rA(ctx->opcode));
1504     gen_op_rotli64_T0(sh);
1505  do_mask:
1506     mask = MASK(mb, 63 - sh);
1507     gen_andi_T0_64(ctx, mask);
1508     gen_andi_T1_64(ctx, ~mask);
1509     gen_op_or();
1510  do_store:
1511     gen_op_store_T0_gpr(rA(ctx->opcode));
1512     if (unlikely(Rc(ctx->opcode) != 0))
1513         gen_set_Rc0(ctx);
1514 }
1515 GEN_PPC64_R4(rldimi, 0x1E, 0x06);
1516 #endif
1517
1518 /***                             Integer shift                             ***/
1519 /* slw & slw. */
1520 __GEN_LOGICAL2(slw, 0x18, 0x00, PPC_INTEGER);
1521 /* sraw & sraw. */
1522 __GEN_LOGICAL2(sraw, 0x18, 0x18, PPC_INTEGER);
1523 /* srawi & srawi. */
1524 GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER)
1525 {
1526     int mb, me;
1527     gen_op_load_gpr_T0(rS(ctx->opcode));
1528     if (SH(ctx->opcode) != 0) {
1529         gen_op_move_T1_T0();
1530         mb = 32 - SH(ctx->opcode);
1531         me = 31;
1532 #if defined(TARGET_PPC64)
1533         mb += 32;
1534         me += 32;
1535 #endif
1536         gen_op_srawi(SH(ctx->opcode), MASK(mb, me));
1537     }
1538     gen_op_store_T0_gpr(rA(ctx->opcode));
1539     if (unlikely(Rc(ctx->opcode) != 0))
1540         gen_set_Rc0(ctx);
1541 }
1542 /* srw & srw. */
1543 __GEN_LOGICAL2(srw, 0x18, 0x10, PPC_INTEGER);
1544
1545 #if defined(TARGET_PPC64)
1546 /* sld & sld. */
1547 __GEN_LOGICAL2(sld, 0x1B, 0x00, PPC_64B);
1548 /* srad & srad. */
1549 __GEN_LOGICAL2(srad, 0x1A, 0x18, PPC_64B);
1550 /* sradi & sradi. */
1551 static inline void gen_sradi (DisasContext *ctx, int n)
1552 {
1553     uint64_t mask;
1554     int sh, mb, me;
1555
1556     gen_op_load_gpr_T0(rS(ctx->opcode));
1557     sh = SH(ctx->opcode) + (n << 5);
1558     if (sh != 0) {
1559         gen_op_move_T1_T0();
1560         mb = 64 - SH(ctx->opcode);
1561         me = 63;
1562         mask = MASK(mb, me);
1563         gen_op_sradi(sh, mask >> 32, mask);
1564     }
1565     gen_op_store_T0_gpr(rA(ctx->opcode));
1566     if (unlikely(Rc(ctx->opcode) != 0))
1567         gen_set_Rc0(ctx);
1568 }
1569 GEN_HANDLER(sradi0, 0x1F, 0x1A, 0x19, 0x00000000, PPC_64B)
1570 {
1571     gen_sradi(ctx, 0);
1572 }
1573 GEN_HANDLER(sradi1, 0x1F, 0x1B, 0x19, 0x00000000, PPC_64B)
1574 {
1575     gen_sradi(ctx, 1);
1576 }
1577 /* srd & srd. */
1578 __GEN_LOGICAL2(srd, 0x1B, 0x10, PPC_64B);
1579 #endif
1580
1581 /***                       Floating-Point arithmetic                       ***/
1582 #define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat, type)                     \
1583 GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, type)                        \
1584 {                                                                             \
1585     if (unlikely(!ctx->fpu_enabled)) {                                        \
1586         GEN_EXCP_NO_FP(ctx);                                                  \
1587         return;                                                               \
1588     }                                                                         \
1589     gen_op_reset_scrfx();                                                     \
1590     gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
1591     gen_op_load_fpr_FT1(rC(ctx->opcode));                                     \
1592     gen_op_load_fpr_FT2(rB(ctx->opcode));                                     \
1593     gen_op_f##op();                                                           \
1594     if (isfloat) {                                                            \
1595         gen_op_frsp();                                                        \
1596     }                                                                         \
1597     gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1598     if (unlikely(Rc(ctx->opcode) != 0))                                       \
1599         gen_op_set_Rc1();                                                     \
1600 }
1601
1602 #define GEN_FLOAT_ACB(name, op2, type)                                        \
1603 _GEN_FLOAT_ACB(name, name, 0x3F, op2, 0, type);                               \
1604 _GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, type);
1605
1606 #define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat)                     \
1607 GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT)                        \
1608 {                                                                             \
1609     if (unlikely(!ctx->fpu_enabled)) {                                        \
1610         GEN_EXCP_NO_FP(ctx);                                                  \
1611         return;                                                               \
1612     }                                                                         \
1613     gen_op_reset_scrfx();                                                     \
1614     gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
1615     gen_op_load_fpr_FT1(rB(ctx->opcode));                                     \
1616     gen_op_f##op();                                                           \
1617     if (isfloat) {                                                            \
1618         gen_op_frsp();                                                        \
1619     }                                                                         \
1620     gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1621     if (unlikely(Rc(ctx->opcode) != 0))                                       \
1622         gen_op_set_Rc1();                                                     \
1623 }
1624 #define GEN_FLOAT_AB(name, op2, inval)                                        \
1625 _GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0);                               \
1626 _GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1);
1627
1628 #define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat)                     \
1629 GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT)                        \
1630 {                                                                             \
1631     if (unlikely(!ctx->fpu_enabled)) {                                        \
1632         GEN_EXCP_NO_FP(ctx);                                                  \
1633         return;                                                               \
1634     }                                                                         \
1635     gen_op_reset_scrfx();                                                     \
1636     gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
1637     gen_op_load_fpr_FT1(rC(ctx->opcode));                                     \
1638     gen_op_f##op();                                                           \
1639     if (isfloat) {                                                            \
1640         gen_op_frsp();                                                        \
1641     }                                                                         \
1642     gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1643     if (unlikely(Rc(ctx->opcode) != 0))                                       \
1644         gen_op_set_Rc1();                                                     \
1645 }
1646 #define GEN_FLOAT_AC(name, op2, inval)                                        \
1647 _GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0);                               \
1648 _GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1);
1649
1650 #define GEN_FLOAT_B(name, op2, op3, type)                                     \
1651 GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, type)                        \
1652 {                                                                             \
1653     if (unlikely(!ctx->fpu_enabled)) {                                        \
1654         GEN_EXCP_NO_FP(ctx);                                                  \
1655         return;                                                               \
1656     }                                                                         \
1657     gen_op_reset_scrfx();                                                     \
1658     gen_op_load_fpr_FT0(rB(ctx->opcode));                                     \
1659     gen_op_f##name();                                                         \
1660     gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1661     if (unlikely(Rc(ctx->opcode) != 0))                                       \
1662         gen_op_set_Rc1();                                                     \
1663 }
1664
1665 #define GEN_FLOAT_BS(name, op1, op2, type)                                    \
1666 GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, type)                        \
1667 {                                                                             \
1668     if (unlikely(!ctx->fpu_enabled)) {                                        \
1669         GEN_EXCP_NO_FP(ctx);                                                  \
1670         return;                                                               \
1671     }                                                                         \
1672     gen_op_reset_scrfx();                                                     \
1673     gen_op_load_fpr_FT0(rB(ctx->opcode));                                     \
1674     gen_op_f##name();                                                         \
1675     gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1676     if (unlikely(Rc(ctx->opcode) != 0))                                       \
1677         gen_op_set_Rc1();                                                     \
1678 }
1679
1680 /* fadd - fadds */
1681 GEN_FLOAT_AB(add, 0x15, 0x000007C0);
1682 /* fdiv - fdivs */
1683 GEN_FLOAT_AB(div, 0x12, 0x000007C0);
1684 /* fmul - fmuls */
1685 GEN_FLOAT_AC(mul, 0x19, 0x0000F800);
1686
1687 /* fre */
1688 GEN_FLOAT_BS(re, 0x3F, 0x18, PPC_FLOAT_EXT);
1689
1690 /* fres */
1691 GEN_FLOAT_BS(res, 0x3B, 0x18, PPC_FLOAT_FRES);
1692
1693 /* frsqrte */
1694 GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A, PPC_FLOAT_FRSQRTE);
1695
1696 /* fsel */
1697 _GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0, PPC_FLOAT_FSEL);
1698 /* fsub - fsubs */
1699 GEN_FLOAT_AB(sub, 0x14, 0x000007C0);
1700 /* Optional: */
1701 /* fsqrt */
1702 GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
1703 {
1704     if (unlikely(!ctx->fpu_enabled)) {
1705         GEN_EXCP_NO_FP(ctx);
1706         return;
1707     }
1708     gen_op_reset_scrfx();
1709     gen_op_load_fpr_FT0(rB(ctx->opcode));
1710     gen_op_fsqrt();
1711     gen_op_store_FT0_fpr(rD(ctx->opcode));
1712     if (unlikely(Rc(ctx->opcode) != 0))
1713         gen_op_set_Rc1();
1714 }
1715
1716 GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
1717 {
1718     if (unlikely(!ctx->fpu_enabled)) {
1719         GEN_EXCP_NO_FP(ctx);
1720         return;
1721     }
1722     gen_op_reset_scrfx();
1723     gen_op_load_fpr_FT0(rB(ctx->opcode));
1724     gen_op_fsqrt();
1725     gen_op_frsp();
1726     gen_op_store_FT0_fpr(rD(ctx->opcode));
1727     if (unlikely(Rc(ctx->opcode) != 0))
1728         gen_op_set_Rc1();
1729 }
1730
1731 /***                     Floating-Point multiply-and-add                   ***/
1732 /* fmadd - fmadds */
1733 GEN_FLOAT_ACB(madd, 0x1D, PPC_FLOAT);
1734 /* fmsub - fmsubs */
1735 GEN_FLOAT_ACB(msub, 0x1C, PPC_FLOAT);
1736 /* fnmadd - fnmadds */
1737 GEN_FLOAT_ACB(nmadd, 0x1F, PPC_FLOAT);
1738 /* fnmsub - fnmsubs */
1739 GEN_FLOAT_ACB(nmsub, 0x1E, PPC_FLOAT);
1740
1741 /***                     Floating-Point round & convert                    ***/
1742 /* fctiw */
1743 GEN_FLOAT_B(ctiw, 0x0E, 0x00, PPC_FLOAT);
1744 /* fctiwz */
1745 GEN_FLOAT_B(ctiwz, 0x0F, 0x00, PPC_FLOAT);
1746 /* frsp */
1747 GEN_FLOAT_B(rsp, 0x0C, 0x00, PPC_FLOAT);
1748 #if defined(TARGET_PPC64)
1749 /* fcfid */
1750 GEN_FLOAT_B(cfid, 0x0E, 0x1A, PPC_64B);
1751 /* fctid */
1752 GEN_FLOAT_B(ctid, 0x0E, 0x19, PPC_64B);
1753 /* fctidz */
1754 GEN_FLOAT_B(ctidz, 0x0F, 0x19, PPC_64B);
1755 #endif
1756
1757 /* frin */
1758 GEN_FLOAT_B(rin, 0x08, 0x0C, PPC_FLOAT_EXT);
1759 /* friz */
1760 GEN_FLOAT_B(riz, 0x08, 0x0D, PPC_FLOAT_EXT);
1761 /* frip */
1762 GEN_FLOAT_B(rip, 0x08, 0x0E, PPC_FLOAT_EXT);
1763 /* frim */
1764 GEN_FLOAT_B(rim, 0x08, 0x0F, PPC_FLOAT_EXT);
1765
1766 /***                         Floating-Point compare                        ***/
1767 /* fcmpo */
1768 GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT)
1769 {
1770     if (unlikely(!ctx->fpu_enabled)) {
1771         GEN_EXCP_NO_FP(ctx);
1772         return;
1773     }
1774     gen_op_reset_scrfx();
1775     gen_op_load_fpr_FT0(rA(ctx->opcode));
1776     gen_op_load_fpr_FT1(rB(ctx->opcode));
1777     gen_op_fcmpo();
1778     gen_op_store_T0_crf(crfD(ctx->opcode));
1779 }
1780
1781 /* fcmpu */
1782 GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT)
1783 {
1784     if (unlikely(!ctx->fpu_enabled)) {
1785         GEN_EXCP_NO_FP(ctx);
1786         return;
1787     }
1788     gen_op_reset_scrfx();
1789     gen_op_load_fpr_FT0(rA(ctx->opcode));
1790     gen_op_load_fpr_FT1(rB(ctx->opcode));
1791     gen_op_fcmpu();
1792     gen_op_store_T0_crf(crfD(ctx->opcode));
1793 }
1794
1795 /***                         Floating-point move                           ***/
1796 /* fabs */
1797 GEN_FLOAT_B(abs, 0x08, 0x08, PPC_FLOAT);
1798
1799 /* fmr  - fmr. */
1800 GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT)
1801 {
1802     if (unlikely(!ctx->fpu_enabled)) {
1803         GEN_EXCP_NO_FP(ctx);
1804         return;
1805     }
1806     gen_op_reset_scrfx();
1807     gen_op_load_fpr_FT0(rB(ctx->opcode));
1808     gen_op_store_FT0_fpr(rD(ctx->opcode));
1809     if (unlikely(Rc(ctx->opcode) != 0))
1810         gen_op_set_Rc1();
1811 }
1812
1813 /* fnabs */
1814 GEN_FLOAT_B(nabs, 0x08, 0x04, PPC_FLOAT);
1815 /* fneg */
1816 GEN_FLOAT_B(neg, 0x08, 0x01, PPC_FLOAT);
1817
1818 /***                  Floating-Point status & ctrl register                ***/
1819 /* mcrfs */
1820 GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT)
1821 {
1822     if (unlikely(!ctx->fpu_enabled)) {
1823         GEN_EXCP_NO_FP(ctx);
1824         return;
1825     }
1826     gen_op_load_fpscr_T0(crfS(ctx->opcode));
1827     gen_op_store_T0_crf(crfD(ctx->opcode));
1828     gen_op_clear_fpscr(crfS(ctx->opcode));
1829 }
1830
1831 /* mffs */
1832 GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT)
1833 {
1834     if (unlikely(!ctx->fpu_enabled)) {
1835         GEN_EXCP_NO_FP(ctx);
1836         return;
1837     }
1838     gen_op_load_fpscr();
1839     gen_op_store_FT0_fpr(rD(ctx->opcode));
1840     if (unlikely(Rc(ctx->opcode) != 0))
1841         gen_op_set_Rc1();
1842 }
1843
1844 /* mtfsb0 */
1845 GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT)
1846 {
1847     uint8_t crb;
1848
1849     if (unlikely(!ctx->fpu_enabled)) {
1850         GEN_EXCP_NO_FP(ctx);
1851         return;
1852     }
1853     crb = crbD(ctx->opcode) >> 2;
1854     gen_op_load_fpscr_T0(crb);
1855     gen_op_andi_T0(~(1 << (crbD(ctx->opcode) & 0x03)));
1856     gen_op_store_T0_fpscr(crb);
1857     if (unlikely(Rc(ctx->opcode) != 0))
1858         gen_op_set_Rc1();
1859 }
1860
1861 /* mtfsb1 */
1862 GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT)
1863 {
1864     uint8_t crb;
1865
1866     if (unlikely(!ctx->fpu_enabled)) {
1867         GEN_EXCP_NO_FP(ctx);
1868         return;
1869     }
1870     crb = crbD(ctx->opcode) >> 2;
1871     gen_op_load_fpscr_T0(crb);
1872     gen_op_ori(1 << (crbD(ctx->opcode) & 0x03));
1873     gen_op_store_T0_fpscr(crb);
1874     if (unlikely(Rc(ctx->opcode) != 0))
1875         gen_op_set_Rc1();
1876 }
1877
1878 /* mtfsf */
1879 GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT)
1880 {
1881     if (unlikely(!ctx->fpu_enabled)) {
1882         GEN_EXCP_NO_FP(ctx);
1883         return;
1884     }
1885     gen_op_load_fpr_FT0(rB(ctx->opcode));
1886     gen_op_store_fpscr(FM(ctx->opcode));
1887     if (unlikely(Rc(ctx->opcode) != 0))
1888         gen_op_set_Rc1();
1889 }
1890
1891 /* mtfsfi */
1892 GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT)
1893 {
1894     if (unlikely(!ctx->fpu_enabled)) {
1895         GEN_EXCP_NO_FP(ctx);
1896         return;
1897     }
1898     gen_op_store_T0_fpscri(crbD(ctx->opcode) >> 2, FPIMM(ctx->opcode));
1899     if (unlikely(Rc(ctx->opcode) != 0))
1900         gen_op_set_Rc1();
1901 }
1902
1903 /***                           Addressing modes                            ***/
1904 /* Register indirect with immediate index : EA = (rA|0) + SIMM */
1905 static inline void gen_addr_imm_index (DisasContext *ctx, int maskl)
1906 {
1907     target_long simm = SIMM(ctx->opcode);
1908
1909     if (maskl)
1910         simm &= ~0x03;
1911     if (rA(ctx->opcode) == 0) {
1912         gen_set_T0(simm);
1913     } else {
1914         gen_op_load_gpr_T0(rA(ctx->opcode));
1915         if (likely(simm != 0))
1916             gen_op_addi(simm);
1917     }
1918 #ifdef DEBUG_MEMORY_ACCESSES
1919     gen_op_print_mem_EA();
1920 #endif
1921 }
1922
1923 static inline void gen_addr_reg_index (DisasContext *ctx)
1924 {
1925     if (rA(ctx->opcode) == 0) {
1926         gen_op_load_gpr_T0(rB(ctx->opcode));
1927     } else {
1928         gen_op_load_gpr_T0(rA(ctx->opcode));
1929         gen_op_load_gpr_T1(rB(ctx->opcode));
1930         gen_op_add();
1931     }
1932 #ifdef DEBUG_MEMORY_ACCESSES
1933     gen_op_print_mem_EA();
1934 #endif
1935 }
1936
1937 static inline void gen_addr_register (DisasContext *ctx)
1938 {
1939     if (rA(ctx->opcode) == 0) {
1940         gen_op_reset_T0();
1941     } else {
1942         gen_op_load_gpr_T0(rA(ctx->opcode));
1943     }
1944 #ifdef DEBUG_MEMORY_ACCESSES
1945     gen_op_print_mem_EA();
1946 #endif
1947 }
1948
1949 /***                             Integer load                              ***/
1950 #define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
1951 #if defined(CONFIG_USER_ONLY)
1952 #if defined(TARGET_PPC64)
1953 #define OP_LD_TABLE(width)                                                    \
1954 static GenOpFunc *gen_op_l##width[] = {                                       \
1955     &gen_op_l##width##_raw,                                                   \
1956     &gen_op_l##width##_le_raw,                                                \
1957     &gen_op_l##width##_64_raw,                                                \
1958     &gen_op_l##width##_le_64_raw,                                             \
1959 };
1960 #define OP_ST_TABLE(width)                                                    \
1961 static GenOpFunc *gen_op_st##width[] = {                                      \
1962     &gen_op_st##width##_raw,                                                  \
1963     &gen_op_st##width##_le_raw,                                               \
1964     &gen_op_st##width##_64_raw,                                               \
1965     &gen_op_st##width##_le_64_raw,                                            \
1966 };
1967 /* Byte access routine are endian safe */
1968 #define gen_op_stb_le_64_raw gen_op_stb_64_raw
1969 #define gen_op_lbz_le_64_raw gen_op_lbz_64_raw
1970 #else
1971 #define OP_LD_TABLE(width)                                                    \
1972 static GenOpFunc *gen_op_l##width[] = {                                       \
1973     &gen_op_l##width##_raw,                                                   \
1974     &gen_op_l##width##_le_raw,                                                \
1975 };
1976 #define OP_ST_TABLE(width)                                                    \
1977 static GenOpFunc *gen_op_st##width[] = {                                      \
1978     &gen_op_st##width##_raw,                                                  \
1979     &gen_op_st##width##_le_raw,                                               \
1980 };
1981 #endif
1982 /* Byte access routine are endian safe */
1983 #define gen_op_stb_le_raw gen_op_stb_raw
1984 #define gen_op_lbz_le_raw gen_op_lbz_raw
1985 #else
1986 #if defined(TARGET_PPC64)
1987 #define OP_LD_TABLE(width)                                                    \
1988 static GenOpFunc *gen_op_l##width[] = {                                       \
1989     &gen_op_l##width##_user,                                                  \
1990     &gen_op_l##width##_le_user,                                               \
1991     &gen_op_l##width##_kernel,                                                \
1992     &gen_op_l##width##_le_kernel,                                             \
1993     &gen_op_l##width##_64_user,                                               \
1994     &gen_op_l##width##_le_64_user,                                            \
1995     &gen_op_l##width##_64_kernel,                                             \
1996     &gen_op_l##width##_le_64_kernel,                                          \
1997 };
1998 #define OP_ST_TABLE(width)                                                    \
1999 static GenOpFunc *gen_op_st##width[] = {                                      \
2000     &gen_op_st##width##_user,                                                 \
2001     &gen_op_st##width##_le_user,                                              \
2002     &gen_op_st##width##_kernel,                                               \
2003     &gen_op_st##width##_le_kernel,                                            \
2004     &gen_op_st##width##_64_user,                                              \
2005     &gen_op_st##width##_le_64_user,                                           \
2006     &gen_op_st##width##_64_kernel,                                            \
2007     &gen_op_st##width##_le_64_kernel,                                         \
2008 };
2009 /* Byte access routine are endian safe */
2010 #define gen_op_stb_le_64_user gen_op_stb_64_user
2011 #define gen_op_lbz_le_64_user gen_op_lbz_64_user
2012 #define gen_op_stb_le_64_kernel gen_op_stb_64_kernel
2013 #define gen_op_lbz_le_64_kernel gen_op_lbz_64_kernel
2014 #else
2015 #define OP_LD_TABLE(width)                                                    \
2016 static GenOpFunc *gen_op_l##width[] = {                                       \
2017     &gen_op_l##width##_user,                                                  \
2018     &gen_op_l##width##_le_user,                                               \
2019     &gen_op_l##width##_kernel,                                                \
2020     &gen_op_l##width##_le_kernel,                                             \
2021 };
2022 #define OP_ST_TABLE(width)                                                    \
2023 static GenOpFunc *gen_op_st##width[] = {                                      \
2024     &gen_op_st##width##_user,                                                 \
2025     &gen_op_st##width##_le_user,                                              \
2026     &gen_op_st##width##_kernel,                                               \
2027     &gen_op_st##width##_le_kernel,                                            \
2028 };
2029 #endif
2030 /* Byte access routine are endian safe */
2031 #define gen_op_stb_le_user gen_op_stb_user
2032 #define gen_op_lbz_le_user gen_op_lbz_user
2033 #define gen_op_stb_le_kernel gen_op_stb_kernel
2034 #define gen_op_lbz_le_kernel gen_op_lbz_kernel
2035 #endif
2036
2037 #define GEN_LD(width, opc, type)                                              \
2038 GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, type)                      \
2039 {                                                                             \
2040     gen_addr_imm_index(ctx, 0);                                               \
2041     op_ldst(l##width);                                                        \
2042     gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
2043 }
2044
2045 #define GEN_LDU(width, opc, type)                                             \
2046 GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                   \
2047 {                                                                             \
2048     if (unlikely(rA(ctx->opcode) == 0 ||                                      \
2049                  rA(ctx->opcode) == rD(ctx->opcode))) {                       \
2050         GEN_EXCP_INVAL(ctx);                                                  \
2051         return;                                                               \
2052     }                                                                         \
2053     if (type == PPC_64B)                                                      \
2054         gen_addr_imm_index(ctx, 1);                                           \
2055     else                                                                      \
2056         gen_addr_imm_index(ctx, 0);                                           \
2057     op_ldst(l##width);                                                        \
2058     gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
2059     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2060 }
2061
2062 #define GEN_LDUX(width, opc2, opc3, type)                                     \
2063 GEN_HANDLER(l##width##ux, 0x1F, opc2, opc3, 0x00000001, type)                 \
2064 {                                                                             \
2065     if (unlikely(rA(ctx->opcode) == 0 ||                                      \
2066                  rA(ctx->opcode) == rD(ctx->opcode))) {                       \
2067         GEN_EXCP_INVAL(ctx);                                                  \
2068         return;                                                               \
2069     }                                                                         \
2070     gen_addr_reg_index(ctx);                                                  \
2071     op_ldst(l##width);                                                        \
2072     gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
2073     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2074 }
2075
2076 #define GEN_LDX(width, opc2, opc3, type)                                      \
2077 GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, type)                  \
2078 {                                                                             \
2079     gen_addr_reg_index(ctx);                                                  \
2080     op_ldst(l##width);                                                        \
2081     gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
2082 }
2083
2084 #define GEN_LDS(width, op, type)                                              \
2085 OP_LD_TABLE(width);                                                           \
2086 GEN_LD(width, op | 0x20, type);                                               \
2087 GEN_LDU(width, op | 0x21, type);                                              \
2088 GEN_LDUX(width, 0x17, op | 0x01, type);                                       \
2089 GEN_LDX(width, 0x17, op | 0x00, type)
2090
2091 /* lbz lbzu lbzux lbzx */
2092 GEN_LDS(bz, 0x02, PPC_INTEGER);
2093 /* lha lhau lhaux lhax */
2094 GEN_LDS(ha, 0x0A, PPC_INTEGER);
2095 /* lhz lhzu lhzux lhzx */
2096 GEN_LDS(hz, 0x08, PPC_INTEGER);
2097 /* lwz lwzu lwzux lwzx */
2098 GEN_LDS(wz, 0x00, PPC_INTEGER);
2099 #if defined(TARGET_PPC64)
2100 OP_LD_TABLE(wa);
2101 OP_LD_TABLE(d);
2102 /* lwaux */
2103 GEN_LDUX(wa, 0x15, 0x0B, PPC_64B);
2104 /* lwax */
2105 GEN_LDX(wa, 0x15, 0x0A, PPC_64B);
2106 /* ldux */
2107 GEN_LDUX(d, 0x15, 0x01, PPC_64B);
2108 /* ldx */
2109 GEN_LDX(d, 0x15, 0x00, PPC_64B);
2110 GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B)
2111 {
2112     if (Rc(ctx->opcode)) {
2113         if (unlikely(rA(ctx->opcode) == 0 ||
2114                      rA(ctx->opcode) == rD(ctx->opcode))) {
2115             GEN_EXCP_INVAL(ctx);
2116             return;
2117         }
2118     }
2119     gen_addr_imm_index(ctx, 1);
2120     if (ctx->opcode & 0x02) {
2121         /* lwa (lwau is undefined) */
2122         op_ldst(lwa);
2123     } else {
2124         /* ld - ldu */
2125         op_ldst(ld);
2126     }
2127     gen_op_store_T1_gpr(rD(ctx->opcode));
2128     if (Rc(ctx->opcode))
2129         gen_op_store_T0_gpr(rA(ctx->opcode));
2130 }
2131 #endif
2132
2133 /***                              Integer store                            ***/
2134 #define GEN_ST(width, opc, type)                                              \
2135 GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, type)                     \
2136 {                                                                             \
2137     gen_addr_imm_index(ctx, 0);                                               \
2138     gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
2139     op_ldst(st##width);                                                       \
2140 }
2141
2142 #define GEN_STU(width, opc, type)                                             \
2143 GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                  \
2144 {                                                                             \
2145     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2146         GEN_EXCP_INVAL(ctx);                                                  \
2147         return;                                                               \
2148     }                                                                         \
2149     if (type == PPC_64B)                                                      \
2150         gen_addr_imm_index(ctx, 1);                                           \
2151     else                                                                      \
2152         gen_addr_imm_index(ctx, 0);                                           \
2153     gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
2154     op_ldst(st##width);                                                       \
2155     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2156 }
2157
2158 #define GEN_STUX(width, opc2, opc3, type)                                     \
2159 GEN_HANDLER(st##width##ux, 0x1F, opc2, opc3, 0x00000001, type)                \
2160 {                                                                             \
2161     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2162         GEN_EXCP_INVAL(ctx);                                                  \
2163         return;                                                               \
2164     }                                                                         \
2165     gen_addr_reg_index(ctx);                                                  \
2166     gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
2167     op_ldst(st##width);                                                       \
2168     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2169 }
2170
2171 #define GEN_STX(width, opc2, opc3, type)                                      \
2172 GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, type)                 \
2173 {                                                                             \
2174     gen_addr_reg_index(ctx);                                                  \
2175     gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
2176     op_ldst(st##width);                                                       \
2177 }
2178
2179 #define GEN_STS(width, op, type)                                              \
2180 OP_ST_TABLE(width);                                                           \
2181 GEN_ST(width, op | 0x20, type);                                               \
2182 GEN_STU(width, op | 0x21, type);                                              \
2183 GEN_STUX(width, 0x17, op | 0x01, type);                                       \
2184 GEN_STX(width, 0x17, op | 0x00, type)
2185
2186 /* stb stbu stbux stbx */
2187 GEN_STS(b, 0x06, PPC_INTEGER);
2188 /* sth sthu sthux sthx */
2189 GEN_STS(h, 0x0C, PPC_INTEGER);
2190 /* stw stwu stwux stwx */
2191 GEN_STS(w, 0x04, PPC_INTEGER);
2192 #if defined(TARGET_PPC64)
2193 OP_ST_TABLE(d);
2194 GEN_STUX(d, 0x15, 0x05, PPC_64B);
2195 GEN_STX(d, 0x15, 0x04, PPC_64B);
2196 GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000002, PPC_64B)
2197 {
2198     if (Rc(ctx->opcode)) {
2199         if (unlikely(rA(ctx->opcode) == 0)) {
2200             GEN_EXCP_INVAL(ctx);
2201             return;
2202         }
2203     }
2204     gen_addr_imm_index(ctx, 1);
2205     gen_op_load_gpr_T1(rS(ctx->opcode));
2206     op_ldst(std);
2207     if (Rc(ctx->opcode))
2208         gen_op_store_T0_gpr(rA(ctx->opcode));
2209 }
2210 #endif
2211 /***                Integer load and store with byte reverse               ***/
2212 /* lhbrx */
2213 OP_LD_TABLE(hbr);
2214 GEN_LDX(hbr, 0x16, 0x18, PPC_INTEGER);
2215 /* lwbrx */
2216 OP_LD_TABLE(wbr);
2217 GEN_LDX(wbr, 0x16, 0x10, PPC_INTEGER);
2218 /* sthbrx */
2219 OP_ST_TABLE(hbr);
2220 GEN_STX(hbr, 0x16, 0x1C, PPC_INTEGER);
2221 /* stwbrx */
2222 OP_ST_TABLE(wbr);
2223 GEN_STX(wbr, 0x16, 0x14, PPC_INTEGER);
2224
2225 /***                    Integer load and store multiple                    ***/
2226 #define op_ldstm(name, reg) (*gen_op_##name[ctx->mem_idx])(reg)
2227 #if defined(TARGET_PPC64)
2228 #if defined(CONFIG_USER_ONLY)
2229 static GenOpFunc1 *gen_op_lmw[] = {
2230     &gen_op_lmw_raw,
2231     &gen_op_lmw_le_raw,
2232     &gen_op_lmw_64_raw,
2233     &gen_op_lmw_le_64_raw,
2234 };
2235 static GenOpFunc1 *gen_op_stmw[] = {
2236     &gen_op_stmw_64_raw,
2237     &gen_op_stmw_le_64_raw,
2238 };
2239 #else
2240 static GenOpFunc1 *gen_op_lmw[] = {
2241     &gen_op_lmw_user,
2242     &gen_op_lmw_le_user,
2243     &gen_op_lmw_kernel,
2244     &gen_op_lmw_le_kernel,
2245     &gen_op_lmw_64_user,
2246     &gen_op_lmw_le_64_user,
2247     &gen_op_lmw_64_kernel,
2248     &gen_op_lmw_le_64_kernel,
2249 };
2250 static GenOpFunc1 *gen_op_stmw[] = {
2251     &gen_op_stmw_user,
2252     &gen_op_stmw_le_user,
2253     &gen_op_stmw_kernel,
2254     &gen_op_stmw_le_kernel,
2255     &gen_op_stmw_64_user,
2256     &gen_op_stmw_le_64_user,
2257     &gen_op_stmw_64_kernel,
2258     &gen_op_stmw_le_64_kernel,
2259 };
2260 #endif
2261 #else
2262 #if defined(CONFIG_USER_ONLY)
2263 static GenOpFunc1 *gen_op_lmw[] = {
2264     &gen_op_lmw_raw,
2265     &gen_op_lmw_le_raw,
2266 };
2267 static GenOpFunc1 *gen_op_stmw[] = {
2268     &gen_op_stmw_raw,
2269     &gen_op_stmw_le_raw,
2270 };
2271 #else
2272 static GenOpFunc1 *gen_op_lmw[] = {
2273     &gen_op_lmw_user,
2274     &gen_op_lmw_le_user,
2275     &gen_op_lmw_kernel,
2276     &gen_op_lmw_le_kernel,
2277 };
2278 static GenOpFunc1 *gen_op_stmw[] = {
2279     &gen_op_stmw_user,
2280     &gen_op_stmw_le_user,
2281     &gen_op_stmw_kernel,
2282     &gen_op_stmw_le_kernel,
2283 };
2284 #endif
2285 #endif
2286
2287 /* lmw */
2288 GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
2289 {
2290     /* NIP cannot be restored if the memory exception comes from an helper */
2291     gen_update_nip(ctx, ctx->nip - 4);
2292     gen_addr_imm_index(ctx, 0);
2293     op_ldstm(lmw, rD(ctx->opcode));
2294 }
2295
2296 /* stmw */
2297 GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
2298 {
2299     /* NIP cannot be restored if the memory exception comes from an helper */
2300     gen_update_nip(ctx, ctx->nip - 4);
2301     gen_addr_imm_index(ctx, 0);
2302     op_ldstm(stmw, rS(ctx->opcode));
2303 }
2304
2305 /***                    Integer load and store strings                     ***/
2306 #define op_ldsts(name, start) (*gen_op_##name[ctx->mem_idx])(start)
2307 #define op_ldstsx(name, rd, ra, rb) (*gen_op_##name[ctx->mem_idx])(rd, ra, rb)
2308 #if defined(TARGET_PPC64)
2309 #if defined(CONFIG_USER_ONLY)
2310 static GenOpFunc1 *gen_op_lswi[] = {
2311     &gen_op_lswi_raw,
2312     &gen_op_lswi_le_raw,
2313     &gen_op_lswi_64_raw,
2314     &gen_op_lswi_le_64_raw,
2315 };
2316 static GenOpFunc3 *gen_op_lswx[] = {
2317     &gen_op_lswx_raw,
2318     &gen_op_lswx_le_raw,
2319     &gen_op_lswx_64_raw,
2320     &gen_op_lswx_le_64_raw,
2321 };
2322 static GenOpFunc1 *gen_op_stsw[] = {
2323     &gen_op_stsw_raw,
2324     &gen_op_stsw_le_raw,
2325     &gen_op_stsw_64_raw,
2326     &gen_op_stsw_le_64_raw,
2327 };
2328 #else
2329 static GenOpFunc1 *gen_op_lswi[] = {
2330     &gen_op_lswi_user,
2331     &gen_op_lswi_le_user,
2332     &gen_op_lswi_kernel,
2333     &gen_op_lswi_le_kernel,
2334     &gen_op_lswi_64_user,
2335     &gen_op_lswi_le_64_user,
2336     &gen_op_lswi_64_kernel,
2337     &gen_op_lswi_le_64_kernel,
2338 };
2339 static GenOpFunc3 *gen_op_lswx[] = {
2340     &gen_op_lswx_user,
2341     &gen_op_lswx_le_user,
2342     &gen_op_lswx_kernel,
2343     &gen_op_lswx_le_kernel,
2344     &gen_op_lswx_64_user,
2345     &gen_op_lswx_le_64_user,
2346     &gen_op_lswx_64_kernel,
2347     &gen_op_lswx_le_64_kernel,
2348 };
2349 static GenOpFunc1 *gen_op_stsw[] = {
2350     &gen_op_stsw_user,
2351     &gen_op_stsw_le_user,
2352     &gen_op_stsw_kernel,
2353     &gen_op_stsw_le_kernel,
2354     &gen_op_stsw_64_user,
2355     &gen_op_stsw_le_64_user,
2356     &gen_op_stsw_64_kernel,
2357     &gen_op_stsw_le_64_kernel,
2358 };
2359 #endif
2360 #else
2361 #if defined(CONFIG_USER_ONLY)
2362 static GenOpFunc1 *gen_op_lswi[] = {
2363     &gen_op_lswi_raw,
2364     &gen_op_lswi_le_raw,
2365 };
2366 static GenOpFunc3 *gen_op_lswx[] = {
2367     &gen_op_lswx_raw,
2368     &gen_op_lswx_le_raw,
2369 };
2370 static GenOpFunc1 *gen_op_stsw[] = {
2371     &gen_op_stsw_raw,
2372     &gen_op_stsw_le_raw,
2373 };
2374 #else
2375 static GenOpFunc1 *gen_op_lswi[] = {
2376     &gen_op_lswi_user,
2377     &gen_op_lswi_le_user,
2378     &gen_op_lswi_kernel,
2379     &gen_op_lswi_le_kernel,
2380 };
2381 static GenOpFunc3 *gen_op_lswx[] = {
2382     &gen_op_lswx_user,
2383     &gen_op_lswx_le_user,
2384     &gen_op_lswx_kernel,
2385     &gen_op_lswx_le_kernel,
2386 };
2387 static GenOpFunc1 *gen_op_stsw[] = {
2388     &gen_op_stsw_user,
2389     &gen_op_stsw_le_user,
2390     &gen_op_stsw_kernel,
2391     &gen_op_stsw_le_kernel,
2392 };
2393 #endif
2394 #endif
2395
2396 /* lswi */
2397 /* PowerPC32 specification says we must generate an exception if
2398  * rA is in the range of registers to be loaded.
2399  * In an other hand, IBM says this is valid, but rA won't be loaded.
2400  * For now, I'll follow the spec...
2401  */
2402 GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_INTEGER)
2403 {
2404     int nb = NB(ctx->opcode);
2405     int start = rD(ctx->opcode);
2406     int ra = rA(ctx->opcode);
2407     int nr;
2408
2409     if (nb == 0)
2410         nb = 32;
2411     nr = nb / 4;
2412     if (unlikely(((start + nr) > 32  &&
2413                   start <= ra && (start + nr - 32) > ra) ||
2414                  ((start + nr) <= 32 && start <= ra && (start + nr) > ra))) {
2415         GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM,
2416                  POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_LSWX);
2417         return;
2418     }
2419     /* NIP cannot be restored if the memory exception comes from an helper */
2420     gen_update_nip(ctx, ctx->nip - 4);
2421     gen_addr_register(ctx);
2422     gen_op_set_T1(nb);
2423     op_ldsts(lswi, start);
2424 }
2425
2426 /* lswx */
2427 GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_INTEGER)
2428 {
2429     int ra = rA(ctx->opcode);
2430     int rb = rB(ctx->opcode);
2431
2432     /* NIP cannot be restored if the memory exception comes from an helper */
2433     gen_update_nip(ctx, ctx->nip - 4);
2434     gen_addr_reg_index(ctx);
2435     if (ra == 0) {
2436         ra = rb;
2437     }
2438     gen_op_load_xer_bc();
2439     op_ldstsx(lswx, rD(ctx->opcode), ra, rb);
2440 }
2441
2442 /* stswi */
2443 GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_INTEGER)
2444 {
2445     int nb = NB(ctx->opcode);
2446
2447     /* NIP cannot be restored if the memory exception comes from an helper */
2448     gen_update_nip(ctx, ctx->nip - 4);
2449     gen_addr_register(ctx);
2450     if (nb == 0)
2451         nb = 32;
2452     gen_op_set_T1(nb);
2453     op_ldsts(stsw, rS(ctx->opcode));
2454 }
2455
2456 /* stswx */
2457 GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_INTEGER)
2458 {
2459     /* NIP cannot be restored if the memory exception comes from an helper */
2460     gen_update_nip(ctx, ctx->nip - 4);
2461     gen_addr_reg_index(ctx);
2462     gen_op_load_xer_bc();
2463     op_ldsts(stsw, rS(ctx->opcode));
2464 }
2465
2466 /***                        Memory synchronisation                         ***/
2467 /* eieio */
2468 GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FFF801, PPC_MEM_EIEIO)
2469 {
2470 }
2471
2472 /* isync */
2473 GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FFF801, PPC_MEM)
2474 {
2475     GEN_STOP(ctx);
2476 }
2477
2478 #define op_lwarx() (*gen_op_lwarx[ctx->mem_idx])()
2479 #define op_stwcx() (*gen_op_stwcx[ctx->mem_idx])()
2480 #if defined(TARGET_PPC64)
2481 #if defined(CONFIG_USER_ONLY)
2482 static GenOpFunc *gen_op_lwarx[] = {
2483     &gen_op_lwarx_raw,
2484     &gen_op_lwarx_le_raw,
2485     &gen_op_lwarx_64_raw,
2486     &gen_op_lwarx_le_64_raw,
2487 };
2488 static GenOpFunc *gen_op_stwcx[] = {
2489     &gen_op_stwcx_raw,
2490     &gen_op_stwcx_le_raw,
2491     &gen_op_stwcx_64_raw,
2492     &gen_op_stwcx_le_64_raw,
2493 };
2494 #else
2495 static GenOpFunc *gen_op_lwarx[] = {
2496     &gen_op_lwarx_user,
2497     &gen_op_lwarx_le_user,
2498     &gen_op_lwarx_kernel,
2499     &gen_op_lwarx_le_kernel,
2500     &gen_op_lwarx_64_user,
2501     &gen_op_lwarx_le_64_user,
2502     &gen_op_lwarx_64_kernel,
2503     &gen_op_lwarx_le_64_kernel,
2504 };
2505 static GenOpFunc *gen_op_stwcx[] = {
2506     &gen_op_stwcx_user,
2507     &gen_op_stwcx_le_user,
2508     &gen_op_stwcx_kernel,
2509     &gen_op_stwcx_le_kernel,
2510     &gen_op_stwcx_64_user,
2511     &gen_op_stwcx_le_64_user,
2512     &gen_op_stwcx_64_kernel,
2513     &gen_op_stwcx_le_64_kernel,
2514 };
2515 #endif
2516 #else
2517 #if defined(CONFIG_USER_ONLY)
2518 static GenOpFunc *gen_op_lwarx[] = {
2519     &gen_op_lwarx_raw,
2520     &gen_op_lwarx_le_raw,
2521 };
2522 static GenOpFunc *gen_op_stwcx[] = {
2523     &gen_op_stwcx_raw,
2524     &gen_op_stwcx_le_raw,
2525 };
2526 #else
2527 static GenOpFunc *gen_op_lwarx[] = {
2528     &gen_op_lwarx_user,
2529     &gen_op_lwarx_le_user,
2530     &gen_op_lwarx_kernel,
2531     &gen_op_lwarx_le_kernel,
2532 };
2533 static GenOpFunc *gen_op_stwcx[] = {
2534     &gen_op_stwcx_user,
2535     &gen_op_stwcx_le_user,
2536     &gen_op_stwcx_kernel,
2537     &gen_op_stwcx_le_kernel,
2538 };
2539 #endif
2540 #endif
2541
2542 /* lwarx */
2543 GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000001, PPC_RES)
2544 {
2545     gen_addr_reg_index(ctx);
2546     op_lwarx();
2547     gen_op_store_T1_gpr(rD(ctx->opcode));
2548 }
2549
2550 /* stwcx. */
2551 GEN_HANDLER(stwcx_, 0x1F, 0x16, 0x04, 0x00000000, PPC_RES)
2552 {
2553     gen_addr_reg_index(ctx);
2554     gen_op_load_gpr_T1(rS(ctx->opcode));
2555     op_stwcx();
2556 }
2557
2558 #if defined(TARGET_PPC64)
2559 #define op_ldarx() (*gen_op_ldarx[ctx->mem_idx])()
2560 #define op_stdcx() (*gen_op_stdcx[ctx->mem_idx])()
2561 #if defined(CONFIG_USER_ONLY)
2562 static GenOpFunc *gen_op_ldarx[] = {
2563     &gen_op_ldarx_raw,
2564     &gen_op_ldarx_le_raw,
2565     &gen_op_ldarx_64_raw,
2566     &gen_op_ldarx_le_64_raw,
2567 };
2568 static GenOpFunc *gen_op_stdcx[] = {
2569     &gen_op_stdcx_raw,
2570     &gen_op_stdcx_le_raw,
2571     &gen_op_stdcx_64_raw,
2572     &gen_op_stdcx_le_64_raw,
2573 };
2574 #else
2575 static GenOpFunc *gen_op_ldarx[] = {
2576     &gen_op_ldarx_user,
2577     &gen_op_ldarx_le_user,
2578     &gen_op_ldarx_kernel,
2579     &gen_op_ldarx_le_kernel,
2580     &gen_op_ldarx_64_user,
2581     &gen_op_ldarx_le_64_user,
2582     &gen_op_ldarx_64_kernel,
2583     &gen_op_ldarx_le_64_kernel,
2584 };
2585 static GenOpFunc *gen_op_stdcx[] = {
2586     &gen_op_stdcx_user,
2587     &gen_op_stdcx_le_user,
2588     &gen_op_stdcx_kernel,
2589     &gen_op_stdcx_le_kernel,
2590     &gen_op_stdcx_64_user,
2591     &gen_op_stdcx_le_64_user,
2592     &gen_op_stdcx_64_kernel,
2593     &gen_op_stdcx_le_64_kernel,
2594 };
2595 #endif
2596
2597 /* ldarx */
2598 GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000001, PPC_64B)
2599 {
2600     gen_addr_reg_index(ctx);
2601     op_ldarx();
2602     gen_op_store_T1_gpr(rD(ctx->opcode));
2603 }
2604
2605 /* stdcx. */
2606 GEN_HANDLER(stdcx_, 0x1F, 0x16, 0x06, 0x00000000, PPC_64B)
2607 {
2608     gen_addr_reg_index(ctx);
2609     gen_op_load_gpr_T1(rS(ctx->opcode));
2610     op_stdcx();
2611 }
2612 #endif /* defined(TARGET_PPC64) */
2613
2614 /* sync */
2615 GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x03BFF801, PPC_MEM_SYNC)
2616 {
2617 }
2618
2619 /* wait */
2620 GEN_HANDLER(wait, 0x1F, 0x1E, 0x01, 0x03FFF801, PPC_WAIT)
2621 {
2622     /* Stop translation, as the CPU is supposed to sleep from now */
2623     /* XXX: TODO: handle this idle CPU case */
2624     GEN_STOP(ctx);
2625 }
2626
2627 /***                         Floating-point load                           ***/
2628 #define GEN_LDF(width, opc, type)                                             \
2629 GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, type)                      \
2630 {                                                                             \
2631     if (unlikely(!ctx->fpu_enabled)) {                                        \
2632         GEN_EXCP_NO_FP(ctx);                                                  \
2633         return;                                                               \
2634     }                                                                         \
2635     gen_addr_imm_index(ctx, 0);                                               \
2636     op_ldst(l##width);                                                        \
2637     gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2638 }
2639
2640 #define GEN_LDUF(width, opc, type)                                            \
2641 GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                   \
2642 {                                                                             \
2643     if (unlikely(!ctx->fpu_enabled)) {                                        \
2644         GEN_EXCP_NO_FP(ctx);                                                  \
2645         return;                                                               \
2646     }                                                                         \
2647     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2648         GEN_EXCP_INVAL(ctx);                                                  \
2649         return;                                                               \
2650     }                                                                         \
2651     gen_addr_imm_index(ctx, 0);                                               \
2652     op_ldst(l##width);                                                        \
2653     gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2654     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2655 }
2656
2657 #define GEN_LDUXF(width, opc, type)                                           \
2658 GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, type)                  \
2659 {                                                                             \
2660     if (unlikely(!ctx->fpu_enabled)) {                                        \
2661         GEN_EXCP_NO_FP(ctx);                                                  \
2662         return;                                                               \
2663     }                                                                         \
2664     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2665         GEN_EXCP_INVAL(ctx);                                                  \
2666         return;                                                               \
2667     }                                                                         \
2668     gen_addr_reg_index(ctx);                                                  \
2669     op_ldst(l##width);                                                        \
2670     gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2671     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2672 }
2673
2674 #define GEN_LDXF(width, opc2, opc3, type)                                     \
2675 GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, type)                  \
2676 {                                                                             \
2677     if (unlikely(!ctx->fpu_enabled)) {                                        \
2678         GEN_EXCP_NO_FP(ctx);                                                  \
2679         return;                                                               \
2680     }                                                                         \
2681     gen_addr_reg_index(ctx);                                                  \
2682     op_ldst(l##width);                                                        \
2683     gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2684 }
2685
2686 #define GEN_LDFS(width, op, type)                                             \
2687 OP_LD_TABLE(width);                                                           \
2688 GEN_LDF(width, op | 0x20, type);                                              \
2689 GEN_LDUF(width, op | 0x21, type);                                             \
2690 GEN_LDUXF(width, op | 0x01, type);                                            \
2691 GEN_LDXF(width, 0x17, op | 0x00, type)
2692
2693 /* lfd lfdu lfdux lfdx */
2694 GEN_LDFS(fd, 0x12, PPC_FLOAT);
2695 /* lfs lfsu lfsux lfsx */
2696 GEN_LDFS(fs, 0x10, PPC_FLOAT);
2697
2698 /***                         Floating-point store                          ***/
2699 #define GEN_STF(width, opc, type)                                             \
2700 GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, type)                     \
2701 {                                                                             \
2702     if (unlikely(!ctx->fpu_enabled)) {                                        \
2703         GEN_EXCP_NO_FP(ctx);                                                  \
2704         return;                                                               \
2705     }                                                                         \
2706     gen_addr_imm_index(ctx, 0);                                               \
2707     gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
2708     op_ldst(st##width);                                                       \
2709 }
2710
2711 #define GEN_STUF(width, opc, type)                                            \
2712 GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                  \
2713 {                                                                             \
2714     if (unlikely(!ctx->fpu_enabled)) {                                        \
2715         GEN_EXCP_NO_FP(ctx);                                                  \
2716         return;                                                               \
2717     }                                                                         \
2718     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2719         GEN_EXCP_INVAL(ctx);                                                  \
2720         return;                                                               \
2721     }                                                                         \
2722     gen_addr_imm_index(ctx, 0);                                               \
2723     gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
2724     op_ldst(st##width);                                                       \
2725     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2726 }
2727
2728 #define GEN_STUXF(width, opc, type)                                           \
2729 GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, type)                 \
2730 {                                                                             \
2731     if (unlikely(!ctx->fpu_enabled)) {                                        \
2732         GEN_EXCP_NO_FP(ctx);                                                  \
2733         return;                                                               \
2734     }                                                                         \
2735     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2736         GEN_EXCP_INVAL(ctx);                                                  \
2737         return;                                                               \
2738     }                                                                         \
2739     gen_addr_reg_index(ctx);                                                  \
2740     gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
2741     op_ldst(st##width);                                                       \
2742     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2743 }
2744
2745 #define GEN_STXF(width, opc2, opc3, type)                                     \
2746 GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, type)                 \
2747 {                                                                             \
2748     if (unlikely(!ctx->fpu_enabled)) {                                        \
2749         GEN_EXCP_NO_FP(ctx);                                                  \
2750         return;                                                               \
2751     }                                                                         \
2752     gen_addr_reg_index(ctx);                                                  \
2753     gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
2754     op_ldst(st##width);                                                       \
2755 }
2756
2757 #define GEN_STFS(width, op, type)                                             \
2758 OP_ST_TABLE(width);                                                           \
2759 GEN_STF(width, op | 0x20, type);                                              \
2760 GEN_STUF(width, op | 0x21, type);                                             \
2761 GEN_STUXF(width, op | 0x01, type);                                            \
2762 GEN_STXF(width, 0x17, op | 0x00, type)
2763
2764 /* stfd stfdu stfdux stfdx */
2765 GEN_STFS(fd, 0x16, PPC_FLOAT);
2766 /* stfs stfsu stfsux stfsx */
2767 GEN_STFS(fs, 0x14, PPC_FLOAT);
2768
2769 /* Optional: */
2770 /* stfiwx */
2771 OP_ST_TABLE(fiwx);
2772 GEN_STXF(fiwx, 0x17, 0x1E, PPC_FLOAT_STFIWX);
2773
2774 /***                                Branch                                 ***/
2775 static inline void gen_goto_tb (DisasContext *ctx, int n, target_ulong dest)
2776 {
2777     TranslationBlock *tb;
2778     tb = ctx->tb;
2779     if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
2780         if (n == 0)
2781             gen_op_goto_tb0(TBPARAM(tb));
2782         else
2783             gen_op_goto_tb1(TBPARAM(tb));
2784         gen_set_T1(dest);
2785 #if defined(TARGET_PPC64)
2786         if (ctx->sf_mode)
2787             gen_op_b_T1_64();
2788         else
2789 #endif
2790             gen_op_b_T1();
2791         gen_op_set_T0((long)tb + n);
2792         if (ctx->singlestep_enabled)
2793             gen_op_debug();
2794         gen_op_exit_tb();
2795     } else {
2796         gen_set_T1(dest);
2797 #if defined(TARGET_PPC64)
2798         if (ctx->sf_mode)
2799             gen_op_b_T1_64();
2800         else
2801 #endif
2802             gen_op_b_T1();
2803         gen_op_reset_T0();
2804         if (ctx->singlestep_enabled)
2805             gen_op_debug();
2806         gen_op_exit_tb();
2807     }
2808 }
2809
2810 static inline void gen_setlr (DisasContext *ctx, target_ulong nip)
2811 {
2812 #if defined(TARGET_PPC64)
2813     if (ctx->sf_mode != 0 && (nip >> 32))
2814         gen_op_setlr_64(ctx->nip >> 32, ctx->nip);
2815     else
2816 #endif
2817         gen_op_setlr(ctx->nip);
2818 }
2819
2820 /* b ba bl bla */
2821 GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
2822 {
2823     target_ulong li, target;
2824
2825     /* sign extend LI */
2826 #if defined(TARGET_PPC64)
2827     if (ctx->sf_mode)
2828         li = ((int64_t)LI(ctx->opcode) << 38) >> 38;
2829     else
2830 #endif
2831         li = ((int32_t)LI(ctx->opcode) << 6) >> 6;
2832     if (likely(AA(ctx->opcode) == 0))
2833         target = ctx->nip + li - 4;
2834     else
2835         target = li;
2836 #if defined(TARGET_PPC64)
2837     if (!ctx->sf_mode)
2838         target = (uint32_t)target;
2839 #endif
2840     if (LK(ctx->opcode))
2841         gen_setlr(ctx, ctx->nip);
2842     gen_goto_tb(ctx, 0, target);
2843     ctx->exception = POWERPC_EXCP_BRANCH;
2844 }
2845
2846 #define BCOND_IM  0
2847 #define BCOND_LR  1
2848 #define BCOND_CTR 2
2849
2850 static inline void gen_bcond (DisasContext *ctx, int type)
2851 {
2852     target_ulong target = 0;
2853     target_ulong li;
2854     uint32_t bo = BO(ctx->opcode);
2855     uint32_t bi = BI(ctx->opcode);
2856     uint32_t mask;
2857
2858     if ((bo & 0x4) == 0)
2859         gen_op_dec_ctr();
2860     switch(type) {
2861     case BCOND_IM:
2862         li = (target_long)((int16_t)(BD(ctx->opcode)));
2863         if (likely(AA(ctx->opcode) == 0)) {
2864             target = ctx->nip + li - 4;
2865         } else {
2866             target = li;
2867         }
2868 #if defined(TARGET_PPC64)
2869         if (!ctx->sf_mode)
2870             target = (uint32_t)target;
2871 #endif
2872         break;
2873     case BCOND_CTR:
2874         gen_op_movl_T1_ctr();
2875         break;
2876     default:
2877     case BCOND_LR:
2878         gen_op_movl_T1_lr();
2879         break;
2880     }
2881     if (LK(ctx->opcode))
2882         gen_setlr(ctx, ctx->nip);
2883     if (bo & 0x10) {
2884         /* No CR condition */
2885         switch (bo & 0x6) {
2886         case 0:
2887 #if defined(TARGET_PPC64)
2888             if (ctx->sf_mode)
2889                 gen_op_test_ctr_64();
2890             else
2891 #endif
2892                 gen_op_test_ctr();
2893             break;
2894         case 2:
2895 #if defined(TARGET_PPC64)
2896             if (ctx->sf_mode)
2897                 gen_op_test_ctrz_64();
2898             else
2899 #endif
2900                 gen_op_test_ctrz();
2901             break;
2902         default:
2903         case 4:
2904         case 6:
2905             if (type == BCOND_IM) {
2906                 gen_goto_tb(ctx, 0, target);
2907             } else {
2908 #if defined(TARGET_PPC64)
2909                 if (ctx->sf_mode)
2910                     gen_op_b_T1_64();
2911                 else
2912 #endif
2913                     gen_op_b_T1();
2914                 gen_op_reset_T0();
2915             }
2916             goto no_test;
2917         }
2918     } else {
2919         mask = 1 << (3 - (bi & 0x03));
2920         gen_op_load_crf_T0(bi >> 2);
2921         if (bo & 0x8) {
2922             switch (bo & 0x6) {
2923             case 0:
2924 #if defined(TARGET_PPC64)
2925                 if (ctx->sf_mode)
2926                     gen_op_test_ctr_true_64(mask);
2927                 else
2928 #endif
2929                     gen_op_test_ctr_true(mask);
2930                 break;
2931             case 2:
2932 #if defined(TARGET_PPC64)
2933                 if (ctx->sf_mode)
2934                     gen_op_test_ctrz_true_64(mask);
2935                 else
2936 #endif
2937                     gen_op_test_ctrz_true(mask);
2938                 break;
2939             default:
2940             case 4:
2941             case 6:
2942                 gen_op_test_true(mask);
2943                 break;
2944             }
2945         } else {
2946             switch (bo & 0x6) {
2947             case 0:
2948 #if defined(TARGET_PPC64)
2949                 if (ctx->sf_mode)
2950                     gen_op_test_ctr_false_64(mask);
2951                 else
2952 #endif
2953                     gen_op_test_ctr_false(mask);
2954                 break;
2955             case 2:
2956 #if defined(TARGET_PPC64)
2957                 if (ctx->sf_mode)
2958                     gen_op_test_ctrz_false_64(mask);
2959                 else
2960 #endif
2961                     gen_op_test_ctrz_false(mask);
2962                 break;
2963             default:
2964             case 4:
2965             case 6:
2966                 gen_op_test_false(mask);
2967                 break;
2968             }
2969         }
2970     }
2971     if (type == BCOND_IM) {
2972         int l1 = gen_new_label();
2973         gen_op_jz_T0(l1);
2974         gen_goto_tb(ctx, 0, target);
2975         gen_set_label(l1);
2976         gen_goto_tb(ctx, 1, ctx->nip);
2977     } else {
2978 #if defined(TARGET_PPC64)
2979         if (ctx->sf_mode)
2980             gen_op_btest_T1_64(ctx->nip >> 32, ctx->nip);
2981         else
2982 #endif
2983             gen_op_btest_T1(ctx->nip);
2984         gen_op_reset_T0();
2985     no_test:
2986         if (ctx->singlestep_enabled)
2987             gen_op_debug();
2988         gen_op_exit_tb();
2989     }
2990     ctx->exception = POWERPC_EXCP_BRANCH;
2991 }
2992
2993 GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
2994 {
2995     gen_bcond(ctx, BCOND_IM);
2996 }
2997
2998 GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW)
2999 {
3000     gen_bcond(ctx, BCOND_CTR);
3001 }
3002
3003 GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW)
3004 {
3005     gen_bcond(ctx, BCOND_LR);
3006 }
3007
3008 /***                      Condition register logical                       ***/
3009 #define GEN_CRLOGIC(op, opc)                                                  \
3010 GEN_HANDLER(cr##op, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER)                 \
3011 {                                                                             \
3012     gen_op_load_crf_T0(crbA(ctx->opcode) >> 2);                               \
3013     gen_op_getbit_T0(3 - (crbA(ctx->opcode) & 0x03));                         \
3014     gen_op_load_crf_T1(crbB(ctx->opcode) >> 2);                               \
3015     gen_op_getbit_T1(3 - (crbB(ctx->opcode) & 0x03));                         \
3016     gen_op_##op();                                                            \
3017     gen_op_load_crf_T1(crbD(ctx->opcode) >> 2);                               \
3018     gen_op_setcrfbit(~(1 << (3 - (crbD(ctx->opcode) & 0x03))),                \
3019                      3 - (crbD(ctx->opcode) & 0x03));                         \
3020     gen_op_store_T1_crf(crbD(ctx->opcode) >> 2);                              \
3021 }
3022
3023 /* crand */
3024 GEN_CRLOGIC(and, 0x08);
3025 /* crandc */
3026 GEN_CRLOGIC(andc, 0x04);
3027 /* creqv */
3028 GEN_CRLOGIC(eqv, 0x09);
3029 /* crnand */
3030 GEN_CRLOGIC(nand, 0x07);
3031 /* crnor */
3032 GEN_CRLOGIC(nor, 0x01);
3033 /* cror */
3034 GEN_CRLOGIC(or, 0x0E);
3035 /* crorc */
3036 GEN_CRLOGIC(orc, 0x0D);
3037 /* crxor */
3038 GEN_CRLOGIC(xor, 0x06);
3039 /* mcrf */
3040 GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER)
3041 {
3042     gen_op_load_crf_T0(crfS(ctx->opcode));
3043     gen_op_store_T0_crf(crfD(ctx->opcode));
3044 }
3045
3046 /***                           System linkage                              ***/
3047 /* rfi (supervisor only) */
3048 GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW)
3049 {
3050 #if defined(CONFIG_USER_ONLY)
3051     GEN_EXCP_PRIVOPC(ctx);
3052 #else
3053     /* Restore CPU state */
3054     if (unlikely(!ctx->supervisor)) {
3055         GEN_EXCP_PRIVOPC(ctx);
3056         return;
3057     }
3058     gen_op_rfi();
3059     GEN_SYNC(ctx);
3060 #endif
3061 }
3062
3063 #if defined(TARGET_PPC64)
3064 GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B)
3065 {
3066 #if defined(CONFIG_USER_ONLY)
3067     GEN_EXCP_PRIVOPC(ctx);
3068 #else
3069     /* Restore CPU state */
3070     if (unlikely(!ctx->supervisor)) {
3071         GEN_EXCP_PRIVOPC(ctx);
3072         return;
3073     }
3074     gen_op_rfid();
3075     GEN_SYNC(ctx);
3076 #endif
3077 }
3078 #endif
3079
3080 /* sc */
3081 GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFF01D, PPC_FLOW)
3082 {
3083     uint32_t lev;
3084
3085     lev = (ctx->opcode >> 5) & 0x7F;
3086 #if defined(CONFIG_USER_ONLY)
3087     GEN_EXCP(ctx, POWERPC_EXCP_SYSCALL_USER, lev);
3088 #else
3089     GEN_EXCP(ctx, POWERPC_EXCP_SYSCALL, lev);
3090 #endif
3091 }
3092
3093 /***                                Trap                                   ***/
3094 /* tw */
3095 GEN_HANDLER(tw, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW)
3096 {
3097     gen_op_load_gpr_T0(rA(ctx->opcode));
3098     gen_op_load_gpr_T1(rB(ctx->opcode));
3099     /* Update the nip since this might generate a trap exception */
3100     gen_update_nip(ctx, ctx->nip);
3101     gen_op_tw(TO(ctx->opcode));
3102 }
3103
3104 /* twi */
3105 GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
3106 {
3107     gen_op_load_gpr_T0(rA(ctx->opcode));
3108     gen_set_T1(SIMM(ctx->opcode));
3109     /* Update the nip since this might generate a trap exception */
3110     gen_update_nip(ctx, ctx->nip);
3111     gen_op_tw(TO(ctx->opcode));
3112 }
3113
3114 #if defined(TARGET_PPC64)
3115 /* td */
3116 GEN_HANDLER(td, 0x1F, 0x04, 0x02, 0x00000001, PPC_64B)
3117 {
3118     gen_op_load_gpr_T0(rA(ctx->opcode));
3119     gen_op_load_gpr_T1(rB(ctx->opcode));
3120     /* Update the nip since this might generate a trap exception */
3121     gen_update_nip(ctx, ctx->nip);
3122     gen_op_td(TO(ctx->opcode));
3123 }
3124
3125 /* tdi */
3126 GEN_HANDLER(tdi, 0x02, 0xFF, 0xFF, 0x00000000, PPC_64B)
3127 {
3128     gen_op_load_gpr_T0(rA(ctx->opcode));
3129     gen_set_T1(SIMM(ctx->opcode));
3130     /* Update the nip since this might generate a trap exception */
3131     gen_update_nip(ctx, ctx->nip);
3132     gen_op_td(TO(ctx->opcode));
3133 }
3134 #endif
3135
3136 /***                          Processor control                            ***/
3137 /* mcrxr */
3138 GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC)
3139 {
3140     gen_op_load_xer_cr();
3141     gen_op_store_T0_crf(crfD(ctx->opcode));
3142     gen_op_clear_xer_ov();
3143     gen_op_clear_xer_ca();
3144 }
3145
3146 /* mfcr */
3147 GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC)
3148 {
3149     uint32_t crm, crn;
3150
3151     if (likely(ctx->opcode & 0x00100000)) {
3152         crm = CRM(ctx->opcode);
3153         if (likely((crm ^ (crm - 1)) == 0)) {
3154             crn = ffs(crm);
3155             gen_op_load_cro(7 - crn);
3156         }
3157     } else {
3158         gen_op_load_cr();
3159     }
3160     gen_op_store_T0_gpr(rD(ctx->opcode));
3161 }
3162
3163 /* mfmsr */
3164 GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC)
3165 {
3166 #if defined(CONFIG_USER_ONLY)
3167     GEN_EXCP_PRIVREG(ctx);
3168 #else
3169     if (unlikely(!ctx->supervisor)) {
3170         GEN_EXCP_PRIVREG(ctx);
3171         return;
3172     }
3173     gen_op_load_msr();
3174     gen_op_store_T0_gpr(rD(ctx->opcode));
3175 #endif
3176 }
3177
3178 #if 0
3179 #define SPR_NOACCESS ((void *)(-1))
3180 #else
3181 static void spr_noaccess (void *opaque, int sprn)
3182 {
3183     sprn = ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
3184     printf("ERROR: try to access SPR %d !\n", sprn);
3185 }
3186 #define SPR_NOACCESS (&spr_noaccess)
3187 #endif
3188
3189 /* mfspr */
3190 static inline void gen_op_mfspr (DisasContext *ctx)
3191 {
3192     void (*read_cb)(void *opaque, int sprn);
3193     uint32_t sprn = SPR(ctx->opcode);
3194
3195 #if !defined(CONFIG_USER_ONLY)
3196     if (ctx->supervisor)
3197         read_cb = ctx->spr_cb[sprn].oea_read;
3198     else
3199 #endif
3200         read_cb = ctx->spr_cb[sprn].uea_read;
3201     if (likely(read_cb != NULL)) {
3202         if (likely(read_cb != SPR_NOACCESS)) {
3203             (*read_cb)(ctx, sprn);
3204             gen_op_store_T0_gpr(rD(ctx->opcode));
3205         } else {
3206             /* Privilege exception */
3207             if (loglevel != 0) {
3208                 fprintf(logfile, "Trying to read privileged spr %d %03x\n",
3209                         sprn, sprn);
3210             }
3211             printf("Trying to read privileged spr %d %03x\n", sprn, sprn);
3212             GEN_EXCP_PRIVREG(ctx);
3213         }
3214     } else {
3215         /* Not defined */
3216         if (loglevel != 0) {
3217             fprintf(logfile, "Trying to read invalid spr %d %03x\n",
3218                     sprn, sprn);
3219         }
3220         printf("Trying to read invalid spr %d %03x\n", sprn, sprn);
3221         GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM,
3222                  POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_SPR);
3223     }
3224 }
3225
3226 GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC)
3227 {
3228     gen_op_mfspr(ctx);
3229 }
3230
3231 /* mftb */
3232 GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MFTB)
3233 {
3234     gen_op_mfspr(ctx);
3235 }
3236
3237 /* mtcrf */
3238 GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC)
3239 {
3240     uint32_t crm, crn;
3241
3242     gen_op_load_gpr_T0(rS(ctx->opcode));
3243     crm = CRM(ctx->opcode);
3244     if (likely((ctx->opcode & 0x00100000) || (crm ^ (crm - 1)) == 0)) {
3245         crn = ffs(crm);
3246         gen_op_srli_T0(crn * 4);
3247         gen_op_andi_T0(0xF);
3248         gen_op_store_cro(7 - crn);
3249     } else {
3250         gen_op_store_cr(crm);
3251     }
3252 }
3253
3254 /* mtmsr */
3255 #if defined(TARGET_PPC64)
3256 GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001FF801, PPC_64B)
3257 {
3258 #if defined(CONFIG_USER_ONLY)
3259     GEN_EXCP_PRIVREG(ctx);
3260 #else
3261     if (unlikely(!ctx->supervisor)) {
3262         GEN_EXCP_PRIVREG(ctx);
3263         return;
3264     }
3265     gen_update_nip(ctx, ctx->nip);
3266     gen_op_load_gpr_T0(rS(ctx->opcode));
3267     gen_op_store_msr();
3268     /* Must stop the translation as machine state (may have) changed */
3269     /* Note that mtmsr is not always defined as context-synchronizing */
3270     GEN_STOP(ctx);
3271 #endif
3272 }
3273 #endif
3274
3275 GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC)
3276 {
3277 #if defined(CONFIG_USER_ONLY)
3278     GEN_EXCP_PRIVREG(ctx);
3279 #else
3280     if (unlikely(!ctx->supervisor)) {
3281         GEN_EXCP_PRIVREG(ctx);
3282         return;
3283     }
3284     gen_update_nip(ctx, ctx->nip);
3285     gen_op_load_gpr_T0(rS(ctx->opcode));
3286 #if defined(TARGET_PPC64)
3287     if (!ctx->sf_mode)
3288         gen_op_store_msr_32();
3289     else
3290 #endif
3291         gen_op_store_msr();
3292     /* Must stop the translation as machine state (may have) changed */
3293     /* Note that mtmsrd is not always defined as context-synchronizing */
3294     GEN_STOP(ctx);
3295 #endif
3296 }
3297
3298 /* mtspr */
3299 GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC)
3300 {
3301     void (*write_cb)(void *opaque, int sprn);
3302     uint32_t sprn = SPR(ctx->opcode);
3303
3304 #if !defined(CONFIG_USER_ONLY)
3305     if (ctx->supervisor)
3306         write_cb = ctx->spr_cb[sprn].oea_write;
3307     else
3308 #endif
3309         write_cb = ctx->spr_cb[sprn].uea_write;
3310     if (likely(write_cb != NULL)) {
3311         if (likely(write_cb != SPR_NOACCESS)) {
3312             gen_op_load_gpr_T0(rS(ctx->opcode));
3313             (*write_cb)(ctx, sprn);
3314         } else {
3315             /* Privilege exception */
3316             if (loglevel != 0) {
3317                 fprintf(logfile, "Trying to write privileged spr %d %03x\n",
3318                         sprn, sprn);
3319             }
3320             printf("Trying to write privileged spr %d %03x\n", sprn, sprn);
3321             GEN_EXCP_PRIVREG(ctx);
3322         }
3323     } else {
3324         /* Not defined */
3325         if (loglevel != 0) {
3326             fprintf(logfile, "Trying to write invalid spr %d %03x\n",
3327                     sprn, sprn);
3328         }
3329         printf("Trying to write invalid spr %d %03x\n", sprn, sprn);
3330         GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM,
3331                  POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_SPR);
3332     }
3333 }
3334
3335 /***                         Cache management                              ***/
3336 /* For now, all those will be implemented as nop:
3337  * this is valid, regarding the PowerPC specs...
3338  * We just have to flush tb while invalidating instruction cache lines...
3339  */
3340 /* dcbf */
3341 GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03C00001, PPC_CACHE)
3342 {
3343     gen_addr_reg_index(ctx);
3344     op_ldst(lbz);
3345 }
3346
3347 /* dcbi (Supervisor only) */
3348 GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE)
3349 {
3350 #if defined(CONFIG_USER_ONLY)
3351     GEN_EXCP_PRIVOPC(ctx);
3352 #else
3353     if (unlikely(!ctx->supervisor)) {
3354         GEN_EXCP_PRIVOPC(ctx);
3355         return;
3356     }
3357     gen_addr_reg_index(ctx);
3358     /* XXX: specification says this should be treated as a store by the MMU */
3359     //op_ldst(lbz);
3360     op_ldst(stb);
3361 #endif
3362 }
3363
3364 /* dcdst */
3365 GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE)
3366 {
3367     /* XXX: specification say this is treated as a load by the MMU */
3368     gen_addr_reg_index(ctx);
3369     op_ldst(lbz);
3370 }
3371
3372 /* dcbt */
3373 GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x02000001, PPC_CACHE)
3374 {
3375     /* interpreted as no-op */
3376     /* XXX: specification say this is treated as a load by the MMU
3377      *      but does not generate any exception
3378      */
3379 }
3380
3381 /* dcbtst */
3382 GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x02000001, PPC_CACHE)
3383 {
3384     /* interpreted as no-op */
3385     /* XXX: specification say this is treated as a load by the MMU
3386      *      but does not generate any exception
3387      */
3388 }
3389
3390 /* dcbz */
3391 #define op_dcbz() (*gen_op_dcbz[ctx->mem_idx])()
3392 #if defined(TARGET_PPC64)
3393 #if defined(CONFIG_USER_ONLY)
3394 static GenOpFunc *gen_op_dcbz[] = {
3395     &gen_op_dcbz_raw,
3396     &gen_op_dcbz_raw,
3397     &gen_op_dcbz_64_raw,
3398     &gen_op_dcbz_64_raw,
3399 };
3400 #else
3401 static GenOpFunc *gen_op_dcbz[] = {
3402     &gen_op_dcbz_user,
3403     &gen_op_dcbz_user,
3404     &gen_op_dcbz_kernel,
3405     &gen_op_dcbz_kernel,
3406     &gen_op_dcbz_64_user,
3407     &gen_op_dcbz_64_user,
3408     &gen_op_dcbz_64_kernel,
3409     &gen_op_dcbz_64_kernel,
3410 };
3411 #endif
3412 #else
3413 #if defined(CONFIG_USER_ONLY)
3414 static GenOpFunc *gen_op_dcbz[] = {
3415     &gen_op_dcbz_raw,
3416     &gen_op_dcbz_raw,
3417 };
3418 #else
3419 static GenOpFunc *gen_op_dcbz[] = {
3420     &gen_op_dcbz_user,
3421     &gen_op_dcbz_user,
3422     &gen_op_dcbz_kernel,
3423     &gen_op_dcbz_kernel,
3424 };
3425 #endif
3426 #endif
3427
3428 GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE)
3429 {
3430     gen_addr_reg_index(ctx);
3431     op_dcbz();
3432     gen_op_check_reservation();
3433 }
3434
3435 /* icbi */
3436 #define op_icbi() (*gen_op_icbi[ctx->mem_idx])()
3437 #if defined(TARGET_PPC64)
3438 #if defined(CONFIG_USER_ONLY)
3439 static GenOpFunc *gen_op_icbi[] = {
3440     &gen_op_icbi_raw,
3441     &gen_op_icbi_raw,
3442     &gen_op_icbi_64_raw,
3443     &gen_op_icbi_64_raw,
3444 };
3445 #else
3446 static GenOpFunc *gen_op_icbi[] = {
3447     &gen_op_icbi_user,
3448     &gen_op_icbi_user,
3449     &gen_op_icbi_kernel,
3450     &gen_op_icbi_kernel,
3451     &gen_op_icbi_64_user,
3452     &gen_op_icbi_64_user,
3453     &gen_op_icbi_64_kernel,
3454     &gen_op_icbi_64_kernel,
3455 };
3456 #endif
3457 #else
3458 #if defined(CONFIG_USER_ONLY)
3459 static GenOpFunc *gen_op_icbi[] = {
3460     &gen_op_icbi_raw,
3461     &gen_op_icbi_raw,
3462 };
3463 #else
3464 static GenOpFunc *gen_op_icbi[] = {
3465     &gen_op_icbi_user,
3466     &gen_op_icbi_user,
3467     &gen_op_icbi_kernel,
3468     &gen_op_icbi_kernel,
3469 };
3470 #endif
3471 #endif
3472
3473 GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE)
3474 {
3475     gen_addr_reg_index(ctx);
3476     op_icbi();
3477 }
3478
3479 /* Optional: */
3480 /* dcba */
3481 GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_DCBA)
3482 {
3483     /* interpreted as no-op */
3484     /* XXX: specification say this is treated as a store by the MMU
3485      *      but does not generate any exception
3486      */
3487 }
3488
3489 /***                    Segment register manipulation                      ***/
3490 /* Supervisor only: */
3491 /* mfsr */
3492 GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT)
3493 {
3494 #if defined(CONFIG_USER_ONLY)
3495     GEN_EXCP_PRIVREG(ctx);
3496 #else
3497     if (unlikely(!ctx->supervisor)) {
3498         GEN_EXCP_PRIVREG(ctx);
3499         return;
3500     }
3501     gen_op_set_T1(SR(ctx->opcode));
3502     gen_op_load_sr();
3503     gen_op_store_T0_gpr(rD(ctx->opcode));
3504 #endif
3505 }
3506
3507 /* mfsrin */
3508 GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT)
3509 {
3510 #if defined(CONFIG_USER_ONLY)
3511     GEN_EXCP_PRIVREG(ctx);
3512 #else
3513     if (unlikely(!ctx->supervisor)) {
3514         GEN_EXCP_PRIVREG(ctx);
3515         return;
3516     }
3517     gen_op_load_gpr_T1(rB(ctx->opcode));
3518     gen_op_srli_T1(28);
3519     gen_op_load_sr();
3520     gen_op_store_T0_gpr(rD(ctx->opcode));
3521 #endif
3522 }
3523
3524 /* mtsr */
3525 GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT)
3526 {
3527 #if defined(CONFIG_USER_ONLY)
3528     GEN_EXCP_PRIVREG(ctx);
3529 #else
3530     if (unlikely(!ctx->supervisor)) {
3531         GEN_EXCP_PRIVREG(ctx);
3532         return;
3533     }
3534     gen_op_load_gpr_T0(rS(ctx->opcode));
3535     gen_op_set_T1(SR(ctx->opcode));
3536     gen_op_store_sr();
3537 #endif
3538 }
3539
3540 /* mtsrin */
3541 GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT)
3542 {
3543 #if defined(CONFIG_USER_ONLY)
3544     GEN_EXCP_PRIVREG(ctx);
3545 #else
3546     if (unlikely(!ctx->supervisor)) {
3547         GEN_EXCP_PRIVREG(ctx);
3548         return;
3549     }
3550     gen_op_load_gpr_T0(rS(ctx->opcode));
3551     gen_op_load_gpr_T1(rB(ctx->opcode));
3552     gen_op_srli_T1(28);
3553     gen_op_store_sr();
3554 #endif
3555 }
3556
3557 /***                      Lookaside buffer management                      ***/
3558 /* Optional & supervisor only: */
3559 /* tlbia */
3560 GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA)
3561 {
3562 #if defined(CONFIG_USER_ONLY)
3563     GEN_EXCP_PRIVOPC(ctx);
3564 #else
3565     if (unlikely(!ctx->supervisor)) {
3566         if (loglevel != 0)
3567             fprintf(logfile, "%s: ! supervisor\n", __func__);
3568         GEN_EXCP_PRIVOPC(ctx);
3569         return;
3570     }
3571     gen_op_tlbia();
3572 #endif
3573 }
3574
3575 /* tlbie */
3576 GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE)
3577 {
3578 #if defined(CONFIG_USER_ONLY)
3579     GEN_EXCP_PRIVOPC(ctx);
3580 #else
3581     if (unlikely(!ctx->supervisor)) {
3582         GEN_EXCP_PRIVOPC(ctx);
3583         return;
3584     }
3585     gen_op_load_gpr_T0(rB(ctx->opcode));
3586 #if defined(TARGET_PPC64)
3587     if (ctx->sf_mode)
3588         gen_op_tlbie_64();
3589     else
3590 #endif
3591         gen_op_tlbie();
3592 #endif
3593 }
3594
3595 /* tlbsync */
3596 GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC)
3597 {
3598 #if defined(CONFIG_USER_ONLY)
3599     GEN_EXCP_PRIVOPC(ctx);
3600 #else
3601     if (unlikely(!ctx->supervisor)) {
3602         GEN_EXCP_PRIVOPC(ctx);
3603         return;
3604     }
3605     /* This has no effect: it should ensure that all previous
3606      * tlbie have completed
3607      */
3608     GEN_STOP(ctx);
3609 #endif
3610 }
3611
3612 #if defined(TARGET_PPC64)
3613 /* slbia */
3614 GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x03FFFC01, PPC_SLBI)
3615 {
3616 #if defined(CONFIG_USER_ONLY)
3617     GEN_EXCP_PRIVOPC(ctx);
3618 #else
3619     if (unlikely(!ctx->supervisor)) {
3620         if (loglevel != 0)
3621             fprintf(logfile, "%s: ! supervisor\n", __func__);
3622         GEN_EXCP_PRIVOPC(ctx);
3623         return;
3624     }
3625     gen_op_slbia();
3626 #endif
3627 }
3628
3629 /* slbie */
3630 GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI)
3631 {
3632 #if defined(CONFIG_USER_ONLY)
3633     GEN_EXCP_PRIVOPC(ctx);
3634 #else
3635     if (unlikely(!ctx->supervisor)) {
3636         GEN_EXCP_PRIVOPC(ctx);
3637         return;
3638     }
3639     gen_op_load_gpr_T0(rB(ctx->opcode));
3640     gen_op_slbie();
3641 #endif
3642 }
3643 #endif
3644
3645 /***                              External control                         ***/
3646 /* Optional: */
3647 #define op_eciwx() (*gen_op_eciwx[ctx->mem_idx])()
3648 #define op_ecowx() (*gen_op_ecowx[ctx->mem_idx])()
3649 #if defined(TARGET_PPC64)
3650 #if defined(CONFIG_USER_ONLY)
3651 static GenOpFunc *gen_op_eciwx[] = {
3652     &gen_op_eciwx_raw,
3653     &gen_op_eciwx_le_raw,
3654     &gen_op_eciwx_64_raw,
3655     &gen_op_eciwx_le_64_raw,
3656 };
3657 static GenOpFunc *gen_op_ecowx[] = {
3658     &gen_op_ecowx_raw,
3659     &gen_op_ecowx_le_raw,
3660     &gen_op_ecowx_64_raw,
3661     &gen_op_ecowx_le_64_raw,
3662 };
3663 #else
3664 static GenOpFunc *gen_op_eciwx[] = {
3665     &gen_op_eciwx_user,
3666     &gen_op_eciwx_le_user,
3667     &gen_op_eciwx_kernel,
3668     &gen_op_eciwx_le_kernel,
3669     &gen_op_eciwx_64_user,
3670     &gen_op_eciwx_le_64_user,
3671     &gen_op_eciwx_64_kernel,
3672     &gen_op_eciwx_le_64_kernel,
3673 };
3674 static GenOpFunc *gen_op_ecowx[] = {
3675     &gen_op_ecowx_user,
3676     &gen_op_ecowx_le_user,
3677     &gen_op_ecowx_kernel,
3678     &gen_op_ecowx_le_kernel,
3679     &gen_op_ecowx_64_user,
3680     &gen_op_ecowx_le_64_user,
3681     &gen_op_ecowx_64_kernel,
3682     &gen_op_ecowx_le_64_kernel,
3683 };
3684 #endif
3685 #else
3686 #if defined(CONFIG_USER_ONLY)
3687 static GenOpFunc *gen_op_eciwx[] = {
3688     &gen_op_eciwx_raw,
3689     &gen_op_eciwx_le_raw,
3690 };
3691 static GenOpFunc *gen_op_ecowx[] = {
3692     &gen_op_ecowx_raw,
3693     &gen_op_ecowx_le_raw,
3694 };
3695 #else
3696 static GenOpFunc *gen_op_eciwx[] = {
3697     &gen_op_eciwx_user,
3698     &gen_op_eciwx_le_user,
3699     &gen_op_eciwx_kernel,
3700     &gen_op_eciwx_le_kernel,
3701 };
3702 static GenOpFunc *gen_op_ecowx[] = {
3703     &gen_op_ecowx_user,
3704     &gen_op_ecowx_le_user,
3705     &gen_op_ecowx_kernel,
3706     &gen_op_ecowx_le_kernel,
3707 };
3708 #endif
3709 #endif
3710
3711 /* eciwx */
3712 GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN)
3713 {
3714     /* Should check EAR[E] & alignment ! */
3715     gen_addr_reg_index(ctx);
3716     op_eciwx();
3717     gen_op_store_T0_gpr(rD(ctx->opcode));
3718 }
3719
3720 /* ecowx */
3721 GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN)
3722 {
3723     /* Should check EAR[E] & alignment ! */
3724     gen_addr_reg_index(ctx);
3725     gen_op_load_gpr_T1(rS(ctx->opcode));
3726     op_ecowx();
3727 }
3728
3729 /* PowerPC 601 specific instructions */
3730 /* abs - abs. */
3731 GEN_HANDLER(abs, 0x1F, 0x08, 0x0B, 0x0000F800, PPC_POWER_BR)
3732 {
3733     gen_op_load_gpr_T0(rA(ctx->opcode));
3734     gen_op_POWER_abs();
3735     gen_op_store_T0_gpr(rD(ctx->opcode));
3736     if (unlikely(Rc(ctx->opcode) != 0))
3737         gen_set_Rc0(ctx);
3738 }
3739
3740 /* abso - abso. */
3741 GEN_HANDLER(abso, 0x1F, 0x08, 0x1B, 0x0000F800, PPC_POWER_BR)
3742 {
3743     gen_op_load_gpr_T0(rA(ctx->opcode));
3744     gen_op_POWER_abso();
3745     gen_op_store_T0_gpr(rD(ctx->opcode));
3746     if (unlikely(Rc(ctx->opcode) != 0))
3747         gen_set_Rc0(ctx);
3748 }
3749
3750 /* clcs */
3751 GEN_HANDLER(clcs, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR)
3752 {
3753     gen_op_load_gpr_T0(rA(ctx->opcode));
3754     gen_op_POWER_clcs();
3755     gen_op_store_T0_gpr(rD(ctx->opcode));
3756 }
3757
3758 /* div - div. */
3759 GEN_HANDLER(div, 0x1F, 0x0B, 0x0A, 0x00000000, PPC_POWER_BR)
3760 {
3761     gen_op_load_gpr_T0(rA(ctx->opcode));
3762     gen_op_load_gpr_T1(rB(ctx->opcode));
3763     gen_op_POWER_div();
3764     gen_op_store_T0_gpr(rD(ctx->opcode));
3765     if (unlikely(Rc(ctx->opcode) != 0))
3766         gen_set_Rc0(ctx);
3767 }
3768
3769 /* divo - divo. */
3770 GEN_HANDLER(divo, 0x1F, 0x0B, 0x1A, 0x00000000, PPC_POWER_BR)
3771 {
3772     gen_op_load_gpr_T0(rA(ctx->opcode));
3773     gen_op_load_gpr_T1(rB(ctx->opcode));
3774     gen_op_POWER_divo();
3775     gen_op_store_T0_gpr(rD(ctx->opcode));
3776     if (unlikely(Rc(ctx->opcode) != 0))
3777         gen_set_Rc0(ctx);
3778 }
3779
3780 /* divs - divs. */
3781 GEN_HANDLER(divs, 0x1F, 0x0B, 0x0B, 0x00000000, PPC_POWER_BR)
3782 {
3783     gen_op_load_gpr_T0(rA(ctx->opcode));
3784     gen_op_load_gpr_T1(rB(ctx->opcode));
3785     gen_op_POWER_divs();
3786     gen_op_store_T0_gpr(rD(ctx->opcode));
3787     if (unlikely(Rc(ctx->opcode) != 0))
3788         gen_set_Rc0(ctx);
3789 }
3790
3791 /* divso - divso. */
3792 GEN_HANDLER(divso, 0x1F, 0x0B, 0x1B, 0x00000000, PPC_POWER_BR)
3793 {
3794     gen_op_load_gpr_T0(rA(ctx->opcode));
3795     gen_op_load_gpr_T1(rB(ctx->opcode));
3796     gen_op_POWER_divso();
3797     gen_op_store_T0_gpr(rD(ctx->opcode));
3798     if (unlikely(Rc(ctx->opcode) != 0))
3799         gen_set_Rc0(ctx);
3800 }
3801
3802 /* doz - doz. */
3803 GEN_HANDLER(doz, 0x1F, 0x08, 0x08, 0x00000000, PPC_POWER_BR)
3804 {
3805     gen_op_load_gpr_T0(rA(ctx->opcode));
3806     gen_op_load_gpr_T1(rB(ctx->opcode));
3807     gen_op_POWER_doz();
3808     gen_op_store_T0_gpr(rD(ctx->opcode));
3809     if (unlikely(Rc(ctx->opcode) != 0))
3810         gen_set_Rc0(ctx);
3811 }
3812
3813 /* dozo - dozo. */
3814 GEN_HANDLER(dozo, 0x1F, 0x08, 0x18, 0x00000000, PPC_POWER_BR)
3815 {
3816     gen_op_load_gpr_T0(rA(ctx->opcode));
3817     gen_op_load_gpr_T1(rB(ctx->opcode));
3818     gen_op_POWER_dozo();
3819     gen_op_store_T0_gpr(rD(ctx->opcode));
3820     if (unlikely(Rc(ctx->opcode) != 0))
3821         gen_set_Rc0(ctx);
3822 }
3823
3824 /* dozi */
3825 GEN_HANDLER(dozi, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
3826 {
3827     gen_op_load_gpr_T0(rA(ctx->opcode));
3828     gen_op_set_T1(SIMM(ctx->opcode));
3829     gen_op_POWER_doz();
3830     gen_op_store_T0_gpr(rD(ctx->opcode));
3831 }
3832
3833 /* As lscbx load from memory byte after byte, it's always endian safe */
3834 #define op_POWER_lscbx(start, ra, rb) \
3835 (*gen_op_POWER_lscbx[ctx->mem_idx])(start, ra, rb)
3836 #if defined(CONFIG_USER_ONLY)
3837 static GenOpFunc3 *gen_op_POWER_lscbx[] = {
3838     &gen_op_POWER_lscbx_raw,
3839     &gen_op_POWER_lscbx_raw,
3840 };
3841 #else
3842 static GenOpFunc3 *gen_op_POWER_lscbx[] = {
3843     &gen_op_POWER_lscbx_user,
3844     &gen_op_POWER_lscbx_user,
3845     &gen_op_POWER_lscbx_kernel,
3846     &gen_op_POWER_lscbx_kernel,
3847 };
3848 #endif
3849
3850 /* lscbx - lscbx. */
3851 GEN_HANDLER(lscbx, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR)
3852 {
3853     int ra = rA(ctx->opcode);
3854     int rb = rB(ctx->opcode);
3855
3856     gen_addr_reg_index(ctx);
3857     if (ra == 0) {
3858         ra = rb;
3859     }
3860     /* NIP cannot be restored if the memory exception comes from an helper */
3861     gen_update_nip(ctx, ctx->nip - 4);
3862     gen_op_load_xer_bc();
3863     gen_op_load_xer_cmp();
3864     op_POWER_lscbx(rD(ctx->opcode), ra, rb);
3865     gen_op_store_xer_bc();
3866     if (unlikely(Rc(ctx->opcode) != 0))
3867         gen_set_Rc0(ctx);
3868 }
3869
3870 /* maskg - maskg. */
3871 GEN_HANDLER(maskg, 0x1F, 0x1D, 0x00, 0x00000000, PPC_POWER_BR)
3872 {
3873     gen_op_load_gpr_T0(rS(ctx->opcode));
3874     gen_op_load_gpr_T1(rB(ctx->opcode));
3875     gen_op_POWER_maskg();
3876     gen_op_store_T0_gpr(rA(ctx->opcode));
3877     if (unlikely(Rc(ctx->opcode) != 0))
3878         gen_set_Rc0(ctx);
3879 }
3880
3881 /* maskir - maskir. */
3882 GEN_HANDLER(maskir, 0x1F, 0x1D, 0x10, 0x00000000, PPC_POWER_BR)
3883 {
3884     gen_op_load_gpr_T0(rA(ctx->opcode));
3885     gen_op_load_gpr_T1(rS(ctx->opcode));
3886     gen_op_load_gpr_T2(rB(ctx->opcode));
3887     gen_op_POWER_maskir();
3888     gen_op_store_T0_gpr(rA(ctx->opcode));
3889     if (unlikely(Rc(ctx->opcode) != 0))
3890         gen_set_Rc0(ctx);
3891 }
3892
3893 /* mul - mul. */
3894 GEN_HANDLER(mul, 0x1F, 0x0B, 0x03, 0x00000000, PPC_POWER_BR)
3895 {
3896     gen_op_load_gpr_T0(rA(ctx->opcode));
3897     gen_op_load_gpr_T1(rB(ctx->opcode));
3898     gen_op_POWER_mul();
3899     gen_op_store_T0_gpr(rD(ctx->opcode));
3900     if (unlikely(Rc(ctx->opcode) != 0))
3901         gen_set_Rc0(ctx);
3902 }
3903
3904 /* mulo - mulo. */
3905 GEN_HANDLER(mulo, 0x1F, 0x0B, 0x13, 0x00000000, PPC_POWER_BR)
3906 {
3907     gen_op_load_gpr_T0(rA(ctx->opcode));
3908     gen_op_load_gpr_T1(rB(ctx->opcode));
3909     gen_op_POWER_mulo();
3910     gen_op_store_T0_gpr(rD(ctx->opcode));
3911     if (unlikely(Rc(ctx->opcode) != 0))
3912         gen_set_Rc0(ctx);
3913 }
3914
3915 /* nabs - nabs. */
3916 GEN_HANDLER(nabs, 0x1F, 0x08, 0x0F, 0x00000000, PPC_POWER_BR)
3917 {
3918     gen_op_load_gpr_T0(rA(ctx->opcode));
3919     gen_op_POWER_nabs();
3920     gen_op_store_T0_gpr(rD(ctx->opcode));
3921     if (unlikely(Rc(ctx->opcode) != 0))
3922         gen_set_Rc0(ctx);
3923 }
3924
3925 /* nabso - nabso. */
3926 GEN_HANDLER(nabso, 0x1F, 0x08, 0x1F, 0x00000000, PPC_POWER_BR)
3927 {
3928     gen_op_load_gpr_T0(rA(ctx->opcode));
3929     gen_op_POWER_nabso();
3930     gen_op_store_T0_gpr(rD(ctx->opcode));
3931     if (unlikely(Rc(ctx->opcode) != 0))
3932         gen_set_Rc0(ctx);
3933 }
3934
3935 /* rlmi - rlmi. */
3936 GEN_HANDLER(rlmi, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
3937 {
3938     uint32_t mb, me;
3939
3940     mb = MB(ctx->opcode);
3941     me = ME(ctx->opcode);
3942     gen_op_load_gpr_T0(rS(ctx->opcode));
3943     gen_op_load_gpr_T1(rA(ctx->opcode));
3944     gen_op_load_gpr_T2(rB(ctx->opcode));
3945     gen_op_POWER_rlmi(MASK(mb, me), ~MASK(mb, me));
3946     gen_op_store_T0_gpr(rA(ctx->opcode));
3947     if (unlikely(Rc(ctx->opcode) != 0))
3948         gen_set_Rc0(ctx);
3949 }
3950
3951 /* rrib - rrib. */
3952 GEN_HANDLER(rrib, 0x1F, 0x19, 0x10, 0x00000000, PPC_POWER_BR)
3953 {
3954     gen_op_load_gpr_T0(rS(ctx->opcode));
3955     gen_op_load_gpr_T1(rA(ctx->opcode));
3956     gen_op_load_gpr_T2(rB(ctx->opcode));
3957     gen_op_POWER_rrib();
3958     gen_op_store_T0_gpr(rA(ctx->opcode));
3959     if (unlikely(Rc(ctx->opcode) != 0))
3960         gen_set_Rc0(ctx);
3961 }
3962
3963 /* sle - sle. */
3964 GEN_HANDLER(sle, 0x1F, 0x19, 0x04, 0x00000000, PPC_POWER_BR)
3965 {
3966     gen_op_load_gpr_T0(rS(ctx->opcode));
3967     gen_op_load_gpr_T1(rB(ctx->opcode));
3968     gen_op_POWER_sle();
3969     gen_op_store_T0_gpr(rA(ctx->opcode));
3970     if (unlikely(Rc(ctx->opcode) != 0))
3971         gen_set_Rc0(ctx);
3972 }
3973
3974 /* sleq - sleq. */
3975 GEN_HANDLER(sleq, 0x1F, 0x19, 0x06, 0x00000000, PPC_POWER_BR)
3976 {
3977     gen_op_load_gpr_T0(rS(ctx->opcode));
3978     gen_op_load_gpr_T1(rB(ctx->opcode));
3979     gen_op_POWER_sleq();
3980     gen_op_store_T0_gpr(rA(ctx->opcode));
3981     if (unlikely(Rc(ctx->opcode) != 0))
3982         gen_set_Rc0(ctx);
3983 }
3984
3985 /* sliq - sliq. */
3986 GEN_HANDLER(sliq, 0x1F, 0x18, 0x05, 0x00000000, PPC_POWER_BR)
3987 {
3988     gen_op_load_gpr_T0(rS(ctx->opcode));
3989     gen_op_set_T1(SH(ctx->opcode));
3990     gen_op_POWER_sle();
3991     gen_op_store_T0_gpr(rA(ctx->opcode));
3992     if (unlikely(Rc(ctx->opcode) != 0))
3993         gen_set_Rc0(ctx);
3994 }
3995
3996 /* slliq - slliq. */
3997 GEN_HANDLER(slliq, 0x1F, 0x18, 0x07, 0x00000000, PPC_POWER_BR)
3998 {
3999     gen_op_load_gpr_T0(rS(ctx->opcode));
4000     gen_op_set_T1(SH(ctx->opcode));
4001     gen_op_POWER_sleq();
4002     gen_op_store_T0_gpr(rA(ctx->opcode));
4003     if (unlikely(Rc(ctx->opcode) != 0))
4004         gen_set_Rc0(ctx);
4005 }
4006
4007 /* sllq - sllq. */
4008 GEN_HANDLER(sllq, 0x1F, 0x18, 0x06, 0x00000000, PPC_POWER_BR)
4009 {
4010     gen_op_load_gpr_T0(rS(ctx->opcode));
4011     gen_op_load_gpr_T1(rB(ctx->opcode));
4012     gen_op_POWER_sllq();
4013     gen_op_store_T0_gpr(rA(ctx->opcode));
4014     if (unlikely(Rc(ctx->opcode) != 0))
4015         gen_set_Rc0(ctx);
4016 }
4017
4018 /* slq - slq. */
4019 GEN_HANDLER(slq, 0x1F, 0x18, 0x04, 0x00000000, PPC_POWER_BR)
4020 {
4021     gen_op_load_gpr_T0(rS(ctx->opcode));
4022     gen_op_load_gpr_T1(rB(ctx->opcode));
4023     gen_op_POWER_slq();
4024     gen_op_store_T0_gpr(rA(ctx->opcode));
4025     if (unlikely(Rc(ctx->opcode) != 0))
4026         gen_set_Rc0(ctx);
4027 }
4028
4029 /* sraiq - sraiq. */
4030 GEN_HANDLER(sraiq, 0x1F, 0x18, 0x1D, 0x00000000, PPC_POWER_BR)
4031 {
4032     gen_op_load_gpr_T0(rS(ctx->opcode));
4033     gen_op_set_T1(SH(ctx->opcode));
4034     gen_op_POWER_sraq();
4035     gen_op_store_T0_gpr(rA(ctx->opcode));
4036     if (unlikely(Rc(ctx->opcode) != 0))
4037         gen_set_Rc0(ctx);
4038 }
4039
4040 /* sraq - sraq. */
4041 GEN_HANDLER(sraq, 0x1F, 0x18, 0x1C, 0x00000000, PPC_POWER_BR)
4042 {
4043     gen_op_load_gpr_T0(rS(ctx->opcode));
4044     gen_op_load_gpr_T1(rB(ctx->opcode));
4045     gen_op_POWER_sraq();
4046     gen_op_store_T0_gpr(rA(ctx->opcode));
4047     if (unlikely(Rc(ctx->opcode) != 0))
4048         gen_set_Rc0(ctx);
4049 }
4050
4051 /* sre - sre. */
4052 GEN_HANDLER(sre, 0x1F, 0x19, 0x14, 0x00000000, PPC_POWER_BR)
4053 {
4054     gen_op_load_gpr_T0(rS(ctx->opcode));
4055     gen_op_load_gpr_T1(rB(ctx->opcode));
4056     gen_op_POWER_sre();
4057     gen_op_store_T0_gpr(rA(ctx->opcode));
4058     if (unlikely(Rc(ctx->opcode) != 0))
4059         gen_set_Rc0(ctx);
4060 }
4061
4062 /* srea - srea. */
4063 GEN_HANDLER(srea, 0x1F, 0x19, 0x1C, 0x00000000, PPC_POWER_BR)
4064 {
4065     gen_op_load_gpr_T0(rS(ctx->opcode));
4066     gen_op_load_gpr_T1(rB(ctx->opcode));
4067     gen_op_POWER_srea();
4068     gen_op_store_T0_gpr(rA(ctx->opcode));
4069     if (unlikely(Rc(ctx->opcode) != 0))
4070         gen_set_Rc0(ctx);
4071 }
4072
4073 /* sreq */
4074 GEN_HANDLER(sreq, 0x1F, 0x19, 0x16, 0x00000000, PPC_POWER_BR)
4075 {
4076     gen_op_load_gpr_T0(rS(ctx->opcode));
4077     gen_op_load_gpr_T1(rB(ctx->opcode));
4078     gen_op_POWER_sreq();
4079     gen_op_store_T0_gpr(rA(ctx->opcode));
4080     if (unlikely(Rc(ctx->opcode) != 0))
4081         gen_set_Rc0(ctx);
4082 }
4083
4084 /* sriq */
4085 GEN_HANDLER(sriq, 0x1F, 0x18, 0x15, 0x00000000, PPC_POWER_BR)
4086 {
4087     gen_op_load_gpr_T0(rS(ctx->opcode));
4088     gen_op_set_T1(SH(ctx->opcode));
4089     gen_op_POWER_srq();
4090     gen_op_store_T0_gpr(rA(ctx->opcode));
4091     if (unlikely(Rc(ctx->opcode) != 0))
4092         gen_set_Rc0(ctx);
4093 }
4094
4095 /* srliq */
4096 GEN_HANDLER(srliq, 0x1F, 0x18, 0x17, 0x00000000, PPC_POWER_BR)
4097 {
4098     gen_op_load_gpr_T0(rS(ctx->opcode));
4099     gen_op_load_gpr_T1(rB(ctx->opcode));
4100     gen_op_set_T1(SH(ctx->opcode));
4101     gen_op_POWER_srlq();
4102     gen_op_store_T0_gpr(rA(ctx->opcode));
4103     if (unlikely(Rc(ctx->opcode) != 0))
4104         gen_set_Rc0(ctx);
4105 }
4106
4107 /* srlq */
4108 GEN_HANDLER(srlq, 0x1F, 0x18, 0x16, 0x00000000, PPC_POWER_BR)
4109 {
4110     gen_op_load_gpr_T0(rS(ctx->opcode));
4111     gen_op_load_gpr_T1(rB(ctx->opcode));
4112     gen_op_POWER_srlq();
4113     gen_op_store_T0_gpr(rA(ctx->opcode));
4114     if (unlikely(Rc(ctx->opcode) != 0))
4115         gen_set_Rc0(ctx);
4116 }
4117
4118 /* srq */
4119 GEN_HANDLER(srq, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR)
4120 {
4121     gen_op_load_gpr_T0(rS(ctx->opcode));
4122     gen_op_load_gpr_T1(rB(ctx->opcode));
4123     gen_op_POWER_srq();
4124     gen_op_store_T0_gpr(rA(ctx->opcode));
4125     if (unlikely(Rc(ctx->opcode) != 0))
4126         gen_set_Rc0(ctx);
4127 }
4128
4129 /* PowerPC 602 specific instructions */
4130 /* dsa  */
4131 GEN_HANDLER(dsa, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC)
4132 {
4133     /* XXX: TODO */
4134     GEN_EXCP_INVAL(ctx);
4135 }
4136
4137 /* esa */
4138 GEN_HANDLER(esa, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC)
4139 {
4140     /* XXX: TODO */
4141     GEN_EXCP_INVAL(ctx);
4142 }
4143
4144 /* mfrom */
4145 GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC)
4146 {
4147 #if defined(CONFIG_USER_ONLY)
4148     GEN_EXCP_PRIVOPC(ctx);
4149 #else
4150     if (unlikely(!ctx->supervisor)) {
4151         GEN_EXCP_PRIVOPC(ctx);
4152         return;
4153     }
4154     gen_op_load_gpr_T0(rA(ctx->opcode));
4155     gen_op_602_mfrom();
4156     gen_op_store_T0_gpr(rD(ctx->opcode));
4157 #endif
4158 }
4159
4160 /* 602 - 603 - G2 TLB management */
4161 /* tlbld */
4162 GEN_HANDLER(tlbld, 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB)
4163 {
4164 #if defined(CONFIG_USER_ONLY)
4165     GEN_EXCP_PRIVOPC(ctx);
4166 #else
4167     if (unlikely(!ctx->supervisor)) {
4168         GEN_EXCP_PRIVOPC(ctx);
4169         return;
4170     }
4171     gen_op_load_gpr_T0(rB(ctx->opcode));
4172     gen_op_6xx_tlbld();
4173 #endif
4174 }
4175
4176 /* tlbli */
4177 GEN_HANDLER(tlbli, 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB)
4178 {
4179 #if defined(CONFIG_USER_ONLY)
4180     GEN_EXCP_PRIVOPC(ctx);
4181 #else
4182     if (unlikely(!ctx->supervisor)) {
4183         GEN_EXCP_PRIVOPC(ctx);
4184         return;
4185     }
4186     gen_op_load_gpr_T0(rB(ctx->opcode));
4187     gen_op_6xx_tlbli();
4188 #endif
4189 }
4190
4191 /* POWER instructions not in PowerPC 601 */
4192 /* clf */
4193 GEN_HANDLER(clf, 0x1F, 0x16, 0x03, 0x03E00000, PPC_POWER)
4194 {
4195     /* Cache line flush: implemented as no-op */
4196 }
4197
4198 /* cli */
4199 GEN_HANDLER(cli, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER)
4200 {
4201     /* Cache line invalidate: privileged and treated as no-op */
4202 #if defined(CONFIG_USER_ONLY)
4203     GEN_EXCP_PRIVOPC(ctx);
4204 #else
4205     if (unlikely(!ctx->supervisor)) {
4206         GEN_EXCP_PRIVOPC(ctx);
4207         return;
4208     }
4209 #endif
4210 }
4211
4212 /* dclst */
4213 GEN_HANDLER(dclst, 0x1F, 0x16, 0x13, 0x03E00000, PPC_POWER)
4214 {
4215     /* Data cache line store: treated as no-op */
4216 }
4217
4218 GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER)
4219 {
4220 #if defined(CONFIG_USER_ONLY)
4221     GEN_EXCP_PRIVOPC(ctx);
4222 #else
4223     if (unlikely(!ctx->supervisor)) {
4224         GEN_EXCP_PRIVOPC(ctx);
4225         return;
4226     }
4227     int ra = rA(ctx->opcode);
4228     int rd = rD(ctx->opcode);
4229
4230     gen_addr_reg_index(ctx);
4231     gen_op_POWER_mfsri();
4232     gen_op_store_T0_gpr(rd);
4233     if (ra != 0 && ra != rd)
4234         gen_op_store_T1_gpr(ra);
4235 #endif
4236 }
4237
4238 GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER)
4239 {
4240 #if defined(CONFIG_USER_ONLY)
4241     GEN_EXCP_PRIVOPC(ctx);
4242 #else
4243     if (unlikely(!ctx->supervisor)) {
4244         GEN_EXCP_PRIVOPC(ctx);
4245         return;
4246     }
4247     gen_addr_reg_index(ctx);
4248     gen_op_POWER_rac();
4249     gen_op_store_T0_gpr(rD(ctx->opcode));
4250 #endif
4251 }
4252
4253 GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER)
4254 {
4255 #if defined(CONFIG_USER_ONLY)
4256     GEN_EXCP_PRIVOPC(ctx);
4257 #else
4258     if (unlikely(!ctx->supervisor)) {
4259         GEN_EXCP_PRIVOPC(ctx);
4260         return;
4261     }
4262     gen_op_POWER_rfsvc();
4263     GEN_SYNC(ctx);
4264 #endif
4265 }
4266
4267 /* svc is not implemented for now */
4268
4269 /* POWER2 specific instructions */
4270 /* Quad manipulation (load/store two floats at a time) */
4271 #define op_POWER2_lfq() (*gen_op_POWER2_lfq[ctx->mem_idx])()
4272 #define op_POWER2_stfq() (*gen_op_POWER2_stfq[ctx->mem_idx])()
4273 #if defined(CONFIG_USER_ONLY)
4274 static GenOpFunc *gen_op_POWER2_lfq[] = {
4275     &gen_op_POWER2_lfq_le_raw,
4276     &gen_op_POWER2_lfq_raw,
4277 };
4278 static GenOpFunc *gen_op_POWER2_stfq[] = {
4279     &gen_op_POWER2_stfq_le_raw,
4280     &gen_op_POWER2_stfq_raw,
4281 };
4282 #else
4283 static GenOpFunc *gen_op_POWER2_lfq[] = {
4284     &gen_op_POWER2_lfq_le_user,
4285     &gen_op_POWER2_lfq_user,
4286     &gen_op_POWER2_lfq_le_kernel,
4287     &gen_op_POWER2_lfq_kernel,
4288 };
4289 static GenOpFunc *gen_op_POWER2_stfq[] = {
4290     &gen_op_POWER2_stfq_le_user,
4291     &gen_op_POWER2_stfq_user,
4292     &gen_op_POWER2_stfq_le_kernel,
4293     &gen_op_POWER2_stfq_kernel,
4294 };
4295 #endif
4296
4297 /* lfq */
4298 GEN_HANDLER(lfq, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4299 {
4300     /* NIP cannot be restored if the memory exception comes from an helper */
4301     gen_update_nip(ctx, ctx->nip - 4);
4302     gen_addr_imm_index(ctx, 0);
4303     op_POWER2_lfq();
4304     gen_op_store_FT0_fpr(rD(ctx->opcode));
4305     gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4306 }
4307
4308 /* lfqu */
4309 GEN_HANDLER(lfqu, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4310 {
4311     int ra = rA(ctx->opcode);
4312
4313     /* NIP cannot be restored if the memory exception comes from an helper */
4314     gen_update_nip(ctx, ctx->nip - 4);
4315     gen_addr_imm_index(ctx, 0);
4316     op_POWER2_lfq();
4317     gen_op_store_FT0_fpr(rD(ctx->opcode));
4318     gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4319     if (ra != 0)
4320         gen_op_store_T0_gpr(ra);
4321 }
4322
4323 /* lfqux */
4324 GEN_HANDLER(lfqux, 0x1F, 0x17, 0x19, 0x00000001, PPC_POWER2)
4325 {
4326     int ra = rA(ctx->opcode);
4327
4328     /* NIP cannot be restored if the memory exception comes from an helper */
4329     gen_update_nip(ctx, ctx->nip - 4);
4330     gen_addr_reg_index(ctx);
4331     op_POWER2_lfq();
4332     gen_op_store_FT0_fpr(rD(ctx->opcode));
4333     gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4334     if (ra != 0)
4335         gen_op_store_T0_gpr(ra);
4336 }
4337
4338 /* lfqx */
4339 GEN_HANDLER(lfqx, 0x1F, 0x17, 0x18, 0x00000001, PPC_POWER2)
4340 {
4341     /* NIP cannot be restored if the memory exception comes from an helper */
4342     gen_update_nip(ctx, ctx->nip - 4);
4343     gen_addr_reg_index(ctx);
4344     op_POWER2_lfq();
4345     gen_op_store_FT0_fpr(rD(ctx->opcode));
4346     gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4347 }
4348
4349 /* stfq */
4350 GEN_HANDLER(stfq, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4351 {
4352     /* NIP cannot be restored if the memory exception comes from an helper */
4353     gen_update_nip(ctx, ctx->nip - 4);
4354     gen_addr_imm_index(ctx, 0);
4355     gen_op_load_fpr_FT0(rS(ctx->opcode));
4356     gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4357     op_POWER2_stfq();
4358 }
4359
4360 /* stfqu */
4361 GEN_HANDLER(stfqu, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4362 {
4363     int ra = rA(ctx->opcode);
4364
4365     /* NIP cannot be restored if the memory exception comes from an helper */
4366     gen_update_nip(ctx, ctx->nip - 4);
4367     gen_addr_imm_index(ctx, 0);
4368     gen_op_load_fpr_FT0(rS(ctx->opcode));
4369     gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4370     op_POWER2_stfq();
4371     if (ra != 0)
4372         gen_op_store_T0_gpr(ra);
4373 }
4374
4375 /* stfqux */
4376 GEN_HANDLER(stfqux, 0x1F, 0x17, 0x1D, 0x00000001, PPC_POWER2)
4377 {
4378     int ra = rA(ctx->opcode);
4379
4380     /* NIP cannot be restored if the memory exception comes from an helper */
4381     gen_update_nip(ctx, ctx->nip - 4);
4382     gen_addr_reg_index(ctx);
4383     gen_op_load_fpr_FT0(rS(ctx->opcode));
4384     gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4385     op_POWER2_stfq();
4386     if (ra != 0)
4387         gen_op_store_T0_gpr(ra);
4388 }
4389
4390 /* stfqx */
4391 GEN_HANDLER(stfqx, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2)
4392 {
4393     /* NIP cannot be restored if the memory exception comes from an helper */
4394     gen_update_nip(ctx, ctx->nip - 4);
4395     gen_addr_reg_index(ctx);
4396     gen_op_load_fpr_FT0(rS(ctx->opcode));
4397     gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4398     op_POWER2_stfq();
4399 }
4400
4401 /* BookE specific instructions */
4402 /* XXX: not implemented on 440 ? */
4403 GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_BOOKE_EXT)
4404 {
4405     /* XXX: TODO */
4406     GEN_EXCP_INVAL(ctx);
4407 }
4408
4409 /* XXX: not implemented on 440 ? */
4410 GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_BOOKE_EXT)
4411 {
4412 #if defined(CONFIG_USER_ONLY)
4413     GEN_EXCP_PRIVOPC(ctx);
4414 #else
4415     if (unlikely(!ctx->supervisor)) {
4416         GEN_EXCP_PRIVOPC(ctx);
4417         return;
4418     }
4419     gen_addr_reg_index(ctx);
4420     /* Use the same micro-ops as for tlbie */
4421 #if defined(TARGET_PPC64)
4422     if (ctx->sf_mode)
4423         gen_op_tlbie_64();
4424     else
4425 #endif
4426         gen_op_tlbie();
4427 #endif
4428 }
4429
4430 /* All 405 MAC instructions are translated here */
4431 static inline void gen_405_mulladd_insn (DisasContext *ctx, int opc2, int opc3,
4432                                          int ra, int rb, int rt, int Rc)
4433 {
4434     gen_op_load_gpr_T0(ra);
4435     gen_op_load_gpr_T1(rb);
4436     switch (opc3 & 0x0D) {
4437     case 0x05:
4438         /* macchw    - macchw.    - macchwo   - macchwo.   */
4439         /* macchws   - macchws.   - macchwso  - macchwso.  */
4440         /* nmacchw   - nmacchw.   - nmacchwo  - nmacchwo.  */
4441         /* nmacchws  - nmacchws.  - nmacchwso - nmacchwso. */
4442         /* mulchw - mulchw. */
4443         gen_op_405_mulchw();
4444         break;
4445     case 0x04:
4446         /* macchwu   - macchwu.   - macchwuo  - macchwuo.  */
4447         /* macchwsu  - macchwsu.  - macchwsuo - macchwsuo. */
4448         /* mulchwu - mulchwu. */
4449         gen_op_405_mulchwu();
4450         break;
4451     case 0x01:
4452         /* machhw    - machhw.    - machhwo   - machhwo.   */
4453         /* machhws   - machhws.   - machhwso  - machhwso.  */
4454         /* nmachhw   - nmachhw.   - nmachhwo  - nmachhwo.  */
4455         /* nmachhws  - nmachhws.  - nmachhwso - nmachhwso. */
4456         /* mulhhw - mulhhw. */
4457         gen_op_405_mulhhw();
4458         break;
4459     case 0x00:
4460         /* machhwu   - machhwu.   - machhwuo  - machhwuo.  */
4461         /* machhwsu  - machhwsu.  - machhwsuo - machhwsuo. */
4462         /* mulhhwu - mulhhwu. */
4463         gen_op_405_mulhhwu();
4464         break;
4465     case 0x0D:
4466         /* maclhw    - maclhw.    - maclhwo   - maclhwo.   */
4467         /* maclhws   - maclhws.   - maclhwso  - maclhwso.  */
4468         /* nmaclhw   - nmaclhw.   - nmaclhwo  - nmaclhwo.  */
4469         /* nmaclhws  - nmaclhws.  - nmaclhwso - nmaclhwso. */
4470         /* mullhw - mullhw. */
4471         gen_op_405_mullhw();
4472         break;
4473     case 0x0C:
4474         /* maclhwu   - maclhwu.   - maclhwuo  - maclhwuo.  */
4475         /* maclhwsu  - maclhwsu.  - maclhwsuo - maclhwsuo. */
4476         /* mullhwu - mullhwu. */
4477         gen_op_405_mullhwu();
4478         break;
4479     }
4480     if (opc2 & 0x02) {
4481         /* nmultiply-and-accumulate (0x0E) */
4482         gen_op_neg();
4483     }
4484     if (opc2 & 0x04) {
4485         /* (n)multiply-and-accumulate (0x0C - 0x0E) */
4486         gen_op_load_gpr_T2(rt);
4487         gen_op_move_T1_T0();
4488         gen_op_405_add_T0_T2();
4489     }
4490     if (opc3 & 0x10) {
4491         /* Check overflow */
4492         if (opc3 & 0x01)
4493             gen_op_405_check_ov();
4494         else
4495             gen_op_405_check_ovu();
4496     }
4497     if (opc3 & 0x02) {
4498         /* Saturate */
4499         if (opc3 & 0x01)
4500             gen_op_405_check_sat();
4501         else
4502             gen_op_405_check_satu();
4503     }
4504     gen_op_store_T0_gpr(rt);
4505     if (unlikely(Rc) != 0) {
4506         /* Update Rc0 */
4507         gen_set_Rc0(ctx);
4508     }
4509 }
4510
4511 #define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
4512 GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC)                  \
4513 {                                                                             \
4514     gen_405_mulladd_insn(ctx, opc2, opc3, rA(ctx->opcode), rB(ctx->opcode),   \
4515                          rD(ctx->opcode), Rc(ctx->opcode));                   \
4516 }
4517
4518 /* macchw    - macchw.    */
4519 GEN_MAC_HANDLER(macchw, 0x0C, 0x05);
4520 /* macchwo   - macchwo.   */
4521 GEN_MAC_HANDLER(macchwo, 0x0C, 0x15);
4522 /* macchws   - macchws.   */
4523 GEN_MAC_HANDLER(macchws, 0x0C, 0x07);
4524 /* macchwso  - macchwso.  */
4525 GEN_MAC_HANDLER(macchwso, 0x0C, 0x17);
4526 /* macchwsu  - macchwsu.  */
4527 GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06);
4528 /* macchwsuo - macchwsuo. */
4529 GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16);
4530 /* macchwu   - macchwu.   */
4531 GEN_MAC_HANDLER(macchwu, 0x0C, 0x04);
4532 /* macchwuo  - macchwuo.  */
4533 GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14);
4534 /* machhw    - machhw.    */
4535 GEN_MAC_HANDLER(machhw, 0x0C, 0x01);
4536 /* machhwo   - machhwo.   */
4537 GEN_MAC_HANDLER(machhwo, 0x0C, 0x11);
4538 /* machhws   - machhws.   */
4539 GEN_MAC_HANDLER(machhws, 0x0C, 0x03);
4540 /* machhwso  - machhwso.  */
4541 GEN_MAC_HANDLER(machhwso, 0x0C, 0x13);
4542 /* machhwsu  - machhwsu.  */
4543 GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02);
4544 /* machhwsuo - machhwsuo. */
4545 GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12);
4546 /* machhwu   - machhwu.   */
4547 GEN_MAC_HANDLER(machhwu, 0x0C, 0x00);
4548 /* machhwuo  - machhwuo.  */
4549 GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10);
4550 /* maclhw    - maclhw.    */
4551 GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D);
4552 /* maclhwo   - maclhwo.   */
4553 GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D);
4554 /* maclhws   - maclhws.   */
4555 GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F);
4556 /* maclhwso  - maclhwso.  */
4557 GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F);
4558 /* maclhwu   - maclhwu.   */
4559 GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C);
4560 /* maclhwuo  - maclhwuo.  */
4561 GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C);
4562 /* maclhwsu  - maclhwsu.  */
4563 GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E);
4564 /* maclhwsuo - maclhwsuo. */
4565 GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E);
4566 /* nmacchw   - nmacchw.   */
4567 GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05);
4568 /* nmacchwo  - nmacchwo.  */
4569 GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15);
4570 /* nmacchws  - nmacchws.  */
4571 GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07);
4572 /* nmacchwso - nmacchwso. */
4573 GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17);
4574 /* nmachhw   - nmachhw.   */
4575 GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01);
4576 /* nmachhwo  - nmachhwo.  */
4577 GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11);
4578 /* nmachhws  - nmachhws.  */
4579 GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03);
4580 /* nmachhwso - nmachhwso. */
4581 GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13);
4582 /* nmaclhw   - nmaclhw.   */
4583 GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D);
4584 /* nmaclhwo  - nmaclhwo.  */
4585 GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D);
4586 /* nmaclhws  - nmaclhws.  */
4587 GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F);
4588 /* nmaclhwso - nmaclhwso. */
4589 GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F);
4590
4591 /* mulchw  - mulchw.  */
4592 GEN_MAC_HANDLER(mulchw, 0x08, 0x05);
4593 /* mulchwu - mulchwu. */
4594 GEN_MAC_HANDLER(mulchwu, 0x08, 0x04);
4595 /* mulhhw  - mulhhw.  */
4596 GEN_MAC_HANDLER(mulhhw, 0x08, 0x01);
4597 /* mulhhwu - mulhhwu. */
4598 GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00);
4599 /* mullhw  - mullhw.  */
4600 GEN_MAC_HANDLER(mullhw, 0x08, 0x0D);
4601 /* mullhwu - mullhwu. */
4602 GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C);
4603
4604 /* mfdcr */
4605 GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_EMB_COMMON)
4606 {
4607 #if defined(CONFIG_USER_ONLY)
4608     GEN_EXCP_PRIVREG(ctx);
4609 #else
4610     uint32_t dcrn = SPR(ctx->opcode);
4611
4612     if (unlikely(!ctx->supervisor)) {
4613         GEN_EXCP_PRIVREG(ctx);
4614         return;
4615     }
4616     gen_op_set_T0(dcrn);
4617     gen_op_load_dcr();
4618     gen_op_store_T0_gpr(rD(ctx->opcode));
4619 #endif
4620 }
4621
4622 /* mtdcr */
4623 GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_EMB_COMMON)
4624 {
4625 #if defined(CONFIG_USER_ONLY)
4626     GEN_EXCP_PRIVREG(ctx);
4627 #else
4628     uint32_t dcrn = SPR(ctx->opcode);
4629
4630     if (unlikely(!ctx->supervisor)) {
4631         GEN_EXCP_PRIVREG(ctx);
4632         return;
4633     }
4634     gen_op_set_T0(dcrn);
4635     gen_op_load_gpr_T1(rS(ctx->opcode));
4636     gen_op_store_dcr();
4637 #endif
4638 }
4639
4640 /* mfdcrx */
4641 /* XXX: not implemented on 440 ? */
4642 GEN_HANDLER(mfdcrx, 0x1F, 0x03, 0x08, 0x00000000, PPC_BOOKE_EXT)
4643 {
4644 #if defined(CONFIG_USER_ONLY)
4645     GEN_EXCP_PRIVREG(ctx);
4646 #else
4647     if (unlikely(!ctx->supervisor)) {
4648         GEN_EXCP_PRIVREG(ctx);
4649         return;
4650     }
4651     gen_op_load_gpr_T0(rA(ctx->opcode));
4652     gen_op_load_dcr();
4653     gen_op_store_T0_gpr(rD(ctx->opcode));
4654     /* Note: Rc update flag set leads to undefined state of Rc0 */
4655 #endif
4656 }
4657
4658 /* mtdcrx */
4659 /* XXX: not implemented on 440 ? */
4660 GEN_HANDLER(mtdcrx, 0x1F, 0x03, 0x0C, 0x00000000, PPC_BOOKE_EXT)
4661 {
4662 #if defined(CONFIG_USER_ONLY)
4663     GEN_EXCP_PRIVREG(ctx);
4664 #else
4665     if (unlikely(!ctx->supervisor)) {
4666         GEN_EXCP_PRIVREG(ctx);
4667         return;
4668     }
4669     gen_op_load_gpr_T0(rA(ctx->opcode));
4670     gen_op_load_gpr_T1(rS(ctx->opcode));
4671     gen_op_store_dcr();
4672     /* Note: Rc update flag set leads to undefined state of Rc0 */
4673 #endif
4674 }
4675
4676 /* mfdcrux (PPC 460) : user-mode access to DCR */
4677 GEN_HANDLER(mfdcrux, 0x1F, 0x03, 0x09, 0x00000000, PPC_DCRUX)
4678 {
4679     gen_op_load_gpr_T0(rA(ctx->opcode));
4680     gen_op_load_dcr();
4681     gen_op_store_T0_gpr(rD(ctx->opcode));
4682     /* Note: Rc update flag set leads to undefined state of Rc0 */
4683 }
4684
4685 /* mtdcrux (PPC 460) : user-mode access to DCR */
4686 GEN_HANDLER(mtdcrux, 0x1F, 0x03, 0x0D, 0x00000000, PPC_DCRUX)
4687 {
4688     gen_op_load_gpr_T0(rA(ctx->opcode));
4689     gen_op_load_gpr_T1(rS(ctx->opcode));
4690     gen_op_store_dcr();
4691     /* Note: Rc update flag set leads to undefined state of Rc0 */
4692 }
4693
4694 /* dccci */
4695 GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON)
4696 {
4697 #if defined(CONFIG_USER_ONLY)
4698     GEN_EXCP_PRIVOPC(ctx);
4699 #else
4700     if (unlikely(!ctx->supervisor)) {
4701         GEN_EXCP_PRIVOPC(ctx);
4702         return;
4703     }
4704     /* interpreted as no-op */
4705 #endif
4706 }
4707
4708 /* dcread */
4709 GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON)
4710 {
4711 #if defined(CONFIG_USER_ONLY)
4712     GEN_EXCP_PRIVOPC(ctx);
4713 #else
4714     if (unlikely(!ctx->supervisor)) {
4715         GEN_EXCP_PRIVOPC(ctx);
4716         return;
4717     }
4718     gen_addr_reg_index(ctx);
4719     op_ldst(lwz);
4720     gen_op_store_T0_gpr(rD(ctx->opcode));
4721 #endif
4722 }
4723
4724 /* icbt */
4725 GEN_HANDLER(icbt_40x, 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_ICBT)
4726 {
4727     /* interpreted as no-op */
4728     /* XXX: specification say this is treated as a load by the MMU
4729      *      but does not generate any exception
4730      */
4731 }
4732
4733 /* iccci */
4734 GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON)
4735 {
4736 #if defined(CONFIG_USER_ONLY)
4737     GEN_EXCP_PRIVOPC(ctx);
4738 #else
4739     if (unlikely(!ctx->supervisor)) {
4740         GEN_EXCP_PRIVOPC(ctx);
4741         return;
4742     }
4743     /* interpreted as no-op */
4744 #endif
4745 }
4746
4747 /* icread */
4748 GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON)
4749 {
4750 #if defined(CONFIG_USER_ONLY)
4751     GEN_EXCP_PRIVOPC(ctx);
4752 #else
4753     if (unlikely(!ctx->supervisor)) {
4754         GEN_EXCP_PRIVOPC(ctx);
4755         return;
4756     }
4757     /* interpreted as no-op */
4758 #endif
4759 }
4760
4761 /* rfci (supervisor only) */
4762 GEN_HANDLER(rfci_40x, 0x13, 0x13, 0x01, 0x03FF8001, PPC_40x_EXCP)
4763 {
4764 #if defined(CONFIG_USER_ONLY)
4765     GEN_EXCP_PRIVOPC(ctx);
4766 #else
4767     if (unlikely(!ctx->supervisor)) {
4768         GEN_EXCP_PRIVOPC(ctx);
4769         return;
4770     }
4771     /* Restore CPU state */
4772     gen_op_40x_rfci();
4773     GEN_SYNC(ctx);
4774 #endif
4775 }
4776
4777 GEN_HANDLER(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE)
4778 {
4779 #if defined(CONFIG_USER_ONLY)
4780     GEN_EXCP_PRIVOPC(ctx);
4781 #else
4782     if (unlikely(!ctx->supervisor)) {
4783         GEN_EXCP_PRIVOPC(ctx);
4784         return;
4785     }
4786     /* Restore CPU state */
4787     gen_op_rfci();
4788     GEN_SYNC(ctx);
4789 #endif
4790 }
4791
4792 /* BookE specific */
4793 /* XXX: not implemented on 440 ? */
4794 GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_BOOKE_EXT)
4795 {
4796 #if defined(CONFIG_USER_ONLY)
4797     GEN_EXCP_PRIVOPC(ctx);
4798 #else
4799     if (unlikely(!ctx->supervisor)) {
4800         GEN_EXCP_PRIVOPC(ctx);
4801         return;
4802     }
4803     /* Restore CPU state */
4804     gen_op_rfdi();
4805     GEN_SYNC(ctx);
4806 #endif
4807 }
4808
4809 /* XXX: not implemented on 440 ? */
4810 GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_RFMCI)
4811 {
4812 #if defined(CONFIG_USER_ONLY)
4813     GEN_EXCP_PRIVOPC(ctx);
4814 #else
4815     if (unlikely(!ctx->supervisor)) {
4816         GEN_EXCP_PRIVOPC(ctx);
4817         return;
4818     }
4819     /* Restore CPU state */
4820     gen_op_rfmci();
4821     GEN_SYNC(ctx);
4822 #endif
4823 }
4824
4825 /* TLB management - PowerPC 405 implementation */
4826 /* tlbre */
4827 GEN_HANDLER(tlbre_40x, 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB)
4828 {
4829 #if defined(CONFIG_USER_ONLY)
4830     GEN_EXCP_PRIVOPC(ctx);
4831 #else
4832     if (unlikely(!ctx->supervisor)) {
4833         GEN_EXCP_PRIVOPC(ctx);
4834         return;
4835     }
4836     switch (rB(ctx->opcode)) {
4837     case 0:
4838         gen_op_load_gpr_T0(rA(ctx->opcode));
4839         gen_op_4xx_tlbre_hi();
4840         gen_op_store_T0_gpr(rD(ctx->opcode));
4841         break;
4842     case 1:
4843         gen_op_load_gpr_T0(rA(ctx->opcode));
4844         gen_op_4xx_tlbre_lo();
4845         gen_op_store_T0_gpr(rD(ctx->opcode));
4846         break;
4847     default:
4848         GEN_EXCP_INVAL(ctx);
4849         break;
4850     }
4851 #endif
4852 }
4853
4854 /* tlbsx - tlbsx. */
4855 GEN_HANDLER(tlbsx_40x, 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB)
4856 {
4857 #if defined(CONFIG_USER_ONLY)
4858     GEN_EXCP_PRIVOPC(ctx);
4859 #else
4860     if (unlikely(!ctx->supervisor)) {
4861         GEN_EXCP_PRIVOPC(ctx);
4862         return;
4863     }
4864     gen_addr_reg_index(ctx);
4865     if (Rc(ctx->opcode))
4866         gen_op_4xx_tlbsx_();
4867     else
4868         gen_op_4xx_tlbsx();
4869     gen_op_store_T0_gpr(rD(ctx->opcode));
4870 #endif
4871 }
4872
4873 /* tlbwe */
4874 GEN_HANDLER(tlbwe_40x, 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB)
4875 {
4876 #if defined(CONFIG_USER_ONLY)
4877     GEN_EXCP_PRIVOPC(ctx);
4878 #else
4879     if (unlikely(!ctx->supervisor)) {
4880         GEN_EXCP_PRIVOPC(ctx);
4881         return;
4882     }
4883     switch (rB(ctx->opcode)) {
4884     case 0:
4885         gen_op_load_gpr_T0(rA(ctx->opcode));
4886         gen_op_load_gpr_T1(rS(ctx->opcode));
4887         gen_op_4xx_tlbwe_hi();
4888         break;
4889     case 1:
4890         gen_op_load_gpr_T0(rA(ctx->opcode));
4891         gen_op_load_gpr_T1(rS(ctx->opcode));
4892         gen_op_4xx_tlbwe_lo();
4893         break;
4894     default:
4895         GEN_EXCP_INVAL(ctx);
4896         break;
4897     }
4898 #endif
4899 }
4900
4901 /* TLB management - PowerPC 440 implementation */
4902 /* tlbre */
4903 GEN_HANDLER(tlbre_440, 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE)
4904 {
4905 #if defined(CONFIG_USER_ONLY)
4906     GEN_EXCP_PRIVOPC(ctx);
4907 #else
4908     if (unlikely(!ctx->supervisor)) {
4909         GEN_EXCP_PRIVOPC(ctx);
4910         return;
4911     }
4912     switch (rB(ctx->opcode)) {
4913     case 0:
4914     case 1:
4915     case 2:
4916         gen_op_load_gpr_T0(rA(ctx->opcode));
4917         gen_op_440_tlbre(rB(ctx->opcode));
4918         gen_op_store_T0_gpr(rD(ctx->opcode));
4919         break;
4920     default:
4921         GEN_EXCP_INVAL(ctx);
4922         break;
4923     }
4924 #endif
4925 }
4926
4927 /* tlbsx - tlbsx. */
4928 GEN_HANDLER(tlbsx_440, 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE)
4929 {
4930 #if defined(CONFIG_USER_ONLY)
4931     GEN_EXCP_PRIVOPC(ctx);
4932 #else
4933     if (unlikely(!ctx->supervisor)) {
4934         GEN_EXCP_PRIVOPC(ctx);
4935         return;
4936     }
4937     gen_addr_reg_index(ctx);
4938     if (Rc(ctx->opcode))
4939         gen_op_440_tlbsx_();
4940     else
4941         gen_op_440_tlbsx();
4942     gen_op_store_T0_gpr(rD(ctx->opcode));
4943 #endif
4944 }
4945
4946 /* tlbwe */
4947 GEN_HANDLER(tlbwe_440, 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE)
4948 {
4949 #if defined(CONFIG_USER_ONLY)
4950     GEN_EXCP_PRIVOPC(ctx);
4951 #else
4952     if (unlikely(!ctx->supervisor)) {
4953         GEN_EXCP_PRIVOPC(ctx);
4954         return;
4955     }
4956     switch (rB(ctx->opcode)) {
4957     case 0:
4958     case 1:
4959     case 2:
4960         gen_op_load_gpr_T0(rA(ctx->opcode));
4961         gen_op_load_gpr_T1(rS(ctx->opcode));
4962         gen_op_440_tlbwe(rB(ctx->opcode));
4963         break;
4964     default:
4965         GEN_EXCP_INVAL(ctx);
4966         break;
4967     }
4968 #endif
4969 }
4970
4971 /* wrtee */
4972 GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_EMB_COMMON)
4973 {
4974 #if defined(CONFIG_USER_ONLY)
4975     GEN_EXCP_PRIVOPC(ctx);
4976 #else
4977     if (unlikely(!ctx->supervisor)) {
4978         GEN_EXCP_PRIVOPC(ctx);
4979         return;
4980     }
4981     gen_op_load_gpr_T0(rD(ctx->opcode));
4982     gen_op_wrte();
4983     /* Stop translation to have a chance to raise an exception
4984      * if we just set msr_ee to 1
4985      */
4986     GEN_STOP(ctx);
4987 #endif
4988 }
4989
4990 /* wrteei */
4991 GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000EFC01, PPC_EMB_COMMON)
4992 {
4993 #if defined(CONFIG_USER_ONLY)
4994     GEN_EXCP_PRIVOPC(ctx);
4995 #else
4996     if (unlikely(!ctx->supervisor)) {
4997         GEN_EXCP_PRIVOPC(ctx);
4998         return;
4999     }
5000     gen_op_set_T0(ctx->opcode & 0x00010000);
5001     gen_op_wrte();
5002     /* Stop translation to have a chance to raise an exception
5003      * if we just set msr_ee to 1
5004      */
5005     GEN_STOP(ctx);
5006 #endif
5007 }
5008
5009 /* PowerPC 440 specific instructions */
5010 /* dlmzb */
5011 GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC)
5012 {
5013     gen_op_load_gpr_T0(rS(ctx->opcode));
5014     gen_op_load_gpr_T1(rB(ctx->opcode));
5015     gen_op_440_dlmzb();
5016     gen_op_store_T0_gpr(rA(ctx->opcode));
5017     gen_op_store_xer_bc();
5018     if (Rc(ctx->opcode)) {
5019         gen_op_440_dlmzb_update_Rc();
5020         gen_op_store_T0_crf(0);
5021     }
5022 }
5023
5024 /* mbar replaces eieio on 440 */
5025 GEN_HANDLER(mbar, 0x1F, 0x16, 0x13, 0x001FF801, PPC_BOOKE)
5026 {
5027     /* interpreted as no-op */
5028 }
5029
5030 /* msync replaces sync on 440 */
5031 GEN_HANDLER(msync, 0x1F, 0x16, 0x12, 0x03FFF801, PPC_BOOKE)
5032 {
5033     /* interpreted as no-op */
5034 }
5035
5036 /* icbt */
5037 GEN_HANDLER(icbt_440, 0x1F, 0x16, 0x00, 0x03E00001, PPC_BOOKE)
5038 {
5039     /* interpreted as no-op */
5040     /* XXX: specification say this is treated as a load by the MMU
5041      *      but does not generate any exception
5042      */
5043 }
5044
5045 #if defined(TARGET_PPCEMB)
5046 /***                           SPE extension                               ***/
5047
5048 /* Register moves */
5049 GEN32(gen_op_load_gpr64_T0, gen_op_load_gpr64_T0_gpr);
5050 GEN32(gen_op_load_gpr64_T1, gen_op_load_gpr64_T1_gpr);
5051 #if 0 // unused
5052 GEN32(gen_op_load_gpr64_T2, gen_op_load_gpr64_T2_gpr);
5053 #endif
5054
5055 GEN32(gen_op_store_T0_gpr64, gen_op_store_T0_gpr64_gpr);
5056 GEN32(gen_op_store_T1_gpr64, gen_op_store_T1_gpr64_gpr);
5057 #if 0 // unused
5058 GEN32(gen_op_store_T2_gpr64, gen_op_store_T2_gpr64_gpr);
5059 #endif
5060
5061 #define GEN_SPE(name0, name1, opc2, opc3, inval, type)                        \
5062 GEN_HANDLER(name0##_##name1, 0x04, opc2, opc3, inval, type)                   \
5063 {                                                                             \
5064     if (Rc(ctx->opcode))                                                      \
5065         gen_##name1(ctx);                                                     \
5066     else                                                                      \
5067         gen_##name0(ctx);                                                     \
5068 }
5069
5070 /* Handler for undefined SPE opcodes */
5071 static inline void gen_speundef (DisasContext *ctx)
5072 {
5073     GEN_EXCP_INVAL(ctx);
5074 }
5075
5076 /* SPE load and stores */
5077 static inline void gen_addr_spe_imm_index (DisasContext *ctx, int sh)
5078 {
5079     target_long simm = rB(ctx->opcode);
5080
5081     if (rA(ctx->opcode) == 0) {
5082         gen_set_T0(simm << sh);
5083     } else {
5084         gen_op_load_gpr_T0(rA(ctx->opcode));
5085         if (likely(simm != 0))
5086             gen_op_addi(simm << sh);
5087     }
5088 }
5089
5090 #define op_spe_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
5091 #if defined(CONFIG_USER_ONLY)
5092 #if defined(TARGET_PPC64)
5093 #define OP_SPE_LD_TABLE(name)                                                 \
5094 static GenOpFunc *gen_op_spe_l##name[] = {                                    \
5095     &gen_op_spe_l##name##_raw,                                                \
5096     &gen_op_spe_l##name##_le_raw,                                             \
5097     &gen_op_spe_l##name##_64_raw,                                             \
5098     &gen_op_spe_l##name##_le_64_raw,                                          \
5099 };
5100 #define OP_SPE_ST_TABLE(name)                                                 \
5101 static GenOpFunc *gen_op_spe_st##name[] = {                                   \
5102     &gen_op_spe_st##name##_raw,                                               \
5103     &gen_op_spe_st##name##_le_raw,                                            \
5104     &gen_op_spe_st##name##_64_raw,                                            \
5105     &gen_op_spe_st##name##_le_64_raw,                                         \
5106 };
5107 #else /* defined(TARGET_PPC64) */
5108 #define OP_SPE_LD_TABLE(name)                                                 \
5109 static GenOpFunc *gen_op_spe_l##name[] = {                                    \
5110     &gen_op_spe_l##name##_raw,                                                \
5111     &gen_op_spe_l##name##_le_raw,                                             \
5112 };
5113 #define OP_SPE_ST_TABLE(name)                                                 \
5114 static GenOpFunc *gen_op_spe_st##name[] = {                                   \
5115     &gen_op_spe_st##name##_raw,                                               \
5116     &gen_op_spe_st##name##_le_raw,                                            \
5117 };
5118 #endif /* defined(TARGET_PPC64) */
5119 #else /* defined(CONFIG_USER_ONLY) */
5120 #if defined(TARGET_PPC64)
5121 #define OP_SPE_LD_TABLE(name)                                                 \
5122 static GenOpFunc *gen_op_spe_l##name[] = {                                    \
5123     &gen_op_spe_l##name##_user,                                               \
5124     &gen_op_spe_l##name##_le_user,                                            \
5125     &gen_op_spe_l##name##_kernel,                                             \
5126     &gen_op_spe_l##name##_le_kernel,                                          \
5127     &gen_op_spe_l##name##_64_user,                                            \
5128     &gen_op_spe_l##name##_le_64_user,                                         \
5129     &gen_op_spe_l##name##_64_kernel,                                          \
5130     &gen_op_spe_l##name##_le_64_kernel,                                       \
5131 };
5132 #define OP_SPE_ST_TABLE(name)                                                 \
5133 static GenOpFunc *gen_op_spe_st##name[] = {                                   \
5134     &gen_op_spe_st##name##_user,                                              \
5135     &gen_op_spe_st##name##_le_user,                                           \
5136     &gen_op_spe_st##name##_kernel,                                            \
5137     &gen_op_spe_st##name##_le_kernel,                                         \
5138     &gen_op_spe_st##name##_64_user,                                           \
5139     &gen_op_spe_st##name##_le_64_user,                                        \
5140     &gen_op_spe_st##name##_64_kernel,                                         \
5141     &gen_op_spe_st##name##_le_64_kernel,                                      \
5142 };
5143 #else /* defined(TARGET_PPC64) */
5144 #define OP_SPE_LD_TABLE(name)                                                 \
5145 static GenOpFunc *gen_op_spe_l##name[] = {                                    \
5146     &gen_op_spe_l##name##_user,                                               \
5147     &gen_op_spe_l##name##_le_user,                                            \
5148     &gen_op_spe_l##name##_kernel,                                             \
5149     &gen_op_spe_l##name##_le_kernel,                                          \
5150 };
5151 #define OP_SPE_ST_TABLE(name)                                                 \
5152 static GenOpFunc *gen_op_spe_st##name[] = {                                   \
5153     &gen_op_spe_st##name##_user,                                              \
5154     &gen_op_spe_st##name##_le_user,                                           \
5155     &gen_op_spe_st##name##_kernel,                                            \
5156     &gen_op_spe_st##name##_le_kernel,                                         \
5157 };
5158 #endif /* defined(TARGET_PPC64) */
5159 #endif /* defined(CONFIG_USER_ONLY) */
5160
5161 #define GEN_SPE_LD(name, sh)                                                  \
5162 static inline void gen_evl##name (DisasContext *ctx)                          \
5163 {                                                                             \
5164     if (unlikely(!ctx->spe_enabled)) {                                        \
5165         GEN_EXCP_NO_AP(ctx);                                                  \
5166         return;                                                               \
5167     }                                                                         \
5168     gen_addr_spe_imm_index(ctx, sh);                                          \
5169     op_spe_ldst(spe_l##name);                                                 \
5170     gen_op_store_T1_gpr64(rD(ctx->opcode));                                   \
5171 }
5172
5173 #define GEN_SPE_LDX(name)                                                     \
5174 static inline void gen_evl##name##x (DisasContext *ctx)                       \
5175 {                                                                             \
5176     if (unlikely(!ctx->spe_enabled)) {                                        \
5177         GEN_EXCP_NO_AP(ctx);                                                  \
5178         return;                                                               \
5179     }                                                                         \
5180     gen_addr_reg_index(ctx);                                                  \
5181     op_spe_ldst(spe_l##name);                                                 \
5182     gen_op_store_T1_gpr64(rD(ctx->opcode));                                   \
5183 }
5184
5185 #define GEN_SPEOP_LD(name, sh)                                                \
5186 OP_SPE_LD_TABLE(name);                                                        \
5187 GEN_SPE_LD(name, sh);                                                         \
5188 GEN_SPE_LDX(name)
5189
5190 #define GEN_SPE_ST(name, sh)                                                  \
5191 static inline void gen_evst##name (DisasContext *ctx)                         \
5192 {                                                                             \
5193     if (unlikely(!ctx->spe_enabled)) {                                        \
5194         GEN_EXCP_NO_AP(ctx);                                                  \
5195         return;                                                               \
5196     }                                                                         \
5197     gen_addr_spe_imm_index(ctx, sh);                                          \
5198     gen_op_load_gpr64_T1(rS(ctx->opcode));                                    \
5199     op_spe_ldst(spe_st##name);                                                \
5200 }
5201
5202 #define GEN_SPE_STX(name)                                                     \
5203 static inline void gen_evst##name##x (DisasContext *ctx)                      \
5204 {                                                                             \
5205     if (unlikely(!ctx->spe_enabled)) {                                        \
5206         GEN_EXCP_NO_AP(ctx);                                                  \
5207         return;                                                               \
5208     }                                                                         \
5209     gen_addr_reg_index(ctx);                                                  \
5210     gen_op_load_gpr64_T1(rS(ctx->opcode));                                    \
5211     op_spe_ldst(spe_st##name);                                                \
5212 }
5213
5214 #define GEN_SPEOP_ST(name, sh)                                                \
5215 OP_SPE_ST_TABLE(name);                                                        \
5216 GEN_SPE_ST(name, sh);                                                         \
5217 GEN_SPE_STX(name)
5218
5219 #define GEN_SPEOP_LDST(name, sh)                                              \
5220 GEN_SPEOP_LD(name, sh);                                                       \
5221 GEN_SPEOP_ST(name, sh)
5222
5223 /* SPE arithmetic and logic */
5224 #define GEN_SPEOP_ARITH2(name)                                                \
5225 static inline void gen_##name (DisasContext *ctx)                             \
5226 {                                                                             \
5227     if (unlikely(!ctx->spe_enabled)) {                                        \
5228         GEN_EXCP_NO_AP(ctx);                                                  \
5229         return;                                                               \
5230     }                                                                         \
5231     gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
5232     gen_op_load_gpr64_T1(rB(ctx->opcode));                                    \
5233     gen_op_##name();                                                          \
5234     gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5235 }
5236
5237 #define GEN_SPEOP_ARITH1(name)                                                \
5238 static inline void gen_##name (DisasContext *ctx)                             \
5239 {                                                                             \
5240     if (unlikely(!ctx->spe_enabled)) {                                        \
5241         GEN_EXCP_NO_AP(ctx);                                                  \
5242         return;                                                               \
5243     }                                                                         \
5244     gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
5245     gen_op_##name();                                                          \
5246     gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5247 }
5248
5249 #define GEN_SPEOP_COMP(name)                                                  \
5250 static inline void gen_##name (DisasContext *ctx)                             \
5251 {                                                                             \
5252     if (unlikely(!ctx->spe_enabled)) {                                        \
5253         GEN_EXCP_NO_AP(ctx);                                                  \
5254         return;                                                               \
5255     }                                                                         \
5256     gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
5257     gen_op_load_gpr64_T1(rB(ctx->opcode));                                    \
5258     gen_op_##name();                                                          \
5259     gen_op_store_T0_crf(crfD(ctx->opcode));                                   \
5260 }
5261
5262 /* Logical */
5263 GEN_SPEOP_ARITH2(evand);
5264 GEN_SPEOP_ARITH2(evandc);
5265 GEN_SPEOP_ARITH2(evxor);
5266 GEN_SPEOP_ARITH2(evor);
5267 GEN_SPEOP_ARITH2(evnor);
5268 GEN_SPEOP_ARITH2(eveqv);
5269 GEN_SPEOP_ARITH2(evorc);
5270 GEN_SPEOP_ARITH2(evnand);
5271 GEN_SPEOP_ARITH2(evsrwu);
5272 GEN_SPEOP_ARITH2(evsrws);
5273 GEN_SPEOP_ARITH2(evslw);
5274 GEN_SPEOP_ARITH2(evrlw);
5275 GEN_SPEOP_ARITH2(evmergehi);
5276 GEN_SPEOP_ARITH2(evmergelo);
5277 GEN_SPEOP_ARITH2(evmergehilo);
5278 GEN_SPEOP_ARITH2(evmergelohi);
5279
5280 /* Arithmetic */
5281 GEN_SPEOP_ARITH2(evaddw);
5282 GEN_SPEOP_ARITH2(evsubfw);
5283 GEN_SPEOP_ARITH1(evabs);
5284 GEN_SPEOP_ARITH1(evneg);
5285 GEN_SPEOP_ARITH1(evextsb);
5286 GEN_SPEOP_ARITH1(evextsh);
5287 GEN_SPEOP_ARITH1(evrndw);
5288 GEN_SPEOP_ARITH1(evcntlzw);
5289 GEN_SPEOP_ARITH1(evcntlsw);
5290 static inline void gen_brinc (DisasContext *ctx)
5291 {
5292     /* Note: brinc is usable even if SPE is disabled */
5293     gen_op_load_gpr64_T0(rA(ctx->opcode));
5294     gen_op_load_gpr64_T1(rB(ctx->opcode));
5295     gen_op_brinc();
5296     gen_op_store_T0_gpr64(rD(ctx->opcode));
5297 }
5298
5299 #define GEN_SPEOP_ARITH_IMM2(name)                                            \
5300 static inline void gen_##name##i (DisasContext *ctx)                          \
5301 {                                                                             \
5302     if (unlikely(!ctx->spe_enabled)) {                                        \
5303         GEN_EXCP_NO_AP(ctx);                                                  \
5304         return;                                                               \
5305     }                                                                         \
5306     gen_op_load_gpr64_T0(rB(ctx->opcode));                                    \
5307     gen_op_splatwi_T1_64(rA(ctx->opcode));                                    \
5308     gen_op_##name();                                                          \
5309     gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5310 }
5311
5312 #define GEN_SPEOP_LOGIC_IMM2(name)                                            \
5313 static inline void gen_##name##i (DisasContext *ctx)                          \
5314 {                                                                             \
5315     if (unlikely(!ctx->spe_enabled)) {                                        \
5316         GEN_EXCP_NO_AP(ctx);                                                  \
5317         return;                                                               \
5318     }                                                                         \
5319     gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
5320     gen_op_splatwi_T1_64(rB(ctx->opcode));                                    \
5321     gen_op_##name();                                                          \
5322     gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5323 }
5324
5325 GEN_SPEOP_ARITH_IMM2(evaddw);
5326 #define gen_evaddiw gen_evaddwi
5327 GEN_SPEOP_ARITH_IMM2(evsubfw);
5328 #define gen_evsubifw gen_evsubfwi
5329 GEN_SPEOP_LOGIC_IMM2(evslw);
5330 GEN_SPEOP_LOGIC_IMM2(evsrwu);
5331 #define gen_evsrwis gen_evsrwsi
5332 GEN_SPEOP_LOGIC_IMM2(evsrws);
5333 #define gen_evsrwiu gen_evsrwui
5334 GEN_SPEOP_LOGIC_IMM2(evrlw);
5335
5336 static inline void gen_evsplati (DisasContext *ctx)
5337 {
5338     int32_t imm = (int32_t)(rA(ctx->opcode) << 27) >> 27;
5339
5340     gen_op_splatwi_T0_64(imm);
5341     gen_op_store_T0_gpr64(rD(ctx->opcode));
5342 }
5343
5344 static inline void gen_evsplatfi (DisasContext *ctx)
5345 {
5346     uint32_t imm = rA(ctx->opcode) << 27;
5347
5348     gen_op_splatwi_T0_64(imm);
5349     gen_op_store_T0_gpr64(rD(ctx->opcode));
5350 }
5351
5352 /* Comparison */
5353 GEN_SPEOP_COMP(evcmpgtu);
5354 GEN_SPEOP_COMP(evcmpgts);
5355 GEN_SPEOP_COMP(evcmpltu);
5356 GEN_SPEOP_COMP(evcmplts);
5357 GEN_SPEOP_COMP(evcmpeq);
5358
5359 GEN_SPE(evaddw,         speundef,      0x00, 0x08, 0x00000000, PPC_SPE); ////
5360 GEN_SPE(evaddiw,        speundef,      0x01, 0x08, 0x00000000, PPC_SPE);
5361 GEN_SPE(evsubfw,        speundef,      0x02, 0x08, 0x00000000, PPC_SPE); ////
5362 GEN_SPE(evsubifw,       speundef,      0x03, 0x08, 0x00000000, PPC_SPE);
5363 GEN_SPE(evabs,          evneg,         0x04, 0x08, 0x0000F800, PPC_SPE); ////
5364 GEN_SPE(evextsb,        evextsh,       0x05, 0x08, 0x0000F800, PPC_SPE); ////
5365 GEN_SPE(evrndw,         evcntlzw,      0x06, 0x08, 0x0000F800, PPC_SPE); ////
5366 GEN_SPE(evcntlsw,       brinc,         0x07, 0x08, 0x00000000, PPC_SPE); //
5367 GEN_SPE(speundef,       evand,         0x08, 0x08, 0x00000000, PPC_SPE); ////
5368 GEN_SPE(evandc,         speundef,      0x09, 0x08, 0x00000000, PPC_SPE); ////
5369 GEN_SPE(evxor,          evor,          0x0B, 0x08, 0x00000000, PPC_SPE); ////
5370 GEN_SPE(evnor,          eveqv,         0x0C, 0x08, 0x00000000, PPC_SPE); ////
5371 GEN_SPE(speundef,       evorc,         0x0D, 0x08, 0x00000000, PPC_SPE); ////
5372 GEN_SPE(evnand,         speundef,      0x0F, 0x08, 0x00000000, PPC_SPE); ////
5373 GEN_SPE(evsrwu,         evsrws,        0x10, 0x08, 0x00000000, PPC_SPE); ////
5374 GEN_SPE(evsrwiu,        evsrwis,       0x11, 0x08, 0x00000000, PPC_SPE);
5375 GEN_SPE(evslw,          speundef,      0x12, 0x08, 0x00000000, PPC_SPE); ////
5376 GEN_SPE(evslwi,         speundef,      0x13, 0x08, 0x00000000, PPC_SPE);
5377 GEN_SPE(evrlw,          evsplati,      0x14, 0x08, 0x00000000, PPC_SPE); //
5378 GEN_SPE(evrlwi,         evsplatfi,     0x15, 0x08, 0x00000000, PPC_SPE);
5379 GEN_SPE(evmergehi,      evmergelo,     0x16, 0x08, 0x00000000, PPC_SPE); ////
5380 GEN_SPE(evmergehilo,    evmergelohi,   0x17, 0x08, 0x00000000, PPC_SPE); ////
5381 GEN_SPE(evcmpgtu,       evcmpgts,      0x18, 0x08, 0x00600000, PPC_SPE); ////
5382 GEN_SPE(evcmpltu,       evcmplts,      0x19, 0x08, 0x00600000, PPC_SPE); ////
5383 GEN_SPE(evcmpeq,        speundef,      0x1A, 0x08, 0x00600000, PPC_SPE); ////
5384
5385 static inline void gen_evsel (DisasContext *ctx)
5386 {
5387     if (unlikely(!ctx->spe_enabled)) {
5388         GEN_EXCP_NO_AP(ctx);
5389         return;
5390     }
5391     gen_op_load_crf_T0(ctx->opcode & 0x7);
5392     gen_op_load_gpr64_T0(rA(ctx->opcode));
5393     gen_op_load_gpr64_T1(rB(ctx->opcode));
5394     gen_op_evsel();
5395     gen_op_store_T0_gpr64(rD(ctx->opcode));
5396 }
5397
5398 GEN_HANDLER(evsel0, 0x04, 0x1c, 0x09, 0x00000000, PPC_SPE)
5399 {
5400     gen_evsel(ctx);
5401 }
5402 GEN_HANDLER(evsel1, 0x04, 0x1d, 0x09, 0x00000000, PPC_SPE)
5403 {
5404     gen_evsel(ctx);
5405 }
5406 GEN_HANDLER(evsel2, 0x04, 0x1e, 0x09, 0x00000000, PPC_SPE)
5407 {
5408     gen_evsel(ctx);
5409 }
5410 GEN_HANDLER(evsel3, 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE)
5411 {
5412     gen_evsel(ctx);
5413 }
5414
5415 /* Load and stores */
5416 #if defined(TARGET_PPC64)
5417 /* In that case, we already have 64 bits load & stores
5418  * so, spe_ldd is equivalent to ld and spe_std is equivalent to std
5419  */
5420 #if defined(CONFIG_USER_ONLY)
5421 #define gen_op_spe_ldd_raw gen_op_ld_raw
5422 #define gen_op_spe_ldd_64_raw gen_op_ld_64_raw
5423 #define gen_op_spe_ldd_le_raw gen_op_ld_le_raw
5424 #define gen_op_spe_ldd_le_64_raw gen_op_ld_le_64_raw
5425 #define gen_op_spe_stdd_raw gen_op_ld_raw
5426 #define gen_op_spe_stdd_64_raw gen_op_std_64_raw
5427 #define gen_op_spe_stdd_le_raw gen_op_std_le_raw
5428 #define gen_op_spe_stdd_le_64_raw gen_op_std_le_64_raw
5429 #else /* defined(CONFIG_USER_ONLY) */
5430 #define gen_op_spe_ldd_kernel gen_op_ld_kernel
5431 #define gen_op_spe_ldd_64_kernel gen_op_ld_64_kernel
5432 #define gen_op_spe_ldd_le_kernel gen_op_ld_kernel
5433 #define gen_op_spe_ldd_le_64_kernel gen_op_ld_64_kernel
5434 #define gen_op_spe_ldd_user gen_op_ld_user
5435 #define gen_op_spe_ldd_64_user gen_op_ld_64_user
5436 #define gen_op_spe_ldd_le_user gen_op_ld_le_user
5437 #define gen_op_spe_ldd_le_64_user gen_op_ld_le_64_user
5438 #define gen_op_spe_stdd_kernel gen_op_std_kernel
5439 #define gen_op_spe_stdd_64_kernel gen_op_std_64_kernel
5440 #define gen_op_spe_stdd_le_kernel gen_op_std_kernel
5441 #define gen_op_spe_stdd_le_64_kernel gen_op_std_64_kernel
5442 #define gen_op_spe_stdd_user gen_op_std_user
5443 #define gen_op_spe_stdd_64_user gen_op_std_64_user
5444 #define gen_op_spe_stdd_le_user gen_op_std_le_user
5445 #define gen_op_spe_stdd_le_64_user gen_op_std_le_64_user
5446 #endif /* defined(CONFIG_USER_ONLY) */
5447 #endif /* defined(TARGET_PPC64) */
5448 GEN_SPEOP_LDST(dd, 3);
5449 GEN_SPEOP_LDST(dw, 3);
5450 GEN_SPEOP_LDST(dh, 3);
5451 GEN_SPEOP_LDST(whe, 2);
5452 GEN_SPEOP_LD(whou, 2);
5453 GEN_SPEOP_LD(whos, 2);
5454 GEN_SPEOP_ST(who, 2);
5455
5456 #if defined(TARGET_PPC64)
5457 /* In that case, spe_stwwo is equivalent to stw */
5458 #if defined(CONFIG_USER_ONLY)
5459 #define gen_op_spe_stwwo_raw gen_op_stw_raw
5460 #define gen_op_spe_stwwo_le_raw gen_op_stw_le_raw
5461 #define gen_op_spe_stwwo_64_raw gen_op_stw_64_raw
5462 #define gen_op_spe_stwwo_le_64_raw gen_op_stw_le_64_raw
5463 #else
5464 #define gen_op_spe_stwwo_user gen_op_stw_user
5465 #define gen_op_spe_stwwo_le_user gen_op_stw_le_user
5466 #define gen_op_spe_stwwo_64_user gen_op_stw_64_user
5467 #define gen_op_spe_stwwo_le_64_user gen_op_stw_le_64_user
5468 #define gen_op_spe_stwwo_kernel gen_op_stw_kernel
5469 #define gen_op_spe_stwwo_le_kernel gen_op_stw_le_kernel
5470 #define gen_op_spe_stwwo_64_kernel gen_op_stw_64_kernel
5471 #define gen_op_spe_stwwo_le_64_kernel gen_op_stw_le_64_kernel
5472 #endif
5473 #endif
5474 #define _GEN_OP_SPE_STWWE(suffix)                                             \
5475 static inline void gen_op_spe_stwwe_##suffix (void)                           \
5476 {                                                                             \
5477     gen_op_srli32_T1_64();                                                    \
5478     gen_op_spe_stwwo_##suffix();                                              \
5479 }
5480 #define _GEN_OP_SPE_STWWE_LE(suffix)                                          \
5481 static inline void gen_op_spe_stwwe_le_##suffix (void)                        \
5482 {                                                                             \
5483     gen_op_srli32_T1_64();                                                    \
5484     gen_op_spe_stwwo_le_##suffix();                                           \
5485 }
5486 #if defined(TARGET_PPC64)
5487 #define GEN_OP_SPE_STWWE(suffix)                                              \
5488 _GEN_OP_SPE_STWWE(suffix);                                                    \
5489 _GEN_OP_SPE_STWWE_LE(suffix);                                                 \
5490 static inline void gen_op_spe_stwwe_64_##suffix (void)                        \
5491 {                                                                             \
5492     gen_op_srli32_T1_64();                                                    \
5493     gen_op_spe_stwwo_64_##suffix();                                           \
5494 }                                                                             \
5495 static inline void gen_op_spe_stwwe_le_64_##suffix (void)                     \
5496 {                                                                             \
5497     gen_op_srli32_T1_64();                                                    \
5498     gen_op_spe_stwwo_le_64_##suffix();                                        \
5499 }
5500 #else
5501 #define GEN_OP_SPE_STWWE(suffix)                                              \
5502 _GEN_OP_SPE_STWWE(suffix);                                                    \
5503 _GEN_OP_SPE_STWWE_LE(suffix)
5504 #endif
5505 #if defined(CONFIG_USER_ONLY)
5506 GEN_OP_SPE_STWWE(raw);
5507 #else /* defined(CONFIG_USER_ONLY) */
5508 GEN_OP_SPE_STWWE(kernel);
5509 GEN_OP_SPE_STWWE(user);
5510 #endif /* defined(CONFIG_USER_ONLY) */
5511 GEN_SPEOP_ST(wwe, 2);
5512 GEN_SPEOP_ST(wwo, 2);
5513
5514 #define GEN_SPE_LDSPLAT(name, op, suffix)                                     \
5515 static inline void gen_op_spe_l##name##_##suffix (void)                       \
5516 {                                                                             \
5517     gen_op_##op##_##suffix();                                                 \
5518     gen_op_splatw_T1_64();                                                    \
5519 }
5520
5521 #define GEN_OP_SPE_LHE(suffix)                                                \
5522 static inline void gen_op_spe_lhe_##suffix (void)                             \
5523 {                                                                             \
5524     gen_op_spe_lh_##suffix();                                                 \
5525     gen_op_sli16_T1_64();                                                     \
5526 }
5527
5528 #define GEN_OP_SPE_LHX(suffix)                                                \
5529 static inline void gen_op_spe_lhx_##suffix (void)                             \
5530 {                                                                             \
5531     gen_op_spe_lh_##suffix();                                                 \
5532     gen_op_extsh_T1_64();                                                     \
5533 }
5534
5535 #if defined(CONFIG_USER_ONLY)
5536 GEN_OP_SPE_LHE(raw);
5537 GEN_SPE_LDSPLAT(hhesplat, spe_lhe, raw);
5538 GEN_OP_SPE_LHE(le_raw);
5539 GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_raw);
5540 GEN_SPE_LDSPLAT(hhousplat, spe_lh, raw);
5541 GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_raw);
5542 GEN_OP_SPE_LHX(raw);
5543 GEN_SPE_LDSPLAT(hhossplat, spe_lhx, raw);
5544 GEN_OP_SPE_LHX(le_raw);
5545 GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_raw);
5546 #if defined(TARGET_PPC64)
5547 GEN_OP_SPE_LHE(64_raw);
5548 GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_raw);
5549 GEN_OP_SPE_LHE(le_64_raw);
5550 GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_raw);
5551 GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_raw);
5552 GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_raw);
5553 GEN_OP_SPE_LHX(64_raw);
5554 GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_raw);
5555 GEN_OP_SPE_LHX(le_64_raw);
5556 GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_raw);
5557 #endif
5558 #else
5559 GEN_OP_SPE_LHE(kernel);
5560 GEN_OP_SPE_LHE(user);
5561 GEN_SPE_LDSPLAT(hhesplat, spe_lhe, kernel);
5562 GEN_SPE_LDSPLAT(hhesplat, spe_lhe, user);
5563 GEN_OP_SPE_LHE(le_kernel);
5564 GEN_OP_SPE_LHE(le_user);
5565 GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_kernel);
5566 GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_user);
5567 GEN_SPE_LDSPLAT(hhousplat, spe_lh, kernel);
5568 GEN_SPE_LDSPLAT(hhousplat, spe_lh, user);
5569 GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_kernel);
5570 GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_user);
5571 GEN_OP_SPE_LHX(kernel);
5572 GEN_OP_SPE_LHX(user);
5573 GEN_SPE_LDSPLAT(hhossplat, spe_lhx, kernel);
5574 GEN_SPE_LDSPLAT(hhossplat, spe_lhx, user);
5575 GEN_OP_SPE_LHX(le_kernel);
5576 GEN_OP_SPE_LHX(le_user);
5577 GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_kernel);
5578 GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_user);
5579 #if defined(TARGET_PPC64)
5580 GEN_OP_SPE_LHE(64_kernel);
5581 GEN_OP_SPE_LHE(64_user);
5582 GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_kernel);
5583 GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_user);
5584 GEN_OP_SPE_LHE(le_64_kernel);
5585 GEN_OP_SPE_LHE(le_64_user);
5586 GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_kernel);
5587 GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_user);
5588 GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_kernel);
5589 GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_user);
5590 GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_kernel);
5591 GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_user);
5592 GEN_OP_SPE_LHX(64_kernel);
5593 GEN_OP_SPE_LHX(64_user);
5594 GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_kernel);
5595 GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_user);
5596 GEN_OP_SPE_LHX(le_64_kernel);
5597 GEN_OP_SPE_LHX(le_64_user);
5598 GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_kernel);
5599 GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_user);
5600 #endif
5601 #endif
5602 GEN_SPEOP_LD(hhesplat, 1);
5603 GEN_SPEOP_LD(hhousplat, 1);
5604 GEN_SPEOP_LD(hhossplat, 1);
5605 GEN_SPEOP_LD(wwsplat, 2);
5606 GEN_SPEOP_LD(whsplat, 2);
5607
5608 GEN_SPE(evlddx,         evldd,         0x00, 0x0C, 0x00000000, PPC_SPE); //
5609 GEN_SPE(evldwx,         evldw,         0x01, 0x0C, 0x00000000, PPC_SPE); //
5610 GEN_SPE(evldhx,         evldh,         0x02, 0x0C, 0x00000000, PPC_SPE); //
5611 GEN_SPE(evlhhesplatx,   evlhhesplat,   0x04, 0x0C, 0x00000000, PPC_SPE); //
5612 GEN_SPE(evlhhousplatx,  evlhhousplat,  0x06, 0x0C, 0x00000000, PPC_SPE); //
5613 GEN_SPE(evlhhossplatx,  evlhhossplat,  0x07, 0x0C, 0x00000000, PPC_SPE); //
5614 GEN_SPE(evlwhex,        evlwhe,        0x08, 0x0C, 0x00000000, PPC_SPE); //
5615 GEN_SPE(evlwhoux,       evlwhou,       0x0A, 0x0C, 0x00000000, PPC_SPE); //
5616 GEN_SPE(evlwhosx,       evlwhos,       0x0B, 0x0C, 0x00000000, PPC_SPE); //
5617 GEN_SPE(evlwwsplatx,    evlwwsplat,    0x0C, 0x0C, 0x00000000, PPC_SPE); //
5618 GEN_SPE(evlwhsplatx,    evlwhsplat,    0x0E, 0x0C, 0x00000000, PPC_SPE); //
5619 GEN_SPE(evstddx,        evstdd,        0x10, 0x0C, 0x00000000, PPC_SPE); //
5620 GEN_SPE(evstdwx,        evstdw,        0x11, 0x0C, 0x00000000, PPC_SPE); //
5621 GEN_SPE(evstdhx,        evstdh,        0x12, 0x0C, 0x00000000, PPC_SPE); //
5622 GEN_SPE(evstwhex,       evstwhe,       0x18, 0x0C, 0x00000000, PPC_SPE); //
5623 GEN_SPE(evstwhox,       evstwho,       0x1A, 0x0C, 0x00000000, PPC_SPE); //
5624 GEN_SPE(evstwwex,       evstwwe,       0x1C, 0x0C, 0x00000000, PPC_SPE); //
5625 GEN_SPE(evstwwox,       evstwwo,       0x1E, 0x0C, 0x00000000, PPC_SPE); //
5626
5627 /* Multiply and add - TODO */
5628 #if 0
5629 GEN_SPE(speundef,       evmhessf,      0x01, 0x10, 0x00000000, PPC_SPE);
5630 GEN_SPE(speundef,       evmhossf,      0x03, 0x10, 0x00000000, PPC_SPE);
5631 GEN_SPE(evmheumi,       evmhesmi,      0x04, 0x10, 0x00000000, PPC_SPE);
5632 GEN_SPE(speundef,       evmhesmf,      0x05, 0x10, 0x00000000, PPC_SPE);
5633 GEN_SPE(evmhoumi,       evmhosmi,      0x06, 0x10, 0x00000000, PPC_SPE);
5634 GEN_SPE(speundef,       evmhosmf,      0x07, 0x10, 0x00000000, PPC_SPE);
5635 GEN_SPE(speundef,       evmhessfa,     0x11, 0x10, 0x00000000, PPC_SPE);
5636 GEN_SPE(speundef,       evmhossfa,     0x13, 0x10, 0x00000000, PPC_SPE);
5637 GEN_SPE(evmheumia,      evmhesmia,     0x14, 0x10, 0x00000000, PPC_SPE);
5638 GEN_SPE(speundef,       evmhesmfa,     0x15, 0x10, 0x00000000, PPC_SPE);
5639 GEN_SPE(evmhoumia,      evmhosmia,     0x16, 0x10, 0x00000000, PPC_SPE);
5640 GEN_SPE(speundef,       evmhosmfa,     0x17, 0x10, 0x00000000, PPC_SPE);
5641
5642 GEN_SPE(speundef,       evmwhssf,      0x03, 0x11, 0x00000000, PPC_SPE);
5643 GEN_SPE(evmwlumi,       speundef,      0x04, 0x11, 0x00000000, PPC_SPE);
5644 GEN_SPE(evmwhumi,       evmwhsmi,      0x06, 0x11, 0x00000000, PPC_SPE);
5645 GEN_SPE(speundef,       evmwhsmf,      0x07, 0x11, 0x00000000, PPC_SPE);
5646 GEN_SPE(speundef,       evmwssf,       0x09, 0x11, 0x00000000, PPC_SPE);
5647 GEN_SPE(evmwumi,        evmwsmi,       0x0C, 0x11, 0x00000000, PPC_SPE);
5648 GEN_SPE(speundef,       evmwsmf,       0x0D, 0x11, 0x00000000, PPC_SPE);
5649 GEN_SPE(speundef,       evmwhssfa,     0x13, 0x11, 0x00000000, PPC_SPE);
5650 GEN_SPE(evmwlumia,      speundef,      0x14, 0x11, 0x00000000, PPC_SPE);
5651 GEN_SPE(evmwhumia,      evmwhsmia,     0x16, 0x11, 0x00000000, PPC_SPE);
5652 GEN_SPE(speundef,       evmwhsmfa,     0x17, 0x11, 0x00000000, PPC_SPE);
5653 GEN_SPE(speundef,       evmwssfa,      0x19, 0x11, 0x00000000, PPC_SPE);
5654 GEN_SPE(evmwumia,       evmwsmia,      0x1C, 0x11, 0x00000000, PPC_SPE);
5655 GEN_SPE(speundef,       evmwsmfa,      0x1D, 0x11, 0x00000000, PPC_SPE);
5656
5657 GEN_SPE(evadduiaaw,     evaddsiaaw,    0x00, 0x13, 0x0000F800, PPC_SPE);
5658 GEN_SPE(evsubfusiaaw,   evsubfssiaaw,  0x01, 0x13, 0x0000F800, PPC_SPE);
5659 GEN_SPE(evaddumiaaw,    evaddsmiaaw,   0x04, 0x13, 0x0000F800, PPC_SPE);
5660 GEN_SPE(evsubfumiaaw,   evsubfsmiaaw,  0x05, 0x13, 0x0000F800, PPC_SPE);
5661 GEN_SPE(evdivws,        evdivwu,       0x06, 0x13, 0x00000000, PPC_SPE);
5662 GEN_SPE(evmra,          speundef,      0x07, 0x13, 0x0000F800, PPC_SPE);
5663
5664 GEN_SPE(evmheusiaaw,    evmhessiaaw,   0x00, 0x14, 0x00000000, PPC_SPE);
5665 GEN_SPE(speundef,       evmhessfaaw,   0x01, 0x14, 0x00000000, PPC_SPE);
5666 GEN_SPE(evmhousiaaw,    evmhossiaaw,   0x02, 0x14, 0x00000000, PPC_SPE);
5667 GEN_SPE(speundef,       evmhossfaaw,   0x03, 0x14, 0x00000000, PPC_SPE);
5668 GEN_SPE(evmheumiaaw,    evmhesmiaaw,   0x04, 0x14, 0x00000000, PPC_SPE);
5669 GEN_SPE(speundef,       evmhesmfaaw,   0x05, 0x14, 0x00000000, PPC_SPE);
5670 GEN_SPE(evmhoumiaaw,    evmhosmiaaw,   0x06, 0x14, 0x00000000, PPC_SPE);
5671 GEN_SPE(speundef,       evmhosmfaaw,   0x07, 0x14, 0x00000000, PPC_SPE);
5672 GEN_SPE(evmhegumiaa,    evmhegsmiaa,   0x14, 0x14, 0x00000000, PPC_SPE);
5673 GEN_SPE(speundef,       evmhegsmfaa,   0x15, 0x14, 0x00000000, PPC_SPE);
5674 GEN_SPE(evmhogumiaa,    evmhogsmiaa,   0x16, 0x14, 0x00000000, PPC_SPE);
5675 GEN_SPE(speundef,       evmhogsmfaa,   0x17, 0x14, 0x00000000, PPC_SPE);
5676
5677 GEN_SPE(evmwlusiaaw,    evmwlssiaaw,   0x00, 0x15, 0x00000000, PPC_SPE);
5678 GEN_SPE(evmwlumiaaw,    evmwlsmiaaw,   0x04, 0x15, 0x00000000, PPC_SPE);
5679 GEN_SPE(speundef,       evmwssfaa,     0x09, 0x15, 0x00000000, PPC_SPE);
5680 GEN_SPE(evmwumiaa,      evmwsmiaa,     0x0C, 0x15, 0x00000000, PPC_SPE);
5681 GEN_SPE(speundef,       evmwsmfaa,     0x0D, 0x15, 0x00000000, PPC_SPE);
5682
5683 GEN_SPE(evmheusianw,    evmhessianw,   0x00, 0x16, 0x00000000, PPC_SPE);
5684 GEN_SPE(speundef,       evmhessfanw,   0x01, 0x16, 0x00000000, PPC_SPE);
5685 GEN_SPE(evmhousianw,    evmhossianw,   0x02, 0x16, 0x00000000, PPC_SPE);
5686 GEN_SPE(speundef,       evmhossfanw,   0x03, 0x16, 0x00000000, PPC_SPE);
5687 GEN_SPE(evmheumianw,    evmhesmianw,   0x04, 0x16, 0x00000000, PPC_SPE);
5688 GEN_SPE(speundef,       evmhesmfanw,   0x05, 0x16, 0x00000000, PPC_SPE);
5689 GEN_SPE(evmhoumianw,    evmhosmianw,   0x06, 0x16, 0x00000000, PPC_SPE);
5690 GEN_SPE(speundef,       evmhosmfanw,   0x07, 0x16, 0x00000000, PPC_SPE);
5691 GEN_SPE(evmhegumian,    evmhegsmian,   0x14, 0x16, 0x00000000, PPC_SPE);
5692 GEN_SPE(speundef,       evmhegsmfan,   0x15, 0x16, 0x00000000, PPC_SPE);
5693 GEN_SPE(evmhigumian,    evmhigsmian,   0x16, 0x16, 0x00000000, PPC_SPE);
5694 GEN_SPE(speundef,       evmhogsmfan,   0x17, 0x16, 0x00000000, PPC_SPE);
5695
5696 GEN_SPE(evmwlusianw,    evmwlssianw,   0x00, 0x17, 0x00000000, PPC_SPE);
5697 GEN_SPE(evmwlumianw,    evmwlsmianw,   0x04, 0x17, 0x00000000, PPC_SPE);
5698 GEN_SPE(speundef,       evmwssfan,     0x09, 0x17, 0x00000000, PPC_SPE);
5699 GEN_SPE(evmwumian,      evmwsmian,     0x0C, 0x17, 0x00000000, PPC_SPE);
5700 GEN_SPE(speundef,       evmwsmfan,     0x0D, 0x17, 0x00000000, PPC_SPE);
5701 #endif
5702
5703 /***                      SPE floating-point extension                     ***/
5704 #define GEN_SPEFPUOP_CONV(name)                                               \
5705 static inline void gen_##name (DisasContext *ctx)                             \
5706 {                                                                             \
5707     gen_op_load_gpr64_T0(rB(ctx->opcode));                                    \
5708     gen_op_##name();                                                          \
5709     gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5710 }
5711
5712 /* Single precision floating-point vectors operations */
5713 /* Arithmetic */
5714 GEN_SPEOP_ARITH2(evfsadd);
5715 GEN_SPEOP_ARITH2(evfssub);
5716 GEN_SPEOP_ARITH2(evfsmul);
5717 GEN_SPEOP_ARITH2(evfsdiv);
5718 GEN_SPEOP_ARITH1(evfsabs);
5719 GEN_SPEOP_ARITH1(evfsnabs);
5720 GEN_SPEOP_ARITH1(evfsneg);
5721 /* Conversion */
5722 GEN_SPEFPUOP_CONV(evfscfui);
5723 GEN_SPEFPUOP_CONV(evfscfsi);
5724 GEN_SPEFPUOP_CONV(evfscfuf);
5725 GEN_SPEFPUOP_CONV(evfscfsf);
5726 GEN_SPEFPUOP_CONV(evfsctui);
5727 GEN_SPEFPUOP_CONV(evfsctsi);
5728 GEN_SPEFPUOP_CONV(evfsctuf);
5729 GEN_SPEFPUOP_CONV(evfsctsf);
5730 GEN_SPEFPUOP_CONV(evfsctuiz);
5731 GEN_SPEFPUOP_CONV(evfsctsiz);
5732 /* Comparison */
5733 GEN_SPEOP_COMP(evfscmpgt);
5734 GEN_SPEOP_COMP(evfscmplt);
5735 GEN_SPEOP_COMP(evfscmpeq);
5736 GEN_SPEOP_COMP(evfststgt);
5737 GEN_SPEOP_COMP(evfststlt);
5738 GEN_SPEOP_COMP(evfststeq);
5739
5740 /* Opcodes definitions */
5741 GEN_SPE(evfsadd,        evfssub,       0x00, 0x0A, 0x00000000, PPC_SPEFPU); //
5742 GEN_SPE(evfsabs,        evfsnabs,      0x02, 0x0A, 0x0000F800, PPC_SPEFPU); //
5743 GEN_SPE(evfsneg,        speundef,      0x03, 0x0A, 0x0000F800, PPC_SPEFPU); //
5744 GEN_SPE(evfsmul,        evfsdiv,       0x04, 0x0A, 0x00000000, PPC_SPEFPU); //
5745 GEN_SPE(evfscmpgt,      evfscmplt,     0x06, 0x0A, 0x00600000, PPC_SPEFPU); //
5746 GEN_SPE(evfscmpeq,      speundef,      0x07, 0x0A, 0x00600000, PPC_SPEFPU); //
5747 GEN_SPE(evfscfui,       evfscfsi,      0x08, 0x0A, 0x00180000, PPC_SPEFPU); //
5748 GEN_SPE(evfscfuf,       evfscfsf,      0x09, 0x0A, 0x00180000, PPC_SPEFPU); //
5749 GEN_SPE(evfsctui,       evfsctsi,      0x0A, 0x0A, 0x00180000, PPC_SPEFPU); //
5750 GEN_SPE(evfsctuf,       evfsctsf,      0x0B, 0x0A, 0x00180000, PPC_SPEFPU); //
5751 GEN_SPE(evfsctuiz,      speundef,      0x0C, 0x0A, 0x00180000, PPC_SPEFPU); //
5752 GEN_SPE(evfsctsiz,      speundef,      0x0D, 0x0A, 0x00180000, PPC_SPEFPU); //
5753 GEN_SPE(evfststgt,      evfststlt,     0x0E, 0x0A, 0x00600000, PPC_SPEFPU); //
5754 GEN_SPE(evfststeq,      speundef,      0x0F, 0x0A, 0x00600000, PPC_SPEFPU); //
5755
5756 /* Single precision floating-point operations */
5757 /* Arithmetic */
5758 GEN_SPEOP_ARITH2(efsadd);
5759 GEN_SPEOP_ARITH2(efssub);
5760 GEN_SPEOP_ARITH2(efsmul);
5761 GEN_SPEOP_ARITH2(efsdiv);
5762 GEN_SPEOP_ARITH1(efsabs);
5763 GEN_SPEOP_ARITH1(efsnabs);
5764 GEN_SPEOP_ARITH1(efsneg);
5765 /* Conversion */
5766 GEN_SPEFPUOP_CONV(efscfui);
5767 GEN_SPEFPUOP_CONV(efscfsi);
5768 GEN_SPEFPUOP_CONV(efscfuf);
5769 GEN_SPEFPUOP_CONV(efscfsf);
5770 GEN_SPEFPUOP_CONV(efsctui);
5771 GEN_SPEFPUOP_CONV(efsctsi);
5772 GEN_SPEFPUOP_CONV(efsctuf);
5773 GEN_SPEFPUOP_CONV(efsctsf);
5774 GEN_SPEFPUOP_CONV(efsctuiz);
5775 GEN_SPEFPUOP_CONV(efsctsiz);
5776 GEN_SPEFPUOP_CONV(efscfd);
5777 /* Comparison */
5778 GEN_SPEOP_COMP(efscmpgt);
5779 GEN_SPEOP_COMP(efscmplt);
5780 GEN_SPEOP_COMP(efscmpeq);
5781 GEN_SPEOP_COMP(efststgt);
5782 GEN_SPEOP_COMP(efststlt);
5783 GEN_SPEOP_COMP(efststeq);
5784
5785 /* Opcodes definitions */
5786 GEN_SPE(efsadd,         efssub,        0x00, 0x0A, 0x00000000, PPC_SPEFPU); //
5787 GEN_SPE(efsabs,         efsnabs,       0x02, 0x0B, 0x0000F800, PPC_SPEFPU); //
5788 GEN_SPE(efsneg,         speundef,      0x03, 0x0B, 0x0000F800, PPC_SPEFPU); //
5789 GEN_SPE(efsmul,         efsdiv,        0x04, 0x0B, 0x00000000, PPC_SPEFPU); //
5790 GEN_SPE(efscmpgt,       efscmplt,      0x06, 0x0B, 0x00600000, PPC_SPEFPU); //
5791 GEN_SPE(efscmpeq,       efscfd,        0x07, 0x0B, 0x00600000, PPC_SPEFPU); //
5792 GEN_SPE(efscfui,        efscfsi,       0x08, 0x0B, 0x00180000, PPC_SPEFPU); //
5793 GEN_SPE(efscfuf,        efscfsf,       0x09, 0x0B, 0x00180000, PPC_SPEFPU); //
5794 GEN_SPE(efsctui,        efsctsi,       0x0A, 0x0B, 0x00180000, PPC_SPEFPU); //
5795 GEN_SPE(efsctuf,        efsctsf,       0x0B, 0x0B, 0x00180000, PPC_SPEFPU); //
5796 GEN_SPE(efsctuiz,       efsctsiz,      0x0C, 0x0B, 0x00180000, PPC_SPEFPU); //
5797 GEN_SPE(efststgt,       efststlt,      0x0E, 0x0B, 0x00600000, PPC_SPEFPU); //
5798 GEN_SPE(efststeq,       speundef,      0x0F, 0x0B, 0x00600000, PPC_SPEFPU); //
5799
5800 /* Double precision floating-point operations */
5801 /* Arithmetic */
5802 GEN_SPEOP_ARITH2(efdadd);
5803 GEN_SPEOP_ARITH2(efdsub);
5804 GEN_SPEOP_ARITH2(efdmul);
5805 GEN_SPEOP_ARITH2(efddiv);
5806 GEN_SPEOP_ARITH1(efdabs);
5807 GEN_SPEOP_ARITH1(efdnabs);
5808 GEN_SPEOP_ARITH1(efdneg);
5809 /* Conversion */
5810
5811 GEN_SPEFPUOP_CONV(efdcfui);
5812 GEN_SPEFPUOP_CONV(efdcfsi);
5813 GEN_SPEFPUOP_CONV(efdcfuf);
5814 GEN_SPEFPUOP_CONV(efdcfsf);
5815 GEN_SPEFPUOP_CONV(efdctui);
5816 GEN_SPEFPUOP_CONV(efdctsi);
5817 GEN_SPEFPUOP_CONV(efdctuf);
5818 GEN_SPEFPUOP_CONV(efdctsf);
5819 GEN_SPEFPUOP_CONV(efdctuiz);
5820 GEN_SPEFPUOP_CONV(efdctsiz);
5821 GEN_SPEFPUOP_CONV(efdcfs);
5822 GEN_SPEFPUOP_CONV(efdcfuid);
5823 GEN_SPEFPUOP_CONV(efdcfsid);
5824 GEN_SPEFPUOP_CONV(efdctuidz);
5825 GEN_SPEFPUOP_CONV(efdctsidz);
5826 /* Comparison */
5827 GEN_SPEOP_COMP(efdcmpgt);
5828 GEN_SPEOP_COMP(efdcmplt);
5829 GEN_SPEOP_COMP(efdcmpeq);
5830 GEN_SPEOP_COMP(efdtstgt);
5831 GEN_SPEOP_COMP(efdtstlt);
5832 GEN_SPEOP_COMP(efdtsteq);
5833
5834 /* Opcodes definitions */
5835 GEN_SPE(efdadd,         efdsub,        0x10, 0x0B, 0x00000000, PPC_SPEFPU); //
5836 GEN_SPE(efdcfuid,       efdcfsid,      0x11, 0x0B, 0x00180000, PPC_SPEFPU); //
5837 GEN_SPE(efdabs,         efdnabs,       0x12, 0x0B, 0x0000F800, PPC_SPEFPU); //
5838 GEN_SPE(efdneg,         speundef,      0x13, 0x0B, 0x0000F800, PPC_SPEFPU); //
5839 GEN_SPE(efdmul,         efddiv,        0x14, 0x0B, 0x00000000, PPC_SPEFPU); //
5840 GEN_SPE(efdctuidz,      efdctsidz,     0x15, 0x0B, 0x00180000, PPC_SPEFPU); //
5841 GEN_SPE(efdcmpgt,       efdcmplt,      0x16, 0x0B, 0x00600000, PPC_SPEFPU); //
5842 GEN_SPE(efdcmpeq,       efdcfs,        0x17, 0x0B, 0x00600000, PPC_SPEFPU); //
5843 GEN_SPE(efdcfui,        efdcfsi,       0x18, 0x0B, 0x00180000, PPC_SPEFPU); //
5844 GEN_SPE(efdcfuf,        efdcfsf,       0x19, 0x0B, 0x00180000, PPC_SPEFPU); //
5845 GEN_SPE(efdctui,        efdctsi,       0x1A, 0x0B, 0x00180000, PPC_SPEFPU); //
5846 GEN_SPE(efdctuf,        efdctsf,       0x1B, 0x0B, 0x00180000, PPC_SPEFPU); //
5847 GEN_SPE(efdctuiz,       speundef,      0x1C, 0x0B, 0x00180000, PPC_SPEFPU); //
5848 GEN_SPE(efdctsiz,       speundef,      0x1D, 0x0B, 0x00180000, PPC_SPEFPU); //
5849 GEN_SPE(efdtstgt,       efdtstlt,      0x1E, 0x0B, 0x00600000, PPC_SPEFPU); //
5850 GEN_SPE(efdtsteq,       speundef,      0x1F, 0x0B, 0x00600000, PPC_SPEFPU); //
5851 #endif
5852
5853 /* End opcode list */
5854 GEN_OPCODE_MARK(end);
5855
5856 #include "translate_init.c"
5857
5858 /*****************************************************************************/
5859 /* Misc PowerPC helpers */
5860 static inline uint32_t load_xer (CPUState *env)
5861 {
5862     return (xer_so << XER_SO) |
5863         (xer_ov << XER_OV) |
5864         (xer_ca << XER_CA) |
5865         (xer_bc << XER_BC) |
5866         (xer_cmp << XER_CMP);
5867 }
5868
5869 void cpu_dump_state (CPUState *env, FILE *f,
5870                      int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
5871                      int flags)
5872 {
5873 #if defined(TARGET_PPC64) || 1
5874 #define FILL ""
5875 #define RGPL  4
5876 #define RFPL  4
5877 #else
5878 #define FILL "        "
5879 #define RGPL  8
5880 #define RFPL  4
5881 #endif
5882
5883     int i;
5884
5885     cpu_fprintf(f, "NIP " ADDRX " LR " ADDRX " CTR " ADDRX "\n",
5886                 env->nip, env->lr, env->ctr);
5887     cpu_fprintf(f, "MSR " REGX FILL " XER %08x      "
5888 #if !defined(NO_TIMER_DUMP)
5889                 "TB %08x %08x "
5890 #if !defined(CONFIG_USER_ONLY)
5891                 "DECR %08x"
5892 #endif
5893 #endif
5894                 "\n",
5895                 do_load_msr(env), load_xer(env)
5896 #if !defined(NO_TIMER_DUMP)
5897                 , cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
5898 #if !defined(CONFIG_USER_ONLY)
5899                 , cpu_ppc_load_decr(env)
5900 #endif
5901 #endif
5902                 );
5903     for (i = 0; i < 32; i++) {
5904         if ((i & (RGPL - 1)) == 0)
5905             cpu_fprintf(f, "GPR%02d", i);
5906         cpu_fprintf(f, " " REGX, (target_ulong)env->gpr[i]);
5907         if ((i & (RGPL - 1)) == (RGPL - 1))
5908             cpu_fprintf(f, "\n");
5909     }
5910     cpu_fprintf(f, "CR ");
5911     for (i = 0; i < 8; i++)
5912         cpu_fprintf(f, "%01x", env->crf[i]);
5913     cpu_fprintf(f, "  [");
5914     for (i = 0; i < 8; i++) {
5915         char a = '-';
5916         if (env->crf[i] & 0x08)
5917             a = 'L';
5918         else if (env->crf[i] & 0x04)
5919             a = 'G';
5920         else if (env->crf[i] & 0x02)
5921             a = 'E';
5922         cpu_fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
5923     }
5924     cpu_fprintf(f, " ]             " FILL "RES " REGX "\n", env->reserve);
5925     for (i = 0; i < 32; i++) {
5926         if ((i & (RFPL - 1)) == 0)
5927             cpu_fprintf(f, "FPR%02d", i);
5928         cpu_fprintf(f, " %016" PRIx64, *((uint64_t *)&env->fpr[i]));
5929         if ((i & (RFPL - 1)) == (RFPL - 1))
5930             cpu_fprintf(f, "\n");
5931     }
5932     cpu_fprintf(f, "SRR0 " REGX " SRR1 " REGX "         " FILL FILL FILL
5933                 "SDR1 " REGX "\n",
5934                 env->spr[SPR_SRR0], env->spr[SPR_SRR1], env->sdr1);
5935
5936 #undef RGPL
5937 #undef RFPL
5938 #undef FILL
5939 }
5940
5941 void cpu_dump_statistics (CPUState *env, FILE*f,
5942                           int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
5943                           int flags)
5944 {
5945 #if defined(DO_PPC_STATISTICS)
5946     opc_handler_t **t1, **t2, **t3, *handler;
5947     int op1, op2, op3;
5948
5949     t1 = env->opcodes;
5950     for (op1 = 0; op1 < 64; op1++) {
5951         handler = t1[op1];
5952         if (is_indirect_opcode(handler)) {
5953             t2 = ind_table(handler);
5954             for (op2 = 0; op2 < 32; op2++) {
5955                 handler = t2[op2];
5956                 if (is_indirect_opcode(handler)) {
5957                     t3 = ind_table(handler);
5958                     for (op3 = 0; op3 < 32; op3++) {
5959                         handler = t3[op3];
5960                         if (handler->count == 0)
5961                             continue;
5962                         cpu_fprintf(f, "%02x %02x %02x (%02x %04d) %16s: "
5963                                     "%016llx %lld\n",
5964                                     op1, op2, op3, op1, (op3 << 5) | op2,
5965                                     handler->oname,
5966                                     handler->count, handler->count);
5967                     }
5968                 } else {
5969                     if (handler->count == 0)
5970                         continue;
5971                     cpu_fprintf(f, "%02x %02x    (%02x %04d) %16s: "
5972                                 "%016llx %lld\n",
5973                                 op1, op2, op1, op2, handler->oname,
5974                                 handler->count, handler->count);
5975                 }
5976             }
5977         } else {
5978             if (handler->count == 0)
5979                 continue;
5980             cpu_fprintf(f, "%02x       (%02x     ) %16s: %016llx %lld\n",
5981                         op1, op1, handler->oname,
5982                         handler->count, handler->count);
5983         }
5984     }
5985 #endif
5986 }
5987
5988 /*****************************************************************************/
5989 static inline int gen_intermediate_code_internal (CPUState *env,
5990                                                   TranslationBlock *tb,
5991                                                   int search_pc)
5992 {
5993     DisasContext ctx, *ctxp = &ctx;
5994     opc_handler_t **table, *handler;
5995     target_ulong pc_start;
5996     uint16_t *gen_opc_end;
5997     int j, lj = -1;
5998
5999     pc_start = tb->pc;
6000     gen_opc_ptr = gen_opc_buf;
6001     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
6002     gen_opparam_ptr = gen_opparam_buf;
6003     nb_gen_labels = 0;
6004     ctx.nip = pc_start;
6005     ctx.tb = tb;
6006     ctx.exception = POWERPC_EXCP_NONE;
6007     ctx.spr_cb = env->spr_cb;
6008 #if defined(CONFIG_USER_ONLY)
6009     ctx.mem_idx = msr_le;
6010 #if defined(TARGET_PPC64)
6011     ctx.mem_idx |= msr_sf << 1;
6012 #endif
6013 #else
6014     ctx.supervisor = 1 - msr_pr;
6015     ctx.mem_idx = ((1 - msr_pr) << 1) | msr_le;
6016 #if defined(TARGET_PPC64)
6017     ctx.mem_idx |= msr_sf << 2;
6018 #endif
6019 #endif
6020 #if defined(TARGET_PPC64)
6021     ctx.sf_mode = msr_sf;
6022 #endif
6023     ctx.fpu_enabled = msr_fp;
6024 #if defined(TARGET_PPCEMB)
6025     ctx.spe_enabled = msr_spe;
6026 #endif
6027     ctx.singlestep_enabled = env->singlestep_enabled;
6028 #if defined (DO_SINGLE_STEP) && 0
6029     /* Single step trace mode */
6030     msr_se = 1;
6031 #endif
6032     /* Set env in case of segfault during code fetch */
6033     while (ctx.exception == POWERPC_EXCP_NONE && gen_opc_ptr < gen_opc_end) {
6034         if (unlikely(env->nb_breakpoints > 0)) {
6035             for (j = 0; j < env->nb_breakpoints; j++) {
6036                 if (env->breakpoints[j] == ctx.nip) {
6037                     gen_update_nip(&ctx, ctx.nip);
6038                     gen_op_debug();
6039                     break;
6040                 }
6041             }
6042         }
6043         if (unlikely(search_pc)) {
6044             j = gen_opc_ptr - gen_opc_buf;
6045             if (lj < j) {
6046                 lj++;
6047                 while (lj < j)
6048                     gen_opc_instr_start[lj++] = 0;
6049                 gen_opc_pc[lj] = ctx.nip;
6050                 gen_opc_instr_start[lj] = 1;
6051             }
6052         }
6053 #if defined PPC_DEBUG_DISAS
6054         if (loglevel & CPU_LOG_TB_IN_ASM) {
6055             fprintf(logfile, "----------------\n");
6056             fprintf(logfile, "nip=" ADDRX " super=%d ir=%d\n",
6057                     ctx.nip, 1 - msr_pr, msr_ir);
6058         }
6059 #endif
6060         ctx.opcode = ldl_code(ctx.nip);
6061         if (msr_le) {
6062             ctx.opcode = ((ctx.opcode & 0xFF000000) >> 24) |
6063                 ((ctx.opcode & 0x00FF0000) >> 8) |
6064                 ((ctx.opcode & 0x0000FF00) << 8) |
6065                 ((ctx.opcode & 0x000000FF) << 24);
6066         }
6067 #if defined PPC_DEBUG_DISAS
6068         if (loglevel & CPU_LOG_TB_IN_ASM) {
6069             fprintf(logfile, "translate opcode %08x (%02x %02x %02x) (%s)\n",
6070                     ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
6071                     opc3(ctx.opcode), msr_le ? "little" : "big");
6072         }
6073 #endif
6074         ctx.nip += 4;
6075         table = env->opcodes;
6076         handler = table[opc1(ctx.opcode)];
6077         if (is_indirect_opcode(handler)) {
6078             table = ind_table(handler);
6079             handler = table[opc2(ctx.opcode)];
6080             if (is_indirect_opcode(handler)) {
6081                 table = ind_table(handler);
6082                 handler = table[opc3(ctx.opcode)];
6083             }
6084         }
6085         /* Is opcode *REALLY* valid ? */
6086         if (unlikely(handler->handler == &gen_invalid)) {
6087             if (loglevel != 0) {
6088                 fprintf(logfile, "invalid/unsupported opcode: "
6089                         "%02x - %02x - %02x (%08x) 0x" ADDRX " %d\n",
6090                         opc1(ctx.opcode), opc2(ctx.opcode),
6091                         opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, msr_ir);
6092             } else {
6093                 printf("invalid/unsupported opcode: "
6094                        "%02x - %02x - %02x (%08x) 0x" ADDRX " %d\n",
6095                        opc1(ctx.opcode), opc2(ctx.opcode),
6096                        opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, msr_ir);
6097             }
6098         } else {
6099             if (unlikely((ctx.opcode & handler->inval) != 0)) {
6100                 if (loglevel != 0) {
6101                     fprintf(logfile, "invalid bits: %08x for opcode: "
6102                             "%02x - %02x - %02x (%08x) 0x" ADDRX "\n",
6103                             ctx.opcode & handler->inval, opc1(ctx.opcode),
6104                             opc2(ctx.opcode), opc3(ctx.opcode),
6105                             ctx.opcode, ctx.nip - 4);
6106                 } else {
6107                     printf("invalid bits: %08x for opcode: "
6108                            "%02x - %02x - %02x (%08x) 0x" ADDRX "\n",
6109                            ctx.opcode & handler->inval, opc1(ctx.opcode),
6110                            opc2(ctx.opcode), opc3(ctx.opcode),
6111                            ctx.opcode, ctx.nip - 4);
6112                 }
6113                 GEN_EXCP_INVAL(ctxp);
6114                 break;
6115             }
6116         }
6117         (*(handler->handler))(&ctx);
6118 #if defined(DO_PPC_STATISTICS)
6119         handler->count++;
6120 #endif
6121         /* Check trace mode exceptions */
6122 #if 0 // XXX: buggy on embedded PowerPC
6123         if (unlikely((msr_be && ctx.exception == POWERPC_EXCP_BRANCH) ||
6124                      /* Check in single step trace mode
6125                       * we need to stop except if:
6126                       * - rfi, trap or syscall
6127                       * - first instruction of an exception handler
6128                       */
6129                      (msr_se && (ctx.nip < 0x100 ||
6130                                  ctx.nip > 0xF00 ||
6131                                  (ctx.nip & 0xFC) != 0x04) &&
6132 #if defined(CONFIG_USER_ONLY)
6133                       ctx.exception != POWERPC_EXCP_SYSCALL_USER &&
6134 #else
6135                       ctx.exception != POWERPC_EXCP_SYSCALL &&
6136 #endif
6137                       ctx.exception != POWERPC_EXCP_TRAP))) {
6138             GEN_EXCP(ctxp, POWERPC_EXCP_TRACE, 0);
6139         }
6140 #endif
6141         /* if we reach a page boundary or are single stepping, stop
6142          * generation
6143          */
6144         if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
6145                      (env->singlestep_enabled))) {
6146             break;
6147         }
6148 #if defined (DO_SINGLE_STEP)
6149         break;
6150 #endif
6151     }
6152     if (ctx.exception == POWERPC_EXCP_NONE) {
6153         gen_goto_tb(&ctx, 0, ctx.nip);
6154     } else if (ctx.exception != POWERPC_EXCP_BRANCH) {
6155         gen_op_reset_T0();
6156         /* Generate the return instruction */
6157         gen_op_exit_tb();
6158     }
6159     *gen_opc_ptr = INDEX_op_end;
6160     if (unlikely(search_pc)) {
6161         j = gen_opc_ptr - gen_opc_buf;
6162         lj++;
6163         while (lj <= j)
6164             gen_opc_instr_start[lj++] = 0;
6165     } else {
6166         tb->size = ctx.nip - pc_start;
6167     }
6168 #if defined(DEBUG_DISAS)
6169     if (loglevel & CPU_LOG_TB_CPU) {
6170         fprintf(logfile, "---------------- excp: %04x\n", ctx.exception);
6171         cpu_dump_state(env, logfile, fprintf, 0);
6172     }
6173     if (loglevel & CPU_LOG_TB_IN_ASM) {
6174         int flags;
6175         flags = env->bfd_mach;
6176         flags |= msr_le << 16;
6177         fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
6178         target_disas(logfile, pc_start, ctx.nip - pc_start, flags);
6179         fprintf(logfile, "\n");
6180     }
6181     if (loglevel & CPU_LOG_TB_OP) {
6182         fprintf(logfile, "OP:\n");
6183         dump_ops(gen_opc_buf, gen_opparam_buf);
6184         fprintf(logfile, "\n");
6185     }
6186 #endif
6187     return 0;
6188 }
6189
6190 int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
6191 {
6192     return gen_intermediate_code_internal(env, tb, 0);
6193 }
6194
6195 int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
6196 {
6197     return gen_intermediate_code_internal(env, tb, 1);
6198 }
This page took 0.381823 seconds and 4 git commands to generate.