Example #1
0
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        /// <exception cref="System.NotSupportedException">
        /// Thrown when loading a static float field.
        /// </exception>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            //Load static field

            //Load the metadata token used to get the type info
            int metadataToken = Utilities.ReadInt32(theOp.ValueBytes, 0);
            //Get the type info for the object to load
            Type theType = conversionState.Input.TheMethodInfo.UnderlyingInfo.Module.ResolveType(metadataToken);
            Types.TypeInfo theTypeInfo = conversionState.TheILLibrary.GetTypeInfo(theType);

            //Get the object size information
            int size = theTypeInfo.SizeOnStackInBytes;

            //Load the object onto the stack
            conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Dword, Dest = "ECX" });
            for (int i = size - 4; i >= 0; i -= 4)
            {
                conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Dword, Src = "[ECX+" + i.ToString() + "]", Dest = "EAX" });
                conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Dword, Src = "EAX" });
            }
            int extra = size % 4;
            for (int i = extra - 1; i >= 0; i--)
            {
                conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Byte, Src = "[ECX+" + i.ToString() + "]", Dest = "AL" });
                conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Byte, Src = "AL" });
            }

            conversionState.CurrentStackFrame.Stack.Push(new StackItem()
            {
                isFloat = false,
                sizeOnStackInBytes = size,
                isGCManaged = false
            });
        }
Example #2
0
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            //Save return address
            conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Word, Src = "$ra" });
            //Push the previous method's fp
            conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Word, Src = "$fp" });
            //Set fp for this method
            conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Src = "$sp", Dest = "$fp", MoveType = ASMOps.Mov.MoveTypes.RegToReg });

            //Allocate stack space for locals
            //Only bother if there are any locals
            if (conversionState.Input.TheMethodInfo.LocalInfos.Count > 0)
            {
                int totalBytes = 0;
                foreach (Types.VariableInfo aLocal in conversionState.Input.TheMethodInfo.LocalInfos)
                {
                    totalBytes += aLocal.TheTypeInfo.SizeOnStackInBytes;
                }
                //We do not use "sub esp, X" (see below) because that leaves
                //junk memory - we need memory to be "initialised" to 0 
                //so that local variables are null unless properly initialised.
                //This prevents errors in the GC.
                for (int i = 0; i < totalBytes / 4; i++)
                {
                    conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Word, Src = "$zero" });
                }
                //result.AppendLine(string.Format("sub esp, {0}", totalBytes));
            }
        }
Example #3
0
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        /// <exception cref="System.NotSupportedException">
        /// Thrown when the metadata token is not for method metadata.
        /// </exception>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            //Load token i.e. typeref
            //It should also support methodref and fieldrefs

            int metadataToken = Utilities.ReadInt32(theOp.ValueBytes, 0);
            try
            {
                Type theType = conversionState.Input.TheMethodInfo.UnderlyingInfo.Module.ResolveType(metadataToken);
                if (theType == null)
                {
                    throw new NullReferenceException();
                }
                string typeTableId = conversionState.TheILLibrary.GetTypeInfo(theType).ID;
                conversionState.AddExternalLabel(typeTableId);

                conversionState.Append(new ASMOps.La() { Dest = "$t4", Label = typeTableId });
                conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Word, Src = "$t4" });

                conversionState.CurrentStackFrame.Stack.Push(new StackItem()
                {
                    isFloat = false,
                    sizeOnStackInBytes = 4,
                    isGCManaged = false
                });
            }
            catch
            {
                throw new NotSupportedException("The metadata token specifies a fieldref or methodref which isn't supported yet!");
            }
        }
Example #4
0
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            //Push the previous method's ebp
            conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Dword, Src = "EBP" });
            //Set ebp for this method
            //See calling convention spec - this allows easy access of
            //args and locals within the method without having to track
            //temporary values (which would be a nightmare with the
            //exception handling implementation that the kernel uses!)
            conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Dword, Src = "ESP", Dest = "EBP" });

            //Allocate stack space for locals
            //Only bother if there are any locals
            if (conversionState.Input.TheMethodInfo.LocalInfos.Count > 0)
            {
                int totalBytes = 0;
                foreach (Types.VariableInfo aLocal in conversionState.Input.TheMethodInfo.LocalInfos)
                {
                    totalBytes += aLocal.TheTypeInfo.SizeOnStackInBytes;
                }
                //We do not use "sub esp, X" (see below) because that leaves
                //junk memory - we need memory to be "initialised" to 0 
                //so that local variables are null unless properly initialised.
                //This prevents errors in the GC.
                for (int i = 0; i < totalBytes / 4; i++)
                {
                    conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Dword, Src = "0" });
                }
                //result.AppendLine(string.Format("sub esp, {0}", totalBytes));
            }
        }
Example #5
0
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        /// <exception cref="System.NotSupportedException">
        /// Thrown when loading a static float field.
        /// </exception>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            //Load the metadata token used to get the type info
            int metadataToken = Utilities.ReadInt32(theOp.ValueBytes, 0);
            //Get the type info for the object to load
            Type theType = conversionState.Input.TheMethodInfo.UnderlyingInfo.Module.ResolveType(metadataToken);
            Types.TypeInfo theTypeInfo = conversionState.TheILLibrary.GetTypeInfo(theType);

            //Get the object size information
            int size = theTypeInfo.IsValueType ? theTypeInfo.SizeOnHeapInBytes : theTypeInfo.SizeOnStackInBytes;

            conversionState.CurrentStackFrame.Stack.Pop();
            conversionState.CurrentStackFrame.Stack.Pop();

            //Load the object onto the stack
            conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Dword, Dest = "ECX", Src = "[ESP+" + theTypeInfo.SizeOnStackInBytes + "]" });
            if (size == 1)
            {
                conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Dword, Dest = "EAX" });
                conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Byte, Src = "AL", Dest = "[ECX]" });
            }
            else if (size == 2)
            {
                conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Dword, Dest = "EAX" });
                conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Src = "AX", Dest = "[ECX]" });
            }
            else if (size >= 4)
            {
                for (int i = 0; i < size; i += 4)
                {
                    conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Dword, Dest = "EAX" });

                    switch (size - i)
                    {
                        case 1:
                            conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Byte, Src = "AL", Dest = "[ECX+" + i + "]" });
                            break;
                        case 2:
                            conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Src = "AX", Dest = "[ECX+" + i + "]" });
                            break;
                        case 3:
                            conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Byte, Src = "AL", Dest = "[ECX+" + i + "]" });
                            conversionState.Append(new ASMOps.Shr() { Src = "16", Dest = "EAX" });
                            conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Src = "AX", Dest = "[ECX+" + (i + 1) + "]" });
                            break;
                        default:
                            conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Dword, Src = "EAX", Dest = "[ECX+" + i + "]" });
                            break;
                    }
                }
            }
            else
            {
                throw new ArgumentOutOfRangeException("Storing object with unsupported size! Size: " + size.ToString());
            }

            conversionState.Append(new ASMOps.Add() { Dest = "ESP", Src = "4" });
        }
Example #6
0
File: Not.cs Project: kztao/FlingOS
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        /// <exception cref="System.NotSupportedException">
        /// Thrown if either or both values to shift left are floating point values or
        /// if the values are 8 bytes in size.
        /// </exception>
        /// <exception cref="System.InvalidOperationException">
        /// Thrown if either or both values to multiply are not 4 or 8 bytes
        /// in size or if the values are of different size.
        /// </exception>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            StackItem theItem = conversionState.CurrentStackFrame.Stack.Peek();
            if (theItem.isFloat)
            {
                //SUPPORT - Not op for floats
                throw new NotSupportedException("Not op not supported for float operands!");
            }

            if (theItem.sizeOnStackInBytes == 4)
            {
                conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Dword, Dest = "EAX" });
                conversionState.Append(new ASMOps.Not() { Dest = "EAX" });
                conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Dword, Src = "EAX" });
            }
            else if (theItem.sizeOnStackInBytes == 8)
            {
                conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Dword, Dest = "EAX" });
                conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Dword, Dest = "EBX" });
                conversionState.Append(new ASMOps.Not() { Dest = "EAX" });
                conversionState.Append(new ASMOps.Not() { Dest = "EBX" });
                conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Dword, Src = "EBX" });
                conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Dword, Src = "EAX" });
            }
            else
            {
                throw new NotSupportedException("Not op not supported for operand size!");
            }
        }
