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