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/OldCGen/mips/mipsdepend.sml
ViewVC logotype

Annotation of /sml/trunk/src/compiler/OldCGen/mips/mipsdepend.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 16 - (view) (download)

1 : monnier 16 (* mipsdepend.sml
2 :     *
3 :     * COPYRIGHT (c) 1996 Bell Laboratories.
4 :     *
5 :     *)
6 :    
7 :     functor MipsInstr(structure E:ENDIAN) : MACHINSTR =
8 :     struct
9 :    
10 :     structure M = MipsInstrSet
11 :     open M
12 :    
13 :     val branchDelayedArch = true
14 :    
15 :     datatype ikind = IK_NOP | IK_JUMP | IK_INSTR
16 :    
17 :     val error = ErrorMsg.impossible
18 :    
19 :     fun instrKind instr = case instr
20 :     of M.NOP => IK_NOP
21 :     | M.JUMP _ => IK_JUMP
22 :     | M.BEQ _ => IK_JUMP
23 :     | M.BCOP1 _ => IK_JUMP
24 :     | _ => IK_INSTR
25 :    
26 :     fun isSdiBranch (BRANCH _) = true
27 :     | isSdiBranch (BRANCH_COP1 _) = true
28 :     | isSdiBranch _ = false
29 :    
30 :     val nop = M.NOP
31 :    
32 :     fun minSize (LOADF _) = 8
33 :     | minSize _ = 4
34 :    
35 :    
36 :     (* sizeOf(sdi,loc)
37 :     * returns the size of I under the current address assignment
38 :     * for labels plus true if the size if the maximum possible for the sdi.
39 :     *)
40 :     fun sizeOf (info as INFO{addrOf,...}) =
41 :     let val labelValue = M.labelValue info
42 :     val hiLabelValue = M.hiLabelValue info
43 :     val loLabelValue = M.loLabelValue info
44 :     in fn (sdi,loc) =>
45 :     let
46 :     fun lab_value (lab,k) = labelValue(POSLAB lab,k - M.constBaseRegOffset)
47 :     fun is_short_mem n = ~32764 <= n andalso n <= 32764
48 :     fun is_short_branch lab = let
49 :     val const = addrOf lab - (loc + 4)
50 :     in
51 :     is_short_mem(const div 4)
52 :     end
53 :     in
54 :     case sdi
55 :     of SETBASEADDR(lab,reg) => let
56 :     val const = M.constBaseRegOffset - (addrOf lab)
57 :     in
58 :     if is_short_mem const then (false, 4) else (true, 12)
59 :     end
60 :     | LOADADDR(_,lab,k) =>
61 :     if is_short_mem (lab_value (lab,k)) then (false,4) else (true,12)
62 :     | LOAD(_,lab,k) =>
63 :     if is_short_mem (lab_value (lab,k)) then (false,4) else (true,12)
64 :     | LOADF(_,lab,offset,_) => let
65 :     val labexp1 = (POSLAB lab,offset-M.constBaseRegOffset)
66 :     val labexp2 = (POSLAB lab,offset-M.constBaseRegOffset+4)
67 :     val labval1 = labelValue labexp1
68 :     val labval2 = labelValue labexp2
69 :     in
70 :     if (is_short_mem labval1) andalso (is_short_mem labval2)
71 :     then (false, 8)
72 :     else if (hiLabelValue labexp1) = (hiLabelValue labexp2)
73 :     then (false,16)
74 :     else (true,20)
75 :     end
76 :     | BRANCH(_,_,_,lab,_,_) =>
77 :     if is_short_branch lab then (false,4) else (true,20)
78 :     | BRANCH_COP1(_,lab,_,_) =>
79 :     if is_short_branch lab then (false,4) else (true,20)
80 :     end
81 :     end
82 :    
83 :     (* expand (I, n)
84 :     * - expands I into n bytes of machine instructions.
85 :     *)
86 :     fun expand info (sdi,size,loc) =
87 :     case sdi
88 :     of SETBASEADDR(lab,reg) =>
89 :     let val labexp = (NEGLAB lab,M.constBaseRegOffset)
90 :     in
91 :     case size
92 :     of 4 => [M.ADD(M.baseReg,reg,LabelOp labexp)]
93 :     | 12 => [M.LUI(M.baseReg,HiLabOff labexp),
94 :     M.ADD(M.baseReg,M.baseReg,LoLabOp labexp),
95 :     M.ADD(M.baseReg,reg,RegOp M.baseReg)]
96 :     | _ => error "MipsInstrSet.expand: SETBASEADDR"
97 :     end
98 :     | LOADADDR(r,lab,k) =>
99 :     let val labexp = (POSLAB lab,~M.constBaseRegOffset+k)
100 :     in case size
101 :     of 4 => [M.ADD(r,M.baseReg,LabelOp labexp)]
102 :     | 12 => [M.LUI(r,HiLabOff labexp),
103 :     M.ADD(r,r,LoLabOp labexp),
104 :     M.ADD(r,M.baseReg,RegOp r)]
105 :     | _ => error "MipsInstrSet.expand: LOADADDR"
106 :     end
107 :     | LOAD(r,lab,k) =>
108 :     let val labexp = (POSLAB lab,~M.constBaseRegOffset+k)
109 :     in case size
110 :     of 4 => [M.LW(r,M.baseReg,LabOff labexp)]
111 :     | 12 => [M.LUI(r,HiLabOff labexp),
112 :     M.ADD(r,M.baseReg,RegOp r),
113 :     M.LW(r,r,LoLabOff labexp)]
114 :     | _ => error "MipsInstrSet.expand: LOAD"
115 :     end
116 :     | LOADF(fp',lab,offset,tmpR) =>
117 :     let val Freg' fp = reg_rep fp'
118 :     val labexp1 = (POSLAB lab,offset-M.constBaseRegOffset)
119 :     val labexp2 = (POSLAB lab,offset-M.constBaseRegOffset+4)
120 :     val lowOff = E.low_order_offset
121 :     in case size
122 :     of 8 =>
123 :     [M.LWC1(Freg(fp+lowOff),M.baseReg,LabOff labexp1),
124 :     M.LWC1(Freg(fp+1-lowOff),M.baseReg,LabOff labexp2)]
125 :     | 16 =>
126 :     [M.LUI(tmpR,HiLabOff labexp1),
127 :     M.ADD(tmpR,tmpR,RegOp M.baseReg),
128 :     M.LWC1(Freg(fp+lowOff),tmpR,LoLabOff labexp1),
129 :     M.LWC1(Freg(fp+1-lowOff),tmpR,LoLabOff labexp2)]
130 :     | 20 =>
131 :     [M.LUI(tmpR,HiLabOff labexp1),
132 :     M.ADD(tmpR,tmpR,LoLabOp labexp1),
133 :     M.ADD(tmpR,tmpR,RegOp M.baseReg),
134 :     M.LWC1(Freg(fp+lowOff),tmpR,Immed16Off 0),
135 :     M.LWC1(Freg(fp+1-lowOff),tmpR,Immed16Off 4)]
136 :     | _ => error "MipsInstrSet.expand: LOADF"
137 :     end
138 :     | BRANCH(bool,rs,rt,tlabel,tmpR,flabel) =>
139 :     (case size
140 :     of 4 => [M.BEQ(bool,rs,rt,LabOff(POSLAB tlabel,0))]
141 :    
142 :     | 20 =>
143 :     let val labexp = (POSLAB tlabel,~M.constBaseRegOffset)
144 :     in
145 :     [M.BEQ(not bool,rs,rt,LabOff(POSLAB flabel,0)),
146 :    
147 :     M.LUI(tmpR,HiLabOff labexp),
148 :     M.ADD(tmpR,tmpR,LoLabOp labexp),
149 :     M.ADD(tmpR,tmpR,RegOp M.baseReg),
150 :     M.JUMP(tmpR)]
151 :     end
152 :     | _ => error "MipsInstrSet.expand: BRANCH")
153 :     | BRANCH_COP1(bool,tlabel,tmpR,flabel) =>
154 :     (case size
155 :     of 4 => [M.BCOP1(bool,LabOff(POSLAB tlabel,0))]
156 :     | 20 =>
157 :     let val labexp = (POSLAB tlabel,~M.constBaseRegOffset)
158 :     in
159 :     [M.BCOP1(not bool,LabOff(POSLAB flabel,0)),
160 :    
161 :     M.LUI(tmpR,HiLabOff labexp),
162 :     M.ADD(tmpR,tmpR,LoLabOp labexp),
163 :     M.ADD(tmpR,tmpR,RegOp M.baseReg),
164 :     M.JUMP(tmpR)]
165 :     end
166 :     | _ => error "MipsInstrSet.expand: BRANCH_COP1")
167 :    
168 :     (*
169 :     * Resources: Mem+($1-$31)+($f0,f1-$f31)+fcc+npc+LO+HI
170 :     *)
171 :     val numResources = 68
172 :    
173 :     local
174 :     structure RId =
175 :     struct
176 :     val mem = 0
177 :     fun reg r = case reg_rep r
178 :     of Reg' 0 => []
179 :     | Reg' i => [i]
180 :     | _ => error "MipsInstrSet.RId.reg"
181 :     fun freg r = case reg_rep r
182 :     of Freg' i => [32+i]
183 :     | _ => error "MipsInstrSet.RId.freg"
184 :     fun fregd r = case reg_rep r
185 :     of Freg' i => [32+i, 32+1+i]
186 :     | _ => error "MipsInstrSet.RId.fregd"
187 :     fun anyreg r = case reg_rep r
188 :     of Reg' 0 => []
189 :     | Reg' i => [i]
190 :     | Freg' i => [32+i]
191 :     val fcc = 64
192 :     val npc = 65
193 :     val LO = 66
194 :     val HI = 67
195 :    
196 :     val Reg'(alloc) = reg_rep M.allocReg (* resource no. for reg = reg no. *)
197 :     val Reg'(exnptr) = reg_rep M.exnptrReg
198 :     end
199 :    
200 :     fun is_allocR reg = reg_eq(reg,M.allocReg)
201 :     fun arithOpndUse opnd = case opnd of RegOp r => RId.reg r | _ => []
202 :    
203 :     val allR = let fun f(~1,l) = l | f(i,l) = f(i-1,i::l)
204 :     in f(numResources-1,[])
205 :     end
206 :     local
207 :     open RId
208 :     in
209 :     fun arith_ud(rd,rs,ea) =
210 :     (mem::alloc::exnptr::(reg rs @ arithOpndUse ea), reg rd)
211 :     fun logical_ud(rd,rs,ea) = (reg rs @ arithOpndUse ea, reg rd)
212 :     fun arith3_ud(rd,rt,rs) =
213 :     (mem::alloc::exnptr::(reg rt @ reg rs), reg rd)
214 :     fun logical3_ud(rd,rt,rs) = (reg rs @ reg rt, reg rd)
215 :    
216 :     fun double_float_ud(fd,fs,ft) =
217 :     (fregd fs @ fregd ft, fregd fd)
218 :    
219 :     fun mult_ud(rt,rs) =
220 :     (reg rs @ reg rt, [LO,HI])
221 :    
222 :     fun load_ud(rt,base,_) = (mem::npc::anyreg base,anyreg rt)
223 :     fun store_ud(rt,base,_) = let val use = anyreg rt @ anyreg base
224 :     in if is_allocR base then (use, [])
225 :     else (use,[mem])
226 :     end
227 :     end
228 :     in
229 :    
230 :     fun rUseDef inst =
231 :     case inst
232 :     of M.NOP => ([], [])
233 :    
234 :     | M.BEQ(_,rt,rs,_) => (RId.reg rs @ RId.reg rt, [RId.npc])
235 :     | M.JUMP rs => (RId.reg rs, [RId.npc])
236 :     | M.BCOP1 _ => ([RId.fcc], [RId.npc])
237 :     | M.BREAK _ => (allR, allR)
238 :    
239 :     | M.SLT arg => logical_ud arg
240 :     | M.SLTU arg => logical_ud arg
241 :     | M.FCMP(_,rt,rs) => (RId.fregd rt @ RId.fregd rs, [RId.fcc])
242 :    
243 :     | M.AND arg => logical_ud arg
244 :     | M.OR arg => logical_ud arg
245 :     | M.XOR arg => logical_ud arg
246 :    
247 :     | M.ADD(arg as (rd,_,rs)) => let
248 :     val (u,d) = arith_ud arg
249 :     in if is_allocR rd then (u, RId.mem::d) else (RId.alloc::u, d)
250 :     end
251 :     | M.ADDU arg => logical_ud arg
252 :     | M.SUB arg => arith3_ud arg
253 :     | M.SUBU arg => logical3_ud arg
254 :    
255 :     | M.MFLO rd => ([RId.LO], RId.reg rd)
256 :     | M.MFHI rd => ([RId.HI], RId.reg rd)
257 :    
258 :     | M.MULT arg => mult_ud arg
259 :     | M.MULTU arg=> mult_ud arg
260 :     | M.DIV arg => mult_ud arg
261 :     | M.DIVU arg => mult_ud arg
262 :    
263 :     | M.NEG_DOUBLE(fd,fs) => (RId.fregd fs, RId.fregd fd)
264 :     | M.ABS_DOUBLE(fd,fs) => (RId.fregd fs, RId.fregd fd)
265 :     | M.MUL_DOUBLE arg => double_float_ud arg
266 :     | M.DIV_DOUBLE arg => double_float_ud arg
267 :     | M.ADD_DOUBLE arg => double_float_ud arg
268 :     | M.SUB_DOUBLE arg => double_float_ud arg
269 :     | M.CVTI2D(dst,src) => (RId.freg src,RId.fregd dst)
270 :     | M.MTC1(src,dst) => (RId.reg src,RId.freg dst)
271 :    
272 :     | M.MOV_DOUBLE(fd,fs) => (RId.fregd fs, RId.fregd fd)
273 :    
274 :     | M.LBU arg => load_ud arg
275 :     | M.LW arg => load_ud arg
276 :     | M.LWC1 arg => load_ud arg
277 :     | M.SB arg => store_ud arg
278 :     | M.SW arg => store_ud arg
279 :     | M.SWC1 arg => store_ud arg
280 :    
281 :     | M.LUI(rd,_) => ([], RId.reg rd)
282 :    
283 :     | M.SLL(rd,rt,_) => (RId.reg rt, RId.reg rd)
284 :     | M.SRA(rd,rt,_) => (RId.reg rt, RId.reg rd)
285 :     | M.SRL(rd,rt,_) => (RId.reg rt, RId.reg rd)
286 :     | M.SLLV arg => logical3_ud arg
287 :     | M.SRAV arg => logical3_ud arg
288 :     | M.SRLV arg => logical3_ud arg
289 :    
290 :    
291 :     fun usesReg (r,I) = let val (ul,_) = rUseDef I
292 :     val [rR] = RId.anyreg r
293 :     in List.exists (fn u => u = rR) ul
294 :     end
295 :    
296 :     fun mayNeedNop (M.LBU _) = 1
297 :     | mayNeedNop (M.LW _) = 1
298 :     | mayNeedNop (M.LWC1 _) = 1
299 :     | mayNeedNop (M.FCMP _) = 1
300 :     | mayNeedNop (M.MFLO _) = 2
301 :     | mayNeedNop (M.MFHI _) = 2
302 :     | mayNeedNop (M.MTC1 _) = 1
303 :     | mayNeedNop (M.BEQ _) = 1
304 :     | mayNeedNop (M.BCOP1 _) = 1
305 :     | mayNeedNop (M.JUMP _) = 1
306 :     | mayNeedNop _ = 0
307 :    
308 :     fun multop (MULT _) = true
309 :     | multop (MULTU _) = true
310 :     | multop (DIV _) = true
311 :     | multop (DIVU _) = true
312 :     | multop _ = false
313 :    
314 :     fun needsNop(instr, MFLO _::_) = if multop instr then 2 else 0
315 :     | needsNop(instr, _::MFLO _::_) = if multop instr then 1 else 0
316 :     | needsNop(instr, MFHI _::_) = if multop instr then 2 else 0
317 :     | needsNop(instr, _::MFHI _::_) = if multop instr then 1 else 0
318 :     | needsNop(next,prev::rest) =
319 :     (case prev
320 :     of M.LBU(rd,_,_) => if usesReg(rd,next) then 1 else 0
321 :     | M.LW(rd,_,_) => if usesReg(rd,next) then 1 else 0
322 :     | M.LWC1(fd,_,_) => if usesReg(fd,next) then 1 else 0
323 :     | M.FCMP _ => (case next of M.BCOP1 _ => 1 | _ => 0)
324 :     | M.MTC1(_,fs) => if usesReg(fs,next) then 1 else 0
325 :     | _ => (case (instrKind next,instrKind prev)
326 :     of (IK_JUMP,IK_JUMP) => 1
327 :     | _ => 0))
328 :     | needsNop _ = 0
329 :    
330 :     (* R2000 latencies *)
331 :     fun latency (M.LW _) = 2
332 :     | latency (M.LWC1 _) = 2
333 :     | latency (M.LBU _) = 2
334 :     | latency (M.MULT _) = 11
335 :     | latency (M.MULTU _) = 11
336 :     | latency (M.DIV _) = 36
337 :     | latency (M.DIVU _) = 36
338 :     | latency (M.JUMP _) = 2
339 :     | latency (M.BEQ _) = 2
340 :     | latency (M.BCOP1 _) = 2
341 :     | latency (M.FCMP _) = 2
342 :     | latency (M.ADD_DOUBLE _) = 2
343 :     | latency (M.MUL_DOUBLE _) = 5
344 :     | latency (M.DIV_DOUBLE _) = 19
345 :     | latency _ = 1
346 :    
347 :     end
348 :     end
349 :    
350 :     (*
351 :     * $Log: mipsdepend.sml,v $
352 :     * Revision 1.3 1997/08/19 14:46:35 george
353 :     * Bug fix for bug 1222 (ref assignment not performed before overflow)
354 :     *
355 :     * Revision 1.2 1997/05/05 19:58:15 george
356 :     * Add the allocation pointer to the list of source registers for the
357 :     * tvs instruction. This fixed the subtle bug on interactions between
358 :     * the allocation-pointer-adjustment instruction and the addi
359 :     * instruction. -- george
360 :     *
361 :     * Revision 1.1.1.1 1997/01/14 01:38:38 george
362 :     * Version 109.24
363 :     *
364 :     *)

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