Skip to content

Commit ecab282

Browse files
authored
Merge pull request #64 from Geramy/Implement-sub.ovf-#9
Added Sub_Ovh implementation.
2 parents 1666202 + b8abc71 commit ecab282

File tree

5 files changed

+179
-63
lines changed

5 files changed

+179
-63
lines changed

source/Cosmos.IL2CPU/IL/Add_Ovf.cs

Lines changed: 50 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2,58 +2,67 @@
22
using XSharp.Assembler.x86;
33
using XSharp;
44
using static XSharp.XSRegisters;
5+
using System.Reflection;
56

67
/* Add.Ovf is signed integer addition with check for overflow */
78
namespace Cosmos.IL2CPU.X86.IL
89
{
9-
[OpCode(ILOpCode.Code.Add_Ovf)]
10-
public class Add_Ovf : ILOp
10+
[OpCode(ILOpCode.Code.Add_Ovf)]
11+
public class Add_Ovf : ILOp
12+
{
13+
public Add_Ovf(XSharp.Assembler.Assembler aAsmblr)
14+
: base(aAsmblr)
1115
{
12-
public Add_Ovf(XSharp.Assembler.Assembler aAsmblr)
13-
: base(aAsmblr)
14-
{
15-
}
16+
}
1617

17-
public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
18-
{
19-
var xType = aOpCode.StackPopTypes[0];
20-
var xSize = SizeOfType(xType);
21-
var xIsFloat = TypeIsFloat(xType);
18+
public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
19+
{
20+
var xType = aOpCode.StackPopTypes[0];
21+
var xSize = SizeOfType(xType);
22+
var xIsFloat = TypeIsFloat(xType);
2223

23-
if (xIsFloat)
24-
{
25-
throw new Exception("Cosmos.IL2CPU.x86->IL->Add_Ovf.cs->Error: Expected signed integer operands but get float!");
26-
}
24+
if (xIsFloat)
25+
{
26+
throw new Exception("Cosmos.IL2CPU.x86->IL->Add_Ovf.cs->Error: Expected signed integer operands but get float!");
27+
}
2728

28-
if (xSize > 8)
29-
{
30-
//EmitNotImplementedException( Assembler, aServiceProvider, "Size '" + xSize.Size + "' not supported (add)", aCurrentLabel, aCurrentMethodInfo, aCurrentOffset, aNextLabel );
31-
throw new NotImplementedException("Cosmos.IL2CPU.x86->IL->Add_Ovf.cs->Error: StackSize > 8 not supported");
32-
}
33-
else
34-
{
35-
var xBaseLabel = GetLabel(aMethod, aOpCode) + ".";
36-
var xSuccessLabel = xBaseLabel + "Success";
37-
if (xSize > 4) // long
38-
{
39-
XS.Pop(EDX); // low part
40-
XS.Pop(EAX); // high part
41-
XS.Add(ESP, EDX, destinationIsIndirect: true);
42-
XS.AddWithCarry(ESP, EAX, destinationDisplacement: 4);
29+
if (xSize > 8)
30+
{
31+
//EmitNotImplementedException( Assembler, aServiceProvider, "Size '" + xSize.Size + "' not supported (add)", aCurrentLabel, aCurrentMethodInfo, aCurrentOffset, aNextLabel );
32+
throw new NotImplementedException("Cosmos.IL2CPU.x86->IL->Add_Ovf.cs->Error: StackSize > 8 not supported");
33+
}
34+
else
35+
{
36+
var xBaseLabel = GetLabel(aMethod, aOpCode) + ".";
37+
var xSuccessLabel = xBaseLabel + "Success";
38+
if (xSize > 4) // long
39+
{
40+
XS.Pop(EDX); // low part
41+
XS.Pop(EAX); // high part
42+
XS.Add(ESP, EDX, destinationIsIndirect: true);
43+
XS.AddWithCarry(ESP, EAX, destinationDisplacement: 4);
4344

44-
}
45-
else //integer
46-
{
45+
}
46+
else //integer
47+
{
4748

48-
XS.Pop(EAX);
49-
XS.Add(ESP, EAX, destinationIsIndirect: true);
50-
}
49+
XS.Pop(EAX);
50+
XS.Add(ESP, EAX, destinationIsIndirect: true);
51+
}
5152

52-
// Let's check if we add overflow and if so throw OverflowException
53-
XS.Jump(ConditionalTestEnum.NoOverflow, xSuccessLabel);
54-
ThrowOverflowException();
55-
XS.Label(xSuccessLabel);
56-
}
53+
// Let's check if we add overflow and if so throw OverflowException
54+
XS.Jump(ConditionalTestEnum.NoOverflow, xSuccessLabel);
55+
if (xSize > 4) // Hack to stop stack corruption
56+
{
57+
XS.Add(ESP, 8);
58+
}
59+
else
60+
{
61+
XS.Add(ESP, 4);
5762
}
63+
Call.DoExecute(Assembler, aMethod, typeof(ExceptionHelper).GetMethod("ThrowOverflow", BindingFlags.Static | BindingFlags.Public), aOpCode, GetLabel(aMethod, aOpCode), xSuccessLabel, DebugEnabled);
64+
XS.Label(xSuccessLabel);
65+
}
5866
}
67+
}
5968
}

source/Cosmos.IL2CPU/IL/Add_Ovf_Un.cs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using XSharp.Assembler.x86;
33
using XSharp;
44
using static XSharp.XSRegisters;
5+
using System.Reflection;
56

67
/* Add.Ovf is unsigned integer addition with check for overflow */
78
namespace Cosmos.IL2CPU.X86.IL
@@ -50,9 +51,17 @@ public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
5051

5152
// Let's check if we add overflow and if so throw OverflowException
5253
XS.Jump(ConditionalTestEnum.NotCarry, xSuccessLabel);
53-
ThrowOverflowException();
54+
if (xSize > 4) // Hack to stop stack corruption
55+
{
56+
XS.Add(ESP, 8);
57+
}
58+
else
59+
{
60+
XS.Add(ESP, 4);
61+
}
62+
Call.DoExecute(Assembler, aMethod, typeof(ExceptionHelper).GetMethod("ThrowOverflow", BindingFlags.Static | BindingFlags.Public), aOpCode, GetLabel(aMethod, aOpCode), xSuccessLabel, DebugEnabled);
5463
XS.Label(xSuccessLabel);
55-
}
64+
}
5665
}
5766
}
5867
}

