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 889 - (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 : leunga 775 | LabelOp of T.labexp ``<emit_labexp labexp>''
64 : leunga 746 (itow(LabelExp.valueOf labexp))
65 :    
66 : george 889 type addressing_mode = CellsBasis.cell * operand
67 : leunga 746
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 : leunga 815 in
425 :     case oper
426 :     of (0wx3f, 0wx16) => (* FSQRT *)
427 : george 823 a_form{opcd=opcd,frt=ft,fra=0w0,frb=fb,frc=0w0,xo=xo,rc=Rc}
428 : george 810 | (0wx3b, 0wx16) => (* FSQRTS *)
429 : george 823 a_form{opcd=opcd,frt=ft,fra=0w0,frb=fb,frc=0w0,xo=xo,rc=Rc}
430 : george 810 | _ =>
431 : leunga 815 x_form{opcd=opcd,rt=ft,ra=0w0,rb=fb,xo=xo,rc=Rc}
432 : leunga 746 end
433 :    
434 :     (* floating point binary *)
435 :     | farith{oper,ft:FP,fa:FP,fb:FP,Rc} =
436 :     let val (opcd,xo) = emit_farith oper
437 :     in case oper of
438 :     (I.FMUL | I.FMULS) =>
439 :     a_form{opcd=opcd,frt=ft,fra=fa,frb=0w0,frc=fb,xo=xo,rc=Rc}
440 :     | _ => a_form{opcd=opcd,frt=ft,fra=fa,frb=fb,frc=0w0,xo=xo,rc=Rc}
441 :     end
442 :    
443 :     (* floating point ternary *)
444 :     | farith3{oper:farith3,ft:FP,fa:FP,fc:FP,fb:FP,Rc} =
445 :     let val (opcd,xo) = oper
446 :     in a_form{opcd=opcd,frt=ft,fra=fa,frb=fb,frc=fc,xo=xo,rc=Rc}
447 :     end
448 :    
449 :     | cr_bit{cc} =
450 :     let val (cr,bit) = cc
451 :     in (emit_CC cr << 0w2) +
452 :     itow(
453 :     case bit of
454 :     I.LT => 0 | I.GT => 1 | I.EQ => 2 | I.SO => 3
455 :     | I.FL => 0 | I.FG => 1 | I.FE => 2 | I.FU => 3
456 :     | I.FX => 0 | I.FEX => 1 | I.VX => 2 | I.OX => 3
457 :     )
458 :     end
459 :    
460 :     | ccarith{oper:ccarith,bt,ba,bb} =
461 :     xl_form{opcd=0w19,bt=cr_bit{cc=bt},ba=cr_bit{cc=ba},bb=cr_bit{cc=bb},
462 :     xo=oper,lk=false}
463 :    
464 :     (* trap on word *)
465 :     | twr{opcd:6=31,to:int 5,ra:GP 5,rb:GP 5,xop:10=4,_:1=0}
466 :     | twi{opcd:6=3,to:int 5,ra:GP 5,si:operand signed 16}
467 :     | tw{to,ra,si} =
468 :     (case si of I.RegOp rb => twr{to,ra,rb} | _ => twi{to,ra,si})
469 :    
470 :     (* trap on double word *)
471 :     | tdr{opcd:6=31,to:int 5,ra:GP 5,rb:GP 5,xop:10=68,_:1=0}
472 :     | tdi{opcd:6=2,to:int 5,ra:GP 5,si:operand signed 16}
473 :     | td{to,ra,si} =
474 :     (case si of I.RegOp rb => tdr{to,ra,rb} | _ => tdi{to,ra,si})
475 :    
476 :     (* move condition field p49 *)
477 :     | mcrf{opcd:6=19,bf:CC 3,_:2=0,bfa:CC 3,_:18=0}
478 :    
479 :     (* move from/to special purpose register p131/132
480 :     * the encoding of spr = spr[0..4] || spr[5..9]
481 :     *)
482 :     | mtspr'{opcd:6=31,rs:GP 5,spr:10,xop:10=467,_:1=0}
483 :     | mtspr{rs,spr:SPR} =
484 :     mtspr'{rs,spr=((spr at [0..4]) << 0w5) + (spr at [5..9])}
485 :     | mfspr'{opcd:6=31,rt:GP 5,spr:10,xop:10=339,_:1=0}
486 :     | mfspr{rt,spr:SPR} =
487 :     mfspr'{rt,spr=((spr at [0..4]) << 0w5) + (spr at [5..9])}
488 :    
489 :     (* Branch p41 *)
490 :     | b{opcd:6=18,li:signed 24,aa:bool 1,lk:bool 1}
491 :     | be{opcd:6=22,li:signed 24,aa:bool 1,lk:bool 1}
492 :    
493 :     (* Branch conditional p42 *)
494 :     | bc{opcd:6=16,bo:bo 5,bi:5,bd:signed 14,aa:bool 1,lk:bool 1}
495 :     | bce{opcd:6=16,bo:bo 5,bi:5,bd:signed 14,aa:bool 1,lk:bool 1}
496 :    
497 :     (* Branch conditional to link register *)
498 :     | bclr{opcd:6=19,bo:bo 5,bi:5,_:5=0,xop:10=16,lk:bool 1}
499 :     | bclre{opcd:6=19,bo:bo 5,bi:5,_:5=0,xop:10=17,lk:bool 1}
500 :    
501 :     (* Branch conditional to count register *)
502 :     | bcctr{opcd:6=19,bo:bo 5,bi:5,_:5=0,xop:10=528,lk:bool 1}
503 :     | bcctre{opcd:6=19,bo:bo 5,bi:5,_:5=0,xop:10=529,lk:bool 1}
504 :    
505 :     (* Rotate *)
506 :     | rlwnm{oper:6=23,rs:GP 5,ra:GP 5,sh:GP 5,mb:int 5,me:int 5,Rc:1=0}
507 :     | rlwinm{oper:6=21,rs:GP 5,ra:GP 5,sh:5,mb:int 5,me:int 5,Rc:1=0}
508 :     | rldcl{oper:6=30,rs:GP 5,ra:GP 5,sh:GP 5,mb:int 5,_:5=8,Rc:1=0}
509 :     | rldicl{oper:6=30,rs:GP 5,ra:GP 5,sh:5,mb:int 5,_:4=0,sh2:1,Rc:1=0}
510 :     | rldcr{oper:6=30,rs:GP 5,ra:GP 5,sh:GP 5,mb:int 5,_:5=9,Rc:1=0}
511 :     | rldicr{oper:6=30,rs:GP 5,ra:GP 5,sh:5,mb:int 5,_:4=1,sh2:1,Rc:1=0}
512 :     | rldic{oper:6=30,rs:GP 5,ra:GP 5,sh:5,mb:int 5,_:4=2,sh2:1,Rc:1=0}
513 :     | rlwimi{oper:6=20,rs:GP 5,ra:GP 5,sh:5,mb:int 5,me:int 5,Rc:1=0}
514 :     | rldimi{oper:6=30,rs:GP 5,ra:GP 5,sh:5,mb:int 5,_:4=3,sh2:1,Rc:1=0}
515 :    
516 :     | rotate{oper,ra,rs,sh,mb,me} =
517 :     (case (oper,me) of
518 :     (I.RLWNM,SOME me) => rlwnm{ra,rs,sh,mb,me}
519 :     | (I.RLDCL,_) => rldcl{ra,rs,sh,mb}
520 :     | (I.RLDCR,_) => rldcr{ra,rs,sh,mb}
521 :     )
522 :     | rotatei{oper,ra,rs,sh:operand,mb,me} =
523 :     (case (oper,me) of
524 :     (I.RLWINM,SOME me) => rlwinm{ra,rs,sh,mb,me}
525 :     | (I.RLWIMI,SOME me) => rlwimi{ra,rs,sh=sh,mb,me}
526 :     | (I.RLDICL,_) => rldicl{ra,rs,sh=sh at [0..4],sh2=sh at [5],mb}
527 :     | (I.RLDICR,_) => rldicr{ra,rs,sh=sh at [0..4],sh2=sh at [5],mb}
528 :     | (I.RLDIC,_) => rldic{ra,rs,sh=sh at [0..4],sh2=sh at [5],mb}
529 :     | (I.RLDIMI,_) => rldimi{ra,rs,sh=sh at [0..4],sh2=sh at [5],mb}
530 :     )
531 :    
532 :    
533 :    
534 :     (*
535 :     * Some helper functions for generating machine code.
536 :     * These are copied from Lal's code.
537 :     *)
538 :     structure MC =
539 :     struct
540 :     fun relative(I.LabelOp lexp) = itow(LabelExp.valueOf lexp - !loc) ~>> 0w2
541 :     | relative _ = error "relative"
542 :     end
543 :    
544 :     (*
545 :     * Reservation tables and pipeline definitions for scheduling
546 :     *)
547 :    
548 :     (* Function units *)
549 :     resource issue and mem and alu and falu and fmul and fdiv and branch
550 :    
551 :     (* Different implementations of cpus *)
552 :     cpu default 2 [2 issue, 2 mem, 1 alu] (* 2 issue machine *)
553 :    
554 :     (* Definitions of various reservation tables *)
555 :     pipeline NOP _ = [issue]
556 :     and ARITH _ = [issue^^alu]
557 :     and LOAD _ = [issue^^mem]
558 :     and STORE _ = [issue^^mem,mem,mem]
559 :     and FARITH _ = [issue^^falu]
560 :     and FMUL _ = [issue^^fmul,fmul]
561 :     and FDIV _ = [issue^^fdiv,fdiv*50]
562 :     and BRANCH _ = [issue^^branch]
563 :    
564 :     (*
565 :     * Some helper functions for generating assembly code.
566 :     *)
567 :     structure Assembly =
568 :     struct
569 :     (* Add the x suffix if necessary; this is a stupid hack *)
570 :     fun emitx(s,I.RegOp _) =
571 :     if String.sub(s,size s-1) = #"e" then
572 :     (emit(String.substring(s,0,size s-1)); emit "xe")
573 :     else (emit(s); emit "x")
574 :     | emitx(s,_) = emit s
575 :    
576 :     fun eOERc{OE=false,Rc=false} = ()
577 :     | eOERc{OE=false,Rc=true} = emit "."
578 :     | eOERc{OE=true,Rc=false} = emit "o"
579 :     | eOERc{OE=true,Rc=true} = emit "o."
580 :     fun eRc false = "" | eRc true = "."
581 :     fun cr_bit(cr,bit) =
582 : george 889 4 * (CellsBasis.physicalRegisterNum cr) +
583 : leunga 746 (case bit of
584 :     I.LT => 0 | I.GT => 1 | I.EQ => 2 | I.SO => 3
585 :     | I.FL => 0 | I.FG => 1 | I.FE => 2 | I.FU => 3
586 :     | I.FX => 0 | I.FEX => 1 | I.VX => 2 | I.OX => 3
587 :     )
588 :     fun eCRbit x = emit(Int.toString(cr_bit x))
589 :     fun eLK true = emit "l" | eLK false = ()
590 :     fun eI (I.RegOp _) = () | eI _ = emit "i"
591 :     fun eBI(bo, bf, bit) =
592 : george 889 case (bo, CellsBasis.physicalRegisterNum bf) of
593 : leunga 746 (I.ALWAYS, _) => ()
594 :     | (I.COUNTER{cond=NONE, ...}, _) => ()
595 :     | (_,0) => emit(asm_bit bit)
596 :     | (_,n) => emit("4*cr" ^ Int.toString n ^ "+" ^ asm_bit bit)
597 :     fun emit_bo bo =
598 :     emit(case bo
599 :     of I.TRUE => "t"
600 :     | I.FALSE => "f"
601 :     | I.ALWAYS => ""
602 :     | I.COUNTER{eqZero, cond=NONE} => if eqZero then "dz" else "dnz"
603 :     | I.COUNTER{eqZero, cond=SOME cc} =>
604 :     (if eqZero then "dz" else "dnz") ^
605 :     (if cc then "t" else "f")
606 :     (*esac*))
607 :    
608 :     fun eME(SOME me) = (emit ", "; emit_int me)
609 :     | eME(NONE) = ()
610 :    
611 :     fun addr(ra,I.RegOp rb) = (emitCell ra; emit ", "; emitCell rb)
612 :     | addr(ra,d) = (emit_operand d; emit "("; emitCell ra; emit ")")
613 :    
614 :     end (* Assembly *)
615 :    
616 :     instruction
617 :     L of {ld:load, rt: $GP, ra: $GP, d:operand, mem:Region.region}
618 :     ``<emitx(asm_load ld,d)>\t<rt>, <addr(ra,d)><mem>''
619 :     load{ld,rt,ra,d}
620 :    
621 :     | LF of {ld:fload, ft: $FP, ra: $GP, d:operand, mem:Region.region}
622 :     ``<emitx(asm_fload ld,d)>\t<ft>, <addr(ra,d)><mem>''
623 :     fload{ld,ft,ra,d}
624 :    
625 :     | ST of {st:store, rs: $GP, ra: $GP, d:operand, mem:Region.region}
626 :     ``<emitx(asm_store st,d)>\t<rs>, <addr(ra,d)><mem>''
627 :     store{st,rs,ra,d}
628 :    
629 :     | STF of {st:fstore, fs: $FP, ra: $GP, d:operand, mem:Region.region}
630 :     ``<emitx(asm_fstore st,d)>\t<fs>, <addr(ra,d)><mem>''
631 :     fstore{st,fs,ra,d}
632 :    
633 :     | UNARY of {oper:unary, rt: $GP, ra: $GP, Rc:bool, OE:bool}
634 :     ``<oper><eOERc{Rc,OE}>\t<rt>, <ra>''
635 :     unary{oper,rt,ra,OE,Rc}
636 :    
637 :     | ARITH of {oper:arith, rt: $GP, ra: $GP, rb: $GP, Rc:bool, OE:bool}
638 :     ``<oper><eOERc{Rc,OE}>\t<rt>, <ra>, <rb>''
639 :     arith{oper,rt,ra,rb,OE,Rc}
640 :    
641 :     | ARITHI of {oper:arithi, rt: $GP, ra: $GP, im:operand}
642 :     ``<oper>\t<rt>, <ra>, <im>''
643 :     arithi{oper,rt,ra,im}
644 :    
645 :     | ROTATE of {oper:rotate, ra: $GP, rs: $GP, sh: $GP, mb:int, me:int option}
646 :     ``<oper>\t<ra>, <rs>, <sh>, <mb><eME me>''
647 :     rotate{oper,ra,rs,sh,mb,me}
648 :    
649 :     | ROTATEI of {oper:rotatei, ra: $GP, rs: $GP, sh:operand, mb:int, me:int option}
650 :     ``<oper>\t<ra>, <rs>, <sh>, <mb><eME me>''
651 :     rotatei{oper,ra,rs,sh,mb,me}
652 :    
653 :     | COMPARE of {cmp:cmp, l:bool, bf: $CC, ra: $GP, rb:operand}
654 :     ``<cmp><eI rb>\t<bf>, <emit(if l then "1" else "0")>, <ra>, <rb>''
655 :     compare{cmp,bf,l,ra,rb}
656 :    
657 :     | FCOMPARE of {cmp:fcmp, bf: $CC, fa: $FP, fb: $FP}
658 :     ``<cmp>\t<bf>, <fa>, <fb>''
659 :     fcmp{cmp,bf,fa,fb}
660 :    
661 :     | FUNARY of {oper:funary, ft: $FP, fb: $FP, Rc:bool}
662 :     ``<oper><eRc Rc>\t<ft>, <fb>''
663 :     funary{oper,ft,fb,Rc}
664 :    
665 :     | FARITH of {oper:farith, ft: $FP, fa: $FP, fb: $FP, Rc:bool}
666 :     ``<oper><eRc Rc>\t<ft>, <fa>, <fb>''
667 :     farith{oper,ft,fa,fb,Rc}
668 :    
669 :     | FARITH3 of {oper:farith3, ft: $FP, fa: $FP, fb: $FP, fc: $FP, Rc:bool}
670 :     ``<oper><eRc Rc>\t<ft>, <fa>, <fb>, <fc>''
671 :     farith3{oper,ft,fa,fb,fc,Rc}
672 :    
673 :     | CCARITH of {oper:ccarith, bt:cr_bit, ba:cr_bit, bb:cr_bit}
674 :     ``<oper>\t<eCRbit bt>, <eCRbit ba>, <eCRbit bb>''
675 :     ccarith{oper,bt,ba,bb}
676 :    
677 :     | MCRF of {bf: $CC, bfa: $CC} (* move condition register field p49 *)
678 :     ``mcrf\t<bf>, <bfa>''
679 :     mcrf{bf,bfa}
680 :    
681 :     (* move to special register p131 *)
682 :     | MTSPR of {rs: $GP, spr: $SPR}
683 :     ``mt<spr>\t<rs>''
684 :     mtspr{rs,spr}
685 :    
686 :     (* move from special register p132 *)
687 :     | MFSPR of {rt: $GP, spr: $SPR}
688 :     ``mf<spr>\t<rt>''
689 :     mfspr{rt,spr}
690 :    
691 :     (* Trapping word *)
692 :     | TW of {to:int, ra: $GP, si:operand}
693 :     ``tw<eI si>\t<to>, <ra>, <si>''
694 :     tw{to,ra,si}
695 :    
696 :     (* Trapping double word *)
697 :     | TD of {to:int, ra: $GP, si:operand}
698 :     ``td<eI si>\t<to>, <ra>, <si>''
699 :     td{to,ra,si}
700 :    
701 :     (* Control Instructions - AA is always assumed to be 0 *)
702 :     | BC of {bo:bo, bf: $CC, bit:bit, addr:operand, LK:bool, fall:operand}
703 :     ``b<bo><eLK LK>\t<eBI(bo,bf,bit)>, <addr>''
704 :     bc{bo,bi=cr_bit{cc=(bf,bit)},bd=relative addr,aa=false,lk=LK}
705 :    
706 :     | BCLR of {bo:bo, bf: $CC, bit:bit, LK:bool, labels:Label.label list}
707 :     ``b<bo>lr<eLK LK>\t<eBI(bo,bf,bit)>''
708 :     bclr{bo,bi=cr_bit{cc=(bf,bit)},lk=LK}
709 :    
710 :     | B of {addr:operand, LK:bool}
711 :     ``b<eLK LK>\t<addr>''
712 :     b{li=relative addr,aa=false,lk=LK}
713 :    
714 :     (* CALL = BCLR {bo=ALWAYS, bf=0, bit=0, LK=true, labels=[] *)
715 : leunga 796 | CALL of {def:C.cellset, use:C.cellset,
716 :     cutsTo: Label.label list, mem: Region.region}
717 :     ``blrl<mem><emit_defs(def)><emit_uses(use)><emit_cutsTo cutsTo>''
718 : leunga 746 bclr{bo=I.ALWAYS,bi=0w0,lk=true}
719 :    
720 :     | COPY of {dst: $GP list, src: $GP list,
721 :     impl:instruction list option ref,
722 :     tmp: ea option}
723 :     asm: emitInstrs (Shuffle.shuffle{tmp,dst,src})
724 :    
725 :     | FCOPY of {dst: $FP list, src: $FP list,
726 :     impl:instruction list option ref,
727 :     tmp: ea option}
728 :     asm: emitInstrs (Shuffle.shufflefp{tmp,dst,src})
729 :    
730 :     | ANNOTATION of {i:instruction, a:Annotations.annotation}
731 :     asm: (comment(Annotations.toString a); nl(); emitInstr i)
732 :     mc: emitInstr i
733 :    
734 :     | SOURCE of {}
735 :     asm: ``source''
736 :     mc: ()
737 :    
738 :     | SINK of {}
739 :     asm: ``sink''
740 :     mc: ()
741 :    
742 :     | PHI of {}
743 :     asm: ``phi''
744 :     mc: ()
745 :    
746 :     structure SSA =
747 :     struct
748 :    
749 :     fun operand(ty, I.RegOp r) = T.REG(32, r)
750 :     | operand(ty, I.ImmedOp i) = T.LI i
751 :     (*| operand(ty, I.LabelOp le) = T.LABEL le*)
752 :    
753 :     end
754 :    
755 :     end

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