SCM Repository
Annotation of /sml/trunk/src/MLRISC/alpha/alpha.mdl
Parent Directory
|
Revision Log
Revision 746 - (view) (download)
1 : | leunga | 746 | (* |
2 : | * This machine description now includes 64-bit and single precision | ||
3 : | * floating point support. The description | ||
4 : | * is copied from the book ``Alpha Architecture Reference Manual'' edited | ||
5 : | * by Richard L. Sites, Digital Press, 1992. | ||
6 : | * | ||
7 : | * -- Allen Leung | ||
8 : | *) | ||
9 : | architecture Alpha = | ||
10 : | struct | ||
11 : | |||
12 : | superscalar | ||
13 : | |||
14 : | little endian | ||
15 : | |||
16 : | lowercase assembly | ||
17 : | |||
18 : | (* | ||
19 : | * This specify the cells interface | ||
20 : | *) | ||
21 : | storage | ||
22 : | GP = $r[32] of 64 bits where $r[31] = 0 | ||
23 : | asm: (fn (30,_) => "$sp" | ||
24 : | | (r,_) => "$"^Int.toString r | ||
25 : | ) | ||
26 : | | FP = $f[32] of 64 bits where $f[31] = 0 | ||
27 : | asm: (fn (f,_) => "$f"^Int.toString f) | ||
28 : | | CC = $cc[] of 64 bits aliasing GP asm: "cc" | ||
29 : | | MEM = $m[] of 8 aggregable bits asm: (fn (r,_) => "m"^Int.toString r) | ||
30 : | | CTRL = $ctrl[] asm: (fn (r,_) => "ctrl"^Int.toString r) | ||
31 : | |||
32 : | locations | ||
33 : | stackptrR = $r[30] | ||
34 : | and asmTmpR = $r[28] | ||
35 : | and fasmTmp = $r[30] | ||
36 : | and returnAddr = $r[26] | ||
37 : | and r31 = $r[31] | ||
38 : | and f31 = $f[31] | ||
39 : | |||
40 : | structure RTL = | ||
41 : | struct | ||
42 : | include "Tools/basis.mdl" | ||
43 : | open Basis | ||
44 : | infix 1 || | ||
45 : | infix 2 := | ||
46 : | infix 3 << >> ~>> | ||
47 : | |||
48 : | (* rtl COPY{dst,src} = $r[forall dst] := $r[forall src] | ||
49 : | rtl FCOPY{dst,src} = $f[forall dst] := $f[forall src] *) | ||
50 : | |||
51 : | (* How to align addresses *) | ||
52 : | fun align4 addr = andb(addr,notb 3) | ||
53 : | fun align8 addr = andb(addr,notb 7) | ||
54 : | fun align8Upper addr = orb(andb(addr,notb 7),4) | ||
55 : | |||
56 : | fun %% l = (l : #64 bits) | ||
57 : | |||
58 : | fun disp(b,d) = $r[b] + d | ||
59 : | |||
60 : | fun byte x = (x : #8 bits) | ||
61 : | fun word x = (x : #16 bits) | ||
62 : | fun dword x = (x : #32 bits) | ||
63 : | fun qword x = (x : #64 bits) | ||
64 : | fun float x = (x : #32 bits) | ||
65 : | fun double x = (x : #64 bits) | ||
66 : | |||
67 : | rtl LDA{r,b,d} = $r[r] := $r[b] + d | ||
68 : | rtl LDAH{r,b,d} = $r[r] := $r[b] + d << 16 | ||
69 : | |||
70 : | (* Integer loads *) | ||
71 : | rtl LDB{r,b,d,mem} = $r[r] := sx (byte $m[disp(b,d):mem]) | ||
72 : | rtl LDW{r,b,d,mem} = $r[r] := sx (word $m[disp(b,d):mem]) | ||
73 : | rtl LDBU{r,b,d,mem} = $r[r] := zx (byte $m[disp(b,d):mem]) | ||
74 : | rtl LDWU{r,b,d,mem} = $r[r] := zx (word $m[disp(b,d):mem]) | ||
75 : | rtl LDL{r,b,d,mem} = $r[r] := sx (dword $m[disp(b,d):mem]) | ||
76 : | rtl LDL_L{r,b,d,mem} = $r[r] := sx (dword $m[align4(disp(b,d)):mem]) | ||
77 : | rtl LDQ{r,b,d,mem} = $r[r] := qword $m[disp(b,d):mem] | ||
78 : | rtl LDQ_L{r,b,d,mem} = $r[r] := qword $m[align8(disp(b,d)):mem] | ||
79 : | rtl LDQ_U{r,b,d,mem} = $r[r] := qword $m[align8Upper(disp(b,d)):mem] | ||
80 : | |||
81 : | (* Integer stores *) | ||
82 : | rtl STB{r,b,d,mem} = $m[disp(b,d):mem] := $r[r] at [0..7] | ||
83 : | rtl STW{r,b,d,mem} = $m[disp(b,d):mem] := $r[r] at [0..15] | ||
84 : | rtl STL{r,b,d,mem} = $m[disp(b,d):mem] := $r[r] at [0..31] | ||
85 : | rtl STQ{r,b,d,mem} = $m[disp(b,d):mem] := $r[r] | ||
86 : | rtl STQ_U{r,b,d,mem} = $m[align8(disp(b,d)):mem] := $r[r] | ||
87 : | |||
88 : | (* Floating point loads *) | ||
89 : | rtl LDF{r,b,d,mem} = $f[r] := sx (float $m[disp(b,d):mem]) | ||
90 : | rtl LDG{r,b,d,mem} = $f[r] := double $m[disp(b,d):mem] | ||
91 : | rtl LDS{r,b,d,mem} = $f[r] := double $m[disp(b,d):mem] | ||
92 : | rtl LDT{r,b,d,mem} = $f[r] := double $m[disp(b,d):mem] | ||
93 : | |||
94 : | (* Floating point stores *) | ||
95 : | rtl STF{r,b,d,mem} = $m[disp(b,d):mem] := float(sx $f[r]) | ||
96 : | rtl STG{r,b,d,mem} = $m[disp(b,d):mem] := $f[r] | ||
97 : | rtl STS{r,b,d,mem} = $m[disp(b,d):mem] := $f[r] | ||
98 : | rtl STT{r,b,d,mem} = $m[disp(b,d):mem] := $f[r] | ||
99 : | |||
100 : | (* Integer operators *) | ||
101 : | rtl ADDL{ra,rb,rc} = $r[rc] := sx($r[ra] + rb) | ||
102 : | rtl ADDQ{ra,rb,rc} = $r[rc] := $r[ra] + rb | ||
103 : | fun cmp oper {ra,rb,rc} = $r[rc] := cond(oper($r[ra],rb), 1, 0) | ||
104 : | |||
105 : | rtl [CMPBGE, CMPEQ, CMPLE, CMPLT, CMPULE, CMPULT] = | ||
106 : | map cmp [(>=), (==), (<=), (<), (leu), (ltu)] | ||
107 : | |||
108 : | fun binop oper {ra,rb,rc} = $r[rc] := oper($r[ra], rb) | ||
109 : | |||
110 : | rtl SUBL{ra,rb,rc} = $r[rc] := sx($r[ra] - rb) | ||
111 : | rtl SUBQ{ra,rb,rc} = $r[rc] := $r[ra] - rb | ||
112 : | rtl S4ADDL{ra,rb,rc} = $r[rc] := sx($r[ra] << 2 + rb) | ||
113 : | rtl S4ADDQ{ra,rb,rc} = $r[rc] := $r[ra] << 2 + rb | ||
114 : | rtl S4SUBL{ra,rb,rc} = $r[rc] := sx($r[ra] << 2 - rb) | ||
115 : | rtl S4SUBQ{ra,rb,rc} = $r[rc] := $r[ra] << 2 - rb | ||
116 : | rtl S8ADDL{ra,rb,rc} = $r[rc] := sx($r[ra] << 3 + rb) | ||
117 : | rtl S8ADDQ{ra,rb,rc} = $r[rc] := $r[ra] << 3 + rb | ||
118 : | rtl S8SUBL{ra,rb,rc} = $r[rc] := sx($r[ra] << 3 - rb) | ||
119 : | rtl S8SUBQ{ra,rb,rc} = $r[rc] := $r[ra] << 3 - rb | ||
120 : | rtl AND{ra,rb,rc} = $r[rc] := andb($r[ra], rb) | ||
121 : | rtl BIC{ra,rb,rc} = $r[rc] := andb($r[ra], notb(rb)) (* XXX *) | ||
122 : | rtl BIS{ra,rb,rc} = $r[rc] := orb($r[ra], rb) | ||
123 : | rtl EQV{ra,rb,rc} = $r[rc] := eqvb($r[ra], rb) | ||
124 : | rtl ORNOT{ra,rb,rc} = $r[rc] := orb($r[ra], notb(rb)) | ||
125 : | rtl XOR{ra,rb,rc} = $r[rc] := xorb($r[ra], rb) | ||
126 : | |||
127 : | rtl extbl extlh extll extqh extql extwh extwl insbl inslh insll | ||
128 : | insqh insql inswh inswl mskbl msklh mskll mskqh mskql mskwh mskwl | ||
129 : | : #n bits * #n bits -> #n bits | ||
130 : | rtl [EXTBL, EXTLH, EXTLL, EXTQH, EXTQL, EXTWH, EXTWL, | ||
131 : | INSBL, INSLH, INSLL, INSQH, INSQL, INSWH, INSWL, | ||
132 : | MSKBL, MSKLH, MSKLL, MSKQH, MSKQL, MSKWH, MSKWL] = | ||
133 : | map binop | ||
134 : | [extbl, extlh, extll, extqh, extql, extwh, extwl, | ||
135 : | insbl, inslh, insll, insqh, insql, inswh, inswl, | ||
136 : | mskbl, msklh, mskll, mskqh, mskql, mskwh, mskwl] | ||
137 : | |||
138 : | rtl [SLL, SRA, SRL] = | ||
139 : | map binop [(<<), (~>>), (>>)] | ||
140 : | |||
141 : | rtl zap zapnot umulh : #n bits * #n bits -> #n bits | ||
142 : | rtl ZAP{ra,rb,rc} = $r[rc] := zap($r[ra], rb) | ||
143 : | rtl ZAPNOT{ra,rb,rc} = $r[rc] := zapnot($r[ra], rb) | ||
144 : | rtl MULL{ra,rb,rc} = $r[rc] := sx(muls($r[ra], rb)) | ||
145 : | rtl MULQ{ra,rb,rc} = $r[rc] := muls($r[ra], rb) | ||
146 : | rtl UMULH{ra,rb,rc} = $r[rc] := umulh($r[ra], rb) | ||
147 : | |||
148 : | (* Integer trapping operators *) | ||
149 : | val overflowtrap = () | ||
150 : | rtl ADDLV{ra,rb,rc} = ADDL{ra,rb,rc} || overflowtrap | ||
151 : | rtl ADDQV{ra,rb,rc} = ADDQ{ra,rb,rc} || overflowtrap | ||
152 : | rtl SUBLV{ra,rb,rc} = SUBL{ra,rb,rc} || overflowtrap | ||
153 : | rtl SUBQV{ra,rb,rc} = SUBQ{ra,rb,rc} || overflowtrap | ||
154 : | rtl MULLV{ra,rb,rc} = MULL{ra,rb,rc} || overflowtrap | ||
155 : | rtl MULQV{ra,rb,rc} = MULQ{ra,rb,rc} || overflowtrap | ||
156 : | |||
157 : | fun lbc(x,y) = andb(x,1) == y | ||
158 : | fun lbs(x,y) = andb(x,1) <> y | ||
159 : | |||
160 : | val comparisons = [(==), lbc, lbs, (>=), (>), (<=), (<), (<>)] | ||
161 : | |||
162 : | (* Conditional moves *) | ||
163 : | fun cmov oper {ra,rb,rc} = if oper($r[ra], 0) then $r[rc] := rb else () | ||
164 : | |||
165 : | rtl CMOV ^^ [EQ, LBC, LBS, GE, GT, LE, LT, NE] = | ||
166 : | map cmov comparisons | ||
167 : | |||
168 : | (* Integer branches *) | ||
169 : | rtl BR{lab} = Jmp(%%lab) | ||
170 : | rtl BSR{lab,r,defs,uses,mem} = | ||
171 : | Call(%%lab) || | ||
172 : | Kill $r[r] || | ||
173 : | Kill $cellset[defs] || | ||
174 : | Use $cellset[uses] || | ||
175 : | $m[??? :mem] := ($m[??? :mem] : #8 bits) | ||
176 : | |||
177 : | fun branch oper {r,lab} = if oper($r[r], 0) then Jmp(%%lab) else () | ||
178 : | |||
179 : | rtl [BEQ, BLBC, BLBS, BGE, BGT, BLE, BLT, BNE] = | ||
180 : | map branch comparisons | ||
181 : | |||
182 : | (* Floating point operators *) | ||
183 : | rtl DEFFREG{FP} = Kill $f[FP] | ||
184 : | |||
185 : | val SU = () | ||
186 : | val SUD = () | ||
187 : | fun farith oper {fa,fb,fc} = $f[fc] := oper($f[fa], $f[fb]) | ||
188 : | fun funary oper {fb,fc} = $f[fc] := oper($f[fb]) | ||
189 : | rtl fops as [ADDS, ADDT, SUBS, SUBT, MULS, MULT, DIVS, DIVT] = | ||
190 : | map farith | ||
191 : | [fadd, fadd, fsub, fsub, fmul, fmul, fdiv, fdiv] | ||
192 : | fun su fop {fa,fb,fc} = fop{fa,fb,fc} || SU | ||
193 : | fun sud fop {fa,fb,fc} = fop{fa,fb,fc} || SUD | ||
194 : | rtl [ADDSSU, ADDTSU, SUBSSU, SUBTSU, MULSSU, MULTSU, DIVSSU, DIVTSU] = | ||
195 : | map su fops | ||
196 : | rtl [ADDSSUD, ADDTSUD, SUBSSUD, SUBTSUD, | ||
197 : | MULSSUD, MULTSUD, DIVSSUD, DIVTSUD] = | ||
198 : | map sud fops | ||
199 : | |||
200 : | rtl cpys cpyse cpysn mf_fpcr mt_fpcr : #64 bits * #64 bits -> #64 bits | ||
201 : | rtl [CPYS,CPYSE, CPYSN, MF_FPCR, MT_FPCR] = | ||
202 : | map farith [cpys, cpyse, cpysn, mf_fpcr, mt_fpcr] | ||
203 : | |||
204 : | rtl cvtlq cvtql cvtqlsv cvtqlv cvtqs cvtqsc | ||
205 : | cvtqt cvtqtc cvtts cvttsc | ||
206 : | cvtst cvtsts cvttq cvttqc : #64 bits -> #64 bits | ||
207 : | |||
208 : | rtl CVT^^[LQ,QL,QLSV,QLV,QS,QSC,QT,QTC,TS,TSC,ST,STS,TQ,TQC] = | ||
209 : | map funary cvt^^[lq,ql,qlsv,qlv,qs,qsc,qt,qtc,ts,tsc,st,sts,tq,tqc] | ||
210 : | |||
211 : | rtl teq tlt tle tun : #64 bits * #64 bits -> #64 bits | ||
212 : | rtl fcmps as [CMPTEQ, CMPTLT, CMPTLE, CMPTUN] = | ||
213 : | map farith [teq, tlt, tle, tun] | ||
214 : | rtl [CMPTEQSU, CMPTLTSU, CMPTLESU, CMPTUNSU] = | ||
215 : | map su fcmps | ||
216 : | |||
217 : | (* Floating point branches *) | ||
218 : | fun fbranch oper {f,lab} = if oper($f[f],???) then Jmp(%%lab) else () | ||
219 : | rtl [FBEQ, FBLT, FBLE, FBNE, FBGE, FBGT] = | ||
220 : | map fbranch [|==|, |<|, |<=|, |<>|, |>=|, |>|] | ||
221 : | |||
222 : | (* Floating point moves *) | ||
223 : | fun fcmove cmp {fa,fb,fc} = | ||
224 : | if cmp($f[fa],???) then $f[fc] := $f[fb] else () | ||
225 : | rtl FCMOV ^^ [EQ, LT, LE, NE, GE, GT] = | ||
226 : | map fcmove [|==|, |<|, |<=|, |<>|, |>=|, |>|] | ||
227 : | |||
228 : | (* Call/return *) | ||
229 : | rtl JSR{r,b,defs,uses,mem} = | ||
230 : | Call($r[b]) || | ||
231 : | Kill $r[r] || | ||
232 : | Kill $cellset[defs] || | ||
233 : | Use $cellset[uses] || | ||
234 : | $m[??? :mem] := ($m[??? :mem] : #8 bits) | ||
235 : | rtl RET{r,b} = Jmp($r[b]) || Kill $r[r] | ||
236 : | rtl JMPL{r,b} = Jmp($r[b]) || Kill $r[r] | ||
237 : | rtl TRAPB{} = () | ||
238 : | |||
239 : | (* Pseudo arithmetic *) | ||
240 : | fun pseudoOp oper {ra,rb,rc,tmps} = | ||
241 : | $r[rc] := oper($r[ra], rb) || | ||
242 : | Kill $cellset[tmps] (* XXX *) | ||
243 : | rtl PSEUDOARITH_ ^^ [ DIVL, DIVLU, DIVQ, DIVQU, | ||
244 : | REML, REMLU, REMQ, REMQU ] = | ||
245 : | map pseudoOp [ divs, divu, divs, divu, (* XXX *) | ||
246 : | rems, remu, rems, remu ] | ||
247 : | (* Pal code | ||
248 : | * Note: I have no idea what these things are, so I'm just going | ||
249 : | * fake them | ||
250 : | *) | ||
251 : | rtl BPT BUGCHK CALLSYS GENTRAP IMB RDUNIQUE WRUNIQUE : #64 bits -> #64 bits | ||
252 : | fun CALL_PAL code {def,use} = | ||
253 : | Call(qword(code(qword 0))) || | ||
254 : | Kill $cellset[def] || | ||
255 : | Use $cellset[use] | ||
256 : | rtl CALL_PAL_ ^^ | ||
257 : | [BPT, BUGCHK, CALLSYS, GENTRAP, IMB, RDUNIQUE, WRUNIQUE] = | ||
258 : | map CALL_PAL | ||
259 : | [BPT, BUGCHK, CALLSYS, GENTRAP, IMB, RDUNIQUE, WRUNIQUE] | ||
260 : | end (* RTL *) | ||
261 : | |||
262 : | |||
263 : | (* | ||
264 : | * Reservation tables and pipeline definitions for scheduling | ||
265 : | *) | ||
266 : | |||
267 : | (* Function units *) | ||
268 : | resource issue and mem and alu and falu and fmul and fdiv and branch | ||
269 : | |||
270 : | (* Different implementations of cpus *) | ||
271 : | cpu default 2 [2 issue, 2 mem, 1 alu] (* 2 issue machine *) | ||
272 : | |||
273 : | (* Definitions of various reservation tables *) | ||
274 : | pipeline NOP _ = [issue] | ||
275 : | and ARITH _ = [issue^^alu] | ||
276 : | and LOAD _ = [issue^^mem] | ||
277 : | and STORE _ = [issue^^mem,mem,mem] | ||
278 : | and FARITH _ = [issue^^falu] | ||
279 : | and FMUL _ = [issue^^fmul,fmul] | ||
280 : | and FDIV _ = [issue^^fdiv,fdiv*50] | ||
281 : | and BRANCH _ = [issue^^branch] | ||
282 : | |||
283 : | (* | ||
284 : | * We now specify the instruction representation, assembly, | ||
285 : | * machine code encoding and ``semantics'' | ||
286 : | *) | ||
287 : | structure Instruction = | ||
288 : | struct | ||
289 : | datatype ea = | ||
290 : | Direct of $GP | ||
291 : | | FDirect of $FP | ||
292 : | | Displace of {base: $GP, disp:int} | ||
293 : | |||
294 : | datatype operand = | ||
295 : | REGop of $GP ``<GP>'' rtl: $r[GP] | ||
296 : | | IMMop of int ``<int>'' rtl: immed int | ||
297 : | | HILABop of LabelExp.labexp ``hi(<labexp>)'' rtl: hi(labexp) | ||
298 : | | LOLABop of LabelExp.labexp ``lo(<labexp>)'' rtl: lo(labexp) | ||
299 : | | LABop of LabelExp.labexp ``<labexp>'' rtl: labexp | ||
300 : | |||
301 : | (* | ||
302 : | * When I say ! after the datatype name XXX, it means generate a | ||
303 : | * function emit_XXX that converts the constructors into the corresponding | ||
304 : | * assembly text. By default, it uses the same name as the constructor, | ||
305 : | * but may be modified by the lowercase/uppercase assembly directive. | ||
306 : | * | ||
307 : | *) | ||
308 : | datatype branch! = (* table C-2 *) | ||
309 : | BR 0x30 | ||
310 : | (*| BSR 0x34 *) | ||
311 : | | BLBC 0x38 | ||
312 : | | BEQ 0x39 | BLT 0x3a | BLE 0x3b | ||
313 : | | BLBS 0x3c | BNE 0x3d | BGE 0x3e | ||
314 : | | BGT 0x3f | ||
315 : | |||
316 : | datatype fbranch! = (* table C-2 *) | ||
317 : | FBEQ 0x31 | FBLT 0x32 | ||
318 : | | FBLE 0x33 | FBNE 0x35 | ||
319 : | | FBGE 0x36 | FBGT 0x37 | ||
320 : | |||
321 : | datatype load! = (* table C-1 *) | ||
322 : | LDB | ||
323 : | | LDW | ||
324 : | | LDBU 0x02 | ||
325 : | | LDWU 0x04 | ||
326 : | | LDL 0x28 | ||
327 : | | LDL_L 0x2A | ||
328 : | | LDQ 0x29 | ||
329 : | | LDQ_L 0x2B | ||
330 : | | LDQ_U 0x0B | ||
331 : | datatype store! = STB 0x0E | STW 0x0D | STL 0x2C | STQ 0x2D | STQ_U 0x0F | ||
332 : | datatype fload [0x20..0x23] ! = LDF | LDG | LDS | LDT | ||
333 : | datatype fstore [0x24..0x27] ! = STF | STG | STS | STT | ||
334 : | |||
335 : | (* non-trapping opcodes *) | ||
336 : | datatype operate! = (* table C-5 *) | ||
337 : | ADDL (0wx10,0wx00) | ADDQ (0wx10,0wx20) | ||
338 : | | CMPBGE(0wx10,0wx0f) | CMPEQ (0wx10,0wx2d) | ||
339 : | | CMPLE (0wx10,0wx6d) | CMPLT (0wx10,0wx4d) | CMPULE (0wx10,0wx3d) | ||
340 : | | CMPULT(0wx10,0wx1d) | SUBL (0wx10,0wx09) | ||
341 : | | SUBQ (0wx10,0wx29) | ||
342 : | | S4ADDL(0wx10,0wx02) | S4ADDQ (0wx10,0wx22) | S4SUBL (0wx10,0wx0b) | ||
343 : | | S4SUBQ(0wx10,0wx2b) | S8ADDL (0wx10,0wx12) | S8ADDQ (0wx10,0wx32) | ||
344 : | | S8SUBL(0wx10,0wx1b) | S8SUBQ (0wx10,0wx3b) | ||
345 : | |||
346 : | | AND (0wx11,0wx00) | BIC (0wx11,0wx08) | BIS (0wx11,0wx20) | ||
347 : | | EQV (0wx11,0wx48) | ||
348 : | | ORNOT (0wx11,0wx28) | XOR (0wx11,0wx40) | ||
349 : | |||
350 : | | EXTBL (0wx12,0wx06) | EXTLH (0wx12,0wx6a) | EXTLL(0wx12,0wx26) | ||
351 : | | EXTQH (0wx12,0wx7a) | EXTQL (0wx12,0wx36) | EXTWH(0wx12,0wx5a) | ||
352 : | | EXTWL (0wx12,0wx16) | INSBL (0wx12,0wx0b) | INSLH(0wx12,0wx67) | ||
353 : | | INSLL (0wx12,0wx2b) | INSQH (0wx12,0wx77) | INSQL(0wx12,0wx3b) | ||
354 : | | INSWH (0wx12,0wx57) | INSWL (0wx12,0wx1b) | MSKBL(0wx12,0wx02) | ||
355 : | | MSKLH (0wx12,0wx62) | MSKLL (0wx12,0wx22) | MSKQH(0wx12,0wx72) | ||
356 : | | MSKQL (0wx12,0wx32) | MSKWH (0wx12,0wx52) | MSKWL(0wx12,0wx12) | ||
357 : | | SLL (0wx12,0wx39) | SRA (0wx12,0wx3c) | SRL (0wx12,0wx34) | ||
358 : | | ZAP (0wx12,0wx30) | ZAPNOT (0wx12,0wx31) | ||
359 : | | MULL (0wx13,0wx00) | MULQ (0wx13,0wx20) | ||
360 : | | UMULH (0wx13,0wx30) | ||
361 : | |||
362 : | (* conditional moves *) | ||
363 : | datatype cmove! = | ||
364 : | CMOVEQ 0wx24 | CMOVLBC 0wx16 | CMOVLBS 0wx14 | ||
365 : | | CMOVGE 0wx46 | CMOVGT 0wx66 | CMOVLE 0wx64 | ||
366 : | | CMOVLT 0wx44 | CMOVNE 0wx26 | ||
367 : | |||
368 : | datatype pseudo_op! = DIVL | DIVLU | DIVQ | DIVQU | ||
369 : | | REML | REMLU | REMQ | REMQU | ||
370 : | |||
371 : | datatype operateV! = (* table C-5 opc/func *) | ||
372 : | ADDLV (0wx10,0wx40) | ADDQV (0wx10,0wx60) | ||
373 : | | SUBLV (0wx10,0wx49) | SUBQV (0wx10,0wx69) | ||
374 : | | MULLV (0wx13,0wx40) | MULQV (0wx13,0wx60) | ||
375 : | |||
376 : | datatype funary! = (* table C-6/C-7 *) | ||
377 : | (* C-6 *) | ||
378 : | CVTLQ (0wx17,0wx010) | CVTQL (0wx17,0wx030) | CVTQLSV (0wx17,0wx530) | ||
379 : | | CVTQLV (0wx17,0wx130) | ||
380 : | |||
381 : | (* C-7 *) | ||
382 : | | CVTQS (0wx16,0wxbc) | CVTQSC (0wx16,0wx3c) | ||
383 : | | CVTQT (0wx16,0wxbe) | CVTQTC (0wx16,0wx3e) | ||
384 : | | CVTTS (0wx16,0wxac) | CVTTSC (0wx16,0wx2c) | ||
385 : | | CVTST (0wx16,0wx2ac) | CVTSTS (0wx16,0wx6ac) | ||
386 : | | CVTTQ (0wx16,0wxaf) | CVTTQC (0wx16,0wx2f) | ||
387 : | |||
388 : | datatype foperate! = (* table C-6 *) | ||
389 : | CPYS (0wx17,0wx20) | CPYSE (0wx17,0wx022) | CPYSN (0wx17,0wx021) | ||
390 : | | MF_FPCR (0wx17,0wx025) | MT_FPCR (0wx17,0wx024) | ||
391 : | |||
392 : | (* table C-7 *) | ||
393 : | | CMPTEQ (0wx16,0wx0a5) | CMPTLT (0wx16,0wx0a6) | CMPTLE (0wx16,0wx0a7) | ||
394 : | | CMPTUN (0wx16,0wx0a4) | ||
395 : | |||
396 : | | CMPTEQSU(0wx16,0wx5a5) | CMPTLTSU(0wx16,0wx5a6) |CMPTLESU(0wx16,0wx5a7) | ||
397 : | | CMPTUNSU(0wx16,0wx5a4) | ||
398 : | |||
399 : | | ADDS (0wx16,0wx080) | ADDT (0wx16,0wx0a0) | ||
400 : | | DIVS (0wx16,0wx083) | DIVT (0wx16,0wx0a3) | ||
401 : | | MULS (0wx16,0wx082) | MULT (0wx16,0wx0a2) | ||
402 : | | SUBS (0wx16,0wx081) | SUBT (0wx16,0wx0a1) | ||
403 : | |||
404 : | datatype fcmove! = | ||
405 : | FCMOVEQ 0wx02a | FCMOVGE 0wx02d | FCMOVGT 0wx02f | ||
406 : | | FCMOVLE 0wx02e | FCMOVLT 0wx02c | FCMOVNE 0wx02b | ||
407 : | |||
408 : | datatype foperateV! = (* table C-7 *) | ||
409 : | ADDSSUD 0wx5c0 | ADDSSU 0wx580 | ||
410 : | | ADDTSUD 0wx5e0 | ADDTSU 0wx5a0 | ||
411 : | | DIVSSUD 0wx5c3 | DIVSSU 0wx583 | ||
412 : | | DIVTSUD 0wx5e3 | DIVTSU 0wx5a3 | ||
413 : | | MULSSUD 0wx5c2 | MULSSU 0wx582 | ||
414 : | | MULTSUD 0wx5e2 | MULTSU 0wx5a2 | ||
415 : | | SUBSSUD 0wx5c1 | SUBSSU 0wx581 | ||
416 : | | SUBTSUD 0wx5e1 | SUBTSU 0wx5a1 | ||
417 : | |||
418 : | datatype osf_user_palcode! = | ||
419 : | BPT 0x80 | BUGCHK 0x81 | CALLSYS 0x83 | ||
420 : | | GENTRAP 0xaa | IMB 0x86 | RDUNIQUE 0x9e | WRUNIQUE 0x9f | ||
421 : | |||
422 : | type addressing_mode = C.cell * operand | ||
423 : | |||
424 : | end (* Instruction *) | ||
425 : | |||
426 : | (* | ||
427 : | * Alpha has very simple instruction encoding formats. | ||
428 : | *) | ||
429 : | instruction formats 32 bits | ||
430 : | Memory{opc:6, ra:5, rb:GP 5, disp: signed 16} (* p3-9 *) | ||
431 : | (* derived from Memory *) | ||
432 : | | Split{le} = let val i = LabelExp.valueOf le | ||
433 : | val w = itow i | ||
434 : | val hi = w ~>> 0w16 | ||
435 : | val lo = w && 0w65535 | ||
436 : | in if lo < 0w32768 then (hi,lo) else (hi+0w1,lo-0w65536) | ||
437 : | end | ||
438 : | | High{le} = let val (hi,_) = Split{le=le} in hi end | ||
439 : | | Low{le} = let val (_,lo) = Split{le=le} in lo end | ||
440 : | | LoadStore{opc,ra,rb,disp} = | ||
441 : | let val disp = | ||
442 : | case disp of | ||
443 : | I.REGop rb => emit_GP rb | ||
444 : | | I.IMMop i => itow i | ||
445 : | | I.HILABop le => High{le=le} | ||
446 : | | I.LOLABop le => Low{le=le} | ||
447 : | | I.LABop le => itow(LabelExp.valueOf le) | ||
448 : | in Memory{opc,ra,rb,disp} | ||
449 : | end | ||
450 : | | ILoadStore{opc,r:GP,b,d} = LoadStore{opc,ra=r,rb=b,disp=d} | ||
451 : | | FLoadStore{opc,r:FP,b,d} = LoadStore{opc,ra=r,rb=b,disp=d} | ||
452 : | |||
453 : | | Jump{opc:6=0wx1a,ra:GP 5,rb:GP 5,h:2,disp:int signed 14} (* table C-3 *) | ||
454 : | | Memory_fun{opc:6, ra:GP 5, rb:GP 5, func:16} (* p3-9 *) | ||
455 : | | Branch{opc:branch 6, ra:GP 5, disp:signed 21} (* p3-10 *) | ||
456 : | | Bsr{opc:6=0wx34, ra:GP 5, disp:signed 21} (* p3-10 *) | ||
457 : | | Fbranch{opc:fbranch 6, ra:FP 5, disp:signed 21} (* p3-10 *) | ||
458 : | (* p3-11 *) | ||
459 : | | Operate0{opc:6,ra:GP 5,rb:GP 5,sbz:13..15=0,_:1=0,func:5..11,rc:GP 5} | ||
460 : | (* p3-11 *) | ||
461 : | | Operate1{opc:6,ra:GP 5,lit:signed 13..20,_:1=1,func:5..11,rc:GP 5} | ||
462 : | | Operate{opc,ra,rb,func,rc} = | ||
463 : | (case rb of | ||
464 : | I.REGop rb => Operate0{opc,ra,rb,func,rc} | ||
465 : | | I.IMMop i => Operate1{opc,ra,lit=itow i,func,rc} | ||
466 : | | I.HILABop le => Operate1{opc,ra,lit=High{le=le},func,rc} | ||
467 : | | I.LOLABop le => Operate1{opc,ra,lit=Low{le=le},func,rc} | ||
468 : | | I.LABop le => Operate1{opc,ra,lit=itow(LabelExp.valueOf le),func,rc} | ||
469 : | ) | ||
470 : | | Foperate{opc:6,fa:FP 5,fb:FP 5,func:5..15,fc:FP 5} | ||
471 : | | Funary{opc:6,fa:5=31,fb:FP 5,func:5..15,fc:FP 5} | ||
472 : | | Pal{opc:6=0,func:26} | ||
473 : | |||
474 : | structure MC = | ||
475 : | struct | ||
476 : | (* compute displacement address *) | ||
477 : | fun disp lab = itow(Label.addrOf lab - !loc - 4) ~>> 0w2 | ||
478 : | val zeroR = Option.valOf(C.zeroReg C.GP) | ||
479 : | end | ||
480 : | |||
481 : | structure Assembly = | ||
482 : | struct | ||
483 : | fun isZero(I.LABop le) = LabelExp.valueOf le = 0 | ||
484 : | | isZero _ = false | ||
485 : | end | ||
486 : | |||
487 : | (* | ||
488 : | * The main instruction set definition consists of the following: | ||
489 : | * 1) constructor-like declaration defines the view of the instruction, | ||
490 : | * 2) assembly directive in funny quotes `` '', | ||
491 : | * 3) machine encoding expression, | ||
492 : | * 4) delay slot directives etc (not necessary in this architecture) | ||
493 : | *) | ||
494 : | instruction | ||
495 : | |||
496 : | (* Pseudo instruction for the register allocator *) | ||
497 : | DEFFREG of $FP (* define a floating point register *) | ||
498 : | asm: ``/* deffreg\t<FP> */'' | ||
499 : | mc: () (* do nothing when emitting code *) | ||
500 : | rtl: ``DEFFREG'' | ||
501 : | |||
502 : | (* Load/Store *) | ||
503 : | | LDA of {r: $GP, b: $GP, d:operand} (* use of REGop is illegal *) | ||
504 : | asm: if isZero d andalso C.sameCell(r,b) then () | ||
505 : | else (``lda\t<r>, <d>''; | ||
506 : | if C.registerId b = 31 then () else ``(<b>)'' | ||
507 : | ) | ||
508 : | mc: ILoadStore{opc=0w08,r,b,d} | ||
509 : | rtl: ``LDA'' | ||
510 : | |||
511 : | | LDAH of {r: $GP, b: $GP, d:operand} (* use of REGop is illegal *) | ||
512 : | asm: (``ldah\t<r>, <d>''; | ||
513 : | if C.registerId b = 31 then () else ``(<b>)'' | ||
514 : | ) | ||
515 : | mc: ILoadStore{opc=0w09,r,b,d} | ||
516 : | rtl: ``LDAH'' | ||
517 : | |||
518 : | | LOAD of {ldOp:load, r: $GP, b: $GP, d:operand, mem:Region.region} | ||
519 : | asm: ``<ldOp>\t<r>, <d>(<b>)<mem>'' | ||
520 : | mc: ILoadStore{opc=emit_load ldOp,r,b,d} | ||
521 : | rtl: ``<ldOp>'' | ||
522 : | latency: 1 | ||
523 : | |||
524 : | | STORE of {stOp:store, r: $GP, b: $GP, d:operand, mem:Region.region} | ||
525 : | asm: ``<stOp>\t<r>, <d>(<b>)<mem>'' | ||
526 : | mc: ILoadStore{opc=emit_store stOp,r,b,d} | ||
527 : | rtl: ``<stOp>'' | ||
528 : | |||
529 : | | FLOAD of {ldOp:fload, r: $FP, b: $GP, d:operand, mem:Region.region} | ||
530 : | asm: ``<ldOp>\t<r>, <d>(<b>)<mem>'' | ||
531 : | mc: FLoadStore{opc=emit_fload ldOp,r,b,d} | ||
532 : | rtl: ``<ldOp>'' | ||
533 : | latency: 1 | ||
534 : | |||
535 : | | FSTORE of {stOp:fstore, r: $FP, b: $GP, d:operand, mem:Region.region} | ||
536 : | asm: ``<stOp>\t<r>, <d>(<b>)<mem>'' | ||
537 : | mc: FLoadStore{opc=emit_fstore stOp,r,b,d} | ||
538 : | rtl: ``<stOp>'' | ||
539 : | |||
540 : | (* Control Instructions *) | ||
541 : | | JMPL of {r: $GP, b: $GP, d:int} * Label.label list | ||
542 : | asm: ``jmp\t<r>, (<b>)'' | ||
543 : | mc: Jump{h=0w0,ra=r,rb=b,disp=d} (* table C-3 *) | ||
544 : | rtl: ``JMPL'' | ||
545 : | |||
546 : | | JSR of {r: $GP, b: $GP, d:int, | ||
547 : | defs: $cellset, uses: $cellset, mem:Region.region} | ||
548 : | asm: ``jsr\t<r>, (<b>)<mem><emit_defs(defs)><emit_uses(uses)>'' | ||
549 : | mc: Jump{h=0w1,ra=r,rb=b,disp=d} | ||
550 : | rtl: ``JSR'' | ||
551 : | |||
552 : | | BSR of {r: $GP, lab: Label.label, | ||
553 : | defs: $cellset, uses: $cellset, mem:Region.region} | ||
554 : | asm: ``bsr\t<r>, <lab><mem><emit_defs(defs)><emit_uses(uses)>'' | ||
555 : | mc: Bsr{ra=r,disp=disp lab} | ||
556 : | rtl: ``BSR'' | ||
557 : | |||
558 : | | RET of {r: $GP, b: $GP, d:int} | ||
559 : | asm: ``ret\t<r>, (<b>)'' | ||
560 : | mc: Jump{h=0w2,ra=r,rb=b,disp=d} | ||
561 : | rtl: ``RET'' | ||
562 : | |||
563 : | | BRANCH of {b:branch, r: $GP, lab:Label.label} | ||
564 : | asm: ``<b>\t<r>, <lab>'' | ||
565 : | mc: Branch{opc=b,ra=r,disp=disp lab} | ||
566 : | rtl: ``<b>'' | ||
567 : | |||
568 : | | FBRANCH of {b:fbranch, f: $FP, lab:Label.label} | ||
569 : | asm: ``<b>\t<f>, <lab>'' | ||
570 : | mc: Fbranch{opc=b,ra=f,disp=disp lab} | ||
571 : | rtl: ``<b>'' | ||
572 : | |||
573 : | (* Integer Operate *) | ||
574 : | | OPERATE of {oper:operate, ra: $GP, rb:operand, rc: $GP} | ||
575 : | (* Pretty print ldgp differently *) | ||
576 : | asm: let fun disp() = ``<oper>\t<ra>, <rb>, <rc>'' | ||
577 : | in case (oper,C.registerId ra,rb,C.registerId rc) of | ||
578 : | (I.BIS,27,I.REGop rb,29) => | ||
579 : | if C.registerId rb = 31 then ``ldgp\t$29, 0($27)'' | ||
580 : | else disp() | ||
581 : | | (I.BIS,26,I.REGop rb,29) => | ||
582 : | if C.registerId rb = 31 then ``ldgp\t$29, 0($26)'' | ||
583 : | else disp() | ||
584 : | | _ => disp() | ||
585 : | end | ||
586 : | mc: let val (opc,func) = emit_operate oper | ||
587 : | in Operate{opc,func,ra,rb,rc} | ||
588 : | end | ||
589 : | rtl: ``<oper>'' | ||
590 : | |||
591 : | | OPERATEV of {oper:operateV, ra: $GP, rb:operand, rc: $GP} | ||
592 : | asm: ``<oper>\t<ra>, <rb>, <rc>'' | ||
593 : | mc: let val (opc,func) = emit_operateV oper | ||
594 : | in Operate{opc,func,ra,rb,rc} | ||
595 : | end | ||
596 : | rtl: ``<oper>'' | ||
597 : | |||
598 : | | CMOVE of {oper:cmove, ra: $GP, rb:operand, rc: $GP} | ||
599 : | asm: ``<oper>\t<ra>, <rb>, <rc>'' | ||
600 : | mc: Operate{opc=0wx11,func=emit_cmove oper,ra,rb,rc} | ||
601 : | rtl: ``<oper>'' | ||
602 : | |||
603 : | | PSEUDOARITH of {oper: pseudo_op, ra: $GP, rb:operand, rc: $GP, | ||
604 : | tmps: $cellset} | ||
605 : | asm: ``<oper>\t<ra>, <rb>, <rc><emit_cellset("tmps",tmps)>'' | ||
606 : | rtl: ``PSEUDOARITH_<oper>'' | ||
607 : | |||
608 : | (* Copy instructions *) | ||
609 : | | COPY of {dst: $GP list, src: $GP list, | ||
610 : | impl:instruction list option ref, tmp: ea option} | ||
611 : | asm: emitInstrs (Shuffle.shuffle{tmp,dst,src}) | ||
612 : | rtl: ``COPY'' | ||
613 : | |||
614 : | | FCOPY of {dst: $FP list, src: $FP list, | ||
615 : | impl:instruction list option ref, tmp: ea option} | ||
616 : | asm: emitInstrs (Shuffle.shufflefp{tmp,dst,src}) | ||
617 : | rtl: ``FCOPY'' | ||
618 : | |||
619 : | (* Floating Point Unary Operation *) | ||
620 : | | FUNARY of {oper:funary, fb: $FP, fc: $FP} | ||
621 : | asm: ``<oper>\t<fb>, <fc>'' | ||
622 : | mc: let val (opc,func) = emit_funary oper | ||
623 : | in Funary{opc,func,fb,fc} | ||
624 : | end | ||
625 : | rtl: ``<oper>'' | ||
626 : | |||
627 : | (* Floating Point Operate *) | ||
628 : | | FOPERATE of {oper:foperate, fa: $FP, fb: $FP, fc: $FP} | ||
629 : | asm: ``<oper>\t<fa>, <fb>, <fc>'' | ||
630 : | mc: let val (opc,func) = emit_foperate oper | ||
631 : | in Foperate{opc,func,fa,fb,fc} | ||
632 : | end | ||
633 : | rtl: ``<oper>'' | ||
634 : | |||
635 : | (* Trapping versions of the above (what trap -- allen) ??? *) | ||
636 : | | FOPERATEV of {oper:foperateV, fa: $FP, fb: $FP, fc: $FP} | ||
637 : | asm: ``<oper>\t<fa>, <fb>, <fc>'' | ||
638 : | mc: Foperate{opc=0wx16,func=emit_foperateV oper,fa,fb,fc} | ||
639 : | rtl: ``<oper>'' | ||
640 : | |||
641 : | | FCMOVE of {oper:fcmove, fa: $FP, fb: $FP, fc: $FP} | ||
642 : | asm: ``<oper>\t<fa>, <fb>, <fc>'' | ||
643 : | mc: Foperate{opc=0wx17,func=emit_fcmove oper,fa,fb,fc} | ||
644 : | rtl: ``<oper>'' | ||
645 : | |||
646 : | (* Misc *) | ||
647 : | | TRAPB (* Trap barrier *) | ||
648 : | asm: ``trapb'' | ||
649 : | mc: Memory_fun{opc=0wx18,ra=zeroR,rb=zeroR,func=0wx0} | ||
650 : | rtl: ``TRAPB'' | ||
651 : | |||
652 : | | CALL_PAL of {code:osf_user_palcode, def: $cellset, use: $cellset} | ||
653 : | asm: ``call_pal <code>'' | ||
654 : | mc: Pal{func=emit_osf_user_palcode code} | ||
655 : | rtl: ``CALL_PAL_<code>'' | ||
656 : | |||
657 : | | ANNOTATION of {i:instruction, a:Annotations.annotation} | ||
658 : | asm: (comment(Annotations.toString a); nl(); emitInstr i) | ||
659 : | mc: (emitInstr i) | ||
660 : | (* rtl: [[ #i ]] *) | ||
661 : | |||
662 : | | SOURCE of {} | ||
663 : | asm: ``source'' | ||
664 : | mc: () | ||
665 : | |||
666 : | | SINK of {} | ||
667 : | asm: ``sink'' | ||
668 : | mc: () | ||
669 : | |||
670 : | | PHI of {} | ||
671 : | asm: ``phi'' | ||
672 : | mc: () | ||
673 : | |||
674 : | structure SSA = | ||
675 : | struct | ||
676 : | fun operand(ty, I.REGop r) = T.REG(ty, r) | ||
677 : | | operand(ty, I.IMMop i) = T.LI i | ||
678 : | | operand(ty, _) = error "operand" | ||
679 : | end | ||
680 : | |||
681 : | end |
root@smlnj-gforge.cs.uchicago.edu | ViewVC Help |
Powered by ViewVC 1.0.0 |