public ILEmitterCtx( MemoryManager memory, TranslatorCache cache, TranslatorQueue queue, TranslationTier tier, Block graph) { Memory = memory ?? throw new ArgumentNullException(nameof(memory)); _cache = cache ?? throw new ArgumentNullException(nameof(cache)); _queue = queue ?? throw new ArgumentNullException(nameof(queue)); _currBlock = graph ?? throw new ArgumentNullException(nameof(graph)); Tier = tier; _labels = new Dictionary <long, ILLabel>(); _visitedBlocks = new Dictionary <Block, ILBlock>(); _visitedBlocks.Add(graph, new ILBlock()); _branchTargets = new Queue <Block>(); _ilBlocks = new List <ILBlock>(); _subPosition = graph.Position; ResetBlockState(); if (AdvanceOpCode()) { EmitSynchronization(); _ilBlock.Add(new ILOpCodeLoadState(_ilBlock, isSubEntry: true)); } }
private void EmitOpCode() { if (_currBlock == null) { return; } if (_opcIndex == 0) { MarkLabel(GetLabel(_currBlock.Position)); EmitSynchronization(); } //On AARCH32 mode, (almost) all instruction can be conditionally //executed, and the required condition is encoded on the opcode. //We handle that here, skipping the instruction if the condition //is not met. We can just ignore it when the condition is "Always", //because in this case the instruction is always going to be executed. //Condition "Never" is also ignored because this is a special encoding //used by some unconditional instructions. ILLabel lblSkip = null; if (CurrOp is OpCode32 op && op.Cond < Condition.Al) { lblSkip = new ILLabel(); EmitCondBranch(lblSkip, GetInverseCond(op.Cond)); } CurrOp.Emitter(this); if (lblSkip != null) { MarkLabel(lblSkip); //If this is the last op on the block, and there's no "next" block //after this one, then we have to return right now, with the address //of the next instruction to be executed (in the case that the condition //is false, and the branch was not taken, as all basic blocks should end with //some kind of branch). if (CurrOp == CurrBlock.GetLastOp() && CurrBlock.Next == null) { EmitStoreState(); EmitLdc_I8(CurrOp.Position + CurrOp.OpCodeSizeInBytes); Emit(OpCodes.Ret); } } _ilBlock.Add(new ILBarrier()); }
public void EmitOpCode() { if (_opcIndex == 0) { MarkLabel(GetLabel(CurrBlock.Position)); EmitSynchronization(); } CurrOp.Emitter(this); _ilBlock.Add(new ILBarrier()); }
private void EmitOpCode() { if (_currBlock == null) { return; } if (_opcIndex == 0) { MarkLabel(GetLabel(_currBlock.Position)); EmitSynchronization(); } CurrOp.Emitter(this); _ilBlock.Add(new ILBarrier()); }