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