]> Git Repo - qemu.git/blob - target-ppc/translate.c
Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging
[qemu.git] / target-ppc / translate.c
1 /*
2  *  PowerPC emulation for qemu: main translation routines.
3  *
4  *  Copyright (c) 2003-2007 Jocelyn Mayer
5  *  Copyright (C) 2011 Freescale Semiconductor, Inc.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include "qemu/osdep.h"
22 #include "cpu.h"
23 #include "disas/disas.h"
24 #include "tcg-op.h"
25 #include "qemu/host-utils.h"
26 #include "exec/cpu_ldst.h"
27
28 #include "exec/helper-proto.h"
29 #include "exec/helper-gen.h"
30
31 #include "trace-tcg.h"
32 #include "exec/log.h"
33
34
35 #define CPU_SINGLE_STEP 0x1
36 #define CPU_BRANCH_STEP 0x2
37 #define GDBSTUB_SINGLE_STEP 0x4
38
39 /* Include definitions for instructions classes and implementations flags */
40 //#define PPC_DEBUG_DISAS
41 //#define DO_PPC_STATISTICS
42
43 #ifdef PPC_DEBUG_DISAS
44 #  define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
45 #else
46 #  define LOG_DISAS(...) do { } while (0)
47 #endif
48 /*****************************************************************************/
49 /* Code translation helpers                                                  */
50
51 /* global register indexes */
52 static TCGv_ptr cpu_env;
53 static char cpu_reg_names[10*3 + 22*4 /* GPR */
54     + 10*4 + 22*5 /* SPE GPRh */
55     + 10*4 + 22*5 /* FPR */
56     + 2*(10*6 + 22*7) /* AVRh, AVRl */
57     + 10*5 + 22*6 /* VSR */
58     + 8*5 /* CRF */];
59 static TCGv cpu_gpr[32];
60 static TCGv cpu_gprh[32];
61 static TCGv_i64 cpu_fpr[32];
62 static TCGv_i64 cpu_avrh[32], cpu_avrl[32];
63 static TCGv_i64 cpu_vsr[32];
64 static TCGv_i32 cpu_crf[8];
65 static TCGv cpu_nip;
66 static TCGv cpu_msr;
67 static TCGv cpu_ctr;
68 static TCGv cpu_lr;
69 #if defined(TARGET_PPC64)
70 static TCGv cpu_cfar;
71 #endif
72 static TCGv cpu_xer, cpu_so, cpu_ov, cpu_ca;
73 static TCGv cpu_reserve;
74 static TCGv cpu_fpscr;
75 static TCGv_i32 cpu_access_type;
76
77 #include "exec/gen-icount.h"
78
79 void ppc_translate_init(void)
80 {
81     int i;
82     char* p;
83     size_t cpu_reg_names_size;
84     static int done_init = 0;
85
86     if (done_init)
87         return;
88
89     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
90
91     p = cpu_reg_names;
92     cpu_reg_names_size = sizeof(cpu_reg_names);
93
94     for (i = 0; i < 8; i++) {
95         snprintf(p, cpu_reg_names_size, "crf%d", i);
96         cpu_crf[i] = tcg_global_mem_new_i32(cpu_env,
97                                             offsetof(CPUPPCState, crf[i]), p);
98         p += 5;
99         cpu_reg_names_size -= 5;
100     }
101
102     for (i = 0; i < 32; i++) {
103         snprintf(p, cpu_reg_names_size, "r%d", i);
104         cpu_gpr[i] = tcg_global_mem_new(cpu_env,
105                                         offsetof(CPUPPCState, gpr[i]), p);
106         p += (i < 10) ? 3 : 4;
107         cpu_reg_names_size -= (i < 10) ? 3 : 4;
108         snprintf(p, cpu_reg_names_size, "r%dH", i);
109         cpu_gprh[i] = tcg_global_mem_new(cpu_env,
110                                          offsetof(CPUPPCState, gprh[i]), p);
111         p += (i < 10) ? 4 : 5;
112         cpu_reg_names_size -= (i < 10) ? 4 : 5;
113
114         snprintf(p, cpu_reg_names_size, "fp%d", i);
115         cpu_fpr[i] = tcg_global_mem_new_i64(cpu_env,
116                                             offsetof(CPUPPCState, fpr[i]), p);
117         p += (i < 10) ? 4 : 5;
118         cpu_reg_names_size -= (i < 10) ? 4 : 5;
119
120         snprintf(p, cpu_reg_names_size, "avr%dH", i);
121 #ifdef HOST_WORDS_BIGENDIAN
122         cpu_avrh[i] = tcg_global_mem_new_i64(cpu_env,
123                                              offsetof(CPUPPCState, avr[i].u64[0]), p);
124 #else
125         cpu_avrh[i] = tcg_global_mem_new_i64(cpu_env,
126                                              offsetof(CPUPPCState, avr[i].u64[1]), p);
127 #endif
128         p += (i < 10) ? 6 : 7;
129         cpu_reg_names_size -= (i < 10) ? 6 : 7;
130
131         snprintf(p, cpu_reg_names_size, "avr%dL", i);
132 #ifdef HOST_WORDS_BIGENDIAN
133         cpu_avrl[i] = tcg_global_mem_new_i64(cpu_env,
134                                              offsetof(CPUPPCState, avr[i].u64[1]), p);
135 #else
136         cpu_avrl[i] = tcg_global_mem_new_i64(cpu_env,
137                                              offsetof(CPUPPCState, avr[i].u64[0]), p);
138 #endif
139         p += (i < 10) ? 6 : 7;
140         cpu_reg_names_size -= (i < 10) ? 6 : 7;
141         snprintf(p, cpu_reg_names_size, "vsr%d", i);
142         cpu_vsr[i] = tcg_global_mem_new_i64(cpu_env,
143                                             offsetof(CPUPPCState, vsr[i]), p);
144         p += (i < 10) ? 5 : 6;
145         cpu_reg_names_size -= (i < 10) ? 5 : 6;
146     }
147
148     cpu_nip = tcg_global_mem_new(cpu_env,
149                                  offsetof(CPUPPCState, nip), "nip");
150
151     cpu_msr = tcg_global_mem_new(cpu_env,
152                                  offsetof(CPUPPCState, msr), "msr");
153
154     cpu_ctr = tcg_global_mem_new(cpu_env,
155                                  offsetof(CPUPPCState, ctr), "ctr");
156
157     cpu_lr = tcg_global_mem_new(cpu_env,
158                                 offsetof(CPUPPCState, lr), "lr");
159
160 #if defined(TARGET_PPC64)
161     cpu_cfar = tcg_global_mem_new(cpu_env,
162                                   offsetof(CPUPPCState, cfar), "cfar");
163 #endif
164
165     cpu_xer = tcg_global_mem_new(cpu_env,
166                                  offsetof(CPUPPCState, xer), "xer");
167     cpu_so = tcg_global_mem_new(cpu_env,
168                                 offsetof(CPUPPCState, so), "SO");
169     cpu_ov = tcg_global_mem_new(cpu_env,
170                                 offsetof(CPUPPCState, ov), "OV");
171     cpu_ca = tcg_global_mem_new(cpu_env,
172                                 offsetof(CPUPPCState, ca), "CA");
173
174     cpu_reserve = tcg_global_mem_new(cpu_env,
175                                      offsetof(CPUPPCState, reserve_addr),
176                                      "reserve_addr");
177
178     cpu_fpscr = tcg_global_mem_new(cpu_env,
179                                    offsetof(CPUPPCState, fpscr), "fpscr");
180
181     cpu_access_type = tcg_global_mem_new_i32(cpu_env,
182                                              offsetof(CPUPPCState, access_type), "access_type");
183
184     done_init = 1;
185 }
186
187 /* internal defines */
188 struct DisasContext {
189     struct TranslationBlock *tb;
190     target_ulong nip;
191     uint32_t opcode;
192     uint32_t exception;
193     /* Routine used to access memory */
194     bool pr, hv;
195     int mem_idx;
196     int access_type;
197     /* Translation flags */
198     int le_mode;
199     TCGMemOp default_tcg_memop_mask;
200 #if defined(TARGET_PPC64)
201     int sf_mode;
202     int has_cfar;
203 #endif
204     int fpu_enabled;
205     int altivec_enabled;
206     int vsx_enabled;
207     int spe_enabled;
208     int tm_enabled;
209     ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
210     int singlestep_enabled;
211     uint64_t insns_flags;
212     uint64_t insns_flags2;
213 };
214
215 /* Return true iff byteswap is needed in a scalar memop */
216 static inline bool need_byteswap(const DisasContext *ctx)
217 {
218 #if defined(TARGET_WORDS_BIGENDIAN)
219      return ctx->le_mode;
220 #else
221      return !ctx->le_mode;
222 #endif
223 }
224
225 /* True when active word size < size of target_long.  */
226 #ifdef TARGET_PPC64
227 # define NARROW_MODE(C)  (!(C)->sf_mode)
228 #else
229 # define NARROW_MODE(C)  0
230 #endif
231
232 struct opc_handler_t {
233     /* invalid bits for instruction 1 (Rc(opcode) == 0) */
234     uint32_t inval1;
235     /* invalid bits for instruction 2 (Rc(opcode) == 1) */
236     uint32_t inval2;
237     /* instruction type */
238     uint64_t type;
239     /* extended instruction type */
240     uint64_t type2;
241     /* handler */
242     void (*handler)(DisasContext *ctx);
243 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
244     const char *oname;
245 #endif
246 #if defined(DO_PPC_STATISTICS)
247     uint64_t count;
248 #endif
249 };
250
251 static inline void gen_reset_fpstatus(void)
252 {
253     gen_helper_reset_fpstatus(cpu_env);
254 }
255
256 static inline void gen_compute_fprf(TCGv_i64 arg)
257 {
258     gen_helper_compute_fprf(cpu_env, arg);
259     gen_helper_float_check_status(cpu_env);
260 }
261
262 static inline void gen_set_access_type(DisasContext *ctx, int access_type)
263 {
264     if (ctx->access_type != access_type) {
265         tcg_gen_movi_i32(cpu_access_type, access_type);
266         ctx->access_type = access_type;
267     }
268 }
269
270 static inline void gen_update_nip(DisasContext *ctx, target_ulong nip)
271 {
272     if (NARROW_MODE(ctx)) {
273         nip = (uint32_t)nip;
274     }
275     tcg_gen_movi_tl(cpu_nip, nip);
276 }
277
278 void gen_update_current_nip(void *opaque)
279 {
280     DisasContext *ctx = opaque;
281
282     tcg_gen_movi_tl(cpu_nip, ctx->nip);
283 }
284
285 static inline void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t error)
286 {
287     TCGv_i32 t0, t1;
288     if (ctx->exception == POWERPC_EXCP_NONE) {
289         gen_update_nip(ctx, ctx->nip);
290     }
291     t0 = tcg_const_i32(excp);
292     t1 = tcg_const_i32(error);
293     gen_helper_raise_exception_err(cpu_env, t0, t1);
294     tcg_temp_free_i32(t0);
295     tcg_temp_free_i32(t1);
296     ctx->exception = (excp);
297 }
298
299 static inline void gen_exception(DisasContext *ctx, uint32_t excp)
300 {
301     TCGv_i32 t0;
302     if (ctx->exception == POWERPC_EXCP_NONE) {
303         gen_update_nip(ctx, ctx->nip);
304     }
305     t0 = tcg_const_i32(excp);
306     gen_helper_raise_exception(cpu_env, t0);
307     tcg_temp_free_i32(t0);
308     ctx->exception = (excp);
309 }
310
311 static inline void gen_debug_exception(DisasContext *ctx)
312 {
313     TCGv_i32 t0;
314
315     if ((ctx->exception != POWERPC_EXCP_BRANCH) &&
316         (ctx->exception != POWERPC_EXCP_SYNC)) {
317         gen_update_nip(ctx, ctx->nip);
318     }
319     t0 = tcg_const_i32(EXCP_DEBUG);
320     gen_helper_raise_exception(cpu_env, t0);
321     tcg_temp_free_i32(t0);
322 }
323
324 static inline void gen_inval_exception(DisasContext *ctx, uint32_t error)
325 {
326     gen_exception_err(ctx, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_INVAL | error);
327 }
328
329 /* Stop translation */
330 static inline void gen_stop_exception(DisasContext *ctx)
331 {
332     gen_update_nip(ctx, ctx->nip);
333     ctx->exception = POWERPC_EXCP_STOP;
334 }
335
336 #ifndef CONFIG_USER_ONLY
337 /* No need to update nip here, as execution flow will change */
338 static inline void gen_sync_exception(DisasContext *ctx)
339 {
340     ctx->exception = POWERPC_EXCP_SYNC;
341 }
342 #endif
343
344 #define GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                      \
345 GEN_OPCODE(name, opc1, opc2, opc3, inval, type, PPC_NONE)
346
347 #define GEN_HANDLER_E(name, opc1, opc2, opc3, inval, type, type2)             \
348 GEN_OPCODE(name, opc1, opc2, opc3, inval, type, type2)
349
350 #define GEN_HANDLER2(name, onam, opc1, opc2, opc3, inval, type)               \
351 GEN_OPCODE2(name, onam, opc1, opc2, opc3, inval, type, PPC_NONE)
352
353 #define GEN_HANDLER2_E(name, onam, opc1, opc2, opc3, inval, type, type2)      \
354 GEN_OPCODE2(name, onam, opc1, opc2, opc3, inval, type, type2)
355
356 typedef struct opcode_t {
357     unsigned char opc1, opc2, opc3;
358 #if HOST_LONG_BITS == 64 /* Explicitly align to 64 bits */
359     unsigned char pad[5];
360 #else
361     unsigned char pad[1];
362 #endif
363     opc_handler_t handler;
364     const char *oname;
365 } opcode_t;
366
367 /*****************************************************************************/
368 /***                           Instruction decoding                        ***/
369 #define EXTRACT_HELPER(name, shift, nb)                                       \
370 static inline uint32_t name(uint32_t opcode)                                  \
371 {                                                                             \
372     return (opcode >> (shift)) & ((1 << (nb)) - 1);                           \
373 }
374
375 #define EXTRACT_SHELPER(name, shift, nb)                                      \
376 static inline int32_t name(uint32_t opcode)                                   \
377 {                                                                             \
378     return (int16_t)((opcode >> (shift)) & ((1 << (nb)) - 1));                \
379 }
380
381 #define EXTRACT_HELPER_SPLIT(name, shift1, nb1, shift2, nb2)                  \
382 static inline uint32_t name(uint32_t opcode)                                  \
383 {                                                                             \
384     return (((opcode >> (shift1)) & ((1 << (nb1)) - 1)) << nb2) |             \
385             ((opcode >> (shift2)) & ((1 << (nb2)) - 1));                      \
386 }
387 /* Opcode part 1 */
388 EXTRACT_HELPER(opc1, 26, 6);
389 /* Opcode part 2 */
390 EXTRACT_HELPER(opc2, 1, 5);
391 /* Opcode part 3 */
392 EXTRACT_HELPER(opc3, 6, 5);
393 /* Update Cr0 flags */
394 EXTRACT_HELPER(Rc, 0, 1);
395 /* Update Cr6 flags (Altivec) */
396 EXTRACT_HELPER(Rc21, 10, 1);
397 /* Destination */
398 EXTRACT_HELPER(rD, 21, 5);
399 /* Source */
400 EXTRACT_HELPER(rS, 21, 5);
401 /* First operand */
402 EXTRACT_HELPER(rA, 16, 5);
403 /* Second operand */
404 EXTRACT_HELPER(rB, 11, 5);
405 /* Third operand */
406 EXTRACT_HELPER(rC, 6, 5);
407 /***                               Get CRn                                 ***/
408 EXTRACT_HELPER(crfD, 23, 3);
409 EXTRACT_HELPER(crfS, 18, 3);
410 EXTRACT_HELPER(crbD, 21, 5);
411 EXTRACT_HELPER(crbA, 16, 5);
412 EXTRACT_HELPER(crbB, 11, 5);
413 /* SPR / TBL */
414 EXTRACT_HELPER(_SPR, 11, 10);
415 static inline uint32_t SPR(uint32_t opcode)
416 {
417     uint32_t sprn = _SPR(opcode);
418
419     return ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
420 }
421 /***                              Get constants                            ***/
422 /* 16 bits signed immediate value */
423 EXTRACT_SHELPER(SIMM, 0, 16);
424 /* 16 bits unsigned immediate value */
425 EXTRACT_HELPER(UIMM, 0, 16);
426 /* 5 bits signed immediate value */
427 EXTRACT_HELPER(SIMM5, 16, 5);
428 /* 5 bits signed immediate value */
429 EXTRACT_HELPER(UIMM5, 16, 5);
430 /* Bit count */
431 EXTRACT_HELPER(NB, 11, 5);
432 /* Shift count */
433 EXTRACT_HELPER(SH, 11, 5);
434 /* Vector shift count */
435 EXTRACT_HELPER(VSH, 6, 4);
436 /* Mask start */
437 EXTRACT_HELPER(MB, 6, 5);
438 /* Mask end */
439 EXTRACT_HELPER(ME, 1, 5);
440 /* Trap operand */
441 EXTRACT_HELPER(TO, 21, 5);
442
443 EXTRACT_HELPER(CRM, 12, 8);
444
445 #ifndef CONFIG_USER_ONLY
446 EXTRACT_HELPER(SR, 16, 4);
447 #endif
448
449 /* mtfsf/mtfsfi */
450 EXTRACT_HELPER(FPBF, 23, 3);
451 EXTRACT_HELPER(FPIMM, 12, 4);
452 EXTRACT_HELPER(FPL, 25, 1);
453 EXTRACT_HELPER(FPFLM, 17, 8);
454 EXTRACT_HELPER(FPW, 16, 1);
455
456 /***                            Jump target decoding                       ***/
457 /* Immediate address */
458 static inline target_ulong LI(uint32_t opcode)
459 {
460     return (opcode >> 0) & 0x03FFFFFC;
461 }
462
463 static inline uint32_t BD(uint32_t opcode)
464 {
465     return (opcode >> 0) & 0xFFFC;
466 }
467
468 EXTRACT_HELPER(BO, 21, 5);
469 EXTRACT_HELPER(BI, 16, 5);
470 /* Absolute/relative address */
471 EXTRACT_HELPER(AA, 1, 1);
472 /* Link */
473 EXTRACT_HELPER(LK, 0, 1);
474
475 /* DFP Z22-form */
476 EXTRACT_HELPER(DCM, 10, 6)
477
478 /* DFP Z23-form */
479 EXTRACT_HELPER(RMC, 9, 2)
480
481 /* Create a mask between <start> and <end> bits */
482 static inline target_ulong MASK(uint32_t start, uint32_t end)
483 {
484     target_ulong ret;
485
486 #if defined(TARGET_PPC64)
487     if (likely(start == 0)) {
488         ret = UINT64_MAX << (63 - end);
489     } else if (likely(end == 63)) {
490         ret = UINT64_MAX >> start;
491     }
492 #else
493     if (likely(start == 0)) {
494         ret = UINT32_MAX << (31  - end);
495     } else if (likely(end == 31)) {
496         ret = UINT32_MAX >> start;
497     }
498 #endif
499     else {
500         ret = (((target_ulong)(-1ULL)) >> (start)) ^
501             (((target_ulong)(-1ULL) >> (end)) >> 1);
502         if (unlikely(start > end))
503             return ~ret;
504     }
505
506     return ret;
507 }
508
509 EXTRACT_HELPER_SPLIT(xT, 0, 1, 21, 5);
510 EXTRACT_HELPER_SPLIT(xS, 0, 1, 21, 5);
511 EXTRACT_HELPER_SPLIT(xA, 2, 1, 16, 5);
512 EXTRACT_HELPER_SPLIT(xB, 1, 1, 11, 5);
513 EXTRACT_HELPER_SPLIT(xC, 3, 1,  6, 5);
514 EXTRACT_HELPER(DM, 8, 2);
515 EXTRACT_HELPER(UIM, 16, 2);
516 EXTRACT_HELPER(SHW, 8, 2);
517 EXTRACT_HELPER(SP, 19, 2);
518 /*****************************************************************************/
519 /* PowerPC instructions table                                                */
520
521 #if defined(DO_PPC_STATISTICS)
522 #define GEN_OPCODE(name, op1, op2, op3, invl, _typ, _typ2)                    \
523 {                                                                             \
524     .opc1 = op1,                                                              \
525     .opc2 = op2,                                                              \
526     .opc3 = op3,                                                              \
527     .pad  = { 0, },                                                           \
528     .handler = {                                                              \
529         .inval1  = invl,                                                      \
530         .type = _typ,                                                         \
531         .type2 = _typ2,                                                       \
532         .handler = &gen_##name,                                               \
533         .oname = stringify(name),                                             \
534     },                                                                        \
535     .oname = stringify(name),                                                 \
536 }
537 #define GEN_OPCODE_DUAL(name, op1, op2, op3, invl1, invl2, _typ, _typ2)       \
538 {                                                                             \
539     .opc1 = op1,                                                              \
540     .opc2 = op2,                                                              \
541     .opc3 = op3,                                                              \
542     .pad  = { 0, },                                                           \
543     .handler = {                                                              \
544         .inval1  = invl1,                                                     \
545         .inval2  = invl2,                                                     \
546         .type = _typ,                                                         \
547         .type2 = _typ2,                                                       \
548         .handler = &gen_##name,                                               \
549         .oname = stringify(name),                                             \
550     },                                                                        \
551     .oname = stringify(name),                                                 \
552 }
553 #define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ, _typ2)             \
554 {                                                                             \
555     .opc1 = op1,                                                              \
556     .opc2 = op2,                                                              \
557     .opc3 = op3,                                                              \
558     .pad  = { 0, },                                                           \
559     .handler = {                                                              \
560         .inval1  = invl,                                                      \
561         .type = _typ,                                                         \
562         .type2 = _typ2,                                                       \
563         .handler = &gen_##name,                                               \
564         .oname = onam,                                                        \
565     },                                                                        \
566     .oname = onam,                                                            \
567 }
568 #else
569 #define GEN_OPCODE(name, op1, op2, op3, invl, _typ, _typ2)                    \
570 {                                                                             \
571     .opc1 = op1,                                                              \
572     .opc2 = op2,                                                              \
573     .opc3 = op3,                                                              \
574     .pad  = { 0, },                                                           \
575     .handler = {                                                              \
576         .inval1  = invl,                                                      \
577         .type = _typ,                                                         \
578         .type2 = _typ2,                                                       \
579         .handler = &gen_##name,                                               \
580     },                                                                        \
581     .oname = stringify(name),                                                 \
582 }
583 #define GEN_OPCODE_DUAL(name, op1, op2, op3, invl1, invl2, _typ, _typ2)       \
584 {                                                                             \
585     .opc1 = op1,                                                              \
586     .opc2 = op2,                                                              \
587     .opc3 = op3,                                                              \
588     .pad  = { 0, },                                                           \
589     .handler = {                                                              \
590         .inval1  = invl1,                                                     \
591         .inval2  = invl2,                                                     \
592         .type = _typ,                                                         \
593         .type2 = _typ2,                                                       \
594         .handler = &gen_##name,                                               \
595     },                                                                        \
596     .oname = stringify(name),                                                 \
597 }
598 #define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ, _typ2)             \
599 {                                                                             \
600     .opc1 = op1,                                                              \
601     .opc2 = op2,                                                              \
602     .opc3 = op3,                                                              \
603     .pad  = { 0, },                                                           \
604     .handler = {                                                              \
605         .inval1  = invl,                                                      \
606         .type = _typ,                                                         \
607         .type2 = _typ2,                                                       \
608         .handler = &gen_##name,                                               \
609     },                                                                        \
610     .oname = onam,                                                            \
611 }
612 #endif
613
614 /* SPR load/store helpers */
615 static inline void gen_load_spr(TCGv t, int reg)
616 {
617     tcg_gen_ld_tl(t, cpu_env, offsetof(CPUPPCState, spr[reg]));
618 }
619
620 static inline void gen_store_spr(int reg, TCGv t)
621 {
622     tcg_gen_st_tl(t, cpu_env, offsetof(CPUPPCState, spr[reg]));
623 }
624
625 /* Invalid instruction */
626 static void gen_invalid(DisasContext *ctx)
627 {
628     gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
629 }
630
631 static opc_handler_t invalid_handler = {
632     .inval1  = 0xFFFFFFFF,
633     .inval2  = 0xFFFFFFFF,
634     .type    = PPC_NONE,
635     .type2   = PPC_NONE,
636     .handler = gen_invalid,
637 };
638
639 /***                           Integer comparison                          ***/
640
641 static inline void gen_op_cmp(TCGv arg0, TCGv arg1, int s, int crf)
642 {
643     TCGv t0 = tcg_temp_new();
644     TCGv_i32 t1 = tcg_temp_new_i32();
645
646     tcg_gen_trunc_tl_i32(cpu_crf[crf], cpu_so);
647
648     tcg_gen_setcond_tl((s ? TCG_COND_LT: TCG_COND_LTU), t0, arg0, arg1);
649     tcg_gen_trunc_tl_i32(t1, t0);
650     tcg_gen_shli_i32(t1, t1, CRF_LT);
651     tcg_gen_or_i32(cpu_crf[crf], cpu_crf[crf], t1);
652
653     tcg_gen_setcond_tl((s ? TCG_COND_GT: TCG_COND_GTU), t0, arg0, arg1);
654     tcg_gen_trunc_tl_i32(t1, t0);
655     tcg_gen_shli_i32(t1, t1, CRF_GT);
656     tcg_gen_or_i32(cpu_crf[crf], cpu_crf[crf], t1);
657
658     tcg_gen_setcond_tl(TCG_COND_EQ, t0, arg0, arg1);
659     tcg_gen_trunc_tl_i32(t1, t0);
660     tcg_gen_shli_i32(t1, t1, CRF_EQ);
661     tcg_gen_or_i32(cpu_crf[crf], cpu_crf[crf], t1);
662
663     tcg_temp_free(t0);
664     tcg_temp_free_i32(t1);
665 }
666
667 static inline void gen_op_cmpi(TCGv arg0, target_ulong arg1, int s, int crf)
668 {
669     TCGv t0 = tcg_const_tl(arg1);
670     gen_op_cmp(arg0, t0, s, crf);
671     tcg_temp_free(t0);
672 }
673
674 static inline void gen_op_cmp32(TCGv arg0, TCGv arg1, int s, int crf)
675 {
676     TCGv t0, t1;
677     t0 = tcg_temp_new();
678     t1 = tcg_temp_new();
679     if (s) {
680         tcg_gen_ext32s_tl(t0, arg0);
681         tcg_gen_ext32s_tl(t1, arg1);
682     } else {
683         tcg_gen_ext32u_tl(t0, arg0);
684         tcg_gen_ext32u_tl(t1, arg1);
685     }
686     gen_op_cmp(t0, t1, s, crf);
687     tcg_temp_free(t1);
688     tcg_temp_free(t0);
689 }
690
691 static inline void gen_op_cmpi32(TCGv arg0, target_ulong arg1, int s, int crf)
692 {
693     TCGv t0 = tcg_const_tl(arg1);
694     gen_op_cmp32(arg0, t0, s, crf);
695     tcg_temp_free(t0);
696 }
697
698 static inline void gen_set_Rc0(DisasContext *ctx, TCGv reg)
699 {
700     if (NARROW_MODE(ctx)) {
701         gen_op_cmpi32(reg, 0, 1, 0);
702     } else {
703         gen_op_cmpi(reg, 0, 1, 0);
704     }
705 }
706
707 /* cmp */
708 static void gen_cmp(DisasContext *ctx)
709 {
710     if ((ctx->opcode & 0x00200000) && (ctx->insns_flags & PPC_64B)) {
711         gen_op_cmp(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
712                    1, crfD(ctx->opcode));
713     } else {
714         gen_op_cmp32(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
715                      1, crfD(ctx->opcode));
716     }
717 }
718
719 /* cmpi */
720 static void gen_cmpi(DisasContext *ctx)
721 {
722     if ((ctx->opcode & 0x00200000) && (ctx->insns_flags & PPC_64B)) {
723         gen_op_cmpi(cpu_gpr[rA(ctx->opcode)], SIMM(ctx->opcode),
724                     1, crfD(ctx->opcode));
725     } else {
726         gen_op_cmpi32(cpu_gpr[rA(ctx->opcode)], SIMM(ctx->opcode),
727                       1, crfD(ctx->opcode));
728     }
729 }
730
731 /* cmpl */
732 static void gen_cmpl(DisasContext *ctx)
733 {
734     if ((ctx->opcode & 0x00200000) && (ctx->insns_flags & PPC_64B)) {
735         gen_op_cmp(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
736                    0, crfD(ctx->opcode));
737     } else {
738         gen_op_cmp32(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
739                      0, crfD(ctx->opcode));
740     }
741 }
742
743 /* cmpli */
744 static void gen_cmpli(DisasContext *ctx)
745 {
746     if ((ctx->opcode & 0x00200000) && (ctx->insns_flags & PPC_64B)) {
747         gen_op_cmpi(cpu_gpr[rA(ctx->opcode)], UIMM(ctx->opcode),
748                     0, crfD(ctx->opcode));
749     } else {
750         gen_op_cmpi32(cpu_gpr[rA(ctx->opcode)], UIMM(ctx->opcode),
751                       0, crfD(ctx->opcode));
752     }
753 }
754
755 /* isel (PowerPC 2.03 specification) */
756 static void gen_isel(DisasContext *ctx)
757 {
758     TCGLabel *l1, *l2;
759     uint32_t bi = rC(ctx->opcode);
760     uint32_t mask;
761     TCGv_i32 t0;
762
763     l1 = gen_new_label();
764     l2 = gen_new_label();
765
766     mask = 0x08 >> (bi & 0x03);
767     t0 = tcg_temp_new_i32();
768     tcg_gen_andi_i32(t0, cpu_crf[bi >> 2], mask);
769     tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
770     if (rA(ctx->opcode) == 0)
771         tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
772     else
773         tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
774     tcg_gen_br(l2);
775     gen_set_label(l1);
776     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
777     gen_set_label(l2);
778     tcg_temp_free_i32(t0);
779 }
780
781 /* cmpb: PowerPC 2.05 specification */
782 static void gen_cmpb(DisasContext *ctx)
783 {
784     gen_helper_cmpb(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)],
785                     cpu_gpr[rB(ctx->opcode)]);
786 }
787
788 /***                           Integer arithmetic                          ***/
789
790 static inline void gen_op_arith_compute_ov(DisasContext *ctx, TCGv arg0,
791                                            TCGv arg1, TCGv arg2, int sub)
792 {
793     TCGv t0 = tcg_temp_new();
794
795     tcg_gen_xor_tl(cpu_ov, arg0, arg2);
796     tcg_gen_xor_tl(t0, arg1, arg2);
797     if (sub) {
798         tcg_gen_and_tl(cpu_ov, cpu_ov, t0);
799     } else {
800         tcg_gen_andc_tl(cpu_ov, cpu_ov, t0);
801     }
802     tcg_temp_free(t0);
803     if (NARROW_MODE(ctx)) {
804         tcg_gen_ext32s_tl(cpu_ov, cpu_ov);
805     }
806     tcg_gen_shri_tl(cpu_ov, cpu_ov, TARGET_LONG_BITS - 1);
807     tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov);
808 }
809
810 /* Common add function */
811 static inline void gen_op_arith_add(DisasContext *ctx, TCGv ret, TCGv arg1,
812                                     TCGv arg2, bool add_ca, bool compute_ca,
813                                     bool compute_ov, bool compute_rc0)
814 {
815     TCGv t0 = ret;
816
817     if (compute_ca || compute_ov) {
818         t0 = tcg_temp_new();
819     }
820
821     if (compute_ca) {
822         if (NARROW_MODE(ctx)) {
823             /* Caution: a non-obvious corner case of the spec is that we
824                must produce the *entire* 64-bit addition, but produce the
825                carry into bit 32.  */
826             TCGv t1 = tcg_temp_new();
827             tcg_gen_xor_tl(t1, arg1, arg2);        /* add without carry */
828             tcg_gen_add_tl(t0, arg1, arg2);
829             if (add_ca) {
830                 tcg_gen_add_tl(t0, t0, cpu_ca);
831             }
832             tcg_gen_xor_tl(cpu_ca, t0, t1);        /* bits changed w/ carry */
833             tcg_temp_free(t1);
834             tcg_gen_shri_tl(cpu_ca, cpu_ca, 32);   /* extract bit 32 */
835             tcg_gen_andi_tl(cpu_ca, cpu_ca, 1);
836         } else {
837             TCGv zero = tcg_const_tl(0);
838             if (add_ca) {
839                 tcg_gen_add2_tl(t0, cpu_ca, arg1, zero, cpu_ca, zero);
840                 tcg_gen_add2_tl(t0, cpu_ca, t0, cpu_ca, arg2, zero);
841             } else {
842                 tcg_gen_add2_tl(t0, cpu_ca, arg1, zero, arg2, zero);
843             }
844             tcg_temp_free(zero);
845         }
846     } else {
847         tcg_gen_add_tl(t0, arg1, arg2);
848         if (add_ca) {
849             tcg_gen_add_tl(t0, t0, cpu_ca);
850         }
851     }
852
853     if (compute_ov) {
854         gen_op_arith_compute_ov(ctx, t0, arg1, arg2, 0);
855     }
856     if (unlikely(compute_rc0)) {
857         gen_set_Rc0(ctx, t0);
858     }
859
860     if (!TCGV_EQUAL(t0, ret)) {
861         tcg_gen_mov_tl(ret, t0);
862         tcg_temp_free(t0);
863     }
864 }
865 /* Add functions with two operands */
866 #define GEN_INT_ARITH_ADD(name, opc3, add_ca, compute_ca, compute_ov)         \
867 static void glue(gen_, name)(DisasContext *ctx)                               \
868 {                                                                             \
869     gen_op_arith_add(ctx, cpu_gpr[rD(ctx->opcode)],                           \
870                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],      \
871                      add_ca, compute_ca, compute_ov, Rc(ctx->opcode));        \
872 }
873 /* Add functions with one operand and one immediate */
874 #define GEN_INT_ARITH_ADD_CONST(name, opc3, const_val,                        \
875                                 add_ca, compute_ca, compute_ov)               \
876 static void glue(gen_, name)(DisasContext *ctx)                               \
877 {                                                                             \
878     TCGv t0 = tcg_const_tl(const_val);                                        \
879     gen_op_arith_add(ctx, cpu_gpr[rD(ctx->opcode)],                           \
880                      cpu_gpr[rA(ctx->opcode)], t0,                            \
881                      add_ca, compute_ca, compute_ov, Rc(ctx->opcode));        \
882     tcg_temp_free(t0);                                                        \
883 }
884
885 /* add  add.  addo  addo. */
886 GEN_INT_ARITH_ADD(add, 0x08, 0, 0, 0)
887 GEN_INT_ARITH_ADD(addo, 0x18, 0, 0, 1)
888 /* addc  addc.  addco  addco. */
889 GEN_INT_ARITH_ADD(addc, 0x00, 0, 1, 0)
890 GEN_INT_ARITH_ADD(addco, 0x10, 0, 1, 1)
891 /* adde  adde.  addeo  addeo. */
892 GEN_INT_ARITH_ADD(adde, 0x04, 1, 1, 0)
893 GEN_INT_ARITH_ADD(addeo, 0x14, 1, 1, 1)
894 /* addme  addme.  addmeo  addmeo.  */
895 GEN_INT_ARITH_ADD_CONST(addme, 0x07, -1LL, 1, 1, 0)
896 GEN_INT_ARITH_ADD_CONST(addmeo, 0x17, -1LL, 1, 1, 1)
897 /* addze  addze.  addzeo  addzeo.*/
898 GEN_INT_ARITH_ADD_CONST(addze, 0x06, 0, 1, 1, 0)
899 GEN_INT_ARITH_ADD_CONST(addzeo, 0x16, 0, 1, 1, 1)
900 /* addi */
901 static void gen_addi(DisasContext *ctx)
902 {
903     target_long simm = SIMM(ctx->opcode);
904
905     if (rA(ctx->opcode) == 0) {
906         /* li case */
907         tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], simm);
908     } else {
909         tcg_gen_addi_tl(cpu_gpr[rD(ctx->opcode)],
910                         cpu_gpr[rA(ctx->opcode)], simm);
911     }
912 }
913 /* addic  addic.*/
914 static inline void gen_op_addic(DisasContext *ctx, bool compute_rc0)
915 {
916     TCGv c = tcg_const_tl(SIMM(ctx->opcode));
917     gen_op_arith_add(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
918                      c, 0, 1, 0, compute_rc0);
919     tcg_temp_free(c);
920 }
921
922 static void gen_addic(DisasContext *ctx)
923 {
924     gen_op_addic(ctx, 0);
925 }
926
927 static void gen_addic_(DisasContext *ctx)
928 {
929     gen_op_addic(ctx, 1);
930 }
931
932 /* addis */
933 static void gen_addis(DisasContext *ctx)
934 {
935     target_long simm = SIMM(ctx->opcode);
936
937     if (rA(ctx->opcode) == 0) {
938         /* lis case */
939         tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], simm << 16);
940     } else {
941         tcg_gen_addi_tl(cpu_gpr[rD(ctx->opcode)],
942                         cpu_gpr[rA(ctx->opcode)], simm << 16);
943     }
944 }
945
946 static inline void gen_op_arith_divw(DisasContext *ctx, TCGv ret, TCGv arg1,
947                                      TCGv arg2, int sign, int compute_ov)
948 {
949     TCGLabel *l1 = gen_new_label();
950     TCGLabel *l2 = gen_new_label();
951     TCGv_i32 t0 = tcg_temp_local_new_i32();
952     TCGv_i32 t1 = tcg_temp_local_new_i32();
953
954     tcg_gen_trunc_tl_i32(t0, arg1);
955     tcg_gen_trunc_tl_i32(t1, arg2);
956     tcg_gen_brcondi_i32(TCG_COND_EQ, t1, 0, l1);
957     if (sign) {
958         TCGLabel *l3 = gen_new_label();
959         tcg_gen_brcondi_i32(TCG_COND_NE, t1, -1, l3);
960         tcg_gen_brcondi_i32(TCG_COND_EQ, t0, INT32_MIN, l1);
961         gen_set_label(l3);
962         tcg_gen_div_i32(t0, t0, t1);
963     } else {
964         tcg_gen_divu_i32(t0, t0, t1);
965     }
966     if (compute_ov) {
967         tcg_gen_movi_tl(cpu_ov, 0);
968     }
969     tcg_gen_br(l2);
970     gen_set_label(l1);
971     if (sign) {
972         tcg_gen_sari_i32(t0, t0, 31);
973     } else {
974         tcg_gen_movi_i32(t0, 0);
975     }
976     if (compute_ov) {
977         tcg_gen_movi_tl(cpu_ov, 1);
978         tcg_gen_movi_tl(cpu_so, 1);
979     }
980     gen_set_label(l2);
981     tcg_gen_extu_i32_tl(ret, t0);
982     tcg_temp_free_i32(t0);
983     tcg_temp_free_i32(t1);
984     if (unlikely(Rc(ctx->opcode) != 0))
985         gen_set_Rc0(ctx, ret);
986 }
987 /* Div functions */
988 #define GEN_INT_ARITH_DIVW(name, opc3, sign, compute_ov)                      \
989 static void glue(gen_, name)(DisasContext *ctx)                                       \
990 {                                                                             \
991     gen_op_arith_divw(ctx, cpu_gpr[rD(ctx->opcode)],                          \
992                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],      \
993                      sign, compute_ov);                                       \
994 }
995 /* divwu  divwu.  divwuo  divwuo.   */
996 GEN_INT_ARITH_DIVW(divwu, 0x0E, 0, 0);
997 GEN_INT_ARITH_DIVW(divwuo, 0x1E, 0, 1);
998 /* divw  divw.  divwo  divwo.   */
999 GEN_INT_ARITH_DIVW(divw, 0x0F, 1, 0);
1000 GEN_INT_ARITH_DIVW(divwo, 0x1F, 1, 1);
1001
1002 /* div[wd]eu[o][.] */
1003 #define GEN_DIVE(name, hlpr, compute_ov)                                      \
1004 static void gen_##name(DisasContext *ctx)                                     \
1005 {                                                                             \
1006     TCGv_i32 t0 = tcg_const_i32(compute_ov);                                  \
1007     gen_helper_##hlpr(cpu_gpr[rD(ctx->opcode)], cpu_env,                      \
1008                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], t0); \
1009     tcg_temp_free_i32(t0);                                                    \
1010     if (unlikely(Rc(ctx->opcode) != 0)) {                                     \
1011         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);                           \
1012     }                                                                         \
1013 }
1014
1015 GEN_DIVE(divweu, divweu, 0);
1016 GEN_DIVE(divweuo, divweu, 1);
1017 GEN_DIVE(divwe, divwe, 0);
1018 GEN_DIVE(divweo, divwe, 1);
1019
1020 #if defined(TARGET_PPC64)
1021 static inline void gen_op_arith_divd(DisasContext *ctx, TCGv ret, TCGv arg1,
1022                                      TCGv arg2, int sign, int compute_ov)
1023 {
1024     TCGLabel *l1 = gen_new_label();
1025     TCGLabel *l2 = gen_new_label();
1026
1027     tcg_gen_brcondi_i64(TCG_COND_EQ, arg2, 0, l1);
1028     if (sign) {
1029         TCGLabel *l3 = gen_new_label();
1030         tcg_gen_brcondi_i64(TCG_COND_NE, arg2, -1, l3);
1031         tcg_gen_brcondi_i64(TCG_COND_EQ, arg1, INT64_MIN, l1);
1032         gen_set_label(l3);
1033         tcg_gen_div_i64(ret, arg1, arg2);
1034     } else {
1035         tcg_gen_divu_i64(ret, arg1, arg2);
1036     }
1037     if (compute_ov) {
1038         tcg_gen_movi_tl(cpu_ov, 0);
1039     }
1040     tcg_gen_br(l2);
1041     gen_set_label(l1);
1042     if (sign) {
1043         tcg_gen_sari_i64(ret, arg1, 63);
1044     } else {
1045         tcg_gen_movi_i64(ret, 0);
1046     }
1047     if (compute_ov) {
1048         tcg_gen_movi_tl(cpu_ov, 1);
1049         tcg_gen_movi_tl(cpu_so, 1);
1050     }
1051     gen_set_label(l2);
1052     if (unlikely(Rc(ctx->opcode) != 0))
1053         gen_set_Rc0(ctx, ret);
1054 }
1055 #define GEN_INT_ARITH_DIVD(name, opc3, sign, compute_ov)                      \
1056 static void glue(gen_, name)(DisasContext *ctx)                                       \
1057 {                                                                             \
1058     gen_op_arith_divd(ctx, cpu_gpr[rD(ctx->opcode)],                          \
1059                       cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],     \
1060                       sign, compute_ov);                                      \
1061 }
1062 /* divwu  divwu.  divwuo  divwuo.   */
1063 GEN_INT_ARITH_DIVD(divdu, 0x0E, 0, 0);
1064 GEN_INT_ARITH_DIVD(divduo, 0x1E, 0, 1);
1065 /* divw  divw.  divwo  divwo.   */
1066 GEN_INT_ARITH_DIVD(divd, 0x0F, 1, 0);
1067 GEN_INT_ARITH_DIVD(divdo, 0x1F, 1, 1);
1068
1069 GEN_DIVE(divdeu, divdeu, 0);
1070 GEN_DIVE(divdeuo, divdeu, 1);
1071 GEN_DIVE(divde, divde, 0);
1072 GEN_DIVE(divdeo, divde, 1);
1073 #endif
1074
1075 /* mulhw  mulhw. */
1076 static void gen_mulhw(DisasContext *ctx)
1077 {
1078     TCGv_i32 t0 = tcg_temp_new_i32();
1079     TCGv_i32 t1 = tcg_temp_new_i32();
1080
1081     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);
1082     tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);
1083     tcg_gen_muls2_i32(t0, t1, t0, t1);
1084     tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t1);
1085     tcg_temp_free_i32(t0);
1086     tcg_temp_free_i32(t1);
1087     if (unlikely(Rc(ctx->opcode) != 0))
1088         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1089 }
1090
1091 /* mulhwu  mulhwu.  */
1092 static void gen_mulhwu(DisasContext *ctx)
1093 {
1094     TCGv_i32 t0 = tcg_temp_new_i32();
1095     TCGv_i32 t1 = tcg_temp_new_i32();
1096
1097     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);
1098     tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);
1099     tcg_gen_mulu2_i32(t0, t1, t0, t1);
1100     tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t1);
1101     tcg_temp_free_i32(t0);
1102     tcg_temp_free_i32(t1);
1103     if (unlikely(Rc(ctx->opcode) != 0))
1104         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1105 }
1106
1107 /* mullw  mullw. */
1108 static void gen_mullw(DisasContext *ctx)
1109 {
1110 #if defined(TARGET_PPC64)
1111     TCGv_i64 t0, t1;
1112     t0 = tcg_temp_new_i64();
1113     t1 = tcg_temp_new_i64();
1114     tcg_gen_ext32s_tl(t0, cpu_gpr[rA(ctx->opcode)]);
1115     tcg_gen_ext32s_tl(t1, cpu_gpr[rB(ctx->opcode)]);
1116     tcg_gen_mul_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);
1117     tcg_temp_free(t0);
1118     tcg_temp_free(t1);
1119 #else
1120     tcg_gen_mul_i32(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
1121                     cpu_gpr[rB(ctx->opcode)]);
1122 #endif
1123     if (unlikely(Rc(ctx->opcode) != 0))
1124         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1125 }
1126
1127 /* mullwo  mullwo. */
1128 static void gen_mullwo(DisasContext *ctx)
1129 {
1130     TCGv_i32 t0 = tcg_temp_new_i32();
1131     TCGv_i32 t1 = tcg_temp_new_i32();
1132
1133     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);
1134     tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);
1135     tcg_gen_muls2_i32(t0, t1, t0, t1);
1136 #if defined(TARGET_PPC64)
1137     tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);
1138 #else
1139     tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], t0);
1140 #endif
1141
1142     tcg_gen_sari_i32(t0, t0, 31);
1143     tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t1);
1144     tcg_gen_extu_i32_tl(cpu_ov, t0);
1145     tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov);
1146
1147     tcg_temp_free_i32(t0);
1148     tcg_temp_free_i32(t1);
1149     if (unlikely(Rc(ctx->opcode) != 0))
1150         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1151 }
1152
1153 /* mulli */
1154 static void gen_mulli(DisasContext *ctx)
1155 {
1156     tcg_gen_muli_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
1157                     SIMM(ctx->opcode));
1158 }
1159
1160 #if defined(TARGET_PPC64)
1161 /* mulhd  mulhd. */
1162 static void gen_mulhd(DisasContext *ctx)
1163 {
1164     TCGv lo = tcg_temp_new();
1165     tcg_gen_muls2_tl(lo, cpu_gpr[rD(ctx->opcode)],
1166                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1167     tcg_temp_free(lo);
1168     if (unlikely(Rc(ctx->opcode) != 0)) {
1169         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1170     }
1171 }
1172
1173 /* mulhdu  mulhdu. */
1174 static void gen_mulhdu(DisasContext *ctx)
1175 {
1176     TCGv lo = tcg_temp_new();
1177     tcg_gen_mulu2_tl(lo, cpu_gpr[rD(ctx->opcode)],
1178                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1179     tcg_temp_free(lo);
1180     if (unlikely(Rc(ctx->opcode) != 0)) {
1181         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1182     }
1183 }
1184
1185 /* mulld  mulld. */
1186 static void gen_mulld(DisasContext *ctx)
1187 {
1188     tcg_gen_mul_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
1189                    cpu_gpr[rB(ctx->opcode)]);
1190     if (unlikely(Rc(ctx->opcode) != 0))
1191         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1192 }
1193
1194 /* mulldo  mulldo. */
1195 static void gen_mulldo(DisasContext *ctx)
1196 {
1197     TCGv_i64 t0 = tcg_temp_new_i64();
1198     TCGv_i64 t1 = tcg_temp_new_i64();
1199
1200     tcg_gen_muls2_i64(t0, t1, cpu_gpr[rA(ctx->opcode)],
1201                       cpu_gpr[rB(ctx->opcode)]);
1202     tcg_gen_mov_i64(cpu_gpr[rD(ctx->opcode)], t0);
1203
1204     tcg_gen_sari_i64(t0, t0, 63);
1205     tcg_gen_setcond_i64(TCG_COND_NE, cpu_ov, t0, t1);
1206     tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov);
1207
1208     tcg_temp_free_i64(t0);
1209     tcg_temp_free_i64(t1);
1210
1211     if (unlikely(Rc(ctx->opcode) != 0)) {
1212         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1213     }
1214 }
1215 #endif
1216
1217 /* Common subf function */
1218 static inline void gen_op_arith_subf(DisasContext *ctx, TCGv ret, TCGv arg1,
1219                                      TCGv arg2, bool add_ca, bool compute_ca,
1220                                      bool compute_ov, bool compute_rc0)
1221 {
1222     TCGv t0 = ret;
1223
1224     if (compute_ca || compute_ov) {
1225         t0 = tcg_temp_new();
1226     }
1227
1228     if (compute_ca) {
1229         /* dest = ~arg1 + arg2 [+ ca].  */
1230         if (NARROW_MODE(ctx)) {
1231             /* Caution: a non-obvious corner case of the spec is that we
1232                must produce the *entire* 64-bit addition, but produce the
1233                carry into bit 32.  */
1234             TCGv inv1 = tcg_temp_new();
1235             TCGv t1 = tcg_temp_new();
1236             tcg_gen_not_tl(inv1, arg1);
1237             if (add_ca) {
1238                 tcg_gen_add_tl(t0, arg2, cpu_ca);
1239             } else {
1240                 tcg_gen_addi_tl(t0, arg2, 1);
1241             }
1242             tcg_gen_xor_tl(t1, arg2, inv1);         /* add without carry */
1243             tcg_gen_add_tl(t0, t0, inv1);
1244             tcg_temp_free(inv1);
1245             tcg_gen_xor_tl(cpu_ca, t0, t1);         /* bits changes w/ carry */
1246             tcg_temp_free(t1);
1247             tcg_gen_shri_tl(cpu_ca, cpu_ca, 32);    /* extract bit 32 */
1248             tcg_gen_andi_tl(cpu_ca, cpu_ca, 1);
1249         } else if (add_ca) {
1250             TCGv zero, inv1 = tcg_temp_new();
1251             tcg_gen_not_tl(inv1, arg1);
1252             zero = tcg_const_tl(0);
1253             tcg_gen_add2_tl(t0, cpu_ca, arg2, zero, cpu_ca, zero);
1254             tcg_gen_add2_tl(t0, cpu_ca, t0, cpu_ca, inv1, zero);
1255             tcg_temp_free(zero);
1256             tcg_temp_free(inv1);
1257         } else {
1258             tcg_gen_setcond_tl(TCG_COND_GEU, cpu_ca, arg2, arg1);
1259             tcg_gen_sub_tl(t0, arg2, arg1);
1260         }
1261     } else if (add_ca) {
1262         /* Since we're ignoring carry-out, we can simplify the
1263            standard ~arg1 + arg2 + ca to arg2 - arg1 + ca - 1.  */
1264         tcg_gen_sub_tl(t0, arg2, arg1);
1265         tcg_gen_add_tl(t0, t0, cpu_ca);
1266         tcg_gen_subi_tl(t0, t0, 1);
1267     } else {
1268         tcg_gen_sub_tl(t0, arg2, arg1);
1269     }
1270
1271     if (compute_ov) {
1272         gen_op_arith_compute_ov(ctx, t0, arg1, arg2, 1);
1273     }
1274     if (unlikely(compute_rc0)) {
1275         gen_set_Rc0(ctx, t0);
1276     }
1277
1278     if (!TCGV_EQUAL(t0, ret)) {
1279         tcg_gen_mov_tl(ret, t0);
1280         tcg_temp_free(t0);
1281     }
1282 }
1283 /* Sub functions with Two operands functions */
1284 #define GEN_INT_ARITH_SUBF(name, opc3, add_ca, compute_ca, compute_ov)        \
1285 static void glue(gen_, name)(DisasContext *ctx)                               \
1286 {                                                                             \
1287     gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)],                          \
1288                       cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],     \
1289                       add_ca, compute_ca, compute_ov, Rc(ctx->opcode));       \
1290 }
1291 /* Sub functions with one operand and one immediate */
1292 #define GEN_INT_ARITH_SUBF_CONST(name, opc3, const_val,                       \
1293                                 add_ca, compute_ca, compute_ov)               \
1294 static void glue(gen_, name)(DisasContext *ctx)                               \
1295 {                                                                             \
1296     TCGv t0 = tcg_const_tl(const_val);                                        \
1297     gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)],                          \
1298                       cpu_gpr[rA(ctx->opcode)], t0,                           \
1299                       add_ca, compute_ca, compute_ov, Rc(ctx->opcode));       \
1300     tcg_temp_free(t0);                                                        \
1301 }
1302 /* subf  subf.  subfo  subfo. */
1303 GEN_INT_ARITH_SUBF(subf, 0x01, 0, 0, 0)
1304 GEN_INT_ARITH_SUBF(subfo, 0x11, 0, 0, 1)
1305 /* subfc  subfc.  subfco  subfco. */
1306 GEN_INT_ARITH_SUBF(subfc, 0x00, 0, 1, 0)
1307 GEN_INT_ARITH_SUBF(subfco, 0x10, 0, 1, 1)
1308 /* subfe  subfe.  subfeo  subfo. */
1309 GEN_INT_ARITH_SUBF(subfe, 0x04, 1, 1, 0)
1310 GEN_INT_ARITH_SUBF(subfeo, 0x14, 1, 1, 1)
1311 /* subfme  subfme.  subfmeo  subfmeo.  */
1312 GEN_INT_ARITH_SUBF_CONST(subfme, 0x07, -1LL, 1, 1, 0)
1313 GEN_INT_ARITH_SUBF_CONST(subfmeo, 0x17, -1LL, 1, 1, 1)
1314 /* subfze  subfze.  subfzeo  subfzeo.*/
1315 GEN_INT_ARITH_SUBF_CONST(subfze, 0x06, 0, 1, 1, 0)
1316 GEN_INT_ARITH_SUBF_CONST(subfzeo, 0x16, 0, 1, 1, 1)
1317
1318 /* subfic */
1319 static void gen_subfic(DisasContext *ctx)
1320 {
1321     TCGv c = tcg_const_tl(SIMM(ctx->opcode));
1322     gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
1323                       c, 0, 1, 0, 0);
1324     tcg_temp_free(c);
1325 }
1326
1327 /* neg neg. nego nego. */
1328 static inline void gen_op_arith_neg(DisasContext *ctx, bool compute_ov)
1329 {
1330     TCGv zero = tcg_const_tl(0);
1331     gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
1332                       zero, 0, 0, compute_ov, Rc(ctx->opcode));
1333     tcg_temp_free(zero);
1334 }
1335
1336 static void gen_neg(DisasContext *ctx)
1337 {
1338     gen_op_arith_neg(ctx, 0);
1339 }
1340
1341 static void gen_nego(DisasContext *ctx)
1342 {
1343     gen_op_arith_neg(ctx, 1);
1344 }
1345
1346 /***                            Integer logical                            ***/
1347 #define GEN_LOGICAL2(name, tcg_op, opc, type)                                 \
1348 static void glue(gen_, name)(DisasContext *ctx)                                       \
1349 {                                                                             \
1350     tcg_op(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)],                \
1351        cpu_gpr[rB(ctx->opcode)]);                                             \
1352     if (unlikely(Rc(ctx->opcode) != 0))                                       \
1353         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);                           \
1354 }
1355
1356 #define GEN_LOGICAL1(name, tcg_op, opc, type)                                 \
1357 static void glue(gen_, name)(DisasContext *ctx)                                       \
1358 {                                                                             \
1359     tcg_op(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);               \
1360     if (unlikely(Rc(ctx->opcode) != 0))                                       \
1361         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);                           \
1362 }
1363
1364 /* and & and. */
1365 GEN_LOGICAL2(and, tcg_gen_and_tl, 0x00, PPC_INTEGER);
1366 /* andc & andc. */
1367 GEN_LOGICAL2(andc, tcg_gen_andc_tl, 0x01, PPC_INTEGER);
1368
1369 /* andi. */
1370 static void gen_andi_(DisasContext *ctx)
1371 {
1372     tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], UIMM(ctx->opcode));
1373     gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1374 }
1375
1376 /* andis. */
1377 static void gen_andis_(DisasContext *ctx)
1378 {
1379     tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], UIMM(ctx->opcode) << 16);
1380     gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1381 }
1382
1383 /* cntlzw */
1384 static void gen_cntlzw(DisasContext *ctx)
1385 {
1386     gen_helper_cntlzw(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1387     if (unlikely(Rc(ctx->opcode) != 0))
1388         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1389 }
1390 /* eqv & eqv. */
1391 GEN_LOGICAL2(eqv, tcg_gen_eqv_tl, 0x08, PPC_INTEGER);
1392 /* extsb & extsb. */
1393 GEN_LOGICAL1(extsb, tcg_gen_ext8s_tl, 0x1D, PPC_INTEGER);
1394 /* extsh & extsh. */
1395 GEN_LOGICAL1(extsh, tcg_gen_ext16s_tl, 0x1C, PPC_INTEGER);
1396 /* nand & nand. */
1397 GEN_LOGICAL2(nand, tcg_gen_nand_tl, 0x0E, PPC_INTEGER);
1398 /* nor & nor. */
1399 GEN_LOGICAL2(nor, tcg_gen_nor_tl, 0x03, PPC_INTEGER);
1400
1401 /* or & or. */
1402 static void gen_or(DisasContext *ctx)
1403 {
1404     int rs, ra, rb;
1405
1406     rs = rS(ctx->opcode);
1407     ra = rA(ctx->opcode);
1408     rb = rB(ctx->opcode);
1409     /* Optimisation for mr. ri case */
1410     if (rs != ra || rs != rb) {
1411         if (rs != rb)
1412             tcg_gen_or_tl(cpu_gpr[ra], cpu_gpr[rs], cpu_gpr[rb]);
1413         else
1414             tcg_gen_mov_tl(cpu_gpr[ra], cpu_gpr[rs]);
1415         if (unlikely(Rc(ctx->opcode) != 0))
1416             gen_set_Rc0(ctx, cpu_gpr[ra]);
1417     } else if (unlikely(Rc(ctx->opcode) != 0)) {
1418         gen_set_Rc0(ctx, cpu_gpr[rs]);
1419 #if defined(TARGET_PPC64)
1420     } else {
1421         int prio = 0;
1422
1423         switch (rs) {
1424         case 1:
1425             /* Set process priority to low */
1426             prio = 2;
1427             break;
1428         case 6:
1429             /* Set process priority to medium-low */
1430             prio = 3;
1431             break;
1432         case 2:
1433             /* Set process priority to normal */
1434             prio = 4;
1435             break;
1436 #if !defined(CONFIG_USER_ONLY)
1437         case 31:
1438             if (!ctx->pr) {
1439                 /* Set process priority to very low */
1440                 prio = 1;
1441             }
1442             break;
1443         case 5:
1444             if (!ctx->pr) {
1445                 /* Set process priority to medium-hight */
1446                 prio = 5;
1447             }
1448             break;
1449         case 3:
1450             if (!ctx->pr) {
1451                 /* Set process priority to high */
1452                 prio = 6;
1453             }
1454             break;
1455         case 7:
1456             if (ctx->hv) {
1457                 /* Set process priority to very high */
1458                 prio = 7;
1459             }
1460             break;
1461 #endif
1462         default:
1463             /* nop */
1464             break;
1465         }
1466         if (prio) {
1467             TCGv t0 = tcg_temp_new();
1468             gen_load_spr(t0, SPR_PPR);
1469             tcg_gen_andi_tl(t0, t0, ~0x001C000000000000ULL);
1470             tcg_gen_ori_tl(t0, t0, ((uint64_t)prio) << 50);
1471             gen_store_spr(SPR_PPR, t0);
1472             tcg_temp_free(t0);
1473         }
1474 #endif
1475     }
1476 }
1477 /* orc & orc. */
1478 GEN_LOGICAL2(orc, tcg_gen_orc_tl, 0x0C, PPC_INTEGER);
1479
1480 /* xor & xor. */
1481 static void gen_xor(DisasContext *ctx)
1482 {
1483     /* Optimisation for "set to zero" case */
1484     if (rS(ctx->opcode) != rB(ctx->opcode))
1485         tcg_gen_xor_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1486     else
1487         tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
1488     if (unlikely(Rc(ctx->opcode) != 0))
1489         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1490 }
1491
1492 /* ori */
1493 static void gen_ori(DisasContext *ctx)
1494 {
1495     target_ulong uimm = UIMM(ctx->opcode);
1496
1497     if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1498         /* NOP */
1499         /* XXX: should handle special NOPs for POWER series */
1500         return;
1501     }
1502     tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm);
1503 }
1504
1505 /* oris */
1506 static void gen_oris(DisasContext *ctx)
1507 {
1508     target_ulong uimm = UIMM(ctx->opcode);
1509
1510     if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1511         /* NOP */
1512         return;
1513     }
1514     tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm << 16);
1515 }
1516
1517 /* xori */
1518 static void gen_xori(DisasContext *ctx)
1519 {
1520     target_ulong uimm = UIMM(ctx->opcode);
1521
1522     if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1523         /* NOP */
1524         return;
1525     }
1526     tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm);
1527 }
1528
1529 /* xoris */
1530 static void gen_xoris(DisasContext *ctx)
1531 {
1532     target_ulong uimm = UIMM(ctx->opcode);
1533
1534     if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1535         /* NOP */
1536         return;
1537     }
1538     tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm << 16);
1539 }
1540
1541 /* popcntb : PowerPC 2.03 specification */
1542 static void gen_popcntb(DisasContext *ctx)
1543 {
1544     gen_helper_popcntb(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1545 }
1546
1547 static void gen_popcntw(DisasContext *ctx)
1548 {
1549     gen_helper_popcntw(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1550 }
1551
1552 #if defined(TARGET_PPC64)
1553 /* popcntd: PowerPC 2.06 specification */
1554 static void gen_popcntd(DisasContext *ctx)
1555 {
1556     gen_helper_popcntd(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1557 }
1558 #endif
1559
1560 /* prtyw: PowerPC 2.05 specification */
1561 static void gen_prtyw(DisasContext *ctx)
1562 {
1563     TCGv ra = cpu_gpr[rA(ctx->opcode)];
1564     TCGv rs = cpu_gpr[rS(ctx->opcode)];
1565     TCGv t0 = tcg_temp_new();
1566     tcg_gen_shri_tl(t0, rs, 16);
1567     tcg_gen_xor_tl(ra, rs, t0);
1568     tcg_gen_shri_tl(t0, ra, 8);
1569     tcg_gen_xor_tl(ra, ra, t0);
1570     tcg_gen_andi_tl(ra, ra, (target_ulong)0x100000001ULL);
1571     tcg_temp_free(t0);
1572 }
1573
1574 #if defined(TARGET_PPC64)
1575 /* prtyd: PowerPC 2.05 specification */
1576 static void gen_prtyd(DisasContext *ctx)
1577 {
1578     TCGv ra = cpu_gpr[rA(ctx->opcode)];
1579     TCGv rs = cpu_gpr[rS(ctx->opcode)];
1580     TCGv t0 = tcg_temp_new();
1581     tcg_gen_shri_tl(t0, rs, 32);
1582     tcg_gen_xor_tl(ra, rs, t0);
1583     tcg_gen_shri_tl(t0, ra, 16);
1584     tcg_gen_xor_tl(ra, ra, t0);
1585     tcg_gen_shri_tl(t0, ra, 8);
1586     tcg_gen_xor_tl(ra, ra, t0);
1587     tcg_gen_andi_tl(ra, ra, 1);
1588     tcg_temp_free(t0);
1589 }
1590 #endif
1591
1592 #if defined(TARGET_PPC64)
1593 /* bpermd */
1594 static void gen_bpermd(DisasContext *ctx)
1595 {
1596     gen_helper_bpermd(cpu_gpr[rA(ctx->opcode)],
1597                       cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1598 }
1599 #endif
1600
1601 #if defined(TARGET_PPC64)
1602 /* extsw & extsw. */
1603 GEN_LOGICAL1(extsw, tcg_gen_ext32s_tl, 0x1E, PPC_64B);
1604
1605 /* cntlzd */
1606 static void gen_cntlzd(DisasContext *ctx)
1607 {
1608     gen_helper_cntlzd(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1609     if (unlikely(Rc(ctx->opcode) != 0))
1610         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1611 }
1612 #endif
1613
1614 /***                             Integer rotate                            ***/
1615
1616 /* rlwimi & rlwimi. */
1617 static void gen_rlwimi(DisasContext *ctx)
1618 {
1619     uint32_t mb, me, sh;
1620
1621     mb = MB(ctx->opcode);
1622     me = ME(ctx->opcode);
1623     sh = SH(ctx->opcode);
1624     if (likely(sh == (31-me) && mb <= me)) {
1625         tcg_gen_deposit_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
1626                            cpu_gpr[rS(ctx->opcode)], sh, me - mb + 1);
1627     } else {
1628         target_ulong mask;
1629         TCGv t1;
1630         TCGv t0 = tcg_temp_new();
1631 #if defined(TARGET_PPC64)
1632         tcg_gen_deposit_i64(t0, cpu_gpr[rS(ctx->opcode)],
1633             cpu_gpr[rS(ctx->opcode)], 32, 32);
1634         tcg_gen_rotli_i64(t0, t0, sh);
1635 #else
1636         tcg_gen_rotli_i32(t0, cpu_gpr[rS(ctx->opcode)], sh);
1637 #endif
1638 #if defined(TARGET_PPC64)
1639         mb += 32;
1640         me += 32;
1641 #endif
1642         mask = MASK(mb, me);
1643         t1 = tcg_temp_new();
1644         tcg_gen_andi_tl(t0, t0, mask);
1645         tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], ~mask);
1646         tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
1647         tcg_temp_free(t0);
1648         tcg_temp_free(t1);
1649     }
1650     if (unlikely(Rc(ctx->opcode) != 0))
1651         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1652 }
1653
1654 /* rlwinm & rlwinm. */
1655 static void gen_rlwinm(DisasContext *ctx)
1656 {
1657     uint32_t mb, me, sh;
1658
1659     sh = SH(ctx->opcode);
1660     mb = MB(ctx->opcode);
1661     me = ME(ctx->opcode);
1662
1663     if (likely(mb == 0 && me == (31 - sh))) {
1664         if (likely(sh == 0)) {
1665             tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1666         } else {
1667             TCGv t0 = tcg_temp_new();
1668             tcg_gen_ext32u_tl(t0, cpu_gpr[rS(ctx->opcode)]);
1669             tcg_gen_shli_tl(t0, t0, sh);
1670             tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], t0);
1671             tcg_temp_free(t0);
1672         }
1673     } else if (likely(sh != 0 && me == 31 && sh == (32 - mb))) {
1674         TCGv t0 = tcg_temp_new();
1675         tcg_gen_ext32u_tl(t0, cpu_gpr[rS(ctx->opcode)]);
1676         tcg_gen_shri_tl(t0, t0, mb);
1677         tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], t0);
1678         tcg_temp_free(t0);
1679     } else if (likely(mb == 0 && me == 31)) {
1680         TCGv_i32 t0 = tcg_temp_new_i32();
1681         tcg_gen_trunc_tl_i32(t0, cpu_gpr[rS(ctx->opcode)]);
1682         tcg_gen_rotli_i32(t0, t0, sh);
1683         tcg_gen_extu_i32_tl(cpu_gpr[rA(ctx->opcode)], t0);
1684         tcg_temp_free_i32(t0);
1685     } else {
1686         TCGv t0 = tcg_temp_new();
1687 #if defined(TARGET_PPC64)
1688         tcg_gen_deposit_i64(t0, cpu_gpr[rS(ctx->opcode)],
1689             cpu_gpr[rS(ctx->opcode)], 32, 32);
1690         tcg_gen_rotli_i64(t0, t0, sh);
1691 #else
1692         tcg_gen_rotli_i32(t0, cpu_gpr[rS(ctx->opcode)], sh);
1693 #endif
1694 #if defined(TARGET_PPC64)
1695         mb += 32;
1696         me += 32;
1697 #endif
1698         tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t0, MASK(mb, me));
1699         tcg_temp_free(t0);
1700     }
1701     if (unlikely(Rc(ctx->opcode) != 0))
1702         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1703 }
1704
1705 /* rlwnm & rlwnm. */
1706 static void gen_rlwnm(DisasContext *ctx)
1707 {
1708     uint32_t mb, me;
1709     mb = MB(ctx->opcode);
1710     me = ME(ctx->opcode);
1711
1712     if (likely(mb == 0 && me == 31)) {
1713         TCGv_i32 t0, t1;
1714         t0 = tcg_temp_new_i32();
1715         t1 = tcg_temp_new_i32();
1716         tcg_gen_trunc_tl_i32(t0, cpu_gpr[rB(ctx->opcode)]);
1717         tcg_gen_trunc_tl_i32(t1, cpu_gpr[rS(ctx->opcode)]);
1718         tcg_gen_andi_i32(t0, t0, 0x1f);
1719         tcg_gen_rotl_i32(t1, t1, t0);
1720         tcg_gen_extu_i32_tl(cpu_gpr[rA(ctx->opcode)], t1);
1721         tcg_temp_free_i32(t0);
1722         tcg_temp_free_i32(t1);
1723     } else {
1724         TCGv t0;
1725 #if defined(TARGET_PPC64)
1726         TCGv t1;
1727 #endif
1728
1729         t0 = tcg_temp_new();
1730         tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1f);
1731 #if defined(TARGET_PPC64)
1732         t1 = tcg_temp_new_i64();
1733         tcg_gen_deposit_i64(t1, cpu_gpr[rS(ctx->opcode)],
1734                             cpu_gpr[rS(ctx->opcode)], 32, 32);
1735         tcg_gen_rotl_i64(t0, t1, t0);
1736         tcg_temp_free_i64(t1);
1737 #else
1738         tcg_gen_rotl_i32(t0, cpu_gpr[rS(ctx->opcode)], t0);
1739 #endif
1740         if (unlikely(mb != 0 || me != 31)) {
1741 #if defined(TARGET_PPC64)
1742             mb += 32;
1743             me += 32;
1744 #endif
1745             tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t0, MASK(mb, me));
1746         } else {
1747             tcg_gen_andi_tl(t0, t0, MASK(32, 63));
1748             tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
1749         }
1750         tcg_temp_free(t0);
1751     }
1752     if (unlikely(Rc(ctx->opcode) != 0))
1753         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1754 }
1755
1756 #if defined(TARGET_PPC64)
1757 #define GEN_PPC64_R2(name, opc1, opc2)                                        \
1758 static void glue(gen_, name##0)(DisasContext *ctx)                            \
1759 {                                                                             \
1760     gen_##name(ctx, 0);                                                       \
1761 }                                                                             \
1762                                                                               \
1763 static void glue(gen_, name##1)(DisasContext *ctx)                            \
1764 {                                                                             \
1765     gen_##name(ctx, 1);                                                       \
1766 }
1767 #define GEN_PPC64_R4(name, opc1, opc2)                                        \
1768 static void glue(gen_, name##0)(DisasContext *ctx)                            \
1769 {                                                                             \
1770     gen_##name(ctx, 0, 0);                                                    \
1771 }                                                                             \
1772                                                                               \
1773 static void glue(gen_, name##1)(DisasContext *ctx)                            \
1774 {                                                                             \
1775     gen_##name(ctx, 0, 1);                                                    \
1776 }                                                                             \
1777                                                                               \
1778 static void glue(gen_, name##2)(DisasContext *ctx)                            \
1779 {                                                                             \
1780     gen_##name(ctx, 1, 0);                                                    \
1781 }                                                                             \
1782                                                                               \
1783 static void glue(gen_, name##3)(DisasContext *ctx)                            \
1784 {                                                                             \
1785     gen_##name(ctx, 1, 1);                                                    \
1786 }
1787
1788 static inline void gen_rldinm(DisasContext *ctx, uint32_t mb, uint32_t me,
1789                               uint32_t sh)
1790 {
1791     if (likely(sh != 0 && mb == 0 && me == (63 - sh))) {
1792         tcg_gen_shli_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], sh);
1793     } else if (likely(sh != 0 && me == 63 && sh == (64 - mb))) {
1794         tcg_gen_shri_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], mb);
1795     } else {
1796         TCGv t0 = tcg_temp_new();
1797         tcg_gen_rotli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
1798         if (likely(mb == 0 && me == 63)) {
1799             tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
1800         } else {
1801             tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t0, MASK(mb, me));
1802         }
1803         tcg_temp_free(t0);
1804     }
1805     if (unlikely(Rc(ctx->opcode) != 0))
1806         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1807 }
1808 /* rldicl - rldicl. */
1809 static inline void gen_rldicl(DisasContext *ctx, int mbn, int shn)
1810 {
1811     uint32_t sh, mb;
1812
1813     sh = SH(ctx->opcode) | (shn << 5);
1814     mb = MB(ctx->opcode) | (mbn << 5);
1815     gen_rldinm(ctx, mb, 63, sh);
1816 }
1817 GEN_PPC64_R4(rldicl, 0x1E, 0x00);
1818 /* rldicr - rldicr. */
1819 static inline void gen_rldicr(DisasContext *ctx, int men, int shn)
1820 {
1821     uint32_t sh, me;
1822
1823     sh = SH(ctx->opcode) | (shn << 5);
1824     me = MB(ctx->opcode) | (men << 5);
1825     gen_rldinm(ctx, 0, me, sh);
1826 }
1827 GEN_PPC64_R4(rldicr, 0x1E, 0x02);
1828 /* rldic - rldic. */
1829 static inline void gen_rldic(DisasContext *ctx, int mbn, int shn)
1830 {
1831     uint32_t sh, mb;
1832
1833     sh = SH(ctx->opcode) | (shn << 5);
1834     mb = MB(ctx->opcode) | (mbn << 5);
1835     gen_rldinm(ctx, mb, 63 - sh, sh);
1836 }
1837 GEN_PPC64_R4(rldic, 0x1E, 0x04);
1838
1839 static inline void gen_rldnm(DisasContext *ctx, uint32_t mb, uint32_t me)
1840 {
1841     TCGv t0;
1842
1843     t0 = tcg_temp_new();
1844     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3f);
1845     tcg_gen_rotl_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
1846     if (unlikely(mb != 0 || me != 63)) {
1847         tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t0, MASK(mb, me));
1848     } else {
1849         tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
1850     }
1851     tcg_temp_free(t0);
1852     if (unlikely(Rc(ctx->opcode) != 0))
1853         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1854 }
1855
1856 /* rldcl - rldcl. */
1857 static inline void gen_rldcl(DisasContext *ctx, int mbn)
1858 {
1859     uint32_t mb;
1860
1861     mb = MB(ctx->opcode) | (mbn << 5);
1862     gen_rldnm(ctx, mb, 63);
1863 }
1864 GEN_PPC64_R2(rldcl, 0x1E, 0x08);
1865 /* rldcr - rldcr. */
1866 static inline void gen_rldcr(DisasContext *ctx, int men)
1867 {
1868     uint32_t me;
1869
1870     me = MB(ctx->opcode) | (men << 5);
1871     gen_rldnm(ctx, 0, me);
1872 }
1873 GEN_PPC64_R2(rldcr, 0x1E, 0x09);
1874 /* rldimi - rldimi. */
1875 static inline void gen_rldimi(DisasContext *ctx, int mbn, int shn)
1876 {
1877     uint32_t sh, mb, me;
1878
1879     sh = SH(ctx->opcode) | (shn << 5);
1880     mb = MB(ctx->opcode) | (mbn << 5);
1881     me = 63 - sh;
1882     if (unlikely(sh == 0 && mb == 0)) {
1883         tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1884     } else {
1885         TCGv t0, t1;
1886         target_ulong mask;
1887
1888         t0 = tcg_temp_new();
1889         tcg_gen_rotli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
1890         t1 = tcg_temp_new();
1891         mask = MASK(mb, me);
1892         tcg_gen_andi_tl(t0, t0, mask);
1893         tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], ~mask);
1894         tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
1895         tcg_temp_free(t0);
1896         tcg_temp_free(t1);
1897     }
1898     if (unlikely(Rc(ctx->opcode) != 0))
1899         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1900 }
1901 GEN_PPC64_R4(rldimi, 0x1E, 0x06);
1902 #endif
1903
1904 /***                             Integer shift                             ***/
1905
1906 /* slw & slw. */
1907 static void gen_slw(DisasContext *ctx)
1908 {
1909     TCGv t0, t1;
1910
1911     t0 = tcg_temp_new();
1912     /* AND rS with a mask that is 0 when rB >= 0x20 */
1913 #if defined(TARGET_PPC64)
1914     tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3a);
1915     tcg_gen_sari_tl(t0, t0, 0x3f);
1916 #else
1917     tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1a);
1918     tcg_gen_sari_tl(t0, t0, 0x1f);
1919 #endif
1920     tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
1921     t1 = tcg_temp_new();
1922     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1f);
1923     tcg_gen_shl_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
1924     tcg_temp_free(t1);
1925     tcg_temp_free(t0);
1926     tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
1927     if (unlikely(Rc(ctx->opcode) != 0))
1928         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1929 }
1930
1931 /* sraw & sraw. */
1932 static void gen_sraw(DisasContext *ctx)
1933 {
1934     gen_helper_sraw(cpu_gpr[rA(ctx->opcode)], cpu_env,
1935                     cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1936     if (unlikely(Rc(ctx->opcode) != 0))
1937         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1938 }
1939
1940 /* srawi & srawi. */
1941 static void gen_srawi(DisasContext *ctx)
1942 {
1943     int sh = SH(ctx->opcode);
1944     TCGv dst = cpu_gpr[rA(ctx->opcode)];
1945     TCGv src = cpu_gpr[rS(ctx->opcode)];
1946     if (sh == 0) {
1947         tcg_gen_ext32s_tl(dst, src);
1948         tcg_gen_movi_tl(cpu_ca, 0);
1949     } else {
1950         TCGv t0;
1951         tcg_gen_ext32s_tl(dst, src);
1952         tcg_gen_andi_tl(cpu_ca, dst, (1ULL << sh) - 1);
1953         t0 = tcg_temp_new();
1954         tcg_gen_sari_tl(t0, dst, TARGET_LONG_BITS - 1);
1955         tcg_gen_and_tl(cpu_ca, cpu_ca, t0);
1956         tcg_temp_free(t0);
1957         tcg_gen_setcondi_tl(TCG_COND_NE, cpu_ca, cpu_ca, 0);
1958         tcg_gen_sari_tl(dst, dst, sh);
1959     }
1960     if (unlikely(Rc(ctx->opcode) != 0)) {
1961         gen_set_Rc0(ctx, dst);
1962     }
1963 }
1964
1965 /* srw & srw. */
1966 static void gen_srw(DisasContext *ctx)
1967 {
1968     TCGv t0, t1;
1969
1970     t0 = tcg_temp_new();
1971     /* AND rS with a mask that is 0 when rB >= 0x20 */
1972 #if defined(TARGET_PPC64)
1973     tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3a);
1974     tcg_gen_sari_tl(t0, t0, 0x3f);
1975 #else
1976     tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1a);
1977     tcg_gen_sari_tl(t0, t0, 0x1f);
1978 #endif
1979     tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
1980     tcg_gen_ext32u_tl(t0, t0);
1981     t1 = tcg_temp_new();
1982     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1f);
1983     tcg_gen_shr_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
1984     tcg_temp_free(t1);
1985     tcg_temp_free(t0);
1986     if (unlikely(Rc(ctx->opcode) != 0))
1987         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1988 }
1989
1990 #if defined(TARGET_PPC64)
1991 /* sld & sld. */
1992 static void gen_sld(DisasContext *ctx)
1993 {
1994     TCGv t0, t1;
1995
1996     t0 = tcg_temp_new();
1997     /* AND rS with a mask that is 0 when rB >= 0x40 */
1998     tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x39);
1999     tcg_gen_sari_tl(t0, t0, 0x3f);
2000     tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
2001     t1 = tcg_temp_new();
2002     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x3f);
2003     tcg_gen_shl_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
2004     tcg_temp_free(t1);
2005     tcg_temp_free(t0);
2006     if (unlikely(Rc(ctx->opcode) != 0))
2007         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
2008 }
2009
2010 /* srad & srad. */
2011 static void gen_srad(DisasContext *ctx)
2012 {
2013     gen_helper_srad(cpu_gpr[rA(ctx->opcode)], cpu_env,
2014                     cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
2015     if (unlikely(Rc(ctx->opcode) != 0))
2016         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
2017 }
2018 /* sradi & sradi. */
2019 static inline void gen_sradi(DisasContext *ctx, int n)
2020 {
2021     int sh = SH(ctx->opcode) + (n << 5);
2022     TCGv dst = cpu_gpr[rA(ctx->opcode)];
2023     TCGv src = cpu_gpr[rS(ctx->opcode)];
2024     if (sh == 0) {
2025         tcg_gen_mov_tl(dst, src);
2026         tcg_gen_movi_tl(cpu_ca, 0);
2027     } else {
2028         TCGv t0;
2029         tcg_gen_andi_tl(cpu_ca, src, (1ULL << sh) - 1);
2030         t0 = tcg_temp_new();
2031         tcg_gen_sari_tl(t0, src, TARGET_LONG_BITS - 1);
2032         tcg_gen_and_tl(cpu_ca, cpu_ca, t0);
2033         tcg_temp_free(t0);
2034         tcg_gen_setcondi_tl(TCG_COND_NE, cpu_ca, cpu_ca, 0);
2035         tcg_gen_sari_tl(dst, src, sh);
2036     }
2037     if (unlikely(Rc(ctx->opcode) != 0)) {
2038         gen_set_Rc0(ctx, dst);
2039     }
2040 }
2041
2042 static void gen_sradi0(DisasContext *ctx)
2043 {
2044     gen_sradi(ctx, 0);
2045 }
2046
2047 static void gen_sradi1(DisasContext *ctx)
2048 {
2049     gen_sradi(ctx, 1);
2050 }
2051
2052 /* srd & srd. */
2053 static void gen_srd(DisasContext *ctx)
2054 {
2055     TCGv t0, t1;
2056
2057     t0 = tcg_temp_new();
2058     /* AND rS with a mask that is 0 when rB >= 0x40 */
2059     tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x39);
2060     tcg_gen_sari_tl(t0, t0, 0x3f);
2061     tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
2062     t1 = tcg_temp_new();
2063     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x3f);
2064     tcg_gen_shr_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
2065     tcg_temp_free(t1);
2066     tcg_temp_free(t0);
2067     if (unlikely(Rc(ctx->opcode) != 0))
2068         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
2069 }
2070 #endif
2071
2072 #if defined(TARGET_PPC64)
2073 static void gen_set_cr1_from_fpscr(DisasContext *ctx)
2074 {
2075     TCGv_i32 tmp = tcg_temp_new_i32();
2076     tcg_gen_trunc_tl_i32(tmp, cpu_fpscr);
2077     tcg_gen_shri_i32(cpu_crf[1], tmp, 28);
2078     tcg_temp_free_i32(tmp);
2079 }
2080 #else
2081 static void gen_set_cr1_from_fpscr(DisasContext *ctx)
2082 {
2083     tcg_gen_shri_tl(cpu_crf[1], cpu_fpscr, 28);
2084 }
2085 #endif
2086
2087 /***                       Floating-Point arithmetic                       ***/
2088 #define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat, set_fprf, type)           \
2089 static void gen_f##name(DisasContext *ctx)                                    \
2090 {                                                                             \
2091     if (unlikely(!ctx->fpu_enabled)) {                                        \
2092         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
2093         return;                                                               \
2094     }                                                                         \
2095     /* NIP cannot be restored if the memory exception comes from an helper */ \
2096     gen_update_nip(ctx, ctx->nip - 4);                                        \
2097     gen_reset_fpstatus();                                                     \
2098     gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_env,                       \
2099                      cpu_fpr[rA(ctx->opcode)],                                \
2100                      cpu_fpr[rC(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);     \
2101     if (isfloat) {                                                            \
2102         gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_env,                    \
2103                         cpu_fpr[rD(ctx->opcode)]);                            \
2104     }                                                                         \
2105     if (set_fprf) {                                                           \
2106         gen_compute_fprf(cpu_fpr[rD(ctx->opcode)]);                           \
2107     }                                                                         \
2108     if (unlikely(Rc(ctx->opcode) != 0)) {                                     \
2109         gen_set_cr1_from_fpscr(ctx);                                          \
2110     }                                                                         \
2111 }
2112
2113 #define GEN_FLOAT_ACB(name, op2, set_fprf, type)                              \
2114 _GEN_FLOAT_ACB(name, name, 0x3F, op2, 0, set_fprf, type);                     \
2115 _GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, set_fprf, type);
2116
2117 #define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
2118 static void gen_f##name(DisasContext *ctx)                                    \
2119 {                                                                             \
2120     if (unlikely(!ctx->fpu_enabled)) {                                        \
2121         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
2122         return;                                                               \
2123     }                                                                         \
2124     /* NIP cannot be restored if the memory exception comes from an helper */ \
2125     gen_update_nip(ctx, ctx->nip - 4);                                        \
2126     gen_reset_fpstatus();                                                     \
2127     gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_env,                       \
2128                      cpu_fpr[rA(ctx->opcode)],                                \
2129                      cpu_fpr[rB(ctx->opcode)]);                               \
2130     if (isfloat) {                                                            \
2131         gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_env,                    \
2132                         cpu_fpr[rD(ctx->opcode)]);                            \
2133     }                                                                         \
2134     if (set_fprf) {                                                           \
2135         gen_compute_fprf(cpu_fpr[rD(ctx->opcode)]);                           \
2136     }                                                                         \
2137     if (unlikely(Rc(ctx->opcode) != 0)) {                                     \
2138         gen_set_cr1_from_fpscr(ctx);                                          \
2139     }                                                                         \
2140 }
2141 #define GEN_FLOAT_AB(name, op2, inval, set_fprf, type)                        \
2142 _GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0, set_fprf, type);               \
2143 _GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1, set_fprf, type);
2144
2145 #define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
2146 static void gen_f##name(DisasContext *ctx)                                    \
2147 {                                                                             \
2148     if (unlikely(!ctx->fpu_enabled)) {                                        \
2149         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
2150         return;                                                               \
2151     }                                                                         \
2152     /* NIP cannot be restored if the memory exception comes from an helper */ \
2153     gen_update_nip(ctx, ctx->nip - 4);                                        \
2154     gen_reset_fpstatus();                                                     \
2155     gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_env,                       \
2156                      cpu_fpr[rA(ctx->opcode)],                                \
2157                      cpu_fpr[rC(ctx->opcode)]);                               \
2158     if (isfloat) {                                                            \
2159         gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_env,                    \
2160                         cpu_fpr[rD(ctx->opcode)]);                            \
2161     }                                                                         \
2162     if (set_fprf) {                                                           \
2163         gen_compute_fprf(cpu_fpr[rD(ctx->opcode)]);                           \
2164     }                                                                         \
2165     if (unlikely(Rc(ctx->opcode) != 0)) {                                     \
2166         gen_set_cr1_from_fpscr(ctx);                                          \
2167     }                                                                         \
2168 }
2169 #define GEN_FLOAT_AC(name, op2, inval, set_fprf, type)                        \
2170 _GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0, set_fprf, type);               \
2171 _GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1, set_fprf, type);
2172
2173 #define GEN_FLOAT_B(name, op2, op3, set_fprf, type)                           \
2174 static void gen_f##name(DisasContext *ctx)                                    \
2175 {                                                                             \
2176     if (unlikely(!ctx->fpu_enabled)) {                                        \
2177         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
2178         return;                                                               \
2179     }                                                                         \
2180     /* NIP cannot be restored if the memory exception comes from an helper */ \
2181     gen_update_nip(ctx, ctx->nip - 4);                                        \
2182     gen_reset_fpstatus();                                                     \
2183     gen_helper_f##name(cpu_fpr[rD(ctx->opcode)], cpu_env,                     \
2184                        cpu_fpr[rB(ctx->opcode)]);                             \
2185     if (set_fprf) {                                                           \
2186         gen_compute_fprf(cpu_fpr[rD(ctx->opcode)]);                           \
2187     }                                                                         \
2188     if (unlikely(Rc(ctx->opcode) != 0)) {                                     \
2189         gen_set_cr1_from_fpscr(ctx);                                          \
2190     }                                                                         \
2191 }
2192
2193 #define GEN_FLOAT_BS(name, op1, op2, set_fprf, type)                          \
2194 static void gen_f##name(DisasContext *ctx)                                    \
2195 {                                                                             \
2196     if (unlikely(!ctx->fpu_enabled)) {                                        \
2197         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
2198         return;                                                               \
2199     }                                                                         \
2200     /* NIP cannot be restored if the memory exception comes from an helper */ \
2201     gen_update_nip(ctx, ctx->nip - 4);                                        \
2202     gen_reset_fpstatus();                                                     \
2203     gen_helper_f##name(cpu_fpr[rD(ctx->opcode)], cpu_env,                     \
2204                        cpu_fpr[rB(ctx->opcode)]);                             \
2205     if (set_fprf) {                                                           \
2206         gen_compute_fprf(cpu_fpr[rD(ctx->opcode)]);                           \
2207     }                                                                         \
2208     if (unlikely(Rc(ctx->opcode) != 0)) {                                     \
2209         gen_set_cr1_from_fpscr(ctx);                                          \
2210     }                                                                         \
2211 }
2212
2213 /* fadd - fadds */
2214 GEN_FLOAT_AB(add, 0x15, 0x000007C0, 1, PPC_FLOAT);
2215 /* fdiv - fdivs */
2216 GEN_FLOAT_AB(div, 0x12, 0x000007C0, 1, PPC_FLOAT);
2217 /* fmul - fmuls */
2218 GEN_FLOAT_AC(mul, 0x19, 0x0000F800, 1, PPC_FLOAT);
2219
2220 /* fre */
2221 GEN_FLOAT_BS(re, 0x3F, 0x18, 1, PPC_FLOAT_EXT);
2222
2223 /* fres */
2224 GEN_FLOAT_BS(res, 0x3B, 0x18, 1, PPC_FLOAT_FRES);
2225
2226 /* frsqrte */
2227 GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A, 1, PPC_FLOAT_FRSQRTE);
2228
2229 /* frsqrtes */
2230 static void gen_frsqrtes(DisasContext *ctx)
2231 {
2232     if (unlikely(!ctx->fpu_enabled)) {
2233         gen_exception(ctx, POWERPC_EXCP_FPU);
2234         return;
2235     }
2236     /* NIP cannot be restored if the memory exception comes from an helper */
2237     gen_update_nip(ctx, ctx->nip - 4);
2238     gen_reset_fpstatus();
2239     gen_helper_frsqrte(cpu_fpr[rD(ctx->opcode)], cpu_env,
2240                        cpu_fpr[rB(ctx->opcode)]);
2241     gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_env,
2242                     cpu_fpr[rD(ctx->opcode)]);
2243     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)]);
2244     if (unlikely(Rc(ctx->opcode) != 0)) {
2245         gen_set_cr1_from_fpscr(ctx);
2246     }
2247 }
2248
2249 /* fsel */
2250 _GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0, 0, PPC_FLOAT_FSEL);
2251 /* fsub - fsubs */
2252 GEN_FLOAT_AB(sub, 0x14, 0x000007C0, 1, PPC_FLOAT);
2253 /* Optional: */
2254
2255 /* fsqrt */
2256 static void gen_fsqrt(DisasContext *ctx)
2257 {
2258     if (unlikely(!ctx->fpu_enabled)) {
2259         gen_exception(ctx, POWERPC_EXCP_FPU);
2260         return;
2261     }
2262     /* NIP cannot be restored if the memory exception comes from an helper */
2263     gen_update_nip(ctx, ctx->nip - 4);
2264     gen_reset_fpstatus();
2265     gen_helper_fsqrt(cpu_fpr[rD(ctx->opcode)], cpu_env,
2266                      cpu_fpr[rB(ctx->opcode)]);
2267     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)]);
2268     if (unlikely(Rc(ctx->opcode) != 0)) {
2269         gen_set_cr1_from_fpscr(ctx);
2270     }
2271 }
2272
2273 static void gen_fsqrts(DisasContext *ctx)
2274 {
2275     if (unlikely(!ctx->fpu_enabled)) {
2276         gen_exception(ctx, POWERPC_EXCP_FPU);
2277         return;
2278     }
2279     /* NIP cannot be restored if the memory exception comes from an helper */
2280     gen_update_nip(ctx, ctx->nip - 4);
2281     gen_reset_fpstatus();
2282     gen_helper_fsqrt(cpu_fpr[rD(ctx->opcode)], cpu_env,
2283                      cpu_fpr[rB(ctx->opcode)]);
2284     gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_env,
2285                     cpu_fpr[rD(ctx->opcode)]);
2286     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)]);
2287     if (unlikely(Rc(ctx->opcode) != 0)) {
2288         gen_set_cr1_from_fpscr(ctx);
2289     }
2290 }
2291
2292 /***                     Floating-Point multiply-and-add                   ***/
2293 /* fmadd - fmadds */
2294 GEN_FLOAT_ACB(madd, 0x1D, 1, PPC_FLOAT);
2295 /* fmsub - fmsubs */
2296 GEN_FLOAT_ACB(msub, 0x1C, 1, PPC_FLOAT);
2297 /* fnmadd - fnmadds */
2298 GEN_FLOAT_ACB(nmadd, 0x1F, 1, PPC_FLOAT);
2299 /* fnmsub - fnmsubs */
2300 GEN_FLOAT_ACB(nmsub, 0x1E, 1, PPC_FLOAT);
2301
2302 /***                     Floating-Point round & convert                    ***/
2303 /* fctiw */
2304 GEN_FLOAT_B(ctiw, 0x0E, 0x00, 0, PPC_FLOAT);
2305 /* fctiwu */
2306 GEN_FLOAT_B(ctiwu, 0x0E, 0x04, 0, PPC2_FP_CVT_ISA206);
2307 /* fctiwz */
2308 GEN_FLOAT_B(ctiwz, 0x0F, 0x00, 0, PPC_FLOAT);
2309 /* fctiwuz */
2310 GEN_FLOAT_B(ctiwuz, 0x0F, 0x04, 0, PPC2_FP_CVT_ISA206);
2311 /* frsp */
2312 GEN_FLOAT_B(rsp, 0x0C, 0x00, 1, PPC_FLOAT);
2313 /* fcfid */
2314 GEN_FLOAT_B(cfid, 0x0E, 0x1A, 1, PPC2_FP_CVT_S64);
2315 /* fcfids */
2316 GEN_FLOAT_B(cfids, 0x0E, 0x1A, 0, PPC2_FP_CVT_ISA206);
2317 /* fcfidu */
2318 GEN_FLOAT_B(cfidu, 0x0E, 0x1E, 0, PPC2_FP_CVT_ISA206);
2319 /* fcfidus */
2320 GEN_FLOAT_B(cfidus, 0x0E, 0x1E, 0, PPC2_FP_CVT_ISA206);
2321 /* fctid */
2322 GEN_FLOAT_B(ctid, 0x0E, 0x19, 0, PPC2_FP_CVT_S64);
2323 /* fctidu */
2324 GEN_FLOAT_B(ctidu, 0x0E, 0x1D, 0, PPC2_FP_CVT_ISA206);
2325 /* fctidz */
2326 GEN_FLOAT_B(ctidz, 0x0F, 0x19, 0, PPC2_FP_CVT_S64);
2327 /* fctidu */
2328 GEN_FLOAT_B(ctiduz, 0x0F, 0x1D, 0, PPC2_FP_CVT_ISA206);
2329
2330 /* frin */
2331 GEN_FLOAT_B(rin, 0x08, 0x0C, 1, PPC_FLOAT_EXT);
2332 /* friz */
2333 GEN_FLOAT_B(riz, 0x08, 0x0D, 1, PPC_FLOAT_EXT);
2334 /* frip */
2335 GEN_FLOAT_B(rip, 0x08, 0x0E, 1, PPC_FLOAT_EXT);
2336 /* frim */
2337 GEN_FLOAT_B(rim, 0x08, 0x0F, 1, PPC_FLOAT_EXT);
2338
2339 static void gen_ftdiv(DisasContext *ctx)
2340 {
2341     if (unlikely(!ctx->fpu_enabled)) {
2342         gen_exception(ctx, POWERPC_EXCP_FPU);
2343         return;
2344     }
2345     gen_helper_ftdiv(cpu_crf[crfD(ctx->opcode)], cpu_fpr[rA(ctx->opcode)],
2346                      cpu_fpr[rB(ctx->opcode)]);
2347 }
2348
2349 static void gen_ftsqrt(DisasContext *ctx)
2350 {
2351     if (unlikely(!ctx->fpu_enabled)) {
2352         gen_exception(ctx, POWERPC_EXCP_FPU);
2353         return;
2354     }
2355     gen_helper_ftsqrt(cpu_crf[crfD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
2356 }
2357
2358
2359
2360 /***                         Floating-Point compare                        ***/
2361
2362 /* fcmpo */
2363 static void gen_fcmpo(DisasContext *ctx)
2364 {
2365     TCGv_i32 crf;
2366     if (unlikely(!ctx->fpu_enabled)) {
2367         gen_exception(ctx, POWERPC_EXCP_FPU);
2368         return;
2369     }
2370     /* NIP cannot be restored if the memory exception comes from an helper */
2371     gen_update_nip(ctx, ctx->nip - 4);
2372     gen_reset_fpstatus();
2373     crf = tcg_const_i32(crfD(ctx->opcode));
2374     gen_helper_fcmpo(cpu_env, cpu_fpr[rA(ctx->opcode)],
2375                      cpu_fpr[rB(ctx->opcode)], crf);
2376     tcg_temp_free_i32(crf);
2377     gen_helper_float_check_status(cpu_env);
2378 }
2379
2380 /* fcmpu */
2381 static void gen_fcmpu(DisasContext *ctx)
2382 {
2383     TCGv_i32 crf;
2384     if (unlikely(!ctx->fpu_enabled)) {
2385         gen_exception(ctx, POWERPC_EXCP_FPU);
2386         return;
2387     }
2388     /* NIP cannot be restored if the memory exception comes from an helper */
2389     gen_update_nip(ctx, ctx->nip - 4);
2390     gen_reset_fpstatus();
2391     crf = tcg_const_i32(crfD(ctx->opcode));
2392     gen_helper_fcmpu(cpu_env, cpu_fpr[rA(ctx->opcode)],
2393                      cpu_fpr[rB(ctx->opcode)], crf);
2394     tcg_temp_free_i32(crf);
2395     gen_helper_float_check_status(cpu_env);
2396 }
2397
2398 /***                         Floating-point move                           ***/
2399 /* fabs */
2400 /* XXX: beware that fabs never checks for NaNs nor update FPSCR */
2401 static void gen_fabs(DisasContext *ctx)
2402 {
2403     if (unlikely(!ctx->fpu_enabled)) {
2404         gen_exception(ctx, POWERPC_EXCP_FPU);
2405         return;
2406     }
2407     tcg_gen_andi_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)],
2408                      ~(1ULL << 63));
2409     if (unlikely(Rc(ctx->opcode))) {
2410         gen_set_cr1_from_fpscr(ctx);
2411     }
2412 }
2413
2414 /* fmr  - fmr. */
2415 /* XXX: beware that fmr never checks for NaNs nor update FPSCR */
2416 static void gen_fmr(DisasContext *ctx)
2417 {
2418     if (unlikely(!ctx->fpu_enabled)) {
2419         gen_exception(ctx, POWERPC_EXCP_FPU);
2420         return;
2421     }
2422     tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
2423     if (unlikely(Rc(ctx->opcode))) {
2424         gen_set_cr1_from_fpscr(ctx);
2425     }
2426 }
2427
2428 /* fnabs */
2429 /* XXX: beware that fnabs never checks for NaNs nor update FPSCR */
2430 static void gen_fnabs(DisasContext *ctx)
2431 {
2432     if (unlikely(!ctx->fpu_enabled)) {
2433         gen_exception(ctx, POWERPC_EXCP_FPU);
2434         return;
2435     }
2436     tcg_gen_ori_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)],
2437                     1ULL << 63);
2438     if (unlikely(Rc(ctx->opcode))) {
2439         gen_set_cr1_from_fpscr(ctx);
2440     }
2441 }
2442
2443 /* fneg */
2444 /* XXX: beware that fneg never checks for NaNs nor update FPSCR */
2445 static void gen_fneg(DisasContext *ctx)
2446 {
2447     if (unlikely(!ctx->fpu_enabled)) {
2448         gen_exception(ctx, POWERPC_EXCP_FPU);
2449         return;
2450     }
2451     tcg_gen_xori_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)],
2452                      1ULL << 63);
2453     if (unlikely(Rc(ctx->opcode))) {
2454         gen_set_cr1_from_fpscr(ctx);
2455     }
2456 }
2457
2458 /* fcpsgn: PowerPC 2.05 specification */
2459 /* XXX: beware that fcpsgn never checks for NaNs nor update FPSCR */
2460 static void gen_fcpsgn(DisasContext *ctx)
2461 {
2462     if (unlikely(!ctx->fpu_enabled)) {
2463         gen_exception(ctx, POWERPC_EXCP_FPU);
2464         return;
2465     }
2466     tcg_gen_deposit_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rA(ctx->opcode)],
2467                         cpu_fpr[rB(ctx->opcode)], 0, 63);
2468     if (unlikely(Rc(ctx->opcode))) {
2469         gen_set_cr1_from_fpscr(ctx);
2470     }
2471 }
2472
2473 static void gen_fmrgew(DisasContext *ctx)
2474 {
2475     TCGv_i64 b0;
2476     if (unlikely(!ctx->fpu_enabled)) {
2477         gen_exception(ctx, POWERPC_EXCP_FPU);
2478         return;
2479     }
2480     b0 = tcg_temp_new_i64();
2481     tcg_gen_shri_i64(b0, cpu_fpr[rB(ctx->opcode)], 32);
2482     tcg_gen_deposit_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rA(ctx->opcode)],
2483                         b0, 0, 32);
2484     tcg_temp_free_i64(b0);
2485 }
2486
2487 static void gen_fmrgow(DisasContext *ctx)
2488 {
2489     if (unlikely(!ctx->fpu_enabled)) {
2490         gen_exception(ctx, POWERPC_EXCP_FPU);
2491         return;
2492     }
2493     tcg_gen_deposit_i64(cpu_fpr[rD(ctx->opcode)],
2494                         cpu_fpr[rB(ctx->opcode)],
2495                         cpu_fpr[rA(ctx->opcode)],
2496                         32, 32);
2497 }
2498
2499 /***                  Floating-Point status & ctrl register                ***/
2500
2501 /* mcrfs */
2502 static void gen_mcrfs(DisasContext *ctx)
2503 {
2504     TCGv tmp = tcg_temp_new();
2505     TCGv_i32 tmask;
2506     TCGv_i64 tnew_fpscr = tcg_temp_new_i64();
2507     int bfa;
2508     int nibble;
2509     int shift;
2510
2511     if (unlikely(!ctx->fpu_enabled)) {
2512         gen_exception(ctx, POWERPC_EXCP_FPU);
2513         return;
2514     }
2515     bfa = crfS(ctx->opcode);
2516     nibble = 7 - bfa;
2517     shift = 4 * nibble;
2518     tcg_gen_shri_tl(tmp, cpu_fpscr, shift);
2519     tcg_gen_trunc_tl_i32(cpu_crf[crfD(ctx->opcode)], tmp);
2520     tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], 0xf);
2521     tcg_temp_free(tmp);
2522     tcg_gen_extu_tl_i64(tnew_fpscr, cpu_fpscr);
2523     /* Only the exception bits (including FX) should be cleared if read */
2524     tcg_gen_andi_i64(tnew_fpscr, tnew_fpscr, ~((0xF << shift) & FP_EX_CLEAR_BITS));
2525     /* FEX and VX need to be updated, so don't set fpscr directly */
2526     tmask = tcg_const_i32(1 << nibble);
2527     gen_helper_store_fpscr(cpu_env, tnew_fpscr, tmask);
2528     tcg_temp_free_i32(tmask);
2529     tcg_temp_free_i64(tnew_fpscr);
2530 }
2531
2532 /* mffs */
2533 static void gen_mffs(DisasContext *ctx)
2534 {
2535     if (unlikely(!ctx->fpu_enabled)) {
2536         gen_exception(ctx, POWERPC_EXCP_FPU);
2537         return;
2538     }
2539     gen_reset_fpstatus();
2540     tcg_gen_extu_tl_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpscr);
2541     if (unlikely(Rc(ctx->opcode))) {
2542         gen_set_cr1_from_fpscr(ctx);
2543     }
2544 }
2545
2546 /* mtfsb0 */
2547 static void gen_mtfsb0(DisasContext *ctx)
2548 {
2549     uint8_t crb;
2550
2551     if (unlikely(!ctx->fpu_enabled)) {
2552         gen_exception(ctx, POWERPC_EXCP_FPU);
2553         return;
2554     }
2555     crb = 31 - crbD(ctx->opcode);
2556     gen_reset_fpstatus();
2557     if (likely(crb != FPSCR_FEX && crb != FPSCR_VX)) {
2558         TCGv_i32 t0;
2559         /* NIP cannot be restored if the memory exception comes from an helper */
2560         gen_update_nip(ctx, ctx->nip - 4);
2561         t0 = tcg_const_i32(crb);
2562         gen_helper_fpscr_clrbit(cpu_env, t0);
2563         tcg_temp_free_i32(t0);
2564     }
2565     if (unlikely(Rc(ctx->opcode) != 0)) {
2566         tcg_gen_trunc_tl_i32(cpu_crf[1], cpu_fpscr);
2567         tcg_gen_shri_i32(cpu_crf[1], cpu_crf[1], FPSCR_OX);
2568     }
2569 }
2570
2571 /* mtfsb1 */
2572 static void gen_mtfsb1(DisasContext *ctx)
2573 {
2574     uint8_t crb;
2575
2576     if (unlikely(!ctx->fpu_enabled)) {
2577         gen_exception(ctx, POWERPC_EXCP_FPU);
2578         return;
2579     }
2580     crb = 31 - crbD(ctx->opcode);
2581     gen_reset_fpstatus();
2582     /* XXX: we pretend we can only do IEEE floating-point computations */
2583     if (likely(crb != FPSCR_FEX && crb != FPSCR_VX && crb != FPSCR_NI)) {
2584         TCGv_i32 t0;
2585         /* NIP cannot be restored if the memory exception comes from an helper */
2586         gen_update_nip(ctx, ctx->nip - 4);
2587         t0 = tcg_const_i32(crb);
2588         gen_helper_fpscr_setbit(cpu_env, t0);
2589         tcg_temp_free_i32(t0);
2590     }
2591     if (unlikely(Rc(ctx->opcode) != 0)) {
2592         tcg_gen_trunc_tl_i32(cpu_crf[1], cpu_fpscr);
2593         tcg_gen_shri_i32(cpu_crf[1], cpu_crf[1], FPSCR_OX);
2594     }
2595     /* We can raise a differed exception */
2596     gen_helper_float_check_status(cpu_env);
2597 }
2598
2599 /* mtfsf */
2600 static void gen_mtfsf(DisasContext *ctx)
2601 {
2602     TCGv_i32 t0;
2603     int flm, l, w;
2604
2605     if (unlikely(!ctx->fpu_enabled)) {
2606         gen_exception(ctx, POWERPC_EXCP_FPU);
2607         return;
2608     }
2609     flm = FPFLM(ctx->opcode);
2610     l = FPL(ctx->opcode);
2611     w = FPW(ctx->opcode);
2612     if (unlikely(w & !(ctx->insns_flags2 & PPC2_ISA205))) {
2613         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
2614         return;
2615     }
2616     /* NIP cannot be restored if the memory exception comes from an helper */
2617     gen_update_nip(ctx, ctx->nip - 4);
2618     gen_reset_fpstatus();
2619     if (l) {
2620         t0 = tcg_const_i32((ctx->insns_flags2 & PPC2_ISA205) ? 0xffff : 0xff);
2621     } else {
2622         t0 = tcg_const_i32(flm << (w * 8));
2623     }
2624     gen_helper_store_fpscr(cpu_env, cpu_fpr[rB(ctx->opcode)], t0);
2625     tcg_temp_free_i32(t0);
2626     if (unlikely(Rc(ctx->opcode) != 0)) {
2627         tcg_gen_trunc_tl_i32(cpu_crf[1], cpu_fpscr);
2628         tcg_gen_shri_i32(cpu_crf[1], cpu_crf[1], FPSCR_OX);
2629     }
2630     /* We can raise a differed exception */
2631     gen_helper_float_check_status(cpu_env);
2632 }
2633
2634 /* mtfsfi */
2635 static void gen_mtfsfi(DisasContext *ctx)
2636 {
2637     int bf, sh, w;
2638     TCGv_i64 t0;
2639     TCGv_i32 t1;
2640
2641     if (unlikely(!ctx->fpu_enabled)) {
2642         gen_exception(ctx, POWERPC_EXCP_FPU);
2643         return;
2644     }
2645     w = FPW(ctx->opcode);
2646     bf = FPBF(ctx->opcode);
2647     if (unlikely(w & !(ctx->insns_flags2 & PPC2_ISA205))) {
2648         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
2649         return;
2650     }
2651     sh = (8 * w) + 7 - bf;
2652     /* NIP cannot be restored if the memory exception comes from an helper */
2653     gen_update_nip(ctx, ctx->nip - 4);
2654     gen_reset_fpstatus();
2655     t0 = tcg_const_i64(((uint64_t)FPIMM(ctx->opcode)) << (4 * sh));
2656     t1 = tcg_const_i32(1 << sh);
2657     gen_helper_store_fpscr(cpu_env, t0, t1);
2658     tcg_temp_free_i64(t0);
2659     tcg_temp_free_i32(t1);
2660     if (unlikely(Rc(ctx->opcode) != 0)) {
2661         tcg_gen_trunc_tl_i32(cpu_crf[1], cpu_fpscr);
2662         tcg_gen_shri_i32(cpu_crf[1], cpu_crf[1], FPSCR_OX);
2663     }
2664     /* We can raise a differed exception */
2665     gen_helper_float_check_status(cpu_env);
2666 }
2667
2668 /***                           Addressing modes                            ***/
2669 /* Register indirect with immediate index : EA = (rA|0) + SIMM */
2670 static inline void gen_addr_imm_index(DisasContext *ctx, TCGv EA,
2671                                       target_long maskl)
2672 {
2673     target_long simm = SIMM(ctx->opcode);
2674
2675     simm &= ~maskl;
2676     if (rA(ctx->opcode) == 0) {
2677         if (NARROW_MODE(ctx)) {
2678             simm = (uint32_t)simm;
2679         }
2680         tcg_gen_movi_tl(EA, simm);
2681     } else if (likely(simm != 0)) {
2682         tcg_gen_addi_tl(EA, cpu_gpr[rA(ctx->opcode)], simm);
2683         if (NARROW_MODE(ctx)) {
2684             tcg_gen_ext32u_tl(EA, EA);
2685         }
2686     } else {
2687         if (NARROW_MODE(ctx)) {
2688             tcg_gen_ext32u_tl(EA, cpu_gpr[rA(ctx->opcode)]);
2689         } else {
2690             tcg_gen_mov_tl(EA, cpu_gpr[rA(ctx->opcode)]);
2691         }
2692     }
2693 }
2694
2695 static inline void gen_addr_reg_index(DisasContext *ctx, TCGv EA)
2696 {
2697     if (rA(ctx->opcode) == 0) {
2698         if (NARROW_MODE(ctx)) {
2699             tcg_gen_ext32u_tl(EA, cpu_gpr[rB(ctx->opcode)]);
2700         } else {
2701             tcg_gen_mov_tl(EA, cpu_gpr[rB(ctx->opcode)]);
2702         }
2703     } else {
2704         tcg_gen_add_tl(EA, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
2705         if (NARROW_MODE(ctx)) {
2706             tcg_gen_ext32u_tl(EA, EA);
2707         }
2708     }
2709 }
2710
2711 static inline void gen_addr_register(DisasContext *ctx, TCGv EA)
2712 {
2713     if (rA(ctx->opcode) == 0) {
2714         tcg_gen_movi_tl(EA, 0);
2715     } else if (NARROW_MODE(ctx)) {
2716         tcg_gen_ext32u_tl(EA, cpu_gpr[rA(ctx->opcode)]);
2717     } else {
2718         tcg_gen_mov_tl(EA, cpu_gpr[rA(ctx->opcode)]);
2719     }
2720 }
2721
2722 static inline void gen_addr_add(DisasContext *ctx, TCGv ret, TCGv arg1,
2723                                 target_long val)
2724 {
2725     tcg_gen_addi_tl(ret, arg1, val);
2726     if (NARROW_MODE(ctx)) {
2727         tcg_gen_ext32u_tl(ret, ret);
2728     }
2729 }
2730
2731 static inline void gen_check_align(DisasContext *ctx, TCGv EA, int mask)
2732 {
2733     TCGLabel *l1 = gen_new_label();
2734     TCGv t0 = tcg_temp_new();
2735     TCGv_i32 t1, t2;
2736     /* NIP cannot be restored if the memory exception comes from an helper */
2737     gen_update_nip(ctx, ctx->nip - 4);
2738     tcg_gen_andi_tl(t0, EA, mask);
2739     tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
2740     t1 = tcg_const_i32(POWERPC_EXCP_ALIGN);
2741     t2 = tcg_const_i32(0);
2742     gen_helper_raise_exception_err(cpu_env, t1, t2);
2743     tcg_temp_free_i32(t1);
2744     tcg_temp_free_i32(t2);
2745     gen_set_label(l1);
2746     tcg_temp_free(t0);
2747 }
2748
2749 /***                             Integer load                              ***/
2750 static inline void gen_qemu_ld8u(DisasContext *ctx, TCGv arg1, TCGv arg2)
2751 {
2752     tcg_gen_qemu_ld8u(arg1, arg2, ctx->mem_idx);
2753 }
2754
2755 static inline void gen_qemu_ld16u(DisasContext *ctx, TCGv arg1, TCGv arg2)
2756 {
2757     TCGMemOp op = MO_UW | ctx->default_tcg_memop_mask;
2758     tcg_gen_qemu_ld_tl(arg1, arg2, ctx->mem_idx, op);
2759 }
2760
2761 static inline void gen_qemu_ld16s(DisasContext *ctx, TCGv arg1, TCGv arg2)
2762 {
2763     TCGMemOp op = MO_SW | ctx->default_tcg_memop_mask;
2764     tcg_gen_qemu_ld_tl(arg1, arg2, ctx->mem_idx, op);
2765 }
2766
2767 static inline void gen_qemu_ld32u(DisasContext *ctx, TCGv arg1, TCGv arg2)
2768 {
2769     TCGMemOp op = MO_UL | ctx->default_tcg_memop_mask;
2770     tcg_gen_qemu_ld_tl(arg1, arg2, ctx->mem_idx, op);
2771 }
2772
2773 static void gen_qemu_ld32u_i64(DisasContext *ctx, TCGv_i64 val, TCGv addr)
2774 {
2775     TCGv tmp = tcg_temp_new();
2776     gen_qemu_ld32u(ctx, tmp, addr);
2777     tcg_gen_extu_tl_i64(val, tmp);
2778     tcg_temp_free(tmp);
2779 }
2780
2781 static inline void gen_qemu_ld32s(DisasContext *ctx, TCGv arg1, TCGv arg2)
2782 {
2783     TCGMemOp op = MO_SL | ctx->default_tcg_memop_mask;
2784     tcg_gen_qemu_ld_tl(arg1, arg2, ctx->mem_idx, op);
2785 }
2786
2787 static void gen_qemu_ld32s_i64(DisasContext *ctx, TCGv_i64 val, TCGv addr)
2788 {
2789     TCGv tmp = tcg_temp_new();
2790     gen_qemu_ld32s(ctx, tmp, addr);
2791     tcg_gen_ext_tl_i64(val, tmp);
2792     tcg_temp_free(tmp);
2793 }
2794
2795 static inline void gen_qemu_ld64(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
2796 {
2797     TCGMemOp op = MO_Q | ctx->default_tcg_memop_mask;
2798     tcg_gen_qemu_ld_i64(arg1, arg2, ctx->mem_idx, op);
2799 }
2800
2801 static inline void gen_qemu_st8(DisasContext *ctx, TCGv arg1, TCGv arg2)
2802 {
2803     tcg_gen_qemu_st8(arg1, arg2, ctx->mem_idx);
2804 }
2805
2806 static inline void gen_qemu_st16(DisasContext *ctx, TCGv arg1, TCGv arg2)
2807 {
2808     TCGMemOp op = MO_UW | ctx->default_tcg_memop_mask;
2809     tcg_gen_qemu_st_tl(arg1, arg2, ctx->mem_idx, op);
2810 }
2811
2812 static inline void gen_qemu_st32(DisasContext *ctx, TCGv arg1, TCGv arg2)
2813 {
2814     TCGMemOp op = MO_UL | ctx->default_tcg_memop_mask;
2815     tcg_gen_qemu_st_tl(arg1, arg2, ctx->mem_idx, op);
2816 }
2817
2818 static void gen_qemu_st32_i64(DisasContext *ctx, TCGv_i64 val, TCGv addr)
2819 {
2820     TCGv tmp = tcg_temp_new();
2821     tcg_gen_trunc_i64_tl(tmp, val);
2822     gen_qemu_st32(ctx, tmp, addr);
2823     tcg_temp_free(tmp);
2824 }
2825
2826 static inline void gen_qemu_st64(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
2827 {
2828     TCGMemOp op = MO_Q | ctx->default_tcg_memop_mask;
2829     tcg_gen_qemu_st_i64(arg1, arg2, ctx->mem_idx, op);
2830 }
2831
2832 #define GEN_LD(name, ldop, opc, type)                                         \
2833 static void glue(gen_, name)(DisasContext *ctx)                                       \
2834 {                                                                             \
2835     TCGv EA;                                                                  \
2836     gen_set_access_type(ctx, ACCESS_INT);                                     \
2837     EA = tcg_temp_new();                                                      \
2838     gen_addr_imm_index(ctx, EA, 0);                                           \
2839     gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA);                       \
2840     tcg_temp_free(EA);                                                        \
2841 }
2842
2843 #define GEN_LDU(name, ldop, opc, type)                                        \
2844 static void glue(gen_, name##u)(DisasContext *ctx)                                    \
2845 {                                                                             \
2846     TCGv EA;                                                                  \
2847     if (unlikely(rA(ctx->opcode) == 0 ||                                      \
2848                  rA(ctx->opcode) == rD(ctx->opcode))) {                       \
2849         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
2850         return;                                                               \
2851     }                                                                         \
2852     gen_set_access_type(ctx, ACCESS_INT);                                     \
2853     EA = tcg_temp_new();                                                      \
2854     if (type == PPC_64B)                                                      \
2855         gen_addr_imm_index(ctx, EA, 0x03);                                    \
2856     else                                                                      \
2857         gen_addr_imm_index(ctx, EA, 0);                                       \
2858     gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA);                       \
2859     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
2860     tcg_temp_free(EA);                                                        \
2861 }
2862
2863 #define GEN_LDUX(name, ldop, opc2, opc3, type)                                \
2864 static void glue(gen_, name##ux)(DisasContext *ctx)                                   \
2865 {                                                                             \
2866     TCGv EA;                                                                  \
2867     if (unlikely(rA(ctx->opcode) == 0 ||                                      \
2868                  rA(ctx->opcode) == rD(ctx->opcode))) {                       \
2869         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
2870         return;                                                               \
2871     }                                                                         \
2872     gen_set_access_type(ctx, ACCESS_INT);                                     \
2873     EA = tcg_temp_new();                                                      \
2874     gen_addr_reg_index(ctx, EA);                                              \
2875     gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA);                       \
2876     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
2877     tcg_temp_free(EA);                                                        \
2878 }
2879
2880 #define GEN_LDX_E(name, ldop, opc2, opc3, type, type2)                        \
2881 static void glue(gen_, name##x)(DisasContext *ctx)                            \
2882 {                                                                             \
2883     TCGv EA;                                                                  \
2884     gen_set_access_type(ctx, ACCESS_INT);                                     \
2885     EA = tcg_temp_new();                                                      \
2886     gen_addr_reg_index(ctx, EA);                                              \
2887     gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA);                       \
2888     tcg_temp_free(EA);                                                        \
2889 }
2890 #define GEN_LDX(name, ldop, opc2, opc3, type)                                 \
2891     GEN_LDX_E(name, ldop, opc2, opc3, type, PPC_NONE)
2892
2893 #define GEN_LDS(name, ldop, op, type)                                         \
2894 GEN_LD(name, ldop, op | 0x20, type);                                          \
2895 GEN_LDU(name, ldop, op | 0x21, type);                                         \
2896 GEN_LDUX(name, ldop, 0x17, op | 0x01, type);                                  \
2897 GEN_LDX(name, ldop, 0x17, op | 0x00, type)
2898
2899 /* lbz lbzu lbzux lbzx */
2900 GEN_LDS(lbz, ld8u, 0x02, PPC_INTEGER);
2901 /* lha lhau lhaux lhax */
2902 GEN_LDS(lha, ld16s, 0x0A, PPC_INTEGER);
2903 /* lhz lhzu lhzux lhzx */
2904 GEN_LDS(lhz, ld16u, 0x08, PPC_INTEGER);
2905 /* lwz lwzu lwzux lwzx */
2906 GEN_LDS(lwz, ld32u, 0x00, PPC_INTEGER);
2907 #if defined(TARGET_PPC64)
2908 /* lwaux */
2909 GEN_LDUX(lwa, ld32s, 0x15, 0x0B, PPC_64B);
2910 /* lwax */
2911 GEN_LDX(lwa, ld32s, 0x15, 0x0A, PPC_64B);
2912 /* ldux */
2913 GEN_LDUX(ld, ld64, 0x15, 0x01, PPC_64B);
2914 /* ldx */
2915 GEN_LDX(ld, ld64, 0x15, 0x00, PPC_64B);
2916
2917 static void gen_ld(DisasContext *ctx)
2918 {
2919     TCGv EA;
2920     if (Rc(ctx->opcode)) {
2921         if (unlikely(rA(ctx->opcode) == 0 ||
2922                      rA(ctx->opcode) == rD(ctx->opcode))) {
2923             gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
2924             return;
2925         }
2926     }
2927     gen_set_access_type(ctx, ACCESS_INT);
2928     EA = tcg_temp_new();
2929     gen_addr_imm_index(ctx, EA, 0x03);
2930     if (ctx->opcode & 0x02) {
2931         /* lwa (lwau is undefined) */
2932         gen_qemu_ld32s(ctx, cpu_gpr[rD(ctx->opcode)], EA);
2933     } else {
2934         /* ld - ldu */
2935         gen_qemu_ld64(ctx, cpu_gpr[rD(ctx->opcode)], EA);
2936     }
2937     if (Rc(ctx->opcode))
2938         tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);
2939     tcg_temp_free(EA);
2940 }
2941
2942 /* lq */
2943 static void gen_lq(DisasContext *ctx)
2944 {
2945     int ra, rd;
2946     TCGv EA;
2947
2948     /* lq is a legal user mode instruction starting in ISA 2.07 */
2949     bool legal_in_user_mode = (ctx->insns_flags2 & PPC2_LSQ_ISA207) != 0;
2950     bool le_is_supported = (ctx->insns_flags2 & PPC2_LSQ_ISA207) != 0;
2951
2952     if (!legal_in_user_mode && ctx->pr) {
2953         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
2954         return;
2955     }
2956
2957     if (!le_is_supported && ctx->le_mode) {
2958         gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
2959         return;
2960     }
2961
2962     ra = rA(ctx->opcode);
2963     rd = rD(ctx->opcode);
2964     if (unlikely((rd & 1) || rd == ra)) {
2965         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
2966         return;
2967     }
2968
2969     gen_set_access_type(ctx, ACCESS_INT);
2970     EA = tcg_temp_new();
2971     gen_addr_imm_index(ctx, EA, 0x0F);
2972
2973     /* We only need to swap high and low halves. gen_qemu_ld64 does necessary
2974        64-bit byteswap already. */
2975     if (unlikely(ctx->le_mode)) {
2976         gen_qemu_ld64(ctx, cpu_gpr[rd+1], EA);
2977         gen_addr_add(ctx, EA, EA, 8);
2978         gen_qemu_ld64(ctx, cpu_gpr[rd], EA);
2979     } else {
2980         gen_qemu_ld64(ctx, cpu_gpr[rd], EA);
2981         gen_addr_add(ctx, EA, EA, 8);
2982         gen_qemu_ld64(ctx, cpu_gpr[rd+1], EA);
2983     }
2984     tcg_temp_free(EA);
2985 }
2986 #endif
2987
2988 /***                              Integer store                            ***/
2989 #define GEN_ST(name, stop, opc, type)                                         \
2990 static void glue(gen_, name)(DisasContext *ctx)                                       \
2991 {                                                                             \
2992     TCGv EA;                                                                  \
2993     gen_set_access_type(ctx, ACCESS_INT);                                     \
2994     EA = tcg_temp_new();                                                      \
2995     gen_addr_imm_index(ctx, EA, 0);                                           \
2996     gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA);                       \
2997     tcg_temp_free(EA);                                                        \
2998 }
2999
3000 #define GEN_STU(name, stop, opc, type)                                        \
3001 static void glue(gen_, stop##u)(DisasContext *ctx)                                    \
3002 {                                                                             \
3003     TCGv EA;                                                                  \
3004     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
3005         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
3006         return;                                                               \
3007     }                                                                         \
3008     gen_set_access_type(ctx, ACCESS_INT);                                     \
3009     EA = tcg_temp_new();                                                      \
3010     if (type == PPC_64B)                                                      \
3011         gen_addr_imm_index(ctx, EA, 0x03);                                    \
3012     else                                                                      \
3013         gen_addr_imm_index(ctx, EA, 0);                                       \
3014     gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA);                       \
3015     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
3016     tcg_temp_free(EA);                                                        \
3017 }
3018
3019 #define GEN_STUX(name, stop, opc2, opc3, type)                                \
3020 static void glue(gen_, name##ux)(DisasContext *ctx)                                   \
3021 {                                                                             \
3022     TCGv EA;                                                                  \
3023     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
3024         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
3025         return;                                                               \
3026     }                                                                         \
3027     gen_set_access_type(ctx, ACCESS_INT);                                     \
3028     EA = tcg_temp_new();                                                      \
3029     gen_addr_reg_index(ctx, EA);                                              \
3030     gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA);                       \
3031     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
3032     tcg_temp_free(EA);                                                        \
3033 }
3034
3035 #define GEN_STX_E(name, stop, opc2, opc3, type, type2)                        \
3036 static void glue(gen_, name##x)(DisasContext *ctx)                            \
3037 {                                                                             \
3038     TCGv EA;                                                                  \
3039     gen_set_access_type(ctx, ACCESS_INT);                                     \
3040     EA = tcg_temp_new();                                                      \
3041     gen_addr_reg_index(ctx, EA);                                              \
3042     gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA);                       \
3043     tcg_temp_free(EA);                                                        \
3044 }
3045 #define GEN_STX(name, stop, opc2, opc3, type)                                 \
3046     GEN_STX_E(name, stop, opc2, opc3, type, PPC_NONE)
3047
3048 #define GEN_STS(name, stop, op, type)                                         \
3049 GEN_ST(name, stop, op | 0x20, type);                                          \
3050 GEN_STU(name, stop, op | 0x21, type);                                         \
3051 GEN_STUX(name, stop, 0x17, op | 0x01, type);                                  \
3052 GEN_STX(name, stop, 0x17, op | 0x00, type)
3053
3054 /* stb stbu stbux stbx */
3055 GEN_STS(stb, st8, 0x06, PPC_INTEGER);
3056 /* sth sthu sthux sthx */
3057 GEN_STS(sth, st16, 0x0C, PPC_INTEGER);
3058 /* stw stwu stwux stwx */
3059 GEN_STS(stw, st32, 0x04, PPC_INTEGER);
3060 #if defined(TARGET_PPC64)
3061 GEN_STUX(std, st64, 0x15, 0x05, PPC_64B);
3062 GEN_STX(std, st64, 0x15, 0x04, PPC_64B);
3063
3064 static void gen_std(DisasContext *ctx)
3065 {
3066     int rs;
3067     TCGv EA;
3068
3069     rs = rS(ctx->opcode);
3070     if ((ctx->opcode & 0x3) == 0x2) { /* stq */
3071
3072         bool legal_in_user_mode = (ctx->insns_flags2 & PPC2_LSQ_ISA207) != 0;
3073         bool le_is_supported = (ctx->insns_flags2 & PPC2_LSQ_ISA207) != 0;
3074
3075         if (!legal_in_user_mode && ctx->pr) {
3076             gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
3077             return;
3078         }
3079
3080         if (!le_is_supported && ctx->le_mode) {
3081             gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
3082             return;
3083         }
3084
3085         if (unlikely(rs & 1)) {
3086             gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
3087             return;
3088         }
3089         gen_set_access_type(ctx, ACCESS_INT);
3090         EA = tcg_temp_new();
3091         gen_addr_imm_index(ctx, EA, 0x03);
3092
3093         /* We only need to swap high and low halves. gen_qemu_st64 does
3094            necessary 64-bit byteswap already. */
3095         if (unlikely(ctx->le_mode)) {
3096             gen_qemu_st64(ctx, cpu_gpr[rs+1], EA);
3097             gen_addr_add(ctx, EA, EA, 8);
3098             gen_qemu_st64(ctx, cpu_gpr[rs], EA);
3099         } else {
3100             gen_qemu_st64(ctx, cpu_gpr[rs], EA);
3101             gen_addr_add(ctx, EA, EA, 8);
3102             gen_qemu_st64(ctx, cpu_gpr[rs+1], EA);
3103         }
3104         tcg_temp_free(EA);
3105     } else {
3106         /* std / stdu*/
3107         if (Rc(ctx->opcode)) {
3108             if (unlikely(rA(ctx->opcode) == 0)) {
3109                 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
3110                 return;
3111             }
3112         }
3113         gen_set_access_type(ctx, ACCESS_INT);
3114         EA = tcg_temp_new();
3115         gen_addr_imm_index(ctx, EA, 0x03);
3116         gen_qemu_st64(ctx, cpu_gpr[rs], EA);
3117         if (Rc(ctx->opcode))
3118             tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);
3119         tcg_temp_free(EA);
3120     }
3121 }
3122 #endif
3123 /***                Integer load and store with byte reverse               ***/
3124
3125 /* lhbrx */
3126 static inline void gen_qemu_ld16ur(DisasContext *ctx, TCGv arg1, TCGv arg2)
3127 {
3128     TCGMemOp op = MO_UW | (ctx->default_tcg_memop_mask ^ MO_BSWAP);
3129     tcg_gen_qemu_ld_tl(arg1, arg2, ctx->mem_idx, op);
3130 }
3131 GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER);
3132
3133 /* lwbrx */
3134 static inline void gen_qemu_ld32ur(DisasContext *ctx, TCGv arg1, TCGv arg2)
3135 {
3136     TCGMemOp op = MO_UL | (ctx->default_tcg_memop_mask ^ MO_BSWAP);
3137     tcg_gen_qemu_ld_tl(arg1, arg2, ctx->mem_idx, op);
3138 }
3139 GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER);
3140
3141 #if defined(TARGET_PPC64)
3142 /* ldbrx */
3143 static inline void gen_qemu_ld64ur(DisasContext *ctx, TCGv arg1, TCGv arg2)
3144 {
3145     TCGMemOp op = MO_Q | (ctx->default_tcg_memop_mask ^ MO_BSWAP);
3146     tcg_gen_qemu_ld_i64(arg1, arg2, ctx->mem_idx, op);
3147 }
3148 GEN_LDX_E(ldbr, ld64ur, 0x14, 0x10, PPC_NONE, PPC2_DBRX);
3149 #endif  /* TARGET_PPC64 */
3150
3151 /* sthbrx */
3152 static inline void gen_qemu_st16r(DisasContext *ctx, TCGv arg1, TCGv arg2)
3153 {
3154     TCGMemOp op = MO_UW | (ctx->default_tcg_memop_mask ^ MO_BSWAP);
3155     tcg_gen_qemu_st_tl(arg1, arg2, ctx->mem_idx, op);
3156 }
3157 GEN_STX(sthbr, st16r, 0x16, 0x1C, PPC_INTEGER);
3158
3159 /* stwbrx */
3160 static inline void gen_qemu_st32r(DisasContext *ctx, TCGv arg1, TCGv arg2)
3161 {
3162     TCGMemOp op = MO_UL | (ctx->default_tcg_memop_mask ^ MO_BSWAP);
3163     tcg_gen_qemu_st_tl(arg1, arg2, ctx->mem_idx, op);
3164 }
3165 GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER);
3166
3167 #if defined(TARGET_PPC64)
3168 /* stdbrx */
3169 static inline void gen_qemu_st64r(DisasContext *ctx, TCGv arg1, TCGv arg2)
3170 {
3171     TCGMemOp op = MO_Q | (ctx->default_tcg_memop_mask ^ MO_BSWAP);
3172     tcg_gen_qemu_st_i64(arg1, arg2, ctx->mem_idx, op);
3173 }
3174 GEN_STX_E(stdbr, st64r, 0x14, 0x14, PPC_NONE, PPC2_DBRX);
3175 #endif  /* TARGET_PPC64 */
3176
3177 /***                    Integer load and store multiple                    ***/
3178
3179 /* lmw */
3180 static void gen_lmw(DisasContext *ctx)
3181 {
3182     TCGv t0;
3183     TCGv_i32 t1;
3184     gen_set_access_type(ctx, ACCESS_INT);
3185     /* NIP cannot be restored if the memory exception comes from an helper */
3186     gen_update_nip(ctx, ctx->nip - 4);
3187     t0 = tcg_temp_new();
3188     t1 = tcg_const_i32(rD(ctx->opcode));
3189     gen_addr_imm_index(ctx, t0, 0);
3190     gen_helper_lmw(cpu_env, t0, t1);
3191     tcg_temp_free(t0);
3192     tcg_temp_free_i32(t1);
3193 }
3194
3195 /* stmw */
3196 static void gen_stmw(DisasContext *ctx)
3197 {
3198     TCGv t0;
3199     TCGv_i32 t1;
3200     gen_set_access_type(ctx, ACCESS_INT);
3201     /* NIP cannot be restored if the memory exception comes from an helper */
3202     gen_update_nip(ctx, ctx->nip - 4);
3203     t0 = tcg_temp_new();
3204     t1 = tcg_const_i32(rS(ctx->opcode));
3205     gen_addr_imm_index(ctx, t0, 0);
3206     gen_helper_stmw(cpu_env, t0, t1);
3207     tcg_temp_free(t0);
3208     tcg_temp_free_i32(t1);
3209 }
3210
3211 /***                    Integer load and store strings                     ***/
3212
3213 /* lswi */
3214 /* PowerPC32 specification says we must generate an exception if
3215  * rA is in the range of registers to be loaded.
3216  * In an other hand, IBM says this is valid, but rA won't be loaded.
3217  * For now, I'll follow the spec...
3218  */
3219 static void gen_lswi(DisasContext *ctx)
3220 {
3221     TCGv t0;
3222     TCGv_i32 t1, t2;
3223     int nb = NB(ctx->opcode);
3224     int start = rD(ctx->opcode);
3225     int ra = rA(ctx->opcode);
3226     int nr;
3227
3228     if (nb == 0)
3229         nb = 32;
3230     nr = nb / 4;
3231     if (unlikely(((start + nr) > 32  &&
3232                   start <= ra && (start + nr - 32) > ra) ||
3233                  ((start + nr) <= 32 && start <= ra && (start + nr) > ra))) {
3234         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_LSWX);
3235         return;
3236     }
3237     gen_set_access_type(ctx, ACCESS_INT);
3238     /* NIP cannot be restored if the memory exception comes from an helper */
3239     gen_update_nip(ctx, ctx->nip - 4);
3240     t0 = tcg_temp_new();
3241     gen_addr_register(ctx, t0);
3242     t1 = tcg_const_i32(nb);
3243     t2 = tcg_const_i32(start);
3244     gen_helper_lsw(cpu_env, t0, t1, t2);
3245     tcg_temp_free(t0);
3246     tcg_temp_free_i32(t1);
3247     tcg_temp_free_i32(t2);
3248 }
3249
3250 /* lswx */
3251 static void gen_lswx(DisasContext *ctx)
3252 {
3253     TCGv t0;
3254     TCGv_i32 t1, t2, t3;
3255     gen_set_access_type(ctx, ACCESS_INT);
3256     /* NIP cannot be restored if the memory exception comes from an helper */
3257     gen_update_nip(ctx, ctx->nip - 4);
3258     t0 = tcg_temp_new();
3259     gen_addr_reg_index(ctx, t0);
3260     t1 = tcg_const_i32(rD(ctx->opcode));
3261     t2 = tcg_const_i32(rA(ctx->opcode));
3262     t3 = tcg_const_i32(rB(ctx->opcode));
3263     gen_helper_lswx(cpu_env, t0, t1, t2, t3);
3264     tcg_temp_free(t0);
3265     tcg_temp_free_i32(t1);
3266     tcg_temp_free_i32(t2);
3267     tcg_temp_free_i32(t3);
3268 }
3269
3270 /* stswi */
3271 static void gen_stswi(DisasContext *ctx)
3272 {
3273     TCGv t0;
3274     TCGv_i32 t1, t2;
3275     int nb = NB(ctx->opcode);
3276     gen_set_access_type(ctx, ACCESS_INT);
3277     /* NIP cannot be restored if the memory exception comes from an helper */
3278     gen_update_nip(ctx, ctx->nip - 4);
3279     t0 = tcg_temp_new();
3280     gen_addr_register(ctx, t0);
3281     if (nb == 0)
3282         nb = 32;
3283     t1 = tcg_const_i32(nb);
3284     t2 = tcg_const_i32(rS(ctx->opcode));
3285     gen_helper_stsw(cpu_env, t0, t1, t2);
3286     tcg_temp_free(t0);
3287     tcg_temp_free_i32(t1);
3288     tcg_temp_free_i32(t2);
3289 }
3290
3291 /* stswx */
3292 static void gen_stswx(DisasContext *ctx)
3293 {
3294     TCGv t0;
3295     TCGv_i32 t1, t2;
3296     gen_set_access_type(ctx, ACCESS_INT);
3297     /* NIP cannot be restored if the memory exception comes from an helper */
3298     gen_update_nip(ctx, ctx->nip - 4);
3299     t0 = tcg_temp_new();
3300     gen_addr_reg_index(ctx, t0);
3301     t1 = tcg_temp_new_i32();
3302     tcg_gen_trunc_tl_i32(t1, cpu_xer);
3303     tcg_gen_andi_i32(t1, t1, 0x7F);
3304     t2 = tcg_const_i32(rS(ctx->opcode));
3305     gen_helper_stsw(cpu_env, t0, t1, t2);
3306     tcg_temp_free(t0);
3307     tcg_temp_free_i32(t1);
3308     tcg_temp_free_i32(t2);
3309 }
3310
3311 /***                        Memory synchronisation                         ***/
3312 /* eieio */
3313 static void gen_eieio(DisasContext *ctx)
3314 {
3315 }
3316
3317 /* isync */
3318 static void gen_isync(DisasContext *ctx)
3319 {
3320     gen_stop_exception(ctx);
3321 }
3322
3323 #define LARX(name, len, loadop)                                      \
3324 static void gen_##name(DisasContext *ctx)                            \
3325 {                                                                    \
3326     TCGv t0;                                                         \
3327     TCGv gpr = cpu_gpr[rD(ctx->opcode)];                             \
3328     gen_set_access_type(ctx, ACCESS_RES);                            \
3329     t0 = tcg_temp_local_new();                                       \
3330     gen_addr_reg_index(ctx, t0);                                     \
3331     if ((len) > 1) {                                                 \
3332         gen_check_align(ctx, t0, (len)-1);                           \
3333     }                                                                \
3334     gen_qemu_##loadop(ctx, gpr, t0);                                 \
3335     tcg_gen_mov_tl(cpu_reserve, t0);                                 \
3336     tcg_gen_st_tl(gpr, cpu_env, offsetof(CPUPPCState, reserve_val)); \
3337     tcg_temp_free(t0);                                               \
3338 }
3339
3340 /* lwarx */
3341 LARX(lbarx, 1, ld8u);
3342 LARX(lharx, 2, ld16u);
3343 LARX(lwarx, 4, ld32u);
3344
3345
3346 #if defined(CONFIG_USER_ONLY)
3347 static void gen_conditional_store(DisasContext *ctx, TCGv EA,
3348                                   int reg, int size)
3349 {
3350     TCGv t0 = tcg_temp_new();
3351     uint32_t save_exception = ctx->exception;
3352
3353     tcg_gen_st_tl(EA, cpu_env, offsetof(CPUPPCState, reserve_ea));
3354     tcg_gen_movi_tl(t0, (size << 5) | reg);
3355     tcg_gen_st_tl(t0, cpu_env, offsetof(CPUPPCState, reserve_info));
3356     tcg_temp_free(t0);
3357     gen_update_nip(ctx, ctx->nip-4);
3358     ctx->exception = POWERPC_EXCP_BRANCH;
3359     gen_exception(ctx, POWERPC_EXCP_STCX);
3360     ctx->exception = save_exception;
3361 }
3362 #else
3363 static void gen_conditional_store(DisasContext *ctx, TCGv EA,
3364                                   int reg, int size)
3365 {
3366     TCGLabel *l1;
3367
3368     tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
3369     l1 = gen_new_label();
3370     tcg_gen_brcond_tl(TCG_COND_NE, EA, cpu_reserve, l1);
3371     tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 1 << CRF_EQ);
3372 #if defined(TARGET_PPC64)
3373     if (size == 8) {
3374         gen_qemu_st64(ctx, cpu_gpr[reg], EA);
3375     } else
3376 #endif
3377     if (size == 4) {
3378         gen_qemu_st32(ctx, cpu_gpr[reg], EA);
3379     } else if (size == 2) {
3380         gen_qemu_st16(ctx, cpu_gpr[reg], EA);
3381 #if defined(TARGET_PPC64)
3382     } else if (size == 16) {
3383         TCGv gpr1, gpr2 , EA8;
3384         if (unlikely(ctx->le_mode)) {
3385             gpr1 = cpu_gpr[reg+1];
3386             gpr2 = cpu_gpr[reg];
3387         } else {
3388             gpr1 = cpu_gpr[reg];
3389             gpr2 = cpu_gpr[reg+1];
3390         }
3391         gen_qemu_st64(ctx, gpr1, EA);
3392         EA8 = tcg_temp_local_new();
3393         gen_addr_add(ctx, EA8, EA, 8);
3394         gen_qemu_st64(ctx, gpr2, EA8);
3395         tcg_temp_free(EA8);
3396 #endif
3397     } else {
3398         gen_qemu_st8(ctx, cpu_gpr[reg], EA);
3399     }
3400     gen_set_label(l1);
3401     tcg_gen_movi_tl(cpu_reserve, -1);
3402 }
3403 #endif
3404
3405 #define STCX(name, len)                                   \
3406 static void gen_##name(DisasContext *ctx)                 \
3407 {                                                         \
3408     TCGv t0;                                              \
3409     if (unlikely((len == 16) && (rD(ctx->opcode) & 1))) { \
3410         gen_inval_exception(ctx,                          \
3411                             POWERPC_EXCP_INVAL_INVAL);    \
3412         return;                                           \
3413     }                                                     \
3414     gen_set_access_type(ctx, ACCESS_RES);                 \
3415     t0 = tcg_temp_local_new();                            \
3416     gen_addr_reg_index(ctx, t0);                          \
3417     if (len > 1) {                                        \
3418         gen_check_align(ctx, t0, (len)-1);                \
3419     }                                                     \
3420     gen_conditional_store(ctx, t0, rS(ctx->opcode), len); \
3421     tcg_temp_free(t0);                                    \
3422 }
3423
3424 STCX(stbcx_, 1);
3425 STCX(sthcx_, 2);
3426 STCX(stwcx_, 4);
3427
3428 #if defined(TARGET_PPC64)
3429 /* ldarx */
3430 LARX(ldarx, 8, ld64);
3431
3432 /* lqarx */
3433 static void gen_lqarx(DisasContext *ctx)
3434 {
3435     TCGv EA;
3436     int rd = rD(ctx->opcode);
3437     TCGv gpr1, gpr2;
3438
3439     if (unlikely((rd & 1) || (rd == rA(ctx->opcode)) ||
3440                  (rd == rB(ctx->opcode)))) {
3441         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
3442         return;
3443     }
3444
3445     gen_set_access_type(ctx, ACCESS_RES);
3446     EA = tcg_temp_local_new();
3447     gen_addr_reg_index(ctx, EA);
3448     gen_check_align(ctx, EA, 15);
3449     if (unlikely(ctx->le_mode)) {
3450         gpr1 = cpu_gpr[rd+1];
3451         gpr2 = cpu_gpr[rd];
3452     } else {
3453         gpr1 = cpu_gpr[rd];
3454         gpr2 = cpu_gpr[rd+1];
3455     }
3456     gen_qemu_ld64(ctx, gpr1, EA);
3457     tcg_gen_mov_tl(cpu_reserve, EA);
3458
3459     gen_addr_add(ctx, EA, EA, 8);
3460     gen_qemu_ld64(ctx, gpr2, EA);
3461
3462     tcg_gen_st_tl(gpr1, cpu_env, offsetof(CPUPPCState, reserve_val));
3463     tcg_gen_st_tl(gpr2, cpu_env, offsetof(CPUPPCState, reserve_val2));
3464
3465     tcg_temp_free(EA);
3466 }
3467
3468 /* stdcx. */
3469 STCX(stdcx_, 8);
3470 STCX(stqcx_, 16);
3471 #endif /* defined(TARGET_PPC64) */
3472
3473 /* sync */
3474 static void gen_sync(DisasContext *ctx)
3475 {
3476 }
3477
3478 /* wait */
3479 static void gen_wait(DisasContext *ctx)
3480 {
3481     TCGv_i32 t0 = tcg_temp_new_i32();
3482     tcg_gen_st_i32(t0, cpu_env,
3483                    -offsetof(PowerPCCPU, env) + offsetof(CPUState, halted));
3484     tcg_temp_free_i32(t0);
3485     /* Stop translation, as the CPU is supposed to sleep from now */
3486     gen_exception_err(ctx, EXCP_HLT, 1);
3487 }
3488
3489 /***                         Floating-point load                           ***/
3490 #define GEN_LDF(name, ldop, opc, type)                                        \
3491 static void glue(gen_, name)(DisasContext *ctx)                                       \
3492 {                                                                             \
3493     TCGv EA;                                                                  \
3494     if (unlikely(!ctx->fpu_enabled)) {                                        \
3495         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3496         return;                                                               \
3497     }                                                                         \
3498     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3499     EA = tcg_temp_new();                                                      \
3500     gen_addr_imm_index(ctx, EA, 0);                                           \
3501     gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA);                       \
3502     tcg_temp_free(EA);                                                        \
3503 }
3504
3505 #define GEN_LDUF(name, ldop, opc, type)                                       \
3506 static void glue(gen_, name##u)(DisasContext *ctx)                                    \
3507 {                                                                             \
3508     TCGv EA;                                                                  \
3509     if (unlikely(!ctx->fpu_enabled)) {                                        \
3510         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3511         return;                                                               \
3512     }                                                                         \
3513     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
3514         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
3515         return;                                                               \
3516     }                                                                         \
3517     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3518     EA = tcg_temp_new();                                                      \
3519     gen_addr_imm_index(ctx, EA, 0);                                           \
3520     gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA);                       \
3521     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
3522     tcg_temp_free(EA);                                                        \
3523 }
3524
3525 #define GEN_LDUXF(name, ldop, opc, type)                                      \
3526 static void glue(gen_, name##ux)(DisasContext *ctx)                                   \
3527 {                                                                             \
3528     TCGv EA;                                                                  \
3529     if (unlikely(!ctx->fpu_enabled)) {                                        \
3530         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3531         return;                                                               \
3532     }                                                                         \
3533     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
3534         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
3535         return;                                                               \
3536     }                                                                         \
3537     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3538     EA = tcg_temp_new();                                                      \
3539     gen_addr_reg_index(ctx, EA);                                              \
3540     gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA);                       \
3541     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
3542     tcg_temp_free(EA);                                                        \
3543 }
3544
3545 #define GEN_LDXF(name, ldop, opc2, opc3, type)                                \
3546 static void glue(gen_, name##x)(DisasContext *ctx)                                    \
3547 {                                                                             \
3548     TCGv EA;                                                                  \
3549     if (unlikely(!ctx->fpu_enabled)) {                                        \
3550         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3551         return;                                                               \
3552     }                                                                         \
3553     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3554     EA = tcg_temp_new();                                                      \
3555     gen_addr_reg_index(ctx, EA);                                              \
3556     gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA);                       \
3557     tcg_temp_free(EA);                                                        \
3558 }
3559
3560 #define GEN_LDFS(name, ldop, op, type)                                        \
3561 GEN_LDF(name, ldop, op | 0x20, type);                                         \
3562 GEN_LDUF(name, ldop, op | 0x21, type);                                        \
3563 GEN_LDUXF(name, ldop, op | 0x01, type);                                       \
3564 GEN_LDXF(name, ldop, 0x17, op | 0x00, type)
3565
3566 static inline void gen_qemu_ld32fs(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
3567 {
3568     TCGv t0 = tcg_temp_new();
3569     TCGv_i32 t1 = tcg_temp_new_i32();
3570     gen_qemu_ld32u(ctx, t0, arg2);
3571     tcg_gen_trunc_tl_i32(t1, t0);
3572     tcg_temp_free(t0);
3573     gen_helper_float32_to_float64(arg1, cpu_env, t1);
3574     tcg_temp_free_i32(t1);
3575 }
3576
3577  /* lfd lfdu lfdux lfdx */
3578 GEN_LDFS(lfd, ld64, 0x12, PPC_FLOAT);
3579  /* lfs lfsu lfsux lfsx */
3580 GEN_LDFS(lfs, ld32fs, 0x10, PPC_FLOAT);
3581
3582 /* lfdp */
3583 static void gen_lfdp(DisasContext *ctx)
3584 {
3585     TCGv EA;
3586     if (unlikely(!ctx->fpu_enabled)) {
3587         gen_exception(ctx, POWERPC_EXCP_FPU);
3588         return;
3589     }
3590     gen_set_access_type(ctx, ACCESS_FLOAT);
3591     EA = tcg_temp_new();
3592     gen_addr_imm_index(ctx, EA, 0);
3593     /* We only need to swap high and low halves. gen_qemu_ld64 does necessary
3594        64-bit byteswap already. */
3595     if (unlikely(ctx->le_mode)) {
3596         gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
3597         tcg_gen_addi_tl(EA, EA, 8);
3598         gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
3599     } else {
3600         gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
3601         tcg_gen_addi_tl(EA, EA, 8);
3602         gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
3603     }
3604     tcg_temp_free(EA);
3605 }
3606
3607 /* lfdpx */
3608 static void gen_lfdpx(DisasContext *ctx)
3609 {
3610     TCGv EA;
3611     if (unlikely(!ctx->fpu_enabled)) {
3612         gen_exception(ctx, POWERPC_EXCP_FPU);
3613         return;
3614     }
3615     gen_set_access_type(ctx, ACCESS_FLOAT);
3616     EA = tcg_temp_new();
3617     gen_addr_reg_index(ctx, EA);
3618     /* We only need to swap high and low halves. gen_qemu_ld64 does necessary
3619        64-bit byteswap already. */
3620     if (unlikely(ctx->le_mode)) {
3621         gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
3622         tcg_gen_addi_tl(EA, EA, 8);
3623         gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
3624     } else {
3625         gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
3626         tcg_gen_addi_tl(EA, EA, 8);
3627         gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
3628     }
3629     tcg_temp_free(EA);
3630 }
3631
3632 /* lfiwax */
3633 static void gen_lfiwax(DisasContext *ctx)
3634 {
3635     TCGv EA;
3636     TCGv t0;
3637     if (unlikely(!ctx->fpu_enabled)) {
3638         gen_exception(ctx, POWERPC_EXCP_FPU);
3639         return;
3640     }
3641     gen_set_access_type(ctx, ACCESS_FLOAT);
3642     EA = tcg_temp_new();
3643     t0 = tcg_temp_new();
3644     gen_addr_reg_index(ctx, EA);
3645     gen_qemu_ld32s(ctx, t0, EA);
3646     tcg_gen_ext_tl_i64(cpu_fpr[rD(ctx->opcode)], t0);
3647     tcg_temp_free(EA);
3648     tcg_temp_free(t0);
3649 }
3650
3651 /* lfiwzx */
3652 static void gen_lfiwzx(DisasContext *ctx)
3653 {
3654     TCGv EA;
3655     if (unlikely(!ctx->fpu_enabled)) {
3656         gen_exception(ctx, POWERPC_EXCP_FPU);
3657         return;
3658     }
3659     gen_set_access_type(ctx, ACCESS_FLOAT);
3660     EA = tcg_temp_new();
3661     gen_addr_reg_index(ctx, EA);
3662     gen_qemu_ld32u_i64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
3663     tcg_temp_free(EA);
3664 }
3665 /***                         Floating-point store                          ***/
3666 #define GEN_STF(name, stop, opc, type)                                        \
3667 static void glue(gen_, name)(DisasContext *ctx)                                       \
3668 {                                                                             \
3669     TCGv EA;                                                                  \
3670     if (unlikely(!ctx->fpu_enabled)) {                                        \
3671         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3672         return;                                                               \
3673     }                                                                         \
3674     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3675     EA = tcg_temp_new();                                                      \
3676     gen_addr_imm_index(ctx, EA, 0);                                           \
3677     gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA);                       \
3678     tcg_temp_free(EA);                                                        \
3679 }
3680
3681 #define GEN_STUF(name, stop, opc, type)                                       \
3682 static void glue(gen_, name##u)(DisasContext *ctx)                                    \
3683 {                                                                             \
3684     TCGv EA;                                                                  \
3685     if (unlikely(!ctx->fpu_enabled)) {                                        \
3686         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3687         return;                                                               \
3688     }                                                                         \
3689     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
3690         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
3691         return;                                                               \
3692     }                                                                         \
3693     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3694     EA = tcg_temp_new();                                                      \
3695     gen_addr_imm_index(ctx, EA, 0);                                           \
3696     gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA);                       \
3697     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
3698     tcg_temp_free(EA);                                                        \
3699 }
3700
3701 #define GEN_STUXF(name, stop, opc, type)                                      \
3702 static void glue(gen_, name##ux)(DisasContext *ctx)                                   \
3703 {                                                                             \
3704     TCGv EA;                                                                  \
3705     if (unlikely(!ctx->fpu_enabled)) {                                        \
3706         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3707         return;                                                               \
3708     }                                                                         \
3709     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
3710         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
3711         return;                                                               \
3712     }                                                                         \
3713     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3714     EA = tcg_temp_new();                                                      \
3715     gen_addr_reg_index(ctx, EA);                                              \
3716     gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA);                       \
3717     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
3718     tcg_temp_free(EA);                                                        \
3719 }
3720
3721 #define GEN_STXF(name, stop, opc2, opc3, type)                                \
3722 static void glue(gen_, name##x)(DisasContext *ctx)                                    \
3723 {                                                                             \
3724     TCGv EA;                                                                  \
3725     if (unlikely(!ctx->fpu_enabled)) {                                        \
3726         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3727         return;                                                               \
3728     }                                                                         \
3729     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3730     EA = tcg_temp_new();                                                      \
3731     gen_addr_reg_index(ctx, EA);                                              \
3732     gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA);                       \
3733     tcg_temp_free(EA);                                                        \
3734 }
3735
3736 #define GEN_STFS(name, stop, op, type)                                        \
3737 GEN_STF(name, stop, op | 0x20, type);                                         \
3738 GEN_STUF(name, stop, op | 0x21, type);                                        \
3739 GEN_STUXF(name, stop, op | 0x01, type);                                       \
3740 GEN_STXF(name, stop, 0x17, op | 0x00, type)
3741
3742 static inline void gen_qemu_st32fs(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
3743 {
3744     TCGv_i32 t0 = tcg_temp_new_i32();
3745     TCGv t1 = tcg_temp_new();
3746     gen_helper_float64_to_float32(t0, cpu_env, arg1);
3747     tcg_gen_extu_i32_tl(t1, t0);
3748     tcg_temp_free_i32(t0);
3749     gen_qemu_st32(ctx, t1, arg2);
3750     tcg_temp_free(t1);
3751 }
3752
3753 /* stfd stfdu stfdux stfdx */
3754 GEN_STFS(stfd, st64, 0x16, PPC_FLOAT);
3755 /* stfs stfsu stfsux stfsx */
3756 GEN_STFS(stfs, st32fs, 0x14, PPC_FLOAT);
3757
3758 /* stfdp */
3759 static void gen_stfdp(DisasContext *ctx)
3760 {
3761     TCGv EA;
3762     if (unlikely(!ctx->fpu_enabled)) {
3763         gen_exception(ctx, POWERPC_EXCP_FPU);
3764         return;
3765     }
3766     gen_set_access_type(ctx, ACCESS_FLOAT);
3767     EA = tcg_temp_new();
3768     gen_addr_imm_index(ctx, EA, 0);
3769     /* We only need to swap high and low halves. gen_qemu_st64 does necessary
3770        64-bit byteswap already. */
3771     if (unlikely(ctx->le_mode)) {
3772         gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
3773         tcg_gen_addi_tl(EA, EA, 8);
3774         gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
3775     } else {
3776         gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
3777         tcg_gen_addi_tl(EA, EA, 8);
3778         gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
3779     }
3780     tcg_temp_free(EA);
3781 }
3782
3783 /* stfdpx */
3784 static void gen_stfdpx(DisasContext *ctx)
3785 {
3786     TCGv EA;
3787     if (unlikely(!ctx->fpu_enabled)) {
3788         gen_exception(ctx, POWERPC_EXCP_FPU);
3789         return;
3790     }
3791     gen_set_access_type(ctx, ACCESS_FLOAT);
3792     EA = tcg_temp_new();
3793     gen_addr_reg_index(ctx, EA);
3794     /* We only need to swap high and low halves. gen_qemu_st64 does necessary
3795        64-bit byteswap already. */
3796     if (unlikely(ctx->le_mode)) {
3797         gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
3798         tcg_gen_addi_tl(EA, EA, 8);
3799         gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
3800     } else {
3801         gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
3802         tcg_gen_addi_tl(EA, EA, 8);
3803         gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
3804     }
3805     tcg_temp_free(EA);
3806 }
3807
3808 /* Optional: */
3809 static inline void gen_qemu_st32fiw(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
3810 {
3811     TCGv t0 = tcg_temp_new();
3812     tcg_gen_trunc_i64_tl(t0, arg1),
3813     gen_qemu_st32(ctx, t0, arg2);
3814     tcg_temp_free(t0);
3815 }
3816 /* stfiwx */
3817 GEN_STXF(stfiw, st32fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX);
3818
3819 static inline void gen_update_cfar(DisasContext *ctx, target_ulong nip)
3820 {
3821 #if defined(TARGET_PPC64)
3822     if (ctx->has_cfar)
3823         tcg_gen_movi_tl(cpu_cfar, nip);
3824 #endif
3825 }
3826
3827 /***                                Branch                                 ***/
3828 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
3829 {
3830     TranslationBlock *tb;
3831     tb = ctx->tb;
3832     if (NARROW_MODE(ctx)) {
3833         dest = (uint32_t) dest;
3834     }
3835     if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3836         likely(!ctx->singlestep_enabled)) {
3837         tcg_gen_goto_tb(n);
3838         tcg_gen_movi_tl(cpu_nip, dest & ~3);
3839         tcg_gen_exit_tb((uintptr_t)tb + n);
3840     } else {
3841         tcg_gen_movi_tl(cpu_nip, dest & ~3);
3842         if (unlikely(ctx->singlestep_enabled)) {
3843             if ((ctx->singlestep_enabled &
3844                 (CPU_BRANCH_STEP | CPU_SINGLE_STEP)) &&
3845                 (ctx->exception == POWERPC_EXCP_BRANCH ||
3846                  ctx->exception == POWERPC_EXCP_TRACE)) {
3847                 target_ulong tmp = ctx->nip;
3848                 ctx->nip = dest;
3849                 gen_exception(ctx, POWERPC_EXCP_TRACE);
3850                 ctx->nip = tmp;
3851             }
3852             if (ctx->singlestep_enabled & GDBSTUB_SINGLE_STEP) {
3853                 gen_debug_exception(ctx);
3854             }
3855         }
3856         tcg_gen_exit_tb(0);
3857     }
3858 }
3859
3860 static inline void gen_setlr(DisasContext *ctx, target_ulong nip)
3861 {
3862     if (NARROW_MODE(ctx)) {
3863         nip = (uint32_t)nip;
3864     }
3865     tcg_gen_movi_tl(cpu_lr, nip);
3866 }
3867
3868 /* b ba bl bla */
3869 static void gen_b(DisasContext *ctx)
3870 {
3871     target_ulong li, target;
3872
3873     ctx->exception = POWERPC_EXCP_BRANCH;
3874     /* sign extend LI */
3875     li = LI(ctx->opcode);
3876     li = (li ^ 0x02000000) - 0x02000000;
3877     if (likely(AA(ctx->opcode) == 0)) {
3878         target = ctx->nip + li - 4;
3879     } else {
3880         target = li;
3881     }
3882     if (LK(ctx->opcode)) {
3883         gen_setlr(ctx, ctx->nip);
3884     }
3885     gen_update_cfar(ctx, ctx->nip);
3886     gen_goto_tb(ctx, 0, target);
3887 }
3888
3889 #define BCOND_IM  0
3890 #define BCOND_LR  1
3891 #define BCOND_CTR 2
3892 #define BCOND_TAR 3
3893
3894 static inline void gen_bcond(DisasContext *ctx, int type)
3895 {
3896     uint32_t bo = BO(ctx->opcode);
3897     TCGLabel *l1;
3898     TCGv target;
3899
3900     ctx->exception = POWERPC_EXCP_BRANCH;
3901     if (type == BCOND_LR || type == BCOND_CTR || type == BCOND_TAR) {
3902         target = tcg_temp_local_new();
3903         if (type == BCOND_CTR)
3904             tcg_gen_mov_tl(target, cpu_ctr);
3905         else if (type == BCOND_TAR)
3906             gen_load_spr(target, SPR_TAR);
3907         else
3908             tcg_gen_mov_tl(target, cpu_lr);
3909     } else {
3910         TCGV_UNUSED(target);
3911     }
3912     if (LK(ctx->opcode))
3913         gen_setlr(ctx, ctx->nip);
3914     l1 = gen_new_label();
3915     if ((bo & 0x4) == 0) {
3916         /* Decrement and test CTR */
3917         TCGv temp = tcg_temp_new();
3918         if (unlikely(type == BCOND_CTR)) {
3919             gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
3920             return;
3921         }
3922         tcg_gen_subi_tl(cpu_ctr, cpu_ctr, 1);
3923         if (NARROW_MODE(ctx)) {
3924             tcg_gen_ext32u_tl(temp, cpu_ctr);
3925         } else {
3926             tcg_gen_mov_tl(temp, cpu_ctr);
3927         }
3928         if (bo & 0x2) {
3929             tcg_gen_brcondi_tl(TCG_COND_NE, temp, 0, l1);
3930         } else {
3931             tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1);
3932         }
3933         tcg_temp_free(temp);
3934     }
3935     if ((bo & 0x10) == 0) {
3936         /* Test CR */
3937         uint32_t bi = BI(ctx->opcode);
3938         uint32_t mask = 0x08 >> (bi & 0x03);
3939         TCGv_i32 temp = tcg_temp_new_i32();
3940
3941         if (bo & 0x8) {
3942             tcg_gen_andi_i32(temp, cpu_crf[bi >> 2], mask);
3943             tcg_gen_brcondi_i32(TCG_COND_EQ, temp, 0, l1);
3944         } else {
3945             tcg_gen_andi_i32(temp, cpu_crf[bi >> 2], mask);
3946             tcg_gen_brcondi_i32(TCG_COND_NE, temp, 0, l1);
3947         }
3948         tcg_temp_free_i32(temp);
3949     }
3950     gen_update_cfar(ctx, ctx->nip);
3951     if (type == BCOND_IM) {
3952         target_ulong li = (target_long)((int16_t)(BD(ctx->opcode)));
3953         if (likely(AA(ctx->opcode) == 0)) {
3954             gen_goto_tb(ctx, 0, ctx->nip + li - 4);
3955         } else {
3956             gen_goto_tb(ctx, 0, li);
3957         }
3958         gen_set_label(l1);
3959         gen_goto_tb(ctx, 1, ctx->nip);
3960     } else {
3961         if (NARROW_MODE(ctx)) {
3962             tcg_gen_andi_tl(cpu_nip, target, (uint32_t)~3);
3963         } else {
3964             tcg_gen_andi_tl(cpu_nip, target, ~3);
3965         }
3966         tcg_gen_exit_tb(0);
3967         gen_set_label(l1);
3968         gen_update_nip(ctx, ctx->nip);
3969         tcg_gen_exit_tb(0);
3970     }
3971     if (type == BCOND_LR || type == BCOND_CTR || type == BCOND_TAR) {
3972         tcg_temp_free(target);
3973     }
3974 }
3975
3976 static void gen_bc(DisasContext *ctx)
3977 {
3978     gen_bcond(ctx, BCOND_IM);
3979 }
3980
3981 static void gen_bcctr(DisasContext *ctx)
3982 {
3983     gen_bcond(ctx, BCOND_CTR);
3984 }
3985
3986 static void gen_bclr(DisasContext *ctx)
3987 {
3988     gen_bcond(ctx, BCOND_LR);
3989 }
3990
3991 static void gen_bctar(DisasContext *ctx)
3992 {
3993     gen_bcond(ctx, BCOND_TAR);
3994 }
3995
3996 /***                      Condition register logical                       ***/
3997 #define GEN_CRLOGIC(name, tcg_op, opc)                                        \
3998 static void glue(gen_, name)(DisasContext *ctx)                                       \
3999 {                                                                             \
4000     uint8_t bitmask;                                                          \
4001     int sh;                                                                   \
4002     TCGv_i32 t0, t1;                                                          \
4003     sh = (crbD(ctx->opcode) & 0x03) - (crbA(ctx->opcode) & 0x03);             \
4004     t0 = tcg_temp_new_i32();                                                  \
4005     if (sh > 0)                                                               \
4006         tcg_gen_shri_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2], sh);            \
4007     else if (sh < 0)                                                          \
4008         tcg_gen_shli_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2], -sh);           \
4009     else                                                                      \
4010         tcg_gen_mov_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2]);                 \
4011     t1 = tcg_temp_new_i32();                                                  \
4012     sh = (crbD(ctx->opcode) & 0x03) - (crbB(ctx->opcode) & 0x03);             \
4013     if (sh > 0)                                                               \
4014         tcg_gen_shri_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2], sh);            \
4015     else if (sh < 0)                                                          \
4016         tcg_gen_shli_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2], -sh);           \
4017     else                                                                      \
4018         tcg_gen_mov_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2]);                 \
4019     tcg_op(t0, t0, t1);                                                       \
4020     bitmask = 0x08 >> (crbD(ctx->opcode) & 0x03);                             \
4021     tcg_gen_andi_i32(t0, t0, bitmask);                                        \
4022     tcg_gen_andi_i32(t1, cpu_crf[crbD(ctx->opcode) >> 2], ~bitmask);          \
4023     tcg_gen_or_i32(cpu_crf[crbD(ctx->opcode) >> 2], t0, t1);                  \
4024     tcg_temp_free_i32(t0);                                                    \
4025     tcg_temp_free_i32(t1);                                                    \
4026 }
4027
4028 /* crand */
4029 GEN_CRLOGIC(crand, tcg_gen_and_i32, 0x08);
4030 /* crandc */
4031 GEN_CRLOGIC(crandc, tcg_gen_andc_i32, 0x04);
4032 /* creqv */
4033 GEN_CRLOGIC(creqv, tcg_gen_eqv_i32, 0x09);
4034 /* crnand */
4035 GEN_CRLOGIC(crnand, tcg_gen_nand_i32, 0x07);
4036 /* crnor */
4037 GEN_CRLOGIC(crnor, tcg_gen_nor_i32, 0x01);
4038 /* cror */
4039 GEN_CRLOGIC(cror, tcg_gen_or_i32, 0x0E);
4040 /* crorc */
4041 GEN_CRLOGIC(crorc, tcg_gen_orc_i32, 0x0D);
4042 /* crxor */
4043 GEN_CRLOGIC(crxor, tcg_gen_xor_i32, 0x06);
4044
4045 /* mcrf */
4046 static void gen_mcrf(DisasContext *ctx)
4047 {
4048     tcg_gen_mov_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfS(ctx->opcode)]);
4049 }
4050
4051 /***                           System linkage                              ***/
4052
4053 /* rfi (supervisor only) */
4054 static void gen_rfi(DisasContext *ctx)
4055 {
4056 #if defined(CONFIG_USER_ONLY)
4057     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4058 #else
4059     /* Restore CPU state */
4060     if (unlikely(ctx->pr)) {
4061         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4062         return;
4063     }
4064     gen_update_cfar(ctx, ctx->nip);
4065     gen_helper_rfi(cpu_env);
4066     gen_sync_exception(ctx);
4067 #endif
4068 }
4069
4070 #if defined(TARGET_PPC64)
4071 static void gen_rfid(DisasContext *ctx)
4072 {
4073 #if defined(CONFIG_USER_ONLY)
4074     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4075 #else
4076     /* Restore CPU state */
4077     if (unlikely(ctx->pr)) {
4078         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4079         return;
4080     }
4081     gen_update_cfar(ctx, ctx->nip);
4082     gen_helper_rfid(cpu_env);
4083     gen_sync_exception(ctx);
4084 #endif
4085 }
4086
4087 static void gen_hrfid(DisasContext *ctx)
4088 {
4089 #if defined(CONFIG_USER_ONLY)
4090     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4091 #else
4092     /* Restore CPU state */
4093     if (unlikely(!ctx->hv)) {
4094         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4095         return;
4096     }
4097     gen_helper_hrfid(cpu_env);
4098     gen_sync_exception(ctx);
4099 #endif
4100 }
4101 #endif
4102
4103 /* sc */
4104 #if defined(CONFIG_USER_ONLY)
4105 #define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL_USER
4106 #else
4107 #define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL
4108 #endif
4109 static void gen_sc(DisasContext *ctx)
4110 {
4111     uint32_t lev;
4112
4113     lev = (ctx->opcode >> 5) & 0x7F;
4114     gen_exception_err(ctx, POWERPC_SYSCALL, lev);
4115 }
4116
4117 /***                                Trap                                   ***/
4118
4119 /* tw */
4120 static void gen_tw(DisasContext *ctx)
4121 {
4122     TCGv_i32 t0 = tcg_const_i32(TO(ctx->opcode));
4123     /* Update the nip since this might generate a trap exception */
4124     gen_update_nip(ctx, ctx->nip);
4125     gen_helper_tw(cpu_env, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
4126                   t0);
4127     tcg_temp_free_i32(t0);
4128 }
4129
4130 /* twi */
4131 static void gen_twi(DisasContext *ctx)
4132 {
4133     TCGv t0 = tcg_const_tl(SIMM(ctx->opcode));
4134     TCGv_i32 t1 = tcg_const_i32(TO(ctx->opcode));
4135     /* Update the nip since this might generate a trap exception */
4136     gen_update_nip(ctx, ctx->nip);
4137     gen_helper_tw(cpu_env, cpu_gpr[rA(ctx->opcode)], t0, t1);
4138     tcg_temp_free(t0);
4139     tcg_temp_free_i32(t1);
4140 }
4141
4142 #if defined(TARGET_PPC64)
4143 /* td */
4144 static void gen_td(DisasContext *ctx)
4145 {
4146     TCGv_i32 t0 = tcg_const_i32(TO(ctx->opcode));
4147     /* Update the nip since this might generate a trap exception */
4148     gen_update_nip(ctx, ctx->nip);
4149     gen_helper_td(cpu_env, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
4150                   t0);
4151     tcg_temp_free_i32(t0);
4152 }
4153
4154 /* tdi */
4155 static void gen_tdi(DisasContext *ctx)
4156 {
4157     TCGv t0 = tcg_const_tl(SIMM(ctx->opcode));
4158     TCGv_i32 t1 = tcg_const_i32(TO(ctx->opcode));
4159     /* Update the nip since this might generate a trap exception */
4160     gen_update_nip(ctx, ctx->nip);
4161     gen_helper_td(cpu_env, cpu_gpr[rA(ctx->opcode)], t0, t1);
4162     tcg_temp_free(t0);
4163     tcg_temp_free_i32(t1);
4164 }
4165 #endif
4166
4167 /***                          Processor control                            ***/
4168
4169 static void gen_read_xer(TCGv dst)
4170 {
4171     TCGv t0 = tcg_temp_new();
4172     TCGv t1 = tcg_temp_new();
4173     TCGv t2 = tcg_temp_new();
4174     tcg_gen_mov_tl(dst, cpu_xer);
4175     tcg_gen_shli_tl(t0, cpu_so, XER_SO);
4176     tcg_gen_shli_tl(t1, cpu_ov, XER_OV);
4177     tcg_gen_shli_tl(t2, cpu_ca, XER_CA);
4178     tcg_gen_or_tl(t0, t0, t1);
4179     tcg_gen_or_tl(dst, dst, t2);
4180     tcg_gen_or_tl(dst, dst, t0);
4181     tcg_temp_free(t0);
4182     tcg_temp_free(t1);
4183     tcg_temp_free(t2);
4184 }
4185
4186 static void gen_write_xer(TCGv src)
4187 {
4188     tcg_gen_andi_tl(cpu_xer, src,
4189                     ~((1u << XER_SO) | (1u << XER_OV) | (1u << XER_CA)));
4190     tcg_gen_shri_tl(cpu_so, src, XER_SO);
4191     tcg_gen_shri_tl(cpu_ov, src, XER_OV);
4192     tcg_gen_shri_tl(cpu_ca, src, XER_CA);
4193     tcg_gen_andi_tl(cpu_so, cpu_so, 1);
4194     tcg_gen_andi_tl(cpu_ov, cpu_ov, 1);
4195     tcg_gen_andi_tl(cpu_ca, cpu_ca, 1);
4196 }
4197
4198 /* mcrxr */
4199 static void gen_mcrxr(DisasContext *ctx)
4200 {
4201     TCGv_i32 t0 = tcg_temp_new_i32();
4202     TCGv_i32 t1 = tcg_temp_new_i32();
4203     TCGv_i32 dst = cpu_crf[crfD(ctx->opcode)];
4204
4205     tcg_gen_trunc_tl_i32(t0, cpu_so);
4206     tcg_gen_trunc_tl_i32(t1, cpu_ov);
4207     tcg_gen_trunc_tl_i32(dst, cpu_ca);
4208     tcg_gen_shli_i32(t0, t0, 3);
4209     tcg_gen_shli_i32(t1, t1, 2);
4210     tcg_gen_shli_i32(dst, dst, 1);
4211     tcg_gen_or_i32(dst, dst, t0);
4212     tcg_gen_or_i32(dst, dst, t1);
4213     tcg_temp_free_i32(t0);
4214     tcg_temp_free_i32(t1);
4215
4216     tcg_gen_movi_tl(cpu_so, 0);
4217     tcg_gen_movi_tl(cpu_ov, 0);
4218     tcg_gen_movi_tl(cpu_ca, 0);
4219 }
4220
4221 /* mfcr mfocrf */
4222 static void gen_mfcr(DisasContext *ctx)
4223 {
4224     uint32_t crm, crn;
4225
4226     if (likely(ctx->opcode & 0x00100000)) {
4227         crm = CRM(ctx->opcode);
4228         if (likely(crm && ((crm & (crm - 1)) == 0))) {
4229             crn = ctz32 (crm);
4230             tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], cpu_crf[7 - crn]);
4231             tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)],
4232                             cpu_gpr[rD(ctx->opcode)], crn * 4);
4233         }
4234     } else {
4235         TCGv_i32 t0 = tcg_temp_new_i32();
4236         tcg_gen_mov_i32(t0, cpu_crf[0]);
4237         tcg_gen_shli_i32(t0, t0, 4);
4238         tcg_gen_or_i32(t0, t0, cpu_crf[1]);
4239         tcg_gen_shli_i32(t0, t0, 4);
4240         tcg_gen_or_i32(t0, t0, cpu_crf[2]);
4241         tcg_gen_shli_i32(t0, t0, 4);
4242         tcg_gen_or_i32(t0, t0, cpu_crf[3]);
4243         tcg_gen_shli_i32(t0, t0, 4);
4244         tcg_gen_or_i32(t0, t0, cpu_crf[4]);
4245         tcg_gen_shli_i32(t0, t0, 4);
4246         tcg_gen_or_i32(t0, t0, cpu_crf[5]);
4247         tcg_gen_shli_i32(t0, t0, 4);
4248         tcg_gen_or_i32(t0, t0, cpu_crf[6]);
4249         tcg_gen_shli_i32(t0, t0, 4);
4250         tcg_gen_or_i32(t0, t0, cpu_crf[7]);
4251         tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0);
4252         tcg_temp_free_i32(t0);
4253     }
4254 }
4255
4256 /* mfmsr */
4257 static void gen_mfmsr(DisasContext *ctx)
4258 {
4259 #if defined(CONFIG_USER_ONLY)
4260     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4261 #else
4262     if (unlikely(ctx->pr)) {
4263         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4264         return;
4265     }
4266     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_msr);
4267 #endif
4268 }
4269
4270 static void spr_noaccess(DisasContext *ctx, int gprn, int sprn)
4271 {
4272 #if 0
4273     sprn = ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
4274     printf("ERROR: try to access SPR %d !\n", sprn);
4275 #endif
4276 }
4277 #define SPR_NOACCESS (&spr_noaccess)
4278
4279 /* mfspr */
4280 static inline void gen_op_mfspr(DisasContext *ctx)
4281 {
4282     void (*read_cb)(DisasContext *ctx, int gprn, int sprn);
4283     uint32_t sprn = SPR(ctx->opcode);
4284
4285 #if !defined(CONFIG_USER_ONLY)
4286     if (ctx->hv)
4287         read_cb = ctx->spr_cb[sprn].hea_read;
4288     else if (!ctx->pr)
4289         read_cb = ctx->spr_cb[sprn].oea_read;
4290     else
4291 #endif
4292         read_cb = ctx->spr_cb[sprn].uea_read;
4293     if (likely(read_cb != NULL)) {
4294         if (likely(read_cb != SPR_NOACCESS)) {
4295             (*read_cb)(ctx, rD(ctx->opcode), sprn);
4296         } else {
4297             /* Privilege exception */
4298             /* This is a hack to avoid warnings when running Linux:
4299              * this OS breaks the PowerPC virtualisation model,
4300              * allowing userland application to read the PVR
4301              */
4302             if (sprn != SPR_PVR) {
4303                 fprintf(stderr, "Trying to read privileged spr %d (0x%03x) at "
4304                         TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
4305                 if (qemu_log_separate()) {
4306                     qemu_log("Trying to read privileged spr %d (0x%03x) at "
4307                              TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
4308                 }
4309             }
4310             gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4311         }
4312     } else {
4313         /* Not defined */
4314         fprintf(stderr, "Trying to read invalid spr %d (0x%03x) at "
4315                 TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
4316         if (qemu_log_separate()) {
4317             qemu_log("Trying to read invalid spr %d (0x%03x) at "
4318                      TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
4319         }
4320         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR);
4321     }
4322 }
4323
4324 static void gen_mfspr(DisasContext *ctx)
4325 {
4326     gen_op_mfspr(ctx);
4327 }
4328
4329 /* mftb */
4330 static void gen_mftb(DisasContext *ctx)
4331 {
4332     gen_op_mfspr(ctx);
4333 }
4334
4335 /* mtcrf mtocrf*/
4336 static void gen_mtcrf(DisasContext *ctx)
4337 {
4338     uint32_t crm, crn;
4339
4340     crm = CRM(ctx->opcode);
4341     if (likely((ctx->opcode & 0x00100000))) {
4342         if (crm && ((crm & (crm - 1)) == 0)) {
4343             TCGv_i32 temp = tcg_temp_new_i32();
4344             crn = ctz32 (crm);
4345             tcg_gen_trunc_tl_i32(temp, cpu_gpr[rS(ctx->opcode)]);
4346             tcg_gen_shri_i32(temp, temp, crn * 4);
4347             tcg_gen_andi_i32(cpu_crf[7 - crn], temp, 0xf);
4348             tcg_temp_free_i32(temp);
4349         }
4350     } else {
4351         TCGv_i32 temp = tcg_temp_new_i32();
4352         tcg_gen_trunc_tl_i32(temp, cpu_gpr[rS(ctx->opcode)]);
4353         for (crn = 0 ; crn < 8 ; crn++) {
4354             if (crm & (1 << crn)) {
4355                     tcg_gen_shri_i32(cpu_crf[7 - crn], temp, crn * 4);
4356                     tcg_gen_andi_i32(cpu_crf[7 - crn], cpu_crf[7 - crn], 0xf);
4357             }
4358         }
4359         tcg_temp_free_i32(temp);
4360     }
4361 }
4362
4363 /* mtmsr */
4364 #if defined(TARGET_PPC64)
4365 static void gen_mtmsrd(DisasContext *ctx)
4366 {
4367 #if defined(CONFIG_USER_ONLY)
4368     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4369 #else
4370     if (unlikely(ctx->pr)) {
4371         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4372         return;
4373     }
4374     if (ctx->opcode & 0x00010000) {
4375         /* Special form that does not need any synchronisation */
4376         TCGv t0 = tcg_temp_new();
4377         tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1 << MSR_RI) | (1 << MSR_EE));
4378         tcg_gen_andi_tl(cpu_msr, cpu_msr, ~((1 << MSR_RI) | (1 << MSR_EE)));
4379         tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
4380         tcg_temp_free(t0);
4381     } else {
4382         /* XXX: we need to update nip before the store
4383          *      if we enter power saving mode, we will exit the loop
4384          *      directly from ppc_store_msr
4385          */
4386         gen_update_nip(ctx, ctx->nip);
4387         gen_helper_store_msr(cpu_env, cpu_gpr[rS(ctx->opcode)]);
4388         /* Must stop the translation as machine state (may have) changed */
4389         /* Note that mtmsr is not always defined as context-synchronizing */
4390         gen_stop_exception(ctx);
4391     }
4392 #endif
4393 }
4394 #endif
4395
4396 static void gen_mtmsr(DisasContext *ctx)
4397 {
4398 #if defined(CONFIG_USER_ONLY)
4399     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4400 #else
4401     if (unlikely(ctx->pr)) {
4402         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4403         return;
4404     }
4405     if (ctx->opcode & 0x00010000) {
4406         /* Special form that does not need any synchronisation */
4407         TCGv t0 = tcg_temp_new();
4408         tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1 << MSR_RI) | (1 << MSR_EE));
4409         tcg_gen_andi_tl(cpu_msr, cpu_msr, ~((1 << MSR_RI) | (1 << MSR_EE)));
4410         tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
4411         tcg_temp_free(t0);
4412     } else {
4413         TCGv msr = tcg_temp_new();
4414
4415         /* XXX: we need to update nip before the store
4416          *      if we enter power saving mode, we will exit the loop
4417          *      directly from ppc_store_msr
4418          */
4419         gen_update_nip(ctx, ctx->nip);
4420 #if defined(TARGET_PPC64)
4421         tcg_gen_deposit_tl(msr, cpu_msr, cpu_gpr[rS(ctx->opcode)], 0, 32);
4422 #else
4423         tcg_gen_mov_tl(msr, cpu_gpr[rS(ctx->opcode)]);
4424 #endif
4425         gen_helper_store_msr(cpu_env, msr);
4426         tcg_temp_free(msr);
4427         /* Must stop the translation as machine state (may have) changed */
4428         /* Note that mtmsr is not always defined as context-synchronizing */
4429         gen_stop_exception(ctx);
4430     }
4431 #endif
4432 }
4433
4434 /* mtspr */
4435 static void gen_mtspr(DisasContext *ctx)
4436 {
4437     void (*write_cb)(DisasContext *ctx, int sprn, int gprn);
4438     uint32_t sprn = SPR(ctx->opcode);
4439
4440 #if !defined(CONFIG_USER_ONLY)
4441     if (ctx->hv)
4442         write_cb = ctx->spr_cb[sprn].hea_write;
4443     else if (!ctx->pr)
4444         write_cb = ctx->spr_cb[sprn].oea_write;
4445     else
4446 #endif
4447         write_cb = ctx->spr_cb[sprn].uea_write;
4448     if (likely(write_cb != NULL)) {
4449         if (likely(write_cb != SPR_NOACCESS)) {
4450             (*write_cb)(ctx, sprn, rS(ctx->opcode));
4451         } else {
4452             /* Privilege exception */
4453             fprintf(stderr, "Trying to write privileged spr %d (0x%03x) at "
4454                     TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
4455             if (qemu_log_separate()) {
4456                 qemu_log("Trying to write privileged spr %d (0x%03x) at "
4457                          TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
4458             }
4459             gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4460         }
4461     } else {
4462         /* Not defined */
4463         if (qemu_log_separate()) {
4464             qemu_log("Trying to write invalid spr %d (0x%03x) at "
4465                      TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
4466         }
4467         fprintf(stderr, "Trying to write invalid spr %d (0x%03x) at "
4468                 TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
4469         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR);
4470     }
4471 }
4472
4473 /***                         Cache management                              ***/
4474
4475 /* dcbf */
4476 static void gen_dcbf(DisasContext *ctx)
4477 {
4478     /* XXX: specification says this is treated as a load by the MMU */
4479     TCGv t0;
4480     gen_set_access_type(ctx, ACCESS_CACHE);
4481     t0 = tcg_temp_new();
4482     gen_addr_reg_index(ctx, t0);
4483     gen_qemu_ld8u(ctx, t0, t0);
4484     tcg_temp_free(t0);
4485 }
4486
4487 /* dcbi (Supervisor only) */
4488 static void gen_dcbi(DisasContext *ctx)
4489 {
4490 #if defined(CONFIG_USER_ONLY)
4491     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4492 #else
4493     TCGv EA, val;
4494     if (unlikely(ctx->pr)) {
4495         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4496         return;
4497     }
4498     EA = tcg_temp_new();
4499     gen_set_access_type(ctx, ACCESS_CACHE);
4500     gen_addr_reg_index(ctx, EA);
4501     val = tcg_temp_new();
4502     /* XXX: specification says this should be treated as a store by the MMU */
4503     gen_qemu_ld8u(ctx, val, EA);
4504     gen_qemu_st8(ctx, val, EA);
4505     tcg_temp_free(val);
4506     tcg_temp_free(EA);
4507 #endif
4508 }
4509
4510 /* dcdst */
4511 static void gen_dcbst(DisasContext *ctx)
4512 {
4513     /* XXX: specification say this is treated as a load by the MMU */
4514     TCGv t0;
4515     gen_set_access_type(ctx, ACCESS_CACHE);
4516     t0 = tcg_temp_new();
4517     gen_addr_reg_index(ctx, t0);
4518     gen_qemu_ld8u(ctx, t0, t0);
4519     tcg_temp_free(t0);
4520 }
4521
4522 /* dcbt */
4523 static void gen_dcbt(DisasContext *ctx)
4524 {
4525     /* interpreted as no-op */
4526     /* XXX: specification say this is treated as a load by the MMU
4527      *      but does not generate any exception
4528      */
4529 }
4530
4531 /* dcbtst */
4532 static void gen_dcbtst(DisasContext *ctx)
4533 {
4534     /* interpreted as no-op */
4535     /* XXX: specification say this is treated as a load by the MMU
4536      *      but does not generate any exception
4537      */
4538 }
4539
4540 /* dcbtls */
4541 static void gen_dcbtls(DisasContext *ctx)
4542 {
4543     /* Always fails locking the cache */
4544     TCGv t0 = tcg_temp_new();
4545     gen_load_spr(t0, SPR_Exxx_L1CSR0);
4546     tcg_gen_ori_tl(t0, t0, L1CSR0_CUL);
4547     gen_store_spr(SPR_Exxx_L1CSR0, t0);
4548     tcg_temp_free(t0);
4549 }
4550
4551 /* dcbz */
4552 static void gen_dcbz(DisasContext *ctx)
4553 {
4554     TCGv tcgv_addr;
4555     TCGv_i32 tcgv_is_dcbzl;
4556     int is_dcbzl = ctx->opcode & 0x00200000 ? 1 : 0;
4557
4558     gen_set_access_type(ctx, ACCESS_CACHE);
4559     /* NIP cannot be restored if the memory exception comes from an helper */
4560     gen_update_nip(ctx, ctx->nip - 4);
4561     tcgv_addr = tcg_temp_new();
4562     tcgv_is_dcbzl = tcg_const_i32(is_dcbzl);
4563
4564     gen_addr_reg_index(ctx, tcgv_addr);
4565     gen_helper_dcbz(cpu_env, tcgv_addr, tcgv_is_dcbzl);
4566
4567     tcg_temp_free(tcgv_addr);
4568     tcg_temp_free_i32(tcgv_is_dcbzl);
4569 }
4570
4571 /* dst / dstt */
4572 static void gen_dst(DisasContext *ctx)
4573 {
4574     if (rA(ctx->opcode) == 0) {
4575         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_LSWX);
4576     } else {
4577         /* interpreted as no-op */
4578     }
4579 }
4580
4581 /* dstst /dststt */
4582 static void gen_dstst(DisasContext *ctx)
4583 {
4584     if (rA(ctx->opcode) == 0) {
4585         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_LSWX);
4586     } else {
4587         /* interpreted as no-op */
4588     }
4589
4590 }
4591
4592 /* dss / dssall */
4593 static void gen_dss(DisasContext *ctx)
4594 {
4595     /* interpreted as no-op */
4596 }
4597
4598 /* icbi */
4599 static void gen_icbi(DisasContext *ctx)
4600 {
4601     TCGv t0;
4602     gen_set_access_type(ctx, ACCESS_CACHE);
4603     /* NIP cannot be restored if the memory exception comes from an helper */
4604     gen_update_nip(ctx, ctx->nip - 4);
4605     t0 = tcg_temp_new();
4606     gen_addr_reg_index(ctx, t0);
4607     gen_helper_icbi(cpu_env, t0);
4608     tcg_temp_free(t0);
4609 }
4610
4611 /* Optional: */
4612 /* dcba */
4613 static void gen_dcba(DisasContext *ctx)
4614 {
4615     /* interpreted as no-op */
4616     /* XXX: specification say this is treated as a store by the MMU
4617      *      but does not generate any exception
4618      */
4619 }
4620
4621 /***                    Segment register manipulation                      ***/
4622 /* Supervisor only: */
4623
4624 /* mfsr */
4625 static void gen_mfsr(DisasContext *ctx)
4626 {
4627 #if defined(CONFIG_USER_ONLY)
4628     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4629 #else
4630     TCGv t0;
4631     if (unlikely(ctx->pr)) {
4632         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4633         return;
4634     }
4635     t0 = tcg_const_tl(SR(ctx->opcode));
4636     gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
4637     tcg_temp_free(t0);
4638 #endif
4639 }
4640
4641 /* mfsrin */
4642 static void gen_mfsrin(DisasContext *ctx)
4643 {
4644 #if defined(CONFIG_USER_ONLY)
4645     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4646 #else
4647     TCGv t0;
4648     if (unlikely(ctx->pr)) {
4649         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4650         return;
4651     }
4652     t0 = tcg_temp_new();
4653     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
4654     tcg_gen_andi_tl(t0, t0, 0xF);
4655     gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
4656     tcg_temp_free(t0);
4657 #endif
4658 }
4659
4660 /* mtsr */
4661 static void gen_mtsr(DisasContext *ctx)
4662 {
4663 #if defined(CONFIG_USER_ONLY)
4664     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4665 #else
4666     TCGv t0;
4667     if (unlikely(ctx->pr)) {
4668         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4669         return;
4670     }
4671     t0 = tcg_const_tl(SR(ctx->opcode));
4672     gen_helper_store_sr(cpu_env, t0, cpu_gpr[rS(ctx->opcode)]);
4673     tcg_temp_free(t0);
4674 #endif
4675 }
4676
4677 /* mtsrin */
4678 static void gen_mtsrin(DisasContext *ctx)
4679 {
4680 #if defined(CONFIG_USER_ONLY)
4681     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4682 #else
4683     TCGv t0;
4684     if (unlikely(ctx->pr)) {
4685         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4686         return;
4687     }
4688     t0 = tcg_temp_new();
4689     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
4690     tcg_gen_andi_tl(t0, t0, 0xF);
4691     gen_helper_store_sr(cpu_env, t0, cpu_gpr[rD(ctx->opcode)]);
4692     tcg_temp_free(t0);
4693 #endif
4694 }
4695
4696 #if defined(TARGET_PPC64)
4697 /* Specific implementation for PowerPC 64 "bridge" emulation using SLB */
4698
4699 /* mfsr */
4700 static void gen_mfsr_64b(DisasContext *ctx)
4701 {
4702 #if defined(CONFIG_USER_ONLY)
4703     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4704 #else
4705     TCGv t0;
4706     if (unlikely(ctx->pr)) {
4707         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4708         return;
4709     }
4710     t0 = tcg_const_tl(SR(ctx->opcode));
4711     gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
4712     tcg_temp_free(t0);
4713 #endif
4714 }
4715
4716 /* mfsrin */
4717 static void gen_mfsrin_64b(DisasContext *ctx)
4718 {
4719 #if defined(CONFIG_USER_ONLY)
4720     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4721 #else
4722     TCGv t0;
4723     if (unlikely(ctx->pr)) {
4724         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4725         return;
4726     }
4727     t0 = tcg_temp_new();
4728     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
4729     tcg_gen_andi_tl(t0, t0, 0xF);
4730     gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
4731     tcg_temp_free(t0);
4732 #endif
4733 }
4734
4735 /* mtsr */
4736 static void gen_mtsr_64b(DisasContext *ctx)
4737 {
4738 #if defined(CONFIG_USER_ONLY)
4739     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4740 #else
4741     TCGv t0;
4742     if (unlikely(ctx->pr)) {
4743         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4744         return;
4745     }
4746     t0 = tcg_const_tl(SR(ctx->opcode));
4747     gen_helper_store_sr(cpu_env, t0, cpu_gpr[rS(ctx->opcode)]);
4748     tcg_temp_free(t0);
4749 #endif
4750 }
4751
4752 /* mtsrin */
4753 static void gen_mtsrin_64b(DisasContext *ctx)
4754 {
4755 #if defined(CONFIG_USER_ONLY)
4756     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4757 #else
4758     TCGv t0;
4759     if (unlikely(ctx->pr)) {
4760         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4761         return;
4762     }
4763     t0 = tcg_temp_new();
4764     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
4765     tcg_gen_andi_tl(t0, t0, 0xF);
4766     gen_helper_store_sr(cpu_env, t0, cpu_gpr[rS(ctx->opcode)]);
4767     tcg_temp_free(t0);
4768 #endif
4769 }
4770
4771 /* slbmte */
4772 static void gen_slbmte(DisasContext *ctx)
4773 {
4774 #if defined(CONFIG_USER_ONLY)
4775     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4776 #else
4777     if (unlikely(ctx->pr)) {
4778         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4779         return;
4780     }
4781     gen_helper_store_slb(cpu_env, cpu_gpr[rB(ctx->opcode)],
4782                          cpu_gpr[rS(ctx->opcode)]);
4783 #endif
4784 }
4785
4786 static void gen_slbmfee(DisasContext *ctx)
4787 {
4788 #if defined(CONFIG_USER_ONLY)
4789     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4790 #else
4791     if (unlikely(ctx->pr)) {
4792         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4793         return;
4794     }
4795     gen_helper_load_slb_esid(cpu_gpr[rS(ctx->opcode)], cpu_env,
4796                              cpu_gpr[rB(ctx->opcode)]);
4797 #endif
4798 }
4799
4800 static void gen_slbmfev(DisasContext *ctx)
4801 {
4802 #if defined(CONFIG_USER_ONLY)
4803     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4804 #else
4805     if (unlikely(ctx->pr)) {
4806         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4807         return;
4808     }
4809     gen_helper_load_slb_vsid(cpu_gpr[rS(ctx->opcode)], cpu_env,
4810                              cpu_gpr[rB(ctx->opcode)]);
4811 #endif
4812 }
4813 #endif /* defined(TARGET_PPC64) */
4814
4815 /***                      Lookaside buffer management                      ***/
4816 /* Optional & supervisor only: */
4817
4818 /* tlbia */
4819 static void gen_tlbia(DisasContext *ctx)
4820 {
4821 #if defined(CONFIG_USER_ONLY)
4822     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4823 #else
4824     if (unlikely(ctx->pr)) {
4825         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4826         return;
4827     }
4828     gen_helper_tlbia(cpu_env);
4829 #endif
4830 }
4831
4832 /* tlbiel */
4833 static void gen_tlbiel(DisasContext *ctx)
4834 {
4835 #if defined(CONFIG_USER_ONLY)
4836     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4837 #else
4838     if (unlikely(ctx->pr)) {
4839         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4840         return;
4841     }
4842     gen_helper_tlbie(cpu_env, cpu_gpr[rB(ctx->opcode)]);
4843 #endif
4844 }
4845
4846 /* tlbie */
4847 static void gen_tlbie(DisasContext *ctx)
4848 {
4849 #if defined(CONFIG_USER_ONLY)
4850     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4851 #else
4852     if (unlikely(ctx->pr)) {
4853         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4854         return;
4855     }
4856     if (NARROW_MODE(ctx)) {
4857         TCGv t0 = tcg_temp_new();
4858         tcg_gen_ext32u_tl(t0, cpu_gpr[rB(ctx->opcode)]);
4859         gen_helper_tlbie(cpu_env, t0);
4860         tcg_temp_free(t0);
4861     } else {
4862         gen_helper_tlbie(cpu_env, cpu_gpr[rB(ctx->opcode)]);
4863     }
4864 #endif
4865 }
4866
4867 /* tlbsync */
4868 static void gen_tlbsync(DisasContext *ctx)
4869 {
4870 #if defined(CONFIG_USER_ONLY)
4871     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4872 #else
4873     if (unlikely(ctx->pr)) {
4874         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4875         return;
4876     }
4877     /* This has no effect: it should ensure that all previous
4878      * tlbie have completed
4879      */
4880     gen_stop_exception(ctx);
4881 #endif
4882 }
4883
4884 #if defined(TARGET_PPC64)
4885 /* slbia */
4886 static void gen_slbia(DisasContext *ctx)
4887 {
4888 #if defined(CONFIG_USER_ONLY)
4889     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4890 #else
4891     if (unlikely(ctx->pr)) {
4892         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4893         return;
4894     }
4895     gen_helper_slbia(cpu_env);
4896 #endif
4897 }
4898
4899 /* slbie */
4900 static void gen_slbie(DisasContext *ctx)
4901 {
4902 #if defined(CONFIG_USER_ONLY)
4903     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4904 #else
4905     if (unlikely(ctx->pr)) {
4906         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4907         return;
4908     }
4909     gen_helper_slbie(cpu_env, cpu_gpr[rB(ctx->opcode)]);
4910 #endif
4911 }
4912 #endif
4913
4914 /***                              External control                         ***/
4915 /* Optional: */
4916
4917 /* eciwx */
4918 static void gen_eciwx(DisasContext *ctx)
4919 {
4920     TCGv t0;
4921     /* Should check EAR[E] ! */
4922     gen_set_access_type(ctx, ACCESS_EXT);
4923     t0 = tcg_temp_new();
4924     gen_addr_reg_index(ctx, t0);
4925     gen_check_align(ctx, t0, 0x03);
4926     gen_qemu_ld32u(ctx, cpu_gpr[rD(ctx->opcode)], t0);
4927     tcg_temp_free(t0);
4928 }
4929
4930 /* ecowx */
4931 static void gen_ecowx(DisasContext *ctx)
4932 {
4933     TCGv t0;
4934     /* Should check EAR[E] ! */
4935     gen_set_access_type(ctx, ACCESS_EXT);
4936     t0 = tcg_temp_new();
4937     gen_addr_reg_index(ctx, t0);
4938     gen_check_align(ctx, t0, 0x03);
4939     gen_qemu_st32(ctx, cpu_gpr[rD(ctx->opcode)], t0);
4940     tcg_temp_free(t0);
4941 }
4942
4943 /* PowerPC 601 specific instructions */
4944
4945 /* abs - abs. */
4946 static void gen_abs(DisasContext *ctx)
4947 {
4948     TCGLabel *l1 = gen_new_label();
4949     TCGLabel *l2 = gen_new_label();
4950     tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rA(ctx->opcode)], 0, l1);
4951     tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4952     tcg_gen_br(l2);
4953     gen_set_label(l1);
4954     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4955     gen_set_label(l2);
4956     if (unlikely(Rc(ctx->opcode) != 0))
4957         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4958 }
4959
4960 /* abso - abso. */
4961 static void gen_abso(DisasContext *ctx)
4962 {
4963     TCGLabel *l1 = gen_new_label();
4964     TCGLabel *l2 = gen_new_label();
4965     TCGLabel *l3 = gen_new_label();
4966     /* Start with XER OV disabled, the most likely case */
4967     tcg_gen_movi_tl(cpu_ov, 0);
4968     tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rA(ctx->opcode)], 0, l2);
4969     tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rA(ctx->opcode)], 0x80000000, l1);
4970     tcg_gen_movi_tl(cpu_ov, 1);
4971     tcg_gen_movi_tl(cpu_so, 1);
4972     tcg_gen_br(l2);
4973     gen_set_label(l1);
4974     tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4975     tcg_gen_br(l3);
4976     gen_set_label(l2);
4977     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4978     gen_set_label(l3);
4979     if (unlikely(Rc(ctx->opcode) != 0))
4980         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4981 }
4982
4983 /* clcs */
4984 static void gen_clcs(DisasContext *ctx)
4985 {
4986     TCGv_i32 t0 = tcg_const_i32(rA(ctx->opcode));
4987     gen_helper_clcs(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
4988     tcg_temp_free_i32(t0);
4989     /* Rc=1 sets CR0 to an undefined state */
4990 }
4991
4992 /* div - div. */
4993 static void gen_div(DisasContext *ctx)
4994 {
4995     gen_helper_div(cpu_gpr[rD(ctx->opcode)], cpu_env, cpu_gpr[rA(ctx->opcode)],
4996                    cpu_gpr[rB(ctx->opcode)]);
4997     if (unlikely(Rc(ctx->opcode) != 0))
4998         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4999 }
5000
5001 /* divo - divo. */
5002 static void gen_divo(DisasContext *ctx)
5003 {
5004     gen_helper_divo(cpu_gpr[rD(ctx->opcode)], cpu_env, cpu_gpr[rA(ctx->opcode)],
5005                     cpu_gpr[rB(ctx->opcode)]);
5006     if (unlikely(Rc(ctx->opcode) != 0))
5007         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
5008 }
5009
5010 /* divs - divs. */
5011 static void gen_divs(DisasContext *ctx)
5012 {
5013     gen_helper_divs(cpu_gpr[rD(ctx->opcode)], cpu_env, cpu_gpr[rA(ctx->opcode)],
5014                     cpu_gpr[rB(ctx->opcode)]);
5015     if (unlikely(Rc(ctx->opcode) != 0))
5016         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
5017 }
5018
5019 /* divso - divso. */
5020 static void gen_divso(DisasContext *ctx)
5021 {
5022     gen_helper_divso(cpu_gpr[rD(ctx->opcode)], cpu_env,
5023                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
5024     if (unlikely(Rc(ctx->opcode) != 0))
5025         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
5026 }
5027
5028 /* doz - doz. */
5029 static void gen_doz(DisasContext *ctx)
5030 {
5031     TCGLabel *l1 = gen_new_label();
5032     TCGLabel *l2 = gen_new_label();
5033     tcg_gen_brcond_tl(TCG_COND_GE, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], l1);
5034     tcg_gen_sub_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5035     tcg_gen_br(l2);
5036     gen_set_label(l1);
5037     tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
5038     gen_set_label(l2);
5039     if (unlikely(Rc(ctx->opcode) != 0))
5040         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
5041 }
5042
5043 /* dozo - dozo. */
5044 static void gen_dozo(DisasContext *ctx)
5045 {
5046     TCGLabel *l1 = gen_new_label();
5047     TCGLabel *l2 = gen_new_label();
5048     TCGv t0 = tcg_temp_new();
5049     TCGv t1 = tcg_temp_new();
5050     TCGv t2 = tcg_temp_new();
5051     /* Start with XER OV disabled, the most likely case */
5052     tcg_gen_movi_tl(cpu_ov, 0);
5053     tcg_gen_brcond_tl(TCG_COND_GE, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], l1);
5054     tcg_gen_sub_tl(t0, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5055     tcg_gen_xor_tl(t1, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5056     tcg_gen_xor_tl(t2, cpu_gpr[rA(ctx->opcode)], t0);
5057     tcg_gen_andc_tl(t1, t1, t2);
5058     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
5059     tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l2);
5060     tcg_gen_movi_tl(cpu_ov, 1);
5061     tcg_gen_movi_tl(cpu_so, 1);
5062     tcg_gen_br(l2);
5063     gen_set_label(l1);
5064     tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
5065     gen_set_label(l2);
5066     tcg_temp_free(t0);
5067     tcg_temp_free(t1);
5068     tcg_temp_free(t2);
5069     if (unlikely(Rc(ctx->opcode) != 0))
5070         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
5071 }
5072
5073 /* dozi */
5074 static void gen_dozi(DisasContext *ctx)
5075 {
5076     target_long simm = SIMM(ctx->opcode);
5077     TCGLabel *l1 = gen_new_label();
5078     TCGLabel *l2 = gen_new_label();
5079     tcg_gen_brcondi_tl(TCG_COND_LT, cpu_gpr[rA(ctx->opcode)], simm, l1);
5080     tcg_gen_subfi_tl(cpu_gpr[rD(ctx->opcode)], simm, cpu_gpr[rA(ctx->opcode)]);
5081     tcg_gen_br(l2);
5082     gen_set_label(l1);
5083     tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
5084     gen_set_label(l2);
5085     if (unlikely(Rc(ctx->opcode) != 0))
5086         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
5087 }
5088
5089 /* lscbx - lscbx. */
5090 static void gen_lscbx(DisasContext *ctx)
5091 {
5092     TCGv t0 = tcg_temp_new();
5093     TCGv_i32 t1 = tcg_const_i32(rD(ctx->opcode));
5094     TCGv_i32 t2 = tcg_const_i32(rA(ctx->opcode));
5095     TCGv_i32 t3 = tcg_const_i32(rB(ctx->opcode));
5096
5097     gen_addr_reg_index(ctx, t0);
5098     /* NIP cannot be restored if the memory exception comes from an helper */
5099     gen_update_nip(ctx, ctx->nip - 4);
5100     gen_helper_lscbx(t0, cpu_env, t0, t1, t2, t3);
5101     tcg_temp_free_i32(t1);
5102     tcg_temp_free_i32(t2);
5103     tcg_temp_free_i32(t3);
5104     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~0x7F);
5105     tcg_gen_or_tl(cpu_xer, cpu_xer, t0);
5106     if (unlikely(Rc(ctx->opcode) != 0))
5107         gen_set_Rc0(ctx, t0);
5108     tcg_temp_free(t0);
5109 }
5110
5111 /* maskg - maskg. */
5112 static void gen_maskg(DisasContext *ctx)
5113 {
5114     TCGLabel *l1 = gen_new_label();
5115     TCGv t0 = tcg_temp_new();
5116     TCGv t1 = tcg_temp_new();
5117     TCGv t2 = tcg_temp_new();
5118     TCGv t3 = tcg_temp_new();
5119     tcg_gen_movi_tl(t3, 0xFFFFFFFF);
5120     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
5121     tcg_gen_andi_tl(t1, cpu_gpr[rS(ctx->opcode)], 0x1F);
5122     tcg_gen_addi_tl(t2, t0, 1);
5123     tcg_gen_shr_tl(t2, t3, t2);
5124     tcg_gen_shr_tl(t3, t3, t1);
5125     tcg_gen_xor_tl(cpu_gpr[rA(ctx->opcode)], t2, t3);
5126     tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
5127     tcg_gen_neg_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5128     gen_set_label(l1);
5129     tcg_temp_free(t0);
5130     tcg_temp_free(t1);
5131     tcg_temp_free(t2);
5132     tcg_temp_free(t3);
5133     if (unlikely(Rc(ctx->opcode) != 0))
5134         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5135 }
5136
5137 /* maskir - maskir. */
5138 static void gen_maskir(DisasContext *ctx)
5139 {
5140     TCGv t0 = tcg_temp_new();
5141     TCGv t1 = tcg_temp_new();
5142     tcg_gen_and_tl(t0, cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
5143     tcg_gen_andc_tl(t1, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
5144     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5145     tcg_temp_free(t0);
5146     tcg_temp_free(t1);
5147     if (unlikely(Rc(ctx->opcode) != 0))
5148         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5149 }
5150
5151 /* mul - mul. */
5152 static void gen_mul(DisasContext *ctx)
5153 {
5154     TCGv_i64 t0 = tcg_temp_new_i64();
5155     TCGv_i64 t1 = tcg_temp_new_i64();
5156     TCGv t2 = tcg_temp_new();
5157     tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
5158     tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
5159     tcg_gen_mul_i64(t0, t0, t1);
5160     tcg_gen_trunc_i64_tl(t2, t0);
5161     gen_store_spr(SPR_MQ, t2);
5162     tcg_gen_shri_i64(t1, t0, 32);
5163     tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t1);
5164     tcg_temp_free_i64(t0);
5165     tcg_temp_free_i64(t1);
5166     tcg_temp_free(t2);
5167     if (unlikely(Rc(ctx->opcode) != 0))
5168         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
5169 }
5170
5171 /* mulo - mulo. */
5172 static void gen_mulo(DisasContext *ctx)
5173 {
5174     TCGLabel *l1 = gen_new_label();
5175     TCGv_i64 t0 = tcg_temp_new_i64();
5176     TCGv_i64 t1 = tcg_temp_new_i64();
5177     TCGv t2 = tcg_temp_new();
5178     /* Start with XER OV disabled, the most likely case */
5179     tcg_gen_movi_tl(cpu_ov, 0);
5180     tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
5181     tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
5182     tcg_gen_mul_i64(t0, t0, t1);
5183     tcg_gen_trunc_i64_tl(t2, t0);
5184     gen_store_spr(SPR_MQ, t2);
5185     tcg_gen_shri_i64(t1, t0, 32);
5186     tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t1);
5187     tcg_gen_ext32s_i64(t1, t0);
5188     tcg_gen_brcond_i64(TCG_COND_EQ, t0, t1, l1);
5189     tcg_gen_movi_tl(cpu_ov, 1);
5190     tcg_gen_movi_tl(cpu_so, 1);
5191     gen_set_label(l1);
5192     tcg_temp_free_i64(t0);
5193     tcg_temp_free_i64(t1);
5194     tcg_temp_free(t2);
5195     if (unlikely(Rc(ctx->opcode) != 0))
5196         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
5197 }
5198
5199 /* nabs - nabs. */
5200 static void gen_nabs(DisasContext *ctx)
5201 {
5202     TCGLabel *l1 = gen_new_label();
5203     TCGLabel *l2 = gen_new_label();
5204     tcg_gen_brcondi_tl(TCG_COND_GT, cpu_gpr[rA(ctx->opcode)], 0, l1);
5205     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5206     tcg_gen_br(l2);
5207     gen_set_label(l1);
5208     tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5209     gen_set_label(l2);
5210     if (unlikely(Rc(ctx->opcode) != 0))
5211         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
5212 }
5213
5214 /* nabso - nabso. */
5215 static void gen_nabso(DisasContext *ctx)
5216 {
5217     TCGLabel *l1 = gen_new_label();
5218     TCGLabel *l2 = gen_new_label();
5219     tcg_gen_brcondi_tl(TCG_COND_GT, cpu_gpr[rA(ctx->opcode)], 0, l1);
5220     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5221     tcg_gen_br(l2);
5222     gen_set_label(l1);
5223     tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5224     gen_set_label(l2);
5225     /* nabs never overflows */
5226     tcg_gen_movi_tl(cpu_ov, 0);
5227     if (unlikely(Rc(ctx->opcode) != 0))
5228         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
5229 }
5230
5231 /* rlmi - rlmi. */
5232 static void gen_rlmi(DisasContext *ctx)
5233 {
5234     uint32_t mb = MB(ctx->opcode);
5235     uint32_t me = ME(ctx->opcode);
5236     TCGv t0 = tcg_temp_new();
5237     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
5238     tcg_gen_rotl_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
5239     tcg_gen_andi_tl(t0, t0, MASK(mb, me));
5240     tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~MASK(mb, me));
5241     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], t0);
5242     tcg_temp_free(t0);
5243     if (unlikely(Rc(ctx->opcode) != 0))
5244         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5245 }
5246
5247 /* rrib - rrib. */
5248 static void gen_rrib(DisasContext *ctx)
5249 {
5250     TCGv t0 = tcg_temp_new();
5251     TCGv t1 = tcg_temp_new();
5252     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
5253     tcg_gen_movi_tl(t1, 0x80000000);
5254     tcg_gen_shr_tl(t1, t1, t0);
5255     tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
5256     tcg_gen_and_tl(t0, t0, t1);
5257     tcg_gen_andc_tl(t1, cpu_gpr[rA(ctx->opcode)], t1);
5258     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5259     tcg_temp_free(t0);
5260     tcg_temp_free(t1);
5261     if (unlikely(Rc(ctx->opcode) != 0))
5262         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5263 }
5264
5265 /* sle - sle. */
5266 static void gen_sle(DisasContext *ctx)
5267 {
5268     TCGv t0 = tcg_temp_new();
5269     TCGv t1 = tcg_temp_new();
5270     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
5271     tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
5272     tcg_gen_subfi_tl(t1, 32, t1);
5273     tcg_gen_shr_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
5274     tcg_gen_or_tl(t1, t0, t1);
5275     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
5276     gen_store_spr(SPR_MQ, t1);
5277     tcg_temp_free(t0);
5278     tcg_temp_free(t1);
5279     if (unlikely(Rc(ctx->opcode) != 0))
5280         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5281 }
5282
5283 /* sleq - sleq. */
5284 static void gen_sleq(DisasContext *ctx)
5285 {
5286     TCGv t0 = tcg_temp_new();
5287     TCGv t1 = tcg_temp_new();
5288     TCGv t2 = tcg_temp_new();
5289     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
5290     tcg_gen_movi_tl(t2, 0xFFFFFFFF);
5291     tcg_gen_shl_tl(t2, t2, t0);
5292     tcg_gen_rotl_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
5293     gen_load_spr(t1, SPR_MQ);
5294     gen_store_spr(SPR_MQ, t0);
5295     tcg_gen_and_tl(t0, t0, t2);
5296     tcg_gen_andc_tl(t1, t1, t2);
5297     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5298     tcg_temp_free(t0);
5299     tcg_temp_free(t1);
5300     tcg_temp_free(t2);
5301     if (unlikely(Rc(ctx->opcode) != 0))
5302         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5303 }
5304
5305 /* sliq - sliq. */
5306 static void gen_sliq(DisasContext *ctx)
5307 {
5308     int sh = SH(ctx->opcode);
5309     TCGv t0 = tcg_temp_new();
5310     TCGv t1 = tcg_temp_new();
5311     tcg_gen_shli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
5312     tcg_gen_shri_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh);
5313     tcg_gen_or_tl(t1, t0, t1);
5314     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
5315     gen_store_spr(SPR_MQ, t1);
5316     tcg_temp_free(t0);
5317     tcg_temp_free(t1);
5318     if (unlikely(Rc(ctx->opcode) != 0))
5319         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5320 }
5321
5322 /* slliq - slliq. */
5323 static void gen_slliq(DisasContext *ctx)
5324 {
5325     int sh = SH(ctx->opcode);
5326     TCGv t0 = tcg_temp_new();
5327     TCGv t1 = tcg_temp_new();
5328     tcg_gen_rotli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
5329     gen_load_spr(t1, SPR_MQ);
5330     gen_store_spr(SPR_MQ, t0);
5331     tcg_gen_andi_tl(t0, t0,  (0xFFFFFFFFU << sh));
5332     tcg_gen_andi_tl(t1, t1, ~(0xFFFFFFFFU << sh));
5333     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5334     tcg_temp_free(t0);
5335     tcg_temp_free(t1);
5336     if (unlikely(Rc(ctx->opcode) != 0))
5337         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5338 }
5339
5340 /* sllq - sllq. */
5341 static void gen_sllq(DisasContext *ctx)
5342 {
5343     TCGLabel *l1 = gen_new_label();
5344     TCGLabel *l2 = gen_new_label();
5345     TCGv t0 = tcg_temp_local_new();
5346     TCGv t1 = tcg_temp_local_new();
5347     TCGv t2 = tcg_temp_local_new();
5348     tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F);
5349     tcg_gen_movi_tl(t1, 0xFFFFFFFF);
5350     tcg_gen_shl_tl(t1, t1, t2);
5351     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20);
5352     tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
5353     gen_load_spr(t0, SPR_MQ);
5354     tcg_gen_and_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5355     tcg_gen_br(l2);
5356     gen_set_label(l1);
5357     tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t2);
5358     gen_load_spr(t2, SPR_MQ);
5359     tcg_gen_andc_tl(t1, t2, t1);
5360     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5361     gen_set_label(l2);
5362     tcg_temp_free(t0);
5363     tcg_temp_free(t1);
5364     tcg_temp_free(t2);
5365     if (unlikely(Rc(ctx->opcode) != 0))
5366         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5367 }
5368
5369 /* slq - slq. */
5370 static void gen_slq(DisasContext *ctx)
5371 {
5372     TCGLabel *l1 = gen_new_label();
5373     TCGv t0 = tcg_temp_new();
5374     TCGv t1 = tcg_temp_new();
5375     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
5376     tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
5377     tcg_gen_subfi_tl(t1, 32, t1);
5378     tcg_gen_shr_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
5379     tcg_gen_or_tl(t1, t0, t1);
5380     gen_store_spr(SPR_MQ, t1);
5381     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x20);
5382     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
5383     tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5384     tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
5385     gen_set_label(l1);
5386     tcg_temp_free(t0);
5387     tcg_temp_free(t1);
5388     if (unlikely(Rc(ctx->opcode) != 0))
5389         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5390 }
5391
5392 /* sraiq - sraiq. */
5393 static void gen_sraiq(DisasContext *ctx)
5394 {
5395     int sh = SH(ctx->opcode);
5396     TCGLabel *l1 = gen_new_label();
5397     TCGv t0 = tcg_temp_new();
5398     TCGv t1 = tcg_temp_new();
5399     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
5400     tcg_gen_shli_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh);
5401     tcg_gen_or_tl(t0, t0, t1);
5402     gen_store_spr(SPR_MQ, t0);
5403     tcg_gen_movi_tl(cpu_ca, 0);
5404     tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5405     tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rS(ctx->opcode)], 0, l1);
5406     tcg_gen_movi_tl(cpu_ca, 1);
5407     gen_set_label(l1);
5408     tcg_gen_sari_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], sh);
5409     tcg_temp_free(t0);
5410     tcg_temp_free(t1);
5411     if (unlikely(Rc(ctx->opcode) != 0))
5412         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5413 }
5414
5415 /* sraq - sraq. */
5416 static void gen_sraq(DisasContext *ctx)
5417 {
5418     TCGLabel *l1 = gen_new_label();
5419     TCGLabel *l2 = gen_new_label();
5420     TCGv t0 = tcg_temp_new();
5421     TCGv t1 = tcg_temp_local_new();
5422     TCGv t2 = tcg_temp_local_new();
5423     tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F);
5424     tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t2);
5425     tcg_gen_sar_tl(t1, cpu_gpr[rS(ctx->opcode)], t2);
5426     tcg_gen_subfi_tl(t2, 32, t2);
5427     tcg_gen_shl_tl(t2, cpu_gpr[rS(ctx->opcode)], t2);
5428     tcg_gen_or_tl(t0, t0, t2);
5429     gen_store_spr(SPR_MQ, t0);
5430     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20);
5431     tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, l1);
5432     tcg_gen_mov_tl(t2, cpu_gpr[rS(ctx->opcode)]);
5433     tcg_gen_sari_tl(t1, cpu_gpr[rS(ctx->opcode)], 31);
5434     gen_set_label(l1);
5435     tcg_temp_free(t0);
5436     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t1);
5437     tcg_gen_movi_tl(cpu_ca, 0);
5438     tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l2);
5439     tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, l2);
5440     tcg_gen_movi_tl(cpu_ca, 1);
5441     gen_set_label(l2);
5442     tcg_temp_free(t1);
5443     tcg_temp_free(t2);
5444     if (unlikely(Rc(ctx->opcode) != 0))
5445         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5446 }
5447
5448 /* sre - sre. */
5449 static void gen_sre(DisasContext *ctx)
5450 {
5451     TCGv t0 = tcg_temp_new();
5452     TCGv t1 = tcg_temp_new();
5453     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
5454     tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
5455     tcg_gen_subfi_tl(t1, 32, t1);
5456     tcg_gen_shl_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
5457     tcg_gen_or_tl(t1, t0, t1);
5458     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
5459     gen_store_spr(SPR_MQ, t1);
5460     tcg_temp_free(t0);
5461     tcg_temp_free(t1);
5462     if (unlikely(Rc(ctx->opcode) != 0))
5463         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5464 }
5465
5466 /* srea - srea. */
5467 static void gen_srea(DisasContext *ctx)
5468 {
5469     TCGv t0 = tcg_temp_new();
5470     TCGv t1 = tcg_temp_new();
5471     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
5472     tcg_gen_rotr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
5473     gen_store_spr(SPR_MQ, t0);
5474     tcg_gen_sar_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], t1);
5475     tcg_temp_free(t0);
5476     tcg_temp_free(t1);
5477     if (unlikely(Rc(ctx->opcode) != 0))
5478         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5479 }
5480
5481 /* sreq */
5482 static void gen_sreq(DisasContext *ctx)
5483 {
5484     TCGv t0 = tcg_temp_new();
5485     TCGv t1 = tcg_temp_new();
5486     TCGv t2 = tcg_temp_new();
5487     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
5488     tcg_gen_movi_tl(t1, 0xFFFFFFFF);
5489     tcg_gen_shr_tl(t1, t1, t0);
5490     tcg_gen_rotr_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
5491     gen_load_spr(t2, SPR_MQ);
5492     gen_store_spr(SPR_MQ, t0);
5493     tcg_gen_and_tl(t0, t0, t1);
5494     tcg_gen_andc_tl(t2, t2, t1);
5495     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t2);
5496     tcg_temp_free(t0);
5497     tcg_temp_free(t1);
5498     tcg_temp_free(t2);
5499     if (unlikely(Rc(ctx->opcode) != 0))
5500         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5501 }
5502
5503 /* sriq */
5504 static void gen_sriq(DisasContext *ctx)
5505 {
5506     int sh = SH(ctx->opcode);
5507     TCGv t0 = tcg_temp_new();
5508     TCGv t1 = tcg_temp_new();
5509     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
5510     tcg_gen_shli_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh);
5511     tcg_gen_or_tl(t1, t0, t1);
5512     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
5513     gen_store_spr(SPR_MQ, t1);
5514     tcg_temp_free(t0);
5515     tcg_temp_free(t1);
5516     if (unlikely(Rc(ctx->opcode) != 0))
5517         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5518 }
5519
5520 /* srliq */
5521 static void gen_srliq(DisasContext *ctx)
5522 {
5523     int sh = SH(ctx->opcode);
5524     TCGv t0 = tcg_temp_new();
5525     TCGv t1 = tcg_temp_new();
5526     tcg_gen_rotri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
5527     gen_load_spr(t1, SPR_MQ);
5528     gen_store_spr(SPR_MQ, t0);
5529     tcg_gen_andi_tl(t0, t0,  (0xFFFFFFFFU >> sh));
5530     tcg_gen_andi_tl(t1, t1, ~(0xFFFFFFFFU >> sh));
5531     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5532     tcg_temp_free(t0);
5533     tcg_temp_free(t1);
5534     if (unlikely(Rc(ctx->opcode) != 0))
5535         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5536 }
5537
5538 /* srlq */
5539 static void gen_srlq(DisasContext *ctx)
5540 {
5541     TCGLabel *l1 = gen_new_label();
5542     TCGLabel *l2 = gen_new_label();
5543     TCGv t0 = tcg_temp_local_new();
5544     TCGv t1 = tcg_temp_local_new();
5545     TCGv t2 = tcg_temp_local_new();
5546     tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F);
5547     tcg_gen_movi_tl(t1, 0xFFFFFFFF);
5548     tcg_gen_shr_tl(t2, t1, t2);
5549     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20);
5550     tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
5551     gen_load_spr(t0, SPR_MQ);
5552     tcg_gen_and_tl(cpu_gpr[rA(ctx->opcode)], t0, t2);
5553     tcg_gen_br(l2);
5554     gen_set_label(l1);
5555     tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t2);
5556     tcg_gen_and_tl(t0, t0, t2);
5557     gen_load_spr(t1, SPR_MQ);
5558     tcg_gen_andc_tl(t1, t1, t2);
5559     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5560     gen_set_label(l2);
5561     tcg_temp_free(t0);
5562     tcg_temp_free(t1);
5563     tcg_temp_free(t2);
5564     if (unlikely(Rc(ctx->opcode) != 0))
5565         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5566 }
5567
5568 /* srq */
5569 static void gen_srq(DisasContext *ctx)
5570 {
5571     TCGLabel *l1 = gen_new_label();
5572     TCGv t0 = tcg_temp_new();
5573     TCGv t1 = tcg_temp_new();
5574     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
5575     tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
5576     tcg_gen_subfi_tl(t1, 32, t1);
5577     tcg_gen_shl_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
5578     tcg_gen_or_tl(t1, t0, t1);
5579     gen_store_spr(SPR_MQ, t1);
5580     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x20);
5581     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
5582     tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
5583     tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
5584     gen_set_label(l1);
5585     tcg_temp_free(t0);
5586     tcg_temp_free(t1);
5587     if (unlikely(Rc(ctx->opcode) != 0))
5588         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5589 }
5590
5591 /* PowerPC 602 specific instructions */
5592
5593 /* dsa  */
5594 static void gen_dsa(DisasContext *ctx)
5595 {
5596     /* XXX: TODO */
5597     gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5598 }
5599
5600 /* esa */
5601 static void gen_esa(DisasContext *ctx)
5602 {
5603     /* XXX: TODO */
5604     gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5605 }
5606
5607 /* mfrom */
5608 static void gen_mfrom(DisasContext *ctx)
5609 {
5610 #if defined(CONFIG_USER_ONLY)
5611     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5612 #else
5613     if (unlikely(ctx->pr)) {
5614         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5615         return;
5616     }
5617     gen_helper_602_mfrom(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5618 #endif
5619 }
5620
5621 /* 602 - 603 - G2 TLB management */
5622
5623 /* tlbld */
5624 static void gen_tlbld_6xx(DisasContext *ctx)
5625 {
5626 #if defined(CONFIG_USER_ONLY)
5627     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5628 #else
5629     if (unlikely(ctx->pr)) {
5630         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5631         return;
5632     }
5633     gen_helper_6xx_tlbd(cpu_env, cpu_gpr[rB(ctx->opcode)]);
5634 #endif
5635 }
5636
5637 /* tlbli */
5638 static void gen_tlbli_6xx(DisasContext *ctx)
5639 {
5640 #if defined(CONFIG_USER_ONLY)
5641     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5642 #else
5643     if (unlikely(ctx->pr)) {
5644         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5645         return;
5646     }
5647     gen_helper_6xx_tlbi(cpu_env, cpu_gpr[rB(ctx->opcode)]);
5648 #endif
5649 }
5650
5651 /* 74xx TLB management */
5652
5653 /* tlbld */
5654 static void gen_tlbld_74xx(DisasContext *ctx)
5655 {
5656 #if defined(CONFIG_USER_ONLY)
5657     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5658 #else
5659     if (unlikely(ctx->pr)) {
5660         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5661         return;
5662     }
5663     gen_helper_74xx_tlbd(cpu_env, cpu_gpr[rB(ctx->opcode)]);
5664 #endif
5665 }
5666
5667 /* tlbli */
5668 static void gen_tlbli_74xx(DisasContext *ctx)
5669 {
5670 #if defined(CONFIG_USER_ONLY)
5671     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5672 #else
5673     if (unlikely(ctx->pr)) {
5674         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5675         return;
5676     }
5677     gen_helper_74xx_tlbi(cpu_env, cpu_gpr[rB(ctx->opcode)]);
5678 #endif
5679 }
5680
5681 /* POWER instructions not in PowerPC 601 */
5682
5683 /* clf */
5684 static void gen_clf(DisasContext *ctx)
5685 {
5686     /* Cache line flush: implemented as no-op */
5687 }
5688
5689 /* cli */
5690 static void gen_cli(DisasContext *ctx)
5691 {
5692     /* Cache line invalidate: privileged and treated as no-op */
5693 #if defined(CONFIG_USER_ONLY)
5694     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5695 #else
5696     if (unlikely(ctx->pr)) {
5697         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5698         return;
5699     }
5700 #endif
5701 }
5702
5703 /* dclst */
5704 static void gen_dclst(DisasContext *ctx)
5705 {
5706     /* Data cache line store: treated as no-op */
5707 }
5708
5709 static void gen_mfsri(DisasContext *ctx)
5710 {
5711 #if defined(CONFIG_USER_ONLY)
5712     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5713 #else
5714     int ra = rA(ctx->opcode);
5715     int rd = rD(ctx->opcode);
5716     TCGv t0;
5717     if (unlikely(ctx->pr)) {
5718         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5719         return;
5720     }
5721     t0 = tcg_temp_new();
5722     gen_addr_reg_index(ctx, t0);
5723     tcg_gen_shri_tl(t0, t0, 28);
5724     tcg_gen_andi_tl(t0, t0, 0xF);
5725     gen_helper_load_sr(cpu_gpr[rd], cpu_env, t0);
5726     tcg_temp_free(t0);
5727     if (ra != 0 && ra != rd)
5728         tcg_gen_mov_tl(cpu_gpr[ra], cpu_gpr[rd]);
5729 #endif
5730 }
5731
5732 static void gen_rac(DisasContext *ctx)
5733 {
5734 #if defined(CONFIG_USER_ONLY)
5735     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5736 #else
5737     TCGv t0;
5738     if (unlikely(ctx->pr)) {
5739         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5740         return;
5741     }
5742     t0 = tcg_temp_new();
5743     gen_addr_reg_index(ctx, t0);
5744     gen_helper_rac(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
5745     tcg_temp_free(t0);
5746 #endif
5747 }
5748
5749 static void gen_rfsvc(DisasContext *ctx)
5750 {
5751 #if defined(CONFIG_USER_ONLY)
5752     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5753 #else
5754     if (unlikely(ctx->pr)) {
5755         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5756         return;
5757     }
5758     gen_helper_rfsvc(cpu_env);
5759     gen_sync_exception(ctx);
5760 #endif
5761 }
5762
5763 /* svc is not implemented for now */
5764
5765 /* POWER2 specific instructions */
5766 /* Quad manipulation (load/store two floats at a time) */
5767
5768 /* lfq */
5769 static void gen_lfq(DisasContext *ctx)
5770 {
5771     int rd = rD(ctx->opcode);
5772     TCGv t0;
5773     gen_set_access_type(ctx, ACCESS_FLOAT);
5774     t0 = tcg_temp_new();
5775     gen_addr_imm_index(ctx, t0, 0);
5776     gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
5777     gen_addr_add(ctx, t0, t0, 8);
5778     gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t0);
5779     tcg_temp_free(t0);
5780 }
5781
5782 /* lfqu */
5783 static void gen_lfqu(DisasContext *ctx)
5784 {
5785     int ra = rA(ctx->opcode);
5786     int rd = rD(ctx->opcode);
5787     TCGv t0, t1;
5788     gen_set_access_type(ctx, ACCESS_FLOAT);
5789     t0 = tcg_temp_new();
5790     t1 = tcg_temp_new();
5791     gen_addr_imm_index(ctx, t0, 0);
5792     gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
5793     gen_addr_add(ctx, t1, t0, 8);
5794     gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t1);
5795     if (ra != 0)
5796         tcg_gen_mov_tl(cpu_gpr[ra], t0);
5797     tcg_temp_free(t0);
5798     tcg_temp_free(t1);
5799 }
5800
5801 /* lfqux */
5802 static void gen_lfqux(DisasContext *ctx)
5803 {
5804     int ra = rA(ctx->opcode);
5805     int rd = rD(ctx->opcode);
5806     gen_set_access_type(ctx, ACCESS_FLOAT);
5807     TCGv t0, t1;
5808     t0 = tcg_temp_new();
5809     gen_addr_reg_index(ctx, t0);
5810     gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
5811     t1 = tcg_temp_new();
5812     gen_addr_add(ctx, t1, t0, 8);
5813     gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t1);
5814     tcg_temp_free(t1);
5815     if (ra != 0)
5816         tcg_gen_mov_tl(cpu_gpr[ra], t0);
5817     tcg_temp_free(t0);
5818 }
5819
5820 /* lfqx */
5821 static void gen_lfqx(DisasContext *ctx)
5822 {
5823     int rd = rD(ctx->opcode);
5824     TCGv t0;
5825     gen_set_access_type(ctx, ACCESS_FLOAT);
5826     t0 = tcg_temp_new();
5827     gen_addr_reg_index(ctx, t0);
5828     gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
5829     gen_addr_add(ctx, t0, t0, 8);
5830     gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t0);
5831     tcg_temp_free(t0);
5832 }
5833
5834 /* stfq */
5835 static void gen_stfq(DisasContext *ctx)
5836 {
5837     int rd = rD(ctx->opcode);
5838     TCGv t0;
5839     gen_set_access_type(ctx, ACCESS_FLOAT);
5840     t0 = tcg_temp_new();
5841     gen_addr_imm_index(ctx, t0, 0);
5842     gen_qemu_st64(ctx, cpu_fpr[rd], t0);
5843     gen_addr_add(ctx, t0, t0, 8);
5844     gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t0);
5845     tcg_temp_free(t0);
5846 }
5847
5848 /* stfqu */
5849 static void gen_stfqu(DisasContext *ctx)
5850 {
5851     int ra = rA(ctx->opcode);
5852     int rd = rD(ctx->opcode);
5853     TCGv t0, t1;
5854     gen_set_access_type(ctx, ACCESS_FLOAT);
5855     t0 = tcg_temp_new();
5856     gen_addr_imm_index(ctx, t0, 0);
5857     gen_qemu_st64(ctx, cpu_fpr[rd], t0);
5858     t1 = tcg_temp_new();
5859     gen_addr_add(ctx, t1, t0, 8);
5860     gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t1);
5861     tcg_temp_free(t1);
5862     if (ra != 0)
5863         tcg_gen_mov_tl(cpu_gpr[ra], t0);
5864     tcg_temp_free(t0);
5865 }
5866
5867 /* stfqux */
5868 static void gen_stfqux(DisasContext *ctx)
5869 {
5870     int ra = rA(ctx->opcode);
5871     int rd = rD(ctx->opcode);
5872     TCGv t0, t1;
5873     gen_set_access_type(ctx, ACCESS_FLOAT);
5874     t0 = tcg_temp_new();
5875     gen_addr_reg_index(ctx, t0);
5876     gen_qemu_st64(ctx, cpu_fpr[rd], t0);
5877     t1 = tcg_temp_new();
5878     gen_addr_add(ctx, t1, t0, 8);
5879     gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t1);
5880     tcg_temp_free(t1);
5881     if (ra != 0)
5882         tcg_gen_mov_tl(cpu_gpr[ra], t0);
5883     tcg_temp_free(t0);
5884 }
5885
5886 /* stfqx */
5887 static void gen_stfqx(DisasContext *ctx)
5888 {
5889     int rd = rD(ctx->opcode);
5890     TCGv t0;
5891     gen_set_access_type(ctx, ACCESS_FLOAT);
5892     t0 = tcg_temp_new();
5893     gen_addr_reg_index(ctx, t0);
5894     gen_qemu_st64(ctx, cpu_fpr[rd], t0);
5895     gen_addr_add(ctx, t0, t0, 8);
5896     gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t0);
5897     tcg_temp_free(t0);
5898 }
5899
5900 /* BookE specific instructions */
5901
5902 /* XXX: not implemented on 440 ? */
5903 static void gen_mfapidi(DisasContext *ctx)
5904 {
5905     /* XXX: TODO */
5906     gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5907 }
5908
5909 /* XXX: not implemented on 440 ? */
5910 static void gen_tlbiva(DisasContext *ctx)
5911 {
5912 #if defined(CONFIG_USER_ONLY)
5913     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5914 #else
5915     TCGv t0;
5916     if (unlikely(ctx->pr)) {
5917         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5918         return;
5919     }
5920     t0 = tcg_temp_new();
5921     gen_addr_reg_index(ctx, t0);
5922     gen_helper_tlbiva(cpu_env, cpu_gpr[rB(ctx->opcode)]);
5923     tcg_temp_free(t0);
5924 #endif
5925 }
5926
5927 /* All 405 MAC instructions are translated here */
5928 static inline void gen_405_mulladd_insn(DisasContext *ctx, int opc2, int opc3,
5929                                         int ra, int rb, int rt, int Rc)
5930 {
5931     TCGv t0, t1;
5932
5933     t0 = tcg_temp_local_new();
5934     t1 = tcg_temp_local_new();
5935
5936     switch (opc3 & 0x0D) {
5937     case 0x05:
5938         /* macchw    - macchw.    - macchwo   - macchwo.   */
5939         /* macchws   - macchws.   - macchwso  - macchwso.  */
5940         /* nmacchw   - nmacchw.   - nmacchwo  - nmacchwo.  */
5941         /* nmacchws  - nmacchws.  - nmacchwso - nmacchwso. */
5942         /* mulchw - mulchw. */
5943         tcg_gen_ext16s_tl(t0, cpu_gpr[ra]);
5944         tcg_gen_sari_tl(t1, cpu_gpr[rb], 16);
5945         tcg_gen_ext16s_tl(t1, t1);
5946         break;
5947     case 0x04:
5948         /* macchwu   - macchwu.   - macchwuo  - macchwuo.  */
5949         /* macchwsu  - macchwsu.  - macchwsuo - macchwsuo. */
5950         /* mulchwu - mulchwu. */
5951         tcg_gen_ext16u_tl(t0, cpu_gpr[ra]);
5952         tcg_gen_shri_tl(t1, cpu_gpr[rb], 16);
5953         tcg_gen_ext16u_tl(t1, t1);
5954         break;
5955     case 0x01:
5956         /* machhw    - machhw.    - machhwo   - machhwo.   */
5957         /* machhws   - machhws.   - machhwso  - machhwso.  */
5958         /* nmachhw   - nmachhw.   - nmachhwo  - nmachhwo.  */
5959         /* nmachhws  - nmachhws.  - nmachhwso - nmachhwso. */
5960         /* mulhhw - mulhhw. */
5961         tcg_gen_sari_tl(t0, cpu_gpr[ra], 16);
5962         tcg_gen_ext16s_tl(t0, t0);
5963         tcg_gen_sari_tl(t1, cpu_gpr[rb], 16);
5964         tcg_gen_ext16s_tl(t1, t1);
5965         break;
5966     case 0x00:
5967         /* machhwu   - machhwu.   - machhwuo  - machhwuo.  */
5968         /* machhwsu  - machhwsu.  - machhwsuo - machhwsuo. */
5969         /* mulhhwu - mulhhwu. */
5970         tcg_gen_shri_tl(t0, cpu_gpr[ra], 16);
5971         tcg_gen_ext16u_tl(t0, t0);
5972         tcg_gen_shri_tl(t1, cpu_gpr[rb], 16);
5973         tcg_gen_ext16u_tl(t1, t1);
5974         break;
5975     case 0x0D:
5976         /* maclhw    - maclhw.    - maclhwo   - maclhwo.   */
5977         /* maclhws   - maclhws.   - maclhwso  - maclhwso.  */
5978         /* nmaclhw   - nmaclhw.   - nmaclhwo  - nmaclhwo.  */
5979         /* nmaclhws  - nmaclhws.  - nmaclhwso - nmaclhwso. */
5980         /* mullhw - mullhw. */
5981         tcg_gen_ext16s_tl(t0, cpu_gpr[ra]);
5982         tcg_gen_ext16s_tl(t1, cpu_gpr[rb]);
5983         break;
5984     case 0x0C:
5985         /* maclhwu   - maclhwu.   - maclhwuo  - maclhwuo.  */
5986         /* maclhwsu  - maclhwsu.  - maclhwsuo - maclhwsuo. */
5987         /* mullhwu - mullhwu. */
5988         tcg_gen_ext16u_tl(t0, cpu_gpr[ra]);
5989         tcg_gen_ext16u_tl(t1, cpu_gpr[rb]);
5990         break;
5991     }
5992     if (opc2 & 0x04) {
5993         /* (n)multiply-and-accumulate (0x0C / 0x0E) */
5994         tcg_gen_mul_tl(t1, t0, t1);
5995         if (opc2 & 0x02) {
5996             /* nmultiply-and-accumulate (0x0E) */
5997             tcg_gen_sub_tl(t0, cpu_gpr[rt], t1);
5998         } else {
5999             /* multiply-and-accumulate (0x0C) */
6000             tcg_gen_add_tl(t0, cpu_gpr[rt], t1);
6001         }
6002
6003         if (opc3 & 0x12) {
6004             /* Check overflow and/or saturate */
6005             TCGLabel *l1 = gen_new_label();
6006
6007             if (opc3 & 0x10) {
6008                 /* Start with XER OV disabled, the most likely case */
6009                 tcg_gen_movi_tl(cpu_ov, 0);
6010             }
6011             if (opc3 & 0x01) {
6012                 /* Signed */
6013                 tcg_gen_xor_tl(t1, cpu_gpr[rt], t1);
6014                 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
6015                 tcg_gen_xor_tl(t1, cpu_gpr[rt], t0);
6016                 tcg_gen_brcondi_tl(TCG_COND_LT, t1, 0, l1);
6017                 if (opc3 & 0x02) {
6018                     /* Saturate */
6019                     tcg_gen_sari_tl(t0, cpu_gpr[rt], 31);
6020                     tcg_gen_xori_tl(t0, t0, 0x7fffffff);
6021                 }
6022             } else {
6023                 /* Unsigned */
6024                 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6025                 if (opc3 & 0x02) {
6026                     /* Saturate */
6027                     tcg_gen_movi_tl(t0, UINT32_MAX);
6028                 }
6029             }
6030             if (opc3 & 0x10) {
6031                 /* Check overflow */
6032                 tcg_gen_movi_tl(cpu_ov, 1);
6033                 tcg_gen_movi_tl(cpu_so, 1);
6034             }
6035             gen_set_label(l1);
6036             tcg_gen_mov_tl(cpu_gpr[rt], t0);
6037         }
6038     } else {
6039         tcg_gen_mul_tl(cpu_gpr[rt], t0, t1);
6040     }
6041     tcg_temp_free(t0);
6042     tcg_temp_free(t1);
6043     if (unlikely(Rc) != 0) {
6044         /* Update Rc0 */
6045         gen_set_Rc0(ctx, cpu_gpr[rt]);
6046     }
6047 }
6048
6049 #define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
6050 static void glue(gen_, name)(DisasContext *ctx)                               \
6051 {                                                                             \
6052     gen_405_mulladd_insn(ctx, opc2, opc3, rA(ctx->opcode), rB(ctx->opcode),   \
6053                          rD(ctx->opcode), Rc(ctx->opcode));                   \
6054 }
6055
6056 /* macchw    - macchw.    */
6057 GEN_MAC_HANDLER(macchw, 0x0C, 0x05);
6058 /* macchwo   - macchwo.   */
6059 GEN_MAC_HANDLER(macchwo, 0x0C, 0x15);
6060 /* macchws   - macchws.   */
6061 GEN_MAC_HANDLER(macchws, 0x0C, 0x07);
6062 /* macchwso  - macchwso.  */
6063 GEN_MAC_HANDLER(macchwso, 0x0C, 0x17);
6064 /* macchwsu  - macchwsu.  */
6065 GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06);
6066 /* macchwsuo - macchwsuo. */
6067 GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16);
6068 /* macchwu   - macchwu.   */
6069 GEN_MAC_HANDLER(macchwu, 0x0C, 0x04);
6070 /* macchwuo  - macchwuo.  */
6071 GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14);
6072 /* machhw    - machhw.    */
6073 GEN_MAC_HANDLER(machhw, 0x0C, 0x01);
6074 /* machhwo   - machhwo.   */
6075 GEN_MAC_HANDLER(machhwo, 0x0C, 0x11);
6076 /* machhws   - machhws.   */
6077 GEN_MAC_HANDLER(machhws, 0x0C, 0x03);
6078 /* machhwso  - machhwso.  */
6079 GEN_MAC_HANDLER(machhwso, 0x0C, 0x13);
6080 /* machhwsu  - machhwsu.  */
6081 GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02);
6082 /* machhwsuo - machhwsuo. */
6083 GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12);
6084 /* machhwu   - machhwu.   */
6085 GEN_MAC_HANDLER(machhwu, 0x0C, 0x00);
6086 /* machhwuo  - machhwuo.  */
6087 GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10);
6088 /* maclhw    - maclhw.    */
6089 GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D);
6090 /* maclhwo   - maclhwo.   */
6091 GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D);
6092 /* maclhws   - maclhws.   */
6093 GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F);
6094 /* maclhwso  - maclhwso.  */
6095 GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F);
6096 /* maclhwu   - maclhwu.   */
6097 GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C);
6098 /* maclhwuo  - maclhwuo.  */
6099 GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C);
6100 /* maclhwsu  - maclhwsu.  */
6101 GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E);
6102 /* maclhwsuo - maclhwsuo. */
6103 GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E);
6104 /* nmacchw   - nmacchw.   */
6105 GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05);
6106 /* nmacchwo  - nmacchwo.  */
6107 GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15);
6108 /* nmacchws  - nmacchws.  */
6109 GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07);
6110 /* nmacchwso - nmacchwso. */
6111 GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17);
6112 /* nmachhw   - nmachhw.   */
6113 GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01);
6114 /* nmachhwo  - nmachhwo.  */
6115 GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11);
6116 /* nmachhws  - nmachhws.  */
6117 GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03);
6118 /* nmachhwso - nmachhwso. */
6119 GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13);
6120 /* nmaclhw   - nmaclhw.   */
6121 GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D);
6122 /* nmaclhwo  - nmaclhwo.  */
6123 GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D);
6124 /* nmaclhws  - nmaclhws.  */
6125 GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F);
6126 /* nmaclhwso - nmaclhwso. */
6127 GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F);
6128
6129 /* mulchw  - mulchw.  */
6130 GEN_MAC_HANDLER(mulchw, 0x08, 0x05);
6131 /* mulchwu - mulchwu. */
6132 GEN_MAC_HANDLER(mulchwu, 0x08, 0x04);
6133 /* mulhhw  - mulhhw.  */
6134 GEN_MAC_HANDLER(mulhhw, 0x08, 0x01);
6135 /* mulhhwu - mulhhwu. */
6136 GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00);
6137 /* mullhw  - mullhw.  */
6138 GEN_MAC_HANDLER(mullhw, 0x08, 0x0D);
6139 /* mullhwu - mullhwu. */
6140 GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C);
6141
6142 /* mfdcr */
6143 static void gen_mfdcr(DisasContext *ctx)
6144 {
6145 #if defined(CONFIG_USER_ONLY)
6146     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
6147 #else
6148     TCGv dcrn;
6149     if (unlikely(ctx->pr)) {
6150         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
6151         return;
6152     }
6153     /* NIP cannot be restored if the memory exception comes from an helper */
6154     gen_update_nip(ctx, ctx->nip - 4);
6155     dcrn = tcg_const_tl(SPR(ctx->opcode));
6156     gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_env, dcrn);
6157     tcg_temp_free(dcrn);
6158 #endif
6159 }
6160
6161 /* mtdcr */
6162 static void gen_mtdcr(DisasContext *ctx)
6163 {
6164 #if defined(CONFIG_USER_ONLY)
6165     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
6166 #else
6167     TCGv dcrn;
6168     if (unlikely(ctx->pr)) {
6169         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
6170         return;
6171     }
6172     /* NIP cannot be restored if the memory exception comes from an helper */
6173     gen_update_nip(ctx, ctx->nip - 4);
6174     dcrn = tcg_const_tl(SPR(ctx->opcode));
6175     gen_helper_store_dcr(cpu_env, dcrn, cpu_gpr[rS(ctx->opcode)]);
6176     tcg_temp_free(dcrn);
6177 #endif
6178 }
6179
6180 /* mfdcrx */
6181 /* XXX: not implemented on 440 ? */
6182 static void gen_mfdcrx(DisasContext *ctx)
6183 {
6184 #if defined(CONFIG_USER_ONLY)
6185     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
6186 #else
6187     if (unlikely(ctx->pr)) {
6188         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
6189         return;
6190     }
6191     /* NIP cannot be restored if the memory exception comes from an helper */
6192     gen_update_nip(ctx, ctx->nip - 4);
6193     gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_env,
6194                         cpu_gpr[rA(ctx->opcode)]);
6195     /* Note: Rc update flag set leads to undefined state of Rc0 */
6196 #endif
6197 }
6198
6199 /* mtdcrx */
6200 /* XXX: not implemented on 440 ? */
6201 static void gen_mtdcrx(DisasContext *ctx)
6202 {
6203 #if defined(CONFIG_USER_ONLY)
6204     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
6205 #else
6206     if (unlikely(ctx->pr)) {
6207         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
6208         return;
6209     }
6210     /* NIP cannot be restored if the memory exception comes from an helper */
6211     gen_update_nip(ctx, ctx->nip - 4);
6212     gen_helper_store_dcr(cpu_env, cpu_gpr[rA(ctx->opcode)],
6213                          cpu_gpr[rS(ctx->opcode)]);
6214     /* Note: Rc update flag set leads to undefined state of Rc0 */
6215 #endif
6216 }
6217
6218 /* mfdcrux (PPC 460) : user-mode access to DCR */
6219 static void gen_mfdcrux(DisasContext *ctx)
6220 {
6221     /* NIP cannot be restored if the memory exception comes from an helper */
6222     gen_update_nip(ctx, ctx->nip - 4);
6223     gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_env,
6224                         cpu_gpr[rA(ctx->opcode)]);
6225     /* Note: Rc update flag set leads to undefined state of Rc0 */
6226 }
6227
6228 /* mtdcrux (PPC 460) : user-mode access to DCR */
6229 static void gen_mtdcrux(DisasContext *ctx)
6230 {
6231     /* NIP cannot be restored if the memory exception comes from an helper */
6232     gen_update_nip(ctx, ctx->nip - 4);
6233     gen_helper_store_dcr(cpu_env, cpu_gpr[rA(ctx->opcode)],
6234                          cpu_gpr[rS(ctx->opcode)]);
6235     /* Note: Rc update flag set leads to undefined state of Rc0 */
6236 }
6237
6238 /* dccci */
6239 static void gen_dccci(DisasContext *ctx)
6240 {
6241 #if defined(CONFIG_USER_ONLY)
6242     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6243 #else
6244     if (unlikely(ctx->pr)) {
6245         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6246         return;
6247     }
6248     /* interpreted as no-op */
6249 #endif
6250 }
6251
6252 /* dcread */
6253 static void gen_dcread(DisasContext *ctx)
6254 {
6255 #if defined(CONFIG_USER_ONLY)
6256     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6257 #else
6258     TCGv EA, val;
6259     if (unlikely(ctx->pr)) {
6260         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6261         return;
6262     }
6263     gen_set_access_type(ctx, ACCESS_CACHE);
6264     EA = tcg_temp_new();
6265     gen_addr_reg_index(ctx, EA);
6266     val = tcg_temp_new();
6267     gen_qemu_ld32u(ctx, val, EA);
6268     tcg_temp_free(val);
6269     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], EA);
6270     tcg_temp_free(EA);
6271 #endif
6272 }
6273
6274 /* icbt */
6275 static void gen_icbt_40x(DisasContext *ctx)
6276 {
6277     /* interpreted as no-op */
6278     /* XXX: specification say this is treated as a load by the MMU
6279      *      but does not generate any exception
6280      */
6281 }
6282
6283 /* iccci */
6284 static void gen_iccci(DisasContext *ctx)
6285 {
6286 #if defined(CONFIG_USER_ONLY)
6287     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6288 #else
6289     if (unlikely(ctx->pr)) {
6290         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6291         return;
6292     }
6293     /* interpreted as no-op */
6294 #endif
6295 }
6296
6297 /* icread */
6298 static void gen_icread(DisasContext *ctx)
6299 {
6300 #if defined(CONFIG_USER_ONLY)
6301     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6302 #else
6303     if (unlikely(ctx->pr)) {
6304         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6305         return;
6306     }
6307     /* interpreted as no-op */
6308 #endif
6309 }
6310
6311 /* rfci (supervisor only) */
6312 static void gen_rfci_40x(DisasContext *ctx)
6313 {
6314 #if defined(CONFIG_USER_ONLY)
6315     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6316 #else
6317     if (unlikely(ctx->pr)) {
6318         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6319         return;
6320     }
6321     /* Restore CPU state */
6322     gen_helper_40x_rfci(cpu_env);
6323     gen_sync_exception(ctx);
6324 #endif
6325 }
6326
6327 static void gen_rfci(DisasContext *ctx)
6328 {
6329 #if defined(CONFIG_USER_ONLY)
6330     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6331 #else
6332     if (unlikely(ctx->pr)) {
6333         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6334         return;
6335     }
6336     /* Restore CPU state */
6337     gen_helper_rfci(cpu_env);
6338     gen_sync_exception(ctx);
6339 #endif
6340 }
6341
6342 /* BookE specific */
6343
6344 /* XXX: not implemented on 440 ? */
6345 static void gen_rfdi(DisasContext *ctx)
6346 {
6347 #if defined(CONFIG_USER_ONLY)
6348     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6349 #else
6350     if (unlikely(ctx->pr)) {
6351         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6352         return;
6353     }
6354     /* Restore CPU state */
6355     gen_helper_rfdi(cpu_env);
6356     gen_sync_exception(ctx);
6357 #endif
6358 }
6359
6360 /* XXX: not implemented on 440 ? */
6361 static void gen_rfmci(DisasContext *ctx)
6362 {
6363 #if defined(CONFIG_USER_ONLY)
6364     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6365 #else
6366     if (unlikely(ctx->pr)) {
6367         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6368         return;
6369     }
6370     /* Restore CPU state */
6371     gen_helper_rfmci(cpu_env);
6372     gen_sync_exception(ctx);
6373 #endif
6374 }
6375
6376 /* TLB management - PowerPC 405 implementation */
6377
6378 /* tlbre */
6379 static void gen_tlbre_40x(DisasContext *ctx)
6380 {
6381 #if defined(CONFIG_USER_ONLY)
6382     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6383 #else
6384     if (unlikely(ctx->pr)) {
6385         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6386         return;
6387     }
6388     switch (rB(ctx->opcode)) {
6389     case 0:
6390         gen_helper_4xx_tlbre_hi(cpu_gpr[rD(ctx->opcode)], cpu_env,
6391                                 cpu_gpr[rA(ctx->opcode)]);
6392         break;
6393     case 1:
6394         gen_helper_4xx_tlbre_lo(cpu_gpr[rD(ctx->opcode)], cpu_env,
6395                                 cpu_gpr[rA(ctx->opcode)]);
6396         break;
6397     default:
6398         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
6399         break;
6400     }
6401 #endif
6402 }
6403
6404 /* tlbsx - tlbsx. */
6405 static void gen_tlbsx_40x(DisasContext *ctx)
6406 {
6407 #if defined(CONFIG_USER_ONLY)
6408     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6409 #else
6410     TCGv t0;
6411     if (unlikely(ctx->pr)) {
6412         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6413         return;
6414     }
6415     t0 = tcg_temp_new();
6416     gen_addr_reg_index(ctx, t0);
6417     gen_helper_4xx_tlbsx(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
6418     tcg_temp_free(t0);
6419     if (Rc(ctx->opcode)) {
6420         TCGLabel *l1 = gen_new_label();
6421         tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
6422         tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rD(ctx->opcode)], -1, l1);
6423         tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
6424         gen_set_label(l1);
6425     }
6426 #endif
6427 }
6428
6429 /* tlbwe */
6430 static void gen_tlbwe_40x(DisasContext *ctx)
6431 {
6432 #if defined(CONFIG_USER_ONLY)
6433     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6434 #else
6435     if (unlikely(ctx->pr)) {
6436         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6437         return;
6438     }
6439     switch (rB(ctx->opcode)) {
6440     case 0:
6441         gen_helper_4xx_tlbwe_hi(cpu_env, cpu_gpr[rA(ctx->opcode)],
6442                                 cpu_gpr[rS(ctx->opcode)]);
6443         break;
6444     case 1:
6445         gen_helper_4xx_tlbwe_lo(cpu_env, cpu_gpr[rA(ctx->opcode)],
6446                                 cpu_gpr[rS(ctx->opcode)]);
6447         break;
6448     default:
6449         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
6450         break;
6451     }
6452 #endif
6453 }
6454
6455 /* TLB management - PowerPC 440 implementation */
6456
6457 /* tlbre */
6458 static void gen_tlbre_440(DisasContext *ctx)
6459 {
6460 #if defined(CONFIG_USER_ONLY)
6461     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6462 #else
6463     if (unlikely(ctx->pr)) {
6464         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6465         return;
6466     }
6467     switch (rB(ctx->opcode)) {
6468     case 0:
6469     case 1:
6470     case 2:
6471         {
6472             TCGv_i32 t0 = tcg_const_i32(rB(ctx->opcode));
6473             gen_helper_440_tlbre(cpu_gpr[rD(ctx->opcode)], cpu_env,
6474                                  t0, cpu_gpr[rA(ctx->opcode)]);
6475             tcg_temp_free_i32(t0);
6476         }
6477         break;
6478     default:
6479         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
6480         break;
6481     }
6482 #endif
6483 }
6484
6485 /* tlbsx - tlbsx. */
6486 static void gen_tlbsx_440(DisasContext *ctx)
6487 {
6488 #if defined(CONFIG_USER_ONLY)
6489     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6490 #else
6491     TCGv t0;
6492     if (unlikely(ctx->pr)) {
6493         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6494         return;
6495     }
6496     t0 = tcg_temp_new();
6497     gen_addr_reg_index(ctx, t0);
6498     gen_helper_440_tlbsx(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
6499     tcg_temp_free(t0);
6500     if (Rc(ctx->opcode)) {
6501         TCGLabel *l1 = gen_new_label();
6502         tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
6503         tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rD(ctx->opcode)], -1, l1);
6504         tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
6505         gen_set_label(l1);
6506     }
6507 #endif
6508 }
6509
6510 /* tlbwe */
6511 static void gen_tlbwe_440(DisasContext *ctx)
6512 {
6513 #if defined(CONFIG_USER_ONLY)
6514     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6515 #else
6516     if (unlikely(ctx->pr)) {
6517         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6518         return;
6519     }
6520     switch (rB(ctx->opcode)) {
6521     case 0:
6522     case 1:
6523     case 2:
6524         {
6525             TCGv_i32 t0 = tcg_const_i32(rB(ctx->opcode));
6526             gen_helper_440_tlbwe(cpu_env, t0, cpu_gpr[rA(ctx->opcode)],
6527                                  cpu_gpr[rS(ctx->opcode)]);
6528             tcg_temp_free_i32(t0);
6529         }
6530         break;
6531     default:
6532         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
6533         break;
6534     }
6535 #endif
6536 }
6537
6538 /* TLB management - PowerPC BookE 2.06 implementation */
6539
6540 /* tlbre */
6541 static void gen_tlbre_booke206(DisasContext *ctx)
6542 {
6543 #if defined(CONFIG_USER_ONLY)
6544     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6545 #else
6546     if (unlikely(ctx->pr)) {
6547         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6548         return;
6549     }
6550
6551     gen_helper_booke206_tlbre(cpu_env);
6552 #endif
6553 }
6554
6555 /* tlbsx - tlbsx. */
6556 static void gen_tlbsx_booke206(DisasContext *ctx)
6557 {
6558 #if defined(CONFIG_USER_ONLY)
6559     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6560 #else
6561     TCGv t0;
6562     if (unlikely(ctx->pr)) {
6563         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6564         return;
6565     }
6566
6567     if (rA(ctx->opcode)) {
6568         t0 = tcg_temp_new();
6569         tcg_gen_mov_tl(t0, cpu_gpr[rD(ctx->opcode)]);
6570     } else {
6571         t0 = tcg_const_tl(0);
6572     }
6573
6574     tcg_gen_add_tl(t0, t0, cpu_gpr[rB(ctx->opcode)]);
6575     gen_helper_booke206_tlbsx(cpu_env, t0);
6576     tcg_temp_free(t0);
6577 #endif
6578 }
6579
6580 /* tlbwe */
6581 static void gen_tlbwe_booke206(DisasContext *ctx)
6582 {
6583 #if defined(CONFIG_USER_ONLY)
6584     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6585 #else
6586     if (unlikely(ctx->pr)) {
6587         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6588         return;
6589     }
6590     gen_update_nip(ctx, ctx->nip - 4);
6591     gen_helper_booke206_tlbwe(cpu_env);
6592 #endif
6593 }
6594
6595 static void gen_tlbivax_booke206(DisasContext *ctx)
6596 {
6597 #if defined(CONFIG_USER_ONLY)
6598     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6599 #else
6600     TCGv t0;
6601     if (unlikely(ctx->pr)) {
6602         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6603         return;
6604     }
6605
6606     t0 = tcg_temp_new();
6607     gen_addr_reg_index(ctx, t0);
6608
6609     gen_helper_booke206_tlbivax(cpu_env, t0);
6610     tcg_temp_free(t0);
6611 #endif
6612 }
6613
6614 static void gen_tlbilx_booke206(DisasContext *ctx)
6615 {
6616 #if defined(CONFIG_USER_ONLY)
6617     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6618 #else
6619     TCGv t0;
6620     if (unlikely(ctx->pr)) {
6621         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6622         return;
6623     }
6624
6625     t0 = tcg_temp_new();
6626     gen_addr_reg_index(ctx, t0);
6627
6628     switch((ctx->opcode >> 21) & 0x3) {
6629     case 0:
6630         gen_helper_booke206_tlbilx0(cpu_env, t0);
6631         break;
6632     case 1:
6633         gen_helper_booke206_tlbilx1(cpu_env, t0);
6634         break;
6635     case 3:
6636         gen_helper_booke206_tlbilx3(cpu_env, t0);
6637         break;
6638     default:
6639         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
6640         break;
6641     }
6642
6643     tcg_temp_free(t0);
6644 #endif
6645 }
6646
6647
6648 /* wrtee */
6649 static void gen_wrtee(DisasContext *ctx)
6650 {
6651 #if defined(CONFIG_USER_ONLY)
6652     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6653 #else
6654     TCGv t0;
6655     if (unlikely(ctx->pr)) {
6656         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6657         return;
6658     }
6659     t0 = tcg_temp_new();
6660     tcg_gen_andi_tl(t0, cpu_gpr[rD(ctx->opcode)], (1 << MSR_EE));
6661     tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE));
6662     tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
6663     tcg_temp_free(t0);
6664     /* Stop translation to have a chance to raise an exception
6665      * if we just set msr_ee to 1
6666      */
6667     gen_stop_exception(ctx);
6668 #endif
6669 }
6670
6671 /* wrteei */
6672 static void gen_wrteei(DisasContext *ctx)
6673 {
6674 #if defined(CONFIG_USER_ONLY)
6675     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6676 #else
6677     if (unlikely(ctx->pr)) {
6678         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6679         return;
6680     }
6681     if (ctx->opcode & 0x00008000) {
6682         tcg_gen_ori_tl(cpu_msr, cpu_msr, (1 << MSR_EE));
6683         /* Stop translation to have a chance to raise an exception */
6684         gen_stop_exception(ctx);
6685     } else {
6686         tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE));
6687     }
6688 #endif
6689 }
6690
6691 /* PowerPC 440 specific instructions */
6692
6693 /* dlmzb */
6694 static void gen_dlmzb(DisasContext *ctx)
6695 {
6696     TCGv_i32 t0 = tcg_const_i32(Rc(ctx->opcode));
6697     gen_helper_dlmzb(cpu_gpr[rA(ctx->opcode)], cpu_env,
6698                      cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], t0);
6699     tcg_temp_free_i32(t0);
6700 }
6701
6702 /* mbar replaces eieio on 440 */
6703 static void gen_mbar(DisasContext *ctx)
6704 {
6705     /* interpreted as no-op */
6706 }
6707
6708 /* msync replaces sync on 440 */
6709 static void gen_msync_4xx(DisasContext *ctx)
6710 {
6711     /* interpreted as no-op */
6712 }
6713
6714 /* icbt */
6715 static void gen_icbt_440(DisasContext *ctx)
6716 {
6717     /* interpreted as no-op */
6718     /* XXX: specification say this is treated as a load by the MMU
6719      *      but does not generate any exception
6720      */
6721 }
6722
6723 /* Embedded.Processor Control */
6724
6725 static void gen_msgclr(DisasContext *ctx)
6726 {
6727 #if defined(CONFIG_USER_ONLY)
6728     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6729 #else
6730     if (unlikely(ctx->pr)) {
6731         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6732         return;
6733     }
6734
6735     gen_helper_msgclr(cpu_env, cpu_gpr[rB(ctx->opcode)]);
6736 #endif
6737 }
6738
6739 static void gen_msgsnd(DisasContext *ctx)
6740 {
6741 #if defined(CONFIG_USER_ONLY)
6742     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6743 #else
6744     if (unlikely(ctx->pr)) {
6745         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6746         return;
6747     }
6748
6749     gen_helper_msgsnd(cpu_gpr[rB(ctx->opcode)]);
6750 #endif
6751 }
6752
6753 /***                      Altivec vector extension                         ***/
6754 /* Altivec registers moves */
6755
6756 static inline TCGv_ptr gen_avr_ptr(int reg)
6757 {
6758     TCGv_ptr r = tcg_temp_new_ptr();
6759     tcg_gen_addi_ptr(r, cpu_env, offsetof(CPUPPCState, avr[reg]));
6760     return r;
6761 }
6762
6763 #define GEN_VR_LDX(name, opc2, opc3)                                          \
6764 static void glue(gen_, name)(DisasContext *ctx)                                       \
6765 {                                                                             \
6766     TCGv EA;                                                                  \
6767     if (unlikely(!ctx->altivec_enabled)) {                                    \
6768         gen_exception(ctx, POWERPC_EXCP_VPU);                                 \
6769         return;                                                               \
6770     }                                                                         \
6771     gen_set_access_type(ctx, ACCESS_INT);                                     \
6772     EA = tcg_temp_new();                                                      \
6773     gen_addr_reg_index(ctx, EA);                                              \
6774     tcg_gen_andi_tl(EA, EA, ~0xf);                                            \
6775     /* We only need to swap high and low halves. gen_qemu_ld64 does necessary \
6776        64-bit byteswap already. */                                            \
6777     if (ctx->le_mode) {                                                       \
6778         gen_qemu_ld64(ctx, cpu_avrl[rD(ctx->opcode)], EA);                    \
6779         tcg_gen_addi_tl(EA, EA, 8);                                           \
6780         gen_qemu_ld64(ctx, cpu_avrh[rD(ctx->opcode)], EA);                    \
6781     } else {                                                                  \
6782         gen_qemu_ld64(ctx, cpu_avrh[rD(ctx->opcode)], EA);                    \
6783         tcg_gen_addi_tl(EA, EA, 8);                                           \
6784         gen_qemu_ld64(ctx, cpu_avrl[rD(ctx->opcode)], EA);                    \
6785     }                                                                         \
6786     tcg_temp_free(EA);                                                        \
6787 }
6788
6789 #define GEN_VR_STX(name, opc2, opc3)                                          \
6790 static void gen_st##name(DisasContext *ctx)                                   \
6791 {                                                                             \
6792     TCGv EA;                                                                  \
6793     if (unlikely(!ctx->altivec_enabled)) {                                    \
6794         gen_exception(ctx, POWERPC_EXCP_VPU);                                 \
6795         return;                                                               \
6796     }                                                                         \
6797     gen_set_access_type(ctx, ACCESS_INT);                                     \
6798     EA = tcg_temp_new();                                                      \
6799     gen_addr_reg_index(ctx, EA);                                              \
6800     tcg_gen_andi_tl(EA, EA, ~0xf);                                            \
6801     /* We only need to swap high and low halves. gen_qemu_st64 does necessary \
6802        64-bit byteswap already. */                                            \
6803     if (ctx->le_mode) {                                                       \
6804         gen_qemu_st64(ctx, cpu_avrl[rD(ctx->opcode)], EA);                    \
6805         tcg_gen_addi_tl(EA, EA, 8);                                           \
6806         gen_qemu_st64(ctx, cpu_avrh[rD(ctx->opcode)], EA);                    \
6807     } else {                                                                  \
6808         gen_qemu_st64(ctx, cpu_avrh[rD(ctx->opcode)], EA);                    \
6809         tcg_gen_addi_tl(EA, EA, 8);                                           \
6810         gen_qemu_st64(ctx, cpu_avrl[rD(ctx->opcode)], EA);                    \
6811     }                                                                         \
6812     tcg_temp_free(EA);                                                        \
6813 }
6814
6815 #define GEN_VR_LVE(name, opc2, opc3, size)                              \
6816 static void gen_lve##name(DisasContext *ctx)                            \
6817     {                                                                   \
6818         TCGv EA;                                                        \
6819         TCGv_ptr rs;                                                    \
6820         if (unlikely(!ctx->altivec_enabled)) {                          \
6821             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
6822             return;                                                     \
6823         }                                                               \
6824         gen_set_access_type(ctx, ACCESS_INT);                           \
6825         EA = tcg_temp_new();                                            \
6826         gen_addr_reg_index(ctx, EA);                                    \
6827         if (size > 1) {                                                 \
6828             tcg_gen_andi_tl(EA, EA, ~(size - 1));                       \
6829         }                                                               \
6830         rs = gen_avr_ptr(rS(ctx->opcode));                              \
6831         gen_helper_lve##name(cpu_env, rs, EA);                          \
6832         tcg_temp_free(EA);                                              \
6833         tcg_temp_free_ptr(rs);                                          \
6834     }
6835
6836 #define GEN_VR_STVE(name, opc2, opc3, size)                             \
6837 static void gen_stve##name(DisasContext *ctx)                           \
6838     {                                                                   \
6839         TCGv EA;                                                        \
6840         TCGv_ptr rs;                                                    \
6841         if (unlikely(!ctx->altivec_enabled)) {                          \
6842             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
6843             return;                                                     \
6844         }                                                               \
6845         gen_set_access_type(ctx, ACCESS_INT);                           \
6846         EA = tcg_temp_new();                                            \
6847         gen_addr_reg_index(ctx, EA);                                    \
6848         if (size > 1) {                                                 \
6849             tcg_gen_andi_tl(EA, EA, ~(size - 1));                       \
6850         }                                                               \
6851         rs = gen_avr_ptr(rS(ctx->opcode));                              \
6852         gen_helper_stve##name(cpu_env, rs, EA);                         \
6853         tcg_temp_free(EA);                                              \
6854         tcg_temp_free_ptr(rs);                                          \
6855     }
6856
6857 GEN_VR_LDX(lvx, 0x07, 0x03);
6858 /* As we don't emulate the cache, lvxl is stricly equivalent to lvx */
6859 GEN_VR_LDX(lvxl, 0x07, 0x0B);
6860
6861 GEN_VR_LVE(bx, 0x07, 0x00, 1);
6862 GEN_VR_LVE(hx, 0x07, 0x01, 2);
6863 GEN_VR_LVE(wx, 0x07, 0x02, 4);
6864
6865 GEN_VR_STX(svx, 0x07, 0x07);
6866 /* As we don't emulate the cache, stvxl is stricly equivalent to stvx */
6867 GEN_VR_STX(svxl, 0x07, 0x0F);
6868
6869 GEN_VR_STVE(bx, 0x07, 0x04, 1);
6870 GEN_VR_STVE(hx, 0x07, 0x05, 2);
6871 GEN_VR_STVE(wx, 0x07, 0x06, 4);
6872
6873 static void gen_lvsl(DisasContext *ctx)
6874 {
6875     TCGv_ptr rd;
6876     TCGv EA;
6877     if (unlikely(!ctx->altivec_enabled)) {
6878         gen_exception(ctx, POWERPC_EXCP_VPU);
6879         return;
6880     }
6881     EA = tcg_temp_new();
6882     gen_addr_reg_index(ctx, EA);
6883     rd = gen_avr_ptr(rD(ctx->opcode));
6884     gen_helper_lvsl(rd, EA);
6885     tcg_temp_free(EA);
6886     tcg_temp_free_ptr(rd);
6887 }
6888
6889 static void gen_lvsr(DisasContext *ctx)
6890 {
6891     TCGv_ptr rd;
6892     TCGv EA;
6893     if (unlikely(!ctx->altivec_enabled)) {
6894         gen_exception(ctx, POWERPC_EXCP_VPU);
6895         return;
6896     }
6897     EA = tcg_temp_new();
6898     gen_addr_reg_index(ctx, EA);
6899     rd = gen_avr_ptr(rD(ctx->opcode));
6900     gen_helper_lvsr(rd, EA);
6901     tcg_temp_free(EA);
6902     tcg_temp_free_ptr(rd);
6903 }
6904
6905 static void gen_mfvscr(DisasContext *ctx)
6906 {
6907     TCGv_i32 t;
6908     if (unlikely(!ctx->altivec_enabled)) {
6909         gen_exception(ctx, POWERPC_EXCP_VPU);
6910         return;
6911     }
6912     tcg_gen_movi_i64(cpu_avrh[rD(ctx->opcode)], 0);
6913     t = tcg_temp_new_i32();
6914     tcg_gen_ld_i32(t, cpu_env, offsetof(CPUPPCState, vscr));
6915     tcg_gen_extu_i32_i64(cpu_avrl[rD(ctx->opcode)], t);
6916     tcg_temp_free_i32(t);
6917 }
6918
6919 static void gen_mtvscr(DisasContext *ctx)
6920 {
6921     TCGv_ptr p;
6922     if (unlikely(!ctx->altivec_enabled)) {
6923         gen_exception(ctx, POWERPC_EXCP_VPU);
6924         return;
6925     }
6926     p = gen_avr_ptr(rB(ctx->opcode));
6927     gen_helper_mtvscr(cpu_env, p);
6928     tcg_temp_free_ptr(p);
6929 }
6930
6931 /* Logical operations */
6932 #define GEN_VX_LOGICAL(name, tcg_op, opc2, opc3)                        \
6933 static void glue(gen_, name)(DisasContext *ctx)                                 \
6934 {                                                                       \
6935     if (unlikely(!ctx->altivec_enabled)) {                              \
6936         gen_exception(ctx, POWERPC_EXCP_VPU);                           \
6937         return;                                                         \
6938     }                                                                   \
6939     tcg_op(cpu_avrh[rD(ctx->opcode)], cpu_avrh[rA(ctx->opcode)], cpu_avrh[rB(ctx->opcode)]); \
6940     tcg_op(cpu_avrl[rD(ctx->opcode)], cpu_avrl[rA(ctx->opcode)], cpu_avrl[rB(ctx->opcode)]); \
6941 }
6942
6943 GEN_VX_LOGICAL(vand, tcg_gen_and_i64, 2, 16);
6944 GEN_VX_LOGICAL(vandc, tcg_gen_andc_i64, 2, 17);
6945 GEN_VX_LOGICAL(vor, tcg_gen_or_i64, 2, 18);
6946 GEN_VX_LOGICAL(vxor, tcg_gen_xor_i64, 2, 19);
6947 GEN_VX_LOGICAL(vnor, tcg_gen_nor_i64, 2, 20);
6948 GEN_VX_LOGICAL(veqv, tcg_gen_eqv_i64, 2, 26);
6949 GEN_VX_LOGICAL(vnand, tcg_gen_nand_i64, 2, 22);
6950 GEN_VX_LOGICAL(vorc, tcg_gen_orc_i64, 2, 21);
6951
6952 #define GEN_VXFORM(name, opc2, opc3)                                    \
6953 static void glue(gen_, name)(DisasContext *ctx)                                 \
6954 {                                                                       \
6955     TCGv_ptr ra, rb, rd;                                                \
6956     if (unlikely(!ctx->altivec_enabled)) {                              \
6957         gen_exception(ctx, POWERPC_EXCP_VPU);                           \
6958         return;                                                         \
6959     }                                                                   \
6960     ra = gen_avr_ptr(rA(ctx->opcode));                                  \
6961     rb = gen_avr_ptr(rB(ctx->opcode));                                  \
6962     rd = gen_avr_ptr(rD(ctx->opcode));                                  \
6963     gen_helper_##name (rd, ra, rb);                                     \
6964     tcg_temp_free_ptr(ra);                                              \
6965     tcg_temp_free_ptr(rb);                                              \
6966     tcg_temp_free_ptr(rd);                                              \
6967 }
6968
6969 #define GEN_VXFORM_ENV(name, opc2, opc3)                                \
6970 static void glue(gen_, name)(DisasContext *ctx)                         \
6971 {                                                                       \
6972     TCGv_ptr ra, rb, rd;                                                \
6973     if (unlikely(!ctx->altivec_enabled)) {                              \
6974         gen_exception(ctx, POWERPC_EXCP_VPU);                           \
6975         return;                                                         \
6976     }                                                                   \
6977     ra = gen_avr_ptr(rA(ctx->opcode));                                  \
6978     rb = gen_avr_ptr(rB(ctx->opcode));                                  \
6979     rd = gen_avr_ptr(rD(ctx->opcode));                                  \
6980     gen_helper_##name(cpu_env, rd, ra, rb);                             \
6981     tcg_temp_free_ptr(ra);                                              \
6982     tcg_temp_free_ptr(rb);                                              \
6983     tcg_temp_free_ptr(rd);                                              \
6984 }
6985
6986 #define GEN_VXFORM3(name, opc2, opc3)                                   \
6987 static void glue(gen_, name)(DisasContext *ctx)                         \
6988 {                                                                       \
6989     TCGv_ptr ra, rb, rc, rd;                                            \
6990     if (unlikely(!ctx->altivec_enabled)) {                              \
6991         gen_exception(ctx, POWERPC_EXCP_VPU);                           \
6992         return;                                                         \
6993     }                                                                   \
6994     ra = gen_avr_ptr(rA(ctx->opcode));                                  \
6995     rb = gen_avr_ptr(rB(ctx->opcode));                                  \
6996     rc = gen_avr_ptr(rC(ctx->opcode));                                  \
6997     rd = gen_avr_ptr(rD(ctx->opcode));                                  \
6998     gen_helper_##name(rd, ra, rb, rc);                                  \
6999     tcg_temp_free_ptr(ra);                                              \
7000     tcg_temp_free_ptr(rb);                                              \
7001     tcg_temp_free_ptr(rc);                                              \
7002     tcg_temp_free_ptr(rd);                                              \
7003 }
7004
7005 /*
7006  * Support for Altivec instruction pairs that use bit 31 (Rc) as
7007  * an opcode bit.  In general, these pairs come from different
7008  * versions of the ISA, so we must also support a pair of flags for
7009  * each instruction.
7010  */
7011 #define GEN_VXFORM_DUAL(name0, flg0, flg2_0, name1, flg1, flg2_1)          \
7012 static void glue(gen_, name0##_##name1)(DisasContext *ctx)             \
7013 {                                                                      \
7014     if ((Rc(ctx->opcode) == 0) &&                                      \
7015         ((ctx->insns_flags & flg0) || (ctx->insns_flags2 & flg2_0))) { \
7016         gen_##name0(ctx);                                              \
7017     } else if ((Rc(ctx->opcode) == 1) &&                               \
7018         ((ctx->insns_flags & flg1) || (ctx->insns_flags2 & flg2_1))) { \
7019         gen_##name1(ctx);                                              \
7020     } else {                                                           \
7021         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);            \
7022     }                                                                  \
7023 }
7024
7025 GEN_VXFORM(vaddubm, 0, 0);
7026 GEN_VXFORM(vadduhm, 0, 1);
7027 GEN_VXFORM(vadduwm, 0, 2);
7028 GEN_VXFORM(vaddudm, 0, 3);
7029 GEN_VXFORM(vsububm, 0, 16);
7030 GEN_VXFORM(vsubuhm, 0, 17);
7031 GEN_VXFORM(vsubuwm, 0, 18);
7032 GEN_VXFORM(vsubudm, 0, 19);
7033 GEN_VXFORM(vmaxub, 1, 0);
7034 GEN_VXFORM(vmaxuh, 1, 1);
7035 GEN_VXFORM(vmaxuw, 1, 2);
7036 GEN_VXFORM(vmaxud, 1, 3);
7037 GEN_VXFORM(vmaxsb, 1, 4);
7038 GEN_VXFORM(vmaxsh, 1, 5);
7039 GEN_VXFORM(vmaxsw, 1, 6);
7040 GEN_VXFORM(vmaxsd, 1, 7);
7041 GEN_VXFORM(vminub, 1, 8);
7042 GEN_VXFORM(vminuh, 1, 9);
7043 GEN_VXFORM(vminuw, 1, 10);
7044 GEN_VXFORM(vminud, 1, 11);
7045 GEN_VXFORM(vminsb, 1, 12);
7046 GEN_VXFORM(vminsh, 1, 13);
7047 GEN_VXFORM(vminsw, 1, 14);
7048 GEN_VXFORM(vminsd, 1, 15);
7049 GEN_VXFORM(vavgub, 1, 16);
7050 GEN_VXFORM(vavguh, 1, 17);
7051 GEN_VXFORM(vavguw, 1, 18);
7052 GEN_VXFORM(vavgsb, 1, 20);
7053 GEN_VXFORM(vavgsh, 1, 21);
7054 GEN_VXFORM(vavgsw, 1, 22);
7055 GEN_VXFORM(vmrghb, 6, 0);
7056 GEN_VXFORM(vmrghh, 6, 1);
7057 GEN_VXFORM(vmrghw, 6, 2);
7058 GEN_VXFORM(vmrglb, 6, 4);
7059 GEN_VXFORM(vmrglh, 6, 5);
7060 GEN_VXFORM(vmrglw, 6, 6);
7061
7062 static void gen_vmrgew(DisasContext *ctx)
7063 {
7064     TCGv_i64 tmp;
7065     int VT, VA, VB;
7066     if (unlikely(!ctx->altivec_enabled)) {
7067         gen_exception(ctx, POWERPC_EXCP_VPU);
7068         return;
7069     }
7070     VT = rD(ctx->opcode);
7071     VA = rA(ctx->opcode);
7072     VB = rB(ctx->opcode);
7073     tmp = tcg_temp_new_i64();
7074     tcg_gen_shri_i64(tmp, cpu_avrh[VB], 32);
7075     tcg_gen_deposit_i64(cpu_avrh[VT], cpu_avrh[VA], tmp, 0, 32);
7076     tcg_gen_shri_i64(tmp, cpu_avrl[VB], 32);
7077     tcg_gen_deposit_i64(cpu_avrl[VT], cpu_avrl[VA], tmp, 0, 32);
7078     tcg_temp_free_i64(tmp);
7079 }
7080
7081 static void gen_vmrgow(DisasContext *ctx)
7082 {
7083     int VT, VA, VB;
7084     if (unlikely(!ctx->altivec_enabled)) {
7085         gen_exception(ctx, POWERPC_EXCP_VPU);
7086         return;
7087     }
7088     VT = rD(ctx->opcode);
7089     VA = rA(ctx->opcode);
7090     VB = rB(ctx->opcode);
7091
7092     tcg_gen_deposit_i64(cpu_avrh[VT], cpu_avrh[VB], cpu_avrh[VA], 32, 32);
7093     tcg_gen_deposit_i64(cpu_avrl[VT], cpu_avrl[VB], cpu_avrl[VA], 32, 32);
7094 }
7095
7096 GEN_VXFORM(vmuloub, 4, 0);
7097 GEN_VXFORM(vmulouh, 4, 1);
7098 GEN_VXFORM(vmulouw, 4, 2);
7099 GEN_VXFORM(vmuluwm, 4, 2);
7100 GEN_VXFORM_DUAL(vmulouw, PPC_ALTIVEC, PPC_NONE,
7101                 vmuluwm, PPC_NONE, PPC2_ALTIVEC_207)
7102 GEN_VXFORM(vmulosb, 4, 4);
7103 GEN_VXFORM(vmulosh, 4, 5);
7104 GEN_VXFORM(vmulosw, 4, 6);
7105 GEN_VXFORM(vmuleub, 4, 8);
7106 GEN_VXFORM(vmuleuh, 4, 9);
7107 GEN_VXFORM(vmuleuw, 4, 10);
7108 GEN_VXFORM(vmulesb, 4, 12);
7109 GEN_VXFORM(vmulesh, 4, 13);
7110 GEN_VXFORM(vmulesw, 4, 14);
7111 GEN_VXFORM(vslb, 2, 4);
7112 GEN_VXFORM(vslh, 2, 5);
7113 GEN_VXFORM(vslw, 2, 6);
7114 GEN_VXFORM(vsld, 2, 23);
7115 GEN_VXFORM(vsrb, 2, 8);
7116 GEN_VXFORM(vsrh, 2, 9);
7117 GEN_VXFORM(vsrw, 2, 10);
7118 GEN_VXFORM(vsrd, 2, 27);
7119 GEN_VXFORM(vsrab, 2, 12);
7120 GEN_VXFORM(vsrah, 2, 13);
7121 GEN_VXFORM(vsraw, 2, 14);
7122 GEN_VXFORM(vsrad, 2, 15);
7123 GEN_VXFORM(vslo, 6, 16);
7124 GEN_VXFORM(vsro, 6, 17);
7125 GEN_VXFORM(vaddcuw, 0, 6);
7126 GEN_VXFORM(vsubcuw, 0, 22);
7127 GEN_VXFORM_ENV(vaddubs, 0, 8);
7128 GEN_VXFORM_ENV(vadduhs, 0, 9);
7129 GEN_VXFORM_ENV(vadduws, 0, 10);
7130 GEN_VXFORM_ENV(vaddsbs, 0, 12);
7131 GEN_VXFORM_ENV(vaddshs, 0, 13);
7132 GEN_VXFORM_ENV(vaddsws, 0, 14);
7133 GEN_VXFORM_ENV(vsububs, 0, 24);
7134 GEN_VXFORM_ENV(vsubuhs, 0, 25);
7135 GEN_VXFORM_ENV(vsubuws, 0, 26);
7136 GEN_VXFORM_ENV(vsubsbs, 0, 28);
7137 GEN_VXFORM_ENV(vsubshs, 0, 29);
7138 GEN_VXFORM_ENV(vsubsws, 0, 30);
7139 GEN_VXFORM(vadduqm, 0, 4);
7140 GEN_VXFORM(vaddcuq, 0, 5);
7141 GEN_VXFORM3(vaddeuqm, 30, 0);
7142 GEN_VXFORM3(vaddecuq, 30, 0);
7143 GEN_VXFORM_DUAL(vaddeuqm, PPC_NONE, PPC2_ALTIVEC_207, \
7144             vaddecuq, PPC_NONE, PPC2_ALTIVEC_207)
7145 GEN_VXFORM(vsubuqm, 0, 20);
7146 GEN_VXFORM(vsubcuq, 0, 21);
7147 GEN_VXFORM3(vsubeuqm, 31, 0);
7148 GEN_VXFORM3(vsubecuq, 31, 0);
7149 GEN_VXFORM_DUAL(vsubeuqm, PPC_NONE, PPC2_ALTIVEC_207, \
7150             vsubecuq, PPC_NONE, PPC2_ALTIVEC_207)
7151 GEN_VXFORM(vrlb, 2, 0);
7152 GEN_VXFORM(vrlh, 2, 1);
7153 GEN_VXFORM(vrlw, 2, 2);
7154 GEN_VXFORM(vrld, 2, 3);
7155 GEN_VXFORM(vsl, 2, 7);
7156 GEN_VXFORM(vsr, 2, 11);
7157 GEN_VXFORM_ENV(vpkuhum, 7, 0);
7158 GEN_VXFORM_ENV(vpkuwum, 7, 1);
7159 GEN_VXFORM_ENV(vpkudum, 7, 17);
7160 GEN_VXFORM_ENV(vpkuhus, 7, 2);
7161 GEN_VXFORM_ENV(vpkuwus, 7, 3);
7162 GEN_VXFORM_ENV(vpkudus, 7, 19);
7163 GEN_VXFORM_ENV(vpkshus, 7, 4);
7164 GEN_VXFORM_ENV(vpkswus, 7, 5);
7165 GEN_VXFORM_ENV(vpksdus, 7, 21);
7166 GEN_VXFORM_ENV(vpkshss, 7, 6);
7167 GEN_VXFORM_ENV(vpkswss, 7, 7);
7168 GEN_VXFORM_ENV(vpksdss, 7, 23);
7169 GEN_VXFORM(vpkpx, 7, 12);
7170 GEN_VXFORM_ENV(vsum4ubs, 4, 24);
7171 GEN_VXFORM_ENV(vsum4sbs, 4, 28);
7172 GEN_VXFORM_ENV(vsum4shs, 4, 25);
7173 GEN_VXFORM_ENV(vsum2sws, 4, 26);
7174 GEN_VXFORM_ENV(vsumsws, 4, 30);
7175 GEN_VXFORM_ENV(vaddfp, 5, 0);
7176 GEN_VXFORM_ENV(vsubfp, 5, 1);
7177 GEN_VXFORM_ENV(vmaxfp, 5, 16);
7178 GEN_VXFORM_ENV(vminfp, 5, 17);
7179
7180 #define GEN_VXRFORM1(opname, name, str, opc2, opc3)                     \
7181 static void glue(gen_, name)(DisasContext *ctx)                         \
7182     {                                                                   \
7183         TCGv_ptr ra, rb, rd;                                            \
7184         if (unlikely(!ctx->altivec_enabled)) {                          \
7185             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
7186             return;                                                     \
7187         }                                                               \
7188         ra = gen_avr_ptr(rA(ctx->opcode));                              \
7189         rb = gen_avr_ptr(rB(ctx->opcode));                              \
7190         rd = gen_avr_ptr(rD(ctx->opcode));                              \
7191         gen_helper_##opname(cpu_env, rd, ra, rb);                       \
7192         tcg_temp_free_ptr(ra);                                          \
7193         tcg_temp_free_ptr(rb);                                          \
7194         tcg_temp_free_ptr(rd);                                          \
7195     }
7196
7197 #define GEN_VXRFORM(name, opc2, opc3)                                \
7198     GEN_VXRFORM1(name, name, #name, opc2, opc3)                      \
7199     GEN_VXRFORM1(name##_dot, name##_, #name ".", opc2, (opc3 | (0x1 << 4)))
7200
7201 /*
7202  * Support for Altivec instructions that use bit 31 (Rc) as an opcode
7203  * bit but also use bit 21 as an actual Rc bit.  In general, thse pairs
7204  * come from different versions of the ISA, so we must also support a
7205  * pair of flags for each instruction.
7206  */
7207 #define GEN_VXRFORM_DUAL(name0, flg0, flg2_0, name1, flg1, flg2_1)     \
7208 static void glue(gen_, name0##_##name1)(DisasContext *ctx)             \
7209 {                                                                      \
7210     if ((Rc(ctx->opcode) == 0) &&                                      \
7211         ((ctx->insns_flags & flg0) || (ctx->insns_flags2 & flg2_0))) { \
7212         if (Rc21(ctx->opcode) == 0) {                                  \
7213             gen_##name0(ctx);                                          \
7214         } else {                                                       \
7215             gen_##name0##_(ctx);                                       \
7216         }                                                              \
7217     } else if ((Rc(ctx->opcode) == 1) &&                               \
7218         ((ctx->insns_flags & flg1) || (ctx->insns_flags2 & flg2_1))) { \
7219         if (Rc21(ctx->opcode) == 0) {                                  \
7220             gen_##name1(ctx);                                          \
7221         } else {                                                       \
7222             gen_##name1##_(ctx);                                       \
7223         }                                                              \
7224     } else {                                                           \
7225         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);            \
7226     }                                                                  \
7227 }
7228
7229 GEN_VXRFORM(vcmpequb, 3, 0)
7230 GEN_VXRFORM(vcmpequh, 3, 1)
7231 GEN_VXRFORM(vcmpequw, 3, 2)
7232 GEN_VXRFORM(vcmpequd, 3, 3)
7233 GEN_VXRFORM(vcmpgtsb, 3, 12)
7234 GEN_VXRFORM(vcmpgtsh, 3, 13)
7235 GEN_VXRFORM(vcmpgtsw, 3, 14)
7236 GEN_VXRFORM(vcmpgtsd, 3, 15)
7237 GEN_VXRFORM(vcmpgtub, 3, 8)
7238 GEN_VXRFORM(vcmpgtuh, 3, 9)
7239 GEN_VXRFORM(vcmpgtuw, 3, 10)
7240 GEN_VXRFORM(vcmpgtud, 3, 11)
7241 GEN_VXRFORM(vcmpeqfp, 3, 3)
7242 GEN_VXRFORM(vcmpgefp, 3, 7)
7243 GEN_VXRFORM(vcmpgtfp, 3, 11)
7244 GEN_VXRFORM(vcmpbfp, 3, 15)
7245
7246 GEN_VXRFORM_DUAL(vcmpeqfp, PPC_ALTIVEC, PPC_NONE, \
7247                  vcmpequd, PPC_NONE, PPC2_ALTIVEC_207)
7248 GEN_VXRFORM_DUAL(vcmpbfp, PPC_ALTIVEC, PPC_NONE, \
7249                  vcmpgtsd, PPC_NONE, PPC2_ALTIVEC_207)
7250 GEN_VXRFORM_DUAL(vcmpgtfp, PPC_ALTIVEC, PPC_NONE, \
7251                  vcmpgtud, PPC_NONE, PPC2_ALTIVEC_207)
7252
7253 #define GEN_VXFORM_SIMM(name, opc2, opc3)                               \
7254 static void glue(gen_, name)(DisasContext *ctx)                         \
7255     {                                                                   \
7256         TCGv_ptr rd;                                                    \
7257         TCGv_i32 simm;                                                  \
7258         if (unlikely(!ctx->altivec_enabled)) {                          \
7259             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
7260             return;                                                     \
7261         }                                                               \
7262         simm = tcg_const_i32(SIMM5(ctx->opcode));                       \
7263         rd = gen_avr_ptr(rD(ctx->opcode));                              \
7264         gen_helper_##name (rd, simm);                                   \
7265         tcg_temp_free_i32(simm);                                        \
7266         tcg_temp_free_ptr(rd);                                          \
7267     }
7268
7269 GEN_VXFORM_SIMM(vspltisb, 6, 12);
7270 GEN_VXFORM_SIMM(vspltish, 6, 13);
7271 GEN_VXFORM_SIMM(vspltisw, 6, 14);
7272
7273 #define GEN_VXFORM_NOA(name, opc2, opc3)                                \
7274 static void glue(gen_, name)(DisasContext *ctx)                                 \
7275     {                                                                   \
7276         TCGv_ptr rb, rd;                                                \
7277         if (unlikely(!ctx->altivec_enabled)) {                          \
7278             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
7279             return;                                                     \
7280         }                                                               \
7281         rb = gen_avr_ptr(rB(ctx->opcode));                              \
7282         rd = gen_avr_ptr(rD(ctx->opcode));                              \
7283         gen_helper_##name (rd, rb);                                     \
7284         tcg_temp_free_ptr(rb);                                          \
7285         tcg_temp_free_ptr(rd);                                         \
7286     }
7287
7288 #define GEN_VXFORM_NOA_ENV(name, opc2, opc3)                            \
7289 static void glue(gen_, name)(DisasContext *ctx)                         \
7290     {                                                                   \
7291         TCGv_ptr rb, rd;                                                \
7292                                                                         \
7293         if (unlikely(!ctx->altivec_enabled)) {                          \
7294             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
7295             return;                                                     \
7296         }                                                               \
7297         rb = gen_avr_ptr(rB(ctx->opcode));                              \
7298         rd = gen_avr_ptr(rD(ctx->opcode));                              \
7299         gen_helper_##name(cpu_env, rd, rb);                             \
7300         tcg_temp_free_ptr(rb);                                          \
7301         tcg_temp_free_ptr(rd);                                          \
7302     }
7303
7304 GEN_VXFORM_NOA(vupkhsb, 7, 8);
7305 GEN_VXFORM_NOA(vupkhsh, 7, 9);
7306 GEN_VXFORM_NOA(vupkhsw, 7, 25);
7307 GEN_VXFORM_NOA(vupklsb, 7, 10);
7308 GEN_VXFORM_NOA(vupklsh, 7, 11);
7309 GEN_VXFORM_NOA(vupklsw, 7, 27);
7310 GEN_VXFORM_NOA(vupkhpx, 7, 13);
7311 GEN_VXFORM_NOA(vupklpx, 7, 15);
7312 GEN_VXFORM_NOA_ENV(vrefp, 5, 4);
7313 GEN_VXFORM_NOA_ENV(vrsqrtefp, 5, 5);
7314 GEN_VXFORM_NOA_ENV(vexptefp, 5, 6);
7315 GEN_VXFORM_NOA_ENV(vlogefp, 5, 7);
7316 GEN_VXFORM_NOA_ENV(vrfim, 5, 11);
7317 GEN_VXFORM_NOA_ENV(vrfin, 5, 8);
7318 GEN_VXFORM_NOA_ENV(vrfip, 5, 10);
7319 GEN_VXFORM_NOA_ENV(vrfiz, 5, 9);
7320
7321 #define GEN_VXFORM_SIMM(name, opc2, opc3)                               \
7322 static void glue(gen_, name)(DisasContext *ctx)                                 \
7323     {                                                                   \
7324         TCGv_ptr rd;                                                    \
7325         TCGv_i32 simm;                                                  \
7326         if (unlikely(!ctx->altivec_enabled)) {                          \
7327             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
7328             return;                                                     \
7329         }                                                               \
7330         simm = tcg_const_i32(SIMM5(ctx->opcode));                       \
7331         rd = gen_avr_ptr(rD(ctx->opcode));                              \
7332         gen_helper_##name (rd, simm);                                   \
7333         tcg_temp_free_i32(simm);                                        \
7334         tcg_temp_free_ptr(rd);                                          \
7335     }
7336
7337 #define GEN_VXFORM_UIMM(name, opc2, opc3)                               \
7338 static void glue(gen_, name)(DisasContext *ctx)                                 \
7339     {                                                                   \
7340         TCGv_ptr rb, rd;                                                \
7341         TCGv_i32 uimm;                                                  \
7342         if (unlikely(!ctx->altivec_enabled)) {                          \
7343             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
7344             return;                                                     \
7345         }                                                               \
7346         uimm = tcg_const_i32(UIMM5(ctx->opcode));                       \
7347         rb = gen_avr_ptr(rB(ctx->opcode));                              \
7348         rd = gen_avr_ptr(rD(ctx->opcode));                              \
7349         gen_helper_##name (rd, rb, uimm);                               \
7350         tcg_temp_free_i32(uimm);                                        \
7351         tcg_temp_free_ptr(rb);                                          \
7352         tcg_temp_free_ptr(rd);                                          \
7353     }
7354
7355 #define GEN_VXFORM_UIMM_ENV(name, opc2, opc3)                           \
7356 static void glue(gen_, name)(DisasContext *ctx)                         \
7357     {                                                                   \
7358         TCGv_ptr rb, rd;                                                \
7359         TCGv_i32 uimm;                                                  \
7360                                                                         \
7361         if (unlikely(!ctx->altivec_enabled)) {                          \
7362             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
7363             return;                                                     \
7364         }                                                               \
7365         uimm = tcg_const_i32(UIMM5(ctx->opcode));                       \
7366         rb = gen_avr_ptr(rB(ctx->opcode));                              \
7367         rd = gen_avr_ptr(rD(ctx->opcode));                              \
7368         gen_helper_##name(cpu_env, rd, rb, uimm);                       \
7369         tcg_temp_free_i32(uimm);                                        \
7370         tcg_temp_free_ptr(rb);                                          \
7371         tcg_temp_free_ptr(rd);                                          \
7372     }
7373
7374 GEN_VXFORM_UIMM(vspltb, 6, 8);
7375 GEN_VXFORM_UIMM(vsplth, 6, 9);
7376 GEN_VXFORM_UIMM(vspltw, 6, 10);
7377 GEN_VXFORM_UIMM_ENV(vcfux, 5, 12);
7378 GEN_VXFORM_UIMM_ENV(vcfsx, 5, 13);
7379 GEN_VXFORM_UIMM_ENV(vctuxs, 5, 14);
7380 GEN_VXFORM_UIMM_ENV(vctsxs, 5, 15);
7381
7382 static void gen_vsldoi(DisasContext *ctx)
7383 {
7384     TCGv_ptr ra, rb, rd;
7385     TCGv_i32 sh;
7386     if (unlikely(!ctx->altivec_enabled)) {
7387         gen_exception(ctx, POWERPC_EXCP_VPU);
7388         return;
7389     }
7390     ra = gen_avr_ptr(rA(ctx->opcode));
7391     rb = gen_avr_ptr(rB(ctx->opcode));
7392     rd = gen_avr_ptr(rD(ctx->opcode));
7393     sh = tcg_const_i32(VSH(ctx->opcode));
7394     gen_helper_vsldoi (rd, ra, rb, sh);
7395     tcg_temp_free_ptr(ra);
7396     tcg_temp_free_ptr(rb);
7397     tcg_temp_free_ptr(rd);
7398     tcg_temp_free_i32(sh);
7399 }
7400
7401 #define GEN_VAFORM_PAIRED(name0, name1, opc2)                           \
7402 static void glue(gen_, name0##_##name1)(DisasContext *ctx)              \
7403     {                                                                   \
7404         TCGv_ptr ra, rb, rc, rd;                                        \
7405         if (unlikely(!ctx->altivec_enabled)) {                          \
7406             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
7407             return;                                                     \
7408         }                                                               \
7409         ra = gen_avr_ptr(rA(ctx->opcode));                              \
7410         rb = gen_avr_ptr(rB(ctx->opcode));                              \
7411         rc = gen_avr_ptr(rC(ctx->opcode));                              \
7412         rd = gen_avr_ptr(rD(ctx->opcode));                              \
7413         if (Rc(ctx->opcode)) {                                          \
7414             gen_helper_##name1(cpu_env, rd, ra, rb, rc);                \
7415         } else {                                                        \
7416             gen_helper_##name0(cpu_env, rd, ra, rb, rc);                \
7417         }                                                               \
7418         tcg_temp_free_ptr(ra);                                          \
7419         tcg_temp_free_ptr(rb);                                          \
7420         tcg_temp_free_ptr(rc);                                          \
7421         tcg_temp_free_ptr(rd);                                          \
7422     }
7423
7424 GEN_VAFORM_PAIRED(vmhaddshs, vmhraddshs, 16)
7425
7426 static void gen_vmladduhm(DisasContext *ctx)
7427 {
7428     TCGv_ptr ra, rb, rc, rd;
7429     if (unlikely(!ctx->altivec_enabled)) {
7430         gen_exception(ctx, POWERPC_EXCP_VPU);
7431         return;
7432     }
7433     ra = gen_avr_ptr(rA(ctx->opcode));
7434     rb = gen_avr_ptr(rB(ctx->opcode));
7435     rc = gen_avr_ptr(rC(ctx->opcode));
7436     rd = gen_avr_ptr(rD(ctx->opcode));
7437     gen_helper_vmladduhm(rd, ra, rb, rc);
7438     tcg_temp_free_ptr(ra);
7439     tcg_temp_free_ptr(rb);
7440     tcg_temp_free_ptr(rc);
7441     tcg_temp_free_ptr(rd);
7442 }
7443
7444 GEN_VAFORM_PAIRED(vmsumubm, vmsummbm, 18)
7445 GEN_VAFORM_PAIRED(vmsumuhm, vmsumuhs, 19)
7446 GEN_VAFORM_PAIRED(vmsumshm, vmsumshs, 20)
7447 GEN_VAFORM_PAIRED(vsel, vperm, 21)
7448 GEN_VAFORM_PAIRED(vmaddfp, vnmsubfp, 23)
7449
7450 GEN_VXFORM_NOA(vclzb, 1, 28)
7451 GEN_VXFORM_NOA(vclzh, 1, 29)
7452 GEN_VXFORM_NOA(vclzw, 1, 30)
7453 GEN_VXFORM_NOA(vclzd, 1, 31)
7454 GEN_VXFORM_NOA(vpopcntb, 1, 28)
7455 GEN_VXFORM_NOA(vpopcnth, 1, 29)
7456 GEN_VXFORM_NOA(vpopcntw, 1, 30)
7457 GEN_VXFORM_NOA(vpopcntd, 1, 31)
7458 GEN_VXFORM_DUAL(vclzb, PPC_NONE, PPC2_ALTIVEC_207, \
7459                 vpopcntb, PPC_NONE, PPC2_ALTIVEC_207)
7460 GEN_VXFORM_DUAL(vclzh, PPC_NONE, PPC2_ALTIVEC_207, \
7461                 vpopcnth, PPC_NONE, PPC2_ALTIVEC_207)
7462 GEN_VXFORM_DUAL(vclzw, PPC_NONE, PPC2_ALTIVEC_207, \
7463                 vpopcntw, PPC_NONE, PPC2_ALTIVEC_207)
7464 GEN_VXFORM_DUAL(vclzd, PPC_NONE, PPC2_ALTIVEC_207, \
7465                 vpopcntd, PPC_NONE, PPC2_ALTIVEC_207)
7466 GEN_VXFORM(vbpermq, 6, 21);
7467 GEN_VXFORM_NOA(vgbbd, 6, 20);
7468 GEN_VXFORM(vpmsumb, 4, 16)
7469 GEN_VXFORM(vpmsumh, 4, 17)
7470 GEN_VXFORM(vpmsumw, 4, 18)
7471 GEN_VXFORM(vpmsumd, 4, 19)
7472
7473 #define GEN_BCD(op)                                 \
7474 static void gen_##op(DisasContext *ctx)             \
7475 {                                                   \
7476     TCGv_ptr ra, rb, rd;                            \
7477     TCGv_i32 ps;                                    \
7478                                                     \
7479     if (unlikely(!ctx->altivec_enabled)) {          \
7480         gen_exception(ctx, POWERPC_EXCP_VPU);       \
7481         return;                                     \
7482     }                                               \
7483                                                     \
7484     ra = gen_avr_ptr(rA(ctx->opcode));              \
7485     rb = gen_avr_ptr(rB(ctx->opcode));              \
7486     rd = gen_avr_ptr(rD(ctx->opcode));              \
7487                                                     \
7488     ps = tcg_const_i32((ctx->opcode & 0x200) != 0); \
7489                                                     \
7490     gen_helper_##op(cpu_crf[6], rd, ra, rb, ps);    \
7491                                                     \
7492     tcg_temp_free_ptr(ra);                          \
7493     tcg_temp_free_ptr(rb);                          \
7494     tcg_temp_free_ptr(rd);                          \
7495     tcg_temp_free_i32(ps);                          \
7496 }
7497
7498 GEN_BCD(bcdadd)
7499 GEN_BCD(bcdsub)
7500
7501 GEN_VXFORM_DUAL(vsububm, PPC_ALTIVEC, PPC_NONE, \
7502                 bcdadd, PPC_NONE, PPC2_ALTIVEC_207)
7503 GEN_VXFORM_DUAL(vsububs, PPC_ALTIVEC, PPC_NONE, \
7504                 bcdadd, PPC_NONE, PPC2_ALTIVEC_207)
7505 GEN_VXFORM_DUAL(vsubuhm, PPC_ALTIVEC, PPC_NONE, \
7506                 bcdsub, PPC_NONE, PPC2_ALTIVEC_207)
7507 GEN_VXFORM_DUAL(vsubuhs, PPC_ALTIVEC, PPC_NONE, \
7508                 bcdsub, PPC_NONE, PPC2_ALTIVEC_207)
7509
7510 static void gen_vsbox(DisasContext *ctx)
7511 {
7512     TCGv_ptr ra, rd;
7513     if (unlikely(!ctx->altivec_enabled)) {
7514         gen_exception(ctx, POWERPC_EXCP_VPU);
7515         return;
7516     }
7517     ra = gen_avr_ptr(rA(ctx->opcode));
7518     rd = gen_avr_ptr(rD(ctx->opcode));
7519     gen_helper_vsbox(rd, ra);
7520     tcg_temp_free_ptr(ra);
7521     tcg_temp_free_ptr(rd);
7522 }
7523
7524 GEN_VXFORM(vcipher, 4, 20)
7525 GEN_VXFORM(vcipherlast, 4, 20)
7526 GEN_VXFORM(vncipher, 4, 21)
7527 GEN_VXFORM(vncipherlast, 4, 21)
7528
7529 GEN_VXFORM_DUAL(vcipher, PPC_NONE, PPC2_ALTIVEC_207,
7530                 vcipherlast, PPC_NONE, PPC2_ALTIVEC_207)
7531 GEN_VXFORM_DUAL(vncipher, PPC_NONE, PPC2_ALTIVEC_207,
7532                 vncipherlast, PPC_NONE, PPC2_ALTIVEC_207)
7533
7534 #define VSHASIGMA(op)                         \
7535 static void gen_##op(DisasContext *ctx)       \
7536 {                                             \
7537     TCGv_ptr ra, rd;                          \
7538     TCGv_i32 st_six;                          \
7539     if (unlikely(!ctx->altivec_enabled)) {    \
7540         gen_exception(ctx, POWERPC_EXCP_VPU); \
7541         return;                               \
7542     }                                         \
7543     ra = gen_avr_ptr(rA(ctx->opcode));        \
7544     rd = gen_avr_ptr(rD(ctx->opcode));        \
7545     st_six = tcg_const_i32(rB(ctx->opcode));  \
7546     gen_helper_##op(rd, ra, st_six);          \
7547     tcg_temp_free_ptr(ra);                    \
7548     tcg_temp_free_ptr(rd);                    \
7549     tcg_temp_free_i32(st_six);                \
7550 }
7551
7552 VSHASIGMA(vshasigmaw)
7553 VSHASIGMA(vshasigmad)
7554
7555 GEN_VXFORM3(vpermxor, 22, 0xFF)
7556 GEN_VXFORM_DUAL(vsldoi, PPC_ALTIVEC, PPC_NONE,
7557                 vpermxor, PPC_NONE, PPC2_ALTIVEC_207)
7558
7559 /***                           VSX extension                               ***/
7560
7561 static inline TCGv_i64 cpu_vsrh(int n)
7562 {
7563     if (n < 32) {
7564         return cpu_fpr[n];
7565     } else {
7566         return cpu_avrh[n-32];
7567     }
7568 }
7569
7570 static inline TCGv_i64 cpu_vsrl(int n)
7571 {
7572     if (n < 32) {
7573         return cpu_vsr[n];
7574     } else {
7575         return cpu_avrl[n-32];
7576     }
7577 }
7578
7579 #define VSX_LOAD_SCALAR(name, operation)                      \
7580 static void gen_##name(DisasContext *ctx)                     \
7581 {                                                             \
7582     TCGv EA;                                                  \
7583     if (unlikely(!ctx->vsx_enabled)) {                        \
7584         gen_exception(ctx, POWERPC_EXCP_VSXU);                \
7585         return;                                               \
7586     }                                                         \
7587     gen_set_access_type(ctx, ACCESS_INT);                     \
7588     EA = tcg_temp_new();                                      \
7589     gen_addr_reg_index(ctx, EA);                              \
7590     gen_qemu_##operation(ctx, cpu_vsrh(xT(ctx->opcode)), EA); \
7591     /* NOTE: cpu_vsrl is undefined */                         \
7592     tcg_temp_free(EA);                                        \
7593 }
7594
7595 VSX_LOAD_SCALAR(lxsdx, ld64)
7596 VSX_LOAD_SCALAR(lxsiwax, ld32s_i64)
7597 VSX_LOAD_SCALAR(lxsiwzx, ld32u_i64)
7598 VSX_LOAD_SCALAR(lxsspx, ld32fs)
7599
7600 static void gen_lxvd2x(DisasContext *ctx)
7601 {
7602     TCGv EA;
7603     if (unlikely(!ctx->vsx_enabled)) {
7604         gen_exception(ctx, POWERPC_EXCP_VSXU);
7605         return;
7606     }
7607     gen_set_access_type(ctx, ACCESS_INT);
7608     EA = tcg_temp_new();
7609     gen_addr_reg_index(ctx, EA);
7610     gen_qemu_ld64(ctx, cpu_vsrh(xT(ctx->opcode)), EA);
7611     tcg_gen_addi_tl(EA, EA, 8);
7612     gen_qemu_ld64(ctx, cpu_vsrl(xT(ctx->opcode)), EA);
7613     tcg_temp_free(EA);
7614 }
7615
7616 static void gen_lxvdsx(DisasContext *ctx)
7617 {
7618     TCGv EA;
7619     if (unlikely(!ctx->vsx_enabled)) {
7620         gen_exception(ctx, POWERPC_EXCP_VSXU);
7621         return;
7622     }
7623     gen_set_access_type(ctx, ACCESS_INT);
7624     EA = tcg_temp_new();
7625     gen_addr_reg_index(ctx, EA);
7626     gen_qemu_ld64(ctx, cpu_vsrh(xT(ctx->opcode)), EA);
7627     tcg_gen_mov_i64(cpu_vsrl(xT(ctx->opcode)), cpu_vsrh(xT(ctx->opcode)));
7628     tcg_temp_free(EA);
7629 }
7630
7631 static void gen_lxvw4x(DisasContext *ctx)
7632 {
7633     TCGv EA;
7634     TCGv_i64 tmp;
7635     TCGv_i64 xth = cpu_vsrh(xT(ctx->opcode));
7636     TCGv_i64 xtl = cpu_vsrl(xT(ctx->opcode));
7637     if (unlikely(!ctx->vsx_enabled)) {
7638         gen_exception(ctx, POWERPC_EXCP_VSXU);
7639         return;
7640     }
7641     gen_set_access_type(ctx, ACCESS_INT);
7642     EA = tcg_temp_new();
7643     tmp = tcg_temp_new_i64();
7644
7645     gen_addr_reg_index(ctx, EA);
7646     gen_qemu_ld32u_i64(ctx, tmp, EA);
7647     tcg_gen_addi_tl(EA, EA, 4);
7648     gen_qemu_ld32u_i64(ctx, xth, EA);
7649     tcg_gen_deposit_i64(xth, xth, tmp, 32, 32);
7650
7651     tcg_gen_addi_tl(EA, EA, 4);
7652     gen_qemu_ld32u_i64(ctx, tmp, EA);
7653     tcg_gen_addi_tl(EA, EA, 4);
7654     gen_qemu_ld32u_i64(ctx, xtl, EA);
7655     tcg_gen_deposit_i64(xtl, xtl, tmp, 32, 32);
7656
7657     tcg_temp_free(EA);
7658     tcg_temp_free_i64(tmp);
7659 }
7660
7661 #define VSX_STORE_SCALAR(name, operation)                     \
7662 static void gen_##name(DisasContext *ctx)                     \
7663 {                                                             \
7664     TCGv EA;                                                  \
7665     if (unlikely(!ctx->vsx_enabled)) {                        \
7666         gen_exception(ctx, POWERPC_EXCP_VSXU);                \
7667         return;                                               \
7668     }                                                         \
7669     gen_set_access_type(ctx, ACCESS_INT);                     \
7670     EA = tcg_temp_new();                                      \
7671     gen_addr_reg_index(ctx, EA);                              \
7672     gen_qemu_##operation(ctx, cpu_vsrh(xS(ctx->opcode)), EA); \
7673     tcg_temp_free(EA);                                        \
7674 }
7675
7676 VSX_STORE_SCALAR(stxsdx, st64)
7677 VSX_STORE_SCALAR(stxsiwx, st32_i64)
7678 VSX_STORE_SCALAR(stxsspx, st32fs)
7679
7680 static void gen_stxvd2x(DisasContext *ctx)
7681 {
7682     TCGv EA;
7683     if (unlikely(!ctx->vsx_enabled)) {
7684         gen_exception(ctx, POWERPC_EXCP_VSXU);
7685         return;
7686     }
7687     gen_set_access_type(ctx, ACCESS_INT);
7688     EA = tcg_temp_new();
7689     gen_addr_reg_index(ctx, EA);
7690     gen_qemu_st64(ctx, cpu_vsrh(xS(ctx->opcode)), EA);
7691     tcg_gen_addi_tl(EA, EA, 8);
7692     gen_qemu_st64(ctx, cpu_vsrl(xS(ctx->opcode)), EA);
7693     tcg_temp_free(EA);
7694 }
7695
7696 static void gen_stxvw4x(DisasContext *ctx)
7697 {
7698     TCGv_i64 tmp;
7699     TCGv EA;
7700     if (unlikely(!ctx->vsx_enabled)) {
7701         gen_exception(ctx, POWERPC_EXCP_VSXU);
7702         return;
7703     }
7704     gen_set_access_type(ctx, ACCESS_INT);
7705     EA = tcg_temp_new();
7706     gen_addr_reg_index(ctx, EA);
7707     tmp = tcg_temp_new_i64();
7708
7709     tcg_gen_shri_i64(tmp, cpu_vsrh(xS(ctx->opcode)), 32);
7710     gen_qemu_st32_i64(ctx, tmp, EA);
7711     tcg_gen_addi_tl(EA, EA, 4);
7712     gen_qemu_st32_i64(ctx, cpu_vsrh(xS(ctx->opcode)), EA);
7713
7714     tcg_gen_shri_i64(tmp, cpu_vsrl(xS(ctx->opcode)), 32);
7715     tcg_gen_addi_tl(EA, EA, 4);
7716     gen_qemu_st32_i64(ctx, tmp, EA);
7717     tcg_gen_addi_tl(EA, EA, 4);
7718     gen_qemu_st32_i64(ctx, cpu_vsrl(xS(ctx->opcode)), EA);
7719
7720     tcg_temp_free(EA);
7721     tcg_temp_free_i64(tmp);
7722 }
7723
7724 #define MV_VSRW(name, tcgop1, tcgop2, target, source)           \
7725 static void gen_##name(DisasContext *ctx)                       \
7726 {                                                               \
7727     if (xS(ctx->opcode) < 32) {                                 \
7728         if (unlikely(!ctx->fpu_enabled)) {                      \
7729             gen_exception(ctx, POWERPC_EXCP_FPU);               \
7730             return;                                             \
7731         }                                                       \
7732     } else {                                                    \
7733         if (unlikely(!ctx->altivec_enabled)) {                  \
7734             gen_exception(ctx, POWERPC_EXCP_VPU);               \
7735             return;                                             \
7736         }                                                       \
7737     }                                                           \
7738     TCGv_i64 tmp = tcg_temp_new_i64();                          \
7739     tcg_gen_##tcgop1(tmp, source);                              \
7740     tcg_gen_##tcgop2(target, tmp);                              \
7741     tcg_temp_free_i64(tmp);                                     \
7742 }
7743
7744
7745 MV_VSRW(mfvsrwz, ext32u_i64, trunc_i64_tl, cpu_gpr[rA(ctx->opcode)], \
7746         cpu_vsrh(xS(ctx->opcode)))
7747 MV_VSRW(mtvsrwa, extu_tl_i64, ext32s_i64, cpu_vsrh(xT(ctx->opcode)), \
7748         cpu_gpr[rA(ctx->opcode)])
7749 MV_VSRW(mtvsrwz, extu_tl_i64, ext32u_i64, cpu_vsrh(xT(ctx->opcode)), \
7750         cpu_gpr[rA(ctx->opcode)])
7751
7752 #if defined(TARGET_PPC64)
7753 #define MV_VSRD(name, target, source)                           \
7754 static void gen_##name(DisasContext *ctx)                       \
7755 {                                                               \
7756     if (xS(ctx->opcode) < 32) {                                 \
7757         if (unlikely(!ctx->fpu_enabled)) {                      \
7758             gen_exception(ctx, POWERPC_EXCP_FPU);               \
7759             return;                                             \
7760         }                                                       \
7761     } else {                                                    \
7762         if (unlikely(!ctx->altivec_enabled)) {                  \
7763             gen_exception(ctx, POWERPC_EXCP_VPU);               \
7764             return;                                             \
7765         }                                                       \
7766     }                                                           \
7767     tcg_gen_mov_i64(target, source);                            \
7768 }
7769
7770 MV_VSRD(mfvsrd, cpu_gpr[rA(ctx->opcode)], cpu_vsrh(xS(ctx->opcode)))
7771 MV_VSRD(mtvsrd, cpu_vsrh(xT(ctx->opcode)), cpu_gpr[rA(ctx->opcode)])
7772
7773 #endif
7774
7775 static void gen_xxpermdi(DisasContext *ctx)
7776 {
7777     if (unlikely(!ctx->vsx_enabled)) {
7778         gen_exception(ctx, POWERPC_EXCP_VSXU);
7779         return;
7780     }
7781
7782     if (unlikely((xT(ctx->opcode) == xA(ctx->opcode)) ||
7783                  (xT(ctx->opcode) == xB(ctx->opcode)))) {
7784         TCGv_i64 xh, xl;
7785
7786         xh = tcg_temp_new_i64();
7787         xl = tcg_temp_new_i64();
7788
7789         if ((DM(ctx->opcode) & 2) == 0) {
7790             tcg_gen_mov_i64(xh, cpu_vsrh(xA(ctx->opcode)));
7791         } else {
7792             tcg_gen_mov_i64(xh, cpu_vsrl(xA(ctx->opcode)));
7793         }
7794         if ((DM(ctx->opcode) & 1) == 0) {
7795             tcg_gen_mov_i64(xl, cpu_vsrh(xB(ctx->opcode)));
7796         } else {
7797             tcg_gen_mov_i64(xl, cpu_vsrl(xB(ctx->opcode)));
7798         }
7799
7800         tcg_gen_mov_i64(cpu_vsrh(xT(ctx->opcode)), xh);
7801         tcg_gen_mov_i64(cpu_vsrl(xT(ctx->opcode)), xl);
7802
7803         tcg_temp_free_i64(xh);
7804         tcg_temp_free_i64(xl);
7805     } else {
7806         if ((DM(ctx->opcode) & 2) == 0) {
7807             tcg_gen_mov_i64(cpu_vsrh(xT(ctx->opcode)), cpu_vsrh(xA(ctx->opcode)));
7808         } else {
7809             tcg_gen_mov_i64(cpu_vsrh(xT(ctx->opcode)), cpu_vsrl(xA(ctx->opcode)));
7810         }
7811         if ((DM(ctx->opcode) & 1) == 0) {
7812             tcg_gen_mov_i64(cpu_vsrl(xT(ctx->opcode)), cpu_vsrh(xB(ctx->opcode)));
7813         } else {
7814             tcg_gen_mov_i64(cpu_vsrl(xT(ctx->opcode)), cpu_vsrl(xB(ctx->opcode)));
7815         }
7816     }
7817 }
7818
7819 #define OP_ABS 1
7820 #define OP_NABS 2
7821 #define OP_NEG 3
7822 #define OP_CPSGN 4
7823 #define SGN_MASK_DP  0x8000000000000000ull
7824 #define SGN_MASK_SP 0x8000000080000000ull
7825
7826 #define VSX_SCALAR_MOVE(name, op, sgn_mask)                       \
7827 static void glue(gen_, name)(DisasContext * ctx)                  \
7828     {                                                             \
7829         TCGv_i64 xb, sgm;                                         \
7830         if (unlikely(!ctx->vsx_enabled)) {                        \
7831             gen_exception(ctx, POWERPC_EXCP_VSXU);                \
7832             return;                                               \
7833         }                                                         \
7834         xb = tcg_temp_new_i64();                                  \
7835         sgm = tcg_temp_new_i64();                                 \
7836         tcg_gen_mov_i64(xb, cpu_vsrh(xB(ctx->opcode)));           \
7837         tcg_gen_movi_i64(sgm, sgn_mask);                          \
7838         switch (op) {                                             \
7839             case OP_ABS: {                                        \
7840                 tcg_gen_andc_i64(xb, xb, sgm);                    \
7841                 break;                                            \
7842             }                                                     \
7843             case OP_NABS: {                                       \
7844                 tcg_gen_or_i64(xb, xb, sgm);                      \
7845                 break;                                            \
7846             }                                                     \
7847             case OP_NEG: {                                        \
7848                 tcg_gen_xor_i64(xb, xb, sgm);                     \
7849                 break;                                            \
7850             }                                                     \
7851             case OP_CPSGN: {                                      \
7852                 TCGv_i64 xa = tcg_temp_new_i64();                 \
7853                 tcg_gen_mov_i64(xa, cpu_vsrh(xA(ctx->opcode)));   \
7854                 tcg_gen_and_i64(xa, xa, sgm);                     \
7855                 tcg_gen_andc_i64(xb, xb, sgm);                    \
7856                 tcg_gen_or_i64(xb, xb, xa);                       \
7857                 tcg_temp_free_i64(xa);                            \
7858                 break;                                            \
7859             }                                                     \
7860         }                                                         \
7861         tcg_gen_mov_i64(cpu_vsrh(xT(ctx->opcode)), xb);           \
7862         tcg_temp_free_i64(xb);                                    \
7863         tcg_temp_free_i64(sgm);                                   \
7864     }
7865
7866 VSX_SCALAR_MOVE(xsabsdp, OP_ABS, SGN_MASK_DP)
7867 VSX_SCALAR_MOVE(xsnabsdp, OP_NABS, SGN_MASK_DP)
7868 VSX_SCALAR_MOVE(xsnegdp, OP_NEG, SGN_MASK_DP)
7869 VSX_SCALAR_MOVE(xscpsgndp, OP_CPSGN, SGN_MASK_DP)
7870
7871 #define VSX_VECTOR_MOVE(name, op, sgn_mask)                      \
7872 static void glue(gen_, name)(DisasContext * ctx)                 \
7873     {                                                            \
7874         TCGv_i64 xbh, xbl, sgm;                                  \
7875         if (unlikely(!ctx->vsx_enabled)) {                       \
7876             gen_exception(ctx, POWERPC_EXCP_VSXU);               \
7877             return;                                              \
7878         }                                                        \
7879         xbh = tcg_temp_new_i64();                                \
7880         xbl = tcg_temp_new_i64();                                \
7881         sgm = tcg_temp_new_i64();                                \
7882         tcg_gen_mov_i64(xbh, cpu_vsrh(xB(ctx->opcode)));         \
7883         tcg_gen_mov_i64(xbl, cpu_vsrl(xB(ctx->opcode)));         \
7884         tcg_gen_movi_i64(sgm, sgn_mask);                         \
7885         switch (op) {                                            \
7886             case OP_ABS: {                                       \
7887                 tcg_gen_andc_i64(xbh, xbh, sgm);                 \
7888                 tcg_gen_andc_i64(xbl, xbl, sgm);                 \
7889                 break;                                           \
7890             }                                                    \
7891             case OP_NABS: {                                      \
7892                 tcg_gen_or_i64(xbh, xbh, sgm);                   \
7893                 tcg_gen_or_i64(xbl, xbl, sgm);                   \
7894                 break;                                           \
7895             }                                                    \
7896             case OP_NEG: {                                       \
7897                 tcg_gen_xor_i64(xbh, xbh, sgm);                  \
7898                 tcg_gen_xor_i64(xbl, xbl, sgm);                  \
7899                 break;                                           \
7900             }                                                    \
7901             case OP_CPSGN: {                                     \
7902                 TCGv_i64 xah = tcg_temp_new_i64();               \
7903                 TCGv_i64 xal = tcg_temp_new_i64();               \
7904                 tcg_gen_mov_i64(xah, cpu_vsrh(xA(ctx->opcode))); \
7905                 tcg_gen_mov_i64(xal, cpu_vsrl(xA(ctx->opcode))); \
7906                 tcg_gen_and_i64(xah, xah, sgm);                  \
7907                 tcg_gen_and_i64(xal, xal, sgm);                  \
7908                 tcg_gen_andc_i64(xbh, xbh, sgm);                 \
7909                 tcg_gen_andc_i64(xbl, xbl, sgm);                 \
7910                 tcg_gen_or_i64(xbh, xbh, xah);                   \
7911                 tcg_gen_or_i64(xbl, xbl, xal);                   \
7912                 tcg_temp_free_i64(xah);                          \
7913                 tcg_temp_free_i64(xal);                          \
7914                 break;                                           \
7915             }                                                    \
7916         }                                                        \
7917         tcg_gen_mov_i64(cpu_vsrh(xT(ctx->opcode)), xbh);         \
7918         tcg_gen_mov_i64(cpu_vsrl(xT(ctx->opcode)), xbl);         \
7919         tcg_temp_free_i64(xbh);                                  \
7920         tcg_temp_free_i64(xbl);                                  \
7921         tcg_temp_free_i64(sgm);                                  \
7922     }
7923
7924 VSX_VECTOR_MOVE(xvabsdp, OP_ABS, SGN_MASK_DP)
7925 VSX_VECTOR_MOVE(xvnabsdp, OP_NABS, SGN_MASK_DP)
7926 VSX_VECTOR_MOVE(xvnegdp, OP_NEG, SGN_MASK_DP)
7927 VSX_VECTOR_MOVE(xvcpsgndp, OP_CPSGN, SGN_MASK_DP)
7928 VSX_VECTOR_MOVE(xvabssp, OP_ABS, SGN_MASK_SP)
7929 VSX_VECTOR_MOVE(xvnabssp, OP_NABS, SGN_MASK_SP)
7930 VSX_VECTOR_MOVE(xvnegsp, OP_NEG, SGN_MASK_SP)
7931 VSX_VECTOR_MOVE(xvcpsgnsp, OP_CPSGN, SGN_MASK_SP)
7932
7933 #define GEN_VSX_HELPER_2(name, op1, op2, inval, type)                         \
7934 static void gen_##name(DisasContext * ctx)                                    \
7935 {                                                                             \
7936     TCGv_i32 opc;                                                             \
7937     if (unlikely(!ctx->vsx_enabled)) {                                        \
7938         gen_exception(ctx, POWERPC_EXCP_VSXU);                                \
7939         return;                                                               \
7940     }                                                                         \
7941     /* NIP cannot be restored if the memory exception comes from an helper */ \
7942     gen_update_nip(ctx, ctx->nip - 4);                                        \
7943     opc = tcg_const_i32(ctx->opcode);                                         \
7944     gen_helper_##name(cpu_env, opc);                                          \
7945     tcg_temp_free_i32(opc);                                                   \
7946 }
7947
7948 #define GEN_VSX_HELPER_XT_XB_ENV(name, op1, op2, inval, type) \
7949 static void gen_##name(DisasContext * ctx)                    \
7950 {                                                             \
7951     if (unlikely(!ctx->vsx_enabled)) {                        \
7952         gen_exception(ctx, POWERPC_EXCP_VSXU);                \
7953         return;                                               \
7954     }                                                         \
7955     /* NIP cannot be restored if the exception comes */       \
7956     /* from a helper. */                                      \
7957     gen_update_nip(ctx, ctx->nip - 4);                        \
7958                                                               \
7959     gen_helper_##name(cpu_vsrh(xT(ctx->opcode)), cpu_env,     \
7960                       cpu_vsrh(xB(ctx->opcode)));             \
7961 }
7962
7963 GEN_VSX_HELPER_2(xsadddp, 0x00, 0x04, 0, PPC2_VSX)
7964 GEN_VSX_HELPER_2(xssubdp, 0x00, 0x05, 0, PPC2_VSX)
7965 GEN_VSX_HELPER_2(xsmuldp, 0x00, 0x06, 0, PPC2_VSX)
7966 GEN_VSX_HELPER_2(xsdivdp, 0x00, 0x07, 0, PPC2_VSX)
7967 GEN_VSX_HELPER_2(xsredp, 0x14, 0x05, 0, PPC2_VSX)
7968 GEN_VSX_HELPER_2(xssqrtdp, 0x16, 0x04, 0, PPC2_VSX)
7969 GEN_VSX_HELPER_2(xsrsqrtedp, 0x14, 0x04, 0, PPC2_VSX)
7970 GEN_VSX_HELPER_2(xstdivdp, 0x14, 0x07, 0, PPC2_VSX)
7971 GEN_VSX_HELPER_2(xstsqrtdp, 0x14, 0x06, 0, PPC2_VSX)
7972 GEN_VSX_HELPER_2(xsmaddadp, 0x04, 0x04, 0, PPC2_VSX)
7973 GEN_VSX_HELPER_2(xsmaddmdp, 0x04, 0x05, 0, PPC2_VSX)
7974 GEN_VSX_HELPER_2(xsmsubadp, 0x04, 0x06, 0, PPC2_VSX)
7975 GEN_VSX_HELPER_2(xsmsubmdp, 0x04, 0x07, 0, PPC2_VSX)
7976 GEN_VSX_HELPER_2(xsnmaddadp, 0x04, 0x14, 0, PPC2_VSX)
7977 GEN_VSX_HELPER_2(xsnmaddmdp, 0x04, 0x15, 0, PPC2_VSX)
7978 GEN_VSX_HELPER_2(xsnmsubadp, 0x04, 0x16, 0, PPC2_VSX)
7979 GEN_VSX_HELPER_2(xsnmsubmdp, 0x04, 0x17, 0, PPC2_VSX)
7980 GEN_VSX_HELPER_2(xscmpodp, 0x0C, 0x05, 0, PPC2_VSX)
7981 GEN_VSX_HELPER_2(xscmpudp, 0x0C, 0x04, 0, PPC2_VSX)
7982 GEN_VSX_HELPER_2(xsmaxdp, 0x00, 0x14, 0, PPC2_VSX)
7983 GEN_VSX_HELPER_2(xsmindp, 0x00, 0x15, 0, PPC2_VSX)
7984 GEN_VSX_HELPER_2(xscvdpsp, 0x12, 0x10, 0, PPC2_VSX)
7985 GEN_VSX_HELPER_XT_XB_ENV(xscvdpspn, 0x16, 0x10, 0, PPC2_VSX207)
7986 GEN_VSX_HELPER_2(xscvspdp, 0x12, 0x14, 0, PPC2_VSX)
7987 GEN_VSX_HELPER_XT_XB_ENV(xscvspdpn, 0x16, 0x14, 0, PPC2_VSX207)
7988 GEN_VSX_HELPER_2(xscvdpsxds, 0x10, 0x15, 0, PPC2_VSX)
7989 GEN_VSX_HELPER_2(xscvdpsxws, 0x10, 0x05, 0, PPC2_VSX)
7990 GEN_VSX_HELPER_2(xscvdpuxds, 0x10, 0x14, 0, PPC2_VSX)
7991 GEN_VSX_HELPER_2(xscvdpuxws, 0x10, 0x04, 0, PPC2_VSX)
7992 GEN_VSX_HELPER_2(xscvsxddp, 0x10, 0x17, 0, PPC2_VSX)
7993 GEN_VSX_HELPER_2(xscvuxddp, 0x10, 0x16, 0, PPC2_VSX)
7994 GEN_VSX_HELPER_2(xsrdpi, 0x12, 0x04, 0, PPC2_VSX)
7995 GEN_VSX_HELPER_2(xsrdpic, 0x16, 0x06, 0, PPC2_VSX)
7996 GEN_VSX_HELPER_2(xsrdpim, 0x12, 0x07, 0, PPC2_VSX)
7997 GEN_VSX_HELPER_2(xsrdpip, 0x12, 0x06, 0, PPC2_VSX)
7998 GEN_VSX_HELPER_2(xsrdpiz, 0x12, 0x05, 0, PPC2_VSX)
7999 GEN_VSX_HELPER_XT_XB_ENV(xsrsp, 0x12, 0x11, 0, PPC2_VSX207)
8000
8001 GEN_VSX_HELPER_2(xsaddsp, 0x00, 0x00, 0, PPC2_VSX207)
8002 GEN_VSX_HELPER_2(xssubsp, 0x00, 0x01, 0, PPC2_VSX207)
8003 GEN_VSX_HELPER_2(xsmulsp, 0x00, 0x02, 0, PPC2_VSX207)
8004 GEN_VSX_HELPER_2(xsdivsp, 0x00, 0x03, 0, PPC2_VSX207)
8005 GEN_VSX_HELPER_2(xsresp, 0x14, 0x01, 0, PPC2_VSX207)
8006 GEN_VSX_HELPER_2(xssqrtsp, 0x16, 0x00, 0, PPC2_VSX207)
8007 GEN_VSX_HELPER_2(xsrsqrtesp, 0x14, 0x00, 0, PPC2_VSX207)
8008 GEN_VSX_HELPER_2(xsmaddasp, 0x04, 0x00, 0, PPC2_VSX207)
8009 GEN_VSX_HELPER_2(xsmaddmsp, 0x04, 0x01, 0, PPC2_VSX207)
8010 GEN_VSX_HELPER_2(xsmsubasp, 0x04, 0x02, 0, PPC2_VSX207)
8011 GEN_VSX_HELPER_2(xsmsubmsp, 0x04, 0x03, 0, PPC2_VSX207)
8012 GEN_VSX_HELPER_2(xsnmaddasp, 0x04, 0x10, 0, PPC2_VSX207)
8013 GEN_VSX_HELPER_2(xsnmaddmsp, 0x04, 0x11, 0, PPC2_VSX207)
8014 GEN_VSX_HELPER_2(xsnmsubasp, 0x04, 0x12, 0, PPC2_VSX207)
8015 GEN_VSX_HELPER_2(xsnmsubmsp, 0x04, 0x13, 0, PPC2_VSX207)
8016 GEN_VSX_HELPER_2(xscvsxdsp, 0x10, 0x13, 0, PPC2_VSX207)
8017 GEN_VSX_HELPER_2(xscvuxdsp, 0x10, 0x12, 0, PPC2_VSX207)
8018
8019 GEN_VSX_HELPER_2(xvadddp, 0x00, 0x0C, 0, PPC2_VSX)
8020 GEN_VSX_HELPER_2(xvsubdp, 0x00, 0x0D, 0, PPC2_VSX)
8021 GEN_VSX_HELPER_2(xvmuldp, 0x00, 0x0E, 0, PPC2_VSX)
8022 GEN_VSX_HELPER_2(xvdivdp, 0x00, 0x0F, 0, PPC2_VSX)
8023 GEN_VSX_HELPER_2(xvredp, 0x14, 0x0D, 0, PPC2_VSX)
8024 GEN_VSX_HELPER_2(xvsqrtdp, 0x16, 0x0C, 0, PPC2_VSX)
8025 GEN_VSX_HELPER_2(xvrsqrtedp, 0x14, 0x0C, 0, PPC2_VSX)
8026 GEN_VSX_HELPER_2(xvtdivdp, 0x14, 0x0F, 0, PPC2_VSX)
8027 GEN_VSX_HELPER_2(xvtsqrtdp, 0x14, 0x0E, 0, PPC2_VSX)
8028 GEN_VSX_HELPER_2(xvmaddadp, 0x04, 0x0C, 0, PPC2_VSX)
8029 GEN_VSX_HELPER_2(xvmaddmdp, 0x04, 0x0D, 0, PPC2_VSX)
8030 GEN_VSX_HELPER_2(xvmsubadp, 0x04, 0x0E, 0, PPC2_VSX)
8031 GEN_VSX_HELPER_2(xvmsubmdp, 0x04, 0x0F, 0, PPC2_VSX)
8032 GEN_VSX_HELPER_2(xvnmaddadp, 0x04, 0x1C, 0, PPC2_VSX)
8033 GEN_VSX_HELPER_2(xvnmaddmdp, 0x04, 0x1D, 0, PPC2_VSX)
8034 GEN_VSX_HELPER_2(xvnmsubadp, 0x04, 0x1E, 0, PPC2_VSX)
8035 GEN_VSX_HELPER_2(xvnmsubmdp, 0x04, 0x1F, 0, PPC2_VSX)
8036 GEN_VSX_HELPER_2(xvmaxdp, 0x00, 0x1C, 0, PPC2_VSX)
8037 GEN_VSX_HELPER_2(xvmindp, 0x00, 0x1D, 0, PPC2_VSX)
8038 GEN_VSX_HELPER_2(xvcmpeqdp, 0x0C, 0x0C, 0, PPC2_VSX)
8039 GEN_VSX_HELPER_2(xvcmpgtdp, 0x0C, 0x0D, 0, PPC2_VSX)
8040 GEN_VSX_HELPER_2(xvcmpgedp, 0x0C, 0x0E, 0, PPC2_VSX)
8041 GEN_VSX_HELPER_2(xvcvdpsp, 0x12, 0x18, 0, PPC2_VSX)
8042 GEN_VSX_HELPER_2(xvcvdpsxds, 0x10, 0x1D, 0, PPC2_VSX)
8043 GEN_VSX_HELPER_2(xvcvdpsxws, 0x10, 0x0D, 0, PPC2_VSX)
8044 GEN_VSX_HELPER_2(xvcvdpuxds, 0x10, 0x1C, 0, PPC2_VSX)
8045 GEN_VSX_HELPER_2(xvcvdpuxws, 0x10, 0x0C, 0, PPC2_VSX)
8046 GEN_VSX_HELPER_2(xvcvsxddp, 0x10, 0x1F, 0, PPC2_VSX)
8047 GEN_VSX_HELPER_2(xvcvuxddp, 0x10, 0x1E, 0, PPC2_VSX)
8048 GEN_VSX_HELPER_2(xvcvsxwdp, 0x10, 0x0F, 0, PPC2_VSX)
8049 GEN_VSX_HELPER_2(xvcvuxwdp, 0x10, 0x0E, 0, PPC2_VSX)
8050 GEN_VSX_HELPER_2(xvrdpi, 0x12, 0x0C, 0, PPC2_VSX)
8051 GEN_VSX_HELPER_2(xvrdpic, 0x16, 0x0E, 0, PPC2_VSX)
8052 GEN_VSX_HELPER_2(xvrdpim, 0x12, 0x0F, 0, PPC2_VSX)
8053 GEN_VSX_HELPER_2(xvrdpip, 0x12, 0x0E, 0, PPC2_VSX)
8054 GEN_VSX_HELPER_2(xvrdpiz, 0x12, 0x0D, 0, PPC2_VSX)
8055
8056 GEN_VSX_HELPER_2(xvaddsp, 0x00, 0x08, 0, PPC2_VSX)
8057 GEN_VSX_HELPER_2(xvsubsp, 0x00, 0x09, 0, PPC2_VSX)
8058 GEN_VSX_HELPER_2(xvmulsp, 0x00, 0x0A, 0, PPC2_VSX)
8059 GEN_VSX_HELPER_2(xvdivsp, 0x00, 0x0B, 0, PPC2_VSX)
8060 GEN_VSX_HELPER_2(xvresp, 0x14, 0x09, 0, PPC2_VSX)
8061 GEN_VSX_HELPER_2(xvsqrtsp, 0x16, 0x08, 0, PPC2_VSX)
8062 GEN_VSX_HELPER_2(xvrsqrtesp, 0x14, 0x08, 0, PPC2_VSX)
8063 GEN_VSX_HELPER_2(xvtdivsp, 0x14, 0x0B, 0, PPC2_VSX)
8064 GEN_VSX_HELPER_2(xvtsqrtsp, 0x14, 0x0A, 0, PPC2_VSX)
8065 GEN_VSX_HELPER_2(xvmaddasp, 0x04, 0x08, 0, PPC2_VSX)
8066 GEN_VSX_HELPER_2(xvmaddmsp, 0x04, 0x09, 0, PPC2_VSX)
8067 GEN_VSX_HELPER_2(xvmsubasp, 0x04, 0x0A, 0, PPC2_VSX)
8068 GEN_VSX_HELPER_2(xvmsubmsp, 0x04, 0x0B, 0, PPC2_VSX)
8069 GEN_VSX_HELPER_2(xvnmaddasp, 0x04, 0x18, 0, PPC2_VSX)
8070 GEN_VSX_HELPER_2(xvnmaddmsp, 0x04, 0x19, 0, PPC2_VSX)
8071 GEN_VSX_HELPER_2(xvnmsubasp, 0x04, 0x1A, 0, PPC2_VSX)
8072 GEN_VSX_HELPER_2(xvnmsubmsp, 0x04, 0x1B, 0, PPC2_VSX)
8073 GEN_VSX_HELPER_2(xvmaxsp, 0x00, 0x18, 0, PPC2_VSX)
8074 GEN_VSX_HELPER_2(xvminsp, 0x00, 0x19, 0, PPC2_VSX)
8075 GEN_VSX_HELPER_2(xvcmpeqsp, 0x0C, 0x08, 0, PPC2_VSX)
8076 GEN_VSX_HELPER_2(xvcmpgtsp, 0x0C, 0x09, 0, PPC2_VSX)
8077 GEN_VSX_HELPER_2(xvcmpgesp, 0x0C, 0x0A, 0, PPC2_VSX)
8078 GEN_VSX_HELPER_2(xvcvspdp, 0x12, 0x1C, 0, PPC2_VSX)
8079 GEN_VSX_HELPER_2(xvcvspsxds, 0x10, 0x19, 0, PPC2_VSX)
8080 GEN_VSX_HELPER_2(xvcvspsxws, 0x10, 0x09, 0, PPC2_VSX)
8081 GEN_VSX_HELPER_2(xvcvspuxds, 0x10, 0x18, 0, PPC2_VSX)
8082 GEN_VSX_HELPER_2(xvcvspuxws, 0x10, 0x08, 0, PPC2_VSX)
8083 GEN_VSX_HELPER_2(xvcvsxdsp, 0x10, 0x1B, 0, PPC2_VSX)
8084 GEN_VSX_HELPER_2(xvcvuxdsp, 0x10, 0x1A, 0, PPC2_VSX)
8085 GEN_VSX_HELPER_2(xvcvsxwsp, 0x10, 0x0B, 0, PPC2_VSX)
8086 GEN_VSX_HELPER_2(xvcvuxwsp, 0x10, 0x0A, 0, PPC2_VSX)
8087 GEN_VSX_HELPER_2(xvrspi, 0x12, 0x08, 0, PPC2_VSX)
8088 GEN_VSX_HELPER_2(xvrspic, 0x16, 0x0A, 0, PPC2_VSX)
8089 GEN_VSX_HELPER_2(xvrspim, 0x12, 0x0B, 0, PPC2_VSX)
8090 GEN_VSX_HELPER_2(xvrspip, 0x12, 0x0A, 0, PPC2_VSX)
8091 GEN_VSX_HELPER_2(xvrspiz, 0x12, 0x09, 0, PPC2_VSX)
8092
8093 #define VSX_LOGICAL(name, tcg_op)                                    \
8094 static void glue(gen_, name)(DisasContext * ctx)                     \
8095     {                                                                \
8096         if (unlikely(!ctx->vsx_enabled)) {                           \
8097             gen_exception(ctx, POWERPC_EXCP_VSXU);                   \
8098             return;                                                  \
8099         }                                                            \
8100         tcg_op(cpu_vsrh(xT(ctx->opcode)), cpu_vsrh(xA(ctx->opcode)), \
8101             cpu_vsrh(xB(ctx->opcode)));                              \
8102         tcg_op(cpu_vsrl(xT(ctx->opcode)), cpu_vsrl(xA(ctx->opcode)), \
8103             cpu_vsrl(xB(ctx->opcode)));                              \
8104     }
8105
8106 VSX_LOGICAL(xxland, tcg_gen_and_i64)
8107 VSX_LOGICAL(xxlandc, tcg_gen_andc_i64)
8108 VSX_LOGICAL(xxlor, tcg_gen_or_i64)
8109 VSX_LOGICAL(xxlxor, tcg_gen_xor_i64)
8110 VSX_LOGICAL(xxlnor, tcg_gen_nor_i64)
8111 VSX_LOGICAL(xxleqv, tcg_gen_eqv_i64)
8112 VSX_LOGICAL(xxlnand, tcg_gen_nand_i64)
8113 VSX_LOGICAL(xxlorc, tcg_gen_orc_i64)
8114
8115 #define VSX_XXMRG(name, high)                               \
8116 static void glue(gen_, name)(DisasContext * ctx)            \
8117     {                                                       \
8118         TCGv_i64 a0, a1, b0, b1;                            \
8119         if (unlikely(!ctx->vsx_enabled)) {                  \
8120             gen_exception(ctx, POWERPC_EXCP_VSXU);          \
8121             return;                                         \
8122         }                                                   \
8123         a0 = tcg_temp_new_i64();                            \
8124         a1 = tcg_temp_new_i64();                            \
8125         b0 = tcg_temp_new_i64();                            \
8126         b1 = tcg_temp_new_i64();                            \
8127         if (high) {                                         \
8128             tcg_gen_mov_i64(a0, cpu_vsrh(xA(ctx->opcode))); \
8129             tcg_gen_mov_i64(a1, cpu_vsrh(xA(ctx->opcode))); \
8130             tcg_gen_mov_i64(b0, cpu_vsrh(xB(ctx->opcode))); \
8131             tcg_gen_mov_i64(b1, cpu_vsrh(xB(ctx->opcode))); \
8132         } else {                                            \
8133             tcg_gen_mov_i64(a0, cpu_vsrl(xA(ctx->opcode))); \
8134             tcg_gen_mov_i64(a1, cpu_vsrl(xA(ctx->opcode))); \
8135             tcg_gen_mov_i64(b0, cpu_vsrl(xB(ctx->opcode))); \
8136             tcg_gen_mov_i64(b1, cpu_vsrl(xB(ctx->opcode))); \
8137         }                                                   \
8138         tcg_gen_shri_i64(a0, a0, 32);                       \
8139         tcg_gen_shri_i64(b0, b0, 32);                       \
8140         tcg_gen_deposit_i64(cpu_vsrh(xT(ctx->opcode)),      \
8141                             b0, a0, 32, 32);                \
8142         tcg_gen_deposit_i64(cpu_vsrl(xT(ctx->opcode)),      \
8143                             b1, a1, 32, 32);                \
8144         tcg_temp_free_i64(a0);                              \
8145         tcg_temp_free_i64(a1);                              \
8146         tcg_temp_free_i64(b0);                              \
8147         tcg_temp_free_i64(b1);                              \
8148     }
8149
8150 VSX_XXMRG(xxmrghw, 1)
8151 VSX_XXMRG(xxmrglw, 0)
8152
8153 static void gen_xxsel(DisasContext * ctx)
8154 {
8155     TCGv_i64 a, b, c;
8156     if (unlikely(!ctx->vsx_enabled)) {
8157         gen_exception(ctx, POWERPC_EXCP_VSXU);
8158         return;
8159     }
8160     a = tcg_temp_new_i64();
8161     b = tcg_temp_new_i64();
8162     c = tcg_temp_new_i64();
8163
8164     tcg_gen_mov_i64(a, cpu_vsrh(xA(ctx->opcode)));
8165     tcg_gen_mov_i64(b, cpu_vsrh(xB(ctx->opcode)));
8166     tcg_gen_mov_i64(c, cpu_vsrh(xC(ctx->opcode)));
8167
8168     tcg_gen_and_i64(b, b, c);
8169     tcg_gen_andc_i64(a, a, c);
8170     tcg_gen_or_i64(cpu_vsrh(xT(ctx->opcode)), a, b);
8171
8172     tcg_gen_mov_i64(a, cpu_vsrl(xA(ctx->opcode)));
8173     tcg_gen_mov_i64(b, cpu_vsrl(xB(ctx->opcode)));
8174     tcg_gen_mov_i64(c, cpu_vsrl(xC(ctx->opcode)));
8175
8176     tcg_gen_and_i64(b, b, c);
8177     tcg_gen_andc_i64(a, a, c);
8178     tcg_gen_or_i64(cpu_vsrl(xT(ctx->opcode)), a, b);
8179
8180     tcg_temp_free_i64(a);
8181     tcg_temp_free_i64(b);
8182     tcg_temp_free_i64(c);
8183 }
8184
8185 static void gen_xxspltw(DisasContext *ctx)
8186 {
8187     TCGv_i64 b, b2;
8188     TCGv_i64 vsr = (UIM(ctx->opcode) & 2) ?
8189                    cpu_vsrl(xB(ctx->opcode)) :
8190                    cpu_vsrh(xB(ctx->opcode));
8191
8192     if (unlikely(!ctx->vsx_enabled)) {
8193         gen_exception(ctx, POWERPC_EXCP_VSXU);
8194         return;
8195     }
8196
8197     b = tcg_temp_new_i64();
8198     b2 = tcg_temp_new_i64();
8199
8200     if (UIM(ctx->opcode) & 1) {
8201         tcg_gen_ext32u_i64(b, vsr);
8202     } else {
8203         tcg_gen_shri_i64(b, vsr, 32);
8204     }
8205
8206     tcg_gen_shli_i64(b2, b, 32);
8207     tcg_gen_or_i64(cpu_vsrh(xT(ctx->opcode)), b, b2);
8208     tcg_gen_mov_i64(cpu_vsrl(xT(ctx->opcode)), cpu_vsrh(xT(ctx->opcode)));
8209
8210     tcg_temp_free_i64(b);
8211     tcg_temp_free_i64(b2);
8212 }
8213
8214 static void gen_xxsldwi(DisasContext *ctx)
8215 {
8216     TCGv_i64 xth, xtl;
8217     if (unlikely(!ctx->vsx_enabled)) {
8218         gen_exception(ctx, POWERPC_EXCP_VSXU);
8219         return;
8220     }
8221     xth = tcg_temp_new_i64();
8222     xtl = tcg_temp_new_i64();
8223
8224     switch (SHW(ctx->opcode)) {
8225         case 0: {
8226             tcg_gen_mov_i64(xth, cpu_vsrh(xA(ctx->opcode)));
8227             tcg_gen_mov_i64(xtl, cpu_vsrl(xA(ctx->opcode)));
8228             break;
8229         }
8230         case 1: {
8231             TCGv_i64 t0 = tcg_temp_new_i64();
8232             tcg_gen_mov_i64(xth, cpu_vsrh(xA(ctx->opcode)));
8233             tcg_gen_shli_i64(xth, xth, 32);
8234             tcg_gen_mov_i64(t0, cpu_vsrl(xA(ctx->opcode)));
8235             tcg_gen_shri_i64(t0, t0, 32);
8236             tcg_gen_or_i64(xth, xth, t0);
8237             tcg_gen_mov_i64(xtl, cpu_vsrl(xA(ctx->opcode)));
8238             tcg_gen_shli_i64(xtl, xtl, 32);
8239             tcg_gen_mov_i64(t0, cpu_vsrh(xB(ctx->opcode)));
8240             tcg_gen_shri_i64(t0, t0, 32);
8241             tcg_gen_or_i64(xtl, xtl, t0);
8242             tcg_temp_free_i64(t0);
8243             break;
8244         }
8245         case 2: {
8246             tcg_gen_mov_i64(xth, cpu_vsrl(xA(ctx->opcode)));
8247             tcg_gen_mov_i64(xtl, cpu_vsrh(xB(ctx->opcode)));
8248             break;
8249         }
8250         case 3: {
8251             TCGv_i64 t0 = tcg_temp_new_i64();
8252             tcg_gen_mov_i64(xth, cpu_vsrl(xA(ctx->opcode)));
8253             tcg_gen_shli_i64(xth, xth, 32);
8254             tcg_gen_mov_i64(t0, cpu_vsrh(xB(ctx->opcode)));
8255             tcg_gen_shri_i64(t0, t0, 32);
8256             tcg_gen_or_i64(xth, xth, t0);
8257             tcg_gen_mov_i64(xtl, cpu_vsrh(xB(ctx->opcode)));
8258             tcg_gen_shli_i64(xtl, xtl, 32);
8259             tcg_gen_mov_i64(t0, cpu_vsrl(xB(ctx->opcode)));
8260             tcg_gen_shri_i64(t0, t0, 32);
8261             tcg_gen_or_i64(xtl, xtl, t0);
8262             tcg_temp_free_i64(t0);
8263             break;
8264         }
8265     }
8266
8267     tcg_gen_mov_i64(cpu_vsrh(xT(ctx->opcode)), xth);
8268     tcg_gen_mov_i64(cpu_vsrl(xT(ctx->opcode)), xtl);
8269
8270     tcg_temp_free_i64(xth);
8271     tcg_temp_free_i64(xtl);
8272 }
8273
8274 /*** Decimal Floating Point ***/
8275
8276 static inline TCGv_ptr gen_fprp_ptr(int reg)
8277 {
8278     TCGv_ptr r = tcg_temp_new_ptr();
8279     tcg_gen_addi_ptr(r, cpu_env, offsetof(CPUPPCState, fpr[reg]));
8280     return r;
8281 }
8282
8283 #define GEN_DFP_T_A_B_Rc(name)                   \
8284 static void gen_##name(DisasContext *ctx)        \
8285 {                                                \
8286     TCGv_ptr rd, ra, rb;                         \
8287     if (unlikely(!ctx->fpu_enabled)) {           \
8288         gen_exception(ctx, POWERPC_EXCP_FPU);    \
8289         return;                                  \
8290     }                                            \
8291     gen_update_nip(ctx, ctx->nip - 4);           \
8292     rd = gen_fprp_ptr(rD(ctx->opcode));          \
8293     ra = gen_fprp_ptr(rA(ctx->opcode));          \
8294     rb = gen_fprp_ptr(rB(ctx->opcode));          \
8295     gen_helper_##name(cpu_env, rd, ra, rb);      \
8296     if (unlikely(Rc(ctx->opcode) != 0)) {        \
8297         gen_set_cr1_from_fpscr(ctx);             \
8298     }                                            \
8299     tcg_temp_free_ptr(rd);                       \
8300     tcg_temp_free_ptr(ra);                       \
8301     tcg_temp_free_ptr(rb);                       \
8302 }
8303
8304 #define GEN_DFP_BF_A_B(name)                      \
8305 static void gen_##name(DisasContext *ctx)         \
8306 {                                                 \
8307     TCGv_ptr ra, rb;                              \
8308     if (unlikely(!ctx->fpu_enabled)) {            \
8309         gen_exception(ctx, POWERPC_EXCP_FPU);     \
8310         return;                                   \
8311     }                                             \
8312     gen_update_nip(ctx, ctx->nip - 4);            \
8313     ra = gen_fprp_ptr(rA(ctx->opcode));           \
8314     rb = gen_fprp_ptr(rB(ctx->opcode));           \
8315     gen_helper_##name(cpu_crf[crfD(ctx->opcode)], \
8316                       cpu_env, ra, rb);           \
8317     tcg_temp_free_ptr(ra);                        \
8318     tcg_temp_free_ptr(rb);                        \
8319 }
8320
8321 #define GEN_DFP_BF_A_DCM(name)                    \
8322 static void gen_##name(DisasContext *ctx)         \
8323 {                                                 \
8324     TCGv_ptr ra;                                  \
8325     TCGv_i32 dcm;                                 \
8326     if (unlikely(!ctx->fpu_enabled)) {            \
8327         gen_exception(ctx, POWERPC_EXCP_FPU);     \
8328         return;                                   \
8329     }                                             \
8330     gen_update_nip(ctx, ctx->nip - 4);            \
8331     ra = gen_fprp_ptr(rA(ctx->opcode));           \
8332     dcm = tcg_const_i32(DCM(ctx->opcode));        \
8333     gen_helper_##name(cpu_crf[crfD(ctx->opcode)], \
8334                       cpu_env, ra, dcm);          \
8335     tcg_temp_free_ptr(ra);                        \
8336     tcg_temp_free_i32(dcm);                       \
8337 }
8338
8339 #define GEN_DFP_T_B_U32_U32_Rc(name, u32f1, u32f2)    \
8340 static void gen_##name(DisasContext *ctx)             \
8341 {                                                     \
8342     TCGv_ptr rt, rb;                                  \
8343     TCGv_i32 u32_1, u32_2;                            \
8344     if (unlikely(!ctx->fpu_enabled)) {                \
8345         gen_exception(ctx, POWERPC_EXCP_FPU);         \
8346         return;                                       \
8347     }                                                 \
8348     gen_update_nip(ctx, ctx->nip - 4);                \
8349     rt = gen_fprp_ptr(rD(ctx->opcode));               \
8350     rb = gen_fprp_ptr(rB(ctx->opcode));               \
8351     u32_1 = tcg_const_i32(u32f1(ctx->opcode));        \
8352     u32_2 = tcg_const_i32(u32f2(ctx->opcode));        \
8353     gen_helper_##name(cpu_env, rt, rb, u32_1, u32_2); \
8354     if (unlikely(Rc(ctx->opcode) != 0)) {             \
8355         gen_set_cr1_from_fpscr(ctx);                  \
8356     }                                                 \
8357     tcg_temp_free_ptr(rt);                            \
8358     tcg_temp_free_ptr(rb);                            \
8359     tcg_temp_free_i32(u32_1);                         \
8360     tcg_temp_free_i32(u32_2);                         \
8361 }
8362
8363 #define GEN_DFP_T_A_B_I32_Rc(name, i32fld)       \
8364 static void gen_##name(DisasContext *ctx)        \
8365 {                                                \
8366     TCGv_ptr rt, ra, rb;                         \
8367     TCGv_i32 i32;                                \
8368     if (unlikely(!ctx->fpu_enabled)) {           \
8369         gen_exception(ctx, POWERPC_EXCP_FPU);    \
8370         return;                                  \
8371     }                                            \
8372     gen_update_nip(ctx, ctx->nip - 4);           \
8373     rt = gen_fprp_ptr(rD(ctx->opcode));          \
8374     ra = gen_fprp_ptr(rA(ctx->opcode));          \
8375     rb = gen_fprp_ptr(rB(ctx->opcode));          \
8376     i32 = tcg_const_i32(i32fld(ctx->opcode));    \
8377     gen_helper_##name(cpu_env, rt, ra, rb, i32); \
8378     if (unlikely(Rc(ctx->opcode) != 0)) {        \
8379         gen_set_cr1_from_fpscr(ctx);             \
8380     }                                            \
8381     tcg_temp_free_ptr(rt);                       \
8382     tcg_temp_free_ptr(rb);                       \
8383     tcg_temp_free_ptr(ra);                       \
8384     tcg_temp_free_i32(i32);                      \
8385     }
8386
8387 #define GEN_DFP_T_B_Rc(name)                     \
8388 static void gen_##name(DisasContext *ctx)        \
8389 {                                                \
8390     TCGv_ptr rt, rb;                             \
8391     if (unlikely(!ctx->fpu_enabled)) {           \
8392         gen_exception(ctx, POWERPC_EXCP_FPU);    \
8393         return;                                  \
8394     }                                            \
8395     gen_update_nip(ctx, ctx->nip - 4);           \
8396     rt = gen_fprp_ptr(rD(ctx->opcode));          \
8397     rb = gen_fprp_ptr(rB(ctx->opcode));          \
8398     gen_helper_##name(cpu_env, rt, rb);          \
8399     if (unlikely(Rc(ctx->opcode) != 0)) {        \
8400         gen_set_cr1_from_fpscr(ctx);             \
8401     }                                            \
8402     tcg_temp_free_ptr(rt);                       \
8403     tcg_temp_free_ptr(rb);                       \
8404     }
8405
8406 #define GEN_DFP_T_FPR_I32_Rc(name, fprfld, i32fld) \
8407 static void gen_##name(DisasContext *ctx)          \
8408 {                                                  \
8409     TCGv_ptr rt, rs;                               \
8410     TCGv_i32 i32;                                  \
8411     if (unlikely(!ctx->fpu_enabled)) {             \
8412         gen_exception(ctx, POWERPC_EXCP_FPU);      \
8413         return;                                    \
8414     }                                              \
8415     gen_update_nip(ctx, ctx->nip - 4);             \
8416     rt = gen_fprp_ptr(rD(ctx->opcode));            \
8417     rs = gen_fprp_ptr(fprfld(ctx->opcode));        \
8418     i32 = tcg_const_i32(i32fld(ctx->opcode));      \
8419     gen_helper_##name(cpu_env, rt, rs, i32);       \
8420     if (unlikely(Rc(ctx->opcode) != 0)) {          \
8421         gen_set_cr1_from_fpscr(ctx);               \
8422     }                                              \
8423     tcg_temp_free_ptr(rt);                         \
8424     tcg_temp_free_ptr(rs);                         \
8425     tcg_temp_free_i32(i32);                        \
8426 }
8427
8428 GEN_DFP_T_A_B_Rc(dadd)
8429 GEN_DFP_T_A_B_Rc(daddq)
8430 GEN_DFP_T_A_B_Rc(dsub)
8431 GEN_DFP_T_A_B_Rc(dsubq)
8432 GEN_DFP_T_A_B_Rc(dmul)
8433 GEN_DFP_T_A_B_Rc(dmulq)
8434 GEN_DFP_T_A_B_Rc(ddiv)
8435 GEN_DFP_T_A_B_Rc(ddivq)
8436 GEN_DFP_BF_A_B(dcmpu)
8437 GEN_DFP_BF_A_B(dcmpuq)
8438 GEN_DFP_BF_A_B(dcmpo)
8439 GEN_DFP_BF_A_B(dcmpoq)
8440 GEN_DFP_BF_A_DCM(dtstdc)
8441 GEN_DFP_BF_A_DCM(dtstdcq)
8442 GEN_DFP_BF_A_DCM(dtstdg)
8443 GEN_DFP_BF_A_DCM(dtstdgq)
8444 GEN_DFP_BF_A_B(dtstex)
8445 GEN_DFP_BF_A_B(dtstexq)
8446 GEN_DFP_BF_A_B(dtstsf)
8447 GEN_DFP_BF_A_B(dtstsfq)
8448 GEN_DFP_T_B_U32_U32_Rc(dquai, SIMM5, RMC)
8449 GEN_DFP_T_B_U32_U32_Rc(dquaiq, SIMM5, RMC)
8450 GEN_DFP_T_A_B_I32_Rc(dqua, RMC)
8451 GEN_DFP_T_A_B_I32_Rc(dquaq, RMC)
8452 GEN_DFP_T_A_B_I32_Rc(drrnd, RMC)
8453 GEN_DFP_T_A_B_I32_Rc(drrndq, RMC)
8454 GEN_DFP_T_B_U32_U32_Rc(drintx, FPW, RMC)
8455 GEN_DFP_T_B_U32_U32_Rc(drintxq, FPW, RMC)
8456 GEN_DFP_T_B_U32_U32_Rc(drintn, FPW, RMC)
8457 GEN_DFP_T_B_U32_U32_Rc(drintnq, FPW, RMC)
8458 GEN_DFP_T_B_Rc(dctdp)
8459 GEN_DFP_T_B_Rc(dctqpq)
8460 GEN_DFP_T_B_Rc(drsp)
8461 GEN_DFP_T_B_Rc(drdpq)
8462 GEN_DFP_T_B_Rc(dcffix)
8463 GEN_DFP_T_B_Rc(dcffixq)
8464 GEN_DFP_T_B_Rc(dctfix)
8465 GEN_DFP_T_B_Rc(dctfixq)
8466 GEN_DFP_T_FPR_I32_Rc(ddedpd, rB, SP)
8467 GEN_DFP_T_FPR_I32_Rc(ddedpdq, rB, SP)
8468 GEN_DFP_T_FPR_I32_Rc(denbcd, rB, SP)
8469 GEN_DFP_T_FPR_I32_Rc(denbcdq, rB, SP)
8470 GEN_DFP_T_B_Rc(dxex)
8471 GEN_DFP_T_B_Rc(dxexq)
8472 GEN_DFP_T_A_B_Rc(diex)
8473 GEN_DFP_T_A_B_Rc(diexq)
8474 GEN_DFP_T_FPR_I32_Rc(dscli, rA, DCM)
8475 GEN_DFP_T_FPR_I32_Rc(dscliq, rA, DCM)
8476 GEN_DFP_T_FPR_I32_Rc(dscri, rA, DCM)
8477 GEN_DFP_T_FPR_I32_Rc(dscriq, rA, DCM)
8478
8479 /***                           SPE extension                               ***/
8480 /* Register moves */
8481
8482 static inline void gen_evmra(DisasContext *ctx)
8483 {
8484
8485     if (unlikely(!ctx->spe_enabled)) {
8486         gen_exception(ctx, POWERPC_EXCP_SPEU);
8487         return;
8488     }
8489
8490     TCGv_i64 tmp = tcg_temp_new_i64();
8491
8492     /* tmp := rA_lo + rA_hi << 32 */
8493     tcg_gen_concat_tl_i64(tmp, cpu_gpr[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
8494
8495     /* spe_acc := tmp */
8496     tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUPPCState, spe_acc));
8497     tcg_temp_free_i64(tmp);
8498
8499     /* rD := rA */
8500     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
8501     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
8502 }
8503
8504 static inline void gen_load_gpr64(TCGv_i64 t, int reg)
8505 {
8506     tcg_gen_concat_tl_i64(t, cpu_gpr[reg], cpu_gprh[reg]);
8507 }
8508
8509 static inline void gen_store_gpr64(int reg, TCGv_i64 t)
8510 {
8511     tcg_gen_extr_i64_tl(cpu_gpr[reg], cpu_gprh[reg], t);
8512 }
8513
8514 #define GEN_SPE(name0, name1, opc2, opc3, inval0, inval1, type)         \
8515 static void glue(gen_, name0##_##name1)(DisasContext *ctx)                    \
8516 {                                                                             \
8517     if (Rc(ctx->opcode))                                                      \
8518         gen_##name1(ctx);                                                     \
8519     else                                                                      \
8520         gen_##name0(ctx);                                                     \
8521 }
8522
8523 /* Handler for undefined SPE opcodes */
8524 static inline void gen_speundef(DisasContext *ctx)
8525 {
8526     gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
8527 }
8528
8529 /* SPE logic */
8530 #define GEN_SPEOP_LOGIC2(name, tcg_op)                                        \
8531 static inline void gen_##name(DisasContext *ctx)                              \
8532 {                                                                             \
8533     if (unlikely(!ctx->spe_enabled)) {                                        \
8534         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
8535         return;                                                               \
8536     }                                                                         \
8537     tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],                \
8538            cpu_gpr[rB(ctx->opcode)]);                                         \
8539     tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],              \
8540            cpu_gprh[rB(ctx->opcode)]);                                        \
8541 }
8542
8543 GEN_SPEOP_LOGIC2(evand, tcg_gen_and_tl);
8544 GEN_SPEOP_LOGIC2(evandc, tcg_gen_andc_tl);
8545 GEN_SPEOP_LOGIC2(evxor, tcg_gen_xor_tl);
8546 GEN_SPEOP_LOGIC2(evor, tcg_gen_or_tl);
8547 GEN_SPEOP_LOGIC2(evnor, tcg_gen_nor_tl);
8548 GEN_SPEOP_LOGIC2(eveqv, tcg_gen_eqv_tl);
8549 GEN_SPEOP_LOGIC2(evorc, tcg_gen_orc_tl);
8550 GEN_SPEOP_LOGIC2(evnand, tcg_gen_nand_tl);
8551
8552 /* SPE logic immediate */
8553 #define GEN_SPEOP_TCG_LOGIC_IMM2(name, tcg_opi)                               \
8554 static inline void gen_##name(DisasContext *ctx)                              \
8555 {                                                                             \
8556     TCGv_i32 t0;                                                              \
8557     if (unlikely(!ctx->spe_enabled)) {                                        \
8558         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
8559         return;                                                               \
8560     }                                                                         \
8561     t0 = tcg_temp_new_i32();                                                  \
8562                                                                               \
8563     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);                       \
8564     tcg_opi(t0, t0, rB(ctx->opcode));                                         \
8565     tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0);                        \
8566                                                                               \
8567     tcg_gen_trunc_tl_i32(t0, cpu_gprh[rA(ctx->opcode)]);                      \
8568     tcg_opi(t0, t0, rB(ctx->opcode));                                         \
8569     tcg_gen_extu_i32_tl(cpu_gprh[rD(ctx->opcode)], t0);                       \
8570                                                                               \
8571     tcg_temp_free_i32(t0);                                                    \
8572 }
8573 GEN_SPEOP_TCG_LOGIC_IMM2(evslwi, tcg_gen_shli_i32);
8574 GEN_SPEOP_TCG_LOGIC_IMM2(evsrwiu, tcg_gen_shri_i32);
8575 GEN_SPEOP_TCG_LOGIC_IMM2(evsrwis, tcg_gen_sari_i32);
8576 GEN_SPEOP_TCG_LOGIC_IMM2(evrlwi, tcg_gen_rotli_i32);
8577
8578 /* SPE arithmetic */
8579 #define GEN_SPEOP_ARITH1(name, tcg_op)                                        \
8580 static inline void gen_##name(DisasContext *ctx)                              \
8581 {                                                                             \
8582     TCGv_i32 t0;                                                              \
8583     if (unlikely(!ctx->spe_enabled)) {                                        \
8584         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
8585         return;                                                               \
8586     }                                                                         \
8587     t0 = tcg_temp_new_i32();                                                  \
8588                                                                               \
8589     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);                       \
8590     tcg_op(t0, t0);                                                           \
8591     tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0);                        \
8592                                                                               \
8593     tcg_gen_trunc_tl_i32(t0, cpu_gprh[rA(ctx->opcode)]);                      \
8594     tcg_op(t0, t0);                                                           \
8595     tcg_gen_extu_i32_tl(cpu_gprh[rD(ctx->opcode)], t0);                       \
8596                                                                               \
8597     tcg_temp_free_i32(t0);                                                    \
8598 }
8599
8600 static inline void gen_op_evabs(TCGv_i32 ret, TCGv_i32 arg1)
8601 {
8602     TCGLabel *l1 = gen_new_label();
8603     TCGLabel *l2 = gen_new_label();
8604
8605     tcg_gen_brcondi_i32(TCG_COND_GE, arg1, 0, l1);
8606     tcg_gen_neg_i32(ret, arg1);
8607     tcg_gen_br(l2);
8608     gen_set_label(l1);
8609     tcg_gen_mov_i32(ret, arg1);
8610     gen_set_label(l2);
8611 }
8612 GEN_SPEOP_ARITH1(evabs, gen_op_evabs);
8613 GEN_SPEOP_ARITH1(evneg, tcg_gen_neg_i32);
8614 GEN_SPEOP_ARITH1(evextsb, tcg_gen_ext8s_i32);
8615 GEN_SPEOP_ARITH1(evextsh, tcg_gen_ext16s_i32);
8616 static inline void gen_op_evrndw(TCGv_i32 ret, TCGv_i32 arg1)
8617 {
8618     tcg_gen_addi_i32(ret, arg1, 0x8000);
8619     tcg_gen_ext16u_i32(ret, ret);
8620 }
8621 GEN_SPEOP_ARITH1(evrndw, gen_op_evrndw);
8622 GEN_SPEOP_ARITH1(evcntlsw, gen_helper_cntlsw32);
8623 GEN_SPEOP_ARITH1(evcntlzw, gen_helper_cntlzw32);
8624
8625 #define GEN_SPEOP_ARITH2(name, tcg_op)                                        \
8626 static inline void gen_##name(DisasContext *ctx)                              \
8627 {                                                                             \
8628     TCGv_i32 t0, t1;                                                          \
8629     if (unlikely(!ctx->spe_enabled)) {                                        \
8630         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
8631         return;                                                               \
8632     }                                                                         \
8633     t0 = tcg_temp_new_i32();                                                  \
8634     t1 = tcg_temp_new_i32();                                                  \
8635                                                                               \
8636     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);                       \
8637     tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);                       \
8638     tcg_op(t0, t0, t1);                                                       \
8639     tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0);                        \
8640                                                                               \
8641     tcg_gen_trunc_tl_i32(t0, cpu_gprh[rA(ctx->opcode)]);                      \
8642     tcg_gen_trunc_tl_i32(t1, cpu_gprh[rB(ctx->opcode)]);                      \
8643     tcg_op(t0, t0, t1);                                                       \
8644     tcg_gen_extu_i32_tl(cpu_gprh[rD(ctx->opcode)], t0);                       \
8645                                                                               \
8646     tcg_temp_free_i32(t0);                                                    \
8647     tcg_temp_free_i32(t1);                                                    \
8648 }
8649
8650 static inline void gen_op_evsrwu(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
8651 {
8652     TCGLabel *l1 = gen_new_label();
8653     TCGLabel *l2 = gen_new_label();
8654     TCGv_i32 t0 = tcg_temp_local_new_i32();
8655
8656     /* No error here: 6 bits are used */
8657     tcg_gen_andi_i32(t0, arg2, 0x3F);
8658     tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1);
8659     tcg_gen_shr_i32(ret, arg1, t0);
8660     tcg_gen_br(l2);
8661     gen_set_label(l1);
8662     tcg_gen_movi_i32(ret, 0);
8663     gen_set_label(l2);
8664     tcg_temp_free_i32(t0);
8665 }
8666 GEN_SPEOP_ARITH2(evsrwu, gen_op_evsrwu);
8667 static inline void gen_op_evsrws(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
8668 {
8669     TCGLabel *l1 = gen_new_label();
8670     TCGLabel *l2 = gen_new_label();
8671     TCGv_i32 t0 = tcg_temp_local_new_i32();
8672
8673     /* No error here: 6 bits are used */
8674     tcg_gen_andi_i32(t0, arg2, 0x3F);
8675     tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1);
8676     tcg_gen_sar_i32(ret, arg1, t0);
8677     tcg_gen_br(l2);
8678     gen_set_label(l1);
8679     tcg_gen_movi_i32(ret, 0);
8680     gen_set_label(l2);
8681     tcg_temp_free_i32(t0);
8682 }
8683 GEN_SPEOP_ARITH2(evsrws, gen_op_evsrws);
8684 static inline void gen_op_evslw(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
8685 {
8686     TCGLabel *l1 = gen_new_label();
8687     TCGLabel *l2 = gen_new_label();
8688     TCGv_i32 t0 = tcg_temp_local_new_i32();
8689
8690     /* No error here: 6 bits are used */
8691     tcg_gen_andi_i32(t0, arg2, 0x3F);
8692     tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1);
8693     tcg_gen_shl_i32(ret, arg1, t0);
8694     tcg_gen_br(l2);
8695     gen_set_label(l1);
8696     tcg_gen_movi_i32(ret, 0);
8697     gen_set_label(l2);
8698     tcg_temp_free_i32(t0);
8699 }
8700 GEN_SPEOP_ARITH2(evslw, gen_op_evslw);
8701 static inline void gen_op_evrlw(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
8702 {
8703     TCGv_i32 t0 = tcg_temp_new_i32();
8704     tcg_gen_andi_i32(t0, arg2, 0x1F);
8705     tcg_gen_rotl_i32(ret, arg1, t0);
8706     tcg_temp_free_i32(t0);
8707 }
8708 GEN_SPEOP_ARITH2(evrlw, gen_op_evrlw);
8709 static inline void gen_evmergehi(DisasContext *ctx)
8710 {
8711     if (unlikely(!ctx->spe_enabled)) {
8712         gen_exception(ctx, POWERPC_EXCP_SPEU);
8713         return;
8714     }
8715     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
8716     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
8717 }
8718 GEN_SPEOP_ARITH2(evaddw, tcg_gen_add_i32);
8719 static inline void gen_op_evsubf(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
8720 {
8721     tcg_gen_sub_i32(ret, arg2, arg1);
8722 }
8723 GEN_SPEOP_ARITH2(evsubfw, gen_op_evsubf);
8724
8725 /* SPE arithmetic immediate */
8726 #define GEN_SPEOP_ARITH_IMM2(name, tcg_op)                                    \
8727 static inline void gen_##name(DisasContext *ctx)                              \
8728 {                                                                             \
8729     TCGv_i32 t0;                                                              \
8730     if (unlikely(!ctx->spe_enabled)) {                                        \
8731         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
8732         return;                                                               \
8733     }                                                                         \
8734     t0 = tcg_temp_new_i32();                                                  \
8735                                                                               \
8736     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rB(ctx->opcode)]);                       \
8737     tcg_op(t0, t0, rA(ctx->opcode));                                          \
8738     tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0);                        \
8739                                                                               \
8740     tcg_gen_trunc_tl_i32(t0, cpu_gprh[rB(ctx->opcode)]);                      \
8741     tcg_op(t0, t0, rA(ctx->opcode));                                          \
8742     tcg_gen_extu_i32_tl(cpu_gprh[rD(ctx->opcode)], t0);                       \
8743                                                                               \
8744     tcg_temp_free_i32(t0);                                                    \
8745 }
8746 GEN_SPEOP_ARITH_IMM2(evaddiw, tcg_gen_addi_i32);
8747 GEN_SPEOP_ARITH_IMM2(evsubifw, tcg_gen_subi_i32);
8748
8749 /* SPE comparison */
8750 #define GEN_SPEOP_COMP(name, tcg_cond)                                        \
8751 static inline void gen_##name(DisasContext *ctx)                              \
8752 {                                                                             \
8753     if (unlikely(!ctx->spe_enabled)) {                                        \
8754         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
8755         return;                                                               \
8756     }                                                                         \
8757     TCGLabel *l1 = gen_new_label();                                           \
8758     TCGLabel *l2 = gen_new_label();                                           \
8759     TCGLabel *l3 = gen_new_label();                                           \
8760     TCGLabel *l4 = gen_new_label();                                           \
8761                                                                               \
8762     tcg_gen_ext32s_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);    \
8763     tcg_gen_ext32s_tl(cpu_gpr[rB(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
8764     tcg_gen_ext32s_tl(cpu_gprh[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);  \
8765     tcg_gen_ext32s_tl(cpu_gprh[rB(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);  \
8766                                                                               \
8767     tcg_gen_brcond_tl(tcg_cond, cpu_gpr[rA(ctx->opcode)],                     \
8768                        cpu_gpr[rB(ctx->opcode)], l1);                         \
8769     tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)], 0);                          \
8770     tcg_gen_br(l2);                                                           \
8771     gen_set_label(l1);                                                        \
8772     tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)],                              \
8773                      CRF_CL | CRF_CH_OR_CL | CRF_CH_AND_CL);                  \
8774     gen_set_label(l2);                                                        \
8775     tcg_gen_brcond_tl(tcg_cond, cpu_gprh[rA(ctx->opcode)],                    \
8776                        cpu_gprh[rB(ctx->opcode)], l3);                        \
8777     tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)],  \
8778                      ~(CRF_CH | CRF_CH_AND_CL));                              \
8779     tcg_gen_br(l4);                                                           \
8780     gen_set_label(l3);                                                        \
8781     tcg_gen_ori_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)],   \
8782                     CRF_CH | CRF_CH_OR_CL);                                   \
8783     gen_set_label(l4);                                                        \
8784 }
8785 GEN_SPEOP_COMP(evcmpgtu, TCG_COND_GTU);
8786 GEN_SPEOP_COMP(evcmpgts, TCG_COND_GT);
8787 GEN_SPEOP_COMP(evcmpltu, TCG_COND_LTU);
8788 GEN_SPEOP_COMP(evcmplts, TCG_COND_LT);
8789 GEN_SPEOP_COMP(evcmpeq, TCG_COND_EQ);
8790
8791 /* SPE misc */
8792 static inline void gen_brinc(DisasContext *ctx)
8793 {
8794     /* Note: brinc is usable even if SPE is disabled */
8795     gen_helper_brinc(cpu_gpr[rD(ctx->opcode)],
8796                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
8797 }
8798 static inline void gen_evmergelo(DisasContext *ctx)
8799 {
8800     if (unlikely(!ctx->spe_enabled)) {
8801         gen_exception(ctx, POWERPC_EXCP_SPEU);
8802         return;
8803     }
8804     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
8805     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
8806 }
8807 static inline void gen_evmergehilo(DisasContext *ctx)
8808 {
8809     if (unlikely(!ctx->spe_enabled)) {
8810         gen_exception(ctx, POWERPC_EXCP_SPEU);
8811         return;
8812     }
8813     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
8814     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
8815 }
8816 static inline void gen_evmergelohi(DisasContext *ctx)
8817 {
8818     if (unlikely(!ctx->spe_enabled)) {
8819         gen_exception(ctx, POWERPC_EXCP_SPEU);
8820         return;
8821     }
8822     if (rD(ctx->opcode) == rA(ctx->opcode)) {
8823         TCGv tmp = tcg_temp_new();
8824         tcg_gen_mov_tl(tmp, cpu_gpr[rA(ctx->opcode)]);
8825         tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
8826         tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], tmp);
8827         tcg_temp_free(tmp);
8828     } else {
8829         tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
8830         tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
8831     }
8832 }
8833 static inline void gen_evsplati(DisasContext *ctx)
8834 {
8835     uint64_t imm = ((int32_t)(rA(ctx->opcode) << 27)) >> 27;
8836
8837     tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], imm);
8838     tcg_gen_movi_tl(cpu_gprh[rD(ctx->opcode)], imm);
8839 }
8840 static inline void gen_evsplatfi(DisasContext *ctx)
8841 {
8842     uint64_t imm = rA(ctx->opcode) << 27;
8843
8844     tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], imm);
8845     tcg_gen_movi_tl(cpu_gprh[rD(ctx->opcode)], imm);
8846 }
8847
8848 static inline void gen_evsel(DisasContext *ctx)
8849 {
8850     TCGLabel *l1 = gen_new_label();
8851     TCGLabel *l2 = gen_new_label();
8852     TCGLabel *l3 = gen_new_label();
8853     TCGLabel *l4 = gen_new_label();
8854     TCGv_i32 t0 = tcg_temp_local_new_i32();
8855
8856     tcg_gen_andi_i32(t0, cpu_crf[ctx->opcode & 0x07], 1 << 3);
8857     tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
8858     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
8859     tcg_gen_br(l2);
8860     gen_set_label(l1);
8861     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
8862     gen_set_label(l2);
8863     tcg_gen_andi_i32(t0, cpu_crf[ctx->opcode & 0x07], 1 << 2);
8864     tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l3);
8865     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
8866     tcg_gen_br(l4);
8867     gen_set_label(l3);
8868     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
8869     gen_set_label(l4);
8870     tcg_temp_free_i32(t0);
8871 }
8872
8873 static void gen_evsel0(DisasContext *ctx)
8874 {
8875     gen_evsel(ctx);
8876 }
8877
8878 static void gen_evsel1(DisasContext *ctx)
8879 {
8880     gen_evsel(ctx);
8881 }
8882
8883 static void gen_evsel2(DisasContext *ctx)
8884 {
8885     gen_evsel(ctx);
8886 }
8887
8888 static void gen_evsel3(DisasContext *ctx)
8889 {
8890     gen_evsel(ctx);
8891 }
8892
8893 /* Multiply */
8894
8895 static inline void gen_evmwumi(DisasContext *ctx)
8896 {
8897     TCGv_i64 t0, t1;
8898
8899     if (unlikely(!ctx->spe_enabled)) {
8900         gen_exception(ctx, POWERPC_EXCP_SPEU);
8901         return;
8902     }
8903
8904     t0 = tcg_temp_new_i64();
8905     t1 = tcg_temp_new_i64();
8906
8907     /* t0 := rA; t1 := rB */
8908     tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
8909     tcg_gen_ext32u_i64(t0, t0);
8910     tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
8911     tcg_gen_ext32u_i64(t1, t1);
8912
8913     tcg_gen_mul_i64(t0, t0, t1);  /* t0 := rA * rB */
8914
8915     gen_store_gpr64(rD(ctx->opcode), t0); /* rD := t0 */
8916
8917     tcg_temp_free_i64(t0);
8918     tcg_temp_free_i64(t1);
8919 }
8920
8921 static inline void gen_evmwumia(DisasContext *ctx)
8922 {
8923     TCGv_i64 tmp;
8924
8925     if (unlikely(!ctx->spe_enabled)) {
8926         gen_exception(ctx, POWERPC_EXCP_SPEU);
8927         return;
8928     }
8929
8930     gen_evmwumi(ctx);            /* rD := rA * rB */
8931
8932     tmp = tcg_temp_new_i64();
8933
8934     /* acc := rD */
8935     gen_load_gpr64(tmp, rD(ctx->opcode));
8936     tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUPPCState, spe_acc));
8937     tcg_temp_free_i64(tmp);
8938 }
8939
8940 static inline void gen_evmwumiaa(DisasContext *ctx)
8941 {
8942     TCGv_i64 acc;
8943     TCGv_i64 tmp;
8944
8945     if (unlikely(!ctx->spe_enabled)) {
8946         gen_exception(ctx, POWERPC_EXCP_SPEU);
8947         return;
8948     }
8949
8950     gen_evmwumi(ctx);           /* rD := rA * rB */
8951
8952     acc = tcg_temp_new_i64();
8953     tmp = tcg_temp_new_i64();
8954
8955     /* tmp := rD */
8956     gen_load_gpr64(tmp, rD(ctx->opcode));
8957
8958     /* Load acc */
8959     tcg_gen_ld_i64(acc, cpu_env, offsetof(CPUPPCState, spe_acc));
8960
8961     /* acc := tmp + acc */
8962     tcg_gen_add_i64(acc, acc, tmp);
8963
8964     /* Store acc */
8965     tcg_gen_st_i64(acc, cpu_env, offsetof(CPUPPCState, spe_acc));
8966
8967     /* rD := acc */
8968     gen_store_gpr64(rD(ctx->opcode), acc);
8969
8970     tcg_temp_free_i64(acc);
8971     tcg_temp_free_i64(tmp);
8972 }
8973
8974 static inline void gen_evmwsmi(DisasContext *ctx)
8975 {
8976     TCGv_i64 t0, t1;
8977
8978     if (unlikely(!ctx->spe_enabled)) {
8979         gen_exception(ctx, POWERPC_EXCP_SPEU);
8980         return;
8981     }
8982
8983     t0 = tcg_temp_new_i64();
8984     t1 = tcg_temp_new_i64();
8985
8986     /* t0 := rA; t1 := rB */
8987     tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
8988     tcg_gen_ext32s_i64(t0, t0);
8989     tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
8990     tcg_gen_ext32s_i64(t1, t1);
8991
8992     tcg_gen_mul_i64(t0, t0, t1);  /* t0 := rA * rB */
8993
8994     gen_store_gpr64(rD(ctx->opcode), t0); /* rD := t0 */
8995
8996     tcg_temp_free_i64(t0);
8997     tcg_temp_free_i64(t1);
8998 }
8999
9000 static inline void gen_evmwsmia(DisasContext *ctx)
9001 {
9002     TCGv_i64 tmp;
9003
9004     gen_evmwsmi(ctx);            /* rD := rA * rB */
9005
9006     tmp = tcg_temp_new_i64();
9007
9008     /* acc := rD */
9009     gen_load_gpr64(tmp, rD(ctx->opcode));
9010     tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUPPCState, spe_acc));
9011
9012     tcg_temp_free_i64(tmp);
9013 }
9014
9015 static inline void gen_evmwsmiaa(DisasContext *ctx)
9016 {
9017     TCGv_i64 acc = tcg_temp_new_i64();
9018     TCGv_i64 tmp = tcg_temp_new_i64();
9019
9020     gen_evmwsmi(ctx);           /* rD := rA * rB */
9021
9022     acc = tcg_temp_new_i64();
9023     tmp = tcg_temp_new_i64();
9024
9025     /* tmp := rD */
9026     gen_load_gpr64(tmp, rD(ctx->opcode));
9027
9028     /* Load acc */
9029     tcg_gen_ld_i64(acc, cpu_env, offsetof(CPUPPCState, spe_acc));
9030
9031     /* acc := tmp + acc */
9032     tcg_gen_add_i64(acc, acc, tmp);
9033
9034     /* Store acc */
9035     tcg_gen_st_i64(acc, cpu_env, offsetof(CPUPPCState, spe_acc));
9036
9037     /* rD := acc */
9038     gen_store_gpr64(rD(ctx->opcode), acc);
9039
9040     tcg_temp_free_i64(acc);
9041     tcg_temp_free_i64(tmp);
9042 }
9043
9044 GEN_SPE(evaddw,      speundef,    0x00, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE); ////
9045 GEN_SPE(evaddiw,     speundef,    0x01, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE);
9046 GEN_SPE(evsubfw,     speundef,    0x02, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE); ////
9047 GEN_SPE(evsubifw,    speundef,    0x03, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE);
9048 GEN_SPE(evabs,       evneg,       0x04, 0x08, 0x0000F800, 0x0000F800, PPC_SPE); ////
9049 GEN_SPE(evextsb,     evextsh,     0x05, 0x08, 0x0000F800, 0x0000F800, PPC_SPE); ////
9050 GEN_SPE(evrndw,      evcntlzw,    0x06, 0x08, 0x0000F800, 0x0000F800, PPC_SPE); ////
9051 GEN_SPE(evcntlsw,    brinc,       0x07, 0x08, 0x0000F800, 0x00000000, PPC_SPE); //
9052 GEN_SPE(evmra,       speundef,    0x02, 0x13, 0x0000F800, 0xFFFFFFFF, PPC_SPE);
9053 GEN_SPE(speundef,    evand,       0x08, 0x08, 0xFFFFFFFF, 0x00000000, PPC_SPE); ////
9054 GEN_SPE(evandc,      speundef,    0x09, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE); ////
9055 GEN_SPE(evxor,       evor,        0x0B, 0x08, 0x00000000, 0x00000000, PPC_SPE); ////
9056 GEN_SPE(evnor,       eveqv,       0x0C, 0x08, 0x00000000, 0x00000000, PPC_SPE); ////
9057 GEN_SPE(evmwumi,     evmwsmi,     0x0C, 0x11, 0x00000000, 0x00000000, PPC_SPE);
9058 GEN_SPE(evmwumia,    evmwsmia,    0x1C, 0x11, 0x00000000, 0x00000000, PPC_SPE);
9059 GEN_SPE(evmwumiaa,   evmwsmiaa,   0x0C, 0x15, 0x00000000, 0x00000000, PPC_SPE);
9060 GEN_SPE(speundef,    evorc,       0x0D, 0x08, 0xFFFFFFFF, 0x00000000, PPC_SPE); ////
9061 GEN_SPE(evnand,      speundef,    0x0F, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE); ////
9062 GEN_SPE(evsrwu,      evsrws,      0x10, 0x08, 0x00000000, 0x00000000, PPC_SPE); ////
9063 GEN_SPE(evsrwiu,     evsrwis,     0x11, 0x08, 0x00000000, 0x00000000, PPC_SPE);
9064 GEN_SPE(evslw,       speundef,    0x12, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE); ////
9065 GEN_SPE(evslwi,      speundef,    0x13, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE);
9066 GEN_SPE(evrlw,       evsplati,    0x14, 0x08, 0x00000000, 0x0000F800, PPC_SPE); //
9067 GEN_SPE(evrlwi,      evsplatfi,   0x15, 0x08, 0x00000000, 0x0000F800, PPC_SPE);
9068 GEN_SPE(evmergehi,   evmergelo,   0x16, 0x08, 0x00000000, 0x00000000, PPC_SPE); ////
9069 GEN_SPE(evmergehilo, evmergelohi, 0x17, 0x08, 0x00000000, 0x00000000, PPC_SPE); ////
9070 GEN_SPE(evcmpgtu,    evcmpgts,    0x18, 0x08, 0x00600000, 0x00600000, PPC_SPE); ////
9071 GEN_SPE(evcmpltu,    evcmplts,    0x19, 0x08, 0x00600000, 0x00600000, PPC_SPE); ////
9072 GEN_SPE(evcmpeq,     speundef,    0x1A, 0x08, 0x00600000, 0xFFFFFFFF, PPC_SPE); ////
9073
9074 /* SPE load and stores */
9075 static inline void gen_addr_spe_imm_index(DisasContext *ctx, TCGv EA, int sh)
9076 {
9077     target_ulong uimm = rB(ctx->opcode);
9078
9079     if (rA(ctx->opcode) == 0) {
9080         tcg_gen_movi_tl(EA, uimm << sh);
9081     } else {
9082         tcg_gen_addi_tl(EA, cpu_gpr[rA(ctx->opcode)], uimm << sh);
9083         if (NARROW_MODE(ctx)) {
9084             tcg_gen_ext32u_tl(EA, EA);
9085         }
9086     }
9087 }
9088
9089 static inline void gen_op_evldd(DisasContext *ctx, TCGv addr)
9090 {
9091     TCGv_i64 t0 = tcg_temp_new_i64();
9092     gen_qemu_ld64(ctx, t0, addr);
9093     gen_store_gpr64(rD(ctx->opcode), t0);
9094     tcg_temp_free_i64(t0);
9095 }
9096
9097 static inline void gen_op_evldw(DisasContext *ctx, TCGv addr)
9098 {
9099     gen_qemu_ld32u(ctx, cpu_gprh[rD(ctx->opcode)], addr);
9100     gen_addr_add(ctx, addr, addr, 4);
9101     gen_qemu_ld32u(ctx, cpu_gpr[rD(ctx->opcode)], addr);
9102 }
9103
9104 static inline void gen_op_evldh(DisasContext *ctx, TCGv addr)
9105 {
9106     TCGv t0 = tcg_temp_new();
9107     gen_qemu_ld16u(ctx, t0, addr);
9108     tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
9109     gen_addr_add(ctx, addr, addr, 2);
9110     gen_qemu_ld16u(ctx, t0, addr);
9111     tcg_gen_or_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0);
9112     gen_addr_add(ctx, addr, addr, 2);
9113     gen_qemu_ld16u(ctx, t0, addr);
9114     tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
9115     gen_addr_add(ctx, addr, addr, 2);
9116     gen_qemu_ld16u(ctx, t0, addr);
9117     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
9118     tcg_temp_free(t0);
9119 }
9120
9121 static inline void gen_op_evlhhesplat(DisasContext *ctx, TCGv addr)
9122 {
9123     TCGv t0 = tcg_temp_new();
9124     gen_qemu_ld16u(ctx, t0, addr);
9125     tcg_gen_shli_tl(t0, t0, 16);
9126     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
9127     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
9128     tcg_temp_free(t0);
9129 }
9130
9131 static inline void gen_op_evlhhousplat(DisasContext *ctx, TCGv addr)
9132 {
9133     TCGv t0 = tcg_temp_new();
9134     gen_qemu_ld16u(ctx, t0, addr);
9135     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
9136     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
9137     tcg_temp_free(t0);
9138 }
9139
9140 static inline void gen_op_evlhhossplat(DisasContext *ctx, TCGv addr)
9141 {
9142     TCGv t0 = tcg_temp_new();
9143     gen_qemu_ld16s(ctx, t0, addr);
9144     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
9145     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
9146     tcg_temp_free(t0);
9147 }
9148
9149 static inline void gen_op_evlwhe(DisasContext *ctx, TCGv addr)
9150 {
9151     TCGv t0 = tcg_temp_new();
9152     gen_qemu_ld16u(ctx, t0, addr);
9153     tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
9154     gen_addr_add(ctx, addr, addr, 2);
9155     gen_qemu_ld16u(ctx, t0, addr);
9156     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 16);
9157     tcg_temp_free(t0);
9158 }
9159
9160 static inline void gen_op_evlwhou(DisasContext *ctx, TCGv addr)
9161 {
9162     gen_qemu_ld16u(ctx, cpu_gprh[rD(ctx->opcode)], addr);
9163     gen_addr_add(ctx, addr, addr, 2);
9164     gen_qemu_ld16u(ctx, cpu_gpr[rD(ctx->opcode)], addr);
9165 }
9166
9167 static inline void gen_op_evlwhos(DisasContext *ctx, TCGv addr)
9168 {
9169     gen_qemu_ld16s(ctx, cpu_gprh[rD(ctx->opcode)], addr);
9170     gen_addr_add(ctx, addr, addr, 2);
9171     gen_qemu_ld16s(ctx, cpu_gpr[rD(ctx->opcode)], addr);
9172 }
9173
9174 static inline void gen_op_evlwwsplat(DisasContext *ctx, TCGv addr)
9175 {
9176     TCGv t0 = tcg_temp_new();
9177     gen_qemu_ld32u(ctx, t0, addr);
9178     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
9179     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
9180     tcg_temp_free(t0);
9181 }
9182
9183 static inline void gen_op_evlwhsplat(DisasContext *ctx, TCGv addr)
9184 {
9185     TCGv t0 = tcg_temp_new();
9186     gen_qemu_ld16u(ctx, t0, addr);
9187     tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
9188     tcg_gen_or_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0);
9189     gen_addr_add(ctx, addr, addr, 2);
9190     gen_qemu_ld16u(ctx, t0, addr);
9191     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 16);
9192     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0);
9193     tcg_temp_free(t0);
9194 }
9195
9196 static inline void gen_op_evstdd(DisasContext *ctx, TCGv addr)
9197 {
9198     TCGv_i64 t0 = tcg_temp_new_i64();
9199     gen_load_gpr64(t0, rS(ctx->opcode));
9200     gen_qemu_st64(ctx, t0, addr);
9201     tcg_temp_free_i64(t0);
9202 }
9203
9204 static inline void gen_op_evstdw(DisasContext *ctx, TCGv addr)
9205 {
9206     gen_qemu_st32(ctx, cpu_gprh[rS(ctx->opcode)], addr);
9207     gen_addr_add(ctx, addr, addr, 4);
9208     gen_qemu_st32(ctx, cpu_gpr[rS(ctx->opcode)], addr);
9209 }
9210
9211 static inline void gen_op_evstdh(DisasContext *ctx, TCGv addr)
9212 {
9213     TCGv t0 = tcg_temp_new();
9214     tcg_gen_shri_tl(t0, cpu_gprh[rS(ctx->opcode)], 16);
9215     gen_qemu_st16(ctx, t0, addr);
9216     gen_addr_add(ctx, addr, addr, 2);
9217     gen_qemu_st16(ctx, cpu_gprh[rS(ctx->opcode)], addr);
9218     gen_addr_add(ctx, addr, addr, 2);
9219     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 16);
9220     gen_qemu_st16(ctx, t0, addr);
9221     tcg_temp_free(t0);
9222     gen_addr_add(ctx, addr, addr, 2);
9223     gen_qemu_st16(ctx, cpu_gpr[rS(ctx->opcode)], addr);
9224 }
9225
9226 static inline void gen_op_evstwhe(DisasContext *ctx, TCGv addr)
9227 {
9228     TCGv t0 = tcg_temp_new();
9229     tcg_gen_shri_tl(t0, cpu_gprh[rS(ctx->opcode)], 16);
9230     gen_qemu_st16(ctx, t0, addr);
9231     gen_addr_add(ctx, addr, addr, 2);
9232     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 16);
9233     gen_qemu_st16(ctx, t0, addr);
9234     tcg_temp_free(t0);
9235 }
9236
9237 static inline void gen_op_evstwho(DisasContext *ctx, TCGv addr)
9238 {
9239     gen_qemu_st16(ctx, cpu_gprh[rS(ctx->opcode)], addr);
9240     gen_addr_add(ctx, addr, addr, 2);
9241     gen_qemu_st16(ctx, cpu_gpr[rS(ctx->opcode)], addr);
9242 }
9243
9244 static inline void gen_op_evstwwe(DisasContext *ctx, TCGv addr)
9245 {
9246     gen_qemu_st32(ctx, cpu_gprh[rS(ctx->opcode)], addr);
9247 }
9248
9249 static inline void gen_op_evstwwo(DisasContext *ctx, TCGv addr)
9250 {
9251     gen_qemu_st32(ctx, cpu_gpr[rS(ctx->opcode)], addr);
9252 }
9253
9254 #define GEN_SPEOP_LDST(name, opc2, sh)                                        \
9255 static void glue(gen_, name)(DisasContext *ctx)                                       \
9256 {                                                                             \
9257     TCGv t0;                                                                  \
9258     if (unlikely(!ctx->spe_enabled)) {                                        \
9259         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
9260         return;                                                               \
9261     }                                                                         \
9262     gen_set_access_type(ctx, ACCESS_INT);                                     \
9263     t0 = tcg_temp_new();                                                      \
9264     if (Rc(ctx->opcode)) {                                                    \
9265         gen_addr_spe_imm_index(ctx, t0, sh);                                  \
9266     } else {                                                                  \
9267         gen_addr_reg_index(ctx, t0);                                          \
9268     }                                                                         \
9269     gen_op_##name(ctx, t0);                                                   \
9270     tcg_temp_free(t0);                                                        \
9271 }
9272
9273 GEN_SPEOP_LDST(evldd, 0x00, 3);
9274 GEN_SPEOP_LDST(evldw, 0x01, 3);
9275 GEN_SPEOP_LDST(evldh, 0x02, 3);
9276 GEN_SPEOP_LDST(evlhhesplat, 0x04, 1);
9277 GEN_SPEOP_LDST(evlhhousplat, 0x06, 1);
9278 GEN_SPEOP_LDST(evlhhossplat, 0x07, 1);
9279 GEN_SPEOP_LDST(evlwhe, 0x08, 2);
9280 GEN_SPEOP_LDST(evlwhou, 0x0A, 2);
9281 GEN_SPEOP_LDST(evlwhos, 0x0B, 2);
9282 GEN_SPEOP_LDST(evlwwsplat, 0x0C, 2);
9283 GEN_SPEOP_LDST(evlwhsplat, 0x0E, 2);
9284
9285 GEN_SPEOP_LDST(evstdd, 0x10, 3);
9286 GEN_SPEOP_LDST(evstdw, 0x11, 3);
9287 GEN_SPEOP_LDST(evstdh, 0x12, 3);
9288 GEN_SPEOP_LDST(evstwhe, 0x18, 2);
9289 GEN_SPEOP_LDST(evstwho, 0x1A, 2);
9290 GEN_SPEOP_LDST(evstwwe, 0x1C, 2);
9291 GEN_SPEOP_LDST(evstwwo, 0x1E, 2);
9292
9293 /* Multiply and add - TODO */
9294 #if 0
9295 GEN_SPE(speundef,       evmhessf,      0x01, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);//
9296 GEN_SPE(speundef,       evmhossf,      0x03, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9297 GEN_SPE(evmheumi,       evmhesmi,      0x04, 0x10, 0x00000000, 0x00000000, PPC_SPE);
9298 GEN_SPE(speundef,       evmhesmf,      0x05, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9299 GEN_SPE(evmhoumi,       evmhosmi,      0x06, 0x10, 0x00000000, 0x00000000, PPC_SPE);
9300 GEN_SPE(speundef,       evmhosmf,      0x07, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9301 GEN_SPE(speundef,       evmhessfa,     0x11, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9302 GEN_SPE(speundef,       evmhossfa,     0x13, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9303 GEN_SPE(evmheumia,      evmhesmia,     0x14, 0x10, 0x00000000, 0x00000000, PPC_SPE);
9304 GEN_SPE(speundef,       evmhesmfa,     0x15, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9305 GEN_SPE(evmhoumia,      evmhosmia,     0x16, 0x10, 0x00000000, 0x00000000, PPC_SPE);
9306 GEN_SPE(speundef,       evmhosmfa,     0x17, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9307
9308 GEN_SPE(speundef,       evmwhssf,      0x03, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9309 GEN_SPE(evmwlumi,       speundef,      0x04, 0x11, 0x00000000, 0xFFFFFFFF, PPC_SPE);
9310 GEN_SPE(evmwhumi,       evmwhsmi,      0x06, 0x11, 0x00000000, 0x00000000, PPC_SPE);
9311 GEN_SPE(speundef,       evmwhsmf,      0x07, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9312 GEN_SPE(speundef,       evmwssf,       0x09, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9313 GEN_SPE(speundef,       evmwsmf,       0x0D, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9314 GEN_SPE(speundef,       evmwhssfa,     0x13, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9315 GEN_SPE(evmwlumia,      speundef,      0x14, 0x11, 0x00000000, 0xFFFFFFFF, PPC_SPE);
9316 GEN_SPE(evmwhumia,      evmwhsmia,     0x16, 0x11, 0x00000000, 0x00000000, PPC_SPE);
9317 GEN_SPE(speundef,       evmwhsmfa,     0x17, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9318 GEN_SPE(speundef,       evmwssfa,      0x19, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9319 GEN_SPE(speundef,       evmwsmfa,      0x1D, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9320
9321 GEN_SPE(evadduiaaw,     evaddsiaaw,    0x00, 0x13, 0x0000F800, 0x0000F800, PPC_SPE);
9322 GEN_SPE(evsubfusiaaw,   evsubfssiaaw,  0x01, 0x13, 0x0000F800, 0x0000F800, PPC_SPE);
9323 GEN_SPE(evaddumiaaw,    evaddsmiaaw,   0x04, 0x13, 0x0000F800, 0x0000F800, PPC_SPE);
9324 GEN_SPE(evsubfumiaaw,   evsubfsmiaaw,  0x05, 0x13, 0x0000F800, 0x0000F800, PPC_SPE);
9325 GEN_SPE(evdivws,        evdivwu,       0x06, 0x13, 0x00000000, 0x00000000, PPC_SPE);
9326
9327 GEN_SPE(evmheusiaaw,    evmhessiaaw,   0x00, 0x14, 0x00000000, 0x00000000, PPC_SPE);
9328 GEN_SPE(speundef,       evmhessfaaw,   0x01, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9329 GEN_SPE(evmhousiaaw,    evmhossiaaw,   0x02, 0x14, 0x00000000, 0x00000000, PPC_SPE);
9330 GEN_SPE(speundef,       evmhossfaaw,   0x03, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9331 GEN_SPE(evmheumiaaw,    evmhesmiaaw,   0x04, 0x14, 0x00000000, 0x00000000, PPC_SPE);
9332 GEN_SPE(speundef,       evmhesmfaaw,   0x05, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9333 GEN_SPE(evmhoumiaaw,    evmhosmiaaw,   0x06, 0x14, 0x00000000, 0x00000000, PPC_SPE);
9334 GEN_SPE(speundef,       evmhosmfaaw,   0x07, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9335 GEN_SPE(evmhegumiaa,    evmhegsmiaa,   0x14, 0x14, 0x00000000, 0x00000000, PPC_SPE);
9336 GEN_SPE(speundef,       evmhegsmfaa,   0x15, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9337 GEN_SPE(evmhogumiaa,    evmhogsmiaa,   0x16, 0x14, 0x00000000, 0x00000000, PPC_SPE);
9338 GEN_SPE(speundef,       evmhogsmfaa,   0x17, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9339
9340 GEN_SPE(evmwlusiaaw,    evmwlssiaaw,   0x00, 0x15, 0x00000000, 0x00000000, PPC_SPE);
9341 GEN_SPE(evmwlumiaaw,    evmwlsmiaaw,   0x04, 0x15, 0x00000000, 0x00000000, PPC_SPE);
9342 GEN_SPE(speundef,       evmwssfaa,     0x09, 0x15, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9343 GEN_SPE(speundef,       evmwsmfaa,     0x0D, 0x15, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9344
9345 GEN_SPE(evmheusianw,    evmhessianw,   0x00, 0x16, 0x00000000, 0x00000000, PPC_SPE);
9346 GEN_SPE(speundef,       evmhessfanw,   0x01, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9347 GEN_SPE(evmhousianw,    evmhossianw,   0x02, 0x16, 0x00000000, 0x00000000, PPC_SPE);
9348 GEN_SPE(speundef,       evmhossfanw,   0x03, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9349 GEN_SPE(evmheumianw,    evmhesmianw,   0x04, 0x16, 0x00000000, 0x00000000, PPC_SPE);
9350 GEN_SPE(speundef,       evmhesmfanw,   0x05, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9351 GEN_SPE(evmhoumianw,    evmhosmianw,   0x06, 0x16, 0x00000000, 0x00000000, PPC_SPE);
9352 GEN_SPE(speundef,       evmhosmfanw,   0x07, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9353 GEN_SPE(evmhegumian,    evmhegsmian,   0x14, 0x16, 0x00000000, 0x00000000, PPC_SPE);
9354 GEN_SPE(speundef,       evmhegsmfan,   0x15, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9355 GEN_SPE(evmhigumian,    evmhigsmian,   0x16, 0x16, 0x00000000, 0x00000000, PPC_SPE);
9356 GEN_SPE(speundef,       evmhogsmfan,   0x17, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9357
9358 GEN_SPE(evmwlusianw,    evmwlssianw,   0x00, 0x17, 0x00000000, 0x00000000, PPC_SPE);
9359 GEN_SPE(evmwlumianw,    evmwlsmianw,   0x04, 0x17, 0x00000000, 0x00000000, PPC_SPE);
9360 GEN_SPE(speundef,       evmwssfan,     0x09, 0x17, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9361 GEN_SPE(evmwumian,      evmwsmian,     0x0C, 0x17, 0x00000000, 0x00000000, PPC_SPE);
9362 GEN_SPE(speundef,       evmwsmfan,     0x0D, 0x17, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9363 #endif
9364
9365 /***                      SPE floating-point extension                     ***/
9366 #define GEN_SPEFPUOP_CONV_32_32(name)                                         \
9367 static inline void gen_##name(DisasContext *ctx)                              \
9368 {                                                                             \
9369     TCGv_i32 t0 = tcg_temp_new_i32();                                         \
9370     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rB(ctx->opcode)]);                       \
9371     gen_helper_##name(t0, cpu_env, t0);                                       \
9372     tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0);                        \
9373     tcg_temp_free_i32(t0);                                                    \
9374 }
9375 #define GEN_SPEFPUOP_CONV_32_64(name)                                         \
9376 static inline void gen_##name(DisasContext *ctx)                              \
9377 {                                                                             \
9378     TCGv_i64 t0 = tcg_temp_new_i64();                                         \
9379     TCGv_i32 t1 = tcg_temp_new_i32();                                         \
9380     gen_load_gpr64(t0, rB(ctx->opcode));                                      \
9381     gen_helper_##name(t1, cpu_env, t0);                                       \
9382     tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t1);                        \
9383     tcg_temp_free_i64(t0);                                                    \
9384     tcg_temp_free_i32(t1);                                                    \
9385 }
9386 #define GEN_SPEFPUOP_CONV_64_32(name)                                         \
9387 static inline void gen_##name(DisasContext *ctx)                              \
9388 {                                                                             \
9389     TCGv_i64 t0 = tcg_temp_new_i64();                                         \
9390     TCGv_i32 t1 = tcg_temp_new_i32();                                         \
9391     tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);                       \
9392     gen_helper_##name(t0, cpu_env, t1);                                       \
9393     gen_store_gpr64(rD(ctx->opcode), t0);                                     \
9394     tcg_temp_free_i64(t0);                                                    \
9395     tcg_temp_free_i32(t1);                                                    \
9396 }
9397 #define GEN_SPEFPUOP_CONV_64_64(name)                                         \
9398 static inline void gen_##name(DisasContext *ctx)                              \
9399 {                                                                             \
9400     TCGv_i64 t0 = tcg_temp_new_i64();                                         \
9401     gen_load_gpr64(t0, rB(ctx->opcode));                                      \
9402     gen_helper_##name(t0, cpu_env, t0);                                       \
9403     gen_store_gpr64(rD(ctx->opcode), t0);                                     \
9404     tcg_temp_free_i64(t0);                                                    \
9405 }
9406 #define GEN_SPEFPUOP_ARITH2_32_32(name)                                       \
9407 static inline void gen_##name(DisasContext *ctx)                              \
9408 {                                                                             \
9409     TCGv_i32 t0, t1;                                                          \
9410     if (unlikely(!ctx->spe_enabled)) {                                        \
9411         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
9412         return;                                                               \
9413     }                                                                         \
9414     t0 = tcg_temp_new_i32();                                                  \
9415     t1 = tcg_temp_new_i32();                                                  \
9416     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);                       \
9417     tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);                       \
9418     gen_helper_##name(t0, cpu_env, t0, t1);                                   \
9419     tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0);                        \
9420                                                                               \
9421     tcg_temp_free_i32(t0);                                                    \
9422     tcg_temp_free_i32(t1);                                                    \
9423 }
9424 #define GEN_SPEFPUOP_ARITH2_64_64(name)                                       \
9425 static inline void gen_##name(DisasContext *ctx)                              \
9426 {                                                                             \
9427     TCGv_i64 t0, t1;                                                          \
9428     if (unlikely(!ctx->spe_enabled)) {                                        \
9429         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
9430         return;                                                               \
9431     }                                                                         \
9432     t0 = tcg_temp_new_i64();                                                  \
9433     t1 = tcg_temp_new_i64();                                                  \
9434     gen_load_gpr64(t0, rA(ctx->opcode));                                      \
9435     gen_load_gpr64(t1, rB(ctx->opcode));                                      \
9436     gen_helper_##name(t0, cpu_env, t0, t1);                                   \
9437     gen_store_gpr64(rD(ctx->opcode), t0);                                     \
9438     tcg_temp_free_i64(t0);                                                    \
9439     tcg_temp_free_i64(t1);                                                    \
9440 }
9441 #define GEN_SPEFPUOP_COMP_32(name)                                            \
9442 static inline void gen_##name(DisasContext *ctx)                              \
9443 {                                                                             \
9444     TCGv_i32 t0, t1;                                                          \
9445     if (unlikely(!ctx->spe_enabled)) {                                        \
9446         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
9447         return;                                                               \
9448     }                                                                         \
9449     t0 = tcg_temp_new_i32();                                                  \
9450     t1 = tcg_temp_new_i32();                                                  \
9451                                                                               \
9452     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);                       \
9453     tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);                       \
9454     gen_helper_##name(cpu_crf[crfD(ctx->opcode)], cpu_env, t0, t1);           \
9455                                                                               \
9456     tcg_temp_free_i32(t0);                                                    \
9457     tcg_temp_free_i32(t1);                                                    \
9458 }
9459 #define GEN_SPEFPUOP_COMP_64(name)                                            \
9460 static inline void gen_##name(DisasContext *ctx)                              \
9461 {                                                                             \
9462     TCGv_i64 t0, t1;                                                          \
9463     if (unlikely(!ctx->spe_enabled)) {                                        \
9464         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
9465         return;                                                               \
9466     }                                                                         \
9467     t0 = tcg_temp_new_i64();                                                  \
9468     t1 = tcg_temp_new_i64();                                                  \
9469     gen_load_gpr64(t0, rA(ctx->opcode));                                      \
9470     gen_load_gpr64(t1, rB(ctx->opcode));                                      \
9471     gen_helper_##name(cpu_crf[crfD(ctx->opcode)], cpu_env, t0, t1);           \
9472     tcg_temp_free_i64(t0);                                                    \
9473     tcg_temp_free_i64(t1);                                                    \
9474 }
9475
9476 /* Single precision floating-point vectors operations */
9477 /* Arithmetic */
9478 GEN_SPEFPUOP_ARITH2_64_64(evfsadd);
9479 GEN_SPEFPUOP_ARITH2_64_64(evfssub);
9480 GEN_SPEFPUOP_ARITH2_64_64(evfsmul);
9481 GEN_SPEFPUOP_ARITH2_64_64(evfsdiv);
9482 static inline void gen_evfsabs(DisasContext *ctx)
9483 {
9484     if (unlikely(!ctx->spe_enabled)) {
9485         gen_exception(ctx, POWERPC_EXCP_SPEU);
9486         return;
9487     }
9488     tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
9489                     ~0x80000000);
9490     tcg_gen_andi_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],
9491                     ~0x80000000);
9492 }
9493 static inline void gen_evfsnabs(DisasContext *ctx)
9494 {
9495     if (unlikely(!ctx->spe_enabled)) {
9496         gen_exception(ctx, POWERPC_EXCP_SPEU);
9497         return;
9498     }
9499     tcg_gen_ori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
9500                    0x80000000);
9501     tcg_gen_ori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],
9502                    0x80000000);
9503 }
9504 static inline void gen_evfsneg(DisasContext *ctx)
9505 {
9506     if (unlikely(!ctx->spe_enabled)) {
9507         gen_exception(ctx, POWERPC_EXCP_SPEU);
9508         return;
9509     }
9510     tcg_gen_xori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
9511                     0x80000000);
9512     tcg_gen_xori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],
9513                     0x80000000);
9514 }
9515
9516 /* Conversion */
9517 GEN_SPEFPUOP_CONV_64_64(evfscfui);
9518 GEN_SPEFPUOP_CONV_64_64(evfscfsi);
9519 GEN_SPEFPUOP_CONV_64_64(evfscfuf);
9520 GEN_SPEFPUOP_CONV_64_64(evfscfsf);
9521 GEN_SPEFPUOP_CONV_64_64(evfsctui);
9522 GEN_SPEFPUOP_CONV_64_64(evfsctsi);
9523 GEN_SPEFPUOP_CONV_64_64(evfsctuf);
9524 GEN_SPEFPUOP_CONV_64_64(evfsctsf);
9525 GEN_SPEFPUOP_CONV_64_64(evfsctuiz);
9526 GEN_SPEFPUOP_CONV_64_64(evfsctsiz);
9527
9528 /* Comparison */
9529 GEN_SPEFPUOP_COMP_64(evfscmpgt);
9530 GEN_SPEFPUOP_COMP_64(evfscmplt);
9531 GEN_SPEFPUOP_COMP_64(evfscmpeq);
9532 GEN_SPEFPUOP_COMP_64(evfststgt);
9533 GEN_SPEFPUOP_COMP_64(evfststlt);
9534 GEN_SPEFPUOP_COMP_64(evfststeq);
9535
9536 /* Opcodes definitions */
9537 GEN_SPE(evfsadd,   evfssub,   0x00, 0x0A, 0x00000000, 0x00000000, PPC_SPE_SINGLE); //
9538 GEN_SPE(evfsabs,   evfsnabs,  0x02, 0x0A, 0x0000F800, 0x0000F800, PPC_SPE_SINGLE); //
9539 GEN_SPE(evfsneg,   speundef,  0x03, 0x0A, 0x0000F800, 0xFFFFFFFF, PPC_SPE_SINGLE); //
9540 GEN_SPE(evfsmul,   evfsdiv,   0x04, 0x0A, 0x00000000, 0x00000000, PPC_SPE_SINGLE); //
9541 GEN_SPE(evfscmpgt, evfscmplt, 0x06, 0x0A, 0x00600000, 0x00600000, PPC_SPE_SINGLE); //
9542 GEN_SPE(evfscmpeq, speundef,  0x07, 0x0A, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
9543 GEN_SPE(evfscfui,  evfscfsi,  0x08, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
9544 GEN_SPE(evfscfuf,  evfscfsf,  0x09, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
9545 GEN_SPE(evfsctui,  evfsctsi,  0x0A, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
9546 GEN_SPE(evfsctuf,  evfsctsf,  0x0B, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
9547 GEN_SPE(evfsctuiz, speundef,  0x0C, 0x0A, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
9548 GEN_SPE(evfsctsiz, speundef,  0x0D, 0x0A, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
9549 GEN_SPE(evfststgt, evfststlt, 0x0E, 0x0A, 0x00600000, 0x00600000, PPC_SPE_SINGLE); //
9550 GEN_SPE(evfststeq, speundef,  0x0F, 0x0A, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
9551
9552 /* Single precision floating-point operations */
9553 /* Arithmetic */
9554 GEN_SPEFPUOP_ARITH2_32_32(efsadd);
9555 GEN_SPEFPUOP_ARITH2_32_32(efssub);
9556 GEN_SPEFPUOP_ARITH2_32_32(efsmul);
9557 GEN_SPEFPUOP_ARITH2_32_32(efsdiv);
9558 static inline void gen_efsabs(DisasContext *ctx)
9559 {
9560     if (unlikely(!ctx->spe_enabled)) {
9561         gen_exception(ctx, POWERPC_EXCP_SPEU);
9562         return;
9563     }
9564     tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], (target_long)~0x80000000LL);
9565 }
9566 static inline void gen_efsnabs(DisasContext *ctx)
9567 {
9568     if (unlikely(!ctx->spe_enabled)) {
9569         gen_exception(ctx, POWERPC_EXCP_SPEU);
9570         return;
9571     }
9572     tcg_gen_ori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
9573 }
9574 static inline void gen_efsneg(DisasContext *ctx)
9575 {
9576     if (unlikely(!ctx->spe_enabled)) {
9577         gen_exception(ctx, POWERPC_EXCP_SPEU);
9578         return;
9579     }
9580     tcg_gen_xori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
9581 }
9582
9583 /* Conversion */
9584 GEN_SPEFPUOP_CONV_32_32(efscfui);
9585 GEN_SPEFPUOP_CONV_32_32(efscfsi);
9586 GEN_SPEFPUOP_CONV_32_32(efscfuf);
9587 GEN_SPEFPUOP_CONV_32_32(efscfsf);
9588 GEN_SPEFPUOP_CONV_32_32(efsctui);
9589 GEN_SPEFPUOP_CONV_32_32(efsctsi);
9590 GEN_SPEFPUOP_CONV_32_32(efsctuf);
9591 GEN_SPEFPUOP_CONV_32_32(efsctsf);
9592 GEN_SPEFPUOP_CONV_32_32(efsctuiz);
9593 GEN_SPEFPUOP_CONV_32_32(efsctsiz);
9594 GEN_SPEFPUOP_CONV_32_64(efscfd);
9595
9596 /* Comparison */
9597 GEN_SPEFPUOP_COMP_32(efscmpgt);
9598 GEN_SPEFPUOP_COMP_32(efscmplt);
9599 GEN_SPEFPUOP_COMP_32(efscmpeq);
9600 GEN_SPEFPUOP_COMP_32(efststgt);
9601 GEN_SPEFPUOP_COMP_32(efststlt);
9602 GEN_SPEFPUOP_COMP_32(efststeq);
9603
9604 /* Opcodes definitions */
9605 GEN_SPE(efsadd,   efssub,   0x00, 0x0B, 0x00000000, 0x00000000, PPC_SPE_SINGLE); //
9606 GEN_SPE(efsabs,   efsnabs,  0x02, 0x0B, 0x0000F800, 0x0000F800, PPC_SPE_SINGLE); //
9607 GEN_SPE(efsneg,   speundef, 0x03, 0x0B, 0x0000F800, 0xFFFFFFFF, PPC_SPE_SINGLE); //
9608 GEN_SPE(efsmul,   efsdiv,   0x04, 0x0B, 0x00000000, 0x00000000, PPC_SPE_SINGLE); //
9609 GEN_SPE(efscmpgt, efscmplt, 0x06, 0x0B, 0x00600000, 0x00600000, PPC_SPE_SINGLE); //
9610 GEN_SPE(efscmpeq, efscfd,   0x07, 0x0B, 0x00600000, 0x00180000, PPC_SPE_SINGLE); //
9611 GEN_SPE(efscfui,  efscfsi,  0x08, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
9612 GEN_SPE(efscfuf,  efscfsf,  0x09, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
9613 GEN_SPE(efsctui,  efsctsi,  0x0A, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
9614 GEN_SPE(efsctuf,  efsctsf,  0x0B, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
9615 GEN_SPE(efsctuiz, speundef, 0x0C, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
9616 GEN_SPE(efsctsiz, speundef, 0x0D, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
9617 GEN_SPE(efststgt, efststlt, 0x0E, 0x0B, 0x00600000, 0x00600000, PPC_SPE_SINGLE); //
9618 GEN_SPE(efststeq, speundef, 0x0F, 0x0B, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
9619
9620 /* Double precision floating-point operations */
9621 /* Arithmetic */
9622 GEN_SPEFPUOP_ARITH2_64_64(efdadd);
9623 GEN_SPEFPUOP_ARITH2_64_64(efdsub);
9624 GEN_SPEFPUOP_ARITH2_64_64(efdmul);
9625 GEN_SPEFPUOP_ARITH2_64_64(efddiv);
9626 static inline void gen_efdabs(DisasContext *ctx)
9627 {
9628     if (unlikely(!ctx->spe_enabled)) {
9629         gen_exception(ctx, POWERPC_EXCP_SPEU);
9630         return;
9631     }
9632     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
9633     tcg_gen_andi_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],
9634                     ~0x80000000);
9635 }
9636 static inline void gen_efdnabs(DisasContext *ctx)
9637 {
9638     if (unlikely(!ctx->spe_enabled)) {
9639         gen_exception(ctx, POWERPC_EXCP_SPEU);
9640         return;
9641     }
9642     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
9643     tcg_gen_ori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],
9644                    0x80000000);
9645 }
9646 static inline void gen_efdneg(DisasContext *ctx)
9647 {
9648     if (unlikely(!ctx->spe_enabled)) {
9649         gen_exception(ctx, POWERPC_EXCP_SPEU);
9650         return;
9651     }
9652     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
9653     tcg_gen_xori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],
9654                     0x80000000);
9655 }
9656
9657 /* Conversion */
9658 GEN_SPEFPUOP_CONV_64_32(efdcfui);
9659 GEN_SPEFPUOP_CONV_64_32(efdcfsi);
9660 GEN_SPEFPUOP_CONV_64_32(efdcfuf);
9661 GEN_SPEFPUOP_CONV_64_32(efdcfsf);
9662 GEN_SPEFPUOP_CONV_32_64(efdctui);
9663 GEN_SPEFPUOP_CONV_32_64(efdctsi);
9664 GEN_SPEFPUOP_CONV_32_64(efdctuf);
9665 GEN_SPEFPUOP_CONV_32_64(efdctsf);
9666 GEN_SPEFPUOP_CONV_32_64(efdctuiz);
9667 GEN_SPEFPUOP_CONV_32_64(efdctsiz);
9668 GEN_SPEFPUOP_CONV_64_32(efdcfs);
9669 GEN_SPEFPUOP_CONV_64_64(efdcfuid);
9670 GEN_SPEFPUOP_CONV_64_64(efdcfsid);
9671 GEN_SPEFPUOP_CONV_64_64(efdctuidz);
9672 GEN_SPEFPUOP_CONV_64_64(efdctsidz);
9673
9674 /* Comparison */
9675 GEN_SPEFPUOP_COMP_64(efdcmpgt);
9676 GEN_SPEFPUOP_COMP_64(efdcmplt);
9677 GEN_SPEFPUOP_COMP_64(efdcmpeq);
9678 GEN_SPEFPUOP_COMP_64(efdtstgt);
9679 GEN_SPEFPUOP_COMP_64(efdtstlt);
9680 GEN_SPEFPUOP_COMP_64(efdtsteq);
9681
9682 /* Opcodes definitions */
9683 GEN_SPE(efdadd,    efdsub,    0x10, 0x0B, 0x00000000, 0x00000000, PPC_SPE_DOUBLE); //
9684 GEN_SPE(efdcfuid,  efdcfsid,  0x11, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
9685 GEN_SPE(efdabs,    efdnabs,   0x12, 0x0B, 0x0000F800, 0x0000F800, PPC_SPE_DOUBLE); //
9686 GEN_SPE(efdneg,    speundef,  0x13, 0x0B, 0x0000F800, 0xFFFFFFFF, PPC_SPE_DOUBLE); //
9687 GEN_SPE(efdmul,    efddiv,    0x14, 0x0B, 0x00000000, 0x00000000, PPC_SPE_DOUBLE); //
9688 GEN_SPE(efdctuidz, efdctsidz, 0x15, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
9689 GEN_SPE(efdcmpgt,  efdcmplt,  0x16, 0x0B, 0x00600000, 0x00600000, PPC_SPE_DOUBLE); //
9690 GEN_SPE(efdcmpeq,  efdcfs,    0x17, 0x0B, 0x00600000, 0x00180000, PPC_SPE_DOUBLE); //
9691 GEN_SPE(efdcfui,   efdcfsi,   0x18, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
9692 GEN_SPE(efdcfuf,   efdcfsf,   0x19, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
9693 GEN_SPE(efdctui,   efdctsi,   0x1A, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
9694 GEN_SPE(efdctuf,   efdctsf,   0x1B, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
9695 GEN_SPE(efdctuiz,  speundef,  0x1C, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_DOUBLE); //
9696 GEN_SPE(efdctsiz,  speundef,  0x1D, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_DOUBLE); //
9697 GEN_SPE(efdtstgt,  efdtstlt,  0x1E, 0x0B, 0x00600000, 0x00600000, PPC_SPE_DOUBLE); //
9698 GEN_SPE(efdtsteq,  speundef,  0x1F, 0x0B, 0x00600000, 0xFFFFFFFF, PPC_SPE_DOUBLE); //
9699
9700 static void gen_tbegin(DisasContext *ctx)
9701 {
9702     if (unlikely(!ctx->tm_enabled)) {
9703         gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_TM);
9704         return;
9705     }
9706     gen_helper_tbegin(cpu_env);
9707 }
9708
9709 #define GEN_TM_NOOP(name)                                      \
9710 static inline void gen_##name(DisasContext *ctx)               \
9711 {                                                              \
9712     if (unlikely(!ctx->tm_enabled)) {                          \
9713         gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_TM);   \
9714         return;                                                \
9715     }                                                          \
9716     /* Because tbegin always fails in QEMU, these user         \
9717      * space instructions all have a simple implementation:    \
9718      *                                                         \
9719      *     CR[0] = 0b0 || MSR[TS] || 0b0                       \
9720      *           = 0b0 || 0b00    || 0b0                       \
9721      */                                                        \
9722     tcg_gen_movi_i32(cpu_crf[0], 0);                           \
9723 }
9724
9725 GEN_TM_NOOP(tend);
9726 GEN_TM_NOOP(tabort);
9727 GEN_TM_NOOP(tabortwc);
9728 GEN_TM_NOOP(tabortwci);
9729 GEN_TM_NOOP(tabortdc);
9730 GEN_TM_NOOP(tabortdci);
9731 GEN_TM_NOOP(tsr);
9732
9733 static void gen_tcheck(DisasContext *ctx)
9734 {
9735     if (unlikely(!ctx->tm_enabled)) {
9736         gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_TM);
9737         return;
9738     }
9739     /* Because tbegin always fails, the tcheck implementation
9740      * is simple:
9741      *
9742      * CR[CRF] = TDOOMED || MSR[TS] || 0b0
9743      *         = 0b1 || 0b00 || 0b0
9744      */
9745     tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)], 0x8);
9746 }
9747
9748 #if defined(CONFIG_USER_ONLY)
9749 #define GEN_TM_PRIV_NOOP(name)                                 \
9750 static inline void gen_##name(DisasContext *ctx)               \
9751 {                                                              \
9752     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);           \
9753 }
9754
9755 #else
9756
9757 #define GEN_TM_PRIV_NOOP(name)                                 \
9758 static inline void gen_##name(DisasContext *ctx)               \
9759 {                                                              \
9760     if (unlikely(ctx->pr)) {                                   \
9761         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);       \
9762         return;                                                \
9763     }                                                          \
9764     if (unlikely(!ctx->tm_enabled)) {                          \
9765         gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_TM);   \
9766         return;                                                \
9767     }                                                          \
9768     /* Because tbegin always fails, the implementation is      \
9769      * simple:                                                 \
9770      *                                                         \
9771      *   CR[0] = 0b0 || MSR[TS] || 0b0                         \
9772      *         = 0b0 || 0b00 | 0b0                             \
9773      */                                                        \
9774     tcg_gen_movi_i32(cpu_crf[0], 0);                           \
9775 }
9776
9777 #endif
9778
9779 GEN_TM_PRIV_NOOP(treclaim);
9780 GEN_TM_PRIV_NOOP(trechkpt);
9781
9782 static opcode_t opcodes[] = {
9783 GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE),
9784 GEN_HANDLER(cmp, 0x1F, 0x00, 0x00, 0x00400000, PPC_INTEGER),
9785 GEN_HANDLER(cmpi, 0x0B, 0xFF, 0xFF, 0x00400000, PPC_INTEGER),
9786 GEN_HANDLER(cmpl, 0x1F, 0x00, 0x01, 0x00400000, PPC_INTEGER),
9787 GEN_HANDLER(cmpli, 0x0A, 0xFF, 0xFF, 0x00400000, PPC_INTEGER),
9788 GEN_HANDLER_E(cmpb, 0x1F, 0x1C, 0x0F, 0x00000001, PPC_NONE, PPC2_ISA205),
9789 GEN_HANDLER(isel, 0x1F, 0x0F, 0xFF, 0x00000001, PPC_ISEL),
9790 GEN_HANDLER(addi, 0x0E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9791 GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9792 GEN_HANDLER2(addic_, "addic.", 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9793 GEN_HANDLER(addis, 0x0F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9794 GEN_HANDLER(mulhw, 0x1F, 0x0B, 0x02, 0x00000400, PPC_INTEGER),
9795 GEN_HANDLER(mulhwu, 0x1F, 0x0B, 0x00, 0x00000400, PPC_INTEGER),
9796 GEN_HANDLER(mullw, 0x1F, 0x0B, 0x07, 0x00000000, PPC_INTEGER),
9797 GEN_HANDLER(mullwo, 0x1F, 0x0B, 0x17, 0x00000000, PPC_INTEGER),
9798 GEN_HANDLER(mulli, 0x07, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9799 #if defined(TARGET_PPC64)
9800 GEN_HANDLER(mulld, 0x1F, 0x09, 0x07, 0x00000000, PPC_64B),
9801 #endif
9802 GEN_HANDLER(neg, 0x1F, 0x08, 0x03, 0x0000F800, PPC_INTEGER),
9803 GEN_HANDLER(nego, 0x1F, 0x08, 0x13, 0x0000F800, PPC_INTEGER),
9804 GEN_HANDLER(subfic, 0x08, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9805 GEN_HANDLER2(andi_, "andi.", 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9806 GEN_HANDLER2(andis_, "andis.", 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9807 GEN_HANDLER(cntlzw, 0x1F, 0x1A, 0x00, 0x00000000, PPC_INTEGER),
9808 GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER),
9809 GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER),
9810 GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9811 GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9812 GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9813 GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9814 GEN_HANDLER(popcntb, 0x1F, 0x1A, 0x03, 0x0000F801, PPC_POPCNTB),
9815 GEN_HANDLER(popcntw, 0x1F, 0x1A, 0x0b, 0x0000F801, PPC_POPCNTWD),
9816 GEN_HANDLER_E(prtyw, 0x1F, 0x1A, 0x04, 0x0000F801, PPC_NONE, PPC2_ISA205),
9817 #if defined(TARGET_PPC64)
9818 GEN_HANDLER(popcntd, 0x1F, 0x1A, 0x0F, 0x0000F801, PPC_POPCNTWD),
9819 GEN_HANDLER(cntlzd, 0x1F, 0x1A, 0x01, 0x00000000, PPC_64B),
9820 GEN_HANDLER_E(prtyd, 0x1F, 0x1A, 0x05, 0x0000F801, PPC_NONE, PPC2_ISA205),
9821 GEN_HANDLER_E(bpermd, 0x1F, 0x1C, 0x07, 0x00000001, PPC_NONE, PPC2_PERM_ISA206),
9822 #endif
9823 GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9824 GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9825 GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9826 GEN_HANDLER(slw, 0x1F, 0x18, 0x00, 0x00000000, PPC_INTEGER),
9827 GEN_HANDLER(sraw, 0x1F, 0x18, 0x18, 0x00000000, PPC_INTEGER),
9828 GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER),
9829 GEN_HANDLER(srw, 0x1F, 0x18, 0x10, 0x00000000, PPC_INTEGER),
9830 #if defined(TARGET_PPC64)
9831 GEN_HANDLER(sld, 0x1F, 0x1B, 0x00, 0x00000000, PPC_64B),
9832 GEN_HANDLER(srad, 0x1F, 0x1A, 0x18, 0x00000000, PPC_64B),
9833 GEN_HANDLER2(sradi0, "sradi", 0x1F, 0x1A, 0x19, 0x00000000, PPC_64B),
9834 GEN_HANDLER2(sradi1, "sradi", 0x1F, 0x1B, 0x19, 0x00000000, PPC_64B),
9835 GEN_HANDLER(srd, 0x1F, 0x1B, 0x10, 0x00000000, PPC_64B),
9836 #endif
9837 GEN_HANDLER(frsqrtes, 0x3B, 0x1A, 0xFF, 0x001F07C0, PPC_FLOAT_FRSQRTES),
9838 GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT),
9839 GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT),
9840 GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT),
9841 GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT),
9842 GEN_HANDLER(fabs, 0x3F, 0x08, 0x08, 0x001F0000, PPC_FLOAT),
9843 GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT),
9844 GEN_HANDLER(fnabs, 0x3F, 0x08, 0x04, 0x001F0000, PPC_FLOAT),
9845 GEN_HANDLER(fneg, 0x3F, 0x08, 0x01, 0x001F0000, PPC_FLOAT),
9846 GEN_HANDLER_E(fcpsgn, 0x3F, 0x08, 0x00, 0x00000000, PPC_NONE, PPC2_ISA205),
9847 GEN_HANDLER_E(fmrgew, 0x3F, 0x06, 0x1E, 0x00000001, PPC_NONE, PPC2_VSX207),
9848 GEN_HANDLER_E(fmrgow, 0x3F, 0x06, 0x1A, 0x00000001, PPC_NONE, PPC2_VSX207),
9849 GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT),
9850 GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT),
9851 GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT),
9852 GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT),
9853 GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x00000000, PPC_FLOAT),
9854 GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006e0800, PPC_FLOAT),
9855 #if defined(TARGET_PPC64)
9856 GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B),
9857 GEN_HANDLER(lq, 0x38, 0xFF, 0xFF, 0x00000000, PPC_64BX),
9858 GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000000, PPC_64B),
9859 #endif
9860 GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9861 GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9862 GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_STRING),
9863 GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_STRING),
9864 GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_STRING),
9865 GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_STRING),
9866 GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FFF801, PPC_MEM_EIEIO),
9867 GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FFF801, PPC_MEM),
9868 GEN_HANDLER_E(lbarx, 0x1F, 0x14, 0x01, 0, PPC_NONE, PPC2_ATOMIC_ISA206),
9869 GEN_HANDLER_E(lharx, 0x1F, 0x14, 0x03, 0, PPC_NONE, PPC2_ATOMIC_ISA206),
9870 GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000000, PPC_RES),
9871 GEN_HANDLER_E(stbcx_, 0x1F, 0x16, 0x15, 0, PPC_NONE, PPC2_ATOMIC_ISA206),
9872 GEN_HANDLER_E(sthcx_, 0x1F, 0x16, 0x16, 0, PPC_NONE, PPC2_ATOMIC_ISA206),
9873 GEN_HANDLER2(stwcx_, "stwcx.", 0x1F, 0x16, 0x04, 0x00000000, PPC_RES),
9874 #if defined(TARGET_PPC64)
9875 GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000000, PPC_64B),
9876 GEN_HANDLER_E(lqarx, 0x1F, 0x14, 0x08, 0, PPC_NONE, PPC2_LSQ_ISA207),
9877 GEN_HANDLER2(stdcx_, "stdcx.", 0x1F, 0x16, 0x06, 0x00000000, PPC_64B),
9878 GEN_HANDLER_E(stqcx_, 0x1F, 0x16, 0x05, 0, PPC_NONE, PPC2_LSQ_ISA207),
9879 #endif
9880 GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x039FF801, PPC_MEM_SYNC),
9881 GEN_HANDLER(wait, 0x1F, 0x1E, 0x01, 0x03FFF801, PPC_WAIT),
9882 GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
9883 GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
9884 GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW),
9885 GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW),
9886 GEN_HANDLER_E(bctar, 0x13, 0x10, 0x11, 0, PPC_NONE, PPC2_BCTAR_ISA207),
9887 GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER),
9888 GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW),
9889 #if defined(TARGET_PPC64)
9890 GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B),
9891 GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64H),
9892 #endif
9893 GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFF01D, PPC_FLOW),
9894 GEN_HANDLER(tw, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW),
9895 GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
9896 #if defined(TARGET_PPC64)
9897 GEN_HANDLER(td, 0x1F, 0x04, 0x02, 0x00000001, PPC_64B),
9898 GEN_HANDLER(tdi, 0x02, 0xFF, 0xFF, 0x00000000, PPC_64B),
9899 #endif
9900 GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC),
9901 GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC),
9902 GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC),
9903 GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC),
9904 GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MFTB),
9905 GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC),
9906 #if defined(TARGET_PPC64)
9907 GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001EF801, PPC_64B),
9908 #endif
9909 GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC),
9910 GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000000, PPC_MISC),
9911 GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03C00001, PPC_CACHE),
9912 GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE),
9913 GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE),
9914 GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x00000001, PPC_CACHE),
9915 GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x00000001, PPC_CACHE),
9916 GEN_HANDLER_E(dcbtls, 0x1F, 0x06, 0x05, 0x02000001, PPC_BOOKE, PPC2_BOOKE206),
9917 GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZ),
9918 GEN_HANDLER(dst, 0x1F, 0x16, 0x0A, 0x01800001, PPC_ALTIVEC),
9919 GEN_HANDLER(dstst, 0x1F, 0x16, 0x0B, 0x02000001, PPC_ALTIVEC),
9920 GEN_HANDLER(dss, 0x1F, 0x16, 0x19, 0x019FF801, PPC_ALTIVEC),
9921 GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE_ICBI),
9922 GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_DCBA),
9923 GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT),
9924 GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT),
9925 GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT),
9926 GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT),
9927 #if defined(TARGET_PPC64)
9928 GEN_HANDLER2(mfsr_64b, "mfsr", 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT_64B),
9929 GEN_HANDLER2(mfsrin_64b, "mfsrin", 0x1F, 0x13, 0x14, 0x001F0001,
9930              PPC_SEGMENT_64B),
9931 GEN_HANDLER2(mtsr_64b, "mtsr", 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B),
9932 GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001,
9933              PPC_SEGMENT_64B),
9934 GEN_HANDLER2(slbmte, "slbmte", 0x1F, 0x12, 0x0C, 0x001F0001, PPC_SEGMENT_64B),
9935 GEN_HANDLER2(slbmfee, "slbmfee", 0x1F, 0x13, 0x1C, 0x001F0001, PPC_SEGMENT_64B),
9936 GEN_HANDLER2(slbmfev, "slbmfev", 0x1F, 0x13, 0x1A, 0x001F0001, PPC_SEGMENT_64B),
9937 #endif
9938 GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA),
9939 GEN_HANDLER(tlbiel, 0x1F, 0x12, 0x08, 0x03FF0001, PPC_MEM_TLBIE),
9940 GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE),
9941 GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC),
9942 #if defined(TARGET_PPC64)
9943 GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x03FFFC01, PPC_SLBI),
9944 GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI),
9945 #endif
9946 GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN),
9947 GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN),
9948 GEN_HANDLER(abs, 0x1F, 0x08, 0x0B, 0x0000F800, PPC_POWER_BR),
9949 GEN_HANDLER(abso, 0x1F, 0x08, 0x1B, 0x0000F800, PPC_POWER_BR),
9950 GEN_HANDLER(clcs, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR),
9951 GEN_HANDLER(div, 0x1F, 0x0B, 0x0A, 0x00000000, PPC_POWER_BR),
9952 GEN_HANDLER(divo, 0x1F, 0x0B, 0x1A, 0x00000000, PPC_POWER_BR),
9953 GEN_HANDLER(divs, 0x1F, 0x0B, 0x0B, 0x00000000, PPC_POWER_BR),
9954 GEN_HANDLER(divso, 0x1F, 0x0B, 0x1B, 0x00000000, PPC_POWER_BR),
9955 GEN_HANDLER(doz, 0x1F, 0x08, 0x08, 0x00000000, PPC_POWER_BR),
9956 GEN_HANDLER(dozo, 0x1F, 0x08, 0x18, 0x00000000, PPC_POWER_BR),
9957 GEN_HANDLER(dozi, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR),
9958 GEN_HANDLER(lscbx, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR),
9959 GEN_HANDLER(maskg, 0x1F, 0x1D, 0x00, 0x00000000, PPC_POWER_BR),
9960 GEN_HANDLER(maskir, 0x1F, 0x1D, 0x10, 0x00000000, PPC_POWER_BR),
9961 GEN_HANDLER(mul, 0x1F, 0x0B, 0x03, 0x00000000, PPC_POWER_BR),
9962 GEN_HANDLER(mulo, 0x1F, 0x0B, 0x13, 0x00000000, PPC_POWER_BR),
9963 GEN_HANDLER(nabs, 0x1F, 0x08, 0x0F, 0x00000000, PPC_POWER_BR),
9964 GEN_HANDLER(nabso, 0x1F, 0x08, 0x1F, 0x00000000, PPC_POWER_BR),
9965 GEN_HANDLER(rlmi, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR),
9966 GEN_HANDLER(rrib, 0x1F, 0x19, 0x10, 0x00000000, PPC_POWER_BR),
9967 GEN_HANDLER(sle, 0x1F, 0x19, 0x04, 0x00000000, PPC_POWER_BR),
9968 GEN_HANDLER(sleq, 0x1F, 0x19, 0x06, 0x00000000, PPC_POWER_BR),
9969 GEN_HANDLER(sliq, 0x1F, 0x18, 0x05, 0x00000000, PPC_POWER_BR),
9970 GEN_HANDLER(slliq, 0x1F, 0x18, 0x07, 0x00000000, PPC_POWER_BR),
9971 GEN_HANDLER(sllq, 0x1F, 0x18, 0x06, 0x00000000, PPC_POWER_BR),
9972 GEN_HANDLER(slq, 0x1F, 0x18, 0x04, 0x00000000, PPC_POWER_BR),
9973 GEN_HANDLER(sraiq, 0x1F, 0x18, 0x1D, 0x00000000, PPC_POWER_BR),
9974 GEN_HANDLER(sraq, 0x1F, 0x18, 0x1C, 0x00000000, PPC_POWER_BR),
9975 GEN_HANDLER(sre, 0x1F, 0x19, 0x14, 0x00000000, PPC_POWER_BR),
9976 GEN_HANDLER(srea, 0x1F, 0x19, 0x1C, 0x00000000, PPC_POWER_BR),
9977 GEN_HANDLER(sreq, 0x1F, 0x19, 0x16, 0x00000000, PPC_POWER_BR),
9978 GEN_HANDLER(sriq, 0x1F, 0x18, 0x15, 0x00000000, PPC_POWER_BR),
9979 GEN_HANDLER(srliq, 0x1F, 0x18, 0x17, 0x00000000, PPC_POWER_BR),
9980 GEN_HANDLER(srlq, 0x1F, 0x18, 0x16, 0x00000000, PPC_POWER_BR),
9981 GEN_HANDLER(srq, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR),
9982 GEN_HANDLER(dsa, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC),
9983 GEN_HANDLER(esa, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC),
9984 GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC),
9985 GEN_HANDLER2(tlbld_6xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB),
9986 GEN_HANDLER2(tlbli_6xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB),
9987 GEN_HANDLER2(tlbld_74xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_74xx_TLB),
9988 GEN_HANDLER2(tlbli_74xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_74xx_TLB),
9989 GEN_HANDLER(clf, 0x1F, 0x16, 0x03, 0x03E00000, PPC_POWER),
9990 GEN_HANDLER(cli, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER),
9991 GEN_HANDLER(dclst, 0x1F, 0x16, 0x13, 0x03E00000, PPC_POWER),
9992 GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER),
9993 GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER),
9994 GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER),
9995 GEN_HANDLER(lfq, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
9996 GEN_HANDLER(lfqu, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
9997 GEN_HANDLER(lfqux, 0x1F, 0x17, 0x19, 0x00000001, PPC_POWER2),
9998 GEN_HANDLER(lfqx, 0x1F, 0x17, 0x18, 0x00000001, PPC_POWER2),
9999 GEN_HANDLER(stfq, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
10000 GEN_HANDLER(stfqu, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
10001 GEN_HANDLER(stfqux, 0x1F, 0x17, 0x1D, 0x00000001, PPC_POWER2),
10002 GEN_HANDLER(stfqx, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2),
10003 GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_MFAPIDI),
10004 GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_TLBIVA),
10005 GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_DCR),
10006 GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_DCR),
10007 GEN_HANDLER(mfdcrx, 0x1F, 0x03, 0x08, 0x00000000, PPC_DCRX),
10008 GEN_HANDLER(mtdcrx, 0x1F, 0x03, 0x0C, 0x00000000, PPC_DCRX),
10009 GEN_HANDLER(mfdcrux, 0x1F, 0x03, 0x09, 0x00000000, PPC_DCRUX),
10010 GEN_HANDLER(mtdcrux, 0x1F, 0x03, 0x0D, 0x00000000, PPC_DCRUX),
10011 GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON),
10012 GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON),
10013 GEN_HANDLER2(icbt_40x, "icbt", 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_ICBT),
10014 GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON),
10015 GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON),
10016 GEN_HANDLER2(rfci_40x, "rfci", 0x13, 0x13, 0x01, 0x03FF8001, PPC_40x_EXCP),
10017 GEN_HANDLER_E(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE, PPC2_BOOKE206),
10018 GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_RFDI),
10019 GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_RFMCI),
10020 GEN_HANDLER2(tlbre_40x, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB),
10021 GEN_HANDLER2(tlbsx_40x, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB),
10022 GEN_HANDLER2(tlbwe_40x, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB),
10023 GEN_HANDLER2(tlbre_440, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE),
10024 GEN_HANDLER2(tlbsx_440, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE),
10025 GEN_HANDLER2(tlbwe_440, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE),
10026 GEN_HANDLER2_E(tlbre_booke206, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001,
10027                PPC_NONE, PPC2_BOOKE206),
10028 GEN_HANDLER2_E(tlbsx_booke206, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000,
10029                PPC_NONE, PPC2_BOOKE206),
10030 GEN_HANDLER2_E(tlbwe_booke206, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001,
10031                PPC_NONE, PPC2_BOOKE206),
10032 GEN_HANDLER2_E(tlbivax_booke206, "tlbivax", 0x1F, 0x12, 0x18, 0x00000001,
10033                PPC_NONE, PPC2_BOOKE206),
10034 GEN_HANDLER2_E(tlbilx_booke206, "tlbilx", 0x1F, 0x12, 0x00, 0x03800001,
10035                PPC_NONE, PPC2_BOOKE206),
10036 GEN_HANDLER2_E(msgsnd, "msgsnd", 0x1F, 0x0E, 0x06, 0x03ff0001,
10037                PPC_NONE, PPC2_PRCNTL),
10038 GEN_HANDLER2_E(msgclr, "msgclr", 0x1F, 0x0E, 0x07, 0x03ff0001,
10039                PPC_NONE, PPC2_PRCNTL),
10040 GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE),
10041 GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000E7C01, PPC_WRTEE),
10042 GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC),
10043 GEN_HANDLER_E(mbar, 0x1F, 0x16, 0x1a, 0x001FF801,
10044               PPC_BOOKE, PPC2_BOOKE206),
10045 GEN_HANDLER(msync_4xx, 0x1F, 0x16, 0x12, 0x03FFF801, PPC_BOOKE),
10046 GEN_HANDLER2_E(icbt_440, "icbt", 0x1F, 0x16, 0x00, 0x03E00001,
10047                PPC_BOOKE, PPC2_BOOKE206),
10048 GEN_HANDLER(lvsl, 0x1f, 0x06, 0x00, 0x00000001, PPC_ALTIVEC),
10049 GEN_HANDLER(lvsr, 0x1f, 0x06, 0x01, 0x00000001, PPC_ALTIVEC),
10050 GEN_HANDLER(mfvscr, 0x04, 0x2, 0x18, 0x001ff800, PPC_ALTIVEC),
10051 GEN_HANDLER(mtvscr, 0x04, 0x2, 0x19, 0x03ff0000, PPC_ALTIVEC),
10052 GEN_HANDLER(vmladduhm, 0x04, 0x11, 0xFF, 0x00000000, PPC_ALTIVEC),
10053 GEN_HANDLER2(evsel0, "evsel", 0x04, 0x1c, 0x09, 0x00000000, PPC_SPE),
10054 GEN_HANDLER2(evsel1, "evsel", 0x04, 0x1d, 0x09, 0x00000000, PPC_SPE),
10055 GEN_HANDLER2(evsel2, "evsel", 0x04, 0x1e, 0x09, 0x00000000, PPC_SPE),
10056 GEN_HANDLER2(evsel3, "evsel", 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE),
10057
10058 #undef GEN_INT_ARITH_ADD
10059 #undef GEN_INT_ARITH_ADD_CONST
10060 #define GEN_INT_ARITH_ADD(name, opc3, add_ca, compute_ca, compute_ov)         \
10061 GEN_HANDLER(name, 0x1F, 0x0A, opc3, 0x00000000, PPC_INTEGER),
10062 #define GEN_INT_ARITH_ADD_CONST(name, opc3, const_val,                        \
10063                                 add_ca, compute_ca, compute_ov)               \
10064 GEN_HANDLER(name, 0x1F, 0x0A, opc3, 0x0000F800, PPC_INTEGER),
10065 GEN_INT_ARITH_ADD(add, 0x08, 0, 0, 0)
10066 GEN_INT_ARITH_ADD(addo, 0x18, 0, 0, 1)
10067 GEN_INT_ARITH_ADD(addc, 0x00, 0, 1, 0)
10068 GEN_INT_ARITH_ADD(addco, 0x10, 0, 1, 1)
10069 GEN_INT_ARITH_ADD(adde, 0x04, 1, 1, 0)
10070 GEN_INT_ARITH_ADD(addeo, 0x14, 1, 1, 1)
10071 GEN_INT_ARITH_ADD_CONST(addme, 0x07, -1LL, 1, 1, 0)
10072 GEN_INT_ARITH_ADD_CONST(addmeo, 0x17, -1LL, 1, 1, 1)
10073 GEN_INT_ARITH_ADD_CONST(addze, 0x06, 0, 1, 1, 0)
10074 GEN_INT_ARITH_ADD_CONST(addzeo, 0x16, 0, 1, 1, 1)
10075
10076 #undef GEN_INT_ARITH_DIVW
10077 #define GEN_INT_ARITH_DIVW(name, opc3, sign, compute_ov)                      \
10078 GEN_HANDLER(name, 0x1F, 0x0B, opc3, 0x00000000, PPC_INTEGER)
10079 GEN_INT_ARITH_DIVW(divwu, 0x0E, 0, 0),
10080 GEN_INT_ARITH_DIVW(divwuo, 0x1E, 0, 1),
10081 GEN_INT_ARITH_DIVW(divw, 0x0F, 1, 0),
10082 GEN_INT_ARITH_DIVW(divwo, 0x1F, 1, 1),
10083 GEN_HANDLER_E(divwe, 0x1F, 0x0B, 0x0D, 0, PPC_NONE, PPC2_DIVE_ISA206),
10084 GEN_HANDLER_E(divweo, 0x1F, 0x0B, 0x1D, 0, PPC_NONE, PPC2_DIVE_ISA206),
10085 GEN_HANDLER_E(divweu, 0x1F, 0x0B, 0x0C, 0, PPC_NONE, PPC2_DIVE_ISA206),
10086 GEN_HANDLER_E(divweuo, 0x1F, 0x0B, 0x1C, 0, PPC_NONE, PPC2_DIVE_ISA206),
10087
10088 #if defined(TARGET_PPC64)
10089 #undef GEN_INT_ARITH_DIVD
10090 #define GEN_INT_ARITH_DIVD(name, opc3, sign, compute_ov)                      \
10091 GEN_HANDLER(name, 0x1F, 0x09, opc3, 0x00000000, PPC_64B)
10092 GEN_INT_ARITH_DIVD(divdu, 0x0E, 0, 0),
10093 GEN_INT_ARITH_DIVD(divduo, 0x1E, 0, 1),
10094 GEN_INT_ARITH_DIVD(divd, 0x0F, 1, 0),
10095 GEN_INT_ARITH_DIVD(divdo, 0x1F, 1, 1),
10096
10097 GEN_HANDLER_E(divdeu, 0x1F, 0x09, 0x0C, 0, PPC_NONE, PPC2_DIVE_ISA206),
10098 GEN_HANDLER_E(divdeuo, 0x1F, 0x09, 0x1C, 0, PPC_NONE, PPC2_DIVE_ISA206),
10099 GEN_HANDLER_E(divde, 0x1F, 0x09, 0x0D, 0, PPC_NONE, PPC2_DIVE_ISA206),
10100 GEN_HANDLER_E(divdeo, 0x1F, 0x09, 0x1D, 0, PPC_NONE, PPC2_DIVE_ISA206),
10101
10102 #undef GEN_INT_ARITH_MUL_HELPER
10103 #define GEN_INT_ARITH_MUL_HELPER(name, opc3)                                  \
10104 GEN_HANDLER(name, 0x1F, 0x09, opc3, 0x00000000, PPC_64B)
10105 GEN_INT_ARITH_MUL_HELPER(mulhdu, 0x00),
10106 GEN_INT_ARITH_MUL_HELPER(mulhd, 0x02),
10107 GEN_INT_ARITH_MUL_HELPER(mulldo, 0x17),
10108 #endif
10109
10110 #undef GEN_INT_ARITH_SUBF
10111 #undef GEN_INT_ARITH_SUBF_CONST
10112 #define GEN_INT_ARITH_SUBF(name, opc3, add_ca, compute_ca, compute_ov)        \
10113 GEN_HANDLER(name, 0x1F, 0x08, opc3, 0x00000000, PPC_INTEGER),
10114 #define GEN_INT_ARITH_SUBF_CONST(name, opc3, const_val,                       \
10115                                 add_ca, compute_ca, compute_ov)               \
10116 GEN_HANDLER(name, 0x1F, 0x08, opc3, 0x0000F800, PPC_INTEGER),
10117 GEN_INT_ARITH_SUBF(subf, 0x01, 0, 0, 0)
10118 GEN_INT_ARITH_SUBF(subfo, 0x11, 0, 0, 1)
10119 GEN_INT_ARITH_SUBF(subfc, 0x00, 0, 1, 0)
10120 GEN_INT_ARITH_SUBF(subfco, 0x10, 0, 1, 1)
10121 GEN_INT_ARITH_SUBF(subfe, 0x04, 1, 1, 0)
10122 GEN_INT_ARITH_SUBF(subfeo, 0x14, 1, 1, 1)
10123 GEN_INT_ARITH_SUBF_CONST(subfme, 0x07, -1LL, 1, 1, 0)
10124 GEN_INT_ARITH_SUBF_CONST(subfmeo, 0x17, -1LL, 1, 1, 1)
10125 GEN_INT_ARITH_SUBF_CONST(subfze, 0x06, 0, 1, 1, 0)
10126 GEN_INT_ARITH_SUBF_CONST(subfzeo, 0x16, 0, 1, 1, 1)
10127
10128 #undef GEN_LOGICAL1
10129 #undef GEN_LOGICAL2
10130 #define GEN_LOGICAL2(name, tcg_op, opc, type)                                 \
10131 GEN_HANDLER(name, 0x1F, 0x1C, opc, 0x00000000, type)
10132 #define GEN_LOGICAL1(name, tcg_op, opc, type)                                 \
10133 GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, type)
10134 GEN_LOGICAL2(and, tcg_gen_and_tl, 0x00, PPC_INTEGER),
10135 GEN_LOGICAL2(andc, tcg_gen_andc_tl, 0x01, PPC_INTEGER),
10136 GEN_LOGICAL2(eqv, tcg_gen_eqv_tl, 0x08, PPC_INTEGER),
10137 GEN_LOGICAL1(extsb, tcg_gen_ext8s_tl, 0x1D, PPC_INTEGER),
10138 GEN_LOGICAL1(extsh, tcg_gen_ext16s_tl, 0x1C, PPC_INTEGER),
10139 GEN_LOGICAL2(nand, tcg_gen_nand_tl, 0x0E, PPC_INTEGER),
10140 GEN_LOGICAL2(nor, tcg_gen_nor_tl, 0x03, PPC_INTEGER),
10141 GEN_LOGICAL2(orc, tcg_gen_orc_tl, 0x0C, PPC_INTEGER),
10142 #if defined(TARGET_PPC64)
10143 GEN_LOGICAL1(extsw, tcg_gen_ext32s_tl, 0x1E, PPC_64B),
10144 #endif
10145
10146 #if defined(TARGET_PPC64)
10147 #undef GEN_PPC64_R2
10148 #undef GEN_PPC64_R4
10149 #define GEN_PPC64_R2(name, opc1, opc2)                                        \
10150 GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B),\
10151 GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000,   \
10152              PPC_64B)
10153 #define GEN_PPC64_R4(name, opc1, opc2)                                        \
10154 GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B),\
10155 GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x01, 0xFF, 0x00000000,   \
10156              PPC_64B),                                                        \
10157 GEN_HANDLER2(name##2, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000,   \
10158              PPC_64B),                                                        \
10159 GEN_HANDLER2(name##3, stringify(name), opc1, opc2 | 0x11, 0xFF, 0x00000000,   \
10160              PPC_64B)
10161 GEN_PPC64_R4(rldicl, 0x1E, 0x00),
10162 GEN_PPC64_R4(rldicr, 0x1E, 0x02),
10163 GEN_PPC64_R4(rldic, 0x1E, 0x04),
10164 GEN_PPC64_R2(rldcl, 0x1E, 0x08),
10165 GEN_PPC64_R2(rldcr, 0x1E, 0x09),
10166 GEN_PPC64_R4(rldimi, 0x1E, 0x06),
10167 #endif
10168
10169 #undef _GEN_FLOAT_ACB
10170 #undef GEN_FLOAT_ACB
10171 #undef _GEN_FLOAT_AB
10172 #undef GEN_FLOAT_AB
10173 #undef _GEN_FLOAT_AC
10174 #undef GEN_FLOAT_AC
10175 #undef GEN_FLOAT_B
10176 #undef GEN_FLOAT_BS
10177 #define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat, set_fprf, type)           \
10178 GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, type)
10179 #define GEN_FLOAT_ACB(name, op2, set_fprf, type)                              \
10180 _GEN_FLOAT_ACB(name, name, 0x3F, op2, 0, set_fprf, type),                     \
10181 _GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, set_fprf, type)
10182 #define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
10183 GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)
10184 #define GEN_FLOAT_AB(name, op2, inval, set_fprf, type)                        \
10185 _GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0, set_fprf, type),               \
10186 _GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1, set_fprf, type)
10187 #define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
10188 GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)
10189 #define GEN_FLOAT_AC(name, op2, inval, set_fprf, type)                        \
10190 _GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0, set_fprf, type),               \
10191 _GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1, set_fprf, type)
10192 #define GEN_FLOAT_B(name, op2, op3, set_fprf, type)                           \
10193 GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, type)
10194 #define GEN_FLOAT_BS(name, op1, op2, set_fprf, type)                          \
10195 GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, type)
10196
10197 GEN_FLOAT_AB(add, 0x15, 0x000007C0, 1, PPC_FLOAT),
10198 GEN_FLOAT_AB(div, 0x12, 0x000007C0, 1, PPC_FLOAT),
10199 GEN_FLOAT_AC(mul, 0x19, 0x0000F800, 1, PPC_FLOAT),
10200 GEN_FLOAT_BS(re, 0x3F, 0x18, 1, PPC_FLOAT_EXT),
10201 GEN_FLOAT_BS(res, 0x3B, 0x18, 1, PPC_FLOAT_FRES),
10202 GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A, 1, PPC_FLOAT_FRSQRTE),
10203 _GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0, 0, PPC_FLOAT_FSEL),
10204 GEN_FLOAT_AB(sub, 0x14, 0x000007C0, 1, PPC_FLOAT),
10205 GEN_FLOAT_ACB(madd, 0x1D, 1, PPC_FLOAT),
10206 GEN_FLOAT_ACB(msub, 0x1C, 1, PPC_FLOAT),
10207 GEN_FLOAT_ACB(nmadd, 0x1F, 1, PPC_FLOAT),
10208 GEN_FLOAT_ACB(nmsub, 0x1E, 1, PPC_FLOAT),
10209 GEN_HANDLER_E(ftdiv, 0x3F, 0x00, 0x04, 1, PPC_NONE, PPC2_FP_TST_ISA206),
10210 GEN_HANDLER_E(ftsqrt, 0x3F, 0x00, 0x05, 1, PPC_NONE, PPC2_FP_TST_ISA206),
10211 GEN_FLOAT_B(ctiw, 0x0E, 0x00, 0, PPC_FLOAT),
10212 GEN_HANDLER_E(fctiwu, 0x3F, 0x0E, 0x04, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
10213 GEN_FLOAT_B(ctiwz, 0x0F, 0x00, 0, PPC_FLOAT),
10214 GEN_HANDLER_E(fctiwuz, 0x3F, 0x0F, 0x04, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
10215 GEN_FLOAT_B(rsp, 0x0C, 0x00, 1, PPC_FLOAT),
10216 GEN_HANDLER_E(fcfid, 0x3F, 0x0E, 0x1A, 0x001F0000, PPC_NONE, PPC2_FP_CVT_S64),
10217 GEN_HANDLER_E(fcfids, 0x3B, 0x0E, 0x1A, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
10218 GEN_HANDLER_E(fcfidu, 0x3F, 0x0E, 0x1E, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
10219 GEN_HANDLER_E(fcfidus, 0x3B, 0x0E, 0x1E, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
10220 GEN_HANDLER_E(fctid, 0x3F, 0x0E, 0x19, 0x001F0000, PPC_NONE, PPC2_FP_CVT_S64),
10221 GEN_HANDLER_E(fctidu, 0x3F, 0x0E, 0x1D, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
10222 GEN_HANDLER_E(fctidz, 0x3F, 0x0F, 0x19, 0x001F0000, PPC_NONE, PPC2_FP_CVT_S64),
10223 GEN_HANDLER_E(fctiduz, 0x3F, 0x0F, 0x1D, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
10224 GEN_FLOAT_B(rin, 0x08, 0x0C, 1, PPC_FLOAT_EXT),
10225 GEN_FLOAT_B(riz, 0x08, 0x0D, 1, PPC_FLOAT_EXT),
10226 GEN_FLOAT_B(rip, 0x08, 0x0E, 1, PPC_FLOAT_EXT),
10227 GEN_FLOAT_B(rim, 0x08, 0x0F, 1, PPC_FLOAT_EXT),
10228
10229 #undef GEN_LD
10230 #undef GEN_LDU
10231 #undef GEN_LDUX
10232 #undef GEN_LDX_E
10233 #undef GEN_LDS
10234 #define GEN_LD(name, ldop, opc, type)                                         \
10235 GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
10236 #define GEN_LDU(name, ldop, opc, type)                                        \
10237 GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
10238 #define GEN_LDUX(name, ldop, opc2, opc3, type)                                \
10239 GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type),
10240 #define GEN_LDX_E(name, ldop, opc2, opc3, type, type2)                        \
10241 GEN_HANDLER_E(name##x, 0x1F, opc2, opc3, 0x00000001, type, type2),
10242 #define GEN_LDS(name, ldop, op, type)                                         \
10243 GEN_LD(name, ldop, op | 0x20, type)                                           \
10244 GEN_LDU(name, ldop, op | 0x21, type)                                          \
10245 GEN_LDUX(name, ldop, 0x17, op | 0x01, type)                                   \
10246 GEN_LDX(name, ldop, 0x17, op | 0x00, type)
10247
10248 GEN_LDS(lbz, ld8u, 0x02, PPC_INTEGER)
10249 GEN_LDS(lha, ld16s, 0x0A, PPC_INTEGER)
10250 GEN_LDS(lhz, ld16u, 0x08, PPC_INTEGER)
10251 GEN_LDS(lwz, ld32u, 0x00, PPC_INTEGER)
10252 #if defined(TARGET_PPC64)
10253 GEN_LDUX(lwa, ld32s, 0x15, 0x0B, PPC_64B)
10254 GEN_LDX(lwa, ld32s, 0x15, 0x0A, PPC_64B)
10255 GEN_LDUX(ld, ld64, 0x15, 0x01, PPC_64B)
10256 GEN_LDX(ld, ld64, 0x15, 0x00, PPC_64B)
10257 GEN_LDX_E(ldbr, ld64ur, 0x14, 0x10, PPC_NONE, PPC2_DBRX)
10258 #endif
10259 GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER)
10260 GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER)
10261
10262 #undef GEN_ST
10263 #undef GEN_STU
10264 #undef GEN_STUX
10265 #undef GEN_STX_E
10266 #undef GEN_STS
10267 #define GEN_ST(name, stop, opc, type)                                         \
10268 GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
10269 #define GEN_STU(name, stop, opc, type)                                        \
10270 GEN_HANDLER(stop##u, opc, 0xFF, 0xFF, 0x00000000, type),
10271 #define GEN_STUX(name, stop, opc2, opc3, type)                                \
10272 GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type),
10273 #define GEN_STX_E(name, stop, opc2, opc3, type, type2)                        \
10274 GEN_HANDLER_E(name##x, 0x1F, opc2, opc3, 0x00000001, type, type2),
10275 #define GEN_STS(name, stop, op, type)                                         \
10276 GEN_ST(name, stop, op | 0x20, type)                                           \
10277 GEN_STU(name, stop, op | 0x21, type)                                          \
10278 GEN_STUX(name, stop, 0x17, op | 0x01, type)                                   \
10279 GEN_STX(name, stop, 0x17, op | 0x00, type)
10280
10281 GEN_STS(stb, st8, 0x06, PPC_INTEGER)
10282 GEN_STS(sth, st16, 0x0C, PPC_INTEGER)
10283 GEN_STS(stw, st32, 0x04, PPC_INTEGER)
10284 #if defined(TARGET_PPC64)
10285 GEN_STUX(std, st64, 0x15, 0x05, PPC_64B)
10286 GEN_STX(std, st64, 0x15, 0x04, PPC_64B)
10287 GEN_STX_E(stdbr, st64r, 0x14, 0x14, PPC_NONE, PPC2_DBRX)
10288 #endif
10289 GEN_STX(sthbr, st16r, 0x16, 0x1C, PPC_INTEGER)
10290 GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER)
10291
10292 #undef GEN_LDF
10293 #undef GEN_LDUF
10294 #undef GEN_LDUXF
10295 #undef GEN_LDXF
10296 #undef GEN_LDFS
10297 #define GEN_LDF(name, ldop, opc, type)                                        \
10298 GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
10299 #define GEN_LDUF(name, ldop, opc, type)                                       \
10300 GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
10301 #define GEN_LDUXF(name, ldop, opc, type)                                      \
10302 GEN_HANDLER(name##ux, 0x1F, 0x17, opc, 0x00000001, type),
10303 #define GEN_LDXF(name, ldop, opc2, opc3, type)                                \
10304 GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type),
10305 #define GEN_LDFS(name, ldop, op, type)                                        \
10306 GEN_LDF(name, ldop, op | 0x20, type)                                          \
10307 GEN_LDUF(name, ldop, op | 0x21, type)                                         \
10308 GEN_LDUXF(name, ldop, op | 0x01, type)                                        \
10309 GEN_LDXF(name, ldop, 0x17, op | 0x00, type)
10310
10311 GEN_LDFS(lfd, ld64, 0x12, PPC_FLOAT)
10312 GEN_LDFS(lfs, ld32fs, 0x10, PPC_FLOAT)
10313 GEN_HANDLER_E(lfiwax, 0x1f, 0x17, 0x1a, 0x00000001, PPC_NONE, PPC2_ISA205),
10314 GEN_HANDLER_E(lfiwzx, 0x1f, 0x17, 0x1b, 0x1, PPC_NONE, PPC2_FP_CVT_ISA206),
10315 GEN_HANDLER_E(lfdp, 0x39, 0xFF, 0xFF, 0x00200003, PPC_NONE, PPC2_ISA205),
10316 GEN_HANDLER_E(lfdpx, 0x1F, 0x17, 0x18, 0x00200001, PPC_NONE, PPC2_ISA205),
10317
10318 #undef GEN_STF
10319 #undef GEN_STUF
10320 #undef GEN_STUXF
10321 #undef GEN_STXF
10322 #undef GEN_STFS
10323 #define GEN_STF(name, stop, opc, type)                                        \
10324 GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
10325 #define GEN_STUF(name, stop, opc, type)                                       \
10326 GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
10327 #define GEN_STUXF(name, stop, opc, type)                                      \
10328 GEN_HANDLER(name##ux, 0x1F, 0x17, opc, 0x00000001, type),
10329 #define GEN_STXF(name, stop, opc2, opc3, type)                                \
10330 GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type),
10331 #define GEN_STFS(name, stop, op, type)                                        \
10332 GEN_STF(name, stop, op | 0x20, type)                                          \
10333 GEN_STUF(name, stop, op | 0x21, type)                                         \
10334 GEN_STUXF(name, stop, op | 0x01, type)                                        \
10335 GEN_STXF(name, stop, 0x17, op | 0x00, type)
10336
10337 GEN_STFS(stfd, st64, 0x16, PPC_FLOAT)
10338 GEN_STFS(stfs, st32fs, 0x14, PPC_FLOAT)
10339 GEN_STXF(stfiw, st32fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX)
10340 GEN_HANDLER_E(stfdp, 0x3D, 0xFF, 0xFF, 0x00200003, PPC_NONE, PPC2_ISA205),
10341 GEN_HANDLER_E(stfdpx, 0x1F, 0x17, 0x1C, 0x00200001, PPC_NONE, PPC2_ISA205),
10342
10343 #undef GEN_CRLOGIC
10344 #define GEN_CRLOGIC(name, tcg_op, opc)                                        \
10345 GEN_HANDLER(name, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER)
10346 GEN_CRLOGIC(crand, tcg_gen_and_i32, 0x08),
10347 GEN_CRLOGIC(crandc, tcg_gen_andc_i32, 0x04),
10348 GEN_CRLOGIC(creqv, tcg_gen_eqv_i32, 0x09),
10349 GEN_CRLOGIC(crnand, tcg_gen_nand_i32, 0x07),
10350 GEN_CRLOGIC(crnor, tcg_gen_nor_i32, 0x01),
10351 GEN_CRLOGIC(cror, tcg_gen_or_i32, 0x0E),
10352 GEN_CRLOGIC(crorc, tcg_gen_orc_i32, 0x0D),
10353 GEN_CRLOGIC(crxor, tcg_gen_xor_i32, 0x06),
10354
10355 #undef GEN_MAC_HANDLER
10356 #define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
10357 GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC)
10358 GEN_MAC_HANDLER(macchw, 0x0C, 0x05),
10359 GEN_MAC_HANDLER(macchwo, 0x0C, 0x15),
10360 GEN_MAC_HANDLER(macchws, 0x0C, 0x07),
10361 GEN_MAC_HANDLER(macchwso, 0x0C, 0x17),
10362 GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06),
10363 GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16),
10364 GEN_MAC_HANDLER(macchwu, 0x0C, 0x04),
10365 GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14),
10366 GEN_MAC_HANDLER(machhw, 0x0C, 0x01),
10367 GEN_MAC_HANDLER(machhwo, 0x0C, 0x11),
10368 GEN_MAC_HANDLER(machhws, 0x0C, 0x03),
10369 GEN_MAC_HANDLER(machhwso, 0x0C, 0x13),
10370 GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02),
10371 GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12),
10372 GEN_MAC_HANDLER(machhwu, 0x0C, 0x00),
10373 GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10),
10374 GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D),
10375 GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D),
10376 GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F),
10377 GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F),
10378 GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C),
10379 GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C),
10380 GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E),
10381 GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E),
10382 GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05),
10383 GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15),
10384 GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07),
10385 GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17),
10386 GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01),
10387 GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11),
10388 GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03),
10389 GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13),
10390 GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D),
10391 GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D),
10392 GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F),
10393 GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F),
10394 GEN_MAC_HANDLER(mulchw, 0x08, 0x05),
10395 GEN_MAC_HANDLER(mulchwu, 0x08, 0x04),
10396 GEN_MAC_HANDLER(mulhhw, 0x08, 0x01),
10397 GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00),
10398 GEN_MAC_HANDLER(mullhw, 0x08, 0x0D),
10399 GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C),
10400
10401 #undef GEN_VR_LDX
10402 #undef GEN_VR_STX
10403 #undef GEN_VR_LVE
10404 #undef GEN_VR_STVE
10405 #define GEN_VR_LDX(name, opc2, opc3)                                          \
10406 GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
10407 #define GEN_VR_STX(name, opc2, opc3)                                          \
10408 GEN_HANDLER(st##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
10409 #define GEN_VR_LVE(name, opc2, opc3)                                    \
10410     GEN_HANDLER(lve##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
10411 #define GEN_VR_STVE(name, opc2, opc3)                                   \
10412     GEN_HANDLER(stve##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
10413 GEN_VR_LDX(lvx, 0x07, 0x03),
10414 GEN_VR_LDX(lvxl, 0x07, 0x0B),
10415 GEN_VR_LVE(bx, 0x07, 0x00),
10416 GEN_VR_LVE(hx, 0x07, 0x01),
10417 GEN_VR_LVE(wx, 0x07, 0x02),
10418 GEN_VR_STX(svx, 0x07, 0x07),
10419 GEN_VR_STX(svxl, 0x07, 0x0F),
10420 GEN_VR_STVE(bx, 0x07, 0x04),
10421 GEN_VR_STVE(hx, 0x07, 0x05),
10422 GEN_VR_STVE(wx, 0x07, 0x06),
10423
10424 #undef GEN_VX_LOGICAL
10425 #define GEN_VX_LOGICAL(name, tcg_op, opc2, opc3)                        \
10426 GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
10427
10428 #undef GEN_VX_LOGICAL_207
10429 #define GEN_VX_LOGICAL_207(name, tcg_op, opc2, opc3) \
10430 GEN_HANDLER_E(name, 0x04, opc2, opc3, 0x00000000, PPC_NONE, PPC2_ALTIVEC_207)
10431
10432 GEN_VX_LOGICAL(vand, tcg_gen_and_i64, 2, 16),
10433 GEN_VX_LOGICAL(vandc, tcg_gen_andc_i64, 2, 17),
10434 GEN_VX_LOGICAL(vor, tcg_gen_or_i64, 2, 18),
10435 GEN_VX_LOGICAL(vxor, tcg_gen_xor_i64, 2, 19),
10436 GEN_VX_LOGICAL(vnor, tcg_gen_nor_i64, 2, 20),
10437 GEN_VX_LOGICAL_207(veqv, tcg_gen_eqv_i64, 2, 26),
10438 GEN_VX_LOGICAL_207(vnand, tcg_gen_nand_i64, 2, 22),
10439 GEN_VX_LOGICAL_207(vorc, tcg_gen_orc_i64, 2, 21),
10440
10441 #undef GEN_VXFORM
10442 #define GEN_VXFORM(name, opc2, opc3)                                    \
10443 GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
10444
10445 #undef GEN_VXFORM_207
10446 #define GEN_VXFORM_207(name, opc2, opc3) \
10447 GEN_HANDLER_E(name, 0x04, opc2, opc3, 0x00000000, PPC_NONE, PPC2_ALTIVEC_207)
10448
10449 #undef GEN_VXFORM_DUAL
10450 #define GEN_VXFORM_DUAL(name0, name1, opc2, opc3, type0, type1) \
10451 GEN_HANDLER_E(name0##_##name1, 0x4, opc2, opc3, 0x00000000, type0, type1)
10452
10453 #undef GEN_VXRFORM_DUAL
10454 #define GEN_VXRFORM_DUAL(name0, name1, opc2, opc3, tp0, tp1) \
10455 GEN_HANDLER_E(name0##_##name1, 0x4, opc2, opc3, 0x00000000, tp0, tp1), \
10456 GEN_HANDLER_E(name0##_##name1, 0x4, opc2, (opc3 | 0x10), 0x00000000, tp0, tp1),
10457
10458 GEN_VXFORM(vaddubm, 0, 0),
10459 GEN_VXFORM(vadduhm, 0, 1),
10460 GEN_VXFORM(vadduwm, 0, 2),
10461 GEN_VXFORM_207(vaddudm, 0, 3),
10462 GEN_VXFORM_DUAL(vsububm, bcdadd, 0, 16, PPC_ALTIVEC, PPC_NONE),
10463 GEN_VXFORM_DUAL(vsubuhm, bcdsub, 0, 17, PPC_ALTIVEC, PPC_NONE),
10464 GEN_VXFORM(vsubuwm, 0, 18),
10465 GEN_VXFORM_207(vsubudm, 0, 19),
10466 GEN_VXFORM(vmaxub, 1, 0),
10467 GEN_VXFORM(vmaxuh, 1, 1),
10468 GEN_VXFORM(vmaxuw, 1, 2),
10469 GEN_VXFORM_207(vmaxud, 1, 3),
10470 GEN_VXFORM(vmaxsb, 1, 4),
10471 GEN_VXFORM(vmaxsh, 1, 5),
10472 GEN_VXFORM(vmaxsw, 1, 6),
10473 GEN_VXFORM_207(vmaxsd, 1, 7),
10474 GEN_VXFORM(vminub, 1, 8),
10475 GEN_VXFORM(vminuh, 1, 9),
10476 GEN_VXFORM(vminuw, 1, 10),
10477 GEN_VXFORM_207(vminud, 1, 11),
10478 GEN_VXFORM(vminsb, 1, 12),
10479 GEN_VXFORM(vminsh, 1, 13),
10480 GEN_VXFORM(vminsw, 1, 14),
10481 GEN_VXFORM_207(vminsd, 1, 15),
10482 GEN_VXFORM(vavgub, 1, 16),
10483 GEN_VXFORM(vavguh, 1, 17),
10484 GEN_VXFORM(vavguw, 1, 18),
10485 GEN_VXFORM(vavgsb, 1, 20),
10486 GEN_VXFORM(vavgsh, 1, 21),
10487 GEN_VXFORM(vavgsw, 1, 22),
10488 GEN_VXFORM(vmrghb, 6, 0),
10489 GEN_VXFORM(vmrghh, 6, 1),
10490 GEN_VXFORM(vmrghw, 6, 2),
10491 GEN_VXFORM(vmrglb, 6, 4),
10492 GEN_VXFORM(vmrglh, 6, 5),
10493 GEN_VXFORM(vmrglw, 6, 6),
10494 GEN_VXFORM_207(vmrgew, 6, 30),
10495 GEN_VXFORM_207(vmrgow, 6, 26),
10496 GEN_VXFORM(vmuloub, 4, 0),
10497 GEN_VXFORM(vmulouh, 4, 1),
10498 GEN_VXFORM_DUAL(vmulouw, vmuluwm, 4, 2, PPC_ALTIVEC, PPC_NONE),
10499 GEN_VXFORM(vmulosb, 4, 4),
10500 GEN_VXFORM(vmulosh, 4, 5),
10501 GEN_VXFORM_207(vmulosw, 4, 6),
10502 GEN_VXFORM(vmuleub, 4, 8),
10503 GEN_VXFORM(vmuleuh, 4, 9),
10504 GEN_VXFORM_207(vmuleuw, 4, 10),
10505 GEN_VXFORM(vmulesb, 4, 12),
10506 GEN_VXFORM(vmulesh, 4, 13),
10507 GEN_VXFORM_207(vmulesw, 4, 14),
10508 GEN_VXFORM(vslb, 2, 4),
10509 GEN_VXFORM(vslh, 2, 5),
10510 GEN_VXFORM(vslw, 2, 6),
10511 GEN_VXFORM_207(vsld, 2, 23),
10512 GEN_VXFORM(vsrb, 2, 8),
10513 GEN_VXFORM(vsrh, 2, 9),
10514 GEN_VXFORM(vsrw, 2, 10),
10515 GEN_VXFORM_207(vsrd, 2, 27),
10516 GEN_VXFORM(vsrab, 2, 12),
10517 GEN_VXFORM(vsrah, 2, 13),
10518 GEN_VXFORM(vsraw, 2, 14),
10519 GEN_VXFORM_207(vsrad, 2, 15),
10520 GEN_VXFORM(vslo, 6, 16),
10521 GEN_VXFORM(vsro, 6, 17),
10522 GEN_VXFORM(vaddcuw, 0, 6),
10523 GEN_VXFORM(vsubcuw, 0, 22),
10524 GEN_VXFORM(vaddubs, 0, 8),
10525 GEN_VXFORM(vadduhs, 0, 9),
10526 GEN_VXFORM(vadduws, 0, 10),
10527 GEN_VXFORM(vaddsbs, 0, 12),
10528 GEN_VXFORM(vaddshs, 0, 13),
10529 GEN_VXFORM(vaddsws, 0, 14),
10530 GEN_VXFORM_DUAL(vsububs, bcdadd, 0, 24, PPC_ALTIVEC, PPC_NONE),
10531 GEN_VXFORM_DUAL(vsubuhs, bcdsub, 0, 25, PPC_ALTIVEC, PPC_NONE),
10532 GEN_VXFORM(vsubuws, 0, 26),
10533 GEN_VXFORM(vsubsbs, 0, 28),
10534 GEN_VXFORM(vsubshs, 0, 29),
10535 GEN_VXFORM(vsubsws, 0, 30),
10536 GEN_VXFORM_207(vadduqm, 0, 4),
10537 GEN_VXFORM_207(vaddcuq, 0, 5),
10538 GEN_VXFORM_DUAL(vaddeuqm, vaddecuq, 30, 0xFF, PPC_NONE, PPC2_ALTIVEC_207),
10539 GEN_VXFORM_207(vsubuqm, 0, 20),
10540 GEN_VXFORM_207(vsubcuq, 0, 21),
10541 GEN_VXFORM_DUAL(vsubeuqm, vsubecuq, 31, 0xFF, PPC_NONE, PPC2_ALTIVEC_207),
10542 GEN_VXFORM(vrlb, 2, 0),
10543 GEN_VXFORM(vrlh, 2, 1),
10544 GEN_VXFORM(vrlw, 2, 2),
10545 GEN_VXFORM_207(vrld, 2, 3),
10546 GEN_VXFORM(vsl, 2, 7),
10547 GEN_VXFORM(vsr, 2, 11),
10548 GEN_VXFORM(vpkuhum, 7, 0),
10549 GEN_VXFORM(vpkuwum, 7, 1),
10550 GEN_VXFORM_207(vpkudum, 7, 17),
10551 GEN_VXFORM(vpkuhus, 7, 2),
10552 GEN_VXFORM(vpkuwus, 7, 3),
10553 GEN_VXFORM_207(vpkudus, 7, 19),
10554 GEN_VXFORM(vpkshus, 7, 4),
10555 GEN_VXFORM(vpkswus, 7, 5),
10556 GEN_VXFORM_207(vpksdus, 7, 21),
10557 GEN_VXFORM(vpkshss, 7, 6),
10558 GEN_VXFORM(vpkswss, 7, 7),
10559 GEN_VXFORM_207(vpksdss, 7, 23),
10560 GEN_VXFORM(vpkpx, 7, 12),
10561 GEN_VXFORM(vsum4ubs, 4, 24),
10562 GEN_VXFORM(vsum4sbs, 4, 28),
10563 GEN_VXFORM(vsum4shs, 4, 25),
10564 GEN_VXFORM(vsum2sws, 4, 26),
10565 GEN_VXFORM(vsumsws, 4, 30),
10566 GEN_VXFORM(vaddfp, 5, 0),
10567 GEN_VXFORM(vsubfp, 5, 1),
10568 GEN_VXFORM(vmaxfp, 5, 16),
10569 GEN_VXFORM(vminfp, 5, 17),
10570
10571 #undef GEN_VXRFORM1
10572 #undef GEN_VXRFORM
10573 #define GEN_VXRFORM1(opname, name, str, opc2, opc3)                     \
10574     GEN_HANDLER2(name, str, 0x4, opc2, opc3, 0x00000000, PPC_ALTIVEC),
10575 #define GEN_VXRFORM(name, opc2, opc3)                                \
10576     GEN_VXRFORM1(name, name, #name, opc2, opc3)                      \
10577     GEN_VXRFORM1(name##_dot, name##_, #name ".", opc2, (opc3 | (0x1 << 4)))
10578 GEN_VXRFORM(vcmpequb, 3, 0)
10579 GEN_VXRFORM(vcmpequh, 3, 1)
10580 GEN_VXRFORM(vcmpequw, 3, 2)
10581 GEN_VXRFORM(vcmpgtsb, 3, 12)
10582 GEN_VXRFORM(vcmpgtsh, 3, 13)
10583 GEN_VXRFORM(vcmpgtsw, 3, 14)
10584 GEN_VXRFORM(vcmpgtub, 3, 8)
10585 GEN_VXRFORM(vcmpgtuh, 3, 9)
10586 GEN_VXRFORM(vcmpgtuw, 3, 10)
10587 GEN_VXRFORM_DUAL(vcmpeqfp, vcmpequd, 3, 3, PPC_ALTIVEC, PPC_NONE)
10588 GEN_VXRFORM(vcmpgefp, 3, 7)
10589 GEN_VXRFORM_DUAL(vcmpgtfp, vcmpgtud, 3, 11, PPC_ALTIVEC, PPC_NONE)
10590 GEN_VXRFORM_DUAL(vcmpbfp, vcmpgtsd, 3, 15, PPC_ALTIVEC, PPC_NONE)
10591
10592 #undef GEN_VXFORM_SIMM
10593 #define GEN_VXFORM_SIMM(name, opc2, opc3)                               \
10594     GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
10595 GEN_VXFORM_SIMM(vspltisb, 6, 12),
10596 GEN_VXFORM_SIMM(vspltish, 6, 13),
10597 GEN_VXFORM_SIMM(vspltisw, 6, 14),
10598
10599 #undef GEN_VXFORM_NOA
10600 #define GEN_VXFORM_NOA(name, opc2, opc3)                                \
10601     GEN_HANDLER(name, 0x04, opc2, opc3, 0x001f0000, PPC_ALTIVEC)
10602 GEN_VXFORM_NOA(vupkhsb, 7, 8),
10603 GEN_VXFORM_NOA(vupkhsh, 7, 9),
10604 GEN_VXFORM_207(vupkhsw, 7, 25),
10605 GEN_VXFORM_NOA(vupklsb, 7, 10),
10606 GEN_VXFORM_NOA(vupklsh, 7, 11),
10607 GEN_VXFORM_207(vupklsw, 7, 27),
10608 GEN_VXFORM_NOA(vupkhpx, 7, 13),
10609 GEN_VXFORM_NOA(vupklpx, 7, 15),
10610 GEN_VXFORM_NOA(vrefp, 5, 4),
10611 GEN_VXFORM_NOA(vrsqrtefp, 5, 5),
10612 GEN_VXFORM_NOA(vexptefp, 5, 6),
10613 GEN_VXFORM_NOA(vlogefp, 5, 7),
10614 GEN_VXFORM_NOA(vrfim, 5, 11),
10615 GEN_VXFORM_NOA(vrfin, 5, 8),
10616 GEN_VXFORM_NOA(vrfip, 5, 10),
10617 GEN_VXFORM_NOA(vrfiz, 5, 9),
10618
10619 #undef GEN_VXFORM_UIMM
10620 #define GEN_VXFORM_UIMM(name, opc2, opc3)                               \
10621     GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
10622 GEN_VXFORM_UIMM(vspltb, 6, 8),
10623 GEN_VXFORM_UIMM(vsplth, 6, 9),
10624 GEN_VXFORM_UIMM(vspltw, 6, 10),
10625 GEN_VXFORM_UIMM(vcfux, 5, 12),
10626 GEN_VXFORM_UIMM(vcfsx, 5, 13),
10627 GEN_VXFORM_UIMM(vctuxs, 5, 14),
10628 GEN_VXFORM_UIMM(vctsxs, 5, 15),
10629
10630 #undef GEN_VAFORM_PAIRED
10631 #define GEN_VAFORM_PAIRED(name0, name1, opc2)                           \
10632     GEN_HANDLER(name0##_##name1, 0x04, opc2, 0xFF, 0x00000000, PPC_ALTIVEC)
10633 GEN_VAFORM_PAIRED(vmhaddshs, vmhraddshs, 16),
10634 GEN_VAFORM_PAIRED(vmsumubm, vmsummbm, 18),
10635 GEN_VAFORM_PAIRED(vmsumuhm, vmsumuhs, 19),
10636 GEN_VAFORM_PAIRED(vmsumshm, vmsumshs, 20),
10637 GEN_VAFORM_PAIRED(vsel, vperm, 21),
10638 GEN_VAFORM_PAIRED(vmaddfp, vnmsubfp, 23),
10639
10640 GEN_VXFORM_DUAL(vclzb, vpopcntb, 1, 28, PPC_NONE, PPC2_ALTIVEC_207),
10641 GEN_VXFORM_DUAL(vclzh, vpopcnth, 1, 29, PPC_NONE, PPC2_ALTIVEC_207),
10642 GEN_VXFORM_DUAL(vclzw, vpopcntw, 1, 30, PPC_NONE, PPC2_ALTIVEC_207),
10643 GEN_VXFORM_DUAL(vclzd, vpopcntd, 1, 31, PPC_NONE, PPC2_ALTIVEC_207),
10644
10645 GEN_VXFORM_207(vbpermq, 6, 21),
10646 GEN_VXFORM_207(vgbbd, 6, 20),
10647 GEN_VXFORM_207(vpmsumb, 4, 16),
10648 GEN_VXFORM_207(vpmsumh, 4, 17),
10649 GEN_VXFORM_207(vpmsumw, 4, 18),
10650 GEN_VXFORM_207(vpmsumd, 4, 19),
10651
10652 GEN_VXFORM_207(vsbox, 4, 23),
10653
10654 GEN_VXFORM_DUAL(vcipher, vcipherlast, 4, 20, PPC_NONE, PPC2_ALTIVEC_207),
10655 GEN_VXFORM_DUAL(vncipher, vncipherlast, 4, 21, PPC_NONE, PPC2_ALTIVEC_207),
10656
10657 GEN_VXFORM_207(vshasigmaw, 1, 26),
10658 GEN_VXFORM_207(vshasigmad, 1, 27),
10659
10660 GEN_VXFORM_DUAL(vsldoi, vpermxor, 22, 0xFF, PPC_ALTIVEC, PPC_NONE),
10661
10662 GEN_HANDLER_E(lxsdx, 0x1F, 0x0C, 0x12, 0, PPC_NONE, PPC2_VSX),
10663 GEN_HANDLER_E(lxsiwax, 0x1F, 0x0C, 0x02, 0, PPC_NONE, PPC2_VSX207),
10664 GEN_HANDLER_E(lxsiwzx, 0x1F, 0x0C, 0x00, 0, PPC_NONE, PPC2_VSX207),
10665 GEN_HANDLER_E(lxsspx, 0x1F, 0x0C, 0x10, 0, PPC_NONE, PPC2_VSX207),
10666 GEN_HANDLER_E(lxvd2x, 0x1F, 0x0C, 0x1A, 0, PPC_NONE, PPC2_VSX),
10667 GEN_HANDLER_E(lxvdsx, 0x1F, 0x0C, 0x0A, 0, PPC_NONE, PPC2_VSX),
10668 GEN_HANDLER_E(lxvw4x, 0x1F, 0x0C, 0x18, 0, PPC_NONE, PPC2_VSX),
10669
10670 GEN_HANDLER_E(stxsdx, 0x1F, 0xC, 0x16, 0, PPC_NONE, PPC2_VSX),
10671 GEN_HANDLER_E(stxsiwx, 0x1F, 0xC, 0x04, 0, PPC_NONE, PPC2_VSX207),
10672 GEN_HANDLER_E(stxsspx, 0x1F, 0xC, 0x14, 0, PPC_NONE, PPC2_VSX207),
10673 GEN_HANDLER_E(stxvd2x, 0x1F, 0xC, 0x1E, 0, PPC_NONE, PPC2_VSX),
10674 GEN_HANDLER_E(stxvw4x, 0x1F, 0xC, 0x1C, 0, PPC_NONE, PPC2_VSX),
10675
10676 GEN_HANDLER_E(mfvsrwz, 0x1F, 0x13, 0x03, 0x0000F800, PPC_NONE, PPC2_VSX207),
10677 GEN_HANDLER_E(mtvsrwa, 0x1F, 0x13, 0x06, 0x0000F800, PPC_NONE, PPC2_VSX207),
10678 GEN_HANDLER_E(mtvsrwz, 0x1F, 0x13, 0x07, 0x0000F800, PPC_NONE, PPC2_VSX207),
10679 #if defined(TARGET_PPC64)
10680 GEN_HANDLER_E(mfvsrd, 0x1F, 0x13, 0x01, 0x0000F800, PPC_NONE, PPC2_VSX207),
10681 GEN_HANDLER_E(mtvsrd, 0x1F, 0x13, 0x05, 0x0000F800, PPC_NONE, PPC2_VSX207),
10682 #endif
10683
10684 #undef GEN_XX2FORM
10685 #define GEN_XX2FORM(name, opc2, opc3, fl2)                           \
10686 GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0, opc3, 0, PPC_NONE, fl2), \
10687 GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 1, opc3, 0, PPC_NONE, fl2)
10688
10689 #undef GEN_XX3FORM
10690 #define GEN_XX3FORM(name, opc2, opc3, fl2)                           \
10691 GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0, opc3, 0, PPC_NONE, fl2), \
10692 GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 1, opc3, 0, PPC_NONE, fl2), \
10693 GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 2, opc3, 0, PPC_NONE, fl2), \
10694 GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 3, opc3, 0, PPC_NONE, fl2)
10695
10696 #undef GEN_XX2IFORM
10697 #define GEN_XX2IFORM(name, opc2, opc3, fl2)                           \
10698 GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0, opc3, 1, PPC_NONE, fl2), \
10699 GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 1, opc3, 1, PPC_NONE, fl2), \
10700 GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 2, opc3, 1, PPC_NONE, fl2), \
10701 GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 3, opc3, 1, PPC_NONE, fl2)
10702
10703 #undef GEN_XX3_RC_FORM
10704 #define GEN_XX3_RC_FORM(name, opc2, opc3, fl2)                          \
10705 GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0x00, opc3 | 0x00, 0, PPC_NONE, fl2), \
10706 GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0x01, opc3 | 0x00, 0, PPC_NONE, fl2), \
10707 GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0x02, opc3 | 0x00, 0, PPC_NONE, fl2), \
10708 GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0x03, opc3 | 0x00, 0, PPC_NONE, fl2), \
10709 GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0x00, opc3 | 0x10, 0, PPC_NONE, fl2), \
10710 GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0x01, opc3 | 0x10, 0, PPC_NONE, fl2), \
10711 GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0x02, opc3 | 0x10, 0, PPC_NONE, fl2), \
10712 GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0x03, opc3 | 0x10, 0, PPC_NONE, fl2)
10713
10714 #undef GEN_XX3FORM_DM
10715 #define GEN_XX3FORM_DM(name, opc2, opc3) \
10716 GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x00, opc3|0x00, 0, PPC_NONE, PPC2_VSX),\
10717 GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x01, opc3|0x00, 0, PPC_NONE, PPC2_VSX),\
10718 GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x02, opc3|0x00, 0, PPC_NONE, PPC2_VSX),\
10719 GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x03, opc3|0x00, 0, PPC_NONE, PPC2_VSX),\
10720 GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x00, opc3|0x04, 0, PPC_NONE, PPC2_VSX),\
10721 GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x01, opc3|0x04, 0, PPC_NONE, PPC2_VSX),\
10722 GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x02, opc3|0x04, 0, PPC_NONE, PPC2_VSX),\
10723 GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x03, opc3|0x04, 0, PPC_NONE, PPC2_VSX),\
10724 GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x00, opc3|0x08, 0, PPC_NONE, PPC2_VSX),\
10725 GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x01, opc3|0x08, 0, PPC_NONE, PPC2_VSX),\
10726 GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x02, opc3|0x08, 0, PPC_NONE, PPC2_VSX),\
10727 GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x03, opc3|0x08, 0, PPC_NONE, PPC2_VSX),\
10728 GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x00, opc3|0x0C, 0, PPC_NONE, PPC2_VSX),\
10729 GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x01, opc3|0x0C, 0, PPC_NONE, PPC2_VSX),\
10730 GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x02, opc3|0x0C, 0, PPC_NONE, PPC2_VSX),\
10731 GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x03, opc3|0x0C, 0, PPC_NONE, PPC2_VSX)
10732
10733 GEN_XX2FORM(xsabsdp, 0x12, 0x15, PPC2_VSX),
10734 GEN_XX2FORM(xsnabsdp, 0x12, 0x16, PPC2_VSX),
10735 GEN_XX2FORM(xsnegdp, 0x12, 0x17, PPC2_VSX),
10736 GEN_XX3FORM(xscpsgndp, 0x00, 0x16, PPC2_VSX),
10737
10738 GEN_XX2FORM(xvabsdp, 0x12, 0x1D, PPC2_VSX),
10739 GEN_XX2FORM(xvnabsdp, 0x12, 0x1E, PPC2_VSX),
10740 GEN_XX2FORM(xvnegdp, 0x12, 0x1F, PPC2_VSX),
10741 GEN_XX3FORM(xvcpsgndp, 0x00, 0x1E, PPC2_VSX),
10742 GEN_XX2FORM(xvabssp, 0x12, 0x19, PPC2_VSX),
10743 GEN_XX2FORM(xvnabssp, 0x12, 0x1A, PPC2_VSX),
10744 GEN_XX2FORM(xvnegsp, 0x12, 0x1B, PPC2_VSX),
10745 GEN_XX3FORM(xvcpsgnsp, 0x00, 0x1A, PPC2_VSX),
10746
10747 GEN_XX3FORM(xsadddp, 0x00, 0x04, PPC2_VSX),
10748 GEN_XX3FORM(xssubdp, 0x00, 0x05, PPC2_VSX),
10749 GEN_XX3FORM(xsmuldp, 0x00, 0x06, PPC2_VSX),
10750 GEN_XX3FORM(xsdivdp, 0x00, 0x07, PPC2_VSX),
10751 GEN_XX2FORM(xsredp,  0x14, 0x05, PPC2_VSX),
10752 GEN_XX2FORM(xssqrtdp,  0x16, 0x04, PPC2_VSX),
10753 GEN_XX2FORM(xsrsqrtedp,  0x14, 0x04, PPC2_VSX),
10754 GEN_XX3FORM(xstdivdp,  0x14, 0x07, PPC2_VSX),
10755 GEN_XX2FORM(xstsqrtdp,  0x14, 0x06, PPC2_VSX),
10756 GEN_XX3FORM(xsmaddadp, 0x04, 0x04, PPC2_VSX),
10757 GEN_XX3FORM(xsmaddmdp, 0x04, 0x05, PPC2_VSX),
10758 GEN_XX3FORM(xsmsubadp, 0x04, 0x06, PPC2_VSX),
10759 GEN_XX3FORM(xsmsubmdp, 0x04, 0x07, PPC2_VSX),
10760 GEN_XX3FORM(xsnmaddadp, 0x04, 0x14, PPC2_VSX),
10761 GEN_XX3FORM(xsnmaddmdp, 0x04, 0x15, PPC2_VSX),
10762 GEN_XX3FORM(xsnmsubadp, 0x04, 0x16, PPC2_VSX),
10763 GEN_XX3FORM(xsnmsubmdp, 0x04, 0x17, PPC2_VSX),
10764 GEN_XX2IFORM(xscmpodp,  0x0C, 0x05, PPC2_VSX),
10765 GEN_XX2IFORM(xscmpudp,  0x0C, 0x04, PPC2_VSX),
10766 GEN_XX3FORM(xsmaxdp, 0x00, 0x14, PPC2_VSX),
10767 GEN_XX3FORM(xsmindp, 0x00, 0x15, PPC2_VSX),
10768 GEN_XX2FORM(xscvdpsp, 0x12, 0x10, PPC2_VSX),
10769 GEN_XX2FORM(xscvdpspn, 0x16, 0x10, PPC2_VSX207),
10770 GEN_XX2FORM(xscvspdp, 0x12, 0x14, PPC2_VSX),
10771 GEN_XX2FORM(xscvspdpn, 0x16, 0x14, PPC2_VSX207),
10772 GEN_XX2FORM(xscvdpsxds, 0x10, 0x15, PPC2_VSX),
10773 GEN_XX2FORM(xscvdpsxws, 0x10, 0x05, PPC2_VSX),
10774 GEN_XX2FORM(xscvdpuxds, 0x10, 0x14, PPC2_VSX),
10775 GEN_XX2FORM(xscvdpuxws, 0x10, 0x04, PPC2_VSX),
10776 GEN_XX2FORM(xscvsxddp, 0x10, 0x17, PPC2_VSX),
10777 GEN_XX2FORM(xscvuxddp, 0x10, 0x16, PPC2_VSX),
10778 GEN_XX2FORM(xsrdpi, 0x12, 0x04, PPC2_VSX),
10779 GEN_XX2FORM(xsrdpic, 0x16, 0x06, PPC2_VSX),
10780 GEN_XX2FORM(xsrdpim, 0x12, 0x07, PPC2_VSX),
10781 GEN_XX2FORM(xsrdpip, 0x12, 0x06, PPC2_VSX),
10782 GEN_XX2FORM(xsrdpiz, 0x12, 0x05, PPC2_VSX),
10783
10784 GEN_XX3FORM(xsaddsp, 0x00, 0x00, PPC2_VSX207),
10785 GEN_XX3FORM(xssubsp, 0x00, 0x01, PPC2_VSX207),
10786 GEN_XX3FORM(xsmulsp, 0x00, 0x02, PPC2_VSX207),
10787 GEN_XX3FORM(xsdivsp, 0x00, 0x03, PPC2_VSX207),
10788 GEN_XX2FORM(xsresp,  0x14, 0x01, PPC2_VSX207),
10789 GEN_XX2FORM(xsrsp, 0x12, 0x11, PPC2_VSX207),
10790 GEN_XX2FORM(xssqrtsp,  0x16, 0x00, PPC2_VSX207),
10791 GEN_XX2FORM(xsrsqrtesp,  0x14, 0x00, PPC2_VSX207),
10792 GEN_XX3FORM(xsmaddasp, 0x04, 0x00, PPC2_VSX207),
10793 GEN_XX3FORM(xsmaddmsp, 0x04, 0x01, PPC2_VSX207),
10794 GEN_XX3FORM(xsmsubasp, 0x04, 0x02, PPC2_VSX207),
10795 GEN_XX3FORM(xsmsubmsp, 0x04, 0x03, PPC2_VSX207),
10796 GEN_XX3FORM(xsnmaddasp, 0x04, 0x10, PPC2_VSX207),
10797 GEN_XX3FORM(xsnmaddmsp, 0x04, 0x11, PPC2_VSX207),
10798 GEN_XX3FORM(xsnmsubasp, 0x04, 0x12, PPC2_VSX207),
10799 GEN_XX3FORM(xsnmsubmsp, 0x04, 0x13, PPC2_VSX207),
10800 GEN_XX2FORM(xscvsxdsp, 0x10, 0x13, PPC2_VSX207),
10801 GEN_XX2FORM(xscvuxdsp, 0x10, 0x12, PPC2_VSX207),
10802
10803 GEN_XX3FORM(xvadddp, 0x00, 0x0C, PPC2_VSX),
10804 GEN_XX3FORM(xvsubdp, 0x00, 0x0D, PPC2_VSX),
10805 GEN_XX3FORM(xvmuldp, 0x00, 0x0E, PPC2_VSX),
10806 GEN_XX3FORM(xvdivdp, 0x00, 0x0F, PPC2_VSX),
10807 GEN_XX2FORM(xvredp,  0x14, 0x0D, PPC2_VSX),
10808 GEN_XX2FORM(xvsqrtdp,  0x16, 0x0C, PPC2_VSX),
10809 GEN_XX2FORM(xvrsqrtedp,  0x14, 0x0C, PPC2_VSX),
10810 GEN_XX3FORM(xvtdivdp, 0x14, 0x0F, PPC2_VSX),
10811 GEN_XX2FORM(xvtsqrtdp, 0x14, 0x0E, PPC2_VSX),
10812 GEN_XX3FORM(xvmaddadp, 0x04, 0x0C, PPC2_VSX),
10813 GEN_XX3FORM(xvmaddmdp, 0x04, 0x0D, PPC2_VSX),
10814 GEN_XX3FORM(xvmsubadp, 0x04, 0x0E, PPC2_VSX),
10815 GEN_XX3FORM(xvmsubmdp, 0x04, 0x0F, PPC2_VSX),
10816 GEN_XX3FORM(xvnmaddadp, 0x04, 0x1C, PPC2_VSX),
10817 GEN_XX3FORM(xvnmaddmdp, 0x04, 0x1D, PPC2_VSX),
10818 GEN_XX3FORM(xvnmsubadp, 0x04, 0x1E, PPC2_VSX),
10819 GEN_XX3FORM(xvnmsubmdp, 0x04, 0x1F, PPC2_VSX),
10820 GEN_XX3FORM(xvmaxdp, 0x00, 0x1C, PPC2_VSX),
10821 GEN_XX3FORM(xvmindp, 0x00, 0x1D, PPC2_VSX),
10822 GEN_XX3_RC_FORM(xvcmpeqdp, 0x0C, 0x0C, PPC2_VSX),
10823 GEN_XX3_RC_FORM(xvcmpgtdp, 0x0C, 0x0D, PPC2_VSX),
10824 GEN_XX3_RC_FORM(xvcmpgedp, 0x0C, 0x0E, PPC2_VSX),
10825 GEN_XX2FORM(xvcvdpsp, 0x12, 0x18, PPC2_VSX),
10826 GEN_XX2FORM(xvcvdpsxds, 0x10, 0x1D, PPC2_VSX),
10827 GEN_XX2FORM(xvcvdpsxws, 0x10, 0x0D, PPC2_VSX),
10828 GEN_XX2FORM(xvcvdpuxds, 0x10, 0x1C, PPC2_VSX),
10829 GEN_XX2FORM(xvcvdpuxws, 0x10, 0x0C, PPC2_VSX),
10830 GEN_XX2FORM(xvcvsxddp, 0x10, 0x1F, PPC2_VSX),
10831 GEN_XX2FORM(xvcvuxddp, 0x10, 0x1E, PPC2_VSX),
10832 GEN_XX2FORM(xvcvsxwdp, 0x10, 0x0F, PPC2_VSX),
10833 GEN_XX2FORM(xvcvuxwdp, 0x10, 0x0E, PPC2_VSX),
10834 GEN_XX2FORM(xvrdpi, 0x12, 0x0C, PPC2_VSX),
10835 GEN_XX2FORM(xvrdpic, 0x16, 0x0E, PPC2_VSX),
10836 GEN_XX2FORM(xvrdpim, 0x12, 0x0F, PPC2_VSX),
10837 GEN_XX2FORM(xvrdpip, 0x12, 0x0E, PPC2_VSX),
10838 GEN_XX2FORM(xvrdpiz, 0x12, 0x0D, PPC2_VSX),
10839
10840 GEN_XX3FORM(xvaddsp, 0x00, 0x08, PPC2_VSX),
10841 GEN_XX3FORM(xvsubsp, 0x00, 0x09, PPC2_VSX),
10842 GEN_XX3FORM(xvmulsp, 0x00, 0x0A, PPC2_VSX),
10843 GEN_XX3FORM(xvdivsp, 0x00, 0x0B, PPC2_VSX),
10844 GEN_XX2FORM(xvresp, 0x14, 0x09, PPC2_VSX),
10845 GEN_XX2FORM(xvsqrtsp, 0x16, 0x08, PPC2_VSX),
10846 GEN_XX2FORM(xvrsqrtesp, 0x14, 0x08, PPC2_VSX),
10847 GEN_XX3FORM(xvtdivsp, 0x14, 0x0B, PPC2_VSX),
10848 GEN_XX2FORM(xvtsqrtsp, 0x14, 0x0A, PPC2_VSX),
10849 GEN_XX3FORM(xvmaddasp, 0x04, 0x08, PPC2_VSX),
10850 GEN_XX3FORM(xvmaddmsp, 0x04, 0x09, PPC2_VSX),
10851 GEN_XX3FORM(xvmsubasp, 0x04, 0x0A, PPC2_VSX),
10852 GEN_XX3FORM(xvmsubmsp, 0x04, 0x0B, PPC2_VSX),
10853 GEN_XX3FORM(xvnmaddasp, 0x04, 0x18, PPC2_VSX),
10854 GEN_XX3FORM(xvnmaddmsp, 0x04, 0x19, PPC2_VSX),
10855 GEN_XX3FORM(xvnmsubasp, 0x04, 0x1A, PPC2_VSX),
10856 GEN_XX3FORM(xvnmsubmsp, 0x04, 0x1B, PPC2_VSX),
10857 GEN_XX3FORM(xvmaxsp, 0x00, 0x18, PPC2_VSX),
10858 GEN_XX3FORM(xvminsp, 0x00, 0x19, PPC2_VSX),
10859 GEN_XX3_RC_FORM(xvcmpeqsp, 0x0C, 0x08, PPC2_VSX),
10860 GEN_XX3_RC_FORM(xvcmpgtsp, 0x0C, 0x09, PPC2_VSX),
10861 GEN_XX3_RC_FORM(xvcmpgesp, 0x0C, 0x0A, PPC2_VSX),
10862 GEN_XX2FORM(xvcvspdp, 0x12, 0x1C, PPC2_VSX),
10863 GEN_XX2FORM(xvcvspsxds, 0x10, 0x19, PPC2_VSX),
10864 GEN_XX2FORM(xvcvspsxws, 0x10, 0x09, PPC2_VSX),
10865 GEN_XX2FORM(xvcvspuxds, 0x10, 0x18, PPC2_VSX),
10866 GEN_XX2FORM(xvcvspuxws, 0x10, 0x08, PPC2_VSX),
10867 GEN_XX2FORM(xvcvsxdsp, 0x10, 0x1B, PPC2_VSX),
10868 GEN_XX2FORM(xvcvuxdsp, 0x10, 0x1A, PPC2_VSX),
10869 GEN_XX2FORM(xvcvsxwsp, 0x10, 0x0B, PPC2_VSX),
10870 GEN_XX2FORM(xvcvuxwsp, 0x10, 0x0A, PPC2_VSX),
10871 GEN_XX2FORM(xvrspi, 0x12, 0x08, PPC2_VSX),
10872 GEN_XX2FORM(xvrspic, 0x16, 0x0A, PPC2_VSX),
10873 GEN_XX2FORM(xvrspim, 0x12, 0x0B, PPC2_VSX),
10874 GEN_XX2FORM(xvrspip, 0x12, 0x0A, PPC2_VSX),
10875 GEN_XX2FORM(xvrspiz, 0x12, 0x09, PPC2_VSX),
10876
10877 #undef VSX_LOGICAL
10878 #define VSX_LOGICAL(name, opc2, opc3, fl2) \
10879 GEN_XX3FORM(name, opc2, opc3, fl2)
10880
10881 VSX_LOGICAL(xxland, 0x8, 0x10, PPC2_VSX),
10882 VSX_LOGICAL(xxlandc, 0x8, 0x11, PPC2_VSX),
10883 VSX_LOGICAL(xxlor, 0x8, 0x12, PPC2_VSX),
10884 VSX_LOGICAL(xxlxor, 0x8, 0x13, PPC2_VSX),
10885 VSX_LOGICAL(xxlnor, 0x8, 0x14, PPC2_VSX),
10886 VSX_LOGICAL(xxleqv, 0x8, 0x17, PPC2_VSX207),
10887 VSX_LOGICAL(xxlnand, 0x8, 0x16, PPC2_VSX207),
10888 VSX_LOGICAL(xxlorc, 0x8, 0x15, PPC2_VSX207),
10889 GEN_XX3FORM(xxmrghw, 0x08, 0x02, PPC2_VSX),
10890 GEN_XX3FORM(xxmrglw, 0x08, 0x06, PPC2_VSX),
10891 GEN_XX2FORM(xxspltw, 0x08, 0x0A, PPC2_VSX),
10892 GEN_XX3FORM_DM(xxsldwi, 0x08, 0x00),
10893
10894 #define GEN_XXSEL_ROW(opc3) \
10895 GEN_HANDLER2_E(xxsel, "xxsel", 0x3C, 0x18, opc3, 0, PPC_NONE, PPC2_VSX), \
10896 GEN_HANDLER2_E(xxsel, "xxsel", 0x3C, 0x19, opc3, 0, PPC_NONE, PPC2_VSX), \
10897 GEN_HANDLER2_E(xxsel, "xxsel", 0x3C, 0x1A, opc3, 0, PPC_NONE, PPC2_VSX), \
10898 GEN_HANDLER2_E(xxsel, "xxsel", 0x3C, 0x1B, opc3, 0, PPC_NONE, PPC2_VSX), \
10899 GEN_HANDLER2_E(xxsel, "xxsel", 0x3C, 0x1C, opc3, 0, PPC_NONE, PPC2_VSX), \
10900 GEN_HANDLER2_E(xxsel, "xxsel", 0x3C, 0x1D, opc3, 0, PPC_NONE, PPC2_VSX), \
10901 GEN_HANDLER2_E(xxsel, "xxsel", 0x3C, 0x1E, opc3, 0, PPC_NONE, PPC2_VSX), \
10902 GEN_HANDLER2_E(xxsel, "xxsel", 0x3C, 0x1F, opc3, 0, PPC_NONE, PPC2_VSX), \
10903
10904 GEN_XXSEL_ROW(0x00)
10905 GEN_XXSEL_ROW(0x01)
10906 GEN_XXSEL_ROW(0x02)
10907 GEN_XXSEL_ROW(0x03)
10908 GEN_XXSEL_ROW(0x04)
10909 GEN_XXSEL_ROW(0x05)
10910 GEN_XXSEL_ROW(0x06)
10911 GEN_XXSEL_ROW(0x07)
10912 GEN_XXSEL_ROW(0x08)
10913 GEN_XXSEL_ROW(0x09)
10914 GEN_XXSEL_ROW(0x0A)
10915 GEN_XXSEL_ROW(0x0B)
10916 GEN_XXSEL_ROW(0x0C)
10917 GEN_XXSEL_ROW(0x0D)
10918 GEN_XXSEL_ROW(0x0E)
10919 GEN_XXSEL_ROW(0x0F)
10920 GEN_XXSEL_ROW(0x10)
10921 GEN_XXSEL_ROW(0x11)
10922 GEN_XXSEL_ROW(0x12)
10923 GEN_XXSEL_ROW(0x13)
10924 GEN_XXSEL_ROW(0x14)
10925 GEN_XXSEL_ROW(0x15)
10926 GEN_XXSEL_ROW(0x16)
10927 GEN_XXSEL_ROW(0x17)
10928 GEN_XXSEL_ROW(0x18)
10929 GEN_XXSEL_ROW(0x19)
10930 GEN_XXSEL_ROW(0x1A)
10931 GEN_XXSEL_ROW(0x1B)
10932 GEN_XXSEL_ROW(0x1C)
10933 GEN_XXSEL_ROW(0x1D)
10934 GEN_XXSEL_ROW(0x1E)
10935 GEN_XXSEL_ROW(0x1F)
10936
10937 GEN_XX3FORM_DM(xxpermdi, 0x08, 0x01),
10938
10939 #undef GEN_DFP_T_A_B_Rc
10940 #undef GEN_DFP_BF_A_B
10941 #undef GEN_DFP_BF_A_DCM
10942 #undef GEN_DFP_T_B_U32_U32_Rc
10943 #undef GEN_DFP_T_A_B_I32_Rc
10944 #undef GEN_DFP_T_B_Rc
10945 #undef GEN_DFP_T_FPR_I32_Rc
10946
10947 #define _GEN_DFP_LONG(name, op1, op2, mask) \
10948 GEN_HANDLER_E(name, 0x3B, op1, op2, mask, PPC_NONE, PPC2_DFP)
10949
10950 #define _GEN_DFP_LONGx2(name, op1, op2, mask) \
10951 GEN_HANDLER_E(name, 0x3B, op1, 0x00 | op2, mask, PPC_NONE, PPC2_DFP), \
10952 GEN_HANDLER_E(name, 0x3B, op1, 0x10 | op2, mask, PPC_NONE, PPC2_DFP)
10953
10954 #define _GEN_DFP_LONGx4(name, op1, op2, mask) \
10955 GEN_HANDLER_E(name, 0x3B, op1, 0x00 | op2, mask, PPC_NONE, PPC2_DFP), \
10956 GEN_HANDLER_E(name, 0x3B, op1, 0x08 | op2, mask, PPC_NONE, PPC2_DFP), \
10957 GEN_HANDLER_E(name, 0x3B, op1, 0x10 | op2, mask, PPC_NONE, PPC2_DFP), \
10958 GEN_HANDLER_E(name, 0x3B, op1, 0x18 | op2, mask, PPC_NONE, PPC2_DFP)
10959
10960 #define _GEN_DFP_QUAD(name, op1, op2, mask) \
10961 GEN_HANDLER_E(name, 0x3F, op1, op2, mask, PPC_NONE, PPC2_DFP)
10962
10963 #define _GEN_DFP_QUADx2(name, op1, op2, mask) \
10964 GEN_HANDLER_E(name, 0x3F, op1, 0x00 | op2, mask, PPC_NONE, PPC2_DFP), \
10965 GEN_HANDLER_E(name, 0x3F, op1, 0x10 | op2, mask, PPC_NONE, PPC2_DFP)
10966
10967 #define _GEN_DFP_QUADx4(name, op1, op2, mask)                         \
10968 GEN_HANDLER_E(name, 0x3F, op1, 0x00 | op2, mask, PPC_NONE, PPC2_DFP), \
10969 GEN_HANDLER_E(name, 0x3F, op1, 0x08 | op2, mask, PPC_NONE, PPC2_DFP), \
10970 GEN_HANDLER_E(name, 0x3F, op1, 0x10 | op2, mask, PPC_NONE, PPC2_DFP), \
10971 GEN_HANDLER_E(name, 0x3F, op1, 0x18 | op2, mask, PPC_NONE, PPC2_DFP)
10972
10973 #define GEN_DFP_T_A_B_Rc(name, op1, op2) \
10974 _GEN_DFP_LONG(name, op1, op2, 0x00000000)
10975
10976 #define GEN_DFP_Tp_Ap_Bp_Rc(name, op1, op2) \
10977 _GEN_DFP_QUAD(name, op1, op2, 0x00210800)
10978
10979 #define GEN_DFP_Tp_A_Bp_Rc(name, op1, op2) \
10980 _GEN_DFP_QUAD(name, op1, op2, 0x00200800)
10981
10982 #define GEN_DFP_T_B_Rc(name, op1, op2) \
10983 _GEN_DFP_LONG(name, op1, op2, 0x001F0000)
10984
10985 #define GEN_DFP_Tp_Bp_Rc(name, op1, op2) \
10986 _GEN_DFP_QUAD(name, op1, op2, 0x003F0800)
10987
10988 #define GEN_DFP_Tp_B_Rc(name, op1, op2) \
10989 _GEN_DFP_QUAD(name, op1, op2, 0x003F0000)
10990
10991 #define GEN_DFP_T_Bp_Rc(name, op1, op2) \
10992 _GEN_DFP_QUAD(name, op1, op2, 0x001F0800)
10993
10994 #define GEN_DFP_BF_A_B(name, op1, op2) \
10995 _GEN_DFP_LONG(name, op1, op2, 0x00000001)
10996
10997 #define GEN_DFP_BF_Ap_Bp(name, op1, op2) \
10998 _GEN_DFP_QUAD(name, op1, op2, 0x00610801)
10999
11000 #define GEN_DFP_BF_A_Bp(name, op1, op2) \
11001 _GEN_DFP_QUAD(name, op1, op2, 0x00600801)
11002
11003 #define GEN_DFP_BF_A_DCM(name, op1, op2) \
11004 _GEN_DFP_LONGx2(name, op1, op2, 0x00600001)
11005
11006 #define GEN_DFP_BF_Ap_DCM(name, op1, op2) \
11007 _GEN_DFP_QUADx2(name, op1, op2, 0x00610001)
11008
11009 #define GEN_DFP_T_A_B_RMC_Rc(name, op1, op2) \
11010 _GEN_DFP_LONGx4(name, op1, op2, 0x00000000)
11011
11012 #define GEN_DFP_Tp_Ap_Bp_RMC_Rc(name, op1, op2) \
11013 _GEN_DFP_QUADx4(name, op1, op2, 0x02010800)
11014
11015 #define GEN_DFP_Tp_A_Bp_RMC_Rc(name, op1, op2) \
11016 _GEN_DFP_QUADx4(name, op1, op2, 0x02000800)
11017
11018 #define GEN_DFP_TE_T_B_RMC_Rc(name, op1, op2) \
11019 _GEN_DFP_LONGx4(name, op1, op2, 0x00000000)
11020
11021 #define GEN_DFP_TE_Tp_Bp_RMC_Rc(name, op1, op2) \
11022 _GEN_DFP_QUADx4(name, op1, op2, 0x00200800)
11023
11024 #define GEN_DFP_R_T_B_RMC_Rc(name, op1, op2) \
11025 _GEN_DFP_LONGx4(name, op1, op2, 0x001E0000)
11026
11027 #define GEN_DFP_R_Tp_Bp_RMC_Rc(name, op1, op2) \
11028 _GEN_DFP_QUADx4(name, op1, op2, 0x003E0800)
11029
11030 #define GEN_DFP_SP_T_B_Rc(name, op1, op2) \
11031 _GEN_DFP_LONG(name, op1, op2, 0x00070000)
11032
11033 #define GEN_DFP_SP_Tp_Bp_Rc(name, op1, op2) \
11034 _GEN_DFP_QUAD(name, op1, op2, 0x00270800)
11035
11036 #define GEN_DFP_S_T_B_Rc(name, op1, op2) \
11037 _GEN_DFP_LONG(name, op1, op2, 0x000F0000)
11038
11039 #define GEN_DFP_S_Tp_Bp_Rc(name, op1, op2) \
11040 _GEN_DFP_QUAD(name, op1, op2, 0x002F0800)
11041
11042 #define GEN_DFP_T_A_SH_Rc(name, op1, op2) \
11043 _GEN_DFP_LONGx2(name, op1, op2, 0x00000000)
11044
11045 #define GEN_DFP_Tp_Ap_SH_Rc(name, op1, op2) \
11046 _GEN_DFP_QUADx2(name, op1, op2, 0x00210000)
11047
11048 GEN_DFP_T_A_B_Rc(dadd, 0x02, 0x00),
11049 GEN_DFP_Tp_Ap_Bp_Rc(daddq, 0x02, 0x00),
11050 GEN_DFP_T_A_B_Rc(dsub, 0x02, 0x10),
11051 GEN_DFP_Tp_Ap_Bp_Rc(dsubq, 0x02, 0x10),
11052 GEN_DFP_T_A_B_Rc(dmul, 0x02, 0x01),
11053 GEN_DFP_Tp_Ap_Bp_Rc(dmulq, 0x02, 0x01),
11054 GEN_DFP_T_A_B_Rc(ddiv, 0x02, 0x11),
11055 GEN_DFP_Tp_Ap_Bp_Rc(ddivq, 0x02, 0x11),
11056 GEN_DFP_BF_A_B(dcmpu, 0x02, 0x14),
11057 GEN_DFP_BF_Ap_Bp(dcmpuq, 0x02, 0x14),
11058 GEN_DFP_BF_A_B(dcmpo, 0x02, 0x04),
11059 GEN_DFP_BF_Ap_Bp(dcmpoq, 0x02, 0x04),
11060 GEN_DFP_BF_A_DCM(dtstdc, 0x02, 0x06),
11061 GEN_DFP_BF_Ap_DCM(dtstdcq, 0x02, 0x06),
11062 GEN_DFP_BF_A_DCM(dtstdg, 0x02, 0x07),
11063 GEN_DFP_BF_Ap_DCM(dtstdgq, 0x02, 0x07),
11064 GEN_DFP_BF_A_B(dtstex, 0x02, 0x05),
11065 GEN_DFP_BF_Ap_Bp(dtstexq, 0x02, 0x05),
11066 GEN_DFP_BF_A_B(dtstsf, 0x02, 0x15),
11067 GEN_DFP_BF_A_Bp(dtstsfq, 0x02, 0x15),
11068 GEN_DFP_TE_T_B_RMC_Rc(dquai, 0x03, 0x02),
11069 GEN_DFP_TE_Tp_Bp_RMC_Rc(dquaiq, 0x03, 0x02),
11070 GEN_DFP_T_A_B_RMC_Rc(dqua, 0x03, 0x00),
11071 GEN_DFP_Tp_Ap_Bp_RMC_Rc(dquaq, 0x03, 0x00),
11072 GEN_DFP_T_A_B_RMC_Rc(drrnd, 0x03, 0x01),
11073 GEN_DFP_Tp_A_Bp_RMC_Rc(drrndq, 0x03, 0x01),
11074 GEN_DFP_R_T_B_RMC_Rc(drintx, 0x03, 0x03),
11075 GEN_DFP_R_Tp_Bp_RMC_Rc(drintxq, 0x03, 0x03),
11076 GEN_DFP_R_T_B_RMC_Rc(drintn, 0x03, 0x07),
11077 GEN_DFP_R_Tp_Bp_RMC_Rc(drintnq, 0x03, 0x07),
11078 GEN_DFP_T_B_Rc(dctdp, 0x02, 0x08),
11079 GEN_DFP_Tp_B_Rc(dctqpq, 0x02, 0x08),
11080 GEN_DFP_T_B_Rc(drsp, 0x02, 0x18),
11081 GEN_DFP_Tp_Bp_Rc(drdpq, 0x02, 0x18),
11082 GEN_DFP_T_B_Rc(dcffix, 0x02, 0x19),
11083 GEN_DFP_Tp_B_Rc(dcffixq, 0x02, 0x19),
11084 GEN_DFP_T_B_Rc(dctfix, 0x02, 0x09),
11085 GEN_DFP_T_Bp_Rc(dctfixq, 0x02, 0x09),
11086 GEN_DFP_SP_T_B_Rc(ddedpd, 0x02, 0x0a),
11087 GEN_DFP_SP_Tp_Bp_Rc(ddedpdq, 0x02, 0x0a),
11088 GEN_DFP_S_T_B_Rc(denbcd, 0x02, 0x1a),
11089 GEN_DFP_S_Tp_Bp_Rc(denbcdq, 0x02, 0x1a),
11090 GEN_DFP_T_B_Rc(dxex, 0x02, 0x0b),
11091 GEN_DFP_T_Bp_Rc(dxexq, 0x02, 0x0b),
11092 GEN_DFP_T_A_B_Rc(diex, 0x02, 0x1b),
11093 GEN_DFP_Tp_A_Bp_Rc(diexq, 0x02, 0x1b),
11094 GEN_DFP_T_A_SH_Rc(dscli, 0x02, 0x02),
11095 GEN_DFP_Tp_Ap_SH_Rc(dscliq, 0x02, 0x02),
11096 GEN_DFP_T_A_SH_Rc(dscri, 0x02, 0x03),
11097 GEN_DFP_Tp_Ap_SH_Rc(dscriq, 0x02, 0x03),
11098
11099 #undef GEN_SPE
11100 #define GEN_SPE(name0, name1, opc2, opc3, inval0, inval1, type) \
11101     GEN_OPCODE_DUAL(name0##_##name1, 0x04, opc2, opc3, inval0, inval1, type, PPC_NONE)
11102 GEN_SPE(evaddw,      speundef,    0x00, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
11103 GEN_SPE(evaddiw,     speundef,    0x01, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
11104 GEN_SPE(evsubfw,     speundef,    0x02, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
11105 GEN_SPE(evsubifw,    speundef,    0x03, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
11106 GEN_SPE(evabs,       evneg,       0x04, 0x08, 0x0000F800, 0x0000F800, PPC_SPE),
11107 GEN_SPE(evextsb,     evextsh,     0x05, 0x08, 0x0000F800, 0x0000F800, PPC_SPE),
11108 GEN_SPE(evrndw,      evcntlzw,    0x06, 0x08, 0x0000F800, 0x0000F800, PPC_SPE),
11109 GEN_SPE(evcntlsw,    brinc,       0x07, 0x08, 0x0000F800, 0x00000000, PPC_SPE),
11110 GEN_SPE(evmra,       speundef,    0x02, 0x13, 0x0000F800, 0xFFFFFFFF, PPC_SPE),
11111 GEN_SPE(speundef,    evand,       0x08, 0x08, 0xFFFFFFFF, 0x00000000, PPC_SPE),
11112 GEN_SPE(evandc,      speundef,    0x09, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
11113 GEN_SPE(evxor,       evor,        0x0B, 0x08, 0x00000000, 0x00000000, PPC_SPE),
11114 GEN_SPE(evnor,       eveqv,       0x0C, 0x08, 0x00000000, 0x00000000, PPC_SPE),
11115 GEN_SPE(evmwumi,     evmwsmi,     0x0C, 0x11, 0x00000000, 0x00000000, PPC_SPE),
11116 GEN_SPE(evmwumia,    evmwsmia,    0x1C, 0x11, 0x00000000, 0x00000000, PPC_SPE),
11117 GEN_SPE(evmwumiaa,   evmwsmiaa,   0x0C, 0x15, 0x00000000, 0x00000000, PPC_SPE),
11118 GEN_SPE(speundef,    evorc,       0x0D, 0x08, 0xFFFFFFFF, 0x00000000, PPC_SPE),
11119 GEN_SPE(evnand,      speundef,    0x0F, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
11120 GEN_SPE(evsrwu,      evsrws,      0x10, 0x08, 0x00000000, 0x00000000, PPC_SPE),
11121 GEN_SPE(evsrwiu,     evsrwis,     0x11, 0x08, 0x00000000, 0x00000000, PPC_SPE),
11122 GEN_SPE(evslw,       speundef,    0x12, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
11123 GEN_SPE(evslwi,      speundef,    0x13, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
11124 GEN_SPE(evrlw,       evsplati,    0x14, 0x08, 0x00000000, 0x0000F800, PPC_SPE),
11125 GEN_SPE(evrlwi,      evsplatfi,   0x15, 0x08, 0x00000000, 0x0000F800, PPC_SPE),
11126 GEN_SPE(evmergehi,   evmergelo,   0x16, 0x08, 0x00000000, 0x00000000, PPC_SPE),
11127 GEN_SPE(evmergehilo, evmergelohi, 0x17, 0x08, 0x00000000, 0x00000000, PPC_SPE),
11128 GEN_SPE(evcmpgtu,    evcmpgts,    0x18, 0x08, 0x00600000, 0x00600000, PPC_SPE),
11129 GEN_SPE(evcmpltu,    evcmplts,    0x19, 0x08, 0x00600000, 0x00600000, PPC_SPE),
11130 GEN_SPE(evcmpeq,     speundef,    0x1A, 0x08, 0x00600000, 0xFFFFFFFF, PPC_SPE),
11131
11132 GEN_SPE(evfsadd,     evfssub,     0x00, 0x0A, 0x00000000, 0x00000000, PPC_SPE_SINGLE),
11133 GEN_SPE(evfsabs,     evfsnabs,    0x02, 0x0A, 0x0000F800, 0x0000F800, PPC_SPE_SINGLE),
11134 GEN_SPE(evfsneg,     speundef,    0x03, 0x0A, 0x0000F800, 0xFFFFFFFF, PPC_SPE_SINGLE),
11135 GEN_SPE(evfsmul,     evfsdiv,     0x04, 0x0A, 0x00000000, 0x00000000, PPC_SPE_SINGLE),
11136 GEN_SPE(evfscmpgt,   evfscmplt,   0x06, 0x0A, 0x00600000, 0x00600000, PPC_SPE_SINGLE),
11137 GEN_SPE(evfscmpeq,   speundef,    0x07, 0x0A, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE),
11138 GEN_SPE(evfscfui,    evfscfsi,    0x08, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
11139 GEN_SPE(evfscfuf,    evfscfsf,    0x09, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
11140 GEN_SPE(evfsctui,    evfsctsi,    0x0A, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
11141 GEN_SPE(evfsctuf,    evfsctsf,    0x0B, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
11142 GEN_SPE(evfsctuiz,   speundef,    0x0C, 0x0A, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE),
11143 GEN_SPE(evfsctsiz,   speundef,    0x0D, 0x0A, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE),
11144 GEN_SPE(evfststgt,   evfststlt,   0x0E, 0x0A, 0x00600000, 0x00600000, PPC_SPE_SINGLE),
11145 GEN_SPE(evfststeq,   speundef,    0x0F, 0x0A, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE),
11146
11147 GEN_SPE(efsadd,      efssub,      0x00, 0x0B, 0x00000000, 0x00000000, PPC_SPE_SINGLE),
11148 GEN_SPE(efsabs,      efsnabs,     0x02, 0x0B, 0x0000F800, 0x0000F800, PPC_SPE_SINGLE),
11149 GEN_SPE(efsneg,      speundef,    0x03, 0x0B, 0x0000F800, 0xFFFFFFFF, PPC_SPE_SINGLE),
11150 GEN_SPE(efsmul,      efsdiv,      0x04, 0x0B, 0x00000000, 0x00000000, PPC_SPE_SINGLE),
11151 GEN_SPE(efscmpgt,    efscmplt,    0x06, 0x0B, 0x00600000, 0x00600000, PPC_SPE_SINGLE),
11152 GEN_SPE(efscmpeq,    efscfd,      0x07, 0x0B, 0x00600000, 0x00180000, PPC_SPE_SINGLE),
11153 GEN_SPE(efscfui,     efscfsi,     0x08, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
11154 GEN_SPE(efscfuf,     efscfsf,     0x09, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
11155 GEN_SPE(efsctui,     efsctsi,     0x0A, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
11156 GEN_SPE(efsctuf,     efsctsf,     0x0B, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
11157 GEN_SPE(efsctuiz,    speundef,    0x0C, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE),
11158 GEN_SPE(efsctsiz,    speundef,    0x0D, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE),
11159 GEN_SPE(efststgt,    efststlt,    0x0E, 0x0B, 0x00600000, 0x00600000, PPC_SPE_SINGLE),
11160 GEN_SPE(efststeq,    speundef,    0x0F, 0x0B, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE),
11161
11162 GEN_SPE(efdadd,      efdsub,      0x10, 0x0B, 0x00000000, 0x00000000, PPC_SPE_DOUBLE),
11163 GEN_SPE(efdcfuid,    efdcfsid,    0x11, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
11164 GEN_SPE(efdabs,      efdnabs,     0x12, 0x0B, 0x0000F800, 0x0000F800, PPC_SPE_DOUBLE),
11165 GEN_SPE(efdneg,      speundef,    0x13, 0x0B, 0x0000F800, 0xFFFFFFFF, PPC_SPE_DOUBLE),
11166 GEN_SPE(efdmul,      efddiv,      0x14, 0x0B, 0x00000000, 0x00000000, PPC_SPE_DOUBLE),
11167 GEN_SPE(efdctuidz,   efdctsidz,   0x15, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
11168 GEN_SPE(efdcmpgt,    efdcmplt,    0x16, 0x0B, 0x00600000, 0x00600000, PPC_SPE_DOUBLE),
11169 GEN_SPE(efdcmpeq,    efdcfs,      0x17, 0x0B, 0x00600000, 0x00180000, PPC_SPE_DOUBLE),
11170 GEN_SPE(efdcfui,     efdcfsi,     0x18, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
11171 GEN_SPE(efdcfuf,     efdcfsf,     0x19, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
11172 GEN_SPE(efdctui,     efdctsi,     0x1A, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
11173 GEN_SPE(efdctuf,     efdctsf,     0x1B, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
11174 GEN_SPE(efdctuiz,    speundef,    0x1C, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_DOUBLE),
11175 GEN_SPE(efdctsiz,    speundef,    0x1D, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_DOUBLE),
11176 GEN_SPE(efdtstgt,    efdtstlt,    0x1E, 0x0B, 0x00600000, 0x00600000, PPC_SPE_DOUBLE),
11177 GEN_SPE(efdtsteq,    speundef,    0x1F, 0x0B, 0x00600000, 0xFFFFFFFF, PPC_SPE_DOUBLE),
11178
11179 #undef GEN_SPEOP_LDST
11180 #define GEN_SPEOP_LDST(name, opc2, sh)                                        \
11181 GEN_HANDLER(name, 0x04, opc2, 0x0C, 0x00000000, PPC_SPE)
11182 GEN_SPEOP_LDST(evldd, 0x00, 3),
11183 GEN_SPEOP_LDST(evldw, 0x01, 3),
11184 GEN_SPEOP_LDST(evldh, 0x02, 3),
11185 GEN_SPEOP_LDST(evlhhesplat, 0x04, 1),
11186 GEN_SPEOP_LDST(evlhhousplat, 0x06, 1),
11187 GEN_SPEOP_LDST(evlhhossplat, 0x07, 1),
11188 GEN_SPEOP_LDST(evlwhe, 0x08, 2),
11189 GEN_SPEOP_LDST(evlwhou, 0x0A, 2),
11190 GEN_SPEOP_LDST(evlwhos, 0x0B, 2),
11191 GEN_SPEOP_LDST(evlwwsplat, 0x0C, 2),
11192 GEN_SPEOP_LDST(evlwhsplat, 0x0E, 2),
11193
11194 GEN_SPEOP_LDST(evstdd, 0x10, 3),
11195 GEN_SPEOP_LDST(evstdw, 0x11, 3),
11196 GEN_SPEOP_LDST(evstdh, 0x12, 3),
11197 GEN_SPEOP_LDST(evstwhe, 0x18, 2),
11198 GEN_SPEOP_LDST(evstwho, 0x1A, 2),
11199 GEN_SPEOP_LDST(evstwwe, 0x1C, 2),
11200 GEN_SPEOP_LDST(evstwwo, 0x1E, 2),
11201
11202 GEN_HANDLER2_E(tbegin, "tbegin", 0x1F, 0x0E, 0x14, 0x01DFF800, \
11203                PPC_NONE, PPC2_TM),
11204 GEN_HANDLER2_E(tend,   "tend",   0x1F, 0x0E, 0x15, 0x01FFF800, \
11205                PPC_NONE, PPC2_TM),
11206 GEN_HANDLER2_E(tabort, "tabort", 0x1F, 0x0E, 0x1C, 0x03E0F800, \
11207                PPC_NONE, PPC2_TM),
11208 GEN_HANDLER2_E(tabortwc, "tabortwc", 0x1F, 0x0E, 0x18, 0x00000000, \
11209                PPC_NONE, PPC2_TM),
11210 GEN_HANDLER2_E(tabortwci, "tabortwci", 0x1F, 0x0E, 0x1A, 0x00000000, \
11211                PPC_NONE, PPC2_TM),
11212 GEN_HANDLER2_E(tabortdc, "tabortdc", 0x1F, 0x0E, 0x19, 0x00000000, \
11213                PPC_NONE, PPC2_TM),
11214 GEN_HANDLER2_E(tabortdci, "tabortdci", 0x1F, 0x0E, 0x1B, 0x00000000, \
11215                PPC_NONE, PPC2_TM),
11216 GEN_HANDLER2_E(tsr, "tsr", 0x1F, 0x0E, 0x17, 0x03DFF800, \
11217                PPC_NONE, PPC2_TM),
11218 GEN_HANDLER2_E(tcheck, "tcheck", 0x1F, 0x0E, 0x16, 0x007FF800, \
11219                PPC_NONE, PPC2_TM),
11220 GEN_HANDLER2_E(treclaim, "treclaim", 0x1F, 0x0E, 0x1D, 0x03E0F800, \
11221                PPC_NONE, PPC2_TM),
11222 GEN_HANDLER2_E(trechkpt, "trechkpt", 0x1F, 0x0E, 0x1F, 0x03FFF800, \
11223                PPC_NONE, PPC2_TM),
11224 };
11225
11226 #include "helper_regs.h"
11227 #include "translate_init.c"
11228
11229 /*****************************************************************************/
11230 /* Misc PowerPC helpers */
11231 void ppc_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
11232                         int flags)
11233 {
11234 #define RGPL  4
11235 #define RFPL  4
11236
11237     PowerPCCPU *cpu = POWERPC_CPU(cs);
11238     CPUPPCState *env = &cpu->env;
11239     int i;
11240
11241     cpu_fprintf(f, "NIP " TARGET_FMT_lx "   LR " TARGET_FMT_lx " CTR "
11242                 TARGET_FMT_lx " XER " TARGET_FMT_lx " CPU#%d\n",
11243                 env->nip, env->lr, env->ctr, cpu_read_xer(env),
11244                 cs->cpu_index);
11245     cpu_fprintf(f, "MSR " TARGET_FMT_lx " HID0 " TARGET_FMT_lx "  HF "
11246                 TARGET_FMT_lx " idx %d\n", env->msr, env->spr[SPR_HID0],
11247                 env->hflags, env->mmu_idx);
11248 #if !defined(NO_TIMER_DUMP)
11249     cpu_fprintf(f, "TB %08" PRIu32 " %08" PRIu64
11250 #if !defined(CONFIG_USER_ONLY)
11251                 " DECR %08" PRIu32
11252 #endif
11253                 "\n",
11254                 cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
11255 #if !defined(CONFIG_USER_ONLY)
11256                 , cpu_ppc_load_decr(env)
11257 #endif
11258                 );
11259 #endif
11260     for (i = 0; i < 32; i++) {
11261         if ((i & (RGPL - 1)) == 0)
11262             cpu_fprintf(f, "GPR%02d", i);
11263         cpu_fprintf(f, " %016" PRIx64, ppc_dump_gpr(env, i));
11264         if ((i & (RGPL - 1)) == (RGPL - 1))
11265             cpu_fprintf(f, "\n");
11266     }
11267     cpu_fprintf(f, "CR ");
11268     for (i = 0; i < 8; i++)
11269         cpu_fprintf(f, "%01x", env->crf[i]);
11270     cpu_fprintf(f, "  [");
11271     for (i = 0; i < 8; i++) {
11272         char a = '-';
11273         if (env->crf[i] & 0x08)
11274             a = 'L';
11275         else if (env->crf[i] & 0x04)
11276             a = 'G';
11277         else if (env->crf[i] & 0x02)
11278             a = 'E';
11279         cpu_fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
11280     }
11281     cpu_fprintf(f, " ]             RES " TARGET_FMT_lx "\n",
11282                 env->reserve_addr);
11283     for (i = 0; i < 32; i++) {
11284         if ((i & (RFPL - 1)) == 0)
11285             cpu_fprintf(f, "FPR%02d", i);
11286         cpu_fprintf(f, " %016" PRIx64, *((uint64_t *)&env->fpr[i]));
11287         if ((i & (RFPL - 1)) == (RFPL - 1))
11288             cpu_fprintf(f, "\n");
11289     }
11290     cpu_fprintf(f, "FPSCR " TARGET_FMT_lx "\n", env->fpscr);
11291 #if !defined(CONFIG_USER_ONLY)
11292     cpu_fprintf(f, " SRR0 " TARGET_FMT_lx "  SRR1 " TARGET_FMT_lx
11293                    "    PVR " TARGET_FMT_lx " VRSAVE " TARGET_FMT_lx "\n",
11294                 env->spr[SPR_SRR0], env->spr[SPR_SRR1],
11295                 env->spr[SPR_PVR], env->spr[SPR_VRSAVE]);
11296
11297     cpu_fprintf(f, "SPRG0 " TARGET_FMT_lx " SPRG1 " TARGET_FMT_lx
11298                    "  SPRG2 " TARGET_FMT_lx "  SPRG3 " TARGET_FMT_lx "\n",
11299                 env->spr[SPR_SPRG0], env->spr[SPR_SPRG1],
11300                 env->spr[SPR_SPRG2], env->spr[SPR_SPRG3]);
11301
11302     cpu_fprintf(f, "SPRG4 " TARGET_FMT_lx " SPRG5 " TARGET_FMT_lx
11303                    "  SPRG6 " TARGET_FMT_lx "  SPRG7 " TARGET_FMT_lx "\n",
11304                 env->spr[SPR_SPRG4], env->spr[SPR_SPRG5],
11305                 env->spr[SPR_SPRG6], env->spr[SPR_SPRG7]);
11306
11307     if (env->excp_model == POWERPC_EXCP_BOOKE) {
11308         cpu_fprintf(f, "CSRR0 " TARGET_FMT_lx " CSRR1 " TARGET_FMT_lx
11309                        " MCSRR0 " TARGET_FMT_lx " MCSRR1 " TARGET_FMT_lx "\n",
11310                     env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1],
11311                     env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1]);
11312
11313         cpu_fprintf(f, "  TCR " TARGET_FMT_lx "   TSR " TARGET_FMT_lx
11314                        "    ESR " TARGET_FMT_lx "   DEAR " TARGET_FMT_lx "\n",
11315                     env->spr[SPR_BOOKE_TCR], env->spr[SPR_BOOKE_TSR],
11316                     env->spr[SPR_BOOKE_ESR], env->spr[SPR_BOOKE_DEAR]);
11317
11318         cpu_fprintf(f, "  PIR " TARGET_FMT_lx " DECAR " TARGET_FMT_lx
11319                        "   IVPR " TARGET_FMT_lx "   EPCR " TARGET_FMT_lx "\n",
11320                     env->spr[SPR_BOOKE_PIR], env->spr[SPR_BOOKE_DECAR],
11321                     env->spr[SPR_BOOKE_IVPR], env->spr[SPR_BOOKE_EPCR]);
11322
11323         cpu_fprintf(f, " MCSR " TARGET_FMT_lx " SPRG8 " TARGET_FMT_lx
11324                        "    EPR " TARGET_FMT_lx "\n",
11325                     env->spr[SPR_BOOKE_MCSR], env->spr[SPR_BOOKE_SPRG8],
11326                     env->spr[SPR_BOOKE_EPR]);
11327
11328         /* FSL-specific */
11329         cpu_fprintf(f, " MCAR " TARGET_FMT_lx "  PID1 " TARGET_FMT_lx
11330                        "   PID2 " TARGET_FMT_lx "    SVR " TARGET_FMT_lx "\n",
11331                     env->spr[SPR_Exxx_MCAR], env->spr[SPR_BOOKE_PID1],
11332                     env->spr[SPR_BOOKE_PID2], env->spr[SPR_E500_SVR]);
11333
11334         /*
11335          * IVORs are left out as they are large and do not change often --
11336          * they can be read with "p $ivor0", "p $ivor1", etc.
11337          */
11338     }
11339
11340 #if defined(TARGET_PPC64)
11341     if (env->flags & POWERPC_FLAG_CFAR) {
11342         cpu_fprintf(f, " CFAR " TARGET_FMT_lx"\n", env->cfar);
11343     }
11344 #endif
11345
11346     switch (env->mmu_model) {
11347     case POWERPC_MMU_32B:
11348     case POWERPC_MMU_601:
11349     case POWERPC_MMU_SOFT_6xx:
11350     case POWERPC_MMU_SOFT_74xx:
11351 #if defined(TARGET_PPC64)
11352     case POWERPC_MMU_64B:
11353     case POWERPC_MMU_2_03:
11354     case POWERPC_MMU_2_06:
11355     case POWERPC_MMU_2_06a:
11356     case POWERPC_MMU_2_07:
11357     case POWERPC_MMU_2_07a:
11358 #endif
11359         cpu_fprintf(f, " SDR1 " TARGET_FMT_lx "   DAR " TARGET_FMT_lx
11360                        "  DSISR " TARGET_FMT_lx "\n", env->spr[SPR_SDR1],
11361                     env->spr[SPR_DAR], env->spr[SPR_DSISR]);
11362         break;
11363     case POWERPC_MMU_BOOKE206:
11364         cpu_fprintf(f, " MAS0 " TARGET_FMT_lx "  MAS1 " TARGET_FMT_lx
11365                        "   MAS2 " TARGET_FMT_lx "   MAS3 " TARGET_FMT_lx "\n",
11366                     env->spr[SPR_BOOKE_MAS0], env->spr[SPR_BOOKE_MAS1],
11367                     env->spr[SPR_BOOKE_MAS2], env->spr[SPR_BOOKE_MAS3]);
11368
11369         cpu_fprintf(f, " MAS4 " TARGET_FMT_lx "  MAS6 " TARGET_FMT_lx
11370                        "   MAS7 " TARGET_FMT_lx "    PID " TARGET_FMT_lx "\n",
11371                     env->spr[SPR_BOOKE_MAS4], env->spr[SPR_BOOKE_MAS6],
11372                     env->spr[SPR_BOOKE_MAS7], env->spr[SPR_BOOKE_PID]);
11373
11374         cpu_fprintf(f, "MMUCFG " TARGET_FMT_lx " TLB0CFG " TARGET_FMT_lx
11375                        " TLB1CFG " TARGET_FMT_lx "\n",
11376                     env->spr[SPR_MMUCFG], env->spr[SPR_BOOKE_TLB0CFG],
11377                     env->spr[SPR_BOOKE_TLB1CFG]);
11378         break;
11379     default:
11380         break;
11381     }
11382 #endif
11383
11384 #undef RGPL
11385 #undef RFPL
11386 }
11387
11388 void ppc_cpu_dump_statistics(CPUState *cs, FILE*f,
11389                              fprintf_function cpu_fprintf, int flags)
11390 {
11391 #if defined(DO_PPC_STATISTICS)
11392     PowerPCCPU *cpu = POWERPC_CPU(cs);
11393     opc_handler_t **t1, **t2, **t3, *handler;
11394     int op1, op2, op3;
11395
11396     t1 = cpu->env.opcodes;
11397     for (op1 = 0; op1 < 64; op1++) {
11398         handler = t1[op1];
11399         if (is_indirect_opcode(handler)) {
11400             t2 = ind_table(handler);
11401             for (op2 = 0; op2 < 32; op2++) {
11402                 handler = t2[op2];
11403                 if (is_indirect_opcode(handler)) {
11404                     t3 = ind_table(handler);
11405                     for (op3 = 0; op3 < 32; op3++) {
11406                         handler = t3[op3];
11407                         if (handler->count == 0)
11408                             continue;
11409                         cpu_fprintf(f, "%02x %02x %02x (%02x %04d) %16s: "
11410                                     "%016" PRIx64 " %" PRId64 "\n",
11411                                     op1, op2, op3, op1, (op3 << 5) | op2,
11412                                     handler->oname,
11413                                     handler->count, handler->count);
11414                     }
11415                 } else {
11416                     if (handler->count == 0)
11417                         continue;
11418                     cpu_fprintf(f, "%02x %02x    (%02x %04d) %16s: "
11419                                 "%016" PRIx64 " %" PRId64 "\n",
11420                                 op1, op2, op1, op2, handler->oname,
11421                                 handler->count, handler->count);
11422                 }
11423             }
11424         } else {
11425             if (handler->count == 0)
11426                 continue;
11427             cpu_fprintf(f, "%02x       (%02x     ) %16s: %016" PRIx64
11428                         " %" PRId64 "\n",
11429                         op1, op1, handler->oname,
11430                         handler->count, handler->count);
11431         }
11432     }
11433 #endif
11434 }
11435
11436 /*****************************************************************************/
11437 void gen_intermediate_code(CPUPPCState *env, struct TranslationBlock *tb)
11438 {
11439     PowerPCCPU *cpu = ppc_env_get_cpu(env);
11440     CPUState *cs = CPU(cpu);
11441     DisasContext ctx, *ctxp = &ctx;
11442     opc_handler_t **table, *handler;
11443     target_ulong pc_start;
11444     int num_insns;
11445     int max_insns;
11446
11447     pc_start = tb->pc;
11448     ctx.nip = pc_start;
11449     ctx.tb = tb;
11450     ctx.exception = POWERPC_EXCP_NONE;
11451     ctx.spr_cb = env->spr_cb;
11452     ctx.pr = msr_pr;
11453     ctx.hv = !msr_pr && msr_hv;
11454     ctx.mem_idx = env->mmu_idx;
11455     ctx.insns_flags = env->insns_flags;
11456     ctx.insns_flags2 = env->insns_flags2;
11457     ctx.access_type = -1;
11458     ctx.le_mode = env->hflags & (1 << MSR_LE) ? 1 : 0;
11459     ctx.default_tcg_memop_mask = ctx.le_mode ? MO_LE : MO_BE;
11460 #if defined(TARGET_PPC64)
11461     ctx.sf_mode = msr_is_64bit(env, env->msr);
11462     ctx.has_cfar = !!(env->flags & POWERPC_FLAG_CFAR);
11463 #endif
11464     ctx.fpu_enabled = msr_fp;
11465     if ((env->flags & POWERPC_FLAG_SPE) && msr_spe)
11466         ctx.spe_enabled = msr_spe;
11467     else
11468         ctx.spe_enabled = 0;
11469     if ((env->flags & POWERPC_FLAG_VRE) && msr_vr)
11470         ctx.altivec_enabled = msr_vr;
11471     else
11472         ctx.altivec_enabled = 0;
11473     if ((env->flags & POWERPC_FLAG_VSX) && msr_vsx) {
11474         ctx.vsx_enabled = msr_vsx;
11475     } else {
11476         ctx.vsx_enabled = 0;
11477     }
11478 #if defined(TARGET_PPC64)
11479     if ((env->flags & POWERPC_FLAG_TM) && msr_tm) {
11480         ctx.tm_enabled = msr_tm;
11481     } else {
11482         ctx.tm_enabled = 0;
11483     }
11484 #endif
11485     if ((env->flags & POWERPC_FLAG_SE) && msr_se)
11486         ctx.singlestep_enabled = CPU_SINGLE_STEP;
11487     else
11488         ctx.singlestep_enabled = 0;
11489     if ((env->flags & POWERPC_FLAG_BE) && msr_be)
11490         ctx.singlestep_enabled |= CPU_BRANCH_STEP;
11491     if (unlikely(cs->singlestep_enabled)) {
11492         ctx.singlestep_enabled |= GDBSTUB_SINGLE_STEP;
11493     }
11494 #if defined (DO_SINGLE_STEP) && 0
11495     /* Single step trace mode */
11496     msr_se = 1;
11497 #endif
11498     num_insns = 0;
11499     max_insns = tb->cflags & CF_COUNT_MASK;
11500     if (max_insns == 0) {
11501         max_insns = CF_COUNT_MASK;
11502     }
11503     if (max_insns > TCG_MAX_INSNS) {
11504         max_insns = TCG_MAX_INSNS;
11505     }
11506
11507     gen_tb_start(tb);
11508     tcg_clear_temp_count();
11509     /* Set env in case of segfault during code fetch */
11510     while (ctx.exception == POWERPC_EXCP_NONE && !tcg_op_buf_full()) {
11511         tcg_gen_insn_start(ctx.nip);
11512         num_insns++;
11513
11514         if (unlikely(cpu_breakpoint_test(cs, ctx.nip, BP_ANY))) {
11515             gen_debug_exception(ctxp);
11516             /* The address covered by the breakpoint must be included in
11517                [tb->pc, tb->pc + tb->size) in order to for it to be
11518                properly cleared -- thus we increment the PC here so that
11519                the logic setting tb->size below does the right thing.  */
11520             ctx.nip += 4;
11521             break;
11522         }
11523
11524         LOG_DISAS("----------------\n");
11525         LOG_DISAS("nip=" TARGET_FMT_lx " super=%d ir=%d\n",
11526                   ctx.nip, ctx.mem_idx, (int)msr_ir);
11527         if (num_insns == max_insns && (tb->cflags & CF_LAST_IO))
11528             gen_io_start();
11529         if (unlikely(need_byteswap(&ctx))) {
11530             ctx.opcode = bswap32(cpu_ldl_code(env, ctx.nip));
11531         } else {
11532             ctx.opcode = cpu_ldl_code(env, ctx.nip);
11533         }
11534         LOG_DISAS("translate opcode %08x (%02x %02x %02x) (%s)\n",
11535                     ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
11536                     opc3(ctx.opcode), ctx.le_mode ? "little" : "big");
11537         ctx.nip += 4;
11538         table = env->opcodes;
11539         handler = table[opc1(ctx.opcode)];
11540         if (is_indirect_opcode(handler)) {
11541             table = ind_table(handler);
11542             handler = table[opc2(ctx.opcode)];
11543             if (is_indirect_opcode(handler)) {
11544                 table = ind_table(handler);
11545                 handler = table[opc3(ctx.opcode)];
11546             }
11547         }
11548         /* Is opcode *REALLY* valid ? */
11549         if (unlikely(handler->handler == &gen_invalid)) {
11550             qemu_log_mask(LOG_GUEST_ERROR, "invalid/unsupported opcode: "
11551                           "%02x - %02x - %02x (%08x) " TARGET_FMT_lx " %d\n",
11552                           opc1(ctx.opcode), opc2(ctx.opcode),
11553                           opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, (int)msr_ir);
11554         } else {
11555             uint32_t inval;
11556
11557             if (unlikely(handler->type & (PPC_SPE | PPC_SPE_SINGLE | PPC_SPE_DOUBLE) && Rc(ctx.opcode))) {
11558                 inval = handler->inval2;
11559             } else {
11560                 inval = handler->inval1;
11561             }
11562
11563             if (unlikely((ctx.opcode & inval) != 0)) {
11564                 qemu_log_mask(LOG_GUEST_ERROR, "invalid bits: %08x for opcode: "
11565                               "%02x - %02x - %02x (%08x) " TARGET_FMT_lx "\n",
11566                               ctx.opcode & inval, opc1(ctx.opcode),
11567                               opc2(ctx.opcode), opc3(ctx.opcode),
11568                               ctx.opcode, ctx.nip - 4);
11569                 gen_inval_exception(ctxp, POWERPC_EXCP_INVAL_INVAL);
11570                 break;
11571             }
11572         }
11573         (*(handler->handler))(&ctx);
11574 #if defined(DO_PPC_STATISTICS)
11575         handler->count++;
11576 #endif
11577         /* Check trace mode exceptions */
11578         if (unlikely(ctx.singlestep_enabled & CPU_SINGLE_STEP &&
11579                      (ctx.nip <= 0x100 || ctx.nip > 0xF00) &&
11580                      ctx.exception != POWERPC_SYSCALL &&
11581                      ctx.exception != POWERPC_EXCP_TRAP &&
11582                      ctx.exception != POWERPC_EXCP_BRANCH)) {
11583             gen_exception(ctxp, POWERPC_EXCP_TRACE);
11584         } else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
11585                             (cs->singlestep_enabled) ||
11586                             singlestep ||
11587                             num_insns >= max_insns)) {
11588             /* if we reach a page boundary or are single stepping, stop
11589              * generation
11590              */
11591             break;
11592         }
11593         if (tcg_check_temp_count()) {
11594             fprintf(stderr, "Opcode %02x %02x %02x (%08x) leaked temporaries\n",
11595                     opc1(ctx.opcode), opc2(ctx.opcode), opc3(ctx.opcode),
11596                     ctx.opcode);
11597             exit(1);
11598         }
11599     }
11600     if (tb->cflags & CF_LAST_IO)
11601         gen_io_end();
11602     if (ctx.exception == POWERPC_EXCP_NONE) {
11603         gen_goto_tb(&ctx, 0, ctx.nip);
11604     } else if (ctx.exception != POWERPC_EXCP_BRANCH) {
11605         if (unlikely(cs->singlestep_enabled)) {
11606             gen_debug_exception(ctxp);
11607         }
11608         /* Generate the return instruction */
11609         tcg_gen_exit_tb(0);
11610     }
11611     gen_tb_end(tb, num_insns);
11612
11613     tb->size = ctx.nip - pc_start;
11614     tb->icount = num_insns;
11615
11616 #if defined(DEBUG_DISAS)
11617     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
11618         int flags;
11619         flags = env->bfd_mach;
11620         flags |= ctx.le_mode << 16;
11621         qemu_log("IN: %s\n", lookup_symbol(pc_start));
11622         log_target_disas(cs, pc_start, ctx.nip - pc_start, flags);
11623         qemu_log("\n");
11624     }
11625 #endif
11626 }
11627
11628 void restore_state_to_opc(CPUPPCState *env, TranslationBlock *tb,
11629                           target_ulong *data)
11630 {
11631     env->nip = data[0];
11632 }
This page took 0.69757 seconds and 4 git commands to generate.