]> Git Repo - qemu.git/blob - target-ppc/translate.c
serial: Update parameters after load
[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_tlbwe(t0, cpu_gpr[rD(ctx->opcode)], 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 static inline void gen_load_gpr64(TCGv_i64 t, int reg)
6506 {
6507 #if defined(TARGET_PPC64)
6508     tcg_gen_mov_i64(t, cpu_gpr[reg]);
6509 #else
6510     tcg_gen_concat_i32_i64(t, cpu_gpr[reg], cpu_gprh[reg]);
6511 #endif
6512 }
6513
6514 static inline void gen_store_gpr64(int reg, TCGv_i64 t)
6515 {
6516 #if defined(TARGET_PPC64)
6517     tcg_gen_mov_i64(cpu_gpr[reg], t);
6518 #else
6519     TCGv_i64 tmp = tcg_temp_new_i64();
6520     tcg_gen_trunc_i64_i32(cpu_gpr[reg], t);
6521     tcg_gen_shri_i64(tmp, t, 32);
6522     tcg_gen_trunc_i64_i32(cpu_gprh[reg], tmp);
6523     tcg_temp_free_i64(tmp);
6524 #endif
6525 }
6526
6527 #define GEN_SPE(name0, name1, opc2, opc3, inval, type)                        \
6528 static void glue(gen_, name0##_##name1)(DisasContext *ctx)                    \
6529 {                                                                             \
6530     if (Rc(ctx->opcode))                                                      \
6531         gen_##name1(ctx);                                                     \
6532     else                                                                      \
6533         gen_##name0(ctx);                                                     \
6534 }
6535
6536 /* Handler for undefined SPE opcodes */
6537 static inline void gen_speundef(DisasContext *ctx)
6538 {
6539     gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
6540 }
6541
6542 /* SPE logic */
6543 #if defined(TARGET_PPC64)
6544 #define GEN_SPEOP_LOGIC2(name, tcg_op)                                        \
6545 static inline void gen_##name(DisasContext *ctx)                              \
6546 {                                                                             \
6547     if (unlikely(!ctx->spe_enabled)) {                                        \
6548         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6549         return;                                                               \
6550     }                                                                         \
6551     tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],                \
6552            cpu_gpr[rB(ctx->opcode)]);                                         \
6553 }
6554 #else
6555 #define GEN_SPEOP_LOGIC2(name, tcg_op)                                        \
6556 static inline void gen_##name(DisasContext *ctx)                              \
6557 {                                                                             \
6558     if (unlikely(!ctx->spe_enabled)) {                                        \
6559         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6560         return;                                                               \
6561     }                                                                         \
6562     tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],                \
6563            cpu_gpr[rB(ctx->opcode)]);                                         \
6564     tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],              \
6565            cpu_gprh[rB(ctx->opcode)]);                                        \
6566 }
6567 #endif
6568
6569 GEN_SPEOP_LOGIC2(evand, tcg_gen_and_tl);
6570 GEN_SPEOP_LOGIC2(evandc, tcg_gen_andc_tl);
6571 GEN_SPEOP_LOGIC2(evxor, tcg_gen_xor_tl);
6572 GEN_SPEOP_LOGIC2(evor, tcg_gen_or_tl);
6573 GEN_SPEOP_LOGIC2(evnor, tcg_gen_nor_tl);
6574 GEN_SPEOP_LOGIC2(eveqv, tcg_gen_eqv_tl);
6575 GEN_SPEOP_LOGIC2(evorc, tcg_gen_orc_tl);
6576 GEN_SPEOP_LOGIC2(evnand, tcg_gen_nand_tl);
6577
6578 /* SPE logic immediate */
6579 #if defined(TARGET_PPC64)
6580 #define GEN_SPEOP_TCG_LOGIC_IMM2(name, tcg_opi)                               \
6581 static inline void gen_##name(DisasContext *ctx)                              \
6582 {                                                                             \
6583     if (unlikely(!ctx->spe_enabled)) {                                        \
6584         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6585         return;                                                               \
6586     }                                                                         \
6587     TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
6588     TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
6589     TCGv_i64 t2 = tcg_temp_local_new_i64();                                   \
6590     tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]);                      \
6591     tcg_opi(t0, t0, rB(ctx->opcode));                                         \
6592     tcg_gen_shri_i64(t2, cpu_gpr[rA(ctx->opcode)], 32);                       \
6593     tcg_gen_trunc_i64_i32(t1, t2);                                            \
6594     tcg_temp_free_i64(t2);                                                    \
6595     tcg_opi(t1, t1, rB(ctx->opcode));                                         \
6596     tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);                 \
6597     tcg_temp_free_i32(t0);                                                    \
6598     tcg_temp_free_i32(t1);                                                    \
6599 }
6600 #else
6601 #define GEN_SPEOP_TCG_LOGIC_IMM2(name, tcg_opi)                               \
6602 static inline void gen_##name(DisasContext *ctx)                              \
6603 {                                                                             \
6604     if (unlikely(!ctx->spe_enabled)) {                                        \
6605         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6606         return;                                                               \
6607     }                                                                         \
6608     tcg_opi(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],               \
6609             rB(ctx->opcode));                                                 \
6610     tcg_opi(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],             \
6611             rB(ctx->opcode));                                                 \
6612 }
6613 #endif
6614 GEN_SPEOP_TCG_LOGIC_IMM2(evslwi, tcg_gen_shli_i32);
6615 GEN_SPEOP_TCG_LOGIC_IMM2(evsrwiu, tcg_gen_shri_i32);
6616 GEN_SPEOP_TCG_LOGIC_IMM2(evsrwis, tcg_gen_sari_i32);
6617 GEN_SPEOP_TCG_LOGIC_IMM2(evrlwi, tcg_gen_rotli_i32);
6618
6619 /* SPE arithmetic */
6620 #if defined(TARGET_PPC64)
6621 #define GEN_SPEOP_ARITH1(name, tcg_op)                                        \
6622 static inline void gen_##name(DisasContext *ctx)                              \
6623 {                                                                             \
6624     if (unlikely(!ctx->spe_enabled)) {                                        \
6625         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6626         return;                                                               \
6627     }                                                                         \
6628     TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
6629     TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
6630     TCGv_i64 t2 = tcg_temp_local_new_i64();                                   \
6631     tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]);                      \
6632     tcg_op(t0, t0);                                                           \
6633     tcg_gen_shri_i64(t2, cpu_gpr[rA(ctx->opcode)], 32);                       \
6634     tcg_gen_trunc_i64_i32(t1, t2);                                            \
6635     tcg_temp_free_i64(t2);                                                    \
6636     tcg_op(t1, t1);                                                           \
6637     tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);                 \
6638     tcg_temp_free_i32(t0);                                                    \
6639     tcg_temp_free_i32(t1);                                                    \
6640 }
6641 #else
6642 #define GEN_SPEOP_ARITH1(name, tcg_op)                                        \
6643 static inline void gen_##name(DisasContext *ctx)                              \
6644 {                                                                             \
6645     if (unlikely(!ctx->spe_enabled)) {                                        \
6646         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6647         return;                                                               \
6648     }                                                                         \
6649     tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);               \
6650     tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);             \
6651 }
6652 #endif
6653
6654 static inline void gen_op_evabs(TCGv_i32 ret, TCGv_i32 arg1)
6655 {
6656     int l1 = gen_new_label();
6657     int l2 = gen_new_label();
6658
6659     tcg_gen_brcondi_i32(TCG_COND_GE, arg1, 0, l1);
6660     tcg_gen_neg_i32(ret, arg1);
6661     tcg_gen_br(l2);
6662     gen_set_label(l1);
6663     tcg_gen_mov_i32(ret, arg1);
6664     gen_set_label(l2);
6665 }
6666 GEN_SPEOP_ARITH1(evabs, gen_op_evabs);
6667 GEN_SPEOP_ARITH1(evneg, tcg_gen_neg_i32);
6668 GEN_SPEOP_ARITH1(evextsb, tcg_gen_ext8s_i32);
6669 GEN_SPEOP_ARITH1(evextsh, tcg_gen_ext16s_i32);
6670 static inline void gen_op_evrndw(TCGv_i32 ret, TCGv_i32 arg1)
6671 {
6672     tcg_gen_addi_i32(ret, arg1, 0x8000);
6673     tcg_gen_ext16u_i32(ret, ret);
6674 }
6675 GEN_SPEOP_ARITH1(evrndw, gen_op_evrndw);
6676 GEN_SPEOP_ARITH1(evcntlsw, gen_helper_cntlsw32);
6677 GEN_SPEOP_ARITH1(evcntlzw, gen_helper_cntlzw32);
6678
6679 #if defined(TARGET_PPC64)
6680 #define GEN_SPEOP_ARITH2(name, tcg_op)                                        \
6681 static inline void gen_##name(DisasContext *ctx)                              \
6682 {                                                                             \
6683     if (unlikely(!ctx->spe_enabled)) {                                        \
6684         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6685         return;                                                               \
6686     }                                                                         \
6687     TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
6688     TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
6689     TCGv_i32 t2 = tcg_temp_local_new_i32();                                   \
6690     TCGv_i64 t3 = tcg_temp_local_new_i64();                                   \
6691     tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]);                      \
6692     tcg_gen_trunc_i64_i32(t2, cpu_gpr[rB(ctx->opcode)]);                      \
6693     tcg_op(t0, t0, t2);                                                       \
6694     tcg_gen_shri_i64(t3, cpu_gpr[rA(ctx->opcode)], 32);                       \
6695     tcg_gen_trunc_i64_i32(t1, t3);                                            \
6696     tcg_gen_shri_i64(t3, cpu_gpr[rB(ctx->opcode)], 32);                       \
6697     tcg_gen_trunc_i64_i32(t2, t3);                                            \
6698     tcg_temp_free_i64(t3);                                                    \
6699     tcg_op(t1, t1, t2);                                                       \
6700     tcg_temp_free_i32(t2);                                                    \
6701     tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);                 \
6702     tcg_temp_free_i32(t0);                                                    \
6703     tcg_temp_free_i32(t1);                                                    \
6704 }
6705 #else
6706 #define GEN_SPEOP_ARITH2(name, tcg_op)                                        \
6707 static inline void gen_##name(DisasContext *ctx)                              \
6708 {                                                                             \
6709     if (unlikely(!ctx->spe_enabled)) {                                        \
6710         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6711         return;                                                               \
6712     }                                                                         \
6713     tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],                \
6714            cpu_gpr[rB(ctx->opcode)]);                                         \
6715     tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],              \
6716            cpu_gprh[rB(ctx->opcode)]);                                        \
6717 }
6718 #endif
6719
6720 static inline void gen_op_evsrwu(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
6721 {
6722     TCGv_i32 t0;
6723     int l1, l2;
6724
6725     l1 = gen_new_label();
6726     l2 = gen_new_label();
6727     t0 = tcg_temp_local_new_i32();
6728     /* No error here: 6 bits are used */
6729     tcg_gen_andi_i32(t0, arg2, 0x3F);
6730     tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1);
6731     tcg_gen_shr_i32(ret, arg1, t0);
6732     tcg_gen_br(l2);
6733     gen_set_label(l1);
6734     tcg_gen_movi_i32(ret, 0);
6735     gen_set_label(l2);
6736     tcg_temp_free_i32(t0);
6737 }
6738 GEN_SPEOP_ARITH2(evsrwu, gen_op_evsrwu);
6739 static inline void gen_op_evsrws(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
6740 {
6741     TCGv_i32 t0;
6742     int l1, l2;
6743
6744     l1 = gen_new_label();
6745     l2 = gen_new_label();
6746     t0 = tcg_temp_local_new_i32();
6747     /* No error here: 6 bits are used */
6748     tcg_gen_andi_i32(t0, arg2, 0x3F);
6749     tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1);
6750     tcg_gen_sar_i32(ret, arg1, t0);
6751     tcg_gen_br(l2);
6752     gen_set_label(l1);
6753     tcg_gen_movi_i32(ret, 0);
6754     gen_set_label(l2);
6755     tcg_temp_free_i32(t0);
6756 }
6757 GEN_SPEOP_ARITH2(evsrws, gen_op_evsrws);
6758 static inline void gen_op_evslw(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
6759 {
6760     TCGv_i32 t0;
6761     int l1, l2;
6762
6763     l1 = gen_new_label();
6764     l2 = gen_new_label();
6765     t0 = tcg_temp_local_new_i32();
6766     /* No error here: 6 bits are used */
6767     tcg_gen_andi_i32(t0, arg2, 0x3F);
6768     tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1);
6769     tcg_gen_shl_i32(ret, arg1, t0);
6770     tcg_gen_br(l2);
6771     gen_set_label(l1);
6772     tcg_gen_movi_i32(ret, 0);
6773     gen_set_label(l2);
6774     tcg_temp_free_i32(t0);
6775 }
6776 GEN_SPEOP_ARITH2(evslw, gen_op_evslw);
6777 static inline void gen_op_evrlw(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
6778 {
6779     TCGv_i32 t0 = tcg_temp_new_i32();
6780     tcg_gen_andi_i32(t0, arg2, 0x1F);
6781     tcg_gen_rotl_i32(ret, arg1, t0);
6782     tcg_temp_free_i32(t0);
6783 }
6784 GEN_SPEOP_ARITH2(evrlw, gen_op_evrlw);
6785 static inline void gen_evmergehi(DisasContext *ctx)
6786 {
6787     if (unlikely(!ctx->spe_enabled)) {
6788         gen_exception(ctx, POWERPC_EXCP_APU);
6789         return;
6790     }
6791 #if defined(TARGET_PPC64)
6792     TCGv t0 = tcg_temp_new();
6793     TCGv t1 = tcg_temp_new();
6794     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 32);
6795     tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], 0xFFFFFFFF0000000ULL);
6796     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
6797     tcg_temp_free(t0);
6798     tcg_temp_free(t1);
6799 #else
6800     tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
6801     tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
6802 #endif
6803 }
6804 GEN_SPEOP_ARITH2(evaddw, tcg_gen_add_i32);
6805 static inline void gen_op_evsubf(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
6806 {
6807     tcg_gen_sub_i32(ret, arg2, arg1);
6808 }
6809 GEN_SPEOP_ARITH2(evsubfw, gen_op_evsubf);
6810
6811 /* SPE arithmetic immediate */
6812 #if defined(TARGET_PPC64)
6813 #define GEN_SPEOP_ARITH_IMM2(name, tcg_op)                                    \
6814 static inline void gen_##name(DisasContext *ctx)                              \
6815 {                                                                             \
6816     if (unlikely(!ctx->spe_enabled)) {                                        \
6817         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6818         return;                                                               \
6819     }                                                                         \
6820     TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
6821     TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
6822     TCGv_i64 t2 = tcg_temp_local_new_i64();                                   \
6823     tcg_gen_trunc_i64_i32(t0, cpu_gpr[rB(ctx->opcode)]);                      \
6824     tcg_op(t0, t0, rA(ctx->opcode));                                          \
6825     tcg_gen_shri_i64(t2, cpu_gpr[rB(ctx->opcode)], 32);                       \
6826     tcg_gen_trunc_i64_i32(t1, t2);                                            \
6827     tcg_temp_free_i64(t2);                                                    \
6828     tcg_op(t1, t1, rA(ctx->opcode));                                          \
6829     tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);                 \
6830     tcg_temp_free_i32(t0);                                                    \
6831     tcg_temp_free_i32(t1);                                                    \
6832 }
6833 #else
6834 #define GEN_SPEOP_ARITH_IMM2(name, tcg_op)                                    \
6835 static inline void gen_##name(DisasContext *ctx)                              \
6836 {                                                                             \
6837     if (unlikely(!ctx->spe_enabled)) {                                        \
6838         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6839         return;                                                               \
6840     }                                                                         \
6841     tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],                \
6842            rA(ctx->opcode));                                                  \
6843     tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)],              \
6844            rA(ctx->opcode));                                                  \
6845 }
6846 #endif
6847 GEN_SPEOP_ARITH_IMM2(evaddiw, tcg_gen_addi_i32);
6848 GEN_SPEOP_ARITH_IMM2(evsubifw, tcg_gen_subi_i32);
6849
6850 /* SPE comparison */
6851 #if defined(TARGET_PPC64)
6852 #define GEN_SPEOP_COMP(name, tcg_cond)                                        \
6853 static inline void gen_##name(DisasContext *ctx)                              \
6854 {                                                                             \
6855     if (unlikely(!ctx->spe_enabled)) {                                        \
6856         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6857         return;                                                               \
6858     }                                                                         \
6859     int l1 = gen_new_label();                                                 \
6860     int l2 = gen_new_label();                                                 \
6861     int l3 = gen_new_label();                                                 \
6862     int l4 = gen_new_label();                                                 \
6863     TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
6864     TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
6865     TCGv_i64 t2 = tcg_temp_local_new_i64();                                   \
6866     tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]);                      \
6867     tcg_gen_trunc_i64_i32(t1, cpu_gpr[rB(ctx->opcode)]);                      \
6868     tcg_gen_brcond_i32(tcg_cond, t0, t1, l1);                                 \
6869     tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)], 0);                          \
6870     tcg_gen_br(l2);                                                           \
6871     gen_set_label(l1);                                                        \
6872     tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)],                              \
6873                      CRF_CL | CRF_CH_OR_CL | CRF_CH_AND_CL);                  \
6874     gen_set_label(l2);                                                        \
6875     tcg_gen_shri_i64(t2, cpu_gpr[rA(ctx->opcode)], 32);                       \
6876     tcg_gen_trunc_i64_i32(t0, t2);                                            \
6877     tcg_gen_shri_i64(t2, cpu_gpr[rB(ctx->opcode)], 32);                       \
6878     tcg_gen_trunc_i64_i32(t1, t2);                                            \
6879     tcg_temp_free_i64(t2);                                                    \
6880     tcg_gen_brcond_i32(tcg_cond, t0, t1, l3);                                 \
6881     tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)],  \
6882                      ~(CRF_CH | CRF_CH_AND_CL));                              \
6883     tcg_gen_br(l4);                                                           \
6884     gen_set_label(l3);                                                        \
6885     tcg_gen_ori_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)],   \
6886                     CRF_CH | CRF_CH_OR_CL);                                   \
6887     gen_set_label(l4);                                                        \
6888     tcg_temp_free_i32(t0);                                                    \
6889     tcg_temp_free_i32(t1);                                                    \
6890 }
6891 #else
6892 #define GEN_SPEOP_COMP(name, tcg_cond)                                        \
6893 static inline void gen_##name(DisasContext *ctx)                              \
6894 {                                                                             \
6895     if (unlikely(!ctx->spe_enabled)) {                                        \
6896         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6897         return;                                                               \
6898     }                                                                         \
6899     int l1 = gen_new_label();                                                 \
6900     int l2 = gen_new_label();                                                 \
6901     int l3 = gen_new_label();                                                 \
6902     int l4 = gen_new_label();                                                 \
6903                                                                               \
6904     tcg_gen_brcond_i32(tcg_cond, cpu_gpr[rA(ctx->opcode)],                    \
6905                        cpu_gpr[rB(ctx->opcode)], l1);                         \
6906     tcg_gen_movi_tl(cpu_crf[crfD(ctx->opcode)], 0);                           \
6907     tcg_gen_br(l2);                                                           \
6908     gen_set_label(l1);                                                        \
6909     tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)],                              \
6910                      CRF_CL | CRF_CH_OR_CL | CRF_CH_AND_CL);                  \
6911     gen_set_label(l2);                                                        \
6912     tcg_gen_brcond_i32(tcg_cond, cpu_gprh[rA(ctx->opcode)],                   \
6913                        cpu_gprh[rB(ctx->opcode)], 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 }
6922 #endif
6923 GEN_SPEOP_COMP(evcmpgtu, TCG_COND_GTU);
6924 GEN_SPEOP_COMP(evcmpgts, TCG_COND_GT);
6925 GEN_SPEOP_COMP(evcmpltu, TCG_COND_LTU);
6926 GEN_SPEOP_COMP(evcmplts, TCG_COND_LT);
6927 GEN_SPEOP_COMP(evcmpeq, TCG_COND_EQ);
6928
6929 /* SPE misc */
6930 static inline void gen_brinc(DisasContext *ctx)
6931 {
6932     /* Note: brinc is usable even if SPE is disabled */
6933     gen_helper_brinc(cpu_gpr[rD(ctx->opcode)],
6934                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
6935 }
6936 static inline void gen_evmergelo(DisasContext *ctx)
6937 {
6938     if (unlikely(!ctx->spe_enabled)) {
6939         gen_exception(ctx, POWERPC_EXCP_APU);
6940         return;
6941     }
6942 #if defined(TARGET_PPC64)
6943     TCGv t0 = tcg_temp_new();
6944     TCGv t1 = tcg_temp_new();
6945     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x00000000FFFFFFFFLL);
6946     tcg_gen_shli_tl(t1, cpu_gpr[rA(ctx->opcode)], 32);
6947     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
6948     tcg_temp_free(t0);
6949     tcg_temp_free(t1);
6950 #else
6951     tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
6952     tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
6953 #endif
6954 }
6955 static inline void gen_evmergehilo(DisasContext *ctx)
6956 {
6957     if (unlikely(!ctx->spe_enabled)) {
6958         gen_exception(ctx, POWERPC_EXCP_APU);
6959         return;
6960     }
6961 #if defined(TARGET_PPC64)
6962     TCGv t0 = tcg_temp_new();
6963     TCGv t1 = tcg_temp_new();
6964     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x00000000FFFFFFFFLL);
6965     tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], 0xFFFFFFFF0000000ULL);
6966     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
6967     tcg_temp_free(t0);
6968     tcg_temp_free(t1);
6969 #else
6970     tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
6971     tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
6972 #endif
6973 }
6974 static inline void gen_evmergelohi(DisasContext *ctx)
6975 {
6976     if (unlikely(!ctx->spe_enabled)) {
6977         gen_exception(ctx, POWERPC_EXCP_APU);
6978         return;
6979     }
6980 #if defined(TARGET_PPC64)
6981     TCGv t0 = tcg_temp_new();
6982     TCGv t1 = tcg_temp_new();
6983     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 32);
6984     tcg_gen_shli_tl(t1, cpu_gpr[rA(ctx->opcode)], 32);
6985     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
6986     tcg_temp_free(t0);
6987     tcg_temp_free(t1);
6988 #else
6989     if (rD(ctx->opcode) == rA(ctx->opcode)) {
6990         TCGv_i32 tmp = tcg_temp_new_i32();
6991         tcg_gen_mov_i32(tmp, cpu_gpr[rA(ctx->opcode)]);
6992         tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
6993         tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], tmp);
6994         tcg_temp_free_i32(tmp);
6995     } else {
6996         tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
6997         tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
6998     }
6999 #endif
7000 }
7001 static inline void gen_evsplati(DisasContext *ctx)
7002 {
7003     uint64_t imm = ((int32_t)(rA(ctx->opcode) << 27)) >> 27;
7004
7005 #if defined(TARGET_PPC64)
7006     tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], (imm << 32) | imm);
7007 #else
7008     tcg_gen_movi_i32(cpu_gpr[rD(ctx->opcode)], imm);
7009     tcg_gen_movi_i32(cpu_gprh[rD(ctx->opcode)], imm);
7010 #endif
7011 }
7012 static inline void gen_evsplatfi(DisasContext *ctx)
7013 {
7014     uint64_t imm = rA(ctx->opcode) << 27;
7015
7016 #if defined(TARGET_PPC64)
7017     tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], (imm << 32) | imm);
7018 #else
7019     tcg_gen_movi_i32(cpu_gpr[rD(ctx->opcode)], imm);
7020     tcg_gen_movi_i32(cpu_gprh[rD(ctx->opcode)], imm);
7021 #endif
7022 }
7023
7024 static inline void gen_evsel(DisasContext *ctx)
7025 {
7026     int l1 = gen_new_label();
7027     int l2 = gen_new_label();
7028     int l3 = gen_new_label();
7029     int l4 = gen_new_label();
7030     TCGv_i32 t0 = tcg_temp_local_new_i32();
7031 #if defined(TARGET_PPC64)
7032     TCGv t1 = tcg_temp_local_new();
7033     TCGv t2 = tcg_temp_local_new();
7034 #endif
7035     tcg_gen_andi_i32(t0, cpu_crf[ctx->opcode & 0x07], 1 << 3);
7036     tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
7037 #if defined(TARGET_PPC64)
7038     tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], 0xFFFFFFFF00000000ULL);
7039 #else
7040     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
7041 #endif
7042     tcg_gen_br(l2);
7043     gen_set_label(l1);
7044 #if defined(TARGET_PPC64)
7045     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0xFFFFFFFF00000000ULL);
7046 #else
7047     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
7048 #endif
7049     gen_set_label(l2);
7050     tcg_gen_andi_i32(t0, cpu_crf[ctx->opcode & 0x07], 1 << 2);
7051     tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l3);
7052 #if defined(TARGET_PPC64)
7053     tcg_gen_andi_tl(t2, cpu_gpr[rA(ctx->opcode)], 0x00000000FFFFFFFFULL);
7054 #else
7055     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
7056 #endif
7057     tcg_gen_br(l4);
7058     gen_set_label(l3);
7059 #if defined(TARGET_PPC64)
7060     tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x00000000FFFFFFFFULL);
7061 #else
7062     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
7063 #endif
7064     gen_set_label(l4);
7065     tcg_temp_free_i32(t0);
7066 #if defined(TARGET_PPC64)
7067     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t1, t2);
7068     tcg_temp_free(t1);
7069     tcg_temp_free(t2);
7070 #endif
7071 }
7072
7073 static void gen_evsel0(DisasContext *ctx)
7074 {
7075     gen_evsel(ctx);
7076 }
7077
7078 static void gen_evsel1(DisasContext *ctx)
7079 {
7080     gen_evsel(ctx);
7081 }
7082
7083 static void gen_evsel2(DisasContext *ctx)
7084 {
7085     gen_evsel(ctx);
7086 }
7087
7088 static void gen_evsel3(DisasContext *ctx)
7089 {
7090     gen_evsel(ctx);
7091 }
7092
7093 GEN_SPE(evaddw,         speundef,      0x00, 0x08, 0x00000000, PPC_SPE); ////
7094 GEN_SPE(evaddiw,        speundef,      0x01, 0x08, 0x00000000, PPC_SPE);
7095 GEN_SPE(evsubfw,        speundef,      0x02, 0x08, 0x00000000, PPC_SPE); ////
7096 GEN_SPE(evsubifw,       speundef,      0x03, 0x08, 0x00000000, PPC_SPE);
7097 GEN_SPE(evabs,          evneg,         0x04, 0x08, 0x0000F800, PPC_SPE); ////
7098 GEN_SPE(evextsb,        evextsh,       0x05, 0x08, 0x0000F800, PPC_SPE); ////
7099 GEN_SPE(evrndw,         evcntlzw,      0x06, 0x08, 0x0000F800, PPC_SPE); ////
7100 GEN_SPE(evcntlsw,       brinc,         0x07, 0x08, 0x00000000, PPC_SPE); //
7101 GEN_SPE(speundef,       evand,         0x08, 0x08, 0x00000000, PPC_SPE); ////
7102 GEN_SPE(evandc,         speundef,      0x09, 0x08, 0x00000000, PPC_SPE); ////
7103 GEN_SPE(evxor,          evor,          0x0B, 0x08, 0x00000000, PPC_SPE); ////
7104 GEN_SPE(evnor,          eveqv,         0x0C, 0x08, 0x00000000, PPC_SPE); ////
7105 GEN_SPE(speundef,       evorc,         0x0D, 0x08, 0x00000000, PPC_SPE); ////
7106 GEN_SPE(evnand,         speundef,      0x0F, 0x08, 0x00000000, PPC_SPE); ////
7107 GEN_SPE(evsrwu,         evsrws,        0x10, 0x08, 0x00000000, PPC_SPE); ////
7108 GEN_SPE(evsrwiu,        evsrwis,       0x11, 0x08, 0x00000000, PPC_SPE);
7109 GEN_SPE(evslw,          speundef,      0x12, 0x08, 0x00000000, PPC_SPE); ////
7110 GEN_SPE(evslwi,         speundef,      0x13, 0x08, 0x00000000, PPC_SPE);
7111 GEN_SPE(evrlw,          evsplati,      0x14, 0x08, 0x00000000, PPC_SPE); //
7112 GEN_SPE(evrlwi,         evsplatfi,     0x15, 0x08, 0x00000000, PPC_SPE);
7113 GEN_SPE(evmergehi,      evmergelo,     0x16, 0x08, 0x00000000, PPC_SPE); ////
7114 GEN_SPE(evmergehilo,    evmergelohi,   0x17, 0x08, 0x00000000, PPC_SPE); ////
7115 GEN_SPE(evcmpgtu,       evcmpgts,      0x18, 0x08, 0x00600000, PPC_SPE); ////
7116 GEN_SPE(evcmpltu,       evcmplts,      0x19, 0x08, 0x00600000, PPC_SPE); ////
7117 GEN_SPE(evcmpeq,        speundef,      0x1A, 0x08, 0x00600000, PPC_SPE); ////
7118
7119 /* SPE load and stores */
7120 static inline void gen_addr_spe_imm_index(DisasContext *ctx, TCGv EA, int sh)
7121 {
7122     target_ulong uimm = rB(ctx->opcode);
7123
7124     if (rA(ctx->opcode) == 0) {
7125         tcg_gen_movi_tl(EA, uimm << sh);
7126     } else {
7127         tcg_gen_addi_tl(EA, cpu_gpr[rA(ctx->opcode)], uimm << sh);
7128 #if defined(TARGET_PPC64)
7129         if (!ctx->sf_mode) {
7130             tcg_gen_ext32u_tl(EA, EA);
7131         }
7132 #endif
7133     }
7134 }
7135
7136 static inline void gen_op_evldd(DisasContext *ctx, TCGv addr)
7137 {
7138 #if defined(TARGET_PPC64)
7139     gen_qemu_ld64(ctx, cpu_gpr[rD(ctx->opcode)], addr);
7140 #else
7141     TCGv_i64 t0 = tcg_temp_new_i64();
7142     gen_qemu_ld64(ctx, t0, addr);
7143     tcg_gen_trunc_i64_i32(cpu_gpr[rD(ctx->opcode)], t0);
7144     tcg_gen_shri_i64(t0, t0, 32);
7145     tcg_gen_trunc_i64_i32(cpu_gprh[rD(ctx->opcode)], t0);
7146     tcg_temp_free_i64(t0);
7147 #endif
7148 }
7149
7150 static inline void gen_op_evldw(DisasContext *ctx, TCGv addr)
7151 {
7152 #if defined(TARGET_PPC64)
7153     TCGv t0 = tcg_temp_new();
7154     gen_qemu_ld32u(ctx, t0, addr);
7155     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32);
7156     gen_addr_add(ctx, addr, addr, 4);
7157     gen_qemu_ld32u(ctx, t0, addr);
7158     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7159     tcg_temp_free(t0);
7160 #else
7161     gen_qemu_ld32u(ctx, cpu_gprh[rD(ctx->opcode)], addr);
7162     gen_addr_add(ctx, addr, addr, 4);
7163     gen_qemu_ld32u(ctx, cpu_gpr[rD(ctx->opcode)], addr);
7164 #endif
7165 }
7166
7167 static inline void gen_op_evldh(DisasContext *ctx, TCGv addr)
7168 {
7169     TCGv t0 = tcg_temp_new();
7170 #if defined(TARGET_PPC64)
7171     gen_qemu_ld16u(ctx, t0, addr);
7172     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48);
7173     gen_addr_add(ctx, addr, addr, 2);
7174     gen_qemu_ld16u(ctx, t0, addr);
7175     tcg_gen_shli_tl(t0, t0, 32);
7176     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7177     gen_addr_add(ctx, addr, addr, 2);
7178     gen_qemu_ld16u(ctx, t0, addr);
7179     tcg_gen_shli_tl(t0, t0, 16);
7180     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7181     gen_addr_add(ctx, addr, addr, 2);
7182     gen_qemu_ld16u(ctx, t0, addr);
7183     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7184 #else
7185     gen_qemu_ld16u(ctx, t0, addr);
7186     tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
7187     gen_addr_add(ctx, addr, addr, 2);
7188     gen_qemu_ld16u(ctx, t0, addr);
7189     tcg_gen_or_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0);
7190     gen_addr_add(ctx, addr, addr, 2);
7191     gen_qemu_ld16u(ctx, t0, addr);
7192     tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
7193     gen_addr_add(ctx, addr, addr, 2);
7194     gen_qemu_ld16u(ctx, t0, addr);
7195     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7196 #endif
7197     tcg_temp_free(t0);
7198 }
7199
7200 static inline void gen_op_evlhhesplat(DisasContext *ctx, TCGv addr)
7201 {
7202     TCGv t0 = tcg_temp_new();
7203     gen_qemu_ld16u(ctx, t0, addr);
7204 #if defined(TARGET_PPC64)
7205     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48);
7206     tcg_gen_shli_tl(t0, t0, 16);
7207     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7208 #else
7209     tcg_gen_shli_tl(t0, t0, 16);
7210     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
7211     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
7212 #endif
7213     tcg_temp_free(t0);
7214 }
7215
7216 static inline void gen_op_evlhhousplat(DisasContext *ctx, TCGv addr)
7217 {
7218     TCGv t0 = tcg_temp_new();
7219     gen_qemu_ld16u(ctx, t0, addr);
7220 #if defined(TARGET_PPC64)
7221     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32);
7222     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7223 #else
7224     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
7225     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
7226 #endif
7227     tcg_temp_free(t0);
7228 }
7229
7230 static inline void gen_op_evlhhossplat(DisasContext *ctx, TCGv addr)
7231 {
7232     TCGv t0 = tcg_temp_new();
7233     gen_qemu_ld16s(ctx, t0, addr);
7234 #if defined(TARGET_PPC64)
7235     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32);
7236     tcg_gen_ext32u_tl(t0, t0);
7237     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7238 #else
7239     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
7240     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
7241 #endif
7242     tcg_temp_free(t0);
7243 }
7244
7245 static inline void gen_op_evlwhe(DisasContext *ctx, TCGv addr)
7246 {
7247     TCGv t0 = tcg_temp_new();
7248 #if defined(TARGET_PPC64)
7249     gen_qemu_ld16u(ctx, t0, addr);
7250     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48);
7251     gen_addr_add(ctx, addr, addr, 2);
7252     gen_qemu_ld16u(ctx, t0, addr);
7253     tcg_gen_shli_tl(t0, t0, 16);
7254     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7255 #else
7256     gen_qemu_ld16u(ctx, t0, addr);
7257     tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
7258     gen_addr_add(ctx, addr, addr, 2);
7259     gen_qemu_ld16u(ctx, t0, addr);
7260     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 16);
7261 #endif
7262     tcg_temp_free(t0);
7263 }
7264
7265 static inline void gen_op_evlwhou(DisasContext *ctx, TCGv addr)
7266 {
7267 #if defined(TARGET_PPC64)
7268     TCGv t0 = tcg_temp_new();
7269     gen_qemu_ld16u(ctx, cpu_gpr[rD(ctx->opcode)], addr);
7270     gen_addr_add(ctx, addr, addr, 2);
7271     gen_qemu_ld16u(ctx, t0, addr);
7272     tcg_gen_shli_tl(t0, t0, 32);
7273     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7274     tcg_temp_free(t0);
7275 #else
7276     gen_qemu_ld16u(ctx, cpu_gprh[rD(ctx->opcode)], addr);
7277     gen_addr_add(ctx, addr, addr, 2);
7278     gen_qemu_ld16u(ctx, cpu_gpr[rD(ctx->opcode)], addr);
7279 #endif
7280 }
7281
7282 static inline void gen_op_evlwhos(DisasContext *ctx, TCGv addr)
7283 {
7284 #if defined(TARGET_PPC64)
7285     TCGv t0 = tcg_temp_new();
7286     gen_qemu_ld16s(ctx, t0, addr);
7287     tcg_gen_ext32u_tl(cpu_gpr[rD(ctx->opcode)], t0);
7288     gen_addr_add(ctx, addr, addr, 2);
7289     gen_qemu_ld16s(ctx, t0, addr);
7290     tcg_gen_shli_tl(t0, t0, 32);
7291     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7292     tcg_temp_free(t0);
7293 #else
7294     gen_qemu_ld16s(ctx, cpu_gprh[rD(ctx->opcode)], addr);
7295     gen_addr_add(ctx, addr, addr, 2);
7296     gen_qemu_ld16s(ctx, cpu_gpr[rD(ctx->opcode)], addr);
7297 #endif
7298 }
7299
7300 static inline void gen_op_evlwwsplat(DisasContext *ctx, TCGv addr)
7301 {
7302     TCGv t0 = tcg_temp_new();
7303     gen_qemu_ld32u(ctx, t0, addr);
7304 #if defined(TARGET_PPC64)
7305     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32);
7306     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7307 #else
7308     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
7309     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
7310 #endif
7311     tcg_temp_free(t0);
7312 }
7313
7314 static inline void gen_op_evlwhsplat(DisasContext *ctx, TCGv addr)
7315 {
7316     TCGv t0 = tcg_temp_new();
7317 #if defined(TARGET_PPC64)
7318     gen_qemu_ld16u(ctx, t0, addr);
7319     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48);
7320     tcg_gen_shli_tl(t0, t0, 32);
7321     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7322     gen_addr_add(ctx, addr, addr, 2);
7323     gen_qemu_ld16u(ctx, t0, addr);
7324     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7325     tcg_gen_shli_tl(t0, t0, 16);
7326     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7327 #else
7328     gen_qemu_ld16u(ctx, t0, addr);
7329     tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
7330     tcg_gen_or_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0);
7331     gen_addr_add(ctx, addr, addr, 2);
7332     gen_qemu_ld16u(ctx, t0, addr);
7333     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 16);
7334     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0);
7335 #endif
7336     tcg_temp_free(t0);
7337 }
7338
7339 static inline void gen_op_evstdd(DisasContext *ctx, TCGv addr)
7340 {
7341 #if defined(TARGET_PPC64)
7342     gen_qemu_st64(ctx, cpu_gpr[rS(ctx->opcode)], addr);
7343 #else
7344     TCGv_i64 t0 = tcg_temp_new_i64();
7345     tcg_gen_concat_i32_i64(t0, cpu_gpr[rS(ctx->opcode)], cpu_gprh[rS(ctx->opcode)]);
7346     gen_qemu_st64(ctx, t0, addr);
7347     tcg_temp_free_i64(t0);
7348 #endif
7349 }
7350
7351 static inline void gen_op_evstdw(DisasContext *ctx, TCGv addr)
7352 {
7353 #if defined(TARGET_PPC64)
7354     TCGv t0 = tcg_temp_new();
7355     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32);
7356     gen_qemu_st32(ctx, t0, addr);
7357     tcg_temp_free(t0);
7358 #else
7359     gen_qemu_st32(ctx, cpu_gprh[rS(ctx->opcode)], addr);
7360 #endif
7361     gen_addr_add(ctx, addr, addr, 4);
7362     gen_qemu_st32(ctx, cpu_gpr[rS(ctx->opcode)], addr);
7363 }
7364
7365 static inline void gen_op_evstdh(DisasContext *ctx, TCGv addr)
7366 {
7367     TCGv t0 = tcg_temp_new();
7368 #if defined(TARGET_PPC64)
7369     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 48);
7370 #else
7371     tcg_gen_shri_tl(t0, cpu_gprh[rS(ctx->opcode)], 16);
7372 #endif
7373     gen_qemu_st16(ctx, t0, addr);
7374     gen_addr_add(ctx, addr, addr, 2);
7375 #if defined(TARGET_PPC64)
7376     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32);
7377     gen_qemu_st16(ctx, t0, addr);
7378 #else
7379     gen_qemu_st16(ctx, cpu_gprh[rS(ctx->opcode)], addr);
7380 #endif
7381     gen_addr_add(ctx, addr, addr, 2);
7382     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 16);
7383     gen_qemu_st16(ctx, t0, addr);
7384     tcg_temp_free(t0);
7385     gen_addr_add(ctx, addr, addr, 2);
7386     gen_qemu_st16(ctx, cpu_gpr[rS(ctx->opcode)], addr);
7387 }
7388
7389 static inline void gen_op_evstwhe(DisasContext *ctx, TCGv addr)
7390 {
7391     TCGv t0 = tcg_temp_new();
7392 #if defined(TARGET_PPC64)
7393     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 48);
7394 #else
7395     tcg_gen_shri_tl(t0, cpu_gprh[rS(ctx->opcode)], 16);
7396 #endif
7397     gen_qemu_st16(ctx, t0, addr);
7398     gen_addr_add(ctx, addr, addr, 2);
7399     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 16);
7400     gen_qemu_st16(ctx, t0, addr);
7401     tcg_temp_free(t0);
7402 }
7403
7404 static inline void gen_op_evstwho(DisasContext *ctx, TCGv addr)
7405 {
7406 #if defined(TARGET_PPC64)
7407     TCGv t0 = tcg_temp_new();
7408     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32);
7409     gen_qemu_st16(ctx, t0, addr);
7410     tcg_temp_free(t0);
7411 #else
7412     gen_qemu_st16(ctx, cpu_gprh[rS(ctx->opcode)], addr);
7413 #endif
7414     gen_addr_add(ctx, addr, addr, 2);
7415     gen_qemu_st16(ctx, cpu_gpr[rS(ctx->opcode)], addr);
7416 }
7417
7418 static inline void gen_op_evstwwe(DisasContext *ctx, TCGv addr)
7419 {
7420 #if defined(TARGET_PPC64)
7421     TCGv t0 = tcg_temp_new();
7422     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32);
7423     gen_qemu_st32(ctx, t0, addr);
7424     tcg_temp_free(t0);
7425 #else
7426     gen_qemu_st32(ctx, cpu_gprh[rS(ctx->opcode)], addr);
7427 #endif
7428 }
7429
7430 static inline void gen_op_evstwwo(DisasContext *ctx, TCGv addr)
7431 {
7432     gen_qemu_st32(ctx, cpu_gpr[rS(ctx->opcode)], addr);
7433 }
7434
7435 #define GEN_SPEOP_LDST(name, opc2, sh)                                        \
7436 static void glue(gen_, name)(DisasContext *ctx)                                       \
7437 {                                                                             \
7438     TCGv t0;                                                                  \
7439     if (unlikely(!ctx->spe_enabled)) {                                        \
7440         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
7441         return;                                                               \
7442     }                                                                         \
7443     gen_set_access_type(ctx, ACCESS_INT);                                     \
7444     t0 = tcg_temp_new();                                                      \
7445     if (Rc(ctx->opcode)) {                                                    \
7446         gen_addr_spe_imm_index(ctx, t0, sh);                                  \
7447     } else {                                                                  \
7448         gen_addr_reg_index(ctx, t0);                                          \
7449     }                                                                         \
7450     gen_op_##name(ctx, t0);                                                   \
7451     tcg_temp_free(t0);                                                        \
7452 }
7453
7454 GEN_SPEOP_LDST(evldd, 0x00, 3);
7455 GEN_SPEOP_LDST(evldw, 0x01, 3);
7456 GEN_SPEOP_LDST(evldh, 0x02, 3);
7457 GEN_SPEOP_LDST(evlhhesplat, 0x04, 1);
7458 GEN_SPEOP_LDST(evlhhousplat, 0x06, 1);
7459 GEN_SPEOP_LDST(evlhhossplat, 0x07, 1);
7460 GEN_SPEOP_LDST(evlwhe, 0x08, 2);
7461 GEN_SPEOP_LDST(evlwhou, 0x0A, 2);
7462 GEN_SPEOP_LDST(evlwhos, 0x0B, 2);
7463 GEN_SPEOP_LDST(evlwwsplat, 0x0C, 2);
7464 GEN_SPEOP_LDST(evlwhsplat, 0x0E, 2);
7465
7466 GEN_SPEOP_LDST(evstdd, 0x10, 3);
7467 GEN_SPEOP_LDST(evstdw, 0x11, 3);
7468 GEN_SPEOP_LDST(evstdh, 0x12, 3);
7469 GEN_SPEOP_LDST(evstwhe, 0x18, 2);
7470 GEN_SPEOP_LDST(evstwho, 0x1A, 2);
7471 GEN_SPEOP_LDST(evstwwe, 0x1C, 2);
7472 GEN_SPEOP_LDST(evstwwo, 0x1E, 2);
7473
7474 /* Multiply and add - TODO */
7475 #if 0
7476 GEN_SPE(speundef,       evmhessf,      0x01, 0x10, 0x00000000, PPC_SPE);
7477 GEN_SPE(speundef,       evmhossf,      0x03, 0x10, 0x00000000, PPC_SPE);
7478 GEN_SPE(evmheumi,       evmhesmi,      0x04, 0x10, 0x00000000, PPC_SPE);
7479 GEN_SPE(speundef,       evmhesmf,      0x05, 0x10, 0x00000000, PPC_SPE);
7480 GEN_SPE(evmhoumi,       evmhosmi,      0x06, 0x10, 0x00000000, PPC_SPE);
7481 GEN_SPE(speundef,       evmhosmf,      0x07, 0x10, 0x00000000, PPC_SPE);
7482 GEN_SPE(speundef,       evmhessfa,     0x11, 0x10, 0x00000000, PPC_SPE);
7483 GEN_SPE(speundef,       evmhossfa,     0x13, 0x10, 0x00000000, PPC_SPE);
7484 GEN_SPE(evmheumia,      evmhesmia,     0x14, 0x10, 0x00000000, PPC_SPE);
7485 GEN_SPE(speundef,       evmhesmfa,     0x15, 0x10, 0x00000000, PPC_SPE);
7486 GEN_SPE(evmhoumia,      evmhosmia,     0x16, 0x10, 0x00000000, PPC_SPE);
7487 GEN_SPE(speundef,       evmhosmfa,     0x17, 0x10, 0x00000000, PPC_SPE);
7488
7489 GEN_SPE(speundef,       evmwhssf,      0x03, 0x11, 0x00000000, PPC_SPE);
7490 GEN_SPE(evmwlumi,       speundef,      0x04, 0x11, 0x00000000, PPC_SPE);
7491 GEN_SPE(evmwhumi,       evmwhsmi,      0x06, 0x11, 0x00000000, PPC_SPE);
7492 GEN_SPE(speundef,       evmwhsmf,      0x07, 0x11, 0x00000000, PPC_SPE);
7493 GEN_SPE(speundef,       evmwssf,       0x09, 0x11, 0x00000000, PPC_SPE);
7494 GEN_SPE(evmwumi,        evmwsmi,       0x0C, 0x11, 0x00000000, PPC_SPE);
7495 GEN_SPE(speundef,       evmwsmf,       0x0D, 0x11, 0x00000000, PPC_SPE);
7496 GEN_SPE(speundef,       evmwhssfa,     0x13, 0x11, 0x00000000, PPC_SPE);
7497 GEN_SPE(evmwlumia,      speundef,      0x14, 0x11, 0x00000000, PPC_SPE);
7498 GEN_SPE(evmwhumia,      evmwhsmia,     0x16, 0x11, 0x00000000, PPC_SPE);
7499 GEN_SPE(speundef,       evmwhsmfa,     0x17, 0x11, 0x00000000, PPC_SPE);
7500 GEN_SPE(speundef,       evmwssfa,      0x19, 0x11, 0x00000000, PPC_SPE);
7501 GEN_SPE(evmwumia,       evmwsmia,      0x1C, 0x11, 0x00000000, PPC_SPE);
7502 GEN_SPE(speundef,       evmwsmfa,      0x1D, 0x11, 0x00000000, PPC_SPE);
7503
7504 GEN_SPE(evadduiaaw,     evaddsiaaw,    0x00, 0x13, 0x0000F800, PPC_SPE);
7505 GEN_SPE(evsubfusiaaw,   evsubfssiaaw,  0x01, 0x13, 0x0000F800, PPC_SPE);
7506 GEN_SPE(evaddumiaaw,    evaddsmiaaw,   0x04, 0x13, 0x0000F800, PPC_SPE);
7507 GEN_SPE(evsubfumiaaw,   evsubfsmiaaw,  0x05, 0x13, 0x0000F800, PPC_SPE);
7508 GEN_SPE(evdivws,        evdivwu,       0x06, 0x13, 0x00000000, PPC_SPE);
7509 GEN_SPE(evmra,          speundef,      0x07, 0x13, 0x0000F800, PPC_SPE);
7510
7511 GEN_SPE(evmheusiaaw,    evmhessiaaw,   0x00, 0x14, 0x00000000, PPC_SPE);
7512 GEN_SPE(speundef,       evmhessfaaw,   0x01, 0x14, 0x00000000, PPC_SPE);
7513 GEN_SPE(evmhousiaaw,    evmhossiaaw,   0x02, 0x14, 0x00000000, PPC_SPE);
7514 GEN_SPE(speundef,       evmhossfaaw,   0x03, 0x14, 0x00000000, PPC_SPE);
7515 GEN_SPE(evmheumiaaw,    evmhesmiaaw,   0x04, 0x14, 0x00000000, PPC_SPE);
7516 GEN_SPE(speundef,       evmhesmfaaw,   0x05, 0x14, 0x00000000, PPC_SPE);
7517 GEN_SPE(evmhoumiaaw,    evmhosmiaaw,   0x06, 0x14, 0x00000000, PPC_SPE);
7518 GEN_SPE(speundef,       evmhosmfaaw,   0x07, 0x14, 0x00000000, PPC_SPE);
7519 GEN_SPE(evmhegumiaa,    evmhegsmiaa,   0x14, 0x14, 0x00000000, PPC_SPE);
7520 GEN_SPE(speundef,       evmhegsmfaa,   0x15, 0x14, 0x00000000, PPC_SPE);
7521 GEN_SPE(evmhogumiaa,    evmhogsmiaa,   0x16, 0x14, 0x00000000, PPC_SPE);
7522 GEN_SPE(speundef,       evmhogsmfaa,   0x17, 0x14, 0x00000000, PPC_SPE);
7523
7524 GEN_SPE(evmwlusiaaw,    evmwlssiaaw,   0x00, 0x15, 0x00000000, PPC_SPE);
7525 GEN_SPE(evmwlumiaaw,    evmwlsmiaaw,   0x04, 0x15, 0x00000000, PPC_SPE);
7526 GEN_SPE(speundef,       evmwssfaa,     0x09, 0x15, 0x00000000, PPC_SPE);
7527 GEN_SPE(evmwumiaa,      evmwsmiaa,     0x0C, 0x15, 0x00000000, PPC_SPE);
7528 GEN_SPE(speundef,       evmwsmfaa,     0x0D, 0x15, 0x00000000, PPC_SPE);
7529
7530 GEN_SPE(evmheusianw,    evmhessianw,   0x00, 0x16, 0x00000000, PPC_SPE);
7531 GEN_SPE(speundef,       evmhessfanw,   0x01, 0x16, 0x00000000, PPC_SPE);
7532 GEN_SPE(evmhousianw,    evmhossianw,   0x02, 0x16, 0x00000000, PPC_SPE);
7533 GEN_SPE(speundef,       evmhossfanw,   0x03, 0x16, 0x00000000, PPC_SPE);
7534 GEN_SPE(evmheumianw,    evmhesmianw,   0x04, 0x16, 0x00000000, PPC_SPE);
7535 GEN_SPE(speundef,       evmhesmfanw,   0x05, 0x16, 0x00000000, PPC_SPE);
7536 GEN_SPE(evmhoumianw,    evmhosmianw,   0x06, 0x16, 0x00000000, PPC_SPE);
7537 GEN_SPE(speundef,       evmhosmfanw,   0x07, 0x16, 0x00000000, PPC_SPE);
7538 GEN_SPE(evmhegumian,    evmhegsmian,   0x14, 0x16, 0x00000000, PPC_SPE);
7539 GEN_SPE(speundef,       evmhegsmfan,   0x15, 0x16, 0x00000000, PPC_SPE);
7540 GEN_SPE(evmhigumian,    evmhigsmian,   0x16, 0x16, 0x00000000, PPC_SPE);
7541 GEN_SPE(speundef,       evmhogsmfan,   0x17, 0x16, 0x00000000, PPC_SPE);
7542
7543 GEN_SPE(evmwlusianw,    evmwlssianw,   0x00, 0x17, 0x00000000, PPC_SPE);
7544 GEN_SPE(evmwlumianw,    evmwlsmianw,   0x04, 0x17, 0x00000000, PPC_SPE);
7545 GEN_SPE(speundef,       evmwssfan,     0x09, 0x17, 0x00000000, PPC_SPE);
7546 GEN_SPE(evmwumian,      evmwsmian,     0x0C, 0x17, 0x00000000, PPC_SPE);
7547 GEN_SPE(speundef,       evmwsmfan,     0x0D, 0x17, 0x00000000, PPC_SPE);
7548 #endif
7549
7550 /***                      SPE floating-point extension                     ***/
7551 #if defined(TARGET_PPC64)
7552 #define GEN_SPEFPUOP_CONV_32_32(name)                                         \
7553 static inline void gen_##name(DisasContext *ctx)                              \
7554 {                                                                             \
7555     TCGv_i32 t0;                                                              \
7556     TCGv t1;                                                                  \
7557     t0 = tcg_temp_new_i32();                                                  \
7558     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rB(ctx->opcode)]);                       \
7559     gen_helper_##name(t0, t0);                                                \
7560     t1 = tcg_temp_new();                                                      \
7561     tcg_gen_extu_i32_tl(t1, t0);                                              \
7562     tcg_temp_free_i32(t0);                                                    \
7563     tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)],       \
7564                     0xFFFFFFFF00000000ULL);                                   \
7565     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t1);    \
7566     tcg_temp_free(t1);                                                        \
7567 }
7568 #define GEN_SPEFPUOP_CONV_32_64(name)                                         \
7569 static inline void gen_##name(DisasContext *ctx)                              \
7570 {                                                                             \
7571     TCGv_i32 t0;                                                              \
7572     TCGv t1;                                                                  \
7573     t0 = tcg_temp_new_i32();                                                  \
7574     gen_helper_##name(t0, cpu_gpr[rB(ctx->opcode)]);                          \
7575     t1 = tcg_temp_new();                                                      \
7576     tcg_gen_extu_i32_tl(t1, t0);                                              \
7577     tcg_temp_free_i32(t0);                                                    \
7578     tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)],       \
7579                     0xFFFFFFFF00000000ULL);                                   \
7580     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t1);    \
7581     tcg_temp_free(t1);                                                        \
7582 }
7583 #define GEN_SPEFPUOP_CONV_64_32(name)                                         \
7584 static inline void gen_##name(DisasContext *ctx)                              \
7585 {                                                                             \
7586     TCGv_i32 t0 = tcg_temp_new_i32();                                         \
7587     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rB(ctx->opcode)]);                       \
7588     gen_helper_##name(cpu_gpr[rD(ctx->opcode)], t0);                          \
7589     tcg_temp_free_i32(t0);                                                    \
7590 }
7591 #define GEN_SPEFPUOP_CONV_64_64(name)                                         \
7592 static inline void gen_##name(DisasContext *ctx)                              \
7593 {                                                                             \
7594     gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
7595 }
7596 #define GEN_SPEFPUOP_ARITH2_32_32(name)                                       \
7597 static inline void gen_##name(DisasContext *ctx)                              \
7598 {                                                                             \
7599     TCGv_i32 t0, t1;                                                          \
7600     TCGv_i64 t2;                                                              \
7601     if (unlikely(!ctx->spe_enabled)) {                                        \
7602         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
7603         return;                                                               \
7604     }                                                                         \
7605     t0 = tcg_temp_new_i32();                                                  \
7606     t1 = tcg_temp_new_i32();                                                  \
7607     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);                       \
7608     tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);                       \
7609     gen_helper_##name(t0, t0, t1);                                            \
7610     tcg_temp_free_i32(t1);                                                    \
7611     t2 = tcg_temp_new();                                                      \
7612     tcg_gen_extu_i32_tl(t2, t0);                                              \
7613     tcg_temp_free_i32(t0);                                                    \
7614     tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)],       \
7615                     0xFFFFFFFF00000000ULL);                                   \
7616     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t2);    \
7617     tcg_temp_free(t2);                                                        \
7618 }
7619 #define GEN_SPEFPUOP_ARITH2_64_64(name)                                       \
7620 static inline void gen_##name(DisasContext *ctx)                              \
7621 {                                                                             \
7622     if (unlikely(!ctx->spe_enabled)) {                                        \
7623         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
7624         return;                                                               \
7625     }                                                                         \
7626     gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],     \
7627                       cpu_gpr[rB(ctx->opcode)]);                              \
7628 }
7629 #define GEN_SPEFPUOP_COMP_32(name)                                            \
7630 static inline void gen_##name(DisasContext *ctx)                              \
7631 {                                                                             \
7632     TCGv_i32 t0, t1;                                                          \
7633     if (unlikely(!ctx->spe_enabled)) {                                        \
7634         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
7635         return;                                                               \
7636     }                                                                         \
7637     t0 = tcg_temp_new_i32();                                                  \
7638     t1 = tcg_temp_new_i32();                                                  \
7639     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);                       \
7640     tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);                       \
7641     gen_helper_##name(cpu_crf[crfD(ctx->opcode)], t0, t1);                    \
7642     tcg_temp_free_i32(t0);                                                    \
7643     tcg_temp_free_i32(t1);                                                    \
7644 }
7645 #define GEN_SPEFPUOP_COMP_64(name)                                            \
7646 static inline void gen_##name(DisasContext *ctx)                              \
7647 {                                                                             \
7648     if (unlikely(!ctx->spe_enabled)) {                                        \
7649         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
7650         return;                                                               \
7651     }                                                                         \
7652     gen_helper_##name(cpu_crf[crfD(ctx->opcode)],                             \
7653                       cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
7654 }
7655 #else
7656 #define GEN_SPEFPUOP_CONV_32_32(name)                                         \
7657 static inline void gen_##name(DisasContext *ctx)                              \
7658 {                                                                             \
7659     gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
7660 }
7661 #define GEN_SPEFPUOP_CONV_32_64(name)                                         \
7662 static inline void gen_##name(DisasContext *ctx)                              \
7663 {                                                                             \
7664     TCGv_i64 t0 = tcg_temp_new_i64();                                         \
7665     gen_load_gpr64(t0, rB(ctx->opcode));                                      \
7666     gen_helper_##name(cpu_gpr[rD(ctx->opcode)], t0);                          \
7667     tcg_temp_free_i64(t0);                                                    \
7668 }
7669 #define GEN_SPEFPUOP_CONV_64_32(name)                                         \
7670 static inline void gen_##name(DisasContext *ctx)                              \
7671 {                                                                             \
7672     TCGv_i64 t0 = tcg_temp_new_i64();                                         \
7673     gen_helper_##name(t0, cpu_gpr[rB(ctx->opcode)]);                          \
7674     gen_store_gpr64(rD(ctx->opcode), t0);                                     \
7675     tcg_temp_free_i64(t0);                                                    \
7676 }
7677 #define GEN_SPEFPUOP_CONV_64_64(name)                                         \
7678 static inline void gen_##name(DisasContext *ctx)                              \
7679 {                                                                             \
7680     TCGv_i64 t0 = tcg_temp_new_i64();                                         \
7681     gen_load_gpr64(t0, rB(ctx->opcode));                                      \
7682     gen_helper_##name(t0, t0);                                                \
7683     gen_store_gpr64(rD(ctx->opcode), t0);                                     \
7684     tcg_temp_free_i64(t0);                                                    \
7685 }
7686 #define GEN_SPEFPUOP_ARITH2_32_32(name)                                       \
7687 static inline void gen_##name(DisasContext *ctx)                              \
7688 {                                                                             \
7689     if (unlikely(!ctx->spe_enabled)) {                                        \
7690         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
7691         return;                                                               \
7692     }                                                                         \
7693     gen_helper_##name(cpu_gpr[rD(ctx->opcode)],                               \
7694                       cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
7695 }
7696 #define GEN_SPEFPUOP_ARITH2_64_64(name)                                       \
7697 static inline void gen_##name(DisasContext *ctx)                              \
7698 {                                                                             \
7699     TCGv_i64 t0, t1;                                                          \
7700     if (unlikely(!ctx->spe_enabled)) {                                        \
7701         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
7702         return;                                                               \
7703     }                                                                         \
7704     t0 = tcg_temp_new_i64();                                                  \
7705     t1 = tcg_temp_new_i64();                                                  \
7706     gen_load_gpr64(t0, rA(ctx->opcode));                                      \
7707     gen_load_gpr64(t1, rB(ctx->opcode));                                      \
7708     gen_helper_##name(t0, t0, t1);                                            \
7709     gen_store_gpr64(rD(ctx->opcode), t0);                                     \
7710     tcg_temp_free_i64(t0);                                                    \
7711     tcg_temp_free_i64(t1);                                                    \
7712 }
7713 #define GEN_SPEFPUOP_COMP_32(name)                                            \
7714 static inline void gen_##name(DisasContext *ctx)                              \
7715 {                                                                             \
7716     if (unlikely(!ctx->spe_enabled)) {                                        \
7717         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
7718         return;                                                               \
7719     }                                                                         \
7720     gen_helper_##name(cpu_crf[crfD(ctx->opcode)],                             \
7721                       cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
7722 }
7723 #define GEN_SPEFPUOP_COMP_64(name)                                            \
7724 static inline void gen_##name(DisasContext *ctx)                              \
7725 {                                                                             \
7726     TCGv_i64 t0, t1;                                                          \
7727     if (unlikely(!ctx->spe_enabled)) {                                        \
7728         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
7729         return;                                                               \
7730     }                                                                         \
7731     t0 = tcg_temp_new_i64();                                                  \
7732     t1 = tcg_temp_new_i64();                                                  \
7733     gen_load_gpr64(t0, rA(ctx->opcode));                                      \
7734     gen_load_gpr64(t1, rB(ctx->opcode));                                      \
7735     gen_helper_##name(cpu_crf[crfD(ctx->opcode)], t0, t1);                    \
7736     tcg_temp_free_i64(t0);                                                    \
7737     tcg_temp_free_i64(t1);                                                    \
7738 }
7739 #endif
7740
7741 /* Single precision floating-point vectors operations */
7742 /* Arithmetic */
7743 GEN_SPEFPUOP_ARITH2_64_64(evfsadd);
7744 GEN_SPEFPUOP_ARITH2_64_64(evfssub);
7745 GEN_SPEFPUOP_ARITH2_64_64(evfsmul);
7746 GEN_SPEFPUOP_ARITH2_64_64(evfsdiv);
7747 static inline void gen_evfsabs(DisasContext *ctx)
7748 {
7749     if (unlikely(!ctx->spe_enabled)) {
7750         gen_exception(ctx, POWERPC_EXCP_APU);
7751         return;
7752     }
7753 #if defined(TARGET_PPC64)
7754     tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~0x8000000080000000LL);
7755 #else
7756     tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~0x80000000);
7757     tcg_gen_andi_tl(cpu_gprh[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], ~0x80000000);
7758 #endif
7759 }
7760 static inline void gen_evfsnabs(DisasContext *ctx)
7761 {
7762     if (unlikely(!ctx->spe_enabled)) {
7763         gen_exception(ctx, POWERPC_EXCP_APU);
7764         return;
7765     }
7766 #if defined(TARGET_PPC64)
7767     tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000080000000LL);
7768 #else
7769     tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
7770     tcg_gen_ori_tl(cpu_gprh[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000);
7771 #endif
7772 }
7773 static inline void gen_evfsneg(DisasContext *ctx)
7774 {
7775     if (unlikely(!ctx->spe_enabled)) {
7776         gen_exception(ctx, POWERPC_EXCP_APU);
7777         return;
7778     }
7779 #if defined(TARGET_PPC64)
7780     tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000080000000LL);
7781 #else
7782     tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
7783     tcg_gen_xori_tl(cpu_gprh[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000);
7784 #endif
7785 }
7786
7787 /* Conversion */
7788 GEN_SPEFPUOP_CONV_64_64(evfscfui);
7789 GEN_SPEFPUOP_CONV_64_64(evfscfsi);
7790 GEN_SPEFPUOP_CONV_64_64(evfscfuf);
7791 GEN_SPEFPUOP_CONV_64_64(evfscfsf);
7792 GEN_SPEFPUOP_CONV_64_64(evfsctui);
7793 GEN_SPEFPUOP_CONV_64_64(evfsctsi);
7794 GEN_SPEFPUOP_CONV_64_64(evfsctuf);
7795 GEN_SPEFPUOP_CONV_64_64(evfsctsf);
7796 GEN_SPEFPUOP_CONV_64_64(evfsctuiz);
7797 GEN_SPEFPUOP_CONV_64_64(evfsctsiz);
7798
7799 /* Comparison */
7800 GEN_SPEFPUOP_COMP_64(evfscmpgt);
7801 GEN_SPEFPUOP_COMP_64(evfscmplt);
7802 GEN_SPEFPUOP_COMP_64(evfscmpeq);
7803 GEN_SPEFPUOP_COMP_64(evfststgt);
7804 GEN_SPEFPUOP_COMP_64(evfststlt);
7805 GEN_SPEFPUOP_COMP_64(evfststeq);
7806
7807 /* Opcodes definitions */
7808 GEN_SPE(evfsadd,        evfssub,       0x00, 0x0A, 0x00000000, PPC_SPE_SINGLE); //
7809 GEN_SPE(evfsabs,        evfsnabs,      0x02, 0x0A, 0x0000F800, PPC_SPE_SINGLE); //
7810 GEN_SPE(evfsneg,        speundef,      0x03, 0x0A, 0x0000F800, PPC_SPE_SINGLE); //
7811 GEN_SPE(evfsmul,        evfsdiv,       0x04, 0x0A, 0x00000000, PPC_SPE_SINGLE); //
7812 GEN_SPE(evfscmpgt,      evfscmplt,     0x06, 0x0A, 0x00600000, PPC_SPE_SINGLE); //
7813 GEN_SPE(evfscmpeq,      speundef,      0x07, 0x0A, 0x00600000, PPC_SPE_SINGLE); //
7814 GEN_SPE(evfscfui,       evfscfsi,      0x08, 0x0A, 0x00180000, PPC_SPE_SINGLE); //
7815 GEN_SPE(evfscfuf,       evfscfsf,      0x09, 0x0A, 0x00180000, PPC_SPE_SINGLE); //
7816 GEN_SPE(evfsctui,       evfsctsi,      0x0A, 0x0A, 0x00180000, PPC_SPE_SINGLE); //
7817 GEN_SPE(evfsctuf,       evfsctsf,      0x0B, 0x0A, 0x00180000, PPC_SPE_SINGLE); //
7818 GEN_SPE(evfsctuiz,      speundef,      0x0C, 0x0A, 0x00180000, PPC_SPE_SINGLE); //
7819 GEN_SPE(evfsctsiz,      speundef,      0x0D, 0x0A, 0x00180000, PPC_SPE_SINGLE); //
7820 GEN_SPE(evfststgt,      evfststlt,     0x0E, 0x0A, 0x00600000, PPC_SPE_SINGLE); //
7821 GEN_SPE(evfststeq,      speundef,      0x0F, 0x0A, 0x00600000, PPC_SPE_SINGLE); //
7822
7823 /* Single precision floating-point operations */
7824 /* Arithmetic */
7825 GEN_SPEFPUOP_ARITH2_32_32(efsadd);
7826 GEN_SPEFPUOP_ARITH2_32_32(efssub);
7827 GEN_SPEFPUOP_ARITH2_32_32(efsmul);
7828 GEN_SPEFPUOP_ARITH2_32_32(efsdiv);
7829 static inline void gen_efsabs(DisasContext *ctx)
7830 {
7831     if (unlikely(!ctx->spe_enabled)) {
7832         gen_exception(ctx, POWERPC_EXCP_APU);
7833         return;
7834     }
7835     tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], (target_long)~0x80000000LL);
7836 }
7837 static inline void gen_efsnabs(DisasContext *ctx)
7838 {
7839     if (unlikely(!ctx->spe_enabled)) {
7840         gen_exception(ctx, POWERPC_EXCP_APU);
7841         return;
7842     }
7843     tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
7844 }
7845 static inline void gen_efsneg(DisasContext *ctx)
7846 {
7847     if (unlikely(!ctx->spe_enabled)) {
7848         gen_exception(ctx, POWERPC_EXCP_APU);
7849         return;
7850     }
7851     tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
7852 }
7853
7854 /* Conversion */
7855 GEN_SPEFPUOP_CONV_32_32(efscfui);
7856 GEN_SPEFPUOP_CONV_32_32(efscfsi);
7857 GEN_SPEFPUOP_CONV_32_32(efscfuf);
7858 GEN_SPEFPUOP_CONV_32_32(efscfsf);
7859 GEN_SPEFPUOP_CONV_32_32(efsctui);
7860 GEN_SPEFPUOP_CONV_32_32(efsctsi);
7861 GEN_SPEFPUOP_CONV_32_32(efsctuf);
7862 GEN_SPEFPUOP_CONV_32_32(efsctsf);
7863 GEN_SPEFPUOP_CONV_32_32(efsctuiz);
7864 GEN_SPEFPUOP_CONV_32_32(efsctsiz);
7865 GEN_SPEFPUOP_CONV_32_64(efscfd);
7866
7867 /* Comparison */
7868 GEN_SPEFPUOP_COMP_32(efscmpgt);
7869 GEN_SPEFPUOP_COMP_32(efscmplt);
7870 GEN_SPEFPUOP_COMP_32(efscmpeq);
7871 GEN_SPEFPUOP_COMP_32(efststgt);
7872 GEN_SPEFPUOP_COMP_32(efststlt);
7873 GEN_SPEFPUOP_COMP_32(efststeq);
7874
7875 /* Opcodes definitions */
7876 GEN_SPE(efsadd,         efssub,        0x00, 0x0B, 0x00000000, PPC_SPE_SINGLE); //
7877 GEN_SPE(efsabs,         efsnabs,       0x02, 0x0B, 0x0000F800, PPC_SPE_SINGLE); //
7878 GEN_SPE(efsneg,         speundef,      0x03, 0x0B, 0x0000F800, PPC_SPE_SINGLE); //
7879 GEN_SPE(efsmul,         efsdiv,        0x04, 0x0B, 0x00000000, PPC_SPE_SINGLE); //
7880 GEN_SPE(efscmpgt,       efscmplt,      0x06, 0x0B, 0x00600000, PPC_SPE_SINGLE); //
7881 GEN_SPE(efscmpeq,       efscfd,        0x07, 0x0B, 0x00600000, PPC_SPE_SINGLE); //
7882 GEN_SPE(efscfui,        efscfsi,       0x08, 0x0B, 0x00180000, PPC_SPE_SINGLE); //
7883 GEN_SPE(efscfuf,        efscfsf,       0x09, 0x0B, 0x00180000, PPC_SPE_SINGLE); //
7884 GEN_SPE(efsctui,        efsctsi,       0x0A, 0x0B, 0x00180000, PPC_SPE_SINGLE); //
7885 GEN_SPE(efsctuf,        efsctsf,       0x0B, 0x0B, 0x00180000, PPC_SPE_SINGLE); //
7886 GEN_SPE(efsctuiz,       speundef,      0x0C, 0x0B, 0x00180000, PPC_SPE_SINGLE); //
7887 GEN_SPE(efsctsiz,       speundef,      0x0D, 0x0B, 0x00180000, PPC_SPE_SINGLE); //
7888 GEN_SPE(efststgt,       efststlt,      0x0E, 0x0B, 0x00600000, PPC_SPE_SINGLE); //
7889 GEN_SPE(efststeq,       speundef,      0x0F, 0x0B, 0x00600000, PPC_SPE_SINGLE); //
7890
7891 /* Double precision floating-point operations */
7892 /* Arithmetic */
7893 GEN_SPEFPUOP_ARITH2_64_64(efdadd);
7894 GEN_SPEFPUOP_ARITH2_64_64(efdsub);
7895 GEN_SPEFPUOP_ARITH2_64_64(efdmul);
7896 GEN_SPEFPUOP_ARITH2_64_64(efddiv);
7897 static inline void gen_efdabs(DisasContext *ctx)
7898 {
7899     if (unlikely(!ctx->spe_enabled)) {
7900         gen_exception(ctx, POWERPC_EXCP_APU);
7901         return;
7902     }
7903 #if defined(TARGET_PPC64)
7904     tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~0x8000000000000000LL);
7905 #else
7906     tcg_gen_andi_tl(cpu_gprh[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], ~0x80000000);
7907 #endif
7908 }
7909 static inline void gen_efdnabs(DisasContext *ctx)
7910 {
7911     if (unlikely(!ctx->spe_enabled)) {
7912         gen_exception(ctx, POWERPC_EXCP_APU);
7913         return;
7914     }
7915 #if defined(TARGET_PPC64)
7916     tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000000000000LL);
7917 #else
7918     tcg_gen_ori_tl(cpu_gprh[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000);
7919 #endif
7920 }
7921 static inline void gen_efdneg(DisasContext *ctx)
7922 {
7923     if (unlikely(!ctx->spe_enabled)) {
7924         gen_exception(ctx, POWERPC_EXCP_APU);
7925         return;
7926     }
7927 #if defined(TARGET_PPC64)
7928     tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000000000000LL);
7929 #else
7930     tcg_gen_xori_tl(cpu_gprh[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000);
7931 #endif
7932 }
7933
7934 /* Conversion */
7935 GEN_SPEFPUOP_CONV_64_32(efdcfui);
7936 GEN_SPEFPUOP_CONV_64_32(efdcfsi);
7937 GEN_SPEFPUOP_CONV_64_32(efdcfuf);
7938 GEN_SPEFPUOP_CONV_64_32(efdcfsf);
7939 GEN_SPEFPUOP_CONV_32_64(efdctui);
7940 GEN_SPEFPUOP_CONV_32_64(efdctsi);
7941 GEN_SPEFPUOP_CONV_32_64(efdctuf);
7942 GEN_SPEFPUOP_CONV_32_64(efdctsf);
7943 GEN_SPEFPUOP_CONV_32_64(efdctuiz);
7944 GEN_SPEFPUOP_CONV_32_64(efdctsiz);
7945 GEN_SPEFPUOP_CONV_64_32(efdcfs);
7946 GEN_SPEFPUOP_CONV_64_64(efdcfuid);
7947 GEN_SPEFPUOP_CONV_64_64(efdcfsid);
7948 GEN_SPEFPUOP_CONV_64_64(efdctuidz);
7949 GEN_SPEFPUOP_CONV_64_64(efdctsidz);
7950
7951 /* Comparison */
7952 GEN_SPEFPUOP_COMP_64(efdcmpgt);
7953 GEN_SPEFPUOP_COMP_64(efdcmplt);
7954 GEN_SPEFPUOP_COMP_64(efdcmpeq);
7955 GEN_SPEFPUOP_COMP_64(efdtstgt);
7956 GEN_SPEFPUOP_COMP_64(efdtstlt);
7957 GEN_SPEFPUOP_COMP_64(efdtsteq);
7958
7959 /* Opcodes definitions */
7960 GEN_SPE(efdadd,         efdsub,        0x10, 0x0B, 0x00000000, PPC_SPE_DOUBLE); //
7961 GEN_SPE(efdcfuid,       efdcfsid,      0x11, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
7962 GEN_SPE(efdabs,         efdnabs,       0x12, 0x0B, 0x0000F800, PPC_SPE_DOUBLE); //
7963 GEN_SPE(efdneg,         speundef,      0x13, 0x0B, 0x0000F800, PPC_SPE_DOUBLE); //
7964 GEN_SPE(efdmul,         efddiv,        0x14, 0x0B, 0x00000000, PPC_SPE_DOUBLE); //
7965 GEN_SPE(efdctuidz,      efdctsidz,     0x15, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
7966 GEN_SPE(efdcmpgt,       efdcmplt,      0x16, 0x0B, 0x00600000, PPC_SPE_DOUBLE); //
7967 GEN_SPE(efdcmpeq,       efdcfs,        0x17, 0x0B, 0x00600000, PPC_SPE_DOUBLE); //
7968 GEN_SPE(efdcfui,        efdcfsi,       0x18, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
7969 GEN_SPE(efdcfuf,        efdcfsf,       0x19, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
7970 GEN_SPE(efdctui,        efdctsi,       0x1A, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
7971 GEN_SPE(efdctuf,        efdctsf,       0x1B, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
7972 GEN_SPE(efdctuiz,       speundef,      0x1C, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
7973 GEN_SPE(efdctsiz,       speundef,      0x1D, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
7974 GEN_SPE(efdtstgt,       efdtstlt,      0x1E, 0x0B, 0x00600000, PPC_SPE_DOUBLE); //
7975 GEN_SPE(efdtsteq,       speundef,      0x1F, 0x0B, 0x00600000, PPC_SPE_DOUBLE); //
7976
7977 static opcode_t opcodes[] = {
7978 GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE),
7979 GEN_HANDLER(cmp, 0x1F, 0x00, 0x00, 0x00400000, PPC_INTEGER),
7980 GEN_HANDLER(cmpi, 0x0B, 0xFF, 0xFF, 0x00400000, PPC_INTEGER),
7981 GEN_HANDLER(cmpl, 0x1F, 0x00, 0x01, 0x00400000, PPC_INTEGER),
7982 GEN_HANDLER(cmpli, 0x0A, 0xFF, 0xFF, 0x00400000, PPC_INTEGER),
7983 GEN_HANDLER(isel, 0x1F, 0x0F, 0xFF, 0x00000001, PPC_ISEL),
7984 GEN_HANDLER(addi, 0x0E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
7985 GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
7986 GEN_HANDLER2(addic_, "addic.", 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
7987 GEN_HANDLER(addis, 0x0F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
7988 GEN_HANDLER(mulhw, 0x1F, 0x0B, 0x02, 0x00000400, PPC_INTEGER),
7989 GEN_HANDLER(mulhwu, 0x1F, 0x0B, 0x00, 0x00000400, PPC_INTEGER),
7990 GEN_HANDLER(mullw, 0x1F, 0x0B, 0x07, 0x00000000, PPC_INTEGER),
7991 GEN_HANDLER(mullwo, 0x1F, 0x0B, 0x17, 0x00000000, PPC_INTEGER),
7992 GEN_HANDLER(mulli, 0x07, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
7993 #if defined(TARGET_PPC64)
7994 GEN_HANDLER(mulld, 0x1F, 0x09, 0x07, 0x00000000, PPC_64B),
7995 #endif
7996 GEN_HANDLER(neg, 0x1F, 0x08, 0x03, 0x0000F800, PPC_INTEGER),
7997 GEN_HANDLER(nego, 0x1F, 0x08, 0x13, 0x0000F800, PPC_INTEGER),
7998 GEN_HANDLER(subfic, 0x08, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
7999 GEN_HANDLER2(andi_, "andi.", 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8000 GEN_HANDLER2(andis_, "andis.", 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8001 GEN_HANDLER(cntlzw, 0x1F, 0x1A, 0x00, 0x00000000, PPC_INTEGER),
8002 GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER),
8003 GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER),
8004 GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8005 GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8006 GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8007 GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8008 GEN_HANDLER(popcntb, 0x1F, 0x03, 0x03, 0x0000F801, PPC_POPCNTB),
8009 #if defined(TARGET_PPC64)
8010 GEN_HANDLER(cntlzd, 0x1F, 0x1A, 0x01, 0x00000000, PPC_64B),
8011 #endif
8012 GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8013 GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8014 GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8015 GEN_HANDLER(slw, 0x1F, 0x18, 0x00, 0x00000000, PPC_INTEGER),
8016 GEN_HANDLER(sraw, 0x1F, 0x18, 0x18, 0x00000000, PPC_INTEGER),
8017 GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER),
8018 GEN_HANDLER(srw, 0x1F, 0x18, 0x10, 0x00000000, PPC_INTEGER),
8019 #if defined(TARGET_PPC64)
8020 GEN_HANDLER(sld, 0x1F, 0x1B, 0x00, 0x00000000, PPC_64B),
8021 GEN_HANDLER(srad, 0x1F, 0x1A, 0x18, 0x00000000, PPC_64B),
8022 GEN_HANDLER2(sradi0, "sradi", 0x1F, 0x1A, 0x19, 0x00000000, PPC_64B),
8023 GEN_HANDLER2(sradi1, "sradi", 0x1F, 0x1B, 0x19, 0x00000000, PPC_64B),
8024 GEN_HANDLER(srd, 0x1F, 0x1B, 0x10, 0x00000000, PPC_64B),
8025 #endif
8026 GEN_HANDLER(frsqrtes, 0x3B, 0x1A, 0xFF, 0x001F07C0, PPC_FLOAT_FRSQRTES),
8027 GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT),
8028 GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT),
8029 GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT),
8030 GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT),
8031 GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT),
8032 GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT),
8033 GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT),
8034 GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT),
8035 GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT),
8036 GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x00010000, PPC_FLOAT),
8037 GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT),
8038 #if defined(TARGET_PPC64)
8039 GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B),
8040 GEN_HANDLER(lq, 0x38, 0xFF, 0xFF, 0x00000000, PPC_64BX),
8041 GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000000, PPC_64B),
8042 #endif
8043 GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8044 GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8045 GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_STRING),
8046 GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_STRING),
8047 GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_STRING),
8048 GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_STRING),
8049 GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FFF801, PPC_MEM_EIEIO),
8050 GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FFF801, PPC_MEM),
8051 GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000001, PPC_RES),
8052 GEN_HANDLER2(stwcx_, "stwcx.", 0x1F, 0x16, 0x04, 0x00000000, PPC_RES),
8053 #if defined(TARGET_PPC64)
8054 GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000001, PPC_64B),
8055 GEN_HANDLER2(stdcx_, "stdcx.", 0x1F, 0x16, 0x06, 0x00000000, PPC_64B),
8056 #endif
8057 GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x039FF801, PPC_MEM_SYNC),
8058 GEN_HANDLER(wait, 0x1F, 0x1E, 0x01, 0x03FFF801, PPC_WAIT),
8059 GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
8060 GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
8061 GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW),
8062 GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW),
8063 GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER),
8064 GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW),
8065 #if defined(TARGET_PPC64)
8066 GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B),
8067 GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64H),
8068 #endif
8069 GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFF01D, PPC_FLOW),
8070 GEN_HANDLER(tw, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW),
8071 GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
8072 #if defined(TARGET_PPC64)
8073 GEN_HANDLER(td, 0x1F, 0x04, 0x02, 0x00000001, PPC_64B),
8074 GEN_HANDLER(tdi, 0x02, 0xFF, 0xFF, 0x00000000, PPC_64B),
8075 #endif
8076 GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC),
8077 GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC),
8078 GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC),
8079 GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC),
8080 GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MFTB),
8081 GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC),
8082 #if defined(TARGET_PPC64)
8083 GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001EF801, PPC_64B),
8084 #endif
8085 GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC),
8086 GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC),
8087 GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03C00001, PPC_CACHE),
8088 GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE),
8089 GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE),
8090 GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x02000001, PPC_CACHE),
8091 GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x02000001, PPC_CACHE),
8092 GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE_DCBZ),
8093 GEN_HANDLER2(dcbz_970, "dcbz", 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZT),
8094 GEN_HANDLER(dst, 0x1F, 0x16, 0x0A, 0x01800001, PPC_ALTIVEC),
8095 GEN_HANDLER(dstst, 0x1F, 0x16, 0x0B, 0x02000001, PPC_ALTIVEC),
8096 GEN_HANDLER(dss, 0x1F, 0x16, 0x19, 0x019FF801, PPC_ALTIVEC),
8097 GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE_ICBI),
8098 GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_DCBA),
8099 GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT),
8100 GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT),
8101 GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT),
8102 GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT),
8103 #if defined(TARGET_PPC64)
8104 GEN_HANDLER2(mfsr_64b, "mfsr", 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT_64B),
8105 GEN_HANDLER2(mfsrin_64b, "mfsrin", 0x1F, 0x13, 0x14, 0x001F0001,
8106              PPC_SEGMENT_64B),
8107 GEN_HANDLER2(mtsr_64b, "mtsr", 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B),
8108 GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001,
8109              PPC_SEGMENT_64B),
8110 GEN_HANDLER2(slbmte, "slbmte", 0x1F, 0x12, 0x0C, 0x00000000, PPC_SEGMENT_64B),
8111 #endif
8112 GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA),
8113 GEN_HANDLER(tlbiel, 0x1F, 0x12, 0x08, 0x03FF0001, PPC_MEM_TLBIE),
8114 GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE),
8115 GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC),
8116 #if defined(TARGET_PPC64)
8117 GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x03FFFC01, PPC_SLBI),
8118 GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI),
8119 #endif
8120 GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN),
8121 GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN),
8122 GEN_HANDLER(abs, 0x1F, 0x08, 0x0B, 0x0000F800, PPC_POWER_BR),
8123 GEN_HANDLER(abso, 0x1F, 0x08, 0x1B, 0x0000F800, PPC_POWER_BR),
8124 GEN_HANDLER(clcs, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR),
8125 GEN_HANDLER(div, 0x1F, 0x0B, 0x0A, 0x00000000, PPC_POWER_BR),
8126 GEN_HANDLER(divo, 0x1F, 0x0B, 0x1A, 0x00000000, PPC_POWER_BR),
8127 GEN_HANDLER(divs, 0x1F, 0x0B, 0x0B, 0x00000000, PPC_POWER_BR),
8128 GEN_HANDLER(divso, 0x1F, 0x0B, 0x1B, 0x00000000, PPC_POWER_BR),
8129 GEN_HANDLER(doz, 0x1F, 0x08, 0x08, 0x00000000, PPC_POWER_BR),
8130 GEN_HANDLER(dozo, 0x1F, 0x08, 0x18, 0x00000000, PPC_POWER_BR),
8131 GEN_HANDLER(dozi, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR),
8132 GEN_HANDLER(lscbx, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR),
8133 GEN_HANDLER(maskg, 0x1F, 0x1D, 0x00, 0x00000000, PPC_POWER_BR),
8134 GEN_HANDLER(maskir, 0x1F, 0x1D, 0x10, 0x00000000, PPC_POWER_BR),
8135 GEN_HANDLER(mul, 0x1F, 0x0B, 0x03, 0x00000000, PPC_POWER_BR),
8136 GEN_HANDLER(mulo, 0x1F, 0x0B, 0x13, 0x00000000, PPC_POWER_BR),
8137 GEN_HANDLER(nabs, 0x1F, 0x08, 0x0F, 0x00000000, PPC_POWER_BR),
8138 GEN_HANDLER(nabso, 0x1F, 0x08, 0x1F, 0x00000000, PPC_POWER_BR),
8139 GEN_HANDLER(rlmi, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR),
8140 GEN_HANDLER(rrib, 0x1F, 0x19, 0x10, 0x00000000, PPC_POWER_BR),
8141 GEN_HANDLER(sle, 0x1F, 0x19, 0x04, 0x00000000, PPC_POWER_BR),
8142 GEN_HANDLER(sleq, 0x1F, 0x19, 0x06, 0x00000000, PPC_POWER_BR),
8143 GEN_HANDLER(sliq, 0x1F, 0x18, 0x05, 0x00000000, PPC_POWER_BR),
8144 GEN_HANDLER(slliq, 0x1F, 0x18, 0x07, 0x00000000, PPC_POWER_BR),
8145 GEN_HANDLER(sllq, 0x1F, 0x18, 0x06, 0x00000000, PPC_POWER_BR),
8146 GEN_HANDLER(slq, 0x1F, 0x18, 0x04, 0x00000000, PPC_POWER_BR),
8147 GEN_HANDLER(sraiq, 0x1F, 0x18, 0x1D, 0x00000000, PPC_POWER_BR),
8148 GEN_HANDLER(sraq, 0x1F, 0x18, 0x1C, 0x00000000, PPC_POWER_BR),
8149 GEN_HANDLER(sre, 0x1F, 0x19, 0x14, 0x00000000, PPC_POWER_BR),
8150 GEN_HANDLER(srea, 0x1F, 0x19, 0x1C, 0x00000000, PPC_POWER_BR),
8151 GEN_HANDLER(sreq, 0x1F, 0x19, 0x16, 0x00000000, PPC_POWER_BR),
8152 GEN_HANDLER(sriq, 0x1F, 0x18, 0x15, 0x00000000, PPC_POWER_BR),
8153 GEN_HANDLER(srliq, 0x1F, 0x18, 0x17, 0x00000000, PPC_POWER_BR),
8154 GEN_HANDLER(srlq, 0x1F, 0x18, 0x16, 0x00000000, PPC_POWER_BR),
8155 GEN_HANDLER(srq, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR),
8156 GEN_HANDLER(dsa, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC),
8157 GEN_HANDLER(esa, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC),
8158 GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC),
8159 GEN_HANDLER2(tlbld_6xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB),
8160 GEN_HANDLER2(tlbli_6xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB),
8161 GEN_HANDLER2(tlbld_74xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_74xx_TLB),
8162 GEN_HANDLER2(tlbli_74xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_74xx_TLB),
8163 GEN_HANDLER(clf, 0x1F, 0x16, 0x03, 0x03E00000, PPC_POWER),
8164 GEN_HANDLER(cli, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER),
8165 GEN_HANDLER(dclst, 0x1F, 0x16, 0x13, 0x03E00000, PPC_POWER),
8166 GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER),
8167 GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER),
8168 GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER),
8169 GEN_HANDLER(lfq, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
8170 GEN_HANDLER(lfqu, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
8171 GEN_HANDLER(lfqux, 0x1F, 0x17, 0x19, 0x00000001, PPC_POWER2),
8172 GEN_HANDLER(lfqx, 0x1F, 0x17, 0x18, 0x00000001, PPC_POWER2),
8173 GEN_HANDLER(stfq, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
8174 GEN_HANDLER(stfqu, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
8175 GEN_HANDLER(stfqux, 0x1F, 0x17, 0x1D, 0x00000001, PPC_POWER2),
8176 GEN_HANDLER(stfqx, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2),
8177 GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_MFAPIDI),
8178 GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_TLBIVA),
8179 GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_DCR),
8180 GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_DCR),
8181 GEN_HANDLER(mfdcrx, 0x1F, 0x03, 0x08, 0x00000000, PPC_DCRX),
8182 GEN_HANDLER(mtdcrx, 0x1F, 0x03, 0x0C, 0x00000000, PPC_DCRX),
8183 GEN_HANDLER(mfdcrux, 0x1F, 0x03, 0x09, 0x00000000, PPC_DCRUX),
8184 GEN_HANDLER(mtdcrux, 0x1F, 0x03, 0x0D, 0x00000000, PPC_DCRUX),
8185 GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON),
8186 GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON),
8187 GEN_HANDLER2(icbt_40x, "icbt", 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_ICBT),
8188 GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON),
8189 GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON),
8190 GEN_HANDLER2(rfci_40x, "rfci", 0x13, 0x13, 0x01, 0x03FF8001, PPC_40x_EXCP),
8191 GEN_HANDLER(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE),
8192 GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_RFDI),
8193 GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_RFMCI),
8194 GEN_HANDLER2(tlbre_40x, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB),
8195 GEN_HANDLER2(tlbsx_40x, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB),
8196 GEN_HANDLER2(tlbwe_40x, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB),
8197 GEN_HANDLER2(tlbre_440, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE),
8198 GEN_HANDLER2(tlbsx_440, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE),
8199 GEN_HANDLER2(tlbwe_440, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE),
8200 GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE),
8201 GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000E7C01, PPC_WRTEE),
8202 GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC),
8203 GEN_HANDLER(mbar, 0x1F, 0x16, 0x1a, 0x001FF801, PPC_BOOKE),
8204 GEN_HANDLER(msync, 0x1F, 0x16, 0x12, 0x03FFF801, PPC_BOOKE),
8205 GEN_HANDLER2(icbt_440, "icbt", 0x1F, 0x16, 0x00, 0x03E00001, PPC_BOOKE),
8206 GEN_HANDLER(lvsl, 0x1f, 0x06, 0x00, 0x00000001, PPC_ALTIVEC),
8207 GEN_HANDLER(lvsr, 0x1f, 0x06, 0x01, 0x00000001, PPC_ALTIVEC),
8208 GEN_HANDLER(mfvscr, 0x04, 0x2, 0x18, 0x001ff800, PPC_ALTIVEC),
8209 GEN_HANDLER(mtvscr, 0x04, 0x2, 0x19, 0x03ff0000, PPC_ALTIVEC),
8210 GEN_HANDLER(vsldoi, 0x04, 0x16, 0xFF, 0x00000400, PPC_ALTIVEC),
8211 GEN_HANDLER(vmladduhm, 0x04, 0x11, 0xFF, 0x00000000, PPC_ALTIVEC),
8212 GEN_HANDLER2(evsel0, "evsel", 0x04, 0x1c, 0x09, 0x00000000, PPC_SPE),
8213 GEN_HANDLER2(evsel1, "evsel", 0x04, 0x1d, 0x09, 0x00000000, PPC_SPE),
8214 GEN_HANDLER2(evsel2, "evsel", 0x04, 0x1e, 0x09, 0x00000000, PPC_SPE),
8215 GEN_HANDLER2(evsel3, "evsel", 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE),
8216
8217 #undef GEN_INT_ARITH_ADD
8218 #undef GEN_INT_ARITH_ADD_CONST
8219 #define GEN_INT_ARITH_ADD(name, opc3, add_ca, compute_ca, compute_ov)         \
8220 GEN_HANDLER(name, 0x1F, 0x0A, opc3, 0x00000000, PPC_INTEGER),
8221 #define GEN_INT_ARITH_ADD_CONST(name, opc3, const_val,                        \
8222                                 add_ca, compute_ca, compute_ov)               \
8223 GEN_HANDLER(name, 0x1F, 0x0A, opc3, 0x0000F800, PPC_INTEGER),
8224 GEN_INT_ARITH_ADD(add, 0x08, 0, 0, 0)
8225 GEN_INT_ARITH_ADD(addo, 0x18, 0, 0, 1)
8226 GEN_INT_ARITH_ADD(addc, 0x00, 0, 1, 0)
8227 GEN_INT_ARITH_ADD(addco, 0x10, 0, 1, 1)
8228 GEN_INT_ARITH_ADD(adde, 0x04, 1, 1, 0)
8229 GEN_INT_ARITH_ADD(addeo, 0x14, 1, 1, 1)
8230 GEN_INT_ARITH_ADD_CONST(addme, 0x07, -1LL, 1, 1, 0)
8231 GEN_INT_ARITH_ADD_CONST(addmeo, 0x17, -1LL, 1, 1, 1)
8232 GEN_INT_ARITH_ADD_CONST(addze, 0x06, 0, 1, 1, 0)
8233 GEN_INT_ARITH_ADD_CONST(addzeo, 0x16, 0, 1, 1, 1)
8234
8235 #undef GEN_INT_ARITH_DIVW
8236 #define GEN_INT_ARITH_DIVW(name, opc3, sign, compute_ov)                      \
8237 GEN_HANDLER(name, 0x1F, 0x0B, opc3, 0x00000000, PPC_INTEGER)
8238 GEN_INT_ARITH_DIVW(divwu, 0x0E, 0, 0),
8239 GEN_INT_ARITH_DIVW(divwuo, 0x1E, 0, 1),
8240 GEN_INT_ARITH_DIVW(divw, 0x0F, 1, 0),
8241 GEN_INT_ARITH_DIVW(divwo, 0x1F, 1, 1),
8242
8243 #if defined(TARGET_PPC64)
8244 #undef GEN_INT_ARITH_DIVD
8245 #define GEN_INT_ARITH_DIVD(name, opc3, sign, compute_ov)                      \
8246 GEN_HANDLER(name, 0x1F, 0x09, opc3, 0x00000000, PPC_64B)
8247 GEN_INT_ARITH_DIVD(divdu, 0x0E, 0, 0),
8248 GEN_INT_ARITH_DIVD(divduo, 0x1E, 0, 1),
8249 GEN_INT_ARITH_DIVD(divd, 0x0F, 1, 0),
8250 GEN_INT_ARITH_DIVD(divdo, 0x1F, 1, 1),
8251
8252 #undef GEN_INT_ARITH_MUL_HELPER
8253 #define GEN_INT_ARITH_MUL_HELPER(name, opc3)                                  \
8254 GEN_HANDLER(name, 0x1F, 0x09, opc3, 0x00000000, PPC_64B)
8255 GEN_INT_ARITH_MUL_HELPER(mulhdu, 0x00),
8256 GEN_INT_ARITH_MUL_HELPER(mulhd, 0x02),
8257 GEN_INT_ARITH_MUL_HELPER(mulldo, 0x17),
8258 #endif
8259
8260 #undef GEN_INT_ARITH_SUBF
8261 #undef GEN_INT_ARITH_SUBF_CONST
8262 #define GEN_INT_ARITH_SUBF(name, opc3, add_ca, compute_ca, compute_ov)        \
8263 GEN_HANDLER(name, 0x1F, 0x08, opc3, 0x00000000, PPC_INTEGER),
8264 #define GEN_INT_ARITH_SUBF_CONST(name, opc3, const_val,                       \
8265                                 add_ca, compute_ca, compute_ov)               \
8266 GEN_HANDLER(name, 0x1F, 0x08, opc3, 0x0000F800, PPC_INTEGER),
8267 GEN_INT_ARITH_SUBF(subf, 0x01, 0, 0, 0)
8268 GEN_INT_ARITH_SUBF(subfo, 0x11, 0, 0, 1)
8269 GEN_INT_ARITH_SUBF(subfc, 0x00, 0, 1, 0)
8270 GEN_INT_ARITH_SUBF(subfco, 0x10, 0, 1, 1)
8271 GEN_INT_ARITH_SUBF(subfe, 0x04, 1, 1, 0)
8272 GEN_INT_ARITH_SUBF(subfeo, 0x14, 1, 1, 1)
8273 GEN_INT_ARITH_SUBF_CONST(subfme, 0x07, -1LL, 1, 1, 0)
8274 GEN_INT_ARITH_SUBF_CONST(subfmeo, 0x17, -1LL, 1, 1, 1)
8275 GEN_INT_ARITH_SUBF_CONST(subfze, 0x06, 0, 1, 1, 0)
8276 GEN_INT_ARITH_SUBF_CONST(subfzeo, 0x16, 0, 1, 1, 1)
8277
8278 #undef GEN_LOGICAL1
8279 #undef GEN_LOGICAL2
8280 #define GEN_LOGICAL2(name, tcg_op, opc, type)                                 \
8281 GEN_HANDLER(name, 0x1F, 0x1C, opc, 0x00000000, type)
8282 #define GEN_LOGICAL1(name, tcg_op, opc, type)                                 \
8283 GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, type)
8284 GEN_LOGICAL2(and, tcg_gen_and_tl, 0x00, PPC_INTEGER),
8285 GEN_LOGICAL2(andc, tcg_gen_andc_tl, 0x01, PPC_INTEGER),
8286 GEN_LOGICAL2(eqv, tcg_gen_eqv_tl, 0x08, PPC_INTEGER),
8287 GEN_LOGICAL1(extsb, tcg_gen_ext8s_tl, 0x1D, PPC_INTEGER),
8288 GEN_LOGICAL1(extsh, tcg_gen_ext16s_tl, 0x1C, PPC_INTEGER),
8289 GEN_LOGICAL2(nand, tcg_gen_nand_tl, 0x0E, PPC_INTEGER),
8290 GEN_LOGICAL2(nor, tcg_gen_nor_tl, 0x03, PPC_INTEGER),
8291 GEN_LOGICAL2(orc, tcg_gen_orc_tl, 0x0C, PPC_INTEGER),
8292 #if defined(TARGET_PPC64)
8293 GEN_LOGICAL1(extsw, tcg_gen_ext32s_tl, 0x1E, PPC_64B),
8294 #endif
8295
8296 #if defined(TARGET_PPC64)
8297 #undef GEN_PPC64_R2
8298 #undef GEN_PPC64_R4
8299 #define GEN_PPC64_R2(name, opc1, opc2)                                        \
8300 GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B),\
8301 GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000,   \
8302              PPC_64B)
8303 #define GEN_PPC64_R4(name, opc1, opc2)                                        \
8304 GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B),\
8305 GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x01, 0xFF, 0x00000000,   \
8306              PPC_64B),                                                        \
8307 GEN_HANDLER2(name##2, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000,   \
8308              PPC_64B),                                                        \
8309 GEN_HANDLER2(name##3, stringify(name), opc1, opc2 | 0x11, 0xFF, 0x00000000,   \
8310              PPC_64B)
8311 GEN_PPC64_R4(rldicl, 0x1E, 0x00),
8312 GEN_PPC64_R4(rldicr, 0x1E, 0x02),
8313 GEN_PPC64_R4(rldic, 0x1E, 0x04),
8314 GEN_PPC64_R2(rldcl, 0x1E, 0x08),
8315 GEN_PPC64_R2(rldcr, 0x1E, 0x09),
8316 GEN_PPC64_R4(rldimi, 0x1E, 0x06),
8317 #endif
8318
8319 #undef _GEN_FLOAT_ACB
8320 #undef GEN_FLOAT_ACB
8321 #undef _GEN_FLOAT_AB
8322 #undef GEN_FLOAT_AB
8323 #undef _GEN_FLOAT_AC
8324 #undef GEN_FLOAT_AC
8325 #undef GEN_FLOAT_B
8326 #undef GEN_FLOAT_BS
8327 #define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat, set_fprf, type)           \
8328 GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, type)
8329 #define GEN_FLOAT_ACB(name, op2, set_fprf, type)                              \
8330 _GEN_FLOAT_ACB(name, name, 0x3F, op2, 0, set_fprf, type),                     \
8331 _GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, set_fprf, type)
8332 #define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
8333 GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)
8334 #define GEN_FLOAT_AB(name, op2, inval, set_fprf, type)                        \
8335 _GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0, set_fprf, type),               \
8336 _GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1, set_fprf, type)
8337 #define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
8338 GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)
8339 #define GEN_FLOAT_AC(name, op2, inval, set_fprf, type)                        \
8340 _GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0, set_fprf, type),               \
8341 _GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1, set_fprf, type)
8342 #define GEN_FLOAT_B(name, op2, op3, set_fprf, type)                           \
8343 GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, type)
8344 #define GEN_FLOAT_BS(name, op1, op2, set_fprf, type)                          \
8345 GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, type)
8346
8347 GEN_FLOAT_AB(add, 0x15, 0x000007C0, 1, PPC_FLOAT),
8348 GEN_FLOAT_AB(div, 0x12, 0x000007C0, 1, PPC_FLOAT),
8349 GEN_FLOAT_AC(mul, 0x19, 0x0000F800, 1, PPC_FLOAT),
8350 GEN_FLOAT_BS(re, 0x3F, 0x18, 1, PPC_FLOAT_EXT),
8351 GEN_FLOAT_BS(res, 0x3B, 0x18, 1, PPC_FLOAT_FRES),
8352 GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A, 1, PPC_FLOAT_FRSQRTE),
8353 _GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0, 0, PPC_FLOAT_FSEL),
8354 GEN_FLOAT_AB(sub, 0x14, 0x000007C0, 1, PPC_FLOAT),
8355 GEN_FLOAT_ACB(madd, 0x1D, 1, PPC_FLOAT),
8356 GEN_FLOAT_ACB(msub, 0x1C, 1, PPC_FLOAT),
8357 GEN_FLOAT_ACB(nmadd, 0x1F, 1, PPC_FLOAT),
8358 GEN_FLOAT_ACB(nmsub, 0x1E, 1, PPC_FLOAT),
8359 GEN_FLOAT_B(ctiw, 0x0E, 0x00, 0, PPC_FLOAT),
8360 GEN_FLOAT_B(ctiwz, 0x0F, 0x00, 0, PPC_FLOAT),
8361 GEN_FLOAT_B(rsp, 0x0C, 0x00, 1, PPC_FLOAT),
8362 #if defined(TARGET_PPC64)
8363 GEN_FLOAT_B(cfid, 0x0E, 0x1A, 1, PPC_64B),
8364 GEN_FLOAT_B(ctid, 0x0E, 0x19, 0, PPC_64B),
8365 GEN_FLOAT_B(ctidz, 0x0F, 0x19, 0, PPC_64B),
8366 #endif
8367 GEN_FLOAT_B(rin, 0x08, 0x0C, 1, PPC_FLOAT_EXT),
8368 GEN_FLOAT_B(riz, 0x08, 0x0D, 1, PPC_FLOAT_EXT),
8369 GEN_FLOAT_B(rip, 0x08, 0x0E, 1, PPC_FLOAT_EXT),
8370 GEN_FLOAT_B(rim, 0x08, 0x0F, 1, PPC_FLOAT_EXT),
8371 GEN_FLOAT_B(abs, 0x08, 0x08, 0, PPC_FLOAT),
8372 GEN_FLOAT_B(nabs, 0x08, 0x04, 0, PPC_FLOAT),
8373 GEN_FLOAT_B(neg, 0x08, 0x01, 0, PPC_FLOAT),
8374
8375 #undef GEN_LD
8376 #undef GEN_LDU
8377 #undef GEN_LDUX
8378 #undef GEN_LDX
8379 #undef GEN_LDS
8380 #define GEN_LD(name, ldop, opc, type)                                         \
8381 GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
8382 #define GEN_LDU(name, ldop, opc, type)                                        \
8383 GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
8384 #define GEN_LDUX(name, ldop, opc2, opc3, type)                                \
8385 GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type),
8386 #define GEN_LDX(name, ldop, opc2, opc3, type)                                 \
8387 GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type),
8388 #define GEN_LDS(name, ldop, op, type)                                         \
8389 GEN_LD(name, ldop, op | 0x20, type)                                           \
8390 GEN_LDU(name, ldop, op | 0x21, type)                                          \
8391 GEN_LDUX(name, ldop, 0x17, op | 0x01, type)                                   \
8392 GEN_LDX(name, ldop, 0x17, op | 0x00, type)
8393
8394 GEN_LDS(lbz, ld8u, 0x02, PPC_INTEGER)
8395 GEN_LDS(lha, ld16s, 0x0A, PPC_INTEGER)
8396 GEN_LDS(lhz, ld16u, 0x08, PPC_INTEGER)
8397 GEN_LDS(lwz, ld32u, 0x00, PPC_INTEGER)
8398 #if defined(TARGET_PPC64)
8399 GEN_LDUX(lwa, ld32s, 0x15, 0x0B, PPC_64B)
8400 GEN_LDX(lwa, ld32s, 0x15, 0x0A, PPC_64B)
8401 GEN_LDUX(ld, ld64, 0x15, 0x01, PPC_64B)
8402 GEN_LDX(ld, ld64, 0x15, 0x00, PPC_64B)
8403 #endif
8404 GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER)
8405 GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER)
8406
8407 #undef GEN_ST
8408 #undef GEN_STU
8409 #undef GEN_STUX
8410 #undef GEN_STX
8411 #undef GEN_STS
8412 #define GEN_ST(name, stop, opc, type)                                         \
8413 GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
8414 #define GEN_STU(name, stop, opc, type)                                        \
8415 GEN_HANDLER(stop##u, opc, 0xFF, 0xFF, 0x00000000, type),
8416 #define GEN_STUX(name, stop, opc2, opc3, type)                                \
8417 GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type),
8418 #define GEN_STX(name, stop, opc2, opc3, type)                                 \
8419 GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type),
8420 #define GEN_STS(name, stop, op, type)                                         \
8421 GEN_ST(name, stop, op | 0x20, type)                                           \
8422 GEN_STU(name, stop, op | 0x21, type)                                          \
8423 GEN_STUX(name, stop, 0x17, op | 0x01, type)                                   \
8424 GEN_STX(name, stop, 0x17, op | 0x00, type)
8425
8426 GEN_STS(stb, st8, 0x06, PPC_INTEGER)
8427 GEN_STS(sth, st16, 0x0C, PPC_INTEGER)
8428 GEN_STS(stw, st32, 0x04, PPC_INTEGER)
8429 #if defined(TARGET_PPC64)
8430 GEN_STUX(std, st64, 0x15, 0x05, PPC_64B)
8431 GEN_STX(std, st64, 0x15, 0x04, PPC_64B)
8432 #endif
8433 GEN_STX(sthbr, st16r, 0x16, 0x1C, PPC_INTEGER)
8434 GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER)
8435
8436 #undef GEN_LDF
8437 #undef GEN_LDUF
8438 #undef GEN_LDUXF
8439 #undef GEN_LDXF
8440 #undef GEN_LDFS
8441 #define GEN_LDF(name, ldop, opc, type)                                        \
8442 GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
8443 #define GEN_LDUF(name, ldop, opc, type)                                       \
8444 GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
8445 #define GEN_LDUXF(name, ldop, opc, type)                                      \
8446 GEN_HANDLER(name##ux, 0x1F, 0x17, opc, 0x00000001, type),
8447 #define GEN_LDXF(name, ldop, opc2, opc3, type)                                \
8448 GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type),
8449 #define GEN_LDFS(name, ldop, op, type)                                        \
8450 GEN_LDF(name, ldop, op | 0x20, type)                                          \
8451 GEN_LDUF(name, ldop, op | 0x21, type)                                         \
8452 GEN_LDUXF(name, ldop, op | 0x01, type)                                        \
8453 GEN_LDXF(name, ldop, 0x17, op | 0x00, type)
8454
8455 GEN_LDFS(lfd, ld64, 0x12, PPC_FLOAT)
8456 GEN_LDFS(lfs, ld32fs, 0x10, PPC_FLOAT)
8457
8458 #undef GEN_STF
8459 #undef GEN_STUF
8460 #undef GEN_STUXF
8461 #undef GEN_STXF
8462 #undef GEN_STFS
8463 #define GEN_STF(name, stop, opc, type)                                        \
8464 GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
8465 #define GEN_STUF(name, stop, opc, type)                                       \
8466 GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
8467 #define GEN_STUXF(name, stop, opc, type)                                      \
8468 GEN_HANDLER(name##ux, 0x1F, 0x17, opc, 0x00000001, type),
8469 #define GEN_STXF(name, stop, opc2, opc3, type)                                \
8470 GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type),
8471 #define GEN_STFS(name, stop, op, type)                                        \
8472 GEN_STF(name, stop, op | 0x20, type)                                          \
8473 GEN_STUF(name, stop, op | 0x21, type)                                         \
8474 GEN_STUXF(name, stop, op | 0x01, type)                                        \
8475 GEN_STXF(name, stop, 0x17, op | 0x00, type)
8476
8477 GEN_STFS(stfd, st64, 0x16, PPC_FLOAT)
8478 GEN_STFS(stfs, st32fs, 0x14, PPC_FLOAT)
8479 GEN_STXF(stfiw, st32fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX)
8480
8481 #undef GEN_CRLOGIC
8482 #define GEN_CRLOGIC(name, tcg_op, opc)                                        \
8483 GEN_HANDLER(name, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER)
8484 GEN_CRLOGIC(crand, tcg_gen_and_i32, 0x08),
8485 GEN_CRLOGIC(crandc, tcg_gen_andc_i32, 0x04),
8486 GEN_CRLOGIC(creqv, tcg_gen_eqv_i32, 0x09),
8487 GEN_CRLOGIC(crnand, tcg_gen_nand_i32, 0x07),
8488 GEN_CRLOGIC(crnor, tcg_gen_nor_i32, 0x01),
8489 GEN_CRLOGIC(cror, tcg_gen_or_i32, 0x0E),
8490 GEN_CRLOGIC(crorc, tcg_gen_orc_i32, 0x0D),
8491 GEN_CRLOGIC(crxor, tcg_gen_xor_i32, 0x06),
8492
8493 #undef GEN_MAC_HANDLER
8494 #define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
8495 GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC)
8496 GEN_MAC_HANDLER(macchw, 0x0C, 0x05),
8497 GEN_MAC_HANDLER(macchwo, 0x0C, 0x15),
8498 GEN_MAC_HANDLER(macchws, 0x0C, 0x07),
8499 GEN_MAC_HANDLER(macchwso, 0x0C, 0x17),
8500 GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06),
8501 GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16),
8502 GEN_MAC_HANDLER(macchwu, 0x0C, 0x04),
8503 GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14),
8504 GEN_MAC_HANDLER(machhw, 0x0C, 0x01),
8505 GEN_MAC_HANDLER(machhwo, 0x0C, 0x11),
8506 GEN_MAC_HANDLER(machhws, 0x0C, 0x03),
8507 GEN_MAC_HANDLER(machhwso, 0x0C, 0x13),
8508 GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02),
8509 GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12),
8510 GEN_MAC_HANDLER(machhwu, 0x0C, 0x00),
8511 GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10),
8512 GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D),
8513 GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D),
8514 GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F),
8515 GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F),
8516 GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C),
8517 GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C),
8518 GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E),
8519 GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E),
8520 GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05),
8521 GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15),
8522 GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07),
8523 GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17),
8524 GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01),
8525 GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11),
8526 GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03),
8527 GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13),
8528 GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D),
8529 GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D),
8530 GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F),
8531 GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F),
8532 GEN_MAC_HANDLER(mulchw, 0x08, 0x05),
8533 GEN_MAC_HANDLER(mulchwu, 0x08, 0x04),
8534 GEN_MAC_HANDLER(mulhhw, 0x08, 0x01),
8535 GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00),
8536 GEN_MAC_HANDLER(mullhw, 0x08, 0x0D),
8537 GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C),
8538
8539 #undef GEN_VR_LDX
8540 #undef GEN_VR_STX
8541 #undef GEN_VR_LVE
8542 #undef GEN_VR_STVE
8543 #define GEN_VR_LDX(name, opc2, opc3)                                          \
8544 GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
8545 #define GEN_VR_STX(name, opc2, opc3)                                          \
8546 GEN_HANDLER(st##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
8547 #define GEN_VR_LVE(name, opc2, opc3)                                    \
8548     GEN_HANDLER(lve##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
8549 #define GEN_VR_STVE(name, opc2, opc3)                                   \
8550     GEN_HANDLER(stve##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
8551 GEN_VR_LDX(lvx, 0x07, 0x03),
8552 GEN_VR_LDX(lvxl, 0x07, 0x0B),
8553 GEN_VR_LVE(bx, 0x07, 0x00),
8554 GEN_VR_LVE(hx, 0x07, 0x01),
8555 GEN_VR_LVE(wx, 0x07, 0x02),
8556 GEN_VR_STX(svx, 0x07, 0x07),
8557 GEN_VR_STX(svxl, 0x07, 0x0F),
8558 GEN_VR_STVE(bx, 0x07, 0x04),
8559 GEN_VR_STVE(hx, 0x07, 0x05),
8560 GEN_VR_STVE(wx, 0x07, 0x06),
8561
8562 #undef GEN_VX_LOGICAL
8563 #define GEN_VX_LOGICAL(name, tcg_op, opc2, opc3)                        \
8564 GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
8565 GEN_VX_LOGICAL(vand, tcg_gen_and_i64, 2, 16),
8566 GEN_VX_LOGICAL(vandc, tcg_gen_andc_i64, 2, 17),
8567 GEN_VX_LOGICAL(vor, tcg_gen_or_i64, 2, 18),
8568 GEN_VX_LOGICAL(vxor, tcg_gen_xor_i64, 2, 19),
8569 GEN_VX_LOGICAL(vnor, tcg_gen_nor_i64, 2, 20),
8570
8571 #undef GEN_VXFORM
8572 #define GEN_VXFORM(name, opc2, opc3)                                    \
8573 GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
8574 GEN_VXFORM(vaddubm, 0, 0),
8575 GEN_VXFORM(vadduhm, 0, 1),
8576 GEN_VXFORM(vadduwm, 0, 2),
8577 GEN_VXFORM(vsububm, 0, 16),
8578 GEN_VXFORM(vsubuhm, 0, 17),
8579 GEN_VXFORM(vsubuwm, 0, 18),
8580 GEN_VXFORM(vmaxub, 1, 0),
8581 GEN_VXFORM(vmaxuh, 1, 1),
8582 GEN_VXFORM(vmaxuw, 1, 2),
8583 GEN_VXFORM(vmaxsb, 1, 4),
8584 GEN_VXFORM(vmaxsh, 1, 5),
8585 GEN_VXFORM(vmaxsw, 1, 6),
8586 GEN_VXFORM(vminub, 1, 8),
8587 GEN_VXFORM(vminuh, 1, 9),
8588 GEN_VXFORM(vminuw, 1, 10),
8589 GEN_VXFORM(vminsb, 1, 12),
8590 GEN_VXFORM(vminsh, 1, 13),
8591 GEN_VXFORM(vminsw, 1, 14),
8592 GEN_VXFORM(vavgub, 1, 16),
8593 GEN_VXFORM(vavguh, 1, 17),
8594 GEN_VXFORM(vavguw, 1, 18),
8595 GEN_VXFORM(vavgsb, 1, 20),
8596 GEN_VXFORM(vavgsh, 1, 21),
8597 GEN_VXFORM(vavgsw, 1, 22),
8598 GEN_VXFORM(vmrghb, 6, 0),
8599 GEN_VXFORM(vmrghh, 6, 1),
8600 GEN_VXFORM(vmrghw, 6, 2),
8601 GEN_VXFORM(vmrglb, 6, 4),
8602 GEN_VXFORM(vmrglh, 6, 5),
8603 GEN_VXFORM(vmrglw, 6, 6),
8604 GEN_VXFORM(vmuloub, 4, 0),
8605 GEN_VXFORM(vmulouh, 4, 1),
8606 GEN_VXFORM(vmulosb, 4, 4),
8607 GEN_VXFORM(vmulosh, 4, 5),
8608 GEN_VXFORM(vmuleub, 4, 8),
8609 GEN_VXFORM(vmuleuh, 4, 9),
8610 GEN_VXFORM(vmulesb, 4, 12),
8611 GEN_VXFORM(vmulesh, 4, 13),
8612 GEN_VXFORM(vslb, 2, 4),
8613 GEN_VXFORM(vslh, 2, 5),
8614 GEN_VXFORM(vslw, 2, 6),
8615 GEN_VXFORM(vsrb, 2, 8),
8616 GEN_VXFORM(vsrh, 2, 9),
8617 GEN_VXFORM(vsrw, 2, 10),
8618 GEN_VXFORM(vsrab, 2, 12),
8619 GEN_VXFORM(vsrah, 2, 13),
8620 GEN_VXFORM(vsraw, 2, 14),
8621 GEN_VXFORM(vslo, 6, 16),
8622 GEN_VXFORM(vsro, 6, 17),
8623 GEN_VXFORM(vaddcuw, 0, 6),
8624 GEN_VXFORM(vsubcuw, 0, 22),
8625 GEN_VXFORM(vaddubs, 0, 8),
8626 GEN_VXFORM(vadduhs, 0, 9),
8627 GEN_VXFORM(vadduws, 0, 10),
8628 GEN_VXFORM(vaddsbs, 0, 12),
8629 GEN_VXFORM(vaddshs, 0, 13),
8630 GEN_VXFORM(vaddsws, 0, 14),
8631 GEN_VXFORM(vsububs, 0, 24),
8632 GEN_VXFORM(vsubuhs, 0, 25),
8633 GEN_VXFORM(vsubuws, 0, 26),
8634 GEN_VXFORM(vsubsbs, 0, 28),
8635 GEN_VXFORM(vsubshs, 0, 29),
8636 GEN_VXFORM(vsubsws, 0, 30),
8637 GEN_VXFORM(vrlb, 2, 0),
8638 GEN_VXFORM(vrlh, 2, 1),
8639 GEN_VXFORM(vrlw, 2, 2),
8640 GEN_VXFORM(vsl, 2, 7),
8641 GEN_VXFORM(vsr, 2, 11),
8642 GEN_VXFORM(vpkuhum, 7, 0),
8643 GEN_VXFORM(vpkuwum, 7, 1),
8644 GEN_VXFORM(vpkuhus, 7, 2),
8645 GEN_VXFORM(vpkuwus, 7, 3),
8646 GEN_VXFORM(vpkshus, 7, 4),
8647 GEN_VXFORM(vpkswus, 7, 5),
8648 GEN_VXFORM(vpkshss, 7, 6),
8649 GEN_VXFORM(vpkswss, 7, 7),
8650 GEN_VXFORM(vpkpx, 7, 12),
8651 GEN_VXFORM(vsum4ubs, 4, 24),
8652 GEN_VXFORM(vsum4sbs, 4, 28),
8653 GEN_VXFORM(vsum4shs, 4, 25),
8654 GEN_VXFORM(vsum2sws, 4, 26),
8655 GEN_VXFORM(vsumsws, 4, 30),
8656 GEN_VXFORM(vaddfp, 5, 0),
8657 GEN_VXFORM(vsubfp, 5, 1),
8658 GEN_VXFORM(vmaxfp, 5, 16),
8659 GEN_VXFORM(vminfp, 5, 17),
8660
8661 #undef GEN_VXRFORM1
8662 #undef GEN_VXRFORM
8663 #define GEN_VXRFORM1(opname, name, str, opc2, opc3)                     \
8664     GEN_HANDLER2(name, str, 0x4, opc2, opc3, 0x00000000, PPC_ALTIVEC),
8665 #define GEN_VXRFORM(name, opc2, opc3)                                \
8666     GEN_VXRFORM1(name, name, #name, opc2, opc3)                      \
8667     GEN_VXRFORM1(name##_dot, name##_, #name ".", opc2, (opc3 | (0x1 << 4)))
8668 GEN_VXRFORM(vcmpequb, 3, 0)
8669 GEN_VXRFORM(vcmpequh, 3, 1)
8670 GEN_VXRFORM(vcmpequw, 3, 2)
8671 GEN_VXRFORM(vcmpgtsb, 3, 12)
8672 GEN_VXRFORM(vcmpgtsh, 3, 13)
8673 GEN_VXRFORM(vcmpgtsw, 3, 14)
8674 GEN_VXRFORM(vcmpgtub, 3, 8)
8675 GEN_VXRFORM(vcmpgtuh, 3, 9)
8676 GEN_VXRFORM(vcmpgtuw, 3, 10)
8677 GEN_VXRFORM(vcmpeqfp, 3, 3)
8678 GEN_VXRFORM(vcmpgefp, 3, 7)
8679 GEN_VXRFORM(vcmpgtfp, 3, 11)
8680 GEN_VXRFORM(vcmpbfp, 3, 15)
8681
8682 #undef GEN_VXFORM_SIMM
8683 #define GEN_VXFORM_SIMM(name, opc2, opc3)                               \
8684     GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
8685 GEN_VXFORM_SIMM(vspltisb, 6, 12),
8686 GEN_VXFORM_SIMM(vspltish, 6, 13),
8687 GEN_VXFORM_SIMM(vspltisw, 6, 14),
8688
8689 #undef GEN_VXFORM_NOA
8690 #define GEN_VXFORM_NOA(name, opc2, opc3)                                \
8691     GEN_HANDLER(name, 0x04, opc2, opc3, 0x001f0000, PPC_ALTIVEC)
8692 GEN_VXFORM_NOA(vupkhsb, 7, 8),
8693 GEN_VXFORM_NOA(vupkhsh, 7, 9),
8694 GEN_VXFORM_NOA(vupklsb, 7, 10),
8695 GEN_VXFORM_NOA(vupklsh, 7, 11),
8696 GEN_VXFORM_NOA(vupkhpx, 7, 13),
8697 GEN_VXFORM_NOA(vupklpx, 7, 15),
8698 GEN_VXFORM_NOA(vrefp, 5, 4),
8699 GEN_VXFORM_NOA(vrsqrtefp, 5, 5),
8700 GEN_VXFORM_NOA(vexptefp, 5, 6),
8701 GEN_VXFORM_NOA(vlogefp, 5, 7),
8702 GEN_VXFORM_NOA(vrfim, 5, 8),
8703 GEN_VXFORM_NOA(vrfin, 5, 9),
8704 GEN_VXFORM_NOA(vrfip, 5, 10),
8705 GEN_VXFORM_NOA(vrfiz, 5, 11),
8706
8707 #undef GEN_VXFORM_UIMM
8708 #define GEN_VXFORM_UIMM(name, opc2, opc3)                               \
8709     GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
8710 GEN_VXFORM_UIMM(vspltb, 6, 8),
8711 GEN_VXFORM_UIMM(vsplth, 6, 9),
8712 GEN_VXFORM_UIMM(vspltw, 6, 10),
8713 GEN_VXFORM_UIMM(vcfux, 5, 12),
8714 GEN_VXFORM_UIMM(vcfsx, 5, 13),
8715 GEN_VXFORM_UIMM(vctuxs, 5, 14),
8716 GEN_VXFORM_UIMM(vctsxs, 5, 15),
8717
8718 #undef GEN_VAFORM_PAIRED
8719 #define GEN_VAFORM_PAIRED(name0, name1, opc2)                           \
8720     GEN_HANDLER(name0##_##name1, 0x04, opc2, 0xFF, 0x00000000, PPC_ALTIVEC)
8721 GEN_VAFORM_PAIRED(vmhaddshs, vmhraddshs, 16),
8722 GEN_VAFORM_PAIRED(vmsumubm, vmsummbm, 18),
8723 GEN_VAFORM_PAIRED(vmsumuhm, vmsumuhs, 19),
8724 GEN_VAFORM_PAIRED(vmsumshm, vmsumshs, 20),
8725 GEN_VAFORM_PAIRED(vsel, vperm, 21),
8726 GEN_VAFORM_PAIRED(vmaddfp, vnmsubfp, 23),
8727
8728 #undef GEN_SPE
8729 #define GEN_SPE(name0, name1, opc2, opc3, inval, type)                        \
8730 GEN_HANDLER(name0##_##name1, 0x04, opc2, opc3, inval, type)
8731 GEN_SPE(evaddw,         speundef,      0x00, 0x08, 0x00000000, PPC_SPE),
8732 GEN_SPE(evaddiw,        speundef,      0x01, 0x08, 0x00000000, PPC_SPE),
8733 GEN_SPE(evsubfw,        speundef,      0x02, 0x08, 0x00000000, PPC_SPE),
8734 GEN_SPE(evsubifw,       speundef,      0x03, 0x08, 0x00000000, PPC_SPE),
8735 GEN_SPE(evabs,          evneg,         0x04, 0x08, 0x0000F800, PPC_SPE),
8736 GEN_SPE(evextsb,        evextsh,       0x05, 0x08, 0x0000F800, PPC_SPE),
8737 GEN_SPE(evrndw,         evcntlzw,      0x06, 0x08, 0x0000F800, PPC_SPE),
8738 GEN_SPE(evcntlsw,       brinc,         0x07, 0x08, 0x00000000, PPC_SPE),
8739 GEN_SPE(speundef,       evand,         0x08, 0x08, 0x00000000, PPC_SPE),
8740 GEN_SPE(evandc,         speundef,      0x09, 0x08, 0x00000000, PPC_SPE),
8741 GEN_SPE(evxor,          evor,          0x0B, 0x08, 0x00000000, PPC_SPE),
8742 GEN_SPE(evnor,          eveqv,         0x0C, 0x08, 0x00000000, PPC_SPE),
8743 GEN_SPE(speundef,       evorc,         0x0D, 0x08, 0x00000000, PPC_SPE),
8744 GEN_SPE(evnand,         speundef,      0x0F, 0x08, 0x00000000, PPC_SPE),
8745 GEN_SPE(evsrwu,         evsrws,        0x10, 0x08, 0x00000000, PPC_SPE),
8746 GEN_SPE(evsrwiu,        evsrwis,       0x11, 0x08, 0x00000000, PPC_SPE),
8747 GEN_SPE(evslw,          speundef,      0x12, 0x08, 0x00000000, PPC_SPE),
8748 GEN_SPE(evslwi,         speundef,      0x13, 0x08, 0x00000000, PPC_SPE),
8749 GEN_SPE(evrlw,          evsplati,      0x14, 0x08, 0x00000000, PPC_SPE),
8750 GEN_SPE(evrlwi,         evsplatfi,     0x15, 0x08, 0x00000000, PPC_SPE),
8751 GEN_SPE(evmergehi,      evmergelo,     0x16, 0x08, 0x00000000, PPC_SPE),
8752 GEN_SPE(evmergehilo,    evmergelohi,   0x17, 0x08, 0x00000000, PPC_SPE),
8753 GEN_SPE(evcmpgtu,       evcmpgts,      0x18, 0x08, 0x00600000, PPC_SPE),
8754 GEN_SPE(evcmpltu,       evcmplts,      0x19, 0x08, 0x00600000, PPC_SPE),
8755 GEN_SPE(evcmpeq,        speundef,      0x1A, 0x08, 0x00600000, PPC_SPE),
8756
8757 GEN_SPE(evfsadd,        evfssub,       0x00, 0x0A, 0x00000000, PPC_SPE_SINGLE),
8758 GEN_SPE(evfsabs,        evfsnabs,      0x02, 0x0A, 0x0000F800, PPC_SPE_SINGLE),
8759 GEN_SPE(evfsneg,        speundef,      0x03, 0x0A, 0x0000F800, PPC_SPE_SINGLE),
8760 GEN_SPE(evfsmul,        evfsdiv,       0x04, 0x0A, 0x00000000, PPC_SPE_SINGLE),
8761 GEN_SPE(evfscmpgt,      evfscmplt,     0x06, 0x0A, 0x00600000, PPC_SPE_SINGLE),
8762 GEN_SPE(evfscmpeq,      speundef,      0x07, 0x0A, 0x00600000, PPC_SPE_SINGLE),
8763 GEN_SPE(evfscfui,       evfscfsi,      0x08, 0x0A, 0x00180000, PPC_SPE_SINGLE),
8764 GEN_SPE(evfscfuf,       evfscfsf,      0x09, 0x0A, 0x00180000, PPC_SPE_SINGLE),
8765 GEN_SPE(evfsctui,       evfsctsi,      0x0A, 0x0A, 0x00180000, PPC_SPE_SINGLE),
8766 GEN_SPE(evfsctuf,       evfsctsf,      0x0B, 0x0A, 0x00180000, PPC_SPE_SINGLE),
8767 GEN_SPE(evfsctuiz,      speundef,      0x0C, 0x0A, 0x00180000, PPC_SPE_SINGLE),
8768 GEN_SPE(evfsctsiz,      speundef,      0x0D, 0x0A, 0x00180000, PPC_SPE_SINGLE),
8769 GEN_SPE(evfststgt,      evfststlt,     0x0E, 0x0A, 0x00600000, PPC_SPE_SINGLE),
8770 GEN_SPE(evfststeq,      speundef,      0x0F, 0x0A, 0x00600000, PPC_SPE_SINGLE),
8771
8772 GEN_SPE(efsadd,         efssub,        0x00, 0x0B, 0x00000000, PPC_SPE_SINGLE),
8773 GEN_SPE(efsabs,         efsnabs,       0x02, 0x0B, 0x0000F800, PPC_SPE_SINGLE),
8774 GEN_SPE(efsneg,         speundef,      0x03, 0x0B, 0x0000F800, PPC_SPE_SINGLE),
8775 GEN_SPE(efsmul,         efsdiv,        0x04, 0x0B, 0x00000000, PPC_SPE_SINGLE),
8776 GEN_SPE(efscmpgt,       efscmplt,      0x06, 0x0B, 0x00600000, PPC_SPE_SINGLE),
8777 GEN_SPE(efscmpeq,       efscfd,        0x07, 0x0B, 0x00600000, PPC_SPE_SINGLE),
8778 GEN_SPE(efscfui,        efscfsi,       0x08, 0x0B, 0x00180000, PPC_SPE_SINGLE),
8779 GEN_SPE(efscfuf,        efscfsf,       0x09, 0x0B, 0x00180000, PPC_SPE_SINGLE),
8780 GEN_SPE(efsctui,        efsctsi,       0x0A, 0x0B, 0x00180000, PPC_SPE_SINGLE),
8781 GEN_SPE(efsctuf,        efsctsf,       0x0B, 0x0B, 0x00180000, PPC_SPE_SINGLE),
8782 GEN_SPE(efsctuiz,       speundef,      0x0C, 0x0B, 0x00180000, PPC_SPE_SINGLE),
8783 GEN_SPE(efsctsiz,       speundef,      0x0D, 0x0B, 0x00180000, PPC_SPE_SINGLE),
8784 GEN_SPE(efststgt,       efststlt,      0x0E, 0x0B, 0x00600000, PPC_SPE_SINGLE),
8785 GEN_SPE(efststeq,       speundef,      0x0F, 0x0B, 0x00600000, PPC_SPE_SINGLE),
8786
8787 GEN_SPE(efdadd,         efdsub,        0x10, 0x0B, 0x00000000, PPC_SPE_DOUBLE),
8788 GEN_SPE(efdcfuid,       efdcfsid,      0x11, 0x0B, 0x00180000, PPC_SPE_DOUBLE),
8789 GEN_SPE(efdabs,         efdnabs,       0x12, 0x0B, 0x0000F800, PPC_SPE_DOUBLE),
8790 GEN_SPE(efdneg,         speundef,      0x13, 0x0B, 0x0000F800, PPC_SPE_DOUBLE),
8791 GEN_SPE(efdmul,         efddiv,        0x14, 0x0B, 0x00000000, PPC_SPE_DOUBLE),
8792 GEN_SPE(efdctuidz,      efdctsidz,     0x15, 0x0B, 0x00180000, PPC_SPE_DOUBLE),
8793 GEN_SPE(efdcmpgt,       efdcmplt,      0x16, 0x0B, 0x00600000, PPC_SPE_DOUBLE),
8794 GEN_SPE(efdcmpeq,       efdcfs,        0x17, 0x0B, 0x00600000, PPC_SPE_DOUBLE),
8795 GEN_SPE(efdcfui,        efdcfsi,       0x18, 0x0B, 0x00180000, PPC_SPE_DOUBLE),
8796 GEN_SPE(efdcfuf,        efdcfsf,       0x19, 0x0B, 0x00180000, PPC_SPE_DOUBLE),
8797 GEN_SPE(efdctui,        efdctsi,       0x1A, 0x0B, 0x00180000, PPC_SPE_DOUBLE),
8798 GEN_SPE(efdctuf,        efdctsf,       0x1B, 0x0B, 0x00180000, PPC_SPE_DOUBLE),
8799 GEN_SPE(efdctuiz,       speundef,      0x1C, 0x0B, 0x00180000, PPC_SPE_DOUBLE),
8800 GEN_SPE(efdctsiz,       speundef,      0x1D, 0x0B, 0x00180000, PPC_SPE_DOUBLE),
8801 GEN_SPE(efdtstgt,       efdtstlt,      0x1E, 0x0B, 0x00600000, PPC_SPE_DOUBLE),
8802 GEN_SPE(efdtsteq,       speundef,      0x1F, 0x0B, 0x00600000, PPC_SPE_DOUBLE),
8803
8804 #undef GEN_SPEOP_LDST
8805 #define GEN_SPEOP_LDST(name, opc2, sh)                                        \
8806 GEN_HANDLER(name, 0x04, opc2, 0x0C, 0x00000000, PPC_SPE)
8807 GEN_SPEOP_LDST(evldd, 0x00, 3),
8808 GEN_SPEOP_LDST(evldw, 0x01, 3),
8809 GEN_SPEOP_LDST(evldh, 0x02, 3),
8810 GEN_SPEOP_LDST(evlhhesplat, 0x04, 1),
8811 GEN_SPEOP_LDST(evlhhousplat, 0x06, 1),
8812 GEN_SPEOP_LDST(evlhhossplat, 0x07, 1),
8813 GEN_SPEOP_LDST(evlwhe, 0x08, 2),
8814 GEN_SPEOP_LDST(evlwhou, 0x0A, 2),
8815 GEN_SPEOP_LDST(evlwhos, 0x0B, 2),
8816 GEN_SPEOP_LDST(evlwwsplat, 0x0C, 2),
8817 GEN_SPEOP_LDST(evlwhsplat, 0x0E, 2),
8818
8819 GEN_SPEOP_LDST(evstdd, 0x10, 3),
8820 GEN_SPEOP_LDST(evstdw, 0x11, 3),
8821 GEN_SPEOP_LDST(evstdh, 0x12, 3),
8822 GEN_SPEOP_LDST(evstwhe, 0x18, 2),
8823 GEN_SPEOP_LDST(evstwho, 0x1A, 2),
8824 GEN_SPEOP_LDST(evstwwe, 0x1C, 2),
8825 GEN_SPEOP_LDST(evstwwo, 0x1E, 2),
8826 };
8827
8828 #include "translate_init.c"
8829 #include "helper_regs.h"
8830
8831 /*****************************************************************************/
8832 /* Misc PowerPC helpers */
8833 void cpu_dump_state (CPUState *env, FILE *f,
8834                      int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8835                      int flags)
8836 {
8837 #define RGPL  4
8838 #define RFPL  4
8839
8840     int i;
8841
8842     cpu_fprintf(f, "NIP " TARGET_FMT_lx "   LR " TARGET_FMT_lx " CTR "
8843                 TARGET_FMT_lx " XER %08x\n", env->nip, env->lr, env->ctr,
8844                 env->xer);
8845     cpu_fprintf(f, "MSR " TARGET_FMT_lx " HID0 " TARGET_FMT_lx "  HF "
8846                 TARGET_FMT_lx " idx %d\n", env->msr, env->spr[SPR_HID0],
8847                 env->hflags, env->mmu_idx);
8848 #if !defined(NO_TIMER_DUMP)
8849     cpu_fprintf(f, "TB %08x %08x "
8850 #if !defined(CONFIG_USER_ONLY)
8851                 "DECR %08x"
8852 #endif
8853                 "\n",
8854                 cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
8855 #if !defined(CONFIG_USER_ONLY)
8856                 , cpu_ppc_load_decr(env)
8857 #endif
8858                 );
8859 #endif
8860     for (i = 0; i < 32; i++) {
8861         if ((i & (RGPL - 1)) == 0)
8862             cpu_fprintf(f, "GPR%02d", i);
8863         cpu_fprintf(f, " %016" PRIx64, ppc_dump_gpr(env, i));
8864         if ((i & (RGPL - 1)) == (RGPL - 1))
8865             cpu_fprintf(f, "\n");
8866     }
8867     cpu_fprintf(f, "CR ");
8868     for (i = 0; i < 8; i++)
8869         cpu_fprintf(f, "%01x", env->crf[i]);
8870     cpu_fprintf(f, "  [");
8871     for (i = 0; i < 8; i++) {
8872         char a = '-';
8873         if (env->crf[i] & 0x08)
8874             a = 'L';
8875         else if (env->crf[i] & 0x04)
8876             a = 'G';
8877         else if (env->crf[i] & 0x02)
8878             a = 'E';
8879         cpu_fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
8880     }
8881     cpu_fprintf(f, " ]             RES " TARGET_FMT_lx "\n",
8882                 env->reserve_addr);
8883     for (i = 0; i < 32; i++) {
8884         if ((i & (RFPL - 1)) == 0)
8885             cpu_fprintf(f, "FPR%02d", i);
8886         cpu_fprintf(f, " %016" PRIx64, *((uint64_t *)&env->fpr[i]));
8887         if ((i & (RFPL - 1)) == (RFPL - 1))
8888             cpu_fprintf(f, "\n");
8889     }
8890     cpu_fprintf(f, "FPSCR %08x\n", env->fpscr);
8891 #if !defined(CONFIG_USER_ONLY)
8892     cpu_fprintf(f, "SRR0 " TARGET_FMT_lx " SRR1 " TARGET_FMT_lx " SDR1 "
8893                 TARGET_FMT_lx "\n", env->spr[SPR_SRR0], env->spr[SPR_SRR1],
8894                 env->sdr1);
8895 #endif
8896
8897 #undef RGPL
8898 #undef RFPL
8899 }
8900
8901 void cpu_dump_statistics (CPUState *env, FILE*f,
8902                           int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8903                           int flags)
8904 {
8905 #if defined(DO_PPC_STATISTICS)
8906     opc_handler_t **t1, **t2, **t3, *handler;
8907     int op1, op2, op3;
8908
8909     t1 = env->opcodes;
8910     for (op1 = 0; op1 < 64; op1++) {
8911         handler = t1[op1];
8912         if (is_indirect_opcode(handler)) {
8913             t2 = ind_table(handler);
8914             for (op2 = 0; op2 < 32; op2++) {
8915                 handler = t2[op2];
8916                 if (is_indirect_opcode(handler)) {
8917                     t3 = ind_table(handler);
8918                     for (op3 = 0; op3 < 32; op3++) {
8919                         handler = t3[op3];
8920                         if (handler->count == 0)
8921                             continue;
8922                         cpu_fprintf(f, "%02x %02x %02x (%02x %04d) %16s: "
8923                                     "%016" PRIx64 " %" PRId64 "\n",
8924                                     op1, op2, op3, op1, (op3 << 5) | op2,
8925                                     handler->oname,
8926                                     handler->count, handler->count);
8927                     }
8928                 } else {
8929                     if (handler->count == 0)
8930                         continue;
8931                     cpu_fprintf(f, "%02x %02x    (%02x %04d) %16s: "
8932                                 "%016" PRIx64 " %" PRId64 "\n",
8933                                 op1, op2, op1, op2, handler->oname,
8934                                 handler->count, handler->count);
8935                 }
8936             }
8937         } else {
8938             if (handler->count == 0)
8939                 continue;
8940             cpu_fprintf(f, "%02x       (%02x     ) %16s: %016" PRIx64
8941                         " %" PRId64 "\n",
8942                         op1, op1, handler->oname,
8943                         handler->count, handler->count);
8944         }
8945     }
8946 #endif
8947 }
8948
8949 /*****************************************************************************/
8950 static inline void gen_intermediate_code_internal(CPUState *env,
8951                                                   TranslationBlock *tb,
8952                                                   int search_pc)
8953 {
8954     DisasContext ctx, *ctxp = &ctx;
8955     opc_handler_t **table, *handler;
8956     target_ulong pc_start;
8957     uint16_t *gen_opc_end;
8958     CPUBreakpoint *bp;
8959     int j, lj = -1;
8960     int num_insns;
8961     int max_insns;
8962
8963     pc_start = tb->pc;
8964     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
8965     ctx.nip = pc_start;
8966     ctx.tb = tb;
8967     ctx.exception = POWERPC_EXCP_NONE;
8968     ctx.spr_cb = env->spr_cb;
8969     ctx.mem_idx = env->mmu_idx;
8970     ctx.access_type = -1;
8971     ctx.le_mode = env->hflags & (1 << MSR_LE) ? 1 : 0;
8972 #if defined(TARGET_PPC64)
8973     ctx.sf_mode = msr_sf;
8974 #endif
8975     ctx.fpu_enabled = msr_fp;
8976     if ((env->flags & POWERPC_FLAG_SPE) && msr_spe)
8977         ctx.spe_enabled = msr_spe;
8978     else
8979         ctx.spe_enabled = 0;
8980     if ((env->flags & POWERPC_FLAG_VRE) && msr_vr)
8981         ctx.altivec_enabled = msr_vr;
8982     else
8983         ctx.altivec_enabled = 0;
8984     if ((env->flags & POWERPC_FLAG_SE) && msr_se)
8985         ctx.singlestep_enabled = CPU_SINGLE_STEP;
8986     else
8987         ctx.singlestep_enabled = 0;
8988     if ((env->flags & POWERPC_FLAG_BE) && msr_be)
8989         ctx.singlestep_enabled |= CPU_BRANCH_STEP;
8990     if (unlikely(env->singlestep_enabled))
8991         ctx.singlestep_enabled |= GDBSTUB_SINGLE_STEP;
8992 #if defined (DO_SINGLE_STEP) && 0
8993     /* Single step trace mode */
8994     msr_se = 1;
8995 #endif
8996     num_insns = 0;
8997     max_insns = tb->cflags & CF_COUNT_MASK;
8998     if (max_insns == 0)
8999         max_insns = CF_COUNT_MASK;
9000
9001     gen_icount_start();
9002     /* Set env in case of segfault during code fetch */
9003     while (ctx.exception == POWERPC_EXCP_NONE && gen_opc_ptr < gen_opc_end) {
9004         if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
9005             QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
9006                 if (bp->pc == ctx.nip) {
9007                     gen_debug_exception(ctxp);
9008                     break;
9009                 }
9010             }
9011         }
9012         if (unlikely(search_pc)) {
9013             j = gen_opc_ptr - gen_opc_buf;
9014             if (lj < j) {
9015                 lj++;
9016                 while (lj < j)
9017                     gen_opc_instr_start[lj++] = 0;
9018             }
9019             gen_opc_pc[lj] = ctx.nip;
9020             gen_opc_instr_start[lj] = 1;
9021             gen_opc_icount[lj] = num_insns;
9022         }
9023         LOG_DISAS("----------------\n");
9024         LOG_DISAS("nip=" TARGET_FMT_lx " super=%d ir=%d\n",
9025                   ctx.nip, ctx.mem_idx, (int)msr_ir);
9026         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
9027             gen_io_start();
9028         if (unlikely(ctx.le_mode)) {
9029             ctx.opcode = bswap32(ldl_code(ctx.nip));
9030         } else {
9031             ctx.opcode = ldl_code(ctx.nip);
9032         }
9033         LOG_DISAS("translate opcode %08x (%02x %02x %02x) (%s)\n",
9034                     ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
9035                     opc3(ctx.opcode), little_endian ? "little" : "big");
9036         if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
9037             tcg_gen_debug_insn_start(ctx.nip);
9038         ctx.nip += 4;
9039         table = env->opcodes;
9040         num_insns++;
9041         handler = table[opc1(ctx.opcode)];
9042         if (is_indirect_opcode(handler)) {
9043             table = ind_table(handler);
9044             handler = table[opc2(ctx.opcode)];
9045             if (is_indirect_opcode(handler)) {
9046                 table = ind_table(handler);
9047                 handler = table[opc3(ctx.opcode)];
9048             }
9049         }
9050         /* Is opcode *REALLY* valid ? */
9051         if (unlikely(handler->handler == &gen_invalid)) {
9052             if (qemu_log_enabled()) {
9053                 qemu_log("invalid/unsupported opcode: "
9054                          "%02x - %02x - %02x (%08x) " TARGET_FMT_lx " %d\n",
9055                          opc1(ctx.opcode), opc2(ctx.opcode),
9056                          opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, (int)msr_ir);
9057             }
9058         } else {
9059             if (unlikely((ctx.opcode & handler->inval) != 0)) {
9060                 if (qemu_log_enabled()) {
9061                     qemu_log("invalid bits: %08x for opcode: "
9062                              "%02x - %02x - %02x (%08x) " TARGET_FMT_lx "\n",
9063                              ctx.opcode & handler->inval, opc1(ctx.opcode),
9064                              opc2(ctx.opcode), opc3(ctx.opcode),
9065                              ctx.opcode, ctx.nip - 4);
9066                 }
9067                 gen_inval_exception(ctxp, POWERPC_EXCP_INVAL_INVAL);
9068                 break;
9069             }
9070         }
9071         (*(handler->handler))(&ctx);
9072 #if defined(DO_PPC_STATISTICS)
9073         handler->count++;
9074 #endif
9075         /* Check trace mode exceptions */
9076         if (unlikely(ctx.singlestep_enabled & CPU_SINGLE_STEP &&
9077                      (ctx.nip <= 0x100 || ctx.nip > 0xF00) &&
9078                      ctx.exception != POWERPC_SYSCALL &&
9079                      ctx.exception != POWERPC_EXCP_TRAP &&
9080                      ctx.exception != POWERPC_EXCP_BRANCH)) {
9081             gen_exception(ctxp, POWERPC_EXCP_TRACE);
9082         } else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
9083                             (env->singlestep_enabled) ||
9084                             singlestep ||
9085                             num_insns >= max_insns)) {
9086             /* if we reach a page boundary or are single stepping, stop
9087              * generation
9088              */
9089             break;
9090         }
9091     }
9092     if (tb->cflags & CF_LAST_IO)
9093         gen_io_end();
9094     if (ctx.exception == POWERPC_EXCP_NONE) {
9095         gen_goto_tb(&ctx, 0, ctx.nip);
9096     } else if (ctx.exception != POWERPC_EXCP_BRANCH) {
9097         if (unlikely(env->singlestep_enabled)) {
9098             gen_debug_exception(ctxp);
9099         }
9100         /* Generate the return instruction */
9101         tcg_gen_exit_tb(0);
9102     }
9103     gen_icount_end(tb, num_insns);
9104     *gen_opc_ptr = INDEX_op_end;
9105     if (unlikely(search_pc)) {
9106         j = gen_opc_ptr - gen_opc_buf;
9107         lj++;
9108         while (lj <= j)
9109             gen_opc_instr_start[lj++] = 0;
9110     } else {
9111         tb->size = ctx.nip - pc_start;
9112         tb->icount = num_insns;
9113     }
9114 #if defined(DEBUG_DISAS)
9115     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
9116         int flags;
9117         flags = env->bfd_mach;
9118         flags |= ctx.le_mode << 16;
9119         qemu_log("IN: %s\n", lookup_symbol(pc_start));
9120         log_target_disas(pc_start, ctx.nip - pc_start, flags);
9121         qemu_log("\n");
9122     }
9123 #endif
9124 }
9125
9126 void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
9127 {
9128     gen_intermediate_code_internal(env, tb, 0);
9129 }
9130
9131 void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
9132 {
9133     gen_intermediate_code_internal(env, tb, 1);
9134 }
9135
9136 void gen_pc_load(CPUState *env, TranslationBlock *tb,
9137                 unsigned long searched_pc, int pc_pos, void *puc)
9138 {
9139     env->nip = gen_opc_pc[pc_pos];
9140 }
This page took 0.53935 seconds and 4 git commands to generate.