예제 #1
0
파일: Stsfld.cs 프로젝트: zrbruce/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 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"
                });
            }
        }
예제 #2
0
파일: Ldsfld.cs 프로젝트: zrbruce/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 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 field info
            int metadataToken = Utilities.ReadInt32(theOp.ValueBytes, 0);
            //Get the field info for the field to load
            FieldInfo theField = conversionState.Input.TheMethodInfo.UnderlyingInfo.Module.ResolveField(metadataToken);
            //Get the ID (i.e. ASM label) of the field to load
            string fieldID = conversionState.GetFieldInfo(theField.DeclaringType, theField.Name).ID;

            conversionState.AddExternalLabel(fieldID);

            //Load the field or field address
            switch ((OpCodes)theOp.opCode.Value)
            {
            case OpCodes.Ldsfld:
            {
                Types.TypeInfo theTypeInfo = conversionState.TheILLibrary.GetTypeInfo(theField.FieldType);
                int            size        = /*theTypeInfo.IsValueType ? theTypeInfo.SizeOnHeapInBytes : */ theTypeInfo.SizeOnStackInBytes;
                bool           isFloat     = Utilities.IsFloat(theField.FieldType);

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

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

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

                conversionState.CurrentStackFrame.Stack.Push(new StackItem()
                    {
                        isFloat            = isFloat,
                        sizeOnStackInBytes = (size == 8 ? 8 : 4),
                        isGCManaged        = theTypeInfo.IsGCManaged,
                        isValue            = theTypeInfo.IsValueType
                    });
            }
            break;

            case OpCodes.Ldsflda:
                //Load the address of the field i.e. address of the ASM label
                conversionState.Append(new ASMOps.La()
                {
                    Label = fieldID, Dest = "$t4"
                });
                conversionState.Append(new ASMOps.Push()
                {
                    Size = ASMOps.OperandSize.Word, Src = "$t4"
                });

                conversionState.CurrentStackFrame.Stack.Push(new StackItem()
                {
                    isFloat            = false,
                    sizeOnStackInBytes = 4,
                    isGCManaged        = false,
                    isValue            = false
                });
                break;
            }
        }
