4 * Altivec/VMX translation
7 /*** Altivec vector extension ***/
8 /* Altivec registers moves */
10 static inline TCGv_ptr
gen_avr_ptr(int reg
)
12 TCGv_ptr r
= tcg_temp_new_ptr();
13 tcg_gen_addi_ptr(r
, cpu_env
, offsetof(CPUPPCState
, avr
[reg
]));
17 #define GEN_VR_LDX(name, opc2, opc3) \
18 static void glue(gen_, name)(DisasContext *ctx) \
21 if (unlikely(!ctx->altivec_enabled)) { \
22 gen_exception(ctx, POWERPC_EXCP_VPU); \
25 gen_set_access_type(ctx, ACCESS_INT); \
26 EA = tcg_temp_new(); \
27 gen_addr_reg_index(ctx, EA); \
28 tcg_gen_andi_tl(EA, EA, ~0xf); \
29 /* We only need to swap high and low halves. gen_qemu_ld64_i64 does \
30 necessary 64-bit byteswap already. */ \
32 gen_qemu_ld64_i64(ctx, cpu_avrl[rD(ctx->opcode)], EA); \
33 tcg_gen_addi_tl(EA, EA, 8); \
34 gen_qemu_ld64_i64(ctx, cpu_avrh[rD(ctx->opcode)], EA); \
36 gen_qemu_ld64_i64(ctx, cpu_avrh[rD(ctx->opcode)], EA); \
37 tcg_gen_addi_tl(EA, EA, 8); \
38 gen_qemu_ld64_i64(ctx, cpu_avrl[rD(ctx->opcode)], EA); \
43 #define GEN_VR_STX(name, opc2, opc3) \
44 static void gen_st##name(DisasContext *ctx) \
47 if (unlikely(!ctx->altivec_enabled)) { \
48 gen_exception(ctx, POWERPC_EXCP_VPU); \
51 gen_set_access_type(ctx, ACCESS_INT); \
52 EA = tcg_temp_new(); \
53 gen_addr_reg_index(ctx, EA); \
54 tcg_gen_andi_tl(EA, EA, ~0xf); \
55 /* We only need to swap high and low halves. gen_qemu_st64_i64 does \
56 necessary 64-bit byteswap already. */ \
58 gen_qemu_st64_i64(ctx, cpu_avrl[rD(ctx->opcode)], EA); \
59 tcg_gen_addi_tl(EA, EA, 8); \
60 gen_qemu_st64_i64(ctx, cpu_avrh[rD(ctx->opcode)], EA); \
62 gen_qemu_st64_i64(ctx, cpu_avrh[rD(ctx->opcode)], EA); \
63 tcg_gen_addi_tl(EA, EA, 8); \
64 gen_qemu_st64_i64(ctx, cpu_avrl[rD(ctx->opcode)], EA); \
69 #define GEN_VR_LVE(name, opc2, opc3, size) \
70 static void gen_lve##name(DisasContext *ctx) \
74 if (unlikely(!ctx->altivec_enabled)) { \
75 gen_exception(ctx, POWERPC_EXCP_VPU); \
78 gen_set_access_type(ctx, ACCESS_INT); \
79 EA = tcg_temp_new(); \
80 gen_addr_reg_index(ctx, EA); \
82 tcg_gen_andi_tl(EA, EA, ~(size - 1)); \
84 rs = gen_avr_ptr(rS(ctx->opcode)); \
85 gen_helper_lve##name(cpu_env, rs, EA); \
87 tcg_temp_free_ptr(rs); \
90 #define GEN_VR_STVE(name, opc2, opc3, size) \
91 static void gen_stve##name(DisasContext *ctx) \
95 if (unlikely(!ctx->altivec_enabled)) { \
96 gen_exception(ctx, POWERPC_EXCP_VPU); \
99 gen_set_access_type(ctx, ACCESS_INT); \
100 EA = tcg_temp_new(); \
101 gen_addr_reg_index(ctx, EA); \
103 tcg_gen_andi_tl(EA, EA, ~(size - 1)); \
105 rs = gen_avr_ptr(rS(ctx->opcode)); \
106 gen_helper_stve##name(cpu_env, rs, EA); \
108 tcg_temp_free_ptr(rs); \
111 GEN_VR_LDX(lvx
, 0x07, 0x03);
112 /* As we don't emulate the cache, lvxl is stricly equivalent to lvx */
113 GEN_VR_LDX(lvxl
, 0x07, 0x0B);
115 GEN_VR_LVE(bx
, 0x07, 0x00, 1);
116 GEN_VR_LVE(hx
, 0x07, 0x01, 2);
117 GEN_VR_LVE(wx
, 0x07, 0x02, 4);
119 GEN_VR_STX(svx
, 0x07, 0x07);
120 /* As we don't emulate the cache, stvxl is stricly equivalent to stvx */
121 GEN_VR_STX(svxl
, 0x07, 0x0F);
123 GEN_VR_STVE(bx
, 0x07, 0x04, 1);
124 GEN_VR_STVE(hx
, 0x07, 0x05, 2);
125 GEN_VR_STVE(wx
, 0x07, 0x06, 4);
127 static void gen_lvsl(DisasContext
*ctx
)
131 if (unlikely(!ctx
->altivec_enabled
)) {
132 gen_exception(ctx
, POWERPC_EXCP_VPU
);
136 gen_addr_reg_index(ctx
, EA
);
137 rd
= gen_avr_ptr(rD(ctx
->opcode
));
138 gen_helper_lvsl(rd
, EA
);
140 tcg_temp_free_ptr(rd
);
143 static void gen_lvsr(DisasContext
*ctx
)
147 if (unlikely(!ctx
->altivec_enabled
)) {
148 gen_exception(ctx
, POWERPC_EXCP_VPU
);
152 gen_addr_reg_index(ctx
, EA
);
153 rd
= gen_avr_ptr(rD(ctx
->opcode
));
154 gen_helper_lvsr(rd
, EA
);
156 tcg_temp_free_ptr(rd
);
159 static void gen_mfvscr(DisasContext
*ctx
)
162 if (unlikely(!ctx
->altivec_enabled
)) {
163 gen_exception(ctx
, POWERPC_EXCP_VPU
);
166 tcg_gen_movi_i64(cpu_avrh
[rD(ctx
->opcode
)], 0);
167 t
= tcg_temp_new_i32();
168 tcg_gen_ld_i32(t
, cpu_env
, offsetof(CPUPPCState
, vscr
));
169 tcg_gen_extu_i32_i64(cpu_avrl
[rD(ctx
->opcode
)], t
);
170 tcg_temp_free_i32(t
);
173 static void gen_mtvscr(DisasContext
*ctx
)
176 if (unlikely(!ctx
->altivec_enabled
)) {
177 gen_exception(ctx
, POWERPC_EXCP_VPU
);
180 p
= gen_avr_ptr(rB(ctx
->opcode
));
181 gen_helper_mtvscr(cpu_env
, p
);
182 tcg_temp_free_ptr(p
);
185 #define GEN_VX_VMUL10(name, add_cin, ret_carry) \
186 static void glue(gen_, name)(DisasContext *ctx) \
188 TCGv_i64 t0 = tcg_temp_new_i64(); \
189 TCGv_i64 t1 = tcg_temp_new_i64(); \
190 TCGv_i64 t2 = tcg_temp_new_i64(); \
193 if (unlikely(!ctx->altivec_enabled)) { \
194 gen_exception(ctx, POWERPC_EXCP_VPU); \
198 ten = tcg_const_i64(10); \
199 z = tcg_const_i64(0); \
202 tcg_gen_mulu2_i64(t0, t1, cpu_avrl[rA(ctx->opcode)], ten); \
203 tcg_gen_andi_i64(t2, cpu_avrl[rB(ctx->opcode)], 0xF); \
204 tcg_gen_add2_i64(cpu_avrl[rD(ctx->opcode)], t2, t0, t1, t2, z); \
206 tcg_gen_mulu2_i64(cpu_avrl[rD(ctx->opcode)], t2, \
207 cpu_avrl[rA(ctx->opcode)], ten); \
211 tcg_gen_mulu2_i64(t0, t1, cpu_avrh[rA(ctx->opcode)], ten); \
212 tcg_gen_add2_i64(t0, cpu_avrl[rD(ctx->opcode)], t0, t1, t2, z); \
213 tcg_gen_movi_i64(cpu_avrh[rD(ctx->opcode)], 0); \
215 tcg_gen_mul_i64(t0, cpu_avrh[rA(ctx->opcode)], ten); \
216 tcg_gen_add_i64(cpu_avrh[rD(ctx->opcode)], t0, t2); \
219 tcg_temp_free_i64(t0); \
220 tcg_temp_free_i64(t1); \
221 tcg_temp_free_i64(t2); \
222 tcg_temp_free_i64(ten); \
223 tcg_temp_free_i64(z); \
226 GEN_VX_VMUL10(vmul10uq, 0, 0);
227 GEN_VX_VMUL10(vmul10euq
, 1, 0);
228 GEN_VX_VMUL10(vmul10cuq
, 0, 1);
229 GEN_VX_VMUL10(vmul10ecuq
, 1, 1);
231 /* Logical operations */
232 #define GEN_VX_LOGICAL(name, tcg_op, opc2, opc3) \
233 static void glue(gen_, name)(DisasContext *ctx) \
235 if (unlikely(!ctx->altivec_enabled)) { \
236 gen_exception(ctx, POWERPC_EXCP_VPU); \
239 tcg_op(cpu_avrh[rD(ctx->opcode)], cpu_avrh[rA(ctx->opcode)], cpu_avrh[rB(ctx->opcode)]); \
240 tcg_op(cpu_avrl[rD(ctx->opcode)], cpu_avrl[rA(ctx->opcode)], cpu_avrl[rB(ctx->opcode)]); \
243 GEN_VX_LOGICAL(vand
, tcg_gen_and_i64
, 2, 16);
244 GEN_VX_LOGICAL(vandc
, tcg_gen_andc_i64
, 2, 17);
245 GEN_VX_LOGICAL(vor
, tcg_gen_or_i64
, 2, 18);
246 GEN_VX_LOGICAL(vxor
, tcg_gen_xor_i64
, 2, 19);
247 GEN_VX_LOGICAL(vnor
, tcg_gen_nor_i64
, 2, 20);
248 GEN_VX_LOGICAL(veqv
, tcg_gen_eqv_i64
, 2, 26);
249 GEN_VX_LOGICAL(vnand
, tcg_gen_nand_i64
, 2, 22);
250 GEN_VX_LOGICAL(vorc
, tcg_gen_orc_i64
, 2, 21);
252 #define GEN_VXFORM(name, opc2, opc3) \
253 static void glue(gen_, name)(DisasContext *ctx) \
255 TCGv_ptr ra, rb, rd; \
256 if (unlikely(!ctx->altivec_enabled)) { \
257 gen_exception(ctx, POWERPC_EXCP_VPU); \
260 ra = gen_avr_ptr(rA(ctx->opcode)); \
261 rb = gen_avr_ptr(rB(ctx->opcode)); \
262 rd = gen_avr_ptr(rD(ctx->opcode)); \
263 gen_helper_##name (rd, ra, rb); \
264 tcg_temp_free_ptr(ra); \
265 tcg_temp_free_ptr(rb); \
266 tcg_temp_free_ptr(rd); \
269 #define GEN_VXFORM_ENV(name, opc2, opc3) \
270 static void glue(gen_, name)(DisasContext *ctx) \
272 TCGv_ptr ra, rb, rd; \
273 if (unlikely(!ctx->altivec_enabled)) { \
274 gen_exception(ctx, POWERPC_EXCP_VPU); \
277 ra = gen_avr_ptr(rA(ctx->opcode)); \
278 rb = gen_avr_ptr(rB(ctx->opcode)); \
279 rd = gen_avr_ptr(rD(ctx->opcode)); \
280 gen_helper_##name(cpu_env, rd, ra, rb); \
281 tcg_temp_free_ptr(ra); \
282 tcg_temp_free_ptr(rb); \
283 tcg_temp_free_ptr(rd); \
286 #define GEN_VXFORM3(name, opc2, opc3) \
287 static void glue(gen_, name)(DisasContext *ctx) \
289 TCGv_ptr ra, rb, rc, rd; \
290 if (unlikely(!ctx->altivec_enabled)) { \
291 gen_exception(ctx, POWERPC_EXCP_VPU); \
294 ra = gen_avr_ptr(rA(ctx->opcode)); \
295 rb = gen_avr_ptr(rB(ctx->opcode)); \
296 rc = gen_avr_ptr(rC(ctx->opcode)); \
297 rd = gen_avr_ptr(rD(ctx->opcode)); \
298 gen_helper_##name(rd, ra, rb, rc); \
299 tcg_temp_free_ptr(ra); \
300 tcg_temp_free_ptr(rb); \
301 tcg_temp_free_ptr(rc); \
302 tcg_temp_free_ptr(rd); \
306 * Support for Altivec instruction pairs that use bit 31 (Rc) as
307 * an opcode bit. In general, these pairs come from different
308 * versions of the ISA, so we must also support a pair of flags for
311 #define GEN_VXFORM_DUAL(name0, flg0, flg2_0, name1, flg1, flg2_1) \
312 static void glue(gen_, name0##_##name1)(DisasContext *ctx) \
314 if ((Rc(ctx->opcode) == 0) && \
315 ((ctx->insns_flags & flg0) || (ctx->insns_flags2 & flg2_0))) { \
317 } else if ((Rc(ctx->opcode) == 1) && \
318 ((ctx->insns_flags & flg1) || (ctx->insns_flags2 & flg2_1))) { \
321 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \
325 /* Adds support to provide invalid mask */
326 #define GEN_VXFORM_DUAL_EXT(name0, flg0, flg2_0, inval0, \
327 name1, flg1, flg2_1, inval1) \
328 static void glue(gen_, name0##_##name1)(DisasContext *ctx) \
330 if ((Rc(ctx->opcode) == 0) && \
331 ((ctx->insns_flags & flg0) || (ctx->insns_flags2 & flg2_0)) && \
332 !(ctx->opcode & inval0)) { \
334 } else if ((Rc(ctx->opcode) == 1) && \
335 ((ctx->insns_flags & flg1) || (ctx->insns_flags2 & flg2_1)) && \
336 !(ctx->opcode & inval1)) { \
339 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \
343 #define GEN_VXFORM_HETRO(name, opc2, opc3) \
344 static void glue(gen_, name)(DisasContext *ctx) \
347 if (unlikely(!ctx->altivec_enabled)) { \
348 gen_exception(ctx, POWERPC_EXCP_VPU); \
351 rb = gen_avr_ptr(rB(ctx->opcode)); \
352 gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], rb); \
353 tcg_temp_free_ptr(rb); \
356 GEN_VXFORM(vaddubm
, 0, 0);
357 GEN_VXFORM_DUAL_EXT(vaddubm
, PPC_ALTIVEC
, PPC_NONE
, 0, \
358 vmul10cuq
, PPC_NONE
, PPC2_ISA300
, 0x0000F800)
359 GEN_VXFORM(vadduhm
, 0, 1);
360 GEN_VXFORM_DUAL(vadduhm
, PPC_ALTIVEC
, PPC_NONE
, \
361 vmul10ecuq
, PPC_NONE
, PPC2_ISA300
)
362 GEN_VXFORM(vadduwm
, 0, 2);
363 GEN_VXFORM(vaddudm
, 0, 3);
364 GEN_VXFORM(vsububm
, 0, 16);
365 GEN_VXFORM(vsubuhm
, 0, 17);
366 GEN_VXFORM(vsubuwm
, 0, 18);
367 GEN_VXFORM(vsubudm
, 0, 19);
368 GEN_VXFORM(vmaxub
, 1, 0);
369 GEN_VXFORM(vmaxuh
, 1, 1);
370 GEN_VXFORM(vmaxuw
, 1, 2);
371 GEN_VXFORM(vmaxud
, 1, 3);
372 GEN_VXFORM(vmaxsb
, 1, 4);
373 GEN_VXFORM(vmaxsh
, 1, 5);
374 GEN_VXFORM(vmaxsw
, 1, 6);
375 GEN_VXFORM(vmaxsd
, 1, 7);
376 GEN_VXFORM(vminub
, 1, 8);
377 GEN_VXFORM(vminuh
, 1, 9);
378 GEN_VXFORM(vminuw
, 1, 10);
379 GEN_VXFORM(vminud
, 1, 11);
380 GEN_VXFORM(vminsb
, 1, 12);
381 GEN_VXFORM(vminsh
, 1, 13);
382 GEN_VXFORM(vminsw
, 1, 14);
383 GEN_VXFORM(vminsd
, 1, 15);
384 GEN_VXFORM(vavgub
, 1, 16);
385 GEN_VXFORM(vabsdub
, 1, 16);
386 GEN_VXFORM_DUAL(vavgub
, PPC_ALTIVEC
, PPC_NONE
, \
387 vabsdub
, PPC_NONE
, PPC2_ISA300
)
388 GEN_VXFORM(vavguh
, 1, 17);
389 GEN_VXFORM(vabsduh
, 1, 17);
390 GEN_VXFORM_DUAL(vavguh
, PPC_ALTIVEC
, PPC_NONE
, \
391 vabsduh
, PPC_NONE
, PPC2_ISA300
)
392 GEN_VXFORM(vavguw
, 1, 18);
393 GEN_VXFORM(vabsduw
, 1, 18);
394 GEN_VXFORM_DUAL(vavguw
, PPC_ALTIVEC
, PPC_NONE
, \
395 vabsduw
, PPC_NONE
, PPC2_ISA300
)
396 GEN_VXFORM(vavgsb
, 1, 20);
397 GEN_VXFORM(vavgsh
, 1, 21);
398 GEN_VXFORM(vavgsw
, 1, 22);
399 GEN_VXFORM(vmrghb
, 6, 0);
400 GEN_VXFORM(vmrghh
, 6, 1);
401 GEN_VXFORM(vmrghw
, 6, 2);
402 GEN_VXFORM(vmrglb
, 6, 4);
403 GEN_VXFORM(vmrglh
, 6, 5);
404 GEN_VXFORM(vmrglw
, 6, 6);
406 static void gen_vmrgew(DisasContext
*ctx
)
410 if (unlikely(!ctx
->altivec_enabled
)) {
411 gen_exception(ctx
, POWERPC_EXCP_VPU
);
414 VT
= rD(ctx
->opcode
);
415 VA
= rA(ctx
->opcode
);
416 VB
= rB(ctx
->opcode
);
417 tmp
= tcg_temp_new_i64();
418 tcg_gen_shri_i64(tmp
, cpu_avrh
[VB
], 32);
419 tcg_gen_deposit_i64(cpu_avrh
[VT
], cpu_avrh
[VA
], tmp
, 0, 32);
420 tcg_gen_shri_i64(tmp
, cpu_avrl
[VB
], 32);
421 tcg_gen_deposit_i64(cpu_avrl
[VT
], cpu_avrl
[VA
], tmp
, 0, 32);
422 tcg_temp_free_i64(tmp
);
425 static void gen_vmrgow(DisasContext
*ctx
)
428 if (unlikely(!ctx
->altivec_enabled
)) {
429 gen_exception(ctx
, POWERPC_EXCP_VPU
);
432 VT
= rD(ctx
->opcode
);
433 VA
= rA(ctx
->opcode
);
434 VB
= rB(ctx
->opcode
);
436 tcg_gen_deposit_i64(cpu_avrh
[VT
], cpu_avrh
[VB
], cpu_avrh
[VA
], 32, 32);
437 tcg_gen_deposit_i64(cpu_avrl
[VT
], cpu_avrl
[VB
], cpu_avrl
[VA
], 32, 32);
440 GEN_VXFORM(vmuloub
, 4, 0);
441 GEN_VXFORM(vmulouh
, 4, 1);
442 GEN_VXFORM(vmulouw
, 4, 2);
443 GEN_VXFORM(vmuluwm
, 4, 2);
444 GEN_VXFORM_DUAL(vmulouw
, PPC_ALTIVEC
, PPC_NONE
,
445 vmuluwm
, PPC_NONE
, PPC2_ALTIVEC_207
)
446 GEN_VXFORM(vmulosb
, 4, 4);
447 GEN_VXFORM(vmulosh
, 4, 5);
448 GEN_VXFORM(vmulosw
, 4, 6);
449 GEN_VXFORM(vmuleub
, 4, 8);
450 GEN_VXFORM(vmuleuh
, 4, 9);
451 GEN_VXFORM(vmuleuw
, 4, 10);
452 GEN_VXFORM(vmulesb
, 4, 12);
453 GEN_VXFORM(vmulesh
, 4, 13);
454 GEN_VXFORM(vmulesw
, 4, 14);
455 GEN_VXFORM(vslb
, 2, 4);
456 GEN_VXFORM(vslh
, 2, 5);
457 GEN_VXFORM(vslw
, 2, 6);
458 GEN_VXFORM(vrlwnm
, 2, 6);
459 GEN_VXFORM_DUAL(vslw
, PPC_ALTIVEC
, PPC_NONE
, \
460 vrlwnm
, PPC_NONE
, PPC2_ISA300
)
461 GEN_VXFORM(vsld
, 2, 23);
462 GEN_VXFORM(vsrb
, 2, 8);
463 GEN_VXFORM(vsrh
, 2, 9);
464 GEN_VXFORM(vsrw
, 2, 10);
465 GEN_VXFORM(vsrd
, 2, 27);
466 GEN_VXFORM(vsrab
, 2, 12);
467 GEN_VXFORM(vsrah
, 2, 13);
468 GEN_VXFORM(vsraw
, 2, 14);
469 GEN_VXFORM(vsrad
, 2, 15);
470 GEN_VXFORM(vsrv
, 2, 28);
471 GEN_VXFORM(vslv
, 2, 29);
472 GEN_VXFORM(vslo
, 6, 16);
473 GEN_VXFORM(vsro
, 6, 17);
474 GEN_VXFORM(vaddcuw
, 0, 6);
475 GEN_VXFORM(vsubcuw
, 0, 22);
476 GEN_VXFORM_ENV(vaddubs
, 0, 8);
477 GEN_VXFORM_DUAL_EXT(vaddubs
, PPC_ALTIVEC
, PPC_NONE
, 0, \
478 vmul10uq
, PPC_NONE
, PPC2_ISA300
, 0x0000F800)
479 GEN_VXFORM_ENV(vadduhs
, 0, 9);
480 GEN_VXFORM_DUAL(vadduhs
, PPC_ALTIVEC
, PPC_NONE
, \
481 vmul10euq
, PPC_NONE
, PPC2_ISA300
)
482 GEN_VXFORM_ENV(vadduws
, 0, 10);
483 GEN_VXFORM_ENV(vaddsbs
, 0, 12);
484 GEN_VXFORM_ENV(vaddshs
, 0, 13);
485 GEN_VXFORM_ENV(vaddsws
, 0, 14);
486 GEN_VXFORM_ENV(vsububs
, 0, 24);
487 GEN_VXFORM_ENV(vsubuhs
, 0, 25);
488 GEN_VXFORM_ENV(vsubuws
, 0, 26);
489 GEN_VXFORM_ENV(vsubsbs
, 0, 28);
490 GEN_VXFORM_ENV(vsubshs
, 0, 29);
491 GEN_VXFORM_ENV(vsubsws
, 0, 30);
492 GEN_VXFORM(vadduqm
, 0, 4);
493 GEN_VXFORM(vaddcuq
, 0, 5);
494 GEN_VXFORM3(vaddeuqm
, 30, 0);
495 GEN_VXFORM3(vaddecuq
, 30, 0);
496 GEN_VXFORM_DUAL(vaddeuqm
, PPC_NONE
, PPC2_ALTIVEC_207
, \
497 vaddecuq
, PPC_NONE
, PPC2_ALTIVEC_207
)
498 GEN_VXFORM(vsubuqm
, 0, 20);
499 GEN_VXFORM(vsubcuq
, 0, 21);
500 GEN_VXFORM3(vsubeuqm
, 31, 0);
501 GEN_VXFORM3(vsubecuq
, 31, 0);
502 GEN_VXFORM_DUAL(vsubeuqm
, PPC_NONE
, PPC2_ALTIVEC_207
, \
503 vsubecuq
, PPC_NONE
, PPC2_ALTIVEC_207
)
504 GEN_VXFORM(vrlb
, 2, 0);
505 GEN_VXFORM(vrlh
, 2, 1);
506 GEN_VXFORM(vrlw
, 2, 2);
507 GEN_VXFORM(vrlwmi
, 2, 2);
508 GEN_VXFORM_DUAL(vrlw
, PPC_ALTIVEC
, PPC_NONE
, \
509 vrlwmi
, PPC_NONE
, PPC2_ISA300
)
510 GEN_VXFORM(vrld
, 2, 3);
511 GEN_VXFORM(vrldmi
, 2, 3);
512 GEN_VXFORM_DUAL(vrld
, PPC_NONE
, PPC2_ALTIVEC_207
, \
513 vrldmi
, PPC_NONE
, PPC2_ISA300
)
514 GEN_VXFORM(vsl
, 2, 7);
515 GEN_VXFORM(vrldnm
, 2, 7);
516 GEN_VXFORM_DUAL(vsl
, PPC_ALTIVEC
, PPC_NONE
, \
517 vrldnm
, PPC_NONE
, PPC2_ISA300
)
518 GEN_VXFORM(vsr
, 2, 11);
519 GEN_VXFORM_ENV(vpkuhum
, 7, 0);
520 GEN_VXFORM_ENV(vpkuwum
, 7, 1);
521 GEN_VXFORM_ENV(vpkudum
, 7, 17);
522 GEN_VXFORM_ENV(vpkuhus
, 7, 2);
523 GEN_VXFORM_ENV(vpkuwus
, 7, 3);
524 GEN_VXFORM_ENV(vpkudus
, 7, 19);
525 GEN_VXFORM_ENV(vpkshus
, 7, 4);
526 GEN_VXFORM_ENV(vpkswus
, 7, 5);
527 GEN_VXFORM_ENV(vpksdus
, 7, 21);
528 GEN_VXFORM_ENV(vpkshss
, 7, 6);
529 GEN_VXFORM_ENV(vpkswss
, 7, 7);
530 GEN_VXFORM_ENV(vpksdss
, 7, 23);
531 GEN_VXFORM(vpkpx
, 7, 12);
532 GEN_VXFORM_ENV(vsum4ubs
, 4, 24);
533 GEN_VXFORM_ENV(vsum4sbs
, 4, 28);
534 GEN_VXFORM_ENV(vsum4shs
, 4, 25);
535 GEN_VXFORM_ENV(vsum2sws
, 4, 26);
536 GEN_VXFORM_ENV(vsumsws
, 4, 30);
537 GEN_VXFORM_ENV(vaddfp
, 5, 0);
538 GEN_VXFORM_ENV(vsubfp
, 5, 1);
539 GEN_VXFORM_ENV(vmaxfp
, 5, 16);
540 GEN_VXFORM_ENV(vminfp
, 5, 17);
541 GEN_VXFORM_HETRO(vextublx
, 6, 24)
542 GEN_VXFORM_HETRO(vextuhlx
, 6, 25)
543 GEN_VXFORM_HETRO(vextuwlx
, 6, 26)
544 GEN_VXFORM_DUAL(vmrgow
, PPC_NONE
, PPC2_ALTIVEC_207
,
545 vextuwlx
, PPC_NONE
, PPC2_ISA300
)
546 GEN_VXFORM_HETRO(vextubrx
, 6, 28)
547 GEN_VXFORM_HETRO(vextuhrx
, 6, 29)
548 GEN_VXFORM_HETRO(vextuwrx
, 6, 30)
549 GEN_VXFORM_DUAL(vmrgew
, PPC_NONE
, PPC2_ALTIVEC_207
, \
550 vextuwrx
, PPC_NONE
, PPC2_ISA300
)
552 #define GEN_VXRFORM1(opname, name, str, opc2, opc3) \
553 static void glue(gen_, name)(DisasContext *ctx) \
555 TCGv_ptr ra, rb, rd; \
556 if (unlikely(!ctx->altivec_enabled)) { \
557 gen_exception(ctx, POWERPC_EXCP_VPU); \
560 ra = gen_avr_ptr(rA(ctx->opcode)); \
561 rb = gen_avr_ptr(rB(ctx->opcode)); \
562 rd = gen_avr_ptr(rD(ctx->opcode)); \
563 gen_helper_##opname(cpu_env, rd, ra, rb); \
564 tcg_temp_free_ptr(ra); \
565 tcg_temp_free_ptr(rb); \
566 tcg_temp_free_ptr(rd); \
569 #define GEN_VXRFORM(name, opc2, opc3) \
570 GEN_VXRFORM1(name, name, #name, opc2, opc3) \
571 GEN_VXRFORM1(name##_dot, name##_, #name ".", opc2, (opc3 | (0x1 << 4)))
574 * Support for Altivec instructions that use bit 31 (Rc) as an opcode
575 * bit but also use bit 21 as an actual Rc bit. In general, thse pairs
576 * come from different versions of the ISA, so we must also support a
577 * pair of flags for each instruction.
579 #define GEN_VXRFORM_DUAL(name0, flg0, flg2_0, name1, flg1, flg2_1) \
580 static void glue(gen_, name0##_##name1)(DisasContext *ctx) \
582 if ((Rc(ctx->opcode) == 0) && \
583 ((ctx->insns_flags & flg0) || (ctx->insns_flags2 & flg2_0))) { \
584 if (Rc21(ctx->opcode) == 0) { \
587 gen_##name0##_(ctx); \
589 } else if ((Rc(ctx->opcode) == 1) && \
590 ((ctx->insns_flags & flg1) || (ctx->insns_flags2 & flg2_1))) { \
591 if (Rc21(ctx->opcode) == 0) { \
594 gen_##name1##_(ctx); \
597 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \
601 GEN_VXRFORM(vcmpequb
, 3, 0)
602 GEN_VXRFORM(vcmpequh
, 3, 1)
603 GEN_VXRFORM(vcmpequw
, 3, 2)
604 GEN_VXRFORM(vcmpequd
, 3, 3)
605 GEN_VXRFORM(vcmpnezb
, 3, 4)
606 GEN_VXRFORM(vcmpnezh
, 3, 5)
607 GEN_VXRFORM(vcmpnezw
, 3, 6)
608 GEN_VXRFORM(vcmpgtsb
, 3, 12)
609 GEN_VXRFORM(vcmpgtsh
, 3, 13)
610 GEN_VXRFORM(vcmpgtsw
, 3, 14)
611 GEN_VXRFORM(vcmpgtsd
, 3, 15)
612 GEN_VXRFORM(vcmpgtub
, 3, 8)
613 GEN_VXRFORM(vcmpgtuh
, 3, 9)
614 GEN_VXRFORM(vcmpgtuw
, 3, 10)
615 GEN_VXRFORM(vcmpgtud
, 3, 11)
616 GEN_VXRFORM(vcmpeqfp
, 3, 3)
617 GEN_VXRFORM(vcmpgefp
, 3, 7)
618 GEN_VXRFORM(vcmpgtfp
, 3, 11)
619 GEN_VXRFORM(vcmpbfp
, 3, 15)
620 GEN_VXRFORM(vcmpneb
, 3, 0)
621 GEN_VXRFORM(vcmpneh
, 3, 1)
622 GEN_VXRFORM(vcmpnew
, 3, 2)
624 GEN_VXRFORM_DUAL(vcmpequb
, PPC_ALTIVEC
, PPC_NONE
, \
625 vcmpneb
, PPC_NONE
, PPC2_ISA300
)
626 GEN_VXRFORM_DUAL(vcmpequh
, PPC_ALTIVEC
, PPC_NONE
, \
627 vcmpneh
, PPC_NONE
, PPC2_ISA300
)
628 GEN_VXRFORM_DUAL(vcmpequw
, PPC_ALTIVEC
, PPC_NONE
, \
629 vcmpnew
, PPC_NONE
, PPC2_ISA300
)
630 GEN_VXRFORM_DUAL(vcmpeqfp
, PPC_ALTIVEC
, PPC_NONE
, \
631 vcmpequd
, PPC_NONE
, PPC2_ALTIVEC_207
)
632 GEN_VXRFORM_DUAL(vcmpbfp
, PPC_ALTIVEC
, PPC_NONE
, \
633 vcmpgtsd
, PPC_NONE
, PPC2_ALTIVEC_207
)
634 GEN_VXRFORM_DUAL(vcmpgtfp
, PPC_ALTIVEC
, PPC_NONE
, \
635 vcmpgtud
, PPC_NONE
, PPC2_ALTIVEC_207
)
637 #define GEN_VXFORM_SIMM(name, opc2, opc3) \
638 static void glue(gen_, name)(DisasContext *ctx) \
642 if (unlikely(!ctx->altivec_enabled)) { \
643 gen_exception(ctx, POWERPC_EXCP_VPU); \
646 simm = tcg_const_i32(SIMM5(ctx->opcode)); \
647 rd = gen_avr_ptr(rD(ctx->opcode)); \
648 gen_helper_##name (rd, simm); \
649 tcg_temp_free_i32(simm); \
650 tcg_temp_free_ptr(rd); \
653 GEN_VXFORM_SIMM(vspltisb
, 6, 12);
654 GEN_VXFORM_SIMM(vspltish
, 6, 13);
655 GEN_VXFORM_SIMM(vspltisw
, 6, 14);
657 #define GEN_VXFORM_NOA(name, opc2, opc3) \
658 static void glue(gen_, name)(DisasContext *ctx) \
661 if (unlikely(!ctx->altivec_enabled)) { \
662 gen_exception(ctx, POWERPC_EXCP_VPU); \
665 rb = gen_avr_ptr(rB(ctx->opcode)); \
666 rd = gen_avr_ptr(rD(ctx->opcode)); \
667 gen_helper_##name (rd, rb); \
668 tcg_temp_free_ptr(rb); \
669 tcg_temp_free_ptr(rd); \
672 #define GEN_VXFORM_NOA_ENV(name, opc2, opc3) \
673 static void glue(gen_, name)(DisasContext *ctx) \
677 if (unlikely(!ctx->altivec_enabled)) { \
678 gen_exception(ctx, POWERPC_EXCP_VPU); \
681 rb = gen_avr_ptr(rB(ctx->opcode)); \
682 rd = gen_avr_ptr(rD(ctx->opcode)); \
683 gen_helper_##name(cpu_env, rd, rb); \
684 tcg_temp_free_ptr(rb); \
685 tcg_temp_free_ptr(rd); \
688 #define GEN_VXFORM_NOA_2(name, opc2, opc3, opc4) \
689 static void glue(gen_, name)(DisasContext *ctx) \
692 if (unlikely(!ctx->altivec_enabled)) { \
693 gen_exception(ctx, POWERPC_EXCP_VPU); \
696 rb = gen_avr_ptr(rB(ctx->opcode)); \
697 rd = gen_avr_ptr(rD(ctx->opcode)); \
698 gen_helper_##name(rd, rb); \
699 tcg_temp_free_ptr(rb); \
700 tcg_temp_free_ptr(rd); \
703 #define GEN_VXFORM_NOA_3(name, opc2, opc3, opc4) \
704 static void glue(gen_, name)(DisasContext *ctx) \
707 if (unlikely(!ctx->altivec_enabled)) { \
708 gen_exception(ctx, POWERPC_EXCP_VPU); \
711 rb = gen_avr_ptr(rB(ctx->opcode)); \
712 gen_helper_##name(cpu_gpr[rD(ctx->opcode)], rb); \
713 tcg_temp_free_ptr(rb); \
715 GEN_VXFORM_NOA(vupkhsb
, 7, 8);
716 GEN_VXFORM_NOA(vupkhsh
, 7, 9);
717 GEN_VXFORM_NOA(vupkhsw
, 7, 25);
718 GEN_VXFORM_NOA(vupklsb
, 7, 10);
719 GEN_VXFORM_NOA(vupklsh
, 7, 11);
720 GEN_VXFORM_NOA(vupklsw
, 7, 27);
721 GEN_VXFORM_NOA(vupkhpx
, 7, 13);
722 GEN_VXFORM_NOA(vupklpx
, 7, 15);
723 GEN_VXFORM_NOA_ENV(vrefp
, 5, 4);
724 GEN_VXFORM_NOA_ENV(vrsqrtefp
, 5, 5);
725 GEN_VXFORM_NOA_ENV(vexptefp
, 5, 6);
726 GEN_VXFORM_NOA_ENV(vlogefp
, 5, 7);
727 GEN_VXFORM_NOA_ENV(vrfim
, 5, 11);
728 GEN_VXFORM_NOA_ENV(vrfin
, 5, 8);
729 GEN_VXFORM_NOA_ENV(vrfip
, 5, 10);
730 GEN_VXFORM_NOA_ENV(vrfiz
, 5, 9);
731 GEN_VXFORM_NOA(vprtybw
, 1, 24);
732 GEN_VXFORM_NOA(vprtybd
, 1, 24);
733 GEN_VXFORM_NOA(vprtybq
, 1, 24);
735 #define GEN_VXFORM_SIMM(name, opc2, opc3) \
736 static void glue(gen_, name)(DisasContext *ctx) \
740 if (unlikely(!ctx->altivec_enabled)) { \
741 gen_exception(ctx, POWERPC_EXCP_VPU); \
744 simm = tcg_const_i32(SIMM5(ctx->opcode)); \
745 rd = gen_avr_ptr(rD(ctx->opcode)); \
746 gen_helper_##name (rd, simm); \
747 tcg_temp_free_i32(simm); \
748 tcg_temp_free_ptr(rd); \
751 #define GEN_VXFORM_UIMM(name, opc2, opc3) \
752 static void glue(gen_, name)(DisasContext *ctx) \
756 if (unlikely(!ctx->altivec_enabled)) { \
757 gen_exception(ctx, POWERPC_EXCP_VPU); \
760 uimm = tcg_const_i32(UIMM5(ctx->opcode)); \
761 rb = gen_avr_ptr(rB(ctx->opcode)); \
762 rd = gen_avr_ptr(rD(ctx->opcode)); \
763 gen_helper_##name (rd, rb, uimm); \
764 tcg_temp_free_i32(uimm); \
765 tcg_temp_free_ptr(rb); \
766 tcg_temp_free_ptr(rd); \
769 #define GEN_VXFORM_UIMM_ENV(name, opc2, opc3) \
770 static void glue(gen_, name)(DisasContext *ctx) \
775 if (unlikely(!ctx->altivec_enabled)) { \
776 gen_exception(ctx, POWERPC_EXCP_VPU); \
779 uimm = tcg_const_i32(UIMM5(ctx->opcode)); \
780 rb = gen_avr_ptr(rB(ctx->opcode)); \
781 rd = gen_avr_ptr(rD(ctx->opcode)); \
782 gen_helper_##name(cpu_env, rd, rb, uimm); \
783 tcg_temp_free_i32(uimm); \
784 tcg_temp_free_ptr(rb); \
785 tcg_temp_free_ptr(rd); \
788 #define GEN_VXFORM_UIMM_SPLAT(name, opc2, opc3, splat_max) \
789 static void glue(gen_, name)(DisasContext *ctx) \
792 uint8_t uimm = UIMM4(ctx->opcode); \
793 TCGv_i32 t0 = tcg_temp_new_i32(); \
794 if (unlikely(!ctx->altivec_enabled)) { \
795 gen_exception(ctx, POWERPC_EXCP_VPU); \
798 if (uimm > splat_max) { \
801 tcg_gen_movi_i32(t0, uimm); \
802 rb = gen_avr_ptr(rB(ctx->opcode)); \
803 rd = gen_avr_ptr(rD(ctx->opcode)); \
804 gen_helper_##name(rd, rb, t0); \
805 tcg_temp_free_i32(t0); \
806 tcg_temp_free_ptr(rb); \
807 tcg_temp_free_ptr(rd); \
810 GEN_VXFORM_UIMM(vspltb
, 6, 8);
811 GEN_VXFORM_UIMM(vsplth
, 6, 9);
812 GEN_VXFORM_UIMM(vspltw
, 6, 10);
813 GEN_VXFORM_UIMM_SPLAT(vextractub
, 6, 8, 15);
814 GEN_VXFORM_UIMM_SPLAT(vextractuh
, 6, 9, 14);
815 GEN_VXFORM_UIMM_SPLAT(vextractuw
, 6, 10, 12);
816 GEN_VXFORM_UIMM_SPLAT(vextractd
, 6, 11, 8);
817 GEN_VXFORM_UIMM_SPLAT(vinsertb
, 6, 12, 15);
818 GEN_VXFORM_UIMM_SPLAT(vinserth
, 6, 13, 14);
819 GEN_VXFORM_UIMM_SPLAT(vinsertw
, 6, 14, 12);
820 GEN_VXFORM_UIMM_SPLAT(vinsertd
, 6, 15, 8);
821 GEN_VXFORM_UIMM_ENV(vcfux
, 5, 12);
822 GEN_VXFORM_UIMM_ENV(vcfsx
, 5, 13);
823 GEN_VXFORM_UIMM_ENV(vctuxs
, 5, 14);
824 GEN_VXFORM_UIMM_ENV(vctsxs
, 5, 15);
825 GEN_VXFORM_DUAL(vspltb
, PPC_ALTIVEC
, PPC_NONE
,
826 vextractub
, PPC_NONE
, PPC2_ISA300
);
827 GEN_VXFORM_DUAL(vsplth
, PPC_ALTIVEC
, PPC_NONE
,
828 vextractuh
, PPC_NONE
, PPC2_ISA300
);
829 GEN_VXFORM_DUAL(vspltw
, PPC_ALTIVEC
, PPC_NONE
,
830 vextractuw
, PPC_NONE
, PPC2_ISA300
);
831 GEN_VXFORM_DUAL(vspltisb
, PPC_ALTIVEC
, PPC_NONE
,
832 vinsertb
, PPC_NONE
, PPC2_ISA300
);
833 GEN_VXFORM_DUAL(vspltish
, PPC_ALTIVEC
, PPC_NONE
,
834 vinserth
, PPC_NONE
, PPC2_ISA300
);
835 GEN_VXFORM_DUAL(vspltisw
, PPC_ALTIVEC
, PPC_NONE
,
836 vinsertw
, PPC_NONE
, PPC2_ISA300
);
838 static void gen_vsldoi(DisasContext
*ctx
)
842 if (unlikely(!ctx
->altivec_enabled
)) {
843 gen_exception(ctx
, POWERPC_EXCP_VPU
);
846 ra
= gen_avr_ptr(rA(ctx
->opcode
));
847 rb
= gen_avr_ptr(rB(ctx
->opcode
));
848 rd
= gen_avr_ptr(rD(ctx
->opcode
));
849 sh
= tcg_const_i32(VSH(ctx
->opcode
));
850 gen_helper_vsldoi (rd
, ra
, rb
, sh
);
851 tcg_temp_free_ptr(ra
);
852 tcg_temp_free_ptr(rb
);
853 tcg_temp_free_ptr(rd
);
854 tcg_temp_free_i32(sh
);
857 #define GEN_VAFORM_PAIRED(name0, name1, opc2) \
858 static void glue(gen_, name0##_##name1)(DisasContext *ctx) \
860 TCGv_ptr ra, rb, rc, rd; \
861 if (unlikely(!ctx->altivec_enabled)) { \
862 gen_exception(ctx, POWERPC_EXCP_VPU); \
865 ra = gen_avr_ptr(rA(ctx->opcode)); \
866 rb = gen_avr_ptr(rB(ctx->opcode)); \
867 rc = gen_avr_ptr(rC(ctx->opcode)); \
868 rd = gen_avr_ptr(rD(ctx->opcode)); \
869 if (Rc(ctx->opcode)) { \
870 gen_helper_##name1(cpu_env, rd, ra, rb, rc); \
872 gen_helper_##name0(cpu_env, rd, ra, rb, rc); \
874 tcg_temp_free_ptr(ra); \
875 tcg_temp_free_ptr(rb); \
876 tcg_temp_free_ptr(rc); \
877 tcg_temp_free_ptr(rd); \
880 GEN_VAFORM_PAIRED(vmhaddshs
, vmhraddshs
, 16)
882 static void gen_vmladduhm(DisasContext
*ctx
)
884 TCGv_ptr ra
, rb
, rc
, rd
;
885 if (unlikely(!ctx
->altivec_enabled
)) {
886 gen_exception(ctx
, POWERPC_EXCP_VPU
);
889 ra
= gen_avr_ptr(rA(ctx
->opcode
));
890 rb
= gen_avr_ptr(rB(ctx
->opcode
));
891 rc
= gen_avr_ptr(rC(ctx
->opcode
));
892 rd
= gen_avr_ptr(rD(ctx
->opcode
));
893 gen_helper_vmladduhm(rd
, ra
, rb
, rc
);
894 tcg_temp_free_ptr(ra
);
895 tcg_temp_free_ptr(rb
);
896 tcg_temp_free_ptr(rc
);
897 tcg_temp_free_ptr(rd
);
900 static void gen_vpermr(DisasContext
*ctx
)
902 TCGv_ptr ra
, rb
, rc
, rd
;
903 if (unlikely(!ctx
->altivec_enabled
)) {
904 gen_exception(ctx
, POWERPC_EXCP_VPU
);
907 ra
= gen_avr_ptr(rA(ctx
->opcode
));
908 rb
= gen_avr_ptr(rB(ctx
->opcode
));
909 rc
= gen_avr_ptr(rC(ctx
->opcode
));
910 rd
= gen_avr_ptr(rD(ctx
->opcode
));
911 gen_helper_vpermr(cpu_env
, rd
, ra
, rb
, rc
);
912 tcg_temp_free_ptr(ra
);
913 tcg_temp_free_ptr(rb
);
914 tcg_temp_free_ptr(rc
);
915 tcg_temp_free_ptr(rd
);
918 GEN_VAFORM_PAIRED(vmsumubm
, vmsummbm
, 18)
919 GEN_VAFORM_PAIRED(vmsumuhm
, vmsumuhs
, 19)
920 GEN_VAFORM_PAIRED(vmsumshm
, vmsumshs
, 20)
921 GEN_VAFORM_PAIRED(vsel
, vperm
, 21)
922 GEN_VAFORM_PAIRED(vmaddfp
, vnmsubfp
, 23)
924 GEN_VXFORM_NOA(vclzb
, 1, 28)
925 GEN_VXFORM_NOA(vclzh
, 1, 29)
926 GEN_VXFORM_NOA(vclzw
, 1, 30)
927 GEN_VXFORM_NOA(vclzd
, 1, 31)
928 GEN_VXFORM_NOA_2(vnegw
, 1, 24, 6)
929 GEN_VXFORM_NOA_2(vnegd
, 1, 24, 7)
930 GEN_VXFORM_NOA_2(vextsb2w
, 1, 24, 16)
931 GEN_VXFORM_NOA_2(vextsh2w
, 1, 24, 17)
932 GEN_VXFORM_NOA_2(vextsb2d
, 1, 24, 24)
933 GEN_VXFORM_NOA_2(vextsh2d
, 1, 24, 25)
934 GEN_VXFORM_NOA_2(vextsw2d
, 1, 24, 26)
935 GEN_VXFORM_NOA_2(vctzb
, 1, 24, 28)
936 GEN_VXFORM_NOA_2(vctzh
, 1, 24, 29)
937 GEN_VXFORM_NOA_2(vctzw
, 1, 24, 30)
938 GEN_VXFORM_NOA_2(vctzd
, 1, 24, 31)
939 GEN_VXFORM_NOA_3(vclzlsbb
, 1, 24, 0)
940 GEN_VXFORM_NOA_3(vctzlsbb
, 1, 24, 1)
941 GEN_VXFORM_NOA(vpopcntb
, 1, 28)
942 GEN_VXFORM_NOA(vpopcnth
, 1, 29)
943 GEN_VXFORM_NOA(vpopcntw
, 1, 30)
944 GEN_VXFORM_NOA(vpopcntd
, 1, 31)
945 GEN_VXFORM_DUAL(vclzb
, PPC_NONE
, PPC2_ALTIVEC_207
, \
946 vpopcntb
, PPC_NONE
, PPC2_ALTIVEC_207
)
947 GEN_VXFORM_DUAL(vclzh
, PPC_NONE
, PPC2_ALTIVEC_207
, \
948 vpopcnth
, PPC_NONE
, PPC2_ALTIVEC_207
)
949 GEN_VXFORM_DUAL(vclzw
, PPC_NONE
, PPC2_ALTIVEC_207
, \
950 vpopcntw
, PPC_NONE
, PPC2_ALTIVEC_207
)
951 GEN_VXFORM_DUAL(vclzd
, PPC_NONE
, PPC2_ALTIVEC_207
, \
952 vpopcntd
, PPC_NONE
, PPC2_ALTIVEC_207
)
953 GEN_VXFORM(vbpermd
, 6, 23);
954 GEN_VXFORM(vbpermq
, 6, 21);
955 GEN_VXFORM_NOA(vgbbd
, 6, 20);
956 GEN_VXFORM(vpmsumb
, 4, 16)
957 GEN_VXFORM(vpmsumh
, 4, 17)
958 GEN_VXFORM(vpmsumw
, 4, 18)
959 GEN_VXFORM(vpmsumd
, 4, 19)
961 #define GEN_BCD(op) \
962 static void gen_##op(DisasContext *ctx) \
964 TCGv_ptr ra, rb, rd; \
967 if (unlikely(!ctx->altivec_enabled)) { \
968 gen_exception(ctx, POWERPC_EXCP_VPU); \
972 ra = gen_avr_ptr(rA(ctx->opcode)); \
973 rb = gen_avr_ptr(rB(ctx->opcode)); \
974 rd = gen_avr_ptr(rD(ctx->opcode)); \
976 ps = tcg_const_i32((ctx->opcode & 0x200) != 0); \
978 gen_helper_##op(cpu_crf[6], rd, ra, rb, ps); \
980 tcg_temp_free_ptr(ra); \
981 tcg_temp_free_ptr(rb); \
982 tcg_temp_free_ptr(rd); \
983 tcg_temp_free_i32(ps); \
986 #define GEN_BCD2(op) \
987 static void gen_##op(DisasContext *ctx) \
992 if (unlikely(!ctx->altivec_enabled)) { \
993 gen_exception(ctx, POWERPC_EXCP_VPU); \
997 rb = gen_avr_ptr(rB(ctx->opcode)); \
998 rd = gen_avr_ptr(rD(ctx->opcode)); \
1000 ps = tcg_const_i32((ctx->opcode & 0x200) != 0); \
1002 gen_helper_##op(cpu_crf[6], rd, rb, ps); \
1004 tcg_temp_free_ptr(rb); \
1005 tcg_temp_free_ptr(rd); \
1006 tcg_temp_free_i32(ps); \
1025 static void gen_xpnd04_1(DisasContext
*ctx
)
1027 switch (opc4(ctx
->opcode
)) {
1055 static void gen_xpnd04_2(DisasContext
*ctx
)
1057 switch (opc4(ctx
->opcode
)) {
1083 GEN_VXFORM_DUAL(vsubcuw
, PPC_ALTIVEC
, PPC_NONE
, \
1084 xpnd04_1
, PPC_NONE
, PPC2_ISA300
)
1085 GEN_VXFORM_DUAL(vsubsws
, PPC_ALTIVEC
, PPC_NONE
, \
1086 xpnd04_2
, PPC_NONE
, PPC2_ISA300
)
1088 GEN_VXFORM_DUAL(vsububm
, PPC_ALTIVEC
, PPC_NONE
, \
1089 bcdadd
, PPC_NONE
, PPC2_ALTIVEC_207
)
1090 GEN_VXFORM_DUAL(vsububs
, PPC_ALTIVEC
, PPC_NONE
, \
1091 bcdadd
, PPC_NONE
, PPC2_ALTIVEC_207
)
1092 GEN_VXFORM_DUAL(vsubuhm
, PPC_ALTIVEC
, PPC_NONE
, \
1093 bcdsub
, PPC_NONE
, PPC2_ALTIVEC_207
)
1094 GEN_VXFORM_DUAL(vsubuhs
, PPC_ALTIVEC
, PPC_NONE
, \
1095 bcdsub
, PPC_NONE
, PPC2_ALTIVEC_207
)
1096 GEN_VXFORM_DUAL(vaddshs
, PPC_ALTIVEC
, PPC_NONE
, \
1097 bcdcpsgn
, PPC_NONE
, PPC2_ISA300
)
1098 GEN_VXFORM_DUAL(vsubudm
, PPC2_ALTIVEC_207
, PPC_NONE
, \
1099 bcds
, PPC_NONE
, PPC2_ISA300
)
1100 GEN_VXFORM_DUAL(vsubuwm
, PPC_ALTIVEC
, PPC_NONE
, \
1101 bcdus
, PPC_NONE
, PPC2_ISA300
)
1102 GEN_VXFORM_DUAL(vsubsbs
, PPC_ALTIVEC
, PPC_NONE
, \
1103 bcdtrunc
, PPC_NONE
, PPC2_ISA300
)
1104 GEN_VXFORM_DUAL(vsubuqm
, PPC2_ALTIVEC_207
, PPC_NONE
, \
1105 bcdtrunc
, PPC_NONE
, PPC2_ISA300
)
1106 GEN_VXFORM_DUAL(vsubcuq
, PPC2_ALTIVEC_207
, PPC_NONE
, \
1107 bcdutrunc
, PPC_NONE
, PPC2_ISA300
)
1110 static void gen_vsbox(DisasContext
*ctx
)
1113 if (unlikely(!ctx
->altivec_enabled
)) {
1114 gen_exception(ctx
, POWERPC_EXCP_VPU
);
1117 ra
= gen_avr_ptr(rA(ctx
->opcode
));
1118 rd
= gen_avr_ptr(rD(ctx
->opcode
));
1119 gen_helper_vsbox(rd
, ra
);
1120 tcg_temp_free_ptr(ra
);
1121 tcg_temp_free_ptr(rd
);
1124 GEN_VXFORM(vcipher
, 4, 20)
1125 GEN_VXFORM(vcipherlast
, 4, 20)
1126 GEN_VXFORM(vncipher
, 4, 21)
1127 GEN_VXFORM(vncipherlast
, 4, 21)
1129 GEN_VXFORM_DUAL(vcipher
, PPC_NONE
, PPC2_ALTIVEC_207
,
1130 vcipherlast
, PPC_NONE
, PPC2_ALTIVEC_207
)
1131 GEN_VXFORM_DUAL(vncipher
, PPC_NONE
, PPC2_ALTIVEC_207
,
1132 vncipherlast
, PPC_NONE
, PPC2_ALTIVEC_207
)
1134 #define VSHASIGMA(op) \
1135 static void gen_##op(DisasContext *ctx) \
1139 if (unlikely(!ctx->altivec_enabled)) { \
1140 gen_exception(ctx, POWERPC_EXCP_VPU); \
1143 ra = gen_avr_ptr(rA(ctx->opcode)); \
1144 rd = gen_avr_ptr(rD(ctx->opcode)); \
1145 st_six = tcg_const_i32(rB(ctx->opcode)); \
1146 gen_helper_##op(rd, ra, st_six); \
1147 tcg_temp_free_ptr(ra); \
1148 tcg_temp_free_ptr(rd); \
1149 tcg_temp_free_i32(st_six); \
1152 VSHASIGMA(vshasigmaw
)
1153 VSHASIGMA(vshasigmad
)
1155 GEN_VXFORM3(vpermxor
, 22, 0xFF)
1156 GEN_VXFORM_DUAL(vsldoi
, PPC_ALTIVEC
, PPC_NONE
,
1157 vpermxor
, PPC_NONE
, PPC2_ALTIVEC_207
)
1164 #undef GEN_VX_LOGICAL
1165 #undef GEN_VX_LOGICAL_207
1167 #undef GEN_VXFORM_207
1168 #undef GEN_VXFORM_DUAL
1169 #undef GEN_VXRFORM_DUAL
1172 #undef GEN_VXFORM_SIMM
1173 #undef GEN_VXFORM_NOA
1174 #undef GEN_VXFORM_UIMM
1175 #undef GEN_VAFORM_PAIRED