mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-21 21:38:52 +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 {
|
||||
public class ILOpProfiler : Cosmos.IL2CPU.ILOp {
|
||||
protected ILOpProfiler(ILOpCode aOpCode)
|
||||
public ILOpProfiler(ILOpCode aOpCode)
|
||||
: base(aOpCode) {
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@
|
|||
<Compile Include="ILOpCode.cs" />
|
||||
<Compile Include="ILOpCodes\InlineI.cs" />
|
||||
<Compile Include="ILOpCodes\InlineNone.cs" />
|
||||
<Compile Include="ILOpCodes\InlineVar.cs" />
|
||||
<Compile Include="ILReader.cs" />
|
||||
<Compile Include="OpCodeAttribute.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
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:
|
||||
// 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 {
|
||||
|
|
|
|||
|
|
@ -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});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue