target/loongarch: Implement vilvl vilvh vextrins vshuf
This patch includes: - VILV{L/H}.{B/H/W/D}; - VSHUF.{B/H/W/D}; - VSHUF4I.{B/H/W/D}; - VPERMI.W; - VEXTRINS.{B/H/W/D}. Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Song Gao <gaosong@loongson.cn> Message-Id: <20230504122810.4094787-41-gaosong@loongson.cn>
This commit is contained in:
parent
d5e5563cb3
commit
e93dd43147
@ -1629,3 +1629,28 @@ INSN_LSX(vpickod_b, vvv)
|
||||
INSN_LSX(vpickod_h, vvv)
|
||||
INSN_LSX(vpickod_w, vvv)
|
||||
INSN_LSX(vpickod_d, vvv)
|
||||
|
||||
INSN_LSX(vilvl_b, vvv)
|
||||
INSN_LSX(vilvl_h, vvv)
|
||||
INSN_LSX(vilvl_w, vvv)
|
||||
INSN_LSX(vilvl_d, vvv)
|
||||
INSN_LSX(vilvh_b, vvv)
|
||||
INSN_LSX(vilvh_h, vvv)
|
||||
INSN_LSX(vilvh_w, vvv)
|
||||
INSN_LSX(vilvh_d, vvv)
|
||||
|
||||
INSN_LSX(vshuf_b, vvvv)
|
||||
INSN_LSX(vshuf_h, vvv)
|
||||
INSN_LSX(vshuf_w, vvv)
|
||||
INSN_LSX(vshuf_d, vvv)
|
||||
INSN_LSX(vshuf4i_b, vv_i)
|
||||
INSN_LSX(vshuf4i_h, vv_i)
|
||||
INSN_LSX(vshuf4i_w, vv_i)
|
||||
INSN_LSX(vshuf4i_d, vv_i)
|
||||
|
||||
INSN_LSX(vpermi_w, vv_i)
|
||||
|
||||
INSN_LSX(vextrins_d, vv_i)
|
||||
INSN_LSX(vextrins_w, vv_i)
|
||||
INSN_LSX(vextrins_h, vv_i)
|
||||
INSN_LSX(vextrins_b, vv_i)
|
||||
|
@ -671,3 +671,28 @@ DEF_HELPER_4(vpickod_b, void, env, i32, i32, i32)
|
||||
DEF_HELPER_4(vpickod_h, void, env, i32, i32, i32)
|
||||
DEF_HELPER_4(vpickod_w, void, env, i32, i32, i32)
|
||||
DEF_HELPER_4(vpickod_d, void, env, i32, i32, i32)
|
||||
|
||||
DEF_HELPER_4(vilvl_b, void, env, i32, i32, i32)
|
||||
DEF_HELPER_4(vilvl_h, void, env, i32, i32, i32)
|
||||
DEF_HELPER_4(vilvl_w, void, env, i32, i32, i32)
|
||||
DEF_HELPER_4(vilvl_d, void, env, i32, i32, i32)
|
||||
DEF_HELPER_4(vilvh_b, void, env, i32, i32, i32)
|
||||
DEF_HELPER_4(vilvh_h, void, env, i32, i32, i32)
|
||||
DEF_HELPER_4(vilvh_w, void, env, i32, i32, i32)
|
||||
DEF_HELPER_4(vilvh_d, void, env, i32, i32, i32)
|
||||
|
||||
DEF_HELPER_5(vshuf_b, void, env, i32, i32, i32, i32)
|
||||
DEF_HELPER_4(vshuf_h, void, env, i32, i32, i32)
|
||||
DEF_HELPER_4(vshuf_w, void, env, i32, i32, i32)
|
||||
DEF_HELPER_4(vshuf_d, void, env, i32, i32, i32)
|
||||
DEF_HELPER_4(vshuf4i_b, void, env, i32, i32, i32)
|
||||
DEF_HELPER_4(vshuf4i_h, void, env, i32, i32, i32)
|
||||
DEF_HELPER_4(vshuf4i_w, void, env, i32, i32, i32)
|
||||
DEF_HELPER_4(vshuf4i_d, void, env, i32, i32, i32)
|
||||
|
||||
DEF_HELPER_4(vpermi_w, void, env, i32, i32, i32)
|
||||
|
||||
DEF_HELPER_4(vextrins_b, void, env, i32, i32, i32)
|
||||
DEF_HELPER_4(vextrins_h, void, env, i32, i32, i32)
|
||||
DEF_HELPER_4(vextrins_w, void, env, i32, i32, i32)
|
||||
DEF_HELPER_4(vextrins_d, void, env, i32, i32, i32)
|
||||
|
@ -4077,3 +4077,28 @@ TRANS(vpickod_b, gen_vvv, gen_helper_vpickod_b)
|
||||
TRANS(vpickod_h, gen_vvv, gen_helper_vpickod_h)
|
||||
TRANS(vpickod_w, gen_vvv, gen_helper_vpickod_w)
|
||||
TRANS(vpickod_d, gen_vvv, gen_helper_vpickod_d)
|
||||
|
||||
TRANS(vilvl_b, gen_vvv, gen_helper_vilvl_b)
|
||||
TRANS(vilvl_h, gen_vvv, gen_helper_vilvl_h)
|
||||
TRANS(vilvl_w, gen_vvv, gen_helper_vilvl_w)
|
||||
TRANS(vilvl_d, gen_vvv, gen_helper_vilvl_d)
|
||||
TRANS(vilvh_b, gen_vvv, gen_helper_vilvh_b)
|
||||
TRANS(vilvh_h, gen_vvv, gen_helper_vilvh_h)
|
||||
TRANS(vilvh_w, gen_vvv, gen_helper_vilvh_w)
|
||||
TRANS(vilvh_d, gen_vvv, gen_helper_vilvh_d)
|
||||
|
||||
TRANS(vshuf_b, gen_vvvv, gen_helper_vshuf_b)
|
||||
TRANS(vshuf_h, gen_vvv, gen_helper_vshuf_h)
|
||||
TRANS(vshuf_w, gen_vvv, gen_helper_vshuf_w)
|
||||
TRANS(vshuf_d, gen_vvv, gen_helper_vshuf_d)
|
||||
TRANS(vshuf4i_b, gen_vv_i, gen_helper_vshuf4i_b)
|
||||
TRANS(vshuf4i_h, gen_vv_i, gen_helper_vshuf4i_h)
|
||||
TRANS(vshuf4i_w, gen_vv_i, gen_helper_vshuf4i_w)
|
||||
TRANS(vshuf4i_d, gen_vv_i, gen_helper_vshuf4i_d)
|
||||
|
||||
TRANS(vpermi_w, gen_vv_i, gen_helper_vpermi_w)
|
||||
|
||||
TRANS(vextrins_b, gen_vv_i, gen_helper_vextrins_b)
|
||||
TRANS(vextrins_h, gen_vv_i, gen_helper_vextrins_h)
|
||||
TRANS(vextrins_w, gen_vv_i, gen_helper_vextrins_w)
|
||||
TRANS(vextrins_d, gen_vv_i, gen_helper_vextrins_d)
|
||||
|
@ -1231,3 +1231,28 @@ vpickod_b 0111 00010010 00000 ..... ..... ..... @vvv
|
||||
vpickod_h 0111 00010010 00001 ..... ..... ..... @vvv
|
||||
vpickod_w 0111 00010010 00010 ..... ..... ..... @vvv
|
||||
vpickod_d 0111 00010010 00011 ..... ..... ..... @vvv
|
||||
|
||||
vilvl_b 0111 00010001 10100 ..... ..... ..... @vvv
|
||||
vilvl_h 0111 00010001 10101 ..... ..... ..... @vvv
|
||||
vilvl_w 0111 00010001 10110 ..... ..... ..... @vvv
|
||||
vilvl_d 0111 00010001 10111 ..... ..... ..... @vvv
|
||||
vilvh_b 0111 00010001 11000 ..... ..... ..... @vvv
|
||||
vilvh_h 0111 00010001 11001 ..... ..... ..... @vvv
|
||||
vilvh_w 0111 00010001 11010 ..... ..... ..... @vvv
|
||||
vilvh_d 0111 00010001 11011 ..... ..... ..... @vvv
|
||||
|
||||
vshuf_b 0000 11010101 ..... ..... ..... ..... @vvvv
|
||||
vshuf_h 0111 00010111 10101 ..... ..... ..... @vvv
|
||||
vshuf_w 0111 00010111 10110 ..... ..... ..... @vvv
|
||||
vshuf_d 0111 00010111 10111 ..... ..... ..... @vvv
|
||||
vshuf4i_b 0111 00111001 00 ........ ..... ..... @vv_ui8
|
||||
vshuf4i_h 0111 00111001 01 ........ ..... ..... @vv_ui8
|
||||
vshuf4i_w 0111 00111001 10 ........ ..... ..... @vv_ui8
|
||||
vshuf4i_d 0111 00111001 11 ........ ..... ..... @vv_ui8
|
||||
|
||||
vpermi_w 0111 00111110 01 ........ ..... ..... @vv_ui8
|
||||
|
||||
vextrins_d 0111 00111000 00 ........ ..... ..... @vv_ui8
|
||||
vextrins_w 0111 00111000 01 ........ ..... ..... @vv_ui8
|
||||
vextrins_h 0111 00111000 10 ........ ..... ..... @vv_ui8
|
||||
vextrins_b 0111 00111000 11 ........ ..... ..... @vv_ui8
|
||||
|
@ -2854,3 +2854,151 @@ VPICKOD(vpickod_b, 16, B)
|
||||
VPICKOD(vpickod_h, 32, H)
|
||||
VPICKOD(vpickod_w, 64, W)
|
||||
VPICKOD(vpickod_d, 128, D)
|
||||
|
||||
#define VILVL(NAME, BIT, E) \
|
||||
void HELPER(NAME)(CPULoongArchState *env, \
|
||||
uint32_t vd, uint32_t vj, uint32_t vk) \
|
||||
{ \
|
||||
int i; \
|
||||
VReg temp; \
|
||||
VReg *Vd = &(env->fpr[vd].vreg); \
|
||||
VReg *Vj = &(env->fpr[vj].vreg); \
|
||||
VReg *Vk = &(env->fpr[vk].vreg); \
|
||||
\
|
||||
for (i = 0; i < LSX_LEN/BIT; i++) { \
|
||||
temp.E(2 * i + 1) = Vj->E(i); \
|
||||
temp.E(2 * i) = Vk->E(i); \
|
||||
} \
|
||||
*Vd = temp; \
|
||||
}
|
||||
|
||||
VILVL(vilvl_b, 16, B)
|
||||
VILVL(vilvl_h, 32, H)
|
||||
VILVL(vilvl_w, 64, W)
|
||||
VILVL(vilvl_d, 128, D)
|
||||
|
||||
#define VILVH(NAME, BIT, E) \
|
||||
void HELPER(NAME)(CPULoongArchState *env, \
|
||||
uint32_t vd, uint32_t vj, uint32_t vk) \
|
||||
{ \
|
||||
int i; \
|
||||
VReg temp; \
|
||||
VReg *Vd = &(env->fpr[vd].vreg); \
|
||||
VReg *Vj = &(env->fpr[vj].vreg); \
|
||||
VReg *Vk = &(env->fpr[vk].vreg); \
|
||||
\
|
||||
for (i = 0; i < LSX_LEN/BIT; i++) { \
|
||||
temp.E(2 * i + 1) = Vj->E(i + LSX_LEN/BIT); \
|
||||
temp.E(2 * i) = Vk->E(i + LSX_LEN/BIT); \
|
||||
} \
|
||||
*Vd = temp; \
|
||||
}
|
||||
|
||||
VILVH(vilvh_b, 16, B)
|
||||
VILVH(vilvh_h, 32, H)
|
||||
VILVH(vilvh_w, 64, W)
|
||||
VILVH(vilvh_d, 128, D)
|
||||
|
||||
void HELPER(vshuf_b)(CPULoongArchState *env,
|
||||
uint32_t vd, uint32_t vj, uint32_t vk, uint32_t va)
|
||||
{
|
||||
int i, m;
|
||||
VReg temp;
|
||||
VReg *Vd = &(env->fpr[vd].vreg);
|
||||
VReg *Vj = &(env->fpr[vj].vreg);
|
||||
VReg *Vk = &(env->fpr[vk].vreg);
|
||||
VReg *Va = &(env->fpr[va].vreg);
|
||||
|
||||
m = LSX_LEN/8;
|
||||
for (i = 0; i < m ; i++) {
|
||||
uint64_t k = (uint8_t)Va->B(i) % (2 * m);
|
||||
temp.B(i) = k < m ? Vk->B(k) : Vj->B(k - m);
|
||||
}
|
||||
*Vd = temp;
|
||||
}
|
||||
|
||||
#define VSHUF(NAME, BIT, E) \
|
||||
void HELPER(NAME)(CPULoongArchState *env, \
|
||||
uint32_t vd, uint32_t vj, uint32_t vk) \
|
||||
{ \
|
||||
int i, m; \
|
||||
VReg temp; \
|
||||
VReg *Vd = &(env->fpr[vd].vreg); \
|
||||
VReg *Vj = &(env->fpr[vj].vreg); \
|
||||
VReg *Vk = &(env->fpr[vk].vreg); \
|
||||
\
|
||||
m = LSX_LEN/BIT; \
|
||||
for (i = 0; i < m; i++) { \
|
||||
uint64_t k = ((uint8_t) Vd->E(i)) % (2 * m); \
|
||||
temp.E(i) = k < m ? Vk->E(k) : Vj->E(k - m); \
|
||||
} \
|
||||
*Vd = temp; \
|
||||
}
|
||||
|
||||
VSHUF(vshuf_h, 16, H)
|
||||
VSHUF(vshuf_w, 32, W)
|
||||
VSHUF(vshuf_d, 64, D)
|
||||
|
||||
#define VSHUF4I(NAME, BIT, E) \
|
||||
void HELPER(NAME)(CPULoongArchState *env, \
|
||||
uint32_t vd, uint32_t vj, uint32_t imm) \
|
||||
{ \
|
||||
int i; \
|
||||
VReg temp; \
|
||||
VReg *Vd = &(env->fpr[vd].vreg); \
|
||||
VReg *Vj = &(env->fpr[vj].vreg); \
|
||||
\
|
||||
for (i = 0; i < LSX_LEN/BIT; i++) { \
|
||||
temp.E(i) = Vj->E(((i) & 0xfc) + (((imm) >> \
|
||||
(2 * ((i) & 0x03))) & 0x03)); \
|
||||
} \
|
||||
*Vd = temp; \
|
||||
}
|
||||
|
||||
VSHUF4I(vshuf4i_b, 8, B)
|
||||
VSHUF4I(vshuf4i_h, 16, H)
|
||||
VSHUF4I(vshuf4i_w, 32, W)
|
||||
|
||||
void HELPER(vshuf4i_d)(CPULoongArchState *env,
|
||||
uint32_t vd, uint32_t vj, uint32_t imm)
|
||||
{
|
||||
VReg *Vd = &(env->fpr[vd].vreg);
|
||||
VReg *Vj = &(env->fpr[vj].vreg);
|
||||
|
||||
VReg temp;
|
||||
temp.D(0) = (imm & 2 ? Vj : Vd)->D(imm & 1);
|
||||
temp.D(1) = (imm & 8 ? Vj : Vd)->D((imm >> 2) & 1);
|
||||
*Vd = temp;
|
||||
}
|
||||
|
||||
void HELPER(vpermi_w)(CPULoongArchState *env,
|
||||
uint32_t vd, uint32_t vj, uint32_t imm)
|
||||
{
|
||||
VReg temp;
|
||||
VReg *Vd = &(env->fpr[vd].vreg);
|
||||
VReg *Vj = &(env->fpr[vj].vreg);
|
||||
|
||||
temp.W(0) = Vj->W(imm & 0x3);
|
||||
temp.W(1) = Vj->W((imm >> 2) & 0x3);
|
||||
temp.W(2) = Vd->W((imm >> 4) & 0x3);
|
||||
temp.W(3) = Vd->W((imm >> 6) & 0x3);
|
||||
*Vd = temp;
|
||||
}
|
||||
|
||||
#define VEXTRINS(NAME, BIT, E, MASK) \
|
||||
void HELPER(NAME)(CPULoongArchState *env, \
|
||||
uint32_t vd, uint32_t vj, uint32_t imm) \
|
||||
{ \
|
||||
int ins, extr; \
|
||||
VReg *Vd = &(env->fpr[vd].vreg); \
|
||||
VReg *Vj = &(env->fpr[vj].vreg); \
|
||||
\
|
||||
ins = (imm >> 4) & MASK; \
|
||||
extr = imm & MASK; \
|
||||
Vd->E(ins) = Vj->E(extr); \
|
||||
}
|
||||
|
||||
VEXTRINS(vextrins_b, 8, B, 0xf)
|
||||
VEXTRINS(vextrins_h, 16, H, 0x7)
|
||||
VEXTRINS(vextrins_w, 32, W, 0x3)
|
||||
VEXTRINS(vextrins_d, 64, D, 0x1)
|
||||
|
Loading…
Reference in New Issue
Block a user