using System; using CPU = Indy.IL2CPU.Assembler; using CPUx86 = Indy.IL2CPU.Assembler.X86; namespace Indy.IL2CPU.IL.X86 { // todo: Improve 8byte support [OpCode(OpCodeEnum.Shr)] public class Shr: Op { private string mLabelName; public Shr(ILReader aReader, MethodInformation aMethodInfo) : base(aReader, aMethodInfo) { mLabelName= GetInstructionLabel(aReader); } public override void DoAssemble() { var xStackItem_ShiftAmount = Assembler.StackContents.Pop(); var xStackItem_Value = Assembler.StackContents.Pop(); if (xStackItem_Value.IsFloat) { throw new NotImplementedException("Floats not yet supported!"); } if (xStackItem_Value.Size <= 4) { new CPUx86.Pop(CPUx86.Registers.EAX); // shift amount new CPUx86.Pop(CPUx86.Registers.EBX); // value new CPUx86.Move(CPUx86.Registers.CL, CPUx86.Registers.AL); new CPUx86.ShiftRight(CPUx86.Registers.EBX, CPUx86.Registers.CL); new CPUx86.Pushd(CPUx86.Registers.EBX); Assembler.StackContents.Push(xStackItem_Value); return; } if (xStackItem_Value.Size <= 8) { new CPUx86.Pop("edx"); new CPUx86.Move("eax", "0"); new CPU.Label(mLabelName + "__StartLoop"); new CPUx86.Compare("edx", "eax"); new CPUx86.JumpIfEqual(mLabelName + "__EndLoop"); new CPUx86.Move("ebx", "[esp]"); new CPUx86.Move("CL", "1"); new CPUx86.ShiftRight("ebx", "CL"); new CPUx86.Move("[esp]", "ebx"); new CPUx86.Move("CL", "1"); new CPUx86.RotateThroughCarryRight("dword [esp+4]"); new CPUx86.Add("eax", "1"); new CPUx86.Jump(mLabelName + "__StartLoop"); new CPU.Label(mLabelName + "__EndLoop"); Assembler.StackContents.Push(xStackItem_Value); return; } throw new NotImplementedException(); } } }