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