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/hppa/emit/hppaMC.sml
ViewVC logotype

Annotation of /sml/trunk/src/MLRISC/hppa/emit/hppaMC.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 246 - (view) (download)

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

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