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