diff --git a/ARMeilleure/Decoders/OpCode32AluImm16.cs b/ARMeilleure/Decoders/OpCode32AluImm16.cs new file mode 100644 index 0000000000..5d49cfd51b --- /dev/null +++ b/ARMeilleure/Decoders/OpCode32AluImm16.cs @@ -0,0 +1,15 @@ +namespace ARMeilleure.Decoders +{ + class OpCode32AluImm16 : OpCode32Alu + { + public int Immediate { get; private set; } + + public OpCode32AluImm16(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) + { + int imm12 = opCode & 0xffff; + int imm4 = (opCode >> 16) & 0xf; + + Immediate = (imm4 << 12) | imm12; + } + } +} diff --git a/ARMeilleure/Decoders/OpCode32AluRsImm.cs b/ARMeilleure/Decoders/OpCode32AluRsImm.cs index 779d6cecf8..68ca0d0cbe 100644 --- a/ARMeilleure/Decoders/OpCode32AluRsImm.cs +++ b/ARMeilleure/Decoders/OpCode32AluRsImm.cs @@ -2,15 +2,15 @@ namespace ARMeilleure.Decoders { class OpCode32AluRsImm : OpCode32Alu { - public int Rm { get; private set; } - public int Imm { get; private set; } + public int Rm { get; private set; } + public int Immediate { get; private set; } public ShiftType ShiftType { get; private set; } public OpCode32AluRsImm(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { - Rm = (opCode >> 0) & 0xf; - Imm = (opCode >> 7) & 0x1f; + Rm = (opCode >> 0) & 0xf; + Immediate = (opCode >> 7) & 0x1f; ShiftType = (ShiftType)((opCode >> 5) & 3); } diff --git a/ARMeilleure/Decoders/OpCodeTable.cs b/ARMeilleure/Decoders/OpCodeTable.cs index 2fa7702d90..5aa9c691e4 100644 --- a/ARMeilleure/Decoders/OpCodeTable.cs +++ b/ARMeilleure/Decoders/OpCodeTable.cs @@ -617,6 +617,7 @@ namespace ARMeilleure.Decoders SetA32("<<<<000xx1x1xxxxxxxxxxxx1111xxxx", InstName.Ldrsh, InstEmit32.Ldrsh, typeof(OpCode32MemImm8)); SetA32("<<<<0011101x0000xxxxxxxxxxxxxxxx", InstName.Mov, InstEmit32.Mov, typeof(OpCode32AluImm)); SetA32("<<<<0001101x0000xxxxxxxxxxx0xxxx", InstName.Mov, InstEmit32.Mov, typeof(OpCode32AluRsImm)); + SetA32("<<<<00110000xxxxxxxxxxxxxxxxxxxx", InstName.Mov, InstEmit32.Mov, typeof(OpCode32AluImm16)); SetT32("xxxxxxxxxxxxxxxx00100xxxxxxxxxxx", InstName.Mov, InstEmit32.Mov, typeof(OpCodeT16AluImm8)); SetA32("<<<<100xx0x0xxxxxxxxxxxxxxxxxxxx", InstName.Stm, InstEmit32.Stm, typeof(OpCode32MemMult)); SetA32("<<<<010xx0x0xxxxxxxxxxxxxxxxxxxx", InstName.Str, InstEmit32.Str, typeof(OpCode32MemImm)); @@ -625,6 +626,7 @@ namespace ARMeilleure.Decoders SetA32("<<<<000xx1x0xxxxxxxxxxxx1011xxxx", InstName.Strh, InstEmit32.Strh, typeof(OpCode32MemImm8)); SetA32("<<<<0010010xxxxxxxxxxxxxxxxxxxxx", InstName.Sub, InstEmit32.Sub, typeof(OpCode32AluImm)); SetA32("<<<<0000010xxxxxxxxxxxxxxxx0xxxx", InstName.Sub, InstEmit32.Sub, typeof(OpCode32AluRsImm)); + SetA32("<<<<00110011xxxx0000xxxxxxxxxxxx", InstName.Teq, InstEmit32.Teq, typeof(OpCode32AluImm)); #endregion FillFastLookupTable(_instA32FastLookup, _allInstA32); diff --git a/ARMeilleure/Instructions/InstEmitAlu32.cs b/ARMeilleure/Instructions/InstEmitAlu32.cs index 79b0abbc32..bef6f4e289 100644 --- a/ARMeilleure/Instructions/InstEmitAlu32.cs +++ b/ARMeilleure/Instructions/InstEmitAlu32.cs @@ -80,6 +80,18 @@ namespace ARMeilleure.Instructions EmitAluStore(context, res); } + public static void Teq(ArmEmitterContext context) + { + IOpCode32Alu op = (IOpCode32Alu)context.CurrOp; + + Operand n = GetAluN(context); + Operand m = GetAluM(context); + + Operand res = context.BitwiseExclusiveOr(n, m); + + EmitNZFlagsCheck(context, res); + } + private static void EmitAluStore(ArmEmitterContext context, Operand value) { IOpCode32Alu op = (IOpCode32Alu)context.CurrOp; diff --git a/ARMeilleure/Instructions/InstEmitAluHelper.cs b/ARMeilleure/Instructions/InstEmitAluHelper.cs index d032b32e87..48e212caad 100644 --- a/ARMeilleure/Instructions/InstEmitAluHelper.cs +++ b/ARMeilleure/Instructions/InstEmitAluHelper.cs @@ -116,6 +116,8 @@ namespace ARMeilleure.Instructions return Const(op.Immediate); } + case OpCode32AluImm16 op: return Const(op.Immediate); + case OpCode32AluRsImm op: return GetMShiftedByImmediate(context, op, setCarry); case OpCodeT16AluImm8 op: return Const(op.Immediate); @@ -171,7 +173,7 @@ namespace ARMeilleure.Instructions { Operand m = GetIntA32(context, op.Rm); - int shift = op.Imm; + int shift = op.Immediate; if (shift == 0) { @@ -193,7 +195,7 @@ namespace ARMeilleure.Instructions case ShiftType.Lsr: m = GetLsrC(context, m, setCarry, shift); break; case ShiftType.Asr: m = GetAsrC(context, m, setCarry, shift); break; case ShiftType.Ror: - if (op.Imm != 0) + if (op.Immediate != 0) { m = GetRorC(context, m, setCarry, shift); } diff --git a/ARMeilleure/Instructions/InstName.cs b/ARMeilleure/Instructions/InstName.cs index c81484a6f4..d5857218a5 100644 --- a/ARMeilleure/Instructions/InstName.cs +++ b/ARMeilleure/Instructions/InstName.cs @@ -458,6 +458,7 @@ namespace ARMeilleure.Instructions Stm, Strb, Strd, - Strh + Strh, + Teq } }