(* * This machine description now includes 64-bit and single precision * floating point support. The description * is copied from the book ``Alpha Architecture Reference Manual'' edited * by Richard L. Sites, Digital Press, 1992. * * -- Allen Leung *) architecture Alpha = struct superscalar little endian lowercase assembly (* * This specify the cells interface *) storage GP = $r[32] of 64 bits where $r[31] = 0 asm: (fn (30,_) => "$sp" | (r,_) => "$"^Int.toString r ) | FP = $f[32] of 64 bits where $f[31] = 0 asm: (fn (f,_) => "$f"^Int.toString f) | CC = $cc[] of 64 bits aliasing GP asm: "cc" | MEM = $m[] of 8 aggregable bits asm: (fn (r,_) => "m"^Int.toString r) | CTRL = $ctrl[] asm: (fn (r,_) => "ctrl"^Int.toString r) locations stackptrR = $r[30] and asmTmpR = $r[28] and fasmTmp = $r[30] and returnAddr = $r[26] and r31 = $r[31] and f31 = $f[31] structure RTL = struct include "Tools/basis.mdl" open Basis infix 1 || infix 2 := infix 3 << >> ~>> (* rtl COPY{dst,src} = $r[forall dst] := $r[forall src] rtl FCOPY{dst,src} = $f[forall dst] := $f[forall src] *) (* How to align addresses *) fun align4 addr = andb(addr,notb 3) fun align8 addr = andb(addr,notb 7) fun align8Upper addr = orb(andb(addr,notb 7),4) fun %% l = (l : #64 bits) fun disp(b,d) = $r[b] + d fun byte x = (x : #8 bits) fun word x = (x : #16 bits) fun dword x = (x : #32 bits) fun qword x = (x : #64 bits) fun float x = (x : #32 bits) fun double x = (x : #64 bits) rtl LDA{r,b,d} = $r[r] := $r[b] + d rtl LDAH{r,b,d} = $r[r] := $r[b] + d << 16 (* Integer loads *) rtl LDB{r,b,d,mem} = $r[r] := sx (byte $m[disp(b,d):mem]) rtl LDW{r,b,d,mem} = $r[r] := sx (word $m[disp(b,d):mem]) rtl LDBU{r,b,d,mem} = $r[r] := zx (byte $m[disp(b,d):mem]) rtl LDWU{r,b,d,mem} = $r[r] := zx (word $m[disp(b,d):mem]) rtl LDL{r,b,d,mem} = $r[r] := sx (dword $m[disp(b,d):mem]) rtl LDL_L{r,b,d,mem} = $r[r] := sx (dword $m[align4(disp(b,d)):mem]) rtl LDQ{r,b,d,mem} = $r[r] := qword $m[disp(b,d):mem] rtl LDQ_L{r,b,d,mem} = $r[r] := qword $m[align8(disp(b,d)):mem] rtl LDQ_U{r,b,d,mem} = $r[r] := qword $m[align8Upper(disp(b,d)):mem] (* Integer stores *) rtl STB{r,b,d,mem} = $m[disp(b,d):mem] := $r[r] at [0..7] rtl STW{r,b,d,mem} = $m[disp(b,d):mem] := $r[r] at [0..15] rtl STL{r,b,d,mem} = $m[disp(b,d):mem] := $r[r] at [0..31] rtl STQ{r,b,d,mem} = $m[disp(b,d):mem] := $r[r] rtl STQ_U{r,b,d,mem} = $m[align8(disp(b,d)):mem] := $r[r] (* Floating point loads *) rtl LDF{r,b,d,mem} = $f[r] := sx (float $m[disp(b,d):mem]) rtl LDG{r,b,d,mem} = $f[r] := double $m[disp(b,d):mem] rtl LDS{r,b,d,mem} = $f[r] := double $m[disp(b,d):mem] rtl LDT{r,b,d,mem} = $f[r] := double $m[disp(b,d):mem] (* Floating point stores *) rtl STF{r,b,d,mem} = $m[disp(b,d):mem] := float(sx $f[r]) rtl STG{r,b,d,mem} = $m[disp(b,d):mem] := $f[r] rtl STS{r,b,d,mem} = $m[disp(b,d):mem] := $f[r] rtl STT{r,b,d,mem} = $m[disp(b,d):mem] := $f[r] (* Integer operators *) rtl ADDL{ra,rb,rc} = $r[rc] := sx($r[ra] + rb) rtl ADDQ{ra,rb,rc} = $r[rc] := $r[ra] + rb fun cmp oper {ra,rb,rc} = $r[rc] := cond(oper($r[ra],rb), 1, 0) rtl [CMPBGE, CMPEQ, CMPLE, CMPLT, CMPULE, CMPULT] = map cmp [(>=), (==), (<=), (<), (leu), (ltu)] fun binop oper {ra,rb,rc} = $r[rc] := oper($r[ra], rb) rtl SUBL{ra,rb,rc} = $r[rc] := sx($r[ra] - rb) rtl SUBQ{ra,rb,rc} = $r[rc] := $r[ra] - rb rtl S4ADDL{ra,rb,rc} = $r[rc] := sx($r[ra] << 2 + rb) rtl S4ADDQ{ra,rb,rc} = $r[rc] := $r[ra] << 2 + rb rtl S4SUBL{ra,rb,rc} = $r[rc] := sx($r[ra] << 2 - rb) rtl S4SUBQ{ra,rb,rc} = $r[rc] := $r[ra] << 2 - rb rtl S8ADDL{ra,rb,rc} = $r[rc] := sx($r[ra] << 3 + rb) rtl S8ADDQ{ra,rb,rc} = $r[rc] := $r[ra] << 3 + rb rtl S8SUBL{ra,rb,rc} = $r[rc] := sx($r[ra] << 3 - rb) rtl S8SUBQ{ra,rb,rc} = $r[rc] := $r[ra] << 3 - rb rtl AND{ra,rb,rc} = $r[rc] := andb($r[ra], rb) rtl BIC{ra,rb,rc} = $r[rc] := andb($r[ra], notb(rb)) (* XXX *) rtl BIS{ra,rb,rc} = $r[rc] := orb($r[ra], rb) rtl EQV{ra,rb,rc} = $r[rc] := eqvb($r[ra], rb) rtl ORNOT{ra,rb,rc} = $r[rc] := orb($r[ra], notb(rb)) rtl XOR{ra,rb,rc} = $r[rc] := xorb($r[ra], rb) rtl extbl extlh extll extqh extql extwh extwl insbl inslh insll insqh insql inswh inswl mskbl msklh mskll mskqh mskql mskwh mskwl : #n bits * #n bits -> #n bits rtl [EXTBL, EXTLH, EXTLL, EXTQH, EXTQL, EXTWH, EXTWL, INSBL, INSLH, INSLL, INSQH, INSQL, INSWH, INSWL, MSKBL, MSKLH, MSKLL, MSKQH, MSKQL, MSKWH, MSKWL] = map binop [extbl, extlh, extll, extqh, extql, extwh, extwl, insbl, inslh, insll, insqh, insql, inswh, inswl, mskbl, msklh, mskll, mskqh, mskql, mskwh, mskwl] rtl [SLL, SRA, SRL] = map binop [(<<), (~>>), (>>)] rtl zap zapnot umulh : #n bits * #n bits -> #n bits rtl ZAP{ra,rb,rc} = $r[rc] := zap($r[ra], rb) rtl ZAPNOT{ra,rb,rc} = $r[rc] := zapnot($r[ra], rb) rtl MULL{ra,rb,rc} = $r[rc] := sx(muls($r[ra], rb)) rtl MULQ{ra,rb,rc} = $r[rc] := muls($r[ra], rb) rtl UMULH{ra,rb,rc} = $r[rc] := umulh($r[ra], rb) (* Integer trapping operators *) val overflowtrap = () rtl ADDLV{ra,rb,rc} = ADDL{ra,rb,rc} || overflowtrap rtl ADDQV{ra,rb,rc} = ADDQ{ra,rb,rc} || overflowtrap rtl SUBLV{ra,rb,rc} = SUBL{ra,rb,rc} || overflowtrap rtl SUBQV{ra,rb,rc} = SUBQ{ra,rb,rc} || overflowtrap rtl MULLV{ra,rb,rc} = MULL{ra,rb,rc} || overflowtrap rtl MULQV{ra,rb,rc} = MULQ{ra,rb,rc} || overflowtrap fun lbc(x,y) = andb(x,1) == y fun lbs(x,y) = andb(x,1) <> y val comparisons = [(==), lbc, lbs, (>=), (>), (<=), (<), (<>)] (* Conditional moves *) fun cmov oper {ra,rb,rc} = if oper($r[ra], 0) then $r[rc] := rb else () rtl CMOV ^^ [EQ, LBC, LBS, GE, GT, LE, LT, NE] = map cmov comparisons (* Integer branches *) rtl BR{lab} = Jmp(%%lab) rtl BSR{lab,r,defs,uses,mem} = Call(%%lab) || Kill $r[r] || Kill $cellset[defs] || Use $cellset[uses] || $m[??? :mem] := ($m[??? :mem] : #8 bits) fun branch oper {r,lab} = if oper($r[r], 0) then Jmp(%%lab) else () rtl [BEQ, BLBC, BLBS, BGE, BGT, BLE, BLT, BNE] = map branch comparisons (* Floating point operators *) rtl DEFFREG{FP} = Kill $f[FP] val SU = () val SUD = () fun farith oper {fa,fb,fc} = $f[fc] := oper($f[fa], $f[fb]) fun funary oper {fb,fc} = $f[fc] := oper($f[fb]) rtl fops as [ADDS, ADDT, SUBS, SUBT, MULS, MULT, DIVS, DIVT] = map farith [fadd, fadd, fsub, fsub, fmul, fmul, fdiv, fdiv] fun su fop {fa,fb,fc} = fop{fa,fb,fc} || SU fun sud fop {fa,fb,fc} = fop{fa,fb,fc} || SUD rtl [ADDSSU, ADDTSU, SUBSSU, SUBTSU, MULSSU, MULTSU, DIVSSU, DIVTSU] = map su fops rtl [ADDSSUD, ADDTSUD, SUBSSUD, SUBTSUD, MULSSUD, MULTSUD, DIVSSUD, DIVTSUD] = map sud fops rtl cpys cpyse cpysn mf_fpcr mt_fpcr : #64 bits * #64 bits -> #64 bits rtl [CPYS,CPYSE, CPYSN, MF_FPCR, MT_FPCR] = map farith [cpys, cpyse, cpysn, mf_fpcr, mt_fpcr] rtl cvtlq cvtql cvtqlsv cvtqlv cvtqs cvtqsc cvtqt cvtqtc cvtts cvttsc cvtst cvtsts cvttq cvttqc : #64 bits -> #64 bits rtl CVT^^[LQ,QL,QLSV,QLV,QS,QSC,QT,QTC,TS,TSC,ST,STS,TQ,TQC] = map funary cvt^^[lq,ql,qlsv,qlv,qs,qsc,qt,qtc,ts,tsc,st,sts,tq,tqc] rtl teq tlt tle tun : #64 bits * #64 bits -> #64 bits rtl fcmps as [CMPTEQ, CMPTLT, CMPTLE, CMPTUN] = map farith [teq, tlt, tle, tun] rtl [CMPTEQSU, CMPTLTSU, CMPTLESU, CMPTUNSU] = map su fcmps (* Floating point branches *) fun fbranch oper {f,lab} = if oper($f[f],???) then Jmp(%%lab) else () rtl [FBEQ, FBLT, FBLE, FBNE, FBGE, FBGT] = map fbranch [|==|, |<|, |<=|, |<>|, |>=|, |>|] (* Floating point moves *) fun fcmove cmp {fa,fb,fc} = if cmp($f[fa],???) then $f[fc] := $f[fb] else () rtl FCMOV ^^ [EQ, LT, LE, NE, GE, GT] = map fcmove [|==|, |<|, |<=|, |<>|, |>=|, |>|] (* Call/return *) rtl JSR{r,b,defs,uses,mem} = Call($r[b]) || Kill $r[r] || Kill $cellset[defs] || Use $cellset[uses] || $m[??? :mem] := ($m[??? :mem] : #8 bits) rtl RET{r,b} = Jmp($r[b]) || Kill $r[r] rtl JMPL{r,b} = Jmp($r[b]) || Kill $r[r] rtl TRAPB{} = () (* Pseudo arithmetic *) fun pseudoOp oper {ra,rb,rc,tmps} = $r[rc] := oper($r[ra], rb) || Kill $cellset[tmps] (* XXX *) rtl PSEUDOARITH_ ^^ [ DIVL, DIVLU, DIVQ, DIVQU, REML, REMLU, REMQ, REMQU ] = map pseudoOp [ divs, divu, divs, divu, (* XXX *) rems, remu, rems, remu ] (* Pal code * Note: I have no idea what these things are, so I'm just going * fake them *) rtl BPT BUGCHK CALLSYS GENTRAP IMB RDUNIQUE WRUNIQUE : #64 bits -> #64 bits fun CALL_PAL code {def,use} = Call(qword(code(qword 0))) || Kill $cellset[def] || Use $cellset[use] rtl CALL_PAL_ ^^ [BPT, BUGCHK, CALLSYS, GENTRAP, IMB, RDUNIQUE, WRUNIQUE] = map CALL_PAL [BPT, BUGCHK, CALLSYS, GENTRAP, IMB, RDUNIQUE, WRUNIQUE] end (* RTL *) (* * Reservation tables and pipeline definitions for scheduling *) (* Function units *) resource issue and mem and alu and falu and fmul and fdiv and branch (* Different implementations of cpus *) cpu default 2 [2 issue, 2 mem, 1 alu] (* 2 issue machine *) (* Definitions of various reservation tables *) pipeline NOP _ = [issue] and ARITH _ = [issue^^alu] and LOAD _ = [issue^^mem] and STORE _ = [issue^^mem,mem,mem] and FARITH _ = [issue^^falu] and FMUL _ = [issue^^fmul,fmul] and FDIV _ = [issue^^fdiv,fdiv*50] and BRANCH _ = [issue^^branch] (* * We now specify the instruction representation, assembly, * machine code encoding and ``semantics'' *) structure Instruction = struct datatype ea = Direct of $GP | FDirect of $FP | Displace of {base: $GP, disp:int} datatype operand = REGop of $GP ``'' rtl: $r[GP] | IMMop of int ``'' rtl: immed int | HILABop of LabelExp.labexp ``hi()'' rtl: hi(labexp) | LOLABop of LabelExp.labexp ``lo()'' rtl: lo(labexp) | LABop of LabelExp.labexp ``'' rtl: labexp (* * When I say ! after the datatype name XXX, it means generate a * function emit_XXX that converts the constructors into the corresponding * assembly text. By default, it uses the same name as the constructor, * but may be modified by the lowercase/uppercase assembly directive. * *) datatype branch! = (* table C-2 *) BR 0x30 (*| BSR 0x34 *) | BLBC 0x38 | BEQ 0x39 | BLT 0x3a | BLE 0x3b | BLBS 0x3c | BNE 0x3d | BGE 0x3e | BGT 0x3f datatype fbranch! = (* table C-2 *) FBEQ 0x31 | FBLT 0x32 | FBLE 0x33 | FBNE 0x35 | FBGE 0x36 | FBGT 0x37 datatype load! = (* table C-1 *) LDB | LDW | LDBU 0x02 | LDWU 0x04 | LDL 0x28 | LDL_L 0x2A | LDQ 0x29 | LDQ_L 0x2B | LDQ_U 0x0B datatype store! = STB 0x0E | STW 0x0D | STL 0x2C | STQ 0x2D | STQ_U 0x0F datatype fload [0x20..0x23] ! = LDF | LDG | LDS | LDT datatype fstore [0x24..0x27] ! = STF | STG | STS | STT (* non-trapping opcodes *) datatype operate! = (* table C-5 *) ADDL (0wx10,0wx00) | ADDQ (0wx10,0wx20) | CMPBGE(0wx10,0wx0f) | CMPEQ (0wx10,0wx2d) | CMPLE (0wx10,0wx6d) | CMPLT (0wx10,0wx4d) | CMPULE (0wx10,0wx3d) | CMPULT(0wx10,0wx1d) | SUBL (0wx10,0wx09) | SUBQ (0wx10,0wx29) | S4ADDL(0wx10,0wx02) | S4ADDQ (0wx10,0wx22) | S4SUBL (0wx10,0wx0b) | S4SUBQ(0wx10,0wx2b) | S8ADDL (0wx10,0wx12) | S8ADDQ (0wx10,0wx32) | S8SUBL(0wx10,0wx1b) | S8SUBQ (0wx10,0wx3b) | AND (0wx11,0wx00) | BIC (0wx11,0wx08) | BIS (0wx11,0wx20) | EQV (0wx11,0wx48) | ORNOT (0wx11,0wx28) | XOR (0wx11,0wx40) | EXTBL (0wx12,0wx06) | EXTLH (0wx12,0wx6a) | EXTLL(0wx12,0wx26) | EXTQH (0wx12,0wx7a) | EXTQL (0wx12,0wx36) | EXTWH(0wx12,0wx5a) | EXTWL (0wx12,0wx16) | INSBL (0wx12,0wx0b) | INSLH(0wx12,0wx67) | INSLL (0wx12,0wx2b) | INSQH (0wx12,0wx77) | INSQL(0wx12,0wx3b) | INSWH (0wx12,0wx57) | INSWL (0wx12,0wx1b) | MSKBL(0wx12,0wx02) | MSKLH (0wx12,0wx62) | MSKLL (0wx12,0wx22) | MSKQH(0wx12,0wx72) | MSKQL (0wx12,0wx32) | MSKWH (0wx12,0wx52) | MSKWL(0wx12,0wx12) | SLL (0wx12,0wx39) | SRA (0wx12,0wx3c) | SRL (0wx12,0wx34) | ZAP (0wx12,0wx30) | ZAPNOT (0wx12,0wx31) | MULL (0wx13,0wx00) | MULQ (0wx13,0wx20) | UMULH (0wx13,0wx30) (* conditional moves *) datatype cmove! = CMOVEQ 0wx24 | CMOVLBC 0wx16 | CMOVLBS 0wx14 | CMOVGE 0wx46 | CMOVGT 0wx66 | CMOVLE 0wx64 | CMOVLT 0wx44 | CMOVNE 0wx26 datatype pseudo_op! = DIVL | DIVLU | DIVQ | DIVQU | REML | REMLU | REMQ | REMQU datatype operateV! = (* table C-5 opc/func *) ADDLV (0wx10,0wx40) | ADDQV (0wx10,0wx60) | SUBLV (0wx10,0wx49) | SUBQV (0wx10,0wx69) | MULLV (0wx13,0wx40) | MULQV (0wx13,0wx60) datatype funary! = (* table C-6/C-7 *) (* C-6 *) CVTLQ (0wx17,0wx010) | CVTQL (0wx17,0wx030) | CVTQLSV (0wx17,0wx530) | CVTQLV (0wx17,0wx130) (* C-7 *) | CVTQS (0wx16,0wxbc) | CVTQSC (0wx16,0wx3c) | CVTQT (0wx16,0wxbe) | CVTQTC (0wx16,0wx3e) | CVTTS (0wx16,0wxac) | CVTTSC (0wx16,0wx2c) | CVTST (0wx16,0wx2ac) | CVTSTS (0wx16,0wx6ac) | CVTTQ (0wx16,0wxaf) | CVTTQC (0wx16,0wx2f) datatype foperate! = (* table C-6 *) CPYS (0wx17,0wx20) | CPYSE (0wx17,0wx022) | CPYSN (0wx17,0wx021) | MF_FPCR (0wx17,0wx025) | MT_FPCR (0wx17,0wx024) (* table C-7 *) | CMPTEQ (0wx16,0wx0a5) | CMPTLT (0wx16,0wx0a6) | CMPTLE (0wx16,0wx0a7) | CMPTUN (0wx16,0wx0a4) | CMPTEQSU(0wx16,0wx5a5) | CMPTLTSU(0wx16,0wx5a6) |CMPTLESU(0wx16,0wx5a7) | CMPTUNSU(0wx16,0wx5a4) | ADDS (0wx16,0wx080) | ADDT (0wx16,0wx0a0) | DIVS (0wx16,0wx083) | DIVT (0wx16,0wx0a3) | MULS (0wx16,0wx082) | MULT (0wx16,0wx0a2) | SUBS (0wx16,0wx081) | SUBT (0wx16,0wx0a1) datatype fcmove! = FCMOVEQ 0wx02a | FCMOVGE 0wx02d | FCMOVGT 0wx02f | FCMOVLE 0wx02e | FCMOVLT 0wx02c | FCMOVNE 0wx02b datatype foperateV! = (* table C-7 *) ADDSSUD 0wx5c0 | ADDSSU 0wx580 | ADDTSUD 0wx5e0 | ADDTSU 0wx5a0 | DIVSSUD 0wx5c3 | DIVSSU 0wx583 | DIVTSUD 0wx5e3 | DIVTSU 0wx5a3 | MULSSUD 0wx5c2 | MULSSU 0wx582 | MULTSUD 0wx5e2 | MULTSU 0wx5a2 | SUBSSUD 0wx5c1 | SUBSSU 0wx581 | SUBTSUD 0wx5e1 | SUBTSU 0wx5a1 datatype osf_user_palcode! = BPT 0x80 | BUGCHK 0x81 | CALLSYS 0x83 | GENTRAP 0xaa | IMB 0x86 | RDUNIQUE 0x9e | WRUNIQUE 0x9f type addressing_mode = C.cell * operand end (* Instruction *) (* * Alpha has very simple instruction encoding formats. *) instruction formats 32 bits Memory{opc:6, ra:5, rb:GP 5, disp: signed 16} (* p3-9 *) (* derived from Memory *) | Split{le} = let val i = LabelExp.valueOf le val w = itow i val hi = w ~>> 0w16 val lo = w && 0w65535 in if lo < 0w32768 then (hi,lo) else (hi+0w1,lo-0w65536) end | High{le} = let val (hi,_) = Split{le=le} in hi end | Low{le} = let val (_,lo) = Split{le=le} in lo end | LoadStore{opc,ra,rb,disp} = let val disp = case disp of I.REGop rb => emit_GP rb | I.IMMop i => itow i | I.HILABop le => High{le=le} | I.LOLABop le => Low{le=le} | I.LABop le => itow(LabelExp.valueOf le) in Memory{opc,ra,rb,disp} end | ILoadStore{opc,r:GP,b,d} = LoadStore{opc,ra=r,rb=b,disp=d} | FLoadStore{opc,r:FP,b,d} = LoadStore{opc,ra=r,rb=b,disp=d} | Jump{opc:6=0wx1a,ra:GP 5,rb:GP 5,h:2,disp:int signed 14} (* table C-3 *) | Memory_fun{opc:6, ra:GP 5, rb:GP 5, func:16} (* p3-9 *) | Branch{opc:branch 6, ra:GP 5, disp:signed 21} (* p3-10 *) | Bsr{opc:6=0wx34, ra:GP 5, disp:signed 21} (* p3-10 *) | Fbranch{opc:fbranch 6, ra:FP 5, disp:signed 21} (* p3-10 *) (* p3-11 *) | Operate0{opc:6,ra:GP 5,rb:GP 5,sbz:13..15=0,_:1=0,func:5..11,rc:GP 5} (* p3-11 *) | Operate1{opc:6,ra:GP 5,lit:signed 13..20,_:1=1,func:5..11,rc:GP 5} | Operate{opc,ra,rb,func,rc} = (case rb of I.REGop rb => Operate0{opc,ra,rb,func,rc} | I.IMMop i => Operate1{opc,ra,lit=itow i,func,rc} | I.HILABop le => Operate1{opc,ra,lit=High{le=le},func,rc} | I.LOLABop le => Operate1{opc,ra,lit=Low{le=le},func,rc} | I.LABop le => Operate1{opc,ra,lit=itow(LabelExp.valueOf le),func,rc} ) | Foperate{opc:6,fa:FP 5,fb:FP 5,func:5..15,fc:FP 5} | Funary{opc:6,fa:5=31,fb:FP 5,func:5..15,fc:FP 5} | Pal{opc:6=0,func:26} structure MC = struct (* compute displacement address *) fun disp lab = itow(Label.addrOf lab - !loc - 4) ~>> 0w2 val zeroR = Option.valOf(C.zeroReg C.GP) end structure Assembly = struct fun isZero(I.LABop le) = LabelExp.valueOf le = 0 | isZero _ = false end (* * The main instruction set definition consists of the following: * 1) constructor-like declaration defines the view of the instruction, * 2) assembly directive in funny quotes `` '', * 3) machine encoding expression, * 4) delay slot directives etc (not necessary in this architecture) *) instruction (* Pseudo instruction for the register allocator *) DEFFREG of $FP (* define a floating point register *) asm: ``/* deffreg\t */'' mc: () (* do nothing when emitting code *) rtl: ``DEFFREG'' (* Load/Store *) | LDA of {r: $GP, b: $GP, d:operand} (* use of REGop is illegal *) asm: if isZero d andalso C.sameCell(r,b) then () else (``lda\t, ''; if C.registerId b = 31 then () else ``()'' ) mc: ILoadStore{opc=0w08,r,b,d} rtl: ``LDA'' | LDAH of {r: $GP, b: $GP, d:operand} (* use of REGop is illegal *) asm: (``ldah\t, ''; if C.registerId b = 31 then () else ``()'' ) mc: ILoadStore{opc=0w09,r,b,d} rtl: ``LDAH'' | LOAD of {ldOp:load, r: $GP, b: $GP, d:operand, mem:Region.region} asm: ``\t, ()'' mc: ILoadStore{opc=emit_load ldOp,r,b,d} rtl: ``'' latency: 1 | STORE of {stOp:store, r: $GP, b: $GP, d:operand, mem:Region.region} asm: ``\t, ()'' mc: ILoadStore{opc=emit_store stOp,r,b,d} rtl: ``'' | FLOAD of {ldOp:fload, r: $FP, b: $GP, d:operand, mem:Region.region} asm: ``\t, ()'' mc: FLoadStore{opc=emit_fload ldOp,r,b,d} rtl: ``'' latency: 1 | FSTORE of {stOp:fstore, r: $FP, b: $GP, d:operand, mem:Region.region} asm: ``\t, ()'' mc: FLoadStore{opc=emit_fstore stOp,r,b,d} rtl: ``'' (* Control Instructions *) | JMPL of {r: $GP, b: $GP, d:int} * Label.label list asm: ``jmp\t, ()'' mc: Jump{h=0w0,ra=r,rb=b,disp=d} (* table C-3 *) rtl: ``JMPL'' | JSR of {r: $GP, b: $GP, d:int, defs: $cellset, uses: $cellset, mem:Region.region} asm: ``jsr\t, ()'' mc: Jump{h=0w1,ra=r,rb=b,disp=d} rtl: ``JSR'' | BSR of {r: $GP, lab: Label.label, defs: $cellset, uses: $cellset, mem:Region.region} asm: ``bsr\t, '' mc: Bsr{ra=r,disp=disp lab} rtl: ``BSR'' | RET of {r: $GP, b: $GP, d:int} asm: ``ret\t, ()'' mc: Jump{h=0w2,ra=r,rb=b,disp=d} rtl: ``RET'' | BRANCH of {b:branch, r: $GP, lab:Label.label} asm: ``\t, '' mc: Branch{opc=b,ra=r,disp=disp lab} rtl: ``'' | FBRANCH of {b:fbranch, f: $FP, lab:Label.label} asm: ``\t, '' mc: Fbranch{opc=b,ra=f,disp=disp lab} rtl: ``'' (* Integer Operate *) | OPERATE of {oper:operate, ra: $GP, rb:operand, rc: $GP} (* Pretty print ldgp differently *) asm: let fun disp() = ``\t, , '' in case (oper,C.registerId ra,rb,C.registerId rc) of (I.BIS,27,I.REGop rb,29) => if C.registerId rb = 31 then ``ldgp\t$29, 0($27)'' else disp() | (I.BIS,26,I.REGop rb,29) => if C.registerId rb = 31 then ``ldgp\t$29, 0($26)'' else disp() | _ => disp() end mc: let val (opc,func) = emit_operate oper in Operate{opc,func,ra,rb,rc} end rtl: ``'' | OPERATEV of {oper:operateV, ra: $GP, rb:operand, rc: $GP} asm: ``\t, , '' mc: let val (opc,func) = emit_operateV oper in Operate{opc,func,ra,rb,rc} end rtl: ``'' | CMOVE of {oper:cmove, ra: $GP, rb:operand, rc: $GP} asm: ``\t, , '' mc: Operate{opc=0wx11,func=emit_cmove oper,ra,rb,rc} rtl: ``'' | PSEUDOARITH of {oper: pseudo_op, ra: $GP, rb:operand, rc: $GP, tmps: $cellset} asm: ``\t, , '' rtl: ``PSEUDOARITH_'' (* Copy instructions *) | COPY of {dst: $GP list, src: $GP list, impl:instruction list option ref, tmp: ea option} asm: emitInstrs (Shuffle.shuffle{tmp,dst,src}) rtl: ``COPY'' | FCOPY of {dst: $FP list, src: $FP list, impl:instruction list option ref, tmp: ea option} asm: emitInstrs (Shuffle.shufflefp{tmp,dst,src}) rtl: ``FCOPY'' (* Floating Point Unary Operation *) | FUNARY of {oper:funary, fb: $FP, fc: $FP} asm: ``\t, '' mc: let val (opc,func) = emit_funary oper in Funary{opc,func,fb,fc} end rtl: ``'' (* Floating Point Operate *) | FOPERATE of {oper:foperate, fa: $FP, fb: $FP, fc: $FP} asm: ``\t, , '' mc: let val (opc,func) = emit_foperate oper in Foperate{opc,func,fa,fb,fc} end rtl: ``'' (* Trapping versions of the above (what trap -- allen) ??? *) | FOPERATEV of {oper:foperateV, fa: $FP, fb: $FP, fc: $FP} asm: ``\t, , '' mc: Foperate{opc=0wx16,func=emit_foperateV oper,fa,fb,fc} rtl: ``'' | FCMOVE of {oper:fcmove, fa: $FP, fb: $FP, fc: $FP} asm: ``\t, , '' mc: Foperate{opc=0wx17,func=emit_fcmove oper,fa,fb,fc} rtl: ``'' (* Misc *) | TRAPB (* Trap barrier *) asm: ``trapb'' mc: Memory_fun{opc=0wx18,ra=zeroR,rb=zeroR,func=0wx0} rtl: ``TRAPB'' | CALL_PAL of {code:osf_user_palcode, def: $cellset, use: $cellset} asm: ``call_pal '' mc: Pal{func=emit_osf_user_palcode code} rtl: ``CALL_PAL_'' | ANNOTATION of {i:instruction, a:Annotations.annotation} asm: (comment(Annotations.toString a); nl(); emitInstr i) mc: (emitInstr i) (* rtl: [[ #i ]] *) | SOURCE of {} asm: ``source'' mc: () | SINK of {} asm: ``sink'' mc: () | PHI of {} asm: ``phi'' mc: () structure SSA = struct fun operand(ty, I.REGop r) = T.REG(ty, r) | operand(ty, I.IMMop i) = T.LI i | operand(ty, _) = error "operand" end end
Click to toggle
does not end with </html> tag
does not end with </body> tag
The output has ended thus: , r) | operand(ty, I.IMMop i) = T.LI i | operand(ty, _) = error "operand" end end