These changes are the raw update to qemu-2.6.
[kvmfornfv.git] / qemu / 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_env 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 + 3) / 4;
3231     if (unlikely(lsw_reg_in_range(start, nr, ra))) {
3232         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_LSWX);
3233         return;
3234     }
3235     gen_set_access_type(ctx, ACCESS_INT);
3236     /* NIP cannot be restored if the memory exception comes from an helper */
3237     gen_update_nip(ctx, ctx->nip - 4);
3238     t0 = tcg_temp_new();
3239     gen_addr_register(ctx, t0);
3240     t1 = tcg_const_i32(nb);
3241     t2 = tcg_const_i32(start);
3242     gen_helper_lsw(cpu_env, t0, t1, t2);
3243     tcg_temp_free(t0);
3244     tcg_temp_free_i32(t1);
3245     tcg_temp_free_i32(t2);
3246 }
3247
3248 /* lswx */
3249 static void gen_lswx(DisasContext *ctx)
3250 {
3251     TCGv t0;
3252     TCGv_i32 t1, t2, t3;
3253     gen_set_access_type(ctx, ACCESS_INT);
3254     /* NIP cannot be restored if the memory exception comes from an helper */
3255     gen_update_nip(ctx, ctx->nip - 4);
3256     t0 = tcg_temp_new();
3257     gen_addr_reg_index(ctx, t0);
3258     t1 = tcg_const_i32(rD(ctx->opcode));
3259     t2 = tcg_const_i32(rA(ctx->opcode));
3260     t3 = tcg_const_i32(rB(ctx->opcode));
3261     gen_helper_lswx(cpu_env, t0, t1, t2, t3);
3262     tcg_temp_free(t0);
3263     tcg_temp_free_i32(t1);
3264     tcg_temp_free_i32(t2);
3265     tcg_temp_free_i32(t3);
3266 }
3267
3268 /* stswi */
3269 static void gen_stswi(DisasContext *ctx)
3270 {
3271     TCGv t0;
3272     TCGv_i32 t1, t2;
3273     int nb = NB(ctx->opcode);
3274     gen_set_access_type(ctx, ACCESS_INT);
3275     /* NIP cannot be restored if the memory exception comes from an helper */
3276     gen_update_nip(ctx, ctx->nip - 4);
3277     t0 = tcg_temp_new();
3278     gen_addr_register(ctx, t0);
3279     if (nb == 0)
3280         nb = 32;
3281     t1 = tcg_const_i32(nb);
3282     t2 = tcg_const_i32(rS(ctx->opcode));
3283     gen_helper_stsw(cpu_env, t0, t1, t2);
3284     tcg_temp_free(t0);
3285     tcg_temp_free_i32(t1);
3286     tcg_temp_free_i32(t2);
3287 }
3288
3289 /* stswx */
3290 static void gen_stswx(DisasContext *ctx)
3291 {
3292     TCGv t0;
3293     TCGv_i32 t1, t2;
3294     gen_set_access_type(ctx, ACCESS_INT);
3295     /* NIP cannot be restored if the memory exception comes from an helper */
3296     gen_update_nip(ctx, ctx->nip - 4);
3297     t0 = tcg_temp_new();
3298     gen_addr_reg_index(ctx, t0);
3299     t1 = tcg_temp_new_i32();
3300     tcg_gen_trunc_tl_i32(t1, cpu_xer);
3301     tcg_gen_andi_i32(t1, t1, 0x7F);
3302     t2 = tcg_const_i32(rS(ctx->opcode));
3303     gen_helper_stsw(cpu_env, t0, t1, t2);
3304     tcg_temp_free(t0);
3305     tcg_temp_free_i32(t1);
3306     tcg_temp_free_i32(t2);
3307 }
3308
3309 /***                        Memory synchronisation                         ***/
3310 /* eieio */
3311 static void gen_eieio(DisasContext *ctx)
3312 {
3313 }
3314
3315 /* isync */
3316 static void gen_isync(DisasContext *ctx)
3317 {
3318     gen_stop_exception(ctx);
3319 }
3320
3321 #define LARX(name, len, loadop)                                      \
3322 static void gen_##name(DisasContext *ctx)                            \
3323 {                                                                    \
3324     TCGv t0;                                                         \
3325     TCGv gpr = cpu_gpr[rD(ctx->opcode)];                             \
3326     gen_set_access_type(ctx, ACCESS_RES);                            \
3327     t0 = tcg_temp_local_new();                                       \
3328     gen_addr_reg_index(ctx, t0);                                     \
3329     if ((len) > 1) {                                                 \
3330         gen_check_align(ctx, t0, (len)-1);                           \
3331     }                                                                \
3332     gen_qemu_##loadop(ctx, gpr, t0);                                 \
3333     tcg_gen_mov_tl(cpu_reserve, t0);                                 \
3334     tcg_gen_st_tl(gpr, cpu_env, offsetof(CPUPPCState, reserve_val)); \
3335     tcg_temp_free(t0);                                               \
3336 }
3337
3338 /* lwarx */
3339 LARX(lbarx, 1, ld8u);
3340 LARX(lharx, 2, ld16u);
3341 LARX(lwarx, 4, ld32u);
3342
3343
3344 #if defined(CONFIG_USER_ONLY)
3345 static void gen_conditional_store(DisasContext *ctx, TCGv EA,
3346                                   int reg, int size)
3347 {
3348     TCGv t0 = tcg_temp_new();
3349     uint32_t save_exception = ctx->exception;
3350
3351     tcg_gen_st_tl(EA, cpu_env, offsetof(CPUPPCState, reserve_ea));
3352     tcg_gen_movi_tl(t0, (size << 5) | reg);
3353     tcg_gen_st_tl(t0, cpu_env, offsetof(CPUPPCState, reserve_info));
3354     tcg_temp_free(t0);
3355     gen_update_nip(ctx, ctx->nip-4);
3356     ctx->exception = POWERPC_EXCP_BRANCH;
3357     gen_exception(ctx, POWERPC_EXCP_STCX);
3358     ctx->exception = save_exception;
3359 }
3360 #else
3361 static void gen_conditional_store(DisasContext *ctx, TCGv EA,
3362                                   int reg, int size)
3363 {
3364     TCGLabel *l1;
3365
3366     tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
3367     l1 = gen_new_label();
3368     tcg_gen_brcond_tl(TCG_COND_NE, EA, cpu_reserve, l1);
3369     tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 1 << CRF_EQ);
3370 #if defined(TARGET_PPC64)
3371     if (size == 8) {
3372         gen_qemu_st64(ctx, cpu_gpr[reg], EA);
3373     } else
3374 #endif
3375     if (size == 4) {
3376         gen_qemu_st32(ctx, cpu_gpr[reg], EA);
3377     } else if (size == 2) {
3378         gen_qemu_st16(ctx, cpu_gpr[reg], EA);
3379 #if defined(TARGET_PPC64)
3380     } else if (size == 16) {
3381         TCGv gpr1, gpr2 , EA8;
3382         if (unlikely(ctx->le_mode)) {
3383             gpr1 = cpu_gpr[reg+1];
3384             gpr2 = cpu_gpr[reg];
3385         } else {
3386             gpr1 = cpu_gpr[reg];
3387             gpr2 = cpu_gpr[reg+1];
3388         }
3389         gen_qemu_st64(ctx, gpr1, EA);
3390         EA8 = tcg_temp_local_new();
3391         gen_addr_add(ctx, EA8, EA, 8);
3392         gen_qemu_st64(ctx, gpr2, EA8);
3393         tcg_temp_free(EA8);
3394 #endif
3395     } else {
3396         gen_qemu_st8(ctx, cpu_gpr[reg], EA);
3397     }
3398     gen_set_label(l1);
3399     tcg_gen_movi_tl(cpu_reserve, -1);
3400 }
3401 #endif
3402
3403 #define STCX(name, len)                                   \
3404 static void gen_##name(DisasContext *ctx)                 \
3405 {                                                         \
3406     TCGv t0;                                              \
3407     if (unlikely((len == 16) && (rD(ctx->opcode) & 1))) { \
3408         gen_inval_exception(ctx,                          \
3409                             POWERPC_EXCP_INVAL_INVAL);    \
3410         return;                                           \
3411     }                                                     \
3412     gen_set_access_type(ctx, ACCESS_RES);                 \
3413     t0 = tcg_temp_local_new();                            \
3414     gen_addr_reg_index(ctx, t0);                          \
3415     if (len > 1) {                                        \
3416         gen_check_align(ctx, t0, (len)-1);                \
3417     }                                                     \
3418     gen_conditional_store(ctx, t0, rS(ctx->opcode), len); \
3419     tcg_temp_free(t0);                                    \
3420 }
3421
3422 STCX(stbcx_, 1);
3423 STCX(sthcx_, 2);
3424 STCX(stwcx_, 4);
3425
3426 #if defined(TARGET_PPC64)
3427 /* ldarx */
3428 LARX(ldarx, 8, ld64);
3429
3430 /* lqarx */
3431 static void gen_lqarx(DisasContext *ctx)
3432 {
3433     TCGv EA;
3434     int rd = rD(ctx->opcode);
3435     TCGv gpr1, gpr2;
3436
3437     if (unlikely((rd & 1) || (rd == rA(ctx->opcode)) ||
3438                  (rd == rB(ctx->opcode)))) {
3439         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
3440         return;
3441     }
3442
3443     gen_set_access_type(ctx, ACCESS_RES);
3444     EA = tcg_temp_local_new();
3445     gen_addr_reg_index(ctx, EA);
3446     gen_check_align(ctx, EA, 15);
3447     if (unlikely(ctx->le_mode)) {
3448         gpr1 = cpu_gpr[rd+1];
3449         gpr2 = cpu_gpr[rd];
3450     } else {
3451         gpr1 = cpu_gpr[rd];
3452         gpr2 = cpu_gpr[rd+1];
3453     }
3454     gen_qemu_ld64(ctx, gpr1, EA);
3455     tcg_gen_mov_tl(cpu_reserve, EA);
3456
3457     gen_addr_add(ctx, EA, EA, 8);
3458     gen_qemu_ld64(ctx, gpr2, EA);
3459
3460     tcg_gen_st_tl(gpr1, cpu_env, offsetof(CPUPPCState, reserve_val));
3461     tcg_gen_st_tl(gpr2, cpu_env, offsetof(CPUPPCState, reserve_val2));
3462
3463     tcg_temp_free(EA);
3464 }
3465
3466 /* stdcx. */
3467 STCX(stdcx_, 8);
3468 STCX(stqcx_, 16);
3469 #endif /* defined(TARGET_PPC64) */
3470
3471 /* sync */
3472 static void gen_sync(DisasContext *ctx)
3473 {
3474 }
3475
3476 /* wait */
3477 static void gen_wait(DisasContext *ctx)
3478 {
3479     TCGv_i32 t0 = tcg_temp_new_i32();
3480     tcg_gen_st_i32(t0, cpu_env,
3481                    -offsetof(PowerPCCPU, env) + offsetof(CPUState, halted));
3482     tcg_temp_free_i32(t0);
3483     /* Stop translation, as the CPU is supposed to sleep from now */
3484     gen_exception_err(ctx, EXCP_HLT, 1);
3485 }
3486
3487 /***                         Floating-point load                           ***/
3488 #define GEN_LDF(name, ldop, opc, type)                                        \
3489 static void glue(gen_, name)(DisasContext *ctx)                                       \
3490 {                                                                             \
3491     TCGv EA;                                                                  \
3492     if (unlikely(!ctx->fpu_enabled)) {                                        \
3493         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3494         return;                                                               \
3495     }                                                                         \
3496     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3497     EA = tcg_temp_new();                                                      \
3498     gen_addr_imm_index(ctx, EA, 0);                                           \
3499     gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA);                       \
3500     tcg_temp_free(EA);                                                        \
3501 }
3502
3503 #define GEN_LDUF(name, ldop, opc, type)                                       \
3504 static void glue(gen_, name##u)(DisasContext *ctx)                                    \
3505 {                                                                             \
3506     TCGv EA;                                                                  \
3507     if (unlikely(!ctx->fpu_enabled)) {                                        \
3508         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3509         return;                                                               \
3510     }                                                                         \
3511     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
3512         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
3513         return;                                                               \
3514     }                                                                         \
3515     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3516     EA = tcg_temp_new();                                                      \
3517     gen_addr_imm_index(ctx, EA, 0);                                           \
3518     gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA);                       \
3519     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
3520     tcg_temp_free(EA);                                                        \
3521 }
3522
3523 #define GEN_LDUXF(name, ldop, opc, type)                                      \
3524 static void glue(gen_, name##ux)(DisasContext *ctx)                                   \
3525 {                                                                             \
3526     TCGv EA;                                                                  \
3527     if (unlikely(!ctx->fpu_enabled)) {                                        \
3528         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3529         return;                                                               \
3530     }                                                                         \
3531     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
3532         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
3533         return;                                                               \
3534     }                                                                         \
3535     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3536     EA = tcg_temp_new();                                                      \
3537     gen_addr_reg_index(ctx, EA);                                              \
3538     gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA);                       \
3539     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
3540     tcg_temp_free(EA);                                                        \
3541 }
3542
3543 #define GEN_LDXF(name, ldop, opc2, opc3, type)                                \
3544 static void glue(gen_, name##x)(DisasContext *ctx)                                    \
3545 {                                                                             \
3546     TCGv EA;                                                                  \
3547     if (unlikely(!ctx->fpu_enabled)) {                                        \
3548         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3549         return;                                                               \
3550     }                                                                         \
3551     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3552     EA = tcg_temp_new();                                                      \
3553     gen_addr_reg_index(ctx, EA);                                              \
3554     gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA);                       \
3555     tcg_temp_free(EA);                                                        \
3556 }
3557
3558 #define GEN_LDFS(name, ldop, op, type)                                        \
3559 GEN_LDF(name, ldop, op | 0x20, type);                                         \
3560 GEN_LDUF(name, ldop, op | 0x21, type);                                        \
3561 GEN_LDUXF(name, ldop, op | 0x01, type);                                       \
3562 GEN_LDXF(name, ldop, 0x17, op | 0x00, type)
3563
3564 static inline void gen_qemu_ld32fs(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
3565 {
3566     TCGv t0 = tcg_temp_new();
3567     TCGv_i32 t1 = tcg_temp_new_i32();
3568     gen_qemu_ld32u(ctx, t0, arg2);
3569     tcg_gen_trunc_tl_i32(t1, t0);
3570     tcg_temp_free(t0);
3571     gen_helper_float32_to_float64(arg1, cpu_env, t1);
3572     tcg_temp_free_i32(t1);
3573 }
3574
3575  /* lfd lfdu lfdux lfdx */
3576 GEN_LDFS(lfd, ld64, 0x12, PPC_FLOAT);
3577  /* lfs lfsu lfsux lfsx */
3578 GEN_LDFS(lfs, ld32fs, 0x10, PPC_FLOAT);
3579
3580 /* lfdp */
3581 static void gen_lfdp(DisasContext *ctx)
3582 {
3583     TCGv EA;
3584     if (unlikely(!ctx->fpu_enabled)) {
3585         gen_exception(ctx, POWERPC_EXCP_FPU);
3586         return;
3587     }
3588     gen_set_access_type(ctx, ACCESS_FLOAT);
3589     EA = tcg_temp_new();
3590     gen_addr_imm_index(ctx, EA, 0);
3591     /* We only need to swap high and low halves. gen_qemu_ld64 does necessary
3592        64-bit byteswap already. */
3593     if (unlikely(ctx->le_mode)) {
3594         gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
3595         tcg_gen_addi_tl(EA, EA, 8);
3596         gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
3597     } else {
3598         gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
3599         tcg_gen_addi_tl(EA, EA, 8);
3600         gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
3601     }
3602     tcg_temp_free(EA);
3603 }
3604
3605 /* lfdpx */
3606 static void gen_lfdpx(DisasContext *ctx)
3607 {
3608     TCGv EA;
3609     if (unlikely(!ctx->fpu_enabled)) {
3610         gen_exception(ctx, POWERPC_EXCP_FPU);
3611         return;
3612     }
3613     gen_set_access_type(ctx, ACCESS_FLOAT);
3614     EA = tcg_temp_new();
3615     gen_addr_reg_index(ctx, EA);
3616     /* We only need to swap high and low halves. gen_qemu_ld64 does necessary
3617        64-bit byteswap already. */
3618     if (unlikely(ctx->le_mode)) {
3619         gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
3620         tcg_gen_addi_tl(EA, EA, 8);
3621         gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
3622     } else {
3623         gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
3624         tcg_gen_addi_tl(EA, EA, 8);
3625         gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
3626     }
3627     tcg_temp_free(EA);
3628 }
3629
3630 /* lfiwax */
3631 static void gen_lfiwax(DisasContext *ctx)
3632 {
3633     TCGv EA;
3634     TCGv t0;
3635     if (unlikely(!ctx->fpu_enabled)) {
3636         gen_exception(ctx, POWERPC_EXCP_FPU);
3637         return;
3638     }
3639     gen_set_access_type(ctx, ACCESS_FLOAT);
3640     EA = tcg_temp_new();
3641     t0 = tcg_temp_new();
3642     gen_addr_reg_index(ctx, EA);
3643     gen_qemu_ld32s(ctx, t0, EA);
3644     tcg_gen_ext_tl_i64(cpu_fpr[rD(ctx->opcode)], t0);
3645     tcg_temp_free(EA);
3646     tcg_temp_free(t0);
3647 }
3648
3649 /* lfiwzx */
3650 static void gen_lfiwzx(DisasContext *ctx)
3651 {
3652     TCGv EA;
3653     if (unlikely(!ctx->fpu_enabled)) {
3654         gen_exception(ctx, POWERPC_EXCP_FPU);
3655         return;
3656     }
3657     gen_set_access_type(ctx, ACCESS_FLOAT);
3658     EA = tcg_temp_new();
3659     gen_addr_reg_index(ctx, EA);
3660     gen_qemu_ld32u_i64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
3661     tcg_temp_free(EA);
3662 }
3663 /***                         Floating-point store                          ***/
3664 #define GEN_STF(name, stop, opc, type)                                        \
3665 static void glue(gen_, name)(DisasContext *ctx)                                       \
3666 {                                                                             \
3667     TCGv EA;                                                                  \
3668     if (unlikely(!ctx->fpu_enabled)) {                                        \
3669         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3670         return;                                                               \
3671     }                                                                         \
3672     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3673     EA = tcg_temp_new();                                                      \
3674     gen_addr_imm_index(ctx, EA, 0);                                           \
3675     gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA);                       \
3676     tcg_temp_free(EA);                                                        \
3677 }
3678
3679 #define GEN_STUF(name, stop, opc, type)                                       \
3680 static void glue(gen_, name##u)(DisasContext *ctx)                                    \
3681 {                                                                             \
3682     TCGv EA;                                                                  \
3683     if (unlikely(!ctx->fpu_enabled)) {                                        \
3684         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3685         return;                                                               \
3686     }                                                                         \
3687     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
3688         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
3689         return;                                                               \
3690     }                                                                         \
3691     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3692     EA = tcg_temp_new();                                                      \
3693     gen_addr_imm_index(ctx, EA, 0);                                           \
3694     gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA);                       \
3695     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
3696     tcg_temp_free(EA);                                                        \
3697 }
3698
3699 #define GEN_STUXF(name, stop, opc, type)                                      \
3700 static void glue(gen_, name##ux)(DisasContext *ctx)                                   \
3701 {                                                                             \
3702     TCGv EA;                                                                  \
3703     if (unlikely(!ctx->fpu_enabled)) {                                        \
3704         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3705         return;                                                               \
3706     }                                                                         \
3707     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
3708         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
3709         return;                                                               \
3710     }                                                                         \
3711     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3712     EA = tcg_temp_new();                                                      \
3713     gen_addr_reg_index(ctx, EA);                                              \
3714     gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA);                       \
3715     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
3716     tcg_temp_free(EA);                                                        \
3717 }
3718
3719 #define GEN_STXF(name, stop, opc2, opc3, type)                                \
3720 static void glue(gen_, name##x)(DisasContext *ctx)                                    \
3721 {                                                                             \
3722     TCGv EA;                                                                  \
3723     if (unlikely(!ctx->fpu_enabled)) {                                        \
3724         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3725         return;                                                               \
3726     }                                                                         \
3727     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3728     EA = tcg_temp_new();                                                      \
3729     gen_addr_reg_index(ctx, EA);                                              \
3730     gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA);                       \
3731     tcg_temp_free(EA);                                                        \
3732 }
3733
3734 #define GEN_STFS(name, stop, op, type)                                        \
3735 GEN_STF(name, stop, op | 0x20, type);                                         \
3736 GEN_STUF(name, stop, op | 0x21, type);                                        \
3737 GEN_STUXF(name, stop, op | 0x01, type);                                       \
3738 GEN_STXF(name, stop, 0x17, op | 0x00, type)
3739
3740 static inline void gen_qemu_st32fs(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
3741 {
3742     TCGv_i32 t0 = tcg_temp_new_i32();
3743     TCGv t1 = tcg_temp_new();
3744     gen_helper_float64_to_float32(t0, cpu_env, arg1);
3745     tcg_gen_extu_i32_tl(t1, t0);
3746     tcg_temp_free_i32(t0);
3747     gen_qemu_st32(ctx, t1, arg2);
3748     tcg_temp_free(t1);
3749 }
3750
3751 /* stfd stfdu stfdux stfdx */
3752 GEN_STFS(stfd, st64, 0x16, PPC_FLOAT);
3753 /* stfs stfsu stfsux stfsx */
3754 GEN_STFS(stfs, st32fs, 0x14, PPC_FLOAT);
3755
3756 /* stfdp */
3757 static void gen_stfdp(DisasContext *ctx)
3758 {
3759     TCGv EA;
3760     if (unlikely(!ctx->fpu_enabled)) {
3761         gen_exception(ctx, POWERPC_EXCP_FPU);
3762         return;
3763     }
3764     gen_set_access_type(ctx, ACCESS_FLOAT);
3765     EA = tcg_temp_new();
3766     gen_addr_imm_index(ctx, EA, 0);
3767     /* We only need to swap high and low halves. gen_qemu_st64 does necessary
3768        64-bit byteswap already. */
3769     if (unlikely(ctx->le_mode)) {
3770         gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
3771         tcg_gen_addi_tl(EA, EA, 8);
3772         gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
3773     } else {
3774         gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
3775         tcg_gen_addi_tl(EA, EA, 8);
3776         gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
3777     }
3778     tcg_temp_free(EA);
3779 }
3780
3781 /* stfdpx */
3782 static void gen_stfdpx(DisasContext *ctx)
3783 {
3784     TCGv EA;
3785     if (unlikely(!ctx->fpu_enabled)) {
3786         gen_exception(ctx, POWERPC_EXCP_FPU);
3787         return;
3788     }
3789     gen_set_access_type(ctx, ACCESS_FLOAT);
3790     EA = tcg_temp_new();
3791     gen_addr_reg_index(ctx, EA);
3792     /* We only need to swap high and low halves. gen_qemu_st64 does necessary
3793        64-bit byteswap already. */
3794     if (unlikely(ctx->le_mode)) {
3795         gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
3796         tcg_gen_addi_tl(EA, EA, 8);
3797         gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
3798     } else {
3799         gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
3800         tcg_gen_addi_tl(EA, EA, 8);
3801         gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
3802     }
3803     tcg_temp_free(EA);
3804 }
3805
3806 /* Optional: */
3807 static inline void gen_qemu_st32fiw(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
3808 {
3809     TCGv t0 = tcg_temp_new();
3810     tcg_gen_trunc_i64_tl(t0, arg1),
3811     gen_qemu_st32(ctx, t0, arg2);
3812     tcg_temp_free(t0);
3813 }
3814 /* stfiwx */
3815 GEN_STXF(stfiw, st32fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX);
3816
3817 static inline void gen_update_cfar(DisasContext *ctx, target_ulong nip)
3818 {
3819 #if defined(TARGET_PPC64)
3820     if (ctx->has_cfar)
3821         tcg_gen_movi_tl(cpu_cfar, nip);
3822 #endif
3823 }
3824
3825 /***                                Branch                                 ***/
3826 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
3827 {
3828     TranslationBlock *tb;
3829     tb = ctx->tb;
3830     if (NARROW_MODE(ctx)) {
3831         dest = (uint32_t) dest;
3832     }
3833     if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3834         likely(!ctx->singlestep_enabled)) {
3835         tcg_gen_goto_tb(n);
3836         tcg_gen_movi_tl(cpu_nip, dest & ~3);
3837         tcg_gen_exit_tb((uintptr_t)tb + n);
3838     } else {
3839         tcg_gen_movi_tl(cpu_nip, dest & ~3);
3840         if (unlikely(ctx->singlestep_enabled)) {
3841             if ((ctx->singlestep_enabled &
3842                 (CPU_BRANCH_STEP | CPU_SINGLE_STEP)) &&
3843                 (ctx->exception == POWERPC_EXCP_BRANCH ||
3844                  ctx->exception == POWERPC_EXCP_TRACE)) {
3845                 target_ulong tmp = ctx->nip;
3846                 ctx->nip = dest;
3847                 gen_exception(ctx, POWERPC_EXCP_TRACE);
3848                 ctx->nip = tmp;
3849             }
3850             if (ctx->singlestep_enabled & GDBSTUB_SINGLE_STEP) {
3851                 gen_debug_exception(ctx);
3852             }
3853         }
3854         tcg_gen_exit_tb(0);
3855     }
3856 }
3857
3858 static inline void gen_setlr(DisasContext *ctx, target_ulong nip)
3859 {
3860     if (NARROW_MODE(ctx)) {
3861         nip = (uint32_t)nip;
3862     }
3863     tcg_gen_movi_tl(cpu_lr, nip);
3864 }
3865
3866 /* b ba bl bla */
3867 static void gen_b(DisasContext *ctx)
3868 {
3869     target_ulong li, target;
3870
3871     ctx->exception = POWERPC_EXCP_BRANCH;
3872     /* sign extend LI */
3873     li = LI(ctx->opcode);
3874     li = (li ^ 0x02000000) - 0x02000000;
3875     if (likely(AA(ctx->opcode) == 0)) {
3876         target = ctx->nip + li - 4;
3877     } else {
3878         target = li;
3879     }
3880     if (LK(ctx->opcode)) {
3881         gen_setlr(ctx, ctx->nip);
3882     }
3883     gen_update_cfar(ctx, ctx->nip);
3884     gen_goto_tb(ctx, 0, target);
3885 }
3886
3887 #define BCOND_IM  0
3888 #define BCOND_LR  1
3889 #define BCOND_CTR 2
3890 #define BCOND_TAR 3
3891
3892 static inline void gen_bcond(DisasContext *ctx, int type)
3893 {
3894     uint32_t bo = BO(ctx->opcode);
3895     TCGLabel *l1;
3896     TCGv target;
3897
3898     ctx->exception = POWERPC_EXCP_BRANCH;
3899     if (type == BCOND_LR || type == BCOND_CTR || type == BCOND_TAR) {
3900         target = tcg_temp_local_new();
3901         if (type == BCOND_CTR)
3902             tcg_gen_mov_tl(target, cpu_ctr);
3903         else if (type == BCOND_TAR)
3904             gen_load_spr(target, SPR_TAR);
3905         else
3906             tcg_gen_mov_tl(target, cpu_lr);
3907     } else {
3908         TCGV_UNUSED(target);
3909     }
3910     if (LK(ctx->opcode))
3911         gen_setlr(ctx, ctx->nip);
3912     l1 = gen_new_label();
3913     if ((bo & 0x4) == 0) {
3914         /* Decrement and test CTR */
3915         TCGv temp = tcg_temp_new();
3916         if (unlikely(type == BCOND_CTR)) {
3917             gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
3918             return;
3919         }
3920         tcg_gen_subi_tl(cpu_ctr, cpu_ctr, 1);
3921         if (NARROW_MODE(ctx)) {
3922             tcg_gen_ext32u_tl(temp, cpu_ctr);
3923         } else {
3924             tcg_gen_mov_tl(temp, cpu_ctr);
3925         }
3926         if (bo & 0x2) {
3927             tcg_gen_brcondi_tl(TCG_COND_NE, temp, 0, l1);
3928         } else {
3929             tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1);
3930         }
3931         tcg_temp_free(temp);
3932     }
3933     if ((bo & 0x10) == 0) {
3934         /* Test CR */
3935         uint32_t bi = BI(ctx->opcode);
3936         uint32_t mask = 0x08 >> (bi & 0x03);
3937         TCGv_i32 temp = tcg_temp_new_i32();
3938
3939         if (bo & 0x8) {
3940             tcg_gen_andi_i32(temp, cpu_crf[bi >> 2], mask);
3941             tcg_gen_brcondi_i32(TCG_COND_EQ, temp, 0, l1);
3942         } else {
3943             tcg_gen_andi_i32(temp, cpu_crf[bi >> 2], mask);
3944             tcg_gen_brcondi_i32(TCG_COND_NE, temp, 0, l1);
3945         }
3946         tcg_temp_free_i32(temp);
3947     }
3948     gen_update_cfar(ctx, ctx->nip);
3949     if (type == BCOND_IM) {
3950         target_ulong li = (target_long)((int16_t)(BD(ctx->opcode)));
3951         if (likely(AA(ctx->opcode) == 0)) {
3952             gen_goto_tb(ctx, 0, ctx->nip + li - 4);
3953         } else {
3954             gen_goto_tb(ctx, 0, li);
3955         }
3956         gen_set_label(l1);
3957         gen_goto_tb(ctx, 1, ctx->nip);
3958     } else {
3959         if (NARROW_MODE(ctx)) {
3960             tcg_gen_andi_tl(cpu_nip, target, (uint32_t)~3);
3961         } else {
3962             tcg_gen_andi_tl(cpu_nip, target, ~3);
3963         }
3964         tcg_gen_exit_tb(0);
3965         gen_set_label(l1);
3966         gen_update_nip(ctx, ctx->nip);
3967         tcg_gen_exit_tb(0);
3968     }
3969     if (type == BCOND_LR || type == BCOND_CTR || type == BCOND_TAR) {
3970         tcg_temp_free(target);
3971     }
3972 }
3973
3974 static void gen_bc(DisasContext *ctx)
3975 {
3976     gen_bcond(ctx, BCOND_IM);
3977 }
3978
3979 static void gen_bcctr(DisasContext *ctx)
3980 {
3981     gen_bcond(ctx, BCOND_CTR);
3982 }
3983
3984 static void gen_bclr(DisasContext *ctx)
3985 {
3986     gen_bcond(ctx, BCOND_LR);
3987 }
3988
3989 static void gen_bctar(DisasContext *ctx)
3990 {
3991     gen_bcond(ctx, BCOND_TAR);
3992 }
3993
3994 /***                      Condition register logical                       ***/
3995 #define GEN_CRLOGIC(name, tcg_op, opc)                                        \
3996 static void glue(gen_, name)(DisasContext *ctx)                                       \
3997 {                                                                             \
3998     uint8_t bitmask;                                                          \
3999     int sh;                                                                   \
4000     TCGv_i32 t0, t1;                                                          \
4001     sh = (crbD(ctx->opcode) & 0x03) - (crbA(ctx->opcode) & 0x03);             \
4002     t0 = tcg_temp_new_i32();                                                  \
4003     if (sh > 0)                                                               \
4004         tcg_gen_shri_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2], sh);            \
4005     else if (sh < 0)                                                          \
4006         tcg_gen_shli_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2], -sh);           \
4007     else                                                                      \
4008         tcg_gen_mov_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2]);                 \
4009     t1 = tcg_temp_new_i32();                                                  \
4010     sh = (crbD(ctx->opcode) & 0x03) - (crbB(ctx->opcode) & 0x03);             \
4011     if (sh > 0)                                                               \
4012         tcg_gen_shri_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2], sh);            \
4013     else if (sh < 0)                                                          \
4014         tcg_gen_shli_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2], -sh);           \
4015     else                                                                      \
4016         tcg_gen_mov_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2]);                 \
4017     tcg_op(t0, t0, t1);                                                       \
4018     bitmask = 0x08 >> (crbD(ctx->opcode) & 0x03);                             \
4019     tcg_gen_andi_i32(t0, t0, bitmask);                                        \
4020     tcg_gen_andi_i32(t1, cpu_crf[crbD(ctx->opcode) >> 2], ~bitmask);          \
4021     tcg_gen_or_i32(cpu_crf[crbD(ctx->opcode) >> 2], t0, t1);                  \
4022     tcg_temp_free_i32(t0);                                                    \
4023     tcg_temp_free_i32(t1);                                                    \
4024 }
4025
4026 /* crand */
4027 GEN_CRLOGIC(crand, tcg_gen_and_i32, 0x08);
4028 /* crandc */
4029 GEN_CRLOGIC(crandc, tcg_gen_andc_i32, 0x04);
4030 /* creqv */
4031 GEN_CRLOGIC(creqv, tcg_gen_eqv_i32, 0x09);
4032 /* crnand */
4033 GEN_CRLOGIC(crnand, tcg_gen_nand_i32, 0x07);
4034 /* crnor */
4035 GEN_CRLOGIC(crnor, tcg_gen_nor_i32, 0x01);
4036 /* cror */
4037 GEN_CRLOGIC(cror, tcg_gen_or_i32, 0x0E);
4038 /* crorc */
4039 GEN_CRLOGIC(crorc, tcg_gen_orc_i32, 0x0D);
4040 /* crxor */
4041 GEN_CRLOGIC(crxor, tcg_gen_xor_i32, 0x06);
4042
4043 /* mcrf */
4044 static void gen_mcrf(DisasContext *ctx)
4045 {
4046     tcg_gen_mov_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfS(ctx->opcode)]);
4047 }
4048
4049 /***                           System linkage                              ***/
4050
4051 /* rfi (supervisor only) */
4052 static void gen_rfi(DisasContext *ctx)
4053 {
4054 #if defined(CONFIG_USER_ONLY)
4055     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4056 #else
4057     /* Restore CPU state */
4058     if (unlikely(ctx->pr)) {
4059         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4060         return;
4061     }
4062     gen_update_cfar(ctx, ctx->nip);
4063     gen_helper_rfi(cpu_env);
4064     gen_sync_exception(ctx);
4065 #endif
4066 }
4067
4068 #if defined(TARGET_PPC64)
4069 static void gen_rfid(DisasContext *ctx)
4070 {
4071 #if defined(CONFIG_USER_ONLY)
4072     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4073 #else
4074     /* Restore CPU state */
4075     if (unlikely(ctx->pr)) {
4076         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4077         return;
4078     }
4079     gen_update_cfar(ctx, ctx->nip);
4080     gen_helper_rfid(cpu_env);
4081     gen_sync_exception(ctx);
4082 #endif
4083 }
4084
4085 static void gen_hrfid(DisasContext *ctx)
4086 {
4087 #if defined(CONFIG_USER_ONLY)
4088     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4089 #else
4090     /* Restore CPU state */
4091     if (unlikely(!ctx->hv)) {
4092         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4093         return;
4094     }
4095     gen_helper_hrfid(cpu_env);
4096     gen_sync_exception(ctx);
4097 #endif
4098 }
4099 #endif
4100
4101 /* sc */
4102 #if defined(CONFIG_USER_ONLY)
4103 #define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL_USER
4104 #else
4105 #define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL
4106 #endif
4107 static void gen_sc(DisasContext *ctx)
4108 {
4109     uint32_t lev;
4110
4111     lev = (ctx->opcode >> 5) & 0x7F;
4112     gen_exception_err(ctx, POWERPC_SYSCALL, lev);
4113 }
4114
4115 /***                                Trap                                   ***/
4116
4117 /* tw */
4118 static void gen_tw(DisasContext *ctx)
4119 {
4120     TCGv_i32 t0 = tcg_const_i32(TO(ctx->opcode));
4121     /* Update the nip since this might generate a trap exception */
4122     gen_update_nip(ctx, ctx->nip);
4123     gen_helper_tw(cpu_env, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
4124                   t0);
4125     tcg_temp_free_i32(t0);
4126 }
4127
4128 /* twi */
4129 static void gen_twi(DisasContext *ctx)
4130 {
4131     TCGv t0 = tcg_const_tl(SIMM(ctx->opcode));
4132     TCGv_i32 t1 = tcg_const_i32(TO(ctx->opcode));
4133     /* Update the nip since this might generate a trap exception */
4134     gen_update_nip(ctx, ctx->nip);
4135     gen_helper_tw(cpu_env, cpu_gpr[rA(ctx->opcode)], t0, t1);
4136     tcg_temp_free(t0);
4137     tcg_temp_free_i32(t1);
4138 }
4139
4140 #if defined(TARGET_PPC64)
4141 /* td */
4142 static void gen_td(DisasContext *ctx)
4143 {
4144     TCGv_i32 t0 = tcg_const_i32(TO(ctx->opcode));
4145     /* Update the nip since this might generate a trap exception */
4146     gen_update_nip(ctx, ctx->nip);
4147     gen_helper_td(cpu_env, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
4148                   t0);
4149     tcg_temp_free_i32(t0);
4150 }
4151
4152 /* tdi */
4153 static void gen_tdi(DisasContext *ctx)
4154 {
4155     TCGv t0 = tcg_const_tl(SIMM(ctx->opcode));
4156     TCGv_i32 t1 = tcg_const_i32(TO(ctx->opcode));
4157     /* Update the nip since this might generate a trap exception */
4158     gen_update_nip(ctx, ctx->nip);
4159     gen_helper_td(cpu_env, cpu_gpr[rA(ctx->opcode)], t0, t1);
4160     tcg_temp_free(t0);
4161     tcg_temp_free_i32(t1);
4162 }
4163 #endif
4164
4165 /***                          Processor control                            ***/
4166
4167 static void gen_read_xer(TCGv dst)
4168 {
4169     TCGv t0 = tcg_temp_new();
4170     TCGv t1 = tcg_temp_new();
4171     TCGv t2 = tcg_temp_new();
4172     tcg_gen_mov_tl(dst, cpu_xer);
4173     tcg_gen_shli_tl(t0, cpu_so, XER_SO);
4174     tcg_gen_shli_tl(t1, cpu_ov, XER_OV);
4175     tcg_gen_shli_tl(t2, cpu_ca, XER_CA);
4176     tcg_gen_or_tl(t0, t0, t1);
4177     tcg_gen_or_tl(dst, dst, t2);
4178     tcg_gen_or_tl(dst, dst, t0);
4179     tcg_temp_free(t0);
4180     tcg_temp_free(t1);
4181     tcg_temp_free(t2);
4182 }
4183
4184 static void gen_write_xer(TCGv src)
4185 {
4186     tcg_gen_andi_tl(cpu_xer, src,
4187                     ~((1u << XER_SO) | (1u << XER_OV) | (1u << XER_CA)));
4188     tcg_gen_shri_tl(cpu_so, src, XER_SO);
4189     tcg_gen_shri_tl(cpu_ov, src, XER_OV);
4190     tcg_gen_shri_tl(cpu_ca, src, XER_CA);
4191     tcg_gen_andi_tl(cpu_so, cpu_so, 1);
4192     tcg_gen_andi_tl(cpu_ov, cpu_ov, 1);
4193     tcg_gen_andi_tl(cpu_ca, cpu_ca, 1);
4194 }
4195
4196 /* mcrxr */
4197 static void gen_mcrxr(DisasContext *ctx)
4198 {
4199     TCGv_i32 t0 = tcg_temp_new_i32();
4200     TCGv_i32 t1 = tcg_temp_new_i32();
4201     TCGv_i32 dst = cpu_crf[crfD(ctx->opcode)];
4202
4203     tcg_gen_trunc_tl_i32(t0, cpu_so);
4204     tcg_gen_trunc_tl_i32(t1, cpu_ov);
4205     tcg_gen_trunc_tl_i32(dst, cpu_ca);
4206     tcg_gen_shli_i32(t0, t0, 3);
4207     tcg_gen_shli_i32(t1, t1, 2);
4208     tcg_gen_shli_i32(dst, dst, 1);
4209     tcg_gen_or_i32(dst, dst, t0);
4210     tcg_gen_or_i32(dst, dst, t1);
4211     tcg_temp_free_i32(t0);
4212     tcg_temp_free_i32(t1);
4213
4214     tcg_gen_movi_tl(cpu_so, 0);
4215     tcg_gen_movi_tl(cpu_ov, 0);
4216     tcg_gen_movi_tl(cpu_ca, 0);
4217 }
4218
4219 /* mfcr mfocrf */
4220 static void gen_mfcr(DisasContext *ctx)
4221 {
4222     uint32_t crm, crn;
4223
4224     if (likely(ctx->opcode & 0x00100000)) {
4225         crm = CRM(ctx->opcode);
4226         if (likely(crm && ((crm & (crm - 1)) == 0))) {
4227             crn = ctz32 (crm);
4228             tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], cpu_crf[7 - crn]);
4229             tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)],
4230                             cpu_gpr[rD(ctx->opcode)], crn * 4);
4231         }
4232     } else {
4233         TCGv_i32 t0 = tcg_temp_new_i32();
4234         tcg_gen_mov_i32(t0, cpu_crf[0]);
4235         tcg_gen_shli_i32(t0, t0, 4);
4236         tcg_gen_or_i32(t0, t0, cpu_crf[1]);
4237         tcg_gen_shli_i32(t0, t0, 4);
4238         tcg_gen_or_i32(t0, t0, cpu_crf[2]);
4239         tcg_gen_shli_i32(t0, t0, 4);
4240         tcg_gen_or_i32(t0, t0, cpu_crf[3]);
4241         tcg_gen_shli_i32(t0, t0, 4);
4242         tcg_gen_or_i32(t0, t0, cpu_crf[4]);
4243         tcg_gen_shli_i32(t0, t0, 4);
4244         tcg_gen_or_i32(t0, t0, cpu_crf[5]);
4245         tcg_gen_shli_i32(t0, t0, 4);
4246         tcg_gen_or_i32(t0, t0, cpu_crf[6]);
4247         tcg_gen_shli_i32(t0, t0, 4);
4248         tcg_gen_or_i32(t0, t0, cpu_crf[7]);
4249         tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0);
4250         tcg_temp_free_i32(t0);
4251     }
4252 }
4253
4254 /* mfmsr */
4255 static void gen_mfmsr(DisasContext *ctx)
4256 {
4257 #if defined(CONFIG_USER_ONLY)
4258     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4259 #else
4260     if (unlikely(ctx->pr)) {
4261         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4262         return;
4263     }
4264     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_msr);
4265 #endif
4266 }
4267
4268 static void spr_noaccess(DisasContext *ctx, int gprn, int sprn)
4269 {
4270 #if 0
4271     sprn = ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
4272     printf("ERROR: try to access SPR %d !\n", sprn);
4273 #endif
4274 }
4275 #define SPR_NOACCESS (&spr_noaccess)
4276
4277 /* mfspr */
4278 static inline void gen_op_mfspr(DisasContext *ctx)
4279 {
4280     void (*read_cb)(DisasContext *ctx, int gprn, int sprn);
4281     uint32_t sprn = SPR(ctx->opcode);
4282
4283 #if defined(CONFIG_USER_ONLY)
4284     read_cb = ctx->spr_cb[sprn].uea_read;
4285 #else
4286     if (ctx->pr) {
4287         read_cb = ctx->spr_cb[sprn].uea_read;
4288     } else if (ctx->hv) {
4289         read_cb = ctx->spr_cb[sprn].hea_read;
4290     } else {
4291         read_cb = ctx->spr_cb[sprn].oea_read;
4292     }
4293 #endif
4294     if (likely(read_cb != NULL)) {
4295         if (likely(read_cb != SPR_NOACCESS)) {
4296             (*read_cb)(ctx, rD(ctx->opcode), sprn);
4297         } else {
4298             /* Privilege exception */
4299             /* This is a hack to avoid warnings when running Linux:
4300              * this OS breaks the PowerPC virtualisation model,
4301              * allowing userland application to read the PVR
4302              */
4303             if (sprn != SPR_PVR) {
4304                 fprintf(stderr, "Trying to read privileged spr %d (0x%03x) at "
4305                         TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
4306                 if (qemu_log_separate()) {
4307                     qemu_log("Trying to read privileged spr %d (0x%03x) at "
4308                              TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
4309                 }
4310             }
4311             gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4312         }
4313     } else {
4314         /* Not defined */
4315         fprintf(stderr, "Trying to read invalid spr %d (0x%03x) at "
4316                 TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
4317         if (qemu_log_separate()) {
4318             qemu_log("Trying to read invalid spr %d (0x%03x) at "
4319                      TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
4320         }
4321         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR);
4322     }
4323 }
4324
4325 static void gen_mfspr(DisasContext *ctx)
4326 {
4327     gen_op_mfspr(ctx);
4328 }
4329
4330 /* mftb */
4331 static void gen_mftb(DisasContext *ctx)
4332 {
4333     gen_op_mfspr(ctx);
4334 }
4335
4336 /* mtcrf mtocrf*/
4337 static void gen_mtcrf(DisasContext *ctx)
4338 {
4339     uint32_t crm, crn;
4340
4341     crm = CRM(ctx->opcode);
4342     if (likely((ctx->opcode & 0x00100000))) {
4343         if (crm && ((crm & (crm - 1)) == 0)) {
4344             TCGv_i32 temp = tcg_temp_new_i32();
4345             crn = ctz32 (crm);
4346             tcg_gen_trunc_tl_i32(temp, cpu_gpr[rS(ctx->opcode)]);
4347             tcg_gen_shri_i32(temp, temp, crn * 4);
4348             tcg_gen_andi_i32(cpu_crf[7 - crn], temp, 0xf);
4349             tcg_temp_free_i32(temp);
4350         }
4351     } else {
4352         TCGv_i32 temp = tcg_temp_new_i32();
4353         tcg_gen_trunc_tl_i32(temp, cpu_gpr[rS(ctx->opcode)]);
4354         for (crn = 0 ; crn < 8 ; crn++) {
4355             if (crm & (1 << crn)) {
4356                     tcg_gen_shri_i32(cpu_crf[7 - crn], temp, crn * 4);
4357                     tcg_gen_andi_i32(cpu_crf[7 - crn], cpu_crf[7 - crn], 0xf);
4358             }
4359         }
4360         tcg_temp_free_i32(temp);
4361     }
4362 }
4363
4364 /* mtmsr */
4365 #if defined(TARGET_PPC64)
4366 static void gen_mtmsrd(DisasContext *ctx)
4367 {
4368 #if defined(CONFIG_USER_ONLY)
4369     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4370 #else
4371     if (unlikely(ctx->pr)) {
4372         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4373         return;
4374     }
4375     if (ctx->opcode & 0x00010000) {
4376         /* Special form that does not need any synchronisation */
4377         TCGv t0 = tcg_temp_new();
4378         tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1 << MSR_RI) | (1 << MSR_EE));
4379         tcg_gen_andi_tl(cpu_msr, cpu_msr, ~((1 << MSR_RI) | (1 << MSR_EE)));
4380         tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
4381         tcg_temp_free(t0);
4382     } else {
4383         /* XXX: we need to update nip before the store
4384          *      if we enter power saving mode, we will exit the loop
4385          *      directly from ppc_store_msr
4386          */
4387         gen_update_nip(ctx, ctx->nip);
4388         gen_helper_store_msr(cpu_env, cpu_gpr[rS(ctx->opcode)]);
4389         /* Must stop the translation as machine state (may have) changed */
4390         /* Note that mtmsr is not always defined as context-synchronizing */
4391         gen_stop_exception(ctx);
4392     }
4393 #endif
4394 }
4395 #endif
4396
4397 static void gen_mtmsr(DisasContext *ctx)
4398 {
4399 #if defined(CONFIG_USER_ONLY)
4400     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4401 #else
4402     if (unlikely(ctx->pr)) {
4403         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4404         return;
4405     }
4406     if (ctx->opcode & 0x00010000) {
4407         /* Special form that does not need any synchronisation */
4408         TCGv t0 = tcg_temp_new();
4409         tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1 << MSR_RI) | (1 << MSR_EE));
4410         tcg_gen_andi_tl(cpu_msr, cpu_msr, ~((1 << MSR_RI) | (1 << MSR_EE)));
4411         tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
4412         tcg_temp_free(t0);
4413     } else {
4414         TCGv msr = tcg_temp_new();
4415
4416         /* XXX: we need to update nip before the store
4417          *      if we enter power saving mode, we will exit the loop
4418          *      directly from ppc_store_msr
4419          */
4420         gen_update_nip(ctx, ctx->nip);
4421 #if defined(TARGET_PPC64)
4422         tcg_gen_deposit_tl(msr, cpu_msr, cpu_gpr[rS(ctx->opcode)], 0, 32);
4423 #else
4424         tcg_gen_mov_tl(msr, cpu_gpr[rS(ctx->opcode)]);
4425 #endif
4426         gen_helper_store_msr(cpu_env, msr);
4427         tcg_temp_free(msr);
4428         /* Must stop the translation as machine state (may have) changed */
4429         /* Note that mtmsr is not always defined as context-synchronizing */
4430         gen_stop_exception(ctx);
4431     }
4432 #endif
4433 }
4434
4435 /* mtspr */
4436 static void gen_mtspr(DisasContext *ctx)
4437 {
4438     void (*write_cb)(DisasContext *ctx, int sprn, int gprn);
4439     uint32_t sprn = SPR(ctx->opcode);
4440
4441 #if defined(CONFIG_USER_ONLY)
4442     write_cb = ctx->spr_cb[sprn].uea_write;
4443 #else
4444     if (ctx->pr) {
4445         write_cb = ctx->spr_cb[sprn].uea_write;
4446     } else if (ctx->hv) {
4447         write_cb = ctx->spr_cb[sprn].hea_write;
4448     } else {
4449         write_cb = ctx->spr_cb[sprn].oea_write;
4450     }
4451 #endif
4452     if (likely(write_cb != NULL)) {
4453         if (likely(write_cb != SPR_NOACCESS)) {
4454             (*write_cb)(ctx, sprn, rS(ctx->opcode));
4455         } else {
4456             /* Privilege exception */
4457             fprintf(stderr, "Trying to write privileged spr %d (0x%03x) at "
4458                     TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
4459             if (qemu_log_separate()) {
4460                 qemu_log("Trying to write privileged spr %d (0x%03x) at "
4461                          TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
4462             }
4463             gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4464         }
4465     } else {
4466         /* Not defined */
4467         if (qemu_log_separate()) {
4468             qemu_log("Trying to write invalid spr %d (0x%03x) at "
4469                      TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
4470         }
4471         fprintf(stderr, "Trying to write invalid spr %d (0x%03x) at "
4472                 TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
4473         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR);
4474     }
4475 }
4476
4477 /***                         Cache management                              ***/
4478
4479 /* dcbf */
4480 static void gen_dcbf(DisasContext *ctx)
4481 {
4482     /* XXX: specification says this is treated as a load by the MMU */
4483     TCGv t0;
4484     gen_set_access_type(ctx, ACCESS_CACHE);
4485     t0 = tcg_temp_new();
4486     gen_addr_reg_index(ctx, t0);
4487     gen_qemu_ld8u(ctx, t0, t0);
4488     tcg_temp_free(t0);
4489 }
4490
4491 /* dcbi (Supervisor only) */
4492 static void gen_dcbi(DisasContext *ctx)
4493 {
4494 #if defined(CONFIG_USER_ONLY)
4495     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4496 #else
4497     TCGv EA, val;
4498     if (unlikely(ctx->pr)) {
4499         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4500         return;
4501     }
4502     EA = tcg_temp_new();
4503     gen_set_access_type(ctx, ACCESS_CACHE);
4504     gen_addr_reg_index(ctx, EA);
4505     val = tcg_temp_new();
4506     /* XXX: specification says this should be treated as a store by the MMU */
4507     gen_qemu_ld8u(ctx, val, EA);
4508     gen_qemu_st8(ctx, val, EA);
4509     tcg_temp_free(val);
4510     tcg_temp_free(EA);
4511 #endif
4512 }
4513
4514 /* dcdst */
4515 static void gen_dcbst(DisasContext *ctx)
4516 {
4517     /* XXX: specification say this is treated as a load by the MMU */
4518     TCGv t0;
4519     gen_set_access_type(ctx, ACCESS_CACHE);
4520     t0 = tcg_temp_new();
4521     gen_addr_reg_index(ctx, t0);
4522     gen_qemu_ld8u(ctx, t0, t0);
4523     tcg_temp_free(t0);
4524 }
4525
4526 /* dcbt */
4527 static void gen_dcbt(DisasContext *ctx)
4528 {
4529     /* interpreted as no-op */
4530     /* XXX: specification say this is treated as a load by the MMU
4531      *      but does not generate any exception
4532      */
4533 }
4534
4535 /* dcbtst */
4536 static void gen_dcbtst(DisasContext *ctx)
4537 {
4538     /* interpreted as no-op */
4539     /* XXX: specification say this is treated as a load by the MMU
4540      *      but does not generate any exception
4541      */
4542 }
4543
4544 /* dcbtls */
4545 static void gen_dcbtls(DisasContext *ctx)
4546 {
4547     /* Always fails locking the cache */
4548     TCGv t0 = tcg_temp_new();
4549     gen_load_spr(t0, SPR_Exxx_L1CSR0);
4550     tcg_gen_ori_tl(t0, t0, L1CSR0_CUL);
4551     gen_store_spr(SPR_Exxx_L1CSR0, t0);
4552     tcg_temp_free(t0);
4553 }
4554
4555 /* dcbz */
4556 static void gen_dcbz(DisasContext *ctx)
4557 {
4558     TCGv tcgv_addr;
4559     TCGv_i32 tcgv_is_dcbzl;
4560     int is_dcbzl = ctx->opcode & 0x00200000 ? 1 : 0;
4561
4562     gen_set_access_type(ctx, ACCESS_CACHE);
4563     /* NIP cannot be restored if the memory exception comes from an helper */
4564     gen_update_nip(ctx, ctx->nip - 4);
4565     tcgv_addr = tcg_temp_new();
4566     tcgv_is_dcbzl = tcg_const_i32(is_dcbzl);
4567
4568     gen_addr_reg_index(ctx, tcgv_addr);
4569     gen_helper_dcbz(cpu_env, tcgv_addr, tcgv_is_dcbzl);
4570
4571     tcg_temp_free(tcgv_addr);
4572     tcg_temp_free_i32(tcgv_is_dcbzl);
4573 }
4574
4575 /* dst / dstt */
4576 static void gen_dst(DisasContext *ctx)
4577 {
4578     if (rA(ctx->opcode) == 0) {
4579         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_LSWX);
4580     } else {
4581         /* interpreted as no-op */
4582     }
4583 }
4584
4585 /* dstst /dststt */
4586 static void gen_dstst(DisasContext *ctx)
4587 {
4588     if (rA(ctx->opcode) == 0) {
4589         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_LSWX);
4590     } else {
4591         /* interpreted as no-op */
4592     }
4593
4594 }
4595
4596 /* dss / dssall */
4597 static void gen_dss(DisasContext *ctx)
4598 {
4599     /* interpreted as no-op */
4600 }
4601
4602 /* icbi */
4603 static void gen_icbi(DisasContext *ctx)
4604 {
4605     TCGv t0;
4606     gen_set_access_type(ctx, ACCESS_CACHE);
4607     /* NIP cannot be restored if the memory exception comes from an helper */
4608     gen_update_nip(ctx, ctx->nip - 4);
4609     t0 = tcg_temp_new();
4610     gen_addr_reg_index(ctx, t0);
4611     gen_helper_icbi(cpu_env, t0);
4612     tcg_temp_free(t0);
4613 }
4614
4615 /* Optional: */
4616 /* dcba */
4617 static void gen_dcba(DisasContext *ctx)
4618 {
4619     /* interpreted as no-op */
4620     /* XXX: specification say this is treated as a store by the MMU
4621      *      but does not generate any exception
4622      */
4623 }
4624
4625 /***                    Segment register manipulation                      ***/
4626 /* Supervisor only: */
4627
4628 /* mfsr */
4629 static void gen_mfsr(DisasContext *ctx)
4630 {
4631 #if defined(CONFIG_USER_ONLY)
4632     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4633 #else
4634     TCGv t0;
4635     if (unlikely(ctx->pr)) {
4636         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4637         return;
4638     }
4639     t0 = tcg_const_tl(SR(ctx->opcode));
4640     gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
4641     tcg_temp_free(t0);
4642 #endif
4643 }
4644
4645 /* mfsrin */
4646 static void gen_mfsrin(DisasContext *ctx)
4647 {
4648 #if defined(CONFIG_USER_ONLY)
4649     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4650 #else
4651     TCGv t0;
4652     if (unlikely(ctx->pr)) {
4653         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4654         return;
4655     }
4656     t0 = tcg_temp_new();
4657     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
4658     tcg_gen_andi_tl(t0, t0, 0xF);
4659     gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
4660     tcg_temp_free(t0);
4661 #endif
4662 }
4663
4664 /* mtsr */
4665 static void gen_mtsr(DisasContext *ctx)
4666 {
4667 #if defined(CONFIG_USER_ONLY)
4668     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4669 #else
4670     TCGv t0;
4671     if (unlikely(ctx->pr)) {
4672         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4673         return;
4674     }
4675     t0 = tcg_const_tl(SR(ctx->opcode));
4676     gen_helper_store_sr(cpu_env, t0, cpu_gpr[rS(ctx->opcode)]);
4677     tcg_temp_free(t0);
4678 #endif
4679 }
4680
4681 /* mtsrin */
4682 static void gen_mtsrin(DisasContext *ctx)
4683 {
4684 #if defined(CONFIG_USER_ONLY)
4685     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4686 #else
4687     TCGv t0;
4688     if (unlikely(ctx->pr)) {
4689         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4690         return;
4691     }
4692     t0 = tcg_temp_new();
4693     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
4694     tcg_gen_andi_tl(t0, t0, 0xF);
4695     gen_helper_store_sr(cpu_env, t0, cpu_gpr[rD(ctx->opcode)]);
4696     tcg_temp_free(t0);
4697 #endif
4698 }
4699
4700 #if defined(TARGET_PPC64)
4701 /* Specific implementation for PowerPC 64 "bridge" emulation using SLB */
4702
4703 /* mfsr */
4704 static void gen_mfsr_64b(DisasContext *ctx)
4705 {
4706 #if defined(CONFIG_USER_ONLY)
4707     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4708 #else
4709     TCGv t0;
4710     if (unlikely(ctx->pr)) {
4711         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4712         return;
4713     }
4714     t0 = tcg_const_tl(SR(ctx->opcode));
4715     gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
4716     tcg_temp_free(t0);
4717 #endif
4718 }
4719
4720 /* mfsrin */
4721 static void gen_mfsrin_64b(DisasContext *ctx)
4722 {
4723 #if defined(CONFIG_USER_ONLY)
4724     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4725 #else
4726     TCGv t0;
4727     if (unlikely(ctx->pr)) {
4728         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4729         return;
4730     }
4731     t0 = tcg_temp_new();
4732     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
4733     tcg_gen_andi_tl(t0, t0, 0xF);
4734     gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
4735     tcg_temp_free(t0);
4736 #endif
4737 }
4738
4739 /* mtsr */
4740 static void gen_mtsr_64b(DisasContext *ctx)
4741 {
4742 #if defined(CONFIG_USER_ONLY)
4743     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4744 #else
4745     TCGv t0;
4746     if (unlikely(ctx->pr)) {
4747         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4748         return;
4749     }
4750     t0 = tcg_const_tl(SR(ctx->opcode));
4751     gen_helper_store_sr(cpu_env, t0, cpu_gpr[rS(ctx->opcode)]);
4752     tcg_temp_free(t0);
4753 #endif
4754 }
4755
4756 /* mtsrin */
4757 static void gen_mtsrin_64b(DisasContext *ctx)
4758 {
4759 #if defined(CONFIG_USER_ONLY)
4760     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4761 #else
4762     TCGv t0;
4763     if (unlikely(ctx->pr)) {
4764         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4765         return;
4766     }
4767     t0 = tcg_temp_new();
4768     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
4769     tcg_gen_andi_tl(t0, t0, 0xF);
4770     gen_helper_store_sr(cpu_env, t0, cpu_gpr[rS(ctx->opcode)]);
4771     tcg_temp_free(t0);
4772 #endif
4773 }
4774
4775 /* slbmte */
4776 static void gen_slbmte(DisasContext *ctx)
4777 {
4778 #if defined(CONFIG_USER_ONLY)
4779     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4780 #else
4781     if (unlikely(ctx->pr)) {
4782         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4783         return;
4784     }
4785     gen_helper_store_slb(cpu_env, cpu_gpr[rB(ctx->opcode)],
4786                          cpu_gpr[rS(ctx->opcode)]);
4787 #endif
4788 }
4789
4790 static void gen_slbmfee(DisasContext *ctx)
4791 {
4792 #if defined(CONFIG_USER_ONLY)
4793     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4794 #else
4795     if (unlikely(ctx->pr)) {
4796         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4797         return;
4798     }
4799     gen_helper_load_slb_esid(cpu_gpr[rS(ctx->opcode)], cpu_env,
4800                              cpu_gpr[rB(ctx->opcode)]);
4801 #endif
4802 }
4803
4804 static void gen_slbmfev(DisasContext *ctx)
4805 {
4806 #if defined(CONFIG_USER_ONLY)
4807     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4808 #else
4809     if (unlikely(ctx->pr)) {
4810         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4811         return;
4812     }
4813     gen_helper_load_slb_vsid(cpu_gpr[rS(ctx->opcode)], cpu_env,
4814                              cpu_gpr[rB(ctx->opcode)]);
4815 #endif
4816 }
4817 #endif /* defined(TARGET_PPC64) */
4818
4819 /***                      Lookaside buffer management                      ***/
4820 /* Optional & supervisor only: */
4821
4822 /* tlbia */
4823 static void gen_tlbia(DisasContext *ctx)
4824 {
4825 #if defined(CONFIG_USER_ONLY)
4826     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4827 #else
4828     if (unlikely(ctx->pr)) {
4829         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4830         return;
4831     }
4832     gen_helper_tlbia(cpu_env);
4833 #endif
4834 }
4835
4836 /* tlbiel */
4837 static void gen_tlbiel(DisasContext *ctx)
4838 {
4839 #if defined(CONFIG_USER_ONLY)
4840     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4841 #else
4842     if (unlikely(ctx->pr)) {
4843         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4844         return;
4845     }
4846     gen_helper_tlbie(cpu_env, cpu_gpr[rB(ctx->opcode)]);
4847 #endif
4848 }
4849
4850 /* tlbie */
4851 static void gen_tlbie(DisasContext *ctx)
4852 {
4853 #if defined(CONFIG_USER_ONLY)
4854     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4855 #else
4856     if (unlikely(ctx->pr)) {
4857         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4858         return;
4859     }
4860     if (NARROW_MODE(ctx)) {
4861         TCGv t0 = tcg_temp_new();
4862         tcg_gen_ext32u_tl(t0, cpu_gpr[rB(ctx->opcode)]);
4863         gen_helper_tlbie(cpu_env, t0);
4864         tcg_temp_free(t0);
4865     } else {
4866         gen_helper_tlbie(cpu_env, cpu_gpr[rB(ctx->opcode)]);
4867     }
4868 #endif
4869 }
4870
4871 /* tlbsync */
4872 static void gen_tlbsync(DisasContext *ctx)
4873 {
4874 #if defined(CONFIG_USER_ONLY)
4875     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4876 #else
4877     if (unlikely(ctx->pr)) {
4878         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4879         return;
4880     }
4881     /* This has no effect: it should ensure that all previous
4882      * tlbie have completed
4883      */
4884     gen_stop_exception(ctx);
4885 #endif
4886 }
4887
4888 #if defined(TARGET_PPC64)
4889 /* slbia */
4890 static void gen_slbia(DisasContext *ctx)
4891 {
4892 #if defined(CONFIG_USER_ONLY)
4893     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4894 #else
4895     if (unlikely(ctx->pr)) {
4896         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4897         return;
4898     }
4899     gen_helper_slbia(cpu_env);
4900 #endif
4901 }
4902
4903 /* slbie */
4904 static void gen_slbie(DisasContext *ctx)
4905 {
4906 #if defined(CONFIG_USER_ONLY)
4907     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4908 #else
4909     if (unlikely(ctx->pr)) {
4910         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4911         return;
4912     }
4913     gen_helper_slbie(cpu_env, cpu_gpr[rB(ctx->opcode)]);
4914 #endif
4915 }
4916 #endif
4917
4918 /***                              External control                         ***/
4919 /* Optional: */
4920
4921 /* eciwx */
4922 static void gen_eciwx(DisasContext *ctx)
4923 {
4924     TCGv t0;
4925     /* Should check EAR[E] ! */
4926     gen_set_access_type(ctx, ACCESS_EXT);
4927     t0 = tcg_temp_new();
4928     gen_addr_reg_index(ctx, t0);
4929     gen_check_align(ctx, t0, 0x03);
4930     gen_qemu_ld32u(ctx, cpu_gpr[rD(ctx->opcode)], t0);
4931     tcg_temp_free(t0);
4932 }
4933
4934 /* ecowx */
4935 static void gen_ecowx(DisasContext *ctx)
4936 {
4937     TCGv t0;
4938     /* Should check EAR[E] ! */
4939     gen_set_access_type(ctx, ACCESS_EXT);
4940     t0 = tcg_temp_new();
4941     gen_addr_reg_index(ctx, t0);
4942     gen_check_align(ctx, t0, 0x03);
4943     gen_qemu_st32(ctx, cpu_gpr[rD(ctx->opcode)], t0);
4944     tcg_temp_free(t0);
4945 }
4946
4947 /* PowerPC 601 specific instructions */
4948
4949 /* abs - abs. */
4950 static void gen_abs(DisasContext *ctx)
4951 {
4952     TCGLabel *l1 = gen_new_label();
4953     TCGLabel *l2 = gen_new_label();
4954     tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rA(ctx->opcode)], 0, l1);
4955     tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4956     tcg_gen_br(l2);
4957     gen_set_label(l1);
4958     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4959     gen_set_label(l2);
4960     if (unlikely(Rc(ctx->opcode) != 0))
4961         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4962 }
4963
4964 /* abso - abso. */
4965 static void gen_abso(DisasContext *ctx)
4966 {
4967     TCGLabel *l1 = gen_new_label();
4968     TCGLabel *l2 = gen_new_label();
4969     TCGLabel *l3 = gen_new_label();
4970     /* Start with XER OV disabled, the most likely case */
4971     tcg_gen_movi_tl(cpu_ov, 0);
4972     tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rA(ctx->opcode)], 0, l2);
4973     tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rA(ctx->opcode)], 0x80000000, l1);
4974     tcg_gen_movi_tl(cpu_ov, 1);
4975     tcg_gen_movi_tl(cpu_so, 1);
4976     tcg_gen_br(l2);
4977     gen_set_label(l1);
4978     tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4979     tcg_gen_br(l3);
4980     gen_set_label(l2);
4981     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4982     gen_set_label(l3);
4983     if (unlikely(Rc(ctx->opcode) != 0))
4984         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4985 }
4986
4987 /* clcs */
4988 static void gen_clcs(DisasContext *ctx)
4989 {
4990     TCGv_i32 t0 = tcg_const_i32(rA(ctx->opcode));
4991     gen_helper_clcs(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
4992     tcg_temp_free_i32(t0);
4993     /* Rc=1 sets CR0 to an undefined state */
4994 }
4995
4996 /* div - div. */
4997 static void gen_div(DisasContext *ctx)
4998 {
4999     gen_helper_div(cpu_gpr[rD(ctx->opcode)], cpu_env, cpu_gpr[rA(ctx->opcode)],
5000                    cpu_gpr[rB(ctx->opcode)]);
5001     if (unlikely(Rc(ctx->opcode) != 0))
5002         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
5003 }
5004
5005 /* divo - divo. */
5006 static void gen_divo(DisasContext *ctx)
5007 {
5008     gen_helper_divo(cpu_gpr[rD(ctx->opcode)], cpu_env, cpu_gpr[rA(ctx->opcode)],
5009                     cpu_gpr[rB(ctx->opcode)]);
5010     if (unlikely(Rc(ctx->opcode) != 0))
5011         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
5012 }
5013
5014 /* divs - divs. */
5015 static void gen_divs(DisasContext *ctx)
5016 {
5017     gen_helper_divs(cpu_gpr[rD(ctx->opcode)], cpu_env, cpu_gpr[rA(ctx->opcode)],
5018                     cpu_gpr[rB(ctx->opcode)]);
5019     if (unlikely(Rc(ctx->opcode) != 0))
5020         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
5021 }
5022
5023 /* divso - divso. */
5024 static void gen_divso(DisasContext *ctx)
5025 {
5026     gen_helper_divso(cpu_gpr[rD(ctx->opcode)], cpu_env,
5027                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
5028     if (unlikely(Rc(ctx->opcode) != 0))
5029         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
5030 }
5031
5032 /* doz - doz. */
5033 static void gen_doz(DisasContext *ctx)
5034 {
5035     TCGLabel *l1 = gen_new_label();
5036     TCGLabel *l2 = gen_new_label();
5037     tcg_gen_brcond_tl(TCG_COND_GE, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], l1);
5038     tcg_gen_sub_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5039     tcg_gen_br(l2);
5040     gen_set_label(l1);
5041     tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
5042     gen_set_label(l2);
5043     if (unlikely(Rc(ctx->opcode) != 0))
5044         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
5045 }
5046
5047 /* dozo - dozo. */
5048 static void gen_dozo(DisasContext *ctx)
5049 {
5050     TCGLabel *l1 = gen_new_label();
5051     TCGLabel *l2 = gen_new_label();
5052     TCGv t0 = tcg_temp_new();
5053     TCGv t1 = tcg_temp_new();
5054     TCGv t2 = tcg_temp_new();
5055     /* Start with XER OV disabled, the most likely case */
5056     tcg_gen_movi_tl(cpu_ov, 0);
5057     tcg_gen_brcond_tl(TCG_COND_GE, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], l1);
5058     tcg_gen_sub_tl(t0, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5059     tcg_gen_xor_tl(t1, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5060     tcg_gen_xor_tl(t2, cpu_gpr[rA(ctx->opcode)], t0);
5061     tcg_gen_andc_tl(t1, t1, t2);
5062     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
5063     tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l2);
5064     tcg_gen_movi_tl(cpu_ov, 1);
5065     tcg_gen_movi_tl(cpu_so, 1);
5066     tcg_gen_br(l2);
5067     gen_set_label(l1);
5068     tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
5069     gen_set_label(l2);
5070     tcg_temp_free(t0);
5071     tcg_temp_free(t1);
5072     tcg_temp_free(t2);
5073     if (unlikely(Rc(ctx->opcode) != 0))
5074         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
5075 }
5076
5077 /* dozi */
5078 static void gen_dozi(DisasContext *ctx)
5079 {
5080     target_long simm = SIMM(ctx->opcode);
5081     TCGLabel *l1 = gen_new_label();
5082     TCGLabel *l2 = gen_new_label();
5083     tcg_gen_brcondi_tl(TCG_COND_LT, cpu_gpr[rA(ctx->opcode)], simm, l1);
5084     tcg_gen_subfi_tl(cpu_gpr[rD(ctx->opcode)], simm, cpu_gpr[rA(ctx->opcode)]);
5085     tcg_gen_br(l2);
5086     gen_set_label(l1);
5087     tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
5088     gen_set_label(l2);
5089     if (unlikely(Rc(ctx->opcode) != 0))
5090         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
5091 }
5092
5093 /* lscbx - lscbx. */
5094 static void gen_lscbx(DisasContext *ctx)
5095 {
5096     TCGv t0 = tcg_temp_new();
5097     TCGv_i32 t1 = tcg_const_i32(rD(ctx->opcode));
5098     TCGv_i32 t2 = tcg_const_i32(rA(ctx->opcode));
5099     TCGv_i32 t3 = tcg_const_i32(rB(ctx->opcode));
5100
5101     gen_addr_reg_index(ctx, t0);
5102     /* NIP cannot be restored if the memory exception comes from an helper */
5103     gen_update_nip(ctx, ctx->nip - 4);
5104     gen_helper_lscbx(t0, cpu_env, t0, t1, t2, t3);
5105     tcg_temp_free_i32(t1);
5106     tcg_temp_free_i32(t2);
5107     tcg_temp_free_i32(t3);
5108     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~0x7F);
5109     tcg_gen_or_tl(cpu_xer, cpu_xer, t0);
5110     if (unlikely(Rc(ctx->opcode) != 0))
5111         gen_set_Rc0(ctx, t0);
5112     tcg_temp_free(t0);
5113 }
5114
5115 /* maskg - maskg. */
5116 static void gen_maskg(DisasContext *ctx)
5117 {
5118     TCGLabel *l1 = gen_new_label();
5119     TCGv t0 = tcg_temp_new();
5120     TCGv t1 = tcg_temp_new();
5121     TCGv t2 = tcg_temp_new();
5122     TCGv t3 = tcg_temp_new();
5123     tcg_gen_movi_tl(t3, 0xFFFFFFFF);
5124     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
5125     tcg_gen_andi_tl(t1, cpu_gpr[rS(ctx->opcode)], 0x1F);
5126     tcg_gen_addi_tl(t2, t0, 1);
5127     tcg_gen_shr_tl(t2, t3, t2);
5128     tcg_gen_shr_tl(t3, t3, t1);
5129     tcg_gen_xor_tl(cpu_gpr[rA(ctx->opcode)], t2, t3);
5130     tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
5131     tcg_gen_neg_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5132     gen_set_label(l1);
5133     tcg_temp_free(t0);
5134     tcg_temp_free(t1);
5135     tcg_temp_free(t2);
5136     tcg_temp_free(t3);
5137     if (unlikely(Rc(ctx->opcode) != 0))
5138         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5139 }
5140
5141 /* maskir - maskir. */
5142 static void gen_maskir(DisasContext *ctx)
5143 {
5144     TCGv t0 = tcg_temp_new();
5145     TCGv t1 = tcg_temp_new();
5146     tcg_gen_and_tl(t0, cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
5147     tcg_gen_andc_tl(t1, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
5148     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5149     tcg_temp_free(t0);
5150     tcg_temp_free(t1);
5151     if (unlikely(Rc(ctx->opcode) != 0))
5152         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5153 }
5154
5155 /* mul - mul. */
5156 static void gen_mul(DisasContext *ctx)
5157 {
5158     TCGv_i64 t0 = tcg_temp_new_i64();
5159     TCGv_i64 t1 = tcg_temp_new_i64();
5160     TCGv t2 = tcg_temp_new();
5161     tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
5162     tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
5163     tcg_gen_mul_i64(t0, t0, t1);
5164     tcg_gen_trunc_i64_tl(t2, t0);
5165     gen_store_spr(SPR_MQ, t2);
5166     tcg_gen_shri_i64(t1, t0, 32);
5167     tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t1);
5168     tcg_temp_free_i64(t0);
5169     tcg_temp_free_i64(t1);
5170     tcg_temp_free(t2);
5171     if (unlikely(Rc(ctx->opcode) != 0))
5172         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
5173 }
5174
5175 /* mulo - mulo. */
5176 static void gen_mulo(DisasContext *ctx)
5177 {
5178     TCGLabel *l1 = gen_new_label();
5179     TCGv_i64 t0 = tcg_temp_new_i64();
5180     TCGv_i64 t1 = tcg_temp_new_i64();
5181     TCGv t2 = tcg_temp_new();
5182     /* Start with XER OV disabled, the most likely case */
5183     tcg_gen_movi_tl(cpu_ov, 0);
5184     tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
5185     tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
5186     tcg_gen_mul_i64(t0, t0, t1);
5187     tcg_gen_trunc_i64_tl(t2, t0);
5188     gen_store_spr(SPR_MQ, t2);
5189     tcg_gen_shri_i64(t1, t0, 32);
5190     tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t1);
5191     tcg_gen_ext32s_i64(t1, t0);
5192     tcg_gen_brcond_i64(TCG_COND_EQ, t0, t1, l1);
5193     tcg_gen_movi_tl(cpu_ov, 1);
5194     tcg_gen_movi_tl(cpu_so, 1);
5195     gen_set_label(l1);
5196     tcg_temp_free_i64(t0);
5197     tcg_temp_free_i64(t1);
5198     tcg_temp_free(t2);
5199     if (unlikely(Rc(ctx->opcode) != 0))
5200         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
5201 }
5202
5203 /* nabs - nabs. */
5204 static void gen_nabs(DisasContext *ctx)
5205 {
5206     TCGLabel *l1 = gen_new_label();
5207     TCGLabel *l2 = gen_new_label();
5208     tcg_gen_brcondi_tl(TCG_COND_GT, cpu_gpr[rA(ctx->opcode)], 0, l1);
5209     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5210     tcg_gen_br(l2);
5211     gen_set_label(l1);
5212     tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5213     gen_set_label(l2);
5214     if (unlikely(Rc(ctx->opcode) != 0))
5215         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
5216 }
5217
5218 /* nabso - nabso. */
5219 static void gen_nabso(DisasContext *ctx)
5220 {
5221     TCGLabel *l1 = gen_new_label();
5222     TCGLabel *l2 = gen_new_label();
5223     tcg_gen_brcondi_tl(TCG_COND_GT, cpu_gpr[rA(ctx->opcode)], 0, l1);
5224     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5225     tcg_gen_br(l2);
5226     gen_set_label(l1);
5227     tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5228     gen_set_label(l2);
5229     /* nabs never overflows */
5230     tcg_gen_movi_tl(cpu_ov, 0);
5231     if (unlikely(Rc(ctx->opcode) != 0))
5232         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
5233 }
5234
5235 /* rlmi - rlmi. */
5236 static void gen_rlmi(DisasContext *ctx)
5237 {
5238     uint32_t mb = MB(ctx->opcode);
5239     uint32_t me = ME(ctx->opcode);
5240     TCGv t0 = tcg_temp_new();
5241     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
5242     tcg_gen_rotl_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
5243     tcg_gen_andi_tl(t0, t0, MASK(mb, me));
5244     tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~MASK(mb, me));
5245     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], t0);
5246     tcg_temp_free(t0);
5247     if (unlikely(Rc(ctx->opcode) != 0))
5248         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5249 }
5250
5251 /* rrib - rrib. */
5252 static void gen_rrib(DisasContext *ctx)
5253 {
5254     TCGv t0 = tcg_temp_new();
5255     TCGv t1 = tcg_temp_new();
5256     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
5257     tcg_gen_movi_tl(t1, 0x80000000);
5258     tcg_gen_shr_tl(t1, t1, t0);
5259     tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
5260     tcg_gen_and_tl(t0, t0, t1);
5261     tcg_gen_andc_tl(t1, cpu_gpr[rA(ctx->opcode)], t1);
5262     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5263     tcg_temp_free(t0);
5264     tcg_temp_free(t1);
5265     if (unlikely(Rc(ctx->opcode) != 0))
5266         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5267 }
5268
5269 /* sle - sle. */
5270 static void gen_sle(DisasContext *ctx)
5271 {
5272     TCGv t0 = tcg_temp_new();
5273     TCGv t1 = tcg_temp_new();
5274     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
5275     tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
5276     tcg_gen_subfi_tl(t1, 32, t1);
5277     tcg_gen_shr_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
5278     tcg_gen_or_tl(t1, t0, t1);
5279     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
5280     gen_store_spr(SPR_MQ, t1);
5281     tcg_temp_free(t0);
5282     tcg_temp_free(t1);
5283     if (unlikely(Rc(ctx->opcode) != 0))
5284         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5285 }
5286
5287 /* sleq - sleq. */
5288 static void gen_sleq(DisasContext *ctx)
5289 {
5290     TCGv t0 = tcg_temp_new();
5291     TCGv t1 = tcg_temp_new();
5292     TCGv t2 = tcg_temp_new();
5293     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
5294     tcg_gen_movi_tl(t2, 0xFFFFFFFF);
5295     tcg_gen_shl_tl(t2, t2, t0);
5296     tcg_gen_rotl_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
5297     gen_load_spr(t1, SPR_MQ);
5298     gen_store_spr(SPR_MQ, t0);
5299     tcg_gen_and_tl(t0, t0, t2);
5300     tcg_gen_andc_tl(t1, t1, t2);
5301     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5302     tcg_temp_free(t0);
5303     tcg_temp_free(t1);
5304     tcg_temp_free(t2);
5305     if (unlikely(Rc(ctx->opcode) != 0))
5306         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5307 }
5308
5309 /* sliq - sliq. */
5310 static void gen_sliq(DisasContext *ctx)
5311 {
5312     int sh = SH(ctx->opcode);
5313     TCGv t0 = tcg_temp_new();
5314     TCGv t1 = tcg_temp_new();
5315     tcg_gen_shli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
5316     tcg_gen_shri_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh);
5317     tcg_gen_or_tl(t1, t0, t1);
5318     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
5319     gen_store_spr(SPR_MQ, t1);
5320     tcg_temp_free(t0);
5321     tcg_temp_free(t1);
5322     if (unlikely(Rc(ctx->opcode) != 0))
5323         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5324 }
5325
5326 /* slliq - slliq. */
5327 static void gen_slliq(DisasContext *ctx)
5328 {
5329     int sh = SH(ctx->opcode);
5330     TCGv t0 = tcg_temp_new();
5331     TCGv t1 = tcg_temp_new();
5332     tcg_gen_rotli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
5333     gen_load_spr(t1, SPR_MQ);
5334     gen_store_spr(SPR_MQ, t0);
5335     tcg_gen_andi_tl(t0, t0,  (0xFFFFFFFFU << sh));
5336     tcg_gen_andi_tl(t1, t1, ~(0xFFFFFFFFU << sh));
5337     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5338     tcg_temp_free(t0);
5339     tcg_temp_free(t1);
5340     if (unlikely(Rc(ctx->opcode) != 0))
5341         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5342 }
5343
5344 /* sllq - sllq. */
5345 static void gen_sllq(DisasContext *ctx)
5346 {
5347     TCGLabel *l1 = gen_new_label();
5348     TCGLabel *l2 = gen_new_label();
5349     TCGv t0 = tcg_temp_local_new();
5350     TCGv t1 = tcg_temp_local_new();
5351     TCGv t2 = tcg_temp_local_new();
5352     tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F);
5353     tcg_gen_movi_tl(t1, 0xFFFFFFFF);
5354     tcg_gen_shl_tl(t1, t1, t2);
5355     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20);
5356     tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
5357     gen_load_spr(t0, SPR_MQ);
5358     tcg_gen_and_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5359     tcg_gen_br(l2);
5360     gen_set_label(l1);
5361     tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t2);
5362     gen_load_spr(t2, SPR_MQ);
5363     tcg_gen_andc_tl(t1, t2, t1);
5364     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5365     gen_set_label(l2);
5366     tcg_temp_free(t0);
5367     tcg_temp_free(t1);
5368     tcg_temp_free(t2);
5369     if (unlikely(Rc(ctx->opcode) != 0))
5370         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5371 }
5372
5373 /* slq - slq. */
5374 static void gen_slq(DisasContext *ctx)
5375 {
5376     TCGLabel *l1 = gen_new_label();
5377     TCGv t0 = tcg_temp_new();
5378     TCGv t1 = tcg_temp_new();
5379     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
5380     tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
5381     tcg_gen_subfi_tl(t1, 32, t1);
5382     tcg_gen_shr_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
5383     tcg_gen_or_tl(t1, t0, t1);
5384     gen_store_spr(SPR_MQ, t1);
5385     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x20);
5386     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
5387     tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5388     tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
5389     gen_set_label(l1);
5390     tcg_temp_free(t0);
5391     tcg_temp_free(t1);
5392     if (unlikely(Rc(ctx->opcode) != 0))
5393         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5394 }
5395
5396 /* sraiq - sraiq. */
5397 static void gen_sraiq(DisasContext *ctx)
5398 {
5399     int sh = SH(ctx->opcode);
5400     TCGLabel *l1 = gen_new_label();
5401     TCGv t0 = tcg_temp_new();
5402     TCGv t1 = tcg_temp_new();
5403     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
5404     tcg_gen_shli_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh);
5405     tcg_gen_or_tl(t0, t0, t1);
5406     gen_store_spr(SPR_MQ, t0);
5407     tcg_gen_movi_tl(cpu_ca, 0);
5408     tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5409     tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rS(ctx->opcode)], 0, l1);
5410     tcg_gen_movi_tl(cpu_ca, 1);
5411     gen_set_label(l1);
5412     tcg_gen_sari_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], sh);
5413     tcg_temp_free(t0);
5414     tcg_temp_free(t1);
5415     if (unlikely(Rc(ctx->opcode) != 0))
5416         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5417 }
5418
5419 /* sraq - sraq. */
5420 static void gen_sraq(DisasContext *ctx)
5421 {
5422     TCGLabel *l1 = gen_new_label();
5423     TCGLabel *l2 = gen_new_label();
5424     TCGv t0 = tcg_temp_new();
5425     TCGv t1 = tcg_temp_local_new();
5426     TCGv t2 = tcg_temp_local_new();
5427     tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F);
5428     tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t2);
5429     tcg_gen_sar_tl(t1, cpu_gpr[rS(ctx->opcode)], t2);
5430     tcg_gen_subfi_tl(t2, 32, t2);
5431     tcg_gen_shl_tl(t2, cpu_gpr[rS(ctx->opcode)], t2);
5432     tcg_gen_or_tl(t0, t0, t2);
5433     gen_store_spr(SPR_MQ, t0);
5434     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20);
5435     tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, l1);
5436     tcg_gen_mov_tl(t2, cpu_gpr[rS(ctx->opcode)]);
5437     tcg_gen_sari_tl(t1, cpu_gpr[rS(ctx->opcode)], 31);
5438     gen_set_label(l1);
5439     tcg_temp_free(t0);
5440     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t1);
5441     tcg_gen_movi_tl(cpu_ca, 0);
5442     tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l2);
5443     tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, l2);
5444     tcg_gen_movi_tl(cpu_ca, 1);
5445     gen_set_label(l2);
5446     tcg_temp_free(t1);
5447     tcg_temp_free(t2);
5448     if (unlikely(Rc(ctx->opcode) != 0))
5449         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5450 }
5451
5452 /* sre - sre. */
5453 static void gen_sre(DisasContext *ctx)
5454 {
5455     TCGv t0 = tcg_temp_new();
5456     TCGv t1 = tcg_temp_new();
5457     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
5458     tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
5459     tcg_gen_subfi_tl(t1, 32, t1);
5460     tcg_gen_shl_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
5461     tcg_gen_or_tl(t1, t0, t1);
5462     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
5463     gen_store_spr(SPR_MQ, t1);
5464     tcg_temp_free(t0);
5465     tcg_temp_free(t1);
5466     if (unlikely(Rc(ctx->opcode) != 0))
5467         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5468 }
5469
5470 /* srea - srea. */
5471 static void gen_srea(DisasContext *ctx)
5472 {
5473     TCGv t0 = tcg_temp_new();
5474     TCGv t1 = tcg_temp_new();
5475     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
5476     tcg_gen_rotr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
5477     gen_store_spr(SPR_MQ, t0);
5478     tcg_gen_sar_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], t1);
5479     tcg_temp_free(t0);
5480     tcg_temp_free(t1);
5481     if (unlikely(Rc(ctx->opcode) != 0))
5482         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5483 }
5484
5485 /* sreq */
5486 static void gen_sreq(DisasContext *ctx)
5487 {
5488     TCGv t0 = tcg_temp_new();
5489     TCGv t1 = tcg_temp_new();
5490     TCGv t2 = tcg_temp_new();
5491     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
5492     tcg_gen_movi_tl(t1, 0xFFFFFFFF);
5493     tcg_gen_shr_tl(t1, t1, t0);
5494     tcg_gen_rotr_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
5495     gen_load_spr(t2, SPR_MQ);
5496     gen_store_spr(SPR_MQ, t0);
5497     tcg_gen_and_tl(t0, t0, t1);
5498     tcg_gen_andc_tl(t2, t2, t1);
5499     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t2);
5500     tcg_temp_free(t0);
5501     tcg_temp_free(t1);
5502     tcg_temp_free(t2);
5503     if (unlikely(Rc(ctx->opcode) != 0))
5504         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5505 }
5506
5507 /* sriq */
5508 static void gen_sriq(DisasContext *ctx)
5509 {
5510     int sh = SH(ctx->opcode);
5511     TCGv t0 = tcg_temp_new();
5512     TCGv t1 = tcg_temp_new();
5513     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
5514     tcg_gen_shli_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh);
5515     tcg_gen_or_tl(t1, t0, t1);
5516     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
5517     gen_store_spr(SPR_MQ, t1);
5518     tcg_temp_free(t0);
5519     tcg_temp_free(t1);
5520     if (unlikely(Rc(ctx->opcode) != 0))
5521         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5522 }
5523
5524 /* srliq */
5525 static void gen_srliq(DisasContext *ctx)
5526 {
5527     int sh = SH(ctx->opcode);
5528     TCGv t0 = tcg_temp_new();
5529     TCGv t1 = tcg_temp_new();
5530     tcg_gen_rotri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
5531     gen_load_spr(t1, SPR_MQ);
5532     gen_store_spr(SPR_MQ, t0);
5533     tcg_gen_andi_tl(t0, t0,  (0xFFFFFFFFU >> sh));
5534     tcg_gen_andi_tl(t1, t1, ~(0xFFFFFFFFU >> sh));
5535     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5536     tcg_temp_free(t0);
5537     tcg_temp_free(t1);
5538     if (unlikely(Rc(ctx->opcode) != 0))
5539         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5540 }
5541
5542 /* srlq */
5543 static void gen_srlq(DisasContext *ctx)
5544 {
5545     TCGLabel *l1 = gen_new_label();
5546     TCGLabel *l2 = gen_new_label();
5547     TCGv t0 = tcg_temp_local_new();
5548     TCGv t1 = tcg_temp_local_new();
5549     TCGv t2 = tcg_temp_local_new();
5550     tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F);
5551     tcg_gen_movi_tl(t1, 0xFFFFFFFF);
5552     tcg_gen_shr_tl(t2, t1, t2);
5553     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20);
5554     tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
5555     gen_load_spr(t0, SPR_MQ);
5556     tcg_gen_and_tl(cpu_gpr[rA(ctx->opcode)], t0, t2);
5557     tcg_gen_br(l2);
5558     gen_set_label(l1);
5559     tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t2);
5560     tcg_gen_and_tl(t0, t0, t2);
5561     gen_load_spr(t1, SPR_MQ);
5562     tcg_gen_andc_tl(t1, t1, t2);
5563     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5564     gen_set_label(l2);
5565     tcg_temp_free(t0);
5566     tcg_temp_free(t1);
5567     tcg_temp_free(t2);
5568     if (unlikely(Rc(ctx->opcode) != 0))
5569         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5570 }
5571
5572 /* srq */
5573 static void gen_srq(DisasContext *ctx)
5574 {
5575     TCGLabel *l1 = gen_new_label();
5576     TCGv t0 = tcg_temp_new();
5577     TCGv t1 = tcg_temp_new();
5578     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
5579     tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
5580     tcg_gen_subfi_tl(t1, 32, t1);
5581     tcg_gen_shl_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
5582     tcg_gen_or_tl(t1, t0, t1);
5583     gen_store_spr(SPR_MQ, t1);
5584     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x20);
5585     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
5586     tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
5587     tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
5588     gen_set_label(l1);
5589     tcg_temp_free(t0);
5590     tcg_temp_free(t1);
5591     if (unlikely(Rc(ctx->opcode) != 0))
5592         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5593 }
5594
5595 /* PowerPC 602 specific instructions */
5596
5597 /* dsa  */
5598 static void gen_dsa(DisasContext *ctx)
5599 {
5600     /* XXX: TODO */
5601     gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5602 }
5603
5604 /* esa */
5605 static void gen_esa(DisasContext *ctx)
5606 {
5607     /* XXX: TODO */
5608     gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5609 }
5610
5611 /* mfrom */
5612 static void gen_mfrom(DisasContext *ctx)
5613 {
5614 #if defined(CONFIG_USER_ONLY)
5615     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5616 #else
5617     if (unlikely(ctx->pr)) {
5618         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5619         return;
5620     }
5621     gen_helper_602_mfrom(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5622 #endif
5623 }
5624
5625 /* 602 - 603 - G2 TLB management */
5626
5627 /* tlbld */
5628 static void gen_tlbld_6xx(DisasContext *ctx)
5629 {
5630 #if defined(CONFIG_USER_ONLY)
5631     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5632 #else
5633     if (unlikely(ctx->pr)) {
5634         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5635         return;
5636     }
5637     gen_helper_6xx_tlbd(cpu_env, cpu_gpr[rB(ctx->opcode)]);
5638 #endif
5639 }
5640
5641 /* tlbli */
5642 static void gen_tlbli_6xx(DisasContext *ctx)
5643 {
5644 #if defined(CONFIG_USER_ONLY)
5645     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5646 #else
5647     if (unlikely(ctx->pr)) {
5648         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5649         return;
5650     }
5651     gen_helper_6xx_tlbi(cpu_env, cpu_gpr[rB(ctx->opcode)]);
5652 #endif
5653 }
5654
5655 /* 74xx TLB management */
5656
5657 /* tlbld */
5658 static void gen_tlbld_74xx(DisasContext *ctx)
5659 {
5660 #if defined(CONFIG_USER_ONLY)
5661     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5662 #else
5663     if (unlikely(ctx->pr)) {
5664         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5665         return;
5666     }
5667     gen_helper_74xx_tlbd(cpu_env, cpu_gpr[rB(ctx->opcode)]);
5668 #endif
5669 }
5670
5671 /* tlbli */
5672 static void gen_tlbli_74xx(DisasContext *ctx)
5673 {
5674 #if defined(CONFIG_USER_ONLY)
5675     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5676 #else
5677     if (unlikely(ctx->pr)) {
5678         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5679         return;
5680     }
5681     gen_helper_74xx_tlbi(cpu_env, cpu_gpr[rB(ctx->opcode)]);
5682 #endif
5683 }
5684
5685 /* POWER instructions not in PowerPC 601 */
5686
5687 /* clf */
5688 static void gen_clf(DisasContext *ctx)
5689 {
5690     /* Cache line flush: implemented as no-op */
5691 }
5692
5693 /* cli */
5694 static void gen_cli(DisasContext *ctx)
5695 {
5696     /* Cache line invalidate: privileged and treated as no-op */
5697 #if defined(CONFIG_USER_ONLY)
5698     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5699 #else
5700     if (unlikely(ctx->pr)) {
5701         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5702         return;
5703     }
5704 #endif
5705 }
5706
5707 /* dclst */
5708 static void gen_dclst(DisasContext *ctx)
5709 {
5710     /* Data cache line store: treated as no-op */
5711 }
5712
5713 static void gen_mfsri(DisasContext *ctx)
5714 {
5715 #if defined(CONFIG_USER_ONLY)
5716     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5717 #else
5718     int ra = rA(ctx->opcode);
5719     int rd = rD(ctx->opcode);
5720     TCGv t0;
5721     if (unlikely(ctx->pr)) {
5722         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5723         return;
5724     }
5725     t0 = tcg_temp_new();
5726     gen_addr_reg_index(ctx, t0);
5727     tcg_gen_shri_tl(t0, t0, 28);
5728     tcg_gen_andi_tl(t0, t0, 0xF);
5729     gen_helper_load_sr(cpu_gpr[rd], cpu_env, t0);
5730     tcg_temp_free(t0);
5731     if (ra != 0 && ra != rd)
5732         tcg_gen_mov_tl(cpu_gpr[ra], cpu_gpr[rd]);
5733 #endif
5734 }
5735
5736 static void gen_rac(DisasContext *ctx)
5737 {
5738 #if defined(CONFIG_USER_ONLY)
5739     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5740 #else
5741     TCGv t0;
5742     if (unlikely(ctx->pr)) {
5743         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5744         return;
5745     }
5746     t0 = tcg_temp_new();
5747     gen_addr_reg_index(ctx, t0);
5748     gen_helper_rac(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
5749     tcg_temp_free(t0);
5750 #endif
5751 }
5752
5753 static void gen_rfsvc(DisasContext *ctx)
5754 {
5755 #if defined(CONFIG_USER_ONLY)
5756     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5757 #else
5758     if (unlikely(ctx->pr)) {
5759         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5760         return;
5761     }
5762     gen_helper_rfsvc(cpu_env);
5763     gen_sync_exception(ctx);
5764 #endif
5765 }
5766
5767 /* svc is not implemented for now */
5768
5769 /* POWER2 specific instructions */
5770 /* Quad manipulation (load/store two floats at a time) */
5771
5772 /* lfq */
5773 static void gen_lfq(DisasContext *ctx)
5774 {
5775     int rd = rD(ctx->opcode);
5776     TCGv t0;
5777     gen_set_access_type(ctx, ACCESS_FLOAT);
5778     t0 = tcg_temp_new();
5779     gen_addr_imm_index(ctx, t0, 0);
5780     gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
5781     gen_addr_add(ctx, t0, t0, 8);
5782     gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t0);
5783     tcg_temp_free(t0);
5784 }
5785
5786 /* lfqu */
5787 static void gen_lfqu(DisasContext *ctx)
5788 {
5789     int ra = rA(ctx->opcode);
5790     int rd = rD(ctx->opcode);
5791     TCGv t0, t1;
5792     gen_set_access_type(ctx, ACCESS_FLOAT);
5793     t0 = tcg_temp_new();
5794     t1 = tcg_temp_new();
5795     gen_addr_imm_index(ctx, t0, 0);
5796     gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
5797     gen_addr_add(ctx, t1, t0, 8);
5798     gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t1);
5799     if (ra != 0)
5800         tcg_gen_mov_tl(cpu_gpr[ra], t0);
5801     tcg_temp_free(t0);
5802     tcg_temp_free(t1);
5803 }
5804
5805 /* lfqux */
5806 static void gen_lfqux(DisasContext *ctx)
5807 {
5808     int ra = rA(ctx->opcode);
5809     int rd = rD(ctx->opcode);
5810     gen_set_access_type(ctx, ACCESS_FLOAT);
5811     TCGv t0, t1;
5812     t0 = tcg_temp_new();
5813     gen_addr_reg_index(ctx, t0);
5814     gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
5815     t1 = tcg_temp_new();
5816     gen_addr_add(ctx, t1, t0, 8);
5817     gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t1);
5818     tcg_temp_free(t1);
5819     if (ra != 0)
5820         tcg_gen_mov_tl(cpu_gpr[ra], t0);
5821     tcg_temp_free(t0);
5822 }
5823
5824 /* lfqx */
5825 static void gen_lfqx(DisasContext *ctx)
5826 {
5827     int rd = rD(ctx->opcode);
5828     TCGv t0;
5829     gen_set_access_type(ctx, ACCESS_FLOAT);
5830     t0 = tcg_temp_new();
5831     gen_addr_reg_index(ctx, t0);
5832     gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
5833     gen_addr_add(ctx, t0, t0, 8);
5834     gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t0);
5835     tcg_temp_free(t0);
5836 }
5837
5838 /* stfq */
5839 static void gen_stfq(DisasContext *ctx)
5840 {
5841     int rd = rD(ctx->opcode);
5842     TCGv t0;
5843     gen_set_access_type(ctx, ACCESS_FLOAT);
5844     t0 = tcg_temp_new();
5845     gen_addr_imm_index(ctx, t0, 0);
5846     gen_qemu_st64(ctx, cpu_fpr[rd], t0);
5847     gen_addr_add(ctx, t0, t0, 8);
5848     gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t0);
5849     tcg_temp_free(t0);
5850 }
5851
5852 /* stfqu */
5853 static void gen_stfqu(DisasContext *ctx)
5854 {
5855     int ra = rA(ctx->opcode);
5856     int rd = rD(ctx->opcode);
5857     TCGv t0, t1;
5858     gen_set_access_type(ctx, ACCESS_FLOAT);
5859     t0 = tcg_temp_new();
5860     gen_addr_imm_index(ctx, t0, 0);
5861     gen_qemu_st64(ctx, cpu_fpr[rd], t0);
5862     t1 = tcg_temp_new();
5863     gen_addr_add(ctx, t1, t0, 8);
5864     gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t1);
5865     tcg_temp_free(t1);
5866     if (ra != 0)
5867         tcg_gen_mov_tl(cpu_gpr[ra], t0);
5868     tcg_temp_free(t0);
5869 }
5870
5871 /* stfqux */
5872 static void gen_stfqux(DisasContext *ctx)
5873 {
5874     int ra = rA(ctx->opcode);
5875     int rd = rD(ctx->opcode);
5876     TCGv t0, t1;
5877     gen_set_access_type(ctx, ACCESS_FLOAT);
5878     t0 = tcg_temp_new();
5879     gen_addr_reg_index(ctx, t0);
5880     gen_qemu_st64(ctx, cpu_fpr[rd], t0);
5881     t1 = tcg_temp_new();
5882     gen_addr_add(ctx, t1, t0, 8);
5883     gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t1);
5884     tcg_temp_free(t1);
5885     if (ra != 0)
5886         tcg_gen_mov_tl(cpu_gpr[ra], t0);
5887     tcg_temp_free(t0);
5888 }
5889
5890 /* stfqx */
5891 static void gen_stfqx(DisasContext *ctx)
5892 {
5893     int rd = rD(ctx->opcode);
5894     TCGv t0;
5895     gen_set_access_type(ctx, ACCESS_FLOAT);
5896     t0 = tcg_temp_new();
5897     gen_addr_reg_index(ctx, t0);
5898     gen_qemu_st64(ctx, cpu_fpr[rd], t0);
5899     gen_addr_add(ctx, t0, t0, 8);
5900     gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t0);
5901     tcg_temp_free(t0);
5902 }
5903
5904 /* BookE specific instructions */
5905
5906 /* XXX: not implemented on 440 ? */
5907 static void gen_mfapidi(DisasContext *ctx)
5908 {
5909     /* XXX: TODO */
5910     gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5911 }
5912
5913 /* XXX: not implemented on 440 ? */
5914 static void gen_tlbiva(DisasContext *ctx)
5915 {
5916 #if defined(CONFIG_USER_ONLY)
5917     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5918 #else
5919     TCGv t0;
5920     if (unlikely(ctx->pr)) {
5921         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5922         return;
5923     }
5924     t0 = tcg_temp_new();
5925     gen_addr_reg_index(ctx, t0);
5926     gen_helper_tlbiva(cpu_env, cpu_gpr[rB(ctx->opcode)]);
5927     tcg_temp_free(t0);
5928 #endif
5929 }
5930
5931 /* All 405 MAC instructions are translated here */
5932 static inline void gen_405_mulladd_insn(DisasContext *ctx, int opc2, int opc3,
5933                                         int ra, int rb, int rt, int Rc)
5934 {
5935     TCGv t0, t1;
5936
5937     t0 = tcg_temp_local_new();
5938     t1 = tcg_temp_local_new();
5939
5940     switch (opc3 & 0x0D) {
5941     case 0x05:
5942         /* macchw    - macchw.    - macchwo   - macchwo.   */
5943         /* macchws   - macchws.   - macchwso  - macchwso.  */
5944         /* nmacchw   - nmacchw.   - nmacchwo  - nmacchwo.  */
5945         /* nmacchws  - nmacchws.  - nmacchwso - nmacchwso. */
5946         /* mulchw - mulchw. */
5947         tcg_gen_ext16s_tl(t0, cpu_gpr[ra]);
5948         tcg_gen_sari_tl(t1, cpu_gpr[rb], 16);
5949         tcg_gen_ext16s_tl(t1, t1);
5950         break;
5951     case 0x04:
5952         /* macchwu   - macchwu.   - macchwuo  - macchwuo.  */
5953         /* macchwsu  - macchwsu.  - macchwsuo - macchwsuo. */
5954         /* mulchwu - mulchwu. */
5955         tcg_gen_ext16u_tl(t0, cpu_gpr[ra]);
5956         tcg_gen_shri_tl(t1, cpu_gpr[rb], 16);
5957         tcg_gen_ext16u_tl(t1, t1);
5958         break;
5959     case 0x01:
5960         /* machhw    - machhw.    - machhwo   - machhwo.   */
5961         /* machhws   - machhws.   - machhwso  - machhwso.  */
5962         /* nmachhw   - nmachhw.   - nmachhwo  - nmachhwo.  */
5963         /* nmachhws  - nmachhws.  - nmachhwso - nmachhwso. */
5964         /* mulhhw - mulhhw. */
5965         tcg_gen_sari_tl(t0, cpu_gpr[ra], 16);
5966         tcg_gen_ext16s_tl(t0, t0);
5967         tcg_gen_sari_tl(t1, cpu_gpr[rb], 16);
5968         tcg_gen_ext16s_tl(t1, t1);
5969         break;
5970     case 0x00:
5971         /* machhwu   - machhwu.   - machhwuo  - machhwuo.  */
5972         /* machhwsu  - machhwsu.  - machhwsuo - machhwsuo. */
5973         /* mulhhwu - mulhhwu. */
5974         tcg_gen_shri_tl(t0, cpu_gpr[ra], 16);
5975         tcg_gen_ext16u_tl(t0, t0);
5976         tcg_gen_shri_tl(t1, cpu_gpr[rb], 16);
5977         tcg_gen_ext16u_tl(t1, t1);
5978         break;
5979     case 0x0D:
5980         /* maclhw    - maclhw.    - maclhwo   - maclhwo.   */
5981         /* maclhws   - maclhws.   - maclhwso  - maclhwso.  */
5982         /* nmaclhw   - nmaclhw.   - nmaclhwo  - nmaclhwo.  */
5983         /* nmaclhws  - nmaclhws.  - nmaclhwso - nmaclhwso. */
5984         /* mullhw - mullhw. */
5985         tcg_gen_ext16s_tl(t0, cpu_gpr[ra]);
5986         tcg_gen_ext16s_tl(t1, cpu_gpr[rb]);
5987         break;
5988     case 0x0C:
5989         /* maclhwu   - maclhwu.   - maclhwuo  - maclhwuo.  */
5990         /* maclhwsu  - maclhwsu.  - maclhwsuo - maclhwsuo. */
5991         /* mullhwu - mullhwu. */
5992         tcg_gen_ext16u_tl(t0, cpu_gpr[ra]);
5993         tcg_gen_ext16u_tl(t1, cpu_gpr[rb]);
5994         break;
5995     }
5996     if (opc2 & 0x04) {
5997         /* (n)multiply-and-accumulate (0x0C / 0x0E) */
5998         tcg_gen_mul_tl(t1, t0, t1);
5999         if (opc2 & 0x02) {
6000             /* nmultiply-and-accumulate (0x0E) */
6001             tcg_gen_sub_tl(t0, cpu_gpr[rt], t1);
6002         } else {
6003             /* multiply-and-accumulate (0x0C) */
6004             tcg_gen_add_tl(t0, cpu_gpr[rt], t1);
6005         }
6006
6007         if (opc3 & 0x12) {
6008             /* Check overflow and/or saturate */
6009             TCGLabel *l1 = gen_new_label();
6010
6011             if (opc3 & 0x10) {
6012                 /* Start with XER OV disabled, the most likely case */
6013                 tcg_gen_movi_tl(cpu_ov, 0);
6014             }
6015             if (opc3 & 0x01) {
6016                 /* Signed */
6017                 tcg_gen_xor_tl(t1, cpu_gpr[rt], t1);
6018                 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
6019                 tcg_gen_xor_tl(t1, cpu_gpr[rt], t0);
6020                 tcg_gen_brcondi_tl(TCG_COND_LT, t1, 0, l1);
6021                 if (opc3 & 0x02) {
6022                     /* Saturate */
6023                     tcg_gen_sari_tl(t0, cpu_gpr[rt], 31);
6024                     tcg_gen_xori_tl(t0, t0, 0x7fffffff);
6025                 }
6026             } else {
6027                 /* Unsigned */
6028                 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6029                 if (opc3 & 0x02) {
6030                     /* Saturate */
6031                     tcg_gen_movi_tl(t0, UINT32_MAX);
6032                 }
6033             }
6034             if (opc3 & 0x10) {
6035                 /* Check overflow */
6036                 tcg_gen_movi_tl(cpu_ov, 1);
6037                 tcg_gen_movi_tl(cpu_so, 1);
6038             }
6039             gen_set_label(l1);
6040             tcg_gen_mov_tl(cpu_gpr[rt], t0);
6041         }
6042     } else {
6043         tcg_gen_mul_tl(cpu_gpr[rt], t0, t1);
6044     }
6045     tcg_temp_free(t0);
6046     tcg_temp_free(t1);
6047     if (unlikely(Rc) != 0) {
6048         /* Update Rc0 */
6049         gen_set_Rc0(ctx, cpu_gpr[rt]);
6050     }
6051 }
6052
6053 #define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
6054 static void glue(gen_, name)(DisasContext *ctx)                               \
6055 {                                                                             \
6056     gen_405_mulladd_insn(ctx, opc2, opc3, rA(ctx->opcode), rB(ctx->opcode),   \
6057                          rD(ctx->opcode), Rc(ctx->opcode));                   \
6058 }
6059
6060 /* macchw    - macchw.    */
6061 GEN_MAC_HANDLER(macchw, 0x0C, 0x05);
6062 /* macchwo   - macchwo.   */
6063 GEN_MAC_HANDLER(macchwo, 0x0C, 0x15);
6064 /* macchws   - macchws.   */
6065 GEN_MAC_HANDLER(macchws, 0x0C, 0x07);
6066 /* macchwso  - macchwso.  */
6067 GEN_MAC_HANDLER(macchwso, 0x0C, 0x17);
6068 /* macchwsu  - macchwsu.  */
6069 GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06);
6070 /* macchwsuo - macchwsuo. */
6071 GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16);
6072 /* macchwu   - macchwu.   */
6073 GEN_MAC_HANDLER(macchwu, 0x0C, 0x04);
6074 /* macchwuo  - macchwuo.  */
6075 GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14);
6076 /* machhw    - machhw.    */
6077 GEN_MAC_HANDLER(machhw, 0x0C, 0x01);
6078 /* machhwo   - machhwo.   */
6079 GEN_MAC_HANDLER(machhwo, 0x0C, 0x11);
6080 /* machhws   - machhws.   */
6081 GEN_MAC_HANDLER(machhws, 0x0C, 0x03);
6082 /* machhwso  - machhwso.  */
6083 GEN_MAC_HANDLER(machhwso, 0x0C, 0x13);
6084 /* machhwsu  - machhwsu.  */
6085 GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02);
6086 /* machhwsuo - machhwsuo. */
6087 GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12);
6088 /* machhwu   - machhwu.   */
6089 GEN_MAC_HANDLER(machhwu, 0x0C, 0x00);
6090 /* machhwuo  - machhwuo.  */
6091 GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10);
6092 /* maclhw    - maclhw.    */
6093 GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D);
6094 /* maclhwo   - maclhwo.   */
6095 GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D);
6096 /* maclhws   - maclhws.   */
6097 GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F);
6098 /* maclhwso  - maclhwso.  */
6099 GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F);
6100 /* maclhwu   - maclhwu.   */
6101 GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C);
6102 /* maclhwuo  - maclhwuo.  */
6103 GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C);
6104 /* maclhwsu  - maclhwsu.  */
6105 GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E);
6106 /* maclhwsuo - maclhwsuo. */
6107 GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E);
6108 /* nmacchw   - nmacchw.   */
6109 GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05);
6110 /* nmacchwo  - nmacchwo.  */
6111 GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15);
6112 /* nmacchws  - nmacchws.  */
6113 GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07);
6114 /* nmacchwso - nmacchwso. */
6115 GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17);
6116 /* nmachhw   - nmachhw.   */
6117 GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01);
6118 /* nmachhwo  - nmachhwo.  */
6119 GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11);
6120 /* nmachhws  - nmachhws.  */
6121 GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03);
6122 /* nmachhwso - nmachhwso. */
6123 GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13);
6124 /* nmaclhw   - nmaclhw.   */
6125 GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D);
6126 /* nmaclhwo  - nmaclhwo.  */
6127 GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D);
6128 /* nmaclhws  - nmaclhws.  */
6129 GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F);
6130 /* nmaclhwso - nmaclhwso. */
6131 GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F);
6132
6133 /* mulchw  - mulchw.  */
6134 GEN_MAC_HANDLER(mulchw, 0x08, 0x05);
6135 /* mulchwu - mulchwu. */
6136 GEN_MAC_HANDLER(mulchwu, 0x08, 0x04);
6137 /* mulhhw  - mulhhw.  */
6138 GEN_MAC_HANDLER(mulhhw, 0x08, 0x01);
6139 /* mulhhwu - mulhhwu. */
6140 GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00);
6141 /* mullhw  - mullhw.  */
6142 GEN_MAC_HANDLER(mullhw, 0x08, 0x0D);
6143 /* mullhwu - mullhwu. */
6144 GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C);
6145
6146 /* mfdcr */
6147 static void gen_mfdcr(DisasContext *ctx)
6148 {
6149 #if defined(CONFIG_USER_ONLY)
6150     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
6151 #else
6152     TCGv dcrn;
6153     if (unlikely(ctx->pr)) {
6154         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
6155         return;
6156     }
6157     /* NIP cannot be restored if the memory exception comes from an helper */
6158     gen_update_nip(ctx, ctx->nip - 4);
6159     dcrn = tcg_const_tl(SPR(ctx->opcode));
6160     gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_env, dcrn);
6161     tcg_temp_free(dcrn);
6162 #endif
6163 }
6164
6165 /* mtdcr */
6166 static void gen_mtdcr(DisasContext *ctx)
6167 {
6168 #if defined(CONFIG_USER_ONLY)
6169     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
6170 #else
6171     TCGv dcrn;
6172     if (unlikely(ctx->pr)) {
6173         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
6174         return;
6175     }
6176     /* NIP cannot be restored if the memory exception comes from an helper */
6177     gen_update_nip(ctx, ctx->nip - 4);
6178     dcrn = tcg_const_tl(SPR(ctx->opcode));
6179     gen_helper_store_dcr(cpu_env, dcrn, cpu_gpr[rS(ctx->opcode)]);
6180     tcg_temp_free(dcrn);
6181 #endif
6182 }
6183
6184 /* mfdcrx */
6185 /* XXX: not implemented on 440 ? */
6186 static void gen_mfdcrx(DisasContext *ctx)
6187 {
6188 #if defined(CONFIG_USER_ONLY)
6189     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
6190 #else
6191     if (unlikely(ctx->pr)) {
6192         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
6193         return;
6194     }
6195     /* NIP cannot be restored if the memory exception comes from an helper */
6196     gen_update_nip(ctx, ctx->nip - 4);
6197     gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_env,
6198                         cpu_gpr[rA(ctx->opcode)]);
6199     /* Note: Rc update flag set leads to undefined state of Rc0 */
6200 #endif
6201 }
6202
6203 /* mtdcrx */
6204 /* XXX: not implemented on 440 ? */
6205 static void gen_mtdcrx(DisasContext *ctx)
6206 {
6207 #if defined(CONFIG_USER_ONLY)
6208     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
6209 #else
6210     if (unlikely(ctx->pr)) {
6211         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
6212         return;
6213     }
6214     /* NIP cannot be restored if the memory exception comes from an helper */
6215     gen_update_nip(ctx, ctx->nip - 4);
6216     gen_helper_store_dcr(cpu_env, cpu_gpr[rA(ctx->opcode)],
6217                          cpu_gpr[rS(ctx->opcode)]);
6218     /* Note: Rc update flag set leads to undefined state of Rc0 */
6219 #endif
6220 }
6221
6222 /* mfdcrux (PPC 460) : user-mode access to DCR */
6223 static void gen_mfdcrux(DisasContext *ctx)
6224 {
6225     /* NIP cannot be restored if the memory exception comes from an helper */
6226     gen_update_nip(ctx, ctx->nip - 4);
6227     gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_env,
6228                         cpu_gpr[rA(ctx->opcode)]);
6229     /* Note: Rc update flag set leads to undefined state of Rc0 */
6230 }
6231
6232 /* mtdcrux (PPC 460) : user-mode access to DCR */
6233 static void gen_mtdcrux(DisasContext *ctx)
6234 {
6235     /* NIP cannot be restored if the memory exception comes from an helper */
6236     gen_update_nip(ctx, ctx->nip - 4);
6237     gen_helper_store_dcr(cpu_env, cpu_gpr[rA(ctx->opcode)],
6238                          cpu_gpr[rS(ctx->opcode)]);
6239     /* Note: Rc update flag set leads to undefined state of Rc0 */
6240 }
6241
6242 /* dccci */
6243 static void gen_dccci(DisasContext *ctx)
6244 {
6245 #if defined(CONFIG_USER_ONLY)
6246     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6247 #else
6248     if (unlikely(ctx->pr)) {
6249         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6250         return;
6251     }
6252     /* interpreted as no-op */
6253 #endif
6254 }
6255
6256 /* dcread */
6257 static void gen_dcread(DisasContext *ctx)
6258 {
6259 #if defined(CONFIG_USER_ONLY)
6260     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6261 #else
6262     TCGv EA, val;
6263     if (unlikely(ctx->pr)) {
6264         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6265         return;
6266     }
6267     gen_set_access_type(ctx, ACCESS_CACHE);
6268     EA = tcg_temp_new();
6269     gen_addr_reg_index(ctx, EA);
6270     val = tcg_temp_new();
6271     gen_qemu_ld32u(ctx, val, EA);
6272     tcg_temp_free(val);
6273     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], EA);
6274     tcg_temp_free(EA);
6275 #endif
6276 }
6277
6278 /* icbt */
6279 static void gen_icbt_40x(DisasContext *ctx)
6280 {
6281     /* interpreted as no-op */
6282     /* XXX: specification say this is treated as a load by the MMU
6283      *      but does not generate any exception
6284      */
6285 }
6286
6287 /* iccci */
6288 static void gen_iccci(DisasContext *ctx)
6289 {
6290 #if defined(CONFIG_USER_ONLY)
6291     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6292 #else
6293     if (unlikely(ctx->pr)) {
6294         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6295         return;
6296     }
6297     /* interpreted as no-op */
6298 #endif
6299 }
6300
6301 /* icread */
6302 static void gen_icread(DisasContext *ctx)
6303 {
6304 #if defined(CONFIG_USER_ONLY)
6305     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6306 #else
6307     if (unlikely(ctx->pr)) {
6308         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6309         return;
6310     }
6311     /* interpreted as no-op */
6312 #endif
6313 }
6314
6315 /* rfci (supervisor only) */
6316 static void gen_rfci_40x(DisasContext *ctx)
6317 {
6318 #if defined(CONFIG_USER_ONLY)
6319     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6320 #else
6321     if (unlikely(ctx->pr)) {
6322         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6323         return;
6324     }
6325     /* Restore CPU state */
6326     gen_helper_40x_rfci(cpu_env);
6327     gen_sync_exception(ctx);
6328 #endif
6329 }
6330
6331 static void gen_rfci(DisasContext *ctx)
6332 {
6333 #if defined(CONFIG_USER_ONLY)
6334     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6335 #else
6336     if (unlikely(ctx->pr)) {
6337         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6338         return;
6339     }
6340     /* Restore CPU state */
6341     gen_helper_rfci(cpu_env);
6342     gen_sync_exception(ctx);
6343 #endif
6344 }
6345
6346 /* BookE specific */
6347
6348 /* XXX: not implemented on 440 ? */
6349 static void gen_rfdi(DisasContext *ctx)
6350 {
6351 #if defined(CONFIG_USER_ONLY)
6352     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6353 #else
6354     if (unlikely(ctx->pr)) {
6355         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6356         return;
6357     }
6358     /* Restore CPU state */
6359     gen_helper_rfdi(cpu_env);
6360     gen_sync_exception(ctx);
6361 #endif
6362 }
6363
6364 /* XXX: not implemented on 440 ? */
6365 static void gen_rfmci(DisasContext *ctx)
6366 {
6367 #if defined(CONFIG_USER_ONLY)
6368     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6369 #else
6370     if (unlikely(ctx->pr)) {
6371         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6372         return;
6373     }
6374     /* Restore CPU state */
6375     gen_helper_rfmci(cpu_env);
6376     gen_sync_exception(ctx);
6377 #endif
6378 }
6379
6380 /* TLB management - PowerPC 405 implementation */
6381
6382 /* tlbre */
6383 static void gen_tlbre_40x(DisasContext *ctx)
6384 {
6385 #if defined(CONFIG_USER_ONLY)
6386     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6387 #else
6388     if (unlikely(ctx->pr)) {
6389         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6390         return;
6391     }
6392     switch (rB(ctx->opcode)) {
6393     case 0:
6394         gen_helper_4xx_tlbre_hi(cpu_gpr[rD(ctx->opcode)], cpu_env,
6395                                 cpu_gpr[rA(ctx->opcode)]);
6396         break;
6397     case 1:
6398         gen_helper_4xx_tlbre_lo(cpu_gpr[rD(ctx->opcode)], cpu_env,
6399                                 cpu_gpr[rA(ctx->opcode)]);
6400         break;
6401     default:
6402         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
6403         break;
6404     }
6405 #endif
6406 }
6407
6408 /* tlbsx - tlbsx. */
6409 static void gen_tlbsx_40x(DisasContext *ctx)
6410 {
6411 #if defined(CONFIG_USER_ONLY)
6412     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6413 #else
6414     TCGv t0;
6415     if (unlikely(ctx->pr)) {
6416         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6417         return;
6418     }
6419     t0 = tcg_temp_new();
6420     gen_addr_reg_index(ctx, t0);
6421     gen_helper_4xx_tlbsx(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
6422     tcg_temp_free(t0);
6423     if (Rc(ctx->opcode)) {
6424         TCGLabel *l1 = gen_new_label();
6425         tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
6426         tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rD(ctx->opcode)], -1, l1);
6427         tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
6428         gen_set_label(l1);
6429     }
6430 #endif
6431 }
6432
6433 /* tlbwe */
6434 static void gen_tlbwe_40x(DisasContext *ctx)
6435 {
6436 #if defined(CONFIG_USER_ONLY)
6437     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6438 #else
6439     if (unlikely(ctx->pr)) {
6440         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6441         return;
6442     }
6443     switch (rB(ctx->opcode)) {
6444     case 0:
6445         gen_helper_4xx_tlbwe_hi(cpu_env, cpu_gpr[rA(ctx->opcode)],
6446                                 cpu_gpr[rS(ctx->opcode)]);
6447         break;
6448     case 1:
6449         gen_helper_4xx_tlbwe_lo(cpu_env, cpu_gpr[rA(ctx->opcode)],
6450                                 cpu_gpr[rS(ctx->opcode)]);
6451         break;
6452     default:
6453         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
6454         break;
6455     }
6456 #endif
6457 }
6458
6459 /* TLB management - PowerPC 440 implementation */
6460
6461 /* tlbre */
6462 static void gen_tlbre_440(DisasContext *ctx)
6463 {
6464 #if defined(CONFIG_USER_ONLY)
6465     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6466 #else
6467     if (unlikely(ctx->pr)) {
6468         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6469         return;
6470     }
6471     switch (rB(ctx->opcode)) {
6472     case 0:
6473     case 1:
6474     case 2:
6475         {
6476             TCGv_i32 t0 = tcg_const_i32(rB(ctx->opcode));
6477             gen_helper_440_tlbre(cpu_gpr[rD(ctx->opcode)], cpu_env,
6478                                  t0, cpu_gpr[rA(ctx->opcode)]);
6479             tcg_temp_free_i32(t0);
6480         }
6481         break;
6482     default:
6483         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
6484         break;
6485     }
6486 #endif
6487 }
6488
6489 /* tlbsx - tlbsx. */
6490 static void gen_tlbsx_440(DisasContext *ctx)
6491 {
6492 #if defined(CONFIG_USER_ONLY)
6493     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6494 #else
6495     TCGv t0;
6496     if (unlikely(ctx->pr)) {
6497         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6498         return;
6499     }
6500     t0 = tcg_temp_new();
6501     gen_addr_reg_index(ctx, t0);
6502     gen_helper_440_tlbsx(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
6503     tcg_temp_free(t0);
6504     if (Rc(ctx->opcode)) {
6505         TCGLabel *l1 = gen_new_label();
6506         tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
6507         tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rD(ctx->opcode)], -1, l1);
6508         tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
6509         gen_set_label(l1);
6510     }
6511 #endif
6512 }
6513
6514 /* tlbwe */
6515 static void gen_tlbwe_440(DisasContext *ctx)
6516 {
6517 #if defined(CONFIG_USER_ONLY)
6518     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6519 #else
6520     if (unlikely(ctx->pr)) {
6521         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6522         return;
6523     }
6524     switch (rB(ctx->opcode)) {
6525     case 0:
6526     case 1:
6527     case 2:
6528         {
6529             TCGv_i32 t0 = tcg_const_i32(rB(ctx->opcode));
6530             gen_helper_440_tlbwe(cpu_env, t0, cpu_gpr[rA(ctx->opcode)],
6531                                  cpu_gpr[rS(ctx->opcode)]);
6532             tcg_temp_free_i32(t0);
6533         }
6534         break;
6535     default:
6536         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
6537         break;
6538     }
6539 #endif
6540 }
6541
6542 /* TLB management - PowerPC BookE 2.06 implementation */
6543
6544 /* tlbre */
6545 static void gen_tlbre_booke206(DisasContext *ctx)
6546 {
6547 #if defined(CONFIG_USER_ONLY)
6548     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6549 #else
6550     if (unlikely(ctx->pr)) {
6551         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6552         return;
6553     }
6554
6555     gen_helper_booke206_tlbre(cpu_env);
6556 #endif
6557 }
6558
6559 /* tlbsx - tlbsx. */
6560 static void gen_tlbsx_booke206(DisasContext *ctx)
6561 {
6562 #if defined(CONFIG_USER_ONLY)
6563     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6564 #else
6565     TCGv t0;
6566     if (unlikely(ctx->pr)) {
6567         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6568         return;
6569     }
6570
6571     if (rA(ctx->opcode)) {
6572         t0 = tcg_temp_new();
6573         tcg_gen_mov_tl(t0, cpu_gpr[rD(ctx->opcode)]);
6574     } else {
6575         t0 = tcg_const_tl(0);
6576     }
6577
6578     tcg_gen_add_tl(t0, t0, cpu_gpr[rB(ctx->opcode)]);
6579     gen_helper_booke206_tlbsx(cpu_env, t0);
6580     tcg_temp_free(t0);
6581 #endif
6582 }
6583
6584 /* tlbwe */
6585 static void gen_tlbwe_booke206(DisasContext *ctx)
6586 {
6587 #if defined(CONFIG_USER_ONLY)
6588     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6589 #else
6590     if (unlikely(ctx->pr)) {
6591         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6592         return;
6593     }
6594     gen_update_nip(ctx, ctx->nip - 4);
6595     gen_helper_booke206_tlbwe(cpu_env);
6596 #endif
6597 }
6598
6599 static void gen_tlbivax_booke206(DisasContext *ctx)
6600 {
6601 #if defined(CONFIG_USER_ONLY)
6602     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6603 #else
6604     TCGv t0;
6605     if (unlikely(ctx->pr)) {
6606         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6607         return;
6608     }
6609
6610     t0 = tcg_temp_new();
6611     gen_addr_reg_index(ctx, t0);
6612
6613     gen_helper_booke206_tlbivax(cpu_env, t0);
6614     tcg_temp_free(t0);
6615 #endif
6616 }
6617
6618 static void gen_tlbilx_booke206(DisasContext *ctx)
6619 {
6620 #if defined(CONFIG_USER_ONLY)
6621     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6622 #else
6623     TCGv t0;
6624     if (unlikely(ctx->pr)) {
6625         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6626         return;
6627     }
6628
6629     t0 = tcg_temp_new();
6630     gen_addr_reg_index(ctx, t0);
6631
6632     switch((ctx->opcode >> 21) & 0x3) {
6633     case 0:
6634         gen_helper_booke206_tlbilx0(cpu_env, t0);
6635         break;
6636     case 1:
6637         gen_helper_booke206_tlbilx1(cpu_env, t0);
6638         break;
6639     case 3:
6640         gen_helper_booke206_tlbilx3(cpu_env, t0);
6641         break;
6642     default:
6643         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
6644         break;
6645     }
6646
6647     tcg_temp_free(t0);
6648 #endif
6649 }
6650
6651
6652 /* wrtee */
6653 static void gen_wrtee(DisasContext *ctx)
6654 {
6655 #if defined(CONFIG_USER_ONLY)
6656     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6657 #else
6658     TCGv t0;
6659     if (unlikely(ctx->pr)) {
6660         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6661         return;
6662     }
6663     t0 = tcg_temp_new();
6664     tcg_gen_andi_tl(t0, cpu_gpr[rD(ctx->opcode)], (1 << MSR_EE));
6665     tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE));
6666     tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
6667     tcg_temp_free(t0);
6668     /* Stop translation to have a chance to raise an exception
6669      * if we just set msr_ee to 1
6670      */
6671     gen_stop_exception(ctx);
6672 #endif
6673 }
6674
6675 /* wrteei */
6676 static void gen_wrteei(DisasContext *ctx)
6677 {
6678 #if defined(CONFIG_USER_ONLY)
6679     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6680 #else
6681     if (unlikely(ctx->pr)) {
6682         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6683         return;
6684     }
6685     if (ctx->opcode & 0x00008000) {
6686         tcg_gen_ori_tl(cpu_msr, cpu_msr, (1 << MSR_EE));
6687         /* Stop translation to have a chance to raise an exception */
6688         gen_stop_exception(ctx);
6689     } else {
6690         tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE));
6691     }
6692 #endif
6693 }
6694
6695 /* PowerPC 440 specific instructions */
6696
6697 /* dlmzb */
6698 static void gen_dlmzb(DisasContext *ctx)
6699 {
6700     TCGv_i32 t0 = tcg_const_i32(Rc(ctx->opcode));
6701     gen_helper_dlmzb(cpu_gpr[rA(ctx->opcode)], cpu_env,
6702                      cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], t0);
6703     tcg_temp_free_i32(t0);
6704 }
6705
6706 /* mbar replaces eieio on 440 */
6707 static void gen_mbar(DisasContext *ctx)
6708 {
6709     /* interpreted as no-op */
6710 }
6711
6712 /* msync replaces sync on 440 */
6713 static void gen_msync_4xx(DisasContext *ctx)
6714 {
6715     /* interpreted as no-op */
6716 }
6717
6718 /* icbt */
6719 static void gen_icbt_440(DisasContext *ctx)
6720 {
6721     /* interpreted as no-op */
6722     /* XXX: specification say this is treated as a load by the MMU
6723      *      but does not generate any exception
6724      */
6725 }
6726
6727 /* Embedded.Processor Control */
6728
6729 static void gen_msgclr(DisasContext *ctx)
6730 {
6731 #if defined(CONFIG_USER_ONLY)
6732     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6733 #else
6734     if (unlikely(ctx->pr)) {
6735         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6736         return;
6737     }
6738
6739     gen_helper_msgclr(cpu_env, cpu_gpr[rB(ctx->opcode)]);
6740 #endif
6741 }
6742
6743 static void gen_msgsnd(DisasContext *ctx)
6744 {
6745 #if defined(CONFIG_USER_ONLY)
6746     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6747 #else
6748     if (unlikely(ctx->pr)) {
6749         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6750         return;
6751     }
6752
6753     gen_helper_msgsnd(cpu_gpr[rB(ctx->opcode)]);
6754 #endif
6755 }
6756
6757 /***                      Altivec vector extension                         ***/
6758 /* Altivec registers moves */
6759
6760 static inline TCGv_ptr gen_avr_ptr(int reg)
6761 {
6762     TCGv_ptr r = tcg_temp_new_ptr();
6763     tcg_gen_addi_ptr(r, cpu_env, offsetof(CPUPPCState, avr[reg]));
6764     return r;
6765 }
6766
6767 #define GEN_VR_LDX(name, opc2, opc3)                                          \
6768 static void glue(gen_, name)(DisasContext *ctx)                                       \
6769 {                                                                             \
6770     TCGv EA;                                                                  \
6771     if (unlikely(!ctx->altivec_enabled)) {                                    \
6772         gen_exception(ctx, POWERPC_EXCP_VPU);                                 \
6773         return;                                                               \
6774     }                                                                         \
6775     gen_set_access_type(ctx, ACCESS_INT);                                     \
6776     EA = tcg_temp_new();                                                      \
6777     gen_addr_reg_index(ctx, EA);                                              \
6778     tcg_gen_andi_tl(EA, EA, ~0xf);                                            \
6779     /* We only need to swap high and low halves. gen_qemu_ld64 does necessary \
6780        64-bit byteswap already. */                                            \
6781     if (ctx->le_mode) {                                                       \
6782         gen_qemu_ld64(ctx, cpu_avrl[rD(ctx->opcode)], EA);                    \
6783         tcg_gen_addi_tl(EA, EA, 8);                                           \
6784         gen_qemu_ld64(ctx, cpu_avrh[rD(ctx->opcode)], EA);                    \
6785     } else {                                                                  \
6786         gen_qemu_ld64(ctx, cpu_avrh[rD(ctx->opcode)], EA);                    \
6787         tcg_gen_addi_tl(EA, EA, 8);                                           \
6788         gen_qemu_ld64(ctx, cpu_avrl[rD(ctx->opcode)], EA);                    \
6789     }                                                                         \
6790     tcg_temp_free(EA);                                                        \
6791 }
6792
6793 #define GEN_VR_STX(name, opc2, opc3)                                          \
6794 static void gen_st##name(DisasContext *ctx)                                   \
6795 {                                                                             \
6796     TCGv EA;                                                                  \
6797     if (unlikely(!ctx->altivec_enabled)) {                                    \
6798         gen_exception(ctx, POWERPC_EXCP_VPU);                                 \
6799         return;                                                               \
6800     }                                                                         \
6801     gen_set_access_type(ctx, ACCESS_INT);                                     \
6802     EA = tcg_temp_new();                                                      \
6803     gen_addr_reg_index(ctx, EA);                                              \
6804     tcg_gen_andi_tl(EA, EA, ~0xf);                                            \
6805     /* We only need to swap high and low halves. gen_qemu_st64 does necessary \
6806        64-bit byteswap already. */                                            \
6807     if (ctx->le_mode) {                                                       \
6808         gen_qemu_st64(ctx, cpu_avrl[rD(ctx->opcode)], EA);                    \
6809         tcg_gen_addi_tl(EA, EA, 8);                                           \
6810         gen_qemu_st64(ctx, cpu_avrh[rD(ctx->opcode)], EA);                    \
6811     } else {                                                                  \
6812         gen_qemu_st64(ctx, cpu_avrh[rD(ctx->opcode)], EA);                    \
6813         tcg_gen_addi_tl(EA, EA, 8);                                           \
6814         gen_qemu_st64(ctx, cpu_avrl[rD(ctx->opcode)], EA);                    \
6815     }                                                                         \
6816     tcg_temp_free(EA);                                                        \
6817 }
6818
6819 #define GEN_VR_LVE(name, opc2, opc3, size)                              \
6820 static void gen_lve##name(DisasContext *ctx)                            \
6821     {                                                                   \
6822         TCGv EA;                                                        \
6823         TCGv_ptr rs;                                                    \
6824         if (unlikely(!ctx->altivec_enabled)) {                          \
6825             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
6826             return;                                                     \
6827         }                                                               \
6828         gen_set_access_type(ctx, ACCESS_INT);                           \
6829         EA = tcg_temp_new();                                            \
6830         gen_addr_reg_index(ctx, EA);                                    \
6831         if (size > 1) {                                                 \
6832             tcg_gen_andi_tl(EA, EA, ~(size - 1));                       \
6833         }                                                               \
6834         rs = gen_avr_ptr(rS(ctx->opcode));                              \
6835         gen_helper_lve##name(cpu_env, rs, EA);                          \
6836         tcg_temp_free(EA);                                              \
6837         tcg_temp_free_ptr(rs);                                          \
6838     }
6839
6840 #define GEN_VR_STVE(name, opc2, opc3, size)                             \
6841 static void gen_stve##name(DisasContext *ctx)                           \
6842     {                                                                   \
6843         TCGv EA;                                                        \
6844         TCGv_ptr rs;                                                    \
6845         if (unlikely(!ctx->altivec_enabled)) {                          \
6846             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
6847             return;                                                     \
6848         }                                                               \
6849         gen_set_access_type(ctx, ACCESS_INT);                           \
6850         EA = tcg_temp_new();                                            \
6851         gen_addr_reg_index(ctx, EA);                                    \
6852         if (size > 1) {                                                 \
6853             tcg_gen_andi_tl(EA, EA, ~(size - 1));                       \
6854         }                                                               \
6855         rs = gen_avr_ptr(rS(ctx->opcode));                              \
6856         gen_helper_stve##name(cpu_env, rs, EA);                         \
6857         tcg_temp_free(EA);                                              \
6858         tcg_temp_free_ptr(rs);                                          \
6859     }
6860
6861 GEN_VR_LDX(lvx, 0x07, 0x03);
6862 /* As we don't emulate the cache, lvxl is stricly equivalent to lvx */
6863 GEN_VR_LDX(lvxl, 0x07, 0x0B);
6864
6865 GEN_VR_LVE(bx, 0x07, 0x00, 1);
6866 GEN_VR_LVE(hx, 0x07, 0x01, 2);
6867 GEN_VR_LVE(wx, 0x07, 0x02, 4);
6868
6869 GEN_VR_STX(svx, 0x07, 0x07);
6870 /* As we don't emulate the cache, stvxl is stricly equivalent to stvx */
6871 GEN_VR_STX(svxl, 0x07, 0x0F);
6872
6873 GEN_VR_STVE(bx, 0x07, 0x04, 1);
6874 GEN_VR_STVE(hx, 0x07, 0x05, 2);
6875 GEN_VR_STVE(wx, 0x07, 0x06, 4);
6876
6877 static void gen_lvsl(DisasContext *ctx)
6878 {
6879     TCGv_ptr rd;
6880     TCGv EA;
6881     if (unlikely(!ctx->altivec_enabled)) {
6882         gen_exception(ctx, POWERPC_EXCP_VPU);
6883         return;
6884     }
6885     EA = tcg_temp_new();
6886     gen_addr_reg_index(ctx, EA);
6887     rd = gen_avr_ptr(rD(ctx->opcode));
6888     gen_helper_lvsl(rd, EA);
6889     tcg_temp_free(EA);
6890     tcg_temp_free_ptr(rd);
6891 }
6892
6893 static void gen_lvsr(DisasContext *ctx)
6894 {
6895     TCGv_ptr rd;
6896     TCGv EA;
6897     if (unlikely(!ctx->altivec_enabled)) {
6898         gen_exception(ctx, POWERPC_EXCP_VPU);
6899         return;
6900     }
6901     EA = tcg_temp_new();
6902     gen_addr_reg_index(ctx, EA);
6903     rd = gen_avr_ptr(rD(ctx->opcode));
6904     gen_helper_lvsr(rd, EA);
6905     tcg_temp_free(EA);
6906     tcg_temp_free_ptr(rd);
6907 }
6908
6909 static void gen_mfvscr(DisasContext *ctx)
6910 {
6911     TCGv_i32 t;
6912     if (unlikely(!ctx->altivec_enabled)) {
6913         gen_exception(ctx, POWERPC_EXCP_VPU);
6914         return;
6915     }
6916     tcg_gen_movi_i64(cpu_avrh[rD(ctx->opcode)], 0);
6917     t = tcg_temp_new_i32();
6918     tcg_gen_ld_i32(t, cpu_env, offsetof(CPUPPCState, vscr));
6919     tcg_gen_extu_i32_i64(cpu_avrl[rD(ctx->opcode)], t);
6920     tcg_temp_free_i32(t);
6921 }
6922
6923 static void gen_mtvscr(DisasContext *ctx)
6924 {
6925     TCGv_ptr p;
6926     if (unlikely(!ctx->altivec_enabled)) {
6927         gen_exception(ctx, POWERPC_EXCP_VPU);
6928         return;
6929     }
6930     p = gen_avr_ptr(rB(ctx->opcode));
6931     gen_helper_mtvscr(cpu_env, p);
6932     tcg_temp_free_ptr(p);
6933 }
6934
6935 /* Logical operations */
6936 #define GEN_VX_LOGICAL(name, tcg_op, opc2, opc3)                        \
6937 static void glue(gen_, name)(DisasContext *ctx)                                 \
6938 {                                                                       \
6939     if (unlikely(!ctx->altivec_enabled)) {                              \
6940         gen_exception(ctx, POWERPC_EXCP_VPU);                           \
6941         return;                                                         \
6942     }                                                                   \
6943     tcg_op(cpu_avrh[rD(ctx->opcode)], cpu_avrh[rA(ctx->opcode)], cpu_avrh[rB(ctx->opcode)]); \
6944     tcg_op(cpu_avrl[rD(ctx->opcode)], cpu_avrl[rA(ctx->opcode)], cpu_avrl[rB(ctx->opcode)]); \
6945 }
6946
6947 GEN_VX_LOGICAL(vand, tcg_gen_and_i64, 2, 16);
6948 GEN_VX_LOGICAL(vandc, tcg_gen_andc_i64, 2, 17);
6949 GEN_VX_LOGICAL(vor, tcg_gen_or_i64, 2, 18);
6950 GEN_VX_LOGICAL(vxor, tcg_gen_xor_i64, 2, 19);
6951 GEN_VX_LOGICAL(vnor, tcg_gen_nor_i64, 2, 20);
6952 GEN_VX_LOGICAL(veqv, tcg_gen_eqv_i64, 2, 26);
6953 GEN_VX_LOGICAL(vnand, tcg_gen_nand_i64, 2, 22);
6954 GEN_VX_LOGICAL(vorc, tcg_gen_orc_i64, 2, 21);
6955
6956 #define GEN_VXFORM(name, opc2, opc3)                                    \
6957 static void glue(gen_, name)(DisasContext *ctx)                                 \
6958 {                                                                       \
6959     TCGv_ptr ra, rb, rd;                                                \
6960     if (unlikely(!ctx->altivec_enabled)) {                              \
6961         gen_exception(ctx, POWERPC_EXCP_VPU);                           \
6962         return;                                                         \
6963     }                                                                   \
6964     ra = gen_avr_ptr(rA(ctx->opcode));                                  \
6965     rb = gen_avr_ptr(rB(ctx->opcode));                                  \
6966     rd = gen_avr_ptr(rD(ctx->opcode));                                  \
6967     gen_helper_##name (rd, ra, rb);                                     \
6968     tcg_temp_free_ptr(ra);                                              \
6969     tcg_temp_free_ptr(rb);                                              \
6970     tcg_temp_free_ptr(rd);                                              \
6971 }
6972
6973 #define GEN_VXFORM_ENV(name, opc2, opc3)                                \
6974 static void glue(gen_, name)(DisasContext *ctx)                         \
6975 {                                                                       \
6976     TCGv_ptr ra, rb, rd;                                                \
6977     if (unlikely(!ctx->altivec_enabled)) {                              \
6978         gen_exception(ctx, POWERPC_EXCP_VPU);                           \
6979         return;                                                         \
6980     }                                                                   \
6981     ra = gen_avr_ptr(rA(ctx->opcode));                                  \
6982     rb = gen_avr_ptr(rB(ctx->opcode));                                  \
6983     rd = gen_avr_ptr(rD(ctx->opcode));                                  \
6984     gen_helper_##name(cpu_env, rd, ra, rb);                             \
6985     tcg_temp_free_ptr(ra);                                              \
6986     tcg_temp_free_ptr(rb);                                              \
6987     tcg_temp_free_ptr(rd);                                              \
6988 }
6989
6990 #define GEN_VXFORM3(name, opc2, opc3)                                   \
6991 static void glue(gen_, name)(DisasContext *ctx)                         \
6992 {                                                                       \
6993     TCGv_ptr ra, rb, rc, rd;                                            \
6994     if (unlikely(!ctx->altivec_enabled)) {                              \
6995         gen_exception(ctx, POWERPC_EXCP_VPU);                           \
6996         return;                                                         \
6997     }                                                                   \
6998     ra = gen_avr_ptr(rA(ctx->opcode));                                  \
6999     rb = gen_avr_ptr(rB(ctx->opcode));                                  \
7000     rc = gen_avr_ptr(rC(ctx->opcode));                                  \
7001     rd = gen_avr_ptr(rD(ctx->opcode));                                  \
7002     gen_helper_##name(rd, ra, rb, rc);                                  \
7003     tcg_temp_free_ptr(ra);                                              \
7004     tcg_temp_free_ptr(rb);                                              \
7005     tcg_temp_free_ptr(rc);                                              \
7006     tcg_temp_free_ptr(rd);                                              \
7007 }
7008
7009 /*
7010  * Support for Altivec instruction pairs that use bit 31 (Rc) as
7011  * an opcode bit.  In general, these pairs come from different
7012  * versions of the ISA, so we must also support a pair of flags for
7013  * each instruction.
7014  */
7015 #define GEN_VXFORM_DUAL(name0, flg0, flg2_0, name1, flg1, flg2_1)          \
7016 static void glue(gen_, name0##_##name1)(DisasContext *ctx)             \
7017 {                                                                      \
7018     if ((Rc(ctx->opcode) == 0) &&                                      \
7019         ((ctx->insns_flags & flg0) || (ctx->insns_flags2 & flg2_0))) { \
7020         gen_##name0(ctx);                                              \
7021     } else if ((Rc(ctx->opcode) == 1) &&                               \
7022         ((ctx->insns_flags & flg1) || (ctx->insns_flags2 & flg2_1))) { \
7023         gen_##name1(ctx);                                              \
7024     } else {                                                           \
7025         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);            \
7026     }                                                                  \
7027 }
7028
7029 GEN_VXFORM(vaddubm, 0, 0);
7030 GEN_VXFORM(vadduhm, 0, 1);
7031 GEN_VXFORM(vadduwm, 0, 2);
7032 GEN_VXFORM(vaddudm, 0, 3);
7033 GEN_VXFORM(vsububm, 0, 16);
7034 GEN_VXFORM(vsubuhm, 0, 17);
7035 GEN_VXFORM(vsubuwm, 0, 18);
7036 GEN_VXFORM(vsubudm, 0, 19);
7037 GEN_VXFORM(vmaxub, 1, 0);
7038 GEN_VXFORM(vmaxuh, 1, 1);
7039 GEN_VXFORM(vmaxuw, 1, 2);
7040 GEN_VXFORM(vmaxud, 1, 3);
7041 GEN_VXFORM(vmaxsb, 1, 4);
7042 GEN_VXFORM(vmaxsh, 1, 5);
7043 GEN_VXFORM(vmaxsw, 1, 6);
7044 GEN_VXFORM(vmaxsd, 1, 7);
7045 GEN_VXFORM(vminub, 1, 8);
7046 GEN_VXFORM(vminuh, 1, 9);
7047 GEN_VXFORM(vminuw, 1, 10);
7048 GEN_VXFORM(vminud, 1, 11);
7049 GEN_VXFORM(vminsb, 1, 12);
7050 GEN_VXFORM(vminsh, 1, 13);
7051 GEN_VXFORM(vminsw, 1, 14);
7052 GEN_VXFORM(vminsd, 1, 15);
7053 GEN_VXFORM(vavgub, 1, 16);
7054 GEN_VXFORM(vavguh, 1, 17);
7055 GEN_VXFORM(vavguw, 1, 18);
7056 GEN_VXFORM(vavgsb, 1, 20);
7057 GEN_VXFORM(vavgsh, 1, 21);
7058 GEN_VXFORM(vavgsw, 1, 22);
7059 GEN_VXFORM(vmrghb, 6, 0);
7060 GEN_VXFORM(vmrghh, 6, 1);
7061 GEN_VXFORM(vmrghw, 6, 2);
7062 GEN_VXFORM(vmrglb, 6, 4);
7063 GEN_VXFORM(vmrglh, 6, 5);
7064 GEN_VXFORM(vmrglw, 6, 6);
7065
7066 static void gen_vmrgew(DisasContext *ctx)
7067 {
7068     TCGv_i64 tmp;
7069     int VT, VA, VB;
7070     if (unlikely(!ctx->altivec_enabled)) {
7071         gen_exception(ctx, POWERPC_EXCP_VPU);
7072         return;
7073     }
7074     VT = rD(ctx->opcode);
7075     VA = rA(ctx->opcode);
7076     VB = rB(ctx->opcode);
7077     tmp = tcg_temp_new_i64();
7078     tcg_gen_shri_i64(tmp, cpu_avrh[VB], 32);
7079     tcg_gen_deposit_i64(cpu_avrh[VT], cpu_avrh[VA], tmp, 0, 32);
7080     tcg_gen_shri_i64(tmp, cpu_avrl[VB], 32);
7081     tcg_gen_deposit_i64(cpu_avrl[VT], cpu_avrl[VA], tmp, 0, 32);
7082     tcg_temp_free_i64(tmp);
7083 }
7084
7085 static void gen_vmrgow(DisasContext *ctx)
7086 {
7087     int VT, VA, VB;
7088     if (unlikely(!ctx->altivec_enabled)) {
7089         gen_exception(ctx, POWERPC_EXCP_VPU);
7090         return;
7091     }
7092     VT = rD(ctx->opcode);
7093     VA = rA(ctx->opcode);
7094     VB = rB(ctx->opcode);
7095
7096     tcg_gen_deposit_i64(cpu_avrh[VT], cpu_avrh[VB], cpu_avrh[VA], 32, 32);
7097     tcg_gen_deposit_i64(cpu_avrl[VT], cpu_avrl[VB], cpu_avrl[VA], 32, 32);
7098 }
7099
7100 GEN_VXFORM(vmuloub, 4, 0);
7101 GEN_VXFORM(vmulouh, 4, 1);
7102 GEN_VXFORM(vmulouw, 4, 2);
7103 GEN_VXFORM(vmuluwm, 4, 2);
7104 GEN_VXFORM_DUAL(vmulouw, PPC_ALTIVEC, PPC_NONE,
7105                 vmuluwm, PPC_NONE, PPC2_ALTIVEC_207)
7106 GEN_VXFORM(vmulosb, 4, 4);
7107 GEN_VXFORM(vmulosh, 4, 5);
7108 GEN_VXFORM(vmulosw, 4, 6);
7109 GEN_VXFORM(vmuleub, 4, 8);
7110 GEN_VXFORM(vmuleuh, 4, 9);
7111 GEN_VXFORM(vmuleuw, 4, 10);
7112 GEN_VXFORM(vmulesb, 4, 12);
7113 GEN_VXFORM(vmulesh, 4, 13);
7114 GEN_VXFORM(vmulesw, 4, 14);
7115 GEN_VXFORM(vslb, 2, 4);
7116 GEN_VXFORM(vslh, 2, 5);
7117 GEN_VXFORM(vslw, 2, 6);
7118 GEN_VXFORM(vsld, 2, 23);
7119 GEN_VXFORM(vsrb, 2, 8);
7120 GEN_VXFORM(vsrh, 2, 9);
7121 GEN_VXFORM(vsrw, 2, 10);
7122 GEN_VXFORM(vsrd, 2, 27);
7123 GEN_VXFORM(vsrab, 2, 12);
7124 GEN_VXFORM(vsrah, 2, 13);
7125 GEN_VXFORM(vsraw, 2, 14);
7126 GEN_VXFORM(vsrad, 2, 15);
7127 GEN_VXFORM(vslo, 6, 16);
7128 GEN_VXFORM(vsro, 6, 17);
7129 GEN_VXFORM(vaddcuw, 0, 6);
7130 GEN_VXFORM(vsubcuw, 0, 22);
7131 GEN_VXFORM_ENV(vaddubs, 0, 8);
7132 GEN_VXFORM_ENV(vadduhs, 0, 9);
7133 GEN_VXFORM_ENV(vadduws, 0, 10);
7134 GEN_VXFORM_ENV(vaddsbs, 0, 12);
7135 GEN_VXFORM_ENV(vaddshs, 0, 13);
7136 GEN_VXFORM_ENV(vaddsws, 0, 14);
7137 GEN_VXFORM_ENV(vsububs, 0, 24);
7138 GEN_VXFORM_ENV(vsubuhs, 0, 25);
7139 GEN_VXFORM_ENV(vsubuws, 0, 26);
7140 GEN_VXFORM_ENV(vsubsbs, 0, 28);
7141 GEN_VXFORM_ENV(vsubshs, 0, 29);
7142 GEN_VXFORM_ENV(vsubsws, 0, 30);
7143 GEN_VXFORM(vadduqm, 0, 4);
7144 GEN_VXFORM(vaddcuq, 0, 5);
7145 GEN_VXFORM3(vaddeuqm, 30, 0);
7146 GEN_VXFORM3(vaddecuq, 30, 0);
7147 GEN_VXFORM_DUAL(vaddeuqm, PPC_NONE, PPC2_ALTIVEC_207, \
7148             vaddecuq, PPC_NONE, PPC2_ALTIVEC_207)
7149 GEN_VXFORM(vsubuqm, 0, 20);
7150 GEN_VXFORM(vsubcuq, 0, 21);
7151 GEN_VXFORM3(vsubeuqm, 31, 0);
7152 GEN_VXFORM3(vsubecuq, 31, 0);
7153 GEN_VXFORM_DUAL(vsubeuqm, PPC_NONE, PPC2_ALTIVEC_207, \
7154             vsubecuq, PPC_NONE, PPC2_ALTIVEC_207)
7155 GEN_VXFORM(vrlb, 2, 0);
7156 GEN_VXFORM(vrlh, 2, 1);
7157 GEN_VXFORM(vrlw, 2, 2);
7158 GEN_VXFORM(vrld, 2, 3);
7159 GEN_VXFORM(vsl, 2, 7);
7160 GEN_VXFORM(vsr, 2, 11);
7161 GEN_VXFORM_ENV(vpkuhum, 7, 0);
7162 GEN_VXFORM_ENV(vpkuwum, 7, 1);
7163 GEN_VXFORM_ENV(vpkudum, 7, 17);
7164 GEN_VXFORM_ENV(vpkuhus, 7, 2);
7165 GEN_VXFORM_ENV(vpkuwus, 7, 3);
7166 GEN_VXFORM_ENV(vpkudus, 7, 19);
7167 GEN_VXFORM_ENV(vpkshus, 7, 4);
7168 GEN_VXFORM_ENV(vpkswus, 7, 5);
7169 GEN_VXFORM_ENV(vpksdus, 7, 21);
7170 GEN_VXFORM_ENV(vpkshss, 7, 6);
7171 GEN_VXFORM_ENV(vpkswss, 7, 7);
7172 GEN_VXFORM_ENV(vpksdss, 7, 23);
7173 GEN_VXFORM(vpkpx, 7, 12);
7174 GEN_VXFORM_ENV(vsum4ubs, 4, 24);
7175 GEN_VXFORM_ENV(vsum4sbs, 4, 28);
7176 GEN_VXFORM_ENV(vsum4shs, 4, 25);
7177 GEN_VXFORM_ENV(vsum2sws, 4, 26);
7178 GEN_VXFORM_ENV(vsumsws, 4, 30);
7179 GEN_VXFORM_ENV(vaddfp, 5, 0);
7180 GEN_VXFORM_ENV(vsubfp, 5, 1);
7181 GEN_VXFORM_ENV(vmaxfp, 5, 16);
7182 GEN_VXFORM_ENV(vminfp, 5, 17);
7183
7184 #define GEN_VXRFORM1(opname, name, str, opc2, opc3)                     \
7185 static void glue(gen_, name)(DisasContext *ctx)                         \
7186     {                                                                   \
7187         TCGv_ptr ra, rb, rd;                                            \
7188         if (unlikely(!ctx->altivec_enabled)) {                          \
7189             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
7190             return;                                                     \
7191         }                                                               \
7192         ra = gen_avr_ptr(rA(ctx->opcode));                              \
7193         rb = gen_avr_ptr(rB(ctx->opcode));                              \
7194         rd = gen_avr_ptr(rD(ctx->opcode));                              \
7195         gen_helper_##opname(cpu_env, rd, ra, rb);                       \
7196         tcg_temp_free_ptr(ra);                                          \
7197         tcg_temp_free_ptr(rb);                                          \
7198         tcg_temp_free_ptr(rd);                                          \
7199     }
7200
7201 #define GEN_VXRFORM(name, opc2, opc3)                                \
7202     GEN_VXRFORM1(name, name, #name, opc2, opc3)                      \
7203     GEN_VXRFORM1(name##_dot, name##_, #name ".", opc2, (opc3 | (0x1 << 4)))
7204
7205 /*
7206  * Support for Altivec instructions that use bit 31 (Rc) as an opcode
7207  * bit but also use bit 21 as an actual Rc bit.  In general, thse pairs
7208  * come from different versions of the ISA, so we must also support a
7209  * pair of flags for each instruction.
7210  */
7211 #define GEN_VXRFORM_DUAL(name0, flg0, flg2_0, name1, flg1, flg2_1)     \
7212 static void glue(gen_, name0##_##name1)(DisasContext *ctx)             \
7213 {                                                                      \
7214     if ((Rc(ctx->opcode) == 0) &&                                      \
7215         ((ctx->insns_flags & flg0) || (ctx->insns_flags2 & flg2_0))) { \
7216         if (Rc21(ctx->opcode) == 0) {                                  \
7217             gen_##name0(ctx);                                          \
7218         } else {                                                       \
7219             gen_##name0##_(ctx);                                       \
7220         }                                                              \
7221     } else if ((Rc(ctx->opcode) == 1) &&                               \
7222         ((ctx->insns_flags & flg1) || (ctx->insns_flags2 & flg2_1))) { \
7223         if (Rc21(ctx->opcode) == 0) {                                  \
7224             gen_##name1(ctx);                                          \
7225         } else {                                                       \
7226             gen_##name1##_(ctx);                                       \
7227         }                                                              \
7228     } else {                                                           \
7229         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);            \
7230     }                                                                  \
7231 }
7232
7233 GEN_VXRFORM(vcmpequb, 3, 0)
7234 GEN_VXRFORM(vcmpequh, 3, 1)
7235 GEN_VXRFORM(vcmpequw, 3, 2)
7236 GEN_VXRFORM(vcmpequd, 3, 3)
7237 GEN_VXRFORM(vcmpgtsb, 3, 12)
7238 GEN_VXRFORM(vcmpgtsh, 3, 13)
7239 GEN_VXRFORM(vcmpgtsw, 3, 14)
7240 GEN_VXRFORM(vcmpgtsd, 3, 15)
7241 GEN_VXRFORM(vcmpgtub, 3, 8)
7242 GEN_VXRFORM(vcmpgtuh, 3, 9)
7243 GEN_VXRFORM(vcmpgtuw, 3, 10)
7244 GEN_VXRFORM(vcmpgtud, 3, 11)
7245 GEN_VXRFORM(vcmpeqfp, 3, 3)
7246 GEN_VXRFORM(vcmpgefp, 3, 7)
7247 GEN_VXRFORM(vcmpgtfp, 3, 11)
7248 GEN_VXRFORM(vcmpbfp, 3, 15)
7249
7250 GEN_VXRFORM_DUAL(vcmpeqfp, PPC_ALTIVEC, PPC_NONE, \
7251                  vcmpequd, PPC_NONE, PPC2_ALTIVEC_207)
7252 GEN_VXRFORM_DUAL(vcmpbfp, PPC_ALTIVEC, PPC_NONE, \
7253                  vcmpgtsd, PPC_NONE, PPC2_ALTIVEC_207)
7254 GEN_VXRFORM_DUAL(vcmpgtfp, PPC_ALTIVEC, PPC_NONE, \
7255                  vcmpgtud, PPC_NONE, PPC2_ALTIVEC_207)
7256
7257 #define GEN_VXFORM_SIMM(name, opc2, opc3)                               \
7258 static void glue(gen_, name)(DisasContext *ctx)                         \
7259     {                                                                   \
7260         TCGv_ptr rd;                                                    \
7261         TCGv_i32 simm;                                                  \
7262         if (unlikely(!ctx->altivec_enabled)) {                          \
7263             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
7264             return;                                                     \
7265         }                                                               \
7266         simm = tcg_const_i32(SIMM5(ctx->opcode));                       \
7267         rd = gen_avr_ptr(rD(ctx->opcode));                              \
7268         gen_helper_##name (rd, simm);                                   \
7269         tcg_temp_free_i32(simm);                                        \
7270         tcg_temp_free_ptr(rd);                                          \
7271     }
7272
7273 GEN_VXFORM_SIMM(vspltisb, 6, 12);
7274 GEN_VXFORM_SIMM(vspltish, 6, 13);
7275 GEN_VXFORM_SIMM(vspltisw, 6, 14);
7276
7277 #define GEN_VXFORM_NOA(name, opc2, opc3)                                \
7278 static void glue(gen_, name)(DisasContext *ctx)                                 \
7279     {                                                                   \
7280         TCGv_ptr rb, rd;                                                \
7281         if (unlikely(!ctx->altivec_enabled)) {                          \
7282             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
7283             return;                                                     \
7284         }                                                               \
7285         rb = gen_avr_ptr(rB(ctx->opcode));                              \
7286         rd = gen_avr_ptr(rD(ctx->opcode));                              \
7287         gen_helper_##name (rd, rb);                                     \
7288         tcg_temp_free_ptr(rb);                                          \
7289         tcg_temp_free_ptr(rd);                                         \
7290     }
7291
7292 #define GEN_VXFORM_NOA_ENV(name, opc2, opc3)                            \
7293 static void glue(gen_, name)(DisasContext *ctx)                         \
7294     {                                                                   \
7295         TCGv_ptr rb, rd;                                                \
7296                                                                         \
7297         if (unlikely(!ctx->altivec_enabled)) {                          \
7298             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
7299             return;                                                     \
7300         }                                                               \
7301         rb = gen_avr_ptr(rB(ctx->opcode));                              \
7302         rd = gen_avr_ptr(rD(ctx->opcode));                              \
7303         gen_helper_##name(cpu_env, rd, rb);                             \
7304         tcg_temp_free_ptr(rb);                                          \
7305         tcg_temp_free_ptr(rd);                                          \
7306     }
7307
7308 GEN_VXFORM_NOA(vupkhsb, 7, 8);
7309 GEN_VXFORM_NOA(vupkhsh, 7, 9);
7310 GEN_VXFORM_NOA(vupkhsw, 7, 25);
7311 GEN_VXFORM_NOA(vupklsb, 7, 10);
7312 GEN_VXFORM_NOA(vupklsh, 7, 11);
7313 GEN_VXFORM_NOA(vupklsw, 7, 27);
7314 GEN_VXFORM_NOA(vupkhpx, 7, 13);
7315 GEN_VXFORM_NOA(vupklpx, 7, 15);
7316 GEN_VXFORM_NOA_ENV(vrefp, 5, 4);
7317 GEN_VXFORM_NOA_ENV(vrsqrtefp, 5, 5);
7318 GEN_VXFORM_NOA_ENV(vexptefp, 5, 6);
7319 GEN_VXFORM_NOA_ENV(vlogefp, 5, 7);
7320 GEN_VXFORM_NOA_ENV(vrfim, 5, 11);
7321 GEN_VXFORM_NOA_ENV(vrfin, 5, 8);
7322 GEN_VXFORM_NOA_ENV(vrfip, 5, 10);
7323 GEN_VXFORM_NOA_ENV(vrfiz, 5, 9);
7324
7325 #define GEN_VXFORM_SIMM(name, opc2, opc3)                               \
7326 static void glue(gen_, name)(DisasContext *ctx)                                 \
7327     {                                                                   \
7328         TCGv_ptr rd;                                                    \
7329         TCGv_i32 simm;                                                  \
7330         if (unlikely(!ctx->altivec_enabled)) {                          \
7331             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
7332             return;                                                     \
7333         }                                                               \
7334         simm = tcg_const_i32(SIMM5(ctx->opcode));                       \
7335         rd = gen_avr_ptr(rD(ctx->opcode));                              \
7336         gen_helper_##name (rd, simm);                                   \
7337         tcg_temp_free_i32(simm);                                        \
7338         tcg_temp_free_ptr(rd);                                          \
7339     }
7340
7341 #define GEN_VXFORM_UIMM(name, opc2, opc3)                               \
7342 static void glue(gen_, name)(DisasContext *ctx)                                 \
7343     {                                                                   \
7344         TCGv_ptr rb, rd;                                                \
7345         TCGv_i32 uimm;                                                  \
7346         if (unlikely(!ctx->altivec_enabled)) {                          \
7347             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
7348             return;                                                     \
7349         }                                                               \
7350         uimm = tcg_const_i32(UIMM5(ctx->opcode));                       \
7351         rb = gen_avr_ptr(rB(ctx->opcode));                              \
7352         rd = gen_avr_ptr(rD(ctx->opcode));                              \
7353         gen_helper_##name (rd, rb, uimm);                               \
7354         tcg_temp_free_i32(uimm);                                        \
7355         tcg_temp_free_ptr(rb);                                          \
7356         tcg_temp_free_ptr(rd);                                          \
7357     }
7358
7359 #define GEN_VXFORM_UIMM_ENV(name, opc2, opc3)                           \
7360 static void glue(gen_, name)(DisasContext *ctx)                         \
7361     {                                                                   \
7362         TCGv_ptr rb, rd;                                                \
7363         TCGv_i32 uimm;                                                  \
7364                                                                         \
7365         if (unlikely(!ctx->altivec_enabled)) {                          \
7366             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
7367             return;                                                     \
7368         }                                                               \
7369         uimm = tcg_const_i32(UIMM5(ctx->opcode));                       \
7370         rb = gen_avr_ptr(rB(ctx->opcode));                              \
7371         rd = gen_avr_ptr(rD(ctx->opcode));                              \
7372         gen_helper_##name(cpu_env, rd, rb, uimm);                       \
7373         tcg_temp_free_i32(uimm);                                        \
7374         tcg_temp_free_ptr(rb);                                          \
7375         tcg_temp_free_ptr(rd);                                          \
7376     }
7377
7378 GEN_VXFORM_UIMM(vspltb, 6, 8);
7379 GEN_VXFORM_UIMM(vsplth, 6, 9);
7380 GEN_VXFORM_UIMM(vspltw, 6, 10);
7381 GEN_VXFORM_UIMM_ENV(vcfux, 5, 12);
7382 GEN_VXFORM_UIMM_ENV(vcfsx, 5, 13);
7383 GEN_VXFORM_UIMM_ENV(vctuxs, 5, 14);
7384 GEN_VXFORM_UIMM_ENV(vctsxs, 5, 15);
7385
7386 static void gen_vsldoi(DisasContext *ctx)
7387 {
7388     TCGv_ptr ra, rb, rd;
7389     TCGv_i32 sh;
7390     if (unlikely(!ctx->altivec_enabled)) {
7391         gen_exception(ctx, POWERPC_EXCP_VPU);
7392         return;
7393     }
7394     ra = gen_avr_ptr(rA(ctx->opcode));
7395     rb = gen_avr_ptr(rB(ctx->opcode));
7396     rd = gen_avr_ptr(rD(ctx->opcode));
7397     sh = tcg_const_i32(VSH(ctx->opcode));
7398     gen_helper_vsldoi (rd, ra, rb, sh);
7399     tcg_temp_free_ptr(ra);
7400     tcg_temp_free_ptr(rb);
7401     tcg_temp_free_ptr(rd);
7402     tcg_temp_free_i32(sh);
7403 }
7404
7405 #define GEN_VAFORM_PAIRED(name0, name1, opc2)                           \
7406 static void glue(gen_, name0##_##name1)(DisasContext *ctx)              \
7407     {                                                                   \
7408         TCGv_ptr ra, rb, rc, rd;                                        \
7409         if (unlikely(!ctx->altivec_enabled)) {                          \
7410             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
7411             return;                                                     \
7412         }                                                               \
7413         ra = gen_avr_ptr(rA(ctx->opcode));                              \
7414         rb = gen_avr_ptr(rB(ctx->opcode));                              \
7415         rc = gen_avr_ptr(rC(ctx->opcode));                              \
7416         rd = gen_avr_ptr(rD(ctx->opcode));                              \
7417         if (Rc(ctx->opcode)) {                                          \
7418             gen_helper_##name1(cpu_env, rd, ra, rb, rc);                \
7419         } else {                                                        \
7420             gen_helper_##name0(cpu_env, rd, ra, rb, rc);                \
7421         }                                                               \
7422         tcg_temp_free_ptr(ra);                                          \
7423         tcg_temp_free_ptr(rb);                                          \
7424         tcg_temp_free_ptr(rc);                                          \
7425         tcg_temp_free_ptr(rd);                                          \
7426     }
7427
7428 GEN_VAFORM_PAIRED(vmhaddshs, vmhraddshs, 16)
7429
7430 static void gen_vmladduhm(DisasContext *ctx)
7431 {
7432     TCGv_ptr ra, rb, rc, rd;
7433     if (unlikely(!ctx->altivec_enabled)) {
7434         gen_exception(ctx, POWERPC_EXCP_VPU);
7435         return;
7436     }
7437     ra = gen_avr_ptr(rA(ctx->opcode));
7438     rb = gen_avr_ptr(rB(ctx->opcode));
7439     rc = gen_avr_ptr(rC(ctx->opcode));
7440     rd = gen_avr_ptr(rD(ctx->opcode));
7441     gen_helper_vmladduhm(rd, ra, rb, rc);
7442     tcg_temp_free_ptr(ra);
7443     tcg_temp_free_ptr(rb);
7444     tcg_temp_free_ptr(rc);
7445     tcg_temp_free_ptr(rd);
7446 }
7447
7448 GEN_VAFORM_PAIRED(vmsumubm, vmsummbm, 18)
7449 GEN_VAFORM_PAIRED(vmsumuhm, vmsumuhs, 19)
7450 GEN_VAFORM_PAIRED(vmsumshm, vmsumshs, 20)
7451 GEN_VAFORM_PAIRED(vsel, vperm, 21)
7452 GEN_VAFORM_PAIRED(vmaddfp, vnmsubfp, 23)
7453
7454 GEN_VXFORM_NOA(vclzb, 1, 28)
7455 GEN_VXFORM_NOA(vclzh, 1, 29)
7456 GEN_VXFORM_NOA(vclzw, 1, 30)
7457 GEN_VXFORM_NOA(vclzd, 1, 31)
7458 GEN_VXFORM_NOA(vpopcntb, 1, 28)
7459 GEN_VXFORM_NOA(vpopcnth, 1, 29)
7460 GEN_VXFORM_NOA(vpopcntw, 1, 30)
7461 GEN_VXFORM_NOA(vpopcntd, 1, 31)
7462 GEN_VXFORM_DUAL(vclzb, PPC_NONE, PPC2_ALTIVEC_207, \
7463                 vpopcntb, PPC_NONE, PPC2_ALTIVEC_207)
7464 GEN_VXFORM_DUAL(vclzh, PPC_NONE, PPC2_ALTIVEC_207, \
7465                 vpopcnth, PPC_NONE, PPC2_ALTIVEC_207)
7466 GEN_VXFORM_DUAL(vclzw, PPC_NONE, PPC2_ALTIVEC_207, \
7467                 vpopcntw, PPC_NONE, PPC2_ALTIVEC_207)
7468 GEN_VXFORM_DUAL(vclzd, PPC_NONE, PPC2_ALTIVEC_207, \
7469                 vpopcntd, PPC_NONE, PPC2_ALTIVEC_207)
7470 GEN_VXFORM(vbpermq, 6, 21);
7471 GEN_VXFORM_NOA(vgbbd, 6, 20);
7472 GEN_VXFORM(vpmsumb, 4, 16)
7473 GEN_VXFORM(vpmsumh, 4, 17)
7474 GEN_VXFORM(vpmsumw, 4, 18)
7475 GEN_VXFORM(vpmsumd, 4, 19)
7476
7477 #define GEN_BCD(op)                                 \
7478 static void gen_##op(DisasContext *ctx)             \
7479 {                                                   \
7480     TCGv_ptr ra, rb, rd;                            \
7481     TCGv_i32 ps;                                    \
7482                                                     \
7483     if (unlikely(!ctx->altivec_enabled)) {          \
7484         gen_exception(ctx, POWERPC_EXCP_VPU);       \
7485         return;                                     \
7486     }                                               \
7487                                                     \
7488     ra = gen_avr_ptr(rA(ctx->opcode));              \
7489     rb = gen_avr_ptr(rB(ctx->opcode));              \
7490     rd = gen_avr_ptr(rD(ctx->opcode));              \
7491                                                     \
7492     ps = tcg_const_i32((ctx->opcode & 0x200) != 0); \
7493                                                     \
7494     gen_helper_##op(cpu_crf[6], rd, ra, rb, ps);    \
7495                                                     \
7496     tcg_temp_free_ptr(ra);                          \
7497     tcg_temp_free_ptr(rb);                          \
7498     tcg_temp_free_ptr(rd);                          \
7499     tcg_temp_free_i32(ps);                          \
7500 }
7501
7502 GEN_BCD(bcdadd)
7503 GEN_BCD(bcdsub)
7504
7505 GEN_VXFORM_DUAL(vsububm, PPC_ALTIVEC, PPC_NONE, \
7506                 bcdadd, PPC_NONE, PPC2_ALTIVEC_207)
7507 GEN_VXFORM_DUAL(vsububs, PPC_ALTIVEC, PPC_NONE, \
7508                 bcdadd, PPC_NONE, PPC2_ALTIVEC_207)
7509 GEN_VXFORM_DUAL(vsubuhm, PPC_ALTIVEC, PPC_NONE, \
7510                 bcdsub, PPC_NONE, PPC2_ALTIVEC_207)
7511 GEN_VXFORM_DUAL(vsubuhs, PPC_ALTIVEC, PPC_NONE, \
7512                 bcdsub, PPC_NONE, PPC2_ALTIVEC_207)
7513
7514 static void gen_vsbox(DisasContext *ctx)
7515 {
7516     TCGv_ptr ra, rd;
7517     if (unlikely(!ctx->altivec_enabled)) {
7518         gen_exception(ctx, POWERPC_EXCP_VPU);
7519         return;
7520     }
7521     ra = gen_avr_ptr(rA(ctx->opcode));
7522     rd = gen_avr_ptr(rD(ctx->opcode));
7523     gen_helper_vsbox(rd, ra);
7524     tcg_temp_free_ptr(ra);
7525     tcg_temp_free_ptr(rd);
7526 }
7527
7528 GEN_VXFORM(vcipher, 4, 20)
7529 GEN_VXFORM(vcipherlast, 4, 20)
7530 GEN_VXFORM(vncipher, 4, 21)
7531 GEN_VXFORM(vncipherlast, 4, 21)
7532
7533 GEN_VXFORM_DUAL(vcipher, PPC_NONE, PPC2_ALTIVEC_207,
7534                 vcipherlast, PPC_NONE, PPC2_ALTIVEC_207)
7535 GEN_VXFORM_DUAL(vncipher, PPC_NONE, PPC2_ALTIVEC_207,
7536                 vncipherlast, PPC_NONE, PPC2_ALTIVEC_207)
7537
7538 #define VSHASIGMA(op)                         \
7539 static void gen_##op(DisasContext *ctx)       \
7540 {                                             \
7541     TCGv_ptr ra, rd;                          \
7542     TCGv_i32 st_six;                          \
7543     if (unlikely(!ctx->altivec_enabled)) {    \
7544         gen_exception(ctx, POWERPC_EXCP_VPU); \
7545         return;                               \
7546     }                                         \
7547     ra = gen_avr_ptr(rA(ctx->opcode));        \
7548     rd = gen_avr_ptr(rD(ctx->opcode));        \
7549     st_six = tcg_const_i32(rB(ctx->opcode));  \
7550     gen_helper_##op(rd, ra, st_six);          \
7551     tcg_temp_free_ptr(ra);                    \
7552     tcg_temp_free_ptr(rd);                    \
7553     tcg_temp_free_i32(st_six);                \
7554 }
7555
7556 VSHASIGMA(vshasigmaw)
7557 VSHASIGMA(vshasigmad)
7558
7559 GEN_VXFORM3(vpermxor, 22, 0xFF)
7560 GEN_VXFORM_DUAL(vsldoi, PPC_ALTIVEC, PPC_NONE,
7561                 vpermxor, PPC_NONE, PPC2_ALTIVEC_207)
7562
7563 /***                           VSX extension                               ***/
7564
7565 static inline TCGv_i64 cpu_vsrh(int n)
7566 {
7567     if (n < 32) {
7568         return cpu_fpr[n];
7569     } else {
7570         return cpu_avrh[n-32];
7571     }
7572 }
7573
7574 static inline TCGv_i64 cpu_vsrl(int n)
7575 {
7576     if (n < 32) {
7577         return cpu_vsr[n];
7578     } else {
7579         return cpu_avrl[n-32];
7580     }
7581 }
7582
7583 #define VSX_LOAD_SCALAR(name, operation)                      \
7584 static void gen_##name(DisasContext *ctx)                     \
7585 {                                                             \
7586     TCGv EA;                                                  \
7587     if (unlikely(!ctx->vsx_enabled)) {                        \
7588         gen_exception(ctx, POWERPC_EXCP_VSXU);                \
7589         return;                                               \
7590     }                                                         \
7591     gen_set_access_type(ctx, ACCESS_INT);                     \
7592     EA = tcg_temp_new();                                      \
7593     gen_addr_reg_index(ctx, EA);                              \
7594     gen_qemu_##operation(ctx, cpu_vsrh(xT(ctx->opcode)), EA); \
7595     /* NOTE: cpu_vsrl is undefined */                         \
7596     tcg_temp_free(EA);                                        \
7597 }
7598
7599 VSX_LOAD_SCALAR(lxsdx, ld64)
7600 VSX_LOAD_SCALAR(lxsiwax, ld32s_i64)
7601 VSX_LOAD_SCALAR(lxsiwzx, ld32u_i64)
7602 VSX_LOAD_SCALAR(lxsspx, ld32fs)
7603
7604 static void gen_lxvd2x(DisasContext *ctx)
7605 {
7606     TCGv EA;
7607     if (unlikely(!ctx->vsx_enabled)) {
7608         gen_exception(ctx, POWERPC_EXCP_VSXU);
7609         return;
7610     }
7611     gen_set_access_type(ctx, ACCESS_INT);
7612     EA = tcg_temp_new();
7613     gen_addr_reg_index(ctx, EA);
7614     gen_qemu_ld64(ctx, cpu_vsrh(xT(ctx->opcode)), EA);
7615     tcg_gen_addi_tl(EA, EA, 8);
7616     gen_qemu_ld64(ctx, cpu_vsrl(xT(ctx->opcode)), EA);
7617     tcg_temp_free(EA);
7618 }
7619
7620 static void gen_lxvdsx(DisasContext *ctx)
7621 {
7622     TCGv EA;
7623     if (unlikely(!ctx->vsx_enabled)) {
7624         gen_exception(ctx, POWERPC_EXCP_VSXU);
7625         return;
7626     }
7627     gen_set_access_type(ctx, ACCESS_INT);
7628     EA = tcg_temp_new();
7629     gen_addr_reg_index(ctx, EA);
7630     gen_qemu_ld64(ctx, cpu_vsrh(xT(ctx->opcode)), EA);
7631     tcg_gen_mov_i64(cpu_vsrl(xT(ctx->opcode)), cpu_vsrh(xT(ctx->opcode)));
7632     tcg_temp_free(EA);
7633 }
7634
7635 static void gen_lxvw4x(DisasContext *ctx)
7636 {
7637     TCGv EA;
7638     TCGv_i64 tmp;
7639     TCGv_i64 xth = cpu_vsrh(xT(ctx->opcode));
7640     TCGv_i64 xtl = cpu_vsrl(xT(ctx->opcode));
7641     if (unlikely(!ctx->vsx_enabled)) {
7642         gen_exception(ctx, POWERPC_EXCP_VSXU);
7643         return;
7644     }
7645     gen_set_access_type(ctx, ACCESS_INT);
7646     EA = tcg_temp_new();
7647     tmp = tcg_temp_new_i64();
7648
7649     gen_addr_reg_index(ctx, EA);
7650     gen_qemu_ld32u_i64(ctx, tmp, EA);
7651     tcg_gen_addi_tl(EA, EA, 4);
7652     gen_qemu_ld32u_i64(ctx, xth, EA);
7653     tcg_gen_deposit_i64(xth, xth, tmp, 32, 32);
7654
7655     tcg_gen_addi_tl(EA, EA, 4);
7656     gen_qemu_ld32u_i64(ctx, tmp, EA);
7657     tcg_gen_addi_tl(EA, EA, 4);
7658     gen_qemu_ld32u_i64(ctx, xtl, EA);
7659     tcg_gen_deposit_i64(xtl, xtl, tmp, 32, 32);
7660
7661     tcg_temp_free(EA);
7662     tcg_temp_free_i64(tmp);
7663 }
7664
7665 #define VSX_STORE_SCALAR(name, operation)                     \
7666 static void gen_##name(DisasContext *ctx)                     \
7667 {                                                             \
7668     TCGv EA;                                                  \
7669     if (unlikely(!ctx->vsx_enabled)) {                        \
7670         gen_exception(ctx, POWERPC_EXCP_VSXU);                \
7671         return;                                               \
7672     }                                                         \
7673     gen_set_access_type(ctx, ACCESS_INT);                     \
7674     EA = tcg_temp_new();                                      \
7675     gen_addr_reg_index(ctx, EA);                              \
7676     gen_qemu_##operation(ctx, cpu_vsrh(xS(ctx->opcode)), EA); \
7677     tcg_temp_free(EA);                                        \
7678 }
7679
7680 VSX_STORE_SCALAR(stxsdx, st64)
7681 VSX_STORE_SCALAR(stxsiwx, st32_i64)
7682 VSX_STORE_SCALAR(stxsspx, st32fs)
7683
7684 static void gen_stxvd2x(DisasContext *ctx)
7685 {
7686     TCGv EA;
7687     if (unlikely(!ctx->vsx_enabled)) {
7688         gen_exception(ctx, POWERPC_EXCP_VSXU);
7689         return;
7690     }
7691     gen_set_access_type(ctx, ACCESS_INT);
7692     EA = tcg_temp_new();
7693     gen_addr_reg_index(ctx, EA);
7694     gen_qemu_st64(ctx, cpu_vsrh(xS(ctx->opcode)), EA);
7695     tcg_gen_addi_tl(EA, EA, 8);
7696     gen_qemu_st64(ctx, cpu_vsrl(xS(ctx->opcode)), EA);
7697     tcg_temp_free(EA);
7698 }
7699
7700 static void gen_stxvw4x(DisasContext *ctx)
7701 {
7702     TCGv_i64 tmp;
7703     TCGv EA;
7704     if (unlikely(!ctx->vsx_enabled)) {
7705         gen_exception(ctx, POWERPC_EXCP_VSXU);
7706         return;
7707     }
7708     gen_set_access_type(ctx, ACCESS_INT);
7709     EA = tcg_temp_new();
7710     gen_addr_reg_index(ctx, EA);
7711     tmp = tcg_temp_new_i64();
7712
7713     tcg_gen_shri_i64(tmp, cpu_vsrh(xS(ctx->opcode)), 32);
7714     gen_qemu_st32_i64(ctx, tmp, EA);
7715     tcg_gen_addi_tl(EA, EA, 4);
7716     gen_qemu_st32_i64(ctx, cpu_vsrh(xS(ctx->opcode)), EA);
7717
7718     tcg_gen_shri_i64(tmp, cpu_vsrl(xS(ctx->opcode)), 32);
7719     tcg_gen_addi_tl(EA, EA, 4);
7720     gen_qemu_st32_i64(ctx, tmp, EA);
7721     tcg_gen_addi_tl(EA, EA, 4);
7722     gen_qemu_st32_i64(ctx, cpu_vsrl(xS(ctx->opcode)), EA);
7723
7724     tcg_temp_free(EA);
7725     tcg_temp_free_i64(tmp);
7726 }
7727
7728 #define MV_VSRW(name, tcgop1, tcgop2, target, source)           \
7729 static void gen_##name(DisasContext *ctx)                       \
7730 {                                                               \
7731     if (xS(ctx->opcode) < 32) {                                 \
7732         if (unlikely(!ctx->fpu_enabled)) {                      \
7733             gen_exception(ctx, POWERPC_EXCP_FPU);               \
7734             return;                                             \
7735         }                                                       \
7736     } else {                                                    \
7737         if (unlikely(!ctx->altivec_enabled)) {                  \
7738             gen_exception(ctx, POWERPC_EXCP_VPU);               \
7739             return;                                             \
7740         }                                                       \
7741     }                                                           \
7742     TCGv_i64 tmp = tcg_temp_new_i64();                          \
7743     tcg_gen_##tcgop1(tmp, source);                              \
7744     tcg_gen_##tcgop2(target, tmp);                              \
7745     tcg_temp_free_i64(tmp);                                     \
7746 }
7747
7748
7749 MV_VSRW(mfvsrwz, ext32u_i64, trunc_i64_tl, cpu_gpr[rA(ctx->opcode)], \
7750         cpu_vsrh(xS(ctx->opcode)))
7751 MV_VSRW(mtvsrwa, extu_tl_i64, ext32s_i64, cpu_vsrh(xT(ctx->opcode)), \
7752         cpu_gpr[rA(ctx->opcode)])
7753 MV_VSRW(mtvsrwz, extu_tl_i64, ext32u_i64, cpu_vsrh(xT(ctx->opcode)), \
7754         cpu_gpr[rA(ctx->opcode)])
7755
7756 #if defined(TARGET_PPC64)
7757 #define MV_VSRD(name, target, source)                           \
7758 static void gen_##name(DisasContext *ctx)                       \
7759 {                                                               \
7760     if (xS(ctx->opcode) < 32) {                                 \
7761         if (unlikely(!ctx->fpu_enabled)) {                      \
7762             gen_exception(ctx, POWERPC_EXCP_FPU);               \
7763             return;                                             \
7764         }                                                       \
7765     } else {                                                    \
7766         if (unlikely(!ctx->altivec_enabled)) {                  \
7767             gen_exception(ctx, POWERPC_EXCP_VPU);               \
7768             return;                                             \
7769         }                                                       \
7770     }                                                           \
7771     tcg_gen_mov_i64(target, source);                            \
7772 }
7773
7774 MV_VSRD(mfvsrd, cpu_gpr[rA(ctx->opcode)], cpu_vsrh(xS(ctx->opcode)))
7775 MV_VSRD(mtvsrd, cpu_vsrh(xT(ctx->opcode)), cpu_gpr[rA(ctx->opcode)])
7776
7777 #endif
7778
7779 static void gen_xxpermdi(DisasContext *ctx)
7780 {
7781     if (unlikely(!ctx->vsx_enabled)) {
7782         gen_exception(ctx, POWERPC_EXCP_VSXU);
7783         return;
7784     }
7785
7786     if (unlikely((xT(ctx->opcode) == xA(ctx->opcode)) ||
7787                  (xT(ctx->opcode) == xB(ctx->opcode)))) {
7788         TCGv_i64 xh, xl;
7789
7790         xh = tcg_temp_new_i64();
7791         xl = tcg_temp_new_i64();
7792
7793         if ((DM(ctx->opcode) & 2) == 0) {
7794             tcg_gen_mov_i64(xh, cpu_vsrh(xA(ctx->opcode)));
7795         } else {
7796             tcg_gen_mov_i64(xh, cpu_vsrl(xA(ctx->opcode)));
7797         }
7798         if ((DM(ctx->opcode) & 1) == 0) {
7799             tcg_gen_mov_i64(xl, cpu_vsrh(xB(ctx->opcode)));
7800         } else {
7801             tcg_gen_mov_i64(xl, cpu_vsrl(xB(ctx->opcode)));
7802         }
7803
7804         tcg_gen_mov_i64(cpu_vsrh(xT(ctx->opcode)), xh);
7805         tcg_gen_mov_i64(cpu_vsrl(xT(ctx->opcode)), xl);
7806
7807         tcg_temp_free_i64(xh);
7808         tcg_temp_free_i64(xl);
7809     } else {
7810         if ((DM(ctx->opcode) & 2) == 0) {
7811             tcg_gen_mov_i64(cpu_vsrh(xT(ctx->opcode)), cpu_vsrh(xA(ctx->opcode)));
7812         } else {
7813             tcg_gen_mov_i64(cpu_vsrh(xT(ctx->opcode)), cpu_vsrl(xA(ctx->opcode)));
7814         }
7815         if ((DM(ctx->opcode) & 1) == 0) {
7816             tcg_gen_mov_i64(cpu_vsrl(xT(ctx->opcode)), cpu_vsrh(xB(ctx->opcode)));
7817         } else {
7818             tcg_gen_mov_i64(cpu_vsrl(xT(ctx->opcode)), cpu_vsrl(xB(ctx->opcode)));
7819         }
7820     }
7821 }
7822
7823 #define OP_ABS 1
7824 #define OP_NABS 2
7825 #define OP_NEG 3
7826 #define OP_CPSGN 4
7827 #define SGN_MASK_DP  0x8000000000000000ull
7828 #define SGN_MASK_SP 0x8000000080000000ull
7829
7830 #define VSX_SCALAR_MOVE(name, op, sgn_mask)                       \
7831 static void glue(gen_, name)(DisasContext * ctx)                  \
7832     {                                                             \
7833         TCGv_i64 xb, sgm;                                         \
7834         if (unlikely(!ctx->vsx_enabled)) {                        \
7835             gen_exception(ctx, POWERPC_EXCP_VSXU);                \
7836             return;                                               \
7837         }                                                         \
7838         xb = tcg_temp_new_i64();                                  \
7839         sgm = tcg_temp_new_i64();                                 \
7840         tcg_gen_mov_i64(xb, cpu_vsrh(xB(ctx->opcode)));           \
7841         tcg_gen_movi_i64(sgm, sgn_mask);                          \
7842         switch (op) {                                             \
7843             case OP_ABS: {                                        \
7844                 tcg_gen_andc_i64(xb, xb, sgm);                    \
7845                 break;                                            \
7846             }                                                     \
7847             case OP_NABS: {                                       \
7848                 tcg_gen_or_i64(xb, xb, sgm);                      \
7849                 break;                                            \
7850             }                                                     \
7851             case OP_NEG: {                                        \
7852                 tcg_gen_xor_i64(xb, xb, sgm);                     \
7853                 break;                                            \
7854             }                                                     \
7855             case OP_CPSGN: {                                      \
7856                 TCGv_i64 xa = tcg_temp_new_i64();                 \
7857                 tcg_gen_mov_i64(xa, cpu_vsrh(xA(ctx->opcode)));   \
7858                 tcg_gen_and_i64(xa, xa, sgm);                     \
7859                 tcg_gen_andc_i64(xb, xb, sgm);                    \
7860                 tcg_gen_or_i64(xb, xb, xa);                       \
7861                 tcg_temp_free_i64(xa);                            \
7862                 break;                                            \
7863             }                                                     \
7864         }                                                         \
7865         tcg_gen_mov_i64(cpu_vsrh(xT(ctx->opcode)), xb);           \
7866         tcg_temp_free_i64(xb);                                    \
7867         tcg_temp_free_i64(sgm);                                   \
7868     }
7869
7870 VSX_SCALAR_MOVE(xsabsdp, OP_ABS, SGN_MASK_DP)
7871 VSX_SCALAR_MOVE(xsnabsdp, OP_NABS, SGN_MASK_DP)
7872 VSX_SCALAR_MOVE(xsnegdp, OP_NEG, SGN_MASK_DP)
7873 VSX_SCALAR_MOVE(xscpsgndp, OP_CPSGN, SGN_MASK_DP)
7874
7875 #define VSX_VECTOR_MOVE(name, op, sgn_mask)                      \
7876 static void glue(gen_, name)(DisasContext * ctx)                 \
7877     {                                                            \
7878         TCGv_i64 xbh, xbl, sgm;                                  \
7879         if (unlikely(!ctx->vsx_enabled)) {                       \
7880             gen_exception(ctx, POWERPC_EXCP_VSXU);               \
7881             return;                                              \
7882         }                                                        \
7883         xbh = tcg_temp_new_i64();                                \
7884         xbl = tcg_temp_new_i64();                                \
7885         sgm = tcg_temp_new_i64();                                \
7886         tcg_gen_mov_i64(xbh, cpu_vsrh(xB(ctx->opcode)));         \
7887         tcg_gen_mov_i64(xbl, cpu_vsrl(xB(ctx->opcode)));         \
7888         tcg_gen_movi_i64(sgm, sgn_mask);                         \
7889         switch (op) {                                            \
7890             case OP_ABS: {                                       \
7891                 tcg_gen_andc_i64(xbh, xbh, sgm);                 \
7892                 tcg_gen_andc_i64(xbl, xbl, sgm);                 \
7893                 break;                                           \
7894             }                                                    \
7895             case OP_NABS: {                                      \
7896                 tcg_gen_or_i64(xbh, xbh, sgm);                   \
7897                 tcg_gen_or_i64(xbl, xbl, sgm);                   \
7898                 break;                                           \
7899             }                                                    \
7900             case OP_NEG: {                                       \
7901                 tcg_gen_xor_i64(xbh, xbh, sgm);                  \
7902                 tcg_gen_xor_i64(xbl, xbl, sgm);                  \
7903                 break;                                           \
7904             }                                                    \
7905             case OP_CPSGN: {                                     \
7906                 TCGv_i64 xah = tcg_temp_new_i64();               \
7907                 TCGv_i64 xal = tcg_temp_new_i64();               \
7908                 tcg_gen_mov_i64(xah, cpu_vsrh(xA(ctx->opcode))); \
7909                 tcg_gen_mov_i64(xal, cpu_vsrl(xA(ctx->opcode))); \
7910                 tcg_gen_and_i64(xah, xah, sgm);                  \
7911                 tcg_gen_and_i64(xal, xal, sgm);                  \
7912                 tcg_gen_andc_i64(xbh, xbh, sgm);                 \
7913                 tcg_gen_andc_i64(xbl, xbl, sgm);                 \
7914                 tcg_gen_or_i64(xbh, xbh, xah);                   \
7915                 tcg_gen_or_i64(xbl, xbl, xal);                   \
7916                 tcg_temp_free_i64(xah);                          \
7917                 tcg_temp_free_i64(xal);                          \
7918                 break;                                           \
7919             }                                                    \
7920         }                                                        \
7921         tcg_gen_mov_i64(cpu_vsrh(xT(ctx->opcode)), xbh);         \
7922         tcg_gen_mov_i64(cpu_vsrl(xT(ctx->opcode)), xbl);         \
7923         tcg_temp_free_i64(xbh);                                  \
7924         tcg_temp_free_i64(xbl);                                  \
7925         tcg_temp_free_i64(sgm);                                  \
7926     }
7927
7928 VSX_VECTOR_MOVE(xvabsdp, OP_ABS, SGN_MASK_DP)
7929 VSX_VECTOR_MOVE(xvnabsdp, OP_NABS, SGN_MASK_DP)
7930 VSX_VECTOR_MOVE(xvnegdp, OP_NEG, SGN_MASK_DP)
7931 VSX_VECTOR_MOVE(xvcpsgndp, OP_CPSGN, SGN_MASK_DP)
7932 VSX_VECTOR_MOVE(xvabssp, OP_ABS, SGN_MASK_SP)
7933 VSX_VECTOR_MOVE(xvnabssp, OP_NABS, SGN_MASK_SP)
7934 VSX_VECTOR_MOVE(xvnegsp, OP_NEG, SGN_MASK_SP)
7935 VSX_VECTOR_MOVE(xvcpsgnsp, OP_CPSGN, SGN_MASK_SP)
7936
7937 #define GEN_VSX_HELPER_2(name, op1, op2, inval, type)                         \
7938 static void gen_##name(DisasContext * ctx)                                    \
7939 {                                                                             \
7940     TCGv_i32 opc;                                                             \
7941     if (unlikely(!ctx->vsx_enabled)) {                                        \
7942         gen_exception(ctx, POWERPC_EXCP_VSXU);                                \
7943         return;                                                               \
7944     }                                                                         \
7945     /* NIP cannot be restored if the memory exception comes from an helper */ \
7946     gen_update_nip(ctx, ctx->nip - 4);                                        \
7947     opc = tcg_const_i32(ctx->opcode);                                         \
7948     gen_helper_##name(cpu_env, opc);                                          \
7949     tcg_temp_free_i32(opc);                                                   \
7950 }
7951
7952 #define GEN_VSX_HELPER_XT_XB_ENV(name, op1, op2, inval, type) \
7953 static void gen_##name(DisasContext * ctx)                    \
7954 {                                                             \
7955     if (unlikely(!ctx->vsx_enabled)) {                        \
7956         gen_exception(ctx, POWERPC_EXCP_VSXU);                \
7957         return;                                               \
7958     }                                                         \
7959     /* NIP cannot be restored if the exception comes */       \
7960     /* from a helper. */                                      \
7961     gen_update_nip(ctx, ctx->nip - 4);                        \
7962                                                               \
7963     gen_helper_##name(cpu_vsrh(xT(ctx->opcode)), cpu_env,     \
7964                       cpu_vsrh(xB(ctx->opcode)));             \
7965 }
7966
7967 GEN_VSX_HELPER_2(xsadddp, 0x00, 0x04, 0, PPC2_VSX)
7968 GEN_VSX_HELPER_2(xssubdp, 0x00, 0x05, 0, PPC2_VSX)
7969 GEN_VSX_HELPER_2(xsmuldp, 0x00, 0x06, 0, PPC2_VSX)
7970 GEN_VSX_HELPER_2(xsdivdp, 0x00, 0x07, 0, PPC2_VSX)
7971 GEN_VSX_HELPER_2(xsredp, 0x14, 0x05, 0, PPC2_VSX)
7972 GEN_VSX_HELPER_2(xssqrtdp, 0x16, 0x04, 0, PPC2_VSX)
7973 GEN_VSX_HELPER_2(xsrsqrtedp, 0x14, 0x04, 0, PPC2_VSX)
7974 GEN_VSX_HELPER_2(xstdivdp, 0x14, 0x07, 0, PPC2_VSX)
7975 GEN_VSX_HELPER_2(xstsqrtdp, 0x14, 0x06, 0, PPC2_VSX)
7976 GEN_VSX_HELPER_2(xsmaddadp, 0x04, 0x04, 0, PPC2_VSX)
7977 GEN_VSX_HELPER_2(xsmaddmdp, 0x04, 0x05, 0, PPC2_VSX)
7978 GEN_VSX_HELPER_2(xsmsubadp, 0x04, 0x06, 0, PPC2_VSX)
7979 GEN_VSX_HELPER_2(xsmsubmdp, 0x04, 0x07, 0, PPC2_VSX)
7980 GEN_VSX_HELPER_2(xsnmaddadp, 0x04, 0x14, 0, PPC2_VSX)
7981 GEN_VSX_HELPER_2(xsnmaddmdp, 0x04, 0x15, 0, PPC2_VSX)
7982 GEN_VSX_HELPER_2(xsnmsubadp, 0x04, 0x16, 0, PPC2_VSX)
7983 GEN_VSX_HELPER_2(xsnmsubmdp, 0x04, 0x17, 0, PPC2_VSX)
7984 GEN_VSX_HELPER_2(xscmpodp, 0x0C, 0x05, 0, PPC2_VSX)
7985 GEN_VSX_HELPER_2(xscmpudp, 0x0C, 0x04, 0, PPC2_VSX)
7986 GEN_VSX_HELPER_2(xsmaxdp, 0x00, 0x14, 0, PPC2_VSX)
7987 GEN_VSX_HELPER_2(xsmindp, 0x00, 0x15, 0, PPC2_VSX)
7988 GEN_VSX_HELPER_2(xscvdpsp, 0x12, 0x10, 0, PPC2_VSX)
7989 GEN_VSX_HELPER_XT_XB_ENV(xscvdpspn, 0x16, 0x10, 0, PPC2_VSX207)
7990 GEN_VSX_HELPER_2(xscvspdp, 0x12, 0x14, 0, PPC2_VSX)
7991 GEN_VSX_HELPER_XT_XB_ENV(xscvspdpn, 0x16, 0x14, 0, PPC2_VSX207)
7992 GEN_VSX_HELPER_2(xscvdpsxds, 0x10, 0x15, 0, PPC2_VSX)
7993 GEN_VSX_HELPER_2(xscvdpsxws, 0x10, 0x05, 0, PPC2_VSX)
7994 GEN_VSX_HELPER_2(xscvdpuxds, 0x10, 0x14, 0, PPC2_VSX)
7995 GEN_VSX_HELPER_2(xscvdpuxws, 0x10, 0x04, 0, PPC2_VSX)
7996 GEN_VSX_HELPER_2(xscvsxddp, 0x10, 0x17, 0, PPC2_VSX)
7997 GEN_VSX_HELPER_2(xscvuxddp, 0x10, 0x16, 0, PPC2_VSX)
7998 GEN_VSX_HELPER_2(xsrdpi, 0x12, 0x04, 0, PPC2_VSX)
7999 GEN_VSX_HELPER_2(xsrdpic, 0x16, 0x06, 0, PPC2_VSX)
8000 GEN_VSX_HELPER_2(xsrdpim, 0x12, 0x07, 0, PPC2_VSX)
8001 GEN_VSX_HELPER_2(xsrdpip, 0x12, 0x06, 0, PPC2_VSX)
8002 GEN_VSX_HELPER_2(xsrdpiz, 0x12, 0x05, 0, PPC2_VSX)
8003 GEN_VSX_HELPER_XT_XB_ENV(xsrsp, 0x12, 0x11, 0, PPC2_VSX207)
8004
8005 GEN_VSX_HELPER_2(xsaddsp, 0x00, 0x00, 0, PPC2_VSX207)
8006 GEN_VSX_HELPER_2(xssubsp, 0x00, 0x01, 0, PPC2_VSX207)
8007 GEN_VSX_HELPER_2(xsmulsp, 0x00, 0x02, 0, PPC2_VSX207)
8008 GEN_VSX_HELPER_2(xsdivsp, 0x00, 0x03, 0, PPC2_VSX207)
8009 GEN_VSX_HELPER_2(xsresp, 0x14, 0x01, 0, PPC2_VSX207)
8010 GEN_VSX_HELPER_2(xssqrtsp, 0x16, 0x00, 0, PPC2_VSX207)
8011 GEN_VSX_HELPER_2(xsrsqrtesp, 0x14, 0x00, 0, PPC2_VSX207)
8012 GEN_VSX_HELPER_2(xsmaddasp, 0x04, 0x00, 0, PPC2_VSX207)
8013 GEN_VSX_HELPER_2(xsmaddmsp, 0x04, 0x01, 0, PPC2_VSX207)
8014 GEN_VSX_HELPER_2(xsmsubasp, 0x04, 0x02, 0, PPC2_VSX207)
8015 GEN_VSX_HELPER_2(xsmsubmsp, 0x04, 0x03, 0, PPC2_VSX207)
8016 GEN_VSX_HELPER_2(xsnmaddasp, 0x04, 0x10, 0, PPC2_VSX207)
8017 GEN_VSX_HELPER_2(xsnmaddmsp, 0x04, 0x11, 0, PPC2_VSX207)
8018 GEN_VSX_HELPER_2(xsnmsubasp, 0x04, 0x12, 0, PPC2_VSX207)
8019 GEN_VSX_HELPER_2(xsnmsubmsp, 0x04, 0x13, 0, PPC2_VSX207)
8020 GEN_VSX_HELPER_2(xscvsxdsp, 0x10, 0x13, 0, PPC2_VSX207)
8021 GEN_VSX_HELPER_2(xscvuxdsp, 0x10, 0x12, 0, PPC2_VSX207)
8022
8023 GEN_VSX_HELPER_2(xvadddp, 0x00, 0x0C, 0, PPC2_VSX)
8024 GEN_VSX_HELPER_2(xvsubdp, 0x00, 0x0D, 0, PPC2_VSX)
8025 GEN_VSX_HELPER_2(xvmuldp, 0x00, 0x0E, 0, PPC2_VSX)
8026 GEN_VSX_HELPER_2(xvdivdp, 0x00, 0x0F, 0, PPC2_VSX)
8027 GEN_VSX_HELPER_2(xvredp, 0x14, 0x0D, 0, PPC2_VSX)
8028 GEN_VSX_HELPER_2(xvsqrtdp, 0x16, 0x0C, 0, PPC2_VSX)
8029 GEN_VSX_HELPER_2(xvrsqrtedp, 0x14, 0x0C, 0, PPC2_VSX)
8030 GEN_VSX_HELPER_2(xvtdivdp, 0x14, 0x0F, 0, PPC2_VSX)
8031 GEN_VSX_HELPER_2(xvtsqrtdp, 0x14, 0x0E, 0, PPC2_VSX)
8032 GEN_VSX_HELPER_2(xvmaddadp, 0x04, 0x0C, 0, PPC2_VSX)
8033 GEN_VSX_HELPER_2(xvmaddmdp, 0x04, 0x0D, 0, PPC2_VSX)
8034 GEN_VSX_HELPER_2(xvmsubadp, 0x04, 0x0E, 0, PPC2_VSX)
8035 GEN_VSX_HELPER_2(xvmsubmdp, 0x04, 0x0F, 0, PPC2_VSX)
8036 GEN_VSX_HELPER_2(xvnmaddadp, 0x04, 0x1C, 0, PPC2_VSX)
8037 GEN_VSX_HELPER_2(xvnmaddmdp, 0x04, 0x1D, 0, PPC2_VSX)
8038 GEN_VSX_HELPER_2(xvnmsubadp, 0x04, 0x1E, 0, PPC2_VSX)
8039 GEN_VSX_HELPER_2(xvnmsubmdp, 0x04, 0x1F, 0, PPC2_VSX)
8040 GEN_VSX_HELPER_2(xvmaxdp, 0x00, 0x1C, 0, PPC2_VSX)
8041 GEN_VSX_HELPER_2(xvmindp, 0x00, 0x1D, 0, PPC2_VSX)
8042 GEN_VSX_HELPER_2(xvcmpeqdp, 0x0C, 0x0C, 0, PPC2_VSX)
8043 GEN_VSX_HELPER_2(xvcmpgtdp, 0x0C, 0x0D, 0, PPC2_VSX)
8044 GEN_VSX_HELPER_2(xvcmpgedp, 0x0C, 0x0E, 0, PPC2_VSX)
8045 GEN_VSX_HELPER_2(xvcvdpsp, 0x12, 0x18, 0, PPC2_VSX)
8046 GEN_VSX_HELPER_2(xvcvdpsxds, 0x10, 0x1D, 0, PPC2_VSX)
8047 GEN_VSX_HELPER_2(xvcvdpsxws, 0x10, 0x0D, 0, PPC2_VSX)
8048 GEN_VSX_HELPER_2(xvcvdpuxds, 0x10, 0x1C, 0, PPC2_VSX)
8049 GEN_VSX_HELPER_2(xvcvdpuxws, 0x10, 0x0C, 0, PPC2_VSX)
8050 GEN_VSX_HELPER_2(xvcvsxddp, 0x10, 0x1F, 0, PPC2_VSX)
8051 GEN_VSX_HELPER_2(xvcvuxddp, 0x10, 0x1E, 0, PPC2_VSX)
8052 GEN_VSX_HELPER_2(xvcvsxwdp, 0x10, 0x0F, 0, PPC2_VSX)
8053 GEN_VSX_HELPER_2(xvcvuxwdp, 0x10, 0x0E, 0, PPC2_VSX)
8054 GEN_VSX_HELPER_2(xvrdpi, 0x12, 0x0C, 0, PPC2_VSX)
8055 GEN_VSX_HELPER_2(xvrdpic, 0x16, 0x0E, 0, PPC2_VSX)
8056 GEN_VSX_HELPER_2(xvrdpim, 0x12, 0x0F, 0, PPC2_VSX)
8057 GEN_VSX_HELPER_2(xvrdpip, 0x12, 0x0E, 0, PPC2_VSX)
8058 GEN_VSX_HELPER_2(xvrdpiz, 0x12, 0x0D, 0, PPC2_VSX)
8059
8060 GEN_VSX_HELPER_2(xvaddsp, 0x00, 0x08, 0, PPC2_VSX)
8061 GEN_VSX_HELPER_2(xvsubsp, 0x00, 0x09, 0, PPC2_VSX)
8062 GEN_VSX_HELPER_2(xvmulsp, 0x00, 0x0A, 0, PPC2_VSX)
8063 GEN_VSX_HELPER_2(xvdivsp, 0x00, 0x0B, 0, PPC2_VSX)
8064 GEN_VSX_HELPER_2(xvresp, 0x14, 0x09, 0, PPC2_VSX)
8065 GEN_VSX_HELPER_2(xvsqrtsp, 0x16, 0x08, 0, PPC2_VSX)
8066 GEN_VSX_HELPER_2(xvrsqrtesp, 0x14, 0x08, 0, PPC2_VSX)
8067 GEN_VSX_HELPER_2(xvtdivsp, 0x14, 0x0B, 0, PPC2_VSX)
8068 GEN_VSX_HELPER_2(xvtsqrtsp, 0x14, 0x0A, 0, PPC2_VSX)
8069 GEN_VSX_HELPER_2(xvmaddasp, 0x04, 0x08, 0, PPC2_VSX)
8070 GEN_VSX_HELPER_2(xvmaddmsp, 0x04, 0x09, 0, PPC2_VSX)
8071 GEN_VSX_HELPER_2(xvmsubasp, 0x04, 0x0A, 0, PPC2_VSX)
8072 GEN_VSX_HELPER_2(xvmsubmsp, 0x04, 0x0B, 0, PPC2_VSX)
8073 GEN_VSX_HELPER_2(xvnmaddasp, 0x04, 0x18, 0, PPC2_VSX)
8074 GEN_VSX_HELPER_2(xvnmaddmsp, 0x04, 0x19, 0, PPC2_VSX)
8075 GEN_VSX_HELPER_2(xvnmsubasp, 0x04, 0x1A, 0, PPC2_VSX)
8076 GEN_VSX_HELPER_2(xvnmsubmsp, 0x04, 0x1B, 0, PPC2_VSX)
8077 GEN_VSX_HELPER_2(xvmaxsp, 0x00, 0x18, 0, PPC2_VSX)
8078 GEN_VSX_HELPER_2(xvminsp, 0x00, 0x19, 0, PPC2_VSX)
8079 GEN_VSX_HELPER_2(xvcmpeqsp, 0x0C, 0x08, 0, PPC2_VSX)
8080 GEN_VSX_HELPER_2(xvcmpgtsp, 0x0C, 0x09, 0, PPC2_VSX)
8081 GEN_VSX_HELPER_2(xvcmpgesp, 0x0C, 0x0A, 0, PPC2_VSX)
8082 GEN_VSX_HELPER_2(xvcvspdp, 0x12, 0x1C, 0, PPC2_VSX)
8083 GEN_VSX_HELPER_2(xvcvspsxds, 0x10, 0x19, 0, PPC2_VSX)
8084 GEN_VSX_HELPER_2(xvcvspsxws, 0x10, 0x09, 0, PPC2_VSX)
8085 GEN_VSX_HELPER_2(xvcvspuxds, 0x10, 0x18, 0, PPC2_VSX)
8086 GEN_VSX_HELPER_2(xvcvspuxws, 0x10, 0x08, 0, PPC2_VSX)
8087 GEN_VSX_HELPER_2(xvcvsxdsp, 0x10, 0x1B, 0, PPC2_VSX)
8088 GEN_VSX_HELPER_2(xvcvuxdsp, 0x10, 0x1A, 0, PPC2_VSX)
8089 GEN_VSX_HELPER_2(xvcvsxwsp, 0x10, 0x0B, 0, PPC2_VSX)
8090 GEN_VSX_HELPER_2(xvcvuxwsp, 0x10, 0x0A, 0, PPC2_VSX)
8091 GEN_VSX_HELPER_2(xvrspi, 0x12, 0x08, 0, PPC2_VSX)
8092 GEN_VSX_HELPER_2(xvrspic, 0x16, 0x0A, 0, PPC2_VSX)
8093 GEN_VSX_HELPER_2(xvrspim, 0x12, 0x0B, 0, PPC2_VSX)
8094 GEN_VSX_HELPER_2(xvrspip, 0x12, 0x0A, 0, PPC2_VSX)
8095 GEN_VSX_HELPER_2(xvrspiz, 0x12, 0x09, 0, PPC2_VSX)
8096
8097 #define VSX_LOGICAL(name, tcg_op)                                    \
8098 static void glue(gen_, name)(DisasContext * ctx)                     \
8099     {                                                                \
8100         if (unlikely(!ctx->vsx_enabled)) {                           \
8101             gen_exception(ctx, POWERPC_EXCP_VSXU);                   \
8102             return;                                                  \
8103         }                                                            \
8104         tcg_op(cpu_vsrh(xT(ctx->opcode)), cpu_vsrh(xA(ctx->opcode)), \
8105             cpu_vsrh(xB(ctx->opcode)));                              \
8106         tcg_op(cpu_vsrl(xT(ctx->opcode)), cpu_vsrl(xA(ctx->opcode)), \
8107             cpu_vsrl(xB(ctx->opcode)));                              \
8108     }
8109
8110 VSX_LOGICAL(xxland, tcg_gen_and_i64)
8111 VSX_LOGICAL(xxlandc, tcg_gen_andc_i64)
8112 VSX_LOGICAL(xxlor, tcg_gen_or_i64)
8113 VSX_LOGICAL(xxlxor, tcg_gen_xor_i64)
8114 VSX_LOGICAL(xxlnor, tcg_gen_nor_i64)
8115 VSX_LOGICAL(xxleqv, tcg_gen_eqv_i64)
8116 VSX_LOGICAL(xxlnand, tcg_gen_nand_i64)
8117 VSX_LOGICAL(xxlorc, tcg_gen_orc_i64)
8118
8119 #define VSX_XXMRG(name, high)                               \
8120 static void glue(gen_, name)(DisasContext * ctx)            \
8121     {                                                       \
8122         TCGv_i64 a0, a1, b0, b1;                            \
8123         if (unlikely(!ctx->vsx_enabled)) {                  \
8124             gen_exception(ctx, POWERPC_EXCP_VSXU);          \
8125             return;                                         \
8126         }                                                   \
8127         a0 = tcg_temp_new_i64();                            \
8128         a1 = tcg_temp_new_i64();                            \
8129         b0 = tcg_temp_new_i64();                            \
8130         b1 = tcg_temp_new_i64();                            \
8131         if (high) {                                         \
8132             tcg_gen_mov_i64(a0, cpu_vsrh(xA(ctx->opcode))); \
8133             tcg_gen_mov_i64(a1, cpu_vsrh(xA(ctx->opcode))); \
8134             tcg_gen_mov_i64(b0, cpu_vsrh(xB(ctx->opcode))); \
8135             tcg_gen_mov_i64(b1, cpu_vsrh(xB(ctx->opcode))); \
8136         } else {                                            \
8137             tcg_gen_mov_i64(a0, cpu_vsrl(xA(ctx->opcode))); \
8138             tcg_gen_mov_i64(a1, cpu_vsrl(xA(ctx->opcode))); \
8139             tcg_gen_mov_i64(b0, cpu_vsrl(xB(ctx->opcode))); \
8140             tcg_gen_mov_i64(b1, cpu_vsrl(xB(ctx->opcode))); \
8141         }                                                   \
8142         tcg_gen_shri_i64(a0, a0, 32);                       \
8143         tcg_gen_shri_i64(b0, b0, 32);                       \
8144         tcg_gen_deposit_i64(cpu_vsrh(xT(ctx->opcode)),      \
8145                             b0, a0, 32, 32);                \
8146         tcg_gen_deposit_i64(cpu_vsrl(xT(ctx->opcode)),      \
8147                             b1, a1, 32, 32);                \
8148         tcg_temp_free_i64(a0);                              \
8149         tcg_temp_free_i64(a1);                              \
8150         tcg_temp_free_i64(b0);                              \
8151         tcg_temp_free_i64(b1);                              \
8152     }
8153
8154 VSX_XXMRG(xxmrghw, 1)
8155 VSX_XXMRG(xxmrglw, 0)
8156
8157 static void gen_xxsel(DisasContext * ctx)
8158 {
8159     TCGv_i64 a, b, c;
8160     if (unlikely(!ctx->vsx_enabled)) {
8161         gen_exception(ctx, POWERPC_EXCP_VSXU);
8162         return;
8163     }
8164     a = tcg_temp_new_i64();
8165     b = tcg_temp_new_i64();
8166     c = tcg_temp_new_i64();
8167
8168     tcg_gen_mov_i64(a, cpu_vsrh(xA(ctx->opcode)));
8169     tcg_gen_mov_i64(b, cpu_vsrh(xB(ctx->opcode)));
8170     tcg_gen_mov_i64(c, cpu_vsrh(xC(ctx->opcode)));
8171
8172     tcg_gen_and_i64(b, b, c);
8173     tcg_gen_andc_i64(a, a, c);
8174     tcg_gen_or_i64(cpu_vsrh(xT(ctx->opcode)), a, b);
8175
8176     tcg_gen_mov_i64(a, cpu_vsrl(xA(ctx->opcode)));
8177     tcg_gen_mov_i64(b, cpu_vsrl(xB(ctx->opcode)));
8178     tcg_gen_mov_i64(c, cpu_vsrl(xC(ctx->opcode)));
8179
8180     tcg_gen_and_i64(b, b, c);
8181     tcg_gen_andc_i64(a, a, c);
8182     tcg_gen_or_i64(cpu_vsrl(xT(ctx->opcode)), a, b);
8183
8184     tcg_temp_free_i64(a);
8185     tcg_temp_free_i64(b);
8186     tcg_temp_free_i64(c);
8187 }
8188
8189 static void gen_xxspltw(DisasContext *ctx)
8190 {
8191     TCGv_i64 b, b2;
8192     TCGv_i64 vsr = (UIM(ctx->opcode) & 2) ?
8193                    cpu_vsrl(xB(ctx->opcode)) :
8194                    cpu_vsrh(xB(ctx->opcode));
8195
8196     if (unlikely(!ctx->vsx_enabled)) {
8197         gen_exception(ctx, POWERPC_EXCP_VSXU);
8198         return;
8199     }
8200
8201     b = tcg_temp_new_i64();
8202     b2 = tcg_temp_new_i64();
8203
8204     if (UIM(ctx->opcode) & 1) {
8205         tcg_gen_ext32u_i64(b, vsr);
8206     } else {
8207         tcg_gen_shri_i64(b, vsr, 32);
8208     }
8209
8210     tcg_gen_shli_i64(b2, b, 32);
8211     tcg_gen_or_i64(cpu_vsrh(xT(ctx->opcode)), b, b2);
8212     tcg_gen_mov_i64(cpu_vsrl(xT(ctx->opcode)), cpu_vsrh(xT(ctx->opcode)));
8213
8214     tcg_temp_free_i64(b);
8215     tcg_temp_free_i64(b2);
8216 }
8217
8218 static void gen_xxsldwi(DisasContext *ctx)
8219 {
8220     TCGv_i64 xth, xtl;
8221     if (unlikely(!ctx->vsx_enabled)) {
8222         gen_exception(ctx, POWERPC_EXCP_VSXU);
8223         return;
8224     }
8225     xth = tcg_temp_new_i64();
8226     xtl = tcg_temp_new_i64();
8227
8228     switch (SHW(ctx->opcode)) {
8229         case 0: {
8230             tcg_gen_mov_i64(xth, cpu_vsrh(xA(ctx->opcode)));
8231             tcg_gen_mov_i64(xtl, cpu_vsrl(xA(ctx->opcode)));
8232             break;
8233         }
8234         case 1: {
8235             TCGv_i64 t0 = tcg_temp_new_i64();
8236             tcg_gen_mov_i64(xth, cpu_vsrh(xA(ctx->opcode)));
8237             tcg_gen_shli_i64(xth, xth, 32);
8238             tcg_gen_mov_i64(t0, cpu_vsrl(xA(ctx->opcode)));
8239             tcg_gen_shri_i64(t0, t0, 32);
8240             tcg_gen_or_i64(xth, xth, t0);
8241             tcg_gen_mov_i64(xtl, cpu_vsrl(xA(ctx->opcode)));
8242             tcg_gen_shli_i64(xtl, xtl, 32);
8243             tcg_gen_mov_i64(t0, cpu_vsrh(xB(ctx->opcode)));
8244             tcg_gen_shri_i64(t0, t0, 32);
8245             tcg_gen_or_i64(xtl, xtl, t0);
8246             tcg_temp_free_i64(t0);
8247             break;
8248         }
8249         case 2: {
8250             tcg_gen_mov_i64(xth, cpu_vsrl(xA(ctx->opcode)));
8251             tcg_gen_mov_i64(xtl, cpu_vsrh(xB(ctx->opcode)));
8252             break;
8253         }
8254         case 3: {
8255             TCGv_i64 t0 = tcg_temp_new_i64();
8256             tcg_gen_mov_i64(xth, cpu_vsrl(xA(ctx->opcode)));
8257             tcg_gen_shli_i64(xth, xth, 32);
8258             tcg_gen_mov_i64(t0, cpu_vsrh(xB(ctx->opcode)));
8259             tcg_gen_shri_i64(t0, t0, 32);
8260             tcg_gen_or_i64(xth, xth, t0);
8261             tcg_gen_mov_i64(xtl, cpu_vsrh(xB(ctx->opcode)));
8262             tcg_gen_shli_i64(xtl, xtl, 32);
8263             tcg_gen_mov_i64(t0, cpu_vsrl(xB(ctx->opcode)));
8264             tcg_gen_shri_i64(t0, t0, 32);
8265             tcg_gen_or_i64(xtl, xtl, t0);
8266             tcg_temp_free_i64(t0);
8267             break;
8268         }
8269     }
8270
8271     tcg_gen_mov_i64(cpu_vsrh(xT(ctx->opcode)), xth);
8272     tcg_gen_mov_i64(cpu_vsrl(xT(ctx->opcode)), xtl);
8273
8274     tcg_temp_free_i64(xth);
8275     tcg_temp_free_i64(xtl);
8276 }
8277
8278 /*** Decimal Floating Point ***/
8279
8280 static inline TCGv_ptr gen_fprp_ptr(int reg)
8281 {
8282     TCGv_ptr r = tcg_temp_new_ptr();
8283     tcg_gen_addi_ptr(r, cpu_env, offsetof(CPUPPCState, fpr[reg]));
8284     return r;
8285 }
8286
8287 #define GEN_DFP_T_A_B_Rc(name)                   \
8288 static void gen_##name(DisasContext *ctx)        \
8289 {                                                \
8290     TCGv_ptr rd, ra, rb;                         \
8291     if (unlikely(!ctx->fpu_enabled)) {           \
8292         gen_exception(ctx, POWERPC_EXCP_FPU);    \
8293         return;                                  \
8294     }                                            \
8295     gen_update_nip(ctx, ctx->nip - 4);           \
8296     rd = gen_fprp_ptr(rD(ctx->opcode));          \
8297     ra = gen_fprp_ptr(rA(ctx->opcode));          \
8298     rb = gen_fprp_ptr(rB(ctx->opcode));          \
8299     gen_helper_##name(cpu_env, rd, ra, rb);      \
8300     if (unlikely(Rc(ctx->opcode) != 0)) {        \
8301         gen_set_cr1_from_fpscr(ctx);             \
8302     }                                            \
8303     tcg_temp_free_ptr(rd);                       \
8304     tcg_temp_free_ptr(ra);                       \
8305     tcg_temp_free_ptr(rb);                       \
8306 }
8307
8308 #define GEN_DFP_BF_A_B(name)                      \
8309 static void gen_##name(DisasContext *ctx)         \
8310 {                                                 \
8311     TCGv_ptr ra, rb;                              \
8312     if (unlikely(!ctx->fpu_enabled)) {            \
8313         gen_exception(ctx, POWERPC_EXCP_FPU);     \
8314         return;                                   \
8315     }                                             \
8316     gen_update_nip(ctx, ctx->nip - 4);            \
8317     ra = gen_fprp_ptr(rA(ctx->opcode));           \
8318     rb = gen_fprp_ptr(rB(ctx->opcode));           \
8319     gen_helper_##name(cpu_crf[crfD(ctx->opcode)], \
8320                       cpu_env, ra, rb);           \
8321     tcg_temp_free_ptr(ra);                        \
8322     tcg_temp_free_ptr(rb);                        \
8323 }
8324
8325 #define GEN_DFP_BF_A_DCM(name)                    \
8326 static void gen_##name(DisasContext *ctx)         \
8327 {                                                 \
8328     TCGv_ptr ra;                                  \
8329     TCGv_i32 dcm;                                 \
8330     if (unlikely(!ctx->fpu_enabled)) {            \
8331         gen_exception(ctx, POWERPC_EXCP_FPU);     \
8332         return;                                   \
8333     }                                             \
8334     gen_update_nip(ctx, ctx->nip - 4);            \
8335     ra = gen_fprp_ptr(rA(ctx->opcode));           \
8336     dcm = tcg_const_i32(DCM(ctx->opcode));        \
8337     gen_helper_##name(cpu_crf[crfD(ctx->opcode)], \
8338                       cpu_env, ra, dcm);          \
8339     tcg_temp_free_ptr(ra);                        \
8340     tcg_temp_free_i32(dcm);                       \
8341 }
8342
8343 #define GEN_DFP_T_B_U32_U32_Rc(name, u32f1, u32f2)    \
8344 static void gen_##name(DisasContext *ctx)             \
8345 {                                                     \
8346     TCGv_ptr rt, rb;                                  \
8347     TCGv_i32 u32_1, u32_2;                            \
8348     if (unlikely(!ctx->fpu_enabled)) {                \
8349         gen_exception(ctx, POWERPC_EXCP_FPU);         \
8350         return;                                       \
8351     }                                                 \
8352     gen_update_nip(ctx, ctx->nip - 4);                \
8353     rt = gen_fprp_ptr(rD(ctx->opcode));               \
8354     rb = gen_fprp_ptr(rB(ctx->opcode));               \
8355     u32_1 = tcg_const_i32(u32f1(ctx->opcode));        \
8356     u32_2 = tcg_const_i32(u32f2(ctx->opcode));        \
8357     gen_helper_##name(cpu_env, rt, rb, u32_1, u32_2); \
8358     if (unlikely(Rc(ctx->opcode) != 0)) {             \
8359         gen_set_cr1_from_fpscr(ctx);                  \
8360     }                                                 \
8361     tcg_temp_free_ptr(rt);                            \
8362     tcg_temp_free_ptr(rb);                            \
8363     tcg_temp_free_i32(u32_1);                         \
8364     tcg_temp_free_i32(u32_2);                         \
8365 }
8366
8367 #define GEN_DFP_T_A_B_I32_Rc(name, i32fld)       \
8368 static void gen_##name(DisasContext *ctx)        \
8369 {                                                \
8370     TCGv_ptr rt, ra, rb;                         \
8371     TCGv_i32 i32;                                \
8372     if (unlikely(!ctx->fpu_enabled)) {           \
8373         gen_exception(ctx, POWERPC_EXCP_FPU);    \
8374         return;                                  \
8375     }                                            \
8376     gen_update_nip(ctx, ctx->nip - 4);           \
8377     rt = gen_fprp_ptr(rD(ctx->opcode));          \
8378     ra = gen_fprp_ptr(rA(ctx->opcode));          \
8379     rb = gen_fprp_ptr(rB(ctx->opcode));          \
8380     i32 = tcg_const_i32(i32fld(ctx->opcode));    \
8381     gen_helper_##name(cpu_env, rt, ra, rb, i32); \
8382     if (unlikely(Rc(ctx->opcode) != 0)) {        \
8383         gen_set_cr1_from_fpscr(ctx);             \
8384     }                                            \
8385     tcg_temp_free_ptr(rt);                       \
8386     tcg_temp_free_ptr(rb);                       \
8387     tcg_temp_free_ptr(ra);                       \
8388     tcg_temp_free_i32(i32);                      \
8389     }
8390
8391 #define GEN_DFP_T_B_Rc(name)                     \
8392 static void gen_##name(DisasContext *ctx)        \
8393 {                                                \
8394     TCGv_ptr rt, rb;                             \
8395     if (unlikely(!ctx->fpu_enabled)) {           \
8396         gen_exception(ctx, POWERPC_EXCP_FPU);    \
8397         return;                                  \
8398     }                                            \
8399     gen_update_nip(ctx, ctx->nip - 4);           \
8400     rt = gen_fprp_ptr(rD(ctx->opcode));          \
8401     rb = gen_fprp_ptr(rB(ctx->opcode));          \
8402     gen_helper_##name(cpu_env, rt, rb);          \
8403     if (unlikely(Rc(ctx->opcode) != 0)) {        \
8404         gen_set_cr1_from_fpscr(ctx);             \
8405     }                                            \
8406     tcg_temp_free_ptr(rt);                       \
8407     tcg_temp_free_ptr(rb);                       \
8408     }
8409
8410 #define GEN_DFP_T_FPR_I32_Rc(name, fprfld, i32fld) \
8411 static void gen_##name(DisasContext *ctx)          \
8412 {                                                  \
8413     TCGv_ptr rt, rs;                               \
8414     TCGv_i32 i32;                                  \
8415     if (unlikely(!ctx->fpu_enabled)) {             \
8416         gen_exception(ctx, POWERPC_EXCP_FPU);      \
8417         return;                                    \
8418     }                                              \
8419     gen_update_nip(ctx, ctx->nip - 4);             \
8420     rt = gen_fprp_ptr(rD(ctx->opcode));            \
8421     rs = gen_fprp_ptr(fprfld(ctx->opcode));        \
8422     i32 = tcg_const_i32(i32fld(ctx->opcode));      \
8423     gen_helper_##name(cpu_env, rt, rs, i32);       \
8424     if (unlikely(Rc(ctx->opcode) != 0)) {          \
8425         gen_set_cr1_from_fpscr(ctx);               \
8426     }                                              \
8427     tcg_temp_free_ptr(rt);                         \
8428     tcg_temp_free_ptr(rs);                         \
8429     tcg_temp_free_i32(i32);                        \
8430 }
8431
8432 GEN_DFP_T_A_B_Rc(dadd)
8433 GEN_DFP_T_A_B_Rc(daddq)
8434 GEN_DFP_T_A_B_Rc(dsub)
8435 GEN_DFP_T_A_B_Rc(dsubq)
8436 GEN_DFP_T_A_B_Rc(dmul)
8437 GEN_DFP_T_A_B_Rc(dmulq)
8438 GEN_DFP_T_A_B_Rc(ddiv)
8439 GEN_DFP_T_A_B_Rc(ddivq)
8440 GEN_DFP_BF_A_B(dcmpu)
8441 GEN_DFP_BF_A_B(dcmpuq)
8442 GEN_DFP_BF_A_B(dcmpo)
8443 GEN_DFP_BF_A_B(dcmpoq)
8444 GEN_DFP_BF_A_DCM(dtstdc)
8445 GEN_DFP_BF_A_DCM(dtstdcq)
8446 GEN_DFP_BF_A_DCM(dtstdg)
8447 GEN_DFP_BF_A_DCM(dtstdgq)
8448 GEN_DFP_BF_A_B(dtstex)
8449 GEN_DFP_BF_A_B(dtstexq)
8450 GEN_DFP_BF_A_B(dtstsf)
8451 GEN_DFP_BF_A_B(dtstsfq)
8452 GEN_DFP_T_B_U32_U32_Rc(dquai, SIMM5, RMC)
8453 GEN_DFP_T_B_U32_U32_Rc(dquaiq, SIMM5, RMC)
8454 GEN_DFP_T_A_B_I32_Rc(dqua, RMC)
8455 GEN_DFP_T_A_B_I32_Rc(dquaq, RMC)
8456 GEN_DFP_T_A_B_I32_Rc(drrnd, RMC)
8457 GEN_DFP_T_A_B_I32_Rc(drrndq, RMC)
8458 GEN_DFP_T_B_U32_U32_Rc(drintx, FPW, RMC)
8459 GEN_DFP_T_B_U32_U32_Rc(drintxq, FPW, RMC)
8460 GEN_DFP_T_B_U32_U32_Rc(drintn, FPW, RMC)
8461 GEN_DFP_T_B_U32_U32_Rc(drintnq, FPW, RMC)
8462 GEN_DFP_T_B_Rc(dctdp)
8463 GEN_DFP_T_B_Rc(dctqpq)
8464 GEN_DFP_T_B_Rc(drsp)
8465 GEN_DFP_T_B_Rc(drdpq)
8466 GEN_DFP_T_B_Rc(dcffix)
8467 GEN_DFP_T_B_Rc(dcffixq)
8468 GEN_DFP_T_B_Rc(dctfix)
8469 GEN_DFP_T_B_Rc(dctfixq)
8470 GEN_DFP_T_FPR_I32_Rc(ddedpd, rB, SP)
8471 GEN_DFP_T_FPR_I32_Rc(ddedpdq, rB, SP)
8472 GEN_DFP_T_FPR_I32_Rc(denbcd, rB, SP)
8473 GEN_DFP_T_FPR_I32_Rc(denbcdq, rB, SP)
8474 GEN_DFP_T_B_Rc(dxex)
8475 GEN_DFP_T_B_Rc(dxexq)
8476 GEN_DFP_T_A_B_Rc(diex)
8477 GEN_DFP_T_A_B_Rc(diexq)
8478 GEN_DFP_T_FPR_I32_Rc(dscli, rA, DCM)
8479 GEN_DFP_T_FPR_I32_Rc(dscliq, rA, DCM)
8480 GEN_DFP_T_FPR_I32_Rc(dscri, rA, DCM)
8481 GEN_DFP_T_FPR_I32_Rc(dscriq, rA, DCM)
8482
8483 /***                           SPE extension                               ***/
8484 /* Register moves */
8485
8486 static inline void gen_evmra(DisasContext *ctx)
8487 {
8488
8489     if (unlikely(!ctx->spe_enabled)) {
8490         gen_exception(ctx, POWERPC_EXCP_SPEU);
8491         return;
8492     }
8493
8494     TCGv_i64 tmp = tcg_temp_new_i64();
8495
8496     /* tmp := rA_lo + rA_hi << 32 */
8497     tcg_gen_concat_tl_i64(tmp, cpu_gpr[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
8498
8499     /* spe_acc := tmp */
8500     tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUPPCState, spe_acc));
8501     tcg_temp_free_i64(tmp);
8502
8503     /* rD := rA */
8504     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
8505     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
8506 }
8507
8508 static inline void gen_load_gpr64(TCGv_i64 t, int reg)
8509 {
8510     tcg_gen_concat_tl_i64(t, cpu_gpr[reg], cpu_gprh[reg]);
8511 }
8512
8513 static inline void gen_store_gpr64(int reg, TCGv_i64 t)
8514 {
8515     tcg_gen_extr_i64_tl(cpu_gpr[reg], cpu_gprh[reg], t);
8516 }
8517
8518 #define GEN_SPE(name0, name1, opc2, opc3, inval0, inval1, type)         \
8519 static void glue(gen_, name0##_##name1)(DisasContext *ctx)                    \
8520 {                                                                             \
8521     if (Rc(ctx->opcode))                                                      \
8522         gen_##name1(ctx);                                                     \
8523     else                                                                      \
8524         gen_##name0(ctx);                                                     \
8525 }
8526
8527 /* Handler for undefined SPE opcodes */
8528 static inline void gen_speundef(DisasContext *ctx)
8529 {
8530     gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
8531 }
8532
8533 /* SPE logic */
8534 #define GEN_SPEOP_LOGIC2(name, tcg_op)                                        \
8535 static inline void gen_##name(DisasContext *ctx)                              \
8536 {                                                                             \
8537     if (unlikely(!ctx->spe_enabled)) {                                        \
8538         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
8539         return;                                                               \
8540     }                                                                         \
8541     tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],                \
8542            cpu_gpr[rB(ctx->opcode)]);                                         \
8543     tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],              \
8544            cpu_gprh[rB(ctx->opcode)]);                                        \
8545 }
8546
8547 GEN_SPEOP_LOGIC2(evand, tcg_gen_and_tl);
8548 GEN_SPEOP_LOGIC2(evandc, tcg_gen_andc_tl);
8549 GEN_SPEOP_LOGIC2(evxor, tcg_gen_xor_tl);
8550 GEN_SPEOP_LOGIC2(evor, tcg_gen_or_tl);
8551 GEN_SPEOP_LOGIC2(evnor, tcg_gen_nor_tl);
8552 GEN_SPEOP_LOGIC2(eveqv, tcg_gen_eqv_tl);
8553 GEN_SPEOP_LOGIC2(evorc, tcg_gen_orc_tl);
8554 GEN_SPEOP_LOGIC2(evnand, tcg_gen_nand_tl);
8555
8556 /* SPE logic immediate */
8557 #define GEN_SPEOP_TCG_LOGIC_IMM2(name, tcg_opi)                               \
8558 static inline void gen_##name(DisasContext *ctx)                              \
8559 {                                                                             \
8560     TCGv_i32 t0;                                                              \
8561     if (unlikely(!ctx->spe_enabled)) {                                        \
8562         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
8563         return;                                                               \
8564     }                                                                         \
8565     t0 = tcg_temp_new_i32();                                                  \
8566                                                                               \
8567     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);                       \
8568     tcg_opi(t0, t0, rB(ctx->opcode));                                         \
8569     tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0);                        \
8570                                                                               \
8571     tcg_gen_trunc_tl_i32(t0, cpu_gprh[rA(ctx->opcode)]);                      \
8572     tcg_opi(t0, t0, rB(ctx->opcode));                                         \
8573     tcg_gen_extu_i32_tl(cpu_gprh[rD(ctx->opcode)], t0);                       \
8574                                                                               \
8575     tcg_temp_free_i32(t0);                                                    \
8576 }
8577 GEN_SPEOP_TCG_LOGIC_IMM2(evslwi, tcg_gen_shli_i32);
8578 GEN_SPEOP_TCG_LOGIC_IMM2(evsrwiu, tcg_gen_shri_i32);
8579 GEN_SPEOP_TCG_LOGIC_IMM2(evsrwis, tcg_gen_sari_i32);
8580 GEN_SPEOP_TCG_LOGIC_IMM2(evrlwi, tcg_gen_rotli_i32);
8581
8582 /* SPE arithmetic */
8583 #define GEN_SPEOP_ARITH1(name, tcg_op)                                        \
8584 static inline void gen_##name(DisasContext *ctx)                              \
8585 {                                                                             \
8586     TCGv_i32 t0;                                                              \
8587     if (unlikely(!ctx->spe_enabled)) {                                        \
8588         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
8589         return;                                                               \
8590     }                                                                         \
8591     t0 = tcg_temp_new_i32();                                                  \
8592                                                                               \
8593     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);                       \
8594     tcg_op(t0, t0);                                                           \
8595     tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0);                        \
8596                                                                               \
8597     tcg_gen_trunc_tl_i32(t0, cpu_gprh[rA(ctx->opcode)]);                      \
8598     tcg_op(t0, t0);                                                           \
8599     tcg_gen_extu_i32_tl(cpu_gprh[rD(ctx->opcode)], t0);                       \
8600                                                                               \
8601     tcg_temp_free_i32(t0);                                                    \
8602 }
8603
8604 static inline void gen_op_evabs(TCGv_i32 ret, TCGv_i32 arg1)
8605 {
8606     TCGLabel *l1 = gen_new_label();
8607     TCGLabel *l2 = gen_new_label();
8608
8609     tcg_gen_brcondi_i32(TCG_COND_GE, arg1, 0, l1);
8610     tcg_gen_neg_i32(ret, arg1);
8611     tcg_gen_br(l2);
8612     gen_set_label(l1);
8613     tcg_gen_mov_i32(ret, arg1);
8614     gen_set_label(l2);
8615 }
8616 GEN_SPEOP_ARITH1(evabs, gen_op_evabs);
8617 GEN_SPEOP_ARITH1(evneg, tcg_gen_neg_i32);
8618 GEN_SPEOP_ARITH1(evextsb, tcg_gen_ext8s_i32);
8619 GEN_SPEOP_ARITH1(evextsh, tcg_gen_ext16s_i32);
8620 static inline void gen_op_evrndw(TCGv_i32 ret, TCGv_i32 arg1)
8621 {
8622     tcg_gen_addi_i32(ret, arg1, 0x8000);
8623     tcg_gen_ext16u_i32(ret, ret);
8624 }
8625 GEN_SPEOP_ARITH1(evrndw, gen_op_evrndw);
8626 GEN_SPEOP_ARITH1(evcntlsw, gen_helper_cntlsw32);
8627 GEN_SPEOP_ARITH1(evcntlzw, gen_helper_cntlzw32);
8628
8629 #define GEN_SPEOP_ARITH2(name, tcg_op)                                        \
8630 static inline void gen_##name(DisasContext *ctx)                              \
8631 {                                                                             \
8632     TCGv_i32 t0, t1;                                                          \
8633     if (unlikely(!ctx->spe_enabled)) {                                        \
8634         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
8635         return;                                                               \
8636     }                                                                         \
8637     t0 = tcg_temp_new_i32();                                                  \
8638     t1 = tcg_temp_new_i32();                                                  \
8639                                                                               \
8640     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);                       \
8641     tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);                       \
8642     tcg_op(t0, t0, t1);                                                       \
8643     tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0);                        \
8644                                                                               \
8645     tcg_gen_trunc_tl_i32(t0, cpu_gprh[rA(ctx->opcode)]);                      \
8646     tcg_gen_trunc_tl_i32(t1, cpu_gprh[rB(ctx->opcode)]);                      \
8647     tcg_op(t0, t0, t1);                                                       \
8648     tcg_gen_extu_i32_tl(cpu_gprh[rD(ctx->opcode)], t0);                       \
8649                                                                               \
8650     tcg_temp_free_i32(t0);                                                    \
8651     tcg_temp_free_i32(t1);                                                    \
8652 }
8653
8654 static inline void gen_op_evsrwu(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
8655 {
8656     TCGLabel *l1 = gen_new_label();
8657     TCGLabel *l2 = gen_new_label();
8658     TCGv_i32 t0 = tcg_temp_local_new_i32();
8659
8660     /* No error here: 6 bits are used */
8661     tcg_gen_andi_i32(t0, arg2, 0x3F);
8662     tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1);
8663     tcg_gen_shr_i32(ret, arg1, t0);
8664     tcg_gen_br(l2);
8665     gen_set_label(l1);
8666     tcg_gen_movi_i32(ret, 0);
8667     gen_set_label(l2);
8668     tcg_temp_free_i32(t0);
8669 }
8670 GEN_SPEOP_ARITH2(evsrwu, gen_op_evsrwu);
8671 static inline void gen_op_evsrws(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
8672 {
8673     TCGLabel *l1 = gen_new_label();
8674     TCGLabel *l2 = gen_new_label();
8675     TCGv_i32 t0 = tcg_temp_local_new_i32();
8676
8677     /* No error here: 6 bits are used */
8678     tcg_gen_andi_i32(t0, arg2, 0x3F);
8679     tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1);
8680     tcg_gen_sar_i32(ret, arg1, t0);
8681     tcg_gen_br(l2);
8682     gen_set_label(l1);
8683     tcg_gen_movi_i32(ret, 0);
8684     gen_set_label(l2);
8685     tcg_temp_free_i32(t0);
8686 }
8687 GEN_SPEOP_ARITH2(evsrws, gen_op_evsrws);
8688 static inline void gen_op_evslw(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
8689 {
8690     TCGLabel *l1 = gen_new_label();
8691     TCGLabel *l2 = gen_new_label();
8692     TCGv_i32 t0 = tcg_temp_local_new_i32();
8693
8694     /* No error here: 6 bits are used */
8695     tcg_gen_andi_i32(t0, arg2, 0x3F);
8696     tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1);
8697     tcg_gen_shl_i32(ret, arg1, t0);
8698     tcg_gen_br(l2);
8699     gen_set_label(l1);
8700     tcg_gen_movi_i32(ret, 0);
8701     gen_set_label(l2);
8702     tcg_temp_free_i32(t0);
8703 }
8704 GEN_SPEOP_ARITH2(evslw, gen_op_evslw);
8705 static inline void gen_op_evrlw(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
8706 {
8707     TCGv_i32 t0 = tcg_temp_new_i32();
8708     tcg_gen_andi_i32(t0, arg2, 0x1F);
8709     tcg_gen_rotl_i32(ret, arg1, t0);
8710     tcg_temp_free_i32(t0);
8711 }
8712 GEN_SPEOP_ARITH2(evrlw, gen_op_evrlw);
8713 static inline void gen_evmergehi(DisasContext *ctx)
8714 {
8715     if (unlikely(!ctx->spe_enabled)) {
8716         gen_exception(ctx, POWERPC_EXCP_SPEU);
8717         return;
8718     }
8719     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
8720     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
8721 }
8722 GEN_SPEOP_ARITH2(evaddw, tcg_gen_add_i32);
8723 static inline void gen_op_evsubf(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
8724 {
8725     tcg_gen_sub_i32(ret, arg2, arg1);
8726 }
8727 GEN_SPEOP_ARITH2(evsubfw, gen_op_evsubf);
8728
8729 /* SPE arithmetic immediate */
8730 #define GEN_SPEOP_ARITH_IMM2(name, tcg_op)                                    \
8731 static inline void gen_##name(DisasContext *ctx)                              \
8732 {                                                                             \
8733     TCGv_i32 t0;                                                              \
8734     if (unlikely(!ctx->spe_enabled)) {                                        \
8735         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
8736         return;                                                               \
8737     }                                                                         \
8738     t0 = tcg_temp_new_i32();                                                  \
8739                                                                               \
8740     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rB(ctx->opcode)]);                       \
8741     tcg_op(t0, t0, rA(ctx->opcode));                                          \
8742     tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0);                        \
8743                                                                               \
8744     tcg_gen_trunc_tl_i32(t0, cpu_gprh[rB(ctx->opcode)]);                      \
8745     tcg_op(t0, t0, rA(ctx->opcode));                                          \
8746     tcg_gen_extu_i32_tl(cpu_gprh[rD(ctx->opcode)], t0);                       \
8747                                                                               \
8748     tcg_temp_free_i32(t0);                                                    \
8749 }
8750 GEN_SPEOP_ARITH_IMM2(evaddiw, tcg_gen_addi_i32);
8751 GEN_SPEOP_ARITH_IMM2(evsubifw, tcg_gen_subi_i32);
8752
8753 /* SPE comparison */
8754 #define GEN_SPEOP_COMP(name, tcg_cond)                                        \
8755 static inline void gen_##name(DisasContext *ctx)                              \
8756 {                                                                             \
8757     if (unlikely(!ctx->spe_enabled)) {                                        \
8758         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
8759         return;                                                               \
8760     }                                                                         \
8761     TCGLabel *l1 = gen_new_label();                                           \
8762     TCGLabel *l2 = gen_new_label();                                           \
8763     TCGLabel *l3 = gen_new_label();                                           \
8764     TCGLabel *l4 = gen_new_label();                                           \
8765                                                                               \
8766     tcg_gen_ext32s_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);    \
8767     tcg_gen_ext32s_tl(cpu_gpr[rB(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
8768     tcg_gen_ext32s_tl(cpu_gprh[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);  \
8769     tcg_gen_ext32s_tl(cpu_gprh[rB(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);  \
8770                                                                               \
8771     tcg_gen_brcond_tl(tcg_cond, cpu_gpr[rA(ctx->opcode)],                     \
8772                        cpu_gpr[rB(ctx->opcode)], l1);                         \
8773     tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)], 0);                          \
8774     tcg_gen_br(l2);                                                           \
8775     gen_set_label(l1);                                                        \
8776     tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)],                              \
8777                      CRF_CL | CRF_CH_OR_CL | CRF_CH_AND_CL);                  \
8778     gen_set_label(l2);                                                        \
8779     tcg_gen_brcond_tl(tcg_cond, cpu_gprh[rA(ctx->opcode)],                    \
8780                        cpu_gprh[rB(ctx->opcode)], l3);                        \
8781     tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)],  \
8782                      ~(CRF_CH | CRF_CH_AND_CL));                              \
8783     tcg_gen_br(l4);                                                           \
8784     gen_set_label(l3);                                                        \
8785     tcg_gen_ori_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)],   \
8786                     CRF_CH | CRF_CH_OR_CL);                                   \
8787     gen_set_label(l4);                                                        \
8788 }
8789 GEN_SPEOP_COMP(evcmpgtu, TCG_COND_GTU);
8790 GEN_SPEOP_COMP(evcmpgts, TCG_COND_GT);
8791 GEN_SPEOP_COMP(evcmpltu, TCG_COND_LTU);
8792 GEN_SPEOP_COMP(evcmplts, TCG_COND_LT);
8793 GEN_SPEOP_COMP(evcmpeq, TCG_COND_EQ);
8794
8795 /* SPE misc */
8796 static inline void gen_brinc(DisasContext *ctx)
8797 {
8798     /* Note: brinc is usable even if SPE is disabled */
8799     gen_helper_brinc(cpu_gpr[rD(ctx->opcode)],
8800                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
8801 }
8802 static inline void gen_evmergelo(DisasContext *ctx)
8803 {
8804     if (unlikely(!ctx->spe_enabled)) {
8805         gen_exception(ctx, POWERPC_EXCP_SPEU);
8806         return;
8807     }
8808     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
8809     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
8810 }
8811 static inline void gen_evmergehilo(DisasContext *ctx)
8812 {
8813     if (unlikely(!ctx->spe_enabled)) {
8814         gen_exception(ctx, POWERPC_EXCP_SPEU);
8815         return;
8816     }
8817     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
8818     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
8819 }
8820 static inline void gen_evmergelohi(DisasContext *ctx)
8821 {
8822     if (unlikely(!ctx->spe_enabled)) {
8823         gen_exception(ctx, POWERPC_EXCP_SPEU);
8824         return;
8825     }
8826     if (rD(ctx->opcode) == rA(ctx->opcode)) {
8827         TCGv tmp = tcg_temp_new();
8828         tcg_gen_mov_tl(tmp, cpu_gpr[rA(ctx->opcode)]);
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)], tmp);
8831         tcg_temp_free(tmp);
8832     } else {
8833         tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
8834         tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
8835     }
8836 }
8837 static inline void gen_evsplati(DisasContext *ctx)
8838 {
8839     uint64_t imm = ((int32_t)(rA(ctx->opcode) << 27)) >> 27;
8840
8841     tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], imm);
8842     tcg_gen_movi_tl(cpu_gprh[rD(ctx->opcode)], imm);
8843 }
8844 static inline void gen_evsplatfi(DisasContext *ctx)
8845 {
8846     uint64_t imm = rA(ctx->opcode) << 27;
8847
8848     tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], imm);
8849     tcg_gen_movi_tl(cpu_gprh[rD(ctx->opcode)], imm);
8850 }
8851
8852 static inline void gen_evsel(DisasContext *ctx)
8853 {
8854     TCGLabel *l1 = gen_new_label();
8855     TCGLabel *l2 = gen_new_label();
8856     TCGLabel *l3 = gen_new_label();
8857     TCGLabel *l4 = gen_new_label();
8858     TCGv_i32 t0 = tcg_temp_local_new_i32();
8859
8860     tcg_gen_andi_i32(t0, cpu_crf[ctx->opcode & 0x07], 1 << 3);
8861     tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
8862     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
8863     tcg_gen_br(l2);
8864     gen_set_label(l1);
8865     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
8866     gen_set_label(l2);
8867     tcg_gen_andi_i32(t0, cpu_crf[ctx->opcode & 0x07], 1 << 2);
8868     tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l3);
8869     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
8870     tcg_gen_br(l4);
8871     gen_set_label(l3);
8872     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
8873     gen_set_label(l4);
8874     tcg_temp_free_i32(t0);
8875 }
8876
8877 static void gen_evsel0(DisasContext *ctx)
8878 {
8879     gen_evsel(ctx);
8880 }
8881
8882 static void gen_evsel1(DisasContext *ctx)
8883 {
8884     gen_evsel(ctx);
8885 }
8886
8887 static void gen_evsel2(DisasContext *ctx)
8888 {
8889     gen_evsel(ctx);
8890 }
8891
8892 static void gen_evsel3(DisasContext *ctx)
8893 {
8894     gen_evsel(ctx);
8895 }
8896
8897 /* Multiply */
8898
8899 static inline void gen_evmwumi(DisasContext *ctx)
8900 {
8901     TCGv_i64 t0, t1;
8902
8903     if (unlikely(!ctx->spe_enabled)) {
8904         gen_exception(ctx, POWERPC_EXCP_SPEU);
8905         return;
8906     }
8907
8908     t0 = tcg_temp_new_i64();
8909     t1 = tcg_temp_new_i64();
8910
8911     /* t0 := rA; t1 := rB */
8912     tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
8913     tcg_gen_ext32u_i64(t0, t0);
8914     tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
8915     tcg_gen_ext32u_i64(t1, t1);
8916
8917     tcg_gen_mul_i64(t0, t0, t1);  /* t0 := rA * rB */
8918
8919     gen_store_gpr64(rD(ctx->opcode), t0); /* rD := t0 */
8920
8921     tcg_temp_free_i64(t0);
8922     tcg_temp_free_i64(t1);
8923 }
8924
8925 static inline void gen_evmwumia(DisasContext *ctx)
8926 {
8927     TCGv_i64 tmp;
8928
8929     if (unlikely(!ctx->spe_enabled)) {
8930         gen_exception(ctx, POWERPC_EXCP_SPEU);
8931         return;
8932     }
8933
8934     gen_evmwumi(ctx);            /* rD := rA * rB */
8935
8936     tmp = tcg_temp_new_i64();
8937
8938     /* acc := rD */
8939     gen_load_gpr64(tmp, rD(ctx->opcode));
8940     tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUPPCState, spe_acc));
8941     tcg_temp_free_i64(tmp);
8942 }
8943
8944 static inline void gen_evmwumiaa(DisasContext *ctx)
8945 {
8946     TCGv_i64 acc;
8947     TCGv_i64 tmp;
8948
8949     if (unlikely(!ctx->spe_enabled)) {
8950         gen_exception(ctx, POWERPC_EXCP_SPEU);
8951         return;
8952     }
8953
8954     gen_evmwumi(ctx);           /* rD := rA * rB */
8955
8956     acc = tcg_temp_new_i64();
8957     tmp = tcg_temp_new_i64();
8958
8959     /* tmp := rD */
8960     gen_load_gpr64(tmp, rD(ctx->opcode));
8961
8962     /* Load acc */
8963     tcg_gen_ld_i64(acc, cpu_env, offsetof(CPUPPCState, spe_acc));
8964
8965     /* acc := tmp + acc */
8966     tcg_gen_add_i64(acc, acc, tmp);
8967
8968     /* Store acc */
8969     tcg_gen_st_i64(acc, cpu_env, offsetof(CPUPPCState, spe_acc));
8970
8971     /* rD := acc */
8972     gen_store_gpr64(rD(ctx->opcode), acc);
8973
8974     tcg_temp_free_i64(acc);
8975     tcg_temp_free_i64(tmp);
8976 }
8977
8978 static inline void gen_evmwsmi(DisasContext *ctx)
8979 {
8980     TCGv_i64 t0, t1;
8981
8982     if (unlikely(!ctx->spe_enabled)) {
8983         gen_exception(ctx, POWERPC_EXCP_SPEU);
8984         return;
8985     }
8986
8987     t0 = tcg_temp_new_i64();
8988     t1 = tcg_temp_new_i64();
8989
8990     /* t0 := rA; t1 := rB */
8991     tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
8992     tcg_gen_ext32s_i64(t0, t0);
8993     tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
8994     tcg_gen_ext32s_i64(t1, t1);
8995
8996     tcg_gen_mul_i64(t0, t0, t1);  /* t0 := rA * rB */
8997
8998     gen_store_gpr64(rD(ctx->opcode), t0); /* rD := t0 */
8999
9000     tcg_temp_free_i64(t0);
9001     tcg_temp_free_i64(t1);
9002 }
9003
9004 static inline void gen_evmwsmia(DisasContext *ctx)
9005 {
9006     TCGv_i64 tmp;
9007
9008     gen_evmwsmi(ctx);            /* rD := rA * rB */
9009
9010     tmp = tcg_temp_new_i64();
9011
9012     /* acc := rD */
9013     gen_load_gpr64(tmp, rD(ctx->opcode));
9014     tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUPPCState, spe_acc));
9015
9016     tcg_temp_free_i64(tmp);
9017 }
9018
9019 static inline void gen_evmwsmiaa(DisasContext *ctx)
9020 {
9021     TCGv_i64 acc = tcg_temp_new_i64();
9022     TCGv_i64 tmp = tcg_temp_new_i64();
9023
9024     gen_evmwsmi(ctx);           /* rD := rA * rB */
9025
9026     acc = tcg_temp_new_i64();
9027     tmp = tcg_temp_new_i64();
9028
9029     /* tmp := rD */
9030     gen_load_gpr64(tmp, rD(ctx->opcode));
9031
9032     /* Load acc */
9033     tcg_gen_ld_i64(acc, cpu_env, offsetof(CPUPPCState, spe_acc));
9034
9035     /* acc := tmp + acc */
9036     tcg_gen_add_i64(acc, acc, tmp);
9037
9038     /* Store acc */
9039     tcg_gen_st_i64(acc, cpu_env, offsetof(CPUPPCState, spe_acc));
9040
9041     /* rD := acc */
9042     gen_store_gpr64(rD(ctx->opcode), acc);
9043
9044     tcg_temp_free_i64(acc);
9045     tcg_temp_free_i64(tmp);
9046 }
9047
9048 GEN_SPE(evaddw,      speundef,    0x00, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE); ////
9049 GEN_SPE(evaddiw,     speundef,    0x01, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE);
9050 GEN_SPE(evsubfw,     speundef,    0x02, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE); ////
9051 GEN_SPE(evsubifw,    speundef,    0x03, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE);
9052 GEN_SPE(evabs,       evneg,       0x04, 0x08, 0x0000F800, 0x0000F800, PPC_SPE); ////
9053 GEN_SPE(evextsb,     evextsh,     0x05, 0x08, 0x0000F800, 0x0000F800, PPC_SPE); ////
9054 GEN_SPE(evrndw,      evcntlzw,    0x06, 0x08, 0x0000F800, 0x0000F800, PPC_SPE); ////
9055 GEN_SPE(evcntlsw,    brinc,       0x07, 0x08, 0x0000F800, 0x00000000, PPC_SPE); //
9056 GEN_SPE(evmra,       speundef,    0x02, 0x13, 0x0000F800, 0xFFFFFFFF, PPC_SPE);
9057 GEN_SPE(speundef,    evand,       0x08, 0x08, 0xFFFFFFFF, 0x00000000, PPC_SPE); ////
9058 GEN_SPE(evandc,      speundef,    0x09, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE); ////
9059 GEN_SPE(evxor,       evor,        0x0B, 0x08, 0x00000000, 0x00000000, PPC_SPE); ////
9060 GEN_SPE(evnor,       eveqv,       0x0C, 0x08, 0x00000000, 0x00000000, PPC_SPE); ////
9061 GEN_SPE(evmwumi,     evmwsmi,     0x0C, 0x11, 0x00000000, 0x00000000, PPC_SPE);
9062 GEN_SPE(evmwumia,    evmwsmia,    0x1C, 0x11, 0x00000000, 0x00000000, PPC_SPE);
9063 GEN_SPE(evmwumiaa,   evmwsmiaa,   0x0C, 0x15, 0x00000000, 0x00000000, PPC_SPE);
9064 GEN_SPE(speundef,    evorc,       0x0D, 0x08, 0xFFFFFFFF, 0x00000000, PPC_SPE); ////
9065 GEN_SPE(evnand,      speundef,    0x0F, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE); ////
9066 GEN_SPE(evsrwu,      evsrws,      0x10, 0x08, 0x00000000, 0x00000000, PPC_SPE); ////
9067 GEN_SPE(evsrwiu,     evsrwis,     0x11, 0x08, 0x00000000, 0x00000000, PPC_SPE);
9068 GEN_SPE(evslw,       speundef,    0x12, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE); ////
9069 GEN_SPE(evslwi,      speundef,    0x13, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE);
9070 GEN_SPE(evrlw,       evsplati,    0x14, 0x08, 0x00000000, 0x0000F800, PPC_SPE); //
9071 GEN_SPE(evrlwi,      evsplatfi,   0x15, 0x08, 0x00000000, 0x0000F800, PPC_SPE);
9072 GEN_SPE(evmergehi,   evmergelo,   0x16, 0x08, 0x00000000, 0x00000000, PPC_SPE); ////
9073 GEN_SPE(evmergehilo, evmergelohi, 0x17, 0x08, 0x00000000, 0x00000000, PPC_SPE); ////
9074 GEN_SPE(evcmpgtu,    evcmpgts,    0x18, 0x08, 0x00600000, 0x00600000, PPC_SPE); ////
9075 GEN_SPE(evcmpltu,    evcmplts,    0x19, 0x08, 0x00600000, 0x00600000, PPC_SPE); ////
9076 GEN_SPE(evcmpeq,     speundef,    0x1A, 0x08, 0x00600000, 0xFFFFFFFF, PPC_SPE); ////
9077
9078 /* SPE load and stores */
9079 static inline void gen_addr_spe_imm_index(DisasContext *ctx, TCGv EA, int sh)
9080 {
9081     target_ulong uimm = rB(ctx->opcode);
9082
9083     if (rA(ctx->opcode) == 0) {
9084         tcg_gen_movi_tl(EA, uimm << sh);
9085     } else {
9086         tcg_gen_addi_tl(EA, cpu_gpr[rA(ctx->opcode)], uimm << sh);
9087         if (NARROW_MODE(ctx)) {
9088             tcg_gen_ext32u_tl(EA, EA);
9089         }
9090     }
9091 }
9092
9093 static inline void gen_op_evldd(DisasContext *ctx, TCGv addr)
9094 {
9095     TCGv_i64 t0 = tcg_temp_new_i64();
9096     gen_qemu_ld64(ctx, t0, addr);
9097     gen_store_gpr64(rD(ctx->opcode), t0);
9098     tcg_temp_free_i64(t0);
9099 }
9100
9101 static inline void gen_op_evldw(DisasContext *ctx, TCGv addr)
9102 {
9103     gen_qemu_ld32u(ctx, cpu_gprh[rD(ctx->opcode)], addr);
9104     gen_addr_add(ctx, addr, addr, 4);
9105     gen_qemu_ld32u(ctx, cpu_gpr[rD(ctx->opcode)], addr);
9106 }
9107
9108 static inline void gen_op_evldh(DisasContext *ctx, TCGv addr)
9109 {
9110     TCGv t0 = tcg_temp_new();
9111     gen_qemu_ld16u(ctx, t0, addr);
9112     tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
9113     gen_addr_add(ctx, addr, addr, 2);
9114     gen_qemu_ld16u(ctx, t0, addr);
9115     tcg_gen_or_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0);
9116     gen_addr_add(ctx, addr, addr, 2);
9117     gen_qemu_ld16u(ctx, t0, addr);
9118     tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
9119     gen_addr_add(ctx, addr, addr, 2);
9120     gen_qemu_ld16u(ctx, t0, addr);
9121     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
9122     tcg_temp_free(t0);
9123 }
9124
9125 static inline void gen_op_evlhhesplat(DisasContext *ctx, TCGv addr)
9126 {
9127     TCGv t0 = tcg_temp_new();
9128     gen_qemu_ld16u(ctx, t0, addr);
9129     tcg_gen_shli_tl(t0, t0, 16);
9130     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
9131     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
9132     tcg_temp_free(t0);
9133 }
9134
9135 static inline void gen_op_evlhhousplat(DisasContext *ctx, TCGv addr)
9136 {
9137     TCGv t0 = tcg_temp_new();
9138     gen_qemu_ld16u(ctx, t0, addr);
9139     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
9140     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
9141     tcg_temp_free(t0);
9142 }
9143
9144 static inline void gen_op_evlhhossplat(DisasContext *ctx, TCGv addr)
9145 {
9146     TCGv t0 = tcg_temp_new();
9147     gen_qemu_ld16s(ctx, t0, addr);
9148     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
9149     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
9150     tcg_temp_free(t0);
9151 }
9152
9153 static inline void gen_op_evlwhe(DisasContext *ctx, TCGv addr)
9154 {
9155     TCGv t0 = tcg_temp_new();
9156     gen_qemu_ld16u(ctx, t0, addr);
9157     tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
9158     gen_addr_add(ctx, addr, addr, 2);
9159     gen_qemu_ld16u(ctx, t0, addr);
9160     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 16);
9161     tcg_temp_free(t0);
9162 }
9163
9164 static inline void gen_op_evlwhou(DisasContext *ctx, TCGv addr)
9165 {
9166     gen_qemu_ld16u(ctx, cpu_gprh[rD(ctx->opcode)], addr);
9167     gen_addr_add(ctx, addr, addr, 2);
9168     gen_qemu_ld16u(ctx, cpu_gpr[rD(ctx->opcode)], addr);
9169 }
9170
9171 static inline void gen_op_evlwhos(DisasContext *ctx, TCGv addr)
9172 {
9173     gen_qemu_ld16s(ctx, cpu_gprh[rD(ctx->opcode)], addr);
9174     gen_addr_add(ctx, addr, addr, 2);
9175     gen_qemu_ld16s(ctx, cpu_gpr[rD(ctx->opcode)], addr);
9176 }
9177
9178 static inline void gen_op_evlwwsplat(DisasContext *ctx, TCGv addr)
9179 {
9180     TCGv t0 = tcg_temp_new();
9181     gen_qemu_ld32u(ctx, t0, addr);
9182     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
9183     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
9184     tcg_temp_free(t0);
9185 }
9186
9187 static inline void gen_op_evlwhsplat(DisasContext *ctx, TCGv addr)
9188 {
9189     TCGv t0 = tcg_temp_new();
9190     gen_qemu_ld16u(ctx, t0, addr);
9191     tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
9192     tcg_gen_or_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0);
9193     gen_addr_add(ctx, addr, addr, 2);
9194     gen_qemu_ld16u(ctx, t0, addr);
9195     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 16);
9196     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0);
9197     tcg_temp_free(t0);
9198 }
9199
9200 static inline void gen_op_evstdd(DisasContext *ctx, TCGv addr)
9201 {
9202     TCGv_i64 t0 = tcg_temp_new_i64();
9203     gen_load_gpr64(t0, rS(ctx->opcode));
9204     gen_qemu_st64(ctx, t0, addr);
9205     tcg_temp_free_i64(t0);
9206 }
9207
9208 static inline void gen_op_evstdw(DisasContext *ctx, TCGv addr)
9209 {
9210     gen_qemu_st32(ctx, cpu_gprh[rS(ctx->opcode)], addr);
9211     gen_addr_add(ctx, addr, addr, 4);
9212     gen_qemu_st32(ctx, cpu_gpr[rS(ctx->opcode)], addr);
9213 }
9214
9215 static inline void gen_op_evstdh(DisasContext *ctx, TCGv addr)
9216 {
9217     TCGv t0 = tcg_temp_new();
9218     tcg_gen_shri_tl(t0, cpu_gprh[rS(ctx->opcode)], 16);
9219     gen_qemu_st16(ctx, t0, addr);
9220     gen_addr_add(ctx, addr, addr, 2);
9221     gen_qemu_st16(ctx, cpu_gprh[rS(ctx->opcode)], addr);
9222     gen_addr_add(ctx, addr, addr, 2);
9223     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 16);
9224     gen_qemu_st16(ctx, t0, addr);
9225     tcg_temp_free(t0);
9226     gen_addr_add(ctx, addr, addr, 2);
9227     gen_qemu_st16(ctx, cpu_gpr[rS(ctx->opcode)], addr);
9228 }
9229
9230 static inline void gen_op_evstwhe(DisasContext *ctx, TCGv addr)
9231 {
9232     TCGv t0 = tcg_temp_new();
9233     tcg_gen_shri_tl(t0, cpu_gprh[rS(ctx->opcode)], 16);
9234     gen_qemu_st16(ctx, t0, addr);
9235     gen_addr_add(ctx, addr, addr, 2);
9236     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 16);
9237     gen_qemu_st16(ctx, t0, addr);
9238     tcg_temp_free(t0);
9239 }
9240
9241 static inline void gen_op_evstwho(DisasContext *ctx, TCGv addr)
9242 {
9243     gen_qemu_st16(ctx, cpu_gprh[rS(ctx->opcode)], addr);
9244     gen_addr_add(ctx, addr, addr, 2);
9245     gen_qemu_st16(ctx, cpu_gpr[rS(ctx->opcode)], addr);
9246 }
9247
9248 static inline void gen_op_evstwwe(DisasContext *ctx, TCGv addr)
9249 {
9250     gen_qemu_st32(ctx, cpu_gprh[rS(ctx->opcode)], addr);
9251 }
9252
9253 static inline void gen_op_evstwwo(DisasContext *ctx, TCGv addr)
9254 {
9255     gen_qemu_st32(ctx, cpu_gpr[rS(ctx->opcode)], addr);
9256 }
9257
9258 #define GEN_SPEOP_LDST(name, opc2, sh)                                        \
9259 static void glue(gen_, name)(DisasContext *ctx)                                       \
9260 {                                                                             \
9261     TCGv t0;                                                                  \
9262     if (unlikely(!ctx->spe_enabled)) {                                        \
9263         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
9264         return;                                                               \
9265     }                                                                         \
9266     gen_set_access_type(ctx, ACCESS_INT);                                     \
9267     t0 = tcg_temp_new();                                                      \
9268     if (Rc(ctx->opcode)) {                                                    \
9269         gen_addr_spe_imm_index(ctx, t0, sh);                                  \
9270     } else {                                                                  \
9271         gen_addr_reg_index(ctx, t0);                                          \
9272     }                                                                         \
9273     gen_op_##name(ctx, t0);                                                   \
9274     tcg_temp_free(t0);                                                        \
9275 }
9276
9277 GEN_SPEOP_LDST(evldd, 0x00, 3);
9278 GEN_SPEOP_LDST(evldw, 0x01, 3);
9279 GEN_SPEOP_LDST(evldh, 0x02, 3);
9280 GEN_SPEOP_LDST(evlhhesplat, 0x04, 1);
9281 GEN_SPEOP_LDST(evlhhousplat, 0x06, 1);
9282 GEN_SPEOP_LDST(evlhhossplat, 0x07, 1);
9283 GEN_SPEOP_LDST(evlwhe, 0x08, 2);
9284 GEN_SPEOP_LDST(evlwhou, 0x0A, 2);
9285 GEN_SPEOP_LDST(evlwhos, 0x0B, 2);
9286 GEN_SPEOP_LDST(evlwwsplat, 0x0C, 2);
9287 GEN_SPEOP_LDST(evlwhsplat, 0x0E, 2);
9288
9289 GEN_SPEOP_LDST(evstdd, 0x10, 3);
9290 GEN_SPEOP_LDST(evstdw, 0x11, 3);
9291 GEN_SPEOP_LDST(evstdh, 0x12, 3);
9292 GEN_SPEOP_LDST(evstwhe, 0x18, 2);
9293 GEN_SPEOP_LDST(evstwho, 0x1A, 2);
9294 GEN_SPEOP_LDST(evstwwe, 0x1C, 2);
9295 GEN_SPEOP_LDST(evstwwo, 0x1E, 2);
9296
9297 /* Multiply and add - TODO */
9298 #if 0
9299 GEN_SPE(speundef,       evmhessf,      0x01, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);//
9300 GEN_SPE(speundef,       evmhossf,      0x03, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9301 GEN_SPE(evmheumi,       evmhesmi,      0x04, 0x10, 0x00000000, 0x00000000, PPC_SPE);
9302 GEN_SPE(speundef,       evmhesmf,      0x05, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9303 GEN_SPE(evmhoumi,       evmhosmi,      0x06, 0x10, 0x00000000, 0x00000000, PPC_SPE);
9304 GEN_SPE(speundef,       evmhosmf,      0x07, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9305 GEN_SPE(speundef,       evmhessfa,     0x11, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9306 GEN_SPE(speundef,       evmhossfa,     0x13, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9307 GEN_SPE(evmheumia,      evmhesmia,     0x14, 0x10, 0x00000000, 0x00000000, PPC_SPE);
9308 GEN_SPE(speundef,       evmhesmfa,     0x15, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9309 GEN_SPE(evmhoumia,      evmhosmia,     0x16, 0x10, 0x00000000, 0x00000000, PPC_SPE);
9310 GEN_SPE(speundef,       evmhosmfa,     0x17, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9311
9312 GEN_SPE(speundef,       evmwhssf,      0x03, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9313 GEN_SPE(evmwlumi,       speundef,      0x04, 0x11, 0x00000000, 0xFFFFFFFF, PPC_SPE);
9314 GEN_SPE(evmwhumi,       evmwhsmi,      0x06, 0x11, 0x00000000, 0x00000000, PPC_SPE);
9315 GEN_SPE(speundef,       evmwhsmf,      0x07, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9316 GEN_SPE(speundef,       evmwssf,       0x09, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9317 GEN_SPE(speundef,       evmwsmf,       0x0D, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9318 GEN_SPE(speundef,       evmwhssfa,     0x13, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9319 GEN_SPE(evmwlumia,      speundef,      0x14, 0x11, 0x00000000, 0xFFFFFFFF, PPC_SPE);
9320 GEN_SPE(evmwhumia,      evmwhsmia,     0x16, 0x11, 0x00000000, 0x00000000, PPC_SPE);
9321 GEN_SPE(speundef,       evmwhsmfa,     0x17, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9322 GEN_SPE(speundef,       evmwssfa,      0x19, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9323 GEN_SPE(speundef,       evmwsmfa,      0x1D, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9324
9325 GEN_SPE(evadduiaaw,     evaddsiaaw,    0x00, 0x13, 0x0000F800, 0x0000F800, PPC_SPE);
9326 GEN_SPE(evsubfusiaaw,   evsubfssiaaw,  0x01, 0x13, 0x0000F800, 0x0000F800, PPC_SPE);
9327 GEN_SPE(evaddumiaaw,    evaddsmiaaw,   0x04, 0x13, 0x0000F800, 0x0000F800, PPC_SPE);
9328 GEN_SPE(evsubfumiaaw,   evsubfsmiaaw,  0x05, 0x13, 0x0000F800, 0x0000F800, PPC_SPE);
9329 GEN_SPE(evdivws,        evdivwu,       0x06, 0x13, 0x00000000, 0x00000000, PPC_SPE);
9330
9331 GEN_SPE(evmheusiaaw,    evmhessiaaw,   0x00, 0x14, 0x00000000, 0x00000000, PPC_SPE);
9332 GEN_SPE(speundef,       evmhessfaaw,   0x01, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9333 GEN_SPE(evmhousiaaw,    evmhossiaaw,   0x02, 0x14, 0x00000000, 0x00000000, PPC_SPE);
9334 GEN_SPE(speundef,       evmhossfaaw,   0x03, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9335 GEN_SPE(evmheumiaaw,    evmhesmiaaw,   0x04, 0x14, 0x00000000, 0x00000000, PPC_SPE);
9336 GEN_SPE(speundef,       evmhesmfaaw,   0x05, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9337 GEN_SPE(evmhoumiaaw,    evmhosmiaaw,   0x06, 0x14, 0x00000000, 0x00000000, PPC_SPE);
9338 GEN_SPE(speundef,       evmhosmfaaw,   0x07, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9339 GEN_SPE(evmhegumiaa,    evmhegsmiaa,   0x14, 0x14, 0x00000000, 0x00000000, PPC_SPE);
9340 GEN_SPE(speundef,       evmhegsmfaa,   0x15, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9341 GEN_SPE(evmhogumiaa,    evmhogsmiaa,   0x16, 0x14, 0x00000000, 0x00000000, PPC_SPE);
9342 GEN_SPE(speundef,       evmhogsmfaa,   0x17, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9343
9344 GEN_SPE(evmwlusiaaw,    evmwlssiaaw,   0x00, 0x15, 0x00000000, 0x00000000, PPC_SPE);
9345 GEN_SPE(evmwlumiaaw,    evmwlsmiaaw,   0x04, 0x15, 0x00000000, 0x00000000, PPC_SPE);
9346 GEN_SPE(speundef,       evmwssfaa,     0x09, 0x15, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9347 GEN_SPE(speundef,       evmwsmfaa,     0x0D, 0x15, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9348
9349 GEN_SPE(evmheusianw,    evmhessianw,   0x00, 0x16, 0x00000000, 0x00000000, PPC_SPE);
9350 GEN_SPE(speundef,       evmhessfanw,   0x01, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9351 GEN_SPE(evmhousianw,    evmhossianw,   0x02, 0x16, 0x00000000, 0x00000000, PPC_SPE);
9352 GEN_SPE(speundef,       evmhossfanw,   0x03, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9353 GEN_SPE(evmheumianw,    evmhesmianw,   0x04, 0x16, 0x00000000, 0x00000000, PPC_SPE);
9354 GEN_SPE(speundef,       evmhesmfanw,   0x05, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9355 GEN_SPE(evmhoumianw,    evmhosmianw,   0x06, 0x16, 0x00000000, 0x00000000, PPC_SPE);
9356 GEN_SPE(speundef,       evmhosmfanw,   0x07, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9357 GEN_SPE(evmhegumian,    evmhegsmian,   0x14, 0x16, 0x00000000, 0x00000000, PPC_SPE);
9358 GEN_SPE(speundef,       evmhegsmfan,   0x15, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9359 GEN_SPE(evmhigumian,    evmhigsmian,   0x16, 0x16, 0x00000000, 0x00000000, PPC_SPE);
9360 GEN_SPE(speundef,       evmhogsmfan,   0x17, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9361
9362 GEN_SPE(evmwlusianw,    evmwlssianw,   0x00, 0x17, 0x00000000, 0x00000000, PPC_SPE);
9363 GEN_SPE(evmwlumianw,    evmwlsmianw,   0x04, 0x17, 0x00000000, 0x00000000, PPC_SPE);
9364 GEN_SPE(speundef,       evmwssfan,     0x09, 0x17, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9365 GEN_SPE(evmwumian,      evmwsmian,     0x0C, 0x17, 0x00000000, 0x00000000, PPC_SPE);
9366 GEN_SPE(speundef,       evmwsmfan,     0x0D, 0x17, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9367 #endif
9368
9369 /***                      SPE floating-point extension                     ***/
9370 #define GEN_SPEFPUOP_CONV_32_32(name)                                         \
9371 static inline void gen_##name(DisasContext *ctx)                              \
9372 {                                                                             \
9373     TCGv_i32 t0 = tcg_temp_new_i32();                                         \
9374     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rB(ctx->opcode)]);                       \
9375     gen_helper_##name(t0, cpu_env, t0);                                       \
9376     tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0);                        \
9377     tcg_temp_free_i32(t0);                                                    \
9378 }
9379 #define GEN_SPEFPUOP_CONV_32_64(name)                                         \
9380 static inline void gen_##name(DisasContext *ctx)                              \
9381 {                                                                             \
9382     TCGv_i64 t0 = tcg_temp_new_i64();                                         \
9383     TCGv_i32 t1 = tcg_temp_new_i32();                                         \
9384     gen_load_gpr64(t0, rB(ctx->opcode));                                      \
9385     gen_helper_##name(t1, cpu_env, t0);                                       \
9386     tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t1);                        \
9387     tcg_temp_free_i64(t0);                                                    \
9388     tcg_temp_free_i32(t1);                                                    \
9389 }
9390 #define GEN_SPEFPUOP_CONV_64_32(name)                                         \
9391 static inline void gen_##name(DisasContext *ctx)                              \
9392 {                                                                             \
9393     TCGv_i64 t0 = tcg_temp_new_i64();                                         \
9394     TCGv_i32 t1 = tcg_temp_new_i32();                                         \
9395     tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);                       \
9396     gen_helper_##name(t0, cpu_env, t1);                                       \
9397     gen_store_gpr64(rD(ctx->opcode), t0);                                     \
9398     tcg_temp_free_i64(t0);                                                    \
9399     tcg_temp_free_i32(t1);                                                    \
9400 }
9401 #define GEN_SPEFPUOP_CONV_64_64(name)                                         \
9402 static inline void gen_##name(DisasContext *ctx)                              \
9403 {                                                                             \
9404     TCGv_i64 t0 = tcg_temp_new_i64();                                         \
9405     gen_load_gpr64(t0, rB(ctx->opcode));                                      \
9406     gen_helper_##name(t0, cpu_env, t0);                                       \
9407     gen_store_gpr64(rD(ctx->opcode), t0);                                     \
9408     tcg_temp_free_i64(t0);                                                    \
9409 }
9410 #define GEN_SPEFPUOP_ARITH2_32_32(name)                                       \
9411 static inline void gen_##name(DisasContext *ctx)                              \
9412 {                                                                             \
9413     TCGv_i32 t0, t1;                                                          \
9414     if (unlikely(!ctx->spe_enabled)) {                                        \
9415         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
9416         return;                                                               \
9417     }                                                                         \
9418     t0 = tcg_temp_new_i32();                                                  \
9419     t1 = tcg_temp_new_i32();                                                  \
9420     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);                       \
9421     tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);                       \
9422     gen_helper_##name(t0, cpu_env, t0, t1);                                   \
9423     tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0);                        \
9424                                                                               \
9425     tcg_temp_free_i32(t0);                                                    \
9426     tcg_temp_free_i32(t1);                                                    \
9427 }
9428 #define GEN_SPEFPUOP_ARITH2_64_64(name)                                       \
9429 static inline void gen_##name(DisasContext *ctx)                              \
9430 {                                                                             \
9431     TCGv_i64 t0, t1;                                                          \
9432     if (unlikely(!ctx->spe_enabled)) {                                        \
9433         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
9434         return;                                                               \
9435     }                                                                         \
9436     t0 = tcg_temp_new_i64();                                                  \
9437     t1 = tcg_temp_new_i64();                                                  \
9438     gen_load_gpr64(t0, rA(ctx->opcode));                                      \
9439     gen_load_gpr64(t1, rB(ctx->opcode));                                      \
9440     gen_helper_##name(t0, cpu_env, t0, t1);                                   \
9441     gen_store_gpr64(rD(ctx->opcode), t0);                                     \
9442     tcg_temp_free_i64(t0);                                                    \
9443     tcg_temp_free_i64(t1);                                                    \
9444 }
9445 #define GEN_SPEFPUOP_COMP_32(name)                                            \
9446 static inline void gen_##name(DisasContext *ctx)                              \
9447 {                                                                             \
9448     TCGv_i32 t0, t1;                                                          \
9449     if (unlikely(!ctx->spe_enabled)) {                                        \
9450         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
9451         return;                                                               \
9452     }                                                                         \
9453     t0 = tcg_temp_new_i32();                                                  \
9454     t1 = tcg_temp_new_i32();                                                  \
9455                                                                               \
9456     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);                       \
9457     tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);                       \
9458     gen_helper_##name(cpu_crf[crfD(ctx->opcode)], cpu_env, t0, t1);           \
9459                                                                               \
9460     tcg_temp_free_i32(t0);                                                    \
9461     tcg_temp_free_i32(t1);                                                    \
9462 }
9463 #define GEN_SPEFPUOP_COMP_64(name)                                            \
9464 static inline void gen_##name(DisasContext *ctx)                              \
9465 {                                                                             \
9466     TCGv_i64 t0, t1;                                                          \
9467     if (unlikely(!ctx->spe_enabled)) {                                        \
9468         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
9469         return;                                                               \
9470     }                                                                         \
9471     t0 = tcg_temp_new_i64();                                                  \
9472     t1 = tcg_temp_new_i64();                                                  \
9473     gen_load_gpr64(t0, rA(ctx->opcode));                                      \
9474     gen_load_gpr64(t1, rB(ctx->opcode));                                      \
9475     gen_helper_##name(cpu_crf[crfD(ctx->opcode)], cpu_env, t0, t1);           \
9476     tcg_temp_free_i64(t0);                                                    \
9477     tcg_temp_free_i64(t1);                                                    \
9478 }
9479
9480 /* Single precision floating-point vectors operations */
9481 /* Arithmetic */
9482 GEN_SPEFPUOP_ARITH2_64_64(evfsadd);
9483 GEN_SPEFPUOP_ARITH2_64_64(evfssub);
9484 GEN_SPEFPUOP_ARITH2_64_64(evfsmul);
9485 GEN_SPEFPUOP_ARITH2_64_64(evfsdiv);
9486 static inline void gen_evfsabs(DisasContext *ctx)
9487 {
9488     if (unlikely(!ctx->spe_enabled)) {
9489         gen_exception(ctx, POWERPC_EXCP_SPEU);
9490         return;
9491     }
9492     tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
9493                     ~0x80000000);
9494     tcg_gen_andi_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],
9495                     ~0x80000000);
9496 }
9497 static inline void gen_evfsnabs(DisasContext *ctx)
9498 {
9499     if (unlikely(!ctx->spe_enabled)) {
9500         gen_exception(ctx, POWERPC_EXCP_SPEU);
9501         return;
9502     }
9503     tcg_gen_ori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
9504                    0x80000000);
9505     tcg_gen_ori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],
9506                    0x80000000);
9507 }
9508 static inline void gen_evfsneg(DisasContext *ctx)
9509 {
9510     if (unlikely(!ctx->spe_enabled)) {
9511         gen_exception(ctx, POWERPC_EXCP_SPEU);
9512         return;
9513     }
9514     tcg_gen_xori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
9515                     0x80000000);
9516     tcg_gen_xori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],
9517                     0x80000000);
9518 }
9519
9520 /* Conversion */
9521 GEN_SPEFPUOP_CONV_64_64(evfscfui);
9522 GEN_SPEFPUOP_CONV_64_64(evfscfsi);
9523 GEN_SPEFPUOP_CONV_64_64(evfscfuf);
9524 GEN_SPEFPUOP_CONV_64_64(evfscfsf);
9525 GEN_SPEFPUOP_CONV_64_64(evfsctui);
9526 GEN_SPEFPUOP_CONV_64_64(evfsctsi);
9527 GEN_SPEFPUOP_CONV_64_64(evfsctuf);
9528 GEN_SPEFPUOP_CONV_64_64(evfsctsf);
9529 GEN_SPEFPUOP_CONV_64_64(evfsctuiz);
9530 GEN_SPEFPUOP_CONV_64_64(evfsctsiz);
9531
9532 /* Comparison */
9533 GEN_SPEFPUOP_COMP_64(evfscmpgt);
9534 GEN_SPEFPUOP_COMP_64(evfscmplt);
9535 GEN_SPEFPUOP_COMP_64(evfscmpeq);
9536 GEN_SPEFPUOP_COMP_64(evfststgt);
9537 GEN_SPEFPUOP_COMP_64(evfststlt);
9538 GEN_SPEFPUOP_COMP_64(evfststeq);
9539
9540 /* Opcodes definitions */
9541 GEN_SPE(evfsadd,   evfssub,   0x00, 0x0A, 0x00000000, 0x00000000, PPC_SPE_SINGLE); //
9542 GEN_SPE(evfsabs,   evfsnabs,  0x02, 0x0A, 0x0000F800, 0x0000F800, PPC_SPE_SINGLE); //
9543 GEN_SPE(evfsneg,   speundef,  0x03, 0x0A, 0x0000F800, 0xFFFFFFFF, PPC_SPE_SINGLE); //
9544 GEN_SPE(evfsmul,   evfsdiv,   0x04, 0x0A, 0x00000000, 0x00000000, PPC_SPE_SINGLE); //
9545 GEN_SPE(evfscmpgt, evfscmplt, 0x06, 0x0A, 0x00600000, 0x00600000, PPC_SPE_SINGLE); //
9546 GEN_SPE(evfscmpeq, speundef,  0x07, 0x0A, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
9547 GEN_SPE(evfscfui,  evfscfsi,  0x08, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
9548 GEN_SPE(evfscfuf,  evfscfsf,  0x09, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
9549 GEN_SPE(evfsctui,  evfsctsi,  0x0A, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
9550 GEN_SPE(evfsctuf,  evfsctsf,  0x0B, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
9551 GEN_SPE(evfsctuiz, speundef,  0x0C, 0x0A, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
9552 GEN_SPE(evfsctsiz, speundef,  0x0D, 0x0A, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
9553 GEN_SPE(evfststgt, evfststlt, 0x0E, 0x0A, 0x00600000, 0x00600000, PPC_SPE_SINGLE); //
9554 GEN_SPE(evfststeq, speundef,  0x0F, 0x0A, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
9555
9556 /* Single precision floating-point operations */
9557 /* Arithmetic */
9558 GEN_SPEFPUOP_ARITH2_32_32(efsadd);
9559 GEN_SPEFPUOP_ARITH2_32_32(efssub);
9560 GEN_SPEFPUOP_ARITH2_32_32(efsmul);
9561 GEN_SPEFPUOP_ARITH2_32_32(efsdiv);
9562 static inline void gen_efsabs(DisasContext *ctx)
9563 {
9564     if (unlikely(!ctx->spe_enabled)) {
9565         gen_exception(ctx, POWERPC_EXCP_SPEU);
9566         return;
9567     }
9568     tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], (target_long)~0x80000000LL);
9569 }
9570 static inline void gen_efsnabs(DisasContext *ctx)
9571 {
9572     if (unlikely(!ctx->spe_enabled)) {
9573         gen_exception(ctx, POWERPC_EXCP_SPEU);
9574         return;
9575     }
9576     tcg_gen_ori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
9577 }
9578 static inline void gen_efsneg(DisasContext *ctx)
9579 {
9580     if (unlikely(!ctx->spe_enabled)) {
9581         gen_exception(ctx, POWERPC_EXCP_SPEU);
9582         return;
9583     }
9584     tcg_gen_xori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
9585 }
9586
9587 /* Conversion */
9588 GEN_SPEFPUOP_CONV_32_32(efscfui);
9589 GEN_SPEFPUOP_CONV_32_32(efscfsi);
9590 GEN_SPEFPUOP_CONV_32_32(efscfuf);
9591 GEN_SPEFPUOP_CONV_32_32(efscfsf);
9592 GEN_SPEFPUOP_CONV_32_32(efsctui);
9593 GEN_SPEFPUOP_CONV_32_32(efsctsi);
9594 GEN_SPEFPUOP_CONV_32_32(efsctuf);
9595 GEN_SPEFPUOP_CONV_32_32(efsctsf);
9596 GEN_SPEFPUOP_CONV_32_32(efsctuiz);
9597 GEN_SPEFPUOP_CONV_32_32(efsctsiz);
9598 GEN_SPEFPUOP_CONV_32_64(efscfd);
9599
9600 /* Comparison */
9601 GEN_SPEFPUOP_COMP_32(efscmpgt);
9602 GEN_SPEFPUOP_COMP_32(efscmplt);
9603 GEN_SPEFPUOP_COMP_32(efscmpeq);
9604 GEN_SPEFPUOP_COMP_32(efststgt);
9605 GEN_SPEFPUOP_COMP_32(efststlt);
9606 GEN_SPEFPUOP_COMP_32(efststeq);
9607
9608 /* Opcodes definitions */
9609 GEN_SPE(efsadd,   efssub,   0x00, 0x0B, 0x00000000, 0x00000000, PPC_SPE_SINGLE); //
9610 GEN_SPE(efsabs,   efsnabs,  0x02, 0x0B, 0x0000F800, 0x0000F800, PPC_SPE_SINGLE); //
9611 GEN_SPE(efsneg,   speundef, 0x03, 0x0B, 0x0000F800, 0xFFFFFFFF, PPC_SPE_SINGLE); //
9612 GEN_SPE(efsmul,   efsdiv,   0x04, 0x0B, 0x00000000, 0x00000000, PPC_SPE_SINGLE); //
9613 GEN_SPE(efscmpgt, efscmplt, 0x06, 0x0B, 0x00600000, 0x00600000, PPC_SPE_SINGLE); //
9614 GEN_SPE(efscmpeq, efscfd,   0x07, 0x0B, 0x00600000, 0x00180000, PPC_SPE_SINGLE); //
9615 GEN_SPE(efscfui,  efscfsi,  0x08, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
9616 GEN_SPE(efscfuf,  efscfsf,  0x09, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
9617 GEN_SPE(efsctui,  efsctsi,  0x0A, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
9618 GEN_SPE(efsctuf,  efsctsf,  0x0B, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
9619 GEN_SPE(efsctuiz, speundef, 0x0C, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
9620 GEN_SPE(efsctsiz, speundef, 0x0D, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
9621 GEN_SPE(efststgt, efststlt, 0x0E, 0x0B, 0x00600000, 0x00600000, PPC_SPE_SINGLE); //
9622 GEN_SPE(efststeq, speundef, 0x0F, 0x0B, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
9623
9624 /* Double precision floating-point operations */
9625 /* Arithmetic */
9626 GEN_SPEFPUOP_ARITH2_64_64(efdadd);
9627 GEN_SPEFPUOP_ARITH2_64_64(efdsub);
9628 GEN_SPEFPUOP_ARITH2_64_64(efdmul);
9629 GEN_SPEFPUOP_ARITH2_64_64(efddiv);
9630 static inline void gen_efdabs(DisasContext *ctx)
9631 {
9632     if (unlikely(!ctx->spe_enabled)) {
9633         gen_exception(ctx, POWERPC_EXCP_SPEU);
9634         return;
9635     }
9636     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
9637     tcg_gen_andi_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],
9638                     ~0x80000000);
9639 }
9640 static inline void gen_efdnabs(DisasContext *ctx)
9641 {
9642     if (unlikely(!ctx->spe_enabled)) {
9643         gen_exception(ctx, POWERPC_EXCP_SPEU);
9644         return;
9645     }
9646     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
9647     tcg_gen_ori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],
9648                    0x80000000);
9649 }
9650 static inline void gen_efdneg(DisasContext *ctx)
9651 {
9652     if (unlikely(!ctx->spe_enabled)) {
9653         gen_exception(ctx, POWERPC_EXCP_SPEU);
9654         return;
9655     }
9656     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
9657     tcg_gen_xori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],
9658                     0x80000000);
9659 }
9660
9661 /* Conversion */
9662 GEN_SPEFPUOP_CONV_64_32(efdcfui);
9663 GEN_SPEFPUOP_CONV_64_32(efdcfsi);
9664 GEN_SPEFPUOP_CONV_64_32(efdcfuf);
9665 GEN_SPEFPUOP_CONV_64_32(efdcfsf);
9666 GEN_SPEFPUOP_CONV_32_64(efdctui);
9667 GEN_SPEFPUOP_CONV_32_64(efdctsi);
9668 GEN_SPEFPUOP_CONV_32_64(efdctuf);
9669 GEN_SPEFPUOP_CONV_32_64(efdctsf);
9670 GEN_SPEFPUOP_CONV_32_64(efdctuiz);
9671 GEN_SPEFPUOP_CONV_32_64(efdctsiz);
9672 GEN_SPEFPUOP_CONV_64_32(efdcfs);
9673 GEN_SPEFPUOP_CONV_64_64(efdcfuid);
9674 GEN_SPEFPUOP_CONV_64_64(efdcfsid);
9675 GEN_SPEFPUOP_CONV_64_64(efdctuidz);
9676 GEN_SPEFPUOP_CONV_64_64(efdctsidz);
9677
9678 /* Comparison */
9679 GEN_SPEFPUOP_COMP_64(efdcmpgt);
9680 GEN_SPEFPUOP_COMP_64(efdcmplt);
9681 GEN_SPEFPUOP_COMP_64(efdcmpeq);
9682 GEN_SPEFPUOP_COMP_64(efdtstgt);
9683 GEN_SPEFPUOP_COMP_64(efdtstlt);
9684 GEN_SPEFPUOP_COMP_64(efdtsteq);
9685
9686 /* Opcodes definitions */
9687 GEN_SPE(efdadd,    efdsub,    0x10, 0x0B, 0x00000000, 0x00000000, PPC_SPE_DOUBLE); //
9688 GEN_SPE(efdcfuid,  efdcfsid,  0x11, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
9689 GEN_SPE(efdabs,    efdnabs,   0x12, 0x0B, 0x0000F800, 0x0000F800, PPC_SPE_DOUBLE); //
9690 GEN_SPE(efdneg,    speundef,  0x13, 0x0B, 0x0000F800, 0xFFFFFFFF, PPC_SPE_DOUBLE); //
9691 GEN_SPE(efdmul,    efddiv,    0x14, 0x0B, 0x00000000, 0x00000000, PPC_SPE_DOUBLE); //
9692 GEN_SPE(efdctuidz, efdctsidz, 0x15, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
9693 GEN_SPE(efdcmpgt,  efdcmplt,  0x16, 0x0B, 0x00600000, 0x00600000, PPC_SPE_DOUBLE); //
9694 GEN_SPE(efdcmpeq,  efdcfs,    0x17, 0x0B, 0x00600000, 0x00180000, PPC_SPE_DOUBLE); //
9695 GEN_SPE(efdcfui,   efdcfsi,   0x18, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
9696 GEN_SPE(efdcfuf,   efdcfsf,   0x19, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
9697 GEN_SPE(efdctui,   efdctsi,   0x1A, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
9698 GEN_SPE(efdctuf,   efdctsf,   0x1B, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
9699 GEN_SPE(efdctuiz,  speundef,  0x1C, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_DOUBLE); //
9700 GEN_SPE(efdctsiz,  speundef,  0x1D, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_DOUBLE); //
9701 GEN_SPE(efdtstgt,  efdtstlt,  0x1E, 0x0B, 0x00600000, 0x00600000, PPC_SPE_DOUBLE); //
9702 GEN_SPE(efdtsteq,  speundef,  0x1F, 0x0B, 0x00600000, 0xFFFFFFFF, PPC_SPE_DOUBLE); //
9703
9704 static void gen_tbegin(DisasContext *ctx)
9705 {
9706     if (unlikely(!ctx->tm_enabled)) {
9707         gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_TM);
9708         return;
9709     }
9710     gen_helper_tbegin(cpu_env);
9711 }
9712
9713 #define GEN_TM_NOOP(name)                                      \
9714 static inline void gen_##name(DisasContext *ctx)               \
9715 {                                                              \
9716     if (unlikely(!ctx->tm_enabled)) {                          \
9717         gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_TM);   \
9718         return;                                                \
9719     }                                                          \
9720     /* Because tbegin always fails in QEMU, these user         \
9721      * space instructions all have a simple implementation:    \
9722      *                                                         \
9723      *     CR[0] = 0b0 || MSR[TS] || 0b0                       \
9724      *           = 0b0 || 0b00    || 0b0                       \
9725      */                                                        \
9726     tcg_gen_movi_i32(cpu_crf[0], 0);                           \
9727 }
9728
9729 GEN_TM_NOOP(tend);
9730 GEN_TM_NOOP(tabort);
9731 GEN_TM_NOOP(tabortwc);
9732 GEN_TM_NOOP(tabortwci);
9733 GEN_TM_NOOP(tabortdc);
9734 GEN_TM_NOOP(tabortdci);
9735 GEN_TM_NOOP(tsr);
9736
9737 static void gen_tcheck(DisasContext *ctx)
9738 {
9739     if (unlikely(!ctx->tm_enabled)) {
9740         gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_TM);
9741         return;
9742     }
9743     /* Because tbegin always fails, the tcheck implementation
9744      * is simple:
9745      *
9746      * CR[CRF] = TDOOMED || MSR[TS] || 0b0
9747      *         = 0b1 || 0b00 || 0b0
9748      */
9749     tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)], 0x8);
9750 }
9751
9752 #if defined(CONFIG_USER_ONLY)
9753 #define GEN_TM_PRIV_NOOP(name)                                 \
9754 static inline void gen_##name(DisasContext *ctx)               \
9755 {                                                              \
9756     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);           \
9757 }
9758
9759 #else
9760
9761 #define GEN_TM_PRIV_NOOP(name)                                 \
9762 static inline void gen_##name(DisasContext *ctx)               \
9763 {                                                              \
9764     if (unlikely(ctx->pr)) {                                   \
9765         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);       \
9766         return;                                                \
9767     }                                                          \
9768     if (unlikely(!ctx->tm_enabled)) {                          \
9769         gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_TM);   \
9770         return;                                                \
9771     }                                                          \
9772     /* Because tbegin always fails, the implementation is      \
9773      * simple:                                                 \
9774      *                                                         \
9775      *   CR[0] = 0b0 || MSR[TS] || 0b0                         \
9776      *         = 0b0 || 0b00 | 0b0                             \
9777      */                                                        \
9778     tcg_gen_movi_i32(cpu_crf[0], 0);                           \
9779 }
9780
9781 #endif
9782
9783 GEN_TM_PRIV_NOOP(treclaim);
9784 GEN_TM_PRIV_NOOP(trechkpt);
9785
9786 static opcode_t opcodes[] = {
9787 GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE),
9788 GEN_HANDLER(cmp, 0x1F, 0x00, 0x00, 0x00400000, PPC_INTEGER),
9789 GEN_HANDLER(cmpi, 0x0B, 0xFF, 0xFF, 0x00400000, PPC_INTEGER),
9790 GEN_HANDLER(cmpl, 0x1F, 0x00, 0x01, 0x00400000, PPC_INTEGER),
9791 GEN_HANDLER(cmpli, 0x0A, 0xFF, 0xFF, 0x00400000, PPC_INTEGER),
9792 GEN_HANDLER_E(cmpb, 0x1F, 0x1C, 0x0F, 0x00000001, PPC_NONE, PPC2_ISA205),
9793 GEN_HANDLER(isel, 0x1F, 0x0F, 0xFF, 0x00000001, PPC_ISEL),
9794 GEN_HANDLER(addi, 0x0E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9795 GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9796 GEN_HANDLER2(addic_, "addic.", 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9797 GEN_HANDLER(addis, 0x0F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9798 GEN_HANDLER(mulhw, 0x1F, 0x0B, 0x02, 0x00000400, PPC_INTEGER),
9799 GEN_HANDLER(mulhwu, 0x1F, 0x0B, 0x00, 0x00000400, PPC_INTEGER),
9800 GEN_HANDLER(mullw, 0x1F, 0x0B, 0x07, 0x00000000, PPC_INTEGER),
9801 GEN_HANDLER(mullwo, 0x1F, 0x0B, 0x17, 0x00000000, PPC_INTEGER),
9802 GEN_HANDLER(mulli, 0x07, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9803 #if defined(TARGET_PPC64)
9804 GEN_HANDLER(mulld, 0x1F, 0x09, 0x07, 0x00000000, PPC_64B),
9805 #endif
9806 GEN_HANDLER(neg, 0x1F, 0x08, 0x03, 0x0000F800, PPC_INTEGER),
9807 GEN_HANDLER(nego, 0x1F, 0x08, 0x13, 0x0000F800, PPC_INTEGER),
9808 GEN_HANDLER(subfic, 0x08, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9809 GEN_HANDLER2(andi_, "andi.", 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9810 GEN_HANDLER2(andis_, "andis.", 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9811 GEN_HANDLER(cntlzw, 0x1F, 0x1A, 0x00, 0x00000000, PPC_INTEGER),
9812 GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER),
9813 GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER),
9814 GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9815 GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9816 GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9817 GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9818 GEN_HANDLER(popcntb, 0x1F, 0x1A, 0x03, 0x0000F801, PPC_POPCNTB),
9819 GEN_HANDLER(popcntw, 0x1F, 0x1A, 0x0b, 0x0000F801, PPC_POPCNTWD),
9820 GEN_HANDLER_E(prtyw, 0x1F, 0x1A, 0x04, 0x0000F801, PPC_NONE, PPC2_ISA205),
9821 #if defined(TARGET_PPC64)
9822 GEN_HANDLER(popcntd, 0x1F, 0x1A, 0x0F, 0x0000F801, PPC_POPCNTWD),
9823 GEN_HANDLER(cntlzd, 0x1F, 0x1A, 0x01, 0x00000000, PPC_64B),
9824 GEN_HANDLER_E(prtyd, 0x1F, 0x1A, 0x05, 0x0000F801, PPC_NONE, PPC2_ISA205),
9825 GEN_HANDLER_E(bpermd, 0x1F, 0x1C, 0x07, 0x00000001, PPC_NONE, PPC2_PERM_ISA206),
9826 #endif
9827 GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9828 GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9829 GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9830 GEN_HANDLER(slw, 0x1F, 0x18, 0x00, 0x00000000, PPC_INTEGER),
9831 GEN_HANDLER(sraw, 0x1F, 0x18, 0x18, 0x00000000, PPC_INTEGER),
9832 GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER),
9833 GEN_HANDLER(srw, 0x1F, 0x18, 0x10, 0x00000000, PPC_INTEGER),
9834 #if defined(TARGET_PPC64)
9835 GEN_HANDLER(sld, 0x1F, 0x1B, 0x00, 0x00000000, PPC_64B),
9836 GEN_HANDLER(srad, 0x1F, 0x1A, 0x18, 0x00000000, PPC_64B),
9837 GEN_HANDLER2(sradi0, "sradi", 0x1F, 0x1A, 0x19, 0x00000000, PPC_64B),
9838 GEN_HANDLER2(sradi1, "sradi", 0x1F, 0x1B, 0x19, 0x00000000, PPC_64B),
9839 GEN_HANDLER(srd, 0x1F, 0x1B, 0x10, 0x00000000, PPC_64B),
9840 #endif
9841 GEN_HANDLER(frsqrtes, 0x3B, 0x1A, 0xFF, 0x001F07C0, PPC_FLOAT_FRSQRTES),
9842 GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT),
9843 GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT),
9844 GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT),
9845 GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT),
9846 GEN_HANDLER(fabs, 0x3F, 0x08, 0x08, 0x001F0000, PPC_FLOAT),
9847 GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT),
9848 GEN_HANDLER(fnabs, 0x3F, 0x08, 0x04, 0x001F0000, PPC_FLOAT),
9849 GEN_HANDLER(fneg, 0x3F, 0x08, 0x01, 0x001F0000, PPC_FLOAT),
9850 GEN_HANDLER_E(fcpsgn, 0x3F, 0x08, 0x00, 0x00000000, PPC_NONE, PPC2_ISA205),
9851 GEN_HANDLER_E(fmrgew, 0x3F, 0x06, 0x1E, 0x00000001, PPC_NONE, PPC2_VSX207),
9852 GEN_HANDLER_E(fmrgow, 0x3F, 0x06, 0x1A, 0x00000001, PPC_NONE, PPC2_VSX207),
9853 GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT),
9854 GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT),
9855 GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT),
9856 GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT),
9857 GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x00000000, PPC_FLOAT),
9858 GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006e0800, PPC_FLOAT),
9859 #if defined(TARGET_PPC64)
9860 GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B),
9861 GEN_HANDLER(lq, 0x38, 0xFF, 0xFF, 0x00000000, PPC_64BX),
9862 GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000000, PPC_64B),
9863 #endif
9864 GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9865 GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9866 GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_STRING),
9867 GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_STRING),
9868 GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_STRING),
9869 GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_STRING),
9870 GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FFF801, PPC_MEM_EIEIO),
9871 GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FFF801, PPC_MEM),
9872 GEN_HANDLER_E(lbarx, 0x1F, 0x14, 0x01, 0, PPC_NONE, PPC2_ATOMIC_ISA206),
9873 GEN_HANDLER_E(lharx, 0x1F, 0x14, 0x03, 0, PPC_NONE, PPC2_ATOMIC_ISA206),
9874 GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000000, PPC_RES),
9875 GEN_HANDLER_E(stbcx_, 0x1F, 0x16, 0x15, 0, PPC_NONE, PPC2_ATOMIC_ISA206),
9876 GEN_HANDLER_E(sthcx_, 0x1F, 0x16, 0x16, 0, PPC_NONE, PPC2_ATOMIC_ISA206),
9877 GEN_HANDLER2(stwcx_, "stwcx.", 0x1F, 0x16, 0x04, 0x00000000, PPC_RES),
9878 #if defined(TARGET_PPC64)
9879 GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000000, PPC_64B),
9880 GEN_HANDLER_E(lqarx, 0x1F, 0x14, 0x08, 0, PPC_NONE, PPC2_LSQ_ISA207),
9881 GEN_HANDLER2(stdcx_, "stdcx.", 0x1F, 0x16, 0x06, 0x00000000, PPC_64B),
9882 GEN_HANDLER_E(stqcx_, 0x1F, 0x16, 0x05, 0, PPC_NONE, PPC2_LSQ_ISA207),
9883 #endif
9884 GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x039FF801, PPC_MEM_SYNC),
9885 GEN_HANDLER(wait, 0x1F, 0x1E, 0x01, 0x03FFF801, PPC_WAIT),
9886 GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
9887 GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
9888 GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW),
9889 GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW),
9890 GEN_HANDLER_E(bctar, 0x13, 0x10, 0x11, 0, PPC_NONE, PPC2_BCTAR_ISA207),
9891 GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER),
9892 GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW),
9893 #if defined(TARGET_PPC64)
9894 GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B),
9895 GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64H),
9896 #endif
9897 GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFF01D, PPC_FLOW),
9898 GEN_HANDLER(tw, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW),
9899 GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
9900 #if defined(TARGET_PPC64)
9901 GEN_HANDLER(td, 0x1F, 0x04, 0x02, 0x00000001, PPC_64B),
9902 GEN_HANDLER(tdi, 0x02, 0xFF, 0xFF, 0x00000000, PPC_64B),
9903 #endif
9904 GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC),
9905 GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC),
9906 GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC),
9907 GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC),
9908 GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MFTB),
9909 GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC),
9910 #if defined(TARGET_PPC64)
9911 GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001EF801, PPC_64B),
9912 #endif
9913 GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC),
9914 GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000000, PPC_MISC),
9915 GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03C00001, PPC_CACHE),
9916 GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE),
9917 GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE),
9918 GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x00000001, PPC_CACHE),
9919 GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x00000001, PPC_CACHE),
9920 GEN_HANDLER_E(dcbtls, 0x1F, 0x06, 0x05, 0x02000001, PPC_BOOKE, PPC2_BOOKE206),
9921 GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZ),
9922 GEN_HANDLER(dst, 0x1F, 0x16, 0x0A, 0x01800001, PPC_ALTIVEC),
9923 GEN_HANDLER(dstst, 0x1F, 0x16, 0x0B, 0x02000001, PPC_ALTIVEC),
9924 GEN_HANDLER(dss, 0x1F, 0x16, 0x19, 0x019FF801, PPC_ALTIVEC),
9925 GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE_ICBI),
9926 GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_DCBA),
9927 GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT),
9928 GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT),
9929 GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT),
9930 GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT),
9931 #if defined(TARGET_PPC64)
9932 GEN_HANDLER2(mfsr_64b, "mfsr", 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT_64B),
9933 GEN_HANDLER2(mfsrin_64b, "mfsrin", 0x1F, 0x13, 0x14, 0x001F0001,
9934              PPC_SEGMENT_64B),
9935 GEN_HANDLER2(mtsr_64b, "mtsr", 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B),
9936 GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001,
9937              PPC_SEGMENT_64B),
9938 GEN_HANDLER2(slbmte, "slbmte", 0x1F, 0x12, 0x0C, 0x001F0001, PPC_SEGMENT_64B),
9939 GEN_HANDLER2(slbmfee, "slbmfee", 0x1F, 0x13, 0x1C, 0x001F0001, PPC_SEGMENT_64B),
9940 GEN_HANDLER2(slbmfev, "slbmfev", 0x1F, 0x13, 0x1A, 0x001F0001, PPC_SEGMENT_64B),
9941 #endif
9942 GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA),
9943 GEN_HANDLER(tlbiel, 0x1F, 0x12, 0x08, 0x03FF0001, PPC_MEM_TLBIE),
9944 GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE),
9945 GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC),
9946 #if defined(TARGET_PPC64)
9947 GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x03FFFC01, PPC_SLBI),
9948 GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI),
9949 #endif
9950 GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN),
9951 GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN),
9952 GEN_HANDLER(abs, 0x1F, 0x08, 0x0B, 0x0000F800, PPC_POWER_BR),
9953 GEN_HANDLER(abso, 0x1F, 0x08, 0x1B, 0x0000F800, PPC_POWER_BR),
9954 GEN_HANDLER(clcs, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR),
9955 GEN_HANDLER(div, 0x1F, 0x0B, 0x0A, 0x00000000, PPC_POWER_BR),
9956 GEN_HANDLER(divo, 0x1F, 0x0B, 0x1A, 0x00000000, PPC_POWER_BR),
9957 GEN_HANDLER(divs, 0x1F, 0x0B, 0x0B, 0x00000000, PPC_POWER_BR),
9958 GEN_HANDLER(divso, 0x1F, 0x0B, 0x1B, 0x00000000, PPC_POWER_BR),
9959 GEN_HANDLER(doz, 0x1F, 0x08, 0x08, 0x00000000, PPC_POWER_BR),
9960 GEN_HANDLER(dozo, 0x1F, 0x08, 0x18, 0x00000000, PPC_POWER_BR),
9961 GEN_HANDLER(dozi, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR),
9962 GEN_HANDLER(lscbx, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR),
9963 GEN_HANDLER(maskg, 0x1F, 0x1D, 0x00, 0x00000000, PPC_POWER_BR),
9964 GEN_HANDLER(maskir, 0x1F, 0x1D, 0x10, 0x00000000, PPC_POWER_BR),
9965 GEN_HANDLER(mul, 0x1F, 0x0B, 0x03, 0x00000000, PPC_POWER_BR),
9966 GEN_HANDLER(mulo, 0x1F, 0x0B, 0x13, 0x00000000, PPC_POWER_BR),
9967 GEN_HANDLER(nabs, 0x1F, 0x08, 0x0F, 0x00000000, PPC_POWER_BR),
9968 GEN_HANDLER(nabso, 0x1F, 0x08, 0x1F, 0x00000000, PPC_POWER_BR),
9969 GEN_HANDLER(rlmi, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR),
9970 GEN_HANDLER(rrib, 0x1F, 0x19, 0x10, 0x00000000, PPC_POWER_BR),
9971 GEN_HANDLER(sle, 0x1F, 0x19, 0x04, 0x00000000, PPC_POWER_BR),
9972 GEN_HANDLER(sleq, 0x1F, 0x19, 0x06, 0x00000000, PPC_POWER_BR),
9973 GEN_HANDLER(sliq, 0x1F, 0x18, 0x05, 0x00000000, PPC_POWER_BR),
9974 GEN_HANDLER(slliq, 0x1F, 0x18, 0x07, 0x00000000, PPC_POWER_BR),
9975 GEN_HANDLER(sllq, 0x1F, 0x18, 0x06, 0x00000000, PPC_POWER_BR),
9976 GEN_HANDLER(slq, 0x1F, 0x18, 0x04, 0x00000000, PPC_POWER_BR),
9977 GEN_HANDLER(sraiq, 0x1F, 0x18, 0x1D, 0x00000000, PPC_POWER_BR),
9978 GEN_HANDLER(sraq, 0x1F, 0x18, 0x1C, 0x00000000, PPC_POWER_BR),
9979 GEN_HANDLER(sre, 0x1F, 0x19, 0x14, 0x00000000, PPC_POWER_BR),
9980 GEN_HANDLER(srea, 0x1F, 0x19, 0x1C, 0x00000000, PPC_POWER_BR),
9981 GEN_HANDLER(sreq, 0x1F, 0x19, 0x16, 0x00000000, PPC_POWER_BR),
9982 GEN_HANDLER(sriq, 0x1F, 0x18, 0x15, 0x00000000, PPC_POWER_BR),
9983 GEN_HANDLER(srliq, 0x1F, 0x18, 0x17, 0x00000000, PPC_POWER_BR),
9984 GEN_HANDLER(srlq, 0x1F, 0x18, 0x16, 0x00000000, PPC_POWER_BR),
9985 GEN_HANDLER(srq, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR),
9986 GEN_HANDLER(dsa, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC),
9987 GEN_HANDLER(esa, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC),
9988 GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC),
9989 GEN_HANDLER2(tlbld_6xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB),
9990 GEN_HANDLER2(tlbli_6xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB),
9991 GEN_HANDLER2(tlbld_74xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_74xx_TLB),
9992 GEN_HANDLER2(tlbli_74xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_74xx_TLB),
9993 GEN_HANDLER(clf, 0x1F, 0x16, 0x03, 0x03E00000, PPC_POWER),
9994 GEN_HANDLER(cli, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER),
9995 GEN_HANDLER(dclst, 0x1F, 0x16, 0x13, 0x03E00000, PPC_POWER),
9996 GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER),
9997 GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER),
9998 GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER),
9999 GEN_HANDLER(lfq, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
10000 GEN_HANDLER(lfqu, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
10001 GEN_HANDLER(lfqux, 0x1F, 0x17, 0x19, 0x00000001, PPC_POWER2),
10002 GEN_HANDLER(lfqx, 0x1F, 0x17, 0x18, 0x00000001, PPC_POWER2),
10003 GEN_HANDLER(stfq, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
10004 GEN_HANDLER(stfqu, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
10005 GEN_HANDLER(stfqux, 0x1F, 0x17, 0x1D, 0x00000001, PPC_POWER2),
10006 GEN_HANDLER(stfqx, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2),
10007 GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_MFAPIDI),
10008 GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_TLBIVA),
10009 GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_DCR),
10010 GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_DCR),
10011 GEN_HANDLER(mfdcrx, 0x1F, 0x03, 0x08, 0x00000000, PPC_DCRX),
10012 GEN_HANDLER(mtdcrx, 0x1F, 0x03, 0x0C, 0x00000000, PPC_DCRX),
10013 GEN_HANDLER(mfdcrux, 0x1F, 0x03, 0x09, 0x00000000, PPC_DCRUX),
10014 GEN_HANDLER(mtdcrux, 0x1F, 0x03, 0x0D, 0x00000000, PPC_DCRUX),
10015 GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON),
10016 GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON),
10017 GEN_HANDLER2(icbt_40x, "icbt", 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_ICBT),
10018 GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON),
10019 GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON),
10020 GEN_HANDLER2(rfci_40x, "rfci", 0x13, 0x13, 0x01, 0x03FF8001, PPC_40x_EXCP),
10021 GEN_HANDLER_E(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE, PPC2_BOOKE206),
10022 GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_RFDI),
10023 GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_RFMCI),
10024 GEN_HANDLER2(tlbre_40x, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB),
10025 GEN_HANDLER2(tlbsx_40x, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB),
10026 GEN_HANDLER2(tlbwe_40x, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB),
10027 GEN_HANDLER2(tlbre_440, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE),
10028 GEN_HANDLER2(tlbsx_440, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE),
10029 GEN_HANDLER2(tlbwe_440, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE),
10030 GEN_HANDLER2_E(tlbre_booke206, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001,
10031                PPC_NONE, PPC2_BOOKE206),
10032 GEN_HANDLER2_E(tlbsx_booke206, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000,
10033                PPC_NONE, PPC2_BOOKE206),
10034 GEN_HANDLER2_E(tlbwe_booke206, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001,
10035                PPC_NONE, PPC2_BOOKE206),
10036 GEN_HANDLER2_E(tlbivax_booke206, "tlbivax", 0x1F, 0x12, 0x18, 0x00000001,
10037                PPC_NONE, PPC2_BOOKE206),
10038 GEN_HANDLER2_E(tlbilx_booke206, "tlbilx", 0x1F, 0x12, 0x00, 0x03800001,
10039                PPC_NONE, PPC2_BOOKE206),
10040 GEN_HANDLER2_E(msgsnd, "msgsnd", 0x1F, 0x0E, 0x06, 0x03ff0001,
10041                PPC_NONE, PPC2_PRCNTL),
10042 GEN_HANDLER2_E(msgclr, "msgclr", 0x1F, 0x0E, 0x07, 0x03ff0001,
10043                PPC_NONE, PPC2_PRCNTL),
10044 GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE),
10045 GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000E7C01, PPC_WRTEE),
10046 GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC),
10047 GEN_HANDLER_E(mbar, 0x1F, 0x16, 0x1a, 0x001FF801,
10048               PPC_BOOKE, PPC2_BOOKE206),
10049 GEN_HANDLER(msync_4xx, 0x1F, 0x16, 0x12, 0x03FFF801, PPC_BOOKE),
10050 GEN_HANDLER2_E(icbt_440, "icbt", 0x1F, 0x16, 0x00, 0x03E00001,
10051                PPC_BOOKE, PPC2_BOOKE206),
10052 GEN_HANDLER(lvsl, 0x1f, 0x06, 0x00, 0x00000001, PPC_ALTIVEC),
10053 GEN_HANDLER(lvsr, 0x1f, 0x06, 0x01, 0x00000001, PPC_ALTIVEC),
10054 GEN_HANDLER(mfvscr, 0x04, 0x2, 0x18, 0x001ff800, PPC_ALTIVEC),
10055 GEN_HANDLER(mtvscr, 0x04, 0x2, 0x19, 0x03ff0000, PPC_ALTIVEC),
10056 GEN_HANDLER(vmladduhm, 0x04, 0x11, 0xFF, 0x00000000, PPC_ALTIVEC),
10057 GEN_HANDLER2(evsel0, "evsel", 0x04, 0x1c, 0x09, 0x00000000, PPC_SPE),
10058 GEN_HANDLER2(evsel1, "evsel", 0x04, 0x1d, 0x09, 0x00000000, PPC_SPE),
10059 GEN_HANDLER2(evsel2, "evsel", 0x04, 0x1e, 0x09, 0x00000000, PPC_SPE),
10060 GEN_HANDLER2(evsel3, "evsel", 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE),
10061
10062 #undef GEN_INT_ARITH_ADD
10063 #undef GEN_INT_ARITH_ADD_CONST
10064 #define GEN_INT_ARITH_ADD(name, opc3, add_ca, compute_ca, compute_ov)         \
10065 GEN_HANDLER(name, 0x1F, 0x0A, opc3, 0x00000000, PPC_INTEGER),
10066 #define GEN_INT_ARITH_ADD_CONST(name, opc3, const_val,                        \
10067                                 add_ca, compute_ca, compute_ov)               \
10068 GEN_HANDLER(name, 0x1F, 0x0A, opc3, 0x0000F800, PPC_INTEGER),
10069 GEN_INT_ARITH_ADD(add, 0x08, 0, 0, 0)
10070 GEN_INT_ARITH_ADD(addo, 0x18, 0, 0, 1)
10071 GEN_INT_ARITH_ADD(addc, 0x00, 0, 1, 0)
10072 GEN_INT_ARITH_ADD(addco, 0x10, 0, 1, 1)
10073 GEN_INT_ARITH_ADD(adde, 0x04, 1, 1, 0)
10074 GEN_INT_ARITH_ADD(addeo, 0x14, 1, 1, 1)
10075 GEN_INT_ARITH_ADD_CONST(addme, 0x07, -1LL, 1, 1, 0)
10076 GEN_INT_ARITH_ADD_CONST(addmeo, 0x17, -1LL, 1, 1, 1)
10077 GEN_INT_ARITH_ADD_CONST(addze, 0x06, 0, 1, 1, 0)
10078 GEN_INT_ARITH_ADD_CONST(addzeo, 0x16, 0, 1, 1, 1)
10079
10080 #undef GEN_INT_ARITH_DIVW
10081 #define GEN_INT_ARITH_DIVW(name, opc3, sign, compute_ov)                      \
10082 GEN_HANDLER(name, 0x1F, 0x0B, opc3, 0x00000000, PPC_INTEGER)
10083 GEN_INT_ARITH_DIVW(divwu, 0x0E, 0, 0),
10084 GEN_INT_ARITH_DIVW(divwuo, 0x1E, 0, 1),
10085 GEN_INT_ARITH_DIVW(divw, 0x0F, 1, 0),
10086 GEN_INT_ARITH_DIVW(divwo, 0x1F, 1, 1),
10087 GEN_HANDLER_E(divwe, 0x1F, 0x0B, 0x0D, 0, PPC_NONE, PPC2_DIVE_ISA206),
10088 GEN_HANDLER_E(divweo, 0x1F, 0x0B, 0x1D, 0, PPC_NONE, PPC2_DIVE_ISA206),
10089 GEN_HANDLER_E(divweu, 0x1F, 0x0B, 0x0C, 0, PPC_NONE, PPC2_DIVE_ISA206),
10090 GEN_HANDLER_E(divweuo, 0x1F, 0x0B, 0x1C, 0, PPC_NONE, PPC2_DIVE_ISA206),
10091
10092 #if defined(TARGET_PPC64)
10093 #undef GEN_INT_ARITH_DIVD
10094 #define GEN_INT_ARITH_DIVD(name, opc3, sign, compute_ov)                      \
10095 GEN_HANDLER(name, 0x1F, 0x09, opc3, 0x00000000, PPC_64B)
10096 GEN_INT_ARITH_DIVD(divdu, 0x0E, 0, 0),
10097 GEN_INT_ARITH_DIVD(divduo, 0x1E, 0, 1),
10098 GEN_INT_ARITH_DIVD(divd, 0x0F, 1, 0),
10099 GEN_INT_ARITH_DIVD(divdo, 0x1F, 1, 1),
10100
10101 GEN_HANDLER_E(divdeu, 0x1F, 0x09, 0x0C, 0, PPC_NONE, PPC2_DIVE_ISA206),
10102 GEN_HANDLER_E(divdeuo, 0x1F, 0x09, 0x1C, 0, PPC_NONE, PPC2_DIVE_ISA206),
10103 GEN_HANDLER_E(divde, 0x1F, 0x09, 0x0D, 0, PPC_NONE, PPC2_DIVE_ISA206),
10104 GEN_HANDLER_E(divdeo, 0x1F, 0x09, 0x1D, 0, PPC_NONE, PPC2_DIVE_ISA206),
10105
10106 #undef GEN_INT_ARITH_MUL_HELPER
10107 #define GEN_INT_ARITH_MUL_HELPER(name, opc3)                                  \
10108 GEN_HANDLER(name, 0x1F, 0x09, opc3, 0x00000000, PPC_64B)
10109 GEN_INT_ARITH_MUL_HELPER(mulhdu, 0x00),
10110 GEN_INT_ARITH_MUL_HELPER(mulhd, 0x02),
10111 GEN_INT_ARITH_MUL_HELPER(mulldo, 0x17),
10112 #endif
10113
10114 #undef GEN_INT_ARITH_SUBF
10115 #undef GEN_INT_ARITH_SUBF_CONST
10116 #define GEN_INT_ARITH_SUBF(name, opc3, add_ca, compute_ca, compute_ov)        \
10117 GEN_HANDLER(name, 0x1F, 0x08, opc3, 0x00000000, PPC_INTEGER),
10118 #define GEN_INT_ARITH_SUBF_CONST(name, opc3, const_val,                       \
10119                                 add_ca, compute_ca, compute_ov)               \
10120 GEN_HANDLER(name, 0x1F, 0x08, opc3, 0x0000F800, PPC_INTEGER),
10121 GEN_INT_ARITH_SUBF(subf, 0x01, 0, 0, 0)
10122 GEN_INT_ARITH_SUBF(subfo, 0x11, 0, 0, 1)
10123 GEN_INT_ARITH_SUBF(subfc, 0x00, 0, 1, 0)
10124 GEN_INT_ARITH_SUBF(subfco, 0x10, 0, 1, 1)
10125 GEN_INT_ARITH_SUBF(subfe, 0x04, 1, 1, 0)
10126 GEN_INT_ARITH_SUBF(subfeo, 0x14, 1, 1, 1)
10127 GEN_INT_ARITH_SUBF_CONST(subfme, 0x07, -1LL, 1, 1, 0)
10128 GEN_INT_ARITH_SUBF_CONST(subfmeo, 0x17, -1LL, 1, 1, 1)
10129 GEN_INT_ARITH_SUBF_CONST(subfze, 0x06, 0, 1, 1, 0)
10130 GEN_INT_ARITH_SUBF_CONST(subfzeo, 0x16, 0, 1, 1, 1)
10131
10132 #undef GEN_LOGICAL1
10133 #undef GEN_LOGICAL2
10134 #define GEN_LOGICAL2(name, tcg_op, opc, type)                                 \
10135 GEN_HANDLER(name, 0x1F, 0x1C, opc, 0x00000000, type)
10136 #define GEN_LOGICAL1(name, tcg_op, opc, type)                                 \
10137 GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, type)
10138 GEN_LOGICAL2(and, tcg_gen_and_tl, 0x00, PPC_INTEGER),
10139 GEN_LOGICAL2(andc, tcg_gen_andc_tl, 0x01, PPC_INTEGER),
10140 GEN_LOGICAL2(eqv, tcg_gen_eqv_tl, 0x08, PPC_INTEGER),
10141 GEN_LOGICAL1(extsb, tcg_gen_ext8s_tl, 0x1D, PPC_INTEGER),
10142 GEN_LOGICAL1(extsh, tcg_gen_ext16s_tl, 0x1C, PPC_INTEGER),
10143 GEN_LOGICAL2(nand, tcg_gen_nand_tl, 0x0E, PPC_INTEGER),
10144 GEN_LOGICAL2(nor, tcg_gen_nor_tl, 0x03, PPC_INTEGER),
10145 GEN_LOGICAL2(orc, tcg_gen_orc_tl, 0x0C, PPC_INTEGER),
10146 #if defined(TARGET_PPC64)
10147 GEN_LOGICAL1(extsw, tcg_gen_ext32s_tl, 0x1E, PPC_64B),
10148 #endif
10149
10150 #if defined(TARGET_PPC64)
10151 #undef GEN_PPC64_R2
10152 #undef GEN_PPC64_R4
10153 #define GEN_PPC64_R2(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 | 0x10, 0xFF, 0x00000000,   \
10156              PPC_64B)
10157 #define GEN_PPC64_R4(name, opc1, opc2)                                        \
10158 GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B),\
10159 GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x01, 0xFF, 0x00000000,   \
10160              PPC_64B),                                                        \
10161 GEN_HANDLER2(name##2, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000,   \
10162              PPC_64B),                                                        \
10163 GEN_HANDLER2(name##3, stringify(name), opc1, opc2 | 0x11, 0xFF, 0x00000000,   \
10164              PPC_64B)
10165 GEN_PPC64_R4(rldicl, 0x1E, 0x00),
10166 GEN_PPC64_R4(rldicr, 0x1E, 0x02),
10167 GEN_PPC64_R4(rldic, 0x1E, 0x04),
10168 GEN_PPC64_R2(rldcl, 0x1E, 0x08),
10169 GEN_PPC64_R2(rldcr, 0x1E, 0x09),
10170 GEN_PPC64_R4(rldimi, 0x1E, 0x06),
10171 #endif
10172
10173 #undef _GEN_FLOAT_ACB
10174 #undef GEN_FLOAT_ACB
10175 #undef _GEN_FLOAT_AB
10176 #undef GEN_FLOAT_AB
10177 #undef _GEN_FLOAT_AC
10178 #undef GEN_FLOAT_AC
10179 #undef GEN_FLOAT_B
10180 #undef GEN_FLOAT_BS
10181 #define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat, set_fprf, type)           \
10182 GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, type)
10183 #define GEN_FLOAT_ACB(name, op2, set_fprf, type)                              \
10184 _GEN_FLOAT_ACB(name, name, 0x3F, op2, 0, set_fprf, type),                     \
10185 _GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, set_fprf, type)
10186 #define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
10187 GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)
10188 #define GEN_FLOAT_AB(name, op2, inval, set_fprf, type)                        \
10189 _GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0, set_fprf, type),               \
10190 _GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1, set_fprf, type)
10191 #define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
10192 GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)
10193 #define GEN_FLOAT_AC(name, op2, inval, set_fprf, type)                        \
10194 _GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0, set_fprf, type),               \
10195 _GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1, set_fprf, type)
10196 #define GEN_FLOAT_B(name, op2, op3, set_fprf, type)                           \
10197 GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, type)
10198 #define GEN_FLOAT_BS(name, op1, op2, set_fprf, type)                          \
10199 GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, type)
10200
10201 GEN_FLOAT_AB(add, 0x15, 0x000007C0, 1, PPC_FLOAT),
10202 GEN_FLOAT_AB(div, 0x12, 0x000007C0, 1, PPC_FLOAT),
10203 GEN_FLOAT_AC(mul, 0x19, 0x0000F800, 1, PPC_FLOAT),
10204 GEN_FLOAT_BS(re, 0x3F, 0x18, 1, PPC_FLOAT_EXT),
10205 GEN_FLOAT_BS(res, 0x3B, 0x18, 1, PPC_FLOAT_FRES),
10206 GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A, 1, PPC_FLOAT_FRSQRTE),
10207 _GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0, 0, PPC_FLOAT_FSEL),
10208 GEN_FLOAT_AB(sub, 0x14, 0x000007C0, 1, PPC_FLOAT),
10209 GEN_FLOAT_ACB(madd, 0x1D, 1, PPC_FLOAT),
10210 GEN_FLOAT_ACB(msub, 0x1C, 1, PPC_FLOAT),
10211 GEN_FLOAT_ACB(nmadd, 0x1F, 1, PPC_FLOAT),
10212 GEN_FLOAT_ACB(nmsub, 0x1E, 1, PPC_FLOAT),
10213 GEN_HANDLER_E(ftdiv, 0x3F, 0x00, 0x04, 1, PPC_NONE, PPC2_FP_TST_ISA206),
10214 GEN_HANDLER_E(ftsqrt, 0x3F, 0x00, 0x05, 1, PPC_NONE, PPC2_FP_TST_ISA206),
10215 GEN_FLOAT_B(ctiw, 0x0E, 0x00, 0, PPC_FLOAT),
10216 GEN_HANDLER_E(fctiwu, 0x3F, 0x0E, 0x04, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
10217 GEN_FLOAT_B(ctiwz, 0x0F, 0x00, 0, PPC_FLOAT),
10218 GEN_HANDLER_E(fctiwuz, 0x3F, 0x0F, 0x04, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
10219 GEN_FLOAT_B(rsp, 0x0C, 0x00, 1, PPC_FLOAT),
10220 GEN_HANDLER_E(fcfid, 0x3F, 0x0E, 0x1A, 0x001F0000, PPC_NONE, PPC2_FP_CVT_S64),
10221 GEN_HANDLER_E(fcfids, 0x3B, 0x0E, 0x1A, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
10222 GEN_HANDLER_E(fcfidu, 0x3F, 0x0E, 0x1E, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
10223 GEN_HANDLER_E(fcfidus, 0x3B, 0x0E, 0x1E, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
10224 GEN_HANDLER_E(fctid, 0x3F, 0x0E, 0x19, 0x001F0000, PPC_NONE, PPC2_FP_CVT_S64),
10225 GEN_HANDLER_E(fctidu, 0x3F, 0x0E, 0x1D, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
10226 GEN_HANDLER_E(fctidz, 0x3F, 0x0F, 0x19, 0x001F0000, PPC_NONE, PPC2_FP_CVT_S64),
10227 GEN_HANDLER_E(fctiduz, 0x3F, 0x0F, 0x1D, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
10228 GEN_FLOAT_B(rin, 0x08, 0x0C, 1, PPC_FLOAT_EXT),
10229 GEN_FLOAT_B(riz, 0x08, 0x0D, 1, PPC_FLOAT_EXT),
10230 GEN_FLOAT_B(rip, 0x08, 0x0E, 1, PPC_FLOAT_EXT),
10231 GEN_FLOAT_B(rim, 0x08, 0x0F, 1, PPC_FLOAT_EXT),
10232
10233 #undef GEN_LD
10234 #undef GEN_LDU
10235 #undef GEN_LDUX
10236 #undef GEN_LDX_E
10237 #undef GEN_LDS
10238 #define GEN_LD(name, ldop, opc, type)                                         \
10239 GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
10240 #define GEN_LDU(name, ldop, opc, type)                                        \
10241 GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
10242 #define GEN_LDUX(name, ldop, opc2, opc3, type)                                \
10243 GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type),
10244 #define GEN_LDX_E(name, ldop, opc2, opc3, type, type2)                        \
10245 GEN_HANDLER_E(name##x, 0x1F, opc2, opc3, 0x00000001, type, type2),
10246 #define GEN_LDS(name, ldop, op, type)                                         \
10247 GEN_LD(name, ldop, op | 0x20, type)                                           \
10248 GEN_LDU(name, ldop, op | 0x21, type)                                          \
10249 GEN_LDUX(name, ldop, 0x17, op | 0x01, type)                                   \
10250 GEN_LDX(name, ldop, 0x17, op | 0x00, type)
10251
10252 GEN_LDS(lbz, ld8u, 0x02, PPC_INTEGER)
10253 GEN_LDS(lha, ld16s, 0x0A, PPC_INTEGER)
10254 GEN_LDS(lhz, ld16u, 0x08, PPC_INTEGER)
10255 GEN_LDS(lwz, ld32u, 0x00, PPC_INTEGER)
10256 #if defined(TARGET_PPC64)
10257 GEN_LDUX(lwa, ld32s, 0x15, 0x0B, PPC_64B)
10258 GEN_LDX(lwa, ld32s, 0x15, 0x0A, PPC_64B)
10259 GEN_LDUX(ld, ld64, 0x15, 0x01, PPC_64B)
10260 GEN_LDX(ld, ld64, 0x15, 0x00, PPC_64B)
10261 GEN_LDX_E(ldbr, ld64ur, 0x14, 0x10, PPC_NONE, PPC2_DBRX)
10262 #endif
10263 GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER)
10264 GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER)
10265
10266 #undef GEN_ST
10267 #undef GEN_STU
10268 #undef GEN_STUX
10269 #undef GEN_STX_E
10270 #undef GEN_STS
10271 #define GEN_ST(name, stop, opc, type)                                         \
10272 GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
10273 #define GEN_STU(name, stop, opc, type)                                        \
10274 GEN_HANDLER(stop##u, opc, 0xFF, 0xFF, 0x00000000, type),
10275 #define GEN_STUX(name, stop, opc2, opc3, type)                                \
10276 GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type),
10277 #define GEN_STX_E(name, stop, opc2, opc3, type, type2)                        \
10278 GEN_HANDLER_E(name##x, 0x1F, opc2, opc3, 0x00000001, type, type2),
10279 #define GEN_STS(name, stop, op, type)                                         \
10280 GEN_ST(name, stop, op | 0x20, type)                                           \
10281 GEN_STU(name, stop, op | 0x21, type)                                          \
10282 GEN_STUX(name, stop, 0x17, op | 0x01, type)                                   \
10283 GEN_STX(name, stop, 0x17, op | 0x00, type)
10284
10285 GEN_STS(stb, st8, 0x06, PPC_INTEGER)
10286 GEN_STS(sth, st16, 0x0C, PPC_INTEGER)
10287 GEN_STS(stw, st32, 0x04, PPC_INTEGER)
10288 #if defined(TARGET_PPC64)
10289 GEN_STUX(std, st64, 0x15, 0x05, PPC_64B)
10290 GEN_STX(std, st64, 0x15, 0x04, PPC_64B)
10291 GEN_STX_E(stdbr, st64r, 0x14, 0x14, PPC_NONE, PPC2_DBRX)
10292 #endif
10293 GEN_STX(sthbr, st16r, 0x16, 0x1C, PPC_INTEGER)
10294 GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER)
10295
10296 #undef GEN_LDF
10297 #undef GEN_LDUF
10298 #undef GEN_LDUXF
10299 #undef GEN_LDXF
10300 #undef GEN_LDFS
10301 #define GEN_LDF(name, ldop, opc, type)                                        \
10302 GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
10303 #define GEN_LDUF(name, ldop, opc, type)                                       \
10304 GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
10305 #define GEN_LDUXF(name, ldop, opc, type)                                      \
10306 GEN_HANDLER(name##ux, 0x1F, 0x17, opc, 0x00000001, type),
10307 #define GEN_LDXF(name, ldop, opc2, opc3, type)                                \
10308 GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type),
10309 #define GEN_LDFS(name, ldop, op, type)                                        \
10310 GEN_LDF(name, ldop, op | 0x20, type)                                          \
10311 GEN_LDUF(name, ldop, op | 0x21, type)                                         \
10312 GEN_LDUXF(name, ldop, op | 0x01, type)                                        \
10313 GEN_LDXF(name, ldop, 0x17, op | 0x00, type)
10314
10315 GEN_LDFS(lfd, ld64, 0x12, PPC_FLOAT)
10316 GEN_LDFS(lfs, ld32fs, 0x10, PPC_FLOAT)
10317 GEN_HANDLER_E(lfiwax, 0x1f, 0x17, 0x1a, 0x00000001, PPC_NONE, PPC2_ISA205),
10318 GEN_HANDLER_E(lfiwzx, 0x1f, 0x17, 0x1b, 0x1, PPC_NONE, PPC2_FP_CVT_ISA206),
10319 GEN_HANDLER_E(lfdp, 0x39, 0xFF, 0xFF, 0x00200003, PPC_NONE, PPC2_ISA205),
10320 GEN_HANDLER_E(lfdpx, 0x1F, 0x17, 0x18, 0x00200001, PPC_NONE, PPC2_ISA205),
10321
10322 #undef GEN_STF
10323 #undef GEN_STUF
10324 #undef GEN_STUXF
10325 #undef GEN_STXF
10326 #undef GEN_STFS
10327 #define GEN_STF(name, stop, opc, type)                                        \
10328 GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
10329 #define GEN_STUF(name, stop, opc, type)                                       \
10330 GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
10331 #define GEN_STUXF(name, stop, opc, type)                                      \
10332 GEN_HANDLER(name##ux, 0x1F, 0x17, opc, 0x00000001, type),
10333 #define GEN_STXF(name, stop, opc2, opc3, type)                                \
10334 GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type),
10335 #define GEN_STFS(name, stop, op, type)                                        \
10336 GEN_STF(name, stop, op | 0x20, type)                                          \
10337 GEN_STUF(name, stop, op | 0x21, type)                                         \
10338 GEN_STUXF(name, stop, op | 0x01, type)                                        \
10339 GEN_STXF(name, stop, 0x17, op | 0x00, type)
10340
10341 GEN_STFS(stfd, st64, 0x16, PPC_FLOAT)
10342 GEN_STFS(stfs, st32fs, 0x14, PPC_FLOAT)
10343 GEN_STXF(stfiw, st32fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX)
10344 GEN_HANDLER_E(stfdp, 0x3D, 0xFF, 0xFF, 0x00200003, PPC_NONE, PPC2_ISA205),
10345 GEN_HANDLER_E(stfdpx, 0x1F, 0x17, 0x1C, 0x00200001, PPC_NONE, PPC2_ISA205),
10346
10347 #undef GEN_CRLOGIC
10348 #define GEN_CRLOGIC(name, tcg_op, opc)                                        \
10349 GEN_HANDLER(name, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER)
10350 GEN_CRLOGIC(crand, tcg_gen_and_i32, 0x08),
10351 GEN_CRLOGIC(crandc, tcg_gen_andc_i32, 0x04),
10352 GEN_CRLOGIC(creqv, tcg_gen_eqv_i32, 0x09),
10353 GEN_CRLOGIC(crnand, tcg_gen_nand_i32, 0x07),
10354 GEN_CRLOGIC(crnor, tcg_gen_nor_i32, 0x01),
10355 GEN_CRLOGIC(cror, tcg_gen_or_i32, 0x0E),
10356 GEN_CRLOGIC(crorc, tcg_gen_orc_i32, 0x0D),
10357 GEN_CRLOGIC(crxor, tcg_gen_xor_i32, 0x06),
10358
10359 #undef GEN_MAC_HANDLER
10360 #define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
10361 GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC)
10362 GEN_MAC_HANDLER(macchw, 0x0C, 0x05),
10363 GEN_MAC_HANDLER(macchwo, 0x0C, 0x15),
10364 GEN_MAC_HANDLER(macchws, 0x0C, 0x07),
10365 GEN_MAC_HANDLER(macchwso, 0x0C, 0x17),
10366 GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06),
10367 GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16),
10368 GEN_MAC_HANDLER(macchwu, 0x0C, 0x04),
10369 GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14),
10370 GEN_MAC_HANDLER(machhw, 0x0C, 0x01),
10371 GEN_MAC_HANDLER(machhwo, 0x0C, 0x11),
10372 GEN_MAC_HANDLER(machhws, 0x0C, 0x03),
10373 GEN_MAC_HANDLER(machhwso, 0x0C, 0x13),
10374 GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02),
10375 GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12),
10376 GEN_MAC_HANDLER(machhwu, 0x0C, 0x00),
10377 GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10),
10378 GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D),
10379 GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D),
10380 GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F),
10381 GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F),
10382 GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C),
10383 GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C),
10384 GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E),
10385 GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E),
10386 GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05),
10387 GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15),
10388 GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07),
10389 GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17),
10390 GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01),
10391 GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11),
10392 GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03),
10393 GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13),
10394 GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D),
10395 GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D),
10396 GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F),
10397 GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F),
10398 GEN_MAC_HANDLER(mulchw, 0x08, 0x05),
10399 GEN_MAC_HANDLER(mulchwu, 0x08, 0x04),
10400 GEN_MAC_HANDLER(mulhhw, 0x08, 0x01),
10401 GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00),
10402 GEN_MAC_HANDLER(mullhw, 0x08, 0x0D),
10403 GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C),
10404
10405 #undef GEN_VR_LDX
10406 #undef GEN_VR_STX
10407 #undef GEN_VR_LVE
10408 #undef GEN_VR_STVE
10409 #define GEN_VR_LDX(name, opc2, opc3)                                          \
10410 GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
10411 #define GEN_VR_STX(name, opc2, opc3)                                          \
10412 GEN_HANDLER(st##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
10413 #define GEN_VR_LVE(name, opc2, opc3)                                    \
10414     GEN_HANDLER(lve##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
10415 #define GEN_VR_STVE(name, opc2, opc3)                                   \
10416     GEN_HANDLER(stve##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
10417 GEN_VR_LDX(lvx, 0x07, 0x03),
10418 GEN_VR_LDX(lvxl, 0x07, 0x0B),
10419 GEN_VR_LVE(bx, 0x07, 0x00),
10420 GEN_VR_LVE(hx, 0x07, 0x01),
10421 GEN_VR_LVE(wx, 0x07, 0x02),
10422 GEN_VR_STX(svx, 0x07, 0x07),
10423 GEN_VR_STX(svxl, 0x07, 0x0F),
10424 GEN_VR_STVE(bx, 0x07, 0x04),
10425 GEN_VR_STVE(hx, 0x07, 0x05),
10426 GEN_VR_STVE(wx, 0x07, 0x06),
10427
10428 #undef GEN_VX_LOGICAL
10429 #define GEN_VX_LOGICAL(name, tcg_op, opc2, opc3)                        \
10430 GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
10431
10432 #undef GEN_VX_LOGICAL_207
10433 #define GEN_VX_LOGICAL_207(name, tcg_op, opc2, opc3) \
10434 GEN_HANDLER_E(name, 0x04, opc2, opc3, 0x00000000, PPC_NONE, PPC2_ALTIVEC_207)
10435
10436 GEN_VX_LOGICAL(vand, tcg_gen_and_i64, 2, 16),
10437 GEN_VX_LOGICAL(vandc, tcg_gen_andc_i64, 2, 17),
10438 GEN_VX_LOGICAL(vor, tcg_gen_or_i64, 2, 18),
10439 GEN_VX_LOGICAL(vxor, tcg_gen_xor_i64, 2, 19),
10440 GEN_VX_LOGICAL(vnor, tcg_gen_nor_i64, 2, 20),
10441 GEN_VX_LOGICAL_207(veqv, tcg_gen_eqv_i64, 2, 26),
10442 GEN_VX_LOGICAL_207(vnand, tcg_gen_nand_i64, 2, 22),
10443 GEN_VX_LOGICAL_207(vorc, tcg_gen_orc_i64, 2, 21),
10444
10445 #undef GEN_VXFORM
10446 #define GEN_VXFORM(name, opc2, opc3)                                    \
10447 GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
10448
10449 #undef GEN_VXFORM_207
10450 #define GEN_VXFORM_207(name, opc2, opc3) \
10451 GEN_HANDLER_E(name, 0x04, opc2, opc3, 0x00000000, PPC_NONE, PPC2_ALTIVEC_207)
10452
10453 #undef GEN_VXFORM_DUAL
10454 #define GEN_VXFORM_DUAL(name0, name1, opc2, opc3, type0, type1) \
10455 GEN_HANDLER_E(name0##_##name1, 0x4, opc2, opc3, 0x00000000, type0, type1)
10456
10457 #undef GEN_VXRFORM_DUAL
10458 #define GEN_VXRFORM_DUAL(name0, name1, opc2, opc3, tp0, tp1) \
10459 GEN_HANDLER_E(name0##_##name1, 0x4, opc2, opc3, 0x00000000, tp0, tp1), \
10460 GEN_HANDLER_E(name0##_##name1, 0x4, opc2, (opc3 | 0x10), 0x00000000, tp0, tp1),
10461
10462 GEN_VXFORM(vaddubm, 0, 0),
10463 GEN_VXFORM(vadduhm, 0, 1),
10464 GEN_VXFORM(vadduwm, 0, 2),
10465 GEN_VXFORM_207(vaddudm, 0, 3),
10466 GEN_VXFORM_DUAL(vsububm, bcdadd, 0, 16, PPC_ALTIVEC, PPC_NONE),
10467 GEN_VXFORM_DUAL(vsubuhm, bcdsub, 0, 17, PPC_ALTIVEC, PPC_NONE),
10468 GEN_VXFORM(vsubuwm, 0, 18),
10469 GEN_VXFORM_207(vsubudm, 0, 19),
10470 GEN_VXFORM(vmaxub, 1, 0),
10471 GEN_VXFORM(vmaxuh, 1, 1),
10472 GEN_VXFORM(vmaxuw, 1, 2),
10473 GEN_VXFORM_207(vmaxud, 1, 3),
10474 GEN_VXFORM(vmaxsb, 1, 4),
10475 GEN_VXFORM(vmaxsh, 1, 5),
10476 GEN_VXFORM(vmaxsw, 1, 6),
10477 GEN_VXFORM_207(vmaxsd, 1, 7),
10478 GEN_VXFORM(vminub, 1, 8),
10479 GEN_VXFORM(vminuh, 1, 9),
10480 GEN_VXFORM(vminuw, 1, 10),
10481 GEN_VXFORM_207(vminud, 1, 11),
10482 GEN_VXFORM(vminsb, 1, 12),
10483 GEN_VXFORM(vminsh, 1, 13),
10484 GEN_VXFORM(vminsw, 1, 14),
10485 GEN_VXFORM_207(vminsd, 1, 15),
10486 GEN_VXFORM(vavgub, 1, 16),
10487 GEN_VXFORM(vavguh, 1, 17),
10488 GEN_VXFORM(vavguw, 1, 18),
10489 GEN_VXFORM(vavgsb, 1, 20),
10490 GEN_VXFORM(vavgsh, 1, 21),
10491 GEN_VXFORM(vavgsw, 1, 22),
10492 GEN_VXFORM(vmrghb, 6, 0),
10493 GEN_VXFORM(vmrghh, 6, 1),
10494 GEN_VXFORM(vmrghw, 6, 2),
10495 GEN_VXFORM(vmrglb, 6, 4),
10496 GEN_VXFORM(vmrglh, 6, 5),
10497 GEN_VXFORM(vmrglw, 6, 6),
10498 GEN_VXFORM_207(vmrgew, 6, 30),
10499 GEN_VXFORM_207(vmrgow, 6, 26),
10500 GEN_VXFORM(vmuloub, 4, 0),
10501 GEN_VXFORM(vmulouh, 4, 1),
10502 GEN_VXFORM_DUAL(vmulouw, vmuluwm, 4, 2, PPC_ALTIVEC, PPC_NONE),
10503 GEN_VXFORM(vmulosb, 4, 4),
10504 GEN_VXFORM(vmulosh, 4, 5),
10505 GEN_VXFORM_207(vmulosw, 4, 6),
10506 GEN_VXFORM(vmuleub, 4, 8),
10507 GEN_VXFORM(vmuleuh, 4, 9),
10508 GEN_VXFORM_207(vmuleuw, 4, 10),
10509 GEN_VXFORM(vmulesb, 4, 12),
10510 GEN_VXFORM(vmulesh, 4, 13),
10511 GEN_VXFORM_207(vmulesw, 4, 14),
10512 GEN_VXFORM(vslb, 2, 4),
10513 GEN_VXFORM(vslh, 2, 5),
10514 GEN_VXFORM(vslw, 2, 6),
10515 GEN_VXFORM_207(vsld, 2, 23),
10516 GEN_VXFORM(vsrb, 2, 8),
10517 GEN_VXFORM(vsrh, 2, 9),
10518 GEN_VXFORM(vsrw, 2, 10),
10519 GEN_VXFORM_207(vsrd, 2, 27),
10520 GEN_VXFORM(vsrab, 2, 12),
10521 GEN_VXFORM(vsrah, 2, 13),
10522 GEN_VXFORM(vsraw, 2, 14),
10523 GEN_VXFORM_207(vsrad, 2, 15),
10524 GEN_VXFORM(vslo, 6, 16),
10525 GEN_VXFORM(vsro, 6, 17),
10526 GEN_VXFORM(vaddcuw, 0, 6),
10527 GEN_VXFORM(vsubcuw, 0, 22),
10528 GEN_VXFORM(vaddubs, 0, 8),
10529 GEN_VXFORM(vadduhs, 0, 9),
10530 GEN_VXFORM(vadduws, 0, 10),
10531 GEN_VXFORM(vaddsbs, 0, 12),
10532 GEN_VXFORM(vaddshs, 0, 13),
10533 GEN_VXFORM(vaddsws, 0, 14),
10534 GEN_VXFORM_DUAL(vsububs, bcdadd, 0, 24, PPC_ALTIVEC, PPC_NONE),
10535 GEN_VXFORM_DUAL(vsubuhs, bcdsub, 0, 25, PPC_ALTIVEC, PPC_NONE),
10536 GEN_VXFORM(vsubuws, 0, 26),
10537 GEN_VXFORM(vsubsbs, 0, 28),
10538 GEN_VXFORM(vsubshs, 0, 29),
10539 GEN_VXFORM(vsubsws, 0, 30),
10540 GEN_VXFORM_207(vadduqm, 0, 4),
10541 GEN_VXFORM_207(vaddcuq, 0, 5),
10542 GEN_VXFORM_DUAL(vaddeuqm, vaddecuq, 30, 0xFF, PPC_NONE, PPC2_ALTIVEC_207),
10543 GEN_VXFORM_207(vsubuqm, 0, 20),
10544 GEN_VXFORM_207(vsubcuq, 0, 21),
10545 GEN_VXFORM_DUAL(vsubeuqm, vsubecuq, 31, 0xFF, PPC_NONE, PPC2_ALTIVEC_207),
10546 GEN_VXFORM(vrlb, 2, 0),
10547 GEN_VXFORM(vrlh, 2, 1),
10548 GEN_VXFORM(vrlw, 2, 2),
10549 GEN_VXFORM_207(vrld, 2, 3),
10550 GEN_VXFORM(vsl, 2, 7),
10551 GEN_VXFORM(vsr, 2, 11),
10552 GEN_VXFORM(vpkuhum, 7, 0),
10553 GEN_VXFORM(vpkuwum, 7, 1),
10554 GEN_VXFORM_207(vpkudum, 7, 17),
10555 GEN_VXFORM(vpkuhus, 7, 2),
10556 GEN_VXFORM(vpkuwus, 7, 3),
10557 GEN_VXFORM_207(vpkudus, 7, 19),
10558 GEN_VXFORM(vpkshus, 7, 4),
10559 GEN_VXFORM(vpkswus, 7, 5),
10560 GEN_VXFORM_207(vpksdus, 7, 21),
10561 GEN_VXFORM(vpkshss, 7, 6),
10562 GEN_VXFORM(vpkswss, 7, 7),
10563 GEN_VXFORM_207(vpksdss, 7, 23),
10564 GEN_VXFORM(vpkpx, 7, 12),
10565 GEN_VXFORM(vsum4ubs, 4, 24),
10566 GEN_VXFORM(vsum4sbs, 4, 28),
10567 GEN_VXFORM(vsum4shs, 4, 25),
10568 GEN_VXFORM(vsum2sws, 4, 26),
10569 GEN_VXFORM(vsumsws, 4, 30),
10570 GEN_VXFORM(vaddfp, 5, 0),
10571 GEN_VXFORM(vsubfp, 5, 1),
10572 GEN_VXFORM(vmaxfp, 5, 16),
10573 GEN_VXFORM(vminfp, 5, 17),
10574
10575 #undef GEN_VXRFORM1
10576 #undef GEN_VXRFORM
10577 #define GEN_VXRFORM1(opname, name, str, opc2, opc3)                     \
10578     GEN_HANDLER2(name, str, 0x4, opc2, opc3, 0x00000000, PPC_ALTIVEC),
10579 #define GEN_VXRFORM(name, opc2, opc3)                                \
10580     GEN_VXRFORM1(name, name, #name, opc2, opc3)                      \
10581     GEN_VXRFORM1(name##_dot, name##_, #name ".", opc2, (opc3 | (0x1 << 4)))
10582 GEN_VXRFORM(vcmpequb, 3, 0)
10583 GEN_VXRFORM(vcmpequh, 3, 1)
10584 GEN_VXRFORM(vcmpequw, 3, 2)
10585 GEN_VXRFORM(vcmpgtsb, 3, 12)
10586 GEN_VXRFORM(vcmpgtsh, 3, 13)
10587 GEN_VXRFORM(vcmpgtsw, 3, 14)
10588 GEN_VXRFORM(vcmpgtub, 3, 8)
10589 GEN_VXRFORM(vcmpgtuh, 3, 9)
10590 GEN_VXRFORM(vcmpgtuw, 3, 10)
10591 GEN_VXRFORM_DUAL(vcmpeqfp, vcmpequd, 3, 3, PPC_ALTIVEC, PPC_NONE)
10592 GEN_VXRFORM(vcmpgefp, 3, 7)
10593 GEN_VXRFORM_DUAL(vcmpgtfp, vcmpgtud, 3, 11, PPC_ALTIVEC, PPC_NONE)
10594 GEN_VXRFORM_DUAL(vcmpbfp, vcmpgtsd, 3, 15, PPC_ALTIVEC, PPC_NONE)
10595
10596 #undef GEN_VXFORM_SIMM
10597 #define GEN_VXFORM_SIMM(name, opc2, opc3)                               \
10598     GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
10599 GEN_VXFORM_SIMM(vspltisb, 6, 12),
10600 GEN_VXFORM_SIMM(vspltish, 6, 13),
10601 GEN_VXFORM_SIMM(vspltisw, 6, 14),
10602
10603 #undef GEN_VXFORM_NOA
10604 #define GEN_VXFORM_NOA(name, opc2, opc3)                                \
10605     GEN_HANDLER(name, 0x04, opc2, opc3, 0x001f0000, PPC_ALTIVEC)
10606 GEN_VXFORM_NOA(vupkhsb, 7, 8),
10607 GEN_VXFORM_NOA(vupkhsh, 7, 9),
10608 GEN_VXFORM_207(vupkhsw, 7, 25),
10609 GEN_VXFORM_NOA(vupklsb, 7, 10),
10610 GEN_VXFORM_NOA(vupklsh, 7, 11),
10611 GEN_VXFORM_207(vupklsw, 7, 27),
10612 GEN_VXFORM_NOA(vupkhpx, 7, 13),
10613 GEN_VXFORM_NOA(vupklpx, 7, 15),
10614 GEN_VXFORM_NOA(vrefp, 5, 4),
10615 GEN_VXFORM_NOA(vrsqrtefp, 5, 5),
10616 GEN_VXFORM_NOA(vexptefp, 5, 6),
10617 GEN_VXFORM_NOA(vlogefp, 5, 7),
10618 GEN_VXFORM_NOA(vrfim, 5, 11),
10619 GEN_VXFORM_NOA(vrfin, 5, 8),
10620 GEN_VXFORM_NOA(vrfip, 5, 10),
10621 GEN_VXFORM_NOA(vrfiz, 5, 9),
10622
10623 #undef GEN_VXFORM_UIMM
10624 #define GEN_VXFORM_UIMM(name, opc2, opc3)                               \
10625     GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
10626 GEN_VXFORM_UIMM(vspltb, 6, 8),
10627 GEN_VXFORM_UIMM(vsplth, 6, 9),
10628 GEN_VXFORM_UIMM(vspltw, 6, 10),
10629 GEN_VXFORM_UIMM(vcfux, 5, 12),
10630 GEN_VXFORM_UIMM(vcfsx, 5, 13),
10631 GEN_VXFORM_UIMM(vctuxs, 5, 14),
10632 GEN_VXFORM_UIMM(vctsxs, 5, 15),
10633
10634 #undef GEN_VAFORM_PAIRED
10635 #define GEN_VAFORM_PAIRED(name0, name1, opc2)                           \
10636     GEN_HANDLER(name0##_##name1, 0x04, opc2, 0xFF, 0x00000000, PPC_ALTIVEC)
10637 GEN_VAFORM_PAIRED(vmhaddshs, vmhraddshs, 16),
10638 GEN_VAFORM_PAIRED(vmsumubm, vmsummbm, 18),
10639 GEN_VAFORM_PAIRED(vmsumuhm, vmsumuhs, 19),
10640 GEN_VAFORM_PAIRED(vmsumshm, vmsumshs, 20),
10641 GEN_VAFORM_PAIRED(vsel, vperm, 21),
10642 GEN_VAFORM_PAIRED(vmaddfp, vnmsubfp, 23),
10643
10644 GEN_VXFORM_DUAL(vclzb, vpopcntb, 1, 28, PPC_NONE, PPC2_ALTIVEC_207),
10645 GEN_VXFORM_DUAL(vclzh, vpopcnth, 1, 29, PPC_NONE, PPC2_ALTIVEC_207),
10646 GEN_VXFORM_DUAL(vclzw, vpopcntw, 1, 30, PPC_NONE, PPC2_ALTIVEC_207),
10647 GEN_VXFORM_DUAL(vclzd, vpopcntd, 1, 31, PPC_NONE, PPC2_ALTIVEC_207),
10648
10649 GEN_VXFORM_207(vbpermq, 6, 21),
10650 GEN_VXFORM_207(vgbbd, 6, 20),
10651 GEN_VXFORM_207(vpmsumb, 4, 16),
10652 GEN_VXFORM_207(vpmsumh, 4, 17),
10653 GEN_VXFORM_207(vpmsumw, 4, 18),
10654 GEN_VXFORM_207(vpmsumd, 4, 19),
10655
10656 GEN_VXFORM_207(vsbox, 4, 23),
10657
10658 GEN_VXFORM_DUAL(vcipher, vcipherlast, 4, 20, PPC_NONE, PPC2_ALTIVEC_207),
10659 GEN_VXFORM_DUAL(vncipher, vncipherlast, 4, 21, PPC_NONE, PPC2_ALTIVEC_207),
10660
10661 GEN_VXFORM_207(vshasigmaw, 1, 26),
10662 GEN_VXFORM_207(vshasigmad, 1, 27),
10663
10664 GEN_VXFORM_DUAL(vsldoi, vpermxor, 22, 0xFF, PPC_ALTIVEC, PPC_NONE),
10665
10666 GEN_HANDLER_E(lxsdx, 0x1F, 0x0C, 0x12, 0, PPC_NONE, PPC2_VSX),
10667 GEN_HANDLER_E(lxsiwax, 0x1F, 0x0C, 0x02, 0, PPC_NONE, PPC2_VSX207),
10668 GEN_HANDLER_E(lxsiwzx, 0x1F, 0x0C, 0x00, 0, PPC_NONE, PPC2_VSX207),
10669 GEN_HANDLER_E(lxsspx, 0x1F, 0x0C, 0x10, 0, PPC_NONE, PPC2_VSX207),
10670 GEN_HANDLER_E(lxvd2x, 0x1F, 0x0C, 0x1A, 0, PPC_NONE, PPC2_VSX),
10671 GEN_HANDLER_E(lxvdsx, 0x1F, 0x0C, 0x0A, 0, PPC_NONE, PPC2_VSX),
10672 GEN_HANDLER_E(lxvw4x, 0x1F, 0x0C, 0x18, 0, PPC_NONE, PPC2_VSX),
10673
10674 GEN_HANDLER_E(stxsdx, 0x1F, 0xC, 0x16, 0, PPC_NONE, PPC2_VSX),
10675 GEN_HANDLER_E(stxsiwx, 0x1F, 0xC, 0x04, 0, PPC_NONE, PPC2_VSX207),
10676 GEN_HANDLER_E(stxsspx, 0x1F, 0xC, 0x14, 0, PPC_NONE, PPC2_VSX207),
10677 GEN_HANDLER_E(stxvd2x, 0x1F, 0xC, 0x1E, 0, PPC_NONE, PPC2_VSX),
10678 GEN_HANDLER_E(stxvw4x, 0x1F, 0xC, 0x1C, 0, PPC_NONE, PPC2_VSX),
10679
10680 GEN_HANDLER_E(mfvsrwz, 0x1F, 0x13, 0x03, 0x0000F800, PPC_NONE, PPC2_VSX207),
10681 GEN_HANDLER_E(mtvsrwa, 0x1F, 0x13, 0x06, 0x0000F800, PPC_NONE, PPC2_VSX207),
10682 GEN_HANDLER_E(mtvsrwz, 0x1F, 0x13, 0x07, 0x0000F800, PPC_NONE, PPC2_VSX207),
10683 #if defined(TARGET_PPC64)
10684 GEN_HANDLER_E(mfvsrd, 0x1F, 0x13, 0x01, 0x0000F800, PPC_NONE, PPC2_VSX207),
10685 GEN_HANDLER_E(mtvsrd, 0x1F, 0x13, 0x05, 0x0000F800, PPC_NONE, PPC2_VSX207),
10686 #endif
10687
10688 #undef GEN_XX2FORM
10689 #define GEN_XX2FORM(name, opc2, opc3, fl2)                           \
10690 GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0, opc3, 0, PPC_NONE, fl2), \
10691 GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 1, opc3, 0, PPC_NONE, fl2)
10692
10693 #undef GEN_XX3FORM
10694 #define GEN_XX3FORM(name, opc2, opc3, fl2)                           \
10695 GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0, opc3, 0, PPC_NONE, fl2), \
10696 GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 1, opc3, 0, PPC_NONE, fl2), \
10697 GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 2, opc3, 0, PPC_NONE, fl2), \
10698 GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 3, opc3, 0, PPC_NONE, fl2)
10699
10700 #undef GEN_XX2IFORM
10701 #define GEN_XX2IFORM(name, opc2, opc3, fl2)                           \
10702 GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0, opc3, 1, PPC_NONE, fl2), \
10703 GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 1, opc3, 1, PPC_NONE, fl2), \
10704 GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 2, opc3, 1, PPC_NONE, fl2), \
10705 GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 3, opc3, 1, PPC_NONE, fl2)
10706
10707 #undef GEN_XX3_RC_FORM
10708 #define GEN_XX3_RC_FORM(name, opc2, opc3, fl2)                          \
10709 GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0x00, opc3 | 0x00, 0, PPC_NONE, fl2), \
10710 GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0x01, opc3 | 0x00, 0, PPC_NONE, fl2), \
10711 GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0x02, opc3 | 0x00, 0, PPC_NONE, fl2), \
10712 GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0x03, opc3 | 0x00, 0, PPC_NONE, fl2), \
10713 GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0x00, opc3 | 0x10, 0, PPC_NONE, fl2), \
10714 GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0x01, opc3 | 0x10, 0, PPC_NONE, fl2), \
10715 GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0x02, opc3 | 0x10, 0, PPC_NONE, fl2), \
10716 GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0x03, opc3 | 0x10, 0, PPC_NONE, fl2)
10717
10718 #undef GEN_XX3FORM_DM
10719 #define GEN_XX3FORM_DM(name, opc2, opc3) \
10720 GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x00, opc3|0x00, 0, PPC_NONE, PPC2_VSX),\
10721 GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x01, opc3|0x00, 0, PPC_NONE, PPC2_VSX),\
10722 GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x02, opc3|0x00, 0, PPC_NONE, PPC2_VSX),\
10723 GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x03, opc3|0x00, 0, PPC_NONE, PPC2_VSX),\
10724 GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x00, opc3|0x04, 0, PPC_NONE, PPC2_VSX),\
10725 GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x01, opc3|0x04, 0, PPC_NONE, PPC2_VSX),\
10726 GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x02, opc3|0x04, 0, PPC_NONE, PPC2_VSX),\
10727 GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x03, opc3|0x04, 0, PPC_NONE, PPC2_VSX),\
10728 GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x00, opc3|0x08, 0, PPC_NONE, PPC2_VSX),\
10729 GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x01, opc3|0x08, 0, PPC_NONE, PPC2_VSX),\
10730 GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x02, opc3|0x08, 0, PPC_NONE, PPC2_VSX),\
10731 GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x03, opc3|0x08, 0, PPC_NONE, PPC2_VSX),\
10732 GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x00, opc3|0x0C, 0, PPC_NONE, PPC2_VSX),\
10733 GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x01, opc3|0x0C, 0, PPC_NONE, PPC2_VSX),\
10734 GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x02, opc3|0x0C, 0, PPC_NONE, PPC2_VSX),\
10735 GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x03, opc3|0x0C, 0, PPC_NONE, PPC2_VSX)
10736
10737 GEN_XX2FORM(xsabsdp, 0x12, 0x15, PPC2_VSX),
10738 GEN_XX2FORM(xsnabsdp, 0x12, 0x16, PPC2_VSX),
10739 GEN_XX2FORM(xsnegdp, 0x12, 0x17, PPC2_VSX),
10740 GEN_XX3FORM(xscpsgndp, 0x00, 0x16, PPC2_VSX),
10741
10742 GEN_XX2FORM(xvabsdp, 0x12, 0x1D, PPC2_VSX),
10743 GEN_XX2FORM(xvnabsdp, 0x12, 0x1E, PPC2_VSX),
10744 GEN_XX2FORM(xvnegdp, 0x12, 0x1F, PPC2_VSX),
10745 GEN_XX3FORM(xvcpsgndp, 0x00, 0x1E, PPC2_VSX),
10746 GEN_XX2FORM(xvabssp, 0x12, 0x19, PPC2_VSX),
10747 GEN_XX2FORM(xvnabssp, 0x12, 0x1A, PPC2_VSX),
10748 GEN_XX2FORM(xvnegsp, 0x12, 0x1B, PPC2_VSX),
10749 GEN_XX3FORM(xvcpsgnsp, 0x00, 0x1A, PPC2_VSX),
10750
10751 GEN_XX3FORM(xsadddp, 0x00, 0x04, PPC2_VSX),
10752 GEN_XX3FORM(xssubdp, 0x00, 0x05, PPC2_VSX),
10753 GEN_XX3FORM(xsmuldp, 0x00, 0x06, PPC2_VSX),
10754 GEN_XX3FORM(xsdivdp, 0x00, 0x07, PPC2_VSX),
10755 GEN_XX2FORM(xsredp,  0x14, 0x05, PPC2_VSX),
10756 GEN_XX2FORM(xssqrtdp,  0x16, 0x04, PPC2_VSX),
10757 GEN_XX2FORM(xsrsqrtedp,  0x14, 0x04, PPC2_VSX),
10758 GEN_XX3FORM(xstdivdp,  0x14, 0x07, PPC2_VSX),
10759 GEN_XX2FORM(xstsqrtdp,  0x14, 0x06, PPC2_VSX),
10760 GEN_XX3FORM(xsmaddadp, 0x04, 0x04, PPC2_VSX),
10761 GEN_XX3FORM(xsmaddmdp, 0x04, 0x05, PPC2_VSX),
10762 GEN_XX3FORM(xsmsubadp, 0x04, 0x06, PPC2_VSX),
10763 GEN_XX3FORM(xsmsubmdp, 0x04, 0x07, PPC2_VSX),
10764 GEN_XX3FORM(xsnmaddadp, 0x04, 0x14, PPC2_VSX),
10765 GEN_XX3FORM(xsnmaddmdp, 0x04, 0x15, PPC2_VSX),
10766 GEN_XX3FORM(xsnmsubadp, 0x04, 0x16, PPC2_VSX),
10767 GEN_XX3FORM(xsnmsubmdp, 0x04, 0x17, PPC2_VSX),
10768 GEN_XX2IFORM(xscmpodp,  0x0C, 0x05, PPC2_VSX),
10769 GEN_XX2IFORM(xscmpudp,  0x0C, 0x04, PPC2_VSX),
10770 GEN_XX3FORM(xsmaxdp, 0x00, 0x14, PPC2_VSX),
10771 GEN_XX3FORM(xsmindp, 0x00, 0x15, PPC2_VSX),
10772 GEN_XX2FORM(xscvdpsp, 0x12, 0x10, PPC2_VSX),
10773 GEN_XX2FORM(xscvdpspn, 0x16, 0x10, PPC2_VSX207),
10774 GEN_XX2FORM(xscvspdp, 0x12, 0x14, PPC2_VSX),
10775 GEN_XX2FORM(xscvspdpn, 0x16, 0x14, PPC2_VSX207),
10776 GEN_XX2FORM(xscvdpsxds, 0x10, 0x15, PPC2_VSX),
10777 GEN_XX2FORM(xscvdpsxws, 0x10, 0x05, PPC2_VSX),
10778 GEN_XX2FORM(xscvdpuxds, 0x10, 0x14, PPC2_VSX),
10779 GEN_XX2FORM(xscvdpuxws, 0x10, 0x04, PPC2_VSX),
10780 GEN_XX2FORM(xscvsxddp, 0x10, 0x17, PPC2_VSX),
10781 GEN_XX2FORM(xscvuxddp, 0x10, 0x16, PPC2_VSX),
10782 GEN_XX2FORM(xsrdpi, 0x12, 0x04, PPC2_VSX),
10783 GEN_XX2FORM(xsrdpic, 0x16, 0x06, PPC2_VSX),
10784 GEN_XX2FORM(xsrdpim, 0x12, 0x07, PPC2_VSX),
10785 GEN_XX2FORM(xsrdpip, 0x12, 0x06, PPC2_VSX),
10786 GEN_XX2FORM(xsrdpiz, 0x12, 0x05, PPC2_VSX),
10787
10788 GEN_XX3FORM(xsaddsp, 0x00, 0x00, PPC2_VSX207),
10789 GEN_XX3FORM(xssubsp, 0x00, 0x01, PPC2_VSX207),
10790 GEN_XX3FORM(xsmulsp, 0x00, 0x02, PPC2_VSX207),
10791 GEN_XX3FORM(xsdivsp, 0x00, 0x03, PPC2_VSX207),
10792 GEN_XX2FORM(xsresp,  0x14, 0x01, PPC2_VSX207),
10793 GEN_XX2FORM(xsrsp, 0x12, 0x11, PPC2_VSX207),
10794 GEN_XX2FORM(xssqrtsp,  0x16, 0x00, PPC2_VSX207),
10795 GEN_XX2FORM(xsrsqrtesp,  0x14, 0x00, PPC2_VSX207),
10796 GEN_XX3FORM(xsmaddasp, 0x04, 0x00, PPC2_VSX207),
10797 GEN_XX3FORM(xsmaddmsp, 0x04, 0x01, PPC2_VSX207),
10798 GEN_XX3FORM(xsmsubasp, 0x04, 0x02, PPC2_VSX207),
10799 GEN_XX3FORM(xsmsubmsp, 0x04, 0x03, PPC2_VSX207),
10800 GEN_XX3FORM(xsnmaddasp, 0x04, 0x10, PPC2_VSX207),
10801 GEN_XX3FORM(xsnmaddmsp, 0x04, 0x11, PPC2_VSX207),
10802 GEN_XX3FORM(xsnmsubasp, 0x04, 0x12, PPC2_VSX207),
10803 GEN_XX3FORM(xsnmsubmsp, 0x04, 0x13, PPC2_VSX207),
10804 GEN_XX2FORM(xscvsxdsp, 0x10, 0x13, PPC2_VSX207),
10805 GEN_XX2FORM(xscvuxdsp, 0x10, 0x12, PPC2_VSX207),
10806
10807 GEN_XX3FORM(xvadddp, 0x00, 0x0C, PPC2_VSX),
10808 GEN_XX3FORM(xvsubdp, 0x00, 0x0D, PPC2_VSX),
10809 GEN_XX3FORM(xvmuldp, 0x00, 0x0E, PPC2_VSX),
10810 GEN_XX3FORM(xvdivdp, 0x00, 0x0F, PPC2_VSX),
10811 GEN_XX2FORM(xvredp,  0x14, 0x0D, PPC2_VSX),
10812 GEN_XX2FORM(xvsqrtdp,  0x16, 0x0C, PPC2_VSX),
10813 GEN_XX2FORM(xvrsqrtedp,  0x14, 0x0C, PPC2_VSX),
10814 GEN_XX3FORM(xvtdivdp, 0x14, 0x0F, PPC2_VSX),
10815 GEN_XX2FORM(xvtsqrtdp, 0x14, 0x0E, PPC2_VSX),
10816 GEN_XX3FORM(xvmaddadp, 0x04, 0x0C, PPC2_VSX),
10817 GEN_XX3FORM(xvmaddmdp, 0x04, 0x0D, PPC2_VSX),
10818 GEN_XX3FORM(xvmsubadp, 0x04, 0x0E, PPC2_VSX),
10819 GEN_XX3FORM(xvmsubmdp, 0x04, 0x0F, PPC2_VSX),
10820 GEN_XX3FORM(xvnmaddadp, 0x04, 0x1C, PPC2_VSX),
10821 GEN_XX3FORM(xvnmaddmdp, 0x04, 0x1D, PPC2_VSX),
10822 GEN_XX3FORM(xvnmsubadp, 0x04, 0x1E, PPC2_VSX),
10823 GEN_XX3FORM(xvnmsubmdp, 0x04, 0x1F, PPC2_VSX),
10824 GEN_XX3FORM(xvmaxdp, 0x00, 0x1C, PPC2_VSX),
10825 GEN_XX3FORM(xvmindp, 0x00, 0x1D, PPC2_VSX),
10826 GEN_XX3_RC_FORM(xvcmpeqdp, 0x0C, 0x0C, PPC2_VSX),
10827 GEN_XX3_RC_FORM(xvcmpgtdp, 0x0C, 0x0D, PPC2_VSX),
10828 GEN_XX3_RC_FORM(xvcmpgedp, 0x0C, 0x0E, PPC2_VSX),
10829 GEN_XX2FORM(xvcvdpsp, 0x12, 0x18, PPC2_VSX),
10830 GEN_XX2FORM(xvcvdpsxds, 0x10, 0x1D, PPC2_VSX),
10831 GEN_XX2FORM(xvcvdpsxws, 0x10, 0x0D, PPC2_VSX),
10832 GEN_XX2FORM(xvcvdpuxds, 0x10, 0x1C, PPC2_VSX),
10833 GEN_XX2FORM(xvcvdpuxws, 0x10, 0x0C, PPC2_VSX),
10834 GEN_XX2FORM(xvcvsxddp, 0x10, 0x1F, PPC2_VSX),
10835 GEN_XX2FORM(xvcvuxddp, 0x10, 0x1E, PPC2_VSX),
10836 GEN_XX2FORM(xvcvsxwdp, 0x10, 0x0F, PPC2_VSX),
10837 GEN_XX2FORM(xvcvuxwdp, 0x10, 0x0E, PPC2_VSX),
10838 GEN_XX2FORM(xvrdpi, 0x12, 0x0C, PPC2_VSX),
10839 GEN_XX2FORM(xvrdpic, 0x16, 0x0E, PPC2_VSX),
10840 GEN_XX2FORM(xvrdpim, 0x12, 0x0F, PPC2_VSX),
10841 GEN_XX2FORM(xvrdpip, 0x12, 0x0E, PPC2_VSX),
10842 GEN_XX2FORM(xvrdpiz, 0x12, 0x0D, PPC2_VSX),
10843
10844 GEN_XX3FORM(xvaddsp, 0x00, 0x08, PPC2_VSX),
10845 GEN_XX3FORM(xvsubsp, 0x00, 0x09, PPC2_VSX),
10846 GEN_XX3FORM(xvmulsp, 0x00, 0x0A, PPC2_VSX),
10847 GEN_XX3FORM(xvdivsp, 0x00, 0x0B, PPC2_VSX),
10848 GEN_XX2FORM(xvresp, 0x14, 0x09, PPC2_VSX),
10849 GEN_XX2FORM(xvsqrtsp, 0x16, 0x08, PPC2_VSX),
10850 GEN_XX2FORM(xvrsqrtesp, 0x14, 0x08, PPC2_VSX),
10851 GEN_XX3FORM(xvtdivsp, 0x14, 0x0B, PPC2_VSX),
10852 GEN_XX2FORM(xvtsqrtsp, 0x14, 0x0A, PPC2_VSX),
10853 GEN_XX3FORM(xvmaddasp, 0x04, 0x08, PPC2_VSX),
10854 GEN_XX3FORM(xvmaddmsp, 0x04, 0x09, PPC2_VSX),
10855 GEN_XX3FORM(xvmsubasp, 0x04, 0x0A, PPC2_VSX),
10856 GEN_XX3FORM(xvmsubmsp, 0x04, 0x0B, PPC2_VSX),
10857 GEN_XX3FORM(xvnmaddasp, 0x04, 0x18, PPC2_VSX),
10858 GEN_XX3FORM(xvnmaddmsp, 0x04, 0x19, PPC2_VSX),
10859 GEN_XX3FORM(xvnmsubasp, 0x04, 0x1A, PPC2_VSX),
10860 GEN_XX3FORM(xvnmsubmsp, 0x04, 0x1B, PPC2_VSX),
10861 GEN_XX3FORM(xvmaxsp, 0x00, 0x18, PPC2_VSX),
10862 GEN_XX3FORM(xvminsp, 0x00, 0x19, PPC2_VSX),
10863 GEN_XX3_RC_FORM(xvcmpeqsp, 0x0C, 0x08, PPC2_VSX),
10864 GEN_XX3_RC_FORM(xvcmpgtsp, 0x0C, 0x09, PPC2_VSX),
10865 GEN_XX3_RC_FORM(xvcmpgesp, 0x0C, 0x0A, PPC2_VSX),
10866 GEN_XX2FORM(xvcvspdp, 0x12, 0x1C, PPC2_VSX),
10867 GEN_XX2FORM(xvcvspsxds, 0x10, 0x19, PPC2_VSX),
10868 GEN_XX2FORM(xvcvspsxws, 0x10, 0x09, PPC2_VSX),
10869 GEN_XX2FORM(xvcvspuxds, 0x10, 0x18, PPC2_VSX),
10870 GEN_XX2FORM(xvcvspuxws, 0x10, 0x08, PPC2_VSX),
10871 GEN_XX2FORM(xvcvsxdsp, 0x10, 0x1B, PPC2_VSX),
10872 GEN_XX2FORM(xvcvuxdsp, 0x10, 0x1A, PPC2_VSX),
10873 GEN_XX2FORM(xvcvsxwsp, 0x10, 0x0B, PPC2_VSX),
10874 GEN_XX2FORM(xvcvuxwsp, 0x10, 0x0A, PPC2_VSX),
10875 GEN_XX2FORM(xvrspi, 0x12, 0x08, PPC2_VSX),
10876 GEN_XX2FORM(xvrspic, 0x16, 0x0A, PPC2_VSX),
10877 GEN_XX2FORM(xvrspim, 0x12, 0x0B, PPC2_VSX),
10878 GEN_XX2FORM(xvrspip, 0x12, 0x0A, PPC2_VSX),
10879 GEN_XX2FORM(xvrspiz, 0x12, 0x09, PPC2_VSX),
10880
10881 #undef VSX_LOGICAL
10882 #define VSX_LOGICAL(name, opc2, opc3, fl2) \
10883 GEN_XX3FORM(name, opc2, opc3, fl2)
10884
10885 VSX_LOGICAL(xxland, 0x8, 0x10, PPC2_VSX),
10886 VSX_LOGICAL(xxlandc, 0x8, 0x11, PPC2_VSX),
10887 VSX_LOGICAL(xxlor, 0x8, 0x12, PPC2_VSX),
10888 VSX_LOGICAL(xxlxor, 0x8, 0x13, PPC2_VSX),
10889 VSX_LOGICAL(xxlnor, 0x8, 0x14, PPC2_VSX),
10890 VSX_LOGICAL(xxleqv, 0x8, 0x17, PPC2_VSX207),
10891 VSX_LOGICAL(xxlnand, 0x8, 0x16, PPC2_VSX207),
10892 VSX_LOGICAL(xxlorc, 0x8, 0x15, PPC2_VSX207),
10893 GEN_XX3FORM(xxmrghw, 0x08, 0x02, PPC2_VSX),
10894 GEN_XX3FORM(xxmrglw, 0x08, 0x06, PPC2_VSX),
10895 GEN_XX2FORM(xxspltw, 0x08, 0x0A, PPC2_VSX),
10896 GEN_XX3FORM_DM(xxsldwi, 0x08, 0x00),
10897
10898 #define GEN_XXSEL_ROW(opc3) \
10899 GEN_HANDLER2_E(xxsel, "xxsel", 0x3C, 0x18, opc3, 0, PPC_NONE, PPC2_VSX), \
10900 GEN_HANDLER2_E(xxsel, "xxsel", 0x3C, 0x19, opc3, 0, PPC_NONE, PPC2_VSX), \
10901 GEN_HANDLER2_E(xxsel, "xxsel", 0x3C, 0x1A, opc3, 0, PPC_NONE, PPC2_VSX), \
10902 GEN_HANDLER2_E(xxsel, "xxsel", 0x3C, 0x1B, opc3, 0, PPC_NONE, PPC2_VSX), \
10903 GEN_HANDLER2_E(xxsel, "xxsel", 0x3C, 0x1C, opc3, 0, PPC_NONE, PPC2_VSX), \
10904 GEN_HANDLER2_E(xxsel, "xxsel", 0x3C, 0x1D, opc3, 0, PPC_NONE, PPC2_VSX), \
10905 GEN_HANDLER2_E(xxsel, "xxsel", 0x3C, 0x1E, opc3, 0, PPC_NONE, PPC2_VSX), \
10906 GEN_HANDLER2_E(xxsel, "xxsel", 0x3C, 0x1F, opc3, 0, PPC_NONE, PPC2_VSX), \
10907
10908 GEN_XXSEL_ROW(0x00)
10909 GEN_XXSEL_ROW(0x01)
10910 GEN_XXSEL_ROW(0x02)
10911 GEN_XXSEL_ROW(0x03)
10912 GEN_XXSEL_ROW(0x04)
10913 GEN_XXSEL_ROW(0x05)
10914 GEN_XXSEL_ROW(0x06)
10915 GEN_XXSEL_ROW(0x07)
10916 GEN_XXSEL_ROW(0x08)
10917 GEN_XXSEL_ROW(0x09)
10918 GEN_XXSEL_ROW(0x0A)
10919 GEN_XXSEL_ROW(0x0B)
10920 GEN_XXSEL_ROW(0x0C)
10921 GEN_XXSEL_ROW(0x0D)
10922 GEN_XXSEL_ROW(0x0E)
10923 GEN_XXSEL_ROW(0x0F)
10924 GEN_XXSEL_ROW(0x10)
10925 GEN_XXSEL_ROW(0x11)
10926 GEN_XXSEL_ROW(0x12)
10927 GEN_XXSEL_ROW(0x13)
10928 GEN_XXSEL_ROW(0x14)
10929 GEN_XXSEL_ROW(0x15)
10930 GEN_XXSEL_ROW(0x16)
10931 GEN_XXSEL_ROW(0x17)
10932 GEN_XXSEL_ROW(0x18)
10933 GEN_XXSEL_ROW(0x19)
10934 GEN_XXSEL_ROW(0x1A)
10935 GEN_XXSEL_ROW(0x1B)
10936 GEN_XXSEL_ROW(0x1C)
10937 GEN_XXSEL_ROW(0x1D)
10938 GEN_XXSEL_ROW(0x1E)
10939 GEN_XXSEL_ROW(0x1F)
10940
10941 GEN_XX3FORM_DM(xxpermdi, 0x08, 0x01),
10942
10943 #undef GEN_DFP_T_A_B_Rc
10944 #undef GEN_DFP_BF_A_B
10945 #undef GEN_DFP_BF_A_DCM
10946 #undef GEN_DFP_T_B_U32_U32_Rc
10947 #undef GEN_DFP_T_A_B_I32_Rc
10948 #undef GEN_DFP_T_B_Rc
10949 #undef GEN_DFP_T_FPR_I32_Rc
10950
10951 #define _GEN_DFP_LONG(name, op1, op2, mask) \
10952 GEN_HANDLER_E(name, 0x3B, op1, op2, mask, PPC_NONE, PPC2_DFP)
10953
10954 #define _GEN_DFP_LONGx2(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, 0x10 | op2, mask, PPC_NONE, PPC2_DFP)
10957
10958 #define _GEN_DFP_LONGx4(name, op1, op2, mask) \
10959 GEN_HANDLER_E(name, 0x3B, op1, 0x00 | op2, mask, PPC_NONE, PPC2_DFP), \
10960 GEN_HANDLER_E(name, 0x3B, op1, 0x08 | op2, mask, PPC_NONE, PPC2_DFP), \
10961 GEN_HANDLER_E(name, 0x3B, op1, 0x10 | op2, mask, PPC_NONE, PPC2_DFP), \
10962 GEN_HANDLER_E(name, 0x3B, op1, 0x18 | op2, mask, PPC_NONE, PPC2_DFP)
10963
10964 #define _GEN_DFP_QUAD(name, op1, op2, mask) \
10965 GEN_HANDLER_E(name, 0x3F, op1, op2, mask, PPC_NONE, PPC2_DFP)
10966
10967 #define _GEN_DFP_QUADx2(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, 0x10 | op2, mask, PPC_NONE, PPC2_DFP)
10970
10971 #define _GEN_DFP_QUADx4(name, op1, op2, mask)                         \
10972 GEN_HANDLER_E(name, 0x3F, op1, 0x00 | op2, mask, PPC_NONE, PPC2_DFP), \
10973 GEN_HANDLER_E(name, 0x3F, op1, 0x08 | op2, mask, PPC_NONE, PPC2_DFP), \
10974 GEN_HANDLER_E(name, 0x3F, op1, 0x10 | op2, mask, PPC_NONE, PPC2_DFP), \
10975 GEN_HANDLER_E(name, 0x3F, op1, 0x18 | op2, mask, PPC_NONE, PPC2_DFP)
10976
10977 #define GEN_DFP_T_A_B_Rc(name, op1, op2) \
10978 _GEN_DFP_LONG(name, op1, op2, 0x00000000)
10979
10980 #define GEN_DFP_Tp_Ap_Bp_Rc(name, op1, op2) \
10981 _GEN_DFP_QUAD(name, op1, op2, 0x00210800)
10982
10983 #define GEN_DFP_Tp_A_Bp_Rc(name, op1, op2) \
10984 _GEN_DFP_QUAD(name, op1, op2, 0x00200800)
10985
10986 #define GEN_DFP_T_B_Rc(name, op1, op2) \
10987 _GEN_DFP_LONG(name, op1, op2, 0x001F0000)
10988
10989 #define GEN_DFP_Tp_Bp_Rc(name, op1, op2) \
10990 _GEN_DFP_QUAD(name, op1, op2, 0x003F0800)
10991
10992 #define GEN_DFP_Tp_B_Rc(name, op1, op2) \
10993 _GEN_DFP_QUAD(name, op1, op2, 0x003F0000)
10994
10995 #define GEN_DFP_T_Bp_Rc(name, op1, op2) \
10996 _GEN_DFP_QUAD(name, op1, op2, 0x001F0800)
10997
10998 #define GEN_DFP_BF_A_B(name, op1, op2) \
10999 _GEN_DFP_LONG(name, op1, op2, 0x00000001)
11000
11001 #define GEN_DFP_BF_Ap_Bp(name, op1, op2) \
11002 _GEN_DFP_QUAD(name, op1, op2, 0x00610801)
11003
11004 #define GEN_DFP_BF_A_Bp(name, op1, op2) \
11005 _GEN_DFP_QUAD(name, op1, op2, 0x00600801)
11006
11007 #define GEN_DFP_BF_A_DCM(name, op1, op2) \
11008 _GEN_DFP_LONGx2(name, op1, op2, 0x00600001)
11009
11010 #define GEN_DFP_BF_Ap_DCM(name, op1, op2) \
11011 _GEN_DFP_QUADx2(name, op1, op2, 0x00610001)
11012
11013 #define GEN_DFP_T_A_B_RMC_Rc(name, op1, op2) \
11014 _GEN_DFP_LONGx4(name, op1, op2, 0x00000000)
11015
11016 #define GEN_DFP_Tp_Ap_Bp_RMC_Rc(name, op1, op2) \
11017 _GEN_DFP_QUADx4(name, op1, op2, 0x02010800)
11018
11019 #define GEN_DFP_Tp_A_Bp_RMC_Rc(name, op1, op2) \
11020 _GEN_DFP_QUADx4(name, op1, op2, 0x02000800)
11021
11022 #define GEN_DFP_TE_T_B_RMC_Rc(name, op1, op2) \
11023 _GEN_DFP_LONGx4(name, op1, op2, 0x00000000)
11024
11025 #define GEN_DFP_TE_Tp_Bp_RMC_Rc(name, op1, op2) \
11026 _GEN_DFP_QUADx4(name, op1, op2, 0x00200800)
11027
11028 #define GEN_DFP_R_T_B_RMC_Rc(name, op1, op2) \
11029 _GEN_DFP_LONGx4(name, op1, op2, 0x001E0000)
11030
11031 #define GEN_DFP_R_Tp_Bp_RMC_Rc(name, op1, op2) \
11032 _GEN_DFP_QUADx4(name, op1, op2, 0x003E0800)
11033
11034 #define GEN_DFP_SP_T_B_Rc(name, op1, op2) \
11035 _GEN_DFP_LONG(name, op1, op2, 0x00070000)
11036
11037 #define GEN_DFP_SP_Tp_Bp_Rc(name, op1, op2) \
11038 _GEN_DFP_QUAD(name, op1, op2, 0x00270800)
11039
11040 #define GEN_DFP_S_T_B_Rc(name, op1, op2) \
11041 _GEN_DFP_LONG(name, op1, op2, 0x000F0000)
11042
11043 #define GEN_DFP_S_Tp_Bp_Rc(name, op1, op2) \
11044 _GEN_DFP_QUAD(name, op1, op2, 0x002F0800)
11045
11046 #define GEN_DFP_T_A_SH_Rc(name, op1, op2) \
11047 _GEN_DFP_LONGx2(name, op1, op2, 0x00000000)
11048
11049 #define GEN_DFP_Tp_Ap_SH_Rc(name, op1, op2) \
11050 _GEN_DFP_QUADx2(name, op1, op2, 0x00210000)
11051
11052 GEN_DFP_T_A_B_Rc(dadd, 0x02, 0x00),
11053 GEN_DFP_Tp_Ap_Bp_Rc(daddq, 0x02, 0x00),
11054 GEN_DFP_T_A_B_Rc(dsub, 0x02, 0x10),
11055 GEN_DFP_Tp_Ap_Bp_Rc(dsubq, 0x02, 0x10),
11056 GEN_DFP_T_A_B_Rc(dmul, 0x02, 0x01),
11057 GEN_DFP_Tp_Ap_Bp_Rc(dmulq, 0x02, 0x01),
11058 GEN_DFP_T_A_B_Rc(ddiv, 0x02, 0x11),
11059 GEN_DFP_Tp_Ap_Bp_Rc(ddivq, 0x02, 0x11),
11060 GEN_DFP_BF_A_B(dcmpu, 0x02, 0x14),
11061 GEN_DFP_BF_Ap_Bp(dcmpuq, 0x02, 0x14),
11062 GEN_DFP_BF_A_B(dcmpo, 0x02, 0x04),
11063 GEN_DFP_BF_Ap_Bp(dcmpoq, 0x02, 0x04),
11064 GEN_DFP_BF_A_DCM(dtstdc, 0x02, 0x06),
11065 GEN_DFP_BF_Ap_DCM(dtstdcq, 0x02, 0x06),
11066 GEN_DFP_BF_A_DCM(dtstdg, 0x02, 0x07),
11067 GEN_DFP_BF_Ap_DCM(dtstdgq, 0x02, 0x07),
11068 GEN_DFP_BF_A_B(dtstex, 0x02, 0x05),
11069 GEN_DFP_BF_Ap_Bp(dtstexq, 0x02, 0x05),
11070 GEN_DFP_BF_A_B(dtstsf, 0x02, 0x15),
11071 GEN_DFP_BF_A_Bp(dtstsfq, 0x02, 0x15),
11072 GEN_DFP_TE_T_B_RMC_Rc(dquai, 0x03, 0x02),
11073 GEN_DFP_TE_Tp_Bp_RMC_Rc(dquaiq, 0x03, 0x02),
11074 GEN_DFP_T_A_B_RMC_Rc(dqua, 0x03, 0x00),
11075 GEN_DFP_Tp_Ap_Bp_RMC_Rc(dquaq, 0x03, 0x00),
11076 GEN_DFP_T_A_B_RMC_Rc(drrnd, 0x03, 0x01),
11077 GEN_DFP_Tp_A_Bp_RMC_Rc(drrndq, 0x03, 0x01),
11078 GEN_DFP_R_T_B_RMC_Rc(drintx, 0x03, 0x03),
11079 GEN_DFP_R_Tp_Bp_RMC_Rc(drintxq, 0x03, 0x03),
11080 GEN_DFP_R_T_B_RMC_Rc(drintn, 0x03, 0x07),
11081 GEN_DFP_R_Tp_Bp_RMC_Rc(drintnq, 0x03, 0x07),
11082 GEN_DFP_T_B_Rc(dctdp, 0x02, 0x08),
11083 GEN_DFP_Tp_B_Rc(dctqpq, 0x02, 0x08),
11084 GEN_DFP_T_B_Rc(drsp, 0x02, 0x18),
11085 GEN_DFP_Tp_Bp_Rc(drdpq, 0x02, 0x18),
11086 GEN_DFP_T_B_Rc(dcffix, 0x02, 0x19),
11087 GEN_DFP_Tp_B_Rc(dcffixq, 0x02, 0x19),
11088 GEN_DFP_T_B_Rc(dctfix, 0x02, 0x09),
11089 GEN_DFP_T_Bp_Rc(dctfixq, 0x02, 0x09),
11090 GEN_DFP_SP_T_B_Rc(ddedpd, 0x02, 0x0a),
11091 GEN_DFP_SP_Tp_Bp_Rc(ddedpdq, 0x02, 0x0a),
11092 GEN_DFP_S_T_B_Rc(denbcd, 0x02, 0x1a),
11093 GEN_DFP_S_Tp_Bp_Rc(denbcdq, 0x02, 0x1a),
11094 GEN_DFP_T_B_Rc(dxex, 0x02, 0x0b),
11095 GEN_DFP_T_Bp_Rc(dxexq, 0x02, 0x0b),
11096 GEN_DFP_T_A_B_Rc(diex, 0x02, 0x1b),
11097 GEN_DFP_Tp_A_Bp_Rc(diexq, 0x02, 0x1b),
11098 GEN_DFP_T_A_SH_Rc(dscli, 0x02, 0x02),
11099 GEN_DFP_Tp_Ap_SH_Rc(dscliq, 0x02, 0x02),
11100 GEN_DFP_T_A_SH_Rc(dscri, 0x02, 0x03),
11101 GEN_DFP_Tp_Ap_SH_Rc(dscriq, 0x02, 0x03),
11102
11103 #undef GEN_SPE
11104 #define GEN_SPE(name0, name1, opc2, opc3, inval0, inval1, type) \
11105     GEN_OPCODE_DUAL(name0##_##name1, 0x04, opc2, opc3, inval0, inval1, type, PPC_NONE)
11106 GEN_SPE(evaddw,      speundef,    0x00, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
11107 GEN_SPE(evaddiw,     speundef,    0x01, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
11108 GEN_SPE(evsubfw,     speundef,    0x02, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
11109 GEN_SPE(evsubifw,    speundef,    0x03, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
11110 GEN_SPE(evabs,       evneg,       0x04, 0x08, 0x0000F800, 0x0000F800, PPC_SPE),
11111 GEN_SPE(evextsb,     evextsh,     0x05, 0x08, 0x0000F800, 0x0000F800, PPC_SPE),
11112 GEN_SPE(evrndw,      evcntlzw,    0x06, 0x08, 0x0000F800, 0x0000F800, PPC_SPE),
11113 GEN_SPE(evcntlsw,    brinc,       0x07, 0x08, 0x0000F800, 0x00000000, PPC_SPE),
11114 GEN_SPE(evmra,       speundef,    0x02, 0x13, 0x0000F800, 0xFFFFFFFF, PPC_SPE),
11115 GEN_SPE(speundef,    evand,       0x08, 0x08, 0xFFFFFFFF, 0x00000000, PPC_SPE),
11116 GEN_SPE(evandc,      speundef,    0x09, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
11117 GEN_SPE(evxor,       evor,        0x0B, 0x08, 0x00000000, 0x00000000, PPC_SPE),
11118 GEN_SPE(evnor,       eveqv,       0x0C, 0x08, 0x00000000, 0x00000000, PPC_SPE),
11119 GEN_SPE(evmwumi,     evmwsmi,     0x0C, 0x11, 0x00000000, 0x00000000, PPC_SPE),
11120 GEN_SPE(evmwumia,    evmwsmia,    0x1C, 0x11, 0x00000000, 0x00000000, PPC_SPE),
11121 GEN_SPE(evmwumiaa,   evmwsmiaa,   0x0C, 0x15, 0x00000000, 0x00000000, PPC_SPE),
11122 GEN_SPE(speundef,    evorc,       0x0D, 0x08, 0xFFFFFFFF, 0x00000000, PPC_SPE),
11123 GEN_SPE(evnand,      speundef,    0x0F, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
11124 GEN_SPE(evsrwu,      evsrws,      0x10, 0x08, 0x00000000, 0x00000000, PPC_SPE),
11125 GEN_SPE(evsrwiu,     evsrwis,     0x11, 0x08, 0x00000000, 0x00000000, PPC_SPE),
11126 GEN_SPE(evslw,       speundef,    0x12, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
11127 GEN_SPE(evslwi,      speundef,    0x13, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
11128 GEN_SPE(evrlw,       evsplati,    0x14, 0x08, 0x00000000, 0x0000F800, PPC_SPE),
11129 GEN_SPE(evrlwi,      evsplatfi,   0x15, 0x08, 0x00000000, 0x0000F800, PPC_SPE),
11130 GEN_SPE(evmergehi,   evmergelo,   0x16, 0x08, 0x00000000, 0x00000000, PPC_SPE),
11131 GEN_SPE(evmergehilo, evmergelohi, 0x17, 0x08, 0x00000000, 0x00000000, PPC_SPE),
11132 GEN_SPE(evcmpgtu,    evcmpgts,    0x18, 0x08, 0x00600000, 0x00600000, PPC_SPE),
11133 GEN_SPE(evcmpltu,    evcmplts,    0x19, 0x08, 0x00600000, 0x00600000, PPC_SPE),
11134 GEN_SPE(evcmpeq,     speundef,    0x1A, 0x08, 0x00600000, 0xFFFFFFFF, PPC_SPE),
11135
11136 GEN_SPE(evfsadd,     evfssub,     0x00, 0x0A, 0x00000000, 0x00000000, PPC_SPE_SINGLE),
11137 GEN_SPE(evfsabs,     evfsnabs,    0x02, 0x0A, 0x0000F800, 0x0000F800, PPC_SPE_SINGLE),
11138 GEN_SPE(evfsneg,     speundef,    0x03, 0x0A, 0x0000F800, 0xFFFFFFFF, PPC_SPE_SINGLE),
11139 GEN_SPE(evfsmul,     evfsdiv,     0x04, 0x0A, 0x00000000, 0x00000000, PPC_SPE_SINGLE),
11140 GEN_SPE(evfscmpgt,   evfscmplt,   0x06, 0x0A, 0x00600000, 0x00600000, PPC_SPE_SINGLE),
11141 GEN_SPE(evfscmpeq,   speundef,    0x07, 0x0A, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE),
11142 GEN_SPE(evfscfui,    evfscfsi,    0x08, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
11143 GEN_SPE(evfscfuf,    evfscfsf,    0x09, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
11144 GEN_SPE(evfsctui,    evfsctsi,    0x0A, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
11145 GEN_SPE(evfsctuf,    evfsctsf,    0x0B, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
11146 GEN_SPE(evfsctuiz,   speundef,    0x0C, 0x0A, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE),
11147 GEN_SPE(evfsctsiz,   speundef,    0x0D, 0x0A, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE),
11148 GEN_SPE(evfststgt,   evfststlt,   0x0E, 0x0A, 0x00600000, 0x00600000, PPC_SPE_SINGLE),
11149 GEN_SPE(evfststeq,   speundef,    0x0F, 0x0A, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE),
11150
11151 GEN_SPE(efsadd,      efssub,      0x00, 0x0B, 0x00000000, 0x00000000, PPC_SPE_SINGLE),
11152 GEN_SPE(efsabs,      efsnabs,     0x02, 0x0B, 0x0000F800, 0x0000F800, PPC_SPE_SINGLE),
11153 GEN_SPE(efsneg,      speundef,    0x03, 0x0B, 0x0000F800, 0xFFFFFFFF, PPC_SPE_SINGLE),
11154 GEN_SPE(efsmul,      efsdiv,      0x04, 0x0B, 0x00000000, 0x00000000, PPC_SPE_SINGLE),
11155 GEN_SPE(efscmpgt,    efscmplt,    0x06, 0x0B, 0x00600000, 0x00600000, PPC_SPE_SINGLE),
11156 GEN_SPE(efscmpeq,    efscfd,      0x07, 0x0B, 0x00600000, 0x00180000, PPC_SPE_SINGLE),
11157 GEN_SPE(efscfui,     efscfsi,     0x08, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
11158 GEN_SPE(efscfuf,     efscfsf,     0x09, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
11159 GEN_SPE(efsctui,     efsctsi,     0x0A, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
11160 GEN_SPE(efsctuf,     efsctsf,     0x0B, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
11161 GEN_SPE(efsctuiz,    speundef,    0x0C, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE),
11162 GEN_SPE(efsctsiz,    speundef,    0x0D, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE),
11163 GEN_SPE(efststgt,    efststlt,    0x0E, 0x0B, 0x00600000, 0x00600000, PPC_SPE_SINGLE),
11164 GEN_SPE(efststeq,    speundef,    0x0F, 0x0B, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE),
11165
11166 GEN_SPE(efdadd,      efdsub,      0x10, 0x0B, 0x00000000, 0x00000000, PPC_SPE_DOUBLE),
11167 GEN_SPE(efdcfuid,    efdcfsid,    0x11, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
11168 GEN_SPE(efdabs,      efdnabs,     0x12, 0x0B, 0x0000F800, 0x0000F800, PPC_SPE_DOUBLE),
11169 GEN_SPE(efdneg,      speundef,    0x13, 0x0B, 0x0000F800, 0xFFFFFFFF, PPC_SPE_DOUBLE),
11170 GEN_SPE(efdmul,      efddiv,      0x14, 0x0B, 0x00000000, 0x00000000, PPC_SPE_DOUBLE),
11171 GEN_SPE(efdctuidz,   efdctsidz,   0x15, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
11172 GEN_SPE(efdcmpgt,    efdcmplt,    0x16, 0x0B, 0x00600000, 0x00600000, PPC_SPE_DOUBLE),
11173 GEN_SPE(efdcmpeq,    efdcfs,      0x17, 0x0B, 0x00600000, 0x00180000, PPC_SPE_DOUBLE),
11174 GEN_SPE(efdcfui,     efdcfsi,     0x18, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
11175 GEN_SPE(efdcfuf,     efdcfsf,     0x19, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
11176 GEN_SPE(efdctui,     efdctsi,     0x1A, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
11177 GEN_SPE(efdctuf,     efdctsf,     0x1B, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
11178 GEN_SPE(efdctuiz,    speundef,    0x1C, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_DOUBLE),
11179 GEN_SPE(efdctsiz,    speundef,    0x1D, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_DOUBLE),
11180 GEN_SPE(efdtstgt,    efdtstlt,    0x1E, 0x0B, 0x00600000, 0x00600000, PPC_SPE_DOUBLE),
11181 GEN_SPE(efdtsteq,    speundef,    0x1F, 0x0B, 0x00600000, 0xFFFFFFFF, PPC_SPE_DOUBLE),
11182
11183 #undef GEN_SPEOP_LDST
11184 #define GEN_SPEOP_LDST(name, opc2, sh)                                        \
11185 GEN_HANDLER(name, 0x04, opc2, 0x0C, 0x00000000, PPC_SPE)
11186 GEN_SPEOP_LDST(evldd, 0x00, 3),
11187 GEN_SPEOP_LDST(evldw, 0x01, 3),
11188 GEN_SPEOP_LDST(evldh, 0x02, 3),
11189 GEN_SPEOP_LDST(evlhhesplat, 0x04, 1),
11190 GEN_SPEOP_LDST(evlhhousplat, 0x06, 1),
11191 GEN_SPEOP_LDST(evlhhossplat, 0x07, 1),
11192 GEN_SPEOP_LDST(evlwhe, 0x08, 2),
11193 GEN_SPEOP_LDST(evlwhou, 0x0A, 2),
11194 GEN_SPEOP_LDST(evlwhos, 0x0B, 2),
11195 GEN_SPEOP_LDST(evlwwsplat, 0x0C, 2),
11196 GEN_SPEOP_LDST(evlwhsplat, 0x0E, 2),
11197
11198 GEN_SPEOP_LDST(evstdd, 0x10, 3),
11199 GEN_SPEOP_LDST(evstdw, 0x11, 3),
11200 GEN_SPEOP_LDST(evstdh, 0x12, 3),
11201 GEN_SPEOP_LDST(evstwhe, 0x18, 2),
11202 GEN_SPEOP_LDST(evstwho, 0x1A, 2),
11203 GEN_SPEOP_LDST(evstwwe, 0x1C, 2),
11204 GEN_SPEOP_LDST(evstwwo, 0x1E, 2),
11205
11206 GEN_HANDLER2_E(tbegin, "tbegin", 0x1F, 0x0E, 0x14, 0x01DFF800, \
11207                PPC_NONE, PPC2_TM),
11208 GEN_HANDLER2_E(tend,   "tend",   0x1F, 0x0E, 0x15, 0x01FFF800, \
11209                PPC_NONE, PPC2_TM),
11210 GEN_HANDLER2_E(tabort, "tabort", 0x1F, 0x0E, 0x1C, 0x03E0F800, \
11211                PPC_NONE, PPC2_TM),
11212 GEN_HANDLER2_E(tabortwc, "tabortwc", 0x1F, 0x0E, 0x18, 0x00000000, \
11213                PPC_NONE, PPC2_TM),
11214 GEN_HANDLER2_E(tabortwci, "tabortwci", 0x1F, 0x0E, 0x1A, 0x00000000, \
11215                PPC_NONE, PPC2_TM),
11216 GEN_HANDLER2_E(tabortdc, "tabortdc", 0x1F, 0x0E, 0x19, 0x00000000, \
11217                PPC_NONE, PPC2_TM),
11218 GEN_HANDLER2_E(tabortdci, "tabortdci", 0x1F, 0x0E, 0x1B, 0x00000000, \
11219                PPC_NONE, PPC2_TM),
11220 GEN_HANDLER2_E(tsr, "tsr", 0x1F, 0x0E, 0x17, 0x03DFF800, \
11221                PPC_NONE, PPC2_TM),
11222 GEN_HANDLER2_E(tcheck, "tcheck", 0x1F, 0x0E, 0x16, 0x007FF800, \
11223                PPC_NONE, PPC2_TM),
11224 GEN_HANDLER2_E(treclaim, "treclaim", 0x1F, 0x0E, 0x1D, 0x03E0F800, \
11225                PPC_NONE, PPC2_TM),
11226 GEN_HANDLER2_E(trechkpt, "trechkpt", 0x1F, 0x0E, 0x1F, 0x03FFF800, \
11227                PPC_NONE, PPC2_TM),
11228 };
11229
11230 #include "helper_regs.h"
11231 #include "translate_init.c"
11232
11233 /*****************************************************************************/
11234 /* Misc PowerPC helpers */
11235 void ppc_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
11236                         int flags)
11237 {
11238 #define RGPL  4
11239 #define RFPL  4
11240
11241     PowerPCCPU *cpu = POWERPC_CPU(cs);
11242     CPUPPCState *env = &cpu->env;
11243     int i;
11244
11245     cpu_fprintf(f, "NIP " TARGET_FMT_lx "   LR " TARGET_FMT_lx " CTR "
11246                 TARGET_FMT_lx " XER " TARGET_FMT_lx " CPU#%d\n",
11247                 env->nip, env->lr, env->ctr, cpu_read_xer(env),
11248                 cs->cpu_index);
11249     cpu_fprintf(f, "MSR " TARGET_FMT_lx " HID0 " TARGET_FMT_lx "  HF "
11250                 TARGET_FMT_lx " idx %d\n", env->msr, env->spr[SPR_HID0],
11251                 env->hflags, env->mmu_idx);
11252 #if !defined(NO_TIMER_DUMP)
11253     cpu_fprintf(f, "TB %08" PRIu32 " %08" PRIu64
11254 #if !defined(CONFIG_USER_ONLY)
11255                 " DECR %08" PRIu32
11256 #endif
11257                 "\n",
11258                 cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
11259 #if !defined(CONFIG_USER_ONLY)
11260                 , cpu_ppc_load_decr(env)
11261 #endif
11262                 );
11263 #endif
11264     for (i = 0; i < 32; i++) {
11265         if ((i & (RGPL - 1)) == 0)
11266             cpu_fprintf(f, "GPR%02d", i);
11267         cpu_fprintf(f, " %016" PRIx64, ppc_dump_gpr(env, i));
11268         if ((i & (RGPL - 1)) == (RGPL - 1))
11269             cpu_fprintf(f, "\n");
11270     }
11271     cpu_fprintf(f, "CR ");
11272     for (i = 0; i < 8; i++)
11273         cpu_fprintf(f, "%01x", env->crf[i]);
11274     cpu_fprintf(f, "  [");
11275     for (i = 0; i < 8; i++) {
11276         char a = '-';
11277         if (env->crf[i] & 0x08)
11278             a = 'L';
11279         else if (env->crf[i] & 0x04)
11280             a = 'G';
11281         else if (env->crf[i] & 0x02)
11282             a = 'E';
11283         cpu_fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
11284     }
11285     cpu_fprintf(f, " ]             RES " TARGET_FMT_lx "\n",
11286                 env->reserve_addr);
11287     for (i = 0; i < 32; i++) {
11288         if ((i & (RFPL - 1)) == 0)
11289             cpu_fprintf(f, "FPR%02d", i);
11290         cpu_fprintf(f, " %016" PRIx64, *((uint64_t *)&env->fpr[i]));
11291         if ((i & (RFPL - 1)) == (RFPL - 1))
11292             cpu_fprintf(f, "\n");
11293     }
11294     cpu_fprintf(f, "FPSCR " TARGET_FMT_lx "\n", env->fpscr);
11295 #if !defined(CONFIG_USER_ONLY)
11296     cpu_fprintf(f, " SRR0 " TARGET_FMT_lx "  SRR1 " TARGET_FMT_lx
11297                    "    PVR " TARGET_FMT_lx " VRSAVE " TARGET_FMT_lx "\n",
11298                 env->spr[SPR_SRR0], env->spr[SPR_SRR1],
11299                 env->spr[SPR_PVR], env->spr[SPR_VRSAVE]);
11300
11301     cpu_fprintf(f, "SPRG0 " TARGET_FMT_lx " SPRG1 " TARGET_FMT_lx
11302                    "  SPRG2 " TARGET_FMT_lx "  SPRG3 " TARGET_FMT_lx "\n",
11303                 env->spr[SPR_SPRG0], env->spr[SPR_SPRG1],
11304                 env->spr[SPR_SPRG2], env->spr[SPR_SPRG3]);
11305
11306     cpu_fprintf(f, "SPRG4 " TARGET_FMT_lx " SPRG5 " TARGET_FMT_lx
11307                    "  SPRG6 " TARGET_FMT_lx "  SPRG7 " TARGET_FMT_lx "\n",
11308                 env->spr[SPR_SPRG4], env->spr[SPR_SPRG5],
11309                 env->spr[SPR_SPRG6], env->spr[SPR_SPRG7]);
11310
11311     if (env->excp_model == POWERPC_EXCP_BOOKE) {
11312         cpu_fprintf(f, "CSRR0 " TARGET_FMT_lx " CSRR1 " TARGET_FMT_lx
11313                        " MCSRR0 " TARGET_FMT_lx " MCSRR1 " TARGET_FMT_lx "\n",
11314                     env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1],
11315                     env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1]);
11316
11317         cpu_fprintf(f, "  TCR " TARGET_FMT_lx "   TSR " TARGET_FMT_lx
11318                        "    ESR " TARGET_FMT_lx "   DEAR " TARGET_FMT_lx "\n",
11319                     env->spr[SPR_BOOKE_TCR], env->spr[SPR_BOOKE_TSR],
11320                     env->spr[SPR_BOOKE_ESR], env->spr[SPR_BOOKE_DEAR]);
11321
11322         cpu_fprintf(f, "  PIR " TARGET_FMT_lx " DECAR " TARGET_FMT_lx
11323                        "   IVPR " TARGET_FMT_lx "   EPCR " TARGET_FMT_lx "\n",
11324                     env->spr[SPR_BOOKE_PIR], env->spr[SPR_BOOKE_DECAR],
11325                     env->spr[SPR_BOOKE_IVPR], env->spr[SPR_BOOKE_EPCR]);
11326
11327         cpu_fprintf(f, " MCSR " TARGET_FMT_lx " SPRG8 " TARGET_FMT_lx
11328                        "    EPR " TARGET_FMT_lx "\n",
11329                     env->spr[SPR_BOOKE_MCSR], env->spr[SPR_BOOKE_SPRG8],
11330                     env->spr[SPR_BOOKE_EPR]);
11331
11332         /* FSL-specific */
11333         cpu_fprintf(f, " MCAR " TARGET_FMT_lx "  PID1 " TARGET_FMT_lx
11334                        "   PID2 " TARGET_FMT_lx "    SVR " TARGET_FMT_lx "\n",
11335                     env->spr[SPR_Exxx_MCAR], env->spr[SPR_BOOKE_PID1],
11336                     env->spr[SPR_BOOKE_PID2], env->spr[SPR_E500_SVR]);
11337
11338         /*
11339          * IVORs are left out as they are large and do not change often --
11340          * they can be read with "p $ivor0", "p $ivor1", etc.
11341          */
11342     }
11343
11344 #if defined(TARGET_PPC64)
11345     if (env->flags & POWERPC_FLAG_CFAR) {
11346         cpu_fprintf(f, " CFAR " TARGET_FMT_lx"\n", env->cfar);
11347     }
11348 #endif
11349
11350     switch (env->mmu_model) {
11351     case POWERPC_MMU_32B:
11352     case POWERPC_MMU_601:
11353     case POWERPC_MMU_SOFT_6xx:
11354     case POWERPC_MMU_SOFT_74xx:
11355 #if defined(TARGET_PPC64)
11356     case POWERPC_MMU_64B:
11357     case POWERPC_MMU_2_03:
11358     case POWERPC_MMU_2_06:
11359     case POWERPC_MMU_2_06a:
11360     case POWERPC_MMU_2_07:
11361     case POWERPC_MMU_2_07a:
11362 #endif
11363         cpu_fprintf(f, " SDR1 " TARGET_FMT_lx "   DAR " TARGET_FMT_lx
11364                        "  DSISR " TARGET_FMT_lx "\n", env->spr[SPR_SDR1],
11365                     env->spr[SPR_DAR], env->spr[SPR_DSISR]);
11366         break;
11367     case POWERPC_MMU_BOOKE206:
11368         cpu_fprintf(f, " MAS0 " TARGET_FMT_lx "  MAS1 " TARGET_FMT_lx
11369                        "   MAS2 " TARGET_FMT_lx "   MAS3 " TARGET_FMT_lx "\n",
11370                     env->spr[SPR_BOOKE_MAS0], env->spr[SPR_BOOKE_MAS1],
11371                     env->spr[SPR_BOOKE_MAS2], env->spr[SPR_BOOKE_MAS3]);
11372
11373         cpu_fprintf(f, " MAS4 " TARGET_FMT_lx "  MAS6 " TARGET_FMT_lx
11374                        "   MAS7 " TARGET_FMT_lx "    PID " TARGET_FMT_lx "\n",
11375                     env->spr[SPR_BOOKE_MAS4], env->spr[SPR_BOOKE_MAS6],
11376                     env->spr[SPR_BOOKE_MAS7], env->spr[SPR_BOOKE_PID]);
11377
11378         cpu_fprintf(f, "MMUCFG " TARGET_FMT_lx " TLB0CFG " TARGET_FMT_lx
11379                        " TLB1CFG " TARGET_FMT_lx "\n",
11380                     env->spr[SPR_MMUCFG], env->spr[SPR_BOOKE_TLB0CFG],
11381                     env->spr[SPR_BOOKE_TLB1CFG]);
11382         break;
11383     default:
11384         break;
11385     }
11386 #endif
11387
11388 #undef RGPL
11389 #undef RFPL
11390 }
11391
11392 void ppc_cpu_dump_statistics(CPUState *cs, FILE*f,
11393                              fprintf_function cpu_fprintf, int flags)
11394 {
11395 #if defined(DO_PPC_STATISTICS)
11396     PowerPCCPU *cpu = POWERPC_CPU(cs);
11397     opc_handler_t **t1, **t2, **t3, *handler;
11398     int op1, op2, op3;
11399
11400     t1 = cpu->env.opcodes;
11401     for (op1 = 0; op1 < 64; op1++) {
11402         handler = t1[op1];
11403         if (is_indirect_opcode(handler)) {
11404             t2 = ind_table(handler);
11405             for (op2 = 0; op2 < 32; op2++) {
11406                 handler = t2[op2];
11407                 if (is_indirect_opcode(handler)) {
11408                     t3 = ind_table(handler);
11409                     for (op3 = 0; op3 < 32; op3++) {
11410                         handler = t3[op3];
11411                         if (handler->count == 0)
11412                             continue;
11413                         cpu_fprintf(f, "%02x %02x %02x (%02x %04d) %16s: "
11414                                     "%016" PRIx64 " %" PRId64 "\n",
11415                                     op1, op2, op3, op1, (op3 << 5) | op2,
11416                                     handler->oname,
11417                                     handler->count, handler->count);
11418                     }
11419                 } else {
11420                     if (handler->count == 0)
11421                         continue;
11422                     cpu_fprintf(f, "%02x %02x    (%02x %04d) %16s: "
11423                                 "%016" PRIx64 " %" PRId64 "\n",
11424                                 op1, op2, op1, op2, handler->oname,
11425                                 handler->count, handler->count);
11426                 }
11427             }
11428         } else {
11429             if (handler->count == 0)
11430                 continue;
11431             cpu_fprintf(f, "%02x       (%02x     ) %16s: %016" PRIx64
11432                         " %" PRId64 "\n",
11433                         op1, op1, handler->oname,
11434                         handler->count, handler->count);
11435         }
11436     }
11437 #endif
11438 }
11439
11440 /*****************************************************************************/
11441 void gen_intermediate_code(CPUPPCState *env, struct TranslationBlock *tb)
11442 {
11443     PowerPCCPU *cpu = ppc_env_get_cpu(env);
11444     CPUState *cs = CPU(cpu);
11445     DisasContext ctx, *ctxp = &ctx;
11446     opc_handler_t **table, *handler;
11447     target_ulong pc_start;
11448     int num_insns;
11449     int max_insns;
11450
11451     pc_start = tb->pc;
11452     ctx.nip = pc_start;
11453     ctx.tb = tb;
11454     ctx.exception = POWERPC_EXCP_NONE;
11455     ctx.spr_cb = env->spr_cb;
11456     ctx.pr = msr_pr;
11457     ctx.hv = !msr_pr && msr_hv;
11458     ctx.mem_idx = env->mmu_idx;
11459     ctx.insns_flags = env->insns_flags;
11460     ctx.insns_flags2 = env->insns_flags2;
11461     ctx.access_type = -1;
11462     ctx.le_mode = env->hflags & (1 << MSR_LE) ? 1 : 0;
11463     ctx.default_tcg_memop_mask = ctx.le_mode ? MO_LE : MO_BE;
11464 #if defined(TARGET_PPC64)
11465     ctx.sf_mode = msr_is_64bit(env, env->msr);
11466     ctx.has_cfar = !!(env->flags & POWERPC_FLAG_CFAR);
11467 #endif
11468     ctx.fpu_enabled = msr_fp;
11469     if ((env->flags & POWERPC_FLAG_SPE) && msr_spe)
11470         ctx.spe_enabled = msr_spe;
11471     else
11472         ctx.spe_enabled = 0;
11473     if ((env->flags & POWERPC_FLAG_VRE) && msr_vr)
11474         ctx.altivec_enabled = msr_vr;
11475     else
11476         ctx.altivec_enabled = 0;
11477     if ((env->flags & POWERPC_FLAG_VSX) && msr_vsx) {
11478         ctx.vsx_enabled = msr_vsx;
11479     } else {
11480         ctx.vsx_enabled = 0;
11481     }
11482 #if defined(TARGET_PPC64)
11483     if ((env->flags & POWERPC_FLAG_TM) && msr_tm) {
11484         ctx.tm_enabled = msr_tm;
11485     } else {
11486         ctx.tm_enabled = 0;
11487     }
11488 #endif
11489     if ((env->flags & POWERPC_FLAG_SE) && msr_se)
11490         ctx.singlestep_enabled = CPU_SINGLE_STEP;
11491     else
11492         ctx.singlestep_enabled = 0;
11493     if ((env->flags & POWERPC_FLAG_BE) && msr_be)
11494         ctx.singlestep_enabled |= CPU_BRANCH_STEP;
11495     if (unlikely(cs->singlestep_enabled)) {
11496         ctx.singlestep_enabled |= GDBSTUB_SINGLE_STEP;
11497     }
11498 #if defined (DO_SINGLE_STEP) && 0
11499     /* Single step trace mode */
11500     msr_se = 1;
11501 #endif
11502     num_insns = 0;
11503     max_insns = tb->cflags & CF_COUNT_MASK;
11504     if (max_insns == 0) {
11505         max_insns = CF_COUNT_MASK;
11506     }
11507     if (max_insns > TCG_MAX_INSNS) {
11508         max_insns = TCG_MAX_INSNS;
11509     }
11510
11511     gen_tb_start(tb);
11512     tcg_clear_temp_count();
11513     /* Set env in case of segfault during code fetch */
11514     while (ctx.exception == POWERPC_EXCP_NONE && !tcg_op_buf_full()) {
11515         tcg_gen_insn_start(ctx.nip);
11516         num_insns++;
11517
11518         if (unlikely(cpu_breakpoint_test(cs, ctx.nip, BP_ANY))) {
11519             gen_debug_exception(ctxp);
11520             /* The address covered by the breakpoint must be included in
11521                [tb->pc, tb->pc + tb->size) in order to for it to be
11522                properly cleared -- thus we increment the PC here so that
11523                the logic setting tb->size below does the right thing.  */
11524             ctx.nip += 4;
11525             break;
11526         }
11527
11528         LOG_DISAS("----------------\n");
11529         LOG_DISAS("nip=" TARGET_FMT_lx " super=%d ir=%d\n",
11530                   ctx.nip, ctx.mem_idx, (int)msr_ir);
11531         if (num_insns == max_insns && (tb->cflags & CF_LAST_IO))
11532             gen_io_start();
11533         if (unlikely(need_byteswap(&ctx))) {
11534             ctx.opcode = bswap32(cpu_ldl_code(env, ctx.nip));
11535         } else {
11536             ctx.opcode = cpu_ldl_code(env, ctx.nip);
11537         }
11538         LOG_DISAS("translate opcode %08x (%02x %02x %02x) (%s)\n",
11539                     ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
11540                     opc3(ctx.opcode), ctx.le_mode ? "little" : "big");
11541         ctx.nip += 4;
11542         table = env->opcodes;
11543         handler = table[opc1(ctx.opcode)];
11544         if (is_indirect_opcode(handler)) {
11545             table = ind_table(handler);
11546             handler = table[opc2(ctx.opcode)];
11547             if (is_indirect_opcode(handler)) {
11548                 table = ind_table(handler);
11549                 handler = table[opc3(ctx.opcode)];
11550             }
11551         }
11552         /* Is opcode *REALLY* valid ? */
11553         if (unlikely(handler->handler == &gen_invalid)) {
11554             qemu_log_mask(LOG_GUEST_ERROR, "invalid/unsupported opcode: "
11555                           "%02x - %02x - %02x (%08x) " TARGET_FMT_lx " %d\n",
11556                           opc1(ctx.opcode), opc2(ctx.opcode),
11557                           opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, (int)msr_ir);
11558         } else {
11559             uint32_t inval;
11560
11561             if (unlikely(handler->type & (PPC_SPE | PPC_SPE_SINGLE | PPC_SPE_DOUBLE) && Rc(ctx.opcode))) {
11562                 inval = handler->inval2;
11563             } else {
11564                 inval = handler->inval1;
11565             }
11566
11567             if (unlikely((ctx.opcode & inval) != 0)) {
11568                 qemu_log_mask(LOG_GUEST_ERROR, "invalid bits: %08x for opcode: "
11569                               "%02x - %02x - %02x (%08x) " TARGET_FMT_lx "\n",
11570                               ctx.opcode & inval, opc1(ctx.opcode),
11571                               opc2(ctx.opcode), opc3(ctx.opcode),
11572                               ctx.opcode, ctx.nip - 4);
11573                 gen_inval_exception(ctxp, POWERPC_EXCP_INVAL_INVAL);
11574                 break;
11575             }
11576         }
11577         (*(handler->handler))(&ctx);
11578 #if defined(DO_PPC_STATISTICS)
11579         handler->count++;
11580 #endif
11581         /* Check trace mode exceptions */
11582         if (unlikely(ctx.singlestep_enabled & CPU_SINGLE_STEP &&
11583                      (ctx.nip <= 0x100 || ctx.nip > 0xF00) &&
11584                      ctx.exception != POWERPC_SYSCALL &&
11585                      ctx.exception != POWERPC_EXCP_TRAP &&
11586                      ctx.exception != POWERPC_EXCP_BRANCH)) {
11587             gen_exception(ctxp, POWERPC_EXCP_TRACE);
11588         } else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
11589                             (cs->singlestep_enabled) ||
11590                             singlestep ||
11591                             num_insns >= max_insns)) {
11592             /* if we reach a page boundary or are single stepping, stop
11593              * generation
11594              */
11595             break;
11596         }
11597         if (tcg_check_temp_count()) {
11598             fprintf(stderr, "Opcode %02x %02x %02x (%08x) leaked temporaries\n",
11599                     opc1(ctx.opcode), opc2(ctx.opcode), opc3(ctx.opcode),
11600                     ctx.opcode);
11601             exit(1);
11602         }
11603     }
11604     if (tb->cflags & CF_LAST_IO)
11605         gen_io_end();
11606     if (ctx.exception == POWERPC_EXCP_NONE) {
11607         gen_goto_tb(&ctx, 0, ctx.nip);
11608     } else if (ctx.exception != POWERPC_EXCP_BRANCH) {
11609         if (unlikely(cs->singlestep_enabled)) {
11610             gen_debug_exception(ctxp);
11611         }
11612         /* Generate the return instruction */
11613         tcg_gen_exit_tb(0);
11614     }
11615     gen_tb_end(tb, num_insns);
11616
11617     tb->size = ctx.nip - pc_start;
11618     tb->icount = num_insns;
11619
11620 #if defined(DEBUG_DISAS)
11621     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
11622         int flags;
11623         flags = env->bfd_mach;
11624         flags |= ctx.le_mode << 16;
11625         qemu_log("IN: %s\n", lookup_symbol(pc_start));
11626         log_target_disas(cs, pc_start, ctx.nip - pc_start, flags);
11627         qemu_log("\n");
11628     }
11629 #endif
11630 }
11631
11632 void restore_state_to_opc(CPUPPCState *env, TranslationBlock *tb,
11633                           target_ulong *data)
11634 {
11635     env->nip = data[0];
11636 }