1 /*
2  *  PowerPC emulation for qemu: main translation routines.
3  *
4  *  Copyright (c) 2003-2007 Jocelyn Mayer
5  *  Copyright (C) 2011 Freescale Semiconductor, Inc.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 #include "qemu/osdep.h"
22 #include "cpu.h"
23 #include "internal.h"
24 #include "disas/disas.h"
25 #include "exec/exec-all.h"
26 #include "tcg/tcg-op.h"
27 #include "tcg/tcg-op-gvec.h"
28 #include "qemu/host-utils.h"
29 #include "qemu/main-loop.h"
30 #include "exec/cpu_ldst.h"
31 
32 #include "exec/helper-proto.h"
33 #include "exec/helper-gen.h"
34 
35 #include "trace-tcg.h"
36 #include "exec/translator.h"
37 #include "exec/log.h"
38 #include "qemu/atomic128.h"
39 
40 
41 #define CPU_SINGLE_STEP 0x1
42 #define CPU_BRANCH_STEP 0x2
43 #define GDBSTUB_SINGLE_STEP 0x4
44 
45 /* Include definitions for instructions classes and implementations flags */
46 /* #define PPC_DEBUG_DISAS */
47 /* #define DO_PPC_STATISTICS */
48 
49 #ifdef PPC_DEBUG_DISAS
50 #  define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
51 #else
52 #  define LOG_DISAS(...) do { } while (0)
53 #endif
54 /*****************************************************************************/
55 /* Code translation helpers                                                  */
56 
57 /* global register indexes */
58 static char cpu_reg_names[10 * 3 + 22 * 4   /* GPR */
59                           + 10 * 4 + 22 * 5 /* SPE GPRh */
60                           + 8 * 5           /* CRF */];
61 static TCGv cpu_gpr[32];
62 static TCGv cpu_gprh[32];
63 static TCGv_i32 cpu_crf[8];
64 static TCGv cpu_nip;
65 static TCGv cpu_msr;
66 static TCGv cpu_ctr;
67 static TCGv cpu_lr;
68 #if defined(TARGET_PPC64)
69 static TCGv cpu_cfar;
70 #endif
71 static TCGv cpu_xer, cpu_so, cpu_ov, cpu_ca, cpu_ov32, cpu_ca32;
72 static TCGv cpu_reserve;
73 static TCGv cpu_reserve_val;
74 static TCGv cpu_fpscr;
75 static TCGv_i32 cpu_access_type;
76 
77 #include "exec/gen-icount.h"
78 
ppc_translate_init(void)79 void ppc_translate_init(void)
80 {
81     int i;
82     char *p;
83     size_t cpu_reg_names_size;
84 
85     p = cpu_reg_names;
86     cpu_reg_names_size = sizeof(cpu_reg_names);
87 
88     for (i = 0; i < 8; i++) {
89         snprintf(p, cpu_reg_names_size, "crf%d", i);
90         cpu_crf[i] = tcg_global_mem_new_i32(cpu_env,
91                                             offsetof(CPUPPCState, crf[i]), p);
92         p += 5;
93         cpu_reg_names_size -= 5;
94     }
95 
96     for (i = 0; i < 32; i++) {
97         snprintf(p, cpu_reg_names_size, "r%d", i);
98         cpu_gpr[i] = tcg_global_mem_new(cpu_env,
99                                         offsetof(CPUPPCState, gpr[i]), p);
100         p += (i < 10) ? 3 : 4;
101         cpu_reg_names_size -= (i < 10) ? 3 : 4;
102         snprintf(p, cpu_reg_names_size, "r%dH", i);
103         cpu_gprh[i] = tcg_global_mem_new(cpu_env,
104                                          offsetof(CPUPPCState, gprh[i]), p);
105         p += (i < 10) ? 4 : 5;
106         cpu_reg_names_size -= (i < 10) ? 4 : 5;
107     }
108 
109     cpu_nip = tcg_global_mem_new(cpu_env,
110                                  offsetof(CPUPPCState, nip), "nip");
111 
112     cpu_msr = tcg_global_mem_new(cpu_env,
113                                  offsetof(CPUPPCState, msr), "msr");
114 
115     cpu_ctr = tcg_global_mem_new(cpu_env,
116                                  offsetof(CPUPPCState, ctr), "ctr");
117 
118     cpu_lr = tcg_global_mem_new(cpu_env,
119                                 offsetof(CPUPPCState, lr), "lr");
120 
121 #if defined(TARGET_PPC64)
122     cpu_cfar = tcg_global_mem_new(cpu_env,
123                                   offsetof(CPUPPCState, cfar), "cfar");
124 #endif
125 
126     cpu_xer = tcg_global_mem_new(cpu_env,
127                                  offsetof(CPUPPCState, xer), "xer");
128     cpu_so = tcg_global_mem_new(cpu_env,
129                                 offsetof(CPUPPCState, so), "SO");
130     cpu_ov = tcg_global_mem_new(cpu_env,
131                                 offsetof(CPUPPCState, ov), "OV");
132     cpu_ca = tcg_global_mem_new(cpu_env,
133                                 offsetof(CPUPPCState, ca), "CA");
134     cpu_ov32 = tcg_global_mem_new(cpu_env,
135                                   offsetof(CPUPPCState, ov32), "OV32");
136     cpu_ca32 = tcg_global_mem_new(cpu_env,
137                                   offsetof(CPUPPCState, ca32), "CA32");
138 
139     cpu_reserve = tcg_global_mem_new(cpu_env,
140                                      offsetof(CPUPPCState, reserve_addr),
141                                      "reserve_addr");
142     cpu_reserve_val = tcg_global_mem_new(cpu_env,
143                                      offsetof(CPUPPCState, reserve_val),
144                                      "reserve_val");
145 
146     cpu_fpscr = tcg_global_mem_new(cpu_env,
147                                    offsetof(CPUPPCState, fpscr), "fpscr");
148 
149     cpu_access_type = tcg_global_mem_new_i32(cpu_env,
150                                              offsetof(CPUPPCState, access_type),
151                                              "access_type");
152 }
153 
154 /* internal defines */
155 struct DisasContext {
156     DisasContextBase base;
157     uint32_t opcode;
158     uint32_t exception;
159     /* Routine used to access memory */
160     bool pr, hv, dr, le_mode;
161     bool lazy_tlb_flush;
162     bool need_access_type;
163     int mem_idx;
164     int access_type;
165     /* Translation flags */
166     MemOp default_tcg_memop_mask;
167 #if defined(TARGET_PPC64)
168     bool sf_mode;
169     bool has_cfar;
170 #endif
171     bool fpu_enabled;
172     bool altivec_enabled;
173     bool vsx_enabled;
174     bool spe_enabled;
175     bool tm_enabled;
176     bool scv_enabled;
177     bool gtse;
178     ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
179     int singlestep_enabled;
180     uint32_t flags;
181     uint64_t insns_flags;
182     uint64_t insns_flags2;
183 };
184 
185 /* Return true iff byteswap is needed in a scalar memop */
need_byteswap(const DisasContext * ctx)186 static inline bool need_byteswap(const DisasContext *ctx)
187 {
188 #if defined(TARGET_WORDS_BIGENDIAN)
189      return ctx->le_mode;
190 #else
191      return !ctx->le_mode;
192 #endif
193 }
194 
195 /* True when active word size < size of target_long.  */
196 #ifdef TARGET_PPC64
197 # define NARROW_MODE(C)  (!(C)->sf_mode)
198 #else
199 # define NARROW_MODE(C)  0
200 #endif
201 
202 struct opc_handler_t {
203     /* invalid bits for instruction 1 (Rc(opcode) == 0) */
204     uint32_t inval1;
205     /* invalid bits for instruction 2 (Rc(opcode) == 1) */
206     uint32_t inval2;
207     /* instruction type */
208     uint64_t type;
209     /* extended instruction type */
210     uint64_t type2;
211     /* handler */
212     void (*handler)(DisasContext *ctx);
213 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
214     const char *oname;
215 #endif
216 #if defined(DO_PPC_STATISTICS)
217     uint64_t count;
218 #endif
219 };
220 
221 /* SPR load/store helpers */
gen_load_spr(TCGv t,int reg)222 static inline void gen_load_spr(TCGv t, int reg)
223 {
224     tcg_gen_ld_tl(t, cpu_env, offsetof(CPUPPCState, spr[reg]));
225 }
226 
gen_store_spr(int reg,TCGv t)227 static inline void gen_store_spr(int reg, TCGv t)
228 {
229     tcg_gen_st_tl(t, cpu_env, offsetof(CPUPPCState, spr[reg]));
230 }
231 
gen_set_access_type(DisasContext * ctx,int access_type)232 static inline void gen_set_access_type(DisasContext *ctx, int access_type)
233 {
234     if (ctx->need_access_type && ctx->access_type != access_type) {
235         tcg_gen_movi_i32(cpu_access_type, access_type);
236         ctx->access_type = access_type;
237     }
238 }
239 
gen_update_nip(DisasContext * ctx,target_ulong nip)240 static inline void gen_update_nip(DisasContext *ctx, target_ulong nip)
241 {
242     if (NARROW_MODE(ctx)) {
243         nip = (uint32_t)nip;
244     }
245     tcg_gen_movi_tl(cpu_nip, nip);
246 }
247 
gen_exception_err(DisasContext * ctx,uint32_t excp,uint32_t error)248 static void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t error)
249 {
250     TCGv_i32 t0, t1;
251 
252     /*
253      * These are all synchronous exceptions, we set the PC back to the
254      * faulting instruction
255      */
256     if (ctx->exception == POWERPC_EXCP_NONE) {
257         gen_update_nip(ctx, ctx->base.pc_next - 4);
258     }
259     t0 = tcg_const_i32(excp);
260     t1 = tcg_const_i32(error);
261     gen_helper_raise_exception_err(cpu_env, t0, t1);
262     tcg_temp_free_i32(t0);
263     tcg_temp_free_i32(t1);
264     ctx->exception = (excp);
265 }
266 
gen_exception(DisasContext * ctx,uint32_t excp)267 static void gen_exception(DisasContext *ctx, uint32_t excp)
268 {
269     TCGv_i32 t0;
270 
271     /*
272      * These are all synchronous exceptions, we set the PC back to the
273      * faulting instruction
274      */
275     if (ctx->exception == POWERPC_EXCP_NONE) {
276         gen_update_nip(ctx, ctx->base.pc_next - 4);
277     }
278     t0 = tcg_const_i32(excp);
279     gen_helper_raise_exception(cpu_env, t0);
280     tcg_temp_free_i32(t0);
281     ctx->exception = (excp);
282 }
283 
gen_exception_nip(DisasContext * ctx,uint32_t excp,target_ulong nip)284 static void gen_exception_nip(DisasContext *ctx, uint32_t excp,
285                               target_ulong nip)
286 {
287     TCGv_i32 t0;
288 
289     gen_update_nip(ctx, nip);
290     t0 = tcg_const_i32(excp);
291     gen_helper_raise_exception(cpu_env, t0);
292     tcg_temp_free_i32(t0);
293     ctx->exception = (excp);
294 }
295 
296 /*
297  * Tells the caller what is the appropriate exception to generate and prepares
298  * SPR registers for this exception.
299  *
300  * The exception can be either POWERPC_EXCP_TRACE (on most PowerPCs) or
301  * POWERPC_EXCP_DEBUG (on BookE).
302  */
gen_prep_dbgex(DisasContext * ctx)303 static uint32_t gen_prep_dbgex(DisasContext *ctx)
304 {
305     if (ctx->flags & POWERPC_FLAG_DE) {
306         target_ulong dbsr = 0;
307         if (ctx->singlestep_enabled & CPU_SINGLE_STEP) {
308             dbsr = DBCR0_ICMP;
309         } else {
310             /* Must have been branch */
311             dbsr = DBCR0_BRT;
312         }
313         TCGv t0 = tcg_temp_new();
314         gen_load_spr(t0, SPR_BOOKE_DBSR);
315         tcg_gen_ori_tl(t0, t0, dbsr);
316         gen_store_spr(SPR_BOOKE_DBSR, t0);
317         tcg_temp_free(t0);
318         return POWERPC_EXCP_DEBUG;
319     } else {
320         return POWERPC_EXCP_TRACE;
321     }
322 }
323 
gen_debug_exception(DisasContext * ctx)324 static void gen_debug_exception(DisasContext *ctx)
325 {
326     TCGv_i32 t0;
327 
328     /*
329      * These are all synchronous exceptions, we set the PC back to the
330      * faulting instruction
331      */
332     if ((ctx->exception != POWERPC_EXCP_BRANCH) &&
333         (ctx->exception != POWERPC_EXCP_SYNC)) {
334         gen_update_nip(ctx, ctx->base.pc_next);
335     }
336     t0 = tcg_const_i32(EXCP_DEBUG);
337     gen_helper_raise_exception(cpu_env, t0);
338     tcg_temp_free_i32(t0);
339 }
340 
gen_inval_exception(DisasContext * ctx,uint32_t error)341 static inline void gen_inval_exception(DisasContext *ctx, uint32_t error)
342 {
343     /* Will be converted to program check if needed */
344     gen_exception_err(ctx, POWERPC_EXCP_HV_EMU, POWERPC_EXCP_INVAL | error);
345 }
346 
gen_priv_exception(DisasContext * ctx,uint32_t error)347 static inline void gen_priv_exception(DisasContext *ctx, uint32_t error)
348 {
349     gen_exception_err(ctx, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_PRIV | error);
350 }
351 
gen_hvpriv_exception(DisasContext * ctx,uint32_t error)352 static inline void gen_hvpriv_exception(DisasContext *ctx, uint32_t error)
353 {
354     /* Will be converted to program check if needed */
355     gen_exception_err(ctx, POWERPC_EXCP_HV_EMU, POWERPC_EXCP_PRIV | error);
356 }
357 
358 /* Stop translation */
gen_stop_exception(DisasContext * ctx)359 static inline void gen_stop_exception(DisasContext *ctx)
360 {
361     gen_update_nip(ctx, ctx->base.pc_next);
362     ctx->exception = POWERPC_EXCP_STOP;
363 }
364 
365 #ifndef CONFIG_USER_ONLY
366 /* No need to update nip here, as execution flow will change */
gen_sync_exception(DisasContext * ctx)367 static inline void gen_sync_exception(DisasContext *ctx)
368 {
369     ctx->exception = POWERPC_EXCP_SYNC;
370 }
371 #endif
372 
373 #define GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                      \
374 GEN_OPCODE(name, opc1, opc2, opc3, inval, type, PPC_NONE)
375 
376 #define GEN_HANDLER_E(name, opc1, opc2, opc3, inval, type, type2)             \
377 GEN_OPCODE(name, opc1, opc2, opc3, inval, type, type2)
378 
379 #define GEN_HANDLER2(name, onam, opc1, opc2, opc3, inval, type)               \
380 GEN_OPCODE2(name, onam, opc1, opc2, opc3, inval, type, PPC_NONE)
381 
382 #define GEN_HANDLER2_E(name, onam, opc1, opc2, opc3, inval, type, type2)      \
383 GEN_OPCODE2(name, onam, opc1, opc2, opc3, inval, type, type2)
384 
385 #define GEN_HANDLER_E_2(name, opc1, opc2, opc3, opc4, inval, type, type2)     \
386 GEN_OPCODE3(name, opc1, opc2, opc3, opc4, inval, type, type2)
387 
388 #define GEN_HANDLER2_E_2(name, onam, opc1, opc2, opc3, opc4, inval, typ, typ2) \
389 GEN_OPCODE4(name, onam, opc1, opc2, opc3, opc4, inval, typ, typ2)
390 
391 typedef struct opcode_t {
392     unsigned char opc1, opc2, opc3, opc4;
393 #if HOST_LONG_BITS == 64 /* Explicitly align to 64 bits */
394     unsigned char pad[4];
395 #endif
396     opc_handler_t handler;
397     const char *oname;
398 } opcode_t;
399 
400 /* Helpers for priv. check */
401 #define GEN_PRIV                                                \
402     do {                                                        \
403         gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC); return; \
404     } while (0)
405 
406 #if defined(CONFIG_USER_ONLY)
407 #define CHK_HV GEN_PRIV
408 #define CHK_SV GEN_PRIV
409 #define CHK_HVRM GEN_PRIV
410 #else
411 #define CHK_HV                                                          \
412     do {                                                                \
413         if (unlikely(ctx->pr || !ctx->hv)) {                            \
414             GEN_PRIV;                                                   \
415         }                                                               \
416     } while (0)
417 #define CHK_SV                   \
418     do {                         \
419         if (unlikely(ctx->pr)) { \
420             GEN_PRIV;            \
421         }                        \
422     } while (0)
423 #define CHK_HVRM                                            \
424     do {                                                    \
425         if (unlikely(ctx->pr || !ctx->hv || ctx->dr)) {     \
426             GEN_PRIV;                                       \
427         }                                                   \
428     } while (0)
429 #endif
430 
431 #define CHK_NONE
432 
433 /*****************************************************************************/
434 /* PowerPC instructions table                                                */
435 
436 #if defined(DO_PPC_STATISTICS)
437 #define GEN_OPCODE(name, op1, op2, op3, invl, _typ, _typ2)                    \
438 {                                                                             \
439     .opc1 = op1,                                                              \
440     .opc2 = op2,                                                              \
441     .opc3 = op3,                                                              \
442     .opc4 = 0xff,                                                             \
443     .handler = {                                                              \
444         .inval1  = invl,                                                      \
445         .type = _typ,                                                         \
446         .type2 = _typ2,                                                       \
447         .handler = &gen_##name,                                               \
448         .oname = stringify(name),                                             \
449     },                                                                        \
450     .oname = stringify(name),                                                 \
451 }
452 #define GEN_OPCODE_DUAL(name, op1, op2, op3, invl1, invl2, _typ, _typ2)       \
453 {                                                                             \
454     .opc1 = op1,                                                              \
455     .opc2 = op2,                                                              \
456     .opc3 = op3,                                                              \
457     .opc4 = 0xff,                                                             \
458     .handler = {                                                              \
459         .inval1  = invl1,                                                     \
460         .inval2  = invl2,                                                     \
461         .type = _typ,                                                         \
462         .type2 = _typ2,                                                       \
463         .handler = &gen_##name,                                               \
464         .oname = stringify(name),                                             \
465     },                                                                        \
466     .oname = stringify(name),                                                 \
467 }
468 #define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ, _typ2)             \
469 {                                                                             \
470     .opc1 = op1,                                                              \
471     .opc2 = op2,                                                              \
472     .opc3 = op3,                                                              \
473     .opc4 = 0xff,                                                             \
474     .handler = {                                                              \
475         .inval1  = invl,                                                      \
476         .type = _typ,                                                         \
477         .type2 = _typ2,                                                       \
478         .handler = &gen_##name,                                               \
479         .oname = onam,                                                        \
480     },                                                                        \
481     .oname = onam,                                                            \
482 }
483 #define GEN_OPCODE3(name, op1, op2, op3, op4, invl, _typ, _typ2)              \
484 {                                                                             \
485     .opc1 = op1,                                                              \
486     .opc2 = op2,                                                              \
487     .opc3 = op3,                                                              \
488     .opc4 = op4,                                                              \
489     .handler = {                                                              \
490         .inval1  = invl,                                                      \
491         .type = _typ,                                                         \
492         .type2 = _typ2,                                                       \
493         .handler = &gen_##name,                                               \
494         .oname = stringify(name),                                             \
495     },                                                                        \
496     .oname = stringify(name),                                                 \
497 }
498 #define GEN_OPCODE4(name, onam, op1, op2, op3, op4, invl, _typ, _typ2)        \
499 {                                                                             \
500     .opc1 = op1,                                                              \
501     .opc2 = op2,                                                              \
502     .opc3 = op3,                                                              \
503     .opc4 = op4,                                                              \
504     .handler = {                                                              \
505         .inval1  = invl,                                                      \
506         .type = _typ,                                                         \
507         .type2 = _typ2,                                                       \
508         .handler = &gen_##name,                                               \
509         .oname = onam,                                                        \
510     },                                                                        \
511     .oname = onam,                                                            \
512 }
513 #else
514 #define GEN_OPCODE(name, op1, op2, op3, invl, _typ, _typ2)                    \
515 {                                                                             \
516     .opc1 = op1,                                                              \
517     .opc2 = op2,                                                              \
518     .opc3 = op3,                                                              \
519     .opc4 = 0xff,                                                             \
520     .handler = {                                                              \
521         .inval1  = invl,                                                      \
522         .type = _typ,                                                         \
523         .type2 = _typ2,                                                       \
524         .handler = &gen_##name,                                               \
525     },                                                                        \
526     .oname = stringify(name),                                                 \
527 }
528 #define GEN_OPCODE_DUAL(name, op1, op2, op3, invl1, invl2, _typ, _typ2)       \
529 {                                                                             \
530     .opc1 = op1,                                                              \
531     .opc2 = op2,                                                              \
532     .opc3 = op3,                                                              \
533     .opc4 = 0xff,                                                             \
534     .handler = {                                                              \
535         .inval1  = invl1,                                                     \
536         .inval2  = invl2,                                                     \
537         .type = _typ,                                                         \
538         .type2 = _typ2,                                                       \
539         .handler = &gen_##name,                                               \
540     },                                                                        \
541     .oname = stringify(name),                                                 \
542 }
543 #define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ, _typ2)             \
544 {                                                                             \
545     .opc1 = op1,                                                              \
546     .opc2 = op2,                                                              \
547     .opc3 = op3,                                                              \
548     .opc4 = 0xff,                                                             \
549     .handler = {                                                              \
550         .inval1  = invl,                                                      \
551         .type = _typ,                                                         \
552         .type2 = _typ2,                                                       \
553         .handler = &gen_##name,                                               \
554     },                                                                        \
555     .oname = onam,                                                            \
556 }
557 #define GEN_OPCODE3(name, op1, op2, op3, op4, invl, _typ, _typ2)              \
558 {                                                                             \
559     .opc1 = op1,                                                              \
560     .opc2 = op2,                                                              \
561     .opc3 = op3,                                                              \
562     .opc4 = op4,                                                              \
563     .handler = {                                                              \
564         .inval1  = invl,                                                      \
565         .type = _typ,                                                         \
566         .type2 = _typ2,                                                       \
567         .handler = &gen_##name,                                               \
568     },                                                                        \
569     .oname = stringify(name),                                                 \
570 }
571 #define GEN_OPCODE4(name, onam, op1, op2, op3, op4, invl, _typ, _typ2)        \
572 {                                                                             \
573     .opc1 = op1,                                                              \
574     .opc2 = op2,                                                              \
575     .opc3 = op3,                                                              \
576     .opc4 = op4,                                                              \
577     .handler = {                                                              \
578         .inval1  = invl,                                                      \
579         .type = _typ,                                                         \
580         .type2 = _typ2,                                                       \
581         .handler = &gen_##name,                                               \
582     },                                                                        \
583     .oname = onam,                                                            \
584 }
585 #endif
586 
587 /* Invalid instruction */
gen_invalid(DisasContext * ctx)588 static void gen_invalid(DisasContext *ctx)
589 {
590     gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
591 }
592 
593 static opc_handler_t invalid_handler = {
594     .inval1  = 0xFFFFFFFF,
595     .inval2  = 0xFFFFFFFF,
596     .type    = PPC_NONE,
597     .type2   = PPC_NONE,
598     .handler = gen_invalid,
599 };
600 
601 /***                           Integer comparison                          ***/
602 
gen_op_cmp(TCGv arg0,TCGv arg1,int s,int crf)603 static inline void gen_op_cmp(TCGv arg0, TCGv arg1, int s, int crf)
604 {
605     TCGv t0 = tcg_temp_new();
606     TCGv t1 = tcg_temp_new();
607     TCGv_i32 t = tcg_temp_new_i32();
608 
609     tcg_gen_movi_tl(t0, CRF_EQ);
610     tcg_gen_movi_tl(t1, CRF_LT);
611     tcg_gen_movcond_tl((s ? TCG_COND_LT : TCG_COND_LTU),
612                        t0, arg0, arg1, t1, t0);
613     tcg_gen_movi_tl(t1, CRF_GT);
614     tcg_gen_movcond_tl((s ? TCG_COND_GT : TCG_COND_GTU),
615                        t0, arg0, arg1, t1, t0);
616 
617     tcg_gen_trunc_tl_i32(t, t0);
618     tcg_gen_trunc_tl_i32(cpu_crf[crf], cpu_so);
619     tcg_gen_or_i32(cpu_crf[crf], cpu_crf[crf], t);
620 
621     tcg_temp_free(t0);
622     tcg_temp_free(t1);
623     tcg_temp_free_i32(t);
624 }
625 
gen_op_cmpi(TCGv arg0,target_ulong arg1,int s,int crf)626 static inline void gen_op_cmpi(TCGv arg0, target_ulong arg1, int s, int crf)
627 {
628     TCGv t0 = tcg_const_tl(arg1);
629     gen_op_cmp(arg0, t0, s, crf);
630     tcg_temp_free(t0);
631 }
632 
gen_op_cmp32(TCGv arg0,TCGv arg1,int s,int crf)633 static inline void gen_op_cmp32(TCGv arg0, TCGv arg1, int s, int crf)
634 {
635     TCGv t0, t1;
636     t0 = tcg_temp_new();
637     t1 = tcg_temp_new();
638     if (s) {
639         tcg_gen_ext32s_tl(t0, arg0);
640         tcg_gen_ext32s_tl(t1, arg1);
641     } else {
642         tcg_gen_ext32u_tl(t0, arg0);
643         tcg_gen_ext32u_tl(t1, arg1);
644     }
645     gen_op_cmp(t0, t1, s, crf);
646     tcg_temp_free(t1);
647     tcg_temp_free(t0);
648 }
649 
gen_op_cmpi32(TCGv arg0,target_ulong arg1,int s,int crf)650 static inline void gen_op_cmpi32(TCGv arg0, target_ulong arg1, int s, int crf)
651 {
652     TCGv t0 = tcg_const_tl(arg1);
653     gen_op_cmp32(arg0, t0, s, crf);
654     tcg_temp_free(t0);
655 }
656 
gen_set_Rc0(DisasContext * ctx,TCGv reg)657 static inline void gen_set_Rc0(DisasContext *ctx, TCGv reg)
658 {
659     if (NARROW_MODE(ctx)) {
660         gen_op_cmpi32(reg, 0, 1, 0);
661     } else {
662         gen_op_cmpi(reg, 0, 1, 0);
663     }
664 }
665 
666 /* cmp */
gen_cmp(DisasContext * ctx)667 static void gen_cmp(DisasContext *ctx)
668 {
669     if ((ctx->opcode & 0x00200000) && (ctx->insns_flags & PPC_64B)) {
670         gen_op_cmp(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
671                    1, crfD(ctx->opcode));
672     } else {
673         gen_op_cmp32(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
674                      1, crfD(ctx->opcode));
675     }
676 }
677 
678 /* cmpi */
gen_cmpi(DisasContext * ctx)679 static void gen_cmpi(DisasContext *ctx)
680 {
681     if ((ctx->opcode & 0x00200000) && (ctx->insns_flags & PPC_64B)) {
682         gen_op_cmpi(cpu_gpr[rA(ctx->opcode)], SIMM(ctx->opcode),
683                     1, crfD(ctx->opcode));
684     } else {
685         gen_op_cmpi32(cpu_gpr[rA(ctx->opcode)], SIMM(ctx->opcode),
686                       1, crfD(ctx->opcode));
687     }
688 }
689 
690 /* cmpl */
gen_cmpl(DisasContext * ctx)691 static void gen_cmpl(DisasContext *ctx)
692 {
693     if ((ctx->opcode & 0x00200000) && (ctx->insns_flags & PPC_64B)) {
694         gen_op_cmp(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
695                    0, crfD(ctx->opcode));
696     } else {
697         gen_op_cmp32(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
698                      0, crfD(ctx->opcode));
699     }
700 }
701 
702 /* cmpli */
gen_cmpli(DisasContext * ctx)703 static void gen_cmpli(DisasContext *ctx)
704 {
705     if ((ctx->opcode & 0x00200000) && (ctx->insns_flags & PPC_64B)) {
706         gen_op_cmpi(cpu_gpr[rA(ctx->opcode)], UIMM(ctx->opcode),
707                     0, crfD(ctx->opcode));
708     } else {
709         gen_op_cmpi32(cpu_gpr[rA(ctx->opcode)], UIMM(ctx->opcode),
710                       0, crfD(ctx->opcode));
711     }
712 }
713 
714 /* cmprb - range comparison: isupper, isaplha, islower*/
gen_cmprb(DisasContext * ctx)715 static void gen_cmprb(DisasContext *ctx)
716 {
717     TCGv_i32 src1 = tcg_temp_new_i32();
718     TCGv_i32 src2 = tcg_temp_new_i32();
719     TCGv_i32 src2lo = tcg_temp_new_i32();
720     TCGv_i32 src2hi = tcg_temp_new_i32();
721     TCGv_i32 crf = cpu_crf[crfD(ctx->opcode)];
722 
723     tcg_gen_trunc_tl_i32(src1, cpu_gpr[rA(ctx->opcode)]);
724     tcg_gen_trunc_tl_i32(src2, cpu_gpr[rB(ctx->opcode)]);
725 
726     tcg_gen_andi_i32(src1, src1, 0xFF);
727     tcg_gen_ext8u_i32(src2lo, src2);
728     tcg_gen_shri_i32(src2, src2, 8);
729     tcg_gen_ext8u_i32(src2hi, src2);
730 
731     tcg_gen_setcond_i32(TCG_COND_LEU, src2lo, src2lo, src1);
732     tcg_gen_setcond_i32(TCG_COND_LEU, src2hi, src1, src2hi);
733     tcg_gen_and_i32(crf, src2lo, src2hi);
734 
735     if (ctx->opcode & 0x00200000) {
736         tcg_gen_shri_i32(src2, src2, 8);
737         tcg_gen_ext8u_i32(src2lo, src2);
738         tcg_gen_shri_i32(src2, src2, 8);
739         tcg_gen_ext8u_i32(src2hi, src2);
740         tcg_gen_setcond_i32(TCG_COND_LEU, src2lo, src2lo, src1);
741         tcg_gen_setcond_i32(TCG_COND_LEU, src2hi, src1, src2hi);
742         tcg_gen_and_i32(src2lo, src2lo, src2hi);
743         tcg_gen_or_i32(crf, crf, src2lo);
744     }
745     tcg_gen_shli_i32(crf, crf, CRF_GT_BIT);
746     tcg_temp_free_i32(src1);
747     tcg_temp_free_i32(src2);
748     tcg_temp_free_i32(src2lo);
749     tcg_temp_free_i32(src2hi);
750 }
751 
752 #if defined(TARGET_PPC64)
753 /* cmpeqb */
gen_cmpeqb(DisasContext * ctx)754 static void gen_cmpeqb(DisasContext *ctx)
755 {
756     gen_helper_cmpeqb(cpu_crf[crfD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
757                       cpu_gpr[rB(ctx->opcode)]);
758 }
759 #endif
760 
761 /* isel (PowerPC 2.03 specification) */
gen_isel(DisasContext * ctx)762 static void gen_isel(DisasContext *ctx)
763 {
764     uint32_t bi = rC(ctx->opcode);
765     uint32_t mask = 0x08 >> (bi & 0x03);
766     TCGv t0 = tcg_temp_new();
767     TCGv zr;
768 
769     tcg_gen_extu_i32_tl(t0, cpu_crf[bi >> 2]);
770     tcg_gen_andi_tl(t0, t0, mask);
771 
772     zr = tcg_const_tl(0);
773     tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rD(ctx->opcode)], t0, zr,
774                        rA(ctx->opcode) ? cpu_gpr[rA(ctx->opcode)] : zr,
775                        cpu_gpr[rB(ctx->opcode)]);
776     tcg_temp_free(zr);
777     tcg_temp_free(t0);
778 }
779 
780 /* cmpb: PowerPC 2.05 specification */
gen_cmpb(DisasContext * ctx)781 static void gen_cmpb(DisasContext *ctx)
782 {
783     gen_helper_cmpb(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)],
784                     cpu_gpr[rB(ctx->opcode)]);
785 }
786 
787 /***                           Integer arithmetic                          ***/
788 
gen_op_arith_compute_ov(DisasContext * ctx,TCGv arg0,TCGv arg1,TCGv arg2,int sub)789 static inline void gen_op_arith_compute_ov(DisasContext *ctx, TCGv arg0,
790                                            TCGv arg1, TCGv arg2, int sub)
791 {
792     TCGv t0 = tcg_temp_new();
793 
794     tcg_gen_xor_tl(cpu_ov, arg0, arg2);
795     tcg_gen_xor_tl(t0, arg1, arg2);
796     if (sub) {
797         tcg_gen_and_tl(cpu_ov, cpu_ov, t0);
798     } else {
799         tcg_gen_andc_tl(cpu_ov, cpu_ov, t0);
800     }
801     tcg_temp_free(t0);
802     if (NARROW_MODE(ctx)) {
803         tcg_gen_extract_tl(cpu_ov, cpu_ov, 31, 1);
804         if (is_isa300(ctx)) {
805             tcg_gen_mov_tl(cpu_ov32, cpu_ov);
806         }
807     } else {
808         if (is_isa300(ctx)) {
809             tcg_gen_extract_tl(cpu_ov32, cpu_ov, 31, 1);
810         }
811         tcg_gen_extract_tl(cpu_ov, cpu_ov, TARGET_LONG_BITS - 1, 1);
812     }
813     tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov);
814 }
815 
gen_op_arith_compute_ca32(DisasContext * ctx,TCGv res,TCGv arg0,TCGv arg1,TCGv ca32,int sub)816 static inline void gen_op_arith_compute_ca32(DisasContext *ctx,
817                                              TCGv res, TCGv arg0, TCGv arg1,
818                                              TCGv ca32, int sub)
819 {
820     TCGv t0;
821 
822     if (!is_isa300(ctx)) {
823         return;
824     }
825 
826     t0 = tcg_temp_new();
827     if (sub) {
828         tcg_gen_eqv_tl(t0, arg0, arg1);
829     } else {
830         tcg_gen_xor_tl(t0, arg0, arg1);
831     }
832     tcg_gen_xor_tl(t0, t0, res);
833     tcg_gen_extract_tl(ca32, t0, 32, 1);
834     tcg_temp_free(t0);
835 }
836 
837 /* Common add function */
gen_op_arith_add(DisasContext * ctx,TCGv ret,TCGv arg1,TCGv arg2,TCGv ca,TCGv ca32,bool add_ca,bool compute_ca,bool compute_ov,bool compute_rc0)838 static inline void gen_op_arith_add(DisasContext *ctx, TCGv ret, TCGv arg1,
839                                     TCGv arg2, TCGv ca, TCGv ca32,
840                                     bool add_ca, bool compute_ca,
841                                     bool compute_ov, bool compute_rc0)
842 {
843     TCGv t0 = ret;
844 
845     if (compute_ca || compute_ov) {
846         t0 = tcg_temp_new();
847     }
848 
849     if (compute_ca) {
850         if (NARROW_MODE(ctx)) {
851             /*
852              * Caution: a non-obvious corner case of the spec is that
853              * we must produce the *entire* 64-bit addition, but
854              * produce the carry into bit 32.
855              */
856             TCGv t1 = tcg_temp_new();
857             tcg_gen_xor_tl(t1, arg1, arg2);        /* add without carry */
858             tcg_gen_add_tl(t0, arg1, arg2);
859             if (add_ca) {
860                 tcg_gen_add_tl(t0, t0, ca);
861             }
862             tcg_gen_xor_tl(ca, t0, t1);        /* bits changed w/ carry */
863             tcg_temp_free(t1);
864             tcg_gen_extract_tl(ca, ca, 32, 1);
865             if (is_isa300(ctx)) {
866                 tcg_gen_mov_tl(ca32, ca);
867             }
868         } else {
869             TCGv zero = tcg_const_tl(0);
870             if (add_ca) {
871                 tcg_gen_add2_tl(t0, ca, arg1, zero, ca, zero);
872                 tcg_gen_add2_tl(t0, ca, t0, ca, arg2, zero);
873             } else {
874                 tcg_gen_add2_tl(t0, ca, arg1, zero, arg2, zero);
875             }
876             gen_op_arith_compute_ca32(ctx, t0, arg1, arg2, ca32, 0);
877             tcg_temp_free(zero);
878         }
879     } else {
880         tcg_gen_add_tl(t0, arg1, arg2);
881         if (add_ca) {
882             tcg_gen_add_tl(t0, t0, ca);
883         }
884     }
885 
886     if (compute_ov) {
887         gen_op_arith_compute_ov(ctx, t0, arg1, arg2, 0);
888     }
889     if (unlikely(compute_rc0)) {
890         gen_set_Rc0(ctx, t0);
891     }
892 
893     if (t0 != ret) {
894         tcg_gen_mov_tl(ret, t0);
895         tcg_temp_free(t0);
896     }
897 }
898 /* Add functions with two operands */
899 #define GEN_INT_ARITH_ADD(name, opc3, ca, add_ca, compute_ca, compute_ov)     \
900 static void glue(gen_, name)(DisasContext *ctx)                               \
901 {                                                                             \
902     gen_op_arith_add(ctx, cpu_gpr[rD(ctx->opcode)],                           \
903                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],      \
904                      ca, glue(ca, 32),                                        \
905                      add_ca, compute_ca, compute_ov, Rc(ctx->opcode));        \
906 }
907 /* Add functions with one operand and one immediate */
908 #define GEN_INT_ARITH_ADD_CONST(name, opc3, const_val, ca,                    \
909                                 add_ca, compute_ca, compute_ov)               \
910 static void glue(gen_, name)(DisasContext *ctx)                               \
911 {                                                                             \
912     TCGv t0 = tcg_const_tl(const_val);                                        \
913     gen_op_arith_add(ctx, cpu_gpr[rD(ctx->opcode)],                           \
914                      cpu_gpr[rA(ctx->opcode)], t0,                            \
915                      ca, glue(ca, 32),                                        \
916                      add_ca, compute_ca, compute_ov, Rc(ctx->opcode));        \
917     tcg_temp_free(t0);                                                        \
918 }
919 
920 /* add  add.  addo  addo. */
921 GEN_INT_ARITH_ADD(add, 0x08, cpu_ca, 0, 0, 0)
922 GEN_INT_ARITH_ADD(addo, 0x18, cpu_ca, 0, 0, 1)
923 /* addc  addc.  addco  addco. */
924 GEN_INT_ARITH_ADD(addc, 0x00, cpu_ca, 0, 1, 0)
925 GEN_INT_ARITH_ADD(addco, 0x10, cpu_ca, 0, 1, 1)
926 /* adde  adde.  addeo  addeo. */
927 GEN_INT_ARITH_ADD(adde, 0x04, cpu_ca, 1, 1, 0)
928 GEN_INT_ARITH_ADD(addeo, 0x14, cpu_ca, 1, 1, 1)
929 /* addme  addme.  addmeo  addmeo.  */
930 GEN_INT_ARITH_ADD_CONST(addme, 0x07, -1LL, cpu_ca, 1, 1, 0)
931 GEN_INT_ARITH_ADD_CONST(addmeo, 0x17, -1LL, cpu_ca, 1, 1, 1)
932 /* addex */
933 GEN_INT_ARITH_ADD(addex, 0x05, cpu_ov, 1, 1, 0);
934 /* addze  addze.  addzeo  addzeo.*/
935 GEN_INT_ARITH_ADD_CONST(addze, 0x06, 0, cpu_ca, 1, 1, 0)
936 GEN_INT_ARITH_ADD_CONST(addzeo, 0x16, 0, cpu_ca, 1, 1, 1)
937 /* addi */
gen_addi(DisasContext * ctx)938 static void gen_addi(DisasContext *ctx)
939 {
940     target_long simm = SIMM(ctx->opcode);
941 
942     if (rA(ctx->opcode) == 0) {
943         /* li case */
944         tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], simm);
945     } else {
946         tcg_gen_addi_tl(cpu_gpr[rD(ctx->opcode)],
947                         cpu_gpr[rA(ctx->opcode)], simm);
948     }
949 }
950 /* addic  addic.*/
gen_op_addic(DisasContext * ctx,bool compute_rc0)951 static inline void gen_op_addic(DisasContext *ctx, bool compute_rc0)
952 {
953     TCGv c = tcg_const_tl(SIMM(ctx->opcode));
954     gen_op_arith_add(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
955                      c, cpu_ca, cpu_ca32, 0, 1, 0, compute_rc0);
956     tcg_temp_free(c);
957 }
958 
gen_addic(DisasContext * ctx)959 static void gen_addic(DisasContext *ctx)
960 {
961     gen_op_addic(ctx, 0);
962 }
963 
gen_addic_(DisasContext * ctx)964 static void gen_addic_(DisasContext *ctx)
965 {
966     gen_op_addic(ctx, 1);
967 }
968 
969 /* addis */
gen_addis(DisasContext * ctx)970 static void gen_addis(DisasContext *ctx)
971 {
972     target_long simm = SIMM(ctx->opcode);
973 
974     if (rA(ctx->opcode) == 0) {
975         /* lis case */
976         tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], simm << 16);
977     } else {
978         tcg_gen_addi_tl(cpu_gpr[rD(ctx->opcode)],
979                         cpu_gpr[rA(ctx->opcode)], simm << 16);
980     }
981 }
982 
983 /* addpcis */
gen_addpcis(DisasContext * ctx)984 static void gen_addpcis(DisasContext *ctx)
985 {
986     target_long d = DX(ctx->opcode);
987 
988     tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], ctx->base.pc_next + (d << 16));
989 }
990 
gen_op_arith_divw(DisasContext * ctx,TCGv ret,TCGv arg1,TCGv arg2,int sign,int compute_ov)991 static inline void gen_op_arith_divw(DisasContext *ctx, TCGv ret, TCGv arg1,
992                                      TCGv arg2, int sign, int compute_ov)
993 {
994     TCGv_i32 t0 = tcg_temp_new_i32();
995     TCGv_i32 t1 = tcg_temp_new_i32();
996     TCGv_i32 t2 = tcg_temp_new_i32();
997     TCGv_i32 t3 = tcg_temp_new_i32();
998 
999     tcg_gen_trunc_tl_i32(t0, arg1);
1000     tcg_gen_trunc_tl_i32(t1, arg2);
1001     if (sign) {
1002         tcg_gen_setcondi_i32(TCG_COND_EQ, t2, t0, INT_MIN);
1003         tcg_gen_setcondi_i32(TCG_COND_EQ, t3, t1, -1);
1004         tcg_gen_and_i32(t2, t2, t3);
1005         tcg_gen_setcondi_i32(TCG_COND_EQ, t3, t1, 0);
1006         tcg_gen_or_i32(t2, t2, t3);
1007         tcg_gen_movi_i32(t3, 0);
1008         tcg_gen_movcond_i32(TCG_COND_NE, t1, t2, t3, t2, t1);
1009         tcg_gen_div_i32(t3, t0, t1);
1010         tcg_gen_extu_i32_tl(ret, t3);
1011     } else {
1012         tcg_gen_setcondi_i32(TCG_COND_EQ, t2, t1, 0);
1013         tcg_gen_movi_i32(t3, 0);
1014         tcg_gen_movcond_i32(TCG_COND_NE, t1, t2, t3, t2, t1);
1015         tcg_gen_divu_i32(t3, t0, t1);
1016         tcg_gen_extu_i32_tl(ret, t3);
1017     }
1018     if (compute_ov) {
1019         tcg_gen_extu_i32_tl(cpu_ov, t2);
1020         if (is_isa300(ctx)) {
1021             tcg_gen_extu_i32_tl(cpu_ov32, t2);
1022         }
1023         tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov);
1024     }
1025     tcg_temp_free_i32(t0);
1026     tcg_temp_free_i32(t1);
1027     tcg_temp_free_i32(t2);
1028     tcg_temp_free_i32(t3);
1029 
1030     if (unlikely(Rc(ctx->opcode) != 0)) {
1031         gen_set_Rc0(ctx, ret);
1032     }
1033 }
1034 /* Div functions */
1035 #define GEN_INT_ARITH_DIVW(name, opc3, sign, compute_ov)                      \
1036 static void glue(gen_, name)(DisasContext *ctx)                               \
1037 {                                                                             \
1038     gen_op_arith_divw(ctx, cpu_gpr[rD(ctx->opcode)],                          \
1039                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],      \
1040                      sign, compute_ov);                                       \
1041 }
1042 /* divwu  divwu.  divwuo  divwuo.   */
1043 GEN_INT_ARITH_DIVW(divwu, 0x0E, 0, 0);
1044 GEN_INT_ARITH_DIVW(divwuo, 0x1E, 0, 1);
1045 /* divw  divw.  divwo  divwo.   */
1046 GEN_INT_ARITH_DIVW(divw, 0x0F, 1, 0);
1047 GEN_INT_ARITH_DIVW(divwo, 0x1F, 1, 1);
1048 
1049 /* div[wd]eu[o][.] */
1050 #define GEN_DIVE(name, hlpr, compute_ov)                                      \
1051 static void gen_##name(DisasContext *ctx)                                     \
1052 {                                                                             \
1053     TCGv_i32 t0 = tcg_const_i32(compute_ov);                                  \
1054     gen_helper_##hlpr(cpu_gpr[rD(ctx->opcode)], cpu_env,                      \
1055                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], t0); \
1056     tcg_temp_free_i32(t0);                                                    \
1057     if (unlikely(Rc(ctx->opcode) != 0)) {                                     \
1058         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);                           \
1059     }                                                                         \
1060 }
1061 
1062 GEN_DIVE(divweu, divweu, 0);
1063 GEN_DIVE(divweuo, divweu, 1);
1064 GEN_DIVE(divwe, divwe, 0);
1065 GEN_DIVE(divweo, divwe, 1);
1066 
1067 #if defined(TARGET_PPC64)
gen_op_arith_divd(DisasContext * ctx,TCGv ret,TCGv arg1,TCGv arg2,int sign,int compute_ov)1068 static inline void gen_op_arith_divd(DisasContext *ctx, TCGv ret, TCGv arg1,
1069                                      TCGv arg2, int sign, int compute_ov)
1070 {
1071     TCGv_i64 t0 = tcg_temp_new_i64();
1072     TCGv_i64 t1 = tcg_temp_new_i64();
1073     TCGv_i64 t2 = tcg_temp_new_i64();
1074     TCGv_i64 t3 = tcg_temp_new_i64();
1075 
1076     tcg_gen_mov_i64(t0, arg1);
1077     tcg_gen_mov_i64(t1, arg2);
1078     if (sign) {
1079         tcg_gen_setcondi_i64(TCG_COND_EQ, t2, t0, INT64_MIN);
1080         tcg_gen_setcondi_i64(TCG_COND_EQ, t3, t1, -1);
1081         tcg_gen_and_i64(t2, t2, t3);
1082         tcg_gen_setcondi_i64(TCG_COND_EQ, t3, t1, 0);
1083         tcg_gen_or_i64(t2, t2, t3);
1084         tcg_gen_movi_i64(t3, 0);
1085         tcg_gen_movcond_i64(TCG_COND_NE, t1, t2, t3, t2, t1);
1086         tcg_gen_div_i64(ret, t0, t1);
1087     } else {
1088         tcg_gen_setcondi_i64(TCG_COND_EQ, t2, t1, 0);
1089         tcg_gen_movi_i64(t3, 0);
1090         tcg_gen_movcond_i64(TCG_COND_NE, t1, t2, t3, t2, t1);
1091         tcg_gen_divu_i64(ret, t0, t1);
1092     }
1093     if (compute_ov) {
1094         tcg_gen_mov_tl(cpu_ov, t2);
1095         if (is_isa300(ctx)) {
1096             tcg_gen_mov_tl(cpu_ov32, t2);
1097         }
1098         tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov);
1099     }
1100     tcg_temp_free_i64(t0);
1101     tcg_temp_free_i64(t1);
1102     tcg_temp_free_i64(t2);
1103     tcg_temp_free_i64(t3);
1104 
1105     if (unlikely(Rc(ctx->opcode) != 0)) {
1106         gen_set_Rc0(ctx, ret);
1107     }
1108 }
1109 
1110 #define GEN_INT_ARITH_DIVD(name, opc3, sign, compute_ov)                      \
1111 static void glue(gen_, name)(DisasContext *ctx)                               \
1112 {                                                                             \
1113     gen_op_arith_divd(ctx, cpu_gpr[rD(ctx->opcode)],                          \
1114                       cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],     \
1115                       sign, compute_ov);                                      \
1116 }
1117 /* divdu  divdu.  divduo  divduo.   */
1118 GEN_INT_ARITH_DIVD(divdu, 0x0E, 0, 0);
1119 GEN_INT_ARITH_DIVD(divduo, 0x1E, 0, 1);
1120 /* divd  divd.  divdo  divdo.   */
1121 GEN_INT_ARITH_DIVD(divd, 0x0F, 1, 0);
1122 GEN_INT_ARITH_DIVD(divdo, 0x1F, 1, 1);
1123 
1124 GEN_DIVE(divdeu, divdeu, 0);
1125 GEN_DIVE(divdeuo, divdeu, 1);
1126 GEN_DIVE(divde, divde, 0);
1127 GEN_DIVE(divdeo, divde, 1);
1128 #endif
1129 
gen_op_arith_modw(DisasContext * ctx,TCGv ret,TCGv arg1,TCGv arg2,int sign)1130 static inline void gen_op_arith_modw(DisasContext *ctx, TCGv ret, TCGv arg1,
1131                                      TCGv arg2, int sign)
1132 {
1133     TCGv_i32 t0 = tcg_temp_new_i32();
1134     TCGv_i32 t1 = tcg_temp_new_i32();
1135 
1136     tcg_gen_trunc_tl_i32(t0, arg1);
1137     tcg_gen_trunc_tl_i32(t1, arg2);
1138     if (sign) {
1139         TCGv_i32 t2 = tcg_temp_new_i32();
1140         TCGv_i32 t3 = tcg_temp_new_i32();
1141         tcg_gen_setcondi_i32(TCG_COND_EQ, t2, t0, INT_MIN);
1142         tcg_gen_setcondi_i32(TCG_COND_EQ, t3, t1, -1);
1143         tcg_gen_and_i32(t2, t2, t3);
1144         tcg_gen_setcondi_i32(TCG_COND_EQ, t3, t1, 0);
1145         tcg_gen_or_i32(t2, t2, t3);
1146         tcg_gen_movi_i32(t3, 0);
1147         tcg_gen_movcond_i32(TCG_COND_NE, t1, t2, t3, t2, t1);
1148         tcg_gen_rem_i32(t3, t0, t1);
1149         tcg_gen_ext_i32_tl(ret, t3);
1150         tcg_temp_free_i32(t2);
1151         tcg_temp_free_i32(t3);
1152     } else {
1153         TCGv_i32 t2 = tcg_const_i32(1);
1154         TCGv_i32 t3 = tcg_const_i32(0);
1155         tcg_gen_movcond_i32(TCG_COND_EQ, t1, t1, t3, t2, t1);
1156         tcg_gen_remu_i32(t3, t0, t1);
1157         tcg_gen_extu_i32_tl(ret, t3);
1158         tcg_temp_free_i32(t2);
1159         tcg_temp_free_i32(t3);
1160     }
1161     tcg_temp_free_i32(t0);
1162     tcg_temp_free_i32(t1);
1163 }
1164 
1165 #define GEN_INT_ARITH_MODW(name, opc3, sign)                                \
1166 static void glue(gen_, name)(DisasContext *ctx)                             \
1167 {                                                                           \
1168     gen_op_arith_modw(ctx, cpu_gpr[rD(ctx->opcode)],                        \
1169                       cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],   \
1170                       sign);                                                \
1171 }
1172 
1173 GEN_INT_ARITH_MODW(moduw, 0x08, 0);
1174 GEN_INT_ARITH_MODW(modsw, 0x18, 1);
1175 
1176 #if defined(TARGET_PPC64)
gen_op_arith_modd(DisasContext * ctx,TCGv ret,TCGv arg1,TCGv arg2,int sign)1177 static inline void gen_op_arith_modd(DisasContext *ctx, TCGv ret, TCGv arg1,
1178                                      TCGv arg2, int sign)
1179 {
1180     TCGv_i64 t0 = tcg_temp_new_i64();
1181     TCGv_i64 t1 = tcg_temp_new_i64();
1182 
1183     tcg_gen_mov_i64(t0, arg1);
1184     tcg_gen_mov_i64(t1, arg2);
1185     if (sign) {
1186         TCGv_i64 t2 = tcg_temp_new_i64();
1187         TCGv_i64 t3 = tcg_temp_new_i64();
1188         tcg_gen_setcondi_i64(TCG_COND_EQ, t2, t0, INT64_MIN);
1189         tcg_gen_setcondi_i64(TCG_COND_EQ, t3, t1, -1);
1190         tcg_gen_and_i64(t2, t2, t3);
1191         tcg_gen_setcondi_i64(TCG_COND_EQ, t3, t1, 0);
1192         tcg_gen_or_i64(t2, t2, t3);
1193         tcg_gen_movi_i64(t3, 0);
1194         tcg_gen_movcond_i64(TCG_COND_NE, t1, t2, t3, t2, t1);
1195         tcg_gen_rem_i64(ret, t0, t1);
1196         tcg_temp_free_i64(t2);
1197         tcg_temp_free_i64(t3);
1198     } else {
1199         TCGv_i64 t2 = tcg_const_i64(1);
1200         TCGv_i64 t3 = tcg_const_i64(0);
1201         tcg_gen_movcond_i64(TCG_COND_EQ, t1, t1, t3, t2, t1);
1202         tcg_gen_remu_i64(ret, t0, t1);
1203         tcg_temp_free_i64(t2);
1204         tcg_temp_free_i64(t3);
1205     }
1206     tcg_temp_free_i64(t0);
1207     tcg_temp_free_i64(t1);
1208 }
1209 
1210 #define GEN_INT_ARITH_MODD(name, opc3, sign)                            \
1211 static void glue(gen_, name)(DisasContext *ctx)                           \
1212 {                                                                         \
1213   gen_op_arith_modd(ctx, cpu_gpr[rD(ctx->opcode)],                        \
1214                     cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],   \
1215                     sign);                                                \
1216 }
1217 
1218 GEN_INT_ARITH_MODD(modud, 0x08, 0);
1219 GEN_INT_ARITH_MODD(modsd, 0x18, 1);
1220 #endif
1221 
1222 /* mulhw  mulhw. */
gen_mulhw(DisasContext * ctx)1223 static void gen_mulhw(DisasContext *ctx)
1224 {
1225     TCGv_i32 t0 = tcg_temp_new_i32();
1226     TCGv_i32 t1 = tcg_temp_new_i32();
1227 
1228     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);
1229     tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);
1230     tcg_gen_muls2_i32(t0, t1, t0, t1);
1231     tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t1);
1232     tcg_temp_free_i32(t0);
1233     tcg_temp_free_i32(t1);
1234     if (unlikely(Rc(ctx->opcode) != 0)) {
1235         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1236     }
1237 }
1238 
1239 /* mulhwu  mulhwu.  */
gen_mulhwu(DisasContext * ctx)1240 static void gen_mulhwu(DisasContext *ctx)
1241 {
1242     TCGv_i32 t0 = tcg_temp_new_i32();
1243     TCGv_i32 t1 = tcg_temp_new_i32();
1244 
1245     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);
1246     tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);
1247     tcg_gen_mulu2_i32(t0, t1, t0, t1);
1248     tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t1);
1249     tcg_temp_free_i32(t0);
1250     tcg_temp_free_i32(t1);
1251     if (unlikely(Rc(ctx->opcode) != 0)) {
1252         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1253     }
1254 }
1255 
1256 /* mullw  mullw. */
gen_mullw(DisasContext * ctx)1257 static void gen_mullw(DisasContext *ctx)
1258 {
1259 #if defined(TARGET_PPC64)
1260     TCGv_i64 t0, t1;
1261     t0 = tcg_temp_new_i64();
1262     t1 = tcg_temp_new_i64();
1263     tcg_gen_ext32s_tl(t0, cpu_gpr[rA(ctx->opcode)]);
1264     tcg_gen_ext32s_tl(t1, cpu_gpr[rB(ctx->opcode)]);
1265     tcg_gen_mul_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);
1266     tcg_temp_free(t0);
1267     tcg_temp_free(t1);
1268 #else
1269     tcg_gen_mul_i32(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
1270                     cpu_gpr[rB(ctx->opcode)]);
1271 #endif
1272     if (unlikely(Rc(ctx->opcode) != 0)) {
1273         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1274     }
1275 }
1276 
1277 /* mullwo  mullwo. */
gen_mullwo(DisasContext * ctx)1278 static void gen_mullwo(DisasContext *ctx)
1279 {
1280     TCGv_i32 t0 = tcg_temp_new_i32();
1281     TCGv_i32 t1 = tcg_temp_new_i32();
1282 
1283     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);
1284     tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);
1285     tcg_gen_muls2_i32(t0, t1, t0, t1);
1286 #if defined(TARGET_PPC64)
1287     tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);
1288 #else
1289     tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], t0);
1290 #endif
1291 
1292     tcg_gen_sari_i32(t0, t0, 31);
1293     tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t1);
1294     tcg_gen_extu_i32_tl(cpu_ov, t0);
1295     if (is_isa300(ctx)) {
1296         tcg_gen_mov_tl(cpu_ov32, cpu_ov);
1297     }
1298     tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov);
1299 
1300     tcg_temp_free_i32(t0);
1301     tcg_temp_free_i32(t1);
1302     if (unlikely(Rc(ctx->opcode) != 0)) {
1303         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1304     }
1305 }
1306 
1307 /* mulli */
gen_mulli(DisasContext * ctx)1308 static void gen_mulli(DisasContext *ctx)
1309 {
1310     tcg_gen_muli_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
1311                     SIMM(ctx->opcode));
1312 }
1313 
1314 #if defined(TARGET_PPC64)
1315 /* mulhd  mulhd. */
gen_mulhd(DisasContext * ctx)1316 static void gen_mulhd(DisasContext *ctx)
1317 {
1318     TCGv lo = tcg_temp_new();
1319     tcg_gen_muls2_tl(lo, cpu_gpr[rD(ctx->opcode)],
1320                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1321     tcg_temp_free(lo);
1322     if (unlikely(Rc(ctx->opcode) != 0)) {
1323         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1324     }
1325 }
1326 
1327 /* mulhdu  mulhdu. */
gen_mulhdu(DisasContext * ctx)1328 static void gen_mulhdu(DisasContext *ctx)
1329 {
1330     TCGv lo = tcg_temp_new();
1331     tcg_gen_mulu2_tl(lo, cpu_gpr[rD(ctx->opcode)],
1332                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1333     tcg_temp_free(lo);
1334     if (unlikely(Rc(ctx->opcode) != 0)) {
1335         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1336     }
1337 }
1338 
1339 /* mulld  mulld. */
gen_mulld(DisasContext * ctx)1340 static void gen_mulld(DisasContext *ctx)
1341 {
1342     tcg_gen_mul_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
1343                    cpu_gpr[rB(ctx->opcode)]);
1344     if (unlikely(Rc(ctx->opcode) != 0)) {
1345         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1346     }
1347 }
1348 
1349 /* mulldo  mulldo. */
gen_mulldo(DisasContext * ctx)1350 static void gen_mulldo(DisasContext *ctx)
1351 {
1352     TCGv_i64 t0 = tcg_temp_new_i64();
1353     TCGv_i64 t1 = tcg_temp_new_i64();
1354 
1355     tcg_gen_muls2_i64(t0, t1, cpu_gpr[rA(ctx->opcode)],
1356                       cpu_gpr[rB(ctx->opcode)]);
1357     tcg_gen_mov_i64(cpu_gpr[rD(ctx->opcode)], t0);
1358 
1359     tcg_gen_sari_i64(t0, t0, 63);
1360     tcg_gen_setcond_i64(TCG_COND_NE, cpu_ov, t0, t1);
1361     if (is_isa300(ctx)) {
1362         tcg_gen_mov_tl(cpu_ov32, cpu_ov);
1363     }
1364     tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov);
1365 
1366     tcg_temp_free_i64(t0);
1367     tcg_temp_free_i64(t1);
1368 
1369     if (unlikely(Rc(ctx->opcode) != 0)) {
1370         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1371     }
1372 }
1373 #endif
1374 
1375 /* Common subf function */
gen_op_arith_subf(DisasContext * ctx,TCGv ret,TCGv arg1,TCGv arg2,bool add_ca,bool compute_ca,bool compute_ov,bool compute_rc0)1376 static inline void gen_op_arith_subf(DisasContext *ctx, TCGv ret, TCGv arg1,
1377                                      TCGv arg2, bool add_ca, bool compute_ca,
1378                                      bool compute_ov, bool compute_rc0)
1379 {
1380     TCGv t0 = ret;
1381 
1382     if (compute_ca || compute_ov) {
1383         t0 = tcg_temp_new();
1384     }
1385 
1386     if (compute_ca) {
1387         /* dest = ~arg1 + arg2 [+ ca].  */
1388         if (NARROW_MODE(ctx)) {
1389             /*
1390              * Caution: a non-obvious corner case of the spec is that
1391              * we must produce the *entire* 64-bit addition, but
1392              * produce the carry into bit 32.
1393              */
1394             TCGv inv1 = tcg_temp_new();
1395             TCGv t1 = tcg_temp_new();
1396             tcg_gen_not_tl(inv1, arg1);
1397             if (add_ca) {
1398                 tcg_gen_add_tl(t0, arg2, cpu_ca);
1399             } else {
1400                 tcg_gen_addi_tl(t0, arg2, 1);
1401             }
1402             tcg_gen_xor_tl(t1, arg2, inv1);         /* add without carry */
1403             tcg_gen_add_tl(t0, t0, inv1);
1404             tcg_temp_free(inv1);
1405             tcg_gen_xor_tl(cpu_ca, t0, t1);         /* bits changes w/ carry */
1406             tcg_temp_free(t1);
1407             tcg_gen_extract_tl(cpu_ca, cpu_ca, 32, 1);
1408             if (is_isa300(ctx)) {
1409                 tcg_gen_mov_tl(cpu_ca32, cpu_ca);
1410             }
1411         } else if (add_ca) {
1412             TCGv zero, inv1 = tcg_temp_new();
1413             tcg_gen_not_tl(inv1, arg1);
1414             zero = tcg_const_tl(0);
1415             tcg_gen_add2_tl(t0, cpu_ca, arg2, zero, cpu_ca, zero);
1416             tcg_gen_add2_tl(t0, cpu_ca, t0, cpu_ca, inv1, zero);
1417             gen_op_arith_compute_ca32(ctx, t0, inv1, arg2, cpu_ca32, 0);
1418             tcg_temp_free(zero);
1419             tcg_temp_free(inv1);
1420         } else {
1421             tcg_gen_setcond_tl(TCG_COND_GEU, cpu_ca, arg2, arg1);
1422             tcg_gen_sub_tl(t0, arg2, arg1);
1423             gen_op_arith_compute_ca32(ctx, t0, arg1, arg2, cpu_ca32, 1);
1424         }
1425     } else if (add_ca) {
1426         /*
1427          * Since we're ignoring carry-out, we can simplify the
1428          * standard ~arg1 + arg2 + ca to arg2 - arg1 + ca - 1.
1429          */
1430         tcg_gen_sub_tl(t0, arg2, arg1);
1431         tcg_gen_add_tl(t0, t0, cpu_ca);
1432         tcg_gen_subi_tl(t0, t0, 1);
1433     } else {
1434         tcg_gen_sub_tl(t0, arg2, arg1);
1435     }
1436 
1437     if (compute_ov) {
1438         gen_op_arith_compute_ov(ctx, t0, arg1, arg2, 1);
1439     }
1440     if (unlikely(compute_rc0)) {
1441         gen_set_Rc0(ctx, t0);
1442     }
1443 
1444     if (t0 != ret) {
1445         tcg_gen_mov_tl(ret, t0);
1446         tcg_temp_free(t0);
1447     }
1448 }
1449 /* Sub functions with Two operands functions */
1450 #define GEN_INT_ARITH_SUBF(name, opc3, add_ca, compute_ca, compute_ov)        \
1451 static void glue(gen_, name)(DisasContext *ctx)                               \
1452 {                                                                             \
1453     gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)],                          \
1454                       cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],     \
1455                       add_ca, compute_ca, compute_ov, Rc(ctx->opcode));       \
1456 }
1457 /* Sub functions with one operand and one immediate */
1458 #define GEN_INT_ARITH_SUBF_CONST(name, opc3, const_val,                       \
1459                                 add_ca, compute_ca, compute_ov)               \
1460 static void glue(gen_, name)(DisasContext *ctx)                               \
1461 {                                                                             \
1462     TCGv t0 = tcg_const_tl(const_val);                                        \
1463     gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)],                          \
1464                       cpu_gpr[rA(ctx->opcode)], t0,                           \
1465                       add_ca, compute_ca, compute_ov, Rc(ctx->opcode));       \
1466     tcg_temp_free(t0);                                                        \
1467 }
1468 /* subf  subf.  subfo  subfo. */
1469 GEN_INT_ARITH_SUBF(subf, 0x01, 0, 0, 0)
1470 GEN_INT_ARITH_SUBF(subfo, 0x11, 0, 0, 1)
1471 /* subfc  subfc.  subfco  subfco. */
1472 GEN_INT_ARITH_SUBF(subfc, 0x00, 0, 1, 0)
1473 GEN_INT_ARITH_SUBF(subfco, 0x10, 0, 1, 1)
1474 /* subfe  subfe.  subfeo  subfo. */
1475 GEN_INT_ARITH_SUBF(subfe, 0x04, 1, 1, 0)
1476 GEN_INT_ARITH_SUBF(subfeo, 0x14, 1, 1, 1)
1477 /* subfme  subfme.  subfmeo  subfmeo.  */
1478 GEN_INT_ARITH_SUBF_CONST(subfme, 0x07, -1LL, 1, 1, 0)
1479 GEN_INT_ARITH_SUBF_CONST(subfmeo, 0x17, -1LL, 1, 1, 1)
1480 /* subfze  subfze.  subfzeo  subfzeo.*/
1481 GEN_INT_ARITH_SUBF_CONST(subfze, 0x06, 0, 1, 1, 0)
1482 GEN_INT_ARITH_SUBF_CONST(subfzeo, 0x16, 0, 1, 1, 1)
1483 
1484 /* subfic */
gen_subfic(DisasContext * ctx)1485 static void gen_subfic(DisasContext *ctx)
1486 {
1487     TCGv c = tcg_const_tl(SIMM(ctx->opcode));
1488     gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
1489                       c, 0, 1, 0, 0);
1490     tcg_temp_free(c);
1491 }
1492 
1493 /* neg neg. nego nego. */
gen_op_arith_neg(DisasContext * ctx,bool compute_ov)1494 static inline void gen_op_arith_neg(DisasContext *ctx, bool compute_ov)
1495 {
1496     TCGv zero = tcg_const_tl(0);
1497     gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
1498                       zero, 0, 0, compute_ov, Rc(ctx->opcode));
1499     tcg_temp_free(zero);
1500 }
1501 
gen_neg(DisasContext * ctx)1502 static void gen_neg(DisasContext *ctx)
1503 {
1504     tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
1505     if (unlikely(Rc(ctx->opcode))) {
1506         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1507     }
1508 }
1509 
gen_nego(DisasContext * ctx)1510 static void gen_nego(DisasContext *ctx)
1511 {
1512     gen_op_arith_neg(ctx, 1);
1513 }
1514 
1515 /***                            Integer logical                            ***/
1516 #define GEN_LOGICAL2(name, tcg_op, opc, type)                                 \
1517 static void glue(gen_, name)(DisasContext *ctx)                               \
1518 {                                                                             \
1519     tcg_op(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)],                \
1520        cpu_gpr[rB(ctx->opcode)]);                                             \
1521     if (unlikely(Rc(ctx->opcode) != 0))                                       \
1522         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);                           \
1523 }
1524 
1525 #define GEN_LOGICAL1(name, tcg_op, opc, type)                                 \
1526 static void glue(gen_, name)(DisasContext *ctx)                               \
1527 {                                                                             \
1528     tcg_op(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);               \
1529     if (unlikely(Rc(ctx->opcode) != 0))                                       \
1530         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);                           \
1531 }
1532 
1533 /* and & and. */
1534 GEN_LOGICAL2(and, tcg_gen_and_tl, 0x00, PPC_INTEGER);
1535 /* andc & andc. */
1536 GEN_LOGICAL2(andc, tcg_gen_andc_tl, 0x01, PPC_INTEGER);
1537 
1538 /* andi. */
gen_andi_(DisasContext * ctx)1539 static void gen_andi_(DisasContext *ctx)
1540 {
1541     tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)],
1542                     UIMM(ctx->opcode));
1543     gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1544 }
1545 
1546 /* andis. */
gen_andis_(DisasContext * ctx)1547 static void gen_andis_(DisasContext *ctx)
1548 {
1549     tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)],
1550                     UIMM(ctx->opcode) << 16);
1551     gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1552 }
1553 
1554 /* cntlzw */
gen_cntlzw(DisasContext * ctx)1555 static void gen_cntlzw(DisasContext *ctx)
1556 {
1557     TCGv_i32 t = tcg_temp_new_i32();
1558 
1559     tcg_gen_trunc_tl_i32(t, cpu_gpr[rS(ctx->opcode)]);
1560     tcg_gen_clzi_i32(t, t, 32);
1561     tcg_gen_extu_i32_tl(cpu_gpr[rA(ctx->opcode)], t);
1562     tcg_temp_free_i32(t);
1563 
1564     if (unlikely(Rc(ctx->opcode) != 0)) {
1565         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1566     }
1567 }
1568 
1569 /* cnttzw */
gen_cnttzw(DisasContext * ctx)1570 static void gen_cnttzw(DisasContext *ctx)
1571 {
1572     TCGv_i32 t = tcg_temp_new_i32();
1573 
1574     tcg_gen_trunc_tl_i32(t, cpu_gpr[rS(ctx->opcode)]);
1575     tcg_gen_ctzi_i32(t, t, 32);
1576     tcg_gen_extu_i32_tl(cpu_gpr[rA(ctx->opcode)], t);
1577     tcg_temp_free_i32(t);
1578 
1579     if (unlikely(Rc(ctx->opcode) != 0)) {
1580         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1581     }
1582 }
1583 
1584 /* eqv & eqv. */
1585 GEN_LOGICAL2(eqv, tcg_gen_eqv_tl, 0x08, PPC_INTEGER);
1586 /* extsb & extsb. */
1587 GEN_LOGICAL1(extsb, tcg_gen_ext8s_tl, 0x1D, PPC_INTEGER);
1588 /* extsh & extsh. */
1589 GEN_LOGICAL1(extsh, tcg_gen_ext16s_tl, 0x1C, PPC_INTEGER);
1590 /* nand & nand. */
1591 GEN_LOGICAL2(nand, tcg_gen_nand_tl, 0x0E, PPC_INTEGER);
1592 /* nor & nor. */
1593 GEN_LOGICAL2(nor, tcg_gen_nor_tl, 0x03, PPC_INTEGER);
1594 
1595 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
gen_pause(DisasContext * ctx)1596 static void gen_pause(DisasContext *ctx)
1597 {
1598     TCGv_i32 t0 = tcg_const_i32(0);
1599     tcg_gen_st_i32(t0, cpu_env,
1600                    -offsetof(PowerPCCPU, env) + offsetof(CPUState, halted));
1601     tcg_temp_free_i32(t0);
1602 
1603     /* Stop translation, this gives other CPUs a chance to run */
1604     gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next);
1605 }
1606 #endif /* defined(TARGET_PPC64) */
1607 
1608 /* or & or. */
gen_or(DisasContext * ctx)1609 static void gen_or(DisasContext *ctx)
1610 {
1611     int rs, ra, rb;
1612 
1613     rs = rS(ctx->opcode);
1614     ra = rA(ctx->opcode);
1615     rb = rB(ctx->opcode);
1616     /* Optimisation for mr. ri case */
1617     if (rs != ra || rs != rb) {
1618         if (rs != rb) {
1619             tcg_gen_or_tl(cpu_gpr[ra], cpu_gpr[rs], cpu_gpr[rb]);
1620         } else {
1621             tcg_gen_mov_tl(cpu_gpr[ra], cpu_gpr[rs]);
1622         }
1623         if (unlikely(Rc(ctx->opcode) != 0)) {
1624             gen_set_Rc0(ctx, cpu_gpr[ra]);
1625         }
1626     } else if (unlikely(Rc(ctx->opcode) != 0)) {
1627         gen_set_Rc0(ctx, cpu_gpr[rs]);
1628 #if defined(TARGET_PPC64)
1629     } else if (rs != 0) { /* 0 is nop */
1630         int prio = 0;
1631 
1632         switch (rs) {
1633         case 1:
1634             /* Set process priority to low */
1635             prio = 2;
1636             break;
1637         case 6:
1638             /* Set process priority to medium-low */
1639             prio = 3;
1640             break;
1641         case 2:
1642             /* Set process priority to normal */
1643             prio = 4;
1644             break;
1645 #if !defined(CONFIG_USER_ONLY)
1646         case 31:
1647             if (!ctx->pr) {
1648                 /* Set process priority to very low */
1649                 prio = 1;
1650             }
1651             break;
1652         case 5:
1653             if (!ctx->pr) {
1654                 /* Set process priority to medium-hight */
1655                 prio = 5;
1656             }
1657             break;
1658         case 3:
1659             if (!ctx->pr) {
1660                 /* Set process priority to high */
1661                 prio = 6;
1662             }
1663             break;
1664         case 7:
1665             if (ctx->hv && !ctx->pr) {
1666                 /* Set process priority to very high */
1667                 prio = 7;
1668             }
1669             break;
1670 #endif
1671         default:
1672             break;
1673         }
1674         if (prio) {
1675             TCGv t0 = tcg_temp_new();
1676             gen_load_spr(t0, SPR_PPR);
1677             tcg_gen_andi_tl(t0, t0, ~0x001C000000000000ULL);
1678             tcg_gen_ori_tl(t0, t0, ((uint64_t)prio) << 50);
1679             gen_store_spr(SPR_PPR, t0);
1680             tcg_temp_free(t0);
1681         }
1682 #if !defined(CONFIG_USER_ONLY)
1683         /*
1684          * Pause out of TCG otherwise spin loops with smt_low eat too
1685          * much CPU and the kernel hangs.  This applies to all
1686          * encodings other than no-op, e.g., miso(rs=26), yield(27),
1687          * mdoio(29), mdoom(30), and all currently undefined.
1688          */
1689         gen_pause(ctx);
1690 #endif
1691 #endif
1692     }
1693 }
1694 /* orc & orc. */
1695 GEN_LOGICAL2(orc, tcg_gen_orc_tl, 0x0C, PPC_INTEGER);
1696 
1697 /* xor & xor. */
gen_xor(DisasContext * ctx)1698 static void gen_xor(DisasContext *ctx)
1699 {
1700     /* Optimisation for "set to zero" case */
1701     if (rS(ctx->opcode) != rB(ctx->opcode)) {
1702         tcg_gen_xor_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)],
1703                        cpu_gpr[rB(ctx->opcode)]);
1704     } else {
1705         tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
1706     }
1707     if (unlikely(Rc(ctx->opcode) != 0)) {
1708         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1709     }
1710 }
1711 
1712 /* ori */
gen_ori(DisasContext * ctx)1713 static void gen_ori(DisasContext *ctx)
1714 {
1715     target_ulong uimm = UIMM(ctx->opcode);
1716 
1717     if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1718         return;
1719     }
1720     tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm);
1721 }
1722 
1723 /* oris */
gen_oris(DisasContext * ctx)1724 static void gen_oris(DisasContext *ctx)
1725 {
1726     target_ulong uimm = UIMM(ctx->opcode);
1727 
1728     if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1729         /* NOP */
1730         return;
1731     }
1732     tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)],
1733                    uimm << 16);
1734 }
1735 
1736 /* xori */
gen_xori(DisasContext * ctx)1737 static void gen_xori(DisasContext *ctx)
1738 {
1739     target_ulong uimm = UIMM(ctx->opcode);
1740 
1741     if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1742         /* NOP */
1743         return;
1744     }
1745     tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm);
1746 }
1747 
1748 /* xoris */
gen_xoris(DisasContext * ctx)1749 static void gen_xoris(DisasContext *ctx)
1750 {
1751     target_ulong uimm = UIMM(ctx->opcode);
1752 
1753     if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1754         /* NOP */
1755         return;
1756     }
1757     tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)],
1758                     uimm << 16);
1759 }
1760 
1761 /* popcntb : PowerPC 2.03 specification */
gen_popcntb(DisasContext * ctx)1762 static void gen_popcntb(DisasContext *ctx)
1763 {
1764     gen_helper_popcntb(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1765 }
1766 
gen_popcntw(DisasContext * ctx)1767 static void gen_popcntw(DisasContext *ctx)
1768 {
1769 #if defined(TARGET_PPC64)
1770     gen_helper_popcntw(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1771 #else
1772     tcg_gen_ctpop_i32(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1773 #endif
1774 }
1775 
1776 #if defined(TARGET_PPC64)
1777 /* popcntd: PowerPC 2.06 specification */
gen_popcntd(DisasContext * ctx)1778 static void gen_popcntd(DisasContext *ctx)
1779 {
1780     tcg_gen_ctpop_i64(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1781 }
1782 #endif
1783 
1784 /* prtyw: PowerPC 2.05 specification */
gen_prtyw(DisasContext * ctx)1785 static void gen_prtyw(DisasContext *ctx)
1786 {
1787     TCGv ra = cpu_gpr[rA(ctx->opcode)];
1788     TCGv rs = cpu_gpr[rS(ctx->opcode)];
1789     TCGv t0 = tcg_temp_new();
1790     tcg_gen_shri_tl(t0, rs, 16);
1791     tcg_gen_xor_tl(ra, rs, t0);
1792     tcg_gen_shri_tl(t0, ra, 8);
1793     tcg_gen_xor_tl(ra, ra, t0);
1794     tcg_gen_andi_tl(ra, ra, (target_ulong)0x100000001ULL);
1795     tcg_temp_free(t0);
1796 }
1797 
1798 #if defined(TARGET_PPC64)
1799 /* prtyd: PowerPC 2.05 specification */
gen_prtyd(DisasContext * ctx)1800 static void gen_prtyd(DisasContext *ctx)
1801 {
1802     TCGv ra = cpu_gpr[rA(ctx->opcode)];
1803     TCGv rs = cpu_gpr[rS(ctx->opcode)];
1804     TCGv t0 = tcg_temp_new();
1805     tcg_gen_shri_tl(t0, rs, 32);
1806     tcg_gen_xor_tl(ra, rs, t0);
1807     tcg_gen_shri_tl(t0, ra, 16);
1808     tcg_gen_xor_tl(ra, ra, t0);
1809     tcg_gen_shri_tl(t0, ra, 8);
1810     tcg_gen_xor_tl(ra, ra, t0);
1811     tcg_gen_andi_tl(ra, ra, 1);
1812     tcg_temp_free(t0);
1813 }
1814 #endif
1815 
1816 #if defined(TARGET_PPC64)
1817 /* bpermd */
gen_bpermd(DisasContext * ctx)1818 static void gen_bpermd(DisasContext *ctx)
1819 {
1820     gen_helper_bpermd(cpu_gpr[rA(ctx->opcode)],
1821                       cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1822 }
1823 #endif
1824 
1825 #if defined(TARGET_PPC64)
1826 /* extsw & extsw. */
1827 GEN_LOGICAL1(extsw, tcg_gen_ext32s_tl, 0x1E, PPC_64B);
1828 
1829 /* cntlzd */
gen_cntlzd(DisasContext * ctx)1830 static void gen_cntlzd(DisasContext *ctx)
1831 {
1832     tcg_gen_clzi_i64(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], 64);
1833     if (unlikely(Rc(ctx->opcode) != 0)) {
1834         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1835     }
1836 }
1837 
1838 /* cnttzd */
gen_cnttzd(DisasContext * ctx)1839 static void gen_cnttzd(DisasContext *ctx)
1840 {
1841     tcg_gen_ctzi_i64(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], 64);
1842     if (unlikely(Rc(ctx->opcode) != 0)) {
1843         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1844     }
1845 }
1846 
1847 /* darn */
gen_darn(DisasContext * ctx)1848 static void gen_darn(DisasContext *ctx)
1849 {
1850     int l = L(ctx->opcode);
1851 
1852     if (l > 2) {
1853         tcg_gen_movi_i64(cpu_gpr[rD(ctx->opcode)], -1);
1854     } else {
1855         if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
1856             gen_io_start();
1857         }
1858         if (l == 0) {
1859             gen_helper_darn32(cpu_gpr[rD(ctx->opcode)]);
1860         } else {
1861             /* Return 64-bit random for both CRN and RRN */
1862             gen_helper_darn64(cpu_gpr[rD(ctx->opcode)]);
1863         }
1864         if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
1865             gen_stop_exception(ctx);
1866         }
1867     }
1868 }
1869 #endif
1870 
1871 /***                             Integer rotate                            ***/
1872 
1873 /* rlwimi & rlwimi. */
gen_rlwimi(DisasContext * ctx)1874 static void gen_rlwimi(DisasContext *ctx)
1875 {
1876     TCGv t_ra = cpu_gpr[rA(ctx->opcode)];
1877     TCGv t_rs = cpu_gpr[rS(ctx->opcode)];
1878     uint32_t sh = SH(ctx->opcode);
1879     uint32_t mb = MB(ctx->opcode);
1880     uint32_t me = ME(ctx->opcode);
1881 
1882     if (sh == (31 - me) && mb <= me) {
1883         tcg_gen_deposit_tl(t_ra, t_ra, t_rs, sh, me - mb + 1);
1884     } else {
1885         target_ulong mask;
1886         bool mask_in_32b = true;
1887         TCGv t1;
1888 
1889 #if defined(TARGET_PPC64)
1890         mb += 32;
1891         me += 32;
1892 #endif
1893         mask = MASK(mb, me);
1894 
1895 #if defined(TARGET_PPC64)
1896         if (mask > 0xffffffffu) {
1897             mask_in_32b = false;
1898         }
1899 #endif
1900         t1 = tcg_temp_new();
1901         if (mask_in_32b) {
1902             TCGv_i32 t0 = tcg_temp_new_i32();
1903             tcg_gen_trunc_tl_i32(t0, t_rs);
1904             tcg_gen_rotli_i32(t0, t0, sh);
1905             tcg_gen_extu_i32_tl(t1, t0);
1906             tcg_temp_free_i32(t0);
1907         } else {
1908 #if defined(TARGET_PPC64)
1909             tcg_gen_deposit_i64(t1, t_rs, t_rs, 32, 32);
1910             tcg_gen_rotli_i64(t1, t1, sh);
1911 #else
1912             g_assert_not_reached();
1913 #endif
1914         }
1915 
1916         tcg_gen_andi_tl(t1, t1, mask);
1917         tcg_gen_andi_tl(t_ra, t_ra, ~mask);
1918         tcg_gen_or_tl(t_ra, t_ra, t1);
1919         tcg_temp_free(t1);
1920     }
1921     if (unlikely(Rc(ctx->opcode) != 0)) {
1922         gen_set_Rc0(ctx, t_ra);
1923     }
1924 }
1925 
1926 /* rlwinm & rlwinm. */
gen_rlwinm(DisasContext * ctx)1927 static void gen_rlwinm(DisasContext *ctx)
1928 {
1929     TCGv t_ra = cpu_gpr[rA(ctx->opcode)];
1930     TCGv t_rs = cpu_gpr[rS(ctx->opcode)];
1931     int sh = SH(ctx->opcode);
1932     int mb = MB(ctx->opcode);
1933     int me = ME(ctx->opcode);
1934     int len = me - mb + 1;
1935     int rsh = (32 - sh) & 31;
1936 
1937     if (sh != 0 && len > 0 && me == (31 - sh)) {
1938         tcg_gen_deposit_z_tl(t_ra, t_rs, sh, len);
1939     } else if (me == 31 && rsh + len <= 32) {
1940         tcg_gen_extract_tl(t_ra, t_rs, rsh, len);
1941     } else {
1942         target_ulong mask;
1943         bool mask_in_32b = true;
1944 #if defined(TARGET_PPC64)
1945         mb += 32;
1946         me += 32;
1947 #endif
1948         mask = MASK(mb, me);
1949 #if defined(TARGET_PPC64)
1950         if (mask > 0xffffffffu) {
1951             mask_in_32b = false;
1952         }
1953 #endif
1954         if (mask_in_32b) {
1955             if (sh == 0) {
1956                 tcg_gen_andi_tl(t_ra, t_rs, mask);
1957             } else {
1958                 TCGv_i32 t0 = tcg_temp_new_i32();
1959                 tcg_gen_trunc_tl_i32(t0, t_rs);
1960                 tcg_gen_rotli_i32(t0, t0, sh);
1961                 tcg_gen_andi_i32(t0, t0, mask);
1962                 tcg_gen_extu_i32_tl(t_ra, t0);
1963                 tcg_temp_free_i32(t0);
1964             }
1965         } else {
1966 #if defined(TARGET_PPC64)
1967             tcg_gen_deposit_i64(t_ra, t_rs, t_rs, 32, 32);
1968             tcg_gen_rotli_i64(t_ra, t_ra, sh);
1969             tcg_gen_andi_i64(t_ra, t_ra, mask);
1970 #else
1971             g_assert_not_reached();
1972 #endif
1973         }
1974     }
1975     if (unlikely(Rc(ctx->opcode) != 0)) {
1976         gen_set_Rc0(ctx, t_ra);
1977     }
1978 }
1979 
1980 /* rlwnm & rlwnm. */
gen_rlwnm(DisasContext * ctx)1981 static void gen_rlwnm(DisasContext *ctx)
1982 {
1983     TCGv t_ra = cpu_gpr[rA(ctx->opcode)];
1984     TCGv t_rs = cpu_gpr[rS(ctx->opcode)];
1985     TCGv t_rb = cpu_gpr[rB(ctx->opcode)];
1986     uint32_t mb = MB(ctx->opcode);
1987     uint32_t me = ME(ctx->opcode);
1988     target_ulong mask;
1989     bool mask_in_32b = true;
1990 
1991 #if defined(TARGET_PPC64)
1992     mb += 32;
1993     me += 32;
1994 #endif
1995     mask = MASK(mb, me);
1996 
1997 #if defined(TARGET_PPC64)
1998     if (mask > 0xffffffffu) {
1999         mask_in_32b = false;
2000     }
2001 #endif
2002     if (mask_in_32b) {
2003         TCGv_i32 t0 = tcg_temp_new_i32();
2004         TCGv_i32 t1 = tcg_temp_new_i32();
2005         tcg_gen_trunc_tl_i32(t0, t_rb);
2006         tcg_gen_trunc_tl_i32(t1, t_rs);
2007         tcg_gen_andi_i32(t0, t0, 0x1f);
2008         tcg_gen_rotl_i32(t1, t1, t0);
2009         tcg_gen_extu_i32_tl(t_ra, t1);
2010         tcg_temp_free_i32(t0);
2011         tcg_temp_free_i32(t1);
2012     } else {
2013 #if defined(TARGET_PPC64)
2014         TCGv_i64 t0 = tcg_temp_new_i64();
2015         tcg_gen_andi_i64(t0, t_rb, 0x1f);
2016         tcg_gen_deposit_i64(t_ra, t_rs, t_rs, 32, 32);
2017         tcg_gen_rotl_i64(t_ra, t_ra, t0);
2018         tcg_temp_free_i64(t0);
2019 #else
2020         g_assert_not_reached();
2021 #endif
2022     }
2023 
2024     tcg_gen_andi_tl(t_ra, t_ra, mask);
2025 
2026     if (unlikely(Rc(ctx->opcode) != 0)) {
2027         gen_set_Rc0(ctx, t_ra);
2028     }
2029 }
2030 
2031 #if defined(TARGET_PPC64)
2032 #define GEN_PPC64_R2(name, opc1, opc2)                                        \
2033 static void glue(gen_, name##0)(DisasContext *ctx)                            \
2034 {                                                                             \
2035     gen_##name(ctx, 0);                                                       \
2036 }                                                                             \
2037                                                                               \
2038 static void glue(gen_, name##1)(DisasContext *ctx)                            \
2039 {                                                                             \
2040     gen_##name(ctx, 1);                                                       \
2041 }
2042 #define GEN_PPC64_R4(name, opc1, opc2)                                        \
2043 static void glue(gen_, name##0)(DisasContext *ctx)                            \
2044 {                                                                             \
2045     gen_##name(ctx, 0, 0);                                                    \
2046 }                                                                             \
2047                                                                               \
2048 static void glue(gen_, name##1)(DisasContext *ctx)                            \
2049 {                                                                             \
2050     gen_##name(ctx, 0, 1);                                                    \
2051 }                                                                             \
2052                                                                               \
2053 static void glue(gen_, name##2)(DisasContext *ctx)                            \
2054 {                                                                             \
2055     gen_##name(ctx, 1, 0);                                                    \
2056 }                                                                             \
2057                                                                               \
2058 static void glue(gen_, name##3)(DisasContext *ctx)                            \
2059 {                                                                             \
2060     gen_##name(ctx, 1, 1);                                                    \
2061 }
2062 
gen_rldinm(DisasContext * ctx,int mb,int me,int sh)2063 static void gen_rldinm(DisasContext *ctx, int mb, int me, int sh)
2064 {
2065     TCGv t_ra = cpu_gpr[rA(ctx->opcode)];
2066     TCGv t_rs = cpu_gpr[rS(ctx->opcode)];
2067     int len = me - mb + 1;
2068     int rsh = (64 - sh) & 63;
2069 
2070     if (sh != 0 && len > 0 && me == (63 - sh)) {
2071         tcg_gen_deposit_z_tl(t_ra, t_rs, sh, len);
2072     } else if (me == 63 && rsh + len <= 64) {
2073         tcg_gen_extract_tl(t_ra, t_rs, rsh, len);
2074     } else {
2075         tcg_gen_rotli_tl(t_ra, t_rs, sh);
2076         tcg_gen_andi_tl(t_ra, t_ra, MASK(mb, me));
2077     }
2078     if (unlikely(Rc(ctx->opcode) != 0)) {
2079         gen_set_Rc0(ctx, t_ra);
2080     }
2081 }
2082 
2083 /* rldicl - rldicl. */
gen_rldicl(DisasContext * ctx,int mbn,int shn)2084 static inline void gen_rldicl(DisasContext *ctx, int mbn, int shn)
2085 {
2086     uint32_t sh, mb;
2087 
2088     sh = SH(ctx->opcode) | (shn << 5);
2089     mb = MB(ctx->opcode) | (mbn << 5);
2090     gen_rldinm(ctx, mb, 63, sh);
2091 }
2092 GEN_PPC64_R4(rldicl, 0x1E, 0x00);
2093 
2094 /* rldicr - rldicr. */
gen_rldicr(DisasContext * ctx,int men,int shn)2095 static inline void gen_rldicr(DisasContext *ctx, int men, int shn)
2096 {
2097     uint32_t sh, me;
2098 
2099     sh = SH(ctx->opcode) | (shn << 5);
2100     me = MB(ctx->opcode) | (men << 5);
2101     gen_rldinm(ctx, 0, me, sh);
2102 }
2103 GEN_PPC64_R4(rldicr, 0x1E, 0x02);
2104 
2105 /* rldic - rldic. */
gen_rldic(DisasContext * ctx,int mbn,int shn)2106 static inline void gen_rldic(DisasContext *ctx, int mbn, int shn)
2107 {
2108     uint32_t sh, mb;
2109 
2110     sh = SH(ctx->opcode) | (shn << 5);
2111     mb = MB(ctx->opcode) | (mbn << 5);
2112     gen_rldinm(ctx, mb, 63 - sh, sh);
2113 }
2114 GEN_PPC64_R4(rldic, 0x1E, 0x04);
2115 
gen_rldnm(DisasContext * ctx,int mb,int me)2116 static void gen_rldnm(DisasContext *ctx, int mb, int me)
2117 {
2118     TCGv t_ra = cpu_gpr[rA(ctx->opcode)];
2119     TCGv t_rs = cpu_gpr[rS(ctx->opcode)];
2120     TCGv t_rb = cpu_gpr[rB(ctx->opcode)];
2121     TCGv t0;
2122 
2123     t0 = tcg_temp_new();
2124     tcg_gen_andi_tl(t0, t_rb, 0x3f);
2125     tcg_gen_rotl_tl(t_ra, t_rs, t0);
2126     tcg_temp_free(t0);
2127 
2128     tcg_gen_andi_tl(t_ra, t_ra, MASK(mb, me));
2129     if (unlikely(Rc(ctx->opcode) != 0)) {
2130         gen_set_Rc0(ctx, t_ra);
2131     }
2132 }
2133 
2134 /* rldcl - rldcl. */
gen_rldcl(DisasContext * ctx,int mbn)2135 static inline void gen_rldcl(DisasContext *ctx, int mbn)
2136 {
2137     uint32_t mb;
2138 
2139     mb = MB(ctx->opcode) | (mbn << 5);
2140     gen_rldnm(ctx, mb, 63);
2141 }
2142 GEN_PPC64_R2(rldcl, 0x1E, 0x08);
2143 
2144 /* rldcr - rldcr. */
gen_rldcr(DisasContext * ctx,int men)2145 static inline void gen_rldcr(DisasContext *ctx, int men)
2146 {
2147     uint32_t me;
2148 
2149     me = MB(ctx->opcode) | (men << 5);
2150     gen_rldnm(ctx, 0, me);
2151 }
2152 GEN_PPC64_R2(rldcr, 0x1E, 0x09);
2153 
2154 /* rldimi - rldimi. */
gen_rldimi(DisasContext * ctx,int mbn,int shn)2155 static void gen_rldimi(DisasContext *ctx, int mbn, int shn)
2156 {
2157     TCGv t_ra = cpu_gpr[rA(ctx->opcode)];
2158     TCGv t_rs = cpu_gpr[rS(ctx->opcode)];
2159     uint32_t sh = SH(ctx->opcode) | (shn << 5);
2160     uint32_t mb = MB(ctx->opcode) | (mbn << 5);
2161     uint32_t me = 63 - sh;
2162 
2163     if (mb <= me) {
2164         tcg_gen_deposit_tl(t_ra, t_ra, t_rs, sh, me - mb + 1);
2165     } else {
2166         target_ulong mask = MASK(mb, me);
2167         TCGv t1 = tcg_temp_new();
2168 
2169         tcg_gen_rotli_tl(t1, t_rs, sh);
2170         tcg_gen_andi_tl(t1, t1, mask);
2171         tcg_gen_andi_tl(t_ra, t_ra, ~mask);
2172         tcg_gen_or_tl(t_ra, t_ra, t1);
2173         tcg_temp_free(t1);
2174     }
2175     if (unlikely(Rc(ctx->opcode) != 0)) {
2176         gen_set_Rc0(ctx, t_ra);
2177     }
2178 }
2179 GEN_PPC64_R4(rldimi, 0x1E, 0x06);
2180 #endif
2181 
2182 /***                             Integer shift                             ***/
2183 
2184 /* slw & slw. */
gen_slw(DisasContext * ctx)2185 static void gen_slw(DisasContext *ctx)
2186 {
2187     TCGv t0, t1;
2188 
2189     t0 = tcg_temp_new();
2190     /* AND rS with a mask that is 0 when rB >= 0x20 */
2191 #if defined(TARGET_PPC64)
2192     tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3a);
2193     tcg_gen_sari_tl(t0, t0, 0x3f);
2194 #else
2195     tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1a);
2196     tcg_gen_sari_tl(t0, t0, 0x1f);
2197 #endif
2198     tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
2199     t1 = tcg_temp_new();
2200     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1f);
2201     tcg_gen_shl_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
2202     tcg_temp_free(t1);
2203     tcg_temp_free(t0);
2204     tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
2205     if (unlikely(Rc(ctx->opcode) != 0)) {
2206         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
2207     }
2208 }
2209 
2210 /* sraw & sraw. */
gen_sraw(DisasContext * ctx)2211 static void gen_sraw(DisasContext *ctx)
2212 {
2213     gen_helper_sraw(cpu_gpr[rA(ctx->opcode)], cpu_env,
2214                     cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
2215     if (unlikely(Rc(ctx->opcode) != 0)) {
2216         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
2217     }
2218 }
2219 
2220 /* srawi & srawi. */
gen_srawi(DisasContext * ctx)2221 static void gen_srawi(DisasContext *ctx)
2222 {
2223     int sh = SH(ctx->opcode);
2224     TCGv dst = cpu_gpr[rA(ctx->opcode)];
2225     TCGv src = cpu_gpr[rS(ctx->opcode)];
2226     if (sh == 0) {
2227         tcg_gen_ext32s_tl(dst, src);
2228         tcg_gen_movi_tl(cpu_ca, 0);
2229         if (is_isa300(ctx)) {
2230             tcg_gen_movi_tl(cpu_ca32, 0);
2231         }
2232     } else {
2233         TCGv t0;
2234         tcg_gen_ext32s_tl(dst, src);
2235         tcg_gen_andi_tl(cpu_ca, dst, (1ULL << sh) - 1);
2236         t0 = tcg_temp_new();
2237         tcg_gen_sari_tl(t0, dst, TARGET_LONG_BITS - 1);
2238         tcg_gen_and_tl(cpu_ca, cpu_ca, t0);
2239         tcg_temp_free(t0);
2240         tcg_gen_setcondi_tl(TCG_COND_NE, cpu_ca, cpu_ca, 0);
2241         if (is_isa300(ctx)) {
2242             tcg_gen_mov_tl(cpu_ca32, cpu_ca);
2243         }
2244         tcg_gen_sari_tl(dst, dst, sh);
2245     }
2246     if (unlikely(Rc(ctx->opcode) != 0)) {
2247         gen_set_Rc0(ctx, dst);
2248     }
2249 }
2250 
2251 /* srw & srw. */
gen_srw(DisasContext * ctx)2252 static void gen_srw(DisasContext *ctx)
2253 {
2254     TCGv t0, t1;
2255 
2256     t0 = tcg_temp_new();
2257     /* AND rS with a mask that is 0 when rB >= 0x20 */
2258 #if defined(TARGET_PPC64)
2259     tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3a);
2260     tcg_gen_sari_tl(t0, t0, 0x3f);
2261 #else
2262     tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1a);
2263     tcg_gen_sari_tl(t0, t0, 0x1f);
2264 #endif
2265     tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
2266     tcg_gen_ext32u_tl(t0, t0);
2267     t1 = tcg_temp_new();
2268     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1f);
2269     tcg_gen_shr_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
2270     tcg_temp_free(t1);
2271     tcg_temp_free(t0);
2272     if (unlikely(Rc(ctx->opcode) != 0)) {
2273         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
2274     }
2275 }
2276 
2277 #if defined(TARGET_PPC64)
2278 /* sld & sld. */
gen_sld(DisasContext * ctx)2279 static void gen_sld(DisasContext *ctx)
2280 {
2281     TCGv t0, t1;
2282 
2283     t0 = tcg_temp_new();
2284     /* AND rS with a mask that is 0 when rB >= 0x40 */
2285     tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x39);
2286     tcg_gen_sari_tl(t0, t0, 0x3f);
2287     tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
2288     t1 = tcg_temp_new();
2289     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x3f);
2290     tcg_gen_shl_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
2291     tcg_temp_free(t1);
2292     tcg_temp_free(t0);
2293     if (unlikely(Rc(ctx->opcode) != 0)) {
2294         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
2295     }
2296 }
2297 
2298 /* srad & srad. */
gen_srad(DisasContext * ctx)2299 static void gen_srad(DisasContext *ctx)
2300 {
2301     gen_helper_srad(cpu_gpr[rA(ctx->opcode)], cpu_env,
2302                     cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
2303     if (unlikely(Rc(ctx->opcode) != 0)) {
2304         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
2305     }
2306 }
2307 /* sradi & sradi. */
gen_sradi(DisasContext * ctx,int n)2308 static inline void gen_sradi(DisasContext *ctx, int n)
2309 {
2310     int sh = SH(ctx->opcode) + (n << 5);
2311     TCGv dst = cpu_gpr[rA(ctx->opcode)];
2312     TCGv src = cpu_gpr[rS(ctx->opcode)];
2313     if (sh == 0) {
2314         tcg_gen_mov_tl(dst, src);
2315         tcg_gen_movi_tl(cpu_ca, 0);
2316         if (is_isa300(ctx)) {
2317             tcg_gen_movi_tl(cpu_ca32, 0);
2318         }
2319     } else {
2320         TCGv t0;
2321         tcg_gen_andi_tl(cpu_ca, src, (1ULL << sh) - 1);
2322         t0 = tcg_temp_new();
2323         tcg_gen_sari_tl(t0, src, TARGET_LONG_BITS - 1);
2324         tcg_gen_and_tl(cpu_ca, cpu_ca, t0);
2325         tcg_temp_free(t0);
2326         tcg_gen_setcondi_tl(TCG_COND_NE, cpu_ca, cpu_ca, 0);
2327         if (is_isa300(ctx)) {
2328             tcg_gen_mov_tl(cpu_ca32, cpu_ca);
2329         }
2330         tcg_gen_sari_tl(dst, src, sh);
2331     }
2332     if (unlikely(Rc(ctx->opcode) != 0)) {
2333         gen_set_Rc0(ctx, dst);
2334     }
2335 }
2336 
gen_sradi0(DisasContext * ctx)2337 static void gen_sradi0(DisasContext *ctx)
2338 {
2339     gen_sradi(ctx, 0);
2340 }
2341 
gen_sradi1(DisasContext * ctx)2342 static void gen_sradi1(DisasContext *ctx)
2343 {
2344     gen_sradi(ctx, 1);
2345 }
2346 
2347 /* extswsli & extswsli. */
gen_extswsli(DisasContext * ctx,int n)2348 static inline void gen_extswsli(DisasContext *ctx, int n)
2349 {
2350     int sh = SH(ctx->opcode) + (n << 5);
2351     TCGv dst = cpu_gpr[rA(ctx->opcode)];
2352     TCGv src = cpu_gpr[rS(ctx->opcode)];
2353 
2354     tcg_gen_ext32s_tl(dst, src);
2355     tcg_gen_shli_tl(dst, dst, sh);
2356     if (unlikely(Rc(ctx->opcode) != 0)) {
2357         gen_set_Rc0(ctx, dst);
2358     }
2359 }
2360 
gen_extswsli0(DisasContext * ctx)2361 static void gen_extswsli0(DisasContext *ctx)
2362 {
2363     gen_extswsli(ctx, 0);
2364 }
2365 
gen_extswsli1(DisasContext * ctx)2366 static void gen_extswsli1(DisasContext *ctx)
2367 {
2368     gen_extswsli(ctx, 1);
2369 }
2370 
2371 /* srd & srd. */
gen_srd(DisasContext * ctx)2372 static void gen_srd(DisasContext *ctx)
2373 {
2374     TCGv t0, t1;
2375 
2376     t0 = tcg_temp_new();
2377     /* AND rS with a mask that is 0 when rB >= 0x40 */
2378     tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x39);
2379     tcg_gen_sari_tl(t0, t0, 0x3f);
2380     tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
2381     t1 = tcg_temp_new();
2382     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x3f);
2383     tcg_gen_shr_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
2384     tcg_temp_free(t1);
2385     tcg_temp_free(t0);
2386     if (unlikely(Rc(ctx->opcode) != 0)) {
2387         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
2388     }
2389 }
2390 #endif
2391 
2392 /***                           Addressing modes                            ***/
2393 /* Register indirect with immediate index : EA = (rA|0) + SIMM */
gen_addr_imm_index(DisasContext * ctx,TCGv EA,target_long maskl)2394 static inline void gen_addr_imm_index(DisasContext *ctx, TCGv EA,
2395                                       target_long maskl)
2396 {
2397     target_long simm = SIMM(ctx->opcode);
2398 
2399     simm &= ~maskl;
2400     if (rA(ctx->opcode) == 0) {
2401         if (NARROW_MODE(ctx)) {
2402             simm = (uint32_t)simm;
2403         }
2404         tcg_gen_movi_tl(EA, simm);
2405     } else if (likely(simm != 0)) {
2406         tcg_gen_addi_tl(EA, cpu_gpr[rA(ctx->opcode)], simm);
2407         if (NARROW_MODE(ctx)) {
2408             tcg_gen_ext32u_tl(EA, EA);
2409         }
2410     } else {
2411         if (NARROW_MODE(ctx)) {
2412             tcg_gen_ext32u_tl(EA, cpu_gpr[rA(ctx->opcode)]);
2413         } else {
2414             tcg_gen_mov_tl(EA, cpu_gpr[rA(ctx->opcode)]);
2415         }
2416     }
2417 }
2418 
gen_addr_reg_index(DisasContext * ctx,TCGv EA)2419 static inline void gen_addr_reg_index(DisasContext *ctx, TCGv EA)
2420 {
2421     if (rA(ctx->opcode) == 0) {
2422         if (NARROW_MODE(ctx)) {
2423             tcg_gen_ext32u_tl(EA, cpu_gpr[rB(ctx->opcode)]);
2424         } else {
2425             tcg_gen_mov_tl(EA, cpu_gpr[rB(ctx->opcode)]);
2426         }
2427     } else {
2428         tcg_gen_add_tl(EA, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
2429         if (NARROW_MODE(ctx)) {
2430             tcg_gen_ext32u_tl(EA, EA);
2431         }
2432     }
2433 }
2434 
gen_addr_register(DisasContext * ctx,TCGv EA)2435 static inline void gen_addr_register(DisasContext *ctx, TCGv EA)
2436 {
2437     if (rA(ctx->opcode) == 0) {
2438         tcg_gen_movi_tl(EA, 0);
2439     } else if (NARROW_MODE(ctx)) {
2440         tcg_gen_ext32u_tl(EA, cpu_gpr[rA(ctx->opcode)]);
2441     } else {
2442         tcg_gen_mov_tl(EA, cpu_gpr[rA(ctx->opcode)]);
2443     }
2444 }
2445 
gen_addr_add(DisasContext * ctx,TCGv ret,TCGv arg1,target_long val)2446 static inline void gen_addr_add(DisasContext *ctx, TCGv ret, TCGv arg1,
2447                                 target_long val)
2448 {
2449     tcg_gen_addi_tl(ret, arg1, val);
2450     if (NARROW_MODE(ctx)) {
2451         tcg_gen_ext32u_tl(ret, ret);
2452     }
2453 }
2454 
gen_align_no_le(DisasContext * ctx)2455 static inline void gen_align_no_le(DisasContext *ctx)
2456 {
2457     gen_exception_err(ctx, POWERPC_EXCP_ALIGN,
2458                       (ctx->opcode & 0x03FF0000) | POWERPC_EXCP_ALIGN_LE);
2459 }
2460 
2461 /***                             Integer load                              ***/
2462 #define DEF_MEMOP(op) ((op) | ctx->default_tcg_memop_mask)
2463 #define BSWAP_MEMOP(op) ((op) | (ctx->default_tcg_memop_mask ^ MO_BSWAP))
2464 
2465 #define GEN_QEMU_LOAD_TL(ldop, op)                                      \
2466 static void glue(gen_qemu_, ldop)(DisasContext *ctx,                    \
2467                                   TCGv val,                             \
2468                                   TCGv addr)                            \
2469 {                                                                       \
2470     tcg_gen_qemu_ld_tl(val, addr, ctx->mem_idx, op);                    \
2471 }
2472 
2473 GEN_QEMU_LOAD_TL(ld8u,  DEF_MEMOP(MO_UB))
2474 GEN_QEMU_LOAD_TL(ld16u, DEF_MEMOP(MO_UW))
2475 GEN_QEMU_LOAD_TL(ld16s, DEF_MEMOP(MO_SW))
2476 GEN_QEMU_LOAD_TL(ld32u, DEF_MEMOP(MO_UL))
2477 GEN_QEMU_LOAD_TL(ld32s, DEF_MEMOP(MO_SL))
2478 
2479 GEN_QEMU_LOAD_TL(ld16ur, BSWAP_MEMOP(MO_UW))
2480 GEN_QEMU_LOAD_TL(ld32ur, BSWAP_MEMOP(MO_UL))
2481 
2482 #define GEN_QEMU_LOAD_64(ldop, op)                                  \
2483 static void glue(gen_qemu_, glue(ldop, _i64))(DisasContext *ctx,    \
2484                                              TCGv_i64 val,          \
2485                                              TCGv addr)             \
2486 {                                                                   \
2487     tcg_gen_qemu_ld_i64(val, addr, ctx->mem_idx, op);               \
2488 }
2489 
2490 GEN_QEMU_LOAD_64(ld8u,  DEF_MEMOP(MO_UB))
2491 GEN_QEMU_LOAD_64(ld16u, DEF_MEMOP(MO_UW))
2492 GEN_QEMU_LOAD_64(ld32u, DEF_MEMOP(MO_UL))
2493 GEN_QEMU_LOAD_64(ld32s, DEF_MEMOP(MO_SL))
2494 GEN_QEMU_LOAD_64(ld64,  DEF_MEMOP(MO_Q))
2495 
2496 #if defined(TARGET_PPC64)
2497 GEN_QEMU_LOAD_64(ld64ur, BSWAP_MEMOP(MO_Q))
2498 #endif
2499 
2500 #define GEN_QEMU_STORE_TL(stop, op)                                     \
2501 static void glue(gen_qemu_, stop)(DisasContext *ctx,                    \
2502                                   TCGv val,                             \
2503                                   TCGv addr)                            \
2504 {                                                                       \
2505     tcg_gen_qemu_st_tl(val, addr, ctx->mem_idx, op);                    \
2506 }
2507 
2508 GEN_QEMU_STORE_TL(st8,  DEF_MEMOP(MO_UB))
2509 GEN_QEMU_STORE_TL(st16, DEF_MEMOP(MO_UW))
2510 GEN_QEMU_STORE_TL(st32, DEF_MEMOP(MO_UL))
2511 
2512 GEN_QEMU_STORE_TL(st16r, BSWAP_MEMOP(MO_UW))
2513 GEN_QEMU_STORE_TL(st32r, BSWAP_MEMOP(MO_UL))
2514 
2515 #define GEN_QEMU_STORE_64(stop, op)                               \
2516 static void glue(gen_qemu_, glue(stop, _i64))(DisasContext *ctx,  \
2517                                               TCGv_i64 val,       \
2518                                               TCGv addr)          \
2519 {                                                                 \
2520     tcg_gen_qemu_st_i64(val, addr, ctx->mem_idx, op);             \
2521 }
2522 
2523 GEN_QEMU_STORE_64(st8,  DEF_MEMOP(MO_UB))
2524 GEN_QEMU_STORE_64(st16, DEF_MEMOP(MO_UW))
2525 GEN_QEMU_STORE_64(st32, DEF_MEMOP(MO_UL))
2526 GEN_QEMU_STORE_64(st64, DEF_MEMOP(MO_Q))
2527 
2528 #if defined(TARGET_PPC64)
2529 GEN_QEMU_STORE_64(st64r, BSWAP_MEMOP(MO_Q))
2530 #endif
2531 
2532 #define GEN_LD(name, ldop, opc, type)                                         \
2533 static void glue(gen_, name)(DisasContext *ctx)                               \
2534 {                                                                             \
2535     TCGv EA;                                                                  \
2536     gen_set_access_type(ctx, ACCESS_INT);                                     \
2537     EA = tcg_temp_new();                                                      \
2538     gen_addr_imm_index(ctx, EA, 0);                                           \
2539     gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA);                       \
2540     tcg_temp_free(EA);                                                        \
2541 }
2542 
2543 #define GEN_LDU(name, ldop, opc, type)                                        \
2544 static void glue(gen_, name##u)(DisasContext *ctx)                            \
2545 {                                                                             \
2546     TCGv EA;                                                                  \
2547     if (unlikely(rA(ctx->opcode) == 0 ||                                      \
2548                  rA(ctx->opcode) == rD(ctx->opcode))) {                       \
2549         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
2550         return;                                                               \
2551     }                                                                         \
2552     gen_set_access_type(ctx, ACCESS_INT);                                     \
2553     EA = tcg_temp_new();                                                      \
2554     if (type == PPC_64B)                                                      \
2555         gen_addr_imm_index(ctx, EA, 0x03);                                    \
2556     else                                                                      \
2557         gen_addr_imm_index(ctx, EA, 0);                                       \
2558     gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA);                       \
2559     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
2560     tcg_temp_free(EA);                                                        \
2561 }
2562 
2563 #define GEN_LDUX(name, ldop, opc2, opc3, type)                                \
2564 static void glue(gen_, name##ux)(DisasContext *ctx)                           \
2565 {                                                                             \
2566     TCGv EA;                                                                  \
2567     if (unlikely(rA(ctx->opcode) == 0 ||                                      \
2568                  rA(ctx->opcode) == rD(ctx->opcode))) {                       \
2569         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
2570         return;                                                               \
2571     }                                                                         \
2572     gen_set_access_type(ctx, ACCESS_INT);                                     \
2573     EA = tcg_temp_new();                                                      \
2574     gen_addr_reg_index(ctx, EA);                                              \
2575     gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA);                       \
2576     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
2577     tcg_temp_free(EA);                                                        \
2578 }
2579 
2580 #define GEN_LDX_E(name, ldop, opc2, opc3, type, type2, chk)                   \
2581 static void glue(gen_, name##x)(DisasContext *ctx)                            \
2582 {                                                                             \
2583     TCGv EA;                                                                  \
2584     chk;                                                                      \
2585     gen_set_access_type(ctx, ACCESS_INT);                                     \
2586     EA = tcg_temp_new();                                                      \
2587     gen_addr_reg_index(ctx, EA);                                              \
2588     gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA);                       \
2589     tcg_temp_free(EA);                                                        \
2590 }
2591 
2592 #define GEN_LDX(name, ldop, opc2, opc3, type)                                 \
2593     GEN_LDX_E(name, ldop, opc2, opc3, type, PPC_NONE, CHK_NONE)
2594 
2595 #define GEN_LDX_HVRM(name, ldop, opc2, opc3, type)                            \
2596     GEN_LDX_E(name, ldop, opc2, opc3, type, PPC_NONE, CHK_HVRM)
2597 
2598 #define GEN_LDS(name, ldop, op, type)                                         \
2599 GEN_LD(name, ldop, op | 0x20, type);                                          \
2600 GEN_LDU(name, ldop, op | 0x21, type);                                         \
2601 GEN_LDUX(name, ldop, 0x17, op | 0x01, type);                                  \
2602 GEN_LDX(name, ldop, 0x17, op | 0x00, type)
2603 
2604 /* lbz lbzu lbzux lbzx */
2605 GEN_LDS(lbz, ld8u, 0x02, PPC_INTEGER);
2606 /* lha lhau lhaux lhax */
2607 GEN_LDS(lha, ld16s, 0x0A, PPC_INTEGER);
2608 /* lhz lhzu lhzux lhzx */
2609 GEN_LDS(lhz, ld16u, 0x08, PPC_INTEGER);
2610 /* lwz lwzu lwzux lwzx */
2611 GEN_LDS(lwz, ld32u, 0x00, PPC_INTEGER);
2612 
2613 #define GEN_LDEPX(name, ldop, opc2, opc3)                                     \
2614 static void glue(gen_, name##epx)(DisasContext *ctx)                          \
2615 {                                                                             \
2616     TCGv EA;                                                                  \
2617     CHK_SV;                                                                   \
2618     gen_set_access_type(ctx, ACCESS_INT);                                     \
2619     EA = tcg_temp_new();                                                      \
2620     gen_addr_reg_index(ctx, EA);                                              \
2621     tcg_gen_qemu_ld_tl(cpu_gpr[rD(ctx->opcode)], EA, PPC_TLB_EPID_LOAD, ldop);\
2622     tcg_temp_free(EA);                                                        \
2623 }
2624 
2625 GEN_LDEPX(lb, DEF_MEMOP(MO_UB), 0x1F, 0x02)
2626 GEN_LDEPX(lh, DEF_MEMOP(MO_UW), 0x1F, 0x08)
2627 GEN_LDEPX(lw, DEF_MEMOP(MO_UL), 0x1F, 0x00)
2628 #if defined(TARGET_PPC64)
2629 GEN_LDEPX(ld, DEF_MEMOP(MO_Q), 0x1D, 0x00)
2630 #endif
2631 
2632 #if defined(TARGET_PPC64)
2633 /* lwaux */
2634 GEN_LDUX(lwa, ld32s, 0x15, 0x0B, PPC_64B);
2635 /* lwax */
2636 GEN_LDX(lwa, ld32s, 0x15, 0x0A, PPC_64B);
2637 /* ldux */
2638 GEN_LDUX(ld, ld64_i64, 0x15, 0x01, PPC_64B);
2639 /* ldx */
2640 GEN_LDX(ld, ld64_i64, 0x15, 0x00, PPC_64B);
2641 
2642 /* CI load/store variants */
2643 GEN_LDX_HVRM(ldcix, ld64_i64, 0x15, 0x1b, PPC_CILDST)
2644 GEN_LDX_HVRM(lwzcix, ld32u, 0x15, 0x15, PPC_CILDST)
2645 GEN_LDX_HVRM(lhzcix, ld16u, 0x15, 0x19, PPC_CILDST)
2646 GEN_LDX_HVRM(lbzcix, ld8u, 0x15, 0x1a, PPC_CILDST)
2647 
gen_ld(DisasContext * ctx)2648 static void gen_ld(DisasContext *ctx)
2649 {
2650     TCGv EA;
2651     if (Rc(ctx->opcode)) {
2652         if (unlikely(rA(ctx->opcode) == 0 ||
2653                      rA(ctx->opcode) == rD(ctx->opcode))) {
2654             gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
2655             return;
2656         }
2657     }
2658     gen_set_access_type(ctx, ACCESS_INT);
2659     EA = tcg_temp_new();
2660     gen_addr_imm_index(ctx, EA, 0x03);
2661     if (ctx->opcode & 0x02) {
2662         /* lwa (lwau is undefined) */
2663         gen_qemu_ld32s(ctx, cpu_gpr[rD(ctx->opcode)], EA);
2664     } else {
2665         /* ld - ldu */
2666         gen_qemu_ld64_i64(ctx, cpu_gpr[rD(ctx->opcode)], EA);
2667     }
2668     if (Rc(ctx->opcode)) {
2669         tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);
2670     }
2671     tcg_temp_free(EA);
2672 }
2673 
2674 /* lq */
gen_lq(DisasContext * ctx)2675 static void gen_lq(DisasContext *ctx)
2676 {
2677     int ra, rd;
2678     TCGv EA, hi, lo;
2679 
2680     /* lq is a legal user mode instruction starting in ISA 2.07 */
2681     bool legal_in_user_mode = (ctx->insns_flags2 & PPC2_LSQ_ISA207) != 0;
2682     bool le_is_supported = (ctx->insns_flags2 & PPC2_LSQ_ISA207) != 0;
2683 
2684     if (!legal_in_user_mode && ctx->pr) {
2685         gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC);
2686         return;
2687     }
2688 
2689     if (!le_is_supported && ctx->le_mode) {
2690         gen_align_no_le(ctx);
2691         return;
2692     }
2693     ra = rA(ctx->opcode);
2694     rd = rD(ctx->opcode);
2695     if (unlikely((rd & 1) || rd == ra)) {
2696         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
2697         return;
2698     }
2699 
2700     gen_set_access_type(ctx, ACCESS_INT);
2701     EA = tcg_temp_new();
2702     gen_addr_imm_index(ctx, EA, 0x0F);
2703 
2704     /* Note that the low part is always in RD+1, even in LE mode.  */
2705     lo = cpu_gpr[rd + 1];
2706     hi = cpu_gpr[rd];
2707 
2708     if (tb_cflags(ctx->base.tb) & CF_PARALLEL) {
2709         if (HAVE_ATOMIC128) {
2710             TCGv_i32 oi = tcg_temp_new_i32();
2711             if (ctx->le_mode) {
2712                 tcg_gen_movi_i32(oi, make_memop_idx(MO_LEQ, ctx->mem_idx));
2713                 gen_helper_lq_le_parallel(lo, cpu_env, EA, oi);
2714             } else {
2715                 tcg_gen_movi_i32(oi, make_memop_idx(MO_BEQ, ctx->mem_idx));
2716                 gen_helper_lq_be_parallel(lo, cpu_env, EA, oi);
2717             }
2718             tcg_temp_free_i32(oi);
2719             tcg_gen_ld_i64(hi, cpu_env, offsetof(CPUPPCState, retxh));
2720         } else {
2721             /* Restart with exclusive lock.  */
2722             gen_helper_exit_atomic(cpu_env);
2723             ctx->base.is_jmp = DISAS_NORETURN;
2724         }
2725     } else if (ctx->le_mode) {
2726         tcg_gen_qemu_ld_i64(lo, EA, ctx->mem_idx, MO_LEQ);
2727         gen_addr_add(ctx, EA, EA, 8);
2728         tcg_gen_qemu_ld_i64(hi, EA, ctx->mem_idx, MO_LEQ);
2729     } else {
2730         tcg_gen_qemu_ld_i64(hi, EA, ctx->mem_idx, MO_BEQ);
2731         gen_addr_add(ctx, EA, EA, 8);
2732         tcg_gen_qemu_ld_i64(lo, EA, ctx->mem_idx, MO_BEQ);
2733     }
2734     tcg_temp_free(EA);
2735 }
2736 #endif
2737 
2738 /***                              Integer store                            ***/
2739 #define GEN_ST(name, stop, opc, type)                                         \
2740 static void glue(gen_, name)(DisasContext *ctx)                               \
2741 {                                                                             \
2742     TCGv EA;                                                                  \
2743     gen_set_access_type(ctx, ACCESS_INT);                                     \
2744     EA = tcg_temp_new();                                                      \
2745     gen_addr_imm_index(ctx, EA, 0);                                           \
2746     gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA);                       \
2747     tcg_temp_free(EA);                                                        \
2748 }
2749 
2750 #define GEN_STU(name, stop, opc, type)                                        \
2751 static void glue(gen_, stop##u)(DisasContext *ctx)                            \
2752 {                                                                             \
2753     TCGv EA;                                                                  \
2754     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2755         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
2756         return;                                                               \
2757     }                                                                         \
2758     gen_set_access_type(ctx, ACCESS_INT);                                     \
2759     EA = tcg_temp_new();                                                      \
2760     if (type == PPC_64B)                                                      \
2761         gen_addr_imm_index(ctx, EA, 0x03);                                    \
2762     else                                                                      \
2763         gen_addr_imm_index(ctx, EA, 0);                                       \
2764     gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA);                       \
2765     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
2766     tcg_temp_free(EA);                                                        \
2767 }
2768 
2769 #define GEN_STUX(name, stop, opc2, opc3, type)                                \
2770 static void glue(gen_, name##ux)(DisasContext *ctx)                           \
2771 {                                                                             \
2772     TCGv EA;                                                                  \
2773     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2774         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
2775         return;                                                               \
2776     }                                                                         \
2777     gen_set_access_type(ctx, ACCESS_INT);                                     \
2778     EA = tcg_temp_new();                                                      \
2779     gen_addr_reg_index(ctx, EA);                                              \
2780     gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA);                       \
2781     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
2782     tcg_temp_free(EA);                                                        \
2783 }
2784 
2785 #define GEN_STX_E(name, stop, opc2, opc3, type, type2, chk)                   \
2786 static void glue(gen_, name##x)(DisasContext *ctx)                            \
2787 {                                                                             \
2788     TCGv EA;                                                                  \
2789     chk;                                                                      \
2790     gen_set_access_type(ctx, ACCESS_INT);                                     \
2791     EA = tcg_temp_new();                                                      \
2792     gen_addr_reg_index(ctx, EA);                                              \
2793     gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA);                       \
2794     tcg_temp_free(EA);                                                        \
2795 }
2796 #define GEN_STX(name, stop, opc2, opc3, type)                                 \
2797     GEN_STX_E(name, stop, opc2, opc3, type, PPC_NONE, CHK_NONE)
2798 
2799 #define GEN_STX_HVRM(name, stop, opc2, opc3, type)                            \
2800     GEN_STX_E(name, stop, opc2, opc3, type, PPC_NONE, CHK_HVRM)
2801 
2802 #define GEN_STS(name, stop, op, type)                                         \
2803 GEN_ST(name, stop, op | 0x20, type);                                          \
2804 GEN_STU(name, stop, op | 0x21, type);                                         \
2805 GEN_STUX(name, stop, 0x17, op | 0x01, type);                                  \
2806 GEN_STX(name, stop, 0x17, op | 0x00, type)
2807 
2808 /* stb stbu stbux stbx */
2809 GEN_STS(stb, st8, 0x06, PPC_INTEGER);
2810 /* sth sthu sthux sthx */
2811 GEN_STS(sth, st16, 0x0C, PPC_INTEGER);
2812 /* stw stwu stwux stwx */
2813 GEN_STS(stw, st32, 0x04, PPC_INTEGER);
2814 
2815 #define GEN_STEPX(name, stop, opc2, opc3)                                     \
2816 static void glue(gen_, name##epx)(DisasContext *ctx)                          \
2817 {                                                                             \
2818     TCGv EA;                                                                  \
2819     CHK_SV;                                                                   \
2820     gen_set_access_type(ctx, ACCESS_INT);                                     \
2821     EA = tcg_temp_new();                                                      \
2822     gen_addr_reg_index(ctx, EA);                                              \
2823     tcg_gen_qemu_st_tl(                                                       \
2824         cpu_gpr[rD(ctx->opcode)], EA, PPC_TLB_EPID_STORE, stop);              \
2825     tcg_temp_free(EA);                                                        \
2826 }
2827 
2828 GEN_STEPX(stb, DEF_MEMOP(MO_UB), 0x1F, 0x06)
2829 GEN_STEPX(sth, DEF_MEMOP(MO_UW), 0x1F, 0x0C)
2830 GEN_STEPX(stw, DEF_MEMOP(MO_UL), 0x1F, 0x04)
2831 #if defined(TARGET_PPC64)
2832 GEN_STEPX(std, DEF_MEMOP(MO_Q), 0x1d, 0x04)
2833 #endif
2834 
2835 #if defined(TARGET_PPC64)
2836 GEN_STUX(std, st64_i64, 0x15, 0x05, PPC_64B);
2837 GEN_STX(std, st64_i64, 0x15, 0x04, PPC_64B);
2838 GEN_STX_HVRM(stdcix, st64_i64, 0x15, 0x1f, PPC_CILDST)
2839 GEN_STX_HVRM(stwcix, st32, 0x15, 0x1c, PPC_CILDST)
2840 GEN_STX_HVRM(sthcix, st16, 0x15, 0x1d, PPC_CILDST)
2841 GEN_STX_HVRM(stbcix, st8, 0x15, 0x1e, PPC_CILDST)
2842 
gen_std(DisasContext * ctx)2843 static void gen_std(DisasContext *ctx)
2844 {
2845     int rs;
2846     TCGv EA;
2847 
2848     rs = rS(ctx->opcode);
2849     if ((ctx->opcode & 0x3) == 0x2) { /* stq */
2850         bool legal_in_user_mode = (ctx->insns_flags2 & PPC2_LSQ_ISA207) != 0;
2851         bool le_is_supported = (ctx->insns_flags2 & PPC2_LSQ_ISA207) != 0;
2852         TCGv hi, lo;
2853 
2854         if (!(ctx->insns_flags & PPC_64BX)) {
2855             gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
2856         }
2857 
2858         if (!legal_in_user_mode && ctx->pr) {
2859             gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC);
2860             return;
2861         }
2862 
2863         if (!le_is_supported && ctx->le_mode) {
2864             gen_align_no_le(ctx);
2865             return;
2866         }
2867 
2868         if (unlikely(rs & 1)) {
2869             gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
2870             return;
2871         }
2872         gen_set_access_type(ctx, ACCESS_INT);
2873         EA = tcg_temp_new();
2874         gen_addr_imm_index(ctx, EA, 0x03);
2875 
2876         /* Note that the low part is always in RS+1, even in LE mode.  */
2877         lo = cpu_gpr[rs + 1];
2878         hi = cpu_gpr[rs];
2879 
2880         if (tb_cflags(ctx->base.tb) & CF_PARALLEL) {
2881             if (HAVE_ATOMIC128) {
2882                 TCGv_i32 oi = tcg_temp_new_i32();
2883                 if (ctx->le_mode) {
2884                     tcg_gen_movi_i32(oi, make_memop_idx(MO_LEQ, ctx->mem_idx));
2885                     gen_helper_stq_le_parallel(cpu_env, EA, lo, hi, oi);
2886                 } else {
2887                     tcg_gen_movi_i32(oi, make_memop_idx(MO_BEQ, ctx->mem_idx));
2888                     gen_helper_stq_be_parallel(cpu_env, EA, lo, hi, oi);
2889                 }
2890                 tcg_temp_free_i32(oi);
2891             } else {
2892                 /* Restart with exclusive lock.  */
2893                 gen_helper_exit_atomic(cpu_env);
2894                 ctx->base.is_jmp = DISAS_NORETURN;
2895             }
2896         } else if (ctx->le_mode) {
2897             tcg_gen_qemu_st_i64(lo, EA, ctx->mem_idx, MO_LEQ);
2898             gen_addr_add(ctx, EA, EA, 8);
2899             tcg_gen_qemu_st_i64(hi, EA, ctx->mem_idx, MO_LEQ);
2900         } else {
2901             tcg_gen_qemu_st_i64(hi, EA, ctx->mem_idx, MO_BEQ);
2902             gen_addr_add(ctx, EA, EA, 8);
2903             tcg_gen_qemu_st_i64(lo, EA, ctx->mem_idx, MO_BEQ);
2904         }
2905         tcg_temp_free(EA);
2906     } else {
2907         /* std / stdu */
2908         if (Rc(ctx->opcode)) {
2909             if (unlikely(rA(ctx->opcode) == 0)) {
2910                 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
2911                 return;
2912             }
2913         }
2914         gen_set_access_type(ctx, ACCESS_INT);
2915         EA = tcg_temp_new();
2916         gen_addr_imm_index(ctx, EA, 0x03);
2917         gen_qemu_st64_i64(ctx, cpu_gpr[rs], EA);
2918         if (Rc(ctx->opcode)) {
2919             tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);
2920         }
2921         tcg_temp_free(EA);
2922     }
2923 }
2924 #endif
2925 /***                Integer load and store with byte reverse               ***/
2926 
2927 /* lhbrx */
2928 GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER);
2929 
2930 /* lwbrx */
2931 GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER);
2932 
2933 #if defined(TARGET_PPC64)
2934 /* ldbrx */
2935 GEN_LDX_E(ldbr, ld64ur_i64, 0x14, 0x10, PPC_NONE, PPC2_DBRX, CHK_NONE);
2936 /* stdbrx */
2937 GEN_STX_E(stdbr, st64r_i64, 0x14, 0x14, PPC_NONE, PPC2_DBRX, CHK_NONE);
2938 #endif  /* TARGET_PPC64 */
2939 
2940 /* sthbrx */
2941 GEN_STX(sthbr, st16r, 0x16, 0x1C, PPC_INTEGER);
2942 /* stwbrx */
2943 GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER);
2944 
2945 /***                    Integer load and store multiple                    ***/
2946 
2947 /* lmw */
gen_lmw(DisasContext * ctx)2948 static void gen_lmw(DisasContext *ctx)
2949 {
2950     TCGv t0;
2951     TCGv_i32 t1;
2952 
2953     if (ctx->le_mode) {
2954         gen_align_no_le(ctx);
2955         return;
2956     }
2957     gen_set_access_type(ctx, ACCESS_INT);
2958     t0 = tcg_temp_new();
2959     t1 = tcg_const_i32(rD(ctx->opcode));
2960     gen_addr_imm_index(ctx, t0, 0);
2961     gen_helper_lmw(cpu_env, t0, t1);
2962     tcg_temp_free(t0);
2963     tcg_temp_free_i32(t1);
2964 }
2965 
2966 /* stmw */
gen_stmw(DisasContext * ctx)2967 static void gen_stmw(DisasContext *ctx)
2968 {
2969     TCGv t0;
2970     TCGv_i32 t1;
2971 
2972     if (ctx->le_mode) {
2973         gen_align_no_le(ctx);
2974         return;
2975     }
2976     gen_set_access_type(ctx, ACCESS_INT);
2977     t0 = tcg_temp_new();
2978     t1 = tcg_const_i32(rS(ctx->opcode));
2979     gen_addr_imm_index(ctx, t0, 0);
2980     gen_helper_stmw(cpu_env, t0, t1);
2981     tcg_temp_free(t0);
2982     tcg_temp_free_i32(t1);
2983 }
2984 
2985 /***                    Integer load and store strings                     ***/
2986 
2987 /* lswi */
2988 /*
2989  * PowerPC32 specification says we must generate an exception if rA is
2990  * in the range of registers to be loaded.  In an other hand, IBM says
2991  * this is valid, but rA won't be loaded.  For now, I'll follow the
2992  * spec...
2993  */
gen_lswi(DisasContext * ctx)2994 static void gen_lswi(DisasContext *ctx)
2995 {
2996     TCGv t0;
2997     TCGv_i32 t1, t2;
2998     int nb = NB(ctx->opcode);
2999     int start = rD(ctx->opcode);
3000     int ra = rA(ctx->opcode);
3001     int nr;
3002 
3003     if (ctx->le_mode) {
3004         gen_align_no_le(ctx);
3005         return;
3006     }
3007     if (nb == 0) {
3008         nb = 32;
3009     }
3010     nr = DIV_ROUND_UP(nb, 4);
3011     if (unlikely(lsw_reg_in_range(start, nr, ra))) {
3012         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_LSWX);
3013         return;
3014     }
3015     gen_set_access_type(ctx, ACCESS_INT);
3016     t0 = tcg_temp_new();
3017     gen_addr_register(ctx, t0);
3018     t1 = tcg_const_i32(nb);
3019     t2 = tcg_const_i32(start);
3020     gen_helper_lsw(cpu_env, t0, t1, t2);
3021     tcg_temp_free(t0);
3022     tcg_temp_free_i32(t1);
3023     tcg_temp_free_i32(t2);
3024 }
3025 
3026 /* lswx */
gen_lswx(DisasContext * ctx)3027 static void gen_lswx(DisasContext *ctx)
3028 {
3029     TCGv t0;
3030     TCGv_i32 t1, t2, t3;
3031 
3032     if (ctx->le_mode) {
3033         gen_align_no_le(ctx);
3034         return;
3035     }
3036     gen_set_access_type(ctx, ACCESS_INT);
3037     t0 = tcg_temp_new();
3038     gen_addr_reg_index(ctx, t0);
3039     t1 = tcg_const_i32(rD(ctx->opcode));
3040     t2 = tcg_const_i32(rA(ctx->opcode));
3041     t3 = tcg_const_i32(rB(ctx->opcode));
3042     gen_helper_lswx(cpu_env, t0, t1, t2, t3);
3043     tcg_temp_free(t0);
3044     tcg_temp_free_i32(t1);
3045     tcg_temp_free_i32(t2);
3046     tcg_temp_free_i32(t3);
3047 }
3048 
3049 /* stswi */
gen_stswi(DisasContext * ctx)3050 static void gen_stswi(DisasContext *ctx)
3051 {
3052     TCGv t0;
3053     TCGv_i32 t1, t2;
3054     int nb = NB(ctx->opcode);
3055 
3056     if (ctx->le_mode) {
3057         gen_align_no_le(ctx);
3058         return;
3059     }
3060     gen_set_access_type(ctx, ACCESS_INT);
3061     t0 = tcg_temp_new();
3062     gen_addr_register(ctx, t0);
3063     if (nb == 0) {
3064         nb = 32;
3065     }
3066     t1 = tcg_const_i32(nb);
3067     t2 = tcg_const_i32(rS(ctx->opcode));
3068     gen_helper_stsw(cpu_env, t0, t1, t2);
3069     tcg_temp_free(t0);
3070     tcg_temp_free_i32(t1);
3071     tcg_temp_free_i32(t2);
3072 }
3073 
3074 /* stswx */
gen_stswx(DisasContext * ctx)3075 static void gen_stswx(DisasContext *ctx)
3076 {
3077     TCGv t0;
3078     TCGv_i32 t1, t2;
3079 
3080     if (ctx->le_mode) {
3081         gen_align_no_le(ctx);
3082         return;
3083     }
3084     gen_set_access_type(ctx, ACCESS_INT);
3085     t0 = tcg_temp_new();
3086     gen_addr_reg_index(ctx, t0);
3087     t1 = tcg_temp_new_i32();
3088     tcg_gen_trunc_tl_i32(t1, cpu_xer);
3089     tcg_gen_andi_i32(t1, t1, 0x7F);
3090     t2 = tcg_const_i32(rS(ctx->opcode));
3091     gen_helper_stsw(cpu_env, t0, t1, t2);
3092     tcg_temp_free(t0);
3093     tcg_temp_free_i32(t1);
3094     tcg_temp_free_i32(t2);
3095 }
3096 
3097 /***                        Memory synchronisation                         ***/
3098 /* eieio */
gen_eieio(DisasContext * ctx)3099 static void gen_eieio(DisasContext *ctx)
3100 {
3101     TCGBar bar = TCG_MO_LD_ST;
3102 
3103     /*
3104      * POWER9 has a eieio instruction variant using bit 6 as a hint to
3105      * tell the CPU it is a store-forwarding barrier.
3106      */
3107     if (ctx->opcode & 0x2000000) {
3108         /*
3109          * ISA says that "Reserved fields in instructions are ignored
3110          * by the processor". So ignore the bit 6 on non-POWER9 CPU but
3111          * as this is not an instruction software should be using,
3112          * complain to the user.
3113          */
3114         if (!(ctx->insns_flags2 & PPC2_ISA300)) {
3115             qemu_log_mask(LOG_GUEST_ERROR, "invalid eieio using bit 6 at @"
3116                           TARGET_FMT_lx "\n", ctx->base.pc_next - 4);
3117         } else {
3118             bar = TCG_MO_ST_LD;
3119         }
3120     }
3121 
3122     tcg_gen_mb(bar | TCG_BAR_SC);
3123 }
3124 
3125 #if !defined(CONFIG_USER_ONLY)
gen_check_tlb_flush(DisasContext * ctx,bool global)3126 static inline void gen_check_tlb_flush(DisasContext *ctx, bool global)
3127 {
3128     TCGv_i32 t;
3129     TCGLabel *l;
3130 
3131     if (!ctx->lazy_tlb_flush) {
3132         return;
3133     }
3134     l = gen_new_label();
3135     t = tcg_temp_new_i32();
3136     tcg_gen_ld_i32(t, cpu_env, offsetof(CPUPPCState, tlb_need_flush));
3137     tcg_gen_brcondi_i32(TCG_COND_EQ, t, 0, l);
3138     if (global) {
3139         gen_helper_check_tlb_flush_global(cpu_env);
3140     } else {
3141         gen_helper_check_tlb_flush_local(cpu_env);
3142     }
3143     gen_set_label(l);
3144     tcg_temp_free_i32(t);
3145 }
3146 #else
gen_check_tlb_flush(DisasContext * ctx,bool global)3147 static inline void gen_check_tlb_flush(DisasContext *ctx, bool global) { }
3148 #endif
3149 
3150 /* isync */
gen_isync(DisasContext * ctx)3151 static void gen_isync(DisasContext *ctx)
3152 {
3153     /*
3154      * We need to check for a pending TLB flush. This can only happen in
3155      * kernel mode however so check MSR_PR
3156      */
3157     if (!ctx->pr) {
3158         gen_check_tlb_flush(ctx, false);
3159     }
3160     tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
3161     gen_stop_exception(ctx);
3162 }
3163 
3164 #define MEMOP_GET_SIZE(x)  (1 << ((x) & MO_SIZE))
3165 
gen_load_locked(DisasContext * ctx,MemOp memop)3166 static void gen_load_locked(DisasContext *ctx, MemOp memop)
3167 {
3168     TCGv gpr = cpu_gpr[rD(ctx->opcode)];
3169     TCGv t0 = tcg_temp_new();
3170 
3171     gen_set_access_type(ctx, ACCESS_RES);
3172     gen_addr_reg_index(ctx, t0);
3173     tcg_gen_qemu_ld_tl(gpr, t0, ctx->mem_idx, memop | MO_ALIGN);
3174     tcg_gen_mov_tl(cpu_reserve, t0);
3175     tcg_gen_mov_tl(cpu_reserve_val, gpr);
3176     tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
3177     tcg_temp_free(t0);
3178 }
3179 
3180 #define LARX(name, memop)                  \
3181 static void gen_##name(DisasContext *ctx)  \
3182 {                                          \
3183     gen_load_locked(ctx, memop);           \
3184 }
3185 
3186 /* lwarx */
LARX(lbarx,DEF_MEMOP (MO_UB))3187 LARX(lbarx, DEF_MEMOP(MO_UB))
3188 LARX(lharx, DEF_MEMOP(MO_UW))
3189 LARX(lwarx, DEF_MEMOP(MO_UL))
3190 
3191 static void gen_fetch_inc_conditional(DisasContext *ctx, MemOp memop,
3192                                       TCGv EA, TCGCond cond, int addend)
3193 {
3194     TCGv t = tcg_temp_new();
3195     TCGv t2 = tcg_temp_new();
3196     TCGv u = tcg_temp_new();
3197 
3198     tcg_gen_qemu_ld_tl(t, EA, ctx->mem_idx, memop);
3199     tcg_gen_addi_tl(t2, EA, MEMOP_GET_SIZE(memop));
3200     tcg_gen_qemu_ld_tl(t2, t2, ctx->mem_idx, memop);
3201     tcg_gen_addi_tl(u, t, addend);
3202 
3203     /* E.g. for fetch and increment bounded... */
3204     /* mem(EA,s) = (t != t2 ? u = t + 1 : t) */
3205     tcg_gen_movcond_tl(cond, u, t, t2, u, t);
3206     tcg_gen_qemu_st_tl(u, EA, ctx->mem_idx, memop);
3207 
3208     /* RT = (t != t2 ? t : u = 1<<(s*8-1)) */
3209     tcg_gen_movi_tl(u, 1 << (MEMOP_GET_SIZE(memop) * 8 - 1));
3210     tcg_gen_movcond_tl(cond, cpu_gpr[rD(ctx->opcode)], t, t2, t, u);
3211 
3212     tcg_temp_free(t);
3213     tcg_temp_free(t2);
3214     tcg_temp_free(u);
3215 }
3216 
gen_ld_atomic(DisasContext * ctx,MemOp memop)3217 static void gen_ld_atomic(DisasContext *ctx, MemOp memop)
3218 {
3219     uint32_t gpr_FC = FC(ctx->opcode);
3220     TCGv EA = tcg_temp_new();
3221     int rt = rD(ctx->opcode);
3222     bool need_serial;
3223     TCGv src, dst;
3224 
3225     gen_addr_register(ctx, EA);
3226     dst = cpu_gpr[rt];
3227     src = cpu_gpr[(rt + 1) & 31];
3228 
3229     need_serial = false;
3230     memop |= MO_ALIGN;
3231     switch (gpr_FC) {
3232     case 0: /* Fetch and add */
3233         tcg_gen_atomic_fetch_add_tl(dst, EA, src, ctx->mem_idx, memop);
3234         break;
3235     case 1: /* Fetch and xor */
3236         tcg_gen_atomic_fetch_xor_tl(dst, EA, src, ctx->mem_idx, memop);
3237         break;
3238     case 2: /* Fetch and or */
3239         tcg_gen_atomic_fetch_or_tl(dst, EA, src, ctx->mem_idx, memop);
3240         break;
3241     case 3: /* Fetch and 'and' */
3242         tcg_gen_atomic_fetch_and_tl(dst, EA, src, ctx->mem_idx, memop);
3243         break;
3244     case 4:  /* Fetch and max unsigned */
3245         tcg_gen_atomic_fetch_umax_tl(dst, EA, src, ctx->mem_idx, memop);
3246         break;
3247     case 5:  /* Fetch and max signed */
3248         tcg_gen_atomic_fetch_smax_tl(dst, EA, src, ctx->mem_idx, memop);
3249         break;
3250     case 6:  /* Fetch and min unsigned */
3251         tcg_gen_atomic_fetch_umin_tl(dst, EA, src, ctx->mem_idx, memop);
3252         break;
3253     case 7:  /* Fetch and min signed */
3254         tcg_gen_atomic_fetch_smin_tl(dst, EA, src, ctx->mem_idx, memop);
3255         break;
3256     case 8: /* Swap */
3257         tcg_gen_atomic_xchg_tl(dst, EA, src, ctx->mem_idx, memop);
3258         break;
3259 
3260     case 16: /* Compare and swap not equal */
3261         if (tb_cflags(ctx->base.tb) & CF_PARALLEL) {
3262             need_serial = true;
3263         } else {
3264             TCGv t0 = tcg_temp_new();
3265             TCGv t1 = tcg_temp_new();
3266 
3267             tcg_gen_qemu_ld_tl(t0, EA, ctx->mem_idx, memop);
3268             if ((memop & MO_SIZE) == MO_64 || TARGET_LONG_BITS == 32) {
3269                 tcg_gen_mov_tl(t1, src);
3270             } else {
3271                 tcg_gen_ext32u_tl(t1, src);
3272             }
3273             tcg_gen_movcond_tl(TCG_COND_NE, t1, t0, t1,
3274                                cpu_gpr[(rt + 2) & 31], t0);
3275             tcg_gen_qemu_st_tl(t1, EA, ctx->mem_idx, memop);
3276             tcg_gen_mov_tl(dst, t0);
3277 
3278             tcg_temp_free(t0);
3279             tcg_temp_free(t1);
3280         }
3281         break;
3282 
3283     case 24: /* Fetch and increment bounded */
3284         if (tb_cflags(ctx->base.tb) & CF_PARALLEL) {
3285             need_serial = true;
3286         } else {
3287             gen_fetch_inc_conditional(ctx, memop, EA, TCG_COND_NE, 1);
3288         }
3289         break;
3290     case 25: /* Fetch and increment equal */
3291         if (tb_cflags(ctx->base.tb) & CF_PARALLEL) {
3292             need_serial = true;
3293         } else {
3294             gen_fetch_inc_conditional(ctx, memop, EA, TCG_COND_EQ, 1);
3295         }
3296         break;
3297     case 28: /* Fetch and decrement bounded */
3298         if (tb_cflags(ctx->base.tb) & CF_PARALLEL) {
3299             need_serial = true;
3300         } else {
3301             gen_fetch_inc_conditional(ctx, memop, EA, TCG_COND_NE, -1);
3302         }
3303         break;
3304 
3305     default:
3306         /* invoke data storage error handler */
3307         gen_exception_err(ctx, POWERPC_EXCP_DSI, POWERPC_EXCP_INVAL);
3308     }
3309     tcg_temp_free(EA);
3310 
3311     if (need_serial) {
3312         /* Restart with exclusive lock.  */
3313         gen_helper_exit_atomic(cpu_env);
3314         ctx->base.is_jmp = DISAS_NORETURN;
3315     }
3316 }
3317 
gen_lwat(DisasContext * ctx)3318 static void gen_lwat(DisasContext *ctx)
3319 {
3320     gen_ld_atomic(ctx, DEF_MEMOP(MO_UL));
3321 }
3322 
3323 #ifdef TARGET_PPC64
gen_ldat(DisasContext * ctx)3324 static void gen_ldat(DisasContext *ctx)
3325 {
3326     gen_ld_atomic(ctx, DEF_MEMOP(MO_Q));
3327 }
3328 #endif
3329 
gen_st_atomic(DisasContext * ctx,MemOp memop)3330 static void gen_st_atomic(DisasContext *ctx, MemOp memop)
3331 {
3332     uint32_t gpr_FC = FC(ctx->opcode);
3333     TCGv EA = tcg_temp_new();
3334     TCGv src, discard;
3335 
3336     gen_addr_register(ctx, EA);
3337     src = cpu_gpr[rD(ctx->opcode)];
3338     discard = tcg_temp_new();
3339 
3340     memop |= MO_ALIGN;
3341     switch (gpr_FC) {
3342     case 0: /* add and Store */
3343         tcg_gen_atomic_add_fetch_tl(discard, EA, src, ctx->mem_idx, memop);
3344         break;
3345     case 1: /* xor and Store */
3346         tcg_gen_atomic_xor_fetch_tl(discard, EA, src, ctx->mem_idx, memop);
3347         break;
3348     case 2: /* Or and Store */
3349         tcg_gen_atomic_or_fetch_tl(discard, EA, src, ctx->mem_idx, memop);
3350         break;
3351     case 3: /* 'and' and Store */
3352         tcg_gen_atomic_and_fetch_tl(discard, EA, src, ctx->mem_idx, memop);
3353         break;
3354     case 4:  /* Store max unsigned */
3355         tcg_gen_atomic_umax_fetch_tl(discard, EA, src, ctx->mem_idx, memop);
3356         break;
3357     case 5:  /* Store max signed */
3358         tcg_gen_atomic_smax_fetch_tl(discard, EA, src, ctx->mem_idx, memop);
3359         break;
3360     case 6:  /* Store min unsigned */
3361         tcg_gen_atomic_umin_fetch_tl(discard, EA, src, ctx->mem_idx, memop);
3362         break;
3363     case 7:  /* Store min signed */
3364         tcg_gen_atomic_smin_fetch_tl(discard, EA, src, ctx->mem_idx, memop);
3365         break;
3366     case 24: /* Store twin  */
3367         if (tb_cflags(ctx->base.tb) & CF_PARALLEL) {
3368             /* Restart with exclusive lock.  */
3369             gen_helper_exit_atomic(cpu_env);
3370             ctx->base.is_jmp = DISAS_NORETURN;
3371         } else {
3372             TCGv t = tcg_temp_new();
3373             TCGv t2 = tcg_temp_new();
3374             TCGv s = tcg_temp_new();
3375             TCGv s2 = tcg_temp_new();
3376             TCGv ea_plus_s = tcg_temp_new();
3377 
3378             tcg_gen_qemu_ld_tl(t, EA, ctx->mem_idx, memop);
3379             tcg_gen_addi_tl(ea_plus_s, EA, MEMOP_GET_SIZE(memop));
3380             tcg_gen_qemu_ld_tl(t2, ea_plus_s, ctx->mem_idx, memop);
3381             tcg_gen_movcond_tl(TCG_COND_EQ, s, t, t2, src, t);
3382             tcg_gen_movcond_tl(TCG_COND_EQ, s2, t, t2, src, t2);
3383             tcg_gen_qemu_st_tl(s, EA, ctx->mem_idx, memop);
3384             tcg_gen_qemu_st_tl(s2, ea_plus_s, ctx->mem_idx, memop);
3385 
3386             tcg_temp_free(ea_plus_s);
3387             tcg_temp_free(s2);
3388             tcg_temp_free(s);
3389             tcg_temp_free(t2);
3390             tcg_temp_free(t);
3391         }
3392         break;
3393     default:
3394         /* invoke data storage error handler */
3395         gen_exception_err(ctx, POWERPC_EXCP_DSI, POWERPC_EXCP_INVAL);
3396     }
3397     tcg_temp_free(discard);
3398     tcg_temp_free(EA);
3399 }
3400 
gen_stwat(DisasContext * ctx)3401 static void gen_stwat(DisasContext *ctx)
3402 {
3403     gen_st_atomic(ctx, DEF_MEMOP(MO_UL));
3404 }
3405 
3406 #ifdef TARGET_PPC64
gen_stdat(DisasContext * ctx)3407 static void gen_stdat(DisasContext *ctx)
3408 {
3409     gen_st_atomic(ctx, DEF_MEMOP(MO_Q));
3410 }
3411 #endif
3412 
gen_conditional_store(DisasContext * ctx,MemOp memop)3413 static void gen_conditional_store(DisasContext *ctx, MemOp memop)
3414 {
3415     TCGLabel *l1 = gen_new_label();
3416     TCGLabel *l2 = gen_new_label();
3417     TCGv t0 = tcg_temp_new();
3418     int reg = rS(ctx->opcode);
3419 
3420     gen_set_access_type(ctx, ACCESS_RES);
3421     gen_addr_reg_index(ctx, t0);
3422     tcg_gen_brcond_tl(TCG_COND_NE, t0, cpu_reserve, l1);
3423     tcg_temp_free(t0);
3424 
3425     t0 = tcg_temp_new();
3426     tcg_gen_atomic_cmpxchg_tl(t0, cpu_reserve, cpu_reserve_val,
3427                               cpu_gpr[reg], ctx->mem_idx,
3428                               DEF_MEMOP(memop) | MO_ALIGN);
3429     tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_reserve_val);
3430     tcg_gen_shli_tl(t0, t0, CRF_EQ_BIT);
3431     tcg_gen_or_tl(t0, t0, cpu_so);
3432     tcg_gen_trunc_tl_i32(cpu_crf[0], t0);
3433     tcg_temp_free(t0);
3434     tcg_gen_br(l2);
3435 
3436     gen_set_label(l1);
3437 
3438     /*
3439      * Address mismatch implies failure.  But we still need to provide
3440      * the memory barrier semantics of the instruction.
3441      */
3442     tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
3443     tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
3444 
3445     gen_set_label(l2);
3446     tcg_gen_movi_tl(cpu_reserve, -1);
3447 }
3448 
3449 #define STCX(name, memop)                  \
3450 static void gen_##name(DisasContext *ctx)  \
3451 {                                          \
3452     gen_conditional_store(ctx, memop);     \
3453 }
3454 
STCX(stbcx_,DEF_MEMOP (MO_UB))3455 STCX(stbcx_, DEF_MEMOP(MO_UB))
3456 STCX(sthcx_, DEF_MEMOP(MO_UW))
3457 STCX(stwcx_, DEF_MEMOP(MO_UL))
3458 
3459 #if defined(TARGET_PPC64)
3460 /* ldarx */
3461 LARX(ldarx, DEF_MEMOP(MO_Q))
3462 /* stdcx. */
3463 STCX(stdcx_, DEF_MEMOP(MO_Q))
3464 
3465 /* lqarx */
3466 static void gen_lqarx(DisasContext *ctx)
3467 {
3468     int rd = rD(ctx->opcode);
3469     TCGv EA, hi, lo;
3470 
3471     if (unlikely((rd & 1) || (rd == rA(ctx->opcode)) ||
3472                  (rd == rB(ctx->opcode)))) {
3473         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
3474         return;
3475     }
3476 
3477     gen_set_access_type(ctx, ACCESS_RES);
3478     EA = tcg_temp_new();
3479     gen_addr_reg_index(ctx, EA);
3480 
3481     /* Note that the low part is always in RD+1, even in LE mode.  */
3482     lo = cpu_gpr[rd + 1];
3483     hi = cpu_gpr[rd];
3484 
3485     if (tb_cflags(ctx->base.tb) & CF_PARALLEL) {
3486         if (HAVE_ATOMIC128) {
3487             TCGv_i32 oi = tcg_temp_new_i32();
3488             if (ctx->le_mode) {
3489                 tcg_gen_movi_i32(oi, make_memop_idx(MO_LEQ | MO_ALIGN_16,
3490                                                     ctx->mem_idx));
3491                 gen_helper_lq_le_parallel(lo, cpu_env, EA, oi);
3492             } else {
3493                 tcg_gen_movi_i32(oi, make_memop_idx(MO_BEQ | MO_ALIGN_16,
3494                                                     ctx->mem_idx));
3495                 gen_helper_lq_be_parallel(lo, cpu_env, EA, oi);
3496             }
3497             tcg_temp_free_i32(oi);
3498             tcg_gen_ld_i64(hi, cpu_env, offsetof(CPUPPCState, retxh));
3499         } else {
3500             /* Restart with exclusive lock.  */
3501             gen_helper_exit_atomic(cpu_env);
3502             ctx->base.is_jmp = DISAS_NORETURN;
3503             tcg_temp_free(EA);
3504             return;
3505         }
3506     } else if (ctx->le_mode) {
3507         tcg_gen_qemu_ld_i64(lo, EA, ctx->mem_idx, MO_LEQ | MO_ALIGN_16);
3508         tcg_gen_mov_tl(cpu_reserve, EA);
3509         gen_addr_add(ctx, EA, EA, 8);
3510         tcg_gen_qemu_ld_i64(hi, EA, ctx->mem_idx, MO_LEQ);
3511     } else {
3512         tcg_gen_qemu_ld_i64(hi, EA, ctx->mem_idx, MO_BEQ | MO_ALIGN_16);
3513         tcg_gen_mov_tl(cpu_reserve, EA);
3514         gen_addr_add(ctx, EA, EA, 8);
3515         tcg_gen_qemu_ld_i64(lo, EA, ctx->mem_idx, MO_BEQ);
3516     }
3517     tcg_temp_free(EA);
3518 
3519     tcg_gen_st_tl(hi, cpu_env, offsetof(CPUPPCState, reserve_val));
3520     tcg_gen_st_tl(lo, cpu_env, offsetof(CPUPPCState, reserve_val2));
3521 }
3522 
3523 /* stqcx. */
gen_stqcx_(DisasContext * ctx)3524 static void gen_stqcx_(DisasContext *ctx)
3525 {
3526     int rs = rS(ctx->opcode);
3527     TCGv EA, hi, lo;
3528 
3529     if (unlikely(rs & 1)) {
3530         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
3531         return;
3532     }
3533 
3534     gen_set_access_type(ctx, ACCESS_RES);
3535     EA = tcg_temp_new();
3536     gen_addr_reg_index(ctx, EA);
3537 
3538     /* Note that the low part is always in RS+1, even in LE mode.  */
3539     lo = cpu_gpr[rs + 1];
3540     hi = cpu_gpr[rs];
3541 
3542     if (tb_cflags(ctx->base.tb) & CF_PARALLEL) {
3543         if (HAVE_CMPXCHG128) {
3544             TCGv_i32 oi = tcg_const_i32(DEF_MEMOP(MO_Q) | MO_ALIGN_16);
3545             if (ctx->le_mode) {
3546                 gen_helper_stqcx_le_parallel(cpu_crf[0], cpu_env,
3547                                              EA, lo, hi, oi);
3548             } else {
3549                 gen_helper_stqcx_be_parallel(cpu_crf[0], cpu_env,
3550                                              EA, lo, hi, oi);
3551             }
3552             tcg_temp_free_i32(oi);
3553         } else {
3554             /* Restart with exclusive lock.  */
3555             gen_helper_exit_atomic(cpu_env);
3556             ctx->base.is_jmp = DISAS_NORETURN;
3557         }
3558         tcg_temp_free(EA);
3559     } else {
3560         TCGLabel *lab_fail = gen_new_label();
3561         TCGLabel *lab_over = gen_new_label();
3562         TCGv_i64 t0 = tcg_temp_new_i64();
3563         TCGv_i64 t1 = tcg_temp_new_i64();
3564 
3565         tcg_gen_brcond_tl(TCG_COND_NE, EA, cpu_reserve, lab_fail);
3566         tcg_temp_free(EA);
3567 
3568         gen_qemu_ld64_i64(ctx, t0, cpu_reserve);
3569         tcg_gen_ld_i64(t1, cpu_env, (ctx->le_mode
3570                                      ? offsetof(CPUPPCState, reserve_val2)
3571                                      : offsetof(CPUPPCState, reserve_val)));
3572         tcg_gen_brcond_i64(TCG_COND_NE, t0, t1, lab_fail);
3573 
3574         tcg_gen_addi_i64(t0, cpu_reserve, 8);
3575         gen_qemu_ld64_i64(ctx, t0, t0);
3576         tcg_gen_ld_i64(t1, cpu_env, (ctx->le_mode
3577                                      ? offsetof(CPUPPCState, reserve_val)
3578                                      : offsetof(CPUPPCState, reserve_val2)));
3579         tcg_gen_brcond_i64(TCG_COND_NE, t0, t1, lab_fail);
3580 
3581         /* Success */
3582         gen_qemu_st64_i64(ctx, ctx->le_mode ? lo : hi, cpu_reserve);
3583         tcg_gen_addi_i64(t0, cpu_reserve, 8);
3584         gen_qemu_st64_i64(ctx, ctx->le_mode ? hi : lo, t0);
3585 
3586         tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
3587         tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], CRF_EQ);
3588         tcg_gen_br(lab_over);
3589 
3590         gen_set_label(lab_fail);
3591         tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
3592 
3593         gen_set_label(lab_over);
3594         tcg_gen_movi_tl(cpu_reserve, -1);
3595         tcg_temp_free_i64(t0);
3596         tcg_temp_free_i64(t1);
3597     }
3598 }
3599 #endif /* defined(TARGET_PPC64) */
3600 
3601 /* sync */
gen_sync(DisasContext * ctx)3602 static void gen_sync(DisasContext *ctx)
3603 {
3604     uint32_t l = (ctx->opcode >> 21) & 3;
3605 
3606     /*
3607      * We may need to check for a pending TLB flush.
3608      *
3609      * We do this on ptesync (l == 2) on ppc64 and any sync pn ppc32.
3610      *
3611      * Additionally, this can only happen in kernel mode however so
3612      * check MSR_PR as well.
3613      */
3614     if (((l == 2) || !(ctx->insns_flags & PPC_64B)) && !ctx->pr) {
3615         gen_check_tlb_flush(ctx, true);
3616     }
3617     tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
3618 }
3619 
3620 /* wait */
gen_wait(DisasContext * ctx)3621 static void gen_wait(DisasContext *ctx)
3622 {
3623     TCGv_i32 t0 = tcg_const_i32(1);
3624     tcg_gen_st_i32(t0, cpu_env,
3625                    -offsetof(PowerPCCPU, env) + offsetof(CPUState, halted));
3626     tcg_temp_free_i32(t0);
3627     /* Stop translation, as the CPU is supposed to sleep from now */
3628     gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next);
3629 }
3630 
3631 #if defined(TARGET_PPC64)
gen_doze(DisasContext * ctx)3632 static void gen_doze(DisasContext *ctx)
3633 {
3634 #if defined(CONFIG_USER_ONLY)
3635     GEN_PRIV;
3636 #else
3637     TCGv_i32 t;
3638 
3639     CHK_HV;
3640     t = tcg_const_i32(PPC_PM_DOZE);
3641     gen_helper_pminsn(cpu_env, t);
3642     tcg_temp_free_i32(t);
3643     /* Stop translation, as the CPU is supposed to sleep from now */
3644     gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next);
3645 #endif /* defined(CONFIG_USER_ONLY) */
3646 }
3647 
gen_nap(DisasContext * ctx)3648 static void gen_nap(DisasContext *ctx)
3649 {
3650 #if defined(CONFIG_USER_ONLY)
3651     GEN_PRIV;
3652 #else
3653     TCGv_i32 t;
3654 
3655     CHK_HV;
3656     t = tcg_const_i32(PPC_PM_NAP);
3657     gen_helper_pminsn(cpu_env, t);
3658     tcg_temp_free_i32(t);
3659     /* Stop translation, as the CPU is supposed to sleep from now */
3660     gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next);
3661 #endif /* defined(CONFIG_USER_ONLY) */
3662 }
3663 
gen_stop(DisasContext * ctx)3664 static void gen_stop(DisasContext *ctx)
3665 {
3666 #if defined(CONFIG_USER_ONLY)
3667     GEN_PRIV;
3668 #else
3669     TCGv_i32 t;
3670 
3671     CHK_HV;
3672     t = tcg_const_i32(PPC_PM_STOP);
3673     gen_helper_pminsn(cpu_env, t);
3674     tcg_temp_free_i32(t);
3675     /* Stop translation, as the CPU is supposed to sleep from now */
3676     gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next);
3677 #endif /* defined(CONFIG_USER_ONLY) */
3678 }
3679 
gen_sleep(DisasContext * ctx)3680 static void gen_sleep(DisasContext *ctx)
3681 {
3682 #if defined(CONFIG_USER_ONLY)
3683     GEN_PRIV;
3684 #else
3685     TCGv_i32 t;
3686 
3687     CHK_HV;
3688     t = tcg_const_i32(PPC_PM_SLEEP);
3689     gen_helper_pminsn(cpu_env, t);
3690     tcg_temp_free_i32(t);
3691     /* Stop translation, as the CPU is supposed to sleep from now */
3692     gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next);
3693 #endif /* defined(CONFIG_USER_ONLY) */
3694 }
3695 
gen_rvwinkle(DisasContext * ctx)3696 static void gen_rvwinkle(DisasContext *ctx)
3697 {
3698 #if defined(CONFIG_USER_ONLY)
3699     GEN_PRIV;
3700 #else
3701     TCGv_i32 t;
3702 
3703     CHK_HV;
3704     t = tcg_const_i32(PPC_PM_RVWINKLE);
3705     gen_helper_pminsn(cpu_env, t);
3706     tcg_temp_free_i32(t);
3707     /* Stop translation, as the CPU is supposed to sleep from now */
3708     gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next);
3709 #endif /* defined(CONFIG_USER_ONLY) */
3710 }
3711 #endif /* #if defined(TARGET_PPC64) */
3712 
gen_update_cfar(DisasContext * ctx,target_ulong nip)3713 static inline void gen_update_cfar(DisasContext *ctx, target_ulong nip)
3714 {
3715 #if defined(TARGET_PPC64)
3716     if (ctx->has_cfar) {
3717         tcg_gen_movi_tl(cpu_cfar, nip);
3718     }
3719 #endif
3720 }
3721 
use_goto_tb(DisasContext * ctx,target_ulong dest)3722 static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
3723 {
3724     if (unlikely(ctx->singlestep_enabled)) {
3725         return false;
3726     }
3727 
3728 #ifndef CONFIG_USER_ONLY
3729     return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
3730 #else
3731     return true;
3732 #endif
3733 }
3734 
gen_lookup_and_goto_ptr(DisasContext * ctx)3735 static void gen_lookup_and_goto_ptr(DisasContext *ctx)
3736 {
3737     int sse = ctx->singlestep_enabled;
3738     if (unlikely(sse)) {
3739         if (sse & GDBSTUB_SINGLE_STEP) {
3740             gen_debug_exception(ctx);
3741         } else if (sse & (CPU_SINGLE_STEP | CPU_BRANCH_STEP)) {
3742             uint32_t excp = gen_prep_dbgex(ctx);
3743             gen_exception(ctx, excp);
3744         }
3745         tcg_gen_exit_tb(NULL, 0);
3746     } else {
3747         tcg_gen_lookup_and_goto_ptr();
3748     }
3749 }
3750 
3751 /***                                Branch                                 ***/
gen_goto_tb(DisasContext * ctx,int n,target_ulong dest)3752 static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
3753 {
3754     if (NARROW_MODE(ctx)) {
3755         dest = (uint32_t) dest;
3756     }
3757     if (use_goto_tb(ctx, dest)) {
3758         tcg_gen_goto_tb(n);
3759         tcg_gen_movi_tl(cpu_nip, dest & ~3);
3760         tcg_gen_exit_tb(ctx->base.tb, n);
3761     } else {
3762         tcg_gen_movi_tl(cpu_nip, dest & ~3);
3763         gen_lookup_and_goto_ptr(ctx);
3764     }
3765 }
3766 
gen_setlr(DisasContext * ctx,target_ulong nip)3767 static inline void gen_setlr(DisasContext *ctx, target_ulong nip)
3768 {
3769     if (NARROW_MODE(ctx)) {
3770         nip = (uint32_t)nip;
3771     }
3772     tcg_gen_movi_tl(cpu_lr, nip);
3773 }
3774 
3775 /* b ba bl bla */
gen_b(DisasContext * ctx)3776 static void gen_b(DisasContext *ctx)
3777 {
3778     target_ulong li, target;
3779 
3780     ctx->exception = POWERPC_EXCP_BRANCH;
3781     /* sign extend LI */
3782     li = LI(ctx->opcode);
3783     li = (li ^ 0x02000000) - 0x02000000;
3784     if (likely(AA(ctx->opcode) == 0)) {
3785         target = ctx->base.pc_next + li - 4;
3786     } else {
3787         target = li;
3788     }
3789     if (LK(ctx->opcode)) {
3790         gen_setlr(ctx, ctx->base.pc_next);
3791     }
3792     gen_update_cfar(ctx, ctx->base.pc_next - 4);
3793     gen_goto_tb(ctx, 0, target);
3794 }
3795 
3796 #define BCOND_IM  0
3797 #define BCOND_LR  1
3798 #define BCOND_CTR 2
3799 #define BCOND_TAR 3
3800 
gen_bcond(DisasContext * ctx,int type)3801 static void gen_bcond(DisasContext *ctx, int type)
3802 {
3803     uint32_t bo = BO(ctx->opcode);
3804     TCGLabel *l1;
3805     TCGv target;
3806     ctx->exception = POWERPC_EXCP_BRANCH;
3807 
3808     if (type == BCOND_LR || type == BCOND_CTR || type == BCOND_TAR) {
3809         target = tcg_temp_local_new();
3810         if (type == BCOND_CTR) {
3811             tcg_gen_mov_tl(target, cpu_ctr);
3812         } else if (type == BCOND_TAR) {
3813             gen_load_spr(target, SPR_TAR);
3814         } else {
3815             tcg_gen_mov_tl(target, cpu_lr);
3816         }
3817     } else {
3818         target = NULL;
3819     }
3820     if (LK(ctx->opcode)) {
3821         gen_setlr(ctx, ctx->base.pc_next);
3822     }
3823     l1 = gen_new_label();
3824     if ((bo & 0x4) == 0) {
3825         /* Decrement and test CTR */
3826         TCGv temp = tcg_temp_new();
3827 
3828         if (type == BCOND_CTR) {
3829             /*
3830              * All ISAs up to v3 describe this form of bcctr as invalid but
3831              * some processors, ie. 64-bit server processors compliant with
3832              * arch 2.x, do implement a "test and decrement" logic instead,
3833              * as described in their respective UMs. This logic involves CTR
3834              * to act as both the branch target and a counter, which makes
3835              * it basically useless and thus never used in real code.
3836              *
3837              * This form was hence chosen to trigger extra micro-architectural
3838              * side-effect on real HW needed for the Spectre v2 workaround.
3839              * It is up to guests that implement such workaround, ie. linux, to
3840              * use this form in a way it just triggers the side-effect without
3841              * doing anything else harmful.
3842              */
3843             if (unlikely(!is_book3s_arch2x(ctx))) {
3844                 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
3845                 tcg_temp_free(temp);
3846                 tcg_temp_free(target);
3847                 return;
3848             }
3849 
3850             if (NARROW_MODE(ctx)) {
3851                 tcg_gen_ext32u_tl(temp, cpu_ctr);
3852             } else {
3853                 tcg_gen_mov_tl(temp, cpu_ctr);
3854             }
3855             if (bo & 0x2) {
3856                 tcg_gen_brcondi_tl(TCG_COND_NE, temp, 0, l1);
3857             } else {
3858                 tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1);
3859             }
3860             tcg_gen_subi_tl(cpu_ctr, cpu_ctr, 1);
3861         } else {
3862             tcg_gen_subi_tl(cpu_ctr, cpu_ctr, 1);
3863             if (NARROW_MODE(ctx)) {
3864                 tcg_gen_ext32u_tl(temp, cpu_ctr);
3865             } else {
3866                 tcg_gen_mov_tl(temp, cpu_ctr);
3867             }
3868             if (bo & 0x2) {
3869                 tcg_gen_brcondi_tl(TCG_COND_NE, temp, 0, l1);
3870             } else {
3871                 tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1);
3872             }
3873         }
3874         tcg_temp_free(temp);
3875     }
3876     if ((bo & 0x10) == 0) {
3877         /* Test CR */
3878         uint32_t bi = BI(ctx->opcode);
3879         uint32_t mask = 0x08 >> (bi & 0x03);
3880         TCGv_i32 temp = tcg_temp_new_i32();
3881 
3882         if (bo & 0x8) {
3883             tcg_gen_andi_i32(temp, cpu_crf[bi >> 2], mask);
3884             tcg_gen_brcondi_i32(TCG_COND_EQ, temp, 0, l1);
3885         } else {
3886             tcg_gen_andi_i32(temp, cpu_crf[bi >> 2], mask);
3887             tcg_gen_brcondi_i32(TCG_COND_NE, temp, 0, l1);
3888         }
3889         tcg_temp_free_i32(temp);
3890     }
3891     gen_update_cfar(ctx, ctx->base.pc_next - 4);
3892     if (type == BCOND_IM) {
3893         target_ulong li = (target_long)((int16_t)(BD(ctx->opcode)));
3894         if (likely(AA(ctx->opcode) == 0)) {
3895             gen_goto_tb(ctx, 0, ctx->base.pc_next + li - 4);
3896         } else {
3897             gen_goto_tb(ctx, 0, li);
3898         }
3899     } else {
3900         if (NARROW_MODE(ctx)) {
3901             tcg_gen_andi_tl(cpu_nip, target, (uint32_t)~3);
3902         } else {
3903             tcg_gen_andi_tl(cpu_nip, target, ~3);
3904         }
3905         gen_lookup_and_goto_ptr(ctx);
3906         tcg_temp_free(target);
3907     }
3908     if ((bo & 0x14) != 0x14) {
3909         /* fallthrough case */
3910         gen_set_label(l1);
3911         gen_goto_tb(ctx, 1, ctx->base.pc_next);
3912     }
3913 }
3914 
gen_bc(DisasContext * ctx)3915 static void gen_bc(DisasContext *ctx)
3916 {
3917     gen_bcond(ctx, BCOND_IM);
3918 }
3919 
gen_bcctr(DisasContext * ctx)3920 static void gen_bcctr(DisasContext *ctx)
3921 {
3922     gen_bcond(ctx, BCOND_CTR);
3923 }
3924 
gen_bclr(DisasContext * ctx)3925 static void gen_bclr(DisasContext *ctx)
3926 {
3927     gen_bcond(ctx, BCOND_LR);
3928 }
3929 
gen_bctar(DisasContext * ctx)3930 static void gen_bctar(DisasContext *ctx)
3931 {
3932     gen_bcond(ctx, BCOND_TAR);
3933 }
3934 
3935 /***                      Condition register logical                       ***/
3936 #define GEN_CRLOGIC(name, tcg_op, opc)                                        \
3937 static void glue(gen_, name)(DisasContext *ctx)                               \
3938 {                                                                             \
3939     uint8_t bitmask;                                                          \
3940     int sh;                                                                   \
3941     TCGv_i32 t0, t1;                                                          \
3942     sh = (crbD(ctx->opcode) & 0x03) - (crbA(ctx->opcode) & 0x03);             \
3943     t0 = tcg_temp_new_i32();                                                  \
3944     if (sh > 0)                                                               \
3945         tcg_gen_shri_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2], sh);            \
3946     else if (sh < 0)                                                          \
3947         tcg_gen_shli_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2], -sh);           \
3948     else                                                                      \
3949         tcg_gen_mov_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2]);                 \
3950     t1 = tcg_temp_new_i32();                                                  \
3951     sh = (crbD(ctx->opcode) & 0x03) - (crbB(ctx->opcode) & 0x03);             \
3952     if (sh > 0)                                                               \
3953         tcg_gen_shri_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2], sh);            \
3954     else if (sh < 0)                                                          \
3955         tcg_gen_shli_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2], -sh);           \
3956     else                                                                      \
3957         tcg_gen_mov_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2]);                 \
3958     tcg_op(t0, t0, t1);                                                       \
3959     bitmask = 0x08 >> (crbD(ctx->opcode) & 0x03);                             \
3960     tcg_gen_andi_i32(t0, t0, bitmask);                                        \
3961     tcg_gen_andi_i32(t1, cpu_crf[crbD(ctx->opcode) >> 2], ~bitmask);          \
3962     tcg_gen_or_i32(cpu_crf[crbD(ctx->opcode) >> 2], t0, t1);                  \
3963     tcg_temp_free_i32(t0);                                                    \
3964     tcg_temp_free_i32(t1);                                                    \
3965 }
3966 
3967 /* crand */
3968 GEN_CRLOGIC(crand, tcg_gen_and_i32, 0x08);
3969 /* crandc */
3970 GEN_CRLOGIC(crandc, tcg_gen_andc_i32, 0x04);
3971 /* creqv */
3972 GEN_CRLOGIC(creqv, tcg_gen_eqv_i32, 0x09);
3973 /* crnand */
3974 GEN_CRLOGIC(crnand, tcg_gen_nand_i32, 0x07);
3975 /* crnor */
3976 GEN_CRLOGIC(crnor, tcg_gen_nor_i32, 0x01);
3977 /* cror */
3978 GEN_CRLOGIC(cror, tcg_gen_or_i32, 0x0E);
3979 /* crorc */
3980 GEN_CRLOGIC(crorc, tcg_gen_orc_i32, 0x0D);
3981 /* crxor */
3982 GEN_CRLOGIC(crxor, tcg_gen_xor_i32, 0x06);
3983 
3984 /* mcrf */
gen_mcrf(DisasContext * ctx)3985 static void gen_mcrf(DisasContext *ctx)
3986 {
3987     tcg_gen_mov_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfS(ctx->opcode)]);
3988 }
3989 
3990 /***                           System linkage                              ***/
3991 
3992 /* rfi (supervisor only) */
gen_rfi(DisasContext * ctx)3993 static void gen_rfi(DisasContext *ctx)
3994 {
3995 #if defined(CONFIG_USER_ONLY)
3996     GEN_PRIV;
3997 #else
3998     /*
3999      * This instruction doesn't exist anymore on 64-bit server
4000      * processors compliant with arch 2.x
4001      */
4002     if (is_book3s_arch2x(ctx)) {
4003         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
4004         return;
4005     }
4006     /* Restore CPU state */
4007     CHK_SV;
4008     if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
4009         gen_io_start();
4010     }
4011     gen_update_cfar(ctx, ctx->base.pc_next - 4);
4012     gen_helper_rfi(cpu_env);
4013     gen_sync_exception(ctx);
4014 #endif
4015 }
4016 
4017 #if defined(TARGET_PPC64)
gen_rfid(DisasContext * ctx)4018 static void gen_rfid(DisasContext *ctx)
4019 {
4020 #if defined(CONFIG_USER_ONLY)
4021     GEN_PRIV;
4022 #else
4023     /* Restore CPU state */
4024     CHK_SV;
4025     if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
4026         gen_io_start();
4027     }
4028     gen_update_cfar(ctx, ctx->base.pc_next - 4);
4029     gen_helper_rfid(cpu_env);
4030     gen_sync_exception(ctx);
4031 #endif
4032 }
4033 
4034 #if !defined(CONFIG_USER_ONLY)
gen_rfscv(DisasContext * ctx)4035 static void gen_rfscv(DisasContext *ctx)
4036 {
4037 #if defined(CONFIG_USER_ONLY)
4038     GEN_PRIV;
4039 #else
4040     /* Restore CPU state */
4041     CHK_SV;
4042     if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
4043         gen_io_start();
4044     }
4045     gen_update_cfar(ctx, ctx->base.pc_next - 4);
4046     gen_helper_rfscv(cpu_env);
4047     gen_sync_exception(ctx);
4048 #endif
4049 }
4050 #endif
4051 
gen_hrfid(DisasContext * ctx)4052 static void gen_hrfid(DisasContext *ctx)
4053 {
4054 #if defined(CONFIG_USER_ONLY)
4055     GEN_PRIV;
4056 #else
4057     /* Restore CPU state */
4058     CHK_HV;
4059     gen_helper_hrfid(cpu_env);
4060     gen_sync_exception(ctx);
4061 #endif
4062 }
4063 #endif
4064 
4065 /* sc */
4066 #if defined(CONFIG_USER_ONLY)
4067 #define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL_USER
4068 #else
4069 #define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL
4070 #define POWERPC_SYSCALL_VECTORED POWERPC_EXCP_SYSCALL_VECTORED
4071 #endif
gen_sc(DisasContext * ctx)4072 static void gen_sc(DisasContext *ctx)
4073 {
4074     uint32_t lev;
4075 
4076     lev = (ctx->opcode >> 5) & 0x7F;
4077     gen_exception_err(ctx, POWERPC_SYSCALL, lev);
4078 }
4079 
4080 #if defined(TARGET_PPC64)
4081 #if !defined(CONFIG_USER_ONLY)
gen_scv(DisasContext * ctx)4082 static void gen_scv(DisasContext *ctx)
4083 {
4084     uint32_t lev;
4085 
4086     if (unlikely(!ctx->scv_enabled)) {
4087         gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_SCV);
4088         return;
4089     }
4090 
4091     lev = (ctx->opcode >> 5) & 0x7F;
4092     gen_exception_err(ctx, POWERPC_SYSCALL_VECTORED, lev);
4093 }
4094 #endif
4095 #endif
4096 
4097 /***                                Trap                                   ***/
4098 
4099 /* Check for unconditional traps (always or never) */
check_unconditional_trap(DisasContext * ctx)4100 static bool check_unconditional_trap(DisasContext *ctx)
4101 {
4102     /* Trap never */
4103     if (TO(ctx->opcode) == 0) {
4104         return true;
4105     }
4106     /* Trap always */
4107     if (TO(ctx->opcode) == 31) {
4108         gen_exception_err(ctx, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_TRAP);
4109         return true;
4110     }
4111     return false;
4112 }
4113 
4114 /* tw */
gen_tw(DisasContext * ctx)4115 static void gen_tw(DisasContext *ctx)
4116 {
4117     TCGv_i32 t0;
4118 
4119     if (check_unconditional_trap(ctx)) {
4120         return;
4121     }
4122     t0 = tcg_const_i32(TO(ctx->opcode));
4123     gen_helper_tw(cpu_env, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
4124                   t0);
4125     tcg_temp_free_i32(t0);
4126 }
4127 
4128 /* twi */
gen_twi(DisasContext * ctx)4129 static void gen_twi(DisasContext *ctx)
4130 {
4131     TCGv t0;
4132     TCGv_i32 t1;
4133 
4134     if (check_unconditional_trap(ctx)) {
4135         return;
4136     }
4137     t0 = tcg_const_tl(SIMM(ctx->opcode));
4138     t1 = tcg_const_i32(TO(ctx->opcode));
4139     gen_helper_tw(cpu_env, cpu_gpr[rA(ctx->opcode)], t0, t1);
4140     tcg_temp_free(t0);
4141     tcg_temp_free_i32(t1);
4142 }
4143 
4144 #if defined(TARGET_PPC64)
4145 /* td */
gen_td(DisasContext * ctx)4146 static void gen_td(DisasContext *ctx)
4147 {
4148     TCGv_i32 t0;
4149 
4150     if (check_unconditional_trap(ctx)) {
4151         return;
4152     }
4153     t0 = tcg_const_i32(TO(ctx->opcode));
4154     gen_helper_td(cpu_env, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
4155                   t0);
4156     tcg_temp_free_i32(t0);
4157 }
4158 
4159 /* tdi */
gen_tdi(DisasContext * ctx)4160 static void gen_tdi(DisasContext *ctx)
4161 {
4162     TCGv t0;
4163     TCGv_i32 t1;
4164 
4165     if (check_unconditional_trap(ctx)) {
4166         return;
4167     }
4168     t0 = tcg_const_tl(SIMM(ctx->opcode));
4169     t1 = tcg_const_i32(TO(ctx->opcode));
4170     gen_helper_td(cpu_env, cpu_gpr[rA(ctx->opcode)], t0, t1);
4171     tcg_temp_free(t0);
4172     tcg_temp_free_i32(t1);
4173 }
4174 #endif
4175 
4176 /***                          Processor control                            ***/
4177 
gen_read_xer(DisasContext * ctx,TCGv dst)4178 static void gen_read_xer(DisasContext *ctx, TCGv dst)
4179 {
4180     TCGv t0 = tcg_temp_new();
4181     TCGv t1 = tcg_temp_new();
4182     TCGv t2 = tcg_temp_new();
4183     tcg_gen_mov_tl(dst, cpu_xer);
4184     tcg_gen_shli_tl(t0, cpu_so, XER_SO);
4185     tcg_gen_shli_tl(t1, cpu_ov, XER_OV);
4186     tcg_gen_shli_tl(t2, cpu_ca, XER_CA);
4187     tcg_gen_or_tl(t0, t0, t1);
4188     tcg_gen_or_tl(dst, dst, t2);
4189     tcg_gen_or_tl(dst, dst, t0);
4190     if (is_isa300(ctx)) {
4191         tcg_gen_shli_tl(t0, cpu_ov32, XER_OV32);
4192         tcg_gen_or_tl(dst, dst, t0);
4193         tcg_gen_shli_tl(t0, cpu_ca32, XER_CA32);
4194         tcg_gen_or_tl(dst, dst, t0);
4195     }
4196     tcg_temp_free(t0);
4197     tcg_temp_free(t1);
4198     tcg_temp_free(t2);
4199 }
4200 
gen_write_xer(TCGv src)4201 static void gen_write_xer(TCGv src)
4202 {
4203     /* Write all flags, while reading back check for isa300 */
4204     tcg_gen_andi_tl(cpu_xer, src,
4205                     ~((1u << XER_SO) |
4206                       (1u << XER_OV) | (1u << XER_OV32) |
4207                       (1u << XER_CA) | (1u << XER_CA32)));
4208     tcg_gen_extract_tl(cpu_ov32, src, XER_OV32, 1);
4209     tcg_gen_extract_tl(cpu_ca32, src, XER_CA32, 1);
4210     tcg_gen_extract_tl(cpu_so, src, XER_SO, 1);
4211     tcg_gen_extract_tl(cpu_ov, src, XER_OV, 1);
4212     tcg_gen_extract_tl(cpu_ca, src, XER_CA, 1);
4213 }
4214 
4215 /* mcrxr */
gen_mcrxr(DisasContext * ctx)4216 static void gen_mcrxr(DisasContext *ctx)
4217 {
4218     TCGv_i32 t0 = tcg_temp_new_i32();
4219     TCGv_i32 t1 = tcg_temp_new_i32();
4220     TCGv_i32 dst = cpu_crf[crfD(ctx->opcode)];
4221 
4222     tcg_gen_trunc_tl_i32(t0, cpu_so);
4223     tcg_gen_trunc_tl_i32(t1, cpu_ov);
4224     tcg_gen_trunc_tl_i32(dst, cpu_ca);
4225     tcg_gen_shli_i32(t0, t0, 3);
4226     tcg_gen_shli_i32(t1, t1, 2);
4227     tcg_gen_shli_i32(dst, dst, 1);
4228     tcg_gen_or_i32(dst, dst, t0);
4229     tcg_gen_or_i32(dst, dst, t1);
4230     tcg_temp_free_i32(t0);
4231     tcg_temp_free_i32(t1);
4232 
4233     tcg_gen_movi_tl(cpu_so, 0);
4234     tcg_gen_movi_tl(cpu_ov, 0);
4235     tcg_gen_movi_tl(cpu_ca, 0);
4236 }
4237 
4238 #ifdef TARGET_PPC64
4239 /* mcrxrx */
gen_mcrxrx(DisasContext * ctx)4240 static void gen_mcrxrx(DisasContext *ctx)
4241 {
4242     TCGv t0 = tcg_temp_new();
4243     TCGv t1 = tcg_temp_new();
4244     TCGv_i32 dst = cpu_crf[crfD(ctx->opcode)];
4245 
4246     /* copy OV and OV32 */
4247     tcg_gen_shli_tl(t0, cpu_ov, 1);
4248     tcg_gen_or_tl(t0, t0, cpu_ov32);
4249     tcg_gen_shli_tl(t0, t0, 2);
4250     /* copy CA and CA32 */
4251     tcg_gen_shli_tl(t1, cpu_ca, 1);
4252     tcg_gen_or_tl(t1, t1, cpu_ca32);
4253     tcg_gen_or_tl(t0, t0, t1);
4254     tcg_gen_trunc_tl_i32(dst, t0);
4255     tcg_temp_free(t0);
4256     tcg_temp_free(t1);
4257 }
4258 #endif
4259 
4260 /* mfcr mfocrf */
gen_mfcr(DisasContext * ctx)4261 static void gen_mfcr(DisasContext *ctx)
4262 {
4263     uint32_t crm, crn;
4264 
4265     if (likely(ctx->opcode & 0x00100000)) {
4266         crm = CRM(ctx->opcode);
4267         if (likely(crm && ((crm & (crm - 1)) == 0))) {
4268             crn = ctz32(crm);
4269             tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], cpu_crf[7 - crn]);
4270             tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)],
4271                             cpu_gpr[rD(ctx->opcode)], crn * 4);
4272         }
4273     } else {
4274         TCGv_i32 t0 = tcg_temp_new_i32();
4275         tcg_gen_mov_i32(t0, cpu_crf[0]);
4276         tcg_gen_shli_i32(t0, t0, 4);
4277         tcg_gen_or_i32(t0, t0, cpu_crf[1]);
4278         tcg_gen_shli_i32(t0, t0, 4);
4279         tcg_gen_or_i32(t0, t0, cpu_crf[2]);
4280         tcg_gen_shli_i32(t0, t0, 4);
4281         tcg_gen_or_i32(t0, t0, cpu_crf[3]);
4282         tcg_gen_shli_i32(t0, t0, 4);
4283         tcg_gen_or_i32(t0, t0, cpu_crf[4]);
4284         tcg_gen_shli_i32(t0, t0, 4);
4285         tcg_gen_or_i32(t0, t0, cpu_crf[5]);
4286         tcg_gen_shli_i32(t0, t0, 4);
4287         tcg_gen_or_i32(t0, t0, cpu_crf[6]);
4288         tcg_gen_shli_i32(t0, t0, 4);
4289         tcg_gen_or_i32(t0, t0, cpu_crf[7]);
4290         tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0);
4291         tcg_temp_free_i32(t0);
4292     }
4293 }
4294 
4295 /* mfmsr */
gen_mfmsr(DisasContext * ctx)4296 static void gen_mfmsr(DisasContext *ctx)
4297 {
4298     CHK_SV;
4299     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_msr);
4300 }
4301 
spr_noaccess(DisasContext * ctx,int gprn,int sprn)4302 static void spr_noaccess(DisasContext *ctx, int gprn, int sprn)
4303 {
4304 #if 0
4305     sprn = ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
4306     printf("ERROR: try to access SPR %d !\n", sprn);
4307 #endif
4308 }
4309 #define SPR_NOACCESS (&spr_noaccess)
4310 
4311 /* mfspr */
gen_op_mfspr(DisasContext * ctx)4312 static inline void gen_op_mfspr(DisasContext *ctx)
4313 {
4314     void (*read_cb)(DisasContext *ctx, int gprn, int sprn);
4315     uint32_t sprn = SPR(ctx->opcode);
4316 
4317 #if defined(CONFIG_USER_ONLY)
4318     read_cb = ctx->spr_cb[sprn].uea_read;
4319 #else
4320     if (ctx->pr) {
4321         read_cb = ctx->spr_cb[sprn].uea_read;
4322     } else if (ctx->hv) {
4323         read_cb = ctx->spr_cb[sprn].hea_read;
4324     } else {
4325         read_cb = ctx->spr_cb[sprn].oea_read;
4326     }
4327 #endif
4328     if (likely(read_cb != NULL)) {
4329         if (likely(read_cb != SPR_NOACCESS)) {
4330             (*read_cb)(ctx, rD(ctx->opcode), sprn);
4331         } else {
4332             /* Privilege exception */
4333             /*
4334              * This is a hack to avoid warnings when running Linux:
4335              * this OS breaks the PowerPC virtualisation model,
4336              * allowing userland application to read the PVR
4337              */
4338             if (sprn != SPR_PVR) {
4339                 qemu_log_mask(LOG_GUEST_ERROR, "Trying to read privileged spr "
4340                               "%d (0x%03x) at " TARGET_FMT_lx "\n", sprn, sprn,
4341                               ctx->base.pc_next - 4);
4342             }
4343             gen_priv_exception(ctx, POWERPC_EXCP_PRIV_REG);
4344         }
4345     } else {
4346         /* ISA 2.07 defines these as no-ops */
4347         if ((ctx->insns_flags2 & PPC2_ISA207S) &&
4348             (sprn >= 808 && sprn <= 811)) {
4349             /* This is a nop */
4350             return;
4351         }
4352         /* Not defined */
4353         qemu_log_mask(LOG_GUEST_ERROR,
4354                       "Trying to read invalid spr %d (0x%03x) at "
4355                       TARGET_FMT_lx "\n", sprn, sprn, ctx->base.pc_next - 4);
4356 
4357         /*
4358          * The behaviour depends on MSR:PR and SPR# bit 0x10, it can
4359          * generate a priv, a hv emu or a no-op
4360          */
4361         if (sprn & 0x10) {
4362             if (ctx->pr) {
4363                 gen_priv_exception(ctx, POWERPC_EXCP_INVAL_SPR);
4364             }
4365         } else {
4366             if (ctx->pr || sprn == 0 || sprn == 4 || sprn == 5 || sprn == 6) {
4367                 gen_hvpriv_exception(ctx, POWERPC_EXCP_INVAL_SPR);
4368             }
4369         }
4370     }
4371 }
4372 
gen_mfspr(DisasContext * ctx)4373 static void gen_mfspr(DisasContext *ctx)
4374 {
4375     gen_op_mfspr(ctx);
4376 }
4377 
4378 /* mftb */
gen_mftb(DisasContext * ctx)4379 static void gen_mftb(DisasContext *ctx)
4380 {
4381     gen_op_mfspr(ctx);
4382 }
4383 
4384 /* mtcrf mtocrf*/
gen_mtcrf(DisasContext * ctx)4385 static void gen_mtcrf(DisasContext *ctx)
4386 {
4387     uint32_t crm, crn;
4388 
4389     crm = CRM(ctx->opcode);
4390     if (likely((ctx->opcode & 0x00100000))) {
4391         if (crm && ((crm & (crm - 1)) == 0)) {
4392             TCGv_i32 temp = tcg_temp_new_i32();
4393             crn = ctz32(crm);
4394             tcg_gen_trunc_tl_i32(temp, cpu_gpr[rS(ctx->opcode)]);
4395             tcg_gen_shri_i32(temp, temp, crn * 4);
4396             tcg_gen_andi_i32(cpu_crf[7 - crn], temp, 0xf);
4397             tcg_temp_free_i32(temp);
4398         }
4399     } else {
4400         TCGv_i32 temp = tcg_temp_new_i32();
4401         tcg_gen_trunc_tl_i32(temp, cpu_gpr[rS(ctx->opcode)]);
4402         for (crn = 0 ; crn < 8 ; crn++) {
4403             if (crm & (1 << crn)) {
4404                     tcg_gen_shri_i32(cpu_crf[7 - crn], temp, crn * 4);
4405                     tcg_gen_andi_i32(cpu_crf[7 - crn], cpu_crf[7 - crn], 0xf);
4406             }
4407         }
4408         tcg_temp_free_i32(temp);
4409     }
4410 }
4411 
4412 /* mtmsr */
4413 #if defined(TARGET_PPC64)
gen_mtmsrd(DisasContext * ctx)4414 static void gen_mtmsrd(DisasContext *ctx)
4415 {
4416     CHK_SV;
4417 
4418 #if !defined(CONFIG_USER_ONLY)
4419     if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
4420         gen_io_start();
4421     }
4422     if (ctx->opcode & 0x00010000) {
4423         /* L=1 form only updates EE and RI */
4424         TCGv t0 = tcg_temp_new();
4425         TCGv t1 = tcg_temp_new();
4426         tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)],
4427                         (1 << MSR_RI) | (1 << MSR_EE));
4428         tcg_gen_andi_tl(t1, cpu_msr,
4429                         ~(target_ulong)((1 << MSR_RI) | (1 << MSR_EE)));
4430         tcg_gen_or_tl(t1, t1, t0);
4431 
4432         gen_helper_store_msr(cpu_env, t1);
4433         tcg_temp_free(t0);
4434         tcg_temp_free(t1);
4435 
4436     } else {
4437         /*
4438          * XXX: we need to update nip before the store if we enter
4439          *      power saving mode, we will exit the loop directly from
4440          *      ppc_store_msr
4441          */
4442         gen_update_nip(ctx, ctx->base.pc_next);
4443         gen_helper_store_msr(cpu_env, cpu_gpr[rS(ctx->opcode)]);
4444     }
4445     /* Must stop the translation as machine state (may have) changed */
4446     gen_stop_exception(ctx);
4447 #endif /* !defined(CONFIG_USER_ONLY) */
4448 }
4449 #endif /* defined(TARGET_PPC64) */
4450 
gen_mtmsr(DisasContext * ctx)4451 static void gen_mtmsr(DisasContext *ctx)
4452 {
4453     CHK_SV;
4454 
4455 #if !defined(CONFIG_USER_ONLY)
4456     if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
4457         gen_io_start();
4458     }
4459     if (ctx->opcode & 0x00010000) {
4460         /* L=1 form only updates EE and RI */
4461         TCGv t0 = tcg_temp_new();
4462         TCGv t1 = tcg_temp_new();
4463         tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)],
4464                         (1 << MSR_RI) | (1 << MSR_EE));
4465         tcg_gen_andi_tl(t1, cpu_msr,
4466                         ~(target_ulong)((1 << MSR_RI) | (1 << MSR_EE)));
4467         tcg_gen_or_tl(t1, t1, t0);
4468 
4469         gen_helper_store_msr(cpu_env, t1);
4470         tcg_temp_free(t0);
4471         tcg_temp_free(t1);
4472 
4473     } else {
4474         TCGv msr = tcg_temp_new();
4475 
4476         /*
4477          * XXX: we need to update nip before the store if we enter
4478          *      power saving mode, we will exit the loop directly from
4479          *      ppc_store_msr
4480          */
4481         gen_update_nip(ctx, ctx->base.pc_next);
4482 #if defined(TARGET_PPC64)
4483         tcg_gen_deposit_tl(msr, cpu_msr, cpu_gpr[rS(ctx->opcode)], 0, 32);
4484 #else
4485         tcg_gen_mov_tl(msr, cpu_gpr[rS(ctx->opcode)]);
4486 #endif
4487         gen_helper_store_msr(cpu_env, msr);
4488         tcg_temp_free(msr);
4489     }
4490     /* Must stop the translation as machine state (may have) changed */
4491     gen_stop_exception(ctx);
4492 #endif
4493 }
4494 
4495 /* mtspr */
gen_mtspr(DisasContext * ctx)4496 static void gen_mtspr(DisasContext *ctx)
4497 {
4498     void (*write_cb)(DisasContext *ctx, int sprn, int gprn);
4499     uint32_t sprn = SPR(ctx->opcode);
4500 
4501 #if defined(CONFIG_USER_ONLY)
4502     write_cb = ctx->spr_cb[sprn].uea_write;
4503 #else
4504     if (ctx->pr) {
4505         write_cb = ctx->spr_cb[sprn].uea_write;
4506     } else if (ctx->hv) {
4507         write_cb = ctx->spr_cb[sprn].hea_write;
4508     } else {
4509         write_cb = ctx->spr_cb[sprn].oea_write;
4510     }
4511 #endif
4512     if (likely(write_cb != NULL)) {
4513         if (likely(write_cb != SPR_NOACCESS)) {
4514             (*write_cb)(ctx, sprn, rS(ctx->opcode));
4515         } else {
4516             /* Privilege exception */
4517             qemu_log_mask(LOG_GUEST_ERROR, "Trying to write privileged spr "
4518                           "%d (0x%03x) at " TARGET_FMT_lx "\n", sprn, sprn,
4519                           ctx->base.pc_next - 4);
4520             gen_priv_exception(ctx, POWERPC_EXCP_PRIV_REG);
4521         }
4522     } else {
4523         /* ISA 2.07 defines these as no-ops */
4524         if ((ctx->insns_flags2 & PPC2_ISA207S) &&
4525             (sprn >= 808 && sprn <= 811)) {
4526             /* This is a nop */
4527             return;
4528         }
4529 
4530         /* Not defined */
4531         qemu_log_mask(LOG_GUEST_ERROR,
4532                       "Trying to write invalid spr %d (0x%03x) at "
4533                       TARGET_FMT_lx "\n", sprn, sprn, ctx->base.pc_next - 4);
4534 
4535 
4536         /*
4537          * The behaviour depends on MSR:PR and SPR# bit 0x10, it can
4538          * generate a priv, a hv emu or a no-op
4539          */
4540         if (sprn & 0x10) {
4541             if (ctx->pr) {
4542                 gen_priv_exception(ctx, POWERPC_EXCP_INVAL_SPR);
4543             }
4544         } else {
4545             if (ctx->pr || sprn == 0) {
4546                 gen_hvpriv_exception(ctx, POWERPC_EXCP_INVAL_SPR);
4547             }
4548         }
4549     }
4550 }
4551 
4552 #if defined(TARGET_PPC64)
4553 /* setb */
gen_setb(DisasContext * ctx)4554 static void gen_setb(DisasContext *ctx)
4555 {
4556     TCGv_i32 t0 = tcg_temp_new_i32();
4557     TCGv_i32 t8 = tcg_temp_new_i32();
4558     TCGv_i32 tm1 = tcg_temp_new_i32();
4559     int crf = crfS(ctx->opcode);
4560 
4561     tcg_gen_setcondi_i32(TCG_COND_GEU, t0, cpu_crf[crf], 4);
4562     tcg_gen_movi_i32(t8, 8);
4563     tcg_gen_movi_i32(tm1, -1);
4564     tcg_gen_movcond_i32(TCG_COND_GEU, t0, cpu_crf[crf], t8, tm1, t0);
4565     tcg_gen_ext_i32_tl(cpu_gpr[rD(ctx->opcode)], t0);
4566 
4567     tcg_temp_free_i32(t0);
4568     tcg_temp_free_i32(t8);
4569     tcg_temp_free_i32(tm1);
4570 }
4571 #endif
4572 
4573 /***                         Cache management                              ***/
4574 
4575 /* dcbf */
gen_dcbf(DisasContext * ctx)4576 static void gen_dcbf(DisasContext *ctx)
4577 {
4578     /* XXX: specification says this is treated as a load by the MMU */
4579     TCGv t0;
4580     gen_set_access_type(ctx, ACCESS_CACHE);
4581     t0 = tcg_temp_new();
4582     gen_addr_reg_index(ctx, t0);
4583     gen_qemu_ld8u(ctx, t0, t0);
4584     tcg_temp_free(t0);
4585 }
4586 
4587 /* dcbfep (external PID dcbf) */
gen_dcbfep(DisasContext * ctx)4588 static void gen_dcbfep(DisasContext *ctx)
4589 {
4590     /* XXX: specification says this is treated as a load by the MMU */
4591     TCGv t0;
4592     CHK_SV;
4593     gen_set_access_type(ctx, ACCESS_CACHE);
4594     t0 = tcg_temp_new();
4595     gen_addr_reg_index(ctx, t0);
4596     tcg_gen_qemu_ld_tl(t0, t0, PPC_TLB_EPID_LOAD, DEF_MEMOP(MO_UB));
4597     tcg_temp_free(t0);
4598 }
4599 
4600 /* dcbi (Supervisor only) */
gen_dcbi(DisasContext * ctx)4601 static void gen_dcbi(DisasContext *ctx)
4602 {
4603 #if defined(CONFIG_USER_ONLY)
4604     GEN_PRIV;
4605 #else
4606     TCGv EA, val;
4607 
4608     CHK_SV;
4609     EA = tcg_temp_new();
4610     gen_set_access_type(ctx, ACCESS_CACHE);
4611     gen_addr_reg_index(ctx, EA);
4612     val = tcg_temp_new();
4613     /* XXX: specification says this should be treated as a store by the MMU */
4614     gen_qemu_ld8u(ctx, val, EA);
4615     gen_qemu_st8(ctx, val, EA);
4616     tcg_temp_free(val);
4617     tcg_temp_free(EA);
4618 #endif /* defined(CONFIG_USER_ONLY) */
4619 }
4620 
4621 /* dcdst */
gen_dcbst(DisasContext * ctx)4622 static void gen_dcbst(DisasContext *ctx)
4623 {
4624     /* XXX: specification say this is treated as a load by the MMU */
4625     TCGv t0;
4626     gen_set_access_type(ctx, ACCESS_CACHE);
4627     t0 = tcg_temp_new();
4628     gen_addr_reg_index(ctx, t0);
4629     gen_qemu_ld8u(ctx, t0, t0);
4630     tcg_temp_free(t0);
4631 }
4632 
4633 /* dcbstep (dcbstep External PID version) */
gen_dcbstep(DisasContext * ctx)4634 static void gen_dcbstep(DisasContext *ctx)
4635 {
4636     /* XXX: specification say this is treated as a load by the MMU */
4637     TCGv t0;
4638     gen_set_access_type(ctx, ACCESS_CACHE);
4639     t0 = tcg_temp_new();
4640     gen_addr_reg_index(ctx, t0);
4641     tcg_gen_qemu_ld_tl(t0, t0, PPC_TLB_EPID_LOAD, DEF_MEMOP(MO_UB));
4642     tcg_temp_free(t0);
4643 }
4644 
4645 /* dcbt */
gen_dcbt(DisasContext * ctx)4646 static void gen_dcbt(DisasContext *ctx)
4647 {
4648     /*
4649      * interpreted as no-op
4650      * XXX: specification say this is treated as a load by the MMU but
4651      *      does not generate any exception
4652      */
4653 }
4654 
4655 /* dcbtep */
gen_dcbtep(DisasContext * ctx)4656 static void gen_dcbtep(DisasContext *ctx)
4657 {
4658     /*
4659      * interpreted as no-op
4660      * XXX: specification say this is treated as a load by the MMU but
4661      *      does not generate any exception
4662      */
4663 }
4664 
4665 /* dcbtst */
gen_dcbtst(DisasContext * ctx)4666 static void gen_dcbtst(DisasContext *ctx)
4667 {
4668     /*
4669      * interpreted as no-op
4670      * XXX: specification say this is treated as a load by the MMU but
4671      *      does not generate any exception
4672      */
4673 }
4674 
4675 /* dcbtstep */
gen_dcbtstep(DisasContext * ctx)4676 static void gen_dcbtstep(DisasContext *ctx)
4677 {
4678     /*
4679      * interpreted as no-op
4680      * XXX: specification say this is treated as a load by the MMU but
4681      *      does not generate any exception
4682      */
4683 }
4684 
4685 /* dcbtls */
gen_dcbtls(DisasContext * ctx)4686 static void gen_dcbtls(DisasContext *ctx)
4687 {
4688     /* Always fails locking the cache */
4689     TCGv t0 = tcg_temp_new();
4690     gen_load_spr(t0, SPR_Exxx_L1CSR0);
4691     tcg_gen_ori_tl(t0, t0, L1CSR0_CUL);
4692     gen_store_spr(SPR_Exxx_L1CSR0, t0);
4693     tcg_temp_free(t0);
4694 }
4695 
4696 /* dcbz */
gen_dcbz(DisasContext * ctx)4697 static void gen_dcbz(DisasContext *ctx)
4698 {
4699     TCGv tcgv_addr;
4700     TCGv_i32 tcgv_op;
4701 
4702     gen_set_access_type(ctx, ACCESS_CACHE);
4703     tcgv_addr = tcg_temp_new();
4704     tcgv_op = tcg_const_i32(ctx->opcode & 0x03FF000);
4705     gen_addr_reg_index(ctx, tcgv_addr);
4706     gen_helper_dcbz(cpu_env, tcgv_addr, tcgv_op);
4707     tcg_temp_free(tcgv_addr);
4708     tcg_temp_free_i32(tcgv_op);
4709 }
4710 
4711 /* dcbzep */
gen_dcbzep(DisasContext * ctx)4712 static void gen_dcbzep(DisasContext *ctx)
4713 {
4714     TCGv tcgv_addr;
4715     TCGv_i32 tcgv_op;
4716 
4717     gen_set_access_type(ctx, ACCESS_CACHE);
4718     tcgv_addr = tcg_temp_new();
4719     tcgv_op = tcg_const_i32(ctx->opcode & 0x03FF000);
4720     gen_addr_reg_index(ctx, tcgv_addr);
4721     gen_helper_dcbzep(cpu_env, tcgv_addr, tcgv_op);
4722     tcg_temp_free(tcgv_addr);
4723     tcg_temp_free_i32(tcgv_op);
4724 }
4725 
4726 /* dst / dstt */
gen_dst(DisasContext * ctx)4727 static void gen_dst(DisasContext *ctx)
4728 {
4729     if (rA(ctx->opcode) == 0) {
4730         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
4731     } else {
4732         /* interpreted as no-op */
4733     }
4734 }
4735 
4736 /* dstst /dststt */
gen_dstst(DisasContext * ctx)4737 static void gen_dstst(DisasContext *ctx)
4738 {
4739     if (rA(ctx->opcode) == 0) {
4740         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
4741     } else {
4742         /* interpreted as no-op */
4743     }
4744 
4745 }
4746 
4747 /* dss / dssall */
gen_dss(DisasContext * ctx)4748 static void gen_dss(DisasContext *ctx)
4749 {
4750     /* interpreted as no-op */
4751 }
4752 
4753 /* icbi */
gen_icbi(DisasContext * ctx)4754 static void gen_icbi(DisasContext *ctx)
4755 {
4756     TCGv t0;
4757     gen_set_access_type(ctx, ACCESS_CACHE);
4758     t0 = tcg_temp_new();
4759     gen_addr_reg_index(ctx, t0);
4760     gen_helper_icbi(cpu_env, t0);
4761     tcg_temp_free(t0);
4762 }
4763 
4764 /* icbiep */
gen_icbiep(DisasContext * ctx)4765 static void gen_icbiep(DisasContext *ctx)
4766 {
4767     TCGv t0;
4768     gen_set_access_type(ctx, ACCESS_CACHE);
4769     t0 = tcg_temp_new();
4770     gen_addr_reg_index(ctx, t0);
4771     gen_helper_icbiep(cpu_env, t0);
4772     tcg_temp_free(t0);
4773 }
4774 
4775 /* Optional: */
4776 /* dcba */
gen_dcba(DisasContext * ctx)4777 static void gen_dcba(DisasContext *ctx)
4778 {
4779     /*
4780      * interpreted as no-op
4781      * XXX: specification say this is treated as a store by the MMU
4782      *      but does not generate any exception
4783      */
4784 }
4785 
4786 /***                    Segment register manipulation                      ***/
4787 /* Supervisor only: */
4788 
4789 /* mfsr */
gen_mfsr(DisasContext * ctx)4790 static void gen_mfsr(DisasContext *ctx)
4791 {
4792 #if defined(CONFIG_USER_ONLY)
4793     GEN_PRIV;
4794 #else
4795     TCGv t0;
4796 
4797     CHK_SV;
4798     t0 = tcg_const_tl(SR(ctx->opcode));
4799     gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
4800     tcg_temp_free(t0);
4801 #endif /* defined(CONFIG_USER_ONLY) */
4802 }
4803 
4804 /* mfsrin */
gen_mfsrin(DisasContext * ctx)4805 static void gen_mfsrin(DisasContext *ctx)
4806 {
4807 #if defined(CONFIG_USER_ONLY)
4808     GEN_PRIV;
4809 #else
4810     TCGv t0;
4811 
4812     CHK_SV;
4813     t0 = tcg_temp_new();
4814     tcg_gen_extract_tl(t0, cpu_gpr[rB(ctx->opcode)], 28, 4);
4815     gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
4816     tcg_temp_free(t0);
4817 #endif /* defined(CONFIG_USER_ONLY) */
4818 }
4819 
4820 /* mtsr */
gen_mtsr(DisasContext * ctx)4821 static void gen_mtsr(DisasContext *ctx)
4822 {
4823 #if defined(CONFIG_USER_ONLY)
4824     GEN_PRIV;
4825 #else
4826     TCGv t0;
4827 
4828     CHK_SV;
4829     t0 = tcg_const_tl(SR(ctx->opcode));
4830     gen_helper_store_sr(cpu_env, t0, cpu_gpr[rS(ctx->opcode)]);
4831     tcg_temp_free(t0);
4832 #endif /* defined(CONFIG_USER_ONLY) */
4833 }
4834 
4835 /* mtsrin */
gen_mtsrin(DisasContext * ctx)4836 static void gen_mtsrin(DisasContext *ctx)
4837 {
4838 #if defined(CONFIG_USER_ONLY)
4839     GEN_PRIV;
4840 #else
4841     TCGv t0;
4842     CHK_SV;
4843 
4844     t0 = tcg_temp_new();
4845     tcg_gen_extract_tl(t0, cpu_gpr[rB(ctx->opcode)], 28, 4);
4846     gen_helper_store_sr(cpu_env, t0, cpu_gpr[rD(ctx->opcode)]);
4847     tcg_temp_free(t0);
4848 #endif /* defined(CONFIG_USER_ONLY) */
4849 }
4850 
4851 #if defined(TARGET_PPC64)
4852 /* Specific implementation for PowerPC 64 "bridge" emulation using SLB */
4853 
4854 /* mfsr */
gen_mfsr_64b(DisasContext * ctx)4855 static void gen_mfsr_64b(DisasContext *ctx)
4856 {
4857 #if defined(CONFIG_USER_ONLY)
4858     GEN_PRIV;
4859 #else
4860     TCGv t0;
4861 
4862     CHK_SV;
4863     t0 = tcg_const_tl(SR(ctx->opcode));
4864     gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
4865     tcg_temp_free(t0);
4866 #endif /* defined(CONFIG_USER_ONLY) */
4867 }
4868 
4869 /* mfsrin */
gen_mfsrin_64b(DisasContext * ctx)4870 static void gen_mfsrin_64b(DisasContext *ctx)
4871 {
4872 #if defined(CONFIG_USER_ONLY)
4873     GEN_PRIV;
4874 #else
4875     TCGv t0;
4876 
4877     CHK_SV;
4878     t0 = tcg_temp_new();
4879     tcg_gen_extract_tl(t0, cpu_gpr[rB(ctx->opcode)], 28, 4);
4880     gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
4881     tcg_temp_free(t0);
4882 #endif /* defined(CONFIG_USER_ONLY) */
4883 }
4884 
4885 /* mtsr */
gen_mtsr_64b(DisasContext * ctx)4886 static void gen_mtsr_64b(DisasContext *ctx)
4887 {
4888 #if defined(CONFIG_USER_ONLY)
4889     GEN_PRIV;
4890 #else
4891     TCGv t0;
4892 
4893     CHK_SV;
4894     t0 = tcg_const_tl(SR(ctx->opcode));
4895     gen_helper_store_sr(cpu_env, t0, cpu_gpr[rS(ctx->opcode)]);
4896     tcg_temp_free(t0);
4897 #endif /* defined(CONFIG_USER_ONLY) */
4898 }
4899 
4900 /* mtsrin */
gen_mtsrin_64b(DisasContext * ctx)4901 static void gen_mtsrin_64b(DisasContext *ctx)
4902 {
4903 #if defined(CONFIG_USER_ONLY)
4904     GEN_PRIV;
4905 #else
4906     TCGv t0;
4907 
4908     CHK_SV;
4909     t0 = tcg_temp_new();
4910     tcg_gen_extract_tl(t0, cpu_gpr[rB(ctx->opcode)], 28, 4);
4911     gen_helper_store_sr(cpu_env, t0, cpu_gpr[rS(ctx->opcode)]);
4912     tcg_temp_free(t0);
4913 #endif /* defined(CONFIG_USER_ONLY) */
4914 }
4915 
4916 /* slbmte */
gen_slbmte(DisasContext * ctx)4917 static void gen_slbmte(DisasContext *ctx)
4918 {
4919 #if defined(CONFIG_USER_ONLY)
4920     GEN_PRIV;
4921 #else
4922     CHK_SV;
4923 
4924     gen_helper_store_slb(cpu_env, cpu_gpr[rB(ctx->opcode)],
4925                          cpu_gpr[rS(ctx->opcode)]);
4926 #endif /* defined(CONFIG_USER_ONLY) */
4927 }
4928 
gen_slbmfee(DisasContext * ctx)4929 static void gen_slbmfee(DisasContext *ctx)
4930 {
4931 #if defined(CONFIG_USER_ONLY)
4932     GEN_PRIV;
4933 #else
4934     CHK_SV;
4935 
4936     gen_helper_load_slb_esid(cpu_gpr[rS(ctx->opcode)], cpu_env,
4937                              cpu_gpr[rB(ctx->opcode)]);
4938 #endif /* defined(CONFIG_USER_ONLY) */
4939 }
4940 
gen_slbmfev(DisasContext * ctx)4941 static void gen_slbmfev(DisasContext *ctx)
4942 {
4943 #if defined(CONFIG_USER_ONLY)
4944     GEN_PRIV;
4945 #else
4946     CHK_SV;
4947 
4948     gen_helper_load_slb_vsid(cpu_gpr[rS(ctx->opcode)], cpu_env,
4949                              cpu_gpr[rB(ctx->opcode)]);
4950 #endif /* defined(CONFIG_USER_ONLY) */
4951 }
4952 
gen_slbfee_(DisasContext * ctx)4953 static void gen_slbfee_(DisasContext *ctx)
4954 {
4955 #if defined(CONFIG_USER_ONLY)
4956     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4957 #else
4958     TCGLabel *l1, *l2;
4959 
4960     if (unlikely(ctx->pr)) {
4961         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4962         return;
4963     }
4964     gen_helper_find_slb_vsid(cpu_gpr[rS(ctx->opcode)], cpu_env,
4965                              cpu_gpr[rB(ctx->opcode)]);
4966     l1 = gen_new_label();
4967     l2 = gen_new_label();
4968     tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
4969     tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rS(ctx->opcode)], -1, l1);
4970     tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], CRF_EQ);
4971     tcg_gen_br(l2);
4972     gen_set_label(l1);
4973     tcg_gen_movi_tl(cpu_gpr[rS(ctx->opcode)], 0);
4974     gen_set_label(l2);
4975 #endif
4976 }
4977 #endif /* defined(TARGET_PPC64) */
4978 
4979 /***                      Lookaside buffer management                      ***/
4980 /* Optional & supervisor only: */
4981 
4982 /* tlbia */
gen_tlbia(DisasContext * ctx)4983 static void gen_tlbia(DisasContext *ctx)
4984 {
4985 #if defined(CONFIG_USER_ONLY)
4986     GEN_PRIV;
4987 #else
4988     CHK_HV;
4989 
4990     gen_helper_tlbia(cpu_env);
4991 #endif  /* defined(CONFIG_USER_ONLY) */
4992 }
4993 
4994 /* tlbiel */
gen_tlbiel(DisasContext * ctx)4995 static void gen_tlbiel(DisasContext *ctx)
4996 {
4997 #if defined(CONFIG_USER_ONLY)
4998     GEN_PRIV;
4999 #else
5000     CHK_SV;
5001 
5002     gen_helper_tlbie(cpu_env, cpu_gpr[rB(ctx->opcode)]);
5003 #endif /* defined(CONFIG_USER_ONLY) */
5004 }
5005 
5006 /* tlbie */
gen_tlbie(DisasContext * ctx)5007 static void gen_tlbie(DisasContext *ctx)
5008 {
5009 #if defined(CONFIG_USER_ONLY)
5010     GEN_PRIV;
5011 #else
5012     TCGv_i32 t1;
5013 
5014     if (ctx->gtse) {
5015         CHK_SV; /* If gtse is set then tlbie is supervisor privileged */
5016     } else {
5017         CHK_HV; /* Else hypervisor privileged */
5018     }
5019 
5020     if (NARROW_MODE(ctx)) {
5021         TCGv t0 = tcg_temp_new();
5022         tcg_gen_ext32u_tl(t0, cpu_gpr[rB(ctx->opcode)]);
5023         gen_helper_tlbie(cpu_env, t0);
5024         tcg_temp_free(t0);
5025     } else {
5026         gen_helper_tlbie(cpu_env, cpu_gpr[rB(ctx->opcode)]);
5027     }
5028     t1 = tcg_temp_new_i32();
5029     tcg_gen_ld_i32(t1, cpu_env, offsetof(CPUPPCState, tlb_need_flush));
5030     tcg_gen_ori_i32(t1, t1, TLB_NEED_GLOBAL_FLUSH);
5031     tcg_gen_st_i32(t1, cpu_env, offsetof(CPUPPCState, tlb_need_flush));
5032     tcg_temp_free_i32(t1);
5033 #endif /* defined(CONFIG_USER_ONLY) */
5034 }
5035 
5036 /* tlbsync */
gen_tlbsync(DisasContext * ctx)5037 static void gen_tlbsync(DisasContext *ctx)
5038 {
5039 #if defined(CONFIG_USER_ONLY)
5040     GEN_PRIV;
5041 #else
5042 
5043     if (ctx->gtse) {
5044         CHK_SV; /* If gtse is set then tlbsync is supervisor privileged */
5045     } else {
5046         CHK_HV; /* Else hypervisor privileged */
5047     }
5048 
5049     /* BookS does both ptesync and tlbsync make tlbsync a nop for server */
5050     if (ctx->insns_flags & PPC_BOOKE) {
5051         gen_check_tlb_flush(ctx, true);
5052     }
5053 #endif /* defined(CONFIG_USER_ONLY) */
5054 }
5055 
5056 #if defined(TARGET_PPC64)
5057 /* slbia */
gen_slbia(DisasContext * ctx)5058 static void gen_slbia(DisasContext *ctx)
5059 {
5060 #if defined(CONFIG_USER_ONLY)
5061     GEN_PRIV;
5062 #else
5063     uint32_t ih = (ctx->opcode >> 21) & 0x7;
5064     TCGv_i32 t0 = tcg_const_i32(ih);
5065 
5066     CHK_SV;
5067 
5068     gen_helper_slbia(cpu_env, t0);
5069     tcg_temp_free_i32(t0);
5070 #endif /* defined(CONFIG_USER_ONLY) */
5071 }
5072 
5073 /* slbie */
gen_slbie(DisasContext * ctx)5074 static void gen_slbie(DisasContext *ctx)
5075 {
5076 #if defined(CONFIG_USER_ONLY)
5077     GEN_PRIV;
5078 #else
5079     CHK_SV;
5080 
5081     gen_helper_slbie(cpu_env, cpu_gpr[rB(ctx->opcode)]);
5082 #endif /* defined(CONFIG_USER_ONLY) */
5083 }
5084 
5085 /* slbieg */
gen_slbieg(DisasContext * ctx)5086 static void gen_slbieg(DisasContext *ctx)
5087 {
5088 #if defined(CONFIG_USER_ONLY)
5089     GEN_PRIV;
5090 #else
5091     CHK_SV;
5092 
5093     gen_helper_slbieg(cpu_env, cpu_gpr[rB(ctx->opcode)]);
5094 #endif /* defined(CONFIG_USER_ONLY) */
5095 }
5096 
5097 /* slbsync */
gen_slbsync(DisasContext * ctx)5098 static void gen_slbsync(DisasContext *ctx)
5099 {
5100 #if defined(CONFIG_USER_ONLY)
5101     GEN_PRIV;
5102 #else
5103     CHK_SV;
5104     gen_check_tlb_flush(ctx, true);
5105 #endif /* defined(CONFIG_USER_ONLY) */
5106 }
5107 
5108 #endif  /* defined(TARGET_PPC64) */
5109 
5110 /***                              External control                         ***/
5111 /* Optional: */
5112 
5113 /* eciwx */
gen_eciwx(DisasContext * ctx)5114 static void gen_eciwx(DisasContext *ctx)
5115 {
5116     TCGv t0;
5117     /* Should check EAR[E] ! */
5118     gen_set_access_type(ctx, ACCESS_EXT);
5119     t0 = tcg_temp_new();
5120     gen_addr_reg_index(ctx, t0);
5121     tcg_gen_qemu_ld_tl(cpu_gpr[rD(ctx->opcode)], t0, ctx->mem_idx,
5122                        DEF_MEMOP(MO_UL | MO_ALIGN));
5123     tcg_temp_free(t0);
5124 }
5125 
5126 /* ecowx */
gen_ecowx(DisasContext * ctx)5127 static void gen_ecowx(DisasContext *ctx)
5128 {
5129     TCGv t0;
5130     /* Should check EAR[E] ! */
5131     gen_set_access_type(ctx, ACCESS_EXT);
5132     t0 = tcg_temp_new();
5133     gen_addr_reg_index(ctx, t0);
5134     tcg_gen_qemu_st_tl(cpu_gpr[rD(ctx->opcode)], t0, ctx->mem_idx,
5135                        DEF_MEMOP(MO_UL | MO_ALIGN));
5136     tcg_temp_free(t0);
5137 }
5138 
5139 /* PowerPC 601 specific instructions */
5140 
5141 /* abs - abs. */
gen_abs(DisasContext * ctx)5142 static void gen_abs(DisasContext *ctx)
5143 {
5144     TCGv d = cpu_gpr[rD(ctx->opcode)];
5145     TCGv a = cpu_gpr[rA(ctx->opcode)];
5146 
5147     tcg_gen_abs_tl(d, a);
5148     if (unlikely(Rc(ctx->opcode) != 0)) {
5149         gen_set_Rc0(ctx, d);
5150     }
5151 }
5152 
5153 /* abso - abso. */
gen_abso(DisasContext * ctx)5154 static void gen_abso(DisasContext *ctx)
5155 {
5156     TCGv d = cpu_gpr[rD(ctx->opcode)];
5157     TCGv a = cpu_gpr[rA(ctx->opcode)];
5158 
5159     tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_ov, a, 0x80000000);
5160     tcg_gen_abs_tl(d, a);
5161     tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov);
5162     if (unlikely(Rc(ctx->opcode) != 0)) {
5163         gen_set_Rc0(ctx, d);
5164     }
5165 }
5166 
5167 /* clcs */
gen_clcs(DisasContext * ctx)5168 static void gen_clcs(DisasContext *ctx)
5169 {
5170     TCGv_i32 t0 = tcg_const_i32(rA(ctx->opcode));
5171     gen_helper_clcs(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
5172     tcg_temp_free_i32(t0);
5173     /* Rc=1 sets CR0 to an undefined state */
5174 }
5175 
5176 /* div - div. */
gen_div(DisasContext * ctx)5177 static void gen_div(DisasContext *ctx)
5178 {
5179     gen_helper_div(cpu_gpr[rD(ctx->opcode)], cpu_env, cpu_gpr[rA(ctx->opcode)],
5180                    cpu_gpr[rB(ctx->opcode)]);
5181     if (unlikely(Rc(ctx->opcode) != 0)) {
5182         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
5183     }
5184 }
5185 
5186 /* divo - divo. */
gen_divo(DisasContext * ctx)5187 static void gen_divo(DisasContext *ctx)
5188 {
5189     gen_helper_divo(cpu_gpr[rD(ctx->opcode)], cpu_env, cpu_gpr[rA(ctx->opcode)],
5190                     cpu_gpr[rB(ctx->opcode)]);
5191     if (unlikely(Rc(ctx->opcode) != 0)) {
5192         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
5193     }
5194 }
5195 
5196 /* divs - divs. */
gen_divs(DisasContext * ctx)5197 static void gen_divs(DisasContext *ctx)
5198 {
5199     gen_helper_divs(cpu_gpr[rD(ctx->opcode)], cpu_env, cpu_gpr[rA(ctx->opcode)],
5200                     cpu_gpr[rB(ctx->opcode)]);
5201     if (unlikely(Rc(ctx->opcode) != 0)) {
5202         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
5203     }
5204 }
5205 
5206 /* divso - divso. */
gen_divso(DisasContext * ctx)5207 static void gen_divso(DisasContext *ctx)
5208 {
5209     gen_helper_divso(cpu_gpr[rD(ctx->opcode)], cpu_env,
5210                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
5211     if (unlikely(Rc(ctx->opcode) != 0)) {
5212         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
5213     }
5214 }
5215 
5216 /* doz - doz. */
gen_doz(DisasContext * ctx)5217 static void gen_doz(DisasContext *ctx)
5218 {
5219     TCGLabel *l1 = gen_new_label();
5220     TCGLabel *l2 = gen_new_label();
5221     tcg_gen_brcond_tl(TCG_COND_GE, cpu_gpr[rB(ctx->opcode)],
5222                       cpu_gpr[rA(ctx->opcode)], l1);
5223     tcg_gen_sub_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
5224                    cpu_gpr[rA(ctx->opcode)]);
5225     tcg_gen_br(l2);
5226     gen_set_label(l1);
5227     tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
5228     gen_set_label(l2);
5229     if (unlikely(Rc(ctx->opcode) != 0)) {
5230         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
5231     }
5232 }
5233 
5234 /* dozo - dozo. */
gen_dozo(DisasContext * ctx)5235 static void gen_dozo(DisasContext *ctx)
5236 {
5237     TCGLabel *l1 = gen_new_label();
5238     TCGLabel *l2 = gen_new_label();
5239     TCGv t0 = tcg_temp_new();
5240     TCGv t1 = tcg_temp_new();
5241     TCGv t2 = tcg_temp_new();
5242     /* Start with XER OV disabled, the most likely case */
5243     tcg_gen_movi_tl(cpu_ov, 0);
5244     tcg_gen_brcond_tl(TCG_COND_GE, cpu_gpr[rB(ctx->opcode)],
5245                       cpu_gpr[rA(ctx->opcode)], l1);
5246     tcg_gen_sub_tl(t0, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5247     tcg_gen_xor_tl(t1, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5248     tcg_gen_xor_tl(t2, cpu_gpr[rA(ctx->opcode)], t0);
5249     tcg_gen_andc_tl(t1, t1, t2);
5250     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
5251     tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l2);
5252     tcg_gen_movi_tl(cpu_ov, 1);
5253     tcg_gen_movi_tl(cpu_so, 1);
5254     tcg_gen_br(l2);
5255     gen_set_label(l1);
5256     tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
5257     gen_set_label(l2);
5258     tcg_temp_free(t0);
5259     tcg_temp_free(t1);
5260     tcg_temp_free(t2);
5261     if (unlikely(Rc(ctx->opcode) != 0)) {
5262         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
5263     }
5264 }
5265 
5266 /* dozi */
gen_dozi(DisasContext * ctx)5267 static void gen_dozi(DisasContext *ctx)
5268 {
5269     target_long simm = SIMM(ctx->opcode);
5270     TCGLabel *l1 = gen_new_label();
5271     TCGLabel *l2 = gen_new_label();
5272     tcg_gen_brcondi_tl(TCG_COND_LT, cpu_gpr[rA(ctx->opcode)], simm, l1);
5273     tcg_gen_subfi_tl(cpu_gpr[rD(ctx->opcode)], simm, cpu_gpr[rA(ctx->opcode)]);
5274     tcg_gen_br(l2);
5275     gen_set_label(l1);
5276     tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
5277     gen_set_label(l2);
5278     if (unlikely(Rc(ctx->opcode) != 0)) {
5279         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
5280     }
5281 }
5282 
5283 /* lscbx - lscbx. */
gen_lscbx(DisasContext * ctx)5284 static void gen_lscbx(DisasContext *ctx)
5285 {
5286     TCGv t0 = tcg_temp_new();
5287     TCGv_i32 t1 = tcg_const_i32(rD(ctx->opcode));
5288     TCGv_i32 t2 = tcg_const_i32(rA(ctx->opcode));
5289     TCGv_i32 t3 = tcg_const_i32(rB(ctx->opcode));
5290 
5291     gen_addr_reg_index(ctx, t0);
5292     gen_helper_lscbx(t0, cpu_env, t0, t1, t2, t3);
5293     tcg_temp_free_i32(t1);
5294     tcg_temp_free_i32(t2);
5295     tcg_temp_free_i32(t3);
5296     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~0x7F);
5297     tcg_gen_or_tl(cpu_xer, cpu_xer, t0);
5298     if (unlikely(Rc(ctx->opcode) != 0)) {
5299         gen_set_Rc0(ctx, t0);
5300     }
5301     tcg_temp_free(t0);
5302 }
5303 
5304 /* maskg - maskg. */
gen_maskg(DisasContext * ctx)5305 static void gen_maskg(DisasContext *ctx)
5306 {
5307     TCGLabel *l1 = gen_new_label();
5308     TCGv t0 = tcg_temp_new();
5309     TCGv t1 = tcg_temp_new();
5310     TCGv t2 = tcg_temp_new();
5311     TCGv t3 = tcg_temp_new();
5312     tcg_gen_movi_tl(t3, 0xFFFFFFFF);
5313     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
5314     tcg_gen_andi_tl(t1, cpu_gpr[rS(ctx->opcode)], 0x1F);
5315     tcg_gen_addi_tl(t2, t0, 1);
5316     tcg_gen_shr_tl(t2, t3, t2);
5317     tcg_gen_shr_tl(t3, t3, t1);
5318     tcg_gen_xor_tl(cpu_gpr[rA(ctx->opcode)], t2, t3);
5319     tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
5320     tcg_gen_neg_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5321     gen_set_label(l1);
5322     tcg_temp_free(t0);
5323     tcg_temp_free(t1);
5324     tcg_temp_free(t2);
5325     tcg_temp_free(t3);
5326     if (unlikely(Rc(ctx->opcode) != 0)) {
5327         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5328     }
5329 }
5330 
5331 /* maskir - maskir. */
gen_maskir(DisasContext * ctx)5332 static void gen_maskir(DisasContext *ctx)
5333 {
5334     TCGv t0 = tcg_temp_new();
5335     TCGv t1 = tcg_temp_new();
5336     tcg_gen_and_tl(t0, cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
5337     tcg_gen_andc_tl(t1, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
5338     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5339     tcg_temp_free(t0);
5340     tcg_temp_free(t1);
5341     if (unlikely(Rc(ctx->opcode) != 0)) {
5342         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5343     }
5344 }
5345 
5346 /* mul - mul. */
gen_mul(DisasContext * ctx)5347 static void gen_mul(DisasContext *ctx)
5348 {
5349     TCGv_i64 t0 = tcg_temp_new_i64();
5350     TCGv_i64 t1 = tcg_temp_new_i64();
5351     TCGv t2 = tcg_temp_new();
5352     tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
5353     tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
5354     tcg_gen_mul_i64(t0, t0, t1);
5355     tcg_gen_trunc_i64_tl(t2, t0);
5356     gen_store_spr(SPR_MQ, t2);
5357     tcg_gen_shri_i64(t1, t0, 32);
5358     tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t1);
5359     tcg_temp_free_i64(t0);
5360     tcg_temp_free_i64(t1);
5361     tcg_temp_free(t2);
5362     if (unlikely(Rc(ctx->opcode) != 0)) {
5363         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
5364     }
5365 }
5366 
5367 /* mulo - mulo. */
gen_mulo(DisasContext * ctx)5368 static void gen_mulo(DisasContext *ctx)
5369 {
5370     TCGLabel *l1 = gen_new_label();
5371     TCGv_i64 t0 = tcg_temp_new_i64();
5372     TCGv_i64 t1 = tcg_temp_new_i64();
5373     TCGv t2 = tcg_temp_new();
5374     /* Start with XER OV disabled, the most likely case */
5375     tcg_gen_movi_tl(cpu_ov, 0);
5376     tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
5377     tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
5378     tcg_gen_mul_i64(t0, t0, t1);
5379     tcg_gen_trunc_i64_tl(t2, t0);
5380     gen_store_spr(SPR_MQ, t2);
5381     tcg_gen_shri_i64(t1, t0, 32);
5382     tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t1);
5383     tcg_gen_ext32s_i64(t1, t0);
5384     tcg_gen_brcond_i64(TCG_COND_EQ, t0, t1, l1);
5385     tcg_gen_movi_tl(cpu_ov, 1);
5386     tcg_gen_movi_tl(cpu_so, 1);
5387     gen_set_label(l1);
5388     tcg_temp_free_i64(t0);
5389     tcg_temp_free_i64(t1);
5390     tcg_temp_free(t2);
5391     if (unlikely(Rc(ctx->opcode) != 0)) {
5392         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
5393     }
5394 }
5395 
5396 /* nabs - nabs. */
gen_nabs(DisasContext * ctx)5397 static void gen_nabs(DisasContext *ctx)
5398 {
5399     TCGv d = cpu_gpr[rD(ctx->opcode)];
5400     TCGv a = cpu_gpr[rA(ctx->opcode)];
5401 
5402     tcg_gen_abs_tl(d, a);
5403     tcg_gen_neg_tl(d, d);
5404     if (unlikely(Rc(ctx->opcode) != 0)) {
5405         gen_set_Rc0(ctx, d);
5406     }
5407 }
5408 
5409 /* nabso - nabso. */
gen_nabso(DisasContext * ctx)5410 static void gen_nabso(DisasContext *ctx)
5411 {
5412     TCGv d = cpu_gpr[rD(ctx->opcode)];
5413     TCGv a = cpu_gpr[rA(ctx->opcode)];
5414 
5415     tcg_gen_abs_tl(d, a);
5416     tcg_gen_neg_tl(d, d);
5417     /* nabs never overflows */
5418     tcg_gen_movi_tl(cpu_ov, 0);
5419     if (unlikely(Rc(ctx->opcode) != 0)) {
5420         gen_set_Rc0(ctx, d);
5421     }
5422 }
5423 
5424 /* rlmi - rlmi. */
gen_rlmi(DisasContext * ctx)5425 static void gen_rlmi(DisasContext *ctx)
5426 {
5427     uint32_t mb = MB(ctx->opcode);
5428     uint32_t me = ME(ctx->opcode);
5429     TCGv t0 = tcg_temp_new();
5430     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
5431     tcg_gen_rotl_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
5432     tcg_gen_andi_tl(t0, t0, MASK(mb, me));
5433     tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
5434                     ~MASK(mb, me));
5435     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], t0);
5436     tcg_temp_free(t0);
5437     if (unlikely(Rc(ctx->opcode) != 0)) {
5438         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5439     }
5440 }
5441 
5442 /* rrib - rrib. */
gen_rrib(DisasContext * ctx)5443 static void gen_rrib(DisasContext *ctx)
5444 {
5445     TCGv t0 = tcg_temp_new();
5446     TCGv t1 = tcg_temp_new();
5447     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
5448     tcg_gen_movi_tl(t1, 0x80000000);
5449     tcg_gen_shr_tl(t1, t1, t0);
5450     tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
5451     tcg_gen_and_tl(t0, t0, t1);
5452     tcg_gen_andc_tl(t1, cpu_gpr[rA(ctx->opcode)], t1);
5453     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5454     tcg_temp_free(t0);
5455     tcg_temp_free(t1);
5456     if (unlikely(Rc(ctx->opcode) != 0)) {
5457         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5458     }
5459 }
5460 
5461 /* sle - sle. */
gen_sle(DisasContext * ctx)5462 static void gen_sle(DisasContext *ctx)
5463 {
5464     TCGv t0 = tcg_temp_new();
5465     TCGv t1 = tcg_temp_new();
5466     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
5467     tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
5468     tcg_gen_subfi_tl(t1, 32, t1);
5469     tcg_gen_shr_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
5470     tcg_gen_or_tl(t1, t0, t1);
5471     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
5472     gen_store_spr(SPR_MQ, t1);
5473     tcg_temp_free(t0);
5474     tcg_temp_free(t1);
5475     if (unlikely(Rc(ctx->opcode) != 0)) {
5476         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5477     }
5478 }
5479 
5480 /* sleq - sleq. */
gen_sleq(DisasContext * ctx)5481 static void gen_sleq(DisasContext *ctx)
5482 {
5483     TCGv t0 = tcg_temp_new();
5484     TCGv t1 = tcg_temp_new();
5485     TCGv t2 = tcg_temp_new();
5486     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
5487     tcg_gen_movi_tl(t2, 0xFFFFFFFF);
5488     tcg_gen_shl_tl(t2, t2, t0);
5489     tcg_gen_rotl_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
5490     gen_load_spr(t1, SPR_MQ);
5491     gen_store_spr(SPR_MQ, t0);
5492     tcg_gen_and_tl(t0, t0, t2);
5493     tcg_gen_andc_tl(t1, t1, t2);
5494     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5495     tcg_temp_free(t0);
5496     tcg_temp_free(t1);
5497     tcg_temp_free(t2);
5498     if (unlikely(Rc(ctx->opcode) != 0)) {
5499         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5500     }
5501 }
5502 
5503 /* sliq - sliq. */
gen_sliq(DisasContext * ctx)5504 static void gen_sliq(DisasContext *ctx)
5505 {
5506     int sh = SH(ctx->opcode);
5507     TCGv t0 = tcg_temp_new();
5508     TCGv t1 = tcg_temp_new();
5509     tcg_gen_shli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
5510     tcg_gen_shri_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh);
5511     tcg_gen_or_tl(t1, t0, t1);
5512     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
5513     gen_store_spr(SPR_MQ, t1);
5514     tcg_temp_free(t0);
5515     tcg_temp_free(t1);
5516     if (unlikely(Rc(ctx->opcode) != 0)) {
5517         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5518     }
5519 }
5520 
5521 /* slliq - slliq. */
gen_slliq(DisasContext * ctx)5522 static void gen_slliq(DisasContext *ctx)
5523 {
5524     int sh = SH(ctx->opcode);
5525     TCGv t0 = tcg_temp_new();
5526     TCGv t1 = tcg_temp_new();
5527     tcg_gen_rotli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
5528     gen_load_spr(t1, SPR_MQ);
5529     gen_store_spr(SPR_MQ, t0);
5530     tcg_gen_andi_tl(t0, t0,  (0xFFFFFFFFU << sh));
5531     tcg_gen_andi_tl(t1, t1, ~(0xFFFFFFFFU << sh));
5532     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5533     tcg_temp_free(t0);
5534     tcg_temp_free(t1);
5535     if (unlikely(Rc(ctx->opcode) != 0)) {
5536         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5537     }
5538 }
5539 
5540 /* sllq - sllq. */
gen_sllq(DisasContext * ctx)5541 static void gen_sllq(DisasContext *ctx)
5542 {
5543     TCGLabel *l1 = gen_new_label();
5544     TCGLabel *l2 = gen_new_label();
5545     TCGv t0 = tcg_temp_local_new();
5546     TCGv t1 = tcg_temp_local_new();
5547     TCGv t2 = tcg_temp_local_new();
5548     tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F);
5549     tcg_gen_movi_tl(t1, 0xFFFFFFFF);
5550     tcg_gen_shl_tl(t1, t1, t2);
5551     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20);
5552     tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
5553     gen_load_spr(t0, SPR_MQ);
5554     tcg_gen_and_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5555     tcg_gen_br(l2);
5556     gen_set_label(l1);
5557     tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t2);
5558     gen_load_spr(t2, SPR_MQ);
5559     tcg_gen_andc_tl(t1, t2, t1);
5560     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5561     gen_set_label(l2);
5562     tcg_temp_free(t0);
5563     tcg_temp_free(t1);
5564     tcg_temp_free(t2);
5565     if (unlikely(Rc(ctx->opcode) != 0)) {
5566         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5567     }
5568 }
5569 
5570 /* slq - slq. */
gen_slq(DisasContext * ctx)5571 static void gen_slq(DisasContext *ctx)
5572 {
5573     TCGLabel *l1 = gen_new_label();
5574     TCGv t0 = tcg_temp_new();
5575     TCGv t1 = tcg_temp_new();
5576     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
5577     tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
5578     tcg_gen_subfi_tl(t1, 32, t1);
5579     tcg_gen_shr_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
5580     tcg_gen_or_tl(t1, t0, t1);
5581     gen_store_spr(SPR_MQ, t1);
5582     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x20);
5583     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
5584     tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5585     tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
5586     gen_set_label(l1);
5587     tcg_temp_free(t0);
5588     tcg_temp_free(t1);
5589     if (unlikely(Rc(ctx->opcode) != 0)) {
5590         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5591     }
5592 }
5593 
5594 /* sraiq - sraiq. */
gen_sraiq(DisasContext * ctx)5595 static void gen_sraiq(DisasContext *ctx)
5596 {
5597     int sh = SH(ctx->opcode);
5598     TCGLabel *l1 = gen_new_label();
5599     TCGv t0 = tcg_temp_new();
5600     TCGv t1 = tcg_temp_new();
5601     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
5602     tcg_gen_shli_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh);
5603     tcg_gen_or_tl(t0, t0, t1);
5604     gen_store_spr(SPR_MQ, t0);
5605     tcg_gen_movi_tl(cpu_ca, 0);
5606     tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5607     tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rS(ctx->opcode)], 0, l1);
5608     tcg_gen_movi_tl(cpu_ca, 1);
5609     gen_set_label(l1);
5610     tcg_gen_sari_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], sh);
5611     tcg_temp_free(t0);
5612     tcg_temp_free(t1);
5613     if (unlikely(Rc(ctx->opcode) != 0)) {
5614         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5615     }
5616 }
5617 
5618 /* sraq - sraq. */
gen_sraq(DisasContext * ctx)5619 static void gen_sraq(DisasContext *ctx)
5620 {
5621     TCGLabel *l1 = gen_new_label();
5622     TCGLabel *l2 = gen_new_label();
5623     TCGv t0 = tcg_temp_new();
5624     TCGv t1 = tcg_temp_local_new();
5625     TCGv t2 = tcg_temp_local_new();
5626     tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F);
5627     tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t2);
5628     tcg_gen_sar_tl(t1, cpu_gpr[rS(ctx->opcode)], t2);
5629     tcg_gen_subfi_tl(t2, 32, t2);
5630     tcg_gen_shl_tl(t2, cpu_gpr[rS(ctx->opcode)], t2);
5631     tcg_gen_or_tl(t0, t0, t2);
5632     gen_store_spr(SPR_MQ, t0);
5633     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20);
5634     tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, l1);
5635     tcg_gen_mov_tl(t2, cpu_gpr[rS(ctx->opcode)]);
5636     tcg_gen_sari_tl(t1, cpu_gpr[rS(ctx->opcode)], 31);
5637     gen_set_label(l1);
5638     tcg_temp_free(t0);
5639     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t1);
5640     tcg_gen_movi_tl(cpu_ca, 0);
5641     tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l2);
5642     tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, l2);
5643     tcg_gen_movi_tl(cpu_ca, 1);
5644     gen_set_label(l2);
5645     tcg_temp_free(t1);
5646     tcg_temp_free(t2);
5647     if (unlikely(Rc(ctx->opcode) != 0)) {
5648         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5649     }
5650 }
5651 
5652 /* sre - sre. */
gen_sre(DisasContext * ctx)5653 static void gen_sre(DisasContext *ctx)
5654 {
5655     TCGv t0 = tcg_temp_new();
5656     TCGv t1 = tcg_temp_new();
5657     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
5658     tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
5659     tcg_gen_subfi_tl(t1, 32, t1);
5660     tcg_gen_shl_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
5661     tcg_gen_or_tl(t1, t0, t1);
5662     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
5663     gen_store_spr(SPR_MQ, t1);
5664     tcg_temp_free(t0);
5665     tcg_temp_free(t1);
5666     if (unlikely(Rc(ctx->opcode) != 0)) {
5667         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5668     }
5669 }
5670 
5671 /* srea - srea. */
gen_srea(DisasContext * ctx)5672 static void gen_srea(DisasContext *ctx)
5673 {
5674     TCGv t0 = tcg_temp_new();
5675     TCGv t1 = tcg_temp_new();
5676     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
5677     tcg_gen_rotr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
5678     gen_store_spr(SPR_MQ, t0);
5679     tcg_gen_sar_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], t1);
5680     tcg_temp_free(t0);
5681     tcg_temp_free(t1);
5682     if (unlikely(Rc(ctx->opcode) != 0)) {
5683         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5684     }
5685 }
5686 
5687 /* sreq */
gen_sreq(DisasContext * ctx)5688 static void gen_sreq(DisasContext *ctx)
5689 {
5690     TCGv t0 = tcg_temp_new();
5691     TCGv t1 = tcg_temp_new();
5692     TCGv t2 = tcg_temp_new();
5693     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
5694     tcg_gen_movi_tl(t1, 0xFFFFFFFF);
5695     tcg_gen_shr_tl(t1, t1, t0);
5696     tcg_gen_rotr_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
5697     gen_load_spr(t2, SPR_MQ);
5698     gen_store_spr(SPR_MQ, t0);
5699     tcg_gen_and_tl(t0, t0, t1);
5700     tcg_gen_andc_tl(t2, t2, t1);
5701     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t2);
5702     tcg_temp_free(t0);
5703     tcg_temp_free(t1);
5704     tcg_temp_free(t2);
5705     if (unlikely(Rc(ctx->opcode) != 0)) {
5706         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5707     }
5708 }
5709 
5710 /* sriq */
gen_sriq(DisasContext * ctx)5711 static void gen_sriq(DisasContext *ctx)
5712 {
5713     int sh = SH(ctx->opcode);
5714     TCGv t0 = tcg_temp_new();
5715     TCGv t1 = tcg_temp_new();
5716     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
5717     tcg_gen_shli_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh);
5718     tcg_gen_or_tl(t1, t0, t1);
5719     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
5720     gen_store_spr(SPR_MQ, t1);
5721     tcg_temp_free(t0);
5722     tcg_temp_free(t1);
5723     if (unlikely(Rc(ctx->opcode) != 0)) {
5724         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5725     }
5726 }
5727 
5728 /* srliq */
gen_srliq(DisasContext * ctx)5729 static void gen_srliq(DisasContext *ctx)
5730 {
5731     int sh = SH(ctx->opcode);
5732     TCGv t0 = tcg_temp_new();
5733     TCGv t1 = tcg_temp_new();
5734     tcg_gen_rotri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
5735     gen_load_spr(t1, SPR_MQ);
5736     gen_store_spr(SPR_MQ, t0);
5737     tcg_gen_andi_tl(t0, t0,  (0xFFFFFFFFU >> sh));
5738     tcg_gen_andi_tl(t1, t1, ~(0xFFFFFFFFU >> sh));
5739     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5740     tcg_temp_free(t0);
5741     tcg_temp_free(t1);
5742     if (unlikely(Rc(ctx->opcode) != 0)) {
5743         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5744     }
5745 }
5746 
5747 /* srlq */
gen_srlq(DisasContext * ctx)5748 static void gen_srlq(DisasContext *ctx)
5749 {
5750     TCGLabel *l1 = gen_new_label();
5751     TCGLabel *l2 = gen_new_label();
5752     TCGv t0 = tcg_temp_local_new();
5753     TCGv t1 = tcg_temp_local_new();
5754     TCGv t2 = tcg_temp_local_new();
5755     tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F);
5756     tcg_gen_movi_tl(t1, 0xFFFFFFFF);
5757     tcg_gen_shr_tl(t2, t1, t2);
5758     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20);
5759     tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
5760     gen_load_spr(t0, SPR_MQ);
5761     tcg_gen_and_tl(cpu_gpr[rA(ctx->opcode)], t0, t2);
5762     tcg_gen_br(l2);
5763     gen_set_label(l1);
5764     tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t2);
5765     tcg_gen_and_tl(t0, t0, t2);
5766     gen_load_spr(t1, SPR_MQ);
5767     tcg_gen_andc_tl(t1, t1, t2);
5768     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5769     gen_set_label(l2);
5770     tcg_temp_free(t0);
5771     tcg_temp_free(t1);
5772     tcg_temp_free(t2);
5773     if (unlikely(Rc(ctx->opcode) != 0)) {
5774         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5775     }
5776 }
5777 
5778 /* srq */
gen_srq(DisasContext * ctx)5779 static void gen_srq(DisasContext *ctx)
5780 {
5781     TCGLabel *l1 = gen_new_label();
5782     TCGv t0 = tcg_temp_new();
5783     TCGv t1 = tcg_temp_new();
5784     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
5785     tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
5786     tcg_gen_subfi_tl(t1, 32, t1);
5787     tcg_gen_shl_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
5788     tcg_gen_or_tl(t1, t0, t1);
5789     gen_store_spr(SPR_MQ, t1);
5790     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x20);
5791     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
5792     tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
5793     tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
5794     gen_set_label(l1);
5795     tcg_temp_free(t0);
5796     tcg_temp_free(t1);
5797     if (unlikely(Rc(ctx->opcode) != 0)) {
5798         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5799     }
5800 }
5801 
5802 /* PowerPC 602 specific instructions */
5803 
5804 /* dsa  */
gen_dsa(DisasContext * ctx)5805 static void gen_dsa(DisasContext *ctx)
5806 {
5807     /* XXX: TODO */
5808     gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5809 }
5810 
5811 /* esa */
gen_esa(DisasContext * ctx)5812 static void gen_esa(DisasContext *ctx)
5813 {
5814     /* XXX: TODO */
5815     gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5816 }
5817 
5818 /* mfrom */
gen_mfrom(DisasContext * ctx)5819 static void gen_mfrom(DisasContext *ctx)
5820 {
5821 #if defined(CONFIG_USER_ONLY)
5822     GEN_PRIV;
5823 #else
5824     CHK_SV;
5825     gen_helper_602_mfrom(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5826 #endif /* defined(CONFIG_USER_ONLY) */
5827 }
5828 
5829 /* 602 - 603 - G2 TLB management */
5830 
5831 /* tlbld */
gen_tlbld_6xx(DisasContext * ctx)5832 static void gen_tlbld_6xx(DisasContext *ctx)
5833 {
5834 #if defined(CONFIG_USER_ONLY)
5835     GEN_PRIV;
5836 #else
5837     CHK_SV;
5838     gen_helper_6xx_tlbd(cpu_env, cpu_gpr[rB(ctx->opcode)]);
5839 #endif /* defined(CONFIG_USER_ONLY) */
5840 }
5841 
5842 /* tlbli */
gen_tlbli_6xx(DisasContext * ctx)5843 static void gen_tlbli_6xx(DisasContext *ctx)
5844 {
5845 #if defined(CONFIG_USER_ONLY)
5846     GEN_PRIV;
5847 #else
5848     CHK_SV;
5849     gen_helper_6xx_tlbi(cpu_env, cpu_gpr[rB(ctx->opcode)]);
5850 #endif /* defined(CONFIG_USER_ONLY) */
5851 }
5852 
5853 /* 74xx TLB management */
5854 
5855 /* tlbld */
gen_tlbld_74xx(DisasContext * ctx)5856 static void gen_tlbld_74xx(DisasContext *ctx)
5857 {
5858 #if defined(CONFIG_USER_ONLY)
5859     GEN_PRIV;
5860 #else
5861     CHK_SV;
5862     gen_helper_74xx_tlbd(cpu_env, cpu_gpr[rB(ctx->opcode)]);
5863 #endif /* defined(CONFIG_USER_ONLY) */
5864 }
5865 
5866 /* tlbli */
gen_tlbli_74xx(DisasContext * ctx)5867 static void gen_tlbli_74xx(DisasContext *ctx)
5868 {
5869 #if defined(CONFIG_USER_ONLY)
5870     GEN_PRIV;
5871 #else
5872     CHK_SV;
5873     gen_helper_74xx_tlbi(cpu_env, cpu_gpr[rB(ctx->opcode)]);
5874 #endif /* defined(CONFIG_USER_ONLY) */
5875 }
5876 
5877 /* POWER instructions not in PowerPC 601 */
5878 
5879 /* clf */
gen_clf(DisasContext * ctx)5880 static void gen_clf(DisasContext *ctx)
5881 {
5882     /* Cache line flush: implemented as no-op */
5883 }
5884 
5885 /* cli */
gen_cli(DisasContext * ctx)5886 static void gen_cli(DisasContext *ctx)
5887 {
5888 #if defined(CONFIG_USER_ONLY)
5889     GEN_PRIV;
5890 #else
5891     /* Cache line invalidate: privileged and treated as no-op */
5892     CHK_SV;
5893 #endif /* defined(CONFIG_USER_ONLY) */
5894 }
5895 
5896 /* dclst */
gen_dclst(DisasContext * ctx)5897 static void gen_dclst(DisasContext *ctx)
5898 {
5899     /* Data cache line store: treated as no-op */
5900 }
5901 
gen_mfsri(DisasContext * ctx)5902 static void gen_mfsri(DisasContext *ctx)
5903 {
5904 #if defined(CONFIG_USER_ONLY)
5905     GEN_PRIV;
5906 #else
5907     int ra = rA(ctx->opcode);
5908     int rd = rD(ctx->opcode);
5909     TCGv t0;
5910 
5911     CHK_SV;
5912     t0 = tcg_temp_new();
5913     gen_addr_reg_index(ctx, t0);
5914     tcg_gen_extract_tl(t0, t0, 28, 4);
5915     gen_helper_load_sr(cpu_gpr[rd], cpu_env, t0);
5916     tcg_temp_free(t0);
5917     if (ra != 0 && ra != rd) {
5918         tcg_gen_mov_tl(cpu_gpr[ra], cpu_gpr[rd]);
5919     }
5920 #endif /* defined(CONFIG_USER_ONLY) */
5921 }
5922 
gen_rac(DisasContext * ctx)5923 static void gen_rac(DisasContext *ctx)
5924 {
5925 #if defined(CONFIG_USER_ONLY)
5926     GEN_PRIV;
5927 #else
5928     TCGv t0;
5929 
5930     CHK_SV;
5931     t0 = tcg_temp_new();
5932     gen_addr_reg_index(ctx, t0);
5933     gen_helper_rac(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
5934     tcg_temp_free(t0);
5935 #endif /* defined(CONFIG_USER_ONLY) */
5936 }
5937 
gen_rfsvc(DisasContext * ctx)5938 static void gen_rfsvc(DisasContext *ctx)
5939 {
5940 #if defined(CONFIG_USER_ONLY)
5941     GEN_PRIV;
5942 #else
5943     CHK_SV;
5944 
5945     gen_helper_rfsvc(cpu_env);
5946     gen_sync_exception(ctx);
5947 #endif /* defined(CONFIG_USER_ONLY) */
5948 }
5949 
5950 /* svc is not implemented for now */
5951 
5952 /* BookE specific instructions */
5953 
5954 /* XXX: not implemented on 440 ? */
gen_mfapidi(DisasContext * ctx)5955 static void gen_mfapidi(DisasContext *ctx)
5956 {
5957     /* XXX: TODO */
5958     gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5959 }
5960 
5961 /* XXX: not implemented on 440 ? */
gen_tlbiva(DisasContext * ctx)5962 static void gen_tlbiva(DisasContext *ctx)
5963 {
5964 #if defined(CONFIG_USER_ONLY)
5965     GEN_PRIV;
5966 #else
5967     TCGv t0;
5968 
5969     CHK_SV;
5970     t0 = tcg_temp_new();
5971     gen_addr_reg_index(ctx, t0);
5972     gen_helper_tlbiva(cpu_env, cpu_gpr[rB(ctx->opcode)]);
5973     tcg_temp_free(t0);
5974 #endif /* defined(CONFIG_USER_ONLY) */
5975 }
5976 
5977 /* All 405 MAC instructions are translated here */
gen_405_mulladd_insn(DisasContext * ctx,int opc2,int opc3,int ra,int rb,int rt,int Rc)5978 static inline void gen_405_mulladd_insn(DisasContext *ctx, int opc2, int opc3,
5979                                         int ra, int rb, int rt, int Rc)
5980 {
5981     TCGv t0, t1;
5982 
5983     t0 = tcg_temp_local_new();
5984     t1 = tcg_temp_local_new();
5985 
5986     switch (opc3 & 0x0D) {
5987     case 0x05:
5988         /* macchw    - macchw.    - macchwo   - macchwo.   */
5989         /* macchws   - macchws.   - macchwso  - macchwso.  */
5990         /* nmacchw   - nmacchw.   - nmacchwo  - nmacchwo.  */
5991         /* nmacchws  - nmacchws.  - nmacchwso - nmacchwso. */
5992         /* mulchw - mulchw. */
5993         tcg_gen_ext16s_tl(t0, cpu_gpr[ra]);
5994         tcg_gen_sari_tl(t1, cpu_gpr[rb], 16);
5995         tcg_gen_ext16s_tl(t1, t1);
5996         break;
5997     case 0x04:
5998         /* macchwu   - macchwu.   - macchwuo  - macchwuo.  */
5999         /* macchwsu  - macchwsu.  - macchwsuo - macchwsuo. */
6000         /* mulchwu - mulchwu. */
6001         tcg_gen_ext16u_tl(t0, cpu_gpr[ra]);
6002         tcg_gen_shri_tl(t1, cpu_gpr[rb], 16);
6003         tcg_gen_ext16u_tl(t1, t1);
6004         break;
6005     case 0x01:
6006         /* machhw    - machhw.    - machhwo   - machhwo.   */
6007         /* machhws   - machhws.   - machhwso  - machhwso.  */
6008         /* nmachhw   - nmachhw.   - nmachhwo  - nmachhwo.  */
6009         /* nmachhws  - nmachhws.  - nmachhwso - nmachhwso. */
6010         /* mulhhw - mulhhw. */
6011         tcg_gen_sari_tl(t0, cpu_gpr[ra], 16);
6012         tcg_gen_ext16s_tl(t0, t0);
6013         tcg_gen_sari_tl(t1, cpu_gpr[rb], 16);
6014         tcg_gen_ext16s_tl(t1, t1);
6015         break;
6016     case 0x00:
6017         /* machhwu   - machhwu.   - machhwuo  - machhwuo.  */
6018         /* machhwsu  - machhwsu.  - machhwsuo - machhwsuo. */
6019         /* mulhhwu - mulhhwu. */
6020         tcg_gen_shri_tl(t0, cpu_gpr[ra], 16);
6021         tcg_gen_ext16u_tl(t0, t0);
6022         tcg_gen_shri_tl(t1, cpu_gpr[rb], 16);
6023         tcg_gen_ext16u_tl(t1, t1);
6024         break;
6025     case 0x0D:
6026         /* maclhw    - maclhw.    - maclhwo   - maclhwo.   */
6027         /* maclhws   - maclhws.   - maclhwso  - maclhwso.  */
6028         /* nmaclhw   - nmaclhw.   - nmaclhwo  - nmaclhwo.  */
6029         /* nmaclhws  - nmaclhws.  - nmaclhwso - nmaclhwso. */
6030         /* mullhw - mullhw. */
6031         tcg_gen_ext16s_tl(t0, cpu_gpr[ra]);
6032         tcg_gen_ext16s_tl(t1, cpu_gpr[rb]);
6033         break;
6034     case 0x0C:
6035         /* maclhwu   - maclhwu.   - maclhwuo  - maclhwuo.  */
6036         /* maclhwsu  - maclhwsu.  - maclhwsuo - maclhwsuo. */
6037         /* mullhwu - mullhwu. */
6038         tcg_gen_ext16u_tl(t0, cpu_gpr[ra]);
6039         tcg_gen_ext16u_tl(t1, cpu_gpr[rb]);
6040         break;
6041     }
6042     if (opc2 & 0x04) {
6043         /* (n)multiply-and-accumulate (0x0C / 0x0E) */
6044         tcg_gen_mul_tl(t1, t0, t1);
6045         if (opc2 & 0x02) {
6046             /* nmultiply-and-accumulate (0x0E) */
6047             tcg_gen_sub_tl(t0, cpu_gpr[rt], t1);
6048         } else {
6049             /* multiply-and-accumulate (0x0C) */
6050             tcg_gen_add_tl(t0, cpu_gpr[rt], t1);
6051         }
6052 
6053         if (opc3 & 0x12) {
6054             /* Check overflow and/or saturate */
6055             TCGLabel *l1 = gen_new_label();
6056 
6057             if (opc3 & 0x10) {
6058                 /* Start with XER OV disabled, the most likely case */
6059                 tcg_gen_movi_tl(cpu_ov, 0);
6060             }
6061             if (opc3 & 0x01) {
6062                 /* Signed */
6063                 tcg_gen_xor_tl(t1, cpu_gpr[rt], t1);
6064                 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
6065                 tcg_gen_xor_tl(t1, cpu_gpr[rt], t0);
6066                 tcg_gen_brcondi_tl(TCG_COND_LT, t1, 0, l1);
6067                 if (opc3 & 0x02) {
6068                     /* Saturate */
6069                     tcg_gen_sari_tl(t0, cpu_gpr[rt], 31);
6070                     tcg_gen_xori_tl(t0, t0, 0x7fffffff);
6071                 }
6072             } else {
6073                 /* Unsigned */
6074                 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6075                 if (opc3 & 0x02) {
6076                     /* Saturate */
6077                     tcg_gen_movi_tl(t0, UINT32_MAX);
6078                 }
6079             }
6080             if (opc3 & 0x10) {
6081                 /* Check overflow */
6082                 tcg_gen_movi_tl(cpu_ov, 1);
6083                 tcg_gen_movi_tl(cpu_so, 1);
6084             }
6085             gen_set_label(l1);
6086             tcg_gen_mov_tl(cpu_gpr[rt], t0);
6087         }
6088     } else {
6089         tcg_gen_mul_tl(cpu_gpr[rt], t0, t1);
6090     }
6091     tcg_temp_free(t0);
6092     tcg_temp_free(t1);
6093     if (unlikely(Rc) != 0) {
6094         /* Update Rc0 */
6095         gen_set_Rc0(ctx, cpu_gpr[rt]);
6096     }
6097 }
6098 
6099 #define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
6100 static void glue(gen_, name)(DisasContext *ctx)                               \
6101 {                                                                             \
6102     gen_405_mulladd_insn(ctx, opc2, opc3, rA(ctx->opcode), rB(ctx->opcode),   \
6103                          rD(ctx->opcode), Rc(ctx->opcode));                   \
6104 }
6105 
6106 /* macchw    - macchw.    */
6107 GEN_MAC_HANDLER(macchw, 0x0C, 0x05);
6108 /* macchwo   - macchwo.   */
6109 GEN_MAC_HANDLER(macchwo, 0x0C, 0x15);
6110 /* macchws   - macchws.   */
6111 GEN_MAC_HANDLER(macchws, 0x0C, 0x07);
6112 /* macchwso  - macchwso.  */
6113 GEN_MAC_HANDLER(macchwso, 0x0C, 0x17);
6114 /* macchwsu  - macchwsu.  */
6115 GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06);
6116 /* macchwsuo - macchwsuo. */
6117 GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16);
6118 /* macchwu   - macchwu.   */
6119 GEN_MAC_HANDLER(macchwu, 0x0C, 0x04);
6120 /* macchwuo  - macchwuo.  */
6121 GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14);
6122 /* machhw    - machhw.    */
6123 GEN_MAC_HANDLER(machhw, 0x0C, 0x01);
6124 /* machhwo   - machhwo.   */
6125 GEN_MAC_HANDLER(machhwo, 0x0C, 0x11);
6126 /* machhws   - machhws.   */
6127 GEN_MAC_HANDLER(machhws, 0x0C, 0x03);
6128 /* machhwso  - machhwso.  */
6129 GEN_MAC_HANDLER(machhwso, 0x0C, 0x13);
6130 /* machhwsu  - machhwsu.  */
6131 GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02);
6132 /* machhwsuo - machhwsuo. */
6133 GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12);
6134 /* machhwu   - machhwu.   */
6135 GEN_MAC_HANDLER(machhwu, 0x0C, 0x00);
6136 /* machhwuo  - machhwuo.  */
6137 GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10);
6138 /* maclhw    - maclhw.    */
6139 GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D);
6140 /* maclhwo   - maclhwo.   */
6141 GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D);
6142 /* maclhws   - maclhws.   */
6143 GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F);
6144 /* maclhwso  - maclhwso.  */
6145 GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F);
6146 /* maclhwu   - maclhwu.   */
6147 GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C);
6148 /* maclhwuo  - maclhwuo.  */
6149 GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C);
6150 /* maclhwsu  - maclhwsu.  */
6151 GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E);
6152 /* maclhwsuo - maclhwsuo. */
6153 GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E);
6154 /* nmacchw   - nmacchw.   */
6155 GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05);
6156 /* nmacchwo  - nmacchwo.  */
6157 GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15);
6158 /* nmacchws  - nmacchws.  */
6159 GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07);
6160 /* nmacchwso - nmacchwso. */
6161 GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17);
6162 /* nmachhw   - nmachhw.   */
6163 GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01);
6164 /* nmachhwo  - nmachhwo.  */
6165 GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11);
6166 /* nmachhws  - nmachhws.  */
6167 GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03);
6168 /* nmachhwso - nmachhwso. */
6169 GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13);
6170 /* nmaclhw   - nmaclhw.   */
6171 GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D);
6172 /* nmaclhwo  - nmaclhwo.  */
6173 GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D);
6174 /* nmaclhws  - nmaclhws.  */
6175 GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F);
6176 /* nmaclhwso - nmaclhwso. */
6177 GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F);
6178 
6179 /* mulchw  - mulchw.  */
6180 GEN_MAC_HANDLER(mulchw, 0x08, 0x05);
6181 /* mulchwu - mulchwu. */
6182 GEN_MAC_HANDLER(mulchwu, 0x08, 0x04);
6183 /* mulhhw  - mulhhw.  */
6184 GEN_MAC_HANDLER(mulhhw, 0x08, 0x01);
6185 /* mulhhwu - mulhhwu. */
6186 GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00);
6187 /* mullhw  - mullhw.  */
6188 GEN_MAC_HANDLER(mullhw, 0x08, 0x0D);
6189 /* mullhwu - mullhwu. */
6190 GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C);
6191 
6192 /* mfdcr */
gen_mfdcr(DisasContext * ctx)6193 static void gen_mfdcr(DisasContext *ctx)
6194 {
6195 #if defined(CONFIG_USER_ONLY)
6196     GEN_PRIV;
6197 #else
6198     TCGv dcrn;
6199 
6200     CHK_SV;
6201     dcrn = tcg_const_tl(SPR(ctx->opcode));
6202     gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_env, dcrn);
6203     tcg_temp_free(dcrn);
6204 #endif /* defined(CONFIG_USER_ONLY) */
6205 }
6206 
6207 /* mtdcr */
gen_mtdcr(DisasContext * ctx)6208 static void gen_mtdcr(DisasContext *ctx)
6209 {
6210 #if defined(CONFIG_USER_ONLY)
6211     GEN_PRIV;
6212 #else
6213     TCGv dcrn;
6214 
6215     CHK_SV;
6216     dcrn = tcg_const_tl(SPR(ctx->opcode));
6217     gen_helper_store_dcr(cpu_env, dcrn, cpu_gpr[rS(ctx->opcode)]);
6218     tcg_temp_free(dcrn);
6219 #endif /* defined(CONFIG_USER_ONLY) */
6220 }
6221 
6222 /* mfdcrx */
6223 /* XXX: not implemented on 440 ? */
gen_mfdcrx(DisasContext * ctx)6224 static void gen_mfdcrx(DisasContext *ctx)
6225 {
6226 #if defined(CONFIG_USER_ONLY)
6227     GEN_PRIV;
6228 #else
6229     CHK_SV;
6230     gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_env,
6231                         cpu_gpr[rA(ctx->opcode)]);
6232     /* Note: Rc update flag set leads to undefined state of Rc0 */
6233 #endif /* defined(CONFIG_USER_ONLY) */
6234 }
6235 
6236 /* mtdcrx */
6237 /* XXX: not implemented on 440 ? */
gen_mtdcrx(DisasContext * ctx)6238 static void gen_mtdcrx(DisasContext *ctx)
6239 {
6240 #if defined(CONFIG_USER_ONLY)
6241     GEN_PRIV;
6242 #else
6243     CHK_SV;
6244     gen_helper_store_dcr(cpu_env, cpu_gpr[rA(ctx->opcode)],
6245                          cpu_gpr[rS(ctx->opcode)]);
6246     /* Note: Rc update flag set leads to undefined state of Rc0 */
6247 #endif /* defined(CONFIG_USER_ONLY) */
6248 }
6249 
6250 /* mfdcrux (PPC 460) : user-mode access to DCR */
gen_mfdcrux(DisasContext * ctx)6251 static void gen_mfdcrux(DisasContext *ctx)
6252 {
6253     gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_env,
6254                         cpu_gpr[rA(ctx->opcode)]);
6255     /* Note: Rc update flag set leads to undefined state of Rc0 */
6256 }
6257 
6258 /* mtdcrux (PPC 460) : user-mode access to DCR */
gen_mtdcrux(DisasContext * ctx)6259 static void gen_mtdcrux(DisasContext *ctx)
6260 {
6261     gen_helper_store_dcr(cpu_env, cpu_gpr[rA(ctx->opcode)],
6262                          cpu_gpr[rS(ctx->opcode)]);
6263     /* Note: Rc update flag set leads to undefined state of Rc0 */
6264 }
6265 
6266 /* dccci */
gen_dccci(DisasContext * ctx)6267 static void gen_dccci(DisasContext *ctx)
6268 {
6269     CHK_SV;
6270     /* interpreted as no-op */
6271 }
6272 
6273 /* dcread */
gen_dcread(DisasContext * ctx)6274 static void gen_dcread(DisasContext *ctx)
6275 {
6276 #if defined(CONFIG_USER_ONLY)
6277     GEN_PRIV;
6278 #else
6279     TCGv EA, val;
6280 
6281     CHK_SV;
6282     gen_set_access_type(ctx, ACCESS_CACHE);
6283     EA = tcg_temp_new();
6284     gen_addr_reg_index(ctx, EA);
6285     val = tcg_temp_new();
6286     gen_qemu_ld32u(ctx, val, EA);
6287     tcg_temp_free(val);
6288     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], EA);
6289     tcg_temp_free(EA);
6290 #endif /* defined(CONFIG_USER_ONLY) */
6291 }
6292 
6293 /* icbt */
gen_icbt_40x(DisasContext * ctx)6294 static void gen_icbt_40x(DisasContext *ctx)
6295 {
6296     /*
6297      * interpreted as no-op
6298      * XXX: specification say this is treated as a load by the MMU but
6299      *      does not generate any exception
6300      */
6301 }
6302 
6303 /* iccci */
gen_iccci(DisasContext * ctx)6304 static void gen_iccci(DisasContext *ctx)
6305 {
6306     CHK_SV;
6307     /* interpreted as no-op */
6308 }
6309 
6310 /* icread */
gen_icread(DisasContext * ctx)6311 static void gen_icread(DisasContext *ctx)
6312 {
6313     CHK_SV;
6314     /* interpreted as no-op */
6315 }
6316 
6317 /* rfci (supervisor only) */
gen_rfci_40x(DisasContext * ctx)6318 static void gen_rfci_40x(DisasContext *ctx)
6319 {
6320 #if defined(CONFIG_USER_ONLY)
6321     GEN_PRIV;
6322 #else
6323     CHK_SV;
6324     /* Restore CPU state */
6325     gen_helper_40x_rfci(cpu_env);
6326     gen_sync_exception(ctx);
6327 #endif /* defined(CONFIG_USER_ONLY) */
6328 }
6329 
gen_rfci(DisasContext * ctx)6330 static void gen_rfci(DisasContext *ctx)
6331 {
6332 #if defined(CONFIG_USER_ONLY)
6333     GEN_PRIV;
6334 #else
6335     CHK_SV;
6336     /* Restore CPU state */
6337     gen_helper_rfci(cpu_env);
6338     gen_sync_exception(ctx);
6339 #endif /* defined(CONFIG_USER_ONLY) */
6340 }
6341 
6342 /* BookE specific */
6343 
6344 /* XXX: not implemented on 440 ? */
gen_rfdi(DisasContext * ctx)6345 static void gen_rfdi(DisasContext *ctx)
6346 {
6347 #if defined(CONFIG_USER_ONLY)
6348     GEN_PRIV;
6349 #else
6350     CHK_SV;
6351     /* Restore CPU state */
6352     gen_helper_rfdi(cpu_env);
6353     gen_sync_exception(ctx);
6354 #endif /* defined(CONFIG_USER_ONLY) */
6355 }
6356 
6357 /* XXX: not implemented on 440 ? */
gen_rfmci(DisasContext * ctx)6358 static void gen_rfmci(DisasContext *ctx)
6359 {
6360 #if defined(CONFIG_USER_ONLY)
6361     GEN_PRIV;
6362 #else
6363     CHK_SV;
6364     /* Restore CPU state */
6365     gen_helper_rfmci(cpu_env);
6366     gen_sync_exception(ctx);
6367 #endif /* defined(CONFIG_USER_ONLY) */
6368 }
6369 
6370 /* TLB management - PowerPC 405 implementation */
6371 
6372 /* tlbre */
gen_tlbre_40x(DisasContext * ctx)6373 static void gen_tlbre_40x(DisasContext *ctx)
6374 {
6375 #if defined(CONFIG_USER_ONLY)
6376     GEN_PRIV;
6377 #else
6378     CHK_SV;
6379     switch (rB(ctx->opcode)) {
6380     case 0:
6381         gen_helper_4xx_tlbre_hi(cpu_gpr[rD(ctx->opcode)], cpu_env,
6382                                 cpu_gpr[rA(ctx->opcode)]);
6383         break;
6384     case 1:
6385         gen_helper_4xx_tlbre_lo(cpu_gpr[rD(ctx->opcode)], cpu_env,
6386                                 cpu_gpr[rA(ctx->opcode)]);
6387         break;
6388     default:
6389         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
6390         break;
6391     }
6392 #endif /* defined(CONFIG_USER_ONLY) */
6393 }
6394 
6395 /* tlbsx - tlbsx. */
gen_tlbsx_40x(DisasContext * ctx)6396 static void gen_tlbsx_40x(DisasContext *ctx)
6397 {
6398 #if defined(CONFIG_USER_ONLY)
6399     GEN_PRIV;
6400 #else
6401     TCGv t0;
6402 
6403     CHK_SV;
6404     t0 = tcg_temp_new();
6405     gen_addr_reg_index(ctx, t0);
6406     gen_helper_4xx_tlbsx(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
6407     tcg_temp_free(t0);
6408     if (Rc(ctx->opcode)) {
6409         TCGLabel *l1 = gen_new_label();
6410         tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
6411         tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rD(ctx->opcode)], -1, l1);
6412         tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
6413         gen_set_label(l1);
6414     }
6415 #endif /* defined(CONFIG_USER_ONLY) */
6416 }
6417 
6418 /* tlbwe */
gen_tlbwe_40x(DisasContext * ctx)6419 static void gen_tlbwe_40x(DisasContext *ctx)
6420 {
6421 #if defined(CONFIG_USER_ONLY)
6422     GEN_PRIV;
6423 #else
6424     CHK_SV;
6425 
6426     switch (rB(ctx->opcode)) {
6427     case 0:
6428         gen_helper_4xx_tlbwe_hi(cpu_env, cpu_gpr[rA(ctx->opcode)],
6429                                 cpu_gpr[rS(ctx->opcode)]);
6430         break;
6431     case 1:
6432         gen_helper_4xx_tlbwe_lo(cpu_env, cpu_gpr[rA(ctx->opcode)],
6433                                 cpu_gpr[rS(ctx->opcode)]);
6434         break;
6435     default:
6436         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
6437         break;
6438     }
6439 #endif /* defined(CONFIG_USER_ONLY) */
6440 }
6441 
6442 /* TLB management - PowerPC 440 implementation */
6443 
6444 /* tlbre */
gen_tlbre_440(DisasContext * ctx)6445 static void gen_tlbre_440(DisasContext *ctx)
6446 {
6447 #if defined(CONFIG_USER_ONLY)
6448     GEN_PRIV;
6449 #else
6450     CHK_SV;
6451 
6452     switch (rB(ctx->opcode)) {
6453     case 0:
6454     case 1:
6455     case 2:
6456         {
6457             TCGv_i32 t0 = tcg_const_i32(rB(ctx->opcode));
6458             gen_helper_440_tlbre(cpu_gpr[rD(ctx->opcode)], cpu_env,
6459                                  t0, cpu_gpr[rA(ctx->opcode)]);
6460             tcg_temp_free_i32(t0);
6461         }
6462         break;
6463     default:
6464         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
6465         break;
6466     }
6467 #endif /* defined(CONFIG_USER_ONLY) */
6468 }
6469 
6470 /* tlbsx - tlbsx. */
gen_tlbsx_440(DisasContext * ctx)6471 static void gen_tlbsx_440(DisasContext *ctx)
6472 {
6473 #if defined(CONFIG_USER_ONLY)
6474     GEN_PRIV;
6475 #else
6476     TCGv t0;
6477 
6478     CHK_SV;
6479     t0 = tcg_temp_new();
6480     gen_addr_reg_index(ctx, t0);
6481     gen_helper_440_tlbsx(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
6482     tcg_temp_free(t0);
6483     if (Rc(ctx->opcode)) {
6484         TCGLabel *l1 = gen_new_label();
6485         tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
6486         tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rD(ctx->opcode)], -1, l1);
6487         tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
6488         gen_set_label(l1);
6489     }
6490 #endif /* defined(CONFIG_USER_ONLY) */
6491 }
6492 
6493 /* tlbwe */
gen_tlbwe_440(DisasContext * ctx)6494 static void gen_tlbwe_440(DisasContext *ctx)
6495 {
6496 #if defined(CONFIG_USER_ONLY)
6497     GEN_PRIV;
6498 #else
6499     CHK_SV;
6500     switch (rB(ctx->opcode)) {
6501     case 0:
6502     case 1:
6503     case 2:
6504         {
6505             TCGv_i32 t0 = tcg_const_i32(rB(ctx->opcode));
6506             gen_helper_440_tlbwe(cpu_env, t0, cpu_gpr[rA(ctx->opcode)],
6507                                  cpu_gpr[rS(ctx->opcode)]);
6508             tcg_temp_free_i32(t0);
6509         }
6510         break;
6511     default:
6512         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
6513         break;
6514     }
6515 #endif /* defined(CONFIG_USER_ONLY) */
6516 }
6517 
6518 /* TLB management - PowerPC BookE 2.06 implementation */
6519 
6520 /* tlbre */
gen_tlbre_booke206(DisasContext * ctx)6521 static void gen_tlbre_booke206(DisasContext *ctx)
6522 {
6523  #if defined(CONFIG_USER_ONLY)
6524     GEN_PRIV;
6525 #else
6526    CHK_SV;
6527     gen_helper_booke206_tlbre(cpu_env);
6528 #endif /* defined(CONFIG_USER_ONLY) */
6529 }
6530 
6531 /* tlbsx - tlbsx. */
gen_tlbsx_booke206(DisasContext * ctx)6532 static void gen_tlbsx_booke206(DisasContext *ctx)
6533 {
6534 #if defined(CONFIG_USER_ONLY)
6535     GEN_PRIV;
6536 #else
6537     TCGv t0;
6538 
6539     CHK_SV;
6540     if (rA(ctx->opcode)) {
6541         t0 = tcg_temp_new();
6542         tcg_gen_mov_tl(t0, cpu_gpr[rD(ctx->opcode)]);
6543     } else {
6544         t0 = tcg_const_tl(0);
6545     }
6546 
6547     tcg_gen_add_tl(t0, t0, cpu_gpr[rB(ctx->opcode)]);
6548     gen_helper_booke206_tlbsx(cpu_env, t0);
6549     tcg_temp_free(t0);
6550 #endif /* defined(CONFIG_USER_ONLY) */
6551 }
6552 
6553 /* tlbwe */
gen_tlbwe_booke206(DisasContext * ctx)6554 static void gen_tlbwe_booke206(DisasContext *ctx)
6555 {
6556 #if defined(CONFIG_USER_ONLY)
6557     GEN_PRIV;
6558 #else
6559     CHK_SV;
6560     gen_helper_booke206_tlbwe(cpu_env);
6561 #endif /* defined(CONFIG_USER_ONLY) */
6562 }
6563 
gen_tlbivax_booke206(DisasContext * ctx)6564 static void gen_tlbivax_booke206(DisasContext *ctx)
6565 {
6566 #if defined(CONFIG_USER_ONLY)
6567     GEN_PRIV;
6568 #else
6569     TCGv t0;
6570 
6571     CHK_SV;
6572     t0 = tcg_temp_new();
6573     gen_addr_reg_index(ctx, t0);
6574     gen_helper_booke206_tlbivax(cpu_env, t0);
6575     tcg_temp_free(t0);
6576 #endif /* defined(CONFIG_USER_ONLY) */
6577 }
6578 
gen_tlbilx_booke206(DisasContext * ctx)6579 static void gen_tlbilx_booke206(DisasContext *ctx)
6580 {
6581 #if defined(CONFIG_USER_ONLY)
6582     GEN_PRIV;
6583 #else
6584     TCGv t0;
6585 
6586     CHK_SV;
6587     t0 = tcg_temp_new();
6588     gen_addr_reg_index(ctx, t0);
6589 
6590     switch ((ctx->opcode >> 21) & 0x3) {
6591     case 0:
6592         gen_helper_booke206_tlbilx0(cpu_env, t0);
6593         break;
6594     case 1:
6595         gen_helper_booke206_tlbilx1(cpu_env, t0);
6596         break;
6597     case 3:
6598         gen_helper_booke206_tlbilx3(cpu_env, t0);
6599         break;
6600     default:
6601         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
6602         break;
6603     }
6604 
6605     tcg_temp_free(t0);
6606 #endif /* defined(CONFIG_USER_ONLY) */
6607 }
6608 
6609 
6610 /* wrtee */
gen_wrtee(DisasContext * ctx)6611 static void gen_wrtee(DisasContext *ctx)
6612 {
6613 #if defined(CONFIG_USER_ONLY)
6614     GEN_PRIV;
6615 #else
6616     TCGv t0;
6617 
6618     CHK_SV;
6619     t0 = tcg_temp_new();
6620     tcg_gen_andi_tl(t0, cpu_gpr[rD(ctx->opcode)], (1 << MSR_EE));
6621     tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE));
6622     tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
6623     tcg_temp_free(t0);
6624     /*
6625      * Stop translation to have a chance to raise an exception if we
6626      * just set msr_ee to 1
6627      */
6628     gen_stop_exception(ctx);
6629 #endif /* defined(CONFIG_USER_ONLY) */
6630 }
6631 
6632 /* wrteei */
gen_wrteei(DisasContext * ctx)6633 static void gen_wrteei(DisasContext *ctx)
6634 {
6635 #if defined(CONFIG_USER_ONLY)
6636     GEN_PRIV;
6637 #else
6638     CHK_SV;
6639     if (ctx->opcode & 0x00008000) {
6640         tcg_gen_ori_tl(cpu_msr, cpu_msr, (1 << MSR_EE));
6641         /* Stop translation to have a chance to raise an exception */
6642         gen_stop_exception(ctx);
6643     } else {
6644         tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE));
6645     }
6646 #endif /* defined(CONFIG_USER_ONLY) */
6647 }
6648 
6649 /* PowerPC 440 specific instructions */
6650 
6651 /* dlmzb */
gen_dlmzb(DisasContext * ctx)6652 static void gen_dlmzb(DisasContext *ctx)
6653 {
6654     TCGv_i32 t0 = tcg_const_i32(Rc(ctx->opcode));
6655     gen_helper_dlmzb(cpu_gpr[rA(ctx->opcode)], cpu_env,
6656                      cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], t0);
6657     tcg_temp_free_i32(t0);
6658 }
6659 
6660 /* mbar replaces eieio on 440 */
gen_mbar(DisasContext * ctx)6661 static void gen_mbar(DisasContext *ctx)
6662 {
6663     /* interpreted as no-op */
6664 }
6665 
6666 /* msync replaces sync on 440 */
gen_msync_4xx(DisasContext * ctx)6667 static void gen_msync_4xx(DisasContext *ctx)
6668 {
6669     /* Only e500 seems to treat reserved bits as invalid */
6670     if ((ctx->insns_flags2 & PPC2_BOOKE206) &&
6671         (ctx->opcode & 0x03FFF801)) {
6672         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
6673     }
6674     /* otherwise interpreted as no-op */
6675 }
6676 
6677 /* icbt */
gen_icbt_440(DisasContext * ctx)6678 static void gen_icbt_440(DisasContext *ctx)
6679 {
6680     /*
6681      * interpreted as no-op
6682      * XXX: specification say this is treated as a load by the MMU but
6683      *      does not generate any exception
6684      */
6685 }
6686 
6687 /* Embedded.Processor Control */
6688 
gen_msgclr(DisasContext * ctx)6689 static void gen_msgclr(DisasContext *ctx)
6690 {
6691 #if defined(CONFIG_USER_ONLY)
6692     GEN_PRIV;
6693 #else
6694     CHK_HV;
6695     if (is_book3s_arch2x(ctx)) {
6696         gen_helper_book3s_msgclr(cpu_env, cpu_gpr[rB(ctx->opcode)]);
6697     } else {
6698         gen_helper_msgclr(cpu_env, cpu_gpr[rB(ctx->opcode)]);
6699     }
6700 #endif /* defined(CONFIG_USER_ONLY) */
6701 }
6702 
gen_msgsnd(DisasContext * ctx)6703 static void gen_msgsnd(DisasContext *ctx)
6704 {
6705 #if defined(CONFIG_USER_ONLY)
6706     GEN_PRIV;
6707 #else
6708     CHK_HV;
6709     if (is_book3s_arch2x(ctx)) {
6710         gen_helper_book3s_msgsnd(cpu_gpr[rB(ctx->opcode)]);
6711     } else {
6712         gen_helper_msgsnd(cpu_gpr[rB(ctx->opcode)]);
6713     }
6714 #endif /* defined(CONFIG_USER_ONLY) */
6715 }
6716 
6717 #if defined(TARGET_PPC64)
gen_msgclrp(DisasContext * ctx)6718 static void gen_msgclrp(DisasContext *ctx)
6719 {
6720 #if defined(CONFIG_USER_ONLY)
6721     GEN_PRIV;
6722 #else
6723     CHK_SV;
6724     gen_helper_book3s_msgclrp(cpu_env, cpu_gpr[rB(ctx->opcode)]);
6725 #endif /* defined(CONFIG_USER_ONLY) */
6726 }
6727 
gen_msgsndp(DisasContext * ctx)6728 static void gen_msgsndp(DisasContext *ctx)
6729 {
6730 #if defined(CONFIG_USER_ONLY)
6731     GEN_PRIV;
6732 #else
6733     CHK_SV;
6734     gen_helper_book3s_msgsndp(cpu_env, cpu_gpr[rB(ctx->opcode)]);
6735 #endif /* defined(CONFIG_USER_ONLY) */
6736 }
6737 #endif
6738 
gen_msgsync(DisasContext * ctx)6739 static void gen_msgsync(DisasContext *ctx)
6740 {
6741 #if defined(CONFIG_USER_ONLY)
6742     GEN_PRIV;
6743 #else
6744     CHK_HV;
6745 #endif /* defined(CONFIG_USER_ONLY) */
6746     /* interpreted as no-op */
6747 }
6748 
6749 #if defined(TARGET_PPC64)
gen_maddld(DisasContext * ctx)6750 static void gen_maddld(DisasContext *ctx)
6751 {
6752     TCGv_i64 t1 = tcg_temp_new_i64();
6753 
6754     tcg_gen_mul_i64(t1, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
6755     tcg_gen_add_i64(cpu_gpr[rD(ctx->opcode)], t1, cpu_gpr[rC(ctx->opcode)]);
6756     tcg_temp_free_i64(t1);
6757 }
6758 
6759 /* maddhd maddhdu */
gen_maddhd_maddhdu(DisasContext * ctx)6760 static void gen_maddhd_maddhdu(DisasContext *ctx)
6761 {
6762     TCGv_i64 lo = tcg_temp_new_i64();
6763     TCGv_i64 hi = tcg_temp_new_i64();
6764     TCGv_i64 t1 = tcg_temp_new_i64();
6765 
6766     if (Rc(ctx->opcode)) {
6767         tcg_gen_mulu2_i64(lo, hi, cpu_gpr[rA(ctx->opcode)],
6768                           cpu_gpr[rB(ctx->opcode)]);
6769         tcg_gen_movi_i64(t1, 0);
6770     } else {
6771         tcg_gen_muls2_i64(lo, hi, cpu_gpr[rA(ctx->opcode)],
6772                           cpu_gpr[rB(ctx->opcode)]);
6773         tcg_gen_sari_i64(t1, cpu_gpr[rC(ctx->opcode)], 63);
6774     }
6775     tcg_gen_add2_i64(t1, cpu_gpr[rD(ctx->opcode)], lo, hi,
6776                      cpu_gpr[rC(ctx->opcode)], t1);
6777     tcg_temp_free_i64(lo);
6778     tcg_temp_free_i64(hi);
6779     tcg_temp_free_i64(t1);
6780 }
6781 #endif /* defined(TARGET_PPC64) */
6782 
gen_tbegin(DisasContext * ctx)6783 static void gen_tbegin(DisasContext *ctx)
6784 {
6785     if (unlikely(!ctx->tm_enabled)) {
6786         gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_TM);
6787         return;
6788     }
6789     gen_helper_tbegin(cpu_env);
6790 }
6791 
6792 #define GEN_TM_NOOP(name)                                      \
6793 static inline void gen_##name(DisasContext *ctx)               \
6794 {                                                              \
6795     if (unlikely(!ctx->tm_enabled)) {                          \
6796         gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_TM);   \
6797         return;                                                \
6798     }                                                          \
6799     /*                                                         \
6800      * Because tbegin always fails in QEMU, these user         \
6801      * space instructions all have a simple implementation:    \
6802      *                                                         \
6803      *     CR[0] = 0b0 || MSR[TS] || 0b0                       \
6804      *           = 0b0 || 0b00    || 0b0                       \
6805      */                                                        \
6806     tcg_gen_movi_i32(cpu_crf[0], 0);                           \
6807 }
6808 
6809 GEN_TM_NOOP(tend);
6810 GEN_TM_NOOP(tabort);
6811 GEN_TM_NOOP(tabortwc);
6812 GEN_TM_NOOP(tabortwci);
6813 GEN_TM_NOOP(tabortdc);
6814 GEN_TM_NOOP(tabortdci);
6815 GEN_TM_NOOP(tsr);
6816 
gen_cp_abort(DisasContext * ctx)6817 static inline void gen_cp_abort(DisasContext *ctx)
6818 {
6819     /* Do Nothing */
6820 }
6821 
6822 #define GEN_CP_PASTE_NOOP(name)                           \
6823 static inline void gen_##name(DisasContext *ctx)          \
6824 {                                                         \
6825     /*                                                    \
6826      * Generate invalid exception until we have an        \
6827      * implementation of the copy paste facility          \
6828      */                                                   \
6829     gen_invalid(ctx);                                     \
6830 }
6831 
6832 GEN_CP_PASTE_NOOP(copy)
GEN_CP_PASTE_NOOP(paste)6833 GEN_CP_PASTE_NOOP(paste)
6834 
6835 static void gen_tcheck(DisasContext *ctx)
6836 {
6837     if (unlikely(!ctx->tm_enabled)) {
6838         gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_TM);
6839         return;
6840     }
6841     /*
6842      * Because tbegin always fails, the tcheck implementation is
6843      * simple:
6844      *
6845      * CR[CRF] = TDOOMED || MSR[TS] || 0b0
6846      *         = 0b1 || 0b00 || 0b0
6847      */
6848     tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)], 0x8);
6849 }
6850 
6851 #if defined(CONFIG_USER_ONLY)
6852 #define GEN_TM_PRIV_NOOP(name)                                 \
6853 static inline void gen_##name(DisasContext *ctx)               \
6854 {                                                              \
6855     gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC);            \
6856 }
6857 
6858 #else
6859 
6860 #define GEN_TM_PRIV_NOOP(name)                                 \
6861 static inline void gen_##name(DisasContext *ctx)               \
6862 {                                                              \
6863     CHK_SV;                                                    \
6864     if (unlikely(!ctx->tm_enabled)) {                          \
6865         gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_TM);   \
6866         return;                                                \
6867     }                                                          \
6868     /*                                                         \
6869      * Because tbegin always fails, the implementation is      \
6870      * simple:                                                 \
6871      *                                                         \
6872      *   CR[0] = 0b0 || MSR[TS] || 0b0                         \
6873      *         = 0b0 || 0b00 | 0b0                             \
6874      */                                                        \
6875     tcg_gen_movi_i32(cpu_crf[0], 0);                           \
6876 }
6877 
6878 #endif
6879 
6880 GEN_TM_PRIV_NOOP(treclaim);
6881 GEN_TM_PRIV_NOOP(trechkpt);
6882 
get_fpr(TCGv_i64 dst,int regno)6883 static inline void get_fpr(TCGv_i64 dst, int regno)
6884 {
6885     tcg_gen_ld_i64(dst, cpu_env, fpr_offset(regno));
6886 }
6887 
set_fpr(int regno,TCGv_i64 src)6888 static inline void set_fpr(int regno, TCGv_i64 src)
6889 {
6890     tcg_gen_st_i64(src, cpu_env, fpr_offset(regno));
6891 }
6892 
get_avr64(TCGv_i64 dst,int regno,bool high)6893 static inline void get_avr64(TCGv_i64 dst, int regno, bool high)
6894 {
6895     tcg_gen_ld_i64(dst, cpu_env, avr64_offset(regno, high));
6896 }
6897 
set_avr64(int regno,TCGv_i64 src,bool high)6898 static inline void set_avr64(int regno, TCGv_i64 src, bool high)
6899 {
6900     tcg_gen_st_i64(src, cpu_env, avr64_offset(regno, high));
6901 }
6902 
6903 #include "translate/fp-impl.c.inc"
6904 
6905 #include "translate/vmx-impl.c.inc"
6906 
6907 #include "translate/vsx-impl.c.inc"
6908 
6909 #include "translate/dfp-impl.c.inc"
6910 
6911 #include "translate/spe-impl.c.inc"
6912 
6913 /* Handles lfdp, lxsd, lxssp */
gen_dform39(DisasContext * ctx)6914 static void gen_dform39(DisasContext *ctx)
6915 {
6916     switch (ctx->opcode & 0x3) {
6917     case 0: /* lfdp */
6918         if (ctx->insns_flags2 & PPC2_ISA205) {
6919             return gen_lfdp(ctx);
6920         }
6921         break;
6922     case 2: /* lxsd */
6923         if (ctx->insns_flags2 & PPC2_ISA300) {
6924             return gen_lxsd(ctx);
6925         }
6926         break;
6927     case 3: /* lxssp */
6928         if (ctx->insns_flags2 & PPC2_ISA300) {
6929             return gen_lxssp(ctx);
6930         }
6931         break;
6932     }
6933     return gen_invalid(ctx);
6934 }
6935 
6936 /* handles stfdp, lxv, stxsd, stxssp lxvx */
gen_dform3D(DisasContext * ctx)6937 static void gen_dform3D(DisasContext *ctx)
6938 {
6939     if ((ctx->opcode & 3) == 1) { /* DQ-FORM */
6940         switch (ctx->opcode & 0x7) {
6941         case 1: /* lxv */
6942             if (ctx->insns_flags2 & PPC2_ISA300) {
6943                 return gen_lxv(ctx);
6944             }
6945             break;
6946         case 5: /* stxv */
6947             if (ctx->insns_flags2 & PPC2_ISA300) {
6948                 return gen_stxv(ctx);
6949             }
6950             break;
6951         }
6952     } else { /* DS-FORM */
6953         switch (ctx->opcode & 0x3) {
6954         case 0: /* stfdp */
6955             if (ctx->insns_flags2 & PPC2_ISA205) {
6956                 return gen_stfdp(ctx);
6957             }
6958             break;
6959         case 2: /* stxsd */
6960             if (ctx->insns_flags2 & PPC2_ISA300) {
6961                 return gen_stxsd(ctx);
6962             }
6963             break;
6964         case 3: /* stxssp */
6965             if (ctx->insns_flags2 & PPC2_ISA300) {
6966                 return gen_stxssp(ctx);
6967             }
6968             break;
6969         }
6970     }
6971     return gen_invalid(ctx);
6972 }
6973 
6974 #if defined(TARGET_PPC64)
6975 /* brd */
gen_brd(DisasContext * ctx)6976 static void gen_brd(DisasContext *ctx)
6977 {
6978     tcg_gen_bswap64_i64(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
6979 }
6980 
6981 /* brw */
gen_brw(DisasContext * ctx)6982 static void gen_brw(DisasContext *ctx)
6983 {
6984     tcg_gen_bswap64_i64(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
6985     tcg_gen_rotli_i64(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 32);
6986 
6987 }
6988 
6989 /* brh */
gen_brh(DisasContext * ctx)6990 static void gen_brh(DisasContext *ctx)
6991 {
6992     TCGv_i64 t0 = tcg_temp_new_i64();
6993     TCGv_i64 t1 = tcg_temp_new_i64();
6994     TCGv_i64 t2 = tcg_temp_new_i64();
6995 
6996     tcg_gen_movi_i64(t0, 0x00ff00ff00ff00ffull);
6997     tcg_gen_shri_i64(t1, cpu_gpr[rS(ctx->opcode)], 8);
6998     tcg_gen_and_i64(t2, t1, t0);
6999     tcg_gen_and_i64(t1, cpu_gpr[rS(ctx->opcode)], t0);
7000     tcg_gen_shli_i64(t1, t1, 8);
7001     tcg_gen_or_i64(cpu_gpr[rA(ctx->opcode)], t1, t2);
7002 
7003     tcg_temp_free_i64(t0);
7004     tcg_temp_free_i64(t1);
7005     tcg_temp_free_i64(t2);
7006 }
7007 #endif
7008 
7009 static opcode_t opcodes[] = {
7010 #if defined(TARGET_PPC64)
7011 GEN_HANDLER_E(brd, 0x1F, 0x1B, 0x05, 0x0000F801, PPC_NONE, PPC2_ISA310),
7012 GEN_HANDLER_E(brw, 0x1F, 0x1B, 0x04, 0x0000F801, PPC_NONE, PPC2_ISA310),
7013 GEN_HANDLER_E(brh, 0x1F, 0x1B, 0x06, 0x0000F801, PPC_NONE, PPC2_ISA310),
7014 #endif
7015 GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE),
7016 GEN_HANDLER(cmp, 0x1F, 0x00, 0x00, 0x00400000, PPC_INTEGER),
7017 GEN_HANDLER(cmpi, 0x0B, 0xFF, 0xFF, 0x00400000, PPC_INTEGER),
7018 GEN_HANDLER(cmpl, 0x1F, 0x00, 0x01, 0x00400001, PPC_INTEGER),
7019 GEN_HANDLER(cmpli, 0x0A, 0xFF, 0xFF, 0x00400000, PPC_INTEGER),
7020 #if defined(TARGET_PPC64)
7021 GEN_HANDLER_E(cmpeqb, 0x1F, 0x00, 0x07, 0x00600000, PPC_NONE, PPC2_ISA300),
7022 #endif
7023 GEN_HANDLER_E(cmpb, 0x1F, 0x1C, 0x0F, 0x00000001, PPC_NONE, PPC2_ISA205),
7024 GEN_HANDLER_E(cmprb, 0x1F, 0x00, 0x06, 0x00400001, PPC_NONE, PPC2_ISA300),
7025 GEN_HANDLER(isel, 0x1F, 0x0F, 0xFF, 0x00000001, PPC_ISEL),
7026 GEN_HANDLER(addi, 0x0E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
7027 GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
7028 GEN_HANDLER2(addic_, "addic.", 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
7029 GEN_HANDLER(addis, 0x0F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
7030 GEN_HANDLER_E(addpcis, 0x13, 0x2, 0xFF, 0x00000000, PPC_NONE, PPC2_ISA300),
7031 GEN_HANDLER(mulhw, 0x1F, 0x0B, 0x02, 0x00000400, PPC_INTEGER),
7032 GEN_HANDLER(mulhwu, 0x1F, 0x0B, 0x00, 0x00000400, PPC_INTEGER),
7033 GEN_HANDLER(mullw, 0x1F, 0x0B, 0x07, 0x00000000, PPC_INTEGER),
7034 GEN_HANDLER(mullwo, 0x1F, 0x0B, 0x17, 0x00000000, PPC_INTEGER),
7035 GEN_HANDLER(mulli, 0x07, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
7036 #if defined(TARGET_PPC64)
7037 GEN_HANDLER(mulld, 0x1F, 0x09, 0x07, 0x00000000, PPC_64B),
7038 #endif
7039 GEN_HANDLER(neg, 0x1F, 0x08, 0x03, 0x0000F800, PPC_INTEGER),
7040 GEN_HANDLER(nego, 0x1F, 0x08, 0x13, 0x0000F800, PPC_INTEGER),
7041 GEN_HANDLER(subfic, 0x08, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
7042 GEN_HANDLER2(andi_, "andi.", 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
7043 GEN_HANDLER2(andis_, "andis.", 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
7044 GEN_HANDLER(cntlzw, 0x1F, 0x1A, 0x00, 0x00000000, PPC_INTEGER),
7045 GEN_HANDLER_E(cnttzw, 0x1F, 0x1A, 0x10, 0x00000000, PPC_NONE, PPC2_ISA300),
7046 GEN_HANDLER_E(copy, 0x1F, 0x06, 0x18, 0x03C00001, PPC_NONE, PPC2_ISA300),
7047 GEN_HANDLER_E(cp_abort, 0x1F, 0x06, 0x1A, 0x03FFF801, PPC_NONE, PPC2_ISA300),
7048 GEN_HANDLER_E(paste, 0x1F, 0x06, 0x1C, 0x03C00000, PPC_NONE, PPC2_ISA300),
7049 GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER),
7050 GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER),
7051 GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
7052 GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
7053 GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
7054 GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
7055 GEN_HANDLER(popcntb, 0x1F, 0x1A, 0x03, 0x0000F801, PPC_POPCNTB),
7056 GEN_HANDLER(popcntw, 0x1F, 0x1A, 0x0b, 0x0000F801, PPC_POPCNTWD),
7057 GEN_HANDLER_E(prtyw, 0x1F, 0x1A, 0x04, 0x0000F801, PPC_NONE, PPC2_ISA205),
7058 #if defined(TARGET_PPC64)
7059 GEN_HANDLER(popcntd, 0x1F, 0x1A, 0x0F, 0x0000F801, PPC_POPCNTWD),
7060 GEN_HANDLER(cntlzd, 0x1F, 0x1A, 0x01, 0x00000000, PPC_64B),
7061 GEN_HANDLER_E(cnttzd, 0x1F, 0x1A, 0x11, 0x00000000, PPC_NONE, PPC2_ISA300),
7062 GEN_HANDLER_E(darn, 0x1F, 0x13, 0x17, 0x001CF801, PPC_NONE, PPC2_ISA300),
7063 GEN_HANDLER_E(prtyd, 0x1F, 0x1A, 0x05, 0x0000F801, PPC_NONE, PPC2_ISA205),
7064 GEN_HANDLER_E(bpermd, 0x1F, 0x1C, 0x07, 0x00000001, PPC_NONE, PPC2_PERM_ISA206),
7065 #endif
7066 GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
7067 GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
7068 GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
7069 GEN_HANDLER(slw, 0x1F, 0x18, 0x00, 0x00000000, PPC_INTEGER),
7070 GEN_HANDLER(sraw, 0x1F, 0x18, 0x18, 0x00000000, PPC_INTEGER),
7071 GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER),
7072 GEN_HANDLER(srw, 0x1F, 0x18, 0x10, 0x00000000, PPC_INTEGER),
7073 #if defined(TARGET_PPC64)
7074 GEN_HANDLER(sld, 0x1F, 0x1B, 0x00, 0x00000000, PPC_64B),
7075 GEN_HANDLER(srad, 0x1F, 0x1A, 0x18, 0x00000000, PPC_64B),
7076 GEN_HANDLER2(sradi0, "sradi", 0x1F, 0x1A, 0x19, 0x00000000, PPC_64B),
7077 GEN_HANDLER2(sradi1, "sradi", 0x1F, 0x1B, 0x19, 0x00000000, PPC_64B),
7078 GEN_HANDLER(srd, 0x1F, 0x1B, 0x10, 0x00000000, PPC_64B),
7079 GEN_HANDLER2_E(extswsli0, "extswsli", 0x1F, 0x1A, 0x1B, 0x00000000,
7080                PPC_NONE, PPC2_ISA300),
7081 GEN_HANDLER2_E(extswsli1, "extswsli", 0x1F, 0x1B, 0x1B, 0x00000000,
7082                PPC_NONE, PPC2_ISA300),
7083 #endif
7084 #if defined(TARGET_PPC64)
7085 GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B),
7086 GEN_HANDLER(lq, 0x38, 0xFF, 0xFF, 0x00000000, PPC_64BX),
7087 GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000000, PPC_64B),
7088 #endif
7089 /* handles lfdp, lxsd, lxssp */
7090 GEN_HANDLER_E(dform39, 0x39, 0xFF, 0xFF, 0x00000000, PPC_NONE, PPC2_ISA205),
7091 /* handles stfdp, lxv, stxsd, stxssp, stxv */
7092 GEN_HANDLER_E(dform3D, 0x3D, 0xFF, 0xFF, 0x00000000, PPC_NONE, PPC2_ISA205),
7093 GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
7094 GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
7095 GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_STRING),
7096 GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_STRING),
7097 GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_STRING),
7098 GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_STRING),
7099 GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x01FFF801, PPC_MEM_EIEIO),
7100 GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FFF801, PPC_MEM),
7101 GEN_HANDLER_E(lbarx, 0x1F, 0x14, 0x01, 0, PPC_NONE, PPC2_ATOMIC_ISA206),
7102 GEN_HANDLER_E(lharx, 0x1F, 0x14, 0x03, 0, PPC_NONE, PPC2_ATOMIC_ISA206),
7103 GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000000, PPC_RES),
7104 GEN_HANDLER_E(lwat, 0x1F, 0x06, 0x12, 0x00000001, PPC_NONE, PPC2_ISA300),
7105 GEN_HANDLER_E(stwat, 0x1F, 0x06, 0x16, 0x00000001, PPC_NONE, PPC2_ISA300),
7106 GEN_HANDLER_E(stbcx_, 0x1F, 0x16, 0x15, 0, PPC_NONE, PPC2_ATOMIC_ISA206),
7107 GEN_HANDLER_E(sthcx_, 0x1F, 0x16, 0x16, 0, PPC_NONE, PPC2_ATOMIC_ISA206),
7108 GEN_HANDLER2(stwcx_, "stwcx.", 0x1F, 0x16, 0x04, 0x00000000, PPC_RES),
7109 #if defined(TARGET_PPC64)
7110 GEN_HANDLER_E(ldat, 0x1F, 0x06, 0x13, 0x00000001, PPC_NONE, PPC2_ISA300),
7111 GEN_HANDLER_E(stdat, 0x1F, 0x06, 0x17, 0x00000001, PPC_NONE, PPC2_ISA300),
7112 GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000000, PPC_64B),
7113 GEN_HANDLER_E(lqarx, 0x1F, 0x14, 0x08, 0, PPC_NONE, PPC2_LSQ_ISA207),
7114 GEN_HANDLER2(stdcx_, "stdcx.", 0x1F, 0x16, 0x06, 0x00000000, PPC_64B),
7115 GEN_HANDLER_E(stqcx_, 0x1F, 0x16, 0x05, 0, PPC_NONE, PPC2_LSQ_ISA207),
7116 #endif
7117 GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x039FF801, PPC_MEM_SYNC),
7118 GEN_HANDLER(wait, 0x1F, 0x1E, 0x01, 0x03FFF801, PPC_WAIT),
7119 GEN_HANDLER_E(wait, 0x1F, 0x1E, 0x00, 0x039FF801, PPC_NONE, PPC2_ISA300),
7120 GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
7121 GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
7122 GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW),
7123 GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW),
7124 GEN_HANDLER_E(bctar, 0x13, 0x10, 0x11, 0x0000E000, PPC_NONE, PPC2_BCTAR_ISA207),
7125 GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER),
7126 GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW),
7127 #if defined(TARGET_PPC64)
7128 GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B),
7129 #if !defined(CONFIG_USER_ONLY)
7130 /* Top bit of opc2 corresponds with low bit of LEV, so use two handlers */
7131 GEN_HANDLER_E(scv, 0x11, 0x10, 0xFF, 0x03FFF01E, PPC_NONE, PPC2_ISA300),
7132 GEN_HANDLER_E(scv, 0x11, 0x00, 0xFF, 0x03FFF01E, PPC_NONE, PPC2_ISA300),
7133 GEN_HANDLER_E(rfscv, 0x13, 0x12, 0x02, 0x03FF8001, PPC_NONE, PPC2_ISA300),
7134 #endif
7135 GEN_HANDLER_E(stop, 0x13, 0x12, 0x0b, 0x03FFF801, PPC_NONE, PPC2_ISA300),
7136 GEN_HANDLER_E(doze, 0x13, 0x12, 0x0c, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
7137 GEN_HANDLER_E(nap, 0x13, 0x12, 0x0d, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
7138 GEN_HANDLER_E(sleep, 0x13, 0x12, 0x0e, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
7139 GEN_HANDLER_E(rvwinkle, 0x13, 0x12, 0x0f, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
7140 GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64H),
7141 #endif
7142 /* Top bit of opc2 corresponds with low bit of LEV, so use two handlers */
7143 GEN_HANDLER(sc, 0x11, 0x11, 0xFF, 0x03FFF01D, PPC_FLOW),
7144 GEN_HANDLER(sc, 0x11, 0x01, 0xFF, 0x03FFF01D, PPC_FLOW),
7145 GEN_HANDLER(tw, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW),
7146 GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
7147 #if defined(TARGET_PPC64)
7148 GEN_HANDLER(td, 0x1F, 0x04, 0x02, 0x00000001, PPC_64B),
7149 GEN_HANDLER(tdi, 0x02, 0xFF, 0xFF, 0x00000000, PPC_64B),
7150 #endif
7151 GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC),
7152 GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC),
7153 GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC),
7154 GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC),
7155 GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MFTB),
7156 GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC),
7157 #if defined(TARGET_PPC64)
7158 GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001EF801, PPC_64B),
7159 GEN_HANDLER_E(setb, 0x1F, 0x00, 0x04, 0x0003F801, PPC_NONE, PPC2_ISA300),
7160 GEN_HANDLER_E(mcrxrx, 0x1F, 0x00, 0x12, 0x007FF801, PPC_NONE, PPC2_ISA300),
7161 #endif
7162 GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001EF801, PPC_MISC),
7163 GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000000, PPC_MISC),
7164 GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03C00001, PPC_CACHE),
7165 GEN_HANDLER_E(dcbfep, 0x1F, 0x1F, 0x03, 0x03C00001, PPC_NONE, PPC2_BOOKE206),
7166 GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE),
7167 GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE),
7168 GEN_HANDLER_E(dcbstep, 0x1F, 0x1F, 0x01, 0x03E00001, PPC_NONE, PPC2_BOOKE206),
7169 GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x00000001, PPC_CACHE),
7170 GEN_HANDLER_E(dcbtep, 0x1F, 0x1F, 0x09, 0x00000001, PPC_NONE, PPC2_BOOKE206),
7171 GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x00000001, PPC_CACHE),
7172 GEN_HANDLER_E(dcbtstep, 0x1F, 0x1F, 0x07, 0x00000001, PPC_NONE, PPC2_BOOKE206),
7173 GEN_HANDLER_E(dcbtls, 0x1F, 0x06, 0x05, 0x02000001, PPC_BOOKE, PPC2_BOOKE206),
7174 GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZ),
7175 GEN_HANDLER_E(dcbzep, 0x1F, 0x1F, 0x1F, 0x03C00001, PPC_NONE, PPC2_BOOKE206),
7176 GEN_HANDLER(dst, 0x1F, 0x16, 0x0A, 0x01800001, PPC_ALTIVEC),
7177 GEN_HANDLER(dstst, 0x1F, 0x16, 0x0B, 0x01800001, PPC_ALTIVEC),
7178 GEN_HANDLER(dss, 0x1F, 0x16, 0x19, 0x019FF801, PPC_ALTIVEC),
7179 GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE_ICBI),
7180 GEN_HANDLER_E(icbiep, 0x1F, 0x1F, 0x1E, 0x03E00001, PPC_NONE, PPC2_BOOKE206),
7181 GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_DCBA),
7182 GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT),
7183 GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT),
7184 GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT),
7185 GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT),
7186 #if defined(TARGET_PPC64)
7187 GEN_HANDLER2(mfsr_64b, "mfsr", 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT_64B),
7188 GEN_HANDLER2(mfsrin_64b, "mfsrin", 0x1F, 0x13, 0x14, 0x001F0001,
7189              PPC_SEGMENT_64B),
7190 GEN_HANDLER2(mtsr_64b, "mtsr", 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B),
7191 GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001,
7192              PPC_SEGMENT_64B),
7193 GEN_HANDLER2(slbmte, "slbmte", 0x1F, 0x12, 0x0C, 0x001F0001, PPC_SEGMENT_64B),
7194 GEN_HANDLER2(slbmfee, "slbmfee", 0x1F, 0x13, 0x1C, 0x001F0001, PPC_SEGMENT_64B),
7195 GEN_HANDLER2(slbmfev, "slbmfev", 0x1F, 0x13, 0x1A, 0x001F0001, PPC_SEGMENT_64B),
7196 GEN_HANDLER2(slbfee_, "slbfee.", 0x1F, 0x13, 0x1E, 0x001F0000, PPC_SEGMENT_64B),
7197 #endif
7198 GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA),
7199 /*
7200  * XXX Those instructions will need to be handled differently for
7201  * different ISA versions
7202  */
7203 GEN_HANDLER(tlbiel, 0x1F, 0x12, 0x08, 0x001F0001, PPC_MEM_TLBIE),
7204 GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x001F0001, PPC_MEM_TLBIE),
7205 GEN_HANDLER_E(tlbiel, 0x1F, 0x12, 0x08, 0x00100001, PPC_NONE, PPC2_ISA300),
7206 GEN_HANDLER_E(tlbie, 0x1F, 0x12, 0x09, 0x00100001, PPC_NONE, PPC2_ISA300),
7207 GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC),
7208 #if defined(TARGET_PPC64)
7209 GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x031FFC01, PPC_SLBI),
7210 GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI),
7211 GEN_HANDLER_E(slbieg, 0x1F, 0x12, 0x0E, 0x001F0001, PPC_NONE, PPC2_ISA300),
7212 GEN_HANDLER_E(slbsync, 0x1F, 0x12, 0x0A, 0x03FFF801, PPC_NONE, PPC2_ISA300),
7213 #endif
7214 GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN),
7215 GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN),
7216 GEN_HANDLER(abs, 0x1F, 0x08, 0x0B, 0x0000F800, PPC_POWER_BR),
7217 GEN_HANDLER(abso, 0x1F, 0x08, 0x1B, 0x0000F800, PPC_POWER_BR),
7218 GEN_HANDLER(clcs, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR),
7219 GEN_HANDLER(div, 0x1F, 0x0B, 0x0A, 0x00000000, PPC_POWER_BR),
7220 GEN_HANDLER(divo, 0x1F, 0x0B, 0x1A, 0x00000000, PPC_POWER_BR),
7221 GEN_HANDLER(divs, 0x1F, 0x0B, 0x0B, 0x00000000, PPC_POWER_BR),
7222 GEN_HANDLER(divso, 0x1F, 0x0B, 0x1B, 0x00000000, PPC_POWER_BR),
7223 GEN_HANDLER(doz, 0x1F, 0x08, 0x08, 0x00000000, PPC_POWER_BR),
7224 GEN_HANDLER(dozo, 0x1F, 0x08, 0x18, 0x00000000, PPC_POWER_BR),
7225 GEN_HANDLER(dozi, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR),
7226 GEN_HANDLER(lscbx, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR),
7227 GEN_HANDLER(maskg, 0x1F, 0x1D, 0x00, 0x00000000, PPC_POWER_BR),
7228 GEN_HANDLER(maskir, 0x1F, 0x1D, 0x10, 0x00000000, PPC_POWER_BR),
7229 GEN_HANDLER(mul, 0x1F, 0x0B, 0x03, 0x00000000, PPC_POWER_BR),
7230 GEN_HANDLER(mulo, 0x1F, 0x0B, 0x13, 0x00000000, PPC_POWER_BR),
7231 GEN_HANDLER(nabs, 0x1F, 0x08, 0x0F, 0x00000000, PPC_POWER_BR),
7232 GEN_HANDLER(nabso, 0x1F, 0x08, 0x1F, 0x00000000, PPC_POWER_BR),
7233 GEN_HANDLER(rlmi, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR),
7234 GEN_HANDLER(rrib, 0x1F, 0x19, 0x10, 0x00000000, PPC_POWER_BR),
7235 GEN_HANDLER(sle, 0x1F, 0x19, 0x04, 0x00000000, PPC_POWER_BR),
7236 GEN_HANDLER(sleq, 0x1F, 0x19, 0x06, 0x00000000, PPC_POWER_BR),
7237 GEN_HANDLER(sliq, 0x1F, 0x18, 0x05, 0x00000000, PPC_POWER_BR),
7238 GEN_HANDLER(slliq, 0x1F, 0x18, 0x07, 0x00000000, PPC_POWER_BR),
7239 GEN_HANDLER(sllq, 0x1F, 0x18, 0x06, 0x00000000, PPC_POWER_BR),
7240 GEN_HANDLER(slq, 0x1F, 0x18, 0x04, 0x00000000, PPC_POWER_BR),
7241 GEN_HANDLER(sraiq, 0x1F, 0x18, 0x1D, 0x00000000, PPC_POWER_BR),
7242 GEN_HANDLER(sraq, 0x1F, 0x18, 0x1C, 0x00000000, PPC_POWER_BR),
7243 GEN_HANDLER(sre, 0x1F, 0x19, 0x14, 0x00000000, PPC_POWER_BR),
7244 GEN_HANDLER(srea, 0x1F, 0x19, 0x1C, 0x00000000, PPC_POWER_BR),
7245 GEN_HANDLER(sreq, 0x1F, 0x19, 0x16, 0x00000000, PPC_POWER_BR),
7246 GEN_HANDLER(sriq, 0x1F, 0x18, 0x15, 0x00000000, PPC_POWER_BR),
7247 GEN_HANDLER(srliq, 0x1F, 0x18, 0x17, 0x00000000, PPC_POWER_BR),
7248 GEN_HANDLER(srlq, 0x1F, 0x18, 0x16, 0x00000000, PPC_POWER_BR),
7249 GEN_HANDLER(srq, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR),
7250 GEN_HANDLER(dsa, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC),
7251 GEN_HANDLER(esa, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC),
7252 GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC),
7253 GEN_HANDLER2(tlbld_6xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB),
7254 GEN_HANDLER2(tlbli_6xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB),
7255 GEN_HANDLER2(tlbld_74xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_74xx_TLB),
7256 GEN_HANDLER2(tlbli_74xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_74xx_TLB),
7257 GEN_HANDLER(clf, 0x1F, 0x16, 0x03, 0x03E00000, PPC_POWER),
7258 GEN_HANDLER(cli, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER),
7259 GEN_HANDLER(dclst, 0x1F, 0x16, 0x13, 0x03E00000, PPC_POWER),
7260 GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER),
7261 GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER),
7262 GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER),
7263 GEN_HANDLER(lfq, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
7264 GEN_HANDLER(lfqu, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
7265 GEN_HANDLER(lfqux, 0x1F, 0x17, 0x19, 0x00000001, PPC_POWER2),
7266 GEN_HANDLER(lfqx, 0x1F, 0x17, 0x18, 0x00000001, PPC_POWER2),
7267 GEN_HANDLER(stfq, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
7268 GEN_HANDLER(stfqu, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
7269 GEN_HANDLER(stfqux, 0x1F, 0x17, 0x1D, 0x00000001, PPC_POWER2),
7270 GEN_HANDLER(stfqx, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2),
7271 GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_MFAPIDI),
7272 GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_TLBIVA),
7273 GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_DCR),
7274 GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_DCR),
7275 GEN_HANDLER(mfdcrx, 0x1F, 0x03, 0x08, 0x00000000, PPC_DCRX),
7276 GEN_HANDLER(mtdcrx, 0x1F, 0x03, 0x0C, 0x00000000, PPC_DCRX),
7277 GEN_HANDLER(mfdcrux, 0x1F, 0x03, 0x09, 0x00000000, PPC_DCRUX),
7278 GEN_HANDLER(mtdcrux, 0x1F, 0x03, 0x0D, 0x00000000, PPC_DCRUX),
7279 GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON),
7280 GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON),
7281 GEN_HANDLER2(icbt_40x, "icbt", 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_ICBT),
7282 GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON),
7283 GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON),
7284 GEN_HANDLER2(rfci_40x, "rfci", 0x13, 0x13, 0x01, 0x03FF8001, PPC_40x_EXCP),
7285 GEN_HANDLER_E(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE, PPC2_BOOKE206),
7286 GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_RFDI),
7287 GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_RFMCI),
7288 GEN_HANDLER2(tlbre_40x, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB),
7289 GEN_HANDLER2(tlbsx_40x, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB),
7290 GEN_HANDLER2(tlbwe_40x, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB),
7291 GEN_HANDLER2(tlbre_440, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE),
7292 GEN_HANDLER2(tlbsx_440, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE),
7293 GEN_HANDLER2(tlbwe_440, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE),
7294 GEN_HANDLER2_E(tlbre_booke206, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001,
7295                PPC_NONE, PPC2_BOOKE206),
7296 GEN_HANDLER2_E(tlbsx_booke206, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000,
7297                PPC_NONE, PPC2_BOOKE206),
7298 GEN_HANDLER2_E(tlbwe_booke206, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001,
7299                PPC_NONE, PPC2_BOOKE206),
7300 GEN_HANDLER2_E(tlbivax_booke206, "tlbivax", 0x1F, 0x12, 0x18, 0x00000001,
7301                PPC_NONE, PPC2_BOOKE206),
7302 GEN_HANDLER2_E(tlbilx_booke206, "tlbilx", 0x1F, 0x12, 0x00, 0x03800001,
7303                PPC_NONE, PPC2_BOOKE206),
7304 GEN_HANDLER2_E(msgsnd, "msgsnd", 0x1F, 0x0E, 0x06, 0x03ff0001,
7305                PPC_NONE, PPC2_PRCNTL),
7306 GEN_HANDLER2_E(msgclr, "msgclr", 0x1F, 0x0E, 0x07, 0x03ff0001,
7307                PPC_NONE, PPC2_PRCNTL),
7308 GEN_HANDLER2_E(msgsync, "msgsync", 0x1F, 0x16, 0x1B, 0x00000000,
7309                PPC_NONE, PPC2_PRCNTL),
7310 GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE),
7311 GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000E7C01, PPC_WRTEE),
7312 GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC),
7313 GEN_HANDLER_E(mbar, 0x1F, 0x16, 0x1a, 0x001FF801,
7314               PPC_BOOKE, PPC2_BOOKE206),
7315 GEN_HANDLER(msync_4xx, 0x1F, 0x16, 0x12, 0x039FF801, PPC_BOOKE),
7316 GEN_HANDLER2_E(icbt_440, "icbt", 0x1F, 0x16, 0x00, 0x03E00001,
7317                PPC_BOOKE, PPC2_BOOKE206),
7318 GEN_HANDLER2(icbt_440, "icbt", 0x1F, 0x06, 0x08, 0x03E00001,
7319              PPC_440_SPEC),
7320 GEN_HANDLER(lvsl, 0x1f, 0x06, 0x00, 0x00000001, PPC_ALTIVEC),
7321 GEN_HANDLER(lvsr, 0x1f, 0x06, 0x01, 0x00000001, PPC_ALTIVEC),
7322 GEN_HANDLER(mfvscr, 0x04, 0x2, 0x18, 0x001ff800, PPC_ALTIVEC),
7323 GEN_HANDLER(mtvscr, 0x04, 0x2, 0x19, 0x03ff0000, PPC_ALTIVEC),
7324 GEN_HANDLER(vmladduhm, 0x04, 0x11, 0xFF, 0x00000000, PPC_ALTIVEC),
7325 #if defined(TARGET_PPC64)
7326 GEN_HANDLER_E(maddhd_maddhdu, 0x04, 0x18, 0xFF, 0x00000000, PPC_NONE,
7327               PPC2_ISA300),
7328 GEN_HANDLER_E(maddld, 0x04, 0x19, 0xFF, 0x00000000, PPC_NONE, PPC2_ISA300),
7329 GEN_HANDLER2_E(msgsndp, "msgsndp", 0x1F, 0x0E, 0x04, 0x03ff0001,
7330                PPC_NONE, PPC2_ISA207S),
7331 GEN_HANDLER2_E(msgclrp, "msgclrp", 0x1F, 0x0E, 0x05, 0x03ff0001,
7332                PPC_NONE, PPC2_ISA207S),
7333 #endif
7334 
7335 #undef GEN_INT_ARITH_ADD
7336 #undef GEN_INT_ARITH_ADD_CONST
7337 #define GEN_INT_ARITH_ADD(name, opc3, add_ca, compute_ca, compute_ov)         \
7338 GEN_HANDLER(name, 0x1F, 0x0A, opc3, 0x00000000, PPC_INTEGER),
7339 #define GEN_INT_ARITH_ADD_CONST(name, opc3, const_val,                        \
7340                                 add_ca, compute_ca, compute_ov)               \
7341 GEN_HANDLER(name, 0x1F, 0x0A, opc3, 0x0000F800, PPC_INTEGER),
7342 GEN_INT_ARITH_ADD(add, 0x08, 0, 0, 0)
7343 GEN_INT_ARITH_ADD(addo, 0x18, 0, 0, 1)
7344 GEN_INT_ARITH_ADD(addc, 0x00, 0, 1, 0)
7345 GEN_INT_ARITH_ADD(addco, 0x10, 0, 1, 1)
7346 GEN_INT_ARITH_ADD(adde, 0x04, 1, 1, 0)
7347 GEN_INT_ARITH_ADD(addeo, 0x14, 1, 1, 1)
7348 GEN_INT_ARITH_ADD_CONST(addme, 0x07, -1LL, 1, 1, 0)
7349 GEN_INT_ARITH_ADD_CONST(addmeo, 0x17, -1LL, 1, 1, 1)
7350 GEN_HANDLER_E(addex, 0x1F, 0x0A, 0x05, 0x00000000, PPC_NONE, PPC2_ISA300),
7351 GEN_INT_ARITH_ADD_CONST(addze, 0x06, 0, 1, 1, 0)
7352 GEN_INT_ARITH_ADD_CONST(addzeo, 0x16, 0, 1, 1, 1)
7353 
7354 #undef GEN_INT_ARITH_DIVW
7355 #define GEN_INT_ARITH_DIVW(name, opc3, sign, compute_ov)                      \
7356 GEN_HANDLER(name, 0x1F, 0x0B, opc3, 0x00000000, PPC_INTEGER)
7357 GEN_INT_ARITH_DIVW(divwu, 0x0E, 0, 0),
7358 GEN_INT_ARITH_DIVW(divwuo, 0x1E, 0, 1),
7359 GEN_INT_ARITH_DIVW(divw, 0x0F, 1, 0),
7360 GEN_INT_ARITH_DIVW(divwo, 0x1F, 1, 1),
7361 GEN_HANDLER_E(divwe, 0x1F, 0x0B, 0x0D, 0, PPC_NONE, PPC2_DIVE_ISA206),
7362 GEN_HANDLER_E(divweo, 0x1F, 0x0B, 0x1D, 0, PPC_NONE, PPC2_DIVE_ISA206),
7363 GEN_HANDLER_E(divweu, 0x1F, 0x0B, 0x0C, 0, PPC_NONE, PPC2_DIVE_ISA206),
7364 GEN_HANDLER_E(divweuo, 0x1F, 0x0B, 0x1C, 0, PPC_NONE, PPC2_DIVE_ISA206),
7365 GEN_HANDLER_E(modsw, 0x1F, 0x0B, 0x18, 0x00000001, PPC_NONE, PPC2_ISA300),
7366 GEN_HANDLER_E(moduw, 0x1F, 0x0B, 0x08, 0x00000001, PPC_NONE, PPC2_ISA300),
7367 
7368 #if defined(TARGET_PPC64)
7369 #undef GEN_INT_ARITH_DIVD
7370 #define GEN_INT_ARITH_DIVD(name, opc3, sign, compute_ov)                      \
7371 GEN_HANDLER(name, 0x1F, 0x09, opc3, 0x00000000, PPC_64B)
7372 GEN_INT_ARITH_DIVD(divdu, 0x0E, 0, 0),
7373 GEN_INT_ARITH_DIVD(divduo, 0x1E, 0, 1),
7374 GEN_INT_ARITH_DIVD(divd, 0x0F, 1, 0),
7375 GEN_INT_ARITH_DIVD(divdo, 0x1F, 1, 1),
7376 
7377 GEN_HANDLER_E(divdeu, 0x1F, 0x09, 0x0C, 0, PPC_NONE, PPC2_DIVE_ISA206),
7378 GEN_HANDLER_E(divdeuo, 0x1F, 0x09, 0x1C, 0, PPC_NONE, PPC2_DIVE_ISA206),
7379 GEN_HANDLER_E(divde, 0x1F, 0x09, 0x0D, 0, PPC_NONE, PPC2_DIVE_ISA206),
7380 GEN_HANDLER_E(divdeo, 0x1F, 0x09, 0x1D, 0, PPC_NONE, PPC2_DIVE_ISA206),
7381 GEN_HANDLER_E(modsd, 0x1F, 0x09, 0x18, 0x00000001, PPC_NONE, PPC2_ISA300),
7382 GEN_HANDLER_E(modud, 0x1F, 0x09, 0x08, 0x00000001, PPC_NONE, PPC2_ISA300),
7383 
7384 #undef GEN_INT_ARITH_MUL_HELPER
7385 #define GEN_INT_ARITH_MUL_HELPER(name, opc3)                                  \
7386 GEN_HANDLER(name, 0x1F, 0x09, opc3, 0x00000000, PPC_64B)
7387 GEN_INT_ARITH_MUL_HELPER(mulhdu, 0x00),
7388 GEN_INT_ARITH_MUL_HELPER(mulhd, 0x02),
7389 GEN_INT_ARITH_MUL_HELPER(mulldo, 0x17),
7390 #endif
7391 
7392 #undef GEN_INT_ARITH_SUBF
7393 #undef GEN_INT_ARITH_SUBF_CONST
7394 #define GEN_INT_ARITH_SUBF(name, opc3, add_ca, compute_ca, compute_ov)        \
7395 GEN_HANDLER(name, 0x1F, 0x08, opc3, 0x00000000, PPC_INTEGER),
7396 #define GEN_INT_ARITH_SUBF_CONST(name, opc3, const_val,                       \
7397                                 add_ca, compute_ca, compute_ov)               \
7398 GEN_HANDLER(name, 0x1F, 0x08, opc3, 0x0000F800, PPC_INTEGER),
7399 GEN_INT_ARITH_SUBF(subf, 0x01, 0, 0, 0)
7400 GEN_INT_ARITH_SUBF(subfo, 0x11, 0, 0, 1)
7401 GEN_INT_ARITH_SUBF(subfc, 0x00, 0, 1, 0)
7402 GEN_INT_ARITH_SUBF(subfco, 0x10, 0, 1, 1)
7403 GEN_INT_ARITH_SUBF(subfe, 0x04, 1, 1, 0)
7404 GEN_INT_ARITH_SUBF(subfeo, 0x14, 1, 1, 1)
7405 GEN_INT_ARITH_SUBF_CONST(subfme, 0x07, -1LL, 1, 1, 0)
7406 GEN_INT_ARITH_SUBF_CONST(subfmeo, 0x17, -1LL, 1, 1, 1)
7407 GEN_INT_ARITH_SUBF_CONST(subfze, 0x06, 0, 1, 1, 0)
7408 GEN_INT_ARITH_SUBF_CONST(subfzeo, 0x16, 0, 1, 1, 1)
7409 
7410 #undef GEN_LOGICAL1
7411 #undef GEN_LOGICAL2
7412 #define GEN_LOGICAL2(name, tcg_op, opc, type)                                 \
7413 GEN_HANDLER(name, 0x1F, 0x1C, opc, 0x00000000, type)
7414 #define GEN_LOGICAL1(name, tcg_op, opc, type)                                 \
7415 GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, type)
7416 GEN_LOGICAL2(and, tcg_gen_and_tl, 0x00, PPC_INTEGER),
7417 GEN_LOGICAL2(andc, tcg_gen_andc_tl, 0x01, PPC_INTEGER),
7418 GEN_LOGICAL2(eqv, tcg_gen_eqv_tl, 0x08, PPC_INTEGER),
7419 GEN_LOGICAL1(extsb, tcg_gen_ext8s_tl, 0x1D, PPC_INTEGER),
7420 GEN_LOGICAL1(extsh, tcg_gen_ext16s_tl, 0x1C, PPC_INTEGER),
7421 GEN_LOGICAL2(nand, tcg_gen_nand_tl, 0x0E, PPC_INTEGER),
7422 GEN_LOGICAL2(nor, tcg_gen_nor_tl, 0x03, PPC_INTEGER),
7423 GEN_LOGICAL2(orc, tcg_gen_orc_tl, 0x0C, PPC_INTEGER),
7424 #if defined(TARGET_PPC64)
7425 GEN_LOGICAL1(extsw, tcg_gen_ext32s_tl, 0x1E, PPC_64B),
7426 #endif
7427 
7428 #if defined(TARGET_PPC64)
7429 #undef GEN_PPC64_R2
7430 #undef GEN_PPC64_R4
7431 #define GEN_PPC64_R2(name, opc1, opc2)                                        \
7432 GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B),\
7433 GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000,   \
7434              PPC_64B)
7435 #define GEN_PPC64_R4(name, opc1, opc2)                                        \
7436 GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B),\
7437 GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x01, 0xFF, 0x00000000,   \
7438              PPC_64B),                                                        \
7439 GEN_HANDLER2(name##2, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000,   \
7440              PPC_64B),                                                        \
7441 GEN_HANDLER2(name##3, stringify(name), opc1, opc2 | 0x11, 0xFF, 0x00000000,   \
7442              PPC_64B)
7443 GEN_PPC64_R4(rldicl, 0x1E, 0x00),
7444 GEN_PPC64_R4(rldicr, 0x1E, 0x02),
7445 GEN_PPC64_R4(rldic, 0x1E, 0x04),
7446 GEN_PPC64_R2(rldcl, 0x1E, 0x08),
7447 GEN_PPC64_R2(rldcr, 0x1E, 0x09),
7448 GEN_PPC64_R4(rldimi, 0x1E, 0x06),
7449 #endif
7450 
7451 #undef GEN_LD
7452 #undef GEN_LDU
7453 #undef GEN_LDUX
7454 #undef GEN_LDX_E
7455 #undef GEN_LDS
7456 #define GEN_LD(name, ldop, opc, type)                                         \
7457 GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
7458 #define GEN_LDU(name, ldop, opc, type)                                        \
7459 GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
7460 #define GEN_LDUX(name, ldop, opc2, opc3, type)                                \
7461 GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type),
7462 #define GEN_LDX_E(name, ldop, opc2, opc3, type, type2, chk)                   \
7463 GEN_HANDLER_E(name##x, 0x1F, opc2, opc3, 0x00000001, type, type2),
7464 #define GEN_LDS(name, ldop, op, type)                                         \
7465 GEN_LD(name, ldop, op | 0x20, type)                                           \
7466 GEN_LDU(name, ldop, op | 0x21, type)                                          \
7467 GEN_LDUX(name, ldop, 0x17, op | 0x01, type)                                   \
7468 GEN_LDX(name, ldop, 0x17, op | 0x00, type)
7469 
7470 GEN_LDS(lbz, ld8u, 0x02, PPC_INTEGER)
7471 GEN_LDS(lha, ld16s, 0x0A, PPC_INTEGER)
7472 GEN_LDS(lhz, ld16u, 0x08, PPC_INTEGER)
7473 GEN_LDS(lwz, ld32u, 0x00, PPC_INTEGER)
7474 #if defined(TARGET_PPC64)
7475 GEN_LDUX(lwa, ld32s, 0x15, 0x0B, PPC_64B)
7476 GEN_LDX(lwa, ld32s, 0x15, 0x0A, PPC_64B)
7477 GEN_LDUX(ld, ld64_i64, 0x15, 0x01, PPC_64B)
7478 GEN_LDX(ld, ld64_i64, 0x15, 0x00, PPC_64B)
7479 GEN_LDX_E(ldbr, ld64ur_i64, 0x14, 0x10, PPC_NONE, PPC2_DBRX, CHK_NONE)
7480 
7481 /* HV/P7 and later only */
7482 GEN_LDX_HVRM(ldcix, ld64_i64, 0x15, 0x1b, PPC_CILDST)
7483 GEN_LDX_HVRM(lwzcix, ld32u, 0x15, 0x18, PPC_CILDST)
7484 GEN_LDX_HVRM(lhzcix, ld16u, 0x15, 0x19, PPC_CILDST)
7485 GEN_LDX_HVRM(lbzcix, ld8u, 0x15, 0x1a, PPC_CILDST)
7486 #endif
7487 GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER)
7488 GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER)
7489 
7490 /* External PID based load */
7491 #undef GEN_LDEPX
7492 #define GEN_LDEPX(name, ldop, opc2, opc3)                                     \
7493 GEN_HANDLER_E(name##epx, 0x1F, opc2, opc3,                                    \
7494               0x00000001, PPC_NONE, PPC2_BOOKE206),
7495 
7496 GEN_LDEPX(lb, DEF_MEMOP(MO_UB), 0x1F, 0x02)
7497 GEN_LDEPX(lh, DEF_MEMOP(MO_UW), 0x1F, 0x08)
7498 GEN_LDEPX(lw, DEF_MEMOP(MO_UL), 0x1F, 0x00)
7499 #if defined(TARGET_PPC64)
7500 GEN_LDEPX(ld, DEF_MEMOP(MO_Q), 0x1D, 0x00)
7501 #endif
7502 
7503 #undef GEN_ST
7504 #undef GEN_STU
7505 #undef GEN_STUX
7506 #undef GEN_STX_E
7507 #undef GEN_STS
7508 #define GEN_ST(name, stop, opc, type)                                         \
7509 GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
7510 #define GEN_STU(name, stop, opc, type)                                        \
7511 GEN_HANDLER(stop##u, opc, 0xFF, 0xFF, 0x00000000, type),
7512 #define GEN_STUX(name, stop, opc2, opc3, type)                                \
7513 GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type),
7514 #define GEN_STX_E(name, stop, opc2, opc3, type, type2, chk)                   \
7515 GEN_HANDLER_E(name##x, 0x1F, opc2, opc3, 0x00000000, type, type2),
7516 #define GEN_STS(name, stop, op, type)                                         \
7517 GEN_ST(name, stop, op | 0x20, type)                                           \
7518 GEN_STU(name, stop, op | 0x21, type)                                          \
7519 GEN_STUX(name, stop, 0x17, op | 0x01, type)                                   \
7520 GEN_STX(name, stop, 0x17, op | 0x00, type)
7521 
7522 GEN_STS(stb, st8, 0x06, PPC_INTEGER)
7523 GEN_STS(sth, st16, 0x0C, PPC_INTEGER)
7524 GEN_STS(stw, st32, 0x04, PPC_INTEGER)
7525 #if defined(TARGET_PPC64)
7526 GEN_STUX(std, st64_i64, 0x15, 0x05, PPC_64B)
7527 GEN_STX(std, st64_i64, 0x15, 0x04, PPC_64B)
7528 GEN_STX_E(stdbr, st64r_i64, 0x14, 0x14, PPC_NONE, PPC2_DBRX, CHK_NONE)
7529 GEN_STX_HVRM(stdcix, st64_i64, 0x15, 0x1f, PPC_CILDST)
7530 GEN_STX_HVRM(stwcix, st32, 0x15, 0x1c, PPC_CILDST)
7531 GEN_STX_HVRM(sthcix, st16, 0x15, 0x1d, PPC_CILDST)
7532 GEN_STX_HVRM(stbcix, st8, 0x15, 0x1e, PPC_CILDST)
7533 #endif
7534 GEN_STX(sthbr, st16r, 0x16, 0x1C, PPC_INTEGER)
7535 GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER)
7536 
7537 #undef GEN_STEPX
7538 #define GEN_STEPX(name, ldop, opc2, opc3)                                     \
7539 GEN_HANDLER_E(name##epx, 0x1F, opc2, opc3,                                    \
7540               0x00000001, PPC_NONE, PPC2_BOOKE206),
7541 
7542 GEN_STEPX(stb, DEF_MEMOP(MO_UB), 0x1F, 0x06)
7543 GEN_STEPX(sth, DEF_MEMOP(MO_UW), 0x1F, 0x0C)
7544 GEN_STEPX(stw, DEF_MEMOP(MO_UL), 0x1F, 0x04)
7545 #if defined(TARGET_PPC64)
7546 GEN_STEPX(std, DEF_MEMOP(MO_Q), 0x1D, 0x04)
7547 #endif
7548 
7549 #undef GEN_CRLOGIC
7550 #define GEN_CRLOGIC(name, tcg_op, opc)                                        \
7551 GEN_HANDLER(name, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER)
7552 GEN_CRLOGIC(crand, tcg_gen_and_i32, 0x08),
7553 GEN_CRLOGIC(crandc, tcg_gen_andc_i32, 0x04),
7554 GEN_CRLOGIC(creqv, tcg_gen_eqv_i32, 0x09),
7555 GEN_CRLOGIC(crnand, tcg_gen_nand_i32, 0x07),
7556 GEN_CRLOGIC(crnor, tcg_gen_nor_i32, 0x01),
7557 GEN_CRLOGIC(cror, tcg_gen_or_i32, 0x0E),
7558 GEN_CRLOGIC(crorc, tcg_gen_orc_i32, 0x0D),
7559 GEN_CRLOGIC(crxor, tcg_gen_xor_i32, 0x06),
7560 
7561 #undef GEN_MAC_HANDLER
7562 #define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
7563 GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC)
7564 GEN_MAC_HANDLER(macchw, 0x0C, 0x05),
7565 GEN_MAC_HANDLER(macchwo, 0x0C, 0x15),
7566 GEN_MAC_HANDLER(macchws, 0x0C, 0x07),
7567 GEN_MAC_HANDLER(macchwso, 0x0C, 0x17),
7568 GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06),
7569 GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16),
7570 GEN_MAC_HANDLER(macchwu, 0x0C, 0x04),
7571 GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14),
7572 GEN_MAC_HANDLER(machhw, 0x0C, 0x01),
7573 GEN_MAC_HANDLER(machhwo, 0x0C, 0x11),
7574 GEN_MAC_HANDLER(machhws, 0x0C, 0x03),
7575 GEN_MAC_HANDLER(machhwso, 0x0C, 0x13),
7576 GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02),
7577 GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12),
7578 GEN_MAC_HANDLER(machhwu, 0x0C, 0x00),
7579 GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10),
7580 GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D),
7581 GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D),
7582 GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F),
7583 GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F),
7584 GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C),
7585 GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C),
7586 GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E),
7587 GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E),
7588 GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05),
7589 GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15),
7590 GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07),
7591 GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17),
7592 GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01),
7593 GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11),
7594 GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03),
7595 GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13),
7596 GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D),
7597 GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D),
7598 GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F),
7599 GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F),
7600 GEN_MAC_HANDLER(mulchw, 0x08, 0x05),
7601 GEN_MAC_HANDLER(mulchwu, 0x08, 0x04),
7602 GEN_MAC_HANDLER(mulhhw, 0x08, 0x01),
7603 GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00),
7604 GEN_MAC_HANDLER(mullhw, 0x08, 0x0D),
7605 GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C),
7606 
7607 GEN_HANDLER2_E(tbegin, "tbegin", 0x1F, 0x0E, 0x14, 0x01DFF800, \
7608                PPC_NONE, PPC2_TM),
7609 GEN_HANDLER2_E(tend,   "tend",   0x1F, 0x0E, 0x15, 0x01FFF800, \
7610                PPC_NONE, PPC2_TM),
7611 GEN_HANDLER2_E(tabort, "tabort", 0x1F, 0x0E, 0x1C, 0x03E0F800, \
7612                PPC_NONE, PPC2_TM),
7613 GEN_HANDLER2_E(tabortwc, "tabortwc", 0x1F, 0x0E, 0x18, 0x00000000, \
7614                PPC_NONE, PPC2_TM),
7615 GEN_HANDLER2_E(tabortwci, "tabortwci", 0x1F, 0x0E, 0x1A, 0x00000000, \
7616                PPC_NONE, PPC2_TM),
7617 GEN_HANDLER2_E(tabortdc, "tabortdc", 0x1F, 0x0E, 0x19, 0x00000000, \
7618                PPC_NONE, PPC2_TM),
7619 GEN_HANDLER2_E(tabortdci, "tabortdci", 0x1F, 0x0E, 0x1B, 0x00000000, \
7620                PPC_NONE, PPC2_TM),
7621 GEN_HANDLER2_E(tsr, "tsr", 0x1F, 0x0E, 0x17, 0x03DFF800, \
7622                PPC_NONE, PPC2_TM),
7623 GEN_HANDLER2_E(tcheck, "tcheck", 0x1F, 0x0E, 0x16, 0x007FF800, \
7624                PPC_NONE, PPC2_TM),
7625 GEN_HANDLER2_E(treclaim, "treclaim", 0x1F, 0x0E, 0x1D, 0x03E0F800, \
7626                PPC_NONE, PPC2_TM),
7627 GEN_HANDLER2_E(trechkpt, "trechkpt", 0x1F, 0x0E, 0x1F, 0x03FFF800, \
7628                PPC_NONE, PPC2_TM),
7629 
7630 #include "translate/fp-ops.c.inc"
7631 
7632 #include "translate/vmx-ops.c.inc"
7633 
7634 #include "translate/vsx-ops.c.inc"
7635 
7636 #include "translate/dfp-ops.c.inc"
7637 
7638 #include "translate/spe-ops.c.inc"
7639 };
7640 
7641 #include "helper_regs.h"
7642 #include "translate_init.c.inc"
7643 
7644 /*****************************************************************************/
7645 /* Misc PowerPC helpers */
ppc_cpu_dump_state(CPUState * cs,FILE * f,int flags)7646 void ppc_cpu_dump_state(CPUState *cs, FILE *f, int flags)
7647 {
7648 #define RGPL  4
7649 #define RFPL  4
7650 
7651     PowerPCCPU *cpu = POWERPC_CPU(cs);
7652     CPUPPCState *env = &cpu->env;
7653     int i;
7654 
7655     qemu_fprintf(f, "NIP " TARGET_FMT_lx "   LR " TARGET_FMT_lx " CTR "
7656                  TARGET_FMT_lx " XER " TARGET_FMT_lx " CPU#%d\n",
7657                  env->nip, env->lr, env->ctr, cpu_read_xer(env),
7658                  cs->cpu_index);
7659     qemu_fprintf(f, "MSR " TARGET_FMT_lx " HID0 " TARGET_FMT_lx "  HF "
7660                  TARGET_FMT_lx " iidx %d didx %d\n",
7661                  env->msr, env->spr[SPR_HID0],
7662                  env->hflags, env->immu_idx, env->dmmu_idx);
7663 #if !defined(NO_TIMER_DUMP)
7664     qemu_fprintf(f, "TB %08" PRIu32 " %08" PRIu64
7665 #if !defined(CONFIG_USER_ONLY)
7666                  " DECR " TARGET_FMT_lu
7667 #endif
7668                  "\n",
7669                  cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
7670 #if !defined(CONFIG_USER_ONLY)
7671                  , cpu_ppc_load_decr(env)
7672 #endif
7673         );
7674 #endif
7675     for (i = 0; i < 32; i++) {
7676         if ((i & (RGPL - 1)) == 0) {
7677             qemu_fprintf(f, "GPR%02d", i);
7678         }
7679         qemu_fprintf(f, " %016" PRIx64, ppc_dump_gpr(env, i));
7680         if ((i & (RGPL - 1)) == (RGPL - 1)) {
7681             qemu_fprintf(f, "\n");
7682         }
7683     }
7684     qemu_fprintf(f, "CR ");
7685     for (i = 0; i < 8; i++)
7686         qemu_fprintf(f, "%01x", env->crf[i]);
7687     qemu_fprintf(f, "  [");
7688     for (i = 0; i < 8; i++) {
7689         char a = '-';
7690         if (env->crf[i] & 0x08) {
7691             a = 'L';
7692         } else if (env->crf[i] & 0x04) {
7693             a = 'G';
7694         } else if (env->crf[i] & 0x02) {
7695             a = 'E';
7696         }
7697         qemu_fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
7698     }
7699     qemu_fprintf(f, " ]             RES " TARGET_FMT_lx "\n",
7700                  env->reserve_addr);
7701 
7702     if (flags & CPU_DUMP_FPU) {
7703         for (i = 0; i < 32; i++) {
7704             if ((i & (RFPL - 1)) == 0) {
7705                 qemu_fprintf(f, "FPR%02d", i);
7706             }
7707             qemu_fprintf(f, " %016" PRIx64, *cpu_fpr_ptr(env, i));
7708             if ((i & (RFPL - 1)) == (RFPL - 1)) {
7709                 qemu_fprintf(f, "\n");
7710             }
7711         }
7712         qemu_fprintf(f, "FPSCR " TARGET_FMT_lx "\n", env->fpscr);
7713     }
7714 
7715 #if !defined(CONFIG_USER_ONLY)
7716     qemu_fprintf(f, " SRR0 " TARGET_FMT_lx "  SRR1 " TARGET_FMT_lx
7717                  "    PVR " TARGET_FMT_lx " VRSAVE " TARGET_FMT_lx "\n",
7718                  env->spr[SPR_SRR0], env->spr[SPR_SRR1],
7719                  env->spr[SPR_PVR], env->spr[SPR_VRSAVE]);
7720 
7721     qemu_fprintf(f, "SPRG0 " TARGET_FMT_lx " SPRG1 " TARGET_FMT_lx
7722                  "  SPRG2 " TARGET_FMT_lx "  SPRG3 " TARGET_FMT_lx "\n",
7723                  env->spr[SPR_SPRG0], env->spr[SPR_SPRG1],
7724                  env->spr[SPR_SPRG2], env->spr[SPR_SPRG3]);
7725 
7726     qemu_fprintf(f, "SPRG4 " TARGET_FMT_lx " SPRG5 " TARGET_FMT_lx
7727                  "  SPRG6 " TARGET_FMT_lx "  SPRG7 " TARGET_FMT_lx "\n",
7728                  env->spr[SPR_SPRG4], env->spr[SPR_SPRG5],
7729                  env->spr[SPR_SPRG6], env->spr[SPR_SPRG7]);
7730 
7731 #if defined(TARGET_PPC64)
7732     if (env->excp_model == POWERPC_EXCP_POWER7 ||
7733         env->excp_model == POWERPC_EXCP_POWER8 ||
7734         env->excp_model == POWERPC_EXCP_POWER9)  {
7735         qemu_fprintf(f, "HSRR0 " TARGET_FMT_lx " HSRR1 " TARGET_FMT_lx "\n",
7736                      env->spr[SPR_HSRR0], env->spr[SPR_HSRR1]);
7737     }
7738 #endif
7739     if (env->excp_model == POWERPC_EXCP_BOOKE) {
7740         qemu_fprintf(f, "CSRR0 " TARGET_FMT_lx " CSRR1 " TARGET_FMT_lx
7741                      " MCSRR0 " TARGET_FMT_lx " MCSRR1 " TARGET_FMT_lx "\n",
7742                      env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1],
7743                      env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1]);
7744 
7745         qemu_fprintf(f, "  TCR " TARGET_FMT_lx "   TSR " TARGET_FMT_lx
7746                      "    ESR " TARGET_FMT_lx "   DEAR " TARGET_FMT_lx "\n",
7747                      env->spr[SPR_BOOKE_TCR], env->spr[SPR_BOOKE_TSR],
7748                      env->spr[SPR_BOOKE_ESR], env->spr[SPR_BOOKE_DEAR]);
7749 
7750         qemu_fprintf(f, "  PIR " TARGET_FMT_lx " DECAR " TARGET_FMT_lx
7751                      "   IVPR " TARGET_FMT_lx "   EPCR " TARGET_FMT_lx "\n",
7752                      env->spr[SPR_BOOKE_PIR], env->spr[SPR_BOOKE_DECAR],
7753                      env->spr[SPR_BOOKE_IVPR], env->spr[SPR_BOOKE_EPCR]);
7754 
7755         qemu_fprintf(f, " MCSR " TARGET_FMT_lx " SPRG8 " TARGET_FMT_lx
7756                      "    EPR " TARGET_FMT_lx "\n",
7757                      env->spr[SPR_BOOKE_MCSR], env->spr[SPR_BOOKE_SPRG8],
7758                      env->spr[SPR_BOOKE_EPR]);
7759 
7760         /* FSL-specific */
7761         qemu_fprintf(f, " MCAR " TARGET_FMT_lx "  PID1 " TARGET_FMT_lx
7762                      "   PID2 " TARGET_FMT_lx "    SVR " TARGET_FMT_lx "\n",
7763                      env->spr[SPR_Exxx_MCAR], env->spr[SPR_BOOKE_PID1],
7764                      env->spr[SPR_BOOKE_PID2], env->spr[SPR_E500_SVR]);
7765 
7766         /*
7767          * IVORs are left out as they are large and do not change often --
7768          * they can be read with "p $ivor0", "p $ivor1", etc.
7769          */
7770     }
7771 
7772 #if defined(TARGET_PPC64)
7773     if (env->flags & POWERPC_FLAG_CFAR) {
7774         qemu_fprintf(f, " CFAR " TARGET_FMT_lx"\n", env->cfar);
7775     }
7776 #endif
7777 
7778     if (env->spr_cb[SPR_LPCR].name) {
7779         qemu_fprintf(f, " LPCR " TARGET_FMT_lx "\n", env->spr[SPR_LPCR]);
7780     }
7781 
7782     switch (env->mmu_model) {
7783     case POWERPC_MMU_32B:
7784     case POWERPC_MMU_601:
7785     case POWERPC_MMU_SOFT_6xx:
7786     case POWERPC_MMU_SOFT_74xx:
7787 #if defined(TARGET_PPC64)
7788     case POWERPC_MMU_64B:
7789     case POWERPC_MMU_2_03:
7790     case POWERPC_MMU_2_06:
7791     case POWERPC_MMU_2_07:
7792     case POWERPC_MMU_3_00:
7793 #endif
7794         if (env->spr_cb[SPR_SDR1].name) { /* SDR1 Exists */
7795             qemu_fprintf(f, " SDR1 " TARGET_FMT_lx " ", env->spr[SPR_SDR1]);
7796         }
7797         if (env->spr_cb[SPR_PTCR].name) { /* PTCR Exists */
7798             qemu_fprintf(f, " PTCR " TARGET_FMT_lx " ", env->spr[SPR_PTCR]);
7799         }
7800         qemu_fprintf(f, "  DAR " TARGET_FMT_lx "  DSISR " TARGET_FMT_lx "\n",
7801                      env->spr[SPR_DAR], env->spr[SPR_DSISR]);
7802         break;
7803     case POWERPC_MMU_BOOKE206:
7804         qemu_fprintf(f, " MAS0 " TARGET_FMT_lx "  MAS1 " TARGET_FMT_lx
7805                      "   MAS2 " TARGET_FMT_lx "   MAS3 " TARGET_FMT_lx "\n",
7806                      env->spr[SPR_BOOKE_MAS0], env->spr[SPR_BOOKE_MAS1],
7807                      env->spr[SPR_BOOKE_MAS2], env->spr[SPR_BOOKE_MAS3]);
7808 
7809         qemu_fprintf(f, " MAS4 " TARGET_FMT_lx "  MAS6 " TARGET_FMT_lx
7810                      "   MAS7 " TARGET_FMT_lx "    PID " TARGET_FMT_lx "\n",
7811                      env->spr[SPR_BOOKE_MAS4], env->spr[SPR_BOOKE_MAS6],
7812                      env->spr[SPR_BOOKE_MAS7], env->spr[SPR_BOOKE_PID]);
7813 
7814         qemu_fprintf(f, "MMUCFG " TARGET_FMT_lx " TLB0CFG " TARGET_FMT_lx
7815                      " TLB1CFG " TARGET_FMT_lx "\n",
7816                      env->spr[SPR_MMUCFG], env->spr[SPR_BOOKE_TLB0CFG],
7817                      env->spr[SPR_BOOKE_TLB1CFG]);
7818         break;
7819     default:
7820         break;
7821     }
7822 #endif
7823 
7824 #undef RGPL
7825 #undef RFPL
7826 }
7827 
ppc_cpu_dump_statistics(CPUState * cs,int flags)7828 void ppc_cpu_dump_statistics(CPUState *cs, int flags)
7829 {
7830 #if defined(DO_PPC_STATISTICS)
7831     PowerPCCPU *cpu = POWERPC_CPU(cs);
7832     opc_handler_t **t1, **t2, **t3, *handler;
7833     int op1, op2, op3;
7834 
7835     t1 = cpu->env.opcodes;
7836     for (op1 = 0; op1 < 64; op1++) {
7837         handler = t1[op1];
7838         if (is_indirect_opcode(handler)) {
7839             t2 = ind_table(handler);
7840             for (op2 = 0; op2 < 32; op2++) {
7841                 handler = t2[op2];
7842                 if (is_indirect_opcode(handler)) {
7843                     t3 = ind_table(handler);
7844                     for (op3 = 0; op3 < 32; op3++) {
7845                         handler = t3[op3];
7846                         if (handler->count == 0) {
7847                             continue;
7848                         }
7849                         qemu_printf("%02x %02x %02x (%02x %04d) %16s: "
7850                                     "%016" PRIx64 " %" PRId64 "\n",
7851                                     op1, op2, op3, op1, (op3 << 5) | op2,
7852                                     handler->oname,
7853                                     handler->count, handler->count);
7854                     }
7855                 } else {
7856                     if (handler->count == 0) {
7857                         continue;
7858                     }
7859                     qemu_printf("%02x %02x    (%02x %04d) %16s: "
7860                                 "%016" PRIx64 " %" PRId64 "\n",
7861                                 op1, op2, op1, op2, handler->oname,
7862                                 handler->count, handler->count);
7863                 }
7864             }
7865         } else {
7866             if (handler->count == 0) {
7867                 continue;
7868             }
7869             qemu_printf("%02x       (%02x     ) %16s: %016" PRIx64
7870                         " %" PRId64 "\n",
7871                         op1, op1, handler->oname,
7872                         handler->count, handler->count);
7873         }
7874     }
7875 #endif
7876 }
7877 
ppc_tr_init_disas_context(DisasContextBase * dcbase,CPUState * cs)7878 static void ppc_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
7879 {
7880     DisasContext *ctx = container_of(dcbase, DisasContext, base);
7881     CPUPPCState *env = cs->env_ptr;
7882     int bound;
7883 
7884     ctx->exception = POWERPC_EXCP_NONE;
7885     ctx->spr_cb = env->spr_cb;
7886     ctx->pr = msr_pr;
7887     ctx->mem_idx = env->dmmu_idx;
7888     ctx->dr = msr_dr;
7889 #if !defined(CONFIG_USER_ONLY)
7890     ctx->hv = msr_hv || !env->has_hv_mode;
7891 #endif
7892     ctx->insns_flags = env->insns_flags;
7893     ctx->insns_flags2 = env->insns_flags2;
7894     ctx->access_type = -1;
7895     ctx->need_access_type = !(env->mmu_model & POWERPC_MMU_64B);
7896     ctx->le_mode = !!(env->hflags & (1 << MSR_LE));
7897     ctx->default_tcg_memop_mask = ctx->le_mode ? MO_LE : MO_BE;
7898     ctx->flags = env->flags;
7899 #if defined(TARGET_PPC64)
7900     ctx->sf_mode = msr_is_64bit(env, env->msr);
7901     ctx->has_cfar = !!(env->flags & POWERPC_FLAG_CFAR);
7902 #endif
7903     ctx->lazy_tlb_flush = env->mmu_model == POWERPC_MMU_32B
7904         || env->mmu_model == POWERPC_MMU_601
7905         || (env->mmu_model & POWERPC_MMU_64B);
7906 
7907     ctx->fpu_enabled = !!msr_fp;
7908     if ((env->flags & POWERPC_FLAG_SPE) && msr_spe) {
7909         ctx->spe_enabled = !!msr_spe;
7910     } else {
7911         ctx->spe_enabled = false;
7912     }
7913     if ((env->flags & POWERPC_FLAG_VRE) && msr_vr) {
7914         ctx->altivec_enabled = !!msr_vr;
7915     } else {
7916         ctx->altivec_enabled = false;
7917     }
7918     if ((env->flags & POWERPC_FLAG_VSX) && msr_vsx) {
7919         ctx->vsx_enabled = !!msr_vsx;
7920     } else {
7921         ctx->vsx_enabled = false;
7922     }
7923     if ((env->flags & POWERPC_FLAG_SCV)
7924         && (env->spr[SPR_FSCR] & (1ull << FSCR_SCV))) {
7925         ctx->scv_enabled = true;
7926     } else {
7927         ctx->scv_enabled = false;
7928     }
7929 #if defined(TARGET_PPC64)
7930     if ((env->flags & POWERPC_FLAG_TM) && msr_tm) {
7931         ctx->tm_enabled = !!msr_tm;
7932     } else {
7933         ctx->tm_enabled = false;
7934     }
7935 #endif
7936     ctx->gtse = !!(env->spr[SPR_LPCR] & LPCR_GTSE);
7937     if ((env->flags & POWERPC_FLAG_SE) && msr_se) {
7938         ctx->singlestep_enabled = CPU_SINGLE_STEP;
7939     } else {
7940         ctx->singlestep_enabled = 0;
7941     }
7942     if ((env->flags & POWERPC_FLAG_BE) && msr_be) {
7943         ctx->singlestep_enabled |= CPU_BRANCH_STEP;
7944     }
7945     if ((env->flags & POWERPC_FLAG_DE) && msr_de) {
7946         ctx->singlestep_enabled = 0;
7947         target_ulong dbcr0 = env->spr[SPR_BOOKE_DBCR0];
7948         if (dbcr0 & DBCR0_ICMP) {
7949             ctx->singlestep_enabled |= CPU_SINGLE_STEP;
7950         }
7951         if (dbcr0 & DBCR0_BRT) {
7952             ctx->singlestep_enabled |= CPU_BRANCH_STEP;
7953         }
7954 
7955     }
7956     if (unlikely(ctx->base.singlestep_enabled)) {
7957         ctx->singlestep_enabled |= GDBSTUB_SINGLE_STEP;
7958     }
7959 #if defined(DO_SINGLE_STEP) && 0
7960     /* Single step trace mode */
7961     msr_se = 1;
7962 #endif
7963 
7964     bound = -(ctx->base.pc_first | TARGET_PAGE_MASK) / 4;
7965     ctx->base.max_insns = MIN(ctx->base.max_insns, bound);
7966 }
7967 
ppc_tr_tb_start(DisasContextBase * db,CPUState * cs)7968 static void ppc_tr_tb_start(DisasContextBase *db, CPUState *cs)
7969 {
7970 }
7971 
ppc_tr_insn_start(DisasContextBase * dcbase,CPUState * cs)7972 static void ppc_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
7973 {
7974     tcg_gen_insn_start(dcbase->pc_next);
7975 }
7976 
ppc_tr_breakpoint_check(DisasContextBase * dcbase,CPUState * cs,const CPUBreakpoint * bp)7977 static bool ppc_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
7978                                     const CPUBreakpoint *bp)
7979 {
7980     DisasContext *ctx = container_of(dcbase, DisasContext, base);
7981 
7982     gen_debug_exception(ctx);
7983     dcbase->is_jmp = DISAS_NORETURN;
7984     /*
7985      * The address covered by the breakpoint must be included in
7986      * [tb->pc, tb->pc + tb->size) in order to for it to be properly
7987      * cleared -- thus we increment the PC here so that the logic
7988      * setting tb->size below does the right thing.
7989      */
7990     ctx->base.pc_next += 4;
7991     return true;
7992 }
7993 
ppc_tr_translate_insn(DisasContextBase * dcbase,CPUState * cs)7994 static void ppc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
7995 {
7996     DisasContext *ctx = container_of(dcbase, DisasContext, base);
7997     PowerPCCPU *cpu = POWERPC_CPU(cs);
7998     CPUPPCState *env = cs->env_ptr;
7999     opc_handler_t **table, *handler;
8000 
8001     LOG_DISAS("----------------\n");
8002     LOG_DISAS("nip=" TARGET_FMT_lx " super=%d ir=%d\n",
8003               ctx->base.pc_next, ctx->mem_idx, (int)msr_ir);
8004 
8005     ctx->opcode = translator_ldl_swap(env, ctx->base.pc_next,
8006                                       need_byteswap(ctx));
8007 
8008     LOG_DISAS("translate opcode %08x (%02x %02x %02x %02x) (%s)\n",
8009               ctx->opcode, opc1(ctx->opcode), opc2(ctx->opcode),
8010               opc3(ctx->opcode), opc4(ctx->opcode),
8011               ctx->le_mode ? "little" : "big");
8012     ctx->base.pc_next += 4;
8013     table = cpu->opcodes;
8014     handler = table[opc1(ctx->opcode)];
8015     if (is_indirect_opcode(handler)) {
8016         table = ind_table(handler);
8017         handler = table[opc2(ctx->opcode)];
8018         if (is_indirect_opcode(handler)) {
8019             table = ind_table(handler);
8020             handler = table[opc3(ctx->opcode)];
8021             if (is_indirect_opcode(handler)) {
8022                 table = ind_table(handler);
8023                 handler = table[opc4(ctx->opcode)];
8024             }
8025         }
8026     }
8027     /* Is opcode *REALLY* valid ? */
8028     if (unlikely(handler->handler == &gen_invalid)) {
8029         qemu_log_mask(LOG_GUEST_ERROR, "invalid/unsupported opcode: "
8030                       "%02x - %02x - %02x - %02x (%08x) "
8031                       TARGET_FMT_lx " %d\n",
8032                       opc1(ctx->opcode), opc2(ctx->opcode),
8033                       opc3(ctx->opcode), opc4(ctx->opcode),
8034                       ctx->opcode, ctx->base.pc_next - 4, (int)msr_ir);
8035     } else {
8036         uint32_t inval;
8037 
8038         if (unlikely(handler->type & (PPC_SPE | PPC_SPE_SINGLE | PPC_SPE_DOUBLE)
8039                      && Rc(ctx->opcode))) {
8040             inval = handler->inval2;
8041         } else {
8042             inval = handler->inval1;
8043         }
8044 
8045         if (unlikely((ctx->opcode & inval) != 0)) {
8046             qemu_log_mask(LOG_GUEST_ERROR, "invalid bits: %08x for opcode: "
8047                           "%02x - %02x - %02x - %02x (%08x) "
8048                           TARGET_FMT_lx "\n", ctx->opcode & inval,
8049                           opc1(ctx->opcode), opc2(ctx->opcode),
8050                           opc3(ctx->opcode), opc4(ctx->opcode),
8051                           ctx->opcode, ctx->base.pc_next - 4);
8052             gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
8053             ctx->base.is_jmp = DISAS_NORETURN;
8054             return;
8055         }
8056     }
8057     (*(handler->handler))(ctx);
8058 #if defined(DO_PPC_STATISTICS)
8059     handler->count++;
8060 #endif
8061     /* Check trace mode exceptions */
8062     if (unlikely(ctx->singlestep_enabled & CPU_SINGLE_STEP &&
8063                  (ctx->base.pc_next <= 0x100 || ctx->base.pc_next > 0xF00) &&
8064                  ctx->exception != POWERPC_SYSCALL &&
8065                  ctx->exception != POWERPC_EXCP_TRAP &&
8066                  ctx->exception != POWERPC_EXCP_BRANCH)) {
8067         uint32_t excp = gen_prep_dbgex(ctx);
8068         gen_exception_nip(ctx, excp, ctx->base.pc_next);
8069     }
8070 
8071     if (tcg_check_temp_count()) {
8072         qemu_log("Opcode %02x %02x %02x %02x (%08x) leaked "
8073                  "temporaries\n", opc1(ctx->opcode), opc2(ctx->opcode),
8074                  opc3(ctx->opcode), opc4(ctx->opcode), ctx->opcode);
8075     }
8076 
8077     ctx->base.is_jmp = ctx->exception == POWERPC_EXCP_NONE ?
8078         DISAS_NEXT : DISAS_NORETURN;
8079 }
8080 
ppc_tr_tb_stop(DisasContextBase * dcbase,CPUState * cs)8081 static void ppc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
8082 {
8083     DisasContext *ctx = container_of(dcbase, DisasContext, base);
8084 
8085     if (ctx->exception == POWERPC_EXCP_NONE) {
8086         gen_goto_tb(ctx, 0, ctx->base.pc_next);
8087     } else if (ctx->exception != POWERPC_EXCP_BRANCH) {
8088         if (unlikely(ctx->base.singlestep_enabled)) {
8089             gen_debug_exception(ctx);
8090         }
8091         /* Generate the return instruction */
8092         tcg_gen_exit_tb(NULL, 0);
8093     }
8094 }
8095 
ppc_tr_disas_log(const DisasContextBase * dcbase,CPUState * cs)8096 static void ppc_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
8097 {
8098     qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
8099     log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
8100 }
8101 
8102 static const TranslatorOps ppc_tr_ops = {
8103     .init_disas_context = ppc_tr_init_disas_context,
8104     .tb_start           = ppc_tr_tb_start,
8105     .insn_start         = ppc_tr_insn_start,
8106     .breakpoint_check   = ppc_tr_breakpoint_check,
8107     .translate_insn     = ppc_tr_translate_insn,
8108     .tb_stop            = ppc_tr_tb_stop,
8109     .disas_log          = ppc_tr_disas_log,
8110 };
8111 
gen_intermediate_code(CPUState * cs,TranslationBlock * tb,int max_insns)8112 void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
8113 {
8114     DisasContext ctx;
8115 
8116     translator_loop(&ppc_tr_ops, &ctx.base, cs, tb, max_insns);
8117 }
8118 
restore_state_to_opc(CPUPPCState * env,TranslationBlock * tb,target_ulong * data)8119 void restore_state_to_opc(CPUPPCState *env, TranslationBlock *tb,
8120                           target_ulong *data)
8121 {
8122     env->nip = data[0];
8123 }
8124