mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-24 12:35:31 +00:00
This commit is contained in:
parent
49bd0d1383
commit
21ec33c46d
5 changed files with 115 additions and 74 deletions
|
|
@ -8,6 +8,7 @@ using NUnit.Framework;
|
||||||
namespace Indy.IL2CPU.Tests.Assembler.X86 {
|
namespace Indy.IL2CPU.Tests.Assembler.X86 {
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class HaltTests: BaseTest {
|
public class HaltTests: BaseTest {
|
||||||
|
[Test]
|
||||||
public void TestIt() {
|
public void TestIt() {
|
||||||
new Halt();
|
new Halt();
|
||||||
Verify();
|
Verify();
|
||||||
|
|
|
||||||
|
|
@ -5,33 +5,38 @@ using System.Text;
|
||||||
|
|
||||||
namespace Indy.IL2CPU.Assembler.X86 {
|
namespace Indy.IL2CPU.Assembler.X86 {
|
||||||
[OpCode("push")]
|
[OpCode("push")]
|
||||||
public class Push : InstructionWithDestination{
|
public class Push : InstructionWithDestination {
|
||||||
public static void InitializeEncodingData(Instruction.InstructionData aData) {
|
public static void InitializeEncodingData(Instruction.InstructionData aData) {
|
||||||
aData.EncodingOptions.Add(new InstructionData.InstructionEncodingOption {
|
aData.EncodingOptions.Add(new InstructionData.InstructionEncodingOption {
|
||||||
OpCode = new byte[] {0x50},
|
OpCode = new byte[] { 0x50 },
|
||||||
AllowedSizes = InstructionSizes.DWord,
|
AllowedSizes = InstructionSizes.DWord,
|
||||||
DestinationReg=Guid.Empty,
|
DestinationReg = Guid.Empty,
|
||||||
DestinationRegByte=0,
|
DestinationRegByte = 0,
|
||||||
DestinationRegBitShiftLeft=0
|
DestinationRegBitShiftLeft = 0
|
||||||
}); // register
|
}); // register
|
||||||
aData.EncodingOptions.Add(new InstructionData.InstructionEncodingOption {
|
aData.EncodingOptions.Add(new InstructionData.InstructionEncodingOption {
|
||||||
OpCode = new byte[] { 0x68 },
|
OpCode = new byte[] { 0x68 },
|
||||||
AllowedSizes = InstructionSizes.DWord,
|
AllowedSizes = InstructionSizes.DWord,
|
||||||
DestinationImmediate=true
|
DestinationImmediate = true
|
||||||
}); // immediate
|
}); // immediate
|
||||||
|
aData.EncodingOptions.Add(new InstructionData.InstructionEncodingOption {
|
||||||
|
AllowedSizes = InstructionSizes.DWord,
|
||||||
|
OpCode = new byte[] { 0xFF },
|
||||||
|
NeedsModRMByte = true,
|
||||||
|
DestinationMemory = true,
|
||||||
|
DefaultSize = InstructionSize.DWord,
|
||||||
|
InitialModRMByteValue = 0x30
|
||||||
|
}); // pop to memory
|
||||||
}
|
}
|
||||||
|
|
||||||
public Push()
|
public Push() {
|
||||||
{
|
|
||||||
//Changed without size
|
//Changed without size
|
||||||
//Size = 32;
|
//Size = 32;
|
||||||
}
|
}
|
||||||
public override string ToString()
|
public override string ToString() {
|
||||||
{
|
|
||||||
return this.mMnemonic + " dword " + this.GetDestinationAsString();
|
return this.mMnemonic + " dword " + this.GetDestinationAsString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,14 +18,15 @@ namespace Indy.IL2CPU.Assembler.X86 {
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum InstructionSize {
|
public enum InstructionSize {
|
||||||
None,
|
None = 0,
|
||||||
Byte,
|
Byte = 8,
|
||||||
Word,
|
Word = 16,
|
||||||
DWord,
|
DWord = 32,
|
||||||
QWord,
|
QWord = 64,
|
||||||
}
|
}
|
||||||
public class InstructionData {
|
public class InstructionData {
|
||||||
public class InstructionEncodingOption {
|
public class InstructionEncodingOption {
|
||||||
|
public Action<byte[], Instruction> ModifyBytes;
|
||||||
|
|
||||||
public byte[] OpCode;
|
public byte[] OpCode;
|
||||||
|
|
||||||
|
|
@ -34,6 +35,7 @@ namespace Indy.IL2CPU.Assembler.X86 {
|
||||||
/// which refer to <see cref="OpCode"/> bytes, can assume an extra ModRM byte.
|
/// which refer to <see cref="OpCode"/> bytes, can assume an extra ModRM byte.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool NeedsModRMByte;
|
public bool NeedsModRMByte;
|
||||||
|
public byte InitialModRMByteValue;
|
||||||
|
|
||||||
public InstructionSizes AllowedSizes;
|
public InstructionSizes AllowedSizes;
|
||||||
public InstructionSize DefaultSize = InstructionSize.DWord;
|
public InstructionSize DefaultSize = InstructionSize.DWord;
|
||||||
|
|
@ -110,7 +112,6 @@ namespace Indy.IL2CPU.Assembler.X86 {
|
||||||
mInstructionDatasLocker = new ReaderWriterLocker();
|
mInstructionDatasLocker = new ReaderWriterLocker();
|
||||||
using (mInstructionDatasLocker.AcquireWriterLock()) {
|
using (mInstructionDatasLocker.AcquireWriterLock()) {
|
||||||
mInstructionDatas = new SortedList<Type, InstructionData>(new TypeComparer());
|
mInstructionDatas = new SortedList<Type, InstructionData>(new TypeComparer());
|
||||||
int xInstructionsWithEncodingOptions = 0;
|
|
||||||
foreach (Type xType in typeof(Instruction).Assembly.GetTypes()) {
|
foreach (Type xType in typeof(Instruction).Assembly.GetTypes()) {
|
||||||
if (!xType.IsSubclassOf(typeof(Instruction))) {
|
if (!xType.IsSubclassOf(typeof(Instruction))) {
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -136,13 +137,9 @@ namespace Indy.IL2CPU.Assembler.X86 {
|
||||||
}
|
}
|
||||||
var xMethod = xType.GetMethod("InitializeEncodingData", new Type[] { typeof(InstructionData) });
|
var xMethod = xType.GetMethod("InitializeEncodingData", new Type[] { typeof(InstructionData) });
|
||||||
if (xMethod != null) {
|
if (xMethod != null) {
|
||||||
xMethod.Invoke(null, new object[]{xNewInstructionData});
|
xMethod.Invoke(null, new object[] { xNewInstructionData });
|
||||||
}
|
|
||||||
if (xNewInstructionData.EncodingOptions.Count > 0) {
|
|
||||||
xInstructionsWithEncodingOptions++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Console.WriteLine("Total Instructions = {0}, Instructions with encoding data = {1}", mInstructionDatas.Count, xInstructionsWithEncodingOptions);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -170,15 +167,15 @@ namespace Indy.IL2CPU.Assembler.X86 {
|
||||||
}
|
}
|
||||||
if (aInstructionData == null) {
|
if (aInstructionData == null) {
|
||||||
aEncodingOption = null;
|
aEncodingOption = null;
|
||||||
aInstructionData=null;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
aEncodingOption=null;
|
aEncodingOption = null;
|
||||||
for (int i = 0; i < aInstructionData.EncodingOptions.Count; i++) {
|
for (int i = 0; i < aInstructionData.EncodingOptions.Count; i++) {
|
||||||
|
|
||||||
var xEncodingOption = aInstructionData.EncodingOptions[i];
|
var xEncodingOption = aInstructionData.EncodingOptions[i];
|
||||||
if (aInstructionWithDestination != null) {
|
if (aInstructionWithDestination != null) {
|
||||||
if (!(((xEncodingOption.DestinationMemory || xEncodingOption.DestinationReg.HasValue) && aInstructionWithDestination.DestinationReg != Guid.Empty) ||
|
if (!(((xEncodingOption.DestinationMemory || xEncodingOption.DestinationReg.HasValue) && (aInstructionWithDestination.DestinationReg != Guid.Empty || aInstructionWithDestination.DestinationValue.HasValue)) ||
|
||||||
(!(xEncodingOption.DestinationMemory || xEncodingOption.DestinationReg.HasValue) && aInstructionWithDestination.DestinationReg == Guid.Empty))) {
|
(!(xEncodingOption.DestinationMemory || xEncodingOption.DestinationReg.HasValue) && aInstructionWithDestination.DestinationReg == Guid.Empty && aInstructionWithDestination.DestinationValue.HasValue))) {
|
||||||
// mismatch
|
// mismatch
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -188,23 +185,26 @@ namespace Indy.IL2CPU.Assembler.X86 {
|
||||||
(!xEncodingOption.DestinationMemory && (aInstructionWithDestination.DestinationReg != Guid.Empty && !aInstructionWithDestination.DestinationIsIndirect)))) && aInstructionWithDestination.DestinationIsIndirect) {
|
(!xEncodingOption.DestinationMemory && (aInstructionWithDestination.DestinationReg != Guid.Empty && !aInstructionWithDestination.DestinationIsIndirect)))) && aInstructionWithDestination.DestinationIsIndirect) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!((xEncodingOption.DestinationImmediate && aInstructionWithDestination.DestinationValue != null) ||
|
if (!((xEncodingOption.DestinationImmediate && aInstructionWithDestination.DestinationValue != null && !aInstructionWithDestination.DestinationIsIndirect) ||
|
||||||
(!xEncodingOption.DestinationImmediate && aInstructionWithDestination.DestinationValue == null))) {
|
(!xEncodingOption.DestinationImmediate && (aInstructionWithDestination.DestinationValue == null || aInstructionWithDestination.DestinationIsIndirect)))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (aInstructionWithSource != null) {
|
if (aInstructionWithSource != null) {
|
||||||
if (!((xEncodingOption.SourceReg.HasValue && aInstructionWithSource.SourceReg != Guid.Empty) ||
|
if (!(((xEncodingOption.SourceMemory || xEncodingOption.SourceReg.HasValue) && (aInstructionWithSource.SourceReg != Guid.Empty || aInstructionWithSource.SourceValue.HasValue)) ||
|
||||||
(!xEncodingOption.SourceReg.HasValue && aInstructionWithSource.SourceReg == Guid.Empty))) {
|
(!(xEncodingOption.SourceMemory || xEncodingOption.SourceReg.HasValue) && aInstructionWithSource.SourceReg == Guid.Empty && aInstructionWithSource.SourceValue.HasValue))) {
|
||||||
// mismatch
|
// mismatch
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!((xEncodingOption.SourceMemory && (aInstructionWithSource.SourceValue != null && aInstructionWithSource.SourceIsIndirect)) ||
|
|
||||||
(!xEncodingOption.SourceMemory && (aInstructionWithSource.SourceValue == null && !aInstructionWithSource.SourceIsIndirect))) && aInstructionWithSource.SourceIsIndirect) {
|
if ((!((xEncodingOption.SourceMemory && (aInstructionWithSource.SourceValue != null && aInstructionWithSource.SourceIsIndirect)) ||
|
||||||
|
(!xEncodingOption.SourceMemory && (aInstructionWithSource.SourceValue == null && !aInstructionWithSource.SourceIsIndirect))) &&
|
||||||
|
!((xEncodingOption.SourceMemory && (aInstructionWithSource.SourceReg != Guid.Empty && aInstructionWithSource.SourceIsIndirect)) ||
|
||||||
|
(!xEncodingOption.SourceMemory && (aInstructionWithSource.SourceReg != Guid.Empty && !aInstructionWithSource.SourceIsIndirect)))) && aInstructionWithSource.SourceIsIndirect) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!((xEncodingOption.SourceImmediate && aInstructionWithSource.SourceValue != null) ||
|
if (!((xEncodingOption.SourceImmediate && aInstructionWithSource.SourceValue != null && !aInstructionWithSource.SourceIsIndirect) ||
|
||||||
(!xEncodingOption.SourceImmediate && aInstructionWithSource.SourceValue == null))) {
|
(!xEncodingOption.SourceImmediate && (aInstructionWithSource.SourceValue == null || aInstructionWithSource.SourceIsIndirect)))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -222,13 +222,12 @@ namespace Indy.IL2CPU.Assembler.X86 {
|
||||||
if (aEncodingOption.NeedsModRMByte) {
|
if (aEncodingOption.NeedsModRMByte) {
|
||||||
aSize += 1;
|
aSize += 1;
|
||||||
bool xSIB = false;
|
bool xSIB = false;
|
||||||
if(aInstructionWithDestination!=null &&
|
if (aInstructionWithDestination != null &&
|
||||||
((aInstructionWithDestination.DestinationReg == Registers.EBP && !(aInstructionWithDestination.DestinationIsIndirect && aInstructionWithDestination.DestinationDisplacement>0)) ||
|
((aInstructionWithDestination.DestinationReg == Registers.EBP && !(aInstructionWithDestination.DestinationIsIndirect && aInstructionWithDestination.DestinationDisplacement > 0)) ||
|
||||||
aInstructionWithDestination.DestinationReg == Registers.ESP)) {
|
aInstructionWithDestination.DestinationReg == Registers.ESP)) {
|
||||||
aSize++;
|
aSize++;
|
||||||
xSIB = true;
|
xSIB = true;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (aInstructionWithSource != null &&
|
if (aInstructionWithSource != null &&
|
||||||
((aInstructionWithSource.SourceReg == Registers.EBP && !(aInstructionWithSource.SourceReg != Guid.Empty && aInstructionWithSource.SourceIsIndirect && aInstructionWithSource.SourceDisplacement > 0)) ||
|
((aInstructionWithSource.SourceReg == Registers.EBP && !(aInstructionWithSource.SourceReg != Guid.Empty && aInstructionWithSource.SourceIsIndirect && aInstructionWithSource.SourceDisplacement > 0)) ||
|
||||||
aInstructionWithSource.SourceReg == Registers.ESP)) {
|
aInstructionWithSource.SourceReg == Registers.ESP)) {
|
||||||
|
|
@ -242,18 +241,19 @@ namespace Indy.IL2CPU.Assembler.X86 {
|
||||||
} else {
|
} else {
|
||||||
if (aInstructionWithDestination.DestinationDisplacement <= Int16.MaxValue) {
|
if (aInstructionWithDestination.DestinationDisplacement <= Int16.MaxValue) {
|
||||||
aSize += 4;
|
aSize += 4;
|
||||||
}else {
|
} else {
|
||||||
aSize += 4;
|
aSize += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (xSIB) {
|
if (xSIB) {
|
||||||
// aSize -= 1;
|
// aSize -= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if (aInstructionWithDestination!= null && aInstructionWithDestination.DestinationValue.HasValue) {
|
if (aInstructionWithDestination != null && aInstructionWithSize != null) {
|
||||||
aSize += (ulong)aInstructionWithSize.Size / 8;
|
if (aInstructionWithDestination != null && aInstructionWithDestination.DestinationValue.HasValue) {
|
||||||
|
aSize += (ulong)aInstructionWithSize.Size / 8;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (aInstructionWithDestination != null && aInstructionWithDestination.DestinationRef != null) {
|
if (aInstructionWithDestination != null && aInstructionWithDestination.DestinationRef != null) {
|
||||||
aSize += 4;
|
aSize += 4;
|
||||||
|
|
@ -261,16 +261,19 @@ namespace Indy.IL2CPU.Assembler.X86 {
|
||||||
if (aInstructionWithSource != null && aInstructionWithSource.SourceValue.HasValue) {
|
if (aInstructionWithSource != null && aInstructionWithSource.SourceValue.HasValue) {
|
||||||
aSize += (ulong)aInstructionWithSize.Size / 8;
|
aSize += (ulong)aInstructionWithSize.Size / 8;
|
||||||
}
|
}
|
||||||
if (aInstructionWithSource!=null && aInstructionWithSource.SourceRef != null) {
|
if (aInstructionWithSource != null && aInstructionWithSource.SourceRef != null) {
|
||||||
aSize += 4;
|
aSize += 4;
|
||||||
}
|
}
|
||||||
if (aEncodingOption.DefaultSize == InstructionSize.DWord && aInstructionWithSize!=null && aInstructionWithSize.Size == 16) {
|
if (aInstructionWithDestination != null && (aInstructionWithDestination.DestinationValue.HasValue && !(aInstructionWithDestination.DestinationIsIndirect && aInstructionWithDestination.DestinationDisplacement > 0))) {
|
||||||
|
aSize += (ulong)aEncodingOption.DefaultSize / 8;
|
||||||
|
}
|
||||||
|
if (aEncodingOption.DefaultSize == InstructionSize.DWord && aInstructionWithSize != null && aInstructionWithSize.Size == 16) {
|
||||||
aSize += 1;
|
aSize += 1;
|
||||||
}
|
}
|
||||||
if (aEncodingOption.DefaultSize == InstructionSize.Word && aInstructionWithSize != null && aInstructionWithSize.Size == 32) {
|
if (aEncodingOption.DefaultSize == InstructionSize.Word && aInstructionWithSize != null && aInstructionWithSize.Size == 32) {
|
||||||
aSize += 1;
|
aSize += 1;
|
||||||
}
|
}
|
||||||
aInstruction.mDataSize=aSize;
|
aInstruction.mDataSize = aSize;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
public override bool DetermineSize(Indy.IL2CPU.Assembler.Assembler aAssembler, out ulong aSize) {
|
public override bool DetermineSize(Indy.IL2CPU.Assembler.Assembler aAssembler, out ulong aSize) {
|
||||||
|
|
@ -279,7 +282,7 @@ namespace Indy.IL2CPU.Assembler.X86 {
|
||||||
var xInstructionWithSize = this as IInstructionWithSize;
|
var xInstructionWithSize = this as IInstructionWithSize;
|
||||||
InstructionData xInstructionData = null;
|
InstructionData xInstructionData = null;
|
||||||
InstructionData.InstructionEncodingOption xEncodingOption = null;
|
InstructionData.InstructionEncodingOption xEncodingOption = null;
|
||||||
if(!GetEffectiveInstructionInfo(this, xInstructionWithDestination, xInstructionWithSize, xInstructionWithSource, out xInstructionData, out xEncodingOption )) {
|
if (!GetEffectiveInstructionInfo(this, xInstructionWithDestination, xInstructionWithSize, xInstructionWithSource, out xInstructionData, out xEncodingOption)) {
|
||||||
return base.DetermineSize(aAssembler, out aSize);
|
return base.DetermineSize(aAssembler, out aSize);
|
||||||
}
|
}
|
||||||
return DetermineSize(aAssembler, out aSize, this, xInstructionWithDestination, xInstructionWithSize, xInstructionWithSource, xInstructionData, xEncodingOption);
|
return DetermineSize(aAssembler, out aSize, this, xInstructionWithDestination, xInstructionWithSize, xInstructionWithSource, xInstructionData, xEncodingOption);
|
||||||
|
|
@ -295,7 +298,7 @@ namespace Indy.IL2CPU.Assembler.X86 {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(xWithSource != null) {
|
if (xWithSource != null) {
|
||||||
if (xWithSource.SourceRef != null && !xWithSource.SourceRef.Resolve(aAssembler, out xAddress)) {
|
if (xWithSource.SourceRef != null && !xWithSource.SourceRef.Resolve(aAssembler, out xAddress)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -329,7 +332,7 @@ namespace Indy.IL2CPU.Assembler.X86 {
|
||||||
return GetData(aAssembler, this, xInstructionWithDestination, xInstructionWithSize, xInstructionWithSource, xInstructionData, xEncodingOption);
|
return GetData(aAssembler, this, xInstructionWithDestination, xInstructionWithSize, xInstructionWithSource, xInstructionData, xEncodingOption);
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] GetData(Indy.IL2CPU.Assembler.Assembler aAssembler, Instruction aInstruction, IInstructionWithDestination aInstructionWithDestination, IInstructionWithSize aInstructionWithSize, IInstructionWithSource aInstructionWithSource, InstructionData aInstructionData, InstructionData.InstructionEncodingOption aEncodingOption) {
|
private static byte[] GetData(Indy.IL2CPU.Assembler.Assembler aAssembler, Instruction aInstruction, IInstructionWithDestination aInstructionWithDestination, IInstructionWithSize aInstructionWithSize, IInstructionWithSource aInstructionWithSource, InstructionData aInstructionData, InstructionData.InstructionEncodingOption aEncodingOption) {
|
||||||
if (aInstruction.ToString() == "mov word [ESP], 0x47") {
|
if (aInstruction.ToString() == "mov word [ESP], 0x47") {
|
||||||
Console.Write("");
|
Console.Write("");
|
||||||
}
|
}
|
||||||
|
|
@ -366,10 +369,11 @@ namespace Indy.IL2CPU.Assembler.X86 {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aEncodingOption.NeedsModRMByte) {
|
if (aEncodingOption.NeedsModRMByte) {
|
||||||
xBuffer[aEncodingOption.OpCode.Length + xExtraOffset] = 0;
|
xBuffer[aEncodingOption.OpCode.Length + xExtraOffset] = aEncodingOption.InitialModRMByteValue;
|
||||||
byte xModRM = 0;
|
|
||||||
if (aInstructionWithDestination != null) {
|
if (aInstructionWithDestination != null) {
|
||||||
xBuffer[aEncodingOption.OpCode.Length + xExtraOffset] |= EncodeRegister(aInstructionWithDestination.DestinationReg);
|
if (aInstructionWithDestination.DestinationReg != Guid.Empty) {
|
||||||
|
xBuffer[aEncodingOption.OpCode.Length + xExtraOffset] |= EncodeRegister(aInstructionWithDestination.DestinationReg);
|
||||||
|
}
|
||||||
byte? xSIB = null;
|
byte? xSIB = null;
|
||||||
//if (!aInstructionWithDestination.DestinationIsIndirect) {
|
//if (!aInstructionWithDestination.DestinationIsIndirect) {
|
||||||
if ((aInstructionWithDestination.DestinationReg == Registers.EBP && !(aInstructionWithDestination.DestinationIsIndirect && aInstructionWithDestination.DestinationDisplacement > 0)) ||
|
if ((aInstructionWithDestination.DestinationReg == Registers.EBP && !(aInstructionWithDestination.DestinationIsIndirect && aInstructionWithDestination.DestinationDisplacement > 0)) ||
|
||||||
|
|
@ -386,16 +390,30 @@ namespace Indy.IL2CPU.Assembler.X86 {
|
||||||
((aInstructionWithSource.SourceReg == Registers.EBP && !(aInstructionWithSource.SourceReg != Guid.Empty && aInstructionWithSource.SourceIsIndirect && aInstructionWithSource.SourceDisplacement > 0)) ||
|
((aInstructionWithSource.SourceReg == Registers.EBP && !(aInstructionWithSource.SourceReg != Guid.Empty && aInstructionWithSource.SourceIsIndirect && aInstructionWithSource.SourceDisplacement > 0)) ||
|
||||||
aInstructionWithSource.SourceReg == Registers.ESP)) {
|
aInstructionWithSource.SourceReg == Registers.ESP)) {
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
|
}else {
|
||||||
|
if(aInstructionWithDestination.DestinationReg == Guid.Empty && aInstructionWithDestination.DestinationIsIndirect) {
|
||||||
|
// todo: fix for 16bit mode, it should then be 0x36
|
||||||
|
xBuffer[aEncodingOption.OpCode.Length + xExtraOffset] |= 0x5;
|
||||||
|
ulong xAddress = 0;
|
||||||
|
if (!(aInstructionWithDestination.DestinationRef != null && aInstructionWithDestination.DestinationRef.Resolve(aAssembler, out xAddress))) {
|
||||||
|
if(aInstructionWithDestination.DestinationValue.HasValue){
|
||||||
|
xAddress = aInstructionWithDestination.DestinationValue.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xAddress += (ulong)aInstructionWithDestination.DestinationDisplacement;
|
||||||
|
Array.Copy(BitConverter.GetBytes((uint)xAddress), 0, xBuffer, aEncodingOption.OpCode.Length + xExtraOffset + 1, 4);
|
||||||
|
xExtraOffset += 4;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//xBuffer[aEncodingOption.OpCode.Length + xExtraOffset] |= 3 << 6;
|
//xBuffer[aEncodingOption.OpCode.Length + xExtraOffset] |= 3 << 6;
|
||||||
//}
|
//}
|
||||||
if(aInstructionWithSource != null && aInstructionWithSource.SourceReg!=Guid.Empty) {
|
if (aInstructionWithSource != null && aInstructionWithSource.SourceReg != Guid.Empty) {
|
||||||
xBuffer[aEncodingOption.OpCode.Length + xExtraOffset] |=(byte)(EncodeRegister(aInstructionWithSource.SourceReg) << 3);
|
xBuffer[aEncodingOption.OpCode.Length + xExtraOffset] |= (byte)(EncodeRegister(aInstructionWithSource.SourceReg) << 3);
|
||||||
}
|
}
|
||||||
//SBArray.Resize(ref xBuffer, xBuffer.Length + 1);
|
//SBArray.Resize(ref xBuffer, xBuffer.Length + 1);
|
||||||
if (aInstructionWithDestination.DestinationIsIndirect && aInstructionWithDestination.DestinationDisplacement > 0) {
|
if (aInstructionWithDestination.DestinationReg != Guid.Empty && aInstructionWithDestination.DestinationIsIndirect && aInstructionWithDestination.DestinationDisplacement > 0) {
|
||||||
var xSIBOffset = 0;
|
var xSIBOffset = 0;
|
||||||
if (xSIB != null) {
|
if (xSIB != null) {
|
||||||
//xExtraOffset++;
|
//xExtraOffset++;
|
||||||
|
|
@ -404,15 +422,15 @@ namespace Indy.IL2CPU.Assembler.X86 {
|
||||||
}
|
}
|
||||||
// todo: optimize for different displacement sizes
|
// todo: optimize for different displacement sizes
|
||||||
//if(aInstructionWithDestination.DestinationDisplacement< 256) {
|
//if(aInstructionWithDestination.DestinationDisplacement< 256) {
|
||||||
xBuffer[aEncodingOption.OpCode.Length + xExtraOffset] |= 2 << 6; // for now use 16bit value
|
xBuffer[aEncodingOption.OpCode.Length + xExtraOffset] |= 2 << 6; // for now use 16bit value
|
||||||
//xBuffer[aEncodingOption.OpCode.Length + xExtraOffset] &= 0xBF; // clear the 1 << 6
|
//xBuffer[aEncodingOption.OpCode.Length + xExtraOffset] &= 0xBF; // clear the 1 << 6
|
||||||
Array.Copy(BitConverter.GetBytes(aInstructionWithDestination.DestinationDisplacement), 0, xBuffer, aEncodingOption.OpCode.Length + xExtraOffset + xSIBOffset + 1, 4);
|
Array.Copy(BitConverter.GetBytes(aInstructionWithDestination.DestinationDisplacement), 0, xBuffer, aEncodingOption.OpCode.Length + xExtraOffset + xSIBOffset + 1, 4);
|
||||||
xExtraOffset += 4;
|
xExtraOffset += 4;
|
||||||
//}
|
//}
|
||||||
if (xSIB != null) {
|
if (xSIB != null) {
|
||||||
xExtraOffset++;
|
xExtraOffset++;
|
||||||
}
|
}
|
||||||
}else {
|
} else {
|
||||||
if (xSIB != null) {
|
if (xSIB != null) {
|
||||||
xExtraOffset++;
|
xExtraOffset++;
|
||||||
xBuffer[aEncodingOption.OpCode.Length + xExtraOffset] = xSIB.Value;
|
xBuffer[aEncodingOption.OpCode.Length + xExtraOffset] = xSIB.Value;
|
||||||
|
|
@ -423,7 +441,22 @@ namespace Indy.IL2CPU.Assembler.X86 {
|
||||||
//EncodeModRMByte(aInstruction.DestinationReg, aInstruction.DestinationIsIndirect, aInstruction.DestinationDisplacement > 0, aInstruction.DestinationDisplacement > 255, out xSIB);
|
//EncodeModRMByte(aInstruction.DestinationReg, aInstruction.DestinationIsIndirect, aInstruction.DestinationDisplacement > 0, aInstruction.DestinationDisplacement > 255, out xSIB);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
if (aInstructionWithDestination != null) {
|
||||||
|
if (aInstructionWithDestination.DestinationValue.HasValue && !aInstructionWithDestination.DestinationIsIndirect) {
|
||||||
|
int xOffset = aEncodingOption.OpCode.Length + xExtraOffset;
|
||||||
|
if (aEncodingOption.NeedsModRMByte) {
|
||||||
|
xOffset++;
|
||||||
|
}
|
||||||
|
var xInstrSize = 0;
|
||||||
|
if (aInstructionWithSize != null) {
|
||||||
|
xInstrSize = aInstructionWithSize.Size / 8;
|
||||||
|
} else {
|
||||||
|
// throw new NotImplementedException("size not known");
|
||||||
|
xInstrSize = (int)aEncodingOption.DefaultSize / 8;
|
||||||
|
}
|
||||||
|
Array.Copy(BitConverter.GetBytes(aInstructionWithDestination.DestinationValue.Value), 0, xBuffer, xOffset, xInstrSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
// todo: add more options
|
// todo: add more options
|
||||||
if (aInstructionWithSource != null) {
|
if (aInstructionWithSource != null) {
|
||||||
if (aInstructionWithSource.SourceValue.HasValue) {
|
if (aInstructionWithSource.SourceValue.HasValue) {
|
||||||
|
|
@ -448,7 +481,9 @@ namespace Indy.IL2CPU.Assembler.X86 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(aEncodingOption.ModifyBytes != null) {
|
||||||
|
aEncodingOption.ModifyBytes(xBuffer, aInstruction);
|
||||||
|
}
|
||||||
//
|
//
|
||||||
return xBuffer;
|
return xBuffer;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ namespace TestApp {
|
||||||
class Program {
|
class Program {
|
||||||
class Renderer : Y86 {
|
class Renderer : Y86 {
|
||||||
public void DoRender() {
|
public void DoRender() {
|
||||||
new Push { DestinationValue = 300000 };
|
new Push { DestinationIsIndirect = true, DestinationValue = 65 };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void Main(string[] args) {
|
static void Main(string[] args) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue