Added recompiled versions of PMULLW, PMULHW and PMADDWD.

This commit is contained in:
SarahW 2018-11-24 12:52:08 +00:00
commit 086422b79f
16 changed files with 314 additions and 13 deletions

View file

@ -151,9 +151,11 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val)
#define OPCODE_LSL (0x1ac02000)
#define OPCODE_LSR (0x1ac02400)
#define OPCODE_MSR_FPCR (0xd51b4400)
#define OPCODE_MUL_V4H (0x0e609c00)
#define OPCODE_NOP (0xd503201f)
#define OPCODE_ORR_V (0x0ea01c00)
#define OPCODE_RET (0xd65f0000)
#define OPCODE_SADDLP_V2S_4H (0x0e602800)
#define OPCODE_SCVTF_D_Q (0x9e620000)
#define OPCODE_SCVTF_D_W (0x1e620000)
#define OPCODE_SQADD_V8B (0x0e200c00)
@ -164,6 +166,8 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val)
#define OPCODE_SQXTN_V4H_4S (0x0e614800)
#define OPCODE_SHL_VD (0x0e005400)
#define OPCODE_SHL_VQ (0x4e005400)
#define OPCODE_SHRN (0x0f008400)
#define OPCODE_SMULL_V4S_4H (0x0e60c000)
#define OPCODE_SSHR_VD (0x0e004400)
#define OPCODE_SSHR_VQ (0x4e004400)
#define OPCODE_STR_REG (0xb8206800)
@ -900,6 +904,11 @@ void host_arm64_MSR_FPCR(codeblock_t *block, int src_reg)
codegen_addlong(block, OPCODE_MSR_FPCR | Rd(src_reg));
}
void host_arm64_MUL_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg)
{
codegen_addlong(block, OPCODE_MUL_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg));
}
void host_arm64_NOP(codeblock_t *block)
{
codegen_addlong(block, OPCODE_NOP);
@ -943,6 +952,11 @@ void host_arm64_RET(codeblock_t *block, int reg)
codegen_addlong(block, OPCODE_RET | Rn(reg));
}
void host_arm64_SADDLP_V2S_4H(codeblock_t *block, int dst_reg, int src_n_reg)
{
codegen_addlong(block, OPCODE_SADDLP_V2S_4H | Rd(dst_reg) | Rn(src_n_reg));
}
void host_arm64_SBFX(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width)
{
codegen_addlong(block, OPCODE_SBFX | Rd(dst_reg) | Rn(src_reg) | IMMN(0) | IMMR(lsb) | IMMS((lsb+width-1) & 31));
@ -957,6 +971,16 @@ void host_arm64_SCVTF_D_W(codeblock_t *block, int dst_reg, int src_reg)
codegen_addlong(block, OPCODE_SCVTF_D_W | Rd(dst_reg) | Rn(src_reg));
}
void host_arm64_SHRN_V4S_4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift)
{
codegen_addlong(block, OPCODE_SHRN | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | SHIFT_IMM_V2S(shift));
}
void host_arm64_SMULL_V4S_4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg)
{
codegen_addlong(block, OPCODE_SMULL_V4S_4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg));
}
void host_arm64_SQADD_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg)
{
codegen_addlong(block, OPCODE_SQADD_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg));
@ -983,28 +1007,28 @@ void host_arm64_SQXTN_V4B_4H(codeblock_t *block, int dst_reg, int src_reg)
codegen_addlong(block, OPCODE_SQXTN_V4B_4H | Rd(dst_reg) | Rn(src_reg));
}
void host_arm64_SHL_V4H(codeblock_t *block, int dst_reg, int src_n_reg, shift)
void host_arm64_SHL_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int shift)
{
codegen_addlong(block, OPCODE_SHL_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V4H(shift));
}
void host_arm64_SHL_V2S(codeblock_t *block, int dst_reg, int src_n_reg, shift)
void host_arm64_SHL_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int shift)
{
codegen_addlong(block, OPCODE_SHL_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2S(shift));
}
void host_arm64_SHL_V2D(codeblock_t *block, int dst_reg, int src_n_reg, shift)
void host_arm64_SHL_V2D(codeblock_t *block, int dst_reg, int src_n_reg, int shift)
{
codegen_addlong(block, OPCODE_SHL_VQ | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2D(shift));
}
void host_arm64_SSHR_V4H(codeblock_t *block, int dst_reg, int src_n_reg, shift)
void host_arm64_SSHR_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int shift)
{
codegen_addlong(block, OPCODE_SSHR_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V4H(shift));
}
void host_arm64_SSHR_V2S(codeblock_t *block, int dst_reg, int src_n_reg, shift)
void host_arm64_SSHR_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int shift)
{
codegen_addlong(block, OPCODE_SSHR_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2S(shift));
}
void host_arm64_SSHR_V2D(codeblock_t *block, int dst_reg, int src_n_reg, shift)
void host_arm64_SSHR_V2D(codeblock_t *block, int dst_reg, int src_n_reg, int shift)
{
codegen_addlong(block, OPCODE_SSHR_VQ | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2D(shift));
}

