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