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/SMLNJ/src/MLRISC/hppa/hppaMC.sml
ViewVC logotype

Annotation of /sml/branches/SMLNJ/src/MLRISC/hppa/hppaMC.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 167 - (view) (download)

1 : monnier 16 (* hppaMC.sml
2 :     *
3 :     * COPYRIGHT (c) 1996 Bell Laboratories.
4 :     *
5 :     *)
6 :    
7 :    
8 :     functor HppaMCEmitter
9 :     (structure Instr : HPPAINSTR
10 : monnier 167 structure Assembler : EMITTER_NEW where I = Instr
11 :     (* sharing/definiton conflict at Instr.Cells.regmap ----
12 : monnier 16 sharing Assembler.F = FlowGraph
13 : monnier 167 sharing FlowGraph.I = Assembler.I = Instr *)
14 :     ) : EMITTER_NEW =
15 : monnier 16 struct
16 :     structure I = Instr
17 : monnier 167 structure P = Assembler.P
18 : monnier 16
19 :     val << = Word.<<
20 :     val >> = Word.>>
21 :     val ~>> = Word.~>>
22 :     val ++ = Word.orb
23 :     val & = Word.andb
24 :     infix << >> ~>> ++ &
25 :    
26 :     fun error msg = MLRiscErrorMsg.impossible ("HppaMCEmitter." ^ msg)
27 :    
28 :     val itow = Word.fromInt
29 :    
30 :     val loc = ref 0
31 :    
32 :     fun emitByte n = let
33 :     val i = !loc
34 :     val wtob = Word8.fromLargeWord o Word.toLargeWord
35 :     in loc:= i+1; CodeString.update(i, wtob n)
36 :     end
37 :    
38 :     fun emitbyte w8 = let
39 :     val i = !loc
40 :     in loc:= i+1; CodeString.update(i, w8)
41 :     end
42 :    
43 :     fun emitWord w = (emitByte((w >> 0w8) & 0w255); emitByte(w & 0w255))
44 :    
45 :     fun defineLabel lab = ()
46 : monnier 167 fun pseudoOp pOp = P.emitValue{pOp=pOp, loc= !loc, emit=emitbyte}
47 : monnier 16 fun comment msg = ()
48 :     fun init n = (CodeString.init n; loc:=0)
49 :    
50 :     fun emitInstr(instr,regmap) = let
51 :     val rMap = Intmap.map regmap
52 :     val rNum = itow o rMap
53 :     val fNum = rNum
54 :    
55 :     fun low_sign_ext_im14 n = ((n & 0wx1fff) << 0w1) ++ ((n & 0wx2000) >> 0w13)
56 :     fun low_sign_ext_im11 n = ((n & 0wx3ff) << 0w1) ++ ((n & 0wx400) >> 0w10)
57 :     fun low_sign_ext_im5 n = ((n & 0wxf) << 0w1) ++ ((n & 0wx10) >> 0w4)
58 :    
59 :     fun assemble_12 n = let
60 :     val w = (n & 0wx800) >> 0w11
61 :     val w1 = ((n & 0wx3ff) << 0w1) ++ ((n & 0wx400) >> 0w10)
62 :     in
63 :     (w1, w)
64 :     end
65 :    
66 :     fun assemble_17 n = let
67 :     val w = (n & 0wx10000) >> 0w16
68 :     val w1 = (n & 0wxf800) >> 0w11
69 :     val w2 = (((n & 0wx3ff) << 0w1) ++ ((n & 0wx400) >> 0w10))
70 :     in
71 :     (w, w1, w2)
72 :     end
73 :    
74 :     fun assemble_21 disp = let
75 :     val w =
76 :     (((disp & 0wx000003) << 0w12) ++
77 :     ((disp & 0wx00007c) << 0w14) ++
78 :     ((disp & 0wx000180) << 0w7) ++
79 :     ((disp & 0wx0ffe00) >> 0w8) ++
80 :     ((disp & 0wx100000) >> 0w20))
81 :     in
82 :     ((w >> 0w16) & 0wx1f, (w & 0wxffff))
83 :     end
84 :    
85 :     fun operand opnd = let
86 :     fun hi21 n = Word.>>(itow n, 0w11)
87 :     fun hi21X n = Word.~>>(itow n, 0w11)
88 :     fun lo11 n = Word.andb(itow n, 0wx7ff)
89 :    
90 :     (* BUG: should respect the field selectors instead of ignoring them *)
91 :     fun f(I.HILabExp(lexp, _)) = hi21X(LabelExp.valueOf lexp)
92 :     | f(I.LOLabExp(lexp, _)) = lo11(LabelExp.valueOf lexp)
93 :     | f(I.ConstOp _) = error "ConstOp"
94 :     | f(I.LabExp(lexp, _)) = itow(LabelExp.valueOf lexp)
95 :     | f(I.IMMED i) = itow i
96 :     in
97 :     f opnd
98 :     end
99 :    
100 :     fun longImmediates(opcode, opnd, t) = let
101 :     val (wh, wl) = assemble_21 (operand opnd)
102 :     in
103 :     emitWord((opcode << 0w10) ++ ((rNum t) << 0w5) ++ wh);
104 :     emitWord wl
105 :     end
106 :    
107 :     fun loadStore(opcode, b, t, im14) =
108 :     (emitWord((opcode << 0w10) ++ ((rNum b) << 0w5) ++ (rNum t));
109 :     emitWord(low_sign_ext_im14 (operand im14)))
110 :    
111 :     (* indexed loads use sr3 which is guaranteed to contain sr5 --- see
112 :     * HPPA.prim.asm.
113 :     *)
114 :     fun indexedLoads(opcode, b, x, ext4, t) =
115 :     (emitWord((opcode << 0w10) ++ ((rNum b) << 0w5) ++ (rNum x));
116 :     emitWord((0w3 << 0w14) ++ (ext4 << 0w6) ++ (rNum t)))
117 :    
118 :     fun arithmeticLogical(opcode, r2, r1, ext7, b6, t) =
119 :     (emitWord((opcode << 0w10) ++ ((rNum r2) << 0w5) ++ (rNum r1));
120 :     emitWord((ext7 << 0w6) ++ (b6 << 0w5) ++ (rNum t)))
121 :    
122 :     fun arithmeticImmediate(opcode, r, t, e, immed) =
123 :     (emitWord((opcode << 0w10) ++ ((rNum r) << 0w5) ++ (rNum t));
124 :     emitWord((e << 0w11) ++ (low_sign_ext_im11 (operand immed))))
125 :    
126 :     fun conditionalBranch (opcode, bc, r1, r2, t, nullify) = let
127 :     val wdisp = ((Label.addrOf t) - !loc - 8) div 4
128 :     val c = (case bc of I.EQ => 0w1 | I.LT => 0w2 | I.LE => 0w3
129 :     | I.LTU => 0w4 | I.LEU => 0w5
130 :     | _ => error "conditionalBranch"
131 :     (*esac*))
132 :     val (w1, w) = assemble_12 (itow wdisp)
133 :     in
134 :     emitWord((opcode << 0w10) ++ (r2 << 0w5) ++ r1);
135 :     emitWord((c << 0w13) ++ (w1 << 0w2) ++ nullify ++ w)
136 :     end
137 :    
138 :     fun branchLink(opcode, r, lab, ext3, nullify) = let
139 :     val disp = ((Label.addrOf lab) - !loc - 8) div 4
140 :     val (w, w1, w2) = assemble_17 (itow disp)
141 :     in
142 :     emitWord((opcode << 0w10) ++ ((rNum r) << 0w5) ++ w1);
143 :     emitWord((ext3 << 0w13) ++ (w2 << 0w2) ++ nullify ++ (w))
144 :     end
145 :    
146 :     fun branchVectored(opcode, b, x, ext3, nullify) =
147 :     (emitWord((opcode << 0w10) ++ ((rNum b) << 0w5) ++ rNum x);
148 :     emitWord((ext3 << 0w13) ++ nullify))
149 :    
150 :     fun branchBit(opcode, p, r1, c, lab) = let
151 :     val wdisp = ((Label.addrOf lab) - !loc - 8) div 4
152 :     val (w1, w) = assemble_12 (itow wdisp)
153 :     in
154 :     emitWord((opcode << 0w10) ++ (p << 0w5) ++ (rNum r1));
155 :     emitWord((c << 0w13) ++ (w1 << 0w2) ++ w)
156 :     end
157 :    
158 :     fun extractDeposit(opcode, r, t, ext3, p, clen) =
159 :     (emitWord((opcode << 0w10) ++ ((rNum r) << 0w5) ++ rNum t);
160 :     emitWord((ext3 << 0w10) ++ (itow p << 0w5) ++ itow clen))
161 :    
162 :     fun coProcShort(opcode, b, immed, b12, b10, b9, uid, r) =
163 :     (emitWord((opcode << 0w10) ++ ((rNum b) << 0w5) ++
164 :     (low_sign_ext_im5 (itow immed)));
165 :     emitWord((b12 << 0w12) ++ (b10 << 0w10) ++ (b9 << 0w9) ++
166 :     (uid << 0w6) ++ (fNum r)))
167 :    
168 :     fun coProcIndexed(opcode, b, x, b12, b10, b9, uid, t) =
169 :     (emitWord((opcode << 0w10) ++ ((rNum b) << 0w5) ++ (rNum x));
170 :     emitWord((b12 << 0w12) ++ (b10 << 0w10) ++ (b9 << 0w9) ++
171 :     (uid << 0w6) ++ (fNum t)))
172 :    
173 :     fun floatOpMaj0C(r1, r2, sub, fmt, b10, b6, t) =
174 :     (emitWord((0wx0c << 0w10) ++ (r1 << 0w5) ++ r2);
175 :     emitWord((sub << 0w13) ++ (fmt << 0w11) ++
176 :     (b10 << 0w9) ++ (b6 << 0w5) ++ t))
177 :    
178 :     fun floatOpMaj0E(r1, r2, sub, fmt, b10, b6, t) =
179 :     (emitWord((0wx0e << 0w10) ++ (r1 << 0w5) ++ r2);
180 :     emitWord((sub << 0w13) ++ (fmt << 0w11) ++
181 :     (b10 << 0w9) ++ (b6 << 0w5) ++ t))
182 :    
183 :     fun compare(opcode, r2, r1, (c, f), ext, t) =
184 :     (emitWord((opcode << 0w10) ++ ((rNum r2) << 0w5) ++ (rNum r1));
185 :     emitWord((c << 0w13) ++ (f << 0w12) ++ (ext << 0w6) ++ (rNum t)))
186 :    
187 :     fun control(opcode, b, r, rv, ext8, t) =
188 :     (emitWord((opcode << 0w10) ++ (itow b << 0w5) ++ r);
189 :     emitWord((rv << 0w13) ++ (ext8 << 0w5) ++ t))
190 :    
191 : monnier 106 fun fcond I.? = 0w2
192 :     | fcond I.!<=> = 0w3
193 :     | fcond I.== = 0w4
194 :     | fcond I.?= = 0w6
195 :     | fcond I.!<> = 0w7
196 :     | fcond I.!?>= = 0w8
197 :     | fcond I.< = 0w9
198 :     | fcond I.?< = 0w10
199 :     | fcond I.!>= = 0w11
200 :     | fcond I.!?> = 0w12
201 :     | fcond I.<= = 0w13
202 :     | fcond I.?<= = 0w14
203 :     | fcond I.!> = 0w15
204 :     | fcond I.!?<= = 0w16
205 : monnier 16 | fcond I.> = 0w17
206 : monnier 106 | fcond I.?> = 0w18
207 :     | fcond I.!<= = 0w19
208 :     | fcond I.!?< = 0w20
209 : monnier 16 | fcond I.>= = 0w21
210 :     | fcond I.?>= = 0w22
211 : monnier 106 | fcond I.!< = 0w23
212 :     | fcond I.!?= = 0w24
213 : monnier 16 | fcond I.<> = 0w25
214 : monnier 106 | fcond I.!= = 0w26
215 :     | fcond I.!? = 0w28
216 :     | fcond I.<=> = 0w29
217 : monnier 16
218 :     fun cmpCond I.EQ = (0w1, 0w0)
219 :     | cmpCond I.LT = (0w2, 0w0)
220 :     | cmpCond I.LE = (0w3, 0w0)
221 :     | cmpCond I.LTU = (0w4, 0w0)
222 :     | cmpCond I.LEU = (0w5, 0w0)
223 :     | cmpCond I.NE = (0w1, 0w1)
224 :     | cmpCond I.GE = (0w2, 0w1)
225 :     | cmpCond I.GT = (0w3, 0w1)
226 :     | cmpCond I.GEU = (0w4, 0w1)
227 :     | cmpCond I.GTU = (0w5, 0w1)
228 :    
229 :     (* nullify bit in instruction *)
230 :     fun nullify true = 0w2
231 :     | nullify false = 0w0
232 :     in
233 :     case instr
234 :     of I.STORE{st, b, d, r, ...} =>
235 :     (case st
236 :     of I.STW => loadStore(0wx1a, b, r, d)
237 :     | I.STH => loadStore(0wx19, b, r, d)
238 :     | I.STB => loadStore(0wx18, b, r, d)
239 :     (*esac*))
240 :     | I.LOAD{l, r1, r2, t, ...} =>
241 :     (case l
242 :     of I.LDWX => indexedLoads(0wx3, r1, r2, 0w2, t)
243 :     | I.LDHX => indexedLoads(0wx3, r1, r2, 0w1, t)
244 :     | I.LDBX => indexedLoads(0wx3, r1, r2, 0w0, t)
245 :     (*esac*))
246 :     | I.LOADI{li, r, i, t, ...} =>
247 :     (case li
248 :     of I.LDW => loadStore(0wx12, r, t, i)
249 :     | I.LDH => loadStore(0wx11, r, t, i)
250 :     | I.LDB => loadStore(0wx10, r, t, i)
251 :     (*esac*))
252 :     | I.ARITH{a, r1, r2, t} =>
253 :     (case a
254 :     of I.ADD => arithmeticLogical(0wx2, r2, r1, 0wx18, 0w0, t)
255 :     | I.ADDO => arithmeticLogical(0wx2, r2, r1, 0wx38, 0w0, t)
256 :     | I.SH1ADD => arithmeticLogical(0wx2, r2, r1, 0wx19, 0w0, t)
257 :     | I.SH1ADDO => arithmeticLogical(0wx2, r2, r1, 0wx39, 0w0, t)
258 :     | I.SUB => arithmeticLogical(0wx2, r2, r1, 0wx10, 0w0, t)
259 :     | I.SUBO => arithmeticLogical(0wx2, r2, r1, 0wx30, 0w0, t)
260 :     | I.OR => arithmeticLogical(0wx2, r2, r1, 0wx09, 0w0, t)
261 :     | I.XOR => arithmeticLogical(0wx2, r2, r1, 0wx0a, 0w0, t)
262 :     | I.AND => arithmeticLogical(0wx2, r2, r1, 0wx08, 0w0, t)
263 :     (*esac*))
264 :     | I.ARITHI{ai, r, i, t} =>
265 :     (case ai
266 :     of I.ADDI => arithmeticImmediate(0wx2d, r, t, 0w0, i)
267 :     | I.ADDIO => arithmeticImmediate(0wx2d, r, t, 0w1, i)
268 :     | I.ADDIL => longImmediates(0wxa, i, r)
269 :     | I.SUBI => arithmeticImmediate(0wx25, r, t, 0w0, i)
270 :     | I.SUBIO => arithmeticImmediate(0wx25, r, t, 0w1, i)
271 :     (*esac*))
272 :     | I.COMCLR{cc, r1, r2, t} => compare(0wx2, r2, r1, cmpCond cc, 0wx22, t)
273 :     | I.SHIFTV{sv, r, len, t} =>
274 :     (case sv
275 :     of I.VEXTRU => extractDeposit(0wx34, r, t, 0w4, 0, 32-len)
276 :     | I.VEXTRS => extractDeposit(0wx34, r, t, 0w5, 0, 32-len)
277 :     | I.ZVDEP => extractDeposit(0wx35, t, r, 0w0, 0, 32-len)
278 :     (*esac*))
279 :     | I.SHIFT{s, r, p, len, t} =>
280 :     (case s
281 :     of I.EXTRU => extractDeposit(0wx34, r, t, 0w6, p, 32-len)
282 :     | I.EXTRS => extractDeposit(0wx34, r, t, 0w7, p, 32-len)
283 :     | I.ZDEP => extractDeposit(0wx35, t, r, 0w2, 31-p, 32-len)
284 :     (*esac*))
285 :     | I.BCOND{cmp, bc, r1, r2, t, n, ...} => let
286 :     val opcode = case cmp of I.COMBT => 0wx20 | I.COMBF => 0wx22
287 :     in
288 :     conditionalBranch(opcode, bc, rNum r1, rNum r2, t, nullify n)
289 :     end
290 :     | I.BCONDI{bc, i, r2, t, cmpi, n, ...} => let
291 :     val opcode = case cmpi of I.COMIBT => 0wx21 | I.COMIBF => 0wx23
292 :     val r1 = low_sign_ext_im5(itow(i))
293 :     in
294 :     conditionalBranch(opcode, bc, r1, rNum r2, t, nullify n)
295 :     end
296 :     | I.LDIL{i, t} => longImmediates(0wx8, i, t)
297 :     | I.LDO{i, b, t} => loadStore(0wx0d, b, t, i)
298 :     | I.BL _ => error "emitInstr:bl"
299 :     | I.BLE{d=I.IMMED 0, sr=5, b, t=31, ...} =>
300 :     (emitWord((0wx39 << 0w10) ++ (rNum b << 0w5));
301 :     emitWord((0w3 << 0w13) ++ 0w2))
302 :     | I.BLE _ => error "BLE: not implemented"
303 :     | I.B{lab, n, ...} => branchLink(0wx3a, 0, lab, 0w0, nullify n)
304 :     | I.BV{b, x, n,...} => branchVectored(0wx3a, b, x, 0w6, nullify n)
305 : monnier 167 | I.BLR{x, t, n,...} => branchVectored(0wx3a, t, x, 0w2, nullify n)
306 : monnier 16 | I.MTCTL{r, t} => control(0w0, t, rNum r, 0w0, 0wxc2, 0w0)
307 :     | I.FSTORE{fst, b, d, r, ...} =>
308 :     (case fst
309 :     of I.FSTDS => coProcShort(0wxb, b, d, 0w1, 0w0, 0w1, 0w0, r)
310 :     | I.FSTWS => coProcShort(0wx9, b, d, 0w1, 0w0, 0w1, 0w1, r)
311 :     (*esac*))
312 :     | I.FSTOREX{fstx, b, x, r, ...} =>
313 :     (case fstx
314 :     of I.FSTDX => coProcIndexed(0wxb, b, x, 0w0, 0w0, 0w1, 0w0, r)
315 :     | I.FSTWX => coProcIndexed(0wx9, b, x, 0w0, 0w0, 0w1, 0w1, r)
316 :     (*esac*))
317 :     | I.FLOAD{fl, b, d, t, ...} =>
318 :     (case fl
319 :     of I.FLDDS => coProcShort(0wxb, b, d, 0w1, 0w0, 0w0, 0w0, t)
320 :     | I.FLDWS => coProcShort(0wx9, b, d, 0w1, 0w0, 0w0, 0w1, t)
321 :     (*esac*))
322 :     | I.FLOADX{flx, b, x, t, ...} =>
323 :     (case flx
324 :     of I.FLDDX => coProcIndexed(0wxb, b, x, 0w0, 0w0, 0w0, 0w0, t)
325 :     | I.FLDWX => coProcIndexed(0wx9, b, x, 0w0, 0w0, 0w0, 0w1, t)
326 :     (*esac*))
327 :     | I.FARITH{fa, r1, r2, t} =>
328 :     (case fa
329 :     of I.FADD => floatOpMaj0C(fNum r1, fNum r2, 0w0, 0w1, 0w3, 0w0, fNum t)
330 :     | I.FSUB => floatOpMaj0C(fNum r1, fNum r2, 0w1, 0w1, 0w3, 0w0, fNum t)
331 :     | I.FMPY => floatOpMaj0C(fNum r1, fNum r2, 0w2, 0w1, 0w3, 0w0, fNum t)
332 :     | I.FDIV => floatOpMaj0C(fNum r1, fNum r2, 0w3, 0w1, 0w3, 0w0, fNum t)
333 :     | I.XMPYU=>
334 :     (emitWord((0wxe << 0w10) ++ (fNum r1 << 0w5) ++ (fNum r2));
335 :     emitWord((0w5 << 0w12) ++ (0wxf << 0w7) ++ (fNum t)))
336 :    
337 :     (*esac*))
338 :     | I.FUNARY{fu, f, t} =>
339 :     (case fu
340 :     of I.FCPY => floatOpMaj0C(fNum f, 0w0, 0w2, 0w1, 0w0, 0w0, fNum t)
341 :     | I.FABS => floatOpMaj0C(fNum f, 0w0, 0w3, 0w1, 0w0, 0w0, fNum t)
342 :     | I.FCNVXF => floatOpMaj0E(fNum f, 0w0, 0w5, 0w0, 0w1, 0w4, fNum t)
343 :     (*esac*))
344 : monnier 167 | I.FBRANCH{cc,f1,f2,n,t,f,long} =>
345 :     ( (* FCMP *)
346 :     floatOpMaj0C(fNum f1, fNum f2, 0w0, 0w1, 0w2, 0w0, fcond cc);
347 :     (* FTEST *)
348 :     emitWord(0wxc << 0w10);
349 :     emitWord((0w1 << 0w13) ++ (0w2 << 0w9) ++ (0w1 << 0w5));
350 :     (* B,n t *)
351 :     branchLink(0wx3a, 0, t, 0w0, nullify n)
352 :     )
353 : monnier 16 | I.BREAK(i, j) =>
354 :     (emitWord((itow i & 0wx1fff) >> 0w3);
355 :     emitWord(((itow i & 0wx7) << 0w13) & (itow j & 0wx1f)))
356 :     | I.NOP => emitInstr(I.ARITH{a=I.OR, r1=0, r2=0, t=0}, regmap)
357 :     | I.COPY _ => error "emitInstr:COPY"
358 :     | I.FCOPY _ => error "emitInstr:FCOPY"
359 :     end (*emitInstr*)
360 :     end
361 :    
362 :     (*
363 :     *)
364 :    
365 :     (*
366 : monnier 167 * $Log: hppaMC.sml,v $
367 :     * Revision 1.4 1998/09/30 19:35:40 dbm
368 :     * fixing sharing/defspec conflict
369 :     *
370 :     * Revision 1.3 1998/05/25 15:10:57 george
371 :     * Fixed RCS keywords
372 :     *
373 : monnier 16 *)

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