View file

@ -134,6 +134,8 @@ void host_arm64_MOVK_IMM(codeblock_t *block, int reg, uint32_t imm_data);
void host_arm64_MSR_FPCR(codeblock_t *block, int src_reg);
void host_arm64_MUL_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg);
void host_arm64_NOP(codeblock_t *block);
void host_arm64_ORR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data);
@ -142,6 +144,8 @@ void host_arm64_ORR_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int sr
void host_arm64_RET(codeblock_t *block, int reg);
void host_arm64_SADDLP_V2S_4H(codeblock_t *block, int dst_reg, int src_n_reg);
void host_arm64_SBFX(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width);
void host_arm64_SCVTF_D_Q(codeblock_t *block, int dst_reg, int src_reg);
@ -159,6 +163,10 @@ void host_arm64_SHL_V4H(codeblock_t *block, int dst_reg, int src_reg, int shift)
void host_arm64_SHL_V2S(codeblock_t *block, int dst_reg, int src_reg, int shift);
void host_arm64_SHL_V2D(codeblock_t *block, int dst_reg, int src_reg, int shift);
void host_arm64_SHRN_V4H_4S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift);
void host_arm64_SMULL_V4S_4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg);
void host_arm64_SSHR_V4H(codeblock_t *block, int dst_reg, int src_reg, int shift);
void host_arm64_SSHR_V2S(codeblock_t *block, int dst_reg, int src_reg, int shift);
void host_arm64_SSHR_V2D(codeblock_t *block, int dst_reg, int src_reg, int shift);

View file

