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