source/Cosmos.IL2CPU/IL/Sub_Ovf.cs

Lines changed: 59 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,66 @@
11
using System;
22
using CPUx86 = XSharp.Assembler.x86;
33
using XSharp.Assembler.x86;
4-
4+
using XSharp;
5+
using static XSharp.XSRegisters;
6+
using System.Reflection;
57

68
namespace Cosmos.IL2CPU.X86.IL
79
{
8-
[Cosmos.IL2CPU.OpCode(ILOpCode.Code.Sub_Ovf)]
9-
public class Sub_Ovf: ILOp
10-
{
11-
public Sub_Ovf(XSharp.Assembler.Assembler aAsmblr):base(aAsmblr) {
12-
}
10+
[Cosmos.IL2CPU.OpCode(ILOpCode.Code.Sub_Ovf)]
11+
public class Sub_Ovf : ILOp
12+
{
13+
public Sub_Ovf(XSharp.Assembler.Assembler aAsmblr) : base(aAsmblr)
14+
{
15+
}
16+
17+
public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
18+
{
19+
var xType = aOpCode.StackPopTypes[0];
20+
var xSize = SizeOfType(xType);
21+
var xIsFloat = TypeIsFloat(xType);
22+
if (xIsFloat)
23+
{
24+
throw new Exception("Cosmos.IL2CPU.x86->IL->Sub_Ovf.cs->Error: Expected signed integer operands but get float!");
25+
}
26+
27+
if (xSize > 8)
28+
{
29+
throw new NotImplementedException("Cosmos.IL2CPU.x86->IL->Sub_Ovf.cs->Error: StackSize > 8 not supported");
30+
}
31+
else
32+
{
33+
var xBaseLabel = GetLabel(aMethod, aOpCode) + ".";
34+
var xSuccessLabel = xBaseLabel + "Success";
35+
if (xSize > 4) // long
36+
{
37+
XS.Pop(EAX);//low part
38+
XS.Pop(EDX);//high part
39+
XS.Sub(ESP, EAX, destinationIsIndirect: true);
40+
XS.SubWithCarry(ESP, EDX, destinationDisplacement: 4);
41+
42+
}
43+
else //integer
44+
{
45+
XS.Pop(ECX);//first integer
46+
XS.Pop(EAX);//second integer
47+
XS.Sub(EAX, ECX);
48+
XS.Push(EAX);//push result on stack
49+
}
1350

14-
public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode) {
15-
//if (Assembler.Stack.Peek().IsFloat) {
16-
// throw new NotImplementedException("Sub_Ovf: TODO need to call Sub IL");
17-
//}
18-
throw new NotImplementedException();
19-
}
20-
}
21-
}
51+
// Let's check if we add overflow and if so throw OverflowException
52+
XS.Jump(ConditionalTestEnum.NoOverflow, xSuccessLabel);
53+
if (xSize > 4) // Hack to stop stack corruption
54+
{
55+
XS.Add(ESP, 8);
56+
}
57+
else
58+
{
59+
XS.Add(ESP, 4);
60+
}
61+
Call.DoExecute(Assembler, aMethod, typeof(ExceptionHelper).GetMethod("ThrowOverflow", BindingFlags.Static | BindingFlags.Public), aOpCode, GetLabel(aMethod, aOpCode), xSuccessLabel, DebugEnabled);
62+
XS.Label(xSuccessLabel);
63+
}
64+
}
65+
}
66+
}
Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
using System;
22
using CPUx86 = XSharp.Assembler.x86;
33
using XSharp.Assembler.x86;
4-
4+
using XSharp;
5+
using static XSharp.XSRegisters;
6+
using System.Reflection;
57

