Cosmos/source/Compiler/Indy.IL2CPU.X86.Plugs/System/Assemblers/Array_InternalCopy.cs
mterwoord_cp b493bf136c
2009-09-12 16:49:12 +00:00

80 lines
6.6 KiB
C#

using System;
using System.Linq;
using Indy.IL2CPU.Plugs;
using Assembler = Cosmos.IL2CPU.Assembler;
using CPUx86 = Cosmos.IL2CPU.X86;
using CosCPUAll = Cosmos.IL2CPU;
using CosCPUx86 = Cosmos.IL2CPU.X86;
namespace Indy.IL2CPU.X86.Plugs.CustomImplementations.System.Assemblers {
public class Array_InternalCopy: AssemblerMethod {
/* void Copy(Array sourceArray, ebp + 0x1C
* int sourceIndex, ebp + 0x18
* Array destinationArray, ebp + 0x14
* int destinationIndex, ebp + 0x10
* int length, ebp + 0xC
* bool reliable); ebp + 0x8
*/
public override void Assemble(Indy.IL2CPU.Assembler.Assembler aAssembler) {
new CPUx86.Push { DestinationReg = CPUx86.Registers.EBP, DestinationIsIndirect = true, DestinationDisplacement = 0x1C };
new CPUx86.Add { DestinationReg = CPUx86.Registers.ESP, DestinationIsIndirect = true, SourceValue = 12, Size = 32 }; // pointer is at the element size
new CPUx86.Pop { DestinationReg = CPUx86.Registers.EAX };
new CPUx86.Move { DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.EAX, SourceIsIndirect = true }; // element size
new CPUx86.Move { DestinationReg = CPUx86.Registers.EBX, SourceReg = CPUx86.Registers.EBP, SourceIsIndirect = true, SourceDisplacement = 0x18 };
new CPUx86.Multiply { DestinationReg = CPUx86.Registers.EBX };
new CPUx86.Add { DestinationReg = CPUx86.Registers.EAX, SourceValue = 16 };
new CPUx86.Move { DestinationReg = CPUx86.Registers.ESI, SourceReg = CPUx86.Registers.EBP, SourceIsIndirect = true, SourceDisplacement = 0x1C };
new CPUx86.Add { DestinationReg = CPUx86.Registers.ESI, SourceReg = CPUx86.Registers.EAX }; // source ptr
new CPUx86.Push { DestinationReg = CPUx86.Registers.EBP, DestinationIsIndirect = true, DestinationDisplacement = 0x14 };
new CPUx86.Add { DestinationReg = CPUx86.Registers.ESP, DestinationIsIndirect = true, SourceValue = 12, Size = 32 }; // pointer is at element size
new CPUx86.Pop { DestinationReg = CPUx86.Registers.EAX };
new CPUx86.Move { DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.EAX, SourceIsIndirect = true };
new CPUx86.Move { DestinationReg = CPUx86.Registers.ECX, SourceReg = CPUx86.Registers.EBP, SourceIsIndirect = true, SourceDisplacement = 0x10 };
new CPUx86.Multiply { DestinationReg = CPUx86.Registers.ECX };
new CPUx86.Add { DestinationReg = CPUx86.Registers.EAX, SourceValue = 16 };
new CPUx86.Move { DestinationReg = CPUx86.Registers.EDI, SourceReg = CPUx86.Registers.EBP, SourceIsIndirect = true, SourceDisplacement = 0x14 };
new CPUx86.Add { DestinationReg = CPUx86.Registers.EDI, SourceReg = CPUx86.Registers.EAX };
// calculate byte count to copy
new CPUx86.Move { DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.EBP, SourceIsIndirect = true, SourceDisplacement = 0x14 };
new CPUx86.Add { DestinationReg = CPUx86.Registers.EAX, SourceValue = 12 };
new CPUx86.Move { DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.EAX, SourceIsIndirect = true };
new CPUx86.Move { DestinationReg = CPUx86.Registers.EDX, SourceReg = CPUx86.Registers.EBP, SourceIsIndirect = true, SourceDisplacement = 0xC };
new CPUx86.Multiply { DestinationReg = CPUx86.Registers.EDX };
new CPUx86.Move { DestinationReg = CPUx86.Registers.ECX, SourceReg = CPUx86.Registers.EAX, };
new CPUx86.Movs { Size = 8, Prefixes = CPUx86.InstructionPrefixes.Repeat };
}
public override void AssembleNew(object aAssembler) {
new CosCPUx86.Push { DestinationReg = CosCPUx86.Registers.EBP, DestinationIsIndirect = true, DestinationDisplacement = 0x1C };
new CosCPUx86.Add { DestinationReg = CosCPUx86.Registers.ESP, DestinationIsIndirect = true, SourceValue = 12, Size = 32 }; // pointer is at the element size
new CosCPUx86.Pop { DestinationReg = CosCPUx86.Registers.EAX };
new CosCPUx86.Move { DestinationReg = CosCPUx86.Registers.EAX, SourceReg = CosCPUx86.Registers.EAX, SourceIsIndirect = true }; // element size
new CosCPUx86.Move { DestinationReg = CosCPUx86.Registers.EBX, SourceReg = CosCPUx86.Registers.EBP, SourceIsIndirect = true, SourceDisplacement = 0x18 };
new CosCPUx86.Multiply { DestinationReg = CosCPUx86.Registers.EBX };
new CosCPUx86.Add { DestinationReg = CosCPUx86.Registers.EAX, SourceValue = 16 };
new CosCPUx86.Move { DestinationReg = CosCPUx86.Registers.ESI, SourceReg = CosCPUx86.Registers.EBP, SourceIsIndirect = true, SourceDisplacement = 0x1C };
new CosCPUx86.Add { DestinationReg = CosCPUx86.Registers.ESI, SourceReg = CosCPUx86.Registers.EAX }; // source ptr
new CosCPUx86.Push { DestinationReg = CosCPUx86.Registers.EBP, DestinationIsIndirect = true, DestinationDisplacement = 0x14 };
new CosCPUx86.Add { DestinationReg = CosCPUx86.Registers.ESP, DestinationIsIndirect = true, SourceValue = 12, Size = 32 }; // pointer is at element size
new CosCPUx86.Pop { DestinationReg = CosCPUx86.Registers.EAX };
new CosCPUx86.Move { DestinationReg = CosCPUx86.Registers.EAX, SourceReg = CosCPUx86.Registers.EAX, SourceIsIndirect = true };
new CosCPUx86.Move { DestinationReg = CosCPUx86.Registers.ECX, SourceReg = CosCPUx86.Registers.EBP, SourceIsIndirect = true, SourceDisplacement = 0x10 };
new CosCPUx86.Multiply { DestinationReg = CosCPUx86.Registers.ECX };
new CosCPUx86.Add { DestinationReg = CosCPUx86.Registers.EAX, SourceValue = 16 };
new CosCPUx86.Move { DestinationReg = CosCPUx86.Registers.EDI, SourceReg = CosCPUx86.Registers.EBP, SourceIsIndirect = true, SourceDisplacement = 0x14 };
new CosCPUx86.Add { DestinationReg = CosCPUx86.Registers.EDI, SourceReg = CosCPUx86.Registers.EAX };
// calculate byte count to copy
new CosCPUx86.Move { DestinationReg = CosCPUx86.Registers.EAX, SourceReg = CosCPUx86.Registers.EBP, SourceIsIndirect = true, SourceDisplacement = 0x14 };
new CosCPUx86.Add { DestinationReg = CosCPUx86.Registers.EAX, SourceValue = 12 };
new CosCPUx86.Move { DestinationReg = CosCPUx86.Registers.EAX, SourceReg = CosCPUx86.Registers.EAX, SourceIsIndirect = true };
new CosCPUx86.Move { DestinationReg = CosCPUx86.Registers.EDX, SourceReg = CosCPUx86.Registers.EBP, SourceIsIndirect = true, SourceDisplacement = 0xC };
new CosCPUx86.Multiply { DestinationReg = CosCPUx86.Registers.EDX };
new CosCPUx86.Move { DestinationReg = CosCPUx86.Registers.ECX, SourceReg = CosCPUx86.Registers.EAX, };
new CPUx86.Movs { Size = 8, Prefixes = CosCPUx86.InstructionPrefixes.Repeat };
}
}
}