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 245 - (view) (download)
Original Path: sml/branches/SMLNJ/src/compiler/CodeGen/alpha32x/alpha32xMC.sml

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

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