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/hppa.mdl
ViewVC logotype

Annotation of /sml/trunk/src/MLRISC/hppa/hppa.mdl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 984 - (view) (download)

1 : leunga 746 (*
2 :     * This is the new machine description language.
3 :     *
4 :     *)
5 :    
6 :     architecture Hppa =
7 :     struct
8 :    
9 :     superscalar
10 :    
11 :     big endian
12 :    
13 :     lowercase assembly
14 :    
15 :     (*========================================================================
16 :     * On the HP, handling of delay slots is quite complicated:
17 :     *
18 :     * For conditional branches:
19 :     * -------------------------
20 :     * Branch direction
21 :     * Forward Backward
22 :     * Nullify bit on Nullify if branch taken Nullify if branch not-taken
23 :     * Nullify bit off Delay slot active Delay slot active
24 :     *
25 :     * For unconditional branches:
26 :     * ---------------------------
27 :     *
28 :     * Nullify bit on Delay slot nullified
29 :     * Nullify bit off Delay slot active
30 :     *========================================================================*)
31 :    
32 :    
33 :     (* debug MC *)
34 :    
35 :     (*========================================================================
36 :     * Storage types definitions
37 :     *========================================================================*)
38 :     storage
39 :     GP = $r[32] of 32 bits where $r[0] = 0
40 :     asm: (fn (r,_) => "%r"^Int.toString r)
41 :     | FP = $f[32] of 64 bits where $f[0] = 0
42 :     asm: (fn (f,_) => "%f"^Int.toString f)
43 :     | CR = $cr[32] of 32 bits asm: (fn (cr,_) => "%cr"^Int.toString cr)
44 :     | CC = $cc[] of 32 bits aliasing GP asm: "cc"
45 :     | MEM = $m[] of 8 aggregable bits asm: (fn (r,_) => "m"^Int.toString r)
46 :     | CTRL = $ctrl[] asm: (fn (r,_) => "ctrl"^Int.toString r)
47 :    
48 :     locations
49 :     returnPtr = $r[2]
50 :     and stackptrR = $r[30]
51 :     and asmTmpR = $r[29]
52 :     and fasmTmp = $f[31]
53 :     and sar = $cr[11]
54 :     and r0 = $r[0]
55 :     and f0 = $f[0]
56 :    
57 :     (*========================================================================
58 :     * RTL specification.
59 :     *========================================================================*)
60 :     structure RTL =
61 :     struct
62 :     include "Tools/basis.mdl"
63 :     open Basis
64 :     infix 1 ||
65 :     infix 2 :=
66 :     infix 5 + -
67 :     infix 6 << >> ~>>
68 :     infix 6 * div mod
69 :    
70 :     fun %% l = (l : #32 bits)
71 :    
72 :     rtl NOP{} = ()
73 :     (* rtl COPY{dst,src} = $r[forall dst] := $r[forall src]
74 :     rtl FCOPY{dst,src} = $f[forall dst] := $f[forall src] *)
75 :    
76 :     (* Integer loads *)
77 :     (* On the HP, addressing modes can be scaled and/or autoincrement *)
78 :     fun disp(r,i) = $r[r] + i
79 :     fun fdisp(r,d) = $r[r] + d
80 :     fun indexed(r1,r2) = $r[r1] + $r[r2]
81 :     fun scaled(r1,r2,scale) = $r[r1] << scale + $r[r2]
82 :     fun autoinc(r,i) = $r[r] := $r[r] + i
83 :     fun overflowtrap{} = ()
84 :    
85 :     fun byte x = (x : #8 bits)
86 :     fun half x = (x : #16 bits)
87 :     fun word x = (x : #32 bits)
88 :     fun quad x = (x : #64 bits)
89 :     fun % x = word x
90 :    
91 :     rtl LDO{b,i,t} = $r[t] := $r[b] + %i
92 :     rtl LDO2{i,t} = $r[t] := i
93 :     rtl LDIL{i,t} = $r[t] := i << 11
94 :     rtl MTCTL{r,t} = $cr[t] := $r[r]
95 :    
96 :     rtl LDW{r,i,t,mem} = $r[t] := $m[disp(r,i) : mem]
97 :     rtl LDH{r,i,t,mem} = $r[t] := zx(half $m[disp(r,i):mem])
98 :     rtl LDB{r,i,t,mem} = $r[t] := zx(byte $m[disp(r,i):mem])
99 :     rtl LDWX{r1,r2,t,mem} = $r[t] := $m[indexed(r1,r2):mem]
100 :     rtl LDWX_S{r1,r2,t,mem} = $r[t] := $m[scaled(r1,r2,2):mem]
101 :     rtl LDWX_M{r1,r2,t,mem} = $r[t] := $m[indexed(r1,r2):mem] || autoinc(r1,1)
102 :     rtl LDWX_SM{r1,r2,t,mem} = $r[t] := $m[scaled(r1,r2,2):mem] || autoinc(r1,4)
103 :     rtl LDHX{r1,r2,t,mem} = $r[t] := zx(half $m[indexed(r1,r2):mem])
104 :     rtl LDHX_S{r1,r2,t,mem} = $r[t] := zx(half $m[scaled(r1,r2,1):mem])
105 :     rtl LDHX_M{r1,r2,t,mem} = $r[t] := zx(half $m[indexed(r1,r2):mem]) ||
106 :     autoinc(r1,1)
107 :     rtl LDHX_SM{r1,r2,t,mem} = $r[t] := zx(half $m[scaled(r1,r2,1):mem]) ||
108 :     autoinc(r1,2)
109 :     rtl LDBX{r1,r2,t,mem} = $r[t] := zx(byte $m[indexed(r1,r2):mem])
110 :     rtl LDBX_M{r1,r2,t,mem} = $r[t] := zx(byte $m[indexed(r1,r2):mem]) ||
111 :     autoinc(r1,1)
112 :    
113 :     (* Integer stores *)
114 :     rtl STW{b,d,r,mem} = $m[disp(b,d):mem] := $r[r]
115 :     rtl STH{b,d,r,mem} = $m[disp(b,d):mem] := half(zx $r[r])
116 :     rtl STB{b,d,r,mem} = $m[disp(b,d):mem] := byte(zx $r[r])
117 :    
118 :     (* Integer opcodes *)
119 :     rtl ADD{r1,r2,t} = $r[t] := $r[r1] + $r[r2]
120 :     rtl ADDL{r1,r2,t} = $r[t] := $r[r1] + $r[r2]
121 :     rtl ADDO{r1,r2,t} = $r[t] := addt($r[r1], $r[r2])
122 :     rtl SUB{r1,r2,t} = $r[t] := $r[r1] - $r[r2]
123 :     rtl SUBO{r1,r2,t} = $r[t] := subt($r[r1], $r[r2])
124 :     rtl SH1ADD{r1,r2,t} = $r[t] := $r[r1] << 1 + $r[r2]
125 :     rtl SH2ADD{r1,r2,t} = $r[t] := $r[r1] << 2 + $r[r2]
126 :     rtl SH3ADD{r1,r2,t} = $r[t] := $r[r1] << 3 + $r[r2]
127 :     rtl SH1ADDL{r1,r2,t} = $r[t] := $r[r1] << 1 + $r[r2]
128 :     rtl SH2ADDL{r1,r2,t} = $r[t] := $r[r1] << 2 + $r[r2]
129 :     rtl SH3ADDL{r1,r2,t} = $r[t] := $r[r1] << 3 + $r[r2]
130 :     rtl SH1ADDO{r1,r2,t} = $r[t] := addt($r[r1] << 1, $r[r2])
131 :     rtl SH2ADDO{r1,r2,t} = $r[t] := addt($r[r1] << 2, $r[r2])
132 :     rtl SH3ADDO{r1,r2,t} = $r[t] := addt($r[r1] << 3, $r[r2])
133 :     rtl OR{r1,r2,t} = $r[t] := orb($r[r1], $r[r2])
134 :     rtl AND{r1,r2,t} = $r[t] := andb($r[r1], $r[r2])
135 :     rtl XOR{r1,r2,t} = $r[t] := xorb($r[r1], $r[r2])
136 :     rtl ANDCM{r1,r2,t} = $r[t] := andb($r[r1], notb($r[r2]))
137 :    
138 :     rtl ADDI{r,i,t} = $r[t] := $r[r] + i
139 :     rtl ADDIO{r,i,t} = $r[t] := addt($r[r], i)
140 :     rtl ADDIL{r,i,t} = $r[t] := $r[r] + i
141 :     rtl SUBI{r,i,t} = $r[t] := $r[r] + i
142 :     rtl SUBIO{r,i,t} = $r[t] := subt($r[r], i)
143 :    
144 :     (* Shifts *)
145 :     rtl extru extrs zdep : #n bits * #n bits * #n bits -> #n bits
146 :     val sar = $cr[11]
147 :     rtl VEXTRU{r, len, t} = $r[t] := extru($r[r], sar, len)
148 :     rtl VEXTRS{r, len, t} = $r[t] := extrs($r[r], sar, len)
149 :     rtl ZVDEP{r, len, t} = $r[t] := zdep($r[r], sar, len)
150 :     rtl EXTRU{r, p, len, t} = $r[t] := extru($r[r], p, len)
151 :     rtl EXTRS{r, p, len, t} = $r[t] := extrs($r[r], p, len)
152 :     rtl ZDEP{r, p, len, t} = $r[t] := zdep($r[r], p, len)
153 :    
154 :     val comparisons =
155 :     [(==), (<), (<=),
156 :     (ltu), (leu), (<>),
157 :     (>=), (>), (gtu), (geu)]
158 :    
159 :     (* COMCLR/LDO composite instruction:
160 :     * COMCLR,cc r1, r2, t1
161 :     * LDO i(b), t2
162 :     *)
163 :     fun COMCLR_LDO cc {r1,r2,t1,i,b,t2} =
164 :     if cc($r[r1],$r[r2]) then $r[t1] := 0 else $r[t2] := $r[b] + i
165 :     rtl COMCLR_LDO_ ^^ [EQ, LT, LE, LTU, LEU, NE, GE, GT, GTU, GEU] =
166 :     map COMCLR_LDO comparisons
167 :    
168 :     (* COMCLR/LDO composite instruction:
169 :     * COMCLR,cc r1, r2, t
170 :     * LDO i(b), t
171 :     * This version assumes that t1 = t2.
172 :     *)
173 :     fun COMCLR_LDO2 cc {r1,r2,t1,i,b} =
174 :     if cc($r[r1],$r[r2]) then $r[t1] := 0 else $r[t1] := $r[b] + i
175 :     rtl COMCLR_LDO2_ ^^ [EQ, LT, LE, LTU, LEU, NE, GE, GT, GTU, GEU] =
176 :     map COMCLR_LDO2 comparisons
177 :    
178 :     (* COMCLR/LDO composite instruction:
179 :     * COMCLR,cc r1, r2, %r0
180 :     * LDO i(b), t
181 :     * This version assumes that t1 = %r0.
182 :     *)
183 :     fun COMCLR_LDO3 cc {r1,r2,t2,i,b} =
184 :     if cc($r[r1],$r[r2]) then () else $r[t2] := $r[b] + i
185 :     rtl COMCLR_LDO3_ ^^ [EQ, LT, LE, LTU, LEU, NE, GE, GT, GTU, GEU] =
186 :     map COMCLR_LDO3 comparisons
187 :    
188 :     (* COMICLR/LDO composite instruction:
189 :     * COMICLR,cc i1, r2, t1
190 :     * LDO i(b), t2
191 :     *)
192 :     fun COMICLR_LDO cc {i1,r2,t1,i2,b,t2} =
193 :     if cc(%i1,$r[r2]) then $r[t1] := 0 else $r[t2] := $r[b] + i2
194 :     rtl COMICLR_LDO_ ^^ [EQ, LT, LE, LTU, LEU, NE, GE, GT, GTU, GEU] =
195 :     map COMICLR_LDO comparisons
196 :    
197 :     (* COMICLR/LDO composite instruction:
198 :     * COMICLR,cc i1, r2, t
199 :     * LDO i(b), t
200 :     * This version assumes that t1 = t2.
201 :     *)
202 :     fun COMICLR_LDO2 cc {i1,r2,t1,i2,b} =
203 :     if cc(i1,$r[r2]) then $r[t1] := 0 else $r[t1] := $r[b] + i2
204 :     rtl COMICLR_LDO2_ ^^ [EQ, LT, LE, LTU, LEU, NE, GE, GT, GTU, GEU] =
205 :     map COMICLR_LDO2 comparisons
206 :    
207 :     (* COMICLR/LDO composite instruction:
208 :     * COMICLR,cc i1, r2, %r0
209 :     * LDO i(b), t
210 :     * This version assumes that t1 = %r0.
211 :     *)
212 :     fun COMICLR_LDO3 cc {i1,r2,t2,i2,b} =
213 :     if cc(%i1,$r[r2]) then () else $r[t2] := $r[b] + i2
214 :     rtl COMICLR_LDO3_ ^^ [EQ, LT, LE, LTU, LEU, NE, GE, GT, GTU, GEU] =
215 :     map COMICLR_LDO3 comparisons
216 :    
217 :     (* Integer branching instructions *)
218 :     fun COMBT cmp {r1,r2,t} =
219 :     (if cmp($r[r1],$r[r2]) then Jmp(%%t) else ()) || $ctrl[0] := ???
220 :     fun COMBF cmp {r1,r2,t} =
221 :     (if cmp($r[r1],$r[r2]) then () else Jmp(%%t)) || $ctrl[0] := ???
222 :     fun COMIBT cmp {i,r2,t} =
223 :     (if cmp(%i,$r[r2]) then Jmp(%%t) else ()) || $ctrl[0] := ???
224 :     fun COMIBF cmp {i,r2,t} =
225 :     (if cmp(%i,$r[r2]) then () else Jmp(%%t)) || $ctrl[0] := ???
226 :     rtl COMBT_ ^^ [EQ, LT, LE, LTU, LEU, NE, GE, GT, GTU, GEU] =
227 :     map COMBT comparisons
228 :     rtl COMBF_ ^^ [EQ, LT, LE, LTU, LEU, NE, GE, GT, GTU, GEU] =
229 :     map COMBF comparisons
230 :     rtl COMIBT_ ^^ [EQ, LT, LE, LTU, LEU, NE, GE, GT, GTU, GEU] =
231 :     map COMIBT comparisons
232 :     rtl COMIBF_ ^^ [EQ, LT, LE, LTU, LEU, NE, GE, GT, GTU, GEU] =
233 :     map COMIBF comparisons
234 :    
235 :     rtl B{lab} = Jmp(%% lab)
236 :     rtl BV{x,b} = Jmp($r[x] << 2 + $r[b])
237 :     (* BB,< branch on bit set *)
238 :     rtl BB_BSET{p,r,t} =
239 :     (if andb($r[r],1 << (31 - p)) <> 0 then Jmp(%%t) else ())
240 :     || $ctrl[0] := ???
241 :     (* BB,>= branch on bit clear *)
242 :     rtl BB_BCLR{p,r,t} =
243 :     (if andb($r[r],1 << (31 - p)) == 0 then Jmp(%%t) else ())
244 :     || $ctrl[0] := ???
245 :    
246 :     rtl BLE{d,b,defs,uses} =
247 :     Call($r[b] + d) || (* call *)
248 :     Kill $r[31] || (* return address *)
249 :     Kill $cellset[defs] ||
250 :     Use $cellset[uses]
251 :    
252 :     (* Floating point loads *)
253 :     rtl FLDDS{b,d,t,mem} = $f[t] := $m[fdisp(b,d):mem]
254 :     rtl FLDWS{b,d,t,mem} = $f[t] := $m[fdisp(b,d):mem]
255 :     rtl FLDDX{b,x,t,mem} = $f[t] := $m[indexed(b,x):mem]
256 :     rtl FLDDX_S{b,x,t,mem} = $f[t] := $m[scaled(b,x,3):mem]
257 :     rtl FLDDX_M{b,x,t,mem} = $f[t] := $m[indexed(b,x):mem] || autoinc(b,8)
258 :     rtl FLDDX_SM{b,x,t,mem} = $f[t] := $m[scaled(b,x,3):mem] || autoinc(b,8)
259 :     rtl FLDWX{b,x,t,mem} = $f[t] := $m[indexed(b,x):mem]
260 :     rtl FLDWX_S{b,x,t,mem} = $f[t] := $m[scaled(b,x,2):mem]
261 :     rtl FLDWX_M{b,x,t,mem} = $f[t] := $m[indexed(b,x):mem] || autoinc(b,4)
262 :     rtl FLDWX_SM{b,x,t,mem} = $f[t] := $m[scaled(b,x,2):mem] || autoinc(b,4)
263 :    
264 :     (* Floating point stores *)
265 :     rtl FSTDS{b,d,r,mem} = $m[fdisp(b,d):mem] := $f[r]
266 :     rtl FSTWS{b,d,r,mem} = $m[fdisp(b,d):mem] := $f[r]
267 :     rtl FSTDX{b,x,r,mem} = $m[indexed(b,x):mem] := $f[r]
268 :     rtl FSTDX_S{b,x,r,mem} = $m[scaled(b,x,3):mem] := $f[r]
269 :     rtl FSTDX_M{b,x,r,mem} = $m[indexed(b,x):mem] := $f[r] || autoinc(b,8)
270 :     rtl FSTDX_SM{b,x,r,mem} = $m[scaled(b,x,3):mem] := $f[r] || autoinc(b,8)
271 :     rtl FSTWX{b,x,r,mem} = $m[indexed(b,x):mem] := $f[r]
272 :     rtl FSTWX_S{b,x,r,mem} = $m[scaled(b,x,2):mem] := $f[r]
273 :     rtl FSTWX_M{b,x,r,mem} = $m[indexed(b,x):mem] := $f[r] || autoinc(b,4)
274 :     rtl FSTWX_SM{b,x,r,mem} = $m[scaled(b,x,2):mem] := $f[r] || autoinc(b,4)
275 :    
276 :     (* Floating point binary operators *)
277 :     rtl FADD_S{r1,r2,t} = $f[t] := fadd($f[r1], $f[r2])
278 :     rtl FADD_D{r1,r2,t} = $f[t] := fadd($f[r1], $f[r2])
279 :     rtl FADD_Q{r1,r2,t} = $f[t] := fadd($f[r1], $f[r2])
280 :     rtl FSUB_S{r1,r2,t} = $f[t] := fsub($f[r1], $f[r2])
281 :     rtl FSUB_D{r1,r2,t} = $f[t] := fsub($f[r1], $f[r2])
282 :     rtl FSUB_Q{r1,r2,t} = $f[t] := fsub($f[r1], $f[r2])
283 :     rtl FMPY_S{r1,r2,t} = $f[t] := fsub($f[r1], $f[r2])
284 :     rtl FMPY_D{r1,r2,t} = $f[t] := fmul($f[r1], $f[r2])
285 :     rtl FMPY_Q{r1,r2,t} = $f[t] := fmul($f[r1], $f[r2])
286 :     rtl FDIV_S{r1,r2,t} = $f[t] := fdiv($f[r1], $f[r2])
287 :     rtl FDIV_D{r1,r2,t} = $f[t] := fdiv($f[r1], $f[r2])
288 :     rtl FDIV_Q{r1,r2,t} = $f[t] := fdiv($f[r1], $f[r2])
289 :     rtl XMPYU{r1,r2,t} = $f[t] := muls($f[r1], $f[r2])
290 :    
291 :     (* Floating point unary operators *)
292 :     rtl cvtf2i : #n bits -> #m bits
293 :     rtl fsqrt : #n bits -> #n bits
294 :     rtl FCPY_S{f,t} = $f[t] := $f[f]
295 :     rtl FCPY_D{f,t} = $f[t] := $f[f]
296 :     rtl FCPY_Q{f,t} = $f[t] := $f[f]
297 :     rtl FABS_S{f,t} = $f[t] := fabs($f[f])
298 :     rtl FABS_D{f,t} = $f[t] := fabs($f[f])
299 :     rtl FABS_Q{f,t} = $f[t] := fabs($f[f])
300 :     rtl FSQRT_S{f,t} = $f[t] := fsqrt($f[f])
301 :     rtl FSQRT_D{f,t} = $f[t] := fsqrt($f[f])
302 :     rtl FSQRT_Q{f,t} = $f[t] := fsqrt($f[f])
303 :     rtl FRND_S{f,t} = $f[t] := cvtf2i($f[f])
304 :     rtl FRND_D{f,t} = $f[t] := cvtf2i($f[f])
305 :     rtl FRND_Q{f,t} = $f[t] := cvtf2i($f[f])
306 :    
307 :     (* Floating point/fix point conversion operators *)
308 :     rtl fcnvff_sd fcnvff_sq fcnvff_ds fcnvff_dq
309 :     fcnvff_qs fcnvff_qd fcnvxf_s fcnvxf_d
310 :     fcnvxf_q fcnvfx_s fcnvfx_d fcnvfx_q
311 :     fcnvfxt_s fcnvfxt_d fcnvfxt_q
312 :     : #n bits -> #n bits
313 :    
314 :     rtl FCNVFF_SD{f,t} = $f[t] := fcnvff_sd $f[f]
315 :     rtl FCNVFF_SQ{f,t} = $f[t] := fcnvff_sq $f[f]
316 :     rtl FCNVFF_DS{f,t} = $f[t] := fcnvff_ds $f[f]
317 :     rtl FCNVFF_DQ{f,t} = $f[t] := fcnvff_dq $f[f]
318 :     rtl FCNVFF_QS{f,t} = $f[t] := fcnvff_qs $f[f]
319 :     rtl FCNVFF_QD{f,t} = $f[t] := fcnvff_qd $f[f]
320 :     (* fixed point -> floating point *)
321 :     rtl FCNVXF_S{f,t} = $f[t] := fcnvxf_s $f[f]
322 :     rtl FCNVXF_D{f,t} = $f[t] := fcnvxf_d $f[f]
323 :     rtl FCNVXF_Q{f,t} = $f[t] := fcnvxf_q $f[f]
324 :     (* floating point -> fixed point (use current rounding mode?) *)
325 :     rtl FCNVFX_S{f,t} = $f[t] := fcnvfx_s $f[f]
326 :     rtl FCNVFX_D{f,t} = $f[t] := fcnvfx_d $f[f]
327 :     rtl FCNVFX_Q{f,t} = $f[t] := fcnvfx_q $f[f]
328 :     (* floating point -> fixed point (and truncate) *)
329 :     rtl FCNVFXT_S{f,t} = $f[t] := fcnvfxt_s $f[f]
330 :     rtl FCNVFXT_D{f,t} = $f[t] := fcnvfxt_d $f[f]
331 :     rtl FCNVFXT_Q{f,t} = $f[t] := fcnvfxt_q $f[f]
332 :    
333 :     (* Floating point branch *)
334 :     fun FBRANCH cmp {f1,f2,t} =
335 :     if cmp($f[f1],$f[f2]) then Jmp(%%t) else ()
336 :    
337 :     rtl FBRANCH_ ^^
338 :     [?, !<=>, ==, ?=, !<>, !?>=, <, ?<,
339 :     !>=, !?>, <=, ?<=, !>, !?<=, >, ?>,
340 :     !<=, !?<, >=, ?>=, !<, !?=, <>, !=,
341 :     !?, <=>, ?<>] =
342 :     map FBRANCH
343 :     [|?|, |!<=>|, |==|, |?=|, |!<>|, |!?>=|, |<|, |?<|,
344 :     |!>=|, |!?>|, |<=|, |?<=|, |!>|, |!?<=|, |>|, |?>|,
345 :     |!<=|, |!?<|, |>=|, |?>=|, |!<|, |!?=|, |<>|, |!=|,
346 :     |!?|, |<=>|, |?<>|]
347 :    
348 :     end (* RTL *)
349 :    
350 :     (*========================================================================
351 :     * Instruction representation
352 :     *========================================================================*)
353 :     structure Instruction =
354 :     struct
355 :    
356 :     datatype fmt! = SGL 0w0 | DBL 0w1 | QUAD 0w3
357 :    
358 :     datatype loadi :Op! = LDW 0x12 (* p5-28 *)
359 :     | LDH 0x11 (* p5-29 *)
360 :     | LDB 0x10 (* p5-30 *)
361 :    
362 :     datatype store :Op! = STW 0x1A (* p5-31 *)
363 :     | STH 0x19 (* p5-32 *)
364 :     | STB 0x18 (* p5-33 *)
365 :    
366 :     (* addressing mode
367 :     * when the u bit is set, the index "x" is scaled by the size
368 :     * when the m bit is set, the base is also auto-incremented
369 :     *)
370 :    
371 :     datatype load :ext4! =
372 :     (* ext4, u, m *)
373 :     LDWX "ldwx" (0w2,0w0,0w0) (* p5-36 *)
374 :     | LDWX_S "ldwx,s" (0w2,0w1,0w0)
375 :     | LDWX_M "ldwx,m" (0w2,0w0,0w1)
376 :     | LDWX_SM "ldwx,sm" (0w2,0w1,0w1)
377 :     | LDHX "ldhx" (0w1,0w0,0w0) (* p5-37 *)
378 :     | LDHX_S "ldhx,s" (0w1,0w1,0w0)
379 :     | LDHX_M "ldhx,m" (0w1,0w0,0w1)
380 :     | LDHX_SM "ldhx,sm" (0w1,0w1,0w1)
381 :     | LDBX "ldbx" (0w0,0w0,0w0) (* p5-38 *)
382 :     | LDBX_M "ldbx,m" (0w0,0w0,0w1)
383 :    
384 :     (* All branching is done with nullification *)
385 :     datatype cmp! = COMBT 0wx20
386 :     | COMBF 0wx22
387 :    
388 :     datatype cmpi! = COMIBT 0wx21
389 :     | COMIBF 0wx23
390 :    
391 :     datatype arith! =
392 :     ADD 0x18 (* p5-83 *)
393 :     | ADDL 0x28 (* p5-84 *)
394 :     | ADDO 0x38 (* p5-85 *)
395 :     | SH1ADD 0x19 (* p5-88 *)
396 :     | SH1ADDL 0x29 (* p5-89 *)
397 :     | SH1ADDO 0x39 (* p5-90 *)
398 :     | SH2ADD 0x1A (* p5-91 *)
399 :     | SH2ADDL 0x2A (* p5-92 *)
400 :     | SH2ADDO 0x3A (* p5-93 *)
401 :     | SH3ADD 0x1B (* p5-94 *)
402 :     | SH3ADDL 0x2B (* p5-95 *)
403 :     | SH3ADDO 0x3B (* p5-96 *)
404 :     | SUB 0x10 (* p5-97 *)
405 :     | SUBO 0x30 (* p5-98 *)
406 :     | OR 0x09 (* p5-105 *)
407 :     | XOR 0x0A (* p5-106 *)
408 :     | AND 0x08 (* p5-107 *)
409 :     | ANDCM 0x00 (* p5-108 *)
410 :    
411 :     datatype arithi! =
412 :     ADDI (0wx2d,0w0)
413 :     | ADDIO (0wx2d,0w1)
414 :     | ADDIL
415 :     | SUBI (0wx25,0w0)
416 :     | SUBIO (0wx25,0w1)
417 :    
418 :     datatype shiftv! = VEXTRU | VEXTRS | ZVDEP
419 :    
420 :     datatype shift! = EXTRU | EXTRS | ZDEP
421 :    
422 :     datatype farith! = (* sop, fmt *)
423 :     FADD_S "fadd,sgl" (0w0, 0w0)
424 :     | FADD_D "fadd,dbl" (0w0, 0w1)
425 :     | FADD_Q "fadd,quad" (0w0, 0w3)
426 :    
427 :     | FSUB_S "fsub,sgl" (0w1, 0w0)
428 :     | FSUB_D "fsub,dbl" (0w1, 0w1)
429 :     | FSUB_Q "fsub,quad" (0w1, 0w3)
430 :    
431 :     | FMPY_S "fmpy,sgl" (0w2, 0w0)
432 :     | FMPY_D "fmpy,dbl" (0w2, 0w1)
433 :     | FMPY_Q "fmpy,quad" (0w2, 0w3)
434 :    
435 :     | FDIV_S "fdiv,sgl" (0w3, 0w0)
436 :     | FDIV_D "fdiv,dbl" (0w3, 0w1)
437 :     | FDIV_Q "fdiv,quad" (0w3, 0w3)
438 :    
439 :     | XMPYU (* ok *)
440 :    
441 :     datatype funary! = (* sop, fmt *)
442 :     (* copy *)
443 :     FCPY_S "fcpy,sgl" (0w2,0w0)
444 :     | FCPY_D "fcpy,dbl" (0w2,0w1)
445 :     | FCPY_Q "fcpy,quad" (0w2,0w3)
446 :    
447 :     | FABS_S "fabs,sgl" (0w3,0w0)
448 :     | FABS_D "fabs,dbl" (0w3,0w1)
449 :     | FABS_Q "fabs,quad" (0w3,0w3)
450 :    
451 :     | FSQRT_S "fsqrt,sgl" (0w4,0w0)
452 :     | FSQRT_D "fsqrt,dbl" (0w4,0w1)
453 :     | FSQRT_Q "fsqrt,quad" (0w4,0w3)
454 :    
455 :     (* round float to integer *)
456 :     | FRND_S "frnd,sgl" (0w5,0w0)
457 :     | FRND_D "frnd,dbl" (0w5,0w1)
458 :     | FRND_Q "frnd,quad" (0w5,0w3)
459 :    
460 :     (* FCNVXF --- the source is the LHS single precision floating register *)
461 :     datatype fcnv = (* sop, sf, df *)
462 :     (* floating point -> floating point *)
463 :     FCNVFF_SD "fcnvff,sgl,dbl" (0w0,0w0,0w1)
464 :     | FCNVFF_SQ "fcnvff,sgl,quad" (0w0,0w0,0w3)
465 :     | FCNVFF_DS "fcnvff,dbl,sgl" (0w0,0w1,0w0)
466 :     | FCNVFF_DQ "fcnvff,dbl,quad" (0w0,0w1,0w3)
467 :     | FCNVFF_QS "fcnvff,quad,sgl" (0w0,0w3,0w0)
468 :     | FCNVFF_QD "fcnvff,quad,dbl" (0w0,0w3,0w1)
469 :    
470 :     (* fixed point -> floating point *)
471 :     | FCNVXF_S "fcnvxf,,sgl" (0w1,0w0,0w0)
472 :     | FCNVXF_D "fcnvxf,,dbl" (0w1,0w0,0w1)
473 :     | FCNVXF_Q "fcnvxf,,quad" (0w1,0w0,0w3)
474 :    
475 :     (* floating point -> fixed point (use current rounding mode?) *)
476 :     | FCNVFX_S "fcnvfx,sgl," (0w2,0w0,0w0)
477 :     | FCNVFX_D "fcnvfx,dbl," (0w2,0w1,0w0)
478 :     | FCNVFX_Q "fcnvfx,quad," (0w2,0w3,0w0)
479 :    
480 :     (* floating point -> fixed point (and truncate) *)
481 :     | FCNVFXT_S "fcnvfxt,sgl," (0w3,0w0,0w0)
482 :     | FCNVFXT_D "fcnvfxt,dbl," (0w3,0w1,0w0)
483 :     | FCNVFXT_Q "fcnvfxt,quad," (0w3,0w3,0w0)
484 :    
485 :     datatype fstore! = FSTDS
486 :     | FSTWS
487 :     (* Op, uid, u, m *)
488 :     datatype fstorex! = FSTDX "fstdx" (0wxb,0w0,0w0,0w0)
489 :     | FSTDX_S "fstdx,s" (0wxb,0w0,0w1,0w0)
490 :     | FSTDX_M "fstdx,m" (0wxb,0w0,0w0,0w1)
491 :     | FSTDX_SM "fstdx,sm" (0wxb,0w0,0w1,0w1)
492 :     | FSTWX "fstwx" (0wx9,0w1,0w0,0w0)
493 :     | FSTWX_S "fstwx,s" (0wx9,0w1,0w1,0w0)
494 :     | FSTWX_M "fstwx,m" (0wx9,0w1,0w0,0w1)
495 :     | FSTWX_SM "fstwx,sm" (0wx9,0w1,0w1,0w1)
496 :    
497 :     (* FLDWX and FLDWS -- loads the RHS of the floating register *)
498 :     (* Op, uid, u, m *)
499 :     datatype floadx! = FLDDX "flddx" (0wxb,0w0,0w0,0w0)
500 :     | FLDDX_S "flddx,s" (0wxb,0w0,0w1,0w0)
501 :     | FLDDX_M "flddx,m" (0wxb,0w0,0w0,0w1)
502 :     | FLDDX_SM "flddx,sm" (0wxb,0w0,0w1,0w1)
503 :     | FLDWX "fldwx" (0wx9,0w1,0w0,0w0)
504 :     | FLDWX_S "fldwx,s" (0wx9,0w1,0w1,0w0)
505 :     | FLDWX_M "fldwx,m" (0wx9,0w1,0w0,0w1)
506 :     | FLDWX_SM "fldwx,sm" (0wx9,0w1,0w1,0w1)
507 :    
508 :     datatype fload! = FLDDS
509 :     | FLDWS
510 :    
511 :     (* page 5-5. fields for (c,f) *)
512 :     datatype bcond! = EQ "=" 0w1
513 :     | LT "<" 0w2
514 :     | LE "<=" 0w3
515 :     | LTU "<<" 0w4
516 :     | LEU "<<=" 0w5
517 :     | NE "<>" (* unimplemented *)
518 :     | GE ">=" (* ... *)
519 :     | GT ">"
520 :     | GTU ">>"
521 :     | GEU ">>="
522 :    
523 :     (* table 5-7 *)
524 :     datatype bitcond! = BSET "<" 0w2 (* bit is 1 *)
525 :     | BCLR ">=" 0w6 (* bit is 0 *)
526 :    
527 :     (* table 6-13 *)
528 :     datatype fcond [0..31] =
529 :     False_ "false?" | False "false" | ? | !<=> | == | EQT "=T" | ?= | !<>
530 :     | !?>= | < | ?< | !>= | !?> | <= | ?<= | !>
531 :     | !?<= | > | ?> | !<= | !?< | >= | ?>=
532 :     | !< | !?= | <> | != | NET "!=T" | !? | <=> | True_ "true?" | True "true"
533 :    
534 :     datatype scond = ALL_ZERO | LEFTMOST_ONE | LEFTMOST_ZERO | RIGHTMOST_ONE
535 :     | RIGHTMOST_ZERO
536 :    
537 :     datatype field_selector = F
538 :     | S
539 :     | D
540 :     | R
541 :     | T
542 :     | P
543 :    
544 :     datatype ea =
545 :     Direct of $GP
546 :     | FDirect of $GP
547 :     | Displace of {base: $GP, disp:int}
548 :    
549 :     datatype operand =
550 :     (* this is used only during instruction selection *)
551 :     REG of $GP rtl: $r[GP]
552 :     | IMMED of int ``<int>'' rtl: int
553 : leunga 775 | LabExp of T.labexp * field_selector ``<labexp>'' rtl: labexp
554 :     | HILabExp of T.labexp * field_selector ``<labexp>''
555 :     | LOLabExp of T.labexp * field_selector ``<labexp>''
556 : leunga 746
557 :     datatype addressing_mode =
558 : george 889 DISPea of CellsBasis.cell * operand (* displacement *)
559 :     | INDXea of CellsBasis.cell * CellsBasis.cell (* indexed *)
560 :     | INDXSCALEDea of CellsBasis.cell * CellsBasis.cell (* indexed with scaling (b,x) *)
561 : leunga 746
562 :     end (* Instruction *)
563 :    
564 :     (* ========================= Instruction Encoding =========================
565 :     *
566 :     * HP has 41 different instruction formats.
567 :     * The instruction encoding is, for the lack of a better phrase,
568 :     * all fucked up.
569 :     *
570 :     * See Appendix C.
571 :     *========================================================================*)
572 :     instruction formats 32 bits
573 :     (* sr=0 for load store, why? *)
574 :     Load{Op:6,b:GP 5,t:GP 5,s:2=0,im14:signed 14}
575 :     | Store{st:store 6,b:GP 5,r:GP 5,s:2=0,im14:signed 14}
576 :    
577 :     (* sr=3, m=0 no modify, cc=0 *)
578 :     | IndexedLoad{Op:6,b:GP 5,x:GP 5,s:2=3,u:1,_:1=0,cc:2=0,ext4:4,m:1,t:GP 5}
579 :    
580 :     | ShortDispLoad{Op:6,b:GP 5,im5:signed 5,s:2,a:1,_:1=1,cc:2,ext4:4,m:1,t:GP 5}
581 :     | ShoftDispShort{Op:6,b:5,r:5,s:2,a:1,_:1=1,cc:2,ext4:4,m:1,im5:signed 5}
582 :    
583 :     | LongImmed{Op:6,r:GP 5,im21:signed 21}
584 :    
585 :     | Arith{Op:6=0x2,r2:GP 5,r1:GP 5,c:3=0,f:1=0,a:arith 6,_:1=0,t:GP 5}
586 :     | Arithi{Op:6,r:GP 5,t:GP 5,c:3=0,f:1=0,e:1,im11:signed 11}
587 :    
588 :     | Extract{Op:6,r:GP 5,t:GP 5,c:3=0,ext3:3,p:int 5,clen:int 5}
589 :    
590 :     | Deposit{Op:6,t:GP 5,r:GP 5,c:3=0,ext3:3,cp:int 5,clen:int 5}
591 :    
592 :     | Shift{Op:6,r2:GP 5,r1:GP 5,c:3=0,ext3:3,cp:5,t:GP 5}
593 :     | ConditionalBranch{Op:6,r2:GP 5,r1:GP 5,c:bcond 3,w1:11,n:bool 1,w:1}
594 :     | ConditionalBranchi{Op:6,r2:GP 5,im5:5,c:bcond 3,w1:11,n:bool 1,w:1}
595 :     | BranchExternal{Op:6,b:GP 5,w1:5,s:3,w2:11,n:bool 1,w:1}
596 :     | BranchAndLink{Op:6,t:GP 5,w1:5,ext3:3,w2:11,n:bool 1,w:1}
597 :     | BranchVectored{Op:6,t:GP 5,x:GP 5,ext3:3,_:11=0,n:bool 1,w:1=0}
598 :     | Break{Op:6,im13:signed 13,ext8:8,im5:signed 5}
599 :     | BranchOnBit{Op:6=0x31,p:int 5,r:GP 5,c:3,w1:11,n:bool 1,w:1}
600 :    
601 :     | MoveToControlReg{Op:6,t:CR 5,r:GP 5,rv:3,ext8:8,_:5=0}
602 :     | CompareClear{Op:6=0wx2,r2:GP 5,r1:GP 5,c:3,f:1,ext:6,_:1=0,t:GP 5}
603 :     | CompareImmClear{Op:6=0wx24,r:GP 5,t:GP 5,c:3,f:1,_:1=0,im11:signed 11}
604 :    
605 :     (* floating point loads and stores *)
606 :     | CoProcShort{Op:6,b:GP 5,im5:5,s:2,a:1,_:1=1,cc:2=0,
607 :     ls:1,uid:3,m:1=0,rt:FP 5}
608 :     | CoProcIndexed{Op:6,b:GP 5,x:GP 5,s:2,u:1,_:1=0,cc:2=0,
609 :     ls:1,uid:3,m:1,rt:FP 5}
610 :    
611 :     (* OR r0,r0,r0 *)
612 :     | NOP{Op:6=0x2,r2:5=0,r1:5=0,c:3=0,f:1=0,a:6=0x9,_:1=0,t:5=0}
613 :    
614 :     | Nop{nop} = if nop then NOP{} else ()
615 :    
616 :     (* floating point ops *)
617 :     | FloatOp0Maj0C{Op:6=0x0C,r:FP 5,_:5=0,sop:3,fmt:2,_:6=0,t:FP 5}
618 :     | FloatOp1Maj0C{Op:6=0x0C,r:FP 5,_:4=0,sop:2,df:2,sf:2,_:2=1,_:4=0,t:FP 5}
619 :     | FloatOp2Maj0C{Op:6=0x0C,r1:FP 5,r2:FP 5,sop:3,fmt:2,_:2=2,_:3=0,n:1,c:5}
620 :     | FloatOp3Maj0C{Op:6=0x0C,r1:FP 5,r2:FP 5,sop:3,fmt:2,_:2=3,_:3=0,n:1,t:FP 5}
621 :    
622 :     | FloatOp0Maj0E{Op:6=0x0E,r:FP 5,_:5=0,sop:3,fmt:2,_:3=0,r2:1,t2:1,_:1=0,
623 :     t:FP 5}
624 :     | FloatOp1Maj0E{Op:6=0x0E,r:FP 5,_:4=0,sop:2,df:2,sf:2,_:2=1,_:1=0,r2:1,t2:1,
625 :     _:1=0,t:FP 5}
626 :     | FloatOp2Maj0E{Op:6=0x0E,r1:FP 5,r2:FP 5,sop:3,r22:1,f:1,_:2=2,_:1=0,
627 :     r11:1,_:2=0,c:5}
628 :     | FloatOp3Maj0E{Op:6=0x0E,r1:FP 5,r2:FP 5,sop:3,r22:1,f:1,_:2=3,_:1=0,
629 :     r11:1,_:2=0,t:FP 5}
630 :     | FloatMultiOp{Op:6=0x0E,rm1:5,rm2:5,ta:5,ra:5,f:1,tm:5}
631 :    
632 :     (* page 6-62 *)
633 :     | FTest{Op:6=0x0C,r1:5=0,r2:5=0,sop:3=1,_:2=0,_:2=2,_:3=0,_:1=1,c:5=0}
634 :    
635 :     structure Assembly =
636 :     struct
637 :     fun emit_n false = () | emit_n true = emit ",n"
638 :     fun emit_nop false = () | emit_nop true = emit "\n\tnop"
639 :     end
640 :    
641 :     (*========================================================================
642 :     * Various utility functions for emitting assembly code
643 :     *========================================================================*)
644 :     structure MC =
645 :     struct
646 : george 889 val zeroR = Option.valOf(C.zeroReg CellsBasis.GP)
647 : leunga 746 fun opn opnd =
648 :     let fun hi21 n = (itow n) >> 0w11
649 :     fun hi21X n = (itow n) ~>> 0w11
650 :     fun lo11 n = (itow n) && 0wx7ff
651 :     (* BUG: should respect the field selectors instead of ignoring them *)
652 :     in case opnd of
653 : george 984 I.HILabExp(lexp, _) => hi21X(MLTreeEval.valueOf lexp)
654 :     | I.LOLabExp(lexp, _) => lo11(MLTreeEval.valueOf lexp)
655 :     | I.LabExp(lexp, _) => itow(MLTreeEval.valueOf lexp)
656 : leunga 746 | I.IMMED i => itow i
657 :     | I.REG _ => error "REG"
658 :     end
659 :    
660 :     (* compute displacement address *)
661 :     fun disp lab = itow((Label.addrOf lab) - !loc - 8) ~>> 0w2
662 :     fun low_sign_ext_im14 n = ((n &&0wx1fff) << 0w1)||((n && 0wx2000) >> 0w13)
663 :     fun low_sign_ext_im11 n = ((n && 0wx3ff) << 0w1)||((n && 0wx400) >> 0w10)
664 :     fun low_sign_ext_im5 n = ((n && 0wxf) << 0w1)||((n && 0wx10) >> 0w4)
665 :    
666 :     fun assemble_3 n =
667 :     let val w1 = (n && 0w4) >> 0w2
668 :     val w2 = (n && 0w3) << 0w1
669 :     in w1 || w2 end
670 :    
671 :     fun assemble_12 n =
672 :     let val w = (n && 0wx800) >> 0w11
673 :     val w1 = ((n && 0wx3ff) << 0w1) || ((n && 0wx400) >> 0w10)
674 :     in (w1, w) end
675 :    
676 :     fun assemble_17 n =
677 :     let val w = (n && 0wx10000) >> 0w16
678 :     val w1 = (n && 0wxf800) >> 0w11
679 :     val w2 = (((n && 0wx3ff) << 0w1) || ((n && 0wx400) >> 0w10))
680 :     in (w, w1, w2) end
681 :    
682 :     fun assemble_21 disp =
683 :     let val w =
684 :     (((disp && 0wx000003) << 0w12) ||
685 :     ((disp && 0wx00007c) << 0w14) ||
686 :     ((disp && 0wx000180) << 0w7) ||
687 :     ((disp && 0wx0ffe00) >> 0w8) ||
688 :     ((disp && 0wx100000) >> 0w20))
689 :     in w end
690 :    
691 :     fun branchLink(Op,t,lab,ext3,n) =
692 :     let val (w,w1,w2) = assemble_17(disp lab)
693 :     in BranchAndLink{Op,t,w1,w2,w,ext3,n} end
694 :    
695 :     fun bcond(cmp,bc,r1,r2,n,t,nop) =
696 :     let val (w1,w) = assemble_12(disp t)
697 :     in ConditionalBranch{Op=emit_cmp cmp,c=bc,r1,r2,n,w,w1}; Nop{nop} end
698 :    
699 :     fun bcondi(cmpi,bc,i,r2,n,t,nop) =
700 :     let val (w1,w) = assemble_12(disp t)
701 :     in ConditionalBranchi{Op=emit_cmpi cmpi,c=bc,
702 :     im5=low_sign_ext_im5(itow i),r2,n,w,w1}; Nop{nop}
703 :     end
704 :     fun branchOnBit(bc,r,p,n,t,nop) =
705 :     let val (w1,w) = assemble_12(disp t)
706 :     in BranchOnBit{p=p,r=r,c=emit_bitcond bc,w1=w1,n=n,w=w}; Nop{nop}
707 :     end
708 :    
709 :     fun cmpCond cond =
710 :     case cond of
711 :     I.EQ => (0w1,0w0)
712 :     | I.LT => (0w2,0w0)
713 :     | I.LE => (0w3,0w0)
714 :     | I.LTU => (0w4,0w0)
715 :     | I.LEU => (0w5,0w0)
716 :     | I.NE => (0w1,0w1)
717 :     | I.GE => (0w2,0w1)
718 :     | I.GT => (0w3,0w1)
719 :     | I.GTU => (0w4,0w1)
720 :     | I.GEU => (0w5,0w1)
721 :    
722 :     end (* MC *)
723 :    
724 :     (*========================================================================
725 :     * Reservation tables and pipeline definitions for scheduling.
726 :     * All information are (uneducated) guesses.
727 :     * But see http://www.cpus.hp.com/techreports/parisc.shtml
728 :     *========================================================================*)
729 :    
730 :     (*
731 :     * Function units.
732 :     *
733 :     *)
734 :     resource mem (* load/store *)
735 :     and alu (* integer alu *)
736 :     and falu (* floating point alu *)
737 :     and fmul (* floating point multiplier *)
738 :     and fdiv (* floating point divider (also sqrt on the HP) *)
739 :     and branch (* branch unit *)
740 :    
741 :     (*
742 :     * Different implementations of cpus.
743 :     * Max
744 :     * Name Aliases Issues Function units
745 :     *)
746 :     cpu PA_700 2 [1 mem, 1 alu, 1 falu, 1 fmul, 1 branch]
747 :     and PA_7100 2 [1 mem, 1 alu, 2 fmul, 2 falu, 1 fdiv, 1 branch]
748 :     and PA_7100LC 2 [1 mem, 1 alu, 2 fmul, 2 falu, 1 fdiv, 1 branch]
749 :     and PA_7200 2 [1 mem, 1 alu, 2 fmul, 2 falu, 1 fdiv, 1 branch]
750 :     and PA_8000 4 [2 mem, 2 alu, 2 fmul, 2 falu, 2 fdiv, 1 branch]
751 :     and PA_8200 "default" 4 [2 mem, 2 alu, 2 fmul, 2 falu, 2 fdiv, 1 branch]
752 :     and PA_8500 4 [2 mem, 2 alu, 2 fmul, 2 falu, 2 fdiv, 1 branch]
753 :    
754 :     (* Definitions of various reservation tables *)
755 :     pipeline NOP _ = []
756 :     and ARITH (PA_700 | PA_7100 | PA_7100LC | PA_7200) = [alu]
757 :     | ARITH (PA_8000 | PA_8200 | PA_8500) = [alu]
758 :     and LOAD _ = [mem]
759 :     and STORE _ = [mem]
760 :     and FARITH (PA_700 | PA_7100 | PA_7100LC | PA_7200) = [falu,falu]
761 :     | FARITH (PA_8000 | PA_8200 | PA_8500) = [falu]
762 :     and FMPY (PA_700 | PA_7100 | PA_7100LC | PA_7200) = [fmul,fmul]
763 :     | FMPY (PA_8000 | PA_8200 | PA_8500) = [fmul]
764 :     (* division is apparently non-pipelined, so we have to
765 :     * hog up the pipeline for a bunch of cycles
766 :     *)
767 :     and FDIV PA_700 = [fmul*10] (* multiplier does division too *)
768 :     | FDIV (PA_7100 | PA_7100LC | PA_7200) = [fdiv*15]
769 :     | FDIV (PA_8000 | PA_8200 | PA_8500) = [fdiv,fdiv*14]
770 :     and BRANCH (PA_700 | PA_7100 | PA_7100LC | PA_7200) = [branch,branch]
771 :     | BRANCH (PA_8000 | PA_8200 | PA_8500) = [branch,branch]
772 :    
773 :     (*
774 :     * Latencies
775 :     * Note: the number refers the *additional* delay, so 0 means that
776 :     * the result computed in cycle t is available in cycle t+1.
777 :     *)
778 :     latency NOP _ = 0
779 :     and ARITH _ = 0
780 :     and LOAD _ = 1
781 :     and FARITH PA_700 = 2
782 :     | FARITH _ = 1
783 :     and FMPY PA_700 = 2
784 :     | FMPY PA_7100 = 2
785 :     | FMPY _ = 2
786 :     and FDIV PA_700 = 9
787 :     | FDIV PA_7100 = 14
788 :     | FDIV _ = 14
789 :     and FSQRT PA_700 = 17
790 :     | FSQRT PA_7100 = 14
791 :     | FSQRT _ = 14
792 :    
793 :     (*========================================================================
794 :     * Instruction definitions
795 :     *========================================================================*)
796 :     (* FLDWS, FLDWX = define the R half of the FP register.
797 :     * FSTWS = uses the R half of the FP register.
798 :     *)
799 :     instruction
800 :     LOADI of {li:loadi, r: $GP, i:operand, t: $GP, mem:Region.region}
801 :     asm: ``<li>\t<i>(<r>), <t><mem>''
802 :     mc: Load{Op=emit_loadi li,b=r,im14=low_sign_ext_im14(opn i),t=t}
803 :     rtl: ``<li>''
804 :     latency: LOAD
805 :     pipeline: LOAD
806 :    
807 :     | LOAD of {l:load, r1: $GP, r2: $GP, t: $GP, mem:Region.region}
808 :     asm: ``<l>\t<r2>(<r1>), <t><mem>''
809 :     mc: let val (ext4,u,m) = emit_load l
810 :     in IndexedLoad{Op=0w3,b=r1,x=r2,ext4,u,t,m}
811 :     end
812 :     rtl: ``<l>''
813 :     latency: LOAD
814 :     pipeline: LOAD
815 :    
816 :     | STORE of {st:store,b: $GP,d:operand,r: $GP, mem:Region.region}
817 :     asm: ``<st>\t<r>, <d>(<b>)<mem>''
818 :     mc: Store{st,b=b,im14=low_sign_ext_im14(opn d),r=r}
819 :     rtl: ``<st>''
820 :     pipeline: STORE
821 :    
822 :     | ARITH of {a:arith,r1: $GP, r2: $GP, t: $GP}
823 :     asm: ``<a>\t<r1>, <r2>, <t>''
824 :     mc: Arith{a,r1,r2,t}
825 :     rtl: ``<a>''
826 :     latency: ARITH
827 :     pipeline: ARITH
828 :    
829 :     | ARITHI of {ai:arithi, i:operand, r: $GP, t: $GP}
830 :     asm: ``<ai>\t<i>, <r>, <t>''
831 :     mc: (case ai of
832 :     I.ADDIL => LongImmed{Op=0wxa,r=r,im21=assemble_21(opn i)}
833 :     | _ => let val (Op,e) = emit_arithi ai
834 :     in Arithi{Op,r,t,im11=low_sign_ext_im11(opn i),e}
835 :     end
836 :     )
837 :     rtl: ``<ai>''
838 :     latency: ARITH
839 :     pipeline: ARITH
840 :    
841 :     (* This is a composite instruction.
842 :     * The effect is the same as t <- if r1 cc r2 then i+b else 0
843 :     * if t1 = t2
844 :     * COMCLR,cc r1, r2, t1
845 :     * LDO i(b), t2
846 :     *)
847 :     | COMCLR_LDO of {cc:bcond, r1: $GP, r2: $GP, t1 : $GP,
848 :     i:int, b: $GP, t2: $GP}
849 :     asm: (``comclr,<cc>\t<r1>, <r2>, <t1>\n\t'';
850 :     ``ldo\t<i>(<b>), <t2>''
851 :     )
852 :     mc: let val (c,f) = cmpCond cc
853 :     in CompareClear{r1,r2,t=t1,c,f,ext=0wx22};
854 :     Load{Op=0wx0d,b,im14=low_sign_ext_im14(itow i),t=t2}
855 :     end
856 :     rtl: if t1 = t2 then ``COMCLR_LDO2_<cc>''
857 :     else if t1 = 0 then ``COMCLR_LDO3_<cc>''
858 :     else ``<COMCLR_LDO_<cc>''
859 :     latency: ARITH
860 :     pipeline: ARITH
861 :    
862 :     | COMICLR_LDO of {cc:bcond, i1:operand, r2: $GP, t1 : $GP,
863 :     i2:int, b: $GP, t2: $GP}
864 :     asm: (``comiclr,<cc>\t<r2>, <i1>, <t1>\n\t'';
865 :     ``ldo\t<i2>(<b>), <t2>''
866 :     )
867 :     mc: let val (c,f) = cmpCond cc
868 :     in CompareImmClear{r=r2,t=t1,c,f,im11=low_sign_ext_im11(opn i1)};
869 :     Load{Op=0wx0d,b,im14=low_sign_ext_im14(itow i2),t=t2}
870 :     end
871 :     rtl: if t1 = t2 then ``COMICLR_LDO2_<cc>''
872 :     else if t1 = 0 then ``COMICLR_LDO3_<cc>''
873 :     else ``COMICLR_LDO_<cc>''
874 :     latency: ARITH
875 :     pipeline: ARITH
876 :    
877 :     | SHIFTV of {sv:shiftv, r: $GP, len:int, t: $GP}
878 :     asm: ``<sv>\t<r>, <len>, <t>''
879 :     mc: (case sv of
880 :     I.VEXTRU => Extract{Op=0wx34,r,t,ext3=0w4,p=0,clen=32-len}
881 :     | I.VEXTRS => Extract{Op=0wx34,r,t,ext3=0w5,p=0,clen=32-len}
882 :     | I.ZVDEP => Deposit{Op=0wx35,t,r,ext3=0w0,cp=0,clen=32-len}
883 :     )
884 :     rtl: ``<sv>''
885 :     latency: ARITH
886 :     pipeline: ARITH
887 :    
888 :     | SHIFT of {s:shift, r: $GP, p:int, len:int, t: $GP}
889 :     asm: ``<s>\t<r>, <p>, <len>, <t>''
890 :     mc: (case s of
891 :     I.EXTRU => Extract{Op=0wx34,r,t,ext3=0w6,p=p,clen=32-len}
892 :     | I.EXTRS => Extract{Op=0wx34,r,t,ext3=0w7,p=p,clen=32-len}
893 :     | I.ZDEP => Deposit{Op=0wx35,t,r,ext3=0w2,cp=31-p,clen=32-len}
894 :     )
895 :     rtl: ``<s>''
896 :     latency: ARITH
897 :     pipeline: ARITH
898 :    
899 :     | BCOND of {cmp: cmp, bc:bcond,r1: $GP,r2: $GP,n:bool,nop:bool,
900 :     t:Label.label, f:Label.label}
901 :     asm: ``<cmp>,<bc><n>\t<r1>, <r2>, <t><nop>''
902 :     mc: bcond(cmp,bc,r1,r2,n,t,nop)
903 :     rtl: ``<cmp>_<bc>''
904 :     padding: nop = true
905 :     nullified: n = true
906 :     delayslot: not nullified orelse
907 :     (branching forwards andalso taken orelse
908 :     branching backwards andalso not taken
909 :     )
910 :     delayslot candidate: false
911 :     pipeline: BRANCH
912 :    
913 :     | BCONDI of {cmpi: cmpi, bc:bcond, i:int, r2: $GP, n:bool, nop:bool,
914 :     t:Label.label, f:Label.label}
915 :     asm: ``<cmpi>,<bc><n>\t<i>, <r2>, <t><nop>''
916 :     mc: bcondi(cmpi,bc,i,r2,n,t,nop)
917 :     rtl: ``<cmpi>_<bc>''
918 :     padding: nop = true
919 :     nullified: n = true
920 :     delayslot: not nullified orelse
921 :     (branching forwards andalso taken orelse
922 :     branching backwards andalso not taken
923 :     )
924 :     delayslot candidate: false
925 :     pipeline: BRANCH
926 :    
927 :     (* bc must be either < or >= *)
928 :     | BB of {bc:bitcond,r: $GP, p:int, n:bool, nop:bool,
929 :     t:Label.label, f:Label.label}
930 :     asm: ``bb,<bc><n>\t<r>, <p>, <t><nop>''
931 :     mc: branchOnBit(bc,r,p,n,t,nop)
932 :     rtl: ``BB_<bc>''
933 :     padding: nop = true
934 :     nullified: n = true
935 :     delayslot: not nullified orelse
936 :     (branching forwards andalso taken orelse
937 :     branching backwards andalso not taken
938 :     )
939 :     delayslot candidate: false
940 :     pipeline: BRANCH
941 :    
942 :     | B of {lab:Label.label, n:bool}
943 :     asm: ``b<n>\t<lab>''
944 :     mc: branchLink(0wx3a,zeroR,lab,0w0,n)
945 :     rtl: ``B''
946 :     nullified: n = true
947 :     delayslot candidate: false
948 :     pipeline: BRANCH
949 :    
950 :     (*
951 :     * This composite instruction is generated only during span dependence
952 :     * resolution when trying to resolve conditional branches.
953 :     * The expanded sequence is 12 bytes long.
954 :     * Basically, the branch and link instruction jumps directly to
955 :     * the next instruction at tmpLab, and put the address of tmpLab + 4
956 :     * into register tmp. The offset computation in addil computes the
957 :     * actual address of lab.
958 :     *)
959 :     | LONGJUMP of {lab:Label.label, n:bool, tmp: $GP, tmpLab:Label.label}
960 :     asm: (``bl,n\t<tmpLab>, <tmp>\n'';
961 :     ``<tmpLab>:\n\t'';
962 :     ``addil <lab>-(<tmpLab>+4), <tmp>\n\t'';
963 :     ``bv<n>\t%r0(<tmp>)''
964 :     )
965 :     mc: let val offset =
966 : leunga 775 T.SUB(32,T.LABEL lab,
967 :     T.ADD(32,T.LABEL tmpLab, T.LI(IntInf.fromInt 4)))
968 : leunga 746 in (* set the location of tmpLab *)
969 :     Label.setAddr(tmpLab, !loc+4);
970 :     branchLink(0wx3a,tmp,tmpLab,0w0,n);
971 :     LongImmed{Op=0wxa,r=tmp,
972 : george 984 im21=assemble_21(itow(MLTreeEval.valueOf offset))};
973 : leunga 746 BranchVectored{Op=0wx3a,t=tmp,x=zeroR,ext3=0w6,n=n}
974 :     end
975 :     rtl: ``B''
976 :     nullified: n = true
977 :     delayslot candidate: false
978 :     pipeline: BRANCH
979 :    
980 :     | BE of {b: $GP, d:operand, sr:int, n:bool, labs: Label.label list}
981 :     asm: ``be<n>\t<d>(<sr>,<b>)''
982 :     mc: let val (w,w1,w2) = assemble_17(opn d)
983 :     in BranchExternal{Op=0wx38,b=b,w1=w1,s=assemble_3(itow sr),
984 :     w2=w2,n=n,w=w}
985 :     end
986 :     nullified: n = true
987 :     delayslot candidate: false
988 :     pipeline: BRANCH
989 :    
990 :     | BV of {x: $GP, b: $GP, labs: Label.label list, n:bool}
991 :     asm: ``bv<n>\t<x>(<b>)''
992 :     mc: BranchVectored{Op=0wx3a,t=b,x=x,ext3=0w6,n=n}
993 :     rtl: ``BV''
994 :     nullified: n = true
995 :     delayslot candidate: false
996 :     pipeline: BRANCH
997 :    
998 :     | BLR of {x: $GP, t: $GP, labs: Label.label list, n:bool}
999 :     asm: ``blr<n>\t<x>(<t>)''
1000 :     mc: BranchVectored{Op=0wx3a,t=t,x=x,ext3=0w2,n=n}
1001 :     nullified: n = true
1002 :     delayslot candidate: false
1003 :     pipeline: BRANCH
1004 :    
1005 :     | BL of {lab:Label.label ,t: $GP, defs: $cellset, uses: $cellset,
1006 : leunga 796 cutsTo: Label.label list, mem:Region.region, n:bool}
1007 :     asm: ``bl<n>\t<lab>, <t><mem><emit_defs(defs)><emit_uses(uses)><emit_cutsTo cutsTo>''
1008 : leunga 746 mc: branchLink(0wx3a,t,lab,0w0,n)
1009 :     nullified: n = true
1010 :     delayslot candidate: false
1011 :     pipeline: BRANCH
1012 :    
1013 :     | BLE of {d:operand,b: $GP, sr:int, t: $GP,
1014 : leunga 796 defs: $cellset, uses: $cellset, cutsTo: Label.label list,
1015 :     mem:Region.region}
1016 : leunga 746 asm: ``ble\t<d>(<emit_int sr>,<b>)<mem><
1017 : leunga 796 emit_defs(defs)><emit_uses(uses)><emit_cutsTo cutsTo>''
1018 : george 889 mc: (case (d,CellsBasis.registerId t) of
1019 : leunga 746 (I.IMMED 0,31) =>
1020 :     BranchExternal{Op=0wx39,b=b,w1=0w0,s=assemble_3(itow sr),
1021 :     w2=0w0,n=true,w=0w0}
1022 :     | _ => error "BLE: not implemented"
1023 :     )
1024 :     rtl: ``BLE''
1025 :     nullified: false
1026 :     delayslot candidate: false
1027 :     pipeline: BRANCH
1028 :    
1029 :     (* BLE implicitly defines %r31. The destination register t
1030 :     * is assigned in the delay slot.
1031 :     *)
1032 :     | LDIL of {i:operand, t: $GP}
1033 :     asm: ``ldil\t<i>, <t>''
1034 :     mc: LongImmed{Op=0wx8,r=t,im21=assemble_21(opn i)}
1035 :     rtl: ``LDIL''
1036 :     latency: ARITH
1037 :     pipeline: ARITH
1038 :    
1039 :     | LDO of {i:operand, b: $GP, t: $GP}
1040 :     asm: ``ldo\t<i>(<b>), <t>''
1041 :     mc: Load{Op=0wx0d,b,im14=low_sign_ext_im14(opn i),t=t}
1042 :     rtl: if b = 0 then ``LDO2'' else ``LDO''
1043 :     latency: ARITH
1044 :     pipeline: ARITH
1045 :    
1046 :     | MTCTL of {r: $GP, t: $CR}
1047 :     asm: ``mtctl\t<r>, <t>''
1048 :     mc: MoveToControlReg{Op=0w0,t,r,rv=0w0,ext8=0wxc2}
1049 :     rtl: ``MTCTL''
1050 :     latency: ARITH
1051 :     pipeline: ARITH
1052 :    
1053 :     | FSTORE of {fst:fstore,b: $GP, d:int, r: $FP,mem:Region.region}
1054 :     asm: ``<fst>\t<r>, <d>(<b>)<mem>''
1055 :     mc: (case fst of
1056 :     I.FSTDS => CoProcShort{Op=0wxb,b,im5=low_sign_ext_im5(itow d),
1057 :     s=0w0,a=0w0,ls=0w1,uid=0w0,rt=r}
1058 :     | I.FSTWS => CoProcShort{Op=0wx9,b,im5=low_sign_ext_im5(itow d),
1059 :     s=0w0,a=0w0,ls=0w1,uid=0w1,rt=r}
1060 :     )
1061 :     rtl: ``<fst>''
1062 :     pipeline: STORE
1063 :    
1064 :     | FSTOREX of {fstx:fstorex, b: $GP, x: $GP,r: $FP,mem:Region.region}
1065 :     asm: ``<fstx>\t<r>, <x>(<b>)<mem>''
1066 :     mc: let val (Op,uid,u,m) = emit_fstorex fstx
1067 :     in CoProcIndexed{Op=Op,b,x,s=0w0,u,m,ls=0w1,uid=uid,rt=r}
1068 :     end
1069 :     rtl: ``<fstx>''
1070 :     pipeline: STORE
1071 :    
1072 :     | FLOAD of {fl:fload, b: $GP, d:int, t: $FP, mem:Region.region}
1073 :     asm: ``<fl>\t<d>(<b>), <t><mem>''
1074 :     mc: (case fl of
1075 :     I.FLDDS => CoProcShort{Op=0wxb,b,im5=low_sign_ext_im5(itow d),
1076 :     s=0w0,a=0w0,ls=0w0,uid=0w0,rt=t}
1077 :     | I.FLDWS => CoProcShort{Op=0wx9,b,im5=low_sign_ext_im5(itow d),
1078 :     s=0w0,a=0w0,ls=0w0,uid=0w1,rt=t}
1079 :     )
1080 :     rtl: ``<fl>''
1081 :     latency: LOAD
1082 :     pipeline: LOAD
1083 :    
1084 :     | FLOADX of {flx:floadx, b: $GP, x: $GP, t: $FP, mem:Region.region}
1085 :     asm: ``<flx>\t<x>(<b>), <t><mem>''
1086 :     mc: let val (Op,uid,u,m) = emit_floadx flx
1087 :     in CoProcIndexed{Op=Op,b,x,s=0w0,u,m,ls=0w0,uid=uid,rt=t}
1088 :     end
1089 :     rtl: ``<flx>''
1090 :     latency: LOAD
1091 :     pipeline: LOAD
1092 :    
1093 :     | FARITH of {fa:farith,r1: $FP, r2: $FP,t: $FP}
1094 :     asm: ``<fa>\t<r1>, <r2>, <t>''
1095 :     mc: (case fa of
1096 :     I.XMPYU => FloatOp3Maj0E{sop=0w2,f=0w1,r1,r2,t,r11=0w0,r22=0w0}
1097 :     | _ => let val (sop,fmt) = emit_farith fa
1098 :     in FloatOp3Maj0C{sop,r1,r2,t,n=0w0,fmt} end
1099 :     )
1100 :     rtl: ``<fa>''
1101 :     latency: (case fa of
1102 :     (I.FMPY_S | I.FMPY_D | I.FMPY_Q) => FMPY
1103 :     | (I.FDIV_S | I.FDIV_D | I.FDIV_Q) => FDIV
1104 :     | _ => FARITH
1105 :     )
1106 :     pipeline: (case fa of
1107 :     (I.FMPY_S | I.FMPY_D | I.FMPY_Q) => FMPY
1108 :     | (I.FDIV_S | I.FDIV_D | I.FDIV_Q) => FDIV
1109 :     | _ => FARITH
1110 :     )
1111 :    
1112 :     | FUNARY of {fu:funary,f: $FP, t: $FP}
1113 :     asm: ``<fu>\t<f>, <t>''
1114 :     mc: let val (sop,fmt) = emit_funary fu
1115 :     in FloatOp0Maj0C{r=f,t=t,sop=sop,fmt=fmt}
1116 :     end
1117 :     rtl: ``<fu>''
1118 :     latency: FARITH
1119 :     pipeline: FARITH
1120 :    
1121 :     | FCNV of {fcnv:fcnv, f: $FP, t: $FP}
1122 :     asm: ``<fcnv>\t<f>, <t>''
1123 :     mc: let val (sop,sf,df) = emit_fcnv fcnv
1124 :     in FloatOp1Maj0E{r=f,t=t,sop=sop,sf=sf,df=df,r2=0w1,t2=0w0}
1125 :     end
1126 :     rtl: ``<fcnv>''
1127 :     latency: FARITH
1128 :     pipeline: FARITH
1129 :    
1130 :     (* The following three instructions have been replaced by FBRANCH.
1131 :     This make life much easier for instruction schedulers.
1132 :     | FCMP of fcond * int * int
1133 :     | FTEST
1134 :     | FBCC of {t:Label.label, f:Label.label, n:bool}
1135 :     *)
1136 :     | FBRANCH of {cc:fcond, fmt:fmt, f1: $FP, f2: $FP,
1137 :     t:Label.label, f:Label.label, n:bool, long:bool}
1138 :     asm: (``fcmp,<fmt>,<cc>\t<f1>, <f2>\n\t'';
1139 :     ``ftest\n\t'';
1140 :     ``b<n>\t<t>''
1141 :     )
1142 :     (* fmt = 1 means double precision; will have to extend later *)
1143 :     mc: (FloatOp2Maj0C{r1=f1,r2=f2,sop=0w0,fmt=emit_fmt fmt,
1144 :     n=0w0,c=emit_fcond cc};
1145 :     FTest{};
1146 :     branchLink(0wx3a,zeroR,t,0w0,n) (* B,n t *)
1147 :     )
1148 :     rtl: ``FBRANCH_<cc>''
1149 :     nullified: n
1150 :     delayslot candidate: false
1151 :     pipeline: BRANCH
1152 :    
1153 :     | BREAK of {code1:int, code2:int}
1154 :     asm: ``break\t<code1>, <code2>''
1155 :     delayslot candidate: false
1156 :    
1157 :     | NOP
1158 :     asm: ``nop''
1159 :     mc: NOP{}
1160 :     rtl: ``NOP''
1161 :     pipeline: NOP
1162 :    
1163 :     | COPY of {dst: $GP list, src: $GP list,
1164 :     impl:instruction list option ref, tmp: ea option}
1165 :     asm: emitInstrs (Shuffle.shuffle{tmp,src,dst})
1166 :     rtl: ``COPY''
1167 :     pipeline: ARITH
1168 :    
1169 :     | FCOPY of {dst: $FP list, src: $FP list,
1170 :     impl:instruction list option ref, tmp: ea option}
1171 :     asm: emitInstrs (Shuffle.shufflefp{tmp,src,dst})
1172 :     rtl: ``FCOPY''
1173 :     pipeline: ARITH
1174 :    
1175 :     | ANNOTATION of {i:instruction, a:Annotations.annotation}
1176 :     asm: (comment(Annotations.toString a); nl(); emitInstr i)
1177 :     mc: emitInstr i
1178 :     (* rtl: [[ #i ]] *)
1179 :    
1180 :     | SOURCE of {}
1181 :     asm: ``source''
1182 :     mc: ()
1183 :    
1184 :     | SINK of {}
1185 :     asm: ``sink''
1186 :     mc: ()
1187 :    
1188 :     | PHI of {}
1189 :     asm: ``phi''
1190 :     mc: ()
1191 :    
1192 :     structure SSA =
1193 :     struct
1194 :    
1195 :     fun operand(ty,I.REG r) = T.REG(ty, r)
1196 : leunga 775 | operand(ty,I.IMMED i) = T.LI(IntInf.fromInt i)
1197 : leunga 746 (*| operand(ty,I.LabExp(le,_)) = T.LABEL le*)
1198 :     | operand _ = error "operand"
1199 :    
1200 :     end
1201 :    
1202 :     end

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