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