Example #7
0
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        /// <exception cref="System.NotSupportedException">
        /// Thrown if the value to store is floating point.
        /// </exception>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            int metadataToken = Utilities.ReadInt32(theOp.ValueBytes, 0);
            FieldInfo theField = conversionState.Input.TheMethodInfo.UnderlyingInfo.Module.ResolveField(metadataToken);
            Types.FieldInfo theFieldInfo = conversionState.GetFieldInfo(theField.DeclaringType, theField.Name);
            Types.TypeInfo theFieldTypeInfo = conversionState.TheILLibrary.GetTypeInfo(theFieldInfo.FieldType);

            string fieldId = theFieldInfo.ID;
            int size = /*theFieldTypeInfo.IsValueType ? theFieldTypeInfo.SizeOnHeapInBytes : */theFieldTypeInfo.SizeOnStackInBytes;
            bool isFloat = Utilities.IsFloat(theField.FieldType);

            conversionState.AddExternalLabel(fieldId);

            StackItem value = conversionState.CurrentStackFrame.Stack.Pop();

            if (isFloat)
            {
                //SUPPORT - floats
                throw new NotSupportedException("Storing static fields of type float not supported yet!");
            }

            conversionState.Append(new ASMOps.La() { Dest = "$t4", Label = fieldId });

            if (size == 1)
            {
                conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Word, Dest = "$t0" });
                conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Byte, Src = "$t1", Dest = "0($t4)", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory });
            }
            else if (size == 2)
            {
                conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Word, Dest = "$t0" });
                conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Halfword, Src = "$t1", Dest = "0($t4)", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory });
            }
            else if (size == 4)
            {
                conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Word, Dest = "$t0" });
                conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Src = "$t0", Dest = "0($t4)", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory });
            }
            else if (size == 8)
            {
                conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Word, Dest = "$t0" });
                conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Src = "$t0", Dest = "0($t4)", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory });
                conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Word, Dest = "$t0" });
                conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Src = "$t0", Dest = "4($t4)", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory });
            }
            else
            {
                throw new ArgumentOutOfRangeException("Storing static field that has stack size greater than 8 not supported!");
            }

            if (value.sizeOnStackInBytes - size > 0)
            {
                conversionState.Append(new ASMOps.Add() { Src1 = "$sp", Src2 = (value.sizeOnStackInBytes - size).ToString(), Dest = "$sp" });
            }
        }
Example #8
0
File: Nop.cs Project: kztao/FlingOS
 /// <summary>
 /// See base class documentation.
 /// </summary>
 /// <param name="theOp">See base class documentation.</param>
 /// <param name="conversionState">See base class documentation.</param>
 /// <returns>See base class documentation.</returns>
 public override void Convert(ILConversionState conversionState, ILOp theOp)
 {
     if (theOp.IsDebugOp)
     {
         conversionState.Append(new ASMOps.Int() { IntNum = "3" });
     }
     else
     {
         conversionState.Append(new ASMOps.Nop());
     }
 }
Example #9
0
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        /// <exception cref="System.NotSupportedException">
        /// Thrown when loading a static float field.
        /// </exception>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            //Load the metadata token used to get the type info
            int metadataToken = Utilities.ReadInt32(theOp.ValueBytes, 0);
            //Get the type info for the object to load
            Type theType = conversionState.Input.TheMethodInfo.UnderlyingInfo.Module.ResolveType(metadataToken);
            Types.TypeInfo theTypeInfo = conversionState.TheILLibrary.GetTypeInfo(theType);

            //Get the object size information
            int memSize = theTypeInfo.IsValueType ? theTypeInfo.SizeOnHeapInBytes : theTypeInfo.SizeOnStackInBytes;

            //Load the object onto the stack
            conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Dword, Dest = "ECX" });

            int irregularSize = memSize % 4;
            if (irregularSize > 0)
            {
                conversionState.Append(new ASMOps.Xor() { Src = "EAX", Dest = "EAX" });
                switch (irregularSize)
                {
                    case 1:
                        conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Byte, Src = "[ECX+" + (memSize - 1).ToString() + "]", Dest = "AL" });
                        break;
                    case 2:
                        conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Src = "[ECX+" + (memSize - 2).ToString() + "]", Dest = "AX" });
                        break;
                    case 3:
                        conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Byte, Src = "[ECX+" + (memSize - 1).ToString() + "]", Dest = "AL" });
                        conversionState.Append(new ASMOps.Shl() { Dest = "EAX", Src = "16" });
                        conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Src = "[ECX+" + (memSize - 3).ToString() + "]", Dest = "AX" });
                        break;
                }
                conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Dword, Src = "EAX" });
            }

            for (int i = memSize - irregularSize - 4; i >= 0; i -= 4)
            {
                conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Dword, Src = "[ECX+" + i.ToString() + "]", Dest = "EAX" });
                conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Dword, Src = "EAX" });
            }

            // Pop address
            conversionState.CurrentStackFrame.Stack.Pop();
            // Push value
            conversionState.CurrentStackFrame.Stack.Push(new StackItem()
            {
                isFloat = false,
                sizeOnStackInBytes = memSize,
                isGCManaged = false,
                isValue = theTypeInfo.IsValueType
            });
        }
Example #10
0
        public static void LoadData(ILConversionState conversionState, ILOp theOp,
            string addressReg, string valueReg, int offset, int size, bool SignExtend = false)
        {
            if (size == 1)
            {
                conversionState.Append(new ASMOps.Mov() { Src = offset + "(" + addressReg + ")", Dest = "$t6", MoveType = ASMOps.Mov.MoveTypes.SrcMemoryToDestReg, Size = ASMOps.OperandSize.Byte, SignExtend = SignExtend });
            }
            else
            {
                conversionState.Append(new ASMOps.Xor() { Src1 = "$t6", Src2 = "$t6", Dest = "$t6" });
                int shiftBits = 0;
                if (offset % 2 == 1)
                {
                    conversionState.Append(new ASMOps.Mov() { Src = offset + "(" + addressReg + ")", Dest = "$t7", MoveType = ASMOps.Mov.MoveTypes.SrcMemoryToDestReg, Size = ASMOps.OperandSize.Byte });
                    conversionState.Append(new ASMOps.Or() { Src1 = "$t7", Src2 = "$t6", Dest = "$t6" });

                    size -= 1;
                    offset += 1;
                    shiftBits += 8;
                }

                while (size > 1)
                {
                    conversionState.Append(new ASMOps.Mov() { Src = offset + "(" + addressReg + ")", Dest = "$t7", MoveType = ASMOps.Mov.MoveTypes.SrcMemoryToDestReg, Size = ASMOps.OperandSize.Halfword, SignExtend = (SignExtend && size == 2) });
                    if (shiftBits > 0)
                    {
                        conversionState.Append(new ASMOps.Sll() { Src = "$t7", Dest = "$t7", Bits = shiftBits });
                    }
                    conversionState.Append(new ASMOps.Or() { Src1 = "$t7", Src2 = "$t6", Dest = "$t6" });

                    size -= 2;
                    offset += 2;
                    shiftBits += 16;
                }

                if (size == 1)
                {
                    conversionState.Append(new ASMOps.Mov() { Src = offset + "(" + addressReg + ")", Dest = "$t7", MoveType = ASMOps.Mov.MoveTypes.SrcMemoryToDestReg, Size = ASMOps.OperandSize.Byte, SignExtend = SignExtend });
                    if (shiftBits > 0)
                    {
                        conversionState.Append(new ASMOps.Sll() { Src = "$t7", Dest = "$t7", Bits = shiftBits });
                    }
                    conversionState.Append(new ASMOps.Or() { Src1 = "$t7", Src2 = "$t6", Dest = "$t6" });

                    size -= 1;
                    offset += 1;
                    shiftBits += 8;
                }
            }

            conversionState.Append(new ASMOps.Mov() { Src = "$t6", Dest = valueReg, Size = ASMOps.OperandSize.Word, MoveType = ASMOps.Mov.MoveTypes.RegToReg });
        }
