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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1326 - (view) (download)

1 : allenleung 1326 (*
2 :     * MIPS IV architecture.
3 :     *
4 :     * Note: information herein is derived from the documents
5 :     * ``MIPSpro Assembly Language Programmer's Guide''
6 :     * Document Number 007-2318-002 and
7 :     *
8 :     * MIPS R4000 Microprocessor User's Manual, Second Edition
9 :     *
10 :     * MIPS IV Instruction Set Revision 3.2 Sept, 1995, Charles Price
11 :     *
12 :     * Basically, the differences between MIPS I, II, III, IV are:
13 :     *
14 :     * MIPS I: old 32-bit architecture. I think this
15 :     one has delay loads with no interlock(?)
16 :     * MIPS II: some 64-bit operations (32-bit address space?)
17 :     * MIPS III: 64-bit CPU with unsigned word loads
18 :     * MIPS IV: register + register addressing mode for FPU
19 :     *
20 :     * We will support MIPS III and MIPS IV in MLRISC, and also provide
21 :     * support for 32-bit mode. But MIPS I and MIPS II will not be supported.
22 :     *
23 :     * -- Allen (leunga@cs.nyu.edu)
24 :     *)
25 :     architecture MIPS =
26 :     struct
27 :    
28 :     superscalar
29 :    
30 :     little endian (* is this right??? *)
31 :    
32 :     lowercase assembly
33 :    
34 :     storage
35 :     GP = $r[32] of 64 bits where $r[0] = 0
36 :     asm: (fn (1,_) => "$at" (* assembler temporary *)
37 :     | (28,_) => "$gp" (* global pointer *)
38 :     | (29,_) => "$sp" (* stack pointer *)
39 :     | (30,_) => "$fp" (* frame pointer *)
40 :     | (r,_) => "$"^Int.toString r)
41 :     | FP = $f[32] of 64 bits asm: (fn (f,_) => "$f"^Int.toString f)
42 :     | CC = $cc[] of 64 bits aliasing GP asm: (fn (r,_) => "$"^Int.toString r)
43 :    
44 :     (* condition code register *)
45 :     | COND = $cond[8] of 64 bits asm: (fn (r,_) => Int.toString r)
46 :     | HI = $hi[1] of 64 bits asm: "$hi"
47 :     | LO = $lo[1] of 64 bits asm: "$lo"
48 :     | MEM = $m[] of 8 aggregable bits asm: (fn (r,_) => "m"^Int.toString r)
49 :     | CTRL = $ctrl[] asm: (fn (r,_) => "ctrl"^Int.toString r)
50 :    
51 :     locations
52 :     stackptrR = $r[29]
53 :     and linkR = $r[31] (* link address from JAL *)
54 :     and frameptrR = $r[30]
55 :     and globalptrR = $r[28]
56 :     and asmTmpR = $r[1]
57 :     and fasmTmp = $f[30]
58 :     and r0 = $r[0]
59 :    
60 :     (* Note on MIPS terminologies
61 :     *
62 :     * B byte - 8 bits
63 :     * H halfword - 16 bits
64 :     * W word - 32 bits
65 :     * D double - 64 bits
66 :     *)
67 :     structure RTL =
68 :     struct
69 :     include "Tools/basis.mdl"
70 :     open Basis
71 :    
72 :     fun disp(b,d) = $r[b] + d
73 :     fun byte x = (x : #8 bits)
74 :     fun half x = (x : #16 bits)
75 :     fun word x = (x : #32 bits)
76 :     fun dword x = (x : #64 bits)
77 :    
78 :     rtl LB{rt,b,d,mem} = $r[rt] := sx(byte $m[disp(b,d):mem])
79 :     rtl LBU{rt,b,d,mem} = $r[rt] := zx(byte $m[disp(b,d):mem])
80 :     rtl LH{rt,b,d,mem} = $r[rt] := sx(half $m[disp(b,d):mem])
81 :     rtl LHU{rt,b,d,mem} = $r[rt] := zx(half $m[disp(b,d):mem])
82 :     rtl LW{rt,b,d,mem} = $r[rt] := sx(word $m[disp(b,d):mem])
83 :     rtl LD{rt,b,d,mem} = $r[rt] := dword $m[disp(b,d):mem]
84 :    
85 :     end
86 :    
87 :     structure Instruction =
88 :     struct
89 :    
90 :     (* L[BWH] are sign extended by default *)
91 :     datatype load! = LD | LW | LH | LHU | LB | LBU
92 :     | LWL | LWR | LWU | LDL | LDR
93 :     | ULH | ULHU | ULW | ULD (* unaligned *)
94 :    
95 :     datatype store! = SD | SW | SH | SB
96 :     | SWL | SWR | SDL | SDR
97 :     | USH | USW | USD
98 :    
99 :     datatype fload! = LDC1 | LWC1
100 :     datatype fstore! = SDC1 | SWC1
101 :    
102 :     datatype fcond =
103 :     FF "f" | FUN "un" | FEQ "eq" | FUEQ "fueq"
104 :     | FOLT "folt" | FULT "ult" | FOLE "ole" | FULE "ule"
105 :     | FNGLE "ngle" | FSP "sf" | FNGL "ngl" | FSEQ "seq"
106 :     | FLT "flt" | FNGE "fnge" | FLE "le" | FNGT "ngt"
107 :    
108 :     datatype cond! =
109 :     EQ | NE | LEZ | GTZ | LTZ | GEZ
110 :    
111 :     datatype fbranch! = BC1T (* true *) | BC1F (* false *)
112 :    
113 :     datatype likely = LIKELY "L" | UNLIKELY ""
114 :    
115 :     (*
116 :     * Note, ADD may raise overflow exception
117 :     * ADDU is the non-trapping version.
118 :     * Same with other operators such as DADD, SUB, DSUB etc.
119 :     *
120 :     * Instructions that may take 16-bit immediate operands:
121 :     * ADDI, ADDIU, SLTI, SLTIU, ANDI,
122 :     * ORI, XORI, LUI, DADDI, DADDIU
123 :     *
124 :     * The immediate operands are unsigned in ORI, ANDI, XORI
125 :     *)
126 :     datatype arith! = ADD | ADDU | AND | XOR | MUL
127 :     | MULO | MULOU | NOR | OR
128 :     | SEQ | SGT | SGE | SGEU | SGTU | SLT | SLE
129 :     | SLEU | SLTU | SNE | SUB | SUBU | REM | REMU
130 :     | SRA | SLL | SRL | ROR | ROL
131 :     | MOVN | MOVZ (* conditional moves *)
132 :    
133 :     (* 64-bit operations from MIPS III *)
134 :     | DADD | DADDU | DMUL | DMULO | DMULOU
135 :     | DSUB | DSUBU | DREM | DREMU
136 :     | DROL | DROR
137 :     | DSLL | DSLL32 | DSLLV
138 :     | DSRA | DSRA32 | DSRAV
139 :     | DSRL | DSRL32 | DSRLV
140 :    
141 :     datatype unary! = ABS | NEG | NEGU | NOT
142 :     | DABS | DNEG | DNEGU
143 :    
144 :     datatype multiply! = MULT | MULTU | DMULT | DMULTU
145 :    
146 :     datatype divide! = DIV | DIVU | DDIV | DDIVU
147 :    
148 :     datatype trap! = TEQ | TNE | TLT | TLTU | TGE | TGEU
149 :    
150 :     datatype farith! = ADD_D "add.d" | ADD_S "add.s"
151 :     | SUB_D "sub.d" | SUB_S "sub.s"
152 :     | MUL_D "mul.d" | MUL_S "mul.s"
153 :     | DIV_D "div.d" | DIV_S "div.s"
154 :    
155 :     datatype funary! = MOV_D "mov.d" | MOV_S "mov.s"
156 :     | ABS_D "abs.d" | ABS_S "abs.s"
157 :     | NEG_D "neg.d" | NEG_S "neg.s"
158 :     | SQRT_D "sqrt.d" | SQRT_S "sqrt.s"
159 :    
160 :     | CVT_SD "cvt.s.d" (* S <- D *)
161 :     | CVT_SW "cvt.s.w"
162 :     | CVT_DS "cvt.d.s"
163 :     | CVT_DW "cvt.d.w"
164 :     | CVT_WS "cvt.w.s"
165 :     | CVT_WD "cvt.w.d"
166 :     | CVT_SL "cvt.s.l"
167 :     | CVT_DL "cvt.d.l"
168 :     | CVT_LS "cvt.l.s"
169 :     | CVT_LD "cvt.l.d"
170 :    
171 :     datatype cvti2f! = MTC1 | DMTC1
172 :     datatype cvtf2i! = MFC1 | DMFC1
173 :    
174 :     (* multiply and add/subtract *)
175 :     datatype farith3! = MADD_D "madd.d" | MADD_S "madd.s"
176 :     | NMADD_D "nmadd.d" | NMADD_S "nmadd.s"
177 :     | MSUB_D "msub.d" | MSUB_S "msub.s"
178 :     | NMSUB_D "nmsub.d" | NMSUB_S "nmsub.s"
179 :    
180 :     (* truncate and rounding *)
181 :     datatype fround! = TRUNC_WS "trunc.w.s"
182 :     | TRUNC_WD "trunc.w.d"
183 :     | ROUND_WS "round.w.d"
184 :     | ROUND_WD "round.w.d"
185 :     | CEIL_WD "ceil.w.d"
186 :     | CEIL_WS "ceil.w.s"
187 :     | CEILU_WD "ceilu.w.d"
188 :     | CEILU_WS "ceilu.w.s"
189 :     | FLOOR_WD "floor.w.d"
190 :     | FLOOR_WS "floor.w.s"
191 :     | FLOORU_WD "flooru.w.d"
192 :     | FLOORU_WS "flooru.w.s"
193 :     | ROUNDU_WD "roundu.w.d"
194 :     | ROUNDU_WS "roundu.w.s"
195 :     | TRUNCU_WD "truncu.w.d"
196 :     | TRUNCU_WS "truncu.w.s"
197 :     | TRUNC_LS "trunc.l.s"
198 :     | TRUNC_LD "trunc.l.d"
199 :     | ROUND_LS "round.l.s"
200 :     | ROUND_LD "round.l.d"
201 :     | CEIL_LS "ceil.l.s"
202 :     | CEIL_LD "ceil.l.d"
203 :     | FLOOR_LS "floor.l.s"
204 :     | FLOOR_LD "floor.l.d"
205 :    
206 :     datatype fmt = SINGLE "S" | DOUBLE "D"
207 :    
208 :     datatype operand! = Imm of int ``<int>'' rtl: immed int (* 16 bits *)
209 :     | Reg of $GP ``<GP>'' rtl: $r[GP]
210 :     | Lab of T.labexp ``<labexp>''
211 :     | HiLab of T.labexp ``$hi(<labexp>)''
212 :     | LoLab of T.labexp ``$lo(<labexp>)''
213 :    
214 :     datatype ea = Direct of $GP
215 :     | FDirect of $FP
216 :     | Displace of {base: $GP, disp:int}
217 :    
218 :     type addressing_mode = C.cell * operand
219 :    
220 :     end (* Instruction *)
221 :    
222 :     (*
223 :     * MIPS instructions are all 32-bits.
224 :     * Address offsets in base+disp is 16 bits.
225 :     *)
226 :     instruction formats 32 bits
227 :     Load{l:6, rt: $GP 5, b: $GP 5, offset:signed 16}
228 :    
229 :     | Special{_:6=0, rs: $GP 5, rt: $GP 5, _:10=0, opc:6}
230 :    
231 :    
232 :     (*
233 :     * Assembly output helper functions
234 :     *)
235 :     structure Assembly =
236 :     struct
237 :     (* Add the i suffix for immediate operands of arithmetic instructions
238 :     * For example:
239 :     * ADD rt, rs1, rs2
240 :     * ADDI rt, rs, 10
241 :     * ADDU rt, rs1, rs2
242 :     * ADDIU rt, rs, 10
243 :     *)
244 :     fun immedSuffix(s, I.Reg _) = s
245 :     | immedSuffix(s, _) =
246 :     let val n = String.size s
247 :     in case String.sub(s, n-1) of
248 :     #"u" => String.substring(s, 0, n-1)^"iu"
249 :     | _ => s^"i"
250 :     end
251 :    
252 :     (* LDC1 -> LDXC1 when using the indexed addressing mode *)
253 :     fun indexed(s, I.Reg _) =
254 :     let val prefix = String.substring(s, 0, 2)
255 :     val suffix = String.substring(s, 2, 4)
256 :     in prefix^"x"^suffix end
257 :     | indexed(s, _) = s
258 :    
259 :     (* Emit nop at delay slot *)
260 :     fun emit_nop false = () | emit_nop true = emit "\n\tnop"
261 :     end (* Asm *)
262 :    
263 :     (*
264 :     * Reservation tables and pipeline definitions for scheduling
265 :     *)
266 :    
267 :     (* Function units *)
268 :     resource mem and alu and falu and fmul and fdiv and branch
269 :    
270 :     (* Different implementations of cpus *)
271 :     cpu default 4 [1 mem, 2 alu, 2 falu, 2 fmul, 1 fdiv, 1 branch]
272 :    
273 :     (* Definitions of various reservation tables *)
274 :     pipeline NOP _ = []
275 :     and ARITH _ = [alu]
276 :     and LOAD _ = [mem]
277 :     and STORE _ = [mem,mem,mem]
278 :     and FARITH _ = [falu]
279 :     and FMUL _ = [fmul,fmul]
280 :     and FDIV _ = [fdiv,fdiv*50]
281 :     and BRANCH _ = [branch]
282 :    
283 :     instruction
284 :     NOP
285 :     ``nop''
286 :    
287 :     (*
288 :     * Load upper immediate
289 :     *)
290 :     | LUI of {rt: $GP, imm:operand}
291 :     ``lui\t<rt>, <imm>''
292 :    
293 :     (*
294 :     * Load address
295 :     *)
296 :     | LA of {rt: $GP, b: $GP, d:operand}
297 :     ``la\t<rt>, <b>, <d>''
298 :    
299 :     | DLA of {rt: $GP, b: $GP, d:operand}
300 :     ``dla\t<rt>, <b>, <d>''
301 :    
302 :     (*
303 :     * load and store instructions:
304 :     *)
305 :     | LOAD of {l:load, rt: $GP, b: $GP, d:operand, mem:Region.region}
306 :     asm: ``<l>\t<rt>, <d>(<b>)<mem>''
307 :     rtl: ``<l>''
308 :    
309 :     | STORE of {s:store, rs: $GP, b: $GP, d:operand, mem:Region.region}
310 :     ``<s>\t<rs>, <d>(<b>)<mem>''
311 :    
312 :     | FLOAD of {l:fload, ft: $FP, b: $GP, d:operand, mem:Region.region}
313 :     ``<indexed(asm_fload l,d)>\t<ft>, <d>(<b>)<mem>''
314 :    
315 :     | FSTORE of {s:fstore, fs: $GP, b: $GP, d:operand, mem:Region.region}
316 :     ``<indexed(asm_fstore s,d)>\t<fs>, <d>(<b>)<mem>''
317 :    
318 :     (*
319 :     * compare instructions:
320 :     *)
321 :     | FCMP of {fcond:fcond, fmt:fmt, cc: $COND, fs1: $FP, fs2: $FP}
322 :     ``c.<fcond>.<fmt>\t<cc>, <fs1>, <fs2>''
323 :    
324 :     (*
325 :     * Integer trapping
326 :     *)
327 :     | TRAP of {t:trap, rs: $GP, i:operand}
328 :     ``<t>\t<rs>, <i>''
329 :    
330 :     (*
331 :     * Branch instructions.
332 :     * All branch instruction have delayslots.
333 :     * We represent them as complex instructions with optional nops attached
334 :     *)
335 :    
336 :     (* jump; branch delay *)
337 :     | J of {lab:Label.label, nop:bool}
338 :     asm: ``j\t<lab><nop>''
339 :     padding: nop
340 :     delayslot: true
341 :     delayslot candidate: false
342 :    
343 :     (* jump register; branch delay *)
344 :     | JR of {rs: $GP, labels:Label.label list, nop:bool}
345 :     asm: ``jr\t<rs><nop>''
346 :     padding: nop
347 :     delayslot: true
348 :     delayslot candidate: false
349 :    
350 :     (* jump and link, set $r31 <- PC + 8; branch delay *)
351 :     | JAL of {lab:Label.label, defs:C.cellset, uses: C.cellset,
352 :     cutsTo: Label.label list, mem:Region.region, nop:bool}
353 :     asm: ``jal\t<lab><mem><
354 :     emit_defs(defs)><emit_uses(uses)><emit_cutsTo cutsTo><nop>''
355 :     padding: nop
356 :     delayslot: true
357 :     delayslot candidate: false
358 :    
359 :     (* jump and link register, set $rt <- PC + 8; branch delay *)
360 :     | JALR of {rt: $GP, rs: $GP,
361 :     defs:C.cellset, uses: C.cellset,
362 :     cutsTo: Label.label list, mem:Region.region, nop:bool}
363 :     asm: ``jalr\t<rt>, <rs><mem><
364 :     emit_defs(defs)><emit_uses(uses)><emit_cutsTo cutsTo><nop>''
365 :     padding: nop
366 :     delayslot: true
367 :     delayslot candidate: false
368 :    
369 :     (* pseudo op for return; branch delay *)
370 :     | RET of {nop:bool}
371 :     asm: ``jr\t$31<nop>''
372 :     padding: nop
373 :     delayslot: true
374 :     delayslot candidate: false
375 :    
376 :     (* Branch; comparing rs and rt *)
377 :     | BRANCH of {likely:likely, cond:cond, rs: $GP, rt: $GP,
378 :     lab:Label.label, nop:bool}
379 :     asm: ``b<cond><likely>\t<rs>, <rt>, <lab><nop>''
380 :     padding: nop
381 :     delayslot: true
382 :     delayslot candidate: false
383 :    
384 :     (* Note: on MIPS II, III there must be at least one instruction
385 :     * between the set condition code instruction and the branch *)
386 :     | FBRANCH of {likely:likely, fbranch:fbranch, cc: $COND, lab:Label.label,
387 :     nop:bool}
388 :     asm: ``<fbranch><likely>\t<cc>, <lab><nop>''
389 :     padding: nop
390 :     delayslot: true
391 :     delayslot candidate: false
392 :    
393 :     (*
394 :     * Arithmetic instructions:
395 :     * arguments are (rt,rs,rt/immed) with the exception of sub (sigh).
396 :     *)
397 :     | ARITH of {oper:arith, rt: $GP, rs: $GP, i:operand}
398 :     ``<immedSuffix(asm_arith oper, i)>\t<rt>, <rs>, <i>''
399 :    
400 :     | UNARY of {oper:unary, rt: $GP, rs: $GP}
401 :     ``<oper>\t<rt>, <rs>''
402 :    
403 :     (*
404 :     * integer mult and div related:
405 :     *)
406 :     | MULTIPLY of {oper:multiply, rt: $GP, rs: $GP}
407 :     ``<oper>\t<rt>, <rs>''
408 :    
409 :     | DIVIDE of {oper:divide, rt: $GP, rs: $GP}
410 :     ``<oper>\t<rt>, <rs>''
411 :    
412 :     | MFLO of $GP
413 :     ``mflo\t<GP>''
414 :    
415 :     | MTLO of $GP
416 :     ``mtlo\t<GP>''
417 :    
418 :     | MFHI of $GP
419 :     ``mfhi\t<GP>''
420 :    
421 :     | MTHI of $GP
422 :     ``mthi\t<GP>''
423 :    
424 :     | BREAK of int
425 :     ``break\t<int>''
426 :    
427 :     (*
428 :     * Floating point arithmetic:
429 :     *)
430 :     | FARITH of {oper:farith, ft: $FP, fs1: $FP, fs2: $FP}
431 :     ``<oper>\t<ft>, <fs1>, <fs2>''
432 :    
433 :     | FUNARY of {oper:funary, ft: $FP, fs: $FP}
434 :     ``<oper>\t<ft>, <fs>''
435 :    
436 :     | FARITH3 of {oper:farith3, ft: $FP, fs1: $FP, fs2: $FP, fs3: $FP}
437 :     ``<oper>\t<ft>, <fs1>, <fs2>, <fs3>''
438 :    
439 :     | FROUND of {oper:fround, ft: $FP, fs1: $FP, rs2: $GP}
440 :     ``<oper>\t<ft>, <fs1>, <fs1>, <rs2>''
441 :    
442 :     | CVTI2F of {cvt:cvti2f, rs: $GP, ft: $FP}
443 :     ``<cvt>\t<ft>, <rs>''
444 :    
445 :     | CVTF2I of {cvt:cvtf2i, fs: $FP, rt: $GP}
446 :     ``<cvt>\t<rt>, <fs>''
447 :    
448 :     | COPY of { dst: $GP list, src: $GP list,
449 :     impl:instruction list option ref, tmp:ea option}
450 :     asm: emitInstrs (Shuffle.shuffle{tmp,src,dst})
451 :    
452 :     | FCOPY of { dst: $FP list, src: $FP list,
453 :     impl:instruction list option ref, tmp:ea option}
454 :     asm: emitInstrs (Shuffle.shufflefp{tmp,src,dst})
455 :    
456 :     | ANNOTATION of {i:instruction, a:Annotations.annotation}
457 :     asm: (comment(Annotations.toString a); nl(); emitInstr i)
458 :     mc: (emitInstr i)
459 :    
460 :     | PHI of {}
461 :     asm: ``phi''
462 :     mc: ()
463 :    
464 :     | SOURCE of {}
465 :     asm: ``source''
466 :     mc: ()
467 :    
468 :     | SINK of {}
469 :     asm: ``sink''
470 :     mc: ()
471 :     end

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