예제 #3
0
파일: Ldsfld.cs 프로젝트: zrbruce/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 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 field info
            int metadataToken = Utilities.ReadInt32(theOp.ValueBytes, 0);
            //Get the field info for the field to load
            FieldInfo theField = conversionState.Input.TheMethodInfo.UnderlyingInfo.Module.ResolveField(metadataToken);
            //Get the ID (i.e. ASM label) of the field to load
            string fieldID = conversionState.GetFieldInfo(theField.DeclaringType, theField.Name).ID;

            conversionState.AddExternalLabel(fieldID);

            //Load the field or field address
            switch ((OpCodes)theOp.opCode.Value)
            {
            case OpCodes.Ldsfld:
            {
                Types.TypeInfo theTypeInfo = conversionState.TheILLibrary.GetTypeInfo(theField.FieldType);
                int            size        = theTypeInfo.IsValueType ? theTypeInfo.SizeOnHeapInBytes : theTypeInfo.SizeOnStackInBytes;
                bool           isFloat     = Utilities.IsFloat(theField.FieldType);

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

                if (size == 1)
                {
                    conversionState.Append(new ASMOps.Xor()
                        {
                            Src = "EAX", Dest = "EAX"
                        });
                    conversionState.Append(new ASMOps.Mov()
                        {
                            Size = ASMOps.OperandSize.Byte, Src = "[" + fieldID + "]", Dest = "AL"
                        });
                    conversionState.Append(new ASMOps.Push()
                        {
                            Size = ASMOps.OperandSize.Dword, Src = "EAX"
                        });
                }
                else if (size == 2)
                {
                    conversionState.Append(new ASMOps.Xor()
                        {
                            Src = "EAX", Dest = "EAX"
                        });
                    conversionState.Append(new ASMOps.Mov()
                        {
                            Size = ASMOps.OperandSize.Word, Src = "[" + fieldID + "]", Dest = "AX"
                        });
                    conversionState.Append(new ASMOps.Push()
                        {
                            Size = ASMOps.OperandSize.Dword, Src = "EAX"
                        });
                }
                else
                {
                    for (int i = size; i > 0;)
                    {
                        int diff = i % 4;
                        diff = diff == 0 ? 4 : diff;
                        i   -= diff;
                        switch (diff)
                        {
                        case 1:
                            conversionState.Append(new ASMOps.Xor()
                                {
                                    Src = "EAX", Dest = "EAX"
                                });
                            conversionState.Append(new ASMOps.Mov()
                                {
                                    Size = ASMOps.OperandSize.Byte, Src = "[" + fieldID + " + " + i + "]", Dest = "AL"
                                });
                            conversionState.Append(new ASMOps.Push()
                                {
                                    Size = ASMOps.OperandSize.Dword, Src = "EAX"
                                });
                            break;

                        case 2:
                            conversionState.Append(new ASMOps.Xor()
                                {
                                    Src = "EAX", Dest = "EAX"
                                });
                            conversionState.Append(new ASMOps.Mov()
                                {
                                    Size = ASMOps.OperandSize.Word, Src = "[" + fieldID + " + " + i + "]", Dest = "AX"
                                });
                            conversionState.Append(new ASMOps.Push()
                                {
                                    Size = ASMOps.OperandSize.Dword, Src = "EAX"
                                });
                            break;

                        case 3:
                            conversionState.Append(new ASMOps.Xor()
                                {
                                    Src = "EAX", Dest = "EAX"
                                });
                            conversionState.Append(new ASMOps.Mov()
                                {
                                    Size = ASMOps.OperandSize.Byte, Src = "[" + fieldID + " + " + i + "]", Dest = "AL"
                                });
                            conversionState.Append(new ASMOps.Push()
                                {
                                    Size = ASMOps.OperandSize.Word, Src = "AX"
                                });
                            conversionState.Append(new ASMOps.Mov()
                                {
                                    Size = ASMOps.OperandSize.Word, Src = "[" + fieldID + " + " + (i + 1) + "]", Dest = "AX"
                                });
                            conversionState.Append(new ASMOps.Push()
                                {
                                    Size = ASMOps.OperandSize.Word, Src = "AX"
                                });
                            break;

                        default:
                            conversionState.Append(new ASMOps.Mov()
                                {
                                    Size = ASMOps.OperandSize.Dword, Src = "[" + fieldID + " + " + i + "]", Dest = "EAX"
                                });
                            conversionState.Append(new ASMOps.Push()
                                {
                                    Size = ASMOps.OperandSize.Dword, Src = "EAX"
                                });
                            break;
                        }
                    }
                }

                conversionState.CurrentStackFrame.Stack.Push(new StackItem()
                    {
                        isFloat            = isFloat,
                        sizeOnStackInBytes = theTypeInfo.SizeOnStackInBytes,
                        isGCManaged        = theTypeInfo.IsGCManaged,
                        isValue            = theTypeInfo.IsValueType
                    });
            }
            break;

            case OpCodes.Ldsflda:
                //Load the address of the field i.e. address of the ASM label
                conversionState.Append(new ASMOps.Push()
                {
                    Size = ASMOps.OperandSize.Dword, Src = fieldID
                });

                conversionState.CurrentStackFrame.Stack.Push(new StackItem()
                {
                    isFloat            = false,
                    sizeOnStackInBytes = 4,
                    isGCManaged        = false,
                    isValue            = false
                });
                break;
            }
        }
예제 #4
0
파일: Stsfld.cs 프로젝트: zrbruce/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 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!");
            }

            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 = "[" + fieldId + "]"
                });
            }
            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 = "[" + fieldId + "]"
                });
            }
            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 = "[" + fieldId + "+" + i + "]"
                        });
                        break;

                    case 2:
                        conversionState.Append(new ASMOps.Mov()
                        {
                            Size = ASMOps.OperandSize.Word, Src = "AX", Dest = "[" + fieldId + "+" + i + "]"
                        });
                        break;

                    case 3:
                        conversionState.Append(new ASMOps.Mov()
                        {
                            Size = ASMOps.OperandSize.Byte, Src = "AL", Dest = "[" + fieldId + "+" + i + "]"
                        });
                        conversionState.Append(new ASMOps.Shr()
                        {
                            Src = "16", Dest = "EAX"
                        });
                        conversionState.Append(new ASMOps.Mov()
                        {
                            Size = ASMOps.OperandSize.Word, Src = "AX", Dest = "[" + fieldId + "+" + (i + 1) + "]"
                        });
                        break;

                    default:
                        conversionState.Append(new ASMOps.Mov()
                        {
                            Size = ASMOps.OperandSize.Dword, Src = "EAX", Dest = "[" + fieldId + "+" + i + "]"
                        });
                        break;
                    }
                }
            }
            else
            {
                throw new ArgumentOutOfRangeException("Storing static field with unsupported size! Size: " + size.ToString());
            }
        }