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

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