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