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