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