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
)],
22 cpu_gprh
[rA(ctx
->opcode
)]);
25 tcg_gen_st_i64(tmp
, cpu_env
, offsetof(CPUPPCState
, spe_acc
));
26 tcg_temp_free_i64(tmp
);
29 tcg_gen_mov_tl(cpu_gpr
[rD(ctx
->opcode
)], cpu_gpr
[rA(ctx
->opcode
)]);
30 tcg_gen_mov_tl(cpu_gprh
[rD(ctx
->opcode
)], cpu_gprh
[rA(ctx
->opcode
)]);
33 static inline void gen_load_gpr64(TCGv_i64 t
, int reg
)
35 tcg_gen_concat_tl_i64(t
, cpu_gpr
[reg
], cpu_gprh
[reg
]);
38 static inline void gen_store_gpr64(int reg
, TCGv_i64 t
)
40 tcg_gen_extr_i64_tl(cpu_gpr
[reg
], cpu_gprh
[reg
], t
);
43 #define GEN_SPE(name0, name1, opc2, opc3, inval0, inval1, type) \
44 static void glue(gen_, name0##_##name1)(DisasContext *ctx) \
46 if (Rc(ctx->opcode)) \
52 /* Handler for undefined SPE opcodes */
53 static inline void gen_speundef(DisasContext
*ctx
)
55 gen_inval_exception(ctx
, POWERPC_EXCP_INVAL_INVAL
);
59 #define GEN_SPEOP_LOGIC2(name, tcg_op) \
60 static inline void gen_##name(DisasContext *ctx) \
62 if (unlikely(!ctx->spe_enabled)) { \
63 gen_exception(ctx, POWERPC_EXCP_SPEU); \
66 tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], \
67 cpu_gpr[rB(ctx->opcode)]); \
68 tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], \
69 cpu_gprh[rB(ctx->opcode)]); \
72 GEN_SPEOP_LOGIC2(evand
, tcg_gen_and_tl
);
73 GEN_SPEOP_LOGIC2(evandc
, tcg_gen_andc_tl
);
74 GEN_SPEOP_LOGIC2(evxor
, tcg_gen_xor_tl
);
75 GEN_SPEOP_LOGIC2(evor
, tcg_gen_or_tl
);
76 GEN_SPEOP_LOGIC2(evnor
, tcg_gen_nor_tl
);
77 GEN_SPEOP_LOGIC2(eveqv
, tcg_gen_eqv_tl
);
78 GEN_SPEOP_LOGIC2(evorc
, tcg_gen_orc_tl
);
79 GEN_SPEOP_LOGIC2(evnand
, tcg_gen_nand_tl
);
81 /* SPE logic immediate */
82 #define GEN_SPEOP_TCG_LOGIC_IMM2(name, tcg_opi) \
83 static inline void gen_##name(DisasContext *ctx) \
86 if (unlikely(!ctx->spe_enabled)) { \
87 gen_exception(ctx, POWERPC_EXCP_SPEU); \
90 t0 = tcg_temp_new_i32(); \
92 tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]); \
93 tcg_opi(t0, t0, rB(ctx->opcode)); \
94 tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0); \
96 tcg_gen_trunc_tl_i32(t0, cpu_gprh[rA(ctx->opcode)]); \
97 tcg_opi(t0, t0, rB(ctx->opcode)); \
98 tcg_gen_extu_i32_tl(cpu_gprh[rD(ctx->opcode)], t0); \
100 tcg_temp_free_i32(t0); \
102 GEN_SPEOP_TCG_LOGIC_IMM2(evslwi
, tcg_gen_shli_i32
);
103 GEN_SPEOP_TCG_LOGIC_IMM2(evsrwiu
, tcg_gen_shri_i32
);
104 GEN_SPEOP_TCG_LOGIC_IMM2(evsrwis
, tcg_gen_sari_i32
);
105 GEN_SPEOP_TCG_LOGIC_IMM2(evrlwi
, tcg_gen_rotli_i32
);
108 #define GEN_SPEOP_ARITH1(name, tcg_op) \
109 static inline void gen_##name(DisasContext *ctx) \
112 if (unlikely(!ctx->spe_enabled)) { \
113 gen_exception(ctx, POWERPC_EXCP_SPEU); \
116 t0 = tcg_temp_new_i32(); \
118 tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]); \
120 tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0); \
122 tcg_gen_trunc_tl_i32(t0, cpu_gprh[rA(ctx->opcode)]); \
124 tcg_gen_extu_i32_tl(cpu_gprh[rD(ctx->opcode)], t0); \
126 tcg_temp_free_i32(t0); \
129 GEN_SPEOP_ARITH1(evabs
, tcg_gen_abs_i32
);
130 GEN_SPEOP_ARITH1(evneg
, tcg_gen_neg_i32
);
131 GEN_SPEOP_ARITH1(evextsb
, tcg_gen_ext8s_i32
);
132 GEN_SPEOP_ARITH1(evextsh
, tcg_gen_ext16s_i32
);
133 static inline void gen_op_evrndw(TCGv_i32 ret
, TCGv_i32 arg1
)
135 tcg_gen_addi_i32(ret
, arg1
, 0x8000);
136 tcg_gen_ext16u_i32(ret
, ret
);
138 GEN_SPEOP_ARITH1(evrndw
, gen_op_evrndw
);
139 GEN_SPEOP_ARITH1(evcntlsw
, gen_helper_cntlsw32
);
140 GEN_SPEOP_ARITH1(evcntlzw
, gen_helper_cntlzw32
);
142 #define GEN_SPEOP_ARITH2(name, tcg_op) \
143 static inline void gen_##name(DisasContext *ctx) \
146 if (unlikely(!ctx->spe_enabled)) { \
147 gen_exception(ctx, POWERPC_EXCP_SPEU); \
150 t0 = tcg_temp_new_i32(); \
151 t1 = tcg_temp_new_i32(); \
153 tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]); \
154 tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]); \
155 tcg_op(t0, t0, t1); \
156 tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0); \
158 tcg_gen_trunc_tl_i32(t0, cpu_gprh[rA(ctx->opcode)]); \
159 tcg_gen_trunc_tl_i32(t1, cpu_gprh[rB(ctx->opcode)]); \
160 tcg_op(t0, t0, t1); \
161 tcg_gen_extu_i32_tl(cpu_gprh[rD(ctx->opcode)], t0); \
163 tcg_temp_free_i32(t0); \
164 tcg_temp_free_i32(t1); \
167 static inline void gen_op_evsrwu(TCGv_i32 ret
, TCGv_i32 arg1
, TCGv_i32 arg2
)
169 TCGLabel
*l1
= gen_new_label();
170 TCGLabel
*l2
= gen_new_label();
171 TCGv_i32 t0
= tcg_temp_local_new_i32();
173 /* No error here: 6 bits are used */
174 tcg_gen_andi_i32(t0
, arg2
, 0x3F);
175 tcg_gen_brcondi_i32(TCG_COND_GE
, t0
, 32, l1
);
176 tcg_gen_shr_i32(ret
, arg1
, t0
);
179 tcg_gen_movi_i32(ret
, 0);
181 tcg_temp_free_i32(t0
);
183 GEN_SPEOP_ARITH2(evsrwu
, gen_op_evsrwu
);
184 static inline void gen_op_evsrws(TCGv_i32 ret
, TCGv_i32 arg1
, TCGv_i32 arg2
)
186 TCGLabel
*l1
= gen_new_label();
187 TCGLabel
*l2
= gen_new_label();
188 TCGv_i32 t0
= tcg_temp_local_new_i32();
190 /* No error here: 6 bits are used */
191 tcg_gen_andi_i32(t0
, arg2
, 0x3F);
192 tcg_gen_brcondi_i32(TCG_COND_GE
, t0
, 32, l1
);
193 tcg_gen_sar_i32(ret
, arg1
, t0
);
196 tcg_gen_movi_i32(ret
, 0);
198 tcg_temp_free_i32(t0
);
200 GEN_SPEOP_ARITH2(evsrws
, gen_op_evsrws
);
201 static inline void gen_op_evslw(TCGv_i32 ret
, TCGv_i32 arg1
, TCGv_i32 arg2
)
203 TCGLabel
*l1
= gen_new_label();
204 TCGLabel
*l2
= gen_new_label();
205 TCGv_i32 t0
= tcg_temp_local_new_i32();
207 /* No error here: 6 bits are used */
208 tcg_gen_andi_i32(t0
, arg2
, 0x3F);
209 tcg_gen_brcondi_i32(TCG_COND_GE
, t0
, 32, l1
);
210 tcg_gen_shl_i32(ret
, arg1
, t0
);
213 tcg_gen_movi_i32(ret
, 0);
215 tcg_temp_free_i32(t0
);
217 GEN_SPEOP_ARITH2(evslw
, gen_op_evslw
);
218 static inline void gen_op_evrlw(TCGv_i32 ret
, TCGv_i32 arg1
, TCGv_i32 arg2
)
220 TCGv_i32 t0
= tcg_temp_new_i32();
221 tcg_gen_andi_i32(t0
, arg2
, 0x1F);
222 tcg_gen_rotl_i32(ret
, arg1
, t0
);
223 tcg_temp_free_i32(t0
);
225 GEN_SPEOP_ARITH2(evrlw
, gen_op_evrlw
);
226 static inline void gen_evmergehi(DisasContext
*ctx
)
228 if (unlikely(!ctx
->spe_enabled
)) {
229 gen_exception(ctx
, POWERPC_EXCP_SPEU
);
232 tcg_gen_mov_tl(cpu_gpr
[rD(ctx
->opcode
)], cpu_gprh
[rB(ctx
->opcode
)]);
233 tcg_gen_mov_tl(cpu_gprh
[rD(ctx
->opcode
)], cpu_gprh
[rA(ctx
->opcode
)]);
235 GEN_SPEOP_ARITH2(evaddw
, tcg_gen_add_i32
);
236 static inline void gen_op_evsubf(TCGv_i32 ret
, TCGv_i32 arg1
, TCGv_i32 arg2
)
238 tcg_gen_sub_i32(ret
, arg2
, arg1
);
240 GEN_SPEOP_ARITH2(evsubfw
, gen_op_evsubf
);
242 /* SPE arithmetic immediate */
243 #define GEN_SPEOP_ARITH_IMM2(name, tcg_op) \
244 static inline void gen_##name(DisasContext *ctx) \
247 if (unlikely(!ctx->spe_enabled)) { \
248 gen_exception(ctx, POWERPC_EXCP_SPEU); \
251 t0 = tcg_temp_new_i32(); \
253 tcg_gen_trunc_tl_i32(t0, cpu_gpr[rB(ctx->opcode)]); \
254 tcg_op(t0, t0, rA(ctx->opcode)); \
255 tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0); \
257 tcg_gen_trunc_tl_i32(t0, cpu_gprh[rB(ctx->opcode)]); \
258 tcg_op(t0, t0, rA(ctx->opcode)); \
259 tcg_gen_extu_i32_tl(cpu_gprh[rD(ctx->opcode)], t0); \
261 tcg_temp_free_i32(t0); \
263 GEN_SPEOP_ARITH_IMM2(evaddiw
, tcg_gen_addi_i32
);
264 GEN_SPEOP_ARITH_IMM2(evsubifw
, tcg_gen_subi_i32
);
267 #define GEN_SPEOP_COMP(name, tcg_cond) \
268 static inline void gen_##name(DisasContext *ctx) \
270 if (unlikely(!ctx->spe_enabled)) { \
271 gen_exception(ctx, POWERPC_EXCP_SPEU); \
274 TCGLabel *l1 = gen_new_label(); \
275 TCGLabel *l2 = gen_new_label(); \
276 TCGLabel *l3 = gen_new_label(); \
277 TCGLabel *l4 = gen_new_label(); \
279 tcg_gen_ext32s_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); \
280 tcg_gen_ext32s_tl(cpu_gpr[rB(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); \
281 tcg_gen_ext32s_tl(cpu_gprh[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]); \
282 tcg_gen_ext32s_tl(cpu_gprh[rB(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]); \
284 tcg_gen_brcond_tl(tcg_cond, cpu_gpr[rA(ctx->opcode)], \
285 cpu_gpr[rB(ctx->opcode)], l1); \
286 tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)], 0); \
289 tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)], \
290 CRF_CL | CRF_CH_OR_CL | CRF_CH_AND_CL); \
292 tcg_gen_brcond_tl(tcg_cond, cpu_gprh[rA(ctx->opcode)], \
293 cpu_gprh[rB(ctx->opcode)], l3); \
294 tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], \
295 ~(CRF_CH | CRF_CH_AND_CL)); \
298 tcg_gen_ori_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], \
299 CRF_CH | CRF_CH_OR_CL); \
302 GEN_SPEOP_COMP(evcmpgtu
, TCG_COND_GTU
);
303 GEN_SPEOP_COMP(evcmpgts
, TCG_COND_GT
);
304 GEN_SPEOP_COMP(evcmpltu
, TCG_COND_LTU
);
305 GEN_SPEOP_COMP(evcmplts
, TCG_COND_LT
);
306 GEN_SPEOP_COMP(evcmpeq
, TCG_COND_EQ
);
309 static inline void gen_brinc(DisasContext
*ctx
)
311 /* Note: brinc is usable even if SPE is disabled */
312 gen_helper_brinc(cpu_gpr
[rD(ctx
->opcode
)],
313 cpu_gpr
[rA(ctx
->opcode
)], cpu_gpr
[rB(ctx
->opcode
)]);
315 static inline void gen_evmergelo(DisasContext
*ctx
)
317 if (unlikely(!ctx
->spe_enabled
)) {
318 gen_exception(ctx
, POWERPC_EXCP_SPEU
);
321 tcg_gen_mov_tl(cpu_gprh
[rD(ctx
->opcode
)], cpu_gpr
[rA(ctx
->opcode
)]);
322 tcg_gen_mov_tl(cpu_gpr
[rD(ctx
->opcode
)], cpu_gpr
[rB(ctx
->opcode
)]);
324 static inline void gen_evmergehilo(DisasContext
*ctx
)
326 if (unlikely(!ctx
->spe_enabled
)) {
327 gen_exception(ctx
, POWERPC_EXCP_SPEU
);
330 tcg_gen_mov_tl(cpu_gpr
[rD(ctx
->opcode
)], cpu_gpr
[rB(ctx
->opcode
)]);
331 tcg_gen_mov_tl(cpu_gprh
[rD(ctx
->opcode
)], cpu_gprh
[rA(ctx
->opcode
)]);
333 static inline void gen_evmergelohi(DisasContext
*ctx
)
335 if (unlikely(!ctx
->spe_enabled
)) {
336 gen_exception(ctx
, POWERPC_EXCP_SPEU
);
339 if (rD(ctx
->opcode
) == rA(ctx
->opcode
)) {
340 TCGv tmp
= tcg_temp_new();
341 tcg_gen_mov_tl(tmp
, cpu_gpr
[rA(ctx
->opcode
)]);
342 tcg_gen_mov_tl(cpu_gpr
[rD(ctx
->opcode
)], cpu_gprh
[rB(ctx
->opcode
)]);
343 tcg_gen_mov_tl(cpu_gprh
[rD(ctx
->opcode
)], tmp
);
346 tcg_gen_mov_tl(cpu_gpr
[rD(ctx
->opcode
)], cpu_gprh
[rB(ctx
->opcode
)]);
347 tcg_gen_mov_tl(cpu_gprh
[rD(ctx
->opcode
)], cpu_gpr
[rA(ctx
->opcode
)]);
350 static inline void gen_evsplati(DisasContext
*ctx
)
352 uint64_t imm
= ((int32_t)(rA(ctx
->opcode
) << 27)) >> 27;
354 tcg_gen_movi_tl(cpu_gpr
[rD(ctx
->opcode
)], imm
);
355 tcg_gen_movi_tl(cpu_gprh
[rD(ctx
->opcode
)], imm
);
357 static inline void gen_evsplatfi(DisasContext
*ctx
)
359 uint64_t imm
= rA(ctx
->opcode
) << 27;
361 tcg_gen_movi_tl(cpu_gpr
[rD(ctx
->opcode
)], imm
);
362 tcg_gen_movi_tl(cpu_gprh
[rD(ctx
->opcode
)], imm
);
365 static inline void gen_evsel(DisasContext
*ctx
)
367 TCGLabel
*l1
= gen_new_label();
368 TCGLabel
*l2
= gen_new_label();
369 TCGLabel
*l3
= gen_new_label();
370 TCGLabel
*l4
= gen_new_label();
371 TCGv_i32 t0
= tcg_temp_local_new_i32();
373 tcg_gen_andi_i32(t0
, cpu_crf
[ctx
->opcode
& 0x07], 1 << 3);
374 tcg_gen_brcondi_i32(TCG_COND_EQ
, t0
, 0, l1
);
375 tcg_gen_mov_tl(cpu_gprh
[rD(ctx
->opcode
)], cpu_gprh
[rA(ctx
->opcode
)]);
378 tcg_gen_mov_tl(cpu_gprh
[rD(ctx
->opcode
)], cpu_gprh
[rB(ctx
->opcode
)]);
380 tcg_gen_andi_i32(t0
, cpu_crf
[ctx
->opcode
& 0x07], 1 << 2);
381 tcg_gen_brcondi_i32(TCG_COND_EQ
, t0
, 0, l3
);
382 tcg_gen_mov_tl(cpu_gpr
[rD(ctx
->opcode
)], cpu_gpr
[rA(ctx
->opcode
)]);
385 tcg_gen_mov_tl(cpu_gpr
[rD(ctx
->opcode
)], cpu_gpr
[rB(ctx
->opcode
)]);
387 tcg_temp_free_i32(t0
);
390 static void gen_evsel0(DisasContext
*ctx
)
395 static void gen_evsel1(DisasContext
*ctx
)
400 static void gen_evsel2(DisasContext
*ctx
)
405 static void gen_evsel3(DisasContext
*ctx
)
412 static inline void gen_evmwumi(DisasContext
*ctx
)
416 if (unlikely(!ctx
->spe_enabled
)) {
417 gen_exception(ctx
, POWERPC_EXCP_SPEU
);
421 t0
= tcg_temp_new_i64();
422 t1
= tcg_temp_new_i64();
424 /* t0 := rA; t1 := rB */
425 tcg_gen_extu_tl_i64(t0
, cpu_gpr
[rA(ctx
->opcode
)]);
426 tcg_gen_ext32u_i64(t0
, t0
);
427 tcg_gen_extu_tl_i64(t1
, cpu_gpr
[rB(ctx
->opcode
)]);
428 tcg_gen_ext32u_i64(t1
, t1
);
430 tcg_gen_mul_i64(t0
, t0
, t1
); /* t0 := rA * rB */
432 gen_store_gpr64(rD(ctx
->opcode
), t0
); /* rD := t0 */
434 tcg_temp_free_i64(t0
);
435 tcg_temp_free_i64(t1
);
438 static inline void gen_evmwumia(DisasContext
*ctx
)
442 if (unlikely(!ctx
->spe_enabled
)) {
443 gen_exception(ctx
, POWERPC_EXCP_SPEU
);
447 gen_evmwumi(ctx
); /* rD := rA * rB */
449 tmp
= tcg_temp_new_i64();
452 gen_load_gpr64(tmp
, rD(ctx
->opcode
));
453 tcg_gen_st_i64(tmp
, cpu_env
, offsetof(CPUPPCState
, spe_acc
));
454 tcg_temp_free_i64(tmp
);
457 static inline void gen_evmwumiaa(DisasContext
*ctx
)
462 if (unlikely(!ctx
->spe_enabled
)) {
463 gen_exception(ctx
, POWERPC_EXCP_SPEU
);
467 gen_evmwumi(ctx
); /* rD := rA * rB */
469 acc
= tcg_temp_new_i64();
470 tmp
= tcg_temp_new_i64();
473 gen_load_gpr64(tmp
, rD(ctx
->opcode
));
476 tcg_gen_ld_i64(acc
, cpu_env
, offsetof(CPUPPCState
, spe_acc
));
478 /* acc := tmp + acc */
479 tcg_gen_add_i64(acc
, acc
, tmp
);
482 tcg_gen_st_i64(acc
, cpu_env
, offsetof(CPUPPCState
, spe_acc
));
485 gen_store_gpr64(rD(ctx
->opcode
), acc
);
487 tcg_temp_free_i64(acc
);
488 tcg_temp_free_i64(tmp
);
491 static inline void gen_evmwsmi(DisasContext
*ctx
)
495 if (unlikely(!ctx
->spe_enabled
)) {
496 gen_exception(ctx
, POWERPC_EXCP_SPEU
);
500 t0
= tcg_temp_new_i64();
501 t1
= tcg_temp_new_i64();
503 /* t0 := rA; t1 := rB */
504 tcg_gen_extu_tl_i64(t0
, cpu_gpr
[rA(ctx
->opcode
)]);
505 tcg_gen_ext32s_i64(t0
, t0
);
506 tcg_gen_extu_tl_i64(t1
, cpu_gpr
[rB(ctx
->opcode
)]);
507 tcg_gen_ext32s_i64(t1
, t1
);
509 tcg_gen_mul_i64(t0
, t0
, t1
); /* t0 := rA * rB */
511 gen_store_gpr64(rD(ctx
->opcode
), t0
); /* rD := t0 */
513 tcg_temp_free_i64(t0
);
514 tcg_temp_free_i64(t1
);
517 static inline void gen_evmwsmia(DisasContext
*ctx
)
521 gen_evmwsmi(ctx
); /* rD := rA * rB */
523 tmp
= tcg_temp_new_i64();
526 gen_load_gpr64(tmp
, rD(ctx
->opcode
));
527 tcg_gen_st_i64(tmp
, cpu_env
, offsetof(CPUPPCState
, spe_acc
));
529 tcg_temp_free_i64(tmp
);
532 static inline void gen_evmwsmiaa(DisasContext
*ctx
)
534 TCGv_i64 acc
= tcg_temp_new_i64();
535 TCGv_i64 tmp
= tcg_temp_new_i64();
537 gen_evmwsmi(ctx
); /* rD := rA * rB */
539 acc
= tcg_temp_new_i64();
540 tmp
= tcg_temp_new_i64();
543 gen_load_gpr64(tmp
, rD(ctx
->opcode
));
546 tcg_gen_ld_i64(acc
, cpu_env
, offsetof(CPUPPCState
, spe_acc
));
548 /* acc := tmp + acc */
549 tcg_gen_add_i64(acc
, acc
, tmp
);
552 tcg_gen_st_i64(acc
, cpu_env
, offsetof(CPUPPCState
, spe_acc
));
555 gen_store_gpr64(rD(ctx
->opcode
), acc
);
557 tcg_temp_free_i64(acc
);
558 tcg_temp_free_i64(tmp
);
561 GEN_SPE(evaddw
, speundef
, 0x00, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE
); ////
562 GEN_SPE(evaddiw
, speundef
, 0x01, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE
);
563 GEN_SPE(evsubfw
, speundef
, 0x02, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE
); ////
564 GEN_SPE(evsubifw
, speundef
, 0x03, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE
);
565 GEN_SPE(evabs
, evneg
, 0x04, 0x08, 0x0000F800, 0x0000F800, PPC_SPE
); ////
566 GEN_SPE(evextsb
, evextsh
, 0x05, 0x08, 0x0000F800, 0x0000F800, PPC_SPE
); ////
567 GEN_SPE(evrndw
, evcntlzw
, 0x06, 0x08, 0x0000F800, 0x0000F800, PPC_SPE
); ////
568 GEN_SPE(evcntlsw
, brinc
, 0x07, 0x08, 0x0000F800, 0x00000000, PPC_SPE
); //
569 GEN_SPE(evmra
, speundef
, 0x02, 0x13, 0x0000F800, 0xFFFFFFFF, PPC_SPE
);
570 GEN_SPE(speundef
, evand
, 0x08, 0x08, 0xFFFFFFFF, 0x00000000, PPC_SPE
); ////
571 GEN_SPE(evandc
, speundef
, 0x09, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE
); ////
572 GEN_SPE(evxor
, evor
, 0x0B, 0x08, 0x00000000, 0x00000000, PPC_SPE
); ////
573 GEN_SPE(evnor
, eveqv
, 0x0C, 0x08, 0x00000000, 0x00000000, PPC_SPE
); ////
574 GEN_SPE(evmwumi
, evmwsmi
, 0x0C, 0x11, 0x00000000, 0x00000000, PPC_SPE
);
575 GEN_SPE(evmwumia
, evmwsmia
, 0x1C, 0x11, 0x00000000, 0x00000000, PPC_SPE
);
576 GEN_SPE(evmwumiaa
, evmwsmiaa
, 0x0C, 0x15, 0x00000000, 0x00000000, PPC_SPE
);
577 GEN_SPE(speundef
, evorc
, 0x0D, 0x08, 0xFFFFFFFF, 0x00000000, PPC_SPE
); ////
578 GEN_SPE(evnand
, speundef
, 0x0F, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE
); ////
579 GEN_SPE(evsrwu
, evsrws
, 0x10, 0x08, 0x00000000, 0x00000000, PPC_SPE
); ////
580 GEN_SPE(evsrwiu
, evsrwis
, 0x11, 0x08, 0x00000000, 0x00000000, PPC_SPE
);
581 GEN_SPE(evslw
, speundef
, 0x12, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE
); ////
582 GEN_SPE(evslwi
, speundef
, 0x13, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE
);
583 GEN_SPE(evrlw
, evsplati
, 0x14, 0x08, 0x00000000, 0x0000F800, PPC_SPE
); //
584 GEN_SPE(evrlwi
, evsplatfi
, 0x15, 0x08, 0x00000000, 0x0000F800, PPC_SPE
);
585 GEN_SPE(evmergehi
, evmergelo
, 0x16, 0x08, 0x00000000, 0x00000000, PPC_SPE
); ////
586 GEN_SPE(evmergehilo
, evmergelohi
, 0x17, 0x08, 0x00000000, 0x00000000, PPC_SPE
); ////
587 GEN_SPE(evcmpgtu
, evcmpgts
, 0x18, 0x08, 0x00600000, 0x00600000, PPC_SPE
); ////
588 GEN_SPE(evcmpltu
, evcmplts
, 0x19, 0x08, 0x00600000, 0x00600000, PPC_SPE
); ////
589 GEN_SPE(evcmpeq
, speundef
, 0x1A, 0x08, 0x00600000, 0xFFFFFFFF, PPC_SPE
); ////
591 /* SPE load and stores */
592 static inline void gen_addr_spe_imm_index(DisasContext
*ctx
, TCGv EA
, int sh
)
594 target_ulong uimm
= rB(ctx
->opcode
);
596 if (rA(ctx
->opcode
) == 0) {
597 tcg_gen_movi_tl(EA
, uimm
<< sh
);
599 tcg_gen_addi_tl(EA
, cpu_gpr
[rA(ctx
->opcode
)], uimm
<< sh
);
600 if (NARROW_MODE(ctx
)) {
601 tcg_gen_ext32u_tl(EA
, EA
);
606 static inline void gen_op_evldd(DisasContext
*ctx
, TCGv addr
)
608 TCGv_i64 t0
= tcg_temp_new_i64();
609 gen_qemu_ld64_i64(ctx
, t0
, addr
);
610 gen_store_gpr64(rD(ctx
->opcode
), t0
);
611 tcg_temp_free_i64(t0
);
614 static inline void gen_op_evldw(DisasContext
*ctx
, TCGv addr
)
616 gen_qemu_ld32u(ctx
, cpu_gprh
[rD(ctx
->opcode
)], addr
);
617 gen_addr_add(ctx
, addr
, addr
, 4);
618 gen_qemu_ld32u(ctx
, cpu_gpr
[rD(ctx
->opcode
)], addr
);
621 static inline void gen_op_evldh(DisasContext
*ctx
, TCGv addr
)
623 TCGv t0
= tcg_temp_new();
624 gen_qemu_ld16u(ctx
, t0
, addr
);
625 tcg_gen_shli_tl(cpu_gprh
[rD(ctx
->opcode
)], t0
, 16);
626 gen_addr_add(ctx
, addr
, addr
, 2);
627 gen_qemu_ld16u(ctx
, t0
, addr
);
628 tcg_gen_or_tl(cpu_gprh
[rD(ctx
->opcode
)], cpu_gprh
[rD(ctx
->opcode
)], t0
);
629 gen_addr_add(ctx
, addr
, addr
, 2);
630 gen_qemu_ld16u(ctx
, t0
, addr
);
631 tcg_gen_shli_tl(cpu_gprh
[rD(ctx
->opcode
)], t0
, 16);
632 gen_addr_add(ctx
, addr
, addr
, 2);
633 gen_qemu_ld16u(ctx
, t0
, addr
);
634 tcg_gen_or_tl(cpu_gpr
[rD(ctx
->opcode
)], cpu_gpr
[rD(ctx
->opcode
)], t0
);
638 static inline void gen_op_evlhhesplat(DisasContext
*ctx
, TCGv addr
)
640 TCGv t0
= tcg_temp_new();
641 gen_qemu_ld16u(ctx
, t0
, addr
);
642 tcg_gen_shli_tl(t0
, t0
, 16);
643 tcg_gen_mov_tl(cpu_gprh
[rD(ctx
->opcode
)], t0
);
644 tcg_gen_mov_tl(cpu_gpr
[rD(ctx
->opcode
)], t0
);
648 static inline void gen_op_evlhhousplat(DisasContext
*ctx
, TCGv addr
)
650 TCGv t0
= tcg_temp_new();
651 gen_qemu_ld16u(ctx
, t0
, addr
);
652 tcg_gen_mov_tl(cpu_gprh
[rD(ctx
->opcode
)], t0
);
653 tcg_gen_mov_tl(cpu_gpr
[rD(ctx
->opcode
)], t0
);
657 static inline void gen_op_evlhhossplat(DisasContext
*ctx
, TCGv addr
)
659 TCGv t0
= tcg_temp_new();
660 gen_qemu_ld16s(ctx
, t0
, addr
);
661 tcg_gen_mov_tl(cpu_gprh
[rD(ctx
->opcode
)], t0
);
662 tcg_gen_mov_tl(cpu_gpr
[rD(ctx
->opcode
)], t0
);
666 static inline void gen_op_evlwhe(DisasContext
*ctx
, TCGv addr
)
668 TCGv t0
= tcg_temp_new();
669 gen_qemu_ld16u(ctx
, t0
, addr
);
670 tcg_gen_shli_tl(cpu_gprh
[rD(ctx
->opcode
)], t0
, 16);
671 gen_addr_add(ctx
, addr
, addr
, 2);
672 gen_qemu_ld16u(ctx
, t0
, addr
);
673 tcg_gen_shli_tl(cpu_gpr
[rD(ctx
->opcode
)], t0
, 16);
677 static inline void gen_op_evlwhou(DisasContext
*ctx
, TCGv addr
)
679 gen_qemu_ld16u(ctx
, cpu_gprh
[rD(ctx
->opcode
)], addr
);
680 gen_addr_add(ctx
, addr
, addr
, 2);
681 gen_qemu_ld16u(ctx
, cpu_gpr
[rD(ctx
->opcode
)], addr
);
684 static inline void gen_op_evlwhos(DisasContext
*ctx
, TCGv addr
)
686 gen_qemu_ld16s(ctx
, cpu_gprh
[rD(ctx
->opcode
)], addr
);
687 gen_addr_add(ctx
, addr
, addr
, 2);
688 gen_qemu_ld16s(ctx
, cpu_gpr
[rD(ctx
->opcode
)], addr
);
691 static inline void gen_op_evlwwsplat(DisasContext
*ctx
, TCGv addr
)
693 TCGv t0
= tcg_temp_new();
694 gen_qemu_ld32u(ctx
, t0
, addr
);
695 tcg_gen_mov_tl(cpu_gprh
[rD(ctx
->opcode
)], t0
);
696 tcg_gen_mov_tl(cpu_gpr
[rD(ctx
->opcode
)], t0
);
700 static inline void gen_op_evlwhsplat(DisasContext
*ctx
, TCGv addr
)
702 TCGv t0
= tcg_temp_new();
703 gen_qemu_ld16u(ctx
, t0
, addr
);
704 tcg_gen_shli_tl(cpu_gprh
[rD(ctx
->opcode
)], t0
, 16);
705 tcg_gen_or_tl(cpu_gprh
[rD(ctx
->opcode
)], cpu_gprh
[rD(ctx
->opcode
)], t0
);
706 gen_addr_add(ctx
, addr
, addr
, 2);
707 gen_qemu_ld16u(ctx
, t0
, addr
);
708 tcg_gen_shli_tl(cpu_gpr
[rD(ctx
->opcode
)], t0
, 16);
709 tcg_gen_or_tl(cpu_gpr
[rD(ctx
->opcode
)], cpu_gprh
[rD(ctx
->opcode
)], t0
);
713 static inline void gen_op_evstdd(DisasContext
*ctx
, TCGv addr
)
715 TCGv_i64 t0
= tcg_temp_new_i64();
716 gen_load_gpr64(t0
, rS(ctx
->opcode
));
717 gen_qemu_st64_i64(ctx
, t0
, addr
);
718 tcg_temp_free_i64(t0
);
721 static inline void gen_op_evstdw(DisasContext
*ctx
, TCGv addr
)
723 gen_qemu_st32(ctx
, cpu_gprh
[rS(ctx
->opcode
)], addr
);
724 gen_addr_add(ctx
, addr
, addr
, 4);
725 gen_qemu_st32(ctx
, cpu_gpr
[rS(ctx
->opcode
)], addr
);
728 static inline void gen_op_evstdh(DisasContext
*ctx
, TCGv addr
)
730 TCGv t0
= tcg_temp_new();
731 tcg_gen_shri_tl(t0
, cpu_gprh
[rS(ctx
->opcode
)], 16);
732 gen_qemu_st16(ctx
, t0
, addr
);
733 gen_addr_add(ctx
, addr
, addr
, 2);
734 gen_qemu_st16(ctx
, cpu_gprh
[rS(ctx
->opcode
)], addr
);
735 gen_addr_add(ctx
, addr
, addr
, 2);
736 tcg_gen_shri_tl(t0
, cpu_gpr
[rS(ctx
->opcode
)], 16);
737 gen_qemu_st16(ctx
, t0
, addr
);
739 gen_addr_add(ctx
, addr
, addr
, 2);
740 gen_qemu_st16(ctx
, cpu_gpr
[rS(ctx
->opcode
)], addr
);
743 static inline void gen_op_evstwhe(DisasContext
*ctx
, TCGv addr
)
745 TCGv t0
= tcg_temp_new();
746 tcg_gen_shri_tl(t0
, cpu_gprh
[rS(ctx
->opcode
)], 16);
747 gen_qemu_st16(ctx
, t0
, addr
);
748 gen_addr_add(ctx
, addr
, addr
, 2);
749 tcg_gen_shri_tl(t0
, cpu_gpr
[rS(ctx
->opcode
)], 16);
750 gen_qemu_st16(ctx
, t0
, addr
);
754 static inline void gen_op_evstwho(DisasContext
*ctx
, TCGv addr
)
756 gen_qemu_st16(ctx
, cpu_gprh
[rS(ctx
->opcode
)], addr
);
757 gen_addr_add(ctx
, addr
, addr
, 2);
758 gen_qemu_st16(ctx
, cpu_gpr
[rS(ctx
->opcode
)], addr
);
761 static inline void gen_op_evstwwe(DisasContext
*ctx
, TCGv addr
)
763 gen_qemu_st32(ctx
, cpu_gprh
[rS(ctx
->opcode
)], addr
);
766 static inline void gen_op_evstwwo(DisasContext
*ctx
, TCGv addr
)
768 gen_qemu_st32(ctx
, cpu_gpr
[rS(ctx
->opcode
)], addr
);
771 #define GEN_SPEOP_LDST(name, opc2, sh) \
772 static void glue(gen_, name)(DisasContext *ctx) \
775 if (unlikely(!ctx->spe_enabled)) { \
776 gen_exception(ctx, POWERPC_EXCP_SPEU); \
779 gen_set_access_type(ctx, ACCESS_INT); \
780 t0 = tcg_temp_new(); \
781 if (Rc(ctx->opcode)) { \
782 gen_addr_spe_imm_index(ctx, t0, sh); \
784 gen_addr_reg_index(ctx, t0); \
786 gen_op_##name(ctx, t0); \
790 GEN_SPEOP_LDST(evldd
, 0x00, 3);
791 GEN_SPEOP_LDST(evldw
, 0x01, 3);
792 GEN_SPEOP_LDST(evldh
, 0x02, 3);
793 GEN_SPEOP_LDST(evlhhesplat
, 0x04, 1);
794 GEN_SPEOP_LDST(evlhhousplat
, 0x06, 1);
795 GEN_SPEOP_LDST(evlhhossplat
, 0x07, 1);
796 GEN_SPEOP_LDST(evlwhe
, 0x08, 2);
797 GEN_SPEOP_LDST(evlwhou
, 0x0A, 2);
798 GEN_SPEOP_LDST(evlwhos
, 0x0B, 2);
799 GEN_SPEOP_LDST(evlwwsplat
, 0x0C, 2);
800 GEN_SPEOP_LDST(evlwhsplat
, 0x0E, 2);
802 GEN_SPEOP_LDST(evstdd
, 0x10, 3);
803 GEN_SPEOP_LDST(evstdw
, 0x11, 3);
804 GEN_SPEOP_LDST(evstdh
, 0x12, 3);
805 GEN_SPEOP_LDST(evstwhe
, 0x18, 2);
806 GEN_SPEOP_LDST(evstwho
, 0x1A, 2);
807 GEN_SPEOP_LDST(evstwwe
, 0x1C, 2);
808 GEN_SPEOP_LDST(evstwwo
, 0x1E, 2);
810 /* Multiply and add - TODO */
812 GEN_SPE(speundef
, evmhessf
, 0x01, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE
);//
813 GEN_SPE(speundef
, evmhossf
, 0x03, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
814 GEN_SPE(evmheumi
, evmhesmi
, 0x04, 0x10, 0x00000000, 0x00000000, PPC_SPE
);
815 GEN_SPE(speundef
, evmhesmf
, 0x05, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
816 GEN_SPE(evmhoumi
, evmhosmi
, 0x06, 0x10, 0x00000000, 0x00000000, PPC_SPE
);
817 GEN_SPE(speundef
, evmhosmf
, 0x07, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
818 GEN_SPE(speundef
, evmhessfa
, 0x11, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
819 GEN_SPE(speundef
, evmhossfa
, 0x13, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
820 GEN_SPE(evmheumia
, evmhesmia
, 0x14, 0x10, 0x00000000, 0x00000000, PPC_SPE
);
821 GEN_SPE(speundef
, evmhesmfa
, 0x15, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
822 GEN_SPE(evmhoumia
, evmhosmia
, 0x16, 0x10, 0x00000000, 0x00000000, PPC_SPE
);
823 GEN_SPE(speundef
, evmhosmfa
, 0x17, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
825 GEN_SPE(speundef
, evmwhssf
, 0x03, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
826 GEN_SPE(evmwlumi
, speundef
, 0x04, 0x11, 0x00000000, 0xFFFFFFFF, PPC_SPE
);
827 GEN_SPE(evmwhumi
, evmwhsmi
, 0x06, 0x11, 0x00000000, 0x00000000, PPC_SPE
);
828 GEN_SPE(speundef
, evmwhsmf
, 0x07, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
829 GEN_SPE(speundef
, evmwssf
, 0x09, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
830 GEN_SPE(speundef
, evmwsmf
, 0x0D, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
831 GEN_SPE(speundef
, evmwhssfa
, 0x13, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
832 GEN_SPE(evmwlumia
, speundef
, 0x14, 0x11, 0x00000000, 0xFFFFFFFF, PPC_SPE
);
833 GEN_SPE(evmwhumia
, evmwhsmia
, 0x16, 0x11, 0x00000000, 0x00000000, PPC_SPE
);
834 GEN_SPE(speundef
, evmwhsmfa
, 0x17, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
835 GEN_SPE(speundef
, evmwssfa
, 0x19, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
836 GEN_SPE(speundef
, evmwsmfa
, 0x1D, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
838 GEN_SPE(evadduiaaw
, evaddsiaaw
, 0x00, 0x13, 0x0000F800, 0x0000F800, PPC_SPE
);
839 GEN_SPE(evsubfusiaaw
, evsubfssiaaw
, 0x01, 0x13, 0x0000F800, 0x0000F800, PPC_SPE
);
840 GEN_SPE(evaddumiaaw
, evaddsmiaaw
, 0x04, 0x13, 0x0000F800, 0x0000F800, PPC_SPE
);
841 GEN_SPE(evsubfumiaaw
, evsubfsmiaaw
, 0x05, 0x13, 0x0000F800, 0x0000F800, PPC_SPE
);
842 GEN_SPE(evdivws
, evdivwu
, 0x06, 0x13, 0x00000000, 0x00000000, PPC_SPE
);
844 GEN_SPE(evmheusiaaw
, evmhessiaaw
, 0x00, 0x14, 0x00000000, 0x00000000, PPC_SPE
);
845 GEN_SPE(speundef
, evmhessfaaw
, 0x01, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
846 GEN_SPE(evmhousiaaw
, evmhossiaaw
, 0x02, 0x14, 0x00000000, 0x00000000, PPC_SPE
);
847 GEN_SPE(speundef
, evmhossfaaw
, 0x03, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
848 GEN_SPE(evmheumiaaw
, evmhesmiaaw
, 0x04, 0x14, 0x00000000, 0x00000000, PPC_SPE
);
849 GEN_SPE(speundef
, evmhesmfaaw
, 0x05, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
850 GEN_SPE(evmhoumiaaw
, evmhosmiaaw
, 0x06, 0x14, 0x00000000, 0x00000000, PPC_SPE
);
851 GEN_SPE(speundef
, evmhosmfaaw
, 0x07, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
852 GEN_SPE(evmhegumiaa
, evmhegsmiaa
, 0x14, 0x14, 0x00000000, 0x00000000, PPC_SPE
);
853 GEN_SPE(speundef
, evmhegsmfaa
, 0x15, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
854 GEN_SPE(evmhogumiaa
, evmhogsmiaa
, 0x16, 0x14, 0x00000000, 0x00000000, PPC_SPE
);
855 GEN_SPE(speundef
, evmhogsmfaa
, 0x17, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
857 GEN_SPE(evmwlusiaaw
, evmwlssiaaw
, 0x00, 0x15, 0x00000000, 0x00000000, PPC_SPE
);
858 GEN_SPE(evmwlumiaaw
, evmwlsmiaaw
, 0x04, 0x15, 0x00000000, 0x00000000, PPC_SPE
);
859 GEN_SPE(speundef
, evmwssfaa
, 0x09, 0x15, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
860 GEN_SPE(speundef
, evmwsmfaa
, 0x0D, 0x15, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
862 GEN_SPE(evmheusianw
, evmhessianw
, 0x00, 0x16, 0x00000000, 0x00000000, PPC_SPE
);
863 GEN_SPE(speundef
, evmhessfanw
, 0x01, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
864 GEN_SPE(evmhousianw
, evmhossianw
, 0x02, 0x16, 0x00000000, 0x00000000, PPC_SPE
);
865 GEN_SPE(speundef
, evmhossfanw
, 0x03, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
866 GEN_SPE(evmheumianw
, evmhesmianw
, 0x04, 0x16, 0x00000000, 0x00000000, PPC_SPE
);
867 GEN_SPE(speundef
, evmhesmfanw
, 0x05, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
868 GEN_SPE(evmhoumianw
, evmhosmianw
, 0x06, 0x16, 0x00000000, 0x00000000, PPC_SPE
);
869 GEN_SPE(speundef
, evmhosmfanw
, 0x07, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
870 GEN_SPE(evmhegumian
, evmhegsmian
, 0x14, 0x16, 0x00000000, 0x00000000, PPC_SPE
);
871 GEN_SPE(speundef
, evmhegsmfan
, 0x15, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
872 GEN_SPE(evmhigumian
, evmhigsmian
, 0x16, 0x16, 0x00000000, 0x00000000, PPC_SPE
);
873 GEN_SPE(speundef
, evmhogsmfan
, 0x17, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
875 GEN_SPE(evmwlusianw
, evmwlssianw
, 0x00, 0x17, 0x00000000, 0x00000000, PPC_SPE
);
876 GEN_SPE(evmwlumianw
, evmwlsmianw
, 0x04, 0x17, 0x00000000, 0x00000000, PPC_SPE
);
877 GEN_SPE(speundef
, evmwssfan
, 0x09, 0x17, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
878 GEN_SPE(evmwumian
, evmwsmian
, 0x0C, 0x17, 0x00000000, 0x00000000, PPC_SPE
);
879 GEN_SPE(speundef
, evmwsmfan
, 0x0D, 0x17, 0xFFFFFFFF, 0x00000000, PPC_SPE
);
882 /*** SPE floating-point extension ***/
883 #define GEN_SPEFPUOP_CONV_32_32(name) \
884 static inline void gen_##name(DisasContext *ctx) \
886 TCGv_i32 t0 = tcg_temp_new_i32(); \
887 tcg_gen_trunc_tl_i32(t0, cpu_gpr[rB(ctx->opcode)]); \
888 gen_helper_##name(t0, cpu_env, t0); \
889 tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0); \
890 tcg_temp_free_i32(t0); \
892 #define GEN_SPEFPUOP_CONV_32_64(name) \
893 static inline void gen_##name(DisasContext *ctx) \
895 TCGv_i64 t0 = tcg_temp_new_i64(); \
896 TCGv_i32 t1 = tcg_temp_new_i32(); \
897 gen_load_gpr64(t0, rB(ctx->opcode)); \
898 gen_helper_##name(t1, cpu_env, t0); \
899 tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t1); \
900 tcg_temp_free_i64(t0); \
901 tcg_temp_free_i32(t1); \
903 #define GEN_SPEFPUOP_CONV_64_32(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 tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]); \
909 gen_helper_##name(t0, cpu_env, t1); \
910 gen_store_gpr64(rD(ctx->opcode), t0); \
911 tcg_temp_free_i64(t0); \
912 tcg_temp_free_i32(t1); \
914 #define GEN_SPEFPUOP_CONV_64_64(name) \
915 static inline void gen_##name(DisasContext *ctx) \
917 TCGv_i64 t0 = tcg_temp_new_i64(); \
918 gen_load_gpr64(t0, rB(ctx->opcode)); \
919 gen_helper_##name(t0, cpu_env, t0); \
920 gen_store_gpr64(rD(ctx->opcode), t0); \
921 tcg_temp_free_i64(t0); \
923 #define GEN_SPEFPUOP_ARITH2_32_32(name) \
924 static inline void gen_##name(DisasContext *ctx) \
927 if (unlikely(!ctx->spe_enabled)) { \
928 gen_exception(ctx, POWERPC_EXCP_SPEU); \
931 t0 = tcg_temp_new_i32(); \
932 t1 = tcg_temp_new_i32(); \
933 tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]); \
934 tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]); \
935 gen_helper_##name(t0, cpu_env, t0, t1); \
936 tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0); \
938 tcg_temp_free_i32(t0); \
939 tcg_temp_free_i32(t1); \
941 #define GEN_SPEFPUOP_ARITH2_64_64(name) \
942 static inline void gen_##name(DisasContext *ctx) \
945 if (unlikely(!ctx->spe_enabled)) { \
946 gen_exception(ctx, POWERPC_EXCP_SPEU); \
949 t0 = tcg_temp_new_i64(); \
950 t1 = tcg_temp_new_i64(); \
951 gen_load_gpr64(t0, rA(ctx->opcode)); \
952 gen_load_gpr64(t1, rB(ctx->opcode)); \
953 gen_helper_##name(t0, cpu_env, t0, t1); \
954 gen_store_gpr64(rD(ctx->opcode), t0); \
955 tcg_temp_free_i64(t0); \
956 tcg_temp_free_i64(t1); \
958 #define GEN_SPEFPUOP_COMP_32(name) \
959 static inline void gen_##name(DisasContext *ctx) \
962 if (unlikely(!ctx->spe_enabled)) { \
963 gen_exception(ctx, POWERPC_EXCP_SPEU); \
966 t0 = tcg_temp_new_i32(); \
967 t1 = tcg_temp_new_i32(); \
969 tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]); \
970 tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]); \
971 gen_helper_##name(cpu_crf[crfD(ctx->opcode)], cpu_env, t0, t1); \
973 tcg_temp_free_i32(t0); \
974 tcg_temp_free_i32(t1); \
976 #define GEN_SPEFPUOP_COMP_64(name) \
977 static inline void gen_##name(DisasContext *ctx) \
980 if (unlikely(!ctx->spe_enabled)) { \
981 gen_exception(ctx, POWERPC_EXCP_SPEU); \
984 t0 = tcg_temp_new_i64(); \
985 t1 = tcg_temp_new_i64(); \
986 gen_load_gpr64(t0, rA(ctx->opcode)); \
987 gen_load_gpr64(t1, rB(ctx->opcode)); \
988 gen_helper_##name(cpu_crf[crfD(ctx->opcode)], cpu_env, t0, t1); \
989 tcg_temp_free_i64(t0); \
990 tcg_temp_free_i64(t1); \
993 /* Single precision floating-point vectors operations */
995 GEN_SPEFPUOP_ARITH2_64_64(evfsadd
);
996 GEN_SPEFPUOP_ARITH2_64_64(evfssub
);
997 GEN_SPEFPUOP_ARITH2_64_64(evfsmul
);
998 GEN_SPEFPUOP_ARITH2_64_64(evfsdiv
);
999 static inline void gen_evfsabs(DisasContext
*ctx
)
1001 if (unlikely(!ctx
->spe_enabled
)) {
1002 gen_exception(ctx
, POWERPC_EXCP_SPEU
);
1005 tcg_gen_andi_tl(cpu_gpr
[rD(ctx
->opcode
)], cpu_gpr
[rA(ctx
->opcode
)],
1007 tcg_gen_andi_tl(cpu_gprh
[rD(ctx
->opcode
)], cpu_gprh
[rA(ctx
->opcode
)],
1010 static inline void gen_evfsnabs(DisasContext
*ctx
)
1012 if (unlikely(!ctx
->spe_enabled
)) {
1013 gen_exception(ctx
, POWERPC_EXCP_SPEU
);
1016 tcg_gen_ori_tl(cpu_gpr
[rD(ctx
->opcode
)], cpu_gpr
[rA(ctx
->opcode
)],
1018 tcg_gen_ori_tl(cpu_gprh
[rD(ctx
->opcode
)], cpu_gprh
[rA(ctx
->opcode
)],
1021 static inline void gen_evfsneg(DisasContext
*ctx
)
1023 if (unlikely(!ctx
->spe_enabled
)) {
1024 gen_exception(ctx
, POWERPC_EXCP_SPEU
);
1027 tcg_gen_xori_tl(cpu_gpr
[rD(ctx
->opcode
)], cpu_gpr
[rA(ctx
->opcode
)],
1029 tcg_gen_xori_tl(cpu_gprh
[rD(ctx
->opcode
)], cpu_gprh
[rA(ctx
->opcode
)],
1034 GEN_SPEFPUOP_CONV_64_64(evfscfui
);
1035 GEN_SPEFPUOP_CONV_64_64(evfscfsi
);
1036 GEN_SPEFPUOP_CONV_64_64(evfscfuf
);
1037 GEN_SPEFPUOP_CONV_64_64(evfscfsf
);
1038 GEN_SPEFPUOP_CONV_64_64(evfsctui
);
1039 GEN_SPEFPUOP_CONV_64_64(evfsctsi
);
1040 GEN_SPEFPUOP_CONV_64_64(evfsctuf
);
1041 GEN_SPEFPUOP_CONV_64_64(evfsctsf
);
1042 GEN_SPEFPUOP_CONV_64_64(evfsctuiz
);
1043 GEN_SPEFPUOP_CONV_64_64(evfsctsiz
);
1046 GEN_SPEFPUOP_COMP_64(evfscmpgt
);
1047 GEN_SPEFPUOP_COMP_64(evfscmplt
);
1048 GEN_SPEFPUOP_COMP_64(evfscmpeq
);
1049 GEN_SPEFPUOP_COMP_64(evfststgt
);
1050 GEN_SPEFPUOP_COMP_64(evfststlt
);
1051 GEN_SPEFPUOP_COMP_64(evfststeq
);
1053 /* Opcodes definitions */
1054 GEN_SPE(evfsadd
, evfssub
, 0x00, 0x0A, 0x00000000, 0x00000000, PPC_SPE_SINGLE
); //
1055 GEN_SPE(evfsabs
, evfsnabs
, 0x02, 0x0A, 0x0000F800, 0x0000F800, PPC_SPE_SINGLE
); //
1056 GEN_SPE(evfsneg
, speundef
, 0x03, 0x0A, 0x0000F800, 0xFFFFFFFF, PPC_SPE_SINGLE
); //
1057 GEN_SPE(evfsmul
, evfsdiv
, 0x04, 0x0A, 0x00000000, 0x00000000, PPC_SPE_SINGLE
); //
1058 GEN_SPE(evfscmpgt
, evfscmplt
, 0x06, 0x0A, 0x00600000, 0x00600000, PPC_SPE_SINGLE
); //
1059 GEN_SPE(evfscmpeq
, speundef
, 0x07, 0x0A, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE
); //
1060 GEN_SPE(evfscfui
, evfscfsi
, 0x08, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE
); //
1061 GEN_SPE(evfscfuf
, evfscfsf
, 0x09, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE
); //
1062 GEN_SPE(evfsctui
, evfsctsi
, 0x0A, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE
); //
1063 GEN_SPE(evfsctuf
, evfsctsf
, 0x0B, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE
); //
1064 GEN_SPE(evfsctuiz
, speundef
, 0x0C, 0x0A, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE
); //
1065 GEN_SPE(evfsctsiz
, speundef
, 0x0D, 0x0A, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE
); //
1066 GEN_SPE(evfststgt
, evfststlt
, 0x0E, 0x0A, 0x00600000, 0x00600000, PPC_SPE_SINGLE
); //
1067 GEN_SPE(evfststeq
, speundef
, 0x0F, 0x0A, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE
); //
1069 /* Single precision floating-point operations */
1071 GEN_SPEFPUOP_ARITH2_32_32(efsadd
);
1072 GEN_SPEFPUOP_ARITH2_32_32(efssub
);
1073 GEN_SPEFPUOP_ARITH2_32_32(efsmul
);
1074 GEN_SPEFPUOP_ARITH2_32_32(efsdiv
);
1075 static inline void gen_efsabs(DisasContext
*ctx
)
1077 if (unlikely(!ctx
->spe_enabled
)) {
1078 gen_exception(ctx
, POWERPC_EXCP_SPEU
);
1081 tcg_gen_andi_tl(cpu_gpr
[rD(ctx
->opcode
)], cpu_gpr
[rA(ctx
->opcode
)],
1082 (target_long
)~0x80000000LL
);
1084 static inline void gen_efsnabs(DisasContext
*ctx
)
1086 if (unlikely(!ctx
->spe_enabled
)) {
1087 gen_exception(ctx
, POWERPC_EXCP_SPEU
);
1090 tcg_gen_ori_tl(cpu_gpr
[rD(ctx
->opcode
)], cpu_gpr
[rA(ctx
->opcode
)],
1093 static inline void gen_efsneg(DisasContext
*ctx
)
1095 if (unlikely(!ctx
->spe_enabled
)) {
1096 gen_exception(ctx
, POWERPC_EXCP_SPEU
);
1099 tcg_gen_xori_tl(cpu_gpr
[rD(ctx
->opcode
)], cpu_gpr
[rA(ctx
->opcode
)],
1104 GEN_SPEFPUOP_CONV_32_32(efscfui
);
1105 GEN_SPEFPUOP_CONV_32_32(efscfsi
);
1106 GEN_SPEFPUOP_CONV_32_32(efscfuf
);
1107 GEN_SPEFPUOP_CONV_32_32(efscfsf
);
1108 GEN_SPEFPUOP_CONV_32_32(efsctui
);
1109 GEN_SPEFPUOP_CONV_32_32(efsctsi
);
1110 GEN_SPEFPUOP_CONV_32_32(efsctuf
);
1111 GEN_SPEFPUOP_CONV_32_32(efsctsf
);
1112 GEN_SPEFPUOP_CONV_32_32(efsctuiz
);
1113 GEN_SPEFPUOP_CONV_32_32(efsctsiz
);
1114 GEN_SPEFPUOP_CONV_32_64(efscfd
);
1117 GEN_SPEFPUOP_COMP_32(efscmpgt
);
1118 GEN_SPEFPUOP_COMP_32(efscmplt
);
1119 GEN_SPEFPUOP_COMP_32(efscmpeq
);
1120 GEN_SPEFPUOP_COMP_32(efststgt
);
1121 GEN_SPEFPUOP_COMP_32(efststlt
);
1122 GEN_SPEFPUOP_COMP_32(efststeq
);
1124 /* Opcodes definitions */
1125 GEN_SPE(efsadd
, efssub
, 0x00, 0x0B, 0x00000000, 0x00000000, PPC_SPE_SINGLE
); //
1126 GEN_SPE(efsabs
, efsnabs
, 0x02, 0x0B, 0x0000F800, 0x0000F800, PPC_SPE_SINGLE
); //
1127 GEN_SPE(efsneg
, speundef
, 0x03, 0x0B, 0x0000F800, 0xFFFFFFFF, PPC_SPE_SINGLE
); //
1128 GEN_SPE(efsmul
, efsdiv
, 0x04, 0x0B, 0x00000000, 0x00000000, PPC_SPE_SINGLE
); //
1129 GEN_SPE(efscmpgt
, efscmplt
, 0x06, 0x0B, 0x00600000, 0x00600000, PPC_SPE_SINGLE
); //
1130 GEN_SPE(efscmpeq
, efscfd
, 0x07, 0x0B, 0x00600000, 0x00180000, PPC_SPE_SINGLE
); //
1131 GEN_SPE(efscfui
, efscfsi
, 0x08, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE
); //
1132 GEN_SPE(efscfuf
, efscfsf
, 0x09, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE
); //
1133 GEN_SPE(efsctui
, efsctsi
, 0x0A, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE
); //
1134 GEN_SPE(efsctuf
, efsctsf
, 0x0B, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE
); //
1135 GEN_SPE(efsctuiz
, speundef
, 0x0C, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE
); //
1136 GEN_SPE(efsctsiz
, speundef
, 0x0D, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE
); //
1137 GEN_SPE(efststgt
, efststlt
, 0x0E, 0x0B, 0x00600000, 0x00600000, PPC_SPE_SINGLE
); //
1138 GEN_SPE(efststeq
, speundef
, 0x0F, 0x0B, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE
); //
1140 /* Double precision floating-point operations */
1142 GEN_SPEFPUOP_ARITH2_64_64(efdadd
);
1143 GEN_SPEFPUOP_ARITH2_64_64(efdsub
);
1144 GEN_SPEFPUOP_ARITH2_64_64(efdmul
);
1145 GEN_SPEFPUOP_ARITH2_64_64(efddiv
);
1146 static inline void gen_efdabs(DisasContext
*ctx
)
1148 if (unlikely(!ctx
->spe_enabled
)) {
1149 gen_exception(ctx
, POWERPC_EXCP_SPEU
);
1152 tcg_gen_mov_tl(cpu_gpr
[rD(ctx
->opcode
)], cpu_gpr
[rA(ctx
->opcode
)]);
1153 tcg_gen_andi_tl(cpu_gprh
[rD(ctx
->opcode
)], cpu_gprh
[rA(ctx
->opcode
)],
1156 static inline void gen_efdnabs(DisasContext
*ctx
)
1158 if (unlikely(!ctx
->spe_enabled
)) {
1159 gen_exception(ctx
, POWERPC_EXCP_SPEU
);
1162 tcg_gen_mov_tl(cpu_gpr
[rD(ctx
->opcode
)], cpu_gpr
[rA(ctx
->opcode
)]);
1163 tcg_gen_ori_tl(cpu_gprh
[rD(ctx
->opcode
)], cpu_gprh
[rA(ctx
->opcode
)],
1166 static inline void gen_efdneg(DisasContext
*ctx
)
1168 if (unlikely(!ctx
->spe_enabled
)) {
1169 gen_exception(ctx
, POWERPC_EXCP_SPEU
);
1172 tcg_gen_mov_tl(cpu_gpr
[rD(ctx
->opcode
)], cpu_gpr
[rA(ctx
->opcode
)]);
1173 tcg_gen_xori_tl(cpu_gprh
[rD(ctx
->opcode
)], cpu_gprh
[rA(ctx
->opcode
)],
1178 GEN_SPEFPUOP_CONV_64_32(efdcfui
);
1179 GEN_SPEFPUOP_CONV_64_32(efdcfsi
);
1180 GEN_SPEFPUOP_CONV_64_32(efdcfuf
);
1181 GEN_SPEFPUOP_CONV_64_32(efdcfsf
);
1182 GEN_SPEFPUOP_CONV_32_64(efdctui
);
1183 GEN_SPEFPUOP_CONV_32_64(efdctsi
);
1184 GEN_SPEFPUOP_CONV_32_64(efdctuf
);
1185 GEN_SPEFPUOP_CONV_32_64(efdctsf
);
1186 GEN_SPEFPUOP_CONV_32_64(efdctuiz
);
1187 GEN_SPEFPUOP_CONV_32_64(efdctsiz
);
1188 GEN_SPEFPUOP_CONV_64_32(efdcfs
);
1189 GEN_SPEFPUOP_CONV_64_64(efdcfuid
);
1190 GEN_SPEFPUOP_CONV_64_64(efdcfsid
);
1191 GEN_SPEFPUOP_CONV_64_64(efdctuidz
);
1192 GEN_SPEFPUOP_CONV_64_64(efdctsidz
);
1195 GEN_SPEFPUOP_COMP_64(efdcmpgt
);
1196 GEN_SPEFPUOP_COMP_64(efdcmplt
);
1197 GEN_SPEFPUOP_COMP_64(efdcmpeq
);
1198 GEN_SPEFPUOP_COMP_64(efdtstgt
);
1199 GEN_SPEFPUOP_COMP_64(efdtstlt
);
1200 GEN_SPEFPUOP_COMP_64(efdtsteq
);
1202 /* Opcodes definitions */
1203 GEN_SPE(efdadd
, efdsub
, 0x10, 0x0B, 0x00000000, 0x00000000, PPC_SPE_DOUBLE
); //
1204 GEN_SPE(efdcfuid
, efdcfsid
, 0x11, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE
); //
1205 GEN_SPE(efdabs
, efdnabs
, 0x12, 0x0B, 0x0000F800, 0x0000F800, PPC_SPE_DOUBLE
); //
1206 GEN_SPE(efdneg
, speundef
, 0x13, 0x0B, 0x0000F800, 0xFFFFFFFF, PPC_SPE_DOUBLE
); //
1207 GEN_SPE(efdmul
, efddiv
, 0x14, 0x0B, 0x00000000, 0x00000000, PPC_SPE_DOUBLE
); //
1208 GEN_SPE(efdctuidz
, efdctsidz
, 0x15, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE
); //
1209 GEN_SPE(efdcmpgt
, efdcmplt
, 0x16, 0x0B, 0x00600000, 0x00600000, PPC_SPE_DOUBLE
); //
1210 GEN_SPE(efdcmpeq
, efdcfs
, 0x17, 0x0B, 0x00600000, 0x00180000, PPC_SPE_DOUBLE
); //
1211 GEN_SPE(efdcfui
, efdcfsi
, 0x18, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE
); //
1212 GEN_SPE(efdcfuf
, efdcfsf
, 0x19, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE
); //
1213 GEN_SPE(efdctui
, efdctsi
, 0x1A, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE
); //
1214 GEN_SPE(efdctuf
, efdctsf
, 0x1B, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE
); //
1215 GEN_SPE(efdctuiz
, speundef
, 0x1C, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_DOUBLE
); //
1216 GEN_SPE(efdctsiz
, speundef
, 0x1D, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_DOUBLE
); //
1217 GEN_SPE(efdtstgt
, efdtstlt
, 0x1E, 0x0B, 0x00600000, 0x00600000, PPC_SPE_DOUBLE
); //
1218 GEN_SPE(efdtsteq
, speundef
, 0x1F, 0x0B, 0x00600000, 0xFFFFFFFF, PPC_SPE_DOUBLE
); //
1221 #undef GEN_SPEOP_LDST