Esempio n. 1
0
        /// <summary>
        /// Gets the memory.
        /// </summary>
        /// <param name="operand">The operand.</param>
        /// <param name="emit">if set to <c>true</c> [emit].</param>
        /// <returns></returns>
        private Memory GetMemory(Operand operand)
        {
            Memory address = null;

            if (operand is FieldOperand)
            {
                address = this.GetAddress(operand as FieldOperand);
            }
            else if (operand is Argument)
            {
                address = this.GetAddress(operand as Argument);
            }
            else if (operand is Local)
            {
                address = this.GetAddress(operand as Local);
            }
            else if (operand is IR.Operands.Register)
            {
                address = this.GetAddress(operand as IR.Operands.Register);
            }
            else
            {
                throw new NotImplementedEngineException("Wrong '" + operand.ToString() + "' Operand.");
            }

            if (operand.InternalType == InternalType.I1 ||
                operand.InternalType == InternalType.U1)
            {
                address = new ByteMemory(address);
            }
            else if (operand.InternalType == InternalType.I2 ||
                     operand.InternalType == InternalType.U2)
            {
                address = new WordMemory(address);
            }
            else if (operand.InternalType == InternalType.I4 ||
                     operand.InternalType == InternalType.U4 ||
                     operand.InternalType == InternalType.I ||
                     operand.InternalType == InternalType.U ||
                     operand.InternalType == InternalType.ValueType ||
                     operand.InternalType == InternalType.O ||
                     operand.InternalType == InternalType.M ||
                     operand.InternalType == InternalType.SZArray ||
                     operand.InternalType == InternalType.Array)
            {
                address = new DWordMemory(address);
            }
            else if (operand.InternalType == InternalType.I8 ||
                     operand.InternalType == InternalType.U8)
            {
                address = new DWordMemory(address);
            }
            else
            {
                throw new NotImplementedEngineException("'" + operand.InternalType + "' not supported.");
            }

            return(address);
        }
Esempio n. 2
0
		/// <summary>
		/// Common implementation for IL instructions which load a value onto the IL evaluation stack.
		/// </summary>
		private void Load (IR.Operands.Register assignee, InternalType sourceType, Memory memory)
		{
			switch (sourceType) {
			case InternalType.I1:
				this.assembly.MOVSX (R32.EAX, new ByteMemory (memory));

				if (assignee.IsRegisterSet)
					this.assembly.MOV (Assembly.GetRegister (assignee.Register), R32.EAX);

				else
					this.assembly.MOV (new DWordMemory (this.GetAddress (assignee)), R32.EAX);

				break;

			case InternalType.U1:
				this.assembly.MOVZX (R32.EAX, new ByteMemory (memory));

				if (assignee.IsRegisterSet)
					this.assembly.MOV (Assembly.GetRegister (assignee.Register), R32.EAX);

				else
					this.assembly.MOV (new DWordMemory (this.GetAddress (assignee)), R32.EAX);

				break;

			case InternalType.I2:
				this.assembly.MOVSX (R32.EAX, new WordMemory (memory));

				if (assignee.IsRegisterSet)
					this.assembly.MOV (Assembly.GetRegister (assignee.Register), R32.EAX);

				else
					this.assembly.MOV (new DWordMemory (this.GetAddress (assignee)), R32.EAX);

				break;

			case InternalType.U2:
				this.assembly.MOVZX (R32.EAX, new WordMemory (memory));

				if (assignee.IsRegisterSet)
					this.assembly.MOV (Assembly.GetRegister (assignee.Register), R32.EAX);

				else
					this.assembly.MOV (new DWordMemory (this.GetAddress (assignee)), R32.EAX);

				break;

			case InternalType.I4:
			case InternalType.U4:
			case InternalType.I:
			case InternalType.U:
			case InternalType.O:
			case InternalType.M:
			case InternalType.SZArray:
			case InternalType.Array:
				this.assembly.MOV (R32.EAX, new DWordMemory (memory));

				if (assignee.IsRegisterSet)
					this.assembly.MOV (Assembly.GetRegister (assignee.Register), R32.EAX);

				else
					this.assembly.MOV (new DWordMemory (this.GetAddress (assignee)), R32.EAX);

				break;

			case InternalType.I8:
			case InternalType.U8:
				DWordMemory source = new DWordMemory (memory);
				source.DisplacementDelta = 4;

				Memory destination = this.GetAddress (assignee);
				destination.DisplacementDelta = 4;

				this.assembly.MOV (R32.EAX, new DWordMemory (memory));
				this.assembly.MOV (new DWordMemory (this.GetAddress (assignee)), R32.EAX);

				this.assembly.MOV (R32.EAX, new DWordMemory (source));
				this.assembly.MOV (new DWordMemory (destination), R32.EAX);
				break;

			case InternalType.ValueType:
				uint size = (uint) assignee.Type.Size;

				if (size == 4) {
					this.assembly.MOV (R32.EAX, new DWordMemory (memory));

					if (assignee.IsRegisterSet)
						this.assembly.MOV (Assembly.GetRegister (assignee.Register), R32.EAX);
					else
						this.assembly.MOV (new DWordMemory (this.GetAddress (assignee)), R32.EAX);

				} else {
					this.assembly.PUSH (R32.ECX);
					this.assembly.PUSH (R32.ESI);
					this.assembly.PUSH (R32.EDI);

					this.assembly.LEA (R32.ESI, new DWordMemory (memory));

					if (assignee.IsRegisterSet)
						this.assembly.MOV (R32.EDI, Assembly.GetRegister (assignee.Register));
					else
						this.assembly.LEA (R32.EDI, new DWordMemory (this.GetAddress (assignee)));

					this.assembly.MOV (R32.ECX, size);

					this.assembly.CLD ();
					this.assembly.REP ();
					this.assembly.MOVSB ();

					this.assembly.POP (R32.EDI);
					this.assembly.POP (R32.ESI);
					this.assembly.POP (R32.ECX);
				}

				break;

			case InternalType.R4:
			case InternalType.R8:
			case InternalType.F:
			case InternalType.TypedReference:
			default:
				throw new NotImplementedEngineException ("Load not supported for InternalType." + sourceType);
			}
		}
