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