Implement thumb1_STR_reg, thumb1_STRH_reg, thumb1_STRB_reg

This commit is contained in:
MerryMage 2016-07-11 23:06:35 +01:00
parent e7922e4fef
commit 1410221b47
9 changed files with 60 additions and 6 deletions

View file

@ -223,10 +223,18 @@ void EmitX64::EmitGetOverflowFromOp(IR::Value*) {
ASSERT_MSG(0, "should never happen");
}
void EmitX64::EmitLeastSignificantHalf(IR::Value* value_) {
auto value = reinterpret_cast<IR::Inst*>(value_);
// TODO: Optimize
reg_alloc.UseDefRegister(value->GetArg(0).get(), value);
}
void EmitX64::EmitLeastSignificantByte(IR::Value* value_) {
auto value = reinterpret_cast<IR::Inst*>(value_);
// TODO: Flag optimization
// TODO: Optimize
reg_alloc.UseDefRegister(value->GetArg(0).get(), value);
}

View file

@ -46,6 +46,7 @@ public:
void EmitSetVFlag(IR::Value* value);
void EmitGetCarryFromOp(IR::Value* value);
void EmitGetOverflowFromOp(IR::Value* value);
void EmitLeastSignificantHalf(IR::Value* value);
void EmitLeastSignificantByte(IR::Value* value);
void EmitMostSignificantBit(IR::Value* value);
void EmitIsZero(IR::Value* value);

View file

@ -56,7 +56,7 @@ private:
};
template <typename V>
static const std::array<Thumb1Matcher<V>, 32> g_thumb1_instruction_table {{
static const std::array<Thumb1Matcher<V>, 35> g_thumb1_instruction_table {{
#define INST(fn, name, bitstring) detail::detail<Thumb1Matcher, u16, 16>::GetMatcher<decltype(fn), fn>(name, bitstring)
@ -98,9 +98,9 @@ static const std::array<Thumb1Matcher<V>, 32> g_thumb1_instruction_table {{
// Store/Load single data item instructions
{ INST(&V::thumb1_LDR_literal, "LDR (literal)", "01001tttvvvvvvvv") },
//{ INST(&V::thumb1_STR_rrr, "STR (rrr)", "0101000mmmnnnddd") },
//{ INST(&V::thumb1_STRH_rrr, "STRH (rrr)", "0101001mmmnnnddd") },
//{ INST(&V::thumb1_STRB_rrr, "STRB (rrr)", "0101010mmmnnnddd") },
{ INST(&V::thumb1_STR_reg, "STR (reg)", "0101000mmmnnnttt") },
{ INST(&V::thumb1_STRH_reg, "STRH (reg)", "0101001mmmnnnttt") },
{ INST(&V::thumb1_STRB_reg, "STRB (reg)", "0101010mmmnnnttt") },
//{ INST(&V::thumb1_LDRSB_rrr, "LDRSB (rrr)", "0101011mmmnnnddd") },
//{ INST(&V::thumb1_LDR_rrr, "LDR (rrr)", "0101100mmmnnnddd") },
//{ INST(&V::thumb1_LDRH_rrr, "LDRH (rrr)", "0101101mmmnnnddd") },

View file

@ -227,6 +227,18 @@ public:
return Common::StringFromFormat("ldr %s, [pc, #%u]", RegStr(t), imm32);
}
std::string thumb1_STR_reg(Reg m, Reg n, Reg t) {
return Common::StringFromFormat("str %s, [%s, %s]", RegStr(t), RegStr(n), RegStr(m));
}
std::string thumb1_STRH_reg(Reg m, Reg n, Reg t) {
return Common::StringFromFormat("strh %s, [%s, %s]", RegStr(t), RegStr(n), RegStr(m));
}
std::string thumb1_STRB_reg(Reg m, Reg n, Reg t) {
return Common::StringFromFormat("strb %s, [%s, %s]", RegStr(t), RegStr(n), RegStr(m));
}
std::string thumb1_LDR_imm_t1(Imm5 imm5, Reg n, Reg t) {
u32 imm32 = imm5 << 2;
return Common::StringFromFormat("ldr %s, [%s, #%u]", RegStr(t), RegStr(n), imm32);

View file

@ -23,6 +23,7 @@ OPCODE(GetCarryFromOp, T::U1, T::U32
OPCODE(GetOverflowFromOp, T::U1, T::U32 )
// Calculations
OPCODE(LeastSignificantHalf, T::U16, T::U32 )
OPCODE(LeastSignificantByte, T::U8, T::U32 )
OPCODE(MostSignificantBit, T::U1, T::U32 )
OPCODE(IsZero, T::U1, T::U32 )

View file

@ -79,6 +79,10 @@ void IREmitter::SetVFlag(IR::ValuePtr value) {
Inst(IR::Opcode::SetVFlag, {value});
}
IR::ValuePtr IREmitter::LeastSignificantHalf(IR::ValuePtr value) {
return Inst(IR::Opcode::LeastSignificantHalf, {value});
}
IR::ValuePtr IREmitter::LeastSignificantByte(IR::ValuePtr value) {
return Inst(IR::Opcode::LeastSignificantByte, {value});
}

View file

@ -50,6 +50,7 @@ public:
void SetCFlag(IR::ValuePtr value);
void SetVFlag(IR::ValuePtr value);
IR::ValuePtr LeastSignificantHalf(IR::ValuePtr value);
IR::ValuePtr LeastSignificantByte(IR::ValuePtr value);
IR::ValuePtr MostSignificantBit(IR::ValuePtr value);
IR::ValuePtr IsZero(IR::ValuePtr value);

View file

@ -375,6 +375,33 @@ struct TranslatorVisitor final {
return true;
}
bool thumb1_STR_reg(Reg m, Reg n, Reg t) {
// STR <Rt>, [<Rn>, <Rm>]
// Rt cannot encode R15.
auto address = ir.Add(ir.GetRegister(n), ir.GetRegister(m));
auto data = ir.GetRegister(t);
ir.WriteMemory32(address, data);
return true;
}
bool thumb1_STRH_reg(Reg m, Reg n, Reg t) {
// STRH <Rt>, [<Rn>, <Rm>]
// Rt cannot encode R15.
auto address = ir.Add(ir.GetRegister(n), ir.GetRegister(m));
auto data = ir.LeastSignificantHalf(ir.GetRegister(t));
ir.WriteMemory16(address, data);
return true;
}
bool thumb1_STRB_reg(Reg m, Reg n, Reg t) {
// STRB <Rt>, [<Rn>, <Rm>]
// Rt cannot encode R15.
auto address = ir.Add(ir.GetRegister(n), ir.GetRegister(m));
auto data = ir.LeastSignificantByte(ir.GetRegister(t));
ir.WriteMemory8(address, data);
return true;
}
bool thumb1_LDR_imm_t1(Imm5 imm5, Reg n, Reg t) {
u32 imm32 = imm5 << 2;
// LDR <Rt>, [<Rn>, #<imm>}