From fed305a7e5e80b580ee549fbc89fac080026d959 Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Sun, 31 Jul 2016 11:40:35 -0700 Subject: [PATCH] ARM Dynarec: Implement Thumb AND, BIC, EOR and ORR --- src/arm/dynarec-arm/dynarec-impl.c | 12 +++++++ src/arm/dynarec-arm/emitter.c | 52 ++++++++++++++++++++++++++++++ src/arm/dynarec-arm/emitter.h | 12 +++++++ 3 files changed, 76 insertions(+) diff --git a/src/arm/dynarec-arm/dynarec-impl.c b/src/arm/dynarec-arm/dynarec-impl.c index e3c8a5472..a83f6c97c 100644 --- a/src/arm/dynarec-arm/dynarec-impl.c +++ b/src/arm/dynarec-arm/dynarec-impl.c @@ -147,6 +147,18 @@ void ARMDynarecRecompileTrace(struct ARMCore* cpu, struct ARMDynarecTrace* trace case ARM_MN_ADD: RECOMPILE_ALU(ADD); break; + case ARM_MN_AND: + RECOMPILE_ALU(AND); + break; + case ARM_MN_BIC: + RECOMPILE_ALU(BIC); + break; + case ARM_MN_EOR: + RECOMPILE_ALU(EOR); + break; + case ARM_MN_ORR: + RECOMPILE_ALU(ORR); + break; default: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wtype-limits" diff --git a/src/arm/dynarec-arm/emitter.c b/src/arm/dynarec-arm/emitter.c index a9a45e377..b1f606759 100644 --- a/src/arm/dynarec-arm/emitter.c +++ b/src/arm/dynarec-arm/emitter.c @@ -11,15 +11,19 @@ #define OP_I 0x02000000 #define OP_S 0x00100000 #define OP_ADD 0x00800000 +#define OP_AND 0x00000000 #define OP_B 0x0A000000 +#define OP_BIC 0x01C00000 #define OP_BL 0x0B000000 #define OP_CMP 0x01500000 +#define OP_EOR 0x00200000 #define OP_LDMIA 0x08900000 #define OP_LDRI 0x05100000 #define OP_MOV 0x01A00000 #define OP_MOVT 0x03400000 #define OP_MOVW 0x03000000 #define OP_MRS 0x010F0000 +#define OP_ORR 0x01800000 #define OP_POP 0x08BD0000 #define OP_PUSH 0x092D0000 #define OP_STMIA 0x08800000 @@ -55,6 +59,30 @@ uint32_t emitADDSI(unsigned dst, unsigned src, unsigned imm) { return OP_ADD | OP_S | OP_I | calculateAddrMode1(imm) | (dst << 12) | (src << 16); } +uint32_t emitANDI(unsigned dst, unsigned src, unsigned imm) { + return OP_AND | OP_I | calculateAddrMode1(imm) | (dst << 12) | (src << 16); +} + +uint32_t emitANDS(unsigned dst, unsigned src, unsigned op2) { + return OP_AND | OP_S | (dst << 12) | (src << 16) | op2; +} + +uint32_t emitANDSI(unsigned dst, unsigned src, unsigned imm) { + return OP_AND | OP_S | OP_I | calculateAddrMode1(imm) | (dst << 12) | (src << 16); +} + +uint32_t emitBICI(unsigned dst, unsigned src, unsigned imm) { + return OP_BIC | OP_I | calculateAddrMode1(imm) | (dst << 12) | (src << 16); +} + +uint32_t emitBICS(unsigned dst, unsigned src, unsigned op2) { + return OP_BIC | OP_S | (dst << 12) | (src << 16) | op2; +} + +uint32_t emitBICSI(unsigned dst, unsigned src, unsigned imm) { + return OP_BIC | OP_S | OP_I | calculateAddrMode1(imm) | (dst << 12) | (src << 16); +} + uint32_t emitB(void* base, void* target) { uint32_t diff = (intptr_t) target - (intptr_t) base - WORD_SIZE_ARM * 2; diff >>= 2; @@ -73,6 +101,18 @@ uint32_t emitCMP(unsigned src1, unsigned src2) { return OP_CMP | src2 | (src1 << 16); } +uint32_t emitEORI(unsigned dst, unsigned src, unsigned imm) { + return OP_EOR | OP_I | calculateAddrMode1(imm) | (dst << 12) | (src << 16); +} + +uint32_t emitEORS(unsigned dst, unsigned src, unsigned op2) { + return OP_EOR | OP_S | (dst << 12) | (src << 16) | op2; +} + +uint32_t emitEORSI(unsigned dst, unsigned src, unsigned imm) { + return OP_EOR | OP_S | OP_I | calculateAddrMode1(imm) | (dst << 12) | (src << 16); +} + uint32_t emitLDMIA(unsigned base, unsigned mask) { return OP_LDMIA | (base << 16) | mask; } @@ -107,6 +147,18 @@ uint32_t emitMRS(unsigned dst) { return OP_MRS | (dst << 12); } +uint32_t emitORRI(unsigned dst, unsigned src, unsigned imm) { + return OP_ORR | OP_I | calculateAddrMode1(imm) | (dst << 12) | (src << 16); +} + +uint32_t emitORRS(unsigned dst, unsigned src, unsigned op2) { + return OP_ORR | OP_S | (dst << 12) | (src << 16) | op2; +} + +uint32_t emitORRSI(unsigned dst, unsigned src, unsigned imm) { + return OP_ORR | OP_S | OP_I | calculateAddrMode1(imm) | (dst << 12) | (src << 16); +} + uint32_t emitPOP(unsigned mask) { return OP_POP | mask; } diff --git a/src/arm/dynarec-arm/emitter.h b/src/arm/dynarec-arm/emitter.h index 1365654ad..e57bea749 100644 --- a/src/arm/dynarec-arm/emitter.h +++ b/src/arm/dynarec-arm/emitter.h @@ -42,9 +42,18 @@ uint32_t calculateAddrMode1(unsigned imm); uint32_t emitADDI(unsigned dst, unsigned src, unsigned imm); uint32_t emitADDS(unsigned dst, unsigned src, unsigned op2); uint32_t emitADDSI(unsigned dst, unsigned src, unsigned imm); +uint32_t emitANDI(unsigned dst, unsigned src, unsigned imm); +uint32_t emitANDS(unsigned dst, unsigned src, unsigned op2); +uint32_t emitANDSI(unsigned dst, unsigned src, unsigned imm); uint32_t emitB(void* base, void* target); +uint32_t emitBICI(unsigned dst, unsigned src, unsigned imm); +uint32_t emitBICS(unsigned dst, unsigned src, unsigned op2); +uint32_t emitBICSI(unsigned dst, unsigned src, unsigned imm); uint32_t emitBL(void* base, void* target); uint32_t emitCMP(unsigned src1, unsigned src2); +uint32_t emitEORI(unsigned dst, unsigned src, unsigned imm); +uint32_t emitEORS(unsigned dst, unsigned src, unsigned op2); +uint32_t emitEORSI(unsigned dst, unsigned src, unsigned imm); uint32_t emitLDMIA(unsigned base, unsigned mask); uint32_t emitLDRI(unsigned reg, unsigned base, int offset); uint32_t emitMOV(unsigned dst, unsigned src); @@ -52,6 +61,9 @@ uint32_t emitMOV_LSRI(unsigned dst, unsigned src, unsigned imm); uint32_t emitMOVT(unsigned dst, uint16_t value); uint32_t emitMOVW(unsigned dst, uint16_t value); uint32_t emitMRS(unsigned dst); +uint32_t emitORRI(unsigned dst, unsigned src, unsigned imm); +uint32_t emitORRS(unsigned dst, unsigned src, unsigned op2); +uint32_t emitORRSI(unsigned dst, unsigned src, unsigned imm); uint32_t emitPOP(unsigned mask); uint32_t emitPUSH(unsigned mask); uint32_t emitSTMIA(unsigned base, unsigned mask);