From df0c3249238247dc83bf42145a9c13d3c8a50343 Mon Sep 17 00:00:00 2001 From: MerryMage Date: Fri, 8 Jul 2016 18:14:50 +0800 Subject: [PATCH] Implement thumb1_EOR_reg --- src/backend_x64/emit_x64.cpp | 9 +++++++++ src/backend_x64/emit_x64.h | 1 + src/frontend/decoder/thumb1.h | 4 ++-- src/frontend/disassembler_thumb.cpp | 4 ++++ src/frontend/ir/opcodes.inc | 1 + src/frontend/ir_emitter.cpp | 4 ++++ src/frontend/ir_emitter.h | 1 + src/frontend/translate_thumb.cpp | 10 ++++++++++ 8 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/backend_x64/emit_x64.cpp b/src/backend_x64/emit_x64.cpp index 52e549dc..90e57846 100644 --- a/src/backend_x64/emit_x64.cpp +++ b/src/backend_x64/emit_x64.cpp @@ -445,6 +445,15 @@ void EmitX64::EmitAnd(IR::Value* value_) { code->AND(32, R(result), R(andend)); } +void EmitX64::EmitEor(IR::Value* value_) { + auto value = reinterpret_cast(value_); + + X64Reg eorend = reg_alloc.UseRegister(value->GetArg(1).get()); + X64Reg result = reg_alloc.UseDefRegister(value->GetArg(0).get(), value); + + code->XOR(32, R(result), R(eorend)); +} + void EmitX64::EmitAddCycles(size_t cycles) { ASSERT(cycles < std::numeric_limits::max()); code->SUB(64, MDisp(R15, offsetof(JitState, cycles_remaining)), Imm32(static_cast(cycles))); diff --git a/src/backend_x64/emit_x64.h b/src/backend_x64/emit_x64.h index 1730e675..81d4d037 100644 --- a/src/backend_x64/emit_x64.h +++ b/src/backend_x64/emit_x64.h @@ -54,6 +54,7 @@ public: void EmitArithmeticShiftRight(IR::Value* value); void EmitAddWithCarry(IR::Value* value); void EmitAnd(IR::Value* value); + void EmitEor(IR::Value* value); void EmitAddCycles(size_t cycles); diff --git a/src/frontend/decoder/thumb1.h b/src/frontend/decoder/thumb1.h index 0d93097d..688c5588 100644 --- a/src/frontend/decoder/thumb1.h +++ b/src/frontend/decoder/thumb1.h @@ -56,7 +56,7 @@ private: }; template -static const std::array, 10> g_thumb1_instruction_table {{ +static const std::array, 11> g_thumb1_instruction_table {{ #define INST(fn, name, bitstring) detail::detail::GetMatcher(name, bitstring) @@ -75,7 +75,7 @@ static const std::array, 10> g_thumb1_instruction_table {{ // Data-processing instructions { INST(&V::thumb1_AND_reg, "AND (reg)", "0100000000mmmddd") }, -// { INST(&V::thumb1_EOR_reg, "EOR (reg)", "0100000001mmmddd") }, + { INST(&V::thumb1_EOR_reg, "EOR (reg)", "0100000001mmmddd") }, { INST(&V::thumb1_LSL_reg, "LSL (reg)", "0100000010mmmddd") }, { INST(&V::thumb1_LSR_reg, "LSR (reg)", "0100000011mmmddd") }, { INST(&V::thumb1_ASR_reg, "ASR (reg)", "0100000100mmmddd") }, diff --git a/src/frontend/disassembler_thumb.cpp b/src/frontend/disassembler_thumb.cpp index 076a6d37..5c8774a2 100644 --- a/src/frontend/disassembler_thumb.cpp +++ b/src/frontend/disassembler_thumb.cpp @@ -122,6 +122,10 @@ public: return Common::StringFromFormat("ands %s, %s", RegStr(d_n), RegStr(m)); } + std::string thumb1_EOR_reg(Reg m, Reg d_n) { + return Common::StringFromFormat("eors %s, %s", RegStr(d_n), RegStr(m)); + } + std::string thumb1_LSL_reg(Reg m, Reg d_n) { return Common::StringFromFormat("lsls %s, %s", RegStr(d_n), RegStr(m)); } diff --git a/src/frontend/ir/opcodes.inc b/src/frontend/ir/opcodes.inc index 79c5a685..aea9ffeb 100644 --- a/src/frontend/ir/opcodes.inc +++ b/src/frontend/ir/opcodes.inc @@ -31,3 +31,4 @@ OPCODE(LogicalShiftRight, T::U32, T::U32, T::U8, OPCODE(ArithmeticShiftRight, T::U32, T::U32, T::U8, T::U1 ) OPCODE(AddWithCarry, T::U32, T::U32, T::U32, T::U1 ) OPCODE(And, T::U32, T::U32, T::U32 ) +OPCODE(Eor, T::U32, T::U32, T::U32 ) diff --git a/src/frontend/ir_emitter.cpp b/src/frontend/ir_emitter.cpp index 8d0ee16a..0aeff43b 100644 --- a/src/frontend/ir_emitter.cpp +++ b/src/frontend/ir_emitter.cpp @@ -110,6 +110,10 @@ IR::ValuePtr IREmitter::And(IR::ValuePtr a, IR::ValuePtr b) { return Inst(IR::Opcode::And, {a, b}); } +IR::ValuePtr IREmitter::Eor(IR::ValuePtr a, IR::ValuePtr b) { + return Inst(IR::Opcode::Eor, {a, b}); +} + void IREmitter::SetTerm(const IR::Terminal& terminal) { ASSERT_MSG(block.terminal.which() == 0, "Terminal has already been set."); block.terminal = terminal; diff --git a/src/frontend/ir_emitter.h b/src/frontend/ir_emitter.h index 0cac8b55..254b8086 100644 --- a/src/frontend/ir_emitter.h +++ b/src/frontend/ir_emitter.h @@ -57,6 +57,7 @@ public: ResultAndCarry ArithmeticShiftRight(IR::ValuePtr value_in, IR::ValuePtr shift_amount, IR::ValuePtr carry_in); ResultAndCarryAndOverflow AddWithCarry(IR::ValuePtr a, IR::ValuePtr b, IR::ValuePtr carry_in); IR::ValuePtr And(IR::ValuePtr a, IR::ValuePtr b); + IR::ValuePtr Eor(IR::ValuePtr a, IR::ValuePtr b); void SetTerm(const IR::Terminal& terminal); diff --git a/src/frontend/translate_thumb.cpp b/src/frontend/translate_thumb.cpp index 83635380..ce618469 100644 --- a/src/frontend/translate_thumb.cpp +++ b/src/frontend/translate_thumb.cpp @@ -86,6 +86,16 @@ struct TranslatorVisitor final { ir.SetZFlag(ir.IsZero(result)); return true; } + bool thumb1_EOR_reg(Reg m, Reg d_n) { + const Reg d = d_n, n = d_n; + // EORS , + // Note that it is not possible to encode Rdn == R15. + auto result = ir.Eor(ir.GetRegister(n), ir.GetRegister(m)); + ir.SetRegister(d, result); + ir.SetNFlag(ir.MostSignificantBit(result)); + ir.SetZFlag(ir.IsZero(result)); + return true; + } bool thumb1_LSL_reg(Reg m, Reg d_n) { const Reg d = d_n, n = d_n; // LSLS ,