Example #11
0
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        /// <exception cref="System.NotSupportedException">
        /// If either value is &lt; 4 bytes in length or
        /// operands are not of the same size.
        /// </exception>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            //Pop item to negate
            StackItem itemA = conversionState.CurrentStackFrame.Stack.Pop();

            if(itemA.isFloat)
            {
                //SUPPORT - floats
                throw new NotSupportedException("Negate float vals not suppported yet!");
            }

            // Two's Complement negation
            //  - "Not" value then add 1

            if(itemA.sizeOnStackInBytes == 4)
            {
                conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Dword, Dest = "EAX" });
                conversionState.Append(new ASMOps.Neg() { Arg = "EAX" });
                conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Dword, Src = "EAX" });
            }
            else if (itemA.sizeOnStackInBytes == 8)
            {
                conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Dword, Dest = "EAX" });
                conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Dword, Dest = "EDX" });
                // Not the value
                conversionState.Append(new ASMOps.Not() { Dest = "EAX" });
                conversionState.Append(new ASMOps.Not() { Dest = "EDX" });

                // Then add 1
                conversionState.Append(new ASMOps.Mov() { Src = "1", Dest = "EBX", Size = ASMOps.OperandSize.Dword });
                conversionState.Append(new ASMOps.Mov() { Src = "0", Dest = "ECX", Size = ASMOps.OperandSize.Dword });

                //Add ecx:ebx to edx:eax
                //Add low bits
                conversionState.Append(new ASMOps.Add() { Src = "EBX", Dest = "EAX" });
                //Add high bits including any carry from 
                //when low bits were added
                conversionState.Append(new ASMOps.Add() { Src = "ECX", Dest = "EDX", WithCarry = true });

                conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Dword, Src = "EDX" });
                conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Dword, Src = "EAX" });
            }
            else
            {
                throw new NotSupportedException("Stack item size not supported by neg op!");
            }

            conversionState.CurrentStackFrame.Stack.Push(new StackItem()
            {
                isFloat = itemA.isFloat,
                sizeOnStackInBytes = itemA.sizeOnStackInBytes,
                isGCManaged = itemA.isGCManaged,
                isValue = itemA.isValue
            });
        }
Example #12
0
 /// <summary>
 /// See base class documentation.
 /// </summary>
 /// <param name="theOp">See base class documentation.</param>
 /// <param name="conversionState">See base class documentation.</param>
 /// <returns>See base class documentation.</returns>
 public override void Convert(ILConversionState conversionState, ILOp theOp)
 {
     if (theOp.IsDebugOp)
     {
         int currOpPosition = conversionState.PositionOf(theOp);
         
         conversionState.Append(new ASMOps.Label() { ILPosition = currOpPosition, Extension = "Debug", IsDebugOp = true });
         conversionState.Append(new ASMOps.Nop());
         //conversionState.Append(new ASMOps.Int() { IntNum = "3" });
     }
     else
     {
         conversionState.Append(new ASMOps.Nop());
     }
 }
Example #13
0
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        /// <exception cref="System.NotSupportedException">
        /// Thrown if divide operands are floating point numbers or if attempting to divide 64-bit numbers.
        /// </exception>
        /// <exception cref="System.InvalidOperationException">
        /// Thrown if either operand is &lt; 4 bytes long.
        /// </exception>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            StackItem testItem = conversionState.CurrentStackFrame.Stack.Pop();

            if (testItem.isFloat)
            {
                //TODO - Support floats
                throw new NotSupportedException("Switch for floats no supported!");
            }
            else if (testItem.sizeOnStackInBytes != 4)
            {
                //TODO - Support other sizes
                throw new NotSupportedException("Switch for non-int32s not supported!");
            }

            conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Dword, Dest = "EAX" });
            for (int i = 0; i < theOp.ValueBytes.Length / 4; i++)
            {
                int branchOffset = theOp.NextOffset + Utilities.ReadInt32(theOp.ValueBytes, i * 4);
                ILOp opToGoTo = conversionState.Input.At(branchOffset);
                int branchPos = conversionState.PositionOf(opToGoTo);
                
                conversionState.Append(new ASMOps.Cmp() { Arg1 = "EAX", Arg2 = i.ToString() });
                conversionState.Append(new ASMOps.Jmp() { JumpType = ASMOps.JmpOp.JumpEqual, DestILPosition = branchPos });
            }
        }
Example #14
0
 public static void InsertPageFaultDetection(ILConversionState conversionState, string reg, int offset, ILOp.OpCodes opCode)
 {
     if (PageFaultDetectionEnabled)
     {
         conversionState.Append(new ASMOps.Call() { Target = PageFaultDetectionMethod });
     }
 }
Example #15
0
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        /// <exception cref="System.NotSupportedException">
        /// Thrown if field to load is a floating value or the field to load
        /// is not of size 4 or 8 bytes.
        /// </exception>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            conversionState.CurrentStackFrame.Stack.Pop();

            Types.TypeInfo arrayTypeInfo = conversionState.GetArrayTypeInfo();
            int lengthOffset = conversionState.TheILLibrary.GetFieldInfo(arrayTypeInfo, "length").OffsetInBytes;

            int currOpPosition = conversionState.PositionOf(theOp);

            conversionState.AddExternalLabel(conversionState.GetThrowNullReferenceExceptionMethodInfo().ID);
            
            // 1. Check array reference is not null
            //      1.1. Move array ref into eax
            //      1.2. Compare eax (array ref) to 0
            //      1.3. If not zero, jump to continue execution further down
            //      1.4. Otherwise, call Exceptions.ThrowNullReferenceException
            // 2. Load array length

            
            //      1.1. Move array ref into eax
            conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Dword, Src = "[ESP]", Dest = "EAX" });
            //      1.2. Compare eax (array ref) to 0
            conversionState.Append(new ASMOps.Cmp() { Arg1 = "EAX", Arg2 = "0" });
            //      1.3. If not zero, jump to continue execution further down
            conversionState.Append(new ASMOps.Jmp() { JumpType = ASMOps.JmpOp.JumpNotZero, DestILPosition = currOpPosition, Extension = "ContinueExecution1" });
            //      1.4. Otherwise, call Exceptions.ThrowNullReferenceException
            conversionState.Append(new ASMOps.Call() { Target = "GetEIP" });
            conversionState.AddExternalLabel("GetEIP");
            conversionState.Append(new ASMOps.Call() { Target = conversionState.GetThrowNullReferenceExceptionMethodInfo().ID });
            conversionState.Append(new ASMOps.Label() { ILPosition = currOpPosition, Extension = "ContinueExecution1" });

            //2. Load array length
            //  - Pop array ref
            conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Dword, Dest = "ECX" });
            //  - Load length from array ref
            conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Dword, Src = "[ECX+" + lengthOffset.ToString() + "]", Dest = "EAX" });
            //  - Push array length
            conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Dword, Src = "EAX" });

            conversionState.CurrentStackFrame.Stack.Push(new StackItem()
            {
                isFloat = false,
                sizeOnStackInBytes = 4,
                isGCManaged = false
            });
        }
Example #16
0
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        /// <exception cref="System.NotSupportedException">
        /// If either value is &lt; 4 bytes in length or
        /// operands are not of the same size.
        /// </exception>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            //Pop item to duplicate
            StackItem itemA = conversionState.CurrentStackFrame.Stack.Pop();

            if(itemA.isFloat)
            {
                //SUPPORT - floats
                throw new NotSupportedException("Duplicate float vals not suppported yet!");
            }
            
            if(itemA.sizeOnStackInBytes == 4)
            {
                conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Dword, Dest = "EAX" });
                conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Dword, Src = "EAX" });
                conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Dword, Src = "EAX" });
            }
            else if (itemA.sizeOnStackInBytes == 8)
            {
                conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Dword, Dest = "EAX" });
                conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Dword, Dest = "EDX" });
                conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Dword, Src = "EDX" });
                conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Dword, Src = "EAX" });
                conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Dword, Src = "EDX" });
                conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Dword, Src = "EAX" });
            }
            else
            {
                throw new NotSupportedException("Stack item size not supported by duplicate op!");
            }

            conversionState.CurrentStackFrame.Stack.Push(new StackItem()
            {
                isFloat = itemA.isFloat,
                sizeOnStackInBytes = itemA.sizeOnStackInBytes,
                isGCManaged = itemA.isGCManaged,
                isValue = itemA.isValue
            });
            conversionState.CurrentStackFrame.Stack.Push(new StackItem()
            {
                isFloat = itemA.isFloat,
                sizeOnStackInBytes = itemA.sizeOnStackInBytes,
                isGCManaged = itemA.isGCManaged,
                isValue = itemA.isValue
            });
        }
