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