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/ppc/ppc.mdl
ViewVC logotype

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 746 - (view) (download)

1 : leunga 746 (*
2 :     * This is the machine description file of PowerPC derived from Lal's code.
3 :     * I have no idea what the instructions do so it probably won't work.
4 :     *
5 :     * Note: I've now added lots of instructions for 64-bit and single precision
6 :     * floating point support.
7 :     *
8 :     * I'm using Book E: PowerPC Architecture Enhanced for Embedded Applications
9 :     * as the reference
10 :     *
11 :     * -- Allen
12 :     *)
13 :    
14 :     architecture PPC =
15 :     struct
16 :    
17 :     superscalar
18 :    
19 :     big endian
20 :    
21 :     lowercase assembly
22 :    
23 :     storage
24 :     GP = $r[32] of 64 bits asm: (fn (r,_) => Int.toString r)
25 :     | FP = $f[32] of 64 bits asm: (fn (f,_) => Int.toString f)
26 :     | CC = $cc[8] of 4 bits asm: (fn (cr,_) => "cr"^Int.toString cr)
27 :     | SPR = $spr[32] of 64 bits
28 :     asm: (fn (1,_) => "xer"
29 :     | (8,_) => "lr"
30 :     | (9,_) => "ctr"
31 :     | (r,_) => Int.toString r
32 :     )
33 :     | MEM = $m[] of 8 aggregable bits asm: (fn (r,_) => "m"^Int.toString r)
34 :     | CTRL = $ctrl[] of 8 bits asm: (fn (r,_) => "ctrl"^Int.toString r)
35 :    
36 :     locations
37 :     stackptrR = $r[1]
38 :     and asmTmpR = $r[28]
39 :     and fasmTmp = $f[0]
40 :     and r0 = $r[0]
41 :    
42 :     (* the encoding of these are from page 372 *)
43 :     and xer = $spr[1] (* Integer exception register *)
44 :     and lr = $spr[8] (* Link register *)
45 :     and ctr = $spr[9] (* counter register *)
46 :    
47 :     structure RTL =
48 :     struct
49 :     end
50 :    
51 :     structure Instruction =
52 :     struct
53 :     type gpr = int (* general purpose register *)
54 :     type fpr = int (* floating point register *)
55 :     type ccr = int (* condition code register *)
56 :     type crf = int (* condition register field *)
57 :    
58 :     datatype spr! = XER | LR | CTR
59 :    
60 :     datatype operand =
61 :     RegOp of $GP ``<GP>'' (emit_GP GP) rtl: $r[GP]
62 :     | ImmedOp of int ``<int>'' (itow int) rtl: immed int
63 :     | LabelOp of LabelExp.labexp ``<emit_labexp labexp>''
64 :     (itow(LabelExp.valueOf labexp))
65 :    
66 :     type addressing_mode = C.cell * operand
67 :    
68 :     datatype ea =
69 :     Direct of $GP
70 :     | FDirect of $FP
71 :     | Displace of {base: $GP, disp:operand} (* RegOp illegal as operand *)
72 :    
73 :     (* Load/store operators that have the E suffix means that 64-bit
74 :     * addressing is used. Note: the x suffix is implicitly added if rb is a
75 :     * register.
76 :     *
77 :     * -- Allen
78 :     *)
79 :    
80 :    
81 :     datatype load! = LBZ (* load byte and zero *)
82 :     | LBZE
83 :     | LHZ (* load half word and zero *)
84 :     | LHZE
85 :     | LHA (* load half word algebraic *)
86 :     | LHAE
87 :     | LWZ (* load word and zero *)
88 :     | LWZE
89 :     | LDE (* load double word extended
90 :     * Note: there is no LD or LDX!!!
91 :     *)
92 :    
93 :     datatype store! = STB
94 :     | STBE
95 :     | STH
96 :     | STHE
97 :     | STW
98 :     | STWE
99 :     | STDE
100 :    
101 :     datatype fload! = LFS
102 :     | LFSE
103 :     | LFD
104 :     | LFDE
105 :    
106 :     datatype fstore! = STFS
107 :     | STFSE
108 :     | STFD
109 :     | STFDE
110 :    
111 :     datatype cmp! = CMP | CMPL
112 :    
113 :     datatype fcmp! = FCMPO 0w32 (* ordered *)
114 :     | FCMPU 0w0 (* unordered *)
115 :    
116 :     (* xo *)
117 :     datatype unary! = NEG 0w104
118 :     | EXTSB 0w954 (* extend sign byte *)
119 :     | EXTSH 0w922 (* extend sign halfword *)
120 :     | EXTSW 0w986 (* extend sign word *)
121 :     | CNTLZW 0w26 (* count leading zeros word *)
122 :     | CNTLZD 0w58 (* count leading zeros double word *)
123 :    
124 :    
125 :     (* opcd/xo *)
126 :     datatype funary! = FMR (0w63,0w72)
127 :     | FNEG (0w63,0w40)
128 :     | FABS (0w63,0w264)
129 :     | FNABS (0w63,0w136)
130 :     | FSQRT (0w63,0w22)
131 :     | FSQRTS (0w59,0w22)
132 :     | FRSP (0w63,0w12) (* round to single precision *)
133 :     | FCTIW (0w63,0w14) (* convert to integer word *)
134 :     | FCTIWZ (0w63,0w15) (* convert to integer word *)
135 :     | FCTID (0w63,0w814) (* convert to double word *)
136 :     | FCTIDZ (0w63,0w815) (* convert to double word *)
137 :     | FCFID (0w63,0w846) (* convert from double word *)
138 :    
139 :     (* opcd/xo *)
140 :     datatype farith! = FADD (0w63,0w21)
141 :     | FSUB (0w63,0w20)
142 :     | FMUL (0w63,0w25)
143 :     | FDIV (0w63,0w18)
144 :     | FADDS (0w59,0w21)
145 :     | FSUBS (0w59,0w20)
146 :     | FMULS (0w59,0w25)
147 :     | FDIVS (0w59,0w18)
148 :    
149 :     (* opcd, xo *)
150 :     datatype farith3! = FMADD (0w63,0w29)
151 :     | FMADDS (0w59,0w29)
152 :     | FMSUB (0w63,0w28)
153 :     | FMSUBS (0w59,0w28)
154 :     | FNMADD (0w63,0w31)
155 :     | FNMADDS (0w59,0w31)
156 :     | FNMSUB (0w63,0w30)
157 :     | FNMSUBS (0w59,0w30)
158 :     | FSEL (0w63,0w23) (* floating point select *)
159 :    
160 :     datatype bo =
161 :     TRUE 0wb01100 (* 011zy *)
162 :     | FALSE 0wb00100 (* 001zy *)
163 :     | ALWAYS 0wb10100 (* 1z1zz *)
164 :     | COUNTER of {eqZero:bool, cond:bool option}
165 :     (case cond of
166 :     NONE => if eqZero then 0wb10010 (* 1z01y *)
167 :     else 0wb10000 (* 1z00y *)
168 :     | SOME cc => case (eqZero,cc) of
169 :     (false,false) => 0wb00000 (* 0000y *)
170 :     | (false,true) => 0wb01000 (* 0100y *)
171 :     | (true,false) => 0wb00010 (* 0001y *)
172 :     | (true,true) => 0wb01010 (* 0101y *)
173 :     )
174 :    
175 :     (* operation ARITH ARITHI *)
176 :     datatype arith! = (* --------- ----- ------ *)
177 :     (* xo *)
178 :     ADD 0w266 (* add add addi *)
179 :     | SUBF 0w40 (* subtract from subf subfic *)
180 :     | MULLW 0w235 (* multiply mullw mulli *)
181 :     | MULLD 0w233 (* multiply double word mulld - *)
182 :     | MULHW 0w75 (* multiply high word mulhw - *)
183 :     | MULHWU 0w11 (* multiply high word unsigned mulhwu - *)
184 :     | DIVW 0w491 (* divide word divw - *)
185 :     | DIVD 0w489 (* divide doubleword divd - *)
186 :     | DIVWU 0w459 (* divide word unsigned divwu - *)
187 :     | DIVDU 0w457 (* divide doubleword unsigned divdu - *)
188 :     | AND 0w28 (* and and andi *)
189 :     | OR 0w444 (* or or ori *)
190 :     | XOR 0w316 (* xor xor xori *)
191 :     | NAND 0w476 (* nand *)
192 :     | NOR 0w124 (* nor *)
193 :     | EQV 0w284 (* eqv *)
194 :     | ANDC 0w60 (* and with complement andc - *)
195 :     | ORC 0w412 (* or with complement orc - *)
196 :     | SLW 0w24 (* shift left word slw rlwinm *)
197 :     | SLD 0w27 (* shift left double word sld rldinm *)
198 :     | SRW 0w536 (* shift right word srw rlwinm *)
199 :     | SRD 0w539 (* shift right double word srd rldinm *)
200 :     | SRAW 0w792 (* shift right algebraic word sraw srawi *)
201 :     | SRAD 0w794 (* shift right algebraic dword srad sradi *)
202 :    
203 :     datatype arithi! = (* --------- ----- ------ *)
204 :     (* opcd *)
205 :     ADDI 0w14 (* add add addi *)
206 :     | ADDIS 0w15 (* add-shifted - addis *)
207 :     | SUBFIC 0w8 (* subtract from subf subfic *)
208 :     | MULLI 0w7 (* multiply mullw mulli *)
209 :     | ANDI_Rc "andi." 0w28 (* and and andi *)
210 :     | ANDIS_Rc "andis." 0w29(* and-shifted - andis *)
211 :     | ORI 0w24 (* or or ori *)
212 :     | ORIS 0w25 (* or-shifted - ori *)
213 :     | XORI 0w26 (* xor xor xori *)
214 :     | XORIS 0w27 (* xor-shifted - xoris *)
215 :     (*
216 :     | SLWI (* !!! *) (* shift left word slw rlwinm *)
217 :     | SLDI (* !!! *) (* shift left double word sld rldinm *)
218 :     | SRWI (* !!! *) (* shift right word srw rlwinm *)
219 :     | SRDI (* !!! *) (* shift right double word srd rldinm *)
220 :     *)
221 :     | SRAWI (* shift right algebric word sraw srawi *)
222 :     | SRADI (* shift right algebraic dword srad sradi *)
223 :    
224 :     (* !!! means that these are pseudo ops! *)
225 :    
226 :     datatype rotate! =
227 :     (* opcd *)
228 :     RLWNM (* rotate left word AND mask rlwnm rlwinm *)
229 :     | RLDCL
230 :     | RLDCR
231 :    
232 :     datatype rotatei! =
233 :     RLWINM (* rotate left word AND mask rlwnm rlwinm *)
234 :     | RLWIMI
235 :     | RLDICL
236 :     | RLDICR
237 :     | RLDIC
238 :     | RLDIMI
239 :    
240 :     datatype ccarith! = (* page 47-49 *)
241 :     (* xo *)
242 :     CRAND 0w257 (* cond. reg. AND *)
243 :     | CROR 0w449 (* cond. reg. OR *)
244 :     | CRXOR 0w193 (* cond. reg. XOR *)
245 :     | CRNAND 0w225 (* cond. reg. NAND *)
246 :     | CRNOR 0w33 (* cond. reg. NOR *)
247 :     | CREQV 0w289 (* cond. reg. EQV *)
248 :     | CRANDC 0w129 (* cond. reg. AND with complement *)
249 :     | CRORC 0w417 (* cond. reg. OR with complement *)
250 :    
251 :    
252 :     (* bits in condition code *)
253 :     datatype bit! =
254 :     LT "lt" | GT "gt" | EQ "eq" | SO "so" (* cr0 *)
255 :     | FL "lt" | FG "gt" | FE "eq" | FU "un" (* cr1 *)
256 :     (* Lal: as far as I can tell there don't seem to be mnemonics
257 :     * for these, however using lt, gt, eq, so should fool
258 :     * the assembler into looking at the right bits in the
259 :     * cc field. Of course the bf field had better be cr1.
260 :     *)
261 :     | FX "lt" | FEX "gt" | VX "eq" | OX "so"
262 :    
263 :     (* bits in integer exception register *)
264 :     datatype xerbit = SO64 (* summary overflow 64 *)
265 :     | OV64 (* overflow 64 *)
266 :     | CA64 (* carry 64 *)
267 :     | SO32 (* summary overflow 32 bits *)
268 :     | OV32 (* overflow 32 bits *)
269 :     | CA32 (* carry 32 bits *)
270 :    
271 :     type cr_bit = $CC * bit
272 :     end (* Instruction *)
273 :    
274 :     (*
275 :     * The following describes the encoding of the instructions.
276 :     *)
277 :     instruction formats 32 bits
278 :    
279 :     (* primitives *)
280 :     x_form{opcd:6,rt:5,ra:5,rb:5,xo:10,rc:bool 1}
281 :     | xl_form{opcd:6,bt:5,ba:5,bb:5,xo:10,lk:bool 1}
282 :     | m_form{opcd:6,rs:5,ra:5,rb:5,mb:5,me:5,rc:bool 1}
283 :     | a_form{opcd:6,frt:5,fra:5,frb:5,frc:5,xo:5,rc:bool 1}
284 :    
285 :     (* integer loads *)
286 :     | loadx{opcd:6=31,rt:GP 5,ra:GP 5,rb:GP 5,xop:10,rc:1=0}
287 :     | loadd{opcd:6,rt:GP 5,ra:GP 5,d:operand signed 16}
288 :     | loadde{opcd:6,rt:GP 5,ra:GP 5,de:operand signed 12,xop:4}
289 :    
290 :     | load{ld,rt,ra,d} =
291 :     (case (d,ld) of
292 :     (I.RegOp rb,I.LBZ) => loadx{rt,ra,rb,xop=0w87} (* lbzx *)
293 :     | (I.RegOp rb,I.LBZE) => loadx{rt,ra,rb,xop=0w95} (* lbzxe *)
294 :     | (I.RegOp rb,I.LHZ) => loadx{rt,ra,rb,xop=0w279} (* lhzx *)
295 :     | (I.RegOp rb,I.LHZE) => loadx{rt,ra,rb,xop=0w287} (* lhzxe *)
296 :     | (I.RegOp rb,I.LHA) => loadx{rt,ra,rb,xop=0w343} (* lhax *)
297 :     | (I.RegOp rb,I.LHAE) => loadx{rt,ra,rb,xop=0w351} (* lhaxe *)
298 :     | (I.RegOp rb,I.LWZ) => loadx{rt,ra,rb,xop=0w23} (* lwzx *)
299 :     | (I.RegOp rb,I.LWZE) => loadx{rt,ra,rb,xop=0w31} (* lwzxe *)
300 :     | (I.RegOp rb,I.LDE) => loadx{rt,ra,rb,xop=0w799} (* ldxe *)
301 :     | (d,I.LBZ) => loadd{opcd=0w34,rt,ra,d}
302 :     | (de,I.LBZE) => loadde{opcd=0w58,rt,ra,de,xop=0w0}
303 :     | (d,I.LHZ) => loadd{opcd=0w40,rt,ra,d}
304 :     | (de,I.LHZE) => loadde{opcd=0w58,rt,ra,de,xop=0w2}
305 :     | (d,I.LHA) => loadd{opcd=0w42,rt,ra,d}
306 :     | (de,I.LHAE) => loadde{opcd=0w58,rt,ra,de,xop=0w4}
307 :     | (d,I.LWZ) => loadd{opcd=0w32,rt,ra,d}
308 :     | (de,I.LWZE) => loadde{opcd=0w58,rt,ra,de,xop=0w6}
309 :     | (de,I.LDE) => loadde{opcd=0w62,rt,ra,de,xop=0w0}
310 :     )
311 :    
312 :     (* floating point loads *)
313 :     | floadx{opcd:6=31,ft:FP 5,ra:GP 5,rb:GP 5,xop:10,rc:1=0}
314 :     | floadd{opcd:6,ft:FP 5,ra:GP 5,d:operand signed 16}
315 :     | floadde{opcd:6,ft:FP 5,ra:GP 5,de:operand signed 12,xop:4}
316 :    
317 :     | fload{ld,ft,ra,d} =
318 :     (case (d,ld) of
319 :     (I.RegOp rb,I.LFS) => floadx{ft,ra,rb,xop=0w535}
320 :     | (I.RegOp rb,I.LFSE) => floadx{ft,ra,rb,xop=0w543}
321 :     | (I.RegOp rb,I.LFD) => floadx{ft,ra,rb,xop=0w599}
322 :     | (I.RegOp rb,I.LFDE) => floadx{ft,ra,rb,xop=0w607}
323 :     | (d,I.LFS) => floadd{ft,ra,d,opcd=0w48}
324 :     | (de,I.LFSE) => floadde{ft,ra,de,opcd=0w62,xop=0w4}
325 :     | (d,I.LFD) => floadd{ft,ra,d,opcd=0w50}
326 :     | (de,I.LFDE) => floadde{ft,ra,de,opcd=0w62,xop=0w6}
327 :     )
328 :    
329 :     (* integer stores *)
330 :     | storex{opcd:6=31,rs:GP 5,ra:GP 5,rb:GP 5,xop:10,rc:1=0}
331 :     | stored{opcd:6,rs:GP 5,ra:GP 5,d:operand signed 16}
332 :     | storede{opcd:6,rs:GP 5,ra:GP 5,de:operand signed 12,xop:4}
333 :    
334 :     | store{st,rs,ra,d} =
335 :     (case (d,st) of
336 :     (I.RegOp rb,I.STB) => storex{rs,ra,rb,xop=0w215}
337 :     | (I.RegOp rb,I.STBE) => storex{rs,ra,rb,xop=0w223}
338 :     | (I.RegOp rb,I.STH) => storex{rs,ra,rb,xop=0w407}
339 :     | (I.RegOp rb,I.STHE) => storex{rs,ra,rb,xop=0w415}
340 :     | (I.RegOp rb,I.STW) => storex{rs,ra,rb,xop=0w151}
341 :     | (I.RegOp rb,I.STWE) => storex{rs,ra,rb,xop=0w159}
342 :     | (I.RegOp rb,I.STDE) => storex{rs,ra,rb,xop=0w927}
343 :     | (d,I.STB) => stored{rs,ra,d,opcd=0w38}
344 :     | (de,I.STBE) => storede{rs,ra,de,opcd=0w58,xop=0w8}
345 :     | (d,I.STH) => stored{rs,ra,d,opcd=0w44}
346 :     | (de,I.STHE) => storede{rs,ra,de,opcd=0w58,xop=0w10}
347 :     | (d,I.STW) => stored{rs,ra,d,opcd=0w36}
348 :     | (de,I.STWE) => storede{rs,ra,de,opcd=0w58,xop=0w14}
349 :     | (de,I.STDE) => storede{rs,ra,de,opcd=0w62,xop=0w8}
350 :     )
351 :    
352 :     (* floating point stores *)
353 :     | fstorex{opcd:6=31,fs:FP 5,ra:GP 5,rb:GP 5,xop:10,rc:1=0}
354 :     | fstored{opcd:6,fs:FP 5,ra:GP 5,d:operand signed 16}
355 :     | fstorede{opcd:6,fs:FP 5,ra:GP 5,de:operand signed 12,xop:4}
356 :    
357 :     | fstore{st,fs,ra,d} =
358 :     (case (d,st) of
359 :     (I.RegOp rb,I.STFS) => fstorex{fs,ra,rb,xop=0w663}
360 :     | (I.RegOp rb,I.STFSE) => fstorex{fs,ra,rb,xop=0w671}
361 :     | (I.RegOp rb,I.STFD) => fstorex{fs,ra,rb,xop=0w727}
362 :     | (I.RegOp rb,I.STFDE) => fstorex{fs,ra,rb,xop=0w759}
363 :     | (d,I.STFS) => fstored{fs,ra,d,opcd=0w52}
364 :     | (de,I.STFSE) => fstorede{fs,ra,de,opcd=0w62,xop=0w12}
365 :     | (d,I.STFD) => fstored{fs,ra,d,opcd=0w54}
366 :     | (de,I.STFDE) => fstorede{fs,ra,de,opcd=0w62,xop=0w14}
367 :     )
368 :    
369 :     (* integer arithmetic *)
370 :     | unary'{opcd:6=31,ra:GP 5,rt:GP 5,_:5=0,OE:bool 1,oper:unary 9,Rc:bool 1}
371 :     | unary{ra,rt,oper,OE,Rc} =
372 :     (case oper of
373 :     I.NEG => unary'{ra=rt,rt=ra,oper,OE,Rc} (* swapped! *)
374 :     | _ => unary'{ra,rt,oper,OE,Rc}
375 :     )
376 :     | arith'{opcd:6=31,rt:GP 5,ra:GP 5,rb:GP 5,OE:bool 1,oper:arith 9,Rc:bool 1}
377 :     | arithi'{oper:arithi 6,rt:GP 5,ra:GP 5,im:operand signed 16}
378 :     | srawi{opcd:6=31,rs:GP 5,ra:GP 5,sh:operand signed 5,xop:10=824,Rc:1=0}
379 :     | sradi'{opcd:6=31,rs:GP 5,ra:GP 5,sh:5,xop:9=0w413,sh2:1,Rc:1=0}
380 :     | sradi{rs,ra,sh:operand signed 6} =
381 :     sradi'{rs=rs,ra=ra,sh=(sh at [0..4]),sh2=sh at [5]}
382 :    
383 :     | arith{oper,rt,ra,rb,OE,Rc} =
384 :     (case oper of
385 :     (I.ADD | I.SUBF | I.MULLW | I.MULLD | I.MULHW | I.MULHWU |
386 :     I.DIVW | I.DIVD | I.DIVWU | I.DIVDU) =>
387 :     arith'{oper,rt,ra,rb,OE,Rc}
388 :     (* For some unknown reasons, the encoding of rt and ra
389 :     * are swapped!
390 :     *)
391 :     | _ => arith'{oper,rt=ra,ra=rt,rb,OE,Rc}
392 :     )
393 :    
394 :     | arithi{oper,rt,ra,im} =
395 :     (case oper of
396 :     (I.ADDI | I.ADDIS | I.SUBFIC | I.MULLI) => arithi'{oper,rt,ra,im}
397 :     | I.SRAWI => srawi{rs=ra,ra=rt,sh=im}
398 :     | I.SRADI => sradi{rs=ra,ra=rt,sh=im}
399 :     (* For some unknown reasons, the encoding of rt and ra
400 :     * are swapped!
401 :     *)
402 :     | _ => arithi'{oper,rt=ra,ra=rt,im}
403 :     )
404 :    
405 :     (* integer compare *)
406 :     | Cmpl{opcd:6=31,bf:CC 3,_:1=0,l:bool 1,ra:GP 5,rb:GP 5,xo:10=32,_:1=0}
407 :     | Cmpli{opcd:6=10,bf:CC 3,_:1=0,l:bool 1,ra:GP 5,ui:operand signed 16}
408 :     | Cmp{opcd:6=31,bf:CC 3,_:1=0,l:bool 1,ra:GP 5,rb:GP 5,xo:10=0,_:1=0}
409 :     | Cmpi{opcd:6=11,bf:CC 3,_:1=0,l:bool 1,ra:GP 5,si:operand signed 16}
410 :     | compare{cmp,bf,l,ra,rb} =
411 :     (case (cmp,rb) of
412 :     (I.CMP,I.RegOp rb) => Cmp{bf,l,ra,rb}
413 :     | (I.CMPL,I.RegOp rb) => Cmpl{bf,l,ra,rb}
414 :     | (I.CMP,si) => Cmpi{bf,l,ra,si}
415 :     | (I.CMPL,ui) => Cmpli{bf,l,ra,ui}
416 :     )
417 :    
418 :     (* floating point compare *)
419 :     | fcmp{opcd:6=63,bf:CC 3,_:2=0,fa:FP 5,fb:FP 5,cmp:fcmp 10,_:1=0}
420 :    
421 :     (* floating point unary *)
422 :     | funary{oper:funary,ft:FP,fb:FP,Rc} =
423 :     let val (opcd,xo) = oper
424 :     in x_form{opcd=opcd,rt=ft,ra=0w0,rb=fb,xo=xo,rc=Rc}
425 :     end
426 :    
427 :     (* floating point binary *)
428 :     | farith{oper,ft:FP,fa:FP,fb:FP,Rc} =
429 :     let val (opcd,xo) = emit_farith oper
430 :     in case oper of
431 :     (I.FMUL | I.FMULS) =>
432 :     a_form{opcd=opcd,frt=ft,fra=fa,frb=0w0,frc=fb,xo=xo,rc=Rc}
433 :     | _ => a_form{opcd=opcd,frt=ft,fra=fa,frb=fb,frc=0w0,xo=xo,rc=Rc}
434 :     end
435 :    
436 :     (* floating point ternary *)
437 :     | farith3{oper:farith3,ft:FP,fa:FP,fc:FP,fb:FP,Rc} =
438 :     let val (opcd,xo) = oper
439 :     in a_form{opcd=opcd,frt=ft,fra=fa,frb=fb,frc=fc,xo=xo,rc=Rc}
440 :     end
441 :    
442 :     | cr_bit{cc} =
443 :     let val (cr,bit) = cc
444 :     in (emit_CC cr << 0w2) +
445 :     itow(
446 :     case bit of
447 :     I.LT => 0 | I.GT => 1 | I.EQ => 2 | I.SO => 3
448 :     | I.FL => 0 | I.FG => 1 | I.FE => 2 | I.FU => 3
449 :     | I.FX => 0 | I.FEX => 1 | I.VX => 2 | I.OX => 3
450 :     )
451 :     end
452 :    
453 :     | ccarith{oper:ccarith,bt,ba,bb} =
454 :     xl_form{opcd=0w19,bt=cr_bit{cc=bt},ba=cr_bit{cc=ba},bb=cr_bit{cc=bb},
455 :     xo=oper,lk=false}
456 :    
457 :     (* trap on word *)
458 :     | twr{opcd:6=31,to:int 5,ra:GP 5,rb:GP 5,xop:10=4,_:1=0}
459 :     | twi{opcd:6=3,to:int 5,ra:GP 5,si:operand signed 16}
460 :     | tw{to,ra,si} =
461 :     (case si of I.RegOp rb => twr{to,ra,rb} | _ => twi{to,ra,si})
462 :    
463 :     (* trap on double word *)
464 :     | tdr{opcd:6=31,to:int 5,ra:GP 5,rb:GP 5,xop:10=68,_:1=0}
465 :     | tdi{opcd:6=2,to:int 5,ra:GP 5,si:operand signed 16}
466 :     | td{to,ra,si} =
467 :     (case si of I.RegOp rb => tdr{to,ra,rb} | _ => tdi{to,ra,si})
468 :    
469 :     (* move condition field p49 *)
470 :     | mcrf{opcd:6=19,bf:CC 3,_:2=0,bfa:CC 3,_:18=0}
471 :    
472 :     (* move from/to special purpose register p131/132
473 :     * the encoding of spr = spr[0..4] || spr[5..9]
474 :     *)
475 :     | mtspr'{opcd:6=31,rs:GP 5,spr:10,xop:10=467,_:1=0}
476 :     | mtspr{rs,spr:SPR} =
477 :     mtspr'{rs,spr=((spr at [0..4]) << 0w5) + (spr at [5..9])}
478 :     | mfspr'{opcd:6=31,rt:GP 5,spr:10,xop:10=339,_:1=0}
479 :     | mfspr{rt,spr:SPR} =
480 :     mfspr'{rt,spr=((spr at [0..4]) << 0w5) + (spr at [5..9])}
481 :    
482 :     (* Branch p41 *)
483 :     | b{opcd:6=18,li:signed 24,aa:bool 1,lk:bool 1}
484 :     | be{opcd:6=22,li:signed 24,aa:bool 1,lk:bool 1}
485 :    
486 :     (* Branch conditional p42 *)
487 :     | bc{opcd:6=16,bo:bo 5,bi:5,bd:signed 14,aa:bool 1,lk:bool 1}
488 :     | bce{opcd:6=16,bo:bo 5,bi:5,bd:signed 14,aa:bool 1,lk:bool 1}
489 :    
490 :     (* Branch conditional to link register *)
491 :     | bclr{opcd:6=19,bo:bo 5,bi:5,_:5=0,xop:10=16,lk:bool 1}
492 :     | bclre{opcd:6=19,bo:bo 5,bi:5,_:5=0,xop:10=17,lk:bool 1}
493 :    
494 :     (* Branch conditional to count register *)
495 :     | bcctr{opcd:6=19,bo:bo 5,bi:5,_:5=0,xop:10=528,lk:bool 1}
496 :     | bcctre{opcd:6=19,bo:bo 5,bi:5,_:5=0,xop:10=529,lk:bool 1}
497 :    
498 :     (* Rotate *)
499 :     | rlwnm{oper:6=23,rs:GP 5,ra:GP 5,sh:GP 5,mb:int 5,me:int 5,Rc:1=0}
500 :     | rlwinm{oper:6=21,rs:GP 5,ra:GP 5,sh:5,mb:int 5,me:int 5,Rc:1=0}
501 :     | rldcl{oper:6=30,rs:GP 5,ra:GP 5,sh:GP 5,mb:int 5,_:5=8,Rc:1=0}
502 :     | rldicl{oper:6=30,rs:GP 5,ra:GP 5,sh:5,mb:int 5,_:4=0,sh2:1,Rc:1=0}
503 :     | rldcr{oper:6=30,rs:GP 5,ra:GP 5,sh:GP 5,mb:int 5,_:5=9,Rc:1=0}
504 :     | rldicr{oper:6=30,rs:GP 5,ra:GP 5,sh:5,mb:int 5,_:4=1,sh2:1,Rc:1=0}
505 :     | rldic{oper:6=30,rs:GP 5,ra:GP 5,sh:5,mb:int 5,_:4=2,sh2:1,Rc:1=0}
506 :     | rlwimi{oper:6=20,rs:GP 5,ra:GP 5,sh:5,mb:int 5,me:int 5,Rc:1=0}
507 :     | rldimi{oper:6=30,rs:GP 5,ra:GP 5,sh:5,mb:int 5,_:4=3,sh2:1,Rc:1=0}
508 :    
509 :     | rotate{oper,ra,rs,sh,mb,me} =
510 :     (case (oper,me) of
511 :     (I.RLWNM,SOME me) => rlwnm{ra,rs,sh,mb,me}
512 :     | (I.RLDCL,_) => rldcl{ra,rs,sh,mb}
513 :     | (I.RLDCR,_) => rldcr{ra,rs,sh,mb}
514 :     )
515 :     | rotatei{oper,ra,rs,sh:operand,mb,me} =
516 :     (case (oper,me) of
517 :     (I.RLWINM,SOME me) => rlwinm{ra,rs,sh,mb,me}
518 :     | (I.RLWIMI,SOME me) => rlwimi{ra,rs,sh=sh,mb,me}
519 :     | (I.RLDICL,_) => rldicl{ra,rs,sh=sh at [0..4],sh2=sh at [5],mb}
520 :     | (I.RLDICR,_) => rldicr{ra,rs,sh=sh at [0..4],sh2=sh at [5],mb}
521 :     | (I.RLDIC,_) => rldic{ra,rs,sh=sh at [0..4],sh2=sh at [5],mb}
522 :     | (I.RLDIMI,_) => rldimi{ra,rs,sh=sh at [0..4],sh2=sh at [5],mb}
523 :     )
524 :    
525 :    
526 :    
527 :     (*
528 :     * Some helper functions for generating machine code.
529 :     * These are copied from Lal's code.
530 :     *)
531 :     structure MC =
532 :     struct
533 :     fun relative(I.LabelOp lexp) = itow(LabelExp.valueOf lexp - !loc) ~>> 0w2
534 :     | relative _ = error "relative"
535 :     end
536 :    
537 :     (*
538 :     * Reservation tables and pipeline definitions for scheduling
539 :     *)
540 :    
541 :     (* Function units *)
542 :     resource issue and mem and alu and falu and fmul and fdiv and branch
543 :    
544 :     (* Different implementations of cpus *)
545 :     cpu default 2 [2 issue, 2 mem, 1 alu] (* 2 issue machine *)
546 :    
547 :     (* Definitions of various reservation tables *)
548 :     pipeline NOP _ = [issue]
549 :     and ARITH _ = [issue^^alu]
550 :     and LOAD _ = [issue^^mem]
551 :     and STORE _ = [issue^^mem,mem,mem]
552 :     and FARITH _ = [issue^^falu]
553 :     and FMUL _ = [issue^^fmul,fmul]
554 :     and FDIV _ = [issue^^fdiv,fdiv*50]
555 :     and BRANCH _ = [issue^^branch]
556 :    
557 :     (*
558 :     * Some helper functions for generating assembly code.
559 :     *)
560 :     structure Assembly =
561 :     struct
562 :     (* Add the x suffix if necessary; this is a stupid hack *)
563 :     fun emitx(s,I.RegOp _) =
564 :     if String.sub(s,size s-1) = #"e" then
565 :     (emit(String.substring(s,0,size s-1)); emit "xe")
566 :     else (emit(s); emit "x")
567 :     | emitx(s,_) = emit s
568 :    
569 :     fun eOERc{OE=false,Rc=false} = ()
570 :     | eOERc{OE=false,Rc=true} = emit "."
571 :     | eOERc{OE=true,Rc=false} = emit "o"
572 :     | eOERc{OE=true,Rc=true} = emit "o."
573 :     fun eRc false = "" | eRc true = "."
574 :     fun cr_bit(cr,bit) =
575 :     4 * (C.physicalRegisterNum cr) +
576 :     (case bit of
577 :     I.LT => 0 | I.GT => 1 | I.EQ => 2 | I.SO => 3
578 :     | I.FL => 0 | I.FG => 1 | I.FE => 2 | I.FU => 3
579 :     | I.FX => 0 | I.FEX => 1 | I.VX => 2 | I.OX => 3
580 :     )
581 :     fun eCRbit x = emit(Int.toString(cr_bit x))
582 :     fun eLK true = emit "l" | eLK false = ()
583 :     fun eI (I.RegOp _) = () | eI _ = emit "i"
584 :     fun eBI(bo, bf, bit) =
585 :     case (bo, C.physicalRegisterNum bf) of
586 :     (I.ALWAYS, _) => ()
587 :     | (I.COUNTER{cond=NONE, ...}, _) => ()
588 :     | (_,0) => emit(asm_bit bit)
589 :     | (_,n) => emit("4*cr" ^ Int.toString n ^ "+" ^ asm_bit bit)
590 :     fun emit_bo bo =
591 :     emit(case bo
592 :     of I.TRUE => "t"
593 :     | I.FALSE => "f"
594 :     | I.ALWAYS => ""
595 :     | I.COUNTER{eqZero, cond=NONE} => if eqZero then "dz" else "dnz"
596 :     | I.COUNTER{eqZero, cond=SOME cc} =>
597 :     (if eqZero then "dz" else "dnz") ^
598 :     (if cc then "t" else "f")
599 :     (*esac*))
600 :    
601 :     fun eME(SOME me) = (emit ", "; emit_int me)
602 :     | eME(NONE) = ()
603 :    
604 :     fun addr(ra,I.RegOp rb) = (emitCell ra; emit ", "; emitCell rb)
605 :     | addr(ra,d) = (emit_operand d; emit "("; emitCell ra; emit ")")
606 :    
607 :     end (* Assembly *)
608 :    
609 :     instruction
610 :     L of {ld:load, rt: $GP, ra: $GP, d:operand, mem:Region.region}
611 :     ``<emitx(asm_load ld,d)>\t<rt>, <addr(ra,d)><mem>''
612 :     load{ld,rt,ra,d}
613 :    
614 :     | LF of {ld:fload, ft: $FP, ra: $GP, d:operand, mem:Region.region}
615 :     ``<emitx(asm_fload ld,d)>\t<ft>, <addr(ra,d)><mem>''
616 :     fload{ld,ft,ra,d}
617 :    
618 :     | ST of {st:store, rs: $GP, ra: $GP, d:operand, mem:Region.region}
619 :     ``<emitx(asm_store st,d)>\t<rs>, <addr(ra,d)><mem>''
620 :     store{st,rs,ra,d}
621 :    
622 :     | STF of {st:fstore, fs: $FP, ra: $GP, d:operand, mem:Region.region}
623 :     ``<emitx(asm_fstore st,d)>\t<fs>, <addr(ra,d)><mem>''
624 :     fstore{st,fs,ra,d}
625 :    
626 :     | UNARY of {oper:unary, rt: $GP, ra: $GP, Rc:bool, OE:bool}
627 :     ``<oper><eOERc{Rc,OE}>\t<rt>, <ra>''
628 :     unary{oper,rt,ra,OE,Rc}
629 :    
630 :     | ARITH of {oper:arith, rt: $GP, ra: $GP, rb: $GP, Rc:bool, OE:bool}
631 :     ``<oper><eOERc{Rc,OE}>\t<rt>, <ra>, <rb>''
632 :     arith{oper,rt,ra,rb,OE,Rc}
633 :    
634 :     | ARITHI of {oper:arithi, rt: $GP, ra: $GP, im:operand}
635 :     ``<oper>\t<rt>, <ra>, <im>''
636 :     arithi{oper,rt,ra,im}
637 :    
638 :     | ROTATE of {oper:rotate, ra: $GP, rs: $GP, sh: $GP, mb:int, me:int option}
639 :     ``<oper>\t<ra>, <rs>, <sh>, <mb><eME me>''
640 :     rotate{oper,ra,rs,sh,mb,me}
641 :    
642 :     | ROTATEI of {oper:rotatei, ra: $GP, rs: $GP, sh:operand, mb:int, me:int option}
643 :     ``<oper>\t<ra>, <rs>, <sh>, <mb><eME me>''
644 :     rotatei{oper,ra,rs,sh,mb,me}
645 :    
646 :     | COMPARE of {cmp:cmp, l:bool, bf: $CC, ra: $GP, rb:operand}
647 :     ``<cmp><eI rb>\t<bf>, <emit(if l then "1" else "0")>, <ra>, <rb>''
648 :     compare{cmp,bf,l,ra,rb}
649 :    
650 :     | FCOMPARE of {cmp:fcmp, bf: $CC, fa: $FP, fb: $FP}
651 :     ``<cmp>\t<bf>, <fa>, <fb>''
652 :     fcmp{cmp,bf,fa,fb}
653 :    
654 :     | FUNARY of {oper:funary, ft: $FP, fb: $FP, Rc:bool}
655 :     ``<oper><eRc Rc>\t<ft>, <fb>''
656 :     funary{oper,ft,fb,Rc}
657 :    
658 :     | FARITH of {oper:farith, ft: $FP, fa: $FP, fb: $FP, Rc:bool}
659 :     ``<oper><eRc Rc>\t<ft>, <fa>, <fb>''
660 :     farith{oper,ft,fa,fb,Rc}
661 :    
662 :     | FARITH3 of {oper:farith3, ft: $FP, fa: $FP, fb: $FP, fc: $FP, Rc:bool}
663 :     ``<oper><eRc Rc>\t<ft>, <fa>, <fb>, <fc>''
664 :     farith3{oper,ft,fa,fb,fc,Rc}
665 :    
666 :     | CCARITH of {oper:ccarith, bt:cr_bit, ba:cr_bit, bb:cr_bit}
667 :     ``<oper>\t<eCRbit bt>, <eCRbit ba>, <eCRbit bb>''
668 :     ccarith{oper,bt,ba,bb}
669 :    
670 :     | MCRF of {bf: $CC, bfa: $CC} (* move condition register field p49 *)
671 :     ``mcrf\t<bf>, <bfa>''
672 :     mcrf{bf,bfa}
673 :    
674 :     (* move to special register p131 *)
675 :     | MTSPR of {rs: $GP, spr: $SPR}
676 :     ``mt<spr>\t<rs>''
677 :     mtspr{rs,spr}
678 :    
679 :     (* move from special register p132 *)
680 :     | MFSPR of {rt: $GP, spr: $SPR}
681 :     ``mf<spr>\t<rt>''
682 :     mfspr{rt,spr}
683 :    
684 :     (* Trapping word *)
685 :     | TW of {to:int, ra: $GP, si:operand}
686 :     ``tw<eI si>\t<to>, <ra>, <si>''
687 :     tw{to,ra,si}
688 :    
689 :     (* Trapping double word *)
690 :     | TD of {to:int, ra: $GP, si:operand}
691 :     ``td<eI si>\t<to>, <ra>, <si>''
692 :     td{to,ra,si}
693 :    
694 :     (* Control Instructions - AA is always assumed to be 0 *)
695 :     | BC of {bo:bo, bf: $CC, bit:bit, addr:operand, LK:bool, fall:operand}
696 :     ``b<bo><eLK LK>\t<eBI(bo,bf,bit)>, <addr>''
697 :     bc{bo,bi=cr_bit{cc=(bf,bit)},bd=relative addr,aa=false,lk=LK}
698 :    
699 :     | BCLR of {bo:bo, bf: $CC, bit:bit, LK:bool, labels:Label.label list}
700 :     ``b<bo>lr<eLK LK>\t<eBI(bo,bf,bit)>''
701 :     bclr{bo,bi=cr_bit{cc=(bf,bit)},lk=LK}
702 :    
703 :     | B of {addr:operand, LK:bool}
704 :     ``b<eLK LK>\t<addr>''
705 :     b{li=relative addr,aa=false,lk=LK}
706 :    
707 :     (* CALL = BCLR {bo=ALWAYS, bf=0, bit=0, LK=true, labels=[] *)
708 :     | CALL of {def:C.cellset, use:C.cellset, mem: Region.region}
709 :     ``blrl<mem><emit_defs(def)><emit_uses(use)>''
710 :     bclr{bo=I.ALWAYS,bi=0w0,lk=true}
711 :    
712 :     | COPY of {dst: $GP list, src: $GP list,
713 :     impl:instruction list option ref,
714 :     tmp: ea option}
715 :     asm: emitInstrs (Shuffle.shuffle{tmp,dst,src})
716 :    
717 :     | FCOPY of {dst: $FP list, src: $FP list,
718 :     impl:instruction list option ref,
719 :     tmp: ea option}
720 :     asm: emitInstrs (Shuffle.shufflefp{tmp,dst,src})
721 :    
722 :     | ANNOTATION of {i:instruction, a:Annotations.annotation}
723 :     asm: (comment(Annotations.toString a); nl(); emitInstr i)
724 :     mc: emitInstr i
725 :    
726 :     | SOURCE of {}
727 :     asm: ``source''
728 :     mc: ()
729 :    
730 :     | SINK of {}
731 :     asm: ``sink''
732 :     mc: ()
733 :    
734 :     | PHI of {}
735 :     asm: ``phi''
736 :     mc: ()
737 :    
738 :     structure SSA =
739 :     struct
740 :    
741 :     fun operand(ty, I.RegOp r) = T.REG(32, r)
742 :     | operand(ty, I.ImmedOp i) = T.LI i
743 :     (*| operand(ty, I.LabelOp le) = T.LABEL le*)
744 :    
745 :     end
746 :    
747 :     end

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