e2k: Implement basic v6 support.

Not tested on a real hardware.

Signed-off-by: Denis Drakhnya <numas13@gmail.com>
This commit is contained in:
Denis Drakhnia 2021-03-13 15:22:02 +02:00 committed by Denis Drakhnia
parent 401ccafc8c
commit 6cbcdc4d5c
5 changed files with 343 additions and 61 deletions

View File

@ -799,6 +799,7 @@ enum {
OP_PLOG_0x80,
OP_QPLOG_0x00,
OP_QPLOG_0x80,
OP_QPSRAD,
};
typedef enum {
@ -1777,6 +1778,7 @@ static AlopDesc alops[] = {
{ X(OP_CLMULL), ALOPF11, ARGS_DDD, ALOP_EXT2, 0x14, 6, -1, CHAN_0134, { -1 }, 0xc0, 0 },
{ X(OP_IBRANCHD), ALOPF12_IBRANCHD, ARGS_DD, ALOP_EXT, 0x53, 6, -1, CHAN_0, { -1 }, 0xc0, 0xc0 },
{ X(OP_ICALLD), ALOPF12_ICALLD, ARGS_DD, ALOP_EXT, 0x54, 6, -1, CHAN_0, { -1 }, 0xc0, 0xc0 },
{ X(OP_QPSRAD), ALOPF11, ARGS_PDP, ALOP_EXT1, 0x25, 6, -1, CHAN_0134, { -1 }, 0xc0, 0 },
{ X(OP_QPCEXT_0X00), ALOPF12, ARGS_DP, ALOP_EXT1, 0x35, 6, -1, CHAN_0134, { -1 }, 0xc0, 0xc0 },
{ X(OP_QPCEXT_0X7F), ALOPF12, ARGS_DP, ALOP_EXT1, 0x35, 6, -1, CHAN_0134, { -1 }, 0xc0, 0xc2 },
{ X(OP_QPCEXT_0X80), ALOPF12, ARGS_DP, ALOP_EXT1, 0x35, 6, -1, CHAN_0134, { -1 }, 0xc0, 0xc4 },

View File

@ -35,6 +35,8 @@ DEF_HELPER_3(rwd, void, env, int, i64)
DEF_HELPER_3(rws, void, env, int, i32)
DEF_HELPER_FLAGS_2(sxt, TCG_CALL_NO_RWG_SE, i64, i64, i32)
DEF_HELPER_FLAGS_2(clmull, TCG_CALL_NO_RWG_SE, i64, i64, i64)
DEF_HELPER_FLAGS_2(clmulh, TCG_CALL_NO_RWG_SE, i64, i64, i64)
/* Packed Min/Max */
DEF_HELPER_FLAGS_2(pminub, TCG_CALL_NO_RWG_SE, i64, i64, i64)
@ -215,6 +217,31 @@ DEF_HELPER_FLAGS_3(pfcmpnlts, TCG_CALL_NO_RWG, i64, env, i64, i64)
DEF_HELPER_FLAGS_3(pfcmpnles, TCG_CALL_NO_RWG, i64, env, i64, i64)
DEF_HELPER_FLAGS_3(pfcmpods, TCG_CALL_NO_RWG, i64, env, i64, i64)
/* FMA */
DEF_HELPER_FLAGS_4(fmas, TCG_CALL_NO_RWG, i32, env, i32, i32, i32)
DEF_HELPER_FLAGS_4(fmss, TCG_CALL_NO_RWG, i32, env, i32, i32, i32)
DEF_HELPER_FLAGS_4(fnmas, TCG_CALL_NO_RWG, i32, env, i32, i32, i32)
DEF_HELPER_FLAGS_4(fnmss, TCG_CALL_NO_RWG, i32, env, i32, i32, i32)
DEF_HELPER_FLAGS_4(fmad, TCG_CALL_NO_RWG, i64, env, i64, i64, i64)
DEF_HELPER_FLAGS_4(fmsd, TCG_CALL_NO_RWG, i64, env, i64, i64, i64)
DEF_HELPER_FLAGS_4(fnmad, TCG_CALL_NO_RWG, i64, env, i64, i64, i64)
DEF_HELPER_FLAGS_4(fnmsd, TCG_CALL_NO_RWG, i64, env, i64, i64, i64)
DEF_HELPER_FLAGS_5(qpfmas, TCG_CALL_NO_RWG, void, vec, env, vec, vec, vec)
DEF_HELPER_FLAGS_5(qpfmss, TCG_CALL_NO_RWG, void, vec, env, vec, vec, vec)
DEF_HELPER_FLAGS_5(qpfnmas, TCG_CALL_NO_RWG, void, vec, env, vec, vec, vec)
DEF_HELPER_FLAGS_5(qpfnmss, TCG_CALL_NO_RWG, void, vec, env, vec, vec, vec)
DEF_HELPER_FLAGS_5(qpfmass, TCG_CALL_NO_RWG, void, vec, env, vec, vec, vec)
DEF_HELPER_FLAGS_5(qpfmsas, TCG_CALL_NO_RWG, void, vec, env, vec, vec, vec)
DEF_HELPER_FLAGS_5(qpfmad, TCG_CALL_NO_RWG, void, vec, env, vec, vec, vec)
DEF_HELPER_FLAGS_5(qpfmsd, TCG_CALL_NO_RWG, void, vec, env, vec, vec, vec)
DEF_HELPER_FLAGS_5(qpfnmad, TCG_CALL_NO_RWG, void, vec, env, vec, vec, vec)
DEF_HELPER_FLAGS_5(qpfnmsd, TCG_CALL_NO_RWG, void, vec, env, vec, vec, vec)
DEF_HELPER_FLAGS_5(qpfmasd, TCG_CALL_NO_RWG, void, vec, env, vec, vec, vec)
DEF_HELPER_FLAGS_5(qpfmsad, TCG_CALL_NO_RWG, void, vec, env, vec, vec, vec)
/* Float x80 ops */
#define DEF_FX_OP2(op) \
DEF_HELPER_FLAGS_3(glue(op, ss), TCG_CALL_NO_RWG, i32, env, f80, i32) \
@ -272,6 +299,8 @@ DEF_HELPER_FP_CMP(fx, s, i64, f80, i32)
DEF_HELPER_FP_CMP(fx, d, i64, f80, i64)
DEF_HELPER_FP_CMP(fx, x, i64, f80, f80)
#undef DEF_HELPER_FP_CMP
/* Float Flag Comparisons */
DEF_HELPER_FLAGS_3(fcmpodsf, TCG_CALL_NO_RWG, i32, env, i32, i32)
DEF_HELPER_FLAGS_3(fcmpudsf, TCG_CALL_NO_RWG, i32, env, i32, i32)

View File

@ -189,6 +189,10 @@ void HELPER(fxscalesx)(floatx80 *r, CPUE2KState *env, floatx80 *a, uint32_t b)
#define make_f80(v) (*(v))
#define make(S, v) glue(make_, S)(v)
#define float_val_f32(v) float32_val(v)
#define float_val_f64(v) float64_val(v)
#define float_val(S, v) glue(float_val_, S)(v)
#define type_i32 uint32_t
#define type_i64 uint64_t
#define type_f32 float32
@ -272,6 +276,24 @@ void HELPER(fxscalesx)(floatx80 *r, CPUE2KState *env, floatx80 *a, uint32_t b)
#define IMPL_ALOPF1_FPU_CMP(FPU, name, S1, S2, R, T, op1, op2) \
IMPL_ALOPF1_FPU_CMP_BASIC(FPU, name, S1, S2, R, T, T, R, op1, op2)
#define IMPL_ALOPF21_FPU(FPU, name, S1, S2, S3, R, T1, T2, T3, TR, op) \
ret_type(R) HELPER(name)(ret_arg(R) CPUE2KState *env, \
arg_type(S1) s1, arg_type(S2) s2, arg_type(S3) s3) \
{ \
int old_flags = glue(FPU, _save_exception_flags)(env); \
float_status *s = &env->glue(FPU, _status); \
type(T1) t1 = convert(S1, T1, make(S1, s1), s); \
type(T2) t2 = convert(S2, T2, make(S2, s2), s); \
type(T3) t3 = convert(S3, T3, make(S3, s3), s); \
type(TR) tr = op(t1, t2, t3, s); \
type(R) r = convert(TR, R, tr, s); \
glue(FPU, _merge_exception_flags)(env, old_flags); \
ret(R, r); \
}
#define IMPL_ALOPF21_FP(name, T, op) \
IMPL_ALOPF21_FPU(fp, name, T, T, T, T, T, T, T, T, op)
#define IMPL_ALOPF1_FX_MANY(name, op) \
IMPL_ALOPF1_FX(glue3(fx, name, ss), f80, f32, f32, op) \
IMPL_ALOPF1_FX(glue3(fx, name, dd), f80, f64, f64, op) \
@ -442,3 +464,70 @@ IMPL_ALOPF2_FP(fsqrts, f32, f32, float32_sqrt)
IMPL_ALOPF2_FP(frcps, f32, f32, frcps)
IMPL_ALOPF2_FP(frsqrts, f32, f32, frsqrts)
IMPL_ALOPF1_FP(fsqrttd, f64, f64, f64, fsqrttd)
#define FMA(T, x, y, z, f, s) \
glue(type_name(T), _muladd)(x, y, z, f, s)
#define FMAS(x, y, z, s) FMA(f32, x, y, z, 0, s)
#define FMAD(x, y, z, s) FMA(f64, x, y, z, 0, s)
#define FMSS(x, y, z, s) FMA(f32, x, y, z, float_muladd_negate_c, s)
#define FMSD(x, y, z, s) FMA(f64, x, y, z, float_muladd_negate_c, s)
#define FNMAS(x, y, z, s) FMA(f32, x, y, z, float_muladd_negate_product, s)
#define FNMAD(x, y, z, s) FMA(f64, x, y, z, float_muladd_negate_product, s)
#define FNMSS(x, y, z, s) FMA(f32, x, y, z, float_muladd_negate_product | float_muladd_negate_c, s)
#define FNMSD(x, y, z, s) FMA(f64, x, y, z, float_muladd_negate_product | float_muladd_negate_c, s)
IMPL_ALOPF21_FP(fmas, f32, FMAS)
IMPL_ALOPF21_FP(fmss, f32, FMSS)
IMPL_ALOPF21_FP(fnmas, f32, FNMAS)
IMPL_ALOPF21_FP(fnmss, f32, FNMSS)
IMPL_ALOPF21_FP(fmad, f64, FMAD)
IMPL_ALOPF21_FP(fmsd, f64, FMSD)
IMPL_ALOPF21_FP(fnmad, f64, FNMAD)
IMPL_ALOPF21_FP(fnmsd, f64, FNMSD)
#define qp_len_uw 4
#define qp_len_ud 2
#define qp_len(T) glue(qp_len_, T)
#define IMPL_OP3_QP_ENV(name, T, F, code) \
void HELPER(name)(E2KReg *r, CPUE2KState *env, E2KReg *s1, \
E2KReg *s2, E2KReg *s3) \
{ \
int old_flags = fp_save_exception_flags(env); \
int i; \
\
for (i = 0; i < qp_len(T); i++) { \
type(F) a = make(F, s1->T[i]); \
type(F) b = make(F, s2->T[i]); \
type(F) c = make(F, s3->T[i]); \
{ code; } \
} \
\
fp_merge_exception_flags(env, old_flags); \
}
#define IMPL_OP3_QP_ENV_OP(name, T, F, op) \
IMPL_OP3_QP_ENV(name, T, F, { \
r->T[i] = float_val(F, op(a, b, c, &env->fp_status)); \
})
IMPL_OP3_QP_ENV_OP(qpfmas, uw, f32, FMAS)
IMPL_OP3_QP_ENV_OP(qpfmss, uw, f32, FMSS)
IMPL_OP3_QP_ENV_OP(qpfnmas, uw, f32, FNMAS)
IMPL_OP3_QP_ENV_OP(qpfnmss, uw, f32, FNMSS)
IMPL_OP3_QP_ENV_OP(qpfmad, ud, f64, FMAD)
IMPL_OP3_QP_ENV_OP(qpfmsd, ud, f64, FMSD)
IMPL_OP3_QP_ENV_OP(qpfnmad, ud, f64, FNMAD)
IMPL_OP3_QP_ENV_OP(qpfnmsd, ud, f64, FNMSD)
#define IMPL_OP3_QP_ENV_OP_ALT(name, T, F, op1, op2) \
IMPL_OP3_QP_ENV(name, T, F, { \
r->T[i] = float_val(F, i & 1 ? op2(a, b, c, &env->fp_status) : \
op1(a, b, c, &env->fp_status)); \
})
IMPL_OP3_QP_ENV_OP_ALT(qpfmass, uw, f32, FMAS, FMSS)
IMPL_OP3_QP_ENV_OP_ALT(qpfmsas, uw, f32, FMSS, FMAS)
IMPL_OP3_QP_ENV_OP_ALT(qpfmasd, ud, f64, FMAD, FMSD)
IMPL_OP3_QP_ENV_OP_ALT(qpfmsad, ud, f64, FMSD, FMAD)

View File

@ -150,3 +150,25 @@ int HELPER(dam_unlock_addr)(CPUE2KState *env, uint64_t addr, int size, int reg)
// TODO: helper_dam_unlock_addr
return 1;
}
uint64_t HELPER(clmull)(uint64_t s1, uint64_t s2)
{
uint64_t r = 0;
for (; s1; s1 >>= 1, s2 <<= 1) {
r ^= s1 & 1 ? s2 : 0;
}
return r;
}
uint64_t HELPER(clmulh)(uint64_t s1, uint64_t s2)
{
uint64_t r = 0;
for (s2 >>= 1; s1; s1 <<= 1, s2 >>= 1) {
r ^= s1 & (1ULL << 63) ? s2 : 0;
}
return r;
}

View File

@ -2514,10 +2514,11 @@ static inline void gen_merge_i64(TCGv_i64 ret, TCGv_i64 src1, TCGv_i64 src2,
\
gen_tagged_src(1, S, instr, a); \
gen_tagged_src(2, S, instr, b); \
gen_result_init(S, instr, r); \
\
gen_mrgc_i32(instr->ctx, instr->chan, t0); \
gen_merge_i32(r.tag, a.tag, b.tag, t0); \
call(S, gen_tag1, r.tag, r.tag); \
gen_tag1(S, r, r); \
call(S, gen_merge, r.val, a.val, b.val, t0); \
gen_al_result(S, instr, r); \
\
@ -3031,6 +3032,36 @@ static inline void gen_pshufw(TCGv_i64 ret, TCGv_i64 src1,
tcg_temp_free_i32(imm8);
}
#define IMPL_GEN_PCMPP(name, op, c, i) \
static void name(TCGv_i64 ret, TCGv_i64 s1, TCGv_i64 s2) \
{ \
TCGv_i64 t0 = tcg_temp_new_i64(); \
\
op(t0, s1, s2); \
tcg_gen_setcondi_i64(c, ret, t0, i); \
\
tcg_temp_free_i64(t0); \
}
IMPL_GEN_PCMPP(gen_pcmpeqbop, gen_helper_pcmpeqb, TCG_COND_NE, 0)
IMPL_GEN_PCMPP(gen_pcmpeqhop, gen_helper_pcmpeqh, TCG_COND_NE, 0)
IMPL_GEN_PCMPP(gen_pcmpeqwop, gen_helper_pcmpeqw, TCG_COND_NE, 0)
IMPL_GEN_PCMPP(gen_pcmpgtbop, gen_helper_pcmpgtb, TCG_COND_NE, 0)
IMPL_GEN_PCMPP(gen_pcmpgthop, gen_helper_pcmpgth, TCG_COND_NE, 0)
IMPL_GEN_PCMPP(gen_pcmpgtwop, gen_helper_pcmpgtw, TCG_COND_NE, 0)
IMPL_GEN_PCMPP(gen_pcmpeqbap, gen_helper_pcmpeqb, TCG_COND_EQ, -1)
IMPL_GEN_PCMPP(gen_pcmpeqhap, gen_helper_pcmpeqh, TCG_COND_EQ, -1)
IMPL_GEN_PCMPP(gen_pcmpeqwap, gen_helper_pcmpeqw, TCG_COND_EQ, -1)
IMPL_GEN_PCMPP(gen_pcmpgtbap, gen_helper_pcmpgtb, TCG_COND_EQ, -1)
IMPL_GEN_PCMPP(gen_pcmpgthap, gen_helper_pcmpgth, TCG_COND_EQ, -1)
IMPL_GEN_PCMPP(gen_pcmpgtwap, gen_helper_pcmpgtw, TCG_COND_EQ, -1)
#define gen_pcmpeqdop gen_cmpedb
#define gen_pcmpeqdap gen_cmpedb
IMPL_CMP(gen_pcmpgtdop, d, TCG_COND_GT)
IMPL_CMP(gen_pcmpgtdap, d, TCG_COND_GT)
static void gen_qppackdl(TCGv_ptr ret, TCGv_i64 hi, TCGv_i64 lo)
{
tcg_gen_st_i64(lo, ret, offsetof(E2KReg, lo));
@ -3232,6 +3263,20 @@ IMPL_GEN_ALOPF1_QDQ(gen_qpsraw, gen_helper_psraw)
IMPL_GEN_ALOPF1_QDQ(gen_qpsrcw, gen_psrcw)
IMPL_GEN_ALOPF1_QDQ(gen_qpsrcd, gen_psrcd)
static void gen_qpsrad_helper(TCGv_i64 ret, TCGv_i64 s1, TCGv_i64 s2)
{
TCGv_i64 t0 = tcg_const_i64(63);
TCGv_i64 t1 = tcg_temp_new_i64();
tcg_gen_movcond_i64(TCG_COND_LTU, t1, s2, t0, s2, t0);
tcg_gen_sar_i64(ret, s1, t1);
tcg_temp_free_i64(t1);
tcg_temp_free_i64(t0);
}
IMPL_GEN_ALOPF1_QDQ(gen_qpsrad, gen_qpsrad_helper)
#define IMPL_GEN_ALOPF21_QQQQ(name, op) \
static void name(TCGv_ptr ret, TCGv_ptr s1, TCGv_ptr s2, TCGv_ptr s3) \
{ \
@ -3393,6 +3438,89 @@ IMPL_GEN_PLOG(gen_plog_0x80, 0x80)
IMPL_GEN_ALOPF21_LOG_QQQQ(gen_qplog_0x00, gen_plog_0x00)
IMPL_GEN_ALOPF21_LOG_QQQQ(gen_qplog_0x80, gen_plog_0x80)
#define IMPL_GEN_ALOPF7_QQB(name, op1, op2) \
static void name(TCGv_i64 ret, TCGv_ptr s1, TCGv_ptr s2) \
{ \
TCGv_i64 t0 = tcg_temp_new_i64(); \
TCGv_i64 t1 = tcg_temp_new_i64(); \
TCGv_i64 t2 = tcg_temp_new_i64(); \
TCGv_i64 t3 = tcg_temp_new_i64(); \
TCGv_i64 t4 = tcg_temp_new_i64(); \
TCGv_i64 t5 = tcg_temp_new_i64(); \
\
gen_qpunpackdl(t0, t1, s1); \
gen_qpunpackdl(t2, t3, s2); \
op1(t4, t0, t2); \
op1(t5, t1, t3); \
op2(ret, t4, t5); \
\
tcg_temp_free_i64(t5); \
tcg_temp_free_i64(t4); \
tcg_temp_free_i64(t3); \
tcg_temp_free_i64(t2); \
tcg_temp_free_i64(t1); \
tcg_temp_free_i64(t0); \
}
IMPL_GEN_ALOPF7_QQB(gen_qpcmpeqbop, gen_pcmpeqbop, tcg_gen_or_i64)
IMPL_GEN_ALOPF7_QQB(gen_qpcmpeqhop, gen_pcmpeqhop, tcg_gen_or_i64)
IMPL_GEN_ALOPF7_QQB(gen_qpcmpeqwop, gen_pcmpeqwop, tcg_gen_or_i64)
IMPL_GEN_ALOPF7_QQB(gen_qpcmpeqdop, gen_pcmpeqdop, tcg_gen_or_i64)
IMPL_GEN_ALOPF7_QQB(gen_qpcmpgtbop, gen_pcmpgtbop, tcg_gen_or_i64)
IMPL_GEN_ALOPF7_QQB(gen_qpcmpgthop, gen_pcmpgthop, tcg_gen_or_i64)
IMPL_GEN_ALOPF7_QQB(gen_qpcmpgtwop, gen_pcmpgtwop, tcg_gen_or_i64)
IMPL_GEN_ALOPF7_QQB(gen_qpcmpgtdop, gen_pcmpgtdop, tcg_gen_or_i64)
IMPL_GEN_ALOPF7_QQB(gen_qpcmpeqbap, gen_pcmpeqbap, tcg_gen_and_i64)
IMPL_GEN_ALOPF7_QQB(gen_qpcmpeqhap, gen_pcmpeqhap, tcg_gen_and_i64)
IMPL_GEN_ALOPF7_QQB(gen_qpcmpeqwap, gen_pcmpeqwap, tcg_gen_and_i64)
IMPL_GEN_ALOPF7_QQB(gen_qpcmpeqdap, gen_pcmpeqdap, tcg_gen_and_i64)
IMPL_GEN_ALOPF7_QQB(gen_qpcmpgtbap, gen_pcmpgtbap, tcg_gen_and_i64)
IMPL_GEN_ALOPF7_QQB(gen_qpcmpgthap, gen_pcmpgthap, tcg_gen_and_i64)
IMPL_GEN_ALOPF7_QQB(gen_qpcmpgtwap, gen_pcmpgtwap, tcg_gen_and_i64)
IMPL_GEN_ALOPF7_QQB(gen_qpcmpgtdap, gen_pcmpgtdap, tcg_gen_and_i64)
static void gen_merge_ptr(TCGv_ptr ret, TCGv_ptr s1, TCGv_ptr s2,
TCGv_i32 cond)
{
TCGv_i64 t0 = tcg_const_i64(0);
TCGv_i64 t1 = tcg_temp_new_i64();
TCGv_i64 t2 = tcg_temp_new_i64();
TCGv_i64 t3 = tcg_temp_new_i64();
TCGv_i64 t4 = tcg_temp_new_i64();
TCGv_i64 t5 = tcg_temp_new_i64();
tcg_gen_extu_i32_i64(t1, cond);
gen_qpunpackdl(t2, t3, s1);
gen_qpunpackdl(t4, t5, s2);
tcg_gen_movcond_i64(TCG_COND_EQ, t2, t0, t1, t2, t4);
tcg_gen_movcond_i64(TCG_COND_EQ, t3, t0, t1, t3, t5);
gen_qppackdl(ret, t2, t3);
tcg_temp_free_i64(t5);
tcg_temp_free_i64(t4);
tcg_temp_free_i64(t3);
tcg_temp_free_i64(t2);
tcg_temp_free_i64(t1);
tcg_temp_free_i64(t0);
}
IMPL_MERGE(gen_qpmrgp, q)
#define IMPL_GEN_QPCEXT(name, CONST) \
static void name(TCGv_ptr ret, TCGv_i64 s2) \
{ \
TCGv_i64 t0 = tcg_const_i64(0x0101010101010101ULL * CONST); \
\
gen_qppackdl(ret, t0, s2); \
\
tcg_temp_free_i64(t0); \
}
IMPL_GEN_QPCEXT(gen_qpcext_0x00, 0x00)
IMPL_GEN_QPCEXT(gen_qpcext_0x7f, 0x7f)
IMPL_GEN_QPCEXT(gen_qpcext_0x80, 0x80)
IMPL_GEN_QPCEXT(gen_qpcext_0xff, 0xff)
static MemOp memop_from_mas(MemOp memop, uint8_t mas)
{
// int disable_cache = extract(mas, 5, 2);
@ -4438,6 +4566,7 @@ IMPL_ALOPF2(gen_alopf2_dd, d, d)
IMPL_ALOPF2(gen_alopf2_xs, x, s)
IMPL_ALOPF2(gen_alopf2_xx, x, x)
IMPL_ALOPF2(gen_alopf2_qs, q, s)
IMPL_ALOPF2(gen_alopf2_dq, d, q)
IMPL_ALOPF2(gen_alopf2_qq, q, q)
#define IMPL_ALOPF2_ENV(name, S2, R) \
@ -4501,6 +4630,7 @@ IMPL_ALOPF2_PSHUFH(gen_alopf2_pshufh, d, d)
IMPL_ALOPF7(gen_alopf7_sss, s, s, s)
IMPL_ALOPF7(gen_alopf7_ddd, d, d, d)
IMPL_ALOPF7(gen_alopf7_qqd, q, q, d)
#define IMPL_ALOPF7_ENV(name, S1, S2, R) \
IMPL_ALOPF7_BASIC(name, S1, S2, R, \
@ -4552,6 +4682,15 @@ IMPL_ALOPF21(gen_alopf21_ddsd, d, d, s, d)
IMPL_ALOPF21(gen_alopf21_dddd, d, d, d, d)
IMPL_ALOPF21(gen_alopf21_qqqq, q, q, q, q)
#define IMPL_ALOPF21_ENV(name, S1, S2, S3, R) \
IMPL_ALOPF21_BASIC(name, S1, S2, S3, R, \
void (*op)(temp(R), TCGv_env, temp(S1), temp(S2), temp(S3)), \
{ (*op)(r.val, cpu_env, s1.val, s2.val, s3.val); })
IMPL_ALOPF21_ENV(gen_alopf21_env_ssss, s, s, s, s)
IMPL_ALOPF21_ENV(gen_alopf21_env_dddd, d, d, d, d)
IMPL_ALOPF21_ENV(gen_alopf21_env_qqqq, q, q, q, q)
#define IMPL_ALOPF21_LOG(name, S1, S2, S3, R) \
IMPL_ALOPF21_BASIC(name, S1, S2, S3, R, \
void (*op)(temp(R), uint32_t, temp(S1), temp(S2), temp(S3)), \
@ -5387,6 +5526,67 @@ static void gen_alop_simple(Instr *instr, uint32_t op, const char *name)
case OP_PLOG_0x80: gen_alopf21_log_dddd(instr, gen_plog_0x80); break;
case OP_QPLOG_0x00: gen_alopf21_log_qqqq(instr, gen_qplog_0x00); break;
case OP_QPLOG_0x80: gen_alopf21_log_qqqq(instr, gen_qplog_0x80); break;
case OP_FMAS: gen_alopf21_env_ssss(instr, gen_helper_fmas); break;
case OP_FMSS: gen_alopf21_env_ssss(instr, gen_helper_fmss); break;
case OP_FNMAS: gen_alopf21_env_ssss(instr, gen_helper_fnmas); break;
case OP_FNMSS: gen_alopf21_env_ssss(instr, gen_helper_fnmss); break;
case OP_FMAD: gen_alopf21_env_dddd(instr, gen_helper_fmad); break;
case OP_FMSD: gen_alopf21_env_dddd(instr, gen_helper_fmsd); break;
case OP_FNMAD: gen_alopf21_env_dddd(instr, gen_helper_fnmad); break;
case OP_FNMSD: gen_alopf21_env_dddd(instr, gen_helper_fnmsd); break;
case OP_QPFMAS: gen_alopf21_env_qqqq(instr, gen_helper_qpfmas); break;
case OP_QPFMSS: gen_alopf21_env_qqqq(instr, gen_helper_qpfmss); break;
case OP_QPFNMAS: gen_alopf21_env_qqqq(instr, gen_helper_qpfnmas); break;
case OP_QPFNMSS: gen_alopf21_env_qqqq(instr, gen_helper_qpfnmss); break;
case OP_QPFMASS: gen_alopf21_env_qqqq(instr, gen_helper_qpfmass); break;
case OP_QPFMSAS: gen_alopf21_env_qqqq(instr, gen_helper_qpfmsas); break;
case OP_QPFMAD: gen_alopf21_env_qqqq(instr, gen_helper_qpfmad); break;
case OP_QPFMSD: gen_alopf21_env_qqqq(instr, gen_helper_qpfmsd); break;
case OP_QPFNMAD: gen_alopf21_env_qqqq(instr, gen_helper_qpfnmad); break;
case OP_QPFNMSD: gen_alopf21_env_qqqq(instr, gen_helper_qpfnmsd); break;
case OP_QPFMASD: gen_alopf21_env_qqqq(instr, gen_helper_qpfmasd); break;
case OP_QPFMSAD: gen_alopf21_env_qqqq(instr, gen_helper_qpfmsad); break;
case OP_PCMPEQBOP: gen_alopf7_ddd(instr, gen_pcmpeqbop); break;
case OP_PCMPEQHOP: gen_alopf7_ddd(instr, gen_pcmpeqhop); break;
case OP_PCMPEQWOP: gen_alopf7_ddd(instr, gen_pcmpeqwop); break;
case OP_PCMPEQDOP: gen_alopf7_ddd(instr, gen_pcmpeqdop); break;
case OP_PCMPGTBOP: gen_alopf7_ddd(instr, gen_pcmpgtbop); break;
case OP_PCMPGTHOP: gen_alopf7_ddd(instr, gen_pcmpgthop); break;
case OP_PCMPGTWOP: gen_alopf7_ddd(instr, gen_pcmpgtwop); break;
case OP_PCMPGTDOP: gen_alopf7_ddd(instr, gen_pcmpgtdop); break;
case OP_PCMPEQBAP: gen_alopf7_ddd(instr, gen_pcmpeqbap); break;
case OP_PCMPEQHAP: gen_alopf7_ddd(instr, gen_pcmpeqhap); break;
case OP_PCMPEQWAP: gen_alopf7_ddd(instr, gen_pcmpeqwap); break;
case OP_PCMPEQDAP: gen_alopf7_ddd(instr, gen_pcmpeqdap); break;
case OP_PCMPGTBAP: gen_alopf7_ddd(instr, gen_pcmpgtbap); break;
case OP_PCMPGTHAP: gen_alopf7_ddd(instr, gen_pcmpgthap); break;
case OP_PCMPGTWAP: gen_alopf7_ddd(instr, gen_pcmpgtwap); break;
case OP_PCMPGTDAP: gen_alopf7_ddd(instr, gen_pcmpgtdap); break;
case OP_QPCMPEQBOP: gen_alopf7_qqd(instr, gen_qpcmpeqbop); break;
case OP_QPCMPEQHOP: gen_alopf7_qqd(instr, gen_qpcmpeqhop); break;
case OP_QPCMPEQWOP: gen_alopf7_qqd(instr, gen_qpcmpeqwop); break;
case OP_QPCMPEQDOP: gen_alopf7_qqd(instr, gen_qpcmpeqdop); break;
case OP_QPCMPGTBOP: gen_alopf7_qqd(instr, gen_qpcmpgtbop); break;
case OP_QPCMPGTHOP: gen_alopf7_qqd(instr, gen_qpcmpgthop); break;
case OP_QPCMPGTWOP: gen_alopf7_qqd(instr, gen_qpcmpgtwop); break;
case OP_QPCMPGTDOP: gen_alopf7_qqd(instr, gen_qpcmpgtdop); break;
case OP_QPCMPEQBAP: gen_alopf7_qqd(instr, gen_qpcmpeqbap); break;
case OP_QPCMPEQHAP: gen_alopf7_qqd(instr, gen_qpcmpeqhap); break;
case OP_QPCMPEQWAP: gen_alopf7_qqd(instr, gen_qpcmpeqwap); break;
case OP_QPCMPEQDAP: gen_alopf7_qqd(instr, gen_qpcmpeqdap); break;
case OP_QPCMPGTBAP: gen_alopf7_qqd(instr, gen_qpcmpgtbap); break;
case OP_QPCMPGTHAP: gen_alopf7_qqd(instr, gen_qpcmpgthap); break;
case OP_QPCMPGTWAP: gen_alopf7_qqd(instr, gen_qpcmpgtwap); break;
case OP_QPCMPGTDAP: gen_alopf7_qqd(instr, gen_qpcmpgtdap); break;
case OP_QPSRAD: gen_alopf1_qdq(instr, gen_qpsrad); break;
case OP_PMRGP: gen_merged(instr); break;
case OP_QPMRGP: gen_qpmrgp(instr); break;
case OP_CLMULH: gen_alopf1_ddd(instr, gen_helper_clmulh); break;
case OP_CLMULL: gen_alopf1_ddd(instr, gen_helper_clmull); break;
case OP_QPCEXT_0X00: gen_alopf2_dq(instr, gen_qpcext_0x00); break;
case OP_QPCEXT_0X7F: gen_alopf2_dq(instr, gen_qpcext_0x7f); break;
case OP_QPCEXT_0X80: gen_alopf2_dq(instr, gen_qpcext_0x80); break;
case OP_QPCEXT_0XFF: gen_alopf2_dq(instr, gen_qpcext_0xff); break;
case OP_VFSI:
case OP_MOVTRS:
case OP_MOVTRCS:
@ -5498,68 +5698,8 @@ static void gen_alop_simple(Instr *instr, uint32_t op, const char *name)
case OP_VFBGV:
case OP_MKFSW:
case OP_MODBGV:
case OP_PCMPEQBOP:
case OP_PCMPEQHOP:
case OP_PCMPEQWOP:
case OP_PCMPEQDOP:
case OP_PCMPGTBOP:
case OP_PCMPGTHOP:
case OP_PCMPGTWOP:
case OP_PCMPGTDOP:
case OP_PCMPEQBAP:
case OP_PCMPEQHAP:
case OP_PCMPEQWAP:
case OP_PCMPEQDAP:
case OP_PCMPGTBAP:
case OP_PCMPGTHAP:
case OP_PCMPGTWAP:
case OP_PCMPGTDAP:
case OP_QPCMPEQBOP:
case OP_QPCMPEQHOP:
case OP_QPCMPEQWOP:
case OP_QPCMPEQDOP:
case OP_QPCMPGTBOP:
case OP_QPCMPGTHOP:
case OP_QPCMPGTWOP:
case OP_QPCMPGTDOP:
case OP_QPCMPEQBAP:
case OP_QPCMPEQHAP:
case OP_QPCMPEQWAP:
case OP_QPCMPEQDAP:
case OP_QPCMPGTBAP:
case OP_QPCMPGTHAP:
case OP_QPCMPGTWAP:
case OP_QPCMPGTDAP:
case OP_PMRGP:
case OP_QPMRGP:
case OP_CLMULH:
case OP_CLMULL:
case OP_IBRANCHD:
case OP_ICALLD:
case OP_QPCEXT_0X00:
case OP_QPCEXT_0X7F:
case OP_QPCEXT_0X80:
case OP_QPCEXT_0XFF:
case OP_FMAS:
case OP_FMSS:
case OP_FNMAS:
case OP_FNMSS:
case OP_FMAD:
case OP_FMSD:
case OP_FNMAD:
case OP_FNMSD:
case OP_QPFMAS:
case OP_QPFMSS:
case OP_QPFNMAS:
case OP_QPFNMSS:
case OP_QPFMAD:
case OP_QPFMSD:
case OP_QPFNMAD:
case OP_QPFNMSD:
case OP_QPFMASS:
case OP_QPFMSAS:
case OP_QPFMASD:
case OP_QPFMSAD:
e2k_todo_illop(ctx, "unimplemented %d (%s)", op, name); break;
}
}