private TranslatedSub TranslateHighCq(long position, ExecutionMode mode, bool isComplete) { Block graph = Decoder.DecodeSubroutine(_memory, position, mode); ILEmitterCtx context = new ILEmitterCtx(_memory, _cache, _queue, TranslationTier.Tier1, graph); ILBlock[] ilBlocks = context.GetILBlocks(); string subName = GetSubroutineName(position); bool isAarch64 = mode == ExecutionMode.Aarch64; isComplete &= !context.HasIndirectJump; ILMethodBuilder ilMthdBuilder = new ILMethodBuilder(ilBlocks, subName, isAarch64, isComplete); TranslatedSub subroutine = ilMthdBuilder.GetSubroutine(TranslationTier.Tier1, context.HasSlowCall); int ilOpCount = 0; foreach (ILBlock ilBlock in ilBlocks) { ilOpCount += ilBlock.Count; } ForceAheadOfTimeCompilation(subroutine); _cache.AddOrUpdate(position, subroutine, ilOpCount); return(subroutine); }
private void TranslateHighCq(long position, ExecutionMode mode) { Block graph = Decoder.DecodeSubroutine(_memory, position, mode); ILEmitterCtx context = new ILEmitterCtx(_cache, _queue, TranslationTier.Tier1, graph); ILBlock[] ilBlocks = context.GetILBlocks(); string subName = GetSubroutineName(position); ILMethodBuilder ilMthdBuilder = new ILMethodBuilder(ilBlocks, subName); TranslatedSub subroutine = ilMthdBuilder.GetSubroutine(TranslationTier.Tier1); int ilOpCount = 0; foreach (ILBlock ilBlock in ilBlocks) { ilOpCount += ilBlock.Count; } _cache.AddOrUpdate(position, subroutine, ilOpCount); ForceAheadOfTimeCompilation(subroutine); }
public void Emit(ILMethodBuilder context) { long intOutputs = context.LocalAlloc.GetIntOutputs(_block); long vecOutputs = context.LocalAlloc.GetVecOutputs(_block); StoreLocals(context, intOutputs, RegisterType.Int); StoreLocals(context, vecOutputs, RegisterType.Vector); }
public Label GetLabel(ILMethodBuilder context) { if (!_hasLabel) { _lbl = context.Generator.DefineLabel(); _hasLabel = true; } return(_lbl); }
private void EmitStloc(ILMethodBuilder context, int index, RegisterType registerType) { Register reg = new Register(index, registerType); if (registerType == RegisterType.Int && RegisterSize == RegisterSize.Int32) { context.Generator.Emit(OpCodes.Conv_U8); } context.Generator.EmitStloc(context.GetLocalIndex(reg)); }
public void Emit(ILMethodBuilder 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(ILMethodBuilder context) { switch (IoType) { case IoType.Arg: context.Generator.EmitStarg(Index); break; case IoType.Flag: EmitStloc(context, Index, RegisterType.Flag); break; case IoType.Int: EmitStloc(context, Index, RegisterType.Int); break; case IoType.Vector: EmitStloc(context, Index, RegisterType.Vector); break; } }
private TranslatedSub TranslateLowCq(long position, ExecutionMode mode) { Block block = Decoder.DecodeBasicBlock(_memory, position, mode); ILEmitterCtx context = new ILEmitterCtx(_cache, _queue, TranslationTier.Tier0, block); string subName = GetSubroutineName(position); ILMethodBuilder ilMthdBuilder = new ILMethodBuilder(context.GetILBlocks(), subName); TranslatedSub subroutine = ilMthdBuilder.GetSubroutine(TranslationTier.Tier0); return(_cache.GetOrAdd(position, subroutine, block.OpCodes.Count)); }
public void Emit(ILMethodBuilder context) { long intInputs = context.RegUsage.GetIntInputs(_block); long vecInputs = context.RegUsage.GetVecInputs(_block); if (Optimizations.AssumeStrictAbiCompliance && context.IsSubComplete) { intInputs = RegisterUsage.ClearCallerSavedIntRegs(intInputs, context.IsAarch64); vecInputs = RegisterUsage.ClearCallerSavedVecRegs(vecInputs, context.IsAarch64); } LoadLocals(context, intInputs, RegisterType.Int); LoadLocals(context, vecInputs, RegisterType.Vector); }
private void StoreLocals(ILMethodBuilder context, long outputs, RegisterType baseType) { for (int bit = 0; bit < 64; bit++) { long mask = 1L << bit; if ((outputs & mask) != 0) { Register reg = ILMethodBuilder.GetRegFromBit(bit, baseType); context.Generator.EmitLdarg(TranslatedSub.StateArgIdx); context.Generator.EmitLdloc(context.GetLocalIndex(reg)); context.Generator.Emit(OpCodes.Stfld, reg.GetField()); } } }
public void Add(IILEmit emitter) { if (emitter is ILBarrier) { //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 (emitter is ILOpCodeLoad ld && ILMethodBuilder.IsRegIndex(ld.Index)) { switch (ld.IoType) { case IoType.Flag: IntInputs |= ((1L << ld.Index) << 32) & ~IntAwOutputs; break; case IoType.Int: IntInputs |= (1L << ld.Index) & ~IntAwOutputs; break; case IoType.Vector: VecInputs |= (1L << ld.Index) & ~VecAwOutputs; break; } }
public void Emit(ILMethodBuilder context) { long intOutputs = context.RegUsage.GetIntOutputs(_block); long vecOutputs = context.RegUsage.GetVecOutputs(_block); if (Optimizations.AssumeStrictAbiCompliance && context.IsSubComplete) { intOutputs = RegisterUsage.ClearCallerSavedIntRegs(intOutputs, context.IsAarch64); vecOutputs = RegisterUsage.ClearCallerSavedVecRegs(vecOutputs, context.IsAarch64); } if (_callSub != null) { //Those register are assigned on the callee function, without //reading it's value first. We don't need to write them because //they are not going to be read on the callee. intOutputs &= ~_callSub.IntNiRegsMask; vecOutputs &= ~_callSub.VecNiRegsMask; } StoreLocals(context, intOutputs, RegisterType.Int); StoreLocals(context, vecOutputs, RegisterType.Vector); }
public void Emit(ILMethodBuilder context) { context.Generator.Emit(OpCodes.Call, _mthdInfo); }
public void Emit(ILMethodBuilder context) { context.Generator.Emit(OpCodes.Ldfld, Info); }
public void Emit(ILMethodBuilder context) { context.Generator.MarkLabel(GetLabel(context)); }
public void Emit(ILMethodBuilder context) { context.Generator.Emit(_ilOp, _label.GetLabel(context)); }
public void Emit(ILMethodBuilder context) { context.Generator.Emit(IsVirtual ? OpCodes.Callvirt : OpCodes.Call, Info); }
public void Emit(ILMethodBuilder context) { context.Generator.Emit(_ilOp); }