public LIRParameter(LIRMethod parent, LIRType tp) { this.Parent = parent; this.Type = tp; this.Index = parent.mParameters.Count; parent.mParameters.Add(this); }
public override void ConvertToLIR(LIRMethod pLIRMethod) { var sA = pLIRMethod.RequestLocal(Sources[0].GetTypeOfLocation()); Sources[0].LoadTo(pLIRMethod, sA); var sB = pLIRMethod.RequestLocal(Sources[1].GetTypeOfLocation()); Sources[1].LoadTo(pLIRMethod, sB); var dest = pLIRMethod.RequestLocal(Destination.GetTypeOfLocation()); LIRInstructions.CompareCondition condition = LIRInstructions.CompareCondition.Equal; switch (CompareCondition) { case IRCompareCondition.Equal: break; case IRCompareCondition.GreaterThan: case IRCompareCondition.GreaterThanUnsigned: condition = LIRInstructions.CompareCondition.GreaterThan; break; case IRCompareCondition.LessThan: case IRCompareCondition.LessThanUnsigned: condition = LIRInstructions.CompareCondition.LessThan; break; default: throw new Exception("Invalid Compare Condition"); } new LIRInstructions.Compare(pLIRMethod, sA, sB, dest, sA.Type, condition); pLIRMethod.ReleaseLocal(sA); pLIRMethod.ReleaseLocal(sB); Destination.StoreTo(pLIRMethod, dest); pLIRMethod.ReleaseLocal(dest); }
public override void ConvertToLIR(LIRMethod pLIRMethod) { var s = pLIRMethod.RequestLocal(Sources[0].GetTypeOfLocation()); Sources[0].LoadTo(pLIRMethod, s); //new LIRInstructions.Throw(pLIRMethod, s, s.Type); pLIRMethod.ReleaseLocal(s); }
public override void ConvertToLIR(LIRMethod pLIRMethod) { Label[] lbls = new Label[TargetIRInstructions.Length]; for (int i = 0; i < lbls.Length; i++) { lbls[i] = TargetIRInstructions[i].Label; } var swDatItem = new SwitchEmittableDataItem(lbls); pLIRMethod.CompileUnit.AddData(swDatItem); // Need to load and compare original value first... var vs = pLIRMethod.RequestLocal(Sources[0].GetTypeOfLocation()); Sources[0].LoadTo(pLIRMethod, vs); var vt = pLIRMethod.RequestLocal(AppDomain.System_Boolean); new LIRInstructions.Compare(pLIRMethod, vs, (LIRImm)0, vt, vs.Type, LIRInstructions.CompareCondition.LessThan); new LIRInstructions.BranchTrue(pLIRMethod, vt, ParentMethod.Instructions[this.IRIndex + 1].Label); new LIRInstructions.Compare(pLIRMethod, vs, (LIRImm)lbls.Length, vt, vs.Type, LIRInstructions.CompareCondition.GreaterThan); new LIRInstructions.BranchTrue(pLIRMethod, vt, ParentMethod.Instructions[this.IRIndex + 1].Label); pLIRMethod.ReleaseLocal(vt); var sBase = pLIRMethod.RequestLocal(AppDomain.System_UIntPtr); new LIRInstructions.Move(pLIRMethod, swDatItem.Label, sBase, AppDomain.System_UIntPtr); new LIRInstructions.Math(pLIRMethod, vs, (LIRImm)VMConfig.PointerSizeForTarget, vs, LIRInstructions.MathOperation.Multiply, vs.Type); new LIRInstructions.Math(pLIRMethod, vs, sBase, sBase, LIRInstructions.MathOperation.Add, sBase.Type); pLIRMethod.ReleaseLocal(vs); new LIRInstructions.Move(pLIRMethod, new Indirect(sBase), sBase, sBase.Type); new LIRInstructions.BranchIndirect(pLIRMethod, sBase); pLIRMethod.ReleaseLocal(sBase); }
public override void ConvertToLIR(LIRMethod pLIRMethod) { if (Constructor.ParentType == AppDomain.System_String) { #warning Finish special cases for string constructors } else { var sTypeDataPtr = pLIRMethod.RequestLocal(AppDomain.System_GC_AllocateObject.LIRMethod.Parameters[0].Type); new LIRInstructions.Move(pLIRMethod, Constructor.ParentType.MetadataLabel, sTypeDataPtr, sTypeDataPtr.Type); var sReturnPtr = pLIRMethod.RequestLocal(AppDomain.System_GC_AllocateObject.LIRMethod.Parameters[1].Type); Destination.LoadAddressTo(pLIRMethod, sReturnPtr); List<ISource> allocateObjectParams = new List<ISource>(2); allocateObjectParams.Add(sTypeDataPtr); // pointer to type data allocateObjectParams.Add(sReturnPtr); // pointer to destination new LIRInstructions.Call(pLIRMethod, AppDomain.System_GC_AllocateObject, allocateObjectParams, null); pLIRMethod.ReleaseLocal(sReturnPtr); pLIRMethod.ReleaseLocal(sTypeDataPtr); List<LIRLocal> constructorParams = new List<LIRLocal>(Sources.Count + 1); var sObj = pLIRMethod.RequestLocal(Destination.GetTypeOfLocation()); Destination.LoadTo(pLIRMethod, sObj); constructorParams.Add(sObj); foreach (IRLinearizedLocation sourceLocation in Sources) { var s = pLIRMethod.RequestLocal(sourceLocation.GetTypeOfLocation()); constructorParams.Add(s); sourceLocation.LoadTo(pLIRMethod, s); } new LIRInstructions.Call(pLIRMethod, Constructor, constructorParams, null); constructorParams.ForEach(s => pLIRMethod.ReleaseLocal(s)); } }
public override void ConvertToLIR(LIRMethod pLIRMethod) { var sTypedReference = pLIRMethod.RequestLocal(Sources[0].GetTypeOfLocation().GetManagedPointerType()); Sources[0].LoadAddressTo(pLIRMethod, sTypedReference); new LIRInstructions.Move(pLIRMethod, new Indirect(sTypedReference), sTypedReference, sTypedReference.Type); Destination.StoreTo(pLIRMethod, sTypedReference); pLIRMethod.ReleaseLocal(sTypedReference); }
public LIRLocal(LIRMethod parent, LIRType tp) { this.Parent = parent; this.Type = tp; this.Index = parent.mLocals.Count; this.Parent.mLocals.Add(this); }
protected LIRInstruction(LIRMethod parent, LIROpCode opCode) { this.OpCode = opCode; if (parent != null) { this.Index = parent.mInstructions.Count; parent.mInstructions.Add(this); } }
public override void ConvertToLIR(LIRMethod pLIRMethod) { var sA = pLIRMethod.RequestLocal(Sources[0].GetTypeOfLocation()); Sources[0].LoadTo(pLIRMethod, sA); var dest = pLIRMethod.RequestLocal(Destination.GetTypeOfLocation()); new LIRInstructions.Convert(pLIRMethod, sA, sA.Type, dest, dest.Type); pLIRMethod.ReleaseLocal(sA); Destination.StoreTo(pLIRMethod, dest); pLIRMethod.ReleaseLocal(dest); }
public override void ConvertToLIR(LIRMethod pLIRMethod) { var s = pLIRMethod.RequestLocal(Sources[0].GetTypeOfLocation()); Sources[0].LoadTo(pLIRMethod, s); var d = pLIRMethod.RequestLocal(Type); new LIRInstructions.Move(pLIRMethod, Type.ToLIRType().Empty, d, Type); new LIRInstructions.Move(pLIRMethod, d, new Indirect(s), Type); pLIRMethod.ReleaseLocal(s); pLIRMethod.ReleaseLocal(d); }
public override void ConvertToLIR(LIRMethod pLIRMethod) { var s = pLIRMethod.RequestLocal(Sources[0].GetTypeOfLocation()); Sources[0].LoadTo(pLIRMethod, s); if (GetValue) { new LIRInstructions.Move(pLIRMethod, new Indirect(s), s, Destination.GetTypeOfLocation()); } Destination.StoreTo(pLIRMethod, s); pLIRMethod.ReleaseLocal(s); }
public override void ConvertToLIR(LIRMethod pLIRMethod) { var sTypedReference = pLIRMethod.RequestLocal(Sources[0].GetTypeOfLocation().GetManagedPointerType()); Sources[0].LoadAddressTo(pLIRMethod, sTypedReference); var sAddressPointer = pLIRMethod.RequestLocal(Destination.GetTypeOfLocation()); new LIRInstructions.Math(pLIRMethod, sTypedReference, (LIRImm)VMConfig.PointerSizeForTarget, sAddressPointer, LIRInstructions.MathOperation.Add, sAddressPointer.Type); new LIRInstructions.Move(pLIRMethod, new Indirect(sAddressPointer), sAddressPointer, sAddressPointer.Type); Destination.StoreTo(pLIRMethod, sAddressPointer); pLIRMethod.ReleaseLocal(sAddressPointer); pLIRMethod.ReleaseLocal(sTypedReference); }
public override void ConvertToLIR(LIRMethod pLIRMethod) { var sA = pLIRMethod.RequestLocal(Sources[0].GetTypeOfLocation()); Sources[0].LoadTo(pLIRMethod, sA); var sB = pLIRMethod.RequestLocal(Sources[1].GetTypeOfLocation()); Sources[1].LoadTo(pLIRMethod, sB); var dest = pLIRMethod.RequestLocal(Destination.GetTypeOfLocation()); new LIRInstructions.Math(pLIRMethod, sA, sB, dest, LIRInstructions.MathOperation.Multiply, dest.Type); pLIRMethod.ReleaseLocal(sA); pLIRMethod.ReleaseLocal(sB); Destination.StoreTo(pLIRMethod, dest); pLIRMethod.ReleaseLocal(dest); }
public override void ConvertToLIR(LIRMethod pLIRMethod) { if (ParentMethod.ReturnType != null) { var sA = pLIRMethod.RequestLocal(Sources[0].GetTypeOfLocation()); Sources[0].LoadTo(pLIRMethod, sA); new LIRInstructions.Return(pLIRMethod, sA, sA.Type); pLIRMethod.ReleaseLocal(sA); } else { new LIRInstructions.Return(pLIRMethod); } }
public override void ConvertToLIR(LIRMethod pLIRMethod) { var sValuePtr = pLIRMethod.RequestLocal(Sources[0].GetTypeOfLocation()); Sources[0].LoadAddressTo(pLIRMethod, sValuePtr); var sTypeDataPtr = pLIRMethod.RequestLocal(AppDomain.System_GC_BoxObject.LIRMethod.Parameters[0].Type); new LIRInstructions.Move(pLIRMethod, Type.MetadataLabel, sTypeDataPtr, sTypeDataPtr.Type); var sReturnPtr = pLIRMethod.RequestLocal(AppDomain.System_GC_BoxObject.LIRMethod.Parameters[2].Type); Destination.LoadAddressTo(pLIRMethod, sReturnPtr); List<ISource> boxObjectParams = new List<ISource>(3); boxObjectParams.Add(sTypeDataPtr); // pointer to type data boxObjectParams.Add(sValuePtr); // pointer to value boxObjectParams.Add(sReturnPtr); // pointer to destination new LIRInstructions.Call(pLIRMethod, AppDomain.System_GC_BoxObject, boxObjectParams, null); pLIRMethod.ReleaseLocal(sReturnPtr); pLIRMethod.ReleaseLocal(sTypeDataPtr); pLIRMethod.ReleaseLocal(sValuePtr); }
public override void ConvertToLIR(LIRMethod pLIRMethod) { var sElementCount = pLIRMethod.RequestLocal(Sources[0].GetTypeOfLocation()); Sources[0].LoadTo(pLIRMethod, sElementCount); var sTypeDataPtr = pLIRMethod.RequestLocal(AppDomain.System_GC_AllocateArrayOfType.LIRMethod.Parameters[0].Type); new LIRInstructions.Move(pLIRMethod, Destination.GetTypeOfLocation().MetadataLabel, sTypeDataPtr, sTypeDataPtr.Type); var sReturnPtr = pLIRMethod.RequestLocal(AppDomain.System_GC_AllocateArrayOfType.LIRMethod.Parameters[2].Type); Destination.LoadAddressTo(pLIRMethod, sReturnPtr); List<ISource> allocateArrayOfTypeParams = new List<ISource>(3); allocateArrayOfTypeParams.Add(sTypeDataPtr); // pointer to type data of array allocateArrayOfTypeParams.Add(sElementCount); // number of elements allocateArrayOfTypeParams.Add(sReturnPtr); // pointer to destination new LIRInstructions.Call(pLIRMethod, AppDomain.System_GC_AllocateArrayOfType, allocateArrayOfTypeParams, null); pLIRMethod.ReleaseLocal(sReturnPtr); pLIRMethod.ReleaseLocal(sTypeDataPtr); pLIRMethod.ReleaseLocal(sElementCount); }
public override void ConvertToLIR(LIRMethod pLIRMethod) { var sA = pLIRMethod.RequestLocal(Sources[0].GetTypeOfLocation()); Sources[0].LoadTo(pLIRMethod, sA); var sB = pLIRMethod.RequestLocal(Sources[1].GetTypeOfLocation()); Sources[1].LoadTo(pLIRMethod, sB); var dest = pLIRMethod.RequestLocal(Destination.GetTypeOfLocation()); LIRInstructions.MathOperation shiftOp = LIRInstructions.MathOperation.ShiftLeft; switch (ShiftType) { case IRShiftType.Left: shiftOp = LIRInstructions.MathOperation.ShiftLeft; break; case IRShiftType.Right: shiftOp = LIRInstructions.MathOperation.ShiftRight; break; case IRShiftType.RightSignExtended: shiftOp = LIRInstructions.MathOperation.ShiftRightSignExtended; break; default: throw new Exception(); } new LIRInstructions.Math(pLIRMethod, sA, sB, dest, shiftOp, dest.Type); pLIRMethod.ReleaseLocal(sA); pLIRMethod.ReleaseLocal(sB); Destination.StoreTo(pLIRMethod, dest); pLIRMethod.ReleaseLocal(dest); }
public override void ConvertToLIR(LIRMethod pLIRMethod) { var src = pLIRMethod.RequestLocal(Sources[0].GetTypeOfLocation()); Sources[0].LoadTo(pLIRMethod, src); var dest = pLIRMethod.RequestLocal(Destination.GetTypeOfLocation()); var canCastResult = pLIRMethod.RequestLocal(ParentMethod.Assembly.AppDomain.System_Boolean); var getTypeByGlobalTypeIDResult = pLIRMethod.RequestLocal(ParentMethod.Assembly.AppDomain.System_Type); // Call to Proton.Runtime.RuntimeHelpers.GetTypeByGlobalTypeID method, which returns the runtime System.Type new LIRInstructions.Call(pLIRMethod, ParentMethod.Assembly.AppDomain.Proton_Runtime_RuntimeHelpers_GetTypeByGlobalTypeID.LIRMethod, new List<ISource>(1) { (LIRImm)Type.GlobalTypeID }, getTypeByGlobalTypeIDResult); // Call to Proton.Runtime.RuntimeHelpers.CanCast method, which determines if an object can be cast to a type // TODO: can src be a value type? if so then we may need to box it first to pass it into this call as an object // TODO: this method should throw an exception if the Type is null, so we can skip testing castType before the call new LIRInstructions.Call(pLIRMethod, ParentMethod.Assembly.AppDomain.Proton_Runtime_RuntimeHelpers_CanCast.LIRMethod, new List<ISource>(2) { src, getTypeByGlobalTypeIDResult }, canCastResult); // Don't need getTypeByGlobalTypeIDResult anymore, we have canCastResult pLIRMethod.ReleaseLocal(getTypeByGlobalTypeIDResult); // Branch if we can cast, fall through if we cannot LIRInstructions.BranchTrue canCastBranchTrue = new LIRInstructions.BranchTrue(pLIRMethod, canCastResult); // Getting here means CanCast returned false, so the emitted code depends on ThrowExceptionOnFailure if (!ThrowExceptionOnFailure) { // If we don't throw an exception, then we are expected to set the destination to it's default value (null, 0, etc) new LIRInstructions.Move(pLIRMethod, dest.Type.Empty, dest, dest.Type); } // Now we jump past the previous BranchTrue logic below LIRInstructions.Branch cannotCastBranchOut = new LIRInstructions.Branch(pLIRMethod); // Getting here means CanCast returned true, so we need to set the BranchTrue target label canCastBranchTrue.SetTarget(new Label()); // And now copy src to dest, based on the destination casted type // TODO: Is it safe to use src here, after it was passed as a source to the Call above? new LIRInstructions.Move(pLIRMethod, src, dest, dest.Type); cannotCastBranchOut.SetTarget(new Label()); // We're done with src now, clean that up pLIRMethod.ReleaseLocal(src); if (!ThrowExceptionOnFailure) { // If we don't throw an exception, then we end up moving null to destination // so we can just do a normal cleanup and store here pLIRMethod.ReleaseLocal(canCastResult); Destination.StoreTo(pLIRMethod, dest); pLIRMethod.ReleaseLocal(dest); } else { // Branch if we can cast, fall through if we cannot canCastBranchTrue = new LIRInstructions.BranchTrue(pLIRMethod, canCastResult); // Getting here means we were not able to cast, so we need to cleanup before we throw an // exception, but we do not store anything to the destination pLIRMethod.ReleaseLocal(canCastResult); pLIRMethod.ReleaseLocal(dest); // TODO: Throw exception here, Branch is here to loop infinite, but this is not valid // it is here only as a placeholder, we need to prepare the object being thrown in a // way that the reference is held until an exception handler has the reference Label loopLabel = new Label(); new LIRInstructions.Comment(pLIRMethod, "TODO: Replace this infinite loop with Throw logic"); new LIRInstructions.Branch(pLIRMethod, loopLabel); // Getting here means we were able to cast, just do a normal cleanup canCastBranchTrue.SetTarget(new Label()); pLIRMethod.ReleaseLocal(canCastResult); Destination.StoreTo(pLIRMethod, dest); pLIRMethod.ReleaseLocal(dest); } // Fall through to next IR instruction if we had a successful cast, or failed without // throwing an exception }
public override void ConvertToLIR(LIRMethod pLIRMethod) { }
public override void ConvertToLIR(LIRMethod pLIRMethod) { throw new NotSupportedException(); }
public void CreateLIRMethod() { if ( this.Name == ".cctor" && ( ( this.Instructions.Count == 1 && this.Instructions[0].Opcode == IROpcode.Return ) || ( this.Instructions.Count == 2 && this.Instructions[0].Opcode == IROpcode.Nop && this.Instructions[1].Opcode == IROpcode.Return ) ) ) { Assembly.AppDomain.Methods.QueueForRemoval(this); return; } LIRMethod = new LIRMethod(Name, ReturnType ?? (LIRType)null); mParameters.ForEach(p => new LIRParameter(LIRMethod, p.Type)); mLocals.ForEach(l => new LIRLocal(LIRMethod, l.Type)); }
public override void ConvertToLIR(LIRMethod pLIRMethod) { switch (BranchCondition) { case IRBranchCondition.Always: new LIRInstructions.Branch(pLIRMethod, TargetIRInstruction.Label); break; case IRBranchCondition.True: { var sA = pLIRMethod.RequestLocal(Sources[0].GetTypeOfLocation()); Sources[0].LoadTo(pLIRMethod, sA); new LIRInstructions.BranchTrue(pLIRMethod, sA, TargetIRInstruction.Label); pLIRMethod.ReleaseLocal(sA); break; } case IRBranchCondition.False: { var sA = pLIRMethod.RequestLocal(Sources[0].GetTypeOfLocation()); Sources[0].LoadTo(pLIRMethod, sA); var sB = pLIRMethod.RequestLocal(ParentMethod.Assembly.AppDomain.System_Int32); new IRLinearizedLocation(this, IRLinearizedLocationType.ConstantI4) { ConstantI4 = new IRLinearizedLocation.ConstantI4LocationData() { Value = 0 } }.LoadTo(pLIRMethod, sB); var dest = pLIRMethod.RequestLocal(ParentMethod.Assembly.AppDomain.System_Int32); new LIRInstructions.Compare(pLIRMethod, sA, sB, dest, sA.Type, BranchCondition == IRBranchCondition.True ? LIRInstructions.CompareCondition.NotEqual : LIRInstructions.CompareCondition.Equal); pLIRMethod.ReleaseLocal(sA); pLIRMethod.ReleaseLocal(sB); new LIRInstructions.BranchTrue(pLIRMethod, dest, TargetIRInstruction.Label); pLIRMethod.ReleaseLocal(dest); break; } case IRBranchCondition.GreaterOrEqual: case IRBranchCondition.GreaterOrEqualUnsigned: case IRBranchCondition.Greater: case IRBranchCondition.GreaterUnsigned: case IRBranchCondition.LessOrEqual: case IRBranchCondition.LessOrEqualUnsigned: case IRBranchCondition.Less: case IRBranchCondition.LessUnsigned: case IRBranchCondition.NotEqualUnsigned: case IRBranchCondition.Equal: { var sA = pLIRMethod.RequestLocal(Sources[0].GetTypeOfLocation()); Sources[0].LoadTo(pLIRMethod, sA); var sB = pLIRMethod.RequestLocal(Sources[1].GetTypeOfLocation()); Sources[1].LoadTo(pLIRMethod, sB); var dest = pLIRMethod.RequestLocal(ParentMethod.Assembly.AppDomain.System_Int32); LIRInstructions.CompareCondition condition = LIRInstructions.CompareCondition.Equal; switch (BranchCondition) { case IRBranchCondition.GreaterOrEqual: case IRBranchCondition.GreaterOrEqualUnsigned: condition = LIRInstructions.CompareCondition.GreaterThanOrEqual; break; case IRBranchCondition.Greater: case IRBranchCondition.GreaterUnsigned: condition = LIRInstructions.CompareCondition.GreaterThan; break; case IRBranchCondition.LessOrEqual: case IRBranchCondition.LessOrEqualUnsigned: condition = LIRInstructions.CompareCondition.LessThanOrEqual; break; case IRBranchCondition.Less: case IRBranchCondition.LessUnsigned: condition = LIRInstructions.CompareCondition.LessThan; break; case IRBranchCondition.NotEqualUnsigned: condition = LIRInstructions.CompareCondition.NotEqual; break; case IRBranchCondition.Equal: condition = LIRInstructions.CompareCondition.Equal; break; default: throw new Exception("Something is rong here, we just were one of these...."); } new LIRInstructions.Compare(pLIRMethod, sA, sB, dest, sA.Type, condition); pLIRMethod.ReleaseLocal(sA); pLIRMethod.ReleaseLocal(sB); new LIRInstructions.BranchTrue(pLIRMethod, dest, TargetIRInstruction.Label); pLIRMethod.ReleaseLocal(dest); break; } default: throw new Exception("Unknown IRBranchCondition!"); } }
public override void ConvertToLIR(LIRMethod pLIRMethod) { if (Virtual) { if (Target.VirtualMethodIndex < 0) throw new Exception(); List<LIRLocal> paramSources = new List<LIRLocal>(Target.Parameters.Count); foreach (var v in Sources) { var s = pLIRMethod.RequestLocal(v.GetTypeOfLocation()); v.LoadTo(pLIRMethod, s); paramSources.Add(s); } ISource methodPointerSource = null; if (!Target.ParentType.IsInterface) { var s = pLIRMethod.RequestLocal(Sources[0].GetTypeOfLocation()); Sources[0].LoadTo(pLIRMethod, s); // Gets Object Pointer new LIRInstructions.Math(pLIRMethod, s, (LIRImm)VMConfig.PointerSizeForTarget, s, LIRInstructions.MathOperation.Subtract, s.Type); // Subtract sizeof pointer to get address of TypeData pointer new LIRInstructions.Move(pLIRMethod, new Indirect(s), s, s.Type); // Get TypeData Pointer new LIRInstructions.Move(pLIRMethod, new Indirect(s), s, s.Type); // Get VirtualMethodTree Pointer Array new LIRInstructions.Math(pLIRMethod, s, (LIRImm)(VMConfig.PointerSizeForTarget * Target.VirtualMethodIndex), s, LIRInstructions.MathOperation.Add, s.Type); // Get VirtualMethod Pointer Address new LIRInstructions.Move(pLIRMethod, new Indirect(s), s, s.Type); // Get VirtualMethod Pointer methodPointerSource = s; } else { #warning Interface Calls Not Yet Implemented. return; } if (Target.ReturnType != null) { var dest = pLIRMethod.RequestLocal(Destination.GetTypeOfLocation()); new LIRInstructions.CallIndirect(pLIRMethod, methodPointerSource, paramSources, dest); Destination.StoreTo(pLIRMethod, dest); pLIRMethod.ReleaseLocal(dest); } else { new LIRInstructions.CallIndirect(pLIRMethod, methodPointerSource, paramSources); } paramSources.ForEach(s => pLIRMethod.ReleaseLocal(s)); } else { List<LIRLocal> paramSources = new List<LIRLocal>(Target.Parameters.Count); foreach (var v in Sources) { var s = pLIRMethod.RequestLocal(v.GetTypeOfLocation()); v.LoadTo(pLIRMethod, s); paramSources.Add(s); } if (Target.ReturnType != null) { var dest = pLIRMethod.RequestLocal(Destination.GetTypeOfLocation()); new LIRInstructions.Call(pLIRMethod, Target.LIRMethod, paramSources, dest); Destination.StoreTo(pLIRMethod, dest); pLIRMethod.ReleaseLocal(dest); } else { new LIRInstructions.Call(pLIRMethod, Target.LIRMethod, paramSources); } paramSources.ForEach(s => pLIRMethod.ReleaseLocal(s)); } }
public override void ConvertToLIR(LIRMethod pLIRMethod) { if (ForceEmit) new LIRInstructions.Nop(pLIRMethod); }
private static void FinalMethodCleanup(LIRMethod m) { for (int i = 0; i < m.mInstructions.Count; i++) { if (m.mInstructions[i].OpCode == LIROpCode.Comment) m.mInstructions[i] = new Instructions.Dead(i); } KnownOptimizationPasses[KnownOptimizationPasses.Length - 1].Run(m); }
public void AddMethod(LIRMethod m) { mMethods.Add(m); m.CompileUnit = this; }
public void StoreTo(LIRMethod pParent, ISource pSource) { switch (Type) { case IRLinearizedLocationType.Local: new LIRInstructions.Move(pParent, pSource, pParent.Locals[Local.LocalIndex], pParent.Locals[Local.LocalIndex].Type); break; case IRLinearizedLocationType.Parameter: new LIRInstructions.Move(pParent, pSource, pParent.Parameters[Parameter.ParameterIndex], pParent.Parameters[Parameter.ParameterIndex].Type); break; case IRLinearizedLocationType.Field: { var obj = pParent.RequestLocal(Field.FieldLocation.GetTypeOfLocation()); Field.FieldLocation.LoadTo(pParent, obj); var foff = pParent.RequestLocal(ParentInstruction.ParentMethod.Assembly.AppDomain.System_UIntPtr); new LIRInstructions.Math(pParent, obj, (LIRImm)Field.Field.Offset, foff, LIRInstructions.MathOperation.Add, ParentInstruction.AppDomain.System_UIntPtr); pParent.ReleaseLocal(obj); new LIRInstructions.Move(pParent, pSource, new Indirect(foff), Field.Field.Type); pParent.ReleaseLocal(foff); break; } case IRLinearizedLocationType.Indirect: { var obj = pParent.RequestLocal(Indirect.AddressLocation.GetTypeOfLocation()); Indirect.AddressLocation.LoadTo(pParent, obj); new LIRInstructions.Move(pParent, pSource, new Indirect(obj), Indirect.Type); pParent.ReleaseLocal(obj); break; } case IRLinearizedLocationType.ArrayElement: { var arr = pParent.RequestLocal(ArrayElement.ArrayLocation.GetTypeOfLocation()); var idx = pParent.RequestLocal(ArrayElement.IndexLocation.GetTypeOfLocation()); ArrayElement.ArrayLocation.LoadTo(pParent, arr); ArrayElement.IndexLocation.LoadTo(pParent, idx); var off = pParent.RequestLocal(ParentInstruction.ParentMethod.Assembly.AppDomain.System_UIntPtr); new LIRInstructions.Math(pParent, idx, (LIRImm)ArrayElement.ElementType.StackSize, off, LIRInstructions.MathOperation.Multiply, ParentInstruction.ParentMethod.Assembly.AppDomain.System_UIntPtr); pParent.ReleaseLocal(idx); new LIRInstructions.Math(pParent, off, (LIRImm)0x04, off, LIRInstructions.MathOperation.Add, ParentInstruction.ParentMethod.Assembly.AppDomain.System_UIntPtr); new LIRInstructions.Math(pParent, off, arr, off, LIRInstructions.MathOperation.Add, ParentInstruction.ParentMethod.Assembly.AppDomain.System_UIntPtr); pParent.ReleaseLocal(arr); new LIRInstructions.Move(pParent, pSource, new Indirect(off), ArrayElement.ElementType); pParent.ReleaseLocal(off); break; } case IRLinearizedLocationType.StaticField: { EmitStaticConstructorCheck(pParent, StaticField.Field.ParentType, ParentInstruction.ParentMethod.ParentType); new LIRInstructions.Move(pParent, pSource, new Indirect(StaticField.Field.Label), StaticField.Field.Type); break; } case IRLinearizedLocationType.Null: case IRLinearizedLocationType.LocalAddress: case IRLinearizedLocationType.ParameterAddress: case IRLinearizedLocationType.ConstantI4: case IRLinearizedLocationType.ConstantI8: case IRLinearizedLocationType.ConstantR4: case IRLinearizedLocationType.ConstantR8: case IRLinearizedLocationType.FieldAddress: case IRLinearizedLocationType.StaticFieldAddress: case IRLinearizedLocationType.ArrayElementAddress: case IRLinearizedLocationType.ArrayLength: case IRLinearizedLocationType.FunctionAddress: case IRLinearizedLocationType.RuntimeHandle: case IRLinearizedLocationType.String: case IRLinearizedLocationType.SizeOf: throw new Exception("It's not possible to store to these!"); case IRLinearizedLocationType.Phi: throw new Exception("All phi's should have been eliminated by this point!"); default: throw new Exception("Unknown IRLinearizedLocationType!"); } }
public void LoadTo(LIRMethod pParent, IDestination pDestination) { switch (Type) { case IRLinearizedLocationType.Null: new LIRInstructions.Move(pParent, (LIRImm)0, pDestination, ParentInstruction.ParentMethod.Assembly.AppDomain.System_UIntPtr); break; case IRLinearizedLocationType.Local: new LIRInstructions.Move(pParent, pParent.Locals[Local.LocalIndex], pDestination, pParent.Locals[Local.LocalIndex].Type); break; case IRLinearizedLocationType.Parameter: new LIRInstructions.Move(pParent, pParent.Parameters[Parameter.ParameterIndex], pDestination, pParent.Parameters[Parameter.ParameterIndex].Type); break; case IRLinearizedLocationType.ConstantI4: new LIRInstructions.Move(pParent, (LIRImm)ConstantI4.Value, pDestination, ParentInstruction.ParentMethod.Assembly.AppDomain.System_Int32); break; case IRLinearizedLocationType.ConstantI8: new LIRInstructions.Move(pParent, (LIRImm)ConstantI8.Value, pDestination, ParentInstruction.ParentMethod.Assembly.AppDomain.System_Int64); break; case IRLinearizedLocationType.ConstantR4: new LIRInstructions.Move(pParent, (LIRImm)ConstantR4.Value, pDestination, ParentInstruction.ParentMethod.Assembly.AppDomain.System_Single); break; case IRLinearizedLocationType.ConstantR8: new LIRInstructions.Move(pParent, (LIRImm)ConstantR8.Value, pDestination, ParentInstruction.ParentMethod.Assembly.AppDomain.System_Double); break; case IRLinearizedLocationType.SizeOf: new LIRInstructions.Move(pParent, (LIRImm)SizeOf.Type.StackSize, pDestination, ParentInstruction.ParentMethod.Assembly.AppDomain.System_Int32); break; case IRLinearizedLocationType.Field: { var obj = pParent.RequestLocal(Field.FieldLocation.GetTypeOfLocation()); Field.FieldLocation.LoadTo(pParent, obj); var foff = pParent.RequestLocal(ParentInstruction.ParentMethod.Assembly.AppDomain.System_UIntPtr); new LIRInstructions.Math(pParent, obj, (LIRImm)Field.Field.Offset, foff, LIRInstructions.MathOperation.Add, ParentInstruction.ParentMethod.Assembly.AppDomain.System_UIntPtr); pParent.ReleaseLocal(obj); new LIRInstructions.Move(pParent, new Indirect(foff), pDestination, Field.Field.Type); pParent.ReleaseLocal(foff); break; } case IRLinearizedLocationType.FieldAddress: { var obj = pParent.RequestLocal(FieldAddress.FieldLocation.GetTypeOfLocation()); FieldAddress.FieldLocation.LoadTo(pParent, obj); var foff = pParent.RequestLocal(ParentInstruction.ParentMethod.Assembly.AppDomain.System_UIntPtr); new LIRInstructions.Math(pParent, obj, (LIRImm)FieldAddress.Field.Offset, foff, LIRInstructions.MathOperation.Add, ParentInstruction.ParentMethod.Assembly.AppDomain.System_UIntPtr); pParent.ReleaseLocal(obj); new LIRInstructions.Move(pParent, foff, pDestination, FieldAddress.Field.Type.GetManagedPointerType()); pParent.ReleaseLocal(foff); break; } case IRLinearizedLocationType.Indirect: { var obj = pParent.RequestLocal(Indirect.AddressLocation.GetTypeOfLocation()); Indirect.AddressLocation.LoadTo(pParent, obj); new LIRInstructions.Move(pParent, new Indirect(obj), pDestination, Indirect.Type); pParent.ReleaseLocal(obj); break; } case IRLinearizedLocationType.ArrayElement: { var arr = pParent.RequestLocal(ArrayElement.ArrayLocation.GetTypeOfLocation()); var idx = pParent.RequestLocal(ArrayElement.IndexLocation.GetTypeOfLocation()); ArrayElement.ArrayLocation.LoadTo(pParent, arr); ArrayElement.IndexLocation.LoadTo(pParent, idx); var off = pParent.RequestLocal(ParentInstruction.ParentMethod.Assembly.AppDomain.System_UIntPtr); new LIRInstructions.Math(pParent, idx, (LIRImm)ArrayElement.ElementType.StackSize, off, LIRInstructions.MathOperation.Multiply, ParentInstruction.ParentMethod.Assembly.AppDomain.System_UIntPtr); pParent.ReleaseLocal(idx); new LIRInstructions.Math(pParent, off, (LIRImm)0x04, off, LIRInstructions.MathOperation.Add, ParentInstruction.ParentMethod.Assembly.AppDomain.System_UIntPtr); new LIRInstructions.Math(pParent, off, arr, off, LIRInstructions.MathOperation.Add, ParentInstruction.ParentMethod.Assembly.AppDomain.System_UIntPtr); pParent.ReleaseLocal(arr); new LIRInstructions.Move(pParent, new Indirect(off), pDestination, ArrayElement.ElementType); pParent.ReleaseLocal(off); break; } case IRLinearizedLocationType.ArrayElementAddress: { var arr = pParent.RequestLocal(ArrayElementAddress.ArrayLocation.GetTypeOfLocation()); var idx = pParent.RequestLocal(ArrayElementAddress.IndexLocation.GetTypeOfLocation()); ArrayElementAddress.ArrayLocation.LoadTo(pParent, arr); ArrayElementAddress.IndexLocation.LoadTo(pParent, idx); var off = pParent.RequestLocal(ParentInstruction.ParentMethod.Assembly.AppDomain.System_UIntPtr); new LIRInstructions.Math(pParent, idx, (LIRImm)ArrayElementAddress.ElementType.StackSize, off, LIRInstructions.MathOperation.Multiply, ParentInstruction.ParentMethod.Assembly.AppDomain.System_UIntPtr); pParent.ReleaseLocal(idx); new LIRInstructions.Math(pParent, off, (LIRImm)0x04, off, LIRInstructions.MathOperation.Add, ParentInstruction.ParentMethod.Assembly.AppDomain.System_UIntPtr); new LIRInstructions.Math(pParent, off, arr, off, LIRInstructions.MathOperation.Add, ParentInstruction.ParentMethod.Assembly.AppDomain.System_UIntPtr); pParent.ReleaseLocal(arr); new LIRInstructions.Move(pParent, off, pDestination, ArrayElementAddress.ElementType.GetManagedPointerType()); pParent.ReleaseLocal(off); break; } case IRLinearizedLocationType.ArrayLength: { var arr = pParent.RequestLocal(ArrayLength.ArrayLocation.GetTypeOfLocation()); ArrayLength.ArrayLocation.LoadTo(pParent, arr); new LIRInstructions.Move(pParent, new Indirect(arr), pDestination, ParentInstruction.ParentMethod.Assembly.AppDomain.System_Int32); pParent.ReleaseLocal(arr); break; } case IRLinearizedLocationType.LocalAddress: new LIRInstructions.Move(pParent, pParent.Locals[Local.LocalIndex].AddressOf(), pDestination, pParent.Locals[Local.LocalIndex].Type); break; case IRLinearizedLocationType.ParameterAddress: new LIRInstructions.Move(pParent, pParent.Parameters[Parameter.ParameterIndex].AddressOf(), pDestination, pParent.Parameters[Parameter.ParameterIndex].Type); break; case IRLinearizedLocationType.String: { var dest = pParent.RequestLocal(ParentInstruction.AppDomain.System_String.GetManagedPointerType()); new LIRInstructions.Move(pParent, dest.AddressOf(), dest, dest.Type); var str = GetStringLiteral(pParent.CompileUnit, String.Value); var strLb = pParent.RequestLocal(ParentInstruction.AppDomain.System_UIntPtr); new LIRInstructions.Move(pParent, str.Label, strLb, strLb.Type); new LIRInstructions.Call(pParent, ParentInstruction.AppDomain.System_GC_AllocateStringFromUTF16, new List<ISource>() { strLb, dest }, null); pParent.ReleaseLocal(strLb); new LIRInstructions.Move(pParent, dest, pDestination, dest.Type); pParent.ReleaseLocal(dest); break; } case IRLinearizedLocationType.StaticField: { EmitStaticConstructorCheck(pParent, StaticField.Field.ParentType, ParentInstruction.ParentMethod.ParentType); new LIRInstructions.Move(pParent, new Indirect(StaticField.Field.Label), pDestination, StaticField.Field.Type); break; } case IRLinearizedLocationType.StaticFieldAddress: { EmitStaticConstructorCheck(pParent, StaticFieldAddress.Field.ParentType, ParentInstruction.ParentMethod.ParentType); new LIRInstructions.Move(pParent, StaticFieldAddress.Field.Label, pDestination, StaticField.Field.Type); break; } case IRLinearizedLocationType.FunctionAddress: { if (FunctionAddress.Virtual) { if (FunctionAddress.Method.VirtualMethodIndex < 0) throw new Exception("The requested method never got laid out in a virtual method tree!"); if (FunctionAddress.Method.ParentType.IsInterface) { #warning Loading the virtual function address of a method on an interface isn't supported yet! } else { var s = pParent.RequestLocal(Indirect.AddressLocation.GetTypeOfLocation()); Indirect.AddressLocation.LoadTo(pParent, s); // Gets Object Pointer new LIRInstructions.Math(pParent, s, (LIRImm)VMConfig.PointerSizeForTarget, s, LIRInstructions.MathOperation.Subtract, s.Type); // Subtract sizeof pointer to get address of TypeData pointer new LIRInstructions.Move(pParent, new Indirect(s), s, s.Type); // Get TypeData Pointer new LIRInstructions.Move(pParent, new Indirect(s), s, s.Type); // Get VirtualMethodTree Pointer Array new LIRInstructions.Math(pParent, s, (LIRImm)(VMConfig.PointerSizeForTarget * FunctionAddress.Method.VirtualMethodIndex), s, LIRInstructions.MathOperation.Add, s.Type); // Get VirtualMethod Pointer Address new LIRInstructions.Move(pParent, new Indirect(s), pDestination, s.Type); // Get VirtualMethod Pointer pParent.ReleaseLocal(s); } } else { new LIRInstructions.Move(pParent, FunctionAddress.Method.LIRMethod.Label, pDestination, ParentInstruction.AppDomain.System_UIntPtr); } break; } case IRLinearizedLocationType.RuntimeHandle: { if (RuntimeHandle.HandleType == ParentInstruction.AppDomain.System_RuntimeTypeHandle) { new LIRInstructions.Move(pParent, RuntimeHandle.TargetType.MetadataLabel, pDestination, RuntimeHandle.HandleType); } else if (RuntimeHandle.HandleType == ParentInstruction.AppDomain.System_RuntimeMethodHandle) { new LIRInstructions.Move(pParent, RuntimeHandle.TargetMethod.MetadataLabel, pDestination, RuntimeHandle.HandleType); } else if (RuntimeHandle.HandleType == ParentInstruction.AppDomain.System_RuntimeFieldHandle) { new LIRInstructions.Move(pParent, RuntimeHandle.TargetField.MetadataLabel, pDestination, RuntimeHandle.HandleType); } else { throw new Exception("Unknown RuntimeHandle HandleType!"); } break; } case IRLinearizedLocationType.Phi: throw new Exception("All phi's should have been eliminated by this point!"); default: throw new Exception("Unknown IRLinearizedLocationType!"); } }
public static void EmitStaticConstructorCheck(LIRMethod m, IRType targetType, IRType curType, bool forceEmit = false) { if (targetType.HasStaticConstructor && (forceEmit || targetType != curType)) { var con = targetType.StaticConstructor; if ( ( con.Instructions.Count == 1 && con.Instructions[0].Opcode == IROpcode.Return ) || ( con.Instructions.Count == 2 && con.Instructions[0].Opcode == IROpcode.Nop && con.Instructions[1].Opcode == IROpcode.Return ) ) { // We don't need a static constructor call } else { StaticConstructorCalledEmittableDataItem d = null; if (!KnownStaticConstructors.TryGetValue(targetType, out d)) { d = new StaticConstructorCalledEmittableDataItem(targetType); m.CompileUnit.AddData(d); KnownStaticConstructors.Add(targetType, d); } new LIRInstructions.Comment(m, "Static Constructor Check"); var c = m.RequestLocal(targetType.Assembly.AppDomain.System_Boolean); new LIRInstructions.Move(m, new Indirect(d.Label), c, targetType.Assembly.AppDomain.System_Boolean); Label called = new Label(); new LIRInstructions.BranchTrue(m, c, called); m.ReleaseLocal(c); new LIRInstructions.Move(m, (LIRImm)1, new Indirect(d.Label), targetType.Assembly.AppDomain.System_Boolean); new LIRInstructions.Call(m, con); m.MarkLabel(called); } } }
public abstract void ConvertToLIR(LIRMethod pLIRMethod);