4 * Freescale SPE extension translation
7 /*** SPE extension ***/
10 static inline void gen_evmra(DisasContext
*ctx
)
13 if (unlikely(!ctx
->spe_enabled
)) {
14 gen_exception(ctx
, POWERPC_EXCP_SPEU
);
18 TCGv_i64 tmp
= tcg_temp_new_i64();
20 /* tmp := rA_lo + rA_hi << 32 */
21 tcg_gen_concat_tl_i64(tmp
, cpu_gpr
[rA(ctx
->opcode
)], cpu_gprh
[rA(ctx
->opcode
)]);
24 tcg_gen_st_i64(tmp
, cpu_env
, offsetof(CPUPPCState
, spe_acc
));
25 tcg_temp_free_i64(tmp
);
28 tcg_gen_mov_tl(cpu_gpr
[rD(ctx
->opcode
)], cpu_gpr
[rA(ctx
->opcode
)]);
29 tcg_gen_mov_tl(cpu_gprh
[rD(ctx
->opcode
)], cpu_gprh
[rA(ctx
->opcode
)]);
32 static inline void gen_load_gpr64(TCGv_i64 t
, int reg
)
34 tcg_gen_concat_tl_i64(t
, cpu_gpr
[reg
], cpu_gprh
[reg
]);
37 static inline void gen_store_gpr64(int reg
, TCGv_i64 t
)
39 tcg_gen_extr_i64_tl(cpu_gpr
[reg
], cpu_gprh
[reg
], t
);
42 #define GEN_SPE(name0, name1, opc2, opc3, inval0, inval1, type) \
43 static void glue(gen_, name0##_##name1)(DisasContext *ctx) \
45 if (Rc(ctx->opcode)) \
51 /* Handler for undefined SPE opcodes */
52 static inline void gen_speundef(DisasContext
*ctx
)
54 gen_inval_exception(ctx
, POWERPC_EXCP_INVAL_INVAL
);
58 #define GEN_SPEOP_LOGIC2(name, tcg_op) \
59 static inline void gen_##name(DisasContext *ctx) \
61 if (unlikely(!ctx->spe_enabled)) { \
62 gen_exception(ctx, POWERPC_EXCP_SPEU); \
65 tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], \
66 cpu_gpr[rB(ctx->opcode)]); \
67 tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], \
68 cpu_gprh[rB(ctx->opcode)]); \
71 GEN_SPEOP_LOGIC2(evand
, tcg_gen_and_tl
);
72 GEN_SPEOP_LOGIC2(evandc
, tcg_gen_andc_tl
);
73 GEN_SPEOP_LOGIC2(evxor
, tcg_gen_xor_tl
);
74 GEN_SPEOP_LOGIC2(evor
, tcg_gen_or_tl
);
75 GEN_SPEOP_LOGIC2(evnor
, tcg_gen_nor_tl
);
76 GEN_SPEOP_LOGIC2(eveqv
, tcg_gen_eqv_tl
);
77 GEN_SPEOP_LOGIC2(evorc
, tcg_gen_orc_tl
);
78 GEN_SPEOP_LOGIC2(evnand
, tcg_gen_nand_tl
);
80 /* SPE logic immediate */
81 #define GEN_SPEOP_TCG_LOGIC_IMM2(name, tcg_opi) \
82 static inline void gen_##name(DisasContext *ctx) \
85 if (unlikely(!ctx->spe_enabled)) { \
86 gen_exception(ctx, POWERPC_EXCP_SPEU); \
89 t0 = tcg_temp_new_i32(); \
91 tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]); \
92 tcg_opi(t0, t0, rB(ctx->opcode)); \
93 tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0); \
95 tcg_gen_trunc_tl_i32(t0, cpu_gprh[rA(ctx->opcode)]); \
96 tcg_opi(t0, t0, rB(ctx->opcode)); \
97 tcg_gen_extu_i32_tl(cpu_gprh[rD(ctx->opcode)], t0); \
99 tcg_temp_free_i32(t0); \
101 GEN_SPEOP_TCG_LOGIC_IMM2(evslwi
, tcg_gen_shli_i32
);
102 GEN_SPEOP_TCG_LOGIC_IMM2(evsrwiu
, tcg_gen_shri_i32
);
103 GEN_SPEOP_TCG_LOGIC_IMM2(evsrwis
, tcg_gen_sari_i32
);
104 GEN_SPEOP_TCG_LOGIC_IMM2(evrlwi
, tcg_gen_rotli_i32
);
107 #define GEN_SPEOP_ARITH1(name, tcg_op) \
108 static inline void gen_##name(DisasContext *ctx) \
111 if (unlikely(!ctx->spe_enabled)) { \
112 gen_exception(ctx, POWERPC_EXCP_SPEU); \
115 t0 = tcg_temp_new_i32(); \
117 tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]); \
119 tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0); \
121 tcg_gen_trunc_tl_i32(t0, cpu_gprh[rA(ctx->opcode)]); \
123 tcg_gen_extu_i32_tl(cpu_gprh[rD(ctx->opcode)], t0); \
125 tcg_temp_free_i32(t0); \
128 static inline void gen_op_evabs(TCGv_i32 ret
, TCGv_i32 arg1
)
130 TCGLabel
*l1
= gen_new_label();
131 TCGLabel
*l2
= gen_new_label();
133 tcg_gen_brcondi_i32(TCG_COND_GE
, arg1
, 0, l1
);
134 tcg_gen_neg_i32(ret
, arg1
);
137 tcg_gen_mov_i32(ret
, arg1
);
140 GEN_SPEOP_ARITH1(evabs
, gen_op_evabs
);
141 GEN_SPEOP_ARITH1(evneg
, tcg_gen_neg_i32
);
142 GEN_SPEOP_ARITH1(evextsb
, tcg_gen_ext8s_i32
);
143 GEN_SPEOP_ARITH1(evextsh
, tcg_gen_ext16s_i32
);
144 static inline void gen_op_evrndw(TCGv_i32 ret
, TCGv_i32 arg1
)
146 tcg_gen_addi_i32(ret
, arg1
, 0x8000);
147 tcg_gen_ext16u_i32(ret
, ret
);
149 GEN_SPEOP_ARITH1(evrndw
, gen_op_evrndw
);
150 GEN_SPEOP_ARITH1(evcntlsw
, gen_helper_cntlsw32
);
151 GEN_SPEOP_ARITH1(evcntlzw
, gen_helper_cntlzw32
);
153 #define GEN_SPEOP_ARITH2(name, tcg_op) \
154 static inline void gen_##name(DisasContext *ctx) \
157 if (unlikely(!ctx->spe_enabled)) { \
158 gen_exception(ctx, POWERPC_EXCP_SPEU); \
161 t0 = tcg_temp_new_i32(); \
162 t1 = tcg_temp_new_i32(); \
164 tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]); \
165 tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]); \
166 tcg_op(t0, t0, t1); \
167 tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0); \
169 tcg_gen_trunc_tl_i32(t0, cpu_gprh[rA(ctx->opcode)]); \
170 tcg_gen_trunc_tl_i32(t1, cpu_gprh[rB(ctx->opcode)]); \
171 tcg_op(t0, t0, t1); \
172 tcg_gen_extu_i32_tl(cpu_gprh[rD(ctx->opcode)], t0); \
174 tcg_temp_free_i32(t0); \
175 tcg_temp_free_i32(t1); \
178 static inline void gen_op_evsrwu(TCGv_i32 ret
, TCGv_i32 arg1
, TCGv_i32 arg2
)
180 TCGLabel
*l1
= gen_new_label();
181 TCGLabel
*l2
= gen_new_label();
182 TCGv_i32 t0
= tcg_temp_local_new_i32();
184 /* No error here: 6 bits are used */
185 tcg_gen_andi_i32(t0
, arg2
, 0x3F);
186 tcg_gen_brcondi_i32(TCG_COND_GE
, t0
, 32, l1
);
187 tcg_gen_shr_i32(ret
, arg1
, t0
);
190 tcg_gen_movi_i32(ret
, 0);
192 tcg_temp_free_i32(t0
);
194 GEN_SPEOP_ARITH2(evsrwu
, gen_op_evsrwu
);
195 static inline void gen_op_evsrws(TCGv_i32 ret
, TCGv_i32 arg1
, TCGv_i32 arg2
)
197 TCGLabel
*l1
= gen_new_label();
198 TCGLabel
*l2
= gen_new_label();
199 TCGv_i32 t0
= tcg_temp_local_new_i32();
201 /* No error here: 6 bits are used */
202 tcg_gen_andi_i32(t0
, arg2
, 0x3F);
203 tcg_gen_brcondi_i32(TCG_COND_GE
, t0
, 32, l1
);
204 tcg_gen_sar_i32(ret
, arg1
, t0
);
207 tcg_gen_movi_i32(ret
, 0);
209 tcg_temp_free_i32(t0
);
211 GEN_SPEOP_ARITH2(evsrws
, gen_op_evsrws
);
212 static inline void gen_op_evslw(TCGv_i32 ret
, TCGv_i32 arg1
, TCGv_i32 arg2
)
214 TCGLabel
*l1
= gen_new_label();
215 TCGLabel
*l2
= gen_new_label();
216 TCGv_i32 t0
= tcg_temp_local_new_i32();
218 /* No error here: 6 bits are used */
219 tcg_gen_andi_i32(t0
, arg2
, 0x3F);
220 tcg_gen_brcondi_i32(TCG_COND_GE
, t0
, 32, l1
);
221 tcg_gen_shl_i32(ret
, arg1
, t0
);
224 tcg_gen_movi_i32(ret
, 0);
226 tcg_temp_free_i32(t0
);
228 GEN_SPEOP_ARITH2(evslw
, gen_op_evslw
);
229 static inline void gen_op_evrlw(TCGv_i32 ret
, TCGv_i32 arg1
, TCGv_i32 arg2
)
231 TCGv_i32 t0
= tcg_temp_new_i32();
232 tcg_gen_andi_i32(t0
, arg2
, 0x1F);
233 tcg_gen_rotl_i32(ret
, arg1
, t0
);
234 tcg_temp_free_i32(t0
);
236 GEN_SPEOP_ARITH2(evrlw
, gen_op_evrlw
);
237 static inline void gen_evmergehi(DisasContext
*ctx
)
239 if (unlikely(!ctx
->spe_enabled
)) {
240 gen_exception(ctx
, POWERPC_EXCP_SPEU
);
243 tcg_gen_mov_tl(cpu_gpr
[rD(ctx
->opcode
)], cpu_gprh
[rB(ctx
->opcode
)]);
244 tcg_gen_mov_tl(cpu_gprh
[rD(ctx
->opcode
)], cpu_gprh
[rA(ctx
->opcode
)]);
246 GEN_SPEOP_ARITH2(evaddw
, tcg_gen_add_i32
);
247 static inline void gen_op_evsubf(TCGv_i32 ret
, TCGv_i32 arg1
, TCGv_i32 arg2
)
249 tcg_gen_sub_i32(ret
, arg2
, arg1
);
251 GEN_SPEOP_ARITH2(evsubfw
, gen_op_evsubf
);
253 /* SPE arithmetic immediate */
254 #define GEN_SPEOP_ARITH_IMM2(name, tcg_op) \
255 static inline void gen_##name(DisasContext *ctx) \
258 if (unlikely(!ctx->spe_enabled)) { \
259 gen_exception(ctx, POWERPC_EXCP_SPEU); \
262 t0 = tcg_temp_new_i32(); \
264 tcg_gen_trunc_tl_i32(t0, cpu_gpr[rB(ctx->opcode)]); \
265 tcg_op(t0, t0, rA(ctx->opcode)); \
266 tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0); \
268 tcg_gen_trunc_tl_i32(t0, cpu_gprh[rB(ctx->opcode)]); \
269 tcg_op(t0, t0, rA(ctx->opcode)); \
270 tcg_gen_extu_i32_tl(cpu_gprh[rD(ctx->opcode)], t0); \
272 tcg_temp_free_i32(t0); \
274 GEN_SPEOP_ARITH_IMM2(evaddiw
, tcg_gen_addi_i32
);
275 GEN_SPEOP_ARITH_IMM2(evsubifw
, tcg_gen_subi_i32
);
278 #define GEN_SPEOP_COMP(name, tcg_cond) \
279 static inline void gen_##name(DisasContext *ctx) \
281 if (unlikely(!ctx->spe_enabled)) { \
282 gen_exception(ctx, POWERPC_EXCP_SPEU); \
285 TCGLabel *l1 = gen_new_label(); \
286 TCGLabel *l2 = gen_new_label(); \
287 TCGLabel *l3 = gen_new_label(); \
288 TCGLabel *l4 = gen_new_label(); \
290 tcg_gen_ext32s_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); \
291 tcg_gen_ext32s_tl(cpu_gpr[rB(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); \
292 tcg_gen_ext32s_tl(cpu_gprh[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]); \
293 tcg_gen_ext32s_tl(cpu_gprh[rB(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]); \
295 tcg_gen_brcond_tl(tcg_cond, cpu_gpr[rA(ctx->opcode)], \
296 cpu_gpr[rB(ctx->opcode)], l1); \
297 tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)], 0); \
300 tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)], \
301 CRF_CL | CRF_CH_OR_CL | CRF_CH_AND_CL); \
303 tcg_gen_brcond_tl(tcg_cond, cpu_gprh[rA(ctx->opcode)], \
304 cpu_gprh[rB(ctx->opcode)], l3); \
305 tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], \
306 ~(CRF_CH | CRF_CH_AND_CL)); \
309 tcg_gen_ori_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], \
310 CRF_CH | CRF_CH_OR_CL); \
313 GEN_SPEOP_COMP(evcmpgtu
, TCG_COND_GTU
);
314 GEN_SPEOP_COMP(evcmpgts
, TCG_COND_GT
);
315 GEN_SPEOP_COMP(evcmpltu
, TCG_COND_LTU
);
316 GEN_SPEOP_COMP(evcmplts
, TCG_COND_LT
);
317 GEN_SPEOP_COMP(evcmpeq
, TCG_COND_EQ
);
320 static inline void gen_brinc(DisasContext
*ctx
)
322 /* Note: brinc is usable even if SPE is disabled */
323 gen_helper_brinc(cpu_gpr
[rD(ctx
->opcode
)],
324 cpu_gpr
[rA(ctx
->opcode
)], cpu_gpr
[rB(ctx
->opcode
)]);
326 static inline void gen_evmergelo(DisasContext
*ctx
)
328 if (unlikely(!ctx
->spe_enabled
)) {
329 gen_exception(ctx
, POWERPC_EXCP_SPEU
);
332 tcg_gen_mov_tl(cpu_gprh
[rD(ctx
->opcode
)], cpu_gpr
[rA(ctx
->opcode
)]);
333 tcg_gen_mov_tl(cpu_gpr
[rD(ctx
->opcode
)], cpu_gpr
[rB(ctx
->opcode
)]);
335 static inline void gen_evmergehilo(DisasContext
*ctx
)
337 if (unlikely(!ctx
->spe_enabled
)) {
338 gen_exception(ctx
, POWERPC_EXCP_SPEU
);
341 tcg_gen_mov_tl(cpu_gpr
[rD(ctx
->opcode
)], cpu_gpr
[rB(ctx
->opcode
)]);
342 tcg_gen_mov_tl(cpu_gprh
[rD(ctx
->opcode
)], cpu_gprh
[rA(ctx
->opcode
)]);
344 static inline void gen_evmergelohi(DisasContext
*ctx
)
346 if (unlikely(!ctx
->spe_enabled
)) {
347 gen_exception(ctx
, POWERPC_EXCP_SPEU
);
350 if (rD(ctx
->opcode
) == rA(ctx
->opcode
)) {
351 TCGv tmp
= tcg_temp_new();
352 tcg_gen_mov_tl(tmp
, cpu_gpr
[rA(ctx
->opcode
)]);
353 tcg_gen_mov_tl(cpu_gpr
[rD(ctx
->opcode
)], cpu_gprh
[rB(ctx
->opcode
)]);
354 tcg_gen_mov_tl(cpu_gprh
[rD(ctx
->opcode
)], tmp
);
357 tcg_gen_mov_tl(cpu_gpr
[rD(ctx
->opcode
)], cpu_gprh
[rB(ctx
->opcode
)]);
358 tcg_gen_mov_tl(cpu_gprh
[rD(ctx
->opcode
)], cpu_gpr
[rA(ctx
->opcode
)]);
361 static inline void gen_evsplati(DisasContext
*ctx
)
363 uint64_t imm
= ((int32_t)(rA(ctx
->opcode
) << 27)) >> 27;
365 tcg_gen_movi_tl(cpu_gpr
[rD(ctx
->opcode
)], imm
);
366 tcg_gen_movi_tl(cpu_gprh
[rD(ctx
->opcode
)], imm
);
368 static inline void gen_evsplatfi(DisasContext
*ctx
)
370 uint64_t imm
= rA(ctx
->opcode
) << 27;
372 tcg_gen_movi_tl(cpu_gpr
[rD(ctx
->opcode
)], imm
);
373 tcg_gen_movi_tl(cpu_gprh
[rD(ctx
->opcode
)], imm
);
376 static inline void gen_evsel(DisasContext
*ctx
)
378 TCGLabel
*l1
= gen_new_label();
379 TCGLabel
*l2
= gen_new_label();
380 TCGLabel
*l3
= gen_new_label();
381 TCGLabel
*l4
= gen_new_label();
382 TCGv_i32 t0
= tcg_temp_local_new_i32();
384 tcg_gen_andi_i32(t0
, cpu_crf
[ctx
->opcode
& 0x07], 1 << 3);
385 tcg_gen_brcondi_i32(TCG_COND_EQ
, t0
, 0, l1
);
386 tcg_gen_mov_tl(cpu_gprh
[rD(ctx
->opcode
)], cpu_gprh
[rA(ctx
->opcode
)]);
389 tcg_gen_mov_tl(cpu_gprh
[rD(ctx
->opcode
)], cpu_gprh
[rB(ctx
->opcode
)]);
391 tcg_gen_andi_i32(t0
, cpu_crf
[ctx
->opcode
& 0x07], 1 << 2);
392 tcg_gen_brcondi_i32(TCG_COND_EQ
, t0
, 0, l3
);
393 tcg_gen_mov_tl(cpu_gpr
[rD(ctx
->opcode
)], cpu_gpr
[rA(ctx
->opcode
)]);
396 tcg_gen_mov_tl(cpu_gpr
[rD(ctx
->opcode
)], cpu_gpr
[rB(ctx
->opcode
)]);
398 tcg_temp_free_i32(t0
);
401 static void gen_evsel0(DisasContext
*ctx
)
406 static void gen_evsel1(DisasContext
*ctx
)
411 static void gen_evsel2(DisasContext
*ctx
)
416 static void gen_evsel3(DisasContext
*ctx
)
423 static inline void gen_evmwumi(DisasContext
*ctx
)
427 if (unlikely(!ctx
->spe_enabled
)) {
428 gen_exception(ctx
, POWERPC_EXCP_SPEU
);
432 t0
= tcg_temp_new_i64();
433 t1
= tcg_temp_new_i64();
435 /* t0 := rA; t1 := rB */
436 tcg_gen_extu_tl_i64(t0
, cpu_gpr
[rA(ctx
->opcode
)]);
437 tcg_gen_ext32u_i64(t0
, t0
);
438 tcg_gen_extu_tl_i64(t1
, cpu_gpr
[rB(ctx
->opcode
)]);
439 tcg_gen_ext32u_i64(t1
, t1
);
441 tcg_gen_mul_i64(t0
, t0
, t1
); /* t0 := rA * rB */
443 gen_store_gpr64(rD(ctx
->opcode
), t0
); /* rD := t0 */
445 tcg_temp_free_i64(t0
);
446 tcg_temp_free_i64(t1
);
449 static inline void gen_evmwumia(DisasContext
*ctx
)
453 if (unlikely(!ctx
->spe_enabled
)) {
454 gen_exception(ctx
, POWERPC_EXCP_SPEU
);
458 gen_evmwumi(ctx
); /* rD := rA * rB */
460 tmp
= tcg_temp_new_i64();
463 gen_load_gpr64(tmp
, rD(ctx
->opcode
));
464 tcg_gen_st_i64(tmp
, cpu_env
, offsetof(CPUPPCState
, spe_acc
));
465 tcg_temp_free_i64(tmp
);
468 static inline void gen_evmwumiaa(DisasContext
*ctx
)
473 if (unlikely(!ctx
->spe_enabled
)) {
474 gen_exception(ctx
, POWERPC_EXCP_SPEU
);
478 gen_evmwumi(ctx
); /* rD := rA * rB */
480 acc
= tcg_temp_new_i64();
481 tmp
= tcg_temp_new_i64();
484 gen_load_gpr64(tmp
, rD(ctx
->opcode
));
487 tcg_gen_ld_i64(acc
, cpu_env
, offsetof(CPUPPCState
, spe_acc
));
489 /* acc := tmp + acc */
490 tcg_gen_add_i64(acc
, acc
, tmp
);
493 tcg_gen_st_i64(acc
, cpu_env
, offsetof(CPUPPCState
, spe_acc
));
496 gen_store_gpr64(rD(ctx
->opcode
), acc
);
498 tcg_temp_free_i64(acc
);
499 tcg_temp_free_i64(tmp
);
502 static inline void gen_evmwsmi(DisasContext
*ctx
)
506 if (unlikely(!ctx
->spe_enabled
)) {
507 gen_exception(ctx
, POWERPC_EXCP_SPEU
);
511 t0
= tcg_temp_new_i64();
512 t1
= tcg_temp_new_i64();
514 /* t0 := rA; t1 := rB */
515 tcg_gen_extu_tl_i64(t0
, cpu_gpr
[rA(ctx
->opcode
)]);
516 tcg_gen_ext32s_i64(t0
, t0
);
517 tcg_gen_extu_tl_i64(t1
, cpu_gpr
[rB(ctx
->opcode
)]);
518 tcg_gen_ext32s_i64(t1
, t1
);
520 tcg_gen_mul_i64(t0
, t0
, t1
); /* t0 := rA * rB */
522 gen_store_gpr64(rD(ctx
->opcode
), t0
); /* rD := t0 */
524 tcg_temp_free_i64(t0
);
525 tcg_temp_free_i64(t1
);
528 static inline void gen_evmwsmia(DisasContext
*ctx
)
532 gen_evmwsmi(ctx
); /* rD := rA * rB */
534 tmp
= tcg_temp_new_i64();
537 gen_load_gpr64(tmp
, rD(ctx
->opcode
));
538 tcg_gen_st_i64(tmp
, cpu_env
, offsetof(CPUPPCState
, spe_acc
));
540 tcg_temp_free_i64(tmp
);
543 static inline void gen_evmwsmiaa(DisasContext
*ctx
)
545 TCGv_i64 acc
= tcg_temp_new_i64();
546 TCGv_i64 tmp
= tcg_temp_new_i64();
548 gen_evmwsmi(ctx
); /* rD := rA * rB */
550 acc
= tcg_temp_new_i64();
551 tmp
= tcg_temp_new_i64();
554 gen_load_gpr64(tmp
, rD(ctx
->opcode
));
557 tcg_gen_ld_i64(acc
, cpu_env
, offsetof(CPUPPCState
, spe_acc
));
559 /* acc := tmp + acc */
560 tcg_gen_add_i64(acc
, acc
, tmp
);
563 tcg_gen_st_i64(acc
, cpu_env
, offsetof(CPUPPCState
, spe_acc
));
566 gen_store_gpr64(rD(ctx
->opcode
), acc
);
568 tcg_temp_free_i64(acc
);
569 tcg_temp_free_i64(tmp
);
572 GEN_SPE(evaddw
, speundef
, 0x00, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE
); ////
573 GEN_SPE(evaddiw
, speundef
, 0x01, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE
);
574 GEN_SPE(evsubfw
, speundef
, 0x02, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE
); ////
575 GEN_SPE(evsubifw
, speundef
, 0x03, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE
);
576 GEN_SPE(evabs
, evneg
, 0x04, 0x08, 0x0000F800, 0x0000F800, PPC_SPE
); ////
577 GEN_SPE(evextsb
, evextsh
, 0x05, 0x08, 0x0000F800, 0x0000F800, PPC_SPE
); ////
578 GEN_SPE(evrndw
, evcntlzw
, 0x06, 0x08, 0x0000F800, 0x0000F800, PPC_SPE
); ////
579 GEN_SPE(evcntlsw
, brinc
, 0x07, 0x08, 0x0000F800, 0x00000000, PPC_SPE
); //
580 GEN_SPE(evmra
, speundef
, 0x02, 0x13, 0x0000F800, 0xFFFFFFFF, PPC_SPE
);
581 GEN_SPE(speundef
, evand
, 0x08, 0x08, 0xFFFFFFFF, 0x00000000, PPC_SPE
); ////
582 GEN_SPE(evandc
, speundef
, 0x09, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE
); ////
583 GEN_SPE(evxor
, evor
, 0x0B, 0x08, 0x00000000, 0x00000000, PPC_SPE
); ////
584 GEN_SPE(evnor
, eveqv
, 0x0C, 0x08, 0x00000000, 0x00000000, PPC_SPE
); ////
585 GEN_SPE(evmwumi
, evmwsmi
, 0x0C, 0x11, 0x00000000, 0x00000000, PPC_SPE
);
586 GEN_SPE(evmwumia
, evmwsmia
, 0x1C, 0x11, 0x00000000, 0x00000000, PPC_SPE
);
587 GEN_SPE(evmwumiaa
, evmwsmiaa
, 0x0C, 0x15, 0x00000000, 0x00000000, PPC_SPE
);
588 GEN_SPE(speundef
, evorc
, 0x0D, 0x08, 0xFFFFFFFF, 0x00000000, PPC_SPE
); ////
589 GEN_SPE(evnand
, speundef
, 0x0F, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE
); ////
590 GEN_SPE(evsrwu
, evsrws
, 0x10, 0x08, 0x00000000, 0x00000000, PPC_SPE
); ////
591 GEN_SPE(evsrwiu
, evsrwis
, 0x11, 0x08, 0x00000000, 0x00000000, PPC_SPE
);
592 GEN_SPE(evslw
, speundef
, 0x12, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE
); ////
593 GEN_SPE(evslwi
, speundef
, 0x13, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE
);
594 GEN_SPE(evrlw
, evsplati
, 0x14, 0x08, 0x00000000, 0x0000F800, PPC_SPE
); //
595 GEN_SPE(evrlwi
, evsplatfi
, 0x15, 0x08, 0x00000000, 0x0000F800, PPC_SPE
);
596 GEN_SPE(evmergehi
, evmergelo
, 0x16, 0x08, 0x00000000, 0x00000000, PPC_SPE
); ////
597 GEN_SPE(evmergehilo
, evmergelohi
, 0x17, 0x08, 0x00000000, 0x00000000, PPC_SPE
); ////
598 GEN_SPE(evcmpgtu
, evcmpgts
, 0x18, 0x08, 0x00600000, 0x00600000, PPC_SPE
); ////
599 GEN_SPE(evcmpltu
, evcmplts
, 0x19, 0x08, 0x00600000, 0x00600000, PPC_SPE
); ////
600 GEN_SPE(evcmpeq
, speundef
, 0x1A, 0x08, 0x00600000, 0xFFFFFFFF, PPC_SPE
); ////
602 /* SPE load and stores */
603 static inline void gen_addr_spe_imm_index(DisasContext
*ctx
, TCGv EA
, int sh
)
605 target_ulong uimm
= rB(ctx
->opcode
);
607 if (rA(ctx
->opcode
) == 0) {
608 tcg_gen_movi_tl(EA
, uimm
<< sh
);
610 tcg_gen_addi_tl(EA
, cpu_gpr
[rA(ctx
->opcode
)], uimm
<< sh
);
611 if (NARROW_MODE(ctx
)) {
612 tcg_gen_ext32u_tl(EA
, EA
);
617 static inline void gen_op_evldd(DisasContext
*ctx
, TCGv addr
)
619 TCGv_i64 t0
= tcg_temp_new_i64();
620 gen_qemu_ld64_i64(ctx
, t0
, addr
);
621 gen_store_gpr64(rD(ctx
->opcode
), t0
);
622 tcg_temp_free_i64(t0
);
625 static inline void gen_op_evldw(DisasContext
*ctx
, TCGv addr
)
627 gen_qemu_ld32u(ctx
, cpu_gprh
[rD(ctx
->opcode
)], addr
);
628 gen_addr_add(ctx
, addr
, addr
, 4);
629 gen_qemu_ld32u(ctx
, cpu_gpr
[rD(ctx
->opcode
)], addr
);
632 static inline void gen_op_evldh(DisasContext
*ctx
, TCGv addr
)
634 TCGv t0
= tcg_temp_new();
635 gen_qemu_ld16u(ctx
, t0
, addr
);
636 tcg_gen_shli_tl(cpu_gprh
[rD(ctx
->opcode
)], t0
, 16);
637 gen_addr_add(ctx
, addr
, addr
, 2);
638 gen_qemu_ld16u(ctx
, t0
, addr
);
639 tcg_gen_or_tl(cpu_gprh
[rD(ctx
->opcode
)], cpu_gprh
[rD(ctx
->opcode
)], t0
);
640 gen_addr_add(ctx
, addr
, addr
, 2);
641 gen_qemu_ld16u(ctx
, t0
, addr
);
642 tcg_gen_shli_tl(cpu_gprh
[rD(ctx
->opcode
)], t0
, 16);
643 gen_addr_add(ctx
, addr
, addr
, 2);
644 gen_qemu_ld16u(ctx
, t0
, addr
);
645 tcg_gen_or_tl(cpu_gpr
[rD(ctx
->opcode
)], cpu_gpr
[rD(ctx
->opcode
)], t0
);
649 static inline void gen_op_evlhhesplat(DisasContext
*ctx
, TCGv addr
)
651 TCGv t0
= tcg_temp_new();
652 gen_qemu_ld16u(ctx
, t0
, addr
);
653 tcg_gen_shli_tl(t0
, t0
, 16);
654 tcg_gen_mov_tl(cpu_gprh
[rD(ctx
->opcode
)], t0
);
655 tcg_gen_mov_tl(cpu_gpr
[rD(ctx
->opcode
)], t0
);
659 static inline void gen_op_evlhhousplat(DisasContext
*ctx
, TCGv addr
)
661 TCGv t0
= tcg_temp_new();
662 gen_qemu_ld16u(ctx
, t0
, addr
);
663 tcg_gen_mov_tl(cpu_gprh
[rD(ctx
->opcode
)], t0
);
664 tcg_gen_mov_tl(cpu_gpr
[rD(ctx
->opcode
)], t0
);
668 static inline void gen_op_evlhhossplat(DisasContext
*ctx
, TCGv addr
)
670 TCGv t0
= tcg_temp_new();
671 gen_qemu_ld16s(ctx
, t0
, addr
);
672 tcg_gen_mov_tl(cpu_gprh
[rD(ctx
->opcode
)], t0
);
673 tcg_gen_mov_tl(cpu_gpr
[rD(ctx
->opcode
)], t0
);
677 static inline void gen_op_evlwhe(DisasContext
*ctx
, TCGv addr
)
679 TCGv t0
= tcg_temp_new();
680 gen_qemu_ld16u(ctx
, t0
, addr
);
681 tcg_gen_shli_tl(cpu_gprh
[rD(ctx
->opcode
)], t0
, 16);
682 gen_addr_add(ctx
, addr
, addr
, 2);
683 gen_qemu_ld16u(ctx
, t0
, addr
);
684 tcg_gen_shli_tl(cpu_gpr
[rD(ctx
->opcode
)], t0
, 16);
688 static inline void gen_op_evlwhou(DisasContext
*ctx
, TCGv addr
)
690 gen_qemu_ld16u(ctx
, cpu_gprh
[rD(ctx
->opcode
)], addr
);
691 gen_addr_add(ctx
, addr
, addr
, 2);
692 gen_qemu_ld16u(ctx
, cpu_gpr
[rD(ctx
->opcode
)], addr
);
695 static inline void gen_op_evlwhos(DisasContext
*ctx
, TCGv addr
)
697 gen_qemu_ld16s(ctx
, cpu_gprh
[rD(ctx
->opcode
)], addr
);
698 gen_addr_add(ctx
, addr
, addr
, 2);
699 gen_qemu_ld16s(ctx
, cpu_gpr
[rD(ctx
->opcode
)], addr
);
702 static inline void gen_op_evlwwsplat(DisasContext
*ctx
, TCGv addr
)
704 TCGv t0
= tcg_temp_new();
705 gen_qemu_ld32u(ctx
, t0
, addr
);
706 tcg_gen_mov_tl(cpu_gprh
[rD(ctx
->opcode
)], t0
);
707 tcg_gen_mov_tl(cpu_gpr
[rD(ctx
->opcode
)], t0
);
711 static inline void gen_op_evlwhsplat(DisasContext
*ctx
, TCGv addr
)
713 TCGv t0
= tcg_temp_new();
714 gen_qemu_ld16u(ctx
, t0
, addr
);
715 tcg_gen_shli_tl(cpu_gprh
[rD(ctx
->opcode
)], t0
, 16);
716 tcg_gen_or_tl(cpu_gprh
[rD(ctx
->opcode
)], cpu_gprh
[rD(ctx
->opcode
)], t0
);
717 gen_addr_add(ctx
, addr
, addr
, 2);
718 gen_qemu_ld16u(ctx
, t0
, addr
);
719 tcg_gen_shli_tl(cpu_gpr
[rD(ctx
->opcode
)], t0
, 16);
720 tcg_gen_or_tl(cpu_gpr
[rD(ctx
->opcode
)], cpu_gprh
[rD(ctx
->opcode
)], t0
);
724 static inline void gen_op_evstdd(DisasContext
*ctx
, TCGv addr
)
726 TCGv_i64 t0
= tcg_temp_new_i64();
727 gen_load_gpr64(t0
, rS(ctx
->opcode
));
728 gen_qemu_st64_i64(ctx
, t0
, addr
);
729 tcg_temp_free_i64(t0
);
732 static inline void gen_op_evstdw(DisasContext
*ctx
, TCGv addr
)
734 gen_qemu_st32(ctx
, cpu_gprh
[rS(ctx
->opcode
)], addr
);
735 gen_addr_add(ctx
, addr
, addr
, 4);
736 gen_qemu_st32(ctx
, cpu_gpr
[rS(ctx
->opcode
)], addr
);
739 static inline void gen_op_evstdh(DisasContext
*ctx
, TCGv addr
)
741 TCGv t0
= tcg_temp_new();
742 tcg_gen_shri_tl(t0
, cpu_gprh
[rS(ctx
->opcode
)], 16);
743 gen_qemu_st16(ctx
, t0
, addr
);
744 gen_addr_add(ctx
, addr
, addr
, 2);
745 gen_qemu_st16(ctx
, cpu_gprh
[rS(ctx
->opcode
)], addr
);
746 gen_addr_add(ctx
, addr
, addr
, 2);
747 tcg_gen_shri_tl(t0
, cpu_gpr
[rS(ctx
->opcode
)], 16);
748 gen_qemu_st16(ctx
, t0
, addr
);
750 gen_addr_add(ctx
, addr
, addr
, 2);
751 gen_qemu_st16(ctx
, cpu_gpr
[rS(ctx
->opcode
)], addr
);
754 static inline void gen_op_evstwhe(DisasContext
*ctx
, TCGv addr
)
756 TCGv t0
= tcg_temp_new();
757 tcg_gen_shri_tl(t0
, cpu_gprh
[rS(ctx
->opcode
)], 16);
758 gen_qemu_st16(ctx
, t0
, addr
);
759 gen_addr_add(ctx
, addr
, addr
, 2);
760 tcg_gen_shri_tl(t0
, cpu_gpr
[rS(ctx
->opcode
)], 16);
761 gen_qemu_st16(ctx
, t0
, addr
);
765 static inline void gen_op_evstwho(DisasContext
*ctx
, TCGv addr
)
767 gen_qemu_st16(ctx
, cpu_gprh
[rS(ctx
->opcode
)], addr
);
768 gen_addr_add(ctx
, addr
, addr
, 2);
769 gen_qemu_st16(ctx
, cpu_gpr
[rS(ctx
->opcode
)], addr
);
772 static inline void gen_op_evstwwe(DisasContext
*ctx
, TCGv addr
)
774 gen_qemu_st32(ctx
, cpu_gprh
[rS(ctx
->opcode
)], addr
);
777 static inline void gen_op_evstwwo(DisasContext
*ctx
, TCGv addr
)
779 gen_qemu_st32(ctx
, cpu_gpr
[rS(ctx
->opcode
)], addr
);
782 #define GEN_SPEOP_LDST(name, opc2, sh) \
783 static void glue(gen_, name)(DisasContext *ctx) \
786 if (unlikely(!ctx->spe_enabled)) { \
787 gen_exception(ctx, POWERPC_EXCP_SPEU); \
790 gen_set_access_type(ctx, ACCESS_INT); \
791 t0 = tcg_temp_new(); \
792 if (Rc(ctx->opcode)) { \
793 gen_addr_spe_imm_index(ctx, t0, sh); \
795 gen_addr_reg_index(ctx, t0); \
797 gen_op_##name(ctx, t0); \
801 GEN_SPEOP_LDST(evldd
, 0x00, 3);
802 GEN_SPEOP_LDST(evldw
, 0x01, 3);
803 GEN_SPEOP_LDST(evldh
, 0x02, 3);
804 GEN_SPEOP_LDST(evlhhesplat
, 0x04, 1);
805 GEN_SPEOP_LDST(evlhhousplat
, 0x06, 1);
806 GEN_SPEOP_LDST(evlhhossplat
, 0x07, 1);
807 GEN_SPEOP_LDST(evlwhe
, 0x08, 2);
808 GEN_SPEOP_LDST(evlwhou
, 0x0A, 2);
809 GEN_SPEOP_LDST(evlwhos
, 0x0B, 2);
810 GEN_SPEOP_LDST(evlwwsplat
, 0x0C, 2);
811 GEN_SPEOP_LDST(evlwhsplat
, 0x0E, 2);
813 GEN_SPEOP_LDST(evstdd
, 0x10, 3);
814 GEN_SPEOP_LDST(evstdw
, 0x11, 3);
815 GEN_SPEOP_LDST(evstdh
, 0x12, 3);
816 GEN_SPEOP_LDST(evstwhe
, 0x18, 2);
817 GEN_SPEOP_LDST(evstwho
, 0x1A, 2);
818 GEN_SPEOP_LDST(evstwwe
, 0x1C, 2);
819 GEN_SPEOP_LDST(evstwwo
, 0x1E, 2);
821 /* Multiply and add - TODO */
823 GEN_SPE(speundef
, evmhessf
, 0x01, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE
);//
824 GEN_SPE(speundef
, evmhossf
, 0x03, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
825 GEN_SPE(evmheumi
, evmhesmi
, 0x04, 0x10, 0x00000000, 0x00000000, PPC_SPE
);
826 GEN_SPE(speundef
, evmhesmf
, 0x05, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
827 GEN_SPE(evmhoumi
, evmhosmi
, 0x06, 0x10, 0x00000000, 0x00000000, PPC_SPE
);
828 GEN_SPE(speundef
, evmhosmf
, 0x07, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
829 GEN_SPE(speundef
, evmhessfa
, 0x11, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
830 GEN_SPE(speundef
, evmhossfa
, 0x13, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
831 GEN_SPE(evmheumia
, evmhesmia
, 0x14, 0x10, 0x00000000, 0x00000000, PPC_SPE
);
832 GEN_SPE(speundef
, evmhesmfa
, 0x15, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
833 GEN_SPE(evmhoumia
, evmhosmia
, 0x16, 0x10, 0x00000000, 0x00000000, PPC_SPE
);
834 GEN_SPE(speundef
, evmhosmfa
, 0x17, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
836 GEN_SPE(speundef
, evmwhssf
, 0x03, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
837 GEN_SPE(evmwlumi
, speundef
, 0x04, 0x11, 0x00000000, 0xFFFFFFFF, PPC_SPE
);
838 GEN_SPE(evmwhumi
, evmwhsmi
, 0x06, 0x11, 0x00000000, 0x00000000, PPC_SPE
);
839 GEN_SPE(speundef
, evmwhsmf
, 0x07, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
840 GEN_SPE(speundef
, evmwssf
, 0x09, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
841 GEN_SPE(speundef
, evmwsmf
, 0x0D, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
842 GEN_SPE(speundef
, evmwhssfa
, 0x13, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
843 GEN_SPE(evmwlumia
, speundef
, 0x14, 0x11, 0x00000000, 0xFFFFFFFF, PPC_SPE
);
844 GEN_SPE(evmwhumia
, evmwhsmia
, 0x16, 0x11, 0x00000000, 0x00000000, PPC_SPE
);
845 GEN_SPE(speundef
, evmwhsmfa
, 0x17, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
846 GEN_SPE(speundef
, evmwssfa
, 0x19, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
847 GEN_SPE(speundef
, evmwsmfa
, 0x1D, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
849 GEN_SPE(evadduiaaw
, evaddsiaaw
, 0x00, 0x13, 0x0000F800, 0x0000F800, PPC_SPE
);
850 GEN_SPE(evsubfusiaaw
, evsubfssiaaw
, 0x01, 0x13, 0x0000F800, 0x0000F800, PPC_SPE
);
851 GEN_SPE(evaddumiaaw
, evaddsmiaaw
, 0x04, 0x13, 0x0000F800, 0x0000F800, PPC_SPE
);
852 GEN_SPE(evsubfumiaaw
, evsubfsmiaaw
, 0x05, 0x13, 0x0000F800, 0x0000F800, PPC_SPE
);
853 GEN_SPE(evdivws
, evdivwu
, 0x06, 0x13, 0x00000000, 0x00000000, PPC_SPE
);
855 GEN_SPE(evmheusiaaw
, evmhessiaaw
, 0x00, 0x14, 0x00000000, 0x00000000, PPC_SPE
);
856 GEN_SPE(speundef
, evmhessfaaw
, 0x01, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
857 GEN_SPE(evmhousiaaw
, evmhossiaaw
, 0x02, 0x14, 0x00000000, 0x00000000, PPC_SPE
);
858 GEN_SPE(speundef
, evmhossfaaw
, 0x03, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
859 GEN_SPE(evmheumiaaw
, evmhesmiaaw
, 0x04, 0x14, 0x00000000, 0x00000000, PPC_SPE
);
860 GEN_SPE(speundef
, evmhesmfaaw
, 0x05, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
861 GEN_SPE(evmhoumiaaw
, evmhosmiaaw
, 0x06, 0x14, 0x00000000, 0x00000000, PPC_SPE
);
862 GEN_SPE(speundef
, evmhosmfaaw
, 0x07, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
863 GEN_SPE(evmhegumiaa
, evmhegsmiaa
, 0x14, 0x14, 0x00000000, 0x00000000, PPC_SPE
);
864 GEN_SPE(speundef
, evmhegsmfaa
, 0x15, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
865 GEN_SPE(evmhogumiaa
, evmhogsmiaa
, 0x16, 0x14, 0x00000000, 0x00000000, PPC_SPE
);
866 GEN_SPE(speundef
, evmhogsmfaa
, 0x17, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
868 GEN_SPE(evmwlusiaaw
, evmwlssiaaw
, 0x00, 0x15, 0x00000000, 0x00000000, PPC_SPE
);
869 GEN_SPE(evmwlumiaaw
, evmwlsmiaaw
, 0x04, 0x15, 0x00000000, 0x00000000, PPC_SPE
);
870 GEN_SPE(speundef
, evmwssfaa
, 0x09, 0x15, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
871 GEN_SPE(speundef
, evmwsmfaa
, 0x0D, 0x15, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
873 GEN_SPE(evmheusianw
, evmhessianw
, 0x00, 0x16, 0x00000000, 0x00000000, PPC_SPE
);
874 GEN_SPE(speundef
, evmhessfanw
, 0x01, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
875 GEN_SPE(evmhousianw
, evmhossianw
, 0x02, 0x16, 0x00000000, 0x00000000, PPC_SPE
);
876 GEN_SPE(speundef
, evmhossfanw
, 0x03, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
877 GEN_SPE(evmheumianw
, evmhesmianw
, 0x04, 0x16, 0x00000000, 0x00000000, PPC_SPE
);
878 GEN_SPE(speundef
, evmhesmfanw
, 0x05, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
879 GEN_SPE(evmhoumianw
, evmhosmianw
, 0x06, 0x16, 0x00000000, 0x00000000, PPC_SPE
);
880 GEN_SPE(speundef
, evmhosmfanw
, 0x07, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
881 GEN_SPE(evmhegumian
, evmhegsmian
, 0x14, 0x16, 0x00000000, 0x00000000, PPC_SPE
);
882 GEN_SPE(speundef
, evmhegsmfan
, 0x15, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
883 GEN_SPE(evmhigumian
, evmhigsmian
, 0x16, 0x16, 0x00000000, 0x00000000, PPC_SPE
);
884 GEN_SPE(speundef
, evmhogsmfan
, 0x17, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
886 GEN_SPE(evmwlusianw
, evmwlssianw
, 0x00, 0x17, 0x00000000, 0x00000000, PPC_SPE
);
887 GEN_SPE(evmwlumianw
, evmwlsmianw
, 0x04, 0x17, 0x00000000, 0x00000000, PPC_SPE
);
888 GEN_SPE(speundef
, evmwssfan
, 0x09, 0x17, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
889 GEN_SPE(evmwumian
, evmwsmian
, 0x0C, 0x17, 0x00000000, 0x00000000, PPC_SPE
);
890 GEN_SPE(speundef
, evmwsmfan
, 0x0D, 0x17, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
893 /*** SPE floating-point extension ***/
894 #define GEN_SPEFPUOP_CONV_32_32(name) \
895 static inline void gen_##name(DisasContext *ctx) \
897 TCGv_i32 t0 = tcg_temp_new_i32(); \
898 tcg_gen_trunc_tl_i32(t0, cpu_gpr[rB(ctx->opcode)]); \
899 gen_helper_##name(t0, cpu_env, t0); \
900 tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0); \
901 tcg_temp_free_i32(t0); \
903 #define GEN_SPEFPUOP_CONV_32_64(name) \
904 static inline void gen_##name(DisasContext *ctx) \
906 TCGv_i64 t0 = tcg_temp_new_i64(); \
907 TCGv_i32 t1 = tcg_temp_new_i32(); \
908 gen_load_gpr64(t0, rB(ctx->opcode)); \
909 gen_helper_##name(t1, cpu_env, t0); \
910 tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t1); \
911 tcg_temp_free_i64(t0); \
912 tcg_temp_free_i32(t1); \
914 #define GEN_SPEFPUOP_CONV_64_32(name) \
915 static inline void gen_##name(DisasContext *ctx) \
917 TCGv_i64 t0 = tcg_temp_new_i64(); \
918 TCGv_i32 t1 = tcg_temp_new_i32(); \
919 tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]); \
920 gen_helper_##name(t0, cpu_env, t1); \
921 gen_store_gpr64(rD(ctx->opcode), t0); \
922 tcg_temp_free_i64(t0); \
923 tcg_temp_free_i32(t1); \
925 #define GEN_SPEFPUOP_CONV_64_64(name) \
926 static inline void gen_##name(DisasContext *ctx) \
928 TCGv_i64 t0 = tcg_temp_new_i64(); \
929 gen_load_gpr64(t0, rB(ctx->opcode)); \
930 gen_helper_##name(t0, cpu_env, t0); \
931 gen_store_gpr64(rD(ctx->opcode), t0); \
932 tcg_temp_free_i64(t0); \
934 #define GEN_SPEFPUOP_ARITH2_32_32(name) \
935 static inline void gen_##name(DisasContext *ctx) \
938 if (unlikely(!ctx->spe_enabled)) { \
939 gen_exception(ctx, POWERPC_EXCP_SPEU); \
942 t0 = tcg_temp_new_i32(); \
943 t1 = tcg_temp_new_i32(); \
944 tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]); \
945 tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]); \
946 gen_helper_##name(t0, cpu_env, t0, t1); \
947 tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0); \
949 tcg_temp_free_i32(t0); \
950 tcg_temp_free_i32(t1); \
952 #define GEN_SPEFPUOP_ARITH2_64_64(name) \
953 static inline void gen_##name(DisasContext *ctx) \
956 if (unlikely(!ctx->spe_enabled)) { \
957 gen_exception(ctx, POWERPC_EXCP_SPEU); \
960 t0 = tcg_temp_new_i64(); \
961 t1 = tcg_temp_new_i64(); \
962 gen_load_gpr64(t0, rA(ctx->opcode)); \
963 gen_load_gpr64(t1, rB(ctx->opcode)); \
964 gen_helper_##name(t0, cpu_env, t0, t1); \
965 gen_store_gpr64(rD(ctx->opcode), t0); \
966 tcg_temp_free_i64(t0); \
967 tcg_temp_free_i64(t1); \
969 #define GEN_SPEFPUOP_COMP_32(name) \
970 static inline void gen_##name(DisasContext *ctx) \
973 if (unlikely(!ctx->spe_enabled)) { \
974 gen_exception(ctx, POWERPC_EXCP_SPEU); \
977 t0 = tcg_temp_new_i32(); \
978 t1 = tcg_temp_new_i32(); \
980 tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]); \
981 tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]); \
982 gen_helper_##name(cpu_crf[crfD(ctx->opcode)], cpu_env, t0, t1); \
984 tcg_temp_free_i32(t0); \
985 tcg_temp_free_i32(t1); \
987 #define GEN_SPEFPUOP_COMP_64(name) \
988 static inline void gen_##name(DisasContext *ctx) \
991 if (unlikely(!ctx->spe_enabled)) { \
992 gen_exception(ctx, POWERPC_EXCP_SPEU); \
995 t0 = tcg_temp_new_i64(); \
996 t1 = tcg_temp_new_i64(); \
997 gen_load_gpr64(t0, rA(ctx->opcode)); \
998 gen_load_gpr64(t1, rB(ctx->opcode)); \
999 gen_helper_##name(cpu_crf[crfD(ctx->opcode)], cpu_env, t0, t1); \
1000 tcg_temp_free_i64(t0); \
1001 tcg_temp_free_i64(t1); \
1004 /* Single precision floating-point vectors operations */
1006 GEN_SPEFPUOP_ARITH2_64_64(evfsadd
);
1007 GEN_SPEFPUOP_ARITH2_64_64(evfssub
);
1008 GEN_SPEFPUOP_ARITH2_64_64(evfsmul
);
1009 GEN_SPEFPUOP_ARITH2_64_64(evfsdiv
);
1010 static inline void gen_evfsabs(DisasContext
*ctx
)
1012 if (unlikely(!ctx
->spe_enabled
)) {
1013 gen_exception(ctx
, POWERPC_EXCP_SPEU
);
1016 tcg_gen_andi_tl(cpu_gpr
[rD(ctx
->opcode
)], cpu_gpr
[rA(ctx
->opcode
)],
1018 tcg_gen_andi_tl(cpu_gprh
[rD(ctx
->opcode
)], cpu_gprh
[rA(ctx
->opcode
)],
1021 static inline void gen_evfsnabs(DisasContext
*ctx
)
1023 if (unlikely(!ctx
->spe_enabled
)) {
1024 gen_exception(ctx
, POWERPC_EXCP_SPEU
);
1027 tcg_gen_ori_tl(cpu_gpr
[rD(ctx
->opcode
)], cpu_gpr
[rA(ctx
->opcode
)],
1029 tcg_gen_ori_tl(cpu_gprh
[rD(ctx
->opcode
)], cpu_gprh
[rA(ctx
->opcode
)],
1032 static inline void gen_evfsneg(DisasContext
*ctx
)
1034 if (unlikely(!ctx
->spe_enabled
)) {
1035 gen_exception(ctx
, POWERPC_EXCP_SPEU
);
1038 tcg_gen_xori_tl(cpu_gpr
[rD(ctx
->opcode
)], cpu_gpr
[rA(ctx
->opcode
)],
1040 tcg_gen_xori_tl(cpu_gprh
[rD(ctx
->opcode
)], cpu_gprh
[rA(ctx
->opcode
)],
1045 GEN_SPEFPUOP_CONV_64_64(evfscfui
);
1046 GEN_SPEFPUOP_CONV_64_64(evfscfsi
);
1047 GEN_SPEFPUOP_CONV_64_64(evfscfuf
);
1048 GEN_SPEFPUOP_CONV_64_64(evfscfsf
);
1049 GEN_SPEFPUOP_CONV_64_64(evfsctui
);
1050 GEN_SPEFPUOP_CONV_64_64(evfsctsi
);
1051 GEN_SPEFPUOP_CONV_64_64(evfsctuf
);
1052 GEN_SPEFPUOP_CONV_64_64(evfsctsf
);
1053 GEN_SPEFPUOP_CONV_64_64(evfsctuiz
);
1054 GEN_SPEFPUOP_CONV_64_64(evfsctsiz
);
1057 GEN_SPEFPUOP_COMP_64(evfscmpgt
);
1058 GEN_SPEFPUOP_COMP_64(evfscmplt
);
1059 GEN_SPEFPUOP_COMP_64(evfscmpeq
);
1060 GEN_SPEFPUOP_COMP_64(evfststgt
);
1061 GEN_SPEFPUOP_COMP_64(evfststlt
);
1062 GEN_SPEFPUOP_COMP_64(evfststeq
);
1064 /* Opcodes definitions */
1065 GEN_SPE(evfsadd
, evfssub
, 0x00, 0x0A, 0x00000000, 0x00000000, PPC_SPE_SINGLE
); //
1066 GEN_SPE(evfsabs
, evfsnabs
, 0x02, 0x0A, 0x0000F800, 0x0000F800, PPC_SPE_SINGLE
); //
1067 GEN_SPE(evfsneg
, speundef
, 0x03, 0x0A, 0x0000F800, 0xFFFFFFFF, PPC_SPE_SINGLE
); //
1068 GEN_SPE(evfsmul
, evfsdiv
, 0x04, 0x0A, 0x00000000, 0x00000000, PPC_SPE_SINGLE
); //
1069 GEN_SPE(evfscmpgt
, evfscmplt
, 0x06, 0x0A, 0x00600000, 0x00600000, PPC_SPE_SINGLE
); //
1070 GEN_SPE(evfscmpeq
, speundef
, 0x07, 0x0A, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE
); //
1071 GEN_SPE(evfscfui
, evfscfsi
, 0x08, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE
); //
1072 GEN_SPE(evfscfuf
, evfscfsf
, 0x09, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE
); //
1073 GEN_SPE(evfsctui
, evfsctsi
, 0x0A, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE
); //
1074 GEN_SPE(evfsctuf
, evfsctsf
, 0x0B, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE
); //
1075 GEN_SPE(evfsctuiz
, speundef
, 0x0C, 0x0A, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE
); //
1076 GEN_SPE(evfsctsiz
, speundef
, 0x0D, 0x0A, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE
); //
1077 GEN_SPE(evfststgt
, evfststlt
, 0x0E, 0x0A, 0x00600000, 0x00600000, PPC_SPE_SINGLE
); //
1078 GEN_SPE(evfststeq
, speundef
, 0x0F, 0x0A, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE
); //
1080 /* Single precision floating-point operations */
1082 GEN_SPEFPUOP_ARITH2_32_32(efsadd
);
1083 GEN_SPEFPUOP_ARITH2_32_32(efssub
);
1084 GEN_SPEFPUOP_ARITH2_32_32(efsmul
);
1085 GEN_SPEFPUOP_ARITH2_32_32(efsdiv
);
1086 static inline void gen_efsabs(DisasContext
*ctx
)
1088 if (unlikely(!ctx
->spe_enabled
)) {
1089 gen_exception(ctx
, POWERPC_EXCP_SPEU
);
1092 tcg_gen_andi_tl(cpu_gpr
[rD(ctx
->opcode
)], cpu_gpr
[rA(ctx
->opcode
)], (target_long
)~0x80000000LL
);
1094 static inline void gen_efsnabs(DisasContext
*ctx
)
1096 if (unlikely(!ctx
->spe_enabled
)) {
1097 gen_exception(ctx
, POWERPC_EXCP_SPEU
);
1100 tcg_gen_ori_tl(cpu_gpr
[rD(ctx
->opcode
)], cpu_gpr
[rA(ctx
->opcode
)], 0x80000000);
1102 static inline void gen_efsneg(DisasContext
*ctx
)
1104 if (unlikely(!ctx
->spe_enabled
)) {
1105 gen_exception(ctx
, POWERPC_EXCP_SPEU
);
1108 tcg_gen_xori_tl(cpu_gpr
[rD(ctx
->opcode
)], cpu_gpr
[rA(ctx
->opcode
)], 0x80000000);
1112 GEN_SPEFPUOP_CONV_32_32(efscfui
);
1113 GEN_SPEFPUOP_CONV_32_32(efscfsi
);
1114 GEN_SPEFPUOP_CONV_32_32(efscfuf
);
1115 GEN_SPEFPUOP_CONV_32_32(efscfsf
);
1116 GEN_SPEFPUOP_CONV_32_32(efsctui
);
1117 GEN_SPEFPUOP_CONV_32_32(efsctsi
);
1118 GEN_SPEFPUOP_CONV_32_32(efsctuf
);
1119 GEN_SPEFPUOP_CONV_32_32(efsctsf
);
1120 GEN_SPEFPUOP_CONV_32_32(efsctuiz
);
1121 GEN_SPEFPUOP_CONV_32_32(efsctsiz
);
1122 GEN_SPEFPUOP_CONV_32_64(efscfd
);
1125 GEN_SPEFPUOP_COMP_32(efscmpgt
);
1126 GEN_SPEFPUOP_COMP_32(efscmplt
);
1127 GEN_SPEFPUOP_COMP_32(efscmpeq
);
1128 GEN_SPEFPUOP_COMP_32(efststgt
);
1129 GEN_SPEFPUOP_COMP_32(efststlt
);
1130 GEN_SPEFPUOP_COMP_32(efststeq
);
1132 /* Opcodes definitions */
1133 GEN_SPE(efsadd
, efssub
, 0x00, 0x0B, 0x00000000, 0x00000000, PPC_SPE_SINGLE
); //
1134 GEN_SPE(efsabs
, efsnabs
, 0x02, 0x0B, 0x0000F800, 0x0000F800, PPC_SPE_SINGLE
); //
1135 GEN_SPE(efsneg
, speundef
, 0x03, 0x0B, 0x0000F800, 0xFFFFFFFF, PPC_SPE_SINGLE
); //
1136 GEN_SPE(efsmul
, efsdiv
, 0x04, 0x0B, 0x00000000, 0x00000000, PPC_SPE_SINGLE
); //
1137 GEN_SPE(efscmpgt
, efscmplt
, 0x06, 0x0B, 0x00600000, 0x00600000, PPC_SPE_SINGLE
); //
1138 GEN_SPE(efscmpeq
, efscfd
, 0x07, 0x0B, 0x00600000, 0x00180000, PPC_SPE_SINGLE
); //
1139 GEN_SPE(efscfui
, efscfsi
, 0x08, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE
); //
1140 GEN_SPE(efscfuf
, efscfsf
, 0x09, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE
); //
1141 GEN_SPE(efsctui
, efsctsi
, 0x0A, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE
); //
1142 GEN_SPE(efsctuf
, efsctsf
, 0x0B, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE
); //
1143 GEN_SPE(efsctuiz
, speundef
, 0x0C, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE
); //
1144 GEN_SPE(efsctsiz
, speundef
, 0x0D, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE
); //
1145 GEN_SPE(efststgt
, efststlt
, 0x0E, 0x0B, 0x00600000, 0x00600000, PPC_SPE_SINGLE
); //
1146 GEN_SPE(efststeq
, speundef
, 0x0F, 0x0B, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE
); //
1148 /* Double precision floating-point operations */
1150 GEN_SPEFPUOP_ARITH2_64_64(efdadd
);
1151 GEN_SPEFPUOP_ARITH2_64_64(efdsub
);
1152 GEN_SPEFPUOP_ARITH2_64_64(efdmul
);
1153 GEN_SPEFPUOP_ARITH2_64_64(efddiv
);
1154 static inline void gen_efdabs(DisasContext
*ctx
)
1156 if (unlikely(!ctx
->spe_enabled
)) {
1157 gen_exception(ctx
, POWERPC_EXCP_SPEU
);
1160 tcg_gen_mov_tl(cpu_gpr
[rD(ctx
->opcode
)], cpu_gpr
[rA(ctx
->opcode
)]);
1161 tcg_gen_andi_tl(cpu_gprh
[rD(ctx
->opcode
)], cpu_gprh
[rA(ctx
->opcode
)],
1164 static inline void gen_efdnabs(DisasContext
*ctx
)
1166 if (unlikely(!ctx
->spe_enabled
)) {
1167 gen_exception(ctx
, POWERPC_EXCP_SPEU
);
1170 tcg_gen_mov_tl(cpu_gpr
[rD(ctx
->opcode
)], cpu_gpr
[rA(ctx
->opcode
)]);
1171 tcg_gen_ori_tl(cpu_gprh
[rD(ctx
->opcode
)], cpu_gprh
[rA(ctx
->opcode
)],
1174 static inline void gen_efdneg(DisasContext
*ctx
)
1176 if (unlikely(!ctx
->spe_enabled
)) {
1177 gen_exception(ctx
, POWERPC_EXCP_SPEU
);
1180 tcg_gen_mov_tl(cpu_gpr
[rD(ctx
->opcode
)], cpu_gpr
[rA(ctx
->opcode
)]);
1181 tcg_gen_xori_tl(cpu_gprh
[rD(ctx
->opcode
)], cpu_gprh
[rA(ctx
->opcode
)],
1186 GEN_SPEFPUOP_CONV_64_32(efdcfui
);
1187 GEN_SPEFPUOP_CONV_64_32(efdcfsi
);
1188 GEN_SPEFPUOP_CONV_64_32(efdcfuf
);
1189 GEN_SPEFPUOP_CONV_64_32(efdcfsf
);
1190 GEN_SPEFPUOP_CONV_32_64(efdctui
);
1191 GEN_SPEFPUOP_CONV_32_64(efdctsi
);
1192 GEN_SPEFPUOP_CONV_32_64(efdctuf
);
1193 GEN_SPEFPUOP_CONV_32_64(efdctsf
);
1194 GEN_SPEFPUOP_CONV_32_64(efdctuiz
);
1195 GEN_SPEFPUOP_CONV_32_64(efdctsiz
);
1196 GEN_SPEFPUOP_CONV_64_32(efdcfs
);
1197 GEN_SPEFPUOP_CONV_64_64(efdcfuid
);
1198 GEN_SPEFPUOP_CONV_64_64(efdcfsid
);
1199 GEN_SPEFPUOP_CONV_64_64(efdctuidz
);
1200 GEN_SPEFPUOP_CONV_64_64(efdctsidz
);
1203 GEN_SPEFPUOP_COMP_64(efdcmpgt
);
1204 GEN_SPEFPUOP_COMP_64(efdcmplt
);
1205 GEN_SPEFPUOP_COMP_64(efdcmpeq
);
1206 GEN_SPEFPUOP_COMP_64(efdtstgt
);
1207 GEN_SPEFPUOP_COMP_64(efdtstlt
);
1208 GEN_SPEFPUOP_COMP_64(efdtsteq
);
1210 /* Opcodes definitions */
1211 GEN_SPE(efdadd
, efdsub
, 0x10, 0x0B, 0x00000000, 0x00000000, PPC_SPE_DOUBLE
); //
1212 GEN_SPE(efdcfuid
, efdcfsid
, 0x11, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE
); //
1213 GEN_SPE(efdabs
, efdnabs
, 0x12, 0x0B, 0x0000F800, 0x0000F800, PPC_SPE_DOUBLE
); //
1214 GEN_SPE(efdneg
, speundef
, 0x13, 0x0B, 0x0000F800, 0xFFFFFFFF, PPC_SPE_DOUBLE
); //
1215 GEN_SPE(efdmul
, efddiv
, 0x14, 0x0B, 0x00000000, 0x00000000, PPC_SPE_DOUBLE
); //
1216 GEN_SPE(efdctuidz
, efdctsidz
, 0x15, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE
); //
1217 GEN_SPE(efdcmpgt
, efdcmplt
, 0x16, 0x0B, 0x00600000, 0x00600000, PPC_SPE_DOUBLE
); //
1218 GEN_SPE(efdcmpeq
, efdcfs
, 0x17, 0x0B, 0x00600000, 0x00180000, PPC_SPE_DOUBLE
); //
1219 GEN_SPE(efdcfui
, efdcfsi
, 0x18, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE
); //
1220 GEN_SPE(efdcfuf
, efdcfsf
, 0x19, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE
); //
1221 GEN_SPE(efdctui
, efdctsi
, 0x1A, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE
); //
1222 GEN_SPE(efdctuf
, efdctsf
, 0x1B, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE
); //
1223 GEN_SPE(efdctuiz
, speundef
, 0x1C, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_DOUBLE
); //
1224 GEN_SPE(efdctsiz
, speundef
, 0x1D, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_DOUBLE
); //
1225 GEN_SPE(efdtstgt
, efdtstlt
, 0x1E, 0x0B, 0x00600000, 0x00600000, PPC_SPE_DOUBLE
); //
1226 GEN_SPE(efdtsteq
, speundef
, 0x1F, 0x0B, 0x00600000, 0xFFFFFFFF, PPC_SPE_DOUBLE
); //
1229 #undef GEN_SPEOP_LDST