@ -1617,6 +1617,51 @@ static int codegen_PCMPGTD(codeblock_t *block, uop_t *uop)
return 0;
}
static int codegen_PMADDWD(codeblock_t *block, uop_t *uop)
{
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real)
{
host_arm64_MUL_V4H(block, dest_reg, src_reg_a, src_reg_b);
host_arm64_SADDLP_V2S_4H(block, dest_reg, dest_reg);
}
else
fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
return 0;
}
static int codegen_PMULHW(codeblock_t *block, uop_t *uop)
{
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real)
{
host_arm64_SMULL_V4S_4H(block, dest_reg, src_reg_a, src_reg_b);
host_arm64_SHRN_V4H_4S(block, dest_reg, dest_reg, 16);
}
else
fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
return 0;
}
static int codegen_PMULLW(codeblock_t *block, uop_t *uop)
{
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real)
{
host_arm64_MUL_V4H(block, dest_reg, src_reg_a, src_reg_b);
}
else
fatal("PMULLW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
return 0;
}
static int codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop)
{
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
@ -2499,6 +2544,10 @@ const uOpFn uop_handlers[UOP_MAX] =
[UOP_PCMPGTW & UOP_MASK] = codegen_PCMPGTW,
[UOP_PCMPGTD & UOP_MASK] = codegen_PCMPGTD,
[UOP_PMADDWD & UOP_MASK] = codegen_PMADDWD,
[UOP_PMULHW & UOP_MASK] = codegen_PMULHW,
[UOP_PMULLW & UOP_MASK] = codegen_PMULLW,
[UOP_PSLLW_IMM & UOP_MASK] = codegen_PSLLW_IMM,
[UOP_PSLLD_IMM & UOP_MASK] = codegen_PSLLD_IMM,
[UOP_PSLLQ_IMM & UOP_MASK] = codegen_PSLLQ_IMM,

View file

@ -116,7 +116,10 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val)
#define OPCODE_VMRS_APSR 0xeef1fa10
#define OPCODE_VMSR_FPSCR 0xeee10a10
#define OPCODE_VMUL 0xee200b00
#define OPCODE_VMUL_S16 0xf2100510
#define OPCODE_VMULL_S16 0xf2900c00
#define OPCODE_VORR_D 0xf2200110
#define OPCODE_VPADDL_S16 0xf3b40200
#define OPCODE_VQADD_S8 0xf2000010
#define OPCODE_VQADD_S16 0xf2100010
#define OPCODE_VQADD_U8 0xf3000010
@ -907,15 +910,30 @@ void host_arm_VMRS_APSR(codeblock_t *block)
{
codegen_addlong(block, COND_AL | OPCODE_VMRS_APSR);
}
void host_arm_VMUL_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m)
{
codegen_addlong(block, COND_AL | OPCODE_VMUL | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m));
}
void host_arm_VMUL_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m)
{
codegen_addlong(block, OPCODE_VMUL_S16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m));
}
void host_arm_VMULL_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m)
{
codegen_addlong(block, OPCODE_VMULL_S16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m));
}
void host_arm_VORR_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m)
{
codegen_addlong(block, OPCODE_VORR_D | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m));
}
void host_arm_VPADDL_S16(codeblock_t *block, int dst_reg, int src_reg)
{
codegen_addlong(block, OPCODE_VPADDL_S16 | Vd(dst_reg) | Vm(src_reg));
}
void host_arm_VQADD_S8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m)
{
codegen_addlong(block, OPCODE_VQADD_S8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m));

View file

@ -170,8 +170,15 @@ void host_arm_VMOV_S_32(codeblock_t *block, int dest_reg, int src_reg);
void host_arm_VMOV_D_D(codeblock_t *block, int dest_reg, int src_reg);
void host_arm_VMRS_APSR(codeblock_t *block);
void host_arm_VMSR_FPSCR(codeblock_t *block, int src_reg);
void host_arm_VMUL_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m);
void host_arm_VMUL_S16(codeblock_t *block, int dest_reg, int src_reg_n, int src_reg_m);
void host_arm_VMULL_S16(codeblock_t *block, int dest_reg, int src_reg_n, int src_reg_m);
void host_arm_VORR_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m);
void host_arm_VPADDL_S16(codeblock_t *block, int dst_reg, int src_reg);
void host_arm_VQADD_S8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m);
void host_arm_VQADD_U8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m);
void host_arm_VQADD_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m);

View file

