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