private void LoadParameterInteger(InstructionNode node) { Debug.Assert(!node.Result.IsR4); Debug.Assert(!node.Result.IsR8); // TODO: Managed 64bit pointers if (!node.Result.Is64BitInteger) { return; } var result = node.Result; var operand1 = node.Operand1; MethodCompiler.SplitLongOperand(operand1, out Operand op0Low, out Operand op0High); var resultLow = AllocateVirtualRegister(TypeSystem.BuiltIn.I4); var resultHigh = AllocateVirtualRegister(TypeSystem.BuiltIn.I4); var context = new Context(node); context.SetInstruction(IRInstruction.LoadParameterInteger, InstructionSize.Size32, resultLow, op0Low); context.AppendInstruction(IRInstruction.LoadParameterInteger, InstructionSize.Size32, resultHigh, op0High); context.AppendInstruction(IRInstruction.To64, result, resultLow, resultHigh); }
private void Add64v2(Context context) { Debug.Assert(context.Result.Is64BitInteger); var result = context.Result; var operand1 = context.Operand1; var operand2 = context.Operand2; var resultLow = AllocateVirtualRegister(TypeSystem.BuiltIn.I4); var resultHigh = AllocateVirtualRegister(TypeSystem.BuiltIn.I4); var resultCarry = AllocateVirtualRegister(TypeSystem.BuiltIn.Boolean); var v1 = AllocateVirtualRegister(TypeSystem.BuiltIn.I4); var v2 = AllocateVirtualRegister(TypeSystem.BuiltIn.I4); var v3 = AllocateVirtualRegister(TypeSystem.BuiltIn.I4); var v4 = AllocateVirtualRegister(TypeSystem.BuiltIn.I4); MethodCompiler.SplitLongOperand(operand1, out Operand op1Low, out Operand op1High); MethodCompiler.SplitLongOperand(operand2, out Operand op2Low, out Operand op2High); context.SetInstruction(IRInstruction.GetLow64, v1, op1Low); context.AppendInstruction(IRInstruction.GetLow64, v2, op2Low); context.AppendInstruction2(IRInstruction.AddCarryOut32, resultLow, resultCarry, v1, v2); context.AppendInstruction(IRInstruction.GetHigh64, v3, op1High); context.AppendInstruction(IRInstruction.GetHigh64, v4, op2High); context.AppendInstruction(IRInstruction.AddCarryIn32, resultHigh, v3, v4, resultCarry); context.AppendInstruction(IRInstruction.To64, result, resultLow, resultHigh); }
void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, MethodCompiler methodCompiler) { Operand n = context.Operand1; Operand d = context.Operand2; Operand result = context.Result; Operand result2 = methodCompiler.CreateVirtualRegister(methodCompiler.TypeSystem.BuiltIn.U4); methodCompiler.SplitLongOperand(n, out Operand op0L, out Operand op0H); context.SetInstruction2(X86.Div32, result2, result, op0H, op0L, d); }
private static void Div(Context context, MethodCompiler methodCompiler) { Operand n = context.Operand1; Operand d = context.Operand2; Operand result = context.Result; Operand result2 = methodCompiler.CreateVirtualRegister(methodCompiler.TypeSystem.BuiltIn.U4); methodCompiler.SplitLongOperand(n, out Operand op0L, out Operand op0H); context.SetInstruction2(X86.Div32, result2, result, op0H, op0L, d); }
private static void RdMSR(Context context, MethodCompiler methodCompiler) { var result = context.Result; var operand1 = context.Operand1; methodCompiler.SplitLongOperand(result, out Operand resultLow, out Operand resultHigh); var EAX = Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.I8, GeneralPurposeRegister.EAX); var EDX = Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.I8, GeneralPurposeRegister.EDX); var ECX = Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.I8, GeneralPurposeRegister.ECX); context.SetInstruction(X64.Mov64, ECX, operand1); context.AppendInstruction2(X64.RdMSR, EAX, EDX, ECX); context.AppendInstruction(X64.Mov64, resultLow, EAX); context.AppendInstruction(X64.Mov64, resultHigh, EDX); }
private static void FrameCallRetU8(Context context, MethodCompiler methodCompiler) { var result = context.Result; var methodAddress = context.Operand1; var eax = Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.I8, GeneralPurposeRegister.EAX); var edx = Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.I8, GeneralPurposeRegister.EDX); methodCompiler.SplitLongOperand(result, out Operand op0L, out Operand op0H); context.SetInstruction(X64.Call, null, methodAddress); context.AppendInstruction(IRInstruction.Gen, eax); context.AppendInstruction(IRInstruction.Gen, edx); context.AppendInstruction(X64.Mov64, op0L, eax); context.AppendInstruction(X64.Mov64, op0H, edx); }
private void LoadParamZeroExtend8x64(Context context) { Debug.Assert(!context.Result.IsR4); Debug.Assert(!context.Result.IsR8); Debug.Assert(context.Result.Is64BitInteger); var result = context.Result; var operand1 = context.Operand1; MethodCompiler.SplitLongOperand(operand1, out Operand op0Low, out Operand _); var resultLow = AllocateVirtualRegister(TypeSystem.BuiltIn.I4); context.SetInstruction(IRInstruction.LoadParamZeroExtend8x32, resultLow, op0Low); context.AppendInstruction(IRInstruction.To64, result, resultLow, ConstantZero); }
private void StoreParam64(Context context) { var operand1 = context.Operand1; var operand2 = context.Operand2; var op0Low = AllocateVirtualRegister(TypeSystem.BuiltIn.I4); var op0High = AllocateVirtualRegister(TypeSystem.BuiltIn.I4); MethodCompiler.SplitLongOperand(operand1, out Operand op1Low, out Operand op1High); MethodCompiler.SplitLongOperand(operand2, out Operand _, out Operand _); SetGetLow64(context, op0Low, operand2); AppendGetHigh64(context, op0High, operand2); context.AppendInstruction(IRInstruction.StoreParam32, null, op1Low, op0Low); context.AppendInstruction(IRInstruction.StoreParam32, null, op1High, op0High); }
void IIntrinsicPlatformMethod.ReplaceIntrinsicCall(Context context, MethodCompiler methodCompiler) { var result = context.Result; var methodAddress = context.Operand1; var newESP = context.Operand2; var eax = Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EAX); var edx = Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EDX); methodCompiler.SplitLongOperand(result, out Operand op0L, out Operand op0H); context.SetInstruction(X86.CallReg, null, methodAddress); context.AppendInstruction(IRInstruction.Gen, eax); context.AppendInstruction(IRInstruction.Gen, edx); context.AppendInstruction(X86.Mov32, op0L, eax); context.AppendInstruction(X86.Mov32, op0H, edx); }
private void StoreParamInt64(Context context) { var result = context.Result; var operand1 = context.Operand1; var operand2 = context.Operand2; var op0Low = AllocateVirtualRegister(TypeSystem.BuiltIn.I4); var op0High = AllocateVirtualRegister(TypeSystem.BuiltIn.I4); MethodCompiler.SplitLongOperand(context.Operand1, out Operand op1Low, out Operand op1High); MethodCompiler.SplitLongOperand(context.Operand2, out Operand op2Low, out Operand op2High); context.SetInstruction(IRInstruction.GetLow64, op0Low, operand2); context.AppendInstruction(IRInstruction.GetHigh64, op0High, operand2); context.AppendInstruction(IRInstruction.StoreParamInt32, null, op1Low, op0Low); context.AppendInstruction(IRInstruction.StoreParamInt32, null, op1High, op0High); }
private void LoadParamSignExtend32x64(Context context) { Debug.Assert(!context.Result.IsR4); Debug.Assert(!context.Result.IsR8); Debug.Assert(context.Result.Is64BitInteger); var result = context.Result; var operand1 = context.Operand1; MethodCompiler.SplitLongOperand(operand1, out Operand op0Low, out Operand _); var resultLow = AllocateVirtualRegister(TypeSystem.BuiltIn.I4); var resultHigh = AllocateVirtualRegister(TypeSystem.BuiltIn.I4); context.SetInstruction(IRInstruction.LoadParam32, resultLow, op0Low); context.AppendInstruction(IRInstruction.ArithShiftRight32, resultHigh, resultLow, CreateConstant((byte)31)); context.AppendInstruction(IRInstruction.To64, result, resultLow, resultHigh); }
private static void FrameCallRetR8(Context context, MethodCompiler methodCompiler) { var result = context.Result; var methodAddress = context.Operand1; var eax = Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.I8, GeneralPurposeRegister.EAX); var edx = Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.I8, GeneralPurposeRegister.EDX); var xmm0 = Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.I8, SSE2Register.XMM0); methodCompiler.SplitLongOperand(result, out Operand op0L, out Operand op0H); context.SetInstruction(X64.Call, null, methodAddress); context.AppendInstruction(IRInstruction.Gen, xmm0); //context.AppendInstruction(X64.Movdi64ss, eax, xmm0); // FIXME: X64 context.AppendInstruction(X64.Pextrd64, edx, xmm0, methodCompiler.CreateConstant((byte)1)); context.AppendInstruction(X64.Mov64, op0L, eax); context.AppendInstruction(X64.Mov64, op0H, edx); }
private static void FrameCallRetR8(Context context, MethodCompiler methodCompiler) { var result = context.Result; var methodAddress = context.Operand1; var newESP = context.Operand2; var eax = Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EAX); var edx = Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EDX); var mmx1 = Operand.CreateCPURegister(methodCompiler.TypeSystem.BuiltIn.I4, SSE2Register.XMM0); methodCompiler.SplitLongOperand(result, out Operand op0L, out Operand op0H); context.SetInstruction(X86.Call, null, methodAddress); context.AppendInstruction(IRInstruction.Gen, mmx1); context.AppendInstruction(X86.Movdi32ss, eax, mmx1); // CHECK context.AppendInstruction(X86.Pextrd32, edx, mmx1, methodCompiler.CreateConstant((byte)1)); context.AppendInstruction(X86.Mov32, op0L, eax); context.AppendInstruction(X86.Mov32, op0H, edx); }
private Operand Map(Operand operand, Dictionary <Operand, Operand> map, InstructionNode callSiteNode) { if (operand == null) { return(null); } if (map.TryGetValue(operand, out Operand mappedOperand)) { return(mappedOperand); } if (operand.IsSymbol) { if (operand.IsString) { // FUTURE: explore operand re-use mappedOperand = Operand.CreateStringSymbol(operand.Name, operand.StringData, operand.Type.TypeSystem); } else if (operand.Method != null) { // FUTURE: explore operand re-use mappedOperand = Operand.CreateSymbolFromMethod(operand.Method, operand.Type.TypeSystem); } else if (operand.Name != null) { // FUTURE: explore operand re-use mappedOperand = Operand.CreateSymbol(operand.Type, operand.Name); } } else if (operand.IsParameter) { mappedOperand = callSiteNode.GetOperand(operand.Index + 1); } else if (operand.IsStackLocal) { mappedOperand = MethodCompiler.AddStackLocal(operand.Type, operand.IsPinned); } else if (operand.IsVirtualRegister) { mappedOperand = AllocateVirtualRegister(operand.Type); } else if (operand.IsStaticField) { // FUTURE: explore operand re-use mappedOperand = Operand.CreateStaticField(operand.Field, TypeSystem); } else if (operand.IsCPURegister) { mappedOperand = operand; } else if (operand.IsConstant) { mappedOperand = operand; } Debug.Assert(mappedOperand != null); if (operand.HasLongParent) { MethodCompiler.SplitLongOperand(mappedOperand); if (operand.IsLow) { mappedOperand = mappedOperand.Low; } else if (operand.IsHigh) { mappedOperand = mappedOperand.High; } } map.Add(operand, mappedOperand); return(mappedOperand); }
public void SplitLongOperand(Operand operand, out Operand operandLow, out Operand operandHigh) { MethodCompiler.SplitLongOperand(operand, out operandLow, out operandHigh); }
private static void WrMSR(Context context, MethodCompiler methodCompiler) { methodCompiler.SplitLongOperand(context.Operand2, out Operand resultLow, out Operand resultHigh); context.SetInstruction(X86.WrMSR, null, context.Operand1, resultLow, resultHigh); }