]> Git Repo - qemu.git/blob - target-ppc/translate.c
269fdad6b2797874dfbccec9b3bcf20709cbea02
[qemu.git] / target-ppc / translate.c
1 /*
2  *  PowerPC emulation for qemu: main translation routines.
3  *
4  *  Copyright (c) 2003-2007 Jocelyn Mayer
5  *  Copyright (C) 2011 Freescale Semiconductor, Inc.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include "cpu.h"
22 #include "disas/disas.h"
23 #include "tcg-op.h"
24 #include "qemu/host-utils.h"
25
26 #include "helper.h"
27 #define GEN_HELPER 1
28 #include "helper.h"
29
30 #define CPU_SINGLE_STEP 0x1
31 #define CPU_BRANCH_STEP 0x2
32 #define GDBSTUB_SINGLE_STEP 0x4
33
34 /* Include definitions for instructions classes and implementations flags */
35 //#define PPC_DEBUG_DISAS
36 //#define DO_PPC_STATISTICS
37
38 #ifdef PPC_DEBUG_DISAS
39 #  define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
40 #else
41 #  define LOG_DISAS(...) do { } while (0)
42 #endif
43 /*****************************************************************************/
44 /* Code translation helpers                                                  */
45
46 /* global register indexes */
47 static TCGv_ptr cpu_env;
48 static char cpu_reg_names[10*3 + 22*4 /* GPR */
49 #if !defined(TARGET_PPC64)
50     + 10*4 + 22*5 /* SPE GPRh */
51 #endif
52     + 10*4 + 22*5 /* FPR */
53     + 2*(10*6 + 22*7) /* AVRh, AVRl */
54     + 10*5 + 22*6 /* VSR */
55     + 8*5 /* CRF */];
56 static TCGv cpu_gpr[32];
57 #if !defined(TARGET_PPC64)
58 static TCGv cpu_gprh[32];
59 #endif
60 static TCGv_i64 cpu_fpr[32];
61 static TCGv_i64 cpu_avrh[32], cpu_avrl[32];
62 static TCGv_i64 cpu_vsr[32];
63 static TCGv_i32 cpu_crf[8];
64 static TCGv cpu_nip;
65 static TCGv cpu_msr;
66 static TCGv cpu_ctr;
67 static TCGv cpu_lr;
68 #if defined(TARGET_PPC64)
69 static TCGv cpu_cfar;
70 #endif
71 static TCGv cpu_xer, cpu_so, cpu_ov, cpu_ca;
72 static TCGv cpu_reserve;
73 static TCGv cpu_fpscr;
74 static TCGv_i32 cpu_access_type;
75
76 #include "exec/gen-icount.h"
77
78 void ppc_translate_init(void)
79 {
80     int i;
81     char* p;
82     size_t cpu_reg_names_size;
83     static int done_init = 0;
84
85     if (done_init)
86         return;
87
88     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
89
90     p = cpu_reg_names;
91     cpu_reg_names_size = sizeof(cpu_reg_names);
92
93     for (i = 0; i < 8; i++) {
94         snprintf(p, cpu_reg_names_size, "crf%d", i);
95         cpu_crf[i] = tcg_global_mem_new_i32(TCG_AREG0,
96                                             offsetof(CPUPPCState, crf[i]), p);
97         p += 5;
98         cpu_reg_names_size -= 5;
99     }
100
101     for (i = 0; i < 32; i++) {
102         snprintf(p, cpu_reg_names_size, "r%d", i);
103         cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
104                                         offsetof(CPUPPCState, gpr[i]), p);
105         p += (i < 10) ? 3 : 4;
106         cpu_reg_names_size -= (i < 10) ? 3 : 4;
107 #if !defined(TARGET_PPC64)
108         snprintf(p, cpu_reg_names_size, "r%dH", i);
109         cpu_gprh[i] = tcg_global_mem_new_i32(TCG_AREG0,
110                                              offsetof(CPUPPCState, gprh[i]), p);
111         p += (i < 10) ? 4 : 5;
112         cpu_reg_names_size -= (i < 10) ? 4 : 5;
113 #endif
114
115         snprintf(p, cpu_reg_names_size, "fp%d", i);
116         cpu_fpr[i] = tcg_global_mem_new_i64(TCG_AREG0,
117                                             offsetof(CPUPPCState, fpr[i]), p);
118         p += (i < 10) ? 4 : 5;
119         cpu_reg_names_size -= (i < 10) ? 4 : 5;
120
121         snprintf(p, cpu_reg_names_size, "avr%dH", i);
122 #ifdef HOST_WORDS_BIGENDIAN
123         cpu_avrh[i] = tcg_global_mem_new_i64(TCG_AREG0,
124                                              offsetof(CPUPPCState, avr[i].u64[0]), p);
125 #else
126         cpu_avrh[i] = tcg_global_mem_new_i64(TCG_AREG0,
127                                              offsetof(CPUPPCState, avr[i].u64[1]), p);
128 #endif
129         p += (i < 10) ? 6 : 7;
130         cpu_reg_names_size -= (i < 10) ? 6 : 7;
131
132         snprintf(p, cpu_reg_names_size, "avr%dL", i);
133 #ifdef HOST_WORDS_BIGENDIAN
134         cpu_avrl[i] = tcg_global_mem_new_i64(TCG_AREG0,
135                                              offsetof(CPUPPCState, avr[i].u64[1]), p);
136 #else
137         cpu_avrl[i] = tcg_global_mem_new_i64(TCG_AREG0,
138                                              offsetof(CPUPPCState, avr[i].u64[0]), p);
139 #endif
140         p += (i < 10) ? 6 : 7;
141         cpu_reg_names_size -= (i < 10) ? 6 : 7;
142         snprintf(p, cpu_reg_names_size, "vsr%d", i);
143         cpu_vsr[i] = tcg_global_mem_new_i64(TCG_AREG0,
144                                              offsetof(CPUPPCState, vsr[i]), p);
145         p += (i < 10) ? 5 : 6;
146         cpu_reg_names_size -= (i < 10) ? 5 : 6;
147     }
148
149     cpu_nip = tcg_global_mem_new(TCG_AREG0,
150                                  offsetof(CPUPPCState, nip), "nip");
151
152     cpu_msr = tcg_global_mem_new(TCG_AREG0,
153                                  offsetof(CPUPPCState, msr), "msr");
154
155     cpu_ctr = tcg_global_mem_new(TCG_AREG0,
156                                  offsetof(CPUPPCState, ctr), "ctr");
157
158     cpu_lr = tcg_global_mem_new(TCG_AREG0,
159                                 offsetof(CPUPPCState, lr), "lr");
160
161 #if defined(TARGET_PPC64)
162     cpu_cfar = tcg_global_mem_new(TCG_AREG0,
163                                   offsetof(CPUPPCState, cfar), "cfar");
164 #endif
165
166     cpu_xer = tcg_global_mem_new(TCG_AREG0,
167                                  offsetof(CPUPPCState, xer), "xer");
168     cpu_so = tcg_global_mem_new(TCG_AREG0,
169                                 offsetof(CPUPPCState, so), "SO");
170     cpu_ov = tcg_global_mem_new(TCG_AREG0,
171                                 offsetof(CPUPPCState, ov), "OV");
172     cpu_ca = tcg_global_mem_new(TCG_AREG0,
173                                 offsetof(CPUPPCState, ca), "CA");
174
175     cpu_reserve = tcg_global_mem_new(TCG_AREG0,
176                                      offsetof(CPUPPCState, reserve_addr),
177                                      "reserve_addr");
178
179     cpu_fpscr = tcg_global_mem_new(TCG_AREG0,
180                                    offsetof(CPUPPCState, fpscr), "fpscr");
181
182     cpu_access_type = tcg_global_mem_new_i32(TCG_AREG0,
183                                              offsetof(CPUPPCState, access_type), "access_type");
184
185     done_init = 1;
186 }
187
188 /* internal defines */
189 typedef struct DisasContext {
190     struct TranslationBlock *tb;
191     target_ulong nip;
192     uint32_t opcode;
193     uint32_t exception;
194     /* Routine used to access memory */
195     int mem_idx;
196     int access_type;
197     /* Translation flags */
198     int le_mode;
199 #if defined(TARGET_PPC64)
200     int sf_mode;
201     int has_cfar;
202 #endif
203     int fpu_enabled;
204     int altivec_enabled;
205     int vsx_enabled;
206     int spe_enabled;
207     ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
208     int singlestep_enabled;
209     uint64_t insns_flags;
210     uint64_t insns_flags2;
211 } DisasContext;
212
213 /* True when active word size < size of target_long.  */
214 #ifdef TARGET_PPC64
215 # define NARROW_MODE(C)  (!(C)->sf_mode)
216 #else
217 # define NARROW_MODE(C)  0
218 #endif
219
220 struct opc_handler_t {
221     /* invalid bits for instruction 1 (Rc(opcode) == 0) */
222     uint32_t inval1;
223     /* invalid bits for instruction 2 (Rc(opcode) == 1) */
224     uint32_t inval2;
225     /* instruction type */
226     uint64_t type;
227     /* extended instruction type */
228     uint64_t type2;
229     /* handler */
230     void (*handler)(DisasContext *ctx);
231 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
232     const char *oname;
233 #endif
234 #if defined(DO_PPC_STATISTICS)
235     uint64_t count;
236 #endif
237 };
238
239 static inline void gen_reset_fpstatus(void)
240 {
241     gen_helper_reset_fpstatus(cpu_env);
242 }
243
244 static inline void gen_compute_fprf(TCGv_i64 arg, int set_fprf, int set_rc)
245 {
246     TCGv_i32 t0 = tcg_temp_new_i32();
247
248     if (set_fprf != 0) {
249         /* This case might be optimized later */
250         tcg_gen_movi_i32(t0, 1);
251         gen_helper_compute_fprf(t0, cpu_env, arg, t0);
252         if (unlikely(set_rc)) {
253             tcg_gen_mov_i32(cpu_crf[1], t0);
254         }
255         gen_helper_float_check_status(cpu_env);
256     } else if (unlikely(set_rc)) {
257         /* We always need to compute fpcc */
258         tcg_gen_movi_i32(t0, 0);
259         gen_helper_compute_fprf(t0, cpu_env, arg, t0);
260         tcg_gen_mov_i32(cpu_crf[1], t0);
261     }
262
263     tcg_temp_free_i32(t0);
264 }
265
266 static inline void gen_set_access_type(DisasContext *ctx, int access_type)
267 {
268     if (ctx->access_type != access_type) {
269         tcg_gen_movi_i32(cpu_access_type, access_type);
270         ctx->access_type = access_type;
271     }
272 }
273
274 static inline void gen_update_nip(DisasContext *ctx, target_ulong nip)
275 {
276     if (NARROW_MODE(ctx)) {
277         nip = (uint32_t)nip;
278     }
279     tcg_gen_movi_tl(cpu_nip, nip);
280 }
281
282 static inline void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t error)
283 {
284     TCGv_i32 t0, t1;
285     if (ctx->exception == POWERPC_EXCP_NONE) {
286         gen_update_nip(ctx, ctx->nip);
287     }
288     t0 = tcg_const_i32(excp);
289     t1 = tcg_const_i32(error);
290     gen_helper_raise_exception_err(cpu_env, t0, t1);
291     tcg_temp_free_i32(t0);
292     tcg_temp_free_i32(t1);
293     ctx->exception = (excp);
294 }
295
296 static inline void gen_exception(DisasContext *ctx, uint32_t excp)
297 {
298     TCGv_i32 t0;
299     if (ctx->exception == POWERPC_EXCP_NONE) {
300         gen_update_nip(ctx, ctx->nip);
301     }
302     t0 = tcg_const_i32(excp);
303     gen_helper_raise_exception(cpu_env, t0);
304     tcg_temp_free_i32(t0);
305     ctx->exception = (excp);
306 }
307
308 static inline void gen_debug_exception(DisasContext *ctx)
309 {
310     TCGv_i32 t0;
311
312     if ((ctx->exception != POWERPC_EXCP_BRANCH) &&
313         (ctx->exception != POWERPC_EXCP_SYNC)) {
314         gen_update_nip(ctx, ctx->nip);
315     }
316     t0 = tcg_const_i32(EXCP_DEBUG);
317     gen_helper_raise_exception(cpu_env, t0);
318     tcg_temp_free_i32(t0);
319 }
320
321 static inline void gen_inval_exception(DisasContext *ctx, uint32_t error)
322 {
323     gen_exception_err(ctx, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_INVAL | error);
324 }
325
326 /* Stop translation */
327 static inline void gen_stop_exception(DisasContext *ctx)
328 {
329     gen_update_nip(ctx, ctx->nip);
330     ctx->exception = POWERPC_EXCP_STOP;
331 }
332
333 /* No need to update nip here, as execution flow will change */
334 static inline void gen_sync_exception(DisasContext *ctx)
335 {
336     ctx->exception = POWERPC_EXCP_SYNC;
337 }
338
339 #define GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                      \
340 GEN_OPCODE(name, opc1, opc2, opc3, inval, type, PPC_NONE)
341
342 #define GEN_HANDLER_E(name, opc1, opc2, opc3, inval, type, type2)             \
343 GEN_OPCODE(name, opc1, opc2, opc3, inval, type, type2)
344
345 #define GEN_HANDLER2(name, onam, opc1, opc2, opc3, inval, type)               \
346 GEN_OPCODE2(name, onam, opc1, opc2, opc3, inval, type, PPC_NONE)
347
348 #define GEN_HANDLER2_E(name, onam, opc1, opc2, opc3, inval, type, type2)      \
349 GEN_OPCODE2(name, onam, opc1, opc2, opc3, inval, type, type2)
350
351 typedef struct opcode_t {
352     unsigned char opc1, opc2, opc3;
353 #if HOST_LONG_BITS == 64 /* Explicitly align to 64 bits */
354     unsigned char pad[5];
355 #else
356     unsigned char pad[1];
357 #endif
358     opc_handler_t handler;
359     const char *oname;
360 } opcode_t;
361
362 /*****************************************************************************/
363 /***                           Instruction decoding                        ***/
364 #define EXTRACT_HELPER(name, shift, nb)                                       \
365 static inline uint32_t name(uint32_t opcode)                                  \
366 {                                                                             \
367     return (opcode >> (shift)) & ((1 << (nb)) - 1);                           \
368 }
369
370 #define EXTRACT_SHELPER(name, shift, nb)                                      \
371 static inline int32_t name(uint32_t opcode)                                   \
372 {                                                                             \
373     return (int16_t)((opcode >> (shift)) & ((1 << (nb)) - 1));                \
374 }
375
376 #define EXTRACT_HELPER_SPLIT(name, shift1, nb1, shift2, nb2)                  \
377 static inline uint32_t name(uint32_t opcode)                                  \
378 {                                                                             \
379     return (((opcode >> (shift1)) & ((1 << (nb1)) - 1)) << nb2) |             \
380             ((opcode >> (shift2)) & ((1 << (nb2)) - 1));                      \
381 }
382 /* Opcode part 1 */
383 EXTRACT_HELPER(opc1, 26, 6);
384 /* Opcode part 2 */
385 EXTRACT_HELPER(opc2, 1, 5);
386 /* Opcode part 3 */
387 EXTRACT_HELPER(opc3, 6, 5);
388 /* Update Cr0 flags */
389 EXTRACT_HELPER(Rc, 0, 1);
390 /* Destination */
391 EXTRACT_HELPER(rD, 21, 5);
392 /* Source */
393 EXTRACT_HELPER(rS, 21, 5);
394 /* First operand */
395 EXTRACT_HELPER(rA, 16, 5);
396 /* Second operand */
397 EXTRACT_HELPER(rB, 11, 5);
398 /* Third operand */
399 EXTRACT_HELPER(rC, 6, 5);
400 /***                               Get CRn                                 ***/
401 EXTRACT_HELPER(crfD, 23, 3);
402 EXTRACT_HELPER(crfS, 18, 3);
403 EXTRACT_HELPER(crbD, 21, 5);
404 EXTRACT_HELPER(crbA, 16, 5);
405 EXTRACT_HELPER(crbB, 11, 5);
406 /* SPR / TBL */
407 EXTRACT_HELPER(_SPR, 11, 10);
408 static inline uint32_t SPR(uint32_t opcode)
409 {
410     uint32_t sprn = _SPR(opcode);
411
412     return ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
413 }
414 /***                              Get constants                            ***/
415 EXTRACT_HELPER(IMM, 12, 8);
416 /* 16 bits signed immediate value */
417 EXTRACT_SHELPER(SIMM, 0, 16);
418 /* 16 bits unsigned immediate value */
419 EXTRACT_HELPER(UIMM, 0, 16);
420 /* 5 bits signed immediate value */
421 EXTRACT_HELPER(SIMM5, 16, 5);
422 /* 5 bits signed immediate value */
423 EXTRACT_HELPER(UIMM5, 16, 5);
424 /* Bit count */
425 EXTRACT_HELPER(NB, 11, 5);
426 /* Shift count */
427 EXTRACT_HELPER(SH, 11, 5);
428 /* Vector shift count */
429 EXTRACT_HELPER(VSH, 6, 4);
430 /* Mask start */
431 EXTRACT_HELPER(MB, 6, 5);
432 /* Mask end */
433 EXTRACT_HELPER(ME, 1, 5);
434 /* Trap operand */
435 EXTRACT_HELPER(TO, 21, 5);
436
437 EXTRACT_HELPER(CRM, 12, 8);
438 EXTRACT_HELPER(SR, 16, 4);
439
440 /* mtfsf/mtfsfi */
441 EXTRACT_HELPER(FPBF, 23, 3);
442 EXTRACT_HELPER(FPIMM, 12, 4);
443 EXTRACT_HELPER(FPL, 25, 1);
444 EXTRACT_HELPER(FPFLM, 17, 8);
445 EXTRACT_HELPER(FPW, 16, 1);
446
447 /***                            Jump target decoding                       ***/
448 /* Displacement */
449 EXTRACT_SHELPER(d, 0, 16);
450 /* Immediate address */
451 static inline target_ulong LI(uint32_t opcode)
452 {
453     return (opcode >> 0) & 0x03FFFFFC;
454 }
455
456 static inline uint32_t BD(uint32_t opcode)
457 {
458     return (opcode >> 0) & 0xFFFC;
459 }
460
461 EXTRACT_HELPER(BO, 21, 5);
462 EXTRACT_HELPER(BI, 16, 5);
463 /* Absolute/relative address */
464 EXTRACT_HELPER(AA, 1, 1);
465 /* Link */
466 EXTRACT_HELPER(LK, 0, 1);
467
468 /* Create a mask between <start> and <end> bits */
469 static inline target_ulong MASK(uint32_t start, uint32_t end)
470 {
471     target_ulong ret;
472
473 #if defined(TARGET_PPC64)
474     if (likely(start == 0)) {
475         ret = UINT64_MAX << (63 - end);
476     } else if (likely(end == 63)) {
477         ret = UINT64_MAX >> start;
478     }
479 #else
480     if (likely(start == 0)) {
481         ret = UINT32_MAX << (31  - end);
482     } else if (likely(end == 31)) {
483         ret = UINT32_MAX >> start;
484     }
485 #endif
486     else {
487         ret = (((target_ulong)(-1ULL)) >> (start)) ^
488             (((target_ulong)(-1ULL) >> (end)) >> 1);
489         if (unlikely(start > end))
490             return ~ret;
491     }
492
493     return ret;
494 }
495
496 EXTRACT_HELPER_SPLIT(xT, 0, 1, 21, 5);
497 EXTRACT_HELPER_SPLIT(xS, 0, 1, 21, 5);
498 EXTRACT_HELPER_SPLIT(xA, 2, 1, 16, 5);
499 EXTRACT_HELPER_SPLIT(xB, 1, 1, 11, 5);
500 EXTRACT_HELPER(DM, 8, 2);
501 /*****************************************************************************/
502 /* PowerPC instructions table                                                */
503
504 #if defined(DO_PPC_STATISTICS)
505 #define GEN_OPCODE(name, op1, op2, op3, invl, _typ, _typ2)                    \
506 {                                                                             \
507     .opc1 = op1,                                                              \
508     .opc2 = op2,                                                              \
509     .opc3 = op3,                                                              \
510     .pad  = { 0, },                                                           \
511     .handler = {                                                              \
512         .inval1  = invl,                                                      \
513         .type = _typ,                                                         \
514         .type2 = _typ2,                                                       \
515         .handler = &gen_##name,                                               \
516         .oname = stringify(name),                                             \
517     },                                                                        \
518     .oname = stringify(name),                                                 \
519 }
520 #define GEN_OPCODE_DUAL(name, op1, op2, op3, invl1, invl2, _typ, _typ2)       \
521 {                                                                             \
522     .opc1 = op1,                                                              \
523     .opc2 = op2,                                                              \
524     .opc3 = op3,                                                              \
525     .pad  = { 0, },                                                           \
526     .handler = {                                                              \
527         .inval1  = invl1,                                                     \
528         .inval2  = invl2,                                                     \
529         .type = _typ,                                                         \
530         .type2 = _typ2,                                                       \
531         .handler = &gen_##name,                                               \
532         .oname = stringify(name),                                             \
533     },                                                                        \
534     .oname = stringify(name),                                                 \
535 }
536 #define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ, _typ2)             \
537 {                                                                             \
538     .opc1 = op1,                                                              \
539     .opc2 = op2,                                                              \
540     .opc3 = op3,                                                              \
541     .pad  = { 0, },                                                           \
542     .handler = {                                                              \
543         .inval1  = invl,                                                      \
544         .type = _typ,                                                         \
545         .type2 = _typ2,                                                       \
546         .handler = &gen_##name,                                               \
547         .oname = onam,                                                        \
548     },                                                                        \
549     .oname = onam,                                                            \
550 }
551 #else
552 #define GEN_OPCODE(name, op1, op2, op3, invl, _typ, _typ2)                    \
553 {                                                                             \
554     .opc1 = op1,                                                              \
555     .opc2 = op2,                                                              \
556     .opc3 = op3,                                                              \
557     .pad  = { 0, },                                                           \
558     .handler = {                                                              \
559         .inval1  = invl,                                                      \
560         .type = _typ,                                                         \
561         .type2 = _typ2,                                                       \
562         .handler = &gen_##name,                                               \
563     },                                                                        \
564     .oname = stringify(name),                                                 \
565 }
566 #define GEN_OPCODE_DUAL(name, op1, op2, op3, invl1, invl2, _typ, _typ2)       \
567 {                                                                             \
568     .opc1 = op1,                                                              \
569     .opc2 = op2,                                                              \
570     .opc3 = op3,                                                              \
571     .pad  = { 0, },                                                           \
572     .handler = {                                                              \
573         .inval1  = invl1,                                                     \
574         .inval2  = invl2,                                                     \
575         .type = _typ,                                                         \
576         .type2 = _typ2,                                                       \
577         .handler = &gen_##name,                                               \
578     },                                                                        \
579     .oname = stringify(name),                                                 \
580 }
581 #define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ, _typ2)             \
582 {                                                                             \
583     .opc1 = op1,                                                              \
584     .opc2 = op2,                                                              \
585     .opc3 = op3,                                                              \
586     .pad  = { 0, },                                                           \
587     .handler = {                                                              \
588         .inval1  = invl,                                                      \
589         .type = _typ,                                                         \
590         .type2 = _typ2,                                                       \
591         .handler = &gen_##name,                                               \
592     },                                                                        \
593     .oname = onam,                                                            \
594 }
595 #endif
596
597 /* SPR load/store helpers */
598 static inline void gen_load_spr(TCGv t, int reg)
599 {
600     tcg_gen_ld_tl(t, cpu_env, offsetof(CPUPPCState, spr[reg]));
601 }
602
603 static inline void gen_store_spr(int reg, TCGv t)
604 {
605     tcg_gen_st_tl(t, cpu_env, offsetof(CPUPPCState, spr[reg]));
606 }
607
608 /* Invalid instruction */
609 static void gen_invalid(DisasContext *ctx)
610 {
611     gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
612 }
613
614 static opc_handler_t invalid_handler = {
615     .inval1  = 0xFFFFFFFF,
616     .inval2  = 0xFFFFFFFF,
617     .type    = PPC_NONE,
618     .type2   = PPC_NONE,
619     .handler = gen_invalid,
620 };
621
622 /***                           Integer comparison                          ***/
623
624 static inline void gen_op_cmp(TCGv arg0, TCGv arg1, int s, int crf)
625 {
626     TCGv t0 = tcg_temp_new();
627     TCGv_i32 t1 = tcg_temp_new_i32();
628
629     tcg_gen_trunc_tl_i32(cpu_crf[crf], cpu_so);
630
631     tcg_gen_setcond_tl((s ? TCG_COND_LT: TCG_COND_LTU), t0, arg0, arg1);
632     tcg_gen_trunc_tl_i32(t1, t0);
633     tcg_gen_shli_i32(t1, t1, CRF_LT);
634     tcg_gen_or_i32(cpu_crf[crf], cpu_crf[crf], t1);
635
636     tcg_gen_setcond_tl((s ? TCG_COND_GT: TCG_COND_GTU), t0, arg0, arg1);
637     tcg_gen_trunc_tl_i32(t1, t0);
638     tcg_gen_shli_i32(t1, t1, CRF_GT);
639     tcg_gen_or_i32(cpu_crf[crf], cpu_crf[crf], t1);
640
641     tcg_gen_setcond_tl(TCG_COND_EQ, t0, arg0, arg1);
642     tcg_gen_trunc_tl_i32(t1, t0);
643     tcg_gen_shli_i32(t1, t1, CRF_EQ);
644     tcg_gen_or_i32(cpu_crf[crf], cpu_crf[crf], t1);
645
646     tcg_temp_free(t0);
647     tcg_temp_free_i32(t1);
648 }
649
650 static inline void gen_op_cmpi(TCGv arg0, target_ulong arg1, int s, int crf)
651 {
652     TCGv t0 = tcg_const_tl(arg1);
653     gen_op_cmp(arg0, t0, s, crf);
654     tcg_temp_free(t0);
655 }
656
657 static inline void gen_op_cmp32(TCGv arg0, TCGv arg1, int s, int crf)
658 {
659     TCGv t0, t1;
660     t0 = tcg_temp_new();
661     t1 = tcg_temp_new();
662     if (s) {
663         tcg_gen_ext32s_tl(t0, arg0);
664         tcg_gen_ext32s_tl(t1, arg1);
665     } else {
666         tcg_gen_ext32u_tl(t0, arg0);
667         tcg_gen_ext32u_tl(t1, arg1);
668     }
669     gen_op_cmp(t0, t1, s, crf);
670     tcg_temp_free(t1);
671     tcg_temp_free(t0);
672 }
673
674 static inline void gen_op_cmpi32(TCGv arg0, target_ulong arg1, int s, int crf)
675 {
676     TCGv t0 = tcg_const_tl(arg1);
677     gen_op_cmp32(arg0, t0, s, crf);
678     tcg_temp_free(t0);
679 }
680
681 static inline void gen_set_Rc0(DisasContext *ctx, TCGv reg)
682 {
683     if (NARROW_MODE(ctx)) {
684         gen_op_cmpi32(reg, 0, 1, 0);
685     } else {
686         gen_op_cmpi(reg, 0, 1, 0);
687     }
688 }
689
690 /* cmp */
691 static void gen_cmp(DisasContext *ctx)
692 {
693     if ((ctx->opcode & 0x00200000) && (ctx->insns_flags & PPC_64B)) {
694         gen_op_cmp(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
695                    1, crfD(ctx->opcode));
696     } else {
697         gen_op_cmp32(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
698                      1, crfD(ctx->opcode));
699     }
700 }
701
702 /* cmpi */
703 static void gen_cmpi(DisasContext *ctx)
704 {
705     if ((ctx->opcode & 0x00200000) && (ctx->insns_flags & PPC_64B)) {
706         gen_op_cmpi(cpu_gpr[rA(ctx->opcode)], SIMM(ctx->opcode),
707                     1, crfD(ctx->opcode));
708     } else {
709         gen_op_cmpi32(cpu_gpr[rA(ctx->opcode)], SIMM(ctx->opcode),
710                       1, crfD(ctx->opcode));
711     }
712 }
713
714 /* cmpl */
715 static void gen_cmpl(DisasContext *ctx)
716 {
717     if ((ctx->opcode & 0x00200000) && (ctx->insns_flags & PPC_64B)) {
718         gen_op_cmp(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
719                    0, crfD(ctx->opcode));
720     } else {
721         gen_op_cmp32(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
722                      0, crfD(ctx->opcode));
723     }
724 }
725
726 /* cmpli */
727 static void gen_cmpli(DisasContext *ctx)
728 {
729     if ((ctx->opcode & 0x00200000) && (ctx->insns_flags & PPC_64B)) {
730         gen_op_cmpi(cpu_gpr[rA(ctx->opcode)], UIMM(ctx->opcode),
731                     0, crfD(ctx->opcode));
732     } else {
733         gen_op_cmpi32(cpu_gpr[rA(ctx->opcode)], UIMM(ctx->opcode),
734                       0, crfD(ctx->opcode));
735     }
736 }
737
738 /* isel (PowerPC 2.03 specification) */
739 static void gen_isel(DisasContext *ctx)
740 {
741     int l1, l2;
742     uint32_t bi = rC(ctx->opcode);
743     uint32_t mask;
744     TCGv_i32 t0;
745
746     l1 = gen_new_label();
747     l2 = gen_new_label();
748
749     mask = 1 << (3 - (bi & 0x03));
750     t0 = tcg_temp_new_i32();
751     tcg_gen_andi_i32(t0, cpu_crf[bi >> 2], mask);
752     tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
753     if (rA(ctx->opcode) == 0)
754         tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
755     else
756         tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
757     tcg_gen_br(l2);
758     gen_set_label(l1);
759     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
760     gen_set_label(l2);
761     tcg_temp_free_i32(t0);
762 }
763
764 /* cmpb: PowerPC 2.05 specification */
765 static void gen_cmpb(DisasContext *ctx)
766 {
767     gen_helper_cmpb(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)],
768                     cpu_gpr[rB(ctx->opcode)]);
769 }
770
771 /***                           Integer arithmetic                          ***/
772
773 static inline void gen_op_arith_compute_ov(DisasContext *ctx, TCGv arg0,
774                                            TCGv arg1, TCGv arg2, int sub)
775 {
776     TCGv t0 = tcg_temp_new();
777
778     tcg_gen_xor_tl(cpu_ov, arg0, arg2);
779     tcg_gen_xor_tl(t0, arg1, arg2);
780     if (sub) {
781         tcg_gen_and_tl(cpu_ov, cpu_ov, t0);
782     } else {
783         tcg_gen_andc_tl(cpu_ov, cpu_ov, t0);
784     }
785     tcg_temp_free(t0);
786     if (NARROW_MODE(ctx)) {
787         tcg_gen_ext32s_tl(cpu_ov, cpu_ov);
788     }
789     tcg_gen_shri_tl(cpu_ov, cpu_ov, TARGET_LONG_BITS - 1);
790     tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov);
791 }
792
793 /* Common add function */
794 static inline void gen_op_arith_add(DisasContext *ctx, TCGv ret, TCGv arg1,
795                                     TCGv arg2, bool add_ca, bool compute_ca,
796                                     bool compute_ov, bool compute_rc0)
797 {
798     TCGv t0 = ret;
799
800     if (compute_ca || compute_ov) {
801         t0 = tcg_temp_new();
802     }
803
804     if (compute_ca) {
805         if (NARROW_MODE(ctx)) {
806             /* Caution: a non-obvious corner case of the spec is that we
807                must produce the *entire* 64-bit addition, but produce the
808                carry into bit 32.  */
809             TCGv t1 = tcg_temp_new();
810             tcg_gen_xor_tl(t1, arg1, arg2);        /* add without carry */
811             tcg_gen_add_tl(t0, arg1, arg2);
812             if (add_ca) {
813                 tcg_gen_add_tl(t0, t0, cpu_ca);
814             }
815             tcg_gen_xor_tl(cpu_ca, t0, t1);        /* bits changed w/ carry */
816             tcg_temp_free(t1);
817             tcg_gen_shri_tl(cpu_ca, cpu_ca, 32);   /* extract bit 32 */
818             tcg_gen_andi_tl(cpu_ca, cpu_ca, 1);
819         } else {
820             TCGv zero = tcg_const_tl(0);
821             if (add_ca) {
822                 tcg_gen_add2_tl(t0, cpu_ca, arg1, zero, cpu_ca, zero);
823                 tcg_gen_add2_tl(t0, cpu_ca, t0, cpu_ca, arg2, zero);
824             } else {
825                 tcg_gen_add2_tl(t0, cpu_ca, arg1, zero, arg2, zero);
826             }
827             tcg_temp_free(zero);
828         }
829     } else {
830         tcg_gen_add_tl(t0, arg1, arg2);
831         if (add_ca) {
832             tcg_gen_add_tl(t0, t0, cpu_ca);
833         }
834     }
835
836     if (compute_ov) {
837         gen_op_arith_compute_ov(ctx, t0, arg1, arg2, 0);
838     }
839     if (unlikely(compute_rc0)) {
840         gen_set_Rc0(ctx, t0);
841     }
842
843     if (!TCGV_EQUAL(t0, ret)) {
844         tcg_gen_mov_tl(ret, t0);
845         tcg_temp_free(t0);
846     }
847 }
848 /* Add functions with two operands */
849 #define GEN_INT_ARITH_ADD(name, opc3, add_ca, compute_ca, compute_ov)         \
850 static void glue(gen_, name)(DisasContext *ctx)                               \
851 {                                                                             \
852     gen_op_arith_add(ctx, cpu_gpr[rD(ctx->opcode)],                           \
853                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],      \
854                      add_ca, compute_ca, compute_ov, Rc(ctx->opcode));        \
855 }
856 /* Add functions with one operand and one immediate */
857 #define GEN_INT_ARITH_ADD_CONST(name, opc3, const_val,                        \
858                                 add_ca, compute_ca, compute_ov)               \
859 static void glue(gen_, name)(DisasContext *ctx)                               \
860 {                                                                             \
861     TCGv t0 = tcg_const_tl(const_val);                                        \
862     gen_op_arith_add(ctx, cpu_gpr[rD(ctx->opcode)],                           \
863                      cpu_gpr[rA(ctx->opcode)], t0,                            \
864                      add_ca, compute_ca, compute_ov, Rc(ctx->opcode));        \
865     tcg_temp_free(t0);                                                        \
866 }
867
868 /* add  add.  addo  addo. */
869 GEN_INT_ARITH_ADD(add, 0x08, 0, 0, 0)
870 GEN_INT_ARITH_ADD(addo, 0x18, 0, 0, 1)
871 /* addc  addc.  addco  addco. */
872 GEN_INT_ARITH_ADD(addc, 0x00, 0, 1, 0)
873 GEN_INT_ARITH_ADD(addco, 0x10, 0, 1, 1)
874 /* adde  adde.  addeo  addeo. */
875 GEN_INT_ARITH_ADD(adde, 0x04, 1, 1, 0)
876 GEN_INT_ARITH_ADD(addeo, 0x14, 1, 1, 1)
877 /* addme  addme.  addmeo  addmeo.  */
878 GEN_INT_ARITH_ADD_CONST(addme, 0x07, -1LL, 1, 1, 0)
879 GEN_INT_ARITH_ADD_CONST(addmeo, 0x17, -1LL, 1, 1, 1)
880 /* addze  addze.  addzeo  addzeo.*/
881 GEN_INT_ARITH_ADD_CONST(addze, 0x06, 0, 1, 1, 0)
882 GEN_INT_ARITH_ADD_CONST(addzeo, 0x16, 0, 1, 1, 1)
883 /* addi */
884 static void gen_addi(DisasContext *ctx)
885 {
886     target_long simm = SIMM(ctx->opcode);
887
888     if (rA(ctx->opcode) == 0) {
889         /* li case */
890         tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], simm);
891     } else {
892         tcg_gen_addi_tl(cpu_gpr[rD(ctx->opcode)],
893                         cpu_gpr[rA(ctx->opcode)], simm);
894     }
895 }
896 /* addic  addic.*/
897 static inline void gen_op_addic(DisasContext *ctx, bool compute_rc0)
898 {
899     TCGv c = tcg_const_tl(SIMM(ctx->opcode));
900     gen_op_arith_add(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
901                      c, 0, 1, 0, compute_rc0);
902     tcg_temp_free(c);
903 }
904
905 static void gen_addic(DisasContext *ctx)
906 {
907     gen_op_addic(ctx, 0);
908 }
909
910 static void gen_addic_(DisasContext *ctx)
911 {
912     gen_op_addic(ctx, 1);
913 }
914
915 /* addis */
916 static void gen_addis(DisasContext *ctx)
917 {
918     target_long simm = SIMM(ctx->opcode);
919
920     if (rA(ctx->opcode) == 0) {
921         /* lis case */
922         tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], simm << 16);
923     } else {
924         tcg_gen_addi_tl(cpu_gpr[rD(ctx->opcode)],
925                         cpu_gpr[rA(ctx->opcode)], simm << 16);
926     }
927 }
928
929 static inline void gen_op_arith_divw(DisasContext *ctx, TCGv ret, TCGv arg1,
930                                      TCGv arg2, int sign, int compute_ov)
931 {
932     int l1 = gen_new_label();
933     int l2 = gen_new_label();
934     TCGv_i32 t0 = tcg_temp_local_new_i32();
935     TCGv_i32 t1 = tcg_temp_local_new_i32();
936
937     tcg_gen_trunc_tl_i32(t0, arg1);
938     tcg_gen_trunc_tl_i32(t1, arg2);
939     tcg_gen_brcondi_i32(TCG_COND_EQ, t1, 0, l1);
940     if (sign) {
941         int l3 = gen_new_label();
942         tcg_gen_brcondi_i32(TCG_COND_NE, t1, -1, l3);
943         tcg_gen_brcondi_i32(TCG_COND_EQ, t0, INT32_MIN, l1);
944         gen_set_label(l3);
945         tcg_gen_div_i32(t0, t0, t1);
946     } else {
947         tcg_gen_divu_i32(t0, t0, t1);
948     }
949     if (compute_ov) {
950         tcg_gen_movi_tl(cpu_ov, 0);
951     }
952     tcg_gen_br(l2);
953     gen_set_label(l1);
954     if (sign) {
955         tcg_gen_sari_i32(t0, t0, 31);
956     } else {
957         tcg_gen_movi_i32(t0, 0);
958     }
959     if (compute_ov) {
960         tcg_gen_movi_tl(cpu_ov, 1);
961         tcg_gen_movi_tl(cpu_so, 1);
962     }
963     gen_set_label(l2);
964     tcg_gen_extu_i32_tl(ret, t0);
965     tcg_temp_free_i32(t0);
966     tcg_temp_free_i32(t1);
967     if (unlikely(Rc(ctx->opcode) != 0))
968         gen_set_Rc0(ctx, ret);
969 }
970 /* Div functions */
971 #define GEN_INT_ARITH_DIVW(name, opc3, sign, compute_ov)                      \
972 static void glue(gen_, name)(DisasContext *ctx)                                       \
973 {                                                                             \
974     gen_op_arith_divw(ctx, cpu_gpr[rD(ctx->opcode)],                          \
975                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],      \
976                      sign, compute_ov);                                       \
977 }
978 /* divwu  divwu.  divwuo  divwuo.   */
979 GEN_INT_ARITH_DIVW(divwu, 0x0E, 0, 0);
980 GEN_INT_ARITH_DIVW(divwuo, 0x1E, 0, 1);
981 /* divw  divw.  divwo  divwo.   */
982 GEN_INT_ARITH_DIVW(divw, 0x0F, 1, 0);
983 GEN_INT_ARITH_DIVW(divwo, 0x1F, 1, 1);
984 #if defined(TARGET_PPC64)
985 static inline void gen_op_arith_divd(DisasContext *ctx, TCGv ret, TCGv arg1,
986                                      TCGv arg2, int sign, int compute_ov)
987 {
988     int l1 = gen_new_label();
989     int l2 = gen_new_label();
990
991     tcg_gen_brcondi_i64(TCG_COND_EQ, arg2, 0, l1);
992     if (sign) {
993         int l3 = gen_new_label();
994         tcg_gen_brcondi_i64(TCG_COND_NE, arg2, -1, l3);
995         tcg_gen_brcondi_i64(TCG_COND_EQ, arg1, INT64_MIN, l1);
996         gen_set_label(l3);
997         tcg_gen_div_i64(ret, arg1, arg2);
998     } else {
999         tcg_gen_divu_i64(ret, arg1, arg2);
1000     }
1001     if (compute_ov) {
1002         tcg_gen_movi_tl(cpu_ov, 0);
1003     }
1004     tcg_gen_br(l2);
1005     gen_set_label(l1);
1006     if (sign) {
1007         tcg_gen_sari_i64(ret, arg1, 63);
1008     } else {
1009         tcg_gen_movi_i64(ret, 0);
1010     }
1011     if (compute_ov) {
1012         tcg_gen_movi_tl(cpu_ov, 1);
1013         tcg_gen_movi_tl(cpu_so, 1);
1014     }
1015     gen_set_label(l2);
1016     if (unlikely(Rc(ctx->opcode) != 0))
1017         gen_set_Rc0(ctx, ret);
1018 }
1019 #define GEN_INT_ARITH_DIVD(name, opc3, sign, compute_ov)                      \
1020 static void glue(gen_, name)(DisasContext *ctx)                                       \
1021 {                                                                             \
1022     gen_op_arith_divd(ctx, cpu_gpr[rD(ctx->opcode)],                          \
1023                       cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],     \
1024                       sign, compute_ov);                                      \
1025 }
1026 /* divwu  divwu.  divwuo  divwuo.   */
1027 GEN_INT_ARITH_DIVD(divdu, 0x0E, 0, 0);
1028 GEN_INT_ARITH_DIVD(divduo, 0x1E, 0, 1);
1029 /* divw  divw.  divwo  divwo.   */
1030 GEN_INT_ARITH_DIVD(divd, 0x0F, 1, 0);
1031 GEN_INT_ARITH_DIVD(divdo, 0x1F, 1, 1);
1032 #endif
1033
1034 /* mulhw  mulhw. */
1035 static void gen_mulhw(DisasContext *ctx)
1036 {
1037     TCGv_i32 t0 = tcg_temp_new_i32();
1038     TCGv_i32 t1 = tcg_temp_new_i32();
1039
1040     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);
1041     tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);
1042     tcg_gen_muls2_i32(t0, t1, t0, t1);
1043     tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t1);
1044     tcg_temp_free_i32(t0);
1045     tcg_temp_free_i32(t1);
1046     if (unlikely(Rc(ctx->opcode) != 0))
1047         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1048 }
1049
1050 /* mulhwu  mulhwu.  */
1051 static void gen_mulhwu(DisasContext *ctx)
1052 {
1053     TCGv_i32 t0 = tcg_temp_new_i32();
1054     TCGv_i32 t1 = tcg_temp_new_i32();
1055
1056     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);
1057     tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);
1058     tcg_gen_mulu2_i32(t0, t1, t0, t1);
1059     tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t1);
1060     tcg_temp_free_i32(t0);
1061     tcg_temp_free_i32(t1);
1062     if (unlikely(Rc(ctx->opcode) != 0))
1063         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1064 }
1065
1066 /* mullw  mullw. */
1067 static void gen_mullw(DisasContext *ctx)
1068 {
1069     tcg_gen_mul_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
1070                    cpu_gpr[rB(ctx->opcode)]);
1071     tcg_gen_ext32s_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)]);
1072     if (unlikely(Rc(ctx->opcode) != 0))
1073         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1074 }
1075
1076 /* mullwo  mullwo. */
1077 static void gen_mullwo(DisasContext *ctx)
1078 {
1079     TCGv_i32 t0 = tcg_temp_new_i32();
1080     TCGv_i32 t1 = tcg_temp_new_i32();
1081
1082     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);
1083     tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);
1084     tcg_gen_muls2_i32(t0, t1, t0, t1);
1085     tcg_gen_ext_i32_tl(cpu_gpr[rD(ctx->opcode)], t0);
1086
1087     tcg_gen_sari_i32(t0, t0, 31);
1088     tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t1);
1089     tcg_gen_extu_i32_tl(cpu_ov, t0);
1090     tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov);
1091
1092     tcg_temp_free_i32(t0);
1093     tcg_temp_free_i32(t1);
1094     if (unlikely(Rc(ctx->opcode) != 0))
1095         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1096 }
1097
1098 /* mulli */
1099 static void gen_mulli(DisasContext *ctx)
1100 {
1101     tcg_gen_muli_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
1102                     SIMM(ctx->opcode));
1103 }
1104
1105 #if defined(TARGET_PPC64)
1106 /* mulhd  mulhd. */
1107 static void gen_mulhd(DisasContext *ctx)
1108 {
1109     TCGv lo = tcg_temp_new();
1110     tcg_gen_muls2_tl(lo, cpu_gpr[rD(ctx->opcode)],
1111                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1112     tcg_temp_free(lo);
1113     if (unlikely(Rc(ctx->opcode) != 0)) {
1114         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1115     }
1116 }
1117
1118 /* mulhdu  mulhdu. */
1119 static void gen_mulhdu(DisasContext *ctx)
1120 {
1121     TCGv lo = tcg_temp_new();
1122     tcg_gen_mulu2_tl(lo, cpu_gpr[rD(ctx->opcode)],
1123                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1124     tcg_temp_free(lo);
1125     if (unlikely(Rc(ctx->opcode) != 0)) {
1126         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1127     }
1128 }
1129
1130 /* mulld  mulld. */
1131 static void gen_mulld(DisasContext *ctx)
1132 {
1133     tcg_gen_mul_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
1134                    cpu_gpr[rB(ctx->opcode)]);
1135     if (unlikely(Rc(ctx->opcode) != 0))
1136         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1137 }
1138
1139 /* mulldo  mulldo. */
1140 static void gen_mulldo(DisasContext *ctx)
1141 {
1142     gen_helper_mulldo(cpu_gpr[rD(ctx->opcode)], cpu_env,
1143                       cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1144     if (unlikely(Rc(ctx->opcode) != 0)) {
1145         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1146     }
1147 }
1148 #endif
1149
1150 /* Common subf function */
1151 static inline void gen_op_arith_subf(DisasContext *ctx, TCGv ret, TCGv arg1,
1152                                      TCGv arg2, bool add_ca, bool compute_ca,
1153                                      bool compute_ov, bool compute_rc0)
1154 {
1155     TCGv t0 = ret;
1156
1157     if (compute_ca || compute_ov) {
1158         t0 = tcg_temp_new();
1159     }
1160
1161     if (compute_ca) {
1162         /* dest = ~arg1 + arg2 [+ ca].  */
1163         if (NARROW_MODE(ctx)) {
1164             /* Caution: a non-obvious corner case of the spec is that we
1165                must produce the *entire* 64-bit addition, but produce the
1166                carry into bit 32.  */
1167             TCGv inv1 = tcg_temp_new();
1168             TCGv t1 = tcg_temp_new();
1169             tcg_gen_not_tl(inv1, arg1);
1170             if (add_ca) {
1171                 tcg_gen_add_tl(t0, arg2, cpu_ca);
1172             } else {
1173                 tcg_gen_addi_tl(t0, arg2, 1);
1174             }
1175             tcg_gen_xor_tl(t1, arg2, inv1);         /* add without carry */
1176             tcg_gen_add_tl(t0, t0, inv1);
1177             tcg_gen_xor_tl(cpu_ca, t0, t1);         /* bits changes w/ carry */
1178             tcg_temp_free(t1);
1179             tcg_gen_shri_tl(cpu_ca, cpu_ca, 32);    /* extract bit 32 */
1180             tcg_gen_andi_tl(cpu_ca, cpu_ca, 1);
1181         } else if (add_ca) {
1182             TCGv zero, inv1 = tcg_temp_new();
1183             tcg_gen_not_tl(inv1, arg1);
1184             zero = tcg_const_tl(0);
1185             tcg_gen_add2_tl(t0, cpu_ca, arg2, zero, cpu_ca, zero);
1186             tcg_gen_add2_tl(t0, cpu_ca, t0, cpu_ca, inv1, zero);
1187             tcg_temp_free(zero);
1188             tcg_temp_free(inv1);
1189         } else {
1190             tcg_gen_setcond_tl(TCG_COND_GEU, cpu_ca, arg2, arg1);
1191             tcg_gen_sub_tl(t0, arg2, arg1);
1192         }
1193     } else if (add_ca) {
1194         /* Since we're ignoring carry-out, we can simplify the
1195            standard ~arg1 + arg2 + ca to arg2 - arg1 + ca - 1.  */
1196         tcg_gen_sub_tl(t0, arg2, arg1);
1197         tcg_gen_add_tl(t0, t0, cpu_ca);
1198         tcg_gen_subi_tl(t0, t0, 1);
1199     } else {
1200         tcg_gen_sub_tl(t0, arg2, arg1);
1201     }
1202
1203     if (compute_ov) {
1204         gen_op_arith_compute_ov(ctx, t0, arg1, arg2, 1);
1205     }
1206     if (unlikely(compute_rc0)) {
1207         gen_set_Rc0(ctx, t0);
1208     }
1209
1210     if (!TCGV_EQUAL(t0, ret)) {
1211         tcg_gen_mov_tl(ret, t0);
1212         tcg_temp_free(t0);
1213     }
1214 }
1215 /* Sub functions with Two operands functions */
1216 #define GEN_INT_ARITH_SUBF(name, opc3, add_ca, compute_ca, compute_ov)        \
1217 static void glue(gen_, name)(DisasContext *ctx)                               \
1218 {                                                                             \
1219     gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)],                          \
1220                       cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],     \
1221                       add_ca, compute_ca, compute_ov, Rc(ctx->opcode));       \
1222 }
1223 /* Sub functions with one operand and one immediate */
1224 #define GEN_INT_ARITH_SUBF_CONST(name, opc3, const_val,                       \
1225                                 add_ca, compute_ca, compute_ov)               \
1226 static void glue(gen_, name)(DisasContext *ctx)                               \
1227 {                                                                             \
1228     TCGv t0 = tcg_const_tl(const_val);                                        \
1229     gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)],                          \
1230                       cpu_gpr[rA(ctx->opcode)], t0,                           \
1231                       add_ca, compute_ca, compute_ov, Rc(ctx->opcode));       \
1232     tcg_temp_free(t0);                                                        \
1233 }
1234 /* subf  subf.  subfo  subfo. */
1235 GEN_INT_ARITH_SUBF(subf, 0x01, 0, 0, 0)
1236 GEN_INT_ARITH_SUBF(subfo, 0x11, 0, 0, 1)
1237 /* subfc  subfc.  subfco  subfco. */
1238 GEN_INT_ARITH_SUBF(subfc, 0x00, 0, 1, 0)
1239 GEN_INT_ARITH_SUBF(subfco, 0x10, 0, 1, 1)
1240 /* subfe  subfe.  subfeo  subfo. */
1241 GEN_INT_ARITH_SUBF(subfe, 0x04, 1, 1, 0)
1242 GEN_INT_ARITH_SUBF(subfeo, 0x14, 1, 1, 1)
1243 /* subfme  subfme.  subfmeo  subfmeo.  */
1244 GEN_INT_ARITH_SUBF_CONST(subfme, 0x07, -1LL, 1, 1, 0)
1245 GEN_INT_ARITH_SUBF_CONST(subfmeo, 0x17, -1LL, 1, 1, 1)
1246 /* subfze  subfze.  subfzeo  subfzeo.*/
1247 GEN_INT_ARITH_SUBF_CONST(subfze, 0x06, 0, 1, 1, 0)
1248 GEN_INT_ARITH_SUBF_CONST(subfzeo, 0x16, 0, 1, 1, 1)
1249
1250 /* subfic */
1251 static void gen_subfic(DisasContext *ctx)
1252 {
1253     TCGv c = tcg_const_tl(SIMM(ctx->opcode));
1254     gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
1255                       c, 0, 1, 0, 0);
1256     tcg_temp_free(c);
1257 }
1258
1259 /* neg neg. nego nego. */
1260 static inline void gen_op_arith_neg(DisasContext *ctx, bool compute_ov)
1261 {
1262     TCGv zero = tcg_const_tl(0);
1263     gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
1264                       zero, 0, 0, compute_ov, Rc(ctx->opcode));
1265     tcg_temp_free(zero);
1266 }
1267
1268 static void gen_neg(DisasContext *ctx)
1269 {
1270     gen_op_arith_neg(ctx, 0);
1271 }
1272
1273 static void gen_nego(DisasContext *ctx)
1274 {
1275     gen_op_arith_neg(ctx, 1);
1276 }
1277
1278 /***                            Integer logical                            ***/
1279 #define GEN_LOGICAL2(name, tcg_op, opc, type)                                 \
1280 static void glue(gen_, name)(DisasContext *ctx)                                       \
1281 {                                                                             \
1282     tcg_op(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)],                \
1283        cpu_gpr[rB(ctx->opcode)]);                                             \
1284     if (unlikely(Rc(ctx->opcode) != 0))                                       \
1285         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);                           \
1286 }
1287
1288 #define GEN_LOGICAL1(name, tcg_op, opc, type)                                 \
1289 static void glue(gen_, name)(DisasContext *ctx)                                       \
1290 {                                                                             \
1291     tcg_op(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);               \
1292     if (unlikely(Rc(ctx->opcode) != 0))                                       \
1293         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);                           \
1294 }
1295
1296 /* and & and. */
1297 GEN_LOGICAL2(and, tcg_gen_and_tl, 0x00, PPC_INTEGER);
1298 /* andc & andc. */
1299 GEN_LOGICAL2(andc, tcg_gen_andc_tl, 0x01, PPC_INTEGER);
1300
1301 /* andi. */
1302 static void gen_andi_(DisasContext *ctx)
1303 {
1304     tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], UIMM(ctx->opcode));
1305     gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1306 }
1307
1308 /* andis. */
1309 static void gen_andis_(DisasContext *ctx)
1310 {
1311     tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], UIMM(ctx->opcode) << 16);
1312     gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1313 }
1314
1315 /* cntlzw */
1316 static void gen_cntlzw(DisasContext *ctx)
1317 {
1318     gen_helper_cntlzw(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1319     if (unlikely(Rc(ctx->opcode) != 0))
1320         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1321 }
1322 /* eqv & eqv. */
1323 GEN_LOGICAL2(eqv, tcg_gen_eqv_tl, 0x08, PPC_INTEGER);
1324 /* extsb & extsb. */
1325 GEN_LOGICAL1(extsb, tcg_gen_ext8s_tl, 0x1D, PPC_INTEGER);
1326 /* extsh & extsh. */
1327 GEN_LOGICAL1(extsh, tcg_gen_ext16s_tl, 0x1C, PPC_INTEGER);
1328 /* nand & nand. */
1329 GEN_LOGICAL2(nand, tcg_gen_nand_tl, 0x0E, PPC_INTEGER);
1330 /* nor & nor. */
1331 GEN_LOGICAL2(nor, tcg_gen_nor_tl, 0x03, PPC_INTEGER);
1332
1333 /* or & or. */
1334 static void gen_or(DisasContext *ctx)
1335 {
1336     int rs, ra, rb;
1337
1338     rs = rS(ctx->opcode);
1339     ra = rA(ctx->opcode);
1340     rb = rB(ctx->opcode);
1341     /* Optimisation for mr. ri case */
1342     if (rs != ra || rs != rb) {
1343         if (rs != rb)
1344             tcg_gen_or_tl(cpu_gpr[ra], cpu_gpr[rs], cpu_gpr[rb]);
1345         else
1346             tcg_gen_mov_tl(cpu_gpr[ra], cpu_gpr[rs]);
1347         if (unlikely(Rc(ctx->opcode) != 0))
1348             gen_set_Rc0(ctx, cpu_gpr[ra]);
1349     } else if (unlikely(Rc(ctx->opcode) != 0)) {
1350         gen_set_Rc0(ctx, cpu_gpr[rs]);
1351 #if defined(TARGET_PPC64)
1352     } else {
1353         int prio = 0;
1354
1355         switch (rs) {
1356         case 1:
1357             /* Set process priority to low */
1358             prio = 2;
1359             break;
1360         case 6:
1361             /* Set process priority to medium-low */
1362             prio = 3;
1363             break;
1364         case 2:
1365             /* Set process priority to normal */
1366             prio = 4;
1367             break;
1368 #if !defined(CONFIG_USER_ONLY)
1369         case 31:
1370             if (ctx->mem_idx > 0) {
1371                 /* Set process priority to very low */
1372                 prio = 1;
1373             }
1374             break;
1375         case 5:
1376             if (ctx->mem_idx > 0) {
1377                 /* Set process priority to medium-hight */
1378                 prio = 5;
1379             }
1380             break;
1381         case 3:
1382             if (ctx->mem_idx > 0) {
1383                 /* Set process priority to high */
1384                 prio = 6;
1385             }
1386             break;
1387         case 7:
1388             if (ctx->mem_idx > 1) {
1389                 /* Set process priority to very high */
1390                 prio = 7;
1391             }
1392             break;
1393 #endif
1394         default:
1395             /* nop */
1396             break;
1397         }
1398         if (prio) {
1399             TCGv t0 = tcg_temp_new();
1400             gen_load_spr(t0, SPR_PPR);
1401             tcg_gen_andi_tl(t0, t0, ~0x001C000000000000ULL);
1402             tcg_gen_ori_tl(t0, t0, ((uint64_t)prio) << 50);
1403             gen_store_spr(SPR_PPR, t0);
1404             tcg_temp_free(t0);
1405         }
1406 #endif
1407     }
1408 }
1409 /* orc & orc. */
1410 GEN_LOGICAL2(orc, tcg_gen_orc_tl, 0x0C, PPC_INTEGER);
1411
1412 /* xor & xor. */
1413 static void gen_xor(DisasContext *ctx)
1414 {
1415     /* Optimisation for "set to zero" case */
1416     if (rS(ctx->opcode) != rB(ctx->opcode))
1417         tcg_gen_xor_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1418     else
1419         tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
1420     if (unlikely(Rc(ctx->opcode) != 0))
1421         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1422 }
1423
1424 /* ori */
1425 static void gen_ori(DisasContext *ctx)
1426 {
1427     target_ulong uimm = UIMM(ctx->opcode);
1428
1429     if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1430         /* NOP */
1431         /* XXX: should handle special NOPs for POWER series */
1432         return;
1433     }
1434     tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm);
1435 }
1436
1437 /* oris */
1438 static void gen_oris(DisasContext *ctx)
1439 {
1440     target_ulong uimm = UIMM(ctx->opcode);
1441
1442     if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1443         /* NOP */
1444         return;
1445     }
1446     tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm << 16);
1447 }
1448
1449 /* xori */
1450 static void gen_xori(DisasContext *ctx)
1451 {
1452     target_ulong uimm = UIMM(ctx->opcode);
1453
1454     if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1455         /* NOP */
1456         return;
1457     }
1458     tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm);
1459 }
1460
1461 /* xoris */
1462 static void gen_xoris(DisasContext *ctx)
1463 {
1464     target_ulong uimm = UIMM(ctx->opcode);
1465
1466     if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1467         /* NOP */
1468         return;
1469     }
1470     tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm << 16);
1471 }
1472
1473 /* popcntb : PowerPC 2.03 specification */
1474 static void gen_popcntb(DisasContext *ctx)
1475 {
1476     gen_helper_popcntb(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1477 }
1478
1479 static void gen_popcntw(DisasContext *ctx)
1480 {
1481     gen_helper_popcntw(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1482 }
1483
1484 #if defined(TARGET_PPC64)
1485 /* popcntd: PowerPC 2.06 specification */
1486 static void gen_popcntd(DisasContext *ctx)
1487 {
1488     gen_helper_popcntd(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1489 }
1490 #endif
1491
1492 /* prtyw: PowerPC 2.05 specification */
1493 static void gen_prtyw(DisasContext *ctx)
1494 {
1495     TCGv ra = cpu_gpr[rA(ctx->opcode)];
1496     TCGv rs = cpu_gpr[rS(ctx->opcode)];
1497     TCGv t0 = tcg_temp_new();
1498     tcg_gen_shri_tl(t0, rs, 16);
1499     tcg_gen_xor_tl(ra, rs, t0);
1500     tcg_gen_shri_tl(t0, ra, 8);
1501     tcg_gen_xor_tl(ra, ra, t0);
1502     tcg_gen_andi_tl(ra, ra, (target_ulong)0x100000001ULL);
1503     tcg_temp_free(t0);
1504 }
1505
1506 #if defined(TARGET_PPC64)
1507 /* prtyd: PowerPC 2.05 specification */
1508 static void gen_prtyd(DisasContext *ctx)
1509 {
1510     TCGv ra = cpu_gpr[rA(ctx->opcode)];
1511     TCGv rs = cpu_gpr[rS(ctx->opcode)];
1512     TCGv t0 = tcg_temp_new();
1513     tcg_gen_shri_tl(t0, rs, 32);
1514     tcg_gen_xor_tl(ra, rs, t0);
1515     tcg_gen_shri_tl(t0, ra, 16);
1516     tcg_gen_xor_tl(ra, ra, t0);
1517     tcg_gen_shri_tl(t0, ra, 8);
1518     tcg_gen_xor_tl(ra, ra, t0);
1519     tcg_gen_andi_tl(ra, ra, 1);
1520     tcg_temp_free(t0);
1521 }
1522 #endif
1523
1524 #if defined(TARGET_PPC64)
1525 /* extsw & extsw. */
1526 GEN_LOGICAL1(extsw, tcg_gen_ext32s_tl, 0x1E, PPC_64B);
1527
1528 /* cntlzd */
1529 static void gen_cntlzd(DisasContext *ctx)
1530 {
1531     gen_helper_cntlzd(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1532     if (unlikely(Rc(ctx->opcode) != 0))
1533         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1534 }
1535 #endif
1536
1537 /***                             Integer rotate                            ***/
1538
1539 /* rlwimi & rlwimi. */
1540 static void gen_rlwimi(DisasContext *ctx)
1541 {
1542     uint32_t mb, me, sh;
1543
1544     mb = MB(ctx->opcode);
1545     me = ME(ctx->opcode);
1546     sh = SH(ctx->opcode);
1547     if (likely(sh == 0 && mb == 0 && me == 31)) {
1548         tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1549     } else {
1550         target_ulong mask;
1551         TCGv t1;
1552         TCGv t0 = tcg_temp_new();
1553 #if defined(TARGET_PPC64)
1554         TCGv_i32 t2 = tcg_temp_new_i32();
1555         tcg_gen_trunc_i64_i32(t2, cpu_gpr[rS(ctx->opcode)]);
1556         tcg_gen_rotli_i32(t2, t2, sh);
1557         tcg_gen_extu_i32_i64(t0, t2);
1558         tcg_temp_free_i32(t2);
1559 #else
1560         tcg_gen_rotli_i32(t0, cpu_gpr[rS(ctx->opcode)], sh);
1561 #endif
1562 #if defined(TARGET_PPC64)
1563         mb += 32;
1564         me += 32;
1565 #endif
1566         mask = MASK(mb, me);
1567         t1 = tcg_temp_new();
1568         tcg_gen_andi_tl(t0, t0, mask);
1569         tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], ~mask);
1570         tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
1571         tcg_temp_free(t0);
1572         tcg_temp_free(t1);
1573     }
1574     if (unlikely(Rc(ctx->opcode) != 0))
1575         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1576 }
1577
1578 /* rlwinm & rlwinm. */
1579 static void gen_rlwinm(DisasContext *ctx)
1580 {
1581     uint32_t mb, me, sh;
1582
1583     sh = SH(ctx->opcode);
1584     mb = MB(ctx->opcode);
1585     me = ME(ctx->opcode);
1586
1587     if (likely(mb == 0 && me == (31 - sh))) {
1588         if (likely(sh == 0)) {
1589             tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1590         } else {
1591             TCGv t0 = tcg_temp_new();
1592             tcg_gen_ext32u_tl(t0, cpu_gpr[rS(ctx->opcode)]);
1593             tcg_gen_shli_tl(t0, t0, sh);
1594             tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], t0);
1595             tcg_temp_free(t0);
1596         }
1597     } else if (likely(sh != 0 && me == 31 && sh == (32 - mb))) {
1598         TCGv t0 = tcg_temp_new();
1599         tcg_gen_ext32u_tl(t0, cpu_gpr[rS(ctx->opcode)]);
1600         tcg_gen_shri_tl(t0, t0, mb);
1601         tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], t0);
1602         tcg_temp_free(t0);
1603     } else {
1604         TCGv t0 = tcg_temp_new();
1605 #if defined(TARGET_PPC64)
1606         TCGv_i32 t1 = tcg_temp_new_i32();
1607         tcg_gen_trunc_i64_i32(t1, cpu_gpr[rS(ctx->opcode)]);
1608         tcg_gen_rotli_i32(t1, t1, sh);
1609         tcg_gen_extu_i32_i64(t0, t1);
1610         tcg_temp_free_i32(t1);
1611 #else
1612         tcg_gen_rotli_i32(t0, cpu_gpr[rS(ctx->opcode)], sh);
1613 #endif
1614 #if defined(TARGET_PPC64)
1615         mb += 32;
1616         me += 32;
1617 #endif
1618         tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t0, MASK(mb, me));
1619         tcg_temp_free(t0);
1620     }
1621     if (unlikely(Rc(ctx->opcode) != 0))
1622         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1623 }
1624
1625 /* rlwnm & rlwnm. */
1626 static void gen_rlwnm(DisasContext *ctx)
1627 {
1628     uint32_t mb, me;
1629     TCGv t0;
1630 #if defined(TARGET_PPC64)
1631     TCGv_i32 t1, t2;
1632 #endif
1633
1634     mb = MB(ctx->opcode);
1635     me = ME(ctx->opcode);
1636     t0 = tcg_temp_new();
1637     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1f);
1638 #if defined(TARGET_PPC64)
1639     t1 = tcg_temp_new_i32();
1640     t2 = tcg_temp_new_i32();
1641     tcg_gen_trunc_i64_i32(t1, cpu_gpr[rS(ctx->opcode)]);
1642     tcg_gen_trunc_i64_i32(t2, t0);
1643     tcg_gen_rotl_i32(t1, t1, t2);
1644     tcg_gen_extu_i32_i64(t0, t1);
1645     tcg_temp_free_i32(t1);
1646     tcg_temp_free_i32(t2);
1647 #else
1648     tcg_gen_rotl_i32(t0, cpu_gpr[rS(ctx->opcode)], t0);
1649 #endif
1650     if (unlikely(mb != 0 || me != 31)) {
1651 #if defined(TARGET_PPC64)
1652         mb += 32;
1653         me += 32;
1654 #endif
1655         tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t0, MASK(mb, me));
1656     } else {
1657         tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
1658     }
1659     tcg_temp_free(t0);
1660     if (unlikely(Rc(ctx->opcode) != 0))
1661         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1662 }
1663
1664 #if defined(TARGET_PPC64)
1665 #define GEN_PPC64_R2(name, opc1, opc2)                                        \
1666 static void glue(gen_, name##0)(DisasContext *ctx)                            \
1667 {                                                                             \
1668     gen_##name(ctx, 0);                                                       \
1669 }                                                                             \
1670                                                                               \
1671 static void glue(gen_, name##1)(DisasContext *ctx)                            \
1672 {                                                                             \
1673     gen_##name(ctx, 1);                                                       \
1674 }
1675 #define GEN_PPC64_R4(name, opc1, opc2)                                        \
1676 static void glue(gen_, name##0)(DisasContext *ctx)                            \
1677 {                                                                             \
1678     gen_##name(ctx, 0, 0);                                                    \
1679 }                                                                             \
1680                                                                               \
1681 static void glue(gen_, name##1)(DisasContext *ctx)                            \
1682 {                                                                             \
1683     gen_##name(ctx, 0, 1);                                                    \
1684 }                                                                             \
1685                                                                               \
1686 static void glue(gen_, name##2)(DisasContext *ctx)                            \
1687 {                                                                             \
1688     gen_##name(ctx, 1, 0);                                                    \
1689 }                                                                             \
1690                                                                               \
1691 static void glue(gen_, name##3)(DisasContext *ctx)                            \
1692 {                                                                             \
1693     gen_##name(ctx, 1, 1);                                                    \
1694 }
1695
1696 static inline void gen_rldinm(DisasContext *ctx, uint32_t mb, uint32_t me,
1697                               uint32_t sh)
1698 {
1699     if (likely(sh != 0 && mb == 0 && me == (63 - sh))) {
1700         tcg_gen_shli_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], sh);
1701     } else if (likely(sh != 0 && me == 63 && sh == (64 - mb))) {
1702         tcg_gen_shri_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], mb);
1703     } else {
1704         TCGv t0 = tcg_temp_new();
1705         tcg_gen_rotli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
1706         if (likely(mb == 0 && me == 63)) {
1707             tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
1708         } else {
1709             tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t0, MASK(mb, me));
1710         }
1711         tcg_temp_free(t0);
1712     }
1713     if (unlikely(Rc(ctx->opcode) != 0))
1714         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1715 }
1716 /* rldicl - rldicl. */
1717 static inline void gen_rldicl(DisasContext *ctx, int mbn, int shn)
1718 {
1719     uint32_t sh, mb;
1720
1721     sh = SH(ctx->opcode) | (shn << 5);
1722     mb = MB(ctx->opcode) | (mbn << 5);
1723     gen_rldinm(ctx, mb, 63, sh);
1724 }
1725 GEN_PPC64_R4(rldicl, 0x1E, 0x00);
1726 /* rldicr - rldicr. */
1727 static inline void gen_rldicr(DisasContext *ctx, int men, int shn)
1728 {
1729     uint32_t sh, me;
1730
1731     sh = SH(ctx->opcode) | (shn << 5);
1732     me = MB(ctx->opcode) | (men << 5);
1733     gen_rldinm(ctx, 0, me, sh);
1734 }
1735 GEN_PPC64_R4(rldicr, 0x1E, 0x02);
1736 /* rldic - rldic. */
1737 static inline void gen_rldic(DisasContext *ctx, int mbn, int shn)
1738 {
1739     uint32_t sh, mb;
1740
1741     sh = SH(ctx->opcode) | (shn << 5);
1742     mb = MB(ctx->opcode) | (mbn << 5);
1743     gen_rldinm(ctx, mb, 63 - sh, sh);
1744 }
1745 GEN_PPC64_R4(rldic, 0x1E, 0x04);
1746
1747 static inline void gen_rldnm(DisasContext *ctx, uint32_t mb, uint32_t me)
1748 {
1749     TCGv t0;
1750
1751     t0 = tcg_temp_new();
1752     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3f);
1753     tcg_gen_rotl_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
1754     if (unlikely(mb != 0 || me != 63)) {
1755         tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t0, MASK(mb, me));
1756     } else {
1757         tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
1758     }
1759     tcg_temp_free(t0);
1760     if (unlikely(Rc(ctx->opcode) != 0))
1761         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1762 }
1763
1764 /* rldcl - rldcl. */
1765 static inline void gen_rldcl(DisasContext *ctx, int mbn)
1766 {
1767     uint32_t mb;
1768
1769     mb = MB(ctx->opcode) | (mbn << 5);
1770     gen_rldnm(ctx, mb, 63);
1771 }
1772 GEN_PPC64_R2(rldcl, 0x1E, 0x08);
1773 /* rldcr - rldcr. */
1774 static inline void gen_rldcr(DisasContext *ctx, int men)
1775 {
1776     uint32_t me;
1777
1778     me = MB(ctx->opcode) | (men << 5);
1779     gen_rldnm(ctx, 0, me);
1780 }
1781 GEN_PPC64_R2(rldcr, 0x1E, 0x09);
1782 /* rldimi - rldimi. */
1783 static inline void gen_rldimi(DisasContext *ctx, int mbn, int shn)
1784 {
1785     uint32_t sh, mb, me;
1786
1787     sh = SH(ctx->opcode) | (shn << 5);
1788     mb = MB(ctx->opcode) | (mbn << 5);
1789     me = 63 - sh;
1790     if (unlikely(sh == 0 && mb == 0)) {
1791         tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1792     } else {
1793         TCGv t0, t1;
1794         target_ulong mask;
1795
1796         t0 = tcg_temp_new();
1797         tcg_gen_rotli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
1798         t1 = tcg_temp_new();
1799         mask = MASK(mb, me);
1800         tcg_gen_andi_tl(t0, t0, mask);
1801         tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], ~mask);
1802         tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
1803         tcg_temp_free(t0);
1804         tcg_temp_free(t1);
1805     }
1806     if (unlikely(Rc(ctx->opcode) != 0))
1807         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1808 }
1809 GEN_PPC64_R4(rldimi, 0x1E, 0x06);
1810 #endif
1811
1812 /***                             Integer shift                             ***/
1813
1814 /* slw & slw. */
1815 static void gen_slw(DisasContext *ctx)
1816 {
1817     TCGv t0, t1;
1818
1819     t0 = tcg_temp_new();
1820     /* AND rS with a mask that is 0 when rB >= 0x20 */
1821 #if defined(TARGET_PPC64)
1822     tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3a);
1823     tcg_gen_sari_tl(t0, t0, 0x3f);
1824 #else
1825     tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1a);
1826     tcg_gen_sari_tl(t0, t0, 0x1f);
1827 #endif
1828     tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
1829     t1 = tcg_temp_new();
1830     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1f);
1831     tcg_gen_shl_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
1832     tcg_temp_free(t1);
1833     tcg_temp_free(t0);
1834     tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
1835     if (unlikely(Rc(ctx->opcode) != 0))
1836         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1837 }
1838
1839 /* sraw & sraw. */
1840 static void gen_sraw(DisasContext *ctx)
1841 {
1842     gen_helper_sraw(cpu_gpr[rA(ctx->opcode)], cpu_env,
1843                     cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1844     if (unlikely(Rc(ctx->opcode) != 0))
1845         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1846 }
1847
1848 /* srawi & srawi. */
1849 static void gen_srawi(DisasContext *ctx)
1850 {
1851     int sh = SH(ctx->opcode);
1852     TCGv dst = cpu_gpr[rA(ctx->opcode)];
1853     TCGv src = cpu_gpr[rS(ctx->opcode)];
1854     if (sh == 0) {
1855         tcg_gen_mov_tl(dst, src);
1856         tcg_gen_movi_tl(cpu_ca, 0);
1857     } else {
1858         TCGv t0;
1859         tcg_gen_ext32s_tl(dst, src);
1860         tcg_gen_andi_tl(cpu_ca, dst, (1ULL << sh) - 1);
1861         t0 = tcg_temp_new();
1862         tcg_gen_sari_tl(t0, dst, TARGET_LONG_BITS - 1);
1863         tcg_gen_and_tl(cpu_ca, cpu_ca, t0);
1864         tcg_temp_free(t0);
1865         tcg_gen_setcondi_tl(TCG_COND_NE, cpu_ca, cpu_ca, 0);
1866         tcg_gen_sari_tl(dst, dst, sh);
1867     }
1868     if (unlikely(Rc(ctx->opcode) != 0)) {
1869         gen_set_Rc0(ctx, dst);
1870     }
1871 }
1872
1873 /* srw & srw. */
1874 static void gen_srw(DisasContext *ctx)
1875 {
1876     TCGv t0, t1;
1877
1878     t0 = tcg_temp_new();
1879     /* AND rS with a mask that is 0 when rB >= 0x20 */
1880 #if defined(TARGET_PPC64)
1881     tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3a);
1882     tcg_gen_sari_tl(t0, t0, 0x3f);
1883 #else
1884     tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1a);
1885     tcg_gen_sari_tl(t0, t0, 0x1f);
1886 #endif
1887     tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
1888     tcg_gen_ext32u_tl(t0, t0);
1889     t1 = tcg_temp_new();
1890     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1f);
1891     tcg_gen_shr_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
1892     tcg_temp_free(t1);
1893     tcg_temp_free(t0);
1894     if (unlikely(Rc(ctx->opcode) != 0))
1895         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1896 }
1897
1898 #if defined(TARGET_PPC64)
1899 /* sld & sld. */
1900 static void gen_sld(DisasContext *ctx)
1901 {
1902     TCGv t0, t1;
1903
1904     t0 = tcg_temp_new();
1905     /* AND rS with a mask that is 0 when rB >= 0x40 */
1906     tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x39);
1907     tcg_gen_sari_tl(t0, t0, 0x3f);
1908     tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
1909     t1 = tcg_temp_new();
1910     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x3f);
1911     tcg_gen_shl_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
1912     tcg_temp_free(t1);
1913     tcg_temp_free(t0);
1914     if (unlikely(Rc(ctx->opcode) != 0))
1915         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1916 }
1917
1918 /* srad & srad. */
1919 static void gen_srad(DisasContext *ctx)
1920 {
1921     gen_helper_srad(cpu_gpr[rA(ctx->opcode)], cpu_env,
1922                     cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1923     if (unlikely(Rc(ctx->opcode) != 0))
1924         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1925 }
1926 /* sradi & sradi. */
1927 static inline void gen_sradi(DisasContext *ctx, int n)
1928 {
1929     int sh = SH(ctx->opcode) + (n << 5);
1930     TCGv dst = cpu_gpr[rA(ctx->opcode)];
1931     TCGv src = cpu_gpr[rS(ctx->opcode)];
1932     if (sh == 0) {
1933         tcg_gen_mov_tl(dst, src);
1934         tcg_gen_movi_tl(cpu_ca, 0);
1935     } else {
1936         TCGv t0;
1937         tcg_gen_andi_tl(cpu_ca, src, (1ULL << sh) - 1);
1938         t0 = tcg_temp_new();
1939         tcg_gen_sari_tl(t0, src, TARGET_LONG_BITS - 1);
1940         tcg_gen_and_tl(cpu_ca, cpu_ca, t0);
1941         tcg_temp_free(t0);
1942         tcg_gen_setcondi_tl(TCG_COND_NE, cpu_ca, cpu_ca, 0);
1943         tcg_gen_sari_tl(dst, src, sh);
1944     }
1945     if (unlikely(Rc(ctx->opcode) != 0)) {
1946         gen_set_Rc0(ctx, dst);
1947     }
1948 }
1949
1950 static void gen_sradi0(DisasContext *ctx)
1951 {
1952     gen_sradi(ctx, 0);
1953 }
1954
1955 static void gen_sradi1(DisasContext *ctx)
1956 {
1957     gen_sradi(ctx, 1);
1958 }
1959
1960 /* srd & srd. */
1961 static void gen_srd(DisasContext *ctx)
1962 {
1963     TCGv t0, t1;
1964
1965     t0 = tcg_temp_new();
1966     /* AND rS with a mask that is 0 when rB >= 0x40 */
1967     tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x39);
1968     tcg_gen_sari_tl(t0, t0, 0x3f);
1969     tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
1970     t1 = tcg_temp_new();
1971     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x3f);
1972     tcg_gen_shr_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
1973     tcg_temp_free(t1);
1974     tcg_temp_free(t0);
1975     if (unlikely(Rc(ctx->opcode) != 0))
1976         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1977 }
1978 #endif
1979
1980 /***                       Floating-Point arithmetic                       ***/
1981 #define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat, set_fprf, type)           \
1982 static void gen_f##name(DisasContext *ctx)                                    \
1983 {                                                                             \
1984     if (unlikely(!ctx->fpu_enabled)) {                                        \
1985         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
1986         return;                                                               \
1987     }                                                                         \
1988     /* NIP cannot be restored if the memory exception comes from an helper */ \
1989     gen_update_nip(ctx, ctx->nip - 4);                                        \
1990     gen_reset_fpstatus();                                                     \
1991     gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_env,                       \
1992                      cpu_fpr[rA(ctx->opcode)],                                \
1993                      cpu_fpr[rC(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);     \
1994     if (isfloat) {                                                            \
1995         gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_env,                    \
1996                         cpu_fpr[rD(ctx->opcode)]);                            \
1997     }                                                                         \
1998     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], set_fprf,                      \
1999                      Rc(ctx->opcode) != 0);                                   \
2000 }
2001
2002 #define GEN_FLOAT_ACB(name, op2, set_fprf, type)                              \
2003 _GEN_FLOAT_ACB(name, name, 0x3F, op2, 0, set_fprf, type);                     \
2004 _GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, set_fprf, type);
2005
2006 #define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
2007 static void gen_f##name(DisasContext *ctx)                                    \
2008 {                                                                             \
2009     if (unlikely(!ctx->fpu_enabled)) {                                        \
2010         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
2011         return;                                                               \
2012     }                                                                         \
2013     /* NIP cannot be restored if the memory exception comes from an helper */ \
2014     gen_update_nip(ctx, ctx->nip - 4);                                        \
2015     gen_reset_fpstatus();                                                     \
2016     gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_env,                       \
2017                      cpu_fpr[rA(ctx->opcode)],                                \
2018                      cpu_fpr[rB(ctx->opcode)]);                               \
2019     if (isfloat) {                                                            \
2020         gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_env,                    \
2021                         cpu_fpr[rD(ctx->opcode)]);                            \
2022     }                                                                         \
2023     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)],                                \
2024                      set_fprf, Rc(ctx->opcode) != 0);                         \
2025 }
2026 #define GEN_FLOAT_AB(name, op2, inval, set_fprf, type)                        \
2027 _GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0, set_fprf, type);               \
2028 _GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1, set_fprf, type);
2029
2030 #define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
2031 static void gen_f##name(DisasContext *ctx)                                    \
2032 {                                                                             \
2033     if (unlikely(!ctx->fpu_enabled)) {                                        \
2034         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
2035         return;                                                               \
2036     }                                                                         \
2037     /* NIP cannot be restored if the memory exception comes from an helper */ \
2038     gen_update_nip(ctx, ctx->nip - 4);                                        \
2039     gen_reset_fpstatus();                                                     \
2040     gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_env,                       \
2041                      cpu_fpr[rA(ctx->opcode)],                                \
2042                      cpu_fpr[rC(ctx->opcode)]);                               \
2043     if (isfloat) {                                                            \
2044         gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_env,                    \
2045                         cpu_fpr[rD(ctx->opcode)]);                            \
2046     }                                                                         \
2047     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)],                                \
2048                      set_fprf, Rc(ctx->opcode) != 0);                         \
2049 }
2050 #define GEN_FLOAT_AC(name, op2, inval, set_fprf, type)                        \
2051 _GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0, set_fprf, type);               \
2052 _GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1, set_fprf, type);
2053
2054 #define GEN_FLOAT_B(name, op2, op3, set_fprf, type)                           \
2055 static void gen_f##name(DisasContext *ctx)                                    \
2056 {                                                                             \
2057     if (unlikely(!ctx->fpu_enabled)) {                                        \
2058         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
2059         return;                                                               \
2060     }                                                                         \
2061     /* NIP cannot be restored if the memory exception comes from an helper */ \
2062     gen_update_nip(ctx, ctx->nip - 4);                                        \
2063     gen_reset_fpstatus();                                                     \
2064     gen_helper_f##name(cpu_fpr[rD(ctx->opcode)], cpu_env,                     \
2065                        cpu_fpr[rB(ctx->opcode)]);                             \
2066     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)],                                \
2067                      set_fprf, Rc(ctx->opcode) != 0);                         \
2068 }
2069
2070 #define GEN_FLOAT_BS(name, op1, op2, set_fprf, type)                          \
2071 static void gen_f##name(DisasContext *ctx)                                    \
2072 {                                                                             \
2073     if (unlikely(!ctx->fpu_enabled)) {                                        \
2074         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
2075         return;                                                               \
2076     }                                                                         \
2077     /* NIP cannot be restored if the memory exception comes from an helper */ \
2078     gen_update_nip(ctx, ctx->nip - 4);                                        \
2079     gen_reset_fpstatus();                                                     \
2080     gen_helper_f##name(cpu_fpr[rD(ctx->opcode)], cpu_env,                     \
2081                        cpu_fpr[rB(ctx->opcode)]);                             \
2082     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)],                                \
2083                      set_fprf, Rc(ctx->opcode) != 0);                         \
2084 }
2085
2086 /* fadd - fadds */
2087 GEN_FLOAT_AB(add, 0x15, 0x000007C0, 1, PPC_FLOAT);
2088 /* fdiv - fdivs */
2089 GEN_FLOAT_AB(div, 0x12, 0x000007C0, 1, PPC_FLOAT);
2090 /* fmul - fmuls */
2091 GEN_FLOAT_AC(mul, 0x19, 0x0000F800, 1, PPC_FLOAT);
2092
2093 /* fre */
2094 GEN_FLOAT_BS(re, 0x3F, 0x18, 1, PPC_FLOAT_EXT);
2095
2096 /* fres */
2097 GEN_FLOAT_BS(res, 0x3B, 0x18, 1, PPC_FLOAT_FRES);
2098
2099 /* frsqrte */
2100 GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A, 1, PPC_FLOAT_FRSQRTE);
2101
2102 /* frsqrtes */
2103 static void gen_frsqrtes(DisasContext *ctx)
2104 {
2105     if (unlikely(!ctx->fpu_enabled)) {
2106         gen_exception(ctx, POWERPC_EXCP_FPU);
2107         return;
2108     }
2109     /* NIP cannot be restored if the memory exception comes from an helper */
2110     gen_update_nip(ctx, ctx->nip - 4);
2111     gen_reset_fpstatus();
2112     gen_helper_frsqrte(cpu_fpr[rD(ctx->opcode)], cpu_env,
2113                        cpu_fpr[rB(ctx->opcode)]);
2114     gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_env,
2115                     cpu_fpr[rD(ctx->opcode)]);
2116     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 1, Rc(ctx->opcode) != 0);
2117 }
2118
2119 /* fsel */
2120 _GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0, 0, PPC_FLOAT_FSEL);
2121 /* fsub - fsubs */
2122 GEN_FLOAT_AB(sub, 0x14, 0x000007C0, 1, PPC_FLOAT);
2123 /* Optional: */
2124
2125 /* fsqrt */
2126 static void gen_fsqrt(DisasContext *ctx)
2127 {
2128     if (unlikely(!ctx->fpu_enabled)) {
2129         gen_exception(ctx, POWERPC_EXCP_FPU);
2130         return;
2131     }
2132     /* NIP cannot be restored if the memory exception comes from an helper */
2133     gen_update_nip(ctx, ctx->nip - 4);
2134     gen_reset_fpstatus();
2135     gen_helper_fsqrt(cpu_fpr[rD(ctx->opcode)], cpu_env,
2136                      cpu_fpr[rB(ctx->opcode)]);
2137     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 1, Rc(ctx->opcode) != 0);
2138 }
2139
2140 static void gen_fsqrts(DisasContext *ctx)
2141 {
2142     if (unlikely(!ctx->fpu_enabled)) {
2143         gen_exception(ctx, POWERPC_EXCP_FPU);
2144         return;
2145     }
2146     /* NIP cannot be restored if the memory exception comes from an helper */
2147     gen_update_nip(ctx, ctx->nip - 4);
2148     gen_reset_fpstatus();
2149     gen_helper_fsqrt(cpu_fpr[rD(ctx->opcode)], cpu_env,
2150                      cpu_fpr[rB(ctx->opcode)]);
2151     gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_env,
2152                     cpu_fpr[rD(ctx->opcode)]);
2153     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 1, Rc(ctx->opcode) != 0);
2154 }
2155
2156 /***                     Floating-Point multiply-and-add                   ***/
2157 /* fmadd - fmadds */
2158 GEN_FLOAT_ACB(madd, 0x1D, 1, PPC_FLOAT);
2159 /* fmsub - fmsubs */
2160 GEN_FLOAT_ACB(msub, 0x1C, 1, PPC_FLOAT);
2161 /* fnmadd - fnmadds */
2162 GEN_FLOAT_ACB(nmadd, 0x1F, 1, PPC_FLOAT);
2163 /* fnmsub - fnmsubs */
2164 GEN_FLOAT_ACB(nmsub, 0x1E, 1, PPC_FLOAT);
2165
2166 /***                     Floating-Point round & convert                    ***/
2167 /* fctiw */
2168 GEN_FLOAT_B(ctiw, 0x0E, 0x00, 0, PPC_FLOAT);
2169 /* fctiwz */
2170 GEN_FLOAT_B(ctiwz, 0x0F, 0x00, 0, PPC_FLOAT);
2171 /* frsp */
2172 GEN_FLOAT_B(rsp, 0x0C, 0x00, 1, PPC_FLOAT);
2173 #if defined(TARGET_PPC64)
2174 /* fcfid */
2175 GEN_FLOAT_B(cfid, 0x0E, 0x1A, 1, PPC_64B);
2176 /* fctid */
2177 GEN_FLOAT_B(ctid, 0x0E, 0x19, 0, PPC_64B);
2178 /* fctidz */
2179 GEN_FLOAT_B(ctidz, 0x0F, 0x19, 0, PPC_64B);
2180 #endif
2181
2182 /* frin */
2183 GEN_FLOAT_B(rin, 0x08, 0x0C, 1, PPC_FLOAT_EXT);
2184 /* friz */
2185 GEN_FLOAT_B(riz, 0x08, 0x0D, 1, PPC_FLOAT_EXT);
2186 /* frip */
2187 GEN_FLOAT_B(rip, 0x08, 0x0E, 1, PPC_FLOAT_EXT);
2188 /* frim */
2189 GEN_FLOAT_B(rim, 0x08, 0x0F, 1, PPC_FLOAT_EXT);
2190
2191 /***                         Floating-Point compare                        ***/
2192
2193 /* fcmpo */
2194 static void gen_fcmpo(DisasContext *ctx)
2195 {
2196     TCGv_i32 crf;
2197     if (unlikely(!ctx->fpu_enabled)) {
2198         gen_exception(ctx, POWERPC_EXCP_FPU);
2199         return;
2200     }
2201     /* NIP cannot be restored if the memory exception comes from an helper */
2202     gen_update_nip(ctx, ctx->nip - 4);
2203     gen_reset_fpstatus();
2204     crf = tcg_const_i32(crfD(ctx->opcode));
2205     gen_helper_fcmpo(cpu_env, cpu_fpr[rA(ctx->opcode)],
2206                      cpu_fpr[rB(ctx->opcode)], crf);
2207     tcg_temp_free_i32(crf);
2208     gen_helper_float_check_status(cpu_env);
2209 }
2210
2211 /* fcmpu */
2212 static void gen_fcmpu(DisasContext *ctx)
2213 {
2214     TCGv_i32 crf;
2215     if (unlikely(!ctx->fpu_enabled)) {
2216         gen_exception(ctx, POWERPC_EXCP_FPU);
2217         return;
2218     }
2219     /* NIP cannot be restored if the memory exception comes from an helper */
2220     gen_update_nip(ctx, ctx->nip - 4);
2221     gen_reset_fpstatus();
2222     crf = tcg_const_i32(crfD(ctx->opcode));
2223     gen_helper_fcmpu(cpu_env, cpu_fpr[rA(ctx->opcode)],
2224                      cpu_fpr[rB(ctx->opcode)], crf);
2225     tcg_temp_free_i32(crf);
2226     gen_helper_float_check_status(cpu_env);
2227 }
2228
2229 /***                         Floating-point move                           ***/
2230 /* fabs */
2231 /* XXX: beware that fabs never checks for NaNs nor update FPSCR */
2232 static void gen_fabs(DisasContext *ctx)
2233 {
2234     if (unlikely(!ctx->fpu_enabled)) {
2235         gen_exception(ctx, POWERPC_EXCP_FPU);
2236         return;
2237     }
2238     tcg_gen_andi_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)],
2239                      ~(1ULL << 63));
2240     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 0, Rc(ctx->opcode) != 0);
2241 }
2242
2243 /* fmr  - fmr. */
2244 /* XXX: beware that fmr never checks for NaNs nor update FPSCR */
2245 static void gen_fmr(DisasContext *ctx)
2246 {
2247     if (unlikely(!ctx->fpu_enabled)) {
2248         gen_exception(ctx, POWERPC_EXCP_FPU);
2249         return;
2250     }
2251     tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
2252     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 0, Rc(ctx->opcode) != 0);
2253 }
2254
2255 /* fnabs */
2256 /* XXX: beware that fnabs never checks for NaNs nor update FPSCR */
2257 static void gen_fnabs(DisasContext *ctx)
2258 {
2259     if (unlikely(!ctx->fpu_enabled)) {
2260         gen_exception(ctx, POWERPC_EXCP_FPU);
2261         return;
2262     }
2263     tcg_gen_ori_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)],
2264                     1ULL << 63);
2265     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 0, Rc(ctx->opcode) != 0);
2266 }
2267
2268 /* fneg */
2269 /* XXX: beware that fneg never checks for NaNs nor update FPSCR */
2270 static void gen_fneg(DisasContext *ctx)
2271 {
2272     if (unlikely(!ctx->fpu_enabled)) {
2273         gen_exception(ctx, POWERPC_EXCP_FPU);
2274         return;
2275     }
2276     tcg_gen_xori_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)],
2277                      1ULL << 63);
2278     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 0, Rc(ctx->opcode) != 0);
2279 }
2280
2281 /* fcpsgn: PowerPC 2.05 specification */
2282 /* XXX: beware that fcpsgn never checks for NaNs nor update FPSCR */
2283 static void gen_fcpsgn(DisasContext *ctx)
2284 {
2285     if (unlikely(!ctx->fpu_enabled)) {
2286         gen_exception(ctx, POWERPC_EXCP_FPU);
2287         return;
2288     }
2289     tcg_gen_deposit_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rA(ctx->opcode)],
2290                         cpu_fpr[rB(ctx->opcode)], 0, 63);
2291     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 0, Rc(ctx->opcode) != 0);
2292 }
2293
2294 /***                  Floating-Point status & ctrl register                ***/
2295
2296 /* mcrfs */
2297 static void gen_mcrfs(DisasContext *ctx)
2298 {
2299     TCGv tmp = tcg_temp_new();
2300     int bfa;
2301
2302     if (unlikely(!ctx->fpu_enabled)) {
2303         gen_exception(ctx, POWERPC_EXCP_FPU);
2304         return;
2305     }
2306     bfa = 4 * (7 - crfS(ctx->opcode));
2307     tcg_gen_shri_tl(tmp, cpu_fpscr, bfa);
2308     tcg_gen_trunc_tl_i32(cpu_crf[crfD(ctx->opcode)], tmp);
2309     tcg_temp_free(tmp);
2310     tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], 0xf);
2311     tcg_gen_andi_tl(cpu_fpscr, cpu_fpscr, ~(0xF << bfa));
2312 }
2313
2314 /* mffs */
2315 static void gen_mffs(DisasContext *ctx)
2316 {
2317     if (unlikely(!ctx->fpu_enabled)) {
2318         gen_exception(ctx, POWERPC_EXCP_FPU);
2319         return;
2320     }
2321     gen_reset_fpstatus();
2322     tcg_gen_extu_tl_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpscr);
2323     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 0, Rc(ctx->opcode) != 0);
2324 }
2325
2326 /* mtfsb0 */
2327 static void gen_mtfsb0(DisasContext *ctx)
2328 {
2329     uint8_t crb;
2330
2331     if (unlikely(!ctx->fpu_enabled)) {
2332         gen_exception(ctx, POWERPC_EXCP_FPU);
2333         return;
2334     }
2335     crb = 31 - crbD(ctx->opcode);
2336     gen_reset_fpstatus();
2337     if (likely(crb != FPSCR_FEX && crb != FPSCR_VX)) {
2338         TCGv_i32 t0;
2339         /* NIP cannot be restored if the memory exception comes from an helper */
2340         gen_update_nip(ctx, ctx->nip - 4);
2341         t0 = tcg_const_i32(crb);
2342         gen_helper_fpscr_clrbit(cpu_env, t0);
2343         tcg_temp_free_i32(t0);
2344     }
2345     if (unlikely(Rc(ctx->opcode) != 0)) {
2346         tcg_gen_trunc_tl_i32(cpu_crf[1], cpu_fpscr);
2347         tcg_gen_shri_i32(cpu_crf[1], cpu_crf[1], FPSCR_OX);
2348     }
2349 }
2350
2351 /* mtfsb1 */
2352 static void gen_mtfsb1(DisasContext *ctx)
2353 {
2354     uint8_t crb;
2355
2356     if (unlikely(!ctx->fpu_enabled)) {
2357         gen_exception(ctx, POWERPC_EXCP_FPU);
2358         return;
2359     }
2360     crb = 31 - crbD(ctx->opcode);
2361     gen_reset_fpstatus();
2362     /* XXX: we pretend we can only do IEEE floating-point computations */
2363     if (likely(crb != FPSCR_FEX && crb != FPSCR_VX && crb != FPSCR_NI)) {
2364         TCGv_i32 t0;
2365         /* NIP cannot be restored if the memory exception comes from an helper */
2366         gen_update_nip(ctx, ctx->nip - 4);
2367         t0 = tcg_const_i32(crb);
2368         gen_helper_fpscr_setbit(cpu_env, t0);
2369         tcg_temp_free_i32(t0);
2370     }
2371     if (unlikely(Rc(ctx->opcode) != 0)) {
2372         tcg_gen_trunc_tl_i32(cpu_crf[1], cpu_fpscr);
2373         tcg_gen_shri_i32(cpu_crf[1], cpu_crf[1], FPSCR_OX);
2374     }
2375     /* We can raise a differed exception */
2376     gen_helper_float_check_status(cpu_env);
2377 }
2378
2379 /* mtfsf */
2380 static void gen_mtfsf(DisasContext *ctx)
2381 {
2382     TCGv_i32 t0;
2383     int flm, l, w;
2384
2385     if (unlikely(!ctx->fpu_enabled)) {
2386         gen_exception(ctx, POWERPC_EXCP_FPU);
2387         return;
2388     }
2389     flm = FPFLM(ctx->opcode);
2390     l = FPL(ctx->opcode);
2391     w = FPW(ctx->opcode);
2392     if (unlikely(w & !(ctx->insns_flags2 & PPC2_ISA205))) {
2393         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
2394         return;
2395     }
2396     /* NIP cannot be restored if the memory exception comes from an helper */
2397     gen_update_nip(ctx, ctx->nip - 4);
2398     gen_reset_fpstatus();
2399     if (l) {
2400         t0 = tcg_const_i32((ctx->insns_flags2 & PPC2_ISA205) ? 0xffff : 0xff);
2401     } else {
2402         t0 = tcg_const_i32(flm << (w * 8));
2403     }
2404     gen_helper_store_fpscr(cpu_env, cpu_fpr[rB(ctx->opcode)], t0);
2405     tcg_temp_free_i32(t0);
2406     if (unlikely(Rc(ctx->opcode) != 0)) {
2407         tcg_gen_trunc_tl_i32(cpu_crf[1], cpu_fpscr);
2408         tcg_gen_shri_i32(cpu_crf[1], cpu_crf[1], FPSCR_OX);
2409     }
2410     /* We can raise a differed exception */
2411     gen_helper_float_check_status(cpu_env);
2412 }
2413
2414 /* mtfsfi */
2415 static void gen_mtfsfi(DisasContext *ctx)
2416 {
2417     int bf, sh, w;
2418     TCGv_i64 t0;
2419     TCGv_i32 t1;
2420
2421     if (unlikely(!ctx->fpu_enabled)) {
2422         gen_exception(ctx, POWERPC_EXCP_FPU);
2423         return;
2424     }
2425     w = FPW(ctx->opcode);
2426     bf = FPBF(ctx->opcode);
2427     if (unlikely(w & !(ctx->insns_flags2 & PPC2_ISA205))) {
2428         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
2429         return;
2430     }
2431     sh = (8 * w) + 7 - bf;
2432     /* NIP cannot be restored if the memory exception comes from an helper */
2433     gen_update_nip(ctx, ctx->nip - 4);
2434     gen_reset_fpstatus();
2435     t0 = tcg_const_i64(((uint64_t)FPIMM(ctx->opcode)) << (4 * sh));
2436     t1 = tcg_const_i32(1 << sh);
2437     gen_helper_store_fpscr(cpu_env, t0, t1);
2438     tcg_temp_free_i64(t0);
2439     tcg_temp_free_i32(t1);
2440     if (unlikely(Rc(ctx->opcode) != 0)) {
2441         tcg_gen_trunc_tl_i32(cpu_crf[1], cpu_fpscr);
2442         tcg_gen_shri_i32(cpu_crf[1], cpu_crf[1], FPSCR_OX);
2443     }
2444     /* We can raise a differed exception */
2445     gen_helper_float_check_status(cpu_env);
2446 }
2447
2448 /***                           Addressing modes                            ***/
2449 /* Register indirect with immediate index : EA = (rA|0) + SIMM */
2450 static inline void gen_addr_imm_index(DisasContext *ctx, TCGv EA,
2451                                       target_long maskl)
2452 {
2453     target_long simm = SIMM(ctx->opcode);
2454
2455     simm &= ~maskl;
2456     if (rA(ctx->opcode) == 0) {
2457         if (NARROW_MODE(ctx)) {
2458             simm = (uint32_t)simm;
2459         }
2460         tcg_gen_movi_tl(EA, simm);
2461     } else if (likely(simm != 0)) {
2462         tcg_gen_addi_tl(EA, cpu_gpr[rA(ctx->opcode)], simm);
2463         if (NARROW_MODE(ctx)) {
2464             tcg_gen_ext32u_tl(EA, EA);
2465         }
2466     } else {
2467         if (NARROW_MODE(ctx)) {
2468             tcg_gen_ext32u_tl(EA, cpu_gpr[rA(ctx->opcode)]);
2469         } else {
2470             tcg_gen_mov_tl(EA, cpu_gpr[rA(ctx->opcode)]);
2471         }
2472     }
2473 }
2474
2475 static inline void gen_addr_reg_index(DisasContext *ctx, TCGv EA)
2476 {
2477     if (rA(ctx->opcode) == 0) {
2478         if (NARROW_MODE(ctx)) {
2479             tcg_gen_ext32u_tl(EA, cpu_gpr[rB(ctx->opcode)]);
2480         } else {
2481             tcg_gen_mov_tl(EA, cpu_gpr[rB(ctx->opcode)]);
2482         }
2483     } else {
2484         tcg_gen_add_tl(EA, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
2485         if (NARROW_MODE(ctx)) {
2486             tcg_gen_ext32u_tl(EA, EA);
2487         }
2488     }
2489 }
2490
2491 static inline void gen_addr_register(DisasContext *ctx, TCGv EA)
2492 {
2493     if (rA(ctx->opcode) == 0) {
2494         tcg_gen_movi_tl(EA, 0);
2495     } else if (NARROW_MODE(ctx)) {
2496         tcg_gen_ext32u_tl(EA, cpu_gpr[rA(ctx->opcode)]);
2497     } else {
2498         tcg_gen_mov_tl(EA, cpu_gpr[rA(ctx->opcode)]);
2499     }
2500 }
2501
2502 static inline void gen_addr_add(DisasContext *ctx, TCGv ret, TCGv arg1,
2503                                 target_long val)
2504 {
2505     tcg_gen_addi_tl(ret, arg1, val);
2506     if (NARROW_MODE(ctx)) {
2507         tcg_gen_ext32u_tl(ret, ret);
2508     }
2509 }
2510
2511 static inline void gen_check_align(DisasContext *ctx, TCGv EA, int mask)
2512 {
2513     int l1 = gen_new_label();
2514     TCGv t0 = tcg_temp_new();
2515     TCGv_i32 t1, t2;
2516     /* NIP cannot be restored if the memory exception comes from an helper */
2517     gen_update_nip(ctx, ctx->nip - 4);
2518     tcg_gen_andi_tl(t0, EA, mask);
2519     tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
2520     t1 = tcg_const_i32(POWERPC_EXCP_ALIGN);
2521     t2 = tcg_const_i32(0);
2522     gen_helper_raise_exception_err(cpu_env, t1, t2);
2523     tcg_temp_free_i32(t1);
2524     tcg_temp_free_i32(t2);
2525     gen_set_label(l1);
2526     tcg_temp_free(t0);
2527 }
2528
2529 /***                             Integer load                              ***/
2530 static inline void gen_qemu_ld8u(DisasContext *ctx, TCGv arg1, TCGv arg2)
2531 {
2532     tcg_gen_qemu_ld8u(arg1, arg2, ctx->mem_idx);
2533 }
2534
2535 static inline void gen_qemu_ld8s(DisasContext *ctx, TCGv arg1, TCGv arg2)
2536 {
2537     tcg_gen_qemu_ld8s(arg1, arg2, ctx->mem_idx);
2538 }
2539
2540 static inline void gen_qemu_ld16u(DisasContext *ctx, TCGv arg1, TCGv arg2)
2541 {
2542     tcg_gen_qemu_ld16u(arg1, arg2, ctx->mem_idx);
2543     if (unlikely(ctx->le_mode)) {
2544         tcg_gen_bswap16_tl(arg1, arg1);
2545     }
2546 }
2547
2548 static inline void gen_qemu_ld16s(DisasContext *ctx, TCGv arg1, TCGv arg2)
2549 {
2550     if (unlikely(ctx->le_mode)) {
2551         tcg_gen_qemu_ld16u(arg1, arg2, ctx->mem_idx);
2552         tcg_gen_bswap16_tl(arg1, arg1);
2553         tcg_gen_ext16s_tl(arg1, arg1);
2554     } else {
2555         tcg_gen_qemu_ld16s(arg1, arg2, ctx->mem_idx);
2556     }
2557 }
2558
2559 static inline void gen_qemu_ld32u(DisasContext *ctx, TCGv arg1, TCGv arg2)
2560 {
2561     tcg_gen_qemu_ld32u(arg1, arg2, ctx->mem_idx);
2562     if (unlikely(ctx->le_mode)) {
2563         tcg_gen_bswap32_tl(arg1, arg1);
2564     }
2565 }
2566
2567 static inline void gen_qemu_ld32s(DisasContext *ctx, TCGv arg1, TCGv arg2)
2568 {
2569     if (unlikely(ctx->le_mode)) {
2570         tcg_gen_qemu_ld32u(arg1, arg2, ctx->mem_idx);
2571         tcg_gen_bswap32_tl(arg1, arg1);
2572         tcg_gen_ext32s_tl(arg1, arg1);
2573     } else
2574         tcg_gen_qemu_ld32s(arg1, arg2, ctx->mem_idx);
2575 }
2576
2577 static inline void gen_qemu_ld64(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
2578 {
2579     tcg_gen_qemu_ld64(arg1, arg2, ctx->mem_idx);
2580     if (unlikely(ctx->le_mode)) {
2581         tcg_gen_bswap64_i64(arg1, arg1);
2582     }
2583 }
2584
2585 static inline void gen_qemu_st8(DisasContext *ctx, TCGv arg1, TCGv arg2)
2586 {
2587     tcg_gen_qemu_st8(arg1, arg2, ctx->mem_idx);
2588 }
2589
2590 static inline void gen_qemu_st16(DisasContext *ctx, TCGv arg1, TCGv arg2)
2591 {
2592     if (unlikely(ctx->le_mode)) {
2593         TCGv t0 = tcg_temp_new();
2594         tcg_gen_ext16u_tl(t0, arg1);
2595         tcg_gen_bswap16_tl(t0, t0);
2596         tcg_gen_qemu_st16(t0, arg2, ctx->mem_idx);
2597         tcg_temp_free(t0);
2598     } else {
2599         tcg_gen_qemu_st16(arg1, arg2, ctx->mem_idx);
2600     }
2601 }
2602
2603 static inline void gen_qemu_st32(DisasContext *ctx, TCGv arg1, TCGv arg2)
2604 {
2605     if (unlikely(ctx->le_mode)) {
2606         TCGv t0 = tcg_temp_new();
2607         tcg_gen_ext32u_tl(t0, arg1);
2608         tcg_gen_bswap32_tl(t0, t0);
2609         tcg_gen_qemu_st32(t0, arg2, ctx->mem_idx);
2610         tcg_temp_free(t0);
2611     } else {
2612         tcg_gen_qemu_st32(arg1, arg2, ctx->mem_idx);
2613     }
2614 }
2615
2616 static inline void gen_qemu_st64(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
2617 {
2618     if (unlikely(ctx->le_mode)) {
2619         TCGv_i64 t0 = tcg_temp_new_i64();
2620         tcg_gen_bswap64_i64(t0, arg1);
2621         tcg_gen_qemu_st64(t0, arg2, ctx->mem_idx);
2622         tcg_temp_free_i64(t0);
2623     } else
2624         tcg_gen_qemu_st64(arg1, arg2, ctx->mem_idx);
2625 }
2626
2627 #define GEN_LD(name, ldop, opc, type)                                         \
2628 static void glue(gen_, name)(DisasContext *ctx)                                       \
2629 {                                                                             \
2630     TCGv EA;                                                                  \
2631     gen_set_access_type(ctx, ACCESS_INT);                                     \
2632     EA = tcg_temp_new();                                                      \
2633     gen_addr_imm_index(ctx, EA, 0);                                           \
2634     gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA);                       \
2635     tcg_temp_free(EA);                                                        \
2636 }
2637
2638 #define GEN_LDU(name, ldop, opc, type)                                        \
2639 static void glue(gen_, name##u)(DisasContext *ctx)                                    \
2640 {                                                                             \
2641     TCGv EA;                                                                  \
2642     if (unlikely(rA(ctx->opcode) == 0 ||                                      \
2643                  rA(ctx->opcode) == rD(ctx->opcode))) {                       \
2644         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
2645         return;                                                               \
2646     }                                                                         \
2647     gen_set_access_type(ctx, ACCESS_INT);                                     \
2648     EA = tcg_temp_new();                                                      \
2649     if (type == PPC_64B)                                                      \
2650         gen_addr_imm_index(ctx, EA, 0x03);                                    \
2651     else                                                                      \
2652         gen_addr_imm_index(ctx, EA, 0);                                       \
2653     gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA);                       \
2654     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
2655     tcg_temp_free(EA);                                                        \
2656 }
2657
2658 #define GEN_LDUX(name, ldop, opc2, opc3, type)                                \
2659 static void glue(gen_, name##ux)(DisasContext *ctx)                                   \
2660 {                                                                             \
2661     TCGv EA;                                                                  \
2662     if (unlikely(rA(ctx->opcode) == 0 ||                                      \
2663                  rA(ctx->opcode) == rD(ctx->opcode))) {                       \
2664         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
2665         return;                                                               \
2666     }                                                                         \
2667     gen_set_access_type(ctx, ACCESS_INT);                                     \
2668     EA = tcg_temp_new();                                                      \
2669     gen_addr_reg_index(ctx, EA);                                              \
2670     gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA);                       \
2671     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
2672     tcg_temp_free(EA);                                                        \
2673 }
2674
2675 #define GEN_LDX_E(name, ldop, opc2, opc3, type, type2)                        \
2676 static void glue(gen_, name##x)(DisasContext *ctx)                            \
2677 {                                                                             \
2678     TCGv EA;                                                                  \
2679     gen_set_access_type(ctx, ACCESS_INT);                                     \
2680     EA = tcg_temp_new();                                                      \
2681     gen_addr_reg_index(ctx, EA);                                              \
2682     gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA);                       \
2683     tcg_temp_free(EA);                                                        \
2684 }
2685 #define GEN_LDX(name, ldop, opc2, opc3, type)                                 \
2686     GEN_LDX_E(name, ldop, opc2, opc3, type, PPC_NONE)
2687
2688 #define GEN_LDS(name, ldop, op, type)                                         \
2689 GEN_LD(name, ldop, op | 0x20, type);                                          \
2690 GEN_LDU(name, ldop, op | 0x21, type);                                         \
2691 GEN_LDUX(name, ldop, 0x17, op | 0x01, type);                                  \
2692 GEN_LDX(name, ldop, 0x17, op | 0x00, type)
2693
2694 /* lbz lbzu lbzux lbzx */
2695 GEN_LDS(lbz, ld8u, 0x02, PPC_INTEGER);
2696 /* lha lhau lhaux lhax */
2697 GEN_LDS(lha, ld16s, 0x0A, PPC_INTEGER);
2698 /* lhz lhzu lhzux lhzx */
2699 GEN_LDS(lhz, ld16u, 0x08, PPC_INTEGER);
2700 /* lwz lwzu lwzux lwzx */
2701 GEN_LDS(lwz, ld32u, 0x00, PPC_INTEGER);
2702 #if defined(TARGET_PPC64)
2703 /* lwaux */
2704 GEN_LDUX(lwa, ld32s, 0x15, 0x0B, PPC_64B);
2705 /* lwax */
2706 GEN_LDX(lwa, ld32s, 0x15, 0x0A, PPC_64B);
2707 /* ldux */
2708 GEN_LDUX(ld, ld64, 0x15, 0x01, PPC_64B);
2709 /* ldx */
2710 GEN_LDX(ld, ld64, 0x15, 0x00, PPC_64B);
2711
2712 static void gen_ld(DisasContext *ctx)
2713 {
2714     TCGv EA;
2715     if (Rc(ctx->opcode)) {
2716         if (unlikely(rA(ctx->opcode) == 0 ||
2717                      rA(ctx->opcode) == rD(ctx->opcode))) {
2718             gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
2719             return;
2720         }
2721     }
2722     gen_set_access_type(ctx, ACCESS_INT);
2723     EA = tcg_temp_new();
2724     gen_addr_imm_index(ctx, EA, 0x03);
2725     if (ctx->opcode & 0x02) {
2726         /* lwa (lwau is undefined) */
2727         gen_qemu_ld32s(ctx, cpu_gpr[rD(ctx->opcode)], EA);
2728     } else {
2729         /* ld - ldu */
2730         gen_qemu_ld64(ctx, cpu_gpr[rD(ctx->opcode)], EA);
2731     }
2732     if (Rc(ctx->opcode))
2733         tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);
2734     tcg_temp_free(EA);
2735 }
2736
2737 /* lq */
2738 static void gen_lq(DisasContext *ctx)
2739 {
2740 #if defined(CONFIG_USER_ONLY)
2741     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
2742 #else
2743     int ra, rd;
2744     TCGv EA;
2745
2746     /* Restore CPU state */
2747     if (unlikely(ctx->mem_idx == 0)) {
2748         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
2749         return;
2750     }
2751     ra = rA(ctx->opcode);
2752     rd = rD(ctx->opcode);
2753     if (unlikely((rd & 1) || rd == ra)) {
2754         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
2755         return;
2756     }
2757     if (unlikely(ctx->le_mode)) {
2758         /* Little-endian mode is not handled */
2759         gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
2760         return;
2761     }
2762     gen_set_access_type(ctx, ACCESS_INT);
2763     EA = tcg_temp_new();
2764     gen_addr_imm_index(ctx, EA, 0x0F);
2765     gen_qemu_ld64(ctx, cpu_gpr[rd], EA);
2766     gen_addr_add(ctx, EA, EA, 8);
2767     gen_qemu_ld64(ctx, cpu_gpr[rd+1], EA);
2768     tcg_temp_free(EA);
2769 #endif
2770 }
2771 #endif
2772
2773 /***                              Integer store                            ***/
2774 #define GEN_ST(name, stop, opc, type)                                         \
2775 static void glue(gen_, name)(DisasContext *ctx)                                       \
2776 {                                                                             \
2777     TCGv EA;                                                                  \
2778     gen_set_access_type(ctx, ACCESS_INT);                                     \
2779     EA = tcg_temp_new();                                                      \
2780     gen_addr_imm_index(ctx, EA, 0);                                           \
2781     gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA);                       \
2782     tcg_temp_free(EA);                                                        \
2783 }
2784
2785 #define GEN_STU(name, stop, opc, type)                                        \
2786 static void glue(gen_, stop##u)(DisasContext *ctx)                                    \
2787 {                                                                             \
2788     TCGv EA;                                                                  \
2789     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2790         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
2791         return;                                                               \
2792     }                                                                         \
2793     gen_set_access_type(ctx, ACCESS_INT);                                     \
2794     EA = tcg_temp_new();                                                      \
2795     if (type == PPC_64B)                                                      \
2796         gen_addr_imm_index(ctx, EA, 0x03);                                    \
2797     else                                                                      \
2798         gen_addr_imm_index(ctx, EA, 0);                                       \
2799     gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA);                       \
2800     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
2801     tcg_temp_free(EA);                                                        \
2802 }
2803
2804 #define GEN_STUX(name, stop, opc2, opc3, type)                                \
2805 static void glue(gen_, name##ux)(DisasContext *ctx)                                   \
2806 {                                                                             \
2807     TCGv EA;                                                                  \
2808     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2809         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
2810         return;                                                               \
2811     }                                                                         \
2812     gen_set_access_type(ctx, ACCESS_INT);                                     \
2813     EA = tcg_temp_new();                                                      \
2814     gen_addr_reg_index(ctx, EA);                                              \
2815     gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA);                       \
2816     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
2817     tcg_temp_free(EA);                                                        \
2818 }
2819
2820 #define GEN_STX_E(name, stop, opc2, opc3, type, type2)                        \
2821 static void glue(gen_, name##x)(DisasContext *ctx)                            \
2822 {                                                                             \
2823     TCGv EA;                                                                  \
2824     gen_set_access_type(ctx, ACCESS_INT);                                     \
2825     EA = tcg_temp_new();                                                      \
2826     gen_addr_reg_index(ctx, EA);                                              \
2827     gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA);                       \
2828     tcg_temp_free(EA);                                                        \
2829 }
2830 #define GEN_STX(name, stop, opc2, opc3, type)                                 \
2831     GEN_STX_E(name, stop, opc2, opc3, type, PPC_NONE)
2832
2833 #define GEN_STS(name, stop, op, type)                                         \
2834 GEN_ST(name, stop, op | 0x20, type);                                          \
2835 GEN_STU(name, stop, op | 0x21, type);                                         \
2836 GEN_STUX(name, stop, 0x17, op | 0x01, type);                                  \
2837 GEN_STX(name, stop, 0x17, op | 0x00, type)
2838
2839 /* stb stbu stbux stbx */
2840 GEN_STS(stb, st8, 0x06, PPC_INTEGER);
2841 /* sth sthu sthux sthx */
2842 GEN_STS(sth, st16, 0x0C, PPC_INTEGER);
2843 /* stw stwu stwux stwx */
2844 GEN_STS(stw, st32, 0x04, PPC_INTEGER);
2845 #if defined(TARGET_PPC64)
2846 GEN_STUX(std, st64, 0x15, 0x05, PPC_64B);
2847 GEN_STX(std, st64, 0x15, 0x04, PPC_64B);
2848
2849 static void gen_std(DisasContext *ctx)
2850 {
2851     int rs;
2852     TCGv EA;
2853
2854     rs = rS(ctx->opcode);
2855     if ((ctx->opcode & 0x3) == 0x2) {
2856 #if defined(CONFIG_USER_ONLY)
2857         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
2858 #else
2859         /* stq */
2860         if (unlikely(ctx->mem_idx == 0)) {
2861             gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
2862             return;
2863         }
2864         if (unlikely(rs & 1)) {
2865             gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
2866             return;
2867         }
2868         if (unlikely(ctx->le_mode)) {
2869             /* Little-endian mode is not handled */
2870             gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
2871             return;
2872         }
2873         gen_set_access_type(ctx, ACCESS_INT);
2874         EA = tcg_temp_new();
2875         gen_addr_imm_index(ctx, EA, 0x03);
2876         gen_qemu_st64(ctx, cpu_gpr[rs], EA);
2877         gen_addr_add(ctx, EA, EA, 8);
2878         gen_qemu_st64(ctx, cpu_gpr[rs+1], EA);
2879         tcg_temp_free(EA);
2880 #endif
2881     } else {
2882         /* std / stdu */
2883         if (Rc(ctx->opcode)) {
2884             if (unlikely(rA(ctx->opcode) == 0)) {
2885                 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
2886                 return;
2887             }
2888         }
2889         gen_set_access_type(ctx, ACCESS_INT);
2890         EA = tcg_temp_new();
2891         gen_addr_imm_index(ctx, EA, 0x03);
2892         gen_qemu_st64(ctx, cpu_gpr[rs], EA);
2893         if (Rc(ctx->opcode))
2894             tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);
2895         tcg_temp_free(EA);
2896     }
2897 }
2898 #endif
2899 /***                Integer load and store with byte reverse               ***/
2900 /* lhbrx */
2901 static inline void gen_qemu_ld16ur(DisasContext *ctx, TCGv arg1, TCGv arg2)
2902 {
2903     tcg_gen_qemu_ld16u(arg1, arg2, ctx->mem_idx);
2904     if (likely(!ctx->le_mode)) {
2905         tcg_gen_bswap16_tl(arg1, arg1);
2906     }
2907 }
2908 GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER);
2909
2910 /* lwbrx */
2911 static inline void gen_qemu_ld32ur(DisasContext *ctx, TCGv arg1, TCGv arg2)
2912 {
2913     tcg_gen_qemu_ld32u(arg1, arg2, ctx->mem_idx);
2914     if (likely(!ctx->le_mode)) {
2915         tcg_gen_bswap32_tl(arg1, arg1);
2916     }
2917 }
2918 GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER);
2919
2920 #if defined(TARGET_PPC64)
2921 /* ldbrx */
2922 static inline void gen_qemu_ld64ur(DisasContext *ctx, TCGv arg1, TCGv arg2)
2923 {
2924     tcg_gen_qemu_ld64(arg1, arg2, ctx->mem_idx);
2925     if (likely(!ctx->le_mode)) {
2926         tcg_gen_bswap64_tl(arg1, arg1);
2927     }
2928 }
2929 GEN_LDX_E(ldbr, ld64ur, 0x14, 0x10, PPC_NONE, PPC2_DBRX);
2930 #endif  /* TARGET_PPC64 */
2931
2932 /* sthbrx */
2933 static inline void gen_qemu_st16r(DisasContext *ctx, TCGv arg1, TCGv arg2)
2934 {
2935     if (likely(!ctx->le_mode)) {
2936         TCGv t0 = tcg_temp_new();
2937         tcg_gen_ext16u_tl(t0, arg1);
2938         tcg_gen_bswap16_tl(t0, t0);
2939         tcg_gen_qemu_st16(t0, arg2, ctx->mem_idx);
2940         tcg_temp_free(t0);
2941     } else {
2942         tcg_gen_qemu_st16(arg1, arg2, ctx->mem_idx);
2943     }
2944 }
2945 GEN_STX(sthbr, st16r, 0x16, 0x1C, PPC_INTEGER);
2946
2947 /* stwbrx */
2948 static inline void gen_qemu_st32r(DisasContext *ctx, TCGv arg1, TCGv arg2)
2949 {
2950     if (likely(!ctx->le_mode)) {
2951         TCGv t0 = tcg_temp_new();
2952         tcg_gen_ext32u_tl(t0, arg1);
2953         tcg_gen_bswap32_tl(t0, t0);
2954         tcg_gen_qemu_st32(t0, arg2, ctx->mem_idx);
2955         tcg_temp_free(t0);
2956     } else {
2957         tcg_gen_qemu_st32(arg1, arg2, ctx->mem_idx);
2958     }
2959 }
2960 GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER);
2961
2962 #if defined(TARGET_PPC64)
2963 /* stdbrx */
2964 static inline void gen_qemu_st64r(DisasContext *ctx, TCGv arg1, TCGv arg2)
2965 {
2966     if (likely(!ctx->le_mode)) {
2967         TCGv t0 = tcg_temp_new();
2968         tcg_gen_bswap64_tl(t0, arg1);
2969         tcg_gen_qemu_st64(t0, arg2, ctx->mem_idx);
2970         tcg_temp_free(t0);
2971     } else {
2972         tcg_gen_qemu_st64(arg1, arg2, ctx->mem_idx);
2973     }
2974 }
2975 GEN_STX_E(stdbr, st64r, 0x14, 0x14, PPC_NONE, PPC2_DBRX);
2976 #endif  /* TARGET_PPC64 */
2977
2978 /***                    Integer load and store multiple                    ***/
2979
2980 /* lmw */
2981 static void gen_lmw(DisasContext *ctx)
2982 {
2983     TCGv t0;
2984     TCGv_i32 t1;
2985     gen_set_access_type(ctx, ACCESS_INT);
2986     /* NIP cannot be restored if the memory exception comes from an helper */
2987     gen_update_nip(ctx, ctx->nip - 4);
2988     t0 = tcg_temp_new();
2989     t1 = tcg_const_i32(rD(ctx->opcode));
2990     gen_addr_imm_index(ctx, t0, 0);
2991     gen_helper_lmw(cpu_env, t0, t1);
2992     tcg_temp_free(t0);
2993     tcg_temp_free_i32(t1);
2994 }
2995
2996 /* stmw */
2997 static void gen_stmw(DisasContext *ctx)
2998 {
2999     TCGv t0;
3000     TCGv_i32 t1;
3001     gen_set_access_type(ctx, ACCESS_INT);
3002     /* NIP cannot be restored if the memory exception comes from an helper */
3003     gen_update_nip(ctx, ctx->nip - 4);
3004     t0 = tcg_temp_new();
3005     t1 = tcg_const_i32(rS(ctx->opcode));
3006     gen_addr_imm_index(ctx, t0, 0);
3007     gen_helper_stmw(cpu_env, t0, t1);
3008     tcg_temp_free(t0);
3009     tcg_temp_free_i32(t1);
3010 }
3011
3012 /***                    Integer load and store strings                     ***/
3013
3014 /* lswi */
3015 /* PowerPC32 specification says we must generate an exception if
3016  * rA is in the range of registers to be loaded.
3017  * In an other hand, IBM says this is valid, but rA won't be loaded.
3018  * For now, I'll follow the spec...
3019  */
3020 static void gen_lswi(DisasContext *ctx)
3021 {
3022     TCGv t0;
3023     TCGv_i32 t1, t2;
3024     int nb = NB(ctx->opcode);
3025     int start = rD(ctx->opcode);
3026     int ra = rA(ctx->opcode);
3027     int nr;
3028
3029     if (nb == 0)
3030         nb = 32;
3031     nr = nb / 4;
3032     if (unlikely(((start + nr) > 32  &&
3033                   start <= ra && (start + nr - 32) > ra) ||
3034                  ((start + nr) <= 32 && start <= ra && (start + nr) > ra))) {
3035         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_LSWX);
3036         return;
3037     }
3038     gen_set_access_type(ctx, ACCESS_INT);
3039     /* NIP cannot be restored if the memory exception comes from an helper */
3040     gen_update_nip(ctx, ctx->nip - 4);
3041     t0 = tcg_temp_new();
3042     gen_addr_register(ctx, t0);
3043     t1 = tcg_const_i32(nb);
3044     t2 = tcg_const_i32(start);
3045     gen_helper_lsw(cpu_env, t0, t1, t2);
3046     tcg_temp_free(t0);
3047     tcg_temp_free_i32(t1);
3048     tcg_temp_free_i32(t2);
3049 }
3050
3051 /* lswx */
3052 static void gen_lswx(DisasContext *ctx)
3053 {
3054     TCGv t0;
3055     TCGv_i32 t1, t2, t3;
3056     gen_set_access_type(ctx, ACCESS_INT);
3057     /* NIP cannot be restored if the memory exception comes from an helper */
3058     gen_update_nip(ctx, ctx->nip - 4);
3059     t0 = tcg_temp_new();
3060     gen_addr_reg_index(ctx, t0);
3061     t1 = tcg_const_i32(rD(ctx->opcode));
3062     t2 = tcg_const_i32(rA(ctx->opcode));
3063     t3 = tcg_const_i32(rB(ctx->opcode));
3064     gen_helper_lswx(cpu_env, t0, t1, t2, t3);
3065     tcg_temp_free(t0);
3066     tcg_temp_free_i32(t1);
3067     tcg_temp_free_i32(t2);
3068     tcg_temp_free_i32(t3);
3069 }
3070
3071 /* stswi */
3072 static void gen_stswi(DisasContext *ctx)
3073 {
3074     TCGv t0;
3075     TCGv_i32 t1, t2;
3076     int nb = NB(ctx->opcode);
3077     gen_set_access_type(ctx, ACCESS_INT);
3078     /* NIP cannot be restored if the memory exception comes from an helper */
3079     gen_update_nip(ctx, ctx->nip - 4);
3080     t0 = tcg_temp_new();
3081     gen_addr_register(ctx, t0);
3082     if (nb == 0)
3083         nb = 32;
3084     t1 = tcg_const_i32(nb);
3085     t2 = tcg_const_i32(rS(ctx->opcode));
3086     gen_helper_stsw(cpu_env, t0, t1, t2);
3087     tcg_temp_free(t0);
3088     tcg_temp_free_i32(t1);
3089     tcg_temp_free_i32(t2);
3090 }
3091
3092 /* stswx */
3093 static void gen_stswx(DisasContext *ctx)
3094 {
3095     TCGv t0;
3096     TCGv_i32 t1, t2;
3097     gen_set_access_type(ctx, ACCESS_INT);
3098     /* NIP cannot be restored if the memory exception comes from an helper */
3099     gen_update_nip(ctx, ctx->nip - 4);
3100     t0 = tcg_temp_new();
3101     gen_addr_reg_index(ctx, t0);
3102     t1 = tcg_temp_new_i32();
3103     tcg_gen_trunc_tl_i32(t1, cpu_xer);
3104     tcg_gen_andi_i32(t1, t1, 0x7F);
3105     t2 = tcg_const_i32(rS(ctx->opcode));
3106     gen_helper_stsw(cpu_env, t0, t1, t2);
3107     tcg_temp_free(t0);
3108     tcg_temp_free_i32(t1);
3109     tcg_temp_free_i32(t2);
3110 }
3111
3112 /***                        Memory synchronisation                         ***/
3113 /* eieio */
3114 static void gen_eieio(DisasContext *ctx)
3115 {
3116 }
3117
3118 /* isync */
3119 static void gen_isync(DisasContext *ctx)
3120 {
3121     gen_stop_exception(ctx);
3122 }
3123
3124 /* lwarx */
3125 static void gen_lwarx(DisasContext *ctx)
3126 {
3127     TCGv t0;
3128     TCGv gpr = cpu_gpr[rD(ctx->opcode)];
3129     gen_set_access_type(ctx, ACCESS_RES);
3130     t0 = tcg_temp_local_new();
3131     gen_addr_reg_index(ctx, t0);
3132     gen_check_align(ctx, t0, 0x03);
3133     gen_qemu_ld32u(ctx, gpr, t0);
3134     tcg_gen_mov_tl(cpu_reserve, t0);
3135     tcg_gen_st_tl(gpr, cpu_env, offsetof(CPUPPCState, reserve_val));
3136     tcg_temp_free(t0);
3137 }
3138
3139 #if defined(CONFIG_USER_ONLY)
3140 static void gen_conditional_store (DisasContext *ctx, TCGv EA,
3141                                    int reg, int size)
3142 {
3143     TCGv t0 = tcg_temp_new();
3144     uint32_t save_exception = ctx->exception;
3145
3146     tcg_gen_st_tl(EA, cpu_env, offsetof(CPUPPCState, reserve_ea));
3147     tcg_gen_movi_tl(t0, (size << 5) | reg);
3148     tcg_gen_st_tl(t0, cpu_env, offsetof(CPUPPCState, reserve_info));
3149     tcg_temp_free(t0);
3150     gen_update_nip(ctx, ctx->nip-4);
3151     ctx->exception = POWERPC_EXCP_BRANCH;
3152     gen_exception(ctx, POWERPC_EXCP_STCX);
3153     ctx->exception = save_exception;
3154 }
3155 #endif
3156
3157 /* stwcx. */
3158 static void gen_stwcx_(DisasContext *ctx)
3159 {
3160     TCGv t0;
3161     gen_set_access_type(ctx, ACCESS_RES);
3162     t0 = tcg_temp_local_new();
3163     gen_addr_reg_index(ctx, t0);
3164     gen_check_align(ctx, t0, 0x03);
3165 #if defined(CONFIG_USER_ONLY)
3166     gen_conditional_store(ctx, t0, rS(ctx->opcode), 4);
3167 #else
3168     {
3169         int l1;
3170
3171         tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
3172         l1 = gen_new_label();
3173         tcg_gen_brcond_tl(TCG_COND_NE, t0, cpu_reserve, l1);
3174         tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 1 << CRF_EQ);
3175         gen_qemu_st32(ctx, cpu_gpr[rS(ctx->opcode)], t0);
3176         gen_set_label(l1);
3177         tcg_gen_movi_tl(cpu_reserve, -1);
3178     }
3179 #endif
3180     tcg_temp_free(t0);
3181 }
3182
3183 #if defined(TARGET_PPC64)
3184 /* ldarx */
3185 static void gen_ldarx(DisasContext *ctx)
3186 {
3187     TCGv t0;
3188     TCGv gpr = cpu_gpr[rD(ctx->opcode)];
3189     gen_set_access_type(ctx, ACCESS_RES);
3190     t0 = tcg_temp_local_new();
3191     gen_addr_reg_index(ctx, t0);
3192     gen_check_align(ctx, t0, 0x07);
3193     gen_qemu_ld64(ctx, gpr, t0);
3194     tcg_gen_mov_tl(cpu_reserve, t0);
3195     tcg_gen_st_tl(gpr, cpu_env, offsetof(CPUPPCState, reserve_val));
3196     tcg_temp_free(t0);
3197 }
3198
3199 /* stdcx. */
3200 static void gen_stdcx_(DisasContext *ctx)
3201 {
3202     TCGv t0;
3203     gen_set_access_type(ctx, ACCESS_RES);
3204     t0 = tcg_temp_local_new();
3205     gen_addr_reg_index(ctx, t0);
3206     gen_check_align(ctx, t0, 0x07);
3207 #if defined(CONFIG_USER_ONLY)
3208     gen_conditional_store(ctx, t0, rS(ctx->opcode), 8);
3209 #else
3210     {
3211         int l1;
3212         tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
3213         l1 = gen_new_label();
3214         tcg_gen_brcond_tl(TCG_COND_NE, t0, cpu_reserve, l1);
3215         tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 1 << CRF_EQ);
3216         gen_qemu_st64(ctx, cpu_gpr[rS(ctx->opcode)], t0);
3217         gen_set_label(l1);
3218         tcg_gen_movi_tl(cpu_reserve, -1);
3219     }
3220 #endif
3221     tcg_temp_free(t0);
3222 }
3223 #endif /* defined(TARGET_PPC64) */
3224
3225 /* sync */
3226 static void gen_sync(DisasContext *ctx)
3227 {
3228 }
3229
3230 /* wait */
3231 static void gen_wait(DisasContext *ctx)
3232 {
3233     TCGv_i32 t0 = tcg_temp_new_i32();
3234     tcg_gen_st_i32(t0, cpu_env,
3235                    -offsetof(PowerPCCPU, env) + offsetof(CPUState, halted));
3236     tcg_temp_free_i32(t0);
3237     /* Stop translation, as the CPU is supposed to sleep from now */
3238     gen_exception_err(ctx, EXCP_HLT, 1);
3239 }
3240
3241 /***                         Floating-point load                           ***/
3242 #define GEN_LDF(name, ldop, opc, type)                                        \
3243 static void glue(gen_, name)(DisasContext *ctx)                                       \
3244 {                                                                             \
3245     TCGv EA;                                                                  \
3246     if (unlikely(!ctx->fpu_enabled)) {                                        \
3247         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3248         return;                                                               \
3249     }                                                                         \
3250     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3251     EA = tcg_temp_new();                                                      \
3252     gen_addr_imm_index(ctx, EA, 0);                                           \
3253     gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA);                       \
3254     tcg_temp_free(EA);                                                        \
3255 }
3256
3257 #define GEN_LDUF(name, ldop, opc, type)                                       \
3258 static void glue(gen_, name##u)(DisasContext *ctx)                                    \
3259 {                                                                             \
3260     TCGv EA;                                                                  \
3261     if (unlikely(!ctx->fpu_enabled)) {                                        \
3262         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3263         return;                                                               \
3264     }                                                                         \
3265     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
3266         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
3267         return;                                                               \
3268     }                                                                         \
3269     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3270     EA = tcg_temp_new();                                                      \
3271     gen_addr_imm_index(ctx, EA, 0);                                           \
3272     gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA);                       \
3273     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
3274     tcg_temp_free(EA);                                                        \
3275 }
3276
3277 #define GEN_LDUXF(name, ldop, opc, type)                                      \
3278 static void glue(gen_, name##ux)(DisasContext *ctx)                                   \
3279 {                                                                             \
3280     TCGv EA;                                                                  \
3281     if (unlikely(!ctx->fpu_enabled)) {                                        \
3282         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3283         return;                                                               \
3284     }                                                                         \
3285     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
3286         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
3287         return;                                                               \
3288     }                                                                         \
3289     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3290     EA = tcg_temp_new();                                                      \
3291     gen_addr_reg_index(ctx, EA);                                              \
3292     gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA);                       \
3293     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
3294     tcg_temp_free(EA);                                                        \
3295 }
3296
3297 #define GEN_LDXF(name, ldop, opc2, opc3, type)                                \
3298 static void glue(gen_, name##x)(DisasContext *ctx)                                    \
3299 {                                                                             \
3300     TCGv EA;                                                                  \
3301     if (unlikely(!ctx->fpu_enabled)) {                                        \
3302         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3303         return;                                                               \
3304     }                                                                         \
3305     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3306     EA = tcg_temp_new();                                                      \
3307     gen_addr_reg_index(ctx, EA);                                              \
3308     gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA);                       \
3309     tcg_temp_free(EA);                                                        \
3310 }
3311
3312 #define GEN_LDFS(name, ldop, op, type)                                        \
3313 GEN_LDF(name, ldop, op | 0x20, type);                                         \
3314 GEN_LDUF(name, ldop, op | 0x21, type);                                        \
3315 GEN_LDUXF(name, ldop, op | 0x01, type);                                       \
3316 GEN_LDXF(name, ldop, 0x17, op | 0x00, type)
3317
3318 static inline void gen_qemu_ld32fs(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
3319 {
3320     TCGv t0 = tcg_temp_new();
3321     TCGv_i32 t1 = tcg_temp_new_i32();
3322     gen_qemu_ld32u(ctx, t0, arg2);
3323     tcg_gen_trunc_tl_i32(t1, t0);
3324     tcg_temp_free(t0);
3325     gen_helper_float32_to_float64(arg1, cpu_env, t1);
3326     tcg_temp_free_i32(t1);
3327 }
3328
3329  /* lfd lfdu lfdux lfdx */
3330 GEN_LDFS(lfd, ld64, 0x12, PPC_FLOAT);
3331  /* lfs lfsu lfsux lfsx */
3332 GEN_LDFS(lfs, ld32fs, 0x10, PPC_FLOAT);
3333
3334 /* lfdp */
3335 static void gen_lfdp(DisasContext *ctx)
3336 {
3337     TCGv EA;
3338     if (unlikely(!ctx->fpu_enabled)) {
3339         gen_exception(ctx, POWERPC_EXCP_FPU);
3340         return;
3341     }
3342     gen_set_access_type(ctx, ACCESS_FLOAT);
3343     EA = tcg_temp_new();
3344     gen_addr_imm_index(ctx, EA, 0);                                           \
3345     if (unlikely(ctx->le_mode)) {
3346         gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
3347         tcg_gen_addi_tl(EA, EA, 8);
3348         gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
3349     } else {
3350         gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
3351         tcg_gen_addi_tl(EA, EA, 8);
3352         gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
3353     }
3354     tcg_temp_free(EA);
3355 }
3356
3357 /* lfdpx */
3358 static void gen_lfdpx(DisasContext *ctx)
3359 {
3360     TCGv EA;
3361     if (unlikely(!ctx->fpu_enabled)) {
3362         gen_exception(ctx, POWERPC_EXCP_FPU);
3363         return;
3364     }
3365     gen_set_access_type(ctx, ACCESS_FLOAT);
3366     EA = tcg_temp_new();
3367     gen_addr_reg_index(ctx, EA);
3368     if (unlikely(ctx->le_mode)) {
3369         gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
3370         tcg_gen_addi_tl(EA, EA, 8);
3371         gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
3372     } else {
3373         gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
3374         tcg_gen_addi_tl(EA, EA, 8);
3375         gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
3376     }
3377     tcg_temp_free(EA);
3378 }
3379
3380 /* lfiwax */
3381 static void gen_lfiwax(DisasContext *ctx)
3382 {
3383     TCGv EA;
3384     TCGv t0;
3385     if (unlikely(!ctx->fpu_enabled)) {
3386         gen_exception(ctx, POWERPC_EXCP_FPU);
3387         return;
3388     }
3389     gen_set_access_type(ctx, ACCESS_FLOAT);
3390     EA = tcg_temp_new();
3391     t0 = tcg_temp_new();
3392     gen_addr_reg_index(ctx, EA);
3393     gen_qemu_ld32s(ctx, t0, EA);
3394     tcg_gen_ext_tl_i64(cpu_fpr[rD(ctx->opcode)], t0);
3395     tcg_temp_free(EA);
3396     tcg_temp_free(t0);
3397 }
3398
3399 /***                         Floating-point store                          ***/
3400 #define GEN_STF(name, stop, opc, type)                                        \
3401 static void glue(gen_, name)(DisasContext *ctx)                                       \
3402 {                                                                             \
3403     TCGv EA;                                                                  \
3404     if (unlikely(!ctx->fpu_enabled)) {                                        \
3405         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3406         return;                                                               \
3407     }                                                                         \
3408     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3409     EA = tcg_temp_new();                                                      \
3410     gen_addr_imm_index(ctx, EA, 0);                                           \
3411     gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA);                       \
3412     tcg_temp_free(EA);                                                        \
3413 }
3414
3415 #define GEN_STUF(name, stop, opc, type)                                       \
3416 static void glue(gen_, name##u)(DisasContext *ctx)                                    \
3417 {                                                                             \
3418     TCGv EA;                                                                  \
3419     if (unlikely(!ctx->fpu_enabled)) {                                        \
3420         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3421         return;                                                               \
3422     }                                                                         \
3423     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
3424         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
3425         return;                                                               \
3426     }                                                                         \
3427     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3428     EA = tcg_temp_new();                                                      \
3429     gen_addr_imm_index(ctx, EA, 0);                                           \
3430     gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA);                       \
3431     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
3432     tcg_temp_free(EA);                                                        \
3433 }
3434
3435 #define GEN_STUXF(name, stop, opc, type)                                      \
3436 static void glue(gen_, name##ux)(DisasContext *ctx)                                   \
3437 {                                                                             \
3438     TCGv EA;                                                                  \
3439     if (unlikely(!ctx->fpu_enabled)) {                                        \
3440         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3441         return;                                                               \
3442     }                                                                         \
3443     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
3444         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
3445         return;                                                               \
3446     }                                                                         \
3447     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3448     EA = tcg_temp_new();                                                      \
3449     gen_addr_reg_index(ctx, EA);                                              \
3450     gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA);                       \
3451     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
3452     tcg_temp_free(EA);                                                        \
3453 }
3454
3455 #define GEN_STXF(name, stop, opc2, opc3, type)                                \
3456 static void glue(gen_, name##x)(DisasContext *ctx)                                    \
3457 {                                                                             \
3458     TCGv EA;                                                                  \
3459     if (unlikely(!ctx->fpu_enabled)) {                                        \
3460         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3461         return;                                                               \
3462     }                                                                         \
3463     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3464     EA = tcg_temp_new();                                                      \
3465     gen_addr_reg_index(ctx, EA);                                              \
3466     gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA);                       \
3467     tcg_temp_free(EA);                                                        \
3468 }
3469
3470 #define GEN_STFS(name, stop, op, type)                                        \
3471 GEN_STF(name, stop, op | 0x20, type);                                         \
3472 GEN_STUF(name, stop, op | 0x21, type);                                        \
3473 GEN_STUXF(name, stop, op | 0x01, type);                                       \
3474 GEN_STXF(name, stop, 0x17, op | 0x00, type)
3475
3476 static inline void gen_qemu_st32fs(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
3477 {
3478     TCGv_i32 t0 = tcg_temp_new_i32();
3479     TCGv t1 = tcg_temp_new();
3480     gen_helper_float64_to_float32(t0, cpu_env, arg1);
3481     tcg_gen_extu_i32_tl(t1, t0);
3482     tcg_temp_free_i32(t0);
3483     gen_qemu_st32(ctx, t1, arg2);
3484     tcg_temp_free(t1);
3485 }
3486
3487 /* stfd stfdu stfdux stfdx */
3488 GEN_STFS(stfd, st64, 0x16, PPC_FLOAT);
3489 /* stfs stfsu stfsux stfsx */
3490 GEN_STFS(stfs, st32fs, 0x14, PPC_FLOAT);
3491
3492 /* stfdp */
3493 static void gen_stfdp(DisasContext *ctx)
3494 {
3495     TCGv EA;
3496     if (unlikely(!ctx->fpu_enabled)) {
3497         gen_exception(ctx, POWERPC_EXCP_FPU);
3498         return;
3499     }
3500     gen_set_access_type(ctx, ACCESS_FLOAT);
3501     EA = tcg_temp_new();
3502     gen_addr_imm_index(ctx, EA, 0);                                           \
3503     if (unlikely(ctx->le_mode)) {
3504         gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
3505         tcg_gen_addi_tl(EA, EA, 8);
3506         gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
3507     } else {
3508         gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
3509         tcg_gen_addi_tl(EA, EA, 8);
3510         gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
3511     }
3512     tcg_temp_free(EA);
3513 }
3514
3515 /* stfdpx */
3516 static void gen_stfdpx(DisasContext *ctx)
3517 {
3518     TCGv EA;
3519     if (unlikely(!ctx->fpu_enabled)) {
3520         gen_exception(ctx, POWERPC_EXCP_FPU);
3521         return;
3522     }
3523     gen_set_access_type(ctx, ACCESS_FLOAT);
3524     EA = tcg_temp_new();
3525     gen_addr_reg_index(ctx, EA);
3526     if (unlikely(ctx->le_mode)) {
3527         gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
3528         tcg_gen_addi_tl(EA, EA, 8);
3529         gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
3530     } else {
3531         gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
3532         tcg_gen_addi_tl(EA, EA, 8);
3533         gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
3534     }
3535     tcg_temp_free(EA);
3536 }
3537
3538 /* Optional: */
3539 static inline void gen_qemu_st32fiw(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
3540 {
3541     TCGv t0 = tcg_temp_new();
3542     tcg_gen_trunc_i64_tl(t0, arg1),
3543     gen_qemu_st32(ctx, t0, arg2);
3544     tcg_temp_free(t0);
3545 }
3546 /* stfiwx */
3547 GEN_STXF(stfiw, st32fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX);
3548
3549 static inline void gen_update_cfar(DisasContext *ctx, target_ulong nip)
3550 {
3551 #if defined(TARGET_PPC64)
3552     if (ctx->has_cfar)
3553         tcg_gen_movi_tl(cpu_cfar, nip);
3554 #endif
3555 }
3556
3557 /***                                Branch                                 ***/
3558 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
3559 {
3560     TranslationBlock *tb;
3561     tb = ctx->tb;
3562     if (NARROW_MODE(ctx)) {
3563         dest = (uint32_t) dest;
3564     }
3565     if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3566         likely(!ctx->singlestep_enabled)) {
3567         tcg_gen_goto_tb(n);
3568         tcg_gen_movi_tl(cpu_nip, dest & ~3);
3569         tcg_gen_exit_tb((uintptr_t)tb + n);
3570     } else {
3571         tcg_gen_movi_tl(cpu_nip, dest & ~3);
3572         if (unlikely(ctx->singlestep_enabled)) {
3573             if ((ctx->singlestep_enabled &
3574                 (CPU_BRANCH_STEP | CPU_SINGLE_STEP)) &&
3575                 (ctx->exception == POWERPC_EXCP_BRANCH ||
3576                  ctx->exception == POWERPC_EXCP_TRACE)) {
3577                 target_ulong tmp = ctx->nip;
3578                 ctx->nip = dest;
3579                 gen_exception(ctx, POWERPC_EXCP_TRACE);
3580                 ctx->nip = tmp;
3581             }
3582             if (ctx->singlestep_enabled & GDBSTUB_SINGLE_STEP) {
3583                 gen_debug_exception(ctx);
3584             }
3585         }
3586         tcg_gen_exit_tb(0);
3587     }
3588 }
3589
3590 static inline void gen_setlr(DisasContext *ctx, target_ulong nip)
3591 {
3592     if (NARROW_MODE(ctx)) {
3593         nip = (uint32_t)nip;
3594     }
3595     tcg_gen_movi_tl(cpu_lr, nip);
3596 }
3597
3598 /* b ba bl bla */
3599 static void gen_b(DisasContext *ctx)
3600 {
3601     target_ulong li, target;
3602
3603     ctx->exception = POWERPC_EXCP_BRANCH;
3604     /* sign extend LI */
3605     li = LI(ctx->opcode);
3606     li = (li ^ 0x02000000) - 0x02000000;
3607     if (likely(AA(ctx->opcode) == 0)) {
3608         target = ctx->nip + li - 4;
3609     } else {
3610         target = li;
3611     }
3612     if (LK(ctx->opcode)) {
3613         gen_setlr(ctx, ctx->nip);
3614     }
3615     gen_update_cfar(ctx, ctx->nip);
3616     gen_goto_tb(ctx, 0, target);
3617 }
3618
3619 #define BCOND_IM  0
3620 #define BCOND_LR  1
3621 #define BCOND_CTR 2
3622
3623 static inline void gen_bcond(DisasContext *ctx, int type)
3624 {
3625     uint32_t bo = BO(ctx->opcode);
3626     int l1;
3627     TCGv target;
3628
3629     ctx->exception = POWERPC_EXCP_BRANCH;
3630     if (type == BCOND_LR || type == BCOND_CTR) {
3631         target = tcg_temp_local_new();
3632         if (type == BCOND_CTR)
3633             tcg_gen_mov_tl(target, cpu_ctr);
3634         else
3635             tcg_gen_mov_tl(target, cpu_lr);
3636     } else {
3637         TCGV_UNUSED(target);
3638     }
3639     if (LK(ctx->opcode))
3640         gen_setlr(ctx, ctx->nip);
3641     l1 = gen_new_label();
3642     if ((bo & 0x4) == 0) {
3643         /* Decrement and test CTR */
3644         TCGv temp = tcg_temp_new();
3645         if (unlikely(type == BCOND_CTR)) {
3646             gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
3647             return;
3648         }
3649         tcg_gen_subi_tl(cpu_ctr, cpu_ctr, 1);
3650         if (NARROW_MODE(ctx)) {
3651             tcg_gen_ext32u_tl(temp, cpu_ctr);
3652         } else {
3653             tcg_gen_mov_tl(temp, cpu_ctr);
3654         }
3655         if (bo & 0x2) {
3656             tcg_gen_brcondi_tl(TCG_COND_NE, temp, 0, l1);
3657         } else {
3658             tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1);
3659         }
3660         tcg_temp_free(temp);
3661     }
3662     if ((bo & 0x10) == 0) {
3663         /* Test CR */
3664         uint32_t bi = BI(ctx->opcode);
3665         uint32_t mask = 1 << (3 - (bi & 0x03));
3666         TCGv_i32 temp = tcg_temp_new_i32();
3667
3668         if (bo & 0x8) {
3669             tcg_gen_andi_i32(temp, cpu_crf[bi >> 2], mask);
3670             tcg_gen_brcondi_i32(TCG_COND_EQ, temp, 0, l1);
3671         } else {
3672             tcg_gen_andi_i32(temp, cpu_crf[bi >> 2], mask);
3673             tcg_gen_brcondi_i32(TCG_COND_NE, temp, 0, l1);
3674         }
3675         tcg_temp_free_i32(temp);
3676     }
3677     gen_update_cfar(ctx, ctx->nip);
3678     if (type == BCOND_IM) {
3679         target_ulong li = (target_long)((int16_t)(BD(ctx->opcode)));
3680         if (likely(AA(ctx->opcode) == 0)) {
3681             gen_goto_tb(ctx, 0, ctx->nip + li - 4);
3682         } else {
3683             gen_goto_tb(ctx, 0, li);
3684         }
3685         gen_set_label(l1);
3686         gen_goto_tb(ctx, 1, ctx->nip);
3687     } else {
3688         if (NARROW_MODE(ctx)) {
3689             tcg_gen_andi_tl(cpu_nip, target, (uint32_t)~3);
3690         } else {
3691             tcg_gen_andi_tl(cpu_nip, target, ~3);
3692         }
3693         tcg_gen_exit_tb(0);
3694         gen_set_label(l1);
3695         gen_update_nip(ctx, ctx->nip);
3696         tcg_gen_exit_tb(0);
3697     }
3698 }
3699
3700 static void gen_bc(DisasContext *ctx)
3701 {
3702     gen_bcond(ctx, BCOND_IM);
3703 }
3704
3705 static void gen_bcctr(DisasContext *ctx)
3706 {
3707     gen_bcond(ctx, BCOND_CTR);
3708 }
3709
3710 static void gen_bclr(DisasContext *ctx)
3711 {
3712     gen_bcond(ctx, BCOND_LR);
3713 }
3714
3715 /***                      Condition register logical                       ***/
3716 #define GEN_CRLOGIC(name, tcg_op, opc)                                        \
3717 static void glue(gen_, name)(DisasContext *ctx)                                       \
3718 {                                                                             \
3719     uint8_t bitmask;                                                          \
3720     int sh;                                                                   \
3721     TCGv_i32 t0, t1;                                                          \
3722     sh = (crbD(ctx->opcode) & 0x03) - (crbA(ctx->opcode) & 0x03);             \
3723     t0 = tcg_temp_new_i32();                                                  \
3724     if (sh > 0)                                                               \
3725         tcg_gen_shri_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2], sh);            \
3726     else if (sh < 0)                                                          \
3727         tcg_gen_shli_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2], -sh);           \
3728     else                                                                      \
3729         tcg_gen_mov_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2]);                 \
3730     t1 = tcg_temp_new_i32();                                                  \
3731     sh = (crbD(ctx->opcode) & 0x03) - (crbB(ctx->opcode) & 0x03);             \
3732     if (sh > 0)                                                               \
3733         tcg_gen_shri_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2], sh);            \
3734     else if (sh < 0)                                                          \
3735         tcg_gen_shli_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2], -sh);           \
3736     else                                                                      \
3737         tcg_gen_mov_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2]);                 \
3738     tcg_op(t0, t0, t1);                                                       \
3739     bitmask = 1 << (3 - (crbD(ctx->opcode) & 0x03));                          \
3740     tcg_gen_andi_i32(t0, t0, bitmask);                                        \
3741     tcg_gen_andi_i32(t1, cpu_crf[crbD(ctx->opcode) >> 2], ~bitmask);          \
3742     tcg_gen_or_i32(cpu_crf[crbD(ctx->opcode) >> 2], t0, t1);                  \
3743     tcg_temp_free_i32(t0);                                                    \
3744     tcg_temp_free_i32(t1);                                                    \
3745 }
3746
3747 /* crand */
3748 GEN_CRLOGIC(crand, tcg_gen_and_i32, 0x08);
3749 /* crandc */
3750 GEN_CRLOGIC(crandc, tcg_gen_andc_i32, 0x04);
3751 /* creqv */
3752 GEN_CRLOGIC(creqv, tcg_gen_eqv_i32, 0x09);
3753 /* crnand */
3754 GEN_CRLOGIC(crnand, tcg_gen_nand_i32, 0x07);
3755 /* crnor */
3756 GEN_CRLOGIC(crnor, tcg_gen_nor_i32, 0x01);
3757 /* cror */
3758 GEN_CRLOGIC(cror, tcg_gen_or_i32, 0x0E);
3759 /* crorc */
3760 GEN_CRLOGIC(crorc, tcg_gen_orc_i32, 0x0D);
3761 /* crxor */
3762 GEN_CRLOGIC(crxor, tcg_gen_xor_i32, 0x06);
3763
3764 /* mcrf */
3765 static void gen_mcrf(DisasContext *ctx)
3766 {
3767     tcg_gen_mov_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfS(ctx->opcode)]);
3768 }
3769
3770 /***                           System linkage                              ***/
3771
3772 /* rfi (mem_idx only) */
3773 static void gen_rfi(DisasContext *ctx)
3774 {
3775 #if defined(CONFIG_USER_ONLY)
3776     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
3777 #else
3778     /* Restore CPU state */
3779     if (unlikely(!ctx->mem_idx)) {
3780         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
3781         return;
3782     }
3783     gen_update_cfar(ctx, ctx->nip);
3784     gen_helper_rfi(cpu_env);
3785     gen_sync_exception(ctx);
3786 #endif
3787 }
3788
3789 #if defined(TARGET_PPC64)
3790 static void gen_rfid(DisasContext *ctx)
3791 {
3792 #if defined(CONFIG_USER_ONLY)
3793     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
3794 #else
3795     /* Restore CPU state */
3796     if (unlikely(!ctx->mem_idx)) {
3797         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
3798         return;
3799     }
3800     gen_update_cfar(ctx, ctx->nip);
3801     gen_helper_rfid(cpu_env);
3802     gen_sync_exception(ctx);
3803 #endif
3804 }
3805
3806 static void gen_hrfid(DisasContext *ctx)
3807 {
3808 #if defined(CONFIG_USER_ONLY)
3809     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
3810 #else
3811     /* Restore CPU state */
3812     if (unlikely(ctx->mem_idx <= 1)) {
3813         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
3814         return;
3815     }
3816     gen_helper_hrfid(cpu_env);
3817     gen_sync_exception(ctx);
3818 #endif
3819 }
3820 #endif
3821
3822 /* sc */
3823 #if defined(CONFIG_USER_ONLY)
3824 #define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL_USER
3825 #else
3826 #define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL
3827 #endif
3828 static void gen_sc(DisasContext *ctx)
3829 {
3830     uint32_t lev;
3831
3832     lev = (ctx->opcode >> 5) & 0x7F;
3833     gen_exception_err(ctx, POWERPC_SYSCALL, lev);
3834 }
3835
3836 /***                                Trap                                   ***/
3837
3838 /* tw */
3839 static void gen_tw(DisasContext *ctx)
3840 {
3841     TCGv_i32 t0 = tcg_const_i32(TO(ctx->opcode));
3842     /* Update the nip since this might generate a trap exception */
3843     gen_update_nip(ctx, ctx->nip);
3844     gen_helper_tw(cpu_env, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
3845                   t0);
3846     tcg_temp_free_i32(t0);
3847 }
3848
3849 /* twi */
3850 static void gen_twi(DisasContext *ctx)
3851 {
3852     TCGv t0 = tcg_const_tl(SIMM(ctx->opcode));
3853     TCGv_i32 t1 = tcg_const_i32(TO(ctx->opcode));
3854     /* Update the nip since this might generate a trap exception */
3855     gen_update_nip(ctx, ctx->nip);
3856     gen_helper_tw(cpu_env, cpu_gpr[rA(ctx->opcode)], t0, t1);
3857     tcg_temp_free(t0);
3858     tcg_temp_free_i32(t1);
3859 }
3860
3861 #if defined(TARGET_PPC64)
3862 /* td */
3863 static void gen_td(DisasContext *ctx)
3864 {
3865     TCGv_i32 t0 = tcg_const_i32(TO(ctx->opcode));
3866     /* Update the nip since this might generate a trap exception */
3867     gen_update_nip(ctx, ctx->nip);
3868     gen_helper_td(cpu_env, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
3869                   t0);
3870     tcg_temp_free_i32(t0);
3871 }
3872
3873 /* tdi */
3874 static void gen_tdi(DisasContext *ctx)
3875 {
3876     TCGv t0 = tcg_const_tl(SIMM(ctx->opcode));
3877     TCGv_i32 t1 = tcg_const_i32(TO(ctx->opcode));
3878     /* Update the nip since this might generate a trap exception */
3879     gen_update_nip(ctx, ctx->nip);
3880     gen_helper_td(cpu_env, cpu_gpr[rA(ctx->opcode)], t0, t1);
3881     tcg_temp_free(t0);
3882     tcg_temp_free_i32(t1);
3883 }
3884 #endif
3885
3886 /***                          Processor control                            ***/
3887
3888 static void gen_read_xer(TCGv dst)
3889 {
3890     TCGv t0 = tcg_temp_new();
3891     TCGv t1 = tcg_temp_new();
3892     TCGv t2 = tcg_temp_new();
3893     tcg_gen_mov_tl(dst, cpu_xer);
3894     tcg_gen_shli_tl(t0, cpu_so, XER_SO);
3895     tcg_gen_shli_tl(t1, cpu_ov, XER_OV);
3896     tcg_gen_shli_tl(t2, cpu_ca, XER_CA);
3897     tcg_gen_or_tl(t0, t0, t1);
3898     tcg_gen_or_tl(dst, dst, t2);
3899     tcg_gen_or_tl(dst, dst, t0);
3900     tcg_temp_free(t0);
3901     tcg_temp_free(t1);
3902     tcg_temp_free(t2);
3903 }
3904
3905 static void gen_write_xer(TCGv src)
3906 {
3907     tcg_gen_andi_tl(cpu_xer, src,
3908                     ~((1u << XER_SO) | (1u << XER_OV) | (1u << XER_CA)));
3909     tcg_gen_shri_tl(cpu_so, src, XER_SO);
3910     tcg_gen_shri_tl(cpu_ov, src, XER_OV);
3911     tcg_gen_shri_tl(cpu_ca, src, XER_CA);
3912     tcg_gen_andi_tl(cpu_so, cpu_so, 1);
3913     tcg_gen_andi_tl(cpu_ov, cpu_ov, 1);
3914     tcg_gen_andi_tl(cpu_ca, cpu_ca, 1);
3915 }
3916
3917 /* mcrxr */
3918 static void gen_mcrxr(DisasContext *ctx)
3919 {
3920     TCGv_i32 t0 = tcg_temp_new_i32();
3921     TCGv_i32 t1 = tcg_temp_new_i32();
3922     TCGv_i32 dst = cpu_crf[crfD(ctx->opcode)];
3923
3924     tcg_gen_trunc_tl_i32(t0, cpu_so);
3925     tcg_gen_trunc_tl_i32(t1, cpu_ov);
3926     tcg_gen_trunc_tl_i32(dst, cpu_ca);
3927     tcg_gen_shri_i32(t0, t0, 2);
3928     tcg_gen_shri_i32(t1, t1, 1);
3929     tcg_gen_or_i32(dst, dst, t0);
3930     tcg_gen_or_i32(dst, dst, t1);
3931     tcg_temp_free_i32(t0);
3932     tcg_temp_free_i32(t1);
3933
3934     tcg_gen_movi_tl(cpu_so, 0);
3935     tcg_gen_movi_tl(cpu_ov, 0);
3936     tcg_gen_movi_tl(cpu_ca, 0);
3937 }
3938
3939 /* mfcr mfocrf */
3940 static void gen_mfcr(DisasContext *ctx)
3941 {
3942     uint32_t crm, crn;
3943
3944     if (likely(ctx->opcode & 0x00100000)) {
3945         crm = CRM(ctx->opcode);
3946         if (likely(crm && ((crm & (crm - 1)) == 0))) {
3947             crn = ctz32 (crm);
3948             tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], cpu_crf[7 - crn]);
3949             tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)],
3950                             cpu_gpr[rD(ctx->opcode)], crn * 4);
3951         }
3952     } else {
3953         TCGv_i32 t0 = tcg_temp_new_i32();
3954         tcg_gen_mov_i32(t0, cpu_crf[0]);
3955         tcg_gen_shli_i32(t0, t0, 4);
3956         tcg_gen_or_i32(t0, t0, cpu_crf[1]);
3957         tcg_gen_shli_i32(t0, t0, 4);
3958         tcg_gen_or_i32(t0, t0, cpu_crf[2]);
3959         tcg_gen_shli_i32(t0, t0, 4);
3960         tcg_gen_or_i32(t0, t0, cpu_crf[3]);
3961         tcg_gen_shli_i32(t0, t0, 4);
3962         tcg_gen_or_i32(t0, t0, cpu_crf[4]);
3963         tcg_gen_shli_i32(t0, t0, 4);
3964         tcg_gen_or_i32(t0, t0, cpu_crf[5]);
3965         tcg_gen_shli_i32(t0, t0, 4);
3966         tcg_gen_or_i32(t0, t0, cpu_crf[6]);
3967         tcg_gen_shli_i32(t0, t0, 4);
3968         tcg_gen_or_i32(t0, t0, cpu_crf[7]);
3969         tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0);
3970         tcg_temp_free_i32(t0);
3971     }
3972 }
3973
3974 /* mfmsr */
3975 static void gen_mfmsr(DisasContext *ctx)
3976 {
3977 #if defined(CONFIG_USER_ONLY)
3978     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
3979 #else
3980     if (unlikely(!ctx->mem_idx)) {
3981         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
3982         return;
3983     }
3984     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_msr);
3985 #endif
3986 }
3987
3988 static void spr_noaccess(void *opaque, int gprn, int sprn)
3989 {
3990 #if 0
3991     sprn = ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
3992     printf("ERROR: try to access SPR %d !\n", sprn);
3993 #endif
3994 }
3995 #define SPR_NOACCESS (&spr_noaccess)
3996
3997 /* mfspr */
3998 static inline void gen_op_mfspr(DisasContext *ctx)
3999 {
4000     void (*read_cb)(void *opaque, int gprn, int sprn);
4001     uint32_t sprn = SPR(ctx->opcode);
4002
4003 #if !defined(CONFIG_USER_ONLY)
4004     if (ctx->mem_idx == 2)
4005         read_cb = ctx->spr_cb[sprn].hea_read;
4006     else if (ctx->mem_idx)
4007         read_cb = ctx->spr_cb[sprn].oea_read;
4008     else
4009 #endif
4010         read_cb = ctx->spr_cb[sprn].uea_read;
4011     if (likely(read_cb != NULL)) {
4012         if (likely(read_cb != SPR_NOACCESS)) {
4013             (*read_cb)(ctx, rD(ctx->opcode), sprn);
4014         } else {
4015             /* Privilege exception */
4016             /* This is a hack to avoid warnings when running Linux:
4017              * this OS breaks the PowerPC virtualisation model,
4018              * allowing userland application to read the PVR
4019              */
4020             if (sprn != SPR_PVR) {
4021                 qemu_log("Trying to read privileged spr %d (0x%03x) at "
4022                          TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
4023                 printf("Trying to read privileged spr %d (0x%03x) at "
4024                        TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
4025             }
4026             gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4027         }
4028     } else {
4029         /* Not defined */
4030         qemu_log("Trying to read invalid spr %d (0x%03x) at "
4031                  TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
4032         printf("Trying to read invalid spr %d (0x%03x) at "
4033                TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
4034         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR);
4035     }
4036 }
4037
4038 static void gen_mfspr(DisasContext *ctx)
4039 {
4040     gen_op_mfspr(ctx);
4041 }
4042
4043 /* mftb */
4044 static void gen_mftb(DisasContext *ctx)
4045 {
4046     gen_op_mfspr(ctx);
4047 }
4048
4049 /* mtcrf mtocrf*/
4050 static void gen_mtcrf(DisasContext *ctx)
4051 {
4052     uint32_t crm, crn;
4053
4054     crm = CRM(ctx->opcode);
4055     if (likely((ctx->opcode & 0x00100000))) {
4056         if (crm && ((crm & (crm - 1)) == 0)) {
4057             TCGv_i32 temp = tcg_temp_new_i32();
4058             crn = ctz32 (crm);
4059             tcg_gen_trunc_tl_i32(temp, cpu_gpr[rS(ctx->opcode)]);
4060             tcg_gen_shri_i32(temp, temp, crn * 4);
4061             tcg_gen_andi_i32(cpu_crf[7 - crn], temp, 0xf);
4062             tcg_temp_free_i32(temp);
4063         }
4064     } else {
4065         TCGv_i32 temp = tcg_temp_new_i32();
4066         tcg_gen_trunc_tl_i32(temp, cpu_gpr[rS(ctx->opcode)]);
4067         for (crn = 0 ; crn < 8 ; crn++) {
4068             if (crm & (1 << crn)) {
4069                     tcg_gen_shri_i32(cpu_crf[7 - crn], temp, crn * 4);
4070                     tcg_gen_andi_i32(cpu_crf[7 - crn], cpu_crf[7 - crn], 0xf);
4071             }
4072         }
4073         tcg_temp_free_i32(temp);
4074     }
4075 }
4076
4077 /* mtmsr */
4078 #if defined(TARGET_PPC64)
4079 static void gen_mtmsrd(DisasContext *ctx)
4080 {
4081 #if defined(CONFIG_USER_ONLY)
4082     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4083 #else
4084     if (unlikely(!ctx->mem_idx)) {
4085         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4086         return;
4087     }
4088     if (ctx->opcode & 0x00010000) {
4089         /* Special form that does not need any synchronisation */
4090         TCGv t0 = tcg_temp_new();
4091         tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1 << MSR_RI) | (1 << MSR_EE));
4092         tcg_gen_andi_tl(cpu_msr, cpu_msr, ~((1 << MSR_RI) | (1 << MSR_EE)));
4093         tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
4094         tcg_temp_free(t0);
4095     } else {
4096         /* XXX: we need to update nip before the store
4097          *      if we enter power saving mode, we will exit the loop
4098          *      directly from ppc_store_msr
4099          */
4100         gen_update_nip(ctx, ctx->nip);
4101         gen_helper_store_msr(cpu_env, cpu_gpr[rS(ctx->opcode)]);
4102         /* Must stop the translation as machine state (may have) changed */
4103         /* Note that mtmsr is not always defined as context-synchronizing */
4104         gen_stop_exception(ctx);
4105     }
4106 #endif
4107 }
4108 #endif
4109
4110 static void gen_mtmsr(DisasContext *ctx)
4111 {
4112 #if defined(CONFIG_USER_ONLY)
4113     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4114 #else
4115     if (unlikely(!ctx->mem_idx)) {
4116         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4117         return;
4118     }
4119     if (ctx->opcode & 0x00010000) {
4120         /* Special form that does not need any synchronisation */
4121         TCGv t0 = tcg_temp_new();
4122         tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1 << MSR_RI) | (1 << MSR_EE));
4123         tcg_gen_andi_tl(cpu_msr, cpu_msr, ~((1 << MSR_RI) | (1 << MSR_EE)));
4124         tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
4125         tcg_temp_free(t0);
4126     } else {
4127         TCGv msr = tcg_temp_new();
4128
4129         /* XXX: we need to update nip before the store
4130          *      if we enter power saving mode, we will exit the loop
4131          *      directly from ppc_store_msr
4132          */
4133         gen_update_nip(ctx, ctx->nip);
4134 #if defined(TARGET_PPC64)
4135         tcg_gen_deposit_tl(msr, cpu_msr, cpu_gpr[rS(ctx->opcode)], 0, 32);
4136 #else
4137         tcg_gen_mov_tl(msr, cpu_gpr[rS(ctx->opcode)]);
4138 #endif
4139         gen_helper_store_msr(cpu_env, msr);
4140         /* Must stop the translation as machine state (may have) changed */
4141         /* Note that mtmsr is not always defined as context-synchronizing */
4142         gen_stop_exception(ctx);
4143     }
4144 #endif
4145 }
4146
4147 /* mtspr */
4148 static void gen_mtspr(DisasContext *ctx)
4149 {
4150     void (*write_cb)(void *opaque, int sprn, int gprn);
4151     uint32_t sprn = SPR(ctx->opcode);
4152
4153 #if !defined(CONFIG_USER_ONLY)
4154     if (ctx->mem_idx == 2)
4155         write_cb = ctx->spr_cb[sprn].hea_write;
4156     else if (ctx->mem_idx)
4157         write_cb = ctx->spr_cb[sprn].oea_write;
4158     else
4159 #endif
4160         write_cb = ctx->spr_cb[sprn].uea_write;
4161     if (likely(write_cb != NULL)) {
4162         if (likely(write_cb != SPR_NOACCESS)) {
4163             (*write_cb)(ctx, sprn, rS(ctx->opcode));
4164         } else {
4165             /* Privilege exception */
4166             qemu_log("Trying to write privileged spr %d (0x%03x) at "
4167                      TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
4168             printf("Trying to write privileged spr %d (0x%03x) at "
4169                    TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
4170             gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4171         }
4172     } else {
4173         /* Not defined */
4174         qemu_log("Trying to write invalid spr %d (0x%03x) at "
4175                  TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
4176         printf("Trying to write invalid spr %d (0x%03x) at "
4177                TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
4178         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR);
4179     }
4180 }
4181
4182 /***                         Cache management                              ***/
4183
4184 /* dcbf */
4185 static void gen_dcbf(DisasContext *ctx)
4186 {
4187     /* XXX: specification says this is treated as a load by the MMU */
4188     TCGv t0;
4189     gen_set_access_type(ctx, ACCESS_CACHE);
4190     t0 = tcg_temp_new();
4191     gen_addr_reg_index(ctx, t0);
4192     gen_qemu_ld8u(ctx, t0, t0);
4193     tcg_temp_free(t0);
4194 }
4195
4196 /* dcbi (Supervisor only) */
4197 static void gen_dcbi(DisasContext *ctx)
4198 {
4199 #if defined(CONFIG_USER_ONLY)
4200     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4201 #else
4202     TCGv EA, val;
4203     if (unlikely(!ctx->mem_idx)) {
4204         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4205         return;
4206     }
4207     EA = tcg_temp_new();
4208     gen_set_access_type(ctx, ACCESS_CACHE);
4209     gen_addr_reg_index(ctx, EA);
4210     val = tcg_temp_new();
4211     /* XXX: specification says this should be treated as a store by the MMU */
4212     gen_qemu_ld8u(ctx, val, EA);
4213     gen_qemu_st8(ctx, val, EA);
4214     tcg_temp_free(val);
4215     tcg_temp_free(EA);
4216 #endif
4217 }
4218
4219 /* dcdst */
4220 static void gen_dcbst(DisasContext *ctx)
4221 {
4222     /* XXX: specification say this is treated as a load by the MMU */
4223     TCGv t0;
4224     gen_set_access_type(ctx, ACCESS_CACHE);
4225     t0 = tcg_temp_new();
4226     gen_addr_reg_index(ctx, t0);
4227     gen_qemu_ld8u(ctx, t0, t0);
4228     tcg_temp_free(t0);
4229 }
4230
4231 /* dcbt */
4232 static void gen_dcbt(DisasContext *ctx)
4233 {
4234     /* interpreted as no-op */
4235     /* XXX: specification say this is treated as a load by the MMU
4236      *      but does not generate any exception
4237      */
4238 }
4239
4240 /* dcbtst */
4241 static void gen_dcbtst(DisasContext *ctx)
4242 {
4243     /* interpreted as no-op */
4244     /* XXX: specification say this is treated as a load by the MMU
4245      *      but does not generate any exception
4246      */
4247 }
4248
4249 /* dcbz */
4250 static void gen_dcbz(DisasContext *ctx)
4251 {
4252     TCGv tcgv_addr;
4253     TCGv_i32 tcgv_is_dcbzl;
4254     int is_dcbzl = ctx->opcode & 0x00200000 ? 1 : 0;
4255
4256     gen_set_access_type(ctx, ACCESS_CACHE);
4257     /* NIP cannot be restored if the memory exception comes from an helper */
4258     gen_update_nip(ctx, ctx->nip - 4);
4259     tcgv_addr = tcg_temp_new();
4260     tcgv_is_dcbzl = tcg_const_i32(is_dcbzl);
4261
4262     gen_addr_reg_index(ctx, tcgv_addr);
4263     gen_helper_dcbz(cpu_env, tcgv_addr, tcgv_is_dcbzl);
4264
4265     tcg_temp_free(tcgv_addr);
4266     tcg_temp_free_i32(tcgv_is_dcbzl);
4267 }
4268
4269 /* dst / dstt */
4270 static void gen_dst(DisasContext *ctx)
4271 {
4272     if (rA(ctx->opcode) == 0) {
4273         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_LSWX);
4274     } else {
4275         /* interpreted as no-op */
4276     }
4277 }
4278
4279 /* dstst /dststt */
4280 static void gen_dstst(DisasContext *ctx)
4281 {
4282     if (rA(ctx->opcode) == 0) {
4283         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_LSWX);
4284     } else {
4285         /* interpreted as no-op */
4286     }
4287
4288 }
4289
4290 /* dss / dssall */
4291 static void gen_dss(DisasContext *ctx)
4292 {
4293     /* interpreted as no-op */
4294 }
4295
4296 /* icbi */
4297 static void gen_icbi(DisasContext *ctx)
4298 {
4299     TCGv t0;
4300     gen_set_access_type(ctx, ACCESS_CACHE);
4301     /* NIP cannot be restored if the memory exception comes from an helper */
4302     gen_update_nip(ctx, ctx->nip - 4);
4303     t0 = tcg_temp_new();
4304     gen_addr_reg_index(ctx, t0);
4305     gen_helper_icbi(cpu_env, t0);
4306     tcg_temp_free(t0);
4307 }
4308
4309 /* Optional: */
4310 /* dcba */
4311 static void gen_dcba(DisasContext *ctx)
4312 {
4313     /* interpreted as no-op */
4314     /* XXX: specification say this is treated as a store by the MMU
4315      *      but does not generate any exception
4316      */
4317 }
4318
4319 /***                    Segment register manipulation                      ***/
4320 /* Supervisor only: */
4321
4322 /* mfsr */
4323 static void gen_mfsr(DisasContext *ctx)
4324 {
4325 #if defined(CONFIG_USER_ONLY)
4326     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4327 #else
4328     TCGv t0;
4329     if (unlikely(!ctx->mem_idx)) {
4330         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4331         return;
4332     }
4333     t0 = tcg_const_tl(SR(ctx->opcode));
4334     gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
4335     tcg_temp_free(t0);
4336 #endif
4337 }
4338
4339 /* mfsrin */
4340 static void gen_mfsrin(DisasContext *ctx)
4341 {
4342 #if defined(CONFIG_USER_ONLY)
4343     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4344 #else
4345     TCGv t0;
4346     if (unlikely(!ctx->mem_idx)) {
4347         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4348         return;
4349     }
4350     t0 = tcg_temp_new();
4351     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
4352     tcg_gen_andi_tl(t0, t0, 0xF);
4353     gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
4354     tcg_temp_free(t0);
4355 #endif
4356 }
4357
4358 /* mtsr */
4359 static void gen_mtsr(DisasContext *ctx)
4360 {
4361 #if defined(CONFIG_USER_ONLY)
4362     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4363 #else
4364     TCGv t0;
4365     if (unlikely(!ctx->mem_idx)) {
4366         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4367         return;
4368     }
4369     t0 = tcg_const_tl(SR(ctx->opcode));
4370     gen_helper_store_sr(cpu_env, t0, cpu_gpr[rS(ctx->opcode)]);
4371     tcg_temp_free(t0);
4372 #endif
4373 }
4374
4375 /* mtsrin */
4376 static void gen_mtsrin(DisasContext *ctx)
4377 {
4378 #if defined(CONFIG_USER_ONLY)
4379     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4380 #else
4381     TCGv t0;
4382     if (unlikely(!ctx->mem_idx)) {
4383         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4384         return;
4385     }
4386     t0 = tcg_temp_new();
4387     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
4388     tcg_gen_andi_tl(t0, t0, 0xF);
4389     gen_helper_store_sr(cpu_env, t0, cpu_gpr[rD(ctx->opcode)]);
4390     tcg_temp_free(t0);
4391 #endif
4392 }
4393
4394 #if defined(TARGET_PPC64)
4395 /* Specific implementation for PowerPC 64 "bridge" emulation using SLB */
4396
4397 /* mfsr */
4398 static void gen_mfsr_64b(DisasContext *ctx)
4399 {
4400 #if defined(CONFIG_USER_ONLY)
4401     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4402 #else
4403     TCGv t0;
4404     if (unlikely(!ctx->mem_idx)) {
4405         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4406         return;
4407     }
4408     t0 = tcg_const_tl(SR(ctx->opcode));
4409     gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
4410     tcg_temp_free(t0);
4411 #endif
4412 }
4413
4414 /* mfsrin */
4415 static void gen_mfsrin_64b(DisasContext *ctx)
4416 {
4417 #if defined(CONFIG_USER_ONLY)
4418     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4419 #else
4420     TCGv t0;
4421     if (unlikely(!ctx->mem_idx)) {
4422         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4423         return;
4424     }
4425     t0 = tcg_temp_new();
4426     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
4427     tcg_gen_andi_tl(t0, t0, 0xF);
4428     gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
4429     tcg_temp_free(t0);
4430 #endif
4431 }
4432
4433 /* mtsr */
4434 static void gen_mtsr_64b(DisasContext *ctx)
4435 {
4436 #if defined(CONFIG_USER_ONLY)
4437     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4438 #else
4439     TCGv t0;
4440     if (unlikely(!ctx->mem_idx)) {
4441         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4442         return;
4443     }
4444     t0 = tcg_const_tl(SR(ctx->opcode));
4445     gen_helper_store_sr(cpu_env, t0, cpu_gpr[rS(ctx->opcode)]);
4446     tcg_temp_free(t0);
4447 #endif
4448 }
4449
4450 /* mtsrin */
4451 static void gen_mtsrin_64b(DisasContext *ctx)
4452 {
4453 #if defined(CONFIG_USER_ONLY)
4454     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4455 #else
4456     TCGv t0;
4457     if (unlikely(!ctx->mem_idx)) {
4458         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4459         return;
4460     }
4461     t0 = tcg_temp_new();
4462     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
4463     tcg_gen_andi_tl(t0, t0, 0xF);
4464     gen_helper_store_sr(cpu_env, t0, cpu_gpr[rS(ctx->opcode)]);
4465     tcg_temp_free(t0);
4466 #endif
4467 }
4468
4469 /* slbmte */
4470 static void gen_slbmte(DisasContext *ctx)
4471 {
4472 #if defined(CONFIG_USER_ONLY)
4473     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4474 #else
4475     if (unlikely(!ctx->mem_idx)) {
4476         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4477         return;
4478     }
4479     gen_helper_store_slb(cpu_env, cpu_gpr[rB(ctx->opcode)],
4480                          cpu_gpr[rS(ctx->opcode)]);
4481 #endif
4482 }
4483
4484 static void gen_slbmfee(DisasContext *ctx)
4485 {
4486 #if defined(CONFIG_USER_ONLY)
4487     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4488 #else
4489     if (unlikely(!ctx->mem_idx)) {
4490         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4491         return;
4492     }
4493     gen_helper_load_slb_esid(cpu_gpr[rS(ctx->opcode)], cpu_env,
4494                              cpu_gpr[rB(ctx->opcode)]);
4495 #endif
4496 }
4497
4498 static void gen_slbmfev(DisasContext *ctx)
4499 {
4500 #if defined(CONFIG_USER_ONLY)
4501     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4502 #else
4503     if (unlikely(!ctx->mem_idx)) {
4504         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4505         return;
4506     }
4507     gen_helper_load_slb_vsid(cpu_gpr[rS(ctx->opcode)], cpu_env,
4508                              cpu_gpr[rB(ctx->opcode)]);
4509 #endif
4510 }
4511 #endif /* defined(TARGET_PPC64) */
4512
4513 /***                      Lookaside buffer management                      ***/
4514 /* Optional & mem_idx only: */
4515
4516 /* tlbia */
4517 static void gen_tlbia(DisasContext *ctx)
4518 {
4519 #if defined(CONFIG_USER_ONLY)
4520     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4521 #else
4522     if (unlikely(!ctx->mem_idx)) {
4523         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4524         return;
4525     }
4526     gen_helper_tlbia(cpu_env);
4527 #endif
4528 }
4529
4530 /* tlbiel */
4531 static void gen_tlbiel(DisasContext *ctx)
4532 {
4533 #if defined(CONFIG_USER_ONLY)
4534     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4535 #else
4536     if (unlikely(!ctx->mem_idx)) {
4537         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4538         return;
4539     }
4540     gen_helper_tlbie(cpu_env, cpu_gpr[rB(ctx->opcode)]);
4541 #endif
4542 }
4543
4544 /* tlbie */
4545 static void gen_tlbie(DisasContext *ctx)
4546 {
4547 #if defined(CONFIG_USER_ONLY)
4548     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4549 #else
4550     if (unlikely(!ctx->mem_idx)) {
4551         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4552         return;
4553     }
4554     if (NARROW_MODE(ctx)) {
4555         TCGv t0 = tcg_temp_new();
4556         tcg_gen_ext32u_tl(t0, cpu_gpr[rB(ctx->opcode)]);
4557         gen_helper_tlbie(cpu_env, t0);
4558         tcg_temp_free(t0);
4559     } else {
4560         gen_helper_tlbie(cpu_env, cpu_gpr[rB(ctx->opcode)]);
4561     }
4562 #endif
4563 }
4564
4565 /* tlbsync */
4566 static void gen_tlbsync(DisasContext *ctx)
4567 {
4568 #if defined(CONFIG_USER_ONLY)
4569     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4570 #else
4571     if (unlikely(!ctx->mem_idx)) {
4572         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4573         return;
4574     }
4575     /* This has no effect: it should ensure that all previous
4576      * tlbie have completed
4577      */
4578     gen_stop_exception(ctx);
4579 #endif
4580 }
4581
4582 #if defined(TARGET_PPC64)
4583 /* slbia */
4584 static void gen_slbia(DisasContext *ctx)
4585 {
4586 #if defined(CONFIG_USER_ONLY)
4587     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4588 #else
4589     if (unlikely(!ctx->mem_idx)) {
4590         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4591         return;
4592     }
4593     gen_helper_slbia(cpu_env);
4594 #endif
4595 }
4596
4597 /* slbie */
4598 static void gen_slbie(DisasContext *ctx)
4599 {
4600 #if defined(CONFIG_USER_ONLY)
4601     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4602 #else
4603     if (unlikely(!ctx->mem_idx)) {
4604         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4605         return;
4606     }
4607     gen_helper_slbie(cpu_env, cpu_gpr[rB(ctx->opcode)]);
4608 #endif
4609 }
4610 #endif
4611
4612 /***                              External control                         ***/
4613 /* Optional: */
4614
4615 /* eciwx */
4616 static void gen_eciwx(DisasContext *ctx)
4617 {
4618     TCGv t0;
4619     /* Should check EAR[E] ! */
4620     gen_set_access_type(ctx, ACCESS_EXT);
4621     t0 = tcg_temp_new();
4622     gen_addr_reg_index(ctx, t0);
4623     gen_check_align(ctx, t0, 0x03);
4624     gen_qemu_ld32u(ctx, cpu_gpr[rD(ctx->opcode)], t0);
4625     tcg_temp_free(t0);
4626 }
4627
4628 /* ecowx */
4629 static void gen_ecowx(DisasContext *ctx)
4630 {
4631     TCGv t0;
4632     /* Should check EAR[E] ! */
4633     gen_set_access_type(ctx, ACCESS_EXT);
4634     t0 = tcg_temp_new();
4635     gen_addr_reg_index(ctx, t0);
4636     gen_check_align(ctx, t0, 0x03);
4637     gen_qemu_st32(ctx, cpu_gpr[rD(ctx->opcode)], t0);
4638     tcg_temp_free(t0);
4639 }
4640
4641 /* PowerPC 601 specific instructions */
4642
4643 /* abs - abs. */
4644 static void gen_abs(DisasContext *ctx)
4645 {
4646     int l1 = gen_new_label();
4647     int l2 = gen_new_label();
4648     tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rA(ctx->opcode)], 0, l1);
4649     tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4650     tcg_gen_br(l2);
4651     gen_set_label(l1);
4652     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4653     gen_set_label(l2);
4654     if (unlikely(Rc(ctx->opcode) != 0))
4655         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4656 }
4657
4658 /* abso - abso. */
4659 static void gen_abso(DisasContext *ctx)
4660 {
4661     int l1 = gen_new_label();
4662     int l2 = gen_new_label();
4663     int l3 = gen_new_label();
4664     /* Start with XER OV disabled, the most likely case */
4665     tcg_gen_movi_tl(cpu_ov, 0);
4666     tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rA(ctx->opcode)], 0, l2);
4667     tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rA(ctx->opcode)], 0x80000000, l1);
4668     tcg_gen_movi_tl(cpu_ov, 1);
4669     tcg_gen_movi_tl(cpu_so, 1);
4670     tcg_gen_br(l2);
4671     gen_set_label(l1);
4672     tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4673     tcg_gen_br(l3);
4674     gen_set_label(l2);
4675     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4676     gen_set_label(l3);
4677     if (unlikely(Rc(ctx->opcode) != 0))
4678         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4679 }
4680
4681 /* clcs */
4682 static void gen_clcs(DisasContext *ctx)
4683 {
4684     TCGv_i32 t0 = tcg_const_i32(rA(ctx->opcode));
4685     gen_helper_clcs(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
4686     tcg_temp_free_i32(t0);
4687     /* Rc=1 sets CR0 to an undefined state */
4688 }
4689
4690 /* div - div. */
4691 static void gen_div(DisasContext *ctx)
4692 {
4693     gen_helper_div(cpu_gpr[rD(ctx->opcode)], cpu_env, cpu_gpr[rA(ctx->opcode)],
4694                    cpu_gpr[rB(ctx->opcode)]);
4695     if (unlikely(Rc(ctx->opcode) != 0))
4696         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4697 }
4698
4699 /* divo - divo. */
4700 static void gen_divo(DisasContext *ctx)
4701 {
4702     gen_helper_divo(cpu_gpr[rD(ctx->opcode)], cpu_env, cpu_gpr[rA(ctx->opcode)],
4703                     cpu_gpr[rB(ctx->opcode)]);
4704     if (unlikely(Rc(ctx->opcode) != 0))
4705         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4706 }
4707
4708 /* divs - divs. */
4709 static void gen_divs(DisasContext *ctx)
4710 {
4711     gen_helper_divs(cpu_gpr[rD(ctx->opcode)], cpu_env, cpu_gpr[rA(ctx->opcode)],
4712                     cpu_gpr[rB(ctx->opcode)]);
4713     if (unlikely(Rc(ctx->opcode) != 0))
4714         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4715 }
4716
4717 /* divso - divso. */
4718 static void gen_divso(DisasContext *ctx)
4719 {
4720     gen_helper_divso(cpu_gpr[rD(ctx->opcode)], cpu_env,
4721                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
4722     if (unlikely(Rc(ctx->opcode) != 0))
4723         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4724 }
4725
4726 /* doz - doz. */
4727 static void gen_doz(DisasContext *ctx)
4728 {
4729     int l1 = gen_new_label();
4730     int l2 = gen_new_label();
4731     tcg_gen_brcond_tl(TCG_COND_GE, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], l1);
4732     tcg_gen_sub_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4733     tcg_gen_br(l2);
4734     gen_set_label(l1);
4735     tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
4736     gen_set_label(l2);
4737     if (unlikely(Rc(ctx->opcode) != 0))
4738         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4739 }
4740
4741 /* dozo - dozo. */
4742 static void gen_dozo(DisasContext *ctx)
4743 {
4744     int l1 = gen_new_label();
4745     int l2 = gen_new_label();
4746     TCGv t0 = tcg_temp_new();
4747     TCGv t1 = tcg_temp_new();
4748     TCGv t2 = tcg_temp_new();
4749     /* Start with XER OV disabled, the most likely case */
4750     tcg_gen_movi_tl(cpu_ov, 0);
4751     tcg_gen_brcond_tl(TCG_COND_GE, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], l1);
4752     tcg_gen_sub_tl(t0, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4753     tcg_gen_xor_tl(t1, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4754     tcg_gen_xor_tl(t2, cpu_gpr[rA(ctx->opcode)], t0);
4755     tcg_gen_andc_tl(t1, t1, t2);
4756     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
4757     tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l2);
4758     tcg_gen_movi_tl(cpu_ov, 1);
4759     tcg_gen_movi_tl(cpu_so, 1);
4760     tcg_gen_br(l2);
4761     gen_set_label(l1);
4762     tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
4763     gen_set_label(l2);
4764     tcg_temp_free(t0);
4765     tcg_temp_free(t1);
4766     tcg_temp_free(t2);
4767     if (unlikely(Rc(ctx->opcode) != 0))
4768         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4769 }
4770
4771 /* dozi */
4772 static void gen_dozi(DisasContext *ctx)
4773 {
4774     target_long simm = SIMM(ctx->opcode);
4775     int l1 = gen_new_label();
4776     int l2 = gen_new_label();
4777     tcg_gen_brcondi_tl(TCG_COND_LT, cpu_gpr[rA(ctx->opcode)], simm, l1);
4778     tcg_gen_subfi_tl(cpu_gpr[rD(ctx->opcode)], simm, cpu_gpr[rA(ctx->opcode)]);
4779     tcg_gen_br(l2);
4780     gen_set_label(l1);
4781     tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
4782     gen_set_label(l2);
4783     if (unlikely(Rc(ctx->opcode) != 0))
4784         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4785 }
4786
4787 /* lscbx - lscbx. */
4788 static void gen_lscbx(DisasContext *ctx)
4789 {
4790     TCGv t0 = tcg_temp_new();
4791     TCGv_i32 t1 = tcg_const_i32(rD(ctx->opcode));
4792     TCGv_i32 t2 = tcg_const_i32(rA(ctx->opcode));
4793     TCGv_i32 t3 = tcg_const_i32(rB(ctx->opcode));
4794
4795     gen_addr_reg_index(ctx, t0);
4796     /* NIP cannot be restored if the memory exception comes from an helper */
4797     gen_update_nip(ctx, ctx->nip - 4);
4798     gen_helper_lscbx(t0, cpu_env, t0, t1, t2, t3);
4799     tcg_temp_free_i32(t1);
4800     tcg_temp_free_i32(t2);
4801     tcg_temp_free_i32(t3);
4802     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~0x7F);
4803     tcg_gen_or_tl(cpu_xer, cpu_xer, t0);
4804     if (unlikely(Rc(ctx->opcode) != 0))
4805         gen_set_Rc0(ctx, t0);
4806     tcg_temp_free(t0);
4807 }
4808
4809 /* maskg - maskg. */
4810 static void gen_maskg(DisasContext *ctx)
4811 {
4812     int l1 = gen_new_label();
4813     TCGv t0 = tcg_temp_new();
4814     TCGv t1 = tcg_temp_new();
4815     TCGv t2 = tcg_temp_new();
4816     TCGv t3 = tcg_temp_new();
4817     tcg_gen_movi_tl(t3, 0xFFFFFFFF);
4818     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
4819     tcg_gen_andi_tl(t1, cpu_gpr[rS(ctx->opcode)], 0x1F);
4820     tcg_gen_addi_tl(t2, t0, 1);
4821     tcg_gen_shr_tl(t2, t3, t2);
4822     tcg_gen_shr_tl(t3, t3, t1);
4823     tcg_gen_xor_tl(cpu_gpr[rA(ctx->opcode)], t2, t3);
4824     tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
4825     tcg_gen_neg_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4826     gen_set_label(l1);
4827     tcg_temp_free(t0);
4828     tcg_temp_free(t1);
4829     tcg_temp_free(t2);
4830     tcg_temp_free(t3);
4831     if (unlikely(Rc(ctx->opcode) != 0))
4832         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4833 }
4834
4835 /* maskir - maskir. */
4836 static void gen_maskir(DisasContext *ctx)
4837 {
4838     TCGv t0 = tcg_temp_new();
4839     TCGv t1 = tcg_temp_new();
4840     tcg_gen_and_tl(t0, cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
4841     tcg_gen_andc_tl(t1, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
4842     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
4843     tcg_temp_free(t0);
4844     tcg_temp_free(t1);
4845     if (unlikely(Rc(ctx->opcode) != 0))
4846         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4847 }
4848
4849 /* mul - mul. */
4850 static void gen_mul(DisasContext *ctx)
4851 {
4852     TCGv_i64 t0 = tcg_temp_new_i64();
4853     TCGv_i64 t1 = tcg_temp_new_i64();
4854     TCGv t2 = tcg_temp_new();
4855     tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
4856     tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
4857     tcg_gen_mul_i64(t0, t0, t1);
4858     tcg_gen_trunc_i64_tl(t2, t0);
4859     gen_store_spr(SPR_MQ, t2);
4860     tcg_gen_shri_i64(t1, t0, 32);
4861     tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t1);
4862     tcg_temp_free_i64(t0);
4863     tcg_temp_free_i64(t1);
4864     tcg_temp_free(t2);
4865     if (unlikely(Rc(ctx->opcode) != 0))
4866         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4867 }
4868
4869 /* mulo - mulo. */
4870 static void gen_mulo(DisasContext *ctx)
4871 {
4872     int l1 = gen_new_label();
4873     TCGv_i64 t0 = tcg_temp_new_i64();
4874     TCGv_i64 t1 = tcg_temp_new_i64();
4875     TCGv t2 = tcg_temp_new();
4876     /* Start with XER OV disabled, the most likely case */
4877     tcg_gen_movi_tl(cpu_ov, 0);
4878     tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
4879     tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
4880     tcg_gen_mul_i64(t0, t0, t1);
4881     tcg_gen_trunc_i64_tl(t2, t0);
4882     gen_store_spr(SPR_MQ, t2);
4883     tcg_gen_shri_i64(t1, t0, 32);
4884     tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t1);
4885     tcg_gen_ext32s_i64(t1, t0);
4886     tcg_gen_brcond_i64(TCG_COND_EQ, t0, t1, l1);
4887     tcg_gen_movi_tl(cpu_ov, 1);
4888     tcg_gen_movi_tl(cpu_so, 1);
4889     gen_set_label(l1);
4890     tcg_temp_free_i64(t0);
4891     tcg_temp_free_i64(t1);
4892     tcg_temp_free(t2);
4893     if (unlikely(Rc(ctx->opcode) != 0))
4894         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4895 }
4896
4897 /* nabs - nabs. */
4898 static void gen_nabs(DisasContext *ctx)
4899 {
4900     int l1 = gen_new_label();
4901     int l2 = gen_new_label();
4902     tcg_gen_brcondi_tl(TCG_COND_GT, cpu_gpr[rA(ctx->opcode)], 0, l1);
4903     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4904     tcg_gen_br(l2);
4905     gen_set_label(l1);
4906     tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4907     gen_set_label(l2);
4908     if (unlikely(Rc(ctx->opcode) != 0))
4909         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4910 }
4911
4912 /* nabso - nabso. */
4913 static void gen_nabso(DisasContext *ctx)
4914 {
4915     int l1 = gen_new_label();
4916     int l2 = gen_new_label();
4917     tcg_gen_brcondi_tl(TCG_COND_GT, cpu_gpr[rA(ctx->opcode)], 0, l1);
4918     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4919     tcg_gen_br(l2);
4920     gen_set_label(l1);
4921     tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4922     gen_set_label(l2);
4923     /* nabs never overflows */
4924     tcg_gen_movi_tl(cpu_ov, 0);
4925     if (unlikely(Rc(ctx->opcode) != 0))
4926         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4927 }
4928
4929 /* rlmi - rlmi. */
4930 static void gen_rlmi(DisasContext *ctx)
4931 {
4932     uint32_t mb = MB(ctx->opcode);
4933     uint32_t me = ME(ctx->opcode);
4934     TCGv t0 = tcg_temp_new();
4935     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
4936     tcg_gen_rotl_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
4937     tcg_gen_andi_tl(t0, t0, MASK(mb, me));
4938     tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~MASK(mb, me));
4939     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], t0);
4940     tcg_temp_free(t0);
4941     if (unlikely(Rc(ctx->opcode) != 0))
4942         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4943 }
4944
4945 /* rrib - rrib. */
4946 static void gen_rrib(DisasContext *ctx)
4947 {
4948     TCGv t0 = tcg_temp_new();
4949     TCGv t1 = tcg_temp_new();
4950     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
4951     tcg_gen_movi_tl(t1, 0x80000000);
4952     tcg_gen_shr_tl(t1, t1, t0);
4953     tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
4954     tcg_gen_and_tl(t0, t0, t1);
4955     tcg_gen_andc_tl(t1, cpu_gpr[rA(ctx->opcode)], t1);
4956     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
4957     tcg_temp_free(t0);
4958     tcg_temp_free(t1);
4959     if (unlikely(Rc(ctx->opcode) != 0))
4960         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4961 }
4962
4963 /* sle - sle. */
4964 static void gen_sle(DisasContext *ctx)
4965 {
4966     TCGv t0 = tcg_temp_new();
4967     TCGv t1 = tcg_temp_new();
4968     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
4969     tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
4970     tcg_gen_subfi_tl(t1, 32, t1);
4971     tcg_gen_shr_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
4972     tcg_gen_or_tl(t1, t0, t1);
4973     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
4974     gen_store_spr(SPR_MQ, t1);
4975     tcg_temp_free(t0);
4976     tcg_temp_free(t1);
4977     if (unlikely(Rc(ctx->opcode) != 0))
4978         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4979 }
4980
4981 /* sleq - sleq. */
4982 static void gen_sleq(DisasContext *ctx)
4983 {
4984     TCGv t0 = tcg_temp_new();
4985     TCGv t1 = tcg_temp_new();
4986     TCGv t2 = tcg_temp_new();
4987     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
4988     tcg_gen_movi_tl(t2, 0xFFFFFFFF);
4989     tcg_gen_shl_tl(t2, t2, t0);
4990     tcg_gen_rotl_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
4991     gen_load_spr(t1, SPR_MQ);
4992     gen_store_spr(SPR_MQ, t0);
4993     tcg_gen_and_tl(t0, t0, t2);
4994     tcg_gen_andc_tl(t1, t1, t2);
4995     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
4996     tcg_temp_free(t0);
4997     tcg_temp_free(t1);
4998     tcg_temp_free(t2);
4999     if (unlikely(Rc(ctx->opcode) != 0))
5000         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5001 }
5002
5003 /* sliq - sliq. */
5004 static void gen_sliq(DisasContext *ctx)
5005 {
5006     int sh = SH(ctx->opcode);
5007     TCGv t0 = tcg_temp_new();
5008     TCGv t1 = tcg_temp_new();
5009     tcg_gen_shli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
5010     tcg_gen_shri_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh);
5011     tcg_gen_or_tl(t1, t0, t1);
5012     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
5013     gen_store_spr(SPR_MQ, t1);
5014     tcg_temp_free(t0);
5015     tcg_temp_free(t1);
5016     if (unlikely(Rc(ctx->opcode) != 0))
5017         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5018 }
5019
5020 /* slliq - slliq. */
5021 static void gen_slliq(DisasContext *ctx)
5022 {
5023     int sh = SH(ctx->opcode);
5024     TCGv t0 = tcg_temp_new();
5025     TCGv t1 = tcg_temp_new();
5026     tcg_gen_rotli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
5027     gen_load_spr(t1, SPR_MQ);
5028     gen_store_spr(SPR_MQ, t0);
5029     tcg_gen_andi_tl(t0, t0,  (0xFFFFFFFFU << sh));
5030     tcg_gen_andi_tl(t1, t1, ~(0xFFFFFFFFU << sh));
5031     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5032     tcg_temp_free(t0);
5033     tcg_temp_free(t1);
5034     if (unlikely(Rc(ctx->opcode) != 0))
5035         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5036 }
5037
5038 /* sllq - sllq. */
5039 static void gen_sllq(DisasContext *ctx)
5040 {
5041     int l1 = gen_new_label();
5042     int l2 = gen_new_label();
5043     TCGv t0 = tcg_temp_local_new();
5044     TCGv t1 = tcg_temp_local_new();
5045     TCGv t2 = tcg_temp_local_new();
5046     tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F);
5047     tcg_gen_movi_tl(t1, 0xFFFFFFFF);
5048     tcg_gen_shl_tl(t1, t1, t2);
5049     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20);
5050     tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
5051     gen_load_spr(t0, SPR_MQ);
5052     tcg_gen_and_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5053     tcg_gen_br(l2);
5054     gen_set_label(l1);
5055     tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t2);
5056     gen_load_spr(t2, SPR_MQ);
5057     tcg_gen_andc_tl(t1, t2, t1);
5058     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5059     gen_set_label(l2);
5060     tcg_temp_free(t0);
5061     tcg_temp_free(t1);
5062     tcg_temp_free(t2);
5063     if (unlikely(Rc(ctx->opcode) != 0))
5064         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5065 }
5066
5067 /* slq - slq. */
5068 static void gen_slq(DisasContext *ctx)
5069 {
5070     int l1 = gen_new_label();
5071     TCGv t0 = tcg_temp_new();
5072     TCGv t1 = tcg_temp_new();
5073     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
5074     tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
5075     tcg_gen_subfi_tl(t1, 32, t1);
5076     tcg_gen_shr_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
5077     tcg_gen_or_tl(t1, t0, t1);
5078     gen_store_spr(SPR_MQ, t1);
5079     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x20);
5080     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
5081     tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5082     tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
5083     gen_set_label(l1);
5084     tcg_temp_free(t0);
5085     tcg_temp_free(t1);
5086     if (unlikely(Rc(ctx->opcode) != 0))
5087         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5088 }
5089
5090 /* sraiq - sraiq. */
5091 static void gen_sraiq(DisasContext *ctx)
5092 {
5093     int sh = SH(ctx->opcode);
5094     int l1 = gen_new_label();
5095     TCGv t0 = tcg_temp_new();
5096     TCGv t1 = tcg_temp_new();
5097     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
5098     tcg_gen_shli_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh);
5099     tcg_gen_or_tl(t0, t0, t1);
5100     gen_store_spr(SPR_MQ, t0);
5101     tcg_gen_movi_tl(cpu_ca, 0);
5102     tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5103     tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rS(ctx->opcode)], 0, l1);
5104     tcg_gen_movi_tl(cpu_ca, 1);
5105     gen_set_label(l1);
5106     tcg_gen_sari_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], sh);
5107     tcg_temp_free(t0);
5108     tcg_temp_free(t1);
5109     if (unlikely(Rc(ctx->opcode) != 0))
5110         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5111 }
5112
5113 /* sraq - sraq. */
5114 static void gen_sraq(DisasContext *ctx)
5115 {
5116     int l1 = gen_new_label();
5117     int l2 = gen_new_label();
5118     TCGv t0 = tcg_temp_new();
5119     TCGv t1 = tcg_temp_local_new();
5120     TCGv t2 = tcg_temp_local_new();
5121     tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F);
5122     tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t2);
5123     tcg_gen_sar_tl(t1, cpu_gpr[rS(ctx->opcode)], t2);
5124     tcg_gen_subfi_tl(t2, 32, t2);
5125     tcg_gen_shl_tl(t2, cpu_gpr[rS(ctx->opcode)], t2);
5126     tcg_gen_or_tl(t0, t0, t2);
5127     gen_store_spr(SPR_MQ, t0);
5128     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20);
5129     tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, l1);
5130     tcg_gen_mov_tl(t2, cpu_gpr[rS(ctx->opcode)]);
5131     tcg_gen_sari_tl(t1, cpu_gpr[rS(ctx->opcode)], 31);
5132     gen_set_label(l1);
5133     tcg_temp_free(t0);
5134     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t1);
5135     tcg_gen_movi_tl(cpu_ca, 0);
5136     tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l2);
5137     tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, l2);
5138     tcg_gen_movi_tl(cpu_ca, 1);
5139     gen_set_label(l2);
5140     tcg_temp_free(t1);
5141     tcg_temp_free(t2);
5142     if (unlikely(Rc(ctx->opcode) != 0))
5143         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5144 }
5145
5146 /* sre - sre. */
5147 static void gen_sre(DisasContext *ctx)
5148 {
5149     TCGv t0 = tcg_temp_new();
5150     TCGv t1 = tcg_temp_new();
5151     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
5152     tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
5153     tcg_gen_subfi_tl(t1, 32, t1);
5154     tcg_gen_shl_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
5155     tcg_gen_or_tl(t1, t0, t1);
5156     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
5157     gen_store_spr(SPR_MQ, t1);
5158     tcg_temp_free(t0);
5159     tcg_temp_free(t1);
5160     if (unlikely(Rc(ctx->opcode) != 0))
5161         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5162 }
5163
5164 /* srea - srea. */
5165 static void gen_srea(DisasContext *ctx)
5166 {
5167     TCGv t0 = tcg_temp_new();
5168     TCGv t1 = tcg_temp_new();
5169     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
5170     tcg_gen_rotr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
5171     gen_store_spr(SPR_MQ, t0);
5172     tcg_gen_sar_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], t1);
5173     tcg_temp_free(t0);
5174     tcg_temp_free(t1);
5175     if (unlikely(Rc(ctx->opcode) != 0))
5176         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5177 }
5178
5179 /* sreq */
5180 static void gen_sreq(DisasContext *ctx)
5181 {
5182     TCGv t0 = tcg_temp_new();
5183     TCGv t1 = tcg_temp_new();
5184     TCGv t2 = tcg_temp_new();
5185     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
5186     tcg_gen_movi_tl(t1, 0xFFFFFFFF);
5187     tcg_gen_shr_tl(t1, t1, t0);
5188     tcg_gen_rotr_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
5189     gen_load_spr(t2, SPR_MQ);
5190     gen_store_spr(SPR_MQ, t0);
5191     tcg_gen_and_tl(t0, t0, t1);
5192     tcg_gen_andc_tl(t2, t2, t1);
5193     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t2);
5194     tcg_temp_free(t0);
5195     tcg_temp_free(t1);
5196     tcg_temp_free(t2);
5197     if (unlikely(Rc(ctx->opcode) != 0))
5198         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5199 }
5200
5201 /* sriq */
5202 static void gen_sriq(DisasContext *ctx)
5203 {
5204     int sh = SH(ctx->opcode);
5205     TCGv t0 = tcg_temp_new();
5206     TCGv t1 = tcg_temp_new();
5207     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
5208     tcg_gen_shli_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh);
5209     tcg_gen_or_tl(t1, t0, t1);
5210     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
5211     gen_store_spr(SPR_MQ, t1);
5212     tcg_temp_free(t0);
5213     tcg_temp_free(t1);
5214     if (unlikely(Rc(ctx->opcode) != 0))
5215         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5216 }
5217
5218 /* srliq */
5219 static void gen_srliq(DisasContext *ctx)
5220 {
5221     int sh = SH(ctx->opcode);
5222     TCGv t0 = tcg_temp_new();
5223     TCGv t1 = tcg_temp_new();
5224     tcg_gen_rotri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
5225     gen_load_spr(t1, SPR_MQ);
5226     gen_store_spr(SPR_MQ, t0);
5227     tcg_gen_andi_tl(t0, t0,  (0xFFFFFFFFU >> sh));
5228     tcg_gen_andi_tl(t1, t1, ~(0xFFFFFFFFU >> sh));
5229     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5230     tcg_temp_free(t0);
5231     tcg_temp_free(t1);
5232     if (unlikely(Rc(ctx->opcode) != 0))
5233         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5234 }
5235
5236 /* srlq */
5237 static void gen_srlq(DisasContext *ctx)
5238 {
5239     int l1 = gen_new_label();
5240     int l2 = gen_new_label();
5241     TCGv t0 = tcg_temp_local_new();
5242     TCGv t1 = tcg_temp_local_new();
5243     TCGv t2 = tcg_temp_local_new();
5244     tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F);
5245     tcg_gen_movi_tl(t1, 0xFFFFFFFF);
5246     tcg_gen_shr_tl(t2, t1, t2);
5247     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20);
5248     tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
5249     gen_load_spr(t0, SPR_MQ);
5250     tcg_gen_and_tl(cpu_gpr[rA(ctx->opcode)], t0, t2);
5251     tcg_gen_br(l2);
5252     gen_set_label(l1);
5253     tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t2);
5254     tcg_gen_and_tl(t0, t0, t2);
5255     gen_load_spr(t1, SPR_MQ);
5256     tcg_gen_andc_tl(t1, t1, t2);
5257     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5258     gen_set_label(l2);
5259     tcg_temp_free(t0);
5260     tcg_temp_free(t1);
5261     tcg_temp_free(t2);
5262     if (unlikely(Rc(ctx->opcode) != 0))
5263         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5264 }
5265
5266 /* srq */
5267 static void gen_srq(DisasContext *ctx)
5268 {
5269     int l1 = gen_new_label();
5270     TCGv t0 = tcg_temp_new();
5271     TCGv t1 = tcg_temp_new();
5272     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
5273     tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
5274     tcg_gen_subfi_tl(t1, 32, t1);
5275     tcg_gen_shl_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
5276     tcg_gen_or_tl(t1, t0, t1);
5277     gen_store_spr(SPR_MQ, t1);
5278     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x20);
5279     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
5280     tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
5281     tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
5282     gen_set_label(l1);
5283     tcg_temp_free(t0);
5284     tcg_temp_free(t1);
5285     if (unlikely(Rc(ctx->opcode) != 0))
5286         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5287 }
5288
5289 /* PowerPC 602 specific instructions */
5290
5291 /* dsa  */
5292 static void gen_dsa(DisasContext *ctx)
5293 {
5294     /* XXX: TODO */
5295     gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5296 }
5297
5298 /* esa */
5299 static void gen_esa(DisasContext *ctx)
5300 {
5301     /* XXX: TODO */
5302     gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5303 }
5304
5305 /* mfrom */
5306 static void gen_mfrom(DisasContext *ctx)
5307 {
5308 #if defined(CONFIG_USER_ONLY)
5309     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5310 #else
5311     if (unlikely(!ctx->mem_idx)) {
5312         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5313         return;
5314     }
5315     gen_helper_602_mfrom(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5316 #endif
5317 }
5318
5319 /* 602 - 603 - G2 TLB management */
5320
5321 /* tlbld */
5322 static void gen_tlbld_6xx(DisasContext *ctx)
5323 {
5324 #if defined(CONFIG_USER_ONLY)
5325     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5326 #else
5327     if (unlikely(!ctx->mem_idx)) {
5328         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5329         return;
5330     }
5331     gen_helper_6xx_tlbd(cpu_env, cpu_gpr[rB(ctx->opcode)]);
5332 #endif
5333 }
5334
5335 /* tlbli */
5336 static void gen_tlbli_6xx(DisasContext *ctx)
5337 {
5338 #if defined(CONFIG_USER_ONLY)
5339     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5340 #else
5341     if (unlikely(!ctx->mem_idx)) {
5342         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5343         return;
5344     }
5345     gen_helper_6xx_tlbi(cpu_env, cpu_gpr[rB(ctx->opcode)]);
5346 #endif
5347 }
5348
5349 /* 74xx TLB management */
5350
5351 /* tlbld */
5352 static void gen_tlbld_74xx(DisasContext *ctx)
5353 {
5354 #if defined(CONFIG_USER_ONLY)
5355     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5356 #else
5357     if (unlikely(!ctx->mem_idx)) {
5358         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5359         return;
5360     }
5361     gen_helper_74xx_tlbd(cpu_env, cpu_gpr[rB(ctx->opcode)]);
5362 #endif
5363 }
5364
5365 /* tlbli */
5366 static void gen_tlbli_74xx(DisasContext *ctx)
5367 {
5368 #if defined(CONFIG_USER_ONLY)
5369     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5370 #else
5371     if (unlikely(!ctx->mem_idx)) {
5372         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5373         return;
5374     }
5375     gen_helper_74xx_tlbi(cpu_env, cpu_gpr[rB(ctx->opcode)]);
5376 #endif
5377 }
5378
5379 /* POWER instructions not in PowerPC 601 */
5380
5381 /* clf */
5382 static void gen_clf(DisasContext *ctx)
5383 {
5384     /* Cache line flush: implemented as no-op */
5385 }
5386
5387 /* cli */
5388 static void gen_cli(DisasContext *ctx)
5389 {
5390     /* Cache line invalidate: privileged and treated as no-op */
5391 #if defined(CONFIG_USER_ONLY)
5392     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5393 #else
5394     if (unlikely(!ctx->mem_idx)) {
5395         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5396         return;
5397     }
5398 #endif
5399 }
5400
5401 /* dclst */
5402 static void gen_dclst(DisasContext *ctx)
5403 {
5404     /* Data cache line store: treated as no-op */
5405 }
5406
5407 static void gen_mfsri(DisasContext *ctx)
5408 {
5409 #if defined(CONFIG_USER_ONLY)
5410     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5411 #else
5412     int ra = rA(ctx->opcode);
5413     int rd = rD(ctx->opcode);
5414     TCGv t0;
5415     if (unlikely(!ctx->mem_idx)) {
5416         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5417         return;
5418     }
5419     t0 = tcg_temp_new();
5420     gen_addr_reg_index(ctx, t0);
5421     tcg_gen_shri_tl(t0, t0, 28);
5422     tcg_gen_andi_tl(t0, t0, 0xF);
5423     gen_helper_load_sr(cpu_gpr[rd], cpu_env, t0);
5424     tcg_temp_free(t0);
5425     if (ra != 0 && ra != rd)
5426         tcg_gen_mov_tl(cpu_gpr[ra], cpu_gpr[rd]);
5427 #endif
5428 }
5429
5430 static void gen_rac(DisasContext *ctx)
5431 {
5432 #if defined(CONFIG_USER_ONLY)
5433     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5434 #else
5435     TCGv t0;
5436     if (unlikely(!ctx->mem_idx)) {
5437         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5438         return;
5439     }
5440     t0 = tcg_temp_new();
5441     gen_addr_reg_index(ctx, t0);
5442     gen_helper_rac(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
5443     tcg_temp_free(t0);
5444 #endif
5445 }
5446
5447 static void gen_rfsvc(DisasContext *ctx)
5448 {
5449 #if defined(CONFIG_USER_ONLY)
5450     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5451 #else
5452     if (unlikely(!ctx->mem_idx)) {
5453         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5454         return;
5455     }
5456     gen_helper_rfsvc(cpu_env);
5457     gen_sync_exception(ctx);
5458 #endif
5459 }
5460
5461 /* svc is not implemented for now */
5462
5463 /* POWER2 specific instructions */
5464 /* Quad manipulation (load/store two floats at a time) */
5465
5466 /* lfq */
5467 static void gen_lfq(DisasContext *ctx)
5468 {
5469     int rd = rD(ctx->opcode);
5470     TCGv t0;
5471     gen_set_access_type(ctx, ACCESS_FLOAT);
5472     t0 = tcg_temp_new();
5473     gen_addr_imm_index(ctx, t0, 0);
5474     gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
5475     gen_addr_add(ctx, t0, t0, 8);
5476     gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t0);
5477     tcg_temp_free(t0);
5478 }
5479
5480 /* lfqu */
5481 static void gen_lfqu(DisasContext *ctx)
5482 {
5483     int ra = rA(ctx->opcode);
5484     int rd = rD(ctx->opcode);
5485     TCGv t0, t1;
5486     gen_set_access_type(ctx, ACCESS_FLOAT);
5487     t0 = tcg_temp_new();
5488     t1 = tcg_temp_new();
5489     gen_addr_imm_index(ctx, t0, 0);
5490     gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
5491     gen_addr_add(ctx, t1, t0, 8);
5492     gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t1);
5493     if (ra != 0)
5494         tcg_gen_mov_tl(cpu_gpr[ra], t0);
5495     tcg_temp_free(t0);
5496     tcg_temp_free(t1);
5497 }
5498
5499 /* lfqux */
5500 static void gen_lfqux(DisasContext *ctx)
5501 {
5502     int ra = rA(ctx->opcode);
5503     int rd = rD(ctx->opcode);
5504     gen_set_access_type(ctx, ACCESS_FLOAT);
5505     TCGv t0, t1;
5506     t0 = tcg_temp_new();
5507     gen_addr_reg_index(ctx, t0);
5508     gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
5509     t1 = tcg_temp_new();
5510     gen_addr_add(ctx, t1, t0, 8);
5511     gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t1);
5512     tcg_temp_free(t1);
5513     if (ra != 0)
5514         tcg_gen_mov_tl(cpu_gpr[ra], t0);
5515     tcg_temp_free(t0);
5516 }
5517
5518 /* lfqx */
5519 static void gen_lfqx(DisasContext *ctx)
5520 {
5521     int rd = rD(ctx->opcode);
5522     TCGv t0;
5523     gen_set_access_type(ctx, ACCESS_FLOAT);
5524     t0 = tcg_temp_new();
5525     gen_addr_reg_index(ctx, t0);
5526     gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
5527     gen_addr_add(ctx, t0, t0, 8);
5528     gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t0);
5529     tcg_temp_free(t0);
5530 }
5531
5532 /* stfq */
5533 static void gen_stfq(DisasContext *ctx)
5534 {
5535     int rd = rD(ctx->opcode);
5536     TCGv t0;
5537     gen_set_access_type(ctx, ACCESS_FLOAT);
5538     t0 = tcg_temp_new();
5539     gen_addr_imm_index(ctx, t0, 0);
5540     gen_qemu_st64(ctx, cpu_fpr[rd], t0);
5541     gen_addr_add(ctx, t0, t0, 8);
5542     gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t0);
5543     tcg_temp_free(t0);
5544 }
5545
5546 /* stfqu */
5547 static void gen_stfqu(DisasContext *ctx)
5548 {
5549     int ra = rA(ctx->opcode);
5550     int rd = rD(ctx->opcode);
5551     TCGv t0, t1;
5552     gen_set_access_type(ctx, ACCESS_FLOAT);
5553     t0 = tcg_temp_new();
5554     gen_addr_imm_index(ctx, t0, 0);
5555     gen_qemu_st64(ctx, cpu_fpr[rd], t0);
5556     t1 = tcg_temp_new();
5557     gen_addr_add(ctx, t1, t0, 8);
5558     gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t1);
5559     tcg_temp_free(t1);
5560     if (ra != 0)
5561         tcg_gen_mov_tl(cpu_gpr[ra], t0);
5562     tcg_temp_free(t0);
5563 }
5564
5565 /* stfqux */
5566 static void gen_stfqux(DisasContext *ctx)
5567 {
5568     int ra = rA(ctx->opcode);
5569     int rd = rD(ctx->opcode);
5570     TCGv t0, t1;
5571     gen_set_access_type(ctx, ACCESS_FLOAT);
5572     t0 = tcg_temp_new();
5573     gen_addr_reg_index(ctx, t0);
5574     gen_qemu_st64(ctx, cpu_fpr[rd], t0);
5575     t1 = tcg_temp_new();
5576     gen_addr_add(ctx, t1, t0, 8);
5577     gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t1);
5578     tcg_temp_free(t1);
5579     if (ra != 0)
5580         tcg_gen_mov_tl(cpu_gpr[ra], t0);
5581     tcg_temp_free(t0);
5582 }
5583
5584 /* stfqx */
5585 static void gen_stfqx(DisasContext *ctx)
5586 {
5587     int rd = rD(ctx->opcode);
5588     TCGv t0;
5589     gen_set_access_type(ctx, ACCESS_FLOAT);
5590     t0 = tcg_temp_new();
5591     gen_addr_reg_index(ctx, t0);
5592     gen_qemu_st64(ctx, cpu_fpr[rd], t0);
5593     gen_addr_add(ctx, t0, t0, 8);
5594     gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t0);
5595     tcg_temp_free(t0);
5596 }
5597
5598 /* BookE specific instructions */
5599
5600 /* XXX: not implemented on 440 ? */
5601 static void gen_mfapidi(DisasContext *ctx)
5602 {
5603     /* XXX: TODO */
5604     gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5605 }
5606
5607 /* XXX: not implemented on 440 ? */
5608 static void gen_tlbiva(DisasContext *ctx)
5609 {
5610 #if defined(CONFIG_USER_ONLY)
5611     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5612 #else
5613     TCGv t0;
5614     if (unlikely(!ctx->mem_idx)) {
5615         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5616         return;
5617     }
5618     t0 = tcg_temp_new();
5619     gen_addr_reg_index(ctx, t0);
5620     gen_helper_tlbie(cpu_env, cpu_gpr[rB(ctx->opcode)]);
5621     tcg_temp_free(t0);
5622 #endif
5623 }
5624
5625 /* All 405 MAC instructions are translated here */
5626 static inline void gen_405_mulladd_insn(DisasContext *ctx, int opc2, int opc3,
5627                                         int ra, int rb, int rt, int Rc)
5628 {
5629     TCGv t0, t1;
5630
5631     t0 = tcg_temp_local_new();
5632     t1 = tcg_temp_local_new();
5633
5634     switch (opc3 & 0x0D) {
5635     case 0x05:
5636         /* macchw    - macchw.    - macchwo   - macchwo.   */
5637         /* macchws   - macchws.   - macchwso  - macchwso.  */
5638         /* nmacchw   - nmacchw.   - nmacchwo  - nmacchwo.  */
5639         /* nmacchws  - nmacchws.  - nmacchwso - nmacchwso. */
5640         /* mulchw - mulchw. */
5641         tcg_gen_ext16s_tl(t0, cpu_gpr[ra]);
5642         tcg_gen_sari_tl(t1, cpu_gpr[rb], 16);
5643         tcg_gen_ext16s_tl(t1, t1);
5644         break;
5645     case 0x04:
5646         /* macchwu   - macchwu.   - macchwuo  - macchwuo.  */
5647         /* macchwsu  - macchwsu.  - macchwsuo - macchwsuo. */
5648         /* mulchwu - mulchwu. */
5649         tcg_gen_ext16u_tl(t0, cpu_gpr[ra]);
5650         tcg_gen_shri_tl(t1, cpu_gpr[rb], 16);
5651         tcg_gen_ext16u_tl(t1, t1);
5652         break;
5653     case 0x01:
5654         /* machhw    - machhw.    - machhwo   - machhwo.   */
5655         /* machhws   - machhws.   - machhwso  - machhwso.  */
5656         /* nmachhw   - nmachhw.   - nmachhwo  - nmachhwo.  */
5657         /* nmachhws  - nmachhws.  - nmachhwso - nmachhwso. */
5658         /* mulhhw - mulhhw. */
5659         tcg_gen_sari_tl(t0, cpu_gpr[ra], 16);
5660         tcg_gen_ext16s_tl(t0, t0);
5661         tcg_gen_sari_tl(t1, cpu_gpr[rb], 16);
5662         tcg_gen_ext16s_tl(t1, t1);
5663         break;
5664     case 0x00:
5665         /* machhwu   - machhwu.   - machhwuo  - machhwuo.  */
5666         /* machhwsu  - machhwsu.  - machhwsuo - machhwsuo. */
5667         /* mulhhwu - mulhhwu. */
5668         tcg_gen_shri_tl(t0, cpu_gpr[ra], 16);
5669         tcg_gen_ext16u_tl(t0, t0);
5670         tcg_gen_shri_tl(t1, cpu_gpr[rb], 16);
5671         tcg_gen_ext16u_tl(t1, t1);
5672         break;
5673     case 0x0D:
5674         /* maclhw    - maclhw.    - maclhwo   - maclhwo.   */
5675         /* maclhws   - maclhws.   - maclhwso  - maclhwso.  */
5676         /* nmaclhw   - nmaclhw.   - nmaclhwo  - nmaclhwo.  */
5677         /* nmaclhws  - nmaclhws.  - nmaclhwso - nmaclhwso. */
5678         /* mullhw - mullhw. */
5679         tcg_gen_ext16s_tl(t0, cpu_gpr[ra]);
5680         tcg_gen_ext16s_tl(t1, cpu_gpr[rb]);
5681         break;
5682     case 0x0C:
5683         /* maclhwu   - maclhwu.   - maclhwuo  - maclhwuo.  */
5684         /* maclhwsu  - maclhwsu.  - maclhwsuo - maclhwsuo. */
5685         /* mullhwu - mullhwu. */
5686         tcg_gen_ext16u_tl(t0, cpu_gpr[ra]);
5687         tcg_gen_ext16u_tl(t1, cpu_gpr[rb]);
5688         break;
5689     }
5690     if (opc2 & 0x04) {
5691         /* (n)multiply-and-accumulate (0x0C / 0x0E) */
5692         tcg_gen_mul_tl(t1, t0, t1);
5693         if (opc2 & 0x02) {
5694             /* nmultiply-and-accumulate (0x0E) */
5695             tcg_gen_sub_tl(t0, cpu_gpr[rt], t1);
5696         } else {
5697             /* multiply-and-accumulate (0x0C) */
5698             tcg_gen_add_tl(t0, cpu_gpr[rt], t1);
5699         }
5700
5701         if (opc3 & 0x12) {
5702             /* Check overflow and/or saturate */
5703             int l1 = gen_new_label();
5704
5705             if (opc3 & 0x10) {
5706                 /* Start with XER OV disabled, the most likely case */
5707                 tcg_gen_movi_tl(cpu_ov, 0);
5708             }
5709             if (opc3 & 0x01) {
5710                 /* Signed */
5711                 tcg_gen_xor_tl(t1, cpu_gpr[rt], t1);
5712                 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
5713                 tcg_gen_xor_tl(t1, cpu_gpr[rt], t0);
5714                 tcg_gen_brcondi_tl(TCG_COND_LT, t1, 0, l1);
5715                 if (opc3 & 0x02) {
5716                     /* Saturate */
5717                     tcg_gen_sari_tl(t0, cpu_gpr[rt], 31);
5718                     tcg_gen_xori_tl(t0, t0, 0x7fffffff);
5719                 }
5720             } else {
5721                 /* Unsigned */
5722                 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
5723                 if (opc3 & 0x02) {
5724                     /* Saturate */
5725                     tcg_gen_movi_tl(t0, UINT32_MAX);
5726                 }
5727             }
5728             if (opc3 & 0x10) {
5729                 /* Check overflow */
5730                 tcg_gen_movi_tl(cpu_ov, 1);
5731                 tcg_gen_movi_tl(cpu_so, 1);
5732             }
5733             gen_set_label(l1);
5734             tcg_gen_mov_tl(cpu_gpr[rt], t0);
5735         }
5736     } else {
5737         tcg_gen_mul_tl(cpu_gpr[rt], t0, t1);
5738     }
5739     tcg_temp_free(t0);
5740     tcg_temp_free(t1);
5741     if (unlikely(Rc) != 0) {
5742         /* Update Rc0 */
5743         gen_set_Rc0(ctx, cpu_gpr[rt]);
5744     }
5745 }
5746
5747 #define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
5748 static void glue(gen_, name)(DisasContext *ctx)                               \
5749 {                                                                             \
5750     gen_405_mulladd_insn(ctx, opc2, opc3, rA(ctx->opcode), rB(ctx->opcode),   \
5751                          rD(ctx->opcode), Rc(ctx->opcode));                   \
5752 }
5753
5754 /* macchw    - macchw.    */
5755 GEN_MAC_HANDLER(macchw, 0x0C, 0x05);
5756 /* macchwo   - macchwo.   */
5757 GEN_MAC_HANDLER(macchwo, 0x0C, 0x15);
5758 /* macchws   - macchws.   */
5759 GEN_MAC_HANDLER(macchws, 0x0C, 0x07);
5760 /* macchwso  - macchwso.  */
5761 GEN_MAC_HANDLER(macchwso, 0x0C, 0x17);
5762 /* macchwsu  - macchwsu.  */
5763 GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06);
5764 /* macchwsuo - macchwsuo. */
5765 GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16);
5766 /* macchwu   - macchwu.   */
5767 GEN_MAC_HANDLER(macchwu, 0x0C, 0x04);
5768 /* macchwuo  - macchwuo.  */
5769 GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14);
5770 /* machhw    - machhw.    */
5771 GEN_MAC_HANDLER(machhw, 0x0C, 0x01);
5772 /* machhwo   - machhwo.   */
5773 GEN_MAC_HANDLER(machhwo, 0x0C, 0x11);
5774 /* machhws   - machhws.   */
5775 GEN_MAC_HANDLER(machhws, 0x0C, 0x03);
5776 /* machhwso  - machhwso.  */
5777 GEN_MAC_HANDLER(machhwso, 0x0C, 0x13);
5778 /* machhwsu  - machhwsu.  */
5779 GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02);
5780 /* machhwsuo - machhwsuo. */
5781 GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12);
5782 /* machhwu   - machhwu.   */
5783 GEN_MAC_HANDLER(machhwu, 0x0C, 0x00);
5784 /* machhwuo  - machhwuo.  */
5785 GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10);
5786 /* maclhw    - maclhw.    */
5787 GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D);
5788 /* maclhwo   - maclhwo.   */
5789 GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D);
5790 /* maclhws   - maclhws.   */
5791 GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F);
5792 /* maclhwso  - maclhwso.  */
5793 GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F);
5794 /* maclhwu   - maclhwu.   */
5795 GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C);
5796 /* maclhwuo  - maclhwuo.  */
5797 GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C);
5798 /* maclhwsu  - maclhwsu.  */
5799 GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E);
5800 /* maclhwsuo - maclhwsuo. */
5801 GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E);
5802 /* nmacchw   - nmacchw.   */
5803 GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05);
5804 /* nmacchwo  - nmacchwo.  */
5805 GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15);
5806 /* nmacchws  - nmacchws.  */
5807 GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07);
5808 /* nmacchwso - nmacchwso. */
5809 GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17);
5810 /* nmachhw   - nmachhw.   */
5811 GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01);
5812 /* nmachhwo  - nmachhwo.  */
5813 GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11);
5814 /* nmachhws  - nmachhws.  */
5815 GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03);
5816 /* nmachhwso - nmachhwso. */
5817 GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13);
5818 /* nmaclhw   - nmaclhw.   */
5819 GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D);
5820 /* nmaclhwo  - nmaclhwo.  */
5821 GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D);
5822 /* nmaclhws  - nmaclhws.  */
5823 GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F);
5824 /* nmaclhwso - nmaclhwso. */
5825 GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F);
5826
5827 /* mulchw  - mulchw.  */
5828 GEN_MAC_HANDLER(mulchw, 0x08, 0x05);
5829 /* mulchwu - mulchwu. */
5830 GEN_MAC_HANDLER(mulchwu, 0x08, 0x04);
5831 /* mulhhw  - mulhhw.  */
5832 GEN_MAC_HANDLER(mulhhw, 0x08, 0x01);
5833 /* mulhhwu - mulhhwu. */
5834 GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00);
5835 /* mullhw  - mullhw.  */
5836 GEN_MAC_HANDLER(mullhw, 0x08, 0x0D);
5837 /* mullhwu - mullhwu. */
5838 GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C);
5839
5840 /* mfdcr */
5841 static void gen_mfdcr(DisasContext *ctx)
5842 {
5843 #if defined(CONFIG_USER_ONLY)
5844     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
5845 #else
5846     TCGv dcrn;
5847     if (unlikely(!ctx->mem_idx)) {
5848         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
5849         return;
5850     }
5851     /* NIP cannot be restored if the memory exception comes from an helper */
5852     gen_update_nip(ctx, ctx->nip - 4);
5853     dcrn = tcg_const_tl(SPR(ctx->opcode));
5854     gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_env, dcrn);
5855     tcg_temp_free(dcrn);
5856 #endif
5857 }
5858
5859 /* mtdcr */
5860 static void gen_mtdcr(DisasContext *ctx)
5861 {
5862 #if defined(CONFIG_USER_ONLY)
5863     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
5864 #else
5865     TCGv dcrn;
5866     if (unlikely(!ctx->mem_idx)) {
5867         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
5868         return;
5869     }
5870     /* NIP cannot be restored if the memory exception comes from an helper */
5871     gen_update_nip(ctx, ctx->nip - 4);
5872     dcrn = tcg_const_tl(SPR(ctx->opcode));
5873     gen_helper_store_dcr(cpu_env, dcrn, cpu_gpr[rS(ctx->opcode)]);
5874     tcg_temp_free(dcrn);
5875 #endif
5876 }
5877
5878 /* mfdcrx */
5879 /* XXX: not implemented on 440 ? */
5880 static void gen_mfdcrx(DisasContext *ctx)
5881 {
5882 #if defined(CONFIG_USER_ONLY)
5883     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
5884 #else
5885     if (unlikely(!ctx->mem_idx)) {
5886         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
5887         return;
5888     }
5889     /* NIP cannot be restored if the memory exception comes from an helper */
5890     gen_update_nip(ctx, ctx->nip - 4);
5891     gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_env,
5892                         cpu_gpr[rA(ctx->opcode)]);
5893     /* Note: Rc update flag set leads to undefined state of Rc0 */
5894 #endif
5895 }
5896
5897 /* mtdcrx */
5898 /* XXX: not implemented on 440 ? */
5899 static void gen_mtdcrx(DisasContext *ctx)
5900 {
5901 #if defined(CONFIG_USER_ONLY)
5902     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
5903 #else
5904     if (unlikely(!ctx->mem_idx)) {
5905         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
5906         return;
5907     }
5908     /* NIP cannot be restored if the memory exception comes from an helper */
5909     gen_update_nip(ctx, ctx->nip - 4);
5910     gen_helper_store_dcr(cpu_env, cpu_gpr[rA(ctx->opcode)],
5911                          cpu_gpr[rS(ctx->opcode)]);
5912     /* Note: Rc update flag set leads to undefined state of Rc0 */
5913 #endif
5914 }
5915
5916 /* mfdcrux (PPC 460) : user-mode access to DCR */
5917 static void gen_mfdcrux(DisasContext *ctx)
5918 {
5919     /* NIP cannot be restored if the memory exception comes from an helper */
5920     gen_update_nip(ctx, ctx->nip - 4);
5921     gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_env,
5922                         cpu_gpr[rA(ctx->opcode)]);
5923     /* Note: Rc update flag set leads to undefined state of Rc0 */
5924 }
5925
5926 /* mtdcrux (PPC 460) : user-mode access to DCR */
5927 static void gen_mtdcrux(DisasContext *ctx)
5928 {
5929     /* NIP cannot be restored if the memory exception comes from an helper */
5930     gen_update_nip(ctx, ctx->nip - 4);
5931     gen_helper_store_dcr(cpu_env, cpu_gpr[rA(ctx->opcode)],
5932                          cpu_gpr[rS(ctx->opcode)]);
5933     /* Note: Rc update flag set leads to undefined state of Rc0 */
5934 }
5935
5936 /* dccci */
5937 static void gen_dccci(DisasContext *ctx)
5938 {
5939 #if defined(CONFIG_USER_ONLY)
5940     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5941 #else
5942     if (unlikely(!ctx->mem_idx)) {
5943         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5944         return;
5945     }
5946     /* interpreted as no-op */
5947 #endif
5948 }
5949
5950 /* dcread */
5951 static void gen_dcread(DisasContext *ctx)
5952 {
5953 #if defined(CONFIG_USER_ONLY)
5954     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5955 #else
5956     TCGv EA, val;
5957     if (unlikely(!ctx->mem_idx)) {
5958         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5959         return;
5960     }
5961     gen_set_access_type(ctx, ACCESS_CACHE);
5962     EA = tcg_temp_new();
5963     gen_addr_reg_index(ctx, EA);
5964     val = tcg_temp_new();
5965     gen_qemu_ld32u(ctx, val, EA);
5966     tcg_temp_free(val);
5967     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], EA);
5968     tcg_temp_free(EA);
5969 #endif
5970 }
5971
5972 /* icbt */
5973 static void gen_icbt_40x(DisasContext *ctx)
5974 {
5975     /* interpreted as no-op */
5976     /* XXX: specification say this is treated as a load by the MMU
5977      *      but does not generate any exception
5978      */
5979 }
5980
5981 /* iccci */
5982 static void gen_iccci(DisasContext *ctx)
5983 {
5984 #if defined(CONFIG_USER_ONLY)
5985     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5986 #else
5987     if (unlikely(!ctx->mem_idx)) {
5988         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5989         return;
5990     }
5991     /* interpreted as no-op */
5992 #endif
5993 }
5994
5995 /* icread */
5996 static void gen_icread(DisasContext *ctx)
5997 {
5998 #if defined(CONFIG_USER_ONLY)
5999     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6000 #else
6001     if (unlikely(!ctx->mem_idx)) {
6002         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6003         return;
6004     }
6005     /* interpreted as no-op */
6006 #endif
6007 }
6008
6009 /* rfci (mem_idx only) */
6010 static void gen_rfci_40x(DisasContext *ctx)
6011 {
6012 #if defined(CONFIG_USER_ONLY)
6013     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6014 #else
6015     if (unlikely(!ctx->mem_idx)) {
6016         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6017         return;
6018     }
6019     /* Restore CPU state */
6020     gen_helper_40x_rfci(cpu_env);
6021     gen_sync_exception(ctx);
6022 #endif
6023 }
6024
6025 static void gen_rfci(DisasContext *ctx)
6026 {
6027 #if defined(CONFIG_USER_ONLY)
6028     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6029 #else
6030     if (unlikely(!ctx->mem_idx)) {
6031         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6032         return;
6033     }
6034     /* Restore CPU state */
6035     gen_helper_rfci(cpu_env);
6036     gen_sync_exception(ctx);
6037 #endif
6038 }
6039
6040 /* BookE specific */
6041
6042 /* XXX: not implemented on 440 ? */
6043 static void gen_rfdi(DisasContext *ctx)
6044 {
6045 #if defined(CONFIG_USER_ONLY)
6046     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6047 #else
6048     if (unlikely(!ctx->mem_idx)) {
6049         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6050         return;
6051     }
6052     /* Restore CPU state */
6053     gen_helper_rfdi(cpu_env);
6054     gen_sync_exception(ctx);
6055 #endif
6056 }
6057
6058 /* XXX: not implemented on 440 ? */
6059 static void gen_rfmci(DisasContext *ctx)
6060 {
6061 #if defined(CONFIG_USER_ONLY)
6062     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6063 #else
6064     if (unlikely(!ctx->mem_idx)) {
6065         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6066         return;
6067     }
6068     /* Restore CPU state */
6069     gen_helper_rfmci(cpu_env);
6070     gen_sync_exception(ctx);
6071 #endif
6072 }
6073
6074 /* TLB management - PowerPC 405 implementation */
6075
6076 /* tlbre */
6077 static void gen_tlbre_40x(DisasContext *ctx)
6078 {
6079 #if defined(CONFIG_USER_ONLY)
6080     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6081 #else
6082     if (unlikely(!ctx->mem_idx)) {
6083         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6084         return;
6085     }
6086     switch (rB(ctx->opcode)) {
6087     case 0:
6088         gen_helper_4xx_tlbre_hi(cpu_gpr[rD(ctx->opcode)], cpu_env,
6089                                 cpu_gpr[rA(ctx->opcode)]);
6090         break;
6091     case 1:
6092         gen_helper_4xx_tlbre_lo(cpu_gpr[rD(ctx->opcode)], cpu_env,
6093                                 cpu_gpr[rA(ctx->opcode)]);
6094         break;
6095     default:
6096         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
6097         break;
6098     }
6099 #endif
6100 }
6101
6102 /* tlbsx - tlbsx. */
6103 static void gen_tlbsx_40x(DisasContext *ctx)
6104 {
6105 #if defined(CONFIG_USER_ONLY)
6106     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6107 #else
6108     TCGv t0;
6109     if (unlikely(!ctx->mem_idx)) {
6110         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6111         return;
6112     }
6113     t0 = tcg_temp_new();
6114     gen_addr_reg_index(ctx, t0);
6115     gen_helper_4xx_tlbsx(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
6116     tcg_temp_free(t0);
6117     if (Rc(ctx->opcode)) {
6118         int l1 = gen_new_label();
6119         tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
6120         tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rD(ctx->opcode)], -1, l1);
6121         tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
6122         gen_set_label(l1);
6123     }
6124 #endif
6125 }
6126
6127 /* tlbwe */
6128 static void gen_tlbwe_40x(DisasContext *ctx)
6129 {
6130 #if defined(CONFIG_USER_ONLY)
6131     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6132 #else
6133     if (unlikely(!ctx->mem_idx)) {
6134         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6135         return;
6136     }
6137     switch (rB(ctx->opcode)) {
6138     case 0:
6139         gen_helper_4xx_tlbwe_hi(cpu_env, cpu_gpr[rA(ctx->opcode)],
6140                                 cpu_gpr[rS(ctx->opcode)]);
6141         break;
6142     case 1:
6143         gen_helper_4xx_tlbwe_lo(cpu_env, cpu_gpr[rA(ctx->opcode)],
6144                                 cpu_gpr[rS(ctx->opcode)]);
6145         break;
6146     default:
6147         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
6148         break;
6149     }
6150 #endif
6151 }
6152
6153 /* TLB management - PowerPC 440 implementation */
6154
6155 /* tlbre */
6156 static void gen_tlbre_440(DisasContext *ctx)
6157 {
6158 #if defined(CONFIG_USER_ONLY)
6159     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6160 #else
6161     if (unlikely(!ctx->mem_idx)) {
6162         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6163         return;
6164     }
6165     switch (rB(ctx->opcode)) {
6166     case 0:
6167     case 1:
6168     case 2:
6169         {
6170             TCGv_i32 t0 = tcg_const_i32(rB(ctx->opcode));
6171             gen_helper_440_tlbre(cpu_gpr[rD(ctx->opcode)], cpu_env,
6172                                  t0, cpu_gpr[rA(ctx->opcode)]);
6173             tcg_temp_free_i32(t0);
6174         }
6175         break;
6176     default:
6177         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
6178         break;
6179     }
6180 #endif
6181 }
6182
6183 /* tlbsx - tlbsx. */
6184 static void gen_tlbsx_440(DisasContext *ctx)
6185 {
6186 #if defined(CONFIG_USER_ONLY)
6187     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6188 #else
6189     TCGv t0;
6190     if (unlikely(!ctx->mem_idx)) {
6191         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6192         return;
6193     }
6194     t0 = tcg_temp_new();
6195     gen_addr_reg_index(ctx, t0);
6196     gen_helper_440_tlbsx(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
6197     tcg_temp_free(t0);
6198     if (Rc(ctx->opcode)) {
6199         int l1 = gen_new_label();
6200         tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
6201         tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rD(ctx->opcode)], -1, l1);
6202         tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
6203         gen_set_label(l1);
6204     }
6205 #endif
6206 }
6207
6208 /* tlbwe */
6209 static void gen_tlbwe_440(DisasContext *ctx)
6210 {
6211 #if defined(CONFIG_USER_ONLY)
6212     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6213 #else
6214     if (unlikely(!ctx->mem_idx)) {
6215         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6216         return;
6217     }
6218     switch (rB(ctx->opcode)) {
6219     case 0:
6220     case 1:
6221     case 2:
6222         {
6223             TCGv_i32 t0 = tcg_const_i32(rB(ctx->opcode));
6224             gen_helper_440_tlbwe(cpu_env, t0, cpu_gpr[rA(ctx->opcode)],
6225                                  cpu_gpr[rS(ctx->opcode)]);
6226             tcg_temp_free_i32(t0);
6227         }
6228         break;
6229     default:
6230         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
6231         break;
6232     }
6233 #endif
6234 }
6235
6236 /* TLB management - PowerPC BookE 2.06 implementation */
6237
6238 /* tlbre */
6239 static void gen_tlbre_booke206(DisasContext *ctx)
6240 {
6241 #if defined(CONFIG_USER_ONLY)
6242     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6243 #else
6244     if (unlikely(!ctx->mem_idx)) {
6245         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6246         return;
6247     }
6248
6249     gen_helper_booke206_tlbre(cpu_env);
6250 #endif
6251 }
6252
6253 /* tlbsx - tlbsx. */
6254 static void gen_tlbsx_booke206(DisasContext *ctx)
6255 {
6256 #if defined(CONFIG_USER_ONLY)
6257     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6258 #else
6259     TCGv t0;
6260     if (unlikely(!ctx->mem_idx)) {
6261         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6262         return;
6263     }
6264
6265     if (rA(ctx->opcode)) {
6266         t0 = tcg_temp_new();
6267         tcg_gen_mov_tl(t0, cpu_gpr[rD(ctx->opcode)]);
6268     } else {
6269         t0 = tcg_const_tl(0);
6270     }
6271
6272     tcg_gen_add_tl(t0, t0, cpu_gpr[rB(ctx->opcode)]);
6273     gen_helper_booke206_tlbsx(cpu_env, t0);
6274 #endif
6275 }
6276
6277 /* tlbwe */
6278 static void gen_tlbwe_booke206(DisasContext *ctx)
6279 {
6280 #if defined(CONFIG_USER_ONLY)
6281     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6282 #else
6283     if (unlikely(!ctx->mem_idx)) {
6284         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6285         return;
6286     }
6287     gen_update_nip(ctx, ctx->nip - 4);
6288     gen_helper_booke206_tlbwe(cpu_env);
6289 #endif
6290 }
6291
6292 static void gen_tlbivax_booke206(DisasContext *ctx)
6293 {
6294 #if defined(CONFIG_USER_ONLY)
6295     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6296 #else
6297     TCGv t0;
6298     if (unlikely(!ctx->mem_idx)) {
6299         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6300         return;
6301     }
6302
6303     t0 = tcg_temp_new();
6304     gen_addr_reg_index(ctx, t0);
6305
6306     gen_helper_booke206_tlbivax(cpu_env, t0);
6307 #endif
6308 }
6309
6310 static void gen_tlbilx_booke206(DisasContext *ctx)
6311 {
6312 #if defined(CONFIG_USER_ONLY)
6313     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6314 #else
6315     TCGv t0;
6316     if (unlikely(!ctx->mem_idx)) {
6317         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6318         return;
6319     }
6320
6321     t0 = tcg_temp_new();
6322     gen_addr_reg_index(ctx, t0);
6323
6324     switch((ctx->opcode >> 21) & 0x3) {
6325     case 0:
6326         gen_helper_booke206_tlbilx0(cpu_env, t0);
6327         break;
6328     case 1:
6329         gen_helper_booke206_tlbilx1(cpu_env, t0);
6330         break;
6331     case 3:
6332         gen_helper_booke206_tlbilx3(cpu_env, t0);
6333         break;
6334     default:
6335         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
6336         break;
6337     }
6338
6339     tcg_temp_free(t0);
6340 #endif
6341 }
6342
6343
6344 /* wrtee */
6345 static void gen_wrtee(DisasContext *ctx)
6346 {
6347 #if defined(CONFIG_USER_ONLY)
6348     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6349 #else
6350     TCGv t0;
6351     if (unlikely(!ctx->mem_idx)) {
6352         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6353         return;
6354     }
6355     t0 = tcg_temp_new();
6356     tcg_gen_andi_tl(t0, cpu_gpr[rD(ctx->opcode)], (1 << MSR_EE));
6357     tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE));
6358     tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
6359     tcg_temp_free(t0);
6360     /* Stop translation to have a chance to raise an exception
6361      * if we just set msr_ee to 1
6362      */
6363     gen_stop_exception(ctx);
6364 #endif
6365 }
6366
6367 /* wrteei */
6368 static void gen_wrteei(DisasContext *ctx)
6369 {
6370 #if defined(CONFIG_USER_ONLY)
6371     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6372 #else
6373     if (unlikely(!ctx->mem_idx)) {
6374         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6375         return;
6376     }
6377     if (ctx->opcode & 0x00008000) {
6378         tcg_gen_ori_tl(cpu_msr, cpu_msr, (1 << MSR_EE));
6379         /* Stop translation to have a chance to raise an exception */
6380         gen_stop_exception(ctx);
6381     } else {
6382         tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE));
6383     }
6384 #endif
6385 }
6386
6387 /* PowerPC 440 specific instructions */
6388
6389 /* dlmzb */
6390 static void gen_dlmzb(DisasContext *ctx)
6391 {
6392     TCGv_i32 t0 = tcg_const_i32(Rc(ctx->opcode));
6393     gen_helper_dlmzb(cpu_gpr[rA(ctx->opcode)], cpu_env,
6394                      cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], t0);
6395     tcg_temp_free_i32(t0);
6396 }
6397
6398 /* mbar replaces eieio on 440 */
6399 static void gen_mbar(DisasContext *ctx)
6400 {
6401     /* interpreted as no-op */
6402 }
6403
6404 /* msync replaces sync on 440 */
6405 static void gen_msync_4xx(DisasContext *ctx)
6406 {
6407     /* interpreted as no-op */
6408 }
6409
6410 /* icbt */
6411 static void gen_icbt_440(DisasContext *ctx)
6412 {
6413     /* interpreted as no-op */
6414     /* XXX: specification say this is treated as a load by the MMU
6415      *      but does not generate any exception
6416      */
6417 }
6418
6419 /* Embedded.Processor Control */
6420
6421 static void gen_msgclr(DisasContext *ctx)
6422 {
6423 #if defined(CONFIG_USER_ONLY)
6424     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6425 #else
6426     if (unlikely(ctx->mem_idx == 0)) {
6427         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6428         return;
6429     }
6430
6431     gen_helper_msgclr(cpu_env, cpu_gpr[rB(ctx->opcode)]);
6432 #endif
6433 }
6434
6435 static void gen_msgsnd(DisasContext *ctx)
6436 {
6437 #if defined(CONFIG_USER_ONLY)
6438     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6439 #else
6440     if (unlikely(ctx->mem_idx == 0)) {
6441         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6442         return;
6443     }
6444
6445     gen_helper_msgsnd(cpu_gpr[rB(ctx->opcode)]);
6446 #endif
6447 }
6448
6449 /***                      Altivec vector extension                         ***/
6450 /* Altivec registers moves */
6451
6452 static inline TCGv_ptr gen_avr_ptr(int reg)
6453 {
6454     TCGv_ptr r = tcg_temp_new_ptr();
6455     tcg_gen_addi_ptr(r, cpu_env, offsetof(CPUPPCState, avr[reg]));
6456     return r;
6457 }
6458
6459 #define GEN_VR_LDX(name, opc2, opc3)                                          \
6460 static void glue(gen_, name)(DisasContext *ctx)                                       \
6461 {                                                                             \
6462     TCGv EA;                                                                  \
6463     if (unlikely(!ctx->altivec_enabled)) {                                    \
6464         gen_exception(ctx, POWERPC_EXCP_VPU);                                 \
6465         return;                                                               \
6466     }                                                                         \
6467     gen_set_access_type(ctx, ACCESS_INT);                                     \
6468     EA = tcg_temp_new();                                                      \
6469     gen_addr_reg_index(ctx, EA);                                              \
6470     tcg_gen_andi_tl(EA, EA, ~0xf);                                            \
6471     if (ctx->le_mode) {                                                       \
6472         gen_qemu_ld64(ctx, cpu_avrl[rD(ctx->opcode)], EA);                    \
6473         tcg_gen_addi_tl(EA, EA, 8);                                           \
6474         gen_qemu_ld64(ctx, cpu_avrh[rD(ctx->opcode)], EA);                    \
6475     } else {                                                                  \
6476         gen_qemu_ld64(ctx, cpu_avrh[rD(ctx->opcode)], EA);                    \
6477         tcg_gen_addi_tl(EA, EA, 8);                                           \
6478         gen_qemu_ld64(ctx, cpu_avrl[rD(ctx->opcode)], EA);                    \
6479     }                                                                         \
6480     tcg_temp_free(EA);                                                        \
6481 }
6482
6483 #define GEN_VR_STX(name, opc2, opc3)                                          \
6484 static void gen_st##name(DisasContext *ctx)                                   \
6485 {                                                                             \
6486     TCGv EA;                                                                  \
6487     if (unlikely(!ctx->altivec_enabled)) {                                    \
6488         gen_exception(ctx, POWERPC_EXCP_VPU);                                 \
6489         return;                                                               \
6490     }                                                                         \
6491     gen_set_access_type(ctx, ACCESS_INT);                                     \
6492     EA = tcg_temp_new();                                                      \
6493     gen_addr_reg_index(ctx, EA);                                              \
6494     tcg_gen_andi_tl(EA, EA, ~0xf);                                            \
6495     if (ctx->le_mode) {                                                       \
6496         gen_qemu_st64(ctx, cpu_avrl[rD(ctx->opcode)], EA);                    \
6497         tcg_gen_addi_tl(EA, EA, 8);                                           \
6498         gen_qemu_st64(ctx, cpu_avrh[rD(ctx->opcode)], EA);                    \
6499     } else {                                                                  \
6500         gen_qemu_st64(ctx, cpu_avrh[rD(ctx->opcode)], EA);                    \
6501         tcg_gen_addi_tl(EA, EA, 8);                                           \
6502         gen_qemu_st64(ctx, cpu_avrl[rD(ctx->opcode)], EA);                    \
6503     }                                                                         \
6504     tcg_temp_free(EA);                                                        \
6505 }
6506
6507 #define GEN_VR_LVE(name, opc2, opc3)                                    \
6508 static void gen_lve##name(DisasContext *ctx)                            \
6509     {                                                                   \
6510         TCGv EA;                                                        \
6511         TCGv_ptr rs;                                                    \
6512         if (unlikely(!ctx->altivec_enabled)) {                          \
6513             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
6514             return;                                                     \
6515         }                                                               \
6516         gen_set_access_type(ctx, ACCESS_INT);                           \
6517         EA = tcg_temp_new();                                            \
6518         gen_addr_reg_index(ctx, EA);                                    \
6519         rs = gen_avr_ptr(rS(ctx->opcode));                              \
6520         gen_helper_lve##name(cpu_env, rs, EA);                          \
6521         tcg_temp_free(EA);                                              \
6522         tcg_temp_free_ptr(rs);                                          \
6523     }
6524
6525 #define GEN_VR_STVE(name, opc2, opc3)                                   \
6526 static void gen_stve##name(DisasContext *ctx)                           \
6527     {                                                                   \
6528         TCGv EA;                                                        \
6529         TCGv_ptr rs;                                                    \
6530         if (unlikely(!ctx->altivec_enabled)) {                          \
6531             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
6532             return;                                                     \
6533         }                                                               \
6534         gen_set_access_type(ctx, ACCESS_INT);                           \
6535         EA = tcg_temp_new();                                            \
6536         gen_addr_reg_index(ctx, EA);                                    \
6537         rs = gen_avr_ptr(rS(ctx->opcode));                              \
6538         gen_helper_stve##name(cpu_env, rs, EA);                         \
6539         tcg_temp_free(EA);                                              \
6540         tcg_temp_free_ptr(rs);                                          \
6541     }
6542
6543 GEN_VR_LDX(lvx, 0x07, 0x03);
6544 /* As we don't emulate the cache, lvxl is stricly equivalent to lvx */
6545 GEN_VR_LDX(lvxl, 0x07, 0x0B);
6546
6547 GEN_VR_LVE(bx, 0x07, 0x00);
6548 GEN_VR_LVE(hx, 0x07, 0x01);
6549 GEN_VR_LVE(wx, 0x07, 0x02);
6550
6551 GEN_VR_STX(svx, 0x07, 0x07);
6552 /* As we don't emulate the cache, stvxl is stricly equivalent to stvx */
6553 GEN_VR_STX(svxl, 0x07, 0x0F);
6554
6555 GEN_VR_STVE(bx, 0x07, 0x04);
6556 GEN_VR_STVE(hx, 0x07, 0x05);
6557 GEN_VR_STVE(wx, 0x07, 0x06);
6558
6559 static void gen_lvsl(DisasContext *ctx)
6560 {
6561     TCGv_ptr rd;
6562     TCGv EA;
6563     if (unlikely(!ctx->altivec_enabled)) {
6564         gen_exception(ctx, POWERPC_EXCP_VPU);
6565         return;
6566     }
6567     EA = tcg_temp_new();
6568     gen_addr_reg_index(ctx, EA);
6569     rd = gen_avr_ptr(rD(ctx->opcode));
6570     gen_helper_lvsl(rd, EA);
6571     tcg_temp_free(EA);
6572     tcg_temp_free_ptr(rd);
6573 }
6574
6575 static void gen_lvsr(DisasContext *ctx)
6576 {
6577     TCGv_ptr rd;
6578     TCGv EA;
6579     if (unlikely(!ctx->altivec_enabled)) {
6580         gen_exception(ctx, POWERPC_EXCP_VPU);
6581         return;
6582     }
6583     EA = tcg_temp_new();
6584     gen_addr_reg_index(ctx, EA);
6585     rd = gen_avr_ptr(rD(ctx->opcode));
6586     gen_helper_lvsr(rd, EA);
6587     tcg_temp_free(EA);
6588     tcg_temp_free_ptr(rd);
6589 }
6590
6591 static void gen_mfvscr(DisasContext *ctx)
6592 {
6593     TCGv_i32 t;
6594     if (unlikely(!ctx->altivec_enabled)) {
6595         gen_exception(ctx, POWERPC_EXCP_VPU);
6596         return;
6597     }
6598     tcg_gen_movi_i64(cpu_avrh[rD(ctx->opcode)], 0);
6599     t = tcg_temp_new_i32();
6600     tcg_gen_ld_i32(t, cpu_env, offsetof(CPUPPCState, vscr));
6601     tcg_gen_extu_i32_i64(cpu_avrl[rD(ctx->opcode)], t);
6602     tcg_temp_free_i32(t);
6603 }
6604
6605 static void gen_mtvscr(DisasContext *ctx)
6606 {
6607     TCGv_ptr p;
6608     if (unlikely(!ctx->altivec_enabled)) {
6609         gen_exception(ctx, POWERPC_EXCP_VPU);
6610         return;
6611     }
6612     p = gen_avr_ptr(rD(ctx->opcode));
6613     gen_helper_mtvscr(cpu_env, p);
6614     tcg_temp_free_ptr(p);
6615 }
6616
6617 /* Logical operations */
6618 #define GEN_VX_LOGICAL(name, tcg_op, opc2, opc3)                        \
6619 static void glue(gen_, name)(DisasContext *ctx)                                 \
6620 {                                                                       \
6621     if (unlikely(!ctx->altivec_enabled)) {                              \
6622         gen_exception(ctx, POWERPC_EXCP_VPU);                           \
6623         return;                                                         \
6624     }                                                                   \
6625     tcg_op(cpu_avrh[rD(ctx->opcode)], cpu_avrh[rA(ctx->opcode)], cpu_avrh[rB(ctx->opcode)]); \
6626     tcg_op(cpu_avrl[rD(ctx->opcode)], cpu_avrl[rA(ctx->opcode)], cpu_avrl[rB(ctx->opcode)]); \
6627 }
6628
6629 GEN_VX_LOGICAL(vand, tcg_gen_and_i64, 2, 16);
6630 GEN_VX_LOGICAL(vandc, tcg_gen_andc_i64, 2, 17);
6631 GEN_VX_LOGICAL(vor, tcg_gen_or_i64, 2, 18);
6632 GEN_VX_LOGICAL(vxor, tcg_gen_xor_i64, 2, 19);
6633 GEN_VX_LOGICAL(vnor, tcg_gen_nor_i64, 2, 20);
6634
6635 #define GEN_VXFORM(name, opc2, opc3)                                    \
6636 static void glue(gen_, name)(DisasContext *ctx)                                 \
6637 {                                                                       \
6638     TCGv_ptr ra, rb, rd;                                                \
6639     if (unlikely(!ctx->altivec_enabled)) {                              \
6640         gen_exception(ctx, POWERPC_EXCP_VPU);                           \
6641         return;                                                         \
6642     }                                                                   \
6643     ra = gen_avr_ptr(rA(ctx->opcode));                                  \
6644     rb = gen_avr_ptr(rB(ctx->opcode));                                  \
6645     rd = gen_avr_ptr(rD(ctx->opcode));                                  \
6646     gen_helper_##name (rd, ra, rb);                                     \
6647     tcg_temp_free_ptr(ra);                                              \
6648     tcg_temp_free_ptr(rb);                                              \
6649     tcg_temp_free_ptr(rd);                                              \
6650 }
6651
6652 #define GEN_VXFORM_ENV(name, opc2, opc3)                                \
6653 static void glue(gen_, name)(DisasContext *ctx)                         \
6654 {                                                                       \
6655     TCGv_ptr ra, rb, rd;                                                \
6656     if (unlikely(!ctx->altivec_enabled)) {                              \
6657         gen_exception(ctx, POWERPC_EXCP_VPU);                           \
6658         return;                                                         \
6659     }                                                                   \
6660     ra = gen_avr_ptr(rA(ctx->opcode));                                  \
6661     rb = gen_avr_ptr(rB(ctx->opcode));                                  \
6662     rd = gen_avr_ptr(rD(ctx->opcode));                                  \
6663     gen_helper_##name(cpu_env, rd, ra, rb);                             \
6664     tcg_temp_free_ptr(ra);                                              \
6665     tcg_temp_free_ptr(rb);                                              \
6666     tcg_temp_free_ptr(rd);                                              \
6667 }
6668
6669 GEN_VXFORM(vaddubm, 0, 0);
6670 GEN_VXFORM(vadduhm, 0, 1);
6671 GEN_VXFORM(vadduwm, 0, 2);
6672 GEN_VXFORM(vsububm, 0, 16);
6673 GEN_VXFORM(vsubuhm, 0, 17);
6674 GEN_VXFORM(vsubuwm, 0, 18);
6675 GEN_VXFORM(vmaxub, 1, 0);
6676 GEN_VXFORM(vmaxuh, 1, 1);
6677 GEN_VXFORM(vmaxuw, 1, 2);
6678 GEN_VXFORM(vmaxsb, 1, 4);
6679 GEN_VXFORM(vmaxsh, 1, 5);
6680 GEN_VXFORM(vmaxsw, 1, 6);
6681 GEN_VXFORM(vminub, 1, 8);
6682 GEN_VXFORM(vminuh, 1, 9);
6683 GEN_VXFORM(vminuw, 1, 10);
6684 GEN_VXFORM(vminsb, 1, 12);
6685 GEN_VXFORM(vminsh, 1, 13);
6686 GEN_VXFORM(vminsw, 1, 14);
6687 GEN_VXFORM(vavgub, 1, 16);
6688 GEN_VXFORM(vavguh, 1, 17);
6689 GEN_VXFORM(vavguw, 1, 18);
6690 GEN_VXFORM(vavgsb, 1, 20);
6691 GEN_VXFORM(vavgsh, 1, 21);
6692 GEN_VXFORM(vavgsw, 1, 22);
6693 GEN_VXFORM(vmrghb, 6, 0);
6694 GEN_VXFORM(vmrghh, 6, 1);
6695 GEN_VXFORM(vmrghw, 6, 2);
6696 GEN_VXFORM(vmrglb, 6, 4);
6697 GEN_VXFORM(vmrglh, 6, 5);
6698 GEN_VXFORM(vmrglw, 6, 6);
6699 GEN_VXFORM(vmuloub, 4, 0);
6700 GEN_VXFORM(vmulouh, 4, 1);
6701 GEN_VXFORM(vmulosb, 4, 4);
6702 GEN_VXFORM(vmulosh, 4, 5);
6703 GEN_VXFORM(vmuleub, 4, 8);
6704 GEN_VXFORM(vmuleuh, 4, 9);
6705 GEN_VXFORM(vmulesb, 4, 12);
6706 GEN_VXFORM(vmulesh, 4, 13);
6707 GEN_VXFORM(vslb, 2, 4);
6708 GEN_VXFORM(vslh, 2, 5);
6709 GEN_VXFORM(vslw, 2, 6);
6710 GEN_VXFORM(vsrb, 2, 8);
6711 GEN_VXFORM(vsrh, 2, 9);
6712 GEN_VXFORM(vsrw, 2, 10);
6713 GEN_VXFORM(vsrab, 2, 12);
6714 GEN_VXFORM(vsrah, 2, 13);
6715 GEN_VXFORM(vsraw, 2, 14);
6716 GEN_VXFORM(vslo, 6, 16);
6717 GEN_VXFORM(vsro, 6, 17);
6718 GEN_VXFORM(vaddcuw, 0, 6);
6719 GEN_VXFORM(vsubcuw, 0, 22);
6720 GEN_VXFORM_ENV(vaddubs, 0, 8);
6721 GEN_VXFORM_ENV(vadduhs, 0, 9);
6722 GEN_VXFORM_ENV(vadduws, 0, 10);
6723 GEN_VXFORM_ENV(vaddsbs, 0, 12);
6724 GEN_VXFORM_ENV(vaddshs, 0, 13);
6725 GEN_VXFORM_ENV(vaddsws, 0, 14);
6726 GEN_VXFORM_ENV(vsububs, 0, 24);
6727 GEN_VXFORM_ENV(vsubuhs, 0, 25);
6728 GEN_VXFORM_ENV(vsubuws, 0, 26);
6729 GEN_VXFORM_ENV(vsubsbs, 0, 28);
6730 GEN_VXFORM_ENV(vsubshs, 0, 29);
6731 GEN_VXFORM_ENV(vsubsws, 0, 30);
6732 GEN_VXFORM(vrlb, 2, 0);
6733 GEN_VXFORM(vrlh, 2, 1);
6734 GEN_VXFORM(vrlw, 2, 2);
6735 GEN_VXFORM(vsl, 2, 7);
6736 GEN_VXFORM(vsr, 2, 11);
6737 GEN_VXFORM_ENV(vpkuhum, 7, 0);
6738 GEN_VXFORM_ENV(vpkuwum, 7, 1);
6739 GEN_VXFORM_ENV(vpkuhus, 7, 2);
6740 GEN_VXFORM_ENV(vpkuwus, 7, 3);
6741 GEN_VXFORM_ENV(vpkshus, 7, 4);
6742 GEN_VXFORM_ENV(vpkswus, 7, 5);
6743 GEN_VXFORM_ENV(vpkshss, 7, 6);
6744 GEN_VXFORM_ENV(vpkswss, 7, 7);
6745 GEN_VXFORM(vpkpx, 7, 12);
6746 GEN_VXFORM_ENV(vsum4ubs, 4, 24);
6747 GEN_VXFORM_ENV(vsum4sbs, 4, 28);
6748 GEN_VXFORM_ENV(vsum4shs, 4, 25);
6749 GEN_VXFORM_ENV(vsum2sws, 4, 26);
6750 GEN_VXFORM_ENV(vsumsws, 4, 30);
6751 GEN_VXFORM_ENV(vaddfp, 5, 0);
6752 GEN_VXFORM_ENV(vsubfp, 5, 1);
6753 GEN_VXFORM_ENV(vmaxfp, 5, 16);
6754 GEN_VXFORM_ENV(vminfp, 5, 17);
6755
6756 #define GEN_VXRFORM1(opname, name, str, opc2, opc3)                     \
6757 static void glue(gen_, name)(DisasContext *ctx)                         \
6758     {                                                                   \
6759         TCGv_ptr ra, rb, rd;                                            \
6760         if (unlikely(!ctx->altivec_enabled)) {                          \
6761             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
6762             return;                                                     \
6763         }                                                               \
6764         ra = gen_avr_ptr(rA(ctx->opcode));                              \
6765         rb = gen_avr_ptr(rB(ctx->opcode));                              \
6766         rd = gen_avr_ptr(rD(ctx->opcode));                              \
6767         gen_helper_##opname(cpu_env, rd, ra, rb);                       \
6768         tcg_temp_free_ptr(ra);                                          \
6769         tcg_temp_free_ptr(rb);                                          \
6770         tcg_temp_free_ptr(rd);                                          \
6771     }
6772
6773 #define GEN_VXRFORM(name, opc2, opc3)                                \
6774     GEN_VXRFORM1(name, name, #name, opc2, opc3)                      \
6775     GEN_VXRFORM1(name##_dot, name##_, #name ".", opc2, (opc3 | (0x1 << 4)))
6776
6777 GEN_VXRFORM(vcmpequb, 3, 0)
6778 GEN_VXRFORM(vcmpequh, 3, 1)
6779 GEN_VXRFORM(vcmpequw, 3, 2)
6780 GEN_VXRFORM(vcmpgtsb, 3, 12)
6781 GEN_VXRFORM(vcmpgtsh, 3, 13)
6782 GEN_VXRFORM(vcmpgtsw, 3, 14)
6783 GEN_VXRFORM(vcmpgtub, 3, 8)
6784 GEN_VXRFORM(vcmpgtuh, 3, 9)
6785 GEN_VXRFORM(vcmpgtuw, 3, 10)
6786 GEN_VXRFORM(vcmpeqfp, 3, 3)
6787 GEN_VXRFORM(vcmpgefp, 3, 7)
6788 GEN_VXRFORM(vcmpgtfp, 3, 11)
6789 GEN_VXRFORM(vcmpbfp, 3, 15)
6790
6791 #define GEN_VXFORM_SIMM(name, opc2, opc3)                               \
6792 static void glue(gen_, name)(DisasContext *ctx)                         \
6793     {                                                                   \
6794         TCGv_ptr rd;                                                    \
6795         TCGv_i32 simm;                                                  \
6796         if (unlikely(!ctx->altivec_enabled)) {                          \
6797             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
6798             return;                                                     \
6799         }                                                               \
6800         simm = tcg_const_i32(SIMM5(ctx->opcode));                       \
6801         rd = gen_avr_ptr(rD(ctx->opcode));                              \
6802         gen_helper_##name (rd, simm);                                   \
6803         tcg_temp_free_i32(simm);                                        \
6804         tcg_temp_free_ptr(rd);                                          \
6805     }
6806
6807 GEN_VXFORM_SIMM(vspltisb, 6, 12);
6808 GEN_VXFORM_SIMM(vspltish, 6, 13);
6809 GEN_VXFORM_SIMM(vspltisw, 6, 14);
6810
6811 #define GEN_VXFORM_NOA(name, opc2, opc3)                                \
6812 static void glue(gen_, name)(DisasContext *ctx)                                 \
6813     {                                                                   \
6814         TCGv_ptr rb, rd;                                                \
6815         if (unlikely(!ctx->altivec_enabled)) {                          \
6816             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
6817             return;                                                     \
6818         }                                                               \
6819         rb = gen_avr_ptr(rB(ctx->opcode));                              \
6820         rd = gen_avr_ptr(rD(ctx->opcode));                              \
6821         gen_helper_##name (rd, rb);                                     \
6822         tcg_temp_free_ptr(rb);                                          \
6823         tcg_temp_free_ptr(rd);                                         \
6824     }
6825
6826 #define GEN_VXFORM_NOA_ENV(name, opc2, opc3)                            \
6827 static void glue(gen_, name)(DisasContext *ctx)                         \
6828     {                                                                   \
6829         TCGv_ptr rb, rd;                                                \
6830                                                                         \
6831         if (unlikely(!ctx->altivec_enabled)) {                          \
6832             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
6833             return;                                                     \
6834         }                                                               \
6835         rb = gen_avr_ptr(rB(ctx->opcode));                              \
6836         rd = gen_avr_ptr(rD(ctx->opcode));                              \
6837         gen_helper_##name(cpu_env, rd, rb);                             \
6838         tcg_temp_free_ptr(rb);                                          \
6839         tcg_temp_free_ptr(rd);                                          \
6840     }
6841
6842 GEN_VXFORM_NOA(vupkhsb, 7, 8);
6843 GEN_VXFORM_NOA(vupkhsh, 7, 9);
6844 GEN_VXFORM_NOA(vupklsb, 7, 10);
6845 GEN_VXFORM_NOA(vupklsh, 7, 11);
6846 GEN_VXFORM_NOA(vupkhpx, 7, 13);
6847 GEN_VXFORM_NOA(vupklpx, 7, 15);
6848 GEN_VXFORM_NOA_ENV(vrefp, 5, 4);
6849 GEN_VXFORM_NOA_ENV(vrsqrtefp, 5, 5);
6850 GEN_VXFORM_NOA_ENV(vexptefp, 5, 6);
6851 GEN_VXFORM_NOA_ENV(vlogefp, 5, 7);
6852 GEN_VXFORM_NOA_ENV(vrfim, 5, 8);
6853 GEN_VXFORM_NOA_ENV(vrfin, 5, 9);
6854 GEN_VXFORM_NOA_ENV(vrfip, 5, 10);
6855 GEN_VXFORM_NOA_ENV(vrfiz, 5, 11);
6856
6857 #define GEN_VXFORM_SIMM(name, opc2, opc3)                               \
6858 static void glue(gen_, name)(DisasContext *ctx)                                 \
6859     {                                                                   \
6860         TCGv_ptr rd;                                                    \
6861         TCGv_i32 simm;                                                  \
6862         if (unlikely(!ctx->altivec_enabled)) {                          \
6863             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
6864             return;                                                     \
6865         }                                                               \
6866         simm = tcg_const_i32(SIMM5(ctx->opcode));                       \
6867         rd = gen_avr_ptr(rD(ctx->opcode));                              \
6868         gen_helper_##name (rd, simm);                                   \
6869         tcg_temp_free_i32(simm);                                        \
6870         tcg_temp_free_ptr(rd);                                          \
6871     }
6872
6873 #define GEN_VXFORM_UIMM(name, opc2, opc3)                               \
6874 static void glue(gen_, name)(DisasContext *ctx)                                 \
6875     {                                                                   \
6876         TCGv_ptr rb, rd;                                                \
6877         TCGv_i32 uimm;                                                  \
6878         if (unlikely(!ctx->altivec_enabled)) {                          \
6879             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
6880             return;                                                     \
6881         }                                                               \
6882         uimm = tcg_const_i32(UIMM5(ctx->opcode));                       \
6883         rb = gen_avr_ptr(rB(ctx->opcode));                              \
6884         rd = gen_avr_ptr(rD(ctx->opcode));                              \
6885         gen_helper_##name (rd, rb, uimm);                               \
6886         tcg_temp_free_i32(uimm);                                        \
6887         tcg_temp_free_ptr(rb);                                          \
6888         tcg_temp_free_ptr(rd);                                          \
6889     }
6890
6891 #define GEN_VXFORM_UIMM_ENV(name, opc2, opc3)                           \
6892 static void glue(gen_, name)(DisasContext *ctx)                         \
6893     {                                                                   \
6894         TCGv_ptr rb, rd;                                                \
6895         TCGv_i32 uimm;                                                  \
6896                                                                         \
6897         if (unlikely(!ctx->altivec_enabled)) {                          \
6898             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
6899             return;                                                     \
6900         }                                                               \
6901         uimm = tcg_const_i32(UIMM5(ctx->opcode));                       \
6902         rb = gen_avr_ptr(rB(ctx->opcode));                              \
6903         rd = gen_avr_ptr(rD(ctx->opcode));                              \
6904         gen_helper_##name(cpu_env, rd, rb, uimm);                       \
6905         tcg_temp_free_i32(uimm);                                        \
6906         tcg_temp_free_ptr(rb);                                          \
6907         tcg_temp_free_ptr(rd);                                          \
6908     }
6909
6910 GEN_VXFORM_UIMM(vspltb, 6, 8);
6911 GEN_VXFORM_UIMM(vsplth, 6, 9);
6912 GEN_VXFORM_UIMM(vspltw, 6, 10);
6913 GEN_VXFORM_UIMM_ENV(vcfux, 5, 12);
6914 GEN_VXFORM_UIMM_ENV(vcfsx, 5, 13);
6915 GEN_VXFORM_UIMM_ENV(vctuxs, 5, 14);
6916 GEN_VXFORM_UIMM_ENV(vctsxs, 5, 15);
6917
6918 static void gen_vsldoi(DisasContext *ctx)
6919 {
6920     TCGv_ptr ra, rb, rd;
6921     TCGv_i32 sh;
6922     if (unlikely(!ctx->altivec_enabled)) {
6923         gen_exception(ctx, POWERPC_EXCP_VPU);
6924         return;
6925     }
6926     ra = gen_avr_ptr(rA(ctx->opcode));
6927     rb = gen_avr_ptr(rB(ctx->opcode));
6928     rd = gen_avr_ptr(rD(ctx->opcode));
6929     sh = tcg_const_i32(VSH(ctx->opcode));
6930     gen_helper_vsldoi (rd, ra, rb, sh);
6931     tcg_temp_free_ptr(ra);
6932     tcg_temp_free_ptr(rb);
6933     tcg_temp_free_ptr(rd);
6934     tcg_temp_free_i32(sh);
6935 }
6936
6937 #define GEN_VAFORM_PAIRED(name0, name1, opc2)                           \
6938 static void glue(gen_, name0##_##name1)(DisasContext *ctx)              \
6939     {                                                                   \
6940         TCGv_ptr ra, rb, rc, rd;                                        \
6941         if (unlikely(!ctx->altivec_enabled)) {                          \
6942             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
6943             return;                                                     \
6944         }                                                               \
6945         ra = gen_avr_ptr(rA(ctx->opcode));                              \
6946         rb = gen_avr_ptr(rB(ctx->opcode));                              \
6947         rc = gen_avr_ptr(rC(ctx->opcode));                              \
6948         rd = gen_avr_ptr(rD(ctx->opcode));                              \
6949         if (Rc(ctx->opcode)) {                                          \
6950             gen_helper_##name1(cpu_env, rd, ra, rb, rc);                \
6951         } else {                                                        \
6952             gen_helper_##name0(cpu_env, rd, ra, rb, rc);                \
6953         }                                                               \
6954         tcg_temp_free_ptr(ra);                                          \
6955         tcg_temp_free_ptr(rb);                                          \
6956         tcg_temp_free_ptr(rc);                                          \
6957         tcg_temp_free_ptr(rd);                                          \
6958     }
6959
6960 GEN_VAFORM_PAIRED(vmhaddshs, vmhraddshs, 16)
6961
6962 static void gen_vmladduhm(DisasContext *ctx)
6963 {
6964     TCGv_ptr ra, rb, rc, rd;
6965     if (unlikely(!ctx->altivec_enabled)) {
6966         gen_exception(ctx, POWERPC_EXCP_VPU);
6967         return;
6968     }
6969     ra = gen_avr_ptr(rA(ctx->opcode));
6970     rb = gen_avr_ptr(rB(ctx->opcode));
6971     rc = gen_avr_ptr(rC(ctx->opcode));
6972     rd = gen_avr_ptr(rD(ctx->opcode));
6973     gen_helper_vmladduhm(rd, ra, rb, rc);
6974     tcg_temp_free_ptr(ra);
6975     tcg_temp_free_ptr(rb);
6976     tcg_temp_free_ptr(rc);
6977     tcg_temp_free_ptr(rd);
6978 }
6979
6980 GEN_VAFORM_PAIRED(vmsumubm, vmsummbm, 18)
6981 GEN_VAFORM_PAIRED(vmsumuhm, vmsumuhs, 19)
6982 GEN_VAFORM_PAIRED(vmsumshm, vmsumshs, 20)
6983 GEN_VAFORM_PAIRED(vsel, vperm, 21)
6984 GEN_VAFORM_PAIRED(vmaddfp, vnmsubfp, 23)
6985
6986 /***                           VSX extension                               ***/
6987
6988 static inline TCGv_i64 cpu_vsrh(int n)
6989 {
6990     if (n < 32) {
6991         return cpu_fpr[n];
6992     } else {
6993         return cpu_avrh[n-32];
6994     }
6995 }
6996
6997 static inline TCGv_i64 cpu_vsrl(int n)
6998 {
6999     if (n < 32) {
7000         return cpu_vsr[n];
7001     } else {
7002         return cpu_avrl[n-32];
7003     }
7004 }
7005
7006 /***                           SPE extension                               ***/
7007 /* Register moves */
7008
7009
7010 static inline void gen_evmra(DisasContext *ctx)
7011 {
7012
7013     if (unlikely(!ctx->spe_enabled)) {
7014         gen_exception(ctx, POWERPC_EXCP_SPEU);
7015         return;
7016     }
7017
7018 #if defined(TARGET_PPC64)
7019     /* rD := rA */
7020     tcg_gen_mov_i64(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
7021
7022     /* spe_acc := rA */
7023     tcg_gen_st_i64(cpu_gpr[rA(ctx->opcode)],
7024                    cpu_env,
7025                    offsetof(CPUPPCState, spe_acc));
7026 #else
7027     TCGv_i64 tmp = tcg_temp_new_i64();
7028
7029     /* tmp := rA_lo + rA_hi << 32 */
7030     tcg_gen_concat_i32_i64(tmp, cpu_gpr[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
7031
7032     /* spe_acc := tmp */
7033     tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUPPCState, spe_acc));
7034     tcg_temp_free_i64(tmp);
7035
7036     /* rD := rA */
7037     tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
7038     tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
7039 #endif
7040 }
7041
7042 static inline void gen_load_gpr64(TCGv_i64 t, int reg)
7043 {
7044 #if defined(TARGET_PPC64)
7045     tcg_gen_mov_i64(t, cpu_gpr[reg]);
7046 #else
7047     tcg_gen_concat_i32_i64(t, cpu_gpr[reg], cpu_gprh[reg]);
7048 #endif
7049 }
7050
7051 static inline void gen_store_gpr64(int reg, TCGv_i64 t)
7052 {
7053 #if defined(TARGET_PPC64)
7054     tcg_gen_mov_i64(cpu_gpr[reg], t);
7055 #else
7056     TCGv_i64 tmp = tcg_temp_new_i64();
7057     tcg_gen_trunc_i64_i32(cpu_gpr[reg], t);
7058     tcg_gen_shri_i64(tmp, t, 32);
7059     tcg_gen_trunc_i64_i32(cpu_gprh[reg], tmp);
7060     tcg_temp_free_i64(tmp);
7061 #endif
7062 }
7063
7064 #define GEN_SPE(name0, name1, opc2, opc3, inval0, inval1, type)         \
7065 static void glue(gen_, name0##_##name1)(DisasContext *ctx)                    \
7066 {                                                                             \
7067     if (Rc(ctx->opcode))                                                      \
7068         gen_##name1(ctx);                                                     \
7069     else                                                                      \
7070         gen_##name0(ctx);                                                     \
7071 }
7072
7073 /* Handler for undefined SPE opcodes */
7074 static inline void gen_speundef(DisasContext *ctx)
7075 {
7076     gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
7077 }
7078
7079 /* SPE logic */
7080 #if defined(TARGET_PPC64)
7081 #define GEN_SPEOP_LOGIC2(name, tcg_op)                                        \
7082 static inline void gen_##name(DisasContext *ctx)                              \
7083 {                                                                             \
7084     if (unlikely(!ctx->spe_enabled)) {                                        \
7085         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
7086         return;                                                               \
7087     }                                                                         \
7088     tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],                \
7089            cpu_gpr[rB(ctx->opcode)]);                                         \
7090 }
7091 #else
7092 #define GEN_SPEOP_LOGIC2(name, tcg_op)                                        \
7093 static inline void gen_##name(DisasContext *ctx)                              \
7094 {                                                                             \
7095     if (unlikely(!ctx->spe_enabled)) {                                        \
7096         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
7097         return;                                                               \
7098     }                                                                         \
7099     tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],                \
7100            cpu_gpr[rB(ctx->opcode)]);                                         \
7101     tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],              \
7102            cpu_gprh[rB(ctx->opcode)]);                                        \
7103 }
7104 #endif
7105
7106 GEN_SPEOP_LOGIC2(evand, tcg_gen_and_tl);
7107 GEN_SPEOP_LOGIC2(evandc, tcg_gen_andc_tl);
7108 GEN_SPEOP_LOGIC2(evxor, tcg_gen_xor_tl);
7109 GEN_SPEOP_LOGIC2(evor, tcg_gen_or_tl);
7110 GEN_SPEOP_LOGIC2(evnor, tcg_gen_nor_tl);
7111 GEN_SPEOP_LOGIC2(eveqv, tcg_gen_eqv_tl);
7112 GEN_SPEOP_LOGIC2(evorc, tcg_gen_orc_tl);
7113 GEN_SPEOP_LOGIC2(evnand, tcg_gen_nand_tl);
7114
7115 /* SPE logic immediate */
7116 #if defined(TARGET_PPC64)
7117 #define GEN_SPEOP_TCG_LOGIC_IMM2(name, tcg_opi)                               \
7118 static inline void gen_##name(DisasContext *ctx)                              \
7119 {                                                                             \
7120     if (unlikely(!ctx->spe_enabled)) {                                        \
7121         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
7122         return;                                                               \
7123     }                                                                         \
7124     TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
7125     TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
7126     TCGv_i64 t2 = tcg_temp_local_new_i64();                                   \
7127     tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]);                      \
7128     tcg_opi(t0, t0, rB(ctx->opcode));                                         \
7129     tcg_gen_shri_i64(t2, cpu_gpr[rA(ctx->opcode)], 32);                       \
7130     tcg_gen_trunc_i64_i32(t1, t2);                                            \
7131     tcg_temp_free_i64(t2);                                                    \
7132     tcg_opi(t1, t1, rB(ctx->opcode));                                         \
7133     tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);                 \
7134     tcg_temp_free_i32(t0);                                                    \
7135     tcg_temp_free_i32(t1);                                                    \
7136 }
7137 #else
7138 #define GEN_SPEOP_TCG_LOGIC_IMM2(name, tcg_opi)                               \
7139 static inline void gen_##name(DisasContext *ctx)                              \
7140 {                                                                             \
7141     if (unlikely(!ctx->spe_enabled)) {                                        \
7142         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
7143         return;                                                               \
7144     }                                                                         \
7145     tcg_opi(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],               \
7146             rB(ctx->opcode));                                                 \
7147     tcg_opi(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],             \
7148             rB(ctx->opcode));                                                 \
7149 }
7150 #endif
7151 GEN_SPEOP_TCG_LOGIC_IMM2(evslwi, tcg_gen_shli_i32);
7152 GEN_SPEOP_TCG_LOGIC_IMM2(evsrwiu, tcg_gen_shri_i32);
7153 GEN_SPEOP_TCG_LOGIC_IMM2(evsrwis, tcg_gen_sari_i32);
7154 GEN_SPEOP_TCG_LOGIC_IMM2(evrlwi, tcg_gen_rotli_i32);
7155
7156 /* SPE arithmetic */
7157 #if defined(TARGET_PPC64)
7158 #define GEN_SPEOP_ARITH1(name, tcg_op)                                        \
7159 static inline void gen_##name(DisasContext *ctx)                              \
7160 {                                                                             \
7161     if (unlikely(!ctx->spe_enabled)) {                                        \
7162         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
7163         return;                                                               \
7164     }                                                                         \
7165     TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
7166     TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
7167     TCGv_i64 t2 = tcg_temp_local_new_i64();                                   \
7168     tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]);                      \
7169     tcg_op(t0, t0);                                                           \
7170     tcg_gen_shri_i64(t2, cpu_gpr[rA(ctx->opcode)], 32);                       \
7171     tcg_gen_trunc_i64_i32(t1, t2);                                            \
7172     tcg_temp_free_i64(t2);                                                    \
7173     tcg_op(t1, t1);                                                           \
7174     tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);                 \
7175     tcg_temp_free_i32(t0);                                                    \
7176     tcg_temp_free_i32(t1);                                                    \
7177 }
7178 #else
7179 #define GEN_SPEOP_ARITH1(name, tcg_op)                                        \
7180 static inline void gen_##name(DisasContext *ctx)                              \
7181 {                                                                             \
7182     if (unlikely(!ctx->spe_enabled)) {                                        \
7183         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
7184         return;                                                               \
7185     }                                                                         \
7186     tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);               \
7187     tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);             \
7188 }
7189 #endif
7190
7191 static inline void gen_op_evabs(TCGv_i32 ret, TCGv_i32 arg1)
7192 {
7193     int l1 = gen_new_label();
7194     int l2 = gen_new_label();
7195
7196     tcg_gen_brcondi_i32(TCG_COND_GE, arg1, 0, l1);
7197     tcg_gen_neg_i32(ret, arg1);
7198     tcg_gen_br(l2);
7199     gen_set_label(l1);
7200     tcg_gen_mov_i32(ret, arg1);
7201     gen_set_label(l2);
7202 }
7203 GEN_SPEOP_ARITH1(evabs, gen_op_evabs);
7204 GEN_SPEOP_ARITH1(evneg, tcg_gen_neg_i32);
7205 GEN_SPEOP_ARITH1(evextsb, tcg_gen_ext8s_i32);
7206 GEN_SPEOP_ARITH1(evextsh, tcg_gen_ext16s_i32);
7207 static inline void gen_op_evrndw(TCGv_i32 ret, TCGv_i32 arg1)
7208 {
7209     tcg_gen_addi_i32(ret, arg1, 0x8000);
7210     tcg_gen_ext16u_i32(ret, ret);
7211 }
7212 GEN_SPEOP_ARITH1(evrndw, gen_op_evrndw);
7213 GEN_SPEOP_ARITH1(evcntlsw, gen_helper_cntlsw32);
7214 GEN_SPEOP_ARITH1(evcntlzw, gen_helper_cntlzw32);
7215
7216 #if defined(TARGET_PPC64)
7217 #define GEN_SPEOP_ARITH2(name, tcg_op)                                        \
7218 static inline void gen_##name(DisasContext *ctx)                              \
7219 {                                                                             \
7220     if (unlikely(!ctx->spe_enabled)) {                                        \
7221         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
7222         return;                                                               \
7223     }                                                                         \
7224     TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
7225     TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
7226     TCGv_i32 t2 = tcg_temp_local_new_i32();                                   \
7227     TCGv_i64 t3 = tcg_temp_local_new_i64();                                   \
7228     tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]);                      \
7229     tcg_gen_trunc_i64_i32(t2, cpu_gpr[rB(ctx->opcode)]);                      \
7230     tcg_op(t0, t0, t2);                                                       \
7231     tcg_gen_shri_i64(t3, cpu_gpr[rA(ctx->opcode)], 32);                       \
7232     tcg_gen_trunc_i64_i32(t1, t3);                                            \
7233     tcg_gen_shri_i64(t3, cpu_gpr[rB(ctx->opcode)], 32);                       \
7234     tcg_gen_trunc_i64_i32(t2, t3);                                            \
7235     tcg_temp_free_i64(t3);                                                    \
7236     tcg_op(t1, t1, t2);                                                       \
7237     tcg_temp_free_i32(t2);                                                    \
7238     tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);                 \
7239     tcg_temp_free_i32(t0);                                                    \
7240     tcg_temp_free_i32(t1);                                                    \
7241 }
7242 #else
7243 #define GEN_SPEOP_ARITH2(name, tcg_op)                                        \
7244 static inline void gen_##name(DisasContext *ctx)                              \
7245 {                                                                             \
7246     if (unlikely(!ctx->spe_enabled)) {                                        \
7247         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
7248         return;                                                               \
7249     }                                                                         \
7250     tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],                \
7251            cpu_gpr[rB(ctx->opcode)]);                                         \
7252     tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],              \
7253            cpu_gprh[rB(ctx->opcode)]);                                        \
7254 }
7255 #endif
7256
7257 static inline void gen_op_evsrwu(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
7258 {
7259     TCGv_i32 t0;
7260     int l1, l2;
7261
7262     l1 = gen_new_label();
7263     l2 = gen_new_label();
7264     t0 = tcg_temp_local_new_i32();
7265     /* No error here: 6 bits are used */
7266     tcg_gen_andi_i32(t0, arg2, 0x3F);
7267     tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1);
7268     tcg_gen_shr_i32(ret, arg1, t0);
7269     tcg_gen_br(l2);
7270     gen_set_label(l1);
7271     tcg_gen_movi_i32(ret, 0);
7272     gen_set_label(l2);
7273     tcg_temp_free_i32(t0);
7274 }
7275 GEN_SPEOP_ARITH2(evsrwu, gen_op_evsrwu);
7276 static inline void gen_op_evsrws(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
7277 {
7278     TCGv_i32 t0;
7279     int l1, l2;
7280
7281     l1 = gen_new_label();
7282     l2 = gen_new_label();
7283     t0 = tcg_temp_local_new_i32();
7284     /* No error here: 6 bits are used */
7285     tcg_gen_andi_i32(t0, arg2, 0x3F);
7286     tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1);
7287     tcg_gen_sar_i32(ret, arg1, t0);
7288     tcg_gen_br(l2);
7289     gen_set_label(l1);
7290     tcg_gen_movi_i32(ret, 0);
7291     gen_set_label(l2);
7292     tcg_temp_free_i32(t0);
7293 }
7294 GEN_SPEOP_ARITH2(evsrws, gen_op_evsrws);
7295 static inline void gen_op_evslw(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
7296 {
7297     TCGv_i32 t0;
7298     int l1, l2;
7299
7300     l1 = gen_new_label();
7301     l2 = gen_new_label();
7302     t0 = tcg_temp_local_new_i32();
7303     /* No error here: 6 bits are used */
7304     tcg_gen_andi_i32(t0, arg2, 0x3F);
7305     tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1);
7306     tcg_gen_shl_i32(ret, arg1, t0);
7307     tcg_gen_br(l2);
7308     gen_set_label(l1);
7309     tcg_gen_movi_i32(ret, 0);
7310     gen_set_label(l2);
7311     tcg_temp_free_i32(t0);
7312 }
7313 GEN_SPEOP_ARITH2(evslw, gen_op_evslw);
7314 static inline void gen_op_evrlw(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
7315 {
7316     TCGv_i32 t0 = tcg_temp_new_i32();
7317     tcg_gen_andi_i32(t0, arg2, 0x1F);
7318     tcg_gen_rotl_i32(ret, arg1, t0);
7319     tcg_temp_free_i32(t0);
7320 }
7321 GEN_SPEOP_ARITH2(evrlw, gen_op_evrlw);
7322 static inline void gen_evmergehi(DisasContext *ctx)
7323 {
7324     if (unlikely(!ctx->spe_enabled)) {
7325         gen_exception(ctx, POWERPC_EXCP_SPEU);
7326         return;
7327     }
7328 #if defined(TARGET_PPC64)
7329     TCGv t0 = tcg_temp_new();
7330     TCGv t1 = tcg_temp_new();
7331     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 32);
7332     tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], 0xFFFFFFFF0000000ULL);
7333     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
7334     tcg_temp_free(t0);
7335     tcg_temp_free(t1);
7336 #else
7337     tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
7338     tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
7339 #endif
7340 }
7341 GEN_SPEOP_ARITH2(evaddw, tcg_gen_add_i32);
7342 static inline void gen_op_evsubf(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
7343 {
7344     tcg_gen_sub_i32(ret, arg2, arg1);
7345 }
7346 GEN_SPEOP_ARITH2(evsubfw, gen_op_evsubf);
7347
7348 /* SPE arithmetic immediate */
7349 #if defined(TARGET_PPC64)
7350 #define GEN_SPEOP_ARITH_IMM2(name, tcg_op)                                    \
7351 static inline void gen_##name(DisasContext *ctx)                              \
7352 {                                                                             \
7353     if (unlikely(!ctx->spe_enabled)) {                                        \
7354         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
7355         return;                                                               \
7356     }                                                                         \
7357     TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
7358     TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
7359     TCGv_i64 t2 = tcg_temp_local_new_i64();                                   \
7360     tcg_gen_trunc_i64_i32(t0, cpu_gpr[rB(ctx->opcode)]);                      \
7361     tcg_op(t0, t0, rA(ctx->opcode));                                          \
7362     tcg_gen_shri_i64(t2, cpu_gpr[rB(ctx->opcode)], 32);                       \
7363     tcg_gen_trunc_i64_i32(t1, t2);                                            \
7364     tcg_temp_free_i64(t2);                                                    \
7365     tcg_op(t1, t1, rA(ctx->opcode));                                          \
7366     tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);                 \
7367     tcg_temp_free_i32(t0);                                                    \
7368     tcg_temp_free_i32(t1);                                                    \
7369 }
7370 #else
7371 #define GEN_SPEOP_ARITH_IMM2(name, tcg_op)                                    \
7372 static inline void gen_##name(DisasContext *ctx)                              \
7373 {                                                                             \
7374     if (unlikely(!ctx->spe_enabled)) {                                        \
7375         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
7376         return;                                                               \
7377     }                                                                         \
7378     tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],                \
7379            rA(ctx->opcode));                                                  \
7380     tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)],              \
7381            rA(ctx->opcode));                                                  \
7382 }
7383 #endif
7384 GEN_SPEOP_ARITH_IMM2(evaddiw, tcg_gen_addi_i32);
7385 GEN_SPEOP_ARITH_IMM2(evsubifw, tcg_gen_subi_i32);
7386
7387 /* SPE comparison */
7388 #if defined(TARGET_PPC64)
7389 #define GEN_SPEOP_COMP(name, tcg_cond)                                        \
7390 static inline void gen_##name(DisasContext *ctx)                              \
7391 {                                                                             \
7392     if (unlikely(!ctx->spe_enabled)) {                                        \
7393         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
7394         return;                                                               \
7395     }                                                                         \
7396     int l1 = gen_new_label();                                                 \
7397     int l2 = gen_new_label();                                                 \
7398     int l3 = gen_new_label();                                                 \
7399     int l4 = gen_new_label();                                                 \
7400     TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
7401     TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
7402     TCGv_i64 t2 = tcg_temp_local_new_i64();                                   \
7403     tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]);                      \
7404     tcg_gen_trunc_i64_i32(t1, cpu_gpr[rB(ctx->opcode)]);                      \
7405     tcg_gen_brcond_i32(tcg_cond, t0, t1, l1);                                 \
7406     tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)], 0);                          \
7407     tcg_gen_br(l2);                                                           \
7408     gen_set_label(l1);                                                        \
7409     tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)],                              \
7410                      CRF_CL | CRF_CH_OR_CL | CRF_CH_AND_CL);                  \
7411     gen_set_label(l2);                                                        \
7412     tcg_gen_shri_i64(t2, cpu_gpr[rA(ctx->opcode)], 32);                       \
7413     tcg_gen_trunc_i64_i32(t0, t2);                                            \
7414     tcg_gen_shri_i64(t2, cpu_gpr[rB(ctx->opcode)], 32);                       \
7415     tcg_gen_trunc_i64_i32(t1, t2);                                            \
7416     tcg_temp_free_i64(t2);                                                    \
7417     tcg_gen_brcond_i32(tcg_cond, t0, t1, l3);                                 \
7418     tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)],  \
7419                      ~(CRF_CH | CRF_CH_AND_CL));                              \
7420     tcg_gen_br(l4);                                                           \
7421     gen_set_label(l3);                                                        \
7422     tcg_gen_ori_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)],   \
7423                     CRF_CH | CRF_CH_OR_CL);                                   \
7424     gen_set_label(l4);                                                        \
7425     tcg_temp_free_i32(t0);                                                    \
7426     tcg_temp_free_i32(t1);                                                    \
7427 }
7428 #else
7429 #define GEN_SPEOP_COMP(name, tcg_cond)                                        \
7430 static inline void gen_##name(DisasContext *ctx)                              \
7431 {                                                                             \
7432     if (unlikely(!ctx->spe_enabled)) {                                        \
7433         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
7434         return;                                                               \
7435     }                                                                         \
7436     int l1 = gen_new_label();                                                 \
7437     int l2 = gen_new_label();                                                 \
7438     int l3 = gen_new_label();                                                 \
7439     int l4 = gen_new_label();                                                 \
7440                                                                               \
7441     tcg_gen_brcond_i32(tcg_cond, cpu_gpr[rA(ctx->opcode)],                    \
7442                        cpu_gpr[rB(ctx->opcode)], l1);                         \
7443     tcg_gen_movi_tl(cpu_crf[crfD(ctx->opcode)], 0);                           \
7444     tcg_gen_br(l2);                                                           \
7445     gen_set_label(l1);                                                        \
7446     tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)],                              \
7447                      CRF_CL | CRF_CH_OR_CL | CRF_CH_AND_CL);                  \
7448     gen_set_label(l2);                                                        \
7449     tcg_gen_brcond_i32(tcg_cond, cpu_gprh[rA(ctx->opcode)],                   \
7450                        cpu_gprh[rB(ctx->opcode)], l3);                        \
7451     tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)],  \
7452                      ~(CRF_CH | CRF_CH_AND_CL));                              \
7453     tcg_gen_br(l4);                                                           \
7454     gen_set_label(l3);                                                        \
7455     tcg_gen_ori_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)],   \
7456                     CRF_CH | CRF_CH_OR_CL);                                   \
7457     gen_set_label(l4);                                                        \
7458 }
7459 #endif
7460 GEN_SPEOP_COMP(evcmpgtu, TCG_COND_GTU);
7461 GEN_SPEOP_COMP(evcmpgts, TCG_COND_GT);
7462 GEN_SPEOP_COMP(evcmpltu, TCG_COND_LTU);
7463 GEN_SPEOP_COMP(evcmplts, TCG_COND_LT);
7464 GEN_SPEOP_COMP(evcmpeq, TCG_COND_EQ);
7465
7466 /* SPE misc */
7467 static inline void gen_brinc(DisasContext *ctx)
7468 {
7469     /* Note: brinc is usable even if SPE is disabled */
7470     gen_helper_brinc(cpu_gpr[rD(ctx->opcode)],
7471                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
7472 }
7473 static inline void gen_evmergelo(DisasContext *ctx)
7474 {
7475     if (unlikely(!ctx->spe_enabled)) {
7476         gen_exception(ctx, POWERPC_EXCP_SPEU);
7477         return;
7478     }
7479 #if defined(TARGET_PPC64)
7480     TCGv t0 = tcg_temp_new();
7481     TCGv t1 = tcg_temp_new();
7482     tcg_gen_ext32u_tl(t0, cpu_gpr[rB(ctx->opcode)]);
7483     tcg_gen_shli_tl(t1, cpu_gpr[rA(ctx->opcode)], 32);
7484     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
7485     tcg_temp_free(t0);
7486     tcg_temp_free(t1);
7487 #else
7488     tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
7489     tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
7490 #endif
7491 }
7492 static inline void gen_evmergehilo(DisasContext *ctx)
7493 {
7494     if (unlikely(!ctx->spe_enabled)) {
7495         gen_exception(ctx, POWERPC_EXCP_SPEU);
7496         return;
7497     }
7498 #if defined(TARGET_PPC64)
7499     TCGv t0 = tcg_temp_new();
7500     TCGv t1 = tcg_temp_new();
7501     tcg_gen_ext32u_tl(t0, cpu_gpr[rB(ctx->opcode)]);
7502     tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], 0xFFFFFFFF0000000ULL);
7503     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
7504     tcg_temp_free(t0);
7505     tcg_temp_free(t1);
7506 #else
7507     tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
7508     tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
7509 #endif
7510 }
7511 static inline void gen_evmergelohi(DisasContext *ctx)
7512 {
7513     if (unlikely(!ctx->spe_enabled)) {
7514         gen_exception(ctx, POWERPC_EXCP_SPEU);
7515         return;
7516     }
7517 #if defined(TARGET_PPC64)
7518     TCGv t0 = tcg_temp_new();
7519     TCGv t1 = tcg_temp_new();
7520     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 32);
7521     tcg_gen_shli_tl(t1, cpu_gpr[rA(ctx->opcode)], 32);
7522     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
7523     tcg_temp_free(t0);
7524     tcg_temp_free(t1);
7525 #else
7526     if (rD(ctx->opcode) == rA(ctx->opcode)) {
7527         TCGv_i32 tmp = tcg_temp_new_i32();
7528         tcg_gen_mov_i32(tmp, cpu_gpr[rA(ctx->opcode)]);
7529         tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
7530         tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], tmp);
7531         tcg_temp_free_i32(tmp);
7532     } else {
7533         tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
7534         tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
7535     }
7536 #endif
7537 }
7538 static inline void gen_evsplati(DisasContext *ctx)
7539 {
7540     uint64_t imm = ((int32_t)(rA(ctx->opcode) << 27)) >> 27;
7541
7542 #if defined(TARGET_PPC64)
7543     tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], (imm << 32) | imm);
7544 #else
7545     tcg_gen_movi_i32(cpu_gpr[rD(ctx->opcode)], imm);
7546     tcg_gen_movi_i32(cpu_gprh[rD(ctx->opcode)], imm);
7547 #endif
7548 }
7549 static inline void gen_evsplatfi(DisasContext *ctx)
7550 {
7551     uint64_t imm = rA(ctx->opcode) << 27;
7552
7553 #if defined(TARGET_PPC64)
7554     tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], (imm << 32) | imm);
7555 #else
7556     tcg_gen_movi_i32(cpu_gpr[rD(ctx->opcode)], imm);
7557     tcg_gen_movi_i32(cpu_gprh[rD(ctx->opcode)], imm);
7558 #endif
7559 }
7560
7561 static inline void gen_evsel(DisasContext *ctx)
7562 {
7563     int l1 = gen_new_label();
7564     int l2 = gen_new_label();
7565     int l3 = gen_new_label();
7566     int l4 = gen_new_label();
7567     TCGv_i32 t0 = tcg_temp_local_new_i32();
7568 #if defined(TARGET_PPC64)
7569     TCGv t1 = tcg_temp_local_new();
7570     TCGv t2 = tcg_temp_local_new();
7571 #endif
7572     tcg_gen_andi_i32(t0, cpu_crf[ctx->opcode & 0x07], 1 << 3);
7573     tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
7574 #if defined(TARGET_PPC64)
7575     tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], 0xFFFFFFFF00000000ULL);
7576 #else
7577     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
7578 #endif
7579     tcg_gen_br(l2);
7580     gen_set_label(l1);
7581 #if defined(TARGET_PPC64)
7582     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0xFFFFFFFF00000000ULL);
7583 #else
7584     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
7585 #endif
7586     gen_set_label(l2);
7587     tcg_gen_andi_i32(t0, cpu_crf[ctx->opcode & 0x07], 1 << 2);
7588     tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l3);
7589 #if defined(TARGET_PPC64)
7590     tcg_gen_ext32u_tl(t2, cpu_gpr[rA(ctx->opcode)]);
7591 #else
7592     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
7593 #endif
7594     tcg_gen_br(l4);
7595     gen_set_label(l3);
7596 #if defined(TARGET_PPC64)
7597     tcg_gen_ext32u_tl(t2, cpu_gpr[rB(ctx->opcode)]);
7598 #else
7599     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
7600 #endif
7601     gen_set_label(l4);
7602     tcg_temp_free_i32(t0);
7603 #if defined(TARGET_PPC64)
7604     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t1, t2);
7605     tcg_temp_free(t1);
7606     tcg_temp_free(t2);
7607 #endif
7608 }
7609
7610 static void gen_evsel0(DisasContext *ctx)
7611 {
7612     gen_evsel(ctx);
7613 }
7614
7615 static void gen_evsel1(DisasContext *ctx)
7616 {
7617     gen_evsel(ctx);
7618 }
7619
7620 static void gen_evsel2(DisasContext *ctx)
7621 {
7622     gen_evsel(ctx);
7623 }
7624
7625 static void gen_evsel3(DisasContext *ctx)
7626 {
7627     gen_evsel(ctx);
7628 }
7629
7630 /* Multiply */
7631
7632 static inline void gen_evmwumi(DisasContext *ctx)
7633 {
7634     TCGv_i64 t0, t1;
7635
7636     if (unlikely(!ctx->spe_enabled)) {
7637         gen_exception(ctx, POWERPC_EXCP_SPEU);
7638         return;
7639     }
7640
7641     t0 = tcg_temp_new_i64();
7642     t1 = tcg_temp_new_i64();
7643
7644     /* t0 := rA; t1 := rB */
7645 #if defined(TARGET_PPC64)
7646     tcg_gen_ext32u_tl(t0, cpu_gpr[rA(ctx->opcode)]);
7647     tcg_gen_ext32u_tl(t1, cpu_gpr[rB(ctx->opcode)]);
7648 #else
7649     tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
7650     tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
7651 #endif
7652
7653     tcg_gen_mul_i64(t0, t0, t1);  /* t0 := rA * rB */
7654
7655     gen_store_gpr64(rD(ctx->opcode), t0); /* rD := t0 */
7656
7657     tcg_temp_free_i64(t0);
7658     tcg_temp_free_i64(t1);
7659 }
7660
7661 static inline void gen_evmwumia(DisasContext *ctx)
7662 {
7663     TCGv_i64 tmp;
7664
7665     if (unlikely(!ctx->spe_enabled)) {
7666         gen_exception(ctx, POWERPC_EXCP_SPEU);
7667         return;
7668     }
7669
7670     gen_evmwumi(ctx);            /* rD := rA * rB */
7671
7672     tmp = tcg_temp_new_i64();
7673
7674     /* acc := rD */
7675     gen_load_gpr64(tmp, rD(ctx->opcode));
7676     tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUPPCState, spe_acc));
7677     tcg_temp_free_i64(tmp);
7678 }
7679
7680 static inline void gen_evmwumiaa(DisasContext *ctx)
7681 {
7682     TCGv_i64 acc;
7683     TCGv_i64 tmp;
7684
7685     if (unlikely(!ctx->spe_enabled)) {
7686         gen_exception(ctx, POWERPC_EXCP_SPEU);
7687         return;
7688     }
7689
7690     gen_evmwumi(ctx);           /* rD := rA * rB */
7691
7692     acc = tcg_temp_new_i64();
7693     tmp = tcg_temp_new_i64();
7694
7695     /* tmp := rD */
7696     gen_load_gpr64(tmp, rD(ctx->opcode));
7697
7698     /* Load acc */
7699     tcg_gen_ld_i64(acc, cpu_env, offsetof(CPUPPCState, spe_acc));
7700
7701     /* acc := tmp + acc */
7702     tcg_gen_add_i64(acc, acc, tmp);
7703
7704     /* Store acc */
7705     tcg_gen_st_i64(acc, cpu_env, offsetof(CPUPPCState, spe_acc));
7706
7707     /* rD := acc */
7708     gen_store_gpr64(rD(ctx->opcode), acc);
7709
7710     tcg_temp_free_i64(acc);
7711     tcg_temp_free_i64(tmp);
7712 }
7713
7714 static inline void gen_evmwsmi(DisasContext *ctx)
7715 {
7716     TCGv_i64 t0, t1;
7717
7718     if (unlikely(!ctx->spe_enabled)) {
7719         gen_exception(ctx, POWERPC_EXCP_SPEU);
7720         return;
7721     }
7722
7723     t0 = tcg_temp_new_i64();
7724     t1 = tcg_temp_new_i64();
7725
7726     /* t0 := rA; t1 := rB */
7727 #if defined(TARGET_PPC64)
7728     tcg_gen_ext32s_tl(t0, cpu_gpr[rA(ctx->opcode)]);
7729     tcg_gen_ext32s_tl(t1, cpu_gpr[rB(ctx->opcode)]);
7730 #else
7731     tcg_gen_ext_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
7732     tcg_gen_ext_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
7733 #endif
7734
7735     tcg_gen_mul_i64(t0, t0, t1);  /* t0 := rA * rB */
7736
7737     gen_store_gpr64(rD(ctx->opcode), t0); /* rD := t0 */
7738
7739     tcg_temp_free_i64(t0);
7740     tcg_temp_free_i64(t1);
7741 }
7742
7743 static inline void gen_evmwsmia(DisasContext *ctx)
7744 {
7745     TCGv_i64 tmp;
7746
7747     gen_evmwsmi(ctx);            /* rD := rA * rB */
7748
7749     tmp = tcg_temp_new_i64();
7750
7751     /* acc := rD */
7752     gen_load_gpr64(tmp, rD(ctx->opcode));
7753     tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUPPCState, spe_acc));
7754
7755     tcg_temp_free_i64(tmp);
7756 }
7757
7758 static inline void gen_evmwsmiaa(DisasContext *ctx)
7759 {
7760     TCGv_i64 acc = tcg_temp_new_i64();
7761     TCGv_i64 tmp = tcg_temp_new_i64();
7762
7763     gen_evmwsmi(ctx);           /* rD := rA * rB */
7764
7765     acc = tcg_temp_new_i64();
7766     tmp = tcg_temp_new_i64();
7767
7768     /* tmp := rD */
7769     gen_load_gpr64(tmp, rD(ctx->opcode));
7770
7771     /* Load acc */
7772     tcg_gen_ld_i64(acc, cpu_env, offsetof(CPUPPCState, spe_acc));
7773
7774     /* acc := tmp + acc */
7775     tcg_gen_add_i64(acc, acc, tmp);
7776
7777     /* Store acc */
7778     tcg_gen_st_i64(acc, cpu_env, offsetof(CPUPPCState, spe_acc));
7779
7780     /* rD := acc */
7781     gen_store_gpr64(rD(ctx->opcode), acc);
7782
7783     tcg_temp_free_i64(acc);
7784     tcg_temp_free_i64(tmp);
7785 }
7786
7787 GEN_SPE(evaddw,      speundef,    0x00, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE); ////
7788 GEN_SPE(evaddiw,     speundef,    0x01, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE);
7789 GEN_SPE(evsubfw,     speundef,    0x02, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE); ////
7790 GEN_SPE(evsubifw,    speundef,    0x03, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE);
7791 GEN_SPE(evabs,       evneg,       0x04, 0x08, 0x0000F800, 0x0000F800, PPC_SPE); ////
7792 GEN_SPE(evextsb,     evextsh,     0x05, 0x08, 0x0000F800, 0x0000F800, PPC_SPE); ////
7793 GEN_SPE(evrndw,      evcntlzw,    0x06, 0x08, 0x0000F800, 0x0000F800, PPC_SPE); ////
7794 GEN_SPE(evcntlsw,    brinc,       0x07, 0x08, 0x0000F800, 0x00000000, PPC_SPE); //
7795 GEN_SPE(evmra,       speundef,    0x02, 0x13, 0x0000F800, 0xFFFFFFFF, PPC_SPE);
7796 GEN_SPE(speundef,    evand,       0x08, 0x08, 0xFFFFFFFF, 0x00000000, PPC_SPE); ////
7797 GEN_SPE(evandc,      speundef,    0x09, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE); ////
7798 GEN_SPE(evxor,       evor,        0x0B, 0x08, 0x00000000, 0x00000000, PPC_SPE); ////
7799 GEN_SPE(evnor,       eveqv,       0x0C, 0x08, 0x00000000, 0x00000000, PPC_SPE); ////
7800 GEN_SPE(evmwumi,     evmwsmi,     0x0C, 0x11, 0x00000000, 0x00000000, PPC_SPE);
7801 GEN_SPE(evmwumia,    evmwsmia,    0x1C, 0x11, 0x00000000, 0x00000000, PPC_SPE);
7802 GEN_SPE(evmwumiaa,   evmwsmiaa,   0x0C, 0x15, 0x00000000, 0x00000000, PPC_SPE);
7803 GEN_SPE(speundef,    evorc,       0x0D, 0x08, 0xFFFFFFFF, 0x00000000, PPC_SPE); ////
7804 GEN_SPE(evnand,      speundef,    0x0F, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE); ////
7805 GEN_SPE(evsrwu,      evsrws,      0x10, 0x08, 0x00000000, 0x00000000, PPC_SPE); ////
7806 GEN_SPE(evsrwiu,     evsrwis,     0x11, 0x08, 0x00000000, 0x00000000, PPC_SPE);
7807 GEN_SPE(evslw,       speundef,    0x12, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE); ////
7808 GEN_SPE(evslwi,      speundef,    0x13, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE);
7809 GEN_SPE(evrlw,       evsplati,    0x14, 0x08, 0x00000000, 0x0000F800, PPC_SPE); //
7810 GEN_SPE(evrlwi,      evsplatfi,   0x15, 0x08, 0x00000000, 0x0000F800, PPC_SPE);
7811 GEN_SPE(evmergehi,   evmergelo,   0x16, 0x08, 0x00000000, 0x00000000, PPC_SPE); ////
7812 GEN_SPE(evmergehilo, evmergelohi, 0x17, 0x08, 0x00000000, 0x00000000, PPC_SPE); ////
7813 GEN_SPE(evcmpgtu,    evcmpgts,    0x18, 0x08, 0x00600000, 0x00600000, PPC_SPE); ////
7814 GEN_SPE(evcmpltu,    evcmplts,    0x19, 0x08, 0x00600000, 0x00600000, PPC_SPE); ////
7815 GEN_SPE(evcmpeq,     speundef,    0x1A, 0x08, 0x00600000, 0xFFFFFFFF, PPC_SPE); ////
7816
7817 /* SPE load and stores */
7818 static inline void gen_addr_spe_imm_index(DisasContext *ctx, TCGv EA, int sh)
7819 {
7820     target_ulong uimm = rB(ctx->opcode);
7821
7822     if (rA(ctx->opcode) == 0) {
7823         tcg_gen_movi_tl(EA, uimm << sh);
7824     } else {
7825         tcg_gen_addi_tl(EA, cpu_gpr[rA(ctx->opcode)], uimm << sh);
7826         if (NARROW_MODE(ctx)) {
7827             tcg_gen_ext32u_tl(EA, EA);
7828         }
7829     }
7830 }
7831
7832 static inline void gen_op_evldd(DisasContext *ctx, TCGv addr)
7833 {
7834 #if defined(TARGET_PPC64)
7835     gen_qemu_ld64(ctx, cpu_gpr[rD(ctx->opcode)], addr);
7836 #else
7837     TCGv_i64 t0 = tcg_temp_new_i64();
7838     gen_qemu_ld64(ctx, t0, addr);
7839     tcg_gen_trunc_i64_i32(cpu_gpr[rD(ctx->opcode)], t0);
7840     tcg_gen_shri_i64(t0, t0, 32);
7841     tcg_gen_trunc_i64_i32(cpu_gprh[rD(ctx->opcode)], t0);
7842     tcg_temp_free_i64(t0);
7843 #endif
7844 }
7845
7846 static inline void gen_op_evldw(DisasContext *ctx, TCGv addr)
7847 {
7848 #if defined(TARGET_PPC64)
7849     TCGv t0 = tcg_temp_new();
7850     gen_qemu_ld32u(ctx, t0, addr);
7851     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32);
7852     gen_addr_add(ctx, addr, addr, 4);
7853     gen_qemu_ld32u(ctx, t0, addr);
7854     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7855     tcg_temp_free(t0);
7856 #else
7857     gen_qemu_ld32u(ctx, cpu_gprh[rD(ctx->opcode)], addr);
7858     gen_addr_add(ctx, addr, addr, 4);
7859     gen_qemu_ld32u(ctx, cpu_gpr[rD(ctx->opcode)], addr);
7860 #endif
7861 }
7862
7863 static inline void gen_op_evldh(DisasContext *ctx, TCGv addr)
7864 {
7865     TCGv t0 = tcg_temp_new();
7866 #if defined(TARGET_PPC64)
7867     gen_qemu_ld16u(ctx, t0, addr);
7868     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48);
7869     gen_addr_add(ctx, addr, addr, 2);
7870     gen_qemu_ld16u(ctx, t0, addr);
7871     tcg_gen_shli_tl(t0, t0, 32);
7872     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7873     gen_addr_add(ctx, addr, addr, 2);
7874     gen_qemu_ld16u(ctx, t0, addr);
7875     tcg_gen_shli_tl(t0, t0, 16);
7876     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7877     gen_addr_add(ctx, addr, addr, 2);
7878     gen_qemu_ld16u(ctx, t0, addr);
7879     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7880 #else
7881     gen_qemu_ld16u(ctx, t0, addr);
7882     tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
7883     gen_addr_add(ctx, addr, addr, 2);
7884     gen_qemu_ld16u(ctx, t0, addr);
7885     tcg_gen_or_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0);
7886     gen_addr_add(ctx, addr, addr, 2);
7887     gen_qemu_ld16u(ctx, t0, addr);
7888     tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
7889     gen_addr_add(ctx, addr, addr, 2);
7890     gen_qemu_ld16u(ctx, t0, addr);
7891     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7892 #endif
7893     tcg_temp_free(t0);
7894 }
7895
7896 static inline void gen_op_evlhhesplat(DisasContext *ctx, TCGv addr)
7897 {
7898     TCGv t0 = tcg_temp_new();
7899     gen_qemu_ld16u(ctx, t0, addr);
7900 #if defined(TARGET_PPC64)
7901     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48);
7902     tcg_gen_shli_tl(t0, t0, 16);
7903     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7904 #else
7905     tcg_gen_shli_tl(t0, t0, 16);
7906     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
7907     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
7908 #endif
7909     tcg_temp_free(t0);
7910 }
7911
7912 static inline void gen_op_evlhhousplat(DisasContext *ctx, TCGv addr)
7913 {
7914     TCGv t0 = tcg_temp_new();
7915     gen_qemu_ld16u(ctx, t0, addr);
7916 #if defined(TARGET_PPC64)
7917     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32);
7918     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7919 #else
7920     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
7921     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
7922 #endif
7923     tcg_temp_free(t0);
7924 }
7925
7926 static inline void gen_op_evlhhossplat(DisasContext *ctx, TCGv addr)
7927 {
7928     TCGv t0 = tcg_temp_new();
7929     gen_qemu_ld16s(ctx, t0, addr);
7930 #if defined(TARGET_PPC64)
7931     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32);
7932     tcg_gen_ext32u_tl(t0, t0);
7933     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7934 #else
7935     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
7936     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
7937 #endif
7938     tcg_temp_free(t0);
7939 }
7940
7941 static inline void gen_op_evlwhe(DisasContext *ctx, TCGv addr)
7942 {
7943     TCGv t0 = tcg_temp_new();
7944 #if defined(TARGET_PPC64)
7945     gen_qemu_ld16u(ctx, t0, addr);
7946     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48);
7947     gen_addr_add(ctx, addr, addr, 2);
7948     gen_qemu_ld16u(ctx, t0, addr);
7949     tcg_gen_shli_tl(t0, t0, 16);
7950     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7951 #else
7952     gen_qemu_ld16u(ctx, t0, addr);
7953     tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
7954     gen_addr_add(ctx, addr, addr, 2);
7955     gen_qemu_ld16u(ctx, t0, addr);
7956     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 16);
7957 #endif
7958     tcg_temp_free(t0);
7959 }
7960
7961 static inline void gen_op_evlwhou(DisasContext *ctx, TCGv addr)
7962 {
7963 #if defined(TARGET_PPC64)
7964     TCGv t0 = tcg_temp_new();
7965     gen_qemu_ld16u(ctx, cpu_gpr[rD(ctx->opcode)], addr);
7966     gen_addr_add(ctx, addr, addr, 2);
7967     gen_qemu_ld16u(ctx, t0, addr);
7968     tcg_gen_shli_tl(t0, t0, 32);
7969     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7970     tcg_temp_free(t0);
7971 #else
7972     gen_qemu_ld16u(ctx, cpu_gprh[rD(ctx->opcode)], addr);
7973     gen_addr_add(ctx, addr, addr, 2);
7974     gen_qemu_ld16u(ctx, cpu_gpr[rD(ctx->opcode)], addr);
7975 #endif
7976 }
7977
7978 static inline void gen_op_evlwhos(DisasContext *ctx, TCGv addr)
7979 {
7980 #if defined(TARGET_PPC64)
7981     TCGv t0 = tcg_temp_new();
7982     gen_qemu_ld16s(ctx, t0, addr);
7983     tcg_gen_ext32u_tl(cpu_gpr[rD(ctx->opcode)], t0);
7984     gen_addr_add(ctx, addr, addr, 2);
7985     gen_qemu_ld16s(ctx, t0, addr);
7986     tcg_gen_shli_tl(t0, t0, 32);
7987     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7988     tcg_temp_free(t0);
7989 #else
7990     gen_qemu_ld16s(ctx, cpu_gprh[rD(ctx->opcode)], addr);
7991     gen_addr_add(ctx, addr, addr, 2);
7992     gen_qemu_ld16s(ctx, cpu_gpr[rD(ctx->opcode)], addr);
7993 #endif
7994 }
7995
7996 static inline void gen_op_evlwwsplat(DisasContext *ctx, TCGv addr)
7997 {
7998     TCGv t0 = tcg_temp_new();
7999     gen_qemu_ld32u(ctx, t0, addr);
8000 #if defined(TARGET_PPC64)
8001     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32);
8002     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
8003 #else
8004     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
8005     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
8006 #endif
8007     tcg_temp_free(t0);
8008 }
8009
8010 static inline void gen_op_evlwhsplat(DisasContext *ctx, TCGv addr)
8011 {
8012     TCGv t0 = tcg_temp_new();
8013 #if defined(TARGET_PPC64)
8014     gen_qemu_ld16u(ctx, t0, addr);
8015     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48);
8016     tcg_gen_shli_tl(t0, t0, 32);
8017     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
8018     gen_addr_add(ctx, addr, addr, 2);
8019     gen_qemu_ld16u(ctx, t0, addr);
8020     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
8021     tcg_gen_shli_tl(t0, t0, 16);
8022     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
8023 #else
8024     gen_qemu_ld16u(ctx, t0, addr);
8025     tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
8026     tcg_gen_or_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0);
8027     gen_addr_add(ctx, addr, addr, 2);
8028     gen_qemu_ld16u(ctx, t0, addr);
8029     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 16);
8030     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0);
8031 #endif
8032     tcg_temp_free(t0);
8033 }
8034
8035 static inline void gen_op_evstdd(DisasContext *ctx, TCGv addr)
8036 {
8037 #if defined(TARGET_PPC64)
8038     gen_qemu_st64(ctx, cpu_gpr[rS(ctx->opcode)], addr);
8039 #else
8040     TCGv_i64 t0 = tcg_temp_new_i64();
8041     tcg_gen_concat_i32_i64(t0, cpu_gpr[rS(ctx->opcode)], cpu_gprh[rS(ctx->opcode)]);
8042     gen_qemu_st64(ctx, t0, addr);
8043     tcg_temp_free_i64(t0);
8044 #endif
8045 }
8046
8047 static inline void gen_op_evstdw(DisasContext *ctx, TCGv addr)
8048 {
8049 #if defined(TARGET_PPC64)
8050     TCGv t0 = tcg_temp_new();
8051     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32);
8052     gen_qemu_st32(ctx, t0, addr);
8053     tcg_temp_free(t0);
8054 #else
8055     gen_qemu_st32(ctx, cpu_gprh[rS(ctx->opcode)], addr);
8056 #endif
8057     gen_addr_add(ctx, addr, addr, 4);
8058     gen_qemu_st32(ctx, cpu_gpr[rS(ctx->opcode)], addr);
8059 }
8060
8061 static inline void gen_op_evstdh(DisasContext *ctx, TCGv addr)
8062 {
8063     TCGv t0 = tcg_temp_new();
8064 #if defined(TARGET_PPC64)
8065     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 48);
8066 #else
8067     tcg_gen_shri_tl(t0, cpu_gprh[rS(ctx->opcode)], 16);
8068 #endif
8069     gen_qemu_st16(ctx, t0, addr);
8070     gen_addr_add(ctx, addr, addr, 2);
8071 #if defined(TARGET_PPC64)
8072     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32);
8073     gen_qemu_st16(ctx, t0, addr);
8074 #else
8075     gen_qemu_st16(ctx, cpu_gprh[rS(ctx->opcode)], addr);
8076 #endif
8077     gen_addr_add(ctx, addr, addr, 2);
8078     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 16);
8079     gen_qemu_st16(ctx, t0, addr);
8080     tcg_temp_free(t0);
8081     gen_addr_add(ctx, addr, addr, 2);
8082     gen_qemu_st16(ctx, cpu_gpr[rS(ctx->opcode)], addr);
8083 }
8084
8085 static inline void gen_op_evstwhe(DisasContext *ctx, TCGv addr)
8086 {
8087     TCGv t0 = tcg_temp_new();
8088 #if defined(TARGET_PPC64)
8089     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 48);
8090 #else
8091     tcg_gen_shri_tl(t0, cpu_gprh[rS(ctx->opcode)], 16);
8092 #endif
8093     gen_qemu_st16(ctx, t0, addr);
8094     gen_addr_add(ctx, addr, addr, 2);
8095     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 16);
8096     gen_qemu_st16(ctx, t0, addr);
8097     tcg_temp_free(t0);
8098 }
8099
8100 static inline void gen_op_evstwho(DisasContext *ctx, TCGv addr)
8101 {
8102 #if defined(TARGET_PPC64)
8103     TCGv t0 = tcg_temp_new();
8104     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32);
8105     gen_qemu_st16(ctx, t0, addr);
8106     tcg_temp_free(t0);
8107 #else
8108     gen_qemu_st16(ctx, cpu_gprh[rS(ctx->opcode)], addr);
8109 #endif
8110     gen_addr_add(ctx, addr, addr, 2);
8111     gen_qemu_st16(ctx, cpu_gpr[rS(ctx->opcode)], addr);
8112 }
8113
8114 static inline void gen_op_evstwwe(DisasContext *ctx, TCGv addr)
8115 {
8116 #if defined(TARGET_PPC64)
8117     TCGv t0 = tcg_temp_new();
8118     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32);
8119     gen_qemu_st32(ctx, t0, addr);
8120     tcg_temp_free(t0);
8121 #else
8122     gen_qemu_st32(ctx, cpu_gprh[rS(ctx->opcode)], addr);
8123 #endif
8124 }
8125
8126 static inline void gen_op_evstwwo(DisasContext *ctx, TCGv addr)
8127 {
8128     gen_qemu_st32(ctx, cpu_gpr[rS(ctx->opcode)], addr);
8129 }
8130
8131 #define GEN_SPEOP_LDST(name, opc2, sh)                                        \
8132 static void glue(gen_, name)(DisasContext *ctx)                                       \
8133 {                                                                             \
8134     TCGv t0;                                                                  \
8135     if (unlikely(!ctx->spe_enabled)) {                                        \
8136         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
8137         return;                                                               \
8138     }                                                                         \
8139     gen_set_access_type(ctx, ACCESS_INT);                                     \
8140     t0 = tcg_temp_new();                                                      \
8141     if (Rc(ctx->opcode)) {                                                    \
8142         gen_addr_spe_imm_index(ctx, t0, sh);                                  \
8143     } else {                                                                  \
8144         gen_addr_reg_index(ctx, t0);                                          \
8145     }                                                                         \
8146     gen_op_##name(ctx, t0);                                                   \
8147     tcg_temp_free(t0);                                                        \
8148 }
8149
8150 GEN_SPEOP_LDST(evldd, 0x00, 3);
8151 GEN_SPEOP_LDST(evldw, 0x01, 3);
8152 GEN_SPEOP_LDST(evldh, 0x02, 3);
8153 GEN_SPEOP_LDST(evlhhesplat, 0x04, 1);
8154 GEN_SPEOP_LDST(evlhhousplat, 0x06, 1);
8155 GEN_SPEOP_LDST(evlhhossplat, 0x07, 1);
8156 GEN_SPEOP_LDST(evlwhe, 0x08, 2);
8157 GEN_SPEOP_LDST(evlwhou, 0x0A, 2);
8158 GEN_SPEOP_LDST(evlwhos, 0x0B, 2);
8159 GEN_SPEOP_LDST(evlwwsplat, 0x0C, 2);
8160 GEN_SPEOP_LDST(evlwhsplat, 0x0E, 2);
8161
8162 GEN_SPEOP_LDST(evstdd, 0x10, 3);
8163 GEN_SPEOP_LDST(evstdw, 0x11, 3);
8164 GEN_SPEOP_LDST(evstdh, 0x12, 3);
8165 GEN_SPEOP_LDST(evstwhe, 0x18, 2);
8166 GEN_SPEOP_LDST(evstwho, 0x1A, 2);
8167 GEN_SPEOP_LDST(evstwwe, 0x1C, 2);
8168 GEN_SPEOP_LDST(evstwwo, 0x1E, 2);
8169
8170 /* Multiply and add - TODO */
8171 #if 0
8172 GEN_SPE(speundef,       evmhessf,      0x01, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);//
8173 GEN_SPE(speundef,       evmhossf,      0x03, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
8174 GEN_SPE(evmheumi,       evmhesmi,      0x04, 0x10, 0x00000000, 0x00000000, PPC_SPE);
8175 GEN_SPE(speundef,       evmhesmf,      0x05, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
8176 GEN_SPE(evmhoumi,       evmhosmi,      0x06, 0x10, 0x00000000, 0x00000000, PPC_SPE);
8177 GEN_SPE(speundef,       evmhosmf,      0x07, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
8178 GEN_SPE(speundef,       evmhessfa,     0x11, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
8179 GEN_SPE(speundef,       evmhossfa,     0x13, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
8180 GEN_SPE(evmheumia,      evmhesmia,     0x14, 0x10, 0x00000000, 0x00000000, PPC_SPE);
8181 GEN_SPE(speundef,       evmhesmfa,     0x15, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
8182 GEN_SPE(evmhoumia,      evmhosmia,     0x16, 0x10, 0x00000000, 0x00000000, PPC_SPE);
8183 GEN_SPE(speundef,       evmhosmfa,     0x17, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
8184
8185 GEN_SPE(speundef,       evmwhssf,      0x03, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
8186 GEN_SPE(evmwlumi,       speundef,      0x04, 0x11, 0x00000000, 0xFFFFFFFF, PPC_SPE);
8187 GEN_SPE(evmwhumi,       evmwhsmi,      0x06, 0x11, 0x00000000, 0x00000000, PPC_SPE);
8188 GEN_SPE(speundef,       evmwhsmf,      0x07, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
8189 GEN_SPE(speundef,       evmwssf,       0x09, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
8190 GEN_SPE(speundef,       evmwsmf,       0x0D, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
8191 GEN_SPE(speundef,       evmwhssfa,     0x13, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
8192 GEN_SPE(evmwlumia,      speundef,      0x14, 0x11, 0x00000000, 0xFFFFFFFF, PPC_SPE);
8193 GEN_SPE(evmwhumia,      evmwhsmia,     0x16, 0x11, 0x00000000, 0x00000000, PPC_SPE);
8194 GEN_SPE(speundef,       evmwhsmfa,     0x17, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
8195 GEN_SPE(speundef,       evmwssfa,      0x19, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
8196 GEN_SPE(speundef,       evmwsmfa,      0x1D, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
8197
8198 GEN_SPE(evadduiaaw,     evaddsiaaw,    0x00, 0x13, 0x0000F800, 0x0000F800, PPC_SPE);
8199 GEN_SPE(evsubfusiaaw,   evsubfssiaaw,  0x01, 0x13, 0x0000F800, 0x0000F800, PPC_SPE);
8200 GEN_SPE(evaddumiaaw,    evaddsmiaaw,   0x04, 0x13, 0x0000F800, 0x0000F800, PPC_SPE);
8201 GEN_SPE(evsubfumiaaw,   evsubfsmiaaw,  0x05, 0x13, 0x0000F800, 0x0000F800, PPC_SPE);
8202 GEN_SPE(evdivws,        evdivwu,       0x06, 0x13, 0x00000000, 0x00000000, PPC_SPE);
8203
8204 GEN_SPE(evmheusiaaw,    evmhessiaaw,   0x00, 0x14, 0x00000000, 0x00000000, PPC_SPE);
8205 GEN_SPE(speundef,       evmhessfaaw,   0x01, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
8206 GEN_SPE(evmhousiaaw,    evmhossiaaw,   0x02, 0x14, 0x00000000, 0x00000000, PPC_SPE);
8207 GEN_SPE(speundef,       evmhossfaaw,   0x03, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
8208 GEN_SPE(evmheumiaaw,    evmhesmiaaw,   0x04, 0x14, 0x00000000, 0x00000000, PPC_SPE);
8209 GEN_SPE(speundef,       evmhesmfaaw,   0x05, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
8210 GEN_SPE(evmhoumiaaw,    evmhosmiaaw,   0x06, 0x14, 0x00000000, 0x00000000, PPC_SPE);
8211 GEN_SPE(speundef,       evmhosmfaaw,   0x07, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
8212 GEN_SPE(evmhegumiaa,    evmhegsmiaa,   0x14, 0x14, 0x00000000, 0x00000000, PPC_SPE);
8213 GEN_SPE(speundef,       evmhegsmfaa,   0x15, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
8214 GEN_SPE(evmhogumiaa,    evmhogsmiaa,   0x16, 0x14, 0x00000000, 0x00000000, PPC_SPE);
8215 GEN_SPE(speundef,       evmhogsmfaa,   0x17, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
8216
8217 GEN_SPE(evmwlusiaaw,    evmwlssiaaw,   0x00, 0x15, 0x00000000, 0x00000000, PPC_SPE);
8218 GEN_SPE(evmwlumiaaw,    evmwlsmiaaw,   0x04, 0x15, 0x00000000, 0x00000000, PPC_SPE);
8219 GEN_SPE(speundef,       evmwssfaa,     0x09, 0x15, 0xFFFFFFFF, 0x00000000, PPC_SPE);
8220 GEN_SPE(speundef,       evmwsmfaa,     0x0D, 0x15, 0xFFFFFFFF, 0x00000000, PPC_SPE);
8221
8222 GEN_SPE(evmheusianw,    evmhessianw,   0x00, 0x16, 0x00000000, 0x00000000, PPC_SPE);
8223 GEN_SPE(speundef,       evmhessfanw,   0x01, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
8224 GEN_SPE(evmhousianw,    evmhossianw,   0x02, 0x16, 0x00000000, 0x00000000, PPC_SPE);
8225 GEN_SPE(speundef,       evmhossfanw,   0x03, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
8226 GEN_SPE(evmheumianw,    evmhesmianw,   0x04, 0x16, 0x00000000, 0x00000000, PPC_SPE);
8227 GEN_SPE(speundef,       evmhesmfanw,   0x05, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
8228 GEN_SPE(evmhoumianw,    evmhosmianw,   0x06, 0x16, 0x00000000, 0x00000000, PPC_SPE);
8229 GEN_SPE(speundef,       evmhosmfanw,   0x07, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
8230 GEN_SPE(evmhegumian,    evmhegsmian,   0x14, 0x16, 0x00000000, 0x00000000, PPC_SPE);
8231 GEN_SPE(speundef,       evmhegsmfan,   0x15, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
8232 GEN_SPE(evmhigumian,    evmhigsmian,   0x16, 0x16, 0x00000000, 0x00000000, PPC_SPE);
8233 GEN_SPE(speundef,       evmhogsmfan,   0x17, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
8234
8235 GEN_SPE(evmwlusianw,    evmwlssianw,   0x00, 0x17, 0x00000000, 0x00000000, PPC_SPE);
8236 GEN_SPE(evmwlumianw,    evmwlsmianw,   0x04, 0x17, 0x00000000, 0x00000000, PPC_SPE);
8237 GEN_SPE(speundef,       evmwssfan,     0x09, 0x17, 0xFFFFFFFF, 0x00000000, PPC_SPE);
8238 GEN_SPE(evmwumian,      evmwsmian,     0x0C, 0x17, 0x00000000, 0x00000000, PPC_SPE);
8239 GEN_SPE(speundef,       evmwsmfan,     0x0D, 0x17, 0xFFFFFFFF, 0x00000000, PPC_SPE);
8240 #endif
8241
8242 /***                      SPE floating-point extension                     ***/
8243 #if defined(TARGET_PPC64)
8244 #define GEN_SPEFPUOP_CONV_32_32(name)                                         \
8245 static inline void gen_##name(DisasContext *ctx)                              \
8246 {                                                                             \
8247     TCGv_i32 t0;                                                              \
8248     TCGv t1;                                                                  \
8249     t0 = tcg_temp_new_i32();                                                  \
8250     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rB(ctx->opcode)]);                       \
8251     gen_helper_##name(t0, cpu_env, t0);                                       \
8252     t1 = tcg_temp_new();                                                      \
8253     tcg_gen_extu_i32_tl(t1, t0);                                              \
8254     tcg_temp_free_i32(t0);                                                    \
8255     tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)],       \
8256                     0xFFFFFFFF00000000ULL);                                   \
8257     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t1);    \
8258     tcg_temp_free(t1);                                                        \
8259 }
8260 #define GEN_SPEFPUOP_CONV_32_64(name)                                         \
8261 static inline void gen_##name(DisasContext *ctx)                              \
8262 {                                                                             \
8263     TCGv_i32 t0;                                                              \
8264     TCGv t1;                                                                  \
8265     t0 = tcg_temp_new_i32();                                                  \
8266     gen_helper_##name(t0, cpu_env, cpu_gpr[rB(ctx->opcode)]);                 \
8267     t1 = tcg_temp_new();                                                      \
8268     tcg_gen_extu_i32_tl(t1, t0);                                              \
8269     tcg_temp_free_i32(t0);                                                    \
8270     tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)],       \
8271                     0xFFFFFFFF00000000ULL);                                   \
8272     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t1);    \
8273     tcg_temp_free(t1);                                                        \
8274 }
8275 #define GEN_SPEFPUOP_CONV_64_32(name)                                         \
8276 static inline void gen_##name(DisasContext *ctx)                              \
8277 {                                                                             \
8278     TCGv_i32 t0 = tcg_temp_new_i32();                                         \
8279     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rB(ctx->opcode)]);                       \
8280     gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);                 \
8281     tcg_temp_free_i32(t0);                                                    \
8282 }
8283 #define GEN_SPEFPUOP_CONV_64_64(name)                                         \
8284 static inline void gen_##name(DisasContext *ctx)                              \
8285 {                                                                             \
8286     gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_env,                      \
8287                       cpu_gpr[rB(ctx->opcode)]);                              \
8288 }
8289 #define GEN_SPEFPUOP_ARITH2_32_32(name)                                       \
8290 static inline void gen_##name(DisasContext *ctx)                              \
8291 {                                                                             \
8292     TCGv_i32 t0, t1;                                                          \
8293     TCGv_i64 t2;                                                              \
8294     if (unlikely(!ctx->spe_enabled)) {                                        \
8295         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
8296         return;                                                               \
8297     }                                                                         \
8298     t0 = tcg_temp_new_i32();                                                  \
8299     t1 = tcg_temp_new_i32();                                                  \
8300     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);                       \
8301     tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);                       \
8302     gen_helper_##name(t0, cpu_env, t0, t1);                                   \
8303     tcg_temp_free_i32(t1);                                                    \
8304     t2 = tcg_temp_new();                                                      \
8305     tcg_gen_extu_i32_tl(t2, t0);                                              \
8306     tcg_temp_free_i32(t0);                                                    \
8307     tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)],       \
8308                     0xFFFFFFFF00000000ULL);                                   \
8309     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t2);    \
8310     tcg_temp_free(t2);                                                        \
8311 }
8312 #define GEN_SPEFPUOP_ARITH2_64_64(name)                                       \
8313 static inline void gen_##name(DisasContext *ctx)                              \
8314 {                                                                             \
8315     if (unlikely(!ctx->spe_enabled)) {                                        \
8316         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
8317         return;                                                               \
8318     }                                                                         \
8319     gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_env,                      \
8320                       cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
8321 }
8322 #define GEN_SPEFPUOP_COMP_32(name)                                            \
8323 static inline void gen_##name(DisasContext *ctx)                              \
8324 {                                                                             \
8325     TCGv_i32 t0, t1;                                                          \
8326     if (unlikely(!ctx->spe_enabled)) {                                        \
8327         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
8328         return;                                                               \
8329     }                                                                         \
8330     t0 = tcg_temp_new_i32();                                                  \
8331     t1 = tcg_temp_new_i32();                                                  \
8332     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);                       \
8333     tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);                       \
8334     gen_helper_##name(cpu_crf[crfD(ctx->opcode)], cpu_env, t0, t1);           \
8335     tcg_temp_free_i32(t0);                                                    \
8336     tcg_temp_free_i32(t1);                                                    \
8337 }
8338 #define GEN_SPEFPUOP_COMP_64(name)                                            \
8339 static inline void gen_##name(DisasContext *ctx)                              \
8340 {                                                                             \
8341     if (unlikely(!ctx->spe_enabled)) {                                        \
8342         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
8343         return;                                                               \
8344     }                                                                         \
8345     gen_helper_##name(cpu_crf[crfD(ctx->opcode)], cpu_env,                    \
8346                       cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
8347 }
8348 #else
8349 #define GEN_SPEFPUOP_CONV_32_32(name)                                         \
8350 static inline void gen_##name(DisasContext *ctx)                              \
8351 {                                                                             \
8352     gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_env,                      \
8353                       cpu_gpr[rB(ctx->opcode)]);                              \
8354 }
8355 #define GEN_SPEFPUOP_CONV_32_64(name)                                         \
8356 static inline void gen_##name(DisasContext *ctx)                              \
8357 {                                                                             \
8358     TCGv_i64 t0 = tcg_temp_new_i64();                                         \
8359     gen_load_gpr64(t0, rB(ctx->opcode));                                      \
8360     gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);                 \
8361     tcg_temp_free_i64(t0);                                                    \
8362 }
8363 #define GEN_SPEFPUOP_CONV_64_32(name)                                         \
8364 static inline void gen_##name(DisasContext *ctx)                              \
8365 {                                                                             \
8366     TCGv_i64 t0 = tcg_temp_new_i64();                                         \
8367     gen_helper_##name(t0, cpu_env, cpu_gpr[rB(ctx->opcode)]);                 \
8368     gen_store_gpr64(rD(ctx->opcode), t0);                                     \
8369     tcg_temp_free_i64(t0);                                                    \
8370 }
8371 #define GEN_SPEFPUOP_CONV_64_64(name)                                         \
8372 static inline void gen_##name(DisasContext *ctx)                              \
8373 {                                                                             \
8374     TCGv_i64 t0 = tcg_temp_new_i64();                                         \
8375     gen_load_gpr64(t0, rB(ctx->opcode));                                      \
8376     gen_helper_##name(t0, cpu_env, t0);                                       \
8377     gen_store_gpr64(rD(ctx->opcode), t0);                                     \
8378     tcg_temp_free_i64(t0);                                                    \
8379 }
8380 #define GEN_SPEFPUOP_ARITH2_32_32(name)                                       \
8381 static inline void gen_##name(DisasContext *ctx)                              \
8382 {                                                                             \
8383     if (unlikely(!ctx->spe_enabled)) {                                        \
8384         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
8385         return;                                                               \
8386     }                                                                         \
8387     gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_env,                      \
8388                       cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
8389 }
8390 #define GEN_SPEFPUOP_ARITH2_64_64(name)                                       \
8391 static inline void gen_##name(DisasContext *ctx)                              \
8392 {                                                                             \
8393     TCGv_i64 t0, t1;                                                          \
8394     if (unlikely(!ctx->spe_enabled)) {                                        \
8395         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
8396         return;                                                               \
8397     }                                                                         \
8398     t0 = tcg_temp_new_i64();                                                  \
8399     t1 = tcg_temp_new_i64();                                                  \
8400     gen_load_gpr64(t0, rA(ctx->opcode));                                      \
8401     gen_load_gpr64(t1, rB(ctx->opcode));                                      \
8402     gen_helper_##name(t0, cpu_env, t0, t1);                                   \
8403     gen_store_gpr64(rD(ctx->opcode), t0);                                     \
8404     tcg_temp_free_i64(t0);                                                    \
8405     tcg_temp_free_i64(t1);                                                    \
8406 }
8407 #define GEN_SPEFPUOP_COMP_32(name)                                            \
8408 static inline void gen_##name(DisasContext *ctx)                              \
8409 {                                                                             \
8410     if (unlikely(!ctx->spe_enabled)) {                                        \
8411         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
8412         return;                                                               \
8413     }                                                                         \
8414     gen_helper_##name(cpu_crf[crfD(ctx->opcode)], cpu_env,                    \
8415                       cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
8416 }
8417 #define GEN_SPEFPUOP_COMP_64(name)                                            \
8418 static inline void gen_##name(DisasContext *ctx)                              \
8419 {                                                                             \
8420     TCGv_i64 t0, t1;                                                          \
8421     if (unlikely(!ctx->spe_enabled)) {                                        \
8422         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
8423         return;                                                               \
8424     }                                                                         \
8425     t0 = tcg_temp_new_i64();                                                  \
8426     t1 = tcg_temp_new_i64();                                                  \
8427     gen_load_gpr64(t0, rA(ctx->opcode));                                      \
8428     gen_load_gpr64(t1, rB(ctx->opcode));                                      \
8429     gen_helper_##name(cpu_crf[crfD(ctx->opcode)], cpu_env, t0, t1);           \
8430     tcg_temp_free_i64(t0);                                                    \
8431     tcg_temp_free_i64(t1);                                                    \
8432 }
8433 #endif
8434
8435 /* Single precision floating-point vectors operations */
8436 /* Arithmetic */
8437 GEN_SPEFPUOP_ARITH2_64_64(evfsadd);
8438 GEN_SPEFPUOP_ARITH2_64_64(evfssub);
8439 GEN_SPEFPUOP_ARITH2_64_64(evfsmul);
8440 GEN_SPEFPUOP_ARITH2_64_64(evfsdiv);
8441 static inline void gen_evfsabs(DisasContext *ctx)
8442 {
8443     if (unlikely(!ctx->spe_enabled)) {
8444         gen_exception(ctx, POWERPC_EXCP_SPEU);
8445         return;
8446     }
8447 #if defined(TARGET_PPC64)
8448     tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~0x8000000080000000LL);
8449 #else
8450     tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~0x80000000);
8451     tcg_gen_andi_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], ~0x80000000);
8452 #endif
8453 }
8454 static inline void gen_evfsnabs(DisasContext *ctx)
8455 {
8456     if (unlikely(!ctx->spe_enabled)) {
8457         gen_exception(ctx, POWERPC_EXCP_SPEU);
8458         return;
8459     }
8460 #if defined(TARGET_PPC64)
8461     tcg_gen_ori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000080000000LL);
8462 #else
8463     tcg_gen_ori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
8464     tcg_gen_ori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000);
8465 #endif
8466 }
8467 static inline void gen_evfsneg(DisasContext *ctx)
8468 {
8469     if (unlikely(!ctx->spe_enabled)) {
8470         gen_exception(ctx, POWERPC_EXCP_SPEU);
8471         return;
8472     }
8473 #if defined(TARGET_PPC64)
8474     tcg_gen_xori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000080000000LL);
8475 #else
8476     tcg_gen_xori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
8477     tcg_gen_xori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000);
8478 #endif
8479 }
8480
8481 /* Conversion */
8482 GEN_SPEFPUOP_CONV_64_64(evfscfui);
8483 GEN_SPEFPUOP_CONV_64_64(evfscfsi);
8484 GEN_SPEFPUOP_CONV_64_64(evfscfuf);
8485 GEN_SPEFPUOP_CONV_64_64(evfscfsf);
8486 GEN_SPEFPUOP_CONV_64_64(evfsctui);
8487 GEN_SPEFPUOP_CONV_64_64(evfsctsi);
8488 GEN_SPEFPUOP_CONV_64_64(evfsctuf);
8489 GEN_SPEFPUOP_CONV_64_64(evfsctsf);
8490 GEN_SPEFPUOP_CONV_64_64(evfsctuiz);
8491 GEN_SPEFPUOP_CONV_64_64(evfsctsiz);
8492
8493 /* Comparison */
8494 GEN_SPEFPUOP_COMP_64(evfscmpgt);
8495 GEN_SPEFPUOP_COMP_64(evfscmplt);
8496 GEN_SPEFPUOP_COMP_64(evfscmpeq);
8497 GEN_SPEFPUOP_COMP_64(evfststgt);
8498 GEN_SPEFPUOP_COMP_64(evfststlt);
8499 GEN_SPEFPUOP_COMP_64(evfststeq);
8500
8501 /* Opcodes definitions */
8502 GEN_SPE(evfsadd,   evfssub,   0x00, 0x0A, 0x00000000, 0x00000000, PPC_SPE_SINGLE); //
8503 GEN_SPE(evfsabs,   evfsnabs,  0x02, 0x0A, 0x0000F800, 0x0000F800, PPC_SPE_SINGLE); //
8504 GEN_SPE(evfsneg,   speundef,  0x03, 0x0A, 0x0000F800, 0xFFFFFFFF, PPC_SPE_SINGLE); //
8505 GEN_SPE(evfsmul,   evfsdiv,   0x04, 0x0A, 0x00000000, 0x00000000, PPC_SPE_SINGLE); //
8506 GEN_SPE(evfscmpgt, evfscmplt, 0x06, 0x0A, 0x00600000, 0x00600000, PPC_SPE_SINGLE); //
8507 GEN_SPE(evfscmpeq, speundef,  0x07, 0x0A, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
8508 GEN_SPE(evfscfui,  evfscfsi,  0x08, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
8509 GEN_SPE(evfscfuf,  evfscfsf,  0x09, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
8510 GEN_SPE(evfsctui,  evfsctsi,  0x0A, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
8511 GEN_SPE(evfsctuf,  evfsctsf,  0x0B, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
8512 GEN_SPE(evfsctuiz, speundef,  0x0C, 0x0A, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
8513 GEN_SPE(evfsctsiz, speundef,  0x0D, 0x0A, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
8514 GEN_SPE(evfststgt, evfststlt, 0x0E, 0x0A, 0x00600000, 0x00600000, PPC_SPE_SINGLE); //
8515 GEN_SPE(evfststeq, speundef,  0x0F, 0x0A, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
8516
8517 /* Single precision floating-point operations */
8518 /* Arithmetic */
8519 GEN_SPEFPUOP_ARITH2_32_32(efsadd);
8520 GEN_SPEFPUOP_ARITH2_32_32(efssub);
8521 GEN_SPEFPUOP_ARITH2_32_32(efsmul);
8522 GEN_SPEFPUOP_ARITH2_32_32(efsdiv);
8523 static inline void gen_efsabs(DisasContext *ctx)
8524 {
8525     if (unlikely(!ctx->spe_enabled)) {
8526         gen_exception(ctx, POWERPC_EXCP_SPEU);
8527         return;
8528     }
8529     tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], (target_long)~0x80000000LL);
8530 }
8531 static inline void gen_efsnabs(DisasContext *ctx)
8532 {
8533     if (unlikely(!ctx->spe_enabled)) {
8534         gen_exception(ctx, POWERPC_EXCP_SPEU);
8535         return;
8536     }
8537     tcg_gen_ori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
8538 }
8539 static inline void gen_efsneg(DisasContext *ctx)
8540 {
8541     if (unlikely(!ctx->spe_enabled)) {
8542         gen_exception(ctx, POWERPC_EXCP_SPEU);
8543         return;
8544     }
8545     tcg_gen_xori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
8546 }
8547
8548 /* Conversion */
8549 GEN_SPEFPUOP_CONV_32_32(efscfui);
8550 GEN_SPEFPUOP_CONV_32_32(efscfsi);
8551 GEN_SPEFPUOP_CONV_32_32(efscfuf);
8552 GEN_SPEFPUOP_CONV_32_32(efscfsf);
8553 GEN_SPEFPUOP_CONV_32_32(efsctui);
8554 GEN_SPEFPUOP_CONV_32_32(efsctsi);
8555 GEN_SPEFPUOP_CONV_32_32(efsctuf);
8556 GEN_SPEFPUOP_CONV_32_32(efsctsf);
8557 GEN_SPEFPUOP_CONV_32_32(efsctuiz);
8558 GEN_SPEFPUOP_CONV_32_32(efsctsiz);
8559 GEN_SPEFPUOP_CONV_32_64(efscfd);
8560
8561 /* Comparison */
8562 GEN_SPEFPUOP_COMP_32(efscmpgt);
8563 GEN_SPEFPUOP_COMP_32(efscmplt);
8564 GEN_SPEFPUOP_COMP_32(efscmpeq);
8565 GEN_SPEFPUOP_COMP_32(efststgt);
8566 GEN_SPEFPUOP_COMP_32(efststlt);
8567 GEN_SPEFPUOP_COMP_32(efststeq);
8568
8569 /* Opcodes definitions */
8570 GEN_SPE(efsadd,   efssub,   0x00, 0x0B, 0x00000000, 0x00000000, PPC_SPE_SINGLE); //
8571 GEN_SPE(efsabs,   efsnabs,  0x02, 0x0B, 0x0000F800, 0x0000F800, PPC_SPE_SINGLE); //
8572 GEN_SPE(efsneg,   speundef, 0x03, 0x0B, 0x0000F800, 0xFFFFFFFF, PPC_SPE_SINGLE); //
8573 GEN_SPE(efsmul,   efsdiv,   0x04, 0x0B, 0x00000000, 0x00000000, PPC_SPE_SINGLE); //
8574 GEN_SPE(efscmpgt, efscmplt, 0x06, 0x0B, 0x00600000, 0x00600000, PPC_SPE_SINGLE); //
8575 GEN_SPE(efscmpeq, efscfd,   0x07, 0x0B, 0x00600000, 0x00180000, PPC_SPE_SINGLE); //
8576 GEN_SPE(efscfui,  efscfsi,  0x08, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
8577 GEN_SPE(efscfuf,  efscfsf,  0x09, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
8578 GEN_SPE(efsctui,  efsctsi,  0x0A, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
8579 GEN_SPE(efsctuf,  efsctsf,  0x0B, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
8580 GEN_SPE(efsctuiz, speundef, 0x0C, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
8581 GEN_SPE(efsctsiz, speundef, 0x0D, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
8582 GEN_SPE(efststgt, efststlt, 0x0E, 0x0B, 0x00600000, 0x00600000, PPC_SPE_SINGLE); //
8583 GEN_SPE(efststeq, speundef, 0x0F, 0x0B, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
8584
8585 /* Double precision floating-point operations */
8586 /* Arithmetic */
8587 GEN_SPEFPUOP_ARITH2_64_64(efdadd);
8588 GEN_SPEFPUOP_ARITH2_64_64(efdsub);
8589 GEN_SPEFPUOP_ARITH2_64_64(efdmul);
8590 GEN_SPEFPUOP_ARITH2_64_64(efddiv);
8591 static inline void gen_efdabs(DisasContext *ctx)
8592 {
8593     if (unlikely(!ctx->spe_enabled)) {
8594         gen_exception(ctx, POWERPC_EXCP_SPEU);
8595         return;
8596     }
8597 #if defined(TARGET_PPC64)
8598     tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~0x8000000000000000LL);
8599 #else
8600     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
8601     tcg_gen_andi_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], ~0x80000000);
8602 #endif
8603 }
8604 static inline void gen_efdnabs(DisasContext *ctx)
8605 {
8606     if (unlikely(!ctx->spe_enabled)) {
8607         gen_exception(ctx, POWERPC_EXCP_SPEU);
8608         return;
8609     }
8610 #if defined(TARGET_PPC64)
8611     tcg_gen_ori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000000000000LL);
8612 #else
8613     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
8614     tcg_gen_ori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000);
8615 #endif
8616 }
8617 static inline void gen_efdneg(DisasContext *ctx)
8618 {
8619     if (unlikely(!ctx->spe_enabled)) {
8620         gen_exception(ctx, POWERPC_EXCP_SPEU);
8621         return;
8622     }
8623 #if defined(TARGET_PPC64)
8624     tcg_gen_xori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000000000000LL);
8625 #else
8626     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
8627     tcg_gen_xori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000);
8628 #endif
8629 }
8630
8631 /* Conversion */
8632 GEN_SPEFPUOP_CONV_64_32(efdcfui);
8633 GEN_SPEFPUOP_CONV_64_32(efdcfsi);
8634 GEN_SPEFPUOP_CONV_64_32(efdcfuf);
8635 GEN_SPEFPUOP_CONV_64_32(efdcfsf);
8636 GEN_SPEFPUOP_CONV_32_64(efdctui);
8637 GEN_SPEFPUOP_CONV_32_64(efdctsi);
8638 GEN_SPEFPUOP_CONV_32_64(efdctuf);
8639 GEN_SPEFPUOP_CONV_32_64(efdctsf);
8640 GEN_SPEFPUOP_CONV_32_64(efdctuiz);
8641 GEN_SPEFPUOP_CONV_32_64(efdctsiz);
8642 GEN_SPEFPUOP_CONV_64_32(efdcfs);
8643 GEN_SPEFPUOP_CONV_64_64(efdcfuid);
8644 GEN_SPEFPUOP_CONV_64_64(efdcfsid);
8645 GEN_SPEFPUOP_CONV_64_64(efdctuidz);
8646 GEN_SPEFPUOP_CONV_64_64(efdctsidz);
8647
8648 /* Comparison */
8649 GEN_SPEFPUOP_COMP_64(efdcmpgt);
8650 GEN_SPEFPUOP_COMP_64(efdcmplt);
8651 GEN_SPEFPUOP_COMP_64(efdcmpeq);
8652 GEN_SPEFPUOP_COMP_64(efdtstgt);
8653 GEN_SPEFPUOP_COMP_64(efdtstlt);
8654 GEN_SPEFPUOP_COMP_64(efdtsteq);
8655
8656 /* Opcodes definitions */
8657 GEN_SPE(efdadd,    efdsub,    0x10, 0x0B, 0x00000000, 0x00000000, PPC_SPE_DOUBLE); //
8658 GEN_SPE(efdcfuid,  efdcfsid,  0x11, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
8659 GEN_SPE(efdabs,    efdnabs,   0x12, 0x0B, 0x0000F800, 0x0000F800, PPC_SPE_DOUBLE); //
8660 GEN_SPE(efdneg,    speundef,  0x13, 0x0B, 0x0000F800, 0xFFFFFFFF, PPC_SPE_DOUBLE); //
8661 GEN_SPE(efdmul,    efddiv,    0x14, 0x0B, 0x00000000, 0x00000000, PPC_SPE_DOUBLE); //
8662 GEN_SPE(efdctuidz, efdctsidz, 0x15, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
8663 GEN_SPE(efdcmpgt,  efdcmplt,  0x16, 0x0B, 0x00600000, 0x00600000, PPC_SPE_DOUBLE); //
8664 GEN_SPE(efdcmpeq,  efdcfs,    0x17, 0x0B, 0x00600000, 0x00180000, PPC_SPE_DOUBLE); //
8665 GEN_SPE(efdcfui,   efdcfsi,   0x18, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
8666 GEN_SPE(efdcfuf,   efdcfsf,   0x19, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
8667 GEN_SPE(efdctui,   efdctsi,   0x1A, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
8668 GEN_SPE(efdctuf,   efdctsf,   0x1B, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
8669 GEN_SPE(efdctuiz,  speundef,  0x1C, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_DOUBLE); //
8670 GEN_SPE(efdctsiz,  speundef,  0x1D, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_DOUBLE); //
8671 GEN_SPE(efdtstgt,  efdtstlt,  0x1E, 0x0B, 0x00600000, 0x00600000, PPC_SPE_DOUBLE); //
8672 GEN_SPE(efdtsteq,  speundef,  0x1F, 0x0B, 0x00600000, 0xFFFFFFFF, PPC_SPE_DOUBLE); //
8673
8674 static opcode_t opcodes[] = {
8675 GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE),
8676 GEN_HANDLER(cmp, 0x1F, 0x00, 0x00, 0x00400000, PPC_INTEGER),
8677 GEN_HANDLER(cmpi, 0x0B, 0xFF, 0xFF, 0x00400000, PPC_INTEGER),
8678 GEN_HANDLER(cmpl, 0x1F, 0x00, 0x01, 0x00400000, PPC_INTEGER),
8679 GEN_HANDLER(cmpli, 0x0A, 0xFF, 0xFF, 0x00400000, PPC_INTEGER),
8680 GEN_HANDLER_E(cmpb, 0x1F, 0x1C, 0x0F, 0x00000001, PPC_NONE, PPC2_ISA205),
8681 GEN_HANDLER(isel, 0x1F, 0x0F, 0xFF, 0x00000001, PPC_ISEL),
8682 GEN_HANDLER(addi, 0x0E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8683 GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8684 GEN_HANDLER2(addic_, "addic.", 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8685 GEN_HANDLER(addis, 0x0F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8686 GEN_HANDLER(mulhw, 0x1F, 0x0B, 0x02, 0x00000400, PPC_INTEGER),
8687 GEN_HANDLER(mulhwu, 0x1F, 0x0B, 0x00, 0x00000400, PPC_INTEGER),
8688 GEN_HANDLER(mullw, 0x1F, 0x0B, 0x07, 0x00000000, PPC_INTEGER),
8689 GEN_HANDLER(mullwo, 0x1F, 0x0B, 0x17, 0x00000000, PPC_INTEGER),
8690 GEN_HANDLER(mulli, 0x07, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8691 #if defined(TARGET_PPC64)
8692 GEN_HANDLER(mulld, 0x1F, 0x09, 0x07, 0x00000000, PPC_64B),
8693 #endif
8694 GEN_HANDLER(neg, 0x1F, 0x08, 0x03, 0x0000F800, PPC_INTEGER),
8695 GEN_HANDLER(nego, 0x1F, 0x08, 0x13, 0x0000F800, PPC_INTEGER),
8696 GEN_HANDLER(subfic, 0x08, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8697 GEN_HANDLER2(andi_, "andi.", 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8698 GEN_HANDLER2(andis_, "andis.", 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8699 GEN_HANDLER(cntlzw, 0x1F, 0x1A, 0x00, 0x00000000, PPC_INTEGER),
8700 GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER),
8701 GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER),
8702 GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8703 GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8704 GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8705 GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8706 GEN_HANDLER(popcntb, 0x1F, 0x03, 0x03, 0x0000F801, PPC_POPCNTB),
8707 GEN_HANDLER(popcntw, 0x1F, 0x1A, 0x0b, 0x0000F801, PPC_POPCNTWD),
8708 GEN_HANDLER_E(prtyw, 0x1F, 0x1A, 0x04, 0x0000F801, PPC_NONE, PPC2_ISA205),
8709 #if defined(TARGET_PPC64)
8710 GEN_HANDLER(popcntd, 0x1F, 0x1A, 0x0F, 0x0000F801, PPC_POPCNTWD),
8711 GEN_HANDLER(cntlzd, 0x1F, 0x1A, 0x01, 0x00000000, PPC_64B),
8712 GEN_HANDLER_E(prtyd, 0x1F, 0x1A, 0x05, 0x0000F801, PPC_NONE, PPC2_ISA205),
8713 #endif
8714 GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8715 GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8716 GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8717 GEN_HANDLER(slw, 0x1F, 0x18, 0x00, 0x00000000, PPC_INTEGER),
8718 GEN_HANDLER(sraw, 0x1F, 0x18, 0x18, 0x00000000, PPC_INTEGER),
8719 GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER),
8720 GEN_HANDLER(srw, 0x1F, 0x18, 0x10, 0x00000000, PPC_INTEGER),
8721 #if defined(TARGET_PPC64)
8722 GEN_HANDLER(sld, 0x1F, 0x1B, 0x00, 0x00000000, PPC_64B),
8723 GEN_HANDLER(srad, 0x1F, 0x1A, 0x18, 0x00000000, PPC_64B),
8724 GEN_HANDLER2(sradi0, "sradi", 0x1F, 0x1A, 0x19, 0x00000000, PPC_64B),
8725 GEN_HANDLER2(sradi1, "sradi", 0x1F, 0x1B, 0x19, 0x00000000, PPC_64B),
8726 GEN_HANDLER(srd, 0x1F, 0x1B, 0x10, 0x00000000, PPC_64B),
8727 #endif
8728 GEN_HANDLER(frsqrtes, 0x3B, 0x1A, 0xFF, 0x001F07C0, PPC_FLOAT_FRSQRTES),
8729 GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT),
8730 GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT),
8731 GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT),
8732 GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT),
8733 GEN_HANDLER(fabs, 0x3F, 0x08, 0x08, 0x001F0000, PPC_FLOAT),
8734 GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT),
8735 GEN_HANDLER(fnabs, 0x3F, 0x08, 0x04, 0x001F0000, PPC_FLOAT),
8736 GEN_HANDLER(fneg, 0x3F, 0x08, 0x01, 0x001F0000, PPC_FLOAT),
8737 GEN_HANDLER_E(fcpsgn, 0x3F, 0x08, 0x00, 0x00000000, PPC_NONE, PPC2_ISA205),
8738 GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT),
8739 GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT),
8740 GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT),
8741 GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT),
8742 GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x00000000, PPC_FLOAT),
8743 GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006e0800, PPC_FLOAT),
8744 #if defined(TARGET_PPC64)
8745 GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B),
8746 GEN_HANDLER(lq, 0x38, 0xFF, 0xFF, 0x00000000, PPC_64BX),
8747 GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000000, PPC_64B),
8748 #endif
8749 GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8750 GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8751 GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_STRING),
8752 GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_STRING),
8753 GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_STRING),
8754 GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_STRING),
8755 GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FFF801, PPC_MEM_EIEIO),
8756 GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FFF801, PPC_MEM),
8757 GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000000, PPC_RES),
8758 GEN_HANDLER2(stwcx_, "stwcx.", 0x1F, 0x16, 0x04, 0x00000000, PPC_RES),
8759 #if defined(TARGET_PPC64)
8760 GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000000, PPC_64B),
8761 GEN_HANDLER2(stdcx_, "stdcx.", 0x1F, 0x16, 0x06, 0x00000000, PPC_64B),
8762 #endif
8763 GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x039FF801, PPC_MEM_SYNC),
8764 GEN_HANDLER(wait, 0x1F, 0x1E, 0x01, 0x03FFF801, PPC_WAIT),
8765 GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
8766 GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
8767 GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW),
8768 GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW),
8769 GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER),
8770 GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW),
8771 #if defined(TARGET_PPC64)
8772 GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B),
8773 GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64H),
8774 #endif
8775 GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFF01D, PPC_FLOW),
8776 GEN_HANDLER(tw, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW),
8777 GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
8778 #if defined(TARGET_PPC64)
8779 GEN_HANDLER(td, 0x1F, 0x04, 0x02, 0x00000001, PPC_64B),
8780 GEN_HANDLER(tdi, 0x02, 0xFF, 0xFF, 0x00000000, PPC_64B),
8781 #endif
8782 GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC),
8783 GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC),
8784 GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC),
8785 GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC),
8786 GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MFTB),
8787 GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC),
8788 #if defined(TARGET_PPC64)
8789 GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001EF801, PPC_64B),
8790 #endif
8791 GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC),
8792 GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC),
8793 GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03C00001, PPC_CACHE),
8794 GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE),
8795 GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE),
8796 GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x02000001, PPC_CACHE),
8797 GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x02000001, PPC_CACHE),
8798 GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZ),
8799 GEN_HANDLER(dst, 0x1F, 0x16, 0x0A, 0x01800001, PPC_ALTIVEC),
8800 GEN_HANDLER(dstst, 0x1F, 0x16, 0x0B, 0x02000001, PPC_ALTIVEC),
8801 GEN_HANDLER(dss, 0x1F, 0x16, 0x19, 0x019FF801, PPC_ALTIVEC),
8802 GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE_ICBI),
8803 GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_DCBA),
8804 GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT),
8805 GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT),
8806 GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT),
8807 GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT),
8808 #if defined(TARGET_PPC64)
8809 GEN_HANDLER2(mfsr_64b, "mfsr", 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT_64B),
8810 GEN_HANDLER2(mfsrin_64b, "mfsrin", 0x1F, 0x13, 0x14, 0x001F0001,
8811              PPC_SEGMENT_64B),
8812 GEN_HANDLER2(mtsr_64b, "mtsr", 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B),
8813 GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001,
8814              PPC_SEGMENT_64B),
8815 GEN_HANDLER2(slbmte, "slbmte", 0x1F, 0x12, 0x0C, 0x001F0001, PPC_SEGMENT_64B),
8816 GEN_HANDLER2(slbmfee, "slbmfee", 0x1F, 0x13, 0x1C, 0x001F0001, PPC_SEGMENT_64B),
8817 GEN_HANDLER2(slbmfev, "slbmfev", 0x1F, 0x13, 0x1A, 0x001F0001, PPC_SEGMENT_64B),
8818 #endif
8819 GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA),
8820 GEN_HANDLER(tlbiel, 0x1F, 0x12, 0x08, 0x03FF0001, PPC_MEM_TLBIE),
8821 GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE),
8822 GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC),
8823 #if defined(TARGET_PPC64)
8824 GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x03FFFC01, PPC_SLBI),
8825 GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI),
8826 #endif
8827 GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN),
8828 GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN),
8829 GEN_HANDLER(abs, 0x1F, 0x08, 0x0B, 0x0000F800, PPC_POWER_BR),
8830 GEN_HANDLER(abso, 0x1F, 0x08, 0x1B, 0x0000F800, PPC_POWER_BR),
8831 GEN_HANDLER(clcs, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR),
8832 GEN_HANDLER(div, 0x1F, 0x0B, 0x0A, 0x00000000, PPC_POWER_BR),
8833 GEN_HANDLER(divo, 0x1F, 0x0B, 0x1A, 0x00000000, PPC_POWER_BR),
8834 GEN_HANDLER(divs, 0x1F, 0x0B, 0x0B, 0x00000000, PPC_POWER_BR),
8835 GEN_HANDLER(divso, 0x1F, 0x0B, 0x1B, 0x00000000, PPC_POWER_BR),
8836 GEN_HANDLER(doz, 0x1F, 0x08, 0x08, 0x00000000, PPC_POWER_BR),
8837 GEN_HANDLER(dozo, 0x1F, 0x08, 0x18, 0x00000000, PPC_POWER_BR),
8838 GEN_HANDLER(dozi, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR),
8839 GEN_HANDLER(lscbx, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR),
8840 GEN_HANDLER(maskg, 0x1F, 0x1D, 0x00, 0x00000000, PPC_POWER_BR),
8841 GEN_HANDLER(maskir, 0x1F, 0x1D, 0x10, 0x00000000, PPC_POWER_BR),
8842 GEN_HANDLER(mul, 0x1F, 0x0B, 0x03, 0x00000000, PPC_POWER_BR),
8843 GEN_HANDLER(mulo, 0x1F, 0x0B, 0x13, 0x00000000, PPC_POWER_BR),
8844 GEN_HANDLER(nabs, 0x1F, 0x08, 0x0F, 0x00000000, PPC_POWER_BR),
8845 GEN_HANDLER(nabso, 0x1F, 0x08, 0x1F, 0x00000000, PPC_POWER_BR),
8846 GEN_HANDLER(rlmi, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR),
8847 GEN_HANDLER(rrib, 0x1F, 0x19, 0x10, 0x00000000, PPC_POWER_BR),
8848 GEN_HANDLER(sle, 0x1F, 0x19, 0x04, 0x00000000, PPC_POWER_BR),
8849 GEN_HANDLER(sleq, 0x1F, 0x19, 0x06, 0x00000000, PPC_POWER_BR),
8850 GEN_HANDLER(sliq, 0x1F, 0x18, 0x05, 0x00000000, PPC_POWER_BR),
8851 GEN_HANDLER(slliq, 0x1F, 0x18, 0x07, 0x00000000, PPC_POWER_BR),
8852 GEN_HANDLER(sllq, 0x1F, 0x18, 0x06, 0x00000000, PPC_POWER_BR),
8853 GEN_HANDLER(slq, 0x1F, 0x18, 0x04, 0x00000000, PPC_POWER_BR),
8854 GEN_HANDLER(sraiq, 0x1F, 0x18, 0x1D, 0x00000000, PPC_POWER_BR),
8855 GEN_HANDLER(sraq, 0x1F, 0x18, 0x1C, 0x00000000, PPC_POWER_BR),
8856 GEN_HANDLER(sre, 0x1F, 0x19, 0x14, 0x00000000, PPC_POWER_BR),
8857 GEN_HANDLER(srea, 0x1F, 0x19, 0x1C, 0x00000000, PPC_POWER_BR),
8858 GEN_HANDLER(sreq, 0x1F, 0x19, 0x16, 0x00000000, PPC_POWER_BR),
8859 GEN_HANDLER(sriq, 0x1F, 0x18, 0x15, 0x00000000, PPC_POWER_BR),
8860 GEN_HANDLER(srliq, 0x1F, 0x18, 0x17, 0x00000000, PPC_POWER_BR),
8861 GEN_HANDLER(srlq, 0x1F, 0x18, 0x16, 0x00000000, PPC_POWER_BR),
8862 GEN_HANDLER(srq, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR),
8863 GEN_HANDLER(dsa, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC),
8864 GEN_HANDLER(esa, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC),
8865 GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC),
8866 GEN_HANDLER2(tlbld_6xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB),
8867 GEN_HANDLER2(tlbli_6xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB),
8868 GEN_HANDLER2(tlbld_74xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_74xx_TLB),
8869 GEN_HANDLER2(tlbli_74xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_74xx_TLB),
8870 GEN_HANDLER(clf, 0x1F, 0x16, 0x03, 0x03E00000, PPC_POWER),
8871 GEN_HANDLER(cli, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER),
8872 GEN_HANDLER(dclst, 0x1F, 0x16, 0x13, 0x03E00000, PPC_POWER),
8873 GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER),
8874 GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER),
8875 GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER),
8876 GEN_HANDLER(lfq, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
8877 GEN_HANDLER(lfqu, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
8878 GEN_HANDLER(lfqux, 0x1F, 0x17, 0x19, 0x00000001, PPC_POWER2),
8879 GEN_HANDLER(lfqx, 0x1F, 0x17, 0x18, 0x00000001, PPC_POWER2),
8880 GEN_HANDLER(stfq, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
8881 GEN_HANDLER(stfqu, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
8882 GEN_HANDLER(stfqux, 0x1F, 0x17, 0x1D, 0x00000001, PPC_POWER2),
8883 GEN_HANDLER(stfqx, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2),
8884 GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_MFAPIDI),
8885 GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_TLBIVA),
8886 GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_DCR),
8887 GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_DCR),
8888 GEN_HANDLER(mfdcrx, 0x1F, 0x03, 0x08, 0x00000000, PPC_DCRX),
8889 GEN_HANDLER(mtdcrx, 0x1F, 0x03, 0x0C, 0x00000000, PPC_DCRX),
8890 GEN_HANDLER(mfdcrux, 0x1F, 0x03, 0x09, 0x00000000, PPC_DCRUX),
8891 GEN_HANDLER(mtdcrux, 0x1F, 0x03, 0x0D, 0x00000000, PPC_DCRUX),
8892 GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON),
8893 GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON),
8894 GEN_HANDLER2(icbt_40x, "icbt", 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_ICBT),
8895 GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON),
8896 GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON),
8897 GEN_HANDLER2(rfci_40x, "rfci", 0x13, 0x13, 0x01, 0x03FF8001, PPC_40x_EXCP),
8898 GEN_HANDLER_E(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE, PPC2_BOOKE206),
8899 GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_RFDI),
8900 GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_RFMCI),
8901 GEN_HANDLER2(tlbre_40x, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB),
8902 GEN_HANDLER2(tlbsx_40x, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB),
8903 GEN_HANDLER2(tlbwe_40x, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB),
8904 GEN_HANDLER2(tlbre_440, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE),
8905 GEN_HANDLER2(tlbsx_440, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE),
8906 GEN_HANDLER2(tlbwe_440, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE),
8907 GEN_HANDLER2_E(tlbre_booke206, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001,
8908                PPC_NONE, PPC2_BOOKE206),
8909 GEN_HANDLER2_E(tlbsx_booke206, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000,
8910                PPC_NONE, PPC2_BOOKE206),
8911 GEN_HANDLER2_E(tlbwe_booke206, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001,
8912                PPC_NONE, PPC2_BOOKE206),
8913 GEN_HANDLER2_E(tlbivax_booke206, "tlbivax", 0x1F, 0x12, 0x18, 0x00000001,
8914                PPC_NONE, PPC2_BOOKE206),
8915 GEN_HANDLER2_E(tlbilx_booke206, "tlbilx", 0x1F, 0x12, 0x00, 0x03800001,
8916                PPC_NONE, PPC2_BOOKE206),
8917 GEN_HANDLER2_E(msgsnd, "msgsnd", 0x1F, 0x0E, 0x06, 0x03ff0001,
8918                PPC_NONE, PPC2_PRCNTL),
8919 GEN_HANDLER2_E(msgclr, "msgclr", 0x1F, 0x0E, 0x07, 0x03ff0001,
8920                PPC_NONE, PPC2_PRCNTL),
8921 GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE),
8922 GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000E7C01, PPC_WRTEE),
8923 GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC),
8924 GEN_HANDLER_E(mbar, 0x1F, 0x16, 0x1a, 0x001FF801,
8925               PPC_BOOKE, PPC2_BOOKE206),
8926 GEN_HANDLER(msync_4xx, 0x1F, 0x16, 0x12, 0x03FFF801, PPC_BOOKE),
8927 GEN_HANDLER2_E(icbt_440, "icbt", 0x1F, 0x16, 0x00, 0x03E00001,
8928                PPC_BOOKE, PPC2_BOOKE206),
8929 GEN_HANDLER(lvsl, 0x1f, 0x06, 0x00, 0x00000001, PPC_ALTIVEC),
8930 GEN_HANDLER(lvsr, 0x1f, 0x06, 0x01, 0x00000001, PPC_ALTIVEC),
8931 GEN_HANDLER(mfvscr, 0x04, 0x2, 0x18, 0x001ff800, PPC_ALTIVEC),
8932 GEN_HANDLER(mtvscr, 0x04, 0x2, 0x19, 0x03ff0000, PPC_ALTIVEC),
8933 GEN_HANDLER(vsldoi, 0x04, 0x16, 0xFF, 0x00000400, PPC_ALTIVEC),
8934 GEN_HANDLER(vmladduhm, 0x04, 0x11, 0xFF, 0x00000000, PPC_ALTIVEC),
8935 GEN_HANDLER2(evsel0, "evsel", 0x04, 0x1c, 0x09, 0x00000000, PPC_SPE),
8936 GEN_HANDLER2(evsel1, "evsel", 0x04, 0x1d, 0x09, 0x00000000, PPC_SPE),
8937 GEN_HANDLER2(evsel2, "evsel", 0x04, 0x1e, 0x09, 0x00000000, PPC_SPE),
8938 GEN_HANDLER2(evsel3, "evsel", 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE),
8939
8940 #undef GEN_INT_ARITH_ADD
8941 #undef GEN_INT_ARITH_ADD_CONST
8942 #define GEN_INT_ARITH_ADD(name, opc3, add_ca, compute_ca, compute_ov)         \
8943 GEN_HANDLER(name, 0x1F, 0x0A, opc3, 0x00000000, PPC_INTEGER),
8944 #define GEN_INT_ARITH_ADD_CONST(name, opc3, const_val,                        \
8945                                 add_ca, compute_ca, compute_ov)               \
8946 GEN_HANDLER(name, 0x1F, 0x0A, opc3, 0x0000F800, PPC_INTEGER),
8947 GEN_INT_ARITH_ADD(add, 0x08, 0, 0, 0)
8948 GEN_INT_ARITH_ADD(addo, 0x18, 0, 0, 1)
8949 GEN_INT_ARITH_ADD(addc, 0x00, 0, 1, 0)
8950 GEN_INT_ARITH_ADD(addco, 0x10, 0, 1, 1)
8951 GEN_INT_ARITH_ADD(adde, 0x04, 1, 1, 0)
8952 GEN_INT_ARITH_ADD(addeo, 0x14, 1, 1, 1)
8953 GEN_INT_ARITH_ADD_CONST(addme, 0x07, -1LL, 1, 1, 0)
8954 GEN_INT_ARITH_ADD_CONST(addmeo, 0x17, -1LL, 1, 1, 1)
8955 GEN_INT_ARITH_ADD_CONST(addze, 0x06, 0, 1, 1, 0)
8956 GEN_INT_ARITH_ADD_CONST(addzeo, 0x16, 0, 1, 1, 1)
8957
8958 #undef GEN_INT_ARITH_DIVW
8959 #define GEN_INT_ARITH_DIVW(name, opc3, sign, compute_ov)                      \
8960 GEN_HANDLER(name, 0x1F, 0x0B, opc3, 0x00000000, PPC_INTEGER)
8961 GEN_INT_ARITH_DIVW(divwu, 0x0E, 0, 0),
8962 GEN_INT_ARITH_DIVW(divwuo, 0x1E, 0, 1),
8963 GEN_INT_ARITH_DIVW(divw, 0x0F, 1, 0),
8964 GEN_INT_ARITH_DIVW(divwo, 0x1F, 1, 1),
8965
8966 #if defined(TARGET_PPC64)
8967 #undef GEN_INT_ARITH_DIVD
8968 #define GEN_INT_ARITH_DIVD(name, opc3, sign, compute_ov)                      \
8969 GEN_HANDLER(name, 0x1F, 0x09, opc3, 0x00000000, PPC_64B)
8970 GEN_INT_ARITH_DIVD(divdu, 0x0E, 0, 0),
8971 GEN_INT_ARITH_DIVD(divduo, 0x1E, 0, 1),
8972 GEN_INT_ARITH_DIVD(divd, 0x0F, 1, 0),
8973 GEN_INT_ARITH_DIVD(divdo, 0x1F, 1, 1),
8974
8975 #undef GEN_INT_ARITH_MUL_HELPER
8976 #define GEN_INT_ARITH_MUL_HELPER(name, opc3)                                  \
8977 GEN_HANDLER(name, 0x1F, 0x09, opc3, 0x00000000, PPC_64B)
8978 GEN_INT_ARITH_MUL_HELPER(mulhdu, 0x00),
8979 GEN_INT_ARITH_MUL_HELPER(mulhd, 0x02),
8980 GEN_INT_ARITH_MUL_HELPER(mulldo, 0x17),
8981 #endif
8982
8983 #undef GEN_INT_ARITH_SUBF
8984 #undef GEN_INT_ARITH_SUBF_CONST
8985 #define GEN_INT_ARITH_SUBF(name, opc3, add_ca, compute_ca, compute_ov)        \
8986 GEN_HANDLER(name, 0x1F, 0x08, opc3, 0x00000000, PPC_INTEGER),
8987 #define GEN_INT_ARITH_SUBF_CONST(name, opc3, const_val,                       \
8988                                 add_ca, compute_ca, compute_ov)               \
8989 GEN_HANDLER(name, 0x1F, 0x08, opc3, 0x0000F800, PPC_INTEGER),
8990 GEN_INT_ARITH_SUBF(subf, 0x01, 0, 0, 0)
8991 GEN_INT_ARITH_SUBF(subfo, 0x11, 0, 0, 1)
8992 GEN_INT_ARITH_SUBF(subfc, 0x00, 0, 1, 0)
8993 GEN_INT_ARITH_SUBF(subfco, 0x10, 0, 1, 1)
8994 GEN_INT_ARITH_SUBF(subfe, 0x04, 1, 1, 0)
8995 GEN_INT_ARITH_SUBF(subfeo, 0x14, 1, 1, 1)
8996 GEN_INT_ARITH_SUBF_CONST(subfme, 0x07, -1LL, 1, 1, 0)
8997 GEN_INT_ARITH_SUBF_CONST(subfmeo, 0x17, -1LL, 1, 1, 1)
8998 GEN_INT_ARITH_SUBF_CONST(subfze, 0x06, 0, 1, 1, 0)
8999 GEN_INT_ARITH_SUBF_CONST(subfzeo, 0x16, 0, 1, 1, 1)
9000
9001 #undef GEN_LOGICAL1
9002 #undef GEN_LOGICAL2
9003 #define GEN_LOGICAL2(name, tcg_op, opc, type)                                 \
9004 GEN_HANDLER(name, 0x1F, 0x1C, opc, 0x00000000, type)
9005 #define GEN_LOGICAL1(name, tcg_op, opc, type)                                 \
9006 GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, type)
9007 GEN_LOGICAL2(and, tcg_gen_and_tl, 0x00, PPC_INTEGER),
9008 GEN_LOGICAL2(andc, tcg_gen_andc_tl, 0x01, PPC_INTEGER),
9009 GEN_LOGICAL2(eqv, tcg_gen_eqv_tl, 0x08, PPC_INTEGER),
9010 GEN_LOGICAL1(extsb, tcg_gen_ext8s_tl, 0x1D, PPC_INTEGER),
9011 GEN_LOGICAL1(extsh, tcg_gen_ext16s_tl, 0x1C, PPC_INTEGER),
9012 GEN_LOGICAL2(nand, tcg_gen_nand_tl, 0x0E, PPC_INTEGER),
9013 GEN_LOGICAL2(nor, tcg_gen_nor_tl, 0x03, PPC_INTEGER),
9014 GEN_LOGICAL2(orc, tcg_gen_orc_tl, 0x0C, PPC_INTEGER),
9015 #if defined(TARGET_PPC64)
9016 GEN_LOGICAL1(extsw, tcg_gen_ext32s_tl, 0x1E, PPC_64B),
9017 #endif
9018
9019 #if defined(TARGET_PPC64)
9020 #undef GEN_PPC64_R2
9021 #undef GEN_PPC64_R4
9022 #define GEN_PPC64_R2(name, opc1, opc2)                                        \
9023 GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B),\
9024 GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000,   \
9025              PPC_64B)
9026 #define GEN_PPC64_R4(name, opc1, opc2)                                        \
9027 GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B),\
9028 GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x01, 0xFF, 0x00000000,   \
9029              PPC_64B),                                                        \
9030 GEN_HANDLER2(name##2, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000,   \
9031              PPC_64B),                                                        \
9032 GEN_HANDLER2(name##3, stringify(name), opc1, opc2 | 0x11, 0xFF, 0x00000000,   \
9033              PPC_64B)
9034 GEN_PPC64_R4(rldicl, 0x1E, 0x00),
9035 GEN_PPC64_R4(rldicr, 0x1E, 0x02),
9036 GEN_PPC64_R4(rldic, 0x1E, 0x04),
9037 GEN_PPC64_R2(rldcl, 0x1E, 0x08),
9038 GEN_PPC64_R2(rldcr, 0x1E, 0x09),
9039 GEN_PPC64_R4(rldimi, 0x1E, 0x06),
9040 #endif
9041
9042 #undef _GEN_FLOAT_ACB
9043 #undef GEN_FLOAT_ACB
9044 #undef _GEN_FLOAT_AB
9045 #undef GEN_FLOAT_AB
9046 #undef _GEN_FLOAT_AC
9047 #undef GEN_FLOAT_AC
9048 #undef GEN_FLOAT_B
9049 #undef GEN_FLOAT_BS
9050 #define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat, set_fprf, type)           \
9051 GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, type)
9052 #define GEN_FLOAT_ACB(name, op2, set_fprf, type)                              \
9053 _GEN_FLOAT_ACB(name, name, 0x3F, op2, 0, set_fprf, type),                     \
9054 _GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, set_fprf, type)
9055 #define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
9056 GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)
9057 #define GEN_FLOAT_AB(name, op2, inval, set_fprf, type)                        \
9058 _GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0, set_fprf, type),               \
9059 _GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1, set_fprf, type)
9060 #define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
9061 GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)
9062 #define GEN_FLOAT_AC(name, op2, inval, set_fprf, type)                        \
9063 _GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0, set_fprf, type),               \
9064 _GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1, set_fprf, type)
9065 #define GEN_FLOAT_B(name, op2, op3, set_fprf, type)                           \
9066 GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, type)
9067 #define GEN_FLOAT_BS(name, op1, op2, set_fprf, type)                          \
9068 GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, type)
9069
9070 GEN_FLOAT_AB(add, 0x15, 0x000007C0, 1, PPC_FLOAT),
9071 GEN_FLOAT_AB(div, 0x12, 0x000007C0, 1, PPC_FLOAT),
9072 GEN_FLOAT_AC(mul, 0x19, 0x0000F800, 1, PPC_FLOAT),
9073 GEN_FLOAT_BS(re, 0x3F, 0x18, 1, PPC_FLOAT_EXT),
9074 GEN_FLOAT_BS(res, 0x3B, 0x18, 1, PPC_FLOAT_FRES),
9075 GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A, 1, PPC_FLOAT_FRSQRTE),
9076 _GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0, 0, PPC_FLOAT_FSEL),
9077 GEN_FLOAT_AB(sub, 0x14, 0x000007C0, 1, PPC_FLOAT),
9078 GEN_FLOAT_ACB(madd, 0x1D, 1, PPC_FLOAT),
9079 GEN_FLOAT_ACB(msub, 0x1C, 1, PPC_FLOAT),
9080 GEN_FLOAT_ACB(nmadd, 0x1F, 1, PPC_FLOAT),
9081 GEN_FLOAT_ACB(nmsub, 0x1E, 1, PPC_FLOAT),
9082 GEN_FLOAT_B(ctiw, 0x0E, 0x00, 0, PPC_FLOAT),
9083 GEN_FLOAT_B(ctiwz, 0x0F, 0x00, 0, PPC_FLOAT),
9084 GEN_FLOAT_B(rsp, 0x0C, 0x00, 1, PPC_FLOAT),
9085 #if defined(TARGET_PPC64)
9086 GEN_FLOAT_B(cfid, 0x0E, 0x1A, 1, PPC_64B),
9087 GEN_FLOAT_B(ctid, 0x0E, 0x19, 0, PPC_64B),
9088 GEN_FLOAT_B(ctidz, 0x0F, 0x19, 0, PPC_64B),
9089 #endif
9090 GEN_FLOAT_B(rin, 0x08, 0x0C, 1, PPC_FLOAT_EXT),
9091 GEN_FLOAT_B(riz, 0x08, 0x0D, 1, PPC_FLOAT_EXT),
9092 GEN_FLOAT_B(rip, 0x08, 0x0E, 1, PPC_FLOAT_EXT),
9093 GEN_FLOAT_B(rim, 0x08, 0x0F, 1, PPC_FLOAT_EXT),
9094
9095 #undef GEN_LD
9096 #undef GEN_LDU
9097 #undef GEN_LDUX
9098 #undef GEN_LDX_E
9099 #undef GEN_LDS
9100 #define GEN_LD(name, ldop, opc, type)                                         \
9101 GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
9102 #define GEN_LDU(name, ldop, opc, type)                                        \
9103 GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
9104 #define GEN_LDUX(name, ldop, opc2, opc3, type)                                \
9105 GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type),
9106 #define GEN_LDX_E(name, ldop, opc2, opc3, type, type2)                        \
9107 GEN_HANDLER_E(name##x, 0x1F, opc2, opc3, 0x00000001, type, type2),
9108 #define GEN_LDS(name, ldop, op, type)                                         \
9109 GEN_LD(name, ldop, op | 0x20, type)                                           \
9110 GEN_LDU(name, ldop, op | 0x21, type)                                          \
9111 GEN_LDUX(name, ldop, 0x17, op | 0x01, type)                                   \
9112 GEN_LDX(name, ldop, 0x17, op | 0x00, type)
9113
9114 GEN_LDS(lbz, ld8u, 0x02, PPC_INTEGER)
9115 GEN_LDS(lha, ld16s, 0x0A, PPC_INTEGER)
9116 GEN_LDS(lhz, ld16u, 0x08, PPC_INTEGER)
9117 GEN_LDS(lwz, ld32u, 0x00, PPC_INTEGER)
9118 #if defined(TARGET_PPC64)
9119 GEN_LDUX(lwa, ld32s, 0x15, 0x0B, PPC_64B)
9120 GEN_LDX(lwa, ld32s, 0x15, 0x0A, PPC_64B)
9121 GEN_LDUX(ld, ld64, 0x15, 0x01, PPC_64B)
9122 GEN_LDX(ld, ld64, 0x15, 0x00, PPC_64B)
9123 GEN_LDX_E(ldbr, ld64ur, 0x14, 0x10, PPC_NONE, PPC2_DBRX)
9124 #endif
9125 GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER)
9126 GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER)
9127
9128 #undef GEN_ST
9129 #undef GEN_STU
9130 #undef GEN_STUX
9131 #undef GEN_STX_E
9132 #undef GEN_STS
9133 #define GEN_ST(name, stop, opc, type)                                         \
9134 GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
9135 #define GEN_STU(name, stop, opc, type)                                        \
9136 GEN_HANDLER(stop##u, opc, 0xFF, 0xFF, 0x00000000, type),
9137 #define GEN_STUX(name, stop, opc2, opc3, type)                                \
9138 GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type),
9139 #define GEN_STX_E(name, stop, opc2, opc3, type, type2)                        \
9140 GEN_HANDLER_E(name##x, 0x1F, opc2, opc3, 0x00000001, type, type2),
9141 #define GEN_STS(name, stop, op, type)                                         \
9142 GEN_ST(name, stop, op | 0x20, type)                                           \
9143 GEN_STU(name, stop, op | 0x21, type)                                          \
9144 GEN_STUX(name, stop, 0x17, op | 0x01, type)                                   \
9145 GEN_STX(name, stop, 0x17, op | 0x00, type)
9146
9147 GEN_STS(stb, st8, 0x06, PPC_INTEGER)
9148 GEN_STS(sth, st16, 0x0C, PPC_INTEGER)
9149 GEN_STS(stw, st32, 0x04, PPC_INTEGER)
9150 #if defined(TARGET_PPC64)
9151 GEN_STUX(std, st64, 0x15, 0x05, PPC_64B)
9152 GEN_STX(std, st64, 0x15, 0x04, PPC_64B)
9153 GEN_STX_E(stdbr, st64r, 0x14, 0x14, PPC_NONE, PPC2_DBRX)
9154 #endif
9155 GEN_STX(sthbr, st16r, 0x16, 0x1C, PPC_INTEGER)
9156 GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER)
9157
9158 #undef GEN_LDF
9159 #undef GEN_LDUF
9160 #undef GEN_LDUXF
9161 #undef GEN_LDXF
9162 #undef GEN_LDFS
9163 #define GEN_LDF(name, ldop, opc, type)                                        \
9164 GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
9165 #define GEN_LDUF(name, ldop, opc, type)                                       \
9166 GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
9167 #define GEN_LDUXF(name, ldop, opc, type)                                      \
9168 GEN_HANDLER(name##ux, 0x1F, 0x17, opc, 0x00000001, type),
9169 #define GEN_LDXF(name, ldop, opc2, opc3, type)                                \
9170 GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type),
9171 #define GEN_LDFS(name, ldop, op, type)                                        \
9172 GEN_LDF(name, ldop, op | 0x20, type)                                          \
9173 GEN_LDUF(name, ldop, op | 0x21, type)                                         \
9174 GEN_LDUXF(name, ldop, op | 0x01, type)                                        \
9175 GEN_LDXF(name, ldop, 0x17, op | 0x00, type)
9176
9177 GEN_LDFS(lfd, ld64, 0x12, PPC_FLOAT)
9178 GEN_LDFS(lfs, ld32fs, 0x10, PPC_FLOAT)
9179 GEN_HANDLER_E(lfiwax, 0x1f, 0x17, 0x1a, 0x00000001, PPC_NONE, PPC2_ISA205),
9180 GEN_HANDLER_E(lfdp, 0x39, 0xFF, 0xFF, 0x00200003, PPC_NONE, PPC2_ISA205),
9181 GEN_HANDLER_E(lfdpx, 0x1F, 0x17, 0x18, 0x00200001, PPC_NONE, PPC2_ISA205),
9182
9183 #undef GEN_STF
9184 #undef GEN_STUF
9185 #undef GEN_STUXF
9186 #undef GEN_STXF
9187 #undef GEN_STFS
9188 #define GEN_STF(name, stop, opc, type)                                        \
9189 GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
9190 #define GEN_STUF(name, stop, opc, type)                                       \
9191 GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
9192 #define GEN_STUXF(name, stop, opc, type)                                      \
9193 GEN_HANDLER(name##ux, 0x1F, 0x17, opc, 0x00000001, type),
9194 #define GEN_STXF(name, stop, opc2, opc3, type)                                \
9195 GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type),
9196 #define GEN_STFS(name, stop, op, type)                                        \
9197 GEN_STF(name, stop, op | 0x20, type)                                          \
9198 GEN_STUF(name, stop, op | 0x21, type)                                         \
9199 GEN_STUXF(name, stop, op | 0x01, type)                                        \
9200 GEN_STXF(name, stop, 0x17, op | 0x00, type)
9201
9202 GEN_STFS(stfd, st64, 0x16, PPC_FLOAT)
9203 GEN_STFS(stfs, st32fs, 0x14, PPC_FLOAT)
9204 GEN_STXF(stfiw, st32fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX)
9205 GEN_HANDLER_E(stfdp, 0x3D, 0xFF, 0xFF, 0x00200003, PPC_NONE, PPC2_ISA205),
9206 GEN_HANDLER_E(stfdpx, 0x1F, 0x17, 0x1C, 0x00200001, PPC_NONE, PPC2_ISA205),
9207
9208 #undef GEN_CRLOGIC
9209 #define GEN_CRLOGIC(name, tcg_op, opc)                                        \
9210 GEN_HANDLER(name, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER)
9211 GEN_CRLOGIC(crand, tcg_gen_and_i32, 0x08),
9212 GEN_CRLOGIC(crandc, tcg_gen_andc_i32, 0x04),
9213 GEN_CRLOGIC(creqv, tcg_gen_eqv_i32, 0x09),
9214 GEN_CRLOGIC(crnand, tcg_gen_nand_i32, 0x07),
9215 GEN_CRLOGIC(crnor, tcg_gen_nor_i32, 0x01),
9216 GEN_CRLOGIC(cror, tcg_gen_or_i32, 0x0E),
9217 GEN_CRLOGIC(crorc, tcg_gen_orc_i32, 0x0D),
9218 GEN_CRLOGIC(crxor, tcg_gen_xor_i32, 0x06),
9219
9220 #undef GEN_MAC_HANDLER
9221 #define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
9222 GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC)
9223 GEN_MAC_HANDLER(macchw, 0x0C, 0x05),
9224 GEN_MAC_HANDLER(macchwo, 0x0C, 0x15),
9225 GEN_MAC_HANDLER(macchws, 0x0C, 0x07),
9226 GEN_MAC_HANDLER(macchwso, 0x0C, 0x17),
9227 GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06),
9228 GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16),
9229 GEN_MAC_HANDLER(macchwu, 0x0C, 0x04),
9230 GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14),
9231 GEN_MAC_HANDLER(machhw, 0x0C, 0x01),
9232 GEN_MAC_HANDLER(machhwo, 0x0C, 0x11),
9233 GEN_MAC_HANDLER(machhws, 0x0C, 0x03),
9234 GEN_MAC_HANDLER(machhwso, 0x0C, 0x13),
9235 GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02),
9236 GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12),
9237 GEN_MAC_HANDLER(machhwu, 0x0C, 0x00),
9238 GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10),
9239 GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D),
9240 GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D),
9241 GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F),
9242 GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F),
9243 GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C),
9244 GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C),
9245 GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E),
9246 GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E),
9247 GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05),
9248 GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15),
9249 GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07),
9250 GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17),
9251 GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01),
9252 GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11),
9253 GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03),
9254 GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13),
9255 GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D),
9256 GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D),
9257 GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F),
9258 GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F),
9259 GEN_MAC_HANDLER(mulchw, 0x08, 0x05),
9260 GEN_MAC_HANDLER(mulchwu, 0x08, 0x04),
9261 GEN_MAC_HANDLER(mulhhw, 0x08, 0x01),
9262 GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00),
9263 GEN_MAC_HANDLER(mullhw, 0x08, 0x0D),
9264 GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C),
9265
9266 #undef GEN_VR_LDX
9267 #undef GEN_VR_STX
9268 #undef GEN_VR_LVE
9269 #undef GEN_VR_STVE
9270 #define GEN_VR_LDX(name, opc2, opc3)                                          \
9271 GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
9272 #define GEN_VR_STX(name, opc2, opc3)                                          \
9273 GEN_HANDLER(st##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
9274 #define GEN_VR_LVE(name, opc2, opc3)                                    \
9275     GEN_HANDLER(lve##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
9276 #define GEN_VR_STVE(name, opc2, opc3)                                   \
9277     GEN_HANDLER(stve##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
9278 GEN_VR_LDX(lvx, 0x07, 0x03),
9279 GEN_VR_LDX(lvxl, 0x07, 0x0B),
9280 GEN_VR_LVE(bx, 0x07, 0x00),
9281 GEN_VR_LVE(hx, 0x07, 0x01),
9282 GEN_VR_LVE(wx, 0x07, 0x02),
9283 GEN_VR_STX(svx, 0x07, 0x07),
9284 GEN_VR_STX(svxl, 0x07, 0x0F),
9285 GEN_VR_STVE(bx, 0x07, 0x04),
9286 GEN_VR_STVE(hx, 0x07, 0x05),
9287 GEN_VR_STVE(wx, 0x07, 0x06),
9288
9289 #undef GEN_VX_LOGICAL
9290 #define GEN_VX_LOGICAL(name, tcg_op, opc2, opc3)                        \
9291 GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
9292 GEN_VX_LOGICAL(vand, tcg_gen_and_i64, 2, 16),
9293 GEN_VX_LOGICAL(vandc, tcg_gen_andc_i64, 2, 17),
9294 GEN_VX_LOGICAL(vor, tcg_gen_or_i64, 2, 18),
9295 GEN_VX_LOGICAL(vxor, tcg_gen_xor_i64, 2, 19),
9296 GEN_VX_LOGICAL(vnor, tcg_gen_nor_i64, 2, 20),
9297
9298 #undef GEN_VXFORM
9299 #define GEN_VXFORM(name, opc2, opc3)                                    \
9300 GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
9301 GEN_VXFORM(vaddubm, 0, 0),
9302 GEN_VXFORM(vadduhm, 0, 1),
9303 GEN_VXFORM(vadduwm, 0, 2),
9304 GEN_VXFORM(vsububm, 0, 16),
9305 GEN_VXFORM(vsubuhm, 0, 17),
9306 GEN_VXFORM(vsubuwm, 0, 18),
9307 GEN_VXFORM(vmaxub, 1, 0),
9308 GEN_VXFORM(vmaxuh, 1, 1),
9309 GEN_VXFORM(vmaxuw, 1, 2),
9310 GEN_VXFORM(vmaxsb, 1, 4),
9311 GEN_VXFORM(vmaxsh, 1, 5),
9312 GEN_VXFORM(vmaxsw, 1, 6),
9313 GEN_VXFORM(vminub, 1, 8),
9314 GEN_VXFORM(vminuh, 1, 9),
9315 GEN_VXFORM(vminuw, 1, 10),
9316 GEN_VXFORM(vminsb, 1, 12),
9317 GEN_VXFORM(vminsh, 1, 13),
9318 GEN_VXFORM(vminsw, 1, 14),
9319 GEN_VXFORM(vavgub, 1, 16),
9320 GEN_VXFORM(vavguh, 1, 17),
9321 GEN_VXFORM(vavguw, 1, 18),
9322 GEN_VXFORM(vavgsb, 1, 20),
9323 GEN_VXFORM(vavgsh, 1, 21),
9324 GEN_VXFORM(vavgsw, 1, 22),
9325 GEN_VXFORM(vmrghb, 6, 0),
9326 GEN_VXFORM(vmrghh, 6, 1),
9327 GEN_VXFORM(vmrghw, 6, 2),
9328 GEN_VXFORM(vmrglb, 6, 4),
9329 GEN_VXFORM(vmrglh, 6, 5),
9330 GEN_VXFORM(vmrglw, 6, 6),
9331 GEN_VXFORM(vmuloub, 4, 0),
9332 GEN_VXFORM(vmulouh, 4, 1),
9333 GEN_VXFORM(vmulosb, 4, 4),
9334 GEN_VXFORM(vmulosh, 4, 5),
9335 GEN_VXFORM(vmuleub, 4, 8),
9336 GEN_VXFORM(vmuleuh, 4, 9),
9337 GEN_VXFORM(vmulesb, 4, 12),
9338 GEN_VXFORM(vmulesh, 4, 13),
9339 GEN_VXFORM(vslb, 2, 4),
9340 GEN_VXFORM(vslh, 2, 5),
9341 GEN_VXFORM(vslw, 2, 6),
9342 GEN_VXFORM(vsrb, 2, 8),
9343 GEN_VXFORM(vsrh, 2, 9),
9344 GEN_VXFORM(vsrw, 2, 10),
9345 GEN_VXFORM(vsrab, 2, 12),
9346 GEN_VXFORM(vsrah, 2, 13),
9347 GEN_VXFORM(vsraw, 2, 14),
9348 GEN_VXFORM(vslo, 6, 16),
9349 GEN_VXFORM(vsro, 6, 17),
9350 GEN_VXFORM(vaddcuw, 0, 6),
9351 GEN_VXFORM(vsubcuw, 0, 22),
9352 GEN_VXFORM(vaddubs, 0, 8),
9353 GEN_VXFORM(vadduhs, 0, 9),
9354 GEN_VXFORM(vadduws, 0, 10),
9355 GEN_VXFORM(vaddsbs, 0, 12),
9356 GEN_VXFORM(vaddshs, 0, 13),
9357 GEN_VXFORM(vaddsws, 0, 14),
9358 GEN_VXFORM(vsububs, 0, 24),
9359 GEN_VXFORM(vsubuhs, 0, 25),
9360 GEN_VXFORM(vsubuws, 0, 26),
9361 GEN_VXFORM(vsubsbs, 0, 28),
9362 GEN_VXFORM(vsubshs, 0, 29),
9363 GEN_VXFORM(vsubsws, 0, 30),
9364 GEN_VXFORM(vrlb, 2, 0),
9365 GEN_VXFORM(vrlh, 2, 1),
9366 GEN_VXFORM(vrlw, 2, 2),
9367 GEN_VXFORM(vsl, 2, 7),
9368 GEN_VXFORM(vsr, 2, 11),
9369 GEN_VXFORM(vpkuhum, 7, 0),
9370 GEN_VXFORM(vpkuwum, 7, 1),
9371 GEN_VXFORM(vpkuhus, 7, 2),
9372 GEN_VXFORM(vpkuwus, 7, 3),
9373 GEN_VXFORM(vpkshus, 7, 4),
9374 GEN_VXFORM(vpkswus, 7, 5),
9375 GEN_VXFORM(vpkshss, 7, 6),
9376 GEN_VXFORM(vpkswss, 7, 7),
9377 GEN_VXFORM(vpkpx, 7, 12),
9378 GEN_VXFORM(vsum4ubs, 4, 24),
9379 GEN_VXFORM(vsum4sbs, 4, 28),
9380 GEN_VXFORM(vsum4shs, 4, 25),
9381 GEN_VXFORM(vsum2sws, 4, 26),
9382 GEN_VXFORM(vsumsws, 4, 30),
9383 GEN_VXFORM(vaddfp, 5, 0),
9384 GEN_VXFORM(vsubfp, 5, 1),
9385 GEN_VXFORM(vmaxfp, 5, 16),
9386 GEN_VXFORM(vminfp, 5, 17),
9387
9388 #undef GEN_VXRFORM1
9389 #undef GEN_VXRFORM
9390 #define GEN_VXRFORM1(opname, name, str, opc2, opc3)                     \
9391     GEN_HANDLER2(name, str, 0x4, opc2, opc3, 0x00000000, PPC_ALTIVEC),
9392 #define GEN_VXRFORM(name, opc2, opc3)                                \
9393     GEN_VXRFORM1(name, name, #name, opc2, opc3)                      \
9394     GEN_VXRFORM1(name##_dot, name##_, #name ".", opc2, (opc3 | (0x1 << 4)))
9395 GEN_VXRFORM(vcmpequb, 3, 0)
9396 GEN_VXRFORM(vcmpequh, 3, 1)
9397 GEN_VXRFORM(vcmpequw, 3, 2)
9398 GEN_VXRFORM(vcmpgtsb, 3, 12)
9399 GEN_VXRFORM(vcmpgtsh, 3, 13)
9400 GEN_VXRFORM(vcmpgtsw, 3, 14)
9401 GEN_VXRFORM(vcmpgtub, 3, 8)
9402 GEN_VXRFORM(vcmpgtuh, 3, 9)
9403 GEN_VXRFORM(vcmpgtuw, 3, 10)
9404 GEN_VXRFORM(vcmpeqfp, 3, 3)
9405 GEN_VXRFORM(vcmpgefp, 3, 7)
9406 GEN_VXRFORM(vcmpgtfp, 3, 11)
9407 GEN_VXRFORM(vcmpbfp, 3, 15)
9408
9409 #undef GEN_VXFORM_SIMM
9410 #define GEN_VXFORM_SIMM(name, opc2, opc3)                               \
9411     GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
9412 GEN_VXFORM_SIMM(vspltisb, 6, 12),
9413 GEN_VXFORM_SIMM(vspltish, 6, 13),
9414 GEN_VXFORM_SIMM(vspltisw, 6, 14),
9415
9416 #undef GEN_VXFORM_NOA
9417 #define GEN_VXFORM_NOA(name, opc2, opc3)                                \
9418     GEN_HANDLER(name, 0x04, opc2, opc3, 0x001f0000, PPC_ALTIVEC)
9419 GEN_VXFORM_NOA(vupkhsb, 7, 8),
9420 GEN_VXFORM_NOA(vupkhsh, 7, 9),
9421 GEN_VXFORM_NOA(vupklsb, 7, 10),
9422 GEN_VXFORM_NOA(vupklsh, 7, 11),
9423 GEN_VXFORM_NOA(vupkhpx, 7, 13),
9424 GEN_VXFORM_NOA(vupklpx, 7, 15),
9425 GEN_VXFORM_NOA(vrefp, 5, 4),
9426 GEN_VXFORM_NOA(vrsqrtefp, 5, 5),
9427 GEN_VXFORM_NOA(vexptefp, 5, 6),
9428 GEN_VXFORM_NOA(vlogefp, 5, 7),
9429 GEN_VXFORM_NOA(vrfim, 5, 8),
9430 GEN_VXFORM_NOA(vrfin, 5, 9),
9431 GEN_VXFORM_NOA(vrfip, 5, 10),
9432 GEN_VXFORM_NOA(vrfiz, 5, 11),
9433
9434 #undef GEN_VXFORM_UIMM
9435 #define GEN_VXFORM_UIMM(name, opc2, opc3)                               \
9436     GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
9437 GEN_VXFORM_UIMM(vspltb, 6, 8),
9438 GEN_VXFORM_UIMM(vsplth, 6, 9),
9439 GEN_VXFORM_UIMM(vspltw, 6, 10),
9440 GEN_VXFORM_UIMM(vcfux, 5, 12),
9441 GEN_VXFORM_UIMM(vcfsx, 5, 13),
9442 GEN_VXFORM_UIMM(vctuxs, 5, 14),
9443 GEN_VXFORM_UIMM(vctsxs, 5, 15),
9444
9445 #undef GEN_VAFORM_PAIRED
9446 #define GEN_VAFORM_PAIRED(name0, name1, opc2)                           \
9447     GEN_HANDLER(name0##_##name1, 0x04, opc2, 0xFF, 0x00000000, PPC_ALTIVEC)
9448 GEN_VAFORM_PAIRED(vmhaddshs, vmhraddshs, 16),
9449 GEN_VAFORM_PAIRED(vmsumubm, vmsummbm, 18),
9450 GEN_VAFORM_PAIRED(vmsumuhm, vmsumuhs, 19),
9451 GEN_VAFORM_PAIRED(vmsumshm, vmsumshs, 20),
9452 GEN_VAFORM_PAIRED(vsel, vperm, 21),
9453 GEN_VAFORM_PAIRED(vmaddfp, vnmsubfp, 23),
9454
9455 #undef GEN_SPE
9456 #define GEN_SPE(name0, name1, opc2, opc3, inval0, inval1, type) \
9457     GEN_OPCODE_DUAL(name0##_##name1, 0x04, opc2, opc3, inval0, inval1, type, PPC_NONE)
9458 GEN_SPE(evaddw,      speundef,    0x00, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
9459 GEN_SPE(evaddiw,     speundef,    0x01, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
9460 GEN_SPE(evsubfw,     speundef,    0x02, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
9461 GEN_SPE(evsubifw,    speundef,    0x03, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
9462 GEN_SPE(evabs,       evneg,       0x04, 0x08, 0x0000F800, 0x0000F800, PPC_SPE),
9463 GEN_SPE(evextsb,     evextsh,     0x05, 0x08, 0x0000F800, 0x0000F800, PPC_SPE),
9464 GEN_SPE(evrndw,      evcntlzw,    0x06, 0x08, 0x0000F800, 0x0000F800, PPC_SPE),
9465 GEN_SPE(evcntlsw,    brinc,       0x07, 0x08, 0x0000F800, 0x00000000, PPC_SPE),
9466 GEN_SPE(evmra,       speundef,    0x02, 0x13, 0x0000F800, 0xFFFFFFFF, PPC_SPE),
9467 GEN_SPE(speundef,    evand,       0x08, 0x08, 0xFFFFFFFF, 0x00000000, PPC_SPE),
9468 GEN_SPE(evandc,      speundef,    0x09, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
9469 GEN_SPE(evxor,       evor,        0x0B, 0x08, 0x00000000, 0x00000000, PPC_SPE),
9470 GEN_SPE(evnor,       eveqv,       0x0C, 0x08, 0x00000000, 0x00000000, PPC_SPE),
9471 GEN_SPE(evmwumi,     evmwsmi,     0x0C, 0x11, 0x00000000, 0x00000000, PPC_SPE),
9472 GEN_SPE(evmwumia,    evmwsmia,    0x1C, 0x11, 0x00000000, 0x00000000, PPC_SPE),
9473 GEN_SPE(evmwumiaa,   evmwsmiaa,   0x0C, 0x15, 0x00000000, 0x00000000, PPC_SPE),
9474 GEN_SPE(speundef,    evorc,       0x0D, 0x08, 0xFFFFFFFF, 0x00000000, PPC_SPE),
9475 GEN_SPE(evnand,      speundef,    0x0F, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
9476 GEN_SPE(evsrwu,      evsrws,      0x10, 0x08, 0x00000000, 0x00000000, PPC_SPE),
9477 GEN_SPE(evsrwiu,     evsrwis,     0x11, 0x08, 0x00000000, 0x00000000, PPC_SPE),
9478 GEN_SPE(evslw,       speundef,    0x12, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
9479 GEN_SPE(evslwi,      speundef,    0x13, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
9480 GEN_SPE(evrlw,       evsplati,    0x14, 0x08, 0x00000000, 0x0000F800, PPC_SPE),
9481 GEN_SPE(evrlwi,      evsplatfi,   0x15, 0x08, 0x00000000, 0x0000F800, PPC_SPE),
9482 GEN_SPE(evmergehi,   evmergelo,   0x16, 0x08, 0x00000000, 0x00000000, PPC_SPE),
9483 GEN_SPE(evmergehilo, evmergelohi, 0x17, 0x08, 0x00000000, 0x00000000, PPC_SPE),
9484 GEN_SPE(evcmpgtu,    evcmpgts,    0x18, 0x08, 0x00600000, 0x00600000, PPC_SPE),
9485 GEN_SPE(evcmpltu,    evcmplts,    0x19, 0x08, 0x00600000, 0x00600000, PPC_SPE),
9486 GEN_SPE(evcmpeq,     speundef,    0x1A, 0x08, 0x00600000, 0xFFFFFFFF, PPC_SPE),
9487
9488 GEN_SPE(evfsadd,     evfssub,     0x00, 0x0A, 0x00000000, 0x00000000, PPC_SPE_SINGLE),
9489 GEN_SPE(evfsabs,     evfsnabs,    0x02, 0x0A, 0x0000F800, 0x0000F800, PPC_SPE_SINGLE),
9490 GEN_SPE(evfsneg,     speundef,    0x03, 0x0A, 0x0000F800, 0xFFFFFFFF, PPC_SPE_SINGLE),
9491 GEN_SPE(evfsmul,     evfsdiv,     0x04, 0x0A, 0x00000000, 0x00000000, PPC_SPE_SINGLE),
9492 GEN_SPE(evfscmpgt,   evfscmplt,   0x06, 0x0A, 0x00600000, 0x00600000, PPC_SPE_SINGLE),
9493 GEN_SPE(evfscmpeq,   speundef,    0x07, 0x0A, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE),
9494 GEN_SPE(evfscfui,    evfscfsi,    0x08, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
9495 GEN_SPE(evfscfuf,    evfscfsf,    0x09, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
9496 GEN_SPE(evfsctui,    evfsctsi,    0x0A, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
9497 GEN_SPE(evfsctuf,    evfsctsf,    0x0B, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
9498 GEN_SPE(evfsctuiz,   speundef,    0x0C, 0x0A, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE),
9499 GEN_SPE(evfsctsiz,   speundef,    0x0D, 0x0A, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE),
9500 GEN_SPE(evfststgt,   evfststlt,   0x0E, 0x0A, 0x00600000, 0x00600000, PPC_SPE_SINGLE),
9501 GEN_SPE(evfststeq,   speundef,    0x0F, 0x0A, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE),
9502
9503 GEN_SPE(efsadd,      efssub,      0x00, 0x0B, 0x00000000, 0x00000000, PPC_SPE_SINGLE),
9504 GEN_SPE(efsabs,      efsnabs,     0x02, 0x0B, 0x0000F800, 0x0000F800, PPC_SPE_SINGLE),
9505 GEN_SPE(efsneg,      speundef,    0x03, 0x0B, 0x0000F800, 0xFFFFFFFF, PPC_SPE_SINGLE),
9506 GEN_SPE(efsmul,      efsdiv,      0x04, 0x0B, 0x00000000, 0x00000000, PPC_SPE_SINGLE),
9507 GEN_SPE(efscmpgt,    efscmplt,    0x06, 0x0B, 0x00600000, 0x00600000, PPC_SPE_SINGLE),
9508 GEN_SPE(efscmpeq,    efscfd,      0x07, 0x0B, 0x00600000, 0x00180000, PPC_SPE_SINGLE),
9509 GEN_SPE(efscfui,     efscfsi,     0x08, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
9510 GEN_SPE(efscfuf,     efscfsf,     0x09, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
9511 GEN_SPE(efsctui,     efsctsi,     0x0A, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
9512 GEN_SPE(efsctuf,     efsctsf,     0x0B, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
9513 GEN_SPE(efsctuiz,    speundef,    0x0C, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE),
9514 GEN_SPE(efsctsiz,    speundef,    0x0D, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE),
9515 GEN_SPE(efststgt,    efststlt,    0x0E, 0x0B, 0x00600000, 0x00600000, PPC_SPE_SINGLE),
9516 GEN_SPE(efststeq,    speundef,    0x0F, 0x0B, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE),
9517
9518 GEN_SPE(efdadd,      efdsub,      0x10, 0x0B, 0x00000000, 0x00000000, PPC_SPE_DOUBLE),
9519 GEN_SPE(efdcfuid,    efdcfsid,    0x11, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
9520 GEN_SPE(efdabs,      efdnabs,     0x12, 0x0B, 0x0000F800, 0x0000F800, PPC_SPE_DOUBLE),
9521 GEN_SPE(efdneg,      speundef,    0x13, 0x0B, 0x0000F800, 0xFFFFFFFF, PPC_SPE_DOUBLE),
9522 GEN_SPE(efdmul,      efddiv,      0x14, 0x0B, 0x00000000, 0x00000000, PPC_SPE_DOUBLE),
9523 GEN_SPE(efdctuidz,   efdctsidz,   0x15, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
9524 GEN_SPE(efdcmpgt,    efdcmplt,    0x16, 0x0B, 0x00600000, 0x00600000, PPC_SPE_DOUBLE),
9525 GEN_SPE(efdcmpeq,    efdcfs,      0x17, 0x0B, 0x00600000, 0x00180000, PPC_SPE_DOUBLE),
9526 GEN_SPE(efdcfui,     efdcfsi,     0x18, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
9527 GEN_SPE(efdcfuf,     efdcfsf,     0x19, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
9528 GEN_SPE(efdctui,     efdctsi,     0x1A, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
9529 GEN_SPE(efdctuf,     efdctsf,     0x1B, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
9530 GEN_SPE(efdctuiz,    speundef,    0x1C, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_DOUBLE),
9531 GEN_SPE(efdctsiz,    speundef,    0x1D, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_DOUBLE),
9532 GEN_SPE(efdtstgt,    efdtstlt,    0x1E, 0x0B, 0x00600000, 0x00600000, PPC_SPE_DOUBLE),
9533 GEN_SPE(efdtsteq,    speundef,    0x1F, 0x0B, 0x00600000, 0xFFFFFFFF, PPC_SPE_DOUBLE),
9534
9535 #undef GEN_SPEOP_LDST
9536 #define GEN_SPEOP_LDST(name, opc2, sh)                                        \
9537 GEN_HANDLER(name, 0x04, opc2, 0x0C, 0x00000000, PPC_SPE)
9538 GEN_SPEOP_LDST(evldd, 0x00, 3),
9539 GEN_SPEOP_LDST(evldw, 0x01, 3),
9540 GEN_SPEOP_LDST(evldh, 0x02, 3),
9541 GEN_SPEOP_LDST(evlhhesplat, 0x04, 1),
9542 GEN_SPEOP_LDST(evlhhousplat, 0x06, 1),
9543 GEN_SPEOP_LDST(evlhhossplat, 0x07, 1),
9544 GEN_SPEOP_LDST(evlwhe, 0x08, 2),
9545 GEN_SPEOP_LDST(evlwhou, 0x0A, 2),
9546 GEN_SPEOP_LDST(evlwhos, 0x0B, 2),
9547 GEN_SPEOP_LDST(evlwwsplat, 0x0C, 2),
9548 GEN_SPEOP_LDST(evlwhsplat, 0x0E, 2),
9549
9550 GEN_SPEOP_LDST(evstdd, 0x10, 3),
9551 GEN_SPEOP_LDST(evstdw, 0x11, 3),
9552 GEN_SPEOP_LDST(evstdh, 0x12, 3),
9553 GEN_SPEOP_LDST(evstwhe, 0x18, 2),
9554 GEN_SPEOP_LDST(evstwho, 0x1A, 2),
9555 GEN_SPEOP_LDST(evstwwe, 0x1C, 2),
9556 GEN_SPEOP_LDST(evstwwo, 0x1E, 2),
9557 };
9558
9559 #include "helper_regs.h"
9560 #include "translate_init.c"
9561
9562 /*****************************************************************************/
9563 /* Misc PowerPC helpers */
9564 void ppc_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
9565                         int flags)
9566 {
9567 #define RGPL  4
9568 #define RFPL  4
9569
9570     PowerPCCPU *cpu = POWERPC_CPU(cs);
9571     CPUPPCState *env = &cpu->env;
9572     int i;
9573
9574     cpu_fprintf(f, "NIP " TARGET_FMT_lx "   LR " TARGET_FMT_lx " CTR "
9575                 TARGET_FMT_lx " XER " TARGET_FMT_lx "\n",
9576                 env->nip, env->lr, env->ctr, cpu_read_xer(env));
9577     cpu_fprintf(f, "MSR " TARGET_FMT_lx " HID0 " TARGET_FMT_lx "  HF "
9578                 TARGET_FMT_lx " idx %d\n", env->msr, env->spr[SPR_HID0],
9579                 env->hflags, env->mmu_idx);
9580 #if !defined(NO_TIMER_DUMP)
9581     cpu_fprintf(f, "TB %08" PRIu32 " %08" PRIu64
9582 #if !defined(CONFIG_USER_ONLY)
9583                 " DECR %08" PRIu32
9584 #endif
9585                 "\n",
9586                 cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
9587 #if !defined(CONFIG_USER_ONLY)
9588                 , cpu_ppc_load_decr(env)
9589 #endif
9590                 );
9591 #endif
9592     for (i = 0; i < 32; i++) {
9593         if ((i & (RGPL - 1)) == 0)
9594             cpu_fprintf(f, "GPR%02d", i);
9595         cpu_fprintf(f, " %016" PRIx64, ppc_dump_gpr(env, i));
9596         if ((i & (RGPL - 1)) == (RGPL - 1))
9597             cpu_fprintf(f, "\n");
9598     }
9599     cpu_fprintf(f, "CR ");
9600     for (i = 0; i < 8; i++)
9601         cpu_fprintf(f, "%01x", env->crf[i]);
9602     cpu_fprintf(f, "  [");
9603     for (i = 0; i < 8; i++) {
9604         char a = '-';
9605         if (env->crf[i] & 0x08)
9606             a = 'L';
9607         else if (env->crf[i] & 0x04)
9608             a = 'G';
9609         else if (env->crf[i] & 0x02)
9610             a = 'E';
9611         cpu_fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
9612     }
9613     cpu_fprintf(f, " ]             RES " TARGET_FMT_lx "\n",
9614                 env->reserve_addr);
9615     for (i = 0; i < 32; i++) {
9616         if ((i & (RFPL - 1)) == 0)
9617             cpu_fprintf(f, "FPR%02d", i);
9618         cpu_fprintf(f, " %016" PRIx64, *((uint64_t *)&env->fpr[i]));
9619         if ((i & (RFPL - 1)) == (RFPL - 1))
9620             cpu_fprintf(f, "\n");
9621     }
9622     cpu_fprintf(f, "FPSCR " TARGET_FMT_lx "\n", env->fpscr);
9623 #if !defined(CONFIG_USER_ONLY)
9624     cpu_fprintf(f, " SRR0 " TARGET_FMT_lx "  SRR1 " TARGET_FMT_lx
9625                    "    PVR " TARGET_FMT_lx " VRSAVE " TARGET_FMT_lx "\n",
9626                 env->spr[SPR_SRR0], env->spr[SPR_SRR1],
9627                 env->spr[SPR_PVR], env->spr[SPR_VRSAVE]);
9628
9629     cpu_fprintf(f, "SPRG0 " TARGET_FMT_lx " SPRG1 " TARGET_FMT_lx
9630                    "  SPRG2 " TARGET_FMT_lx "  SPRG3 " TARGET_FMT_lx "\n",
9631                 env->spr[SPR_SPRG0], env->spr[SPR_SPRG1],
9632                 env->spr[SPR_SPRG2], env->spr[SPR_SPRG3]);
9633
9634     cpu_fprintf(f, "SPRG4 " TARGET_FMT_lx " SPRG5 " TARGET_FMT_lx
9635                    "  SPRG6 " TARGET_FMT_lx "  SPRG7 " TARGET_FMT_lx "\n",
9636                 env->spr[SPR_SPRG4], env->spr[SPR_SPRG5],
9637                 env->spr[SPR_SPRG6], env->spr[SPR_SPRG7]);
9638
9639     if (env->excp_model == POWERPC_EXCP_BOOKE) {
9640         cpu_fprintf(f, "CSRR0 " TARGET_FMT_lx " CSRR1 " TARGET_FMT_lx
9641                        " MCSRR0 " TARGET_FMT_lx " MCSRR1 " TARGET_FMT_lx "\n",
9642                     env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1],
9643                     env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1]);
9644
9645         cpu_fprintf(f, "  TCR " TARGET_FMT_lx "   TSR " TARGET_FMT_lx
9646                        "    ESR " TARGET_FMT_lx "   DEAR " TARGET_FMT_lx "\n",
9647                     env->spr[SPR_BOOKE_TCR], env->spr[SPR_BOOKE_TSR],
9648                     env->spr[SPR_BOOKE_ESR], env->spr[SPR_BOOKE_DEAR]);
9649
9650         cpu_fprintf(f, "  PIR " TARGET_FMT_lx " DECAR " TARGET_FMT_lx
9651                        "   IVPR " TARGET_FMT_lx "   EPCR " TARGET_FMT_lx "\n",
9652                     env->spr[SPR_BOOKE_PIR], env->spr[SPR_BOOKE_DECAR],
9653                     env->spr[SPR_BOOKE_IVPR], env->spr[SPR_BOOKE_EPCR]);
9654
9655         cpu_fprintf(f, " MCSR " TARGET_FMT_lx " SPRG8 " TARGET_FMT_lx
9656                        "    EPR " TARGET_FMT_lx "\n",
9657                     env->spr[SPR_BOOKE_MCSR], env->spr[SPR_BOOKE_SPRG8],
9658                     env->spr[SPR_BOOKE_EPR]);
9659
9660         /* FSL-specific */
9661         cpu_fprintf(f, " MCAR " TARGET_FMT_lx "  PID1 " TARGET_FMT_lx
9662                        "   PID2 " TARGET_FMT_lx "    SVR " TARGET_FMT_lx "\n",
9663                     env->spr[SPR_Exxx_MCAR], env->spr[SPR_BOOKE_PID1],
9664                     env->spr[SPR_BOOKE_PID2], env->spr[SPR_E500_SVR]);
9665
9666         /*
9667          * IVORs are left out as they are large and do not change often --
9668          * they can be read with "p $ivor0", "p $ivor1", etc.
9669          */
9670     }
9671
9672 #if defined(TARGET_PPC64)
9673     if (env->flags & POWERPC_FLAG_CFAR) {
9674         cpu_fprintf(f, " CFAR " TARGET_FMT_lx"\n", env->cfar);
9675     }
9676 #endif
9677
9678     switch (env->mmu_model) {
9679     case POWERPC_MMU_32B:
9680     case POWERPC_MMU_601:
9681     case POWERPC_MMU_SOFT_6xx:
9682     case POWERPC_MMU_SOFT_74xx:
9683 #if defined(TARGET_PPC64)
9684     case POWERPC_MMU_64B:
9685 #endif
9686         cpu_fprintf(f, " SDR1 " TARGET_FMT_lx "\n", env->spr[SPR_SDR1]);
9687         break;
9688     case POWERPC_MMU_BOOKE206:
9689         cpu_fprintf(f, " MAS0 " TARGET_FMT_lx "  MAS1 " TARGET_FMT_lx
9690                        "   MAS2 " TARGET_FMT_lx "   MAS3 " TARGET_FMT_lx "\n",
9691                     env->spr[SPR_BOOKE_MAS0], env->spr[SPR_BOOKE_MAS1],
9692                     env->spr[SPR_BOOKE_MAS2], env->spr[SPR_BOOKE_MAS3]);
9693
9694         cpu_fprintf(f, " MAS4 " TARGET_FMT_lx "  MAS6 " TARGET_FMT_lx
9695                        "   MAS7 " TARGET_FMT_lx "    PID " TARGET_FMT_lx "\n",
9696                     env->spr[SPR_BOOKE_MAS4], env->spr[SPR_BOOKE_MAS6],
9697                     env->spr[SPR_BOOKE_MAS7], env->spr[SPR_BOOKE_PID]);
9698
9699         cpu_fprintf(f, "MMUCFG " TARGET_FMT_lx " TLB0CFG " TARGET_FMT_lx
9700                        " TLB1CFG " TARGET_FMT_lx "\n",
9701                     env->spr[SPR_MMUCFG], env->spr[SPR_BOOKE_TLB0CFG],
9702                     env->spr[SPR_BOOKE_TLB1CFG]);
9703         break;
9704     default:
9705         break;
9706     }
9707 #endif
9708
9709 #undef RGPL
9710 #undef RFPL
9711 }
9712
9713 void ppc_cpu_dump_statistics(CPUState *cs, FILE*f,
9714                              fprintf_function cpu_fprintf, int flags)
9715 {
9716 #if defined(DO_PPC_STATISTICS)
9717     PowerPCCPU *cpu = POWERPC_CPU(cs);
9718     opc_handler_t **t1, **t2, **t3, *handler;
9719     int op1, op2, op3;
9720
9721     t1 = cpu->env.opcodes;
9722     for (op1 = 0; op1 < 64; op1++) {
9723         handler = t1[op1];
9724         if (is_indirect_opcode(handler)) {
9725             t2 = ind_table(handler);
9726             for (op2 = 0; op2 < 32; op2++) {
9727                 handler = t2[op2];
9728                 if (is_indirect_opcode(handler)) {
9729                     t3 = ind_table(handler);
9730                     for (op3 = 0; op3 < 32; op3++) {
9731                         handler = t3[op3];
9732                         if (handler->count == 0)
9733                             continue;
9734                         cpu_fprintf(f, "%02x %02x %02x (%02x %04d) %16s: "
9735                                     "%016" PRIx64 " %" PRId64 "\n",
9736                                     op1, op2, op3, op1, (op3 << 5) | op2,
9737                                     handler->oname,
9738                                     handler->count, handler->count);
9739                     }
9740                 } else {
9741                     if (handler->count == 0)
9742                         continue;
9743                     cpu_fprintf(f, "%02x %02x    (%02x %04d) %16s: "
9744                                 "%016" PRIx64 " %" PRId64 "\n",
9745                                 op1, op2, op1, op2, handler->oname,
9746                                 handler->count, handler->count);
9747                 }
9748             }
9749         } else {
9750             if (handler->count == 0)
9751                 continue;
9752             cpu_fprintf(f, "%02x       (%02x     ) %16s: %016" PRIx64
9753                         " %" PRId64 "\n",
9754                         op1, op1, handler->oname,
9755                         handler->count, handler->count);
9756         }
9757     }
9758 #endif
9759 }
9760
9761 /*****************************************************************************/
9762 static inline void gen_intermediate_code_internal(PowerPCCPU *cpu,
9763                                                   TranslationBlock *tb,
9764                                                   bool search_pc)
9765 {
9766     CPUState *cs = CPU(cpu);
9767     CPUPPCState *env = &cpu->env;
9768     DisasContext ctx, *ctxp = &ctx;
9769     opc_handler_t **table, *handler;
9770     target_ulong pc_start;
9771     uint16_t *gen_opc_end;
9772     CPUBreakpoint *bp;
9773     int j, lj = -1;
9774     int num_insns;
9775     int max_insns;
9776
9777     pc_start = tb->pc;
9778     gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
9779     ctx.nip = pc_start;
9780     ctx.tb = tb;
9781     ctx.exception = POWERPC_EXCP_NONE;
9782     ctx.spr_cb = env->spr_cb;
9783     ctx.mem_idx = env->mmu_idx;
9784     ctx.insns_flags = env->insns_flags;
9785     ctx.insns_flags2 = env->insns_flags2;
9786     ctx.access_type = -1;
9787     ctx.le_mode = env->hflags & (1 << MSR_LE) ? 1 : 0;
9788 #if defined(TARGET_PPC64)
9789     ctx.sf_mode = msr_is_64bit(env, env->msr);
9790     ctx.has_cfar = !!(env->flags & POWERPC_FLAG_CFAR);
9791 #endif
9792     ctx.fpu_enabled = msr_fp;
9793     if ((env->flags & POWERPC_FLAG_SPE) && msr_spe)
9794         ctx.spe_enabled = msr_spe;
9795     else
9796         ctx.spe_enabled = 0;
9797     if ((env->flags & POWERPC_FLAG_VRE) && msr_vr)
9798         ctx.altivec_enabled = msr_vr;
9799     else
9800         ctx.altivec_enabled = 0;
9801     if ((env->flags & POWERPC_FLAG_VSX) && msr_vsx) {
9802         ctx.vsx_enabled = msr_vsx;
9803     } else {
9804         ctx.vsx_enabled = 0;
9805     }
9806     if ((env->flags & POWERPC_FLAG_SE) && msr_se)
9807         ctx.singlestep_enabled = CPU_SINGLE_STEP;
9808     else
9809         ctx.singlestep_enabled = 0;
9810     if ((env->flags & POWERPC_FLAG_BE) && msr_be)
9811         ctx.singlestep_enabled |= CPU_BRANCH_STEP;
9812     if (unlikely(cs->singlestep_enabled)) {
9813         ctx.singlestep_enabled |= GDBSTUB_SINGLE_STEP;
9814     }
9815 #if defined (DO_SINGLE_STEP) && 0
9816     /* Single step trace mode */
9817     msr_se = 1;
9818 #endif
9819     num_insns = 0;
9820     max_insns = tb->cflags & CF_COUNT_MASK;
9821     if (max_insns == 0)
9822         max_insns = CF_COUNT_MASK;
9823
9824     gen_tb_start();
9825     /* Set env in case of segfault during code fetch */
9826     while (ctx.exception == POWERPC_EXCP_NONE
9827             && tcg_ctx.gen_opc_ptr < gen_opc_end) {
9828         if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
9829             QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
9830                 if (bp->pc == ctx.nip) {
9831                     gen_debug_exception(ctxp);
9832                     break;
9833                 }
9834             }
9835         }
9836         if (unlikely(search_pc)) {
9837             j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
9838             if (lj < j) {
9839                 lj++;
9840                 while (lj < j)
9841                     tcg_ctx.gen_opc_instr_start[lj++] = 0;
9842             }
9843             tcg_ctx.gen_opc_pc[lj] = ctx.nip;
9844             tcg_ctx.gen_opc_instr_start[lj] = 1;
9845             tcg_ctx.gen_opc_icount[lj] = num_insns;
9846         }
9847         LOG_DISAS("----------------\n");
9848         LOG_DISAS("nip=" TARGET_FMT_lx " super=%d ir=%d\n",
9849                   ctx.nip, ctx.mem_idx, (int)msr_ir);
9850         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
9851             gen_io_start();
9852         if (unlikely(ctx.le_mode)) {
9853             ctx.opcode = bswap32(cpu_ldl_code(env, ctx.nip));
9854         } else {
9855             ctx.opcode = cpu_ldl_code(env, ctx.nip);
9856         }
9857         LOG_DISAS("translate opcode %08x (%02x %02x %02x) (%s)\n",
9858                     ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
9859                     opc3(ctx.opcode), ctx.le_mode ? "little" : "big");
9860         if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
9861             tcg_gen_debug_insn_start(ctx.nip);
9862         }
9863         ctx.nip += 4;
9864         table = env->opcodes;
9865         num_insns++;
9866         handler = table[opc1(ctx.opcode)];
9867         if (is_indirect_opcode(handler)) {
9868             table = ind_table(handler);
9869             handler = table[opc2(ctx.opcode)];
9870             if (is_indirect_opcode(handler)) {
9871                 table = ind_table(handler);
9872                 handler = table[opc3(ctx.opcode)];
9873             }
9874         }
9875         /* Is opcode *REALLY* valid ? */
9876         if (unlikely(handler->handler == &gen_invalid)) {
9877             if (qemu_log_enabled()) {
9878                 qemu_log("invalid/unsupported opcode: "
9879                          "%02x - %02x - %02x (%08x) " TARGET_FMT_lx " %d\n",
9880                          opc1(ctx.opcode), opc2(ctx.opcode),
9881                          opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, (int)msr_ir);
9882             }
9883         } else {
9884             uint32_t inval;
9885
9886             if (unlikely(handler->type & (PPC_SPE | PPC_SPE_SINGLE | PPC_SPE_DOUBLE) && Rc(ctx.opcode))) {
9887                 inval = handler->inval2;
9888             } else {
9889                 inval = handler->inval1;
9890             }
9891
9892             if (unlikely((ctx.opcode & inval) != 0)) {
9893                 if (qemu_log_enabled()) {
9894                     qemu_log("invalid bits: %08x for opcode: "
9895                              "%02x - %02x - %02x (%08x) " TARGET_FMT_lx "\n",
9896                              ctx.opcode & inval, opc1(ctx.opcode),
9897                              opc2(ctx.opcode), opc3(ctx.opcode),
9898                              ctx.opcode, ctx.nip - 4);
9899                 }
9900                 gen_inval_exception(ctxp, POWERPC_EXCP_INVAL_INVAL);
9901                 break;
9902             }
9903         }
9904         (*(handler->handler))(&ctx);
9905 #if defined(DO_PPC_STATISTICS)
9906         handler->count++;
9907 #endif
9908         /* Check trace mode exceptions */
9909         if (unlikely(ctx.singlestep_enabled & CPU_SINGLE_STEP &&
9910                      (ctx.nip <= 0x100 || ctx.nip > 0xF00) &&
9911                      ctx.exception != POWERPC_SYSCALL &&
9912                      ctx.exception != POWERPC_EXCP_TRAP &&
9913                      ctx.exception != POWERPC_EXCP_BRANCH)) {
9914             gen_exception(ctxp, POWERPC_EXCP_TRACE);
9915         } else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
9916                             (cs->singlestep_enabled) ||
9917                             singlestep ||
9918                             num_insns >= max_insns)) {
9919             /* if we reach a page boundary or are single stepping, stop
9920              * generation
9921              */
9922             break;
9923         }
9924     }
9925     if (tb->cflags & CF_LAST_IO)
9926         gen_io_end();
9927     if (ctx.exception == POWERPC_EXCP_NONE) {
9928         gen_goto_tb(&ctx, 0, ctx.nip);
9929     } else if (ctx.exception != POWERPC_EXCP_BRANCH) {
9930         if (unlikely(cs->singlestep_enabled)) {
9931             gen_debug_exception(ctxp);
9932         }
9933         /* Generate the return instruction */
9934         tcg_gen_exit_tb(0);
9935     }
9936     gen_tb_end(tb, num_insns);
9937     *tcg_ctx.gen_opc_ptr = INDEX_op_end;
9938     if (unlikely(search_pc)) {
9939         j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
9940         lj++;
9941         while (lj <= j)
9942             tcg_ctx.gen_opc_instr_start[lj++] = 0;
9943     } else {
9944         tb->size = ctx.nip - pc_start;
9945         tb->icount = num_insns;
9946     }
9947 #if defined(DEBUG_DISAS)
9948     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
9949         int flags;
9950         flags = env->bfd_mach;
9951         flags |= ctx.le_mode << 16;
9952         qemu_log("IN: %s\n", lookup_symbol(pc_start));
9953         log_target_disas(env, pc_start, ctx.nip - pc_start, flags);
9954         qemu_log("\n");
9955     }
9956 #endif
9957 }
9958
9959 void gen_intermediate_code (CPUPPCState *env, struct TranslationBlock *tb)
9960 {
9961     gen_intermediate_code_internal(ppc_env_get_cpu(env), tb, false);
9962 }
9963
9964 void gen_intermediate_code_pc (CPUPPCState *env, struct TranslationBlock *tb)
9965 {
9966     gen_intermediate_code_internal(ppc_env_get_cpu(env), tb, true);
9967 }
9968
9969 void restore_state_to_opc(CPUPPCState *env, TranslationBlock *tb, int pc_pos)
9970 {
9971     env->nip = tcg_ctx.gen_opc_pc[pc_pos];
9972 }
This page took 0.560631 seconds and 2 git commands to generate.