This commit is contained in:
kudzu_cp 2009-07-24 19:50:53 +00:00
parent a3fccd764b
commit d1f837f66b
6 changed files with 58 additions and 84 deletions

View file

@ -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) {
}
}

View file

@ -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" />

View file

@ -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;
}
}

View 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;
}
}
}

View file

@ -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 {

View file

@ -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});
}
}
}