]> Git Repo - qemu.git/blob - target-ppc/translate.c
Merge remote branch 'amit/for-anthony' into staging
[qemu.git] / target-ppc / translate.c
1 /*
2  *  PowerPC emulation for qemu: main translation routines.
3  *
4  *  Copyright (c) 2003-2007 Jocelyn Mayer
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18  */
19 #include <stdarg.h>
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <inttypes.h>
24
25 #include "cpu.h"
26 #include "exec-all.h"
27 #include "disas.h"
28 #include "tcg-op.h"
29 #include "qemu-common.h"
30 #include "host-utils.h"
31
32 #include "helper.h"
33 #define GEN_HELPER 1
34 #include "helper.h"
35
36 #define CPU_SINGLE_STEP 0x1
37 #define CPU_BRANCH_STEP 0x2
38 #define GDBSTUB_SINGLE_STEP 0x4
39
40 /* Include definitions for instructions classes and implementations flags */
41 //#define PPC_DEBUG_DISAS
42 //#define DO_PPC_STATISTICS
43
44 #ifdef PPC_DEBUG_DISAS
45 #  define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
46 #else
47 #  define LOG_DISAS(...) do { } while (0)
48 #endif
49 /*****************************************************************************/
50 /* Code translation helpers                                                  */
51
52 /* global register indexes */
53 static TCGv_ptr cpu_env;
54 static char cpu_reg_names[10*3 + 22*4 /* GPR */
55 #if !defined(TARGET_PPC64)
56     + 10*4 + 22*5 /* SPE GPRh */
57 #endif
58     + 10*4 + 22*5 /* FPR */
59     + 2*(10*6 + 22*7) /* AVRh, AVRl */
60     + 8*5 /* CRF */];
61 static TCGv cpu_gpr[32];
62 #if !defined(TARGET_PPC64)
63 static TCGv cpu_gprh[32];
64 #endif
65 static TCGv_i64 cpu_fpr[32];
66 static TCGv_i64 cpu_avrh[32], cpu_avrl[32];
67 static TCGv_i32 cpu_crf[8];
68 static TCGv cpu_nip;
69 static TCGv cpu_msr;
70 static TCGv cpu_ctr;
71 static TCGv cpu_lr;
72 static TCGv cpu_xer;
73 static TCGv cpu_reserve;
74 static TCGv_i32 cpu_fpscr;
75 static TCGv_i32 cpu_access_type;
76
77 #include "gen-icount.h"
78
79 void ppc_translate_init(void)
80 {
81     int i;
82     char* p;
83     size_t cpu_reg_names_size;
84     static int done_init = 0;
85
86     if (done_init)
87         return;
88
89     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
90
91     p = cpu_reg_names;
92     cpu_reg_names_size = sizeof(cpu_reg_names);
93
94     for (i = 0; i < 8; i++) {
95         snprintf(p, cpu_reg_names_size, "crf%d", i);
96         cpu_crf[i] = tcg_global_mem_new_i32(TCG_AREG0,
97                                             offsetof(CPUState, crf[i]), p);
98         p += 5;
99         cpu_reg_names_size -= 5;
100     }
101
102     for (i = 0; i < 32; i++) {
103         snprintf(p, cpu_reg_names_size, "r%d", i);
104         cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
105                                         offsetof(CPUState, gpr[i]), p);
106         p += (i < 10) ? 3 : 4;
107         cpu_reg_names_size -= (i < 10) ? 3 : 4;
108 #if !defined(TARGET_PPC64)
109         snprintf(p, cpu_reg_names_size, "r%dH", i);
110         cpu_gprh[i] = tcg_global_mem_new_i32(TCG_AREG0,
111                                              offsetof(CPUState, gprh[i]), p);
112         p += (i < 10) ? 4 : 5;
113         cpu_reg_names_size -= (i < 10) ? 4 : 5;
114 #endif
115
116         snprintf(p, cpu_reg_names_size, "fp%d", i);
117         cpu_fpr[i] = tcg_global_mem_new_i64(TCG_AREG0,
118                                             offsetof(CPUState, fpr[i]), p);
119         p += (i < 10) ? 4 : 5;
120         cpu_reg_names_size -= (i < 10) ? 4 : 5;
121
122         snprintf(p, cpu_reg_names_size, "avr%dH", i);
123 #ifdef HOST_WORDS_BIGENDIAN
124         cpu_avrh[i] = tcg_global_mem_new_i64(TCG_AREG0,
125                                              offsetof(CPUState, avr[i].u64[0]), p);
126 #else
127         cpu_avrh[i] = tcg_global_mem_new_i64(TCG_AREG0,
128                                              offsetof(CPUState, avr[i].u64[1]), p);
129 #endif
130         p += (i < 10) ? 6 : 7;
131         cpu_reg_names_size -= (i < 10) ? 6 : 7;
132
133         snprintf(p, cpu_reg_names_size, "avr%dL", i);
134 #ifdef HOST_WORDS_BIGENDIAN
135         cpu_avrl[i] = tcg_global_mem_new_i64(TCG_AREG0,
136                                              offsetof(CPUState, avr[i].u64[1]), p);
137 #else
138         cpu_avrl[i] = tcg_global_mem_new_i64(TCG_AREG0,
139                                              offsetof(CPUState, avr[i].u64[0]), p);
140 #endif
141         p += (i < 10) ? 6 : 7;
142         cpu_reg_names_size -= (i < 10) ? 6 : 7;
143     }
144
145     cpu_nip = tcg_global_mem_new(TCG_AREG0,
146                                  offsetof(CPUState, nip), "nip");
147
148     cpu_msr = tcg_global_mem_new(TCG_AREG0,
149                                  offsetof(CPUState, msr), "msr");
150
151     cpu_ctr = tcg_global_mem_new(TCG_AREG0,
152                                  offsetof(CPUState, ctr), "ctr");
153
154     cpu_lr = tcg_global_mem_new(TCG_AREG0,
155                                 offsetof(CPUState, lr), "lr");
156
157     cpu_xer = tcg_global_mem_new(TCG_AREG0,
158                                  offsetof(CPUState, xer), "xer");
159
160     cpu_reserve = tcg_global_mem_new(TCG_AREG0,
161                                      offsetof(CPUState, reserve_addr),
162                                      "reserve_addr");
163
164     cpu_fpscr = tcg_global_mem_new_i32(TCG_AREG0,
165                                        offsetof(CPUState, fpscr), "fpscr");
166
167     cpu_access_type = tcg_global_mem_new_i32(TCG_AREG0,
168                                              offsetof(CPUState, access_type), "access_type");
169
170     /* register helpers */
171 #define GEN_HELPER 2
172 #include "helper.h"
173
174     done_init = 1;
175 }
176
177 /* internal defines */
178 typedef struct DisasContext {
179     struct TranslationBlock *tb;
180     target_ulong nip;
181     uint32_t opcode;
182     uint32_t exception;
183     /* Routine used to access memory */
184     int mem_idx;
185     int access_type;
186     /* Translation flags */
187     int le_mode;
188 #if defined(TARGET_PPC64)
189     int sf_mode;
190 #endif
191     int fpu_enabled;
192     int altivec_enabled;
193     int spe_enabled;
194     ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
195     int singlestep_enabled;
196 } DisasContext;
197
198 struct opc_handler_t {
199     /* invalid bits */
200     uint32_t inval;
201     /* instruction type */
202     uint64_t type;
203     /* handler */
204     void (*handler)(DisasContext *ctx);
205 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
206     const char *oname;
207 #endif
208 #if defined(DO_PPC_STATISTICS)
209     uint64_t count;
210 #endif
211 };
212
213 static 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, t1;
1790
1791     t0 = tcg_temp_new();
1792     /* AND rS with a mask that is 0 when rB >= 0x20 */
1793 #if defined(TARGET_PPC64)
1794     tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3a);
1795     tcg_gen_sari_tl(t0, t0, 0x3f);
1796 #else
1797     tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1a);
1798     tcg_gen_sari_tl(t0, t0, 0x1f);
1799 #endif
1800     tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
1801     t1 = tcg_temp_new();
1802     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1f);
1803     tcg_gen_shl_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
1804     tcg_temp_free(t1);
1805     tcg_temp_free(t0);
1806     tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
1807     if (unlikely(Rc(ctx->opcode) != 0))
1808         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1809 }
1810
1811 /* sraw & sraw. */
1812 static void gen_sraw(DisasContext *ctx)
1813 {
1814     gen_helper_sraw(cpu_gpr[rA(ctx->opcode)],
1815                     cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1816     if (unlikely(Rc(ctx->opcode) != 0))
1817         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1818 }
1819
1820 /* srawi & srawi. */
1821 static void gen_srawi(DisasContext *ctx)
1822 {
1823     int sh = SH(ctx->opcode);
1824     if (sh != 0) {
1825         int l1, l2;
1826         TCGv t0;
1827         l1 = gen_new_label();
1828         l2 = gen_new_label();
1829         t0 = tcg_temp_local_new();
1830         tcg_gen_ext32s_tl(t0, cpu_gpr[rS(ctx->opcode)]);
1831         tcg_gen_brcondi_tl(TCG_COND_GE, t0, 0, l1);
1832         tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1ULL << sh) - 1);
1833         tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
1834         tcg_gen_ori_tl(cpu_xer, cpu_xer, 1 << XER_CA);
1835         tcg_gen_br(l2);
1836         gen_set_label(l1);
1837         tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
1838         gen_set_label(l2);
1839         tcg_gen_ext32s_tl(t0, cpu_gpr[rS(ctx->opcode)]);
1840         tcg_gen_sari_tl(cpu_gpr[rA(ctx->opcode)], t0, sh);
1841         tcg_temp_free(t0);
1842     } else {
1843         tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1844         tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
1845     }
1846     if (unlikely(Rc(ctx->opcode) != 0))
1847         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1848 }
1849
1850 /* srw & srw. */
1851 static void gen_srw(DisasContext *ctx)
1852 {
1853     TCGv t0, t1;
1854
1855     t0 = tcg_temp_new();
1856     /* AND rS with a mask that is 0 when rB >= 0x20 */
1857 #if defined(TARGET_PPC64)
1858     tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3a);
1859     tcg_gen_sari_tl(t0, t0, 0x3f);
1860 #else
1861     tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1a);
1862     tcg_gen_sari_tl(t0, t0, 0x1f);
1863 #endif
1864     tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
1865     tcg_gen_ext32u_tl(t0, t0);
1866     t1 = tcg_temp_new();
1867     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1f);
1868     tcg_gen_shr_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
1869     tcg_temp_free(t1);
1870     tcg_temp_free(t0);
1871     if (unlikely(Rc(ctx->opcode) != 0))
1872         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1873 }
1874
1875 #if defined(TARGET_PPC64)
1876 /* sld & sld. */
1877 static void gen_sld(DisasContext *ctx)
1878 {
1879     TCGv t0, t1;
1880
1881     t0 = tcg_temp_new();
1882     /* AND rS with a mask that is 0 when rB >= 0x40 */
1883     tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x39);
1884     tcg_gen_sari_tl(t0, t0, 0x3f);
1885     tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
1886     t1 = tcg_temp_new();
1887     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x3f);
1888     tcg_gen_shl_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
1889     tcg_temp_free(t1);
1890     tcg_temp_free(t0);
1891     if (unlikely(Rc(ctx->opcode) != 0))
1892         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1893 }
1894
1895 /* srad & srad. */
1896 static void gen_srad(DisasContext *ctx)
1897 {
1898     gen_helper_srad(cpu_gpr[rA(ctx->opcode)],
1899                     cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1900     if (unlikely(Rc(ctx->opcode) != 0))
1901         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1902 }
1903 /* sradi & sradi. */
1904 static inline void gen_sradi(DisasContext *ctx, int n)
1905 {
1906     int sh = SH(ctx->opcode) + (n << 5);
1907     if (sh != 0) {
1908         int l1, l2;
1909         TCGv t0;
1910         l1 = gen_new_label();
1911         l2 = gen_new_label();
1912         t0 = tcg_temp_local_new();
1913         tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rS(ctx->opcode)], 0, l1);
1914         tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1ULL << sh) - 1);
1915         tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
1916         tcg_gen_ori_tl(cpu_xer, cpu_xer, 1 << XER_CA);
1917         tcg_gen_br(l2);
1918         gen_set_label(l1);
1919         tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
1920         gen_set_label(l2);
1921         tcg_temp_free(t0);
1922         tcg_gen_sari_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], sh);
1923     } else {
1924         tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1925         tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
1926     }
1927     if (unlikely(Rc(ctx->opcode) != 0))
1928         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1929 }
1930
1931 static void gen_sradi0(DisasContext *ctx)
1932 {
1933     gen_sradi(ctx, 0);
1934 }
1935
1936 static void gen_sradi1(DisasContext *ctx)
1937 {
1938     gen_sradi(ctx, 1);
1939 }
1940
1941 /* srd & srd. */
1942 static void gen_srd(DisasContext *ctx)
1943 {
1944     TCGv t0, t1;
1945
1946     t0 = tcg_temp_new();
1947     /* AND rS with a mask that is 0 when rB >= 0x40 */
1948     tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x39);
1949     tcg_gen_sari_tl(t0, t0, 0x3f);
1950     tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
1951     t1 = tcg_temp_new();
1952     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x3f);
1953     tcg_gen_shr_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
1954     tcg_temp_free(t1);
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 inline void 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 inline void 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 inline void 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 inline void 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;
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 static void spr_noaccess(void *opaque, int gprn, int sprn)
3723 {
3724 #if 0
3725     sprn = ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
3726     printf("ERROR: try to access SPR %d !\n", sprn);
3727 #endif
3728 }
3729 #define SPR_NOACCESS (&spr_noaccess)
3730
3731 /* mfspr */
3732 static inline void gen_op_mfspr(DisasContext *ctx)
3733 {
3734     void (*read_cb)(void *opaque, int gprn, int sprn);
3735     uint32_t sprn = SPR(ctx->opcode);
3736
3737 #if !defined(CONFIG_USER_ONLY)
3738     if (ctx->mem_idx == 2)
3739         read_cb = ctx->spr_cb[sprn].hea_read;
3740     else if (ctx->mem_idx)
3741         read_cb = ctx->spr_cb[sprn].oea_read;
3742     else
3743 #endif
3744         read_cb = ctx->spr_cb[sprn].uea_read;
3745     if (likely(read_cb != NULL)) {
3746         if (likely(read_cb != SPR_NOACCESS)) {
3747             (*read_cb)(ctx, rD(ctx->opcode), sprn);
3748         } else {
3749             /* Privilege exception */
3750             /* This is a hack to avoid warnings when running Linux:
3751              * this OS breaks the PowerPC virtualisation model,
3752              * allowing userland application to read the PVR
3753              */
3754             if (sprn != SPR_PVR) {
3755                 qemu_log("Trying to read privileged spr %d %03x at "
3756                          TARGET_FMT_lx "\n", sprn, sprn, ctx->nip);
3757                 printf("Trying to read privileged spr %d %03x at "
3758                        TARGET_FMT_lx "\n", sprn, sprn, ctx->nip);
3759             }
3760             gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
3761         }
3762     } else {
3763         /* Not defined */
3764         qemu_log("Trying to read invalid spr %d %03x at "
3765                     TARGET_FMT_lx "\n", sprn, sprn, ctx->nip);
3766         printf("Trying to read invalid spr %d %03x at " TARGET_FMT_lx "\n",
3767                sprn, sprn, ctx->nip);
3768         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR);
3769     }
3770 }
3771
3772 static void gen_mfspr(DisasContext *ctx)
3773 {
3774     gen_op_mfspr(ctx);
3775 }
3776
3777 /* mftb */
3778 static void gen_mftb(DisasContext *ctx)
3779 {
3780     gen_op_mfspr(ctx);
3781 }
3782
3783 /* mtcrf mtocrf*/
3784 static void gen_mtcrf(DisasContext *ctx)
3785 {
3786     uint32_t crm, crn;
3787
3788     crm = CRM(ctx->opcode);
3789     if (likely((ctx->opcode & 0x00100000))) {
3790         if (crm && ((crm & (crm - 1)) == 0)) {
3791             TCGv_i32 temp = tcg_temp_new_i32();
3792             crn = ctz32 (crm);
3793             tcg_gen_trunc_tl_i32(temp, cpu_gpr[rS(ctx->opcode)]);
3794             tcg_gen_shri_i32(temp, temp, crn * 4);
3795             tcg_gen_andi_i32(cpu_crf[7 - crn], temp, 0xf);
3796             tcg_temp_free_i32(temp);
3797         }
3798     } else {
3799         TCGv_i32 temp = tcg_temp_new_i32();
3800         tcg_gen_trunc_tl_i32(temp, cpu_gpr[rS(ctx->opcode)]);
3801         for (crn = 0 ; crn < 8 ; crn++) {
3802             if (crm & (1 << crn)) {
3803                     tcg_gen_shri_i32(cpu_crf[7 - crn], temp, crn * 4);
3804                     tcg_gen_andi_i32(cpu_crf[7 - crn], cpu_crf[7 - crn], 0xf);
3805             }
3806         }
3807         tcg_temp_free_i32(temp);
3808     }
3809 }
3810
3811 /* mtmsr */
3812 #if defined(TARGET_PPC64)
3813 static void gen_mtmsrd(DisasContext *ctx)
3814 {
3815 #if defined(CONFIG_USER_ONLY)
3816     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
3817 #else
3818     if (unlikely(!ctx->mem_idx)) {
3819         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
3820         return;
3821     }
3822     if (ctx->opcode & 0x00010000) {
3823         /* Special form that does not need any synchronisation */
3824         TCGv t0 = tcg_temp_new();
3825         tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1 << MSR_RI) | (1 << MSR_EE));
3826         tcg_gen_andi_tl(cpu_msr, cpu_msr, ~((1 << MSR_RI) | (1 << MSR_EE)));
3827         tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
3828         tcg_temp_free(t0);
3829     } else {
3830         /* XXX: we need to update nip before the store
3831          *      if we enter power saving mode, we will exit the loop
3832          *      directly from ppc_store_msr
3833          */
3834         gen_update_nip(ctx, ctx->nip);
3835         gen_helper_store_msr(cpu_gpr[rS(ctx->opcode)]);
3836         /* Must stop the translation as machine state (may have) changed */
3837         /* Note that mtmsr is not always defined as context-synchronizing */
3838         gen_stop_exception(ctx);
3839     }
3840 #endif
3841 }
3842 #endif
3843
3844 static void gen_mtmsr(DisasContext *ctx)
3845 {
3846 #if defined(CONFIG_USER_ONLY)
3847     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
3848 #else
3849     if (unlikely(!ctx->mem_idx)) {
3850         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
3851         return;
3852     }
3853     if (ctx->opcode & 0x00010000) {
3854         /* Special form that does not need any synchronisation */
3855         TCGv t0 = tcg_temp_new();
3856         tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1 << MSR_RI) | (1 << MSR_EE));
3857         tcg_gen_andi_tl(cpu_msr, cpu_msr, ~((1 << MSR_RI) | (1 << MSR_EE)));
3858         tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
3859         tcg_temp_free(t0);
3860     } else {
3861         /* XXX: we need to update nip before the store
3862          *      if we enter power saving mode, we will exit the loop
3863          *      directly from ppc_store_msr
3864          */
3865         gen_update_nip(ctx, ctx->nip);
3866 #if defined(TARGET_PPC64)
3867         if (!ctx->sf_mode) {
3868             TCGv t0 = tcg_temp_new();
3869             TCGv t1 = tcg_temp_new();
3870             tcg_gen_andi_tl(t0, cpu_msr, 0xFFFFFFFF00000000ULL);
3871             tcg_gen_ext32u_tl(t1, cpu_gpr[rS(ctx->opcode)]);
3872             tcg_gen_or_tl(t0, t0, t1);
3873             tcg_temp_free(t1);
3874             gen_helper_store_msr(t0);
3875             tcg_temp_free(t0);
3876         } else
3877 #endif
3878             gen_helper_store_msr(cpu_gpr[rS(ctx->opcode)]);
3879         /* Must stop the translation as machine state (may have) changed */
3880         /* Note that mtmsr is not always defined as context-synchronizing */
3881         gen_stop_exception(ctx);
3882     }
3883 #endif
3884 }
3885
3886 /* mtspr */
3887 static void gen_mtspr(DisasContext *ctx)
3888 {
3889     void (*write_cb)(void *opaque, int sprn, int gprn);
3890     uint32_t sprn = SPR(ctx->opcode);
3891
3892 #if !defined(CONFIG_USER_ONLY)
3893     if (ctx->mem_idx == 2)
3894         write_cb = ctx->spr_cb[sprn].hea_write;
3895     else if (ctx->mem_idx)
3896         write_cb = ctx->spr_cb[sprn].oea_write;
3897     else
3898 #endif
3899         write_cb = ctx->spr_cb[sprn].uea_write;
3900     if (likely(write_cb != NULL)) {
3901         if (likely(write_cb != SPR_NOACCESS)) {
3902             (*write_cb)(ctx, sprn, rS(ctx->opcode));
3903         } else {
3904             /* Privilege exception */
3905             qemu_log("Trying to write privileged spr %d %03x at "
3906                      TARGET_FMT_lx "\n", sprn, sprn, ctx->nip);
3907             printf("Trying to write privileged spr %d %03x at " TARGET_FMT_lx
3908                    "\n", sprn, sprn, ctx->nip);
3909             gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
3910         }
3911     } else {
3912         /* Not defined */
3913         qemu_log("Trying to write invalid spr %d %03x at "
3914                  TARGET_FMT_lx "\n", sprn, sprn, ctx->nip);
3915         printf("Trying to write invalid spr %d %03x at " TARGET_FMT_lx "\n",
3916                sprn, sprn, ctx->nip);
3917         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR);
3918     }
3919 }
3920
3921 /***                         Cache management                              ***/
3922
3923 /* dcbf */
3924 static void gen_dcbf(DisasContext *ctx)
3925 {
3926     /* XXX: specification says this is treated as a load by the MMU */
3927     TCGv t0;
3928     gen_set_access_type(ctx, ACCESS_CACHE);
3929     t0 = tcg_temp_new();
3930     gen_addr_reg_index(ctx, t0);
3931     gen_qemu_ld8u(ctx, t0, t0);
3932     tcg_temp_free(t0);
3933 }
3934
3935 /* dcbi (Supervisor only) */
3936 static void gen_dcbi(DisasContext *ctx)
3937 {
3938 #if defined(CONFIG_USER_ONLY)
3939     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
3940 #else
3941     TCGv EA, val;
3942     if (unlikely(!ctx->mem_idx)) {
3943         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
3944         return;
3945     }
3946     EA = tcg_temp_new();
3947     gen_set_access_type(ctx, ACCESS_CACHE);
3948     gen_addr_reg_index(ctx, EA);
3949     val = tcg_temp_new();
3950     /* XXX: specification says this should be treated as a store by the MMU */
3951     gen_qemu_ld8u(ctx, val, EA);
3952     gen_qemu_st8(ctx, val, EA);
3953     tcg_temp_free(val);
3954     tcg_temp_free(EA);
3955 #endif
3956 }
3957
3958 /* dcdst */
3959 static void gen_dcbst(DisasContext *ctx)
3960 {
3961     /* XXX: specification say this is treated as a load by the MMU */
3962     TCGv t0;
3963     gen_set_access_type(ctx, ACCESS_CACHE);
3964     t0 = tcg_temp_new();
3965     gen_addr_reg_index(ctx, t0);
3966     gen_qemu_ld8u(ctx, t0, t0);
3967     tcg_temp_free(t0);
3968 }
3969
3970 /* dcbt */
3971 static void gen_dcbt(DisasContext *ctx)
3972 {
3973     /* interpreted as no-op */
3974     /* XXX: specification say this is treated as a load by the MMU
3975      *      but does not generate any exception
3976      */
3977 }
3978
3979 /* dcbtst */
3980 static void gen_dcbtst(DisasContext *ctx)
3981 {
3982     /* interpreted as no-op */
3983     /* XXX: specification say this is treated as a load by the MMU
3984      *      but does not generate any exception
3985      */
3986 }
3987
3988 /* dcbz */
3989 static void gen_dcbz(DisasContext *ctx)
3990 {
3991     TCGv t0;
3992     gen_set_access_type(ctx, ACCESS_CACHE);
3993     /* NIP cannot be restored if the memory exception comes from an helper */
3994     gen_update_nip(ctx, ctx->nip - 4);
3995     t0 = tcg_temp_new();
3996     gen_addr_reg_index(ctx, t0);
3997     gen_helper_dcbz(t0);
3998     tcg_temp_free(t0);
3999 }
4000
4001 static void gen_dcbz_970(DisasContext *ctx)
4002 {
4003     TCGv t0;
4004     gen_set_access_type(ctx, ACCESS_CACHE);
4005     /* NIP cannot be restored if the memory exception comes from an helper */
4006     gen_update_nip(ctx, ctx->nip - 4);
4007     t0 = tcg_temp_new();
4008     gen_addr_reg_index(ctx, t0);
4009     if (ctx->opcode & 0x00200000)
4010         gen_helper_dcbz(t0);
4011     else
4012         gen_helper_dcbz_970(t0);
4013     tcg_temp_free(t0);
4014 }
4015
4016 /* dst / dstt */
4017 static void gen_dst(DisasContext *ctx)
4018 {
4019     if (rA(ctx->opcode) == 0) {
4020         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_LSWX);
4021     } else {
4022         /* interpreted as no-op */
4023     }
4024 }
4025
4026 /* dstst /dststt */
4027 static void gen_dstst(DisasContext *ctx)
4028 {
4029     if (rA(ctx->opcode) == 0) {
4030         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_LSWX);
4031     } else {
4032         /* interpreted as no-op */
4033     }
4034
4035 }
4036
4037 /* dss / dssall */
4038 static void gen_dss(DisasContext *ctx)
4039 {
4040     /* interpreted as no-op */
4041 }
4042
4043 /* icbi */
4044 static void gen_icbi(DisasContext *ctx)
4045 {
4046     TCGv t0;
4047     gen_set_access_type(ctx, ACCESS_CACHE);
4048     /* NIP cannot be restored if the memory exception comes from an helper */
4049     gen_update_nip(ctx, ctx->nip - 4);
4050     t0 = tcg_temp_new();
4051     gen_addr_reg_index(ctx, t0);
4052     gen_helper_icbi(t0);
4053     tcg_temp_free(t0);
4054 }
4055
4056 /* Optional: */
4057 /* dcba */
4058 static void gen_dcba(DisasContext *ctx)
4059 {
4060     /* interpreted as no-op */
4061     /* XXX: specification say this is treated as a store by the MMU
4062      *      but does not generate any exception
4063      */
4064 }
4065
4066 /***                    Segment register manipulation                      ***/
4067 /* Supervisor only: */
4068
4069 /* mfsr */
4070 static void gen_mfsr(DisasContext *ctx)
4071 {
4072 #if defined(CONFIG_USER_ONLY)
4073     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4074 #else
4075     TCGv t0;
4076     if (unlikely(!ctx->mem_idx)) {
4077         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4078         return;
4079     }
4080     t0 = tcg_const_tl(SR(ctx->opcode));
4081     gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], t0);
4082     tcg_temp_free(t0);
4083 #endif
4084 }
4085
4086 /* mfsrin */
4087 static void gen_mfsrin(DisasContext *ctx)
4088 {
4089 #if defined(CONFIG_USER_ONLY)
4090     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4091 #else
4092     TCGv t0;
4093     if (unlikely(!ctx->mem_idx)) {
4094         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4095         return;
4096     }
4097     t0 = tcg_temp_new();
4098     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
4099     tcg_gen_andi_tl(t0, t0, 0xF);
4100     gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], t0);
4101     tcg_temp_free(t0);
4102 #endif
4103 }
4104
4105 /* mtsr */
4106 static void gen_mtsr(DisasContext *ctx)
4107 {
4108 #if defined(CONFIG_USER_ONLY)
4109     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4110 #else
4111     TCGv t0;
4112     if (unlikely(!ctx->mem_idx)) {
4113         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4114         return;
4115     }
4116     t0 = tcg_const_tl(SR(ctx->opcode));
4117     gen_helper_store_sr(t0, cpu_gpr[rS(ctx->opcode)]);
4118     tcg_temp_free(t0);
4119 #endif
4120 }
4121
4122 /* mtsrin */
4123 static void gen_mtsrin(DisasContext *ctx)
4124 {
4125 #if defined(CONFIG_USER_ONLY)
4126     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4127 #else
4128     TCGv t0;
4129     if (unlikely(!ctx->mem_idx)) {
4130         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4131         return;
4132     }
4133     t0 = tcg_temp_new();
4134     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
4135     tcg_gen_andi_tl(t0, t0, 0xF);
4136     gen_helper_store_sr(t0, cpu_gpr[rD(ctx->opcode)]);
4137     tcg_temp_free(t0);
4138 #endif
4139 }
4140
4141 #if defined(TARGET_PPC64)
4142 /* Specific implementation for PowerPC 64 "bridge" emulation using SLB */
4143
4144 /* mfsr */
4145 static void gen_mfsr_64b(DisasContext *ctx)
4146 {
4147 #if defined(CONFIG_USER_ONLY)
4148     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4149 #else
4150     TCGv t0;
4151     if (unlikely(!ctx->mem_idx)) {
4152         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4153         return;
4154     }
4155     t0 = tcg_const_tl(SR(ctx->opcode));
4156     gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], t0);
4157     tcg_temp_free(t0);
4158 #endif
4159 }
4160
4161 /* mfsrin */
4162 static void gen_mfsrin_64b(DisasContext *ctx)
4163 {
4164 #if defined(CONFIG_USER_ONLY)
4165     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4166 #else
4167     TCGv t0;
4168     if (unlikely(!ctx->mem_idx)) {
4169         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4170         return;
4171     }
4172     t0 = tcg_temp_new();
4173     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
4174     tcg_gen_andi_tl(t0, t0, 0xF);
4175     gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], t0);
4176     tcg_temp_free(t0);
4177 #endif
4178 }
4179
4180 /* mtsr */
4181 static void gen_mtsr_64b(DisasContext *ctx)
4182 {
4183 #if defined(CONFIG_USER_ONLY)
4184     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4185 #else
4186     TCGv t0;
4187     if (unlikely(!ctx->mem_idx)) {
4188         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4189         return;
4190     }
4191     t0 = tcg_const_tl(SR(ctx->opcode));
4192     gen_helper_store_sr(t0, cpu_gpr[rS(ctx->opcode)]);
4193     tcg_temp_free(t0);
4194 #endif
4195 }
4196
4197 /* mtsrin */
4198 static void gen_mtsrin_64b(DisasContext *ctx)
4199 {
4200 #if defined(CONFIG_USER_ONLY)
4201     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4202 #else
4203     TCGv t0;
4204     if (unlikely(!ctx->mem_idx)) {
4205         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4206         return;
4207     }
4208     t0 = tcg_temp_new();
4209     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
4210     tcg_gen_andi_tl(t0, t0, 0xF);
4211     gen_helper_store_sr(t0, cpu_gpr[rS(ctx->opcode)]);
4212     tcg_temp_free(t0);
4213 #endif
4214 }
4215
4216 /* slbmte */
4217 static void gen_slbmte(DisasContext *ctx)
4218 {
4219 #if defined(CONFIG_USER_ONLY)
4220     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4221 #else
4222     if (unlikely(!ctx->mem_idx)) {
4223         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4224         return;
4225     }
4226     gen_helper_store_slb(cpu_gpr[rB(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
4227 #endif
4228 }
4229
4230 #endif /* defined(TARGET_PPC64) */
4231
4232 /***                      Lookaside buffer management                      ***/
4233 /* Optional & mem_idx only: */
4234
4235 /* tlbia */
4236 static void gen_tlbia(DisasContext *ctx)
4237 {
4238 #if defined(CONFIG_USER_ONLY)
4239     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4240 #else
4241     if (unlikely(!ctx->mem_idx)) {
4242         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4243         return;
4244     }
4245     gen_helper_tlbia();
4246 #endif
4247 }
4248
4249 /* tlbiel */
4250 static void gen_tlbiel(DisasContext *ctx)
4251 {
4252 #if defined(CONFIG_USER_ONLY)
4253     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4254 #else
4255     if (unlikely(!ctx->mem_idx)) {
4256         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4257         return;
4258     }
4259     gen_helper_tlbie(cpu_gpr[rB(ctx->opcode)]);
4260 #endif
4261 }
4262
4263 /* tlbie */
4264 static void gen_tlbie(DisasContext *ctx)
4265 {
4266 #if defined(CONFIG_USER_ONLY)
4267     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4268 #else
4269     if (unlikely(!ctx->mem_idx)) {
4270         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4271         return;
4272     }
4273 #if defined(TARGET_PPC64)
4274     if (!ctx->sf_mode) {
4275         TCGv t0 = tcg_temp_new();
4276         tcg_gen_ext32u_tl(t0, cpu_gpr[rB(ctx->opcode)]);
4277         gen_helper_tlbie(t0);
4278         tcg_temp_free(t0);
4279     } else
4280 #endif
4281         gen_helper_tlbie(cpu_gpr[rB(ctx->opcode)]);
4282 #endif
4283 }
4284
4285 /* tlbsync */
4286 static void gen_tlbsync(DisasContext *ctx)
4287 {
4288 #if defined(CONFIG_USER_ONLY)
4289     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4290 #else
4291     if (unlikely(!ctx->mem_idx)) {
4292         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4293         return;
4294     }
4295     /* This has no effect: it should ensure that all previous
4296      * tlbie have completed
4297      */
4298     gen_stop_exception(ctx);
4299 #endif
4300 }
4301
4302 #if defined(TARGET_PPC64)
4303 /* slbia */
4304 static void gen_slbia(DisasContext *ctx)
4305 {
4306 #if defined(CONFIG_USER_ONLY)
4307     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4308 #else
4309     if (unlikely(!ctx->mem_idx)) {
4310         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4311         return;
4312     }
4313     gen_helper_slbia();
4314 #endif
4315 }
4316
4317 /* slbie */
4318 static void gen_slbie(DisasContext *ctx)
4319 {
4320 #if defined(CONFIG_USER_ONLY)
4321     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4322 #else
4323     if (unlikely(!ctx->mem_idx)) {
4324         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4325         return;
4326     }
4327     gen_helper_slbie(cpu_gpr[rB(ctx->opcode)]);
4328 #endif
4329 }
4330 #endif
4331
4332 /***                              External control                         ***/
4333 /* Optional: */
4334
4335 /* eciwx */
4336 static void gen_eciwx(DisasContext *ctx)
4337 {
4338     TCGv t0;
4339     /* Should check EAR[E] ! */
4340     gen_set_access_type(ctx, ACCESS_EXT);
4341     t0 = tcg_temp_new();
4342     gen_addr_reg_index(ctx, t0);
4343     gen_check_align(ctx, t0, 0x03);
4344     gen_qemu_ld32u(ctx, cpu_gpr[rD(ctx->opcode)], t0);
4345     tcg_temp_free(t0);
4346 }
4347
4348 /* ecowx */
4349 static void gen_ecowx(DisasContext *ctx)
4350 {
4351     TCGv t0;
4352     /* Should check EAR[E] ! */
4353     gen_set_access_type(ctx, ACCESS_EXT);
4354     t0 = tcg_temp_new();
4355     gen_addr_reg_index(ctx, t0);
4356     gen_check_align(ctx, t0, 0x03);
4357     gen_qemu_st32(ctx, cpu_gpr[rD(ctx->opcode)], t0);
4358     tcg_temp_free(t0);
4359 }
4360
4361 /* PowerPC 601 specific instructions */
4362
4363 /* abs - abs. */
4364 static void gen_abs(DisasContext *ctx)
4365 {
4366     int l1 = gen_new_label();
4367     int l2 = gen_new_label();
4368     tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rA(ctx->opcode)], 0, l1);
4369     tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4370     tcg_gen_br(l2);
4371     gen_set_label(l1);
4372     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4373     gen_set_label(l2);
4374     if (unlikely(Rc(ctx->opcode) != 0))
4375         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4376 }
4377
4378 /* abso - abso. */
4379 static void gen_abso(DisasContext *ctx)
4380 {
4381     int l1 = gen_new_label();
4382     int l2 = gen_new_label();
4383     int l3 = gen_new_label();
4384     /* Start with XER OV disabled, the most likely case */
4385     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
4386     tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rA(ctx->opcode)], 0, l2);
4387     tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rA(ctx->opcode)], 0x80000000, l1);
4388     tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
4389     tcg_gen_br(l2);
4390     gen_set_label(l1);
4391     tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4392     tcg_gen_br(l3);
4393     gen_set_label(l2);
4394     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4395     gen_set_label(l3);
4396     if (unlikely(Rc(ctx->opcode) != 0))
4397         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4398 }
4399
4400 /* clcs */
4401 static void gen_clcs(DisasContext *ctx)
4402 {
4403     TCGv_i32 t0 = tcg_const_i32(rA(ctx->opcode));
4404     gen_helper_clcs(cpu_gpr[rD(ctx->opcode)], t0);
4405     tcg_temp_free_i32(t0);
4406     /* Rc=1 sets CR0 to an undefined state */
4407 }
4408
4409 /* div - div. */
4410 static void gen_div(DisasContext *ctx)
4411 {
4412     gen_helper_div(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
4413     if (unlikely(Rc(ctx->opcode) != 0))
4414         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4415 }
4416
4417 /* divo - divo. */
4418 static void gen_divo(DisasContext *ctx)
4419 {
4420     gen_helper_divo(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
4421     if (unlikely(Rc(ctx->opcode) != 0))
4422         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4423 }
4424
4425 /* divs - divs. */
4426 static void gen_divs(DisasContext *ctx)
4427 {
4428     gen_helper_divs(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
4429     if (unlikely(Rc(ctx->opcode) != 0))
4430         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4431 }
4432
4433 /* divso - divso. */
4434 static void gen_divso(DisasContext *ctx)
4435 {
4436     gen_helper_divso(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
4437     if (unlikely(Rc(ctx->opcode) != 0))
4438         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4439 }
4440
4441 /* doz - doz. */
4442 static void gen_doz(DisasContext *ctx)
4443 {
4444     int l1 = gen_new_label();
4445     int l2 = gen_new_label();
4446     tcg_gen_brcond_tl(TCG_COND_GE, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], l1);
4447     tcg_gen_sub_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4448     tcg_gen_br(l2);
4449     gen_set_label(l1);
4450     tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
4451     gen_set_label(l2);
4452     if (unlikely(Rc(ctx->opcode) != 0))
4453         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4454 }
4455
4456 /* dozo - dozo. */
4457 static void gen_dozo(DisasContext *ctx)
4458 {
4459     int l1 = gen_new_label();
4460     int l2 = gen_new_label();
4461     TCGv t0 = tcg_temp_new();
4462     TCGv t1 = tcg_temp_new();
4463     TCGv t2 = tcg_temp_new();
4464     /* Start with XER OV disabled, the most likely case */
4465     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
4466     tcg_gen_brcond_tl(TCG_COND_GE, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], l1);
4467     tcg_gen_sub_tl(t0, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4468     tcg_gen_xor_tl(t1, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4469     tcg_gen_xor_tl(t2, cpu_gpr[rA(ctx->opcode)], t0);
4470     tcg_gen_andc_tl(t1, t1, t2);
4471     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
4472     tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l2);
4473     tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
4474     tcg_gen_br(l2);
4475     gen_set_label(l1);
4476     tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
4477     gen_set_label(l2);
4478     tcg_temp_free(t0);
4479     tcg_temp_free(t1);
4480     tcg_temp_free(t2);
4481     if (unlikely(Rc(ctx->opcode) != 0))
4482         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4483 }
4484
4485 /* dozi */
4486 static void gen_dozi(DisasContext *ctx)
4487 {
4488     target_long simm = SIMM(ctx->opcode);
4489     int l1 = gen_new_label();
4490     int l2 = gen_new_label();
4491     tcg_gen_brcondi_tl(TCG_COND_LT, cpu_gpr[rA(ctx->opcode)], simm, l1);
4492     tcg_gen_subfi_tl(cpu_gpr[rD(ctx->opcode)], simm, cpu_gpr[rA(ctx->opcode)]);
4493     tcg_gen_br(l2);
4494     gen_set_label(l1);
4495     tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
4496     gen_set_label(l2);
4497     if (unlikely(Rc(ctx->opcode) != 0))
4498         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4499 }
4500
4501 /* lscbx - lscbx. */
4502 static void gen_lscbx(DisasContext *ctx)
4503 {
4504     TCGv t0 = tcg_temp_new();
4505     TCGv_i32 t1 = tcg_const_i32(rD(ctx->opcode));
4506     TCGv_i32 t2 = tcg_const_i32(rA(ctx->opcode));
4507     TCGv_i32 t3 = tcg_const_i32(rB(ctx->opcode));
4508
4509     gen_addr_reg_index(ctx, t0);
4510     /* NIP cannot be restored if the memory exception comes from an helper */
4511     gen_update_nip(ctx, ctx->nip - 4);
4512     gen_helper_lscbx(t0, t0, t1, t2, t3);
4513     tcg_temp_free_i32(t1);
4514     tcg_temp_free_i32(t2);
4515     tcg_temp_free_i32(t3);
4516     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~0x7F);
4517     tcg_gen_or_tl(cpu_xer, cpu_xer, t0);
4518     if (unlikely(Rc(ctx->opcode) != 0))
4519         gen_set_Rc0(ctx, t0);
4520     tcg_temp_free(t0);
4521 }
4522
4523 /* maskg - maskg. */
4524 static void gen_maskg(DisasContext *ctx)
4525 {
4526     int l1 = gen_new_label();
4527     TCGv t0 = tcg_temp_new();
4528     TCGv t1 = tcg_temp_new();
4529     TCGv t2 = tcg_temp_new();
4530     TCGv t3 = tcg_temp_new();
4531     tcg_gen_movi_tl(t3, 0xFFFFFFFF);
4532     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
4533     tcg_gen_andi_tl(t1, cpu_gpr[rS(ctx->opcode)], 0x1F);
4534     tcg_gen_addi_tl(t2, t0, 1);
4535     tcg_gen_shr_tl(t2, t3, t2);
4536     tcg_gen_shr_tl(t3, t3, t1);
4537     tcg_gen_xor_tl(cpu_gpr[rA(ctx->opcode)], t2, t3);
4538     tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
4539     tcg_gen_neg_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4540     gen_set_label(l1);
4541     tcg_temp_free(t0);
4542     tcg_temp_free(t1);
4543     tcg_temp_free(t2);
4544     tcg_temp_free(t3);
4545     if (unlikely(Rc(ctx->opcode) != 0))
4546         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4547 }
4548
4549 /* maskir - maskir. */
4550 static void gen_maskir(DisasContext *ctx)
4551 {
4552     TCGv t0 = tcg_temp_new();
4553     TCGv t1 = tcg_temp_new();
4554     tcg_gen_and_tl(t0, cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
4555     tcg_gen_andc_tl(t1, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
4556     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
4557     tcg_temp_free(t0);
4558     tcg_temp_free(t1);
4559     if (unlikely(Rc(ctx->opcode) != 0))
4560         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4561 }
4562
4563 /* mul - mul. */
4564 static void gen_mul(DisasContext *ctx)
4565 {
4566     TCGv_i64 t0 = tcg_temp_new_i64();
4567     TCGv_i64 t1 = tcg_temp_new_i64();
4568     TCGv t2 = tcg_temp_new();
4569     tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
4570     tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
4571     tcg_gen_mul_i64(t0, t0, t1);
4572     tcg_gen_trunc_i64_tl(t2, t0);
4573     gen_store_spr(SPR_MQ, t2);
4574     tcg_gen_shri_i64(t1, t0, 32);
4575     tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t1);
4576     tcg_temp_free_i64(t0);
4577     tcg_temp_free_i64(t1);
4578     tcg_temp_free(t2);
4579     if (unlikely(Rc(ctx->opcode) != 0))
4580         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4581 }
4582
4583 /* mulo - mulo. */
4584 static void gen_mulo(DisasContext *ctx)
4585 {
4586     int l1 = gen_new_label();
4587     TCGv_i64 t0 = tcg_temp_new_i64();
4588     TCGv_i64 t1 = tcg_temp_new_i64();
4589     TCGv t2 = tcg_temp_new();
4590     /* Start with XER OV disabled, the most likely case */
4591     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
4592     tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
4593     tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
4594     tcg_gen_mul_i64(t0, t0, t1);
4595     tcg_gen_trunc_i64_tl(t2, t0);
4596     gen_store_spr(SPR_MQ, t2);
4597     tcg_gen_shri_i64(t1, t0, 32);
4598     tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t1);
4599     tcg_gen_ext32s_i64(t1, t0);
4600     tcg_gen_brcond_i64(TCG_COND_EQ, t0, t1, l1);
4601     tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
4602     gen_set_label(l1);
4603     tcg_temp_free_i64(t0);
4604     tcg_temp_free_i64(t1);
4605     tcg_temp_free(t2);
4606     if (unlikely(Rc(ctx->opcode) != 0))
4607         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4608 }
4609
4610 /* nabs - nabs. */
4611 static void gen_nabs(DisasContext *ctx)
4612 {
4613     int l1 = gen_new_label();
4614     int l2 = gen_new_label();
4615     tcg_gen_brcondi_tl(TCG_COND_GT, cpu_gpr[rA(ctx->opcode)], 0, l1);
4616     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4617     tcg_gen_br(l2);
4618     gen_set_label(l1);
4619     tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4620     gen_set_label(l2);
4621     if (unlikely(Rc(ctx->opcode) != 0))
4622         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4623 }
4624
4625 /* nabso - nabso. */
4626 static void gen_nabso(DisasContext *ctx)
4627 {
4628     int l1 = gen_new_label();
4629     int l2 = gen_new_label();
4630     tcg_gen_brcondi_tl(TCG_COND_GT, cpu_gpr[rA(ctx->opcode)], 0, l1);
4631     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4632     tcg_gen_br(l2);
4633     gen_set_label(l1);
4634     tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4635     gen_set_label(l2);
4636     /* nabs never overflows */
4637     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
4638     if (unlikely(Rc(ctx->opcode) != 0))
4639         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4640 }
4641
4642 /* rlmi - rlmi. */
4643 static void gen_rlmi(DisasContext *ctx)
4644 {
4645     uint32_t mb = MB(ctx->opcode);
4646     uint32_t me = ME(ctx->opcode);
4647     TCGv t0 = tcg_temp_new();
4648     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
4649     tcg_gen_rotl_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
4650     tcg_gen_andi_tl(t0, t0, MASK(mb, me));
4651     tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~MASK(mb, me));
4652     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], t0);
4653     tcg_temp_free(t0);
4654     if (unlikely(Rc(ctx->opcode) != 0))
4655         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4656 }
4657
4658 /* rrib - rrib. */
4659 static void gen_rrib(DisasContext *ctx)
4660 {
4661     TCGv t0 = tcg_temp_new();
4662     TCGv t1 = tcg_temp_new();
4663     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
4664     tcg_gen_movi_tl(t1, 0x80000000);
4665     tcg_gen_shr_tl(t1, t1, t0);
4666     tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
4667     tcg_gen_and_tl(t0, t0, t1);
4668     tcg_gen_andc_tl(t1, cpu_gpr[rA(ctx->opcode)], t1);
4669     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
4670     tcg_temp_free(t0);
4671     tcg_temp_free(t1);
4672     if (unlikely(Rc(ctx->opcode) != 0))
4673         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4674 }
4675
4676 /* sle - sle. */
4677 static void gen_sle(DisasContext *ctx)
4678 {
4679     TCGv t0 = tcg_temp_new();
4680     TCGv t1 = tcg_temp_new();
4681     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
4682     tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
4683     tcg_gen_subfi_tl(t1, 32, t1);
4684     tcg_gen_shr_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
4685     tcg_gen_or_tl(t1, t0, t1);
4686     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
4687     gen_store_spr(SPR_MQ, t1);
4688     tcg_temp_free(t0);
4689     tcg_temp_free(t1);
4690     if (unlikely(Rc(ctx->opcode) != 0))
4691         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4692 }
4693
4694 /* sleq - sleq. */
4695 static void gen_sleq(DisasContext *ctx)
4696 {
4697     TCGv t0 = tcg_temp_new();
4698     TCGv t1 = tcg_temp_new();
4699     TCGv t2 = tcg_temp_new();
4700     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
4701     tcg_gen_movi_tl(t2, 0xFFFFFFFF);
4702     tcg_gen_shl_tl(t2, t2, t0);
4703     tcg_gen_rotl_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
4704     gen_load_spr(t1, SPR_MQ);
4705     gen_store_spr(SPR_MQ, t0);
4706     tcg_gen_and_tl(t0, t0, t2);
4707     tcg_gen_andc_tl(t1, t1, t2);
4708     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
4709     tcg_temp_free(t0);
4710     tcg_temp_free(t1);
4711     tcg_temp_free(t2);
4712     if (unlikely(Rc(ctx->opcode) != 0))
4713         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4714 }
4715
4716 /* sliq - sliq. */
4717 static void gen_sliq(DisasContext *ctx)
4718 {
4719     int sh = SH(ctx->opcode);
4720     TCGv t0 = tcg_temp_new();
4721     TCGv t1 = tcg_temp_new();
4722     tcg_gen_shli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
4723     tcg_gen_shri_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh);
4724     tcg_gen_or_tl(t1, t0, t1);
4725     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
4726     gen_store_spr(SPR_MQ, t1);
4727     tcg_temp_free(t0);
4728     tcg_temp_free(t1);
4729     if (unlikely(Rc(ctx->opcode) != 0))
4730         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4731 }
4732
4733 /* slliq - slliq. */
4734 static void gen_slliq(DisasContext *ctx)
4735 {
4736     int sh = SH(ctx->opcode);
4737     TCGv t0 = tcg_temp_new();
4738     TCGv t1 = tcg_temp_new();
4739     tcg_gen_rotli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
4740     gen_load_spr(t1, SPR_MQ);
4741     gen_store_spr(SPR_MQ, t0);
4742     tcg_gen_andi_tl(t0, t0,  (0xFFFFFFFFU << sh));
4743     tcg_gen_andi_tl(t1, t1, ~(0xFFFFFFFFU << sh));
4744     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
4745     tcg_temp_free(t0);
4746     tcg_temp_free(t1);
4747     if (unlikely(Rc(ctx->opcode) != 0))
4748         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4749 }
4750
4751 /* sllq - sllq. */
4752 static void gen_sllq(DisasContext *ctx)
4753 {
4754     int l1 = gen_new_label();
4755     int l2 = gen_new_label();
4756     TCGv t0 = tcg_temp_local_new();
4757     TCGv t1 = tcg_temp_local_new();
4758     TCGv t2 = tcg_temp_local_new();
4759     tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F);
4760     tcg_gen_movi_tl(t1, 0xFFFFFFFF);
4761     tcg_gen_shl_tl(t1, t1, t2);
4762     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20);
4763     tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
4764     gen_load_spr(t0, SPR_MQ);
4765     tcg_gen_and_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
4766     tcg_gen_br(l2);
4767     gen_set_label(l1);
4768     tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t2);
4769     gen_load_spr(t2, SPR_MQ);
4770     tcg_gen_andc_tl(t1, t2, t1);
4771     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
4772     gen_set_label(l2);
4773     tcg_temp_free(t0);
4774     tcg_temp_free(t1);
4775     tcg_temp_free(t2);
4776     if (unlikely(Rc(ctx->opcode) != 0))
4777         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4778 }
4779
4780 /* slq - slq. */
4781 static void gen_slq(DisasContext *ctx)
4782 {
4783     int l1 = gen_new_label();
4784     TCGv t0 = tcg_temp_new();
4785     TCGv t1 = tcg_temp_new();
4786     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
4787     tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
4788     tcg_gen_subfi_tl(t1, 32, t1);
4789     tcg_gen_shr_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
4790     tcg_gen_or_tl(t1, t0, t1);
4791     gen_store_spr(SPR_MQ, t1);
4792     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x20);
4793     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
4794     tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
4795     tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
4796     gen_set_label(l1);
4797     tcg_temp_free(t0);
4798     tcg_temp_free(t1);
4799     if (unlikely(Rc(ctx->opcode) != 0))
4800         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4801 }
4802
4803 /* sraiq - sraiq. */
4804 static void gen_sraiq(DisasContext *ctx)
4805 {
4806     int sh = SH(ctx->opcode);
4807     int l1 = gen_new_label();
4808     TCGv t0 = tcg_temp_new();
4809     TCGv t1 = tcg_temp_new();
4810     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
4811     tcg_gen_shli_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh);
4812     tcg_gen_or_tl(t0, t0, t1);
4813     gen_store_spr(SPR_MQ, t0);
4814     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
4815     tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
4816     tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rS(ctx->opcode)], 0, l1);
4817     tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_CA));
4818     gen_set_label(l1);
4819     tcg_gen_sari_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], sh);
4820     tcg_temp_free(t0);
4821     tcg_temp_free(t1);
4822     if (unlikely(Rc(ctx->opcode) != 0))
4823         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4824 }
4825
4826 /* sraq - sraq. */
4827 static void gen_sraq(DisasContext *ctx)
4828 {
4829     int l1 = gen_new_label();
4830     int l2 = gen_new_label();
4831     TCGv t0 = tcg_temp_new();
4832     TCGv t1 = tcg_temp_local_new();
4833     TCGv t2 = tcg_temp_local_new();
4834     tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F);
4835     tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t2);
4836     tcg_gen_sar_tl(t1, cpu_gpr[rS(ctx->opcode)], t2);
4837     tcg_gen_subfi_tl(t2, 32, t2);
4838     tcg_gen_shl_tl(t2, cpu_gpr[rS(ctx->opcode)], t2);
4839     tcg_gen_or_tl(t0, t0, t2);
4840     gen_store_spr(SPR_MQ, t0);
4841     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20);
4842     tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, l1);
4843     tcg_gen_mov_tl(t2, cpu_gpr[rS(ctx->opcode)]);
4844     tcg_gen_sari_tl(t1, cpu_gpr[rS(ctx->opcode)], 31);
4845     gen_set_label(l1);
4846     tcg_temp_free(t0);
4847     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t1);
4848     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
4849     tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l2);
4850     tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, l2);
4851     tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_CA));
4852     gen_set_label(l2);
4853     tcg_temp_free(t1);
4854     tcg_temp_free(t2);
4855     if (unlikely(Rc(ctx->opcode) != 0))
4856         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4857 }
4858
4859 /* sre - sre. */
4860 static void gen_sre(DisasContext *ctx)
4861 {
4862     TCGv t0 = tcg_temp_new();
4863     TCGv t1 = tcg_temp_new();
4864     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
4865     tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
4866     tcg_gen_subfi_tl(t1, 32, t1);
4867     tcg_gen_shl_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
4868     tcg_gen_or_tl(t1, t0, t1);
4869     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
4870     gen_store_spr(SPR_MQ, t1);
4871     tcg_temp_free(t0);
4872     tcg_temp_free(t1);
4873     if (unlikely(Rc(ctx->opcode) != 0))
4874         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4875 }
4876
4877 /* srea - srea. */
4878 static void gen_srea(DisasContext *ctx)
4879 {
4880     TCGv t0 = tcg_temp_new();
4881     TCGv t1 = tcg_temp_new();
4882     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
4883     tcg_gen_rotr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
4884     gen_store_spr(SPR_MQ, t0);
4885     tcg_gen_sar_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], t1);
4886     tcg_temp_free(t0);
4887     tcg_temp_free(t1);
4888     if (unlikely(Rc(ctx->opcode) != 0))
4889         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4890 }
4891
4892 /* sreq */
4893 static void gen_sreq(DisasContext *ctx)
4894 {
4895     TCGv t0 = tcg_temp_new();
4896     TCGv t1 = tcg_temp_new();
4897     TCGv t2 = tcg_temp_new();
4898     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
4899     tcg_gen_movi_tl(t1, 0xFFFFFFFF);
4900     tcg_gen_shr_tl(t1, t1, t0);
4901     tcg_gen_rotr_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
4902     gen_load_spr(t2, SPR_MQ);
4903     gen_store_spr(SPR_MQ, t0);
4904     tcg_gen_and_tl(t0, t0, t1);
4905     tcg_gen_andc_tl(t2, t2, t1);
4906     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t2);
4907     tcg_temp_free(t0);
4908     tcg_temp_free(t1);
4909     tcg_temp_free(t2);
4910     if (unlikely(Rc(ctx->opcode) != 0))
4911         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4912 }
4913
4914 /* sriq */
4915 static void gen_sriq(DisasContext *ctx)
4916 {
4917     int sh = SH(ctx->opcode);
4918     TCGv t0 = tcg_temp_new();
4919     TCGv t1 = tcg_temp_new();
4920     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
4921     tcg_gen_shli_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh);
4922     tcg_gen_or_tl(t1, t0, t1);
4923     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
4924     gen_store_spr(SPR_MQ, t1);
4925     tcg_temp_free(t0);
4926     tcg_temp_free(t1);
4927     if (unlikely(Rc(ctx->opcode) != 0))
4928         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4929 }
4930
4931 /* srliq */
4932 static void gen_srliq(DisasContext *ctx)
4933 {
4934     int sh = SH(ctx->opcode);
4935     TCGv t0 = tcg_temp_new();
4936     TCGv t1 = tcg_temp_new();
4937     tcg_gen_rotri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
4938     gen_load_spr(t1, SPR_MQ);
4939     gen_store_spr(SPR_MQ, t0);
4940     tcg_gen_andi_tl(t0, t0,  (0xFFFFFFFFU >> sh));
4941     tcg_gen_andi_tl(t1, t1, ~(0xFFFFFFFFU >> sh));
4942     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
4943     tcg_temp_free(t0);
4944     tcg_temp_free(t1);
4945     if (unlikely(Rc(ctx->opcode) != 0))
4946         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4947 }
4948
4949 /* srlq */
4950 static void gen_srlq(DisasContext *ctx)
4951 {
4952     int l1 = gen_new_label();
4953     int l2 = gen_new_label();
4954     TCGv t0 = tcg_temp_local_new();
4955     TCGv t1 = tcg_temp_local_new();
4956     TCGv t2 = tcg_temp_local_new();
4957     tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F);
4958     tcg_gen_movi_tl(t1, 0xFFFFFFFF);
4959     tcg_gen_shr_tl(t2, t1, t2);
4960     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20);
4961     tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
4962     gen_load_spr(t0, SPR_MQ);
4963     tcg_gen_and_tl(cpu_gpr[rA(ctx->opcode)], t0, t2);
4964     tcg_gen_br(l2);
4965     gen_set_label(l1);
4966     tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t2);
4967     tcg_gen_and_tl(t0, t0, t2);
4968     gen_load_spr(t1, SPR_MQ);
4969     tcg_gen_andc_tl(t1, t1, t2);
4970     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
4971     gen_set_label(l2);
4972     tcg_temp_free(t0);
4973     tcg_temp_free(t1);
4974     tcg_temp_free(t2);
4975     if (unlikely(Rc(ctx->opcode) != 0))
4976         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4977 }
4978
4979 /* srq */
4980 static void gen_srq(DisasContext *ctx)
4981 {
4982     int l1 = gen_new_label();
4983     TCGv t0 = tcg_temp_new();
4984     TCGv t1 = tcg_temp_new();
4985     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
4986     tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
4987     tcg_gen_subfi_tl(t1, 32, t1);
4988     tcg_gen_shl_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
4989     tcg_gen_or_tl(t1, t0, t1);
4990     gen_store_spr(SPR_MQ, t1);
4991     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x20);
4992     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
4993     tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
4994     tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
4995     gen_set_label(l1);
4996     tcg_temp_free(t0);
4997     tcg_temp_free(t1);
4998     if (unlikely(Rc(ctx->opcode) != 0))
4999         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5000 }
5001
5002 /* PowerPC 602 specific instructions */
5003
5004 /* dsa  */
5005 static void gen_dsa(DisasContext *ctx)
5006 {
5007     /* XXX: TODO */
5008     gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5009 }
5010
5011 /* esa */
5012 static void gen_esa(DisasContext *ctx)
5013 {
5014     /* XXX: TODO */
5015     gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5016 }
5017
5018 /* mfrom */
5019 static void gen_mfrom(DisasContext *ctx)
5020 {
5021 #if defined(CONFIG_USER_ONLY)
5022     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5023 #else
5024     if (unlikely(!ctx->mem_idx)) {
5025         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5026         return;
5027     }
5028     gen_helper_602_mfrom(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5029 #endif
5030 }
5031
5032 /* 602 - 603 - G2 TLB management */
5033
5034 /* tlbld */
5035 static void gen_tlbld_6xx(DisasContext *ctx)
5036 {
5037 #if defined(CONFIG_USER_ONLY)
5038     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5039 #else
5040     if (unlikely(!ctx->mem_idx)) {
5041         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5042         return;
5043     }
5044     gen_helper_6xx_tlbd(cpu_gpr[rB(ctx->opcode)]);
5045 #endif
5046 }
5047
5048 /* tlbli */
5049 static void gen_tlbli_6xx(DisasContext *ctx)
5050 {
5051 #if defined(CONFIG_USER_ONLY)
5052     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5053 #else
5054     if (unlikely(!ctx->mem_idx)) {
5055         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5056         return;
5057     }
5058     gen_helper_6xx_tlbi(cpu_gpr[rB(ctx->opcode)]);
5059 #endif
5060 }
5061
5062 /* 74xx TLB management */
5063
5064 /* tlbld */
5065 static void gen_tlbld_74xx(DisasContext *ctx)
5066 {
5067 #if defined(CONFIG_USER_ONLY)
5068     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5069 #else
5070     if (unlikely(!ctx->mem_idx)) {
5071         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5072         return;
5073     }
5074     gen_helper_74xx_tlbd(cpu_gpr[rB(ctx->opcode)]);
5075 #endif
5076 }
5077
5078 /* tlbli */
5079 static void gen_tlbli_74xx(DisasContext *ctx)
5080 {
5081 #if defined(CONFIG_USER_ONLY)
5082     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5083 #else
5084     if (unlikely(!ctx->mem_idx)) {
5085         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5086         return;
5087     }
5088     gen_helper_74xx_tlbi(cpu_gpr[rB(ctx->opcode)]);
5089 #endif
5090 }
5091
5092 /* POWER instructions not in PowerPC 601 */
5093
5094 /* clf */
5095 static void gen_clf(DisasContext *ctx)
5096 {
5097     /* Cache line flush: implemented as no-op */
5098 }
5099
5100 /* cli */
5101 static void gen_cli(DisasContext *ctx)
5102 {
5103     /* Cache line invalidate: privileged and treated as no-op */
5104 #if defined(CONFIG_USER_ONLY)
5105     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5106 #else
5107     if (unlikely(!ctx->mem_idx)) {
5108         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5109         return;
5110     }
5111 #endif
5112 }
5113
5114 /* dclst */
5115 static void gen_dclst(DisasContext *ctx)
5116 {
5117     /* Data cache line store: treated as no-op */
5118 }
5119
5120 static void gen_mfsri(DisasContext *ctx)
5121 {
5122 #if defined(CONFIG_USER_ONLY)
5123     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5124 #else
5125     int ra = rA(ctx->opcode);
5126     int rd = rD(ctx->opcode);
5127     TCGv t0;
5128     if (unlikely(!ctx->mem_idx)) {
5129         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5130         return;
5131     }
5132     t0 = tcg_temp_new();
5133     gen_addr_reg_index(ctx, t0);
5134     tcg_gen_shri_tl(t0, t0, 28);
5135     tcg_gen_andi_tl(t0, t0, 0xF);
5136     gen_helper_load_sr(cpu_gpr[rd], t0);
5137     tcg_temp_free(t0);
5138     if (ra != 0 && ra != rd)
5139         tcg_gen_mov_tl(cpu_gpr[ra], cpu_gpr[rd]);
5140 #endif
5141 }
5142
5143 static void gen_rac(DisasContext *ctx)
5144 {
5145 #if defined(CONFIG_USER_ONLY)
5146     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5147 #else
5148     TCGv t0;
5149     if (unlikely(!ctx->mem_idx)) {
5150         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5151         return;
5152     }
5153     t0 = tcg_temp_new();
5154     gen_addr_reg_index(ctx, t0);
5155     gen_helper_rac(cpu_gpr[rD(ctx->opcode)], t0);
5156     tcg_temp_free(t0);
5157 #endif
5158 }
5159
5160 static void gen_rfsvc(DisasContext *ctx)
5161 {
5162 #if defined(CONFIG_USER_ONLY)
5163     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5164 #else
5165     if (unlikely(!ctx->mem_idx)) {
5166         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5167         return;
5168     }
5169     gen_helper_rfsvc();
5170     gen_sync_exception(ctx);
5171 #endif
5172 }
5173
5174 /* svc is not implemented for now */
5175
5176 /* POWER2 specific instructions */
5177 /* Quad manipulation (load/store two floats at a time) */
5178
5179 /* lfq */
5180 static void gen_lfq(DisasContext *ctx)
5181 {
5182     int rd = rD(ctx->opcode);
5183     TCGv t0;
5184     gen_set_access_type(ctx, ACCESS_FLOAT);
5185     t0 = tcg_temp_new();
5186     gen_addr_imm_index(ctx, t0, 0);
5187     gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
5188     gen_addr_add(ctx, t0, t0, 8);
5189     gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t0);
5190     tcg_temp_free(t0);
5191 }
5192
5193 /* lfqu */
5194 static void gen_lfqu(DisasContext *ctx)
5195 {
5196     int ra = rA(ctx->opcode);
5197     int rd = rD(ctx->opcode);
5198     TCGv t0, t1;
5199     gen_set_access_type(ctx, ACCESS_FLOAT);
5200     t0 = tcg_temp_new();
5201     t1 = tcg_temp_new();
5202     gen_addr_imm_index(ctx, t0, 0);
5203     gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
5204     gen_addr_add(ctx, t1, t0, 8);
5205     gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t1);
5206     if (ra != 0)
5207         tcg_gen_mov_tl(cpu_gpr[ra], t0);
5208     tcg_temp_free(t0);
5209     tcg_temp_free(t1);
5210 }
5211
5212 /* lfqux */
5213 static void gen_lfqux(DisasContext *ctx)
5214 {
5215     int ra = rA(ctx->opcode);
5216     int rd = rD(ctx->opcode);
5217     gen_set_access_type(ctx, ACCESS_FLOAT);
5218     TCGv t0, t1;
5219     t0 = tcg_temp_new();
5220     gen_addr_reg_index(ctx, t0);
5221     gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
5222     t1 = tcg_temp_new();
5223     gen_addr_add(ctx, t1, t0, 8);
5224     gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t1);
5225     tcg_temp_free(t1);
5226     if (ra != 0)
5227         tcg_gen_mov_tl(cpu_gpr[ra], t0);
5228     tcg_temp_free(t0);
5229 }
5230
5231 /* lfqx */
5232 static void gen_lfqx(DisasContext *ctx)
5233 {
5234     int rd = rD(ctx->opcode);
5235     TCGv t0;
5236     gen_set_access_type(ctx, ACCESS_FLOAT);
5237     t0 = tcg_temp_new();
5238     gen_addr_reg_index(ctx, t0);
5239     gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
5240     gen_addr_add(ctx, t0, t0, 8);
5241     gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t0);
5242     tcg_temp_free(t0);
5243 }
5244
5245 /* stfq */
5246 static void gen_stfq(DisasContext *ctx)
5247 {
5248     int rd = rD(ctx->opcode);
5249     TCGv t0;
5250     gen_set_access_type(ctx, ACCESS_FLOAT);
5251     t0 = tcg_temp_new();
5252     gen_addr_imm_index(ctx, t0, 0);
5253     gen_qemu_st64(ctx, cpu_fpr[rd], t0);
5254     gen_addr_add(ctx, t0, t0, 8);
5255     gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t0);
5256     tcg_temp_free(t0);
5257 }
5258
5259 /* stfqu */
5260 static void gen_stfqu(DisasContext *ctx)
5261 {
5262     int ra = rA(ctx->opcode);
5263     int rd = rD(ctx->opcode);
5264     TCGv t0, t1;
5265     gen_set_access_type(ctx, ACCESS_FLOAT);
5266     t0 = tcg_temp_new();
5267     gen_addr_imm_index(ctx, t0, 0);
5268     gen_qemu_st64(ctx, cpu_fpr[rd], t0);
5269     t1 = tcg_temp_new();
5270     gen_addr_add(ctx, t1, t0, 8);
5271     gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t1);
5272     tcg_temp_free(t1);
5273     if (ra != 0)
5274         tcg_gen_mov_tl(cpu_gpr[ra], t0);
5275     tcg_temp_free(t0);
5276 }
5277
5278 /* stfqux */
5279 static void gen_stfqux(DisasContext *ctx)
5280 {
5281     int ra = rA(ctx->opcode);
5282     int rd = rD(ctx->opcode);
5283     TCGv t0, t1;
5284     gen_set_access_type(ctx, ACCESS_FLOAT);
5285     t0 = tcg_temp_new();
5286     gen_addr_reg_index(ctx, t0);
5287     gen_qemu_st64(ctx, cpu_fpr[rd], t0);
5288     t1 = tcg_temp_new();
5289     gen_addr_add(ctx, t1, t0, 8);
5290     gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t1);
5291     tcg_temp_free(t1);
5292     if (ra != 0)
5293         tcg_gen_mov_tl(cpu_gpr[ra], t0);
5294     tcg_temp_free(t0);
5295 }
5296
5297 /* stfqx */
5298 static void gen_stfqx(DisasContext *ctx)
5299 {
5300     int rd = rD(ctx->opcode);
5301     TCGv t0;
5302     gen_set_access_type(ctx, ACCESS_FLOAT);
5303     t0 = tcg_temp_new();
5304     gen_addr_reg_index(ctx, t0);
5305     gen_qemu_st64(ctx, cpu_fpr[rd], t0);
5306     gen_addr_add(ctx, t0, t0, 8);
5307     gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t0);
5308     tcg_temp_free(t0);
5309 }
5310
5311 /* BookE specific instructions */
5312
5313 /* XXX: not implemented on 440 ? */
5314 static void gen_mfapidi(DisasContext *ctx)
5315 {
5316     /* XXX: TODO */
5317     gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5318 }
5319
5320 /* XXX: not implemented on 440 ? */
5321 static void gen_tlbiva(DisasContext *ctx)
5322 {
5323 #if defined(CONFIG_USER_ONLY)
5324     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5325 #else
5326     TCGv t0;
5327     if (unlikely(!ctx->mem_idx)) {
5328         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5329         return;
5330     }
5331     t0 = tcg_temp_new();
5332     gen_addr_reg_index(ctx, t0);
5333     gen_helper_tlbie(cpu_gpr[rB(ctx->opcode)]);
5334     tcg_temp_free(t0);
5335 #endif
5336 }
5337
5338 /* All 405 MAC instructions are translated here */
5339 static inline void gen_405_mulladd_insn(DisasContext *ctx, int opc2, int opc3,
5340                                         int ra, int rb, int rt, int Rc)
5341 {
5342     TCGv t0, t1;
5343
5344     t0 = tcg_temp_local_new();
5345     t1 = tcg_temp_local_new();
5346
5347     switch (opc3 & 0x0D) {
5348     case 0x05:
5349         /* macchw    - macchw.    - macchwo   - macchwo.   */
5350         /* macchws   - macchws.   - macchwso  - macchwso.  */
5351         /* nmacchw   - nmacchw.   - nmacchwo  - nmacchwo.  */
5352         /* nmacchws  - nmacchws.  - nmacchwso - nmacchwso. */
5353         /* mulchw - mulchw. */
5354         tcg_gen_ext16s_tl(t0, cpu_gpr[ra]);
5355         tcg_gen_sari_tl(t1, cpu_gpr[rb], 16);
5356         tcg_gen_ext16s_tl(t1, t1);
5357         break;
5358     case 0x04:
5359         /* macchwu   - macchwu.   - macchwuo  - macchwuo.  */
5360         /* macchwsu  - macchwsu.  - macchwsuo - macchwsuo. */
5361         /* mulchwu - mulchwu. */
5362         tcg_gen_ext16u_tl(t0, cpu_gpr[ra]);
5363         tcg_gen_shri_tl(t1, cpu_gpr[rb], 16);
5364         tcg_gen_ext16u_tl(t1, t1);
5365         break;
5366     case 0x01:
5367         /* machhw    - machhw.    - machhwo   - machhwo.   */
5368         /* machhws   - machhws.   - machhwso  - machhwso.  */
5369         /* nmachhw   - nmachhw.   - nmachhwo  - nmachhwo.  */
5370         /* nmachhws  - nmachhws.  - nmachhwso - nmachhwso. */
5371         /* mulhhw - mulhhw. */
5372         tcg_gen_sari_tl(t0, cpu_gpr[ra], 16);
5373         tcg_gen_ext16s_tl(t0, t0);
5374         tcg_gen_sari_tl(t1, cpu_gpr[rb], 16);
5375         tcg_gen_ext16s_tl(t1, t1);
5376         break;
5377     case 0x00:
5378         /* machhwu   - machhwu.   - machhwuo  - machhwuo.  */
5379         /* machhwsu  - machhwsu.  - machhwsuo - machhwsuo. */
5380         /* mulhhwu - mulhhwu. */
5381         tcg_gen_shri_tl(t0, cpu_gpr[ra], 16);
5382         tcg_gen_ext16u_tl(t0, t0);
5383         tcg_gen_shri_tl(t1, cpu_gpr[rb], 16);
5384         tcg_gen_ext16u_tl(t1, t1);
5385         break;
5386     case 0x0D:
5387         /* maclhw    - maclhw.    - maclhwo   - maclhwo.   */
5388         /* maclhws   - maclhws.   - maclhwso  - maclhwso.  */
5389         /* nmaclhw   - nmaclhw.   - nmaclhwo  - nmaclhwo.  */
5390         /* nmaclhws  - nmaclhws.  - nmaclhwso - nmaclhwso. */
5391         /* mullhw - mullhw. */
5392         tcg_gen_ext16s_tl(t0, cpu_gpr[ra]);
5393         tcg_gen_ext16s_tl(t1, cpu_gpr[rb]);
5394         break;
5395     case 0x0C:
5396         /* maclhwu   - maclhwu.   - maclhwuo  - maclhwuo.  */
5397         /* maclhwsu  - maclhwsu.  - maclhwsuo - maclhwsuo. */
5398         /* mullhwu - mullhwu. */
5399         tcg_gen_ext16u_tl(t0, cpu_gpr[ra]);
5400         tcg_gen_ext16u_tl(t1, cpu_gpr[rb]);
5401         break;
5402     }
5403     if (opc2 & 0x04) {
5404         /* (n)multiply-and-accumulate (0x0C / 0x0E) */
5405         tcg_gen_mul_tl(t1, t0, t1);
5406         if (opc2 & 0x02) {
5407             /* nmultiply-and-accumulate (0x0E) */
5408             tcg_gen_sub_tl(t0, cpu_gpr[rt], t1);
5409         } else {
5410             /* multiply-and-accumulate (0x0C) */
5411             tcg_gen_add_tl(t0, cpu_gpr[rt], t1);
5412         }
5413
5414         if (opc3 & 0x12) {
5415             /* Check overflow and/or saturate */
5416             int l1 = gen_new_label();
5417
5418             if (opc3 & 0x10) {
5419                 /* Start with XER OV disabled, the most likely case */
5420                 tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
5421             }
5422             if (opc3 & 0x01) {
5423                 /* Signed */
5424                 tcg_gen_xor_tl(t1, cpu_gpr[rt], t1);
5425                 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
5426                 tcg_gen_xor_tl(t1, cpu_gpr[rt], t0);
5427                 tcg_gen_brcondi_tl(TCG_COND_LT, t1, 0, l1);
5428                 if (opc3 & 0x02) {
5429                     /* Saturate */
5430                     tcg_gen_sari_tl(t0, cpu_gpr[rt], 31);
5431                     tcg_gen_xori_tl(t0, t0, 0x7fffffff);
5432                 }
5433             } else {
5434                 /* Unsigned */
5435                 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
5436                 if (opc3 & 0x02) {
5437                     /* Saturate */
5438                     tcg_gen_movi_tl(t0, UINT32_MAX);
5439                 }
5440             }
5441             if (opc3 & 0x10) {
5442                 /* Check overflow */
5443                 tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
5444             }
5445             gen_set_label(l1);
5446             tcg_gen_mov_tl(cpu_gpr[rt], t0);
5447         }
5448     } else {
5449         tcg_gen_mul_tl(cpu_gpr[rt], t0, t1);
5450     }
5451     tcg_temp_free(t0);
5452     tcg_temp_free(t1);
5453     if (unlikely(Rc) != 0) {
5454         /* Update Rc0 */
5455         gen_set_Rc0(ctx, cpu_gpr[rt]);
5456     }
5457 }
5458
5459 #define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
5460 static void glue(gen_, name)(DisasContext *ctx)                               \
5461 {                                                                             \
5462     gen_405_mulladd_insn(ctx, opc2, opc3, rA(ctx->opcode), rB(ctx->opcode),   \
5463                          rD(ctx->opcode), Rc(ctx->opcode));                   \
5464 }
5465
5466 /* macchw    - macchw.    */
5467 GEN_MAC_HANDLER(macchw, 0x0C, 0x05);
5468 /* macchwo   - macchwo.   */
5469 GEN_MAC_HANDLER(macchwo, 0x0C, 0x15);
5470 /* macchws   - macchws.   */
5471 GEN_MAC_HANDLER(macchws, 0x0C, 0x07);
5472 /* macchwso  - macchwso.  */
5473 GEN_MAC_HANDLER(macchwso, 0x0C, 0x17);
5474 /* macchwsu  - macchwsu.  */
5475 GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06);
5476 /* macchwsuo - macchwsuo. */
5477 GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16);
5478 /* macchwu   - macchwu.   */
5479 GEN_MAC_HANDLER(macchwu, 0x0C, 0x04);
5480 /* macchwuo  - macchwuo.  */
5481 GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14);
5482 /* machhw    - machhw.    */
5483 GEN_MAC_HANDLER(machhw, 0x0C, 0x01);
5484 /* machhwo   - machhwo.   */
5485 GEN_MAC_HANDLER(machhwo, 0x0C, 0x11);
5486 /* machhws   - machhws.   */
5487 GEN_MAC_HANDLER(machhws, 0x0C, 0x03);
5488 /* machhwso  - machhwso.  */
5489 GEN_MAC_HANDLER(machhwso, 0x0C, 0x13);
5490 /* machhwsu  - machhwsu.  */
5491 GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02);
5492 /* machhwsuo - machhwsuo. */
5493 GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12);
5494 /* machhwu   - machhwu.   */
5495 GEN_MAC_HANDLER(machhwu, 0x0C, 0x00);
5496 /* machhwuo  - machhwuo.  */
5497 GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10);
5498 /* maclhw    - maclhw.    */
5499 GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D);
5500 /* maclhwo   - maclhwo.   */
5501 GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D);
5502 /* maclhws   - maclhws.   */
5503 GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F);
5504 /* maclhwso  - maclhwso.  */
5505 GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F);
5506 /* maclhwu   - maclhwu.   */
5507 GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C);
5508 /* maclhwuo  - maclhwuo.  */
5509 GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C);
5510 /* maclhwsu  - maclhwsu.  */
5511 GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E);
5512 /* maclhwsuo - maclhwsuo. */
5513 GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E);
5514 /* nmacchw   - nmacchw.   */
5515 GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05);
5516 /* nmacchwo  - nmacchwo.  */
5517 GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15);
5518 /* nmacchws  - nmacchws.  */
5519 GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07);
5520 /* nmacchwso - nmacchwso. */
5521 GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17);
5522 /* nmachhw   - nmachhw.   */
5523 GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01);
5524 /* nmachhwo  - nmachhwo.  */
5525 GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11);
5526 /* nmachhws  - nmachhws.  */
5527 GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03);
5528 /* nmachhwso - nmachhwso. */
5529 GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13);
5530 /* nmaclhw   - nmaclhw.   */
5531 GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D);
5532 /* nmaclhwo  - nmaclhwo.  */
5533 GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D);
5534 /* nmaclhws  - nmaclhws.  */
5535 GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F);
5536 /* nmaclhwso - nmaclhwso. */
5537 GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F);
5538
5539 /* mulchw  - mulchw.  */
5540 GEN_MAC_HANDLER(mulchw, 0x08, 0x05);
5541 /* mulchwu - mulchwu. */
5542 GEN_MAC_HANDLER(mulchwu, 0x08, 0x04);
5543 /* mulhhw  - mulhhw.  */
5544 GEN_MAC_HANDLER(mulhhw, 0x08, 0x01);
5545 /* mulhhwu - mulhhwu. */
5546 GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00);
5547 /* mullhw  - mullhw.  */
5548 GEN_MAC_HANDLER(mullhw, 0x08, 0x0D);
5549 /* mullhwu - mullhwu. */
5550 GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C);
5551
5552 /* mfdcr */
5553 static void gen_mfdcr(DisasContext *ctx)
5554 {
5555 #if defined(CONFIG_USER_ONLY)
5556     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
5557 #else
5558     TCGv dcrn;
5559     if (unlikely(!ctx->mem_idx)) {
5560         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
5561         return;
5562     }
5563     /* NIP cannot be restored if the memory exception comes from an helper */
5564     gen_update_nip(ctx, ctx->nip - 4);
5565     dcrn = tcg_const_tl(SPR(ctx->opcode));
5566     gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], dcrn);
5567     tcg_temp_free(dcrn);
5568 #endif
5569 }
5570
5571 /* mtdcr */
5572 static void gen_mtdcr(DisasContext *ctx)
5573 {
5574 #if defined(CONFIG_USER_ONLY)
5575     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
5576 #else
5577     TCGv dcrn;
5578     if (unlikely(!ctx->mem_idx)) {
5579         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
5580         return;
5581     }
5582     /* NIP cannot be restored if the memory exception comes from an helper */
5583     gen_update_nip(ctx, ctx->nip - 4);
5584     dcrn = tcg_const_tl(SPR(ctx->opcode));
5585     gen_helper_store_dcr(dcrn, cpu_gpr[rS(ctx->opcode)]);
5586     tcg_temp_free(dcrn);
5587 #endif
5588 }
5589
5590 /* mfdcrx */
5591 /* XXX: not implemented on 440 ? */
5592 static void gen_mfdcrx(DisasContext *ctx)
5593 {
5594 #if defined(CONFIG_USER_ONLY)
5595     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
5596 #else
5597     if (unlikely(!ctx->mem_idx)) {
5598         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
5599         return;
5600     }
5601     /* NIP cannot be restored if the memory exception comes from an helper */
5602     gen_update_nip(ctx, ctx->nip - 4);
5603     gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5604     /* Note: Rc update flag set leads to undefined state of Rc0 */
5605 #endif
5606 }
5607
5608 /* mtdcrx */
5609 /* XXX: not implemented on 440 ? */
5610 static void gen_mtdcrx(DisasContext *ctx)
5611 {
5612 #if defined(CONFIG_USER_ONLY)
5613     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
5614 #else
5615     if (unlikely(!ctx->mem_idx)) {
5616         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
5617         return;
5618     }
5619     /* NIP cannot be restored if the memory exception comes from an helper */
5620     gen_update_nip(ctx, ctx->nip - 4);
5621     gen_helper_store_dcr(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
5622     /* Note: Rc update flag set leads to undefined state of Rc0 */
5623 #endif
5624 }
5625
5626 /* mfdcrux (PPC 460) : user-mode access to DCR */
5627 static void gen_mfdcrux(DisasContext *ctx)
5628 {
5629     /* NIP cannot be restored if the memory exception comes from an helper */
5630     gen_update_nip(ctx, ctx->nip - 4);
5631     gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5632     /* Note: Rc update flag set leads to undefined state of Rc0 */
5633 }
5634
5635 /* mtdcrux (PPC 460) : user-mode access to DCR */
5636 static void gen_mtdcrux(DisasContext *ctx)
5637 {
5638     /* NIP cannot be restored if the memory exception comes from an helper */
5639     gen_update_nip(ctx, ctx->nip - 4);
5640     gen_helper_store_dcr(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
5641     /* Note: Rc update flag set leads to undefined state of Rc0 */
5642 }
5643
5644 /* dccci */
5645 static void gen_dccci(DisasContext *ctx)
5646 {
5647 #if defined(CONFIG_USER_ONLY)
5648     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5649 #else
5650     if (unlikely(!ctx->mem_idx)) {
5651         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5652         return;
5653     }
5654     /* interpreted as no-op */
5655 #endif
5656 }
5657
5658 /* dcread */
5659 static void gen_dcread(DisasContext *ctx)
5660 {
5661 #if defined(CONFIG_USER_ONLY)
5662     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5663 #else
5664     TCGv EA, val;
5665     if (unlikely(!ctx->mem_idx)) {
5666         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5667         return;
5668     }
5669     gen_set_access_type(ctx, ACCESS_CACHE);
5670     EA = tcg_temp_new();
5671     gen_addr_reg_index(ctx, EA);
5672     val = tcg_temp_new();
5673     gen_qemu_ld32u(ctx, val, EA);
5674     tcg_temp_free(val);
5675     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], EA);
5676     tcg_temp_free(EA);
5677 #endif
5678 }
5679
5680 /* icbt */
5681 static void gen_icbt_40x(DisasContext *ctx)
5682 {
5683     /* interpreted as no-op */
5684     /* XXX: specification say this is treated as a load by the MMU
5685      *      but does not generate any exception
5686      */
5687 }
5688
5689 /* iccci */
5690 static void gen_iccci(DisasContext *ctx)
5691 {
5692 #if defined(CONFIG_USER_ONLY)
5693     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5694 #else
5695     if (unlikely(!ctx->mem_idx)) {
5696         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5697         return;
5698     }
5699     /* interpreted as no-op */
5700 #endif
5701 }
5702
5703 /* icread */
5704 static void gen_icread(DisasContext *ctx)
5705 {
5706 #if defined(CONFIG_USER_ONLY)
5707     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5708 #else
5709     if (unlikely(!ctx->mem_idx)) {
5710         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5711         return;
5712     }
5713     /* interpreted as no-op */
5714 #endif
5715 }
5716
5717 /* rfci (mem_idx only) */
5718 static void gen_rfci_40x(DisasContext *ctx)
5719 {
5720 #if defined(CONFIG_USER_ONLY)
5721     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5722 #else
5723     if (unlikely(!ctx->mem_idx)) {
5724         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5725         return;
5726     }
5727     /* Restore CPU state */
5728     gen_helper_40x_rfci();
5729     gen_sync_exception(ctx);
5730 #endif
5731 }
5732
5733 static void gen_rfci(DisasContext *ctx)
5734 {
5735 #if defined(CONFIG_USER_ONLY)
5736     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5737 #else
5738     if (unlikely(!ctx->mem_idx)) {
5739         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5740         return;
5741     }
5742     /* Restore CPU state */
5743     gen_helper_rfci();
5744     gen_sync_exception(ctx);
5745 #endif
5746 }
5747
5748 /* BookE specific */
5749
5750 /* XXX: not implemented on 440 ? */
5751 static void gen_rfdi(DisasContext *ctx)
5752 {
5753 #if defined(CONFIG_USER_ONLY)
5754     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5755 #else
5756     if (unlikely(!ctx->mem_idx)) {
5757         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5758         return;
5759     }
5760     /* Restore CPU state */
5761     gen_helper_rfdi();
5762     gen_sync_exception(ctx);
5763 #endif
5764 }
5765
5766 /* XXX: not implemented on 440 ? */
5767 static void gen_rfmci(DisasContext *ctx)
5768 {
5769 #if defined(CONFIG_USER_ONLY)
5770     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5771 #else
5772     if (unlikely(!ctx->mem_idx)) {
5773         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5774         return;
5775     }
5776     /* Restore CPU state */
5777     gen_helper_rfmci();
5778     gen_sync_exception(ctx);
5779 #endif
5780 }
5781
5782 /* TLB management - PowerPC 405 implementation */
5783
5784 /* tlbre */
5785 static void gen_tlbre_40x(DisasContext *ctx)
5786 {
5787 #if defined(CONFIG_USER_ONLY)
5788     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5789 #else
5790     if (unlikely(!ctx->mem_idx)) {
5791         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5792         return;
5793     }
5794     switch (rB(ctx->opcode)) {
5795     case 0:
5796         gen_helper_4xx_tlbre_hi(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5797         break;
5798     case 1:
5799         gen_helper_4xx_tlbre_lo(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5800         break;
5801     default:
5802         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5803         break;
5804     }
5805 #endif
5806 }
5807
5808 /* tlbsx - tlbsx. */
5809 static void gen_tlbsx_40x(DisasContext *ctx)
5810 {
5811 #if defined(CONFIG_USER_ONLY)
5812     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5813 #else
5814     TCGv t0;
5815     if (unlikely(!ctx->mem_idx)) {
5816         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5817         return;
5818     }
5819     t0 = tcg_temp_new();
5820     gen_addr_reg_index(ctx, t0);
5821     gen_helper_4xx_tlbsx(cpu_gpr[rD(ctx->opcode)], t0);
5822     tcg_temp_free(t0);
5823     if (Rc(ctx->opcode)) {
5824         int l1 = gen_new_label();
5825         tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_xer);
5826         tcg_gen_shri_i32(cpu_crf[0], cpu_crf[0], XER_SO);
5827         tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 1);
5828         tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rD(ctx->opcode)], -1, l1);
5829         tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
5830         gen_set_label(l1);
5831     }
5832 #endif
5833 }
5834
5835 /* tlbwe */
5836 static void gen_tlbwe_40x(DisasContext *ctx)
5837 {
5838 #if defined(CONFIG_USER_ONLY)
5839     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5840 #else
5841     if (unlikely(!ctx->mem_idx)) {
5842         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5843         return;
5844     }
5845     switch (rB(ctx->opcode)) {
5846     case 0:
5847         gen_helper_4xx_tlbwe_hi(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
5848         break;
5849     case 1:
5850         gen_helper_4xx_tlbwe_lo(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
5851         break;
5852     default:
5853         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5854         break;
5855     }
5856 #endif
5857 }
5858
5859 /* TLB management - PowerPC 440 implementation */
5860
5861 /* tlbre */
5862 static void gen_tlbre_440(DisasContext *ctx)
5863 {
5864 #if defined(CONFIG_USER_ONLY)
5865     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5866 #else
5867     if (unlikely(!ctx->mem_idx)) {
5868         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5869         return;
5870     }
5871     switch (rB(ctx->opcode)) {
5872     case 0:
5873     case 1:
5874     case 2:
5875         {
5876             TCGv_i32 t0 = tcg_const_i32(rB(ctx->opcode));
5877             gen_helper_440_tlbre(cpu_gpr[rD(ctx->opcode)], t0, cpu_gpr[rA(ctx->opcode)]);
5878             tcg_temp_free_i32(t0);
5879         }
5880         break;
5881     default:
5882         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5883         break;
5884     }
5885 #endif
5886 }
5887
5888 /* tlbsx - tlbsx. */
5889 static void gen_tlbsx_440(DisasContext *ctx)
5890 {
5891 #if defined(CONFIG_USER_ONLY)
5892     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5893 #else
5894     TCGv t0;
5895     if (unlikely(!ctx->mem_idx)) {
5896         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5897         return;
5898     }
5899     t0 = tcg_temp_new();
5900     gen_addr_reg_index(ctx, t0);
5901     gen_helper_440_tlbsx(cpu_gpr[rD(ctx->opcode)], t0);
5902     tcg_temp_free(t0);
5903     if (Rc(ctx->opcode)) {
5904         int l1 = gen_new_label();
5905         tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_xer);
5906         tcg_gen_shri_i32(cpu_crf[0], cpu_crf[0], XER_SO);
5907         tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 1);
5908         tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rD(ctx->opcode)], -1, l1);
5909         tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
5910         gen_set_label(l1);
5911     }
5912 #endif
5913 }
5914
5915 /* tlbwe */
5916 static void gen_tlbwe_440(DisasContext *ctx)
5917 {
5918 #if defined(CONFIG_USER_ONLY)
5919     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5920 #else
5921     if (unlikely(!ctx->mem_idx)) {
5922         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5923         return;
5924     }
5925     switch (rB(ctx->opcode)) {
5926     case 0:
5927     case 1:
5928     case 2:
5929         {
5930             TCGv_i32 t0 = tcg_const_i32(rB(ctx->opcode));
5931             gen_helper_440_tlbwe(t0, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
5932             tcg_temp_free_i32(t0);
5933         }
5934         break;
5935     default:
5936         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5937         break;
5938     }
5939 #endif
5940 }
5941
5942 /* wrtee */
5943 static void gen_wrtee(DisasContext *ctx)
5944 {
5945 #if defined(CONFIG_USER_ONLY)
5946     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5947 #else
5948     TCGv t0;
5949     if (unlikely(!ctx->mem_idx)) {
5950         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5951         return;
5952     }
5953     t0 = tcg_temp_new();
5954     tcg_gen_andi_tl(t0, cpu_gpr[rD(ctx->opcode)], (1 << MSR_EE));
5955     tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE));
5956     tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
5957     tcg_temp_free(t0);
5958     /* Stop translation to have a chance to raise an exception
5959      * if we just set msr_ee to 1
5960      */
5961     gen_stop_exception(ctx);
5962 #endif
5963 }
5964
5965 /* wrteei */
5966 static void gen_wrteei(DisasContext *ctx)
5967 {
5968 #if defined(CONFIG_USER_ONLY)
5969     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5970 #else
5971     if (unlikely(!ctx->mem_idx)) {
5972         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5973         return;
5974     }
5975     if (ctx->opcode & 0x00008000) {
5976         tcg_gen_ori_tl(cpu_msr, cpu_msr, (1 << MSR_EE));
5977         /* Stop translation to have a chance to raise an exception */
5978         gen_stop_exception(ctx);
5979     } else {
5980         tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE));
5981     }
5982 #endif
5983 }
5984
5985 /* PowerPC 440 specific instructions */
5986
5987 /* dlmzb */
5988 static void gen_dlmzb(DisasContext *ctx)
5989 {
5990     TCGv_i32 t0 = tcg_const_i32(Rc(ctx->opcode));
5991     gen_helper_dlmzb(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)],
5992                      cpu_gpr[rB(ctx->opcode)], t0);
5993     tcg_temp_free_i32(t0);
5994 }
5995
5996 /* mbar replaces eieio on 440 */
5997 static void gen_mbar(DisasContext *ctx)
5998 {
5999     /* interpreted as no-op */
6000 }
6001
6002 /* msync replaces sync on 440 */
6003 static void gen_msync(DisasContext *ctx)
6004 {
6005     /* interpreted as no-op */
6006 }
6007
6008 /* icbt */
6009 static void gen_icbt_440(DisasContext *ctx)
6010 {
6011     /* interpreted as no-op */
6012     /* XXX: specification say this is treated as a load by the MMU
6013      *      but does not generate any exception
6014      */
6015 }
6016
6017 /***                      Altivec vector extension                         ***/
6018 /* Altivec registers moves */
6019
6020 static inline TCGv_ptr gen_avr_ptr(int reg)
6021 {
6022     TCGv_ptr r = tcg_temp_new_ptr();
6023     tcg_gen_addi_ptr(r, cpu_env, offsetof(CPUPPCState, avr[reg]));
6024     return r;
6025 }
6026
6027 #define GEN_VR_LDX(name, opc2, opc3)                                          \
6028 static void glue(gen_, name)(DisasContext *ctx)                                       \
6029 {                                                                             \
6030     TCGv EA;                                                                  \
6031     if (unlikely(!ctx->altivec_enabled)) {                                    \
6032         gen_exception(ctx, POWERPC_EXCP_VPU);                                 \
6033         return;                                                               \
6034     }                                                                         \
6035     gen_set_access_type(ctx, ACCESS_INT);                                     \
6036     EA = tcg_temp_new();                                                      \
6037     gen_addr_reg_index(ctx, EA);                                              \
6038     tcg_gen_andi_tl(EA, EA, ~0xf);                                            \
6039     if (ctx->le_mode) {                                                       \
6040         gen_qemu_ld64(ctx, cpu_avrl[rD(ctx->opcode)], EA);                    \
6041         tcg_gen_addi_tl(EA, EA, 8);                                           \
6042         gen_qemu_ld64(ctx, cpu_avrh[rD(ctx->opcode)], EA);                    \
6043     } else {                                                                  \
6044         gen_qemu_ld64(ctx, cpu_avrh[rD(ctx->opcode)], EA);                    \
6045         tcg_gen_addi_tl(EA, EA, 8);                                           \
6046         gen_qemu_ld64(ctx, cpu_avrl[rD(ctx->opcode)], EA);                    \
6047     }                                                                         \
6048     tcg_temp_free(EA);                                                        \
6049 }
6050
6051 #define GEN_VR_STX(name, opc2, opc3)                                          \
6052 static void gen_st##name(DisasContext *ctx)                                   \
6053 {                                                                             \
6054     TCGv EA;                                                                  \
6055     if (unlikely(!ctx->altivec_enabled)) {                                    \
6056         gen_exception(ctx, POWERPC_EXCP_VPU);                                 \
6057         return;                                                               \
6058     }                                                                         \
6059     gen_set_access_type(ctx, ACCESS_INT);                                     \
6060     EA = tcg_temp_new();                                                      \
6061     gen_addr_reg_index(ctx, EA);                                              \
6062     tcg_gen_andi_tl(EA, EA, ~0xf);                                            \
6063     if (ctx->le_mode) {                                                       \
6064         gen_qemu_st64(ctx, cpu_avrl[rD(ctx->opcode)], EA);                    \
6065         tcg_gen_addi_tl(EA, EA, 8);                                           \
6066         gen_qemu_st64(ctx, cpu_avrh[rD(ctx->opcode)], EA);                    \
6067     } else {                                                                  \
6068         gen_qemu_st64(ctx, cpu_avrh[rD(ctx->opcode)], EA);                    \
6069         tcg_gen_addi_tl(EA, EA, 8);                                           \
6070         gen_qemu_st64(ctx, cpu_avrl[rD(ctx->opcode)], EA);                    \
6071     }                                                                         \
6072     tcg_temp_free(EA);                                                        \
6073 }
6074
6075 #define GEN_VR_LVE(name, opc2, opc3)                                    \
6076 static void gen_lve##name(DisasContext *ctx)                            \
6077     {                                                                   \
6078         TCGv EA;                                                        \
6079         TCGv_ptr rs;                                                    \
6080         if (unlikely(!ctx->altivec_enabled)) {                          \
6081             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
6082             return;                                                     \
6083         }                                                               \
6084         gen_set_access_type(ctx, ACCESS_INT);                           \
6085         EA = tcg_temp_new();                                            \
6086         gen_addr_reg_index(ctx, EA);                                    \
6087         rs = gen_avr_ptr(rS(ctx->opcode));                              \
6088         gen_helper_lve##name (rs, EA);                                  \
6089         tcg_temp_free(EA);                                              \
6090         tcg_temp_free_ptr(rs);                                          \
6091     }
6092
6093 #define GEN_VR_STVE(name, opc2, opc3)                                   \
6094 static void gen_stve##name(DisasContext *ctx)                           \
6095     {                                                                   \
6096         TCGv EA;                                                        \
6097         TCGv_ptr rs;                                                    \
6098         if (unlikely(!ctx->altivec_enabled)) {                          \
6099             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
6100             return;                                                     \
6101         }                                                               \
6102         gen_set_access_type(ctx, ACCESS_INT);                           \
6103         EA = tcg_temp_new();                                            \
6104         gen_addr_reg_index(ctx, EA);                                    \
6105         rs = gen_avr_ptr(rS(ctx->opcode));                              \
6106         gen_helper_stve##name (rs, EA);                                 \
6107         tcg_temp_free(EA);                                              \
6108         tcg_temp_free_ptr(rs);                                          \
6109     }
6110
6111 GEN_VR_LDX(lvx, 0x07, 0x03);
6112 /* As we don't emulate the cache, lvxl is stricly equivalent to lvx */
6113 GEN_VR_LDX(lvxl, 0x07, 0x0B);
6114
6115 GEN_VR_LVE(bx, 0x07, 0x00);
6116 GEN_VR_LVE(hx, 0x07, 0x01);
6117 GEN_VR_LVE(wx, 0x07, 0x02);
6118
6119 GEN_VR_STX(svx, 0x07, 0x07);
6120 /* As we don't emulate the cache, stvxl is stricly equivalent to stvx */
6121 GEN_VR_STX(svxl, 0x07, 0x0F);
6122
6123 GEN_VR_STVE(bx, 0x07, 0x04);
6124 GEN_VR_STVE(hx, 0x07, 0x05);
6125 GEN_VR_STVE(wx, 0x07, 0x06);
6126
6127 static void gen_lvsl(DisasContext *ctx)
6128 {
6129     TCGv_ptr rd;
6130     TCGv EA;
6131     if (unlikely(!ctx->altivec_enabled)) {
6132         gen_exception(ctx, POWERPC_EXCP_VPU);
6133         return;
6134     }
6135     EA = tcg_temp_new();
6136     gen_addr_reg_index(ctx, EA);
6137     rd = gen_avr_ptr(rD(ctx->opcode));
6138     gen_helper_lvsl(rd, EA);
6139     tcg_temp_free(EA);
6140     tcg_temp_free_ptr(rd);
6141 }
6142
6143 static void gen_lvsr(DisasContext *ctx)
6144 {
6145     TCGv_ptr rd;
6146     TCGv EA;
6147     if (unlikely(!ctx->altivec_enabled)) {
6148         gen_exception(ctx, POWERPC_EXCP_VPU);
6149         return;
6150     }
6151     EA = tcg_temp_new();
6152     gen_addr_reg_index(ctx, EA);
6153     rd = gen_avr_ptr(rD(ctx->opcode));
6154     gen_helper_lvsr(rd, EA);
6155     tcg_temp_free(EA);
6156     tcg_temp_free_ptr(rd);
6157 }
6158
6159 static void gen_mfvscr(DisasContext *ctx)
6160 {
6161     TCGv_i32 t;
6162     if (unlikely(!ctx->altivec_enabled)) {
6163         gen_exception(ctx, POWERPC_EXCP_VPU);
6164         return;
6165     }
6166     tcg_gen_movi_i64(cpu_avrh[rD(ctx->opcode)], 0);
6167     t = tcg_temp_new_i32();
6168     tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, vscr));
6169     tcg_gen_extu_i32_i64(cpu_avrl[rD(ctx->opcode)], t);
6170     tcg_temp_free_i32(t);
6171 }
6172
6173 static void gen_mtvscr(DisasContext *ctx)
6174 {
6175     TCGv_ptr p;
6176     if (unlikely(!ctx->altivec_enabled)) {
6177         gen_exception(ctx, POWERPC_EXCP_VPU);
6178         return;
6179     }
6180     p = gen_avr_ptr(rD(ctx->opcode));
6181     gen_helper_mtvscr(p);
6182     tcg_temp_free_ptr(p);
6183 }
6184
6185 /* Logical operations */
6186 #define GEN_VX_LOGICAL(name, tcg_op, opc2, opc3)                        \
6187 static void glue(gen_, name)(DisasContext *ctx)                                 \
6188 {                                                                       \
6189     if (unlikely(!ctx->altivec_enabled)) {                              \
6190         gen_exception(ctx, POWERPC_EXCP_VPU);                           \
6191         return;                                                         \
6192     }                                                                   \
6193     tcg_op(cpu_avrh[rD(ctx->opcode)], cpu_avrh[rA(ctx->opcode)], cpu_avrh[rB(ctx->opcode)]); \
6194     tcg_op(cpu_avrl[rD(ctx->opcode)], cpu_avrl[rA(ctx->opcode)], cpu_avrl[rB(ctx->opcode)]); \
6195 }
6196
6197 GEN_VX_LOGICAL(vand, tcg_gen_and_i64, 2, 16);
6198 GEN_VX_LOGICAL(vandc, tcg_gen_andc_i64, 2, 17);
6199 GEN_VX_LOGICAL(vor, tcg_gen_or_i64, 2, 18);
6200 GEN_VX_LOGICAL(vxor, tcg_gen_xor_i64, 2, 19);
6201 GEN_VX_LOGICAL(vnor, tcg_gen_nor_i64, 2, 20);
6202
6203 #define GEN_VXFORM(name, opc2, opc3)                                    \
6204 static void glue(gen_, name)(DisasContext *ctx)                                 \
6205 {                                                                       \
6206     TCGv_ptr ra, rb, rd;                                                \
6207     if (unlikely(!ctx->altivec_enabled)) {                              \
6208         gen_exception(ctx, POWERPC_EXCP_VPU);                           \
6209         return;                                                         \
6210     }                                                                   \
6211     ra = gen_avr_ptr(rA(ctx->opcode));                                  \
6212     rb = gen_avr_ptr(rB(ctx->opcode));                                  \
6213     rd = gen_avr_ptr(rD(ctx->opcode));                                  \
6214     gen_helper_##name (rd, ra, rb);                                     \
6215     tcg_temp_free_ptr(ra);                                              \
6216     tcg_temp_free_ptr(rb);                                              \
6217     tcg_temp_free_ptr(rd);                                              \
6218 }
6219
6220 GEN_VXFORM(vaddubm, 0, 0);
6221 GEN_VXFORM(vadduhm, 0, 1);
6222 GEN_VXFORM(vadduwm, 0, 2);
6223 GEN_VXFORM(vsububm, 0, 16);
6224 GEN_VXFORM(vsubuhm, 0, 17);
6225 GEN_VXFORM(vsubuwm, 0, 18);
6226 GEN_VXFORM(vmaxub, 1, 0);
6227 GEN_VXFORM(vmaxuh, 1, 1);
6228 GEN_VXFORM(vmaxuw, 1, 2);
6229 GEN_VXFORM(vmaxsb, 1, 4);
6230 GEN_VXFORM(vmaxsh, 1, 5);
6231 GEN_VXFORM(vmaxsw, 1, 6);
6232 GEN_VXFORM(vminub, 1, 8);
6233 GEN_VXFORM(vminuh, 1, 9);
6234 GEN_VXFORM(vminuw, 1, 10);
6235 GEN_VXFORM(vminsb, 1, 12);
6236 GEN_VXFORM(vminsh, 1, 13);
6237 GEN_VXFORM(vminsw, 1, 14);
6238 GEN_VXFORM(vavgub, 1, 16);
6239 GEN_VXFORM(vavguh, 1, 17);
6240 GEN_VXFORM(vavguw, 1, 18);
6241 GEN_VXFORM(vavgsb, 1, 20);
6242 GEN_VXFORM(vavgsh, 1, 21);
6243 GEN_VXFORM(vavgsw, 1, 22);
6244 GEN_VXFORM(vmrghb, 6, 0);
6245 GEN_VXFORM(vmrghh, 6, 1);
6246 GEN_VXFORM(vmrghw, 6, 2);
6247 GEN_VXFORM(vmrglb, 6, 4);
6248 GEN_VXFORM(vmrglh, 6, 5);
6249 GEN_VXFORM(vmrglw, 6, 6);
6250 GEN_VXFORM(vmuloub, 4, 0);
6251 GEN_VXFORM(vmulouh, 4, 1);
6252 GEN_VXFORM(vmulosb, 4, 4);
6253 GEN_VXFORM(vmulosh, 4, 5);
6254 GEN_VXFORM(vmuleub, 4, 8);
6255 GEN_VXFORM(vmuleuh, 4, 9);
6256 GEN_VXFORM(vmulesb, 4, 12);
6257 GEN_VXFORM(vmulesh, 4, 13);
6258 GEN_VXFORM(vslb, 2, 4);
6259 GEN_VXFORM(vslh, 2, 5);
6260 GEN_VXFORM(vslw, 2, 6);
6261 GEN_VXFORM(vsrb, 2, 8);
6262 GEN_VXFORM(vsrh, 2, 9);
6263 GEN_VXFORM(vsrw, 2, 10);
6264 GEN_VXFORM(vsrab, 2, 12);
6265 GEN_VXFORM(vsrah, 2, 13);
6266 GEN_VXFORM(vsraw, 2, 14);
6267 GEN_VXFORM(vslo, 6, 16);
6268 GEN_VXFORM(vsro, 6, 17);
6269 GEN_VXFORM(vaddcuw, 0, 6);
6270 GEN_VXFORM(vsubcuw, 0, 22);
6271 GEN_VXFORM(vaddubs, 0, 8);
6272 GEN_VXFORM(vadduhs, 0, 9);
6273 GEN_VXFORM(vadduws, 0, 10);
6274 GEN_VXFORM(vaddsbs, 0, 12);
6275 GEN_VXFORM(vaddshs, 0, 13);
6276 GEN_VXFORM(vaddsws, 0, 14);
6277 GEN_VXFORM(vsububs, 0, 24);
6278 GEN_VXFORM(vsubuhs, 0, 25);
6279 GEN_VXFORM(vsubuws, 0, 26);
6280 GEN_VXFORM(vsubsbs, 0, 28);
6281 GEN_VXFORM(vsubshs, 0, 29);
6282 GEN_VXFORM(vsubsws, 0, 30);
6283 GEN_VXFORM(vrlb, 2, 0);
6284 GEN_VXFORM(vrlh, 2, 1);
6285 GEN_VXFORM(vrlw, 2, 2);
6286 GEN_VXFORM(vsl, 2, 7);
6287 GEN_VXFORM(vsr, 2, 11);
6288 GEN_VXFORM(vpkuhum, 7, 0);
6289 GEN_VXFORM(vpkuwum, 7, 1);
6290 GEN_VXFORM(vpkuhus, 7, 2);
6291 GEN_VXFORM(vpkuwus, 7, 3);
6292 GEN_VXFORM(vpkshus, 7, 4);
6293 GEN_VXFORM(vpkswus, 7, 5);
6294 GEN_VXFORM(vpkshss, 7, 6);
6295 GEN_VXFORM(vpkswss, 7, 7);
6296 GEN_VXFORM(vpkpx, 7, 12);
6297 GEN_VXFORM(vsum4ubs, 4, 24);
6298 GEN_VXFORM(vsum4sbs, 4, 28);
6299 GEN_VXFORM(vsum4shs, 4, 25);
6300 GEN_VXFORM(vsum2sws, 4, 26);
6301 GEN_VXFORM(vsumsws, 4, 30);
6302 GEN_VXFORM(vaddfp, 5, 0);
6303 GEN_VXFORM(vsubfp, 5, 1);
6304 GEN_VXFORM(vmaxfp, 5, 16);
6305 GEN_VXFORM(vminfp, 5, 17);
6306
6307 #define GEN_VXRFORM1(opname, name, str, opc2, opc3)                     \
6308 static void glue(gen_, name)(DisasContext *ctx)                         \
6309     {                                                                   \
6310         TCGv_ptr ra, rb, rd;                                            \
6311         if (unlikely(!ctx->altivec_enabled)) {                          \
6312             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
6313             return;                                                     \
6314         }                                                               \
6315         ra = gen_avr_ptr(rA(ctx->opcode));                              \
6316         rb = gen_avr_ptr(rB(ctx->opcode));                              \
6317         rd = gen_avr_ptr(rD(ctx->opcode));                              \
6318         gen_helper_##opname (rd, ra, rb);                               \
6319         tcg_temp_free_ptr(ra);                                          \
6320         tcg_temp_free_ptr(rb);                                          \
6321         tcg_temp_free_ptr(rd);                                          \
6322     }
6323
6324 #define GEN_VXRFORM(name, opc2, opc3)                                \
6325     GEN_VXRFORM1(name, name, #name, opc2, opc3)                      \
6326     GEN_VXRFORM1(name##_dot, name##_, #name ".", opc2, (opc3 | (0x1 << 4)))
6327
6328 GEN_VXRFORM(vcmpequb, 3, 0)
6329 GEN_VXRFORM(vcmpequh, 3, 1)
6330 GEN_VXRFORM(vcmpequw, 3, 2)
6331 GEN_VXRFORM(vcmpgtsb, 3, 12)
6332 GEN_VXRFORM(vcmpgtsh, 3, 13)
6333 GEN_VXRFORM(vcmpgtsw, 3, 14)
6334 GEN_VXRFORM(vcmpgtub, 3, 8)
6335 GEN_VXRFORM(vcmpgtuh, 3, 9)
6336 GEN_VXRFORM(vcmpgtuw, 3, 10)
6337 GEN_VXRFORM(vcmpeqfp, 3, 3)
6338 GEN_VXRFORM(vcmpgefp, 3, 7)
6339 GEN_VXRFORM(vcmpgtfp, 3, 11)
6340 GEN_VXRFORM(vcmpbfp, 3, 15)
6341
6342 #define GEN_VXFORM_SIMM(name, opc2, opc3)                               \
6343 static void glue(gen_, name)(DisasContext *ctx)                         \
6344     {                                                                   \
6345         TCGv_ptr rd;                                                    \
6346         TCGv_i32 simm;                                                  \
6347         if (unlikely(!ctx->altivec_enabled)) {                          \
6348             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
6349             return;                                                     \
6350         }                                                               \
6351         simm = tcg_const_i32(SIMM5(ctx->opcode));                       \
6352         rd = gen_avr_ptr(rD(ctx->opcode));                              \
6353         gen_helper_##name (rd, simm);                                   \
6354         tcg_temp_free_i32(simm);                                        \
6355         tcg_temp_free_ptr(rd);                                          \
6356     }
6357
6358 GEN_VXFORM_SIMM(vspltisb, 6, 12);
6359 GEN_VXFORM_SIMM(vspltish, 6, 13);
6360 GEN_VXFORM_SIMM(vspltisw, 6, 14);
6361
6362 #define GEN_VXFORM_NOA(name, opc2, opc3)                                \
6363 static void glue(gen_, name)(DisasContext *ctx)                                 \
6364     {                                                                   \
6365         TCGv_ptr rb, rd;                                                \
6366         if (unlikely(!ctx->altivec_enabled)) {                          \
6367             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
6368             return;                                                     \
6369         }                                                               \
6370         rb = gen_avr_ptr(rB(ctx->opcode));                              \
6371         rd = gen_avr_ptr(rD(ctx->opcode));                              \
6372         gen_helper_##name (rd, rb);                                     \
6373         tcg_temp_free_ptr(rb);                                          \
6374         tcg_temp_free_ptr(rd);                                         \
6375     }
6376
6377 GEN_VXFORM_NOA(vupkhsb, 7, 8);
6378 GEN_VXFORM_NOA(vupkhsh, 7, 9);
6379 GEN_VXFORM_NOA(vupklsb, 7, 10);
6380 GEN_VXFORM_NOA(vupklsh, 7, 11);
6381 GEN_VXFORM_NOA(vupkhpx, 7, 13);
6382 GEN_VXFORM_NOA(vupklpx, 7, 15);
6383 GEN_VXFORM_NOA(vrefp, 5, 4);
6384 GEN_VXFORM_NOA(vrsqrtefp, 5, 5);
6385 GEN_VXFORM_NOA(vexptefp, 5, 6);
6386 GEN_VXFORM_NOA(vlogefp, 5, 7);
6387 GEN_VXFORM_NOA(vrfim, 5, 8);
6388 GEN_VXFORM_NOA(vrfin, 5, 9);
6389 GEN_VXFORM_NOA(vrfip, 5, 10);
6390 GEN_VXFORM_NOA(vrfiz, 5, 11);
6391
6392 #define GEN_VXFORM_SIMM(name, opc2, opc3)                               \
6393 static void glue(gen_, name)(DisasContext *ctx)                                 \
6394     {                                                                   \
6395         TCGv_ptr rd;                                                    \
6396         TCGv_i32 simm;                                                  \
6397         if (unlikely(!ctx->altivec_enabled)) {                          \
6398             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
6399             return;                                                     \
6400         }                                                               \
6401         simm = tcg_const_i32(SIMM5(ctx->opcode));                       \
6402         rd = gen_avr_ptr(rD(ctx->opcode));                              \
6403         gen_helper_##name (rd, simm);                                   \
6404         tcg_temp_free_i32(simm);                                        \
6405         tcg_temp_free_ptr(rd);                                          \
6406     }
6407
6408 #define GEN_VXFORM_UIMM(name, opc2, opc3)                               \
6409 static void glue(gen_, name)(DisasContext *ctx)                                 \
6410     {                                                                   \
6411         TCGv_ptr rb, rd;                                                \
6412         TCGv_i32 uimm;                                                  \
6413         if (unlikely(!ctx->altivec_enabled)) {                          \
6414             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
6415             return;                                                     \
6416         }                                                               \
6417         uimm = tcg_const_i32(UIMM5(ctx->opcode));                       \
6418         rb = gen_avr_ptr(rB(ctx->opcode));                              \
6419         rd = gen_avr_ptr(rD(ctx->opcode));                              \
6420         gen_helper_##name (rd, rb, uimm);                               \
6421         tcg_temp_free_i32(uimm);                                        \
6422         tcg_temp_free_ptr(rb);                                          \
6423         tcg_temp_free_ptr(rd);                                          \
6424     }
6425
6426 GEN_VXFORM_UIMM(vspltb, 6, 8);
6427 GEN_VXFORM_UIMM(vsplth, 6, 9);
6428 GEN_VXFORM_UIMM(vspltw, 6, 10);
6429 GEN_VXFORM_UIMM(vcfux, 5, 12);
6430 GEN_VXFORM_UIMM(vcfsx, 5, 13);
6431 GEN_VXFORM_UIMM(vctuxs, 5, 14);
6432 GEN_VXFORM_UIMM(vctsxs, 5, 15);
6433
6434 static void gen_vsldoi(DisasContext *ctx)
6435 {
6436     TCGv_ptr ra, rb, rd;
6437     TCGv_i32 sh;
6438     if (unlikely(!ctx->altivec_enabled)) {
6439         gen_exception(ctx, POWERPC_EXCP_VPU);
6440         return;
6441     }
6442     ra = gen_avr_ptr(rA(ctx->opcode));
6443     rb = gen_avr_ptr(rB(ctx->opcode));
6444     rd = gen_avr_ptr(rD(ctx->opcode));
6445     sh = tcg_const_i32(VSH(ctx->opcode));
6446     gen_helper_vsldoi (rd, ra, rb, sh);
6447     tcg_temp_free_ptr(ra);
6448     tcg_temp_free_ptr(rb);
6449     tcg_temp_free_ptr(rd);
6450     tcg_temp_free_i32(sh);
6451 }
6452
6453 #define GEN_VAFORM_PAIRED(name0, name1, opc2)                           \
6454 static void glue(gen_, name0##_##name1)(DisasContext *ctx)                      \
6455     {                                                                   \
6456         TCGv_ptr ra, rb, rc, rd;                                        \
6457         if (unlikely(!ctx->altivec_enabled)) {                          \
6458             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
6459             return;                                                     \
6460         }                                                               \
6461         ra = gen_avr_ptr(rA(ctx->opcode));                              \
6462         rb = gen_avr_ptr(rB(ctx->opcode));                              \
6463         rc = gen_avr_ptr(rC(ctx->opcode));                              \
6464         rd = gen_avr_ptr(rD(ctx->opcode));                              \
6465         if (Rc(ctx->opcode)) {                                          \
6466             gen_helper_##name1 (rd, ra, rb, rc);                        \
6467         } else {                                                        \
6468             gen_helper_##name0 (rd, ra, rb, rc);                        \
6469         }                                                               \
6470         tcg_temp_free_ptr(ra);                                          \
6471         tcg_temp_free_ptr(rb);                                          \
6472         tcg_temp_free_ptr(rc);                                          \
6473         tcg_temp_free_ptr(rd);                                          \
6474     }
6475
6476 GEN_VAFORM_PAIRED(vmhaddshs, vmhraddshs, 16)
6477
6478 static void gen_vmladduhm(DisasContext *ctx)
6479 {
6480     TCGv_ptr ra, rb, rc, rd;
6481     if (unlikely(!ctx->altivec_enabled)) {
6482         gen_exception(ctx, POWERPC_EXCP_VPU);
6483         return;
6484     }
6485     ra = gen_avr_ptr(rA(ctx->opcode));
6486     rb = gen_avr_ptr(rB(ctx->opcode));
6487     rc = gen_avr_ptr(rC(ctx->opcode));
6488     rd = gen_avr_ptr(rD(ctx->opcode));
6489     gen_helper_vmladduhm(rd, ra, rb, rc);
6490     tcg_temp_free_ptr(ra);
6491     tcg_temp_free_ptr(rb);
6492     tcg_temp_free_ptr(rc);
6493     tcg_temp_free_ptr(rd);
6494 }
6495
6496 GEN_VAFORM_PAIRED(vmsumubm, vmsummbm, 18)
6497 GEN_VAFORM_PAIRED(vmsumuhm, vmsumuhs, 19)
6498 GEN_VAFORM_PAIRED(vmsumshm, vmsumshs, 20)
6499 GEN_VAFORM_PAIRED(vsel, vperm, 21)
6500 GEN_VAFORM_PAIRED(vmaddfp, vnmsubfp, 23)
6501
6502 /***                           SPE extension                               ***/
6503 /* Register moves */
6504
6505
6506 static inline void gen_evmra(DisasContext *ctx)
6507 {
6508
6509     if (unlikely(!ctx->spe_enabled)) {
6510         gen_exception(ctx, POWERPC_EXCP_APU);
6511         return;
6512     }
6513
6514 #if defined(TARGET_PPC64)
6515     /* rD := rA */
6516     tcg_gen_mov_i64(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
6517
6518     /* spe_acc := rA */
6519     tcg_gen_st_i64(cpu_gpr[rA(ctx->opcode)],
6520                    cpu_env,
6521                    offsetof(CPUState, spe_acc));
6522 #else
6523     TCGv_i64 tmp = tcg_temp_new_i64();
6524
6525     /* tmp := rA_lo + rA_hi << 32 */
6526     tcg_gen_concat_i32_i64(tmp, cpu_gpr[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
6527
6528     /* spe_acc := tmp */
6529     tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUState, spe_acc));
6530     tcg_temp_free_i64(tmp);
6531
6532     /* rD := rA */
6533     tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
6534     tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
6535 #endif
6536 }
6537
6538 static inline void gen_load_gpr64(TCGv_i64 t, int reg)
6539 {
6540 #if defined(TARGET_PPC64)
6541     tcg_gen_mov_i64(t, cpu_gpr[reg]);
6542 #else
6543     tcg_gen_concat_i32_i64(t, cpu_gpr[reg], cpu_gprh[reg]);
6544 #endif
6545 }
6546
6547 static inline void gen_store_gpr64(int reg, TCGv_i64 t)
6548 {
6549 #if defined(TARGET_PPC64)
6550     tcg_gen_mov_i64(cpu_gpr[reg], t);
6551 #else
6552     TCGv_i64 tmp = tcg_temp_new_i64();
6553     tcg_gen_trunc_i64_i32(cpu_gpr[reg], t);
6554     tcg_gen_shri_i64(tmp, t, 32);
6555     tcg_gen_trunc_i64_i32(cpu_gprh[reg], tmp);
6556     tcg_temp_free_i64(tmp);
6557 #endif
6558 }
6559
6560 #define GEN_SPE(name0, name1, opc2, opc3, inval, type)                        \
6561 static void glue(gen_, name0##_##name1)(DisasContext *ctx)                    \
6562 {                                                                             \
6563     if (Rc(ctx->opcode))                                                      \
6564         gen_##name1(ctx);                                                     \
6565     else                                                                      \
6566         gen_##name0(ctx);                                                     \
6567 }
6568
6569 /* Handler for undefined SPE opcodes */
6570 static inline void gen_speundef(DisasContext *ctx)
6571 {
6572     gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
6573 }
6574
6575 /* SPE logic */
6576 #if defined(TARGET_PPC64)
6577 #define GEN_SPEOP_LOGIC2(name, tcg_op)                                        \
6578 static inline void gen_##name(DisasContext *ctx)                              \
6579 {                                                                             \
6580     if (unlikely(!ctx->spe_enabled)) {                                        \
6581         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6582         return;                                                               \
6583     }                                                                         \
6584     tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],                \
6585            cpu_gpr[rB(ctx->opcode)]);                                         \
6586 }
6587 #else
6588 #define GEN_SPEOP_LOGIC2(name, tcg_op)                                        \
6589 static inline void gen_##name(DisasContext *ctx)                              \
6590 {                                                                             \
6591     if (unlikely(!ctx->spe_enabled)) {                                        \
6592         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6593         return;                                                               \
6594     }                                                                         \
6595     tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],                \
6596            cpu_gpr[rB(ctx->opcode)]);                                         \
6597     tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],              \
6598            cpu_gprh[rB(ctx->opcode)]);                                        \
6599 }
6600 #endif
6601
6602 GEN_SPEOP_LOGIC2(evand, tcg_gen_and_tl);
6603 GEN_SPEOP_LOGIC2(evandc, tcg_gen_andc_tl);
6604 GEN_SPEOP_LOGIC2(evxor, tcg_gen_xor_tl);
6605 GEN_SPEOP_LOGIC2(evor, tcg_gen_or_tl);
6606 GEN_SPEOP_LOGIC2(evnor, tcg_gen_nor_tl);
6607 GEN_SPEOP_LOGIC2(eveqv, tcg_gen_eqv_tl);
6608 GEN_SPEOP_LOGIC2(evorc, tcg_gen_orc_tl);
6609 GEN_SPEOP_LOGIC2(evnand, tcg_gen_nand_tl);
6610
6611 /* SPE logic immediate */
6612 #if defined(TARGET_PPC64)
6613 #define GEN_SPEOP_TCG_LOGIC_IMM2(name, tcg_opi)                               \
6614 static inline void gen_##name(DisasContext *ctx)                              \
6615 {                                                                             \
6616     if (unlikely(!ctx->spe_enabled)) {                                        \
6617         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6618         return;                                                               \
6619     }                                                                         \
6620     TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
6621     TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
6622     TCGv_i64 t2 = tcg_temp_local_new_i64();                                   \
6623     tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]);                      \
6624     tcg_opi(t0, t0, rB(ctx->opcode));                                         \
6625     tcg_gen_shri_i64(t2, cpu_gpr[rA(ctx->opcode)], 32);                       \
6626     tcg_gen_trunc_i64_i32(t1, t2);                                            \
6627     tcg_temp_free_i64(t2);                                                    \
6628     tcg_opi(t1, t1, rB(ctx->opcode));                                         \
6629     tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);                 \
6630     tcg_temp_free_i32(t0);                                                    \
6631     tcg_temp_free_i32(t1);                                                    \
6632 }
6633 #else
6634 #define GEN_SPEOP_TCG_LOGIC_IMM2(name, tcg_opi)                               \
6635 static inline void gen_##name(DisasContext *ctx)                              \
6636 {                                                                             \
6637     if (unlikely(!ctx->spe_enabled)) {                                        \
6638         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6639         return;                                                               \
6640     }                                                                         \
6641     tcg_opi(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],               \
6642             rB(ctx->opcode));                                                 \
6643     tcg_opi(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],             \
6644             rB(ctx->opcode));                                                 \
6645 }
6646 #endif
6647 GEN_SPEOP_TCG_LOGIC_IMM2(evslwi, tcg_gen_shli_i32);
6648 GEN_SPEOP_TCG_LOGIC_IMM2(evsrwiu, tcg_gen_shri_i32);
6649 GEN_SPEOP_TCG_LOGIC_IMM2(evsrwis, tcg_gen_sari_i32);
6650 GEN_SPEOP_TCG_LOGIC_IMM2(evrlwi, tcg_gen_rotli_i32);
6651
6652 /* SPE arithmetic */
6653 #if defined(TARGET_PPC64)
6654 #define GEN_SPEOP_ARITH1(name, tcg_op)                                        \
6655 static inline void gen_##name(DisasContext *ctx)                              \
6656 {                                                                             \
6657     if (unlikely(!ctx->spe_enabled)) {                                        \
6658         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6659         return;                                                               \
6660     }                                                                         \
6661     TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
6662     TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
6663     TCGv_i64 t2 = tcg_temp_local_new_i64();                                   \
6664     tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]);                      \
6665     tcg_op(t0, t0);                                                           \
6666     tcg_gen_shri_i64(t2, cpu_gpr[rA(ctx->opcode)], 32);                       \
6667     tcg_gen_trunc_i64_i32(t1, t2);                                            \
6668     tcg_temp_free_i64(t2);                                                    \
6669     tcg_op(t1, t1);                                                           \
6670     tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);                 \
6671     tcg_temp_free_i32(t0);                                                    \
6672     tcg_temp_free_i32(t1);                                                    \
6673 }
6674 #else
6675 #define GEN_SPEOP_ARITH1(name, tcg_op)                                        \
6676 static inline void gen_##name(DisasContext *ctx)                              \
6677 {                                                                             \
6678     if (unlikely(!ctx->spe_enabled)) {                                        \
6679         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6680         return;                                                               \
6681     }                                                                         \
6682     tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);               \
6683     tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);             \
6684 }
6685 #endif
6686
6687 static inline void gen_op_evabs(TCGv_i32 ret, TCGv_i32 arg1)
6688 {
6689     int l1 = gen_new_label();
6690     int l2 = gen_new_label();
6691
6692     tcg_gen_brcondi_i32(TCG_COND_GE, arg1, 0, l1);
6693     tcg_gen_neg_i32(ret, arg1);
6694     tcg_gen_br(l2);
6695     gen_set_label(l1);
6696     tcg_gen_mov_i32(ret, arg1);
6697     gen_set_label(l2);
6698 }
6699 GEN_SPEOP_ARITH1(evabs, gen_op_evabs);
6700 GEN_SPEOP_ARITH1(evneg, tcg_gen_neg_i32);
6701 GEN_SPEOP_ARITH1(evextsb, tcg_gen_ext8s_i32);
6702 GEN_SPEOP_ARITH1(evextsh, tcg_gen_ext16s_i32);
6703 static inline void gen_op_evrndw(TCGv_i32 ret, TCGv_i32 arg1)
6704 {
6705     tcg_gen_addi_i32(ret, arg1, 0x8000);
6706     tcg_gen_ext16u_i32(ret, ret);
6707 }
6708 GEN_SPEOP_ARITH1(evrndw, gen_op_evrndw);
6709 GEN_SPEOP_ARITH1(evcntlsw, gen_helper_cntlsw32);
6710 GEN_SPEOP_ARITH1(evcntlzw, gen_helper_cntlzw32);
6711
6712 #if defined(TARGET_PPC64)
6713 #define GEN_SPEOP_ARITH2(name, tcg_op)                                        \
6714 static inline void gen_##name(DisasContext *ctx)                              \
6715 {                                                                             \
6716     if (unlikely(!ctx->spe_enabled)) {                                        \
6717         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6718         return;                                                               \
6719     }                                                                         \
6720     TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
6721     TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
6722     TCGv_i32 t2 = tcg_temp_local_new_i32();                                   \
6723     TCGv_i64 t3 = tcg_temp_local_new_i64();                                   \
6724     tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]);                      \
6725     tcg_gen_trunc_i64_i32(t2, cpu_gpr[rB(ctx->opcode)]);                      \
6726     tcg_op(t0, t0, t2);                                                       \
6727     tcg_gen_shri_i64(t3, cpu_gpr[rA(ctx->opcode)], 32);                       \
6728     tcg_gen_trunc_i64_i32(t1, t3);                                            \
6729     tcg_gen_shri_i64(t3, cpu_gpr[rB(ctx->opcode)], 32);                       \
6730     tcg_gen_trunc_i64_i32(t2, t3);                                            \
6731     tcg_temp_free_i64(t3);                                                    \
6732     tcg_op(t1, t1, t2);                                                       \
6733     tcg_temp_free_i32(t2);                                                    \
6734     tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);                 \
6735     tcg_temp_free_i32(t0);                                                    \
6736     tcg_temp_free_i32(t1);                                                    \
6737 }
6738 #else
6739 #define GEN_SPEOP_ARITH2(name, tcg_op)                                        \
6740 static inline void gen_##name(DisasContext *ctx)                              \
6741 {                                                                             \
6742     if (unlikely(!ctx->spe_enabled)) {                                        \
6743         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6744         return;                                                               \
6745     }                                                                         \
6746     tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],                \
6747            cpu_gpr[rB(ctx->opcode)]);                                         \
6748     tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],              \
6749            cpu_gprh[rB(ctx->opcode)]);                                        \
6750 }
6751 #endif
6752
6753 static inline void gen_op_evsrwu(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
6754 {
6755     TCGv_i32 t0;
6756     int l1, l2;
6757
6758     l1 = gen_new_label();
6759     l2 = gen_new_label();
6760     t0 = tcg_temp_local_new_i32();
6761     /* No error here: 6 bits are used */
6762     tcg_gen_andi_i32(t0, arg2, 0x3F);
6763     tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1);
6764     tcg_gen_shr_i32(ret, arg1, t0);
6765     tcg_gen_br(l2);
6766     gen_set_label(l1);
6767     tcg_gen_movi_i32(ret, 0);
6768     gen_set_label(l2);
6769     tcg_temp_free_i32(t0);
6770 }
6771 GEN_SPEOP_ARITH2(evsrwu, gen_op_evsrwu);
6772 static inline void gen_op_evsrws(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
6773 {
6774     TCGv_i32 t0;
6775     int l1, l2;
6776
6777     l1 = gen_new_label();
6778     l2 = gen_new_label();
6779     t0 = tcg_temp_local_new_i32();
6780     /* No error here: 6 bits are used */
6781     tcg_gen_andi_i32(t0, arg2, 0x3F);
6782     tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1);
6783     tcg_gen_sar_i32(ret, arg1, t0);
6784     tcg_gen_br(l2);
6785     gen_set_label(l1);
6786     tcg_gen_movi_i32(ret, 0);
6787     gen_set_label(l2);
6788     tcg_temp_free_i32(t0);
6789 }
6790 GEN_SPEOP_ARITH2(evsrws, gen_op_evsrws);
6791 static inline void gen_op_evslw(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
6792 {
6793     TCGv_i32 t0;
6794     int l1, l2;
6795
6796     l1 = gen_new_label();
6797     l2 = gen_new_label();
6798     t0 = tcg_temp_local_new_i32();
6799     /* No error here: 6 bits are used */
6800     tcg_gen_andi_i32(t0, arg2, 0x3F);
6801     tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1);
6802     tcg_gen_shl_i32(ret, arg1, t0);
6803     tcg_gen_br(l2);
6804     gen_set_label(l1);
6805     tcg_gen_movi_i32(ret, 0);
6806     gen_set_label(l2);
6807     tcg_temp_free_i32(t0);
6808 }
6809 GEN_SPEOP_ARITH2(evslw, gen_op_evslw);
6810 static inline void gen_op_evrlw(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
6811 {
6812     TCGv_i32 t0 = tcg_temp_new_i32();
6813     tcg_gen_andi_i32(t0, arg2, 0x1F);
6814     tcg_gen_rotl_i32(ret, arg1, t0);
6815     tcg_temp_free_i32(t0);
6816 }
6817 GEN_SPEOP_ARITH2(evrlw, gen_op_evrlw);
6818 static inline void gen_evmergehi(DisasContext *ctx)
6819 {
6820     if (unlikely(!ctx->spe_enabled)) {
6821         gen_exception(ctx, POWERPC_EXCP_APU);
6822         return;
6823     }
6824 #if defined(TARGET_PPC64)
6825     TCGv t0 = tcg_temp_new();
6826     TCGv t1 = tcg_temp_new();
6827     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 32);
6828     tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], 0xFFFFFFFF0000000ULL);
6829     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
6830     tcg_temp_free(t0);
6831     tcg_temp_free(t1);
6832 #else
6833     tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
6834     tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
6835 #endif
6836 }
6837 GEN_SPEOP_ARITH2(evaddw, tcg_gen_add_i32);
6838 static inline void gen_op_evsubf(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
6839 {
6840     tcg_gen_sub_i32(ret, arg2, arg1);
6841 }
6842 GEN_SPEOP_ARITH2(evsubfw, gen_op_evsubf);
6843
6844 /* SPE arithmetic immediate */
6845 #if defined(TARGET_PPC64)
6846 #define GEN_SPEOP_ARITH_IMM2(name, tcg_op)                                    \
6847 static inline void gen_##name(DisasContext *ctx)                              \
6848 {                                                                             \
6849     if (unlikely(!ctx->spe_enabled)) {                                        \
6850         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6851         return;                                                               \
6852     }                                                                         \
6853     TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
6854     TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
6855     TCGv_i64 t2 = tcg_temp_local_new_i64();                                   \
6856     tcg_gen_trunc_i64_i32(t0, cpu_gpr[rB(ctx->opcode)]);                      \
6857     tcg_op(t0, t0, rA(ctx->opcode));                                          \
6858     tcg_gen_shri_i64(t2, cpu_gpr[rB(ctx->opcode)], 32);                       \
6859     tcg_gen_trunc_i64_i32(t1, t2);                                            \
6860     tcg_temp_free_i64(t2);                                                    \
6861     tcg_op(t1, t1, rA(ctx->opcode));                                          \
6862     tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);                 \
6863     tcg_temp_free_i32(t0);                                                    \
6864     tcg_temp_free_i32(t1);                                                    \
6865 }
6866 #else
6867 #define GEN_SPEOP_ARITH_IMM2(name, tcg_op)                                    \
6868 static inline void gen_##name(DisasContext *ctx)                              \
6869 {                                                                             \
6870     if (unlikely(!ctx->spe_enabled)) {                                        \
6871         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6872         return;                                                               \
6873     }                                                                         \
6874     tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],                \
6875            rA(ctx->opcode));                                                  \
6876     tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)],              \
6877            rA(ctx->opcode));                                                  \
6878 }
6879 #endif
6880 GEN_SPEOP_ARITH_IMM2(evaddiw, tcg_gen_addi_i32);
6881 GEN_SPEOP_ARITH_IMM2(evsubifw, tcg_gen_subi_i32);
6882
6883 /* SPE comparison */
6884 #if defined(TARGET_PPC64)
6885 #define GEN_SPEOP_COMP(name, tcg_cond)                                        \
6886 static inline void gen_##name(DisasContext *ctx)                              \
6887 {                                                                             \
6888     if (unlikely(!ctx->spe_enabled)) {                                        \
6889         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6890         return;                                                               \
6891     }                                                                         \
6892     int l1 = gen_new_label();                                                 \
6893     int l2 = gen_new_label();                                                 \
6894     int l3 = gen_new_label();                                                 \
6895     int l4 = gen_new_label();                                                 \
6896     TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
6897     TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
6898     TCGv_i64 t2 = tcg_temp_local_new_i64();                                   \
6899     tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]);                      \
6900     tcg_gen_trunc_i64_i32(t1, cpu_gpr[rB(ctx->opcode)]);                      \
6901     tcg_gen_brcond_i32(tcg_cond, t0, t1, l1);                                 \
6902     tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)], 0);                          \
6903     tcg_gen_br(l2);                                                           \
6904     gen_set_label(l1);                                                        \
6905     tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)],                              \
6906                      CRF_CL | CRF_CH_OR_CL | CRF_CH_AND_CL);                  \
6907     gen_set_label(l2);                                                        \
6908     tcg_gen_shri_i64(t2, cpu_gpr[rA(ctx->opcode)], 32);                       \
6909     tcg_gen_trunc_i64_i32(t0, t2);                                            \
6910     tcg_gen_shri_i64(t2, cpu_gpr[rB(ctx->opcode)], 32);                       \
6911     tcg_gen_trunc_i64_i32(t1, t2);                                            \
6912     tcg_temp_free_i64(t2);                                                    \
6913     tcg_gen_brcond_i32(tcg_cond, t0, t1, l3);                                 \
6914     tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)],  \
6915                      ~(CRF_CH | CRF_CH_AND_CL));                              \
6916     tcg_gen_br(l4);                                                           \
6917     gen_set_label(l3);                                                        \
6918     tcg_gen_ori_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)],   \
6919                     CRF_CH | CRF_CH_OR_CL);                                   \
6920     gen_set_label(l4);                                                        \
6921     tcg_temp_free_i32(t0);                                                    \
6922     tcg_temp_free_i32(t1);                                                    \
6923 }
6924 #else
6925 #define GEN_SPEOP_COMP(name, tcg_cond)                                        \
6926 static inline void gen_##name(DisasContext *ctx)                              \
6927 {                                                                             \
6928     if (unlikely(!ctx->spe_enabled)) {                                        \
6929         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6930         return;                                                               \
6931     }                                                                         \
6932     int l1 = gen_new_label();                                                 \
6933     int l2 = gen_new_label();                                                 \
6934     int l3 = gen_new_label();                                                 \
6935     int l4 = gen_new_label();                                                 \
6936                                                                               \
6937     tcg_gen_brcond_i32(tcg_cond, cpu_gpr[rA(ctx->opcode)],                    \
6938                        cpu_gpr[rB(ctx->opcode)], l1);                         \
6939     tcg_gen_movi_tl(cpu_crf[crfD(ctx->opcode)], 0);                           \
6940     tcg_gen_br(l2);                                                           \
6941     gen_set_label(l1);                                                        \
6942     tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)],                              \
6943                      CRF_CL | CRF_CH_OR_CL | CRF_CH_AND_CL);                  \
6944     gen_set_label(l2);                                                        \
6945     tcg_gen_brcond_i32(tcg_cond, cpu_gprh[rA(ctx->opcode)],                   \
6946                        cpu_gprh[rB(ctx->opcode)], l3);                        \
6947     tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)],  \
6948                      ~(CRF_CH | CRF_CH_AND_CL));                              \
6949     tcg_gen_br(l4);                                                           \
6950     gen_set_label(l3);                                                        \
6951     tcg_gen_ori_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)],   \
6952                     CRF_CH | CRF_CH_OR_CL);                                   \
6953     gen_set_label(l4);                                                        \
6954 }
6955 #endif
6956 GEN_SPEOP_COMP(evcmpgtu, TCG_COND_GTU);
6957 GEN_SPEOP_COMP(evcmpgts, TCG_COND_GT);
6958 GEN_SPEOP_COMP(evcmpltu, TCG_COND_LTU);
6959 GEN_SPEOP_COMP(evcmplts, TCG_COND_LT);
6960 GEN_SPEOP_COMP(evcmpeq, TCG_COND_EQ);
6961
6962 /* SPE misc */
6963 static inline void gen_brinc(DisasContext *ctx)
6964 {
6965     /* Note: brinc is usable even if SPE is disabled */
6966     gen_helper_brinc(cpu_gpr[rD(ctx->opcode)],
6967                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
6968 }
6969 static inline void gen_evmergelo(DisasContext *ctx)
6970 {
6971     if (unlikely(!ctx->spe_enabled)) {
6972         gen_exception(ctx, POWERPC_EXCP_APU);
6973         return;
6974     }
6975 #if defined(TARGET_PPC64)
6976     TCGv t0 = tcg_temp_new();
6977     TCGv t1 = tcg_temp_new();
6978     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x00000000FFFFFFFFLL);
6979     tcg_gen_shli_tl(t1, cpu_gpr[rA(ctx->opcode)], 32);
6980     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
6981     tcg_temp_free(t0);
6982     tcg_temp_free(t1);
6983 #else
6984     tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
6985     tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
6986 #endif
6987 }
6988 static inline void gen_evmergehilo(DisasContext *ctx)
6989 {
6990     if (unlikely(!ctx->spe_enabled)) {
6991         gen_exception(ctx, POWERPC_EXCP_APU);
6992         return;
6993     }
6994 #if defined(TARGET_PPC64)
6995     TCGv t0 = tcg_temp_new();
6996     TCGv t1 = tcg_temp_new();
6997     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x00000000FFFFFFFFLL);
6998     tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], 0xFFFFFFFF0000000ULL);
6999     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
7000     tcg_temp_free(t0);
7001     tcg_temp_free(t1);
7002 #else
7003     tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
7004     tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
7005 #endif
7006 }
7007 static inline void gen_evmergelohi(DisasContext *ctx)
7008 {
7009     if (unlikely(!ctx->spe_enabled)) {
7010         gen_exception(ctx, POWERPC_EXCP_APU);
7011         return;
7012     }
7013 #if defined(TARGET_PPC64)
7014     TCGv t0 = tcg_temp_new();
7015     TCGv t1 = tcg_temp_new();
7016     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 32);
7017     tcg_gen_shli_tl(t1, cpu_gpr[rA(ctx->opcode)], 32);
7018     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
7019     tcg_temp_free(t0);
7020     tcg_temp_free(t1);
7021 #else
7022     if (rD(ctx->opcode) == rA(ctx->opcode)) {
7023         TCGv_i32 tmp = tcg_temp_new_i32();
7024         tcg_gen_mov_i32(tmp, cpu_gpr[rA(ctx->opcode)]);
7025         tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
7026         tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], tmp);
7027         tcg_temp_free_i32(tmp);
7028     } else {
7029         tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
7030         tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
7031     }
7032 #endif
7033 }
7034 static inline void gen_evsplati(DisasContext *ctx)
7035 {
7036     uint64_t imm = ((int32_t)(rA(ctx->opcode) << 27)) >> 27;
7037
7038 #if defined(TARGET_PPC64)
7039     tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], (imm << 32) | imm);
7040 #else
7041     tcg_gen_movi_i32(cpu_gpr[rD(ctx->opcode)], imm);
7042     tcg_gen_movi_i32(cpu_gprh[rD(ctx->opcode)], imm);
7043 #endif
7044 }
7045 static inline void gen_evsplatfi(DisasContext *ctx)
7046 {
7047     uint64_t imm = rA(ctx->opcode) << 27;
7048
7049 #if defined(TARGET_PPC64)
7050     tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], (imm << 32) | imm);
7051 #else
7052     tcg_gen_movi_i32(cpu_gpr[rD(ctx->opcode)], imm);
7053     tcg_gen_movi_i32(cpu_gprh[rD(ctx->opcode)], imm);
7054 #endif
7055 }
7056
7057 static inline void gen_evsel(DisasContext *ctx)
7058 {
7059     int l1 = gen_new_label();
7060     int l2 = gen_new_label();
7061     int l3 = gen_new_label();
7062     int l4 = gen_new_label();
7063     TCGv_i32 t0 = tcg_temp_local_new_i32();
7064 #if defined(TARGET_PPC64)
7065     TCGv t1 = tcg_temp_local_new();
7066     TCGv t2 = tcg_temp_local_new();
7067 #endif
7068     tcg_gen_andi_i32(t0, cpu_crf[ctx->opcode & 0x07], 1 << 3);
7069     tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
7070 #if defined(TARGET_PPC64)
7071     tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], 0xFFFFFFFF00000000ULL);
7072 #else
7073     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
7074 #endif
7075     tcg_gen_br(l2);
7076     gen_set_label(l1);
7077 #if defined(TARGET_PPC64)
7078     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0xFFFFFFFF00000000ULL);
7079 #else
7080     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
7081 #endif
7082     gen_set_label(l2);
7083     tcg_gen_andi_i32(t0, cpu_crf[ctx->opcode & 0x07], 1 << 2);
7084     tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l3);
7085 #if defined(TARGET_PPC64)
7086     tcg_gen_andi_tl(t2, cpu_gpr[rA(ctx->opcode)], 0x00000000FFFFFFFFULL);
7087 #else
7088     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
7089 #endif
7090     tcg_gen_br(l4);
7091     gen_set_label(l3);
7092 #if defined(TARGET_PPC64)
7093     tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x00000000FFFFFFFFULL);
7094 #else
7095     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
7096 #endif
7097     gen_set_label(l4);
7098     tcg_temp_free_i32(t0);
7099 #if defined(TARGET_PPC64)
7100     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t1, t2);
7101     tcg_temp_free(t1);
7102     tcg_temp_free(t2);
7103 #endif
7104 }
7105
7106 static void gen_evsel0(DisasContext *ctx)
7107 {
7108     gen_evsel(ctx);
7109 }
7110
7111 static void gen_evsel1(DisasContext *ctx)
7112 {
7113     gen_evsel(ctx);
7114 }
7115
7116 static void gen_evsel2(DisasContext *ctx)
7117 {
7118     gen_evsel(ctx);
7119 }
7120
7121 static void gen_evsel3(DisasContext *ctx)
7122 {
7123     gen_evsel(ctx);
7124 }
7125
7126 /* Multiply */
7127
7128 static inline void gen_evmwumi(DisasContext *ctx)
7129 {
7130     TCGv_i64 t0, t1;
7131
7132     if (unlikely(!ctx->spe_enabled)) {
7133         gen_exception(ctx, POWERPC_EXCP_APU);
7134         return;
7135     }
7136
7137     t0 = tcg_temp_new_i64();
7138     t1 = tcg_temp_new_i64();
7139
7140     /* t0 := rA; t1 := rB */
7141 #if defined(TARGET_PPC64)
7142     tcg_gen_ext32u_tl(t0, cpu_gpr[rA(ctx->opcode)]);
7143     tcg_gen_ext32u_tl(t1, cpu_gpr[rB(ctx->opcode)]);
7144 #else
7145     tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
7146     tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
7147 #endif
7148
7149     tcg_gen_mul_i64(t0, t0, t1);  /* t0 := rA * rB */
7150
7151     gen_store_gpr64(rD(ctx->opcode), t0); /* rD := t0 */
7152
7153     tcg_temp_free_i64(t0);
7154     tcg_temp_free_i64(t1);
7155 }
7156
7157 static inline void gen_evmwumia(DisasContext *ctx)
7158 {
7159     TCGv_i64 tmp;
7160
7161     if (unlikely(!ctx->spe_enabled)) {
7162         gen_exception(ctx, POWERPC_EXCP_APU);
7163         return;
7164     }
7165
7166     gen_evmwumi(ctx);            /* rD := rA * rB */
7167
7168     tmp = tcg_temp_new_i64();
7169
7170     /* acc := rD */
7171     gen_load_gpr64(tmp, rD(ctx->opcode));
7172     tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUState, spe_acc));
7173     tcg_temp_free_i64(tmp);
7174 }
7175
7176 static inline void gen_evmwumiaa(DisasContext *ctx)
7177 {
7178     TCGv_i64 acc;
7179     TCGv_i64 tmp;
7180
7181     if (unlikely(!ctx->spe_enabled)) {
7182         gen_exception(ctx, POWERPC_EXCP_APU);
7183         return;
7184     }
7185
7186     gen_evmwumi(ctx);           /* rD := rA * rB */
7187
7188     acc = tcg_temp_new_i64();
7189     tmp = tcg_temp_new_i64();
7190
7191     /* tmp := rD */
7192     gen_load_gpr64(tmp, rD(ctx->opcode));
7193
7194     /* Load acc */
7195     tcg_gen_ld_i64(acc, cpu_env, offsetof(CPUState, spe_acc));
7196
7197     /* acc := tmp + acc */
7198     tcg_gen_add_i64(acc, acc, tmp);
7199
7200     /* Store acc */
7201     tcg_gen_st_i64(acc, cpu_env, offsetof(CPUState, spe_acc));
7202
7203     /* rD := acc */
7204     gen_store_gpr64(rD(ctx->opcode), acc);
7205
7206     tcg_temp_free_i64(acc);
7207     tcg_temp_free_i64(tmp);
7208 }
7209
7210 static inline void gen_evmwsmi(DisasContext *ctx)
7211 {
7212     TCGv_i64 t0, t1;
7213
7214     if (unlikely(!ctx->spe_enabled)) {
7215         gen_exception(ctx, POWERPC_EXCP_APU);
7216         return;
7217     }
7218
7219     t0 = tcg_temp_new_i64();
7220     t1 = tcg_temp_new_i64();
7221
7222     /* t0 := rA; t1 := rB */
7223 #if defined(TARGET_PPC64)
7224     tcg_gen_ext32s_tl(t0, cpu_gpr[rA(ctx->opcode)]);
7225     tcg_gen_ext32s_tl(t1, cpu_gpr[rB(ctx->opcode)]);
7226 #else
7227     tcg_gen_ext_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
7228     tcg_gen_ext_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
7229 #endif
7230
7231     tcg_gen_mul_i64(t0, t0, t1);  /* t0 := rA * rB */
7232
7233     gen_store_gpr64(rD(ctx->opcode), t0); /* rD := t0 */
7234
7235     tcg_temp_free_i64(t0);
7236     tcg_temp_free_i64(t1);
7237 }
7238
7239 static inline void gen_evmwsmia(DisasContext *ctx)
7240 {
7241     TCGv_i64 tmp;
7242
7243     gen_evmwsmi(ctx);            /* rD := rA * rB */
7244
7245     tmp = tcg_temp_new_i64();
7246
7247     /* acc := rD */
7248     gen_load_gpr64(tmp, rD(ctx->opcode));
7249     tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUState, spe_acc));
7250
7251     tcg_temp_free_i64(tmp);
7252 }
7253
7254 static inline void gen_evmwsmiaa(DisasContext *ctx)
7255 {
7256     TCGv_i64 acc = tcg_temp_new_i64();
7257     TCGv_i64 tmp = tcg_temp_new_i64();
7258
7259     gen_evmwsmi(ctx);           /* rD := rA * rB */
7260
7261     acc = tcg_temp_new_i64();
7262     tmp = tcg_temp_new_i64();
7263
7264     /* tmp := rD */
7265     gen_load_gpr64(tmp, rD(ctx->opcode));
7266
7267     /* Load acc */
7268     tcg_gen_ld_i64(acc, cpu_env, offsetof(CPUState, spe_acc));
7269
7270     /* acc := tmp + acc */
7271     tcg_gen_add_i64(acc, acc, tmp);
7272
7273     /* Store acc */
7274     tcg_gen_st_i64(acc, cpu_env, offsetof(CPUState, spe_acc));
7275
7276     /* rD := acc */
7277     gen_store_gpr64(rD(ctx->opcode), acc);
7278
7279     tcg_temp_free_i64(acc);
7280     tcg_temp_free_i64(tmp);
7281 }
7282
7283 GEN_SPE(evaddw,         speundef,      0x00, 0x08, 0x00000000, PPC_SPE); ////
7284 GEN_SPE(evaddiw,        speundef,      0x01, 0x08, 0x00000000, PPC_SPE);
7285 GEN_SPE(evsubfw,        speundef,      0x02, 0x08, 0x00000000, PPC_SPE); ////
7286 GEN_SPE(evsubifw,       speundef,      0x03, 0x08, 0x00000000, PPC_SPE);
7287 GEN_SPE(evabs,          evneg,         0x04, 0x08, 0x0000F800, PPC_SPE); ////
7288 GEN_SPE(evextsb,        evextsh,       0x05, 0x08, 0x0000F800, PPC_SPE); ////
7289 GEN_SPE(evrndw,         evcntlzw,      0x06, 0x08, 0x0000F800, PPC_SPE); ////
7290 GEN_SPE(evcntlsw,       brinc,         0x07, 0x08, 0x00000000, PPC_SPE); //
7291 GEN_SPE(evmra,          speundef,      0x02, 0x13, 0x0000F800, PPC_SPE);
7292 GEN_SPE(speundef,       evand,         0x08, 0x08, 0x00000000, PPC_SPE); ////
7293 GEN_SPE(evandc,         speundef,      0x09, 0x08, 0x00000000, PPC_SPE); ////
7294 GEN_SPE(evxor,          evor,          0x0B, 0x08, 0x00000000, PPC_SPE); ////
7295 GEN_SPE(evnor,          eveqv,         0x0C, 0x08, 0x00000000, PPC_SPE); ////
7296 GEN_SPE(evmwumi,        evmwsmi,       0x0C, 0x11, 0x00000000, PPC_SPE);
7297 GEN_SPE(evmwumia,       evmwsmia,      0x1C, 0x11, 0x00000000, PPC_SPE);
7298 GEN_SPE(evmwumiaa,      evmwsmiaa,     0x0C, 0x15, 0x00000000, PPC_SPE);
7299 GEN_SPE(speundef,       evorc,         0x0D, 0x08, 0x00000000, PPC_SPE); ////
7300 GEN_SPE(evnand,         speundef,      0x0F, 0x08, 0x00000000, PPC_SPE); ////
7301 GEN_SPE(evsrwu,         evsrws,        0x10, 0x08, 0x00000000, PPC_SPE); ////
7302 GEN_SPE(evsrwiu,        evsrwis,       0x11, 0x08, 0x00000000, PPC_SPE);
7303 GEN_SPE(evslw,          speundef,      0x12, 0x08, 0x00000000, PPC_SPE); ////
7304 GEN_SPE(evslwi,         speundef,      0x13, 0x08, 0x00000000, PPC_SPE);
7305 GEN_SPE(evrlw,          evsplati,      0x14, 0x08, 0x00000000, PPC_SPE); //
7306 GEN_SPE(evrlwi,         evsplatfi,     0x15, 0x08, 0x00000000, PPC_SPE);
7307 GEN_SPE(evmergehi,      evmergelo,     0x16, 0x08, 0x00000000, PPC_SPE); ////
7308 GEN_SPE(evmergehilo,    evmergelohi,   0x17, 0x08, 0x00000000, PPC_SPE); ////
7309 GEN_SPE(evcmpgtu,       evcmpgts,      0x18, 0x08, 0x00600000, PPC_SPE); ////
7310 GEN_SPE(evcmpltu,       evcmplts,      0x19, 0x08, 0x00600000, PPC_SPE); ////
7311 GEN_SPE(evcmpeq,        speundef,      0x1A, 0x08, 0x00600000, PPC_SPE); ////
7312
7313 /* SPE load and stores */
7314 static inline void gen_addr_spe_imm_index(DisasContext *ctx, TCGv EA, int sh)
7315 {
7316     target_ulong uimm = rB(ctx->opcode);
7317
7318     if (rA(ctx->opcode) == 0) {
7319         tcg_gen_movi_tl(EA, uimm << sh);
7320     } else {
7321         tcg_gen_addi_tl(EA, cpu_gpr[rA(ctx->opcode)], uimm << sh);
7322 #if defined(TARGET_PPC64)
7323         if (!ctx->sf_mode) {
7324             tcg_gen_ext32u_tl(EA, EA);
7325         }
7326 #endif
7327     }
7328 }
7329
7330 static inline void gen_op_evldd(DisasContext *ctx, TCGv addr)
7331 {
7332 #if defined(TARGET_PPC64)
7333     gen_qemu_ld64(ctx, cpu_gpr[rD(ctx->opcode)], addr);
7334 #else
7335     TCGv_i64 t0 = tcg_temp_new_i64();
7336     gen_qemu_ld64(ctx, t0, addr);
7337     tcg_gen_trunc_i64_i32(cpu_gpr[rD(ctx->opcode)], t0);
7338     tcg_gen_shri_i64(t0, t0, 32);
7339     tcg_gen_trunc_i64_i32(cpu_gprh[rD(ctx->opcode)], t0);
7340     tcg_temp_free_i64(t0);
7341 #endif
7342 }
7343
7344 static inline void gen_op_evldw(DisasContext *ctx, TCGv addr)
7345 {
7346 #if defined(TARGET_PPC64)
7347     TCGv t0 = tcg_temp_new();
7348     gen_qemu_ld32u(ctx, t0, addr);
7349     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32);
7350     gen_addr_add(ctx, addr, addr, 4);
7351     gen_qemu_ld32u(ctx, t0, addr);
7352     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7353     tcg_temp_free(t0);
7354 #else
7355     gen_qemu_ld32u(ctx, cpu_gprh[rD(ctx->opcode)], addr);
7356     gen_addr_add(ctx, addr, addr, 4);
7357     gen_qemu_ld32u(ctx, cpu_gpr[rD(ctx->opcode)], addr);
7358 #endif
7359 }
7360
7361 static inline void gen_op_evldh(DisasContext *ctx, TCGv addr)
7362 {
7363     TCGv t0 = tcg_temp_new();
7364 #if defined(TARGET_PPC64)
7365     gen_qemu_ld16u(ctx, t0, addr);
7366     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48);
7367     gen_addr_add(ctx, addr, addr, 2);
7368     gen_qemu_ld16u(ctx, t0, addr);
7369     tcg_gen_shli_tl(t0, t0, 32);
7370     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7371     gen_addr_add(ctx, addr, addr, 2);
7372     gen_qemu_ld16u(ctx, t0, addr);
7373     tcg_gen_shli_tl(t0, t0, 16);
7374     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7375     gen_addr_add(ctx, addr, addr, 2);
7376     gen_qemu_ld16u(ctx, t0, addr);
7377     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7378 #else
7379     gen_qemu_ld16u(ctx, t0, addr);
7380     tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
7381     gen_addr_add(ctx, addr, addr, 2);
7382     gen_qemu_ld16u(ctx, t0, addr);
7383     tcg_gen_or_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0);
7384     gen_addr_add(ctx, addr, addr, 2);
7385     gen_qemu_ld16u(ctx, t0, addr);
7386     tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
7387     gen_addr_add(ctx, addr, addr, 2);
7388     gen_qemu_ld16u(ctx, t0, addr);
7389     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7390 #endif
7391     tcg_temp_free(t0);
7392 }
7393
7394 static inline void gen_op_evlhhesplat(DisasContext *ctx, TCGv addr)
7395 {
7396     TCGv t0 = tcg_temp_new();
7397     gen_qemu_ld16u(ctx, t0, addr);
7398 #if defined(TARGET_PPC64)
7399     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48);
7400     tcg_gen_shli_tl(t0, t0, 16);
7401     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7402 #else
7403     tcg_gen_shli_tl(t0, t0, 16);
7404     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
7405     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
7406 #endif
7407     tcg_temp_free(t0);
7408 }
7409
7410 static inline void gen_op_evlhhousplat(DisasContext *ctx, TCGv addr)
7411 {
7412     TCGv t0 = tcg_temp_new();
7413     gen_qemu_ld16u(ctx, t0, addr);
7414 #if defined(TARGET_PPC64)
7415     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32);
7416     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7417 #else
7418     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
7419     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
7420 #endif
7421     tcg_temp_free(t0);
7422 }
7423
7424 static inline void gen_op_evlhhossplat(DisasContext *ctx, TCGv addr)
7425 {
7426     TCGv t0 = tcg_temp_new();
7427     gen_qemu_ld16s(ctx, t0, addr);
7428 #if defined(TARGET_PPC64)
7429     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32);
7430     tcg_gen_ext32u_tl(t0, t0);
7431     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7432 #else
7433     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
7434     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
7435 #endif
7436     tcg_temp_free(t0);
7437 }
7438
7439 static inline void gen_op_evlwhe(DisasContext *ctx, TCGv addr)
7440 {
7441     TCGv t0 = tcg_temp_new();
7442 #if defined(TARGET_PPC64)
7443     gen_qemu_ld16u(ctx, t0, addr);
7444     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48);
7445     gen_addr_add(ctx, addr, addr, 2);
7446     gen_qemu_ld16u(ctx, t0, addr);
7447     tcg_gen_shli_tl(t0, t0, 16);
7448     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7449 #else
7450     gen_qemu_ld16u(ctx, t0, addr);
7451     tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
7452     gen_addr_add(ctx, addr, addr, 2);
7453     gen_qemu_ld16u(ctx, t0, addr);
7454     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 16);
7455 #endif
7456     tcg_temp_free(t0);
7457 }
7458
7459 static inline void gen_op_evlwhou(DisasContext *ctx, TCGv addr)
7460 {
7461 #if defined(TARGET_PPC64)
7462     TCGv t0 = tcg_temp_new();
7463     gen_qemu_ld16u(ctx, cpu_gpr[rD(ctx->opcode)], addr);
7464     gen_addr_add(ctx, addr, addr, 2);
7465     gen_qemu_ld16u(ctx, t0, addr);
7466     tcg_gen_shli_tl(t0, t0, 32);
7467     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7468     tcg_temp_free(t0);
7469 #else
7470     gen_qemu_ld16u(ctx, cpu_gprh[rD(ctx->opcode)], addr);
7471     gen_addr_add(ctx, addr, addr, 2);
7472     gen_qemu_ld16u(ctx, cpu_gpr[rD(ctx->opcode)], addr);
7473 #endif
7474 }
7475
7476 static inline void gen_op_evlwhos(DisasContext *ctx, TCGv addr)
7477 {
7478 #if defined(TARGET_PPC64)
7479     TCGv t0 = tcg_temp_new();
7480     gen_qemu_ld16s(ctx, t0, addr);
7481     tcg_gen_ext32u_tl(cpu_gpr[rD(ctx->opcode)], t0);
7482     gen_addr_add(ctx, addr, addr, 2);
7483     gen_qemu_ld16s(ctx, t0, addr);
7484     tcg_gen_shli_tl(t0, t0, 32);
7485     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7486     tcg_temp_free(t0);
7487 #else
7488     gen_qemu_ld16s(ctx, cpu_gprh[rD(ctx->opcode)], addr);
7489     gen_addr_add(ctx, addr, addr, 2);
7490     gen_qemu_ld16s(ctx, cpu_gpr[rD(ctx->opcode)], addr);
7491 #endif
7492 }
7493
7494 static inline void gen_op_evlwwsplat(DisasContext *ctx, TCGv addr)
7495 {
7496     TCGv t0 = tcg_temp_new();
7497     gen_qemu_ld32u(ctx, t0, addr);
7498 #if defined(TARGET_PPC64)
7499     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32);
7500     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7501 #else
7502     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
7503     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
7504 #endif
7505     tcg_temp_free(t0);
7506 }
7507
7508 static inline void gen_op_evlwhsplat(DisasContext *ctx, TCGv addr)
7509 {
7510     TCGv t0 = tcg_temp_new();
7511 #if defined(TARGET_PPC64)
7512     gen_qemu_ld16u(ctx, t0, addr);
7513     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48);
7514     tcg_gen_shli_tl(t0, t0, 32);
7515     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7516     gen_addr_add(ctx, addr, addr, 2);
7517     gen_qemu_ld16u(ctx, t0, addr);
7518     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7519     tcg_gen_shli_tl(t0, t0, 16);
7520     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7521 #else
7522     gen_qemu_ld16u(ctx, t0, addr);
7523     tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
7524     tcg_gen_or_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0);
7525     gen_addr_add(ctx, addr, addr, 2);
7526     gen_qemu_ld16u(ctx, t0, addr);
7527     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 16);
7528     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0);
7529 #endif
7530     tcg_temp_free(t0);
7531 }
7532
7533 static inline void gen_op_evstdd(DisasContext *ctx, TCGv addr)
7534 {
7535 #if defined(TARGET_PPC64)
7536     gen_qemu_st64(ctx, cpu_gpr[rS(ctx->opcode)], addr);
7537 #else
7538     TCGv_i64 t0 = tcg_temp_new_i64();
7539     tcg_gen_concat_i32_i64(t0, cpu_gpr[rS(ctx->opcode)], cpu_gprh[rS(ctx->opcode)]);
7540     gen_qemu_st64(ctx, t0, addr);
7541     tcg_temp_free_i64(t0);
7542 #endif
7543 }
7544
7545 static inline void gen_op_evstdw(DisasContext *ctx, TCGv addr)
7546 {
7547 #if defined(TARGET_PPC64)
7548     TCGv t0 = tcg_temp_new();
7549     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32);
7550     gen_qemu_st32(ctx, t0, addr);
7551     tcg_temp_free(t0);
7552 #else
7553     gen_qemu_st32(ctx, cpu_gprh[rS(ctx->opcode)], addr);
7554 #endif
7555     gen_addr_add(ctx, addr, addr, 4);
7556     gen_qemu_st32(ctx, cpu_gpr[rS(ctx->opcode)], addr);
7557 }
7558
7559 static inline void gen_op_evstdh(DisasContext *ctx, TCGv addr)
7560 {
7561     TCGv t0 = tcg_temp_new();
7562 #if defined(TARGET_PPC64)
7563     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 48);
7564 #else
7565     tcg_gen_shri_tl(t0, cpu_gprh[rS(ctx->opcode)], 16);
7566 #endif
7567     gen_qemu_st16(ctx, t0, addr);
7568     gen_addr_add(ctx, addr, addr, 2);
7569 #if defined(TARGET_PPC64)
7570     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32);
7571     gen_qemu_st16(ctx, t0, addr);
7572 #else
7573     gen_qemu_st16(ctx, cpu_gprh[rS(ctx->opcode)], addr);
7574 #endif
7575     gen_addr_add(ctx, addr, addr, 2);
7576     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 16);
7577     gen_qemu_st16(ctx, t0, addr);
7578     tcg_temp_free(t0);
7579     gen_addr_add(ctx, addr, addr, 2);
7580     gen_qemu_st16(ctx, cpu_gpr[rS(ctx->opcode)], addr);
7581 }
7582
7583 static inline void gen_op_evstwhe(DisasContext *ctx, TCGv addr)
7584 {
7585     TCGv t0 = tcg_temp_new();
7586 #if defined(TARGET_PPC64)
7587     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 48);
7588 #else
7589     tcg_gen_shri_tl(t0, cpu_gprh[rS(ctx->opcode)], 16);
7590 #endif
7591     gen_qemu_st16(ctx, t0, addr);
7592     gen_addr_add(ctx, addr, addr, 2);
7593     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 16);
7594     gen_qemu_st16(ctx, t0, addr);
7595     tcg_temp_free(t0);
7596 }
7597
7598 static inline void gen_op_evstwho(DisasContext *ctx, TCGv addr)
7599 {
7600 #if defined(TARGET_PPC64)
7601     TCGv t0 = tcg_temp_new();
7602     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32);
7603     gen_qemu_st16(ctx, t0, addr);
7604     tcg_temp_free(t0);
7605 #else
7606     gen_qemu_st16(ctx, cpu_gprh[rS(ctx->opcode)], addr);
7607 #endif
7608     gen_addr_add(ctx, addr, addr, 2);
7609     gen_qemu_st16(ctx, cpu_gpr[rS(ctx->opcode)], addr);
7610 }
7611
7612 static inline void gen_op_evstwwe(DisasContext *ctx, TCGv addr)
7613 {
7614 #if defined(TARGET_PPC64)
7615     TCGv t0 = tcg_temp_new();
7616     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32);
7617     gen_qemu_st32(ctx, t0, addr);
7618     tcg_temp_free(t0);
7619 #else
7620     gen_qemu_st32(ctx, cpu_gprh[rS(ctx->opcode)], addr);
7621 #endif
7622 }
7623
7624 static inline void gen_op_evstwwo(DisasContext *ctx, TCGv addr)
7625 {
7626     gen_qemu_st32(ctx, cpu_gpr[rS(ctx->opcode)], addr);
7627 }
7628
7629 #define GEN_SPEOP_LDST(name, opc2, sh)                                        \
7630 static void glue(gen_, name)(DisasContext *ctx)                                       \
7631 {                                                                             \
7632     TCGv t0;                                                                  \
7633     if (unlikely(!ctx->spe_enabled)) {                                        \
7634         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
7635         return;                                                               \
7636     }                                                                         \
7637     gen_set_access_type(ctx, ACCESS_INT);                                     \
7638     t0 = tcg_temp_new();                                                      \
7639     if (Rc(ctx->opcode)) {                                                    \
7640         gen_addr_spe_imm_index(ctx, t0, sh);                                  \
7641     } else {                                                                  \
7642         gen_addr_reg_index(ctx, t0);                                          \
7643     }                                                                         \
7644     gen_op_##name(ctx, t0);                                                   \
7645     tcg_temp_free(t0);                                                        \
7646 }
7647
7648 GEN_SPEOP_LDST(evldd, 0x00, 3);
7649 GEN_SPEOP_LDST(evldw, 0x01, 3);
7650 GEN_SPEOP_LDST(evldh, 0x02, 3);
7651 GEN_SPEOP_LDST(evlhhesplat, 0x04, 1);
7652 GEN_SPEOP_LDST(evlhhousplat, 0x06, 1);
7653 GEN_SPEOP_LDST(evlhhossplat, 0x07, 1);
7654 GEN_SPEOP_LDST(evlwhe, 0x08, 2);
7655 GEN_SPEOP_LDST(evlwhou, 0x0A, 2);
7656 GEN_SPEOP_LDST(evlwhos, 0x0B, 2);
7657 GEN_SPEOP_LDST(evlwwsplat, 0x0C, 2);
7658 GEN_SPEOP_LDST(evlwhsplat, 0x0E, 2);
7659
7660 GEN_SPEOP_LDST(evstdd, 0x10, 3);
7661 GEN_SPEOP_LDST(evstdw, 0x11, 3);
7662 GEN_SPEOP_LDST(evstdh, 0x12, 3);
7663 GEN_SPEOP_LDST(evstwhe, 0x18, 2);
7664 GEN_SPEOP_LDST(evstwho, 0x1A, 2);
7665 GEN_SPEOP_LDST(evstwwe, 0x1C, 2);
7666 GEN_SPEOP_LDST(evstwwo, 0x1E, 2);
7667
7668 /* Multiply and add - TODO */
7669 #if 0
7670 GEN_SPE(speundef,       evmhessf,      0x01, 0x10, 0x00000000, PPC_SPE);
7671 GEN_SPE(speundef,       evmhossf,      0x03, 0x10, 0x00000000, PPC_SPE);
7672 GEN_SPE(evmheumi,       evmhesmi,      0x04, 0x10, 0x00000000, PPC_SPE);
7673 GEN_SPE(speundef,       evmhesmf,      0x05, 0x10, 0x00000000, PPC_SPE);
7674 GEN_SPE(evmhoumi,       evmhosmi,      0x06, 0x10, 0x00000000, PPC_SPE);
7675 GEN_SPE(speundef,       evmhosmf,      0x07, 0x10, 0x00000000, PPC_SPE);
7676 GEN_SPE(speundef,       evmhessfa,     0x11, 0x10, 0x00000000, PPC_SPE);
7677 GEN_SPE(speundef,       evmhossfa,     0x13, 0x10, 0x00000000, PPC_SPE);
7678 GEN_SPE(evmheumia,      evmhesmia,     0x14, 0x10, 0x00000000, PPC_SPE);
7679 GEN_SPE(speundef,       evmhesmfa,     0x15, 0x10, 0x00000000, PPC_SPE);
7680 GEN_SPE(evmhoumia,      evmhosmia,     0x16, 0x10, 0x00000000, PPC_SPE);
7681 GEN_SPE(speundef,       evmhosmfa,     0x17, 0x10, 0x00000000, PPC_SPE);
7682
7683 GEN_SPE(speundef,       evmwhssf,      0x03, 0x11, 0x00000000, PPC_SPE);
7684 GEN_SPE(evmwlumi,       speundef,      0x04, 0x11, 0x00000000, PPC_SPE);
7685 GEN_SPE(evmwhumi,       evmwhsmi,      0x06, 0x11, 0x00000000, PPC_SPE);
7686 GEN_SPE(speundef,       evmwhsmf,      0x07, 0x11, 0x00000000, PPC_SPE);
7687 GEN_SPE(speundef,       evmwssf,       0x09, 0x11, 0x00000000, PPC_SPE);
7688 GEN_SPE(speundef,       evmwsmf,       0x0D, 0x11, 0x00000000, PPC_SPE);
7689 GEN_SPE(speundef,       evmwhssfa,     0x13, 0x11, 0x00000000, PPC_SPE);
7690 GEN_SPE(evmwlumia,      speundef,      0x14, 0x11, 0x00000000, PPC_SPE);
7691 GEN_SPE(evmwhumia,      evmwhsmia,     0x16, 0x11, 0x00000000, PPC_SPE);
7692 GEN_SPE(speundef,       evmwhsmfa,     0x17, 0x11, 0x00000000, PPC_SPE);
7693 GEN_SPE(speundef,       evmwssfa,      0x19, 0x11, 0x00000000, PPC_SPE);
7694 GEN_SPE(speundef,       evmwsmfa,      0x1D, 0x11, 0x00000000, PPC_SPE);
7695
7696 GEN_SPE(evadduiaaw,     evaddsiaaw,    0x00, 0x13, 0x0000F800, PPC_SPE);
7697 GEN_SPE(evsubfusiaaw,   evsubfssiaaw,  0x01, 0x13, 0x0000F800, PPC_SPE);
7698 GEN_SPE(evaddumiaaw,    evaddsmiaaw,   0x04, 0x13, 0x0000F800, PPC_SPE);
7699 GEN_SPE(evsubfumiaaw,   evsubfsmiaaw,  0x05, 0x13, 0x0000F800, PPC_SPE);
7700 GEN_SPE(evdivws,        evdivwu,       0x06, 0x13, 0x00000000, PPC_SPE);
7701
7702 GEN_SPE(evmheusiaaw,    evmhessiaaw,   0x00, 0x14, 0x00000000, PPC_SPE);
7703 GEN_SPE(speundef,       evmhessfaaw,   0x01, 0x14, 0x00000000, PPC_SPE);
7704 GEN_SPE(evmhousiaaw,    evmhossiaaw,   0x02, 0x14, 0x00000000, PPC_SPE);
7705 GEN_SPE(speundef,       evmhossfaaw,   0x03, 0x14, 0x00000000, PPC_SPE);
7706 GEN_SPE(evmheumiaaw,    evmhesmiaaw,   0x04, 0x14, 0x00000000, PPC_SPE);
7707 GEN_SPE(speundef,       evmhesmfaaw,   0x05, 0x14, 0x00000000, PPC_SPE);
7708 GEN_SPE(evmhoumiaaw,    evmhosmiaaw,   0x06, 0x14, 0x00000000, PPC_SPE);
7709 GEN_SPE(speundef,       evmhosmfaaw,   0x07, 0x14, 0x00000000, PPC_SPE);
7710 GEN_SPE(evmhegumiaa,    evmhegsmiaa,   0x14, 0x14, 0x00000000, PPC_SPE);
7711 GEN_SPE(speundef,       evmhegsmfaa,   0x15, 0x14, 0x00000000, PPC_SPE);
7712 GEN_SPE(evmhogumiaa,    evmhogsmiaa,   0x16, 0x14, 0x00000000, PPC_SPE);
7713 GEN_SPE(speundef,       evmhogsmfaa,   0x17, 0x14, 0x00000000, PPC_SPE);
7714
7715 GEN_SPE(evmwlusiaaw,    evmwlssiaaw,   0x00, 0x15, 0x00000000, PPC_SPE);
7716 GEN_SPE(evmwlumiaaw,    evmwlsmiaaw,   0x04, 0x15, 0x00000000, PPC_SPE);
7717 GEN_SPE(speundef,       evmwssfaa,     0x09, 0x15, 0x00000000, PPC_SPE);
7718 GEN_SPE(speundef,       evmwsmfaa,     0x0D, 0x15, 0x00000000, PPC_SPE);
7719
7720 GEN_SPE(evmheusianw,    evmhessianw,   0x00, 0x16, 0x00000000, PPC_SPE);
7721 GEN_SPE(speundef,       evmhessfanw,   0x01, 0x16, 0x00000000, PPC_SPE);
7722 GEN_SPE(evmhousianw,    evmhossianw,   0x02, 0x16, 0x00000000, PPC_SPE);
7723 GEN_SPE(speundef,       evmhossfanw,   0x03, 0x16, 0x00000000, PPC_SPE);
7724 GEN_SPE(evmheumianw,    evmhesmianw,   0x04, 0x16, 0x00000000, PPC_SPE);
7725 GEN_SPE(speundef,       evmhesmfanw,   0x05, 0x16, 0x00000000, PPC_SPE);
7726 GEN_SPE(evmhoumianw,    evmhosmianw,   0x06, 0x16, 0x00000000, PPC_SPE);
7727 GEN_SPE(speundef,       evmhosmfanw,   0x07, 0x16, 0x00000000, PPC_SPE);
7728 GEN_SPE(evmhegumian,    evmhegsmian,   0x14, 0x16, 0x00000000, PPC_SPE);
7729 GEN_SPE(speundef,       evmhegsmfan,   0x15, 0x16, 0x00000000, PPC_SPE);
7730 GEN_SPE(evmhigumian,    evmhigsmian,   0x16, 0x16, 0x00000000, PPC_SPE);
7731 GEN_SPE(speundef,       evmhogsmfan,   0x17, 0x16, 0x00000000, PPC_SPE);
7732
7733 GEN_SPE(evmwlusianw,    evmwlssianw,   0x00, 0x17, 0x00000000, PPC_SPE);
7734 GEN_SPE(evmwlumianw,    evmwlsmianw,   0x04, 0x17, 0x00000000, PPC_SPE);
7735 GEN_SPE(speundef,       evmwssfan,     0x09, 0x17, 0x00000000, PPC_SPE);
7736 GEN_SPE(evmwumian,      evmwsmian,     0x0C, 0x17, 0x00000000, PPC_SPE);
7737 GEN_SPE(speundef,       evmwsmfan,     0x0D, 0x17, 0x00000000, PPC_SPE);
7738 #endif
7739
7740 /***                      SPE floating-point extension                     ***/
7741 #if defined(TARGET_PPC64)
7742 #define GEN_SPEFPUOP_CONV_32_32(name)                                         \
7743 static inline void gen_##name(DisasContext *ctx)                              \
7744 {                                                                             \
7745     TCGv_i32 t0;                                                              \
7746     TCGv t1;                                                                  \
7747     t0 = tcg_temp_new_i32();                                                  \
7748     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rB(ctx->opcode)]);                       \
7749     gen_helper_##name(t0, t0);                                                \
7750     t1 = tcg_temp_new();                                                      \
7751     tcg_gen_extu_i32_tl(t1, t0);                                              \
7752     tcg_temp_free_i32(t0);                                                    \
7753     tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)],       \
7754                     0xFFFFFFFF00000000ULL);                                   \
7755     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t1);    \
7756     tcg_temp_free(t1);                                                        \
7757 }
7758 #define GEN_SPEFPUOP_CONV_32_64(name)                                         \
7759 static inline void gen_##name(DisasContext *ctx)                              \
7760 {                                                                             \
7761     TCGv_i32 t0;                                                              \
7762     TCGv t1;                                                                  \
7763     t0 = tcg_temp_new_i32();                                                  \
7764     gen_helper_##name(t0, cpu_gpr[rB(ctx->opcode)]);                          \
7765     t1 = tcg_temp_new();                                                      \
7766     tcg_gen_extu_i32_tl(t1, t0);                                              \
7767     tcg_temp_free_i32(t0);                                                    \
7768     tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)],       \
7769                     0xFFFFFFFF00000000ULL);                                   \
7770     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t1);    \
7771     tcg_temp_free(t1);                                                        \
7772 }
7773 #define GEN_SPEFPUOP_CONV_64_32(name)                                         \
7774 static inline void gen_##name(DisasContext *ctx)                              \
7775 {                                                                             \
7776     TCGv_i32 t0 = tcg_temp_new_i32();                                         \
7777     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rB(ctx->opcode)]);                       \
7778     gen_helper_##name(cpu_gpr[rD(ctx->opcode)], t0);                          \
7779     tcg_temp_free_i32(t0);                                                    \
7780 }
7781 #define GEN_SPEFPUOP_CONV_64_64(name)                                         \
7782 static inline void gen_##name(DisasContext *ctx)                              \
7783 {                                                                             \
7784     gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
7785 }
7786 #define GEN_SPEFPUOP_ARITH2_32_32(name)                                       \
7787 static inline void gen_##name(DisasContext *ctx)                              \
7788 {                                                                             \
7789     TCGv_i32 t0, t1;                                                          \
7790     TCGv_i64 t2;                                                              \
7791     if (unlikely(!ctx->spe_enabled)) {                                        \
7792         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
7793         return;                                                               \
7794     }                                                                         \
7795     t0 = tcg_temp_new_i32();                                                  \
7796     t1 = tcg_temp_new_i32();                                                  \
7797     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);                       \
7798     tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);                       \
7799     gen_helper_##name(t0, t0, t1);                                            \
7800     tcg_temp_free_i32(t1);                                                    \
7801     t2 = tcg_temp_new();                                                      \
7802     tcg_gen_extu_i32_tl(t2, t0);                                              \
7803     tcg_temp_free_i32(t0);                                                    \
7804     tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)],       \
7805                     0xFFFFFFFF00000000ULL);                                   \
7806     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t2);    \
7807     tcg_temp_free(t2);                                                        \
7808 }
7809 #define GEN_SPEFPUOP_ARITH2_64_64(name)                                       \
7810 static inline void gen_##name(DisasContext *ctx)                              \
7811 {                                                                             \
7812     if (unlikely(!ctx->spe_enabled)) {                                        \
7813         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
7814         return;                                                               \
7815     }                                                                         \
7816     gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],     \
7817                       cpu_gpr[rB(ctx->opcode)]);                              \
7818 }
7819 #define GEN_SPEFPUOP_COMP_32(name)                                            \
7820 static inline void gen_##name(DisasContext *ctx)                              \
7821 {                                                                             \
7822     TCGv_i32 t0, t1;                                                          \
7823     if (unlikely(!ctx->spe_enabled)) {                                        \
7824         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
7825         return;                                                               \
7826     }                                                                         \
7827     t0 = tcg_temp_new_i32();                                                  \
7828     t1 = tcg_temp_new_i32();                                                  \
7829     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);                       \
7830     tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);                       \
7831     gen_helper_##name(cpu_crf[crfD(ctx->opcode)], t0, t1);                    \
7832     tcg_temp_free_i32(t0);                                                    \
7833     tcg_temp_free_i32(t1);                                                    \
7834 }
7835 #define GEN_SPEFPUOP_COMP_64(name)                                            \
7836 static inline void gen_##name(DisasContext *ctx)                              \
7837 {                                                                             \
7838     if (unlikely(!ctx->spe_enabled)) {                                        \
7839         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
7840         return;                                                               \
7841     }                                                                         \
7842     gen_helper_##name(cpu_crf[crfD(ctx->opcode)],                             \
7843                       cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
7844 }
7845 #else
7846 #define GEN_SPEFPUOP_CONV_32_32(name)                                         \
7847 static inline void gen_##name(DisasContext *ctx)                              \
7848 {                                                                             \
7849     gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
7850 }
7851 #define GEN_SPEFPUOP_CONV_32_64(name)                                         \
7852 static inline void gen_##name(DisasContext *ctx)                              \
7853 {                                                                             \
7854     TCGv_i64 t0 = tcg_temp_new_i64();                                         \
7855     gen_load_gpr64(t0, rB(ctx->opcode));                                      \
7856     gen_helper_##name(cpu_gpr[rD(ctx->opcode)], t0);                          \
7857     tcg_temp_free_i64(t0);                                                    \
7858 }
7859 #define GEN_SPEFPUOP_CONV_64_32(name)                                         \
7860 static inline void gen_##name(DisasContext *ctx)                              \
7861 {                                                                             \
7862     TCGv_i64 t0 = tcg_temp_new_i64();                                         \
7863     gen_helper_##name(t0, cpu_gpr[rB(ctx->opcode)]);                          \
7864     gen_store_gpr64(rD(ctx->opcode), t0);                                     \
7865     tcg_temp_free_i64(t0);                                                    \
7866 }
7867 #define GEN_SPEFPUOP_CONV_64_64(name)                                         \
7868 static inline void gen_##name(DisasContext *ctx)                              \
7869 {                                                                             \
7870     TCGv_i64 t0 = tcg_temp_new_i64();                                         \
7871     gen_load_gpr64(t0, rB(ctx->opcode));                                      \
7872     gen_helper_##name(t0, t0);                                                \
7873     gen_store_gpr64(rD(ctx->opcode), t0);                                     \
7874     tcg_temp_free_i64(t0);                                                    \
7875 }
7876 #define GEN_SPEFPUOP_ARITH2_32_32(name)                                       \
7877 static inline void gen_##name(DisasContext *ctx)                              \
7878 {                                                                             \
7879     if (unlikely(!ctx->spe_enabled)) {                                        \
7880         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
7881         return;                                                               \
7882     }                                                                         \
7883     gen_helper_##name(cpu_gpr[rD(ctx->opcode)],                               \
7884                       cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
7885 }
7886 #define GEN_SPEFPUOP_ARITH2_64_64(name)                                       \
7887 static inline void gen_##name(DisasContext *ctx)                              \
7888 {                                                                             \
7889     TCGv_i64 t0, t1;                                                          \
7890     if (unlikely(!ctx->spe_enabled)) {                                        \
7891         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
7892         return;                                                               \
7893     }                                                                         \
7894     t0 = tcg_temp_new_i64();                                                  \
7895     t1 = tcg_temp_new_i64();                                                  \
7896     gen_load_gpr64(t0, rA(ctx->opcode));                                      \
7897     gen_load_gpr64(t1, rB(ctx->opcode));                                      \
7898     gen_helper_##name(t0, t0, t1);                                            \
7899     gen_store_gpr64(rD(ctx->opcode), t0);                                     \
7900     tcg_temp_free_i64(t0);                                                    \
7901     tcg_temp_free_i64(t1);                                                    \
7902 }
7903 #define GEN_SPEFPUOP_COMP_32(name)                                            \
7904 static inline void gen_##name(DisasContext *ctx)                              \
7905 {                                                                             \
7906     if (unlikely(!ctx->spe_enabled)) {                                        \
7907         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
7908         return;                                                               \
7909     }                                                                         \
7910     gen_helper_##name(cpu_crf[crfD(ctx->opcode)],                             \
7911                       cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
7912 }
7913 #define GEN_SPEFPUOP_COMP_64(name)                                            \
7914 static inline void gen_##name(DisasContext *ctx)                              \
7915 {                                                                             \
7916     TCGv_i64 t0, t1;                                                          \
7917     if (unlikely(!ctx->spe_enabled)) {                                        \
7918         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
7919         return;                                                               \
7920     }                                                                         \
7921     t0 = tcg_temp_new_i64();                                                  \
7922     t1 = tcg_temp_new_i64();                                                  \
7923     gen_load_gpr64(t0, rA(ctx->opcode));                                      \
7924     gen_load_gpr64(t1, rB(ctx->opcode));                                      \
7925     gen_helper_##name(cpu_crf[crfD(ctx->opcode)], t0, t1);                    \
7926     tcg_temp_free_i64(t0);                                                    \
7927     tcg_temp_free_i64(t1);                                                    \
7928 }
7929 #endif
7930
7931 /* Single precision floating-point vectors operations */
7932 /* Arithmetic */
7933 GEN_SPEFPUOP_ARITH2_64_64(evfsadd);
7934 GEN_SPEFPUOP_ARITH2_64_64(evfssub);
7935 GEN_SPEFPUOP_ARITH2_64_64(evfsmul);
7936 GEN_SPEFPUOP_ARITH2_64_64(evfsdiv);
7937 static inline void gen_evfsabs(DisasContext *ctx)
7938 {
7939     if (unlikely(!ctx->spe_enabled)) {
7940         gen_exception(ctx, POWERPC_EXCP_APU);
7941         return;
7942     }
7943 #if defined(TARGET_PPC64)
7944     tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~0x8000000080000000LL);
7945 #else
7946     tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~0x80000000);
7947     tcg_gen_andi_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], ~0x80000000);
7948 #endif
7949 }
7950 static inline void gen_evfsnabs(DisasContext *ctx)
7951 {
7952     if (unlikely(!ctx->spe_enabled)) {
7953         gen_exception(ctx, POWERPC_EXCP_APU);
7954         return;
7955     }
7956 #if defined(TARGET_PPC64)
7957     tcg_gen_ori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000080000000LL);
7958 #else
7959     tcg_gen_ori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
7960     tcg_gen_ori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000);
7961 #endif
7962 }
7963 static inline void gen_evfsneg(DisasContext *ctx)
7964 {
7965     if (unlikely(!ctx->spe_enabled)) {
7966         gen_exception(ctx, POWERPC_EXCP_APU);
7967         return;
7968     }
7969 #if defined(TARGET_PPC64)
7970     tcg_gen_xori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000080000000LL);
7971 #else
7972     tcg_gen_xori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
7973     tcg_gen_xori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000);
7974 #endif
7975 }
7976
7977 /* Conversion */
7978 GEN_SPEFPUOP_CONV_64_64(evfscfui);
7979 GEN_SPEFPUOP_CONV_64_64(evfscfsi);
7980 GEN_SPEFPUOP_CONV_64_64(evfscfuf);
7981 GEN_SPEFPUOP_CONV_64_64(evfscfsf);
7982 GEN_SPEFPUOP_CONV_64_64(evfsctui);
7983 GEN_SPEFPUOP_CONV_64_64(evfsctsi);
7984 GEN_SPEFPUOP_CONV_64_64(evfsctuf);
7985 GEN_SPEFPUOP_CONV_64_64(evfsctsf);
7986 GEN_SPEFPUOP_CONV_64_64(evfsctuiz);
7987 GEN_SPEFPUOP_CONV_64_64(evfsctsiz);
7988
7989 /* Comparison */
7990 GEN_SPEFPUOP_COMP_64(evfscmpgt);
7991 GEN_SPEFPUOP_COMP_64(evfscmplt);
7992 GEN_SPEFPUOP_COMP_64(evfscmpeq);
7993 GEN_SPEFPUOP_COMP_64(evfststgt);
7994 GEN_SPEFPUOP_COMP_64(evfststlt);
7995 GEN_SPEFPUOP_COMP_64(evfststeq);
7996
7997 /* Opcodes definitions */
7998 GEN_SPE(evfsadd,        evfssub,       0x00, 0x0A, 0x00000000, PPC_SPE_SINGLE); //
7999 GEN_SPE(evfsabs,        evfsnabs,      0x02, 0x0A, 0x0000F800, PPC_SPE_SINGLE); //
8000 GEN_SPE(evfsneg,        speundef,      0x03, 0x0A, 0x0000F800, PPC_SPE_SINGLE); //
8001 GEN_SPE(evfsmul,        evfsdiv,       0x04, 0x0A, 0x00000000, PPC_SPE_SINGLE); //
8002 GEN_SPE(evfscmpgt,      evfscmplt,     0x06, 0x0A, 0x00600000, PPC_SPE_SINGLE); //
8003 GEN_SPE(evfscmpeq,      speundef,      0x07, 0x0A, 0x00600000, PPC_SPE_SINGLE); //
8004 GEN_SPE(evfscfui,       evfscfsi,      0x08, 0x0A, 0x00180000, PPC_SPE_SINGLE); //
8005 GEN_SPE(evfscfuf,       evfscfsf,      0x09, 0x0A, 0x00180000, PPC_SPE_SINGLE); //
8006 GEN_SPE(evfsctui,       evfsctsi,      0x0A, 0x0A, 0x00180000, PPC_SPE_SINGLE); //
8007 GEN_SPE(evfsctuf,       evfsctsf,      0x0B, 0x0A, 0x00180000, PPC_SPE_SINGLE); //
8008 GEN_SPE(evfsctuiz,      speundef,      0x0C, 0x0A, 0x00180000, PPC_SPE_SINGLE); //
8009 GEN_SPE(evfsctsiz,      speundef,      0x0D, 0x0A, 0x00180000, PPC_SPE_SINGLE); //
8010 GEN_SPE(evfststgt,      evfststlt,     0x0E, 0x0A, 0x00600000, PPC_SPE_SINGLE); //
8011 GEN_SPE(evfststeq,      speundef,      0x0F, 0x0A, 0x00600000, PPC_SPE_SINGLE); //
8012
8013 /* Single precision floating-point operations */
8014 /* Arithmetic */
8015 GEN_SPEFPUOP_ARITH2_32_32(efsadd);
8016 GEN_SPEFPUOP_ARITH2_32_32(efssub);
8017 GEN_SPEFPUOP_ARITH2_32_32(efsmul);
8018 GEN_SPEFPUOP_ARITH2_32_32(efsdiv);
8019 static inline void gen_efsabs(DisasContext *ctx)
8020 {
8021     if (unlikely(!ctx->spe_enabled)) {
8022         gen_exception(ctx, POWERPC_EXCP_APU);
8023         return;
8024     }
8025     tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], (target_long)~0x80000000LL);
8026 }
8027 static inline void gen_efsnabs(DisasContext *ctx)
8028 {
8029     if (unlikely(!ctx->spe_enabled)) {
8030         gen_exception(ctx, POWERPC_EXCP_APU);
8031         return;
8032     }
8033     tcg_gen_ori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
8034 }
8035 static inline void gen_efsneg(DisasContext *ctx)
8036 {
8037     if (unlikely(!ctx->spe_enabled)) {
8038         gen_exception(ctx, POWERPC_EXCP_APU);
8039         return;
8040     }
8041     tcg_gen_xori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
8042 }
8043
8044 /* Conversion */
8045 GEN_SPEFPUOP_CONV_32_32(efscfui);
8046 GEN_SPEFPUOP_CONV_32_32(efscfsi);
8047 GEN_SPEFPUOP_CONV_32_32(efscfuf);
8048 GEN_SPEFPUOP_CONV_32_32(efscfsf);
8049 GEN_SPEFPUOP_CONV_32_32(efsctui);
8050 GEN_SPEFPUOP_CONV_32_32(efsctsi);
8051 GEN_SPEFPUOP_CONV_32_32(efsctuf);
8052 GEN_SPEFPUOP_CONV_32_32(efsctsf);
8053 GEN_SPEFPUOP_CONV_32_32(efsctuiz);
8054 GEN_SPEFPUOP_CONV_32_32(efsctsiz);
8055 GEN_SPEFPUOP_CONV_32_64(efscfd);
8056
8057 /* Comparison */
8058 GEN_SPEFPUOP_COMP_32(efscmpgt);
8059 GEN_SPEFPUOP_COMP_32(efscmplt);
8060 GEN_SPEFPUOP_COMP_32(efscmpeq);
8061 GEN_SPEFPUOP_COMP_32(efststgt);
8062 GEN_SPEFPUOP_COMP_32(efststlt);
8063 GEN_SPEFPUOP_COMP_32(efststeq);
8064
8065 /* Opcodes definitions */
8066 GEN_SPE(efsadd,         efssub,        0x00, 0x0B, 0x00000000, PPC_SPE_SINGLE); //
8067 GEN_SPE(efsabs,         efsnabs,       0x02, 0x0B, 0x0000F800, PPC_SPE_SINGLE); //
8068 GEN_SPE(efsneg,         speundef,      0x03, 0x0B, 0x0000F800, PPC_SPE_SINGLE); //
8069 GEN_SPE(efsmul,         efsdiv,        0x04, 0x0B, 0x00000000, PPC_SPE_SINGLE); //
8070 GEN_SPE(efscmpgt,       efscmplt,      0x06, 0x0B, 0x00600000, PPC_SPE_SINGLE); //
8071 GEN_SPE(efscmpeq,       efscfd,        0x07, 0x0B, 0x00600000, PPC_SPE_SINGLE); //
8072 GEN_SPE(efscfui,        efscfsi,       0x08, 0x0B, 0x00180000, PPC_SPE_SINGLE); //
8073 GEN_SPE(efscfuf,        efscfsf,       0x09, 0x0B, 0x00180000, PPC_SPE_SINGLE); //
8074 GEN_SPE(efsctui,        efsctsi,       0x0A, 0x0B, 0x00180000, PPC_SPE_SINGLE); //
8075 GEN_SPE(efsctuf,        efsctsf,       0x0B, 0x0B, 0x00180000, PPC_SPE_SINGLE); //
8076 GEN_SPE(efsctuiz,       speundef,      0x0C, 0x0B, 0x00180000, PPC_SPE_SINGLE); //
8077 GEN_SPE(efsctsiz,       speundef,      0x0D, 0x0B, 0x00180000, PPC_SPE_SINGLE); //
8078 GEN_SPE(efststgt,       efststlt,      0x0E, 0x0B, 0x00600000, PPC_SPE_SINGLE); //
8079 GEN_SPE(efststeq,       speundef,      0x0F, 0x0B, 0x00600000, PPC_SPE_SINGLE); //
8080
8081 /* Double precision floating-point operations */
8082 /* Arithmetic */
8083 GEN_SPEFPUOP_ARITH2_64_64(efdadd);
8084 GEN_SPEFPUOP_ARITH2_64_64(efdsub);
8085 GEN_SPEFPUOP_ARITH2_64_64(efdmul);
8086 GEN_SPEFPUOP_ARITH2_64_64(efddiv);
8087 static inline void gen_efdabs(DisasContext *ctx)
8088 {
8089     if (unlikely(!ctx->spe_enabled)) {
8090         gen_exception(ctx, POWERPC_EXCP_APU);
8091         return;
8092     }
8093 #if defined(TARGET_PPC64)
8094     tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~0x8000000000000000LL);
8095 #else
8096     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
8097     tcg_gen_andi_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], ~0x80000000);
8098 #endif
8099 }
8100 static inline void gen_efdnabs(DisasContext *ctx)
8101 {
8102     if (unlikely(!ctx->spe_enabled)) {
8103         gen_exception(ctx, POWERPC_EXCP_APU);
8104         return;
8105     }
8106 #if defined(TARGET_PPC64)
8107     tcg_gen_ori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000000000000LL);
8108 #else
8109     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
8110     tcg_gen_ori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000);
8111 #endif
8112 }
8113 static inline void gen_efdneg(DisasContext *ctx)
8114 {
8115     if (unlikely(!ctx->spe_enabled)) {
8116         gen_exception(ctx, POWERPC_EXCP_APU);
8117         return;
8118     }
8119 #if defined(TARGET_PPC64)
8120     tcg_gen_xori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000000000000LL);
8121 #else
8122     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
8123     tcg_gen_xori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000);
8124 #endif
8125 }
8126
8127 /* Conversion */
8128 GEN_SPEFPUOP_CONV_64_32(efdcfui);
8129 GEN_SPEFPUOP_CONV_64_32(efdcfsi);
8130 GEN_SPEFPUOP_CONV_64_32(efdcfuf);
8131 GEN_SPEFPUOP_CONV_64_32(efdcfsf);
8132 GEN_SPEFPUOP_CONV_32_64(efdctui);
8133 GEN_SPEFPUOP_CONV_32_64(efdctsi);
8134 GEN_SPEFPUOP_CONV_32_64(efdctuf);
8135 GEN_SPEFPUOP_CONV_32_64(efdctsf);
8136 GEN_SPEFPUOP_CONV_32_64(efdctuiz);
8137 GEN_SPEFPUOP_CONV_32_64(efdctsiz);
8138 GEN_SPEFPUOP_CONV_64_32(efdcfs);
8139 GEN_SPEFPUOP_CONV_64_64(efdcfuid);
8140 GEN_SPEFPUOP_CONV_64_64(efdcfsid);
8141 GEN_SPEFPUOP_CONV_64_64(efdctuidz);
8142 GEN_SPEFPUOP_CONV_64_64(efdctsidz);
8143
8144 /* Comparison */
8145 GEN_SPEFPUOP_COMP_64(efdcmpgt);
8146 GEN_SPEFPUOP_COMP_64(efdcmplt);
8147 GEN_SPEFPUOP_COMP_64(efdcmpeq);
8148 GEN_SPEFPUOP_COMP_64(efdtstgt);
8149 GEN_SPEFPUOP_COMP_64(efdtstlt);
8150 GEN_SPEFPUOP_COMP_64(efdtsteq);
8151
8152 /* Opcodes definitions */
8153 GEN_SPE(efdadd,         efdsub,        0x10, 0x0B, 0x00000000, PPC_SPE_DOUBLE); //
8154 GEN_SPE(efdcfuid,       efdcfsid,      0x11, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
8155 GEN_SPE(efdabs,         efdnabs,       0x12, 0x0B, 0x0000F800, PPC_SPE_DOUBLE); //
8156 GEN_SPE(efdneg,         speundef,      0x13, 0x0B, 0x0000F800, PPC_SPE_DOUBLE); //
8157 GEN_SPE(efdmul,         efddiv,        0x14, 0x0B, 0x00000000, PPC_SPE_DOUBLE); //
8158 GEN_SPE(efdctuidz,      efdctsidz,     0x15, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
8159 GEN_SPE(efdcmpgt,       efdcmplt,      0x16, 0x0B, 0x00600000, PPC_SPE_DOUBLE); //
8160 GEN_SPE(efdcmpeq,       efdcfs,        0x17, 0x0B, 0x00600000, PPC_SPE_DOUBLE); //
8161 GEN_SPE(efdcfui,        efdcfsi,       0x18, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
8162 GEN_SPE(efdcfuf,        efdcfsf,       0x19, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
8163 GEN_SPE(efdctui,        efdctsi,       0x1A, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
8164 GEN_SPE(efdctuf,        efdctsf,       0x1B, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
8165 GEN_SPE(efdctuiz,       speundef,      0x1C, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
8166 GEN_SPE(efdctsiz,       speundef,      0x1D, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
8167 GEN_SPE(efdtstgt,       efdtstlt,      0x1E, 0x0B, 0x00600000, PPC_SPE_DOUBLE); //
8168 GEN_SPE(efdtsteq,       speundef,      0x1F, 0x0B, 0x00600000, PPC_SPE_DOUBLE); //
8169
8170 static opcode_t opcodes[] = {
8171 GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE),
8172 GEN_HANDLER(cmp, 0x1F, 0x00, 0x00, 0x00400000, PPC_INTEGER),
8173 GEN_HANDLER(cmpi, 0x0B, 0xFF, 0xFF, 0x00400000, PPC_INTEGER),
8174 GEN_HANDLER(cmpl, 0x1F, 0x00, 0x01, 0x00400000, PPC_INTEGER),
8175 GEN_HANDLER(cmpli, 0x0A, 0xFF, 0xFF, 0x00400000, PPC_INTEGER),
8176 GEN_HANDLER(isel, 0x1F, 0x0F, 0xFF, 0x00000001, PPC_ISEL),
8177 GEN_HANDLER(addi, 0x0E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8178 GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8179 GEN_HANDLER2(addic_, "addic.", 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8180 GEN_HANDLER(addis, 0x0F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8181 GEN_HANDLER(mulhw, 0x1F, 0x0B, 0x02, 0x00000400, PPC_INTEGER),
8182 GEN_HANDLER(mulhwu, 0x1F, 0x0B, 0x00, 0x00000400, PPC_INTEGER),
8183 GEN_HANDLER(mullw, 0x1F, 0x0B, 0x07, 0x00000000, PPC_INTEGER),
8184 GEN_HANDLER(mullwo, 0x1F, 0x0B, 0x17, 0x00000000, PPC_INTEGER),
8185 GEN_HANDLER(mulli, 0x07, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8186 #if defined(TARGET_PPC64)
8187 GEN_HANDLER(mulld, 0x1F, 0x09, 0x07, 0x00000000, PPC_64B),
8188 #endif
8189 GEN_HANDLER(neg, 0x1F, 0x08, 0x03, 0x0000F800, PPC_INTEGER),
8190 GEN_HANDLER(nego, 0x1F, 0x08, 0x13, 0x0000F800, PPC_INTEGER),
8191 GEN_HANDLER(subfic, 0x08, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8192 GEN_HANDLER2(andi_, "andi.", 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8193 GEN_HANDLER2(andis_, "andis.", 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8194 GEN_HANDLER(cntlzw, 0x1F, 0x1A, 0x00, 0x00000000, PPC_INTEGER),
8195 GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER),
8196 GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER),
8197 GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8198 GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8199 GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8200 GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8201 GEN_HANDLER(popcntb, 0x1F, 0x03, 0x03, 0x0000F801, PPC_POPCNTB),
8202 #if defined(TARGET_PPC64)
8203 GEN_HANDLER(cntlzd, 0x1F, 0x1A, 0x01, 0x00000000, PPC_64B),
8204 #endif
8205 GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8206 GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8207 GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8208 GEN_HANDLER(slw, 0x1F, 0x18, 0x00, 0x00000000, PPC_INTEGER),
8209 GEN_HANDLER(sraw, 0x1F, 0x18, 0x18, 0x00000000, PPC_INTEGER),
8210 GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER),
8211 GEN_HANDLER(srw, 0x1F, 0x18, 0x10, 0x00000000, PPC_INTEGER),
8212 #if defined(TARGET_PPC64)
8213 GEN_HANDLER(sld, 0x1F, 0x1B, 0x00, 0x00000000, PPC_64B),
8214 GEN_HANDLER(srad, 0x1F, 0x1A, 0x18, 0x00000000, PPC_64B),
8215 GEN_HANDLER2(sradi0, "sradi", 0x1F, 0x1A, 0x19, 0x00000000, PPC_64B),
8216 GEN_HANDLER2(sradi1, "sradi", 0x1F, 0x1B, 0x19, 0x00000000, PPC_64B),
8217 GEN_HANDLER(srd, 0x1F, 0x1B, 0x10, 0x00000000, PPC_64B),
8218 #endif
8219 GEN_HANDLER(frsqrtes, 0x3B, 0x1A, 0xFF, 0x001F07C0, PPC_FLOAT_FRSQRTES),
8220 GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT),
8221 GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT),
8222 GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT),
8223 GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT),
8224 GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT),
8225 GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT),
8226 GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT),
8227 GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT),
8228 GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT),
8229 GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x00010000, PPC_FLOAT),
8230 GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT),
8231 #if defined(TARGET_PPC64)
8232 GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B),
8233 GEN_HANDLER(lq, 0x38, 0xFF, 0xFF, 0x00000000, PPC_64BX),
8234 GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000000, PPC_64B),
8235 #endif
8236 GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8237 GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8238 GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_STRING),
8239 GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_STRING),
8240 GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_STRING),
8241 GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_STRING),
8242 GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FFF801, PPC_MEM_EIEIO),
8243 GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FFF801, PPC_MEM),
8244 GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000000, PPC_RES),
8245 GEN_HANDLER2(stwcx_, "stwcx.", 0x1F, 0x16, 0x04, 0x00000000, PPC_RES),
8246 #if defined(TARGET_PPC64)
8247 GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000000, PPC_64B),
8248 GEN_HANDLER2(stdcx_, "stdcx.", 0x1F, 0x16, 0x06, 0x00000000, PPC_64B),
8249 #endif
8250 GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x039FF801, PPC_MEM_SYNC),
8251 GEN_HANDLER(wait, 0x1F, 0x1E, 0x01, 0x03FFF801, PPC_WAIT),
8252 GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
8253 GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
8254 GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW),
8255 GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW),
8256 GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER),
8257 GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW),
8258 #if defined(TARGET_PPC64)
8259 GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B),
8260 GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64H),
8261 #endif
8262 GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFF01D, PPC_FLOW),
8263 GEN_HANDLER(tw, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW),
8264 GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
8265 #if defined(TARGET_PPC64)
8266 GEN_HANDLER(td, 0x1F, 0x04, 0x02, 0x00000001, PPC_64B),
8267 GEN_HANDLER(tdi, 0x02, 0xFF, 0xFF, 0x00000000, PPC_64B),
8268 #endif
8269 GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC),
8270 GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC),
8271 GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC),
8272 GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC),
8273 GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MFTB),
8274 GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC),
8275 #if defined(TARGET_PPC64)
8276 GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001EF801, PPC_64B),
8277 #endif
8278 GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC),
8279 GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC),
8280 GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03C00001, PPC_CACHE),
8281 GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE),
8282 GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE),
8283 GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x02000001, PPC_CACHE),
8284 GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x02000001, PPC_CACHE),
8285 GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE_DCBZ),
8286 GEN_HANDLER2(dcbz_970, "dcbz", 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZT),
8287 GEN_HANDLER(dst, 0x1F, 0x16, 0x0A, 0x01800001, PPC_ALTIVEC),
8288 GEN_HANDLER(dstst, 0x1F, 0x16, 0x0B, 0x02000001, PPC_ALTIVEC),
8289 GEN_HANDLER(dss, 0x1F, 0x16, 0x19, 0x019FF801, PPC_ALTIVEC),
8290 GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE_ICBI),
8291 GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_DCBA),
8292 GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT),
8293 GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT),
8294 GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT),
8295 GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT),
8296 #if defined(TARGET_PPC64)
8297 GEN_HANDLER2(mfsr_64b, "mfsr", 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT_64B),
8298 GEN_HANDLER2(mfsrin_64b, "mfsrin", 0x1F, 0x13, 0x14, 0x001F0001,
8299              PPC_SEGMENT_64B),
8300 GEN_HANDLER2(mtsr_64b, "mtsr", 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B),
8301 GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001,
8302              PPC_SEGMENT_64B),
8303 GEN_HANDLER2(slbmte, "slbmte", 0x1F, 0x12, 0x0C, 0x00000000, PPC_SEGMENT_64B),
8304 #endif
8305 GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA),
8306 GEN_HANDLER(tlbiel, 0x1F, 0x12, 0x08, 0x03FF0001, PPC_MEM_TLBIE),
8307 GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE),
8308 GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC),
8309 #if defined(TARGET_PPC64)
8310 GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x03FFFC01, PPC_SLBI),
8311 GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI),
8312 #endif
8313 GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN),
8314 GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN),
8315 GEN_HANDLER(abs, 0x1F, 0x08, 0x0B, 0x0000F800, PPC_POWER_BR),
8316 GEN_HANDLER(abso, 0x1F, 0x08, 0x1B, 0x0000F800, PPC_POWER_BR),
8317 GEN_HANDLER(clcs, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR),
8318 GEN_HANDLER(div, 0x1F, 0x0B, 0x0A, 0x00000000, PPC_POWER_BR),
8319 GEN_HANDLER(divo, 0x1F, 0x0B, 0x1A, 0x00000000, PPC_POWER_BR),
8320 GEN_HANDLER(divs, 0x1F, 0x0B, 0x0B, 0x00000000, PPC_POWER_BR),
8321 GEN_HANDLER(divso, 0x1F, 0x0B, 0x1B, 0x00000000, PPC_POWER_BR),
8322 GEN_HANDLER(doz, 0x1F, 0x08, 0x08, 0x00000000, PPC_POWER_BR),
8323 GEN_HANDLER(dozo, 0x1F, 0x08, 0x18, 0x00000000, PPC_POWER_BR),
8324 GEN_HANDLER(dozi, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR),
8325 GEN_HANDLER(lscbx, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR),
8326 GEN_HANDLER(maskg, 0x1F, 0x1D, 0x00, 0x00000000, PPC_POWER_BR),
8327 GEN_HANDLER(maskir, 0x1F, 0x1D, 0x10, 0x00000000, PPC_POWER_BR),
8328 GEN_HANDLER(mul, 0x1F, 0x0B, 0x03, 0x00000000, PPC_POWER_BR),
8329 GEN_HANDLER(mulo, 0x1F, 0x0B, 0x13, 0x00000000, PPC_POWER_BR),
8330 GEN_HANDLER(nabs, 0x1F, 0x08, 0x0F, 0x00000000, PPC_POWER_BR),
8331 GEN_HANDLER(nabso, 0x1F, 0x08, 0x1F, 0x00000000, PPC_POWER_BR),
8332 GEN_HANDLER(rlmi, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR),
8333 GEN_HANDLER(rrib, 0x1F, 0x19, 0x10, 0x00000000, PPC_POWER_BR),
8334 GEN_HANDLER(sle, 0x1F, 0x19, 0x04, 0x00000000, PPC_POWER_BR),
8335 GEN_HANDLER(sleq, 0x1F, 0x19, 0x06, 0x00000000, PPC_POWER_BR),
8336 GEN_HANDLER(sliq, 0x1F, 0x18, 0x05, 0x00000000, PPC_POWER_BR),
8337 GEN_HANDLER(slliq, 0x1F, 0x18, 0x07, 0x00000000, PPC_POWER_BR),
8338 GEN_HANDLER(sllq, 0x1F, 0x18, 0x06, 0x00000000, PPC_POWER_BR),
8339 GEN_HANDLER(slq, 0x1F, 0x18, 0x04, 0x00000000, PPC_POWER_BR),
8340 GEN_HANDLER(sraiq, 0x1F, 0x18, 0x1D, 0x00000000, PPC_POWER_BR),
8341 GEN_HANDLER(sraq, 0x1F, 0x18, 0x1C, 0x00000000, PPC_POWER_BR),
8342 GEN_HANDLER(sre, 0x1F, 0x19, 0x14, 0x00000000, PPC_POWER_BR),
8343 GEN_HANDLER(srea, 0x1F, 0x19, 0x1C, 0x00000000, PPC_POWER_BR),
8344 GEN_HANDLER(sreq, 0x1F, 0x19, 0x16, 0x00000000, PPC_POWER_BR),
8345 GEN_HANDLER(sriq, 0x1F, 0x18, 0x15, 0x00000000, PPC_POWER_BR),
8346 GEN_HANDLER(srliq, 0x1F, 0x18, 0x17, 0x00000000, PPC_POWER_BR),
8347 GEN_HANDLER(srlq, 0x1F, 0x18, 0x16, 0x00000000, PPC_POWER_BR),
8348 GEN_HANDLER(srq, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR),
8349 GEN_HANDLER(dsa, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC),
8350 GEN_HANDLER(esa, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC),
8351 GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC),
8352 GEN_HANDLER2(tlbld_6xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB),
8353 GEN_HANDLER2(tlbli_6xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB),
8354 GEN_HANDLER2(tlbld_74xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_74xx_TLB),
8355 GEN_HANDLER2(tlbli_74xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_74xx_TLB),
8356 GEN_HANDLER(clf, 0x1F, 0x16, 0x03, 0x03E00000, PPC_POWER),
8357 GEN_HANDLER(cli, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER),
8358 GEN_HANDLER(dclst, 0x1F, 0x16, 0x13, 0x03E00000, PPC_POWER),
8359 GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER),
8360 GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER),
8361 GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER),
8362 GEN_HANDLER(lfq, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
8363 GEN_HANDLER(lfqu, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
8364 GEN_HANDLER(lfqux, 0x1F, 0x17, 0x19, 0x00000001, PPC_POWER2),
8365 GEN_HANDLER(lfqx, 0x1F, 0x17, 0x18, 0x00000001, PPC_POWER2),
8366 GEN_HANDLER(stfq, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
8367 GEN_HANDLER(stfqu, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
8368 GEN_HANDLER(stfqux, 0x1F, 0x17, 0x1D, 0x00000001, PPC_POWER2),
8369 GEN_HANDLER(stfqx, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2),
8370 GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_MFAPIDI),
8371 GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_TLBIVA),
8372 GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_DCR),
8373 GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_DCR),
8374 GEN_HANDLER(mfdcrx, 0x1F, 0x03, 0x08, 0x00000000, PPC_DCRX),
8375 GEN_HANDLER(mtdcrx, 0x1F, 0x03, 0x0C, 0x00000000, PPC_DCRX),
8376 GEN_HANDLER(mfdcrux, 0x1F, 0x03, 0x09, 0x00000000, PPC_DCRUX),
8377 GEN_HANDLER(mtdcrux, 0x1F, 0x03, 0x0D, 0x00000000, PPC_DCRUX),
8378 GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON),
8379 GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON),
8380 GEN_HANDLER2(icbt_40x, "icbt", 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_ICBT),
8381 GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON),
8382 GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON),
8383 GEN_HANDLER2(rfci_40x, "rfci", 0x13, 0x13, 0x01, 0x03FF8001, PPC_40x_EXCP),
8384 GEN_HANDLER(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE),
8385 GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_RFDI),
8386 GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_RFMCI),
8387 GEN_HANDLER2(tlbre_40x, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB),
8388 GEN_HANDLER2(tlbsx_40x, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB),
8389 GEN_HANDLER2(tlbwe_40x, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB),
8390 GEN_HANDLER2(tlbre_440, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE),
8391 GEN_HANDLER2(tlbsx_440, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE),
8392 GEN_HANDLER2(tlbwe_440, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE),
8393 GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE),
8394 GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000E7C01, PPC_WRTEE),
8395 GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC),
8396 GEN_HANDLER(mbar, 0x1F, 0x16, 0x1a, 0x001FF801, PPC_BOOKE),
8397 GEN_HANDLER(msync, 0x1F, 0x16, 0x12, 0x03FFF801, PPC_BOOKE),
8398 GEN_HANDLER2(icbt_440, "icbt", 0x1F, 0x16, 0x00, 0x03E00001, PPC_BOOKE),
8399 GEN_HANDLER(lvsl, 0x1f, 0x06, 0x00, 0x00000001, PPC_ALTIVEC),
8400 GEN_HANDLER(lvsr, 0x1f, 0x06, 0x01, 0x00000001, PPC_ALTIVEC),
8401 GEN_HANDLER(mfvscr, 0x04, 0x2, 0x18, 0x001ff800, PPC_ALTIVEC),
8402 GEN_HANDLER(mtvscr, 0x04, 0x2, 0x19, 0x03ff0000, PPC_ALTIVEC),
8403 GEN_HANDLER(vsldoi, 0x04, 0x16, 0xFF, 0x00000400, PPC_ALTIVEC),
8404 GEN_HANDLER(vmladduhm, 0x04, 0x11, 0xFF, 0x00000000, PPC_ALTIVEC),
8405 GEN_HANDLER2(evsel0, "evsel", 0x04, 0x1c, 0x09, 0x00000000, PPC_SPE),
8406 GEN_HANDLER2(evsel1, "evsel", 0x04, 0x1d, 0x09, 0x00000000, PPC_SPE),
8407 GEN_HANDLER2(evsel2, "evsel", 0x04, 0x1e, 0x09, 0x00000000, PPC_SPE),
8408 GEN_HANDLER2(evsel3, "evsel", 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE),
8409
8410 #undef GEN_INT_ARITH_ADD
8411 #undef GEN_INT_ARITH_ADD_CONST
8412 #define GEN_INT_ARITH_ADD(name, opc3, add_ca, compute_ca, compute_ov)         \
8413 GEN_HANDLER(name, 0x1F, 0x0A, opc3, 0x00000000, PPC_INTEGER),
8414 #define GEN_INT_ARITH_ADD_CONST(name, opc3, const_val,                        \
8415                                 add_ca, compute_ca, compute_ov)               \
8416 GEN_HANDLER(name, 0x1F, 0x0A, opc3, 0x0000F800, PPC_INTEGER),
8417 GEN_INT_ARITH_ADD(add, 0x08, 0, 0, 0)
8418 GEN_INT_ARITH_ADD(addo, 0x18, 0, 0, 1)
8419 GEN_INT_ARITH_ADD(addc, 0x00, 0, 1, 0)
8420 GEN_INT_ARITH_ADD(addco, 0x10, 0, 1, 1)
8421 GEN_INT_ARITH_ADD(adde, 0x04, 1, 1, 0)
8422 GEN_INT_ARITH_ADD(addeo, 0x14, 1, 1, 1)
8423 GEN_INT_ARITH_ADD_CONST(addme, 0x07, -1LL, 1, 1, 0)
8424 GEN_INT_ARITH_ADD_CONST(addmeo, 0x17, -1LL, 1, 1, 1)
8425 GEN_INT_ARITH_ADD_CONST(addze, 0x06, 0, 1, 1, 0)
8426 GEN_INT_ARITH_ADD_CONST(addzeo, 0x16, 0, 1, 1, 1)
8427
8428 #undef GEN_INT_ARITH_DIVW
8429 #define GEN_INT_ARITH_DIVW(name, opc3, sign, compute_ov)                      \
8430 GEN_HANDLER(name, 0x1F, 0x0B, opc3, 0x00000000, PPC_INTEGER)
8431 GEN_INT_ARITH_DIVW(divwu, 0x0E, 0, 0),
8432 GEN_INT_ARITH_DIVW(divwuo, 0x1E, 0, 1),
8433 GEN_INT_ARITH_DIVW(divw, 0x0F, 1, 0),
8434 GEN_INT_ARITH_DIVW(divwo, 0x1F, 1, 1),
8435
8436 #if defined(TARGET_PPC64)
8437 #undef GEN_INT_ARITH_DIVD
8438 #define GEN_INT_ARITH_DIVD(name, opc3, sign, compute_ov)                      \
8439 GEN_HANDLER(name, 0x1F, 0x09, opc3, 0x00000000, PPC_64B)
8440 GEN_INT_ARITH_DIVD(divdu, 0x0E, 0, 0),
8441 GEN_INT_ARITH_DIVD(divduo, 0x1E, 0, 1),
8442 GEN_INT_ARITH_DIVD(divd, 0x0F, 1, 0),
8443 GEN_INT_ARITH_DIVD(divdo, 0x1F, 1, 1),
8444
8445 #undef GEN_INT_ARITH_MUL_HELPER
8446 #define GEN_INT_ARITH_MUL_HELPER(name, opc3)                                  \
8447 GEN_HANDLER(name, 0x1F, 0x09, opc3, 0x00000000, PPC_64B)
8448 GEN_INT_ARITH_MUL_HELPER(mulhdu, 0x00),
8449 GEN_INT_ARITH_MUL_HELPER(mulhd, 0x02),
8450 GEN_INT_ARITH_MUL_HELPER(mulldo, 0x17),
8451 #endif
8452
8453 #undef GEN_INT_ARITH_SUBF
8454 #undef GEN_INT_ARITH_SUBF_CONST
8455 #define GEN_INT_ARITH_SUBF(name, opc3, add_ca, compute_ca, compute_ov)        \
8456 GEN_HANDLER(name, 0x1F, 0x08, opc3, 0x00000000, PPC_INTEGER),
8457 #define GEN_INT_ARITH_SUBF_CONST(name, opc3, const_val,                       \
8458                                 add_ca, compute_ca, compute_ov)               \
8459 GEN_HANDLER(name, 0x1F, 0x08, opc3, 0x0000F800, PPC_INTEGER),
8460 GEN_INT_ARITH_SUBF(subf, 0x01, 0, 0, 0)
8461 GEN_INT_ARITH_SUBF(subfo, 0x11, 0, 0, 1)
8462 GEN_INT_ARITH_SUBF(subfc, 0x00, 0, 1, 0)
8463 GEN_INT_ARITH_SUBF(subfco, 0x10, 0, 1, 1)
8464 GEN_INT_ARITH_SUBF(subfe, 0x04, 1, 1, 0)
8465 GEN_INT_ARITH_SUBF(subfeo, 0x14, 1, 1, 1)
8466 GEN_INT_ARITH_SUBF_CONST(subfme, 0x07, -1LL, 1, 1, 0)
8467 GEN_INT_ARITH_SUBF_CONST(subfmeo, 0x17, -1LL, 1, 1, 1)
8468 GEN_INT_ARITH_SUBF_CONST(subfze, 0x06, 0, 1, 1, 0)
8469 GEN_INT_ARITH_SUBF_CONST(subfzeo, 0x16, 0, 1, 1, 1)
8470
8471 #undef GEN_LOGICAL1
8472 #undef GEN_LOGICAL2
8473 #define GEN_LOGICAL2(name, tcg_op, opc, type)                                 \
8474 GEN_HANDLER(name, 0x1F, 0x1C, opc, 0x00000000, type)
8475 #define GEN_LOGICAL1(name, tcg_op, opc, type)                                 \
8476 GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, type)
8477 GEN_LOGICAL2(and, tcg_gen_and_tl, 0x00, PPC_INTEGER),
8478 GEN_LOGICAL2(andc, tcg_gen_andc_tl, 0x01, PPC_INTEGER),
8479 GEN_LOGICAL2(eqv, tcg_gen_eqv_tl, 0x08, PPC_INTEGER),
8480 GEN_LOGICAL1(extsb, tcg_gen_ext8s_tl, 0x1D, PPC_INTEGER),
8481 GEN_LOGICAL1(extsh, tcg_gen_ext16s_tl, 0x1C, PPC_INTEGER),
8482 GEN_LOGICAL2(nand, tcg_gen_nand_tl, 0x0E, PPC_INTEGER),
8483 GEN_LOGICAL2(nor, tcg_gen_nor_tl, 0x03, PPC_INTEGER),
8484 GEN_LOGICAL2(orc, tcg_gen_orc_tl, 0x0C, PPC_INTEGER),
8485 #if defined(TARGET_PPC64)
8486 GEN_LOGICAL1(extsw, tcg_gen_ext32s_tl, 0x1E, PPC_64B),
8487 #endif
8488
8489 #if defined(TARGET_PPC64)
8490 #undef GEN_PPC64_R2
8491 #undef GEN_PPC64_R4
8492 #define GEN_PPC64_R2(name, opc1, opc2)                                        \
8493 GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B),\
8494 GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000,   \
8495              PPC_64B)
8496 #define GEN_PPC64_R4(name, opc1, opc2)                                        \
8497 GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B),\
8498 GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x01, 0xFF, 0x00000000,   \
8499              PPC_64B),                                                        \
8500 GEN_HANDLER2(name##2, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000,   \
8501              PPC_64B),                                                        \
8502 GEN_HANDLER2(name##3, stringify(name), opc1, opc2 | 0x11, 0xFF, 0x00000000,   \
8503              PPC_64B)
8504 GEN_PPC64_R4(rldicl, 0x1E, 0x00),
8505 GEN_PPC64_R4(rldicr, 0x1E, 0x02),
8506 GEN_PPC64_R4(rldic, 0x1E, 0x04),
8507 GEN_PPC64_R2(rldcl, 0x1E, 0x08),
8508 GEN_PPC64_R2(rldcr, 0x1E, 0x09),
8509 GEN_PPC64_R4(rldimi, 0x1E, 0x06),
8510 #endif
8511
8512 #undef _GEN_FLOAT_ACB
8513 #undef GEN_FLOAT_ACB
8514 #undef _GEN_FLOAT_AB
8515 #undef GEN_FLOAT_AB
8516 #undef _GEN_FLOAT_AC
8517 #undef GEN_FLOAT_AC
8518 #undef GEN_FLOAT_B
8519 #undef GEN_FLOAT_BS
8520 #define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat, set_fprf, type)           \
8521 GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, type)
8522 #define GEN_FLOAT_ACB(name, op2, set_fprf, type)                              \
8523 _GEN_FLOAT_ACB(name, name, 0x3F, op2, 0, set_fprf, type),                     \
8524 _GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, set_fprf, type)
8525 #define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
8526 GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)
8527 #define GEN_FLOAT_AB(name, op2, inval, set_fprf, type)                        \
8528 _GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0, set_fprf, type),               \
8529 _GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1, set_fprf, type)
8530 #define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
8531 GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)
8532 #define GEN_FLOAT_AC(name, op2, inval, set_fprf, type)                        \
8533 _GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0, set_fprf, type),               \
8534 _GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1, set_fprf, type)
8535 #define GEN_FLOAT_B(name, op2, op3, set_fprf, type)                           \
8536 GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, type)
8537 #define GEN_FLOAT_BS(name, op1, op2, set_fprf, type)                          \
8538 GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, type)
8539
8540 GEN_FLOAT_AB(add, 0x15, 0x000007C0, 1, PPC_FLOAT),
8541 GEN_FLOAT_AB(div, 0x12, 0x000007C0, 1, PPC_FLOAT),
8542 GEN_FLOAT_AC(mul, 0x19, 0x0000F800, 1, PPC_FLOAT),
8543 GEN_FLOAT_BS(re, 0x3F, 0x18, 1, PPC_FLOAT_EXT),
8544 GEN_FLOAT_BS(res, 0x3B, 0x18, 1, PPC_FLOAT_FRES),
8545 GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A, 1, PPC_FLOAT_FRSQRTE),
8546 _GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0, 0, PPC_FLOAT_FSEL),
8547 GEN_FLOAT_AB(sub, 0x14, 0x000007C0, 1, PPC_FLOAT),
8548 GEN_FLOAT_ACB(madd, 0x1D, 1, PPC_FLOAT),
8549 GEN_FLOAT_ACB(msub, 0x1C, 1, PPC_FLOAT),
8550 GEN_FLOAT_ACB(nmadd, 0x1F, 1, PPC_FLOAT),
8551 GEN_FLOAT_ACB(nmsub, 0x1E, 1, PPC_FLOAT),
8552 GEN_FLOAT_B(ctiw, 0x0E, 0x00, 0, PPC_FLOAT),
8553 GEN_FLOAT_B(ctiwz, 0x0F, 0x00, 0, PPC_FLOAT),
8554 GEN_FLOAT_B(rsp, 0x0C, 0x00, 1, PPC_FLOAT),
8555 #if defined(TARGET_PPC64)
8556 GEN_FLOAT_B(cfid, 0x0E, 0x1A, 1, PPC_64B),
8557 GEN_FLOAT_B(ctid, 0x0E, 0x19, 0, PPC_64B),
8558 GEN_FLOAT_B(ctidz, 0x0F, 0x19, 0, PPC_64B),
8559 #endif
8560 GEN_FLOAT_B(rin, 0x08, 0x0C, 1, PPC_FLOAT_EXT),
8561 GEN_FLOAT_B(riz, 0x08, 0x0D, 1, PPC_FLOAT_EXT),
8562 GEN_FLOAT_B(rip, 0x08, 0x0E, 1, PPC_FLOAT_EXT),
8563 GEN_FLOAT_B(rim, 0x08, 0x0F, 1, PPC_FLOAT_EXT),
8564 GEN_FLOAT_B(abs, 0x08, 0x08, 0, PPC_FLOAT),
8565 GEN_FLOAT_B(nabs, 0x08, 0x04, 0, PPC_FLOAT),
8566 GEN_FLOAT_B(neg, 0x08, 0x01, 0, PPC_FLOAT),
8567
8568 #undef GEN_LD
8569 #undef GEN_LDU
8570 #undef GEN_LDUX
8571 #undef GEN_LDX
8572 #undef GEN_LDS
8573 #define GEN_LD(name, ldop, opc, type)                                         \
8574 GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
8575 #define GEN_LDU(name, ldop, opc, type)                                        \
8576 GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
8577 #define GEN_LDUX(name, ldop, opc2, opc3, type)                                \
8578 GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type),
8579 #define GEN_LDX(name, ldop, opc2, opc3, type)                                 \
8580 GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type),
8581 #define GEN_LDS(name, ldop, op, type)                                         \
8582 GEN_LD(name, ldop, op | 0x20, type)                                           \
8583 GEN_LDU(name, ldop, op | 0x21, type)                                          \
8584 GEN_LDUX(name, ldop, 0x17, op | 0x01, type)                                   \
8585 GEN_LDX(name, ldop, 0x17, op | 0x00, type)
8586
8587 GEN_LDS(lbz, ld8u, 0x02, PPC_INTEGER)
8588 GEN_LDS(lha, ld16s, 0x0A, PPC_INTEGER)
8589 GEN_LDS(lhz, ld16u, 0x08, PPC_INTEGER)
8590 GEN_LDS(lwz, ld32u, 0x00, PPC_INTEGER)
8591 #if defined(TARGET_PPC64)
8592 GEN_LDUX(lwa, ld32s, 0x15, 0x0B, PPC_64B)
8593 GEN_LDX(lwa, ld32s, 0x15, 0x0A, PPC_64B)
8594 GEN_LDUX(ld, ld64, 0x15, 0x01, PPC_64B)
8595 GEN_LDX(ld, ld64, 0x15, 0x00, PPC_64B)
8596 #endif
8597 GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER)
8598 GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER)
8599
8600 #undef GEN_ST
8601 #undef GEN_STU
8602 #undef GEN_STUX
8603 #undef GEN_STX
8604 #undef GEN_STS
8605 #define GEN_ST(name, stop, opc, type)                                         \
8606 GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
8607 #define GEN_STU(name, stop, opc, type)                                        \
8608 GEN_HANDLER(stop##u, opc, 0xFF, 0xFF, 0x00000000, type),
8609 #define GEN_STUX(name, stop, opc2, opc3, type)                                \
8610 GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type),
8611 #define GEN_STX(name, stop, opc2, opc3, type)                                 \
8612 GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type),
8613 #define GEN_STS(name, stop, op, type)                                         \
8614 GEN_ST(name, stop, op | 0x20, type)                                           \
8615 GEN_STU(name, stop, op | 0x21, type)                                          \
8616 GEN_STUX(name, stop, 0x17, op | 0x01, type)                                   \
8617 GEN_STX(name, stop, 0x17, op | 0x00, type)
8618
8619 GEN_STS(stb, st8, 0x06, PPC_INTEGER)
8620 GEN_STS(sth, st16, 0x0C, PPC_INTEGER)
8621 GEN_STS(stw, st32, 0x04, PPC_INTEGER)
8622 #if defined(TARGET_PPC64)
8623 GEN_STUX(std, st64, 0x15, 0x05, PPC_64B)
8624 GEN_STX(std, st64, 0x15, 0x04, PPC_64B)
8625 #endif
8626 GEN_STX(sthbr, st16r, 0x16, 0x1C, PPC_INTEGER)
8627 GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER)
8628
8629 #undef GEN_LDF
8630 #undef GEN_LDUF
8631 #undef GEN_LDUXF
8632 #undef GEN_LDXF
8633 #undef GEN_LDFS
8634 #define GEN_LDF(name, ldop, opc, type)                                        \
8635 GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
8636 #define GEN_LDUF(name, ldop, opc, type)                                       \
8637 GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
8638 #define GEN_LDUXF(name, ldop, opc, type)                                      \
8639 GEN_HANDLER(name##ux, 0x1F, 0x17, opc, 0x00000001, type),
8640 #define GEN_LDXF(name, ldop, opc2, opc3, type)                                \
8641 GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type),
8642 #define GEN_LDFS(name, ldop, op, type)                                        \
8643 GEN_LDF(name, ldop, op | 0x20, type)                                          \
8644 GEN_LDUF(name, ldop, op | 0x21, type)                                         \
8645 GEN_LDUXF(name, ldop, op | 0x01, type)                                        \
8646 GEN_LDXF(name, ldop, 0x17, op | 0x00, type)
8647
8648 GEN_LDFS(lfd, ld64, 0x12, PPC_FLOAT)
8649 GEN_LDFS(lfs, ld32fs, 0x10, PPC_FLOAT)
8650
8651 #undef GEN_STF
8652 #undef GEN_STUF
8653 #undef GEN_STUXF
8654 #undef GEN_STXF
8655 #undef GEN_STFS
8656 #define GEN_STF(name, stop, opc, type)                                        \
8657 GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
8658 #define GEN_STUF(name, stop, opc, type)                                       \
8659 GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
8660 #define GEN_STUXF(name, stop, opc, type)                                      \
8661 GEN_HANDLER(name##ux, 0x1F, 0x17, opc, 0x00000001, type),
8662 #define GEN_STXF(name, stop, opc2, opc3, type)                                \
8663 GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type),
8664 #define GEN_STFS(name, stop, op, type)                                        \
8665 GEN_STF(name, stop, op | 0x20, type)                                          \
8666 GEN_STUF(name, stop, op | 0x21, type)                                         \
8667 GEN_STUXF(name, stop, op | 0x01, type)                                        \
8668 GEN_STXF(name, stop, 0x17, op | 0x00, type)
8669
8670 GEN_STFS(stfd, st64, 0x16, PPC_FLOAT)
8671 GEN_STFS(stfs, st32fs, 0x14, PPC_FLOAT)
8672 GEN_STXF(stfiw, st32fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX)
8673
8674 #undef GEN_CRLOGIC
8675 #define GEN_CRLOGIC(name, tcg_op, opc)                                        \
8676 GEN_HANDLER(name, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER)
8677 GEN_CRLOGIC(crand, tcg_gen_and_i32, 0x08),
8678 GEN_CRLOGIC(crandc, tcg_gen_andc_i32, 0x04),
8679 GEN_CRLOGIC(creqv, tcg_gen_eqv_i32, 0x09),
8680 GEN_CRLOGIC(crnand, tcg_gen_nand_i32, 0x07),
8681 GEN_CRLOGIC(crnor, tcg_gen_nor_i32, 0x01),
8682 GEN_CRLOGIC(cror, tcg_gen_or_i32, 0x0E),
8683 GEN_CRLOGIC(crorc, tcg_gen_orc_i32, 0x0D),
8684 GEN_CRLOGIC(crxor, tcg_gen_xor_i32, 0x06),
8685
8686 #undef GEN_MAC_HANDLER
8687 #define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
8688 GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC)
8689 GEN_MAC_HANDLER(macchw, 0x0C, 0x05),
8690 GEN_MAC_HANDLER(macchwo, 0x0C, 0x15),
8691 GEN_MAC_HANDLER(macchws, 0x0C, 0x07),
8692 GEN_MAC_HANDLER(macchwso, 0x0C, 0x17),
8693 GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06),
8694 GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16),
8695 GEN_MAC_HANDLER(macchwu, 0x0C, 0x04),
8696 GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14),
8697 GEN_MAC_HANDLER(machhw, 0x0C, 0x01),
8698 GEN_MAC_HANDLER(machhwo, 0x0C, 0x11),
8699 GEN_MAC_HANDLER(machhws, 0x0C, 0x03),
8700 GEN_MAC_HANDLER(machhwso, 0x0C, 0x13),
8701 GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02),
8702 GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12),
8703 GEN_MAC_HANDLER(machhwu, 0x0C, 0x00),
8704 GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10),
8705 GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D),
8706 GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D),
8707 GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F),
8708 GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F),
8709 GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C),
8710 GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C),
8711 GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E),
8712 GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E),
8713 GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05),
8714 GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15),
8715 GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07),
8716 GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17),
8717 GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01),
8718 GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11),
8719 GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03),
8720 GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13),
8721 GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D),
8722 GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D),
8723 GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F),
8724 GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F),
8725 GEN_MAC_HANDLER(mulchw, 0x08, 0x05),
8726 GEN_MAC_HANDLER(mulchwu, 0x08, 0x04),
8727 GEN_MAC_HANDLER(mulhhw, 0x08, 0x01),
8728 GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00),
8729 GEN_MAC_HANDLER(mullhw, 0x08, 0x0D),
8730 GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C),
8731
8732 #undef GEN_VR_LDX
8733 #undef GEN_VR_STX
8734 #undef GEN_VR_LVE
8735 #undef GEN_VR_STVE
8736 #define GEN_VR_LDX(name, opc2, opc3)                                          \
8737 GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
8738 #define GEN_VR_STX(name, opc2, opc3)                                          \
8739 GEN_HANDLER(st##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
8740 #define GEN_VR_LVE(name, opc2, opc3)                                    \
8741     GEN_HANDLER(lve##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
8742 #define GEN_VR_STVE(name, opc2, opc3)                                   \
8743     GEN_HANDLER(stve##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
8744 GEN_VR_LDX(lvx, 0x07, 0x03),
8745 GEN_VR_LDX(lvxl, 0x07, 0x0B),
8746 GEN_VR_LVE(bx, 0x07, 0x00),
8747 GEN_VR_LVE(hx, 0x07, 0x01),
8748 GEN_VR_LVE(wx, 0x07, 0x02),
8749 GEN_VR_STX(svx, 0x07, 0x07),
8750 GEN_VR_STX(svxl, 0x07, 0x0F),
8751 GEN_VR_STVE(bx, 0x07, 0x04),
8752 GEN_VR_STVE(hx, 0x07, 0x05),
8753 GEN_VR_STVE(wx, 0x07, 0x06),
8754
8755 #undef GEN_VX_LOGICAL
8756 #define GEN_VX_LOGICAL(name, tcg_op, opc2, opc3)                        \
8757 GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
8758 GEN_VX_LOGICAL(vand, tcg_gen_and_i64, 2, 16),
8759 GEN_VX_LOGICAL(vandc, tcg_gen_andc_i64, 2, 17),
8760 GEN_VX_LOGICAL(vor, tcg_gen_or_i64, 2, 18),
8761 GEN_VX_LOGICAL(vxor, tcg_gen_xor_i64, 2, 19),
8762 GEN_VX_LOGICAL(vnor, tcg_gen_nor_i64, 2, 20),
8763
8764 #undef GEN_VXFORM
8765 #define GEN_VXFORM(name, opc2, opc3)                                    \
8766 GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
8767 GEN_VXFORM(vaddubm, 0, 0),
8768 GEN_VXFORM(vadduhm, 0, 1),
8769 GEN_VXFORM(vadduwm, 0, 2),
8770 GEN_VXFORM(vsububm, 0, 16),
8771 GEN_VXFORM(vsubuhm, 0, 17),
8772 GEN_VXFORM(vsubuwm, 0, 18),
8773 GEN_VXFORM(vmaxub, 1, 0),
8774 GEN_VXFORM(vmaxuh, 1, 1),
8775 GEN_VXFORM(vmaxuw, 1, 2),
8776 GEN_VXFORM(vmaxsb, 1, 4),
8777 GEN_VXFORM(vmaxsh, 1, 5),
8778 GEN_VXFORM(vmaxsw, 1, 6),
8779 GEN_VXFORM(vminub, 1, 8),
8780 GEN_VXFORM(vminuh, 1, 9),
8781 GEN_VXFORM(vminuw, 1, 10),
8782 GEN_VXFORM(vminsb, 1, 12),
8783 GEN_VXFORM(vminsh, 1, 13),
8784 GEN_VXFORM(vminsw, 1, 14),
8785 GEN_VXFORM(vavgub, 1, 16),
8786 GEN_VXFORM(vavguh, 1, 17),
8787 GEN_VXFORM(vavguw, 1, 18),
8788 GEN_VXFORM(vavgsb, 1, 20),
8789 GEN_VXFORM(vavgsh, 1, 21),
8790 GEN_VXFORM(vavgsw, 1, 22),
8791 GEN_VXFORM(vmrghb, 6, 0),
8792 GEN_VXFORM(vmrghh, 6, 1),
8793 GEN_VXFORM(vmrghw, 6, 2),
8794 GEN_VXFORM(vmrglb, 6, 4),
8795 GEN_VXFORM(vmrglh, 6, 5),
8796 GEN_VXFORM(vmrglw, 6, 6),
8797 GEN_VXFORM(vmuloub, 4, 0),
8798 GEN_VXFORM(vmulouh, 4, 1),
8799 GEN_VXFORM(vmulosb, 4, 4),
8800 GEN_VXFORM(vmulosh, 4, 5),
8801 GEN_VXFORM(vmuleub, 4, 8),
8802 GEN_VXFORM(vmuleuh, 4, 9),
8803 GEN_VXFORM(vmulesb, 4, 12),
8804 GEN_VXFORM(vmulesh, 4, 13),
8805 GEN_VXFORM(vslb, 2, 4),
8806 GEN_VXFORM(vslh, 2, 5),
8807 GEN_VXFORM(vslw, 2, 6),
8808 GEN_VXFORM(vsrb, 2, 8),
8809 GEN_VXFORM(vsrh, 2, 9),
8810 GEN_VXFORM(vsrw, 2, 10),
8811 GEN_VXFORM(vsrab, 2, 12),
8812 GEN_VXFORM(vsrah, 2, 13),
8813 GEN_VXFORM(vsraw, 2, 14),
8814 GEN_VXFORM(vslo, 6, 16),
8815 GEN_VXFORM(vsro, 6, 17),
8816 GEN_VXFORM(vaddcuw, 0, 6),
8817 GEN_VXFORM(vsubcuw, 0, 22),
8818 GEN_VXFORM(vaddubs, 0, 8),
8819 GEN_VXFORM(vadduhs, 0, 9),
8820 GEN_VXFORM(vadduws, 0, 10),
8821 GEN_VXFORM(vaddsbs, 0, 12),
8822 GEN_VXFORM(vaddshs, 0, 13),
8823 GEN_VXFORM(vaddsws, 0, 14),
8824 GEN_VXFORM(vsububs, 0, 24),
8825 GEN_VXFORM(vsubuhs, 0, 25),
8826 GEN_VXFORM(vsubuws, 0, 26),
8827 GEN_VXFORM(vsubsbs, 0, 28),
8828 GEN_VXFORM(vsubshs, 0, 29),
8829 GEN_VXFORM(vsubsws, 0, 30),
8830 GEN_VXFORM(vrlb, 2, 0),
8831 GEN_VXFORM(vrlh, 2, 1),
8832 GEN_VXFORM(vrlw, 2, 2),
8833 GEN_VXFORM(vsl, 2, 7),
8834 GEN_VXFORM(vsr, 2, 11),
8835 GEN_VXFORM(vpkuhum, 7, 0),
8836 GEN_VXFORM(vpkuwum, 7, 1),
8837 GEN_VXFORM(vpkuhus, 7, 2),
8838 GEN_VXFORM(vpkuwus, 7, 3),
8839 GEN_VXFORM(vpkshus, 7, 4),
8840 GEN_VXFORM(vpkswus, 7, 5),
8841 GEN_VXFORM(vpkshss, 7, 6),
8842 GEN_VXFORM(vpkswss, 7, 7),
8843 GEN_VXFORM(vpkpx, 7, 12),
8844 GEN_VXFORM(vsum4ubs, 4, 24),
8845 GEN_VXFORM(vsum4sbs, 4, 28),
8846 GEN_VXFORM(vsum4shs, 4, 25),
8847 GEN_VXFORM(vsum2sws, 4, 26),
8848 GEN_VXFORM(vsumsws, 4, 30),
8849 GEN_VXFORM(vaddfp, 5, 0),
8850 GEN_VXFORM(vsubfp, 5, 1),
8851 GEN_VXFORM(vmaxfp, 5, 16),
8852 GEN_VXFORM(vminfp, 5, 17),
8853
8854 #undef GEN_VXRFORM1
8855 #undef GEN_VXRFORM
8856 #define GEN_VXRFORM1(opname, name, str, opc2, opc3)                     \
8857     GEN_HANDLER2(name, str, 0x4, opc2, opc3, 0x00000000, PPC_ALTIVEC),
8858 #define GEN_VXRFORM(name, opc2, opc3)                                \
8859     GEN_VXRFORM1(name, name, #name, opc2, opc3)                      \
8860     GEN_VXRFORM1(name##_dot, name##_, #name ".", opc2, (opc3 | (0x1 << 4)))
8861 GEN_VXRFORM(vcmpequb, 3, 0)
8862 GEN_VXRFORM(vcmpequh, 3, 1)
8863 GEN_VXRFORM(vcmpequw, 3, 2)
8864 GEN_VXRFORM(vcmpgtsb, 3, 12)
8865 GEN_VXRFORM(vcmpgtsh, 3, 13)
8866 GEN_VXRFORM(vcmpgtsw, 3, 14)
8867 GEN_VXRFORM(vcmpgtub, 3, 8)
8868 GEN_VXRFORM(vcmpgtuh, 3, 9)
8869 GEN_VXRFORM(vcmpgtuw, 3, 10)
8870 GEN_VXRFORM(vcmpeqfp, 3, 3)
8871 GEN_VXRFORM(vcmpgefp, 3, 7)
8872 GEN_VXRFORM(vcmpgtfp, 3, 11)
8873 GEN_VXRFORM(vcmpbfp, 3, 15)
8874
8875 #undef GEN_VXFORM_SIMM
8876 #define GEN_VXFORM_SIMM(name, opc2, opc3)                               \
8877     GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
8878 GEN_VXFORM_SIMM(vspltisb, 6, 12),
8879 GEN_VXFORM_SIMM(vspltish, 6, 13),
8880 GEN_VXFORM_SIMM(vspltisw, 6, 14),
8881
8882 #undef GEN_VXFORM_NOA
8883 #define GEN_VXFORM_NOA(name, opc2, opc3)                                \
8884     GEN_HANDLER(name, 0x04, opc2, opc3, 0x001f0000, PPC_ALTIVEC)
8885 GEN_VXFORM_NOA(vupkhsb, 7, 8),
8886 GEN_VXFORM_NOA(vupkhsh, 7, 9),
8887 GEN_VXFORM_NOA(vupklsb, 7, 10),
8888 GEN_VXFORM_NOA(vupklsh, 7, 11),
8889 GEN_VXFORM_NOA(vupkhpx, 7, 13),
8890 GEN_VXFORM_NOA(vupklpx, 7, 15),
8891 GEN_VXFORM_NOA(vrefp, 5, 4),
8892 GEN_VXFORM_NOA(vrsqrtefp, 5, 5),
8893 GEN_VXFORM_NOA(vexptefp, 5, 6),
8894 GEN_VXFORM_NOA(vlogefp, 5, 7),
8895 GEN_VXFORM_NOA(vrfim, 5, 8),
8896 GEN_VXFORM_NOA(vrfin, 5, 9),
8897 GEN_VXFORM_NOA(vrfip, 5, 10),
8898 GEN_VXFORM_NOA(vrfiz, 5, 11),
8899
8900 #undef GEN_VXFORM_UIMM
8901 #define GEN_VXFORM_UIMM(name, opc2, opc3)                               \
8902     GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
8903 GEN_VXFORM_UIMM(vspltb, 6, 8),
8904 GEN_VXFORM_UIMM(vsplth, 6, 9),
8905 GEN_VXFORM_UIMM(vspltw, 6, 10),
8906 GEN_VXFORM_UIMM(vcfux, 5, 12),
8907 GEN_VXFORM_UIMM(vcfsx, 5, 13),
8908 GEN_VXFORM_UIMM(vctuxs, 5, 14),
8909 GEN_VXFORM_UIMM(vctsxs, 5, 15),
8910
8911 #undef GEN_VAFORM_PAIRED
8912 #define GEN_VAFORM_PAIRED(name0, name1, opc2)                           \
8913     GEN_HANDLER(name0##_##name1, 0x04, opc2, 0xFF, 0x00000000, PPC_ALTIVEC)
8914 GEN_VAFORM_PAIRED(vmhaddshs, vmhraddshs, 16),
8915 GEN_VAFORM_PAIRED(vmsumubm, vmsummbm, 18),
8916 GEN_VAFORM_PAIRED(vmsumuhm, vmsumuhs, 19),
8917 GEN_VAFORM_PAIRED(vmsumshm, vmsumshs, 20),
8918 GEN_VAFORM_PAIRED(vsel, vperm, 21),
8919 GEN_VAFORM_PAIRED(vmaddfp, vnmsubfp, 23),
8920
8921 #undef GEN_SPE
8922 #define GEN_SPE(name0, name1, opc2, opc3, inval, type)                        \
8923 GEN_HANDLER(name0##_##name1, 0x04, opc2, opc3, inval, type)
8924 GEN_SPE(evaddw,         speundef,      0x00, 0x08, 0x00000000, PPC_SPE),
8925 GEN_SPE(evaddiw,        speundef,      0x01, 0x08, 0x00000000, PPC_SPE),
8926 GEN_SPE(evsubfw,        speundef,      0x02, 0x08, 0x00000000, PPC_SPE),
8927 GEN_SPE(evsubifw,       speundef,      0x03, 0x08, 0x00000000, PPC_SPE),
8928 GEN_SPE(evabs,          evneg,         0x04, 0x08, 0x0000F800, PPC_SPE),
8929 GEN_SPE(evextsb,        evextsh,       0x05, 0x08, 0x0000F800, PPC_SPE),
8930 GEN_SPE(evrndw,         evcntlzw,      0x06, 0x08, 0x0000F800, PPC_SPE),
8931 GEN_SPE(evcntlsw,       brinc,         0x07, 0x08, 0x00000000, PPC_SPE),
8932 GEN_SPE(evmra,          speundef,      0x02, 0x13, 0x0000F800, PPC_SPE),
8933 GEN_SPE(speundef,       evand,         0x08, 0x08, 0x00000000, PPC_SPE),
8934 GEN_SPE(evandc,         speundef,      0x09, 0x08, 0x00000000, PPC_SPE),
8935 GEN_SPE(evxor,          evor,          0x0B, 0x08, 0x00000000, PPC_SPE),
8936 GEN_SPE(evnor,          eveqv,         0x0C, 0x08, 0x00000000, PPC_SPE),
8937 GEN_SPE(evmwumi,        evmwsmi,       0x0C, 0x11, 0x00000000, PPC_SPE),
8938 GEN_SPE(evmwumia,       evmwsmia,      0x1C, 0x11, 0x00000000, PPC_SPE),
8939 GEN_SPE(evmwumiaa,      evmwsmiaa,     0x0C, 0x15, 0x00000000, PPC_SPE),
8940 GEN_SPE(speundef,       evorc,         0x0D, 0x08, 0x00000000, PPC_SPE),
8941 GEN_SPE(evnand,         speundef,      0x0F, 0x08, 0x00000000, PPC_SPE),
8942 GEN_SPE(evsrwu,         evsrws,        0x10, 0x08, 0x00000000, PPC_SPE),
8943 GEN_SPE(evsrwiu,        evsrwis,       0x11, 0x08, 0x00000000, PPC_SPE),
8944 GEN_SPE(evslw,          speundef,      0x12, 0x08, 0x00000000, PPC_SPE),
8945 GEN_SPE(evslwi,         speundef,      0x13, 0x08, 0x00000000, PPC_SPE),
8946 GEN_SPE(evrlw,          evsplati,      0x14, 0x08, 0x00000000, PPC_SPE),
8947 GEN_SPE(evrlwi,         evsplatfi,     0x15, 0x08, 0x00000000, PPC_SPE),
8948 GEN_SPE(evmergehi,      evmergelo,     0x16, 0x08, 0x00000000, PPC_SPE),
8949 GEN_SPE(evmergehilo,    evmergelohi,   0x17, 0x08, 0x00000000, PPC_SPE),
8950 GEN_SPE(evcmpgtu,       evcmpgts,      0x18, 0x08, 0x00600000, PPC_SPE),
8951 GEN_SPE(evcmpltu,       evcmplts,      0x19, 0x08, 0x00600000, PPC_SPE),
8952 GEN_SPE(evcmpeq,        speundef,      0x1A, 0x08, 0x00600000, PPC_SPE),
8953
8954 GEN_SPE(evfsadd,        evfssub,       0x00, 0x0A, 0x00000000, PPC_SPE_SINGLE),
8955 GEN_SPE(evfsabs,        evfsnabs,      0x02, 0x0A, 0x0000F800, PPC_SPE_SINGLE),
8956 GEN_SPE(evfsneg,        speundef,      0x03, 0x0A, 0x0000F800, PPC_SPE_SINGLE),
8957 GEN_SPE(evfsmul,        evfsdiv,       0x04, 0x0A, 0x00000000, PPC_SPE_SINGLE),
8958 GEN_SPE(evfscmpgt,      evfscmplt,     0x06, 0x0A, 0x00600000, PPC_SPE_SINGLE),
8959 GEN_SPE(evfscmpeq,      speundef,      0x07, 0x0A, 0x00600000, PPC_SPE_SINGLE),
8960 GEN_SPE(evfscfui,       evfscfsi,      0x08, 0x0A, 0x00180000, PPC_SPE_SINGLE),
8961 GEN_SPE(evfscfuf,       evfscfsf,      0x09, 0x0A, 0x00180000, PPC_SPE_SINGLE),
8962 GEN_SPE(evfsctui,       evfsctsi,      0x0A, 0x0A, 0x00180000, PPC_SPE_SINGLE),
8963 GEN_SPE(evfsctuf,       evfsctsf,      0x0B, 0x0A, 0x00180000, PPC_SPE_SINGLE),
8964 GEN_SPE(evfsctuiz,      speundef,      0x0C, 0x0A, 0x00180000, PPC_SPE_SINGLE),
8965 GEN_SPE(evfsctsiz,      speundef,      0x0D, 0x0A, 0x00180000, PPC_SPE_SINGLE),
8966 GEN_SPE(evfststgt,      evfststlt,     0x0E, 0x0A, 0x00600000, PPC_SPE_SINGLE),
8967 GEN_SPE(evfststeq,      speundef,      0x0F, 0x0A, 0x00600000, PPC_SPE_SINGLE),
8968
8969 GEN_SPE(efsadd,         efssub,        0x00, 0x0B, 0x00000000, PPC_SPE_SINGLE),
8970 GEN_SPE(efsabs,         efsnabs,       0x02, 0x0B, 0x0000F800, PPC_SPE_SINGLE),
8971 GEN_SPE(efsneg,         speundef,      0x03, 0x0B, 0x0000F800, PPC_SPE_SINGLE),
8972 GEN_SPE(efsmul,         efsdiv,        0x04, 0x0B, 0x00000000, PPC_SPE_SINGLE),
8973 GEN_SPE(efscmpgt,       efscmplt,      0x06, 0x0B, 0x00600000, PPC_SPE_SINGLE),
8974 GEN_SPE(efscmpeq,       efscfd,        0x07, 0x0B, 0x00600000, PPC_SPE_SINGLE),
8975 GEN_SPE(efscfui,        efscfsi,       0x08, 0x0B, 0x00180000, PPC_SPE_SINGLE),
8976 GEN_SPE(efscfuf,        efscfsf,       0x09, 0x0B, 0x00180000, PPC_SPE_SINGLE),
8977 GEN_SPE(efsctui,        efsctsi,       0x0A, 0x0B, 0x00180000, PPC_SPE_SINGLE),
8978 GEN_SPE(efsctuf,        efsctsf,       0x0B, 0x0B, 0x00180000, PPC_SPE_SINGLE),
8979 GEN_SPE(efsctuiz,       speundef,      0x0C, 0x0B, 0x00180000, PPC_SPE_SINGLE),
8980 GEN_SPE(efsctsiz,       speundef,      0x0D, 0x0B, 0x00180000, PPC_SPE_SINGLE),
8981 GEN_SPE(efststgt,       efststlt,      0x0E, 0x0B, 0x00600000, PPC_SPE_SINGLE),
8982 GEN_SPE(efststeq,       speundef,      0x0F, 0x0B, 0x00600000, PPC_SPE_SINGLE),
8983
8984 GEN_SPE(efdadd,         efdsub,        0x10, 0x0B, 0x00000000, PPC_SPE_DOUBLE),
8985 GEN_SPE(efdcfuid,       efdcfsid,      0x11, 0x0B, 0x00180000, PPC_SPE_DOUBLE),
8986 GEN_SPE(efdabs,         efdnabs,       0x12, 0x0B, 0x0000F800, PPC_SPE_DOUBLE),
8987 GEN_SPE(efdneg,         speundef,      0x13, 0x0B, 0x0000F800, PPC_SPE_DOUBLE),
8988 GEN_SPE(efdmul,         efddiv,        0x14, 0x0B, 0x00000000, PPC_SPE_DOUBLE),
8989 GEN_SPE(efdctuidz,      efdctsidz,     0x15, 0x0B, 0x00180000, PPC_SPE_DOUBLE),
8990 GEN_SPE(efdcmpgt,       efdcmplt,      0x16, 0x0B, 0x00600000, PPC_SPE_DOUBLE),
8991 GEN_SPE(efdcmpeq,       efdcfs,        0x17, 0x0B, 0x00600000, PPC_SPE_DOUBLE),
8992 GEN_SPE(efdcfui,        efdcfsi,       0x18, 0x0B, 0x00180000, PPC_SPE_DOUBLE),
8993 GEN_SPE(efdcfuf,        efdcfsf,       0x19, 0x0B, 0x00180000, PPC_SPE_DOUBLE),
8994 GEN_SPE(efdctui,        efdctsi,       0x1A, 0x0B, 0x00180000, PPC_SPE_DOUBLE),
8995 GEN_SPE(efdctuf,        efdctsf,       0x1B, 0x0B, 0x00180000, PPC_SPE_DOUBLE),
8996 GEN_SPE(efdctuiz,       speundef,      0x1C, 0x0B, 0x00180000, PPC_SPE_DOUBLE),
8997 GEN_SPE(efdctsiz,       speundef,      0x1D, 0x0B, 0x00180000, PPC_SPE_DOUBLE),
8998 GEN_SPE(efdtstgt,       efdtstlt,      0x1E, 0x0B, 0x00600000, PPC_SPE_DOUBLE),
8999 GEN_SPE(efdtsteq,       speundef,      0x1F, 0x0B, 0x00600000, PPC_SPE_DOUBLE),
9000
9001 #undef GEN_SPEOP_LDST
9002 #define GEN_SPEOP_LDST(name, opc2, sh)                                        \
9003 GEN_HANDLER(name, 0x04, opc2, 0x0C, 0x00000000, PPC_SPE)
9004 GEN_SPEOP_LDST(evldd, 0x00, 3),
9005 GEN_SPEOP_LDST(evldw, 0x01, 3),
9006 GEN_SPEOP_LDST(evldh, 0x02, 3),
9007 GEN_SPEOP_LDST(evlhhesplat, 0x04, 1),
9008 GEN_SPEOP_LDST(evlhhousplat, 0x06, 1),
9009 GEN_SPEOP_LDST(evlhhossplat, 0x07, 1),
9010 GEN_SPEOP_LDST(evlwhe, 0x08, 2),
9011 GEN_SPEOP_LDST(evlwhou, 0x0A, 2),
9012 GEN_SPEOP_LDST(evlwhos, 0x0B, 2),
9013 GEN_SPEOP_LDST(evlwwsplat, 0x0C, 2),
9014 GEN_SPEOP_LDST(evlwhsplat, 0x0E, 2),
9015
9016 GEN_SPEOP_LDST(evstdd, 0x10, 3),
9017 GEN_SPEOP_LDST(evstdw, 0x11, 3),
9018 GEN_SPEOP_LDST(evstdh, 0x12, 3),
9019 GEN_SPEOP_LDST(evstwhe, 0x18, 2),
9020 GEN_SPEOP_LDST(evstwho, 0x1A, 2),
9021 GEN_SPEOP_LDST(evstwwe, 0x1C, 2),
9022 GEN_SPEOP_LDST(evstwwo, 0x1E, 2),
9023 };
9024
9025 #include "translate_init.c"
9026 #include "helper_regs.h"
9027
9028 /*****************************************************************************/
9029 /* Misc PowerPC helpers */
9030 void cpu_dump_state (CPUState *env, FILE *f, fprintf_function cpu_fprintf,
9031                      int flags)
9032 {
9033 #define RGPL  4
9034 #define RFPL  4
9035
9036     int i;
9037
9038     cpu_fprintf(f, "NIP " TARGET_FMT_lx "   LR " TARGET_FMT_lx " CTR "
9039                 TARGET_FMT_lx " XER " TARGET_FMT_lx "\n",
9040                 env->nip, env->lr, env->ctr, env->xer);
9041     cpu_fprintf(f, "MSR " TARGET_FMT_lx " HID0 " TARGET_FMT_lx "  HF "
9042                 TARGET_FMT_lx " idx %d\n", env->msr, env->spr[SPR_HID0],
9043                 env->hflags, env->mmu_idx);
9044 #if !defined(NO_TIMER_DUMP)
9045     cpu_fprintf(f, "TB %08" PRIu32 " %08" PRIu64
9046 #if !defined(CONFIG_USER_ONLY)
9047                 " DECR %08" PRIu32
9048 #endif
9049                 "\n",
9050                 cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
9051 #if !defined(CONFIG_USER_ONLY)
9052                 , cpu_ppc_load_decr(env)
9053 #endif
9054                 );
9055 #endif
9056     for (i = 0; i < 32; i++) {
9057         if ((i & (RGPL - 1)) == 0)
9058             cpu_fprintf(f, "GPR%02d", i);
9059         cpu_fprintf(f, " %016" PRIx64, ppc_dump_gpr(env, i));
9060         if ((i & (RGPL - 1)) == (RGPL - 1))
9061             cpu_fprintf(f, "\n");
9062     }
9063     cpu_fprintf(f, "CR ");
9064     for (i = 0; i < 8; i++)
9065         cpu_fprintf(f, "%01x", env->crf[i]);
9066     cpu_fprintf(f, "  [");
9067     for (i = 0; i < 8; i++) {
9068         char a = '-';
9069         if (env->crf[i] & 0x08)
9070             a = 'L';
9071         else if (env->crf[i] & 0x04)
9072             a = 'G';
9073         else if (env->crf[i] & 0x02)
9074             a = 'E';
9075         cpu_fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
9076     }
9077     cpu_fprintf(f, " ]             RES " TARGET_FMT_lx "\n",
9078                 env->reserve_addr);
9079     for (i = 0; i < 32; i++) {
9080         if ((i & (RFPL - 1)) == 0)
9081             cpu_fprintf(f, "FPR%02d", i);
9082         cpu_fprintf(f, " %016" PRIx64, *((uint64_t *)&env->fpr[i]));
9083         if ((i & (RFPL - 1)) == (RFPL - 1))
9084             cpu_fprintf(f, "\n");
9085     }
9086     cpu_fprintf(f, "FPSCR %08x\n", env->fpscr);
9087 #if !defined(CONFIG_USER_ONLY)
9088     cpu_fprintf(f, "SRR0 " TARGET_FMT_lx " SRR1 " TARGET_FMT_lx " SDR1 "
9089                 TARGET_FMT_lx "\n", env->spr[SPR_SRR0], env->spr[SPR_SRR1],
9090                 env->sdr1);
9091 #endif
9092
9093 #undef RGPL
9094 #undef RFPL
9095 }
9096
9097 void cpu_dump_statistics (CPUState *env, FILE*f, fprintf_function cpu_fprintf,
9098                           int flags)
9099 {
9100 #if defined(DO_PPC_STATISTICS)
9101     opc_handler_t **t1, **t2, **t3, *handler;
9102     int op1, op2, op3;
9103
9104     t1 = env->opcodes;
9105     for (op1 = 0; op1 < 64; op1++) {
9106         handler = t1[op1];
9107         if (is_indirect_opcode(handler)) {
9108             t2 = ind_table(handler);
9109             for (op2 = 0; op2 < 32; op2++) {
9110                 handler = t2[op2];
9111                 if (is_indirect_opcode(handler)) {
9112                     t3 = ind_table(handler);
9113                     for (op3 = 0; op3 < 32; op3++) {
9114                         handler = t3[op3];
9115                         if (handler->count == 0)
9116                             continue;
9117                         cpu_fprintf(f, "%02x %02x %02x (%02x %04d) %16s: "
9118                                     "%016" PRIx64 " %" PRId64 "\n",
9119                                     op1, op2, op3, op1, (op3 << 5) | op2,
9120                                     handler->oname,
9121                                     handler->count, handler->count);
9122                     }
9123                 } else {
9124                     if (handler->count == 0)
9125                         continue;
9126                     cpu_fprintf(f, "%02x %02x    (%02x %04d) %16s: "
9127                                 "%016" PRIx64 " %" PRId64 "\n",
9128                                 op1, op2, op1, op2, handler->oname,
9129                                 handler->count, handler->count);
9130                 }
9131             }
9132         } else {
9133             if (handler->count == 0)
9134                 continue;
9135             cpu_fprintf(f, "%02x       (%02x     ) %16s: %016" PRIx64
9136                         " %" PRId64 "\n",
9137                         op1, op1, handler->oname,
9138                         handler->count, handler->count);
9139         }
9140     }
9141 #endif
9142 }
9143
9144 /*****************************************************************************/
9145 static inline void gen_intermediate_code_internal(CPUState *env,
9146                                                   TranslationBlock *tb,
9147                                                   int search_pc)
9148 {
9149     DisasContext ctx, *ctxp = &ctx;
9150     opc_handler_t **table, *handler;
9151     target_ulong pc_start;
9152     uint16_t *gen_opc_end;
9153     CPUBreakpoint *bp;
9154     int j, lj = -1;
9155     int num_insns;
9156     int max_insns;
9157
9158     pc_start = tb->pc;
9159     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
9160     ctx.nip = pc_start;
9161     ctx.tb = tb;
9162     ctx.exception = POWERPC_EXCP_NONE;
9163     ctx.spr_cb = env->spr_cb;
9164     ctx.mem_idx = env->mmu_idx;
9165     ctx.access_type = -1;
9166     ctx.le_mode = env->hflags & (1 << MSR_LE) ? 1 : 0;
9167 #if defined(TARGET_PPC64)
9168     ctx.sf_mode = msr_sf;
9169 #endif
9170     ctx.fpu_enabled = msr_fp;
9171     if ((env->flags & POWERPC_FLAG_SPE) && msr_spe)
9172         ctx.spe_enabled = msr_spe;
9173     else
9174         ctx.spe_enabled = 0;
9175     if ((env->flags & POWERPC_FLAG_VRE) && msr_vr)
9176         ctx.altivec_enabled = msr_vr;
9177     else
9178         ctx.altivec_enabled = 0;
9179     if ((env->flags & POWERPC_FLAG_SE) && msr_se)
9180         ctx.singlestep_enabled = CPU_SINGLE_STEP;
9181     else
9182         ctx.singlestep_enabled = 0;
9183     if ((env->flags & POWERPC_FLAG_BE) && msr_be)
9184         ctx.singlestep_enabled |= CPU_BRANCH_STEP;
9185     if (unlikely(env->singlestep_enabled))
9186         ctx.singlestep_enabled |= GDBSTUB_SINGLE_STEP;
9187 #if defined (DO_SINGLE_STEP) && 0
9188     /* Single step trace mode */
9189     msr_se = 1;
9190 #endif
9191     num_insns = 0;
9192     max_insns = tb->cflags & CF_COUNT_MASK;
9193     if (max_insns == 0)
9194         max_insns = CF_COUNT_MASK;
9195
9196     gen_icount_start();
9197     /* Set env in case of segfault during code fetch */
9198     while (ctx.exception == POWERPC_EXCP_NONE && gen_opc_ptr < gen_opc_end) {
9199         if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
9200             QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
9201                 if (bp->pc == ctx.nip) {
9202                     gen_debug_exception(ctxp);
9203                     break;
9204                 }
9205             }
9206         }
9207         if (unlikely(search_pc)) {
9208             j = gen_opc_ptr - gen_opc_buf;
9209             if (lj < j) {
9210                 lj++;
9211                 while (lj < j)
9212                     gen_opc_instr_start[lj++] = 0;
9213             }
9214             gen_opc_pc[lj] = ctx.nip;
9215             gen_opc_instr_start[lj] = 1;
9216             gen_opc_icount[lj] = num_insns;
9217         }
9218         LOG_DISAS("----------------\n");
9219         LOG_DISAS("nip=" TARGET_FMT_lx " super=%d ir=%d\n",
9220                   ctx.nip, ctx.mem_idx, (int)msr_ir);
9221         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
9222             gen_io_start();
9223         if (unlikely(ctx.le_mode)) {
9224             ctx.opcode = bswap32(ldl_code(ctx.nip));
9225         } else {
9226             ctx.opcode = ldl_code(ctx.nip);
9227         }
9228         LOG_DISAS("translate opcode %08x (%02x %02x %02x) (%s)\n",
9229                     ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
9230                     opc3(ctx.opcode), little_endian ? "little" : "big");
9231         if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
9232             tcg_gen_debug_insn_start(ctx.nip);
9233         ctx.nip += 4;
9234         table = env->opcodes;
9235         num_insns++;
9236         handler = table[opc1(ctx.opcode)];
9237         if (is_indirect_opcode(handler)) {
9238             table = ind_table(handler);
9239             handler = table[opc2(ctx.opcode)];
9240             if (is_indirect_opcode(handler)) {
9241                 table = ind_table(handler);
9242                 handler = table[opc3(ctx.opcode)];
9243             }
9244         }
9245         /* Is opcode *REALLY* valid ? */
9246         if (unlikely(handler->handler == &gen_invalid)) {
9247             if (qemu_log_enabled()) {
9248                 qemu_log("invalid/unsupported opcode: "
9249                          "%02x - %02x - %02x (%08x) " TARGET_FMT_lx " %d\n",
9250                          opc1(ctx.opcode), opc2(ctx.opcode),
9251                          opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, (int)msr_ir);
9252             }
9253         } else {
9254             if (unlikely((ctx.opcode & handler->inval) != 0)) {
9255                 if (qemu_log_enabled()) {
9256                     qemu_log("invalid bits: %08x for opcode: "
9257                              "%02x - %02x - %02x (%08x) " TARGET_FMT_lx "\n",
9258                              ctx.opcode & handler->inval, opc1(ctx.opcode),
9259                              opc2(ctx.opcode), opc3(ctx.opcode),
9260                              ctx.opcode, ctx.nip - 4);
9261                 }
9262                 gen_inval_exception(ctxp, POWERPC_EXCP_INVAL_INVAL);
9263                 break;
9264             }
9265         }
9266         (*(handler->handler))(&ctx);
9267 #if defined(DO_PPC_STATISTICS)
9268         handler->count++;
9269 #endif
9270         /* Check trace mode exceptions */
9271         if (unlikely(ctx.singlestep_enabled & CPU_SINGLE_STEP &&
9272                      (ctx.nip <= 0x100 || ctx.nip > 0xF00) &&
9273                      ctx.exception != POWERPC_SYSCALL &&
9274                      ctx.exception != POWERPC_EXCP_TRAP &&
9275                      ctx.exception != POWERPC_EXCP_BRANCH)) {
9276             gen_exception(ctxp, POWERPC_EXCP_TRACE);
9277         } else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
9278                             (env->singlestep_enabled) ||
9279                             singlestep ||
9280                             num_insns >= max_insns)) {
9281             /* if we reach a page boundary or are single stepping, stop
9282              * generation
9283              */
9284             break;
9285         }
9286     }
9287     if (tb->cflags & CF_LAST_IO)
9288         gen_io_end();
9289     if (ctx.exception == POWERPC_EXCP_NONE) {
9290         gen_goto_tb(&ctx, 0, ctx.nip);
9291     } else if (ctx.exception != POWERPC_EXCP_BRANCH) {
9292         if (unlikely(env->singlestep_enabled)) {
9293             gen_debug_exception(ctxp);
9294         }
9295         /* Generate the return instruction */
9296         tcg_gen_exit_tb(0);
9297     }
9298     gen_icount_end(tb, num_insns);
9299     *gen_opc_ptr = INDEX_op_end;
9300     if (unlikely(search_pc)) {
9301         j = gen_opc_ptr - gen_opc_buf;
9302         lj++;
9303         while (lj <= j)
9304             gen_opc_instr_start[lj++] = 0;
9305     } else {
9306         tb->size = ctx.nip - pc_start;
9307         tb->icount = num_insns;
9308     }
9309 #if defined(DEBUG_DISAS)
9310     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
9311         int flags;
9312         flags = env->bfd_mach;
9313         flags |= ctx.le_mode << 16;
9314         qemu_log("IN: %s\n", lookup_symbol(pc_start));
9315         log_target_disas(pc_start, ctx.nip - pc_start, flags);
9316         qemu_log("\n");
9317     }
9318 #endif
9319 }
9320
9321 void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
9322 {
9323     gen_intermediate_code_internal(env, tb, 0);
9324 }
9325
9326 void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
9327 {
9328     gen_intermediate_code_internal(env, tb, 1);
9329 }
9330
9331 void gen_pc_load(CPUState *env, TranslationBlock *tb,
9332                 unsigned long searched_pc, int pc_pos, void *puc)
9333 {
9334     env->nip = gen_opc_pc[pc_pos];
9335 }
This page took 0.54159 seconds and 4 git commands to generate.