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