Example #17
0
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            int metadataToken = Utilities.ReadInt32(theOp.ValueBytes, 0);
            Type theType = conversionState.Input.TheMethodInfo.UnderlyingInfo.Module.ResolveType(metadataToken);
            Types.TypeInfo theTypeInfo = conversionState.TheILLibrary.GetTypeInfo(theType);
            conversionState.Append(new ASMOps.Mov() { 
                Src = (theTypeInfo.IsValueType ? theTypeInfo.SizeOnHeapInBytes : theTypeInfo.SizeOnStackInBytes).ToString(), 
                Dest = "$t4", MoveType = ASMOps.Mov.MoveTypes.ImmediateToReg });
            conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Word, Src = "$t4" });

            conversionState.CurrentStackFrame.Stack.Push(new StackItem()
            {
                isFloat = false,
                sizeOnStackInBytes = 4,
                isGCManaged = false
            });
        }
Example #18
0
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {   
            StackItem theItem = conversionState.CurrentStackFrame.Stack.Pop();

            if (theItem.isNewGCObject)
            {
                //Decrement ref count

                //Get the ID of method to call as it will be labeled in the output ASM.
                Types.MethodInfo anInfo = conversionState.GetDecrementRefCountMethodInfo();
                string methodID = anInfo.ID;
                conversionState.AddExternalLabel(anInfo.ID);
                //Append the actual call
                conversionState.Append(new ASMOps.Call() { Target = methodID });
            }

            conversionState.Append(new ASMOps.Add() { Src1 = "$sp", Src2 = theItem.sizeOnStackInBytes.ToString(), Dest = "$sp" });
        }
Example #19
0
 /// <summary>
 /// See base class documentation.
 /// </summary>
 /// <param name="theOp">See base class documentation.</param>
 /// <param name="conversionState">See base class documentation.</param>
 /// <returns>See base class documentation.</returns>
 public override void Convert(ILConversionState conversionState, ILOp theOp)
 {
     //Load null (i.e. 0 as dword)
     conversionState.CurrentStackFrame.Stack.Push(new StackItem()
     {
         isFloat = false,
         sizeOnStackInBytes = 4,
         isGCManaged = false
     });
     conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Dword, Src = "0" });
 }
Example #20
0
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            int dwordsToRotate = theOp.ValueBytes == null ? 2 : BitConverter.ToInt32(theOp.ValueBytes, 0);

            int bytesShift = 0;
            for (int i = 0; i < dwordsToRotate; i++)
            {
                if (i == 0)
                {
                    conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Src = bytesShift.ToString() + "($sp)", Dest = "$t0", MoveType = ASMOps.Mov.MoveTypes.SrcMemoryToDestReg });
                    conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Src = (bytesShift + 4).ToString() + "($sp)", Dest = "$t1", MoveType = ASMOps.Mov.MoveTypes.SrcMemoryToDestReg });
                    conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Src = "$t1", Dest = bytesShift.ToString() + "($sp)", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory });
                }
                else if (i == dwordsToRotate - 1)
                {
                    conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Src = "$t0", Dest = bytesShift + "($sp)", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory });
                }
                else
                {
                    conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Src = (bytesShift + 4).ToString() + "($sp)", Dest = "$t1", MoveType = ASMOps.Mov.MoveTypes.SrcMemoryToDestReg });
                    conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Src = "$t1", Dest = bytesShift.ToString() + "($sp)", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory });
                }
                bytesShift += 4;
            }

            rotateStackItems(conversionState, theOp.StackSwitch_Items, 1);
        }
Example #21
0
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            int dwordsToRotate = theOp.ValueBytes == null ? 2 : BitConverter.ToInt32(theOp.ValueBytes, 0);
            
            int bytesShift = 0;
            for (int i = 0; i < dwordsToRotate; i++)
            {
                if (i == 0)
                {
                    conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Dword, Src = "[ESP+" + bytesShift.ToString() + "]", Dest = "EAX" });
                    conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Dword, Src = "[ESP+" + (bytesShift + 4).ToString() + "]", Dest = "EBX" });
                    conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Dword, Src = "EBX", Dest = "[ESP+" + bytesShift.ToString() + "]" });
                }
                else if (i == dwordsToRotate - 1)
                {
                    conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Dword, Src = "EAX", Dest = "[ESP+" + bytesShift.ToString() + "]" });
                }
                else
                {
                    conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Dword, Src = "[ESP+" + (bytesShift + 4).ToString() + "]", Dest = "EBX" });
                    conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Dword, Src = "EBX", Dest = "[ESP+" + bytesShift.ToString() + "]" });
                }
                bytesShift += 4;
            }

            rotateStackItems(conversionState, theOp.StackSwitch_Items, 1);
        }
Example #22
0
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            //Load a string literal (- fixed string i.e. one programmed as "a string in code")

            //Get the string metadata token used to get the string from the assembly
            int StringMetadataToken = Utilities.ReadInt32(theOp.ValueBytes, 0);
            //Get the value of the string to load
            string theString = conversionState.Input.TheMethodInfo.UnderlyingInfo.Module.ResolveString(StringMetadataToken);
            //Add the string literal and get its ID
            string theStringID = conversionState.TheILLibrary.AddStringLiteral(theString);
            conversionState.AddExternalLabel(theStringID);

            //Push the address of the string (i.e. address of ID - ASM label)
            conversionState.Append(new ASMOps.La() { Dest = "$t4", Label = theStringID });
            conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Word, Src = "$t4" });

            conversionState.CurrentStackFrame.Stack.Push(new StackItem()
            {
                sizeOnStackInBytes = 4,
                isFloat = false,
                isGCManaged = true
            });
        }
Example #23
0
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        /// <exception cref="System.NotSupportedException">
        /// Thrown if field to load is a floating value or the field to load
        /// is not of size 4 or 8 bytes.
        /// </exception>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            conversionState.CurrentStackFrame.Stack.Pop();

            Types.TypeInfo arrayTypeInfo = conversionState.GetArrayTypeInfo();
            int lengthOffset = conversionState.TheILLibrary.GetFieldInfo(arrayTypeInfo, "length").OffsetInBytes;

            int currOpPosition = conversionState.PositionOf(theOp);

            conversionState.AddExternalLabel(conversionState.GetThrowNullReferenceExceptionMethodInfo().ID);

            // 1. Check array reference is not null
            //      1.1. Move array ref into $t0
            //      1.2. Compare $t0 (array ref) to 0
            //      1.3. If not zero, jump to continue execution further down
            //      1.4. Otherwise, call Exceptions.ThrowNullReferenceException
            // 2. Load array length


            //      1.1. Move array ref into eax
            conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Src = "0($sp)", Dest = "$t0", MoveType = ASMOps.Mov.MoveTypes.SrcMemoryToDestReg });
            //      1.2. Compare eax (array ref) to 0
            //      1.3. If not zero, jump to continue execution further down
            conversionState.Append(new ASMOps.Branch() { Src1 = "$t0", Src2 = "0", BranchType = ASMOps.BranchOp.BranchNotZero, DestILPosition = currOpPosition, Extension = "ContinueExecution1", UnsignedTest = false });
            //      1.4. Otherwise, call Exceptions.ThrowNullReferenceException
            conversionState.Append(new ASMOps.Call() { Target = "GetEIP" });
            conversionState.AddExternalLabel("GetEIP");
            conversionState.Append(new ASMOps.Call() { Target = conversionState.GetThrowNullReferenceExceptionMethodInfo().ID });
            conversionState.Append(new ASMOps.Label() { ILPosition = currOpPosition, Extension = "ContinueExecution1" });

            //2. Load array length
            //  - Pop array ref
            conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Word, Dest = "$t2" });
            //  - Load length from array ref
            //conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Src = lengthOffset.ToString() + "($t2)", Dest = "$t0" }); 
            GlobalMethods.LoadData(conversionState, theOp, "$t2", "$t0", lengthOffset, 4);
            //  - Push array length
            conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Word, Src = "$t0" });

            conversionState.CurrentStackFrame.Stack.Push(new StackItem()
            {
                isFloat = false,
                sizeOnStackInBytes = 4,
                isGCManaged = false,
                isValue = true
            });
        }
