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 775 - (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 :     | delay {nop} = if nop then NOP{} else () (* delay slot *)
509 :     | arith {a:arith,r,i,d} = (* p106 *)
510 :     rir{op1=0w2,op3=a,r,i,d}
511 :    
512 :     | shiftr {op1:2=2, rd:5, op3:6, rs1:5, i:1=0, x:1, asi:7=0, rs2:GP 5}
513 :     | shifti {op1:2=2, rd:5, op3:6, rs1:5, i:1=1, x:1, asi:6=0, cnt:signed 6}
514 :     | shift {s:shift,r:GP,i,d:GP} =
515 :     let val (op3,x) = s
516 :     in case i of
517 :     I.REG rs2 => shiftr{op3,rs1=r,rs2=rs2,rd=d,x=x} (* p218 v9 *)
518 :     | _ => shifti{op3,rs1=r,cnt=opn{i},rd=d,x=x}
519 :     end
520 :     | save {r,i,d} = rir{op1=0w2,op3=0wb111100,r,i,d} (* p117 *)
521 :     | restore {r,i,d} = rir{op1=0w2,op3=0wb111101,r,i,d} (* p117 *)
522 :     | bicc{op1:2=0,a:bool 1, b:branch 4, op2:3=0b010, disp22:signed 22}
523 :     | fbfcc{op1:2=0,a:bool 1, b:fbranch 4, op2:3=0b110, disp22:signed 22}
524 :     | call {op1:2=1, disp30:signed 30} (* p125 *)
525 :     | jmpl {r,i,d} = rir{op1=0w2,op3=0wb111000,r,i,d} (* p126 *)
526 :     | jmp {r,i} = rix{op1=0w2,op3=0wb111000,r,i,d=0w0}
527 :    
528 :     | ticcr {op1:2, rd:5, op3:6, rs1:GP 5, i:1=0, cc:cc 2, _:6=0, rs2:GP 5}
529 :     | ticci {op1:2, rd:5, op3:6, rs1:GP 5, i:1=1, cc:cc 2, _:4=0,
530 :     sw_trap:signed 7}
531 :     | ticcx{op1,op3,cc,r,i,d} =
532 :     (case i of
533 :     I.REG rs2 => ticcr{op1,op3,cc,rs1=r,rs2=rs2,rd=d}
534 :     | _ => ticci{op1,op3,cc,rs1=r,rd=d,sw_trap=opn{i}}
535 :     )
536 :     | ticc {t:branch,cc,r,i} =
537 :     ticcx{op1=0w2,d=t,op3=0wb111010,cc,r,i} (* p237 (V9) *)
538 :    
539 :     | rdy {op2:2=2,d:GP 5,op3:6=0b101000,rs1:5=0,x:0..13=0} (* p131 *)
540 :     | wdy {r,i} = rix{op1=0w2,op3=0wb110000,r,i,d=0w0} (* p133 *)
541 :    
542 :     (* one input floating point format *)
543 :     | fop_1 {op1:2=2, d:5, op3:6=0b110100, rs1:5=0, a:9, r:5}
544 :     | fop1 {a:farith1,r:FP,d:FP} = fop_1{a,r,d}
545 :    
546 :     (* generate composite instruction *)
547 :     | fdouble{a:farith1,r:FP,d:FP} =
548 :     (fop_1{a,r,d};
549 :     fop_1{a=0w1,r=r+0w1,d=d+0w1}
550 :     )
551 :     | fquad{a:farith1,r:FP,d:FP} =
552 :     (fop_1{a,r,d};
553 :     fop_1{a=0w1,r=r+0w1,d=d+0w1};
554 :     fop_1{a=0w1,r=r+0w2,d=d+0w2};
555 :     fop_1{a=0w1,r=r+0w3,d=d+0w3}
556 :     )
557 :    
558 :     (* two inputs floating point format *)
559 :     | fop2 {op1:2=2, d:FP 5, op3:6=0b110100, r1:FP 5, a:farith2 9, r2:FP 5}
560 :     | fcmp {op1:2=2, rd:25..29=0, op3:6=0b110101, rs1:FP 5, opf:fcmp 9,rs2:FP 5}
561 :    
562 :     (* conditional moves formats (V9) *)
563 :     | cmovr{op1:2=2,op3:6,rd:5,cc2:1,cond:4,i:1=0,cc1:1,cc0:1,_:6=0,rs2:5}
564 :     | cmovi{op1:2=2,op3:6,rd:5,cc2:1,cond:4,i:1=1,cc1:1,cc0:1,simm11:signed 11}
565 :     | cmov{op3,cond,cc2,cc1,cc0,i,rd} =
566 :     (case i of
567 :     I.REG rs2 => cmovr{op3,cond,rs2=emit_GP rs2,rd,cc0,cc1,cc2}
568 :     | _ => cmovi{op3,cond,rd,cc0,cc1,cc2,simm11=opn{i}}
569 :     )
570 :    
571 :     | movicc {b:branch,i,d:GP} =
572 :     cmov{op3=0wb101100,cond=b,i,rd=d,cc2=0w1,cc1=0w0,cc0=0w0}
573 :     | movfcc {b:fbranch,i,d:GP} = (* use fcc0 *)
574 :     cmov{op3=0wb101100,cond=b,i,rd=d,cc2=0w0,cc1=0w0,cc0=0w0}
575 :     | fmovicc{sz:fsize,b:branch,r:FP,d:FP} =
576 :     cmovr{op3=0wb101100,cond=b,rs2=r,rd=d,cc2=0w1,cc1=0w0,cc0=0w0}
577 :     | fmovfcc{sz:fsize,b:fbranch,r:FP,d:FP} = (* use fcc0 *)
578 :     cmovr{op3=0wb101100,cond=b,rs2=r,rd=d,cc2=0w0,cc1=0w0,cc0=0w0}
579 :    
580 :     (* move integer register on register condition format *)
581 :     | movrr {op1:2=2, rd:GP 5, op3:6=0b101111, rs1:GP 5, i:1=0, rcond:3,
582 :     asi:5=0, rs2:GP 5}
583 :     | movri {op1:2=2, rd:GP 5, op3:6=0b101111, rs1:GP 5, i:1=1, rcond:3,
584 :     simm10:signed 10}
585 :     | movr{rcond:rcond,r,i,d} =
586 :     (case i of
587 :     I.REG rs2 => movrr{rcond,rs1=r,rs2=rs2,rd=d}
588 :     | _ => movri{rcond,rs1=r,rd=d,simm10=opn{i}}
589 :     )
590 :    
591 :     structure MC =
592 :     struct
593 :     (* this computes the displacement address *)
594 :     fun disp label = itow((Label.addrOf label - !loc)) ~>> 0w2
595 :     val r15 = C.Reg C.GP 15
596 :     and r31 = C.Reg C.GP 31
597 :     end
598 :    
599 :    
600 :     (*
601 :     * Reservation tables and pipeline definitions for scheduling
602 :     *)
603 :    
604 :     (* Function units *)
605 :     resource issue and mem and alu and falu and fmul and fdiv and branch
606 :    
607 :     (* Different implementations of cpus *)
608 :     cpu default 2 [2 issue, 2 mem, 1 alu] (* 2 issue machine *)
609 :    
610 :     (* Definitions of various reservation tables *)
611 :     pipeline NOP _ = [issue]
612 :     and ARITH _ = [issue^^alu]
613 :     and LOAD _ = [issue^^mem]
614 :     and STORE _ = [issue^^mem,mem,mem]
615 :     and FARITH _ = [issue^^falu]
616 :     and FMUL _ = [issue^^fmul,fmul]
617 :     and FDIV _ = [issue^^fdiv,fdiv*50]
618 :     and BRANCH _ = [issue^^branch]
619 :    
620 :     (*
621 :     * Notation:
622 :     * r -- source register
623 :     * i -- source operand (immed or register)
624 :     * d -- destination register (or data register in store instructions)
625 :     *)
626 :     instruction
627 :     LOAD of { l:load, d: $GP, r: $GP, i:operand, mem:Region.region }
628 :     asm: ``<l>\t[<r>+<i>], <d><mem>''
629 :     mc: load{l,r,i,d}
630 :     rtl: ``<l>''
631 :     latency: 1
632 :    
633 :     | STORE of { s:store, d: $GP, r: $GP, i:operand, mem:Region.region }
634 :     asm: ``<s>\t<d>, [<r>+<i>]<mem>''
635 :     mc: store{s,r,i,d}
636 :     rtl: ``<s>''
637 :    
638 :     | FLOAD of { l:fload, r: $GP, i:operand, d: $FP, mem:Region.region }
639 :     asm: ``<l>\t[<r>+<i>], <d><mem>''
640 :     mc: fload{l,r,i,d}
641 :     rtl: ``<l>''
642 :     latency: 1
643 :    
644 :     | FSTORE of { s:fstore, d: $FP, r: $GP, i:operand, mem:Region.region }
645 :     asm: ``<s>\t[<r>+<i>], <d><mem>''
646 :     mc: fstore{s,r,i,d}
647 :     rtl: ``<s>''
648 :    
649 :     | SETHI of { i:int, d: $GP }
650 :     asm: let val i = Word32.toString(Word32.<<(Word32.fromInt i,0w10))
651 :     in ``sethi\t%hi(0x<emit i>), <d>''
652 :     end
653 :     mc: sethi{imm22=i,rd=d}
654 :     rtl: ``SETHI''
655 :    
656 :     | ARITH of { a:arith, r: $GP, i:operand, d: $GP }
657 :     asm: (case (a,C.registerId r,C.registerId d) of
658 :     (* generate abbreviations! *)
659 :     (I.OR,0,_) => ``mov\t<i>, <d>''
660 :     | (I.SUBCC,_,0) => ``cmp\t<r>, <i>''
661 :     | _ => ``<a>\t<r>, <i>, <d>''
662 :     )
663 :     mc: arith{a,r,i,d}
664 :     rtl: (case (a,C.registerId r) of
665 :     (I.OR, 0) => ``<li>''
666 :     | _ => ``<a>''
667 :     )
668 :    
669 :     | SHIFT of { s:shift, r: $GP, i:operand, d: $GP }
670 :     asm: ``<s>\t<r>, <i>, <d>''
671 :     mc: shift{s,r,i,d}
672 :     rtl: ``<s>''
673 :    
674 :     (* Conditional moves! *)
675 :     | MOVicc of {b:branch, i:operand, d: $GP } (* V9 *)
676 :     asm: ``mov<b>\t<i>, <d>''
677 :     mc: movicc{b,i,d}
678 :    
679 :     | MOVfcc of {b:fbranch, i:operand, d: $GP } (* V9 *)
680 :     asm: ``mov<b>\t<i>, <d>''
681 :     mc: movfcc{b,i,d}
682 :    
683 :     | MOVR of {rcond:rcond, r: $GP, i: operand, d: $GP} (* V9 *)
684 :     asm: ``movr<rcond>\t<r>, <i>, <d>''
685 :     mc: movr{rcond,r,i,d}
686 :    
687 :     | FMOVicc of {sz:fsize, b:branch, r: $FP, d: $FP } (* V9 *)
688 :     asm: ``fmov<sz><b>\t<r>, <d>''
689 :     mc: fmovicc{sz,b,r,d}
690 :    
691 :     | FMOVfcc of {sz:fsize, b:fbranch, r: $FP, d: $FP } (* V9 *)
692 :     asm: ``fmov<sz><b>\t<r>, <d>''
693 :     mc: fmovfcc{sz,b,r,d}
694 :    
695 :     | Bicc of { b:branch, a:bool, label:Label.label, nop:bool}
696 :     asm: ``b<b><a>\t<label><nop>''
697 :     mc: (bicc{b,a,disp22=disp label}; delay{nop})
698 :     rtl: ``<b>''
699 :     padding: nop = true
700 :     nullified: a = true and (case b of I.BA => false | _ => true)
701 :     delayslot candidate: false
702 :    
703 :     | FBfcc of { b:fbranch, a:bool, label:Label.label, nop:bool }
704 :     asm: ``<b><a>\t<label><nop>''
705 :     mc: (fbfcc{b,a,disp22=disp label}; delay{nop})
706 :     rtl: ``<b>''
707 :     padding: nop = true
708 :     nullified: a = true
709 :     delayslot candidate: false
710 :    
711 :     (* V9 branch on condition in integer register *)
712 :     | BR of {rcond:rcond, p:prediction, r: $GP, a:bool,
713 :     label:Label.label, nop:bool}
714 :     asm: ``b<rcond><a><p>\t<r>, <label><nop>''
715 :    
716 :     (* V9 branch on integer condition code with prediction *)
717 :     | BP of {b:branch, p:prediction, cc:cc, a:bool, label:Label.label,nop:bool}
718 :     asm: ``bp<b><a><p>\t%<emit(if cc = I.ICC then "i" else "x")>cc, <label><nop>''
719 :     | JMP of { r: $GP, i:operand, labs : Label.label list, nop:bool}
720 :     asm: ``jmp\t[<r>+<i>]<nop>''
721 :     mc: (jmp{r,i}; delay{nop})
722 :     rtl: ``JMP''
723 :     padding: nop = true
724 :     nullified: false
725 :     delayslot candidate: false
726 :    
727 :     | JMPL of { r: $GP, i:operand, d: $GP,
728 :     defs: $cellset, uses: $cellset, nop:bool, mem:Region.region
729 :     }
730 :     asm: ``jmpl\t[<r>+<i>], <d><mem><emit_defs defs><emit_uses uses><nop>''
731 :     mc: (jmpl{r,i,d}; delay{nop})
732 :     rtl: ``JMPL''
733 :     padding: nop = true
734 :     nullified: false
735 :     delayslot candidate: false
736 :    
737 :     | CALL of { defs: $cellset, uses: $cellset,
738 :     label:Label.label, nop:bool, mem:Region.region
739 :     }
740 :     asm: ``call\t<label><mem><emit_defs(defs)><emit_uses(uses)><nop>''
741 :     mc: (call{disp30=disp label}; delay{nop})
742 :     rtl: ``CALL''
743 :     padding: nop
744 :     nullified: false
745 :     delayslot candidate: false
746 :    
747 :     (* Note, for V8 the cc bit must be ICC *)
748 :     | Ticc of { t:branch, cc:cc, r: $GP, i:operand}
749 :     asm: ``t<t>\t<if cc = I.ICC then () else emit "%xcc, "><r>+<i>''
750 :     mc: ticc{t,r,cc,i}
751 :     rtl: ``T<cc><t>''
752 :     delayslot candidate: false
753 :    
754 :     | FPop1 of { a:farith1, r: $FP, d: $FP }
755 :     asm: let fun f(a,r,d) =
756 :     (emit(a); emit "\t";
757 :     emit(C.showFP r);
758 :     emit ", ";
759 :     emit(C.showFP d))
760 :     fun g(a,r,d) =
761 :     let val r = C.registerNum r and d = C.registerNum d
762 :     in f(a,r,d); emit "\n\t";
763 :     f("fmovs",r+1,d+1)
764 :     end
765 :     fun h(a,r,d) =
766 :     let val r = C.registerNum r and d = C.registerNum d
767 :     in f(a,r,d); emit "\n\t";
768 :     f("fmovs",r+1,d+1); emit "\n\t";
769 :     f("fmovs",r+2,d+2); emit "\n\t";
770 :     f("fmovs",r+3,d+3)
771 :     end
772 :     in if V9 then ``<a>\t<r>, <d>''
773 :     else
774 :     case a of
775 :     I.FMOVd => g("fmovs",r,d)
776 :     | I.FNEGd => g("fnegs",r,d)
777 :     | I.FABSd => g("fabss",r,d)
778 :     | I.FMOVq => h("fmovs",r,d)
779 :     | I.FNEGq => h("fnegs",r,d)
780 :     | I.FABSq => h("fabss",r,d)
781 :     | _ => ``<a>\t<r>, <d>''
782 :     end
783 :     mc: (case a of
784 :     (* composite instructions *)
785 :     I.FMOVd => fdouble{a=I.FMOVs,r,d}
786 :     | I.FNEGd => fdouble{a=I.FNEGs,r,d}
787 :     | I.FABSd => fdouble{a=I.FABSs,r,d}
788 :     | I.FMOVq => fquad{a=I.FMOVs,r,d}
789 :     | I.FNEGq => fquad{a=I.FNEGs,r,d}
790 :     | I.FABSq => fquad{a=I.FABSs,r,d}
791 :     | _ => fop1{a,r,d}
792 :     )
793 :     rtl: ``<a>''
794 :    
795 :     | FPop2 of { a:farith2, r1: $FP, r2: $FP, d: $FP }
796 :     asm: ``<a>\t<r1>, <r2>, <d>''
797 :     mc: fop2{a,r1,r2,d}
798 :     rtl: ``<a>''
799 :    
800 :     | FCMP of { cmp:fcmp, r1: $FP, r2: $FP, nop:bool }
801 :     asm: ``<cmp>\t<r1>, <r2><nop>''
802 :     mc: (fcmp{opf=cmp,rs1=r1,rs2=r2}; delay{nop})
803 :     rtl: ``<cmp>''
804 :     padding: nop = true
805 :     nullified: false
806 :     delayslot candidate: false
807 :     latency: 1
808 :    
809 :     | COPY of { dst: $GP list, src: $GP list,
810 :     impl:instruction list option ref, tmp:ea option}
811 :     asm: emitInstrs (Shuffle.shuffle{tmp,src,dst})
812 :     rtl: ``COPY''
813 :    
814 :     | FCOPY of { dst: $FP list, src: $FP list,
815 :     impl:instruction list option ref, tmp:ea option}
816 :     asm: emitInstrs (Shuffle.shufflefp{tmp,src,dst})
817 :     rtl: ``FCOPY''
818 :    
819 :     | SAVE of {r: $GP, i:operand, d: $GP}
820 :     asm: ``save\t<r>, <i>, <d>''
821 :     mc: save{r,i,d}
822 :    
823 :     | RESTORE of {r: $GP, i:operand, d: $GP}
824 :     asm: ``restore\t<r>, <i>, <d>''
825 :     mc: restore{r,i,d}
826 :    
827 :     | RDY of {d: $GP}
828 :     asm: ``rd\t%y, <d>''
829 :     mc: rdy{d}
830 :     rtl: ``RDY''
831 :    
832 :     | WRY of {r: $GP,i:operand}
833 :     asm: ``wr\t<r>, <i>, %y''
834 :     mc: wdy{r,i}
835 :     rtl: ``WRY''
836 :    
837 :     | RET of {leaf:bool,nop:bool}
838 :     asm: ``ret<leaf><nop>''
839 :     mc: (jmp{r=if leaf then r31 else r15,i=I.IMMED 8}; delay{nop})
840 :     rtl: ``RET''
841 :     padding: nop = true
842 :     nullified: false
843 :    
844 :     | ANNOTATION of {i:instruction, a:Annotations.annotation}
845 :     asm: (comment(Annotations.toString a); nl(); emitInstr i)
846 :     mc: emitInstr i
847 :     (* rtl: [[#i ]] *)
848 :    
849 :     | SOURCE of {}
850 :     asm: ``source''
851 :     mc: ()
852 :    
853 :     | SINK of {}
854 :     asm: ``sink''
855 :     mc: ()
856 :    
857 :     | PHI of {}
858 :     asm: ``phi''
859 :     mc: ()
860 :    
861 :     structure SSA =
862 :     struct
863 :     fun operand(ty,I.REG r) = T.REG(ty, r)
864 : leunga 775 | operand(ty,I.IMMED i) = T.LI(IntInf.fromInt i)
865 : leunga 746 (*| operand(ty,I.LAB le) = T.LABEL le*)
866 :     | operand(ty,_) = error "operand"
867 :     end
868 :    
869 :     end

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