Esempio n. 3
0
		/// <summary>
		/// Encodes the IL 'call', 'calli', and 'callvirt' instructions
		/// </summary>
		private void Call (SharpOS.AOT.IR.Instructions.Call call)
		{
			if (call.IsSpecialCase) {
				if (this.assembly.IsInstruction (call.Method.Class.TypeFullName))
					this.HandleAssemblyStub (call);
				else
					this.HandleBuiltIns (call);

				return;
			}

			if (call.Method.Class.IsArray
					&& call.Method.SkipProcessing) {
				this.ArrayCalls (call);

				return;
			}

			// TODO add support for call/callvirt/calli/jmp and for tail./constrained.

			// Perform a null check for non-static methods
			if (!(call.Method.MethodDefinition as Mono.Cecil.MethodDefinition).IsStatic) {
				IR.Operands.Register identifier = call.Use [0] as IR.Operands.Register;

				if (identifier.IsRegisterSet)
					this.assembly.MOV (R32.EAX, Assembly.GetRegister (identifier.Register));
				else
					this.assembly.MOV (R32.EAX, new DWordMemory (this.GetAddress (identifier)));

				NullCheck (R32.EAX);
			}

			PushCallParameters (call);

			IR.Operands.Register assignee = call.Def as IR.Operands.Register;

			if (call.Method.IsReturnTypeBigValueType) {
				this.assembly.LEA (R32.EAX, this.GetAddress (assignee));
				this.assembly.PUSH (R32.EAX);
			}

			if (call is Callvirt
					&& (call.Method.IsNewSlot
						|| call.Method.IsVirtual)) {
				IR.Operands.Register _this = call.Use [0] as IR.Operands.Register;

				if (_this.IsRegisterSet)
					this.assembly.MOV (R32.EAX, Assembly.GetRegister (_this.Register));
				else
					this.assembly.MOV (R32.EAX, new DWordMemory (this.GetAddress (_this)));

				if (call.Method.InterfaceMethodNumber == -1) {
					// Do a normal vtable call
					int address = this.assembly.Engine.VTableSize + this.assembly.IntSize * call.Method.VirtualSlot;

					// Get the Object's VTable
					this.assembly.MOV (R32.EAX, new DWordMemory (null, R32.EAX, null, 0));

					// Call virtual method using the table in the Object's VTable
					this.assembly.CALL (new DWordMemory (null, R32.EAX, null, 0, address));
				} else {
					// Do a IMT lookup call for interface method
					int address = this.assembly.IntSize * call.Method.InterfaceMethodKey + this.assembly.Engine.ObjectSize;

					// Get the Object's VTable
					this.assembly.MOV (R32.EAX, new DWordMemory (null, R32.EAX, null, 0));

					// Get the Object's ITable
					this.assembly.MOV (R32.EAX, new DWordMemory (null, R32.EAX, null, 0, this.assembly.IntSize * 4));

					// IMT key in case call hits a colision resolving stub
					this.assembly.MOV (R32.ECX, (uint) call.Method.InterfaceMethodNumber);

					// Call virtual method using the table in the Object's ITable
					this.assembly.CALL (new DWordMemory (null, R32.EAX, null, 0, address));
				}
			} else
				assembly.CALL (call.Method.AssemblyLabel);

			PopCallParameters (call);

			if (assignee != null) {
				switch (assignee.InternalType) {
				case InternalType.I:
				case InternalType.M:
				case InternalType.O:
				case InternalType.I4:
				case InternalType.SZArray:
				case InternalType.Array:
					if (assignee.IsRegisterSet)
						this.assembly.MOV (Assembly.GetRegister (assignee.Register), R32.EAX);
					else
						this.assembly.MOV (new DWordMemory (this.GetAddress (assignee)), R32.EAX);

					break;

				case InternalType.I8:
					Memory assigneeMemory = this.GetAddress (assignee);
					DWordMemory low = new DWordMemory (assigneeMemory);
					this.assembly.MOV (low, R32.EAX);

					DWordMemory high = new DWordMemory (assigneeMemory);
					high.DisplacementDelta = 4;
					this.assembly.MOV (high, R32.EDX);

					break;

				case InternalType.ValueType:
					// It is already handled above
					break;

				default:
					throw new NotImplementedEngineException ("Call assignee handling for InternalType." + assignee.InternalType);
				}
			}
		}
