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