target-ppc: remove FPRF optimization
[qemu] / target-ppc / translate.c
1 /*
2  *  PowerPC emulation for qemu: main translation routines.
3  *
4  *  Copyright (c) 2003-2007 Jocelyn Mayer
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20 #include <stdarg.h>
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <inttypes.h>
25
26 #include "cpu.h"
27 #include "exec-all.h"
28 #include "disas.h"
29 #include "tcg-op.h"
30 #include "qemu-common.h"
31
32 #include "helper.h"
33 #define GEN_HELPER 1
34 #include "helper.h"
35
36 #define CPU_SINGLE_STEP 0x1
37 #define CPU_BRANCH_STEP 0x2
38 #define GDBSTUB_SINGLE_STEP 0x4
39
40 /* Include definitions for instructions classes and implementations flags */
41 //#define DO_SINGLE_STEP
42 //#define PPC_DEBUG_DISAS
43 //#define DO_PPC_STATISTICS
44
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     gen_reset_fpstatus();                                                     \
2076     gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rA(ctx->opcode)],      \
2077                      cpu_fpr[rC(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);     \
2078     if (isfloat) {                                                            \
2079         gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rD(ctx->opcode)]);  \
2080     }                                                                         \
2081     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], set_fprf,                      \
2082                      Rc(ctx->opcode) != 0);                                   \
2083 }
2084
2085 #define GEN_FLOAT_ACB(name, op2, set_fprf, type)                              \
2086 _GEN_FLOAT_ACB(name, name, 0x3F, op2, 0, set_fprf, type);                     \
2087 _GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, set_fprf, type);
2088
2089 #define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
2090 GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)                             \
2091 {                                                                             \
2092     if (unlikely(!ctx->fpu_enabled)) {                                        \
2093         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
2094         return;                                                               \
2095     }                                                                         \
2096     gen_reset_fpstatus();                                                     \
2097     gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rA(ctx->opcode)],      \
2098                      cpu_fpr[rB(ctx->opcode)]);                               \
2099     if (isfloat) {                                                            \
2100         gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rD(ctx->opcode)]);  \
2101     }                                                                         \
2102     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)],                                \
2103                      set_fprf, Rc(ctx->opcode) != 0);                         \
2104 }
2105 #define GEN_FLOAT_AB(name, op2, inval, set_fprf, type)                        \
2106 _GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0, set_fprf, type);               \
2107 _GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1, set_fprf, type);
2108
2109 #define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
2110 GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)                             \
2111 {                                                                             \
2112     if (unlikely(!ctx->fpu_enabled)) {                                        \
2113         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
2114         return;                                                               \
2115     }                                                                         \
2116     gen_reset_fpstatus();                                                     \
2117     gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rA(ctx->opcode)],      \
2118                        cpu_fpr[rC(ctx->opcode)]);                             \
2119     if (isfloat) {                                                            \
2120         gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rD(ctx->opcode)]);  \
2121     }                                                                         \
2122     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)],                                \
2123                      set_fprf, Rc(ctx->opcode) != 0);                         \
2124 }
2125 #define GEN_FLOAT_AC(name, op2, inval, set_fprf, type)                        \
2126 _GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0, set_fprf, type);               \
2127 _GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1, set_fprf, type);
2128
2129 #define GEN_FLOAT_B(name, op2, op3, set_fprf, type)                           \
2130 GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, type)                        \
2131 {                                                                             \
2132     if (unlikely(!ctx->fpu_enabled)) {                                        \
2133         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
2134         return;                                                               \
2135     }                                                                         \
2136     gen_reset_fpstatus();                                                     \
2137     gen_helper_f##name(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);   \
2138     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)],                                \
2139                      set_fprf, Rc(ctx->opcode) != 0);                         \
2140 }
2141
2142 #define GEN_FLOAT_BS(name, op1, op2, set_fprf, type)                          \
2143 GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, type)                        \
2144 {                                                                             \
2145     if (unlikely(!ctx->fpu_enabled)) {                                        \
2146         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
2147         return;                                                               \
2148     }                                                                         \
2149     gen_reset_fpstatus();                                                     \
2150     gen_helper_f##name(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);   \
2151     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)],                                \
2152                      set_fprf, Rc(ctx->opcode) != 0);                         \
2153 }
2154
2155 /* fadd - fadds */
2156 GEN_FLOAT_AB(add, 0x15, 0x000007C0, 1, PPC_FLOAT);
2157 /* fdiv - fdivs */
2158 GEN_FLOAT_AB(div, 0x12, 0x000007C0, 1, PPC_FLOAT);
2159 /* fmul - fmuls */
2160 GEN_FLOAT_AC(mul, 0x19, 0x0000F800, 1, PPC_FLOAT);
2161
2162 /* fre */
2163 GEN_FLOAT_BS(re, 0x3F, 0x18, 1, PPC_FLOAT_EXT);
2164
2165 /* fres */
2166 GEN_FLOAT_BS(res, 0x3B, 0x18, 1, PPC_FLOAT_FRES);
2167
2168 /* frsqrte */
2169 GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A, 1, PPC_FLOAT_FRSQRTE);
2170
2171 /* frsqrtes */
2172 GEN_HANDLER(frsqrtes, 0x3B, 0x1A, 0xFF, 0x001F07C0, PPC_FLOAT_FRSQRTES)
2173 {
2174     if (unlikely(!ctx->fpu_enabled)) {
2175         gen_exception(ctx, POWERPC_EXCP_FPU);
2176         return;
2177     }
2178     gen_reset_fpstatus();
2179     gen_helper_frsqrte(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
2180     gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rD(ctx->opcode)]);
2181     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 1, Rc(ctx->opcode) != 0);
2182 }
2183
2184 /* fsel */
2185 _GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0, 0, PPC_FLOAT_FSEL);
2186 /* fsub - fsubs */
2187 GEN_FLOAT_AB(sub, 0x14, 0x000007C0, 1, PPC_FLOAT);
2188 /* Optional: */
2189 /* fsqrt */
2190 GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
2191 {
2192     if (unlikely(!ctx->fpu_enabled)) {
2193         gen_exception(ctx, POWERPC_EXCP_FPU);
2194         return;
2195     }
2196     gen_reset_fpstatus();
2197     gen_helper_fsqrt(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
2198     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 1, Rc(ctx->opcode) != 0);
2199 }
2200
2201 GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
2202 {
2203     if (unlikely(!ctx->fpu_enabled)) {
2204         gen_exception(ctx, POWERPC_EXCP_FPU);
2205         return;
2206     }
2207     gen_reset_fpstatus();
2208     gen_helper_fsqrt(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
2209     gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rD(ctx->opcode)]);
2210     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 1, Rc(ctx->opcode) != 0);
2211 }
2212
2213 /***                     Floating-Point multiply-and-add                   ***/
2214 /* fmadd - fmadds */
2215 GEN_FLOAT_ACB(madd, 0x1D, 1, PPC_FLOAT);
2216 /* fmsub - fmsubs */
2217 GEN_FLOAT_ACB(msub, 0x1C, 1, PPC_FLOAT);
2218 /* fnmadd - fnmadds */
2219 GEN_FLOAT_ACB(nmadd, 0x1F, 1, PPC_FLOAT);
2220 /* fnmsub - fnmsubs */
2221 GEN_FLOAT_ACB(nmsub, 0x1E, 1, PPC_FLOAT);
2222
2223 /***                     Floating-Point round & convert                    ***/
2224 /* fctiw */
2225 GEN_FLOAT_B(ctiw, 0x0E, 0x00, 0, PPC_FLOAT);
2226 /* fctiwz */
2227 GEN_FLOAT_B(ctiwz, 0x0F, 0x00, 0, PPC_FLOAT);
2228 /* frsp */
2229 GEN_FLOAT_B(rsp, 0x0C, 0x00, 1, PPC_FLOAT);
2230 #if defined(TARGET_PPC64)
2231 /* fcfid */
2232 GEN_FLOAT_B(cfid, 0x0E, 0x1A, 1, PPC_64B);
2233 /* fctid */
2234 GEN_FLOAT_B(ctid, 0x0E, 0x19, 0, PPC_64B);
2235 /* fctidz */
2236 GEN_FLOAT_B(ctidz, 0x0F, 0x19, 0, PPC_64B);
2237 #endif
2238
2239 /* frin */
2240 GEN_FLOAT_B(rin, 0x08, 0x0C, 1, PPC_FLOAT_EXT);
2241 /* friz */
2242 GEN_FLOAT_B(riz, 0x08, 0x0D, 1, PPC_FLOAT_EXT);
2243 /* frip */
2244 GEN_FLOAT_B(rip, 0x08, 0x0E, 1, PPC_FLOAT_EXT);
2245 /* frim */
2246 GEN_FLOAT_B(rim, 0x08, 0x0F, 1, PPC_FLOAT_EXT);
2247
2248 /***                         Floating-Point compare                        ***/
2249 /* fcmpo */
2250 GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT)
2251 {
2252     if (unlikely(!ctx->fpu_enabled)) {
2253         gen_exception(ctx, POWERPC_EXCP_FPU);
2254         return;
2255     }
2256     gen_reset_fpstatus();
2257     gen_helper_fcmpo(cpu_crf[crfD(ctx->opcode)],
2258                      cpu_fpr[rA(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
2259     gen_helper_float_check_status();
2260 }
2261
2262 /* fcmpu */
2263 GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT)
2264 {
2265     if (unlikely(!ctx->fpu_enabled)) {
2266         gen_exception(ctx, POWERPC_EXCP_FPU);
2267         return;
2268     }
2269     gen_reset_fpstatus();
2270     gen_helper_fcmpu(cpu_crf[crfD(ctx->opcode)],
2271                      cpu_fpr[rA(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
2272     gen_helper_float_check_status();
2273 }
2274
2275 /***                         Floating-point move                           ***/
2276 /* fabs */
2277 /* XXX: beware that fabs never checks for NaNs nor update FPSCR */
2278 GEN_FLOAT_B(abs, 0x08, 0x08, 0, PPC_FLOAT);
2279
2280 /* fmr  - fmr. */
2281 /* XXX: beware that fmr never checks for NaNs nor update FPSCR */
2282 GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT)
2283 {
2284     if (unlikely(!ctx->fpu_enabled)) {
2285         gen_exception(ctx, POWERPC_EXCP_FPU);
2286         return;
2287     }
2288     tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
2289     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 0, Rc(ctx->opcode) != 0);
2290 }
2291
2292 /* fnabs */
2293 /* XXX: beware that fnabs never checks for NaNs nor update FPSCR */
2294 GEN_FLOAT_B(nabs, 0x08, 0x04, 0, PPC_FLOAT);
2295 /* fneg */
2296 /* XXX: beware that fneg never checks for NaNs nor update FPSCR */
2297 GEN_FLOAT_B(neg, 0x08, 0x01, 0, PPC_FLOAT);
2298
2299 /***                  Floating-Point status & ctrl register                ***/
2300 /* mcrfs */
2301 GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT)
2302 {
2303     int bfa;
2304
2305     if (unlikely(!ctx->fpu_enabled)) {
2306         gen_exception(ctx, POWERPC_EXCP_FPU);
2307         return;
2308     }
2309     bfa = 4 * (7 - crfS(ctx->opcode));
2310     tcg_gen_shri_i32(cpu_crf[crfD(ctx->opcode)], cpu_fpscr, bfa);
2311     tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], 0xf);
2312     tcg_gen_andi_i32(cpu_fpscr, cpu_fpscr, ~(0xF << bfa));
2313 }
2314
2315 /* mffs */
2316 GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT)
2317 {
2318     if (unlikely(!ctx->fpu_enabled)) {
2319         gen_exception(ctx, POWERPC_EXCP_FPU);
2320         return;
2321     }
2322     gen_reset_fpstatus();
2323     tcg_gen_extu_i32_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpscr);
2324     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 0, Rc(ctx->opcode) != 0);
2325 }
2326
2327 /* mtfsb0 */
2328 GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT)
2329 {
2330     uint8_t crb;
2331
2332     if (unlikely(!ctx->fpu_enabled)) {
2333         gen_exception(ctx, POWERPC_EXCP_FPU);
2334         return;
2335     }
2336     crb = 31 - crbD(ctx->opcode);
2337     gen_reset_fpstatus();
2338     if (likely(crb != FPSCR_FEX && crb != FPSCR_VX)) {
2339         TCGv_i32 t0 = tcg_const_i32(crb);
2340         gen_helper_fpscr_clrbit(t0);
2341         tcg_temp_free_i32(t0);
2342     }
2343     if (unlikely(Rc(ctx->opcode) != 0)) {
2344         tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX);
2345     }
2346 }
2347
2348 /* mtfsb1 */
2349 GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT)
2350 {
2351     uint8_t crb;
2352
2353     if (unlikely(!ctx->fpu_enabled)) {
2354         gen_exception(ctx, POWERPC_EXCP_FPU);
2355         return;
2356     }
2357     crb = 31 - crbD(ctx->opcode);
2358     gen_reset_fpstatus();
2359     /* XXX: we pretend we can only do IEEE floating-point computations */
2360     if (likely(crb != FPSCR_FEX && crb != FPSCR_VX && crb != FPSCR_NI)) {
2361         TCGv_i32 t0 = tcg_const_i32(crb);
2362         gen_helper_fpscr_setbit(t0);
2363         tcg_temp_free_i32(t0);
2364     }
2365     if (unlikely(Rc(ctx->opcode) != 0)) {
2366         tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX);
2367     }
2368     /* We can raise a differed exception */
2369     gen_helper_float_check_status();
2370 }
2371
2372 /* mtfsf */
2373 GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT)
2374 {
2375     TCGv_i32 t0;
2376
2377     if (unlikely(!ctx->fpu_enabled)) {
2378         gen_exception(ctx, POWERPC_EXCP_FPU);
2379         return;
2380     }
2381     gen_reset_fpstatus();
2382     t0 = tcg_const_i32(FM(ctx->opcode));
2383     gen_helper_store_fpscr(cpu_fpr[rB(ctx->opcode)], t0);
2384     tcg_temp_free_i32(t0);
2385     if (unlikely(Rc(ctx->opcode) != 0)) {
2386         tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX);
2387     }
2388     /* We can raise a differed exception */
2389     gen_helper_float_check_status();
2390 }
2391
2392 /* mtfsfi */
2393 GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT)
2394 {
2395     int bf, sh;
2396     TCGv_i64 t0;
2397     TCGv_i32 t1;
2398
2399     if (unlikely(!ctx->fpu_enabled)) {
2400         gen_exception(ctx, POWERPC_EXCP_FPU);
2401         return;
2402     }
2403     bf = crbD(ctx->opcode) >> 2;
2404     sh = 7 - bf;
2405     gen_reset_fpstatus();
2406     t0 = tcg_const_i64(FPIMM(ctx->opcode) << (4 * sh));
2407     t1 = tcg_const_i32(1 << sh);
2408     gen_helper_store_fpscr(t0, t1);
2409     tcg_temp_free_i64(t0);
2410     tcg_temp_free_i32(t1);
2411     if (unlikely(Rc(ctx->opcode) != 0)) {
2412         tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX);
2413     }
2414     /* We can raise a differed exception */
2415     gen_helper_float_check_status();
2416 }
2417
2418 /***                           Addressing modes                            ***/
2419 /* Register indirect with immediate index : EA = (rA|0) + SIMM */
2420 static always_inline void gen_addr_imm_index (DisasContext *ctx, TCGv EA, target_long maskl)
2421 {
2422     target_long simm = SIMM(ctx->opcode);
2423
2424     simm &= ~maskl;
2425     if (rA(ctx->opcode) == 0) {
2426 #if defined(TARGET_PPC64)
2427         if (!ctx->sf_mode) {
2428             tcg_gen_movi_tl(EA, (uint32_t)simm);
2429         } else
2430 #endif
2431         tcg_gen_movi_tl(EA, simm);
2432     } else if (likely(simm != 0)) {
2433         tcg_gen_addi_tl(EA, cpu_gpr[rA(ctx->opcode)], simm);
2434 #if defined(TARGET_PPC64)
2435         if (!ctx->sf_mode) {
2436             tcg_gen_ext32u_tl(EA, EA);
2437         }
2438 #endif
2439     } else {
2440 #if defined(TARGET_PPC64)
2441         if (!ctx->sf_mode) {
2442             tcg_gen_ext32u_tl(EA, cpu_gpr[rA(ctx->opcode)]);
2443         } else
2444 #endif
2445         tcg_gen_mov_tl(EA, cpu_gpr[rA(ctx->opcode)]);
2446     }
2447 }
2448
2449 static always_inline void gen_addr_reg_index (DisasContext *ctx, TCGv EA)
2450 {
2451     if (rA(ctx->opcode) == 0) {
2452 #if defined(TARGET_PPC64)
2453         if (!ctx->sf_mode) {
2454             tcg_gen_ext32u_tl(EA, cpu_gpr[rB(ctx->opcode)]);
2455         } else
2456 #endif
2457         tcg_gen_mov_tl(EA, cpu_gpr[rB(ctx->opcode)]);
2458     } else {
2459         tcg_gen_add_tl(EA, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
2460 #if defined(TARGET_PPC64)
2461         if (!ctx->sf_mode) {
2462             tcg_gen_ext32u_tl(EA, EA);
2463         }
2464 #endif
2465     }
2466 }
2467
2468 static always_inline void gen_addr_register (DisasContext *ctx, TCGv EA)
2469 {
2470     if (rA(ctx->opcode) == 0) {
2471         tcg_gen_movi_tl(EA, 0);
2472     } else {
2473 #if defined(TARGET_PPC64)
2474         if (!ctx->sf_mode) {
2475             tcg_gen_ext32u_tl(EA, cpu_gpr[rA(ctx->opcode)]);
2476         } else
2477 #endif
2478             tcg_gen_mov_tl(EA, cpu_gpr[rA(ctx->opcode)]);
2479     }
2480 }
2481
2482 static always_inline void gen_addr_add (DisasContext *ctx, TCGv ret, TCGv arg1, target_long val)
2483 {
2484     tcg_gen_addi_tl(ret, arg1, val);
2485 #if defined(TARGET_PPC64)
2486     if (!ctx->sf_mode) {
2487         tcg_gen_ext32u_tl(ret, ret);
2488     }
2489 #endif
2490 }
2491
2492 static always_inline void gen_check_align (DisasContext *ctx, TCGv EA, int mask)
2493 {
2494     int l1 = gen_new_label();
2495     TCGv t0 = tcg_temp_new();
2496     TCGv_i32 t1, t2;
2497     /* NIP cannot be restored if the memory exception comes from an helper */
2498     gen_update_nip(ctx, ctx->nip - 4);
2499     tcg_gen_andi_tl(t0, EA, mask);
2500     tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
2501     t1 = tcg_const_i32(POWERPC_EXCP_ALIGN);
2502     t2 = tcg_const_i32(0);
2503     gen_helper_raise_exception_err(t1, t2);
2504     tcg_temp_free_i32(t1);
2505     tcg_temp_free_i32(t2);
2506     gen_set_label(l1);
2507     tcg_temp_free(t0);
2508 }
2509
2510 /***                             Integer load                              ***/
2511 static always_inline void gen_qemu_ld8u(DisasContext *ctx, TCGv arg1, TCGv arg2)
2512 {
2513     tcg_gen_qemu_ld8u(arg1, arg2, ctx->mem_idx);
2514 }
2515
2516 static always_inline void gen_qemu_ld8s(DisasContext *ctx, TCGv arg1, TCGv arg2)
2517 {
2518     tcg_gen_qemu_ld8s(arg1, arg2, ctx->mem_idx);
2519 }
2520
2521 static always_inline void gen_qemu_ld16u(DisasContext *ctx, TCGv arg1, TCGv arg2)
2522 {
2523     tcg_gen_qemu_ld16u(arg1, arg2, ctx->mem_idx);
2524     if (unlikely(ctx->le_mode)) {
2525 #if defined(TARGET_PPC64)
2526         TCGv_i32 t0 = tcg_temp_new_i32();
2527         tcg_gen_trunc_tl_i32(t0, arg1);
2528         tcg_gen_bswap16_i32(t0, t0);
2529         tcg_gen_extu_i32_tl(arg1, t0);
2530         tcg_temp_free_i32(t0);
2531 #else
2532         tcg_gen_bswap16_i32(arg1, arg1);
2533 #endif
2534     }
2535 }
2536
2537 static always_inline void gen_qemu_ld16s(DisasContext *ctx, TCGv arg1, TCGv arg2)
2538 {
2539     if (unlikely(ctx->le_mode)) {
2540 #if defined(TARGET_PPC64)
2541         TCGv_i32 t0;
2542         tcg_gen_qemu_ld16u(arg1, arg2, ctx->mem_idx);
2543         t0 = tcg_temp_new_i32();
2544         tcg_gen_trunc_tl_i32(t0, arg1);
2545         tcg_gen_bswap16_i32(t0, t0);
2546         tcg_gen_extu_i32_tl(arg1, t0);
2547         tcg_gen_ext16s_tl(arg1, arg1);
2548         tcg_temp_free_i32(t0);
2549 #else
2550         tcg_gen_qemu_ld16u(arg1, arg2, ctx->mem_idx);
2551         tcg_gen_bswap16_i32(arg1, arg1);
2552         tcg_gen_ext16s_i32(arg1, arg1);
2553 #endif
2554     } else {
2555         tcg_gen_qemu_ld16s(arg1, arg2, ctx->mem_idx);
2556     }
2557 }
2558
2559 static always_inline void gen_qemu_ld32u(DisasContext *ctx, TCGv arg1, TCGv arg2)
2560 {
2561     tcg_gen_qemu_ld32u(arg1, arg2, ctx->mem_idx);
2562     if (unlikely(ctx->le_mode)) {
2563 #if defined(TARGET_PPC64)
2564         TCGv_i32 t0 = tcg_temp_new_i32();
2565         tcg_gen_trunc_tl_i32(t0, arg1);
2566         tcg_gen_bswap_i32(t0, t0);
2567         tcg_gen_extu_i32_tl(arg1, t0);
2568         tcg_temp_free_i32(t0);
2569 #else
2570         tcg_gen_bswap_i32(arg1, arg1);
2571 #endif
2572     }
2573 }
2574
2575 #if defined(TARGET_PPC64)
2576 static always_inline void gen_qemu_ld32s(DisasContext *ctx, TCGv arg1, TCGv arg2)
2577 {
2578     if (unlikely(ctx->mem_idx)) {
2579         TCGv_i32 t0;
2580         tcg_gen_qemu_ld32u(arg1, arg2, ctx->mem_idx);
2581         t0 = tcg_temp_new_i32();
2582         tcg_gen_trunc_tl_i32(t0, arg1);
2583         tcg_gen_bswap_i32(t0, t0);
2584         tcg_gen_ext_i32_tl(arg1, t0);
2585         tcg_temp_free_i32(t0);
2586     } else
2587         tcg_gen_qemu_ld32s(arg1, arg2, ctx->mem_idx);
2588 }
2589 #endif
2590
2591 static always_inline void gen_qemu_ld64(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
2592 {
2593     tcg_gen_qemu_ld64(arg1, arg2, ctx->mem_idx);
2594     if (unlikely(ctx->le_mode)) {
2595         tcg_gen_bswap_i64(arg1, arg1);
2596     }
2597 }
2598
2599 static always_inline void gen_qemu_st8(DisasContext *ctx, TCGv arg1, TCGv arg2)
2600 {
2601     tcg_gen_qemu_st8(arg1, arg2, ctx->mem_idx);
2602 }
2603
2604 static always_inline void gen_qemu_st16(DisasContext *ctx, TCGv arg1, TCGv arg2)
2605 {
2606     if (unlikely(ctx->le_mode)) {
2607 #if defined(TARGET_PPC64)
2608         TCGv_i32 t0;
2609         TCGv t1;
2610         t0 = tcg_temp_new_i32();
2611         tcg_gen_trunc_tl_i32(t0, arg1);
2612         tcg_gen_ext16u_i32(t0, t0);
2613         tcg_gen_bswap16_i32(t0, t0);
2614         t1 = tcg_temp_new();
2615         tcg_gen_extu_i32_tl(t1, t0);
2616         tcg_temp_free_i32(t0);
2617         tcg_gen_qemu_st16(t1, arg2, ctx->mem_idx);
2618         tcg_temp_free(t1);
2619 #else
2620         TCGv t0 = tcg_temp_new();
2621         tcg_gen_ext16u_tl(t0, arg1);
2622         tcg_gen_bswap16_i32(t0, t0);
2623         tcg_gen_qemu_st16(t0, arg2, ctx->mem_idx);
2624         tcg_temp_free(t0);
2625 #endif
2626     } else {
2627         tcg_gen_qemu_st16(arg1, arg2, ctx->mem_idx);
2628     }
2629 }
2630
2631 static always_inline void gen_qemu_st32(DisasContext *ctx, TCGv arg1, TCGv arg2)
2632 {
2633     if (unlikely(ctx->le_mode)) {
2634 #if defined(TARGET_PPC64)
2635         TCGv_i32 t0;
2636         TCGv t1;
2637         t0 = tcg_temp_new_i32();
2638         tcg_gen_trunc_tl_i32(t0, arg1);
2639         tcg_gen_bswap_i32(t0, t0);
2640         t1 = tcg_temp_new();
2641         tcg_gen_extu_i32_tl(t1, t0);
2642         tcg_temp_free_i32(t0);
2643         tcg_gen_qemu_st32(t1, arg2, ctx->mem_idx);
2644         tcg_temp_free(t1);
2645 #else
2646         TCGv t0 = tcg_temp_new_i32();
2647         tcg_gen_bswap_i32(t0, arg1);
2648         tcg_gen_qemu_st32(t0, arg2, ctx->mem_idx);
2649         tcg_temp_free(t0);
2650 #endif
2651     } else {
2652         tcg_gen_qemu_st32(arg1, arg2, ctx->mem_idx);
2653     }
2654 }
2655
2656 static always_inline void gen_qemu_st64(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
2657 {
2658     if (unlikely(ctx->le_mode)) {
2659         TCGv_i64 t0 = tcg_temp_new_i64();
2660         tcg_gen_bswap_i64(t0, arg1);
2661         tcg_gen_qemu_st64(t0, arg2, ctx->mem_idx);
2662         tcg_temp_free_i64(t0);
2663     } else
2664         tcg_gen_qemu_st64(arg1, arg2, ctx->mem_idx);
2665 }
2666
2667 #define GEN_LD(name, ldop, opc, type)                                         \
2668 GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type)                          \
2669 {                                                                             \
2670     TCGv EA;                                                                  \
2671     gen_set_access_type(ctx, ACCESS_INT);                                     \
2672     EA = tcg_temp_new();                                                      \
2673     gen_addr_imm_index(ctx, EA, 0);                                           \
2674     gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA);                       \
2675     tcg_temp_free(EA);                                                        \
2676 }
2677
2678 #define GEN_LDU(name, ldop, opc, type)                                        \
2679 GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type)                       \
2680 {                                                                             \
2681     TCGv EA;                                                                  \
2682     if (unlikely(rA(ctx->opcode) == 0 ||                                      \
2683                  rA(ctx->opcode) == rD(ctx->opcode))) {                       \
2684         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
2685         return;                                                               \
2686     }                                                                         \
2687     gen_set_access_type(ctx, ACCESS_INT);                                     \
2688     EA = tcg_temp_new();                                                      \
2689     if (type == PPC_64B)                                                      \
2690         gen_addr_imm_index(ctx, EA, 0x03);                                    \
2691     else                                                                      \
2692         gen_addr_imm_index(ctx, EA, 0);                                       \
2693     gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA);                       \
2694     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
2695     tcg_temp_free(EA);                                                        \
2696 }
2697
2698 #define GEN_LDUX(name, ldop, opc2, opc3, type)                                \
2699 GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type)                     \
2700 {                                                                             \
2701     TCGv EA;                                                                  \
2702     if (unlikely(rA(ctx->opcode) == 0 ||                                      \
2703                  rA(ctx->opcode) == rD(ctx->opcode))) {                       \
2704         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
2705         return;                                                               \
2706     }                                                                         \
2707     gen_set_access_type(ctx, ACCESS_INT);                                     \
2708     EA = tcg_temp_new();                                                      \
2709     gen_addr_reg_index(ctx, EA);                                              \
2710     gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA);                       \
2711     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
2712     tcg_temp_free(EA);                                                        \
2713 }
2714
2715 #define GEN_LDX(name, ldop, opc2, opc3, type)                                 \
2716 GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type)                      \
2717 {                                                                             \
2718     TCGv EA;                                                                  \
2719     gen_set_access_type(ctx, ACCESS_INT);                                     \
2720     EA = tcg_temp_new();                                                      \
2721     gen_addr_reg_index(ctx, EA);                                              \
2722     gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA);                       \
2723     tcg_temp_free(EA);                                                        \
2724 }
2725
2726 #define GEN_LDS(name, ldop, op, type)                                         \
2727 GEN_LD(name, ldop, op | 0x20, type);                                          \
2728 GEN_LDU(name, ldop, op | 0x21, type);                                         \
2729 GEN_LDUX(name, ldop, 0x17, op | 0x01, type);                                  \
2730 GEN_LDX(name, ldop, 0x17, op | 0x00, type)
2731
2732 /* lbz lbzu lbzux lbzx */
2733 GEN_LDS(lbz, ld8u, 0x02, PPC_INTEGER);
2734 /* lha lhau lhaux lhax */
2735 GEN_LDS(lha, ld16s, 0x0A, PPC_INTEGER);
2736 /* lhz lhzu lhzux lhzx */
2737 GEN_LDS(lhz, ld16u, 0x08, PPC_INTEGER);
2738 /* lwz lwzu lwzux lwzx */
2739 GEN_LDS(lwz, ld32u, 0x00, PPC_INTEGER);
2740 #if defined(TARGET_PPC64)
2741 /* lwaux */
2742 GEN_LDUX(lwa, ld32s, 0x15, 0x0B, PPC_64B);
2743 /* lwax */
2744 GEN_LDX(lwa, ld32s, 0x15, 0x0A, PPC_64B);
2745 /* ldux */
2746 GEN_LDUX(ld, ld64, 0x15, 0x01, PPC_64B);
2747 /* ldx */
2748 GEN_LDX(ld, ld64, 0x15, 0x00, PPC_64B);
2749 GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B)
2750 {
2751     TCGv EA;
2752     if (Rc(ctx->opcode)) {
2753         if (unlikely(rA(ctx->opcode) == 0 ||
2754                      rA(ctx->opcode) == rD(ctx->opcode))) {
2755             gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
2756             return;
2757         }
2758     }
2759     gen_set_access_type(ctx, ACCESS_INT);
2760     EA = tcg_temp_new();
2761     gen_addr_imm_index(ctx, EA, 0x03);
2762     if (ctx->opcode & 0x02) {
2763         /* lwa (lwau is undefined) */
2764         gen_qemu_ld32s(ctx, cpu_gpr[rD(ctx->opcode)], EA);
2765     } else {
2766         /* ld - ldu */
2767         gen_qemu_ld64(ctx, cpu_gpr[rD(ctx->opcode)], EA);
2768     }
2769     if (Rc(ctx->opcode))
2770         tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);
2771     tcg_temp_free(EA);
2772 }
2773 /* lq */
2774 GEN_HANDLER(lq, 0x38, 0xFF, 0xFF, 0x00000000, PPC_64BX)
2775 {
2776 #if defined(CONFIG_USER_ONLY)
2777     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
2778 #else
2779     int ra, rd;
2780     TCGv EA;
2781
2782     /* Restore CPU state */
2783     if (unlikely(ctx->mem_idx == 0)) {
2784         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
2785         return;
2786     }
2787     ra = rA(ctx->opcode);
2788     rd = rD(ctx->opcode);
2789     if (unlikely((rd & 1) || rd == ra)) {
2790         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
2791         return;
2792     }
2793     if (unlikely(ctx->le_mode)) {
2794         /* Little-endian mode is not handled */
2795         gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
2796         return;
2797     }
2798     gen_set_access_type(ctx, ACCESS_INT);
2799     EA = tcg_temp_new();
2800     gen_addr_imm_index(ctx, EA, 0x0F);
2801     gen_qemu_ld64(ctx, cpu_gpr[rd], EA);
2802     gen_addr_add(ctx, EA, EA, 8);
2803     gen_qemu_ld64(ctx, cpu_gpr[rd+1], EA);
2804     tcg_temp_free(EA);
2805 #endif
2806 }
2807 #endif
2808
2809 /***                              Integer store                            ***/
2810 #define GEN_ST(name, stop, opc, type)                                         \
2811 GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type)                          \
2812 {                                                                             \
2813     TCGv EA;                                                                  \
2814     gen_set_access_type(ctx, ACCESS_INT);                                     \
2815     EA = tcg_temp_new();                                                      \
2816     gen_addr_imm_index(ctx, EA, 0);                                           \
2817     gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA);                       \
2818     tcg_temp_free(EA);                                                        \
2819 }
2820
2821 #define GEN_STU(name, stop, opc, type)                                        \
2822 GEN_HANDLER(stop##u, opc, 0xFF, 0xFF, 0x00000000, type)                       \
2823 {                                                                             \
2824     TCGv EA;                                                                  \
2825     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2826         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
2827         return;                                                               \
2828     }                                                                         \
2829     gen_set_access_type(ctx, ACCESS_INT);                                     \
2830     EA = tcg_temp_new();                                                      \
2831     if (type == PPC_64B)                                                      \
2832         gen_addr_imm_index(ctx, EA, 0x03);                                    \
2833     else                                                                      \
2834         gen_addr_imm_index(ctx, EA, 0);                                       \
2835     gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA);                       \
2836     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
2837     tcg_temp_free(EA);                                                        \
2838 }
2839
2840 #define GEN_STUX(name, stop, opc2, opc3, type)                                \
2841 GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type)                     \
2842 {                                                                             \
2843     TCGv EA;                                                                  \
2844     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2845         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
2846         return;                                                               \
2847     }                                                                         \
2848     gen_set_access_type(ctx, ACCESS_INT);                                     \
2849     EA = tcg_temp_new();                                                      \
2850     gen_addr_reg_index(ctx, EA);                                              \
2851     gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA);                       \
2852     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
2853     tcg_temp_free(EA);                                                        \
2854 }
2855
2856 #define GEN_STX(name, stop, opc2, opc3, type)                                 \
2857 GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type)                      \
2858 {                                                                             \
2859     TCGv EA;                                                                  \
2860     gen_set_access_type(ctx, ACCESS_INT);                                     \
2861     EA = tcg_temp_new();                                                      \
2862     gen_addr_reg_index(ctx, EA);                                              \
2863     gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA);                       \
2864     tcg_temp_free(EA);                                                        \
2865 }
2866
2867 #define GEN_STS(name, stop, op, type)                                         \
2868 GEN_ST(name, stop, op | 0x20, type);                                          \
2869 GEN_STU(name, stop, op | 0x21, type);                                         \
2870 GEN_STUX(name, stop, 0x17, op | 0x01, type);                                  \
2871 GEN_STX(name, stop, 0x17, op | 0x00, type)
2872
2873 /* stb stbu stbux stbx */
2874 GEN_STS(stb, st8, 0x06, PPC_INTEGER);
2875 /* sth sthu sthux sthx */
2876 GEN_STS(sth, st16, 0x0C, PPC_INTEGER);
2877 /* stw stwu stwux stwx */
2878 GEN_STS(stw, st32, 0x04, PPC_INTEGER);
2879 #if defined(TARGET_PPC64)
2880 GEN_STUX(std, st64, 0x15, 0x05, PPC_64B);
2881 GEN_STX(std, st64, 0x15, 0x04, PPC_64B);
2882 GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000000, PPC_64B)
2883 {
2884     int rs;
2885     TCGv EA;
2886
2887     rs = rS(ctx->opcode);
2888     if ((ctx->opcode & 0x3) == 0x2) {
2889 #if defined(CONFIG_USER_ONLY)
2890         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
2891 #else
2892         /* stq */
2893         if (unlikely(ctx->mem_idx == 0)) {
2894             gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
2895             return;
2896         }
2897         if (unlikely(rs & 1)) {
2898             gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
2899             return;
2900         }
2901         if (unlikely(ctx->le_mode)) {
2902             /* Little-endian mode is not handled */
2903             gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
2904             return;
2905         }
2906         gen_set_access_type(ctx, ACCESS_INT);
2907         EA = tcg_temp_new();
2908         gen_addr_imm_index(ctx, EA, 0x03);
2909         gen_qemu_st64(ctx, cpu_gpr[rs], EA);
2910         gen_addr_add(ctx, EA, EA, 8);
2911         gen_qemu_st64(ctx, cpu_gpr[rs+1], EA);
2912         tcg_temp_free(EA);
2913 #endif
2914     } else {
2915         /* std / stdu */
2916         if (Rc(ctx->opcode)) {
2917             if (unlikely(rA(ctx->opcode) == 0)) {
2918                 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
2919                 return;
2920             }
2921         }
2922         gen_set_access_type(ctx, ACCESS_INT);
2923         EA = tcg_temp_new();
2924         gen_addr_imm_index(ctx, EA, 0x03);
2925         gen_qemu_st64(ctx, cpu_gpr[rs], EA);
2926         if (Rc(ctx->opcode))
2927             tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);
2928         tcg_temp_free(EA);
2929     }
2930 }
2931 #endif
2932 /***                Integer load and store with byte reverse               ***/
2933 /* lhbrx */
2934 static void always_inline gen_qemu_ld16ur(DisasContext *ctx, TCGv arg1, TCGv arg2)
2935 {
2936     tcg_gen_qemu_ld16u(arg1, arg2, ctx->mem_idx);
2937     if (likely(!ctx->le_mode)) {
2938 #if defined(TARGET_PPC64)
2939         TCGv_i32 t0 = tcg_temp_new_i32();
2940         tcg_gen_trunc_tl_i32(t0, arg1);
2941         tcg_gen_bswap16_i32(t0, t0);
2942         tcg_gen_extu_i32_tl(arg1, t0);
2943         tcg_temp_free_i32(t0);
2944 #else
2945         tcg_gen_bswap16_i32(arg1, arg1);
2946 #endif
2947     }
2948 }
2949 GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER);
2950
2951 /* lwbrx */
2952 static void always_inline gen_qemu_ld32ur(DisasContext *ctx, TCGv arg1, TCGv arg2)
2953 {
2954     tcg_gen_qemu_ld32u(arg1, arg2, ctx->mem_idx);
2955     if (likely(!ctx->le_mode)) {
2956 #if defined(TARGET_PPC64)
2957         TCGv_i32 t0 = tcg_temp_new_i32();
2958         tcg_gen_trunc_tl_i32(t0, arg1);
2959         tcg_gen_bswap_i32(t0, t0);
2960         tcg_gen_extu_i32_tl(arg1, t0);
2961         tcg_temp_free_i32(t0);
2962 #else
2963         tcg_gen_bswap_i32(arg1, arg1);
2964 #endif
2965     }
2966 }
2967 GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER);
2968
2969 /* sthbrx */
2970 static void always_inline gen_qemu_st16r(DisasContext *ctx, TCGv arg1, TCGv arg2)
2971 {
2972     if (likely(!ctx->le_mode)) {
2973 #if defined(TARGET_PPC64)
2974         TCGv_i32 t0;
2975         TCGv t1;
2976         t0 = tcg_temp_new_i32();
2977         tcg_gen_trunc_tl_i32(t0, arg1);
2978         tcg_gen_ext16u_i32(t0, t0);
2979         tcg_gen_bswap16_i32(t0, t0);
2980         t1 = tcg_temp_new();
2981         tcg_gen_extu_i32_tl(t1, t0);
2982         tcg_temp_free_i32(t0);
2983         tcg_gen_qemu_st16(t1, arg2, ctx->mem_idx);
2984         tcg_temp_free(t1);
2985 #else
2986         TCGv t0 = tcg_temp_new();
2987         tcg_gen_ext16u_tl(t0, arg1);
2988         tcg_gen_bswap16_i32(t0, t0);
2989         tcg_gen_qemu_st16(t0, arg2, ctx->mem_idx);
2990         tcg_temp_free(t0);
2991 #endif
2992     } else {
2993         tcg_gen_qemu_st16(arg1, arg2, ctx->mem_idx);
2994     }
2995 }
2996 GEN_STX(sthbr, st16r, 0x16, 0x1C, PPC_INTEGER);
2997
2998 /* stwbrx */
2999 static void always_inline gen_qemu_st32r(DisasContext *ctx, TCGv arg1, TCGv arg2)
3000 {
3001     if (likely(!ctx->le_mode)) {
3002 #if defined(TARGET_PPC64)
3003         TCGv_i32 t0;
3004         TCGv t1;
3005         t0 = tcg_temp_new_i32();
3006         tcg_gen_trunc_tl_i32(t0, arg1);
3007         tcg_gen_bswap_i32(t0, t0);
3008         t1 = tcg_temp_new();
3009         tcg_gen_extu_i32_tl(t1, t0);
3010         tcg_temp_free_i32(t0);
3011         tcg_gen_qemu_st32(t1, arg2, ctx->mem_idx);
3012         tcg_temp_free(t1);
3013 #else
3014         TCGv t0 = tcg_temp_new_i32();
3015         tcg_gen_bswap_i32(t0, arg1);
3016         tcg_gen_qemu_st32(t0, arg2, ctx->mem_idx);
3017         tcg_temp_free(t0);
3018 #endif
3019     } else {
3020         tcg_gen_qemu_st32(arg1, arg2, ctx->mem_idx);
3021     }
3022 }
3023 GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER);
3024
3025 /***                    Integer load and store multiple                    ***/
3026 /* lmw */
3027 GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
3028 {
3029     TCGv t0;
3030     TCGv_i32 t1;
3031     gen_set_access_type(ctx, ACCESS_INT);
3032     /* NIP cannot be restored if the memory exception comes from an helper */
3033     gen_update_nip(ctx, ctx->nip - 4);
3034     t0 = tcg_temp_new();
3035     t1 = tcg_const_i32(rD(ctx->opcode));
3036     gen_addr_imm_index(ctx, t0, 0);
3037     gen_helper_lmw(t0, t1);
3038     tcg_temp_free(t0);
3039     tcg_temp_free_i32(t1);
3040 }
3041
3042 /* stmw */
3043 GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
3044 {
3045     TCGv t0;
3046     TCGv_i32 t1;
3047     gen_set_access_type(ctx, ACCESS_INT);
3048     /* NIP cannot be restored if the memory exception comes from an helper */
3049     gen_update_nip(ctx, ctx->nip - 4);
3050     t0 = tcg_temp_new();
3051     t1 = tcg_const_i32(rS(ctx->opcode));
3052     gen_addr_imm_index(ctx, t0, 0);
3053     gen_helper_stmw(t0, t1);
3054     tcg_temp_free(t0);
3055     tcg_temp_free_i32(t1);
3056 }
3057
3058 /***                    Integer load and store strings                     ***/
3059 /* lswi */
3060 /* PowerPC32 specification says we must generate an exception if
3061  * rA is in the range of registers to be loaded.
3062  * In an other hand, IBM says this is valid, but rA won't be loaded.
3063  * For now, I'll follow the spec...
3064  */
3065 GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_STRING)
3066 {
3067     TCGv t0;
3068     TCGv_i32 t1, t2;
3069     int nb = NB(ctx->opcode);
3070     int start = rD(ctx->opcode);
3071     int ra = rA(ctx->opcode);
3072     int nr;
3073
3074     if (nb == 0)
3075         nb = 32;
3076     nr = nb / 4;
3077     if (unlikely(((start + nr) > 32  &&
3078                   start <= ra && (start + nr - 32) > ra) ||
3079                  ((start + nr) <= 32 && start <= ra && (start + nr) > ra))) {
3080         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_LSWX);
3081         return;
3082     }
3083     gen_set_access_type(ctx, ACCESS_INT);
3084     /* NIP cannot be restored if the memory exception comes from an helper */
3085     gen_update_nip(ctx, ctx->nip - 4);
3086     t0 = tcg_temp_new();
3087     gen_addr_register(ctx, t0);
3088     t1 = tcg_const_i32(nb);
3089     t2 = tcg_const_i32(start);
3090     gen_helper_lsw(t0, t1, t2);
3091     tcg_temp_free(t0);
3092     tcg_temp_free_i32(t1);
3093     tcg_temp_free_i32(t2);
3094 }
3095
3096 /* lswx */
3097 GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_STRING)
3098 {
3099     TCGv t0;
3100     TCGv_i32 t1, t2, t3;
3101     gen_set_access_type(ctx, ACCESS_INT);
3102     /* NIP cannot be restored if the memory exception comes from an helper */
3103     gen_update_nip(ctx, ctx->nip - 4);
3104     t0 = tcg_temp_new();
3105     gen_addr_reg_index(ctx, t0);
3106     t1 = tcg_const_i32(rD(ctx->opcode));
3107     t2 = tcg_const_i32(rA(ctx->opcode));
3108     t3 = tcg_const_i32(rB(ctx->opcode));
3109     gen_helper_lswx(t0, t1, t2, t3);
3110     tcg_temp_free(t0);
3111     tcg_temp_free_i32(t1);
3112     tcg_temp_free_i32(t2);
3113     tcg_temp_free_i32(t3);
3114 }
3115
3116 /* stswi */
3117 GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_STRING)
3118 {
3119     TCGv t0;
3120     TCGv_i32 t1, t2;
3121     int nb = NB(ctx->opcode);
3122     gen_set_access_type(ctx, ACCESS_INT);
3123     /* NIP cannot be restored if the memory exception comes from an helper */
3124     gen_update_nip(ctx, ctx->nip - 4);
3125     t0 = tcg_temp_new();
3126     gen_addr_register(ctx, t0);
3127     if (nb == 0)
3128         nb = 32;
3129     t1 = tcg_const_i32(nb);
3130     t2 = tcg_const_i32(rS(ctx->opcode));
3131     gen_helper_stsw(t0, t1, t2);
3132     tcg_temp_free(t0);
3133     tcg_temp_free_i32(t1);
3134     tcg_temp_free_i32(t2);
3135 }
3136
3137 /* stswx */
3138 GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_STRING)
3139 {
3140     TCGv t0;
3141     TCGv_i32 t1, t2;
3142     gen_set_access_type(ctx, ACCESS_INT);
3143     /* NIP cannot be restored if the memory exception comes from an helper */
3144     gen_update_nip(ctx, ctx->nip - 4);
3145     t0 = tcg_temp_new();
3146     gen_addr_reg_index(ctx, t0);
3147     t1 = tcg_temp_new_i32();
3148     tcg_gen_trunc_tl_i32(t1, cpu_xer);
3149     tcg_gen_andi_i32(t1, t1, 0x7F);
3150     t2 = tcg_const_i32(rS(ctx->opcode));
3151     gen_helper_stsw(t0, t1, t2);
3152     tcg_temp_free(t0);
3153     tcg_temp_free_i32(t1);
3154     tcg_temp_free_i32(t2);
3155 }
3156
3157 /***                        Memory synchronisation                         ***/
3158 /* eieio */
3159 GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FFF801, PPC_MEM_EIEIO)
3160 {
3161 }
3162
3163 /* isync */
3164 GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FFF801, PPC_MEM)
3165 {
3166     gen_stop_exception(ctx);
3167 }
3168
3169 /* lwarx */
3170 GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000001, PPC_RES)
3171 {
3172     TCGv t0;
3173     gen_set_access_type(ctx, ACCESS_RES);
3174     t0 = tcg_temp_local_new();
3175     gen_addr_reg_index(ctx, t0);
3176     gen_check_align(ctx, t0, 0x03);
3177     gen_qemu_ld32u(ctx, cpu_gpr[rD(ctx->opcode)], t0);
3178     tcg_gen_mov_tl(cpu_reserve, t0);
3179     tcg_temp_free(t0);
3180 }
3181
3182 /* stwcx. */
3183 GEN_HANDLER2(stwcx_, "stwcx.", 0x1F, 0x16, 0x04, 0x00000000, PPC_RES)
3184 {
3185     int l1;
3186     TCGv t0;
3187     gen_set_access_type(ctx, ACCESS_RES);
3188     t0 = tcg_temp_local_new();
3189     gen_addr_reg_index(ctx, t0);
3190     gen_check_align(ctx, t0, 0x03);
3191     tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_xer);
3192     tcg_gen_shri_i32(cpu_crf[0], cpu_crf[0], XER_SO);
3193     tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 1);
3194     l1 = gen_new_label();
3195     tcg_gen_brcond_tl(TCG_COND_NE, t0, cpu_reserve, l1);
3196     tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 1 << CRF_EQ);
3197     gen_qemu_st32(ctx, cpu_gpr[rS(ctx->opcode)], t0);
3198     gen_set_label(l1);
3199     tcg_gen_movi_tl(cpu_reserve, -1);
3200     tcg_temp_free(t0);
3201 }
3202
3203 #if defined(TARGET_PPC64)
3204 /* ldarx */
3205 GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000001, PPC_64B)
3206 {
3207     TCGv t0;
3208     gen_set_access_type(ctx, ACCESS_RES);
3209     t0 = tcg_temp_local_new();
3210     gen_addr_reg_index(ctx, t0);
3211     gen_check_align(ctx, t0, 0x07);
3212     gen_qemu_ld64(ctx, cpu_gpr[rD(ctx->opcode)], t0);
3213     tcg_gen_mov_tl(cpu_reserve, t0);
3214     tcg_temp_free(t0);
3215 }
3216
3217 /* stdcx. */
3218 GEN_HANDLER2(stdcx_, "stdcx.", 0x1F, 0x16, 0x06, 0x00000000, PPC_64B)
3219 {
3220     int l1;
3221     TCGv t0;
3222     gen_set_access_type(ctx, ACCESS_RES);
3223     t0 = tcg_temp_local_new();
3224     gen_addr_reg_index(ctx, t0);
3225     gen_check_align(ctx, t0, 0x07);
3226     tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_xer);
3227     tcg_gen_shri_i32(cpu_crf[0], cpu_crf[0], XER_SO);
3228     tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 1);
3229     l1 = gen_new_label();
3230     tcg_gen_brcond_tl(TCG_COND_NE, t0, cpu_reserve, l1);
3231     tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 1 << CRF_EQ);
3232     gen_qemu_st64(ctx, cpu_gpr[rS(ctx->opcode)], t0);
3233     gen_set_label(l1);
3234     tcg_gen_movi_tl(cpu_reserve, -1);
3235     tcg_temp_free(t0);
3236 }
3237 #endif /* defined(TARGET_PPC64) */
3238
3239 /* sync */
3240 GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x039FF801, PPC_MEM_SYNC)
3241 {
3242 }
3243
3244 /* wait */
3245 GEN_HANDLER(wait, 0x1F, 0x1E, 0x01, 0x03FFF801, PPC_WAIT)
3246 {
3247     TCGv_i32 t0 = tcg_temp_new_i32();
3248     tcg_gen_st_i32(t0, cpu_env, offsetof(CPUState, halted));
3249     tcg_temp_free_i32(t0);
3250     /* Stop translation, as the CPU is supposed to sleep from now */
3251     gen_exception_err(ctx, EXCP_HLT, 1);
3252 }
3253
3254 /***                         Floating-point load                           ***/
3255 #define GEN_LDF(name, ldop, opc, type)                                        \
3256 GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type)                          \
3257 {                                                                             \
3258     TCGv EA;                                                                  \
3259     if (unlikely(!ctx->fpu_enabled)) {                                        \
3260         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3261         return;                                                               \
3262     }                                                                         \
3263     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3264     EA = tcg_temp_new();                                                      \
3265     gen_addr_imm_index(ctx, EA, 0);                                           \
3266     gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA);                       \
3267     tcg_temp_free(EA);                                                        \
3268 }
3269
3270 #define GEN_LDUF(name, ldop, opc, type)                                       \
3271 GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type)                       \
3272 {                                                                             \
3273     TCGv EA;                                                                  \
3274     if (unlikely(!ctx->fpu_enabled)) {                                        \
3275         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3276         return;                                                               \
3277     }                                                                         \
3278     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
3279         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
3280         return;                                                               \
3281     }                                                                         \
3282     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3283     EA = tcg_temp_new();                                                      \
3284     gen_addr_imm_index(ctx, EA, 0);                                           \
3285     gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA);                       \
3286     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
3287     tcg_temp_free(EA);                                                        \
3288 }
3289
3290 #define GEN_LDUXF(name, ldop, opc, type)                                      \
3291 GEN_HANDLER(name##ux, 0x1F, 0x17, opc, 0x00000001, type)                      \
3292 {                                                                             \
3293     TCGv EA;                                                                  \
3294     if (unlikely(!ctx->fpu_enabled)) {                                        \
3295         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3296         return;                                                               \
3297     }                                                                         \
3298     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
3299         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
3300         return;                                                               \
3301     }                                                                         \
3302     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3303     EA = tcg_temp_new();                                                      \
3304     gen_addr_reg_index(ctx, EA);                                              \
3305     gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA);                       \
3306     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
3307     tcg_temp_free(EA);                                                        \
3308 }
3309
3310 #define GEN_LDXF(name, ldop, opc2, opc3, type)                                \
3311 GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type)                      \
3312 {                                                                             \
3313     TCGv EA;                                                                  \
3314     if (unlikely(!ctx->fpu_enabled)) {                                        \
3315         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3316         return;                                                               \
3317     }                                                                         \
3318     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3319     EA = tcg_temp_new();                                                      \
3320     gen_addr_reg_index(ctx, EA);                                              \
3321     gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA);                       \
3322     tcg_temp_free(EA);                                                        \
3323 }
3324
3325 #define GEN_LDFS(name, ldop, op, type)                                        \
3326 GEN_LDF(name, ldop, op | 0x20, type);                                         \
3327 GEN_LDUF(name, ldop, op | 0x21, type);                                        \
3328 GEN_LDUXF(name, ldop, op | 0x01, type);                                       \
3329 GEN_LDXF(name, ldop, 0x17, op | 0x00, type)
3330
3331 static always_inline void gen_qemu_ld32fs(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
3332 {
3333     TCGv t0 = tcg_temp_new();
3334     TCGv_i32 t1 = tcg_temp_new_i32();
3335     gen_qemu_ld32u(ctx, t0, arg2);
3336     tcg_gen_trunc_tl_i32(t1, t0);
3337     tcg_temp_free(t0);
3338     gen_helper_float32_to_float64(arg1, t1);
3339     tcg_temp_free_i32(t1);
3340 }
3341
3342  /* lfd lfdu lfdux lfdx */
3343 GEN_LDFS(lfd, ld64, 0x12, PPC_FLOAT);
3344  /* lfs lfsu lfsux lfsx */
3345 GEN_LDFS(lfs, ld32fs, 0x10, PPC_FLOAT);
3346
3347 /***                         Floating-point store                          ***/
3348 #define GEN_STF(name, stop, opc, type)                                        \
3349 GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type)                          \
3350 {                                                                             \
3351     TCGv EA;                                                                  \
3352     if (unlikely(!ctx->fpu_enabled)) {                                        \
3353         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3354         return;                                                               \
3355     }                                                                         \
3356     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3357     EA = tcg_temp_new();                                                      \
3358     gen_addr_imm_index(ctx, EA, 0);                                           \
3359     gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA);                       \
3360     tcg_temp_free(EA);                                                        \
3361 }
3362
3363 #define GEN_STUF(name, stop, opc, type)                                       \
3364 GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type)                       \
3365 {                                                                             \
3366     TCGv EA;                                                                  \
3367     if (unlikely(!ctx->fpu_enabled)) {                                        \
3368         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3369         return;                                                               \
3370     }                                                                         \
3371     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
3372         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
3373         return;                                                               \
3374     }                                                                         \
3375     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3376     EA = tcg_temp_new();                                                      \
3377     gen_addr_imm_index(ctx, EA, 0);                                           \
3378     gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA);                       \
3379     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
3380     tcg_temp_free(EA);                                                        \
3381 }
3382
3383 #define GEN_STUXF(name, stop, opc, type)                                      \
3384 GEN_HANDLER(name##ux, 0x1F, 0x17, opc, 0x00000001, type)                      \
3385 {                                                                             \
3386     TCGv EA;                                                                  \
3387     if (unlikely(!ctx->fpu_enabled)) {                                        \
3388         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3389         return;                                                               \
3390     }                                                                         \
3391     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
3392         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
3393         return;                                                               \
3394     }                                                                         \
3395     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3396     EA = tcg_temp_new();                                                      \
3397     gen_addr_reg_index(ctx, EA);                                              \
3398     gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA);                       \
3399     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
3400     tcg_temp_free(EA);                                                        \
3401 }
3402
3403 #define GEN_STXF(name, stop, opc2, opc3, type)                                \
3404 GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type)                      \
3405 {                                                                             \
3406     TCGv EA;                                                                  \
3407     if (unlikely(!ctx->fpu_enabled)) {                                        \
3408         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3409         return;                                                               \
3410     }                                                                         \
3411     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3412     EA = tcg_temp_new();                                                      \
3413     gen_addr_reg_index(ctx, EA);                                              \
3414     gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA);                       \
3415     tcg_temp_free(EA);                                                        \
3416 }
3417
3418 #define GEN_STFS(name, stop, op, type)                                        \
3419 GEN_STF(name, stop, op | 0x20, type);                                         \
3420 GEN_STUF(name, stop, op | 0x21, type);                                        \
3421 GEN_STUXF(name, stop, op | 0x01, type);                                       \
3422 GEN_STXF(name, stop, 0x17, op | 0x00, type)
3423
3424 static always_inline void gen_qemu_st32fs(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
3425 {
3426     TCGv_i32 t0 = tcg_temp_new_i32();
3427     TCGv t1 = tcg_temp_new();
3428     gen_helper_float64_to_float32(t0, arg1);
3429     tcg_gen_extu_i32_tl(t1, t0);
3430     tcg_temp_free_i32(t0);
3431     gen_qemu_st32(ctx, t1, arg2);
3432     tcg_temp_free(t1);
3433 }
3434
3435 /* stfd stfdu stfdux stfdx */
3436 GEN_STFS(stfd, st64, 0x16, PPC_FLOAT);
3437 /* stfs stfsu stfsux stfsx */
3438 GEN_STFS(stfs, st32fs, 0x14, PPC_FLOAT);
3439
3440 /* Optional: */
3441 static always_inline void gen_qemu_st32fiw(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
3442 {
3443     TCGv t0 = tcg_temp_new();
3444     tcg_gen_trunc_i64_tl(t0, arg1),
3445     gen_qemu_st32(ctx, t0, arg2);
3446     tcg_temp_free(t0);
3447 }
3448 /* stfiwx */
3449 GEN_STXF(stfiw, st32fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX);
3450
3451 /***                                Branch                                 ***/
3452 static always_inline void gen_goto_tb (DisasContext *ctx, int n,
3453                                        target_ulong dest)
3454 {
3455     TranslationBlock *tb;
3456     tb = ctx->tb;
3457 #if defined(TARGET_PPC64)
3458     if (!ctx->sf_mode)
3459         dest = (uint32_t) dest;
3460 #endif
3461     if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3462         likely(!ctx->singlestep_enabled)) {
3463         tcg_gen_goto_tb(n);
3464         tcg_gen_movi_tl(cpu_nip, dest & ~3);
3465         tcg_gen_exit_tb((long)tb + n);
3466     } else {
3467         tcg_gen_movi_tl(cpu_nip, dest & ~3);
3468         if (unlikely(ctx->singlestep_enabled)) {
3469             if ((ctx->singlestep_enabled &
3470                 (CPU_BRANCH_STEP | CPU_SINGLE_STEP)) &&
3471                 ctx->exception == POWERPC_EXCP_BRANCH) {
3472                 target_ulong tmp = ctx->nip;
3473                 ctx->nip = dest;
3474                 gen_exception(ctx, POWERPC_EXCP_TRACE);
3475                 ctx->nip = tmp;
3476             }
3477             if (ctx->singlestep_enabled & GDBSTUB_SINGLE_STEP) {
3478                 gen_debug_exception(ctx);
3479             }
3480         }
3481         tcg_gen_exit_tb(0);
3482     }
3483 }
3484
3485 static always_inline void gen_setlr (DisasContext *ctx, target_ulong nip)
3486 {
3487 #if defined(TARGET_PPC64)
3488     if (ctx->sf_mode == 0)
3489         tcg_gen_movi_tl(cpu_lr, (uint32_t)nip);
3490     else
3491 #endif
3492         tcg_gen_movi_tl(cpu_lr, nip);
3493 }
3494
3495 /* b ba bl bla */
3496 GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
3497 {
3498     target_ulong li, target;
3499
3500     ctx->exception = POWERPC_EXCP_BRANCH;
3501     /* sign extend LI */
3502 #if defined(TARGET_PPC64)
3503     if (ctx->sf_mode)
3504         li = ((int64_t)LI(ctx->opcode) << 38) >> 38;
3505     else
3506 #endif
3507         li = ((int32_t)LI(ctx->opcode) << 6) >> 6;
3508     if (likely(AA(ctx->opcode) == 0))
3509         target = ctx->nip + li - 4;
3510     else
3511         target = li;
3512     if (LK(ctx->opcode))
3513         gen_setlr(ctx, ctx->nip);
3514     gen_goto_tb(ctx, 0, target);
3515 }
3516
3517 #define BCOND_IM  0
3518 #define BCOND_LR  1
3519 #define BCOND_CTR 2
3520
3521 static always_inline void gen_bcond (DisasContext *ctx, int type)
3522 {
3523     uint32_t bo = BO(ctx->opcode);
3524     int l1 = gen_new_label();
3525     TCGv target;
3526
3527     ctx->exception = POWERPC_EXCP_BRANCH;
3528     if (type == BCOND_LR || type == BCOND_CTR) {
3529         target = tcg_temp_local_new();
3530         if (type == BCOND_CTR)
3531             tcg_gen_mov_tl(target, cpu_ctr);
3532         else
3533             tcg_gen_mov_tl(target, cpu_lr);
3534     }
3535     if (LK(ctx->opcode))
3536         gen_setlr(ctx, ctx->nip);
3537     l1 = gen_new_label();
3538     if ((bo & 0x4) == 0) {
3539         /* Decrement and test CTR */
3540         TCGv temp = tcg_temp_new();
3541         if (unlikely(type == BCOND_CTR)) {
3542             gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
3543             return;
3544         }
3545         tcg_gen_subi_tl(cpu_ctr, cpu_ctr, 1);
3546 #if defined(TARGET_PPC64)
3547         if (!ctx->sf_mode)
3548             tcg_gen_ext32u_tl(temp, cpu_ctr);
3549         else
3550 #endif
3551             tcg_gen_mov_tl(temp, cpu_ctr);
3552         if (bo & 0x2) {
3553             tcg_gen_brcondi_tl(TCG_COND_NE, temp, 0, l1);
3554         } else {
3555             tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1);
3556         }
3557         tcg_temp_free(temp);
3558     }
3559     if ((bo & 0x10) == 0) {
3560         /* Test CR */
3561         uint32_t bi = BI(ctx->opcode);
3562         uint32_t mask = 1 << (3 - (bi & 0x03));
3563         TCGv_i32 temp = tcg_temp_new_i32();
3564
3565         if (bo & 0x8) {
3566             tcg_gen_andi_i32(temp, cpu_crf[bi >> 2], mask);
3567             tcg_gen_brcondi_i32(TCG_COND_EQ, temp, 0, l1);
3568         } else {
3569             tcg_gen_andi_i32(temp, cpu_crf[bi >> 2], mask);
3570             tcg_gen_brcondi_i32(TCG_COND_NE, temp, 0, l1);
3571         }
3572         tcg_temp_free_i32(temp);
3573     }
3574     if (type == BCOND_IM) {
3575         target_ulong li = (target_long)((int16_t)(BD(ctx->opcode)));
3576         if (likely(AA(ctx->opcode) == 0)) {
3577             gen_goto_tb(ctx, 0, ctx->nip + li - 4);
3578         } else {
3579             gen_goto_tb(ctx, 0, li);
3580         }
3581         gen_set_label(l1);
3582         gen_goto_tb(ctx, 1, ctx->nip);
3583     } else {
3584 #if defined(TARGET_PPC64)
3585         if (!(ctx->sf_mode))
3586             tcg_gen_andi_tl(cpu_nip, target, (uint32_t)~3);
3587         else
3588 #endif
3589             tcg_gen_andi_tl(cpu_nip, target, ~3);
3590         tcg_gen_exit_tb(0);
3591         gen_set_label(l1);
3592 #if defined(TARGET_PPC64)
3593         if (!(ctx->sf_mode))
3594             tcg_gen_movi_tl(cpu_nip, (uint32_t)ctx->nip);
3595         else
3596 #endif
3597             tcg_gen_movi_tl(cpu_nip, ctx->nip);
3598         tcg_gen_exit_tb(0);
3599     }
3600 }
3601
3602 GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
3603 {
3604     gen_bcond(ctx, BCOND_IM);
3605 }
3606
3607 GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW)
3608 {
3609     gen_bcond(ctx, BCOND_CTR);
3610 }
3611
3612 GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW)
3613 {
3614     gen_bcond(ctx, BCOND_LR);
3615 }
3616
3617 /***                      Condition register logical                       ***/
3618 #define GEN_CRLOGIC(name, tcg_op, opc)                                        \
3619 GEN_HANDLER(name, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER)                   \
3620 {                                                                             \
3621     uint8_t bitmask;                                                          \
3622     int sh;                                                                   \
3623     TCGv_i32 t0, t1;                                                          \
3624     sh = (crbD(ctx->opcode) & 0x03) - (crbA(ctx->opcode) & 0x03);             \
3625     t0 = tcg_temp_new_i32();                                                  \
3626     if (sh > 0)                                                               \
3627         tcg_gen_shri_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2], sh);            \
3628     else if (sh < 0)                                                          \
3629         tcg_gen_shli_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2], -sh);           \
3630     else                                                                      \
3631         tcg_gen_mov_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2]);                 \
3632     t1 = tcg_temp_new_i32();                                                  \
3633     sh = (crbD(ctx->opcode) & 0x03) - (crbB(ctx->opcode) & 0x03);             \
3634     if (sh > 0)                                                               \
3635         tcg_gen_shri_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2], sh);            \
3636     else if (sh < 0)                                                          \
3637         tcg_gen_shli_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2], -sh);           \
3638     else                                                                      \
3639         tcg_gen_mov_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2]);                 \
3640     tcg_op(t0, t0, t1);                                                       \
3641     bitmask = 1 << (3 - (crbD(ctx->opcode) & 0x03));                          \
3642     tcg_gen_andi_i32(t0, t0, bitmask);                                        \
3643     tcg_gen_andi_i32(t1, cpu_crf[crbD(ctx->opcode) >> 2], ~bitmask);          \
3644     tcg_gen_or_i32(cpu_crf[crbD(ctx->opcode) >> 2], t0, t1);                  \
3645     tcg_temp_free_i32(t0);                                                    \
3646     tcg_temp_free_i32(t1);                                                    \
3647 }
3648
3649 /* crand */
3650 GEN_CRLOGIC(crand, tcg_gen_and_i32, 0x08);
3651 /* crandc */
3652 GEN_CRLOGIC(crandc, tcg_gen_andc_i32, 0x04);
3653 /* creqv */
3654 GEN_CRLOGIC(creqv, tcg_gen_eqv_i32, 0x09);
3655 /* crnand */
3656 GEN_CRLOGIC(crnand, tcg_gen_nand_i32, 0x07);
3657 /* crnor */
3658 GEN_CRLOGIC(crnor, tcg_gen_nor_i32, 0x01);
3659 /* cror */
3660 GEN_CRLOGIC(cror, tcg_gen_or_i32, 0x0E);
3661 /* crorc */
3662 GEN_CRLOGIC(crorc, tcg_gen_orc_i32, 0x0D);
3663 /* crxor */
3664 GEN_CRLOGIC(crxor, tcg_gen_xor_i32, 0x06);
3665 /* mcrf */
3666 GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER)
3667 {
3668     tcg_gen_mov_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfS(ctx->opcode)]);
3669 }
3670
3671 /***                           System linkage                              ***/
3672 /* rfi (mem_idx only) */
3673 GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW)
3674 {
3675 #if defined(CONFIG_USER_ONLY)
3676     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
3677 #else
3678     /* Restore CPU state */
3679     if (unlikely(!ctx->mem_idx)) {
3680         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
3681         return;
3682     }
3683     gen_helper_rfi();
3684     gen_sync_exception(ctx);
3685 #endif
3686 }
3687
3688 #if defined(TARGET_PPC64)
3689 GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B)
3690 {
3691 #if defined(CONFIG_USER_ONLY)
3692     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
3693 #else
3694     /* Restore CPU state */
3695     if (unlikely(!ctx->mem_idx)) {
3696         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
3697         return;
3698     }
3699     gen_helper_rfid();
3700     gen_sync_exception(ctx);
3701 #endif
3702 }
3703
3704 GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64H)
3705 {
3706 #if defined(CONFIG_USER_ONLY)
3707     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
3708 #else
3709     /* Restore CPU state */
3710     if (unlikely(ctx->mem_idx <= 1)) {
3711         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
3712         return;
3713     }
3714     gen_helper_hrfid();
3715     gen_sync_exception(ctx);
3716 #endif
3717 }
3718 #endif
3719
3720 /* sc */
3721 #if defined(CONFIG_USER_ONLY)
3722 #define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL_USER
3723 #else
3724 #define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL
3725 #endif
3726 GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFF01D, PPC_FLOW)
3727 {
3728     uint32_t lev;
3729
3730     lev = (ctx->opcode >> 5) & 0x7F;
3731     gen_exception_err(ctx, POWERPC_SYSCALL, lev);
3732 }
3733
3734 /***                                Trap                                   ***/
3735 /* tw */
3736 GEN_HANDLER(tw, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW)
3737 {
3738     TCGv_i32 t0 = tcg_const_i32(TO(ctx->opcode));
3739     /* Update the nip since this might generate a trap exception */
3740     gen_update_nip(ctx, ctx->nip);
3741     gen_helper_tw(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], t0);
3742     tcg_temp_free_i32(t0);
3743 }
3744
3745 /* twi */
3746 GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
3747 {
3748     TCGv t0 = tcg_const_tl(SIMM(ctx->opcode));
3749     TCGv_i32 t1 = tcg_const_i32(TO(ctx->opcode));
3750     /* Update the nip since this might generate a trap exception */
3751     gen_update_nip(ctx, ctx->nip);
3752     gen_helper_tw(cpu_gpr[rA(ctx->opcode)], t0, t1);
3753     tcg_temp_free(t0);
3754     tcg_temp_free_i32(t1);
3755 }
3756
3757 #if defined(TARGET_PPC64)
3758 /* td */
3759 GEN_HANDLER(td, 0x1F, 0x04, 0x02, 0x00000001, PPC_64B)
3760 {
3761     TCGv_i32 t0 = tcg_const_i32(TO(ctx->opcode));
3762     /* Update the nip since this might generate a trap exception */
3763     gen_update_nip(ctx, ctx->nip);
3764     gen_helper_td(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], t0);
3765     tcg_temp_free_i32(t0);
3766 }
3767
3768 /* tdi */
3769 GEN_HANDLER(tdi, 0x02, 0xFF, 0xFF, 0x00000000, PPC_64B)
3770 {
3771     TCGv t0 = tcg_const_tl(SIMM(ctx->opcode));
3772     TCGv_i32 t1 = 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_td(cpu_gpr[rA(ctx->opcode)], t0, t1);
3776     tcg_temp_free(t0);
3777     tcg_temp_free_i32(t1);
3778 }
3779 #endif
3780
3781 /***                          Processor control                            ***/
3782 /* mcrxr */
3783 GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC)
3784 {
3785     tcg_gen_trunc_tl_i32(cpu_crf[crfD(ctx->opcode)], cpu_xer);
3786     tcg_gen_shri_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], XER_CA);
3787     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_SO | 1 << XER_OV | 1 << XER_CA));
3788 }
3789
3790 /* mfcr */
3791 GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC)
3792 {
3793     uint32_t crm, crn;
3794
3795     if (likely(ctx->opcode & 0x00100000)) {
3796         crm = CRM(ctx->opcode);
3797         if (likely((crm ^ (crm - 1)) == 0)) {
3798             crn = ffs(crm);
3799             tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], cpu_crf[7 - crn]);
3800         }
3801     } else {
3802         gen_helper_load_cr(cpu_gpr[rD(ctx->opcode)]);
3803     }
3804 }
3805
3806 /* mfmsr */
3807 GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC)
3808 {
3809 #if defined(CONFIG_USER_ONLY)
3810     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
3811 #else
3812     if (unlikely(!ctx->mem_idx)) {
3813         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
3814         return;
3815     }
3816     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_msr);
3817 #endif
3818 }
3819
3820 #if 1
3821 #define SPR_NOACCESS ((void *)(-1UL))
3822 #else
3823 static void spr_noaccess (void *opaque, int sprn)
3824 {
3825     sprn = ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
3826     printf("ERROR: try to access SPR %d !\n", sprn);
3827 }
3828 #define SPR_NOACCESS (&spr_noaccess)
3829 #endif
3830
3831 /* mfspr */
3832 static always_inline void gen_op_mfspr (DisasContext *ctx)
3833 {
3834     void (*read_cb)(void *opaque, int gprn, int sprn);
3835     uint32_t sprn = SPR(ctx->opcode);
3836
3837 #if !defined(CONFIG_USER_ONLY)
3838     if (ctx->mem_idx == 2)
3839         read_cb = ctx->spr_cb[sprn].hea_read;
3840     else if (ctx->mem_idx)
3841         read_cb = ctx->spr_cb[sprn].oea_read;
3842     else
3843 #endif
3844         read_cb = ctx->spr_cb[sprn].uea_read;
3845     if (likely(read_cb != NULL)) {
3846         if (likely(read_cb != SPR_NOACCESS)) {
3847             (*read_cb)(ctx, rD(ctx->opcode), sprn);
3848         } else {
3849             /* Privilege exception */
3850             /* This is a hack to avoid warnings when running Linux:
3851              * this OS breaks the PowerPC virtualisation model,
3852              * allowing userland application to read the PVR
3853              */
3854             if (sprn != SPR_PVR) {
3855                 if (loglevel != 0) {
3856                     fprintf(logfile, "Trying to read privileged spr %d %03x at "
3857                             ADDRX "\n", sprn, sprn, ctx->nip);
3858                 }
3859                 printf("Trying to read privileged spr %d %03x at " ADDRX "\n",
3860                        sprn, sprn, ctx->nip);
3861             }
3862             gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
3863         }
3864     } else {
3865         /* Not defined */
3866         if (loglevel != 0) {
3867             fprintf(logfile, "Trying to read invalid spr %d %03x at "
3868                     ADDRX "\n", sprn, sprn, ctx->nip);
3869         }
3870         printf("Trying to read invalid spr %d %03x at " ADDRX "\n",
3871                sprn, sprn, ctx->nip);
3872         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR);
3873     }
3874 }
3875
3876 GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC)
3877 {
3878     gen_op_mfspr(ctx);
3879 }
3880
3881 /* mftb */
3882 GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MFTB)
3883 {
3884     gen_op_mfspr(ctx);
3885 }
3886
3887 /* mtcrf */
3888 GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC)
3889 {
3890     uint32_t crm, crn;
3891
3892     crm = CRM(ctx->opcode);
3893     if (likely((ctx->opcode & 0x00100000) || (crm ^ (crm - 1)) == 0)) {
3894         TCGv_i32 temp = tcg_temp_new_i32();
3895         crn = ffs(crm);
3896         tcg_gen_trunc_tl_i32(temp, cpu_gpr[rS(ctx->opcode)]);
3897         tcg_gen_shri_i32(cpu_crf[7 - crn], temp, crn * 4);
3898         tcg_gen_andi_i32(cpu_crf[7 - crn], cpu_crf[7 - crn], 0xf);
3899         tcg_temp_free_i32(temp);
3900     } else {
3901         TCGv_i32 temp = tcg_const_i32(crm);
3902         gen_helper_store_cr(cpu_gpr[rS(ctx->opcode)], temp);
3903         tcg_temp_free_i32(temp);
3904     }
3905 }
3906
3907 /* mtmsr */
3908 #if defined(TARGET_PPC64)
3909 GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001EF801, PPC_64B)
3910 {
3911 #if defined(CONFIG_USER_ONLY)
3912     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
3913 #else
3914     if (unlikely(!ctx->mem_idx)) {
3915         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
3916         return;
3917     }
3918     if (ctx->opcode & 0x00010000) {
3919         /* Special form that does not need any synchronisation */
3920         TCGv t0 = tcg_temp_new();
3921         tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1 << MSR_RI) | (1 << MSR_EE));
3922         tcg_gen_andi_tl(cpu_msr, cpu_msr, ~((1 << MSR_RI) | (1 << MSR_EE)));
3923         tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
3924         tcg_temp_free(t0);
3925     } else {
3926         /* XXX: we need to update nip before the store
3927          *      if we enter power saving mode, we will exit the loop
3928          *      directly from ppc_store_msr
3929          */
3930         gen_update_nip(ctx, ctx->nip);
3931         gen_helper_store_msr(cpu_gpr[rS(ctx->opcode)]);
3932         /* Must stop the translation as machine state (may have) changed */
3933         /* Note that mtmsr is not always defined as context-synchronizing */
3934         gen_stop_exception(ctx);
3935     }
3936 #endif
3937 }
3938 #endif
3939
3940 GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC)
3941 {
3942 #if defined(CONFIG_USER_ONLY)
3943     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
3944 #else
3945     if (unlikely(!ctx->mem_idx)) {
3946         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
3947         return;
3948     }
3949     if (ctx->opcode & 0x00010000) {
3950         /* Special form that does not need any synchronisation */
3951         TCGv t0 = tcg_temp_new();
3952         tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1 << MSR_RI) | (1 << MSR_EE));
3953         tcg_gen_andi_tl(cpu_msr, cpu_msr, ~((1 << MSR_RI) | (1 << MSR_EE)));
3954         tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
3955         tcg_temp_free(t0);
3956     } else {
3957         /* XXX: we need to update nip before the store
3958          *      if we enter power saving mode, we will exit the loop
3959          *      directly from ppc_store_msr
3960          */
3961         gen_update_nip(ctx, ctx->nip);
3962 #if defined(TARGET_PPC64)
3963         if (!ctx->sf_mode) {
3964             TCGv t0 = tcg_temp_new();
3965             TCGv t1 = tcg_temp_new();
3966             tcg_gen_andi_tl(t0, cpu_msr, 0xFFFFFFFF00000000ULL);
3967             tcg_gen_ext32u_tl(t1, cpu_gpr[rS(ctx->opcode)]);
3968             tcg_gen_or_tl(t0, t0, t1);
3969             tcg_temp_free(t1);
3970             gen_helper_store_msr(t0);
3971             tcg_temp_free(t0);
3972         } else
3973 #endif
3974             gen_helper_store_msr(cpu_gpr[rS(ctx->opcode)]);
3975         /* Must stop the translation as machine state (may have) changed */
3976         /* Note that mtmsr is not always defined as context-synchronizing */
3977         gen_stop_exception(ctx);
3978     }
3979 #endif
3980 }
3981
3982 /* mtspr */
3983 GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC)
3984 {
3985     void (*write_cb)(void *opaque, int sprn, int gprn);
3986     uint32_t sprn = SPR(ctx->opcode);
3987
3988 #if !defined(CONFIG_USER_ONLY)
3989     if (ctx->mem_idx == 2)
3990         write_cb = ctx->spr_cb[sprn].hea_write;
3991     else if (ctx->mem_idx)
3992         write_cb = ctx->spr_cb[sprn].oea_write;
3993     else
3994 #endif
3995         write_cb = ctx->spr_cb[sprn].uea_write;
3996     if (likely(write_cb != NULL)) {
3997         if (likely(write_cb != SPR_NOACCESS)) {
3998             (*write_cb)(ctx, sprn, rS(ctx->opcode));
3999         } else {
4000             /* Privilege exception */
4001             if (loglevel != 0) {
4002                 fprintf(logfile, "Trying to write privileged spr %d %03x at "
4003                         ADDRX "\n", sprn, sprn, ctx->nip);
4004             }
4005             printf("Trying to write privileged spr %d %03x at " ADDRX "\n",
4006                    sprn, sprn, ctx->nip);
4007             gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4008         }
4009     } else {
4010         /* Not defined */
4011         if (loglevel != 0) {
4012             fprintf(logfile, "Trying to write invalid spr %d %03x at "
4013                     ADDRX "\n", sprn, sprn, ctx->nip);
4014         }
4015         printf("Trying to write invalid spr %d %03x at " ADDRX "\n",
4016                sprn, sprn, ctx->nip);
4017         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR);
4018     }
4019 }
4020
4021 /***                         Cache management                              ***/
4022 /* dcbf */
4023 GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03C00001, PPC_CACHE)
4024 {
4025     /* XXX: specification says this is treated as a load by the MMU */
4026     TCGv t0;
4027     gen_set_access_type(ctx, ACCESS_CACHE);
4028     t0 = tcg_temp_new();
4029     gen_addr_reg_index(ctx, t0);
4030     gen_qemu_ld8u(ctx, t0, t0);
4031     tcg_temp_free(t0);
4032 }
4033
4034 /* dcbi (Supervisor only) */
4035 GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE)
4036 {
4037 #if defined(CONFIG_USER_ONLY)
4038     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4039 #else
4040     TCGv EA, val;
4041     if (unlikely(!ctx->mem_idx)) {
4042         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4043         return;
4044     }
4045     EA = tcg_temp_new();
4046     gen_set_access_type(ctx, ACCESS_CACHE);
4047     gen_addr_reg_index(ctx, EA);
4048     val = tcg_temp_new();
4049     /* XXX: specification says this should be treated as a store by the MMU */
4050     gen_qemu_ld8u(ctx, val, EA);
4051     gen_qemu_st8(ctx, val, EA);
4052     tcg_temp_free(val);
4053     tcg_temp_free(EA);
4054 #endif
4055 }
4056
4057 /* dcdst */
4058 GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE)
4059 {
4060     /* XXX: specification say this is treated as a load by the MMU */
4061     TCGv t0;
4062     gen_set_access_type(ctx, ACCESS_CACHE);
4063     t0 = tcg_temp_new();
4064     gen_addr_reg_index(ctx, t0);
4065     gen_qemu_ld8u(ctx, t0, t0);
4066     tcg_temp_free(t0);
4067 }
4068
4069 /* dcbt */
4070 GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x02000001, PPC_CACHE)
4071 {
4072     /* interpreted as no-op */
4073     /* XXX: specification say this is treated as a load by the MMU
4074      *      but does not generate any exception
4075      */
4076 }
4077
4078 /* dcbtst */
4079 GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x02000001, PPC_CACHE)
4080 {
4081     /* interpreted as no-op */
4082     /* XXX: specification say this is treated as a load by the MMU
4083      *      but does not generate any exception
4084      */
4085 }
4086
4087 /* dcbz */
4088 GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE_DCBZ)
4089 {
4090     TCGv t0;
4091     gen_set_access_type(ctx, ACCESS_CACHE);
4092     /* NIP cannot be restored if the memory exception comes from an helper */
4093     gen_update_nip(ctx, ctx->nip - 4);
4094     t0 = tcg_temp_new();
4095     gen_addr_reg_index(ctx, t0);
4096     gen_helper_dcbz(t0);
4097     tcg_temp_free(t0);
4098 }
4099
4100 GEN_HANDLER2(dcbz_970, "dcbz", 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZT)
4101 {
4102     TCGv t0;
4103     gen_set_access_type(ctx, ACCESS_CACHE);
4104     /* NIP cannot be restored if the memory exception comes from an helper */
4105     gen_update_nip(ctx, ctx->nip - 4);
4106     t0 = tcg_temp_new();
4107     gen_addr_reg_index(ctx, t0);
4108     if (ctx->opcode & 0x00200000)
4109         gen_helper_dcbz(t0);
4110     else
4111         gen_helper_dcbz_970(t0);
4112     tcg_temp_free(t0);
4113 }
4114
4115 /* icbi */
4116 GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE_ICBI)
4117 {
4118     TCGv t0;
4119     gen_set_access_type(ctx, ACCESS_CACHE);
4120     /* NIP cannot be restored if the memory exception comes from an helper */
4121     gen_update_nip(ctx, ctx->nip - 4);
4122     t0 = tcg_temp_new();
4123     gen_addr_reg_index(ctx, t0);
4124     gen_helper_icbi(t0);
4125     tcg_temp_free(t0);
4126 }
4127
4128 /* Optional: */
4129 /* dcba */
4130 GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_DCBA)
4131 {
4132     /* interpreted as no-op */
4133     /* XXX: specification say this is treated as a store by the MMU
4134      *      but does not generate any exception
4135      */
4136 }
4137
4138 /***                    Segment register manipulation                      ***/
4139 /* Supervisor only: */
4140 /* mfsr */
4141 GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT)
4142 {
4143 #if defined(CONFIG_USER_ONLY)
4144     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4145 #else
4146     TCGv t0;
4147     if (unlikely(!ctx->mem_idx)) {
4148         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4149         return;
4150     }
4151     t0 = tcg_const_tl(SR(ctx->opcode));
4152     gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], t0);
4153     tcg_temp_free(t0);
4154 #endif
4155 }
4156
4157 /* mfsrin */
4158 GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT)
4159 {
4160 #if defined(CONFIG_USER_ONLY)
4161     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4162 #else
4163     TCGv t0;
4164     if (unlikely(!ctx->mem_idx)) {
4165         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4166         return;
4167     }
4168     t0 = tcg_temp_new();
4169     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
4170     tcg_gen_andi_tl(t0, t0, 0xF);
4171     gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], t0);
4172     tcg_temp_free(t0);
4173 #endif
4174 }
4175
4176 /* mtsr */
4177 GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT)
4178 {
4179 #if defined(CONFIG_USER_ONLY)
4180     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4181 #else
4182     TCGv t0;
4183     if (unlikely(!ctx->mem_idx)) {
4184         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4185         return;
4186     }
4187     t0 = tcg_const_tl(SR(ctx->opcode));
4188     gen_helper_store_sr(t0, cpu_gpr[rS(ctx->opcode)]);
4189     tcg_temp_free(t0);
4190 #endif
4191 }
4192
4193 /* mtsrin */
4194 GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT)
4195 {
4196 #if defined(CONFIG_USER_ONLY)
4197     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4198 #else
4199     TCGv t0;
4200     if (unlikely(!ctx->mem_idx)) {
4201         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4202         return;
4203     }
4204     t0 = tcg_temp_new();
4205     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
4206     tcg_gen_andi_tl(t0, t0, 0xF);
4207     gen_helper_store_sr(t0, cpu_gpr[rD(ctx->opcode)]);
4208     tcg_temp_free(t0);
4209 #endif
4210 }
4211
4212 #if defined(TARGET_PPC64)
4213 /* Specific implementation for PowerPC 64 "bridge" emulation using SLB */
4214 /* mfsr */
4215 GEN_HANDLER2(mfsr_64b, "mfsr", 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT_64B)
4216 {
4217 #if defined(CONFIG_USER_ONLY)
4218     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4219 #else
4220     TCGv t0;
4221     if (unlikely(!ctx->mem_idx)) {
4222         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4223         return;
4224     }
4225     t0 = tcg_const_tl(SR(ctx->opcode));
4226     gen_helper_load_slb(cpu_gpr[rD(ctx->opcode)], t0);
4227     tcg_temp_free(t0);
4228 #endif
4229 }
4230
4231 /* mfsrin */
4232 GEN_HANDLER2(mfsrin_64b, "mfsrin", 0x1F, 0x13, 0x14, 0x001F0001,
4233              PPC_SEGMENT_64B)
4234 {
4235 #if defined(CONFIG_USER_ONLY)
4236     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4237 #else
4238     TCGv t0;
4239     if (unlikely(!ctx->mem_idx)) {
4240         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4241         return;
4242     }
4243     t0 = tcg_temp_new();
4244     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
4245     tcg_gen_andi_tl(t0, t0, 0xF);
4246     gen_helper_load_slb(cpu_gpr[rD(ctx->opcode)], t0);
4247     tcg_temp_free(t0);
4248 #endif
4249 }
4250
4251 /* mtsr */
4252 GEN_HANDLER2(mtsr_64b, "mtsr", 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B)
4253 {
4254 #if defined(CONFIG_USER_ONLY)
4255     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4256 #else
4257     TCGv t0;
4258     if (unlikely(!ctx->mem_idx)) {
4259         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4260         return;
4261     }
4262     t0 = tcg_const_tl(SR(ctx->opcode));
4263     gen_helper_store_slb(t0, cpu_gpr[rS(ctx->opcode)]);
4264     tcg_temp_free(t0);
4265 #endif
4266 }
4267
4268 /* mtsrin */
4269 GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001,
4270              PPC_SEGMENT_64B)
4271 {
4272 #if defined(CONFIG_USER_ONLY)
4273     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4274 #else
4275     TCGv t0;
4276     if (unlikely(!ctx->mem_idx)) {
4277         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4278         return;
4279     }
4280     t0 = tcg_temp_new();
4281     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
4282     tcg_gen_andi_tl(t0, t0, 0xF);
4283     gen_helper_store_slb(t0, cpu_gpr[rS(ctx->opcode)]);
4284     tcg_temp_free(t0);
4285 #endif
4286 }
4287 #endif /* defined(TARGET_PPC64) */
4288
4289 /***                      Lookaside buffer management                      ***/
4290 /* Optional & mem_idx only: */
4291 /* tlbia */
4292 GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA)
4293 {
4294 #if defined(CONFIG_USER_ONLY)
4295     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4296 #else
4297     if (unlikely(!ctx->mem_idx)) {
4298         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4299         return;
4300     }
4301     gen_helper_tlbia();
4302 #endif
4303 }
4304
4305 /* tlbie */
4306 GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE)
4307 {
4308 #if defined(CONFIG_USER_ONLY)
4309     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4310 #else
4311     if (unlikely(!ctx->mem_idx)) {
4312         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4313         return;
4314     }
4315 #if defined(TARGET_PPC64)
4316     if (!ctx->sf_mode) {
4317         TCGv t0 = tcg_temp_new();
4318         tcg_gen_ext32u_tl(t0, cpu_gpr[rB(ctx->opcode)]);
4319         gen_helper_tlbie(t0);
4320         tcg_temp_free(t0);
4321     } else
4322 #endif
4323         gen_helper_tlbie(cpu_gpr[rB(ctx->opcode)]);
4324 #endif
4325 }
4326
4327 /* tlbsync */
4328 GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC)
4329 {
4330 #if defined(CONFIG_USER_ONLY)
4331     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4332 #else
4333     if (unlikely(!ctx->mem_idx)) {
4334         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4335         return;
4336     }
4337     /* This has no effect: it should ensure that all previous
4338      * tlbie have completed
4339      */
4340     gen_stop_exception(ctx);
4341 #endif
4342 }
4343
4344 #if defined(TARGET_PPC64)
4345 /* slbia */
4346 GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x03FFFC01, PPC_SLBI)
4347 {
4348 #if defined(CONFIG_USER_ONLY)
4349     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4350 #else
4351     if (unlikely(!ctx->mem_idx)) {
4352         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4353         return;
4354     }
4355     gen_helper_slbia();
4356 #endif
4357 }
4358
4359 /* slbie */
4360 GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI)
4361 {
4362 #if defined(CONFIG_USER_ONLY)
4363     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4364 #else
4365     if (unlikely(!ctx->mem_idx)) {
4366         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4367         return;
4368     }
4369     gen_helper_slbie(cpu_gpr[rB(ctx->opcode)]);
4370 #endif
4371 }
4372 #endif
4373
4374 /***                              External control                         ***/
4375 /* Optional: */
4376 /* eciwx */
4377 GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN)
4378 {
4379     TCGv t0;
4380     /* Should check EAR[E] ! */
4381     gen_set_access_type(ctx, ACCESS_EXT);
4382     t0 = tcg_temp_new();
4383     gen_addr_reg_index(ctx, t0);
4384     gen_check_align(ctx, t0, 0x03);
4385     gen_qemu_ld32u(ctx, cpu_gpr[rD(ctx->opcode)], t0);
4386     tcg_temp_free(t0);
4387 }
4388
4389 /* ecowx */
4390 GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN)
4391 {
4392     TCGv t0;
4393     /* Should check EAR[E] ! */
4394     gen_set_access_type(ctx, ACCESS_EXT);
4395     t0 = tcg_temp_new();
4396     gen_addr_reg_index(ctx, t0);
4397     gen_check_align(ctx, t0, 0x03);
4398     gen_qemu_st32(ctx, cpu_gpr[rD(ctx->opcode)], t0);
4399     tcg_temp_free(t0);
4400 }
4401
4402 /* PowerPC 601 specific instructions */
4403 /* abs - abs. */
4404 GEN_HANDLER(abs, 0x1F, 0x08, 0x0B, 0x0000F800, PPC_POWER_BR)
4405 {
4406     int l1 = gen_new_label();
4407     int l2 = gen_new_label();
4408     tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rA(ctx->opcode)], 0, l1);
4409     tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4410     tcg_gen_br(l2);
4411     gen_set_label(l1);
4412     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4413     gen_set_label(l2);
4414     if (unlikely(Rc(ctx->opcode) != 0))
4415         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4416 }
4417
4418 /* abso - abso. */
4419 GEN_HANDLER(abso, 0x1F, 0x08, 0x1B, 0x0000F800, PPC_POWER_BR)
4420 {
4421     int l1 = gen_new_label();
4422     int l2 = gen_new_label();
4423     int l3 = gen_new_label();
4424     /* Start with XER OV disabled, the most likely case */
4425     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
4426     tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rA(ctx->opcode)], 0, l2);
4427     tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rA(ctx->opcode)], 0x80000000, l1);
4428     tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
4429     tcg_gen_br(l2);
4430     gen_set_label(l1);
4431     tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4432     tcg_gen_br(l3);
4433     gen_set_label(l2);
4434     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4435     gen_set_label(l3);
4436     if (unlikely(Rc(ctx->opcode) != 0))
4437         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4438 }
4439
4440 /* clcs */
4441 GEN_HANDLER(clcs, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR)
4442 {
4443     TCGv_i32 t0 = tcg_const_i32(rA(ctx->opcode));
4444     gen_helper_clcs(cpu_gpr[rD(ctx->opcode)], t0);
4445     tcg_temp_free_i32(t0);
4446     /* Rc=1 sets CR0 to an undefined state */
4447 }
4448
4449 /* div - div. */
4450 GEN_HANDLER(div, 0x1F, 0x0B, 0x0A, 0x00000000, PPC_POWER_BR)
4451 {
4452     gen_helper_div(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
4453     if (unlikely(Rc(ctx->opcode) != 0))
4454         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4455 }
4456
4457 /* divo - divo. */
4458 GEN_HANDLER(divo, 0x1F, 0x0B, 0x1A, 0x00000000, PPC_POWER_BR)
4459 {
4460     gen_helper_divo(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
4461     if (unlikely(Rc(ctx->opcode) != 0))
4462         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4463 }
4464
4465 /* divs - divs. */
4466 GEN_HANDLER(divs, 0x1F, 0x0B, 0x0B, 0x00000000, PPC_POWER_BR)
4467 {
4468     gen_helper_divs(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
4469     if (unlikely(Rc(ctx->opcode) != 0))
4470         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4471 }
4472
4473 /* divso - divso. */
4474 GEN_HANDLER(divso, 0x1F, 0x0B, 0x1B, 0x00000000, PPC_POWER_BR)
4475 {
4476     gen_helper_divso(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
4477     if (unlikely(Rc(ctx->opcode) != 0))
4478         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4479 }
4480
4481 /* doz - doz. */
4482 GEN_HANDLER(doz, 0x1F, 0x08, 0x08, 0x00000000, PPC_POWER_BR)
4483 {
4484     int l1 = gen_new_label();
4485     int l2 = gen_new_label();
4486     tcg_gen_brcond_tl(TCG_COND_GE, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], l1);
4487     tcg_gen_sub_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4488     tcg_gen_br(l2);
4489     gen_set_label(l1);
4490     tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
4491     gen_set_label(l2);
4492     if (unlikely(Rc(ctx->opcode) != 0))
4493         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4494 }
4495
4496 /* dozo - dozo. */
4497 GEN_HANDLER(dozo, 0x1F, 0x08, 0x18, 0x00000000, PPC_POWER_BR)
4498 {
4499     int l1 = gen_new_label();
4500     int l2 = gen_new_label();
4501     TCGv t0 = tcg_temp_new();
4502     TCGv t1 = tcg_temp_new();
4503     TCGv t2 = tcg_temp_new();
4504     /* Start with XER OV disabled, the most likely case */
4505     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
4506     tcg_gen_brcond_tl(TCG_COND_GE, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], l1);
4507     tcg_gen_sub_tl(t0, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4508     tcg_gen_xor_tl(t1, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4509     tcg_gen_xor_tl(t2, cpu_gpr[rA(ctx->opcode)], t0);
4510     tcg_gen_andc_tl(t1, t1, t2);
4511     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
4512     tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l2);
4513     tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
4514     tcg_gen_br(l2);
4515     gen_set_label(l1);
4516     tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
4517     gen_set_label(l2);
4518     tcg_temp_free(t0);
4519     tcg_temp_free(t1);
4520     tcg_temp_free(t2);
4521     if (unlikely(Rc(ctx->opcode) != 0))
4522         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4523 }
4524
4525 /* dozi */
4526 GEN_HANDLER(dozi, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
4527 {
4528     target_long simm = SIMM(ctx->opcode);
4529     int l1 = gen_new_label();
4530     int l2 = gen_new_label();
4531     tcg_gen_brcondi_tl(TCG_COND_LT, cpu_gpr[rA(ctx->opcode)], simm, l1);
4532     tcg_gen_subfi_tl(cpu_gpr[rD(ctx->opcode)], simm, cpu_gpr[rA(ctx->opcode)]);
4533     tcg_gen_br(l2);
4534     gen_set_label(l1);
4535     tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
4536     gen_set_label(l2);
4537     if (unlikely(Rc(ctx->opcode) != 0))
4538         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4539 }
4540
4541 /* lscbx - lscbx. */
4542 GEN_HANDLER(lscbx, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR)
4543 {
4544     TCGv t0 = tcg_temp_new();
4545     TCGv_i32 t1 = tcg_const_i32(rD(ctx->opcode));
4546     TCGv_i32 t2 = tcg_const_i32(rA(ctx->opcode));
4547     TCGv_i32 t3 = tcg_const_i32(rB(ctx->opcode));
4548
4549     gen_addr_reg_index(ctx, t0);
4550     /* NIP cannot be restored if the memory exception comes from an helper */
4551     gen_update_nip(ctx, ctx->nip - 4);
4552     gen_helper_lscbx(t0, t0, t1, t2, t3);
4553     tcg_temp_free_i32(t1);
4554     tcg_temp_free_i32(t2);
4555     tcg_temp_free_i32(t3);
4556     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~0x7F);
4557     tcg_gen_or_tl(cpu_xer, cpu_xer, t0);
4558     if (unlikely(Rc(ctx->opcode) != 0))
4559         gen_set_Rc0(ctx, t0);
4560     tcg_temp_free(t0);
4561 }
4562
4563 /* maskg - maskg. */
4564 GEN_HANDLER(maskg, 0x1F, 0x1D, 0x00, 0x00000000, PPC_POWER_BR)
4565 {
4566     int l1 = gen_new_label();
4567     TCGv t0 = tcg_temp_new();
4568     TCGv t1 = tcg_temp_new();
4569     TCGv t2 = tcg_temp_new();
4570     TCGv t3 = tcg_temp_new();
4571     tcg_gen_movi_tl(t3, 0xFFFFFFFF);
4572     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
4573     tcg_gen_andi_tl(t1, cpu_gpr[rS(ctx->opcode)], 0x1F);
4574     tcg_gen_addi_tl(t2, t0, 1);
4575     tcg_gen_shr_tl(t2, t3, t2);
4576     tcg_gen_shr_tl(t3, t3, t1);
4577     tcg_gen_xor_tl(cpu_gpr[rA(ctx->opcode)], t2, t3);
4578     tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
4579     tcg_gen_neg_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4580     gen_set_label(l1);
4581     tcg_temp_free(t0);
4582     tcg_temp_free(t1);
4583     tcg_temp_free(t2);
4584     tcg_temp_free(t3);
4585     if (unlikely(Rc(ctx->opcode) != 0))
4586         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4587 }
4588
4589 /* maskir - maskir. */
4590 GEN_HANDLER(maskir, 0x1F, 0x1D, 0x10, 0x00000000, PPC_POWER_BR)
4591 {
4592     TCGv t0 = tcg_temp_new();
4593     TCGv t1 = tcg_temp_new();
4594     tcg_gen_and_tl(t0, cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
4595     tcg_gen_andc_tl(t1, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
4596     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
4597     tcg_temp_free(t0);
4598     tcg_temp_free(t1);
4599     if (unlikely(Rc(ctx->opcode) != 0))
4600         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4601 }
4602
4603 /* mul - mul. */
4604 GEN_HANDLER(mul, 0x1F, 0x0B, 0x03, 0x00000000, PPC_POWER_BR)
4605 {
4606     TCGv_i64 t0 = tcg_temp_new_i64();
4607     TCGv_i64 t1 = tcg_temp_new_i64();
4608     TCGv t2 = tcg_temp_new();
4609     tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
4610     tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
4611     tcg_gen_mul_i64(t0, t0, t1);
4612     tcg_gen_trunc_i64_tl(t2, t0);
4613     gen_store_spr(SPR_MQ, t2);
4614     tcg_gen_shri_i64(t1, t0, 32);
4615     tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t1);
4616     tcg_temp_free_i64(t0);
4617     tcg_temp_free_i64(t1);
4618     tcg_temp_free(t2);
4619     if (unlikely(Rc(ctx->opcode) != 0))
4620         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4621 }
4622
4623 /* mulo - mulo. */
4624 GEN_HANDLER(mulo, 0x1F, 0x0B, 0x13, 0x00000000, PPC_POWER_BR)
4625 {
4626     int l1 = gen_new_label();
4627     TCGv_i64 t0 = tcg_temp_new_i64();
4628     TCGv_i64 t1 = tcg_temp_new_i64();
4629     TCGv t2 = tcg_temp_new();
4630     /* Start with XER OV disabled, the most likely case */
4631     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
4632     tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
4633     tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
4634     tcg_gen_mul_i64(t0, t0, t1);
4635     tcg_gen_trunc_i64_tl(t2, t0);
4636     gen_store_spr(SPR_MQ, t2);
4637     tcg_gen_shri_i64(t1, t0, 32);
4638     tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t1);
4639     tcg_gen_ext32s_i64(t1, t0);
4640     tcg_gen_brcond_i64(TCG_COND_EQ, t0, t1, l1);
4641     tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
4642     gen_set_label(l1);
4643     tcg_temp_free_i64(t0);
4644     tcg_temp_free_i64(t1);
4645     tcg_temp_free(t2);
4646     if (unlikely(Rc(ctx->opcode) != 0))
4647         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4648 }
4649
4650 /* nabs - nabs. */
4651 GEN_HANDLER(nabs, 0x1F, 0x08, 0x0F, 0x00000000, PPC_POWER_BR)
4652 {
4653     int l1 = gen_new_label();
4654     int l2 = gen_new_label();
4655     tcg_gen_brcondi_tl(TCG_COND_GT, cpu_gpr[rA(ctx->opcode)], 0, l1);
4656     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4657     tcg_gen_br(l2);
4658     gen_set_label(l1);
4659     tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4660     gen_set_label(l2);
4661     if (unlikely(Rc(ctx->opcode) != 0))
4662         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4663 }
4664
4665 /* nabso - nabso. */
4666 GEN_HANDLER(nabso, 0x1F, 0x08, 0x1F, 0x00000000, PPC_POWER_BR)
4667 {
4668     int l1 = gen_new_label();
4669     int l2 = gen_new_label();
4670     tcg_gen_brcondi_tl(TCG_COND_GT, cpu_gpr[rA(ctx->opcode)], 0, l1);
4671     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4672     tcg_gen_br(l2);
4673     gen_set_label(l1);
4674     tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4675     gen_set_label(l2);
4676     /* nabs never overflows */
4677     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
4678     if (unlikely(Rc(ctx->opcode) != 0))
4679         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4680 }
4681
4682 /* rlmi - rlmi. */
4683 GEN_HANDLER(rlmi, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
4684 {
4685     uint32_t mb = MB(ctx->opcode);
4686     uint32_t me = ME(ctx->opcode);
4687     TCGv t0 = tcg_temp_new();
4688     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
4689     tcg_gen_rotl_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
4690     tcg_gen_andi_tl(t0, t0, MASK(mb, me));
4691     tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~MASK(mb, me));
4692     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], t0);
4693     tcg_temp_free(t0);
4694     if (unlikely(Rc(ctx->opcode) != 0))
4695         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4696 }
4697
4698 /* rrib - rrib. */
4699 GEN_HANDLER(rrib, 0x1F, 0x19, 0x10, 0x00000000, PPC_POWER_BR)
4700 {
4701     TCGv t0 = tcg_temp_new();
4702     TCGv t1 = tcg_temp_new();
4703     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
4704     tcg_gen_movi_tl(t1, 0x80000000);
4705     tcg_gen_shr_tl(t1, t1, t0);
4706     tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
4707     tcg_gen_and_tl(t0, t0, t1);
4708     tcg_gen_andc_tl(t1, cpu_gpr[rA(ctx->opcode)], t1);
4709     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
4710     tcg_temp_free(t0);
4711     tcg_temp_free(t1);
4712     if (unlikely(Rc(ctx->opcode) != 0))
4713         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4714 }
4715
4716 /* sle - sle. */
4717 GEN_HANDLER(sle, 0x1F, 0x19, 0x04, 0x00000000, PPC_POWER_BR)
4718 {
4719     TCGv t0 = tcg_temp_new();
4720     TCGv t1 = tcg_temp_new();
4721     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
4722     tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
4723     tcg_gen_subfi_tl(t1, 32, t1);
4724     tcg_gen_shr_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
4725     tcg_gen_or_tl(t1, t0, t1);
4726     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
4727     gen_store_spr(SPR_MQ, t1);
4728     tcg_temp_free(t0);
4729     tcg_temp_free(t1);
4730     if (unlikely(Rc(ctx->opcode) != 0))
4731         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4732 }
4733
4734 /* sleq - sleq. */
4735 GEN_HANDLER(sleq, 0x1F, 0x19, 0x06, 0x00000000, PPC_POWER_BR)
4736 {
4737     TCGv t0 = tcg_temp_new();
4738     TCGv t1 = tcg_temp_new();
4739     TCGv t2 = tcg_temp_new();
4740     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
4741     tcg_gen_movi_tl(t2, 0xFFFFFFFF);
4742     tcg_gen_shl_tl(t2, t2, t0);
4743     tcg_gen_rotl_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
4744     gen_load_spr(t1, SPR_MQ);
4745     gen_store_spr(SPR_MQ, t0);
4746     tcg_gen_and_tl(t0, t0, t2);
4747     tcg_gen_andc_tl(t1, t1, t2);
4748     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
4749     tcg_temp_free(t0);
4750     tcg_temp_free(t1);
4751     tcg_temp_free(t2);
4752     if (unlikely(Rc(ctx->opcode) != 0))
4753         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4754 }
4755
4756 /* sliq - sliq. */
4757 GEN_HANDLER(sliq, 0x1F, 0x18, 0x05, 0x00000000, PPC_POWER_BR)
4758 {
4759     int sh = SH(ctx->opcode);
4760     TCGv t0 = tcg_temp_new();
4761     TCGv t1 = tcg_temp_new();
4762     tcg_gen_shli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
4763     tcg_gen_shri_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh);
4764     tcg_gen_or_tl(t1, t0, t1);
4765     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
4766     gen_store_spr(SPR_MQ, t1);
4767     tcg_temp_free(t0);
4768     tcg_temp_free(t1);
4769     if (unlikely(Rc(ctx->opcode) != 0))
4770         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4771 }
4772
4773 /* slliq - slliq. */
4774 GEN_HANDLER(slliq, 0x1F, 0x18, 0x07, 0x00000000, PPC_POWER_BR)
4775 {
4776     int sh = SH(ctx->opcode);
4777     TCGv t0 = tcg_temp_new();
4778     TCGv t1 = tcg_temp_new();
4779     tcg_gen_rotli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
4780     gen_load_spr(t1, SPR_MQ);
4781     gen_store_spr(SPR_MQ, t0);
4782     tcg_gen_andi_tl(t0, t0,  (0xFFFFFFFFU << sh));
4783     tcg_gen_andi_tl(t1, t1, ~(0xFFFFFFFFU << sh));
4784     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
4785     tcg_temp_free(t0);
4786     tcg_temp_free(t1);
4787     if (unlikely(Rc(ctx->opcode) != 0))
4788         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4789 }
4790
4791 /* sllq - sllq. */
4792 GEN_HANDLER(sllq, 0x1F, 0x18, 0x06, 0x00000000, PPC_POWER_BR)
4793 {
4794     int l1 = gen_new_label();
4795     int l2 = gen_new_label();
4796     TCGv t0 = tcg_temp_local_new();
4797     TCGv t1 = tcg_temp_local_new();
4798     TCGv t2 = tcg_temp_local_new();
4799     tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F);
4800     tcg_gen_movi_tl(t1, 0xFFFFFFFF);
4801     tcg_gen_shl_tl(t1, t1, t2);
4802     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20);
4803     tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
4804     gen_load_spr(t0, SPR_MQ);
4805     tcg_gen_and_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
4806     tcg_gen_br(l2);
4807     gen_set_label(l1);
4808     tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t2);
4809     gen_load_spr(t2, SPR_MQ);
4810     tcg_gen_andc_tl(t1, t2, t1);
4811     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
4812     gen_set_label(l2);
4813     tcg_temp_free(t0);
4814     tcg_temp_free(t1);
4815     tcg_temp_free(t2);
4816     if (unlikely(Rc(ctx->opcode) != 0))
4817         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4818 }
4819
4820 /* slq - slq. */
4821 GEN_HANDLER(slq, 0x1F, 0x18, 0x04, 0x00000000, PPC_POWER_BR)
4822 {
4823     int l1 = gen_new_label();
4824     TCGv t0 = tcg_temp_new();
4825     TCGv t1 = tcg_temp_new();
4826     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
4827     tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
4828     tcg_gen_subfi_tl(t1, 32, t1);
4829     tcg_gen_shr_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
4830     tcg_gen_or_tl(t1, t0, t1);
4831     gen_store_spr(SPR_MQ, t1);
4832     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x20);
4833     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
4834     tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
4835     tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
4836     gen_set_label(l1);
4837     tcg_temp_free(t0);
4838     tcg_temp_free(t1);
4839     if (unlikely(Rc(ctx->opcode) != 0))
4840         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4841 }
4842
4843 /* sraiq - sraiq. */
4844 GEN_HANDLER(sraiq, 0x1F, 0x18, 0x1D, 0x00000000, PPC_POWER_BR)
4845 {
4846     int sh = SH(ctx->opcode);
4847     int l1 = gen_new_label();
4848     TCGv t0 = tcg_temp_new();
4849     TCGv t1 = tcg_temp_new();
4850     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
4851     tcg_gen_shli_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh);
4852     tcg_gen_or_tl(t0, t0, t1);
4853     gen_store_spr(SPR_MQ, t0);
4854     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
4855     tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
4856     tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rS(ctx->opcode)], 0, l1);
4857     tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_CA));
4858     gen_set_label(l1);
4859     tcg_gen_sari_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], sh);
4860     tcg_temp_free(t0);
4861     tcg_temp_free(t1);
4862     if (unlikely(Rc(ctx->opcode) != 0))
4863         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4864 }
4865
4866 /* sraq - sraq. */
4867 GEN_HANDLER(sraq, 0x1F, 0x18, 0x1C, 0x00000000, PPC_POWER_BR)
4868 {
4869     int l1 = gen_new_label();
4870     int l2 = gen_new_label();
4871     TCGv t0 = tcg_temp_new();
4872     TCGv t1 = tcg_temp_local_new();
4873     TCGv t2 = tcg_temp_local_new();
4874     tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F);
4875     tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t2);
4876     tcg_gen_sar_tl(t1, cpu_gpr[rS(ctx->opcode)], t2);
4877     tcg_gen_subfi_tl(t2, 32, t2);
4878     tcg_gen_shl_tl(t2, cpu_gpr[rS(ctx->opcode)], t2);
4879     tcg_gen_or_tl(t0, t0, t2);
4880     gen_store_spr(SPR_MQ, t0);
4881     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20);
4882     tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, l1);
4883     tcg_gen_mov_tl(t2, cpu_gpr[rS(ctx->opcode)]);
4884     tcg_gen_sari_tl(t1, cpu_gpr[rS(ctx->opcode)], 31);
4885     gen_set_label(l1);
4886     tcg_temp_free(t0);
4887     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t1);
4888     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
4889     tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l2);
4890     tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, l2);
4891     tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_CA));
4892     gen_set_label(l2);
4893     tcg_temp_free(t1);
4894     tcg_temp_free(t2);
4895     if (unlikely(Rc(ctx->opcode) != 0))
4896         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4897 }
4898
4899 /* sre - sre. */
4900 GEN_HANDLER(sre, 0x1F, 0x19, 0x14, 0x00000000, PPC_POWER_BR)
4901 {
4902     TCGv t0 = tcg_temp_new();
4903     TCGv t1 = tcg_temp_new();
4904     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
4905     tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
4906     tcg_gen_subfi_tl(t1, 32, t1);
4907     tcg_gen_shl_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
4908     tcg_gen_or_tl(t1, t0, t1);
4909     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
4910     gen_store_spr(SPR_MQ, t1);
4911     tcg_temp_free(t0);
4912     tcg_temp_free(t1);
4913     if (unlikely(Rc(ctx->opcode) != 0))
4914         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4915 }
4916
4917 /* srea - srea. */
4918 GEN_HANDLER(srea, 0x1F, 0x19, 0x1C, 0x00000000, PPC_POWER_BR)
4919 {
4920     TCGv t0 = tcg_temp_new();
4921     TCGv t1 = tcg_temp_new();
4922     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
4923     tcg_gen_rotr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
4924     gen_store_spr(SPR_MQ, t0);
4925     tcg_gen_sar_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], t1);
4926     tcg_temp_free(t0);
4927     tcg_temp_free(t1);
4928     if (unlikely(Rc(ctx->opcode) != 0))
4929         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4930 }
4931
4932 /* sreq */
4933 GEN_HANDLER(sreq, 0x1F, 0x19, 0x16, 0x00000000, PPC_POWER_BR)
4934 {
4935     TCGv t0 = tcg_temp_new();
4936     TCGv t1 = tcg_temp_new();
4937     TCGv t2 = tcg_temp_new();
4938     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
4939     tcg_gen_movi_tl(t1, 0xFFFFFFFF);
4940     tcg_gen_shr_tl(t1, t1, t0);
4941     tcg_gen_rotr_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
4942     gen_load_spr(t2, SPR_MQ);
4943     gen_store_spr(SPR_MQ, t0);
4944     tcg_gen_and_tl(t0, t0, t1);
4945     tcg_gen_andc_tl(t2, t2, t1);
4946     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t2);
4947     tcg_temp_free(t0);
4948     tcg_temp_free(t1);
4949     tcg_temp_free(t2);
4950     if (unlikely(Rc(ctx->opcode) != 0))
4951         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4952 }
4953
4954 /* sriq */
4955 GEN_HANDLER(sriq, 0x1F, 0x18, 0x15, 0x00000000, PPC_POWER_BR)
4956 {
4957     int sh = SH(ctx->opcode);
4958     TCGv t0 = tcg_temp_new();
4959     TCGv t1 = tcg_temp_new();
4960     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
4961     tcg_gen_shli_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh);
4962     tcg_gen_or_tl(t1, t0, t1);
4963     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
4964     gen_store_spr(SPR_MQ, t1);
4965     tcg_temp_free(t0);
4966     tcg_temp_free(t1);
4967     if (unlikely(Rc(ctx->opcode) != 0))
4968         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4969 }
4970
4971 /* srliq */
4972 GEN_HANDLER(srliq, 0x1F, 0x18, 0x17, 0x00000000, PPC_POWER_BR)
4973 {
4974     int sh = SH(ctx->opcode);
4975     TCGv t0 = tcg_temp_new();
4976     TCGv t1 = tcg_temp_new();
4977     tcg_gen_rotri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
4978     gen_load_spr(t1, SPR_MQ);
4979     gen_store_spr(SPR_MQ, t0);
4980     tcg_gen_andi_tl(t0, t0,  (0xFFFFFFFFU >> sh));
4981     tcg_gen_andi_tl(t1, t1, ~(0xFFFFFFFFU >> sh));
4982     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
4983     tcg_temp_free(t0);
4984     tcg_temp_free(t1);
4985     if (unlikely(Rc(ctx->opcode) != 0))
4986         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4987 }
4988
4989 /* srlq */
4990 GEN_HANDLER(srlq, 0x1F, 0x18, 0x16, 0x00000000, PPC_POWER_BR)
4991 {
4992     int l1 = gen_new_label();
4993     int l2 = gen_new_label();
4994     TCGv t0 = tcg_temp_local_new();
4995     TCGv t1 = tcg_temp_local_new();
4996     TCGv t2 = tcg_temp_local_new();
4997     tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F);
4998     tcg_gen_movi_tl(t1, 0xFFFFFFFF);
4999     tcg_gen_shr_tl(t2, t1, t2);
5000     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20);
5001     tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
5002     gen_load_spr(t0, SPR_MQ);
5003     tcg_gen_and_tl(cpu_gpr[rA(ctx->opcode)], t0, t2);
5004     tcg_gen_br(l2);
5005     gen_set_label(l1);
5006     tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t2);
5007     tcg_gen_and_tl(t0, t0, t2);
5008     gen_load_spr(t1, SPR_MQ);
5009     tcg_gen_andc_tl(t1, t1, t2);
5010     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5011     gen_set_label(l2);
5012     tcg_temp_free(t0);
5013     tcg_temp_free(t1);
5014     tcg_temp_free(t2);
5015     if (unlikely(Rc(ctx->opcode) != 0))
5016         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5017 }
5018
5019 /* srq */
5020 GEN_HANDLER(srq, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR)
5021 {
5022     int l1 = gen_new_label();
5023     TCGv t0 = tcg_temp_new();
5024     TCGv t1 = tcg_temp_new();
5025     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
5026     tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
5027     tcg_gen_subfi_tl(t1, 32, t1);
5028     tcg_gen_shl_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
5029     tcg_gen_or_tl(t1, t0, t1);
5030     gen_store_spr(SPR_MQ, t1);
5031     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x20);
5032     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
5033     tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
5034     tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
5035     gen_set_label(l1);
5036     tcg_temp_free(t0);
5037     tcg_temp_free(t1);
5038     if (unlikely(Rc(ctx->opcode) != 0))
5039         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5040 }
5041
5042 /* PowerPC 602 specific instructions */
5043 /* dsa  */
5044 GEN_HANDLER(dsa, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC)
5045 {
5046     /* XXX: TODO */
5047     gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5048 }
5049
5050 /* esa */
5051 GEN_HANDLER(esa, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC)
5052 {
5053     /* XXX: TODO */
5054     gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5055 }
5056
5057 /* mfrom */
5058 GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC)
5059 {
5060 #if defined(CONFIG_USER_ONLY)
5061     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5062 #else
5063     if (unlikely(!ctx->mem_idx)) {
5064         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5065         return;
5066     }
5067     gen_helper_602_mfrom(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5068 #endif
5069 }
5070
5071 /* 602 - 603 - G2 TLB management */
5072 /* tlbld */
5073 GEN_HANDLER2(tlbld_6xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB)
5074 {
5075 #if defined(CONFIG_USER_ONLY)
5076     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5077 #else
5078     if (unlikely(!ctx->mem_idx)) {
5079         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5080         return;
5081     }
5082     gen_helper_6xx_tlbd(cpu_gpr[rB(ctx->opcode)]);
5083 #endif
5084 }
5085
5086 /* tlbli */
5087 GEN_HANDLER2(tlbli_6xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB)
5088 {
5089 #if defined(CONFIG_USER_ONLY)
5090     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5091 #else
5092     if (unlikely(!ctx->mem_idx)) {
5093         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5094         return;
5095     }
5096     gen_helper_6xx_tlbi(cpu_gpr[rB(ctx->opcode)]);
5097 #endif
5098 }
5099
5100 /* 74xx TLB management */
5101 /* tlbld */
5102 GEN_HANDLER2(tlbld_74xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_74xx_TLB)
5103 {
5104 #if defined(CONFIG_USER_ONLY)
5105     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5106 #else
5107     if (unlikely(!ctx->mem_idx)) {
5108         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5109         return;
5110     }
5111     gen_helper_74xx_tlbd(cpu_gpr[rB(ctx->opcode)]);
5112 #endif
5113 }
5114
5115 /* tlbli */
5116 GEN_HANDLER2(tlbli_74xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_74xx_TLB)
5117 {
5118 #if defined(CONFIG_USER_ONLY)
5119     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5120 #else
5121     if (unlikely(!ctx->mem_idx)) {
5122         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5123         return;
5124     }
5125     gen_helper_74xx_tlbi(cpu_gpr[rB(ctx->opcode)]);
5126 #endif
5127 }
5128
5129 /* POWER instructions not in PowerPC 601 */
5130 /* clf */
5131 GEN_HANDLER(clf, 0x1F, 0x16, 0x03, 0x03E00000, PPC_POWER)
5132 {
5133     /* Cache line flush: implemented as no-op */
5134 }
5135
5136 /* cli */
5137 GEN_HANDLER(cli, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER)
5138 {
5139     /* Cache line invalidate: privileged and treated as no-op */
5140 #if defined(CONFIG_USER_ONLY)
5141     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5142 #else
5143     if (unlikely(!ctx->mem_idx)) {
5144         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5145         return;
5146     }
5147 #endif
5148 }
5149
5150 /* dclst */
5151 GEN_HANDLER(dclst, 0x1F, 0x16, 0x13, 0x03E00000, PPC_POWER)
5152 {
5153     /* Data cache line store: treated as no-op */
5154 }
5155
5156 GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER)
5157 {
5158 #if defined(CONFIG_USER_ONLY)
5159     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5160 #else
5161     int ra = rA(ctx->opcode);
5162     int rd = rD(ctx->opcode);
5163     TCGv t0;
5164     if (unlikely(!ctx->mem_idx)) {
5165         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5166         return;
5167     }
5168     t0 = tcg_temp_new();
5169     gen_addr_reg_index(ctx, t0);
5170     tcg_gen_shri_tl(t0, t0, 28);
5171     tcg_gen_andi_tl(t0, t0, 0xF);
5172     gen_helper_load_sr(cpu_gpr[rd], t0);
5173     tcg_temp_free(t0);
5174     if (ra != 0 && ra != rd)
5175         tcg_gen_mov_tl(cpu_gpr[ra], cpu_gpr[rd]);
5176 #endif
5177 }
5178
5179 GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER)
5180 {
5181 #if defined(CONFIG_USER_ONLY)
5182     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5183 #else
5184     TCGv t0;
5185     if (unlikely(!ctx->mem_idx)) {
5186         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5187         return;
5188     }
5189     t0 = tcg_temp_new();
5190     gen_addr_reg_index(ctx, t0);
5191     gen_helper_rac(cpu_gpr[rD(ctx->opcode)], t0);
5192     tcg_temp_free(t0);
5193 #endif
5194 }
5195
5196 GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER)
5197 {
5198 #if defined(CONFIG_USER_ONLY)
5199     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5200 #else
5201     if (unlikely(!ctx->mem_idx)) {
5202         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5203         return;
5204     }
5205     gen_helper_rfsvc();
5206     gen_sync_exception(ctx);
5207 #endif
5208 }
5209
5210 /* svc is not implemented for now */
5211
5212 /* POWER2 specific instructions */
5213 /* Quad manipulation (load/store two floats at a time) */
5214
5215 /* lfq */
5216 GEN_HANDLER(lfq, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
5217 {
5218     int rd = rD(ctx->opcode);
5219     TCGv t0;
5220     gen_set_access_type(ctx, ACCESS_FLOAT);
5221     t0 = tcg_temp_new();
5222     gen_addr_imm_index(ctx, t0, 0);
5223     gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
5224     gen_addr_add(ctx, t0, t0, 8);
5225     gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t0);
5226     tcg_temp_free(t0);
5227 }
5228
5229 /* lfqu */
5230 GEN_HANDLER(lfqu, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
5231 {
5232     int ra = rA(ctx->opcode);
5233     int rd = rD(ctx->opcode);
5234     TCGv t0, t1;
5235     gen_set_access_type(ctx, ACCESS_FLOAT);
5236     t0 = tcg_temp_new();
5237     t1 = tcg_temp_new();
5238     gen_addr_imm_index(ctx, t0, 0);
5239     gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
5240     gen_addr_add(ctx, t1, t0, 8);
5241     gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t1);
5242     if (ra != 0)
5243         tcg_gen_mov_tl(cpu_gpr[ra], t0);
5244     tcg_temp_free(t0);
5245     tcg_temp_free(t1);
5246 }
5247
5248 /* lfqux */
5249 GEN_HANDLER(lfqux, 0x1F, 0x17, 0x19, 0x00000001, PPC_POWER2)
5250 {
5251     int ra = rA(ctx->opcode);
5252     int rd = rD(ctx->opcode);
5253     gen_set_access_type(ctx, ACCESS_FLOAT);
5254     TCGv t0, t1;
5255     t0 = tcg_temp_new();
5256     gen_addr_reg_index(ctx, t0);
5257     gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
5258     t1 = tcg_temp_new();
5259     gen_addr_add(ctx, t1, t0, 8);
5260     gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t1);
5261     tcg_temp_free(t1);
5262     if (ra != 0)
5263         tcg_gen_mov_tl(cpu_gpr[ra], t0);
5264     tcg_temp_free(t0);
5265 }
5266
5267 /* lfqx */
5268 GEN_HANDLER(lfqx, 0x1F, 0x17, 0x18, 0x00000001, PPC_POWER2)
5269 {
5270     int rd = rD(ctx->opcode);
5271     TCGv t0;
5272     gen_set_access_type(ctx, ACCESS_FLOAT);
5273     t0 = tcg_temp_new();
5274     gen_addr_reg_index(ctx, t0);
5275     gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
5276     gen_addr_add(ctx, t0, t0, 8);
5277     gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t0);
5278     tcg_temp_free(t0);
5279 }
5280
5281 /* stfq */
5282 GEN_HANDLER(stfq, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
5283 {
5284     int rd = rD(ctx->opcode);
5285     TCGv t0;
5286     gen_set_access_type(ctx, ACCESS_FLOAT);
5287     t0 = tcg_temp_new();
5288     gen_addr_imm_index(ctx, t0, 0);
5289     gen_qemu_st64(ctx, cpu_fpr[rd], t0);
5290     gen_addr_add(ctx, t0, t0, 8);
5291     gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t0);
5292     tcg_temp_free(t0);
5293 }
5294
5295 /* stfqu */
5296 GEN_HANDLER(stfqu, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
5297 {
5298     int ra = rA(ctx->opcode);
5299     int rd = rD(ctx->opcode);
5300     TCGv t0, t1;
5301     gen_set_access_type(ctx, ACCESS_FLOAT);
5302     t0 = tcg_temp_new();
5303     gen_addr_imm_index(ctx, t0, 0);
5304     gen_qemu_st64(ctx, cpu_fpr[rd], t0);
5305     t1 = tcg_temp_new();
5306     gen_addr_add(ctx, t1, t0, 8);
5307     gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t1);
5308     tcg_temp_free(t1);
5309     if (ra != 0)
5310         tcg_gen_mov_tl(cpu_gpr[ra], t0);
5311     tcg_temp_free(t0);
5312 }
5313
5314 /* stfqux */
5315 GEN_HANDLER(stfqux, 0x1F, 0x17, 0x1D, 0x00000001, PPC_POWER2)
5316 {
5317     int ra = rA(ctx->opcode);
5318     int rd = rD(ctx->opcode);
5319     TCGv t0, t1;
5320     gen_set_access_type(ctx, ACCESS_FLOAT);
5321     t0 = tcg_temp_new();
5322     gen_addr_reg_index(ctx, t0);
5323     gen_qemu_st64(ctx, cpu_fpr[rd], t0);
5324     t1 = tcg_temp_new();
5325     gen_addr_add(ctx, t1, t0, 8);
5326     gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t1);
5327     tcg_temp_free(t1);
5328     if (ra != 0)
5329         tcg_gen_mov_tl(cpu_gpr[ra], t0);
5330     tcg_temp_free(t0);
5331 }
5332
5333 /* stfqx */
5334 GEN_HANDLER(stfqx, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2)
5335 {
5336     int rd = rD(ctx->opcode);
5337     TCGv t0;
5338     gen_set_access_type(ctx, ACCESS_FLOAT);
5339     t0 = tcg_temp_new();
5340     gen_addr_reg_index(ctx, t0);
5341     gen_qemu_st64(ctx, cpu_fpr[rd], t0);
5342     gen_addr_add(ctx, t0, t0, 8);
5343     gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t0);
5344     tcg_temp_free(t0);
5345 }
5346
5347 /* BookE specific instructions */
5348 /* XXX: not implemented on 440 ? */
5349 GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_MFAPIDI)
5350 {
5351     /* XXX: TODO */
5352     gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5353 }
5354
5355 /* XXX: not implemented on 440 ? */
5356 GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_TLBIVA)
5357 {
5358 #if defined(CONFIG_USER_ONLY)
5359     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5360 #else
5361     TCGv t0;
5362     if (unlikely(!ctx->mem_idx)) {
5363         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5364         return;
5365     }
5366     t0 = tcg_temp_new();
5367     gen_addr_reg_index(ctx, t0);
5368     gen_helper_tlbie(cpu_gpr[rB(ctx->opcode)]);
5369     tcg_temp_free(t0);
5370 #endif
5371 }
5372
5373 /* All 405 MAC instructions are translated here */
5374 static always_inline void gen_405_mulladd_insn (DisasContext *ctx,
5375                                                 int opc2, int opc3,
5376                                                 int ra, int rb, int rt, int Rc)
5377 {
5378     TCGv t0, t1;
5379
5380     t0 = tcg_temp_local_new();
5381     t1 = tcg_temp_local_new();
5382
5383     switch (opc3 & 0x0D) {
5384     case 0x05:
5385         /* macchw    - macchw.    - macchwo   - macchwo.   */
5386         /* macchws   - macchws.   - macchwso  - macchwso.  */
5387         /* nmacchw   - nmacchw.   - nmacchwo  - nmacchwo.  */
5388         /* nmacchws  - nmacchws.  - nmacchwso - nmacchwso. */
5389         /* mulchw - mulchw. */
5390         tcg_gen_ext16s_tl(t0, cpu_gpr[ra]);
5391         tcg_gen_sari_tl(t1, cpu_gpr[rb], 16);
5392         tcg_gen_ext16s_tl(t1, t1);
5393         break;
5394     case 0x04:
5395         /* macchwu   - macchwu.   - macchwuo  - macchwuo.  */
5396         /* macchwsu  - macchwsu.  - macchwsuo - macchwsuo. */
5397         /* mulchwu - mulchwu. */
5398         tcg_gen_ext16u_tl(t0, cpu_gpr[ra]);
5399         tcg_gen_shri_tl(t1, cpu_gpr[rb], 16);
5400         tcg_gen_ext16u_tl(t1, t1);
5401         break;
5402     case 0x01:
5403         /* machhw    - machhw.    - machhwo   - machhwo.   */
5404         /* machhws   - machhws.   - machhwso  - machhwso.  */
5405         /* nmachhw   - nmachhw.   - nmachhwo  - nmachhwo.  */
5406         /* nmachhws  - nmachhws.  - nmachhwso - nmachhwso. */
5407         /* mulhhw - mulhhw. */
5408         tcg_gen_sari_tl(t0, cpu_gpr[ra], 16);
5409         tcg_gen_ext16s_tl(t0, t0);
5410         tcg_gen_sari_tl(t1, cpu_gpr[rb], 16);
5411         tcg_gen_ext16s_tl(t1, t1);
5412         break;
5413     case 0x00:
5414         /* machhwu   - machhwu.   - machhwuo  - machhwuo.  */
5415         /* machhwsu  - machhwsu.  - machhwsuo - machhwsuo. */
5416         /* mulhhwu - mulhhwu. */
5417         tcg_gen_shri_tl(t0, cpu_gpr[ra], 16);
5418         tcg_gen_ext16u_tl(t0, t0);
5419         tcg_gen_shri_tl(t1, cpu_gpr[rb], 16);
5420         tcg_gen_ext16u_tl(t1, t1);
5421         break;
5422     case 0x0D:
5423         /* maclhw    - maclhw.    - maclhwo   - maclhwo.   */
5424         /* maclhws   - maclhws.   - maclhwso  - maclhwso.  */
5425         /* nmaclhw   - nmaclhw.   - nmaclhwo  - nmaclhwo.  */
5426         /* nmaclhws  - nmaclhws.  - nmaclhwso - nmaclhwso. */
5427         /* mullhw - mullhw. */
5428         tcg_gen_ext16s_tl(t0, cpu_gpr[ra]);
5429         tcg_gen_ext16s_tl(t1, cpu_gpr[rb]);
5430         break;
5431     case 0x0C:
5432         /* maclhwu   - maclhwu.   - maclhwuo  - maclhwuo.  */
5433         /* maclhwsu  - maclhwsu.  - maclhwsuo - maclhwsuo. */
5434         /* mullhwu - mullhwu. */
5435         tcg_gen_ext16u_tl(t0, cpu_gpr[ra]);
5436         tcg_gen_ext16u_tl(t1, cpu_gpr[rb]);
5437         break;
5438     }
5439     if (opc2 & 0x04) {
5440         /* (n)multiply-and-accumulate (0x0C / 0x0E) */
5441         tcg_gen_mul_tl(t1, t0, t1);
5442         if (opc2 & 0x02) {
5443             /* nmultiply-and-accumulate (0x0E) */
5444             tcg_gen_sub_tl(t0, cpu_gpr[rt], t1);
5445         } else {
5446             /* multiply-and-accumulate (0x0C) */
5447             tcg_gen_add_tl(t0, cpu_gpr[rt], t1);
5448         }
5449
5450         if (opc3 & 0x12) {
5451             /* Check overflow and/or saturate */
5452             int l1 = gen_new_label();
5453
5454             if (opc3 & 0x10) {
5455                 /* Start with XER OV disabled, the most likely case */
5456                 tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
5457             }
5458             if (opc3 & 0x01) {
5459                 /* Signed */
5460                 tcg_gen_xor_tl(t1, cpu_gpr[rt], t1);
5461                 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
5462                 tcg_gen_xor_tl(t1, cpu_gpr[rt], t0);
5463                 tcg_gen_brcondi_tl(TCG_COND_LT, t1, 0, l1);
5464                 if (opc3 & 0x02) {
5465                     /* Saturate */
5466                     tcg_gen_sari_tl(t0, cpu_gpr[rt], 31);
5467                     tcg_gen_xori_tl(t0, t0, 0x7fffffff);
5468                 }
5469             } else {
5470                 /* Unsigned */
5471                 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
5472                 if (opc3 & 0x02) {
5473                     /* Saturate */
5474                     tcg_gen_movi_tl(t0, UINT32_MAX);
5475                 }
5476             }
5477             if (opc3 & 0x10) {
5478                 /* Check overflow */
5479                 tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
5480             }
5481             gen_set_label(l1);
5482             tcg_gen_mov_tl(cpu_gpr[rt], t0);
5483         }
5484     } else {
5485         tcg_gen_mul_tl(cpu_gpr[rt], t0, t1);
5486     }
5487     tcg_temp_free(t0);
5488     tcg_temp_free(t1);
5489     if (unlikely(Rc) != 0) {
5490         /* Update Rc0 */
5491         gen_set_Rc0(ctx, cpu_gpr[rt]);
5492     }
5493 }
5494
5495 #define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
5496 GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC)                  \
5497 {                                                                             \
5498     gen_405_mulladd_insn(ctx, opc2, opc3, rA(ctx->opcode), rB(ctx->opcode),   \
5499                          rD(ctx->opcode), Rc(ctx->opcode));                   \
5500 }
5501
5502 /* macchw    - macchw.    */
5503 GEN_MAC_HANDLER(macchw, 0x0C, 0x05);
5504 /* macchwo   - macchwo.   */
5505 GEN_MAC_HANDLER(macchwo, 0x0C, 0x15);
5506 /* macchws   - macchws.   */
5507 GEN_MAC_HANDLER(macchws, 0x0C, 0x07);
5508 /* macchwso  - macchwso.  */
5509 GEN_MAC_HANDLER(macchwso, 0x0C, 0x17);
5510 /* macchwsu  - macchwsu.  */
5511 GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06);
5512 /* macchwsuo - macchwsuo. */
5513 GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16);
5514 /* macchwu   - macchwu.   */
5515 GEN_MAC_HANDLER(macchwu, 0x0C, 0x04);
5516 /* macchwuo  - macchwuo.  */
5517 GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14);
5518 /* machhw    - machhw.    */
5519 GEN_MAC_HANDLER(machhw, 0x0C, 0x01);
5520 /* machhwo   - machhwo.   */
5521 GEN_MAC_HANDLER(machhwo, 0x0C, 0x11);
5522 /* machhws   - machhws.   */
5523 GEN_MAC_HANDLER(machhws, 0x0C, 0x03);
5524 /* machhwso  - machhwso.  */
5525 GEN_MAC_HANDLER(machhwso, 0x0C, 0x13);
5526 /* machhwsu  - machhwsu.  */
5527 GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02);
5528 /* machhwsuo - machhwsuo. */
5529 GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12);
5530 /* machhwu   - machhwu.   */
5531 GEN_MAC_HANDLER(machhwu, 0x0C, 0x00);
5532 /* machhwuo  - machhwuo.  */
5533 GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10);
5534 /* maclhw    - maclhw.    */
5535 GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D);
5536 /* maclhwo   - maclhwo.   */
5537 GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D);
5538 /* maclhws   - maclhws.   */
5539 GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F);
5540 /* maclhwso  - maclhwso.  */
5541 GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F);
5542 /* maclhwu   - maclhwu.   */
5543 GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C);
5544 /* maclhwuo  - maclhwuo.  */
5545 GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C);
5546 /* maclhwsu  - maclhwsu.  */
5547 GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E);
5548 /* maclhwsuo - maclhwsuo. */
5549 GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E);
5550 /* nmacchw   - nmacchw.   */
5551 GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05);
5552 /* nmacchwo  - nmacchwo.  */
5553 GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15);
5554 /* nmacchws  - nmacchws.  */
5555 GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07);
5556 /* nmacchwso - nmacchwso. */
5557 GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17);
5558 /* nmachhw   - nmachhw.   */
5559 GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01);
5560 /* nmachhwo  - nmachhwo.  */
5561 GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11);
5562 /* nmachhws  - nmachhws.  */
5563 GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03);
5564 /* nmachhwso - nmachhwso. */
5565 GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13);
5566 /* nmaclhw   - nmaclhw.   */
5567 GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D);
5568 /* nmaclhwo  - nmaclhwo.  */
5569 GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D);
5570 /* nmaclhws  - nmaclhws.  */
5571 GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F);
5572 /* nmaclhwso - nmaclhwso. */
5573 GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F);
5574
5575 /* mulchw  - mulchw.  */
5576 GEN_MAC_HANDLER(mulchw, 0x08, 0x05);
5577 /* mulchwu - mulchwu. */
5578 GEN_MAC_HANDLER(mulchwu, 0x08, 0x04);
5579 /* mulhhw  - mulhhw.  */
5580 GEN_MAC_HANDLER(mulhhw, 0x08, 0x01);
5581 /* mulhhwu - mulhhwu. */
5582 GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00);
5583 /* mullhw  - mullhw.  */
5584 GEN_MAC_HANDLER(mullhw, 0x08, 0x0D);
5585 /* mullhwu - mullhwu. */
5586 GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C);
5587
5588 /* mfdcr */
5589 GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_DCR)
5590 {
5591 #if defined(CONFIG_USER_ONLY)
5592     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
5593 #else
5594     TCGv dcrn;
5595     if (unlikely(!ctx->mem_idx)) {
5596         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
5597         return;
5598     }
5599     /* NIP cannot be restored if the memory exception comes from an helper */
5600     gen_update_nip(ctx, ctx->nip - 4);
5601     dcrn = tcg_const_tl(SPR(ctx->opcode));
5602     gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], dcrn);
5603     tcg_temp_free(dcrn);
5604 #endif
5605 }
5606
5607 /* mtdcr */
5608 GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_DCR)
5609 {
5610 #if defined(CONFIG_USER_ONLY)
5611     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
5612 #else
5613     TCGv dcrn;
5614     if (unlikely(!ctx->mem_idx)) {
5615         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
5616         return;
5617     }
5618     /* NIP cannot be restored if the memory exception comes from an helper */
5619     gen_update_nip(ctx, ctx->nip - 4);
5620     dcrn = tcg_const_tl(SPR(ctx->opcode));
5621     gen_helper_store_dcr(dcrn, cpu_gpr[rS(ctx->opcode)]);
5622     tcg_temp_free(dcrn);
5623 #endif
5624 }
5625
5626 /* mfdcrx */
5627 /* XXX: not implemented on 440 ? */
5628 GEN_HANDLER(mfdcrx, 0x1F, 0x03, 0x08, 0x00000000, PPC_DCRX)
5629 {
5630 #if defined(CONFIG_USER_ONLY)
5631     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
5632 #else
5633     if (unlikely(!ctx->mem_idx)) {
5634         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
5635         return;
5636     }
5637     /* NIP cannot be restored if the memory exception comes from an helper */
5638     gen_update_nip(ctx, ctx->nip - 4);
5639     gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5640     /* Note: Rc update flag set leads to undefined state of Rc0 */
5641 #endif
5642 }
5643
5644 /* mtdcrx */
5645 /* XXX: not implemented on 440 ? */
5646 GEN_HANDLER(mtdcrx, 0x1F, 0x03, 0x0C, 0x00000000, PPC_DCRX)
5647 {
5648 #if defined(CONFIG_USER_ONLY)
5649     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
5650 #else
5651     if (unlikely(!ctx->mem_idx)) {
5652         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
5653         return;
5654     }
5655     /* NIP cannot be restored if the memory exception comes from an helper */
5656     gen_update_nip(ctx, ctx->nip - 4);
5657     gen_helper_store_dcr(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
5658     /* Note: Rc update flag set leads to undefined state of Rc0 */
5659 #endif
5660 }
5661
5662 /* mfdcrux (PPC 460) : user-mode access to DCR */
5663 GEN_HANDLER(mfdcrux, 0x1F, 0x03, 0x09, 0x00000000, PPC_DCRUX)
5664 {
5665     /* NIP cannot be restored if the memory exception comes from an helper */
5666     gen_update_nip(ctx, ctx->nip - 4);
5667     gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5668     /* Note: Rc update flag set leads to undefined state of Rc0 */
5669 }
5670
5671 /* mtdcrux (PPC 460) : user-mode access to DCR */
5672 GEN_HANDLER(mtdcrux, 0x1F, 0x03, 0x0D, 0x00000000, PPC_DCRUX)
5673 {
5674     /* NIP cannot be restored if the memory exception comes from an helper */
5675     gen_update_nip(ctx, ctx->nip - 4);
5676     gen_helper_store_dcr(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
5677     /* Note: Rc update flag set leads to undefined state of Rc0 */
5678 }
5679
5680 /* dccci */
5681 GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON)
5682 {
5683 #if defined(CONFIG_USER_ONLY)
5684     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5685 #else
5686     if (unlikely(!ctx->mem_idx)) {
5687         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5688         return;
5689     }
5690     /* interpreted as no-op */
5691 #endif
5692 }
5693
5694 /* dcread */
5695 GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON)
5696 {
5697 #if defined(CONFIG_USER_ONLY)
5698     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5699 #else
5700     TCGv EA, val;
5701     if (unlikely(!ctx->mem_idx)) {
5702         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5703         return;
5704     }
5705     gen_set_access_type(ctx, ACCESS_CACHE);
5706     EA = tcg_temp_new();
5707     gen_addr_reg_index(ctx, EA);
5708     val = tcg_temp_new();
5709     gen_qemu_ld32u(ctx, val, EA);
5710     tcg_temp_free(val);
5711     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], EA);
5712     tcg_temp_free(EA);
5713 #endif
5714 }
5715
5716 /* icbt */
5717 GEN_HANDLER2(icbt_40x, "icbt", 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_ICBT)
5718 {
5719     /* interpreted as no-op */
5720     /* XXX: specification say this is treated as a load by the MMU
5721      *      but does not generate any exception
5722      */
5723 }
5724
5725 /* iccci */
5726 GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON)
5727 {
5728 #if defined(CONFIG_USER_ONLY)
5729     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5730 #else
5731     if (unlikely(!ctx->mem_idx)) {
5732         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5733         return;
5734     }
5735     /* interpreted as no-op */
5736 #endif
5737 }
5738
5739 /* icread */
5740 GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON)
5741 {
5742 #if defined(CONFIG_USER_ONLY)
5743     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5744 #else
5745     if (unlikely(!ctx->mem_idx)) {
5746         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5747         return;
5748     }
5749     /* interpreted as no-op */
5750 #endif
5751 }
5752
5753 /* rfci (mem_idx only) */
5754 GEN_HANDLER2(rfci_40x, "rfci", 0x13, 0x13, 0x01, 0x03FF8001, PPC_40x_EXCP)
5755 {
5756 #if defined(CONFIG_USER_ONLY)
5757     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5758 #else
5759     if (unlikely(!ctx->mem_idx)) {
5760         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5761         return;
5762     }
5763     /* Restore CPU state */
5764     gen_helper_40x_rfci();
5765     gen_sync_exception(ctx);
5766 #endif
5767 }
5768
5769 GEN_HANDLER(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE)
5770 {
5771 #if defined(CONFIG_USER_ONLY)
5772     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5773 #else
5774     if (unlikely(!ctx->mem_idx)) {
5775         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5776         return;
5777     }
5778     /* Restore CPU state */
5779     gen_helper_rfci();
5780     gen_sync_exception(ctx);
5781 #endif
5782 }
5783
5784 /* BookE specific */
5785 /* XXX: not implemented on 440 ? */
5786 GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_RFDI)
5787 {
5788 #if defined(CONFIG_USER_ONLY)
5789     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5790 #else
5791     if (unlikely(!ctx->mem_idx)) {
5792         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5793         return;
5794     }
5795     /* Restore CPU state */
5796     gen_helper_rfdi();
5797     gen_sync_exception(ctx);
5798 #endif
5799 }
5800
5801 /* XXX: not implemented on 440 ? */
5802 GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_RFMCI)
5803 {
5804 #if defined(CONFIG_USER_ONLY)
5805     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5806 #else
5807     if (unlikely(!ctx->mem_idx)) {
5808         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5809         return;
5810     }
5811     /* Restore CPU state */
5812     gen_helper_rfmci();
5813     gen_sync_exception(ctx);
5814 #endif
5815 }
5816
5817 /* TLB management - PowerPC 405 implementation */
5818 /* tlbre */
5819 GEN_HANDLER2(tlbre_40x, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB)
5820 {
5821 #if defined(CONFIG_USER_ONLY)
5822     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5823 #else
5824     if (unlikely(!ctx->mem_idx)) {
5825         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5826         return;
5827     }
5828     switch (rB(ctx->opcode)) {
5829     case 0:
5830         gen_helper_4xx_tlbre_hi(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5831         break;
5832     case 1:
5833         gen_helper_4xx_tlbre_lo(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5834         break;
5835     default:
5836         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5837         break;
5838     }
5839 #endif
5840 }
5841
5842 /* tlbsx - tlbsx. */
5843 GEN_HANDLER2(tlbsx_40x, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB)
5844 {
5845 #if defined(CONFIG_USER_ONLY)
5846     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5847 #else
5848     TCGv t0;
5849     if (unlikely(!ctx->mem_idx)) {
5850         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5851         return;
5852     }
5853     t0 = tcg_temp_new();
5854     gen_addr_reg_index(ctx, t0);
5855     gen_helper_4xx_tlbsx(cpu_gpr[rD(ctx->opcode)], t0);
5856     tcg_temp_free(t0);
5857     if (Rc(ctx->opcode)) {
5858         int l1 = gen_new_label();
5859         tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_xer);
5860         tcg_gen_shri_i32(cpu_crf[0], cpu_crf[0], XER_SO);
5861         tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 1);
5862         tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rD(ctx->opcode)], -1, l1);
5863         tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
5864         gen_set_label(l1);
5865     }
5866 #endif
5867 }
5868
5869 /* tlbwe */
5870 GEN_HANDLER2(tlbwe_40x, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB)
5871 {
5872 #if defined(CONFIG_USER_ONLY)
5873     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5874 #else
5875     if (unlikely(!ctx->mem_idx)) {
5876         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5877         return;
5878     }
5879     switch (rB(ctx->opcode)) {
5880     case 0:
5881         gen_helper_4xx_tlbwe_hi(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
5882         break;
5883     case 1:
5884         gen_helper_4xx_tlbwe_lo(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
5885         break;
5886     default:
5887         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5888         break;
5889     }
5890 #endif
5891 }
5892
5893 /* TLB management - PowerPC 440 implementation */
5894 /* tlbre */
5895 GEN_HANDLER2(tlbre_440, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE)
5896 {
5897 #if defined(CONFIG_USER_ONLY)
5898     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5899 #else
5900     if (unlikely(!ctx->mem_idx)) {
5901         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5902         return;
5903     }
5904     switch (rB(ctx->opcode)) {
5905     case 0:
5906     case 1:
5907     case 2:
5908         {
5909             TCGv_i32 t0 = tcg_const_i32(rB(ctx->opcode));
5910             gen_helper_440_tlbwe(t0, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5911             tcg_temp_free_i32(t0);
5912         }
5913         break;
5914     default:
5915         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5916         break;
5917     }
5918 #endif
5919 }
5920
5921 /* tlbsx - tlbsx. */
5922 GEN_HANDLER2(tlbsx_440, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE)
5923 {
5924 #if defined(CONFIG_USER_ONLY)
5925     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5926 #else
5927     TCGv t0;
5928     if (unlikely(!ctx->mem_idx)) {
5929         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5930         return;
5931     }
5932     t0 = tcg_temp_new();
5933     gen_addr_reg_index(ctx, t0);
5934     gen_helper_440_tlbsx(cpu_gpr[rD(ctx->opcode)], t0);
5935     tcg_temp_free(t0);
5936     if (Rc(ctx->opcode)) {
5937         int l1 = gen_new_label();
5938         tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_xer);
5939         tcg_gen_shri_i32(cpu_crf[0], cpu_crf[0], XER_SO);
5940         tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 1);
5941         tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rD(ctx->opcode)], -1, l1);
5942         tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
5943         gen_set_label(l1);
5944     }
5945 #endif
5946 }
5947
5948 /* tlbwe */
5949 GEN_HANDLER2(tlbwe_440, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE)
5950 {
5951 #if defined(CONFIG_USER_ONLY)
5952     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5953 #else
5954     if (unlikely(!ctx->mem_idx)) {
5955         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5956         return;
5957     }
5958     switch (rB(ctx->opcode)) {
5959     case 0:
5960     case 1:
5961     case 2:
5962         {
5963             TCGv_i32 t0 = tcg_const_i32(rB(ctx->opcode));
5964             gen_helper_440_tlbwe(t0, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
5965             tcg_temp_free_i32(t0);
5966         }
5967         break;
5968     default:
5969         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5970         break;
5971     }
5972 #endif
5973 }
5974
5975 /* wrtee */
5976 GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE)
5977 {
5978 #if defined(CONFIG_USER_ONLY)
5979     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5980 #else
5981     TCGv t0;
5982     if (unlikely(!ctx->mem_idx)) {
5983         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5984         return;
5985     }
5986     t0 = tcg_temp_new();
5987     tcg_gen_andi_tl(t0, cpu_gpr[rD(ctx->opcode)], (1 << MSR_EE));
5988     tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE));
5989     tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
5990     tcg_temp_free(t0);
5991     /* Stop translation to have a chance to raise an exception
5992      * if we just set msr_ee to 1
5993      */
5994     gen_stop_exception(ctx);
5995 #endif
5996 }
5997
5998 /* wrteei */
5999 GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000EFC01, PPC_WRTEE)
6000 {
6001 #if defined(CONFIG_USER_ONLY)
6002     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6003 #else
6004     if (unlikely(!ctx->mem_idx)) {
6005         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
6006         return;
6007     }
6008     if (ctx->opcode & 0x00010000) {
6009         tcg_gen_ori_tl(cpu_msr, cpu_msr, (1 << MSR_EE));
6010         /* Stop translation to have a chance to raise an exception */
6011         gen_stop_exception(ctx);
6012     } else {
6013         tcg_gen_andi_tl(cpu_msr, cpu_msr, (1 << MSR_EE));
6014     }
6015 #endif
6016 }
6017
6018 /* PowerPC 440 specific instructions */
6019 /* dlmzb */
6020 GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC)
6021 {
6022     TCGv_i32 t0 = tcg_const_i32(Rc(ctx->opcode));
6023     gen_helper_dlmzb(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)],
6024                      cpu_gpr[rB(ctx->opcode)], t0);
6025     tcg_temp_free_i32(t0);
6026 }
6027
6028 /* mbar replaces eieio on 440 */
6029 GEN_HANDLER(mbar, 0x1F, 0x16, 0x1a, 0x001FF801, PPC_BOOKE)
6030 {
6031     /* interpreted as no-op */
6032 }
6033
6034 /* msync replaces sync on 440 */
6035 GEN_HANDLER(msync, 0x1F, 0x16, 0x12, 0x03FFF801, PPC_BOOKE)
6036 {
6037     /* interpreted as no-op */
6038 }
6039
6040 /* icbt */
6041 GEN_HANDLER2(icbt_440, "icbt", 0x1F, 0x16, 0x00, 0x03E00001, PPC_BOOKE)
6042 {
6043     /* interpreted as no-op */
6044     /* XXX: specification say this is treated as a load by the MMU
6045      *      but does not generate any exception
6046      */
6047 }
6048
6049 /***                      Altivec vector extension                         ***/
6050 /* Altivec registers moves */
6051
6052 #define GEN_VR_LDX(name, opc2, opc3)                                          \
6053 GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)                  \
6054 {                                                                             \
6055     TCGv EA;                                                                  \
6056     if (unlikely(!ctx->altivec_enabled)) {                                    \
6057         gen_exception(ctx, POWERPC_EXCP_VPU);                                 \
6058         return;                                                               \
6059     }                                                                         \
6060     gen_set_access_type(ctx, ACCESS_INT);                                     \
6061     EA = tcg_temp_new();                                                      \
6062     gen_addr_reg_index(ctx, EA);                                              \
6063     tcg_gen_andi_tl(EA, EA, ~0xf);                                            \
6064     if (ctx->le_mode) {                                                       \
6065         gen_qemu_ld64(ctx, cpu_avrl[rD(ctx->opcode)], EA);                    \
6066         tcg_gen_addi_tl(EA, EA, 8);                                           \
6067         gen_qemu_ld64(ctx, cpu_avrh[rD(ctx->opcode)], EA);                    \
6068     } else {                                                                  \
6069         gen_qemu_ld64(ctx, cpu_avrh[rD(ctx->opcode)], EA);                    \
6070         tcg_gen_addi_tl(EA, EA, 8);                                           \
6071         gen_qemu_ld64(ctx, cpu_avrl[rD(ctx->opcode)], EA);                    \
6072     }                                                                         \
6073     tcg_temp_free(EA);                                                        \
6074 }
6075
6076 #define GEN_VR_STX(name, opc2, opc3)                                          \
6077 GEN_HANDLER(st##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)              \
6078 {                                                                             \
6079     TCGv EA;                                                                  \
6080     if (unlikely(!ctx->altivec_enabled)) {                                    \
6081         gen_exception(ctx, POWERPC_EXCP_VPU);                                 \
6082         return;                                                               \
6083     }                                                                         \
6084     gen_set_access_type(ctx, ACCESS_INT);                                     \
6085     EA = tcg_temp_new();                                                      \
6086     gen_addr_reg_index(ctx, EA);                                              \
6087     tcg_gen_andi_tl(EA, EA, ~0xf);                                            \
6088     if (ctx->le_mode) {                                                       \
6089         gen_qemu_st64(ctx, cpu_avrl[rD(ctx->opcode)], EA);                    \
6090         tcg_gen_addi_tl(EA, EA, 8);                                           \
6091         gen_qemu_st64(ctx, cpu_avrh[rD(ctx->opcode)], EA);                    \
6092     } else {                                                                  \
6093         gen_qemu_st64(ctx, cpu_avrh[rD(ctx->opcode)], EA);                    \
6094         tcg_gen_addi_tl(EA, EA, 8);                                           \
6095         gen_qemu_st64(ctx, cpu_avrl[rD(ctx->opcode)], EA);                    \
6096     }                                                                         \
6097     tcg_temp_free(EA);                                                        \
6098 }
6099
6100 GEN_VR_LDX(lvx, 0x07, 0x03);
6101 /* As we don't emulate the cache, lvxl is stricly equivalent to lvx */
6102 GEN_VR_LDX(lvxl, 0x07, 0x0B);
6103
6104 GEN_VR_STX(svx, 0x07, 0x07);
6105 /* As we don't emulate the cache, stvxl is stricly equivalent to stvx */
6106 GEN_VR_STX(svxl, 0x07, 0x0F);
6107
6108 /***                           SPE extension                               ***/
6109 /* Register moves */
6110
6111 static always_inline void gen_load_gpr64(TCGv_i64 t, int reg) {
6112 #if defined(TARGET_PPC64)
6113     tcg_gen_mov_i64(t, cpu_gpr[reg]);
6114 #else
6115     tcg_gen_concat_i32_i64(t, cpu_gpr[reg], cpu_gprh[reg]);
6116 #endif
6117 }
6118
6119 static always_inline void gen_store_gpr64(int reg, TCGv_i64 t) {
6120 #if defined(TARGET_PPC64)
6121     tcg_gen_mov_i64(cpu_gpr[reg], t);
6122 #else
6123     TCGv_i64 tmp = tcg_temp_new_i64();
6124     tcg_gen_trunc_i64_i32(cpu_gpr[reg], t);
6125     tcg_gen_shri_i64(tmp, t, 32);
6126     tcg_gen_trunc_i64_i32(cpu_gprh[reg], tmp);
6127     tcg_temp_free_i64(tmp);
6128 #endif
6129 }
6130
6131 #define GEN_SPE(name0, name1, opc2, opc3, inval, type)                        \
6132 GEN_HANDLER(name0##_##name1, 0x04, opc2, opc3, inval, type)                   \
6133 {                                                                             \
6134     if (Rc(ctx->opcode))                                                      \
6135         gen_##name1(ctx);                                                     \
6136     else                                                                      \
6137         gen_##name0(ctx);                                                     \
6138 }
6139
6140 /* Handler for undefined SPE opcodes */
6141 static always_inline void gen_speundef (DisasContext *ctx)
6142 {
6143     gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
6144 }
6145
6146 /* SPE logic */
6147 #if defined(TARGET_PPC64)
6148 #define GEN_SPEOP_LOGIC2(name, tcg_op)                                        \
6149 static always_inline void gen_##name (DisasContext *ctx)                      \
6150 {                                                                             \
6151     if (unlikely(!ctx->spe_enabled)) {                                        \
6152         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6153         return;                                                               \
6154     }                                                                         \
6155     tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],                \
6156            cpu_gpr[rB(ctx->opcode)]);                                         \
6157 }
6158 #else
6159 #define GEN_SPEOP_LOGIC2(name, tcg_op)                                        \
6160 static always_inline void gen_##name (DisasContext *ctx)                      \
6161 {                                                                             \
6162     if (unlikely(!ctx->spe_enabled)) {                                        \
6163         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6164         return;                                                               \
6165     }                                                                         \
6166     tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],                \
6167            cpu_gpr[rB(ctx->opcode)]);                                         \
6168     tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],              \
6169            cpu_gprh[rB(ctx->opcode)]);                                        \
6170 }
6171 #endif
6172
6173 GEN_SPEOP_LOGIC2(evand, tcg_gen_and_tl);
6174 GEN_SPEOP_LOGIC2(evandc, tcg_gen_andc_tl);
6175 GEN_SPEOP_LOGIC2(evxor, tcg_gen_xor_tl);
6176 GEN_SPEOP_LOGIC2(evor, tcg_gen_or_tl);
6177 GEN_SPEOP_LOGIC2(evnor, tcg_gen_nor_tl);
6178 GEN_SPEOP_LOGIC2(eveqv, tcg_gen_eqv_tl);
6179 GEN_SPEOP_LOGIC2(evorc, tcg_gen_orc_tl);
6180 GEN_SPEOP_LOGIC2(evnand, tcg_gen_nand_tl);
6181
6182 /* SPE logic immediate */
6183 #if defined(TARGET_PPC64)
6184 #define GEN_SPEOP_TCG_LOGIC_IMM2(name, tcg_opi)                               \
6185 static always_inline void gen_##name (DisasContext *ctx)                      \
6186 {                                                                             \
6187     if (unlikely(!ctx->spe_enabled)) {                                        \
6188         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6189         return;                                                               \
6190     }                                                                         \
6191     TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
6192     TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
6193     TCGv_i64 t2 = tcg_temp_local_new_i64();                                   \
6194     tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]);                      \
6195     tcg_opi(t0, t0, rB(ctx->opcode));                                         \
6196     tcg_gen_shri_i64(t2, cpu_gpr[rA(ctx->opcode)], 32);                       \
6197     tcg_gen_trunc_i64_i32(t1, t2);                                            \
6198     tcg_temp_free_i64(t2);                                                    \
6199     tcg_opi(t1, t1, rB(ctx->opcode));                                         \
6200     tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);                 \
6201     tcg_temp_free_i32(t0);                                                    \
6202     tcg_temp_free_i32(t1);                                                    \
6203 }
6204 #else
6205 #define GEN_SPEOP_TCG_LOGIC_IMM2(name, tcg_opi)                               \
6206 static always_inline void gen_##name (DisasContext *ctx)                      \
6207 {                                                                             \
6208     if (unlikely(!ctx->spe_enabled)) {                                        \
6209         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6210         return;                                                               \
6211     }                                                                         \
6212     tcg_opi(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],               \
6213             rB(ctx->opcode));                                                 \
6214     tcg_opi(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],             \
6215             rB(ctx->opcode));                                                 \
6216 }
6217 #endif
6218 GEN_SPEOP_TCG_LOGIC_IMM2(evslwi, tcg_gen_shli_i32);
6219 GEN_SPEOP_TCG_LOGIC_IMM2(evsrwiu, tcg_gen_shri_i32);
6220 GEN_SPEOP_TCG_LOGIC_IMM2(evsrwis, tcg_gen_sari_i32);
6221 GEN_SPEOP_TCG_LOGIC_IMM2(evrlwi, tcg_gen_rotli_i32);
6222
6223 /* SPE arithmetic */
6224 #if defined(TARGET_PPC64)
6225 #define GEN_SPEOP_ARITH1(name, tcg_op)                                        \
6226 static always_inline void gen_##name (DisasContext *ctx)                      \
6227 {                                                                             \
6228     if (unlikely(!ctx->spe_enabled)) {                                        \
6229         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6230         return;                                                               \
6231     }                                                                         \
6232     TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
6233     TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
6234     TCGv_i64 t2 = tcg_temp_local_new_i64();                                   \
6235     tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]);                      \
6236     tcg_op(t0, t0);                                                           \
6237     tcg_gen_shri_i64(t2, cpu_gpr[rA(ctx->opcode)], 32);                       \
6238     tcg_gen_trunc_i64_i32(t1, t2);                                            \
6239     tcg_temp_free_i64(t2);                                                    \
6240     tcg_op(t1, t1);                                                           \
6241     tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);                 \
6242     tcg_temp_free_i32(t0);                                                    \
6243     tcg_temp_free_i32(t1);                                                    \
6244 }
6245 #else
6246 #define GEN_SPEOP_ARITH1(name, tcg_op)                                        \
6247 static always_inline void gen_##name (DisasContext *ctx)                      \
6248 {                                                                             \
6249     if (unlikely(!ctx->spe_enabled)) {                                        \
6250         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6251         return;                                                               \
6252     }                                                                         \
6253     tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);               \
6254     tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);             \
6255 }
6256 #endif
6257
6258 static always_inline void gen_op_evabs (TCGv_i32 ret, TCGv_i32 arg1)
6259 {
6260     int l1 = gen_new_label();
6261     int l2 = gen_new_label();
6262
6263     tcg_gen_brcondi_i32(TCG_COND_GE, arg1, 0, l1);
6264     tcg_gen_neg_i32(ret, arg1);
6265     tcg_gen_br(l2);
6266     gen_set_label(l1);
6267     tcg_gen_mov_i32(ret, arg1);
6268     gen_set_label(l2);
6269 }
6270 GEN_SPEOP_ARITH1(evabs, gen_op_evabs);
6271 GEN_SPEOP_ARITH1(evneg, tcg_gen_neg_i32);
6272 GEN_SPEOP_ARITH1(evextsb, tcg_gen_ext8s_i32);
6273 GEN_SPEOP_ARITH1(evextsh, tcg_gen_ext16s_i32);
6274 static always_inline void gen_op_evrndw (TCGv_i32 ret, TCGv_i32 arg1)
6275 {
6276     tcg_gen_addi_i32(ret, arg1, 0x8000);
6277     tcg_gen_ext16u_i32(ret, ret);
6278 }
6279 GEN_SPEOP_ARITH1(evrndw, gen_op_evrndw);
6280 GEN_SPEOP_ARITH1(evcntlsw, gen_helper_cntlsw32);
6281 GEN_SPEOP_ARITH1(evcntlzw, gen_helper_cntlzw32);
6282
6283 #if defined(TARGET_PPC64)
6284 #define GEN_SPEOP_ARITH2(name, tcg_op)                                        \
6285 static always_inline void gen_##name (DisasContext *ctx)                      \
6286 {                                                                             \
6287     if (unlikely(!ctx->spe_enabled)) {                                        \
6288         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6289         return;                                                               \
6290     }                                                                         \
6291     TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
6292     TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
6293     TCGv_i32 t2 = tcg_temp_local_new_i32();                                   \
6294     TCGv_i64 t3 = tcg_temp_local_new(TCG_TYPE_I64);                           \
6295     tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]);                      \
6296     tcg_gen_trunc_i64_i32(t2, cpu_gpr[rB(ctx->opcode)]);                      \
6297     tcg_op(t0, t0, t2);                                                       \
6298     tcg_gen_shri_i64(t3, cpu_gpr[rA(ctx->opcode)], 32);                       \
6299     tcg_gen_trunc_i64_i32(t1, t3);                                            \
6300     tcg_gen_shri_i64(t3, cpu_gpr[rB(ctx->opcode)], 32);                       \
6301     tcg_gen_trunc_i64_i32(t2, t3);                                            \
6302     tcg_temp_free_i64(t3);                                                    \
6303     tcg_op(t1, t1, t2);                                                       \
6304     tcg_temp_free_i32(t2);                                                    \
6305     tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);                 \
6306     tcg_temp_free_i32(t0);                                                    \
6307     tcg_temp_free_i32(t1);                                                    \
6308 }
6309 #else
6310 #define GEN_SPEOP_ARITH2(name, tcg_op)                                        \
6311 static always_inline void gen_##name (DisasContext *ctx)                      \
6312 {                                                                             \
6313     if (unlikely(!ctx->spe_enabled)) {                                        \
6314         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6315         return;                                                               \
6316     }                                                                         \
6317     tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],                \
6318            cpu_gpr[rB(ctx->opcode)]);                                         \
6319     tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],              \
6320            cpu_gprh[rB(ctx->opcode)]);                                        \
6321 }
6322 #endif
6323
6324 static always_inline void gen_op_evsrwu (TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
6325 {
6326     TCGv_i32 t0;
6327     int l1, l2;
6328
6329     l1 = gen_new_label();
6330     l2 = gen_new_label();
6331     t0 = tcg_temp_local_new_i32();
6332     /* No error here: 6 bits are used */
6333     tcg_gen_andi_i32(t0, arg2, 0x3F);
6334     tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1);
6335     tcg_gen_shr_i32(ret, arg1, t0);
6336     tcg_gen_br(l2);
6337     gen_set_label(l1);
6338     tcg_gen_movi_i32(ret, 0);
6339     tcg_gen_br(l2);
6340     tcg_temp_free_i32(t0);
6341 }
6342 GEN_SPEOP_ARITH2(evsrwu, gen_op_evsrwu);
6343 static always_inline void gen_op_evsrws (TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
6344 {
6345     TCGv_i32 t0;
6346     int l1, l2;
6347
6348     l1 = gen_new_label();
6349     l2 = gen_new_label();
6350     t0 = tcg_temp_local_new_i32();
6351     /* No error here: 6 bits are used */
6352     tcg_gen_andi_i32(t0, arg2, 0x3F);
6353     tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1);
6354     tcg_gen_sar_i32(ret, arg1, t0);
6355     tcg_gen_br(l2);
6356     gen_set_label(l1);
6357     tcg_gen_movi_i32(ret, 0);
6358     tcg_gen_br(l2);
6359     tcg_temp_free_i32(t0);
6360 }
6361 GEN_SPEOP_ARITH2(evsrws, gen_op_evsrws);
6362 static always_inline void gen_op_evslw (TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
6363 {
6364     TCGv_i32 t0;
6365     int l1, l2;
6366
6367     l1 = gen_new_label();
6368     l2 = gen_new_label();
6369     t0 = tcg_temp_local_new_i32();
6370     /* No error here: 6 bits are used */
6371     tcg_gen_andi_i32(t0, arg2, 0x3F);
6372     tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1);
6373     tcg_gen_shl_i32(ret, arg1, t0);
6374     tcg_gen_br(l2);
6375     gen_set_label(l1);
6376     tcg_gen_movi_i32(ret, 0);
6377     tcg_gen_br(l2);
6378     tcg_temp_free_i32(t0);
6379 }
6380 GEN_SPEOP_ARITH2(evslw, gen_op_evslw);
6381 static always_inline void gen_op_evrlw (TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
6382 {
6383     TCGv_i32 t0 = tcg_temp_new_i32();
6384     tcg_gen_andi_i32(t0, arg2, 0x1F);
6385     tcg_gen_rotl_i32(ret, arg1, t0);
6386     tcg_temp_free_i32(t0);
6387 }
6388 GEN_SPEOP_ARITH2(evrlw, gen_op_evrlw);
6389 static always_inline void gen_evmergehi (DisasContext *ctx)
6390 {
6391     if (unlikely(!ctx->spe_enabled)) {
6392         gen_exception(ctx, POWERPC_EXCP_APU);
6393         return;
6394     }
6395 #if defined(TARGET_PPC64)
6396     TCGv t0 = tcg_temp_new();
6397     TCGv t1 = tcg_temp_new();
6398     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 32);
6399     tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], 0xFFFFFFFF0000000ULL);
6400     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
6401     tcg_temp_free(t0);
6402     tcg_temp_free(t1);
6403 #else
6404     tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
6405     tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
6406 #endif
6407 }
6408 GEN_SPEOP_ARITH2(evaddw, tcg_gen_add_i32);
6409 static always_inline void gen_op_evsubf (TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
6410 {
6411     tcg_gen_sub_i32(ret, arg2, arg1);
6412 }
6413 GEN_SPEOP_ARITH2(evsubfw, gen_op_evsubf);
6414
6415 /* SPE arithmetic immediate */
6416 #if defined(TARGET_PPC64)
6417 #define GEN_SPEOP_ARITH_IMM2(name, tcg_op)                                    \
6418 static always_inline void gen_##name (DisasContext *ctx)                      \
6419 {                                                                             \
6420     if (unlikely(!ctx->spe_enabled)) {                                        \
6421         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6422         return;                                                               \
6423     }                                                                         \
6424     TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
6425     TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
6426     TCGv_i64 t2 = tcg_temp_local_new_i64();                                   \
6427     tcg_gen_trunc_i64_i32(t0, cpu_gpr[rB(ctx->opcode)]);                      \
6428     tcg_op(t0, t0, rA(ctx->opcode));                                          \
6429     tcg_gen_shri_i64(t2, cpu_gpr[rB(ctx->opcode)], 32);                       \
6430     tcg_gen_trunc_i64_i32(t1, t2);                                            \
6431     tcg_temp_free_i64(t2);                                                    \
6432     tcg_op(t1, t1, rA(ctx->opcode));                                          \
6433     tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);                 \
6434     tcg_temp_free_i32(t0);                                                    \
6435     tcg_temp_free_i32(t1);                                                    \
6436 }
6437 #else
6438 #define GEN_SPEOP_ARITH_IMM2(name, tcg_op)                                    \
6439 static always_inline void gen_##name (DisasContext *ctx)                      \
6440 {                                                                             \
6441     if (unlikely(!ctx->spe_enabled)) {                                        \
6442         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6443         return;                                                               \
6444     }                                                                         \
6445     tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],                \
6446            rA(ctx->opcode));                                                  \
6447     tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)],              \
6448            rA(ctx->opcode));                                                  \
6449 }
6450 #endif
6451 GEN_SPEOP_ARITH_IMM2(evaddiw, tcg_gen_addi_i32);
6452 GEN_SPEOP_ARITH_IMM2(evsubifw, tcg_gen_subi_i32);
6453
6454 /* SPE comparison */
6455 #if defined(TARGET_PPC64)
6456 #define GEN_SPEOP_COMP(name, tcg_cond)                                        \
6457 static always_inline void gen_##name (DisasContext *ctx)                      \
6458 {                                                                             \
6459     if (unlikely(!ctx->spe_enabled)) {                                        \
6460         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6461         return;                                                               \
6462     }                                                                         \
6463     int l1 = gen_new_label();                                                 \
6464     int l2 = gen_new_label();                                                 \
6465     int l3 = gen_new_label();                                                 \
6466     int l4 = gen_new_label();                                                 \
6467     TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
6468     TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
6469     TCGv_i64 t2 = tcg_temp_local_new_i64();                                   \
6470     tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]);                      \
6471     tcg_gen_trunc_i64_i32(t1, cpu_gpr[rB(ctx->opcode)]);                      \
6472     tcg_gen_brcond_i32(tcg_cond, t0, t1, l1);                                 \
6473     tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)], 0);                          \
6474     tcg_gen_br(l2);                                                           \
6475     gen_set_label(l1);                                                        \
6476     tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)],                              \
6477                      CRF_CL | CRF_CH_OR_CL | CRF_CH_AND_CL);                  \
6478     gen_set_label(l2);                                                        \
6479     tcg_gen_shri_i64(t2, cpu_gpr[rA(ctx->opcode)], 32);                       \
6480     tcg_gen_trunc_i64_i32(t0, t2);                                            \
6481     tcg_gen_shri_i64(t2, cpu_gpr[rB(ctx->opcode)], 32);                       \
6482     tcg_gen_trunc_i64_i32(t1, t2);                                            \
6483     tcg_temp_free_i64(t2);                                                    \
6484     tcg_gen_brcond_i32(tcg_cond, t0, t1, l3);                                 \
6485     tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)],  \
6486                      ~(CRF_CH | CRF_CH_AND_CL));                              \
6487     tcg_gen_br(l4);                                                           \
6488     gen_set_label(l3);                                                        \
6489     tcg_gen_ori_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)],   \
6490                     CRF_CH | CRF_CH_OR_CL);                                   \
6491     gen_set_label(l4);                                                        \
6492     tcg_temp_free_i32(t0);                                                    \
6493     tcg_temp_free_i32(t1);                                                    \
6494 }
6495 #else
6496 #define GEN_SPEOP_COMP(name, tcg_cond)                                        \
6497 static always_inline void gen_##name (DisasContext *ctx)                      \
6498 {                                                                             \
6499     if (unlikely(!ctx->spe_enabled)) {                                        \
6500         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6501         return;                                                               \
6502     }                                                                         \
6503     int l1 = gen_new_label();                                                 \
6504     int l2 = gen_new_label();                                                 \
6505     int l3 = gen_new_label();                                                 \
6506     int l4 = gen_new_label();                                                 \
6507                                                                               \
6508     tcg_gen_brcond_i32(tcg_cond, cpu_gpr[rA(ctx->opcode)],                    \
6509                        cpu_gpr[rB(ctx->opcode)], l1);                         \
6510     tcg_gen_movi_tl(cpu_crf[crfD(ctx->opcode)], 0);                           \
6511     tcg_gen_br(l2);                                                           \
6512     gen_set_label(l1);                                                        \
6513     tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)],                              \
6514                      CRF_CL | CRF_CH_OR_CL | CRF_CH_AND_CL);                  \
6515     gen_set_label(l2);                                                        \
6516     tcg_gen_brcond_i32(tcg_cond, cpu_gprh[rA(ctx->opcode)],                   \
6517                        cpu_gprh[rB(ctx->opcode)], l3);                        \
6518     tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)],  \
6519                      ~(CRF_CH | CRF_CH_AND_CL));                              \
6520     tcg_gen_br(l4);                                                           \
6521     gen_set_label(l3);                                                        \
6522     tcg_gen_ori_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)],   \
6523                     CRF_CH | CRF_CH_OR_CL);                                   \
6524     gen_set_label(l4);                                                        \
6525 }
6526 #endif
6527 GEN_SPEOP_COMP(evcmpgtu, TCG_COND_GTU);
6528 GEN_SPEOP_COMP(evcmpgts, TCG_COND_GT);
6529 GEN_SPEOP_COMP(evcmpltu, TCG_COND_LTU);
6530 GEN_SPEOP_COMP(evcmplts, TCG_COND_LT);
6531 GEN_SPEOP_COMP(evcmpeq, TCG_COND_EQ);
6532
6533 /* SPE misc */
6534 static always_inline void gen_brinc (DisasContext *ctx)
6535 {
6536     /* Note: brinc is usable even if SPE is disabled */
6537     gen_helper_brinc(cpu_gpr[rD(ctx->opcode)],
6538                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
6539 }
6540 static always_inline void gen_evmergelo (DisasContext *ctx)
6541 {
6542     if (unlikely(!ctx->spe_enabled)) {
6543         gen_exception(ctx, POWERPC_EXCP_APU);
6544         return;
6545     }
6546 #if defined(TARGET_PPC64)
6547     TCGv t0 = tcg_temp_new();
6548     TCGv t1 = tcg_temp_new();
6549     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x00000000FFFFFFFFLL);
6550     tcg_gen_shli_tl(t1, cpu_gpr[rA(ctx->opcode)], 32);
6551     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
6552     tcg_temp_free(t0);
6553     tcg_temp_free(t1);
6554 #else
6555     tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
6556     tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
6557 #endif
6558 }
6559 static always_inline void gen_evmergehilo (DisasContext *ctx)
6560 {
6561     if (unlikely(!ctx->spe_enabled)) {
6562         gen_exception(ctx, POWERPC_EXCP_APU);
6563         return;
6564     }
6565 #if defined(TARGET_PPC64)
6566     TCGv t0 = tcg_temp_new();
6567     TCGv t1 = tcg_temp_new();
6568     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x00000000FFFFFFFFLL);
6569     tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], 0xFFFFFFFF0000000ULL);
6570     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
6571     tcg_temp_free(t0);
6572     tcg_temp_free(t1);
6573 #else
6574     tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
6575     tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
6576 #endif
6577 }
6578 static always_inline void gen_evmergelohi (DisasContext *ctx)
6579 {
6580     if (unlikely(!ctx->spe_enabled)) {
6581         gen_exception(ctx, POWERPC_EXCP_APU);
6582         return;
6583     }
6584 #if defined(TARGET_PPC64)
6585     TCGv t0 = tcg_temp_new();
6586     TCGv t1 = tcg_temp_new();
6587     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 32);
6588     tcg_gen_shli_tl(t1, cpu_gpr[rA(ctx->opcode)], 32);
6589     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
6590     tcg_temp_free(t0);
6591     tcg_temp_free(t1);
6592 #else
6593     tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
6594     tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
6595 #endif
6596 }
6597 static always_inline void gen_evsplati (DisasContext *ctx)
6598 {
6599     uint64_t imm = ((int32_t)(rA(ctx->opcode) << 11)) >> 27;
6600
6601 #if defined(TARGET_PPC64)
6602     tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], (imm << 32) | imm);
6603 #else
6604     tcg_gen_movi_i32(cpu_gpr[rD(ctx->opcode)], imm);
6605     tcg_gen_movi_i32(cpu_gprh[rD(ctx->opcode)], imm);
6606 #endif
6607 }
6608 static always_inline void gen_evsplatfi (DisasContext *ctx)
6609 {
6610     uint64_t imm = rA(ctx->opcode) << 11;
6611
6612 #if defined(TARGET_PPC64)
6613     tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], (imm << 32) | imm);
6614 #else
6615     tcg_gen_movi_i32(cpu_gpr[rD(ctx->opcode)], imm);
6616     tcg_gen_movi_i32(cpu_gprh[rD(ctx->opcode)], imm);
6617 #endif
6618 }
6619
6620 static always_inline void gen_evsel (DisasContext *ctx)
6621 {
6622     int l1 = gen_new_label();
6623     int l2 = gen_new_label();
6624     int l3 = gen_new_label();
6625     int l4 = gen_new_label();
6626     TCGv_i32 t0 = tcg_temp_local_new_i32();
6627 #if defined(TARGET_PPC64)
6628     TCGv t1 = tcg_temp_local_new();
6629     TCGv t2 = tcg_temp_local_new();
6630 #endif
6631     tcg_gen_andi_i32(t0, cpu_crf[ctx->opcode & 0x07], 1 << 3);
6632     tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
6633 #if defined(TARGET_PPC64)
6634     tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], 0xFFFFFFFF00000000ULL);
6635 #else
6636     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
6637 #endif
6638     tcg_gen_br(l2);
6639     gen_set_label(l1);
6640 #if defined(TARGET_PPC64)
6641     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0xFFFFFFFF00000000ULL);
6642 #else
6643     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
6644 #endif
6645     gen_set_label(l2);
6646     tcg_gen_andi_i32(t0, cpu_crf[ctx->opcode & 0x07], 1 << 2);
6647     tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l3);
6648 #if defined(TARGET_PPC64)
6649     tcg_gen_andi_tl(t2, cpu_gpr[rA(ctx->opcode)], 0x00000000FFFFFFFFULL);
6650 #else
6651     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
6652 #endif
6653     tcg_gen_br(l4);
6654     gen_set_label(l3);
6655 #if defined(TARGET_PPC64)
6656     tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x00000000FFFFFFFFULL);
6657 #else
6658     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
6659 #endif
6660     gen_set_label(l4);
6661     tcg_temp_free_i32(t0);
6662 #if defined(TARGET_PPC64)
6663     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t1, t2);
6664     tcg_temp_free(t1);
6665     tcg_temp_free(t2);
6666 #endif
6667 }
6668 GEN_HANDLER2(evsel0, "evsel", 0x04, 0x1c, 0x09, 0x00000000, PPC_SPE)
6669 {
6670     gen_evsel(ctx);
6671 }
6672 GEN_HANDLER2(evsel1, "evsel", 0x04, 0x1d, 0x09, 0x00000000, PPC_SPE)
6673 {
6674     gen_evsel(ctx);
6675 }
6676 GEN_HANDLER2(evsel2, "evsel", 0x04, 0x1e, 0x09, 0x00000000, PPC_SPE)
6677 {
6678     gen_evsel(ctx);
6679 }
6680 GEN_HANDLER2(evsel3, "evsel", 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE)
6681 {
6682     gen_evsel(ctx);
6683 }
6684
6685 GEN_SPE(evaddw,         speundef,      0x00, 0x08, 0x00000000, PPC_SPE); ////
6686 GEN_SPE(evaddiw,        speundef,      0x01, 0x08, 0x00000000, PPC_SPE);
6687 GEN_SPE(evsubfw,        speundef,      0x02, 0x08, 0x00000000, PPC_SPE); ////
6688 GEN_SPE(evsubifw,       speundef,      0x03, 0x08, 0x00000000, PPC_SPE);
6689 GEN_SPE(evabs,          evneg,         0x04, 0x08, 0x0000F800, PPC_SPE); ////
6690 GEN_SPE(evextsb,        evextsh,       0x05, 0x08, 0x0000F800, PPC_SPE); ////
6691 GEN_SPE(evrndw,         evcntlzw,      0x06, 0x08, 0x0000F800, PPC_SPE); ////
6692 GEN_SPE(evcntlsw,       brinc,         0x07, 0x08, 0x00000000, PPC_SPE); //
6693 GEN_SPE(speundef,       evand,         0x08, 0x08, 0x00000000, PPC_SPE); ////
6694 GEN_SPE(evandc,         speundef,      0x09, 0x08, 0x00000000, PPC_SPE); ////
6695 GEN_SPE(evxor,          evor,          0x0B, 0x08, 0x00000000, PPC_SPE); ////
6696 GEN_SPE(evnor,          eveqv,         0x0C, 0x08, 0x00000000, PPC_SPE); ////
6697 GEN_SPE(speundef,       evorc,         0x0D, 0x08, 0x00000000, PPC_SPE); ////
6698 GEN_SPE(evnand,         speundef,      0x0F, 0x08, 0x00000000, PPC_SPE); ////
6699 GEN_SPE(evsrwu,         evsrws,        0x10, 0x08, 0x00000000, PPC_SPE); ////
6700 GEN_SPE(evsrwiu,        evsrwis,       0x11, 0x08, 0x00000000, PPC_SPE);
6701 GEN_SPE(evslw,          speundef,      0x12, 0x08, 0x00000000, PPC_SPE); ////
6702 GEN_SPE(evslwi,         speundef,      0x13, 0x08, 0x00000000, PPC_SPE);
6703 GEN_SPE(evrlw,          evsplati,      0x14, 0x08, 0x00000000, PPC_SPE); //
6704 GEN_SPE(evrlwi,         evsplatfi,     0x15, 0x08, 0x00000000, PPC_SPE);
6705 GEN_SPE(evmergehi,      evmergelo,     0x16, 0x08, 0x00000000, PPC_SPE); ////
6706 GEN_SPE(evmergehilo,    evmergelohi,   0x17, 0x08, 0x00000000, PPC_SPE); ////
6707 GEN_SPE(evcmpgtu,       evcmpgts,      0x18, 0x08, 0x00600000, PPC_SPE); ////
6708 GEN_SPE(evcmpltu,       evcmplts,      0x19, 0x08, 0x00600000, PPC_SPE); ////
6709 GEN_SPE(evcmpeq,        speundef,      0x1A, 0x08, 0x00600000, PPC_SPE); ////
6710
6711 /* SPE load and stores */
6712 static always_inline void gen_addr_spe_imm_index (DisasContext *ctx, TCGv EA, int sh)
6713 {
6714     target_ulong uimm = rB(ctx->opcode);
6715
6716     if (rA(ctx->opcode) == 0) {
6717         tcg_gen_movi_tl(EA, uimm << sh);
6718     } else {
6719         tcg_gen_addi_tl(EA, cpu_gpr[rA(ctx->opcode)], uimm << sh);
6720 #if defined(TARGET_PPC64)
6721         if (!ctx->sf_mode) {
6722             tcg_gen_ext32u_tl(EA, EA);
6723         }
6724 #endif
6725     }
6726 }
6727
6728 static always_inline void gen_op_evldd(DisasContext *ctx, TCGv addr)
6729 {
6730 #if defined(TARGET_PPC64)
6731     gen_qemu_ld64(ctx, cpu_gpr[rD(ctx->opcode)], addr);
6732 #else
6733     TCGv_i64 t0 = tcg_temp_new_i64();
6734     gen_qemu_ld64(ctx, t0, addr);
6735     tcg_gen_trunc_i64_i32(cpu_gpr[rD(ctx->opcode)], t0);
6736     tcg_gen_shri_i64(t0, t0, 32);
6737     tcg_gen_trunc_i64_i32(cpu_gprh[rD(ctx->opcode)], t0);
6738     tcg_temp_free_i64(t0);
6739 #endif
6740 }
6741
6742 static always_inline void gen_op_evldw(DisasContext *ctx, TCGv addr)
6743 {
6744 #if defined(TARGET_PPC64)
6745     TCGv t0 = tcg_temp_new();
6746     gen_qemu_ld32u(ctx, t0, addr);
6747     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32);
6748     gen_addr_add(ctx, addr, addr, 4);
6749     gen_qemu_ld32u(ctx, t0, addr);
6750     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
6751     tcg_temp_free(t0);
6752 #else
6753     gen_qemu_ld32u(ctx, cpu_gprh[rD(ctx->opcode)], addr);
6754     gen_addr_add(ctx, addr, addr, 4);
6755     gen_qemu_ld32u(ctx, cpu_gpr[rD(ctx->opcode)], addr);
6756 #endif
6757 }
6758
6759 static always_inline void gen_op_evldh(DisasContext *ctx, TCGv addr)
6760 {
6761     TCGv t0 = tcg_temp_new();
6762 #if defined(TARGET_PPC64)
6763     gen_qemu_ld16u(ctx, t0, addr);
6764     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48);
6765     gen_addr_add(ctx, addr, addr, 2);
6766     gen_qemu_ld16u(ctx, t0, addr);
6767     tcg_gen_shli_tl(t0, t0, 32);
6768     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
6769     gen_addr_add(ctx, addr, addr, 2);
6770     gen_qemu_ld16u(ctx, t0, addr);
6771     tcg_gen_shli_tl(t0, t0, 16);
6772     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
6773     gen_addr_add(ctx, addr, addr, 2);
6774     gen_qemu_ld16u(ctx, t0, addr);
6775     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
6776 #else
6777     gen_qemu_ld16u(ctx, t0, addr);
6778     tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
6779     gen_addr_add(ctx, addr, addr, 2);
6780     gen_qemu_ld16u(ctx, t0, addr);
6781     tcg_gen_or_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0);
6782     gen_addr_add(ctx, addr, addr, 2);
6783     gen_qemu_ld16u(ctx, t0, addr);
6784     tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
6785     gen_addr_add(ctx, addr, addr, 2);
6786     gen_qemu_ld16u(ctx, t0, addr);
6787     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
6788 #endif
6789     tcg_temp_free(t0);
6790 }
6791
6792 static always_inline void gen_op_evlhhesplat(DisasContext *ctx, TCGv addr)
6793 {
6794     TCGv t0 = tcg_temp_new();
6795     gen_qemu_ld16u(ctx, t0, addr);
6796 #if defined(TARGET_PPC64)
6797     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48);
6798     tcg_gen_shli_tl(t0, t0, 16);
6799     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
6800 #else
6801     tcg_gen_shli_tl(t0, t0, 16);
6802     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
6803     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
6804 #endif
6805     tcg_temp_free(t0);
6806 }
6807
6808 static always_inline void gen_op_evlhhousplat(DisasContext *ctx, TCGv addr)
6809 {
6810     TCGv t0 = tcg_temp_new();
6811     gen_qemu_ld16u(ctx, t0, addr);
6812 #if defined(TARGET_PPC64)
6813     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32);
6814     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
6815 #else
6816     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
6817     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
6818 #endif
6819     tcg_temp_free(t0);
6820 }
6821
6822 static always_inline void gen_op_evlhhossplat(DisasContext *ctx, TCGv addr)
6823 {
6824     TCGv t0 = tcg_temp_new();
6825     gen_qemu_ld16s(ctx, t0, addr);
6826 #if defined(TARGET_PPC64)
6827     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32);
6828     tcg_gen_ext32u_tl(t0, t0);
6829     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
6830 #else
6831     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
6832     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
6833 #endif
6834     tcg_temp_free(t0);
6835 }
6836
6837 static always_inline void gen_op_evlwhe(DisasContext *ctx, TCGv addr)
6838 {
6839     TCGv t0 = tcg_temp_new();
6840 #if defined(TARGET_PPC64)
6841     gen_qemu_ld16u(ctx, t0, addr);
6842     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48);
6843     gen_addr_add(ctx, addr, addr, 2);
6844     gen_qemu_ld16u(ctx, t0, addr);
6845     tcg_gen_shli_tl(t0, t0, 16);
6846     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
6847 #else
6848     gen_qemu_ld16u(ctx, t0, addr);
6849     tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
6850     gen_addr_add(ctx, addr, addr, 2);
6851     gen_qemu_ld16u(ctx, t0, addr);
6852     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 16);
6853 #endif
6854     tcg_temp_free(t0);
6855 }
6856
6857 static always_inline void gen_op_evlwhou(DisasContext *ctx, TCGv addr)
6858 {
6859 #if defined(TARGET_PPC64)
6860     TCGv t0 = tcg_temp_new();
6861     gen_qemu_ld16u(ctx, cpu_gpr[rD(ctx->opcode)], addr);
6862     gen_addr_add(ctx, addr, addr, 2);
6863     gen_qemu_ld16u(ctx, t0, addr);
6864     tcg_gen_shli_tl(t0, t0, 32);
6865     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
6866     tcg_temp_free(t0);
6867 #else
6868     gen_qemu_ld16u(ctx, cpu_gprh[rD(ctx->opcode)], addr);
6869     gen_addr_add(ctx, addr, addr, 2);
6870     gen_qemu_ld16u(ctx, cpu_gpr[rD(ctx->opcode)], addr);
6871 #endif
6872 }
6873
6874 static always_inline void gen_op_evlwhos(DisasContext *ctx, TCGv addr)
6875 {
6876 #if defined(TARGET_PPC64)
6877     TCGv t0 = tcg_temp_new();
6878     gen_qemu_ld16s(ctx, t0, addr);
6879     tcg_gen_ext32u_tl(cpu_gpr[rD(ctx->opcode)], t0);
6880     gen_addr_add(ctx, addr, addr, 2);
6881     gen_qemu_ld16s(ctx, t0, addr);
6882     tcg_gen_shli_tl(t0, t0, 32);
6883     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
6884     tcg_temp_free(t0);
6885 #else
6886     gen_qemu_ld16s(ctx, cpu_gprh[rD(ctx->opcode)], addr);
6887     gen_addr_add(ctx, addr, addr, 2);
6888     gen_qemu_ld16s(ctx, cpu_gpr[rD(ctx->opcode)], addr);
6889 #endif
6890 }
6891
6892 static always_inline void gen_op_evlwwsplat(DisasContext *ctx, TCGv addr)
6893 {
6894     TCGv t0 = tcg_temp_new();
6895     gen_qemu_ld32u(ctx, t0, addr);
6896 #if defined(TARGET_PPC64)
6897     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32);
6898     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
6899 #else
6900     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
6901     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
6902 #endif
6903     tcg_temp_free(t0);
6904 }
6905
6906 static always_inline void gen_op_evlwhsplat(DisasContext *ctx, TCGv addr)
6907 {
6908     TCGv t0 = tcg_temp_new();
6909 #if defined(TARGET_PPC64)
6910     gen_qemu_ld16u(ctx, t0, addr);
6911     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48);
6912     tcg_gen_shli_tl(t0, t0, 32);
6913     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
6914     gen_addr_add(ctx, addr, addr, 2);
6915     gen_qemu_ld16u(ctx, t0, addr);
6916     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
6917     tcg_gen_shli_tl(t0, t0, 16);
6918     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
6919 #else
6920     gen_qemu_ld16u(ctx, t0, addr);
6921     tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
6922     tcg_gen_or_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0);
6923     gen_addr_add(ctx, addr, addr, 2);
6924     gen_qemu_ld16u(ctx, t0, addr);
6925     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 16);
6926     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0);
6927 #endif
6928     tcg_temp_free(t0);
6929 }
6930
6931 static always_inline void gen_op_evstdd(DisasContext *ctx, TCGv addr)
6932 {
6933 #if defined(TARGET_PPC64)
6934     gen_qemu_st64(ctx, cpu_gpr[rS(ctx->opcode)], addr);
6935 #else
6936     TCGv_i64 t0 = tcg_temp_new_i64();
6937     tcg_gen_concat_i32_i64(t0, cpu_gpr[rS(ctx->opcode)], cpu_gprh[rS(ctx->opcode)]);
6938     gen_qemu_st64(ctx, t0, addr);
6939     tcg_temp_free_i64(t0);
6940 #endif
6941 }
6942
6943 static always_inline void gen_op_evstdw(DisasContext *ctx, TCGv addr)
6944 {
6945 #if defined(TARGET_PPC64)
6946     TCGv t0 = tcg_temp_new();
6947     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32);
6948     gen_qemu_st32(ctx, t0, addr);
6949     tcg_temp_free(t0);
6950 #else
6951     gen_qemu_st32(ctx, cpu_gprh[rS(ctx->opcode)], addr);
6952 #endif
6953     gen_addr_add(ctx, addr, addr, 4);
6954     gen_qemu_st32(ctx, cpu_gpr[rS(ctx->opcode)], addr);
6955 }
6956
6957 static always_inline void gen_op_evstdh(DisasContext *ctx, TCGv addr)
6958 {
6959     TCGv t0 = tcg_temp_new();
6960 #if defined(TARGET_PPC64)
6961     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 48);
6962 #else
6963     tcg_gen_shri_tl(t0, cpu_gprh[rS(ctx->opcode)], 16);
6964 #endif
6965     gen_qemu_st16(ctx, t0, addr);
6966     gen_addr_add(ctx, addr, addr, 2);
6967 #if defined(TARGET_PPC64)
6968     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32);
6969     gen_qemu_st16(ctx, t0, addr);
6970 #else
6971     gen_qemu_st16(ctx, cpu_gprh[rS(ctx->opcode)], addr);
6972 #endif
6973     gen_addr_add(ctx, addr, addr, 2);
6974     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 16);
6975     gen_qemu_st16(ctx, t0, addr);
6976     tcg_temp_free(t0);
6977     gen_addr_add(ctx, addr, addr, 2);
6978     gen_qemu_st16(ctx, cpu_gpr[rS(ctx->opcode)], addr);
6979 }
6980
6981 static always_inline void gen_op_evstwhe(DisasContext *ctx, TCGv addr)
6982 {
6983     TCGv t0 = tcg_temp_new();
6984 #if defined(TARGET_PPC64)
6985     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 48);
6986 #else
6987     tcg_gen_shri_tl(t0, cpu_gprh[rS(ctx->opcode)], 16);
6988 #endif
6989     gen_qemu_st16(ctx, t0, addr);
6990     gen_addr_add(ctx, addr, addr, 2);
6991     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 16);
6992     gen_qemu_st16(ctx, t0, addr);
6993     tcg_temp_free(t0);
6994 }
6995
6996 static always_inline void gen_op_evstwho(DisasContext *ctx, TCGv addr)
6997 {
6998 #if defined(TARGET_PPC64)
6999     TCGv t0 = tcg_temp_new();
7000     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32);
7001     gen_qemu_st16(ctx, t0, addr);
7002     tcg_temp_free(t0);
7003 #else
7004     gen_qemu_st16(ctx, cpu_gprh[rS(ctx->opcode)], addr);
7005 #endif
7006     gen_addr_add(ctx, addr, addr, 2);
7007     gen_qemu_st16(ctx, cpu_gpr[rS(ctx->opcode)], addr);
7008 }
7009
7010 static always_inline void gen_op_evstwwe(DisasContext *ctx, TCGv addr)
7011 {
7012 #if defined(TARGET_PPC64)
7013     TCGv t0 = tcg_temp_new();
7014     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32);
7015     gen_qemu_st32(ctx, t0, addr);
7016     tcg_temp_free(t0);
7017 #else
7018     gen_qemu_st32(ctx, cpu_gprh[rS(ctx->opcode)], addr);
7019 #endif
7020 }
7021
7022 static always_inline void gen_op_evstwwo(DisasContext *ctx, TCGv addr)
7023 {
7024     gen_qemu_st32(ctx, cpu_gpr[rS(ctx->opcode)], addr);
7025 }
7026
7027 #define GEN_SPEOP_LDST(name, opc2, sh)                                        \
7028 GEN_HANDLER(name, 0x04, opc2, 0x0C, 0x00000000, PPC_SPE)                      \
7029 {                                                                             \
7030     TCGv t0;                                                                  \
7031     if (unlikely(!ctx->spe_enabled)) {                                        \
7032         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
7033         return;                                                               \
7034     }                                                                         \
7035     gen_set_access_type(ctx, ACCESS_INT);                                     \
7036     t0 = tcg_temp_new();                                                      \
7037     if (Rc(ctx->opcode)) {                                                    \
7038         gen_addr_spe_imm_index(ctx, t0, sh);                                  \
7039     } else {                                                                  \
7040         gen_addr_reg_index(ctx, t0);                                          \
7041     }                                                                         \
7042     gen_op_##name(ctx, t0);                                                   \
7043     tcg_temp_free(t0);                                                        \
7044 }
7045
7046 GEN_SPEOP_LDST(evldd, 0x00, 3);
7047 GEN_SPEOP_LDST(evldw, 0x01, 3);
7048 GEN_SPEOP_LDST(evldh, 0x02, 3);
7049 GEN_SPEOP_LDST(evlhhesplat, 0x04, 1);
7050 GEN_SPEOP_LDST(evlhhousplat, 0x06, 1);
7051 GEN_SPEOP_LDST(evlhhossplat, 0x07, 1);
7052 GEN_SPEOP_LDST(evlwhe, 0x08, 2);
7053 GEN_SPEOP_LDST(evlwhou, 0x0A, 2);
7054 GEN_SPEOP_LDST(evlwhos, 0x0B, 2);
7055 GEN_SPEOP_LDST(evlwwsplat, 0x0C, 2);
7056 GEN_SPEOP_LDST(evlwhsplat, 0x0E, 2);
7057
7058 GEN_SPEOP_LDST(evstdd, 0x10, 3);
7059 GEN_SPEOP_LDST(evstdw, 0x11, 3);
7060 GEN_SPEOP_LDST(evstdh, 0x12, 3);
7061 GEN_SPEOP_LDST(evstwhe, 0x18, 2);
7062 GEN_SPEOP_LDST(evstwho, 0x1A, 2);
7063 GEN_SPEOP_LDST(evstwwe, 0x1C, 2);
7064 GEN_SPEOP_LDST(evstwwo, 0x1E, 2);
7065
7066 /* Multiply and add - TODO */
7067 #if 0
7068 GEN_SPE(speundef,       evmhessf,      0x01, 0x10, 0x00000000, PPC_SPE);
7069 GEN_SPE(speundef,       evmhossf,      0x03, 0x10, 0x00000000, PPC_SPE);
7070 GEN_SPE(evmheumi,       evmhesmi,      0x04, 0x10, 0x00000000, PPC_SPE);
7071 GEN_SPE(speundef,       evmhesmf,      0x05, 0x10, 0x00000000, PPC_SPE);
7072 GEN_SPE(evmhoumi,       evmhosmi,      0x06, 0x10, 0x00000000, PPC_SPE);
7073 GEN_SPE(speundef,       evmhosmf,      0x07, 0x10, 0x00000000, PPC_SPE);
7074 GEN_SPE(speundef,       evmhessfa,     0x11, 0x10, 0x00000000, PPC_SPE);
7075 GEN_SPE(speundef,       evmhossfa,     0x13, 0x10, 0x00000000, PPC_SPE);
7076 GEN_SPE(evmheumia,      evmhesmia,     0x14, 0x10, 0x00000000, PPC_SPE);
7077 GEN_SPE(speundef,       evmhesmfa,     0x15, 0x10, 0x00000000, PPC_SPE);
7078 GEN_SPE(evmhoumia,      evmhosmia,     0x16, 0x10, 0x00000000, PPC_SPE);
7079 GEN_SPE(speundef,       evmhosmfa,     0x17, 0x10, 0x00000000, PPC_SPE);
7080
7081 GEN_SPE(speundef,       evmwhssf,      0x03, 0x11, 0x00000000, PPC_SPE);
7082 GEN_SPE(evmwlumi,       speundef,      0x04, 0x11, 0x00000000, PPC_SPE);
7083 GEN_SPE(evmwhumi,       evmwhsmi,      0x06, 0x11, 0x00000000, PPC_SPE);
7084 GEN_SPE(speundef,       evmwhsmf,      0x07, 0x11, 0x00000000, PPC_SPE);
7085 GEN_SPE(speundef,       evmwssf,       0x09, 0x11, 0x00000000, PPC_SPE);
7086 GEN_SPE(evmwumi,        evmwsmi,       0x0C, 0x11, 0x00000000, PPC_SPE);
7087 GEN_SPE(speundef,       evmwsmf,       0x0D, 0x11, 0x00000000, PPC_SPE);
7088 GEN_SPE(speundef,       evmwhssfa,     0x13, 0x11, 0x00000000, PPC_SPE);
7089 GEN_SPE(evmwlumia,      speundef,      0x14, 0x11, 0x00000000, PPC_SPE);
7090 GEN_SPE(evmwhumia,      evmwhsmia,     0x16, 0x11, 0x00000000, PPC_SPE);
7091 GEN_SPE(speundef,       evmwhsmfa,     0x17, 0x11, 0x00000000, PPC_SPE);
7092 GEN_SPE(speundef,       evmwssfa,      0x19, 0x11, 0x00000000, PPC_SPE);
7093 GEN_SPE(evmwumia,       evmwsmia,      0x1C, 0x11, 0x00000000, PPC_SPE);
7094 GEN_SPE(speundef,       evmwsmfa,      0x1D, 0x11, 0x00000000, PPC_SPE);
7095
7096 GEN_SPE(evadduiaaw,     evaddsiaaw,    0x00, 0x13, 0x0000F800, PPC_SPE);
7097 GEN_SPE(evsubfusiaaw,   evsubfssiaaw,  0x01, 0x13, 0x0000F800, PPC_SPE);
7098 GEN_SPE(evaddumiaaw,    evaddsmiaaw,   0x04, 0x13, 0x0000F800, PPC_SPE);
7099 GEN_SPE(evsubfumiaaw,   evsubfsmiaaw,  0x05, 0x13, 0x0000F800, PPC_SPE);
7100 GEN_SPE(evdivws,        evdivwu,       0x06, 0x13, 0x00000000, PPC_SPE);
7101 GEN_SPE(evmra,          speundef,      0x07, 0x13, 0x0000F800, PPC_SPE);
7102
7103 GEN_SPE(evmheusiaaw,    evmhessiaaw,   0x00, 0x14, 0x00000000, PPC_SPE);
7104 GEN_SPE(speundef,       evmhessfaaw,   0x01, 0x14, 0x00000000, PPC_SPE);
7105 GEN_SPE(evmhousiaaw,    evmhossiaaw,   0x02, 0x14, 0x00000000, PPC_SPE);
7106 GEN_SPE(speundef,       evmhossfaaw,   0x03, 0x14, 0x00000000, PPC_SPE);
7107 GEN_SPE(evmheumiaaw,    evmhesmiaaw,   0x04, 0x14, 0x00000000, PPC_SPE);
7108 GEN_SPE(speundef,       evmhesmfaaw,   0x05, 0x14, 0x00000000, PPC_SPE);
7109 GEN_SPE(evmhoumiaaw,    evmhosmiaaw,   0x06, 0x14, 0x00000000, PPC_SPE);
7110 GEN_SPE(speundef,       evmhosmfaaw,   0x07, 0x14, 0x00000000, PPC_SPE);
7111 GEN_SPE(evmhegumiaa,    evmhegsmiaa,   0x14, 0x14, 0x00000000, PPC_SPE);
7112 GEN_SPE(speundef,       evmhegsmfaa,   0x15, 0x14, 0x00000000, PPC_SPE);
7113 GEN_SPE(evmhogumiaa,    evmhogsmiaa,   0x16, 0x14, 0x00000000, PPC_SPE);
7114 GEN_SPE(speundef,       evmhogsmfaa,   0x17, 0x14, 0x00000000, PPC_SPE);
7115
7116 GEN_SPE(evmwlusiaaw,    evmwlssiaaw,   0x00, 0x15, 0x00000000, PPC_SPE);
7117 GEN_SPE(evmwlumiaaw,    evmwlsmiaaw,   0x04, 0x15, 0x00000000, PPC_SPE);
7118 GEN_SPE(speundef,       evmwssfaa,     0x09, 0x15, 0x00000000, PPC_SPE);
7119 GEN_SPE(evmwumiaa,      evmwsmiaa,     0x0C, 0x15, 0x00000000, PPC_SPE);
7120 GEN_SPE(speundef,       evmwsmfaa,     0x0D, 0x15, 0x00000000, PPC_SPE);
7121
7122 GEN_SPE(evmheusianw,    evmhessianw,   0x00, 0x16, 0x00000000, PPC_SPE);
7123 GEN_SPE(speundef,       evmhessfanw,   0x01, 0x16, 0x00000000, PPC_SPE);
7124 GEN_SPE(evmhousianw,    evmhossianw,   0x02, 0x16, 0x00000000, PPC_SPE);
7125 GEN_SPE(speundef,       evmhossfanw,   0x03, 0x16, 0x00000000, PPC_SPE);
7126 GEN_SPE(evmheumianw,    evmhesmianw,   0x04, 0x16, 0x00000000, PPC_SPE);
7127 GEN_SPE(speundef,       evmhesmfanw,   0x05, 0x16, 0x00000000, PPC_SPE);
7128 GEN_SPE(evmhoumianw,    evmhosmianw,   0x06, 0x16, 0x00000000, PPC_SPE);
7129 GEN_SPE(speundef,       evmhosmfanw,   0x07, 0x16, 0x00000000, PPC_SPE);
7130 GEN_SPE(evmhegumian,    evmhegsmian,   0x14, 0x16, 0x00000000, PPC_SPE);
7131 GEN_SPE(speundef,       evmhegsmfan,   0x15, 0x16, 0x00000000, PPC_SPE);
7132 GEN_SPE(evmhigumian,    evmhigsmian,   0x16, 0x16, 0x00000000, PPC_SPE);
7133 GEN_SPE(speundef,       evmhogsmfan,   0x17, 0x16, 0x00000000, PPC_SPE);
7134
7135 GEN_SPE(evmwlusianw,    evmwlssianw,   0x00, 0x17, 0x00000000, PPC_SPE);
7136 GEN_SPE(evmwlumianw,    evmwlsmianw,   0x04, 0x17, 0x00000000, PPC_SPE);
7137 GEN_SPE(speundef,       evmwssfan,     0x09, 0x17, 0x00000000, PPC_SPE);
7138 GEN_SPE(evmwumian,      evmwsmian,     0x0C, 0x17, 0x00000000, PPC_SPE);
7139 GEN_SPE(speundef,       evmwsmfan,     0x0D, 0x17, 0x00000000, PPC_SPE);
7140 #endif
7141
7142 /***                      SPE floating-point extension                     ***/
7143 #if defined(TARGET_PPC64)
7144 #define GEN_SPEFPUOP_CONV_32_32(name)                                         \
7145 static always_inline void gen_##name (DisasContext *ctx)                      \
7146 {                                                                             \
7147     TCGv_i32 t0;                                                              \
7148     TCGv t1;                                                                  \
7149     t0 = tcg_temp_new_i32();                                                  \
7150     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rB(ctx->opcode)]);                       \
7151     gen_helper_##name(t0, t0);                                                \
7152     t1 = tcg_temp_new();                                                      \
7153     tcg_gen_extu_i32_tl(t1, t0);                                              \
7154     tcg_temp_free_i32(t0);                                                    \
7155     tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)],       \
7156                     0xFFFFFFFF00000000ULL);                                   \
7157     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t1);    \
7158     tcg_temp_free(t1);                                                        \
7159 }
7160 #define GEN_SPEFPUOP_CONV_32_64(name)                                         \
7161 static always_inline void gen_##name (DisasContext *ctx)                      \
7162 {                                                                             \
7163     TCGv_i32 t0;                                                              \
7164     TCGv t1;                                                                  \
7165     t0 = tcg_temp_new_i32();                                                  \
7166     gen_helper_##name(t0, cpu_gpr[rB(ctx->opcode)]);                          \
7167     t1 = tcg_temp_new();                                                      \
7168     tcg_gen_extu_i32_tl(t1, t0);                                              \
7169     tcg_temp_free_i32(t0);                                                    \
7170     tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)],       \
7171                     0xFFFFFFFF00000000ULL);                                   \
7172     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t1);    \
7173     tcg_temp_free(t1);                                                        \
7174 }
7175 #define GEN_SPEFPUOP_CONV_64_32(name)                                         \
7176 static always_inline void gen_##name (DisasContext *ctx)                      \
7177 {                                                                             \
7178     TCGv_i32 t0 = tcg_temp_new_i32();                                         \
7179     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rB(ctx->opcode)]);                       \
7180     gen_helper_##name(cpu_gpr[rD(ctx->opcode)], t0);                          \
7181     tcg_temp_free_i32(t0);                                                    \
7182 }
7183 #define GEN_SPEFPUOP_CONV_64_64(name)                                         \
7184 static always_inline void gen_##name (DisasContext *ctx)                      \
7185 {                                                                             \
7186     gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
7187 }
7188 #define GEN_SPEFPUOP_ARITH2_32_32(name)                                       \
7189 static always_inline void gen_##name (DisasContext *ctx)                      \
7190 {                                                                             \
7191     TCGv_i32 t0, t1;                                                          \
7192     TCGv_i64 t2;                                                              \
7193     if (unlikely(!ctx->spe_enabled)) {                                        \
7194         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
7195         return;                                                               \
7196     }                                                                         \
7197     t0 = tcg_temp_new_i32();                                                  \
7198     t1 = tcg_temp_new_i32();                                                  \
7199     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);                       \
7200     tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);                       \
7201     gen_helper_##name(t0, t0, t1);                                            \
7202     tcg_temp_free_i32(t1);                                                    \
7203     t2 = tcg_temp_new();                                                      \
7204     tcg_gen_extu_i32_tl(t2, t0);                                              \
7205     tcg_temp_free_i32(t0);                                                    \
7206     tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)],       \
7207                     0xFFFFFFFF00000000ULL);                                   \
7208     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t2);    \
7209     tcg_temp_free(t2);                                                        \
7210 }
7211 #define GEN_SPEFPUOP_ARITH2_64_64(name)                                       \
7212 static always_inline void gen_##name (DisasContext *ctx)                      \
7213 {                                                                             \
7214     if (unlikely(!ctx->spe_enabled)) {                                        \
7215         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
7216         return;                                                               \
7217     }                                                                         \
7218     gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],     \
7219                       cpu_gpr[rB(ctx->opcode)]);                              \
7220 }
7221 #define GEN_SPEFPUOP_COMP_32(name)                                            \
7222 static always_inline void gen_##name (DisasContext *ctx)                      \
7223 {                                                                             \
7224     TCGv_i32 t0, t1;                                                          \
7225     if (unlikely(!ctx->spe_enabled)) {                                        \
7226         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
7227         return;                                                               \
7228     }                                                                         \
7229     t0 = tcg_temp_new_i32();                                                  \
7230     t1 = tcg_temp_new_i32();                                                  \
7231     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);                       \
7232     tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);                       \
7233     gen_helper_##name(cpu_crf[crfD(ctx->opcode)], t0, t1);                    \
7234     tcg_temp_free_i32(t0);                                                    \
7235     tcg_temp_free_i32(t1);                                                    \
7236 }
7237 #define GEN_SPEFPUOP_COMP_64(name)                                            \
7238 static always_inline void gen_##name (DisasContext *ctx)                      \
7239 {                                                                             \
7240     if (unlikely(!ctx->spe_enabled)) {                                        \
7241         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
7242         return;                                                               \
7243     }                                                                         \
7244     gen_helper_##name(cpu_crf[crfD(ctx->opcode)],                             \
7245                       cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
7246 }
7247 #else
7248 #define GEN_SPEFPUOP_CONV_32_32(name)                                         \
7249 static always_inline void gen_##name (DisasContext *ctx)                      \
7250 {                                                                             \
7251     gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
7252 }
7253 #define GEN_SPEFPUOP_CONV_32_64(name)                                         \
7254 static always_inline void gen_##name (DisasContext *ctx)                      \
7255 {                                                                             \
7256     TCGv_i64 t0 = tcg_temp_new_i64();                                         \
7257     gen_load_gpr64(t0, rB(ctx->opcode));                                      \
7258     gen_helper_##name(cpu_gpr[rD(ctx->opcode)], t0);                          \
7259     tcg_temp_free_i64(t0);                                                    \
7260 }
7261 #define GEN_SPEFPUOP_CONV_64_32(name)                                         \
7262 static always_inline void gen_##name (DisasContext *ctx)                      \
7263 {                                                                             \
7264     TCGv_i64 t0 = tcg_temp_new_i64();                                         \
7265     gen_helper_##name(t0, cpu_gpr[rB(ctx->opcode)]);                          \
7266     gen_store_gpr64(rD(ctx->opcode), t0);                                     \
7267     tcg_temp_free_i64(t0);                                                    \
7268 }
7269 #define GEN_SPEFPUOP_CONV_64_64(name)                                         \
7270 static always_inline void gen_##name (DisasContext *ctx)                      \
7271 {                                                                             \
7272     TCGv_i64 t0 = tcg_temp_new_i64();                                         \
7273     gen_load_gpr64(t0, rB(ctx->opcode));                                      \
7274     gen_helper_##name(t0, t0);                                                \
7275     gen_store_gpr64(rD(ctx->opcode), t0);                                     \
7276     tcg_temp_free_i64(t0);                                                    \
7277 }
7278 #define GEN_SPEFPUOP_ARITH2_32_32(name)                                       \
7279 static always_inline void gen_##name (DisasContext *ctx)                      \
7280 {                                                                             \
7281     if (unlikely(!ctx->spe_enabled)) {                                        \
7282         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
7283         return;                                                               \
7284     }                                                                         \
7285     gen_helper_##name(cpu_gpr[rD(ctx->opcode)],                               \
7286                       cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
7287 }
7288 #define GEN_SPEFPUOP_ARITH2_64_64(name)                                       \
7289 static always_inline void gen_##name (DisasContext *ctx)                      \
7290 {                                                                             \
7291     TCGv_i64 t0, t1;                                                          \
7292     if (unlikely(!ctx->spe_enabled)) {                                        \
7293         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
7294         return;                                                               \
7295     }                                                                         \
7296     t0 = tcg_temp_new_i64();                                                  \
7297     t1 = tcg_temp_new_i64();                                                  \
7298     gen_load_gpr64(t0, rA(ctx->opcode));                                      \
7299     gen_load_gpr64(t1, rB(ctx->opcode));                                      \
7300     gen_helper_##name(t0, t0, t1);                                            \
7301     gen_store_gpr64(rD(ctx->opcode), t0);                                     \
7302     tcg_temp_free_i64(t0);                                                    \
7303     tcg_temp_free_i64(t1);                                                    \
7304 }
7305 #define GEN_SPEFPUOP_COMP_32(name)                                            \
7306 static always_inline void gen_##name (DisasContext *ctx)                      \
7307 {                                                                             \
7308     if (unlikely(!ctx->spe_enabled)) {                                        \
7309         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
7310         return;                                                               \
7311     }                                                                         \
7312     gen_helper_##name(cpu_crf[crfD(ctx->opcode)],                             \
7313                       cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
7314 }
7315 #define GEN_SPEFPUOP_COMP_64(name)                                            \
7316 static always_inline void gen_##name (DisasContext *ctx)                      \
7317 {                                                                             \
7318     TCGv_i64 t0, t1;                                                          \
7319     if (unlikely(!ctx->spe_enabled)) {                                        \
7320         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
7321         return;                                                               \
7322     }                                                                         \
7323     t0 = tcg_temp_new_i64();                                                  \
7324     t1 = tcg_temp_new_i64();                                                  \
7325     gen_load_gpr64(t0, rA(ctx->opcode));                                      \
7326     gen_load_gpr64(t1, rB(ctx->opcode));                                      \
7327     gen_helper_##name(cpu_crf[crfD(ctx->opcode)], t0, t1);                    \
7328     tcg_temp_free_i64(t0);                                                    \
7329     tcg_temp_free_i64(t1);                                                    \
7330 }
7331 #endif
7332
7333 /* Single precision floating-point vectors operations */
7334 /* Arithmetic */
7335 GEN_SPEFPUOP_ARITH2_64_64(evfsadd);
7336 GEN_SPEFPUOP_ARITH2_64_64(evfssub);
7337 GEN_SPEFPUOP_ARITH2_64_64(evfsmul);
7338 GEN_SPEFPUOP_ARITH2_64_64(evfsdiv);
7339 static always_inline void gen_evfsabs (DisasContext *ctx)
7340 {
7341     if (unlikely(!ctx->spe_enabled)) {
7342         gen_exception(ctx, POWERPC_EXCP_APU);
7343         return;
7344     }
7345 #if defined(TARGET_PPC64)
7346     tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~0x8000000080000000LL);
7347 #else
7348     tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~0x80000000);
7349     tcg_gen_andi_tl(cpu_gprh[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], ~0x80000000);
7350 #endif
7351 }
7352 static always_inline void gen_evfsnabs (DisasContext *ctx)
7353 {
7354     if (unlikely(!ctx->spe_enabled)) {
7355         gen_exception(ctx, POWERPC_EXCP_APU);
7356         return;
7357     }
7358 #if defined(TARGET_PPC64)
7359     tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000080000000LL);
7360 #else
7361     tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
7362     tcg_gen_ori_tl(cpu_gprh[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000);
7363 #endif
7364 }
7365 static always_inline void gen_evfsneg (DisasContext *ctx)
7366 {
7367     if (unlikely(!ctx->spe_enabled)) {
7368         gen_exception(ctx, POWERPC_EXCP_APU);
7369         return;
7370     }
7371 #if defined(TARGET_PPC64)
7372     tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000080000000LL);
7373 #else
7374     tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
7375     tcg_gen_xori_tl(cpu_gprh[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000);
7376 #endif
7377 }
7378
7379 /* Conversion */
7380 GEN_SPEFPUOP_CONV_64_64(evfscfui);
7381 GEN_SPEFPUOP_CONV_64_64(evfscfsi);
7382 GEN_SPEFPUOP_CONV_64_64(evfscfuf);
7383 GEN_SPEFPUOP_CONV_64_64(evfscfsf);
7384 GEN_SPEFPUOP_CONV_64_64(evfsctui);
7385 GEN_SPEFPUOP_CONV_64_64(evfsctsi);
7386 GEN_SPEFPUOP_CONV_64_64(evfsctuf);
7387 GEN_SPEFPUOP_CONV_64_64(evfsctsf);
7388 GEN_SPEFPUOP_CONV_64_64(evfsctuiz);
7389 GEN_SPEFPUOP_CONV_64_64(evfsctsiz);
7390
7391 /* Comparison */
7392 GEN_SPEFPUOP_COMP_64(evfscmpgt);
7393 GEN_SPEFPUOP_COMP_64(evfscmplt);
7394 GEN_SPEFPUOP_COMP_64(evfscmpeq);
7395 GEN_SPEFPUOP_COMP_64(evfststgt);
7396 GEN_SPEFPUOP_COMP_64(evfststlt);
7397 GEN_SPEFPUOP_COMP_64(evfststeq);
7398
7399 /* Opcodes definitions */
7400 GEN_SPE(evfsadd,        evfssub,       0x00, 0x0A, 0x00000000, PPC_SPEFPU); //
7401 GEN_SPE(evfsabs,        evfsnabs,      0x02, 0x0A, 0x0000F800, PPC_SPEFPU); //
7402 GEN_SPE(evfsneg,        speundef,      0x03, 0x0A, 0x0000F800, PPC_SPEFPU); //
7403 GEN_SPE(evfsmul,        evfsdiv,       0x04, 0x0A, 0x00000000, PPC_SPEFPU); //
7404 GEN_SPE(evfscmpgt,      evfscmplt,     0x06, 0x0A, 0x00600000, PPC_SPEFPU); //
7405 GEN_SPE(evfscmpeq,      speundef,      0x07, 0x0A, 0x00600000, PPC_SPEFPU); //
7406 GEN_SPE(evfscfui,       evfscfsi,      0x08, 0x0A, 0x00180000, PPC_SPEFPU); //
7407 GEN_SPE(evfscfuf,       evfscfsf,      0x09, 0x0A, 0x00180000, PPC_SPEFPU); //
7408 GEN_SPE(evfsctui,       evfsctsi,      0x0A, 0x0A, 0x00180000, PPC_SPEFPU); //
7409 GEN_SPE(evfsctuf,       evfsctsf,      0x0B, 0x0A, 0x00180000, PPC_SPEFPU); //
7410 GEN_SPE(evfsctuiz,      speundef,      0x0C, 0x0A, 0x00180000, PPC_SPEFPU); //
7411 GEN_SPE(evfsctsiz,      speundef,      0x0D, 0x0A, 0x00180000, PPC_SPEFPU); //
7412 GEN_SPE(evfststgt,      evfststlt,     0x0E, 0x0A, 0x00600000, PPC_SPEFPU); //
7413 GEN_SPE(evfststeq,      speundef,      0x0F, 0x0A, 0x00600000, PPC_SPEFPU); //
7414
7415 /* Single precision floating-point operations */
7416 /* Arithmetic */
7417 GEN_SPEFPUOP_ARITH2_32_32(efsadd);
7418 GEN_SPEFPUOP_ARITH2_32_32(efssub);
7419 GEN_SPEFPUOP_ARITH2_32_32(efsmul);
7420 GEN_SPEFPUOP_ARITH2_32_32(efsdiv);
7421 static always_inline void gen_efsabs (DisasContext *ctx)
7422 {
7423     if (unlikely(!ctx->spe_enabled)) {
7424         gen_exception(ctx, POWERPC_EXCP_APU);
7425         return;
7426     }
7427     tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], (target_long)~0x80000000LL);
7428 }
7429 static always_inline void gen_efsnabs (DisasContext *ctx)
7430 {
7431     if (unlikely(!ctx->spe_enabled)) {
7432         gen_exception(ctx, POWERPC_EXCP_APU);
7433         return;
7434     }
7435     tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
7436 }
7437 static always_inline void gen_efsneg (DisasContext *ctx)
7438 {
7439     if (unlikely(!ctx->spe_enabled)) {
7440         gen_exception(ctx, POWERPC_EXCP_APU);
7441         return;
7442     }
7443     tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
7444 }
7445
7446 /* Conversion */
7447 GEN_SPEFPUOP_CONV_32_32(efscfui);
7448 GEN_SPEFPUOP_CONV_32_32(efscfsi);
7449 GEN_SPEFPUOP_CONV_32_32(efscfuf);
7450 GEN_SPEFPUOP_CONV_32_32(efscfsf);
7451 GEN_SPEFPUOP_CONV_32_32(efsctui);
7452 GEN_SPEFPUOP_CONV_32_32(efsctsi);
7453 GEN_SPEFPUOP_CONV_32_32(efsctuf);
7454 GEN_SPEFPUOP_CONV_32_32(efsctsf);
7455 GEN_SPEFPUOP_CONV_32_32(efsctuiz);
7456 GEN_SPEFPUOP_CONV_32_32(efsctsiz);
7457 GEN_SPEFPUOP_CONV_32_64(efscfd);
7458
7459 /* Comparison */
7460 GEN_SPEFPUOP_COMP_32(efscmpgt);
7461 GEN_SPEFPUOP_COMP_32(efscmplt);
7462 GEN_SPEFPUOP_COMP_32(efscmpeq);
7463 GEN_SPEFPUOP_COMP_32(efststgt);
7464 GEN_SPEFPUOP_COMP_32(efststlt);
7465 GEN_SPEFPUOP_COMP_32(efststeq);
7466
7467 /* Opcodes definitions */
7468 GEN_SPE(efsadd,         efssub,        0x00, 0x0B, 0x00000000, PPC_SPEFPU); //
7469 GEN_SPE(efsabs,         efsnabs,       0x02, 0x0B, 0x0000F800, PPC_SPEFPU); //
7470 GEN_SPE(efsneg,         speundef,      0x03, 0x0B, 0x0000F800, PPC_SPEFPU); //
7471 GEN_SPE(efsmul,         efsdiv,        0x04, 0x0B, 0x00000000, PPC_SPEFPU); //
7472 GEN_SPE(efscmpgt,       efscmplt,      0x06, 0x0B, 0x00600000, PPC_SPEFPU); //
7473 GEN_SPE(efscmpeq,       efscfd,        0x07, 0x0B, 0x00600000, PPC_SPEFPU); //
7474 GEN_SPE(efscfui,        efscfsi,       0x08, 0x0B, 0x00180000, PPC_SPEFPU); //
7475 GEN_SPE(efscfuf,        efscfsf,       0x09, 0x0B, 0x00180000, PPC_SPEFPU); //
7476 GEN_SPE(efsctui,        efsctsi,       0x0A, 0x0B, 0x00180000, PPC_SPEFPU); //
7477 GEN_SPE(efsctuf,        efsctsf,       0x0B, 0x0B, 0x00180000, PPC_SPEFPU); //
7478 GEN_SPE(efsctuiz,       speundef,      0x0C, 0x0B, 0x00180000, PPC_SPEFPU); //
7479 GEN_SPE(efsctsiz,       speundef,      0x0D, 0x0B, 0x00180000, PPC_SPEFPU); //
7480 GEN_SPE(efststgt,       efststlt,      0x0E, 0x0B, 0x00600000, PPC_SPEFPU); //
7481 GEN_SPE(efststeq,       speundef,      0x0F, 0x0B, 0x00600000, PPC_SPEFPU); //
7482
7483 /* Double precision floating-point operations */
7484 /* Arithmetic */
7485 GEN_SPEFPUOP_ARITH2_64_64(efdadd);
7486 GEN_SPEFPUOP_ARITH2_64_64(efdsub);
7487 GEN_SPEFPUOP_ARITH2_64_64(efdmul);
7488 GEN_SPEFPUOP_ARITH2_64_64(efddiv);
7489 static always_inline void gen_efdabs (DisasContext *ctx)
7490 {
7491     if (unlikely(!ctx->spe_enabled)) {
7492         gen_exception(ctx, POWERPC_EXCP_APU);
7493         return;
7494     }
7495 #if defined(TARGET_PPC64)
7496     tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~0x8000000000000000LL);
7497 #else
7498     tcg_gen_andi_tl(cpu_gprh[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], ~0x80000000);
7499 #endif
7500 }
7501 static always_inline void gen_efdnabs (DisasContext *ctx)
7502 {
7503     if (unlikely(!ctx->spe_enabled)) {
7504         gen_exception(ctx, POWERPC_EXCP_APU);
7505         return;
7506     }
7507 #if defined(TARGET_PPC64)
7508     tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000000000000LL);
7509 #else
7510     tcg_gen_ori_tl(cpu_gprh[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000);
7511 #endif
7512 }
7513 static always_inline void gen_efdneg (DisasContext *ctx)
7514 {
7515     if (unlikely(!ctx->spe_enabled)) {
7516         gen_exception(ctx, POWERPC_EXCP_APU);
7517         return;
7518     }
7519 #if defined(TARGET_PPC64)
7520     tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000000000000LL);
7521 #else
7522     tcg_gen_xori_tl(cpu_gprh[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000);
7523 #endif
7524 }
7525
7526 /* Conversion */
7527 GEN_SPEFPUOP_CONV_64_32(efdcfui);
7528 GEN_SPEFPUOP_CONV_64_32(efdcfsi);
7529 GEN_SPEFPUOP_CONV_64_32(efdcfuf);
7530 GEN_SPEFPUOP_CONV_64_32(efdcfsf);
7531 GEN_SPEFPUOP_CONV_32_64(efdctui);
7532 GEN_SPEFPUOP_CONV_32_64(efdctsi);
7533 GEN_SPEFPUOP_CONV_32_64(efdctuf);
7534 GEN_SPEFPUOP_CONV_32_64(efdctsf);
7535 GEN_SPEFPUOP_CONV_32_64(efdctuiz);
7536 GEN_SPEFPUOP_CONV_32_64(efdctsiz);
7537 GEN_SPEFPUOP_CONV_64_32(efdcfs);
7538 GEN_SPEFPUOP_CONV_64_64(efdcfuid);
7539 GEN_SPEFPUOP_CONV_64_64(efdcfsid);
7540 GEN_SPEFPUOP_CONV_64_64(efdctuidz);
7541 GEN_SPEFPUOP_CONV_64_64(efdctsidz);
7542
7543 /* Comparison */
7544 GEN_SPEFPUOP_COMP_64(efdcmpgt);
7545 GEN_SPEFPUOP_COMP_64(efdcmplt);
7546 GEN_SPEFPUOP_COMP_64(efdcmpeq);
7547 GEN_SPEFPUOP_COMP_64(efdtstgt);
7548 GEN_SPEFPUOP_COMP_64(efdtstlt);
7549 GEN_SPEFPUOP_COMP_64(efdtsteq);
7550
7551 /* Opcodes definitions */
7552 GEN_SPE(efdadd,         efdsub,        0x10, 0x0B, 0x00000000, PPC_SPEFPU); //
7553 GEN_SPE(efdcfuid,       efdcfsid,      0x11, 0x0B, 0x00180000, PPC_SPEFPU); //
7554 GEN_SPE(efdabs,         efdnabs,       0x12, 0x0B, 0x0000F800, PPC_SPEFPU); //
7555 GEN_SPE(efdneg,         speundef,      0x13, 0x0B, 0x0000F800, PPC_SPEFPU); //
7556 GEN_SPE(efdmul,         efddiv,        0x14, 0x0B, 0x00000000, PPC_SPEFPU); //
7557 GEN_SPE(efdctuidz,      efdctsidz,     0x15, 0x0B, 0x00180000, PPC_SPEFPU); //
7558 GEN_SPE(efdcmpgt,       efdcmplt,      0x16, 0x0B, 0x00600000, PPC_SPEFPU); //
7559 GEN_SPE(efdcmpeq,       efdcfs,        0x17, 0x0B, 0x00600000, PPC_SPEFPU); //
7560 GEN_SPE(efdcfui,        efdcfsi,       0x18, 0x0B, 0x00180000, PPC_SPEFPU); //
7561 GEN_SPE(efdcfuf,        efdcfsf,       0x19, 0x0B, 0x00180000, PPC_SPEFPU); //
7562 GEN_SPE(efdctui,        efdctsi,       0x1A, 0x0B, 0x00180000, PPC_SPEFPU); //
7563 GEN_SPE(efdctuf,        efdctsf,       0x1B, 0x0B, 0x00180000, PPC_SPEFPU); //
7564 GEN_SPE(efdctuiz,       speundef,      0x1C, 0x0B, 0x00180000, PPC_SPEFPU); //
7565 GEN_SPE(efdctsiz,       speundef,      0x1D, 0x0B, 0x00180000, PPC_SPEFPU); //
7566 GEN_SPE(efdtstgt,       efdtstlt,      0x1E, 0x0B, 0x00600000, PPC_SPEFPU); //
7567 GEN_SPE(efdtsteq,       speundef,      0x1F, 0x0B, 0x00600000, PPC_SPEFPU); //
7568
7569 /* End opcode list */
7570 GEN_OPCODE_MARK(end);
7571
7572 #include "translate_init.c"
7573 #include "helper_regs.h"
7574
7575 /*****************************************************************************/
7576 /* Misc PowerPC helpers */
7577 void cpu_dump_state (CPUState *env, FILE *f,
7578                      int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
7579                      int flags)
7580 {
7581 #define RGPL  4
7582 #define RFPL  4
7583
7584     int i;
7585
7586     cpu_fprintf(f, "NIP " ADDRX "   LR " ADDRX " CTR " ADDRX " XER %08x\n",
7587                 env->nip, env->lr, env->ctr, env->xer);
7588     cpu_fprintf(f, "MSR " ADDRX " HID0 " ADDRX "  HF " ADDRX " idx %d\n",
7589                 env->msr, env->spr[SPR_HID0], env->hflags, env->mmu_idx);
7590 #if !defined(NO_TIMER_DUMP)
7591     cpu_fprintf(f, "TB %08x %08x "
7592 #if !defined(CONFIG_USER_ONLY)
7593                 "DECR %08x"
7594 #endif
7595                 "\n",
7596                 cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
7597 #if !defined(CONFIG_USER_ONLY)
7598                 , cpu_ppc_load_decr(env)
7599 #endif
7600                 );
7601 #endif
7602     for (i = 0; i < 32; i++) {
7603         if ((i & (RGPL - 1)) == 0)
7604             cpu_fprintf(f, "GPR%02d", i);
7605         cpu_fprintf(f, " " REGX, ppc_dump_gpr(env, i));
7606         if ((i & (RGPL - 1)) == (RGPL - 1))
7607             cpu_fprintf(f, "\n");
7608     }
7609     cpu_fprintf(f, "CR ");
7610     for (i = 0; i < 8; i++)
7611         cpu_fprintf(f, "%01x", env->crf[i]);
7612     cpu_fprintf(f, "  [");
7613     for (i = 0; i < 8; i++) {
7614         char a = '-';
7615         if (env->crf[i] & 0x08)
7616             a = 'L';
7617         else if (env->crf[i] & 0x04)
7618             a = 'G';
7619         else if (env->crf[i] & 0x02)
7620             a = 'E';
7621         cpu_fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
7622     }
7623     cpu_fprintf(f, " ]             RES " ADDRX "\n", env->reserve);
7624     for (i = 0; i < 32; i++) {
7625         if ((i & (RFPL - 1)) == 0)
7626             cpu_fprintf(f, "FPR%02d", i);
7627         cpu_fprintf(f, " %016" PRIx64, *((uint64_t *)&env->fpr[i]));
7628         if ((i & (RFPL - 1)) == (RFPL - 1))
7629             cpu_fprintf(f, "\n");
7630     }
7631     cpu_fprintf(f, "FPSCR %08x\n", env->fpscr);
7632 #if !defined(CONFIG_USER_ONLY)
7633     cpu_fprintf(f, "SRR0 " ADDRX " SRR1 " ADDRX " SDR1 " ADDRX "\n",
7634                 env->spr[SPR_SRR0], env->spr[SPR_SRR1], env->sdr1);
7635 #endif
7636
7637 #undef RGPL
7638 #undef RFPL
7639 }
7640
7641 void cpu_dump_statistics (CPUState *env, FILE*f,
7642                           int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
7643                           int flags)
7644 {
7645 #if defined(DO_PPC_STATISTICS)
7646     opc_handler_t **t1, **t2, **t3, *handler;
7647     int op1, op2, op3;
7648
7649     t1 = env->opcodes;
7650     for (op1 = 0; op1 < 64; op1++) {
7651         handler = t1[op1];
7652         if (is_indirect_opcode(handler)) {
7653             t2 = ind_table(handler);
7654             for (op2 = 0; op2 < 32; op2++) {
7655                 handler = t2[op2];
7656                 if (is_indirect_opcode(handler)) {
7657                     t3 = ind_table(handler);
7658                     for (op3 = 0; op3 < 32; op3++) {
7659                         handler = t3[op3];
7660                         if (handler->count == 0)
7661                             continue;
7662                         cpu_fprintf(f, "%02x %02x %02x (%02x %04d) %16s: "
7663                                     "%016llx %lld\n",
7664                                     op1, op2, op3, op1, (op3 << 5) | op2,
7665                                     handler->oname,
7666                                     handler->count, handler->count);
7667                     }
7668                 } else {
7669                     if (handler->count == 0)
7670                         continue;
7671                     cpu_fprintf(f, "%02x %02x    (%02x %04d) %16s: "
7672                                 "%016llx %lld\n",
7673                                 op1, op2, op1, op2, handler->oname,
7674                                 handler->count, handler->count);
7675                 }
7676             }
7677         } else {
7678             if (handler->count == 0)
7679                 continue;
7680             cpu_fprintf(f, "%02x       (%02x     ) %16s: %016llx %lld\n",
7681                         op1, op1, handler->oname,
7682                         handler->count, handler->count);
7683         }
7684     }
7685 #endif
7686 }
7687
7688 /*****************************************************************************/
7689 static always_inline void gen_intermediate_code_internal (CPUState *env,
7690                                                           TranslationBlock *tb,
7691                                                           int search_pc)
7692 {
7693     DisasContext ctx, *ctxp = &ctx;
7694     opc_handler_t **table, *handler;
7695     target_ulong pc_start;
7696     uint16_t *gen_opc_end;
7697     CPUBreakpoint *bp;
7698     int j, lj = -1;
7699     int num_insns;
7700     int max_insns;
7701
7702     pc_start = tb->pc;
7703     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
7704     ctx.nip = pc_start;
7705     ctx.tb = tb;
7706     ctx.exception = POWERPC_EXCP_NONE;
7707     ctx.spr_cb = env->spr_cb;
7708     ctx.mem_idx = env->mmu_idx;
7709     ctx.access_type = -1;
7710     ctx.le_mode = env->hflags & (1 << MSR_LE) ? 1 : 0;
7711 #if defined(TARGET_PPC64)
7712     ctx.sf_mode = msr_sf;
7713 #endif
7714     ctx.fpu_enabled = msr_fp;
7715     if ((env->flags & POWERPC_FLAG_SPE) && msr_spe)
7716         ctx.spe_enabled = msr_spe;
7717     else
7718         ctx.spe_enabled = 0;
7719     if ((env->flags & POWERPC_FLAG_VRE) && msr_vr)
7720         ctx.altivec_enabled = msr_vr;
7721     else
7722         ctx.altivec_enabled = 0;
7723     if ((env->flags & POWERPC_FLAG_SE) && msr_se)
7724         ctx.singlestep_enabled = CPU_SINGLE_STEP;
7725     else
7726         ctx.singlestep_enabled = 0;
7727     if ((env->flags & POWERPC_FLAG_BE) && msr_be)
7728         ctx.singlestep_enabled |= CPU_BRANCH_STEP;
7729     if (unlikely(env->singlestep_enabled))
7730         ctx.singlestep_enabled |= GDBSTUB_SINGLE_STEP;
7731 #if defined (DO_SINGLE_STEP) && 0
7732     /* Single step trace mode */
7733     msr_se = 1;
7734 #endif
7735     num_insns = 0;
7736     max_insns = tb->cflags & CF_COUNT_MASK;
7737     if (max_insns == 0)
7738         max_insns = CF_COUNT_MASK;
7739
7740     gen_icount_start();
7741     /* Set env in case of segfault during code fetch */
7742     while (ctx.exception == POWERPC_EXCP_NONE && gen_opc_ptr < gen_opc_end) {
7743         if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
7744             TAILQ_FOREACH(bp, &env->breakpoints, entry) {
7745                 if (bp->pc == ctx.nip) {
7746                     gen_debug_exception(ctxp);
7747                     break;
7748                 }
7749             }
7750         }
7751         if (unlikely(search_pc)) {
7752             j = gen_opc_ptr - gen_opc_buf;
7753             if (lj < j) {
7754                 lj++;
7755                 while (lj < j)
7756                     gen_opc_instr_start[lj++] = 0;
7757                 gen_opc_pc[lj] = ctx.nip;
7758                 gen_opc_instr_start[lj] = 1;
7759                 gen_opc_icount[lj] = num_insns;
7760             }
7761         }
7762 #if defined PPC_DEBUG_DISAS
7763         if (loglevel & CPU_LOG_TB_IN_ASM) {
7764             fprintf(logfile, "----------------\n");
7765             fprintf(logfile, "nip=" ADDRX " super=%d ir=%d\n",
7766                     ctx.nip, ctx.mem_idx, (int)msr_ir);
7767         }
7768 #endif
7769         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
7770             gen_io_start();
7771         if (unlikely(ctx.le_mode)) {
7772             ctx.opcode = bswap32(ldl_code(ctx.nip));
7773         } else {
7774             ctx.opcode = ldl_code(ctx.nip);
7775         }
7776 #if defined PPC_DEBUG_DISAS
7777         if (loglevel & CPU_LOG_TB_IN_ASM) {
7778             fprintf(logfile, "translate opcode %08x (%02x %02x %02x) (%s)\n",
7779                     ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
7780                     opc3(ctx.opcode), little_endian ? "little" : "big");
7781         }
7782 #endif
7783         ctx.nip += 4;
7784         table = env->opcodes;
7785         num_insns++;
7786         handler = table[opc1(ctx.opcode)];
7787         if (is_indirect_opcode(handler)) {
7788             table = ind_table(handler);
7789             handler = table[opc2(ctx.opcode)];
7790             if (is_indirect_opcode(handler)) {
7791                 table = ind_table(handler);
7792                 handler = table[opc3(ctx.opcode)];
7793             }
7794         }
7795         /* Is opcode *REALLY* valid ? */
7796         if (unlikely(handler->handler == &gen_invalid)) {
7797             if (loglevel != 0) {
7798                 fprintf(logfile, "invalid/unsupported opcode: "
7799                         "%02x - %02x - %02x (%08x) " ADDRX " %d\n",
7800                         opc1(ctx.opcode), opc2(ctx.opcode),
7801                         opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, (int)msr_ir);
7802             } else {
7803                 printf("invalid/unsupported opcode: "
7804                        "%02x - %02x - %02x (%08x) " ADDRX " %d\n",
7805                        opc1(ctx.opcode), opc2(ctx.opcode),
7806                        opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, (int)msr_ir);
7807             }
7808         } else {
7809             if (unlikely((ctx.opcode & handler->inval) != 0)) {
7810                 if (loglevel != 0) {
7811                     fprintf(logfile, "invalid bits: %08x for opcode: "
7812                             "%02x - %02x - %02x (%08x) " ADDRX "\n",
7813                             ctx.opcode & handler->inval, opc1(ctx.opcode),
7814                             opc2(ctx.opcode), opc3(ctx.opcode),
7815                             ctx.opcode, ctx.nip - 4);
7816                 } else {
7817                     printf("invalid bits: %08x for opcode: "
7818                            "%02x - %02x - %02x (%08x) " ADDRX "\n",
7819                            ctx.opcode & handler->inval, opc1(ctx.opcode),
7820                            opc2(ctx.opcode), opc3(ctx.opcode),
7821                            ctx.opcode, ctx.nip - 4);
7822                 }
7823                 gen_inval_exception(ctxp, POWERPC_EXCP_INVAL_INVAL);
7824                 break;
7825             }
7826         }
7827         (*(handler->handler))(&ctx);
7828 #if defined(DO_PPC_STATISTICS)
7829         handler->count++;
7830 #endif
7831         /* Check trace mode exceptions */
7832         if (unlikely(ctx.singlestep_enabled & CPU_SINGLE_STEP &&
7833                      (ctx.nip <= 0x100 || ctx.nip > 0xF00) &&
7834                      ctx.exception != POWERPC_SYSCALL &&
7835                      ctx.exception != POWERPC_EXCP_TRAP &&
7836                      ctx.exception != POWERPC_EXCP_BRANCH)) {
7837             gen_exception(ctxp, POWERPC_EXCP_TRACE);
7838         } else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
7839                             (env->singlestep_enabled) ||
7840                             num_insns >= max_insns)) {
7841             /* if we reach a page boundary or are single stepping, stop
7842              * generation
7843              */
7844             break;
7845         }
7846 #if defined (DO_SINGLE_STEP)
7847         break;
7848 #endif
7849     }
7850     if (tb->cflags & CF_LAST_IO)
7851         gen_io_end();
7852     if (ctx.exception == POWERPC_EXCP_NONE) {
7853         gen_goto_tb(&ctx, 0, ctx.nip);
7854     } else if (ctx.exception != POWERPC_EXCP_BRANCH) {
7855         if (unlikely(env->singlestep_enabled)) {
7856             gen_debug_exception(ctxp);
7857         }
7858         /* Generate the return instruction */
7859         tcg_gen_exit_tb(0);
7860     }
7861     gen_icount_end(tb, num_insns);
7862     *gen_opc_ptr = INDEX_op_end;
7863     if (unlikely(search_pc)) {
7864         j = gen_opc_ptr - gen_opc_buf;
7865         lj++;
7866         while (lj <= j)
7867             gen_opc_instr_start[lj++] = 0;
7868     } else {
7869         tb->size = ctx.nip - pc_start;
7870         tb->icount = num_insns;
7871     }
7872 #if defined(DEBUG_DISAS)
7873     if (loglevel & CPU_LOG_TB_CPU) {
7874         fprintf(logfile, "---------------- excp: %04x\n", ctx.exception);
7875         cpu_dump_state(env, logfile, fprintf, 0);
7876     }
7877     if (loglevel & CPU_LOG_TB_IN_ASM) {
7878         int flags;
7879         flags = env->bfd_mach;
7880         flags |= ctx.le_mode << 16;
7881         fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
7882         target_disas(logfile, pc_start, ctx.nip - pc_start, flags);
7883         fprintf(logfile, "\n");
7884     }
7885 #endif
7886 }
7887
7888 void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
7889 {
7890     gen_intermediate_code_internal(env, tb, 0);
7891 }
7892
7893 void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
7894 {
7895     gen_intermediate_code_internal(env, tb, 1);
7896 }
7897
7898 void gen_pc_load(CPUState *env, TranslationBlock *tb,
7899                 unsigned long searched_pc, int pc_pos, void *puc)
7900 {
7901     env->nip = gen_opc_pc[pc_pos];
7902 }