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