diff options
author | gdkchan <gab.dark.100@gmail.com> | 2022-09-13 19:51:40 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-13 19:51:40 -0300 |
commit | 8e119a1e9694416289c4c4c7ed38c408c096f9a2 (patch) | |
tree | 76e7dd37606858a91d9400824da798448cb6d41f /ARMeilleure/Instructions | |
parent | e05bf90af600f5c75a13a0b4113b7fc6a641ff6a (diff) |
Implement PLD and SUB (imm16) on T32, plus UADD8, SADD8, USUB8 and SSUB8 on both A32 and T32 (#3693)1.1.269
Diffstat (limited to 'ARMeilleure/Instructions')
-rw-r--r-- | ARMeilleure/Instructions/InstEmitAlu32.cs | 88 | ||||
-rw-r--r-- | ARMeilleure/Instructions/InstName.cs | 5 |
2 files changed, 85 insertions, 8 deletions
diff --git a/ARMeilleure/Instructions/InstEmitAlu32.cs b/ARMeilleure/Instructions/InstEmitAlu32.cs index 31d8a02c..584ada7e 100644 --- a/ARMeilleure/Instructions/InstEmitAlu32.cs +++ b/ARMeilleure/Instructions/InstEmitAlu32.cs @@ -363,6 +363,11 @@ namespace ARMeilleure.Instructions EmitAluStore(context, res); } + public static void Sadd8(ArmEmitterContext context) + { + EmitAddSub8(context, add: true, unsigned: false); + } + public static void Sbc(ArmEmitterContext context) { IOpCode32Alu op = (IOpCode32Alu)context.CurrOp; @@ -401,17 +406,38 @@ namespace ARMeilleure.Instructions public static void Sdiv(ArmEmitterContext context) { - EmitDiv(context, false); + EmitDiv(context, unsigned: false); + } + + public static void Sel(ArmEmitterContext context) + { + IOpCode32AluReg op = (IOpCode32AluReg)context.CurrOp; + + Operand n = GetIntA32(context, op.Rn); + Operand m = GetIntA32(context, op.Rm); + + Operand ge0 = context.ZeroExtend8(OperandType.I32, context.Negate(GetFlag(PState.GE0Flag))); + Operand ge1 = context.ZeroExtend8(OperandType.I32, context.Negate(GetFlag(PState.GE1Flag))); + Operand ge2 = context.ZeroExtend8(OperandType.I32, context.Negate(GetFlag(PState.GE2Flag))); + Operand ge3 = context.Negate(GetFlag(PState.GE3Flag)); + + Operand mask = context.BitwiseOr(ge0, context.ShiftLeft(ge1, Const(8))); + mask = context.BitwiseOr(mask, context.ShiftLeft(ge2, Const(16))); + mask = context.BitwiseOr(mask, context.ShiftLeft(ge3, Const(24))); + + Operand res = context.BitwiseOr(context.BitwiseAnd(n, mask), context.BitwiseAnd(m, context.BitwiseNot(mask))); + + SetIntA32(context, op.Rd, res); } public static void Shadd8(ArmEmitterContext context) { - EmitHadd8(context, false); + EmitHadd8(context, unsigned: false); } public static void Shsub8(ArmEmitterContext context) { - EmitHsub8(context, false); + EmitHsub8(context, unsigned: false); } public static void Ssat(ArmEmitterContext context) @@ -428,6 +454,11 @@ namespace ARMeilleure.Instructions EmitSat16(context, -(1 << op.SatImm), (1 << op.SatImm) - 1); } + public static void Ssub8(ArmEmitterContext context) + { + EmitAddSub8(context, add: false, unsigned: false); + } + public static void Sub(ArmEmitterContext context) { IOpCode32Alu op = (IOpCode32Alu)context.CurrOp; @@ -482,6 +513,11 @@ namespace ARMeilleure.Instructions EmitNZFlagsCheck(context, res); } + public static void Uadd8(ArmEmitterContext context) + { + EmitAddSub8(context, add: true, unsigned: true); + } + public static void Ubfx(ArmEmitterContext context) { IOpCode32AluBf op = (IOpCode32AluBf)context.CurrOp; @@ -496,17 +532,17 @@ namespace ARMeilleure.Instructions public static void Udiv(ArmEmitterContext context) { - EmitDiv(context, true); + EmitDiv(context, unsigned: true); } public static void Uhadd8(ArmEmitterContext context) { - EmitHadd8(context, true); + EmitHadd8(context, unsigned: true); } public static void Uhsub8(ArmEmitterContext context) { - EmitHsub8(context, true); + EmitHsub8(context, unsigned: true); } public static void Usat(ArmEmitterContext context) @@ -523,6 +559,11 @@ namespace ARMeilleure.Instructions EmitSat16(context, 0, (1 << op.SatImm) - 1); } + public static void Usub8(ArmEmitterContext context) + { + EmitAddSub8(context, add: false, unsigned: true); + } + public static void Uxtb(ArmEmitterContext context) { EmitSignExtend(context, false, 8); @@ -678,9 +719,40 @@ namespace ARMeilleure.Instructions context.MarkLabel(lblEnd); } + private static void EmitAddSub8(ArmEmitterContext context, bool add, bool unsigned) + { + IOpCode32AluReg op = (IOpCode32AluReg)context.CurrOp; + + Operand n = GetIntA32(context, op.Rn); + Operand m = GetIntA32(context, op.Rm); + + Operand res = Const(0); + + for (int byteSel = 0; byteSel < 4; byteSel++) + { + Operand shift = Const(byteSel * 8); + + Operand nByte = context.ShiftRightUI(n, shift); + Operand mByte = context.ShiftRightUI(m, shift); + + nByte = unsigned ? context.ZeroExtend8(OperandType.I32, nByte) : context.SignExtend8(OperandType.I32, nByte); + mByte = unsigned ? context.ZeroExtend8(OperandType.I32, mByte) : context.SignExtend8(OperandType.I32, mByte); + + Operand resByte = add ? context.Add(nByte, mByte) : context.Subtract(nByte, mByte); + + res = context.BitwiseOr(res, context.ShiftLeft(context.ZeroExtend8(OperandType.I32, resByte), shift)); + + SetFlag(context, PState.GE0Flag + byteSel, unsigned && add + ? context.ShiftRightUI(resByte, Const(8)) + : context.ShiftRightUI(context.BitwiseNot(resByte), Const(31))); + } + + SetIntA32(context, op.Rd, res); + } + private static void EmitHadd8(ArmEmitterContext context, bool unsigned) { - OpCode32AluReg op = (OpCode32AluReg)context.CurrOp; + IOpCode32AluReg op = (IOpCode32AluReg)context.CurrOp; Operand m = GetIntA32(context, op.Rm); Operand n = GetIntA32(context, op.Rn); @@ -710,7 +782,7 @@ namespace ARMeilleure.Instructions private static void EmitHsub8(ArmEmitterContext context, bool unsigned) { - OpCode32AluReg op = (OpCode32AluReg)context.CurrOp; + IOpCode32AluReg op = (IOpCode32AluReg)context.CurrOp; Operand m = GetIntA32(context, op.Rm); Operand n = GetIntA32(context, op.Rn); diff --git a/ARMeilleure/Instructions/InstName.cs b/ARMeilleure/Instructions/InstName.cs index f7022f8e..73be1aef 100644 --- a/ARMeilleure/Instructions/InstName.cs +++ b/ARMeilleure/Instructions/InstName.cs @@ -81,6 +81,7 @@ namespace ARMeilleure.Instructions Sbcs, Sbfm, Sdiv, + Sel, Shsub8, Smaddl, Smsubl, @@ -519,6 +520,7 @@ namespace ARMeilleure.Instructions Revsh, Rsb, Rsc, + Sadd8, Sbfx, Shadd8, Smla__, @@ -529,6 +531,7 @@ namespace ARMeilleure.Instructions Smmls, Smul__, Smmul, + Ssub8, Stl, Stlb, Stlex, @@ -550,6 +553,7 @@ namespace ARMeilleure.Instructions Teq, Trap, Tst, + Uadd8, Ubfx, Uhadd8, Uhsub8, @@ -558,6 +562,7 @@ namespace ARMeilleure.Instructions Umull, Usat, Usat16, + Usub8, Uxtb, Uxtb16, Uxth, |