Example #24
0
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        /// <exception cref="System.NotSupportedException">
        /// Thrown if the value to store is floating point or
        /// if the value is not 4 or 8 bytes in size.
        /// </exception>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            int metadataToken = Utilities.ReadInt32(theOp.ValueBytes, 0);
            FieldInfo theField = conversionState.Input.TheMethodInfo.UnderlyingInfo.Module.ResolveField(metadataToken);
            Types.TypeInfo objTypeInfo = conversionState.TheILLibrary.GetTypeInfo(theField.DeclaringType);
            Types.TypeInfo fieldTypeInfo = conversionState.TheILLibrary.GetTypeInfo(theField.FieldType);
            Types.FieldInfo theFieldInfo = conversionState.TheILLibrary.GetFieldInfo(objTypeInfo, theField.Name);
            

            int offset = theFieldInfo.OffsetInBytes;

            int stackSize = fieldTypeInfo.SizeOnStackInBytes;
            int memSize = fieldTypeInfo.IsValueType ? fieldTypeInfo.SizeOnHeapInBytes : stackSize;

            StackItem value = conversionState.CurrentStackFrame.Stack.Pop();
            StackItem objPointer = conversionState.CurrentStackFrame.Stack.Pop();
            
            if (value.isFloat)
            {
                //SUPPORT - floats
                throw new NotSupportedException("Storing fields of type float not supported yet!");
            }

            //Get object pointer
            GlobalMethods.InsertPageFaultDetection(conversionState, "ESP", stackSize, (OpCodes)theOp.opCode.Value);
            conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Dword, Src = "[ESP+" + stackSize.ToString() + "]", Dest = "ECX" });
            //Pop and mov value
            for (int i = 0; i < memSize; i += 2)
            {
                if (memSize - i == 1)
                {
                    conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Word, Dest = "AX" });
                    GlobalMethods.InsertPageFaultDetection(conversionState, "ECX", offset + i, (OpCodes)theOp.opCode.Value);
                    conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Byte, Src = "AL", Dest = "[ECX+" + (offset + i).ToString() + "]" });
                }
                else
                {
                    conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Word, Dest = "AX" });
                    GlobalMethods.InsertPageFaultDetection(conversionState, "ECX", offset + i, (OpCodes)theOp.opCode.Value);
                    conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Src = "AX", Dest = "[ECX+" + (offset + i).ToString() + "]" });
                }
            }
            //                                                           Rounds down             || Pop object pointer
            conversionState.Append(new ASMOps.Add() { Src = ((((stackSize - memSize) / 2) * 2) + 4).ToString(), Dest = "ESP" });
        }
Example #25
0
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        /// <exception cref="System.NotSupportedException">
        /// Thrown if the value to store is floating point or
        /// if the value is not 4 or 8 bytes in size.
        /// </exception>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            int metadataToken = Utilities.ReadInt32(theOp.ValueBytes, 0);
            FieldInfo theField = conversionState.Input.TheMethodInfo.UnderlyingInfo.Module.ResolveField(metadataToken);
            Types.TypeInfo objTypeInfo = conversionState.TheILLibrary.GetTypeInfo(theField.DeclaringType);
            Types.TypeInfo fieldTypeInfo = conversionState.TheILLibrary.GetTypeInfo(theField.FieldType);
            Types.FieldInfo theFieldInfo = conversionState.TheILLibrary.GetFieldInfo(objTypeInfo, theField.Name);
            

            int offset = theFieldInfo.OffsetInBytes;

            int stackSize = fieldTypeInfo.SizeOnStackInBytes;
            int memSize = fieldTypeInfo.IsValueType ? fieldTypeInfo.SizeOnHeapInBytes : stackSize;

            StackItem value = conversionState.CurrentStackFrame.Stack.Pop();
            StackItem objPointer = conversionState.CurrentStackFrame.Stack.Pop();
            
            if (value.isFloat)
            {
                //SUPPORT - floats
                throw new NotSupportedException("Storing fields of type float not supported yet!");
            }

            //Get object pointer
            conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Src = stackSize.ToString() + "($sp)", Dest = "$t2", MoveType = ASMOps.Mov.MoveTypes.SrcMemoryToDestReg });
            //Pop and mov value
            for (int i = 0; i < memSize; i += 2)
            {
                if (memSize - i == 1)
                {
                    conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Halfword, Dest = "$t0" });
                    //conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Byte, Src = "$t0", Dest = (offset + i).ToString() + "($t2)" });
                    GlobalMethods.StoreData(conversionState, theOp, "$t2", "$t0", (offset + i), 1);
                }
                else
                {
                    conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Halfword, Dest = "$t0" });
                    //conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Src = "$t0", Dest = (offset + i).ToString() + "($t2)" });
                    GlobalMethods.StoreData(conversionState, theOp, "$t2", "$t0", (offset + i), 2);
                }
            }
            //                                                           Rounds down             || Pop object pointer
            conversionState.Append(new ASMOps.Add() { Src1 = "$sp", Src2 = ((((stackSize - memSize) / 2) * 2) + 4).ToString(), Dest = "$sp" });
        }
Example #26
0
File: Clt.cs Project: kztao/FlingOS
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        /// <exception cref="System.NotSupportedException">
        /// Thrown if compare operands are floating point numbers or if either value is &lt; 4 bytes in length or
        /// operands are not of the same size.
        /// </exception>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            //Pop in reverse order to push
            StackItem itemB = conversionState.CurrentStackFrame.Stack.Pop();
            StackItem itemA = conversionState.CurrentStackFrame.Stack.Pop();

            bool unsignedComparison = (OpCodes)theOp.opCode.Value == OpCodes.Clt_Un;
            int currOpPosition = conversionState.PositionOf(theOp);

            if (itemB.isFloat || itemA.isFloat)
            {
                //SUPPORT - floats
                throw new NotSupportedException("Add floats is unsupported!");
            }
            else if(itemA.sizeOnStackInBytes == 4 && itemB.sizeOnStackInBytes == 4)
            {
                //Pop item B
                conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Word, Dest = "$t1" });
                //Pop item A
                conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Word, Dest = "$t0" });
                //If A >= B, jump to Else (not-true case)
                conversionState.Append(new ASMOps.Branch() { BranchType = ASMOps.BranchOp.BranchGreaterThanEqual, Src1 = "$t0", Src2 = "$t1", DestILPosition = currOpPosition, Extension = "Else", UnsignedTest = unsignedComparison });
                //Otherwise, A < B, so push true (true=1)
                conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Dest = "$t4", Src = "1", MoveType = ASMOps.Mov.MoveTypes.ImmediateToReg });
                conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Word, Src = "$t4" });
                //And then jump to the end of this IL op.
                conversionState.Append(new ASMOps.Branch() { BranchType = ASMOps.BranchOp.Branch, DestILPosition = currOpPosition, Extension = "End" });
                //Insert the Else label.
                conversionState.Append(new ASMOps.Label() { ILPosition = currOpPosition, Extension = "Else" });
                //Else case - Push false (false=0)
                conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Word, Src = "$zero" });
                
                //Push the result onto our stack
                conversionState.CurrentStackFrame.Stack.Push(new StackItem()
                {
                    isFloat = false,
                    sizeOnStackInBytes = 4,
                    isGCManaged = false
                });
            }
            else if (itemA.sizeOnStackInBytes == 8 && itemB.sizeOnStackInBytes == 8)
            {
                //Pop item B
                conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Word, Dest = "$t1" });
                conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Word, Dest = "$t2" });
                //Pop item A
                conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Word, Dest = "$t0" });
                conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Word, Dest = "$t3" });
                //If A high bytes < B high bytes : True
                //If A high bytes = B high bytes : Check, if A low bytes < B low bytes : True
                //Else : False
                
                //A high bytes < B high bytes? Branch to true case.
                conversionState.Append(new ASMOps.Branch() { BranchType = ASMOps.BranchOp.BranchLessThan, Src1 = "$t3", Src2 = "$t2", DestILPosition = currOpPosition, Extension = "True", UnsignedTest = unsignedComparison });
                //A high bytes > B high bytes? Branch to else case.
                conversionState.Append(new ASMOps.Branch() { BranchType = ASMOps.BranchOp.BranchGreaterThan, Src1 = "$t3", Src2 = "$t2", DestILPosition = currOpPosition, Extension = "Else", UnsignedTest = unsignedComparison });
                //Otherwise, A high bytes = B high bytes
                //A low bytes >= B low bytes? Branch to else case.
                conversionState.Append(new ASMOps.Branch() { BranchType = ASMOps.BranchOp.BranchGreaterThanEqual, Src1 = "$t0", Src2 = "$t1", DestILPosition = currOpPosition, Extension = "Else", UnsignedTest = unsignedComparison });
                //Otherwise A < B.

                //Insert True case label
                conversionState.Append(new ASMOps.Label() { ILPosition = currOpPosition, Extension = "True" });
                //True case - Push true (true=1)
                conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Dest = "$t4", Src = "1", MoveType = ASMOps.Mov.MoveTypes.ImmediateToReg });
                conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Word, Src = "$t4" });
                //And then jump to the end of this IL op.
                conversionState.Append(new ASMOps.Branch() { BranchType = ASMOps.BranchOp.Branch, DestILPosition = currOpPosition, Extension = "End" });
                //Insert Else case label
                conversionState.Append(new ASMOps.Label() { ILPosition = currOpPosition, Extension = "Else" });
                //Else case - Push false (false=0)
                conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Word, Src = "$zero" });
                
                //Push the result onto our stack
                conversionState.CurrentStackFrame.Stack.Push(new StackItem()
                {
                    isFloat = false,
                    // Yes, this is supposed to be 4 - the value that just got pushed was a 
                    // true / false integer
                    sizeOnStackInBytes = 4,
                    isGCManaged = false
                });
            }
            else
            {
                throw new NotSupportedException("Unsupported number of bytes for compare less than!");
            }

            //Always append the end label
            conversionState.Append(new ASMOps.Label() { ILPosition = currOpPosition, Extension = "End" });
        }
