public CreateVirtualRegister ( MosaType type ) : Operand | ||
type | MosaType | The signature type of the virtual register. |
리턴 | Operand |
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { Operand dest = context.Operand1; Operand value = context.Operand2; Operand v1 = methodCompiler.CreateVirtualRegister(dest.Type); Operand v2 = methodCompiler.CreateVirtualRegister(value.Type); Operand memory = Operand.CreateMemoryAddress(context.InvokeMethod.Signature.Parameters[1].ParameterType, v1, 0); context.SetInstruction(X86.Mov, v1, dest); context.AppendInstruction(X86.Mov, v2, value); context.AppendInstruction(X86.Mov, memory, v2); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { var dest = context.Operand1; var src = context.Operand2; var v0 = methodCompiler.CreateVirtualRegister(methodCompiler.TypeSystem.BuiltIn.Void); var v1 = methodCompiler.CreateVirtualRegister(methodCompiler.TypeSystem.BuiltIn.Void); var zero = Operand.CreateConstant(methodCompiler.TypeSystem, 0); var offset16 = Operand.CreateConstant(methodCompiler.TypeSystem, 16); context.SetInstruction(X86.MovupsLoad, InstructionSize.Size128, v0, dest, zero); context.AppendInstruction(X86.MovupsLoad, InstructionSize.Size128, v1, dest, offset16); context.AppendInstruction(X86.MovupsStore, InstructionSize.Size128, null, dest, zero, v0); context.AppendInstruction(X86.MovupsStore, InstructionSize.Size128, null, dest, offset16, v1); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { var result = context.Result; var address = methodCompiler.CreateVirtualRegister(methodCompiler.TypeSystem.BuiltIn.I4); context.SetInstruction(IRInstruction.Move, address, Operand.CreateUnmanagedSymbolPointer(methodCompiler.TypeSystem, Multiboot0695Stage.MultibootEBX)); context.AppendInstruction(IRInstruction.Move, result, Operand.CreateMemoryAddress(methodCompiler.TypeSystem.BuiltIn.I4, address, 0)); }
private static void PatchConstructor(BaseMethodCompiler methodCompiler) { Operand thisOperand = methodCompiler.Parameters[0]; Operand instanceOperand = methodCompiler.Parameters[1]; Operand methodPointerOperand = methodCompiler.Parameters[2]; var size = methodCompiler.Architecture.NativeInstructionSize; MosaField methodPointerField = GetField(methodCompiler.Method.DeclaringType, "methodPointer"); int methodPointerOffset = methodCompiler.TypeLayout.GetFieldOffset(methodPointerField); Operand methodPointerOffsetOperand = Operand.CreateConstant(methodCompiler.TypeSystem, methodPointerOffset); MosaField instanceField = GetField(methodCompiler.Method.DeclaringType, "instance"); int instanceOffset = methodCompiler.TypeLayout.GetFieldOffset(instanceField); Operand instanceOffsetOperand = Operand.CreateConstant(methodCompiler.TypeSystem, instanceOffset); var context = new Context(CreateMethodStructure(methodCompiler, true)); Operand v1 = methodCompiler.CreateVirtualRegister(thisOperand.Type); context.AppendInstruction(IRInstruction.Move, v1, thisOperand); context.AppendInstruction(IRInstruction.Store, size, null, v1, methodPointerOffsetOperand, methodPointerOperand); context.MosaType = methodPointerOperand.Type; context.AppendInstruction(IRInstruction.Store, size, null, v1, instanceOffsetOperand, instanceOperand); context.MosaType = instanceOperand.Type; context.AppendInstruction(IRInstruction.Return, methodCompiler.BasicBlocks.EpilogueBlock); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { Operand result = context.Result; Operand imm = methodCompiler.CreateVirtualRegister(methodCompiler.TypeSystem.BuiltIn.U4); context.SetInstruction(X86.MovCR, imm, Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.U4, control)); context.AppendInstruction(X86.Mov, result, imm); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { Operand operand1 = context.Operand1; Operand v1 = methodCompiler.CreateVirtualRegister(methodCompiler.TypeSystem.BuiltIn.U4); context.SetInstruction(X86.Mov, v1, operand1); context.AppendInstruction(X86.Mov, Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.U4, SegmentRegister.FS), v1); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { Operand result = context.Result; Operand edx = methodCompiler.CreateVirtualRegister(methodCompiler.TypeSystem.BuiltIn.Pointer); Operand operand = Operand.CreateMemoryAddress(context.Operand1.Type, edx, 0); context.SetInstruction(X86.Mov, edx, context.Operand1); context.AppendInstruction(X86.Mov, result, operand); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { Operand result = context.Result; Operand eax = methodCompiler.CreateVirtualRegister(methodCompiler.TypeSystem.BuiltIn.U4); context.AppendInstruction(X86.Add, eax, eax, Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.U4, GeneralPurposeRegister.ESP)); context.AppendInstruction(X86.Mov, eax, Operand.CreateMemoryAddress(methodCompiler.TypeSystem.BuiltIn.U4, eax, 0)); context.AppendInstruction(X86.Mov, result, eax); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { Operand result = context.Result; Operand v1 = methodCompiler.CreateVirtualRegister(methodCompiler.TypeSystem.BuiltIn.Pointer); Operand operand = Operand.CreateMemoryAddress(methodCompiler.TypeSystem.BuiltIn.U2, v1, 0); Debug.Assert(result.IsI4 | result.IsU4); context.SetInstruction(X86.Mov, v1, context.Operand1); context.AppendInstruction(X86.Movzx, InstructionSize.Size16, result, operand); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { var result = context.Result; var dividend = context.Operand1; var divisor = context.Operand2; if (result.IsR8) { var xmm1 = methodCompiler.CreateVirtualRegister(methodCompiler.TypeSystem.BuiltIn.R8); var xmm2 = methodCompiler.CreateVirtualRegister(methodCompiler.TypeSystem.BuiltIn.R8); var xmm3 = methodCompiler.CreateVirtualRegister(methodCompiler.TypeSystem.BuiltIn.R8); var size = InstructionSize.Size64; context.SetInstruction(X86.Divsd, size, xmm1, dividend, divisor); context.AppendInstruction(X86.Roundsd, size, xmm2, xmm1, Operand.CreateConstant(methodCompiler.TypeSystem.BuiltIn.U1, 0x3)); context.AppendInstruction(X86.Mulsd, size, xmm3, divisor, xmm2); context.AppendInstruction(X86.Subsd, size, result, dividend, xmm3); } else { var xmm1 = methodCompiler.CreateVirtualRegister(methodCompiler.TypeSystem.BuiltIn.R4); var xmm2 = methodCompiler.CreateVirtualRegister(methodCompiler.TypeSystem.BuiltIn.R4); var xmm3 = methodCompiler.CreateVirtualRegister(methodCompiler.TypeSystem.BuiltIn.R4); var size = InstructionSize.Size32; context.SetInstruction(X86.Divss, size, xmm1, dividend, divisor); context.AppendInstruction(X86.Roundss, size, xmm2, xmm1, Operand.CreateConstant(methodCompiler.TypeSystem.BuiltIn.U1, 0x3)); context.AppendInstruction(X86.Mulss, size, xmm3, divisor, xmm2); context.AppendInstruction(X86.Subss, size, result, dividend, xmm3); } }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { Operand n = context.Operand1; Operand d = context.Operand2; Operand result = context.Result; Operand result2 = methodCompiler.CreateVirtualRegister(methodCompiler.TypeSystem.BuiltIn.U4); Operand op0L, op0H; LongOperandTransformationStage.SplitLongOperand(methodCompiler, n, out op0L, out op0H); context.SetInstruction2(X86.Div, result2, result, op0H, op0L, d); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { var pointer = context.Operand1; var oldval = context.Operand2; var newval = context.Operand3; var result = context.Result; var eax = Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.U4, x86.GeneralPurposeRegister.EAX); var v1 = methodCompiler.CreateVirtualRegister(methodCompiler.TypeSystem.BuiltIn.U4); var mem1 = Operand.CreateMemoryAddress(pointer.Type, pointer, 0); context.SetInstruction(X86.Mov, v1, newval); context.AppendInstruction(X86.Mov, eax, oldval); context.AppendInstruction(X86.Lock); context.AppendInstruction(X86.CmpXchg, mem1, mem1, v1, eax); context.AppendInstruction(X86.Setcc, ConditionCode.Equal, result); }
/// <summary> /// Replaces the intrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, BaseMethodCompiler methodCompiler) { var pointer = context.Operand1; var oldval = context.Operand2; var newval = context.Operand3; var result = context.Result; var eax = Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.U4, GeneralPurposeRegister.EAX); var zero = Operand.CreateConstant(methodCompiler.TypeSystem, 0); var v1 = methodCompiler.CreateVirtualRegister(methodCompiler.TypeSystem.BuiltIn.U4); // Compare EAX with r/m32. If equal, ZF is set and r32 is loaded into r/m32. // Else, clear ZF and load r/m32 into EAX. context.SetInstruction(X86.Mov, eax, oldval); context.AppendInstruction(X86.Mov, v1, newval); context.AppendInstruction(X86.Lock); context.AppendInstruction(X86.CmpXchgLoad, InstructionSize.Size32, eax, eax, pointer, zero, v1); context.AppendInstruction(X86.Setcc, ConditionCode.Equal, result); }
private static void PatchConstructor(BaseMethodCompiler methodCompiler) { Operand thisOperand = methodCompiler.Parameters[0]; Operand instanceOperand = methodCompiler.Parameters[1]; Operand methodPointerOperand = methodCompiler.Parameters[2]; var size = methodCompiler.Architecture.NativeInstructionSize; MosaField methodPointerField = GetField(methodCompiler.Method.DeclaringType, "methodPointer"); int methodPointerOffset = methodCompiler.TypeLayout.GetFieldOffset(methodPointerField); Operand methodPointerOffsetOperand = Operand.CreateConstant(methodCompiler.TypeSystem, methodPointerOffset); MosaField instanceField = GetField(methodCompiler.Method.DeclaringType, "instance"); int instanceOffset = methodCompiler.TypeLayout.GetFieldOffset(instanceField); Operand instanceOffsetOperand = Operand.CreateConstant(methodCompiler.TypeSystem, instanceOffset); var context = new Context(CreateMethodStructure(methodCompiler, true)); Operand v1 = methodCompiler.CreateVirtualRegister(thisOperand.Type); Operand v2 = methodCompiler.CreateVirtualRegister(methodPointerOperand.Type); Operand v3 = methodCompiler.CreateVirtualRegister(instanceOperand.Type); context.AppendInstruction(IRInstruction.LoadInteger, v1, methodCompiler.StackFrame, thisOperand); context.AppendInstruction(IRInstruction.LoadInteger, v2, methodCompiler.StackFrame, methodPointerOperand); context.AppendInstruction(IRInstruction.LoadInteger, v3, methodCompiler.StackFrame, instanceOperand); context.AppendInstruction(IRInstruction.StoreInteger, size, null, v1, methodPointerOffsetOperand, v2); context.MosaType = methodPointerOperand.Type; context.AppendInstruction(IRInstruction.StoreInteger, size, null, v1, instanceOffsetOperand, v3); context.MosaType = instanceOperand.Type; context.AppendInstruction(IRInstruction.Return, methodCompiler.BasicBlocks.EpilogueBlock); }
/// <summary> /// Create platform compound move. /// </summary> /// <param name="context">The context.</param> /// <param name="destination">The destination.</param> /// <param name="source">The source.</param> /// <param name="size">The size.</param> public override void InsertCompoundMoveInstruction(BaseMethodCompiler compiler, Context context, Operand destination, Operand source, int size) { const int LargeAlignment = 16; int alignedSize = size - (size % NativeAlignment); int largeAlignedTypeSize = size - (size % LargeAlignment); Debug.Assert(size > 0); var src = source; var dest = destination; Debug.Assert(src.IsMemoryAddress && dest.IsMemoryAddress, context.ToString()); var srcReg = compiler.CreateVirtualRegister(destination.Type.TypeSystem.BuiltIn.I4); var dstReg = compiler.CreateVirtualRegister(destination.Type.TypeSystem.BuiltIn.I4); var tmp = compiler.CreateVirtualRegister(destination.Type.TypeSystem.BuiltIn.I4); var tmpLarge = Operand.CreateCPURegister(destination.Type.TypeSystem.BuiltIn.Void, SSE2Register.XMM1); context.AppendInstruction(X86.Lea, srcReg, src); context.AppendInstruction(X86.Lea, dstReg, dest); for (int i = 0; i < largeAlignedTypeSize; i += LargeAlignment) { // Large aligned moves allow 128bits to be copied at a time var memSrc = Operand.CreateMemoryAddress(destination.Type.TypeSystem.BuiltIn.Void, srcReg, i); var memDest = Operand.CreateMemoryAddress(destination.Type.TypeSystem.BuiltIn.Void, dstReg, i); context.AppendInstruction(X86.MovUPS, InstructionSize.Size128, tmpLarge, memSrc); context.AppendInstruction(X86.MovUPS, InstructionSize.Size128, memDest, tmpLarge); } for (int i = largeAlignedTypeSize; i < alignedSize; i += NativeAlignment) { context.AppendInstruction(X86.Mov, InstructionSize.Size32, tmp, Operand.CreateMemoryAddress(src.Type.TypeSystem.BuiltIn.I4, srcReg, i)); context.AppendInstruction(X86.Mov, InstructionSize.Size32, Operand.CreateMemoryAddress(dest.Type.TypeSystem.BuiltIn.I4, dstReg, i), tmp); } for (int i = alignedSize; i < size; i++) { context.AppendInstruction(X86.Mov, InstructionSize.Size8, tmp, Operand.CreateMemoryAddress(src.Type.TypeSystem.BuiltIn.I4, srcReg, i)); context.AppendInstruction(X86.Mov, InstructionSize.Size8, Operand.CreateMemoryAddress(dest.Type.TypeSystem.BuiltIn.I4, dstReg, i), tmp); } }
/// <summary> /// Create platform compound move. /// </summary> /// <param name="context">The context.</param> /// <param name="destination">The destination.</param> /// <param name="source">The source.</param> /// <param name="size">The size.</param> public override void InsertCompoundMoveInstruction(BaseMethodCompiler compiler, Context context, Operand destination, Operand source, int size) { Debug.Assert(size > 0 && size % 4 == 0); var src = source; var dest = destination; Debug.Assert(src.IsMemoryAddress && dest.IsMemoryAddress); var srcReg = compiler.CreateVirtualRegister(destination.Type.TypeSystem.BuiltIn.I4); var dstReg = compiler.CreateVirtualRegister(destination.Type.TypeSystem.BuiltIn.I4); var tmp = compiler.CreateVirtualRegister(destination.Type.TypeSystem.BuiltIn.I4); context.AppendInstruction(X86.Lea, srcReg, src); context.AppendInstruction(X86.Lea, dstReg, dest); for (int i = 0; i < size; i += 4) { context.AppendInstruction(X86.Mov, tmp, Operand.CreateMemoryAddress(src.Type.TypeSystem.BuiltIn.I4, srcReg, i)); context.AppendInstruction(X86.Mov, Operand.CreateMemoryAddress(dest.Type.TypeSystem.BuiltIn.I4, dstReg, i), tmp); } }
/// <summary> /// Create platform compound move. /// </summary> /// <param name="context">The context.</param> /// <param name="destination">The destination.</param> /// <param name="source">The source.</param> /// <param name="size">The size.</param> public override void InsertCompoundMoveInstruction(BaseMethodCompiler compiler, Context context, Operand destination, Operand source, int size) { int alignedSize = size - (size % NativeAlignment); Debug.Assert(size > 0); var src = source; var dest = destination; Debug.Assert(src.IsMemoryAddress && dest.IsMemoryAddress, context.ToString()); var srcReg = compiler.CreateVirtualRegister(destination.Type.TypeSystem.BuiltIn.I4); var dstReg = compiler.CreateVirtualRegister(destination.Type.TypeSystem.BuiltIn.I4); var tmp = compiler.CreateVirtualRegister(destination.Type.TypeSystem.BuiltIn.I4); context.AppendInstruction(X86.Lea, srcReg, src); context.AppendInstruction(X86.Lea, dstReg, dest); for (int i = 0; i < alignedSize; i += NativeAlignment) { context.AppendInstruction(X86.Mov, InstructionSize.Size32, tmp, Operand.CreateMemoryAddress(src.Type.TypeSystem.BuiltIn.I4, srcReg, i)); context.AppendInstruction(X86.Mov, InstructionSize.Size32, Operand.CreateMemoryAddress(dest.Type.TypeSystem.BuiltIn.I4, dstReg, i), tmp); } for (int i = alignedSize; i < size; i++) { context.AppendInstruction(X86.Mov, InstructionSize.Size8, tmp, Operand.CreateMemoryAddress(src.Type.TypeSystem.BuiltIn.I4, srcReg, i)); context.AppendInstruction(X86.Mov, InstructionSize.Size8, Operand.CreateMemoryAddress(dest.Type.TypeSystem.BuiltIn.I4, dstReg, i), tmp); } }
/// <summary> /// Create platform compound move. /// </summary> /// <param name="context">The context.</param> /// <param name="destination">The destination.</param> /// <param name="source">The source.</param> /// <param name="size">The size.</param> public override void InsertCompoundMoveInstruction(BaseMethodCompiler compiler, Context context, Operand destination, Operand source, int size) { Debug.Assert(size > 0); Debug.Assert(source.IsMemoryAddress && destination.IsMemoryAddress); const int LargeAlignment = 16; int alignedSize = size - (size % NativeAlignment); int largeAlignedTypeSize = size - (size % LargeAlignment); var srcReg = compiler.CreateVirtualRegister(destination.Type.TypeSystem.BuiltIn.I4); var dstReg = compiler.CreateVirtualRegister(destination.Type.TypeSystem.BuiltIn.I4); var tmp = compiler.CreateVirtualRegister(destination.Type.TypeSystem.BuiltIn.I4); var tmpLarge = Operand.CreateCPURegister(destination.Type.TypeSystem.BuiltIn.Void, SSE2Register.XMM1); context.AppendInstruction(X86.Lea, srcReg, source); context.AppendInstruction(X86.Lea, dstReg, destination); for (int i = 0; i < largeAlignedTypeSize; i += LargeAlignment) { // Large aligned moves allow 128bits to be copied at a time var index = Operand.CreateConstant(destination.Type.TypeSystem.BuiltIn.I4, i); context.AppendInstruction(X86.MovupsLoad, InstructionSize.Size128, tmpLarge, srcReg, index); context.AppendInstruction(X86.MovupsStore, InstructionSize.Size128, null, dstReg, index, tmpLarge); } for (int i = largeAlignedTypeSize; i < alignedSize; i += NativeAlignment) { var index = Operand.CreateConstant(destination.Type.TypeSystem.BuiltIn.I4, i); context.AppendInstruction(X86.MovLoad, InstructionSize.Size32, tmp, srcReg, index); context.AppendInstruction(X86.MovStore, InstructionSize.Size32, null, dstReg, index, tmp); } for (int i = alignedSize; i < size; i++) { var index = Operand.CreateConstant(destination.Type.TypeSystem.BuiltIn.I4, i); context.AppendInstruction(X86.MovLoad, InstructionSize.Size8, tmp, srcReg, index); context.AppendInstruction(X86.MovStore, InstructionSize.Size8, null, dstReg, index, tmp); } }