From 72092fc41d089f69a95c8a93c9660bd9d88c7a3f Mon Sep 17 00:00:00 2001 From: LostTheBlack_cp Date: Tue, 18 Mar 2008 13:32:24 +0000 Subject: [PATCH] [+] Fixed issue #4054 (Switch-Case causes InvalidOperationException). [*] All conditional branch instructions on longs marked NotImplemented. [!] Someone familiar enough should review compiler's comparisons handling. --- source/Boot/TestSuite/Tests/MathTest.cs | 2 + source/Boot/TestSuite/Tests/OperatorsTest.cs | 2 +- source/Indy.IL2CPU.IL.X86/Beq.cs | 3 + source/Indy.IL2CPU.IL.X86/Bge.cs | 2 +- source/Indy.IL2CPU.IL.X86/Bge_Un.cs | 3 + source/Indy.IL2CPU.IL.X86/Bgt.cs | 3 + source/Indy.IL2CPU.IL.X86/Bgt_Un.cs | 5 +- source/Indy.IL2CPU.IL.X86/Ble.cs | 3 + source/Indy.IL2CPU.IL.X86/Ble_Un.cs | 3 + source/Indy.IL2CPU.IL.X86/Blt.cs | 85 +++++++++++++++----- source/Indy.IL2CPU.IL.X86/Blt_Un.cs | 2 + source/Indy.IL2CPU.IL.X86/Bne_Un.cs | 3 + 12 files changed, 95 insertions(+), 21 deletions(-) diff --git a/source/Boot/TestSuite/Tests/MathTest.cs b/source/Boot/TestSuite/Tests/MathTest.cs index 38868ccf0..bff5dd15c 100644 --- a/source/Boot/TestSuite/Tests/MathTest.cs +++ b/source/Boot/TestSuite/Tests/MathTest.cs @@ -27,6 +27,8 @@ namespace TestSuite.Tests Assert(2 * 2 == 4, "2 * 2 == 4"); Assert(6 / 2 == 3, "6 / 2 == 3"); Assert(5 - 2 == 3, "5 - 2 == 3"); + Assert(-1 < 1, "-1 < 1"); + Assert(0xFFFFFFFFu > 1u, "0xFFFFFFFFu > 1u"); Assert(2 + 5 * 2 == 12, "2 + 5 * 2 == 12"); Assert((2 + 5) * 2 == 14, "(2 + 5) * 2 == 14"); long al = 0x1FFFFFFFF; diff --git a/source/Boot/TestSuite/Tests/OperatorsTest.cs b/source/Boot/TestSuite/Tests/OperatorsTest.cs index 9c6d3eb8f..51788713d 100644 --- a/source/Boot/TestSuite/Tests/OperatorsTest.cs +++ b/source/Boot/TestSuite/Tests/OperatorsTest.cs @@ -24,7 +24,7 @@ namespace TestSuite.Tests public override void Test() { //switch block - int c = 42; //BUG: Fails if type is byte - see Work Item #4054 + byte c = 42; //BUG: Fails if type is byte - see Work Item #4054 switch (c) { case 192: diff --git a/source/Indy.IL2CPU.IL.X86/Beq.cs b/source/Indy.IL2CPU.IL.X86/Beq.cs index 1769f25bb..6ae4a60ad 100644 --- a/source/Indy.IL2CPU.IL.X86/Beq.cs +++ b/source/Indy.IL2CPU.IL.X86/Beq.cs @@ -26,6 +26,7 @@ namespace Indy.IL2CPU.IL.X86 { string LabelFalse = BaseLabel + "False"; new CPUx86.Pop(CPUx86.Registers.EAX); if (xStackContent.Size > 4) { + throw new NotImplementedException("long comprasion is not implemented"); new CPUx86.Add("esp", "4"); } new CPUx86.Compare(CPUx86.Registers.EAX, CPUx86.Registers.AtESP); @@ -34,12 +35,14 @@ namespace Indy.IL2CPU.IL.X86 { new CPU.Label(LabelTrue); new CPUx86.Add(CPUx86.Registers.ESP, "4"); if (xStackContent.Size > 4) { + throw new NotImplementedException("long comprasion is not implemented"); new CPUx86.Add("esp", "4"); } new CPUx86.JumpAlways(TargetLabel); new CPU.Label(LabelFalse); new CPUx86.Add(CPUx86.Registers.ESP, "4"); if (xStackContent.Size > 4) { + throw new NotImplementedException("long comprasion is not implemented"); new CPUx86.Add("esp", "4"); } } diff --git a/source/Indy.IL2CPU.IL.X86/Bge.cs b/source/Indy.IL2CPU.IL.X86/Bge.cs index df771baa0..552180937 100644 --- a/source/Indy.IL2CPU.IL.X86/Bge.cs +++ b/source/Indy.IL2CPU.IL.X86/Bge.cs @@ -44,7 +44,7 @@ namespace Indy.IL2CPU.IL.X86 { } private void DoAssemble64Bit() { - throw new Exception("Not implemented"); + throw new NotImplementedException("long comprasion is not implemented"); string BaseLabel = CurInstructionLabel + "__"; string LabelTrue = BaseLabel + "True"; string LabelFalse = BaseLabel + "False"; diff --git a/source/Indy.IL2CPU.IL.X86/Bge_Un.cs b/source/Indy.IL2CPU.IL.X86/Bge_Un.cs index 3db578ef4..572a56238 100644 --- a/source/Indy.IL2CPU.IL.X86/Bge_Un.cs +++ b/source/Indy.IL2CPU.IL.X86/Bge_Un.cs @@ -28,6 +28,7 @@ namespace Indy.IL2CPU.IL.X86 { string LabelFalse = BaseLabel + "False"; new CPUx86.Pop(CPUx86.Registers.EAX); if (xSize > 4) { + throw new NotImplementedException("long comprasion is not implemented"); new CPUx86.Add("esp", "4"); } new CPUx86.Compare(CPUx86.Registers.EAX, CPUx86.Registers.AtESP); @@ -35,12 +36,14 @@ namespace Indy.IL2CPU.IL.X86 { new CPUx86.JumpAlways(LabelTrue); new CPU.Label(LabelTrue); if (xSize > 4) { + throw new NotImplementedException("long comprasion is not implemented"); new CPUx86.Add("esp", "4"); } new CPUx86.Add(CPUx86.Registers.ESP, "4"); new CPUx86.JumpAlways(TargetLabel); new CPU.Label(LabelFalse); if (xSize > 4) { + throw new NotImplementedException("long comprasion is not implemented"); new CPUx86.Add("esp", "4"); } new CPUx86.Add(CPUx86.Registers.ESP, "4"); diff --git a/source/Indy.IL2CPU.IL.X86/Bgt.cs b/source/Indy.IL2CPU.IL.X86/Bgt.cs index da5411b95..c39fa32d1 100644 --- a/source/Indy.IL2CPU.IL.X86/Bgt.cs +++ b/source/Indy.IL2CPU.IL.X86/Bgt.cs @@ -29,6 +29,7 @@ namespace Indy.IL2CPU.IL.X86 { } new CPUx86.Pop(CPUx86.Registers.EAX); if (xStackContent.Size > 4) { + throw new NotImplementedException("long comprasion is not implemented"); new CPUx86.Add("esp", "4"); } new CPUx86.Compare(CPUx86.Registers.EAX, CPUx86.Registers.AtESP); @@ -37,12 +38,14 @@ namespace Indy.IL2CPU.IL.X86 { new CPU.Label(LabelTrue); new CPUx86.Add(CPUx86.Registers.ESP, "4"); if (xStackContent.Size > 4) { + throw new NotImplementedException("long comprasion is not implemented"); new CPUx86.Add("esp", "4"); } new CPUx86.JumpAlways(TargetLabel); new CPU.Label(LabelFalse); new CPUx86.Add(CPUx86.Registers.ESP, "4"); if (xStackContent.Size > 4) { + throw new NotImplementedException("long comprasion is not implemented"); new CPUx86.Add("esp", "4"); } } diff --git a/source/Indy.IL2CPU.IL.X86/Bgt_Un.cs b/source/Indy.IL2CPU.IL.X86/Bgt_Un.cs index 652316b56..9b124e167 100644 --- a/source/Indy.IL2CPU.IL.X86/Bgt_Un.cs +++ b/source/Indy.IL2CPU.IL.X86/Bgt_Un.cs @@ -16,7 +16,7 @@ namespace Indy.IL2CPU.IL.X86 { CurInstructionLabel = GetInstructionLabel(aReader); } public override void DoAssemble() { - if (Assembler.StackContents.Pop().IsFloat) { + if (Assembler.StackContents.Peek().IsFloat) { throw new Exception("Floats not yet supported"); } string BaseLabel = CurInstructionLabel + "__"; @@ -29,6 +29,7 @@ namespace Indy.IL2CPU.IL.X86 { } new CPUx86.Pop(CPUx86.Registers.EAX); if (xSize > 4) { + throw new NotImplementedException("long comprasion is not implemented"); new CPUx86.Add("esp", "4"); } new CPUx86.Compare(CPUx86.Registers.EAX, CPUx86.Registers.AtESP); @@ -37,12 +38,14 @@ namespace Indy.IL2CPU.IL.X86 { new CPU.Label(LabelTrue); new CPUx86.Add(CPUx86.Registers.ESP, "4"); if (xSize > 4) { + throw new NotImplementedException("long comprasion is not implemented"); new CPUx86.Add("esp", "4"); } new CPUx86.JumpAlways(TargetLabel); new CPU.Label(LabelFalse); new CPUx86.Add(CPUx86.Registers.ESP, "4"); if (xSize > 4) { + throw new NotImplementedException("long comprasion is not implemented"); new CPUx86.Add("esp", "4"); } diff --git a/source/Indy.IL2CPU.IL.X86/Ble.cs b/source/Indy.IL2CPU.IL.X86/Ble.cs index 4acbf4f90..eaa22bf25 100644 --- a/source/Indy.IL2CPU.IL.X86/Ble.cs +++ b/source/Indy.IL2CPU.IL.X86/Ble.cs @@ -28,6 +28,7 @@ namespace Indy.IL2CPU.IL.X86 { string LabelFalse = BaseLabel + "False"; new CPUx86.Pop(CPUx86.Registers.EAX); if (xSize > 4) { + throw new NotImplementedException("long comprasion is not implemented"); new CPUx86.Add(CPUx86.Registers.ESP, "4"); } new CPUx86.Compare(CPUx86.Registers.EAX, CPUx86.Registers.AtESP); @@ -35,12 +36,14 @@ namespace Indy.IL2CPU.IL.X86 { new CPUx86.JumpAlways(LabelTrue); new CPU.Label(LabelTrue); if (xSize > 4) { + throw new NotImplementedException("long comprasion is not implemented"); new CPUx86.Add(CPUx86.Registers.ESP, "4"); } new CPUx86.Add(CPUx86.Registers.ESP, "4"); new CPUx86.JumpAlways(TargetLabel); new CPU.Label(LabelFalse); if (xSize > 4) { + throw new NotImplementedException("long comprasion is not implemented"); new CPUx86.Add(CPUx86.Registers.ESP, "4"); } new CPUx86.Add(CPUx86.Registers.ESP, "4"); diff --git a/source/Indy.IL2CPU.IL.X86/Ble_Un.cs b/source/Indy.IL2CPU.IL.X86/Ble_Un.cs index 1c9b9eef7..cf8bfb2d4 100644 --- a/source/Indy.IL2CPU.IL.X86/Ble_Un.cs +++ b/source/Indy.IL2CPU.IL.X86/Ble_Un.cs @@ -32,6 +32,7 @@ namespace Indy.IL2CPU.IL.X86 { string LabelFalse = BaseLabel + "False"; new CPUx86.Pop(CPUx86.Registers.EAX); if (xSize > 4) { + throw new NotImplementedException("long comprasion is not implemented"); new CPUx86.Add(CPUx86.Registers.ESP, "4"); } new CPUx86.Compare(CPUx86.Registers.EAX, CPUx86.Registers.AtESP); @@ -39,12 +40,14 @@ namespace Indy.IL2CPU.IL.X86 { new CPUx86.JumpAlways(LabelTrue); new CPU.Label(LabelTrue); if (xSize > 4) { + throw new NotImplementedException("long comprasion is not implemented"); new CPUx86.Add(CPUx86.Registers.ESP, "4"); } new CPUx86.Add(CPUx86.Registers.ESP, "4"); new CPUx86.JumpAlways(TargetLabel); new CPU.Label(LabelFalse); if (xSize > 4) { + throw new NotImplementedException("long comprasion is not implemented"); new CPUx86.Add(CPUx86.Registers.ESP, "4"); } new CPUx86.Add(CPUx86.Registers.ESP, "4"); diff --git a/source/Indy.IL2CPU.IL.X86/Blt.cs b/source/Indy.IL2CPU.IL.X86/Blt.cs index 345aad866..fa3fc797c 100644 --- a/source/Indy.IL2CPU.IL.X86/Blt.cs +++ b/source/Indy.IL2CPU.IL.X86/Blt.cs @@ -10,37 +10,86 @@ namespace Indy.IL2CPU.IL.X86 { public class Blt: Op { public readonly string TargetLabel; public readonly string CurInstructionLabel; + public readonly string NextInstructionLabel; public Blt(ILReader aReader, MethodInformation aMethodInfo) : base(aReader, aMethodInfo) { TargetLabel = GetInstructionLabel(aReader.OperandValueBranchPosition); CurInstructionLabel = GetInstructionLabel(aReader); + NextInstructionLabel = GetInstructionLabel(aReader.NextPosition); } public override void DoAssemble() { if (Assembler.StackContents.Peek().IsFloat) { throw new Exception("Floats not yet supported!"); } - int xSize = Math.Max(Assembler.StackContents.Pop().Size, Assembler.StackContents.Pop().Size); - if(xSize>8)throw new Exception("StackSize>8 not supported"); + var right = Assembler.StackContents.Pop(); + var left = Assembler.StackContents.Pop(); + if (right.Size != left.Size) + throw new NotImplementedException("mixed size operations are not implemented"); + + int xSize = right.Size; + + if (xSize > 8) + throw new NotImplementedException("StackSize>8 not supported"); + string BaseLabel = CurInstructionLabel + "__"; string LabelTrue = BaseLabel + "True"; string LabelFalse = BaseLabel + "False"; - new CPUx86.Pop(CPUx86.Registers.ECX); - if (xSize > 4) { - new CPUx86.Add("esp", "4"); + + switch(xSize) + { + case 4: + new CPUx86.Pop(CPUx86.Registers.ECX); + //if (xSize > 4) + //{ + // throw new NotImplementedException("long comprasion is not implemented"); + // new CPUx86.Add("esp", "4"); + //} + new CPUx86.Pop(CPUx86.Registers.EAX); + //if (xSize > 4) + //{ + // throw new NotImplementedException("long comprasion is not implemented"); + // new CPUx86.Add("esp", "4"); + //} + new CPUx86.Pushd(CPUx86.Registers.ECX); + new CPUx86.Compare(CPUx86.Registers.EAX, CPUx86.Registers.AtESP); + new CPUx86.JumpIfLess(LabelTrue); + new CPUx86.JumpAlways(LabelFalse); + new CPU.Label(LabelTrue); + new CPUx86.Add(CPUx86.Registers.ESP, "4"); + new CPUx86.JumpAlways(TargetLabel); + new CPU.Label(LabelFalse); + new CPUx86.Add(CPUx86.Registers.ESP, "4"); + break; + case 8: + new CPUx86.Pop(CPUx86.Registers.EBX); //ebx = lowright + new CPUx86.Pop(CPUx86.Registers.EAX); //eax = highright + new CPUx86.Pop(CPUx86.Registers.ECX); //ecx = lowleft + new CPUx86.Pop(CPUx86.Registers.EDX); //edx = high left + + new CPUx86.Compare(CPUx86.Registers.EDX, CPUx86.Registers.EAX); + + new CPUx86.JumpIfLess(LabelTrue); //значение на глубине меньше + new CPUx86.JumpIfGreater(NextInstructionLabel); //значение на глубине больше + + if ((0xFFFFFFFF > 0xFFFFFFE) && (0xFFFF0000 < 0xFFFFFFFE)) + { + new CPUx86.Compare(CPUx86.Registers.ECX, CPUx86.Registers.EBX); + + new CPUx86.JumpIfLess(LabelTrue); + new CPUx86.JumpAlways(NextInstructionLabel); + } else + throw new NotImplementedException("long comprasion is not implemented"); + + //значения старших + + new CPU.Label(LabelTrue); + new CPUx86.JumpAlways(TargetLabel); + + //throw new NotImplementedException("long comprasion is not implemented"); + break; + default: + throw new NotSupportedException(string.Format("comprasion of {0} byte values", xSize)); } - new CPUx86.Pop(CPUx86.Registers.EAX); - if (xSize > 4) { - new CPUx86.Add("esp", "4"); - } - new CPUx86.Pushd(CPUx86.Registers.ECX); - new CPUx86.Compare(CPUx86.Registers.EAX, CPUx86.Registers.AtESP); - new CPUx86.JumpIfLess(LabelTrue); - new CPUx86.JumpAlways(LabelFalse); - new CPU.Label(LabelTrue); - new CPUx86.Add(CPUx86.Registers.ESP, "4"); - new CPUx86.JumpAlways(TargetLabel); - new CPU.Label(LabelFalse); - new CPUx86.Add(CPUx86.Registers.ESP, "4"); } } } \ No newline at end of file diff --git a/source/Indy.IL2CPU.IL.X86/Blt_Un.cs b/source/Indy.IL2CPU.IL.X86/Blt_Un.cs index 990b44739..eef3638da 100644 --- a/source/Indy.IL2CPU.IL.X86/Blt_Un.cs +++ b/source/Indy.IL2CPU.IL.X86/Blt_Un.cs @@ -28,10 +28,12 @@ namespace Indy.IL2CPU.IL.X86 { string LabelFalse = BaseLabel + "False"; new CPUx86.Pop(CPUx86.Registers.ECX); if (xSize > 4) { + throw new NotImplementedException("long comprasion is not implemented"); new CPUx86.Add("esp", "4"); } new CPUx86.Pop(CPUx86.Registers.EAX); if (xSize > 4) { + throw new NotImplementedException("long comprasion is not implemented"); new CPUx86.Add("esp", "4"); } new CPUx86.Pushd(CPUx86.Registers.ECX); diff --git a/source/Indy.IL2CPU.IL.X86/Bne_Un.cs b/source/Indy.IL2CPU.IL.X86/Bne_Un.cs index f59816b71..81881772d 100644 --- a/source/Indy.IL2CPU.IL.X86/Bne_Un.cs +++ b/source/Indy.IL2CPU.IL.X86/Bne_Un.cs @@ -28,6 +28,7 @@ namespace Indy.IL2CPU.IL.X86 { string LabelFalse = BaseLabel + "False"; new CPUx86.Pop(CPUx86.Registers.EAX); if (xSize > 4) { + throw new NotImplementedException("long comprasion is not implemented"); new CPUx86.Add("esp", "4"); } new CPUx86.Compare(CPUx86.Registers.EAX, CPUx86.Registers.AtESP); @@ -36,12 +37,14 @@ namespace Indy.IL2CPU.IL.X86 { new CPU.Label(LabelFalse); new CPUx86.Add(CPUx86.Registers.ESP, "4"); if (xSize > 4) { + throw new NotImplementedException("long comprasion is not implemented"); new CPUx86.Add("esp", "4"); } new CPUx86.JumpAlways(TargetLabel); new CPU.Label(LabelTrue); new CPUx86.Add(CPUx86.Registers.ESP, "4"); if (xSize > 4) { + throw new NotImplementedException("long comprasion is not implemented"); new CPUx86.Add("esp", "4"); } }