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

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