@ -1737,6 +1737,51 @@ static int codegen_PCMPGTD(codeblock_t *block, uop_t *uop)
return 0;
}
static int codegen_PMADDWD(codeblock_t *block, uop_t *uop)
{
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real)
{
host_arm_VMUL_S16(block, dest_reg, src_reg_a, src_reg_b);
host_arm_VPADDL_S16(block, dest_reg, dest_reg);
}
else
fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
return 0;
}
static int codegen_PMULHW(codeblock_t *block, uop_t *uop)
{
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real)
{
host_arm_VMULL_S16(block, dest_reg, src_reg_a, src_reg_b);
host_arm_VSHRN_16(block, dest_reg, dest_reg, 16);
}
else
fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
return 0;
}
static int codegen_PMULLW(codeblock_t *block, uop_t *uop)
{
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real)
{
host_arm_VMUL_S16(block, dest_reg, src_reg_a, src_reg_b);
}
else
fatal("PMULLW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
return 0;
}
static int codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop)
{
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
@ -2640,6 +2685,10 @@ const uOpFn uop_handlers[UOP_MAX] =
[UOP_PCMPGTW & UOP_MASK] = codegen_PCMPGTW,
[UOP_PCMPGTD & UOP_MASK] = codegen_PCMPGTD,
[UOP_PMADDWD & UOP_MASK] = codegen_PMADDWD,
[UOP_PMULHW & UOP_MASK] = codegen_PMULHW,
[UOP_PMULLW & UOP_MASK] = codegen_PMULLW,
[UOP_PSLLW_IMM & UOP_MASK] = codegen_PSLLW_IMM,
[UOP_PSLLD_IMM & UOP_MASK] = codegen_PSLLD_IMM,
[UOP_PSLLQ_IMM & UOP_MASK] = codegen_PSLLQ_IMM,

View file

@ -1319,6 +1319,19 @@ void host_x86_PCMPGTD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg)
codegen_addbyte4(block, 0x66, 0x0f, 0x66, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTD dst_reg, src_reg*/
}
void host_x86_PMADDWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg)
{
codegen_addbyte4(block, 0x66, 0x0f, 0xf5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/
}
void host_x86_PMULHW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg)
{
codegen_addbyte4(block, 0x66, 0x0f, 0xe5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/
}
void host_x86_PMULLW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg)
{
codegen_addbyte4(block, 0x66, 0x0f, 0xd5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/
}
void host_x86_PSLLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift)
{
codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x30 | dst_reg); /*PSLLW dst_reg, imm*/

View file

@ -177,6 +177,10 @@ void host_x86_PCMPGTB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg);
void host_x86_PCMPGTW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg);
void host_x86_PCMPGTD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg);
void host_x86_PMADDWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg);
void host_x86_PMULHW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg);
void host_x86_PMULLW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg);
void host_x86_PSLLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift);
void host_x86_PSLLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift);
void host_x86_PSLLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift);

View file

@ -1497,6 +1497,49 @@ static int codegen_PCMPGTD(codeblock_t *block, uop_t *uop)
return 0;
}
static int codegen_PMADDWD(codeblock_t *block, uop_t *uop)
{
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real)
{
host_x86_PMADDWD_XREG_XREG(block, dest_reg, src_reg_b);
}
else
fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
return 0;
}
static int codegen_PMULHW(codeblock_t *block, uop_t *uop)
{
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real)
{
host_x86_PMULHW_XREG_XREG(block, dest_reg, src_reg_b);
}
else
fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
return 0;
}
static int codegen_PMULLW(codeblock_t *block, uop_t *uop)
{
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real)
{
host_x86_PMULLW_XREG_XREG(block, dest_reg, src_reg_b);
}
else
fatal("PMULLW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
return 0;
}
static int codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop)
{
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real);
@ -2264,6 +2307,10 @@ const uOpFn uop_handlers[UOP_MAX] =
[UOP_PCMPGTW & UOP_MASK] = codegen_PCMPGTW,
[UOP_PCMPGTD & UOP_MASK] = codegen_PCMPGTD,
[UOP_PMADDWD & UOP_MASK] = codegen_PMADDWD,
[UOP_PMULHW & UOP_MASK] = codegen_PMULHW,
[UOP_PMULLW & UOP_MASK] = codegen_PMULLW,
[UOP_PSLLW_IMM & UOP_MASK] = codegen_PSLLW_IMM,
[UOP_PSLLD_IMM & UOP_MASK] = codegen_PSLLD_IMM,
[UOP_PSLLQ_IMM & UOP_MASK] = codegen_PSLLQ_IMM,

View file

@ -1177,6 +1177,19 @@ void host_x86_PCMPGTD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg)
codegen_addbyte4(block, 0x66, 0x0f, 0x66, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTD dst_reg, src_reg*/
}
void host_x86_PMADDWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg)
{
codegen_addbyte4(block, 0x66, 0x0f, 0xf5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/
}
void host_x86_PMULHW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg)
{
codegen_addbyte4(block, 0x66, 0x0f, 0xe5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/
}
void host_x86_PMULLW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg)
{
codegen_addbyte4(block, 0x66, 0x0f, 0xd5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/
}
void host_x86_PSLLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift)
{
codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x30 | dst_reg); /*PSLLW dst_reg, imm*/