Esempio n. 4
0
		/// <summary>
		/// Implements the 'mul' IL instruction, which pops two values, multiplies them, and pushes
		/// the result.
		/// </summary>
		private void Mul (IR.Instructions.Mul instruction)
		{
			IR.Operands.Register assignee = instruction.Def as IR.Operands.Register;
			IR.Operands.Register first = instruction.Use [0] as IR.Operands.Register;
			IR.Operands.Register second = instruction.Use [1] as IR.Operands.Register;

			switch (assignee.InternalType) {
			case InternalType.I:
			case InternalType.I4:
				if (first.IsRegisterSet)
					this.assembly.MOV (R32.EAX, Assembly.GetRegister (first.Register));
				else
					this.assembly.MOV (R32.EAX, new DWordMemory (this.GetAddress (first)));

				if (instruction.MulType == IR.Instructions.Mul.Type.Mul || instruction.MulType == IR.Instructions.Mul.Type.MulUnsignedWithOverflowCheck ) {
					if (second.IsRegisterSet)
						this.assembly.IMUL (R32.EAX, Assembly.GetRegister (second.Register));
					else
						this.assembly.IMUL (R32.EAX, new DWordMemory (this.GetAddress (second)));
				} else
					throw new NotImplementedEngineException ("Mul not supported for Mul.Type." + instruction.MulType);

				if (assignee.IsRegisterSet)
					this.assembly.MOV (Assembly.GetRegister (assignee.Register), R32.EAX);
				else
					this.assembly.MOV (new DWordMemory (this.GetAddress (assignee)), R32.EAX);

				break;

			case InternalType.I8:
				if (instruction.MulType == IR.Instructions.Mul.Type.Mul) {
					Memory firstMemory = this.GetAddress (first);
					DWordMemory firstHigh = new DWordMemory (firstMemory);
					firstHigh.DisplacementDelta = 4;
					DWordMemory firstLow = new DWordMemory (firstMemory);

					Memory secondMemory = this.GetAddress (second);
					DWordMemory secondHigh = new DWordMemory (secondMemory);
					secondHigh.DisplacementDelta = 4;
					DWordMemory secondLow = new DWordMemory (secondMemory);

					this.assembly.PUSH (secondHigh);
					this.assembly.PUSH (secondLow);
					this.assembly.PUSH (firstHigh);
					this.assembly.PUSH (firstLow);
					this.assembly.CALL (Assembly.HELPER_LMUL);
					this.assembly.ADD (R32.ESP, 16);

					Memory assigneeMemory = this.GetAddress (assignee);
					this.assembly.MOV (new DWordMemory (assigneeMemory), R32.EAX);
					assigneeMemory.DisplacementDelta = 4;
					this.assembly.MOV (new DWordMemory (assigneeMemory), R32.EDX);
				} else
					throw new NotImplementedEngineException ("Mul not supported for Mul.Type." + instruction.MulType);

				break;

			default:
				throw new NotImplementedEngineException ("Mul not supported for InternalType." + assignee.InternalType);
			}
		}
Esempio n. 5
0
		/// <summary>
		///
		/// </summary>
		private void ConditionCheck (IR.Instructions.ConditionCheck instruction)
		{
			IR.Operands.Register assignee = instruction.Def as IR.Operands.Register;
			IR.Operands.Register first = instruction.Use [0] as IR.Operands.Register;
			IR.Operands.Register second = instruction.Use [1] as IR.Operands.Register;

			string errorLabel = assembly.GetCMPLabel;
			string okLabel = assembly.GetCMPLabel;
			string endLabel = assembly.GetCMPLabel;

			switch (first.InternalType) {
			case InternalType.M:
			case InternalType.O:
			case InternalType.I:
			case InternalType.I4:
			case InternalType.SZArray:
			case InternalType.Array:
				if (first.IsRegisterSet)
					this.assembly.MOV (R32.EAX, Assembly.GetRegister (first.Register));
				else
					this.assembly.MOV (R32.EAX, new DWordMemory (this.GetAddress (first)));

				if (second.IsRegisterSet)
					this.assembly.MOV (R32.EDX, Assembly.GetRegister (second.Register));
				else
					this.assembly.MOV (R32.EDX, new DWordMemory (this.GetAddress (second)));

				this.assembly.CMP (R32.EAX, R32.EDX);

				RelationalTypeCMP (instruction.RelationalType, okLabel);

				break;

			case InternalType.I8:
				DWordMemory firstAddress = new DWordMemory (this.GetAddress (first));
				firstAddress.DisplacementDelta = 4;

				DWordMemory secondAddress = new DWordMemory (this.GetAddress (second));
				secondAddress.DisplacementDelta = 4;

				this.assembly.MOV (R32.EAX, firstAddress);
				this.assembly.MOV (R32.EDX, secondAddress);
				this.assembly.CMP (R32.EAX, R32.EDX);

				RelationalTypeCMP (instruction.RelationalType, okLabel, errorLabel);

				this.assembly.MOV (R32.EAX, new DWordMemory (this.GetAddress (first)));
				this.assembly.MOV (R32.EDX, new DWordMemory (this.GetAddress (second)));
				this.assembly.CMP (R32.EAX, R32.EDX);

				RelationalTypeCMP (instruction.RelationalType, okLabel);

				break;

			default:
				throw new NotImplementedEngineException ("ConditionCheck for " + first.InternalType.ToString() + " and " + second.InternalType.ToString());
			}

			assembly.LABEL (errorLabel);
			this.assembly.XOR (R32.ECX, R32.ECX);
			this.assembly.JMP (endLabel);

			assembly.LABEL (okLabel);
			this.assembly.XOR (R32.ECX, R32.ECX);
			this.assembly.INC (R32.ECX);

			this.assembly.LABEL (endLabel);

			if (assignee.IsRegisterSet)
				this.assembly.MOV (Assembly.GetRegister (assignee.Register), R32.ECX);
			else
				this.assembly.MOV (new DWordMemory (this.GetAddress (assignee)), R32.ECX);
		}
