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