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