Example #27
0
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        /// <exception cref="System.NotSupportedException">
        /// Thrown when the return value is a float or the size on the stack
        /// in bytes is not 4 or 8 bytes.
        /// </exception>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            //Store the return value
            //Get the return type
            Type retType = (conversionState.Input.TheMethodInfo.IsConstructor ?
                typeof(void) : ((MethodInfo)conversionState.Input.TheMethodInfo.UnderlyingInfo).ReturnType);
            Types.TypeInfo retTypeInfo = conversionState.TheILLibrary.GetTypeInfo(retType);
            //Get the size of the return type on stack
            int retSize = retTypeInfo.SizeOnStackInBytes;
            //If the size isn't 0 (i.e. isn't "void" which has no return value)
            if (retSize != 0)
            {
                //Pop the return value off our stack
                StackItem retItem = conversionState.CurrentStackFrame.Stack.Pop();

                //If it is float, well, we don't support it yet...
                if (retItem.isFloat)
                {
                    //SUPPORT - floats
                    throw new NotSupportedException("Floats return type not supported yet!");
                }
                //Otherwise, store the return value at [ebp+8]
                //[ebp+8] because that is last "argument"
                //      - read the calling convention spec
                else if (retSize == 4)
                {
                    conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Word, Dest = "$t0" });
                    conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Dest = "8($fp)", Src = "$t0", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory });
                }
                else if (retSize == 8)
                {
                    conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Word, Dest = "$t0" });
                    conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Dest = "8($fp)", Src = "$t0", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory });

                    conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Word, Dest = "$t0" });
                    conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Dest = "12($fp)", Src = "$t0", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory });
                }
                else
                {
                    throw new NotSupportedException("Return type size not supported / invalid!");
                }
            }

            //Once return value is off the stack, remove the locals
            //Deallocate stack space for locals
            //Only bother if there are any locals
            if (conversionState.Input.TheMethodInfo.LocalInfos.Count > 0)
            {
                //Get the total size of all locals
                int totalBytes = 0;
                foreach (Types.VariableInfo aLocal in conversionState.Input.TheMethodInfo.LocalInfos)
                {
                    totalBytes += aLocal.TheTypeInfo.SizeOnStackInBytes;
                }
                //Move esp past the locals
                conversionState.Append(new ASMOps.Add() { Src1 = "$sp", Src2 = totalBytes.ToString(), Dest = "$sp" });
            }

            //Restore ebp to previous method's ebp
            conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Word, Dest = "$fp" });
            //This pop also takes last value off the stack which
            //means top item is the return address
            //So ret command can now be correctly executed.
        }
Example #28
0
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            int currOpPosition = conversionState.PositionOf(theOp);

            // Test if the object provided inherits from the specified class
            // 1. Pop object ref
            // 1.1. Test if object ref is null:
            // 1.1.1 True: Push null and continue
            // 1.1.2 False: Go to 2
            // 2. Load object type
            // 3. Test if object type == provided type:
            //      3.1 True: Push object ref and continue
            //      3.2 False: 
            //      3.2.1. Move to base type
            //      3.2.2. Test if base type null:
            //      3.2.2.1   True: Push null and continue
            //      3.2.2.2   False: Jump back to (3)

            // 1. Pop object ref
            conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Word, Dest = "$t0" });

            // 1.1. Test if object ref is null:
            conversionState.Append(new ASMOps.Branch() { Src1 = "$t0", Src2 = "0", BranchType = ASMOps.BranchOp.BranchNotEqual, DestILPosition = currOpPosition, Extension = "False1", UnsignedTest = true });

            // 1.1.1 True: Push null and continue
            conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Word, Src = "$zero" });
            conversionState.Append(new ASMOps.Branch() { BranchType = ASMOps.BranchOp.Branch, DestILPosition = currOpPosition, Extension = "End" });

            // 1.1.2 False: Go to 2
            conversionState.Append(new ASMOps.Label() { ILPosition = currOpPosition, Extension = "False1" });

            // 2. Load object type
            //conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Src = "0($t0)", Dest = "$t1", MoveType = ASMOps.Mov.MoveTypes.SrcMemoryToDestReg });
            GlobalMethods.LoadData(conversionState, theOp, "$t0", "$t1", 0, 4);

            // 3. Test if object type == provided type:
            int metadataToken = Utilities.ReadInt32(theOp.ValueBytes, 0);
            Type theType = conversionState.Input.TheMethodInfo.UnderlyingInfo.Module.ResolveType(metadataToken);
            Types.TypeInfo theTypeInfo = conversionState.TheILLibrary.GetTypeInfo(theType);
            string TestTypeId = theTypeInfo.ID;
            conversionState.AddExternalLabel(TestTypeId);

            conversionState.Append(new ASMOps.La() { Label = TestTypeId, Dest = "$t2" });

            conversionState.Append(new ASMOps.Label() { ILPosition = currOpPosition, Extension = "Label3" });

            conversionState.Append(new ASMOps.Branch() { Src1 = "$t1", Src2 = "$t2", BranchType = ASMOps.BranchOp.BranchNotEqual, DestILPosition = currOpPosition, Extension = "False2", UnsignedTest = true });

            //      3.1 True: Push object ref and continue
            conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Word, Src = "$t0" });
            conversionState.Append(new ASMOps.Branch() { BranchType = ASMOps.BranchOp.Branch, DestILPosition = currOpPosition, Extension = "End" });

            //      3.2 False: 
            conversionState.Append(new ASMOps.Label() { ILPosition = currOpPosition, Extension = "False2" });

            //      3.2.1. Move to base type
            int baseTypeOffset = conversionState.GetTypeFieldOffset("TheBaseType");
            //conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Src = baseTypeOffset + "($t1)", Dest = "$t1" });
            GlobalMethods.LoadData(conversionState, theOp, "$t1", "$t1", baseTypeOffset, 4);


            //      3.2.2. Test if base type null:
            //      3.2.2.2   False: Jump back to (3)
            conversionState.Append(new ASMOps.Branch() { Src1 = "$t1", Src2 = "0", BranchType = ASMOps.BranchOp.BranchNotEqual, DestILPosition = currOpPosition, Extension = "Label3", UnsignedTest = true });

            //      3.2.2.1   True: Push null and continue
            conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Word, Src = "$zero" });

            conversionState.Append(new ASMOps.Label() { ILPosition = currOpPosition, Extension = "End" });
        }
