e2k: Add packed float simple and combined ops.
This commit is contained in:
parent
f73e828f75
commit
54c4312744
@ -123,6 +123,7 @@ DEF_HELPER_2(punpckhwd, i64, i64, i64)
|
||||
|
||||
/* Packed shuffle */
|
||||
DEF_HELPER_3(pshufb, i64, i64, i64, i64)
|
||||
DEF_HELPER_3(pmerge, i64, i64, i64, i64)
|
||||
DEF_HELPER_2(pshufh, i64, i64, i32)
|
||||
DEF_HELPER_3(pshufw, i64, i64, i64, i32)
|
||||
|
||||
@ -151,6 +152,30 @@ DEF_HELPER_2(fsqrts, i32, env, i32)
|
||||
DEF_HELPER_2(frsqrts, i32, env, i32)
|
||||
DEF_HELPER_3(fsqrttd, i64, env, i64, i64)
|
||||
|
||||
/* Packed Float ops */
|
||||
DEF_HELPER_3(pfadds, i64, env, i64, i64)
|
||||
DEF_HELPER_3(pfsubs, i64, env, i64, i64)
|
||||
DEF_HELPER_3(pfmuls, i64, env, i64, i64)
|
||||
DEF_HELPER_3(pfmaxs, i64, env, i64, i64)
|
||||
DEF_HELPER_3(pfmins, i64, env, i64, i64)
|
||||
DEF_HELPER_3(pfhadds, i64, env, i64, i64)
|
||||
DEF_HELPER_3(pfhsubs, i64, env, i64, i64)
|
||||
DEF_HELPER_3(pfaddsubs, i64, env, i64, i64)
|
||||
|
||||
DEF_HELPER_3(pfstoifs, i64, env, i64, i64)
|
||||
DEF_HELPER_2(pistofs, i64, env, i64)
|
||||
DEF_HELPER_2(pfstois, i64, env, i64)
|
||||
DEF_HELPER_2(pfstoistr, i64, env, i64)
|
||||
|
||||
DEF_HELPER_3(pfcmpeqs, i64, env, i64, i64)
|
||||
DEF_HELPER_3(pfcmplts, i64, env, i64, i64)
|
||||
DEF_HELPER_3(pfcmples, i64, env, i64, i64)
|
||||
DEF_HELPER_3(pfcmpuods, i64, env, i64, i64)
|
||||
DEF_HELPER_3(pfcmpneqs, i64, env, i64, i64)
|
||||
DEF_HELPER_3(pfcmpnlts, i64, env, i64, i64)
|
||||
DEF_HELPER_3(pfcmpnles, i64, env, i64, i64)
|
||||
DEF_HELPER_3(pfcmpods, i64, env, i64, i64)
|
||||
|
||||
/* Float x80 ops */
|
||||
DEF_HELPER_3(fxaddxx, void, env, f80, f80)
|
||||
DEF_HELPER_3(fxsubxx, void, env, f80, f80)
|
||||
|
@ -250,32 +250,13 @@ uint64_t HELPER(pshufb)(uint64_t src1, uint64_t src2, uint64_t src3)
|
||||
uint8_t byte;
|
||||
|
||||
if (desc < 0x80) {
|
||||
if (desc & 0x08) {
|
||||
byte = s1.ub[index];
|
||||
} else {
|
||||
byte = s2.ub[index];
|
||||
}
|
||||
byte = desc & 0x08 ? s1.ub[index] : s2.ub[index];
|
||||
|
||||
switch(desc >> 5) {
|
||||
case 0x1:
|
||||
byte = reverse_bits(byte);
|
||||
break;
|
||||
case 0x2:
|
||||
if ((byte & 0x80) != 0) {
|
||||
byte = 0xff;
|
||||
} else {
|
||||
byte = 0;
|
||||
}
|
||||
break;
|
||||
case 0x3:
|
||||
if ((byte & 1) != 0) {
|
||||
byte = 0xff;
|
||||
} else {
|
||||
byte = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case 0x1: byte = reverse_bits(byte); break;
|
||||
case 0x2: byte = (byte & 0x80) != 0 ? 0xff : 0; break;
|
||||
case 0x3: byte = (byte & 1) != 0 ? 0xff : 0; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
if (desc & 0x10) {
|
||||
@ -283,18 +264,10 @@ uint64_t HELPER(pshufb)(uint64_t src1, uint64_t src2, uint64_t src3)
|
||||
}
|
||||
} else {
|
||||
switch(desc >> 6) {
|
||||
case 0xa:
|
||||
byte = 0x7f;
|
||||
break;
|
||||
case 0xc:
|
||||
byte = 0x80;
|
||||
break;
|
||||
case 0xe:
|
||||
byte = 0xff;
|
||||
break;
|
||||
default:
|
||||
byte = 0;
|
||||
break;
|
||||
case 0xa: byte = 0x7f; break;
|
||||
case 0xc: byte = 0x80; break;
|
||||
case 0xe: byte = 0xff; break;
|
||||
default: byte = 0; break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -304,6 +277,22 @@ uint64_t HELPER(pshufb)(uint64_t src1, uint64_t src2, uint64_t src3)
|
||||
return ret.ud[0];
|
||||
}
|
||||
|
||||
uint64_t HELPER(pmerge)(uint64_t src1, uint64_t src2, uint64_t src3)
|
||||
{
|
||||
vec64 r, s1, s2, s3;
|
||||
unsigned int i;
|
||||
|
||||
s1.ud[0] = src1;
|
||||
s2.ud[0] = src2;
|
||||
s3.ud[0] = src3;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
r.ub[i] = s3.sb[i] < 0 ? s2.ub[i] : s1.ub[i];
|
||||
}
|
||||
|
||||
return r.ud[0];
|
||||
}
|
||||
|
||||
uint64_t HELPER(pshufh)(uint64_t src1, uint32_t imm8)
|
||||
{
|
||||
int i;
|
||||
@ -370,3 +359,80 @@ uint64_t HELPER(plog)(uint32_t opc, uint64_t src1, uint64_t src2, uint64_t src3)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define GEN_ENV_HELPER_PACKED_N(name, n, code) \
|
||||
uint64_t HELPER(name)(CPUE2KState *env, uint64_t src1, uint64_t src2) \
|
||||
{ \
|
||||
size_t i = 0; \
|
||||
vec64 s1 = { .ud[0] = src1 }, s2 = { .ud[0] = src2 }; \
|
||||
vec64 dst = { .ud[0] = 0 }; \
|
||||
for (; i < n; i++) { \
|
||||
code \
|
||||
} \
|
||||
return dst.ud[0]; \
|
||||
}
|
||||
#define GEN_ENV_HELPER_PACKED(name, type, code) \
|
||||
GEN_ENV_HELPER_PACKED_N(name, vec64_len(type), code)
|
||||
#define GEN_ENV_HELPER_PACKED_OP(name, type, op) \
|
||||
GEN_ENV_HELPER_PACKED_N(name, vec64_len(type), { \
|
||||
dst.type[i] = op(env, s1.type[i], s2.type[i]); \
|
||||
})
|
||||
#define GEN_ENV_HELPER_PACKED_HORIZONTAL_OP(name, type, op, map) \
|
||||
GEN_ENV_HELPER_PACKED_N(name, vec64_len(type) / 2, { \
|
||||
int j = i * 2; \
|
||||
dst.type[i ] = map(op(env, s1.type[j], s1.type[j + 1])); \
|
||||
dst.type[i + vec64_len(type) / 2] = map(op(env, s2.type[j], s2.type[j + 1])); \
|
||||
})
|
||||
|
||||
GEN_ENV_HELPER_PACKED_OP(pfadds, uw, helper_fadds)
|
||||
GEN_ENV_HELPER_PACKED_OP(pfsubs, uw, helper_fsubs)
|
||||
GEN_ENV_HELPER_PACKED_OP(pfmuls, uw, helper_fmuls)
|
||||
GEN_ENV_HELPER_PACKED_OP(pfmaxs, uw, helper_fmaxs)
|
||||
GEN_ENV_HELPER_PACKED_OP(pfmins, uw, helper_fmins)
|
||||
GEN_ENV_HELPER_PACKED_HORIZONTAL_OP(pfhadds, uw, helper_fadds, ident)
|
||||
GEN_ENV_HELPER_PACKED_HORIZONTAL_OP(pfhsubs, uw, helper_fsubs, ident)
|
||||
|
||||
GEN_ENV_HELPER_PACKED_OP(pfcmpeqs, uw, helper_fcmpeqs)
|
||||
GEN_ENV_HELPER_PACKED_OP(pfcmplts, uw, helper_fcmplts)
|
||||
GEN_ENV_HELPER_PACKED_OP(pfcmples, uw, helper_fcmples)
|
||||
GEN_ENV_HELPER_PACKED_OP(pfcmpuods, uw, helper_fcmpuods)
|
||||
GEN_ENV_HELPER_PACKED_OP(pfcmpneqs, uw, helper_fcmpneqs)
|
||||
GEN_ENV_HELPER_PACKED_OP(pfcmpnlts, uw, helper_fcmpnlts)
|
||||
GEN_ENV_HELPER_PACKED_OP(pfcmpnles, uw, helper_fcmpnles)
|
||||
GEN_ENV_HELPER_PACKED_OP(pfcmpods, uw, helper_fcmpods)
|
||||
|
||||
GEN_ENV_HELPER_PACKED(pfaddsubs, uw, { \
|
||||
if (i & 1) { \
|
||||
dst.uw[i] = helper_fadds(env, s1.uw[i], s2.uw[i]); \
|
||||
} else { \
|
||||
dst.uw[i] = helper_fsubs(env, s1.uw[i], s2.uw[i]); \
|
||||
} \
|
||||
})
|
||||
|
||||
#define GEN_ENV_HELPER_PACKED_UNARY_N(name, n, code) \
|
||||
uint64_t HELPER(name)(CPUE2KState *env, uint64_t src2) \
|
||||
{ \
|
||||
size_t i = 0; \
|
||||
vec64 s2 = { .ud[0] = src2 }; \
|
||||
vec64 dst = { .ud[0] = 0 }; \
|
||||
for (; i < n; i++) { \
|
||||
code \
|
||||
} \
|
||||
return dst.ud[0]; \
|
||||
}
|
||||
#define GEN_ENV_HELPER_PACKED_UNARY(name, type, code) \
|
||||
GEN_ENV_HELPER_PACKED_UNARY_N(name, vec64_len(type), code)
|
||||
#define GEN_ENV_HELPER_PACKED_UNARY_OP(name, type, op) \
|
||||
GEN_ENV_HELPER_PACKED_UNARY_N(name, vec64_len(type), { \
|
||||
dst.type[i] = op(env, s2.type[i]); \
|
||||
})
|
||||
|
||||
#define GEN_ENV_HELPER_PACKED_OP_CVT(name, type, op) \
|
||||
GEN_ENV_HELPER_PACKED_N(name, vec64_len(type), { \
|
||||
dst.type[i] = op(env, s1.uw[0], s2.type[i]); \
|
||||
})
|
||||
|
||||
GEN_ENV_HELPER_PACKED_OP_CVT(pfstoifs, uw, helper_fstoifs)
|
||||
GEN_ENV_HELPER_PACKED_UNARY_OP(pistofs, uw, helper_istofs)
|
||||
GEN_ENV_HELPER_PACKED_UNARY_OP(pfstois, uw, helper_fstois)
|
||||
GEN_ENV_HELPER_PACKED_UNARY_OP(pfstoistr, uw, helper_fstoistr)
|
||||
|
@ -246,6 +246,7 @@ typedef enum {
|
||||
ALOPF21,
|
||||
ALOPF21_ICOMB,
|
||||
ALOPF21_FCOMB,
|
||||
ALOPF21_PFCOMB,
|
||||
ALOPF21_LCOMB,
|
||||
ALOPF22,
|
||||
} Alopf;
|
||||
@ -253,6 +254,7 @@ typedef enum {
|
||||
typedef struct {
|
||||
Alopf format;
|
||||
uint32_t op;
|
||||
const char *name;
|
||||
} Alop;
|
||||
|
||||
typedef struct {
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "alops.inc"
|
||||
|
||||
#define glue3(a, b, c) glue(glue(a, b), c)
|
||||
#define glue4(a, b, c, d) glue(glue(a, b), glue(c, d))
|
||||
|
||||
static int16_t alops_map[4][128][6];
|
||||
@ -2797,28 +2798,28 @@ static void gen_alopf1_mrgc_ddd(Instr *instr)
|
||||
tcg_temp_free_i32(t0);
|
||||
}
|
||||
|
||||
static void gen_alopf21_i64(DisasContext *ctx, Instr *instr,
|
||||
static void gen_alopf21_i64(Instr *instr,
|
||||
void (*op)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_i64))
|
||||
{
|
||||
Src64 s1 = get_src1_i64(instr);
|
||||
Src64 s2 = get_src2_i64(instr);
|
||||
Src64 s3 = get_src3_i64(instr);
|
||||
TCGv_i32 tag = e2k_get_temp_i32(ctx);
|
||||
TCGv_i64 dst = e2k_get_temp_i64(ctx);
|
||||
TCGv_i32 tag = get_temp_i32(instr);
|
||||
TCGv_i64 dst = get_temp_i64(instr);
|
||||
|
||||
gen_tag3_i64(tag, s1.tag, s2.tag, s3.tag);
|
||||
(*op)(dst, s1.value, s2.value, s3.value);
|
||||
gen_al_result_i64(instr, dst, tag);
|
||||
}
|
||||
|
||||
static void gen_alopf21_i32(DisasContext *ctx, Instr *instr,
|
||||
static void gen_alopf21_i32(Instr *instr,
|
||||
void (*op)(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_i32))
|
||||
{
|
||||
Src32 s1 = get_src1_i32(instr);
|
||||
Src32 s2 = get_src2_i32(instr);
|
||||
Src32 s3 = get_src3_i32(instr);
|
||||
TCGv_i32 tag = e2k_get_temp_i32(ctx);
|
||||
TCGv_i32 dst = e2k_get_temp_i32(ctx);
|
||||
TCGv_i32 tag = get_temp_i32(instr);
|
||||
TCGv_i32 dst = get_temp_i32(instr);
|
||||
|
||||
gen_tag3_i32(tag, s1.tag, s2.tag, s3.tag);
|
||||
(*op)(dst, s1.value, s2.value, s3.value);
|
||||
@ -3249,6 +3250,7 @@ static void check_args(Alopf alopf, Instr *instr)
|
||||
case ALOPF21:
|
||||
case ALOPF21_ICOMB:
|
||||
case ALOPF21_FCOMB:
|
||||
case ALOPF21_PFCOMB:
|
||||
case ALOPF21_LCOMB:
|
||||
check_reg_src(ctx, instr->src1);
|
||||
check_reg_src(ctx, instr->src2);
|
||||
@ -3403,6 +3405,22 @@ static void gen_alop_simple(Instr *instr, uint32_t op)
|
||||
case OP_FMAXD: gen_alopf1_dedd(instr, gen_helper_fmaxd); break;
|
||||
case OP_FMULS: gen_alopf1_sess(instr, gen_helper_fmuls); break;
|
||||
case OP_FMULD: gen_alopf1_dedd(instr, gen_helper_fmuld); break;
|
||||
case OP_FCMPEQS: gen_alopf1_sess(instr, gen_helper_fcmpeqs); break;
|
||||
case OP_FCMPLTS: gen_alopf1_sess(instr, gen_helper_fcmplts); break;
|
||||
case OP_FCMPLES: gen_alopf1_sess(instr, gen_helper_fcmples); break;
|
||||
case OP_FCMPUODS: gen_alopf1_sess(instr, gen_helper_fcmpuods); break;
|
||||
case OP_FCMPNEQS: gen_alopf1_sess(instr, gen_helper_fcmpneqs); break;
|
||||
case OP_FCMPNLTS: gen_alopf1_sess(instr, gen_helper_fcmpnlts); break;
|
||||
case OP_FCMPNLES: gen_alopf1_sess(instr, gen_helper_fcmpnles); break;
|
||||
case OP_FCMPODS: gen_alopf1_sess(instr, gen_helper_fcmpods); break;
|
||||
case OP_FCMPEQD: gen_alopf1_dedd(instr, gen_helper_fcmpeqd); break;
|
||||
case OP_FCMPLTD: gen_alopf1_dedd(instr, gen_helper_fcmpltd); break;
|
||||
case OP_FCMPLED: gen_alopf1_dedd(instr, gen_helper_fcmpled); break;
|
||||
case OP_FCMPUODD: gen_alopf1_dedd(instr, gen_helper_fcmpuodd); break;
|
||||
case OP_FCMPNEQD: gen_alopf1_dedd(instr, gen_helper_fcmpneqd); break;
|
||||
case OP_FCMPNLTD: gen_alopf1_dedd(instr, gen_helper_fcmpnltd); break;
|
||||
case OP_FCMPNLED: gen_alopf1_dedd(instr, gen_helper_fcmpnled); break;
|
||||
case OP_FCMPODD: gen_alopf1_dedd(instr, gen_helper_fcmpodd); break;
|
||||
case OP_FSTOIS: gen_alopf2_ses(instr, gen_helper_fstois); break;
|
||||
case OP_FSTOISTR: gen_alopf2_ses(instr, gen_helper_fstoistr); break;
|
||||
case OP_ISTOFS: gen_alopf2_ses(instr, gen_helper_istofs); break;
|
||||
@ -3626,6 +3644,41 @@ static void gen_alop_simple(Instr *instr, uint32_t op)
|
||||
case OP_PFDIVD: gen_alopf1_dedd(instr, gen_helper_fdivd); break;
|
||||
case OP_PFMIND: gen_alopf1_dedd(instr, gen_helper_fmind); break;
|
||||
case OP_PFMAXD: gen_alopf1_dedd(instr, gen_helper_fmaxd); break;
|
||||
case OP_PFADDS: gen_alopf1_dedd(instr, gen_helper_pfadds); break;
|
||||
case OP_PFSUBS: gen_alopf1_dedd(instr, gen_helper_pfsubs); break;
|
||||
case OP_PFMULS: gen_alopf1_dedd(instr, gen_helper_pfmuls); break;
|
||||
case OP_PFDIVS: gen_alopf1_sess(instr, gen_helper_fdivs); break;
|
||||
case OP_PFMAXS: gen_alopf1_dedd(instr, gen_helper_pfmaxs); break;
|
||||
case OP_PFMINS: gen_alopf1_dedd(instr, gen_helper_pfmins); break;
|
||||
case OP_PFHADDS: gen_alopf1_dedd(instr, gen_helper_pfhadds); break;
|
||||
case OP_PFHSUBS: gen_alopf1_dedd(instr, gen_helper_pfhsubs); break;
|
||||
case OP_PFADDSUBS: gen_alopf1_dedd(instr, gen_helper_pfaddsubs); break;
|
||||
case OP_PFSQRTS: gen_alopf2_ses(instr, gen_helper_fsqrts); break;
|
||||
case OP_PFSTOIFS: gen_alopf1_dedd(instr, gen_helper_pfstoifs); break;
|
||||
case OP_PISTOFS: gen_alopf2_ded(instr, gen_helper_pistofs); break;
|
||||
case OP_PFSTOIS: gen_alopf2_ded(instr, gen_helper_pfstois); break;
|
||||
case OP_PFSTOISTR: gen_alopf2_ded(instr, gen_helper_pfstoistr); break;
|
||||
case OP_PFSTOFD: gen_alopf2_des(instr, gen_helper_fstofd); break;
|
||||
case OP_PFDTOFS: gen_alopf2_sed(instr, gen_helper_fdtofs); break;
|
||||
case OP_PFDTOIFD: gen_alopf1_dedd(instr, gen_helper_fdtoifd); break;
|
||||
case OP_PFDTOIS: gen_alopf2_sed(instr, gen_helper_fdtois); break;
|
||||
case OP_PFDTOISTR: gen_alopf2_sed(instr, gen_helper_fdtoistr); break;
|
||||
case OP_PFCMPEQS: gen_alopf1_dedd(instr, gen_helper_pfcmpeqs); break;
|
||||
case OP_PFCMPLTS: gen_alopf1_dedd(instr, gen_helper_pfcmplts); break;
|
||||
case OP_PFCMPLES: gen_alopf1_dedd(instr, gen_helper_pfcmples); break;
|
||||
case OP_PFCMPUODS: gen_alopf1_dedd(instr, gen_helper_pfcmpuods); break;
|
||||
case OP_PFCMPNEQS: gen_alopf1_dedd(instr, gen_helper_pfcmpneqs); break;
|
||||
case OP_PFCMPNLTS: gen_alopf1_dedd(instr, gen_helper_pfcmpnlts); break;
|
||||
case OP_PFCMPNLES: gen_alopf1_dedd(instr, gen_helper_pfcmpnles); break;
|
||||
case OP_PFCMPODS: gen_alopf1_dedd(instr, gen_helper_pfcmpods); break;
|
||||
case OP_PFCMPEQD: gen_alopf1_dedd(instr, gen_helper_fcmpeqd); break;
|
||||
case OP_PFCMPLTD: gen_alopf1_dedd(instr, gen_helper_fcmpltd); break;
|
||||
case OP_PFCMPLED: gen_alopf1_dedd(instr, gen_helper_fcmpled); break;
|
||||
case OP_PFCMPUODD: gen_alopf1_dedd(instr, gen_helper_fcmpuodd); break;
|
||||
case OP_PFCMPNEQD: gen_alopf1_dedd(instr, gen_helper_fcmpneqd); break;
|
||||
case OP_PFCMPNLTD: gen_alopf1_dedd(instr, gen_helper_fcmpnltd); break;
|
||||
case OP_PFCMPNLED: gen_alopf1_dedd(instr, gen_helper_fcmpnled); break;
|
||||
case OP_PFCMPODD: gen_alopf1_dedd(instr, gen_helper_fcmpodd); break;
|
||||
case OP_FSCALED: gen_alopf1_deds(instr, gen_helper_fscaled); break;
|
||||
case OP_FSCALES: gen_alopf1_sess(instr, gen_helper_fscales); break;
|
||||
case OP_FXSCALESX: gen_alopf1_xexi(instr, gen_helper_fxscalesx); break;
|
||||
@ -3644,13 +3697,15 @@ static void gen_alop_simple(Instr *instr, uint32_t op)
|
||||
#else
|
||||
#error Not implemented
|
||||
#endif
|
||||
case OP_PFSQRTTD: /* fallthrough */
|
||||
case OP_FSQRTTD: gen_alopf1_dedd(instr, gen_helper_fsqrttd); break;
|
||||
case OP_FXSQRTTSX: gen_alopf1_xsx(instr, gen_helper_fxsqrttxx); break;
|
||||
case OP_FXSQRTTDX: gen_alopf1_xdx(instr, gen_helper_fxsqrttxx); break;
|
||||
case OP_FXSQRTTXX: gen_alopf1_xxx(instr, gen_helper_fxsqrttxx); break;
|
||||
case OP_INSFS: gen_alopf21_i32(ctx, instr, gen_insfs); break;
|
||||
case OP_INSFS: gen_alopf21_i32(instr, gen_insfs); break;
|
||||
case OP_INSFD: gen_insfd(instr); break;
|
||||
case OP_PSHUFB: gen_alopf21_i64(ctx, instr, gen_helper_pshufb); break;
|
||||
case OP_PSHUFB: gen_alopf21_i64(instr, gen_helper_pshufb); break;
|
||||
case OP_PMERGE: gen_alopf21_i64(instr, gen_helper_pmerge); break;
|
||||
case OP_FXDIVTSS:
|
||||
case OP_FXDIVTDD:
|
||||
case OP_FXDIVTSX:
|
||||
@ -3684,13 +3739,6 @@ static void gen_alop_simple(Instr *instr, uint32_t op)
|
||||
case OP_MOVTRCS:
|
||||
case OP_MOVTRD:
|
||||
case OP_MOVTRCD:
|
||||
case OP_PFDTOIS:
|
||||
case OP_PFSTOIS:
|
||||
case OP_PFDTOISTR:
|
||||
case OP_PFSTOISTR:
|
||||
case OP_PISTOFS:
|
||||
case OP_PFSTOFD:
|
||||
case OP_PFDTOFS:
|
||||
case OP_GETPL:
|
||||
case OP_GETSAP:
|
||||
case OP_CUDTOAP:
|
||||
@ -3736,53 +3784,14 @@ static void gen_alop_simple(Instr *instr, uint32_t op)
|
||||
case OP_AAURRD:
|
||||
case OP_AAURRQ:
|
||||
*/
|
||||
case OP_PFMULS:
|
||||
case OP_PFADDS:
|
||||
case OP_PFSUBS:
|
||||
case OP_APTOAP:
|
||||
case OP_APTOAPB:
|
||||
case OP_GETVA:
|
||||
case OP_LDRD:
|
||||
case OP_PUTTC:
|
||||
case OP_PFDIVS:
|
||||
case OP_PFMINS:
|
||||
case OP_PFMAXS:
|
||||
case OP_PFSQRTTD:
|
||||
case OP_CAST:
|
||||
case OP_TDTOMP:
|
||||
case OP_ODTOAP:
|
||||
case OP_FCMPEQS:
|
||||
case OP_FCMPLTS:
|
||||
case OP_FCMPLES:
|
||||
case OP_FCMPUODS:
|
||||
case OP_FCMPNEQS:
|
||||
case OP_FCMPNLTS:
|
||||
case OP_FCMPNLES:
|
||||
case OP_FCMPODS:
|
||||
case OP_FCMPEQD:
|
||||
case OP_FCMPLTD:
|
||||
case OP_FCMPLED:
|
||||
case OP_FCMPUODD:
|
||||
case OP_FCMPNEQD:
|
||||
case OP_FCMPNLTD:
|
||||
case OP_FCMPNLED:
|
||||
case OP_FCMPODD:
|
||||
case OP_PFCMPEQS:
|
||||
case OP_PFCMPLTS:
|
||||
case OP_PFCMPLES:
|
||||
case OP_PFCMPUODS:
|
||||
case OP_PFCMPNEQS:
|
||||
case OP_PFCMPNLTS:
|
||||
case OP_PFCMPNLES:
|
||||
case OP_PFCMPODS:
|
||||
case OP_PFCMPEQD:
|
||||
case OP_PFCMPLTD:
|
||||
case OP_PFCMPLED:
|
||||
case OP_PFCMPUODD:
|
||||
case OP_PFCMPNEQD:
|
||||
case OP_PFCMPNLTD:
|
||||
case OP_PFCMPNLED:
|
||||
case OP_PFCMPODD:
|
||||
case OP_LDGDB:
|
||||
case OP_LDGDH:
|
||||
case OP_LDGDW:
|
||||
@ -3819,7 +3828,6 @@ static void gen_alop_simple(Instr *instr, uint32_t op)
|
||||
case OP_LDFSQ:
|
||||
case OP_LDGSQ:
|
||||
case OP_LDSSQ:
|
||||
case OP_PFSQRTS:
|
||||
case OP_GETTD:
|
||||
case OP_GETTC:
|
||||
case OP_INVTC:
|
||||
@ -3858,11 +3866,6 @@ static void gen_alop_simple(Instr *instr, uint32_t op)
|
||||
case OP_STODWW:
|
||||
case OP_MOVTRQ:
|
||||
case OP_MOVTRCQ:
|
||||
case OP_PFHADDS:
|
||||
case OP_PFHSUBS:
|
||||
case OP_PFADDSUBS:
|
||||
case OP_PFSTOIFS:
|
||||
case OP_PFDTOIFD:
|
||||
case OP_PUTTST:
|
||||
case OP_STAAQP:
|
||||
case OP_QPAND:
|
||||
@ -4099,7 +4102,7 @@ static void gen_alop_simple(Instr *instr, uint32_t op)
|
||||
case OP_QPFMSAS:
|
||||
case OP_QPFMASD:
|
||||
case OP_QPFMSAD:
|
||||
e2k_todo_illop(ctx, "unimplemented %d\n", op); break;
|
||||
e2k_todo_illop(ctx, "unimplemented %d", op); break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -4174,13 +4177,24 @@ static inline bool icomb_check(Instr *instr, IComb opc1, IComb opc2)
|
||||
typedef enum {
|
||||
FCOMB_ADD = 0,
|
||||
FCOMB_SUB = 1,
|
||||
FCOMB_HADD = 2,
|
||||
FCOMB_HSUB = 3,
|
||||
FCOMB_MUL = 4,
|
||||
FCOMB_RSUB = 5,
|
||||
FCOMB_ADDSUB = 7,
|
||||
FCOMB_COUNT = 8,
|
||||
} FComb;
|
||||
|
||||
static inline bool fcomb_is_add_unit(FComb op)
|
||||
{
|
||||
return op != FCOMB_MUL;
|
||||
switch (op) {
|
||||
case FCOMB_ADD:
|
||||
case FCOMB_SUB:
|
||||
case FCOMB_RSUB:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool fcomb_is_mul_unit(FComb op)
|
||||
@ -4192,17 +4206,88 @@ static inline bool fcomb_check(Instr *instr, FComb opc1, FComb opc2)
|
||||
{
|
||||
int ver = instr->ctx->version;
|
||||
|
||||
if (ver < 4 && is_chan_25(instr->chan)) {
|
||||
if (opc1 == FCOMB_RSUB || (ver < 4 && is_chan_25(instr->chan))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ver >= 2) {
|
||||
return !(fcomb_is_mul_unit(opc1) && fcomb_is_mul_unit(opc2));
|
||||
return (fcomb_is_add_unit(opc1) || fcomb_is_mul_unit(opc1))
|
||||
&& fcomb_is_add_unit(opc2);
|
||||
} else {
|
||||
return fcomb_is_add_unit(opc1) == fcomb_is_mul_unit(opc2);
|
||||
}
|
||||
}
|
||||
|
||||
static bool pfcomb_map[FCOMB_COUNT][FCOMB_COUNT] = { false };
|
||||
|
||||
static void pfcomb_init(DisasContext *ctx)
|
||||
{
|
||||
pfcomb_map[FCOMB_MUL][FCOMB_ADD] = true;
|
||||
pfcomb_map[FCOMB_MUL][FCOMB_SUB] = true;
|
||||
pfcomb_map[FCOMB_MUL][FCOMB_RSUB] = true;
|
||||
|
||||
if (ctx->version == 1) {
|
||||
pfcomb_map[FCOMB_ADD][FCOMB_MUL] = true;
|
||||
pfcomb_map[FCOMB_SUB][FCOMB_MUL] = true;
|
||||
}
|
||||
|
||||
if (ctx->version >= 2) {
|
||||
pfcomb_map[FCOMB_ADD][FCOMB_ADD] = true;
|
||||
pfcomb_map[FCOMB_ADD][FCOMB_SUB] = true;
|
||||
pfcomb_map[FCOMB_ADD][FCOMB_RSUB] = true;
|
||||
|
||||
pfcomb_map[FCOMB_SUB][FCOMB_ADD] = true;
|
||||
pfcomb_map[FCOMB_SUB][FCOMB_SUB] = true;
|
||||
pfcomb_map[FCOMB_SUB][FCOMB_RSUB] = true;
|
||||
}
|
||||
|
||||
if (ctx->version >= 3) {
|
||||
pfcomb_map[FCOMB_HADD][FCOMB_ADD] = true;
|
||||
pfcomb_map[FCOMB_HADD][FCOMB_SUB] = true;
|
||||
pfcomb_map[FCOMB_HADD][FCOMB_RSUB] = true;
|
||||
pfcomb_map[FCOMB_HADD][FCOMB_HADD] = true;
|
||||
pfcomb_map[FCOMB_HADD][FCOMB_HSUB] = true;
|
||||
pfcomb_map[FCOMB_HADD][FCOMB_ADDSUB] = true;
|
||||
|
||||
pfcomb_map[FCOMB_HSUB][FCOMB_ADD] = true;
|
||||
pfcomb_map[FCOMB_HSUB][FCOMB_SUB] = true;
|
||||
pfcomb_map[FCOMB_HSUB][FCOMB_RSUB] = true;
|
||||
pfcomb_map[FCOMB_HSUB][FCOMB_HADD] = true;
|
||||
pfcomb_map[FCOMB_HSUB][FCOMB_HSUB] = true;
|
||||
pfcomb_map[FCOMB_HSUB][FCOMB_ADDSUB] = true;
|
||||
|
||||
pfcomb_map[FCOMB_ADDSUB][FCOMB_ADD] = true;
|
||||
pfcomb_map[FCOMB_ADDSUB][FCOMB_SUB] = true;
|
||||
pfcomb_map[FCOMB_ADDSUB][FCOMB_RSUB] = true;
|
||||
pfcomb_map[FCOMB_ADDSUB][FCOMB_HADD] = true;
|
||||
pfcomb_map[FCOMB_ADDSUB][FCOMB_HSUB] = true;
|
||||
pfcomb_map[FCOMB_ADDSUB][FCOMB_ADDSUB] = true;
|
||||
|
||||
pfcomb_map[FCOMB_ADD][FCOMB_HADD] = true;
|
||||
pfcomb_map[FCOMB_ADD][FCOMB_HSUB] = true;
|
||||
pfcomb_map[FCOMB_ADD][FCOMB_ADDSUB] = true;
|
||||
|
||||
pfcomb_map[FCOMB_SUB][FCOMB_HADD] = true;
|
||||
pfcomb_map[FCOMB_SUB][FCOMB_HSUB] = true;
|
||||
pfcomb_map[FCOMB_SUB][FCOMB_ADDSUB] = true;
|
||||
|
||||
pfcomb_map[FCOMB_MUL][FCOMB_HADD] = true;
|
||||
pfcomb_map[FCOMB_MUL][FCOMB_HSUB] = true;
|
||||
pfcomb_map[FCOMB_MUL][FCOMB_ADDSUB] = true;
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool pfcomb_check(Instr *instr, FComb opc1, FComb opc2)
|
||||
{
|
||||
int ver = instr->ctx->version;
|
||||
|
||||
if (ver < 4 && is_chan_25(instr->chan)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return pfcomb_map[opc1][opc2];
|
||||
}
|
||||
|
||||
#define IMPL_GEN_FCOMB_OP(S, T) \
|
||||
static void glue(gen_fcomb_op_, S)(Instr *instr, FComb opc, \
|
||||
glue(TCGv_, S) ret, glue(TCGv_, S) arg1, glue(TCGv_, S) arg2) \
|
||||
@ -4212,25 +4297,58 @@ static inline bool fcomb_check(Instr *instr, FComb opc1, FComb opc2)
|
||||
case FCOMB_SUB: glue(gen_helper_fsub, T)(ret, cpu_env, arg1, arg2); break; \
|
||||
case FCOMB_MUL: glue(gen_helper_fmul, T)(ret, cpu_env, arg1, arg2); break; \
|
||||
case FCOMB_RSUB: glue(gen_helper_fsub, T)(ret, cpu_env, arg2, arg1); break; \
|
||||
default: g_assert_not_reached(); break; \
|
||||
default: e2k_tr_gen_exception(instr->ctx, E2K_EXCP_ILLOPC); break; \
|
||||
} \
|
||||
}
|
||||
|
||||
IMPL_GEN_FCOMB_OP(i64, d)
|
||||
IMPL_GEN_FCOMB_OP(i32, s)
|
||||
|
||||
static inline int comb_opc1(Instr *instr)
|
||||
static void gen_pfcomb_op_i32(Instr *instr, FComb opc,
|
||||
TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
|
||||
{
|
||||
return (instr->opc1 >> 1) & 0xf;
|
||||
switch (opc) {
|
||||
case FCOMB_ADD: gen_helper_pfadds(ret, cpu_env, arg1, arg2); break;
|
||||
case FCOMB_SUB: gen_helper_pfsubs(ret, cpu_env, arg1, arg2); break;
|
||||
case FCOMB_HADD: gen_helper_pfhadds(ret, cpu_env, arg1, arg2); break;
|
||||
case FCOMB_HSUB: gen_helper_pfhsubs(ret, cpu_env, arg1, arg2); break;
|
||||
case FCOMB_MUL: gen_helper_pfmuls(ret, cpu_env, arg1, arg2); break;
|
||||
case FCOMB_RSUB: gen_helper_pfsubs(ret, cpu_env, arg2, arg1); break;
|
||||
case FCOMB_ADDSUB: gen_helper_pfaddsubs(ret, cpu_env, arg1, arg2); break;
|
||||
default: e2k_tr_gen_exception(instr->ctx, E2K_EXCP_ILLOPC); break;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int comb_opc2(Instr *instr)
|
||||
static void gen_pfcomb_op_i64(Instr *instr, FComb opc,
|
||||
TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
|
||||
{
|
||||
return ((instr->opc2 & 3) << 2) | ((instr->opc1 >> 5) & 3);
|
||||
switch (opc) {
|
||||
case FCOMB_ADD: gen_helper_faddd(ret, cpu_env, arg1, arg2); break;
|
||||
case FCOMB_SUB: gen_helper_fsubd(ret, cpu_env, arg1, arg2); break;
|
||||
case FCOMB_MUL: gen_helper_fmuld(ret, cpu_env, arg1, arg2); break;
|
||||
case FCOMB_RSUB: gen_helper_fsubd(ret, cpu_env, arg2, arg1); break;
|
||||
default: e2k_tr_gen_exception(instr->ctx, E2K_EXCP_ILLOPC); break;
|
||||
}
|
||||
}
|
||||
|
||||
#define IMPL_GEN_COMB(P, S, T) \
|
||||
static void glue4(gen_, P, _, S)(Instr *instr, int opc1, int opc2) \
|
||||
static inline int comb_opc1(Instr *instr, int m1)
|
||||
{
|
||||
return (instr->opc1 >> 1) & m1;
|
||||
}
|
||||
|
||||
static inline int comb_opc2(Instr *instr, int m1, int m2)
|
||||
{
|
||||
return ((instr->opc2 & m2) << 2) | ((instr->opc1 >> 5) & m1);
|
||||
}
|
||||
|
||||
#define icomb_opc1(instr) comb_opc1(instr, 0xf)
|
||||
#define fcomb_opc1(instr) comb_opc1(instr, 0x7)
|
||||
|
||||
#define icomb_opc2(instr) comb_opc2(instr, 0x3, 0x3)
|
||||
#define fcomb_opc2(instr) comb_opc2(instr, 0x3, 0x1)
|
||||
|
||||
#define IMPL_GEN_COMB(NAME, P, S, T, OP) \
|
||||
static void NAME(Instr *instr, int opc1, int opc2) \
|
||||
{ \
|
||||
glue(Src, T) s1 = glue(get_src1_, S)(instr); \
|
||||
glue(Src, T) s2 = glue(get_src2_, S)(instr); \
|
||||
@ -4238,39 +4356,34 @@ static inline int comb_opc2(Instr *instr)
|
||||
TCGv_i32 tag = get_temp_i32(instr); \
|
||||
glue(TCGv_, S) dst = glue(get_temp_, S)(instr); \
|
||||
glue(gen_tag3_, S)(tag, s1.tag, s2.tag, s3.tag); \
|
||||
glue4(gen_, P, _op_, S)(instr, opc1, dst, s1.value, s2.value); \
|
||||
glue4(gen_, P, _op_, S)(instr, opc2, dst, s3.value, dst); \
|
||||
OP(instr, opc1, dst, s1.value, s2.value); \
|
||||
OP(instr, opc2, dst, s3.value, dst); \
|
||||
glue(gen_al_result_, S)(instr, dst, tag); \
|
||||
}
|
||||
|
||||
IMPL_GEN_COMB(icomb, i64, 64)
|
||||
IMPL_GEN_COMB(icomb, i32, 32)
|
||||
IMPL_GEN_COMB(fcomb, i64, 64)
|
||||
IMPL_GEN_COMB(fcomb, i32, 32)
|
||||
IMPL_GEN_COMB(gen_icomb_i64, icomb, i64, 64, gen_icomb_op_i64)
|
||||
IMPL_GEN_COMB(gen_icomb_i32, icomb, i32, 32, gen_icomb_op_i32)
|
||||
IMPL_GEN_COMB(gen_fcomb_i64, fcomb, i64, 64, gen_fcomb_op_i64)
|
||||
IMPL_GEN_COMB(gen_fcomb_i32, fcomb, i32, 32, gen_fcomb_op_i32)
|
||||
IMPL_GEN_COMB(gen_pfcomb_i64, pfcomb, i64, 64, gen_pfcomb_op_i64)
|
||||
IMPL_GEN_COMB(gen_pfcomb_i32, pfcomb, i64, 64, gen_pfcomb_op_i32)
|
||||
|
||||
static void gen_icomb(Instr *instr, uint32_t op)
|
||||
{
|
||||
int opc1 = op & 0xffff;
|
||||
int opc2 = op >> 16;
|
||||
|
||||
if (instr->opc1 & 1) {
|
||||
gen_icomb_i64(instr, opc1, opc2);
|
||||
} else {
|
||||
gen_icomb_i32(instr, opc1, opc2);
|
||||
#define IMPL_GEN_COMB_SELECT(NAME) \
|
||||
static void glue(gen_, NAME)(Instr *instr, uint32_t op) \
|
||||
{ \
|
||||
int opc1 = op & 0xffff; \
|
||||
int opc2 = op >> 16; \
|
||||
\
|
||||
if (instr->opc1 & 1) { \
|
||||
glue3(gen_, NAME, _i64)(instr, opc1, opc2); \
|
||||
} else { \
|
||||
glue3(gen_, NAME, _i32)(instr, opc1, opc2); \
|
||||
} \
|
||||
}
|
||||
}
|
||||
|
||||
static void gen_fcomb(Instr *instr, uint32_t op)
|
||||
{
|
||||
int opc1 = op & 0xffff;
|
||||
int opc2 = op >> 16;
|
||||
|
||||
if (instr->opc1 & 1) {
|
||||
gen_fcomb_i64(instr, opc1, opc2);
|
||||
} else {
|
||||
gen_fcomb_i32(instr, opc1, opc2);
|
||||
}
|
||||
}
|
||||
IMPL_GEN_COMB_SELECT(icomb)
|
||||
IMPL_GEN_COMB_SELECT(fcomb)
|
||||
IMPL_GEN_COMB_SELECT(pfcomb)
|
||||
|
||||
static void gen_lcomb_i64(Instr *instr, uint32_t base)
|
||||
{
|
||||
@ -4392,6 +4505,10 @@ static void alop_decode(Instr *instr)
|
||||
{
|
||||
Alop *alop = &instr->ctx->bundle2.alops[instr->chan];
|
||||
|
||||
alop->format = ALOPF_NONE;
|
||||
alop->op = 0;
|
||||
alop->name = "none";
|
||||
|
||||
switch (instr->opc2) {
|
||||
case SHORT:
|
||||
case EXT:
|
||||
@ -4404,6 +4521,7 @@ static void alop_decode(Instr *instr)
|
||||
}
|
||||
alop->format = desc->alopf;
|
||||
alop->op = desc->op;
|
||||
alop->name = desc->dsc;
|
||||
break;
|
||||
}
|
||||
case ICMB0:
|
||||
@ -4420,8 +4538,8 @@ static void alop_decode(Instr *instr)
|
||||
alop->format = ALOPF21;
|
||||
alop->op = instr->opc1 & 1 ? OP_INSFD : OP_INSFS;
|
||||
} else {
|
||||
int opc1 = comb_opc1(instr);
|
||||
int opc2 = comb_opc2(instr);
|
||||
int opc1 = icomb_opc1(instr);
|
||||
int opc2 = icomb_opc2(instr);
|
||||
if (!icomb_check(instr, opc1, opc2)) {
|
||||
e2k_tr_gen_exception(instr->ctx, E2K_EXCP_ILLOPC);
|
||||
return;
|
||||
@ -4430,10 +4548,16 @@ static void alop_decode(Instr *instr)
|
||||
alop->op = (opc2 << 16) | opc1;
|
||||
}
|
||||
break;
|
||||
case FLB:
|
||||
case FLH:
|
||||
case FLW:
|
||||
case FLD:
|
||||
e2k_todo_illop(instr->ctx, "flags ops");
|
||||
break;
|
||||
case FCMB0:
|
||||
case FCMB1: {
|
||||
int opc1 = comb_opc1(instr);
|
||||
int opc2 = comb_opc2(instr);
|
||||
int opc1 = fcomb_opc1(instr);
|
||||
int opc2 = fcomb_opc2(instr);
|
||||
if (!fcomb_check(instr, opc1, opc2)) {
|
||||
e2k_tr_gen_exception(instr->ctx, E2K_EXCP_ILLOPC);
|
||||
return;
|
||||
@ -4442,15 +4566,27 @@ static void alop_decode(Instr *instr)
|
||||
alop->op = (opc2 << 16) | opc1;
|
||||
break;
|
||||
}
|
||||
case PFCMB0:
|
||||
case PFCMB1:
|
||||
if (instr->opc1 == 0x4d
|
||||
&& is_chan_0134(instr->chan)
|
||||
&& instr->ctx->version >= 2)
|
||||
if (instr->opc2 == PFCMB1 && is_chan_0134(instr->chan)
|
||||
&& instr->ctx->version >= 2 && instr->opc1 == 0x4d)
|
||||
{
|
||||
alop->format = ALOPF12_PSHUFH;
|
||||
alop->op = OP_PSHUFB;
|
||||
} else if (instr->opc2 == PFCMB1 && is_chan_0134(instr->chan)
|
||||
&& instr->ctx->version >= 2 && instr->opc1 == 0x6d)
|
||||
{
|
||||
alop->format = ALOPF21;
|
||||
alop->op = OP_PMERGE;
|
||||
} else {
|
||||
e2k_tr_gen_exception(instr->ctx, E2K_EXCP_ILLOPC);
|
||||
int opc1 = fcomb_opc1(instr);
|
||||
int opc2 = fcomb_opc2(instr);
|
||||
if (!pfcomb_check(instr, opc1, opc2)) {
|
||||
e2k_tr_gen_exception(instr->ctx, E2K_EXCP_ILLOPC);
|
||||
return;
|
||||
}
|
||||
alop->format = ALOPF21_PFCOMB;
|
||||
alop->op = (opc2 << 16) | opc1;
|
||||
}
|
||||
break;
|
||||
case LCMBD0:
|
||||
@ -4462,6 +4598,14 @@ static void alop_decode(Instr *instr)
|
||||
e2k_tr_gen_exception(instr->ctx, E2K_EXCP_ILLOPC);
|
||||
}
|
||||
break;
|
||||
case LCMBQ0:
|
||||
case LCMBQ1:
|
||||
e2k_todo_illop(instr->ctx, "logical combined ops");
|
||||
break;
|
||||
case QPFCMB0:
|
||||
case QPFCMB1:
|
||||
e2k_todo_illop(instr->ctx, "packed128 float combined ops");
|
||||
break;
|
||||
default:
|
||||
e2k_tr_gen_exception(instr->ctx, E2K_EXCP_ILLOPC);
|
||||
break;
|
||||
@ -4499,6 +4643,9 @@ static void gen_alop(Instr *instr, Alop *alop)
|
||||
case ALOPF21_FCOMB:
|
||||
gen_fcomb(instr, alop->op);
|
||||
break;
|
||||
case ALOPF21_PFCOMB:
|
||||
gen_pfcomb(instr, alop->op);
|
||||
break;
|
||||
case ALOPF21_LCOMB:
|
||||
gen_lcomb_i64(instr, alop->op);
|
||||
break;
|
||||
@ -4700,6 +4847,8 @@ void alc_init(DisasContext *ctx)
|
||||
int i, j;
|
||||
|
||||
memset(alops_map, -1, sizeof(alops_map));
|
||||
memset(pfcomb_map, 0, sizeof(pfcomb_map));
|
||||
|
||||
// TODO: symmetric alops table
|
||||
/* Most alops are symmetric and can be stored in a half table. */
|
||||
for (i = 0; i < ARRAY_SIZE(alops); i++) {
|
||||
@ -4714,4 +4863,6 @@ void alc_init(DisasContext *ctx)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pfcomb_init(ctx);
|
||||
}
|
||||
|
@ -791,6 +791,7 @@ enum {
|
||||
OP_INSFS,
|
||||
OP_INSFD,
|
||||
OP_PSHUFB,
|
||||
OP_PMERGE,
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
@ -925,8 +926,8 @@ typedef enum {
|
||||
} AlopExt;
|
||||
|
||||
typedef struct {
|
||||
uint16_t op;
|
||||
const char *dsc;
|
||||
uint16_t op;
|
||||
uint8_t alopf;
|
||||
AlopArgs format;
|
||||
uint8_t opc2;
|
||||
@ -939,7 +940,7 @@ typedef struct {
|
||||
uint8_t extra2; /* opce2, implicit_nops, explicit_ales25_v4 */
|
||||
} AlopDesc;
|
||||
|
||||
#define X(x) x, #x
|
||||
#define X(x) #x, x
|
||||
|
||||
static AlopDesc alops[] = {
|
||||
{ X(OP_ADDS), ALOPF1, ARGS_SSS, SHORT, 0x10, 1, -1, CHAN_012345, { -1 } },
|
||||
|
Loading…
Reference in New Issue
Block a user