Cosmos/source/Cosmos.IL2CPU/IL/Ldobj.cs
José Pedro f8e18e3fbc Fixed StringHelper.GetNumberString().
Changes in Conv*, Ld* and St* opcodes so that values with size < 4 bytes are extended to 4 bytes.
Implemented Not and Xor for values with size 8 bytes.
Added tests for bitwise operations, arithmetic operations and Conv* opcodes.
2017-01-24 20:54:07 +00:00

70 lines
2 KiB
C#

using System;
using CPUx86 = Cosmos.Assembler.x86;
using Cosmos.IL2CPU.ILOpCodes;
using XSharp.Compiler;
using static XSharp.Compiler.XSRegisters;
namespace Cosmos.IL2CPU.X86.IL
{
[Cosmos.IL2CPU.OpCode( ILOpCode.Code.Ldobj )]
public class Ldobj : ILOp
{
public Ldobj( Cosmos.Assembler.Assembler aAsmblr )
: base( aAsmblr )
{
}
public override void Execute( MethodInfo aMethod, ILOpCode aOpCode )
{
DoNullReferenceCheck(Assembler, DebugEnabled, 0);
OpType xType = (OpType)aOpCode;
DoAssemble(xType.Value);
}
public static void DoAssemble(Type type)
{
if (type == null)
{
throw new ArgumentNullException("type");
}
XS.Pop(EAX);
var xObjSize = GetStorageSize(type);
switch (xObjSize % 4)
{
case 1:
{
XS.Xor(EBX, EBX);
XS.Set(BL, EAX, sourceDisplacement: (int)(xObjSize - 1));
//XS.ShiftLeft(XSRegisters.EBX, 24);
XS.Push(EBX);
break;
}
case 2:
{
XS.Xor(EBX, EBX);
XS.Set(BX, EAX, sourceDisplacement: (int)(xObjSize - 2));
//XS.ShiftLeft(XSRegisters.EBX, 16);
XS.Push(EBX);
break;
}
case 0:
{
break;
}
default:
throw new Exception("Remainder not supported!");
}
xObjSize -= (xObjSize % 4);
for (int i = 1; i <= (xObjSize / 4); i++)
{
new CPUx86.Push {DestinationReg = CPUx86.RegistersEnum.EAX, DestinationIsIndirect = true, DestinationDisplacement = (int)(xObjSize - (i * 4))};
}
}
}
}