public void Emit(AILEmitter Context) { switch (Type) { case ConstType.Int32: Context.Generator.EmitLdc_I4(Value.I4); break; case ConstType.Int64: { if (Value.I8 >= int.MinValue && Value.I8 <= int.MaxValue) { Context.Generator.EmitLdc_I4(Value.I4); Context.Generator.Emit(OpCodes.Conv_I8); } else { Context.Generator.Emit(OpCodes.Ldc_I8, Value.I8); } break; } case ConstType.Single: Context.Generator.Emit(OpCodes.Ldc_R4, Value.R4); break; case ConstType.Double: Context.Generator.Emit(OpCodes.Ldc_R8, Value.R8); break; } }
private void EmitLdloc(AILEmitter Context, int Index, ARegisterType Type) { ARegister Reg = new ARegister(Index, Type); Context.Generator.EmitLdloc(Context.GetLocalIndex(Reg)); AILConv.EmitConv(Context, Context.GetLocalType(Reg), OperType); }
private void EmitLdfld(AILEmitter Context, int Index) { long IntInputs = Context.LocalAlloc.GetIntInputs(Context.GetILBlock(Index)); long VecInputs = Context.LocalAlloc.GetVecInputs(Context.GetILBlock(Index)); LoadLocals(Context, IntInputs, ARegisterType.Int); LoadLocals(Context, VecInputs, ARegisterType.Vector); }
private void EmitStfld(AILEmitter Context, int Index) { long IntOutputs = Context.LocalAlloc.GetIntOutputs(Context.GetILBlock(Index)); long VecOutputs = Context.LocalAlloc.GetVecOutputs(Context.GetILBlock(Index)); StoreLocals(Context, IntOutputs, ARegisterType.Int); StoreLocals(Context, VecOutputs, ARegisterType.Vector); }
private static void EmitMakeVec(AILEmitter Context, Type SrcType) { string MthdName = nameof(MakeScalar); Type[] MthdTypes = new Type[] { SrcType }; MethodInfo MthdInfo = typeof(AILConv).GetMethod(MthdName, MthdTypes); Context.Generator.Emit(OpCodes.Call, MthdInfo); }
public Label GetLabel(AILEmitter Context) { if (!HasLabel) { Lbl = Context.Generator.DefineLabel(); HasLabel = true; } return(Lbl); }
private void EmitLdloc(AILEmitter Context, int Index, ARegisterType RegisterType) { ARegister Reg = new ARegister(Index, RegisterType); Context.Generator.EmitLdloc(Context.GetLocalIndex(Reg)); if (RegisterType == ARegisterType.Int && RegisterSize == ARegisterSize.Int32) { Context.Generator.Emit(OpCodes.Conv_U4); } }
public void Add(IAILEmit ILEmitter) { if (ILEmitter is AILOpCodeLoad Ld && AILEmitter.IsRegIndex(Ld.Index)) { switch (Ld.IoType) { case AIoType.Flag: IntInputs |= ((1L << Ld.Index) << 32) & ~IntOutputs; break; case AIoType.Int: IntInputs |= (1L << Ld.Index) & ~IntOutputs; break; case AIoType.Vector: VecInputs |= (1L << Ld.Index) & ~VecOutputs; break; } }
public void Emit(AILEmitter Context) { switch (Type) { case ConstType.Int32: Context.Generator.EmitLdc_I4(Value.I4); break; case ConstType.Int64: Context.Generator.Emit(OpCodes.Ldc_I8, Value.I8); break; case ConstType.Single: Context.Generator.Emit(OpCodes.Ldc_R4, Value.R4); break; case ConstType.Double: Context.Generator.Emit(OpCodes.Ldc_R8, Value.R8); break; } }
public void Emit(AILEmitter Context) { switch (IoType & AIoType.Mask) { case AIoType.Arg: EmitLdarg(Context, Index); break; case AIoType.Fields: EmitLdfld(Context, Index); break; case AIoType.Flag: EmitLdloc(Context, Index, ARegisterType.Flag); break; case AIoType.Int: EmitLdloc(Context, Index, ARegisterType.Int); break; case AIoType.Vector: EmitLdloc(Context, Index, ARegisterType.Vector); break; } }
private void LoadLocals(AILEmitter Context, long Inputs, ARegisterType BaseType) { for (int Bit = 0; Bit < 64; Bit++) { long Mask = 1L << Bit; if ((Inputs & Mask) != 0) { ARegister Reg = AILEmitter.GetRegFromBit(Bit, BaseType); Context.Generator.EmitLdarg(ATranslatedSub.StateArgIdx); Context.Generator.Emit(OpCodes.Ldfld, Reg.GetField()); Context.Generator.EmitStloc(Context.GetLocalIndex(Reg)); } } }
public AILEmitterCtx(ATranslator Translator, ABlock[] Graph, ABlock Root) { this.Translator = Translator; this.Graph = Graph; this.Root = Root; string SubName = $"Sub{Root.Position:X16}"; Labels = new Dictionary <long, AILLabel>(); Emitter = new AILEmitter(Graph, Root, SubName); ILBlock = Emitter.GetILBlock(0); OpcIndex = -1; if (!AdvanceOpCode()) { throw new ArgumentException(nameof(Graph)); } }
public AILEmitterCtx( ATranslator Translator, ABlock[] Graph, ABlock Root, string SubName) { if (Translator == null) { throw new ArgumentNullException(nameof(Translator)); } if (Graph == null) { throw new ArgumentNullException(nameof(Graph)); } if (Root == null) { throw new ArgumentNullException(nameof(Root)); } this.Translator = Translator; this.Graph = Graph; this.Root = Root; Callees = new HashSet <long>(); Labels = new Dictionary <long, AILLabel>(); Emitter = new AILEmitter(Graph, Root, SubName); ILBlock = Emitter.GetILBlock(0); OpcIndex = -1; if (Graph.Length == 0 || !AdvanceOpCode()) { throw new ArgumentException(nameof(Graph)); } }
private void StoreLocals(AILEmitter Context, long Outputs, ARegisterType BaseType) { for (int Bit = 0; Bit < 64; Bit++) { long Mask = 1L << Bit; if ((Outputs & Mask) != 0) { ARegister Reg = AILEmitter.GetRegFromBit(Bit, BaseType); Context.Generator.EmitLdarg(ATranslatedSub.RegistersArgIdx); Context.Generator.EmitLdloc(Context.GetLocalIndex(Reg)); AILConv.EmitConv( Context, Context.GetLocalType(Reg), Context.GetFieldType(Reg.Type)); Context.Generator.Emit(OpCodes.Stfld, Reg.GetField()); } } }
public void Add(IAILEmit ILEmitter) { if (ILEmitter is AILBarrier) { //Those barriers are used to separate the groups of CIL //opcodes emitted by each ARM instruction. //We can only consider the new outputs for doing input elimination //after all the CIL opcodes used by the instruction being emitted. IntAwOutputs = IntOutputs; VecAwOutputs = VecOutputs; } else if (ILEmitter is AILOpCodeLoad Ld && AILEmitter.IsRegIndex(Ld.Index)) { switch (Ld.IoType) { case AIoType.Flag: IntInputs |= ((1L << Ld.Index) << 32) & ~IntAwOutputs; break; case AIoType.Int: IntInputs |= (1L << Ld.Index) & ~IntAwOutputs; break; case AIoType.Vector: VecInputs |= (1L << Ld.Index) & ~VecAwOutputs; break; } }
public AILEmitterCtx( ATranslatorCache Cache, ABlock[] Graph, ABlock Root, string SubName) { this.Cache = Cache ?? throw new ArgumentNullException(nameof(Cache)); this.Graph = Graph ?? throw new ArgumentNullException(nameof(Graph)); this.Root = Root ?? throw new ArgumentNullException(nameof(Root)); Labels = new Dictionary <long, AILLabel>(); Emitter = new AILEmitter(Graph, Root, SubName); ILBlock = Emitter.GetILBlock(0); OpcIndex = -1; if (Graph.Length == 0 || !AdvanceOpCode()) { throw new ArgumentException(nameof(Graph)); } }
public void Emit(AILEmitter Context) { switch (IoType) { case AIoType.Arg: Context.Generator.EmitLdarg(Index); break; case AIoType.Fields: { long IntInputs = Context.LocalAlloc.GetIntInputs(Context.GetILBlock(Index)); long VecInputs = Context.LocalAlloc.GetVecInputs(Context.GetILBlock(Index)); LoadLocals(Context, IntInputs, ARegisterType.Int); LoadLocals(Context, VecInputs, ARegisterType.Vector); break; } case AIoType.Flag: EmitLdloc(Context, Index, ARegisterType.Flag); break; case AIoType.Int: EmitLdloc(Context, Index, ARegisterType.Int); break; case AIoType.Vector: EmitLdloc(Context, Index, ARegisterType.Vector); break; } }
private void EmitLdarg(AILEmitter Context, int Index) { Context.Generator.EmitLdarg(Index); }
private static void EmitScalarLdfld(AILEmitter Context, string FldName) { Context.Generator.Emit(OpCodes.Ldfld, typeof(AVec).GetField(FldName)); }
public static void EmitConv(AILEmitter Context, Type SrcType, Type TgtType) { if (SrcType == TgtType) { //If both types are equal we don't need to cast anything. return; } if (SrcType.IsPrimitive) { if (TgtType == typeof(byte)) { Context.Generator.Emit(OpCodes.Conv_U1); } else if (TgtType == typeof(ushort)) { Context.Generator.Emit(OpCodes.Conv_U2); } else if (TgtType == typeof(uint)) { Context.Generator.Emit(OpCodes.Conv_U4); } else if (TgtType == typeof(ulong)) { Context.Generator.Emit(OpCodes.Conv_U8); } else if (TgtType == typeof(float)) { Context.Generator.Emit(OpCodes.Conv_R4); } else if (TgtType == typeof(double)) { Context.Generator.Emit(OpCodes.Conv_R8); } else if (TgtType == typeof(AVec)) { EmitMakeVec(Context, SrcType); } else { throw new ArgumentException(nameof(TgtType)); } } else if (SrcType == typeof(AVec)) { if (TgtType == typeof(float)) { EmitScalarLdfld(Context, nameof(AVec.S0)); } else if (TgtType == typeof(double)) { EmitScalarLdfld(Context, nameof(AVec.D0)); } else if (TgtType == typeof(byte)) { EmitScalarLdfld(Context, nameof(AVec.B0)); } else if (TgtType == typeof(ushort)) { EmitScalarLdfld(Context, nameof(AVec.H0)); } else if (TgtType == typeof(uint)) { EmitScalarLdfld(Context, nameof(AVec.W0)); } else if (TgtType == typeof(ulong)) { EmitScalarLdfld(Context, nameof(AVec.X0)); } else { throw new ArgumentException(nameof(TgtType)); } } else { throw new ArgumentException(nameof(SrcType)); } }
public void Emit(AILEmitter Context) { Context.Generator.Emit(ILOp); }
public void Emit(AILEmitter Context) { Context.Generator.MarkLabel(GetLabel(Context)); }
public void Emit(AILEmitter Context) { Context.Generator.Emit(OpCodes.Call, MthdInfo); }
public void Emit(AILEmitter Context) { Context.Generator.Emit(ILOp, Label.GetLabel(Context)); }