/// <summary> /// Emits a conditional jump instruction to the specified position. /// </summary> /// <param name="condition">The condition code where the jump is executed.</param> /// <param name="blockIndex">The destination basic block index, used for disassembly.</param> /// <param name="target">The jump target position. For blocks, this is received from <see cref="StartBlock"/>.</param> public void EmitJcc(X64Condition condition, int blockIndex, int target) { _disassemblyWriter?.WriteLine($"{Indent}j{GetConditionName(condition)} LB_{blockIndex}"); _outputStream.WriteByte(0x0F); _outputStream.WriteByte((byte)(0x80 | (byte)condition)); Emit4ByteImmediate((uint)(target - _outputStream.Position - 4)); }
private void EmitConditionalJump(X64Condition condition, int targetBlock, int currentBlock) { var emitter = _peWriter.Emitter; if (targetBlock <= currentBlock) { emitter.EmitJcc(condition, targetBlock, _blockPositions[targetBlock]); } else { emitter.EmitJccWithFixup(condition, targetBlock, out var fixup); _fixupsForMethod.Add(fixup); } }
/// <summary> /// Emits a set byte instruction with the specified condition code. /// </summary> public void EmitSetcc(X64Condition condition, StorageLocation <X64Register> dest) { if (!dest.IsRegister) { throw new NotImplementedException("Setcc on stack"); } if (dest.Register >= X64Register.Xmm0) { throw new InvalidOperationException("Setcc on XMM register"); } _disassemblyWriter?.WriteLine($"{Indent}set{GetConditionName(condition)} {GetRegisterName(dest.Register, 1)}"); var(encodedReg, needB) = GetRegisterEncoding(dest.Register); EmitRexPrefixIfNeeded(false, false, false, needB); _outputStream.WriteByte(0x0F); _outputStream.WriteByte((byte)(0x90 | (byte)condition)); EmitModRmForSingleRegister(encodedReg); }
/// <summary> /// Emits a conditional jump instruction to an undetermined position and returns a <see cref="Fixup"/> /// value that can be used to fix the target position once it is known. /// </summary> /// <param name="condition">The condition code where the jump is executed.</param> /// <param name="blockIndex"> /// The destination basic block index. /// This will be used as a tag on the <see cref="Fixup"/>. /// </param> /// <param name="fixup">Information required for fixing the target later.</param> public void EmitJccWithFixup(X64Condition condition, int blockIndex, out Fixup fixup) { // The position points to the displacement, which is 2 bytes past the start of the instruction fixup = new Fixup(FixupType.RelativeJump, blockIndex, (int)_outputStream.Position + 2); EmitJcc(condition, blockIndex, 0); }
private void EmitConditionalSet(X64Condition condition, in StorageLocation <X64Register> destLocation)