Example #1
0
        /// <summary>
        /// Pushes the given register to the operand stack
        /// </summary>
        /// <param name="register">The register</param>
        public void PushRegister(FloatRegister register)
        {
            this.operandTopIndex++;
            int stackOffset = GetStackOperandOffset(this.operandTopIndex);

            this.assembler.Move(
                new MemoryOperand(Register.BP, stackOffset),
                register);
        }
Example #2
0
        /// <summary>
        /// Pops an operand from the operand stack to the given register
        /// </summary>
        /// <param name="register">The register</param>
        public void PopRegister(FloatRegister register)
        {
            this.AssertNotEmpty();

            int stackOffset = GetStackOperandOffset(this.operandTopIndex);

            this.assembler.Move(
                register,
                new MemoryOperand(Register.BP, stackOffset));

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

            int stackOffset = GetStackOperandOffset(this.operandTopIndex);
            Assembler.Move(
                this.function.GeneratedCode,
                register,
                new MemoryOperand(Register.BP, stackOffset));

            this.operandTopIndex--;
        }
        /// <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, FloatRegister source,
            Action<IList<byte>, FloatRegister, FloatRegister> inst1,
            Action<IList<byte>, MemoryOperand, FloatRegister> 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.GetFloatRegisterForVirtual(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);
            }
        }
        /// <summary>
        /// Moves the content from a register to memory where the address is in a register + int offset
        /// </summary>
        /// <param name="codeGenerator">The code generator</param>
        /// <param name="destinationMemoryRegister">The destination memory register</param>
        /// <param name="offset">The offset</param>
        /// <param name="source">The source register</param>
        public static void MoveRegisterToMemoryRegisterWithIntOffset(
            IList<byte> codeGenerator, 
            Register destinationMemoryRegister,
            int offset,
            FloatRegister source)
        {
            codeGenerator.Add(0xf3);
            codeGenerator.Add(0x0f);
            codeGenerator.Add(0x11);

            if (destinationMemoryRegister != Register.SP)
            {
                codeGenerator.Add((byte)(0x80 | (byte)destinationMemoryRegister | (byte)((byte)source << 3)));
            }
            else
            {
                codeGenerator.Add((byte)(0x84 | (byte)((byte)source << 3)));
                codeGenerator.Add(0x24);
            }

            foreach (var component in BitConverter.GetBytes(offset))
            {
                codeGenerator.Add(component);
            }
        }
 /// <summary>
 /// Pops the given register
 /// </summary>
 /// <param name="codeGenerator">The code generator</param>
 /// <param name="register">The register</param>
 public static void PopRegister(IList<byte> codeGenerator, FloatRegister register)
 {
     MoveMemoryByRegisterToRegister(codeGenerator, register, Register.SP);               //movss <reg>, [rsp]
     AddByteToReg(codeGenerator, Register.SP, RegisterSize);    //add rsp, <reg size>
 }
        /// <summary>
        /// Divides the memory by the first register where the memory address is in the second register + offset
        /// </summary>
        /// <param name="codeGenerator">The code generator</param>
        /// <param name="destination">The destination memory register</param>
        /// <param name="offset">The memory offset</param>
        /// <param name="sourceMemoryRegister">The source register</param>
        public static void DivMemoryRegisterWithIntOffsetFromRegister(
            IList<byte> codeGenerator,
            FloatRegister destination,
            Register sourceMemoryRegister, int offset)
        {
            if (sourceMemoryRegister != Register.SP)
            {
                codeGenerator.Add(0xf3);
                codeGenerator.Add(0x0f);
                codeGenerator.Add(0x5e);
                codeGenerator.Add((byte)(0x80 | (byte)sourceMemoryRegister | (byte)destination << 3));
            }
            else
            {
                codeGenerator.Add(0xf3);
                codeGenerator.Add(0x0f);
                codeGenerator.Add(0x5e);
                codeGenerator.Add((byte)(0x84 | (byte)destination << 3));
                codeGenerator.Add(0x24);
            }

            foreach (var component in BitConverter.GetBytes(offset))
            {
                codeGenerator.Add(component);
            }
        }
