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