/// <summary>
        /// Pops an operand from the operand stack to the given register
        /// </summary>
        /// <param name="register">The register to pop to</param>
        public void PopRegister(IntRegister register)
        {
            this.AssertNotEmpty();

            int stackOffset = GetStackOperandOffset(this.operandTopIndex);
            Assembler.Move(
                this.function.GeneratedCode,
                register,
                new MemoryOperand(Register.BP, stackOffset)); //mov <reg>, [rbp+<operand offset>]

            this.operandTopIndex--;
        }
        /// <summary>
        /// Moves an argument to the stack
        /// </summary>
        /// <param name="compilationData">The compilation data</param>
        /// <param name="argumentIndex">The argument index</param>
        /// <param name="argumentType">The type of the argument</param>
        private void MoveArgumentToStack(CompilationData compilationData, int argumentIndex, VMType argumentType)
        {
            var generatedCode = compilationData.Function.GeneratedCode;
            int argStackOffset = -(1 + argumentIndex) * Assembler.RegisterSize;

            if (argumentIndex >= numRegisterArguments)
            {
                int stackArgumentIndex = this.GetStackArgumentIndex(compilationData, argumentIndex);

                var argStackSource = new MemoryOperand(
                    Register.BP,
                    Assembler.RegisterSize * (6 + stackArgumentIndex));

                HardwareRegister tmpReg;

                if (argumentType.IsPrimitiveType(PrimitiveTypes.Float))
                {
                    tmpReg = compilationData.VirtualAssembler.GetFloatSpillRegister();
                }
                else
                {
                    tmpReg = new IntRegister(Register.AX);
                }

                Assembler.Move(generatedCode, tmpReg, argStackSource);
                Assembler.Move(generatedCode, new MemoryOperand(Register.BP, argStackOffset), tmpReg);
            }
            else
            {
                //var argReg = floatArgumentRegisters[argumentIndex];
                HardwareRegister argReg;

                if (argumentType.IsPrimitiveType(PrimitiveTypes.Float))
                {
                    argReg = floatArgumentRegisters[argumentIndex];
                }
                else
                {
                    argReg = intArgumentRegisters[argumentIndex];
                }

                Assembler.Move(generatedCode, new MemoryOperand(Register.BP, argStackOffset), argReg);
            }
        }
Esempio n. 3
0
 /// <summary>
 /// Creates a new int register
 /// </summary>
 /// <param name="intRegister">The int register</param>
 public HardwareRegister(IntRegister intRegister)
 {
     this.IntRegister = intRegister;
     this.Type = HardwareRegisterType.Int;
     this.FloatRegister = FloatRegister.XMM0;
 }
        /// <summary>
        /// Pushes the given register to the operand stack
        /// </summary>
        /// <param name="register">The register</param>
        public void PushRegister(IntRegister register)
        {
            this.operandTopIndex++;
            int stackOffset = GetStackOperandOffset(this.operandTopIndex);

            //mov [rbp+<operand offset>], <reg>
            Assembler.Move(
                this.function.GeneratedCode,
                new MemoryOperand(Register.BP, stackOffset),
                register);
        }
        /// <summary>
        /// Generates code for an instruction with a virtual register destination and fixed register source
        /// </summary>
        /// <param name="destinationRegister">The destination register</param>
        /// <param name="source">The source</param>
        /// <param name="skipIfSame">Indicates if the instruction will be skipped of destination == source.</param>
        public void GenerateTwoRegisterFixedSourceInstruction(VirtualRegister destinationRegister, IntRegister source,
            Action<IList<byte>, IntRegister, IntRegister> inst1,
            Action<IList<byte>, MemoryOperand, IntRegister> inst2,
            bool skipIfSame = false)
        {
            var generatedCode = compilationData.Function.GeneratedCode;
            var regAlloc = compilationData.RegisterAllocation;
            int? opStack = compilationData.RegisterAllocation.GetStackIndex(destinationRegister);

            if (!opStack.HasValue)
            {
                var opReg = this.GetIntRegisterForVirtual(destinationRegister).Value;

                if (skipIfSame)
                {
                    if (opReg != source)
                    {
                        inst1(generatedCode, opReg, source);
                    }
                }
                else
                {
                    inst1(generatedCode, opReg, source);
                }
            }
            else
            {
                var opStackOffset = CalculateStackOffset(opStack.Value);
                inst2(generatedCode, new MemoryOperand(Register.BP, opStackOffset), source);
            }
        }