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

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