Example #8
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>
        /// Moves the content from memory where the address is in the second register to the first register
        /// </summary>
        /// <param name="codeGenerator">The code generator</param>
        /// <param name="destination">The destination register</param>
        /// <param name="sourceMemoryRegister">The source memory register</param>
        public static void MoveMemoryByRegisterToRegister(IList<byte> codeGenerator, FloatRegister destination, Register sourceMemoryRegister)
        {
            codeGenerator.Add(0xf3);
            codeGenerator.Add(0x0f);
            codeGenerator.Add(0x10);

            switch (sourceMemoryRegister)
            {
                case Register.SP:
                    codeGenerator.Add((byte)(0x04 | (byte)((byte)destination << 3)));
                    codeGenerator.Add(0x24);
                    break;
                case Register.BP:
                    codeGenerator.Add((byte)(0x45 | (byte)((byte)destination << 3)));
                    codeGenerator.Add(0x00);
                    break;
                default:
                    codeGenerator.Add((byte)((byte)sourceMemoryRegister | (byte)((byte)destination << 3)));
                    break;
            }
        }
        /// <summary>
        /// Moves the at the given memory address relative to the end of the current instruction to the given register
        /// </summary>
        /// <param name="codeGenerator">The code generator</param>
        /// <param name="destination">The destination register</param>
        /// <param name="relativeAddress">The relative address</param>
        public static void MoveMemoryToRegister(IList<byte> codeGenerator, FloatRegister destination, int relativeAddress)
        {
            codeGenerator.Add(0xf3);
            codeGenerator.Add(0x0f);
            codeGenerator.Add(0x10);
            codeGenerator.Add((byte)(0x04 | (byte)((byte)destination << 3)));
            codeGenerator.Add(0x25);

            foreach (var component in BitConverter.GetBytes(relativeAddress))
            {
                codeGenerator.Add(component);
            }
        }
        /// <summary>
        /// Moves the content from a memory where the address is a register + int offset to a register
        /// </summary>
        /// <param name="codeGenerator">The code generator</param>
        /// <param name="destination">The destination register</param>
        /// <param name="sourceMemoryRegister">The source memory register</param>
        /// <param name="offset">The offset</param>
        public static void MoveMemoryRegisterWithIntOffsetToRegister(
            IList<byte> codeGenerator,
            FloatRegister destination,
            ExtendedRegister sourceMemoryRegister, int offset)
        {
            codeGenerator.Add(0xf3);
            codeGenerator.Add(0x41);
            codeGenerator.Add(0x0f);
            codeGenerator.Add(0x10);
            codeGenerator.Add((byte)(0x80 | (byte)sourceMemoryRegister | (byte)((byte)destination << 3)));

            foreach (var component in BitConverter.GetBytes(offset))
            {
                codeGenerator.Add(component);
            }
        }
 /// <summary>
 /// Pushes the given register
 /// </summary>
 /// <param name="codeGenerator">The code generator</param>
 /// <param name="register">The register</param>
 public static void PushRegister(IList<byte> codeGenerator, FloatRegister register)
 {
     SubByteFromRegister(codeGenerator, Register.SP, RegisterSize);   //sub rsp, <reg size>
     MoveRegisterToMemoryRegisterWithByteOffset(codeGenerator, Register.SP, 0, register);     //movss [rsp+0], <float reg>
 }
 /// <summary>
 /// Converts the second register into an int and stores the result in the first register
 /// </summary>
 /// <param name="codeGenerator">The code generator</param>
 /// <param name="destination">The destination</param>
 /// <param name="source">The source</param>
 public static void ConvertFloatToInt(IList<byte> codeGenerator, Register destination, FloatRegister source)
 {
     codeGenerator.Add(0xf3);
     codeGenerator.Add(0x48);
     codeGenerator.Add(0x0f);
     codeGenerator.Add(0x2c);
     codeGenerator.Add((byte)(0xc0 | (byte)source | (byte)((byte)destination << 3)));
 }
        /// <summary>
        /// Compares a register and a memory address
        /// </summary>
        /// <param name="codeGenerator">The code generator</param>
        /// <param name="register1">The first register</param>
        /// <param name="register2">The second register</param>
        /// <param name="register2MemoryOffset">The offset for register 2</param>
        public static void CompareRegisterToMemoryRegisterWithOffset(
            IList<byte> codeGenerator,
            FloatRegister register1,
            ExtendedRegister register2,
            int register2MemoryOffset)
        {
            codeGenerator.Add(0x41);
            codeGenerator.Add(0x0f);
            codeGenerator.Add(0x2e);
            codeGenerator.Add((byte)(0x80 | (byte)register2 | (byte)((byte)register1 << 3)));

            foreach (var component in BitConverter.GetBytes(register2MemoryOffset))
            {
                codeGenerator.Add(component);
            }
        }
 /// <summary>
 /// Compares the two registers
 /// </summary>
 /// <param name="codeGenerator">The code generator</param>
 /// <param name="register1">The first register</param>
 /// <param name="register2">The second register</param>
 public static void CompareRegisterToRegister(IList<byte> codeGenerator, FloatRegister register1, FloatRegister register2)
 {
     codeGenerator.Add(0x0f);
     codeGenerator.Add(0x2e);
     codeGenerator.Add((byte)(0xc0 | (byte)register2 | (byte)((byte)register1 << 3)));
 }
        /// <summary>
        /// Pushes the given register to the operand stack
        /// </summary>
        /// <param name="register">The register</param>
        public void PushRegister(FloatRegister register)
        {
            this.operandTopIndex++;
            int stackOffset = GetStackOperandOffset(this.operandTopIndex);

            //movss [rbp+<operand offset>], <reg>
            Assembler.Move(
                this.function.GeneratedCode,
                new MemoryOperand(Register.BP, stackOffset),
                register);
        }
 /// <summary>
 /// Moves the content from a register to memory where the address is in a register + offset
 /// </summary>
 /// <param name="codeGenerator">The code generator</param>
 /// <param name="destinationMemoryRegister">The destination memory register</param>
 /// <param name="offset">The offset</param>
 /// <param name="source">The source register</param>
 public static void MoveRegisterToMemoryRegisterWithOffset(
     IList<byte> codeGenerator,
     Register destinationMemoryRegister,
     int offset,
     FloatRegister source)
 {
     if (AssemblerHelpers.IsValidByteValue(offset))
     {
         MoveRegisterToMemoryRegisterWithByteOffset(codeGenerator, destinationMemoryRegister, (byte)offset, source);
     }
     else
     {
         MoveRegisterToMemoryRegisterWithIntOffset(codeGenerator, destinationMemoryRegister, offset, source);
     }
 }
        /// <summary>
        /// Moves the content from a register to memory where the address is in a register + byte offset
        /// </summary>
        /// <param name="codeGenerator">The code generator</param>
        /// <param name="destinationMemoryRegister">The destination memory register</param>
        /// <param name="offset">The offset</param>
        /// <param name="source">The source register</param>
        public static void MoveRegisterToMemoryRegisterWithByteOffset(
            IList<byte> codeGenerator,
            Register destinationMemoryRegister,
            byte offset,
            FloatRegister source)
        {
            codeGenerator.Add(0xf3);
            codeGenerator.Add(0x0f);
            codeGenerator.Add(0x11);

            if (destinationMemoryRegister != Register.SP)
            {
                codeGenerator.Add((byte)(0x40 | (byte)destinationMemoryRegister | (byte)((byte)source << 3)));
                codeGenerator.Add(offset);
            }
            else
            {
                codeGenerator.Add((byte)(0x44 | (byte)((byte)source << 3)));
                codeGenerator.Add(0x24);
                codeGenerator.Add(offset);
            }
        }
Example #19
0
 /// <summary>
 /// Creates a new float register
 /// </summary>
 /// <param name="floatRegister">The float register</param>
 public HardwareRegister(FloatRegister floatRegister)
 {
     this.IntRegister = Register.AX;
     this.Type = HardwareRegisterType.Float;
     this.FloatRegister = floatRegister;
 }
 /// <summary>
 /// Divides the second register from the first
 /// </summary>
 /// <param name="codeGenerator">The code generator</param>
 /// <param name="destination">The destination register</param>
 /// <param name="source">The source register</param>
 public static void DivRegisterFromRegister(IList<byte> codeGenerator, FloatRegister destination, FloatRegister source)
 {
     codeGenerator.Add(0xf3);
     codeGenerator.Add(0x0f);
     codeGenerator.Add(0x5e);
     codeGenerator.Add((byte)(0xc0 | (byte)source | (byte)((byte)destination << 3)));
 }