Example #29
0
File: Shl.cs Project: kztao/FlingOS
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        /// <exception cref="System.NotSupportedException">
        /// Thrown if either or both values to shift left are floating point values or
        /// if the values are 8 bytes in size.
        /// </exception>
        /// <exception cref="System.InvalidOperationException">
        /// Thrown if either or both values to multiply are not 4 or 8 bytes
        /// in size or if the values are of different size.
        /// </exception>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            //Pop in reverse order to push
            StackItem itemB = conversionState.CurrentStackFrame.Stack.Pop();
            StackItem itemA = conversionState.CurrentStackFrame.Stack.Pop();

            int currOpPosition = conversionState.PositionOf(theOp);

            if (itemB.sizeOnStackInBytes < 4 ||
                itemA.sizeOnStackInBytes < 4)
            {
                throw new InvalidOperationException("Invalid stack operand sizes!");
            }
            else if (itemB.isFloat || itemA.isFloat)
            {
                //SUPPORT - floats
                throw new NotSupportedException("Shift left on floats is unsupported!");
            }
            else
            {
                if (itemA.sizeOnStackInBytes == 4 &&
                    itemB.sizeOnStackInBytes == 4)
                {
                    //Pop item B
                    conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Word, Dest = "$t2" });
                    //Pop item A
                    conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Word, Dest = "$t0" });
                    conversionState.Append(new ASMOps.Sllv() { Src = "$t0", BitsReg = "$t2", Dest = "$t0",  });
                    conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Word, Src = "$t0" });

                    conversionState.CurrentStackFrame.Stack.Push(new StackItem()
                    {
                        isFloat = false,
                        sizeOnStackInBytes = 4,
                        isGCManaged = false
                    });
                }
                else if ((itemA.sizeOnStackInBytes == 4 &&
                          itemB.sizeOnStackInBytes == 8))
                {
                    throw new InvalidOperationException("Invalid stack operand sizes! 4,8 not supported.");
                }
                else if ((itemA.sizeOnStackInBytes == 8 &&
                          itemB.sizeOnStackInBytes == 4))
                {
                    //Pop item B
                    conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Word, Dest = "$t2" });
                    //Pop item A (8 bytes)
                    conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Word, Dest = "$t0" });
                    conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Word, Dest = "$t3" });

                    //Check shift size
                    conversionState.Append(new ASMOps.Branch() { Src1 = "$t2", Src2 = "32", BranchType = ASMOps.BranchOp.BranchGreaterThanEqual, DestILPosition = currOpPosition, Extension = "ShiftMoreThan32", UnsignedTest = true });

                    //Shld (< 32)
                    //Works for shifting 64 bit values
                    //Left shift high bits ($t3) by $t2
                    conversionState.Append(new ASMOps.Sllv() { Src = "$t3", BitsReg = "$t2", Dest = "$t3" });
                    //Right shift low bits ($t0) by (32-$t2) into temp ($t1)
                    conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Src = "32", Dest = "$t1", MoveType = ASMOps.Mov.MoveTypes.ImmediateToReg });
                    conversionState.Append(new ASMOps.Sub() { Src1 = "$t1", Src2 = "$t2", Dest = "$t1" });       
                    conversionState.Append(new ASMOps.Srlv() { Src = "$t0", BitsReg = "$t1", Dest = "$t1" });   //$t1 = temp
                    //Copy temp to high bits
                    conversionState.Append(new ASMOps.Or() { Src1 = "$t1", Src2 = "$t3",  Dest = "$t3"});
                    //Left shift low bytes by $t2
                    conversionState.Append(new ASMOps.Sllv() { Src = "$t0", BitsReg = "$t2", Dest = "$t0" });
                    conversionState.Append(new ASMOps.Branch() { BranchType = ASMOps.BranchOp.Branch, DestILPosition = currOpPosition, Extension = "End" });

                    //Shld (>= 32)
                    conversionState.Append(new ASMOps.Label() { ILPosition = currOpPosition, Extension = "ShiftMoreThan32" });
                    //Move low bits ($t0) to high bits ($t3)
                    conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Src = "$t0", Dest = "$t3", MoveType = ASMOps.Mov.MoveTypes.RegToReg });
                    //Zero out low bits
                    conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Src = "0", Dest = "$t0", MoveType = ASMOps.Mov.MoveTypes.ImmediateToReg });
                    //Left shift high bits by (t2-32)
                    conversionState.Append(new ASMOps.Sub() { Src1 = "$t2", Src2 = "32", Dest = "$t2" });
                    conversionState.Append(new ASMOps.Sllv() { Src = "$t3", BitsReg = "$t2", Dest = "$t3" });

                    //Push result
                    conversionState.Append(new ASMOps.Label() { ILPosition = currOpPosition, Extension = "End" });
                    conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Word, Src = "$t3" });
                    conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Word, Src = "$t0" });

                    conversionState.CurrentStackFrame.Stack.Push(new StackItem()
                    {
                        isFloat = false,
                        sizeOnStackInBytes = 8,
                        isGCManaged = false
                    });
                }
                else if (itemA.sizeOnStackInBytes == 8 &&
                    itemB.sizeOnStackInBytes == 8)
                {
                    //Note: Shifting by more than 64 bits is pointless since the value will be annihilated entirely.
                    //          "64" fits well within the low 32-bits
                    //      So for this op, we do the same as the 8-4 byte version but discard the top four bytes
                    //          of the second operand
                    //      Except we must check the high bytes for non-zero value. If they are non-zero, we simply
                    //          push a result of zero.

                    //Pop item B (8 bytes)
                    conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Word, Dest = "$t2" });
                    conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Word, Dest = "$t1" });
                    //Pop item A (8 bytes)
                    conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Word, Dest = "$t0" });
                    conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Word, Dest = "$t3" });
                    //Check high 4 bytes of second param     
                    conversionState.Append(new ASMOps.Branch() { Src1 = "$t1", BranchType = ASMOps.BranchOp.BranchZero, DestILPosition = currOpPosition, Extension = "Zero" });
                    conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Word, Src = "$zero" });
                    conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Word, Src = "$zero" });
                    conversionState.Append(new ASMOps.Branch() { BranchType = ASMOps.BranchOp.Branch, DestILPosition = currOpPosition, Extension = "End2" });
                    conversionState.Append(new ASMOps.Label() { ILPosition = currOpPosition, Extension = "zero" });
                    conversionState.Append(new ASMOps.Branch() { Src1 = "$t2", Src2 = "32", BranchType = ASMOps.BranchOp.BranchGreaterThanEqual, DestILPosition = currOpPosition, Extension = "ShiftMoreThan32", UnsignedTest = true });

                    //Shld (< 32)
                    //Works for shifting 64 bit values
                    //Left shift high bits ($t3) by $t2
                    conversionState.Append(new ASMOps.Sllv() { Src = "$t3", BitsReg = "$t2", Dest = "$t3" });
                    //Right shift low bits ($t0) by (32-$t2)
                    conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Src = "32", Dest = "$t1", MoveType = ASMOps.Mov.MoveTypes.ImmediateToReg });
                    conversionState.Append(new ASMOps.Sub() { Src1 = "$t1", Src2 = "$t2", Dest = "$t1" });       
                    conversionState.Append(new ASMOps.Srlv() { Src = "$t0", BitsReg = "$t1", Dest = "$t1" });   //$t1 = temp
                    //Copy temp to high bits
                    conversionState.Append(new ASMOps.Or() { Src1 = "$t1", Src2 = "$t3",  Dest = "$t3"});
                    conversionState.Append(new ASMOps.Sllv() { Src = "$t0", BitsReg = "$t2", Dest = "$t0" });
                    conversionState.Append(new ASMOps.Branch() { BranchType = ASMOps.BranchOp.Branch, DestILPosition = currOpPosition, Extension = "End1" });

                    //Shl (>= 32)
                    conversionState.Append(new ASMOps.Label() { ILPosition = currOpPosition, Extension = "ShiftMoreThan32" });
                    //Move low bits ($t0) to high bits ($t3)
                    conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Src = "$t0", Dest = "$t3", MoveType = ASMOps.Mov.MoveTypes.RegToReg });
                    //Zero out low bits
                    conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Src = "0", Dest = "$t0", MoveType = ASMOps.Mov.MoveTypes.ImmediateToReg });
                    //Left shift high bits by (t2-32)
                    conversionState.Append(new ASMOps.Sub() { Src1 = "$t2", Src2 = "32", Dest = "$t2" });
                    conversionState.Append(new ASMOps.Sllv() { Src = "$t3", BitsReg = "$t2", Dest = "$t3" });

                    //Push result
                    conversionState.Append(new ASMOps.Label() { ILPosition = currOpPosition, Extension = "End1" });
                    conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Word, Src = "$t3" });
                    conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Word, Src = "$t0" });
                    conversionState.Append(new ASMOps.Label() { ILPosition = currOpPosition, Extension = "End2" });

                    conversionState.CurrentStackFrame.Stack.Push(new StackItem()
                    {
                        isFloat = false,
                        sizeOnStackInBytes = 8,
                        isGCManaged = false
                    });
                }
            }
        }
