diff --git a/src/codegen_backend_x86_ops_sse.c b/src/codegen_backend_x86_ops_sse.c index dc20d34..ed603e7 100644 --- a/src/codegen_backend_x86_ops_sse.c +++ b/src/codegen_backend_x86_ops_sse.c @@ -429,6 +429,13 @@ 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_PSHUFD_XREG_XREG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t shuffle) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | src_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ + codegen_addbyte(block, shuffle); +} + void host_x86_PSLLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { codegen_alloc_bytes(block, 5); @@ -520,27 +527,6 @@ void host_x86_PSUBUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) codegen_addbyte4(block, 0x66, 0x0f, 0xd9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSW dst_reg, src_reg*/ } -void host_x86_PUNPCKHBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0x60, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLBW dst_reg, src_reg*/ - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ - codegen_addbyte(block, 0xee); -} -void host_x86_PUNPCKHWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0x61, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLWD dst_reg, src_reg*/ - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ - codegen_addbyte(block, 0xee); -} -void host_x86_PUNPCKHDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0x62, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLDQ dst_reg, src_reg*/ - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ - codegen_addbyte(block, 0xee); -} void host_x86_PUNPCKLBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { codegen_alloc_bytes(block, 4); diff --git a/src/codegen_backend_x86_ops_sse.h b/src/codegen_backend_x86_ops_sse.h index 596f361..e8afdcb 100644 --- a/src/codegen_backend_x86_ops_sse.h +++ b/src/codegen_backend_x86_ops_sse.h @@ -88,6 +88,8 @@ void host_x86_PSRLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift); void host_x86_PSRLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift); void host_x86_PSRLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift); +void host_x86_PSHUFD_XREG_XREG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t shuffle); + void host_x86_PSUBB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PSUBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PSUBD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); @@ -96,9 +98,6 @@ void host_x86_PSUBSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PSUBUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PSUBUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PUNPCKHBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PUNPCKHWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PUNPCKHDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PUNPCKLBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PUNPCKLWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_PUNPCKLDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index c09512e..8690266 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -2250,7 +2250,8 @@ static int codegen_PUNPCKHBW(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PUNPCKHBW_XREG_XREG(block, dest_reg, src_reg_b); + host_x86_PUNPCKLBW_XREG_XREG(block, dest_reg, src_reg_b); + host_x86_PSHUFD_XREG_XREG_IMM(block, dest_reg, dest_reg, 0xee); /*0xee = move top 64-bits to low 64-bits*/ } #ifdef RECOMPILER_DEBUG else @@ -2265,7 +2266,8 @@ static int codegen_PUNPCKHWD(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PUNPCKHWD_XREG_XREG(block, dest_reg, src_reg_b); + host_x86_PUNPCKLWD_XREG_XREG(block, dest_reg, src_reg_b); + host_x86_PSHUFD_XREG_XREG_IMM(block, dest_reg, dest_reg, 0xee); /*0xee = move top 64-bits to low 64-bits*/ } #ifdef RECOMPILER_DEBUG else @@ -2280,7 +2282,8 @@ static int codegen_PUNPCKHDQ(codeblock_t *block, uop_t *uop) if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PUNPCKHDQ_XREG_XREG(block, dest_reg, src_reg_b); + host_x86_PUNPCKLDQ_XREG_XREG(block, dest_reg, src_reg_b); + host_x86_PSHUFD_XREG_XREG_IMM(block, dest_reg, dest_reg, 0xee); /*0xee = move top 64-bits to low 64-bits*/ } #ifdef RECOMPILER_DEBUG else