From 78c604c73136420ea179f8377915414731d1108f Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 21 Nov 2018 20:51:34 +0000 Subject: [PATCH] Added recompiled versions of PAND, PANDN, POR and PXOR --- src/codegen_backend_arm64_ops.c | 23 ++++++- src/codegen_backend_arm64_ops.h | 7 +- src/codegen_backend_arm64_uops.c | 34 +++++++++- src/codegen_backend_arm_ops.c | 22 +++++- src/codegen_backend_arm_ops.h | 4 ++ src/codegen_backend_arm_uops.c | 33 ++++++++- src/codegen_backend_x86-64_ops.c | 17 +++++ src/codegen_backend_x86-64_ops.h | 5 ++ src/codegen_backend_x86-64_uops.c | 34 +++++++++- src/codegen_backend_x86_ops.c | 17 +++++ src/codegen_backend_x86_ops.h | 5 ++ src/codegen_backend_x86_uops.c | 36 ++++++++-- src/codegen_ir_defs.h | 23 ++++--- src/codegen_ops.c | 9 +-- src/codegen_ops_mmx_logic.c | 108 ++++++++++++++++++++++++++++++ src/codegen_ops_mmx_logic.h | 4 ++ 16 files changed, 351 insertions(+), 30 deletions(-) create mode 100644 src/codegen_ops_mmx_logic.c create mode 100644 src/codegen_ops_mmx_logic.h diff --git a/src/codegen_backend_arm64_ops.c b/src/codegen_backend_arm64_ops.c index 724ea8b..d4e975c 100644 --- a/src/codegen_backend_arm64_ops.c +++ b/src/codegen_backend_arm64_ops.c @@ -104,9 +104,12 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_SUB_LSR (0x25a << 21) #define OPCODE_SUBX_LSL (0x658 << 21) +#define OPCODE_AND_V (0x0e201c00) #define OPCODE_ASR (0x1ac02800) +#define OPCODE_BIC_V (0x0e601c00) #define OPCODE_BLR (0xd63f0000) #define OPCODE_BR (0xd61f0000) +#define OPCODE_EOR_V (0x2e201c00) #define OPCODE_FADD_D (0x1e602800) #define OPCODE_FCMP_D (0x1e602000) #define OPCODE_FCVT_D_S (0x1e22c000) @@ -140,6 +143,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_LSR (0x1ac02400) #define OPCODE_MSR_FPCR (0xd51b4400) #define OPCODE_NOP (0xd503201f) +#define OPCODE_ORR_V (0x0ea01c00) #define OPCODE_RET (0xd65f0000) #define OPCODE_SCVTF_D_Q (0x9e620000) #define OPCODE_SCVTF_D_W (0x1e620000) @@ -319,6 +323,10 @@ void host_arm64_AND_REG_ROR(codeblock_t *block, int dst_reg, int src_n_reg, int { codegen_addlong(block, OPCODE_AND_ROR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } +void host_arm64_AND_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +{ + codegen_addlong(block, OPCODE_AND_V | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} void host_arm64_ANDS_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) { @@ -461,6 +469,11 @@ void host_arm64_BEQ(codeblock_t *block, void *dest) host_arm64_branch_set_offset(opcode, dest); } +void host_arm64_BIC_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +{ + codegen_addlong(block, OPCODE_BIC_V | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} + void host_arm64_CBNZ(codeblock_t *block, int reg, uintptr_t dest) { int offset = dest - (uintptr_t)&block->data[block_pos]; @@ -557,6 +570,10 @@ void host_arm64_EOR_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_ { codegen_addlong(block, OPCODE_EOR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } +void host_arm64_EOR_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +{ + codegen_addlong(block, OPCODE_EOR_V | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} void host_arm64_FADD_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { @@ -840,6 +857,10 @@ void host_arm64_ORR_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_ { codegen_addlong(block, OPCODE_ORR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } +void host_arm64_ORR_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +{ + codegen_addlong(block, OPCODE_ORR_V | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} void host_arm64_RET(codeblock_t *block, int reg) { @@ -995,4 +1016,4 @@ void host_arm64_mov_imm(codeblock_t *block, int reg, uint32_t imm_data) } } -#endif \ No newline at end of file +#endif diff --git a/src/codegen_backend_arm64_ops.h b/src/codegen_backend_arm64_ops.h index ccccae6..724f939 100644 --- a/src/codegen_backend_arm64_ops.h +++ b/src/codegen_backend_arm64_ops.h @@ -8,6 +8,7 @@ void host_arm64_AND_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t void host_arm64_AND_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); void host_arm64_AND_REG_ASR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); void host_arm64_AND_REG_ROR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); +void host_arm64_AND_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_ANDS_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data); @@ -40,6 +41,8 @@ void host_arm64_branch_set_offset(uint32_t *opcode, void *dest); void host_arm64_BR(codeblock_t *block, int addr_reg); +void host_arm64_BIC_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); + void host_arm64_CBNZ(codeblock_t *block, int reg, uintptr_t dest); void host_arm64_CMN_IMM(codeblock_t *block, int src_n_reg, uint32_t imm_data); @@ -57,6 +60,7 @@ void host_arm64_CSEL_VS(codeblock_t *block, int dst_reg, int src_n_reg, int src_ void host_arm64_EOR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data); void host_arm64_EOR_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); +void host_arm64_EOR_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_FADD_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_FCMP_D(codeblock_t *block, int src_n_reg, int src_m_reg); @@ -124,6 +128,7 @@ 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); void host_arm64_ORR_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); +void host_arm64_ORR_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_RET(codeblock_t *block, int reg); @@ -173,4 +178,4 @@ void host_arm64_mov_imm(codeblock_t *block, int reg, uint32_t imm_data); void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p); -int add_literal_q(codeblock_t *block, uint64_t data); \ No newline at end of file +int add_literal_q(codeblock_t *block, uint64_t data); diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index 5464148..baa12fb 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -105,7 +105,11 @@ static int codegen_AND(codeblock_t *block, uop_t *uop) 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_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm64_AND_REG_V(block, dest_reg, src_reg_a, src_reg_b); + } + else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_arm64_AND_REG(block, dest_reg, src_reg_a, src_reg_b, 0); } @@ -200,6 +204,21 @@ static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_ANDN(codeblock_t *block, uop_t *uop) +{ + 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_a) && REG_IS_Q(src_size_b)) + { + host_arm64_BIC_REG_V(block, dest_reg, src_reg_b, src_reg_a); + } + else + fatal("ANDN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + static int codegen_CALL_FUNC(codeblock_t *block, uop_t *uop) { host_arm64_call(block, uop->p); @@ -1300,7 +1319,11 @@ static int codegen_OR(codeblock_t *block, uop_t *uop) 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_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm64_ORR_REG_V(block, dest_reg, src_reg_a, src_reg_b); + } + else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_arm64_ORR_REG(block, dest_reg, src_reg_a, src_reg_b, 0); } @@ -1723,7 +1746,11 @@ static int codegen_XOR(codeblock_t *block, uop_t *uop) 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_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm64_EOR_REG_V(block, dest_reg, src_reg_a, src_reg_b); + } + else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_arm64_EOR_REG(block, dest_reg, src_reg_a, src_reg_b, 0); } @@ -1834,6 +1861,7 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_ADD_LSHIFT & UOP_MASK] = codegen_ADD_LSHIFT, [UOP_AND & UOP_MASK] = codegen_AND, [UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM, + [UOP_ANDN & UOP_MASK] = codegen_ANDN, [UOP_OR & UOP_MASK] = codegen_OR, [UOP_OR_IMM & UOP_MASK] = codegen_OR_IMM, [UOP_SUB & UOP_MASK] = codegen_SUB, diff --git a/src/codegen_backend_arm_ops.c b/src/codegen_backend_arm_ops.c index 85d3646..4e34980 100644 --- a/src/codegen_backend_arm_ops.c +++ b/src/codegen_backend_arm_ops.c @@ -87,6 +87,8 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_UXTB 0xe6ef0070 #define OPCODE_UXTH 0xe6ff0070 #define OPCODE_VADD 0xee300b00 +#define OPCODE_VAND_D 0xf2000110 +#define OPCODE_VBIC_D 0xf2100110 #define OPCODE_VCMP_D 0xeeb40b40 #define OPCODE_VCVT_D_IS 0xeeb80bc0 #define OPCODE_VCVT_D_S 0xeeb70ac0 @@ -94,6 +96,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_VCVT_S_D 0xeeb70bc0 #define OPCODE_VCVTR_IS_D 0xeebd0b40 #define OPCODE_VDIV 0xee800b00 +#define OPCODE_VEOR_D 0xf3000110 #define OPCODE_VLDR_D 0xed900b00 #define OPCODE_VLDR_S 0xed900a00 #define OPCODE_VMOV_32_S 0xee100a10 @@ -104,6 +107,7 @@ 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_VORR_D 0xf2200110 #define OPCODE_VSTR_D 0xed800b00 #define OPCODE_VSTR_S 0xed800a00 #define OPCODE_VSUB 0xee300b40 @@ -750,6 +754,14 @@ void host_arm_VADD_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg { codegen_addlong(block, COND_AL | OPCODE_VADD | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } +void host_arm_VAND_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +{ + codegen_addlong(block, OPCODE_VAND_D | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} +void host_arm_VBIC_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +{ + codegen_addlong(block, OPCODE_VBIC_D | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} void host_arm_VCMP_D(codeblock_t *block, int src_reg_d, int src_reg_m) { codegen_addlong(block, COND_AL | OPCODE_VCMP_D | Rd(src_reg_d) | Rm(src_reg_m)); @@ -778,6 +790,10 @@ void host_arm_VDIV_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg { codegen_addlong(block, COND_AL | OPCODE_VDIV | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } +void host_arm_VEOR_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +{ + codegen_addlong(block, OPCODE_VEOR_D | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} void host_arm_VLDR_D(codeblock_t *block, int dest_reg, int base_reg, int offset) { if ((offset > 1020) || (offset & 3)) @@ -822,6 +838,10 @@ void host_arm_VMUL_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg { codegen_addlong(block, COND_AL | OPCODE_VMUL | 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_VSTR_D(codeblock_t *block, int src_reg, int base_reg, int offset) { if ((offset > 1020) || (offset & 3)) @@ -839,4 +859,4 @@ void host_arm_VSUB_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg codegen_addlong(block, COND_AL | OPCODE_VSUB | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -#endif \ No newline at end of file +#endif diff --git a/src/codegen_backend_arm_ops.h b/src/codegen_backend_arm_ops.h index 1fdd609..9530e72 100644 --- a/src/codegen_backend_arm_ops.h +++ b/src/codegen_backend_arm_ops.h @@ -140,6 +140,8 @@ void host_arm_UXTB(codeblock_t *block, int dst_reg, int src_reg, int rotate); void host_arm_UXTH(codeblock_t *block, int dst_reg, int src_reg, int rotate); void host_arm_VADD_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); +void host_arm_VAND_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); +void host_arm_VBIC_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); void host_arm_VCMP_D(codeblock_t *block, int src_reg_d, int src_reg_m); void host_arm_VCVT_D_IS(codeblock_t *block, int dest_reg, int src_reg); void host_arm_VCVT_D_S(codeblock_t *block, int dest_reg, int src_reg); @@ -147,6 +149,7 @@ void host_arm_VCVT_IS_D(codeblock_t *block, int dest_reg, int src_reg); void host_arm_VCVT_S_D(codeblock_t *block, int dest_reg, int src_reg); void host_arm_VCVTR_IS_D(codeblock_t *block, int dest_reg, int src_reg); void host_arm_VDIV_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); +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); @@ -157,6 +160,7 @@ 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_VORR_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); 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); void host_arm_VSUB_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index 1f132de..c5f8b0a 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -169,7 +169,11 @@ static int codegen_AND(codeblock_t *block, uop_t *uop) 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_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_VAND_D(block, dest_reg, src_reg_a, src_reg_b); + } + else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_arm_AND_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0); } @@ -273,6 +277,20 @@ static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_ANDN(codeblock_t *block, uop_t *uop) +{ + 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_a) && REG_IS_Q(src_size_b)) + { + host_arm_VBIC_D(block, dest_reg, src_reg_b, src_reg_a); + } + else + fatal("ANDN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} static int codegen_CALL_FUNC(codeblock_t *block, uop_t *uop) { @@ -1421,7 +1439,11 @@ static int codegen_OR(codeblock_t *block, uop_t *uop) 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_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_VORR_D(block, dest_reg, src_reg_a, src_reg_b); + } + else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0); } @@ -1844,7 +1866,11 @@ static int codegen_XOR(codeblock_t *block, uop_t *uop) 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_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) + { + host_arm_VEOR_D(block, dest_reg, src_reg_a, src_reg_b); + } + else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0); } @@ -1955,6 +1981,7 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_ADD_LSHIFT & UOP_MASK] = codegen_ADD_LSHIFT, [UOP_AND & UOP_MASK] = codegen_AND, [UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM, + [UOP_ANDN & UOP_MASK] = codegen_ANDN, [UOP_OR & UOP_MASK] = codegen_OR, [UOP_OR_IMM & UOP_MASK] = codegen_OR_IMM, [UOP_SUB & UOP_MASK] = codegen_SUB, diff --git a/src/codegen_backend_x86-64_ops.c b/src/codegen_backend_x86-64_ops.c index c3f1b90..736c8b2 100644 --- a/src/codegen_backend_x86-64_ops.c +++ b/src/codegen_backend_x86-64_ops.c @@ -1229,6 +1229,23 @@ void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int s codegen_addbyte2(block, 0x09, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*OR dst_reg, src_reg_b*/ } +void host_x86_PAND_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xdb, 0xc0 | src_reg | (dst_reg << 3)); /*PAND dst_reg, src_reg*/ +} +void host_x86_PANDN_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xdf, 0xc0 | src_reg | (dst_reg << 3)); /*PANDN dst_reg, src_reg*/ +} +void host_x86_POR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xeb, 0xc0 | src_reg | (dst_reg << 3)); /*POR dst_reg, src_reg*/ +} +void host_x86_PXOR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xef, 0xc0 | src_reg | (dst_reg << 3)); /*PXOR dst_reg, src_reg*/ +} + void host_x86_POP(codeblock_t *block, int dst_reg) { if (dst_reg & 8) diff --git a/src/codegen_backend_x86-64_ops.h b/src/codegen_backend_x86-64_ops.h index ee7a82e..d05ecb6 100644 --- a/src/codegen_backend_x86-64_ops.h +++ b/src/codegen_backend_x86-64_ops.h @@ -153,6 +153,11 @@ void host_x86_OR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int sr void host_x86_OR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b); +void host_x86_PAND_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PANDN_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_POR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PXOR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + void host_x86_POP(codeblock_t *block, int src_reg); void host_x86_PUSH(codeblock_t *block, int src_reg); diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index d27edae..1c8e8bc 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -101,7 +101,11 @@ static int codegen_AND(codeblock_t *block, uop_t *uop) 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_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PAND_XREG_XREG(block, dest_reg, src_reg_b); + } + else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { if (dest_reg != src_reg_a) host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); @@ -154,6 +158,21 @@ static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_ANDN(codeblock_t *block, uop_t *uop) +{ + 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_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PANDN_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("ANDN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + static int codegen_CALL_FUNC(codeblock_t *block, uop_t *uop) { host_x86_CALL(block, uop->p); @@ -1203,7 +1222,11 @@ static int codegen_OR(codeblock_t *block, uop_t *uop) 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_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_POR_XREG_XREG(block, dest_reg, src_reg_b); + } + else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { if (dest_reg != src_reg_a) host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); @@ -1545,7 +1568,11 @@ static int codegen_XOR(codeblock_t *block, uop_t *uop) 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_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PXOR_XREG_XREG(block, dest_reg, src_reg_b); + } + else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_x86_XOR32_REG_REG(block, dest_reg, src_reg_a, src_reg_b); } @@ -1634,6 +1661,7 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, [UOP_ADD_LSHIFT & UOP_MASK] = codegen_ADD_LSHIFT, [UOP_AND & UOP_MASK] = codegen_AND, + [UOP_ANDN & UOP_MASK] = codegen_ANDN, [UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM, [UOP_OR & UOP_MASK] = codegen_OR, [UOP_OR_IMM & UOP_MASK] = codegen_OR_IMM, diff --git a/src/codegen_backend_x86_ops.c b/src/codegen_backend_x86_ops.c index 0dace79..ca24075 100644 --- a/src/codegen_backend_x86_ops.c +++ b/src/codegen_backend_x86_ops.c @@ -1087,6 +1087,23 @@ void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_ } } +void host_x86_PAND_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xdb, 0xc0 | src_reg | (dst_reg << 3)); /*PAND dst_reg, src_reg*/ +} +void host_x86_PANDN_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xdf, 0xc0 | src_reg | (dst_reg << 3)); /*PANDN dst_reg, src_reg*/ +} +void host_x86_POR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xeb, 0xc0 | src_reg | (dst_reg << 3)); /*POR dst_reg, src_reg*/ +} +void host_x86_PXOR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addbyte4(block, 0x66, 0x0f, 0xef, 0xc0 | src_reg | (dst_reg << 3)); /*PXOR dst_reg, src_reg*/ +} + void host_x86_POP(codeblock_t *block, int src_reg) { codegen_addbyte(block, 0x58 | src_reg); /*POP reg*/ diff --git a/src/codegen_backend_x86_ops.h b/src/codegen_backend_x86_ops.h index 96ace96..0f0b469 100644 --- a/src/codegen_backend_x86_ops.h +++ b/src/codegen_backend_x86_ops.h @@ -154,6 +154,11 @@ void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data); void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data); +void host_x86_PAND_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PANDN_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_POR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_PXOR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); + void host_x86_POP(codeblock_t *block, int src_reg); void host_x86_PUSH(codeblock_t *block, int src_reg); diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index a61592a..84ec52f 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -111,7 +111,11 @@ static int codegen_AND(codeblock_t *block, uop_t *uop) 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_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PAND_XREG_XREG(block, dest_reg, src_reg_b); + } + else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { if (uop->dest_reg_a_real != uop->src_reg_a_real) host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); @@ -164,6 +168,21 @@ static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_ANDN(codeblock_t *block, uop_t *uop) +{ + 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_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PANDN_XREG_XREG(block, dest_reg, src_reg_b); + } + else + fatal("ANDN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + static int codegen_CALL_FUNC(codeblock_t *block, uop_t *uop) { host_x86_CALL(block, uop->p); @@ -1206,7 +1225,11 @@ static int codegen_OR(codeblock_t *block, uop_t *uop) 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_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_POR_XREG_XREG(block, dest_reg, src_reg_b); + } + else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { if (uop->dest_reg_a_real != uop->src_reg_a_real) host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); @@ -1544,7 +1567,11 @@ static int codegen_XOR(codeblock_t *block, uop_t *uop) 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_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) + { + host_x86_PXOR_XREG_XREG(block, dest_reg, src_reg_b); + } + else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { host_x86_XOR32_REG_REG(block, dest_reg, src_reg_a, src_reg_b); } @@ -1557,7 +1584,7 @@ static int codegen_XOR(codeblock_t *block, uop_t *uop) host_x86_XOR8_REG_REG(block, dest_reg, src_reg_a, src_reg_b); } else - fatal("OR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + fatal("XOR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); return 0; } @@ -1635,6 +1662,7 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_ADD_LSHIFT & UOP_MASK] = codegen_ADD_LSHIFT, [UOP_AND & UOP_MASK] = codegen_AND, [UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM, + [UOP_ANDN & UOP_MASK] = codegen_ANDN, [UOP_OR & UOP_MASK] = codegen_OR, [UOP_OR_IMM & UOP_MASK] = codegen_OR_IMM, [UOP_SUB & UOP_MASK] = codegen_SUB, diff --git a/src/codegen_ir_defs.h b/src/codegen_ir_defs.h index 5c5d290..e2cd008 100644 --- a/src/codegen_ir_defs.h +++ b/src/codegen_ir_defs.h @@ -93,6 +93,8 @@ #define UOP_XOR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x39) /*UOP_XOR_IMM - dest_reg = src_reg_a ^ immediate*/ #define UOP_XOR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x3a) +/*UOP_ANDN - dest_reg = ~src_reg_a & src_reg_b*/ +#define UOP_ANDN (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x3b) /*UOP_MEM_LOAD_ABS - dest_reg = src_reg_a:[immediate]*/ #define UOP_MEM_LOAD_ABS (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x40 | UOP_TYPE_ORDER_BARRIER) /*UOP_MEM_LOAD_REG - dest_reg = src_reg_a:[src_reg_b]*/ @@ -444,17 +446,18 @@ static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir, #define uop_LOAD_FUNC_ARG_IMM(ir, arg, imm) uop_gen_imm(UOP_LOAD_FUNC_ARG_0_IMM + arg, ir, imm) -#define uop_ADD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_ADD, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_ADD_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_ADD_IMM, ir, dst_reg, src_reg, imm) +#define uop_ADD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_ADD, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_ADD_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_ADD_IMM, ir, dst_reg, src_reg, imm) #define uop_ADD_LSHIFT(ir, dst_reg, src_reg_a, src_reg_b, shift) uop_gen_reg_dst_src2_imm(UOP_ADD_LSHIFT, ir, dst_reg, src_reg_a, src_reg_b, shift) -#define uop_AND(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_AND, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_AND_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_AND_IMM, ir, dst_reg, src_reg, imm) -#define uop_OR(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_OR, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_OR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_OR_IMM, ir, dst_reg, src_reg, imm) -#define uop_SUB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_SUB, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_SUB_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_SUB_IMM, ir, dst_reg, src_reg, imm) -#define uop_XOR(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_XOR, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_XOR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_XOR_IMM, ir, dst_reg, src_reg, imm) +#define uop_AND(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_AND, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_AND_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_AND_IMM, ir, dst_reg, src_reg, imm) +#define uop_ANDN(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_ANDN, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_OR(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_OR, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_OR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_OR_IMM, ir, dst_reg, src_reg, imm) +#define uop_SUB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_SUB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_SUB_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_SUB_IMM, ir, dst_reg, src_reg, imm) +#define uop_XOR(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_XOR, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_XOR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_XOR_IMM, ir, dst_reg, src_reg, imm) #define uop_SAR(ir, dst_reg, src_reg, shift_reg) uop_gen_reg_dst_src2(UOP_SAR, ir, dst_reg, src_reg, shift_reg) #define uop_SAR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_SAR_IMM, ir, dst_reg, src_reg, imm) diff --git a/src/codegen_ops.c b/src/codegen_ops.c index 28dc422..6531dfc 100644 --- a/src/codegen_ops.c +++ b/src/codegen_ops.c @@ -12,6 +12,7 @@ #include "codegen_ops_logic.h" #include "codegen_ops_misc.h" #include "codegen_ops_mmx_loadstore.h" +#include "codegen_ops_mmx_logic.h" #include "codegen_ops_mov.h" #include "codegen_ops_shift.h" #include "codegen_ops_stack.h" @@ -84,8 +85,8 @@ 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, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ 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, NULL, NULL, NULL, ropPAND, NULL, NULL, NULL, ropPANDN, +/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPOR, NULL, NULL, NULL, ropPXOR, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*32-bit data*/ @@ -106,8 +107,8 @@ 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, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ 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, NULL, NULL, NULL, ropPAND, NULL, NULL, NULL, ropPANDN, +/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPOR, NULL, NULL, NULL, ropPXOR, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, }; diff --git a/src/codegen_ops_mmx_logic.c b/src/codegen_ops_mmx_logic.c new file mode 100644 index 0000000..428a591 --- /dev/null +++ b/src/codegen_ops_mmx_logic.c @@ -0,0 +1,108 @@ +#include "ibm.h" + +#include "x86.h" +#include "x86_flags.h" +#include "386_common.h" +#include "codegen.h" +#include "codegen_accumulate.h" +#include "codegen_ir.h" +#include "codegen_ops.h" +#include "codegen_ops_mmx_logic.h" +#include "codegen_ops_helpers.h" + +uint32_t ropPAND(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + uop_MMX_ENTER(ir); + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + uop_AND(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); + uop_AND(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); + } + + return op_pc + 1; + +} +uint32_t ropPANDN(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + uop_MMX_ENTER(ir); + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + uop_ANDN(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); + uop_ANDN(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); + } + + return op_pc + 1; + +} +uint32_t ropPOR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + uop_MMX_ENTER(ir); + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + uop_OR(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); + uop_OR(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); + } + + return op_pc + 1; + +} +uint32_t ropPXOR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + uop_MMX_ENTER(ir); + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + uop_XOR(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); + } + else + { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); + uop_XOR(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); + } + + return op_pc + 1; + +} diff --git a/src/codegen_ops_mmx_logic.h b/src/codegen_ops_mmx_logic.h new file mode 100644 index 0000000..f8f3009 --- /dev/null +++ b/src/codegen_ops_mmx_logic.h @@ -0,0 +1,4 @@ +uint32_t ropPAND(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPANDN(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPOR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPXOR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);