Example #30
0
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        /// <exception cref="System.NotSupportedException">
        /// Thrown if any argument or the return value is a floating point number.
        /// </exception>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            MethodBase methodToCall = theOp.MethodToCall;
            Types.MethodInfo methodToCallInfo = conversionState.TheILLibrary.GetMethodInfo(methodToCall);

            conversionState.AddExternalLabel(methodToCallInfo.ID);

            //The method to call is a method base
            //A method base can be either a method info i.e. a normal method
            //or a constructor method. The two types are treated separately.
            if(methodToCall is MethodInfo)
            {
                //Allocate space on the stack for the return value as necessary
                Type retType = ((MethodInfo)methodToCall).ReturnType;
                Types.TypeInfo retTypeInfo = conversionState.TheILLibrary.GetTypeInfo(retType);
                StackItem returnItem = new StackItem()
                {
                    isFloat = Utilities.IsFloat(retType),
                    sizeOnStackInBytes = retTypeInfo.SizeOnStackInBytes,
                    isGCManaged = retTypeInfo.IsGCManaged
                };
                //We do not push the return value onto the stack unless it has size > 0
                //We do not push the return value onto our stack at this point - it is pushed after the call is done

                if (returnItem.sizeOnStackInBytes != 0)
                {
                    if (returnItem.isFloat)
                    {
                        //SUPPORT - floats
                        throw new NotSupportedException("Cannot handle float return values!");
                    }
                    else if (returnItem.sizeOnStackInBytes == 4)
                    {
                        conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Dword, Src = "0" });
                    }
                    else if (returnItem.sizeOnStackInBytes == 8)
                    {
                        conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Dword, Src = "0" });
                        conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Dword, Src = "0" });
                    }
                    else
                    {
                        throw new NotSupportedException("Invalid return stack operand size!");
                    }
                }

                //Append the actual call
                conversionState.Append(new ASMOps.Call() { Target = methodToCallInfo.ID });

                //After a call, we need to remove the return value and parameters from the stack
                //This is most easily done by just adding the total number of bytes for params and
                //return value to the stack pointer (ESP register).
                
                //Stores the number of bytes to add
                int bytesToAdd = 0;
                //All the parameters for the method that was called
                List<Type> allParams = ((MethodInfo)methodToCall).GetParameters().Select(x => x.ParameterType).ToList();
                //Go through each one
                if (!methodToCall.IsStatic)
                {
                    allParams.Insert(0, methodToCall.DeclaringType);
                }
                foreach (Type aParam in allParams)
                {
                    //Pop the paramter off our stack 
                    //(Note: Return value was never pushed onto our stack. See above)
                    conversionState.CurrentStackFrame.Stack.Pop();
                    //Add the size of the paramter to the total number of bytes to pop
                    bytesToAdd += conversionState.TheILLibrary.GetTypeInfo(aParam).SizeOnStackInBytes;
                }
                //If the number of bytes to add to skip over params is > 0
                if (bytesToAdd > 0)
                {
                    //If there is a return value on the stack
                    if (returnItem.sizeOnStackInBytes != 0)
                    {
                        //We need to store the return value then pop all the params

                        //We now push the return value onto our stack as,
                        //after all is said and done below, it will be the 
                        //top item on the stack
                        conversionState.CurrentStackFrame.Stack.Push(returnItem);

                        //SUPPORT - floats (with above)

                        //Pop the return value into the eax register
                        //We will push it back on after params are skipped over.
                        if (returnItem.sizeOnStackInBytes == 4)
                        {
                            conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Dword, Dest = "EAX" });
                        }
                        else if (returnItem.sizeOnStackInBytes == 8)
                        {
                            conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Dword, Dest = "EAX" });
                            conversionState.Append(new ASMOps.Pop() { Size = ASMOps.OperandSize.Dword, Dest = "EDX" });
                        }
                    }   
                    //Skip over the params
                    conversionState.Append(new ASMOps.Add() { Src = bytesToAdd.ToString(), Dest = "ESP" });
                    //If necessary, push the return value onto the stack.
                    if (returnItem.sizeOnStackInBytes != 0)
                    {
                        //SUPPORT - floats (with above)

                        //The return value was stored in eax
                        //So push it back onto the stack
                        if (returnItem.sizeOnStackInBytes == 4)
                        {
                            conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Dword, Src = "EAX" });
                        }
                        else if (returnItem.sizeOnStackInBytes == 8)
                        {
                            conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Dword, Src = "EDX" });
                            conversionState.Append(new ASMOps.Push() { Size = ASMOps.OperandSize.Dword, Src = "EAX" });
                        }
                    }
                }
                //No params to skip over but we might still need to store return value
                else if (returnItem.sizeOnStackInBytes != 0)
                {
                    //The return value will be the top item on the stack.
                    //So all we need to do is push the return item onto our stack.
                    conversionState.CurrentStackFrame.Stack.Push(returnItem);
                }
            }
            else if(methodToCall is ConstructorInfo)
            {
                ConstructorInfo aConstructor = (ConstructorInfo)methodToCall;
                if (aConstructor.IsStatic)
                {
                    //Static constructors do not have parameters or return values

                    //Append the actual call
                    conversionState.Append(new ASMOps.Call() { Target = methodToCallInfo.ID });
                }
                else
                {
                    //Append the actual call
                    conversionState.Append(new ASMOps.Call() { Target = methodToCallInfo.ID });

                    //After a call, we need to remove the parameters from the stack
                    //This is most easily done by just adding the total number of bytes for params
                    //to the stack pointer (ESP register).

                    //Stores the number of bytes to add
                    int bytesToAdd = 0;
                    //All the parameters for the method that was called
                    ParameterInfo[] allParams = methodToCall.GetParameters();
                    //Go through each one
                    foreach (ParameterInfo aParam in allParams)
                    {
                        //Pop the paramter off our stack 
                        //(Note: Return value was never pushed onto our stack. See above)
                        conversionState.CurrentStackFrame.Stack.Pop();
                        //Add the size of the paramter to the total number of bytes to pop
                        bytesToAdd += conversionState.TheILLibrary.GetTypeInfo(aParam.ParameterType).SizeOnStackInBytes;
                    }
                    //Add 4 bytes for the instance ref
                    bytesToAdd += 4;
                    //If the number of bytes to add to skip over params is > 0
                    if (bytesToAdd > 0)
                    {
                        //Skip over the params
                        conversionState.Append(new ASMOps.Add() { Src = bytesToAdd.ToString(), Dest = "ESP" });
                    }
                }
            }
        }