1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
|
/* NSC -- new scala compiler
* Copyright 2005-2010 LAMP/EPFL
* @author Martin Odersky
*/
package scala.tools.nsc
package backend
package icode;
import java.io.PrintWriter;
trait Primitives { self: ICodes =>
/** This class represents a primitive operation. */
class Primitive {
}
// type : (type) => type
// range: type <- { BOOL, Ix, Ux, Rx }
// jvm : {i, l, f, d}neg
case class Negation(kind: TypeKind) extends Primitive
// type : zero ? (type) => BOOL : (type,type) => BOOL
// range: type <- { BOOL, Ix, Ux, Rx, REF }
// jvm : if{eq, ne, lt, ge, le, gt}, if{null, nonnull}
// if_icmp{eq, ne, lt, ge, le, gt}, if_acmp{eq,ne}
case class Test(op: TestOp, kind: TypeKind, zero: Boolean) extends Primitive
// type : (type,type) => I4
// range: type <- { Ix, Ux, Rx }
// jvm : lcmp, {f, d}cmp{l, g}
case class Comparison(op: ComparisonOp, kind: TypeKind) extends Primitive
// type : (type,type) => type
// range: type <- { Ix, Ux, Rx }
// jvm : {i, l, f, d}{add, sub, mul, div, rem}
case class Arithmetic(op: ArithmeticOp, kind: TypeKind) extends Primitive
// type : (type,type) => type
// range: type <- { BOOL, Ix, Ux }
// jvm : {i, l}{and, or, xor}
case class Logical(op: LogicalOp, kind: TypeKind) extends Primitive
// type : (type,I4) => type
// range: type <- { Ix, Ux }
// jvm : {i, l}{shl, ushl, shr}
case class Shift(op: ShiftOp, kind: TypeKind) extends Primitive
// type : (src) => dst
// range: src,dst <- { Ix, Ux, Rx }
// jvm : i2{l, f, d}, l2{i, f, d}, f2{i, l, d}, d2{i, l, f}, i2{b, c, s}
case class Conversion(src: TypeKind, dst: TypeKind) extends Primitive;
// type : (Array[REF]) => I4
// range: type <- { BOOL, Ix, Ux, Rx, REF }
// jvm : arraylength
case class ArrayLength(kind: TypeKind) extends Primitive;
// type : (buf,el) => buf
// range: lf,rg <- { BOOL, Ix, Ux, Rx, REF, STR }
// jvm : It should call the appropiate 'append' method on StringBuffer
case class StringConcat(el: TypeKind) extends Primitive
/** Signals the beginning of a series of concatenations.
* On the JVM platform, it should create a new StringBuffer
*/
case object StartConcat extends Primitive
/**
* type: (buf) => STR
* jvm : It should turn the StringBuffer into a String.
*/
case object EndConcat extends Primitive
/** Pretty printer for primitives */
class PrimitivePrinter(out: PrintWriter) {
def print(s: String): PrimitivePrinter = {
out.print(s)
this
}
def print(o: AnyRef): PrimitivePrinter = print(o.toString())
def printPrimitive(prim: Primitive) = prim match {
case Negation(kind) =>
print("!")
case Test(op, kind, zero) =>
print(op).print(kind)
case Comparison(op, kind) =>
print(op).print("(").print(kind)
}
}
/** This class represents a comparison operation. */
class ComparisonOp {
/** Returns a string representation of this operation. */
override def toString(): String = this match {
case CMPL => "CMPL"
case CMP => "CMP"
case CMPG => "CMPG"
case _ => throw new RuntimeException("ComparisonOp unknown case")
}
}
/** A comparison operation with -1 default for NaNs */
case object CMPL extends ComparisonOp
/** A comparison operation with no default for NaNs */
case object CMP extends ComparisonOp
/** A comparison operation with +1 default for NaNs */
case object CMPG extends ComparisonOp
/** This class represents a test operation. */
class TestOp {
/** Returns the negation of this operation. */
def negate(): TestOp = this match {
case EQ => NE
case NE => EQ
case LT => GE
case GE => LT
case LE => GT
case GT => LE
case _ => throw new RuntimeException("TestOp unknown case")
}
/** Returns a string representation of this operation. */
override def toString(): String = this match {
case EQ => "EQ"
case NE => "NE"
case LT => "LT"
case GE => "GE"
case LE => "LE"
case GT => "GT"
case _ => throw new RuntimeException("TestOp unknown case")
}
}
/** An equality test */
case object EQ extends TestOp
/** A non-equality test */
case object NE extends TestOp
/** A less-than test */
case object LT extends TestOp
/** A greater-than-or-equal test */
case object GE extends TestOp
/** A less-than-or-equal test */
case object LE extends TestOp
/** A greater-than test */
case object GT extends TestOp
/** This class represents an arithmetic operation. */
class ArithmeticOp {
/** Returns a string representation of this operation. */
override def toString(): String = this match {
case ADD => "ADD"
case SUB => "SUB"
case MUL => "MUL"
case DIV => "DIV"
case REM => "REM"
case NOT => "NOT"
case _ => throw new RuntimeException("ArithmeticOp unknown case")
}
}
/** An arithmetic addition operation */
case object ADD extends ArithmeticOp
/** An arithmetic subtraction operation */
case object SUB extends ArithmeticOp
/** An arithmetic multiplication operation */
case object MUL extends ArithmeticOp
/** An arithmetic division operation */
case object DIV extends ArithmeticOp
/** An arithmetic remainder operation */
case object REM extends ArithmeticOp
/** Bitwise negation. */
case object NOT extends ArithmeticOp
/** This class represents a shift operation. */
class ShiftOp {
/** Returns a string representation of this operation. */
override def toString(): String = this match {
case LSL => "LSL"
case ASR => "ASR"
case LSR => "LSR"
case _ => throw new RuntimeException("ShitOp unknown case")
}
}
/** A logical shift to the left */
case object LSL extends ShiftOp
/** An arithmetic shift to the right */
case object ASR extends ShiftOp
/** A logical shift to the right */
case object LSR extends ShiftOp
/** This class represents a logical operation. */
class LogicalOp {
/** Returns a string representation of this operation. */
override def toString(): String = this match {
case AND => return "AND"
case OR => return "OR"
case XOR => return "XOR"
case _ => throw new RuntimeException("LogicalOp unknown case")
}
}
/** A bitwise AND operation */
case object AND extends LogicalOp
/** A bitwise OR operation */
case object OR extends LogicalOp
/** A bitwise XOR operation */
case object XOR extends LogicalOp
}
|