예제 #1
0
        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);
        }
예제 #2
0
        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);
            }
        }
예제 #3
0
        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));
        }
예제 #5
0
        /// <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);
            }
        }
예제 #6
0
        /// <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);
            }
        }