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/branches/idlbasis-devel/src/MLRISC/ppc/emit/ppcMC.sml
ViewVC logotype

Annotation of /sml/branches/idlbasis-devel/src/MLRISC/ppc/emit/ppcMC.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 245 - (view) (download)
Original Path: sml/branches/SMLNJ/src/MLRISC/ppc/emit/ppcMC.sml

1 : monnier 245 (* ppcMC.sml
2 :     *
3 :     * COPYRIGHT (c) 1999 Lucent Technologies, Bell Labs.
4 :     *
5 :     *)
6 :    
7 :     (** IBM PPC machine code generator **)
8 :    
9 :     functor PPCMCEmitter
10 :     (structure Instr : PPCINSTR
11 :     structure PseudoOps : PSEUDO_OPS
12 :     structure CodeString : CODE_STRING) : EMITTER_NEW =
13 :     struct
14 :     structure I = Instr
15 :     structure P = PseudoOps
16 :     structure C = I.C
17 :    
18 :     structure LE = LabelExp
19 :    
20 :     val << = Word.<<
21 :     val >> = Word.>>
22 :     val ~>> = Word.~>>
23 :     val ++ = Word.orb
24 :     val & = Word.andb
25 :     infix << >> ~>> ++ &
26 :    
27 :     val itow = Word.fromInt
28 :     fun error msg = MLRiscErrorMsg.impossible ("PPCMCEmitter." ^ msg)
29 :     val loc = ref 0
30 :    
31 :    
32 :     fun eBytefromW8 w8 = let
33 :     val i = !loc
34 :     in loc := i+1; CodeString.update(i,w8)
35 :     end
36 :    
37 :     fun eBytefromW w = let
38 :     val i = !loc
39 :     val wtob = Word8.fromLargeWord o Word.toLargeWord
40 :     in loc:= i+1; CodeString.update(i, wtob w)
41 :     end
42 :    
43 :     fun emitHiLo(hi,lo) =
44 :     (eBytefromW ((hi >> 0w8) & 0w255);
45 :     eBytefromW (hi & 0w255);
46 :     eBytefromW ((lo >> 0w8) & 0w255);
47 :     eBytefromW (lo & 0w255))
48 :    
49 :     fun defineLabel lab = ()
50 :     fun pseudoOp pOp = P.emitValue{pOp=pOp, loc= !loc, emit=eBytefromW8}
51 :     fun comment msg = ()
52 :     fun init n = (CodeString.init n; loc:=0)
53 :    
54 :     fun emitInstr(instr, regmap) = let
55 :     val rMap = Intmap.map regmap
56 :     fun rNum r = itow(rMap r)
57 :     val fNum = rNum
58 :    
59 :     val don'tCare = 0w0
60 :    
61 :     fun bitToInt(I.LT) = 0 | bitToInt(I.GT) = 1
62 :     | bitToInt(I.EQ) = 2 | bitToInt(I.SO) = 3
63 :     | bitToInt(I.FL) = 0 | bitToInt(I.FG) = 1
64 :     | bitToInt(I.FE) = 2 | bitToInt(I.FU) = 3
65 :     | bitToInt(I.FX) = 0 | bitToInt(I.FEX)= 1
66 :     | bitToInt(I.VX) = 2 | bitToInt(I.OX) = 3
67 :    
68 :     fun cvtRc true = 0w1
69 :     | cvtRc false = 0w0
70 :    
71 :     fun cvtOE true = 0w1
72 :     | cvtOE false = 0w0
73 :    
74 :     fun cvtLK true = 0w1
75 :     | cvtLK false = 0w0
76 :    
77 :     fun cvtBO I.TRUE = 0w12 (* 011zy *)
78 :     | cvtBO I.FALSE = 0w4 (* 001zy *)
79 :     | cvtBO I.ALWAYS = 0w20 (* 1z1zz *)
80 :     | cvtBO(I.COUNTER{eqZero, cond=NONE}) =
81 :     if eqZero then 0w18 (* 1z01y *)
82 :     else 0w16 (* 1z00y *)
83 :     | cvtBO(I.COUNTER{eqZero, cond=SOME cc}) =
84 :     (case (eqZero, cc)
85 :     of (false, false) => 0w0 (* 0000y *)
86 :     | (false, true) => 0w8 (* 0100y *)
87 :     | (true, false) => 0w2 (* 0001y *)
88 :     | (true, true) => 0w10 (* 0101y *)
89 :     (*esac*))
90 :    
91 :     fun cr_bit(cr, bit) = itow(cr*4 + bitToInt bit)
92 :    
93 :     local
94 :     fun split i = let
95 :     val w = Word.fromInt i
96 :     val hi = Word.~>>(w, 0w16)
97 :     val lo = Word.andb(w, 0w65535)
98 :     in if lo < 0w32768 then (hi, lo) else (hi+0w1, lo-0w65536)
99 :     end
100 :     in
101 :     fun high n = #1 (split n)
102 :     fun low n = #2 (split n)
103 :     end
104 :    
105 :    
106 :     fun operand(I.RegOp r) = error "operand:RegOp"
107 :     | operand(I.ConstOp c) = error "operand:ConstOp"
108 :     | operand(I.ImmedOp i) = itow i
109 :     | operand(I.LabelOp lexp) = itow(LE.valueOf lexp)
110 :    
111 :     fun relative (I.LabelOp lexp) = itow((LE.valueOf lexp - (!loc)) div 4)
112 :     | relative _ = error "relative"
113 :    
114 :     fun d_form(opcd,rt,ra,si) = let
115 :     val hi = (opcd << 0w10) ++ (rt << 0w5) ++ ra
116 :     val lo = si
117 :     in emitHiLo(hi,lo)
118 :     end
119 :    
120 :     fun b_form(opcd,bo,bi,bd,aa,lk) = let
121 :     val hi = (opcd << 0w10) ++ (bo << 0w5) ++ bi
122 :     val lo = (bd << 0w2) ++ (aa << 0w1) ++ lk
123 :     in emitHiLo(hi,lo)
124 :     end
125 :    
126 :     fun x_form(opcd,rt,ra,rb,eo,rc) = let
127 :     val hi = (opcd << 0w10) ++ (rt << 0w5) ++ ra
128 :     val lo = (rb << 0w11) ++ (eo << 0w1) ++ rc
129 :     in emitHiLo(hi,lo)
130 :     end
131 :    
132 :     fun xl_form(opcd,bt,ba,bb,eo,lk) = let
133 :     val hi = (opcd << 0w10) ++ (bt << 0w5) ++ ba
134 :     val lo = (bb << 0w11) ++ (eo << 0w1) ++ lk
135 :     in emitHiLo(hi,lo)
136 :     end
137 :    
138 :     fun xo_form(opcd,rt,ra,rb,oe,eo',rc) = let
139 :     val hi = (opcd << 0w10) ++ (rt << 0w5) ++ ra
140 :     val lo = (rb << 0w11) ++ (oe << 0w10) ++ (eo' << 0w1) ++ rc
141 :     in emitHiLo(hi,lo)
142 :     end
143 :    
144 :     fun a_form(opcd,frt,fra,frb,frc,xo,rc) = let
145 :     val hi = (opcd << 0w10) ++ (frt << 0w5) ++ fra
146 :     val lo = (frb <<0w11) ++ (frc <<0w6) ++ (xo <<0w1) ++ rc
147 :     in emitHiLo(hi,lo)
148 :     end
149 :    
150 :     fun m_form(opcd,rs,ra,rb,mb,me,rc) = let
151 :     val hi = (opcd << 0w10) ++ (rs << 0w5) ++ ra
152 :     val lo = (rb << 0w11) ++ (itow mb << 0w6) ++ (itow me << 0w1) ++ rc
153 :     in emitHiLo(hi,lo)
154 :     end
155 :    
156 :     fun ds_form(opcd, rt, ra, ds, xo) = let
157 :     val hi = (opcd << 0w10) ++ (rt << 0w5) ++ ra
158 :     val lo = (ds << 0w2) ++ xo
159 :     in emitHiLo(hi, lo)
160 :     end
161 :    
162 :     fun xfx_form(opcd, rs, spr, xo, LK) = let
163 :     val hi = (opcd << 0w10) ++ (rs << 0w5) ++ (spr & 0wx1f)
164 :     val lo = ((spr >> 0w5) << 0w11) ++ (xo << 0w1) ++ LK
165 :     in emitHiLo(hi, lo)
166 :     end
167 :    
168 :     fun i_form(opcd,li,lk) = let
169 :     val liLo = li & 0wx3fff
170 :     val liHi = (li ~>> 0w14) & 0wx3ff
171 :     val hi = (opcd << 0w10) ++ liHi
172 :     val lo = (liLo << 0w2) ++ lk
173 :     in emitHiLo(hi,lo)
174 :     end
175 :    
176 :     in
177 :     case instr
178 :     of I.L{sz, rt, ra, d=I.RegOp rb, mem} => let
179 :     val ra = rNum ra
180 :     val rb = rNum rb
181 :     in
182 :     case sz
183 :     of I.Byte => x_form(0w31, rNum rt, ra, rb, 0w87, don'tCare)
184 :     | I.Half => x_form(0w31, rNum rt, ra, rb, 0w279, don'tCare)
185 :     | I.Word => x_form(0w31, rNum rt, ra, rb, 0w23, don'tCare)
186 :     | I.Long => x_form(0w31, rNum rt, ra, rb, 0w21, don'tCare)
187 :     | I.Single => x_form(0w31, fNum rt, ra, rb, 0w535, don'tCare)
188 :     | I.Double => x_form(0w31, fNum rt, ra, rb, 0w599, don'tCare)
189 :     (*esac*)
190 :     end
191 :     | I.L{sz, rt, ra, d, mem} => let
192 :     val ra = rNum ra
193 :     val d = operand d
194 :     in
195 :     case sz
196 :     of I.Byte => d_form(0w34, rNum rt, ra, d)
197 :     | I.Half => d_form(0w40, rNum rt, ra, d)
198 :     | I.Word => d_form(0w32, rNum rt, ra, d)
199 :     | I.Long => ds_form(0w58, rNum rt, ra, d, 0w0)
200 :     | I.Single => d_form(0w48, fNum rt, ra, d)
201 :     | I.Double => d_form(0w50, fNum rt, ra, d)
202 :     (*esac*)
203 :     end
204 :     | I.ST{sz, rs, ra, d=I.RegOp rb, mem} => let
205 :     val ra=rNum ra
206 :     val rb=rNum rb
207 :     in
208 :     case sz
209 :     of I.Byte => x_form(0w31, rNum rs, ra, rb, 0w215, don'tCare)
210 :     | I.Half => x_form(0w31, rNum rs, ra, rb, 0w407, don'tCare)
211 :     | I.Word => x_form(0w31, rNum rs, ra, rb, 0w151, don'tCare)
212 :     | I.Long => x_form(0w31, rNum rs, ra, rb, 0w149, don'tCare)
213 :     | I.Single => x_form(0w31, fNum rs, ra, rb, 0w663, don'tCare)
214 :     | I.Double => x_form(0w31, fNum rs, ra, rb, 0w727, don'tCare)
215 :     (*esac*)
216 :     end
217 :     | I.ST{sz, rs, ra, d, mem} => let
218 :     val ra = rNum ra
219 :     val d = operand d
220 :     in
221 :     case sz
222 :     of I.Byte => d_form(0w38, rNum rs, ra, d)
223 :     | I.Half => d_form(0w44, rNum rs, ra, d)
224 :     | I.Word => d_form(0w36, rNum rs, ra, d)
225 :     | I.Long => ds_form(0w62, rNum rs, ra, d, 0w0)
226 :     | I.Single => d_form(0w52, fNum rs, ra, d)
227 :     | I.Double => d_form(0w54, fNum rs, ra, d)
228 :     (*esac*)
229 :     end
230 :     | I.UNARY{oper,rt,ra,Rc,OE} =>
231 :     (case oper
232 :     of I.NEG =>
233 :     xo_form(0w31, rNum rt, rNum ra, don'tCare, cvtOE OE, 0w104, cvtRc Rc)
234 :     (*esac*))
235 :     | I.ARITH{oper,rt,ra,rb,Rc,OE} => let
236 :     val rt=rNum rt
237 :     val ra=rNum ra
238 :     val rb=rNum rb
239 :     val Rc=cvtRc Rc
240 :     val OE=cvtOE OE
241 :     in
242 :     case oper
243 :     of I.ADD => xo_form(0w31, rt, ra, rb, OE, 0w266, Rc)
244 :     | I.ADDS => error "emitInstr:ARITH:ADDS"
245 :     | I.SUBF => xo_form(0w31, rt, ra, rb, OE, 0w40, Rc)
246 :     | I.MULL => xo_form(0w31, rt, ra, rb, OE, 0w235, Rc)
247 :     | I.DIVW => xo_form(0w31, rt, ra, rb, OE, 0w491, Rc)
248 :     | I.DIVWU=> xo_form(0w31, rt, ra, rb, OE, 0w459, Rc)
249 :     | I.AND => x_form(0w31, ra, rt, rb, 0w28, Rc)
250 :     | I.OR => x_form(0w31, ra, rt, rb, 0w444, Rc)
251 :     | I.XOR => x_form(0w31, ra, rt, rb, 0w316, Rc)
252 :     | I.XORS => error "emitInstr:ARITH:XORS"
253 :     | I.SLW => x_form(0w31, ra, rt, rb, 0w24, Rc)
254 :     | I.SRW => x_form(0w31, ra, rt, rb, 0w536, Rc)
255 :     | I.SRAW => x_form(0w31, ra, rt, rb, 0w792, Rc)
256 :     (*esac*)
257 :     end
258 :     | I.ARITHI{oper, rt=rt', ra=ra', im=im'} => let
259 :     val rt=rNum rt'
260 :     val ra=rNum ra'
261 :     val im=operand im'
262 :     in
263 :     case oper
264 :     of I.ADD => d_form(0w14, rt, ra, im)
265 :     | I.ADDS => d_form(0w15, rt, ra, im)
266 :     | I.SUBF => d_form(0w8, rt, ra, im)
267 :     | I.MULL => d_form(0w7, rt, ra, im)
268 :     | I.DIVW => error "emitInstr:ARITHI:DIVW"
269 :     | I.DIVWU => error "emitInstr:ARITHI:DIVWU"
270 :     | I.AND => d_form(0w28, ra, rt, im)
271 :     | I.OR => d_form(0w24, ra, rt, im)
272 :     | I.XOR => d_form(0w26, ra, rt, im)
273 :     | I.XORS => d_form(0w27, ra, rt, im)
274 :     | I.SLW =>
275 :     (case im'
276 :     of I.ImmedOp n =>
277 :     emitInstr(
278 :     I.ROTATE{oper=I.RLWNM, ra=rt', rs=ra', sh=I.ImmedOp n,
279 :     mb=0, me=31-n},
280 :     regmap)
281 :     | _ => error "emitInstr:ARITHI:SLW"
282 :     (*esac*))
283 :     | I.SRW =>
284 :     (case im'
285 :     of I.ImmedOp n =>
286 :     emitInstr(
287 :     I.ROTATE{oper=I.RLWNM, ra=rt', rs=ra', sh=I.ImmedOp(32-n),
288 :     mb=n, me=31},
289 :     regmap)
290 :     | _ => error "emitInstr:ARITHI:SLW"
291 :     (*esac*))
292 :     | I.SRAW => x_form(0w31, ra, rt, im, 0w824, 0w0)
293 :     (*esac*)
294 :     end
295 :     | I.ROTATE{oper, ra, rs, sh=I.RegOp rb, mb, me} =>
296 :     m_form(0w23, rNum rs, rNum ra, rNum rb, mb, me, don'tCare)
297 :     | I.ROTATE{oper, ra, rs, sh, mb, me} =>
298 :     m_form(0w21, rNum rs, rNum ra, operand sh, mb, me, don'tCare)
299 :     | I.COMPARE{cmp, bf, ra, rb=I.RegOp rb} => let
300 :     val ra=rNum ra
301 :     val rb=rNum rb
302 :     val bf=itow(bf*4)
303 :     in
304 :     case cmp
305 :     of I.CMP => x_form(0w31, bf, ra, rb, 0w0, don'tCare)
306 :     | I.CMPL => x_form(0w31,bf, ra, rb, 0w32, don'tCare)
307 :     (*esac*)
308 :     end
309 :     | I.COMPARE{cmp, bf, ra, rb} => let
310 :     val ra=rNum ra
311 :     val rb=operand rb
312 :     val bf=itow(bf * 4)
313 :     in
314 :     case cmp
315 :     of I.CMP => d_form(0w11, bf, ra, rb)
316 :     | I.CMPL => d_form(0w10, bf, ra, rb)
317 :     (*esac*)
318 :     end
319 :     | I.FCOMPARE{cmp, bf, fa, fb} => let
320 :     val fa=fNum fa
321 :     val fb=fNum fb
322 :     val bf=itow(bf*4)
323 :     in
324 :     case cmp
325 :     of I.FCMPO => x_form(0w63, bf, fa, fb, 0w32, don'tCare)
326 :     | I.FCMPU => x_form(0w63, bf, fa, fb, 0w0, don'tCare)
327 :     (*esac*)
328 :     end
329 :     | I.FUNARY{oper, ft, fb, Rc} => let
330 :     val ft=fNum ft
331 :     val fb=fNum fb
332 :     val Rc=cvtRc Rc
333 :     in
334 :     case oper
335 :     of I.FMR => x_form(0w63, ft, don'tCare, fb, 0w72, Rc)
336 :     | I.FABS => x_form(0w63, ft, don'tCare, fb, 0w264, Rc)
337 :     | I.FNEG => x_form(0w63, ft, don'tCare, fb, 0w40, Rc)
338 :     (*esac*)
339 :     end
340 :     | I.FARITH{oper, ft, fa, fb, Rc} => let
341 :     val fa=fNum fa
342 :     val fb=fNum fb
343 :     val ft=fNum ft
344 :     val Rc=cvtRc Rc
345 :     in
346 :     case oper
347 :     of I.FADD => a_form(0w63, ft, fa, fb, don'tCare, 0w21, Rc)
348 :     | I.FSUB => a_form(0w63, ft, fa, fb, don'tCare, 0w20, Rc)
349 :     | I.FMUL => a_form(0w63, ft, fa, don'tCare, fb, 0w25, Rc)
350 :     | I.FDIV => a_form(0w63, ft, fa, fb, don'tCare, 0w18, Rc)
351 :     (*esac*)
352 :     end
353 :     | I.CCARITH{oper, bt, ba, bb} => let
354 :     val bt=cr_bit bt
355 :     val ba=cr_bit ba
356 :     val bb=cr_bit bb
357 :     in
358 :     case oper
359 :     of I.CRAND => xl_form(0w19, bt, ba, bb, 0w257, don'tCare)
360 :     | I.CROR => xl_form(0w19, bt, ba, bb, 0w449, don'tCare)
361 :     | I.CRXOR => xl_form(0w19, bt, ba, bb, 0w193, don'tCare)
362 :     | I.CRNAND => xl_form(0w19, bt, ba, bb, 0w225, don'tCare)
363 :     | I.CRNOR => xl_form(0w19, bt, ba, bb, 0w33, don'tCare)
364 :     (*esac*)
365 :     end
366 :     | I.MCRF {bf:int, bfa:int} =>
367 :     xl_form(0w19, itow(bf*4), itow(bfa*4), don'tCare, 0w0, don'tCare)
368 :     | I.MTSPR{rs:int, spr:int} =>
369 :     xfx_form(0w31, rNum rs, itow spr, 0w467, don'tCare)
370 :     | I.MFSPR{rt:int, spr:int} =>
371 :     xfx_form(0w31, rNum rt, itow spr, 0w339, don'tCare)
372 :     | I.TWI{to, ra, si} =>
373 :     d_form(0w3, itow to, rNum ra, operand si)
374 :    
375 :     (* Control Instructions - AA is always assumed to be 0 *)
376 :     | I.BC{bo, bf, bit, addr, LK, ...} =>
377 :     b_form(0w16, cvtBO bo, cr_bit(bf, bit), relative addr, 0w0, cvtLK LK)
378 :     | I.BCLR{bo, bf, bit, LK, labels} =>
379 :     xl_form(0w19, cvtBO bo, cr_bit(bf, bit), don'tCare, 0w16, cvtLK LK)
380 :     | I.B{addr, LK} => i_form(0w18, relative addr, cvtLK LK)
381 :    
382 :     (* CALL = BCLR {bo=ALWAYS, bf=0, bit=0, LK=true, labels=[] *)
383 :     | I.CALL{def, use} =>
384 :     emitInstr(
385 :     I.BCLR{bo=I.ALWAYS, bf=0, bit=I.LT, LK=true, labels=[]},
386 :     regmap)
387 :    
388 :     | I.COPY{dst, src, impl, tmp} => error "emitInstr:COPY"
389 :     | I.FCOPY{dst, src, impl, tmp}=> error "emitInstr:FCOPY"
390 :     end(*emitInstr*)
391 :     end (*functor*)

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