mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-26 21:42:11 +00:00
This commit is contained in:
parent
a3fccd764b
commit
d1f837f66b
6 changed files with 58 additions and 84 deletions
|
|
@ -5,7 +5,7 @@ using System.Text;
|
||||||
|
|
||||||
namespace Cosmos.IL2CPU.Profiler {
|
namespace Cosmos.IL2CPU.Profiler {
|
||||||
public class ILOpProfiler : Cosmos.IL2CPU.ILOp {
|
public class ILOpProfiler : Cosmos.IL2CPU.ILOp {
|
||||||
protected ILOpProfiler(ILOpCode aOpCode)
|
public ILOpProfiler(ILOpCode aOpCode)
|
||||||
: base(aOpCode) {
|
: base(aOpCode) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@
|
||||||
<Compile Include="ILOpCode.cs" />
|
<Compile Include="ILOpCode.cs" />
|
||||||
<Compile Include="ILOpCodes\InlineI.cs" />
|
<Compile Include="ILOpCodes\InlineI.cs" />
|
||||||
<Compile Include="ILOpCodes\InlineNone.cs" />
|
<Compile Include="ILOpCodes\InlineNone.cs" />
|
||||||
|
<Compile Include="ILOpCodes\InlineVar.cs" />
|
||||||
<Compile Include="ILReader.cs" />
|
<Compile Include="ILReader.cs" />
|
||||||
<Compile Include="OpCodeAttribute.cs" />
|
<Compile Include="OpCodeAttribute.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
|
|
||||||
|
|
@ -12,15 +12,6 @@ namespace Cosmos.IL2CPU {
|
||||||
//TODO: Change this to an abstract class and make constructor protected
|
//TODO: Change this to an abstract class and make constructor protected
|
||||||
public class ILOpCode {
|
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 {
|
public enum Code : ushort {
|
||||||
#region Values
|
#region Values
|
||||||
Nop = 0x0000,
|
Nop = 0x0000,
|
||||||
|
|
@ -252,55 +243,10 @@ namespace Cosmos.IL2CPU {
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long? GetShortcutOperand(Code aOpCode) {
|
public readonly Code OpCode;
|
||||||
switch (aOpCode) {
|
|
||||||
case Code.Ldarg_0:
|
public ILOpCode(Code aOpCode) {
|
||||||
return 0;
|
OpCode = aOpCode;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
15
source2/IL2PCU/Cosmos.IL2CPU/ILOpCodes/InlineVar.cs
Normal file
15
source2/IL2PCU/Cosmos.IL2CPU/ILOpCodes/InlineVar.cs
Normal file
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -58,13 +58,11 @@ namespace Cosmos.IL2CPU {
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: Need to look at OpCode operandtype and queue for these:
|
//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);
|
// Call: QueueMethod(aReader.OperandValueMethod);
|
||||||
// Callvirt: QueueMethod(aReader.OperandValueMethod);
|
// Callvirt: QueueMethod(aReader.OperandValueMethod);
|
||||||
// Newobj: 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;
|
ILOpCode xILOpCode = null;
|
||||||
switch (xOpCode.OperandType) {
|
switch (xOpCode.OperandType) {
|
||||||
// The operand is a 32-bit integer branch target.
|
// The operand is a 32-bit integer branch target.
|
||||||
|
|
@ -81,7 +79,7 @@ namespace Cosmos.IL2CPU {
|
||||||
|
|
||||||
// The operand is a 32-bit integer.
|
// The operand is a 32-bit integer.
|
||||||
case OperandType.InlineI:
|
case OperandType.InlineI:
|
||||||
xILOpCode = new ILOpCodes.InlineI(xOpCodeVal, ReadInt32(xIL, xPos));
|
xILOpCode = new ILOpCodes.InlineI(xOpCodeVal, ReadUInt32(xIL, xPos));
|
||||||
xPos = xPos + 4;
|
xPos = xPos + 4;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -122,7 +120,7 @@ namespace Cosmos.IL2CPU {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OperandType.InlineSwitch: {
|
case OperandType.InlineSwitch: {
|
||||||
int xCount = (int)ReadInt32(xIL, xPos);
|
int xCount = (int)ReadUInt32(xIL, xPos);
|
||||||
int[] xBranchLocations = new int[xCount];
|
int[] xBranchLocations = new int[xCount];
|
||||||
uint[] xBranchValues = new uint[xCount];
|
uint[] xBranchValues = new uint[xCount];
|
||||||
for (int i = 0; i < xCount; i++) {
|
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.
|
// 16-bit integer containing the ordinal of a local variable or an argument.
|
||||||
case OperandType.InlineVar:
|
case OperandType.InlineVar:
|
||||||
xILOpCode = new ILOpCode(xOpCodeVal);
|
xILOpCode = new ILOpCodes.InlineVar(xOpCodeVal, ReadUInt16(xIL, xPos));
|
||||||
xPos = xPos + 2;
|
xPos = xPos + 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -175,7 +173,7 @@ namespace Cosmos.IL2CPU {
|
||||||
xPos = xPos + 4;
|
xPos = xPos + 4;
|
||||||
break;
|
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:
|
case OperandType.ShortInlineVar:
|
||||||
xILOpCode = new ILOpCode(xOpCodeVal);
|
xILOpCode = new ILOpCode(xOpCodeVal);
|
||||||
xPos = xPos + 4;
|
xPos = xPos + 4;
|
||||||
|
|
@ -186,9 +184,12 @@ namespace Cosmos.IL2CPU {
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Expand shortcuts
|
#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) {
|
switch (xOpCodeVal) {
|
||||||
case ILOpCode.Code.Beq_S:
|
case ILOpCode.Code.Beq_S:
|
||||||
xILOpCode = new ILOpCodes.InlineNone(ILOpCode.Code.Beq);
|
//xILOpCode = new ILOpCodes.xxx(ILOpCode.Code.Beq, xILOpCode.value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ILOpCode.Code.Bge_S:
|
case ILOpCode.Code.Bge_S:
|
||||||
|
|
@ -240,19 +241,19 @@ namespace Cosmos.IL2CPU {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ILOpCode.Code.Ldarg_0:
|
case ILOpCode.Code.Ldarg_0:
|
||||||
//return Code.Ldarg;
|
xILOpCode = new ILOpCodes.InlineVar(ILOpCode.Code.Ldarg, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ILOpCode.Code.Ldarg_1:
|
case ILOpCode.Code.Ldarg_1:
|
||||||
//return Code.Ldarg;
|
xILOpCode = new ILOpCodes.InlineVar(ILOpCode.Code.Ldarg, 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ILOpCode.Code.Ldarg_2:
|
case ILOpCode.Code.Ldarg_2:
|
||||||
//return Code.Ldarg;
|
xILOpCode = new ILOpCodes.InlineVar(ILOpCode.Code.Ldarg, 2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ILOpCode.Code.Ldarg_3:
|
case ILOpCode.Code.Ldarg_3:
|
||||||
//return Code.Ldarg;
|
xILOpCode = new ILOpCodes.InlineVar(ILOpCode.Code.Ldarg, 3);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ILOpCode.Code.Ldarg_S:
|
case ILOpCode.Code.Ldarg_S:
|
||||||
|
|
@ -368,10 +369,14 @@ namespace Cosmos.IL2CPU {
|
||||||
return xResult;
|
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]);
|
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);
|
//mOperandValueStr = mModule.ResolveString(OperandValueInt32);
|
||||||
|
|
||||||
//public MethodBase OperandValueMethod {
|
//public MethodBase OperandValueMethod {
|
||||||
|
|
|
||||||
|
|
@ -33,22 +33,25 @@ namespace Cosmos.IL2CPU {
|
||||||
public ILScanner(Type aAssemblerBaseOp) : this(aAssemblerBaseOp, false) {
|
public ILScanner(Type aAssemblerBaseOp) : this(aAssemblerBaseOp, false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ILScanner(Type aAssemblerBaseOp, bool aProfileMode) {
|
public ILScanner(Type aAssemblerBaseOp, bool aSingleILOp) {
|
||||||
mReader = new ILReader();
|
mReader = new ILReader();
|
||||||
if (aProfileMode) {
|
if (aSingleILOp) {
|
||||||
LoadILOpsForProfiling(aAssemblerBaseOp);
|
LoadILOp(aAssemblerBaseOp);
|
||||||
} else {
|
} else {
|
||||||
LoadILOps(aAssemblerBaseOp);
|
LoadILOps(aAssemblerBaseOp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void LoadILOpsForProfiling(Type aAssemblerBaseOp) {
|
protected void LoadILOp(Type aAssemblerBaseOp) {
|
||||||
var xCtor = aAssemblerBaseOp.GetConstructors()[0];
|
var xCtor = aAssemblerBaseOp.GetConstructors()[0];
|
||||||
foreach (var xCode in Enum.GetValues(typeof(ILOpCode.Code))) {
|
// Don't change the type in the foreach to a var, its necessary as it is now
|
||||||
if ((uint)xCode <= 0xFF) {
|
// to typecast it, so we can then recast to an int.
|
||||||
mILOpsLo[(uint)xCode] = xCtor;
|
foreach (ILOpCode.Code xCode in Enum.GetValues(typeof(ILOpCode.Code))) {
|
||||||
|
int xCodeValue = (int)xCode;
|
||||||
|
if (xCodeValue <= 0xFF) {
|
||||||
|
mILOpsLo[xCodeValue] = xCtor;
|
||||||
} else {
|
} else {
|
||||||
mILOpsHi[(uint)xCode & 0xFF] = xCtor;
|
mILOpsHi[xCodeValue & 0xFF] = xCtor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -101,12 +104,16 @@ namespace Cosmos.IL2CPU {
|
||||||
foreach (var xOpCode in xOpCodes) {
|
foreach (var xOpCode in xOpCodes) {
|
||||||
//InstructionCount++;
|
//InstructionCount++;
|
||||||
ConstructorInfo xCtor;
|
ConstructorInfo xCtor;
|
||||||
if ((uint)xOpCode.OpCode <= 0xFF) {
|
uint xOpCodeVal = (uint)xOpCode.OpCode;
|
||||||
xCtor = mILOpsLo[(uint)xOpCode.OpCode];
|
if (xOpCodeVal <= 0xFF) {
|
||||||
|
xCtor = mILOpsLo[xOpCodeVal];
|
||||||
} else {
|
} 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});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue