1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#include "qemu/osdep.h"
22#include "cpu.h"
23#include "disas/disas.h"
24#include "exec/exec-all.h"
25#include "tcg-op.h"
26#include "qemu/host-utils.h"
27#include "exec/cpu_ldst.h"
28
29#include "exec/helper-proto.h"
30#include "exec/helper-gen.h"
31
32#include "trace-tcg.h"
33#include "exec/log.h"
34
35
36#define CPU_SINGLE_STEP 0x1
37#define CPU_BRANCH_STEP 0x2
38#define GDBSTUB_SINGLE_STEP 0x4
39
40
41
42
43
44#ifdef PPC_DEBUG_DISAS
45# define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
46#else
47# define LOG_DISAS(...) do { } while (0)
48#endif
49
50
51
52
53static TCGv_env cpu_env;
54static char cpu_reg_names[10*3 + 22*4
55 + 10*4 + 22*5
56 + 10*4 + 22*5
57 + 2*(10*6 + 22*7)
58 + 10*5 + 22*6
59 + 8*5 ];
60static TCGv cpu_gpr[32];
61static TCGv cpu_gprh[32];
62static TCGv_i64 cpu_fpr[32];
63static TCGv_i64 cpu_avrh[32], cpu_avrl[32];
64static TCGv_i64 cpu_vsr[32];
65static TCGv_i32 cpu_crf[8];
66static TCGv cpu_nip;
67static TCGv cpu_msr;
68static TCGv cpu_ctr;
69static TCGv cpu_lr;
70#if defined(TARGET_PPC64)
71static TCGv cpu_cfar;
72#endif
73static TCGv cpu_xer, cpu_so, cpu_ov, cpu_ca;
74static TCGv cpu_reserve;
75static TCGv cpu_fpscr;
76static TCGv_i32 cpu_access_type;
77
78#include "exec/gen-icount.h"
79
80void ppc_translate_init(void)
81{
82 int i;
83 char* p;
84 size_t cpu_reg_names_size;
85 static int done_init = 0;
86
87 if (done_init)
88 return;
89
90 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
91 tcg_ctx.tcg_env = cpu_env;
92
93 p = cpu_reg_names;
94 cpu_reg_names_size = sizeof(cpu_reg_names);
95
96 for (i = 0; i < 8; i++) {
97 snprintf(p, cpu_reg_names_size, "crf%d", i);
98 cpu_crf[i] = tcg_global_mem_new_i32(cpu_env,
99 offsetof(CPUPPCState, crf[i]), p);
100 p += 5;
101 cpu_reg_names_size -= 5;
102 }
103
104 for (i = 0; i < 32; i++) {
105 snprintf(p, cpu_reg_names_size, "r%d", i);
106 cpu_gpr[i] = tcg_global_mem_new(cpu_env,
107 offsetof(CPUPPCState, gpr[i]), p);
108 p += (i < 10) ? 3 : 4;
109 cpu_reg_names_size -= (i < 10) ? 3 : 4;
110 snprintf(p, cpu_reg_names_size, "r%dH", i);
111 cpu_gprh[i] = tcg_global_mem_new(cpu_env,
112 offsetof(CPUPPCState, gprh[i]), p);
113 p += (i < 10) ? 4 : 5;
114 cpu_reg_names_size -= (i < 10) ? 4 : 5;
115
116 snprintf(p, cpu_reg_names_size, "fp%d", i);
117 cpu_fpr[i] = tcg_global_mem_new_i64(cpu_env,
118 offsetof(CPUPPCState, fpr[i]), p);
119 p += (i < 10) ? 4 : 5;
120 cpu_reg_names_size -= (i < 10) ? 4 : 5;
121
122 snprintf(p, cpu_reg_names_size, "avr%dH", i);
123#ifdef HOST_WORDS_BIGENDIAN
124 cpu_avrh[i] = tcg_global_mem_new_i64(cpu_env,
125 offsetof(CPUPPCState, avr[i].u64[0]), p);
126#else
127 cpu_avrh[i] = tcg_global_mem_new_i64(cpu_env,
128 offsetof(CPUPPCState, avr[i].u64[1]), p);
129#endif
130 p += (i < 10) ? 6 : 7;
131 cpu_reg_names_size -= (i < 10) ? 6 : 7;
132
133 snprintf(p, cpu_reg_names_size, "avr%dL", i);
134#ifdef HOST_WORDS_BIGENDIAN
135 cpu_avrl[i] = tcg_global_mem_new_i64(cpu_env,
136 offsetof(CPUPPCState, avr[i].u64[1]), p);
137#else
138 cpu_avrl[i] = tcg_global_mem_new_i64(cpu_env,
139 offsetof(CPUPPCState, avr[i].u64[0]), p);
140#endif
141 p += (i < 10) ? 6 : 7;
142 cpu_reg_names_size -= (i < 10) ? 6 : 7;
143 snprintf(p, cpu_reg_names_size, "vsr%d", i);
144 cpu_vsr[i] = tcg_global_mem_new_i64(cpu_env,
145 offsetof(CPUPPCState, vsr[i]), p);
146 p += (i < 10) ? 5 : 6;
147 cpu_reg_names_size -= (i < 10) ? 5 : 6;
148 }
149
150 cpu_nip = tcg_global_mem_new(cpu_env,
151 offsetof(CPUPPCState, nip), "nip");
152
153 cpu_msr = tcg_global_mem_new(cpu_env,
154 offsetof(CPUPPCState, msr), "msr");
155
156 cpu_ctr = tcg_global_mem_new(cpu_env,
157 offsetof(CPUPPCState, ctr), "ctr");
158
159 cpu_lr = tcg_global_mem_new(cpu_env,
160 offsetof(CPUPPCState, lr), "lr");
161
162#if defined(TARGET_PPC64)
163 cpu_cfar = tcg_global_mem_new(cpu_env,
164 offsetof(CPUPPCState, cfar), "cfar");
165#endif
166
167 cpu_xer = tcg_global_mem_new(cpu_env,
168 offsetof(CPUPPCState, xer), "xer");
169 cpu_so = tcg_global_mem_new(cpu_env,
170 offsetof(CPUPPCState, so), "SO");
171 cpu_ov = tcg_global_mem_new(cpu_env,
172 offsetof(CPUPPCState, ov), "OV");
173 cpu_ca = tcg_global_mem_new(cpu_env,
174 offsetof(CPUPPCState, ca), "CA");
175
176 cpu_reserve = tcg_global_mem_new(cpu_env,
177 offsetof(CPUPPCState, reserve_addr),
178 "reserve_addr");
179
180 cpu_fpscr = tcg_global_mem_new(cpu_env,
181 offsetof(CPUPPCState, fpscr), "fpscr");
182
183 cpu_access_type = tcg_global_mem_new_i32(cpu_env,
184 offsetof(CPUPPCState, access_type), "access_type");
185
186 done_init = 1;
187}
188
189
190struct DisasContext {
191 struct TranslationBlock *tb;
192 target_ulong nip;
193 uint32_t opcode;
194 uint32_t exception;
195
196 bool pr, hv, dr, le_mode;
197 bool lazy_tlb_flush;
198 int mem_idx;
199 int access_type;
200
201 TCGMemOp default_tcg_memop_mask;
202#if defined(TARGET_PPC64)
203 bool sf_mode;
204 bool has_cfar;
205#endif
206 bool fpu_enabled;
207 bool altivec_enabled;
208 bool vsx_enabled;
209 bool spe_enabled;
210 bool tm_enabled;
211 ppc_spr_t *spr_cb;
212 int singlestep_enabled;
213 uint64_t insns_flags;
214 uint64_t insns_flags2;
215};
216
217
218static inline bool need_byteswap(const DisasContext *ctx)
219{
220#if defined(TARGET_WORDS_BIGENDIAN)
221 return ctx->le_mode;
222#else
223 return !ctx->le_mode;
224#endif
225}
226
227
228#ifdef TARGET_PPC64
229# define NARROW_MODE(C) (!(C)->sf_mode)
230#else
231# define NARROW_MODE(C) 0
232#endif
233
234struct opc_handler_t {
235
236 uint32_t inval1;
237
238 uint32_t inval2;
239
240 uint64_t type;
241
242 uint64_t type2;
243
244 void (*handler)(DisasContext *ctx);
245#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
246 const char *oname;
247#endif
248#if defined(DO_PPC_STATISTICS)
249 uint64_t count;
250#endif
251};
252
253static inline void gen_reset_fpstatus(void)
254{
255 gen_helper_reset_fpstatus(cpu_env);
256}
257
258static inline void gen_compute_fprf(TCGv_i64 arg)
259{
260 gen_helper_compute_fprf(cpu_env, arg);
261 gen_helper_float_check_status(cpu_env);
262}
263
264static inline void gen_set_access_type(DisasContext *ctx, int access_type)
265{
266 if (ctx->access_type != access_type) {
267 tcg_gen_movi_i32(cpu_access_type, access_type);
268 ctx->access_type = access_type;
269 }
270}
271
272static inline void gen_update_nip(DisasContext *ctx, target_ulong nip)
273{
274 if (NARROW_MODE(ctx)) {
275 nip = (uint32_t)nip;
276 }
277 tcg_gen_movi_tl(cpu_nip, nip);
278}
279
280void gen_update_current_nip(void *opaque)
281{
282 DisasContext *ctx = opaque;
283
284 tcg_gen_movi_tl(cpu_nip, ctx->nip);
285}
286
287static void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t error)
288{
289 TCGv_i32 t0, t1;
290 if (ctx->exception == POWERPC_EXCP_NONE) {
291 gen_update_nip(ctx, ctx->nip);
292 }
293 t0 = tcg_const_i32(excp);
294 t1 = tcg_const_i32(error);
295 gen_helper_raise_exception_err(cpu_env, t0, t1);
296 tcg_temp_free_i32(t0);
297 tcg_temp_free_i32(t1);
298 ctx->exception = (excp);
299}
300
301static void gen_exception(DisasContext *ctx, uint32_t excp)
302{
303 TCGv_i32 t0;
304 if (ctx->exception == POWERPC_EXCP_NONE) {
305 gen_update_nip(ctx, ctx->nip);
306 }
307 t0 = tcg_const_i32(excp);
308 gen_helper_raise_exception(cpu_env, t0);
309 tcg_temp_free_i32(t0);
310 ctx->exception = (excp);
311}
312
313static void gen_debug_exception(DisasContext *ctx)
314{
315 TCGv_i32 t0;
316
317 if ((ctx->exception != POWERPC_EXCP_BRANCH) &&
318 (ctx->exception != POWERPC_EXCP_SYNC)) {
319 gen_update_nip(ctx, ctx->nip);
320 }
321 t0 = tcg_const_i32(EXCP_DEBUG);
322 gen_helper_raise_exception(cpu_env, t0);
323 tcg_temp_free_i32(t0);
324}
325
326static inline void gen_inval_exception(DisasContext *ctx, uint32_t error)
327{
328
329 gen_exception_err(ctx, POWERPC_EXCP_HV_EMU, POWERPC_EXCP_INVAL | error);
330}
331
332static inline void gen_priv_exception(DisasContext *ctx, uint32_t error)
333{
334 gen_exception_err(ctx, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_PRIV | error);
335}
336
337static inline void gen_hvpriv_exception(DisasContext *ctx, uint32_t error)
338{
339
340 gen_exception_err(ctx, POWERPC_EXCP_HV_EMU, POWERPC_EXCP_PRIV | error);
341}
342
343
344static inline void gen_stop_exception(DisasContext *ctx)
345{
346 gen_update_nip(ctx, ctx->nip);
347 ctx->exception = POWERPC_EXCP_STOP;
348}
349
350#ifndef CONFIG_USER_ONLY
351
352static inline void gen_sync_exception(DisasContext *ctx)
353{
354 ctx->exception = POWERPC_EXCP_SYNC;
355}
356#endif
357
358#define GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \
359GEN_OPCODE(name, opc1, opc2, opc3, inval, type, PPC_NONE)
360
361#define GEN_HANDLER_E(name, opc1, opc2, opc3, inval, type, type2) \
362GEN_OPCODE(name, opc1, opc2, opc3, inval, type, type2)
363
364#define GEN_HANDLER2(name, onam, opc1, opc2, opc3, inval, type) \
365GEN_OPCODE2(name, onam, opc1, opc2, opc3, inval, type, PPC_NONE)
366
367#define GEN_HANDLER2_E(name, onam, opc1, opc2, opc3, inval, type, type2) \
368GEN_OPCODE2(name, onam, opc1, opc2, opc3, inval, type, type2)
369
370typedef struct opcode_t {
371 unsigned char opc1, opc2, opc3;
372#if HOST_LONG_BITS == 64
373 unsigned char pad[5];
374#else
375 unsigned char pad[1];
376#endif
377 opc_handler_t handler;
378 const char *oname;
379} opcode_t;
380
381
382#define GEN_PRIV \
383 do { \
384 gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC); return; \
385 } while (0)
386
387#if defined(CONFIG_USER_ONLY)
388#define CHK_HV GEN_PRIV
389#define CHK_SV GEN_PRIV
390#define CHK_HVRM GEN_PRIV
391#else
392#define CHK_HV \
393 do { \
394 if (unlikely(ctx->pr || !ctx->hv)) { \
395 GEN_PRIV; \
396 } \
397 } while (0)
398#define CHK_SV \
399 do { \
400 if (unlikely(ctx->pr)) { \
401 GEN_PRIV; \
402 } \
403 } while (0)
404#define CHK_HVRM \
405 do { \
406 if (unlikely(ctx->pr || !ctx->hv || ctx->dr)) { \
407 GEN_PRIV; \
408 } \
409 } while (0)
410#endif
411
412#define CHK_NONE
413
414
415
416
417#define EXTRACT_HELPER(name, shift, nb) \
418static inline uint32_t name(uint32_t opcode) \
419{ \
420 return (opcode >> (shift)) & ((1 << (nb)) - 1); \
421}
422
423#define EXTRACT_SHELPER(name, shift, nb) \
424static inline int32_t name(uint32_t opcode) \
425{ \
426 return (int16_t)((opcode >> (shift)) & ((1 << (nb)) - 1)); \
427}
428
429#define EXTRACT_HELPER_SPLIT(name, shift1, nb1, shift2, nb2) \
430static inline uint32_t name(uint32_t opcode) \
431{ \
432 return (((opcode >> (shift1)) & ((1 << (nb1)) - 1)) << nb2) | \
433 ((opcode >> (shift2)) & ((1 << (nb2)) - 1)); \
434}
435
436EXTRACT_HELPER(opc1, 26, 6);
437
438EXTRACT_HELPER(opc2, 1, 5);
439
440EXTRACT_HELPER(opc3, 6, 5);
441
442EXTRACT_HELPER(Rc, 0, 1);
443
444EXTRACT_HELPER(Rc21, 10, 1);
445
446EXTRACT_HELPER(rD, 21, 5);
447
448EXTRACT_HELPER(rS, 21, 5);
449
450EXTRACT_HELPER(rA, 16, 5);
451
452EXTRACT_HELPER(rB, 11, 5);
453
454EXTRACT_HELPER(rC, 6, 5);
455
456EXTRACT_HELPER(crfD, 23, 3);
457EXTRACT_HELPER(crfS, 18, 3);
458EXTRACT_HELPER(crbD, 21, 5);
459EXTRACT_HELPER(crbA, 16, 5);
460EXTRACT_HELPER(crbB, 11, 5);
461
462EXTRACT_HELPER(_SPR, 11, 10);
463static inline uint32_t SPR(uint32_t opcode)
464{
465 uint32_t sprn = _SPR(opcode);
466
467 return ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
468}
469
470
471EXTRACT_SHELPER(SIMM, 0, 16);
472
473EXTRACT_HELPER(UIMM, 0, 16);
474
475EXTRACT_HELPER(SIMM5, 16, 5);
476
477EXTRACT_HELPER(UIMM5, 16, 5);
478
479EXTRACT_HELPER(NB, 11, 5);
480
481EXTRACT_HELPER(SH, 11, 5);
482
483EXTRACT_HELPER(VSH, 6, 4);
484
485EXTRACT_HELPER(MB, 6, 5);
486
487EXTRACT_HELPER(ME, 1, 5);
488
489EXTRACT_HELPER(TO, 21, 5);
490
491EXTRACT_HELPER(CRM, 12, 8);
492
493#ifndef CONFIG_USER_ONLY
494EXTRACT_HELPER(SR, 16, 4);
495#endif
496
497
498EXTRACT_HELPER(FPBF, 23, 3);
499EXTRACT_HELPER(FPIMM, 12, 4);
500EXTRACT_HELPER(FPL, 25, 1);
501EXTRACT_HELPER(FPFLM, 17, 8);
502EXTRACT_HELPER(FPW, 16, 1);
503
504
505
506static inline target_ulong LI(uint32_t opcode)
507{
508 return (opcode >> 0) & 0x03FFFFFC;
509}
510
511static inline uint32_t BD(uint32_t opcode)
512{
513 return (opcode >> 0) & 0xFFFC;
514}
515
516EXTRACT_HELPER(BO, 21, 5);
517EXTRACT_HELPER(BI, 16, 5);
518
519EXTRACT_HELPER(AA, 1, 1);
520
521EXTRACT_HELPER(LK, 0, 1);
522
523
524EXTRACT_HELPER(DCM, 10, 6)
525
526
527EXTRACT_HELPER(RMC, 9, 2)
528
529
530static inline target_ulong MASK(uint32_t start, uint32_t end)
531{
532 target_ulong ret;
533
534#if defined(TARGET_PPC64)
535 if (likely(start == 0)) {
536 ret = UINT64_MAX << (63 - end);
537 } else if (likely(end == 63)) {
538 ret = UINT64_MAX >> start;
539 }
540#else
541 if (likely(start == 0)) {
542 ret = UINT32_MAX << (31 - end);
543 } else if (likely(end == 31)) {
544 ret = UINT32_MAX >> start;
545 }
546#endif
547 else {
548 ret = (((target_ulong)(-1ULL)) >> (start)) ^
549 (((target_ulong)(-1ULL) >> (end)) >> 1);
550 if (unlikely(start > end))
551 return ~ret;
552 }
553
554 return ret;
555}
556
557EXTRACT_HELPER_SPLIT(xT, 0, 1, 21, 5);
558EXTRACT_HELPER_SPLIT(xS, 0, 1, 21, 5);
559EXTRACT_HELPER_SPLIT(xA, 2, 1, 16, 5);
560EXTRACT_HELPER_SPLIT(xB, 1, 1, 11, 5);
561EXTRACT_HELPER_SPLIT(xC, 3, 1, 6, 5);
562EXTRACT_HELPER(DM, 8, 2);
563EXTRACT_HELPER(UIM, 16, 2);
564EXTRACT_HELPER(SHW, 8, 2);
565EXTRACT_HELPER(SP, 19, 2);
566
567
568
569#if defined(DO_PPC_STATISTICS)
570#define GEN_OPCODE(name, op1, op2, op3, invl, _typ, _typ2) \
571{ \
572 .opc1 = op1, \
573 .opc2 = op2, \
574 .opc3 = op3, \
575 .pad = { 0, }, \
576 .handler = { \
577 .inval1 = invl, \
578 .type = _typ, \
579 .type2 = _typ2, \
580 .handler = &gen_##name, \
581 .oname = stringify(name), \
582 }, \
583 .oname = stringify(name), \
584}
585#define GEN_OPCODE_DUAL(name, op1, op2, op3, invl1, invl2, _typ, _typ2) \
586{ \
587 .opc1 = op1, \
588 .opc2 = op2, \
589 .opc3 = op3, \
590 .pad = { 0, }, \
591 .handler = { \
592 .inval1 = invl1, \
593 .inval2 = invl2, \
594 .type = _typ, \
595 .type2 = _typ2, \
596 .handler = &gen_##name, \
597 .oname = stringify(name), \
598 }, \
599 .oname = stringify(name), \
600}
601#define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ, _typ2) \
602{ \
603 .opc1 = op1, \
604 .opc2 = op2, \
605 .opc3 = op3, \
606 .pad = { 0, }, \
607 .handler = { \
608 .inval1 = invl, \
609 .type = _typ, \
610 .type2 = _typ2, \
611 .handler = &gen_##name, \
612 .oname = onam, \
613 }, \
614 .oname = onam, \
615}
616#else
617#define GEN_OPCODE(name, op1, op2, op3, invl, _typ, _typ2) \
618{ \
619 .opc1 = op1, \
620 .opc2 = op2, \
621 .opc3 = op3, \
622 .pad = { 0, }, \
623 .handler = { \
624 .inval1 = invl, \
625 .type = _typ, \
626 .type2 = _typ2, \
627 .handler = &gen_##name, \
628 }, \
629 .oname = stringify(name), \
630}
631#define GEN_OPCODE_DUAL(name, op1, op2, op3, invl1, invl2, _typ, _typ2) \
632{ \
633 .opc1 = op1, \
634 .opc2 = op2, \
635 .opc3 = op3, \
636 .pad = { 0, }, \
637 .handler = { \
638 .inval1 = invl1, \
639 .inval2 = invl2, \
640 .type = _typ, \
641 .type2 = _typ2, \
642 .handler = &gen_##name, \
643 }, \
644 .oname = stringify(name), \
645}
646#define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ, _typ2) \
647{ \
648 .opc1 = op1, \
649 .opc2 = op2, \
650 .opc3 = op3, \
651 .pad = { 0, }, \
652 .handler = { \
653 .inval1 = invl, \
654 .type = _typ, \
655 .type2 = _typ2, \
656 .handler = &gen_##name, \
657 }, \
658 .oname = onam, \
659}
660#endif
661
662
663static inline void gen_load_spr(TCGv t, int reg)
664{
665 tcg_gen_ld_tl(t, cpu_env, offsetof(CPUPPCState, spr[reg]));
666}
667
668static inline void gen_store_spr(int reg, TCGv t)
669{
670 tcg_gen_st_tl(t, cpu_env, offsetof(CPUPPCState, spr[reg]));
671}
672
673
674static void gen_invalid(DisasContext *ctx)
675{
676 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
677}
678
679static opc_handler_t invalid_handler = {
680 .inval1 = 0xFFFFFFFF,
681 .inval2 = 0xFFFFFFFF,
682 .type = PPC_NONE,
683 .type2 = PPC_NONE,
684 .handler = gen_invalid,
685};
686
687
688
689static inline void gen_op_cmp(TCGv arg0, TCGv arg1, int s, int crf)
690{
691 TCGv t0 = tcg_temp_new();
692 TCGv_i32 t1 = tcg_temp_new_i32();
693
694 tcg_gen_trunc_tl_i32(cpu_crf[crf], cpu_so);
695
696 tcg_gen_setcond_tl((s ? TCG_COND_LT: TCG_COND_LTU), t0, arg0, arg1);
697 tcg_gen_trunc_tl_i32(t1, t0);
698 tcg_gen_shli_i32(t1, t1, CRF_LT);
699 tcg_gen_or_i32(cpu_crf[crf], cpu_crf[crf], t1);
700
701 tcg_gen_setcond_tl((s ? TCG_COND_GT: TCG_COND_GTU), t0, arg0, arg1);
702 tcg_gen_trunc_tl_i32(t1, t0);
703 tcg_gen_shli_i32(t1, t1, CRF_GT);
704 tcg_gen_or_i32(cpu_crf[crf], cpu_crf[crf], t1);
705
706 tcg_gen_setcond_tl(TCG_COND_EQ, t0, arg0, arg1);
707 tcg_gen_trunc_tl_i32(t1, t0);
708 tcg_gen_shli_i32(t1, t1, CRF_EQ);
709 tcg_gen_or_i32(cpu_crf[crf], cpu_crf[crf], t1);
710
711 tcg_temp_free(t0);
712 tcg_temp_free_i32(t1);
713}
714
715static inline void gen_op_cmpi(TCGv arg0, target_ulong arg1, int s, int crf)
716{
717 TCGv t0 = tcg_const_tl(arg1);
718 gen_op_cmp(arg0, t0, s, crf);
719 tcg_temp_free(t0);
720}
721
722static inline void gen_op_cmp32(TCGv arg0, TCGv arg1, int s, int crf)
723{
724 TCGv t0, t1;
725 t0 = tcg_temp_new();
726 t1 = tcg_temp_new();
727 if (s) {
728 tcg_gen_ext32s_tl(t0, arg0);
729 tcg_gen_ext32s_tl(t1, arg1);
730 } else {
731 tcg_gen_ext32u_tl(t0, arg0);
732 tcg_gen_ext32u_tl(t1, arg1);
733 }
734 gen_op_cmp(t0, t1, s, crf);
735 tcg_temp_free(t1);
736 tcg_temp_free(t0);
737}
738
739static inline void gen_op_cmpi32(TCGv arg0, target_ulong arg1, int s, int crf)
740{
741 TCGv t0 = tcg_const_tl(arg1);
742 gen_op_cmp32(arg0, t0, s, crf);
743 tcg_temp_free(t0);
744}
745
746static inline void gen_set_Rc0(DisasContext *ctx, TCGv reg)
747{
748 if (NARROW_MODE(ctx)) {
749 gen_op_cmpi32(reg, 0, 1, 0);
750 } else {
751 gen_op_cmpi(reg, 0, 1, 0);
752 }
753}
754
755
756static void gen_cmp(DisasContext *ctx)
757{
758 if ((ctx->opcode & 0x00200000) && (ctx->insns_flags & PPC_64B)) {
759 gen_op_cmp(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
760 1, crfD(ctx->opcode));
761 } else {
762 gen_op_cmp32(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
763 1, crfD(ctx->opcode));
764 }
765}
766
767
768static void gen_cmpi(DisasContext *ctx)
769{
770 if ((ctx->opcode & 0x00200000) && (ctx->insns_flags & PPC_64B)) {
771 gen_op_cmpi(cpu_gpr[rA(ctx->opcode)], SIMM(ctx->opcode),
772 1, crfD(ctx->opcode));
773 } else {
774 gen_op_cmpi32(cpu_gpr[rA(ctx->opcode)], SIMM(ctx->opcode),
775 1, crfD(ctx->opcode));
776 }
777}
778
779
780static void gen_cmpl(DisasContext *ctx)
781{
782 if ((ctx->opcode & 0x00200000) && (ctx->insns_flags & PPC_64B)) {
783 gen_op_cmp(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
784 0, crfD(ctx->opcode));
785 } else {
786 gen_op_cmp32(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
787 0, crfD(ctx->opcode));
788 }
789}
790
791
792static void gen_cmpli(DisasContext *ctx)
793{
794 if ((ctx->opcode & 0x00200000) && (ctx->insns_flags & PPC_64B)) {
795 gen_op_cmpi(cpu_gpr[rA(ctx->opcode)], UIMM(ctx->opcode),
796 0, crfD(ctx->opcode));
797 } else {
798 gen_op_cmpi32(cpu_gpr[rA(ctx->opcode)], UIMM(ctx->opcode),
799 0, crfD(ctx->opcode));
800 }
801}
802
803
804static void gen_isel(DisasContext *ctx)
805{
806 uint32_t bi = rC(ctx->opcode);
807 uint32_t mask = 0x08 >> (bi & 0x03);
808 TCGv t0 = tcg_temp_new();
809 TCGv zr;
810
811 tcg_gen_extu_i32_tl(t0, cpu_crf[bi >> 2]);
812 tcg_gen_andi_tl(t0, t0, mask);
813
814 zr = tcg_const_tl(0);
815 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rD(ctx->opcode)], t0, zr,
816 rA(ctx->opcode) ? cpu_gpr[rA(ctx->opcode)] : zr,
817 cpu_gpr[rB(ctx->opcode)]);
818 tcg_temp_free(zr);
819 tcg_temp_free(t0);
820}
821
822
823static void gen_cmpb(DisasContext *ctx)
824{
825 gen_helper_cmpb(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)],
826 cpu_gpr[rB(ctx->opcode)]);
827}
828
829
830
831static inline void gen_op_arith_compute_ov(DisasContext *ctx, TCGv arg0,
832 TCGv arg1, TCGv arg2, int sub)
833{
834 TCGv t0 = tcg_temp_new();
835
836 tcg_gen_xor_tl(cpu_ov, arg0, arg2);
837 tcg_gen_xor_tl(t0, arg1, arg2);
838 if (sub) {
839 tcg_gen_and_tl(cpu_ov, cpu_ov, t0);
840 } else {
841 tcg_gen_andc_tl(cpu_ov, cpu_ov, t0);
842 }
843 tcg_temp_free(t0);
844 if (NARROW_MODE(ctx)) {
845 tcg_gen_ext32s_tl(cpu_ov, cpu_ov);
846 }
847 tcg_gen_shri_tl(cpu_ov, cpu_ov, TARGET_LONG_BITS - 1);
848 tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov);
849}
850
851
852static inline void gen_op_arith_add(DisasContext *ctx, TCGv ret, TCGv arg1,
853 TCGv arg2, bool add_ca, bool compute_ca,
854 bool compute_ov, bool compute_rc0)
855{
856 TCGv t0 = ret;
857
858 if (compute_ca || compute_ov) {
859 t0 = tcg_temp_new();
860 }
861
862 if (compute_ca) {
863 if (NARROW_MODE(ctx)) {
864
865
866
867 TCGv t1 = tcg_temp_new();
868 tcg_gen_xor_tl(t1, arg1, arg2);
869 tcg_gen_add_tl(t0, arg1, arg2);
870 if (add_ca) {
871 tcg_gen_add_tl(t0, t0, cpu_ca);
872 }
873 tcg_gen_xor_tl(cpu_ca, t0, t1);
874 tcg_temp_free(t1);
875 tcg_gen_shri_tl(cpu_ca, cpu_ca, 32);
876 tcg_gen_andi_tl(cpu_ca, cpu_ca, 1);
877 } else {
878 TCGv zero = tcg_const_tl(0);
879 if (add_ca) {
880 tcg_gen_add2_tl(t0, cpu_ca, arg1, zero, cpu_ca, zero);
881 tcg_gen_add2_tl(t0, cpu_ca, t0, cpu_ca, arg2, zero);
882 } else {
883 tcg_gen_add2_tl(t0, cpu_ca, arg1, zero, arg2, zero);
884 }
885 tcg_temp_free(zero);
886 }
887 } else {
888 tcg_gen_add_tl(t0, arg1, arg2);
889 if (add_ca) {
890 tcg_gen_add_tl(t0, t0, cpu_ca);
891 }
892 }
893
894 if (compute_ov) {
895 gen_op_arith_compute_ov(ctx, t0, arg1, arg2, 0);
896 }
897 if (unlikely(compute_rc0)) {
898 gen_set_Rc0(ctx, t0);
899 }
900
901 if (!TCGV_EQUAL(t0, ret)) {
902 tcg_gen_mov_tl(ret, t0);
903 tcg_temp_free(t0);
904 }
905}
906
907#define GEN_INT_ARITH_ADD(name, opc3, add_ca, compute_ca, compute_ov) \
908static void glue(gen_, name)(DisasContext *ctx) \
909{ \
910 gen_op_arith_add(ctx, cpu_gpr[rD(ctx->opcode)], \
911 cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], \
912 add_ca, compute_ca, compute_ov, Rc(ctx->opcode)); \
913}
914
915#define GEN_INT_ARITH_ADD_CONST(name, opc3, const_val, \
916 add_ca, compute_ca, compute_ov) \
917static void glue(gen_, name)(DisasContext *ctx) \
918{ \
919 TCGv t0 = tcg_const_tl(const_val); \
920 gen_op_arith_add(ctx, cpu_gpr[rD(ctx->opcode)], \
921 cpu_gpr[rA(ctx->opcode)], t0, \
922 add_ca, compute_ca, compute_ov, Rc(ctx->opcode)); \
923 tcg_temp_free(t0); \
924}
925
926
927GEN_INT_ARITH_ADD(add, 0x08, 0, 0, 0)
928GEN_INT_ARITH_ADD(addo, 0x18, 0, 0, 1)
929
930GEN_INT_ARITH_ADD(addc, 0x00, 0, 1, 0)
931GEN_INT_ARITH_ADD(addco, 0x10, 0, 1, 1)
932
933GEN_INT_ARITH_ADD(adde, 0x04, 1, 1, 0)
934GEN_INT_ARITH_ADD(addeo, 0x14, 1, 1, 1)
935
936GEN_INT_ARITH_ADD_CONST(addme, 0x07, -1LL, 1, 1, 0)
937GEN_INT_ARITH_ADD_CONST(addmeo, 0x17, -1LL, 1, 1, 1)
938
939GEN_INT_ARITH_ADD_CONST(addze, 0x06, 0, 1, 1, 0)
940GEN_INT_ARITH_ADD_CONST(addzeo, 0x16, 0, 1, 1, 1)
941
942static void gen_addi(DisasContext *ctx)
943{
944 target_long simm = SIMM(ctx->opcode);
945
946 if (rA(ctx->opcode) == 0) {
947
948 tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], simm);
949 } else {
950 tcg_gen_addi_tl(cpu_gpr[rD(ctx->opcode)],
951 cpu_gpr[rA(ctx->opcode)], simm);
952 }
953}
954
955static inline void gen_op_addic(DisasContext *ctx, bool compute_rc0)
956{
957 TCGv c = tcg_const_tl(SIMM(ctx->opcode));
958 gen_op_arith_add(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
959 c, 0, 1, 0, compute_rc0);
960 tcg_temp_free(c);
961}
962
963static void gen_addic(DisasContext *ctx)
964{
965 gen_op_addic(ctx, 0);
966}
967
968static void gen_addic_(DisasContext *ctx)
969{
970 gen_op_addic(ctx, 1);
971}
972
973
974static void gen_addis(DisasContext *ctx)
975{
976 target_long simm = SIMM(ctx->opcode);
977
978 if (rA(ctx->opcode) == 0) {
979
980 tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], simm << 16);
981 } else {
982 tcg_gen_addi_tl(cpu_gpr[rD(ctx->opcode)],
983 cpu_gpr[rA(ctx->opcode)], simm << 16);
984 }
985}
986
987static inline void gen_op_arith_divw(DisasContext *ctx, TCGv ret, TCGv arg1,
988 TCGv arg2, int sign, int compute_ov)
989{
990 TCGLabel *l1 = gen_new_label();
991 TCGLabel *l2 = gen_new_label();
992 TCGv_i32 t0 = tcg_temp_local_new_i32();
993 TCGv_i32 t1 = tcg_temp_local_new_i32();
994
995 tcg_gen_trunc_tl_i32(t0, arg1);
996 tcg_gen_trunc_tl_i32(t1, arg2);
997 tcg_gen_brcondi_i32(TCG_COND_EQ, t1, 0, l1);
998 if (sign) {
999 TCGLabel *l3 = gen_new_label();
1000 tcg_gen_brcondi_i32(TCG_COND_NE, t1, -1, l3);
1001 tcg_gen_brcondi_i32(TCG_COND_EQ, t0, INT32_MIN, l1);
1002 gen_set_label(l3);
1003 tcg_gen_div_i32(t0, t0, t1);
1004 } else {
1005 tcg_gen_divu_i32(t0, t0, t1);
1006 }
1007 if (compute_ov) {
1008 tcg_gen_movi_tl(cpu_ov, 0);
1009 }
1010 tcg_gen_br(l2);
1011 gen_set_label(l1);
1012 if (sign) {
1013 tcg_gen_sari_i32(t0, t0, 31);
1014 } else {
1015 tcg_gen_movi_i32(t0, 0);
1016 }
1017 if (compute_ov) {
1018 tcg_gen_movi_tl(cpu_ov, 1);
1019 tcg_gen_movi_tl(cpu_so, 1);
1020 }
1021 gen_set_label(l2);
1022 tcg_gen_extu_i32_tl(ret, t0);
1023 tcg_temp_free_i32(t0);
1024 tcg_temp_free_i32(t1);
1025 if (unlikely(Rc(ctx->opcode) != 0))
1026 gen_set_Rc0(ctx, ret);
1027}
1028
1029#define GEN_INT_ARITH_DIVW(name, opc3, sign, compute_ov) \
1030static void glue(gen_, name)(DisasContext *ctx) \
1031{ \
1032 gen_op_arith_divw(ctx, cpu_gpr[rD(ctx->opcode)], \
1033 cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], \
1034 sign, compute_ov); \
1035}
1036
1037GEN_INT_ARITH_DIVW(divwu, 0x0E, 0, 0);
1038GEN_INT_ARITH_DIVW(divwuo, 0x1E, 0, 1);
1039
1040GEN_INT_ARITH_DIVW(divw, 0x0F, 1, 0);
1041GEN_INT_ARITH_DIVW(divwo, 0x1F, 1, 1);
1042
1043
1044#define GEN_DIVE(name, hlpr, compute_ov) \
1045static void gen_##name(DisasContext *ctx) \
1046{ \
1047 TCGv_i32 t0 = tcg_const_i32(compute_ov); \
1048 gen_helper_##hlpr(cpu_gpr[rD(ctx->opcode)], cpu_env, \
1049 cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], t0); \
1050 tcg_temp_free_i32(t0); \
1051 if (unlikely(Rc(ctx->opcode) != 0)) { \
1052 gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]); \
1053 } \
1054}
1055
1056GEN_DIVE(divweu, divweu, 0);
1057GEN_DIVE(divweuo, divweu, 1);
1058GEN_DIVE(divwe, divwe, 0);
1059GEN_DIVE(divweo, divwe, 1);
1060
1061#if defined(TARGET_PPC64)
1062static inline void gen_op_arith_divd(DisasContext *ctx, TCGv ret, TCGv arg1,
1063 TCGv arg2, int sign, int compute_ov)
1064{
1065 TCGLabel *l1 = gen_new_label();
1066 TCGLabel *l2 = gen_new_label();
1067
1068 tcg_gen_brcondi_i64(TCG_COND_EQ, arg2, 0, l1);
1069 if (sign) {
1070 TCGLabel *l3 = gen_new_label();
1071 tcg_gen_brcondi_i64(TCG_COND_NE, arg2, -1, l3);
1072 tcg_gen_brcondi_i64(TCG_COND_EQ, arg1, INT64_MIN, l1);
1073 gen_set_label(l3);
1074 tcg_gen_div_i64(ret, arg1, arg2);
1075 } else {
1076 tcg_gen_divu_i64(ret, arg1, arg2);
1077 }
1078 if (compute_ov) {
1079 tcg_gen_movi_tl(cpu_ov, 0);
1080 }
1081 tcg_gen_br(l2);
1082 gen_set_label(l1);
1083 if (sign) {
1084 tcg_gen_sari_i64(ret, arg1, 63);
1085 } else {
1086 tcg_gen_movi_i64(ret, 0);
1087 }
1088 if (compute_ov) {
1089 tcg_gen_movi_tl(cpu_ov, 1);
1090 tcg_gen_movi_tl(cpu_so, 1);
1091 }
1092 gen_set_label(l2);
1093 if (unlikely(Rc(ctx->opcode) != 0))
1094 gen_set_Rc0(ctx, ret);
1095}
1096#define GEN_INT_ARITH_DIVD(name, opc3, sign, compute_ov) \
1097static void glue(gen_, name)(DisasContext *ctx) \
1098{ \
1099 gen_op_arith_divd(ctx, cpu_gpr[rD(ctx->opcode)], \
1100 cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], \
1101 sign, compute_ov); \
1102}
1103
1104GEN_INT_ARITH_DIVD(divdu, 0x0E, 0, 0);
1105GEN_INT_ARITH_DIVD(divduo, 0x1E, 0, 1);
1106
1107GEN_INT_ARITH_DIVD(divd, 0x0F, 1, 0);
1108GEN_INT_ARITH_DIVD(divdo, 0x1F, 1, 1);
1109
1110GEN_DIVE(divdeu, divdeu, 0);
1111GEN_DIVE(divdeuo, divdeu, 1);
1112GEN_DIVE(divde, divde, 0);
1113GEN_DIVE(divdeo, divde, 1);
1114#endif
1115
1116
1117static void gen_mulhw(DisasContext *ctx)
1118{
1119 TCGv_i32 t0 = tcg_temp_new_i32();
1120 TCGv_i32 t1 = tcg_temp_new_i32();
1121
1122 tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);
1123 tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);
1124 tcg_gen_muls2_i32(t0, t1, t0, t1);
1125 tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t1);
1126 tcg_temp_free_i32(t0);
1127 tcg_temp_free_i32(t1);
1128 if (unlikely(Rc(ctx->opcode) != 0))
1129 gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1130}
1131
1132
1133static void gen_mulhwu(DisasContext *ctx)
1134{
1135 TCGv_i32 t0 = tcg_temp_new_i32();
1136 TCGv_i32 t1 = tcg_temp_new_i32();
1137
1138 tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);
1139 tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);
1140 tcg_gen_mulu2_i32(t0, t1, t0, t1);
1141 tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t1);
1142 tcg_temp_free_i32(t0);
1143 tcg_temp_free_i32(t1);
1144 if (unlikely(Rc(ctx->opcode) != 0))
1145 gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1146}
1147
1148
1149static void gen_mullw(DisasContext *ctx)
1150{
1151#if defined(TARGET_PPC64)
1152 TCGv_i64 t0, t1;
1153 t0 = tcg_temp_new_i64();
1154 t1 = tcg_temp_new_i64();
1155 tcg_gen_ext32s_tl(t0, cpu_gpr[rA(ctx->opcode)]);
1156 tcg_gen_ext32s_tl(t1, cpu_gpr[rB(ctx->opcode)]);
1157 tcg_gen_mul_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);
1158 tcg_temp_free(t0);
1159 tcg_temp_free(t1);
1160#else
1161 tcg_gen_mul_i32(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
1162 cpu_gpr[rB(ctx->opcode)]);
1163#endif
1164 if (unlikely(Rc(ctx->opcode) != 0))
1165 gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1166}
1167
1168
1169static void gen_mullwo(DisasContext *ctx)
1170{
1171 TCGv_i32 t0 = tcg_temp_new_i32();
1172 TCGv_i32 t1 = tcg_temp_new_i32();
1173
1174 tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);
1175 tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);
1176 tcg_gen_muls2_i32(t0, t1, t0, t1);
1177#if defined(TARGET_PPC64)
1178 tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);
1179#else
1180 tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], t0);
1181#endif
1182
1183 tcg_gen_sari_i32(t0, t0, 31);
1184 tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t1);
1185 tcg_gen_extu_i32_tl(cpu_ov, t0);
1186 tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov);
1187
1188 tcg_temp_free_i32(t0);
1189 tcg_temp_free_i32(t1);
1190 if (unlikely(Rc(ctx->opcode) != 0))
1191 gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1192}
1193
1194
1195static void gen_mulli(DisasContext *ctx)
1196{
1197 tcg_gen_muli_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
1198 SIMM(ctx->opcode));
1199}
1200
1201#if defined(TARGET_PPC64)
1202
1203static void gen_mulhd(DisasContext *ctx)
1204{
1205 TCGv lo = tcg_temp_new();
1206 tcg_gen_muls2_tl(lo, cpu_gpr[rD(ctx->opcode)],
1207 cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1208 tcg_temp_free(lo);
1209 if (unlikely(Rc(ctx->opcode) != 0)) {
1210 gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1211 }
1212}
1213
1214
1215static void gen_mulhdu(DisasContext *ctx)
1216{
1217 TCGv lo = tcg_temp_new();
1218 tcg_gen_mulu2_tl(lo, cpu_gpr[rD(ctx->opcode)],
1219 cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1220 tcg_temp_free(lo);
1221 if (unlikely(Rc(ctx->opcode) != 0)) {
1222 gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1223 }
1224}
1225
1226
1227static void gen_mulld(DisasContext *ctx)
1228{
1229 tcg_gen_mul_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
1230 cpu_gpr[rB(ctx->opcode)]);
1231 if (unlikely(Rc(ctx->opcode) != 0))
1232 gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1233}
1234
1235
1236static void gen_mulldo(DisasContext *ctx)
1237{
1238 TCGv_i64 t0 = tcg_temp_new_i64();
1239 TCGv_i64 t1 = tcg_temp_new_i64();
1240
1241 tcg_gen_muls2_i64(t0, t1, cpu_gpr[rA(ctx->opcode)],
1242 cpu_gpr[rB(ctx->opcode)]);
1243 tcg_gen_mov_i64(cpu_gpr[rD(ctx->opcode)], t0);
1244
1245 tcg_gen_sari_i64(t0, t0, 63);
1246 tcg_gen_setcond_i64(TCG_COND_NE, cpu_ov, t0, t1);
1247 tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov);
1248
1249 tcg_temp_free_i64(t0);
1250 tcg_temp_free_i64(t1);
1251
1252 if (unlikely(Rc(ctx->opcode) != 0)) {
1253 gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1254 }
1255}
1256#endif
1257
1258
1259static inline void gen_op_arith_subf(DisasContext *ctx, TCGv ret, TCGv arg1,
1260 TCGv arg2, bool add_ca, bool compute_ca,
1261 bool compute_ov, bool compute_rc0)
1262{
1263 TCGv t0 = ret;
1264
1265 if (compute_ca || compute_ov) {
1266 t0 = tcg_temp_new();
1267 }
1268
1269 if (compute_ca) {
1270
1271 if (NARROW_MODE(ctx)) {
1272
1273
1274
1275 TCGv inv1 = tcg_temp_new();
1276 TCGv t1 = tcg_temp_new();
1277 tcg_gen_not_tl(inv1, arg1);
1278 if (add_ca) {
1279 tcg_gen_add_tl(t0, arg2, cpu_ca);
1280 } else {
1281 tcg_gen_addi_tl(t0, arg2, 1);
1282 }
1283 tcg_gen_xor_tl(t1, arg2, inv1);
1284 tcg_gen_add_tl(t0, t0, inv1);
1285 tcg_temp_free(inv1);
1286 tcg_gen_xor_tl(cpu_ca, t0, t1);
1287 tcg_temp_free(t1);
1288 tcg_gen_shri_tl(cpu_ca, cpu_ca, 32);
1289 tcg_gen_andi_tl(cpu_ca, cpu_ca, 1);
1290 } else if (add_ca) {
1291 TCGv zero, inv1 = tcg_temp_new();
1292 tcg_gen_not_tl(inv1, arg1);
1293 zero = tcg_const_tl(0);
1294 tcg_gen_add2_tl(t0, cpu_ca, arg2, zero, cpu_ca, zero);
1295 tcg_gen_add2_tl(t0, cpu_ca, t0, cpu_ca, inv1, zero);
1296 tcg_temp_free(zero);
1297 tcg_temp_free(inv1);
1298 } else {
1299 tcg_gen_setcond_tl(TCG_COND_GEU, cpu_ca, arg2, arg1);
1300 tcg_gen_sub_tl(t0, arg2, arg1);
1301 }
1302 } else if (add_ca) {
1303
1304
1305 tcg_gen_sub_tl(t0, arg2, arg1);
1306 tcg_gen_add_tl(t0, t0, cpu_ca);
1307 tcg_gen_subi_tl(t0, t0, 1);
1308 } else {
1309 tcg_gen_sub_tl(t0, arg2, arg1);
1310 }
1311
1312 if (compute_ov) {
1313 gen_op_arith_compute_ov(ctx, t0, arg1, arg2, 1);
1314 }
1315 if (unlikely(compute_rc0)) {
1316 gen_set_Rc0(ctx, t0);
1317 }
1318
1319 if (!TCGV_EQUAL(t0, ret)) {
1320 tcg_gen_mov_tl(ret, t0);
1321 tcg_temp_free(t0);
1322 }
1323}
1324
1325#define GEN_INT_ARITH_SUBF(name, opc3, add_ca, compute_ca, compute_ov) \
1326static void glue(gen_, name)(DisasContext *ctx) \
1327{ \
1328 gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)], \
1329 cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], \
1330 add_ca, compute_ca, compute_ov, Rc(ctx->opcode)); \
1331}
1332
1333#define GEN_INT_ARITH_SUBF_CONST(name, opc3, const_val, \
1334 add_ca, compute_ca, compute_ov) \
1335static void glue(gen_, name)(DisasContext *ctx) \
1336{ \
1337 TCGv t0 = tcg_const_tl(const_val); \
1338 gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)], \
1339 cpu_gpr[rA(ctx->opcode)], t0, \
1340 add_ca, compute_ca, compute_ov, Rc(ctx->opcode)); \
1341 tcg_temp_free(t0); \
1342}
1343
1344GEN_INT_ARITH_SUBF(subf, 0x01, 0, 0, 0)
1345GEN_INT_ARITH_SUBF(subfo, 0x11, 0, 0, 1)
1346
1347GEN_INT_ARITH_SUBF(subfc, 0x00, 0, 1, 0)
1348GEN_INT_ARITH_SUBF(subfco, 0x10, 0, 1, 1)
1349
1350GEN_INT_ARITH_SUBF(subfe, 0x04, 1, 1, 0)
1351GEN_INT_ARITH_SUBF(subfeo, 0x14, 1, 1, 1)
1352
1353GEN_INT_ARITH_SUBF_CONST(subfme, 0x07, -1LL, 1, 1, 0)
1354GEN_INT_ARITH_SUBF_CONST(subfmeo, 0x17, -1LL, 1, 1, 1)
1355
1356GEN_INT_ARITH_SUBF_CONST(subfze, 0x06, 0, 1, 1, 0)
1357GEN_INT_ARITH_SUBF_CONST(subfzeo, 0x16, 0, 1, 1, 1)
1358
1359
1360static void gen_subfic(DisasContext *ctx)
1361{
1362 TCGv c = tcg_const_tl(SIMM(ctx->opcode));
1363 gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
1364 c, 0, 1, 0, 0);
1365 tcg_temp_free(c);
1366}
1367
1368
1369static inline void gen_op_arith_neg(DisasContext *ctx, bool compute_ov)
1370{
1371 TCGv zero = tcg_const_tl(0);
1372 gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
1373 zero, 0, 0, compute_ov, Rc(ctx->opcode));
1374 tcg_temp_free(zero);
1375}
1376
1377static void gen_neg(DisasContext *ctx)
1378{
1379 gen_op_arith_neg(ctx, 0);
1380}
1381
1382static void gen_nego(DisasContext *ctx)
1383{
1384 gen_op_arith_neg(ctx, 1);
1385}
1386
1387
1388#define GEN_LOGICAL2(name, tcg_op, opc, type) \
1389static void glue(gen_, name)(DisasContext *ctx) \
1390{ \
1391 tcg_op(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], \
1392 cpu_gpr[rB(ctx->opcode)]); \
1393 if (unlikely(Rc(ctx->opcode) != 0)) \
1394 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); \
1395}
1396
1397#define GEN_LOGICAL1(name, tcg_op, opc, type) \
1398static void glue(gen_, name)(DisasContext *ctx) \
1399{ \
1400 tcg_op(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]); \
1401 if (unlikely(Rc(ctx->opcode) != 0)) \
1402 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); \
1403}
1404
1405
1406GEN_LOGICAL2(and, tcg_gen_and_tl, 0x00, PPC_INTEGER);
1407
1408GEN_LOGICAL2(andc, tcg_gen_andc_tl, 0x01, PPC_INTEGER);
1409
1410
1411static void gen_andi_(DisasContext *ctx)
1412{
1413 tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], UIMM(ctx->opcode));
1414 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1415}
1416
1417
1418static void gen_andis_(DisasContext *ctx)
1419{
1420 tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], UIMM(ctx->opcode) << 16);
1421 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1422}
1423
1424
1425static void gen_cntlzw(DisasContext *ctx)
1426{
1427 gen_helper_cntlzw(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1428 if (unlikely(Rc(ctx->opcode) != 0))
1429 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1430}
1431
1432GEN_LOGICAL2(eqv, tcg_gen_eqv_tl, 0x08, PPC_INTEGER);
1433
1434GEN_LOGICAL1(extsb, tcg_gen_ext8s_tl, 0x1D, PPC_INTEGER);
1435
1436GEN_LOGICAL1(extsh, tcg_gen_ext16s_tl, 0x1C, PPC_INTEGER);
1437
1438GEN_LOGICAL2(nand, tcg_gen_nand_tl, 0x0E, PPC_INTEGER);
1439
1440GEN_LOGICAL2(nor, tcg_gen_nor_tl, 0x03, PPC_INTEGER);
1441
1442#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
1443static void gen_pause(DisasContext *ctx)
1444{
1445 TCGv_i32 t0 = tcg_const_i32(0);
1446 tcg_gen_st_i32(t0, cpu_env,
1447 -offsetof(PowerPCCPU, env) + offsetof(CPUState, halted));
1448 tcg_temp_free_i32(t0);
1449
1450
1451 gen_exception_err(ctx, EXCP_HLT, 1);
1452}
1453#endif
1454
1455
1456static void gen_or(DisasContext *ctx)
1457{
1458 int rs, ra, rb;
1459
1460 rs = rS(ctx->opcode);
1461 ra = rA(ctx->opcode);
1462 rb = rB(ctx->opcode);
1463
1464 if (rs != ra || rs != rb) {
1465 if (rs != rb)
1466 tcg_gen_or_tl(cpu_gpr[ra], cpu_gpr[rs], cpu_gpr[rb]);
1467 else
1468 tcg_gen_mov_tl(cpu_gpr[ra], cpu_gpr[rs]);
1469 if (unlikely(Rc(ctx->opcode) != 0))
1470 gen_set_Rc0(ctx, cpu_gpr[ra]);
1471 } else if (unlikely(Rc(ctx->opcode) != 0)) {
1472 gen_set_Rc0(ctx, cpu_gpr[rs]);
1473#if defined(TARGET_PPC64)
1474 } else if (rs != 0) {
1475 int prio = 0;
1476
1477 switch (rs) {
1478 case 1:
1479
1480 prio = 2;
1481 break;
1482 case 6:
1483
1484 prio = 3;
1485 break;
1486 case 2:
1487
1488 prio = 4;
1489 break;
1490#if !defined(CONFIG_USER_ONLY)
1491 case 31:
1492 if (!ctx->pr) {
1493
1494 prio = 1;
1495 }
1496 break;
1497 case 5:
1498 if (!ctx->pr) {
1499
1500 prio = 5;
1501 }
1502 break;
1503 case 3:
1504 if (!ctx->pr) {
1505
1506 prio = 6;
1507 }
1508 break;
1509 case 7:
1510 if (ctx->hv && !ctx->pr) {
1511
1512 prio = 7;
1513 }
1514 break;
1515#endif
1516 default:
1517 break;
1518 }
1519 if (prio) {
1520 TCGv t0 = tcg_temp_new();
1521 gen_load_spr(t0, SPR_PPR);
1522 tcg_gen_andi_tl(t0, t0, ~0x001C000000000000ULL);
1523 tcg_gen_ori_tl(t0, t0, ((uint64_t)prio) << 50);
1524 gen_store_spr(SPR_PPR, t0);
1525 tcg_temp_free(t0);
1526 }
1527#if !defined(CONFIG_USER_ONLY)
1528
1529
1530
1531
1532
1533 gen_pause(ctx);
1534#endif
1535#endif
1536 }
1537}
1538
1539GEN_LOGICAL2(orc, tcg_gen_orc_tl, 0x0C, PPC_INTEGER);
1540
1541
1542static void gen_xor(DisasContext *ctx)
1543{
1544
1545 if (rS(ctx->opcode) != rB(ctx->opcode))
1546 tcg_gen_xor_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1547 else
1548 tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
1549 if (unlikely(Rc(ctx->opcode) != 0))
1550 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1551}
1552
1553
1554static void gen_ori(DisasContext *ctx)
1555{
1556 target_ulong uimm = UIMM(ctx->opcode);
1557
1558 if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1559 return;
1560 }
1561 tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm);
1562}
1563
1564
1565static void gen_oris(DisasContext *ctx)
1566{
1567 target_ulong uimm = UIMM(ctx->opcode);
1568
1569 if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1570
1571 return;
1572 }
1573 tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm << 16);
1574}
1575
1576
1577static void gen_xori(DisasContext *ctx)
1578{
1579 target_ulong uimm = UIMM(ctx->opcode);
1580
1581 if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1582
1583 return;
1584 }
1585 tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm);
1586}
1587
1588
1589static void gen_xoris(DisasContext *ctx)
1590{
1591 target_ulong uimm = UIMM(ctx->opcode);
1592
1593 if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1594
1595 return;
1596 }
1597 tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm << 16);
1598}
1599
1600
1601static void gen_popcntb(DisasContext *ctx)
1602{
1603 gen_helper_popcntb(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1604}
1605
1606static void gen_popcntw(DisasContext *ctx)
1607{
1608 gen_helper_popcntw(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1609}
1610
1611#if defined(TARGET_PPC64)
1612
1613static void gen_popcntd(DisasContext *ctx)
1614{
1615 gen_helper_popcntd(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1616}
1617#endif
1618
1619
1620static void gen_prtyw(DisasContext *ctx)
1621{
1622 TCGv ra = cpu_gpr[rA(ctx->opcode)];
1623 TCGv rs = cpu_gpr[rS(ctx->opcode)];
1624 TCGv t0 = tcg_temp_new();
1625 tcg_gen_shri_tl(t0, rs, 16);
1626 tcg_gen_xor_tl(ra, rs, t0);
1627 tcg_gen_shri_tl(t0, ra, 8);
1628 tcg_gen_xor_tl(ra, ra, t0);
1629 tcg_gen_andi_tl(ra, ra, (target_ulong)0x100000001ULL);
1630 tcg_temp_free(t0);
1631}
1632
1633#if defined(TARGET_PPC64)
1634
1635static void gen_prtyd(DisasContext *ctx)
1636{
1637 TCGv ra = cpu_gpr[rA(ctx->opcode)];
1638 TCGv rs = cpu_gpr[rS(ctx->opcode)];
1639 TCGv t0 = tcg_temp_new();
1640 tcg_gen_shri_tl(t0, rs, 32);
1641 tcg_gen_xor_tl(ra, rs, t0);
1642 tcg_gen_shri_tl(t0, ra, 16);
1643 tcg_gen_xor_tl(ra, ra, t0);
1644 tcg_gen_shri_tl(t0, ra, 8);
1645 tcg_gen_xor_tl(ra, ra, t0);
1646 tcg_gen_andi_tl(ra, ra, 1);
1647 tcg_temp_free(t0);
1648}
1649#endif
1650
1651#if defined(TARGET_PPC64)
1652
1653static void gen_bpermd(DisasContext *ctx)
1654{
1655 gen_helper_bpermd(cpu_gpr[rA(ctx->opcode)],
1656 cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1657}
1658#endif
1659
1660#if defined(TARGET_PPC64)
1661
1662GEN_LOGICAL1(extsw, tcg_gen_ext32s_tl, 0x1E, PPC_64B);
1663
1664
1665static void gen_cntlzd(DisasContext *ctx)
1666{
1667 gen_helper_cntlzd(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1668 if (unlikely(Rc(ctx->opcode) != 0))
1669 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1670}
1671#endif
1672
1673
1674
1675
1676static void gen_rlwimi(DisasContext *ctx)
1677{
1678 TCGv t_ra = cpu_gpr[rA(ctx->opcode)];
1679 TCGv t_rs = cpu_gpr[rS(ctx->opcode)];
1680 uint32_t sh = SH(ctx->opcode);
1681 uint32_t mb = MB(ctx->opcode);
1682 uint32_t me = ME(ctx->opcode);
1683
1684 if (sh == (31-me) && mb <= me) {
1685 tcg_gen_deposit_tl(t_ra, t_ra, t_rs, sh, me - mb + 1);
1686 } else {
1687 target_ulong mask;
1688 TCGv t1;
1689
1690#if defined(TARGET_PPC64)
1691 mb += 32;
1692 me += 32;
1693#endif
1694 mask = MASK(mb, me);
1695
1696 t1 = tcg_temp_new();
1697 if (mask <= 0xffffffffu) {
1698 TCGv_i32 t0 = tcg_temp_new_i32();
1699 tcg_gen_trunc_tl_i32(t0, t_rs);
1700 tcg_gen_rotli_i32(t0, t0, sh);
1701 tcg_gen_extu_i32_tl(t1, t0);
1702 tcg_temp_free_i32(t0);
1703 } else {
1704#if defined(TARGET_PPC64)
1705 tcg_gen_deposit_i64(t1, t_rs, t_rs, 32, 32);
1706 tcg_gen_rotli_i64(t1, t1, sh);
1707#else
1708 g_assert_not_reached();
1709#endif
1710 }
1711
1712 tcg_gen_andi_tl(t1, t1, mask);
1713 tcg_gen_andi_tl(t_ra, t_ra, ~mask);
1714 tcg_gen_or_tl(t_ra, t_ra, t1);
1715 tcg_temp_free(t1);
1716 }
1717 if (unlikely(Rc(ctx->opcode) != 0)) {
1718 gen_set_Rc0(ctx, t_ra);
1719 }
1720}
1721
1722
1723static void gen_rlwinm(DisasContext *ctx)
1724{
1725 TCGv t_ra = cpu_gpr[rA(ctx->opcode)];
1726 TCGv t_rs = cpu_gpr[rS(ctx->opcode)];
1727 uint32_t sh = SH(ctx->opcode);
1728 uint32_t mb = MB(ctx->opcode);
1729 uint32_t me = ME(ctx->opcode);
1730
1731 if (mb == 0 && me == (31 - sh)) {
1732 tcg_gen_shli_tl(t_ra, t_rs, sh);
1733 tcg_gen_ext32u_tl(t_ra, t_ra);
1734 } else if (sh != 0 && me == 31 && sh == (32 - mb)) {
1735 tcg_gen_ext32u_tl(t_ra, t_rs);
1736 tcg_gen_shri_tl(t_ra, t_ra, mb);
1737 } else {
1738 target_ulong mask;
1739#if defined(TARGET_PPC64)
1740 mb += 32;
1741 me += 32;
1742#endif
1743 mask = MASK(mb, me);
1744
1745 if (mask <= 0xffffffffu) {
1746 TCGv_i32 t0 = tcg_temp_new_i32();
1747 tcg_gen_trunc_tl_i32(t0, t_rs);
1748 tcg_gen_rotli_i32(t0, t0, sh);
1749 tcg_gen_andi_i32(t0, t0, mask);
1750 tcg_gen_extu_i32_tl(t_ra, t0);
1751 tcg_temp_free_i32(t0);
1752 } else {
1753#if defined(TARGET_PPC64)
1754 tcg_gen_deposit_i64(t_ra, t_rs, t_rs, 32, 32);
1755 tcg_gen_rotli_i64(t_ra, t_ra, sh);
1756 tcg_gen_andi_i64(t_ra, t_ra, mask);
1757#else
1758 g_assert_not_reached();
1759#endif
1760 }
1761 }
1762 if (unlikely(Rc(ctx->opcode) != 0)) {
1763 gen_set_Rc0(ctx, t_ra);
1764 }
1765}
1766
1767
1768static void gen_rlwnm(DisasContext *ctx)
1769{
1770 TCGv t_ra = cpu_gpr[rA(ctx->opcode)];
1771 TCGv t_rs = cpu_gpr[rS(ctx->opcode)];
1772 TCGv t_rb = cpu_gpr[rB(ctx->opcode)];
1773 uint32_t mb = MB(ctx->opcode);
1774 uint32_t me = ME(ctx->opcode);
1775 target_ulong mask;
1776
1777#if defined(TARGET_PPC64)
1778 mb += 32;
1779 me += 32;
1780#endif
1781 mask = MASK(mb, me);
1782
1783 if (mask <= 0xffffffffu) {
1784 TCGv_i32 t0 = tcg_temp_new_i32();
1785 TCGv_i32 t1 = tcg_temp_new_i32();
1786 tcg_gen_trunc_tl_i32(t0, t_rb);
1787 tcg_gen_trunc_tl_i32(t1, t_rs);
1788 tcg_gen_andi_i32(t0, t0, 0x1f);
1789 tcg_gen_rotl_i32(t1, t1, t0);
1790 tcg_gen_extu_i32_tl(t_ra, t1);
1791 tcg_temp_free_i32(t0);
1792 tcg_temp_free_i32(t1);
1793 } else {
1794#if defined(TARGET_PPC64)
1795 TCGv_i64 t0 = tcg_temp_new_i64();
1796 tcg_gen_andi_i64(t0, t_rb, 0x1f);
1797 tcg_gen_deposit_i64(t_ra, t_rs, t_rs, 32, 32);
1798 tcg_gen_rotl_i64(t_ra, t_ra, t0);
1799 tcg_temp_free_i64(t0);
1800#else
1801 g_assert_not_reached();
1802#endif
1803 }
1804
1805 tcg_gen_andi_tl(t_ra, t_ra, mask);
1806
1807 if (unlikely(Rc(ctx->opcode) != 0)) {
1808 gen_set_Rc0(ctx, t_ra);
1809 }
1810}
1811
1812#if defined(TARGET_PPC64)
1813#define GEN_PPC64_R2(name, opc1, opc2) \
1814static void glue(gen_, name##0)(DisasContext *ctx) \
1815{ \
1816 gen_##name(ctx, 0); \
1817} \
1818 \
1819static void glue(gen_, name##1)(DisasContext *ctx) \
1820{ \
1821 gen_##name(ctx, 1); \
1822}
1823#define GEN_PPC64_R4(name, opc1, opc2) \
1824static void glue(gen_, name##0)(DisasContext *ctx) \
1825{ \
1826 gen_##name(ctx, 0, 0); \
1827} \
1828 \
1829static void glue(gen_, name##1)(DisasContext *ctx) \
1830{ \
1831 gen_##name(ctx, 0, 1); \
1832} \
1833 \
1834static void glue(gen_, name##2)(DisasContext *ctx) \
1835{ \
1836 gen_##name(ctx, 1, 0); \
1837} \
1838 \
1839static void glue(gen_, name##3)(DisasContext *ctx) \
1840{ \
1841 gen_##name(ctx, 1, 1); \
1842}
1843
1844static void gen_rldinm(DisasContext *ctx, int mb, int me, int sh)
1845{
1846 TCGv t_ra = cpu_gpr[rA(ctx->opcode)];
1847 TCGv t_rs = cpu_gpr[rS(ctx->opcode)];
1848
1849 if (sh != 0 && mb == 0 && me == (63 - sh)) {
1850 tcg_gen_shli_tl(t_ra, t_rs, sh);
1851 } else if (sh != 0 && me == 63 && sh == (64 - mb)) {
1852 tcg_gen_shri_tl(t_ra, t_rs, mb);
1853 } else {
1854 tcg_gen_rotli_tl(t_ra, t_rs, sh);
1855 tcg_gen_andi_tl(t_ra, t_ra, MASK(mb, me));
1856 }
1857 if (unlikely(Rc(ctx->opcode) != 0)) {
1858 gen_set_Rc0(ctx, t_ra);
1859 }
1860}
1861
1862
1863static inline void gen_rldicl(DisasContext *ctx, int mbn, int shn)
1864{
1865 uint32_t sh, mb;
1866
1867 sh = SH(ctx->opcode) | (shn << 5);
1868 mb = MB(ctx->opcode) | (mbn << 5);
1869 gen_rldinm(ctx, mb, 63, sh);
1870}
1871GEN_PPC64_R4(rldicl, 0x1E, 0x00);
1872
1873
1874static inline void gen_rldicr(DisasContext *ctx, int men, int shn)
1875{
1876 uint32_t sh, me;
1877
1878 sh = SH(ctx->opcode) | (shn << 5);
1879 me = MB(ctx->opcode) | (men << 5);
1880 gen_rldinm(ctx, 0, me, sh);
1881}
1882GEN_PPC64_R4(rldicr, 0x1E, 0x02);
1883
1884
1885static inline void gen_rldic(DisasContext *ctx, int mbn, int shn)
1886{
1887 uint32_t sh, mb;
1888
1889 sh = SH(ctx->opcode) | (shn << 5);
1890 mb = MB(ctx->opcode) | (mbn << 5);
1891 gen_rldinm(ctx, mb, 63 - sh, sh);
1892}
1893GEN_PPC64_R4(rldic, 0x1E, 0x04);
1894
1895static void gen_rldnm(DisasContext *ctx, int mb, int me)
1896{
1897 TCGv t_ra = cpu_gpr[rA(ctx->opcode)];
1898 TCGv t_rs = cpu_gpr[rS(ctx->opcode)];
1899 TCGv t_rb = cpu_gpr[rB(ctx->opcode)];
1900 TCGv t0;
1901
1902 t0 = tcg_temp_new();
1903 tcg_gen_andi_tl(t0, t_rb, 0x3f);
1904 tcg_gen_rotl_tl(t_ra, t_rs, t0);
1905 tcg_temp_free(t0);
1906
1907 tcg_gen_andi_tl(t_ra, t_ra, MASK(mb, me));
1908 if (unlikely(Rc(ctx->opcode) != 0)) {
1909 gen_set_Rc0(ctx, t_ra);
1910 }
1911}
1912
1913
1914static inline void gen_rldcl(DisasContext *ctx, int mbn)
1915{
1916 uint32_t mb;
1917
1918 mb = MB(ctx->opcode) | (mbn << 5);
1919 gen_rldnm(ctx, mb, 63);
1920}
1921GEN_PPC64_R2(rldcl, 0x1E, 0x08);
1922
1923
1924static inline void gen_rldcr(DisasContext *ctx, int men)
1925{
1926 uint32_t me;
1927
1928 me = MB(ctx->opcode) | (men << 5);
1929 gen_rldnm(ctx, 0, me);
1930}
1931GEN_PPC64_R2(rldcr, 0x1E, 0x09);
1932
1933
1934static void gen_rldimi(DisasContext *ctx, int mbn, int shn)
1935{
1936 TCGv t_ra = cpu_gpr[rA(ctx->opcode)];
1937 TCGv t_rs = cpu_gpr[rS(ctx->opcode)];
1938 uint32_t sh = SH(ctx->opcode) | (shn << 5);
1939 uint32_t mb = MB(ctx->opcode) | (mbn << 5);
1940 uint32_t me = 63 - sh;
1941
1942 if (mb <= me) {
1943 tcg_gen_deposit_tl(t_ra, t_ra, t_rs, sh, me - mb + 1);
1944 } else {
1945 target_ulong mask = MASK(mb, me);
1946 TCGv t1 = tcg_temp_new();
1947
1948 tcg_gen_rotli_tl(t1, t_rs, sh);
1949 tcg_gen_andi_tl(t1, t1, mask);
1950 tcg_gen_andi_tl(t_ra, t_ra, ~mask);
1951 tcg_gen_or_tl(t_ra, t_ra, t1);
1952 tcg_temp_free(t1);
1953 }
1954 if (unlikely(Rc(ctx->opcode) != 0)) {
1955 gen_set_Rc0(ctx, t_ra);
1956 }
1957}
1958GEN_PPC64_R4(rldimi, 0x1E, 0x06);
1959#endif
1960
1961
1962
1963
1964static void gen_slw(DisasContext *ctx)
1965{
1966 TCGv t0, t1;
1967
1968 t0 = tcg_temp_new();
1969
1970#if defined(TARGET_PPC64)
1971 tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3a);
1972 tcg_gen_sari_tl(t0, t0, 0x3f);
1973#else
1974 tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1a);
1975 tcg_gen_sari_tl(t0, t0, 0x1f);
1976#endif
1977 tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
1978 t1 = tcg_temp_new();
1979 tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1f);
1980 tcg_gen_shl_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
1981 tcg_temp_free(t1);
1982 tcg_temp_free(t0);
1983 tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
1984 if (unlikely(Rc(ctx->opcode) != 0))
1985 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1986}
1987
1988
1989static void gen_sraw(DisasContext *ctx)
1990{
1991 gen_helper_sraw(cpu_gpr[rA(ctx->opcode)], cpu_env,
1992 cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1993 if (unlikely(Rc(ctx->opcode) != 0))
1994 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1995}
1996
1997
1998static void gen_srawi(DisasContext *ctx)
1999{
2000 int sh = SH(ctx->opcode);
2001 TCGv dst = cpu_gpr[rA(ctx->opcode)];
2002 TCGv src = cpu_gpr[rS(ctx->opcode)];
2003 if (sh == 0) {
2004 tcg_gen_ext32s_tl(dst, src);
2005 tcg_gen_movi_tl(cpu_ca, 0);
2006 } else {
2007 TCGv t0;
2008 tcg_gen_ext32s_tl(dst, src);
2009 tcg_gen_andi_tl(cpu_ca, dst, (1ULL << sh) - 1);
2010 t0 = tcg_temp_new();
2011 tcg_gen_sari_tl(t0, dst, TARGET_LONG_BITS - 1);
2012 tcg_gen_and_tl(cpu_ca, cpu_ca, t0);
2013 tcg_temp_free(t0);
2014 tcg_gen_setcondi_tl(TCG_COND_NE, cpu_ca, cpu_ca, 0);
2015 tcg_gen_sari_tl(dst, dst, sh);
2016 }
2017 if (unlikely(Rc(ctx->opcode) != 0)) {
2018 gen_set_Rc0(ctx, dst);
2019 }
2020}
2021
2022
2023static void gen_srw(DisasContext *ctx)
2024{
2025 TCGv t0, t1;
2026
2027 t0 = tcg_temp_new();
2028
2029#if defined(TARGET_PPC64)
2030 tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3a);
2031 tcg_gen_sari_tl(t0, t0, 0x3f);
2032#else
2033 tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1a);
2034 tcg_gen_sari_tl(t0, t0, 0x1f);
2035#endif
2036 tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
2037 tcg_gen_ext32u_tl(t0, t0);
2038 t1 = tcg_temp_new();
2039 tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1f);
2040 tcg_gen_shr_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
2041 tcg_temp_free(t1);
2042 tcg_temp_free(t0);
2043 if (unlikely(Rc(ctx->opcode) != 0))
2044 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
2045}
2046
2047#if defined(TARGET_PPC64)
2048
2049static void gen_sld(DisasContext *ctx)
2050{
2051 TCGv t0, t1;
2052
2053 t0 = tcg_temp_new();
2054
2055 tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x39);
2056 tcg_gen_sari_tl(t0, t0, 0x3f);
2057 tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
2058 t1 = tcg_temp_new();
2059 tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x3f);
2060 tcg_gen_shl_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
2061 tcg_temp_free(t1);
2062 tcg_temp_free(t0);
2063 if (unlikely(Rc(ctx->opcode) != 0))
2064 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
2065}
2066
2067
2068static void gen_srad(DisasContext *ctx)
2069{
2070 gen_helper_srad(cpu_gpr[rA(ctx->opcode)], cpu_env,
2071 cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
2072 if (unlikely(Rc(ctx->opcode) != 0))
2073 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
2074}
2075
2076static inline void gen_sradi(DisasContext *ctx, int n)
2077{
2078 int sh = SH(ctx->opcode) + (n << 5);
2079 TCGv dst = cpu_gpr[rA(ctx->opcode)];
2080 TCGv src = cpu_gpr[rS(ctx->opcode)];
2081 if (sh == 0) {
2082 tcg_gen_mov_tl(dst, src);
2083 tcg_gen_movi_tl(cpu_ca, 0);
2084 } else {
2085 TCGv t0;
2086 tcg_gen_andi_tl(cpu_ca, src, (1ULL << sh) - 1);
2087 t0 = tcg_temp_new();
2088 tcg_gen_sari_tl(t0, src, TARGET_LONG_BITS - 1);
2089 tcg_gen_and_tl(cpu_ca, cpu_ca, t0);
2090 tcg_temp_free(t0);
2091 tcg_gen_setcondi_tl(TCG_COND_NE, cpu_ca, cpu_ca, 0);
2092 tcg_gen_sari_tl(dst, src, sh);
2093 }
2094 if (unlikely(Rc(ctx->opcode) != 0)) {
2095 gen_set_Rc0(ctx, dst);
2096 }
2097}
2098
2099static void gen_sradi0(DisasContext *ctx)
2100{
2101 gen_sradi(ctx, 0);
2102}
2103
2104static void gen_sradi1(DisasContext *ctx)
2105{
2106 gen_sradi(ctx, 1);
2107}
2108
2109
2110static void gen_srd(DisasContext *ctx)
2111{
2112 TCGv t0, t1;
2113
2114 t0 = tcg_temp_new();
2115
2116 tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x39);
2117 tcg_gen_sari_tl(t0, t0, 0x3f);
2118 tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
2119 t1 = tcg_temp_new();
2120 tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x3f);
2121 tcg_gen_shr_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
2122 tcg_temp_free(t1);
2123 tcg_temp_free(t0);
2124 if (unlikely(Rc(ctx->opcode) != 0))
2125 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
2126}
2127#endif
2128
2129#if defined(TARGET_PPC64)
2130static void gen_set_cr1_from_fpscr(DisasContext *ctx)
2131{
2132 TCGv_i32 tmp = tcg_temp_new_i32();
2133 tcg_gen_trunc_tl_i32(tmp, cpu_fpscr);
2134 tcg_gen_shri_i32(cpu_crf[1], tmp, 28);
2135 tcg_temp_free_i32(tmp);
2136}
2137#else
2138static void gen_set_cr1_from_fpscr(DisasContext *ctx)
2139{
2140 tcg_gen_shri_tl(cpu_crf[1], cpu_fpscr, 28);
2141}
2142#endif
2143
2144
2145#define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat, set_fprf, type) \
2146static void gen_f##name(DisasContext *ctx) \
2147{ \
2148 if (unlikely(!ctx->fpu_enabled)) { \
2149 gen_exception(ctx, POWERPC_EXCP_FPU); \
2150 return; \
2151 } \
2152 \
2153 gen_update_nip(ctx, ctx->nip - 4); \
2154 gen_reset_fpstatus(); \
2155 gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_env, \
2156 cpu_fpr[rA(ctx->opcode)], \
2157 cpu_fpr[rC(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]); \
2158 if (isfloat) { \
2159 gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_env, \
2160 cpu_fpr[rD(ctx->opcode)]); \
2161 } \
2162 if (set_fprf) { \
2163 gen_compute_fprf(cpu_fpr[rD(ctx->opcode)]); \
2164 } \
2165 if (unlikely(Rc(ctx->opcode) != 0)) { \
2166 gen_set_cr1_from_fpscr(ctx); \
2167 } \
2168}
2169
2170#define GEN_FLOAT_ACB(name, op2, set_fprf, type) \
2171_GEN_FLOAT_ACB(name, name, 0x3F, op2, 0, set_fprf, type); \
2172_GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, set_fprf, type);
2173
2174#define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat, set_fprf, type) \
2175static void gen_f##name(DisasContext *ctx) \
2176{ \
2177 if (unlikely(!ctx->fpu_enabled)) { \
2178 gen_exception(ctx, POWERPC_EXCP_FPU); \
2179 return; \
2180 } \
2181 \
2182 gen_update_nip(ctx, ctx->nip - 4); \
2183 gen_reset_fpstatus(); \
2184 gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_env, \
2185 cpu_fpr[rA(ctx->opcode)], \
2186 cpu_fpr[rB(ctx->opcode)]); \
2187 if (isfloat) { \
2188 gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_env, \
2189 cpu_fpr[rD(ctx->opcode)]); \
2190 } \
2191 if (set_fprf) { \
2192 gen_compute_fprf(cpu_fpr[rD(ctx->opcode)]); \
2193 } \
2194 if (unlikely(Rc(ctx->opcode) != 0)) { \
2195 gen_set_cr1_from_fpscr(ctx); \
2196 } \
2197}
2198#define GEN_FLOAT_AB(name, op2, inval, set_fprf, type) \
2199_GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0, set_fprf, type); \
2200_GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1, set_fprf, type);
2201
2202#define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat, set_fprf, type) \
2203static void gen_f##name(DisasContext *ctx) \
2204{ \
2205 if (unlikely(!ctx->fpu_enabled)) { \
2206 gen_exception(ctx, POWERPC_EXCP_FPU); \
2207 return; \
2208 } \
2209 \
2210 gen_update_nip(ctx, ctx->nip - 4); \
2211 gen_reset_fpstatus(); \
2212 gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_env, \
2213 cpu_fpr[rA(ctx->opcode)], \
2214 cpu_fpr[rC(ctx->opcode)]); \
2215 if (isfloat) { \
2216 gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_env, \
2217 cpu_fpr[rD(ctx->opcode)]); \
2218 } \
2219 if (set_fprf) { \
2220 gen_compute_fprf(cpu_fpr[rD(ctx->opcode)]); \
2221 } \
2222 if (unlikely(Rc(ctx->opcode) != 0)) { \
2223 gen_set_cr1_from_fpscr(ctx); \
2224 } \
2225}
2226#define GEN_FLOAT_AC(name, op2, inval, set_fprf, type) \
2227_GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0, set_fprf, type); \
2228_GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1, set_fprf, type);
2229
2230#define GEN_FLOAT_B(name, op2, op3, set_fprf, type) \
2231static void gen_f##name(DisasContext *ctx) \
2232{ \
2233 if (unlikely(!ctx->fpu_enabled)) { \
2234 gen_exception(ctx, POWERPC_EXCP_FPU); \
2235 return; \
2236 } \
2237 \
2238 gen_update_nip(ctx, ctx->nip - 4); \
2239 gen_reset_fpstatus(); \
2240 gen_helper_f##name(cpu_fpr[rD(ctx->opcode)], cpu_env, \
2241 cpu_fpr[rB(ctx->opcode)]); \
2242 if (set_fprf) { \
2243 gen_compute_fprf(cpu_fpr[rD(ctx->opcode)]); \
2244 } \
2245 if (unlikely(Rc(ctx->opcode) != 0)) { \
2246 gen_set_cr1_from_fpscr(ctx); \
2247 } \
2248}
2249
2250#define GEN_FLOAT_BS(name, op1, op2, set_fprf, type) \
2251static void gen_f##name(DisasContext *ctx) \
2252{ \
2253 if (unlikely(!ctx->fpu_enabled)) { \
2254 gen_exception(ctx, POWERPC_EXCP_FPU); \
2255 return; \
2256 } \
2257 \
2258 gen_update_nip(ctx, ctx->nip - 4); \
2259 gen_reset_fpstatus(); \
2260 gen_helper_f##name(cpu_fpr[rD(ctx->opcode)], cpu_env, \
2261 cpu_fpr[rB(ctx->opcode)]); \
2262 if (set_fprf) { \
2263 gen_compute_fprf(cpu_fpr[rD(ctx->opcode)]); \
2264 } \
2265 if (unlikely(Rc(ctx->opcode) != 0)) { \
2266 gen_set_cr1_from_fpscr(ctx); \
2267 } \
2268}
2269
2270
2271GEN_FLOAT_AB(add, 0x15, 0x000007C0, 1, PPC_FLOAT);
2272
2273GEN_FLOAT_AB(div, 0x12, 0x000007C0, 1, PPC_FLOAT);
2274
2275GEN_FLOAT_AC(mul, 0x19, 0x0000F800, 1, PPC_FLOAT);
2276
2277
2278GEN_FLOAT_BS(re, 0x3F, 0x18, 1, PPC_FLOAT_EXT);
2279
2280
2281GEN_FLOAT_BS(res, 0x3B, 0x18, 1, PPC_FLOAT_FRES);
2282
2283
2284GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A, 1, PPC_FLOAT_FRSQRTE);
2285
2286
2287static void gen_frsqrtes(DisasContext *ctx)
2288{
2289 if (unlikely(!ctx->fpu_enabled)) {
2290 gen_exception(ctx, POWERPC_EXCP_FPU);
2291 return;
2292 }
2293
2294 gen_update_nip(ctx, ctx->nip - 4);
2295 gen_reset_fpstatus();
2296 gen_helper_frsqrte(cpu_fpr[rD(ctx->opcode)], cpu_env,
2297 cpu_fpr[rB(ctx->opcode)]);
2298 gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_env,
2299 cpu_fpr[rD(ctx->opcode)]);
2300 gen_compute_fprf(cpu_fpr[rD(ctx->opcode)]);
2301 if (unlikely(Rc(ctx->opcode) != 0)) {
2302 gen_set_cr1_from_fpscr(ctx);
2303 }
2304}
2305
2306
2307_GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0, 0, PPC_FLOAT_FSEL);
2308
2309GEN_FLOAT_AB(sub, 0x14, 0x000007C0, 1, PPC_FLOAT);
2310
2311
2312
2313static void gen_fsqrt(DisasContext *ctx)
2314{
2315 if (unlikely(!ctx->fpu_enabled)) {
2316 gen_exception(ctx, POWERPC_EXCP_FPU);
2317 return;
2318 }
2319
2320 gen_update_nip(ctx, ctx->nip - 4);
2321 gen_reset_fpstatus();
2322 gen_helper_fsqrt(cpu_fpr[rD(ctx->opcode)], cpu_env,
2323 cpu_fpr[rB(ctx->opcode)]);
2324 gen_compute_fprf(cpu_fpr[rD(ctx->opcode)]);
2325 if (unlikely(Rc(ctx->opcode) != 0)) {
2326 gen_set_cr1_from_fpscr(ctx);
2327 }
2328}
2329
2330static void gen_fsqrts(DisasContext *ctx)
2331{
2332 if (unlikely(!ctx->fpu_enabled)) {
2333 gen_exception(ctx, POWERPC_EXCP_FPU);
2334 return;
2335 }
2336
2337 gen_update_nip(ctx, ctx->nip - 4);
2338 gen_reset_fpstatus();
2339 gen_helper_fsqrt(cpu_fpr[rD(ctx->opcode)], cpu_env,
2340 cpu_fpr[rB(ctx->opcode)]);
2341 gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_env,
2342 cpu_fpr[rD(ctx->opcode)]);
2343 gen_compute_fprf(cpu_fpr[rD(ctx->opcode)]);
2344 if (unlikely(Rc(ctx->opcode) != 0)) {
2345 gen_set_cr1_from_fpscr(ctx);
2346 }
2347}
2348
2349
2350
2351GEN_FLOAT_ACB(madd, 0x1D, 1, PPC_FLOAT);
2352
2353GEN_FLOAT_ACB(msub, 0x1C, 1, PPC_FLOAT);
2354
2355GEN_FLOAT_ACB(nmadd, 0x1F, 1, PPC_FLOAT);
2356
2357GEN_FLOAT_ACB(nmsub, 0x1E, 1, PPC_FLOAT);
2358
2359
2360
2361GEN_FLOAT_B(ctiw, 0x0E, 0x00, 0, PPC_FLOAT);
2362
2363GEN_FLOAT_B(ctiwu, 0x0E, 0x04, 0, PPC2_FP_CVT_ISA206);
2364
2365GEN_FLOAT_B(ctiwz, 0x0F, 0x00, 0, PPC_FLOAT);
2366
2367GEN_FLOAT_B(ctiwuz, 0x0F, 0x04, 0, PPC2_FP_CVT_ISA206);
2368
2369GEN_FLOAT_B(rsp, 0x0C, 0x00, 1, PPC_FLOAT);
2370
2371GEN_FLOAT_B(cfid, 0x0E, 0x1A, 1, PPC2_FP_CVT_S64);
2372
2373GEN_FLOAT_B(cfids, 0x0E, 0x1A, 0, PPC2_FP_CVT_ISA206);
2374
2375GEN_FLOAT_B(cfidu, 0x0E, 0x1E, 0, PPC2_FP_CVT_ISA206);
2376
2377GEN_FLOAT_B(cfidus, 0x0E, 0x1E, 0, PPC2_FP_CVT_ISA206);
2378
2379GEN_FLOAT_B(ctid, 0x0E, 0x19, 0, PPC2_FP_CVT_S64);
2380
2381GEN_FLOAT_B(ctidu, 0x0E, 0x1D, 0, PPC2_FP_CVT_ISA206);
2382
2383GEN_FLOAT_B(ctidz, 0x0F, 0x19, 0, PPC2_FP_CVT_S64);
2384
2385GEN_FLOAT_B(ctiduz, 0x0F, 0x1D, 0, PPC2_FP_CVT_ISA206);
2386
2387
2388GEN_FLOAT_B(rin, 0x08, 0x0C, 1, PPC_FLOAT_EXT);
2389
2390GEN_FLOAT_B(riz, 0x08, 0x0D, 1, PPC_FLOAT_EXT);
2391
2392GEN_FLOAT_B(rip, 0x08, 0x0E, 1, PPC_FLOAT_EXT);
2393
2394GEN_FLOAT_B(rim, 0x08, 0x0F, 1, PPC_FLOAT_EXT);
2395
2396static void gen_ftdiv(DisasContext *ctx)
2397{
2398 if (unlikely(!ctx->fpu_enabled)) {
2399 gen_exception(ctx, POWERPC_EXCP_FPU);
2400 return;
2401 }
2402 gen_helper_ftdiv(cpu_crf[crfD(ctx->opcode)], cpu_fpr[rA(ctx->opcode)],
2403 cpu_fpr[rB(ctx->opcode)]);
2404}
2405
2406static void gen_ftsqrt(DisasContext *ctx)
2407{
2408 if (unlikely(!ctx->fpu_enabled)) {
2409 gen_exception(ctx, POWERPC_EXCP_FPU);
2410 return;
2411 }
2412 gen_helper_ftsqrt(cpu_crf[crfD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
2413}
2414
2415
2416
2417
2418
2419
2420static void gen_fcmpo(DisasContext *ctx)
2421{
2422 TCGv_i32 crf;
2423 if (unlikely(!ctx->fpu_enabled)) {
2424 gen_exception(ctx, POWERPC_EXCP_FPU);
2425 return;
2426 }
2427
2428 gen_update_nip(ctx, ctx->nip - 4);
2429 gen_reset_fpstatus();
2430 crf = tcg_const_i32(crfD(ctx->opcode));
2431 gen_helper_fcmpo(cpu_env, cpu_fpr[rA(ctx->opcode)],
2432 cpu_fpr[rB(ctx->opcode)], crf);
2433 tcg_temp_free_i32(crf);
2434 gen_helper_float_check_status(cpu_env);
2435}
2436
2437
2438static void gen_fcmpu(DisasContext *ctx)
2439{
2440 TCGv_i32 crf;
2441 if (unlikely(!ctx->fpu_enabled)) {
2442 gen_exception(ctx, POWERPC_EXCP_FPU);
2443 return;
2444 }
2445
2446 gen_update_nip(ctx, ctx->nip - 4);
2447 gen_reset_fpstatus();
2448 crf = tcg_const_i32(crfD(ctx->opcode));
2449 gen_helper_fcmpu(cpu_env, cpu_fpr[rA(ctx->opcode)],
2450 cpu_fpr[rB(ctx->opcode)], crf);
2451 tcg_temp_free_i32(crf);
2452 gen_helper_float_check_status(cpu_env);
2453}
2454
2455
2456
2457
2458static void gen_fabs(DisasContext *ctx)
2459{
2460 if (unlikely(!ctx->fpu_enabled)) {
2461 gen_exception(ctx, POWERPC_EXCP_FPU);
2462 return;
2463 }
2464 tcg_gen_andi_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)],
2465 ~(1ULL << 63));
2466 if (unlikely(Rc(ctx->opcode))) {
2467 gen_set_cr1_from_fpscr(ctx);
2468 }
2469}
2470
2471
2472
2473static void gen_fmr(DisasContext *ctx)
2474{
2475 if (unlikely(!ctx->fpu_enabled)) {
2476 gen_exception(ctx, POWERPC_EXCP_FPU);
2477 return;
2478 }
2479 tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
2480 if (unlikely(Rc(ctx->opcode))) {
2481 gen_set_cr1_from_fpscr(ctx);
2482 }
2483}
2484
2485
2486
2487static void gen_fnabs(DisasContext *ctx)
2488{
2489 if (unlikely(!ctx->fpu_enabled)) {
2490 gen_exception(ctx, POWERPC_EXCP_FPU);
2491 return;
2492 }
2493 tcg_gen_ori_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)],
2494 1ULL << 63);
2495 if (unlikely(Rc(ctx->opcode))) {
2496 gen_set_cr1_from_fpscr(ctx);
2497 }
2498}
2499
2500
2501
2502static void gen_fneg(DisasContext *ctx)
2503{
2504 if (unlikely(!ctx->fpu_enabled)) {
2505 gen_exception(ctx, POWERPC_EXCP_FPU);
2506 return;
2507 }
2508 tcg_gen_xori_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)],
2509 1ULL << 63);
2510 if (unlikely(Rc(ctx->opcode))) {
2511 gen_set_cr1_from_fpscr(ctx);
2512 }
2513}
2514
2515
2516
2517static void gen_fcpsgn(DisasContext *ctx)
2518{
2519 if (unlikely(!ctx->fpu_enabled)) {
2520 gen_exception(ctx, POWERPC_EXCP_FPU);
2521 return;
2522 }
2523 tcg_gen_deposit_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rA(ctx->opcode)],
2524 cpu_fpr[rB(ctx->opcode)], 0, 63);
2525 if (unlikely(Rc(ctx->opcode))) {
2526 gen_set_cr1_from_fpscr(ctx);
2527 }
2528}
2529
2530static void gen_fmrgew(DisasContext *ctx)
2531{
2532 TCGv_i64 b0;
2533 if (unlikely(!ctx->fpu_enabled)) {
2534 gen_exception(ctx, POWERPC_EXCP_FPU);
2535 return;
2536 }
2537 b0 = tcg_temp_new_i64();
2538 tcg_gen_shri_i64(b0, cpu_fpr[rB(ctx->opcode)], 32);
2539 tcg_gen_deposit_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rA(ctx->opcode)],
2540 b0, 0, 32);
2541 tcg_temp_free_i64(b0);
2542}
2543
2544static void gen_fmrgow(DisasContext *ctx)
2545{
2546 if (unlikely(!ctx->fpu_enabled)) {
2547 gen_exception(ctx, POWERPC_EXCP_FPU);
2548 return;
2549 }
2550 tcg_gen_deposit_i64(cpu_fpr[rD(ctx->opcode)],
2551 cpu_fpr[rB(ctx->opcode)],
2552 cpu_fpr[rA(ctx->opcode)],
2553 32, 32);
2554}
2555
2556
2557
2558
2559static void gen_mcrfs(DisasContext *ctx)
2560{
2561 TCGv tmp = tcg_temp_new();
2562 TCGv_i32 tmask;
2563 TCGv_i64 tnew_fpscr = tcg_temp_new_i64();
2564 int bfa;
2565 int nibble;
2566 int shift;
2567
2568 if (unlikely(!ctx->fpu_enabled)) {
2569 gen_exception(ctx, POWERPC_EXCP_FPU);
2570 return;
2571 }
2572 bfa = crfS(ctx->opcode);
2573 nibble = 7 - bfa;
2574 shift = 4 * nibble;
2575 tcg_gen_shri_tl(tmp, cpu_fpscr, shift);
2576 tcg_gen_trunc_tl_i32(cpu_crf[crfD(ctx->opcode)], tmp);
2577 tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], 0xf);
2578 tcg_temp_free(tmp);
2579 tcg_gen_extu_tl_i64(tnew_fpscr, cpu_fpscr);
2580
2581 tcg_gen_andi_i64(tnew_fpscr, tnew_fpscr, ~((0xF << shift) & FP_EX_CLEAR_BITS));
2582
2583 tmask = tcg_const_i32(1 << nibble);
2584 gen_helper_store_fpscr(cpu_env, tnew_fpscr, tmask);
2585 tcg_temp_free_i32(tmask);
2586 tcg_temp_free_i64(tnew_fpscr);
2587}
2588
2589
2590static void gen_mffs(DisasContext *ctx)
2591{
2592 if (unlikely(!ctx->fpu_enabled)) {
2593 gen_exception(ctx, POWERPC_EXCP_FPU);
2594 return;
2595 }
2596 gen_reset_fpstatus();
2597 tcg_gen_extu_tl_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpscr);
2598 if (unlikely(Rc(ctx->opcode))) {
2599 gen_set_cr1_from_fpscr(ctx);
2600 }
2601}
2602
2603
2604static void gen_mtfsb0(DisasContext *ctx)
2605{
2606 uint8_t crb;
2607
2608 if (unlikely(!ctx->fpu_enabled)) {
2609 gen_exception(ctx, POWERPC_EXCP_FPU);
2610 return;
2611 }
2612 crb = 31 - crbD(ctx->opcode);
2613 gen_reset_fpstatus();
2614 if (likely(crb != FPSCR_FEX && crb != FPSCR_VX)) {
2615 TCGv_i32 t0;
2616
2617 gen_update_nip(ctx, ctx->nip - 4);
2618 t0 = tcg_const_i32(crb);
2619 gen_helper_fpscr_clrbit(cpu_env, t0);
2620 tcg_temp_free_i32(t0);
2621 }
2622 if (unlikely(Rc(ctx->opcode) != 0)) {
2623 tcg_gen_trunc_tl_i32(cpu_crf[1], cpu_fpscr);
2624 tcg_gen_shri_i32(cpu_crf[1], cpu_crf[1], FPSCR_OX);
2625 }
2626}
2627
2628
2629static void gen_mtfsb1(DisasContext *ctx)
2630{
2631 uint8_t crb;
2632
2633 if (unlikely(!ctx->fpu_enabled)) {
2634 gen_exception(ctx, POWERPC_EXCP_FPU);
2635 return;
2636 }
2637 crb = 31 - crbD(ctx->opcode);
2638 gen_reset_fpstatus();
2639
2640 if (likely(crb != FPSCR_FEX && crb != FPSCR_VX && crb != FPSCR_NI)) {
2641 TCGv_i32 t0;
2642
2643 gen_update_nip(ctx, ctx->nip - 4);
2644 t0 = tcg_const_i32(crb);
2645 gen_helper_fpscr_setbit(cpu_env, t0);
2646 tcg_temp_free_i32(t0);
2647 }
2648 if (unlikely(Rc(ctx->opcode) != 0)) {
2649 tcg_gen_trunc_tl_i32(cpu_crf[1], cpu_fpscr);
2650 tcg_gen_shri_i32(cpu_crf[1], cpu_crf[1], FPSCR_OX);
2651 }
2652
2653 gen_helper_float_check_status(cpu_env);
2654}
2655
2656
2657static void gen_mtfsf(DisasContext *ctx)
2658{
2659 TCGv_i32 t0;
2660 int flm, l, w;
2661
2662 if (unlikely(!ctx->fpu_enabled)) {
2663 gen_exception(ctx, POWERPC_EXCP_FPU);
2664 return;
2665 }
2666 flm = FPFLM(ctx->opcode);
2667 l = FPL(ctx->opcode);
2668 w = FPW(ctx->opcode);
2669 if (unlikely(w & !(ctx->insns_flags2 & PPC2_ISA205))) {
2670 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
2671 return;
2672 }
2673
2674 gen_update_nip(ctx, ctx->nip - 4);
2675 gen_reset_fpstatus();
2676 if (l) {
2677 t0 = tcg_const_i32((ctx->insns_flags2 & PPC2_ISA205) ? 0xffff : 0xff);
2678 } else {
2679 t0 = tcg_const_i32(flm << (w * 8));
2680 }
2681 gen_helper_store_fpscr(cpu_env, cpu_fpr[rB(ctx->opcode)], t0);
2682 tcg_temp_free_i32(t0);
2683 if (unlikely(Rc(ctx->opcode) != 0)) {
2684 tcg_gen_trunc_tl_i32(cpu_crf[1], cpu_fpscr);
2685 tcg_gen_shri_i32(cpu_crf[1], cpu_crf[1], FPSCR_OX);
2686 }
2687
2688 gen_helper_float_check_status(cpu_env);
2689}
2690
2691
2692static void gen_mtfsfi(DisasContext *ctx)
2693{
2694 int bf, sh, w;
2695 TCGv_i64 t0;
2696 TCGv_i32 t1;
2697
2698 if (unlikely(!ctx->fpu_enabled)) {
2699 gen_exception(ctx, POWERPC_EXCP_FPU);
2700 return;
2701 }
2702 w = FPW(ctx->opcode);
2703 bf = FPBF(ctx->opcode);
2704 if (unlikely(w & !(ctx->insns_flags2 & PPC2_ISA205))) {
2705 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
2706 return;
2707 }
2708 sh = (8 * w) + 7 - bf;
2709
2710 gen_update_nip(ctx, ctx->nip - 4);
2711 gen_reset_fpstatus();
2712 t0 = tcg_const_i64(((uint64_t)FPIMM(ctx->opcode)) << (4 * sh));
2713 t1 = tcg_const_i32(1 << sh);
2714 gen_helper_store_fpscr(cpu_env, t0, t1);
2715 tcg_temp_free_i64(t0);
2716 tcg_temp_free_i32(t1);
2717 if (unlikely(Rc(ctx->opcode) != 0)) {
2718 tcg_gen_trunc_tl_i32(cpu_crf[1], cpu_fpscr);
2719 tcg_gen_shri_i32(cpu_crf[1], cpu_crf[1], FPSCR_OX);
2720 }
2721
2722 gen_helper_float_check_status(cpu_env);
2723}
2724
2725
2726
2727static inline void gen_addr_imm_index(DisasContext *ctx, TCGv EA,
2728 target_long maskl)
2729{
2730 target_long simm = SIMM(ctx->opcode);
2731
2732 simm &= ~maskl;
2733 if (rA(ctx->opcode) == 0) {
2734 if (NARROW_MODE(ctx)) {
2735 simm = (uint32_t)simm;
2736 }
2737 tcg_gen_movi_tl(EA, simm);
2738 } else if (likely(simm != 0)) {
2739 tcg_gen_addi_tl(EA, cpu_gpr[rA(ctx->opcode)], simm);
2740 if (NARROW_MODE(ctx)) {
2741 tcg_gen_ext32u_tl(EA, EA);
2742 }
2743 } else {
2744 if (NARROW_MODE(ctx)) {
2745 tcg_gen_ext32u_tl(EA, cpu_gpr[rA(ctx->opcode)]);
2746 } else {
2747 tcg_gen_mov_tl(EA, cpu_gpr[rA(ctx->opcode)]);
2748 }
2749 }
2750}
2751
2752static inline void gen_addr_reg_index(DisasContext *ctx, TCGv EA)
2753{
2754 if (rA(ctx->opcode) == 0) {
2755 if (NARROW_MODE(ctx)) {
2756 tcg_gen_ext32u_tl(EA, cpu_gpr[rB(ctx->opcode)]);
2757 } else {
2758 tcg_gen_mov_tl(EA, cpu_gpr[rB(ctx->opcode)]);
2759 }
2760 } else {
2761 tcg_gen_add_tl(EA, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
2762 if (NARROW_MODE(ctx)) {
2763 tcg_gen_ext32u_tl(EA, EA);
2764 }
2765 }
2766}
2767
2768static inline void gen_addr_register(DisasContext *ctx, TCGv EA)
2769{
2770 if (rA(ctx->opcode) == 0) {
2771 tcg_gen_movi_tl(EA, 0);
2772 } else if (NARROW_MODE(ctx)) {
2773 tcg_gen_ext32u_tl(EA, cpu_gpr[rA(ctx->opcode)]);
2774 } else {
2775 tcg_gen_mov_tl(EA, cpu_gpr[rA(ctx->opcode)]);
2776 }
2777}
2778
2779static inline void gen_addr_add(DisasContext *ctx, TCGv ret, TCGv arg1,
2780 target_long val)
2781{
2782 tcg_gen_addi_tl(ret, arg1, val);
2783 if (NARROW_MODE(ctx)) {
2784 tcg_gen_ext32u_tl(ret, ret);
2785 }
2786}
2787
2788static inline void gen_check_align(DisasContext *ctx, TCGv EA, int mask)
2789{
2790 TCGLabel *l1 = gen_new_label();
2791 TCGv t0 = tcg_temp_new();
2792 TCGv_i32 t1, t2;
2793
2794 gen_update_nip(ctx, ctx->nip - 4);
2795 tcg_gen_andi_tl(t0, EA, mask);
2796 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
2797 t1 = tcg_const_i32(POWERPC_EXCP_ALIGN);
2798 t2 = tcg_const_i32(0);
2799 gen_helper_raise_exception_err(cpu_env, t1, t2);
2800 tcg_temp_free_i32(t1);
2801 tcg_temp_free_i32(t2);
2802 gen_set_label(l1);
2803 tcg_temp_free(t0);
2804}
2805
2806
2807static inline void gen_qemu_ld8u(DisasContext *ctx, TCGv arg1, TCGv arg2)
2808{
2809 tcg_gen_qemu_ld8u(arg1, arg2, ctx->mem_idx);
2810}
2811
2812static inline void gen_qemu_ld16u(DisasContext *ctx, TCGv arg1, TCGv arg2)
2813{
2814 TCGMemOp op = MO_UW | ctx->default_tcg_memop_mask;
2815 tcg_gen_qemu_ld_tl(arg1, arg2, ctx->mem_idx, op);
2816}
2817
2818static inline void gen_qemu_ld16s(DisasContext *ctx, TCGv arg1, TCGv arg2)
2819{
2820 TCGMemOp op = MO_SW | ctx->default_tcg_memop_mask;
2821 tcg_gen_qemu_ld_tl(arg1, arg2, ctx->mem_idx, op);
2822}
2823
2824static inline void gen_qemu_ld32u(DisasContext *ctx, TCGv arg1, TCGv arg2)
2825{
2826 TCGMemOp op = MO_UL | ctx->default_tcg_memop_mask;
2827 tcg_gen_qemu_ld_tl(arg1, arg2, ctx->mem_idx, op);
2828}
2829
2830static void gen_qemu_ld32u_i64(DisasContext *ctx, TCGv_i64 val, TCGv addr)
2831{
2832 TCGv tmp = tcg_temp_new();
2833 gen_qemu_ld32u(ctx, tmp, addr);
2834 tcg_gen_extu_tl_i64(val, tmp);
2835 tcg_temp_free(tmp);
2836}
2837
2838static inline void gen_qemu_ld32s(DisasContext *ctx, TCGv arg1, TCGv arg2)
2839{
2840 TCGMemOp op = MO_SL | ctx->default_tcg_memop_mask;
2841 tcg_gen_qemu_ld_tl(arg1, arg2, ctx->mem_idx, op);
2842}
2843
2844static void gen_qemu_ld32s_i64(DisasContext *ctx, TCGv_i64 val, TCGv addr)
2845{
2846 TCGv tmp = tcg_temp_new();
2847 gen_qemu_ld32s(ctx, tmp, addr);
2848 tcg_gen_ext_tl_i64(val, tmp);
2849 tcg_temp_free(tmp);
2850}
2851
2852static inline void gen_qemu_ld64(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
2853{
2854 TCGMemOp op = MO_Q | ctx->default_tcg_memop_mask;
2855 tcg_gen_qemu_ld_i64(arg1, arg2, ctx->mem_idx, op);
2856}
2857
2858static inline void gen_qemu_st8(DisasContext *ctx, TCGv arg1, TCGv arg2)
2859{
2860 tcg_gen_qemu_st8(arg1, arg2, ctx->mem_idx);
2861}
2862
2863static inline void gen_qemu_st16(DisasContext *ctx, TCGv arg1, TCGv arg2)
2864{
2865 TCGMemOp op = MO_UW | ctx->default_tcg_memop_mask;
2866 tcg_gen_qemu_st_tl(arg1, arg2, ctx->mem_idx, op);
2867}
2868
2869static inline void gen_qemu_st32(DisasContext *ctx, TCGv arg1, TCGv arg2)
2870{
2871 TCGMemOp op = MO_UL | ctx->default_tcg_memop_mask;
2872 tcg_gen_qemu_st_tl(arg1, arg2, ctx->mem_idx, op);
2873}
2874
2875static void gen_qemu_st32_i64(DisasContext *ctx, TCGv_i64 val, TCGv addr)
2876{
2877 TCGv tmp = tcg_temp_new();
2878 tcg_gen_trunc_i64_tl(tmp, val);
2879 gen_qemu_st32(ctx, tmp, addr);
2880 tcg_temp_free(tmp);
2881}
2882
2883static inline void gen_qemu_st64(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
2884{
2885 TCGMemOp op = MO_Q | ctx->default_tcg_memop_mask;
2886 tcg_gen_qemu_st_i64(arg1, arg2, ctx->mem_idx, op);
2887}
2888
2889#define GEN_LD(name, ldop, opc, type) \
2890static void glue(gen_, name)(DisasContext *ctx) \
2891{ \
2892 TCGv EA; \
2893 gen_set_access_type(ctx, ACCESS_INT); \
2894 EA = tcg_temp_new(); \
2895 gen_addr_imm_index(ctx, EA, 0); \
2896 gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA); \
2897 tcg_temp_free(EA); \
2898}
2899
2900#define GEN_LDU(name, ldop, opc, type) \
2901static void glue(gen_, name##u)(DisasContext *ctx) \
2902{ \
2903 TCGv EA; \
2904 if (unlikely(rA(ctx->opcode) == 0 || \
2905 rA(ctx->opcode) == rD(ctx->opcode))) { \
2906 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \
2907 return; \
2908 } \
2909 gen_set_access_type(ctx, ACCESS_INT); \
2910 EA = tcg_temp_new(); \
2911 if (type == PPC_64B) \
2912 gen_addr_imm_index(ctx, EA, 0x03); \
2913 else \
2914 gen_addr_imm_index(ctx, EA, 0); \
2915 gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA); \
2916 tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA); \
2917 tcg_temp_free(EA); \
2918}
2919
2920#define GEN_LDUX(name, ldop, opc2, opc3, type) \
2921static void glue(gen_, name##ux)(DisasContext *ctx) \
2922{ \
2923 TCGv EA; \
2924 if (unlikely(rA(ctx->opcode) == 0 || \
2925 rA(ctx->opcode) == rD(ctx->opcode))) { \
2926 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \
2927 return; \
2928 } \
2929 gen_set_access_type(ctx, ACCESS_INT); \
2930 EA = tcg_temp_new(); \
2931 gen_addr_reg_index(ctx, EA); \
2932 gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA); \
2933 tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA); \
2934 tcg_temp_free(EA); \
2935}
2936
2937#define GEN_LDX_E(name, ldop, opc2, opc3, type, type2, chk) \
2938static void glue(gen_, name##x)(DisasContext *ctx) \
2939{ \
2940 TCGv EA; \
2941 chk; \
2942 gen_set_access_type(ctx, ACCESS_INT); \
2943 EA = tcg_temp_new(); \
2944 gen_addr_reg_index(ctx, EA); \
2945 gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA); \
2946 tcg_temp_free(EA); \
2947}
2948
2949#define GEN_LDX(name, ldop, opc2, opc3, type) \
2950 GEN_LDX_E(name, ldop, opc2, opc3, type, PPC_NONE, CHK_NONE)
2951
2952#define GEN_LDX_HVRM(name, ldop, opc2, opc3, type) \
2953 GEN_LDX_E(name, ldop, opc2, opc3, type, PPC_NONE, CHK_HVRM)
2954
2955#define GEN_LDS(name, ldop, op, type) \
2956GEN_LD(name, ldop, op | 0x20, type); \
2957GEN_LDU(name, ldop, op | 0x21, type); \
2958GEN_LDUX(name, ldop, 0x17, op | 0x01, type); \
2959GEN_LDX(name, ldop, 0x17, op | 0x00, type)
2960
2961
2962GEN_LDS(lbz, ld8u, 0x02, PPC_INTEGER);
2963
2964GEN_LDS(lha, ld16s, 0x0A, PPC_INTEGER);
2965
2966GEN_LDS(lhz, ld16u, 0x08, PPC_INTEGER);
2967
2968GEN_LDS(lwz, ld32u, 0x00, PPC_INTEGER);
2969#if defined(TARGET_PPC64)
2970
2971GEN_LDUX(lwa, ld32s, 0x15, 0x0B, PPC_64B);
2972
2973GEN_LDX(lwa, ld32s, 0x15, 0x0A, PPC_64B);
2974
2975GEN_LDUX(ld, ld64, 0x15, 0x01, PPC_64B);
2976
2977GEN_LDX(ld, ld64, 0x15, 0x00, PPC_64B);
2978
2979
2980GEN_LDX_HVRM(ldcix, ld64, 0x15, 0x1b, PPC_CILDST)
2981GEN_LDX_HVRM(lwzcix, ld32u, 0x15, 0x15, PPC_CILDST)
2982GEN_LDX_HVRM(lhzcix, ld16u, 0x15, 0x19, PPC_CILDST)
2983GEN_LDX_HVRM(lbzcix, ld8u, 0x15, 0x1a, PPC_CILDST)
2984
2985static void gen_ld(DisasContext *ctx)
2986{
2987 TCGv EA;
2988 if (Rc(ctx->opcode)) {
2989 if (unlikely(rA(ctx->opcode) == 0 ||
2990 rA(ctx->opcode) == rD(ctx->opcode))) {
2991 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
2992 return;
2993 }
2994 }
2995 gen_set_access_type(ctx, ACCESS_INT);
2996 EA = tcg_temp_new();
2997 gen_addr_imm_index(ctx, EA, 0x03);
2998 if (ctx->opcode & 0x02) {
2999
3000 gen_qemu_ld32s(ctx, cpu_gpr[rD(ctx->opcode)], EA);
3001 } else {
3002
3003 gen_qemu_ld64(ctx, cpu_gpr[rD(ctx->opcode)], EA);
3004 }
3005 if (Rc(ctx->opcode))
3006 tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);
3007 tcg_temp_free(EA);
3008}
3009
3010
3011static void gen_lq(DisasContext *ctx)
3012{
3013 int ra, rd;
3014 TCGv EA;
3015
3016
3017 bool legal_in_user_mode = (ctx->insns_flags2 & PPC2_LSQ_ISA207) != 0;
3018 bool le_is_supported = (ctx->insns_flags2 & PPC2_LSQ_ISA207) != 0;
3019
3020 if (!legal_in_user_mode && ctx->pr) {
3021 gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC);
3022 return;
3023 }
3024
3025 if (!le_is_supported && ctx->le_mode) {
3026 gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
3027 return;
3028 }
3029
3030 ra = rA(ctx->opcode);
3031 rd = rD(ctx->opcode);
3032 if (unlikely((rd & 1) || rd == ra)) {
3033 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
3034 return;
3035 }
3036
3037 gen_set_access_type(ctx, ACCESS_INT);
3038 EA = tcg_temp_new();
3039 gen_addr_imm_index(ctx, EA, 0x0F);
3040
3041
3042
3043 if (unlikely(ctx->le_mode)) {
3044 gen_qemu_ld64(ctx, cpu_gpr[rd+1], EA);
3045 gen_addr_add(ctx, EA, EA, 8);
3046 gen_qemu_ld64(ctx, cpu_gpr[rd], EA);
3047 } else {
3048 gen_qemu_ld64(ctx, cpu_gpr[rd], EA);
3049 gen_addr_add(ctx, EA, EA, 8);
3050 gen_qemu_ld64(ctx, cpu_gpr[rd+1], EA);
3051 }
3052 tcg_temp_free(EA);
3053}
3054#endif
3055
3056
3057#define GEN_ST(name, stop, opc, type) \
3058static void glue(gen_, name)(DisasContext *ctx) \
3059{ \
3060 TCGv EA; \
3061 gen_set_access_type(ctx, ACCESS_INT); \
3062 EA = tcg_temp_new(); \
3063 gen_addr_imm_index(ctx, EA, 0); \
3064 gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA); \
3065 tcg_temp_free(EA); \
3066}
3067
3068#define GEN_STU(name, stop, opc, type) \
3069static void glue(gen_, stop##u)(DisasContext *ctx) \
3070{ \
3071 TCGv EA; \
3072 if (unlikely(rA(ctx->opcode) == 0)) { \
3073 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \
3074 return; \
3075 } \
3076 gen_set_access_type(ctx, ACCESS_INT); \
3077 EA = tcg_temp_new(); \
3078 if (type == PPC_64B) \
3079 gen_addr_imm_index(ctx, EA, 0x03); \
3080 else \
3081 gen_addr_imm_index(ctx, EA, 0); \
3082 gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA); \
3083 tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA); \
3084 tcg_temp_free(EA); \
3085}
3086
3087#define GEN_STUX(name, stop, opc2, opc3, type) \
3088static void glue(gen_, name##ux)(DisasContext *ctx) \
3089{ \
3090 TCGv EA; \
3091 if (unlikely(rA(ctx->opcode) == 0)) { \
3092 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \
3093 return; \
3094 } \
3095 gen_set_access_type(ctx, ACCESS_INT); \
3096 EA = tcg_temp_new(); \
3097 gen_addr_reg_index(ctx, EA); \
3098 gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA); \
3099 tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA); \
3100 tcg_temp_free(EA); \
3101}
3102
3103#define GEN_STX_E(name, stop, opc2, opc3, type, type2, chk) \
3104static void glue(gen_, name##x)(DisasContext *ctx) \
3105{ \
3106 TCGv EA; \
3107 chk; \
3108 gen_set_access_type(ctx, ACCESS_INT); \
3109 EA = tcg_temp_new(); \
3110 gen_addr_reg_index(ctx, EA); \
3111 gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA); \
3112 tcg_temp_free(EA); \
3113}
3114#define GEN_STX(name, stop, opc2, opc3, type) \
3115 GEN_STX_E(name, stop, opc2, opc3, type, PPC_NONE, CHK_NONE)
3116
3117#define GEN_STX_HVRM(name, stop, opc2, opc3, type) \
3118 GEN_STX_E(name, stop, opc2, opc3, type, PPC_NONE, CHK_HVRM)
3119
3120#define GEN_STS(name, stop, op, type) \
3121GEN_ST(name, stop, op | 0x20, type); \
3122GEN_STU(name, stop, op | 0x21, type); \
3123GEN_STUX(name, stop, 0x17, op | 0x01, type); \
3124GEN_STX(name, stop, 0x17, op | 0x00, type)
3125
3126
3127GEN_STS(stb, st8, 0x06, PPC_INTEGER);
3128
3129GEN_STS(sth, st16, 0x0C, PPC_INTEGER);
3130
3131GEN_STS(stw, st32, 0x04, PPC_INTEGER);
3132#if defined(TARGET_PPC64)
3133GEN_STUX(std, st64, 0x15, 0x05, PPC_64B);
3134GEN_STX(std, st64, 0x15, 0x04, PPC_64B);
3135GEN_STX_HVRM(stdcix, st64, 0x15, 0x1f, PPC_CILDST)
3136GEN_STX_HVRM(stwcix, st32, 0x15, 0x1c, PPC_CILDST)
3137GEN_STX_HVRM(sthcix, st16, 0x15, 0x1d, PPC_CILDST)
3138GEN_STX_HVRM(stbcix, st8, 0x15, 0x1e, PPC_CILDST)
3139
3140static void gen_std(DisasContext *ctx)
3141{
3142 int rs;
3143 TCGv EA;
3144
3145 rs = rS(ctx->opcode);
3146 if ((ctx->opcode & 0x3) == 0x2) {
3147 bool legal_in_user_mode = (ctx->insns_flags2 & PPC2_LSQ_ISA207) != 0;
3148 bool le_is_supported = (ctx->insns_flags2 & PPC2_LSQ_ISA207) != 0;
3149
3150 if (!(ctx->insns_flags & PPC_64BX)) {
3151 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
3152 }
3153
3154 if (!legal_in_user_mode && ctx->pr) {
3155 gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC);
3156 return;
3157 }
3158
3159 if (!le_is_supported && ctx->le_mode) {
3160 gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
3161 return;
3162 }
3163
3164 if (unlikely(rs & 1)) {
3165 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
3166 return;
3167 }
3168 gen_set_access_type(ctx, ACCESS_INT);
3169 EA = tcg_temp_new();
3170 gen_addr_imm_index(ctx, EA, 0x03);
3171
3172
3173
3174 if (unlikely(ctx->le_mode)) {
3175 gen_qemu_st64(ctx, cpu_gpr[rs+1], EA);
3176 gen_addr_add(ctx, EA, EA, 8);
3177 gen_qemu_st64(ctx, cpu_gpr[rs], EA);
3178 } else {
3179 gen_qemu_st64(ctx, cpu_gpr[rs], EA);
3180 gen_addr_add(ctx, EA, EA, 8);
3181 gen_qemu_st64(ctx, cpu_gpr[rs+1], EA);
3182 }
3183 tcg_temp_free(EA);
3184 } else {
3185
3186 if (Rc(ctx->opcode)) {
3187 if (unlikely(rA(ctx->opcode) == 0)) {
3188 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
3189 return;
3190 }
3191 }
3192 gen_set_access_type(ctx, ACCESS_INT);
3193 EA = tcg_temp_new();
3194 gen_addr_imm_index(ctx, EA, 0x03);
3195 gen_qemu_st64(ctx, cpu_gpr[rs], EA);
3196 if (Rc(ctx->opcode))
3197 tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);
3198 tcg_temp_free(EA);
3199 }
3200}
3201#endif
3202
3203
3204
3205static inline void gen_qemu_ld16ur(DisasContext *ctx, TCGv arg1, TCGv arg2)
3206{
3207 TCGMemOp op = MO_UW | (ctx->default_tcg_memop_mask ^ MO_BSWAP);
3208 tcg_gen_qemu_ld_tl(arg1, arg2, ctx->mem_idx, op);
3209}
3210GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER);
3211
3212
3213static inline void gen_qemu_ld32ur(DisasContext *ctx, TCGv arg1, TCGv arg2)
3214{
3215 TCGMemOp op = MO_UL | (ctx->default_tcg_memop_mask ^ MO_BSWAP);
3216 tcg_gen_qemu_ld_tl(arg1, arg2, ctx->mem_idx, op);
3217}
3218GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER);
3219
3220#if defined(TARGET_PPC64)
3221
3222static inline void gen_qemu_ld64ur(DisasContext *ctx, TCGv arg1, TCGv arg2)
3223{
3224 TCGMemOp op = MO_Q | (ctx->default_tcg_memop_mask ^ MO_BSWAP);
3225 tcg_gen_qemu_ld_i64(arg1, arg2, ctx->mem_idx, op);
3226}
3227GEN_LDX_E(ldbr, ld64ur, 0x14, 0x10, PPC_NONE, PPC2_DBRX, CHK_NONE);
3228#endif
3229
3230
3231static inline void gen_qemu_st16r(DisasContext *ctx, TCGv arg1, TCGv arg2)
3232{
3233 TCGMemOp op = MO_UW | (ctx->default_tcg_memop_mask ^ MO_BSWAP);
3234 tcg_gen_qemu_st_tl(arg1, arg2, ctx->mem_idx, op);
3235}
3236GEN_STX(sthbr, st16r, 0x16, 0x1C, PPC_INTEGER);
3237
3238
3239static inline void gen_qemu_st32r(DisasContext *ctx, TCGv arg1, TCGv arg2)
3240{
3241 TCGMemOp op = MO_UL | (ctx->default_tcg_memop_mask ^ MO_BSWAP);
3242 tcg_gen_qemu_st_tl(arg1, arg2, ctx->mem_idx, op);
3243}
3244GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER);
3245
3246#if defined(TARGET_PPC64)
3247
3248static inline void gen_qemu_st64r(DisasContext *ctx, TCGv arg1, TCGv arg2)
3249{
3250 TCGMemOp op = MO_Q | (ctx->default_tcg_memop_mask ^ MO_BSWAP);
3251 tcg_gen_qemu_st_i64(arg1, arg2, ctx->mem_idx, op);
3252}
3253GEN_STX_E(stdbr, st64r, 0x14, 0x14, PPC_NONE, PPC2_DBRX, CHK_NONE);
3254#endif
3255
3256
3257
3258
3259static void gen_lmw(DisasContext *ctx)
3260{
3261 TCGv t0;
3262 TCGv_i32 t1;
3263 gen_set_access_type(ctx, ACCESS_INT);
3264
3265 gen_update_nip(ctx, ctx->nip - 4);
3266 t0 = tcg_temp_new();
3267 t1 = tcg_const_i32(rD(ctx->opcode));
3268 gen_addr_imm_index(ctx, t0, 0);
3269 gen_helper_lmw(cpu_env, t0, t1);
3270 tcg_temp_free(t0);
3271 tcg_temp_free_i32(t1);
3272}
3273
3274
3275static void gen_stmw(DisasContext *ctx)
3276{
3277 TCGv t0;
3278 TCGv_i32 t1;
3279 gen_set_access_type(ctx, ACCESS_INT);
3280
3281 gen_update_nip(ctx, ctx->nip - 4);
3282 t0 = tcg_temp_new();
3283 t1 = tcg_const_i32(rS(ctx->opcode));
3284 gen_addr_imm_index(ctx, t0, 0);
3285 gen_helper_stmw(cpu_env, t0, t1);
3286 tcg_temp_free(t0);
3287 tcg_temp_free_i32(t1);
3288}
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298static void gen_lswi(DisasContext *ctx)
3299{
3300 TCGv t0;
3301 TCGv_i32 t1, t2;
3302 int nb = NB(ctx->opcode);
3303 int start = rD(ctx->opcode);
3304 int ra = rA(ctx->opcode);
3305 int nr;
3306
3307 if (nb == 0)
3308 nb = 32;
3309 nr = (nb + 3) / 4;
3310 if (unlikely(lsw_reg_in_range(start, nr, ra))) {
3311 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_LSWX);
3312 return;
3313 }
3314 gen_set_access_type(ctx, ACCESS_INT);
3315
3316 gen_update_nip(ctx, ctx->nip - 4);
3317 t0 = tcg_temp_new();
3318 gen_addr_register(ctx, t0);
3319 t1 = tcg_const_i32(nb);
3320 t2 = tcg_const_i32(start);
3321 gen_helper_lsw(cpu_env, t0, t1, t2);
3322 tcg_temp_free(t0);
3323 tcg_temp_free_i32(t1);
3324 tcg_temp_free_i32(t2);
3325}
3326
3327
3328static void gen_lswx(DisasContext *ctx)
3329{
3330 TCGv t0;
3331 TCGv_i32 t1, t2, t3;
3332 gen_set_access_type(ctx, ACCESS_INT);
3333
3334 gen_update_nip(ctx, ctx->nip - 4);
3335 t0 = tcg_temp_new();
3336 gen_addr_reg_index(ctx, t0);
3337 t1 = tcg_const_i32(rD(ctx->opcode));
3338 t2 = tcg_const_i32(rA(ctx->opcode));
3339 t3 = tcg_const_i32(rB(ctx->opcode));
3340 gen_helper_lswx(cpu_env, t0, t1, t2, t3);
3341 tcg_temp_free(t0);
3342 tcg_temp_free_i32(t1);
3343 tcg_temp_free_i32(t2);
3344 tcg_temp_free_i32(t3);
3345}
3346
3347
3348static void gen_stswi(DisasContext *ctx)
3349{
3350 TCGv t0;
3351 TCGv_i32 t1, t2;
3352 int nb = NB(ctx->opcode);
3353 gen_set_access_type(ctx, ACCESS_INT);
3354
3355 gen_update_nip(ctx, ctx->nip - 4);
3356 t0 = tcg_temp_new();
3357 gen_addr_register(ctx, t0);
3358 if (nb == 0)
3359 nb = 32;
3360 t1 = tcg_const_i32(nb);
3361 t2 = tcg_const_i32(rS(ctx->opcode));
3362 gen_helper_stsw(cpu_env, t0, t1, t2);
3363 tcg_temp_free(t0);
3364 tcg_temp_free_i32(t1);
3365 tcg_temp_free_i32(t2);
3366}
3367
3368
3369static void gen_stswx(DisasContext *ctx)
3370{
3371 TCGv t0;
3372 TCGv_i32 t1, t2;
3373 gen_set_access_type(ctx, ACCESS_INT);
3374
3375 gen_update_nip(ctx, ctx->nip - 4);
3376 t0 = tcg_temp_new();
3377 gen_addr_reg_index(ctx, t0);
3378 t1 = tcg_temp_new_i32();
3379 tcg_gen_trunc_tl_i32(t1, cpu_xer);
3380 tcg_gen_andi_i32(t1, t1, 0x7F);
3381 t2 = tcg_const_i32(rS(ctx->opcode));
3382 gen_helper_stsw(cpu_env, t0, t1, t2);
3383 tcg_temp_free(t0);
3384 tcg_temp_free_i32(t1);
3385 tcg_temp_free_i32(t2);
3386}
3387
3388
3389
3390static void gen_eieio(DisasContext *ctx)
3391{
3392}
3393
3394#if !defined(CONFIG_USER_ONLY)
3395static inline void gen_check_tlb_flush(DisasContext *ctx)
3396{
3397 TCGv_i32 t;
3398 TCGLabel *l;
3399
3400 if (!ctx->lazy_tlb_flush) {
3401 return;
3402 }
3403 l = gen_new_label();
3404 t = tcg_temp_new_i32();
3405 tcg_gen_ld_i32(t, cpu_env, offsetof(CPUPPCState, tlb_need_flush));
3406 tcg_gen_brcondi_i32(TCG_COND_EQ, t, 0, l);
3407 gen_helper_check_tlb_flush(cpu_env);
3408 gen_set_label(l);
3409 tcg_temp_free_i32(t);
3410}
3411#else
3412static inline void gen_check_tlb_flush(DisasContext *ctx) { }
3413#endif
3414
3415
3416static void gen_isync(DisasContext *ctx)
3417{
3418
3419
3420
3421
3422 if (!ctx->pr) {
3423 gen_check_tlb_flush(ctx);
3424 }
3425 gen_stop_exception(ctx);
3426}
3427
3428#define LARX(name, len, loadop) \
3429static void gen_##name(DisasContext *ctx) \
3430{ \
3431 TCGv t0; \
3432 TCGv gpr = cpu_gpr[rD(ctx->opcode)]; \
3433 gen_set_access_type(ctx, ACCESS_RES); \
3434 t0 = tcg_temp_local_new(); \
3435 gen_addr_reg_index(ctx, t0); \
3436 if ((len) > 1) { \
3437 gen_check_align(ctx, t0, (len)-1); \
3438 } \
3439 gen_qemu_##loadop(ctx, gpr, t0); \
3440 tcg_gen_mov_tl(cpu_reserve, t0); \
3441 tcg_gen_st_tl(gpr, cpu_env, offsetof(CPUPPCState, reserve_val)); \
3442 tcg_temp_free(t0); \
3443}
3444
3445
3446LARX(lbarx, 1, ld8u);
3447LARX(lharx, 2, ld16u);
3448LARX(lwarx, 4, ld32u);
3449
3450
3451#if defined(CONFIG_USER_ONLY)
3452static void gen_conditional_store(DisasContext *ctx, TCGv EA,
3453 int reg, int size)
3454{
3455 TCGv t0 = tcg_temp_new();
3456 uint32_t save_exception = ctx->exception;
3457
3458 tcg_gen_st_tl(EA, cpu_env, offsetof(CPUPPCState, reserve_ea));
3459 tcg_gen_movi_tl(t0, (size << 5) | reg);
3460 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUPPCState, reserve_info));
3461 tcg_temp_free(t0);
3462 gen_update_nip(ctx, ctx->nip-4);
3463 ctx->exception = POWERPC_EXCP_BRANCH;
3464 gen_exception(ctx, POWERPC_EXCP_STCX);
3465 ctx->exception = save_exception;
3466}
3467#else
3468static void gen_conditional_store(DisasContext *ctx, TCGv EA,
3469 int reg, int size)
3470{
3471 TCGLabel *l1;
3472
3473 tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
3474 l1 = gen_new_label();
3475 tcg_gen_brcond_tl(TCG_COND_NE, EA, cpu_reserve, l1);
3476 tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 1 << CRF_EQ);
3477#if defined(TARGET_PPC64)
3478 if (size == 8) {
3479 gen_qemu_st64(ctx, cpu_gpr[reg], EA);
3480 } else
3481#endif
3482 if (size == 4) {
3483 gen_qemu_st32(ctx, cpu_gpr[reg], EA);
3484 } else if (size == 2) {
3485 gen_qemu_st16(ctx, cpu_gpr[reg], EA);
3486#if defined(TARGET_PPC64)
3487 } else if (size == 16) {
3488 TCGv gpr1, gpr2 , EA8;
3489 if (unlikely(ctx->le_mode)) {
3490 gpr1 = cpu_gpr[reg+1];
3491 gpr2 = cpu_gpr[reg];
3492 } else {
3493 gpr1 = cpu_gpr[reg];
3494 gpr2 = cpu_gpr[reg+1];
3495 }
3496 gen_qemu_st64(ctx, gpr1, EA);
3497 EA8 = tcg_temp_local_new();
3498 gen_addr_add(ctx, EA8, EA, 8);
3499 gen_qemu_st64(ctx, gpr2, EA8);
3500 tcg_temp_free(EA8);
3501#endif
3502 } else {
3503 gen_qemu_st8(ctx, cpu_gpr[reg], EA);
3504 }
3505 gen_set_label(l1);
3506 tcg_gen_movi_tl(cpu_reserve, -1);
3507}
3508#endif
3509
3510#define STCX(name, len) \
3511static void gen_##name(DisasContext *ctx) \
3512{ \
3513 TCGv t0; \
3514 if (unlikely((len == 16) && (rD(ctx->opcode) & 1))) { \
3515 gen_inval_exception(ctx, \
3516 POWERPC_EXCP_INVAL_INVAL); \
3517 return; \
3518 } \
3519 gen_set_access_type(ctx, ACCESS_RES); \
3520 t0 = tcg_temp_local_new(); \
3521 gen_addr_reg_index(ctx, t0); \
3522 if (len > 1) { \
3523 gen_check_align(ctx, t0, (len)-1); \
3524 } \
3525 gen_conditional_store(ctx, t0, rS(ctx->opcode), len); \
3526 tcg_temp_free(t0); \
3527}
3528
3529STCX(stbcx_, 1);
3530STCX(sthcx_, 2);
3531STCX(stwcx_, 4);
3532
3533#if defined(TARGET_PPC64)
3534
3535LARX(ldarx, 8, ld64);
3536
3537
3538static void gen_lqarx(DisasContext *ctx)
3539{
3540 TCGv EA;
3541 int rd = rD(ctx->opcode);
3542 TCGv gpr1, gpr2;
3543
3544 if (unlikely((rd & 1) || (rd == rA(ctx->opcode)) ||
3545 (rd == rB(ctx->opcode)))) {
3546 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
3547 return;
3548 }
3549
3550 gen_set_access_type(ctx, ACCESS_RES);
3551 EA = tcg_temp_local_new();
3552 gen_addr_reg_index(ctx, EA);
3553 gen_check_align(ctx, EA, 15);
3554 if (unlikely(ctx->le_mode)) {
3555 gpr1 = cpu_gpr[rd+1];
3556 gpr2 = cpu_gpr[rd];
3557 } else {
3558 gpr1 = cpu_gpr[rd];
3559 gpr2 = cpu_gpr[rd+1];
3560 }
3561 gen_qemu_ld64(ctx, gpr1, EA);
3562 tcg_gen_mov_tl(cpu_reserve, EA);
3563
3564 gen_addr_add(ctx, EA, EA, 8);
3565 gen_qemu_ld64(ctx, gpr2, EA);
3566
3567 tcg_gen_st_tl(gpr1, cpu_env, offsetof(CPUPPCState, reserve_val));
3568 tcg_gen_st_tl(gpr2, cpu_env, offsetof(CPUPPCState, reserve_val2));
3569
3570 tcg_temp_free(EA);
3571}
3572
3573
3574STCX(stdcx_, 8);
3575STCX(stqcx_, 16);
3576#endif
3577
3578
3579static void gen_sync(DisasContext *ctx)
3580{
3581 uint32_t l = (ctx->opcode >> 21) & 3;
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591 if (((l == 2) || !(ctx->insns_flags & PPC_64B)) && !ctx->pr) {
3592 gen_check_tlb_flush(ctx);
3593 }
3594}
3595
3596
3597static void gen_wait(DisasContext *ctx)
3598{
3599 TCGv_i32 t0 = tcg_const_i32(1);
3600 tcg_gen_st_i32(t0, cpu_env,
3601 -offsetof(PowerPCCPU, env) + offsetof(CPUState, halted));
3602 tcg_temp_free_i32(t0);
3603
3604 gen_exception_err(ctx, EXCP_HLT, 1);
3605}
3606
3607#if defined(TARGET_PPC64)
3608static void gen_doze(DisasContext *ctx)
3609{
3610#if defined(CONFIG_USER_ONLY)
3611 GEN_PRIV;
3612#else
3613 TCGv_i32 t;
3614
3615 CHK_HV;
3616 t = tcg_const_i32(PPC_PM_DOZE);
3617 gen_helper_pminsn(cpu_env, t);
3618 tcg_temp_free_i32(t);
3619 gen_stop_exception(ctx);
3620#endif
3621}
3622
3623static void gen_nap(DisasContext *ctx)
3624{
3625#if defined(CONFIG_USER_ONLY)
3626 GEN_PRIV;
3627#else
3628 TCGv_i32 t;
3629
3630 CHK_HV;
3631 t = tcg_const_i32(PPC_PM_NAP);
3632 gen_helper_pminsn(cpu_env, t);
3633 tcg_temp_free_i32(t);
3634 gen_stop_exception(ctx);
3635#endif
3636}
3637
3638static void gen_sleep(DisasContext *ctx)
3639{
3640#if defined(CONFIG_USER_ONLY)
3641 GEN_PRIV;
3642#else
3643 TCGv_i32 t;
3644
3645 CHK_HV;
3646 t = tcg_const_i32(PPC_PM_SLEEP);
3647 gen_helper_pminsn(cpu_env, t);
3648 tcg_temp_free_i32(t);
3649 gen_stop_exception(ctx);
3650#endif
3651}
3652
3653static void gen_rvwinkle(DisasContext *ctx)
3654{
3655#if defined(CONFIG_USER_ONLY)
3656 GEN_PRIV;
3657#else
3658 TCGv_i32 t;
3659
3660 CHK_HV;
3661 t = tcg_const_i32(PPC_PM_RVWINKLE);
3662 gen_helper_pminsn(cpu_env, t);
3663 tcg_temp_free_i32(t);
3664 gen_stop_exception(ctx);
3665#endif
3666}
3667#endif
3668
3669
3670#define GEN_LDF(name, ldop, opc, type) \
3671static void glue(gen_, name)(DisasContext *ctx) \
3672{ \
3673 TCGv EA; \
3674 if (unlikely(!ctx->fpu_enabled)) { \
3675 gen_exception(ctx, POWERPC_EXCP_FPU); \
3676 return; \
3677 } \
3678 gen_set_access_type(ctx, ACCESS_FLOAT); \
3679 EA = tcg_temp_new(); \
3680 gen_addr_imm_index(ctx, EA, 0); \
3681 gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA); \
3682 tcg_temp_free(EA); \
3683}
3684
3685#define GEN_LDUF(name, ldop, opc, type) \
3686static void glue(gen_, name##u)(DisasContext *ctx) \
3687{ \
3688 TCGv EA; \
3689 if (unlikely(!ctx->fpu_enabled)) { \
3690 gen_exception(ctx, POWERPC_EXCP_FPU); \
3691 return; \
3692 } \
3693 if (unlikely(rA(ctx->opcode) == 0)) { \
3694 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \
3695 return; \
3696 } \
3697 gen_set_access_type(ctx, ACCESS_FLOAT); \
3698 EA = tcg_temp_new(); \
3699 gen_addr_imm_index(ctx, EA, 0); \
3700 gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA); \
3701 tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA); \
3702 tcg_temp_free(EA); \
3703}
3704
3705#define GEN_LDUXF(name, ldop, opc, type) \
3706static void glue(gen_, name##ux)(DisasContext *ctx) \
3707{ \
3708 TCGv EA; \
3709 if (unlikely(!ctx->fpu_enabled)) { \
3710 gen_exception(ctx, POWERPC_EXCP_FPU); \
3711 return; \
3712 } \
3713 if (unlikely(rA(ctx->opcode) == 0)) { \
3714 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \
3715 return; \
3716 } \
3717 gen_set_access_type(ctx, ACCESS_FLOAT); \
3718 EA = tcg_temp_new(); \
3719 gen_addr_reg_index(ctx, EA); \
3720 gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA); \
3721 tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA); \
3722 tcg_temp_free(EA); \
3723}
3724
3725#define GEN_LDXF(name, ldop, opc2, opc3, type) \
3726static void glue(gen_, name##x)(DisasContext *ctx) \
3727{ \
3728 TCGv EA; \
3729 if (unlikely(!ctx->fpu_enabled)) { \
3730 gen_exception(ctx, POWERPC_EXCP_FPU); \
3731 return; \
3732 } \
3733 gen_set_access_type(ctx, ACCESS_FLOAT); \
3734 EA = tcg_temp_new(); \
3735 gen_addr_reg_index(ctx, EA); \
3736 gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA); \
3737 tcg_temp_free(EA); \
3738}
3739
3740#define GEN_LDFS(name, ldop, op, type) \
3741GEN_LDF(name, ldop, op | 0x20, type); \
3742GEN_LDUF(name, ldop, op | 0x21, type); \
3743GEN_LDUXF(name, ldop, op | 0x01, type); \
3744GEN_LDXF(name, ldop, 0x17, op | 0x00, type)
3745
3746static inline void gen_qemu_ld32fs(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
3747{
3748 TCGv t0 = tcg_temp_new();
3749 TCGv_i32 t1 = tcg_temp_new_i32();
3750 gen_qemu_ld32u(ctx, t0, arg2);
3751 tcg_gen_trunc_tl_i32(t1, t0);
3752 tcg_temp_free(t0);
3753 gen_helper_float32_to_float64(arg1, cpu_env, t1);
3754 tcg_temp_free_i32(t1);
3755}
3756
3757
3758GEN_LDFS(lfd, ld64, 0x12, PPC_FLOAT);
3759
3760GEN_LDFS(lfs, ld32fs, 0x10, PPC_FLOAT);
3761
3762
3763static void gen_lfdp(DisasContext *ctx)
3764{
3765 TCGv EA;
3766 if (unlikely(!ctx->fpu_enabled)) {
3767 gen_exception(ctx, POWERPC_EXCP_FPU);
3768 return;
3769 }
3770 gen_set_access_type(ctx, ACCESS_FLOAT);
3771 EA = tcg_temp_new();
3772 gen_addr_imm_index(ctx, EA, 0);
3773
3774
3775 if (unlikely(ctx->le_mode)) {
3776 gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
3777 tcg_gen_addi_tl(EA, EA, 8);
3778 gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
3779 } else {
3780 gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
3781 tcg_gen_addi_tl(EA, EA, 8);
3782 gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
3783 }
3784 tcg_temp_free(EA);
3785}
3786
3787
3788static void gen_lfdpx(DisasContext *ctx)
3789{
3790 TCGv EA;
3791 if (unlikely(!ctx->fpu_enabled)) {
3792 gen_exception(ctx, POWERPC_EXCP_FPU);
3793 return;
3794 }
3795 gen_set_access_type(ctx, ACCESS_FLOAT);
3796 EA = tcg_temp_new();
3797 gen_addr_reg_index(ctx, EA);
3798
3799
3800 if (unlikely(ctx->le_mode)) {
3801 gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
3802 tcg_gen_addi_tl(EA, EA, 8);
3803 gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
3804 } else {
3805 gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
3806 tcg_gen_addi_tl(EA, EA, 8);
3807 gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
3808 }
3809 tcg_temp_free(EA);
3810}
3811
3812
3813static void gen_lfiwax(DisasContext *ctx)
3814{
3815 TCGv EA;
3816 TCGv t0;
3817 if (unlikely(!ctx->fpu_enabled)) {
3818 gen_exception(ctx, POWERPC_EXCP_FPU);
3819 return;
3820 }
3821 gen_set_access_type(ctx, ACCESS_FLOAT);
3822 EA = tcg_temp_new();
3823 t0 = tcg_temp_new();
3824 gen_addr_reg_index(ctx, EA);
3825 gen_qemu_ld32s(ctx, t0, EA);
3826 tcg_gen_ext_tl_i64(cpu_fpr[rD(ctx->opcode)], t0);
3827 tcg_temp_free(EA);
3828 tcg_temp_free(t0);
3829}
3830
3831
3832static void gen_lfiwzx(DisasContext *ctx)
3833{
3834 TCGv EA;
3835 if (unlikely(!ctx->fpu_enabled)) {
3836 gen_exception(ctx, POWERPC_EXCP_FPU);
3837 return;
3838 }
3839 gen_set_access_type(ctx, ACCESS_FLOAT);
3840 EA = tcg_temp_new();
3841 gen_addr_reg_index(ctx, EA);
3842 gen_qemu_ld32u_i64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
3843 tcg_temp_free(EA);
3844}
3845
3846#define GEN_STF(name, stop, opc, type) \
3847static void glue(gen_, name)(DisasContext *ctx) \
3848{ \
3849 TCGv EA; \
3850 if (unlikely(!ctx->fpu_enabled)) { \
3851 gen_exception(ctx, POWERPC_EXCP_FPU); \
3852 return; \
3853 } \
3854 gen_set_access_type(ctx, ACCESS_FLOAT); \
3855 EA = tcg_temp_new(); \
3856 gen_addr_imm_index(ctx, EA, 0); \
3857 gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA); \
3858 tcg_temp_free(EA); \
3859}
3860
3861#define GEN_STUF(name, stop, opc, type) \
3862static void glue(gen_, name##u)(DisasContext *ctx) \
3863{ \
3864 TCGv EA; \
3865 if (unlikely(!ctx->fpu_enabled)) { \
3866 gen_exception(ctx, POWERPC_EXCP_FPU); \
3867 return; \
3868 } \
3869 if (unlikely(rA(ctx->opcode) == 0)) { \
3870 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \
3871 return; \
3872 } \
3873 gen_set_access_type(ctx, ACCESS_FLOAT); \
3874 EA = tcg_temp_new(); \
3875 gen_addr_imm_index(ctx, EA, 0); \
3876 gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA); \
3877 tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA); \
3878 tcg_temp_free(EA); \
3879}
3880
3881#define GEN_STUXF(name, stop, opc, type) \
3882static void glue(gen_, name##ux)(DisasContext *ctx) \
3883{ \
3884 TCGv EA; \
3885 if (unlikely(!ctx->fpu_enabled)) { \
3886 gen_exception(ctx, POWERPC_EXCP_FPU); \
3887 return; \
3888 } \
3889 if (unlikely(rA(ctx->opcode) == 0)) { \
3890 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \
3891 return; \
3892 } \
3893 gen_set_access_type(ctx, ACCESS_FLOAT); \
3894 EA = tcg_temp_new(); \
3895 gen_addr_reg_index(ctx, EA); \
3896 gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA); \
3897 tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA); \
3898 tcg_temp_free(EA); \
3899}
3900
3901#define GEN_STXF(name, stop, opc2, opc3, type) \
3902static void glue(gen_, name##x)(DisasContext *ctx) \
3903{ \
3904 TCGv EA; \
3905 if (unlikely(!ctx->fpu_enabled)) { \
3906 gen_exception(ctx, POWERPC_EXCP_FPU); \
3907 return; \
3908 } \
3909 gen_set_access_type(ctx, ACCESS_FLOAT); \
3910 EA = tcg_temp_new(); \
3911 gen_addr_reg_index(ctx, EA); \
3912 gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA); \
3913 tcg_temp_free(EA); \
3914}
3915
3916#define GEN_STFS(name, stop, op, type) \
3917GEN_STF(name, stop, op | 0x20, type); \
3918GEN_STUF(name, stop, op | 0x21, type); \
3919GEN_STUXF(name, stop, op | 0x01, type); \
3920GEN_STXF(name, stop, 0x17, op | 0x00, type)
3921
3922static inline void gen_qemu_st32fs(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
3923{
3924 TCGv_i32 t0 = tcg_temp_new_i32();
3925 TCGv t1 = tcg_temp_new();
3926 gen_helper_float64_to_float32(t0, cpu_env, arg1);
3927 tcg_gen_extu_i32_tl(t1, t0);
3928 tcg_temp_free_i32(t0);
3929 gen_qemu_st32(ctx, t1, arg2);
3930 tcg_temp_free(t1);
3931}
3932
3933
3934GEN_STFS(stfd, st64, 0x16, PPC_FLOAT);
3935
3936GEN_STFS(stfs, st32fs, 0x14, PPC_FLOAT);
3937
3938
3939static void gen_stfdp(DisasContext *ctx)
3940{
3941 TCGv EA;
3942 if (unlikely(!ctx->fpu_enabled)) {
3943 gen_exception(ctx, POWERPC_EXCP_FPU);
3944 return;
3945 }
3946 gen_set_access_type(ctx, ACCESS_FLOAT);
3947 EA = tcg_temp_new();
3948 gen_addr_imm_index(ctx, EA, 0);
3949
3950
3951 if (unlikely(ctx->le_mode)) {
3952 gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
3953 tcg_gen_addi_tl(EA, EA, 8);
3954 gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
3955 } else {
3956 gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
3957 tcg_gen_addi_tl(EA, EA, 8);
3958 gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
3959 }
3960 tcg_temp_free(EA);
3961}
3962
3963
3964static void gen_stfdpx(DisasContext *ctx)
3965{
3966 TCGv EA;
3967 if (unlikely(!ctx->fpu_enabled)) {
3968 gen_exception(ctx, POWERPC_EXCP_FPU);
3969 return;
3970 }
3971 gen_set_access_type(ctx, ACCESS_FLOAT);
3972 EA = tcg_temp_new();
3973 gen_addr_reg_index(ctx, EA);
3974
3975
3976 if (unlikely(ctx->le_mode)) {
3977 gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
3978 tcg_gen_addi_tl(EA, EA, 8);
3979 gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
3980 } else {
3981 gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
3982 tcg_gen_addi_tl(EA, EA, 8);
3983 gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
3984 }
3985 tcg_temp_free(EA);
3986}
3987
3988
3989static inline void gen_qemu_st32fiw(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
3990{
3991 TCGv t0 = tcg_temp_new();
3992 tcg_gen_trunc_i64_tl(t0, arg1),
3993 gen_qemu_st32(ctx, t0, arg2);
3994 tcg_temp_free(t0);
3995}
3996
3997GEN_STXF(stfiw, st32fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX);
3998
3999static inline void gen_update_cfar(DisasContext *ctx, target_ulong nip)
4000{
4001#if defined(TARGET_PPC64)
4002 if (ctx->has_cfar)
4003 tcg_gen_movi_tl(cpu_cfar, nip);
4004#endif
4005}
4006
4007static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
4008{
4009 if (unlikely(ctx->singlestep_enabled)) {
4010 return false;
4011 }
4012
4013#ifndef CONFIG_USER_ONLY
4014 return (ctx->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
4015#else
4016 return true;
4017#endif
4018}
4019
4020
4021static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
4022{
4023 if (NARROW_MODE(ctx)) {
4024 dest = (uint32_t) dest;
4025 }
4026 if (use_goto_tb(ctx, dest)) {
4027 tcg_gen_goto_tb(n);
4028 tcg_gen_movi_tl(cpu_nip, dest & ~3);
4029 tcg_gen_exit_tb((uintptr_t)ctx->tb + n);
4030 } else {
4031 tcg_gen_movi_tl(cpu_nip, dest & ~3);
4032 if (unlikely(ctx->singlestep_enabled)) {
4033 if ((ctx->singlestep_enabled &
4034 (CPU_BRANCH_STEP | CPU_SINGLE_STEP)) &&
4035 (ctx->exception == POWERPC_EXCP_BRANCH ||
4036 ctx->exception == POWERPC_EXCP_TRACE)) {
4037 target_ulong tmp = ctx->nip;
4038 ctx->nip = dest;
4039 gen_exception(ctx, POWERPC_EXCP_TRACE);
4040 ctx->nip = tmp;
4041 }
4042 if (ctx->singlestep_enabled & GDBSTUB_SINGLE_STEP) {
4043 gen_debug_exception(ctx);
4044 }
4045 }
4046 tcg_gen_exit_tb(0);
4047 }
4048}
4049
4050static inline void gen_setlr(DisasContext *ctx, target_ulong nip)
4051{
4052 if (NARROW_MODE(ctx)) {
4053 nip = (uint32_t)nip;
4054 }
4055 tcg_gen_movi_tl(cpu_lr, nip);
4056}
4057
4058
4059static void gen_b(DisasContext *ctx)
4060{
4061 target_ulong li, target;
4062
4063 ctx->exception = POWERPC_EXCP_BRANCH;
4064
4065 li = LI(ctx->opcode);
4066 li = (li ^ 0x02000000) - 0x02000000;
4067 if (likely(AA(ctx->opcode) == 0)) {
4068 target = ctx->nip + li - 4;
4069 } else {
4070 target = li;
4071 }
4072 if (LK(ctx->opcode)) {
4073 gen_setlr(ctx, ctx->nip);
4074 }
4075 gen_update_cfar(ctx, ctx->nip);
4076 gen_goto_tb(ctx, 0, target);
4077}
4078
4079#define BCOND_IM 0
4080#define BCOND_LR 1
4081#define BCOND_CTR 2
4082#define BCOND_TAR 3
4083
4084static inline void gen_bcond(DisasContext *ctx, int type)
4085{
4086 uint32_t bo = BO(ctx->opcode);
4087 TCGLabel *l1;
4088 TCGv target;
4089
4090 ctx->exception = POWERPC_EXCP_BRANCH;
4091 if (type == BCOND_LR || type == BCOND_CTR || type == BCOND_TAR) {
4092 target = tcg_temp_local_new();
4093 if (type == BCOND_CTR)
4094 tcg_gen_mov_tl(target, cpu_ctr);
4095 else if (type == BCOND_TAR)
4096 gen_load_spr(target, SPR_TAR);
4097 else
4098 tcg_gen_mov_tl(target, cpu_lr);
4099 } else {
4100 TCGV_UNUSED(target);
4101 }
4102 if (LK(ctx->opcode))
4103 gen_setlr(ctx, ctx->nip);
4104 l1 = gen_new_label();
4105 if ((bo & 0x4) == 0) {
4106
4107 TCGv temp = tcg_temp_new();
4108 if (unlikely(type == BCOND_CTR)) {
4109 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
4110 return;
4111 }
4112 tcg_gen_subi_tl(cpu_ctr, cpu_ctr, 1);
4113 if (NARROW_MODE(ctx)) {
4114 tcg_gen_ext32u_tl(temp, cpu_ctr);
4115 } else {
4116 tcg_gen_mov_tl(temp, cpu_ctr);
4117 }
4118 if (bo & 0x2) {
4119 tcg_gen_brcondi_tl(TCG_COND_NE, temp, 0, l1);
4120 } else {
4121 tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1);
4122 }
4123 tcg_temp_free(temp);
4124 }
4125 if ((bo & 0x10) == 0) {
4126
4127 uint32_t bi = BI(ctx->opcode);
4128 uint32_t mask = 0x08 >> (bi & 0x03);
4129 TCGv_i32 temp = tcg_temp_new_i32();
4130
4131 if (bo & 0x8) {
4132 tcg_gen_andi_i32(temp, cpu_crf[bi >> 2], mask);
4133 tcg_gen_brcondi_i32(TCG_COND_EQ, temp, 0, l1);
4134 } else {
4135 tcg_gen_andi_i32(temp, cpu_crf[bi >> 2], mask);
4136 tcg_gen_brcondi_i32(TCG_COND_NE, temp, 0, l1);
4137 }
4138 tcg_temp_free_i32(temp);
4139 }
4140 gen_update_cfar(ctx, ctx->nip);
4141 if (type == BCOND_IM) {
4142 target_ulong li = (target_long)((int16_t)(BD(ctx->opcode)));
4143 if (likely(AA(ctx->opcode) == 0)) {
4144 gen_goto_tb(ctx, 0, ctx->nip + li - 4);
4145 } else {
4146 gen_goto_tb(ctx, 0, li);
4147 }
4148 gen_set_label(l1);
4149 gen_goto_tb(ctx, 1, ctx->nip);
4150 } else {
4151 if (NARROW_MODE(ctx)) {
4152 tcg_gen_andi_tl(cpu_nip, target, (uint32_t)~3);
4153 } else {
4154 tcg_gen_andi_tl(cpu_nip, target, ~3);
4155 }
4156 tcg_gen_exit_tb(0);
4157 gen_set_label(l1);
4158 gen_update_nip(ctx, ctx->nip);
4159 tcg_gen_exit_tb(0);
4160 }
4161 if (type == BCOND_LR || type == BCOND_CTR || type == BCOND_TAR) {
4162 tcg_temp_free(target);
4163 }
4164}
4165
4166static void gen_bc(DisasContext *ctx)
4167{
4168 gen_bcond(ctx, BCOND_IM);
4169}
4170
4171static void gen_bcctr(DisasContext *ctx)
4172{
4173 gen_bcond(ctx, BCOND_CTR);
4174}
4175
4176static void gen_bclr(DisasContext *ctx)
4177{
4178 gen_bcond(ctx, BCOND_LR);
4179}
4180
4181static void gen_bctar(DisasContext *ctx)
4182{
4183 gen_bcond(ctx, BCOND_TAR);
4184}
4185
4186
4187#define GEN_CRLOGIC(name, tcg_op, opc) \
4188static void glue(gen_, name)(DisasContext *ctx) \
4189{ \
4190 uint8_t bitmask; \
4191 int sh; \
4192 TCGv_i32 t0, t1; \
4193 sh = (crbD(ctx->opcode) & 0x03) - (crbA(ctx->opcode) & 0x03); \
4194 t0 = tcg_temp_new_i32(); \
4195 if (sh > 0) \
4196 tcg_gen_shri_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2], sh); \
4197 else if (sh < 0) \
4198 tcg_gen_shli_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2], -sh); \
4199 else \
4200 tcg_gen_mov_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2]); \
4201 t1 = tcg_temp_new_i32(); \
4202 sh = (crbD(ctx->opcode) & 0x03) - (crbB(ctx->opcode) & 0x03); \
4203 if (sh > 0) \
4204 tcg_gen_shri_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2], sh); \
4205 else if (sh < 0) \
4206 tcg_gen_shli_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2], -sh); \
4207 else \
4208 tcg_gen_mov_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2]); \
4209 tcg_op(t0, t0, t1); \
4210 bitmask = 0x08 >> (crbD(ctx->opcode) & 0x03); \
4211 tcg_gen_andi_i32(t0, t0, bitmask); \
4212 tcg_gen_andi_i32(t1, cpu_crf[crbD(ctx->opcode) >> 2], ~bitmask); \
4213 tcg_gen_or_i32(cpu_crf[crbD(ctx->opcode) >> 2], t0, t1); \
4214 tcg_temp_free_i32(t0); \
4215 tcg_temp_free_i32(t1); \
4216}
4217
4218
4219GEN_CRLOGIC(crand, tcg_gen_and_i32, 0x08);
4220
4221GEN_CRLOGIC(crandc, tcg_gen_andc_i32, 0x04);
4222
4223GEN_CRLOGIC(creqv, tcg_gen_eqv_i32, 0x09);
4224
4225GEN_CRLOGIC(crnand, tcg_gen_nand_i32, 0x07);
4226
4227GEN_CRLOGIC(crnor, tcg_gen_nor_i32, 0x01);
4228
4229GEN_CRLOGIC(cror, tcg_gen_or_i32, 0x0E);
4230
4231GEN_CRLOGIC(crorc, tcg_gen_orc_i32, 0x0D);
4232
4233GEN_CRLOGIC(crxor, tcg_gen_xor_i32, 0x06);
4234
4235
4236static void gen_mcrf(DisasContext *ctx)
4237{
4238 tcg_gen_mov_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfS(ctx->opcode)]);
4239}
4240
4241
4242
4243
4244static void gen_rfi(DisasContext *ctx)
4245{
4246#if defined(CONFIG_USER_ONLY)
4247 GEN_PRIV;
4248#else
4249
4250
4251
4252
4253
4254 CHK_SV;
4255 gen_update_cfar(ctx, ctx->nip);
4256 gen_helper_rfi(cpu_env);
4257 gen_sync_exception(ctx);
4258#endif
4259}
4260
4261#if defined(TARGET_PPC64)
4262static void gen_rfid(DisasContext *ctx)
4263{
4264#if defined(CONFIG_USER_ONLY)
4265 GEN_PRIV;
4266#else
4267
4268 CHK_SV;
4269 gen_update_cfar(ctx, ctx->nip);
4270 gen_helper_rfid(cpu_env);
4271 gen_sync_exception(ctx);
4272#endif
4273}
4274
4275static void gen_hrfid(DisasContext *ctx)
4276{
4277#if defined(CONFIG_USER_ONLY)
4278 GEN_PRIV;
4279#else
4280
4281 CHK_HV;
4282 gen_helper_hrfid(cpu_env);
4283 gen_sync_exception(ctx);
4284#endif
4285}
4286#endif
4287
4288
4289#if defined(CONFIG_USER_ONLY)
4290#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL_USER
4291#else
4292#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL
4293#endif
4294static void gen_sc(DisasContext *ctx)
4295{
4296 uint32_t lev;
4297
4298 lev = (ctx->opcode >> 5) & 0x7F;
4299 gen_exception_err(ctx, POWERPC_SYSCALL, lev);
4300}
4301
4302
4303
4304
4305static void gen_tw(DisasContext *ctx)
4306{
4307 TCGv_i32 t0 = tcg_const_i32(TO(ctx->opcode));
4308
4309 gen_update_nip(ctx, ctx->nip);
4310 gen_helper_tw(cpu_env, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
4311 t0);
4312 tcg_temp_free_i32(t0);
4313}
4314
4315
4316static void gen_twi(DisasContext *ctx)
4317{
4318 TCGv t0 = tcg_const_tl(SIMM(ctx->opcode));
4319 TCGv_i32 t1 = tcg_const_i32(TO(ctx->opcode));
4320
4321 gen_update_nip(ctx, ctx->nip);
4322 gen_helper_tw(cpu_env, cpu_gpr[rA(ctx->opcode)], t0, t1);
4323 tcg_temp_free(t0);
4324 tcg_temp_free_i32(t1);
4325}
4326
4327#if defined(TARGET_PPC64)
4328
4329static void gen_td(DisasContext *ctx)
4330{
4331 TCGv_i32 t0 = tcg_const_i32(TO(ctx->opcode));
4332
4333 gen_update_nip(ctx, ctx->nip);
4334 gen_helper_td(cpu_env, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
4335 t0);
4336 tcg_temp_free_i32(t0);
4337}
4338
4339
4340static void gen_tdi(DisasContext *ctx)
4341{
4342 TCGv t0 = tcg_const_tl(SIMM(ctx->opcode));
4343 TCGv_i32 t1 = tcg_const_i32(TO(ctx->opcode));
4344
4345 gen_update_nip(ctx, ctx->nip);
4346 gen_helper_td(cpu_env, cpu_gpr[rA(ctx->opcode)], t0, t1);
4347 tcg_temp_free(t0);
4348 tcg_temp_free_i32(t1);
4349}
4350#endif
4351
4352
4353
4354static void gen_read_xer(TCGv dst)
4355{
4356 TCGv t0 = tcg_temp_new();
4357 TCGv t1 = tcg_temp_new();
4358 TCGv t2 = tcg_temp_new();
4359 tcg_gen_mov_tl(dst, cpu_xer);
4360 tcg_gen_shli_tl(t0, cpu_so, XER_SO);
4361 tcg_gen_shli_tl(t1, cpu_ov, XER_OV);
4362 tcg_gen_shli_tl(t2, cpu_ca, XER_CA);
4363 tcg_gen_or_tl(t0, t0, t1);
4364 tcg_gen_or_tl(dst, dst, t2);
4365 tcg_gen_or_tl(dst, dst, t0);
4366 tcg_temp_free(t0);
4367 tcg_temp_free(t1);
4368 tcg_temp_free(t2);
4369}
4370
4371static void gen_write_xer(TCGv src)
4372{
4373 tcg_gen_andi_tl(cpu_xer, src,
4374 ~((1u << XER_SO) | (1u << XER_OV) | (1u << XER_CA)));
4375 tcg_gen_shri_tl(cpu_so, src, XER_SO);
4376 tcg_gen_shri_tl(cpu_ov, src, XER_OV);
4377 tcg_gen_shri_tl(cpu_ca, src, XER_CA);
4378 tcg_gen_andi_tl(cpu_so, cpu_so, 1);
4379 tcg_gen_andi_tl(cpu_ov, cpu_ov, 1);
4380 tcg_gen_andi_tl(cpu_ca, cpu_ca, 1);
4381}
4382
4383
4384static void gen_mcrxr(DisasContext *ctx)
4385{
4386 TCGv_i32 t0 = tcg_temp_new_i32();
4387 TCGv_i32 t1 = tcg_temp_new_i32();
4388 TCGv_i32 dst = cpu_crf[crfD(ctx->opcode)];
4389
4390 tcg_gen_trunc_tl_i32(t0, cpu_so);
4391 tcg_gen_trunc_tl_i32(t1, cpu_ov);
4392 tcg_gen_trunc_tl_i32(dst, cpu_ca);
4393 tcg_gen_shli_i32(t0, t0, 3);
4394 tcg_gen_shli_i32(t1, t1, 2);
4395 tcg_gen_shli_i32(dst, dst, 1);
4396 tcg_gen_or_i32(dst, dst, t0);
4397 tcg_gen_or_i32(dst, dst, t1);
4398 tcg_temp_free_i32(t0);
4399 tcg_temp_free_i32(t1);
4400
4401 tcg_gen_movi_tl(cpu_so, 0);
4402 tcg_gen_movi_tl(cpu_ov, 0);
4403 tcg_gen_movi_tl(cpu_ca, 0);
4404}
4405
4406
4407static void gen_mfcr(DisasContext *ctx)
4408{
4409 uint32_t crm, crn;
4410
4411 if (likely(ctx->opcode & 0x00100000)) {
4412 crm = CRM(ctx->opcode);
4413 if (likely(crm && ((crm & (crm - 1)) == 0))) {
4414 crn = ctz32 (crm);
4415 tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], cpu_crf[7 - crn]);
4416 tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)],
4417 cpu_gpr[rD(ctx->opcode)], crn * 4);
4418 }
4419 } else {
4420 TCGv_i32 t0 = tcg_temp_new_i32();
4421 tcg_gen_mov_i32(t0, cpu_crf[0]);
4422 tcg_gen_shli_i32(t0, t0, 4);
4423 tcg_gen_or_i32(t0, t0, cpu_crf[1]);
4424 tcg_gen_shli_i32(t0, t0, 4);
4425 tcg_gen_or_i32(t0, t0, cpu_crf[2]);
4426 tcg_gen_shli_i32(t0, t0, 4);
4427 tcg_gen_or_i32(t0, t0, cpu_crf[3]);
4428 tcg_gen_shli_i32(t0, t0, 4);
4429 tcg_gen_or_i32(t0, t0, cpu_crf[4]);
4430 tcg_gen_shli_i32(t0, t0, 4);
4431 tcg_gen_or_i32(t0, t0, cpu_crf[5]);
4432 tcg_gen_shli_i32(t0, t0, 4);
4433 tcg_gen_or_i32(t0, t0, cpu_crf[6]);
4434 tcg_gen_shli_i32(t0, t0, 4);
4435 tcg_gen_or_i32(t0, t0, cpu_crf[7]);
4436 tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0);
4437 tcg_temp_free_i32(t0);
4438 }
4439}
4440
4441
4442static void gen_mfmsr(DisasContext *ctx)
4443{
4444 CHK_SV;
4445 tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_msr);
4446}
4447
4448static void spr_noaccess(DisasContext *ctx, int gprn, int sprn)
4449{
4450#if 0
4451 sprn = ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
4452 printf("ERROR: try to access SPR %d !\n", sprn);
4453#endif
4454}
4455#define SPR_NOACCESS (&spr_noaccess)
4456
4457
4458static inline void gen_op_mfspr(DisasContext *ctx)
4459{
4460 void (*read_cb)(DisasContext *ctx, int gprn, int sprn);
4461 uint32_t sprn = SPR(ctx->opcode);
4462
4463#if defined(CONFIG_USER_ONLY)
4464 read_cb = ctx->spr_cb[sprn].uea_read;
4465#else
4466 if (ctx->pr) {
4467 read_cb = ctx->spr_cb[sprn].uea_read;
4468 } else if (ctx->hv) {
4469 read_cb = ctx->spr_cb[sprn].hea_read;
4470 } else {
4471 read_cb = ctx->spr_cb[sprn].oea_read;
4472 }
4473#endif
4474 if (likely(read_cb != NULL)) {
4475 if (likely(read_cb != SPR_NOACCESS)) {
4476 (*read_cb)(ctx, rD(ctx->opcode), sprn);
4477 } else {
4478
4479
4480
4481
4482
4483 if (sprn != SPR_PVR) {
4484 fprintf(stderr, "Trying to read privileged spr %d (0x%03x) at "
4485 TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
4486 if (qemu_log_separate()) {
4487 qemu_log("Trying to read privileged spr %d (0x%03x) at "
4488 TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
4489 }
4490 }
4491 gen_priv_exception(ctx, POWERPC_EXCP_PRIV_REG);
4492 }
4493 } else {
4494
4495 if ((ctx->insns_flags2 & PPC2_ISA207S) &&
4496 (sprn >= 808 && sprn <= 811)) {
4497
4498 return;
4499 }
4500
4501 fprintf(stderr, "Trying to read invalid spr %d (0x%03x) at "
4502 TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
4503 if (qemu_log_separate()) {
4504 qemu_log("Trying to read invalid spr %d (0x%03x) at "
4505 TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
4506 }
4507
4508
4509
4510
4511 if (sprn & 0x10) {
4512 if (ctx->pr) {
4513 gen_priv_exception(ctx, POWERPC_EXCP_INVAL_SPR);
4514 }
4515 } else {
4516 if (ctx->pr || sprn == 0 || sprn == 4 || sprn == 5 || sprn == 6) {
4517 gen_hvpriv_exception(ctx, POWERPC_EXCP_INVAL_SPR);
4518 }
4519 }
4520 }
4521}
4522
4523static void gen_mfspr(DisasContext *ctx)
4524{
4525 gen_op_mfspr(ctx);
4526}
4527
4528
4529static void gen_mftb(DisasContext *ctx)
4530{
4531 gen_op_mfspr(ctx);
4532}
4533
4534
4535static void gen_mtcrf(DisasContext *ctx)
4536{
4537 uint32_t crm, crn;
4538
4539 crm = CRM(ctx->opcode);
4540 if (likely((ctx->opcode & 0x00100000))) {
4541 if (crm && ((crm & (crm - 1)) == 0)) {
4542 TCGv_i32 temp = tcg_temp_new_i32();
4543 crn = ctz32 (crm);
4544 tcg_gen_trunc_tl_i32(temp, cpu_gpr[rS(ctx->opcode)]);
4545 tcg_gen_shri_i32(temp, temp, crn * 4);
4546 tcg_gen_andi_i32(cpu_crf[7 - crn], temp, 0xf);
4547 tcg_temp_free_i32(temp);
4548 }
4549 } else {
4550 TCGv_i32 temp = tcg_temp_new_i32();
4551 tcg_gen_trunc_tl_i32(temp, cpu_gpr[rS(ctx->opcode)]);
4552 for (crn = 0 ; crn < 8 ; crn++) {
4553 if (crm & (1 << crn)) {
4554 tcg_gen_shri_i32(cpu_crf[7 - crn], temp, crn * 4);
4555 tcg_gen_andi_i32(cpu_crf[7 - crn], cpu_crf[7 - crn], 0xf);
4556 }
4557 }
4558 tcg_temp_free_i32(temp);
4559 }
4560}
4561
4562
4563#if defined(TARGET_PPC64)
4564static void gen_mtmsrd(DisasContext *ctx)
4565{
4566 CHK_SV;
4567
4568#if !defined(CONFIG_USER_ONLY)
4569 if (ctx->opcode & 0x00010000) {
4570
4571 TCGv t0 = tcg_temp_new();
4572 tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1 << MSR_RI) | (1 << MSR_EE));
4573 tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(target_ulong)((1 << MSR_RI) | (1 << MSR_EE)));
4574 tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
4575 tcg_temp_free(t0);
4576 } else {
4577
4578
4579
4580
4581 gen_update_nip(ctx, ctx->nip);
4582 gen_helper_store_msr(cpu_env, cpu_gpr[rS(ctx->opcode)]);
4583
4584
4585 gen_stop_exception(ctx);
4586 }
4587#endif
4588}
4589#endif
4590
4591static void gen_mtmsr(DisasContext *ctx)
4592{
4593 CHK_SV;
4594
4595#if !defined(CONFIG_USER_ONLY)
4596 if (ctx->opcode & 0x00010000) {
4597
4598 TCGv t0 = tcg_temp_new();
4599 tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1 << MSR_RI) | (1 << MSR_EE));
4600 tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(target_ulong)((1 << MSR_RI) | (1 << MSR_EE)));
4601 tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
4602 tcg_temp_free(t0);
4603 } else {
4604 TCGv msr = tcg_temp_new();
4605
4606
4607
4608
4609
4610 gen_update_nip(ctx, ctx->nip);
4611#if defined(TARGET_PPC64)
4612 tcg_gen_deposit_tl(msr, cpu_msr, cpu_gpr[rS(ctx->opcode)], 0, 32);
4613#else
4614 tcg_gen_mov_tl(msr, cpu_gpr[rS(ctx->opcode)]);
4615#endif
4616 gen_helper_store_msr(cpu_env, msr);
4617 tcg_temp_free(msr);
4618
4619
4620 gen_stop_exception(ctx);
4621 }
4622#endif
4623}
4624
4625
4626static void gen_mtspr(DisasContext *ctx)
4627{
4628 void (*write_cb)(DisasContext *ctx, int sprn, int gprn);
4629 uint32_t sprn = SPR(ctx->opcode);
4630
4631#if defined(CONFIG_USER_ONLY)
4632 write_cb = ctx->spr_cb[sprn].uea_write;
4633#else
4634 if (ctx->pr) {
4635 write_cb = ctx->spr_cb[sprn].uea_write;
4636 } else if (ctx->hv) {
4637 write_cb = ctx->spr_cb[sprn].hea_write;
4638 } else {
4639 write_cb = ctx->spr_cb[sprn].oea_write;
4640 }
4641#endif
4642 if (likely(write_cb != NULL)) {
4643 if (likely(write_cb != SPR_NOACCESS)) {
4644 (*write_cb)(ctx, sprn, rS(ctx->opcode));
4645 } else {
4646
4647 fprintf(stderr, "Trying to write privileged spr %d (0x%03x) at "
4648 TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
4649 if (qemu_log_separate()) {
4650 qemu_log("Trying to write privileged spr %d (0x%03x) at "
4651 TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
4652 }
4653 gen_priv_exception(ctx, POWERPC_EXCP_PRIV_REG);
4654 }
4655 } else {
4656
4657 if ((ctx->insns_flags2 & PPC2_ISA207S) &&
4658 (sprn >= 808 && sprn <= 811)) {
4659
4660 return;
4661 }
4662
4663
4664 if (qemu_log_separate()) {
4665 qemu_log("Trying to write invalid spr %d (0x%03x) at "
4666 TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
4667 }
4668 fprintf(stderr, "Trying to write invalid spr %d (0x%03x) at "
4669 TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
4670
4671
4672
4673
4674
4675 if (sprn & 0x10) {
4676 if (ctx->pr) {
4677 gen_priv_exception(ctx, POWERPC_EXCP_INVAL_SPR);
4678 }
4679 } else {
4680 if (ctx->pr || sprn == 0) {
4681 gen_hvpriv_exception(ctx, POWERPC_EXCP_INVAL_SPR);
4682 }
4683 }
4684 }
4685}
4686
4687
4688
4689
4690static void gen_dcbf(DisasContext *ctx)
4691{
4692
4693 TCGv t0;
4694 gen_set_access_type(ctx, ACCESS_CACHE);
4695 t0 = tcg_temp_new();
4696 gen_addr_reg_index(ctx, t0);
4697 gen_qemu_ld8u(ctx, t0, t0);
4698 tcg_temp_free(t0);
4699}
4700
4701
4702static void gen_dcbi(DisasContext *ctx)
4703{
4704#if defined(CONFIG_USER_ONLY)
4705 GEN_PRIV;
4706#else
4707 TCGv EA, val;
4708
4709 CHK_SV;
4710 EA = tcg_temp_new();
4711 gen_set_access_type(ctx, ACCESS_CACHE);
4712 gen_addr_reg_index(ctx, EA);
4713 val = tcg_temp_new();
4714
4715 gen_qemu_ld8u(ctx, val, EA);
4716 gen_qemu_st8(ctx, val, EA);
4717 tcg_temp_free(val);
4718 tcg_temp_free(EA);
4719#endif
4720}
4721
4722
4723static void gen_dcbst(DisasContext *ctx)
4724{
4725
4726 TCGv t0;
4727 gen_set_access_type(ctx, ACCESS_CACHE);
4728 t0 = tcg_temp_new();
4729 gen_addr_reg_index(ctx, t0);
4730 gen_qemu_ld8u(ctx, t0, t0);
4731 tcg_temp_free(t0);
4732}
4733
4734
4735static void gen_dcbt(DisasContext *ctx)
4736{
4737
4738
4739
4740
4741}
4742
4743
4744static void gen_dcbtst(DisasContext *ctx)
4745{
4746
4747
4748
4749
4750}
4751
4752
4753static void gen_dcbtls(DisasContext *ctx)
4754{
4755
4756 TCGv t0 = tcg_temp_new();
4757 gen_load_spr(t0, SPR_Exxx_L1CSR0);
4758 tcg_gen_ori_tl(t0, t0, L1CSR0_CUL);
4759 gen_store_spr(SPR_Exxx_L1CSR0, t0);
4760 tcg_temp_free(t0);
4761}
4762
4763
4764static void gen_dcbz(DisasContext *ctx)
4765{
4766 TCGv tcgv_addr;
4767 TCGv_i32 tcgv_is_dcbzl;
4768 int is_dcbzl = ctx->opcode & 0x00200000 ? 1 : 0;
4769
4770 gen_set_access_type(ctx, ACCESS_CACHE);
4771
4772 gen_update_nip(ctx, ctx->nip - 4);
4773 tcgv_addr = tcg_temp_new();
4774 tcgv_is_dcbzl = tcg_const_i32(is_dcbzl);
4775
4776 gen_addr_reg_index(ctx, tcgv_addr);
4777 gen_helper_dcbz(cpu_env, tcgv_addr, tcgv_is_dcbzl);
4778
4779 tcg_temp_free(tcgv_addr);
4780 tcg_temp_free_i32(tcgv_is_dcbzl);
4781}
4782
4783
4784static void gen_dst(DisasContext *ctx)
4785{
4786 if (rA(ctx->opcode) == 0) {
4787 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_LSWX);
4788 } else {
4789
4790 }
4791}
4792
4793
4794static void gen_dstst(DisasContext *ctx)
4795{
4796 if (rA(ctx->opcode) == 0) {
4797 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_LSWX);
4798 } else {
4799
4800 }
4801
4802}
4803
4804
4805static void gen_dss(DisasContext *ctx)
4806{
4807
4808}
4809
4810
4811static void gen_icbi(DisasContext *ctx)
4812{
4813 TCGv t0;
4814 gen_set_access_type(ctx, ACCESS_CACHE);
4815
4816 gen_update_nip(ctx, ctx->nip - 4);
4817 t0 = tcg_temp_new();
4818 gen_addr_reg_index(ctx, t0);
4819 gen_helper_icbi(cpu_env, t0);
4820 tcg_temp_free(t0);
4821}
4822
4823
4824
4825static void gen_dcba(DisasContext *ctx)
4826{
4827
4828
4829
4830
4831}
4832
4833
4834
4835
4836
4837static void gen_mfsr(DisasContext *ctx)
4838{
4839#if defined(CONFIG_USER_ONLY)
4840 GEN_PRIV;
4841#else
4842 TCGv t0;
4843
4844 CHK_SV;
4845 t0 = tcg_const_tl(SR(ctx->opcode));
4846 gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
4847 tcg_temp_free(t0);
4848#endif
4849}
4850
4851
4852static void gen_mfsrin(DisasContext *ctx)
4853{
4854#if defined(CONFIG_USER_ONLY)
4855 GEN_PRIV;
4856#else
4857 TCGv t0;
4858
4859 CHK_SV;
4860 t0 = tcg_temp_new();
4861 tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
4862 tcg_gen_andi_tl(t0, t0, 0xF);
4863 gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
4864 tcg_temp_free(t0);
4865#endif
4866}
4867
4868
4869static void gen_mtsr(DisasContext *ctx)
4870{
4871#if defined(CONFIG_USER_ONLY)
4872 GEN_PRIV;
4873#else
4874 TCGv t0;
4875
4876 CHK_SV;
4877 t0 = tcg_const_tl(SR(ctx->opcode));
4878 gen_helper_store_sr(cpu_env, t0, cpu_gpr[rS(ctx->opcode)]);
4879 tcg_temp_free(t0);
4880#endif
4881}
4882
4883
4884static void gen_mtsrin(DisasContext *ctx)
4885{
4886#if defined(CONFIG_USER_ONLY)
4887 GEN_PRIV;
4888#else
4889 TCGv t0;
4890 CHK_SV;
4891
4892 t0 = tcg_temp_new();
4893 tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
4894 tcg_gen_andi_tl(t0, t0, 0xF);
4895 gen_helper_store_sr(cpu_env, t0, cpu_gpr[rD(ctx->opcode)]);
4896 tcg_temp_free(t0);
4897#endif
4898}
4899
4900#if defined(TARGET_PPC64)
4901
4902
4903
4904static void gen_mfsr_64b(DisasContext *ctx)
4905{
4906#if defined(CONFIG_USER_ONLY)
4907 GEN_PRIV;
4908#else
4909 TCGv t0;
4910
4911 CHK_SV;
4912 t0 = tcg_const_tl(SR(ctx->opcode));
4913 gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
4914 tcg_temp_free(t0);
4915#endif
4916}
4917
4918
4919static void gen_mfsrin_64b(DisasContext *ctx)
4920{
4921#if defined(CONFIG_USER_ONLY)
4922 GEN_PRIV;
4923#else
4924 TCGv t0;
4925
4926 CHK_SV;
4927 t0 = tcg_temp_new();
4928 tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
4929 tcg_gen_andi_tl(t0, t0, 0xF);
4930 gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
4931 tcg_temp_free(t0);
4932#endif
4933}
4934
4935
4936static void gen_mtsr_64b(DisasContext *ctx)
4937{
4938#if defined(CONFIG_USER_ONLY)
4939 GEN_PRIV;
4940#else
4941 TCGv t0;
4942
4943 CHK_SV;
4944 t0 = tcg_const_tl(SR(ctx->opcode));
4945 gen_helper_store_sr(cpu_env, t0, cpu_gpr[rS(ctx->opcode)]);
4946 tcg_temp_free(t0);
4947#endif
4948}
4949
4950
4951static void gen_mtsrin_64b(DisasContext *ctx)
4952{
4953#if defined(CONFIG_USER_ONLY)
4954 GEN_PRIV;
4955#else
4956 TCGv t0;
4957
4958 CHK_SV;
4959 t0 = tcg_temp_new();
4960 tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
4961 tcg_gen_andi_tl(t0, t0, 0xF);
4962 gen_helper_store_sr(cpu_env, t0, cpu_gpr[rS(ctx->opcode)]);
4963 tcg_temp_free(t0);
4964#endif
4965}
4966
4967
4968static void gen_slbmte(DisasContext *ctx)
4969{
4970#if defined(CONFIG_USER_ONLY)
4971 GEN_PRIV;
4972#else
4973 CHK_SV;
4974
4975 gen_helper_store_slb(cpu_env, cpu_gpr[rB(ctx->opcode)],
4976 cpu_gpr[rS(ctx->opcode)]);
4977#endif
4978}
4979
4980static void gen_slbmfee(DisasContext *ctx)
4981{
4982#if defined(CONFIG_USER_ONLY)
4983 GEN_PRIV;
4984#else
4985 CHK_SV;
4986
4987 gen_helper_load_slb_esid(cpu_gpr[rS(ctx->opcode)], cpu_env,
4988 cpu_gpr[rB(ctx->opcode)]);
4989#endif
4990}
4991
4992static void gen_slbmfev(DisasContext *ctx)
4993{
4994#if defined(CONFIG_USER_ONLY)
4995 GEN_PRIV;
4996#else
4997 CHK_SV;
4998
4999 gen_helper_load_slb_vsid(cpu_gpr[rS(ctx->opcode)], cpu_env,
5000 cpu_gpr[rB(ctx->opcode)]);
5001#endif
5002}
5003
5004static void gen_slbfee_(DisasContext *ctx)
5005{
5006#if defined(CONFIG_USER_ONLY)
5007 gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
5008#else
5009 TCGLabel *l1, *l2;
5010
5011 if (unlikely(ctx->pr)) {
5012 gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
5013 return;
5014 }
5015 gen_helper_find_slb_vsid(cpu_gpr[rS(ctx->opcode)], cpu_env,
5016 cpu_gpr[rB(ctx->opcode)]);
5017 l1 = gen_new_label();
5018 l2 = gen_new_label();
5019 tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
5020 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rS(ctx->opcode)], -1, l1);
5021 tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 1 << CRF_EQ);
5022 tcg_gen_br(l2);
5023 gen_set_label(l1);
5024 tcg_gen_movi_tl(cpu_gpr[rS(ctx->opcode)], 0);
5025 gen_set_label(l2);
5026#endif
5027}
5028#endif
5029
5030
5031
5032
5033
5034static void gen_tlbia(DisasContext *ctx)
5035{
5036#if defined(CONFIG_USER_ONLY)
5037 GEN_PRIV;
5038#else
5039 CHK_HV;
5040
5041 gen_helper_tlbia(cpu_env);
5042#endif
5043}
5044
5045
5046static void gen_tlbiel(DisasContext *ctx)
5047{
5048#if defined(CONFIG_USER_ONLY)
5049 GEN_PRIV;
5050#else
5051 CHK_SV;
5052
5053 gen_helper_tlbie(cpu_env, cpu_gpr[rB(ctx->opcode)]);
5054#endif
5055}
5056
5057
5058static void gen_tlbie(DisasContext *ctx)
5059{
5060#if defined(CONFIG_USER_ONLY)
5061 GEN_PRIV;
5062#else
5063 CHK_HV;
5064
5065 if (NARROW_MODE(ctx)) {
5066 TCGv t0 = tcg_temp_new();
5067 tcg_gen_ext32u_tl(t0, cpu_gpr[rB(ctx->opcode)]);
5068 gen_helper_tlbie(cpu_env, t0);
5069 tcg_temp_free(t0);
5070 } else {
5071 gen_helper_tlbie(cpu_env, cpu_gpr[rB(ctx->opcode)]);
5072 }
5073#endif
5074}
5075
5076
5077static void gen_tlbsync(DisasContext *ctx)
5078{
5079#if defined(CONFIG_USER_ONLY)
5080 GEN_PRIV;
5081#else
5082 CHK_HV;
5083
5084
5085
5086
5087
5088 gen_check_tlb_flush(ctx);
5089#endif
5090}
5091
5092#if defined(TARGET_PPC64)
5093
5094static void gen_slbia(DisasContext *ctx)
5095{
5096#if defined(CONFIG_USER_ONLY)
5097 GEN_PRIV;
5098#else
5099 CHK_SV;
5100
5101 gen_helper_slbia(cpu_env);
5102#endif
5103}
5104
5105
5106static void gen_slbie(DisasContext *ctx)
5107{
5108#if defined(CONFIG_USER_ONLY)
5109 GEN_PRIV;
5110#else
5111 CHK_SV;
5112
5113 gen_helper_slbie(cpu_env, cpu_gpr[rB(ctx->opcode)]);
5114#endif
5115}
5116#endif
5117
5118
5119
5120
5121
5122static void gen_eciwx(DisasContext *ctx)
5123{
5124 TCGv t0;
5125
5126 gen_set_access_type(ctx, ACCESS_EXT);
5127 t0 = tcg_temp_new();
5128 gen_addr_reg_index(ctx, t0);
5129 gen_check_align(ctx, t0, 0x03);
5130 gen_qemu_ld32u(ctx, cpu_gpr[rD(ctx->opcode)], t0);
5131 tcg_temp_free(t0);
5132}
5133
5134
5135static void gen_ecowx(DisasContext *ctx)
5136{
5137 TCGv t0;
5138
5139 gen_set_access_type(ctx, ACCESS_EXT);
5140 t0 = tcg_temp_new();
5141 gen_addr_reg_index(ctx, t0);
5142 gen_check_align(ctx, t0, 0x03);
5143 gen_qemu_st32(ctx, cpu_gpr[rD(ctx->opcode)], t0);
5144 tcg_temp_free(t0);
5145}
5146
5147
5148
5149
5150static void gen_abs(DisasContext *ctx)
5151{
5152 TCGLabel *l1 = gen_new_label();
5153 TCGLabel *l2 = gen_new_label();
5154 tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rA(ctx->opcode)], 0, l1);
5155 tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5156 tcg_gen_br(l2);
5157 gen_set_label(l1);
5158 tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5159 gen_set_label(l2);
5160 if (unlikely(Rc(ctx->opcode) != 0))
5161 gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
5162}
5163
5164
5165static void gen_abso(DisasContext *ctx)
5166{
5167 TCGLabel *l1 = gen_new_label();
5168 TCGLabel *l2 = gen_new_label();
5169 TCGLabel *l3 = gen_new_label();
5170
5171 tcg_gen_movi_tl(cpu_ov, 0);
5172 tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rA(ctx->opcode)], 0, l2);
5173 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rA(ctx->opcode)], 0x80000000, l1);
5174 tcg_gen_movi_tl(cpu_ov, 1);
5175 tcg_gen_movi_tl(cpu_so, 1);
5176 tcg_gen_br(l2);
5177 gen_set_label(l1);
5178 tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5179 tcg_gen_br(l3);
5180 gen_set_label(l2);
5181 tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5182 gen_set_label(l3);
5183 if (unlikely(Rc(ctx->opcode) != 0))
5184 gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
5185}
5186
5187
5188static void gen_clcs(DisasContext *ctx)
5189{
5190 TCGv_i32 t0 = tcg_const_i32(rA(ctx->opcode));
5191 gen_helper_clcs(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
5192 tcg_temp_free_i32(t0);
5193
5194}
5195
5196
5197static void gen_div(DisasContext *ctx)
5198{
5199 gen_helper_div(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
5206static void gen_divo(DisasContext *ctx)
5207{
5208 gen_helper_divo(cpu_gpr[rD(ctx->opcode)], cpu_env, cpu_gpr[rA(ctx->opcode)],
5209 cpu_gpr[rB(ctx->opcode)]);
5210 if (unlikely(Rc(ctx->opcode) != 0))
5211 gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
5212}
5213
5214
5215static void gen_divs(DisasContext *ctx)
5216{
5217 gen_helper_divs(cpu_gpr[rD(ctx->opcode)], cpu_env, cpu_gpr[rA(ctx->opcode)],
5218 cpu_gpr[rB(ctx->opcode)]);
5219 if (unlikely(Rc(ctx->opcode) != 0))
5220 gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
5221}
5222
5223
5224static void gen_divso(DisasContext *ctx)
5225{
5226 gen_helper_divso(cpu_gpr[rD(ctx->opcode)], cpu_env,
5227 cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
5228 if (unlikely(Rc(ctx->opcode) != 0))
5229 gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
5230}
5231
5232
5233static void gen_doz(DisasContext *ctx)
5234{
5235 TCGLabel *l1 = gen_new_label();
5236 TCGLabel *l2 = gen_new_label();
5237 tcg_gen_brcond_tl(TCG_COND_GE, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], l1);
5238 tcg_gen_sub_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5239 tcg_gen_br(l2);
5240 gen_set_label(l1);
5241 tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
5242 gen_set_label(l2);
5243 if (unlikely(Rc(ctx->opcode) != 0))
5244 gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
5245}
5246
5247
5248static void gen_dozo(DisasContext *ctx)
5249{
5250 TCGLabel *l1 = gen_new_label();
5251 TCGLabel *l2 = gen_new_label();
5252 TCGv t0 = tcg_temp_new();
5253 TCGv t1 = tcg_temp_new();
5254 TCGv t2 = tcg_temp_new();
5255
5256 tcg_gen_movi_tl(cpu_ov, 0);
5257 tcg_gen_brcond_tl(TCG_COND_GE, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], l1);
5258 tcg_gen_sub_tl(t0, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5259 tcg_gen_xor_tl(t1, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5260 tcg_gen_xor_tl(t2, cpu_gpr[rA(ctx->opcode)], t0);
5261 tcg_gen_andc_tl(t1, t1, t2);
5262 tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
5263 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l2);
5264 tcg_gen_movi_tl(cpu_ov, 1);
5265 tcg_gen_movi_tl(cpu_so, 1);
5266 tcg_gen_br(l2);
5267 gen_set_label(l1);
5268 tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
5269 gen_set_label(l2);
5270 tcg_temp_free(t0);
5271 tcg_temp_free(t1);
5272 tcg_temp_free(t2);
5273 if (unlikely(Rc(ctx->opcode) != 0))
5274 gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
5275}
5276
5277
5278static void gen_dozi(DisasContext *ctx)
5279{
5280 target_long simm = SIMM(ctx->opcode);
5281 TCGLabel *l1 = gen_new_label();
5282 TCGLabel *l2 = gen_new_label();
5283 tcg_gen_brcondi_tl(TCG_COND_LT, cpu_gpr[rA(ctx->opcode)], simm, l1);
5284 tcg_gen_subfi_tl(cpu_gpr[rD(ctx->opcode)], simm, cpu_gpr[rA(ctx->opcode)]);
5285 tcg_gen_br(l2);
5286 gen_set_label(l1);
5287 tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
5288 gen_set_label(l2);
5289 if (unlikely(Rc(ctx->opcode) != 0))
5290 gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
5291}
5292
5293
5294static void gen_lscbx(DisasContext *ctx)
5295{
5296 TCGv t0 = tcg_temp_new();
5297 TCGv_i32 t1 = tcg_const_i32(rD(ctx->opcode));
5298 TCGv_i32 t2 = tcg_const_i32(rA(ctx->opcode));
5299 TCGv_i32 t3 = tcg_const_i32(rB(ctx->opcode));
5300
5301 gen_addr_reg_index(ctx, t0);
5302
5303 gen_update_nip(ctx, ctx->nip - 4);
5304 gen_helper_lscbx(t0, cpu_env, t0, t1, t2, t3);
5305 tcg_temp_free_i32(t1);
5306 tcg_temp_free_i32(t2);
5307 tcg_temp_free_i32(t3);
5308 tcg_gen_andi_tl(cpu_xer, cpu_xer, ~0x7F);
5309 tcg_gen_or_tl(cpu_xer, cpu_xer, t0);
5310 if (unlikely(Rc(ctx->opcode) != 0))
5311 gen_set_Rc0(ctx, t0);
5312 tcg_temp_free(t0);
5313}
5314
5315
5316static void gen_maskg(DisasContext *ctx)
5317{
5318 TCGLabel *l1 = gen_new_label();
5319 TCGv t0 = tcg_temp_new();
5320 TCGv t1 = tcg_temp_new();
5321 TCGv t2 = tcg_temp_new();
5322 TCGv t3 = tcg_temp_new();
5323 tcg_gen_movi_tl(t3, 0xFFFFFFFF);
5324 tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
5325 tcg_gen_andi_tl(t1, cpu_gpr[rS(ctx->opcode)], 0x1F);
5326 tcg_gen_addi_tl(t2, t0, 1);
5327 tcg_gen_shr_tl(t2, t3, t2);
5328 tcg_gen_shr_tl(t3, t3, t1);
5329 tcg_gen_xor_tl(cpu_gpr[rA(ctx->opcode)], t2, t3);
5330 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
5331 tcg_gen_neg_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5332 gen_set_label(l1);
5333 tcg_temp_free(t0);
5334 tcg_temp_free(t1);
5335 tcg_temp_free(t2);
5336 tcg_temp_free(t3);
5337 if (unlikely(Rc(ctx->opcode) != 0))
5338 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5339}
5340
5341
5342static void gen_maskir(DisasContext *ctx)
5343{
5344 TCGv t0 = tcg_temp_new();
5345 TCGv t1 = tcg_temp_new();
5346 tcg_gen_and_tl(t0, cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
5347 tcg_gen_andc_tl(t1, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
5348 tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5349 tcg_temp_free(t0);
5350 tcg_temp_free(t1);
5351 if (unlikely(Rc(ctx->opcode) != 0))
5352 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5353}
5354
5355
5356static void gen_mul(DisasContext *ctx)
5357{
5358 TCGv_i64 t0 = tcg_temp_new_i64();
5359 TCGv_i64 t1 = tcg_temp_new_i64();
5360 TCGv t2 = tcg_temp_new();
5361 tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
5362 tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
5363 tcg_gen_mul_i64(t0, t0, t1);
5364 tcg_gen_trunc_i64_tl(t2, t0);
5365 gen_store_spr(SPR_MQ, t2);
5366 tcg_gen_shri_i64(t1, t0, 32);
5367 tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t1);
5368 tcg_temp_free_i64(t0);
5369 tcg_temp_free_i64(t1);
5370 tcg_temp_free(t2);
5371 if (unlikely(Rc(ctx->opcode) != 0))
5372 gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
5373}
5374
5375
5376static void gen_mulo(DisasContext *ctx)
5377{
5378 TCGLabel *l1 = gen_new_label();
5379 TCGv_i64 t0 = tcg_temp_new_i64();
5380 TCGv_i64 t1 = tcg_temp_new_i64();
5381 TCGv t2 = tcg_temp_new();
5382
5383 tcg_gen_movi_tl(cpu_ov, 0);
5384 tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
5385 tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
5386 tcg_gen_mul_i64(t0, t0, t1);
5387 tcg_gen_trunc_i64_tl(t2, t0);
5388 gen_store_spr(SPR_MQ, t2);
5389 tcg_gen_shri_i64(t1, t0, 32);
5390 tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t1);
5391 tcg_gen_ext32s_i64(t1, t0);
5392 tcg_gen_brcond_i64(TCG_COND_EQ, t0, t1, l1);
5393 tcg_gen_movi_tl(cpu_ov, 1);
5394 tcg_gen_movi_tl(cpu_so, 1);
5395 gen_set_label(l1);
5396 tcg_temp_free_i64(t0);
5397 tcg_temp_free_i64(t1);
5398 tcg_temp_free(t2);
5399 if (unlikely(Rc(ctx->opcode) != 0))
5400 gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
5401}
5402
5403
5404static void gen_nabs(DisasContext *ctx)
5405{
5406 TCGLabel *l1 = gen_new_label();
5407 TCGLabel *l2 = gen_new_label();
5408 tcg_gen_brcondi_tl(TCG_COND_GT, cpu_gpr[rA(ctx->opcode)], 0, l1);
5409 tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5410 tcg_gen_br(l2);
5411 gen_set_label(l1);
5412 tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5413 gen_set_label(l2);
5414 if (unlikely(Rc(ctx->opcode) != 0))
5415 gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
5416}
5417
5418
5419static void gen_nabso(DisasContext *ctx)
5420{
5421 TCGLabel *l1 = gen_new_label();
5422 TCGLabel *l2 = gen_new_label();
5423 tcg_gen_brcondi_tl(TCG_COND_GT, cpu_gpr[rA(ctx->opcode)], 0, l1);
5424 tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5425 tcg_gen_br(l2);
5426 gen_set_label(l1);
5427 tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5428 gen_set_label(l2);
5429
5430 tcg_gen_movi_tl(cpu_ov, 0);
5431 if (unlikely(Rc(ctx->opcode) != 0))
5432 gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
5433}
5434
5435
5436static void gen_rlmi(DisasContext *ctx)
5437{
5438 uint32_t mb = MB(ctx->opcode);
5439 uint32_t me = ME(ctx->opcode);
5440 TCGv t0 = tcg_temp_new();
5441 tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
5442 tcg_gen_rotl_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
5443 tcg_gen_andi_tl(t0, t0, MASK(mb, me));
5444 tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~MASK(mb, me));
5445 tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], t0);
5446 tcg_temp_free(t0);
5447 if (unlikely(Rc(ctx->opcode) != 0))
5448 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5449}
5450
5451
5452static void gen_rrib(DisasContext *ctx)
5453{
5454 TCGv t0 = tcg_temp_new();
5455 TCGv t1 = tcg_temp_new();
5456 tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
5457 tcg_gen_movi_tl(t1, 0x80000000);
5458 tcg_gen_shr_tl(t1, t1, t0);
5459 tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
5460 tcg_gen_and_tl(t0, t0, t1);
5461 tcg_gen_andc_tl(t1, cpu_gpr[rA(ctx->opcode)], t1);
5462 tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5463 tcg_temp_free(t0);
5464 tcg_temp_free(t1);
5465 if (unlikely(Rc(ctx->opcode) != 0))
5466 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5467}
5468
5469
5470static void gen_sle(DisasContext *ctx)
5471{
5472 TCGv t0 = tcg_temp_new();
5473 TCGv t1 = tcg_temp_new();
5474 tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
5475 tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
5476 tcg_gen_subfi_tl(t1, 32, t1);
5477 tcg_gen_shr_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
5478 tcg_gen_or_tl(t1, t0, t1);
5479 tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
5480 gen_store_spr(SPR_MQ, t1);
5481 tcg_temp_free(t0);
5482 tcg_temp_free(t1);
5483 if (unlikely(Rc(ctx->opcode) != 0))
5484 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5485}
5486
5487
5488static void gen_sleq(DisasContext *ctx)
5489{
5490 TCGv t0 = tcg_temp_new();
5491 TCGv t1 = tcg_temp_new();
5492 TCGv t2 = tcg_temp_new();
5493 tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
5494 tcg_gen_movi_tl(t2, 0xFFFFFFFF);
5495 tcg_gen_shl_tl(t2, t2, t0);
5496 tcg_gen_rotl_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
5497 gen_load_spr(t1, SPR_MQ);
5498 gen_store_spr(SPR_MQ, t0);
5499 tcg_gen_and_tl(t0, t0, t2);
5500 tcg_gen_andc_tl(t1, t1, t2);
5501 tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5502 tcg_temp_free(t0);
5503 tcg_temp_free(t1);
5504 tcg_temp_free(t2);
5505 if (unlikely(Rc(ctx->opcode) != 0))
5506 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5507}
5508
5509
5510static void gen_sliq(DisasContext *ctx)
5511{
5512 int sh = SH(ctx->opcode);
5513 TCGv t0 = tcg_temp_new();
5514 TCGv t1 = tcg_temp_new();
5515 tcg_gen_shli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
5516 tcg_gen_shri_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh);
5517 tcg_gen_or_tl(t1, t0, t1);
5518 tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
5519 gen_store_spr(SPR_MQ, t1);
5520 tcg_temp_free(t0);
5521 tcg_temp_free(t1);
5522 if (unlikely(Rc(ctx->opcode) != 0))
5523 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5524}
5525
5526
5527static void gen_slliq(DisasContext *ctx)
5528{
5529 int sh = SH(ctx->opcode);
5530 TCGv t0 = tcg_temp_new();
5531 TCGv t1 = tcg_temp_new();
5532 tcg_gen_rotli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
5533 gen_load_spr(t1, SPR_MQ);
5534 gen_store_spr(SPR_MQ, t0);
5535 tcg_gen_andi_tl(t0, t0, (0xFFFFFFFFU << sh));
5536 tcg_gen_andi_tl(t1, t1, ~(0xFFFFFFFFU << sh));
5537 tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5538 tcg_temp_free(t0);
5539 tcg_temp_free(t1);
5540 if (unlikely(Rc(ctx->opcode) != 0))
5541 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5542}
5543
5544
5545static void gen_sllq(DisasContext *ctx)
5546{
5547 TCGLabel *l1 = gen_new_label();
5548 TCGLabel *l2 = gen_new_label();
5549 TCGv t0 = tcg_temp_local_new();
5550 TCGv t1 = tcg_temp_local_new();
5551 TCGv t2 = tcg_temp_local_new();
5552 tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F);
5553 tcg_gen_movi_tl(t1, 0xFFFFFFFF);
5554 tcg_gen_shl_tl(t1, t1, t2);
5555 tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20);
5556 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
5557 gen_load_spr(t0, SPR_MQ);
5558 tcg_gen_and_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5559 tcg_gen_br(l2);
5560 gen_set_label(l1);
5561 tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t2);
5562 gen_load_spr(t2, SPR_MQ);
5563 tcg_gen_andc_tl(t1, t2, t1);
5564 tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5565 gen_set_label(l2);
5566 tcg_temp_free(t0);
5567 tcg_temp_free(t1);
5568 tcg_temp_free(t2);
5569 if (unlikely(Rc(ctx->opcode) != 0))
5570 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5571}
5572
5573
5574static void gen_slq(DisasContext *ctx)
5575{
5576 TCGLabel *l1 = gen_new_label();
5577 TCGv t0 = tcg_temp_new();
5578 TCGv t1 = tcg_temp_new();
5579 tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
5580 tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
5581 tcg_gen_subfi_tl(t1, 32, t1);
5582 tcg_gen_shr_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
5583 tcg_gen_or_tl(t1, t0, t1);
5584 gen_store_spr(SPR_MQ, t1);
5585 tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x20);
5586 tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
5587 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5588 tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
5589 gen_set_label(l1);
5590 tcg_temp_free(t0);
5591 tcg_temp_free(t1);
5592 if (unlikely(Rc(ctx->opcode) != 0))
5593 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5594}
5595
5596
5597static void gen_sraiq(DisasContext *ctx)
5598{
5599 int sh = SH(ctx->opcode);
5600 TCGLabel *l1 = gen_new_label();
5601 TCGv t0 = tcg_temp_new();
5602 TCGv t1 = tcg_temp_new();
5603 tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
5604 tcg_gen_shli_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh);
5605 tcg_gen_or_tl(t0, t0, t1);
5606 gen_store_spr(SPR_MQ, t0);
5607 tcg_gen_movi_tl(cpu_ca, 0);
5608 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5609 tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rS(ctx->opcode)], 0, l1);
5610 tcg_gen_movi_tl(cpu_ca, 1);
5611 gen_set_label(l1);
5612 tcg_gen_sari_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], sh);
5613 tcg_temp_free(t0);
5614 tcg_temp_free(t1);
5615 if (unlikely(Rc(ctx->opcode) != 0))
5616 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5617}
5618
5619
5620static void gen_sraq(DisasContext *ctx)
5621{
5622 TCGLabel *l1 = gen_new_label();
5623 TCGLabel *l2 = gen_new_label();
5624 TCGv t0 = tcg_temp_new();
5625 TCGv t1 = tcg_temp_local_new();
5626 TCGv t2 = tcg_temp_local_new();
5627 tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F);
5628 tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t2);
5629 tcg_gen_sar_tl(t1, cpu_gpr[rS(ctx->opcode)], t2);
5630 tcg_gen_subfi_tl(t2, 32, t2);
5631 tcg_gen_shl_tl(t2, cpu_gpr[rS(ctx->opcode)], t2);
5632 tcg_gen_or_tl(t0, t0, t2);
5633 gen_store_spr(SPR_MQ, t0);
5634 tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20);
5635 tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, l1);
5636 tcg_gen_mov_tl(t2, cpu_gpr[rS(ctx->opcode)]);
5637 tcg_gen_sari_tl(t1, cpu_gpr[rS(ctx->opcode)], 31);
5638 gen_set_label(l1);
5639 tcg_temp_free(t0);
5640 tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t1);
5641 tcg_gen_movi_tl(cpu_ca, 0);
5642 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l2);
5643 tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, l2);
5644 tcg_gen_movi_tl(cpu_ca, 1);
5645 gen_set_label(l2);
5646 tcg_temp_free(t1);
5647 tcg_temp_free(t2);
5648 if (unlikely(Rc(ctx->opcode) != 0))
5649 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5650}
5651
5652
5653static 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
5671static void gen_srea(DisasContext *ctx)
5672{
5673 TCGv t0 = tcg_temp_new();
5674 TCGv t1 = tcg_temp_new();
5675 tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
5676 tcg_gen_rotr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
5677 gen_store_spr(SPR_MQ, t0);
5678 tcg_gen_sar_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], t1);
5679 tcg_temp_free(t0);
5680 tcg_temp_free(t1);
5681 if (unlikely(Rc(ctx->opcode) != 0))
5682 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5683}
5684
5685
5686static void gen_sreq(DisasContext *ctx)
5687{
5688 TCGv t0 = tcg_temp_new();
5689 TCGv t1 = tcg_temp_new();
5690 TCGv t2 = tcg_temp_new();
5691 tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
5692 tcg_gen_movi_tl(t1, 0xFFFFFFFF);
5693 tcg_gen_shr_tl(t1, t1, t0);
5694 tcg_gen_rotr_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
5695 gen_load_spr(t2, SPR_MQ);
5696 gen_store_spr(SPR_MQ, t0);
5697 tcg_gen_and_tl(t0, t0, t1);
5698 tcg_gen_andc_tl(t2, t2, t1);
5699 tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t2);
5700 tcg_temp_free(t0);
5701 tcg_temp_free(t1);
5702 tcg_temp_free(t2);
5703 if (unlikely(Rc(ctx->opcode) != 0))
5704 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5705}
5706
5707
5708static void gen_sriq(DisasContext *ctx)
5709{
5710 int sh = SH(ctx->opcode);
5711 TCGv t0 = tcg_temp_new();
5712 TCGv t1 = tcg_temp_new();
5713 tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
5714 tcg_gen_shli_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh);
5715 tcg_gen_or_tl(t1, t0, t1);
5716 tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
5717 gen_store_spr(SPR_MQ, t1);
5718 tcg_temp_free(t0);
5719 tcg_temp_free(t1);
5720 if (unlikely(Rc(ctx->opcode) != 0))
5721 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5722}
5723
5724
5725static void gen_srliq(DisasContext *ctx)
5726{
5727 int sh = SH(ctx->opcode);
5728 TCGv t0 = tcg_temp_new();
5729 TCGv t1 = tcg_temp_new();
5730 tcg_gen_rotri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
5731 gen_load_spr(t1, SPR_MQ);
5732 gen_store_spr(SPR_MQ, t0);
5733 tcg_gen_andi_tl(t0, t0, (0xFFFFFFFFU >> sh));
5734 tcg_gen_andi_tl(t1, t1, ~(0xFFFFFFFFU >> sh));
5735 tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5736 tcg_temp_free(t0);
5737 tcg_temp_free(t1);
5738 if (unlikely(Rc(ctx->opcode) != 0))
5739 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5740}
5741
5742
5743static void gen_srlq(DisasContext *ctx)
5744{
5745 TCGLabel *l1 = gen_new_label();
5746 TCGLabel *l2 = gen_new_label();
5747 TCGv t0 = tcg_temp_local_new();
5748 TCGv t1 = tcg_temp_local_new();
5749 TCGv t2 = tcg_temp_local_new();
5750 tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F);
5751 tcg_gen_movi_tl(t1, 0xFFFFFFFF);
5752 tcg_gen_shr_tl(t2, t1, t2);
5753 tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20);
5754 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
5755 gen_load_spr(t0, SPR_MQ);
5756 tcg_gen_and_tl(cpu_gpr[rA(ctx->opcode)], t0, t2);
5757 tcg_gen_br(l2);
5758 gen_set_label(l1);
5759 tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t2);
5760 tcg_gen_and_tl(t0, t0, t2);
5761 gen_load_spr(t1, SPR_MQ);
5762 tcg_gen_andc_tl(t1, t1, t2);
5763 tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5764 gen_set_label(l2);
5765 tcg_temp_free(t0);
5766 tcg_temp_free(t1);
5767 tcg_temp_free(t2);
5768 if (unlikely(Rc(ctx->opcode) != 0))
5769 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5770}
5771
5772
5773static void gen_srq(DisasContext *ctx)
5774{
5775 TCGLabel *l1 = gen_new_label();
5776 TCGv t0 = tcg_temp_new();
5777 TCGv t1 = tcg_temp_new();
5778 tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
5779 tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
5780 tcg_gen_subfi_tl(t1, 32, t1);
5781 tcg_gen_shl_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
5782 tcg_gen_or_tl(t1, t0, t1);
5783 gen_store_spr(SPR_MQ, t1);
5784 tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x20);
5785 tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
5786 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
5787 tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
5788 gen_set_label(l1);
5789 tcg_temp_free(t0);
5790 tcg_temp_free(t1);
5791 if (unlikely(Rc(ctx->opcode) != 0))
5792 gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5793}
5794
5795
5796
5797
5798static void gen_dsa(DisasContext *ctx)
5799{
5800
5801 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5802}
5803
5804
5805static void gen_esa(DisasContext *ctx)
5806{
5807
5808 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5809}
5810
5811
5812static void gen_mfrom(DisasContext *ctx)
5813{
5814#if defined(CONFIG_USER_ONLY)
5815 GEN_PRIV;
5816#else
5817 CHK_SV;
5818 gen_helper_602_mfrom(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5819#endif
5820}
5821
5822
5823
5824
5825static void gen_tlbld_6xx(DisasContext *ctx)
5826{
5827#if defined(CONFIG_USER_ONLY)
5828 GEN_PRIV;
5829#else
5830 CHK_SV;
5831 gen_helper_6xx_tlbd(cpu_env, cpu_gpr[rB(ctx->opcode)]);
5832#endif
5833}
5834
5835
5836static void gen_tlbli_6xx(DisasContext *ctx)
5837{
5838#if defined(CONFIG_USER_ONLY)
5839 GEN_PRIV;
5840#else
5841 CHK_SV;
5842 gen_helper_6xx_tlbi(cpu_env, cpu_gpr[rB(ctx->opcode)]);
5843#endif
5844}
5845
5846
5847
5848
5849static void gen_tlbld_74xx(DisasContext *ctx)
5850{
5851#if defined(CONFIG_USER_ONLY)
5852 GEN_PRIV;
5853#else
5854 CHK_SV;
5855 gen_helper_74xx_tlbd(cpu_env, cpu_gpr[rB(ctx->opcode)]);
5856#endif
5857}
5858
5859
5860static void gen_tlbli_74xx(DisasContext *ctx)
5861{
5862#if defined(CONFIG_USER_ONLY)
5863 GEN_PRIV;
5864#else
5865 CHK_SV;
5866 gen_helper_74xx_tlbi(cpu_env, cpu_gpr[rB(ctx->opcode)]);
5867#endif
5868}
5869
5870
5871
5872
5873static void gen_clf(DisasContext *ctx)
5874{
5875
5876}
5877
5878
5879static void gen_cli(DisasContext *ctx)
5880{
5881#if defined(CONFIG_USER_ONLY)
5882 GEN_PRIV;
5883#else
5884
5885 CHK_SV;
5886#endif
5887}
5888
5889
5890static void gen_dclst(DisasContext *ctx)
5891{
5892
5893}
5894
5895static void gen_mfsri(DisasContext *ctx)
5896{
5897#if defined(CONFIG_USER_ONLY)
5898 GEN_PRIV;
5899#else
5900 int ra = rA(ctx->opcode);
5901 int rd = rD(ctx->opcode);
5902 TCGv t0;
5903
5904 CHK_SV;
5905 t0 = tcg_temp_new();
5906 gen_addr_reg_index(ctx, t0);
5907 tcg_gen_shri_tl(t0, t0, 28);
5908 tcg_gen_andi_tl(t0, t0, 0xF);
5909 gen_helper_load_sr(cpu_gpr[rd], cpu_env, t0);
5910 tcg_temp_free(t0);
5911 if (ra != 0 && ra != rd)
5912 tcg_gen_mov_tl(cpu_gpr[ra], cpu_gpr[rd]);
5913#endif
5914}
5915
5916static void gen_rac(DisasContext *ctx)
5917{
5918#if defined(CONFIG_USER_ONLY)
5919 GEN_PRIV;
5920#else
5921 TCGv t0;
5922
5923 CHK_SV;
5924 t0 = tcg_temp_new();
5925 gen_addr_reg_index(ctx, t0);
5926 gen_helper_rac(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
5927 tcg_temp_free(t0);
5928#endif
5929}
5930
5931static void gen_rfsvc(DisasContext *ctx)
5932{
5933#if defined(CONFIG_USER_ONLY)
5934 GEN_PRIV;
5935#else
5936 CHK_SV;
5937
5938 gen_helper_rfsvc(cpu_env);
5939 gen_sync_exception(ctx);
5940#endif
5941}
5942
5943
5944
5945
5946
5947
5948
5949static void gen_lfq(DisasContext *ctx)
5950{
5951 int rd = rD(ctx->opcode);
5952 TCGv t0;
5953 gen_set_access_type(ctx, ACCESS_FLOAT);
5954 t0 = tcg_temp_new();
5955 gen_addr_imm_index(ctx, t0, 0);
5956 gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
5957 gen_addr_add(ctx, t0, t0, 8);
5958 gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t0);
5959 tcg_temp_free(t0);
5960}
5961
5962
5963static void gen_lfqu(DisasContext *ctx)
5964{
5965 int ra = rA(ctx->opcode);
5966 int rd = rD(ctx->opcode);
5967 TCGv t0, t1;
5968 gen_set_access_type(ctx, ACCESS_FLOAT);
5969 t0 = tcg_temp_new();
5970 t1 = tcg_temp_new();
5971 gen_addr_imm_index(ctx, t0, 0);
5972 gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
5973 gen_addr_add(ctx, t1, t0, 8);
5974 gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t1);
5975 if (ra != 0)
5976 tcg_gen_mov_tl(cpu_gpr[ra], t0);
5977 tcg_temp_free(t0);
5978 tcg_temp_free(t1);
5979}
5980
5981
5982static void gen_lfqux(DisasContext *ctx)
5983{
5984 int ra = rA(ctx->opcode);
5985 int rd = rD(ctx->opcode);
5986 gen_set_access_type(ctx, ACCESS_FLOAT);
5987 TCGv t0, t1;
5988 t0 = tcg_temp_new();
5989 gen_addr_reg_index(ctx, t0);
5990 gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
5991 t1 = tcg_temp_new();
5992 gen_addr_add(ctx, t1, t0, 8);
5993 gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t1);
5994 tcg_temp_free(t1);
5995 if (ra != 0)
5996 tcg_gen_mov_tl(cpu_gpr[ra], t0);
5997 tcg_temp_free(t0);
5998}
5999
6000
6001static void gen_lfqx(DisasContext *ctx)
6002{
6003 int rd = rD(ctx->opcode);
6004 TCGv t0;
6005 gen_set_access_type(ctx, ACCESS_FLOAT);
6006 t0 = tcg_temp_new();
6007 gen_addr_reg_index(ctx, t0);
6008 gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
6009 gen_addr_add(ctx, t0, t0, 8);
6010 gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t0);
6011 tcg_temp_free(t0);
6012}
6013
6014
6015static void gen_stfq(DisasContext *ctx)
6016{
6017 int rd = rD(ctx->opcode);
6018 TCGv t0;
6019 gen_set_access_type(ctx, ACCESS_FLOAT);
6020 t0 = tcg_temp_new();
6021 gen_addr_imm_index(ctx, t0, 0);
6022 gen_qemu_st64(ctx, cpu_fpr[rd], t0);
6023 gen_addr_add(ctx, t0, t0, 8);
6024 gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t0);
6025 tcg_temp_free(t0);
6026}
6027
6028
6029static void gen_stfqu(DisasContext *ctx)
6030{
6031 int ra = rA(ctx->opcode);
6032 int rd = rD(ctx->opcode);
6033 TCGv t0, t1;
6034 gen_set_access_type(ctx, ACCESS_FLOAT);
6035 t0 = tcg_temp_new();
6036 gen_addr_imm_index(ctx, t0, 0);
6037 gen_qemu_st64(ctx, cpu_fpr[rd], t0);
6038 t1 = tcg_temp_new();
6039 gen_addr_add(ctx, t1, t0, 8);
6040 gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t1);
6041 tcg_temp_free(t1);
6042 if (ra != 0)
6043 tcg_gen_mov_tl(cpu_gpr[ra], t0);
6044 tcg_temp_free(t0);
6045}
6046
6047
6048static void gen_stfqux(DisasContext *ctx)
6049{
6050 int ra = rA(ctx->opcode);
6051 int rd = rD(ctx->opcode);
6052 TCGv t0, t1;
6053 gen_set_access_type(ctx, ACCESS_FLOAT);
6054 t0 = tcg_temp_new();
6055 gen_addr_reg_index(ctx, t0);
6056 gen_qemu_st64(ctx, cpu_fpr[rd], t0);
6057 t1 = tcg_temp_new();
6058 gen_addr_add(ctx, t1, t0, 8);
6059 gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t1);
6060 tcg_temp_free(t1);
6061 if (ra != 0)
6062 tcg_gen_mov_tl(cpu_gpr[ra], t0);
6063 tcg_temp_free(t0);
6064}
6065
6066
6067static void gen_stfqx(DisasContext *ctx)
6068{
6069 int rd = rD(ctx->opcode);
6070 TCGv t0;
6071 gen_set_access_type(ctx, ACCESS_FLOAT);
6072 t0 = tcg_temp_new();
6073 gen_addr_reg_index(ctx, t0);
6074 gen_qemu_st64(ctx, cpu_fpr[rd], t0);
6075 gen_addr_add(ctx, t0, t0, 8);
6076 gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t0);
6077 tcg_temp_free(t0);
6078}
6079
6080
6081
6082
6083static void gen_mfapidi(DisasContext *ctx)
6084{
6085
6086 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
6087}
6088
6089
6090static void gen_tlbiva(DisasContext *ctx)
6091{
6092#if defined(CONFIG_USER_ONLY)
6093 GEN_PRIV;
6094#else
6095 TCGv t0;
6096
6097 CHK_SV;
6098 t0 = tcg_temp_new();
6099 gen_addr_reg_index(ctx, t0);
6100 gen_helper_tlbiva(cpu_env, cpu_gpr[rB(ctx->opcode)]);
6101 tcg_temp_free(t0);
6102#endif
6103}
6104
6105
6106static inline void gen_405_mulladd_insn(DisasContext *ctx, int opc2, int opc3,
6107 int ra, int rb, int rt, int Rc)
6108{
6109 TCGv t0, t1;
6110
6111 t0 = tcg_temp_local_new();
6112 t1 = tcg_temp_local_new();
6113
6114 switch (opc3 & 0x0D) {
6115 case 0x05:
6116
6117
6118
6119
6120
6121 tcg_gen_ext16s_tl(t0, cpu_gpr[ra]);
6122 tcg_gen_sari_tl(t1, cpu_gpr[rb], 16);
6123 tcg_gen_ext16s_tl(t1, t1);
6124 break;
6125 case 0x04:
6126
6127
6128
6129 tcg_gen_ext16u_tl(t0, cpu_gpr[ra]);
6130 tcg_gen_shri_tl(t1, cpu_gpr[rb], 16);
6131 tcg_gen_ext16u_tl(t1, t1);
6132 break;
6133 case 0x01:
6134
6135
6136
6137
6138
6139 tcg_gen_sari_tl(t0, cpu_gpr[ra], 16);
6140 tcg_gen_ext16s_tl(t0, t0);
6141 tcg_gen_sari_tl(t1, cpu_gpr[rb], 16);
6142 tcg_gen_ext16s_tl(t1, t1);
6143 break;
6144 case 0x00:
6145
6146
6147
6148 tcg_gen_shri_tl(t0, cpu_gpr[ra], 16);
6149 tcg_gen_ext16u_tl(t0, t0);
6150 tcg_gen_shri_tl(t1, cpu_gpr[rb], 16);
6151 tcg_gen_ext16u_tl(t1, t1);
6152 break;
6153 case 0x0D:
6154
6155
6156
6157
6158
6159 tcg_gen_ext16s_tl(t0, cpu_gpr[ra]);
6160 tcg_gen_ext16s_tl(t1, cpu_gpr[rb]);
6161 break;
6162 case 0x0C:
6163
6164
6165
6166 tcg_gen_ext16u_tl(t0, cpu_gpr[ra]);
6167 tcg_gen_ext16u_tl(t1, cpu_gpr[rb]);
6168 break;
6169 }
6170 if (opc2 & 0x04) {
6171
6172 tcg_gen_mul_tl(t1, t0, t1);
6173 if (opc2 & 0x02) {
6174
6175 tcg_gen_sub_tl(t0, cpu_gpr[rt], t1);
6176 } else {
6177
6178 tcg_gen_add_tl(t0, cpu_gpr[rt], t1);
6179 }
6180
6181 if (opc3 & 0x12) {
6182
6183 TCGLabel *l1 = gen_new_label();
6184
6185 if (opc3 & 0x10) {
6186
6187 tcg_gen_movi_tl(cpu_ov, 0);
6188 }
6189 if (opc3 & 0x01) {
6190
6191 tcg_gen_xor_tl(t1, cpu_gpr[rt], t1);
6192 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
6193 tcg_gen_xor_tl(t1, cpu_gpr[rt], t0);
6194 tcg_gen_brcondi_tl(TCG_COND_LT, t1, 0, l1);
6195 if (opc3 & 0x02) {
6196
6197 tcg_gen_sari_tl(t0, cpu_gpr[rt], 31);
6198 tcg_gen_xori_tl(t0, t0, 0x7fffffff);
6199 }
6200 } else {
6201
6202 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6203 if (opc3 & 0x02) {
6204
6205 tcg_gen_movi_tl(t0, UINT32_MAX);
6206 }
6207 }
6208 if (opc3 & 0x10) {
6209
6210 tcg_gen_movi_tl(cpu_ov, 1);
6211 tcg_gen_movi_tl(cpu_so, 1);
6212 }
6213 gen_set_label(l1);
6214 tcg_gen_mov_tl(cpu_gpr[rt], t0);
6215 }
6216 } else {
6217 tcg_gen_mul_tl(cpu_gpr[rt], t0, t1);
6218 }
6219 tcg_temp_free(t0);
6220 tcg_temp_free(t1);
6221 if (unlikely(Rc) != 0) {
6222
6223 gen_set_Rc0(ctx, cpu_gpr[rt]);
6224 }
6225}
6226
6227#define GEN_MAC_HANDLER(name, opc2, opc3) \
6228static void glue(gen_, name)(DisasContext *ctx) \
6229{ \
6230 gen_405_mulladd_insn(ctx, opc2, opc3, rA(ctx->opcode), rB(ctx->opcode), \
6231 rD(ctx->opcode), Rc(ctx->opcode)); \
6232}
6233
6234
6235GEN_MAC_HANDLER(macchw, 0x0C, 0x05);
6236
6237GEN_MAC_HANDLER(macchwo, 0x0C, 0x15);
6238
6239GEN_MAC_HANDLER(macchws, 0x0C, 0x07);
6240
6241GEN_MAC_HANDLER(macchwso, 0x0C, 0x17);
6242
6243GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06);
6244
6245GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16);
6246
6247GEN_MAC_HANDLER(macchwu, 0x0C, 0x04);
6248
6249GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14);
6250
6251GEN_MAC_HANDLER(machhw, 0x0C, 0x01);
6252
6253GEN_MAC_HANDLER(machhwo, 0x0C, 0x11);
6254
6255GEN_MAC_HANDLER(machhws, 0x0C, 0x03);
6256
6257GEN_MAC_HANDLER(machhwso, 0x0C, 0x13);
6258
6259GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02);
6260
6261GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12);
6262
6263GEN_MAC_HANDLER(machhwu, 0x0C, 0x00);
6264
6265GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10);
6266
6267GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D);
6268
6269GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D);
6270
6271GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F);
6272
6273GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F);
6274
6275GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C);
6276
6277GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C);
6278
6279GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E);
6280
6281GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E);
6282
6283GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05);
6284
6285GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15);
6286
6287GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07);
6288
6289GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17);
6290
6291GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01);
6292
6293GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11);
6294
6295GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03);
6296
6297GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13);
6298
6299GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D);
6300
6301GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D);
6302
6303GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F);
6304
6305GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F);
6306
6307
6308GEN_MAC_HANDLER(mulchw, 0x08, 0x05);
6309
6310GEN_MAC_HANDLER(mulchwu, 0x08, 0x04);
6311
6312GEN_MAC_HANDLER(mulhhw, 0x08, 0x01);
6313
6314GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00);
6315
6316GEN_MAC_HANDLER(mullhw, 0x08, 0x0D);
6317
6318GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C);
6319
6320
6321static void gen_mfdcr(DisasContext *ctx)
6322{
6323#if defined(CONFIG_USER_ONLY)
6324 GEN_PRIV;
6325#else
6326 TCGv dcrn;
6327
6328 CHK_SV;
6329
6330 gen_update_nip(ctx, ctx->nip - 4);
6331 dcrn = tcg_const_tl(SPR(ctx->opcode));
6332 gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_env, dcrn);
6333 tcg_temp_free(dcrn);
6334#endif
6335}
6336
6337
6338static void gen_mtdcr(DisasContext *ctx)
6339{
6340#if defined(CONFIG_USER_ONLY)
6341 GEN_PRIV;
6342#else
6343 TCGv dcrn;
6344
6345 CHK_SV;
6346
6347 gen_update_nip(ctx, ctx->nip - 4);
6348 dcrn = tcg_const_tl(SPR(ctx->opcode));
6349 gen_helper_store_dcr(cpu_env, dcrn, cpu_gpr[rS(ctx->opcode)]);
6350 tcg_temp_free(dcrn);
6351#endif
6352}
6353
6354
6355
6356static void gen_mfdcrx(DisasContext *ctx)
6357{
6358#if defined(CONFIG_USER_ONLY)
6359 GEN_PRIV;
6360#else
6361 CHK_SV;
6362
6363 gen_update_nip(ctx, ctx->nip - 4);
6364 gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_env,
6365 cpu_gpr[rA(ctx->opcode)]);
6366
6367#endif
6368}
6369
6370
6371
6372static void gen_mtdcrx(DisasContext *ctx)
6373{
6374#if defined(CONFIG_USER_ONLY)
6375 GEN_PRIV;
6376#else
6377 CHK_SV;
6378
6379 gen_update_nip(ctx, ctx->nip - 4);
6380 gen_helper_store_dcr(cpu_env, cpu_gpr[rA(ctx->opcode)],
6381 cpu_gpr[rS(ctx->opcode)]);
6382
6383#endif
6384}
6385
6386
6387static void gen_mfdcrux(DisasContext *ctx)
6388{
6389
6390 gen_update_nip(ctx, ctx->nip - 4);
6391 gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_env,
6392 cpu_gpr[rA(ctx->opcode)]);
6393
6394}
6395
6396
6397static void gen_mtdcrux(DisasContext *ctx)
6398{
6399
6400 gen_update_nip(ctx, ctx->nip - 4);
6401 gen_helper_store_dcr(cpu_env, cpu_gpr[rA(ctx->opcode)],
6402 cpu_gpr[rS(ctx->opcode)]);
6403
6404}
6405
6406
6407static void gen_dccci(DisasContext *ctx)
6408{
6409 CHK_SV;
6410
6411}
6412
6413
6414static void gen_dcread(DisasContext *ctx)
6415{
6416#if defined(CONFIG_USER_ONLY)
6417 GEN_PRIV;
6418#else
6419 TCGv EA, val;
6420
6421 CHK_SV;
6422 gen_set_access_type(ctx, ACCESS_CACHE);
6423 EA = tcg_temp_new();
6424 gen_addr_reg_index(ctx, EA);
6425 val = tcg_temp_new();
6426 gen_qemu_ld32u(ctx, val, EA);
6427 tcg_temp_free(val);
6428 tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], EA);
6429 tcg_temp_free(EA);
6430#endif
6431}
6432
6433
6434static void gen_icbt_40x(DisasContext *ctx)
6435{
6436
6437
6438
6439
6440}
6441
6442
6443static void gen_iccci(DisasContext *ctx)
6444{
6445 CHK_SV;
6446
6447}
6448
6449
6450static void gen_icread(DisasContext *ctx)
6451{
6452 CHK_SV;
6453
6454}
6455
6456
6457static void gen_rfci_40x(DisasContext *ctx)
6458{
6459#if defined(CONFIG_USER_ONLY)
6460 GEN_PRIV;
6461#else
6462 CHK_SV;
6463
6464 gen_helper_40x_rfci(cpu_env);
6465 gen_sync_exception(ctx);
6466#endif
6467}
6468
6469static void gen_rfci(DisasContext *ctx)
6470{
6471#if defined(CONFIG_USER_ONLY)
6472 GEN_PRIV;
6473#else
6474 CHK_SV;
6475
6476 gen_helper_rfci(cpu_env);
6477 gen_sync_exception(ctx);
6478#endif
6479}
6480
6481
6482
6483
6484static void gen_rfdi(DisasContext *ctx)
6485{
6486#if defined(CONFIG_USER_ONLY)
6487 GEN_PRIV;
6488#else
6489 CHK_SV;
6490
6491 gen_helper_rfdi(cpu_env);
6492 gen_sync_exception(ctx);
6493#endif
6494}
6495
6496
6497static void gen_rfmci(DisasContext *ctx)
6498{
6499#if defined(CONFIG_USER_ONLY)
6500 GEN_PRIV;
6501#else
6502 CHK_SV;
6503
6504 gen_helper_rfmci(cpu_env);
6505 gen_sync_exception(ctx);
6506#endif
6507}
6508
6509
6510
6511
6512static void gen_tlbre_40x(DisasContext *ctx)
6513{
6514#if defined(CONFIG_USER_ONLY)
6515 GEN_PRIV;
6516#else
6517 CHK_SV;
6518 switch (rB(ctx->opcode)) {
6519 case 0:
6520 gen_helper_4xx_tlbre_hi(cpu_gpr[rD(ctx->opcode)], cpu_env,
6521 cpu_gpr[rA(ctx->opcode)]);
6522 break;
6523 case 1:
6524 gen_helper_4xx_tlbre_lo(cpu_gpr[rD(ctx->opcode)], cpu_env,
6525 cpu_gpr[rA(ctx->opcode)]);
6526 break;
6527 default:
6528 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
6529 break;
6530 }
6531#endif
6532}
6533
6534
6535static void gen_tlbsx_40x(DisasContext *ctx)
6536{
6537#if defined(CONFIG_USER_ONLY)
6538 GEN_PRIV;
6539#else
6540 TCGv t0;
6541
6542 CHK_SV;
6543 t0 = tcg_temp_new();
6544 gen_addr_reg_index(ctx, t0);
6545 gen_helper_4xx_tlbsx(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
6546 tcg_temp_free(t0);
6547 if (Rc(ctx->opcode)) {
6548 TCGLabel *l1 = gen_new_label();
6549 tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
6550 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rD(ctx->opcode)], -1, l1);
6551 tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
6552 gen_set_label(l1);
6553 }
6554#endif
6555}
6556
6557
6558static void gen_tlbwe_40x(DisasContext *ctx)
6559{
6560#if defined(CONFIG_USER_ONLY)
6561 GEN_PRIV;
6562#else
6563 CHK_SV;
6564
6565 switch (rB(ctx->opcode)) {
6566 case 0:
6567 gen_helper_4xx_tlbwe_hi(cpu_env, cpu_gpr[rA(ctx->opcode)],
6568 cpu_gpr[rS(ctx->opcode)]);
6569 break;
6570 case 1:
6571 gen_helper_4xx_tlbwe_lo(cpu_env, cpu_gpr[rA(ctx->opcode)],
6572 cpu_gpr[rS(ctx->opcode)]);
6573 break;
6574 default:
6575 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
6576 break;
6577 }
6578#endif
6579}
6580
6581
6582
6583
6584static void gen_tlbre_440(DisasContext *ctx)
6585{
6586#if defined(CONFIG_USER_ONLY)
6587 GEN_PRIV;
6588#else
6589 CHK_SV;
6590
6591 switch (rB(ctx->opcode)) {
6592 case 0:
6593 case 1:
6594 case 2:
6595 {
6596 TCGv_i32 t0 = tcg_const_i32(rB(ctx->opcode));
6597 gen_helper_440_tlbre(cpu_gpr[rD(ctx->opcode)], cpu_env,
6598 t0, cpu_gpr[rA(ctx->opcode)]);
6599 tcg_temp_free_i32(t0);
6600 }
6601 break;
6602 default:
6603 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
6604 break;
6605 }
6606#endif
6607}
6608
6609
6610static void gen_tlbsx_440(DisasContext *ctx)
6611{
6612#if defined(CONFIG_USER_ONLY)
6613 GEN_PRIV;
6614#else
6615 TCGv t0;
6616
6617 CHK_SV;
6618 t0 = tcg_temp_new();
6619 gen_addr_reg_index(ctx, t0);
6620 gen_helper_440_tlbsx(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
6621 tcg_temp_free(t0);
6622 if (Rc(ctx->opcode)) {
6623 TCGLabel *l1 = gen_new_label();
6624 tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
6625 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rD(ctx->opcode)], -1, l1);
6626 tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
6627 gen_set_label(l1);
6628 }
6629#endif
6630}
6631
6632
6633static void gen_tlbwe_440(DisasContext *ctx)
6634{
6635#if defined(CONFIG_USER_ONLY)
6636 GEN_PRIV;
6637#else
6638 CHK_SV;
6639 switch (rB(ctx->opcode)) {
6640 case 0:
6641 case 1:
6642 case 2:
6643 {
6644 TCGv_i32 t0 = tcg_const_i32(rB(ctx->opcode));
6645 gen_helper_440_tlbwe(cpu_env, t0, cpu_gpr[rA(ctx->opcode)],
6646 cpu_gpr[rS(ctx->opcode)]);
6647 tcg_temp_free_i32(t0);
6648 }
6649 break;
6650 default:
6651 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
6652 break;
6653 }
6654#endif
6655}
6656
6657
6658
6659
6660static void gen_tlbre_booke206(DisasContext *ctx)
6661{
6662 #if defined(CONFIG_USER_ONLY)
6663 GEN_PRIV;
6664#else
6665 CHK_SV;
6666 gen_helper_booke206_tlbre(cpu_env);
6667#endif
6668}
6669
6670
6671static void gen_tlbsx_booke206(DisasContext *ctx)
6672{
6673#if defined(CONFIG_USER_ONLY)
6674 GEN_PRIV;
6675#else
6676 TCGv t0;
6677
6678 CHK_SV;
6679 if (rA(ctx->opcode)) {
6680 t0 = tcg_temp_new();
6681 tcg_gen_mov_tl(t0, cpu_gpr[rD(ctx->opcode)]);
6682 } else {
6683 t0 = tcg_const_tl(0);
6684 }
6685
6686 tcg_gen_add_tl(t0, t0, cpu_gpr[rB(ctx->opcode)]);
6687 gen_helper_booke206_tlbsx(cpu_env, t0);
6688 tcg_temp_free(t0);
6689#endif
6690}
6691
6692
6693static void gen_tlbwe_booke206(DisasContext *ctx)
6694{
6695#if defined(CONFIG_USER_ONLY)
6696 GEN_PRIV;
6697#else
6698 CHK_SV;
6699 gen_update_nip(ctx, ctx->nip - 4);
6700 gen_helper_booke206_tlbwe(cpu_env);
6701#endif
6702}
6703
6704static void gen_tlbivax_booke206(DisasContext *ctx)
6705{
6706#if defined(CONFIG_USER_ONLY)
6707 GEN_PRIV;
6708#else
6709 TCGv t0;
6710
6711 CHK_SV;
6712 t0 = tcg_temp_new();
6713 gen_addr_reg_index(ctx, t0);
6714 gen_helper_booke206_tlbivax(cpu_env, t0);
6715 tcg_temp_free(t0);
6716#endif
6717}
6718
6719static void gen_tlbilx_booke206(DisasContext *ctx)
6720{
6721#if defined(CONFIG_USER_ONLY)
6722 GEN_PRIV;
6723#else
6724 TCGv t0;
6725
6726 CHK_SV;
6727 t0 = tcg_temp_new();
6728 gen_addr_reg_index(ctx, t0);
6729
6730 switch((ctx->opcode >> 21) & 0x3) {
6731 case 0:
6732 gen_helper_booke206_tlbilx0(cpu_env, t0);
6733 break;
6734 case 1:
6735 gen_helper_booke206_tlbilx1(cpu_env, t0);
6736 break;
6737 case 3:
6738 gen_helper_booke206_tlbilx3(cpu_env, t0);
6739 break;
6740 default:
6741 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
6742 break;
6743 }
6744
6745 tcg_temp_free(t0);
6746#endif
6747}
6748
6749
6750
6751static void gen_wrtee(DisasContext *ctx)
6752{
6753#if defined(CONFIG_USER_ONLY)
6754 GEN_PRIV;
6755#else
6756 TCGv t0;
6757
6758 CHK_SV;
6759 t0 = tcg_temp_new();
6760 tcg_gen_andi_tl(t0, cpu_gpr[rD(ctx->opcode)], (1 << MSR_EE));
6761 tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE));
6762 tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
6763 tcg_temp_free(t0);
6764
6765
6766
6767 gen_stop_exception(ctx);
6768#endif
6769}
6770
6771
6772static void gen_wrteei(DisasContext *ctx)
6773{
6774#if defined(CONFIG_USER_ONLY)
6775 GEN_PRIV;
6776#else
6777 CHK_SV;
6778 if (ctx->opcode & 0x00008000) {
6779 tcg_gen_ori_tl(cpu_msr, cpu_msr, (1 << MSR_EE));
6780
6781 gen_stop_exception(ctx);
6782 } else {
6783 tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE));
6784 }
6785#endif
6786}
6787
6788
6789
6790
6791static void gen_dlmzb(DisasContext *ctx)
6792{
6793 TCGv_i32 t0 = tcg_const_i32(Rc(ctx->opcode));
6794 gen_helper_dlmzb(cpu_gpr[rA(ctx->opcode)], cpu_env,
6795 cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], t0);
6796 tcg_temp_free_i32(t0);
6797}
6798
6799
6800static void gen_mbar(DisasContext *ctx)
6801{
6802
6803}
6804
6805
6806static void gen_msync_4xx(DisasContext *ctx)
6807{
6808
6809}
6810
6811
6812static void gen_icbt_440(DisasContext *ctx)
6813{
6814
6815
6816
6817
6818}
6819
6820
6821
6822static void gen_msgclr(DisasContext *ctx)
6823{
6824#if defined(CONFIG_USER_ONLY)
6825 GEN_PRIV;
6826#else
6827 CHK_SV;
6828 gen_helper_msgclr(cpu_env, cpu_gpr[rB(ctx->opcode)]);
6829#endif
6830}
6831
6832static void gen_msgsnd(DisasContext *ctx)
6833{
6834#if defined(CONFIG_USER_ONLY)
6835 GEN_PRIV;
6836#else
6837 CHK_SV;
6838 gen_helper_msgsnd(cpu_gpr[rB(ctx->opcode)]);
6839#endif
6840}
6841
6842
6843
6844
6845static inline TCGv_ptr gen_avr_ptr(int reg)
6846{
6847 TCGv_ptr r = tcg_temp_new_ptr();
6848 tcg_gen_addi_ptr(r, cpu_env, offsetof(CPUPPCState, avr[reg]));
6849 return r;
6850}
6851
6852#define GEN_VR_LDX(name, opc2, opc3) \
6853static void glue(gen_, name)(DisasContext *ctx) \
6854{ \
6855 TCGv EA; \
6856 if (unlikely(!ctx->altivec_enabled)) { \
6857 gen_exception(ctx, POWERPC_EXCP_VPU); \
6858 return; \
6859 } \
6860 gen_set_access_type(ctx, ACCESS_INT); \
6861 EA = tcg_temp_new(); \
6862 gen_addr_reg_index(ctx, EA); \
6863 tcg_gen_andi_tl(EA, EA, ~0xf); \
6864
6865 \
6866 if (ctx->le_mode) { \
6867 gen_qemu_ld64(ctx, cpu_avrl[rD(ctx->opcode)], EA); \
6868 tcg_gen_addi_tl(EA, EA, 8); \
6869 gen_qemu_ld64(ctx, cpu_avrh[rD(ctx->opcode)], EA); \
6870 } else { \
6871 gen_qemu_ld64(ctx, cpu_avrh[rD(ctx->opcode)], EA); \
6872 tcg_gen_addi_tl(EA, EA, 8); \
6873 gen_qemu_ld64(ctx, cpu_avrl[rD(ctx->opcode)], EA); \
6874 } \
6875 tcg_temp_free(EA); \
6876}
6877
6878#define GEN_VR_STX(name, opc2, opc3) \
6879static void gen_st##name(DisasContext *ctx) \
6880{ \
6881 TCGv EA; \
6882 if (unlikely(!ctx->altivec_enabled)) { \
6883 gen_exception(ctx, POWERPC_EXCP_VPU); \
6884 return; \
6885 } \
6886 gen_set_access_type(ctx, ACCESS_INT); \
6887 EA = tcg_temp_new(); \
6888 gen_addr_reg_index(ctx, EA); \
6889 tcg_gen_andi_tl(EA, EA, ~0xf); \
6890
6891 \
6892 if (ctx->le_mode) { \
6893 gen_qemu_st64(ctx, cpu_avrl[rD(ctx->opcode)], EA); \
6894 tcg_gen_addi_tl(EA, EA, 8); \
6895 gen_qemu_st64(ctx, cpu_avrh[rD(ctx->opcode)], EA); \
6896 } else { \
6897 gen_qemu_st64(ctx, cpu_avrh[rD(ctx->opcode)], EA); \
6898 tcg_gen_addi_tl(EA, EA, 8); \
6899 gen_qemu_st64(ctx, cpu_avrl[rD(ctx->opcode)], EA); \
6900 } \
6901 tcg_temp_free(EA); \
6902}
6903
6904#define GEN_VR_LVE(name, opc2, opc3, size) \
6905static void gen_lve##name(DisasContext *ctx) \
6906 { \
6907 TCGv EA; \
6908 TCGv_ptr rs; \
6909 if (unlikely(!ctx->altivec_enabled)) { \
6910 gen_exception(ctx, POWERPC_EXCP_VPU); \
6911 return; \
6912 } \
6913 gen_set_access_type(ctx, ACCESS_INT); \
6914 EA = tcg_temp_new(); \
6915 gen_addr_reg_index(ctx, EA); \
6916 if (size > 1) { \
6917 tcg_gen_andi_tl(EA, EA, ~(size - 1)); \
6918 } \
6919 rs = gen_avr_ptr(rS(ctx->opcode)); \
6920 gen_helper_lve##name(cpu_env, rs, EA); \
6921 tcg_temp_free(EA); \
6922 tcg_temp_free_ptr(rs); \
6923 }
6924
6925#define GEN_VR_STVE(name, opc2, opc3, size) \
6926static void gen_stve##name(DisasContext *ctx) \
6927 { \
6928 TCGv EA; \
6929 TCGv_ptr rs; \
6930 if (unlikely(!ctx->altivec_enabled)) { \
6931 gen_exception(ctx, POWERPC_EXCP_VPU); \
6932 return; \
6933 } \
6934 gen_set_access_type(ctx, ACCESS_INT); \
6935 EA = tcg_temp_new(); \
6936 gen_addr_reg_index(ctx, EA); \
6937 if (size > 1) { \
6938 tcg_gen_andi_tl(EA, EA, ~(size - 1)); \
6939 } \
6940 rs = gen_avr_ptr(rS(ctx->opcode)); \
6941 gen_helper_stve##name(cpu_env, rs, EA); \
6942 tcg_temp_free(EA); \
6943 tcg_temp_free_ptr(rs); \
6944 }
6945
6946GEN_VR_LDX(lvx, 0x07, 0x03);
6947
6948GEN_VR_LDX(lvxl, 0x07, 0x0B);
6949
6950GEN_VR_LVE(bx, 0x07, 0x00, 1);
6951GEN_VR_LVE(hx, 0x07, 0x01, 2);
6952GEN_VR_LVE(wx, 0x07, 0x02, 4);
6953
6954GEN_VR_STX(svx, 0x07, 0x07);
6955
6956GEN_VR_STX(svxl, 0x07, 0x0F);
6957
6958GEN_VR_STVE(bx, 0x07, 0x04, 1);
6959GEN_VR_STVE(hx, 0x07, 0x05, 2);
6960GEN_VR_STVE(wx, 0x07, 0x06, 4);
6961
6962static void gen_lvsl(DisasContext *ctx)
6963{
6964 TCGv_ptr rd;
6965 TCGv EA;
6966 if (unlikely(!ctx->altivec_enabled)) {
6967 gen_exception(ctx, POWERPC_EXCP_VPU);
6968 return;
6969 }
6970 EA = tcg_temp_new();
6971 gen_addr_reg_index(ctx, EA);
6972 rd = gen_avr_ptr(rD(ctx->opcode));
6973 gen_helper_lvsl(rd, EA);
6974 tcg_temp_free(EA);
6975 tcg_temp_free_ptr(rd);
6976}
6977
6978static void gen_lvsr(DisasContext *ctx)
6979{
6980 TCGv_ptr rd;
6981 TCGv EA;
6982 if (unlikely(!ctx->altivec_enabled)) {
6983 gen_exception(ctx, POWERPC_EXCP_VPU);
6984 return;
6985 }
6986 EA = tcg_temp_new();
6987 gen_addr_reg_index(ctx, EA);
6988 rd = gen_avr_ptr(rD(ctx->opcode));
6989 gen_helper_lvsr(rd, EA);
6990 tcg_temp_free(EA);
6991 tcg_temp_free_ptr(rd);
6992}
6993
6994static void gen_mfvscr(DisasContext *ctx)
6995{
6996 TCGv_i32 t;
6997 if (unlikely(!ctx->altivec_enabled)) {
6998 gen_exception(ctx, POWERPC_EXCP_VPU);
6999 return;
7000 }
7001 tcg_gen_movi_i64(cpu_avrh[rD(ctx->opcode)], 0);
7002 t = tcg_temp_new_i32();
7003 tcg_gen_ld_i32(t, cpu_env, offsetof(CPUPPCState, vscr));
7004 tcg_gen_extu_i32_i64(cpu_avrl[rD(ctx->opcode)], t);
7005 tcg_temp_free_i32(t);
7006}
7007
7008static void gen_mtvscr(DisasContext *ctx)
7009{
7010 TCGv_ptr p;
7011 if (unlikely(!ctx->altivec_enabled)) {
7012 gen_exception(ctx, POWERPC_EXCP_VPU);
7013 return;
7014 }
7015 p = gen_avr_ptr(rB(ctx->opcode));
7016 gen_helper_mtvscr(cpu_env, p);
7017 tcg_temp_free_ptr(p);
7018}
7019
7020
7021#define GEN_VX_LOGICAL(name, tcg_op, opc2, opc3) \
7022static void glue(gen_, name)(DisasContext *ctx) \
7023{ \
7024 if (unlikely(!ctx->altivec_enabled)) { \
7025 gen_exception(ctx, POWERPC_EXCP_VPU); \
7026 return; \
7027 } \
7028 tcg_op(cpu_avrh[rD(ctx->opcode)], cpu_avrh[rA(ctx->opcode)], cpu_avrh[rB(ctx->opcode)]); \
7029 tcg_op(cpu_avrl[rD(ctx->opcode)], cpu_avrl[rA(ctx->opcode)], cpu_avrl[rB(ctx->opcode)]); \
7030}
7031
7032GEN_VX_LOGICAL(vand, tcg_gen_and_i64, 2, 16);
7033GEN_VX_LOGICAL(vandc, tcg_gen_andc_i64, 2, 17);
7034GEN_VX_LOGICAL(vor, tcg_gen_or_i64, 2, 18);
7035GEN_VX_LOGICAL(vxor, tcg_gen_xor_i64, 2, 19);
7036GEN_VX_LOGICAL(vnor, tcg_gen_nor_i64, 2, 20);
7037GEN_VX_LOGICAL(veqv, tcg_gen_eqv_i64, 2, 26);
7038GEN_VX_LOGICAL(vnand, tcg_gen_nand_i64, 2, 22);
7039GEN_VX_LOGICAL(vorc, tcg_gen_orc_i64, 2, 21);
7040
7041#define GEN_VXFORM(name, opc2, opc3) \
7042static void glue(gen_, name)(DisasContext *ctx) \
7043{ \
7044 TCGv_ptr ra, rb, rd; \
7045 if (unlikely(!ctx->altivec_enabled)) { \
7046 gen_exception(ctx, POWERPC_EXCP_VPU); \
7047 return; \
7048 } \
7049 ra = gen_avr_ptr(rA(ctx->opcode)); \
7050 rb = gen_avr_ptr(rB(ctx->opcode)); \
7051 rd = gen_avr_ptr(rD(ctx->opcode)); \
7052 gen_helper_##name (rd, ra, rb); \
7053 tcg_temp_free_ptr(ra); \
7054 tcg_temp_free_ptr(rb); \
7055 tcg_temp_free_ptr(rd); \
7056}
7057
7058#define GEN_VXFORM_ENV(name, opc2, opc3) \
7059static void glue(gen_, name)(DisasContext *ctx) \
7060{ \
7061 TCGv_ptr ra, rb, rd; \
7062 if (unlikely(!ctx->altivec_enabled)) { \
7063 gen_exception(ctx, POWERPC_EXCP_VPU); \
7064 return; \
7065 } \
7066 ra = gen_avr_ptr(rA(ctx->opcode)); \
7067 rb = gen_avr_ptr(rB(ctx->opcode)); \
7068 rd = gen_avr_ptr(rD(ctx->opcode)); \
7069 gen_helper_##name(cpu_env, rd, ra, rb); \
7070 tcg_temp_free_ptr(ra); \
7071 tcg_temp_free_ptr(rb); \
7072 tcg_temp_free_ptr(rd); \
7073}
7074
7075#define GEN_VXFORM3(name, opc2, opc3) \
7076static void glue(gen_, name)(DisasContext *ctx) \
7077{ \
7078 TCGv_ptr ra, rb, rc, rd; \
7079 if (unlikely(!ctx->altivec_enabled)) { \
7080 gen_exception(ctx, POWERPC_EXCP_VPU); \
7081 return; \
7082 } \
7083 ra = gen_avr_ptr(rA(ctx->opcode)); \
7084 rb = gen_avr_ptr(rB(ctx->opcode)); \
7085 rc = gen_avr_ptr(rC(ctx->opcode)); \
7086 rd = gen_avr_ptr(rD(ctx->opcode)); \
7087 gen_helper_##name(rd, ra, rb, rc); \
7088 tcg_temp_free_ptr(ra); \
7089 tcg_temp_free_ptr(rb); \
7090 tcg_temp_free_ptr(rc); \
7091 tcg_temp_free_ptr(rd); \
7092}
7093
7094
7095
7096
7097
7098
7099
7100#define GEN_VXFORM_DUAL(name0, flg0, flg2_0, name1, flg1, flg2_1) \
7101static void glue(gen_, name0##_##name1)(DisasContext *ctx) \
7102{ \
7103 if ((Rc(ctx->opcode) == 0) && \
7104 ((ctx->insns_flags & flg0) || (ctx->insns_flags2 & flg2_0))) { \
7105 gen_##name0(ctx); \
7106 } else if ((Rc(ctx->opcode) == 1) && \
7107 ((ctx->insns_flags & flg1) || (ctx->insns_flags2 & flg2_1))) { \
7108 gen_##name1(ctx); \
7109 } else { \
7110 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \
7111 } \
7112}
7113
7114GEN_VXFORM(vaddubm, 0, 0);
7115GEN_VXFORM(vadduhm, 0, 1);
7116GEN_VXFORM(vadduwm, 0, 2);
7117GEN_VXFORM(vaddudm, 0, 3);
7118GEN_VXFORM(vsububm, 0, 16);
7119GEN_VXFORM(vsubuhm, 0, 17);
7120GEN_VXFORM(vsubuwm, 0, 18);
7121GEN_VXFORM(vsubudm, 0, 19);
7122GEN_VXFORM(vmaxub, 1, 0);
7123GEN_VXFORM(vmaxuh, 1, 1);
7124GEN_VXFORM(vmaxuw, 1, 2);
7125GEN_VXFORM(vmaxud, 1, 3);
7126GEN_VXFORM(vmaxsb, 1, 4);
7127GEN_VXFORM(vmaxsh, 1, 5);
7128GEN_VXFORM(vmaxsw, 1, 6);
7129GEN_VXFORM(vmaxsd, 1, 7);
7130GEN_VXFORM(vminub, 1, 8);
7131GEN_VXFORM(vminuh, 1, 9);
7132GEN_VXFORM(vminuw, 1, 10);
7133GEN_VXFORM(vminud, 1, 11);
7134GEN_VXFORM(vminsb, 1, 12);
7135GEN_VXFORM(vminsh, 1, 13);
7136GEN_VXFORM(vminsw, 1, 14);
7137GEN_VXFORM(vminsd, 1, 15);
7138GEN_VXFORM(vavgub, 1, 16);
7139GEN_VXFORM(vavguh, 1, 17);
7140GEN_VXFORM(vavguw, 1, 18);
7141GEN_VXFORM(vavgsb, 1, 20);
7142GEN_VXFORM(vavgsh, 1, 21);
7143GEN_VXFORM(vavgsw, 1, 22);
7144GEN_VXFORM(vmrghb, 6, 0);
7145GEN_VXFORM(vmrghh, 6, 1);
7146GEN_VXFORM(vmrghw, 6, 2);
7147GEN_VXFORM(vmrglb, 6, 4);
7148GEN_VXFORM(vmrglh, 6, 5);
7149GEN_VXFORM(vmrglw, 6, 6);
7150
7151static void gen_vmrgew(DisasContext *ctx)
7152{
7153 TCGv_i64 tmp;
7154 int VT, VA, VB;
7155 if (unlikely(!ctx->altivec_enabled)) {
7156 gen_exception(ctx, POWERPC_EXCP_VPU);
7157 return;
7158 }
7159 VT = rD(ctx->opcode);
7160 VA = rA(ctx->opcode);
7161 VB = rB(ctx->opcode);
7162 tmp = tcg_temp_new_i64();
7163 tcg_gen_shri_i64(tmp, cpu_avrh[VB], 32);
7164 tcg_gen_deposit_i64(cpu_avrh[VT], cpu_avrh[VA], tmp, 0, 32);
7165 tcg_gen_shri_i64(tmp, cpu_avrl[VB], 32);
7166 tcg_gen_deposit_i64(cpu_avrl[VT], cpu_avrl[VA], tmp, 0, 32);
7167 tcg_temp_free_i64(tmp);
7168}
7169
7170static void gen_vmrgow(DisasContext *ctx)
7171{
7172 int VT, VA, VB;
7173 if (unlikely(!ctx->altivec_enabled)) {
7174 gen_exception(ctx, POWERPC_EXCP_VPU);
7175 return;
7176 }
7177 VT = rD(ctx->opcode);
7178 VA = rA(ctx->opcode);
7179 VB = rB(ctx->opcode);
7180
7181 tcg_gen_deposit_i64(cpu_avrh[VT], cpu_avrh[VB], cpu_avrh[VA], 32, 32);
7182 tcg_gen_deposit_i64(cpu_avrl[VT], cpu_avrl[VB], cpu_avrl[VA], 32, 32);
7183}
7184
7185GEN_VXFORM(vmuloub, 4, 0);
7186GEN_VXFORM(vmulouh, 4, 1);
7187GEN_VXFORM(vmulouw, 4, 2);
7188GEN_VXFORM(vmuluwm, 4, 2);
7189GEN_VXFORM_DUAL(vmulouw, PPC_ALTIVEC, PPC_NONE,
7190 vmuluwm, PPC_NONE, PPC2_ALTIVEC_207)
7191GEN_VXFORM(vmulosb, 4, 4);
7192GEN_VXFORM(vmulosh, 4, 5);
7193GEN_VXFORM(vmulosw, 4, 6);
7194GEN_VXFORM(vmuleub, 4, 8);
7195GEN_VXFORM(vmuleuh, 4, 9);
7196GEN_VXFORM(vmuleuw, 4, 10);
7197GEN_VXFORM(vmulesb, 4, 12);
7198GEN_VXFORM(vmulesh, 4, 13);
7199GEN_VXFORM(vmulesw, 4, 14);
7200GEN_VXFORM(vslb, 2, 4);
7201GEN_VXFORM(vslh, 2, 5);
7202GEN_VXFORM(vslw, 2, 6);
7203GEN_VXFORM(vsld, 2, 23);
7204GEN_VXFORM(vsrb, 2, 8);
7205GEN_VXFORM(vsrh, 2, 9);
7206GEN_VXFORM(vsrw, 2, 10);
7207GEN_VXFORM(vsrd, 2, 27);
7208GEN_VXFORM(vsrab, 2, 12);
7209GEN_VXFORM(vsrah, 2, 13);
7210GEN_VXFORM(vsraw, 2, 14);
7211GEN_VXFORM(vsrad, 2, 15);
7212GEN_VXFORM(vslo, 6, 16);
7213GEN_VXFORM(vsro, 6, 17);
7214GEN_VXFORM(vaddcuw, 0, 6);
7215GEN_VXFORM(vsubcuw, 0, 22);
7216GEN_VXFORM_ENV(vaddubs, 0, 8);
7217GEN_VXFORM_ENV(vadduhs, 0, 9);
7218GEN_VXFORM_ENV(vadduws, 0, 10);
7219GEN_VXFORM_ENV(vaddsbs, 0, 12);
7220GEN_VXFORM_ENV(vaddshs, 0, 13);
7221GEN_VXFORM_ENV(vaddsws, 0, 14);
7222GEN_VXFORM_ENV(vsububs, 0, 24);
7223GEN_VXFORM_ENV(vsubuhs, 0, 25);
7224GEN_VXFORM_ENV(vsubuws, 0, 26);
7225GEN_VXFORM_ENV(vsubsbs, 0, 28);
7226GEN_VXFORM_ENV(vsubshs, 0, 29);
7227GEN_VXFORM_ENV(vsubsws, 0, 30);
7228GEN_VXFORM(vadduqm, 0, 4);
7229GEN_VXFORM(vaddcuq, 0, 5);
7230GEN_VXFORM3(vaddeuqm, 30, 0);
7231GEN_VXFORM3(vaddecuq, 30, 0);
7232GEN_VXFORM_DUAL(vaddeuqm, PPC_NONE, PPC2_ALTIVEC_207, \
7233 vaddecuq, PPC_NONE, PPC2_ALTIVEC_207)
7234GEN_VXFORM(vsubuqm, 0, 20);
7235GEN_VXFORM(vsubcuq, 0, 21);
7236GEN_VXFORM3(vsubeuqm, 31, 0);
7237GEN_VXFORM3(vsubecuq, 31, 0);
7238GEN_VXFORM_DUAL(vsubeuqm, PPC_NONE, PPC2_ALTIVEC_207, \
7239 vsubecuq, PPC_NONE, PPC2_ALTIVEC_207)
7240GEN_VXFORM(vrlb, 2, 0);
7241GEN_VXFORM(vrlh, 2, 1);
7242GEN_VXFORM(vrlw, 2, 2);
7243GEN_VXFORM(vrld, 2, 3);
7244GEN_VXFORM(vsl, 2, 7);
7245GEN_VXFORM(vsr, 2, 11);
7246GEN_VXFORM_ENV(vpkuhum, 7, 0);
7247GEN_VXFORM_ENV(vpkuwum, 7, 1);
7248GEN_VXFORM_ENV(vpkudum, 7, 17);
7249GEN_VXFORM_ENV(vpkuhus, 7, 2);
7250GEN_VXFORM_ENV(vpkuwus, 7, 3);
7251GEN_VXFORM_ENV(vpkudus, 7, 19);
7252GEN_VXFORM_ENV(vpkshus, 7, 4);
7253GEN_VXFORM_ENV(vpkswus, 7, 5);
7254GEN_VXFORM_ENV(vpksdus, 7, 21);
7255GEN_VXFORM_ENV(vpkshss, 7, 6);
7256GEN_VXFORM_ENV(vpkswss, 7, 7);
7257GEN_VXFORM_ENV(vpksdss, 7, 23);
7258GEN_VXFORM(vpkpx, 7, 12);
7259GEN_VXFORM_ENV(vsum4ubs, 4, 24);
7260GEN_VXFORM_ENV(vsum4sbs, 4, 28);
7261GEN_VXFORM_ENV(vsum4shs, 4, 25);
7262GEN_VXFORM_ENV(vsum2sws, 4, 26);
7263GEN_VXFORM_ENV(vsumsws, 4, 30);
7264GEN_VXFORM_ENV(vaddfp, 5, 0);
7265GEN_VXFORM_ENV(vsubfp, 5, 1);
7266GEN_VXFORM_ENV(vmaxfp, 5, 16);
7267GEN_VXFORM_ENV(vminfp, 5, 17);
7268
7269#define GEN_VXRFORM1(opname, name, str, opc2, opc3) \
7270static void glue(gen_, name)(DisasContext *ctx) \
7271 { \
7272 TCGv_ptr ra, rb, rd; \
7273 if (unlikely(!ctx->altivec_enabled)) { \
7274 gen_exception(ctx, POWERPC_EXCP_VPU); \
7275 return; \
7276 } \
7277 ra = gen_avr_ptr(rA(ctx->opcode)); \
7278 rb = gen_avr_ptr(rB(ctx->opcode)); \
7279 rd = gen_avr_ptr(rD(ctx->opcode)); \
7280 gen_helper_##opname(cpu_env, rd, ra, rb); \
7281 tcg_temp_free_ptr(ra); \
7282 tcg_temp_free_ptr(rb); \
7283 tcg_temp_free_ptr(rd); \
7284 }
7285
7286#define GEN_VXRFORM(name, opc2, opc3) \
7287 GEN_VXRFORM1(name, name, #name, opc2, opc3) \
7288 GEN_VXRFORM1(name##_dot, name##_, #name ".", opc2, (opc3 | (0x1 << 4)))
7289
7290
7291
7292
7293
7294
7295
7296#define GEN_VXRFORM_DUAL(name0, flg0, flg2_0, name1, flg1, flg2_1) \
7297static void glue(gen_, name0##_##name1)(DisasContext *ctx) \
7298{ \
7299 if ((Rc(ctx->opcode) == 0) && \
7300 ((ctx->insns_flags & flg0) || (ctx->insns_flags2 & flg2_0))) { \
7301 if (Rc21(ctx->opcode) == 0) { \
7302 gen_##name0(ctx); \
7303 } else { \
7304 gen_##name0##_(ctx); \
7305 } \
7306 } else if ((Rc(ctx->opcode) == 1) && \
7307 ((ctx->insns_flags & flg1) || (ctx->insns_flags2 & flg2_1))) { \
7308 if (Rc21(ctx->opcode) == 0) { \
7309 gen_##name1(ctx); \
7310 } else { \
7311 gen_##name1##_(ctx); \
7312 } \
7313 } else { \
7314 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \
7315 } \
7316}
7317
7318GEN_VXRFORM(vcmpequb, 3, 0)
7319GEN_VXRFORM(vcmpequh, 3, 1)
7320GEN_VXRFORM(vcmpequw, 3, 2)
7321GEN_VXRFORM(vcmpequd, 3, 3)
7322GEN_VXRFORM(vcmpgtsb, 3, 12)
7323GEN_VXRFORM(vcmpgtsh, 3, 13)
7324GEN_VXRFORM(vcmpgtsw, 3, 14)
7325GEN_VXRFORM(vcmpgtsd, 3, 15)
7326GEN_VXRFORM(vcmpgtub, 3, 8)
7327GEN_VXRFORM(vcmpgtuh, 3, 9)
7328GEN_VXRFORM(vcmpgtuw, 3, 10)
7329GEN_VXRFORM(vcmpgtud, 3, 11)
7330GEN_VXRFORM(vcmpeqfp, 3, 3)
7331GEN_VXRFORM(vcmpgefp, 3, 7)
7332GEN_VXRFORM(vcmpgtfp, 3, 11)
7333GEN_VXRFORM(vcmpbfp, 3, 15)
7334
7335GEN_VXRFORM_DUAL(vcmpeqfp, PPC_ALTIVEC, PPC_NONE, \
7336 vcmpequd, PPC_NONE, PPC2_ALTIVEC_207)
7337GEN_VXRFORM_DUAL(vcmpbfp, PPC_ALTIVEC, PPC_NONE, \
7338 vcmpgtsd, PPC_NONE, PPC2_ALTIVEC_207)
7339GEN_VXRFORM_DUAL(vcmpgtfp, PPC_ALTIVEC, PPC_NONE, \
7340 vcmpgtud, PPC_NONE, PPC2_ALTIVEC_207)
7341
7342#define GEN_VXFORM_SIMM(name, opc2, opc3) \
7343static void glue(gen_, name)(DisasContext *ctx) \
7344 { \
7345 TCGv_ptr rd; \
7346 TCGv_i32 simm; \
7347 if (unlikely(!ctx->altivec_enabled)) { \
7348 gen_exception(ctx, POWERPC_EXCP_VPU); \
7349 return; \
7350 } \
7351 simm = tcg_const_i32(SIMM5(ctx->opcode)); \
7352 rd = gen_avr_ptr(rD(ctx->opcode)); \
7353 gen_helper_##name (rd, simm); \
7354 tcg_temp_free_i32(simm); \
7355 tcg_temp_free_ptr(rd); \
7356 }
7357
7358GEN_VXFORM_SIMM(vspltisb, 6, 12);
7359GEN_VXFORM_SIMM(vspltish, 6, 13);
7360GEN_VXFORM_SIMM(vspltisw, 6, 14);
7361
7362#define GEN_VXFORM_NOA(name, opc2, opc3) \
7363static void glue(gen_, name)(DisasContext *ctx) \
7364 { \
7365 TCGv_ptr rb, rd; \
7366 if (unlikely(!ctx->altivec_enabled)) { \
7367 gen_exception(ctx, POWERPC_EXCP_VPU); \
7368 return; \
7369 } \
7370 rb = gen_avr_ptr(rB(ctx->opcode)); \
7371 rd = gen_avr_ptr(rD(ctx->opcode)); \
7372 gen_helper_##name (rd, rb); \
7373 tcg_temp_free_ptr(rb); \
7374 tcg_temp_free_ptr(rd); \
7375 }
7376
7377#define GEN_VXFORM_NOA_ENV(name, opc2, opc3) \
7378static void glue(gen_, name)(DisasContext *ctx) \
7379 { \
7380 TCGv_ptr rb, rd; \
7381 \
7382 if (unlikely(!ctx->altivec_enabled)) { \
7383 gen_exception(ctx, POWERPC_EXCP_VPU); \
7384 return; \
7385 } \
7386 rb = gen_avr_ptr(rB(ctx->opcode)); \
7387 rd = gen_avr_ptr(rD(ctx->opcode)); \
7388 gen_helper_##name(cpu_env, rd, rb); \
7389 tcg_temp_free_ptr(rb); \
7390 tcg_temp_free_ptr(rd); \
7391 }
7392
7393GEN_VXFORM_NOA(vupkhsb, 7, 8);
7394GEN_VXFORM_NOA(vupkhsh, 7, 9);
7395GEN_VXFORM_NOA(vupkhsw, 7, 25);
7396GEN_VXFORM_NOA(vupklsb, 7, 10);
7397GEN_VXFORM_NOA(vupklsh, 7, 11);
7398GEN_VXFORM_NOA(vupklsw, 7, 27);
7399GEN_VXFORM_NOA(vupkhpx, 7, 13);
7400GEN_VXFORM_NOA(vupklpx, 7, 15);
7401GEN_VXFORM_NOA_ENV(vrefp, 5, 4);
7402GEN_VXFORM_NOA_ENV(vrsqrtefp, 5, 5);
7403GEN_VXFORM_NOA_ENV(vexptefp, 5, 6);
7404GEN_VXFORM_NOA_ENV(vlogefp, 5, 7);
7405GEN_VXFORM_NOA_ENV(vrfim, 5, 11);
7406GEN_VXFORM_NOA_ENV(vrfin, 5, 8);
7407GEN_VXFORM_NOA_ENV(vrfip, 5, 10);
7408GEN_VXFORM_NOA_ENV(vrfiz, 5, 9);
7409
7410#define GEN_VXFORM_SIMM(name, opc2, opc3) \
7411static void glue(gen_, name)(DisasContext *ctx) \
7412 { \
7413 TCGv_ptr rd; \
7414 TCGv_i32 simm; \
7415 if (unlikely(!ctx->altivec_enabled)) { \
7416 gen_exception(ctx, POWERPC_EXCP_VPU); \
7417 return; \
7418 } \
7419 simm = tcg_const_i32(SIMM5(ctx->opcode)); \
7420 rd = gen_avr_ptr(rD(ctx->opcode)); \
7421 gen_helper_##name (rd, simm); \
7422 tcg_temp_free_i32(simm); \
7423 tcg_temp_free_ptr(rd); \
7424 }
7425
7426#define GEN_VXFORM_UIMM(name, opc2, opc3) \
7427static void glue(gen_, name)(DisasContext *ctx) \
7428 { \
7429 TCGv_ptr rb, rd; \
7430 TCGv_i32 uimm; \
7431 if (unlikely(!ctx->altivec_enabled)) { \
7432 gen_exception(ctx, POWERPC_EXCP_VPU); \
7433 return; \
7434 } \
7435 uimm = tcg_const_i32(UIMM5(ctx->opcode)); \
7436 rb = gen_avr_ptr(rB(ctx->opcode)); \
7437 rd = gen_avr_ptr(rD(ctx->opcode)); \
7438 gen_helper_##name (rd, rb, uimm); \
7439 tcg_temp_free_i32(uimm); \
7440 tcg_temp_free_ptr(rb); \
7441 tcg_temp_free_ptr(rd); \
7442 }
7443
7444#define GEN_VXFORM_UIMM_ENV(name, opc2, opc3) \
7445static void glue(gen_, name)(DisasContext *ctx) \
7446 { \
7447 TCGv_ptr rb, rd; \
7448 TCGv_i32 uimm; \
7449 \
7450 if (unlikely(!ctx->altivec_enabled)) { \
7451 gen_exception(ctx, POWERPC_EXCP_VPU); \
7452 return; \
7453 } \
7454 uimm = tcg_const_i32(UIMM5(ctx->opcode)); \
7455 rb = gen_avr_ptr(rB(ctx->opcode)); \
7456 rd = gen_avr_ptr(rD(ctx->opcode)); \
7457 gen_helper_##name(cpu_env, rd, rb, uimm); \
7458 tcg_temp_free_i32(uimm); \
7459 tcg_temp_free_ptr(rb); \
7460 tcg_temp_free_ptr(rd); \
7461 }
7462
7463GEN_VXFORM_UIMM(vspltb, 6, 8);
7464GEN_VXFORM_UIMM(vsplth, 6, 9);
7465GEN_VXFORM_UIMM(vspltw, 6, 10);
7466GEN_VXFORM_UIMM_ENV(vcfux, 5, 12);
7467GEN_VXFORM_UIMM_ENV(vcfsx, 5, 13);
7468GEN_VXFORM_UIMM_ENV(vctuxs, 5, 14);
7469GEN_VXFORM_UIMM_ENV(vctsxs, 5, 15);
7470
7471static void gen_vsldoi(DisasContext *ctx)
7472{
7473 TCGv_ptr ra, rb, rd;
7474 TCGv_i32 sh;
7475 if (unlikely(!ctx->altivec_enabled)) {
7476 gen_exception(ctx, POWERPC_EXCP_VPU);
7477 return;
7478 }
7479 ra = gen_avr_ptr(rA(ctx->opcode));
7480 rb = gen_avr_ptr(rB(ctx->opcode));
7481 rd = gen_avr_ptr(rD(ctx->opcode));
7482 sh = tcg_const_i32(VSH(ctx->opcode));
7483 gen_helper_vsldoi (rd, ra, rb, sh);
7484 tcg_temp_free_ptr(ra);
7485 tcg_temp_free_ptr(rb);
7486 tcg_temp_free_ptr(rd);
7487 tcg_temp_free_i32(sh);
7488}
7489
7490#define GEN_VAFORM_PAIRED(name0, name1, opc2) \
7491static void glue(gen_, name0##_##name1)(DisasContext *ctx) \
7492 { \
7493 TCGv_ptr ra, rb, rc, rd; \
7494 if (unlikely(!ctx->altivec_enabled)) { \
7495 gen_exception(ctx, POWERPC_EXCP_VPU); \
7496 return; \
7497 } \
7498 ra = gen_avr_ptr(rA(ctx->opcode)); \
7499 rb = gen_avr_ptr(rB(ctx->opcode)); \
7500 rc = gen_avr_ptr(rC(ctx->opcode)); \
7501 rd = gen_avr_ptr(rD(ctx->opcode)); \
7502 if (Rc(ctx->opcode)) { \
7503 gen_helper_##name1(cpu_env, rd, ra, rb, rc); \
7504 } else { \
7505 gen_helper_##name0(cpu_env, rd, ra, rb, rc); \
7506 } \
7507 tcg_temp_free_ptr(ra); \
7508 tcg_temp_free_ptr(rb); \
7509 tcg_temp_free_ptr(rc); \
7510 tcg_temp_free_ptr(rd); \
7511 }
7512
7513GEN_VAFORM_PAIRED(vmhaddshs, vmhraddshs, 16)
7514
7515static void gen_vmladduhm(DisasContext *ctx)
7516{
7517 TCGv_ptr ra, rb, rc, rd;
7518 if (unlikely(!ctx->altivec_enabled)) {
7519 gen_exception(ctx, POWERPC_EXCP_VPU);
7520 return;
7521 }
7522 ra = gen_avr_ptr(rA(ctx->opcode));
7523 rb = gen_avr_ptr(rB(ctx->opcode));
7524 rc = gen_avr_ptr(rC(ctx->opcode));
7525 rd = gen_avr_ptr(rD(ctx->opcode));
7526 gen_helper_vmladduhm(rd, ra, rb, rc);
7527 tcg_temp_free_ptr(ra);
7528 tcg_temp_free_ptr(rb);
7529 tcg_temp_free_ptr(rc);
7530 tcg_temp_free_ptr(rd);
7531}
7532
7533GEN_VAFORM_PAIRED(vmsumubm, vmsummbm, 18)
7534GEN_VAFORM_PAIRED(vmsumuhm, vmsumuhs, 19)
7535GEN_VAFORM_PAIRED(vmsumshm, vmsumshs, 20)
7536GEN_VAFORM_PAIRED(vsel, vperm, 21)
7537GEN_VAFORM_PAIRED(vmaddfp, vnmsubfp, 23)
7538
7539GEN_VXFORM_NOA(vclzb, 1, 28)
7540GEN_VXFORM_NOA(vclzh, 1, 29)
7541GEN_VXFORM_NOA(vclzw, 1, 30)
7542GEN_VXFORM_NOA(vclzd, 1, 31)
7543GEN_VXFORM_NOA(vpopcntb, 1, 28)
7544GEN_VXFORM_NOA(vpopcnth, 1, 29)
7545GEN_VXFORM_NOA(vpopcntw, 1, 30)
7546GEN_VXFORM_NOA(vpopcntd, 1, 31)
7547GEN_VXFORM_DUAL(vclzb, PPC_NONE, PPC2_ALTIVEC_207, \
7548 vpopcntb, PPC_NONE, PPC2_ALTIVEC_207)
7549GEN_VXFORM_DUAL(vclzh, PPC_NONE, PPC2_ALTIVEC_207, \
7550 vpopcnth, PPC_NONE, PPC2_ALTIVEC_207)
7551GEN_VXFORM_DUAL(vclzw, PPC_NONE, PPC2_ALTIVEC_207, \
7552 vpopcntw, PPC_NONE, PPC2_ALTIVEC_207)
7553GEN_VXFORM_DUAL(vclzd, PPC_NONE, PPC2_ALTIVEC_207, \
7554 vpopcntd, PPC_NONE, PPC2_ALTIVEC_207)
7555GEN_VXFORM(vbpermq, 6, 21);
7556GEN_VXFORM_NOA(vgbbd, 6, 20);
7557GEN_VXFORM(vpmsumb, 4, 16)
7558GEN_VXFORM(vpmsumh, 4, 17)
7559GEN_VXFORM(vpmsumw, 4, 18)
7560GEN_VXFORM(vpmsumd, 4, 19)
7561
7562#define GEN_BCD(op) \
7563static void gen_##op(DisasContext *ctx) \
7564{ \
7565 TCGv_ptr ra, rb, rd; \
7566 TCGv_i32 ps; \
7567 \
7568 if (unlikely(!ctx->altivec_enabled)) { \
7569 gen_exception(ctx, POWERPC_EXCP_VPU); \
7570 return; \
7571 } \
7572 \
7573 ra = gen_avr_ptr(rA(ctx->opcode)); \
7574 rb = gen_avr_ptr(rB(ctx->opcode)); \
7575 rd = gen_avr_ptr(rD(ctx->opcode)); \
7576 \
7577 ps = tcg_const_i32((ctx->opcode & 0x200) != 0); \
7578 \
7579 gen_helper_##op(cpu_crf[6], rd, ra, rb, ps); \
7580 \
7581 tcg_temp_free_ptr(ra); \
7582 tcg_temp_free_ptr(rb); \
7583 tcg_temp_free_ptr(rd); \
7584 tcg_temp_free_i32(ps); \
7585}
7586
7587GEN_BCD(bcdadd)
7588GEN_BCD(bcdsub)
7589
7590GEN_VXFORM_DUAL(vsububm, PPC_ALTIVEC, PPC_NONE, \
7591 bcdadd, PPC_NONE, PPC2_ALTIVEC_207)
7592GEN_VXFORM_DUAL(vsububs, PPC_ALTIVEC, PPC_NONE, \
7593 bcdadd, PPC_NONE, PPC2_ALTIVEC_207)
7594GEN_VXFORM_DUAL(vsubuhm, PPC_ALTIVEC, PPC_NONE, \
7595 bcdsub, PPC_NONE, PPC2_ALTIVEC_207)
7596GEN_VXFORM_DUAL(vsubuhs, PPC_ALTIVEC, PPC_NONE, \
7597 bcdsub, PPC_NONE, PPC2_ALTIVEC_207)
7598
7599static void gen_vsbox(DisasContext *ctx)
7600{
7601 TCGv_ptr ra, rd;
7602 if (unlikely(!ctx->altivec_enabled)) {
7603 gen_exception(ctx, POWERPC_EXCP_VPU);
7604 return;
7605 }
7606 ra = gen_avr_ptr(rA(ctx->opcode));
7607 rd = gen_avr_ptr(rD(ctx->opcode));
7608 gen_helper_vsbox(rd, ra);
7609 tcg_temp_free_ptr(ra);
7610 tcg_temp_free_ptr(rd);
7611}
7612
7613GEN_VXFORM(vcipher, 4, 20)
7614GEN_VXFORM(vcipherlast, 4, 20)
7615GEN_VXFORM(vncipher, 4, 21)
7616GEN_VXFORM(vncipherlast, 4, 21)
7617
7618GEN_VXFORM_DUAL(vcipher, PPC_NONE, PPC2_ALTIVEC_207,
7619 vcipherlast, PPC_NONE, PPC2_ALTIVEC_207)
7620GEN_VXFORM_DUAL(vncipher, PPC_NONE, PPC2_ALTIVEC_207,
7621 vncipherlast, PPC_NONE, PPC2_ALTIVEC_207)
7622
7623#define VSHASIGMA(op) \
7624static void gen_##op(DisasContext *ctx) \
7625{ \
7626 TCGv_ptr ra, rd; \
7627 TCGv_i32 st_six; \
7628 if (unlikely(!ctx->altivec_enabled)) { \
7629 gen_exception(ctx, POWERPC_EXCP_VPU); \
7630 return; \
7631 } \
7632 ra = gen_avr_ptr(rA(ctx->opcode)); \
7633 rd = gen_avr_ptr(rD(ctx->opcode)); \
7634 st_six = tcg_const_i32(rB(ctx->opcode)); \
7635 gen_helper_##op(rd, ra, st_six); \
7636 tcg_temp_free_ptr(ra); \
7637 tcg_temp_free_ptr(rd); \
7638 tcg_temp_free_i32(st_six); \
7639}
7640
7641VSHASIGMA(vshasigmaw)
7642VSHASIGMA(vshasigmad)
7643
7644GEN_VXFORM3(vpermxor, 22, 0xFF)
7645GEN_VXFORM_DUAL(vsldoi, PPC_ALTIVEC, PPC_NONE,
7646 vpermxor, PPC_NONE, PPC2_ALTIVEC_207)
7647
7648
7649
7650static inline TCGv_i64 cpu_vsrh(int n)
7651{
7652 if (n < 32) {
7653 return cpu_fpr[n];
7654 } else {
7655 return cpu_avrh[n-32];
7656 }
7657}
7658
7659static inline TCGv_i64 cpu_vsrl(int n)
7660{
7661 if (n < 32) {
7662 return cpu_vsr[n];
7663 } else {
7664 return cpu_avrl[n-32];
7665 }
7666}
7667
7668#define VSX_LOAD_SCALAR(name, operation) \
7669static void gen_##name(DisasContext *ctx) \
7670{ \
7671 TCGv EA; \
7672 if (unlikely(!ctx->vsx_enabled)) { \
7673 gen_exception(ctx, POWERPC_EXCP_VSXU); \
7674 return; \
7675 } \
7676 gen_set_access_type(ctx, ACCESS_INT); \
7677 EA = tcg_temp_new(); \
7678 gen_addr_reg_index(ctx, EA); \
7679 gen_qemu_##operation(ctx, cpu_vsrh(xT(ctx->opcode)), EA); \
7680 \
7681 tcg_temp_free(EA); \
7682}
7683
7684VSX_LOAD_SCALAR(lxsdx, ld64)
7685VSX_LOAD_SCALAR(lxsiwax, ld32s_i64)
7686VSX_LOAD_SCALAR(lxsiwzx, ld32u_i64)
7687VSX_LOAD_SCALAR(lxsspx, ld32fs)
7688
7689static void gen_lxvd2x(DisasContext *ctx)
7690{
7691 TCGv EA;
7692 if (unlikely(!ctx->vsx_enabled)) {
7693 gen_exception(ctx, POWERPC_EXCP_VSXU);
7694 return;
7695 }
7696 gen_set_access_type(ctx, ACCESS_INT);
7697 EA = tcg_temp_new();
7698 gen_addr_reg_index(ctx, EA);
7699 gen_qemu_ld64(ctx, cpu_vsrh(xT(ctx->opcode)), EA);
7700 tcg_gen_addi_tl(EA, EA, 8);
7701 gen_qemu_ld64(ctx, cpu_vsrl(xT(ctx->opcode)), EA);
7702 tcg_temp_free(EA);
7703}
7704
7705static void gen_lxvdsx(DisasContext *ctx)
7706{
7707 TCGv EA;
7708 if (unlikely(!ctx->vsx_enabled)) {
7709 gen_exception(ctx, POWERPC_EXCP_VSXU);
7710 return;
7711 }
7712 gen_set_access_type(ctx, ACCESS_INT);
7713 EA = tcg_temp_new();
7714 gen_addr_reg_index(ctx, EA);
7715 gen_qemu_ld64(ctx, cpu_vsrh(xT(ctx->opcode)), EA);
7716 tcg_gen_mov_i64(cpu_vsrl(xT(ctx->opcode)), cpu_vsrh(xT(ctx->opcode)));
7717 tcg_temp_free(EA);
7718}
7719
7720static void gen_lxvw4x(DisasContext *ctx)
7721{
7722 TCGv EA;
7723 TCGv_i64 tmp;
7724 TCGv_i64 xth = cpu_vsrh(xT(ctx->opcode));
7725 TCGv_i64 xtl = cpu_vsrl(xT(ctx->opcode));
7726 if (unlikely(!ctx->vsx_enabled)) {
7727 gen_exception(ctx, POWERPC_EXCP_VSXU);
7728 return;
7729 }
7730 gen_set_access_type(ctx, ACCESS_INT);
7731 EA = tcg_temp_new();
7732 tmp = tcg_temp_new_i64();
7733
7734 gen_addr_reg_index(ctx, EA);
7735 gen_qemu_ld32u_i64(ctx, tmp, EA);
7736 tcg_gen_addi_tl(EA, EA, 4);
7737 gen_qemu_ld32u_i64(ctx, xth, EA);
7738 tcg_gen_deposit_i64(xth, xth, tmp, 32, 32);
7739
7740 tcg_gen_addi_tl(EA, EA, 4);
7741 gen_qemu_ld32u_i64(ctx, tmp, EA);
7742 tcg_gen_addi_tl(EA, EA, 4);
7743 gen_qemu_ld32u_i64(ctx, xtl, EA);
7744 tcg_gen_deposit_i64(xtl, xtl, tmp, 32, 32);
7745
7746 tcg_temp_free(EA);
7747 tcg_temp_free_i64(tmp);
7748}
7749
7750#define VSX_STORE_SCALAR(name, operation) \
7751static void gen_##name(DisasContext *ctx) \
7752{ \
7753 TCGv EA; \
7754 if (unlikely(!ctx->vsx_enabled)) { \
7755 gen_exception(ctx, POWERPC_EXCP_VSXU); \
7756 return; \
7757 } \
7758 gen_set_access_type(ctx, ACCESS_INT); \
7759 EA = tcg_temp_new(); \
7760 gen_addr_reg_index(ctx, EA); \
7761 gen_qemu_##operation(ctx, cpu_vsrh(xS(ctx->opcode)), EA); \
7762 tcg_temp_free(EA); \
7763}
7764
7765VSX_STORE_SCALAR(stxsdx, st64)
7766VSX_STORE_SCALAR(stxsiwx, st32_i64)
7767VSX_STORE_SCALAR(stxsspx, st32fs)
7768
7769static void gen_stxvd2x(DisasContext *ctx)
7770{
7771 TCGv EA;
7772 if (unlikely(!ctx->vsx_enabled)) {
7773 gen_exception(ctx, POWERPC_EXCP_VSXU);
7774 return;
7775 }
7776 gen_set_access_type(ctx, ACCESS_INT);
7777 EA = tcg_temp_new();
7778 gen_addr_reg_index(ctx, EA);
7779 gen_qemu_st64(ctx, cpu_vsrh(xS(ctx->opcode)), EA);
7780 tcg_gen_addi_tl(EA, EA, 8);
7781 gen_qemu_st64(ctx, cpu_vsrl(xS(ctx->opcode)), EA);
7782 tcg_temp_free(EA);
7783}
7784
7785static void gen_stxvw4x(DisasContext *ctx)
7786{
7787 TCGv_i64 tmp;
7788 TCGv EA;
7789 if (unlikely(!ctx->vsx_enabled)) {
7790 gen_exception(ctx, POWERPC_EXCP_VSXU);
7791 return;
7792 }
7793 gen_set_access_type(ctx, ACCESS_INT);
7794 EA = tcg_temp_new();
7795 gen_addr_reg_index(ctx, EA);
7796 tmp = tcg_temp_new_i64();
7797
7798 tcg_gen_shri_i64(tmp, cpu_vsrh(xS(ctx->opcode)), 32);
7799 gen_qemu_st32_i64(ctx, tmp, EA);
7800 tcg_gen_addi_tl(EA, EA, 4);
7801 gen_qemu_st32_i64(ctx, cpu_vsrh(xS(ctx->opcode)), EA);
7802
7803 tcg_gen_shri_i64(tmp, cpu_vsrl(xS(ctx->opcode)), 32);
7804 tcg_gen_addi_tl(EA, EA, 4);
7805 gen_qemu_st32_i64(ctx, tmp, EA);
7806 tcg_gen_addi_tl(EA, EA, 4);
7807 gen_qemu_st32_i64(ctx, cpu_vsrl(xS(ctx->opcode)), EA);
7808
7809 tcg_temp_free(EA);
7810 tcg_temp_free_i64(tmp);
7811}
7812
7813#define MV_VSRW(name, tcgop1, tcgop2, target, source) \
7814static void gen_##name(DisasContext *ctx) \
7815{ \
7816 if (xS(ctx->opcode) < 32) { \
7817 if (unlikely(!ctx->fpu_enabled)) { \
7818 gen_exception(ctx, POWERPC_EXCP_FPU); \
7819 return; \
7820 } \
7821 } else { \
7822 if (unlikely(!ctx->altivec_enabled)) { \
7823 gen_exception(ctx, POWERPC_EXCP_VPU); \
7824 return; \
7825 } \
7826 } \
7827 TCGv_i64 tmp = tcg_temp_new_i64(); \
7828 tcg_gen_##tcgop1(tmp, source); \
7829 tcg_gen_##tcgop2(target, tmp); \
7830 tcg_temp_free_i64(tmp); \
7831}
7832
7833
7834MV_VSRW(mfvsrwz, ext32u_i64, trunc_i64_tl, cpu_gpr[rA(ctx->opcode)], \
7835 cpu_vsrh(xS(ctx->opcode)))
7836MV_VSRW(mtvsrwa, extu_tl_i64, ext32s_i64, cpu_vsrh(xT(ctx->opcode)), \
7837 cpu_gpr[rA(ctx->opcode)])
7838MV_VSRW(mtvsrwz, extu_tl_i64, ext32u_i64, cpu_vsrh(xT(ctx->opcode)), \
7839 cpu_gpr[rA(ctx->opcode)])
7840
7841#if defined(TARGET_PPC64)
7842#define MV_VSRD(name, target, source) \
7843static void gen_##name(DisasContext *ctx) \
7844{ \
7845 if (xS(ctx->opcode) < 32) { \
7846 if (unlikely(!ctx->fpu_enabled)) { \
7847 gen_exception(ctx, POWERPC_EXCP_FPU); \
7848 return; \
7849 } \
7850 } else { \
7851 if (unlikely(!ctx->altivec_enabled)) { \
7852 gen_exception(ctx, POWERPC_EXCP_VPU); \
7853 return; \
7854 } \
7855 } \
7856 tcg_gen_mov_i64(target, source); \
7857}
7858
7859MV_VSRD(mfvsrd, cpu_gpr[rA(ctx->opcode)], cpu_vsrh(xS(ctx->opcode)))
7860MV_VSRD(mtvsrd, cpu_vsrh(xT(ctx->opcode)), cpu_gpr[rA(ctx->opcode)])
7861
7862#endif
7863
7864static void gen_xxpermdi(DisasContext *ctx)
7865{
7866 if (unlikely(!ctx->vsx_enabled)) {
7867 gen_exception(ctx, POWERPC_EXCP_VSXU);
7868 return;
7869 }
7870
7871 if (unlikely((xT(ctx->opcode) == xA(ctx->opcode)) ||
7872 (xT(ctx->opcode) == xB(ctx->opcode)))) {
7873 TCGv_i64 xh, xl;
7874
7875 xh = tcg_temp_new_i64();
7876 xl = tcg_temp_new_i64();
7877
7878 if ((DM(ctx->opcode) & 2) == 0) {
7879 tcg_gen_mov_i64(xh, cpu_vsrh(xA(ctx->opcode)));
7880 } else {
7881 tcg_gen_mov_i64(xh, cpu_vsrl(xA(ctx->opcode)));
7882 }
7883 if ((DM(ctx->opcode) & 1) == 0) {
7884 tcg_gen_mov_i64(xl, cpu_vsrh(xB(ctx->opcode)));
7885 } else {
7886 tcg_gen_mov_i64(xl, cpu_vsrl(xB(ctx->opcode)));
7887 }
7888
7889 tcg_gen_mov_i64(cpu_vsrh(xT(ctx->opcode)), xh);
7890 tcg_gen_mov_i64(cpu_vsrl(xT(ctx->opcode)), xl);
7891
7892 tcg_temp_free_i64(xh);
7893 tcg_temp_free_i64(xl);
7894 } else {
7895 if ((DM(ctx->opcode) & 2) == 0) {
7896 tcg_gen_mov_i64(cpu_vsrh(xT(ctx->opcode)), cpu_vsrh(xA(ctx->opcode)));
7897 } else {
7898 tcg_gen_mov_i64(cpu_vsrh(xT(ctx->opcode)), cpu_vsrl(xA(ctx->opcode)));
7899 }
7900 if ((DM(ctx->opcode) & 1) == 0) {
7901 tcg_gen_mov_i64(cpu_vsrl(xT(ctx->opcode)), cpu_vsrh(xB(ctx->opcode)));
7902 } else {
7903 tcg_gen_mov_i64(cpu_vsrl(xT(ctx->opcode)), cpu_vsrl(xB(ctx->opcode)));
7904 }
7905 }
7906}
7907
7908#define OP_ABS 1
7909#define OP_NABS 2
7910#define OP_NEG 3
7911#define OP_CPSGN 4
7912#define SGN_MASK_DP 0x8000000000000000ull
7913#define SGN_MASK_SP 0x8000000080000000ull
7914
7915#define VSX_SCALAR_MOVE(name, op, sgn_mask) \
7916static void glue(gen_, name)(DisasContext * ctx) \
7917 { \
7918 TCGv_i64 xb, sgm; \
7919 if (unlikely(!ctx->vsx_enabled)) { \
7920 gen_exception(ctx, POWERPC_EXCP_VSXU); \
7921 return; \
7922 } \
7923 xb = tcg_temp_new_i64(); \
7924 sgm = tcg_temp_new_i64(); \
7925 tcg_gen_mov_i64(xb, cpu_vsrh(xB(ctx->opcode))); \
7926 tcg_gen_movi_i64(sgm, sgn_mask); \
7927 switch (op) { \
7928 case OP_ABS: { \
7929 tcg_gen_andc_i64(xb, xb, sgm); \
7930 break; \
7931 } \
7932 case OP_NABS: { \
7933 tcg_gen_or_i64(xb, xb, sgm); \
7934 break; \
7935 } \
7936 case OP_NEG: { \
7937 tcg_gen_xor_i64(xb, xb, sgm); \
7938 break; \
7939 } \
7940 case OP_CPSGN: { \
7941 TCGv_i64 xa = tcg_temp_new_i64(); \
7942 tcg_gen_mov_i64(xa, cpu_vsrh(xA(ctx->opcode))); \
7943 tcg_gen_and_i64(xa, xa, sgm); \
7944 tcg_gen_andc_i64(xb, xb, sgm); \
7945 tcg_gen_or_i64(xb, xb, xa); \
7946 tcg_temp_free_i64(xa); \
7947 break; \
7948 } \
7949 } \
7950 tcg_gen_mov_i64(cpu_vsrh(xT(ctx->opcode)), xb); \
7951 tcg_temp_free_i64(xb); \
7952 tcg_temp_free_i64(sgm); \
7953 }
7954
7955VSX_SCALAR_MOVE(xsabsdp, OP_ABS, SGN_MASK_DP)
7956VSX_SCALAR_MOVE(xsnabsdp, OP_NABS, SGN_MASK_DP)
7957VSX_SCALAR_MOVE(xsnegdp, OP_NEG, SGN_MASK_DP)
7958VSX_SCALAR_MOVE(xscpsgndp, OP_CPSGN, SGN_MASK_DP)
7959
7960#define VSX_VECTOR_MOVE(name, op, sgn_mask) \
7961static void glue(gen_, name)(DisasContext * ctx) \
7962 { \
7963 TCGv_i64 xbh, xbl, sgm; \
7964 if (unlikely(!ctx->vsx_enabled)) { \
7965 gen_exception(ctx, POWERPC_EXCP_VSXU); \
7966 return; \
7967 } \
7968 xbh = tcg_temp_new_i64(); \
7969 xbl = tcg_temp_new_i64(); \
7970 sgm = tcg_temp_new_i64(); \
7971 tcg_gen_mov_i64(xbh, cpu_vsrh(xB(ctx->opcode))); \
7972 tcg_gen_mov_i64(xbl, cpu_vsrl(xB(ctx->opcode))); \
7973 tcg_gen_movi_i64(sgm, sgn_mask); \
7974 switch (op) { \
7975 case OP_ABS: { \
7976 tcg_gen_andc_i64(xbh, xbh, sgm); \
7977 tcg_gen_andc_i64(xbl, xbl, sgm); \
7978 break; \
7979 } \
7980 case OP_NABS: { \
7981 tcg_gen_or_i64(xbh, xbh, sgm); \
7982 tcg_gen_or_i64(xbl, xbl, sgm); \
7983 break; \
7984 } \
7985 case OP_NEG: { \
7986 tcg_gen_xor_i64(xbh, xbh, sgm); \
7987 tcg_gen_xor_i64(xbl, xbl, sgm); \
7988 break; \
7989 } \
7990 case OP_CPSGN: { \
7991 TCGv_i64 xah = tcg_temp_new_i64(); \
7992 TCGv_i64 xal = tcg_temp_new_i64(); \
7993 tcg_gen_mov_i64(xah, cpu_vsrh(xA(ctx->opcode))); \
7994 tcg_gen_mov_i64(xal, cpu_vsrl(xA(ctx->opcode))); \
7995 tcg_gen_and_i64(xah, xah, sgm); \
7996 tcg_gen_and_i64(xal, xal, sgm); \
7997 tcg_gen_andc_i64(xbh, xbh, sgm); \
7998 tcg_gen_andc_i64(xbl, xbl, sgm); \
7999 tcg_gen_or_i64(xbh, xbh, xah); \
8000 tcg_gen_or_i64(xbl, xbl, xal); \
8001 tcg_temp_free_i64(xah); \
8002 tcg_temp_free_i64(xal); \
8003 break; \
8004 } \
8005 } \
8006 tcg_gen_mov_i64(cpu_vsrh(xT(ctx->opcode)), xbh); \
8007 tcg_gen_mov_i64(cpu_vsrl(xT(ctx->opcode)), xbl); \
8008 tcg_temp_free_i64(xbh); \
8009 tcg_temp_free_i64(xbl); \
8010 tcg_temp_free_i64(sgm); \
8011 }
8012
8013VSX_VECTOR_MOVE(xvabsdp, OP_ABS, SGN_MASK_DP)
8014VSX_VECTOR_MOVE(xvnabsdp, OP_NABS, SGN_MASK_DP)
8015VSX_VECTOR_MOVE(xvnegdp, OP_NEG, SGN_MASK_DP)
8016VSX_VECTOR_MOVE(xvcpsgndp, OP_CPSGN, SGN_MASK_DP)
8017VSX_VECTOR_MOVE(xvabssp, OP_ABS, SGN_MASK_SP)
8018VSX_VECTOR_MOVE(xvnabssp, OP_NABS, SGN_MASK_SP)
8019VSX_VECTOR_MOVE(xvnegsp, OP_NEG, SGN_MASK_SP)
8020VSX_VECTOR_MOVE(xvcpsgnsp, OP_CPSGN, SGN_MASK_SP)
8021
8022#define GEN_VSX_HELPER_2(name, op1, op2, inval, type) \
8023static void gen_##name(DisasContext * ctx) \
8024{ \
8025 TCGv_i32 opc; \
8026 if (unlikely(!ctx->vsx_enabled)) { \
8027 gen_exception(ctx, POWERPC_EXCP_VSXU); \
8028 return; \
8029 } \
8030 \
8031 gen_update_nip(ctx, ctx->nip - 4); \
8032 opc = tcg_const_i32(ctx->opcode); \
8033 gen_helper_##name(cpu_env, opc); \
8034 tcg_temp_free_i32(opc); \
8035}
8036
8037#define GEN_VSX_HELPER_XT_XB_ENV(name, op1, op2, inval, type) \
8038static void gen_##name(DisasContext * ctx) \
8039{ \
8040 if (unlikely(!ctx->vsx_enabled)) { \
8041 gen_exception(ctx, POWERPC_EXCP_VSXU); \
8042 return; \
8043 } \
8044 \
8045 \
8046 gen_update_nip(ctx, ctx->nip - 4); \
8047 \
8048 gen_helper_##name(cpu_vsrh(xT(ctx->opcode)), cpu_env, \
8049 cpu_vsrh(xB(ctx->opcode))); \
8050}
8051
8052GEN_VSX_HELPER_2(xsadddp, 0x00, 0x04, 0, PPC2_VSX)
8053GEN_VSX_HELPER_2(xssubdp, 0x00, 0x05, 0, PPC2_VSX)
8054GEN_VSX_HELPER_2(xsmuldp, 0x00, 0x06, 0, PPC2_VSX)
8055GEN_VSX_HELPER_2(xsdivdp, 0x00, 0x07, 0, PPC2_VSX)
8056GEN_VSX_HELPER_2(xsredp, 0x14, 0x05, 0, PPC2_VSX)
8057GEN_VSX_HELPER_2(xssqrtdp, 0x16, 0x04, 0, PPC2_VSX)
8058GEN_VSX_HELPER_2(xsrsqrtedp, 0x14, 0x04, 0, PPC2_VSX)
8059GEN_VSX_HELPER_2(xstdivdp, 0x14, 0x07, 0, PPC2_VSX)
8060GEN_VSX_HELPER_2(xstsqrtdp, 0x14, 0x06, 0, PPC2_VSX)
8061GEN_VSX_HELPER_2(xsmaddadp, 0x04, 0x04, 0, PPC2_VSX)
8062GEN_VSX_HELPER_2(xsmaddmdp, 0x04, 0x05, 0, PPC2_VSX)
8063GEN_VSX_HELPER_2(xsmsubadp, 0x04, 0x06, 0, PPC2_VSX)
8064GEN_VSX_HELPER_2(xsmsubmdp, 0x04, 0x07, 0, PPC2_VSX)
8065GEN_VSX_HELPER_2(xsnmaddadp, 0x04, 0x14, 0, PPC2_VSX)
8066GEN_VSX_HELPER_2(xsnmaddmdp, 0x04, 0x15, 0, PPC2_VSX)
8067GEN_VSX_HELPER_2(xsnmsubadp, 0x04, 0x16, 0, PPC2_VSX)
8068GEN_VSX_HELPER_2(xsnmsubmdp, 0x04, 0x17, 0, PPC2_VSX)
8069GEN_VSX_HELPER_2(xscmpodp, 0x0C, 0x05, 0, PPC2_VSX)
8070GEN_VSX_HELPER_2(xscmpudp, 0x0C, 0x04, 0, PPC2_VSX)
8071GEN_VSX_HELPER_2(xsmaxdp, 0x00, 0x14, 0, PPC2_VSX)
8072GEN_VSX_HELPER_2(xsmindp, 0x00, 0x15, 0, PPC2_VSX)
8073GEN_VSX_HELPER_2(xscvdpsp, 0x12, 0x10, 0, PPC2_VSX)
8074GEN_VSX_HELPER_XT_XB_ENV(xscvdpspn, 0x16, 0x10, 0, PPC2_VSX207)
8075GEN_VSX_HELPER_2(xscvspdp, 0x12, 0x14, 0, PPC2_VSX)
8076GEN_VSX_HELPER_XT_XB_ENV(xscvspdpn, 0x16, 0x14, 0, PPC2_VSX207)
8077GEN_VSX_HELPER_2(xscvdpsxds, 0x10, 0x15, 0, PPC2_VSX)
8078GEN_VSX_HELPER_2(xscvdpsxws, 0x10, 0x05, 0, PPC2_VSX)
8079GEN_VSX_HELPER_2(xscvdpuxds, 0x10, 0x14, 0, PPC2_VSX)
8080GEN_VSX_HELPER_2(xscvdpuxws, 0x10, 0x04, 0, PPC2_VSX)
8081GEN_VSX_HELPER_2(xscvsxddp, 0x10, 0x17, 0, PPC2_VSX)
8082GEN_VSX_HELPER_2(xscvuxddp, 0x10, 0x16, 0, PPC2_VSX)
8083GEN_VSX_HELPER_2(xsrdpi, 0x12, 0x04, 0, PPC2_VSX)
8084GEN_VSX_HELPER_2(xsrdpic, 0x16, 0x06, 0, PPC2_VSX)
8085GEN_VSX_HELPER_2(xsrdpim, 0x12, 0x07, 0, PPC2_VSX)
8086GEN_VSX_HELPER_2(xsrdpip, 0x12, 0x06, 0, PPC2_VSX)
8087GEN_VSX_HELPER_2(xsrdpiz, 0x12, 0x05, 0, PPC2_VSX)
8088GEN_VSX_HELPER_XT_XB_ENV(xsrsp, 0x12, 0x11, 0, PPC2_VSX207)
8089
8090GEN_VSX_HELPER_2(xsaddsp, 0x00, 0x00, 0, PPC2_VSX207)
8091GEN_VSX_HELPER_2(xssubsp, 0x00, 0x01, 0, PPC2_VSX207)
8092GEN_VSX_HELPER_2(xsmulsp, 0x00, 0x02, 0, PPC2_VSX207)
8093GEN_VSX_HELPER_2(xsdivsp, 0x00, 0x03, 0, PPC2_VSX207)
8094GEN_VSX_HELPER_2(xsresp, 0x14, 0x01, 0, PPC2_VSX207)
8095GEN_VSX_HELPER_2(xssqrtsp, 0x16, 0x00, 0, PPC2_VSX207)
8096GEN_VSX_HELPER_2(xsrsqrtesp, 0x14, 0x00, 0, PPC2_VSX207)
8097GEN_VSX_HELPER_2(xsmaddasp, 0x04, 0x00, 0, PPC2_VSX207)
8098GEN_VSX_HELPER_2(xsmaddmsp, 0x04, 0x01, 0, PPC2_VSX207)
8099GEN_VSX_HELPER_2(xsmsubasp, 0x04, 0x02, 0, PPC2_VSX207)
8100GEN_VSX_HELPER_2(xsmsubmsp, 0x04, 0x03, 0, PPC2_VSX207)
8101GEN_VSX_HELPER_2(xsnmaddasp, 0x04, 0x10, 0, PPC2_VSX207)
8102GEN_VSX_HELPER_2(xsnmaddmsp, 0x04, 0x11, 0, PPC2_VSX207)
8103GEN_VSX_HELPER_2(xsnmsubasp, 0x04, 0x12, 0, PPC2_VSX207)
8104GEN_VSX_HELPER_2(xsnmsubmsp, 0x04, 0x13, 0, PPC2_VSX207)
8105GEN_VSX_HELPER_2(xscvsxdsp, 0x10, 0x13, 0, PPC2_VSX207)
8106GEN_VSX_HELPER_2(xscvuxdsp, 0x10, 0x12, 0, PPC2_VSX207)
8107
8108GEN_VSX_HELPER_2(xvadddp, 0x00, 0x0C, 0, PPC2_VSX)
8109GEN_VSX_HELPER_2(xvsubdp, 0x00, 0x0D, 0, PPC2_VSX)
8110GEN_VSX_HELPER_2(xvmuldp, 0x00, 0x0E, 0, PPC2_VSX)
8111GEN_VSX_HELPER_2(xvdivdp, 0x00, 0x0F, 0, PPC2_VSX)
8112GEN_VSX_HELPER_2(xvredp, 0x14, 0x0D, 0, PPC2_VSX)
8113GEN_VSX_HELPER_2(xvsqrtdp, 0x16, 0x0C, 0, PPC2_VSX)
8114GEN_VSX_HELPER_2(xvrsqrtedp, 0x14, 0x0C, 0, PPC2_VSX)
8115GEN_VSX_HELPER_2(xvtdivdp, 0x14, 0x0F, 0, PPC2_VSX)
8116GEN_VSX_HELPER_2(xvtsqrtdp, 0x14, 0x0E, 0, PPC2_VSX)
8117GEN_VSX_HELPER_2(xvmaddadp, 0x04, 0x0C, 0, PPC2_VSX)
8118GEN_VSX_HELPER_2(xvmaddmdp, 0x04, 0x0D, 0, PPC2_VSX)
8119GEN_VSX_HELPER_2(xvmsubadp, 0x04, 0x0E, 0, PPC2_VSX)
8120GEN_VSX_HELPER_2(xvmsubmdp, 0x04, 0x0F, 0, PPC2_VSX)
8121GEN_VSX_HELPER_2(xvnmaddadp, 0x04, 0x1C, 0, PPC2_VSX)
8122GEN_VSX_HELPER_2(xvnmaddmdp, 0x04, 0x1D, 0, PPC2_VSX)
8123GEN_VSX_HELPER_2(xvnmsubadp, 0x04, 0x1E, 0, PPC2_VSX)
8124GEN_VSX_HELPER_2(xvnmsubmdp, 0x04, 0x1F, 0, PPC2_VSX)
8125GEN_VSX_HELPER_2(xvmaxdp, 0x00, 0x1C, 0, PPC2_VSX)
8126GEN_VSX_HELPER_2(xvmindp, 0x00, 0x1D, 0, PPC2_VSX)
8127GEN_VSX_HELPER_2(xvcmpeqdp, 0x0C, 0x0C, 0, PPC2_VSX)
8128GEN_VSX_HELPER_2(xvcmpgtdp, 0x0C, 0x0D, 0, PPC2_VSX)
8129GEN_VSX_HELPER_2(xvcmpgedp, 0x0C, 0x0E, 0, PPC2_VSX)
8130GEN_VSX_HELPER_2(xvcvdpsp, 0x12, 0x18, 0, PPC2_VSX)
8131GEN_VSX_HELPER_2(xvcvdpsxds, 0x10, 0x1D, 0, PPC2_VSX)
8132GEN_VSX_HELPER_2(xvcvdpsxws, 0x10, 0x0D, 0, PPC2_VSX)
8133GEN_VSX_HELPER_2(xvcvdpuxds, 0x10, 0x1C, 0, PPC2_VSX)
8134GEN_VSX_HELPER_2(xvcvdpuxws, 0x10, 0x0C, 0, PPC2_VSX)
8135GEN_VSX_HELPER_2(xvcvsxddp, 0x10, 0x1F, 0, PPC2_VSX)
8136GEN_VSX_HELPER_2(xvcvuxddp, 0x10, 0x1E, 0, PPC2_VSX)
8137GEN_VSX_HELPER_2(xvcvsxwdp, 0x10, 0x0F, 0, PPC2_VSX)
8138GEN_VSX_HELPER_2(xvcvuxwdp, 0x10, 0x0E, 0, PPC2_VSX)
8139GEN_VSX_HELPER_2(xvrdpi, 0x12, 0x0C, 0, PPC2_VSX)
8140GEN_VSX_HELPER_2(xvrdpic, 0x16, 0x0E, 0, PPC2_VSX)
8141GEN_VSX_HELPER_2(xvrdpim, 0x12, 0x0F, 0, PPC2_VSX)
8142GEN_VSX_HELPER_2(xvrdpip, 0x12, 0x0E, 0, PPC2_VSX)
8143GEN_VSX_HELPER_2(xvrdpiz, 0x12, 0x0D, 0, PPC2_VSX)
8144
8145GEN_VSX_HELPER_2(xvaddsp, 0x00, 0x08, 0, PPC2_VSX)
8146GEN_VSX_HELPER_2(xvsubsp, 0x00, 0x09, 0, PPC2_VSX)
8147GEN_VSX_HELPER_2(xvmulsp, 0x00, 0x0A, 0, PPC2_VSX)
8148GEN_VSX_HELPER_2(xvdivsp, 0x00, 0x0B, 0, PPC2_VSX)
8149GEN_VSX_HELPER_2(xvresp, 0x14, 0x09, 0, PPC2_VSX)
8150GEN_VSX_HELPER_2(xvsqrtsp, 0x16, 0x08, 0, PPC2_VSX)
8151GEN_VSX_HELPER_2(xvrsqrtesp, 0x14, 0x08, 0, PPC2_VSX)
8152GEN_VSX_HELPER_2(xvtdivsp, 0x14, 0x0B, 0, PPC2_VSX)
8153GEN_VSX_HELPER_2(xvtsqrtsp, 0x14, 0x0A, 0, PPC2_VSX)
8154GEN_VSX_HELPER_2(xvmaddasp, 0x04, 0x08, 0, PPC2_VSX)
8155GEN_VSX_HELPER_2(xvmaddmsp, 0x04, 0x09, 0, PPC2_VSX)
8156GEN_VSX_HELPER_2(xvmsubasp, 0x04, 0x0A, 0, PPC2_VSX)
8157GEN_VSX_HELPER_2(xvmsubmsp, 0x04, 0x0B, 0, PPC2_VSX)
8158GEN_VSX_HELPER_2(xvnmaddasp, 0x04, 0x18, 0, PPC2_VSX)
8159GEN_VSX_HELPER_2(xvnmaddmsp, 0x04, 0x19, 0, PPC2_VSX)
8160GEN_VSX_HELPER_2(xvnmsubasp, 0x04, 0x1A, 0, PPC2_VSX)
8161GEN_VSX_HELPER_2(xvnmsubmsp, 0x04, 0x1B, 0, PPC2_VSX)
8162GEN_VSX_HELPER_2(xvmaxsp, 0x00, 0x18, 0, PPC2_VSX)
8163GEN_VSX_HELPER_2(xvminsp, 0x00, 0x19, 0, PPC2_VSX)
8164GEN_VSX_HELPER_2(xvcmpeqsp, 0x0C, 0x08, 0, PPC2_VSX)
8165GEN_VSX_HELPER_2(xvcmpgtsp, 0x0C, 0x09, 0, PPC2_VSX)
8166GEN_VSX_HELPER_2(xvcmpgesp, 0x0C, 0x0A, 0, PPC2_VSX)
8167GEN_VSX_HELPER_2(xvcvspdp, 0x12, 0x1C, 0, PPC2_VSX)
8168GEN_VSX_HELPER_2(xvcvspsxds, 0x10, 0x19, 0, PPC2_VSX)
8169GEN_VSX_HELPER_2(xvcvspsxws, 0x10, 0x09, 0, PPC2_VSX)
8170GEN_VSX_HELPER_2(xvcvspuxds, 0x10, 0x18, 0, PPC2_VSX)
8171GEN_VSX_HELPER_2(xvcvspuxws, 0x10, 0x08, 0, PPC2_VSX)
8172GEN_VSX_HELPER_2(xvcvsxdsp, 0x10, 0x1B, 0, PPC2_VSX)
8173GEN_VSX_HELPER_2(xvcvuxdsp, 0x10, 0x1A, 0, PPC2_VSX)
8174GEN_VSX_HELPER_2(xvcvsxwsp, 0x10, 0x0B, 0, PPC2_VSX)
8175GEN_VSX_HELPER_2(xvcvuxwsp, 0x10, 0x0A, 0, PPC2_VSX)
8176GEN_VSX_HELPER_2(xvrspi, 0x12, 0x08, 0, PPC2_VSX)
8177GEN_VSX_HELPER_2(xvrspic, 0x16, 0x0A, 0, PPC2_VSX)
8178GEN_VSX_HELPER_2(xvrspim, 0x12, 0x0B, 0, PPC2_VSX)
8179GEN_VSX_HELPER_2(xvrspip, 0x12, 0x0A, 0, PPC2_VSX)
8180GEN_VSX_HELPER_2(xvrspiz, 0x12, 0x09, 0, PPC2_VSX)
8181
8182#define VSX_LOGICAL(name, tcg_op) \
8183static void glue(gen_, name)(DisasContext * ctx) \
8184 { \
8185 if (unlikely(!ctx->vsx_enabled)) { \
8186 gen_exception(ctx, POWERPC_EXCP_VSXU); \
8187 return; \
8188 } \
8189 tcg_op(cpu_vsrh(xT(ctx->opcode)), cpu_vsrh(xA(ctx->opcode)), \
8190 cpu_vsrh(xB(ctx->opcode))); \
8191 tcg_op(cpu_vsrl(xT(ctx->opcode)), cpu_vsrl(xA(ctx->opcode)), \
8192 cpu_vsrl(xB(ctx->opcode))); \
8193 }
8194
8195VSX_LOGICAL(xxland, tcg_gen_and_i64)
8196VSX_LOGICAL(xxlandc, tcg_gen_andc_i64)
8197VSX_LOGICAL(xxlor, tcg_gen_or_i64)
8198VSX_LOGICAL(xxlxor, tcg_gen_xor_i64)
8199VSX_LOGICAL(xxlnor, tcg_gen_nor_i64)
8200VSX_LOGICAL(xxleqv, tcg_gen_eqv_i64)
8201VSX_LOGICAL(xxlnand, tcg_gen_nand_i64)
8202VSX_LOGICAL(xxlorc, tcg_gen_orc_i64)
8203
8204#define VSX_XXMRG(name, high) \
8205static void glue(gen_, name)(DisasContext * ctx) \
8206 { \
8207 TCGv_i64 a0, a1, b0, b1; \
8208 if (unlikely(!ctx->vsx_enabled)) { \
8209 gen_exception(ctx, POWERPC_EXCP_VSXU); \
8210 return; \
8211 } \
8212 a0 = tcg_temp_new_i64(); \
8213 a1 = tcg_temp_new_i64(); \
8214 b0 = tcg_temp_new_i64(); \
8215 b1 = tcg_temp_new_i64(); \
8216 if (high) { \
8217 tcg_gen_mov_i64(a0, cpu_vsrh(xA(ctx->opcode))); \
8218 tcg_gen_mov_i64(a1, cpu_vsrh(xA(ctx->opcode))); \
8219 tcg_gen_mov_i64(b0, cpu_vsrh(xB(ctx->opcode))); \
8220 tcg_gen_mov_i64(b1, cpu_vsrh(xB(ctx->opcode))); \
8221 } else { \
8222 tcg_gen_mov_i64(a0, cpu_vsrl(xA(ctx->opcode))); \
8223 tcg_gen_mov_i64(a1, cpu_vsrl(xA(ctx->opcode))); \
8224 tcg_gen_mov_i64(b0, cpu_vsrl(xB(ctx->opcode))); \
8225 tcg_gen_mov_i64(b1, cpu_vsrl(xB(ctx->opcode))); \
8226 } \
8227 tcg_gen_shri_i64(a0, a0, 32); \
8228 tcg_gen_shri_i64(b0, b0, 32); \
8229 tcg_gen_deposit_i64(cpu_vsrh(xT(ctx->opcode)), \
8230 b0, a0, 32, 32); \
8231 tcg_gen_deposit_i64(cpu_vsrl(xT(ctx->opcode)), \
8232 b1, a1, 32, 32); \
8233 tcg_temp_free_i64(a0); \
8234 tcg_temp_free_i64(a1); \
8235 tcg_temp_free_i64(b0); \
8236 tcg_temp_free_i64(b1); \
8237 }
8238
8239VSX_XXMRG(xxmrghw, 1)
8240VSX_XXMRG(xxmrglw, 0)
8241
8242static void gen_xxsel(DisasContext * ctx)
8243{
8244 TCGv_i64 a, b, c;
8245 if (unlikely(!ctx->vsx_enabled)) {
8246 gen_exception(ctx, POWERPC_EXCP_VSXU);
8247 return;
8248 }
8249 a = tcg_temp_new_i64();
8250 b = tcg_temp_new_i64();
8251 c = tcg_temp_new_i64();
8252
8253 tcg_gen_mov_i64(a, cpu_vsrh(xA(ctx->opcode)));
8254 tcg_gen_mov_i64(b, cpu_vsrh(xB(ctx->opcode)));
8255 tcg_gen_mov_i64(c, cpu_vsrh(xC(ctx->opcode)));
8256
8257 tcg_gen_and_i64(b, b, c);
8258 tcg_gen_andc_i64(a, a, c);
8259 tcg_gen_or_i64(cpu_vsrh(xT(ctx->opcode)), a, b);
8260
8261 tcg_gen_mov_i64(a, cpu_vsrl(xA(ctx->opcode)));
8262 tcg_gen_mov_i64(b, cpu_vsrl(xB(ctx->opcode)));
8263 tcg_gen_mov_i64(c, cpu_vsrl(xC(ctx->opcode)));
8264
8265 tcg_gen_and_i64(b, b, c);
8266 tcg_gen_andc_i64(a, a, c);
8267 tcg_gen_or_i64(cpu_vsrl(xT(ctx->opcode)), a, b);
8268
8269 tcg_temp_free_i64(a);
8270 tcg_temp_free_i64(b);
8271 tcg_temp_free_i64(c);
8272}
8273
8274static void gen_xxspltw(DisasContext *ctx)
8275{
8276 TCGv_i64 b, b2;
8277 TCGv_i64 vsr = (UIM(ctx->opcode) & 2) ?
8278 cpu_vsrl(xB(ctx->opcode)) :
8279 cpu_vsrh(xB(ctx->opcode));
8280
8281 if (unlikely(!ctx->vsx_enabled)) {
8282 gen_exception(ctx, POWERPC_EXCP_VSXU);
8283 return;
8284 }
8285
8286 b = tcg_temp_new_i64();
8287 b2 = tcg_temp_new_i64();
8288
8289 if (UIM(ctx->opcode) & 1) {
8290 tcg_gen_ext32u_i64(b, vsr);
8291 } else {
8292 tcg_gen_shri_i64(b, vsr, 32);
8293 }
8294
8295 tcg_gen_shli_i64(b2, b, 32);
8296 tcg_gen_or_i64(cpu_vsrh(xT(ctx->opcode)), b, b2);
8297 tcg_gen_mov_i64(cpu_vsrl(xT(ctx->opcode)), cpu_vsrh(xT(ctx->opcode)));
8298
8299 tcg_temp_free_i64(b);
8300 tcg_temp_free_i64(b2);
8301}
8302
8303static void gen_xxsldwi(DisasContext *ctx)
8304{
8305 TCGv_i64 xth, xtl;
8306 if (unlikely(!ctx->vsx_enabled)) {
8307 gen_exception(ctx, POWERPC_EXCP_VSXU);
8308 return;
8309 }
8310 xth = tcg_temp_new_i64();
8311 xtl = tcg_temp_new_i64();
8312
8313 switch (SHW(ctx->opcode)) {
8314 case 0: {
8315 tcg_gen_mov_i64(xth, cpu_vsrh(xA(ctx->opcode)));
8316 tcg_gen_mov_i64(xtl, cpu_vsrl(xA(ctx->opcode)));
8317 break;
8318 }
8319 case 1: {
8320 TCGv_i64 t0 = tcg_temp_new_i64();
8321 tcg_gen_mov_i64(xth, cpu_vsrh(xA(ctx->opcode)));
8322 tcg_gen_shli_i64(xth, xth, 32);
8323 tcg_gen_mov_i64(t0, cpu_vsrl(xA(ctx->opcode)));
8324 tcg_gen_shri_i64(t0, t0, 32);
8325 tcg_gen_or_i64(xth, xth, t0);
8326 tcg_gen_mov_i64(xtl, cpu_vsrl(xA(ctx->opcode)));
8327 tcg_gen_shli_i64(xtl, xtl, 32);
8328 tcg_gen_mov_i64(t0, cpu_vsrh(xB(ctx->opcode)));
8329 tcg_gen_shri_i64(t0, t0, 32);
8330 tcg_gen_or_i64(xtl, xtl, t0);
8331 tcg_temp_free_i64(t0);
8332 break;
8333 }
8334 case 2: {
8335 tcg_gen_mov_i64(xth, cpu_vsrl(xA(ctx->opcode)));
8336 tcg_gen_mov_i64(xtl, cpu_vsrh(xB(ctx->opcode)));
8337 break;
8338 }
8339 case 3: {
8340 TCGv_i64 t0 = tcg_temp_new_i64();
8341 tcg_gen_mov_i64(xth, cpu_vsrl(xA(ctx->opcode)));
8342 tcg_gen_shli_i64(xth, xth, 32);
8343 tcg_gen_mov_i64(t0, cpu_vsrh(xB(ctx->opcode)));
8344 tcg_gen_shri_i64(t0, t0, 32);
8345 tcg_gen_or_i64(xth, xth, t0);
8346 tcg_gen_mov_i64(xtl, cpu_vsrh(xB(ctx->opcode)));
8347 tcg_gen_shli_i64(xtl, xtl, 32);
8348 tcg_gen_mov_i64(t0, cpu_vsrl(xB(ctx->opcode)));
8349 tcg_gen_shri_i64(t0, t0, 32);
8350 tcg_gen_or_i64(xtl, xtl, t0);
8351 tcg_temp_free_i64(t0);
8352 break;
8353 }
8354 }
8355
8356 tcg_gen_mov_i64(cpu_vsrh(xT(ctx->opcode)), xth);
8357 tcg_gen_mov_i64(cpu_vsrl(xT(ctx->opcode)), xtl);
8358
8359 tcg_temp_free_i64(xth);
8360 tcg_temp_free_i64(xtl);
8361}
8362
8363
8364
8365static inline TCGv_ptr gen_fprp_ptr(int reg)
8366{
8367 TCGv_ptr r = tcg_temp_new_ptr();
8368 tcg_gen_addi_ptr(r, cpu_env, offsetof(CPUPPCState, fpr[reg]));
8369 return r;
8370}
8371
8372#define GEN_DFP_T_A_B_Rc(name) \
8373static void gen_##name(DisasContext *ctx) \
8374{ \
8375 TCGv_ptr rd, ra, rb; \
8376 if (unlikely(!ctx->fpu_enabled)) { \
8377 gen_exception(ctx, POWERPC_EXCP_FPU); \
8378 return; \
8379 } \
8380 gen_update_nip(ctx, ctx->nip - 4); \
8381 rd = gen_fprp_ptr(rD(ctx->opcode)); \
8382 ra = gen_fprp_ptr(rA(ctx->opcode)); \
8383 rb = gen_fprp_ptr(rB(ctx->opcode)); \
8384 gen_helper_##name(cpu_env, rd, ra, rb); \
8385 if (unlikely(Rc(ctx->opcode) != 0)) { \
8386 gen_set_cr1_from_fpscr(ctx); \
8387 } \
8388 tcg_temp_free_ptr(rd); \
8389 tcg_temp_free_ptr(ra); \
8390 tcg_temp_free_ptr(rb); \
8391}
8392
8393#define GEN_DFP_BF_A_B(name) \
8394static void gen_##name(DisasContext *ctx) \
8395{ \
8396 TCGv_ptr ra, rb; \
8397 if (unlikely(!ctx->fpu_enabled)) { \
8398 gen_exception(ctx, POWERPC_EXCP_FPU); \
8399 return; \
8400 } \
8401 gen_update_nip(ctx, ctx->nip - 4); \
8402 ra = gen_fprp_ptr(rA(ctx->opcode)); \
8403 rb = gen_fprp_ptr(rB(ctx->opcode)); \
8404 gen_helper_##name(cpu_crf[crfD(ctx->opcode)], \
8405 cpu_env, ra, rb); \
8406 tcg_temp_free_ptr(ra); \
8407 tcg_temp_free_ptr(rb); \
8408}
8409
8410#define GEN_DFP_BF_A_DCM(name) \
8411static void gen_##name(DisasContext *ctx) \
8412{ \
8413 TCGv_ptr ra; \
8414 TCGv_i32 dcm; \
8415 if (unlikely(!ctx->fpu_enabled)) { \
8416 gen_exception(ctx, POWERPC_EXCP_FPU); \
8417 return; \
8418 } \
8419 gen_update_nip(ctx, ctx->nip - 4); \
8420 ra = gen_fprp_ptr(rA(ctx->opcode)); \
8421 dcm = tcg_const_i32(DCM(ctx->opcode)); \
8422 gen_helper_##name(cpu_crf[crfD(ctx->opcode)], \
8423 cpu_env, ra, dcm); \
8424 tcg_temp_free_ptr(ra); \
8425 tcg_temp_free_i32(dcm); \
8426}
8427
8428#define GEN_DFP_T_B_U32_U32_Rc(name, u32f1, u32f2) \
8429static void gen_##name(DisasContext *ctx) \
8430{ \
8431 TCGv_ptr rt, rb; \
8432 TCGv_i32 u32_1, u32_2; \
8433 if (unlikely(!ctx->fpu_enabled)) { \
8434 gen_exception(ctx, POWERPC_EXCP_FPU); \
8435 return; \
8436 } \
8437 gen_update_nip(ctx, ctx->nip - 4); \
8438 rt = gen_fprp_ptr(rD(ctx->opcode)); \
8439 rb = gen_fprp_ptr(rB(ctx->opcode)); \
8440 u32_1 = tcg_const_i32(u32f1(ctx->opcode)); \
8441 u32_2 = tcg_const_i32(u32f2(ctx->opcode)); \
8442 gen_helper_##name(cpu_env, rt, rb, u32_1, u32_2); \
8443 if (unlikely(Rc(ctx->opcode) != 0)) { \
8444 gen_set_cr1_from_fpscr(ctx); \
8445 } \
8446 tcg_temp_free_ptr(rt); \
8447 tcg_temp_free_ptr(rb); \
8448 tcg_temp_free_i32(u32_1); \
8449 tcg_temp_free_i32(u32_2); \
8450}
8451
8452#define GEN_DFP_T_A_B_I32_Rc(name, i32fld) \
8453static void gen_##name(DisasContext *ctx) \
8454{ \
8455 TCGv_ptr rt, ra, rb; \
8456 TCGv_i32 i32; \
8457 if (unlikely(!ctx->fpu_enabled)) { \
8458 gen_exception(ctx, POWERPC_EXCP_FPU); \
8459 return; \
8460 } \
8461 gen_update_nip(ctx, ctx->nip - 4); \
8462 rt = gen_fprp_ptr(rD(ctx->opcode)); \
8463 ra = gen_fprp_ptr(rA(ctx->opcode)); \
8464 rb = gen_fprp_ptr(rB(ctx->opcode)); \
8465 i32 = tcg_const_i32(i32fld(ctx->opcode)); \
8466 gen_helper_##name(cpu_env, rt, ra, rb, i32); \
8467 if (unlikely(Rc(ctx->opcode) != 0)) { \
8468 gen_set_cr1_from_fpscr(ctx); \
8469 } \
8470 tcg_temp_free_ptr(rt); \
8471 tcg_temp_free_ptr(rb); \
8472 tcg_temp_free_ptr(ra); \
8473 tcg_temp_free_i32(i32); \
8474 }
8475
8476#define GEN_DFP_T_B_Rc(name) \
8477static void gen_##name(DisasContext *ctx) \
8478{ \
8479 TCGv_ptr rt, rb; \
8480 if (unlikely(!ctx->fpu_enabled)) { \
8481 gen_exception(ctx, POWERPC_EXCP_FPU); \
8482 return; \
8483 } \
8484 gen_update_nip(ctx, ctx->nip - 4); \
8485 rt = gen_fprp_ptr(rD(ctx->opcode)); \
8486 rb = gen_fprp_ptr(rB(ctx->opcode)); \
8487 gen_helper_##name(cpu_env, rt, rb); \
8488 if (unlikely(Rc(ctx->opcode) != 0)) { \
8489 gen_set_cr1_from_fpscr(ctx); \
8490 } \
8491 tcg_temp_free_ptr(rt); \
8492 tcg_temp_free_ptr(rb); \
8493 }
8494
8495#define GEN_DFP_T_FPR_I32_Rc(name, fprfld, i32fld) \
8496static void gen_##name(DisasContext *ctx) \
8497{ \
8498 TCGv_ptr rt, rs; \
8499 TCGv_i32 i32; \
8500 if (unlikely(!ctx->fpu_enabled)) { \
8501 gen_exception(ctx, POWERPC_EXCP_FPU); \
8502 return; \
8503 } \
8504 gen_update_nip(ctx, ctx->nip - 4); \
8505 rt = gen_fprp_ptr(rD(ctx->opcode)); \
8506 rs = gen_fprp_ptr(fprfld(ctx->opcode)); \
8507 i32 = tcg_const_i32(i32fld(ctx->opcode)); \
8508 gen_helper_##name(cpu_env, rt, rs, i32); \
8509 if (unlikely(Rc(ctx->opcode) != 0)) { \
8510 gen_set_cr1_from_fpscr(ctx); \
8511 } \
8512 tcg_temp_free_ptr(rt); \
8513 tcg_temp_free_ptr(rs); \
8514 tcg_temp_free_i32(i32); \
8515}
8516
8517GEN_DFP_T_A_B_Rc(dadd)
8518GEN_DFP_T_A_B_Rc(daddq)
8519GEN_DFP_T_A_B_Rc(dsub)
8520GEN_DFP_T_A_B_Rc(dsubq)
8521GEN_DFP_T_A_B_Rc(dmul)
8522GEN_DFP_T_A_B_Rc(dmulq)
8523GEN_DFP_T_A_B_Rc(ddiv)
8524GEN_DFP_T_A_B_Rc(ddivq)
8525GEN_DFP_BF_A_B(dcmpu)
8526GEN_DFP_BF_A_B(dcmpuq)
8527GEN_DFP_BF_A_B(dcmpo)
8528GEN_DFP_BF_A_B(dcmpoq)
8529GEN_DFP_BF_A_DCM(dtstdc)
8530GEN_DFP_BF_A_DCM(dtstdcq)
8531GEN_DFP_BF_A_DCM(dtstdg)
8532GEN_DFP_BF_A_DCM(dtstdgq)
8533GEN_DFP_BF_A_B(dtstex)
8534GEN_DFP_BF_A_B(dtstexq)
8535GEN_DFP_BF_A_B(dtstsf)
8536GEN_DFP_BF_A_B(dtstsfq)
8537GEN_DFP_T_B_U32_U32_Rc(dquai, SIMM5, RMC)
8538GEN_DFP_T_B_U32_U32_Rc(dquaiq, SIMM5, RMC)
8539GEN_DFP_T_A_B_I32_Rc(dqua, RMC)
8540GEN_DFP_T_A_B_I32_Rc(dquaq, RMC)
8541GEN_DFP_T_A_B_I32_Rc(drrnd, RMC)
8542GEN_DFP_T_A_B_I32_Rc(drrndq, RMC)
8543GEN_DFP_T_B_U32_U32_Rc(drintx, FPW, RMC)
8544GEN_DFP_T_B_U32_U32_Rc(drintxq, FPW, RMC)
8545GEN_DFP_T_B_U32_U32_Rc(drintn, FPW, RMC)
8546GEN_DFP_T_B_U32_U32_Rc(drintnq, FPW, RMC)
8547GEN_DFP_T_B_Rc(dctdp)
8548GEN_DFP_T_B_Rc(dctqpq)
8549GEN_DFP_T_B_Rc(drsp)
8550GEN_DFP_T_B_Rc(drdpq)
8551GEN_DFP_T_B_Rc(dcffix)
8552GEN_DFP_T_B_Rc(dcffixq)
8553GEN_DFP_T_B_Rc(dctfix)
8554GEN_DFP_T_B_Rc(dctfixq)
8555GEN_DFP_T_FPR_I32_Rc(ddedpd, rB, SP)
8556GEN_DFP_T_FPR_I32_Rc(ddedpdq, rB, SP)
8557GEN_DFP_T_FPR_I32_Rc(denbcd, rB, SP)
8558GEN_DFP_T_FPR_I32_Rc(denbcdq, rB, SP)
8559GEN_DFP_T_B_Rc(dxex)
8560GEN_DFP_T_B_Rc(dxexq)
8561GEN_DFP_T_A_B_Rc(diex)
8562GEN_DFP_T_A_B_Rc(diexq)
8563GEN_DFP_T_FPR_I32_Rc(dscli, rA, DCM)
8564GEN_DFP_T_FPR_I32_Rc(dscliq, rA, DCM)
8565GEN_DFP_T_FPR_I32_Rc(dscri, rA, DCM)
8566GEN_DFP_T_FPR_I32_Rc(dscriq, rA, DCM)
8567
8568
8569
8570
8571static inline void gen_evmra(DisasContext *ctx)
8572{
8573
8574 if (unlikely(!ctx->spe_enabled)) {
8575 gen_exception(ctx, POWERPC_EXCP_SPEU);
8576 return;
8577 }
8578
8579 TCGv_i64 tmp = tcg_temp_new_i64();
8580
8581
8582 tcg_gen_concat_tl_i64(tmp, cpu_gpr[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
8583
8584
8585 tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUPPCState, spe_acc));
8586 tcg_temp_free_i64(tmp);
8587
8588
8589 tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
8590 tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
8591}
8592
8593static inline void gen_load_gpr64(TCGv_i64 t, int reg)
8594{
8595 tcg_gen_concat_tl_i64(t, cpu_gpr[reg], cpu_gprh[reg]);
8596}
8597
8598static inline void gen_store_gpr64(int reg, TCGv_i64 t)
8599{
8600 tcg_gen_extr_i64_tl(cpu_gpr[reg], cpu_gprh[reg], t);
8601}
8602
8603#define GEN_SPE(name0, name1, opc2, opc3, inval0, inval1, type) \
8604static void glue(gen_, name0##_##name1)(DisasContext *ctx) \
8605{ \
8606 if (Rc(ctx->opcode)) \
8607 gen_##name1(ctx); \
8608 else \
8609 gen_##name0(ctx); \
8610}
8611
8612
8613static inline void gen_speundef(DisasContext *ctx)
8614{
8615 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
8616}
8617
8618
8619#define GEN_SPEOP_LOGIC2(name, tcg_op) \
8620static inline void gen_##name(DisasContext *ctx) \
8621{ \
8622 if (unlikely(!ctx->spe_enabled)) { \
8623 gen_exception(ctx, POWERPC_EXCP_SPEU); \
8624 return; \
8625 } \
8626 tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], \
8627 cpu_gpr[rB(ctx->opcode)]); \
8628 tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], \
8629 cpu_gprh[rB(ctx->opcode)]); \
8630}
8631
8632GEN_SPEOP_LOGIC2(evand, tcg_gen_and_tl);
8633GEN_SPEOP_LOGIC2(evandc, tcg_gen_andc_tl);
8634GEN_SPEOP_LOGIC2(evxor, tcg_gen_xor_tl);
8635GEN_SPEOP_LOGIC2(evor, tcg_gen_or_tl);
8636GEN_SPEOP_LOGIC2(evnor, tcg_gen_nor_tl);
8637GEN_SPEOP_LOGIC2(eveqv, tcg_gen_eqv_tl);
8638GEN_SPEOP_LOGIC2(evorc, tcg_gen_orc_tl);
8639GEN_SPEOP_LOGIC2(evnand, tcg_gen_nand_tl);
8640
8641
8642#define GEN_SPEOP_TCG_LOGIC_IMM2(name, tcg_opi) \
8643static inline void gen_##name(DisasContext *ctx) \
8644{ \
8645 TCGv_i32 t0; \
8646 if (unlikely(!ctx->spe_enabled)) { \
8647 gen_exception(ctx, POWERPC_EXCP_SPEU); \
8648 return; \
8649 } \
8650 t0 = tcg_temp_new_i32(); \
8651 \
8652 tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]); \
8653 tcg_opi(t0, t0, rB(ctx->opcode)); \
8654 tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0); \
8655 \
8656 tcg_gen_trunc_tl_i32(t0, cpu_gprh[rA(ctx->opcode)]); \
8657 tcg_opi(t0, t0, rB(ctx->opcode)); \
8658 tcg_gen_extu_i32_tl(cpu_gprh[rD(ctx->opcode)], t0); \
8659 \
8660 tcg_temp_free_i32(t0); \
8661}
8662GEN_SPEOP_TCG_LOGIC_IMM2(evslwi, tcg_gen_shli_i32);
8663GEN_SPEOP_TCG_LOGIC_IMM2(evsrwiu, tcg_gen_shri_i32);
8664GEN_SPEOP_TCG_LOGIC_IMM2(evsrwis, tcg_gen_sari_i32);
8665GEN_SPEOP_TCG_LOGIC_IMM2(evrlwi, tcg_gen_rotli_i32);
8666
8667
8668#define GEN_SPEOP_ARITH1(name, tcg_op) \
8669static inline void gen_##name(DisasContext *ctx) \
8670{ \
8671 TCGv_i32 t0; \
8672 if (unlikely(!ctx->spe_enabled)) { \
8673 gen_exception(ctx, POWERPC_EXCP_SPEU); \
8674 return; \
8675 } \
8676 t0 = tcg_temp_new_i32(); \
8677 \
8678 tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]); \
8679 tcg_op(t0, t0); \
8680 tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0); \
8681 \
8682 tcg_gen_trunc_tl_i32(t0, cpu_gprh[rA(ctx->opcode)]); \
8683 tcg_op(t0, t0); \
8684 tcg_gen_extu_i32_tl(cpu_gprh[rD(ctx->opcode)], t0); \
8685 \
8686 tcg_temp_free_i32(t0); \
8687}
8688
8689static inline void gen_op_evabs(TCGv_i32 ret, TCGv_i32 arg1)
8690{
8691 TCGLabel *l1 = gen_new_label();
8692 TCGLabel *l2 = gen_new_label();
8693
8694 tcg_gen_brcondi_i32(TCG_COND_GE, arg1, 0, l1);
8695 tcg_gen_neg_i32(ret, arg1);
8696 tcg_gen_br(l2);
8697 gen_set_label(l1);
8698 tcg_gen_mov_i32(ret, arg1);
8699 gen_set_label(l2);
8700}
8701GEN_SPEOP_ARITH1(evabs, gen_op_evabs);
8702GEN_SPEOP_ARITH1(evneg, tcg_gen_neg_i32);
8703GEN_SPEOP_ARITH1(evextsb, tcg_gen_ext8s_i32);
8704GEN_SPEOP_ARITH1(evextsh, tcg_gen_ext16s_i32);
8705static inline void gen_op_evrndw(TCGv_i32 ret, TCGv_i32 arg1)
8706{
8707 tcg_gen_addi_i32(ret, arg1, 0x8000);
8708 tcg_gen_ext16u_i32(ret, ret);
8709}
8710GEN_SPEOP_ARITH1(evrndw, gen_op_evrndw);
8711GEN_SPEOP_ARITH1(evcntlsw, gen_helper_cntlsw32);
8712GEN_SPEOP_ARITH1(evcntlzw, gen_helper_cntlzw32);
8713
8714#define GEN_SPEOP_ARITH2(name, tcg_op) \
8715static inline void gen_##name(DisasContext *ctx) \
8716{ \
8717 TCGv_i32 t0, t1; \
8718 if (unlikely(!ctx->spe_enabled)) { \
8719 gen_exception(ctx, POWERPC_EXCP_SPEU); \
8720 return; \
8721 } \
8722 t0 = tcg_temp_new_i32(); \
8723 t1 = tcg_temp_new_i32(); \
8724 \
8725 tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]); \
8726 tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]); \
8727 tcg_op(t0, t0, t1); \
8728 tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0); \
8729 \
8730 tcg_gen_trunc_tl_i32(t0, cpu_gprh[rA(ctx->opcode)]); \
8731 tcg_gen_trunc_tl_i32(t1, cpu_gprh[rB(ctx->opcode)]); \
8732 tcg_op(t0, t0, t1); \
8733 tcg_gen_extu_i32_tl(cpu_gprh[rD(ctx->opcode)], t0); \
8734 \
8735 tcg_temp_free_i32(t0); \
8736 tcg_temp_free_i32(t1); \
8737}
8738
8739static inline void gen_op_evsrwu(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
8740{
8741 TCGLabel *l1 = gen_new_label();
8742 TCGLabel *l2 = gen_new_label();
8743 TCGv_i32 t0 = tcg_temp_local_new_i32();
8744
8745
8746 tcg_gen_andi_i32(t0, arg2, 0x3F);
8747 tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1);
8748 tcg_gen_shr_i32(ret, arg1, t0);
8749 tcg_gen_br(l2);
8750 gen_set_label(l1);
8751 tcg_gen_movi_i32(ret, 0);
8752 gen_set_label(l2);
8753 tcg_temp_free_i32(t0);
8754}
8755GEN_SPEOP_ARITH2(evsrwu, gen_op_evsrwu);
8756static inline void gen_op_evsrws(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
8757{
8758 TCGLabel *l1 = gen_new_label();
8759 TCGLabel *l2 = gen_new_label();
8760 TCGv_i32 t0 = tcg_temp_local_new_i32();
8761
8762
8763 tcg_gen_andi_i32(t0, arg2, 0x3F);
8764 tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1);
8765 tcg_gen_sar_i32(ret, arg1, t0);
8766 tcg_gen_br(l2);
8767 gen_set_label(l1);
8768 tcg_gen_movi_i32(ret, 0);
8769 gen_set_label(l2);
8770 tcg_temp_free_i32(t0);
8771}
8772GEN_SPEOP_ARITH2(evsrws, gen_op_evsrws);
8773static inline void gen_op_evslw(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
8774{
8775 TCGLabel *l1 = gen_new_label();
8776 TCGLabel *l2 = gen_new_label();
8777 TCGv_i32 t0 = tcg_temp_local_new_i32();
8778
8779
8780 tcg_gen_andi_i32(t0, arg2, 0x3F);
8781 tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1);
8782 tcg_gen_shl_i32(ret, arg1, t0);
8783 tcg_gen_br(l2);
8784 gen_set_label(l1);
8785 tcg_gen_movi_i32(ret, 0);
8786 gen_set_label(l2);
8787 tcg_temp_free_i32(t0);
8788}
8789GEN_SPEOP_ARITH2(evslw, gen_op_evslw);
8790static inline void gen_op_evrlw(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
8791{
8792 TCGv_i32 t0 = tcg_temp_new_i32();
8793 tcg_gen_andi_i32(t0, arg2, 0x1F);
8794 tcg_gen_rotl_i32(ret, arg1, t0);
8795 tcg_temp_free_i32(t0);
8796}
8797GEN_SPEOP_ARITH2(evrlw, gen_op_evrlw);
8798static inline void gen_evmergehi(DisasContext *ctx)
8799{
8800 if (unlikely(!ctx->spe_enabled)) {
8801 gen_exception(ctx, POWERPC_EXCP_SPEU);
8802 return;
8803 }
8804 tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
8805 tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
8806}
8807GEN_SPEOP_ARITH2(evaddw, tcg_gen_add_i32);
8808static inline void gen_op_evsubf(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
8809{
8810 tcg_gen_sub_i32(ret, arg2, arg1);
8811}
8812GEN_SPEOP_ARITH2(evsubfw, gen_op_evsubf);
8813
8814
8815#define GEN_SPEOP_ARITH_IMM2(name, tcg_op) \
8816static inline void gen_##name(DisasContext *ctx) \
8817{ \
8818 TCGv_i32 t0; \
8819 if (unlikely(!ctx->spe_enabled)) { \
8820 gen_exception(ctx, POWERPC_EXCP_SPEU); \
8821 return; \
8822 } \
8823 t0 = tcg_temp_new_i32(); \
8824 \
8825 tcg_gen_trunc_tl_i32(t0, cpu_gpr[rB(ctx->opcode)]); \
8826 tcg_op(t0, t0, rA(ctx->opcode)); \
8827 tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0); \
8828 \
8829 tcg_gen_trunc_tl_i32(t0, cpu_gprh[rB(ctx->opcode)]); \
8830 tcg_op(t0, t0, rA(ctx->opcode)); \
8831 tcg_gen_extu_i32_tl(cpu_gprh[rD(ctx->opcode)], t0); \
8832 \
8833 tcg_temp_free_i32(t0); \
8834}
8835GEN_SPEOP_ARITH_IMM2(evaddiw, tcg_gen_addi_i32);
8836GEN_SPEOP_ARITH_IMM2(evsubifw, tcg_gen_subi_i32);
8837
8838
8839#define GEN_SPEOP_COMP(name, tcg_cond) \
8840static inline void gen_##name(DisasContext *ctx) \
8841{ \
8842 if (unlikely(!ctx->spe_enabled)) { \
8843 gen_exception(ctx, POWERPC_EXCP_SPEU); \
8844 return; \
8845 } \
8846 TCGLabel *l1 = gen_new_label(); \
8847 TCGLabel *l2 = gen_new_label(); \
8848 TCGLabel *l3 = gen_new_label(); \
8849 TCGLabel *l4 = gen_new_label(); \
8850 \
8851 tcg_gen_ext32s_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); \
8852 tcg_gen_ext32s_tl(cpu_gpr[rB(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); \
8853 tcg_gen_ext32s_tl(cpu_gprh[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]); \
8854 tcg_gen_ext32s_tl(cpu_gprh[rB(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]); \
8855 \
8856 tcg_gen_brcond_tl(tcg_cond, cpu_gpr[rA(ctx->opcode)], \
8857 cpu_gpr[rB(ctx->opcode)], l1); \
8858 tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)], 0); \
8859 tcg_gen_br(l2); \
8860 gen_set_label(l1); \
8861 tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)], \
8862 CRF_CL | CRF_CH_OR_CL | CRF_CH_AND_CL); \
8863 gen_set_label(l2); \
8864 tcg_gen_brcond_tl(tcg_cond, cpu_gprh[rA(ctx->opcode)], \
8865 cpu_gprh[rB(ctx->opcode)], l3); \
8866 tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], \
8867 ~(CRF_CH | CRF_CH_AND_CL)); \
8868 tcg_gen_br(l4); \
8869 gen_set_label(l3); \
8870 tcg_gen_ori_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], \
8871 CRF_CH | CRF_CH_OR_CL); \
8872 gen_set_label(l4); \
8873}
8874GEN_SPEOP_COMP(evcmpgtu, TCG_COND_GTU);
8875GEN_SPEOP_COMP(evcmpgts, TCG_COND_GT);
8876GEN_SPEOP_COMP(evcmpltu, TCG_COND_LTU);
8877GEN_SPEOP_COMP(evcmplts, TCG_COND_LT);
8878GEN_SPEOP_COMP(evcmpeq, TCG_COND_EQ);
8879
8880
8881static inline void gen_brinc(DisasContext *ctx)
8882{
8883
8884 gen_helper_brinc(cpu_gpr[rD(ctx->opcode)],
8885 cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
8886}
8887static inline void gen_evmergelo(DisasContext *ctx)
8888{
8889 if (unlikely(!ctx->spe_enabled)) {
8890 gen_exception(ctx, POWERPC_EXCP_SPEU);
8891 return;
8892 }
8893 tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
8894 tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
8895}
8896static inline void gen_evmergehilo(DisasContext *ctx)
8897{
8898 if (unlikely(!ctx->spe_enabled)) {
8899 gen_exception(ctx, POWERPC_EXCP_SPEU);
8900 return;
8901 }
8902 tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
8903 tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
8904}
8905static inline void gen_evmergelohi(DisasContext *ctx)
8906{
8907 if (unlikely(!ctx->spe_enabled)) {
8908 gen_exception(ctx, POWERPC_EXCP_SPEU);
8909 return;
8910 }
8911 if (rD(ctx->opcode) == rA(ctx->opcode)) {
8912 TCGv tmp = tcg_temp_new();
8913 tcg_gen_mov_tl(tmp, cpu_gpr[rA(ctx->opcode)]);
8914 tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
8915 tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], tmp);
8916 tcg_temp_free(tmp);
8917 } else {
8918 tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
8919 tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
8920 }
8921}
8922static inline void gen_evsplati(DisasContext *ctx)
8923{
8924 uint64_t imm = ((int32_t)(rA(ctx->opcode) << 27)) >> 27;
8925
8926 tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], imm);
8927 tcg_gen_movi_tl(cpu_gprh[rD(ctx->opcode)], imm);
8928}
8929static inline void gen_evsplatfi(DisasContext *ctx)
8930{
8931 uint64_t imm = rA(ctx->opcode) << 27;
8932
8933 tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], imm);
8934 tcg_gen_movi_tl(cpu_gprh[rD(ctx->opcode)], imm);
8935}
8936
8937static inline void gen_evsel(DisasContext *ctx)
8938{
8939 TCGLabel *l1 = gen_new_label();
8940 TCGLabel *l2 = gen_new_label();
8941 TCGLabel *l3 = gen_new_label();
8942 TCGLabel *l4 = gen_new_label();
8943 TCGv_i32 t0 = tcg_temp_local_new_i32();
8944
8945 tcg_gen_andi_i32(t0, cpu_crf[ctx->opcode & 0x07], 1 << 3);
8946 tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
8947 tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
8948 tcg_gen_br(l2);
8949 gen_set_label(l1);
8950 tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
8951 gen_set_label(l2);
8952 tcg_gen_andi_i32(t0, cpu_crf[ctx->opcode & 0x07], 1 << 2);
8953 tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l3);
8954 tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
8955 tcg_gen_br(l4);
8956 gen_set_label(l3);
8957 tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
8958 gen_set_label(l4);
8959 tcg_temp_free_i32(t0);
8960}
8961
8962static void gen_evsel0(DisasContext *ctx)
8963{
8964 gen_evsel(ctx);
8965}
8966
8967static void gen_evsel1(DisasContext *ctx)
8968{
8969 gen_evsel(ctx);
8970}
8971
8972static void gen_evsel2(DisasContext *ctx)
8973{
8974 gen_evsel(ctx);
8975}
8976
8977static void gen_evsel3(DisasContext *ctx)
8978{
8979 gen_evsel(ctx);
8980}
8981
8982
8983
8984static inline void gen_evmwumi(DisasContext *ctx)
8985{
8986 TCGv_i64 t0, t1;
8987
8988 if (unlikely(!ctx->spe_enabled)) {
8989 gen_exception(ctx, POWERPC_EXCP_SPEU);
8990 return;
8991 }
8992
8993 t0 = tcg_temp_new_i64();
8994 t1 = tcg_temp_new_i64();
8995
8996
8997 tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
8998 tcg_gen_ext32u_i64(t0, t0);
8999 tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
9000 tcg_gen_ext32u_i64(t1, t1);
9001
9002 tcg_gen_mul_i64(t0, t0, t1);
9003
9004 gen_store_gpr64(rD(ctx->opcode), t0);
9005
9006 tcg_temp_free_i64(t0);
9007 tcg_temp_free_i64(t1);
9008}
9009
9010static inline void gen_evmwumia(DisasContext *ctx)
9011{
9012 TCGv_i64 tmp;
9013
9014 if (unlikely(!ctx->spe_enabled)) {
9015 gen_exception(ctx, POWERPC_EXCP_SPEU);
9016 return;
9017 }
9018
9019 gen_evmwumi(ctx);
9020
9021 tmp = tcg_temp_new_i64();
9022
9023
9024 gen_load_gpr64(tmp, rD(ctx->opcode));
9025 tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUPPCState, spe_acc));
9026 tcg_temp_free_i64(tmp);
9027}
9028
9029static inline void gen_evmwumiaa(DisasContext *ctx)
9030{
9031 TCGv_i64 acc;
9032 TCGv_i64 tmp;
9033
9034 if (unlikely(!ctx->spe_enabled)) {
9035 gen_exception(ctx, POWERPC_EXCP_SPEU);
9036 return;
9037 }
9038
9039 gen_evmwumi(ctx);
9040
9041 acc = tcg_temp_new_i64();
9042 tmp = tcg_temp_new_i64();
9043
9044
9045 gen_load_gpr64(tmp, rD(ctx->opcode));
9046
9047
9048 tcg_gen_ld_i64(acc, cpu_env, offsetof(CPUPPCState, spe_acc));
9049
9050
9051 tcg_gen_add_i64(acc, acc, tmp);
9052
9053
9054 tcg_gen_st_i64(acc, cpu_env, offsetof(CPUPPCState, spe_acc));
9055
9056
9057 gen_store_gpr64(rD(ctx->opcode), acc);
9058
9059 tcg_temp_free_i64(acc);
9060 tcg_temp_free_i64(tmp);
9061}
9062
9063static inline void gen_evmwsmi(DisasContext *ctx)
9064{
9065 TCGv_i64 t0, t1;
9066
9067 if (unlikely(!ctx->spe_enabled)) {
9068 gen_exception(ctx, POWERPC_EXCP_SPEU);
9069 return;
9070 }
9071
9072 t0 = tcg_temp_new_i64();
9073 t1 = tcg_temp_new_i64();
9074
9075
9076 tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
9077 tcg_gen_ext32s_i64(t0, t0);
9078 tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
9079 tcg_gen_ext32s_i64(t1, t1);
9080
9081 tcg_gen_mul_i64(t0, t0, t1);
9082
9083 gen_store_gpr64(rD(ctx->opcode), t0);
9084
9085 tcg_temp_free_i64(t0);
9086 tcg_temp_free_i64(t1);
9087}
9088
9089static inline void gen_evmwsmia(DisasContext *ctx)
9090{
9091 TCGv_i64 tmp;
9092
9093 gen_evmwsmi(ctx);
9094
9095 tmp = tcg_temp_new_i64();
9096
9097
9098 gen_load_gpr64(tmp, rD(ctx->opcode));
9099 tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUPPCState, spe_acc));
9100
9101 tcg_temp_free_i64(tmp);
9102}
9103
9104static inline void gen_evmwsmiaa(DisasContext *ctx)
9105{
9106 TCGv_i64 acc = tcg_temp_new_i64();
9107 TCGv_i64 tmp = tcg_temp_new_i64();
9108
9109 gen_evmwsmi(ctx);
9110
9111 acc = tcg_temp_new_i64();
9112 tmp = tcg_temp_new_i64();
9113
9114
9115 gen_load_gpr64(tmp, rD(ctx->opcode));
9116
9117
9118 tcg_gen_ld_i64(acc, cpu_env, offsetof(CPUPPCState, spe_acc));
9119
9120
9121 tcg_gen_add_i64(acc, acc, tmp);
9122
9123
9124 tcg_gen_st_i64(acc, cpu_env, offsetof(CPUPPCState, spe_acc));
9125
9126
9127 gen_store_gpr64(rD(ctx->opcode), acc);
9128
9129 tcg_temp_free_i64(acc);
9130 tcg_temp_free_i64(tmp);
9131}
9132
9133GEN_SPE(evaddw, speundef, 0x00, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE);
9134GEN_SPE(evaddiw, speundef, 0x01, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE);
9135GEN_SPE(evsubfw, speundef, 0x02, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE);
9136GEN_SPE(evsubifw, speundef, 0x03, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE);
9137GEN_SPE(evabs, evneg, 0x04, 0x08, 0x0000F800, 0x0000F800, PPC_SPE);
9138GEN_SPE(evextsb, evextsh, 0x05, 0x08, 0x0000F800, 0x0000F800, PPC_SPE);
9139GEN_SPE(evrndw, evcntlzw, 0x06, 0x08, 0x0000F800, 0x0000F800, PPC_SPE);
9140GEN_SPE(evcntlsw, brinc, 0x07, 0x08, 0x0000F800, 0x00000000, PPC_SPE);
9141GEN_SPE(evmra, speundef, 0x02, 0x13, 0x0000F800, 0xFFFFFFFF, PPC_SPE);
9142GEN_SPE(speundef, evand, 0x08, 0x08, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9143GEN_SPE(evandc, speundef, 0x09, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE);
9144GEN_SPE(evxor, evor, 0x0B, 0x08, 0x00000000, 0x00000000, PPC_SPE);
9145GEN_SPE(evnor, eveqv, 0x0C, 0x08, 0x00000000, 0x00000000, PPC_SPE);
9146GEN_SPE(evmwumi, evmwsmi, 0x0C, 0x11, 0x00000000, 0x00000000, PPC_SPE);
9147GEN_SPE(evmwumia, evmwsmia, 0x1C, 0x11, 0x00000000, 0x00000000, PPC_SPE);
9148GEN_SPE(evmwumiaa, evmwsmiaa, 0x0C, 0x15, 0x00000000, 0x00000000, PPC_SPE);
9149GEN_SPE(speundef, evorc, 0x0D, 0x08, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9150GEN_SPE(evnand, speundef, 0x0F, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE);
9151GEN_SPE(evsrwu, evsrws, 0x10, 0x08, 0x00000000, 0x00000000, PPC_SPE);
9152GEN_SPE(evsrwiu, evsrwis, 0x11, 0x08, 0x00000000, 0x00000000, PPC_SPE);
9153GEN_SPE(evslw, speundef, 0x12, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE);
9154GEN_SPE(evslwi, speundef, 0x13, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE);
9155GEN_SPE(evrlw, evsplati, 0x14, 0x08, 0x00000000, 0x0000F800, PPC_SPE);
9156GEN_SPE(evrlwi, evsplatfi, 0x15, 0x08, 0x00000000, 0x0000F800, PPC_SPE);
9157GEN_SPE(evmergehi, evmergelo, 0x16, 0x08, 0x00000000, 0x00000000, PPC_SPE);
9158GEN_SPE(evmergehilo, evmergelohi, 0x17, 0x08, 0x00000000, 0x00000000, PPC_SPE);
9159GEN_SPE(evcmpgtu, evcmpgts, 0x18, 0x08, 0x00600000, 0x00600000, PPC_SPE);
9160GEN_SPE(evcmpltu, evcmplts, 0x19, 0x08, 0x00600000, 0x00600000, PPC_SPE);
9161GEN_SPE(evcmpeq, speundef, 0x1A, 0x08, 0x00600000, 0xFFFFFFFF, PPC_SPE);
9162
9163
9164static inline void gen_addr_spe_imm_index(DisasContext *ctx, TCGv EA, int sh)
9165{
9166 target_ulong uimm = rB(ctx->opcode);
9167
9168 if (rA(ctx->opcode) == 0) {
9169 tcg_gen_movi_tl(EA, uimm << sh);
9170 } else {
9171 tcg_gen_addi_tl(EA, cpu_gpr[rA(ctx->opcode)], uimm << sh);
9172 if (NARROW_MODE(ctx)) {
9173 tcg_gen_ext32u_tl(EA, EA);
9174 }
9175 }
9176}
9177
9178static inline void gen_op_evldd(DisasContext *ctx, TCGv addr)
9179{
9180 TCGv_i64 t0 = tcg_temp_new_i64();
9181 gen_qemu_ld64(ctx, t0, addr);
9182 gen_store_gpr64(rD(ctx->opcode), t0);
9183 tcg_temp_free_i64(t0);
9184}
9185
9186static inline void gen_op_evldw(DisasContext *ctx, TCGv addr)
9187{
9188 gen_qemu_ld32u(ctx, cpu_gprh[rD(ctx->opcode)], addr);
9189 gen_addr_add(ctx, addr, addr, 4);
9190 gen_qemu_ld32u(ctx, cpu_gpr[rD(ctx->opcode)], addr);
9191}
9192
9193static inline void gen_op_evldh(DisasContext *ctx, TCGv addr)
9194{
9195 TCGv t0 = tcg_temp_new();
9196 gen_qemu_ld16u(ctx, t0, addr);
9197 tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
9198 gen_addr_add(ctx, addr, addr, 2);
9199 gen_qemu_ld16u(ctx, t0, addr);
9200 tcg_gen_or_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0);
9201 gen_addr_add(ctx, addr, addr, 2);
9202 gen_qemu_ld16u(ctx, t0, addr);
9203 tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
9204 gen_addr_add(ctx, addr, addr, 2);
9205 gen_qemu_ld16u(ctx, t0, addr);
9206 tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
9207 tcg_temp_free(t0);
9208}
9209
9210static inline void gen_op_evlhhesplat(DisasContext *ctx, TCGv addr)
9211{
9212 TCGv t0 = tcg_temp_new();
9213 gen_qemu_ld16u(ctx, t0, addr);
9214 tcg_gen_shli_tl(t0, t0, 16);
9215 tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
9216 tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
9217 tcg_temp_free(t0);
9218}
9219
9220static inline void gen_op_evlhhousplat(DisasContext *ctx, TCGv addr)
9221{
9222 TCGv t0 = tcg_temp_new();
9223 gen_qemu_ld16u(ctx, t0, addr);
9224 tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
9225 tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
9226 tcg_temp_free(t0);
9227}
9228
9229static inline void gen_op_evlhhossplat(DisasContext *ctx, TCGv addr)
9230{
9231 TCGv t0 = tcg_temp_new();
9232 gen_qemu_ld16s(ctx, t0, addr);
9233 tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
9234 tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
9235 tcg_temp_free(t0);
9236}
9237
9238static inline void gen_op_evlwhe(DisasContext *ctx, TCGv addr)
9239{
9240 TCGv t0 = tcg_temp_new();
9241 gen_qemu_ld16u(ctx, t0, addr);
9242 tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
9243 gen_addr_add(ctx, addr, addr, 2);
9244 gen_qemu_ld16u(ctx, t0, addr);
9245 tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 16);
9246 tcg_temp_free(t0);
9247}
9248
9249static inline void gen_op_evlwhou(DisasContext *ctx, TCGv addr)
9250{
9251 gen_qemu_ld16u(ctx, cpu_gprh[rD(ctx->opcode)], addr);
9252 gen_addr_add(ctx, addr, addr, 2);
9253 gen_qemu_ld16u(ctx, cpu_gpr[rD(ctx->opcode)], addr);
9254}
9255
9256static inline void gen_op_evlwhos(DisasContext *ctx, TCGv addr)
9257{
9258 gen_qemu_ld16s(ctx, cpu_gprh[rD(ctx->opcode)], addr);
9259 gen_addr_add(ctx, addr, addr, 2);
9260 gen_qemu_ld16s(ctx, cpu_gpr[rD(ctx->opcode)], addr);
9261}
9262
9263static inline void gen_op_evlwwsplat(DisasContext *ctx, TCGv addr)
9264{
9265 TCGv t0 = tcg_temp_new();
9266 gen_qemu_ld32u(ctx, t0, addr);
9267 tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
9268 tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
9269 tcg_temp_free(t0);
9270}
9271
9272static inline void gen_op_evlwhsplat(DisasContext *ctx, TCGv addr)
9273{
9274 TCGv t0 = tcg_temp_new();
9275 gen_qemu_ld16u(ctx, t0, addr);
9276 tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
9277 tcg_gen_or_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0);
9278 gen_addr_add(ctx, addr, addr, 2);
9279 gen_qemu_ld16u(ctx, t0, addr);
9280 tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 16);
9281 tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0);
9282 tcg_temp_free(t0);
9283}
9284
9285static inline void gen_op_evstdd(DisasContext *ctx, TCGv addr)
9286{
9287 TCGv_i64 t0 = tcg_temp_new_i64();
9288 gen_load_gpr64(t0, rS(ctx->opcode));
9289 gen_qemu_st64(ctx, t0, addr);
9290 tcg_temp_free_i64(t0);
9291}
9292
9293static inline void gen_op_evstdw(DisasContext *ctx, TCGv addr)
9294{
9295 gen_qemu_st32(ctx, cpu_gprh[rS(ctx->opcode)], addr);
9296 gen_addr_add(ctx, addr, addr, 4);
9297 gen_qemu_st32(ctx, cpu_gpr[rS(ctx->opcode)], addr);
9298}
9299
9300static inline void gen_op_evstdh(DisasContext *ctx, TCGv addr)
9301{
9302 TCGv t0 = tcg_temp_new();
9303 tcg_gen_shri_tl(t0, cpu_gprh[rS(ctx->opcode)], 16);
9304 gen_qemu_st16(ctx, t0, addr);
9305 gen_addr_add(ctx, addr, addr, 2);
9306 gen_qemu_st16(ctx, cpu_gprh[rS(ctx->opcode)], addr);
9307 gen_addr_add(ctx, addr, addr, 2);
9308 tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 16);
9309 gen_qemu_st16(ctx, t0, addr);
9310 tcg_temp_free(t0);
9311 gen_addr_add(ctx, addr, addr, 2);
9312 gen_qemu_st16(ctx, cpu_gpr[rS(ctx->opcode)], addr);
9313}
9314
9315static inline void gen_op_evstwhe(DisasContext *ctx, TCGv addr)
9316{
9317 TCGv t0 = tcg_temp_new();
9318 tcg_gen_shri_tl(t0, cpu_gprh[rS(ctx->opcode)], 16);
9319 gen_qemu_st16(ctx, t0, addr);
9320 gen_addr_add(ctx, addr, addr, 2);
9321 tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 16);
9322 gen_qemu_st16(ctx, t0, addr);
9323 tcg_temp_free(t0);
9324}
9325
9326static inline void gen_op_evstwho(DisasContext *ctx, TCGv addr)
9327{
9328 gen_qemu_st16(ctx, cpu_gprh[rS(ctx->opcode)], addr);
9329 gen_addr_add(ctx, addr, addr, 2);
9330 gen_qemu_st16(ctx, cpu_gpr[rS(ctx->opcode)], addr);
9331}
9332
9333static inline void gen_op_evstwwe(DisasContext *ctx, TCGv addr)
9334{
9335 gen_qemu_st32(ctx, cpu_gprh[rS(ctx->opcode)], addr);
9336}
9337
9338static inline void gen_op_evstwwo(DisasContext *ctx, TCGv addr)
9339{
9340 gen_qemu_st32(ctx, cpu_gpr[rS(ctx->opcode)], addr);
9341}
9342
9343#define GEN_SPEOP_LDST(name, opc2, sh) \
9344static void glue(gen_, name)(DisasContext *ctx) \
9345{ \
9346 TCGv t0; \
9347 if (unlikely(!ctx->spe_enabled)) { \
9348 gen_exception(ctx, POWERPC_EXCP_SPEU); \
9349 return; \
9350 } \
9351 gen_set_access_type(ctx, ACCESS_INT); \
9352 t0 = tcg_temp_new(); \
9353 if (Rc(ctx->opcode)) { \
9354 gen_addr_spe_imm_index(ctx, t0, sh); \
9355 } else { \
9356 gen_addr_reg_index(ctx, t0); \
9357 } \
9358 gen_op_##name(ctx, t0); \
9359 tcg_temp_free(t0); \
9360}
9361
9362GEN_SPEOP_LDST(evldd, 0x00, 3);
9363GEN_SPEOP_LDST(evldw, 0x01, 3);
9364GEN_SPEOP_LDST(evldh, 0x02, 3);
9365GEN_SPEOP_LDST(evlhhesplat, 0x04, 1);
9366GEN_SPEOP_LDST(evlhhousplat, 0x06, 1);
9367GEN_SPEOP_LDST(evlhhossplat, 0x07, 1);
9368GEN_SPEOP_LDST(evlwhe, 0x08, 2);
9369GEN_SPEOP_LDST(evlwhou, 0x0A, 2);
9370GEN_SPEOP_LDST(evlwhos, 0x0B, 2);
9371GEN_SPEOP_LDST(evlwwsplat, 0x0C, 2);
9372GEN_SPEOP_LDST(evlwhsplat, 0x0E, 2);
9373
9374GEN_SPEOP_LDST(evstdd, 0x10, 3);
9375GEN_SPEOP_LDST(evstdw, 0x11, 3);
9376GEN_SPEOP_LDST(evstdh, 0x12, 3);
9377GEN_SPEOP_LDST(evstwhe, 0x18, 2);
9378GEN_SPEOP_LDST(evstwho, 0x1A, 2);
9379GEN_SPEOP_LDST(evstwwe, 0x1C, 2);
9380GEN_SPEOP_LDST(evstwwo, 0x1E, 2);
9381
9382
9383#if 0
9384GEN_SPE(speundef, evmhessf, 0x01, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9385GEN_SPE(speundef, evmhossf, 0x03, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9386GEN_SPE(evmheumi, evmhesmi, 0x04, 0x10, 0x00000000, 0x00000000, PPC_SPE);
9387GEN_SPE(speundef, evmhesmf, 0x05, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9388GEN_SPE(evmhoumi, evmhosmi, 0x06, 0x10, 0x00000000, 0x00000000, PPC_SPE);
9389GEN_SPE(speundef, evmhosmf, 0x07, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9390GEN_SPE(speundef, evmhessfa, 0x11, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9391GEN_SPE(speundef, evmhossfa, 0x13, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9392GEN_SPE(evmheumia, evmhesmia, 0x14, 0x10, 0x00000000, 0x00000000, PPC_SPE);
9393GEN_SPE(speundef, evmhesmfa, 0x15, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9394GEN_SPE(evmhoumia, evmhosmia, 0x16, 0x10, 0x00000000, 0x00000000, PPC_SPE);
9395GEN_SPE(speundef, evmhosmfa, 0x17, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9396
9397GEN_SPE(speundef, evmwhssf, 0x03, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9398GEN_SPE(evmwlumi, speundef, 0x04, 0x11, 0x00000000, 0xFFFFFFFF, PPC_SPE);
9399GEN_SPE(evmwhumi, evmwhsmi, 0x06, 0x11, 0x00000000, 0x00000000, PPC_SPE);
9400GEN_SPE(speundef, evmwhsmf, 0x07, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9401GEN_SPE(speundef, evmwssf, 0x09, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9402GEN_SPE(speundef, evmwsmf, 0x0D, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9403GEN_SPE(speundef, evmwhssfa, 0x13, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9404GEN_SPE(evmwlumia, speundef, 0x14, 0x11, 0x00000000, 0xFFFFFFFF, PPC_SPE);
9405GEN_SPE(evmwhumia, evmwhsmia, 0x16, 0x11, 0x00000000, 0x00000000, PPC_SPE);
9406GEN_SPE(speundef, evmwhsmfa, 0x17, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9407GEN_SPE(speundef, evmwssfa, 0x19, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9408GEN_SPE(speundef, evmwsmfa, 0x1D, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9409
9410GEN_SPE(evadduiaaw, evaddsiaaw, 0x00, 0x13, 0x0000F800, 0x0000F800, PPC_SPE);
9411GEN_SPE(evsubfusiaaw, evsubfssiaaw, 0x01, 0x13, 0x0000F800, 0x0000F800, PPC_SPE);
9412GEN_SPE(evaddumiaaw, evaddsmiaaw, 0x04, 0x13, 0x0000F800, 0x0000F800, PPC_SPE);
9413GEN_SPE(evsubfumiaaw, evsubfsmiaaw, 0x05, 0x13, 0x0000F800, 0x0000F800, PPC_SPE);
9414GEN_SPE(evdivws, evdivwu, 0x06, 0x13, 0x00000000, 0x00000000, PPC_SPE);
9415
9416GEN_SPE(evmheusiaaw, evmhessiaaw, 0x00, 0x14, 0x00000000, 0x00000000, PPC_SPE);
9417GEN_SPE(speundef, evmhessfaaw, 0x01, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9418GEN_SPE(evmhousiaaw, evmhossiaaw, 0x02, 0x14, 0x00000000, 0x00000000, PPC_SPE);
9419GEN_SPE(speundef, evmhossfaaw, 0x03, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9420GEN_SPE(evmheumiaaw, evmhesmiaaw, 0x04, 0x14, 0x00000000, 0x00000000, PPC_SPE);
9421GEN_SPE(speundef, evmhesmfaaw, 0x05, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9422GEN_SPE(evmhoumiaaw, evmhosmiaaw, 0x06, 0x14, 0x00000000, 0x00000000, PPC_SPE);
9423GEN_SPE(speundef, evmhosmfaaw, 0x07, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9424GEN_SPE(evmhegumiaa, evmhegsmiaa, 0x14, 0x14, 0x00000000, 0x00000000, PPC_SPE);
9425GEN_SPE(speundef, evmhegsmfaa, 0x15, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9426GEN_SPE(evmhogumiaa, evmhogsmiaa, 0x16, 0x14, 0x00000000, 0x00000000, PPC_SPE);
9427GEN_SPE(speundef, evmhogsmfaa, 0x17, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9428
9429GEN_SPE(evmwlusiaaw, evmwlssiaaw, 0x00, 0x15, 0x00000000, 0x00000000, PPC_SPE);
9430GEN_SPE(evmwlumiaaw, evmwlsmiaaw, 0x04, 0x15, 0x00000000, 0x00000000, PPC_SPE);
9431GEN_SPE(speundef, evmwssfaa, 0x09, 0x15, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9432GEN_SPE(speundef, evmwsmfaa, 0x0D, 0x15, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9433
9434GEN_SPE(evmheusianw, evmhessianw, 0x00, 0x16, 0x00000000, 0x00000000, PPC_SPE);
9435GEN_SPE(speundef, evmhessfanw, 0x01, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9436GEN_SPE(evmhousianw, evmhossianw, 0x02, 0x16, 0x00000000, 0x00000000, PPC_SPE);
9437GEN_SPE(speundef, evmhossfanw, 0x03, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9438GEN_SPE(evmheumianw, evmhesmianw, 0x04, 0x16, 0x00000000, 0x00000000, PPC_SPE);
9439GEN_SPE(speundef, evmhesmfanw, 0x05, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9440GEN_SPE(evmhoumianw, evmhosmianw, 0x06, 0x16, 0x00000000, 0x00000000, PPC_SPE);
9441GEN_SPE(speundef, evmhosmfanw, 0x07, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9442GEN_SPE(evmhegumian, evmhegsmian, 0x14, 0x16, 0x00000000, 0x00000000, PPC_SPE);
9443GEN_SPE(speundef, evmhegsmfan, 0x15, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9444GEN_SPE(evmhigumian, evmhigsmian, 0x16, 0x16, 0x00000000, 0x00000000, PPC_SPE);
9445GEN_SPE(speundef, evmhogsmfan, 0x17, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9446
9447GEN_SPE(evmwlusianw, evmwlssianw, 0x00, 0x17, 0x00000000, 0x00000000, PPC_SPE);
9448GEN_SPE(evmwlumianw, evmwlsmianw, 0x04, 0x17, 0x00000000, 0x00000000, PPC_SPE);
9449GEN_SPE(speundef, evmwssfan, 0x09, 0x17, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9450GEN_SPE(evmwumian, evmwsmian, 0x0C, 0x17, 0x00000000, 0x00000000, PPC_SPE);
9451GEN_SPE(speundef, evmwsmfan, 0x0D, 0x17, 0xFFFFFFFF, 0x00000000, PPC_SPE);
9452#endif
9453
9454
9455#define GEN_SPEFPUOP_CONV_32_32(name) \
9456static inline void gen_##name(DisasContext *ctx) \
9457{ \
9458 TCGv_i32 t0 = tcg_temp_new_i32(); \
9459 tcg_gen_trunc_tl_i32(t0, cpu_gpr[rB(ctx->opcode)]); \
9460 gen_helper_##name(t0, cpu_env, t0); \
9461 tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0); \
9462 tcg_temp_free_i32(t0); \
9463}
9464#define GEN_SPEFPUOP_CONV_32_64(name) \
9465static inline void gen_##name(DisasContext *ctx) \
9466{ \
9467 TCGv_i64 t0 = tcg_temp_new_i64(); \
9468 TCGv_i32 t1 = tcg_temp_new_i32(); \
9469 gen_load_gpr64(t0, rB(ctx->opcode)); \
9470 gen_helper_##name(t1, cpu_env, t0); \
9471 tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t1); \
9472 tcg_temp_free_i64(t0); \
9473 tcg_temp_free_i32(t1); \
9474}
9475#define GEN_SPEFPUOP_CONV_64_32(name) \
9476static inline void gen_##name(DisasContext *ctx) \
9477{ \
9478 TCGv_i64 t0 = tcg_temp_new_i64(); \
9479 TCGv_i32 t1 = tcg_temp_new_i32(); \
9480 tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]); \
9481 gen_helper_##name(t0, cpu_env, t1); \
9482 gen_store_gpr64(rD(ctx->opcode), t0); \
9483 tcg_temp_free_i64(t0); \
9484 tcg_temp_free_i32(t1); \
9485}
9486#define GEN_SPEFPUOP_CONV_64_64(name) \
9487static inline void gen_##name(DisasContext *ctx) \
9488{ \
9489 TCGv_i64 t0 = tcg_temp_new_i64(); \
9490 gen_load_gpr64(t0, rB(ctx->opcode)); \
9491 gen_helper_##name(t0, cpu_env, t0); \
9492 gen_store_gpr64(rD(ctx->opcode), t0); \
9493 tcg_temp_free_i64(t0); \
9494}
9495#define GEN_SPEFPUOP_ARITH2_32_32(name) \
9496static inline void gen_##name(DisasContext *ctx) \
9497{ \
9498 TCGv_i32 t0, t1; \
9499 if (unlikely(!ctx->spe_enabled)) { \
9500 gen_exception(ctx, POWERPC_EXCP_SPEU); \
9501 return; \
9502 } \
9503 t0 = tcg_temp_new_i32(); \
9504 t1 = tcg_temp_new_i32(); \
9505 tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]); \
9506 tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]); \
9507 gen_helper_##name(t0, cpu_env, t0, t1); \
9508 tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0); \
9509 \
9510 tcg_temp_free_i32(t0); \
9511 tcg_temp_free_i32(t1); \
9512}
9513#define GEN_SPEFPUOP_ARITH2_64_64(name) \
9514static inline void gen_##name(DisasContext *ctx) \
9515{ \
9516 TCGv_i64 t0, t1; \
9517 if (unlikely(!ctx->spe_enabled)) { \
9518 gen_exception(ctx, POWERPC_EXCP_SPEU); \
9519 return; \
9520 } \
9521 t0 = tcg_temp_new_i64(); \
9522 t1 = tcg_temp_new_i64(); \
9523 gen_load_gpr64(t0, rA(ctx->opcode)); \
9524 gen_load_gpr64(t1, rB(ctx->opcode)); \
9525 gen_helper_##name(t0, cpu_env, t0, t1); \
9526 gen_store_gpr64(rD(ctx->opcode), t0); \
9527 tcg_temp_free_i64(t0); \
9528 tcg_temp_free_i64(t1); \
9529}
9530#define GEN_SPEFPUOP_COMP_32(name) \
9531static inline void gen_##name(DisasContext *ctx) \
9532{ \
9533 TCGv_i32 t0, t1; \
9534 if (unlikely(!ctx->spe_enabled)) { \
9535 gen_exception(ctx, POWERPC_EXCP_SPEU); \
9536 return; \
9537 } \
9538 t0 = tcg_temp_new_i32(); \
9539 t1 = tcg_temp_new_i32(); \
9540 \
9541 tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]); \
9542 tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]); \
9543 gen_helper_##name(cpu_crf[crfD(ctx->opcode)], cpu_env, t0, t1); \
9544 \
9545 tcg_temp_free_i32(t0); \
9546 tcg_temp_free_i32(t1); \
9547}
9548#define GEN_SPEFPUOP_COMP_64(name) \
9549static inline void gen_##name(DisasContext *ctx) \
9550{ \
9551 TCGv_i64 t0, t1; \
9552 if (unlikely(!ctx->spe_enabled)) { \
9553 gen_exception(ctx, POWERPC_EXCP_SPEU); \
9554 return; \
9555 } \
9556 t0 = tcg_temp_new_i64(); \
9557 t1 = tcg_temp_new_i64(); \
9558 gen_load_gpr64(t0, rA(ctx->opcode)); \
9559 gen_load_gpr64(t1, rB(ctx->opcode)); \
9560 gen_helper_##name(cpu_crf[crfD(ctx->opcode)], cpu_env, t0, t1); \
9561 tcg_temp_free_i64(t0); \
9562 tcg_temp_free_i64(t1); \
9563}
9564
9565
9566
9567GEN_SPEFPUOP_ARITH2_64_64(evfsadd);
9568GEN_SPEFPUOP_ARITH2_64_64(evfssub);
9569GEN_SPEFPUOP_ARITH2_64_64(evfsmul);
9570GEN_SPEFPUOP_ARITH2_64_64(evfsdiv);
9571static inline void gen_evfsabs(DisasContext *ctx)
9572{
9573 if (unlikely(!ctx->spe_enabled)) {
9574 gen_exception(ctx, POWERPC_EXCP_SPEU);
9575 return;
9576 }
9577 tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
9578 ~0x80000000);
9579 tcg_gen_andi_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],
9580 ~0x80000000);
9581}
9582static inline void gen_evfsnabs(DisasContext *ctx)
9583{
9584 if (unlikely(!ctx->spe_enabled)) {
9585 gen_exception(ctx, POWERPC_EXCP_SPEU);
9586 return;
9587 }
9588 tcg_gen_ori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
9589 0x80000000);
9590 tcg_gen_ori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],
9591 0x80000000);
9592}
9593static inline void gen_evfsneg(DisasContext *ctx)
9594{
9595 if (unlikely(!ctx->spe_enabled)) {
9596 gen_exception(ctx, POWERPC_EXCP_SPEU);
9597 return;
9598 }
9599 tcg_gen_xori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
9600 0x80000000);
9601 tcg_gen_xori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],
9602 0x80000000);
9603}
9604
9605
9606GEN_SPEFPUOP_CONV_64_64(evfscfui);
9607GEN_SPEFPUOP_CONV_64_64(evfscfsi);
9608GEN_SPEFPUOP_CONV_64_64(evfscfuf);
9609GEN_SPEFPUOP_CONV_64_64(evfscfsf);
9610GEN_SPEFPUOP_CONV_64_64(evfsctui);
9611GEN_SPEFPUOP_CONV_64_64(evfsctsi);
9612GEN_SPEFPUOP_CONV_64_64(evfsctuf);
9613GEN_SPEFPUOP_CONV_64_64(evfsctsf);
9614GEN_SPEFPUOP_CONV_64_64(evfsctuiz);
9615GEN_SPEFPUOP_CONV_64_64(evfsctsiz);
9616
9617
9618GEN_SPEFPUOP_COMP_64(evfscmpgt);
9619GEN_SPEFPUOP_COMP_64(evfscmplt);
9620GEN_SPEFPUOP_COMP_64(evfscmpeq);
9621GEN_SPEFPUOP_COMP_64(evfststgt);
9622GEN_SPEFPUOP_COMP_64(evfststlt);
9623GEN_SPEFPUOP_COMP_64(evfststeq);
9624
9625
9626GEN_SPE(evfsadd, evfssub, 0x00, 0x0A, 0x00000000, 0x00000000, PPC_SPE_SINGLE);
9627GEN_SPE(evfsabs, evfsnabs, 0x02, 0x0A, 0x0000F800, 0x0000F800, PPC_SPE_SINGLE);
9628GEN_SPE(evfsneg, speundef, 0x03, 0x0A, 0x0000F800, 0xFFFFFFFF, PPC_SPE_SINGLE);
9629GEN_SPE(evfsmul, evfsdiv, 0x04, 0x0A, 0x00000000, 0x00000000, PPC_SPE_SINGLE);
9630GEN_SPE(evfscmpgt, evfscmplt, 0x06, 0x0A, 0x00600000, 0x00600000, PPC_SPE_SINGLE);
9631GEN_SPE(evfscmpeq, speundef, 0x07, 0x0A, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE);
9632GEN_SPE(evfscfui, evfscfsi, 0x08, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE);
9633GEN_SPE(evfscfuf, evfscfsf, 0x09, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE);
9634GEN_SPE(evfsctui, evfsctsi, 0x0A, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE);
9635GEN_SPE(evfsctuf, evfsctsf, 0x0B, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE);
9636GEN_SPE(evfsctuiz, speundef, 0x0C, 0x0A, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE);
9637GEN_SPE(evfsctsiz, speundef, 0x0D, 0x0A, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE);
9638GEN_SPE(evfststgt, evfststlt, 0x0E, 0x0A, 0x00600000, 0x00600000, PPC_SPE_SINGLE);
9639GEN_SPE(evfststeq, speundef, 0x0F, 0x0A, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE);
9640
9641
9642
9643GEN_SPEFPUOP_ARITH2_32_32(efsadd);
9644GEN_SPEFPUOP_ARITH2_32_32(efssub);
9645GEN_SPEFPUOP_ARITH2_32_32(efsmul);
9646GEN_SPEFPUOP_ARITH2_32_32(efsdiv);
9647static inline void gen_efsabs(DisasContext *ctx)
9648{
9649 if (unlikely(!ctx->spe_enabled)) {
9650 gen_exception(ctx, POWERPC_EXCP_SPEU);
9651 return;
9652 }
9653 tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], (target_long)~0x80000000LL);
9654}
9655static inline void gen_efsnabs(DisasContext *ctx)
9656{
9657 if (unlikely(!ctx->spe_enabled)) {
9658 gen_exception(ctx, POWERPC_EXCP_SPEU);
9659 return;
9660 }
9661 tcg_gen_ori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
9662}
9663static inline void gen_efsneg(DisasContext *ctx)
9664{
9665 if (unlikely(!ctx->spe_enabled)) {
9666 gen_exception(ctx, POWERPC_EXCP_SPEU);
9667 return;
9668 }
9669 tcg_gen_xori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
9670}
9671
9672
9673GEN_SPEFPUOP_CONV_32_32(efscfui);
9674GEN_SPEFPUOP_CONV_32_32(efscfsi);
9675GEN_SPEFPUOP_CONV_32_32(efscfuf);
9676GEN_SPEFPUOP_CONV_32_32(efscfsf);
9677GEN_SPEFPUOP_CONV_32_32(efsctui);
9678GEN_SPEFPUOP_CONV_32_32(efsctsi);
9679GEN_SPEFPUOP_CONV_32_32(efsctuf);
9680GEN_SPEFPUOP_CONV_32_32(efsctsf);
9681GEN_SPEFPUOP_CONV_32_32(efsctuiz);
9682GEN_SPEFPUOP_CONV_32_32(efsctsiz);
9683GEN_SPEFPUOP_CONV_32_64(efscfd);
9684
9685
9686GEN_SPEFPUOP_COMP_32(efscmpgt);
9687GEN_SPEFPUOP_COMP_32(efscmplt);
9688GEN_SPEFPUOP_COMP_32(efscmpeq);
9689GEN_SPEFPUOP_COMP_32(efststgt);
9690GEN_SPEFPUOP_COMP_32(efststlt);
9691GEN_SPEFPUOP_COMP_32(efststeq);
9692
9693
9694GEN_SPE(efsadd, efssub, 0x00, 0x0B, 0x00000000, 0x00000000, PPC_SPE_SINGLE);
9695GEN_SPE(efsabs, efsnabs, 0x02, 0x0B, 0x0000F800, 0x0000F800, PPC_SPE_SINGLE);
9696GEN_SPE(efsneg, speundef, 0x03, 0x0B, 0x0000F800, 0xFFFFFFFF, PPC_SPE_SINGLE);
9697GEN_SPE(efsmul, efsdiv, 0x04, 0x0B, 0x00000000, 0x00000000, PPC_SPE_SINGLE);
9698GEN_SPE(efscmpgt, efscmplt, 0x06, 0x0B, 0x00600000, 0x00600000, PPC_SPE_SINGLE);
9699GEN_SPE(efscmpeq, efscfd, 0x07, 0x0B, 0x00600000, 0x00180000, PPC_SPE_SINGLE);
9700GEN_SPE(efscfui, efscfsi, 0x08, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE);
9701GEN_SPE(efscfuf, efscfsf, 0x09, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE);
9702GEN_SPE(efsctui, efsctsi, 0x0A, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE);
9703GEN_SPE(efsctuf, efsctsf, 0x0B, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE);
9704GEN_SPE(efsctuiz, speundef, 0x0C, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE);
9705GEN_SPE(efsctsiz, speundef, 0x0D, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE);
9706GEN_SPE(efststgt, efststlt, 0x0E, 0x0B, 0x00600000, 0x00600000, PPC_SPE_SINGLE);
9707GEN_SPE(efststeq, speundef, 0x0F, 0x0B, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE);
9708
9709
9710
9711GEN_SPEFPUOP_ARITH2_64_64(efdadd);
9712GEN_SPEFPUOP_ARITH2_64_64(efdsub);
9713GEN_SPEFPUOP_ARITH2_64_64(efdmul);
9714GEN_SPEFPUOP_ARITH2_64_64(efddiv);
9715static inline void gen_efdabs(DisasContext *ctx)
9716{
9717 if (unlikely(!ctx->spe_enabled)) {
9718 gen_exception(ctx, POWERPC_EXCP_SPEU);
9719 return;
9720 }
9721 tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
9722 tcg_gen_andi_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],
9723 ~0x80000000);
9724}
9725static inline void gen_efdnabs(DisasContext *ctx)
9726{
9727 if (unlikely(!ctx->spe_enabled)) {
9728 gen_exception(ctx, POWERPC_EXCP_SPEU);
9729 return;
9730 }
9731 tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
9732 tcg_gen_ori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],
9733 0x80000000);
9734}
9735static inline void gen_efdneg(DisasContext *ctx)
9736{
9737 if (unlikely(!ctx->spe_enabled)) {
9738 gen_exception(ctx, POWERPC_EXCP_SPEU);
9739 return;
9740 }
9741 tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
9742 tcg_gen_xori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],
9743 0x80000000);
9744}
9745
9746
9747GEN_SPEFPUOP_CONV_64_32(efdcfui);
9748GEN_SPEFPUOP_CONV_64_32(efdcfsi);
9749GEN_SPEFPUOP_CONV_64_32(efdcfuf);
9750GEN_SPEFPUOP_CONV_64_32(efdcfsf);
9751GEN_SPEFPUOP_CONV_32_64(efdctui);
9752GEN_SPEFPUOP_CONV_32_64(efdctsi);
9753GEN_SPEFPUOP_CONV_32_64(efdctuf);
9754GEN_SPEFPUOP_CONV_32_64(efdctsf);
9755GEN_SPEFPUOP_CONV_32_64(efdctuiz);
9756GEN_SPEFPUOP_CONV_32_64(efdctsiz);
9757GEN_SPEFPUOP_CONV_64_32(efdcfs);
9758GEN_SPEFPUOP_CONV_64_64(efdcfuid);
9759GEN_SPEFPUOP_CONV_64_64(efdcfsid);
9760GEN_SPEFPUOP_CONV_64_64(efdctuidz);
9761GEN_SPEFPUOP_CONV_64_64(efdctsidz);
9762
9763
9764GEN_SPEFPUOP_COMP_64(efdcmpgt);
9765GEN_SPEFPUOP_COMP_64(efdcmplt);
9766GEN_SPEFPUOP_COMP_64(efdcmpeq);
9767GEN_SPEFPUOP_COMP_64(efdtstgt);
9768GEN_SPEFPUOP_COMP_64(efdtstlt);
9769GEN_SPEFPUOP_COMP_64(efdtsteq);
9770
9771
9772GEN_SPE(efdadd, efdsub, 0x10, 0x0B, 0x00000000, 0x00000000, PPC_SPE_DOUBLE);
9773GEN_SPE(efdcfuid, efdcfsid, 0x11, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE);
9774GEN_SPE(efdabs, efdnabs, 0x12, 0x0B, 0x0000F800, 0x0000F800, PPC_SPE_DOUBLE);
9775GEN_SPE(efdneg, speundef, 0x13, 0x0B, 0x0000F800, 0xFFFFFFFF, PPC_SPE_DOUBLE);
9776GEN_SPE(efdmul, efddiv, 0x14, 0x0B, 0x00000000, 0x00000000, PPC_SPE_DOUBLE);
9777GEN_SPE(efdctuidz, efdctsidz, 0x15, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE);
9778GEN_SPE(efdcmpgt, efdcmplt, 0x16, 0x0B, 0x00600000, 0x00600000, PPC_SPE_DOUBLE);
9779GEN_SPE(efdcmpeq, efdcfs, 0x17, 0x0B, 0x00600000, 0x00180000, PPC_SPE_DOUBLE);
9780GEN_SPE(efdcfui, efdcfsi, 0x18, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE);
9781GEN_SPE(efdcfuf, efdcfsf, 0x19, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE);
9782GEN_SPE(efdctui, efdctsi, 0x1A, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE);
9783GEN_SPE(efdctuf, efdctsf, 0x1B, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE);
9784GEN_SPE(efdctuiz, speundef, 0x1C, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_DOUBLE);
9785GEN_SPE(efdctsiz, speundef, 0x1D, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_DOUBLE);
9786GEN_SPE(efdtstgt, efdtstlt, 0x1E, 0x0B, 0x00600000, 0x00600000, PPC_SPE_DOUBLE);
9787GEN_SPE(efdtsteq, speundef, 0x1F, 0x0B, 0x00600000, 0xFFFFFFFF, PPC_SPE_DOUBLE);
9788
9789static void gen_tbegin(DisasContext *ctx)
9790{
9791 if (unlikely(!ctx->tm_enabled)) {
9792 gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_TM);
9793 return;
9794 }
9795 gen_helper_tbegin(cpu_env);
9796}
9797
9798#define GEN_TM_NOOP(name) \
9799static inline void gen_##name(DisasContext *ctx) \
9800{ \
9801 if (unlikely(!ctx->tm_enabled)) { \
9802 gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_TM); \
9803 return; \
9804 } \
9805
9806
9807
9808
9809
9810 \
9811 tcg_gen_movi_i32(cpu_crf[0], 0); \
9812}
9813
9814GEN_TM_NOOP(tend);
9815GEN_TM_NOOP(tabort);
9816GEN_TM_NOOP(tabortwc);
9817GEN_TM_NOOP(tabortwci);
9818GEN_TM_NOOP(tabortdc);
9819GEN_TM_NOOP(tabortdci);
9820GEN_TM_NOOP(tsr);
9821
9822static void gen_tcheck(DisasContext *ctx)
9823{
9824 if (unlikely(!ctx->tm_enabled)) {
9825 gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_TM);
9826 return;
9827 }
9828
9829
9830
9831
9832
9833
9834 tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)], 0x8);
9835}
9836
9837#if defined(CONFIG_USER_ONLY)
9838#define GEN_TM_PRIV_NOOP(name) \
9839static inline void gen_##name(DisasContext *ctx) \
9840{ \
9841 gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC); \
9842}
9843
9844#else
9845
9846#define GEN_TM_PRIV_NOOP(name) \
9847static inline void gen_##name(DisasContext *ctx) \
9848{ \
9849 CHK_SV; \
9850 if (unlikely(!ctx->tm_enabled)) { \
9851 gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_TM); \
9852 return; \
9853 } \
9854
9855
9856
9857
9858
9859 \
9860 tcg_gen_movi_i32(cpu_crf[0], 0); \
9861}
9862
9863#endif
9864
9865GEN_TM_PRIV_NOOP(treclaim);
9866GEN_TM_PRIV_NOOP(trechkpt);
9867
9868static opcode_t opcodes[] = {
9869GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE),
9870GEN_HANDLER(cmp, 0x1F, 0x00, 0x00, 0x00400000, PPC_INTEGER),
9871GEN_HANDLER(cmpi, 0x0B, 0xFF, 0xFF, 0x00400000, PPC_INTEGER),
9872GEN_HANDLER(cmpl, 0x1F, 0x00, 0x01, 0x00400000, PPC_INTEGER),
9873GEN_HANDLER(cmpli, 0x0A, 0xFF, 0xFF, 0x00400000, PPC_INTEGER),
9874GEN_HANDLER_E(cmpb, 0x1F, 0x1C, 0x0F, 0x00000001, PPC_NONE, PPC2_ISA205),
9875GEN_HANDLER(isel, 0x1F, 0x0F, 0xFF, 0x00000001, PPC_ISEL),
9876GEN_HANDLER(addi, 0x0E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9877GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9878GEN_HANDLER2(addic_, "addic.", 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9879GEN_HANDLER(addis, 0x0F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9880GEN_HANDLER(mulhw, 0x1F, 0x0B, 0x02, 0x00000400, PPC_INTEGER),
9881GEN_HANDLER(mulhwu, 0x1F, 0x0B, 0x00, 0x00000400, PPC_INTEGER),
9882GEN_HANDLER(mullw, 0x1F, 0x0B, 0x07, 0x00000000, PPC_INTEGER),
9883GEN_HANDLER(mullwo, 0x1F, 0x0B, 0x17, 0x00000000, PPC_INTEGER),
9884GEN_HANDLER(mulli, 0x07, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9885#if defined(TARGET_PPC64)
9886GEN_HANDLER(mulld, 0x1F, 0x09, 0x07, 0x00000000, PPC_64B),
9887#endif
9888GEN_HANDLER(neg, 0x1F, 0x08, 0x03, 0x0000F800, PPC_INTEGER),
9889GEN_HANDLER(nego, 0x1F, 0x08, 0x13, 0x0000F800, PPC_INTEGER),
9890GEN_HANDLER(subfic, 0x08, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9891GEN_HANDLER2(andi_, "andi.", 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9892GEN_HANDLER2(andis_, "andis.", 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9893GEN_HANDLER(cntlzw, 0x1F, 0x1A, 0x00, 0x00000000, PPC_INTEGER),
9894GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER),
9895GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER),
9896GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9897GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9898GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9899GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9900GEN_HANDLER(popcntb, 0x1F, 0x1A, 0x03, 0x0000F801, PPC_POPCNTB),
9901GEN_HANDLER(popcntw, 0x1F, 0x1A, 0x0b, 0x0000F801, PPC_POPCNTWD),
9902GEN_HANDLER_E(prtyw, 0x1F, 0x1A, 0x04, 0x0000F801, PPC_NONE, PPC2_ISA205),
9903#if defined(TARGET_PPC64)
9904GEN_HANDLER(popcntd, 0x1F, 0x1A, 0x0F, 0x0000F801, PPC_POPCNTWD),
9905GEN_HANDLER(cntlzd, 0x1F, 0x1A, 0x01, 0x00000000, PPC_64B),
9906GEN_HANDLER_E(prtyd, 0x1F, 0x1A, 0x05, 0x0000F801, PPC_NONE, PPC2_ISA205),
9907GEN_HANDLER_E(bpermd, 0x1F, 0x1C, 0x07, 0x00000001, PPC_NONE, PPC2_PERM_ISA206),
9908#endif
9909GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9910GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9911GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9912GEN_HANDLER(slw, 0x1F, 0x18, 0x00, 0x00000000, PPC_INTEGER),
9913GEN_HANDLER(sraw, 0x1F, 0x18, 0x18, 0x00000000, PPC_INTEGER),
9914GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER),
9915GEN_HANDLER(srw, 0x1F, 0x18, 0x10, 0x00000000, PPC_INTEGER),
9916#if defined(TARGET_PPC64)
9917GEN_HANDLER(sld, 0x1F, 0x1B, 0x00, 0x00000000, PPC_64B),
9918GEN_HANDLER(srad, 0x1F, 0x1A, 0x18, 0x00000000, PPC_64B),
9919GEN_HANDLER2(sradi0, "sradi", 0x1F, 0x1A, 0x19, 0x00000000, PPC_64B),
9920GEN_HANDLER2(sradi1, "sradi", 0x1F, 0x1B, 0x19, 0x00000000, PPC_64B),
9921GEN_HANDLER(srd, 0x1F, 0x1B, 0x10, 0x00000000, PPC_64B),
9922#endif
9923GEN_HANDLER(frsqrtes, 0x3B, 0x1A, 0xFF, 0x001F07C0, PPC_FLOAT_FRSQRTES),
9924GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT),
9925GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT),
9926GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT),
9927GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT),
9928GEN_HANDLER(fabs, 0x3F, 0x08, 0x08, 0x001F0000, PPC_FLOAT),
9929GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT),
9930GEN_HANDLER(fnabs, 0x3F, 0x08, 0x04, 0x001F0000, PPC_FLOAT),
9931GEN_HANDLER(fneg, 0x3F, 0x08, 0x01, 0x001F0000, PPC_FLOAT),
9932GEN_HANDLER_E(fcpsgn, 0x3F, 0x08, 0x00, 0x00000000, PPC_NONE, PPC2_ISA205),
9933GEN_HANDLER_E(fmrgew, 0x3F, 0x06, 0x1E, 0x00000001, PPC_NONE, PPC2_VSX207),
9934GEN_HANDLER_E(fmrgow, 0x3F, 0x06, 0x1A, 0x00000001, PPC_NONE, PPC2_VSX207),
9935GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT),
9936GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT),
9937GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT),
9938GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT),
9939GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x00000000, PPC_FLOAT),
9940GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006e0800, PPC_FLOAT),
9941#if defined(TARGET_PPC64)
9942GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B),
9943GEN_HANDLER(lq, 0x38, 0xFF, 0xFF, 0x00000000, PPC_64BX),
9944GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000000, PPC_64B),
9945#endif
9946GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9947GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
9948GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_STRING),
9949GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_STRING),
9950GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_STRING),
9951GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_STRING),
9952GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FFF801, PPC_MEM_EIEIO),
9953GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FFF801, PPC_MEM),
9954GEN_HANDLER_E(lbarx, 0x1F, 0x14, 0x01, 0, PPC_NONE, PPC2_ATOMIC_ISA206),
9955GEN_HANDLER_E(lharx, 0x1F, 0x14, 0x03, 0, PPC_NONE, PPC2_ATOMIC_ISA206),
9956GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000000, PPC_RES),
9957GEN_HANDLER_E(stbcx_, 0x1F, 0x16, 0x15, 0, PPC_NONE, PPC2_ATOMIC_ISA206),
9958GEN_HANDLER_E(sthcx_, 0x1F, 0x16, 0x16, 0, PPC_NONE, PPC2_ATOMIC_ISA206),
9959GEN_HANDLER2(stwcx_, "stwcx.", 0x1F, 0x16, 0x04, 0x00000000, PPC_RES),
9960#if defined(TARGET_PPC64)
9961GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000000, PPC_64B),
9962GEN_HANDLER_E(lqarx, 0x1F, 0x14, 0x08, 0, PPC_NONE, PPC2_LSQ_ISA207),
9963GEN_HANDLER2(stdcx_, "stdcx.", 0x1F, 0x16, 0x06, 0x00000000, PPC_64B),
9964GEN_HANDLER_E(stqcx_, 0x1F, 0x16, 0x05, 0, PPC_NONE, PPC2_LSQ_ISA207),
9965#endif
9966GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x039FF801, PPC_MEM_SYNC),
9967GEN_HANDLER(wait, 0x1F, 0x1E, 0x01, 0x03FFF801, PPC_WAIT),
9968GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
9969GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
9970GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW),
9971GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW),
9972GEN_HANDLER_E(bctar, 0x13, 0x10, 0x11, 0, PPC_NONE, PPC2_BCTAR_ISA207),
9973GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER),
9974GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW),
9975#if defined(TARGET_PPC64)
9976GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B),
9977GEN_HANDLER_E(doze, 0x13, 0x12, 0x0c, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
9978GEN_HANDLER_E(nap, 0x13, 0x12, 0x0d, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
9979GEN_HANDLER_E(sleep, 0x13, 0x12, 0x0e, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
9980GEN_HANDLER_E(rvwinkle, 0x13, 0x12, 0x0f, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
9981GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64H),
9982#endif
9983GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFF01D, PPC_FLOW),
9984GEN_HANDLER(tw, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW),
9985GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
9986#if defined(TARGET_PPC64)
9987GEN_HANDLER(td, 0x1F, 0x04, 0x02, 0x00000001, PPC_64B),
9988GEN_HANDLER(tdi, 0x02, 0xFF, 0xFF, 0x00000000, PPC_64B),
9989#endif
9990GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC),
9991GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC),
9992GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC),
9993GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC),
9994GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MFTB),
9995GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC),
9996#if defined(TARGET_PPC64)
9997GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001EF801, PPC_64B),
9998#endif
9999GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001EF801, PPC_MISC),
10000GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000000, PPC_MISC),
10001GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03C00001, PPC_CACHE),
10002GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE),
10003GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE),
10004GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x00000001, PPC_CACHE),
10005GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x00000001, PPC_CACHE),
10006GEN_HANDLER_E(dcbtls, 0x1F, 0x06, 0x05, 0x02000001, PPC_BOOKE, PPC2_BOOKE206),
10007GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZ),
10008GEN_HANDLER(dst, 0x1F, 0x16, 0x0A, 0x01800001, PPC_ALTIVEC),
10009GEN_HANDLER(dstst, 0x1F, 0x16, 0x0B, 0x02000001, PPC_ALTIVEC),
10010GEN_HANDLER(dss, 0x1F, 0x16, 0x19, 0x019FF801, PPC_ALTIVEC),
10011GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE_ICBI),
10012GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_DCBA),
10013GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT),
10014GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT),
10015GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT),
10016GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT),
10017#if defined(TARGET_PPC64)
10018GEN_HANDLER2(mfsr_64b, "mfsr", 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT_64B),
10019GEN_HANDLER2(mfsrin_64b, "mfsrin", 0x1F, 0x13, 0x14, 0x001F0001,
10020 PPC_SEGMENT_64B),
10021GEN_HANDLER2(mtsr_64b, "mtsr", 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B),
10022GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001,
10023 PPC_SEGMENT_64B),
10024GEN_HANDLER2(slbmte, "slbmte", 0x1F, 0x12, 0x0C, 0x001F0001, PPC_SEGMENT_64B),
10025GEN_HANDLER2(slbmfee, "slbmfee", 0x1F, 0x13, 0x1C, 0x001F0001, PPC_SEGMENT_64B),
10026GEN_HANDLER2(slbmfev, "slbmfev", 0x1F, 0x13, 0x1A, 0x001F0001, PPC_SEGMENT_64B),
10027GEN_HANDLER2(slbfee_, "slbfee.", 0x1F, 0x13, 0x1E, 0x001F0000, PPC_SEGMENT_64B),
10028#endif
10029GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA),
10030
10031
10032GEN_HANDLER(tlbiel, 0x1F, 0x12, 0x08, 0x001F0001, PPC_MEM_TLBIE),
10033GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x001F0001, PPC_MEM_TLBIE),
10034GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC),
10035#if defined(TARGET_PPC64)
10036GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x031FFC01, PPC_SLBI),
10037GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI),
10038#endif
10039GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN),
10040GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN),
10041GEN_HANDLER(abs, 0x1F, 0x08, 0x0B, 0x0000F800, PPC_POWER_BR),
10042GEN_HANDLER(abso, 0x1F, 0x08, 0x1B, 0x0000F800, PPC_POWER_BR),
10043GEN_HANDLER(clcs, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR),
10044GEN_HANDLER(div, 0x1F, 0x0B, 0x0A, 0x00000000, PPC_POWER_BR),
10045GEN_HANDLER(divo, 0x1F, 0x0B, 0x1A, 0x00000000, PPC_POWER_BR),
10046GEN_HANDLER(divs, 0x1F, 0x0B, 0x0B, 0x00000000, PPC_POWER_BR),
10047GEN_HANDLER(divso, 0x1F, 0x0B, 0x1B, 0x00000000, PPC_POWER_BR),
10048GEN_HANDLER(doz, 0x1F, 0x08, 0x08, 0x00000000, PPC_POWER_BR),
10049GEN_HANDLER(dozo, 0x1F, 0x08, 0x18, 0x00000000, PPC_POWER_BR),
10050GEN_HANDLER(dozi, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR),
10051GEN_HANDLER(lscbx, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR),
10052GEN_HANDLER(maskg, 0x1F, 0x1D, 0x00, 0x00000000, PPC_POWER_BR),
10053GEN_HANDLER(maskir, 0x1F, 0x1D, 0x10, 0x00000000, PPC_POWER_BR),
10054GEN_HANDLER(mul, 0x1F, 0x0B, 0x03, 0x00000000, PPC_POWER_BR),
10055GEN_HANDLER(mulo, 0x1F, 0x0B, 0x13, 0x00000000, PPC_POWER_BR),
10056GEN_HANDLER(nabs, 0x1F, 0x08, 0x0F, 0x00000000, PPC_POWER_BR),
10057GEN_HANDLER(nabso, 0x1F, 0x08, 0x1F, 0x00000000, PPC_POWER_BR),
10058GEN_HANDLER(rlmi, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR),
10059GEN_HANDLER(rrib, 0x1F, 0x19, 0x10, 0x00000000, PPC_POWER_BR),
10060GEN_HANDLER(sle, 0x1F, 0x19, 0x04, 0x00000000, PPC_POWER_BR),
10061GEN_HANDLER(sleq, 0x1F, 0x19, 0x06, 0x00000000, PPC_POWER_BR),
10062GEN_HANDLER(sliq, 0x1F, 0x18, 0x05, 0x00000000, PPC_POWER_BR),
10063GEN_HANDLER(slliq, 0x1F, 0x18, 0x07, 0x00000000, PPC_POWER_BR),
10064GEN_HANDLER(sllq, 0x1F, 0x18, 0x06, 0x00000000, PPC_POWER_BR),
10065GEN_HANDLER(slq, 0x1F, 0x18, 0x04, 0x00000000, PPC_POWER_BR),
10066GEN_HANDLER(sraiq, 0x1F, 0x18, 0x1D, 0x00000000, PPC_POWER_BR),
10067GEN_HANDLER(sraq, 0x1F, 0x18, 0x1C, 0x00000000, PPC_POWER_BR),
10068GEN_HANDLER(sre, 0x1F, 0x19, 0x14, 0x00000000, PPC_POWER_BR),
10069GEN_HANDLER(srea, 0x1F, 0x19, 0x1C, 0x00000000, PPC_POWER_BR),
10070GEN_HANDLER(sreq, 0x1F, 0x19, 0x16, 0x00000000, PPC_POWER_BR),
10071GEN_HANDLER(sriq, 0x1F, 0x18, 0x15, 0x00000000, PPC_POWER_BR),
10072GEN_HANDLER(srliq, 0x1F, 0x18, 0x17, 0x00000000, PPC_POWER_BR),
10073GEN_HANDLER(srlq, 0x1F, 0x18, 0x16, 0x00000000, PPC_POWER_BR),
10074GEN_HANDLER(srq, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR),
10075GEN_HANDLER(dsa, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC),
10076GEN_HANDLER(esa, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC),
10077GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC),
10078GEN_HANDLER2(tlbld_6xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB),
10079GEN_HANDLER2(tlbli_6xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB),
10080GEN_HANDLER2(tlbld_74xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_74xx_TLB),
10081GEN_HANDLER2(tlbli_74xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_74xx_TLB),
10082GEN_HANDLER(clf, 0x1F, 0x16, 0x03, 0x03E00000, PPC_POWER),
10083GEN_HANDLER(cli, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER),
10084GEN_HANDLER(dclst, 0x1F, 0x16, 0x13, 0x03E00000, PPC_POWER),
10085GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER),
10086GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER),
10087GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER),
10088GEN_HANDLER(lfq, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
10089GEN_HANDLER(lfqu, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
10090GEN_HANDLER(lfqux, 0x1F, 0x17, 0x19, 0x00000001, PPC_POWER2),
10091GEN_HANDLER(lfqx, 0x1F, 0x17, 0x18, 0x00000001, PPC_POWER2),
10092GEN_HANDLER(stfq, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
10093GEN_HANDLER(stfqu, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
10094GEN_HANDLER(stfqux, 0x1F, 0x17, 0x1D, 0x00000001, PPC_POWER2),
10095GEN_HANDLER(stfqx, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2),
10096GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_MFAPIDI),
10097GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_TLBIVA),
10098GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_DCR),
10099GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_DCR),
10100GEN_HANDLER(mfdcrx, 0x1F, 0x03, 0x08, 0x00000000, PPC_DCRX),
10101GEN_HANDLER(mtdcrx, 0x1F, 0x03, 0x0C, 0x00000000, PPC_DCRX),
10102GEN_HANDLER(mfdcrux, 0x1F, 0x03, 0x09, 0x00000000, PPC_DCRUX),
10103GEN_HANDLER(mtdcrux, 0x1F, 0x03, 0x0D, 0x00000000, PPC_DCRUX),
10104GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON),
10105GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON),
10106GEN_HANDLER2(icbt_40x, "icbt", 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_ICBT),
10107GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON),
10108GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON),
10109GEN_HANDLER2(rfci_40x, "rfci", 0x13, 0x13, 0x01, 0x03FF8001, PPC_40x_EXCP),
10110GEN_HANDLER_E(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE, PPC2_BOOKE206),
10111GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_RFDI),
10112GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_RFMCI),
10113GEN_HANDLER2(tlbre_40x, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB),
10114GEN_HANDLER2(tlbsx_40x, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB),
10115GEN_HANDLER2(tlbwe_40x, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB),
10116GEN_HANDLER2(tlbre_440, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE),
10117GEN_HANDLER2(tlbsx_440, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE),
10118GEN_HANDLER2(tlbwe_440, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE),
10119GEN_HANDLER2_E(tlbre_booke206, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001,
10120 PPC_NONE, PPC2_BOOKE206),
10121GEN_HANDLER2_E(tlbsx_booke206, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000,
10122 PPC_NONE, PPC2_BOOKE206),
10123GEN_HANDLER2_E(tlbwe_booke206, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001,
10124 PPC_NONE, PPC2_BOOKE206),
10125GEN_HANDLER2_E(tlbivax_booke206, "tlbivax", 0x1F, 0x12, 0x18, 0x00000001,
10126 PPC_NONE, PPC2_BOOKE206),
10127GEN_HANDLER2_E(tlbilx_booke206, "tlbilx", 0x1F, 0x12, 0x00, 0x03800001,
10128 PPC_NONE, PPC2_BOOKE206),
10129GEN_HANDLER2_E(msgsnd, "msgsnd", 0x1F, 0x0E, 0x06, 0x03ff0001,
10130 PPC_NONE, PPC2_PRCNTL),
10131GEN_HANDLER2_E(msgclr, "msgclr", 0x1F, 0x0E, 0x07, 0x03ff0001,
10132 PPC_NONE, PPC2_PRCNTL),
10133GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE),
10134GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000E7C01, PPC_WRTEE),
10135GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC),
10136GEN_HANDLER_E(mbar, 0x1F, 0x16, 0x1a, 0x001FF801,
10137 PPC_BOOKE, PPC2_BOOKE206),
10138GEN_HANDLER(msync_4xx, 0x1F, 0x16, 0x12, 0x03FFF801, PPC_BOOKE),
10139GEN_HANDLER2_E(icbt_440, "icbt", 0x1F, 0x16, 0x00, 0x03E00001,
10140 PPC_BOOKE, PPC2_BOOKE206),
10141GEN_HANDLER(lvsl, 0x1f, 0x06, 0x00, 0x00000001, PPC_ALTIVEC),
10142GEN_HANDLER(lvsr, 0x1f, 0x06, 0x01, 0x00000001, PPC_ALTIVEC),
10143GEN_HANDLER(mfvscr, 0x04, 0x2, 0x18, 0x001ff800, PPC_ALTIVEC),
10144GEN_HANDLER(mtvscr, 0x04, 0x2, 0x19, 0x03ff0000, PPC_ALTIVEC),
10145GEN_HANDLER(vmladduhm, 0x04, 0x11, 0xFF, 0x00000000, PPC_ALTIVEC),
10146GEN_HANDLER2(evsel0, "evsel", 0x04, 0x1c, 0x09, 0x00000000, PPC_SPE),
10147GEN_HANDLER2(evsel1, "evsel", 0x04, 0x1d, 0x09, 0x00000000, PPC_SPE),
10148GEN_HANDLER2(evsel2, "evsel", 0x04, 0x1e, 0x09, 0x00000000, PPC_SPE),
10149GEN_HANDLER2(evsel3, "evsel", 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE),
10150
10151#undef GEN_INT_ARITH_ADD
10152#undef GEN_INT_ARITH_ADD_CONST
10153#define GEN_INT_ARITH_ADD(name, opc3, add_ca, compute_ca, compute_ov) \
10154GEN_HANDLER(name, 0x1F, 0x0A, opc3, 0x00000000, PPC_INTEGER),
10155#define GEN_INT_ARITH_ADD_CONST(name, opc3, const_val, \
10156 add_ca, compute_ca, compute_ov) \
10157GEN_HANDLER(name, 0x1F, 0x0A, opc3, 0x0000F800, PPC_INTEGER),
10158GEN_INT_ARITH_ADD(add, 0x08, 0, 0, 0)
10159GEN_INT_ARITH_ADD(addo, 0x18, 0, 0, 1)
10160GEN_INT_ARITH_ADD(addc, 0x00, 0, 1, 0)
10161GEN_INT_ARITH_ADD(addco, 0x10, 0, 1, 1)
10162GEN_INT_ARITH_ADD(adde, 0x04, 1, 1, 0)
10163GEN_INT_ARITH_ADD(addeo, 0x14, 1, 1, 1)
10164GEN_INT_ARITH_ADD_CONST(addme, 0x07, -1LL, 1, 1, 0)
10165GEN_INT_ARITH_ADD_CONST(addmeo, 0x17, -1LL, 1, 1, 1)
10166GEN_INT_ARITH_ADD_CONST(addze, 0x06, 0, 1, 1, 0)
10167GEN_INT_ARITH_ADD_CONST(addzeo, 0x16, 0, 1, 1, 1)
10168
10169#undef GEN_INT_ARITH_DIVW
10170#define GEN_INT_ARITH_DIVW(name, opc3, sign, compute_ov) \
10171GEN_HANDLER(name, 0x1F, 0x0B, opc3, 0x00000000, PPC_INTEGER)
10172GEN_INT_ARITH_DIVW(divwu, 0x0E, 0, 0),
10173GEN_INT_ARITH_DIVW(divwuo, 0x1E, 0, 1),
10174GEN_INT_ARITH_DIVW(divw, 0x0F, 1, 0),
10175GEN_INT_ARITH_DIVW(divwo, 0x1F, 1, 1),
10176GEN_HANDLER_E(divwe, 0x1F, 0x0B, 0x0D, 0, PPC_NONE, PPC2_DIVE_ISA206),
10177GEN_HANDLER_E(divweo, 0x1F, 0x0B, 0x1D, 0, PPC_NONE, PPC2_DIVE_ISA206),
10178GEN_HANDLER_E(divweu, 0x1F, 0x0B, 0x0C, 0, PPC_NONE, PPC2_DIVE_ISA206),
10179GEN_HANDLER_E(divweuo, 0x1F, 0x0B, 0x1C, 0, PPC_NONE, PPC2_DIVE_ISA206),
10180
10181#if defined(TARGET_PPC64)
10182#undef GEN_INT_ARITH_DIVD
10183#define GEN_INT_ARITH_DIVD(name, opc3, sign, compute_ov) \
10184GEN_HANDLER(name, 0x1F, 0x09, opc3, 0x00000000, PPC_64B)
10185GEN_INT_ARITH_DIVD(divdu, 0x0E, 0, 0),
10186GEN_INT_ARITH_DIVD(divduo, 0x1E, 0, 1),
10187GEN_INT_ARITH_DIVD(divd, 0x0F, 1, 0),
10188GEN_INT_ARITH_DIVD(divdo, 0x1F, 1, 1),
10189
10190GEN_HANDLER_E(divdeu, 0x1F, 0x09, 0x0C, 0, PPC_NONE, PPC2_DIVE_ISA206),
10191GEN_HANDLER_E(divdeuo, 0x1F, 0x09, 0x1C, 0, PPC_NONE, PPC2_DIVE_ISA206),
10192GEN_HANDLER_E(divde, 0x1F, 0x09, 0x0D, 0, PPC_NONE, PPC2_DIVE_ISA206),
10193GEN_HANDLER_E(divdeo, 0x1F, 0x09, 0x1D, 0, PPC_NONE, PPC2_DIVE_ISA206),
10194
10195#undef GEN_INT_ARITH_MUL_HELPER
10196#define GEN_INT_ARITH_MUL_HELPER(name, opc3) \
10197GEN_HANDLER(name, 0x1F, 0x09, opc3, 0x00000000, PPC_64B)
10198GEN_INT_ARITH_MUL_HELPER(mulhdu, 0x00),
10199GEN_INT_ARITH_MUL_HELPER(mulhd, 0x02),
10200GEN_INT_ARITH_MUL_HELPER(mulldo, 0x17),
10201#endif
10202
10203#undef GEN_INT_ARITH_SUBF
10204#undef GEN_INT_ARITH_SUBF_CONST
10205#define GEN_INT_ARITH_SUBF(name, opc3, add_ca, compute_ca, compute_ov) \
10206GEN_HANDLER(name, 0x1F, 0x08, opc3, 0x00000000, PPC_INTEGER),
10207#define GEN_INT_ARITH_SUBF_CONST(name, opc3, const_val, \
10208 add_ca, compute_ca, compute_ov) \
10209GEN_HANDLER(name, 0x1F, 0x08, opc3, 0x0000F800, PPC_INTEGER),
10210GEN_INT_ARITH_SUBF(subf, 0x01, 0, 0, 0)
10211GEN_INT_ARITH_SUBF(subfo, 0x11, 0, 0, 1)
10212GEN_INT_ARITH_SUBF(subfc, 0x00, 0, 1, 0)
10213GEN_INT_ARITH_SUBF(subfco, 0x10, 0, 1, 1)
10214GEN_INT_ARITH_SUBF(subfe, 0x04, 1, 1, 0)
10215GEN_INT_ARITH_SUBF(subfeo, 0x14, 1, 1, 1)
10216GEN_INT_ARITH_SUBF_CONST(subfme, 0x07, -1LL, 1, 1, 0)
10217GEN_INT_ARITH_SUBF_CONST(subfmeo, 0x17, -1LL, 1, 1, 1)
10218GEN_INT_ARITH_SUBF_CONST(subfze, 0x06, 0, 1, 1, 0)
10219GEN_INT_ARITH_SUBF_CONST(subfzeo, 0x16, 0, 1, 1, 1)
10220
10221#undef GEN_LOGICAL1
10222#undef GEN_LOGICAL2
10223#define GEN_LOGICAL2(name, tcg_op, opc, type) \
10224GEN_HANDLER(name, 0x1F, 0x1C, opc, 0x00000000, type)
10225#define GEN_LOGICAL1(name, tcg_op, opc, type) \
10226GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, type)
10227GEN_LOGICAL2(and, tcg_gen_and_tl, 0x00, PPC_INTEGER),
10228GEN_LOGICAL2(andc, tcg_gen_andc_tl, 0x01, PPC_INTEGER),
10229GEN_LOGICAL2(eqv, tcg_gen_eqv_tl, 0x08, PPC_INTEGER),
10230GEN_LOGICAL1(extsb, tcg_gen_ext8s_tl, 0x1D, PPC_INTEGER),
10231GEN_LOGICAL1(extsh, tcg_gen_ext16s_tl, 0x1C, PPC_INTEGER),
10232GEN_LOGICAL2(nand, tcg_gen_nand_tl, 0x0E, PPC_INTEGER),
10233GEN_LOGICAL2(nor, tcg_gen_nor_tl, 0x03, PPC_INTEGER),
10234GEN_LOGICAL2(orc, tcg_gen_orc_tl, 0x0C, PPC_INTEGER),
10235#if defined(TARGET_PPC64)
10236GEN_LOGICAL1(extsw, tcg_gen_ext32s_tl, 0x1E, PPC_64B),
10237#endif
10238
10239#if defined(TARGET_PPC64)
10240#undef GEN_PPC64_R2
10241#undef GEN_PPC64_R4
10242#define GEN_PPC64_R2(name, opc1, opc2) \
10243GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B),\
10244GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000, \
10245 PPC_64B)
10246#define GEN_PPC64_R4(name, opc1, opc2) \
10247GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B),\
10248GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x01, 0xFF, 0x00000000, \
10249 PPC_64B), \
10250GEN_HANDLER2(name##2, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000, \
10251 PPC_64B), \
10252GEN_HANDLER2(name##3, stringify(name), opc1, opc2 | 0x11, 0xFF, 0x00000000, \
10253 PPC_64B)
10254GEN_PPC64_R4(rldicl, 0x1E, 0x00),
10255GEN_PPC64_R4(rldicr, 0x1E, 0x02),
10256GEN_PPC64_R4(rldic, 0x1E, 0x04),
10257GEN_PPC64_R2(rldcl, 0x1E, 0x08),
10258GEN_PPC64_R2(rldcr, 0x1E, 0x09),
10259GEN_PPC64_R4(rldimi, 0x1E, 0x06),
10260#endif
10261
10262#undef _GEN_FLOAT_ACB
10263#undef GEN_FLOAT_ACB
10264#undef _GEN_FLOAT_AB
10265#undef GEN_FLOAT_AB
10266#undef _GEN_FLOAT_AC
10267#undef GEN_FLOAT_AC
10268#undef GEN_FLOAT_B
10269#undef GEN_FLOAT_BS
10270#define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat, set_fprf, type) \
10271GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, type)
10272#define GEN_FLOAT_ACB(name, op2, set_fprf, type) \
10273_GEN_FLOAT_ACB(name, name, 0x3F, op2, 0, set_fprf, type), \
10274_GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, set_fprf, type)
10275#define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat, set_fprf, type) \
10276GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)
10277#define GEN_FLOAT_AB(name, op2, inval, set_fprf, type) \
10278_GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0, set_fprf, type), \
10279_GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1, set_fprf, type)
10280#define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat, set_fprf, type) \
10281GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)
10282#define GEN_FLOAT_AC(name, op2, inval, set_fprf, type) \
10283_GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0, set_fprf, type), \
10284_GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1, set_fprf, type)
10285#define GEN_FLOAT_B(name, op2, op3, set_fprf, type) \
10286GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, type)
10287#define GEN_FLOAT_BS(name, op1, op2, set_fprf, type) \
10288GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, type)
10289
10290GEN_FLOAT_AB(add, 0x15, 0x000007C0, 1, PPC_FLOAT),
10291GEN_FLOAT_AB(div, 0x12, 0x000007C0, 1, PPC_FLOAT),
10292GEN_FLOAT_AC(mul, 0x19, 0x0000F800, 1, PPC_FLOAT),
10293GEN_FLOAT_BS(re, 0x3F, 0x18, 1, PPC_FLOAT_EXT),
10294GEN_FLOAT_BS(res, 0x3B, 0x18, 1, PPC_FLOAT_FRES),
10295GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A, 1, PPC_FLOAT_FRSQRTE),
10296_GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0, 0, PPC_FLOAT_FSEL),
10297GEN_FLOAT_AB(sub, 0x14, 0x000007C0, 1, PPC_FLOAT),
10298GEN_FLOAT_ACB(madd, 0x1D, 1, PPC_FLOAT),
10299GEN_FLOAT_ACB(msub, 0x1C, 1, PPC_FLOAT),
10300GEN_FLOAT_ACB(nmadd, 0x1F, 1, PPC_FLOAT),
10301GEN_FLOAT_ACB(nmsub, 0x1E, 1, PPC_FLOAT),
10302GEN_HANDLER_E(ftdiv, 0x3F, 0x00, 0x04, 1, PPC_NONE, PPC2_FP_TST_ISA206),
10303GEN_HANDLER_E(ftsqrt, 0x3F, 0x00, 0x05, 1, PPC_NONE, PPC2_FP_TST_ISA206),
10304GEN_FLOAT_B(ctiw, 0x0E, 0x00, 0, PPC_FLOAT),
10305GEN_HANDLER_E(fctiwu, 0x3F, 0x0E, 0x04, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
10306GEN_FLOAT_B(ctiwz, 0x0F, 0x00, 0, PPC_FLOAT),
10307GEN_HANDLER_E(fctiwuz, 0x3F, 0x0F, 0x04, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
10308GEN_FLOAT_B(rsp, 0x0C, 0x00, 1, PPC_FLOAT),
10309GEN_HANDLER_E(fcfid, 0x3F, 0x0E, 0x1A, 0x001F0000, PPC_NONE, PPC2_FP_CVT_S64),
10310GEN_HANDLER_E(fcfids, 0x3B, 0x0E, 0x1A, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
10311GEN_HANDLER_E(fcfidu, 0x3F, 0x0E, 0x1E, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
10312GEN_HANDLER_E(fcfidus, 0x3B, 0x0E, 0x1E, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
10313GEN_HANDLER_E(fctid, 0x3F, 0x0E, 0x19, 0x001F0000, PPC_NONE, PPC2_FP_CVT_S64),
10314GEN_HANDLER_E(fctidu, 0x3F, 0x0E, 0x1D, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
10315GEN_HANDLER_E(fctidz, 0x3F, 0x0F, 0x19, 0x001F0000, PPC_NONE, PPC2_FP_CVT_S64),
10316GEN_HANDLER_E(fctiduz, 0x3F, 0x0F, 0x1D, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
10317GEN_FLOAT_B(rin, 0x08, 0x0C, 1, PPC_FLOAT_EXT),
10318GEN_FLOAT_B(riz, 0x08, 0x0D, 1, PPC_FLOAT_EXT),
10319GEN_FLOAT_B(rip, 0x08, 0x0E, 1, PPC_FLOAT_EXT),
10320GEN_FLOAT_B(rim, 0x08, 0x0F, 1, PPC_FLOAT_EXT),
10321
10322#undef GEN_LD
10323#undef GEN_LDU
10324#undef GEN_LDUX
10325#undef GEN_LDX_E
10326#undef GEN_LDS
10327#define GEN_LD(name, ldop, opc, type) \
10328GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
10329#define GEN_LDU(name, ldop, opc, type) \
10330GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
10331#define GEN_LDUX(name, ldop, opc2, opc3, type) \
10332GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type),
10333#define GEN_LDX_E(name, ldop, opc2, opc3, type, type2, chk) \
10334GEN_HANDLER_E(name##x, 0x1F, opc2, opc3, 0x00000001, type, type2),
10335#define GEN_LDS(name, ldop, op, type) \
10336GEN_LD(name, ldop, op | 0x20, type) \
10337GEN_LDU(name, ldop, op | 0x21, type) \
10338GEN_LDUX(name, ldop, 0x17, op | 0x01, type) \
10339GEN_LDX(name, ldop, 0x17, op | 0x00, type)
10340
10341GEN_LDS(lbz, ld8u, 0x02, PPC_INTEGER)
10342GEN_LDS(lha, ld16s, 0x0A, PPC_INTEGER)
10343GEN_LDS(lhz, ld16u, 0x08, PPC_INTEGER)
10344GEN_LDS(lwz, ld32u, 0x00, PPC_INTEGER)
10345#if defined(TARGET_PPC64)
10346GEN_LDUX(lwa, ld32s, 0x15, 0x0B, PPC_64B)
10347GEN_LDX(lwa, ld32s, 0x15, 0x0A, PPC_64B)
10348GEN_LDUX(ld, ld64, 0x15, 0x01, PPC_64B)
10349GEN_LDX(ld, ld64, 0x15, 0x00, PPC_64B)
10350GEN_LDX_E(ldbr, ld64ur, 0x14, 0x10, PPC_NONE, PPC2_DBRX, CHK_NONE)
10351
10352
10353GEN_LDX_HVRM(ldcix, ld64, 0x15, 0x1b, PPC_CILDST)
10354GEN_LDX_HVRM(lwzcix, ld32u, 0x15, 0x18, PPC_CILDST)
10355GEN_LDX_HVRM(lhzcix, ld16u, 0x15, 0x19, PPC_CILDST)
10356GEN_LDX_HVRM(lbzcix, ld8u, 0x15, 0x1a, PPC_CILDST)
10357#endif
10358GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER)
10359GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER)
10360
10361#undef GEN_ST
10362#undef GEN_STU
10363#undef GEN_STUX
10364#undef GEN_STX_E
10365#undef GEN_STS
10366#define GEN_ST(name, stop, opc, type) \
10367GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
10368#define GEN_STU(name, stop, opc, type) \
10369GEN_HANDLER(stop##u, opc, 0xFF, 0xFF, 0x00000000, type),
10370#define GEN_STUX(name, stop, opc2, opc3, type) \
10371GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type),
10372#define GEN_STX_E(name, stop, opc2, opc3, type, type2, chk) \
10373GEN_HANDLER_E(name##x, 0x1F, opc2, opc3, 0x00000001, type, type2),
10374#define GEN_STS(name, stop, op, type) \
10375GEN_ST(name, stop, op | 0x20, type) \
10376GEN_STU(name, stop, op | 0x21, type) \
10377GEN_STUX(name, stop, 0x17, op | 0x01, type) \
10378GEN_STX(name, stop, 0x17, op | 0x00, type)
10379
10380GEN_STS(stb, st8, 0x06, PPC_INTEGER)
10381GEN_STS(sth, st16, 0x0C, PPC_INTEGER)
10382GEN_STS(stw, st32, 0x04, PPC_INTEGER)
10383#if defined(TARGET_PPC64)
10384GEN_STUX(std, st64, 0x15, 0x05, PPC_64B)
10385GEN_STX(std, st64, 0x15, 0x04, PPC_64B)
10386GEN_STX_E(stdbr, st64r, 0x14, 0x14, PPC_NONE, PPC2_DBRX, CHK_NONE)
10387GEN_STX_HVRM(stdcix, st64, 0x15, 0x1f, PPC_CILDST)
10388GEN_STX_HVRM(stwcix, st32, 0x15, 0x1c, PPC_CILDST)
10389GEN_STX_HVRM(sthcix, st16, 0x15, 0x1d, PPC_CILDST)
10390GEN_STX_HVRM(stbcix, st8, 0x15, 0x1e, PPC_CILDST)
10391#endif
10392GEN_STX(sthbr, st16r, 0x16, 0x1C, PPC_INTEGER)
10393GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER)
10394
10395#undef GEN_LDF
10396#undef GEN_LDUF
10397#undef GEN_LDUXF
10398#undef GEN_LDXF
10399#undef GEN_LDFS
10400#define GEN_LDF(name, ldop, opc, type) \
10401GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
10402#define GEN_LDUF(name, ldop, opc, type) \
10403GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
10404#define GEN_LDUXF(name, ldop, opc, type) \
10405GEN_HANDLER(name##ux, 0x1F, 0x17, opc, 0x00000001, type),
10406#define GEN_LDXF(name, ldop, opc2, opc3, type) \
10407GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type),
10408#define GEN_LDFS(name, ldop, op, type) \
10409GEN_LDF(name, ldop, op | 0x20, type) \
10410GEN_LDUF(name, ldop, op | 0x21, type) \
10411GEN_LDUXF(name, ldop, op | 0x01, type) \
10412GEN_LDXF(name, ldop, 0x17, op | 0x00, type)
10413
10414GEN_LDFS(lfd, ld64, 0x12, PPC_FLOAT)
10415GEN_LDFS(lfs, ld32fs, 0x10, PPC_FLOAT)
10416GEN_HANDLER_E(lfiwax, 0x1f, 0x17, 0x1a, 0x00000001, PPC_NONE, PPC2_ISA205),
10417GEN_HANDLER_E(lfiwzx, 0x1f, 0x17, 0x1b, 0x1, PPC_NONE, PPC2_FP_CVT_ISA206),
10418GEN_HANDLER_E(lfdp, 0x39, 0xFF, 0xFF, 0x00200003, PPC_NONE, PPC2_ISA205),
10419GEN_HANDLER_E(lfdpx, 0x1F, 0x17, 0x18, 0x00200001, PPC_NONE, PPC2_ISA205),
10420
10421#undef GEN_STF
10422#undef GEN_STUF
10423#undef GEN_STUXF
10424#undef GEN_STXF
10425#undef GEN_STFS
10426#define GEN_STF(name, stop, opc, type) \
10427GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
10428#define GEN_STUF(name, stop, opc, type) \
10429GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
10430#define GEN_STUXF(name, stop, opc, type) \
10431GEN_HANDLER(name##ux, 0x1F, 0x17, opc, 0x00000001, type),
10432#define GEN_STXF(name, stop, opc2, opc3, type) \
10433GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type),
10434#define GEN_STFS(name, stop, op, type) \
10435GEN_STF(name, stop, op | 0x20, type) \
10436GEN_STUF(name, stop, op | 0x21, type) \
10437GEN_STUXF(name, stop, op | 0x01, type) \
10438GEN_STXF(name, stop, 0x17, op | 0x00, type)
10439
10440GEN_STFS(stfd, st64, 0x16, PPC_FLOAT)
10441GEN_STFS(stfs, st32fs, 0x14, PPC_FLOAT)
10442GEN_STXF(stfiw, st32fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX)
10443GEN_HANDLER_E(stfdp, 0x3D, 0xFF, 0xFF, 0x00200003, PPC_NONE, PPC2_ISA205),
10444GEN_HANDLER_E(stfdpx, 0x1F, 0x17, 0x1C, 0x00200001, PPC_NONE, PPC2_ISA205),
10445
10446#undef GEN_CRLOGIC
10447#define GEN_CRLOGIC(name, tcg_op, opc) \
10448GEN_HANDLER(name, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER)
10449GEN_CRLOGIC(crand, tcg_gen_and_i32, 0x08),
10450GEN_CRLOGIC(crandc, tcg_gen_andc_i32, 0x04),
10451GEN_CRLOGIC(creqv, tcg_gen_eqv_i32, 0x09),
10452GEN_CRLOGIC(crnand, tcg_gen_nand_i32, 0x07),
10453GEN_CRLOGIC(crnor, tcg_gen_nor_i32, 0x01),
10454GEN_CRLOGIC(cror, tcg_gen_or_i32, 0x0E),
10455GEN_CRLOGIC(crorc, tcg_gen_orc_i32, 0x0D),
10456GEN_CRLOGIC(crxor, tcg_gen_xor_i32, 0x06),
10457
10458#undef GEN_MAC_HANDLER
10459#define GEN_MAC_HANDLER(name, opc2, opc3) \
10460GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC)
10461GEN_MAC_HANDLER(macchw, 0x0C, 0x05),
10462GEN_MAC_HANDLER(macchwo, 0x0C, 0x15),
10463GEN_MAC_HANDLER(macchws, 0x0C, 0x07),
10464GEN_MAC_HANDLER(macchwso, 0x0C, 0x17),
10465GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06),
10466GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16),
10467GEN_MAC_HANDLER(macchwu, 0x0C, 0x04),
10468GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14),
10469GEN_MAC_HANDLER(machhw, 0x0C, 0x01),
10470GEN_MAC_HANDLER(machhwo, 0x0C, 0x11),
10471GEN_MAC_HANDLER(machhws, 0x0C, 0x03),
10472GEN_MAC_HANDLER(machhwso, 0x0C, 0x13),
10473GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02),
10474GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12),
10475GEN_MAC_HANDLER(machhwu, 0x0C, 0x00),
10476GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10),
10477GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D),
10478GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D),
10479GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F),
10480GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F),
10481GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C),
10482GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C),
10483GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E),
10484GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E),
10485GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05),
10486GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15),
10487GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07),
10488GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17),
10489GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01),
10490GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11),
10491GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03),
10492GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13),
10493GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D),
10494GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D),
10495GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F),
10496GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F),
10497GEN_MAC_HANDLER(mulchw, 0x08, 0x05),
10498GEN_MAC_HANDLER(mulchwu, 0x08, 0x04),
10499GEN_MAC_HANDLER(mulhhw, 0x08, 0x01),
10500GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00),
10501GEN_MAC_HANDLER(mullhw, 0x08, 0x0D),
10502GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C),
10503
10504#undef GEN_VR_LDX
10505#undef GEN_VR_STX
10506#undef GEN_VR_LVE
10507#undef GEN_VR_STVE
10508#define GEN_VR_LDX(name, opc2, opc3) \
10509GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
10510#define GEN_VR_STX(name, opc2, opc3) \
10511GEN_HANDLER(st##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
10512#define GEN_VR_LVE(name, opc2, opc3) \
10513 GEN_HANDLER(lve##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
10514#define GEN_VR_STVE(name, opc2, opc3) \
10515 GEN_HANDLER(stve##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
10516GEN_VR_LDX(lvx, 0x07, 0x03),
10517GEN_VR_LDX(lvxl, 0x07, 0x0B),
10518GEN_VR_LVE(bx, 0x07, 0x00),
10519GEN_VR_LVE(hx, 0x07, 0x01),
10520GEN_VR_LVE(wx, 0x07, 0x02),
10521GEN_VR_STX(svx, 0x07, 0x07),
10522GEN_VR_STX(svxl, 0x07, 0x0F),
10523GEN_VR_STVE(bx, 0x07, 0x04),
10524GEN_VR_STVE(hx, 0x07, 0x05),
10525GEN_VR_STVE(wx, 0x07, 0x06),
10526
10527#undef GEN_VX_LOGICAL
10528#define GEN_VX_LOGICAL(name, tcg_op, opc2, opc3) \
10529GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
10530
10531#undef GEN_VX_LOGICAL_207
10532#define GEN_VX_LOGICAL_207(name, tcg_op, opc2, opc3) \
10533GEN_HANDLER_E(name, 0x04, opc2, opc3, 0x00000000, PPC_NONE, PPC2_ALTIVEC_207)
10534
10535GEN_VX_LOGICAL(vand, tcg_gen_and_i64, 2, 16),
10536GEN_VX_LOGICAL(vandc, tcg_gen_andc_i64, 2, 17),
10537GEN_VX_LOGICAL(vor, tcg_gen_or_i64, 2, 18),
10538GEN_VX_LOGICAL(vxor, tcg_gen_xor_i64, 2, 19),
10539GEN_VX_LOGICAL(vnor, tcg_gen_nor_i64, 2, 20),
10540GEN_VX_LOGICAL_207(veqv, tcg_gen_eqv_i64, 2, 26),
10541GEN_VX_LOGICAL_207(vnand, tcg_gen_nand_i64, 2, 22),
10542GEN_VX_LOGICAL_207(vorc, tcg_gen_orc_i64, 2, 21),
10543
10544#undef GEN_VXFORM
10545#define GEN_VXFORM(name, opc2, opc3) \
10546GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
10547
10548#undef GEN_VXFORM_207
10549#define GEN_VXFORM_207(name, opc2, opc3) \
10550GEN_HANDLER_E(name, 0x04, opc2, opc3, 0x00000000, PPC_NONE, PPC2_ALTIVEC_207)
10551
10552#undef GEN_VXFORM_DUAL
10553#define GEN_VXFORM_DUAL(name0, name1, opc2, opc3, type0, type1) \
10554GEN_HANDLER_E(name0##_##name1, 0x4, opc2, opc3, 0x00000000, type0, type1)
10555
10556#undef GEN_VXRFORM_DUAL
10557#define GEN_VXRFORM_DUAL(name0, name1, opc2, opc3, tp0, tp1) \
10558GEN_HANDLER_E(name0##_##name1, 0x4, opc2, opc3, 0x00000000, tp0, tp1), \
10559GEN_HANDLER_E(name0##_##name1, 0x4, opc2, (opc3 | 0x10), 0x00000000, tp0, tp1),
10560
10561GEN_VXFORM(vaddubm, 0, 0),
10562GEN_VXFORM(vadduhm, 0, 1),
10563GEN_VXFORM(vadduwm, 0, 2),
10564GEN_VXFORM_207(vaddudm, 0, 3),
10565GEN_VXFORM_DUAL(vsububm, bcdadd, 0, 16, PPC_ALTIVEC, PPC_NONE),
10566GEN_VXFORM_DUAL(vsubuhm, bcdsub, 0, 17, PPC_ALTIVEC, PPC_NONE),
10567GEN_VXFORM(vsubuwm, 0, 18),
10568GEN_VXFORM_207(vsubudm, 0, 19),
10569GEN_VXFORM(vmaxub, 1, 0),
10570GEN_VXFORM(vmaxuh, 1, 1),
10571GEN_VXFORM(vmaxuw, 1, 2),
10572GEN_VXFORM_207(vmaxud, 1, 3),
10573GEN_VXFORM(vmaxsb, 1, 4),
10574GEN_VXFORM(vmaxsh, 1, 5),
10575GEN_VXFORM(vmaxsw, 1, 6),
10576GEN_VXFORM_207(vmaxsd, 1, 7),
10577GEN_VXFORM(vminub, 1, 8),
10578GEN_VXFORM(vminuh, 1, 9),
10579GEN_VXFORM(vminuw, 1, 10),
10580GEN_VXFORM_207(vminud, 1, 11),
10581GEN_VXFORM(vminsb, 1, 12),
10582GEN_VXFORM(vminsh, 1, 13),
10583GEN_VXFORM(vminsw, 1, 14),
10584GEN_VXFORM_207(vminsd, 1, 15),
10585GEN_VXFORM(vavgub, 1, 16),
10586GEN_VXFORM(vavguh, 1, 17),
10587GEN_VXFORM(vavguw, 1, 18),
10588GEN_VXFORM(vavgsb, 1, 20),
10589GEN_VXFORM(vavgsh, 1, 21),
10590GEN_VXFORM(vavgsw, 1, 22),
10591GEN_VXFORM(vmrghb, 6, 0),
10592GEN_VXFORM(vmrghh, 6, 1),
10593GEN_VXFORM(vmrghw, 6, 2),
10594GEN_VXFORM(vmrglb, 6, 4),
10595GEN_VXFORM(vmrglh, 6, 5),
10596GEN_VXFORM(vmrglw, 6, 6),
10597GEN_VXFORM_207(vmrgew, 6, 30),
10598GEN_VXFORM_207(vmrgow, 6, 26),
10599GEN_VXFORM(vmuloub, 4, 0),
10600GEN_VXFORM(vmulouh, 4, 1),
10601GEN_VXFORM_DUAL(vmulouw, vmuluwm, 4, 2, PPC_ALTIVEC, PPC_NONE),
10602GEN_VXFORM(vmulosb, 4, 4),
10603GEN_VXFORM(vmulosh, 4, 5),
10604GEN_VXFORM_207(vmulosw, 4, 6),
10605GEN_VXFORM(vmuleub, 4, 8),
10606GEN_VXFORM(vmuleuh, 4, 9),
10607GEN_VXFORM_207(vmuleuw, 4, 10),
10608GEN_VXFORM(vmulesb, 4, 12),
10609GEN_VXFORM(vmulesh, 4, 13),
10610GEN_VXFORM_207(vmulesw, 4, 14),
10611GEN_VXFORM(vslb, 2, 4),
10612GEN_VXFORM(vslh, 2, 5),
10613GEN_VXFORM(vslw, 2, 6),
10614GEN_VXFORM_207(vsld, 2, 23),
10615GEN_VXFORM(vsrb, 2, 8),
10616GEN_VXFORM(vsrh, 2, 9),
10617GEN_VXFORM(vsrw, 2, 10),
10618GEN_VXFORM_207(vsrd, 2, 27),
10619GEN_VXFORM(vsrab, 2, 12),
10620GEN_VXFORM(vsrah, 2, 13),
10621GEN_VXFORM(vsraw, 2, 14),
10622GEN_VXFORM_207(vsrad, 2, 15),
10623GEN_VXFORM(vslo, 6, 16),
10624GEN_VXFORM(vsro, 6, 17),
10625GEN_VXFORM(vaddcuw, 0, 6),
10626GEN_VXFORM(vsubcuw, 0, 22),
10627GEN_VXFORM(vaddubs, 0, 8),
10628GEN_VXFORM(vadduhs, 0, 9),
10629GEN_VXFORM(vadduws, 0, 10),
10630GEN_VXFORM(vaddsbs, 0, 12),
10631GEN_VXFORM(vaddshs, 0, 13),
10632GEN_VXFORM(vaddsws, 0, 14),
10633GEN_VXFORM_DUAL(vsububs, bcdadd, 0, 24, PPC_ALTIVEC, PPC_NONE),
10634GEN_VXFORM_DUAL(vsubuhs, bcdsub, 0, 25, PPC_ALTIVEC, PPC_NONE),
10635GEN_VXFORM(vsubuws, 0, 26),
10636GEN_VXFORM(vsubsbs, 0, 28),
10637GEN_VXFORM(vsubshs, 0, 29),
10638GEN_VXFORM(vsubsws, 0, 30),
10639GEN_VXFORM_207(vadduqm, 0, 4),
10640GEN_VXFORM_207(vaddcuq, 0, 5),
10641GEN_VXFORM_DUAL(vaddeuqm, vaddecuq, 30, 0xFF, PPC_NONE, PPC2_ALTIVEC_207),
10642GEN_VXFORM_207(vsubuqm, 0, 20),
10643GEN_VXFORM_207(vsubcuq, 0, 21),
10644GEN_VXFORM_DUAL(vsubeuqm, vsubecuq, 31, 0xFF, PPC_NONE, PPC2_ALTIVEC_207),
10645GEN_VXFORM(vrlb, 2, 0),
10646GEN_VXFORM(vrlh, 2, 1),
10647GEN_VXFORM(vrlw, 2, 2),
10648GEN_VXFORM_207(vrld, 2, 3),
10649GEN_VXFORM(vsl, 2, 7),
10650GEN_VXFORM(vsr, 2, 11),
10651GEN_VXFORM(vpkuhum, 7, 0),
10652GEN_VXFORM(vpkuwum, 7, 1),
10653GEN_VXFORM_207(vpkudum, 7, 17),
10654GEN_VXFORM(vpkuhus, 7, 2),
10655GEN_VXFORM(vpkuwus, 7, 3),
10656GEN_VXFORM_207(vpkudus, 7, 19),
10657GEN_VXFORM(vpkshus, 7, 4),
10658GEN_VXFORM(vpkswus, 7, 5),
10659GEN_VXFORM_207(vpksdus, 7, 21),
10660GEN_VXFORM(vpkshss, 7, 6),
10661GEN_VXFORM(vpkswss, 7, 7),
10662GEN_VXFORM_207(vpksdss, 7, 23),
10663GEN_VXFORM(vpkpx, 7, 12),
10664GEN_VXFORM(vsum4ubs, 4, 24),
10665GEN_VXFORM(vsum4sbs, 4, 28),
10666GEN_VXFORM(vsum4shs, 4, 25),
10667GEN_VXFORM(vsum2sws, 4, 26),
10668GEN_VXFORM(vsumsws, 4, 30),
10669GEN_VXFORM(vaddfp, 5, 0),
10670GEN_VXFORM(vsubfp, 5, 1),
10671GEN_VXFORM(vmaxfp, 5, 16),
10672GEN_VXFORM(vminfp, 5, 17),
10673
10674#undef GEN_VXRFORM1
10675#undef GEN_VXRFORM
10676#define GEN_VXRFORM1(opname, name, str, opc2, opc3) \
10677 GEN_HANDLER2(name, str, 0x4, opc2, opc3, 0x00000000, PPC_ALTIVEC),
10678#define GEN_VXRFORM(name, opc2, opc3) \
10679 GEN_VXRFORM1(name, name, #name, opc2, opc3) \
10680 GEN_VXRFORM1(name##_dot, name##_, #name ".", opc2, (opc3 | (0x1 << 4)))
10681GEN_VXRFORM(vcmpequb, 3, 0)
10682GEN_VXRFORM(vcmpequh, 3, 1)
10683GEN_VXRFORM(vcmpequw, 3, 2)
10684GEN_VXRFORM(vcmpgtsb, 3, 12)
10685GEN_VXRFORM(vcmpgtsh, 3, 13)
10686GEN_VXRFORM(vcmpgtsw, 3, 14)
10687GEN_VXRFORM(vcmpgtub, 3, 8)
10688GEN_VXRFORM(vcmpgtuh, 3, 9)
10689GEN_VXRFORM(vcmpgtuw, 3, 10)
10690GEN_VXRFORM_DUAL(vcmpeqfp, vcmpequd, 3, 3, PPC_ALTIVEC, PPC_NONE)
10691GEN_VXRFORM(vcmpgefp, 3, 7)
10692GEN_VXRFORM_DUAL(vcmpgtfp, vcmpgtud, 3, 11, PPC_ALTIVEC, PPC_NONE)
10693GEN_VXRFORM_DUAL(vcmpbfp, vcmpgtsd, 3, 15, PPC_ALTIVEC, PPC_NONE)
10694
10695#undef GEN_VXFORM_SIMM
10696#define GEN_VXFORM_SIMM(name, opc2, opc3) \
10697 GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
10698GEN_VXFORM_SIMM(vspltisb, 6, 12),
10699GEN_VXFORM_SIMM(vspltish, 6, 13),
10700GEN_VXFORM_SIMM(vspltisw, 6, 14),
10701
10702#undef GEN_VXFORM_NOA
10703#define GEN_VXFORM_NOA(name, opc2, opc3) \
10704 GEN_HANDLER(name, 0x04, opc2, opc3, 0x001f0000, PPC_ALTIVEC)
10705GEN_VXFORM_NOA(vupkhsb, 7, 8),
10706GEN_VXFORM_NOA(vupkhsh, 7, 9),
10707GEN_VXFORM_207(vupkhsw, 7, 25),
10708GEN_VXFORM_NOA(vupklsb, 7, 10),
10709GEN_VXFORM_NOA(vupklsh, 7, 11),
10710GEN_VXFORM_207(vupklsw, 7, 27),
10711GEN_VXFORM_NOA(vupkhpx, 7, 13),
10712GEN_VXFORM_NOA(vupklpx, 7, 15),
10713GEN_VXFORM_NOA(vrefp, 5, 4),
10714GEN_VXFORM_NOA(vrsqrtefp, 5, 5),
10715GEN_VXFORM_NOA(vexptefp, 5, 6),
10716GEN_VXFORM_NOA(vlogefp, 5, 7),
10717GEN_VXFORM_NOA(vrfim, 5, 11),
10718GEN_VXFORM_NOA(vrfin, 5, 8),
10719GEN_VXFORM_NOA(vrfip, 5, 10),
10720GEN_VXFORM_NOA(vrfiz, 5, 9),
10721
10722#undef GEN_VXFORM_UIMM
10723#define GEN_VXFORM_UIMM(name, opc2, opc3) \
10724 GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
10725GEN_VXFORM_UIMM(vspltb, 6, 8),
10726GEN_VXFORM_UIMM(vsplth, 6, 9),
10727GEN_VXFORM_UIMM(vspltw, 6, 10),
10728GEN_VXFORM_UIMM(vcfux, 5, 12),
10729GEN_VXFORM_UIMM(vcfsx, 5, 13),
10730GEN_VXFORM_UIMM(vctuxs, 5, 14),
10731GEN_VXFORM_UIMM(vctsxs, 5, 15),
10732
10733#undef GEN_VAFORM_PAIRED
10734#define GEN_VAFORM_PAIRED(name0, name1, opc2) \
10735 GEN_HANDLER(name0##_##name1, 0x04, opc2, 0xFF, 0x00000000, PPC_ALTIVEC)
10736GEN_VAFORM_PAIRED(vmhaddshs, vmhraddshs, 16),
10737GEN_VAFORM_PAIRED(vmsumubm, vmsummbm, 18),
10738GEN_VAFORM_PAIRED(vmsumuhm, vmsumuhs, 19),
10739GEN_VAFORM_PAIRED(vmsumshm, vmsumshs, 20),
10740GEN_VAFORM_PAIRED(vsel, vperm, 21),
10741GEN_VAFORM_PAIRED(vmaddfp, vnmsubfp, 23),
10742
10743GEN_VXFORM_DUAL(vclzb, vpopcntb, 1, 28, PPC_NONE, PPC2_ALTIVEC_207),
10744GEN_VXFORM_DUAL(vclzh, vpopcnth, 1, 29, PPC_NONE, PPC2_ALTIVEC_207),
10745GEN_VXFORM_DUAL(vclzw, vpopcntw, 1, 30, PPC_NONE, PPC2_ALTIVEC_207),
10746GEN_VXFORM_DUAL(vclzd, vpopcntd, 1, 31, PPC_NONE, PPC2_ALTIVEC_207),
10747
10748GEN_VXFORM_207(vbpermq, 6, 21),
10749GEN_VXFORM_207(vgbbd, 6, 20),
10750GEN_VXFORM_207(vpmsumb, 4, 16),
10751GEN_VXFORM_207(vpmsumh, 4, 17),
10752GEN_VXFORM_207(vpmsumw, 4, 18),
10753GEN_VXFORM_207(vpmsumd, 4, 19),
10754
10755GEN_VXFORM_207(vsbox, 4, 23),
10756
10757GEN_VXFORM_DUAL(vcipher, vcipherlast, 4, 20, PPC_NONE, PPC2_ALTIVEC_207),
10758GEN_VXFORM_DUAL(vncipher, vncipherlast, 4, 21, PPC_NONE, PPC2_ALTIVEC_207),
10759
10760GEN_VXFORM_207(vshasigmaw, 1, 26),
10761GEN_VXFORM_207(vshasigmad, 1, 27),
10762
10763GEN_VXFORM_DUAL(vsldoi, vpermxor, 22, 0xFF, PPC_ALTIVEC, PPC_NONE),
10764
10765GEN_HANDLER_E(lxsdx, 0x1F, 0x0C, 0x12, 0, PPC_NONE, PPC2_VSX),
10766GEN_HANDLER_E(lxsiwax, 0x1F, 0x0C, 0x02, 0, PPC_NONE, PPC2_VSX207),
10767GEN_HANDLER_E(lxsiwzx, 0x1F, 0x0C, 0x00, 0, PPC_NONE, PPC2_VSX207),
10768GEN_HANDLER_E(lxsspx, 0x1F, 0x0C, 0x10, 0, PPC_NONE, PPC2_VSX207),
10769GEN_HANDLER_E(lxvd2x, 0x1F, 0x0C, 0x1A, 0, PPC_NONE, PPC2_VSX),
10770GEN_HANDLER_E(lxvdsx, 0x1F, 0x0C, 0x0A, 0, PPC_NONE, PPC2_VSX),
10771GEN_HANDLER_E(lxvw4x, 0x1F, 0x0C, 0x18, 0, PPC_NONE, PPC2_VSX),
10772
10773GEN_HANDLER_E(stxsdx, 0x1F, 0xC, 0x16, 0, PPC_NONE, PPC2_VSX),
10774GEN_HANDLER_E(stxsiwx, 0x1F, 0xC, 0x04, 0, PPC_NONE, PPC2_VSX207),
10775GEN_HANDLER_E(stxsspx, 0x1F, 0xC, 0x14, 0, PPC_NONE, PPC2_VSX207),
10776GEN_HANDLER_E(stxvd2x, 0x1F, 0xC, 0x1E, 0, PPC_NONE, PPC2_VSX),
10777GEN_HANDLER_E(stxvw4x, 0x1F, 0xC, 0x1C, 0, PPC_NONE, PPC2_VSX),
10778
10779GEN_HANDLER_E(mfvsrwz, 0x1F, 0x13, 0x03, 0x0000F800, PPC_NONE, PPC2_VSX207),
10780GEN_HANDLER_E(mtvsrwa, 0x1F, 0x13, 0x06, 0x0000F800, PPC_NONE, PPC2_VSX207),
10781GEN_HANDLER_E(mtvsrwz, 0x1F, 0x13, 0x07, 0x0000F800, PPC_NONE, PPC2_VSX207),
10782#if defined(TARGET_PPC64)
10783GEN_HANDLER_E(mfvsrd, 0x1F, 0x13, 0x01, 0x0000F800, PPC_NONE, PPC2_VSX207),
10784GEN_HANDLER_E(mtvsrd, 0x1F, 0x13, 0x05, 0x0000F800, PPC_NONE, PPC2_VSX207),
10785#endif
10786
10787#undef GEN_XX2FORM
10788#define GEN_XX2FORM(name, opc2, opc3, fl2) \
10789GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0, opc3, 0, PPC_NONE, fl2), \
10790GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 1, opc3, 0, PPC_NONE, fl2)
10791
10792#undef GEN_XX3FORM
10793#define GEN_XX3FORM(name, opc2, opc3, fl2) \
10794GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0, opc3, 0, PPC_NONE, fl2), \
10795GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 1, opc3, 0, PPC_NONE, fl2), \
10796GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 2, opc3, 0, PPC_NONE, fl2), \
10797GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 3, opc3, 0, PPC_NONE, fl2)
10798
10799#undef GEN_XX2IFORM
10800#define GEN_XX2IFORM(name, opc2, opc3, fl2) \
10801GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0, opc3, 1, PPC_NONE, fl2), \
10802GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 1, opc3, 1, PPC_NONE, fl2), \
10803GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 2, opc3, 1, PPC_NONE, fl2), \
10804GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 3, opc3, 1, PPC_NONE, fl2)
10805
10806#undef GEN_XX3_RC_FORM
10807#define GEN_XX3_RC_FORM(name, opc2, opc3, fl2) \
10808GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0x00, opc3 | 0x00, 0, PPC_NONE, fl2), \
10809GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0x01, opc3 | 0x00, 0, PPC_NONE, fl2), \
10810GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0x02, opc3 | 0x00, 0, PPC_NONE, fl2), \
10811GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0x03, opc3 | 0x00, 0, PPC_NONE, fl2), \
10812GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0x00, opc3 | 0x10, 0, PPC_NONE, fl2), \
10813GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0x01, opc3 | 0x10, 0, PPC_NONE, fl2), \
10814GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0x02, opc3 | 0x10, 0, PPC_NONE, fl2), \
10815GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0x03, opc3 | 0x10, 0, PPC_NONE, fl2)
10816
10817#undef GEN_XX3FORM_DM
10818#define GEN_XX3FORM_DM(name, opc2, opc3) \
10819GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x00, opc3|0x00, 0, PPC_NONE, PPC2_VSX),\
10820GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x01, opc3|0x00, 0, PPC_NONE, PPC2_VSX),\
10821GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x02, opc3|0x00, 0, PPC_NONE, PPC2_VSX),\
10822GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x03, opc3|0x00, 0, PPC_NONE, PPC2_VSX),\
10823GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x00, opc3|0x04, 0, PPC_NONE, PPC2_VSX),\
10824GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x01, opc3|0x04, 0, PPC_NONE, PPC2_VSX),\
10825GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x02, opc3|0x04, 0, PPC_NONE, PPC2_VSX),\
10826GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x03, opc3|0x04, 0, PPC_NONE, PPC2_VSX),\
10827GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x00, opc3|0x08, 0, PPC_NONE, PPC2_VSX),\
10828GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x01, opc3|0x08, 0, PPC_NONE, PPC2_VSX),\
10829GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x02, opc3|0x08, 0, PPC_NONE, PPC2_VSX),\
10830GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x03, opc3|0x08, 0, PPC_NONE, PPC2_VSX),\
10831GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x00, opc3|0x0C, 0, PPC_NONE, PPC2_VSX),\
10832GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x01, opc3|0x0C, 0, PPC_NONE, PPC2_VSX),\
10833GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x02, opc3|0x0C, 0, PPC_NONE, PPC2_VSX),\
10834GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x03, opc3|0x0C, 0, PPC_NONE, PPC2_VSX)
10835
10836GEN_XX2FORM(xsabsdp, 0x12, 0x15, PPC2_VSX),
10837GEN_XX2FORM(xsnabsdp, 0x12, 0x16, PPC2_VSX),
10838GEN_XX2FORM(xsnegdp, 0x12, 0x17, PPC2_VSX),
10839GEN_XX3FORM(xscpsgndp, 0x00, 0x16, PPC2_VSX),
10840
10841GEN_XX2FORM(xvabsdp, 0x12, 0x1D, PPC2_VSX),
10842GEN_XX2FORM(xvnabsdp, 0x12, 0x1E, PPC2_VSX),
10843GEN_XX2FORM(xvnegdp, 0x12, 0x1F, PPC2_VSX),
10844GEN_XX3FORM(xvcpsgndp, 0x00, 0x1E, PPC2_VSX),
10845GEN_XX2FORM(xvabssp, 0x12, 0x19, PPC2_VSX),
10846GEN_XX2FORM(xvnabssp, 0x12, 0x1A, PPC2_VSX),
10847GEN_XX2FORM(xvnegsp, 0x12, 0x1B, PPC2_VSX),
10848GEN_XX3FORM(xvcpsgnsp, 0x00, 0x1A, PPC2_VSX),
10849
10850GEN_XX3FORM(xsadddp, 0x00, 0x04, PPC2_VSX),
10851GEN_XX3FORM(xssubdp, 0x00, 0x05, PPC2_VSX),
10852GEN_XX3FORM(xsmuldp, 0x00, 0x06, PPC2_VSX),
10853GEN_XX3FORM(xsdivdp, 0x00, 0x07, PPC2_VSX),
10854GEN_XX2FORM(xsredp, 0x14, 0x05, PPC2_VSX),
10855GEN_XX2FORM(xssqrtdp, 0x16, 0x04, PPC2_VSX),
10856GEN_XX2FORM(xsrsqrtedp, 0x14, 0x04, PPC2_VSX),
10857GEN_XX3FORM(xstdivdp, 0x14, 0x07, PPC2_VSX),
10858GEN_XX2FORM(xstsqrtdp, 0x14, 0x06, PPC2_VSX),
10859GEN_XX3FORM(xsmaddadp, 0x04, 0x04, PPC2_VSX),
10860GEN_XX3FORM(xsmaddmdp, 0x04, 0x05, PPC2_VSX),
10861GEN_XX3FORM(xsmsubadp, 0x04, 0x06, PPC2_VSX),
10862GEN_XX3FORM(xsmsubmdp, 0x04, 0x07, PPC2_VSX),
10863GEN_XX3FORM(xsnmaddadp, 0x04, 0x14, PPC2_VSX),
10864GEN_XX3FORM(xsnmaddmdp, 0x04, 0x15, PPC2_VSX),
10865GEN_XX3FORM(xsnmsubadp, 0x04, 0x16, PPC2_VSX),
10866GEN_XX3FORM(xsnmsubmdp, 0x04, 0x17, PPC2_VSX),
10867GEN_XX2IFORM(xscmpodp, 0x0C, 0x05, PPC2_VSX),
10868GEN_XX2IFORM(xscmpudp, 0x0C, 0x04, PPC2_VSX),
10869GEN_XX3FORM(xsmaxdp, 0x00, 0x14, PPC2_VSX),
10870GEN_XX3FORM(xsmindp, 0x00, 0x15, PPC2_VSX),
10871GEN_XX2FORM(xscvdpsp, 0x12, 0x10, PPC2_VSX),
10872GEN_XX2FORM(xscvdpspn, 0x16, 0x10, PPC2_VSX207),
10873GEN_XX2FORM(xscvspdp, 0x12, 0x14, PPC2_VSX),
10874GEN_XX2FORM(xscvspdpn, 0x16, 0x14, PPC2_VSX207),
10875GEN_XX2FORM(xscvdpsxds, 0x10, 0x15, PPC2_VSX),
10876GEN_XX2FORM(xscvdpsxws, 0x10, 0x05, PPC2_VSX),
10877GEN_XX2FORM(xscvdpuxds, 0x10, 0x14, PPC2_VSX),
10878GEN_XX2FORM(xscvdpuxws, 0x10, 0x04, PPC2_VSX),
10879GEN_XX2FORM(xscvsxddp, 0x10, 0x17, PPC2_VSX),
10880GEN_XX2FORM(xscvuxddp, 0x10, 0x16, PPC2_VSX),
10881GEN_XX2FORM(xsrdpi, 0x12, 0x04, PPC2_VSX),
10882GEN_XX2FORM(xsrdpic, 0x16, 0x06, PPC2_VSX),
10883GEN_XX2FORM(xsrdpim, 0x12, 0x07, PPC2_VSX),
10884GEN_XX2FORM(xsrdpip, 0x12, 0x06, PPC2_VSX),
10885GEN_XX2FORM(xsrdpiz, 0x12, 0x05, PPC2_VSX),
10886
10887GEN_XX3FORM(xsaddsp, 0x00, 0x00, PPC2_VSX207),
10888GEN_XX3FORM(xssubsp, 0x00, 0x01, PPC2_VSX207),
10889GEN_XX3FORM(xsmulsp, 0x00, 0x02, PPC2_VSX207),
10890GEN_XX3FORM(xsdivsp, 0x00, 0x03, PPC2_VSX207),
10891GEN_XX2FORM(xsresp, 0x14, 0x01, PPC2_VSX207),
10892GEN_XX2FORM(xsrsp, 0x12, 0x11, PPC2_VSX207),
10893GEN_XX2FORM(xssqrtsp, 0x16, 0x00, PPC2_VSX207),
10894GEN_XX2FORM(xsrsqrtesp, 0x14, 0x00, PPC2_VSX207),
10895GEN_XX3FORM(xsmaddasp, 0x04, 0x00, PPC2_VSX207),
10896GEN_XX3FORM(xsmaddmsp, 0x04, 0x01, PPC2_VSX207),
10897GEN_XX3FORM(xsmsubasp, 0x04, 0x02, PPC2_VSX207),
10898GEN_XX3FORM(xsmsubmsp, 0x04, 0x03, PPC2_VSX207),
10899GEN_XX3FORM(xsnmaddasp, 0x04, 0x10, PPC2_VSX207),
10900GEN_XX3FORM(xsnmaddmsp, 0x04, 0x11, PPC2_VSX207),
10901GEN_XX3FORM(xsnmsubasp, 0x04, 0x12, PPC2_VSX207),
10902GEN_XX3FORM(xsnmsubmsp, 0x04, 0x13, PPC2_VSX207),
10903GEN_XX2FORM(xscvsxdsp, 0x10, 0x13, PPC2_VSX207),
10904GEN_XX2FORM(xscvuxdsp, 0x10, 0x12, PPC2_VSX207),
10905
10906GEN_XX3FORM(xvadddp, 0x00, 0x0C, PPC2_VSX),
10907GEN_XX3FORM(xvsubdp, 0x00, 0x0D, PPC2_VSX),
10908GEN_XX3FORM(xvmuldp, 0x00, 0x0E, PPC2_VSX),
10909GEN_XX3FORM(xvdivdp, 0x00, 0x0F, PPC2_VSX),
10910GEN_XX2FORM(xvredp, 0x14, 0x0D, PPC2_VSX),
10911GEN_XX2FORM(xvsqrtdp, 0x16, 0x0C, PPC2_VSX),
10912GEN_XX2FORM(xvrsqrtedp, 0x14, 0x0C, PPC2_VSX),
10913GEN_XX3FORM(xvtdivdp, 0x14, 0x0F, PPC2_VSX),
10914GEN_XX2FORM(xvtsqrtdp, 0x14, 0x0E, PPC2_VSX),
10915GEN_XX3FORM(xvmaddadp, 0x04, 0x0C, PPC2_VSX),
10916GEN_XX3FORM(xvmaddmdp, 0x04, 0x0D, PPC2_VSX),
10917GEN_XX3FORM(xvmsubadp, 0x04, 0x0E, PPC2_VSX),
10918GEN_XX3FORM(xvmsubmdp, 0x04, 0x0F, PPC2_VSX),
10919GEN_XX3FORM(xvnmaddadp, 0x04, 0x1C, PPC2_VSX),
10920GEN_XX3FORM(xvnmaddmdp, 0x04, 0x1D, PPC2_VSX),
10921GEN_XX3FORM(xvnmsubadp, 0x04, 0x1E, PPC2_VSX),
10922GEN_XX3FORM(xvnmsubmdp, 0x04, 0x1F, PPC2_VSX),
10923GEN_XX3FORM(xvmaxdp, 0x00, 0x1C, PPC2_VSX),
10924GEN_XX3FORM(xvmindp, 0x00, 0x1D, PPC2_VSX),
10925GEN_XX3_RC_FORM(xvcmpeqdp, 0x0C, 0x0C, PPC2_VSX),
10926GEN_XX3_RC_FORM(xvcmpgtdp, 0x0C, 0x0D, PPC2_VSX),
10927GEN_XX3_RC_FORM(xvcmpgedp, 0x0C, 0x0E, PPC2_VSX),
10928GEN_XX2FORM(xvcvdpsp, 0x12, 0x18, PPC2_VSX),
10929GEN_XX2FORM(xvcvdpsxds, 0x10, 0x1D, PPC2_VSX),
10930GEN_XX2FORM(xvcvdpsxws, 0x10, 0x0D, PPC2_VSX),
10931GEN_XX2FORM(xvcvdpuxds, 0x10, 0x1C, PPC2_VSX),
10932GEN_XX2FORM(xvcvdpuxws, 0x10, 0x0C, PPC2_VSX),
10933GEN_XX2FORM(xvcvsxddp, 0x10, 0x1F, PPC2_VSX),
10934GEN_XX2FORM(xvcvuxddp, 0x10, 0x1E, PPC2_VSX),
10935GEN_XX2FORM(xvcvsxwdp, 0x10, 0x0F, PPC2_VSX),
10936GEN_XX2FORM(xvcvuxwdp, 0x10, 0x0E, PPC2_VSX),
10937GEN_XX2FORM(xvrdpi, 0x12, 0x0C, PPC2_VSX),
10938GEN_XX2FORM(xvrdpic, 0x16, 0x0E, PPC2_VSX),
10939GEN_XX2FORM(xvrdpim, 0x12, 0x0F, PPC2_VSX),
10940GEN_XX2FORM(xvrdpip, 0x12, 0x0E, PPC2_VSX),
10941GEN_XX2FORM(xvrdpiz, 0x12, 0x0D, PPC2_VSX),
10942
10943GEN_XX3FORM(xvaddsp, 0x00, 0x08, PPC2_VSX),
10944GEN_XX3FORM(xvsubsp, 0x00, 0x09, PPC2_VSX),
10945GEN_XX3FORM(xvmulsp, 0x00, 0x0A, PPC2_VSX),
10946GEN_XX3FORM(xvdivsp, 0x00, 0x0B, PPC2_VSX),
10947GEN_XX2FORM(xvresp, 0x14, 0x09, PPC2_VSX),
10948GEN_XX2FORM(xvsqrtsp, 0x16, 0x08, PPC2_VSX),
10949GEN_XX2FORM(xvrsqrtesp, 0x14, 0x08, PPC2_VSX),
10950GEN_XX3FORM(xvtdivsp, 0x14, 0x0B, PPC2_VSX),
10951GEN_XX2FORM(xvtsqrtsp, 0x14, 0x0A, PPC2_VSX),
10952GEN_XX3FORM(xvmaddasp, 0x04, 0x08, PPC2_VSX),
10953GEN_XX3FORM(xvmaddmsp, 0x04, 0x09, PPC2_VSX),
10954GEN_XX3FORM(xvmsubasp, 0x04, 0x0A, PPC2_VSX),
10955GEN_XX3FORM(xvmsubmsp, 0x04, 0x0B, PPC2_VSX),
10956GEN_XX3FORM(xvnmaddasp, 0x04, 0x18, PPC2_VSX),
10957GEN_XX3FORM(xvnmaddmsp, 0x04, 0x19, PPC2_VSX),
10958GEN_XX3FORM(xvnmsubasp, 0x04, 0x1A, PPC2_VSX),
10959GEN_XX3FORM(xvnmsubmsp, 0x04, 0x1B, PPC2_VSX),
10960GEN_XX3FORM(xvmaxsp, 0x00, 0x18, PPC2_VSX),
10961GEN_XX3FORM(xvminsp, 0x00, 0x19, PPC2_VSX),
10962GEN_XX3_RC_FORM(xvcmpeqsp, 0x0C, 0x08, PPC2_VSX),
10963GEN_XX3_RC_FORM(xvcmpgtsp, 0x0C, 0x09, PPC2_VSX),
10964GEN_XX3_RC_FORM(xvcmpgesp, 0x0C, 0x0A, PPC2_VSX),
10965GEN_XX2FORM(xvcvspdp, 0x12, 0x1C, PPC2_VSX),
10966GEN_XX2FORM(xvcvspsxds, 0x10, 0x19, PPC2_VSX),
10967GEN_XX2FORM(xvcvspsxws, 0x10, 0x09, PPC2_VSX),
10968GEN_XX2FORM(xvcvspuxds, 0x10, 0x18, PPC2_VSX),
10969GEN_XX2FORM(xvcvspuxws, 0x10, 0x08, PPC2_VSX),
10970GEN_XX2FORM(xvcvsxdsp, 0x10, 0x1B, PPC2_VSX),
10971GEN_XX2FORM(xvcvuxdsp, 0x10, 0x1A, PPC2_VSX),
10972GEN_XX2FORM(xvcvsxwsp, 0x10, 0x0B, PPC2_VSX),
10973GEN_XX2FORM(xvcvuxwsp, 0x10, 0x0A, PPC2_VSX),
10974GEN_XX2FORM(xvrspi, 0x12, 0x08, PPC2_VSX),
10975GEN_XX2FORM(xvrspic, 0x16, 0x0A, PPC2_VSX),
10976GEN_XX2FORM(xvrspim, 0x12, 0x0B, PPC2_VSX),
10977GEN_XX2FORM(xvrspip, 0x12, 0x0A, PPC2_VSX),
10978GEN_XX2FORM(xvrspiz, 0x12, 0x09, PPC2_VSX),
10979
10980#undef VSX_LOGICAL
10981#define VSX_LOGICAL(name, opc2, opc3, fl2) \
10982GEN_XX3FORM(name, opc2, opc3, fl2)
10983
10984VSX_LOGICAL(xxland, 0x8, 0x10, PPC2_VSX),
10985VSX_LOGICAL(xxlandc, 0x8, 0x11, PPC2_VSX),
10986VSX_LOGICAL(xxlor, 0x8, 0x12, PPC2_VSX),
10987VSX_LOGICAL(xxlxor, 0x8, 0x13, PPC2_VSX),
10988VSX_LOGICAL(xxlnor, 0x8, 0x14, PPC2_VSX),
10989VSX_LOGICAL(xxleqv, 0x8, 0x17, PPC2_VSX207),
10990VSX_LOGICAL(xxlnand, 0x8, 0x16, PPC2_VSX207),
10991VSX_LOGICAL(xxlorc, 0x8, 0x15, PPC2_VSX207),
10992GEN_XX3FORM(xxmrghw, 0x08, 0x02, PPC2_VSX),
10993GEN_XX3FORM(xxmrglw, 0x08, 0x06, PPC2_VSX),
10994GEN_XX2FORM(xxspltw, 0x08, 0x0A, PPC2_VSX),
10995GEN_XX3FORM_DM(xxsldwi, 0x08, 0x00),
10996
10997#define GEN_XXSEL_ROW(opc3) \
10998GEN_HANDLER2_E(xxsel, "xxsel", 0x3C, 0x18, opc3, 0, PPC_NONE, PPC2_VSX), \
10999GEN_HANDLER2_E(xxsel, "xxsel", 0x3C, 0x19, opc3, 0, PPC_NONE, PPC2_VSX), \
11000GEN_HANDLER2_E(xxsel, "xxsel", 0x3C, 0x1A, opc3, 0, PPC_NONE, PPC2_VSX), \
11001GEN_HANDLER2_E(xxsel, "xxsel", 0x3C, 0x1B, opc3, 0, PPC_NONE, PPC2_VSX), \
11002GEN_HANDLER2_E(xxsel, "xxsel", 0x3C, 0x1C, opc3, 0, PPC_NONE, PPC2_VSX), \
11003GEN_HANDLER2_E(xxsel, "xxsel", 0x3C, 0x1D, opc3, 0, PPC_NONE, PPC2_VSX), \
11004GEN_HANDLER2_E(xxsel, "xxsel", 0x3C, 0x1E, opc3, 0, PPC_NONE, PPC2_VSX), \
11005GEN_HANDLER2_E(xxsel, "xxsel", 0x3C, 0x1F, opc3, 0, PPC_NONE, PPC2_VSX), \
11006
11007GEN_XXSEL_ROW(0x00)
11008GEN_XXSEL_ROW(0x01)
11009GEN_XXSEL_ROW(0x02)
11010GEN_XXSEL_ROW(0x03)
11011GEN_XXSEL_ROW(0x04)
11012GEN_XXSEL_ROW(0x05)
11013GEN_XXSEL_ROW(0x06)
11014GEN_XXSEL_ROW(0x07)
11015GEN_XXSEL_ROW(0x08)
11016GEN_XXSEL_ROW(0x09)
11017GEN_XXSEL_ROW(0x0A)
11018GEN_XXSEL_ROW(0x0B)
11019GEN_XXSEL_ROW(0x0C)
11020GEN_XXSEL_ROW(0x0D)
11021GEN_XXSEL_ROW(0x0E)
11022GEN_XXSEL_ROW(0x0F)
11023GEN_XXSEL_ROW(0x10)
11024GEN_XXSEL_ROW(0x11)
11025GEN_XXSEL_ROW(0x12)
11026GEN_XXSEL_ROW(0x13)
11027GEN_XXSEL_ROW(0x14)
11028GEN_XXSEL_ROW(0x15)
11029GEN_XXSEL_ROW(0x16)
11030GEN_XXSEL_ROW(0x17)
11031GEN_XXSEL_ROW(0x18)
11032GEN_XXSEL_ROW(0x19)
11033GEN_XXSEL_ROW(0x1A)
11034GEN_XXSEL_ROW(0x1B)
11035GEN_XXSEL_ROW(0x1C)
11036GEN_XXSEL_ROW(0x1D)
11037GEN_XXSEL_ROW(0x1E)
11038GEN_XXSEL_ROW(0x1F)
11039
11040GEN_XX3FORM_DM(xxpermdi, 0x08, 0x01),
11041
11042#undef GEN_DFP_T_A_B_Rc
11043#undef GEN_DFP_BF_A_B
11044#undef GEN_DFP_BF_A_DCM
11045#undef GEN_DFP_T_B_U32_U32_Rc
11046#undef GEN_DFP_T_A_B_I32_Rc
11047#undef GEN_DFP_T_B_Rc
11048#undef GEN_DFP_T_FPR_I32_Rc
11049
11050#define _GEN_DFP_LONG(name, op1, op2, mask) \
11051GEN_HANDLER_E(name, 0x3B, op1, op2, mask, PPC_NONE, PPC2_DFP)
11052
11053#define _GEN_DFP_LONGx2(name, op1, op2, mask) \
11054GEN_HANDLER_E(name, 0x3B, op1, 0x00 | op2, mask, PPC_NONE, PPC2_DFP), \
11055GEN_HANDLER_E(name, 0x3B, op1, 0x10 | op2, mask, PPC_NONE, PPC2_DFP)
11056
11057#define _GEN_DFP_LONGx4(name, op1, op2, mask) \
11058GEN_HANDLER_E(name, 0x3B, op1, 0x00 | op2, mask, PPC_NONE, PPC2_DFP), \
11059GEN_HANDLER_E(name, 0x3B, op1, 0x08 | op2, mask, PPC_NONE, PPC2_DFP), \
11060GEN_HANDLER_E(name, 0x3B, op1, 0x10 | op2, mask, PPC_NONE, PPC2_DFP), \
11061GEN_HANDLER_E(name, 0x3B, op1, 0x18 | op2, mask, PPC_NONE, PPC2_DFP)
11062
11063#define _GEN_DFP_QUAD(name, op1, op2, mask) \
11064GEN_HANDLER_E(name, 0x3F, op1, op2, mask, PPC_NONE, PPC2_DFP)
11065
11066#define _GEN_DFP_QUADx2(name, op1, op2, mask) \
11067GEN_HANDLER_E(name, 0x3F, op1, 0x00 | op2, mask, PPC_NONE, PPC2_DFP), \
11068GEN_HANDLER_E(name, 0x3F, op1, 0x10 | op2, mask, PPC_NONE, PPC2_DFP)
11069
11070#define _GEN_DFP_QUADx4(name, op1, op2, mask) \
11071GEN_HANDLER_E(name, 0x3F, op1, 0x00 | op2, mask, PPC_NONE, PPC2_DFP), \
11072GEN_HANDLER_E(name, 0x3F, op1, 0x08 | op2, mask, PPC_NONE, PPC2_DFP), \
11073GEN_HANDLER_E(name, 0x3F, op1, 0x10 | op2, mask, PPC_NONE, PPC2_DFP), \
11074GEN_HANDLER_E(name, 0x3F, op1, 0x18 | op2, mask, PPC_NONE, PPC2_DFP)
11075
11076#define GEN_DFP_T_A_B_Rc(name, op1, op2) \
11077_GEN_DFP_LONG(name, op1, op2, 0x00000000)
11078
11079#define GEN_DFP_Tp_Ap_Bp_Rc(name, op1, op2) \
11080_GEN_DFP_QUAD(name, op1, op2, 0x00210800)
11081
11082#define GEN_DFP_Tp_A_Bp_Rc(name, op1, op2) \
11083_GEN_DFP_QUAD(name, op1, op2, 0x00200800)
11084
11085#define GEN_DFP_T_B_Rc(name, op1, op2) \
11086_GEN_DFP_LONG(name, op1, op2, 0x001F0000)
11087
11088#define GEN_DFP_Tp_Bp_Rc(name, op1, op2) \
11089_GEN_DFP_QUAD(name, op1, op2, 0x003F0800)
11090
11091#define GEN_DFP_Tp_B_Rc(name, op1, op2) \
11092_GEN_DFP_QUAD(name, op1, op2, 0x003F0000)
11093
11094#define GEN_DFP_T_Bp_Rc(name, op1, op2) \
11095_GEN_DFP_QUAD(name, op1, op2, 0x001F0800)
11096
11097#define GEN_DFP_BF_A_B(name, op1, op2) \
11098_GEN_DFP_LONG(name, op1, op2, 0x00000001)
11099
11100#define GEN_DFP_BF_Ap_Bp(name, op1, op2) \
11101_GEN_DFP_QUAD(name, op1, op2, 0x00610801)
11102
11103#define GEN_DFP_BF_A_Bp(name, op1, op2) \
11104_GEN_DFP_QUAD(name, op1, op2, 0x00600801)
11105
11106#define GEN_DFP_BF_A_DCM(name, op1, op2) \
11107_GEN_DFP_LONGx2(name, op1, op2, 0x00600001)
11108
11109#define GEN_DFP_BF_Ap_DCM(name, op1, op2) \
11110_GEN_DFP_QUADx2(name, op1, op2, 0x00610001)
11111
11112#define GEN_DFP_T_A_B_RMC_Rc(name, op1, op2) \
11113_GEN_DFP_LONGx4(name, op1, op2, 0x00000000)
11114
11115#define GEN_DFP_Tp_Ap_Bp_RMC_Rc(name, op1, op2) \
11116_GEN_DFP_QUADx4(name, op1, op2, 0x02010800)
11117
11118#define GEN_DFP_Tp_A_Bp_RMC_Rc(name, op1, op2) \
11119_GEN_DFP_QUADx4(name, op1, op2, 0x02000800)
11120
11121#define GEN_DFP_TE_T_B_RMC_Rc(name, op1, op2) \
11122_GEN_DFP_LONGx4(name, op1, op2, 0x00000000)
11123
11124#define GEN_DFP_TE_Tp_Bp_RMC_Rc(name, op1, op2) \
11125_GEN_DFP_QUADx4(name, op1, op2, 0x00200800)
11126
11127#define GEN_DFP_R_T_B_RMC_Rc(name, op1, op2) \
11128_GEN_DFP_LONGx4(name, op1, op2, 0x001E0000)
11129
11130#define GEN_DFP_R_Tp_Bp_RMC_Rc(name, op1, op2) \
11131_GEN_DFP_QUADx4(name, op1, op2, 0x003E0800)
11132
11133#define GEN_DFP_SP_T_B_Rc(name, op1, op2) \
11134_GEN_DFP_LONG(name, op1, op2, 0x00070000)
11135
11136#define GEN_DFP_SP_Tp_Bp_Rc(name, op1, op2) \
11137_GEN_DFP_QUAD(name, op1, op2, 0x00270800)
11138
11139#define GEN_DFP_S_T_B_Rc(name, op1, op2) \
11140_GEN_DFP_LONG(name, op1, op2, 0x000F0000)
11141
11142#define GEN_DFP_S_Tp_Bp_Rc(name, op1, op2) \
11143_GEN_DFP_QUAD(name, op1, op2, 0x002F0800)
11144
11145#define GEN_DFP_T_A_SH_Rc(name, op1, op2) \
11146_GEN_DFP_LONGx2(name, op1, op2, 0x00000000)
11147
11148#define GEN_DFP_Tp_Ap_SH_Rc(name, op1, op2) \
11149_GEN_DFP_QUADx2(name, op1, op2, 0x00210000)
11150
11151GEN_DFP_T_A_B_Rc(dadd, 0x02, 0x00),
11152GEN_DFP_Tp_Ap_Bp_Rc(daddq, 0x02, 0x00),
11153GEN_DFP_T_A_B_Rc(dsub, 0x02, 0x10),
11154GEN_DFP_Tp_Ap_Bp_Rc(dsubq, 0x02, 0x10),
11155GEN_DFP_T_A_B_Rc(dmul, 0x02, 0x01),
11156GEN_DFP_Tp_Ap_Bp_Rc(dmulq, 0x02, 0x01),
11157GEN_DFP_T_A_B_Rc(ddiv, 0x02, 0x11),
11158GEN_DFP_Tp_Ap_Bp_Rc(ddivq, 0x02, 0x11),
11159GEN_DFP_BF_A_B(dcmpu, 0x02, 0x14),
11160GEN_DFP_BF_Ap_Bp(dcmpuq, 0x02, 0x14),
11161GEN_DFP_BF_A_B(dcmpo, 0x02, 0x04),
11162GEN_DFP_BF_Ap_Bp(dcmpoq, 0x02, 0x04),
11163GEN_DFP_BF_A_DCM(dtstdc, 0x02, 0x06),
11164GEN_DFP_BF_Ap_DCM(dtstdcq, 0x02, 0x06),
11165GEN_DFP_BF_A_DCM(dtstdg, 0x02, 0x07),
11166GEN_DFP_BF_Ap_DCM(dtstdgq, 0x02, 0x07),
11167GEN_DFP_BF_A_B(dtstex, 0x02, 0x05),
11168GEN_DFP_BF_Ap_Bp(dtstexq, 0x02, 0x05),
11169GEN_DFP_BF_A_B(dtstsf, 0x02, 0x15),
11170GEN_DFP_BF_A_Bp(dtstsfq, 0x02, 0x15),
11171GEN_DFP_TE_T_B_RMC_Rc(dquai, 0x03, 0x02),
11172GEN_DFP_TE_Tp_Bp_RMC_Rc(dquaiq, 0x03, 0x02),
11173GEN_DFP_T_A_B_RMC_Rc(dqua, 0x03, 0x00),
11174GEN_DFP_Tp_Ap_Bp_RMC_Rc(dquaq, 0x03, 0x00),
11175GEN_DFP_T_A_B_RMC_Rc(drrnd, 0x03, 0x01),
11176GEN_DFP_Tp_A_Bp_RMC_Rc(drrndq, 0x03, 0x01),
11177GEN_DFP_R_T_B_RMC_Rc(drintx, 0x03, 0x03),
11178GEN_DFP_R_Tp_Bp_RMC_Rc(drintxq, 0x03, 0x03),
11179GEN_DFP_R_T_B_RMC_Rc(drintn, 0x03, 0x07),
11180GEN_DFP_R_Tp_Bp_RMC_Rc(drintnq, 0x03, 0x07),
11181GEN_DFP_T_B_Rc(dctdp, 0x02, 0x08),
11182GEN_DFP_Tp_B_Rc(dctqpq, 0x02, 0x08),
11183GEN_DFP_T_B_Rc(drsp, 0x02, 0x18),
11184GEN_DFP_Tp_Bp_Rc(drdpq, 0x02, 0x18),
11185GEN_DFP_T_B_Rc(dcffix, 0x02, 0x19),
11186GEN_DFP_Tp_B_Rc(dcffixq, 0x02, 0x19),
11187GEN_DFP_T_B_Rc(dctfix, 0x02, 0x09),
11188GEN_DFP_T_Bp_Rc(dctfixq, 0x02, 0x09),
11189GEN_DFP_SP_T_B_Rc(ddedpd, 0x02, 0x0a),
11190GEN_DFP_SP_Tp_Bp_Rc(ddedpdq, 0x02, 0x0a),
11191GEN_DFP_S_T_B_Rc(denbcd, 0x02, 0x1a),
11192GEN_DFP_S_Tp_Bp_Rc(denbcdq, 0x02, 0x1a),
11193GEN_DFP_T_B_Rc(dxex, 0x02, 0x0b),
11194GEN_DFP_T_Bp_Rc(dxexq, 0x02, 0x0b),
11195GEN_DFP_T_A_B_Rc(diex, 0x02, 0x1b),
11196GEN_DFP_Tp_A_Bp_Rc(diexq, 0x02, 0x1b),
11197GEN_DFP_T_A_SH_Rc(dscli, 0x02, 0x02),
11198GEN_DFP_Tp_Ap_SH_Rc(dscliq, 0x02, 0x02),
11199GEN_DFP_T_A_SH_Rc(dscri, 0x02, 0x03),
11200GEN_DFP_Tp_Ap_SH_Rc(dscriq, 0x02, 0x03),
11201
11202#undef GEN_SPE
11203#define GEN_SPE(name0, name1, opc2, opc3, inval0, inval1, type) \
11204 GEN_OPCODE_DUAL(name0##_##name1, 0x04, opc2, opc3, inval0, inval1, type, PPC_NONE)
11205GEN_SPE(evaddw, speundef, 0x00, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
11206GEN_SPE(evaddiw, speundef, 0x01, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
11207GEN_SPE(evsubfw, speundef, 0x02, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
11208GEN_SPE(evsubifw, speundef, 0x03, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
11209GEN_SPE(evabs, evneg, 0x04, 0x08, 0x0000F800, 0x0000F800, PPC_SPE),
11210GEN_SPE(evextsb, evextsh, 0x05, 0x08, 0x0000F800, 0x0000F800, PPC_SPE),
11211GEN_SPE(evrndw, evcntlzw, 0x06, 0x08, 0x0000F800, 0x0000F800, PPC_SPE),
11212GEN_SPE(evcntlsw, brinc, 0x07, 0x08, 0x0000F800, 0x00000000, PPC_SPE),
11213GEN_SPE(evmra, speundef, 0x02, 0x13, 0x0000F800, 0xFFFFFFFF, PPC_SPE),
11214GEN_SPE(speundef, evand, 0x08, 0x08, 0xFFFFFFFF, 0x00000000, PPC_SPE),
11215GEN_SPE(evandc, speundef, 0x09, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
11216GEN_SPE(evxor, evor, 0x0B, 0x08, 0x00000000, 0x00000000, PPC_SPE),
11217GEN_SPE(evnor, eveqv, 0x0C, 0x08, 0x00000000, 0x00000000, PPC_SPE),
11218GEN_SPE(evmwumi, evmwsmi, 0x0C, 0x11, 0x00000000, 0x00000000, PPC_SPE),
11219GEN_SPE(evmwumia, evmwsmia, 0x1C, 0x11, 0x00000000, 0x00000000, PPC_SPE),
11220GEN_SPE(evmwumiaa, evmwsmiaa, 0x0C, 0x15, 0x00000000, 0x00000000, PPC_SPE),
11221GEN_SPE(speundef, evorc, 0x0D, 0x08, 0xFFFFFFFF, 0x00000000, PPC_SPE),
11222GEN_SPE(evnand, speundef, 0x0F, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
11223GEN_SPE(evsrwu, evsrws, 0x10, 0x08, 0x00000000, 0x00000000, PPC_SPE),
11224GEN_SPE(evsrwiu, evsrwis, 0x11, 0x08, 0x00000000, 0x00000000, PPC_SPE),
11225GEN_SPE(evslw, speundef, 0x12, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
11226GEN_SPE(evslwi, speundef, 0x13, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
11227GEN_SPE(evrlw, evsplati, 0x14, 0x08, 0x00000000, 0x0000F800, PPC_SPE),
11228GEN_SPE(evrlwi, evsplatfi, 0x15, 0x08, 0x00000000, 0x0000F800, PPC_SPE),
11229GEN_SPE(evmergehi, evmergelo, 0x16, 0x08, 0x00000000, 0x00000000, PPC_SPE),
11230GEN_SPE(evmergehilo, evmergelohi, 0x17, 0x08, 0x00000000, 0x00000000, PPC_SPE),
11231GEN_SPE(evcmpgtu, evcmpgts, 0x18, 0x08, 0x00600000, 0x00600000, PPC_SPE),
11232GEN_SPE(evcmpltu, evcmplts, 0x19, 0x08, 0x00600000, 0x00600000, PPC_SPE),
11233GEN_SPE(evcmpeq, speundef, 0x1A, 0x08, 0x00600000, 0xFFFFFFFF, PPC_SPE),
11234
11235GEN_SPE(evfsadd, evfssub, 0x00, 0x0A, 0x00000000, 0x00000000, PPC_SPE_SINGLE),
11236GEN_SPE(evfsabs, evfsnabs, 0x02, 0x0A, 0x0000F800, 0x0000F800, PPC_SPE_SINGLE),
11237GEN_SPE(evfsneg, speundef, 0x03, 0x0A, 0x0000F800, 0xFFFFFFFF, PPC_SPE_SINGLE),
11238GEN_SPE(evfsmul, evfsdiv, 0x04, 0x0A, 0x00000000, 0x00000000, PPC_SPE_SINGLE),
11239GEN_SPE(evfscmpgt, evfscmplt, 0x06, 0x0A, 0x00600000, 0x00600000, PPC_SPE_SINGLE),
11240GEN_SPE(evfscmpeq, speundef, 0x07, 0x0A, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE),
11241GEN_SPE(evfscfui, evfscfsi, 0x08, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
11242GEN_SPE(evfscfuf, evfscfsf, 0x09, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
11243GEN_SPE(evfsctui, evfsctsi, 0x0A, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
11244GEN_SPE(evfsctuf, evfsctsf, 0x0B, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
11245GEN_SPE(evfsctuiz, speundef, 0x0C, 0x0A, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE),
11246GEN_SPE(evfsctsiz, speundef, 0x0D, 0x0A, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE),
11247GEN_SPE(evfststgt, evfststlt, 0x0E, 0x0A, 0x00600000, 0x00600000, PPC_SPE_SINGLE),
11248GEN_SPE(evfststeq, speundef, 0x0F, 0x0A, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE),
11249
11250GEN_SPE(efsadd, efssub, 0x00, 0x0B, 0x00000000, 0x00000000, PPC_SPE_SINGLE),
11251GEN_SPE(efsabs, efsnabs, 0x02, 0x0B, 0x0000F800, 0x0000F800, PPC_SPE_SINGLE),
11252GEN_SPE(efsneg, speundef, 0x03, 0x0B, 0x0000F800, 0xFFFFFFFF, PPC_SPE_SINGLE),
11253GEN_SPE(efsmul, efsdiv, 0x04, 0x0B, 0x00000000, 0x00000000, PPC_SPE_SINGLE),
11254GEN_SPE(efscmpgt, efscmplt, 0x06, 0x0B, 0x00600000, 0x00600000, PPC_SPE_SINGLE),
11255GEN_SPE(efscmpeq, efscfd, 0x07, 0x0B, 0x00600000, 0x00180000, PPC_SPE_SINGLE),
11256GEN_SPE(efscfui, efscfsi, 0x08, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
11257GEN_SPE(efscfuf, efscfsf, 0x09, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
11258GEN_SPE(efsctui, efsctsi, 0x0A, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
11259GEN_SPE(efsctuf, efsctsf, 0x0B, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
11260GEN_SPE(efsctuiz, speundef, 0x0C, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE),
11261GEN_SPE(efsctsiz, speundef, 0x0D, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE),
11262GEN_SPE(efststgt, efststlt, 0x0E, 0x0B, 0x00600000, 0x00600000, PPC_SPE_SINGLE),
11263GEN_SPE(efststeq, speundef, 0x0F, 0x0B, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE),
11264
11265GEN_SPE(efdadd, efdsub, 0x10, 0x0B, 0x00000000, 0x00000000, PPC_SPE_DOUBLE),
11266GEN_SPE(efdcfuid, efdcfsid, 0x11, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
11267GEN_SPE(efdabs, efdnabs, 0x12, 0x0B, 0x0000F800, 0x0000F800, PPC_SPE_DOUBLE),
11268GEN_SPE(efdneg, speundef, 0x13, 0x0B, 0x0000F800, 0xFFFFFFFF, PPC_SPE_DOUBLE),
11269GEN_SPE(efdmul, efddiv, 0x14, 0x0B, 0x00000000, 0x00000000, PPC_SPE_DOUBLE),
11270GEN_SPE(efdctuidz, efdctsidz, 0x15, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
11271GEN_SPE(efdcmpgt, efdcmplt, 0x16, 0x0B, 0x00600000, 0x00600000, PPC_SPE_DOUBLE),
11272GEN_SPE(efdcmpeq, efdcfs, 0x17, 0x0B, 0x00600000, 0x00180000, PPC_SPE_DOUBLE),
11273GEN_SPE(efdcfui, efdcfsi, 0x18, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
11274GEN_SPE(efdcfuf, efdcfsf, 0x19, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
11275GEN_SPE(efdctui, efdctsi, 0x1A, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
11276GEN_SPE(efdctuf, efdctsf, 0x1B, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
11277GEN_SPE(efdctuiz, speundef, 0x1C, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_DOUBLE),
11278GEN_SPE(efdctsiz, speundef, 0x1D, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_DOUBLE),
11279GEN_SPE(efdtstgt, efdtstlt, 0x1E, 0x0B, 0x00600000, 0x00600000, PPC_SPE_DOUBLE),
11280GEN_SPE(efdtsteq, speundef, 0x1F, 0x0B, 0x00600000, 0xFFFFFFFF, PPC_SPE_DOUBLE),
11281
11282#undef GEN_SPEOP_LDST
11283#define GEN_SPEOP_LDST(name, opc2, sh) \
11284GEN_HANDLER(name, 0x04, opc2, 0x0C, 0x00000000, PPC_SPE)
11285GEN_SPEOP_LDST(evldd, 0x00, 3),
11286GEN_SPEOP_LDST(evldw, 0x01, 3),
11287GEN_SPEOP_LDST(evldh, 0x02, 3),
11288GEN_SPEOP_LDST(evlhhesplat, 0x04, 1),
11289GEN_SPEOP_LDST(evlhhousplat, 0x06, 1),
11290GEN_SPEOP_LDST(evlhhossplat, 0x07, 1),
11291GEN_SPEOP_LDST(evlwhe, 0x08, 2),
11292GEN_SPEOP_LDST(evlwhou, 0x0A, 2),
11293GEN_SPEOP_LDST(evlwhos, 0x0B, 2),
11294GEN_SPEOP_LDST(evlwwsplat, 0x0C, 2),
11295GEN_SPEOP_LDST(evlwhsplat, 0x0E, 2),
11296
11297GEN_SPEOP_LDST(evstdd, 0x10, 3),
11298GEN_SPEOP_LDST(evstdw, 0x11, 3),
11299GEN_SPEOP_LDST(evstdh, 0x12, 3),
11300GEN_SPEOP_LDST(evstwhe, 0x18, 2),
11301GEN_SPEOP_LDST(evstwho, 0x1A, 2),
11302GEN_SPEOP_LDST(evstwwe, 0x1C, 2),
11303GEN_SPEOP_LDST(evstwwo, 0x1E, 2),
11304
11305GEN_HANDLER2_E(tbegin, "tbegin", 0x1F, 0x0E, 0x14, 0x01DFF800, \
11306 PPC_NONE, PPC2_TM),
11307GEN_HANDLER2_E(tend, "tend", 0x1F, 0x0E, 0x15, 0x01FFF800, \
11308 PPC_NONE, PPC2_TM),
11309GEN_HANDLER2_E(tabort, "tabort", 0x1F, 0x0E, 0x1C, 0x03E0F800, \
11310 PPC_NONE, PPC2_TM),
11311GEN_HANDLER2_E(tabortwc, "tabortwc", 0x1F, 0x0E, 0x18, 0x00000000, \
11312 PPC_NONE, PPC2_TM),
11313GEN_HANDLER2_E(tabortwci, "tabortwci", 0x1F, 0x0E, 0x1A, 0x00000000, \
11314 PPC_NONE, PPC2_TM),
11315GEN_HANDLER2_E(tabortdc, "tabortdc", 0x1F, 0x0E, 0x19, 0x00000000, \
11316 PPC_NONE, PPC2_TM),
11317GEN_HANDLER2_E(tabortdci, "tabortdci", 0x1F, 0x0E, 0x1B, 0x00000000, \
11318 PPC_NONE, PPC2_TM),
11319GEN_HANDLER2_E(tsr, "tsr", 0x1F, 0x0E, 0x17, 0x03DFF800, \
11320 PPC_NONE, PPC2_TM),
11321GEN_HANDLER2_E(tcheck, "tcheck", 0x1F, 0x0E, 0x16, 0x007FF800, \
11322 PPC_NONE, PPC2_TM),
11323GEN_HANDLER2_E(treclaim, "treclaim", 0x1F, 0x0E, 0x1D, 0x03E0F800, \
11324 PPC_NONE, PPC2_TM),
11325GEN_HANDLER2_E(trechkpt, "trechkpt", 0x1F, 0x0E, 0x1F, 0x03FFF800, \
11326 PPC_NONE, PPC2_TM),
11327};
11328
11329#include "helper_regs.h"
11330#include "translate_init.c"
11331
11332
11333
11334void ppc_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
11335 int flags)
11336{
11337#define RGPL 4
11338#define RFPL 4
11339
11340 PowerPCCPU *cpu = POWERPC_CPU(cs);
11341 CPUPPCState *env = &cpu->env;
11342 int i;
11343
11344 cpu_fprintf(f, "NIP " TARGET_FMT_lx " LR " TARGET_FMT_lx " CTR "
11345 TARGET_FMT_lx " XER " TARGET_FMT_lx " CPU#%d\n",
11346 env->nip, env->lr, env->ctr, cpu_read_xer(env),
11347 cs->cpu_index);
11348 cpu_fprintf(f, "MSR " TARGET_FMT_lx " HID0 " TARGET_FMT_lx " HF "
11349 TARGET_FMT_lx " iidx %d didx %d\n",
11350 env->msr, env->spr[SPR_HID0],
11351 env->hflags, env->immu_idx, env->dmmu_idx);
11352#if !defined(NO_TIMER_DUMP)
11353 cpu_fprintf(f, "TB %08" PRIu32 " %08" PRIu64
11354#if !defined(CONFIG_USER_ONLY)
11355 " DECR %08" PRIu32
11356#endif
11357 "\n",
11358 cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
11359#if !defined(CONFIG_USER_ONLY)
11360 , cpu_ppc_load_decr(env)
11361#endif
11362 );
11363#endif
11364 for (i = 0; i < 32; i++) {
11365 if ((i & (RGPL - 1)) == 0)
11366 cpu_fprintf(f, "GPR%02d", i);
11367 cpu_fprintf(f, " %016" PRIx64, ppc_dump_gpr(env, i));
11368 if ((i & (RGPL - 1)) == (RGPL - 1))
11369 cpu_fprintf(f, "\n");
11370 }
11371 cpu_fprintf(f, "CR ");
11372 for (i = 0; i < 8; i++)
11373 cpu_fprintf(f, "%01x", env->crf[i]);
11374 cpu_fprintf(f, " [");
11375 for (i = 0; i < 8; i++) {
11376 char a = '-';
11377 if (env->crf[i] & 0x08)
11378 a = 'L';
11379 else if (env->crf[i] & 0x04)
11380 a = 'G';
11381 else if (env->crf[i] & 0x02)
11382 a = 'E';
11383 cpu_fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
11384 }
11385 cpu_fprintf(f, " ] RES " TARGET_FMT_lx "\n",
11386 env->reserve_addr);
11387 for (i = 0; i < 32; i++) {
11388 if ((i & (RFPL - 1)) == 0)
11389 cpu_fprintf(f, "FPR%02d", i);
11390 cpu_fprintf(f, " %016" PRIx64, *((uint64_t *)&env->fpr[i]));
11391 if ((i & (RFPL - 1)) == (RFPL - 1))
11392 cpu_fprintf(f, "\n");
11393 }
11394 cpu_fprintf(f, "FPSCR " TARGET_FMT_lx "\n", env->fpscr);
11395#if !defined(CONFIG_USER_ONLY)
11396 cpu_fprintf(f, " SRR0 " TARGET_FMT_lx " SRR1 " TARGET_FMT_lx
11397 " PVR " TARGET_FMT_lx " VRSAVE " TARGET_FMT_lx "\n",
11398 env->spr[SPR_SRR0], env->spr[SPR_SRR1],
11399 env->spr[SPR_PVR], env->spr[SPR_VRSAVE]);
11400
11401 cpu_fprintf(f, "SPRG0 " TARGET_FMT_lx " SPRG1 " TARGET_FMT_lx
11402 " SPRG2 " TARGET_FMT_lx " SPRG3 " TARGET_FMT_lx "\n",
11403 env->spr[SPR_SPRG0], env->spr[SPR_SPRG1],
11404 env->spr[SPR_SPRG2], env->spr[SPR_SPRG3]);
11405
11406 cpu_fprintf(f, "SPRG4 " TARGET_FMT_lx " SPRG5 " TARGET_FMT_lx
11407 " SPRG6 " TARGET_FMT_lx " SPRG7 " TARGET_FMT_lx "\n",
11408 env->spr[SPR_SPRG4], env->spr[SPR_SPRG5],
11409 env->spr[SPR_SPRG6], env->spr[SPR_SPRG7]);
11410
11411#if defined(TARGET_PPC64)
11412 if (env->excp_model == POWERPC_EXCP_POWER7 ||
11413 env->excp_model == POWERPC_EXCP_POWER8) {
11414 cpu_fprintf(f, "HSRR0 " TARGET_FMT_lx " HSRR1 " TARGET_FMT_lx "\n",
11415 env->spr[SPR_HSRR0], env->spr[SPR_HSRR1]);
11416 }
11417#endif
11418 if (env->excp_model == POWERPC_EXCP_BOOKE) {
11419 cpu_fprintf(f, "CSRR0 " TARGET_FMT_lx " CSRR1 " TARGET_FMT_lx
11420 " MCSRR0 " TARGET_FMT_lx " MCSRR1 " TARGET_FMT_lx "\n",
11421 env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1],
11422 env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1]);
11423
11424 cpu_fprintf(f, " TCR " TARGET_FMT_lx " TSR " TARGET_FMT_lx
11425 " ESR " TARGET_FMT_lx " DEAR " TARGET_FMT_lx "\n",
11426 env->spr[SPR_BOOKE_TCR], env->spr[SPR_BOOKE_TSR],
11427 env->spr[SPR_BOOKE_ESR], env->spr[SPR_BOOKE_DEAR]);
11428
11429 cpu_fprintf(f, " PIR " TARGET_FMT_lx " DECAR " TARGET_FMT_lx
11430 " IVPR " TARGET_FMT_lx " EPCR " TARGET_FMT_lx "\n",
11431 env->spr[SPR_BOOKE_PIR], env->spr[SPR_BOOKE_DECAR],
11432 env->spr[SPR_BOOKE_IVPR], env->spr[SPR_BOOKE_EPCR]);
11433
11434 cpu_fprintf(f, " MCSR " TARGET_FMT_lx " SPRG8 " TARGET_FMT_lx
11435 " EPR " TARGET_FMT_lx "\n",
11436 env->spr[SPR_BOOKE_MCSR], env->spr[SPR_BOOKE_SPRG8],
11437 env->spr[SPR_BOOKE_EPR]);
11438
11439
11440 cpu_fprintf(f, " MCAR " TARGET_FMT_lx " PID1 " TARGET_FMT_lx
11441 " PID2 " TARGET_FMT_lx " SVR " TARGET_FMT_lx "\n",
11442 env->spr[SPR_Exxx_MCAR], env->spr[SPR_BOOKE_PID1],
11443 env->spr[SPR_BOOKE_PID2], env->spr[SPR_E500_SVR]);
11444
11445
11446
11447
11448
11449 }
11450
11451#if defined(TARGET_PPC64)
11452 if (env->flags & POWERPC_FLAG_CFAR) {
11453 cpu_fprintf(f, " CFAR " TARGET_FMT_lx"\n", env->cfar);
11454 }
11455#endif
11456
11457 switch (env->mmu_model) {
11458 case POWERPC_MMU_32B:
11459 case POWERPC_MMU_601:
11460 case POWERPC_MMU_SOFT_6xx:
11461 case POWERPC_MMU_SOFT_74xx:
11462#if defined(TARGET_PPC64)
11463 case POWERPC_MMU_64B:
11464 case POWERPC_MMU_2_03:
11465 case POWERPC_MMU_2_06:
11466 case POWERPC_MMU_2_06a:
11467 case POWERPC_MMU_2_07:
11468 case POWERPC_MMU_2_07a:
11469#endif
11470 cpu_fprintf(f, " SDR1 " TARGET_FMT_lx " DAR " TARGET_FMT_lx
11471 " DSISR " TARGET_FMT_lx "\n", env->spr[SPR_SDR1],
11472 env->spr[SPR_DAR], env->spr[SPR_DSISR]);
11473 break;
11474 case POWERPC_MMU_BOOKE206:
11475 cpu_fprintf(f, " MAS0 " TARGET_FMT_lx " MAS1 " TARGET_FMT_lx
11476 " MAS2 " TARGET_FMT_lx " MAS3 " TARGET_FMT_lx "\n",
11477 env->spr[SPR_BOOKE_MAS0], env->spr[SPR_BOOKE_MAS1],
11478 env->spr[SPR_BOOKE_MAS2], env->spr[SPR_BOOKE_MAS3]);
11479
11480 cpu_fprintf(f, " MAS4 " TARGET_FMT_lx " MAS6 " TARGET_FMT_lx
11481 " MAS7 " TARGET_FMT_lx " PID " TARGET_FMT_lx "\n",
11482 env->spr[SPR_BOOKE_MAS4], env->spr[SPR_BOOKE_MAS6],
11483 env->spr[SPR_BOOKE_MAS7], env->spr[SPR_BOOKE_PID]);
11484
11485 cpu_fprintf(f, "MMUCFG " TARGET_FMT_lx " TLB0CFG " TARGET_FMT_lx
11486 " TLB1CFG " TARGET_FMT_lx "\n",
11487 env->spr[SPR_MMUCFG], env->spr[SPR_BOOKE_TLB0CFG],
11488 env->spr[SPR_BOOKE_TLB1CFG]);
11489 break;
11490 default:
11491 break;
11492 }
11493#endif
11494
11495#undef RGPL
11496#undef RFPL
11497}
11498
11499void ppc_cpu_dump_statistics(CPUState *cs, FILE*f,
11500 fprintf_function cpu_fprintf, int flags)
11501{
11502#if defined(DO_PPC_STATISTICS)
11503 PowerPCCPU *cpu = POWERPC_CPU(cs);
11504 opc_handler_t **t1, **t2, **t3, *handler;
11505 int op1, op2, op3;
11506
11507 t1 = cpu->env.opcodes;
11508 for (op1 = 0; op1 < 64; op1++) {
11509 handler = t1[op1];
11510 if (is_indirect_opcode(handler)) {
11511 t2 = ind_table(handler);
11512 for (op2 = 0; op2 < 32; op2++) {
11513 handler = t2[op2];
11514 if (is_indirect_opcode(handler)) {
11515 t3 = ind_table(handler);
11516 for (op3 = 0; op3 < 32; op3++) {
11517 handler = t3[op3];
11518 if (handler->count == 0)
11519 continue;
11520 cpu_fprintf(f, "%02x %02x %02x (%02x %04d) %16s: "
11521 "%016" PRIx64 " %" PRId64 "\n",
11522 op1, op2, op3, op1, (op3 << 5) | op2,
11523 handler->oname,
11524 handler->count, handler->count);
11525 }
11526 } else {
11527 if (handler->count == 0)
11528 continue;
11529 cpu_fprintf(f, "%02x %02x (%02x %04d) %16s: "
11530 "%016" PRIx64 " %" PRId64 "\n",
11531 op1, op2, op1, op2, handler->oname,
11532 handler->count, handler->count);
11533 }
11534 }
11535 } else {
11536 if (handler->count == 0)
11537 continue;
11538 cpu_fprintf(f, "%02x (%02x ) %16s: %016" PRIx64
11539 " %" PRId64 "\n",
11540 op1, op1, handler->oname,
11541 handler->count, handler->count);
11542 }
11543 }
11544#endif
11545}
11546
11547
11548void gen_intermediate_code(CPUPPCState *env, struct TranslationBlock *tb)
11549{
11550 PowerPCCPU *cpu = ppc_env_get_cpu(env);
11551 CPUState *cs = CPU(cpu);
11552 DisasContext ctx, *ctxp = &ctx;
11553 opc_handler_t **table, *handler;
11554 target_ulong pc_start;
11555 int num_insns;
11556 int max_insns;
11557
11558 pc_start = tb->pc;
11559 ctx.nip = pc_start;
11560 ctx.tb = tb;
11561 ctx.exception = POWERPC_EXCP_NONE;
11562 ctx.spr_cb = env->spr_cb;
11563 ctx.pr = msr_pr;
11564 ctx.mem_idx = env->dmmu_idx;
11565 ctx.dr = msr_dr;
11566#if !defined(CONFIG_USER_ONLY)
11567 ctx.hv = msr_hv || !env->has_hv_mode;
11568#endif
11569 ctx.insns_flags = env->insns_flags;
11570 ctx.insns_flags2 = env->insns_flags2;
11571 ctx.access_type = -1;
11572 ctx.le_mode = !!(env->hflags & (1 << MSR_LE));
11573 ctx.default_tcg_memop_mask = ctx.le_mode ? MO_LE : MO_BE;
11574#if defined(TARGET_PPC64)
11575 ctx.sf_mode = msr_is_64bit(env, env->msr);
11576 ctx.has_cfar = !!(env->flags & POWERPC_FLAG_CFAR);
11577#endif
11578 if (env->mmu_model == POWERPC_MMU_32B ||
11579 env->mmu_model == POWERPC_MMU_601 ||
11580 (env->mmu_model & POWERPC_MMU_64B))
11581 ctx.lazy_tlb_flush = true;
11582
11583 ctx.fpu_enabled = !!msr_fp;
11584 if ((env->flags & POWERPC_FLAG_SPE) && msr_spe)
11585 ctx.spe_enabled = !!msr_spe;
11586 else
11587 ctx.spe_enabled = false;
11588 if ((env->flags & POWERPC_FLAG_VRE) && msr_vr)
11589 ctx.altivec_enabled = !!msr_vr;
11590 else
11591 ctx.altivec_enabled = false;
11592 if ((env->flags & POWERPC_FLAG_VSX) && msr_vsx) {
11593 ctx.vsx_enabled = !!msr_vsx;
11594 } else {
11595 ctx.vsx_enabled = false;
11596 }
11597#if defined(TARGET_PPC64)
11598 if ((env->flags & POWERPC_FLAG_TM) && msr_tm) {
11599 ctx.tm_enabled = !!msr_tm;
11600 } else {
11601 ctx.tm_enabled = false;
11602 }
11603#endif
11604 if ((env->flags & POWERPC_FLAG_SE) && msr_se)
11605 ctx.singlestep_enabled = CPU_SINGLE_STEP;
11606 else
11607 ctx.singlestep_enabled = 0;
11608 if ((env->flags & POWERPC_FLAG_BE) && msr_be)
11609 ctx.singlestep_enabled |= CPU_BRANCH_STEP;
11610 if (unlikely(cs->singlestep_enabled)) {
11611 ctx.singlestep_enabled |= GDBSTUB_SINGLE_STEP;
11612 }
11613#if defined (DO_SINGLE_STEP) && 0
11614
11615 msr_se = 1;
11616#endif
11617 num_insns = 0;
11618 max_insns = tb->cflags & CF_COUNT_MASK;
11619 if (max_insns == 0) {
11620 max_insns = CF_COUNT_MASK;
11621 }
11622 if (max_insns > TCG_MAX_INSNS) {
11623 max_insns = TCG_MAX_INSNS;
11624 }
11625
11626 gen_tb_start(tb);
11627 tcg_clear_temp_count();
11628
11629 while (ctx.exception == POWERPC_EXCP_NONE && !tcg_op_buf_full()) {
11630 tcg_gen_insn_start(ctx.nip);
11631 num_insns++;
11632
11633 if (unlikely(cpu_breakpoint_test(cs, ctx.nip, BP_ANY))) {
11634 gen_debug_exception(ctxp);
11635
11636
11637
11638
11639 ctx.nip += 4;
11640 break;
11641 }
11642
11643 LOG_DISAS("----------------\n");
11644 LOG_DISAS("nip=" TARGET_FMT_lx " super=%d ir=%d\n",
11645 ctx.nip, ctx.mem_idx, (int)msr_ir);
11646 if (num_insns == max_insns && (tb->cflags & CF_LAST_IO))
11647 gen_io_start();
11648 if (unlikely(need_byteswap(&ctx))) {
11649 ctx.opcode = bswap32(cpu_ldl_code(env, ctx.nip));
11650 } else {
11651 ctx.opcode = cpu_ldl_code(env, ctx.nip);
11652 }
11653 LOG_DISAS("translate opcode %08x (%02x %02x %02x) (%s)\n",
11654 ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
11655 opc3(ctx.opcode), ctx.le_mode ? "little" : "big");
11656 ctx.nip += 4;
11657 table = env->opcodes;
11658 handler = table[opc1(ctx.opcode)];
11659 if (is_indirect_opcode(handler)) {
11660 table = ind_table(handler);
11661 handler = table[opc2(ctx.opcode)];
11662 if (is_indirect_opcode(handler)) {
11663 table = ind_table(handler);
11664 handler = table[opc3(ctx.opcode)];
11665 }
11666 }
11667
11668 if (unlikely(handler->handler == &gen_invalid)) {
11669 qemu_log_mask(LOG_GUEST_ERROR, "invalid/unsupported opcode: "
11670 "%02x - %02x - %02x (%08x) " TARGET_FMT_lx " %d\n",
11671 opc1(ctx.opcode), opc2(ctx.opcode),
11672 opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, (int)msr_ir);
11673 } else {
11674 uint32_t inval;
11675
11676 if (unlikely(handler->type & (PPC_SPE | PPC_SPE_SINGLE | PPC_SPE_DOUBLE) && Rc(ctx.opcode))) {
11677 inval = handler->inval2;
11678 } else {
11679 inval = handler->inval1;
11680 }
11681
11682 if (unlikely((ctx.opcode & inval) != 0)) {
11683 qemu_log_mask(LOG_GUEST_ERROR, "invalid bits: %08x for opcode: "
11684 "%02x - %02x - %02x (%08x) " TARGET_FMT_lx "\n",
11685 ctx.opcode & inval, opc1(ctx.opcode),
11686 opc2(ctx.opcode), opc3(ctx.opcode),
11687 ctx.opcode, ctx.nip - 4);
11688 gen_inval_exception(ctxp, POWERPC_EXCP_INVAL_INVAL);
11689 break;
11690 }
11691 }
11692 (*(handler->handler))(&ctx);
11693#if defined(DO_PPC_STATISTICS)
11694 handler->count++;
11695#endif
11696
11697 if (unlikely(ctx.singlestep_enabled & CPU_SINGLE_STEP &&
11698 (ctx.nip <= 0x100 || ctx.nip > 0xF00) &&
11699 ctx.exception != POWERPC_SYSCALL &&
11700 ctx.exception != POWERPC_EXCP_TRAP &&
11701 ctx.exception != POWERPC_EXCP_BRANCH)) {
11702 gen_exception(ctxp, POWERPC_EXCP_TRACE);
11703 } else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
11704 (cs->singlestep_enabled) ||
11705 singlestep ||
11706 num_insns >= max_insns)) {
11707
11708
11709
11710 break;
11711 }
11712 if (tcg_check_temp_count()) {
11713 fprintf(stderr, "Opcode %02x %02x %02x (%08x) leaked temporaries\n",
11714 opc1(ctx.opcode), opc2(ctx.opcode), opc3(ctx.opcode),
11715 ctx.opcode);
11716 exit(1);
11717 }
11718 }
11719 if (tb->cflags & CF_LAST_IO)
11720 gen_io_end();
11721 if (ctx.exception == POWERPC_EXCP_NONE) {
11722 gen_goto_tb(&ctx, 0, ctx.nip);
11723 } else if (ctx.exception != POWERPC_EXCP_BRANCH) {
11724 if (unlikely(cs->singlestep_enabled)) {
11725 gen_debug_exception(ctxp);
11726 }
11727
11728 tcg_gen_exit_tb(0);
11729 }
11730 gen_tb_end(tb, num_insns);
11731
11732 tb->size = ctx.nip - pc_start;
11733 tb->icount = num_insns;
11734
11735#if defined(DEBUG_DISAS)
11736 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
11737 && qemu_log_in_addr_range(pc_start)) {
11738 int flags;
11739 flags = env->bfd_mach;
11740 flags |= ctx.le_mode << 16;
11741 qemu_log("IN: %s\n", lookup_symbol(pc_start));
11742 log_target_disas(cs, pc_start, ctx.nip - pc_start, flags);
11743 qemu_log("\n");
11744 }
11745#endif
11746}
11747
11748void restore_state_to_opc(CPUPPCState *env, TranslationBlock *tb,
11749 target_ulong *data)
11750{
11751 env->nip = data[0];
11752}
11753