diff options
Diffstat (limited to 'ARMeilleure/Instructions/InstEmitFlowHelper.cs')
| -rw-r--r-- | ARMeilleure/Instructions/InstEmitFlowHelper.cs | 240 |
1 files changed, 0 insertions, 240 deletions
diff --git a/ARMeilleure/Instructions/InstEmitFlowHelper.cs b/ARMeilleure/Instructions/InstEmitFlowHelper.cs deleted file mode 100644 index 6ac32908..00000000 --- a/ARMeilleure/Instructions/InstEmitFlowHelper.cs +++ /dev/null @@ -1,240 +0,0 @@ -using ARMeilleure.CodeGen.Linking; -using ARMeilleure.Decoders; -using ARMeilleure.IntermediateRepresentation; -using ARMeilleure.State; -using ARMeilleure.Translation; -using ARMeilleure.Translation.PTC; - -using static ARMeilleure.Instructions.InstEmitHelper; -using static ARMeilleure.IntermediateRepresentation.Operand.Factory; - -namespace ARMeilleure.Instructions -{ - static class InstEmitFlowHelper - { - public static void EmitCondBranch(ArmEmitterContext context, Operand target, Condition cond) - { - if (cond != Condition.Al) - { - context.BranchIfTrue(target, GetCondTrue(context, cond)); - } - else - { - context.Branch(target); - } - } - - public static Operand GetCondTrue(ArmEmitterContext context, Condition condition) - { - Operand cmpResult = context.TryGetComparisonResult(condition); - - if (cmpResult != default) - { - return cmpResult; - } - - Operand value = Const(1); - - Operand Inverse(Operand val) - { - return context.BitwiseExclusiveOr(val, Const(1)); - } - - switch (condition) - { - case Condition.Eq: - value = GetFlag(PState.ZFlag); - break; - - case Condition.Ne: - value = Inverse(GetFlag(PState.ZFlag)); - break; - - case Condition.GeUn: - value = GetFlag(PState.CFlag); - break; - - case Condition.LtUn: - value = Inverse(GetFlag(PState.CFlag)); - break; - - case Condition.Mi: - value = GetFlag(PState.NFlag); - break; - - case Condition.Pl: - value = Inverse(GetFlag(PState.NFlag)); - break; - - case Condition.Vs: - value = GetFlag(PState.VFlag); - break; - - case Condition.Vc: - value = Inverse(GetFlag(PState.VFlag)); - break; - - case Condition.GtUn: - { - Operand c = GetFlag(PState.CFlag); - Operand z = GetFlag(PState.ZFlag); - - value = context.BitwiseAnd(c, Inverse(z)); - - break; - } - - case Condition.LeUn: - { - Operand c = GetFlag(PState.CFlag); - Operand z = GetFlag(PState.ZFlag); - - value = context.BitwiseOr(Inverse(c), z); - - break; - } - - case Condition.Ge: - { - Operand n = GetFlag(PState.NFlag); - Operand v = GetFlag(PState.VFlag); - - value = context.ICompareEqual(n, v); - - break; - } - - case Condition.Lt: - { - Operand n = GetFlag(PState.NFlag); - Operand v = GetFlag(PState.VFlag); - - value = context.ICompareNotEqual(n, v); - - break; - } - - case Condition.Gt: - { - Operand n = GetFlag(PState.NFlag); - Operand z = GetFlag(PState.ZFlag); - Operand v = GetFlag(PState.VFlag); - - value = context.BitwiseAnd(Inverse(z), context.ICompareEqual(n, v)); - - break; - } - - case Condition.Le: - { - Operand n = GetFlag(PState.NFlag); - Operand z = GetFlag(PState.ZFlag); - Operand v = GetFlag(PState.VFlag); - - value = context.BitwiseOr(z, context.ICompareNotEqual(n, v)); - - break; - } - } - - return value; - } - - public static void EmitCall(ArmEmitterContext context, ulong immediate) - { - bool isRecursive = immediate == context.EntryAddress; - - if (isRecursive) - { - context.Branch(context.GetLabel(immediate)); - } - else - { - EmitTableBranch(context, Const(immediate), isJump: false); - } - } - - public static void EmitVirtualCall(ArmEmitterContext context, Operand target) - { - EmitTableBranch(context, target, isJump: false); - } - - public static void EmitVirtualJump(ArmEmitterContext context, Operand target, bool isReturn) - { - if (isReturn) - { - if (target.Type == OperandType.I32) - { - target = context.ZeroExtend32(OperandType.I64, target); - } - - context.Return(target); - } - else - { - EmitTableBranch(context, target, isJump: true); - } - } - - private static void EmitTableBranch(ArmEmitterContext context, Operand guestAddress, bool isJump) - { - context.StoreToContext(); - - if (guestAddress.Type == OperandType.I32) - { - guestAddress = context.ZeroExtend32(OperandType.I64, guestAddress); - } - - // Store the target guest address into the native context. The stubs uses this address to dispatch into the - // next translation. - Operand nativeContext = context.LoadArgument(OperandType.I64, 0); - Operand dispAddressAddr = context.Add(nativeContext, Const((ulong)NativeContext.GetDispatchAddressOffset())); - context.Store(dispAddressAddr, guestAddress); - - Operand hostAddress; - - // If address is mapped onto the function table, we can skip the table walk. Otherwise we fallback - // onto the dispatch stub. - if (guestAddress.Kind == OperandKind.Constant && context.FunctionTable.IsValid(guestAddress.Value)) - { - Operand hostAddressAddr = !context.HasPtc ? - Const(ref context.FunctionTable.GetValue(guestAddress.Value)) : - Const(ref context.FunctionTable.GetValue(guestAddress.Value), new Symbol(SymbolType.FunctionTable, guestAddress.Value)); - - hostAddress = context.Load(OperandType.I64, hostAddressAddr); - } - else - { - hostAddress = !context.HasPtc ? - Const((long)context.Stubs.DispatchStub) : - Const((long)context.Stubs.DispatchStub, Ptc.DispatchStubSymbol); - } - - if (isJump) - { - context.Tailcall(hostAddress, nativeContext); - } - else - { - OpCode op = context.CurrOp; - - Operand returnAddress = context.Call(hostAddress, OperandType.I64, nativeContext); - - context.LoadFromContext(); - - // Note: The return value of a translated function is always an Int64 with the address execution has - // returned to. We expect this address to be immediately after the current instruction, if it isn't we - // keep returning until we reach the dispatcher. - Operand nextAddr = Const((long)op.Address + op.OpCodeSizeInBytes); - - // Try to continue within this block. - // If the return address isn't to our next instruction, we need to return so the JIT can figure out - // what to do. - Operand lblContinue = context.GetLabel(nextAddr.Value); - context.BranchIf(lblContinue, returnAddress, nextAddr, Comparison.Equal, BasicBlockFrequency.Cold); - - context.Return(returnAddress); - } - } - } -} |
