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/hppaJumps.sml
ViewVC logotype

Annotation of /sml/branches/SMLNJ/src/MLRISC/hppa/hppaJumps.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 223 - (view) (download)

1 : monnier 16 (* hppaJumps.sml --- information to resolve jumps.
2 :     *
3 :     * COPYRIGHT (c) 1996 Bell Laboratories.
4 :     *
5 :     *)
6 :     functor HppaJumps
7 :     (structure Instr:HPPAINSTR
8 :     structure Shuffle:HPPASHUFFLE
9 :     sharing Shuffle.I = Instr) : SDI_JUMPS =
10 :     struct
11 :     structure I = Instr
12 :     structure C = Instr.C
13 :     structure LE = LabelExp
14 :     structure Const = I.Constant
15 :    
16 :     fun error msg = MLRiscErrorMsg.impossible ("HppaJumps." ^ msg)
17 :    
18 :     val branchDelayedArch = false
19 :    
20 : monnier 167 fun minSize(I.COPY _) = 0
21 :     | minSize(I.FCOPY _) = 0
22 :     | minSize(I.FBRANCH _) = 12 (* FCMP/FTEST/B *)
23 :     | minSize(I.BLR{labs,...}) = 8 + 8 * length labs (* FCMP/FTEST/B *)
24 :     | minSize _ = 4
25 :    
26 : monnier 16 fun maxSize (I.BCOND _) = 20
27 :     | maxSize (I.BCONDI _) = 20
28 :     | maxSize (I.B _) = 16
29 : monnier 167 | maxSize (I.FBRANCH _)= 24
30 : monnier 16 | maxSize (I.COPY _) = error "maxSize:COPY"
31 :     | maxSize (I.FCOPY _) = error "maxSize:FCOPY"
32 :     | maxSize _ = 4
33 :    
34 :     fun mayNeedNops _ = 0
35 :     fun needsNop _ = 0
36 :    
37 :     fun isSdi instr = let
38 :     fun opnd (I.LabExp _) = true
39 :     | opnd (I.ConstOp _) = true
40 :     | opnd _ = false
41 :     in
42 :     case instr
43 :     of I.BCOND _ => true
44 :     | I.BCONDI _ => true
45 :     | I.B _ => true
46 : monnier 167 | I.FBRANCH _ => true
47 :     | I.BLR _ => true
48 : monnier 16 | I.LDO{i, ...} => opnd i
49 :     | I.STORE{d, ...} => opnd d
50 :     | I.ARITHI{i, ...} => opnd i
51 :     | I.LOADI{i, ...} => opnd i
52 :     | I.FCOPY _ => true
53 :     | I.COPY _ => true
54 :     | _ => false
55 :     end
56 :    
57 :     fun im11 n = ~1024 <= n andalso n < 1024
58 :     fun im12 n = ~2048 <= n andalso n < 2048
59 :     fun im14 n = ~8192 <= n andalso n < 8192
60 :     fun im17 n = ~65536 <= n andalso n < 65536
61 :    
62 :     fun sdiSize(instr, regmap, labMap, loc) = let
63 :     fun branchOffset lab = ((labMap lab) - loc - 8) div 4
64 :     fun branch lab = let
65 :     val offset = branchOffset lab
66 :     in
67 :     if im12 offset then 4 else if im17 offset then 8 else 20
68 :     end
69 :     fun memDisp(c, short, long) = if im14(c) then short else long
70 :     val lookup = Intmap.map regmap
71 :     in
72 :     case instr
73 :     of I.LDO{i=I.LabExp(lexp, _), ...} => memDisp(LE.valueOf lexp, 4, 12)
74 :     | I.LDO{i=I.ConstOp c, ...} => memDisp(Const.valueOf c, 4, 8)
75 :     | I.LOADI{i=I.ConstOp c, ...} => memDisp(Const.valueOf c, 4, 12)
76 :     | I.LOADI{i=I.LabExp(lexp, _), ...} => memDisp(LE.valueOf lexp, 4, 12)
77 :     | I.STORE{d=I.ConstOp c, ...} => memDisp(Const.valueOf c, 4, 12)
78 :     | I.ARITHI{ai, i=I.ConstOp c, ...} => let
79 :     fun arithImmed() = if im11(Const.valueOf c) then 4 else 12
80 :     in
81 :     case ai
82 :     of I.ADDI => arithImmed()
83 :     | I.ADDIO => arithImmed()
84 :     | I.SUBI => arithImmed()
85 :     | I.SUBIO => arithImmed()
86 :     | _ => error "sdiSize: ARITHI LabelExp"
87 :     (*esac*)
88 :     end
89 :     | I.ARITHI{ai, i=I.LabExp(lexp,_), ...} => let
90 :     fun arithImmed() = if im11(LabelExp.valueOf lexp) then 4 else 12
91 :     in
92 :     case ai
93 :     of I.ADDI => arithImmed()
94 :     | I.ADDIO => arithImmed()
95 :     | I.SUBI => arithImmed()
96 :     | I.SUBIO => arithImmed()
97 :     | _ => error "sdiSize: ARITHI LabelExp"
98 :     (*esac*)
99 :     end
100 :     | I.BCOND{t, ...} => branch t
101 :     | I.BCONDI{t, ...} => branch t
102 :     | I.B{lab, ...} => if im17 (branchOffset lab) then 4 else 16
103 : monnier 167 | I.FBRANCH{t, ...} => if im17 (branchOffset t) then 12 else 24
104 :     | I.BLR{labs,...} => let
105 :     val l = length labs * 8
106 :     fun badOffsets(t::ts,n) =
107 :     not(im17(branchOffset t + n)) orelse badOffsets(ts,n+2)
108 :     | badOffsets([],n) = false
109 :     in l + (if badOffsets(labs,2) then 20 else 8)
110 :     end
111 : monnier 16 | I.COPY{impl=ref(SOME l), ...} => 4 * length l
112 :     | I.FCOPY{impl=ref(SOME l), ...} => 4 * length l
113 :     | I.COPY{dst, src, impl, tmp} => let
114 :     val instrs = Shuffle.shuffle {regMap=lookup, temp=tmp, dst=dst, src=src}
115 :     in impl := SOME(instrs); 4 * length instrs
116 :     end
117 :     | I.FCOPY{dst, src, impl, tmp} => let
118 :     val instrs = Shuffle.shufflefp {regMap=lookup, temp=tmp, dst=dst, src=src}
119 :     in impl := SOME instrs; 4 * length instrs
120 :     end
121 :     | _ => error "sdiSize"
122 :     end
123 :    
124 :     fun longJump{lab, n} = let
125 :     val baseDisp = LE.MINUS(LE.LABEL lab, LE.CONST 8192)
126 :     val labOpnd = (baseDisp, I.T)
127 :     val baseptrR = 8
128 :     in
129 :     (* Note: A better sequence would be to use ADDIL, however
130 :     * the expansion is done after register allocation and
131 :     * ADDIL defines %r1.
132 :     *)
133 :     [I.LDIL{i=I.HILabExp labOpnd, t=C.asmTmpR},
134 :     I.LDO{i=I.LOLabExp labOpnd, b=C.asmTmpR, t=C.asmTmpR},
135 :     I.ARITH{a=I.ADD, r1=baseptrR, r2=C.asmTmpR, t=C.asmTmpR},
136 :     I.BV{x=0, labs=[lab], b=C.asmTmpR, n=n}]
137 :     end
138 :    
139 :     fun split11 n = let
140 :     val w = Word.fromInt(n)
141 :     in (Word.toIntX(Word.~>>(w, 0w11)), Word.toIntX(Word.andb(w, 0wx7ff)))
142 :     end
143 :    
144 :     fun split11X n = let
145 :     val w = Word.fromInt(n)
146 :     val hi' = Word.~>>(w, 0w11)
147 :     val lo' = Word.andb(w, 0wx7ff)
148 :     val (hi,lo) =
149 :     if Word.<=(lo', 0wx3ff) then (hi', lo') else (hi'+0w1, lo'-0wx800)
150 :     in (Word.toIntX hi, Word.toIntX lo)
151 :     end
152 :    
153 :     fun loadIndexed I.LDW = I.LDWX
154 :     | loadIndexed I.LDH = I.LDHX
155 :     | loadIndexed I.LDB = I.LDBX
156 :    
157 :     fun expand(I.LDO{i=I.LabExp lexp, t, b}, size) =
158 :     (case size
159 :     of 4 => [I.LDO{i=I.LabExp lexp, b=b, t=t}]
160 :     | 12 => [I.LDIL{i=I.HILabExp lexp, t=C.asmTmpR},
161 :     I.LDO{i=I.LOLabExp lexp, b=C.asmTmpR, t=C.asmTmpR},
162 :     I.ARITH{a=I.ADD, r1=C.asmTmpR, r2=b, t=t}]
163 :     (*esac*))
164 :     | expand(I.LDO{i=I.ConstOp c, t, b}, size) =
165 :     (case size
166 :     of 4 => [I.LDO{i=I.IMMED(Const.valueOf c), t=t, b=b}]
167 :     | 8 => let
168 :     val (hi, lo) = split11(Const.valueOf c)
169 :     in
170 :     [I.LDIL{i=I.IMMED hi, t=C.asmTmpR},
171 :     I.LDO{i=I.IMMED lo, b=C.asmTmpR, t=t}]
172 :     end
173 :     (*esac*))
174 :     | expand(I.STORE{st, d=I.ConstOp c, b, r, mem}, size) =
175 :     (case size
176 :     of 4 => [I.STORE{st=st, d=I.IMMED(Const.valueOf c), b=b, r=r, mem=mem}]
177 :     | 12 => let
178 :     val (hi, lo) = split11(Const.valueOf c)
179 :     in
180 :     [I.LDIL{i=I.IMMED hi, t=C.asmTmpR},
181 :     I.ARITH{a=I.ADD, r1=C.asmTmpR, r2=b, t=C.asmTmpR},
182 :     I.STORE{st=st, b=C.asmTmpR, d=I.IMMED lo, r=r, mem=mem}]
183 :     end
184 :     (*esac*))
185 :     | expand(I.STORE _, _) = error "expand:STORE"
186 :     | expand(I.ARITHI{ai, r, i=I.ConstOp c, t}, size) =
187 :     (case size
188 :     of 4 => [I.ARITHI{ai=ai, r=r, i=I.IMMED(Const.valueOf c), t=t}]
189 :     | 12 => let
190 :     val (hi, lo) =
191 :     (case ai
192 :     of I.ADDI => split11X(Const.valueOf c)
193 :     | I.ADDIO => split11X(Const.valueOf c)
194 :     | I.SUBI => split11X(Const.valueOf c)
195 :     | I.SUBIO => split11X(Const.valueOf c)
196 :     | _ => error "expandd: ARITHI"
197 :     (*esac*))
198 :     in
199 :     [I.LDIL{i=I.IMMED hi, t=C.asmTmpR},
200 :     I.ARITH{a=I.ADD, r1=C.asmTmpR, r2=r, t=C.asmTmpR},
201 :     I.ARITHI{ai=ai, r=C.asmTmpR, i=I.IMMED lo, t=t}]
202 :     end
203 :     (*esac*))
204 :     | expand(instr as I.LOADI{li, r, i=I.ConstOp c, t, mem} , size) =
205 :     (case size
206 :     of 4 => [I.LOADI{li=li, r=r, i=I.IMMED(Const.valueOf c), t=t, mem=mem}]
207 :     | 12 => let
208 :     val (hi, lo) = split11(Const.valueOf c)
209 :     in
210 :     [I.LDIL{i=I.IMMED hi, t=C.asmTmpR},
211 :     I.ARITH{a=I.ADD, r1=C.asmTmpR, r2=r, t=C.asmTmpR},
212 :     I.LOADI{li=li, r=C.asmTmpR, i=I.IMMED lo, t=t, mem=mem}]
213 :     end
214 :     (*esac*))
215 :     | expand(instr as I.LOADI{li, r, i=I.LabExp lexp, t, mem} , size) =
216 :     (case size
217 :     of 4 => [instr]
218 :     | 12 => [I.LDIL{i=I.HILabExp lexp, t=C.asmTmpR},
219 :     I.ARITH{a=I.ADD, r1=C.asmTmpR, r2=r, t=C.asmTmpR},
220 :     I.LOADI{li=li, r=C.asmTmpR, i=I.LOLabExp lexp, t=t, mem=mem}]
221 :     (*esac*))
222 :     | expand(instr as I.ARITHI{ai, r, i=I.LabExp lexp, t} , size) =
223 :     (case size
224 :     of 4 => [instr]
225 :     | 12 =>
226 :     (* Note: A better sequence would be to use ADDIL, however
227 :     * the expansion is done after register allocation and
228 :     * ADDIL defines %r1.
229 :     *)
230 :     [I.LDIL{i=I.HILabExp lexp, t=C.asmTmpR},
231 :     I.LDO{i=I.LOLabExp lexp, b=C.asmTmpR, t=C.asmTmpR},
232 :     I.ARITH{
233 :     a = case ai of I.ADDI => I.ADD | I.ADDIO => I.ADDO
234 :     | I.SUBI => I.SUB | I.SUBIO => I.SUBO
235 :     | _ => error "expand: I.ARITHI LabExp",
236 :     t=t,
237 :     r1=C.asmTmpR,
238 :     r2=r}]
239 :     (*esac*))
240 :     | expand(instr as I.BCOND{cmp,bc, t, f, r1, r2, n}, size) = let
241 :     fun rev I.COMBT=I.BCOND{cmp=I.COMBF,bc=bc,t=f,f=f,r1=r1,r2=r2,n=true}
242 :     | rev I.COMBF=I.BCOND{cmp=I.COMBT,bc=bc,t=f,f=f,r1=r1,r2=r2,n=true}
243 :     in
244 :     case size
245 :     of 4 => [instr]
246 :     | 8 => [rev cmp, I.B{lab=t, n=n}]
247 :     | 20 => rev cmp :: longJump{lab=t, n=n}
248 :     (*esac*)
249 :     end
250 :     | expand(instr as I.BCONDI{cmpi, bc, t, f, i, r2, n}, size) = let
251 :     fun rev I.COMIBT=I.BCONDI{cmpi=I.COMIBF,bc=bc,i=i,r2=r2,t=f,f=f,n=true}
252 :     | rev I.COMIBF=I.BCONDI{cmpi=I.COMIBT,bc=bc,i=i,r2=r2,t=f,f=f,n=true}
253 :     in
254 :     (case size
255 :     of 4 => [instr]
256 :     | 8 => [rev cmpi, I.B{lab=t, n=n}]
257 :     | 20 => rev cmpi :: longJump{lab=t, n=n}
258 :     (*esac*))
259 :     end
260 :     | expand(instr as I.B{lab=lab, n=n}, size) =
261 :     (case size
262 :     of 4 => [instr]
263 :     | 16 => longJump{lab=lab, n=n}
264 :     (*esac*))
265 : monnier 167 | expand(instr as I.FBRANCH{t, f, n, ...}, size) =
266 : monnier 16 (case size
267 : monnier 167 of 12 => [instr]
268 :     | 24 =>
269 : monnier 16 (* lets hope this sequence never gets generated sequence:
270 :     FTEST
271 :     allways trapping instruction
272 :     B (f)
273 :     longJmp
274 :     *)
275 : monnier 167 error "FBRANCH"
276 : monnier 16 (*esac*))
277 : monnier 167 | expand(I.BLR{labs,n,t,x,...},size) =
278 :     (if size = 8 + 8 * length labs then
279 :     I.BLR{labs=[],n=n,t=t,x=x}::
280 :     I.NOP::
281 :     foldr (fn (l,is) => I.B{lab=l,n=true}::I.NOP::is) [] labs
282 :     else error "BLR"
283 :     )
284 : monnier 16 | expand(I.COPY{impl=ref(SOME instrs),...}, _) = instrs
285 :     | expand(I.FCOPY{impl=ref(SOME instrs),...}, _) = instrs
286 :     | expand _ = error "expand"
287 :    
288 :     end
289 :    
290 :     (*
291 : monnier 167 * $Log: hppaJumps.sml,v $
292 : monnier 223 * Revision 1.2 1998/10/06 14:04:32 george
293 :     * The instruction sequence FCMP, FTEST, FBCC is being replaced
294 :     * by the composite instruction FBRANCH. This makes scheduling and
295 :     * other tasks easier. Also, added BLR and BL in the instruction set.
296 :     * [leunga]
297 :     *
298 : monnier 167 * Revision 1.1.1.1 1998/04/08 18:39:01 george
299 :     * Version 110.5
300 :     *
301 : monnier 16 *)

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