Merge pull request #820 from brendanzagaeski/master
[mono.git] / mcs / class / dlr / Runtime / Microsoft.Dynamic / Interpreter / Instructions / DivInstruction.cs
1 /* ****************************************************************************
2  *
3  * Copyright (c) Microsoft Corporation. 
4  *
5  * This source code is subject to terms and conditions of the Apache License, Version 2.0. A 
6  * copy of the license can be found in the License.html file at the root of this distribution. If 
7  * you cannot locate the  Apache License, Version 2.0, please send an email to 
8  * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound 
9  * by the terms of the Apache License, Version 2.0.
10  *
11  * You must not remove this notice, or any other, from this software.
12  *
13  *
14  * ***************************************************************************/
15
16 using System;
17 using System.Diagnostics;
18 using Microsoft.Scripting.Runtime;
19 using Microsoft.Scripting.Utils;
20
21 namespace Microsoft.Scripting.Interpreter {
22     internal abstract class DivInstruction : Instruction {
23         private static Instruction _Int16, _Int32, _Int64, _UInt16, _UInt32, _UInt64, _Single, _Double;
24
25         public override int ConsumedStack { get { return 2; } }
26         public override int ProducedStack { get { return 1; } }
27
28         private DivInstruction() {
29         }
30
31         internal sealed class DivInt32 : DivInstruction {
32             public override int Run(InterpretedFrame frame) {
33                 object l = frame.Data[frame.StackIndex - 2];
34                 object r = frame.Data[frame.StackIndex - 1];
35                 frame.Data[frame.StackIndex - 2] = ScriptingRuntimeHelpers.Int32ToObject((Int32)l / (Int32)r);
36                 frame.StackIndex--;
37                 return 1;
38             }
39         }
40
41         internal sealed class DivInt16 : DivInstruction {
42             public override int Run(InterpretedFrame frame) {
43                 object l = frame.Data[frame.StackIndex - 2];
44                 object r = frame.Data[frame.StackIndex - 1];
45                 frame.Data[frame.StackIndex - 2] = (Int16)((Int16)l / (Int16)r);
46                 frame.StackIndex--;
47                 return 1;
48             }
49         }
50
51         internal sealed class DivInt64 : DivInstruction {
52             public override int Run(InterpretedFrame frame) {
53                 object l = frame.Data[frame.StackIndex - 2];
54                 object r = frame.Data[frame.StackIndex - 1];
55                 frame.Data[frame.StackIndex - 2] = (Int64)((Int64)l / (Int64)r);
56                 frame.StackIndex--;
57                 return 1;
58             }
59         }
60
61         internal sealed class DivUInt16 : DivInstruction {
62             public override int Run(InterpretedFrame frame) {
63                 object l = frame.Data[frame.StackIndex - 2];
64                 object r = frame.Data[frame.StackIndex - 1];
65                 frame.Data[frame.StackIndex - 2] = (UInt16)((UInt16)l / (UInt16)r);
66                 frame.StackIndex--;
67                 return 1;
68             }
69         }
70
71         internal sealed class DivUInt32 : DivInstruction {
72             public override int Run(InterpretedFrame frame) {
73                 object l = frame.Data[frame.StackIndex - 2];
74                 object r = frame.Data[frame.StackIndex - 1];
75                 frame.Data[frame.StackIndex - 2] = (UInt32)((UInt32)l / (UInt32)r);
76                 frame.StackIndex--;
77                 return 1;
78             }
79         }
80
81         internal sealed class DivUInt64 : DivInstruction {
82             public override int Run(InterpretedFrame frame) {
83                 object l = frame.Data[frame.StackIndex - 2];
84                 object r = frame.Data[frame.StackIndex - 1];
85                 frame.Data[frame.StackIndex - 2] = (UInt64)((UInt64)l / (UInt64)r);
86                 frame.StackIndex--;
87                 return 1;
88             }
89         }
90
91         internal sealed class DivSingle : DivInstruction {
92             public override int Run(InterpretedFrame frame) {
93                 object l = frame.Data[frame.StackIndex - 2];
94                 object r = frame.Data[frame.StackIndex - 1];
95                 frame.Data[frame.StackIndex - 2] = (Single)((Single)l / (Single)r);
96                 frame.StackIndex--;
97                 return 1;
98             }
99         }
100
101         internal sealed class DivDouble : DivInstruction {
102             public override int Run(InterpretedFrame frame) {
103                 object l = frame.Data[frame.StackIndex - 2];
104                 object r = frame.Data[frame.StackIndex - 1];
105                 frame.Data[frame.StackIndex - 2] = (Double)l / (Double)r;
106                 frame.StackIndex--;
107                 return 1;
108             }
109         }
110
111         public static Instruction Create(Type type) {
112             Debug.Assert(!type.IsEnum());
113             switch (type.GetTypeCode()) {
114                 case TypeCode.Int16: return _Int16 ?? (_Int16 = new DivInt16());
115                 case TypeCode.Int32: return _Int32 ?? (_Int32 = new DivInt32());
116                 case TypeCode.Int64: return _Int64 ?? (_Int64 = new DivInt64());
117                 case TypeCode.UInt16: return _UInt16 ?? (_UInt16 = new DivUInt16());
118                 case TypeCode.UInt32: return _UInt32 ?? (_UInt32 = new DivUInt32());
119                 case TypeCode.UInt64: return _UInt64 ?? (_UInt64 = new DivUInt64());
120                 case TypeCode.Single: return _Single ?? (_Single = new DivSingle());
121                 case TypeCode.Double: return _Double ?? (_Double = new DivDouble());
122
123                 default:
124                     throw Assert.Unreachable;
125             }
126         }
127
128         public override string ToString() {
129             return "Div()";
130         }
131     }
132 }