Skip to content

Commit 0508ac8

Browse files
committed
Fix #7186: add test
1 parent da8fd5f commit 0508ac8

File tree

1 file changed

+241
-0
lines changed

1 file changed

+241
-0
lines changed

tests/patmat/i7186.scala

Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
import MIPS._
2+
3+
object MIPS {
4+
type Labels = Label | ControlLabel
5+
type Src = Register | Constant
6+
type LabelIds = ElseLabel | Join
7+
type Register = Results | Arguments | Temporaries | SavedValues | Trap | Misc
8+
type Addresses = OffsetAddress | Labels
9+
type Dest = Addresses | Register
10+
type Assembler = ZeroAddr | OneAddr | TwoAddr | ThreeAddr | PseudoZero |
11+
PseudoUnary | Labels | Comment
12+
}
13+
14+
enum Results { case V0, V1 }
15+
16+
enum Arguments { case A0, A1, A2, A3 }
17+
18+
enum Temporaries { case T0, T1, T2, T3, T4, T5, T6, T7, T8, T9 }
19+
20+
enum SavedValues { case S0, S1, S2, S3, S4, S5, S6, S7, S8 }
21+
22+
enum Trap { case K0, K1 }
23+
24+
enum Misc { case Zero, Sp, Gp, Fp, Ra }
25+
26+
enum ZeroAddr { case Syscall }
27+
28+
enum OneAddr {
29+
case Jal(dest: Labels)
30+
case Jr(dest: Register)
31+
case J(dest: Labels)
32+
}
33+
34+
enum TwoAddr {
35+
case Beqz(source: Register, breakTo: Labels)
36+
case Move(dest: Register, source: Register)
37+
case Li(dest: Register, source: Constant)
38+
case Lw(dest: Register, source: Addresses)
39+
case La(dest: Register, source: Addresses)
40+
case Sw(source: Register, dest: Addresses)
41+
case Not(dest: Register, r: Src)
42+
case Neg(dest: Register, r: Src)
43+
}
44+
45+
enum ThreeAddr {
46+
case Add(dest: Register, l: Register, r: Src)
47+
case Sub(dest: Register, l: Register, r: Src)
48+
case Mul(dest: Register, l: Register, r: Src)
49+
case Div(dest: Register, l: Register, r: Src)
50+
case Rem(dest: Register, l: Register, r: Src)
51+
case Seq(dest: Register, l: Register, r: Src)
52+
case Sne(dest: Register, l: Register, r: Src)
53+
case Slt(dest: Register, l: Register, r: Src)
54+
case Sle(dest: Register, l: Register, r: Src)
55+
case Sgt(dest: Register, l: Register, r: Src)
56+
case Sge(dest: Register, l: Register, r: Src)
57+
}
58+
59+
case class ElseLabel(id: Long)
60+
case class Join(id: Long)
61+
case class ControlLabel(id: LabelIds)
62+
case class Label(id: Scoped)
63+
case class OffsetAddress(address: Register, offset: Constant)
64+
65+
case class Constant(value: Int)
66+
case class Scoped(id: Identifier, scope: Long)
67+
case class Identifier(id: String)
68+
69+
enum PseudoZero { case Text, Data }
70+
71+
enum PseudoUnary {
72+
case Word(size: Constant)
73+
case Globl(name: Scoped)
74+
case Asciiz(value: String)
75+
}
76+
77+
case class Comment(msg: String)
78+
79+
object printMips {
80+
import MIPS._
81+
import Misc._
82+
import PseudoZero._
83+
import PseudoUnary._
84+
import ZeroAddr._
85+
import OneAddr._
86+
import TwoAddr._
87+
import ThreeAddr._
88+
89+
private val endl = System.lineSeparator
90+
91+
def apply(nodes: List[Assembler]): Unit = {
92+
var symbCount = 0L
93+
val symbols = new scala.collection.mutable.AnyRefMap[Scoped,Long]()
94+
95+
print(mipsNode(nodes, " "))
96+
97+
def mipsNode
98+
( nodes: List[Assembler],
99+
indent: String
100+
): String = {
101+
(for (node <- nodes.view) yield astNode(node, indent)).mkString
102+
}
103+
104+
def astNode
105+
( node: Assembler,
106+
indent: String
107+
): String = {
108+
node match {
109+
case Text =>
110+
s"$indent.text$endl"
111+
case Comment(msg) =>
112+
s"$indent#$msg$endl"
113+
case Data =>
114+
s"$indent.data$endl"
115+
case Globl(Scoped(Identifier(id),_)) =>
116+
s"$indent.globl $id$endl"
117+
case Label(Scoped(Identifier(i),-1)) =>
118+
s"$i:$endl"
119+
case Label(s @ Scoped(Identifier(i), id)) =>
120+
s"${getScopedLabel(s)}: #debug: $i~$id$endl"
121+
case ControlLabel(id) =>
122+
s"${evalLabels(id)}:$endl"
123+
case Word(Constant(w)) =>
124+
s"$indent.word $w$endl"
125+
case Syscall =>
126+
s"${indent}syscall$endl"
127+
case jal: Jal =>
128+
oneAddr(jal,indent)(_.dest)
129+
case jr: Jr =>
130+
oneAddr(jr,indent)(_.dest)
131+
case j: J =>
132+
oneAddr(j,indent)(_.dest)
133+
case li: Li =>
134+
twoAddr(li,indent)(_.dest,_.source)
135+
case lw: Lw =>
136+
twoAddr(lw,indent)(_.dest,_.source)
137+
case neg: Neg =>
138+
twoAddr(neg,indent)(_.dest,_.r)
139+
case not: Not =>
140+
twoAddr(not,indent)(_.dest,_.r)
141+
case move: Move =>
142+
twoAddr(move,indent)(_.dest,_.source)
143+
case beqz: Beqz =>
144+
twoAddr(beqz,indent)(_.source,_.breakTo)
145+
case sw: Sw =>
146+
twoAddr(sw,indent)(_.source,_.dest)
147+
case add: Add =>
148+
threeAddr(add,indent)(_.dest,_.l,_.r)
149+
case sub: Sub =>
150+
threeAddr(sub,indent)(_.dest,_.l,_.r)
151+
case mul: Mul =>
152+
threeAddr(mul,indent)(_.dest,_.l,_.r)
153+
case div: Div =>
154+
threeAddr(div,indent)(_.dest,_.l,_.r)
155+
case rem: Rem =>
156+
threeAddr(rem,indent)(_.dest,_.l,_.r)
157+
case seq: Seq =>
158+
threeAddr(seq,indent)(_.dest,_.l,_.r)
159+
case sne: Sne =>
160+
threeAddr(sne,indent)(_.dest,_.l,_.r)
161+
case slt: Slt =>
162+
threeAddr(slt,indent)(_.dest,_.l,_.r)
163+
case sgt: Sgt =>
164+
threeAddr(sgt,indent)(_.dest,_.l,_.r)
165+
case sle: Sle =>
166+
threeAddr(sle,indent)(_.dest,_.l,_.r)
167+
case sge: Sge =>
168+
threeAddr(sge,indent)(_.dest,_.l,_.r)
169+
case _ => s"${indent}???$endl"
170+
}
171+
}
172+
173+
def oneAddr[O]
174+
( a: O, indent: String)
175+
( r: O => Dest,
176+
): String = {
177+
val name = a.getClass.getSimpleName.toLowerCase
178+
s"${indent}$name ${rsrc(r(a))}$endl"
179+
}
180+
181+
def twoAddr[O]
182+
( a: O, indent: String)
183+
( d: O => Register,
184+
r: O => Dest | Constant
185+
): String = {
186+
val name = a.getClass.getSimpleName.toLowerCase
187+
s"${indent}$name ${registers(d(a))}, ${rsrc(r(a))}$endl"
188+
}
189+
190+
def threeAddr[O]
191+
( a: O,
192+
indent: String )
193+
( d: O => Register,
194+
l: O => Register,
195+
r: O => Src
196+
): String = {
197+
val name = a.getClass.getSimpleName.toLowerCase
198+
s"${indent}$name ${registers(d(a))}, ${registers(l(a))}, ${rsrc(r(a))}$endl"
199+
}
200+
201+
def rsrc(v: Constant | Dest): String = v match {
202+
case Constant(c) => c.toString
203+
case Label(Scoped(Identifier(i),-1)) => s"$i"
204+
case Label(s: Scoped) => getScopedLabel(s)
205+
case ControlLabel(id) => evalLabels(id)
206+
case r: Register => registers(r)
207+
case u => sys.error(s"rsrc: $u")
208+
}
209+
210+
def registers(reg: Register): String = reg match {
211+
case t: Temporaries =>
212+
printEnum(Temporaries.valueOf, t, "$t")
213+
case s: SavedValues =>
214+
printEnum(SavedValues.valueOf, s, "$s")
215+
case r: Results =>
216+
printEnum(Results.valueOf, r, "$v")
217+
case a: Arguments =>
218+
printEnum(Arguments.valueOf, a, "$a")
219+
case Ra =>
220+
"$ra"
221+
case _ =>
222+
"$?_"
223+
}
224+
225+
def evalLabels(v: LabelIds): String = v match {
226+
case ElseLabel(c) => s"else$c"
227+
case Join(ic) => s"join$ic"
228+
}
229+
230+
def getScopedId(s: Scoped): Long =
231+
symbols.getOrElseUpdate(s, { symbCount += 1; symbCount })
232+
233+
def getScopedLabel(s: Scoped): String =
234+
"L" + getScopedId(s)
235+
236+
def printEnum[E](e: String => Enum, t: E, code: String) = {
237+
val num = e(t.toString).ordinal
238+
s"$code$num"
239+
}
240+
}
241+
}

0 commit comments

Comments
 (0)