View file

@ -178,6 +178,10 @@ void host_x86_PCMPGTB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg);
void host_x86_PCMPGTW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg);
void host_x86_PCMPGTD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg);
void host_x86_PMADDWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg);
void host_x86_PMULHW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg);
void host_x86_PMULLW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg);
void host_x86_PSLLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift);
void host_x86_PSLLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift);
void host_x86_PSLLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift);

View file

@ -1500,6 +1500,49 @@ static int codegen_PCMPGTD(codeblock_t *block, uop_t *uop)
return 0;
}
static int codegen_PMADDWD(codeblock_t *block, uop_t *uop)
{
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real)
{
host_x86_PMADDWD_XREG_XREG(block, dest_reg, src_reg_b);
}
else
fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
return 0;
}
static int codegen_PMULHW(codeblock_t *block, uop_t *uop)
{
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real)
{
host_x86_PMULHW_XREG_XREG(block, dest_reg, src_reg_b);
}
else
fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
return 0;
}
static int codegen_PMULLW(codeblock_t *block, uop_t *uop)
{
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real)
{
host_x86_PMULLW_XREG_XREG(block, dest_reg, src_reg_b);
}
else
fatal("PMULLW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
return 0;
}
static int codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop)
{
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real);
@ -2264,6 +2307,10 @@ const uOpFn uop_handlers[UOP_MAX] =
[UOP_PCMPGTW & UOP_MASK] = codegen_PCMPGTW,
[UOP_PCMPGTD & UOP_MASK] = codegen_PCMPGTD,
[UOP_PMADDWD & UOP_MASK] = codegen_PMADDWD,
[UOP_PMULHW & UOP_MASK] = codegen_PMULHW,
[UOP_PMULLW & UOP_MASK] = codegen_PMULLW,
[UOP_PSLLW_IMM & UOP_MASK] = codegen_PSLLW_IMM,
[UOP_PSLLD_IMM & UOP_MASK] = codegen_PSLLD_IMM,
[UOP_PSLLQ_IMM & UOP_MASK] = codegen_PSLLQ_IMM,

View file

@ -260,8 +260,14 @@
#define UOP_PACKSSDW (UOP_TYPE_PARAMS_REGS | 0xb5)
/*UOP_PACKUSWB - dest_reg = interleave src_reg_a/src_reg_b, converting words to bytes with unsigned saturation*/
#define UOP_PACKUSWB (UOP_TYPE_PARAMS_REGS | 0xb6)
/*UOP_PMULLW - (packed word) dest_reg = (src_reg_a * src_reg_b) & 0xffff*/
#define UOP_PMULLW (UOP_TYPE_PARAMS_REGS | 0xb7)
/*UOP_PMULHW - (packed word) dest_reg = (src_reg_a * src_reg_b) >> 16*/
#define UOP_PMULHW (UOP_TYPE_PARAMS_REGS | 0xb8)
/*UOP_PMADDWD - (packed word) dest_reg = (src_reg_a * src_reg_b) >> 16*/
#define UOP_PMADDWD (UOP_TYPE_PARAMS_REGS | 0xb9)
#define UOP_MAX 0xb7
#define UOP_MAX 0xba
#define UOP_MASK 0xffff
@ -620,6 +626,10 @@ static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir,
#define uop_PCMPGTW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PCMPGTW, ir, dst_reg, src_reg_a, src_reg_b)
#define uop_PCMPGTD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PCMPGTD, ir, dst_reg, src_reg_a, src_reg_b)
#define uop_PMADDWD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PMADDWD, ir, dst_reg, src_reg_a, src_reg_b)
#define uop_PMULHW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PMULHW, ir, dst_reg, src_reg_a, src_reg_b)
#define uop_PMULLW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PMULLW, ir, dst_reg, src_reg_a, src_reg_b)
#define uop_PSLLW_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSLLW_IMM, ir, dst_reg, src_reg, imm)
#define uop_PSLLD_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSLLD_IMM, ir, dst_reg, src_reg, imm)
#define uop_PSLLQ_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSLLQ_IMM, ir, dst_reg, src_reg, imm)

