public EmulatedStateValue StackPop() { int index = evaluationStack.Count - 1; EmulatedStateValue value = evaluationStack[index]; evaluationStack.RemoveAt(index); return(value); }
public EmulatedStateValue(LLVMBuilderRef builder, BasicBlock origin, EmulatedStateValue otherValue) { TypeInfo = otherValue.TypeInfo; LLVMValueRef value = otherValue.Value; Value = LLVM.BuildPhi(builder, LLVM.TypeOf(value), string.Empty); LLVMValueRef[] incoming = { value }; LLVMBasicBlockRef[] basicBlocks = { origin.LLVMBlock }; LLVM.AddIncoming(Value, incoming, basicBlocks, 1); }
private LLVMValueRef ToSiInt(EmulatedStateValue value, LLVMBuilderRef builder, LLVMTypeRef newType, out TypeInfo typeInfo) { LLVMValueRef result; if (value.TypeInfo == TypeInfo.FloatingPrimitive) { result = LLVM.BuildFPToSI(builder, value.Value, newType, string.Empty); } else { result = LLVM.BuildIntCast(builder, value.Value, newType, string.Empty); } typeInfo = TypeInfo.SiIntPrimitive; return(result); }
public void Merge(LLVMBuilderRef builder, BasicBlock origin, EmulatedStateValue other) { LLVMValueRef[] incoming = { other.Value }; LLVMBasicBlockRef[] basicBlocks = { origin.LLVMBlock }; LLVM.AddIncoming(Value, incoming, basicBlocks, 1); }
public EmulatedStateValue(EmulatedStateValue other) : this(other.Value, other.TypeInfo) { }
public void Compile() { if (offsetToBasicBlock.Count > 0) { throw new InvalidOperationException("This method is already compiled."); } LLVMBuilderRef builder = LLVM.CreateBuilder(); // Add the entry point as the first basic block. { var it = MethodDef.Body.Instructions.GetEnumerator(); it.MoveNext(); AddBasicBlockAt(it.Current); } // Generate the entry point code for arguments. LLVM.PositionBuilderAtEnd(builder, offsetToBasicBlock[0].LLVMBlock); uint paramCount = LLVM.CountParams(FunctionValueRef); ArgumentValues = new EmulatedStateValue[paramCount]; int offset = MethodDef.HasThis ? 1 : 0; for (uint i = 0; i < paramCount; ++i) { LLVMValueRef param = LLVM.GetParam(FunctionValueRef, i); var valueRef = LLVM.BuildAlloca(builder, LLVM.TypeOf(param), "arg" + i); TypeInfo typeInfo; if (MethodDef.HasThis && i == 0) { typeInfo = TypeInfo.Reference; } else { typeInfo = MethodDef.Parameters[(int)i - offset].ParameterType.GetTypeInfo(); } ArgumentValues[i] = new EmulatedStateValue(valueRef, typeInfo); LLVM.BuildStore(builder, param, valueRef); } // Generate the entry point code for locals. { var locals = MethodDef.Body.Variables; LocalValues = new EmulatedStateValue[locals.Count]; for (int i = 0; i < locals.Count; ++i) { var cilType = locals[i].VariableType; var valueRef = LLVM.BuildAlloca(builder, TypeLookup.GetLLVMTypeRef(cilType), "local" + i); LocalValues[i] = new EmulatedStateValue(valueRef, cilType.GetTypeInfo()); } } // Now, find the basic blocks. { int currentBlockIndex = 0; foreach (Instruction insn in MethodDef.Body.Instructions) { if (HasBasicBlock(insn.Offset)) { // This is a fallthrough? if (currentBlockIndex != insn.Offset) { // Can't be fallthrough if previous instruction was an unconditional branch. if (!insn.Previous.IsUnconditionalBranchInstruction()) { AddOutgoingEdge(currentBlockIndex, insn.Offset); } } currentBlockIndex = insn.Offset; } if (insn.IsBranchInstruction()) { AddBasicBlockAt((Instruction)insn.Operand); AddOutgoingEdge(currentBlockIndex, ((Instruction)insn.Operand).Offset); AddBasicBlockAt(insn.Next); // Can't be fallthrough if current instruction was an unconditional branch. if (!insn.IsUnconditionalBranchInstruction()) { AddOutgoingEdge(currentBlockIndex, insn.Next.Offset); } } } } compileBasicBlock(builder, 0); LLVM.DisposeBuilder(builder); }
public void StackPush(EmulatedStateValue value) { Debug.Assert(value != null); evaluationStack.Add(value); }