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