Esempio n. 6
0
		/// <summary>
		/// Implements the 'conv' family of IL instructions, which handle conversions between primitive data types.
		/// </summary>
		private void Convert (IR.Instructions.Convert instruction)
		{
			IR.Operands.Register assignee = instruction.Def as IR.Operands.Register;
			IR.Operands.Register value = instruction.Use [0] as IR.Operands.Register;

			switch (value.InternalType) {
			case InternalType.M:
			case InternalType.I:
			case InternalType.U:
			case InternalType.I4:
				switch (instruction.ConvertType) {
				case SharpOS.AOT.IR.Instructions.Convert.Type.Conv_I1:
				case SharpOS.AOT.IR.Instructions.Convert.Type.Conv_U1:
					if (value.IsRegisterSet)
						this.assembly.MOV (R32.EAX, Assembly.GetRegister (value.Register));
					else
						this.assembly.MOV (R32.EAX, new DWordMemory (this.GetAddress (value)));

					this.assembly.AND (R32.EAX, (uint) 0xFF);

					if (assignee.IsRegisterSet)
						this.assembly.MOV (Assembly.GetRegister (assignee.Register), R32.EAX);
					else
						this.assembly.MOV (new DWordMemory (this.GetAddress (assignee)), R32.EAX);
					break;

				case SharpOS.AOT.IR.Instructions.Convert.Type.Conv_I2:
				case SharpOS.AOT.IR.Instructions.Convert.Type.Conv_U2:
					if (value.IsRegisterSet)
						this.assembly.MOV (R32.EAX, Assembly.GetRegister (value.Register));
					else
						this.assembly.MOV (R32.EAX, new DWordMemory (this.GetAddress (value)));

					this.assembly.AND (R32.EAX, (uint) 0xFFFF);

					if (assignee.IsRegisterSet)
						this.assembly.MOV (Assembly.GetRegister (assignee.Register), R32.EAX);
					else
						this.assembly.MOV (new DWordMemory (this.GetAddress (assignee)), R32.EAX);
					break;

				case SharpOS.AOT.IR.Instructions.Convert.Type.Conv_I:
				case SharpOS.AOT.IR.Instructions.Convert.Type.Conv_I4:
				case SharpOS.AOT.IR.Instructions.Convert.Type.Conv_U:
				case SharpOS.AOT.IR.Instructions.Convert.Type.Conv_U4:
					if (value.IsRegisterSet)
						this.assembly.MOV (R32.EAX, Assembly.GetRegister (value.Register));
					else
						this.assembly.MOV (R32.EAX, new DWordMemory (this.GetAddress (value)));

					if (assignee.IsRegisterSet)
						this.assembly.MOV (Assembly.GetRegister (assignee.Register), R32.EAX);
					else
						this.assembly.MOV (new DWordMemory (this.GetAddress (assignee)), R32.EAX);

					break;

				case SharpOS.AOT.IR.Instructions.Convert.Type.Conv_I8:
				case SharpOS.AOT.IR.Instructions.Convert.Type.Conv_U8:
					if (value.IsRegisterSet)
						this.assembly.MOV (R32.EAX, Assembly.GetRegister (value.Register));
					else
						this.assembly.MOV (R32.EAX, new DWordMemory (this.GetAddress (value)));

					Memory memory = this.GetAddress (assignee);
					DWordMemory low = new DWordMemory (memory);
					this.assembly.MOV (low, R32.EAX);

					DWordMemory high = new DWordMemory (memory);
					high.DisplacementDelta = 4;
					this.assembly.XOR (R32.EAX, R32.EAX);
					this.assembly.MOV (high, R32.EAX);

					break;

				default:
					throw new NotImplementedEngineException ("The conversion from " + value.InternalType +
						" to " + instruction.ConvertType + " is not yet supported.");
				}

				break;

			case InternalType.I8:
				switch (instruction.ConvertType) {
				case SharpOS.AOT.IR.Instructions.Convert.Type.Conv_I:
				case SharpOS.AOT.IR.Instructions.Convert.Type.Conv_U:
				case SharpOS.AOT.IR.Instructions.Convert.Type.Conv_I4:
				case SharpOS.AOT.IR.Instructions.Convert.Type.Conv_U4:
					this.assembly.MOV (R32.EAX, new DWordMemory (this.GetAddress (value)));

					if (assignee.IsRegisterSet)
						this.assembly.MOV (Assembly.GetRegister (assignee.Register), R32.EAX);
					else
						this.assembly.MOV (new DWordMemory (this.GetAddress (assignee)), R32.EAX);

					break;

				case SharpOS.AOT.IR.Instructions.Convert.Type.Conv_I1:
				case SharpOS.AOT.IR.Instructions.Convert.Type.Conv_U1:
					this.assembly.MOV (R32.EAX, new DWordMemory (this.GetAddress (value)));

					this.assembly.AND (R32.EAX, (uint) 0xFF);

					if (assignee.IsRegisterSet)
						this.assembly.MOV (Assembly.GetRegister (assignee.Register), R32.EAX);
					else
						this.assembly.MOV (new DWordMemory (this.GetAddress (assignee)), R32.EAX);
					break;

				case SharpOS.AOT.IR.Instructions.Convert.Type.Conv_Ovf_I:
				case SharpOS.AOT.IR.Instructions.Convert.Type.Conv_Ovf_I4:
					string exceptLabel = this.assembly.GetCMPLabel;
					string okLabel = this.assembly.GetCMPLabel;
					DWordMemory upper =
						new DWordMemory (this.GetAddress (value));

					upper.DisplacementDelta = 4;

					// Check if it will overflow

					this.assembly.MOV (R32.EAX, upper);
					this.assembly.CMP (R32.EAX, 0);
					this.assembly.JNE (exceptLabel);

					// Handle the conversion

					this.assembly.MOV (R32.EAX, new DWordMemory (this.GetAddress (value)));

					if (assignee.IsRegisterSet)
						this.assembly.MOV (Assembly.GetRegister (assignee.Register), R32.EAX);
					else
						this.assembly.MOV (new DWordMemory (this.GetAddress (assignee)), R32.EAX);

					this.assembly.JMP (okLabel);

					// Conversion overflows, throw exception.

					this.assembly.LABEL (exceptLabel);
					this.assembly.CALL (this.assembly.Engine.OverflowHandler.AssemblyLabel);

					this.assembly.LABEL (okLabel);

					break;
				default:
					throw new NotImplementedEngineException ("The conversion from " + value.InternalType +
						" to " + instruction.ConvertType + " is not yet supported.");
				}

				break;

			default:
				throw new NotImplementedEngineException ("Convert not supported from value type InternalType." + value.InternalType);
			}
		}
