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