diff --git a/source2/IL2PCU/Cosmos.IL2CPU.Profiler/ILOpProfiler.cs b/source2/IL2PCU/Cosmos.IL2CPU.Profiler/ILOpProfiler.cs
index 2304dc521..087160baf 100644
--- a/source2/IL2PCU/Cosmos.IL2CPU.Profiler/ILOpProfiler.cs
+++ b/source2/IL2PCU/Cosmos.IL2CPU.Profiler/ILOpProfiler.cs
@@ -5,7 +5,7 @@ using System.Text;
namespace Cosmos.IL2CPU.Profiler {
public class ILOpProfiler : Cosmos.IL2CPU.ILOp {
- protected ILOpProfiler(ILOpCode aOpCode)
+ public ILOpProfiler(ILOpCode aOpCode)
: base(aOpCode) {
}
}
diff --git a/source2/IL2PCU/Cosmos.IL2CPU/Cosmos.IL2CPU.csproj b/source2/IL2PCU/Cosmos.IL2CPU/Cosmos.IL2CPU.csproj
index 487209a9f..5b555bcf6 100644
--- a/source2/IL2PCU/Cosmos.IL2CPU/Cosmos.IL2CPU.csproj
+++ b/source2/IL2PCU/Cosmos.IL2CPU/Cosmos.IL2CPU.csproj
@@ -53,6 +53,7 @@
+
diff --git a/source2/IL2PCU/Cosmos.IL2CPU/ILOpCode.cs b/source2/IL2PCU/Cosmos.IL2CPU/ILOpCode.cs
index ce4b8379f..fdaaf8022 100644
--- a/source2/IL2PCU/Cosmos.IL2CPU/ILOpCode.cs
+++ b/source2/IL2PCU/Cosmos.IL2CPU/ILOpCode.cs
@@ -12,15 +12,6 @@ namespace Cosmos.IL2CPU {
//TODO: Change this to an abstract class and make constructor protected
public class ILOpCode {
- public readonly Code OpCode;
-
- public ILOpCode(Code aOpCode) {
- OpCode = aOpCode;
- }
-
- //TODO: Use System.Reflection.Emit.OpCodes where possible, but we still need these
- //enums because they are used in attributes and other places that we need
- //compile time values
public enum Code : ushort {
#region Values
Nop = 0x0000,
@@ -252,55 +243,10 @@ namespace Cosmos.IL2CPU {
#endregion
}
- public static long? GetShortcutOperand(Code aOpCode) {
- switch (aOpCode) {
- case Code.Ldarg_0:
- return 0;
- case Code.Ldarg_1:
- return 1;
- case Code.Ldarg_2:
- return 2;
- case Code.Ldarg_3:
- return 3;
- case Code.Ldc_I4_0:
- return 0;
- case Code.Ldc_I4_1:
- return 1;
- case Code.Ldc_I4_2:
- return 2;
- case Code.Ldc_I4_3:
- return 3;
- case Code.Ldc_I4_4:
- return 4;
- case Code.Ldc_I4_5:
- return 5;
- case Code.Ldc_I4_6:
- return 6;
- case Code.Ldc_I4_7:
- return 7;
- case Code.Ldc_I4_8:
- return 8;
- case Code.Ldc_I4_M1:
- return -1;
- case Code.Ldloc_0:
- return 0;
- case Code.Ldloc_1:
- return 1;
- case Code.Ldloc_2:
- return 2;
- case Code.Ldloc_3:
- return 3;
- case Code.Stloc_0:
- return 0;
- case Code.Stloc_1:
- return 1;
- case Code.Stloc_2:
- return 2;
- case Code.Stloc_3:
- return 3;
- default:
- return null;
- }
+ public readonly Code OpCode;
+
+ public ILOpCode(Code aOpCode) {
+ OpCode = aOpCode;
}
}
diff --git a/source2/IL2PCU/Cosmos.IL2CPU/ILOpCodes/InlineVar.cs b/source2/IL2PCU/Cosmos.IL2CPU/ILOpCodes/InlineVar.cs
new file mode 100644
index 000000000..001d2dda6
--- /dev/null
+++ b/source2/IL2PCU/Cosmos.IL2CPU/ILOpCodes/InlineVar.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Cosmos.IL2CPU.ILOpCodes {
+ public class InlineVar : ILOpCode {
+ public readonly UInt16 Value;
+
+ public InlineVar(Code aOpCode, UInt16 aValue)
+ : base(aOpCode) {
+ Value = aValue;
+ }
+ }
+}
diff --git a/source2/IL2PCU/Cosmos.IL2CPU/ILReader.cs b/source2/IL2PCU/Cosmos.IL2CPU/ILReader.cs
index ba3d7b7c1..8d2039462 100644
--- a/source2/IL2PCU/Cosmos.IL2CPU/ILReader.cs
+++ b/source2/IL2PCU/Cosmos.IL2CPU/ILReader.cs
@@ -58,13 +58,11 @@ namespace Cosmos.IL2CPU {
}
//TODO: Need to look at OpCode operandtype and queue for these:
+ // probably dont need to look by op, but can do by operand instead.
// Call: QueueMethod(aReader.OperandValueMethod);
// Callvirt: QueueMethod(aReader.OperandValueMethod);
// Newobj: QueueMethod(aReader.OperandValueMethod);
- // Get arguments before Shortcut expansion.
- //TODO: Are all shortcuts wo arguments? if so we can skip this step for shortcuts
-
ILOpCode xILOpCode = null;
switch (xOpCode.OperandType) {
// The operand is a 32-bit integer branch target.
@@ -81,7 +79,7 @@ namespace Cosmos.IL2CPU {
// The operand is a 32-bit integer.
case OperandType.InlineI:
- xILOpCode = new ILOpCodes.InlineI(xOpCodeVal, ReadInt32(xIL, xPos));
+ xILOpCode = new ILOpCodes.InlineI(xOpCodeVal, ReadUInt32(xIL, xPos));
xPos = xPos + 4;
break;
@@ -122,7 +120,7 @@ namespace Cosmos.IL2CPU {
break;
case OperandType.InlineSwitch: {
- int xCount = (int)ReadInt32(xIL, xPos);
+ int xCount = (int)ReadUInt32(xIL, xPos);
int[] xBranchLocations = new int[xCount];
uint[] xBranchValues = new uint[xCount];
for (int i = 0; i < xCount; i++) {
@@ -153,7 +151,7 @@ namespace Cosmos.IL2CPU {
// 16-bit integer containing the ordinal of a local variable or an argument.
case OperandType.InlineVar:
- xILOpCode = new ILOpCode(xOpCodeVal);
+ xILOpCode = new ILOpCodes.InlineVar(xOpCodeVal, ReadUInt16(xIL, xPos));
xPos = xPos + 2;
break;
@@ -175,7 +173,7 @@ namespace Cosmos.IL2CPU {
xPos = xPos + 4;
break;
- // 8-bit integer containing the ordinal of a local variable or an argumenta.
+ // 8-bit integer containing the ordinal of a local variable or an argument.
case OperandType.ShortInlineVar:
xILOpCode = new ILOpCode(xOpCodeVal);
xPos = xPos + 4;
@@ -186,9 +184,12 @@ namespace Cosmos.IL2CPU {
}
#region Expand shortcuts
+ // This region expands shortcut ops into full ops
+ // This elminates the amount of code required in the assemblers
+ // by allowing them to ignore the shortcuts
switch (xOpCodeVal) {
case ILOpCode.Code.Beq_S:
- xILOpCode = new ILOpCodes.InlineNone(ILOpCode.Code.Beq);
+ //xILOpCode = new ILOpCodes.xxx(ILOpCode.Code.Beq, xILOpCode.value);
break;
case ILOpCode.Code.Bge_S:
@@ -240,19 +241,19 @@ namespace Cosmos.IL2CPU {
break;
case ILOpCode.Code.Ldarg_0:
- //return Code.Ldarg;
+ xILOpCode = new ILOpCodes.InlineVar(ILOpCode.Code.Ldarg, 0);
break;
case ILOpCode.Code.Ldarg_1:
- //return Code.Ldarg;
+ xILOpCode = new ILOpCodes.InlineVar(ILOpCode.Code.Ldarg, 1);
break;
case ILOpCode.Code.Ldarg_2:
- //return Code.Ldarg;
+ xILOpCode = new ILOpCodes.InlineVar(ILOpCode.Code.Ldarg, 2);
break;
case ILOpCode.Code.Ldarg_3:
- //return Code.Ldarg;
+ xILOpCode = new ILOpCodes.InlineVar(ILOpCode.Code.Ldarg, 3);
break;
case ILOpCode.Code.Ldarg_S:
@@ -368,10 +369,14 @@ namespace Cosmos.IL2CPU {
return xResult;
}
- private UInt32 ReadInt32(byte[] aBytes, int aPos) {
+ private UInt32 ReadUInt32(byte[] aBytes, int aPos) {
return (UInt32)(aBytes[aPos + 3] << 24 | aBytes[aPos + 2] << 16 | aBytes[aPos + 1] << 8 | aBytes[aPos]);
}
+ private UInt16 ReadUInt16(byte[] aBytes, int aPos) {
+ return (UInt16)(aBytes[aPos + 1] << 8 | aBytes[aPos]);
+ }
+
//mOperandValueStr = mModule.ResolveString(OperandValueInt32);
//public MethodBase OperandValueMethod {
diff --git a/source2/IL2PCU/Cosmos.IL2CPU/ILScanner.cs b/source2/IL2PCU/Cosmos.IL2CPU/ILScanner.cs
index a551ae205..9ec887c90 100644
--- a/source2/IL2PCU/Cosmos.IL2CPU/ILScanner.cs
+++ b/source2/IL2PCU/Cosmos.IL2CPU/ILScanner.cs
@@ -33,22 +33,25 @@ namespace Cosmos.IL2CPU {
public ILScanner(Type aAssemblerBaseOp) : this(aAssemblerBaseOp, false) {
}
- public ILScanner(Type aAssemblerBaseOp, bool aProfileMode) {
+ public ILScanner(Type aAssemblerBaseOp, bool aSingleILOp) {
mReader = new ILReader();
- if (aProfileMode) {
- LoadILOpsForProfiling(aAssemblerBaseOp);
+ if (aSingleILOp) {
+ LoadILOp(aAssemblerBaseOp);
} else {
LoadILOps(aAssemblerBaseOp);
}
}
- protected void LoadILOpsForProfiling(Type aAssemblerBaseOp) {
+ protected void LoadILOp(Type aAssemblerBaseOp) {
var xCtor = aAssemblerBaseOp.GetConstructors()[0];
- foreach (var xCode in Enum.GetValues(typeof(ILOpCode.Code))) {
- if ((uint)xCode <= 0xFF) {
- mILOpsLo[(uint)xCode] = xCtor;
+ // Don't change the type in the foreach to a var, its necessary as it is now
+ // to typecast it, so we can then recast to an int.
+ foreach (ILOpCode.Code xCode in Enum.GetValues(typeof(ILOpCode.Code))) {
+ int xCodeValue = (int)xCode;
+ if (xCodeValue <= 0xFF) {
+ mILOpsLo[xCodeValue] = xCtor;
} else {
- mILOpsHi[(uint)xCode & 0xFF] = xCtor;
+ mILOpsHi[xCodeValue & 0xFF] = xCtor;
}
}
}
@@ -101,12 +104,16 @@ namespace Cosmos.IL2CPU {
foreach (var xOpCode in xOpCodes) {
//InstructionCount++;
ConstructorInfo xCtor;
- if ((uint)xOpCode.OpCode <= 0xFF) {
- xCtor = mILOpsLo[(uint)xOpCode.OpCode];
+ uint xOpCodeVal = (uint)xOpCode.OpCode;
+ if (xOpCodeVal <= 0xFF) {
+ xCtor = mILOpsLo[xOpCodeVal];
} else {
- xCtor = mILOpsHi[(uint)xOpCode.OpCode];
+ xCtor = mILOpsHi[xOpCodeVal & 0xFF];
+ }
+ // TODO: Remove this if when all shortcut espansions are working again
+ if (xCtor != null) {
+ var xILOp = xCtor.Invoke(new object[] { xOpCode });
}
- var xILOp = xCtor.Invoke(new object[] {xOpCode});
}
}
}