Esempio n. 7
0
        private void PushOperand(Operand operand)
        {
            if (operand is IntConstant)
            {
                Int32 value = System.Convert.ToInt32((operand as IntConstant).Value);

                assembly.PUSH((UInt32)value);
            }
            else if (operand is LongConstant)
            {
                Int64 value = System.Convert.ToInt64((operand as LongConstant).Value);

                assembly.PUSH((UInt32)(value >> 32));
                assembly.PUSH((UInt32)(value & 0xFFFFFFFF));
            }
            else if (operand is IR.Operands.Register)
            {
                IR.Operands.Register identifier = operand as IR.Operands.Register;

                switch (identifier.InternalType)
                {
                case InternalType.SZArray:
                case InternalType.Array:
                case InternalType.I:
                case InternalType.O:
                case InternalType.M:
                case InternalType.I4:
                    if (identifier.IsRegisterSet)
                    {
                        this.assembly.PUSH(Assembly.GetRegister(identifier.Register));
                    }

                    else
                    {
                        this.assembly.PUSH(new DWordMemory(this.GetAddress(identifier)));
                    }

                    break;

                case InternalType.I8:
                    Memory memory = this.GetAddress(identifier);

                    DWordMemory high = new DWordMemory(memory);
                    high.DisplacementDelta = 4;
                    assembly.PUSH(new DWordMemory(high));

                    DWordMemory low = new DWordMemory(memory);
                    assembly.PUSH(low);

                    break;

                case InternalType.ValueType:
                    int size = this.method.Engine.GetTypeSize(identifier.Type.ToString());

                    uint pushSize = (uint)size;

                    if (pushSize % 4 != 0)
                    {
                        pushSize = (uint)(((pushSize / this.assembly.IntSize) + 1) * this.assembly.IntSize);
                    }

                    this.assembly.SUB(R32.ESP, pushSize);

                    this.assembly.PUSH(R32.ESI);
                    this.assembly.PUSH(R32.EDI);
                    this.assembly.PUSH(R32.ECX);

                    this.assembly.LEA(R32.ESI, new DWordMemory(this.GetAddress(identifier)));

                    // The 3 push above changed the ESP so we need a LEA = ESP + 12
                    this.assembly.LEA(R32.EDI, new Memory(null, R32.ESP, null, 0, 12));
                    this.assembly.MOV(R32.ECX, (uint)size);

                    this.assembly.CLD();
                    this.assembly.REP();
                    this.assembly.MOVSB();

                    this.assembly.POP(R32.ECX);
                    this.assembly.POP(R32.EDI);
                    this.assembly.POP(R32.ESI);
                    break;

                default:
                    throw new NotImplementedEngineException("'" + operand + "' is not supported.");
                }
            }
            else
            {
                throw new NotImplementedEngineException("'" + operand + "' is not supported.");
            }
        }
Esempio n. 8
0
		/// <summary>
		/// SHRD mem32,reg32,CL
		/// </summary>
		public static void SHRD___CL (DWordMemory target, R32Type source)
		{
		}
Esempio n. 9
0
		/// <summary>
		/// MUL mem32
		/// </summary>
		public static void MUL (DWordMemory target)
		{
		}
Esempio n. 10
0
		/// <summary>
		/// MOV segreg,mem32
		/// </summary>
		public static void MOV (SegType target, DWordMemory source)
		{
		}
Esempio n. 11
0
		/// <summary>
		/// MOV mem32,segreg
		/// </summary>
		public static void MOV (DWordMemory target, SegType source)
		{
		}
Esempio n. 12
0
		/// <summary>
		/// JMP FAR mem32
		/// </summary>
		public static void JMP_FAR (DWordMemory target)
		{
		}
Esempio n. 13
0
		/// <summary>
		/// INC mem32
		/// </summary>
		public static void INC (DWordMemory target)
		{
		}
Esempio n. 14
0
		/// <summary>
		/// IMUL reg32,mem32,imm32
		/// </summary>
		public static void IMUL (R32Type target, DWordMemory source, UInt32 value)
		{
		}
Esempio n. 15
0
		/// <summary>
		/// IDIV mem32
		/// </summary>
		public static void IDIV (DWordMemory target)
		{
		}
Esempio n. 16
0
		/// <summary>
		/// FSUBR mem32
		/// </summary>
		public static void FSUBR (DWordMemory target)
		{
		}
Esempio n. 17
0
		/// <summary>
		/// SHRD mem32,reg32,imm8
		/// </summary>
		public static void SHRD (DWordMemory target, R32Type source, Byte value)
		{
		}
Esempio n. 18
0
		/// <summary>
		/// NOT mem32
		/// </summary>
		public static void NOT (DWordMemory target)
		{
		}
Esempio n. 19
0
		/// <summary>
		/// SUB mem32,reg32
		/// </summary>
		public static void SUB (DWordMemory target, R32Type source)
		{
		}
Esempio n. 20
0
		/// <summary>
		/// POP mem32
		/// </summary>
		public static void POP (DWordMemory target)
		{
		}
Esempio n. 21
0
		/// <summary>
		/// PUSH mem32
		/// </summary>
		public static void PUSH (DWordMemory target)
		{
		}
Esempio n. 22
0
		/// <summary>
		/// ROL mem32,CL
		/// </summary>
		public static void ROL__CL (DWordMemory target)
		{
		}
Esempio n. 23
0
		/// <summary>
		/// Implements the 'branch' family of IL instructions.
		/// </summary>
		private void Branch (IR.Instructions.Branch instruction)
		{
			string okLabel = this.GetLabel (instruction.Block.Outs [0]);
			string errorLabel = this.GetLabel (instruction.Block.Outs [1]);

			IR.Operands.Register first = instruction.Use [0] as IR.Operands.Register;
			IR.Operands.Register second = instruction.Use [1] as IR.Operands.Register;

			switch (first.InternalType) {
			case InternalType.I:
			case InternalType.O:
			case InternalType.M:
			case InternalType.I4:
			case InternalType.SZArray:
				if (first.IsRegisterSet)
					this.assembly.MOV (R32.EAX, Assembly.GetRegister (first.Register));
				else
					this.assembly.MOV (R32.EAX, new DWordMemory (this.GetAddress (first)));

				if (second.IsRegisterSet)
					this.assembly.MOV (R32.EDX, Assembly.GetRegister (second.Register));
				else
					this.assembly.MOV (R32.EDX, new DWordMemory (this.GetAddress (second)));

				this.assembly.CMP (R32.EAX, R32.EDX);

				this.RelationalTypeCMP (instruction.RelationalType, okLabel);

				break;

			case InternalType.I8:
				DWordMemory firstAddress = new DWordMemory (this.GetAddress (first));
				firstAddress.DisplacementDelta = 4;

				DWordMemory secondAddress = new DWordMemory (this.GetAddress (second));
				secondAddress.DisplacementDelta = 4;

				this.assembly.MOV (R32.EAX, firstAddress);
				this.assembly.MOV (R32.EDX, secondAddress);
				this.assembly.CMP (R32.EAX, R32.EDX);

				RelationalTypeCMP (instruction.RelationalType, okLabel, errorLabel);

				this.assembly.MOV (R32.EAX, new DWordMemory (this.GetAddress (first)));
				this.assembly.MOV (R32.EDX, new DWordMemory (this.GetAddress (second)));
				this.assembly.CMP (R32.EAX, R32.EDX);

				RelationalTypeCMP (instruction.RelationalType, okLabel);

				break;

			default:
				throw new NotImplementedEngineException ("Branch not supported for InternalType." + first.InternalType);
			}
		}
Esempio n. 24
0
		/// <summary>
		/// SBB reg32,mem32
		/// </summary>
		public static void SBB (R32Type target, DWordMemory source)
		{
		}
Esempio n. 25
0
		/// <summary>
		/// Implements the 'dup' IR instruction, which duplicates the top value on the evaluation stack.
		/// </summary>
		private void Dup (IR.Instructions.Dup instruction)
		{
			IR.Operands.Register assignee = instruction.Def as IR.Operands.Register;
			IR.Operands.Register value = instruction.Use [0] as IR.Operands.Register;

			switch (assignee.InternalType) {
			case InternalType.I:
			case InternalType.O:
			case InternalType.M:
			case InternalType.I4:
			case InternalType.SZArray:
			case InternalType.Array:
				if (value.IsRegisterSet)
					this.assembly.MOV (R32.EAX, Assembly.GetRegister (value.Register));
				else
					this.assembly.MOV (R32.EAX, new DWordMemory (this.GetAddress (value)));

				if (assignee.IsRegisterSet)
					this.assembly.MOV (Assembly.GetRegister (assignee.Register), R32.EAX);
				else
					this.assembly.MOV (new DWordMemory (this.GetAddress (assignee)), R32.EAX);

				break;

			case InternalType.I8:
				Memory sourceMemory = this.GetAddress (value);
				DWordMemory source = new DWordMemory (sourceMemory);
				source.DisplacementDelta = 4;

				Memory destinationMemory = this.GetAddress (assignee);
				DWordMemory destination = new DWordMemory (destinationMemory);
				destination.DisplacementDelta = 4;

				this.assembly.MOV (R32.EAX, source);
				this.assembly.MOV (destination, R32.EAX);

				this.assembly.MOV (R32.EAX, new DWordMemory (sourceMemory));
				this.assembly.MOV (new DWordMemory (destinationMemory), R32.EAX);
				break;

			default:
				throw new NotImplementedEngineException ("Dup not supported for InternalType." + assignee.InternalType);
			}
		}
