ARM MMX fixes
This commit is contained in:
parent
2a19183d83
commit
6341caf318
4 changed files with 129 additions and 55 deletions
|
|
@ -43,6 +43,8 @@
|
|||
#define REG_D15 15
|
||||
|
||||
#define REG_D_TEMP REG_D0
|
||||
#define REG_Q_TEMP REG_D0
|
||||
#define REG_Q_TEMP_2 REG_D2
|
||||
|
||||
#define REG_MASK_R0 (1 << REG_R0)
|
||||
#define REG_MASK_R1 (1 << REG_R1)
|
||||
|
|
|
|||
|
|
@ -113,13 +113,17 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val)
|
|||
#define OPCODE_VMOV_D_64 0xec400b10
|
||||
#define OPCODE_VMOV_S_32 0xee000a10
|
||||
#define OPCODE_VMOV_D_D 0xeeb00b40
|
||||
#define OPCODE_VMOVN_I32 0xf3b60200
|
||||
#define OPCODE_VMOVN_I64 0xf3ba0200
|
||||
#define OPCODE_VMRS_APSR 0xeef1fa10
|
||||
#define OPCODE_VMSR_FPSCR 0xeee10a10
|
||||
#define OPCODE_VMUL 0xee200b00
|
||||
#define OPCODE_VMUL_S16 0xf2100510
|
||||
#define OPCODE_VMUL_S16 0xf2100910
|
||||
#define OPCODE_VMULL_S16 0xf2900c00
|
||||
#define OPCODE_VORR_D 0xf2200110
|
||||
#define OPCODE_VPADDL_S16 0xf3b40200
|
||||
#define OPCODE_VPADDL_S32 0xf3b80200
|
||||
#define OPCODE_VPADDL_Q_S32 0xf3b80240
|
||||
#define OPCODE_VQADD_S8 0xf2000010
|
||||
#define OPCODE_VQADD_S16 0xf2100010
|
||||
#define OPCODE_VQADD_U8 0xf3000010
|
||||
|
|
@ -140,14 +144,16 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val)
|
|||
#define OPCODE_VSHR_D_U16 0xf3900010
|
||||
#define OPCODE_VSHR_D_U32 0xf3a00010
|
||||
#define OPCODE_VSHR_D_U64 0xf3800090
|
||||
#define OPCODE_VSHRN 0xf2800810
|
||||
#define OPCODE_VSTR_D 0xed800b00
|
||||
#define OPCODE_VSTR_S 0xed800a00
|
||||
#define OPCODE_VSUB 0xee300b40
|
||||
#define OPCODE_VSUB_I8 0xf3000800
|
||||
#define OPCODE_VSUB_I16 0xf3100800
|
||||
#define OPCODE_VSUB_I32 0xf3200800
|
||||
#define OPCODE_VZIP_D8 0xf3b20180
|
||||
#define OPCODE_VZIP_D16 0xf3b60180
|
||||
#define OPCODE_VZIP_D32 0xf3ba0180
|
||||
#define OPCODE_VZIP_D32 0xf3ba0080
|
||||
|
||||
#define B_OFFSET(x) (((x) >> 2) & 0xffffff)
|
||||
|
||||
|
|
@ -182,6 +188,8 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val)
|
|||
|
||||
#define VSHIFT_IMM(shift) ((shift) << 16)
|
||||
|
||||
#define VSHIFT_IMM_32(shift) (((16 - (shift)) | 0x10) << 16)
|
||||
|
||||
static inline uint32_t arm_data_offset(int offset)
|
||||
{
|
||||
if (offset < -0xffc || offset > 0xffc)
|
||||
|
|
@ -902,6 +910,14 @@ void host_arm_VMOV_D_D(codeblock_t *block, int dest_reg, int src_reg)
|
|||
{
|
||||
codegen_addlong(block, COND_AL | OPCODE_VMOV_D_D | Vd(dest_reg) | Vm(src_reg));
|
||||
}
|
||||
void host_arm_VMOVN_I32(codeblock_t *block, int dest_reg, int src_reg)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_VMOVN_I32 | Vd(dest_reg) | Vm(src_reg));
|
||||
}
|
||||
void host_arm_VMOVN_I64(codeblock_t *block, int dest_reg, int src_reg)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_VMOVN_I64 | Vd(dest_reg) | Vm(src_reg));
|
||||
}
|
||||
void host_arm_VMSR_FPSCR(codeblock_t *block, int src_reg)
|
||||
{
|
||||
codegen_addlong(block, COND_AL | OPCODE_VMSR_FPSCR | Rd(src_reg));
|
||||
|
|
@ -933,6 +949,14 @@ 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_VPADDL_S32(codeblock_t *block, int dst_reg, int src_reg)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_VPADDL_S32 | Vd(dst_reg) | Vm(src_reg));
|
||||
}
|
||||
void host_arm_VPADDL_Q_S32(codeblock_t *block, int dst_reg, int src_reg)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_VPADDL_Q_S32 | 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)
|
||||
{
|
||||
|
|
@ -980,59 +1004,65 @@ void host_arm_VQMOVN_U16(codeblock_t *block, int dst_reg, int src_reg)
|
|||
codegen_addlong(block, OPCODE_VQMOVN_U16 | Vd(dst_reg) | Vm(src_reg));
|
||||
}
|
||||
|
||||
void host_arm_VSHL_D_IMM_16(codeblock_t *block, int dest_reg, int src_reg, int shift)
|
||||
void host_arm_VSHL_D_IMM_16(codeblock_t *block, int dst_reg, int src_reg, int shift)
|
||||
{
|
||||
if (shift > 15)
|
||||
fatal("host_arm_VSHL_D_IMM_16 : shift > 15\n");
|
||||
codegen_addlong(block, OPCODE_VSHL_D_IMM_16 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(shift));
|
||||
}
|
||||
void host_arm_VSHL_D_IMM_32(codeblock_t *block, int dest_reg, int src_reg, int shift)
|
||||
void host_arm_VSHL_D_IMM_32(codeblock_t *block, int dst_reg, int src_reg, int shift)
|
||||
{
|
||||
if (shift > 31)
|
||||
fatal("host_arm_VSHL_D_IMM_32 : shift > 31\n");
|
||||
codegen_addlong(block, OPCODE_VSHL_D_IMM_32 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(shift));
|
||||
}
|
||||
void host_arm_VSHL_D_IMM_64(codeblock_t *block, int dest_reg, int src_reg, int shift)
|
||||
void host_arm_VSHL_D_IMM_64(codeblock_t *block, int dst_reg, int src_reg, int shift)
|
||||
{
|
||||
if (shift > 63)
|
||||
fatal("host_arm_VSHL_D_IMM_64 : shift > 63\n");
|
||||
codegen_addlong(block, OPCODE_VSHL_D_IMM_64 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(shift));
|
||||
}
|
||||
void host_arm_VSHR_SD_16(codeblock_t *block, int dest_reg, int src_reg, int shift)
|
||||
void host_arm_VSHR_D_S16(codeblock_t *block, int dst_reg, int src_reg, int shift)
|
||||
{
|
||||
if (shift > 15)
|
||||
fatal("host_arm_VSHR_SD_IMM_16 : shift > 15\n");
|
||||
codegen_addlong(block, OPCODE_VSHR_SD_16 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(shift));
|
||||
codegen_addlong(block, OPCODE_VSHR_D_S16 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(16-shift));
|
||||
}
|
||||
void host_arm_VSHR_SD_32(codeblock_t *block, int dest_reg, int src_reg, int shift)
|
||||
void host_arm_VSHR_D_S32(codeblock_t *block, int dst_reg, int src_reg, int shift)
|
||||
{
|
||||
if (shift > 31)
|
||||
fatal("host_arm_VSHR_SD_IMM_32 : shift > 31\n");
|
||||
codegen_addlong(block, OPCODE_VSHR_SD_32 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(shift));
|
||||
codegen_addlong(block, OPCODE_VSHR_D_S32 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(32-shift));
|
||||
}
|
||||
void host_arm_VSHR_SD_64(codeblock_t *block, int dest_reg, int src_reg, int shift)
|
||||
void host_arm_VSHR_D_S64(codeblock_t *block, int dst_reg, int src_reg, int shift)
|
||||
{
|
||||
if (shift > 63)
|
||||
fatal("host_arm_VSHR_SD_IMM_64 : shift > 63\n");
|
||||
codegen_addlong(block, OPCODE_VSHR_SD_64 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(shift));
|
||||
codegen_addlong(block, OPCODE_VSHR_D_S64 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(64-shift));
|
||||
}
|
||||
void host_arm_VSHR_UD_16(codeblock_t *block, int dest_reg, int src_reg, int shift)
|
||||
void host_arm_VSHR_D_U16(codeblock_t *block, int dst_reg, int src_reg, int shift)
|
||||
{
|
||||
if (shift > 15)
|
||||
fatal("host_arm_VSHR_UD_IMM_16 : shift > 15\n");
|
||||
codegen_addlong(block, OPCODE_VSHR_UD_16 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(shift));
|
||||
codegen_addlong(block, OPCODE_VSHR_D_U16 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(16-shift));
|
||||
}
|
||||
void host_arm_VSHR_UD_32(codeblock_t *block, int dest_reg, int src_reg, int shift)
|
||||
void host_arm_VSHR_D_U32(codeblock_t *block, int dst_reg, int src_reg, int shift)
|
||||
{
|
||||
if (shift > 31)
|
||||
fatal("host_arm_VSHR_UD_IMM_32 : shift > 31\n");
|
||||
codegen_addlong(block, OPCODE_VSHR_UD_32 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(shift));
|
||||
codegen_addlong(block, OPCODE_VSHR_D_U32 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(32-shift));
|
||||
}
|
||||
void host_arm_VSHR_UD_64(codeblock_t *block, int dest_reg, int src_reg, int shift)
|
||||
void host_arm_VSHR_D_U64(codeblock_t *block, int dst_reg, int src_reg, int shift)
|
||||
{
|
||||
if (shift > 63)
|
||||
fatal("host_arm_VSHR_UD_IMM_64 : shift > 63\n");
|
||||
codegen_addlong(block, OPCODE_VSHR_UD_64 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(shift));
|
||||
codegen_addlong(block, OPCODE_VSHR_D_U64 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(64-shift));
|
||||
}
|
||||
void host_arm_VSHRN_32(codeblock_t *block, int dst_reg, int src_reg, int shift)
|
||||
{
|
||||
if (shift > 16)
|
||||
fatal("host_arm_VSHRN_32 : shift > 16\n");
|
||||
codegen_addlong(block, OPCODE_VSHRN | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM_32(16-shift));
|
||||
}
|
||||
|
||||
void host_arm_VSTR_D(codeblock_t *block, int src_reg, int base_reg, int offset)
|
||||
|
|
@ -1064,6 +1094,10 @@ void host_arm_VSUB_I32(codeblock_t *block, int dst_reg, int src_reg_n, int src_r
|
|||
codegen_addlong(block, OPCODE_VSUB_I32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m));
|
||||
}
|
||||
|
||||
void host_arm_VZIP_D8(codeblock_t *block, int d_reg, int m_reg)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_VZIP_D8 | Vd(d_reg) | Vm(m_reg));
|
||||
}
|
||||
void host_arm_VZIP_D16(codeblock_t *block, int d_reg, int m_reg)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_VZIP_D16 | Vd(d_reg) | Vm(m_reg));
|
||||
|
|
|
|||
|
|
@ -163,11 +163,15 @@ void host_arm_VDIV_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg
|
|||
void host_arm_VEOR_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m);
|
||||
void host_arm_VLDR_D(codeblock_t *block, int dest_reg, int base_reg, int offset);
|
||||
void host_arm_VLDR_S(codeblock_t *block, int dest_reg, int base_reg, int offset);
|
||||
|
||||
void host_arm_VMOV_32_S(codeblock_t *block, int dest_reg, int src_reg);
|
||||
void host_arm_VMOV_64_D(codeblock_t *block, int dest_reg_low, int dest_reg_high, int src_reg);
|
||||
void host_arm_VMOV_D_64(codeblock_t *block, int dest_reg, int src_reg_low, int src_reg_high);
|
||||
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_VMOVN_I32(codeblock_t *block, int dest_reg, int src_reg);
|
||||
void host_arm_VMOVN_I64(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);
|
||||
|
||||
|
|
@ -178,6 +182,8 @@ void host_arm_VMULL_S16(codeblock_t *block, int dest_reg, int src_reg_n, int src
|
|||
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_VPADDL_S32(codeblock_t *block, int dst_reg, int src_reg);
|
||||
void host_arm_VPADDL_Q_S32(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);
|
||||
|
|
@ -201,6 +207,7 @@ void host_arm_VSHR_D_S64(codeblock_t *block, int dest_reg, int src_reg, int shif
|
|||
void host_arm_VSHR_D_U16(codeblock_t *block, int dest_reg, int src_reg, int shift);
|
||||
void host_arm_VSHR_D_U32(codeblock_t *block, int dest_reg, int src_reg, int shift);
|
||||
void host_arm_VSHR_D_U64(codeblock_t *block, int dest_reg, int src_reg, int shift);
|
||||
void host_arm_VSHRN_32(codeblock_t *block, int dest_reg, int src_reg, int shift);
|
||||
|
||||
void host_arm_VSTR_D(codeblock_t *block, int src_reg, int base_reg, int offset);
|
||||
void host_arm_VSTR_S(codeblock_t *block, int src_reg, int base_reg, int offset);
|
||||
|
|
@ -209,5 +216,6 @@ void host_arm_VSUB_I8(codeblock_t *block, int dst_reg, int src_reg_n, int src_re
|
|||
void host_arm_VSUB_I16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m);
|
||||
void host_arm_VSUB_I32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m);
|
||||
|
||||
void host_arm_VZIP_D8(codeblock_t *block, int d_reg, int m_reg);
|
||||
void host_arm_VZIP_D16(codeblock_t *block, int d_reg, int m_reg);
|
||||
void host_arm_VZIP_D32(codeblock_t *block, int d_reg, int m_reg);
|
||||
|
|
|
|||
|
|
@ -1290,7 +1290,7 @@ static int codegen_MOVZX(codeblock_t *block, uop_t *uop)
|
|||
}
|
||||
else if (REG_IS_L(dest_size) && REG_IS_Q(src_size))
|
||||
{
|
||||
host_arm_VMOV_32_S(block, dest_reg, src_reg, REG_TEMP);
|
||||
host_arm_VMOV_32_S(block, dest_reg, src_reg);
|
||||
}
|
||||
else if (REG_IS_L(dest_size) && REG_IS_B(src_size))
|
||||
{
|
||||
|
|
@ -1511,8 +1511,10 @@ static int codegen_PACKSSWB(codeblock_t *block, uop_t *uop)
|
|||
|
||||
if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b))
|
||||
{
|
||||
host_arm_VQMOVN_S16(block, dest_reg, dest_reg);
|
||||
host_arm_VQMOVN_S16(block, REG_D_TEMP, src_reg_b);
|
||||
host_arm_VMOV_D_D(block, REG_Q_TEMP, src_reg_a);
|
||||
host_arm_VMOV_D_D(block, REG_Q_TEMP_2, src_reg_b);
|
||||
host_arm_VQMOVN_S16(block, dest_reg, REG_Q_TEMP);
|
||||
host_arm_VQMOVN_S16(block, REG_D_TEMP, REG_Q_TEMP_2);
|
||||
host_arm_VZIP_D32(block, dest_reg, REG_D_TEMP);
|
||||
}
|
||||
else
|
||||
|
|
@ -1522,13 +1524,15 @@ static int codegen_PACKSSWB(codeblock_t *block, uop_t *uop)
|
|||
}
|
||||
static int codegen_PACKSSDW(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);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_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_a = IREG_GET_SIZE(uop->src_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)
|
||||
if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b))
|
||||
{
|
||||
host_arm_VQMOVN_S32(block, dest_reg, dest_reg);
|
||||
host_arm_VQMOVN_S32(block, REG_D_TEMP, src_reg_b);
|
||||
host_arm_VMOV_D_D(block, REG_Q_TEMP, src_reg_a);
|
||||
host_arm_VMOV_D_D(block, REG_Q_TEMP_2, src_reg_b);
|
||||
host_arm_VQMOVN_S32(block, dest_reg, REG_Q_TEMP);
|
||||
host_arm_VQMOVN_S32(block, REG_D_TEMP, REG_Q_TEMP_2);
|
||||
host_arm_VZIP_D32(block, dest_reg, REG_D_TEMP);
|
||||
}
|
||||
else
|
||||
|
|
@ -1538,13 +1542,15 @@ static int codegen_PACKSSDW(codeblock_t *block, uop_t *uop)
|
|||
}
|
||||
static int codegen_PACKUSWB(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);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_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_a = IREG_GET_SIZE(uop->src_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)
|
||||
if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b))
|
||||
{
|
||||
host_arm_VQMOVN_U16(block, dest_reg, dest_reg);
|
||||
host_arm_VQMOVN_U16(block, REG_D_TEMP, src_reg_b);
|
||||
host_arm_VMOV_D_D(block, REG_Q_TEMP, src_reg_a);
|
||||
host_arm_VMOV_D_D(block, REG_Q_TEMP_2, src_reg_b);
|
||||
host_arm_VQMOVN_U16(block, dest_reg, REG_Q_TEMP);
|
||||
host_arm_VQMOVN_U16(block, REG_D_TEMP, REG_Q_TEMP_2);
|
||||
host_arm_VZIP_D32(block, dest_reg, REG_D_TEMP);
|
||||
}
|
||||
else
|
||||
|
|
@ -1739,13 +1745,14 @@ static int codegen_PCMPGTD(codeblock_t *block, uop_t *uop)
|
|||
|
||||
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);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_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_a = IREG_GET_SIZE(uop->src_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)
|
||||
if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b))
|
||||
{
|
||||
host_arm_VMUL_S16(block, dest_reg, src_reg_a, src_reg_b);
|
||||
host_arm_VPADDL_S16(block, dest_reg, dest_reg);
|
||||
host_arm_VMULL_S16(block, REG_Q_TEMP, src_reg_a, src_reg_b);
|
||||
host_arm_VPADDL_Q_S32(block, REG_Q_TEMP, REG_Q_TEMP);
|
||||
host_arm_VMOVN_I64(block, dest_reg, REG_Q_TEMP);
|
||||
}
|
||||
else
|
||||
fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
|
||||
|
|
@ -1754,13 +1761,13 @@ static int codegen_PMADDWD(codeblock_t *block, uop_t *uop)
|
|||
}
|
||||
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);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_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_a = IREG_GET_SIZE(uop->src_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)
|
||||
if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b))
|
||||
{
|
||||
host_arm_VMULL_S16(block, dest_reg, src_reg_a, src_reg_b);
|
||||
host_arm_VSHRN_16(block, dest_reg, dest_reg, 16);
|
||||
host_arm_VMULL_S16(block, REG_Q_TEMP, src_reg_a, src_reg_b);
|
||||
host_arm_VSHRN_32(block, dest_reg, REG_Q_TEMP, 16);
|
||||
}
|
||||
else
|
||||
fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
|
||||
|
|
@ -1769,10 +1776,10 @@ static int codegen_PMULHW(codeblock_t *block, uop_t *uop)
|
|||
}
|
||||
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);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_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_a = IREG_GET_SIZE(uop->src_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)
|
||||
if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b))
|
||||
{
|
||||
host_arm_VMUL_S16(block, dest_reg, src_reg_a, src_reg_b);
|
||||
}
|
||||
|
|
@ -1789,7 +1796,9 @@ static int codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop)
|
|||
|
||||
if (REG_IS_Q(dest_size) && REG_IS_Q(src_size))
|
||||
{
|
||||
if (uop->imm_data > 15)
|
||||
if (uop->imm_data == 0)
|
||||
host_arm_VMOV_D_D(block, dest_reg, src_reg);
|
||||
else if (uop->imm_data > 15)
|
||||
host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg);
|
||||
else
|
||||
host_arm_VSHL_D_IMM_16(block, dest_reg, src_reg, uop->imm_data);
|
||||
|
|
@ -1806,7 +1815,9 @@ static int codegen_PSLLD_IMM(codeblock_t *block, uop_t *uop)
|
|||
|
||||
if (REG_IS_Q(dest_size) && REG_IS_Q(src_size))
|
||||
{
|
||||
if (uop->imm_data > 31)
|
||||
if (uop->imm_data == 0)
|
||||
host_arm_VMOV_D_D(block, dest_reg, src_reg);
|
||||
else if (uop->imm_data > 31)
|
||||
host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg);
|
||||
else
|
||||
host_arm_VSHL_D_IMM_32(block, dest_reg, src_reg, uop->imm_data);
|
||||
|
|
@ -1823,7 +1834,9 @@ static int codegen_PSLLQ_IMM(codeblock_t *block, uop_t *uop)
|
|||
|
||||
if (REG_IS_Q(dest_size) && REG_IS_Q(src_size))
|
||||
{
|
||||
if (uop->imm_data > 63)
|
||||
if (uop->imm_data == 0)
|
||||
host_arm_VMOV_D_D(block, dest_reg, src_reg);
|
||||
else if (uop->imm_data > 63)
|
||||
host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg);
|
||||
else
|
||||
host_arm_VSHL_D_IMM_64(block, dest_reg, src_reg, uop->imm_data);
|
||||
|
|
@ -1840,7 +1853,9 @@ static int codegen_PSRAW_IMM(codeblock_t *block, uop_t *uop)
|
|||
|
||||
if (REG_IS_Q(dest_size) && REG_IS_Q(src_size))
|
||||
{
|
||||
if (uop->imm_data > 15)
|
||||
if (uop->imm_data == 0)
|
||||
host_arm_VMOV_D_D(block, dest_reg, src_reg);
|
||||
else if (uop->imm_data > 15)
|
||||
host_arm_VSHR_D_S16(block, dest_reg, src_reg, 15);
|
||||
else
|
||||
host_arm_VSHR_D_S16(block, dest_reg, src_reg, uop->imm_data);
|
||||
|
|
@ -1857,7 +1872,9 @@ static int codegen_PSRAD_IMM(codeblock_t *block, uop_t *uop)
|
|||
|
||||
if (REG_IS_Q(dest_size) && REG_IS_Q(src_size))
|
||||
{
|
||||
if (uop->imm_data > 31)
|
||||
if (uop->imm_data == 0)
|
||||
host_arm_VMOV_D_D(block, dest_reg, src_reg);
|
||||
else if (uop->imm_data > 31)
|
||||
host_arm_VSHR_D_S32(block, dest_reg, src_reg, 31);
|
||||
else
|
||||
host_arm_VSHR_D_S32(block, dest_reg, src_reg, uop->imm_data);
|
||||
|
|
@ -1874,7 +1891,9 @@ static int codegen_PSRAQ_IMM(codeblock_t *block, uop_t *uop)
|
|||
|
||||
if (REG_IS_Q(dest_size) && REG_IS_Q(src_size))
|
||||
{
|
||||
if (uop->imm_data > 63)
|
||||
if (uop->imm_data == 0)
|
||||
host_arm_VMOV_D_D(block, dest_reg, src_reg);
|
||||
else if (uop->imm_data > 63)
|
||||
host_arm_VSHR_D_S64(block, dest_reg, src_reg, 63);
|
||||
else
|
||||
host_arm_VSHR_D_S64(block, dest_reg, src_reg, uop->imm_data);
|
||||
|
|
@ -1891,7 +1910,9 @@ static int codegen_PSRLW_IMM(codeblock_t *block, uop_t *uop)
|
|||
|
||||
if (REG_IS_Q(dest_size) && REG_IS_Q(src_size))
|
||||
{
|
||||
if (uop->imm_data > 15)
|
||||
if (uop->imm_data == 0)
|
||||
host_arm_VMOV_D_D(block, dest_reg, src_reg);
|
||||
else if (uop->imm_data > 15)
|
||||
host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg);
|
||||
else
|
||||
host_arm_VSHR_D_U16(block, dest_reg, src_reg, uop->imm_data);
|
||||
|
|
@ -1908,7 +1929,9 @@ static int codegen_PSRLD_IMM(codeblock_t *block, uop_t *uop)
|
|||
|
||||
if (REG_IS_Q(dest_size) && REG_IS_Q(src_size))
|
||||
{
|
||||
if (uop->imm_data > 31)
|
||||
if (uop->imm_data == 0)
|
||||
host_arm_VMOV_D_D(block, dest_reg, src_reg);
|
||||
else if (uop->imm_data > 31)
|
||||
host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg);
|
||||
else
|
||||
host_arm_VSHR_D_U32(block, dest_reg, src_reg, uop->imm_data);
|
||||
|
|
@ -1925,7 +1948,9 @@ static int codegen_PSRLQ_IMM(codeblock_t *block, uop_t *uop)
|
|||
|
||||
if (REG_IS_Q(dest_size) && REG_IS_Q(src_size))
|
||||
{
|
||||
if (uop->imm_data > 63)
|
||||
if (uop->imm_data == 0)
|
||||
host_arm_VMOV_D_D(block, dest_reg, src_reg);
|
||||
else if (uop->imm_data > 63)
|
||||
host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg);
|
||||
else
|
||||
host_arm_VSHR_D_U64(block, dest_reg, src_reg, uop->imm_data);
|
||||
|
|
@ -1966,9 +1991,6 @@ static int codegen_PSUBW(codeblock_t *block, uop_t *uop)
|
|||
}
|
||||
static int codegen_PSUBD(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);
|
||||
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_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_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
|
||||
|
||||
|
|
@ -2851,6 +2873,10 @@ void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_of
|
|||
else
|
||||
fatal("codegen_direct_read_32 - not in range\n");
|
||||
}
|
||||
void codegen_direct_read_64_stack(codeblock_t *block, int host_reg, int stack_offset)
|
||||
{
|
||||
host_arm_VLDR_D(block, host_reg, REG_HOST_SP, stack_offset);
|
||||
}
|
||||
void codegen_direct_read_double_stack(codeblock_t *block, int host_reg, int stack_offset)
|
||||
{
|
||||
host_arm_VLDR_D(block, host_reg, REG_HOST_SP, stack_offset);
|
||||
|
|
@ -2863,6 +2889,10 @@ void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int hos
|
|||
else
|
||||
fatal("codegen_direct_write_32 - not in range\n");
|
||||
}
|
||||
void codegen_direct_write_64_stack(codeblock_t *block, int stack_offset, int host_reg)
|
||||
{
|
||||
host_arm_VSTR_D(block, host_reg, REG_HOST_SP, stack_offset);
|
||||
}
|
||||
void codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int host_reg)
|
||||
{
|
||||
host_arm_VSTR_D(block, host_reg, REG_HOST_SP, stack_offset);
|
||||
|
|
|
|||
Loading…
Reference in a new issue