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