Esempio n. 26
0
		/// <summary>
		/// SBB mem32,imm32
		/// </summary>
		public static void SBB (DWordMemory target, UInt32 source)
		{
		}
Esempio n. 27
0
		/// <summary>
		/// Implements the 'shr' IL instruction, which pops two values from the stack,
		/// right-bit-shifts the first by the amount defined in the second, and pushes
		/// the result.
		/// </summary>
		private void Shr (IR.Instructions.Shr instruction)
		{
			IR.Operands.Register assignee = instruction.Def as IR.Operands.Register;
			IR.Operands.Register first = instruction.Use [0] as IR.Operands.Register;
			IR.Operands.Register second = instruction.Use [1] as IR.Operands.Register;

			switch (assignee.InternalType) {
			case InternalType.I:
			case InternalType.I4:
				if (first.IsRegisterSet)
					this.assembly.MOV (R32.EAX, Assembly.GetRegister (first.Register));
				else
					this.assembly.MOV (R32.EAX, new DWordMemory (this.GetAddress (first)));

				if (second.IsRegisterSet)
					this.assembly.MOV (R32.ECX, Assembly.GetRegister (second.Register));
				else
					this.assembly.MOV (R32.ECX, new DWordMemory (this.GetAddress (second)));

				this.assembly.AND (R32.ECX, (uint) 0xFF);

				if (instruction.ShrType == IR.Instructions.Shr.Type.SHR)
					this.assembly.SAR__CL (R32.EAX);

				else if (instruction.ShrType == IR.Instructions.Shr.Type.SHRUnsigned)
					this.assembly.SHR__CL (R32.EAX);

				else
					throw new NotImplementedEngineException ("Shr not supported for Shr.Type." + instruction.ShrType);

				if (assignee.IsRegisterSet)
					this.assembly.MOV (Assembly.GetRegister (assignee.Register), R32.EAX);
				else
					this.assembly.MOV (new DWordMemory (this.GetAddress (assignee)), R32.EAX);

				break;

			case InternalType.I8:
				Memory firstMemory = this.GetAddress (first);
				DWordMemory high = new DWordMemory (firstMemory);
				high.DisplacementDelta = 4;
				DWordMemory low = new DWordMemory (firstMemory);

				if (second.IsRegisterSet)
					this.assembly.PUSH (Assembly.GetRegister (second.Register));
				else
					this.assembly.PUSH (new DWordMemory (this.GetAddress (second)));

				this.assembly.PUSH (high);
				this.assembly.PUSH (low);

				if (instruction.ShrType == IR.Instructions.Shr.Type.SHR)
					this.assembly.CALL (Assembly.HELPER_LSAR);

				else if (instruction.ShrType == IR.Instructions.Shr.Type.SHRUnsigned)
					this.assembly.CALL (Assembly.HELPER_LSHR);

				else
					throw new NotImplementedEngineException ("Shr not supported for Shr.Type." + instruction.ShrType);

				this.assembly.ADD (R32.ESP, 12);

				Memory assigneeMemory = this.GetAddress (assignee);
				this.assembly.MOV (new DWordMemory (assigneeMemory), R32.EAX);
				assigneeMemory.DisplacementDelta = 4;
				this.assembly.MOV (new DWordMemory (assigneeMemory), R32.EDX);

				break;

			default:
				throw new NotImplementedEngineException ("Shr not supported for InternalType." + assignee.InternalType);
			}
		}
Esempio n. 28
0
		/// <summary>
		/// SHR mem32,CL
		/// </summary>
		public static void SHR__CL (DWordMemory target)
		{
		}
Esempio n. 29
0
		/// <summary>
		/// Implements the 'ret' IL instruction.
		/// </summary>
		/// <param name="block">The block.</param>
		/// <param name="instruction">The instruction.</param>
		private void Return (SharpOS.AOT.IR.Instructions.Return instruction)
		{
			if (instruction.Use != null) {
				IR.Operands.Register value = instruction.Use [0] as IR.Operands.Register;

				switch (value.InternalType) {
				case InternalType.I:
				case InternalType.M:
				case InternalType.O:
				case InternalType.I4:
				case InternalType.SZArray:
				case InternalType.Array:
					if (value.IsRegisterSet)
						this.assembly.MOV (R32.EAX, Assembly.GetRegister (value.Register));
					else
						this.assembly.MOV (R32.EAX, new DWordMemory (this.GetAddress (value)));

					break;

				case InternalType.I8:
					Memory assigneeMemory = this.GetAddress (value);
					DWordMemory low = new DWordMemory (assigneeMemory);
					this.assembly.MOV (R32.EAX, low);

					DWordMemory high = new DWordMemory (assigneeMemory);
					high.DisplacementDelta = 4;
					this.assembly.MOV (R32.EDX, high);

					break;

				case InternalType.ValueType:
					int size = this.method.Engine.GetTypeSize (instruction.Block.Method.ReturnType.TypeFullName, 4) / 4;

					this.assembly.PUSH (R32.ECX);
					this.assembly.PUSH (R32.ESI);
					this.assembly.PUSH (R32.EDI);

					if (value.IsRegisterSet)
						this.assembly.MOV (R32.ESI, Assembly.GetRegister (value.Register));
					else
						this.assembly.LEA (R32.ESI, new DWordMemory (this.GetAddress (value)));

					this.assembly.MOV (R32.EDI, new DWordMemory (null, R32.EBP, null, 0, 8));

					this.assembly.MOV (R32.ECX, (uint) size);

					this.assembly.CLD ();
					this.assembly.REP ();
					this.assembly.MOVSD ();

					this.assembly.POP (R32.EDI);
					this.assembly.POP (R32.ESI);
					this.assembly.POP (R32.ECX);

					break;

				default:
					throw new NotImplementedEngineException ("'" + instruction + "' is not supported.");
				}
			}

			assembly.JMP (method.MethodFullName + " exit");
		}
