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/compiler/CodeGen/alpha32x/alpha32xMC.sml
ViewVC logotype

Annotation of /sml/trunk/src/compiler/CodeGen/alpha32x/alpha32xMC.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 16 - (view) (download)

1 : monnier 16 (* alpha32MC.sml
2 :     *
3 :     * COPYRIGHT (c) 1996 Bell Laboratories.
4 :     *
5 :     *)
6 :    
7 :     functor Alpha32XMCEmitter
8 :     (structure Instr : ALPHA32INSTR
9 :     structure FlowGraph : FLOWGRAPH
10 :     sharing FlowGraph.I = Instr) : EMITTER_NEW =
11 :     struct
12 :     structure I = Instr
13 :     structure F = FlowGraph
14 :     structure C = I.C
15 :    
16 :     structure LE = LabelExp
17 :    
18 :     val << = Word.<<
19 :     val >> = Word.>>
20 :     val ~>> = Word.~>>
21 :     val ++ = Word.orb
22 :     val & = Word.andb
23 :     infix << >> ~>> ++ &
24 :    
25 :     val itow = Word.fromInt
26 :    
27 :     fun error msg = ErrorMsg.impossible ("Alpha32MCEmitter." ^ msg)
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 :     (* Alpha32 is low endian *)
43 :     fun emitWord n = (emitByte(n & 0w255); emitByte((n >> 0w8) & 0w255))
44 :     fun defineLabel lab = ()
45 :     fun emitstring s = Word8Vector.app emitbyte (Byte.stringToBytes s)
46 :     fun comment msg = ()
47 :     fun init n = (CodeString.init n; loc:=0)
48 :     fun pseudoOp pOp = F.P.emitValue{pOp=pOp, loc= !loc, emit=emitbyte}
49 :    
50 :     open Label
51 :     fun emitMCInstr(instr,regmap) = let
52 :     datatype register = REG | FREG
53 :    
54 :     val rMap = Intmap.map regmap
55 :     val rNum = itow o rMap
56 :     val fNum = rNum
57 :    
58 :     local
59 :     fun split i = let
60 :     val w = Word.fromInt i
61 :     val hi = Word.~>>(w, 0w16)
62 :     val lo = Word.andb(w, 0w65535)
63 :     in if lo < 0w32768 then (hi, lo) else (hi+0w1, lo-0w65536)
64 :     end
65 :     in
66 :     fun high n = #1 (split n)
67 :     fun low n = #2 (split n)
68 :     end
69 :    
70 :     fun immed16(I.IMMop i) =
71 :     (if i < ~32768 orelse i > 32767 then
72 :     error ("immed16 - " ^ Int.toString i) else ();
73 :     (itow i & 0w65535))
74 :     | immed16(I.LOLABop labexp) = low (LE.valueOf labexp)
75 :     | immed16(I.HILABop labexp) = high (LE.valueOf labexp)
76 :     | immed16 _ = error "immed16"
77 :    
78 :     fun immed8(I.IMMop i) =
79 :     (if i < 0 orelse i > 255 then
80 :     error ("immed8 - " ^ Int.toString i) else ();
81 :     (itow i & 0w255))
82 :     | immed8 _ = error "immed8"
83 :    
84 :     fun immed21 i =
85 :     (if i < ~1048576 orelse i > 1048575 then
86 :     error ("immed21 - " ^ Int.toString i) else ();
87 :     itow i & 0w2097151)
88 :    
89 :    
90 :     fun Branch typ (opcode, ra', lab) = let
91 :     val ra = (case typ of REG => rNum ra' | FREG => fNum ra')
92 :     val disp = (((Label.addrOf lab) - !loc - 4) div 4)
93 :     val testdisp = immed21 disp
94 :     val lowdisp = testdisp & 0w65535
95 :     in
96 :     emitWord lowdisp;
97 :     emitWord((opcode << 0w10) ++ (ra << 0w5) ++ (testdisp >> 0w16))
98 :     end
99 :    
100 :     val branch = Branch REG
101 :     val fbranch = Branch FREG
102 :    
103 :     fun Memory typ (opcode, ra', rb, disp) = let
104 :     val ra = (case typ of REG => rNum ra' | FREG => fNum ra')
105 :     in
106 :     emitWord (disp);
107 :     emitWord((itow opcode << 0w10) ++ (ra << 0w5) ++ rNum rb)
108 :     end
109 :    
110 :     val memory = Memory REG
111 :     val fmemory = Memory FREG
112 :    
113 :     fun MemoryW typ (opcode, ra', rb, disp) = let
114 :     val ra = (case typ of REG => rNum ra' | FREG => fNum ra')
115 :     in
116 :     emitWord disp;
117 :     emitWord((itow opcode << 0w10) ++ (ra << 0w5) ++ rNum rb)
118 :     end
119 :    
120 :     val memoryW = MemoryW REG
121 :    
122 :     val fmemoryW = MemoryW FREG
123 :    
124 :     fun Jump (opcode, bits, {r=ra, b=rb, d=disp}) =
125 :     let
126 :     (* disp is just a hint to the alpha - it does not affect destination *)
127 :     val _ = if disp <> 0 then error "Jump" else ()
128 :     val d = (itow disp & 0w16383) ++ (itow bits << 0w14)
129 :     in
130 :     memory (opcode, ra, rb, itow disp)
131 :     end
132 :    
133 :     fun Operate (opcode, func, ra, I.REGop rb, rc) =
134 :     (emitWord((func << 0w5) ++ rNum rc);
135 :     emitWord((opcode << 0w10) ++ (rNum ra << 0w5) ++ rNum rb))
136 :     | Operate (opcode, func, ra, opnd, rc) =
137 :     let
138 :     val testi = immed8 opnd
139 :     in
140 :     emitWord((testi << 0w13) ++ 0w4096 ++ (func << 0w5) ++ rNum rc);
141 :     emitWord((opcode << 0w10) ++ (rNum ra << 0w5) ++ (testi >> 0w3))
142 :     end
143 :    
144 :     fun FOperate (opcode, func, fa, fb, fc) =
145 :     (emitWord((func << 0w5) ++ fNum fc);
146 :     emitWord((opcode << 0w10) ++ (fNum fa << 0w5) ++ fNum fb))
147 :    
148 :     fun Pall(opcode) = (emitWord(opcode & 0wxffff); emitWord(opcode >> 0w16))
149 :    
150 :     val zeroR = 31
151 :     in
152 :     case instr of
153 :     I.DEFFREG _ => error "DEFFREG"
154 :     | I.LDA{r, b, d} => memoryW(8, r, b, immed16 d)
155 :     | I.LDAH{r, b, d} => memoryW(9, r, b, immed16 d)
156 :     | I.LOAD{ldOp, r, b ,d, ...} =>
157 :     (case ldOp
158 :     of I.LDL => memory(40, r, b, immed16 d)
159 :     | I.LDQ => memory(41, r, b, immed16 d)
160 :     | I.LDQ_U => memory(11, r, b, immed16 d)
161 :     (* esac *))
162 :     | I.STORE{stOp, r, b, d, ...} =>
163 :     (case stOp
164 :     of I.STL => memory(44, r, b, immed16 d)
165 :     | I.STQ => memory(45, r, b, immed16 d)
166 :     | I.STQ_U => memory(15, r, b, immed16 d)
167 :     (* esac *))
168 :    
169 :     | I.FLOAD{ldOp, r, b, d, ...} =>
170 :     (case ldOp
171 :     of I.LDT => fmemory(35, r, b, immed16 d)
172 :     | I.LDS => fmemory(34, r, b, immed16 d)
173 :     (*esac*))
174 :    
175 :     | I.FSTORE{stOp=I.STT, r, b, d, ...} => fmemory(39, r, b, immed16 d)
176 :    
177 :     | I.JMPL (arg, _) => Jump(26, 0, arg)
178 :     | I.JSR(arg,_,_) => Jump(26, 1, arg)
179 :     | I.BRANCH(brOp, reg, lab) =>
180 :     (case brOp
181 :     of I.BR => branch(0w48, reg, lab)
182 :     | I.BEQ => branch(0w57, reg, lab)
183 :     | I.BGE => branch(0w62, reg, lab)
184 :     | I.BGT => branch(0w63, reg, lab)
185 :     | I.BLE => branch(0w59, reg, lab)
186 :     | I.BLT => branch(0w58, reg, lab)
187 :     | I.BNE => branch(0w61, reg, lab)
188 :     | I.BLBS => branch(0w60, reg, lab)
189 :     | I.BLBC => branch(0w56, reg, lab)
190 :     (*esac*))
191 :    
192 :     | I.FBRANCH(fbrOp, freg, lab) =>
193 :     (case fbrOp
194 :     of I.BEQ => fbranch(0w49, freg, lab)
195 :     | I.BGE => fbranch(0w54, freg, lab)
196 :     | I.BGT => fbranch(0w55, freg, lab)
197 :     | I.BLE => fbranch(0w51, freg, lab)
198 :     | I.BLT => fbranch(0w50, freg, lab)
199 :     | I.BNE => fbranch(0w53, freg, lab)
200 :     | _ => error "FBRANCH"
201 :     (*esac*))
202 :    
203 :     | I.OPERATE{oper, ra, rb, rc} =>
204 :     (case oper
205 :     of I.ZAP => Operate(0w18, 0w48, ra, rb, rc)
206 :     | I.ADDL => Operate(0w16, 0w0, ra, rb, rc)
207 :     | I.ADDQ => Operate(0w16, 0w32, ra, rb, rc)
208 :     | I.SUBL => Operate(0w16, 0w9, ra, rb, rc)
209 :     | I.SUBQ => Operate(0w16, 0w41, ra, rb, rc)
210 :     | I.MULL => Operate(0w19, 0w0, ra, rb, rc)
211 :     | I.S4ADDL => Operate(0w16, 0w2, ra, rb, rc)
212 :     | I.S8ADDL => Operate(0w16, 0w18, ra, rb, rc)
213 :     | I.CMPULE => Operate(0w16, 0w61, ra, rb, rc)
214 :     | I.CMPULT => Operate(0w16, 0w29, ra, rb, rc)
215 :     | I.CMPEQ => Operate(0w16, 0w45, ra, rb, rc)
216 :     | I.CMPLE => Operate(0w16, 0w109, ra, rb, rc)
217 :     | I.CMPLT => Operate(0w16, 0w77, ra, rb, rc)
218 :     | I.SGNXL => Operate(0w16, 0w0, ra, rb, rc) (* ADDL *)
219 :     | I.AND => Operate(0w17, 0w0, ra, rb, rc)
220 :     | I.BIS => Operate(0w17, 0w32, ra, rb, rc)
221 :     | I.XOR => Operate(0w17, 0w64, ra, rb, rc)
222 :     | I.SRA => Operate(0w18, 0w60, ra, rb, rc)
223 :     | I.SRL => Operate(0w18, 0w52, ra, rb, rc)
224 :     | I.SLL => Operate(0w18, 0w57, ra, rb, rc)
225 :     | I.INSBL => Operate(0w18, 0w11, ra, rb, rc)
226 :     | I.EXTBL => Operate(0w18, 0w6, ra, rb, rc)
227 :     | I.EXTQH => Operate(0w18, 0w122, ra, rb, rc)
228 :     | I.MSKBL => Operate(0w18, 0w2, ra, rb, rc)
229 :     | I.MSKLH => Operate(0w18, 0w98, ra, rb, rc)
230 :     (*esac*))
231 :     | I.PSEUDOARITH _ => error "emitInstr:PSEUDOOP"
232 :     | I.OPERATEV{oper, ra, rb, rc} =>
233 :     (case oper
234 :     of I.ADDLV => Operate(0w16, 0w64, ra, rb, rc)
235 :     | I.SUBLV => Operate(0w16, 0w73, ra, rb, rc)
236 :     | I.MULLV => Operate(0w19, 0w64, ra, rb, rc)
237 :     (*esac*))
238 :     | I.FOPERATE{oper, fa, fb, fc} =>
239 :     (case oper
240 :     of I.CPYS => FOperate(0w23, 0w32, fa, fb, fc)
241 :     | I.CPYSN => FOperate(0w23, 0w33, fa, fb, fc)
242 :     | I.CMPTUN => FOperate(0w22, 0wx5a4, fa, fb, fc)
243 :     | I.CMPTEQ => FOperate(0w22, 0wx5a5, fa, fb, fc)
244 :     | I.CMPTLT => FOperate(0w22, 0wx5a6, fa, fb, fc)
245 :     | I.CMPTLE => FOperate(0w22, 0wx5a7, fa, fb, fc)
246 :     | I.CVTQT => FOperate(0w22, 0wx0be, fa, fb, fc)
247 :     | I.CVTLQ => FOperate(0w23, 0w16, fa, fb, fc)
248 :     (*esac*))
249 :     | I.FOPERATEV{oper, fa, fb, fc} =>
250 :     (case oper
251 :     of I.ADDT => FOperate(0w22, 0wx5a0, fa, fb, fc)
252 :     | I.SUBT => FOperate(0w22, 0wx5a1, fa, fb, fc)
253 :     | I.MULT => FOperate(0w22, 0wx5a2, fa, fb, fc)
254 :     | I.DIVT => FOperate(0w22, 0wx5a3, fa, fb, fc) (* chopped *)
255 :     | I.CVTTQ => FOperate(0w22, 0wx02f, fa, fb, fc) (* towards zero*)
256 :     (*esac*))
257 :     | I.TRAPB => memoryW(24, zeroR, zeroR, 0w0)
258 :     | I.CALL_PAL{code, ...} =>
259 :     (case code
260 :     of I.BPT => Pall(0wx80)
261 :     | I.BUGCHK => Pall(0wx81)
262 :     | I.CALLSYS => Pall(0wx83)
263 :     | I.GENTRAP => Pall(0wxaa)
264 :     | I.IMB => Pall(0wx86)
265 :     | I.RDUNIQUE => Pall(0wx9e)
266 :     | I.WRUNIQUE => Pall(0wx9f)
267 :     (*esac*))
268 :     | I.COPY _ => error "emitInstr:COPY"
269 :     | I.FCOPY _ => error "emitInstr:FCOPY"
270 :     end
271 :    
272 :     fun emitInstr(i,regmap) = emitMCInstr(i,regmap)
273 :     end
274 :    
275 :    
276 :    
277 :    
278 :    
279 :    
280 :    
281 :    
282 :     (*
283 :     * $Log: alpha32xMC.sml,v $
284 :     * Revision 1.9 1998/02/12 18:55:58 jhr
285 :     * Removed obsolete reference to System.Tags.
286 :     *
287 :     * Revision 1.8 1997/09/17 20:01:13 george
288 :     * Added support for S4ADDL and S8ADDL
289 :     *
290 :     * Revision 1.7 1997/08/29 11:03:48 george
291 :     * Added code to handle the new LDS, CVTLQ, DIVL, and DIVLU instructions.
292 :     *
293 :     * Revision 1.6 1997/07/28 20:04:37 george
294 :     * Added support for regions
295 :     *
296 :     * Revision 1.5 1997/07/17 12:35:39 george
297 :     * The regmap is now represented as an int map rather than using arrays.
298 :     *
299 :     * Revision 1.4 1997/03/21 21:20:20 george
300 :     * got rid of LADDR has a pseudo-instruction to load labels
301 :     *
302 :     * Revision 1.3 1997/03/21 13:59:33 george
303 :     * added support for CALL_PAL
304 :     *
305 :     * Revision 1.2 1997/03/06 19:07:22 george
306 :     * Displacement values for memory instructions are no longer plain integers.
307 :     *
308 :     * Revision 1.1.1.1 1997/01/14 01:38:09 george
309 :     * Version 109.24
310 :     *
311 :     *)

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