protected Operand MoveConstantToFloatRegisterOrImmediate(Context context, Operand operand, bool allowImmediate) { if (operand.IsVirtualRegister || operand.IsCPURegister) { return(operand); } if (allowImmediate) { var immediate = ConvertFloatToImm(operand); if (immediate != null) { return(immediate); } } // FUTURE: Load float bits (not double) into integer register, than fmov them into the floating point register (saves a memory load) var v1 = operand.IsR4 ? AllocateVirtualRegisterR4() : AllocateVirtualRegisterR8(); var symbol = operand.IsR4 ? Linker.GetConstantSymbol((float)operand.ConstantUnsigned64) : Linker.GetConstantSymbol((double)operand.ConstantUnsigned64); var label = Operand.CreateLabel(v1.Type, symbol.Name); context.InsertBefore().SetInstruction(ARMv8A32.Ldf, v1, label, Constant_0); return(v1); }
protected void FixConstantIntegerToFloat(InstructionNode node) { var source = node.Operand1; var result = node.Result; if (result.IsR4) { var symbol = MethodCompiler.Linker.GetConstantSymbol((float)source.ConstantUnsignedLongInteger); var label = Operand.CreateLabel(result.Type, symbol.Name); node.SetInstruction(MovssLoad, result, label, ConstantZero); } else if (result.IsR8) { var symbol = MethodCompiler.Linker.GetConstantSymbol((double)source.ConstantUnsignedLongInteger); var label = Operand.CreateLabel(result.Type, symbol.Name); node.SetInstruction(MovsdLoad, result, label, ConstantZero); } }
private Operand MoveConstantToFloatRegister(Context context, Operand operand) { if (!operand.IsConstant) { return(operand); } var v1 = operand.IsR4 ? AllocateVirtualRegisterR4() : AllocateVirtualRegisterR8(); var symbol = operand.IsR4 ? Linker.GetConstantSymbol(operand.ConstantFloat) : Linker.GetConstantSymbol(operand.ConstantDouble); var label = Operand.CreateLabel(v1.Type, symbol.Name); var instruction = operand.IsR4 ? (BaseInstruction)X64.MovssLoad : X64.MovsdLoad; context.InsertBefore().SetInstruction(instruction, v1, label, ConstantZero); return(v1); }
/// <summary> /// This function emits a constant variable into the read-only data section. /// </summary> /// <param name="operand">The operand.</param> /// <returns> /// An operand, which represents the reference to the read-only constant. /// </returns> protected Operand EmitFloatingPointConstant(Operand operand) { if (!operand.IsConstant || !operand.IsR) { return(operand); } LinkerSymbol symbol; if (operand.IsR4) { symbol = MethodCompiler.Linker.GetConstantSymbol(operand.ConstantSingleFloatingPoint); } else { symbol = MethodCompiler.Linker.GetConstantSymbol(operand.ConstantDoubleFloatingPoint); } return(Operand.CreateLabel(operand.Type, symbol.Name)); }
/// <summary> /// Emits the constant operands. /// </summary> /// <param name="node">The node.</param> protected void EmitFloatingPointConstants(InstructionNode node) { for (int i = 0; i < node.OperandCount; i++) { var operand = node.GetOperand(i); if (operand == null || !operand.IsConstant || !operand.IsR) { continue; } if (operand.IsUnresolvedConstant) { continue; } var v1 = AllocateVirtualRegister(operand.Type); var symbol = (operand.IsR4) ? MethodCompiler.Linker.GetConstantSymbol(operand.ConstantSingleFloatingPoint) : MethodCompiler.Linker.GetConstantSymbol(operand.ConstantDoubleFloatingPoint); var s1 = Operand.CreateLabel(operand.Type, symbol.Name); var before = new Context(node).InsertBefore(); if (operand.IsR4) { before.SetInstruction(X86.MovssLoad, InstructionSize.Size32, v1, s1, ConstantZero); } else { before.SetInstruction(X86.MovsdLoad, InstructionSize.Size64, v1, s1, ConstantZero); } node.SetOperand(i, v1); } }
/// <summary> /// Emits the constant operands. /// </summary> /// <param name="node">The node.</param> protected void EmitFloatingPointConstants(InstructionNode node) { for (int i = 0; i < node.OperandCount; i++) { var operand = node.GetOperand(i); if (operand == null || !operand.IsConstant || !operand.IsR) { continue; } if (operand.IsUnresolvedConstant) { continue; } var before = new Context(node).InsertBefore(); var v1 = AllocateVirtualRegister(operand.Type); if (operand.IsR4) { var symbol = Linker.GetConstantSymbol(operand.ConstantFloat); var label = Operand.CreateLabel(operand.Type, symbol.Name); before.SetInstruction(MovssLoad, v1, label, ConstantZero); } else { var symbol = Linker.GetConstantSymbol(operand.ConstantDouble); var label = Operand.CreateLabel(operand.Type, symbol.Name); before.SetInstruction(MovsdLoad, v1, label, ConstantZero); } node.SetOperand(i, v1); } }