Esempio n. 30
0
		/// <summary>
		/// BTC mem32,imm8
		/// </summary>
		public static void BTC (DWordMemory target, Byte source)
		{
		}
Esempio n. 31
0
		/// <summary>
		/// Common implementations which pop a value from the IL evaluation stack and save it in another means
		/// of storage (such as stloc, stind, starg).
		/// </summary>
		private void Save (Class _class, InternalType destinationType, Memory memory, IR.Operands.Register value)
		{
			switch (destinationType) {
			case InternalType.I1:
				if (value.IsRegisterSet)
					this.assembly.MOV (R32.EAX, Assembly.GetRegister (value.Register));

				else
					this.assembly.MOV (R32.EAX, new DWordMemory (this.GetAddress (value)));

				this.assembly.MOV (new ByteMemory (memory), R8.AL);

				break;

			case InternalType.U1:
				if (value.IsRegisterSet)
					this.assembly.MOV (R32.EAX, Assembly.GetRegister (value.Register));

				else
					this.assembly.MOV (R32.EAX, new DWordMemory (this.GetAddress (value)));

				this.assembly.MOV (new ByteMemory (memory), R8.AL);

				break;

			case InternalType.I2:
				if (value.IsRegisterSet)
					this.assembly.MOV (R32.EAX, Assembly.GetRegister (value.Register));

				else
					this.assembly.MOV (R32.EAX, new DWordMemory (this.GetAddress (value)));

				this.assembly.MOV (new WordMemory (memory), R16.AX);

				break;

			case InternalType.U2:
				if (value.IsRegisterSet)
					this.assembly.MOV (R32.EAX, Assembly.GetRegister (value.Register));

				else
					this.assembly.MOV (R32.EAX, new DWordMemory (this.GetAddress (value)));

				this.assembly.MOV (new WordMemory (memory), R16.AX);

				break;

			case InternalType.I4:
			case InternalType.U4:
			case InternalType.I:
			case InternalType.U:
			case InternalType.O:
			case InternalType.SZArray:
			case InternalType.Array:
				if (value.IsRegisterSet)
					this.assembly.MOV (R32.EAX, Assembly.GetRegister (value.Register));

				else
					this.assembly.MOV (R32.EAX, new DWordMemory (this.GetAddress (value)));

				this.assembly.MOV (new DWordMemory (memory), R32.EAX);

				break;

			case InternalType.I8:
			case InternalType.U8:
				Memory source = this.GetAddress (value);
				source.DisplacementDelta = 4;

				DWordMemory destination = new DWordMemory (memory);
				destination.DisplacementDelta = 4;

				this.assembly.MOV (R32.EAX, new DWordMemory (this.GetAddress (value)));
				this.assembly.MOV (new DWordMemory (memory), R32.EAX);

				this.assembly.MOV (R32.EAX, new DWordMemory (source));
				this.assembly.MOV (new DWordMemory (destination), R32.EAX);
				break;

			case InternalType.ValueType:
				uint size = (uint) this.method.Engine.GetTypeSize (_class.TypeFullName, 4);

				if (size == 4) {
					if (value.IsRegisterSet)
						this.assembly.MOV (R32.EAX, Assembly.GetRegister (value.Register));
					else
						this.assembly.MOV (R32.EAX, new DWordMemory (this.GetAddress (value)));

					this.assembly.MOV (new DWordMemory (memory), R32.EAX);

				} else {
					this.assembly.PUSH (R32.ECX);
					this.assembly.PUSH (R32.ESI);
					this.assembly.PUSH (R32.EDI);

					if (value.IsRegisterSet)
						this.assembly.MOV (R32.ESI, Assembly.GetRegister (value.Register));
					else
						this.assembly.LEA (R32.ESI, new DWordMemory (this.GetAddress (value)));

					this.assembly.LEA (R32.EDI, new DWordMemory (memory));

					this.assembly.MOV (R32.ECX, size);

					this.assembly.CLD ();
					this.assembly.REP ();
					this.assembly.MOVSB ();

					this.assembly.POP (R32.EDI);
					this.assembly.POP (R32.ESI);
					this.assembly.POP (R32.ECX);
				}
				break;

			case InternalType.R4:
			case InternalType.R8:
			case InternalType.F:
			case InternalType.M:
			case InternalType.TypedReference:
			default:
				throw new NotImplementedEngineException ("Save not supported for InternalType." + destinationType);
			}
		}
Esempio n. 32
0
		/// <summary>
		/// FSTP mem32
		/// </summary>
		public static void FSTP (DWordMemory target)
		{
		}