View file

@ -89,9 +89,9 @@ RecompOpFn recomp_opcodes_0f[512] =
/*b0*/ NULL, NULL, ropLSS_16, NULL, ropLFS_16, ropLGS_16, ropMOVZX_16_8, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_16_8, NULL,
/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPSUBUSB, ropPSUBUSW, NULL, ropPAND, ropPADDUSB, ropPADDUSW, NULL, ropPANDN,
/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPSUBSB, ropPSUBSW, NULL, ropPOR, ropPADDSB, ropPADDSW, NULL, ropPXOR,
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPSUBB, ropPSUBW, ropPSUBD, NULL, ropPADDB, ropPADDW, ropPADDD, NULL,
/*d0*/ NULL, NULL, NULL, NULL, NULL, ropPMULLW, NULL, NULL, ropPSUBUSB, ropPSUBUSW, NULL, ropPAND, ropPADDUSB, ropPADDUSW, NULL, ropPANDN,
/*e0*/ NULL, NULL, NULL, NULL, NULL, ropPMULHW, NULL, NULL, ropPSUBSB, ropPSUBSW, NULL, ropPOR, ropPADDSB, ropPADDSW, NULL, ropPXOR,
/*f0*/ NULL, NULL, NULL, NULL, NULL, ropPMADDWD, NULL, NULL, ropPSUBB, ropPSUBW, ropPSUBD, NULL, ropPADDB, ropPADDW, ropPADDD, NULL,
/*32-bit data*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
@ -111,9 +111,9 @@ RecompOpFn recomp_opcodes_0f[512] =
/*b0*/ NULL, NULL, ropLSS_32, NULL, ropLFS_32, ropLGS_32, ropMOVZX_32_8, ropMOVZX_32_16, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_32_8, ropMOVSX_32_16,
/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPSUBUSB, ropPSUBUSW, NULL, ropPAND, ropPADDUSB, ropPADDUSW, NULL, ropPANDN,
/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPSUBSB, ropPSUBSW, NULL, ropPOR, ropPADDSB, ropPADDSW, NULL, ropPXOR,
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPSUBB, ropPSUBW, ropPSUBD, NULL, ropPADDB, ropPADDW, ropPADDD, NULL,
/*d0*/ NULL, NULL, NULL, NULL, NULL, ropPMULLW, NULL, NULL, ropPSUBUSB, ropPSUBUSW, NULL, ropPAND, ropPADDUSB, ropPADDUSW, NULL, ropPANDN,
/*e0*/ NULL, NULL, NULL, NULL, NULL, ropPMULHW, NULL, NULL, ropPSUBSB, ropPSUBSW, NULL, ropPOR, ropPADDSB, ropPADDSW, NULL, ropPXOR,
/*f0*/ NULL, NULL, NULL, NULL, NULL, ropPMADDWD, NULL, NULL, ropPSUBB, ropPSUBW, ropPSUBD, NULL, ropPADDB, ropPADDW, ropPADDD, NULL,
};
RecompOpFn recomp_opcodes_d8[512] =

View file

@ -50,3 +50,7 @@ ropParith(PSUBSB)
ropParith(PSUBSW)
ropParith(PSUBUSB)
ropParith(PSUBUSW)
ropParith(PMADDWD)
ropParith(PMULHW)
ropParith(PMULLW)

View file

@ -13,3 +13,7 @@ uint32_t ropPSUBSB(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t f
uint32_t ropPSUBSW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
uint32_t ropPSUBUSB(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
uint32_t ropPSUBUSW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
uint32_t ropPMADDWD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
uint32_t ropPMULHW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
uint32_t ropPMULLW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);