68
namespace Cosmos.IL2CPU.X86.IL
79
{
@@ -12,10 +14,51 @@ public Sub_Ovf_Un(XSharp.Assembler.Assembler aAsmblr):base(aAsmblr) {
1214
}
1315

1416
public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode) {
15-
//if (Assembler.Stack.Peek().IsFloat) {
16-
// throw new NotImplementedException("Sub_Ovf_Un: TODO need to call Sub IL");
17-
//}
18-
throw new NotImplementedException();
17+
// TODO overflow check for float
18+
var xType = aOpCode.StackPopTypes[0];
19+
var xSize = SizeOfType(xType);
20+
var xIsFloat = TypeIsFloat(xType);
21+
22+
if (xIsFloat)
23+
{
24+
throw new Exception("Cosmos.IL2CPU.x86->IL->Add_Ovf_Un.cs->Error: Expected unsigned integer operands but get float!");
25+
}
26+
27+
if (xSize > 8)
28+
{
29+
//EmitNotImplementedException( Assembler, aServiceProvider, "Size '" + xSize.Size + "' not supported (add)", aCurrentLabel, aCurrentMethodInfo, aCurrentOffset, aNextLabel );
30+
throw new NotImplementedException("Cosmos.IL2CPU.x86->IL->Add_Ovf_Un.cs->Error: StackSize > 8 not supported");
31+
}
32+
else
33+
{
34+
var xBaseLabel = GetLabel(aMethod, aOpCode) + ".";
35+
var xSuccessLabel = xBaseLabel + "Success";
36+
if (xSize > 4) // long
37+
{
38+
XS.Pop(EDX); // low part
39+
XS.Pop(EAX); // high part
40+
XS.Sub(ESP, EDX, destinationIsIndirect: true);
41+
XS.SubWithCarry(ESP, EAX, destinationDisplacement: 4);
42+
}
43+
else //integer
44+
{
45+
XS.Pop(EAX);
46+
XS.Sub(ESP, EAX, destinationIsIndirect: true);
47+
}
48+
49+
// Let's check if we add overflow and if so throw OverflowException
50+
XS.Jump(ConditionalTestEnum.NotCarry, xSuccessLabel);
51+
if (xSize > 4) // Hack to stop stack corruption
52+
{
53+
XS.Add(ESP, 8);
54+
}
55+
else
56+
{
57+
XS.Add(ESP, 4);
58+
}
59+
Call.DoExecute(Assembler, aMethod, typeof(ExceptionHelper).GetMethod("ThrowOverflow", BindingFlags.Static | BindingFlags.Public), aOpCode, GetLabel(aMethod, aOpCode), xSuccessLabel, DebugEnabled);
60+
XS.Label(xSuccessLabel);
61+
}
1962
}
2063
}
21-
}
64+
}

source/Cosmos.IL2CPU/ILOpCodes/OpNone.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,15 @@ public override int GetNumberOfStackPops(MethodBase aMethod)
6767
return 1;
6868
case Code.Add:
6969
case Code.Add_Ovf:
70+
case Code.Add_Ovf_Un:
7071
case Code.Mul:
7172
case Code.Mul_Ovf:
7273
case Code.Mul_Ovf_Un:
7374
case Code.Div:
7475
case Code.Div_Un:
7576
case Code.Sub:
77+
case Code.Sub_Ovf:
78+
case Code.Sub_Ovf_Un:
7679
case Code.Rem:
7780
case Code.Rem_Un:
7881
case Code.Xor:
@@ -208,12 +211,15 @@ public override int GetNumberOfStackPushes(MethodBase aMethod)
208211
return 1;
209212
case Code.Add:
210213
case Code.Add_Ovf:
214+
case Code.Add_Ovf_Un:
211215
case Code.Mul:
212216
case Code.Mul_Ovf:
213217
case Code.Mul_Ovf_Un:
214218
case Code.Div:
215219
case Code.Div_Un:
216220
case Code.Sub:
221+
case Code.Sub_Ovf:
222+
case Code.Sub_Ovf_Un:
217223
case Code.Rem:
218224
case Code.Rem_Un:
219225
case Code.Xor:
@@ -529,12 +535,16 @@ protected override void DoInterpretStackTypes(ref bool aSituationChanged)
529535
switch (OpCode)
530536
{
531537
case Code.Add:
538+
case Code.Add_Ovf:
539+
case Code.Add_Ovf_Un:
532540
case Code.Mul:
533541
case Code.Mul_Ovf:
534542
case Code.Mul_Ovf_Un:
535543
case Code.Div:
536544
case Code.Div_Un:
537545
case Code.Sub:
546+
case Code.Sub_Ovf:
547+
case Code.Sub_Ovf_Un:
538548
case Code.Rem:
539549
case Code.Rem_Un:
540550
case Code.Xor:

0 commit comments

Comments
 (0)