This commit is contained in:
mterwoord_cp 2007-09-05 13:51:29 +00:00
parent 491be780f8
commit 71ecc7cdf5
25 changed files with 85 additions and 69 deletions

View file

@ -19,7 +19,15 @@ namespace HelloWorld {
object x = "Hello, World!";
}
public static void EmptyMethod() {
}
public static void CallEmptyMethod() {
EmptyMethod();
}
public static void Main() {
CallEmptyMethod();
CallInteger();
Integer();
StringViaCtor();

View file

@ -8,13 +8,17 @@ namespace IL2CPU {
public class Program {
public static void Main(string[] args) {
try {
string exeName = "HelloWorldMetal.exe";
if(args.Length ==1 ) {
exeName = args[0];
}
Engine e = new Engine();
e.DebugLog += delegate(string aMessage) {
Console.WriteLine(aMessage);
};
using (FileStream fs = new FileStream(@"output.asm", FileMode.Create)) {
using (StreamWriter br = new StreamWriter(fs)) {
e.Execute("HelloWorldMetal.exe", TargetPlatformEnum.x86, br);
e.Execute(exeName, TargetPlatformEnum.x86, br);
}
}
} catch (Exception E) {

View file

@ -7,11 +7,16 @@ using CPU = Indy.IL2CPU.Assembler.X86;
namespace Indy.IL2CPU.IL.X86 {
[OpCode(Code.Br_S)]
public class Br_S: Op {
private bool mIsFake;
public Br_S(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo)
: base(aInstruction, aMethodInfo) {
// next physical opcode is +2, because the opcode is singlebyte, and has a byte as param
mIsFake = aInstruction.Next.Offset == (aInstruction.Offset + 2);
}
public override void Assemble() {
throw new NotImplementedException("This file has been autogenerated and not been changed afterwards!");
if (!mIsFake) {
throw new NotImplementedException("This file has been autogenerated and not been changed afterwards!");
}
}
}
}

View file

@ -18,7 +18,7 @@ namespace Indy.IL2CPU.IL.X86 {
public void Assemble(string aMethod) {
Call(aMethod);
if(HasResult) {
Push("EAX");
// Push("EAX");
}
}

View file

@ -7,26 +7,29 @@ using CPU = Indy.IL2CPU.Assembler.X86;
namespace Indy.IL2CPU.IL.X86 {
[OpCode(Code.Ldc_I4)]
public class Ldc_I4: Op {
private int mOffset;
protected void SetLocalIndex(int aIndex, MethodInformation aMethodInfo) {
mOffset = aMethodInfo.Locals[aIndex].Offset + aMethodInfo.Locals[aIndex].Size + 4;
private string mValue;
protected void SetValue(int aValue) {
SetValue(aValue.ToString());
}
protected void SetValue(string aValue) {
mValue = aValue;
}
public Ldc_I4(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo)
: base(aInstruction, aMethodInfo) {
int xLocalIndex;
if(Int32.TryParse((aInstruction.Operand ?? "").ToString(), out xLocalIndex)) {
SetLocalIndex(xLocalIndex, aMethodInfo);
if(aInstruction.Operand != null) {
SetValue(aInstruction.Operand.ToString());
}
}
public int Offset {
public string Value {
get {
return mOffset;
return mValue;
}
}
public override sealed void Assemble() {
Pushd("[esp + " + mOffset + "]");
Pushd(Value);
}
}
}

View file

@ -9,7 +9,7 @@ namespace Indy.IL2CPU.IL.X86 {
public class Ldc_I4_0: Ldc_I4 {
public Ldc_I4_0(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo)
: base(aInstruction, aMethodInfo) {
SetLocalIndex(0, aMethodInfo);
SetValue(0);
}
}
}

View file

@ -9,7 +9,7 @@ namespace Indy.IL2CPU.IL.X86 {
public class Ldc_I4_1: Ldc_I4 {
public Ldc_I4_1(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo)
: base(aInstruction, aMethodInfo) {
SetLocalIndex(1, aMethodInfo);
SetValue(1);
}
}
}

View file

@ -6,12 +6,10 @@ using CPU = Indy.IL2CPU.Assembler.X86;
namespace Indy.IL2CPU.IL.X86 {
[OpCode(Code.Ldc_I4_2)]
public class Ldc_I4_2: Op {
public class Ldc_I4_2: Ldc_I4 {
public Ldc_I4_2(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo)
: base(aInstruction, aMethodInfo) {
}
public override void Assemble() {
throw new NotImplementedException("This file has been autogenerated and not been changed afterwards!");
SetValue(2);
}
}
}

View file

@ -6,12 +6,10 @@ using CPU = Indy.IL2CPU.Assembler.X86;
namespace Indy.IL2CPU.IL.X86 {
[OpCode(Code.Ldc_I4_3)]
public class Ldc_I4_3: Op {
public class Ldc_I4_3: Ldc_I4 {
public Ldc_I4_3(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo)
: base(aInstruction, aMethodInfo) {
}
public override void Assemble() {
throw new NotImplementedException("This file has been autogenerated and not been changed afterwards!");
SetValue(3);
}
}
}

View file

@ -6,12 +6,10 @@ using CPU = Indy.IL2CPU.Assembler.X86;
namespace Indy.IL2CPU.IL.X86 {
[OpCode(Code.Ldc_I4_4)]
public class Ldc_I4_4: Op {
public class Ldc_I4_4: Ldc_I4 {
public Ldc_I4_4(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo)
: base(aInstruction, aMethodInfo) {
}
public override void Assemble() {
throw new NotImplementedException("This file has been autogenerated and not been changed afterwards!");
SetValue(3);
}
}
}

View file

@ -6,12 +6,10 @@ using CPU = Indy.IL2CPU.Assembler.X86;
namespace Indy.IL2CPU.IL.X86 {
[OpCode(Code.Ldc_I4_5)]
public class Ldc_I4_5: Op {
public class Ldc_I4_5: Ldc_I4 {
public Ldc_I4_5(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo)
: base(aInstruction, aMethodInfo) {
}
public override void Assemble() {
throw new NotImplementedException("This file has been autogenerated and not been changed afterwards!");
SetValue(5);
}
}
}

View file

@ -6,12 +6,10 @@ using CPU = Indy.IL2CPU.Assembler.X86;
namespace Indy.IL2CPU.IL.X86 {
[OpCode(Code.Ldc_I4_6)]
public class Ldc_I4_6: Op {
public class Ldc_I4_6: Ldc_I4 {
public Ldc_I4_6(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo)
: base(aInstruction, aMethodInfo) {
}
public override void Assemble() {
throw new NotImplementedException("This file has been autogenerated and not been changed afterwards!");
SetValue(6);
}
}
}

View file

@ -6,12 +6,10 @@ using CPU = Indy.IL2CPU.Assembler.X86;
namespace Indy.IL2CPU.IL.X86 {
[OpCode(Code.Ldc_I4_7)]
public class Ldc_I4_7: Op {
public class Ldc_I4_7: Ldc_I4 {
public Ldc_I4_7(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo)
: base(aInstruction, aMethodInfo) {
}
public override void Assemble() {
throw new NotImplementedException("This file has been autogenerated and not been changed afterwards!");
SetValue(7);
}
}
}

View file

@ -6,12 +6,10 @@ using CPU = Indy.IL2CPU.Assembler.X86;
namespace Indy.IL2CPU.IL.X86 {
[OpCode(Code.Ldc_I4_8)]
public class Ldc_I4_8: Op {
public class Ldc_I4_8: Ldc_I4 {
public Ldc_I4_8(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo)
: base(aInstruction, aMethodInfo) {
}
public override void Assemble() {
throw new NotImplementedException("This file has been autogenerated and not been changed afterwards!");
SetValue(8);
}
}
}

View file

@ -6,12 +6,10 @@ using CPU = Indy.IL2CPU.Assembler.X86;
namespace Indy.IL2CPU.IL.X86 {
[OpCode(Code.Ldc_I4_M1)]
public class Ldc_I4_M1: Op {
public class Ldc_I4_M1: Ldc_I4 {
public Ldc_I4_M1(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo)
: base(aInstruction, aMethodInfo) {
}
public override void Assemble() {
throw new NotImplementedException("This file has been autogenerated and not been changed afterwards!");
SetValue(-1);
}
}
}

View file

@ -6,15 +6,9 @@ using CPU = Indy.IL2CPU.Assembler.X86;
namespace Indy.IL2CPU.IL.X86 {
[OpCode(Code.Ldc_I4_S)]
public class Ldc_I4_S: Op {
public readonly string Value;
public class Ldc_I4_S: Ldc_I4 {
public Ldc_I4_S(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo)
: base(aInstruction, aMethodInfo) {
Value = (aInstruction.Operand ?? "").ToString();
}
public override void Assemble() {
Pushd(Value);
}
}
}

View file

@ -9,7 +9,7 @@ namespace Indy.IL2CPU.IL.X86 {
public class Ldloc: Op {
private int mOffset;
protected void SetLocalIndex(int aIndex, MethodInformation aMethodInfo) {
mOffset = aMethodInfo.Locals[aIndex].Offset + aMethodInfo.Locals[aIndex].Size + 4;
mOffset = aMethodInfo.Locals[aIndex].Offset + aMethodInfo.Locals[aIndex].Size + 8;
}
public Ldloc(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo)
: base(aInstruction, aMethodInfo) {
@ -27,7 +27,7 @@ namespace Indy.IL2CPU.IL.X86 {
public sealed override void Assemble() {
Push("eax");
Move("eax", "[esp+" + mOffset + "]");
Move("eax", "[ebp+" + mOffset + "]");
}
}
}

View file

@ -9,7 +9,7 @@ namespace Indy.IL2CPU.IL.X86 {
public class Ldloca: Op {
private int mOffset;
protected void SetLocalIndex(int aIndex, MethodInformation aMethodInfo) {
mOffset = aMethodInfo.Locals[aIndex].Offset + aMethodInfo.Locals[aIndex].Size + 4;
mOffset = aMethodInfo.Locals[aIndex].Offset + aMethodInfo.Locals[aIndex].Size + 84;
}
public Ldloca(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo)
: base(aInstruction, aMethodInfo) {
@ -27,7 +27,7 @@ namespace Indy.IL2CPU.IL.X86 {
public sealed override void Assemble() {
Push("eax");
Move("eax", "[esp+" + mOffset + "]");
Move("eax", "[ebp+" + mOffset + "]");
}
}
}

View file

@ -15,7 +15,7 @@ namespace Indy.IL2CPU.IL.X86 {
public Newobj(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo)
: base(aInstruction, aMethodInfo) {
CtorName = new Asm.Label(((MethodReference)aInstruction.Operand).Name).Name;
CtorName = new Asm.Label((MethodReference)aInstruction.Operand).Name;
}
public override void Assemble() {

View file

@ -7,11 +7,15 @@ using CPU = Indy.IL2CPU.Assembler.X86;
namespace Indy.IL2CPU.IL.X86 {
[OpCode(Code.Ret)]
public class Ret: Op {
private bool mHasReturn;
public Ret(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo)
: base(aInstruction, aMethodInfo) {
mHasReturn = aMethodInfo.HasReturnValue;
}
public override void Assemble() {
//Ret();
if (mHasReturn) {
//Push("eax");
}
}
}
}

View file

@ -7,9 +7,9 @@ using CPU = Indy.IL2CPU.Assembler.X86;
namespace Indy.IL2CPU.IL.X86 {
[OpCode(Code.Stloc)]
public class Stloc: Op {
private int mOffset;
private string mAddress;
protected void SetLocalIndex(int aIndex, MethodInformation aMethodInfo) {
mOffset = aMethodInfo.Locals[aIndex].Offset + aMethodInfo.Locals[aIndex].Size + 4;
mAddress = aMethodInfo.Locals[aIndex].VirtualAddress;
}
public Stloc(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo)
: base(aInstruction, aMethodInfo) {
@ -19,15 +19,15 @@ namespace Indy.IL2CPU.IL.X86 {
}
}
public int Offset {
public string Address {
get {
return mOffset;
return mAddress;
}
}
public sealed override void Assemble() {
Pop("eax");
Move("[esp+" + mOffset + "]", "eax");
Move("[" + mAddress + "]", "eax");
}
}
}

View file

@ -9,6 +9,7 @@ namespace Indy.IL2CPU.IL.X86 {
public class X86MethodFooterOp: MethodFooterOp {
public readonly int TotalLocalsSize = 0;
public readonly int TotalArgsSize = 0;
public readonly int LocalsCount = 0;
public X86MethodFooterOp(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo)
: base(aInstruction, aMethodInfo) {
if (aMethodInfo.Arguments.Length > 0) {
@ -17,10 +18,18 @@ namespace Indy.IL2CPU.IL.X86 {
if (aMethodInfo.Locals.Length > 0) {
TotalLocalsSize += aMethodInfo.Locals[aMethodInfo.Locals.Length - 1].Offset + aMethodInfo.Locals[aMethodInfo.Locals.Length - 1].Size;
}
LocalsCount = aMethodInfo.Locals.Length;
if(aMethodInfo.HasReturnValue) {
TotalLocalsSize += 4;
LocalsCount++;
}
}
public override void Assemble() {
Assembler.Add(new CPU.Add("esp", TotalLocalsSize.ToString()));
for (int i = 0; i < LocalsCount; i++) {
Assembler.Add(new CPU.Pop("ebp"));
}
Assembler.Add(new CPU.Ret(TotalArgsSize.ToString()));
}
}

View file

@ -18,8 +18,9 @@ namespace Indy.IL2CPU.IL.X86 {
public override void Assemble() {
// TODO: add support for variables with a diff datasize, other than 32bit
Assembler.Add(new CPU.Label(LabelName));
Assembler.Add(new CPUx86.Move("ebp", "esp"));
for (int i = 0; i < LocalsCount; i++) {
Assembler.Add(new CPUx86.Pushd(" 0"));
Assembler.Add(new CPUx86.Pushd("ebp"));
}
}
}

View file

@ -9,9 +9,11 @@ namespace Indy.IL2CPU.IL {
public Variable(int aOffset, int aSize) {
Offset = aOffset;
Size = aSize;
VirtualAddress = "ebp + " + (Offset + Size + 8);
}
public readonly int Offset;
public readonly int Size;
public readonly string VirtualAddress;
}
public struct Argument {
@ -24,14 +26,16 @@ namespace Indy.IL2CPU.IL {
public readonly int Offset;
}
public MethodInformation(string aLabelName, Variable[] aLocals, Argument[] aArguments) {
public MethodInformation(string aLabelName, Variable[] aLocals, Argument[] aArguments, bool aHasReturnValue) {
Locals = aLocals;
LabelName = aLabelName;
Arguments = aArguments;
HasReturnValue = aHasReturnValue;
}
public readonly string LabelName;
public readonly Variable[] Locals;
public readonly Argument[] Arguments;
public readonly bool HasReturnValue;
}
}

View file

@ -11,9 +11,9 @@ using Mono.Cecil;
using Mono.Cecil.Cil;
using Instruction = Mono.Cecil.Cil.Instruction;
ERROR
//ERROR
We need a special local vars register in the assembly
//We need a special local vars register in the assembly
namespace Indy.IL2CPU {
public class MethodDefinitionComparer: IComparer<MethodDefinition> {
@ -122,7 +122,7 @@ namespace Indy.IL2CPU {
xArgs[i] = new MethodInformation.Argument(xArgSize, xCurOffset);
xCurOffset += xArgSize;
}
xMethodInfo = new MethodInformation(new Label(xCurrentMethod).Name, xVars, xArgs);
xMethodInfo = new MethodInformation(new Label(xCurrentMethod).Name, xVars, xArgs, !xCurrentMethod.ReturnType.ReturnType.FullName.Contains("System.Void"));
}
IL.Op xOp = GetOpFromType(mMap.MethodHeaderOp, null, xMethodInfo);
xOp.Assembler = mAssembler;