Ejemplo n.º 1
0
        // ------------------------------------------------------------------------

        public int Size()
        {
            switch (m_sort)
            {
            case Sort.Array:
                return(m_arraySize * m_arrayType.Size());

            case Sort.Struct:
                if (m_memberMap != null)
                {
                    int size = 0;

                    foreach (Symbol symbol in m_memberMap.Values)
                    {
                        size += symbol.Type.Size();
                    }

                    return(size);
                }
                else
                {
                    return(0);
                }

            case Sort.Union:
                if (m_memberMap == null)
                {
                    int size = 0;

                    foreach (Symbol symbol in m_memberMap.Values)
                    {
                        size = Math.Max(size, symbol.Type.Size());
                    }

                    return(size);
                }
                else
                {
                    return(0);
                }

            case Sort.Logical:
                return(TypeSize.SignedIntegerSize);

            default:
                return(TypeSize.Size(m_sort));
            }
        }
Ejemplo n.º 2
0
        private static object CheckValue(Type type, object value)
        {
            if (value is BigInteger)
            {
                BigInteger bigValue = (BigInteger)value;

                if (type.IsUnsigned() && (bigValue < 0))
                {
                    bigValue += TypeSize.GetMaxValue(type.Sort) + 1;
                }

                Error.Check((bigValue >= TypeSize.GetMinValue(type.Sort)) &&
                            (bigValue <= TypeSize.GetMaxValue(type.Sort)),
                            type + ": " + value, Message.Value_overflow);
                return(bigValue);
            }

            return(value);
        }
Ejemplo n.º 3
0
        public List <byte> ByteList()
        {
            object operand0 = m_operandArray[0],
                   operand1 = m_operandArray[1],
                   operand2 = m_operandArray[2];

            if ((Operator == AssemblyOperator.empty) ||
                (Operator == AssemblyOperator.label) ||
                (Operator == AssemblyOperator.comment))
            {
                return(new List <byte>());
            }
            else if (Operator == AssemblyOperator.define_address)
            {
                int         offset   = (int)operand1;
                List <byte> byteList = new List <byte>(new byte[TypeSize.PointerSize]);
                AssemblyCode.LoadByteList(byteList, 0, TypeSize.PointerSize,
                                          (BigInteger)offset);
                return(byteList);
            }
            else if (Operator == AssemblyOperator.define_zero_sequence)
            {
                int size = (int)operand0;
                return(new List <byte>(new byte[size]));
            }
            else if (Operator == AssemblyOperator.define_value)
            {
                Sort   sort  = (Sort)operand0;
                object value = operand1;

                if (sort == Sort.Pointer)
                {
                    List <byte> byteList = new List <byte>(new byte[TypeSize.PointerSize]);

                    if (value is string)
                    {
                        AssemblyCode.LoadByteList(byteList, 0, TypeSize.PointerSize,
                                                  BigInteger.Zero);
                    }
                    else if (value is StaticAddress)
                    {
                        StaticAddress staticAddress = (StaticAddress)value;
                        int           offset        = staticAddress.Offset;
                        AssemblyCode.LoadByteList(byteList, 0, TypeSize.PointerSize,
                                                  (BigInteger)offset);
                    }
                    else
                    {
                        AssemblyCode.LoadByteList(byteList, 0, TypeSize.PointerSize,
                                                  (BigInteger)value);
                    }

                    return(byteList);
                }
                else if (sort == Sort.Float)
                {
                    float floatValue = (float)((decimal)operand0);
                    return(new List <byte>(BitConverter.GetBytes(floatValue)));
                }
                else if ((sort == Sort.Double) || (sort == Sort.Long_Double))
                {
                    double doubleValue = (double)((decimal)value);
                    return(new List <byte>(BitConverter.GetBytes(doubleValue)));
                }
                else if (sort == Sort.String)
                {
                    string      text     = (string)value;
                    List <byte> byteList = new List <byte>();

                    foreach (char c in text)
                    {
                        byteList.Add((byte)c);
                    }

                    byteList.Add((byte)0);
                    return(byteList);
                }
                else
                {
                    int         size     = TypeSize.Size(sort);
                    List <byte> byteList = new List <byte>(new byte[size]);
                    AssemblyCode.LoadByteList(byteList, 0, size, (BigInteger)value);
                    return(byteList);
                }
            }
            else if (IsJumpRegister() || IsCallRegister())
            {
                Register register = (Register)operand0;
                return(LookupByteArray(AssemblyOperator.jmp, register));
            }
            else if (IsCallNotRegister())
            {
                List <byte> byteList =
                    LookupByteArray(AssemblyOperator.jmp, TypeSize.PointerSize);
                LoadByteList(byteList, byteList.Count - TypeSize.PointerSize,
                             TypeSize.PointerSize, 0);
                return(byteList);
            }
            else if (Operator == AssemblyOperator.return_address)
            {
                Register    register = (Register)operand0;
                int         offset   = (int)operand1;
                int         size     = SizeOfValue(offset);
                int         address  = (int)((BigInteger)operand2);
                List <byte> byteList =
                    LookupByteArray(AssemblyOperator.mov_word, register,
                                    size, TypeSize.PointerSize);
                LoadByteList(byteList, byteList.Count - (size + TypeSize.PointerSize),
                             size, offset);
                LoadByteList(byteList, byteList.Count - TypeSize.PointerSize,
                             TypeSize.PointerSize, address);
                return(byteList);
            }
            else if (IsRelationNotRegister() || IsJumpNotRegister())
            {
                int         address  = (int)operand0;
                int         size     = ((address >= -128) && (address <= 127)) ? 1 : 2;
                List <byte> byteList = LookupByteArray(Operator, size);
                LoadByteList(byteList, byteList.Count - size, size, address);
                return(byteList);
            }



            // mov ax, bx
            else if ((operand0 is Register) && (operand1 is Register) && (operand2 == null))
            {
                Register toRegister   = (Register)operand0,
                         fromRegister = (Register)operand1;
                return(LookupByteArray(Operator, toRegister, fromRegister));
            }
            // mov ax, global
            else if ((operand0 is Register) && (operand1 is string) && (operand2 == null))
            {
                Register    register = (Register)operand0;
                int         size     = SizeOfRegister(register);
                List <byte> byteList = LookupByteArray(Operator, register, size);
                LoadByteList(byteList, byteList.Count - size, size, 0);
                return(byteList);
            }
            // mov ax, 123
            else if ((operand0 is Register) && (operand1 is BigInteger) && (operand2 == null))
            {
                Register   register = (Register)operand0;
                BigInteger value    = (BigInteger)operand1;
                int        size     = ((Operator == AssemblyOperator.mov) ||
                                       (Operator == AssemblyOperator.and))
                   ? SizeOfRegister(register) : SizeOfValue(value);
                List <byte> byteList = LookupByteArray(Operator, register, size);
                LoadByteList(byteList, byteList.Count - size, size, value);
                return(byteList);
            }



            /*//	cmp global, bx
             * else if (((operand0 is string) || (operand0 == null)) &&
             *       (operand1 is Register) && (operand2 == null)) {
             * Assert.ErrorXXX(Operator == AssemblyOperator.cmp);
             * Register fromRegister = (Register) operand1;
             * List<byte> byteList = LookupByteArray(Operator, null, fromRegister);
             * return byteList;
             * }
             *
             * //	cmp global, 123
             * else if (((operand0 is string) || (operand0 == null)) &&
             *       (operand1 is BigInteger) && (operand2 == null)) {
             * Assert.ErrorXXX(Operator == AssemblyOperator.cmp);
             * BigInteger value = (BigInteger) operand1;
             * int size = SizeOfValue(value);
             * List<byte> byteList = LookupByteArray(Operator, null, size);
             * LoadByteList(byteList, byteList.Count - size, size, value);
             * return byteList;
             * }
             *
             * //	cmp global, global
             * else if (((operand0 is string) || (operand0 == null)) &&
             *       ((operand1 is string) || (operand1 == null)) &&
             *       (operand2 == null)) {
             * Assert.ErrorXXX(Operator == AssemblyOperator.cmp);
             * return LookupByteArray(Operator, TypeSize.PointerSize, TypeSize.PointerSize);
             * }*/



            // mov [bp + 2], ax
            else if ((operand0 is Register) && (operand1 is int) &&
                     (operand2 is Register))
            {
                Register baseRegister = (Register)operand0,
                         fromRegister = (Register)operand2;
                int         offset    = (int)operand1;
                int         size      = SizeOfValue(offset);
                List <byte> byteList  =
                    LookupByteArray(Operator, baseRegister, size, fromRegister);
                LoadByteList(byteList, byteList.Count - size, size, offset);
                return(byteList);
            }
            // mov [bp + 2], global
            else if ((operand0 is Register) && (operand1 is int) &&
                     (operand2 is string))
            {
                Register    baseRegister = (Register)operand0;
                int         offset       = (int)operand1;
                int         offsetSize   = SizeOfValue(offset);
                List <byte> byteList     =
                    LookupByteArray(Operator, baseRegister, offsetSize,
                                    TypeSize.PointerSize);
                LoadByteList(byteList, byteList.Count -
                             (offsetSize + TypeSize.PointerSize), offsetSize, offset);
                LoadByteList(byteList, byteList.Count - TypeSize.PointerSize,
                             TypeSize.PointerSize, 0);
                return(byteList);
            }
            // mov [bp + 2], 123
            else if ((operand0 is Register) && (operand1 is int) &&
                     (operand2 is BigInteger))
            {
                Register   baseRegister = (Register)operand0;
                int        offset       = (int)operand1;
                BigInteger value        = (BigInteger)operand2;
                int        offsetSize   = SizeOfValue(offset),
                           valueSize    = SizeOfValue(value, Operator);
                List <byte> byteList    =
                    LookupByteArray(Operator, baseRegister, offsetSize, valueSize);
                LoadByteList(byteList, byteList.Count - (offsetSize + valueSize),
                             offsetSize, offset);
                LoadByteList(byteList, byteList.Count - valueSize,
                             valueSize, value);
                return(byteList);
            }



            // mov [global + 4], ax
            else if (((operand0 is string) || (operand0 == null)) &&
                     (operand1 is int) && (operand2 is Register))
            {
                int         offset       = (int)operand1;
                Register    fromRegister = (Register)operand2;
                List <byte> byteList     =
                    LookupByteArray(Operator, null, TypeSize.PointerSize, fromRegister);
                LoadByteList(byteList, byteList.Count - TypeSize.PointerSize,
                             TypeSize.PointerSize, offset);
                return(byteList);
            }
            // mov [global + 4], 123
            else if (((operand0 is string) || (operand0 == null)) &&
                     (operand1 is int) && (operand2 is BigInteger))
            {
                int         offset    = (int)operand1;
                BigInteger  value     = (BigInteger)operand2;
                int         valueSize = SizeOfValue(value, Operator);
                List <byte> byteList  =
                    LookupByteArray(Operator, null, TypeSize.PointerSize, valueSize);
                LoadByteList(byteList, byteList.Count - (TypeSize.PointerSize +
                                                         valueSize), TypeSize.PointerSize, offset);
                LoadByteList(byteList, byteList.Count - valueSize,
                             valueSize, value);
                return(byteList);
            }



            // mov ax, [bp + 2]
            else if ((operand0 is Register) && (operand1 is Register) &&
                     (operand2 is int))
            {
                Register toRegister   = (Register)operand0,
                         baseRegister = (Register)operand1;
                int         offset    = (int)operand2;
                int         size      = SizeOfValue(offset);
                List <byte> byteList  =
                    LookupByteArray(Operator, toRegister, baseRegister, size);
                LoadByteList(byteList, byteList.Count - size, size, offset);
                return(byteList);
            }

            /*// cmp global, [bp + 2]
             * else if (((operand0 is string) || (operand0 == null)) &&
             *       (operand1 is Register) && (operand2 is int)) {
             * Assert.ErrorXXX(Operator == AssemblyOperator.cmp);
             * Register baseRegister = (Register) operand1;
             * int offset = (int) operand2;
             * int size = SizeOfValue(offset);
             * List<byte> byteList =
             *  LookupByteArray(Operator, null, baseRegister, size);
             * LoadByteList(byteList, byteList.Count - size, size, offset);
             * return byteList;
             * }*/

            // mov ax, [global + 4]
            else if ((operand0 is Register) && ((operand1 is string) ||
                                                (operand1 == null)) && (operand2 is int))
            {
                Register    toRegister = (Register)operand0;
                int         offset     = (int)operand2;
                List <byte> byteList   =
                    LookupByteArray(Operator, toRegister, null, TypeSize.PointerSize);
                LoadByteList(byteList, byteList.Count - TypeSize.PointerSize,
                             TypeSize.PointerSize, offset);
                return(byteList);
            }


            /*// cmp global, [global + 4]
             * else if (((operand0 is string) || (operand0 == null)) &&
             *       ((operand1 is string) || (operand1 == null)) &&
             *       (operand2 is int)) {
             * int offset = (int) operand2;
             * List<byte> byteList =
             *  LookupByteArray(Operator, null, null, TypeSize.PointerSize);
             * LoadByteList(byteList, byteList.Count - TypeSize.PointerSize,
             *             TypeSize.PointerSize, offset);
             * return byteList;
             * }*/



            // inc ax
            else if ((operand0 is Register) && (operand1 == null) && (operand2 == null))
            {
                Register register = (Register)operand0;
                return(LookupByteArray(Operator, register));
            }
            // int 33
            else if ((operand0 is BigInteger) && (operand1 == null) && (operand2 == null))
            {
                BigInteger  value    = (BigInteger)operand0;
                int         size     = SizeOfValue(value);
                List <byte> byteList = LookupByteArray(Operator, size);
                LoadByteList(byteList, byteList.Count - size, size, value);
                return(byteList);
            }



            // inc [bp + 2]
            else if ((operand0 is Register) && (operand1 is int) && (operand2 == null))
            {
                Register    baseRegister = (Register)operand0;
                int         offset       = (int)operand1;
                int         size         = SizeOfValue(offset);
                List <byte> byteList     = LookupByteArray(Operator, baseRegister, size);
                LoadByteList(byteList, byteList.Count - size, size, offset);
                return(byteList);
            }
            // inc [global + 4]
            else if (((operand0 is string) || (operand0 == null)) &&
                     (operand1 is int) && (operand2 == null))
            {
                int         offset   = (int)operand1;
                List <byte> byteList =
                    LookupByteArray(Operator, null, TypeSize.PointerSize);
                LoadByteList(byteList, byteList.Count - TypeSize.PointerSize,
                             TypeSize.PointerSize, offset);
                return(byteList);
            }



            // lahf
            else if ((operand0 == null) && (operand1 == null) &&
                     (operand2 == null))
            {
                return(LookupByteArray(Operator));
            }

            Assert.ErrorXXX(false);
            return(null);
        }
Ejemplo n.º 4
0
        public override string ToString()
        {
            object operand0     = m_operandArray[0],
                   operand1     = m_operandArray[1],
                   operand2     = m_operandArray[2];
            string operatorName = Enum.GetName(typeof(AssemblyOperator),
                                               Operator).Replace("_", " ");

            // lahf; syscall
            if (IsNullary())
            {
                Assert.ErrorXXX((operand0 == null) && (operand1 == null) && (operand2 == null));
                return("\t" + operatorName);
            }
            else if (IsUnary())
            {
                // inc [bp + 2]; inc [global + 4]
                if (((operand0 is Register) || (operand0 is string)) &&
                    (operand1 is int) && (operand2 == null))
                {
                    return("\t" + operatorName + " [" + operand0 +
                           WithSign(operand1) + "]");
                }
                // inc ax
                else if ((operand0 is Register) && (operand1 == null) &&
                         (operand2 == null))
                {
                    Assert.ErrorXXX(!(operand0 is BigInteger));
                    return("\t" + operatorName + " " + operand0);
                }
            }
            else if (IsBinary())
            {
                // mov ax, bx; mov ax, global; mov ax, 123
                if ((operand0 is Register) && ((operand1 is Register) ||
                                               (operand1 is string) || (operand1 is BigInteger)) &&
                    (operand2 == null))
                {
                    Assert.ErrorXXX(!(operand0 is string));
                    return("\t" + operatorName + " " + operand0 + ", " + operand1);
                }
                // mov ax, [bp + 2]; mov ax, [global + 4]
                else if ((operand0 is Register) && ((operand1 is Register) ||
                                                    (operand1 is string)) && (operand2 is int))
                {
                    return("\t" + operatorName + " " + operand0 +
                           ", [" + operand1 + WithSign(operand2) + "]");
                }
                // mov [bp + 2], ax; mov [global + 4], ax; mov [bp + 2], 123; mov [global + 4], 123; mov [bp + 2], global; mov [global + 4], global
                else if (((operand0 is Register) || (operand0 is string)) &&
                         (operand1 is int) && ((operand2 is Register) ||
                                               (operand2 is string) || (operand2 is BigInteger)))
                {
                    return("\t" + operatorName +
                           " [" + operand0 + WithSign(operand1) + "], " + operand2);
                }
            }
            else if (Operator == AssemblyOperator.label)
            {
                return("\n " + operand0 + ":");
            }
            else if (Operator == AssemblyOperator.comment)
            {
                return("\t; " + operand0);
            }
            else if (Operator == AssemblyOperator.define_address)
            {
                string name   = (string)operand0;
                int    offset = (int)operand1;
                return("\tdq " + name + WithSign(offset));
            }
            else if (Operator == AssemblyOperator.define_zero_sequence)
            {
                int size = (int)operand0;
                return("\ttimes " + size + " db 0");
            }
            else if (Operator == AssemblyOperator.define_value)
            {
                Sort   sort  = (Sort)operand0;
                object value = operand1;

                if (sort == Sort.String)
                {
                    return("\tdb " + ToVisibleString((string)operand1));
                }
                else
                {
                    string text = operand1.ToString();

                    if (((sort == Sort.Float) || (sort == Sort.Double) ||
                         (sort == Sort.Long_Double)) && !text.Contains("."))
                    {
                        text += ".0";
                    }

                    switch (TypeSize.Size(sort))
                    {
                    case 1:
                        return("\tdb " + text);

                    case 2:
                        return("\tdw " + text);

                    case 4:
                        return("\tdd " + text);

                    case 8:
                        return("\tdq " + text);
                    }
                }
            }
            else if (IsJumpRegister() || IsCallRegister() ||
                     IsCallNotRegister())
            {
                return("\tjmp " + operand0);
            }
            else if (Operator == AssemblyOperator.return_address)
            {
                string target = SymbolTable.CurrentFunction.UniqueName +
                                Symbol.SeparatorId + operand2;
                return("\tmov qword [" + operand0 + WithSign(operand1) + "], " +
                       target);
            }
            else if (IsRelationNotRegister() || IsJumpNotRegister())
            {
                if (operand2 is int)
                {
                    string label = SymbolTable.CurrentFunction.UniqueName +
                                   Symbol.SeparatorId + operand2;
                    return("\t" + operatorName + " " + label);
                }
                else if (operand2 is string)
                {
                    return("\t" + operatorName + " " + operand2);
                }
                else
                {
                    int    labelIndex = (int)operand1;
                    string labelText  = MakeMemoryLabel(labelIndex);
                    return("\t" + operatorName + " " + labelText);
                }
            }
            else if (Operator == AssemblyOperator.empty) // XXX
            {
                return(null);
            }
            else if (Operator == AssemblyOperator.new_middle_code)
            {
                return(null);
            }

            Assert.ErrorXXX(false);
            return(null);
        }