Home My Page Projects Code Snippets Project Openings SML/NJ
Summary Activity Forums Tracker Lists Tasks Docs Surveys News SCM Files

SCM Repository

[smlnj] Annotation of /sml/trunk/src/MLRISC/sparc/sparc.mdl
ViewVC logotype

Annotation of /sml/trunk/src/MLRISC/sparc/sparc.mdl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 839 - (view) (download)

1 : leunga 746 (*
2 :     * This has been upgraded to V9.
3 :     *)
4 :    
5 :     architecture Sparc =
6 :     struct
7 :    
8 :     superscalar
9 :    
10 :     big endian
11 :    
12 :     lowercase assembly
13 :    
14 :     storage
15 :     GP = $r[32] of 64 bits where $r[0] = 0
16 :     asm: (fn (r,_) =>
17 :     if r < 8 then "%g"^Int.toString r
18 :     else if r = 14 then "%sp"
19 :     else if r < 16 then "%o"^Int.toString(r-8)
20 :     else if r < 24 then "%l"^Int.toString(r-16)
21 :     else if r = 30 then "%fp"
22 :     else if r < 32 then "%i"^Int.toString(r-24)
23 :     else "%r"^Int.toString r
24 :     )
25 :     | FP = $f[32] of 32 bits asm: (fn (f,_) => "%f"^Int.toString f)
26 :     | Y = $y[1] of 64 bits asm: "%y"
27 :     | PSR = $psr[1] of 64 bits
28 :     asm: (fn (0,_) => "%psr"
29 :     | (n,_) => "%psr"^Int.toString n)
30 :     | FSR = $fsr[1] of 64 bits
31 :     asm: (fn (0,_) => "%fsr"
32 :     | (n,_) => "%fsr"^Int.toString n)
33 :     | CC = $cc[] of 64 bits aliasing GP asm: "%cc"
34 :     | MEM = $m[] of 8 aggregable bits asm: (fn (r,_) => "m"^Int.toString r)
35 :     | CTRL = $ctrl[] asm: (fn (r,_) => "ctrl"^Int.toString r)
36 :    
37 :     locations
38 :     stackptrR = $r[14]
39 :     and asmTmpR = $r[10] (* %o2 *)
40 :     and linkReg = $r[15]
41 :     and fasmTmp = $f[30]
42 :     and y = $y[0]
43 :     and psr = $psr[0]
44 :     and fsr = $fsr[0]
45 :     and r0 = $r[0]
46 :    
47 :     structure RTL =
48 :     struct
49 :     include "Tools/basis.mdl"
50 :     open Basis
51 :     infix 1 ||
52 :     infix 3 << >> ~>>
53 :    
54 :     fun %% l = (l : #64 bits)
55 :    
56 :     (* Updates condition code *)
57 :     fun cc{} = Kill $psr[0]
58 :    
59 :     fun byte x = (x : #8 bits)
60 :     fun hword x = (x : #16 bits)
61 :     fun word x = (x : #32 bits)
62 :     fun dword x = (x : #64 bits)
63 :     fun single x = (x : #32 bits)
64 :     fun double x = (x : #64 bits)
65 :     fun quad x = (x : #128 bits)
66 :    
67 :     fun disp(r,i) = $r[r] + i
68 :    
69 :     (* read from/write to the y register *)
70 :     rtl RDY{d} = $r[d] := $y[0]
71 :     rtl WRY{r,i} = $y[0] := disp(r,i)
72 :    
73 :     rtl SETHI{i,d} = $r[d] := i << 10
74 :    
75 :     (* Integer load/store *)
76 :     rtl LDSB{r,i,d,mem} = $r[d] := sx(byte $m[disp(r,i):mem])
77 :     rtl LDSH{r,i,d,mem} = $r[d] := sx(hword $m[disp(r,i):mem])
78 :     rtl LDUB{r,i,d,mem} = $r[d] := zx(byte $m[disp(r,i):mem])
79 :     rtl LDUH{r,i,d,mem} = $r[d] := zx(hword $m[disp(r,i):mem])
80 :     rtl LD{r,i,d,mem} = $r[d] := zx(word $m[disp(r,i):mem])
81 :     rtl LDX{r,i,d,mem} = $r[d] := zx(quad $m[disp(r,i):mem])
82 :     rtl STB{r,i,d,mem} = $m[disp(r,i):mem] := $r[d] at [0..7]
83 :     rtl STH{r,i,d,mem} = $m[disp(r,i):mem] := $r[d] at [0..15]
84 :     rtl ST{r,i,d,mem} = $m[disp(r,i):mem] := $r[d] at [0..31]
85 :     rtl STX{r,i,d,mem} = $m[disp(r,i):mem] := $r[d] at [0..63]
86 :    
87 :     (* Integer opcodes *)
88 :    
89 :     (* These are built-in sparc bitops *)
90 :     fun andn(x,y) = andb(x,notb y)
91 :     fun orn(x,y) = orb(x,notb y)
92 :     fun xnor(x,y) = notb(xorb(x,y))
93 :    
94 :     (* Tagged additions operators. We just fake these by
95 :     * generating new operators.
96 :     *)
97 :     rtl tadd taddtv tsub tsubtv : #n bits * #n bits -> #n bits
98 :    
99 :     fun multiply opc {r,i,d} =
100 :     $r[d] := opc($r[r],i) ||
101 :     Kill $y[0]
102 :     fun multiplycc opc {r,i,d} = multiply opc {r,i,d} || cc{}
103 :     fun divide opc {r,i,d} =
104 :     $r[d] := opc($r[r],i) (* XXX *)
105 :     fun dividecc opc {r,i,d} = divide opc {r,i,d} || cc{}
106 :    
107 :     fun logical opc {r,i,d} = $r[d] := opc($r[r],i)
108 :     fun logicalcc opc {r,i,d} = $r[d] := opc($r[r],i) || cc{}
109 :     fun arith opc {r,i,d} = $r[d] := opc($r[r],i)
110 :     fun arithcc opc {r,i,d} = $r[d] := opc($r[r],i) || cc{}
111 :    
112 :     rtl li{i,d} = $r[d] := i (* load immediate *)
113 :    
114 :     rtl [AND,ANDN,OR,ORN,XOR,XNOR] =
115 :     map logical [andb, andn, orb, orn, xorb, xnor]
116 :    
117 :     rtl [ANDCC, ANDNCC, ORCC, ORNCC, XORCC, XNORCC] =
118 :     map logicalcc [andb, andn, orb, orn, xorb, xnor]
119 :    
120 :     rtl [ADD, TADD, TADDTV, SUB, TSUB, TSUBTV] =
121 :     map arith [(+), tadd, taddtv, (-), tsub, tsubtv]
122 :    
123 :     rtl [ADDCC, TADDCC, TADDTVCC, SUBCC, TSUBCC, TSUBTVCC] =
124 :     map arithcc [(+), tadd, taddtv, (-), tsub, tsubtv]
125 :    
126 :     rtl [UMUL,SMUL] = map multiply [mulu,muls]
127 :     rtl [UMULCC,SMULCC] = map multiplycc [mulu,muls]
128 :     rtl [UDIV,SDIV] = map divide [divu,divs]
129 :     rtl [UDIVCC,SDIVCC] = map dividecc [divu,divs]
130 :    
131 :     rtl [MULX, SDIVX, UDIVX] = map arith [muls, divs, divu]
132 :     rtl [SLL, SRL, SRA] = map logical [(<<), (>>), (~>>)] (* XXX *)
133 :     rtl [SLLX, SRLX, SRAX] = map logical [(<<), (>>), (~>>)] (* XXX *)
134 :    
135 :     local fun xor(a, b) = a == b
136 :     (* Extract bits from the $psr *)
137 :     val N = ($psr[0] at [23]) == 1
138 :     val Z = ($psr[0] at [22]) == 1
139 :     val V = ($psr[0] at [21]) == 1
140 :     val C = ($psr[0] at [20]) == 1
141 :     in val [A, E, LE, L, LEU, CS, NEG, VS, (* XXX *)
142 :     N, NE, G, GE, GU, CC, POS, VC] =
143 :     [true, Z, Z, Z, Z, C, N, V,
144 :     false, not Z, Z, Z, Z, not C,not N,not V
145 :     ]
146 :     end
147 :    
148 :     val integer_tests =
149 :     [N, E, LE, L, LEU, CS, NEG, VS,
150 :     A, NE, G, GE, GU, CC, POS, VC]
151 :    
152 :     (* Integer branches *)
153 :     fun branch status {label} = if status then Jmp(%%label) else ()
154 :     rtl [BN, BE, BLE, BL, BLEU, BCS, BNEG, BVS,
155 :     BA, BNE, BG, BGE, BGU, BCC, BPOS, BVC] =
156 :     map branch integer_tests
157 :    
158 :     rtl JMP{r,i} = Jmp(disp(r,i))
159 :    
160 :     (* Conditional moves *)
161 :     fun MOVicc icc {i, d} = if icc then $r[d] := i else ()
162 :     fun FMOVicc icc {r, d} = if icc then $f[d] := $f[r] else ()
163 :    
164 :     val MOV ^^
165 :     [E, LE, L, LEU, CS, NEG, VS,
166 :     NE, G, GE, GU, CC, POS, VC] =
167 :     map MOVicc
168 :     [E, LE, L, LEU, CS, NEG, VS,
169 :     NE, G, GE, GU, CC, POS, VC]
170 :     val FMOV ^^
171 :     [E, LE, L, LEU, CS, NEG, VS,
172 :     NE, G, GE, GU, CC, POS, VC] =
173 :     map FMOVicc
174 :     [E, LE, L, LEU, CS, NEG, VS,
175 :     NE, G, GE, GU, CC, POS, VC]
176 :    
177 :     fun MOVR rcc {r, i, d} = if rcc($r[r], 0) then $r[d] := i else ()
178 :     rtl MOVR ^^ [Z, LEZ, LZ, NZ, GZ, GEZ] =
179 :     map MOVR [(==), (<=), (<), (<>), (>), (>=)]
180 :    
181 :     (* Floating point load/store *)
182 :     rtl LDF{r,i,d,mem} = $f[d] := $m[disp(r,i):mem]
183 :     rtl LDDF{r,i,d,mem} = $f[d] := $m[disp(r,i):mem]
184 :     rtl LDQF{r,i,d,mem} = $f[d] := $m[disp(r,i):mem]
185 :     rtl STF{r,i,d,mem} = $m[disp(r,i):mem] := $f[d]
186 :     rtl STDF{r,i,d,mem} = $m[disp(r,i):mem] := $f[d]
187 :    
188 :     rtl LDFSR{r,i,mem} = $fsr[0] := $m[disp(r,i):mem] (* XXX *)
189 :     rtl LDXFSR{r,i,mem} = $fsr[0] := $m[disp(r,i):mem] (* XXX *)
190 :     rtl STFSR{r,i,mem} = $m[disp(r,i):mem] := $fsr[0] (* XXX *)
191 :    
192 :     (* conversions *)
193 :     rtl fitos fitod fitoq fstoi fdtoi fqtoi fsqrt
194 :     fstod fstoq fdtos fdtoq fqtos fqtod : #n bits -> #n bits
195 :    
196 :     fun fmovs x = x
197 :     fun fmovd x = x
198 :     fun fmovq x = x
199 :    
200 :     fun funary opc {r,d} = $f[d] := opc $f[r]
201 :    
202 :     (* Floating point unary operations *)
203 :     rtl [FiTOs, FiTOd, FiTOq, FsTOi, FdTOi, FqTOi,
204 :     FsTOd, FsTOq, FdTOs, FdTOq, FqTOs, FqTOd,
205 :     FMOVs, FNEGs, FABSs, FMOVd, FNEGd, FABSd,
206 :     FMOVq, FNEGq, FABSq, FSQRTs, FSQRTd, FSQRTq] = (* XXX *)
207 :     map funary
208 :     [fitos, fitod, fitoq, fstoi, fdtoi, fqtoi,
209 :     fstod, fstoq, fdtos, fdtoq, fqtos, fqtod,
210 :     fmovs, fneg, fabs, fmovd, fneg, fabs,
211 :     fmovq, fneg, fabs, fsqrt, fsqrt, fsqrt]
212 :    
213 :     (* Floating point binary operations *)
214 :     fun fbinary opc {r1,r2,d} = $f[d] := opc($f[r1],$f[r2])
215 :     rtl fsmuld fdmulq : #n bits * #n bits -> #n bits (* XXX *)
216 :     rtl [FADDs, FADDd, FADDq, FSUBs, FSUBd, FSUBq, (* XXX *)
217 :     FMULs, FMULd, FMULq, FsMULd, FdMULq,
218 :     FDIVs, FDIVd, FDIVq] =
219 :     map fbinary
220 :     [fadd, fadd, fadd, fsub, fsub, fsub,
221 :     fmul, fmul, fmul, fsmuld, fdmulq,
222 :     fdiv, fdiv, fdiv]
223 :    
224 :     (* Floating point comparisons *)
225 :     rtl Nan : #32 bits -> #32 bits
226 :     fun nan(r) = (* if Nan($f[r]) == 0 then () else () *) ()
227 :     rtl cmps cmpd cmpq : #n bits * #n bits -> #n bits
228 :     rtl FCMPs{r1,r2} = $fsr[0] := cmps($f[r1],$f[r2])
229 :     rtl FCMPd{r1,r2} = $fsr[0] := cmpd($f[r1],$f[r2])
230 :     rtl FCMPq{r1,r2} = $fsr[0] := cmpq($f[r1],$f[r2])
231 :     rtl FCMPEs{r1,r2} = $fsr[0] := cmps($f[r1],$f[r2]) || nan(r1) || nan(r2)
232 :     rtl FCMPEd{r1,r2} = $fsr[0] := cmpd($f[r1],$f[r2]) || nan(r1) || nan(r2)
233 :     rtl FCMPEq{r1,r2} = $fsr[0] := cmpq($f[r1],$f[r2]) || nan(r1) || nan(r2)
234 :    
235 :     local val X = $fsr[0] == 0
236 :     in val floating_point_tests as
237 :     [FN, FNE, FLG, FUL, FL, FUG, FG, FU,
238 :     FA, FE, FUE, FGE, FUGE, FLE, FULE, FO] =
239 :     [X, X, X, X, X, X, X, X,
240 :     X, X, X, X, X, X, X, X
241 :     ]
242 :     end
243 :     fun fbranch fcc {label} = if fcc then Jmp(%%label) else ()
244 :     rtl [FBN, FBNE, FBLG, FBUL, FBL, FBUG, FBG, FBU,
245 :     FBA, FBE, FBUE, FBGE, FBUGE, FBLE, FBULE, FBO] =
246 :     map fbranch floating_point_tests
247 :    
248 :     (* Floating point conditional moves *)
249 :     fun MOVfcc fcc {i, d} = if fcc then $r[d] := i else ()
250 :     fun FMOVfcc fcc { r, d} = if fcc then $f[d] := $f[r] else ()
251 :    
252 :     rtl MOV ^^ [N, NE, LG, UL, L, UG, G, U,
253 :     A, E, UE, GE, UGE, LE, ULE, O] =
254 :     map MOVfcc floating_point_tests
255 :    
256 :     rtl FMOV ^^ [N, NE, LG, UL, L, UG, G, U,
257 :     A, E, UE, GE, UGE, LE, ULE, O] =
258 :     map FMOVfcc floating_point_tests
259 :    
260 :     (* Traps *)
261 :     fun Trap x = Jmp x (* XXX *)
262 :     fun Ticc cc {r,i} = if cc then Trap(disp(r,i)) else ()
263 :     fun Txcc cc {r,i} = if cc then Trap(disp(r,i)) else ()
264 :    
265 :     rtl TICC ^^ [BN,BE, BLE,BL, BLEU,BCS,BNEG,BVS,
266 :     BA,BNE,BG, BGE,BGU, BCC,BPOS,BVC] =
267 :     map Ticc integer_tests
268 :     rtl TXCC ^^ [BN,BE, BLE,BL, BLEU,BCS,BNEG,BVS,
269 :     BA,BNE,BG, BGE,BGU, BCC,BPOS,BVC] =
270 :     map Txcc integer_tests
271 :    
272 :     (* Jmps, calls and returns *)
273 :     rtl JMP{r,i} = Jmp(disp(r,i))
274 :     rtl JMPL{r,i,d,defs,uses} =
275 :     Call(disp(r,i)) ||
276 :     $r[d] := ??? ||
277 :     Kill $cellset[defs] ||
278 :     Use $cellset[uses]
279 :     rtl CALL{label,defs,uses} =
280 :     Call(%%label) ||
281 :     Kill $cellset[defs] ||
282 :     Use $cellset[uses]
283 :     rtl RET{} = Ret
284 :    
285 :     end (* RTL *)
286 :    
287 :     structure Instruction =
288 :     struct
289 :     datatype load : op3! = LDSB 0b001001
290 :     | LDSH 0b001010
291 :     | LDUB 0b000001
292 :     | LDUH 0b000010
293 :     | LD 0b000000
294 :     | LDX 0b001011 (* v9 *)
295 :     | LDD 0b000011
296 :     datatype store : op3! = STB 0b000101
297 :     | STH 0b000110
298 :     | ST 0b000100
299 :     | STX 0b001110 (* v9 *)
300 :     | STD 0b000111
301 :     datatype fload : op3! = LDF 0b100000
302 :     | LDDF 0b100011
303 :     | LDQF 0b100010 (* v9 *)
304 :     | LDFSR 0b100001 (* rd = 0 *)
305 :     | LDXFSR 0b100001 (* v9 *) (* rd = 1 *)
306 :     datatype fstore : op3! = STF 0b100100
307 :     | STDF 0b100111
308 :     | STFSR 0b100101
309 :     datatype arith : op3! = AND 0b000001
310 :     | ANDCC 0b010001
311 :     | ANDN 0b000101
312 :     | ANDNCC 0b010101
313 :     | OR 0b000010
314 :     | ORCC 0b010010
315 :     | ORN 0b000110
316 :     | ORNCC 0b010110
317 :     | XOR 0b000011
318 :     | XORCC 0b010011
319 :     | XNOR 0b000111
320 :     | XNORCC 0b010111
321 :     | ADD 0b000000
322 :     | ADDCC 0b010000
323 :     | TADD 0b100000
324 :     | TADDCC 0b110000
325 :     | TADDTV 0b100010
326 :     | TADDTVCC 0b110010
327 :     | SUB 0b000100
328 :     | SUBCC 0b010100
329 :     | TSUB 0b100001
330 :     | TSUBCC 0b110001
331 :     | TSUBTV 0b100011
332 :     | TSUBTVCC 0b110011
333 :     | UMUL 0b001010
334 :     | UMULCC 0b011010
335 :     | SMUL 0b001011
336 :     | SMULCC 0b011011
337 :     | UDIV 0b001110
338 :     | UDIVCC 0b011110
339 :     | SDIV 0b001111
340 :     | SDIVCC 0b011111
341 :     (* v9 extensions *)
342 :     | MULX 0b001001
343 :     | SDIVX 0b101101
344 :     | UDIVX 0b001101
345 :     (* op3, x *)
346 :     datatype shift : op3! = SLL (0wb100101,0w0)
347 :     | SRL (0wb100110,0w0)
348 :     | SRA (0wb100111,0w0)
349 :     (* v9 extensions *)
350 :     | SLLX (0wb100101,0w1)
351 :     | SRLX (0wb100110,0w1)
352 :     | SRAX (0wb100111,0w1)
353 :     datatype farith1 : opf! = FiTOs 0b011000100
354 :     | FiTOd 0b011001000
355 :     | FiTOq 0b011001100
356 :     | FsTOi 0b011010001
357 :     | FdTOi 0b011010010
358 :     | FqTOi 0b011010011
359 :     | FsTOd 0b011001001
360 :     | FsTOq 0b011010101
361 :     | FdTOs 0b011000110
362 :     | FdTOq 0b011001110
363 :     | FqTOs 0b011000111
364 :     | FqTOd 0b011001011
365 :     | FMOVs 0b000000001
366 :     | FNEGs 0b000000101
367 :     | FABSs 0b000001001
368 :     | FMOVd | FNEGd | FABSd (* composite instr *)
369 :     | FMOVq | FNEGq | FABSq (* composite instr *)
370 :     | FSQRTs 0b000101001
371 :     | FSQRTd 0b000101010
372 :     | FSQRTq 0b000101011
373 :     datatype farith2 :opf! = FADDs 0b001000001
374 :     | FADDd 0b001000010
375 :     | FADDq 0b001000011
376 :     | FSUBs 0b001000101
377 :     | FSUBd 0b001000110
378 :     | FSUBq 0b001000111
379 :     | FMULs 0b001001001
380 :     | FMULd 0b001001010
381 :     | FMULq 0b001001011
382 :     | FsMULd 0b001101001
383 :     | FdMULq 0b001101110
384 :     | FDIVs 0b001001101
385 :     | FDIVd 0b001001110
386 :     | FDIVq 0b001001111
387 :     datatype fcmp : opf! = FCMPs 0b001010001
388 :     | FCMPd 0b001010010
389 :     | FCMPq 0b001010011
390 :     | FCMPEs 0b001010101
391 :     | FCMPEd 0b001010110
392 :     | FCMPEq 0b001010111
393 :    
394 :     datatype branch [0..15] : cond! =
395 :     BN "n"
396 :     | BE "e"
397 :     | BLE "le"
398 :     | BL "l"
399 :     | BLEU "leu"
400 :     | BCS "cs"
401 :     | BNEG "neg"
402 :     | BVS "vs"
403 :     | BA ""
404 :     | BNE "ne"
405 :     | BG "g"
406 :     | BGE "ge"
407 :     | BGU "gu"
408 :     | BCC "cc"
409 :     | BPOS "pos"
410 :     | BVC "vs"
411 :    
412 :     datatype rcond! = (* V9 integer conditions *)
413 :     RZ 0b001
414 :     | RLEZ 0b010
415 :     | RLZ 0b011
416 :     | RNZ 0b101
417 :     | RGZ 0b110
418 :     | RGEZ 0b111
419 :    
420 :     datatype cc = (* V9 condition register *)
421 :     ICC 0b00
422 :     | XCC 0b10
423 :    
424 :     datatype prediction! = (* V9 branch prediction bit *)
425 :     PT | PN
426 :    
427 :     datatype fbranch [0..15] : cond! =
428 :     FBN
429 :     | FBNE
430 :     | FBLG
431 :     | FBUL
432 :     | FBL
433 :     | FBUG
434 :     | FBG
435 :     | FBU
436 :     | FBA "fb"
437 :     | FBE
438 :     | FBUE
439 :     | FBGE
440 :     | FBUGE
441 :     | FBLE
442 :     | FBULE
443 :     | FBO
444 :    
445 :     datatype ea = Direct of $GP
446 :     | FDirect of $GP
447 :     | Displace of {base: $GP, disp: int}
448 :    
449 :     (* used to encode the opf_low field V9 *)
450 :     datatype fsize! = S 0b00100
451 :     | D 0b00110
452 :     | Q 0b00111
453 :    
454 :     datatype operand =
455 : leunga 775 REG of $GP ``<GP>'' rtl: $r[GP]
456 :     | IMMED of int ``<int>'' rtl: immed int
457 :     | LAB of T.labexp ``<labexp>'' rtl: labexp
458 :     | LO of T.labexp ``%lo(<labexp>)'' rtl: lo(labexp)
459 :     | HI of T.labexp ``%hi(<labexp>)'' rtl: hi(labexp)
460 : leunga 746
461 :     type addressing_mode = C.cell * operand
462 :    
463 :     end (* Instruction *)
464 :    
465 :     functor Assembly(val V9 : bool) =
466 :     struct
467 :     (* Some helper functions for assembly generation *)
468 :     fun emit_leaf false = () | emit_leaf true = emit "l"
469 :     fun emit_nop false = () | emit_nop true = emit "\n\tnop"
470 :     fun emit_a false = () | emit_a true = emit ",a"
471 :     fun emit_cc false = () | emit_cc true = emit "cc"
472 :     end
473 :    
474 :     instruction formats 32 bits
475 :     (* Extract the value of an operand *)
476 :     opn{i} =
477 :     let fun hi22 w = (itow w) ~>> 0w10
478 :     fun lo10 w = (itow w) at [0..9]
479 :     in case i of
480 :     I.REG rs2 => error "opn"
481 :     | I.IMMED i => itow i
482 :     | I.LAB l => itow(LabelExp.valueOf l)
483 :     | I.LO l => lo10(LabelExp.valueOf l)
484 :     | I.HI l => hi22(LabelExp.valueOf l)
485 :     end
486 :    
487 :     (* basic formats, integer source registers, target type not determined.*)
488 :     | rr {op1:2, rd:5, op3:6, rs1:GP 5, i:1=0, asi:8=0, rs2:GP 5}
489 :     | ri {op1:2, rd:5, op3:6, rs1:GP 5, i:1=1, simm13:signed 13}
490 :     | rix{op1,op3,r,i,d} =
491 :     (case i of
492 :     I.REG rs2 => rr{op1,op3,rs1=r,rs2=rs2,rd=d}
493 :     | _ => ri{op1,op3,rs1=r,rd=d,simm13=opn{i}}
494 :     )
495 :    
496 :     (* GP + imm/GP -> GP *)
497 :     | rir{op1,op3,r,i,d:GP} = rix{op1,op3,r,i,d}
498 :     (* GP + imm/GP -> FP *)
499 :     | rif{op1,op3,r,i,d:FP} = rix{op1,op3,r,i,d}
500 :    
501 :     (* formats found in the Sparc architecture manual *)
502 :     | load{l:load,r,i,d} = rir{op1=0w3,op3=l,r,i,d} (* p90 *)
503 :     | store{s:store,r,i,d} = rir{op1=0w3,op3=s,r,i,d} (* p95 *)
504 :     | fload{l:fload,r,i,d} = rif{op1=0w3,op3=l,r,i,d} (* p92 *)
505 :     | fstore{s:fstore,r,i,d} = rif{op1=0w3,op3=s,r,i,d} (* p97 *)
506 :     | sethi {op1:2=0, rd:GP 5, op2:3=0b100, imm22:int signed 22} (* p104 *)
507 :     | NOP {op1:2=0, rd:5=0, op2:3=0b100, imm22:22=0} (* p105 *)
508 : blume 839 | unimp {op1:2=0, rd:5=0, op2:3=0, const22:int unsigned 22} (* p137 *)
509 : leunga 746 | delay {nop} = if nop then NOP{} else () (* delay slot *)
510 :     | arith {a:arith,r,i,d} = (* p106 *)
511 :     rir{op1=0w2,op3=a,r,i,d}
512 :    
513 :     | shiftr {op1:2=2, rd:5, op3:6, rs1:5, i:1=0, x:1, asi:7=0, rs2:GP 5}
514 :     | shifti {op1:2=2, rd:5, op3:6, rs1:5, i:1=1, x:1, asi:6=0, cnt:signed 6}
515 :     | shift {s:shift,r:GP,i,d:GP} =
516 :     let val (op3,x) = s
517 :     in case i of
518 :     I.REG rs2 => shiftr{op3,rs1=r,rs2=rs2,rd=d,x=x} (* p218 v9 *)
519 :     | _ => shifti{op3,rs1=r,cnt=opn{i},rd=d,x=x}
520 :     end
521 :     | save {r,i,d} = rir{op1=0w2,op3=0wb111100,r,i,d} (* p117 *)
522 :     | restore {r,i,d} = rir{op1=0w2,op3=0wb111101,r,i,d} (* p117 *)
523 :     | bicc{op1:2=0,a:bool 1, b:branch 4, op2:3=0b010, disp22:signed 22}
524 :     | fbfcc{op1:2=0,a:bool 1, b:fbranch 4, op2:3=0b110, disp22:signed 22}
525 :     | call {op1:2=1, disp30:signed 30} (* p125 *)
526 :     | jmpl {r,i,d} = rir{op1=0w2,op3=0wb111000,r,i,d} (* p126 *)
527 :     | jmp {r,i} = rix{op1=0w2,op3=0wb111000,r,i,d=0w0}
528 :    
529 :     | ticcr {op1:2, rd:5, op3:6, rs1:GP 5, i:1=0, cc:cc 2, _:6=0, rs2:GP 5}
530 :     | ticci {op1:2, rd:5, op3:6, rs1:GP 5, i:1=1, cc:cc 2, _:4=0,
531 :     sw_trap:signed 7}
532 :     | ticcx{op1,op3,cc,r,i,d} =
533 :     (case i of
534 :     I.REG rs2 => ticcr{op1,op3,cc,rs1=r,rs2=rs2,rd=d}
535 :     | _ => ticci{op1,op3,cc,rs1=r,rd=d,sw_trap=opn{i}}
536 :     )
537 :     | ticc {t:branch,cc,r,i} =
538 :     ticcx{op1=0w2,d=t,op3=0wb111010,cc,r,i} (* p237 (V9) *)
539 :    
540 :     | rdy {op2:2=2,d:GP 5,op3:6=0b101000,rs1:5=0,x:0..13=0} (* p131 *)
541 :     | wdy {r,i} = rix{op1=0w2,op3=0wb110000,r,i,d=0w0} (* p133 *)
542 :    
543 :     (* one input floating point format *)
544 :     | fop_1 {op1:2=2, d:5, op3:6=0b110100, rs1:5=0, a:9, r:5}
545 :     | fop1 {a:farith1,r:FP,d:FP} = fop_1{a,r,d}
546 :    
547 :     (* generate composite instruction *)
548 :     | fdouble{a:farith1,r:FP,d:FP} =
549 :     (fop_1{a,r,d};
550 :     fop_1{a=0w1,r=r+0w1,d=d+0w1}
551 :     )
552 :     | fquad{a:farith1,r:FP,d:FP} =
553 :     (fop_1{a,r,d};
554 :     fop_1{a=0w1,r=r+0w1,d=d+0w1};
555 :     fop_1{a=0w1,r=r+0w2,d=d+0w2};
556 :     fop_1{a=0w1,r=r+0w3,d=d+0w3}
557 :     )
558 :    
559 :     (* two inputs floating point format *)
560 :     | fop2 {op1:2=2, d:FP 5, op3:6=0b110100, r1:FP 5, a:farith2 9, r2:FP 5}
561 :     | fcmp {op1:2=2, rd:25..29=0, op3:6=0b110101, rs1:FP 5, opf:fcmp 9,rs2:FP 5}
562 :    
563 :     (* conditional moves formats (V9) *)
564 :     | cmovr{op1:2=2,op3:6,rd:5,cc2:1,cond:4,i:1=0,cc1:1,cc0:1,_:6=0,rs2:5}
565 :     | cmovi{op1:2=2,op3:6,rd:5,cc2:1,cond:4,i:1=1,cc1:1,cc0:1,simm11:signed 11}
566 :     | cmov{op3,cond,cc2,cc1,cc0,i,rd} =
567 :     (case i of
568 :     I.REG rs2 => cmovr{op3,cond,rs2=emit_GP rs2,rd,cc0,cc1,cc2}
569 :     | _ => cmovi{op3,cond,rd,cc0,cc1,cc2,simm11=opn{i}}
570 :     )
571 :    
572 :     | movicc {b:branch,i,d:GP} =
573 :     cmov{op3=0wb101100,cond=b,i,rd=d,cc2=0w1,cc1=0w0,cc0=0w0}
574 :     | movfcc {b:fbranch,i,d:GP} = (* use fcc0 *)
575 :     cmov{op3=0wb101100,cond=b,i,rd=d,cc2=0w0,cc1=0w0,cc0=0w0}
576 :     | fmovicc{sz:fsize,b:branch,r:FP,d:FP} =
577 :     cmovr{op3=0wb101100,cond=b,rs2=r,rd=d,cc2=0w1,cc1=0w0,cc0=0w0}
578 :     | fmovfcc{sz:fsize,b:fbranch,r:FP,d:FP} = (* use fcc0 *)
579 :     cmovr{op3=0wb101100,cond=b,rs2=r,rd=d,cc2=0w0,cc1=0w0,cc0=0w0}
580 :    
581 :     (* move integer register on register condition format *)
582 :     | movrr {op1:2=2, rd:GP 5, op3:6=0b101111, rs1:GP 5, i:1=0, rcond:3,
583 :     asi:5=0, rs2:GP 5}
584 :     | movri {op1:2=2, rd:GP 5, op3:6=0b101111, rs1:GP 5, i:1=1, rcond:3,
585 :     simm10:signed 10}
586 :     | movr{rcond:rcond,r,i,d} =
587 :     (case i of
588 :     I.REG rs2 => movrr{rcond,rs1=r,rs2=rs2,rd=d}
589 :     | _ => movri{rcond,rs1=r,rd=d,simm10=opn{i}}
590 :     )
591 :    
592 :     structure MC =
593 :     struct
594 :     (* this computes the displacement address *)
595 :     fun disp label = itow((Label.addrOf label - !loc)) ~>> 0w2
596 :     val r15 = C.Reg C.GP 15
597 :     and r31 = C.Reg C.GP 31
598 :     end
599 :    
600 :    
601 :     (*
602 :     * Reservation tables and pipeline definitions for scheduling
603 :     *)
604 :    
605 :     (* Function units *)
606 :     resource issue and mem and alu and falu and fmul and fdiv and branch
607 :    
608 :     (* Different implementations of cpus *)
609 :     cpu default 2 [2 issue, 2 mem, 1 alu] (* 2 issue machine *)
610 :    
611 :     (* Definitions of various reservation tables *)
612 :     pipeline NOP _ = [issue]
613 :     and ARITH _ = [issue^^alu]
614 :     and LOAD _ = [issue^^mem]
615 :     and STORE _ = [issue^^mem,mem,mem]
616 :     and FARITH _ = [issue^^falu]
617 :     and FMUL _ = [issue^^fmul,fmul]
618 :     and FDIV _ = [issue^^fdiv,fdiv*50]
619 :     and BRANCH _ = [issue^^branch]
620 :    
621 :     (*
622 :     * Notation:
623 :     * r -- source register
624 :     * i -- source operand (immed or register)
625 :     * d -- destination register (or data register in store instructions)
626 :     *)
627 :     instruction
628 :     LOAD of { l:load, d: $GP, r: $GP, i:operand, mem:Region.region }
629 :     asm: ``<l>\t[<r>+<i>], <d><mem>''
630 :     mc: load{l,r,i,d}
631 :     rtl: ``<l>''
632 :     latency: 1
633 :    
634 :     | STORE of { s:store, d: $GP, r: $GP, i:operand, mem:Region.region }
635 :     asm: ``<s>\t<d>, [<r>+<i>]<mem>''
636 :     mc: store{s,r,i,d}
637 :     rtl: ``<s>''
638 :    
639 :     | FLOAD of { l:fload, r: $GP, i:operand, d: $FP, mem:Region.region }
640 :     asm: ``<l>\t[<r>+<i>], <d><mem>''
641 :     mc: fload{l,r,i,d}
642 :     rtl: ``<l>''
643 :     latency: 1
644 :    
645 :     | FSTORE of { s:fstore, d: $FP, r: $GP, i:operand, mem:Region.region }
646 :     asm: ``<s>\t[<r>+<i>], <d><mem>''
647 :     mc: fstore{s,r,i,d}
648 :     rtl: ``<s>''
649 :    
650 : blume 839 | UNIMP of { const22: int }
651 :     asm: ``unimp <const22>''
652 :     mc: unimp{const22}
653 :    
654 : leunga 746 | SETHI of { i:int, d: $GP }
655 :     asm: let val i = Word32.toString(Word32.<<(Word32.fromInt i,0w10))
656 :     in ``sethi\t%hi(0x<emit i>), <d>''
657 :     end
658 :     mc: sethi{imm22=i,rd=d}
659 :     rtl: ``SETHI''
660 :    
661 :     | ARITH of { a:arith, r: $GP, i:operand, d: $GP }
662 :     asm: (case (a,C.registerId r,C.registerId d) of
663 :     (* generate abbreviations! *)
664 :     (I.OR,0,_) => ``mov\t<i>, <d>''
665 :     | (I.SUBCC,_,0) => ``cmp\t<r>, <i>''
666 :     | _ => ``<a>\t<r>, <i>, <d>''
667 :     )
668 :     mc: arith{a,r,i,d}
669 :     rtl: (case (a,C.registerId r) of
670 :     (I.OR, 0) => ``<li>''
671 :     | _ => ``<a>''
672 :     )
673 :    
674 :     | SHIFT of { s:shift, r: $GP, i:operand, d: $GP }
675 :     asm: ``<s>\t<r>, <i>, <d>''
676 :     mc: shift{s,r,i,d}
677 :     rtl: ``<s>''
678 :    
679 :     (* Conditional moves! *)
680 :     | MOVicc of {b:branch, i:operand, d: $GP } (* V9 *)
681 :     asm: ``mov<b>\t<i>, <d>''
682 :     mc: movicc{b,i,d}
683 :    
684 :     | MOVfcc of {b:fbranch, i:operand, d: $GP } (* V9 *)
685 :     asm: ``mov<b>\t<i>, <d>''
686 :     mc: movfcc{b,i,d}
687 :    
688 :     | MOVR of {rcond:rcond, r: $GP, i: operand, d: $GP} (* V9 *)
689 :     asm: ``movr<rcond>\t<r>, <i>, <d>''
690 :     mc: movr{rcond,r,i,d}
691 :    
692 :     | FMOVicc of {sz:fsize, b:branch, r: $FP, d: $FP } (* V9 *)
693 :     asm: ``fmov<sz><b>\t<r>, <d>''
694 :     mc: fmovicc{sz,b,r,d}
695 :    
696 :     | FMOVfcc of {sz:fsize, b:fbranch, r: $FP, d: $FP } (* V9 *)
697 :     asm: ``fmov<sz><b>\t<r>, <d>''
698 :     mc: fmovfcc{sz,b,r,d}
699 :    
700 :     | Bicc of { b:branch, a:bool, label:Label.label, nop:bool}
701 :     asm: ``b<b><a>\t<label><nop>''
702 :     mc: (bicc{b,a,disp22=disp label}; delay{nop})
703 :     rtl: ``<b>''
704 :     padding: nop = true
705 :     nullified: a = true and (case b of I.BA => false | _ => true)
706 :     delayslot candidate: false
707 :    
708 :     | FBfcc of { b:fbranch, a:bool, label:Label.label, nop:bool }
709 :     asm: ``<b><a>\t<label><nop>''
710 :     mc: (fbfcc{b,a,disp22=disp label}; delay{nop})
711 :     rtl: ``<b>''
712 :     padding: nop = true
713 :     nullified: a = true
714 :     delayslot candidate: false
715 :    
716 :     (* V9 branch on condition in integer register *)
717 :     | BR of {rcond:rcond, p:prediction, r: $GP, a:bool,
718 :     label:Label.label, nop:bool}
719 :     asm: ``b<rcond><a><p>\t<r>, <label><nop>''
720 :    
721 :     (* V9 branch on integer condition code with prediction *)
722 :     | BP of {b:branch, p:prediction, cc:cc, a:bool, label:Label.label,nop:bool}
723 :     asm: ``bp<b><a><p>\t%<emit(if cc = I.ICC then "i" else "x")>cc, <label><nop>''
724 :     | JMP of { r: $GP, i:operand, labs : Label.label list, nop:bool}
725 :     asm: ``jmp\t[<r>+<i>]<nop>''
726 :     mc: (jmp{r,i}; delay{nop})
727 :     rtl: ``JMP''
728 :     padding: nop = true
729 :     nullified: false
730 :     delayslot candidate: false
731 :    
732 :     | JMPL of { r: $GP, i:operand, d: $GP,
733 : leunga 796 defs: $cellset, uses: $cellset,
734 :     cutsTo : Label.label list, nop:bool, mem:Region.region
735 : leunga 746 }
736 : leunga 796 asm: ``jmpl\t[<r>+<i>], <d><mem><emit_defs defs><emit_uses uses><emit_cutsTo cutsTo><nop>''
737 : leunga 746 mc: (jmpl{r,i,d}; delay{nop})
738 :     rtl: ``JMPL''
739 :     padding: nop = true
740 :     nullified: false
741 :     delayslot candidate: false
742 :    
743 :     | CALL of { defs: $cellset, uses: $cellset,
744 : leunga 796 label:Label.label, cutsTo:Label.label list,
745 :     nop:bool, mem:Region.region
746 : leunga 746 }
747 : leunga 796 asm: ``call\t<label><mem><emit_defs(defs)><emit_uses(uses)><emit_cutsTo cutsTo><nop>''
748 : leunga 746 mc: (call{disp30=disp label}; delay{nop})
749 :     rtl: ``CALL''
750 :     padding: nop
751 :     nullified: false
752 :     delayslot candidate: false
753 :    
754 :     (* Note, for V8 the cc bit must be ICC *)
755 :     | Ticc of { t:branch, cc:cc, r: $GP, i:operand}
756 :     asm: ``t<t>\t<if cc = I.ICC then () else emit "%xcc, "><r>+<i>''
757 :     mc: ticc{t,r,cc,i}
758 :     rtl: ``T<cc><t>''
759 :     delayslot candidate: false
760 :    
761 :     | FPop1 of { a:farith1, r: $FP, d: $FP }
762 :     asm: let fun f(a,r,d) =
763 :     (emit(a); emit "\t";
764 :     emit(C.showFP r);
765 :     emit ", ";
766 :     emit(C.showFP d))
767 :     fun g(a,r,d) =
768 :     let val r = C.registerNum r and d = C.registerNum d
769 :     in f(a,r,d); emit "\n\t";
770 :     f("fmovs",r+1,d+1)
771 :     end
772 :     fun h(a,r,d) =
773 :     let val r = C.registerNum r and d = C.registerNum d
774 :     in f(a,r,d); emit "\n\t";
775 :     f("fmovs",r+1,d+1); emit "\n\t";
776 :     f("fmovs",r+2,d+2); emit "\n\t";
777 :     f("fmovs",r+3,d+3)
778 :     end
779 :     in if V9 then ``<a>\t<r>, <d>''
780 :     else
781 :     case a of
782 :     I.FMOVd => g("fmovs",r,d)
783 :     | I.FNEGd => g("fnegs",r,d)
784 :     | I.FABSd => g("fabss",r,d)
785 :     | I.FMOVq => h("fmovs",r,d)
786 :     | I.FNEGq => h("fnegs",r,d)
787 :     | I.FABSq => h("fabss",r,d)
788 :     | _ => ``<a>\t<r>, <d>''
789 :     end
790 :     mc: (case a of
791 :     (* composite instructions *)
792 :     I.FMOVd => fdouble{a=I.FMOVs,r,d}
793 :     | I.FNEGd => fdouble{a=I.FNEGs,r,d}
794 :     | I.FABSd => fdouble{a=I.FABSs,r,d}
795 :     | I.FMOVq => fquad{a=I.FMOVs,r,d}
796 :     | I.FNEGq => fquad{a=I.FNEGs,r,d}
797 :     | I.FABSq => fquad{a=I.FABSs,r,d}
798 :     | _ => fop1{a,r,d}
799 :     )
800 :     rtl: ``<a>''
801 :    
802 :     | FPop2 of { a:farith2, r1: $FP, r2: $FP, d: $FP }
803 :     asm: ``<a>\t<r1>, <r2>, <d>''
804 :     mc: fop2{a,r1,r2,d}
805 :     rtl: ``<a>''
806 :    
807 :     | FCMP of { cmp:fcmp, r1: $FP, r2: $FP, nop:bool }
808 :     asm: ``<cmp>\t<r1>, <r2><nop>''
809 :     mc: (fcmp{opf=cmp,rs1=r1,rs2=r2}; delay{nop})
810 :     rtl: ``<cmp>''
811 :     padding: nop = true
812 :     nullified: false
813 :     delayslot candidate: false
814 :     latency: 1
815 :    
816 :     | COPY of { dst: $GP list, src: $GP list,
817 :     impl:instruction list option ref, tmp:ea option}
818 :     asm: emitInstrs (Shuffle.shuffle{tmp,src,dst})
819 :     rtl: ``COPY''
820 :    
821 :     | FCOPY of { dst: $FP list, src: $FP list,
822 :     impl:instruction list option ref, tmp:ea option}
823 :     asm: emitInstrs (Shuffle.shufflefp{tmp,src,dst})
824 :     rtl: ``FCOPY''
825 :    
826 :     | SAVE of {r: $GP, i:operand, d: $GP}
827 :     asm: ``save\t<r>, <i>, <d>''
828 :     mc: save{r,i,d}
829 :    
830 :     | RESTORE of {r: $GP, i:operand, d: $GP}
831 :     asm: ``restore\t<r>, <i>, <d>''
832 :     mc: restore{r,i,d}
833 :    
834 :     | RDY of {d: $GP}
835 :     asm: ``rd\t%y, <d>''
836 :     mc: rdy{d}
837 :     rtl: ``RDY''
838 :    
839 :     | WRY of {r: $GP,i:operand}
840 :     asm: ``wr\t<r>, <i>, %y''
841 :     mc: wdy{r,i}
842 :     rtl: ``WRY''
843 :    
844 :     | RET of {leaf:bool,nop:bool}
845 :     asm: ``ret<leaf><nop>''
846 :     mc: (jmp{r=if leaf then r31 else r15,i=I.IMMED 8}; delay{nop})
847 :     rtl: ``RET''
848 :     padding: nop = true
849 :     nullified: false
850 :    
851 :     | ANNOTATION of {i:instruction, a:Annotations.annotation}
852 :     asm: (comment(Annotations.toString a); nl(); emitInstr i)
853 :     mc: emitInstr i
854 :     (* rtl: [[#i ]] *)
855 :    
856 :     | SOURCE of {}
857 :     asm: ``source''
858 :     mc: ()
859 :    
860 :     | SINK of {}
861 :     asm: ``sink''
862 :     mc: ()
863 :    
864 :     | PHI of {}
865 :     asm: ``phi''
866 :     mc: ()
867 :    
868 :     structure SSA =
869 :     struct
870 :     fun operand(ty,I.REG r) = T.REG(ty, r)
871 : leunga 775 | operand(ty,I.IMMED i) = T.LI(IntInf.fromInt i)
872 : leunga 746 (*| operand(ty,I.LAB le) = T.LABEL le*)
873 :     | operand(ty,_) = error "operand"
874 :     end
875 :    
876 :     end

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0