SCM Repository
View of /sml/trunk/src/MLRISC/sparc/sparc.mdl
Parent Directory
|
Revision Log
Revision 746 -
(download)
(annotate)
Fri Dec 8 04:16:09 2000 UTC (21 years, 8 months ago) by leunga
File size: 32209 byte(s)
Fri Dec 8 04:16:09 2000 UTC (21 years, 8 months ago) by leunga
File size: 32209 byte(s)
New machine descriptions...
(* * This has been upgraded to V9. *) architecture Sparc = struct superscalar big endian lowercase assembly storage GP = $r[32] of 64 bits where $r[0] = 0 asm: (fn (r,_) => if r < 8 then "%g"^Int.toString r else if r = 14 then "%sp" else if r < 16 then "%o"^Int.toString(r-8) else if r < 24 then "%l"^Int.toString(r-16) else if r = 30 then "%fp" else if r < 32 then "%i"^Int.toString(r-24) else "%r"^Int.toString r ) | FP = $f[32] of 32 bits asm: (fn (f,_) => "%f"^Int.toString f) | Y = $y[1] of 64 bits asm: "%y" | PSR = $psr[1] of 64 bits asm: (fn (0,_) => "%psr" | (n,_) => "%psr"^Int.toString n) | FSR = $fsr[1] of 64 bits asm: (fn (0,_) => "%fsr" | (n,_) => "%fsr"^Int.toString n) | 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[14] and asmTmpR = $r[10] (* %o2 *) and linkReg = $r[15] and fasmTmp = $f[30] and y = $y[0] and psr = $psr[0] and fsr = $fsr[0] and r0 = $r[0] structure RTL = struct include "Tools/basis.mdl" open Basis infix 1 || infix 3 << >> ~>> fun %% l = (l : #64 bits) (* Updates condition code *) fun cc{} = Kill $psr[0] fun byte x = (x : #8 bits) fun hword x = (x : #16 bits) fun word x = (x : #32 bits) fun dword x = (x : #64 bits) fun single x = (x : #32 bits) fun double x = (x : #64 bits) fun quad x = (x : #128 bits) fun disp(r,i) = $r[r] + i (* read from/write to the y register *) rtl RDY{d} = $r[d] := $y[0] rtl WRY{r,i} = $y[0] := disp(r,i) rtl SETHI{i,d} = $r[d] := i << 10 (* Integer load/store *) rtl LDSB{r,i,d,mem} = $r[d] := sx(byte $m[disp(r,i):mem]) rtl LDSH{r,i,d,mem} = $r[d] := sx(hword $m[disp(r,i):mem]) rtl LDUB{r,i,d,mem} = $r[d] := zx(byte $m[disp(r,i):mem]) rtl LDUH{r,i,d,mem} = $r[d] := zx(hword $m[disp(r,i):mem]) rtl LD{r,i,d,mem} = $r[d] := zx(word $m[disp(r,i):mem]) rtl LDX{r,i,d,mem} = $r[d] := zx(quad $m[disp(r,i):mem]) rtl STB{r,i,d,mem} = $m[disp(r,i):mem] := $r[d] at [0..7] rtl STH{r,i,d,mem} = $m[disp(r,i):mem] := $r[d] at [0..15] rtl ST{r,i,d,mem} = $m[disp(r,i):mem] := $r[d] at [0..31] rtl STX{r,i,d,mem} = $m[disp(r,i):mem] := $r[d] at [0..63] (* Integer opcodes *) (* These are built-in sparc bitops *) fun andn(x,y) = andb(x,notb y) fun orn(x,y) = orb(x,notb y) fun xnor(x,y) = notb(xorb(x,y)) (* Tagged additions operators. We just fake these by * generating new operators. *) rtl tadd taddtv tsub tsubtv : #n bits * #n bits -> #n bits fun multiply opc {r,i,d} = $r[d] := opc($r[r],i) || Kill $y[0] fun multiplycc opc {r,i,d} = multiply opc {r,i,d} || cc{} fun divide opc {r,i,d} = $r[d] := opc($r[r],i) (* XXX *) fun dividecc opc {r,i,d} = divide opc {r,i,d} || cc{} fun logical opc {r,i,d} = $r[d] := opc($r[r],i) fun logicalcc opc {r,i,d} = $r[d] := opc($r[r],i) || cc{} fun arith opc {r,i,d} = $r[d] := opc($r[r],i) fun arithcc opc {r,i,d} = $r[d] := opc($r[r],i) || cc{} rtl li{i,d} = $r[d] := i (* load immediate *) rtl [AND,ANDN,OR,ORN,XOR,XNOR] = map logical [andb, andn, orb, orn, xorb, xnor] rtl [ANDCC, ANDNCC, ORCC, ORNCC, XORCC, XNORCC] = map logicalcc [andb, andn, orb, orn, xorb, xnor] rtl [ADD, TADD, TADDTV, SUB, TSUB, TSUBTV] = map arith [(+), tadd, taddtv, (-), tsub, tsubtv] rtl [ADDCC, TADDCC, TADDTVCC, SUBCC, TSUBCC, TSUBTVCC] = map arithcc [(+), tadd, taddtv, (-), tsub, tsubtv] rtl [UMUL,SMUL] = map multiply [mulu,muls] rtl [UMULCC,SMULCC] = map multiplycc [mulu,muls] rtl [UDIV,SDIV] = map divide [divu,divs] rtl [UDIVCC,SDIVCC] = map dividecc [divu,divs] rtl [MULX, SDIVX, UDIVX] = map arith [muls, divs, divu] rtl [SLL, SRL, SRA] = map logical [(<<), (>>), (~>>)] (* XXX *) rtl [SLLX, SRLX, SRAX] = map logical [(<<), (>>), (~>>)] (* XXX *) local fun xor(a, b) = a == b (* Extract bits from the $psr *) val N = ($psr[0] at [23]) == 1 val Z = ($psr[0] at [22]) == 1 val V = ($psr[0] at [21]) == 1 val C = ($psr[0] at [20]) == 1 in val [A, E, LE, L, LEU, CS, NEG, VS, (* XXX *) N, NE, G, GE, GU, CC, POS, VC] = [true, Z, Z, Z, Z, C, N, V, false, not Z, Z, Z, Z, not C,not N,not V ] end val integer_tests = [N, E, LE, L, LEU, CS, NEG, VS, A, NE, G, GE, GU, CC, POS, VC] (* Integer branches *) fun branch status {label} = if status then Jmp(%%label) else () rtl [BN, BE, BLE, BL, BLEU, BCS, BNEG, BVS, BA, BNE, BG, BGE, BGU, BCC, BPOS, BVC] = map branch integer_tests rtl JMP{r,i} = Jmp(disp(r,i)) (* Conditional moves *) fun MOVicc icc {i, d} = if icc then $r[d] := i else () fun FMOVicc icc {r, d} = if icc then $f[d] := $f[r] else () val MOV ^^ [E, LE, L, LEU, CS, NEG, VS, NE, G, GE, GU, CC, POS, VC] = map MOVicc [E, LE, L, LEU, CS, NEG, VS, NE, G, GE, GU, CC, POS, VC] val FMOV ^^ [E, LE, L, LEU, CS, NEG, VS, NE, G, GE, GU, CC, POS, VC] = map FMOVicc [E, LE, L, LEU, CS, NEG, VS, NE, G, GE, GU, CC, POS, VC] fun MOVR rcc {r, i, d} = if rcc($r[r], 0) then $r[d] := i else () rtl MOVR ^^ [Z, LEZ, LZ, NZ, GZ, GEZ] = map MOVR [(==), (<=), (<), (<>), (>), (>=)] (* Floating point load/store *) rtl LDF{r,i,d,mem} = $f[d] := $m[disp(r,i):mem] rtl LDDF{r,i,d,mem} = $f[d] := $m[disp(r,i):mem] rtl LDQF{r,i,d,mem} = $f[d] := $m[disp(r,i):mem] rtl STF{r,i,d,mem} = $m[disp(r,i):mem] := $f[d] rtl STDF{r,i,d,mem} = $m[disp(r,i):mem] := $f[d] rtl LDFSR{r,i,mem} = $fsr[0] := $m[disp(r,i):mem] (* XXX *) rtl LDXFSR{r,i,mem} = $fsr[0] := $m[disp(r,i):mem] (* XXX *) rtl STFSR{r,i,mem} = $m[disp(r,i):mem] := $fsr[0] (* XXX *) (* conversions *) rtl fitos fitod fitoq fstoi fdtoi fqtoi fsqrt fstod fstoq fdtos fdtoq fqtos fqtod : #n bits -> #n bits fun fmovs x = x fun fmovd x = x fun fmovq x = x fun funary opc {r,d} = $f[d] := opc $f[r] (* Floating point unary operations *) rtl [FiTOs, FiTOd, FiTOq, FsTOi, FdTOi, FqTOi, FsTOd, FsTOq, FdTOs, FdTOq, FqTOs, FqTOd, FMOVs, FNEGs, FABSs, FMOVd, FNEGd, FABSd, FMOVq, FNEGq, FABSq, FSQRTs, FSQRTd, FSQRTq] = (* XXX *) map funary [fitos, fitod, fitoq, fstoi, fdtoi, fqtoi, fstod, fstoq, fdtos, fdtoq, fqtos, fqtod, fmovs, fneg, fabs, fmovd, fneg, fabs, fmovq, fneg, fabs, fsqrt, fsqrt, fsqrt] (* Floating point binary operations *) fun fbinary opc {r1,r2,d} = $f[d] := opc($f[r1],$f[r2]) rtl fsmuld fdmulq : #n bits * #n bits -> #n bits (* XXX *) rtl [FADDs, FADDd, FADDq, FSUBs, FSUBd, FSUBq, (* XXX *) FMULs, FMULd, FMULq, FsMULd, FdMULq, FDIVs, FDIVd, FDIVq] = map fbinary [fadd, fadd, fadd, fsub, fsub, fsub, fmul, fmul, fmul, fsmuld, fdmulq, fdiv, fdiv, fdiv] (* Floating point comparisons *) rtl Nan : #32 bits -> #32 bits fun nan(r) = (* if Nan($f[r]) == 0 then () else () *) () rtl cmps cmpd cmpq : #n bits * #n bits -> #n bits rtl FCMPs{r1,r2} = $fsr[0] := cmps($f[r1],$f[r2]) rtl FCMPd{r1,r2} = $fsr[0] := cmpd($f[r1],$f[r2]) rtl FCMPq{r1,r2} = $fsr[0] := cmpq($f[r1],$f[r2]) rtl FCMPEs{r1,r2} = $fsr[0] := cmps($f[r1],$f[r2]) || nan(r1) || nan(r2) rtl FCMPEd{r1,r2} = $fsr[0] := cmpd($f[r1],$f[r2]) || nan(r1) || nan(r2) rtl FCMPEq{r1,r2} = $fsr[0] := cmpq($f[r1],$f[r2]) || nan(r1) || nan(r2) local val X = $fsr[0] == 0 in val floating_point_tests as [FN, FNE, FLG, FUL, FL, FUG, FG, FU, FA, FE, FUE, FGE, FUGE, FLE, FULE, FO] = [X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X ] end fun fbranch fcc {label} = if fcc then Jmp(%%label) else () rtl [FBN, FBNE, FBLG, FBUL, FBL, FBUG, FBG, FBU, FBA, FBE, FBUE, FBGE, FBUGE, FBLE, FBULE, FBO] = map fbranch floating_point_tests (* Floating point conditional moves *) fun MOVfcc fcc {i, d} = if fcc then $r[d] := i else () fun FMOVfcc fcc { r, d} = if fcc then $f[d] := $f[r] else () rtl MOV ^^ [N, NE, LG, UL, L, UG, G, U, A, E, UE, GE, UGE, LE, ULE, O] = map MOVfcc floating_point_tests rtl FMOV ^^ [N, NE, LG, UL, L, UG, G, U, A, E, UE, GE, UGE, LE, ULE, O] = map FMOVfcc floating_point_tests (* Traps *) fun Trap x = Jmp x (* XXX *) fun Ticc cc {r,i} = if cc then Trap(disp(r,i)) else () fun Txcc cc {r,i} = if cc then Trap(disp(r,i)) else () rtl TICC ^^ [BN,BE, BLE,BL, BLEU,BCS,BNEG,BVS, BA,BNE,BG, BGE,BGU, BCC,BPOS,BVC] = map Ticc integer_tests rtl TXCC ^^ [BN,BE, BLE,BL, BLEU,BCS,BNEG,BVS, BA,BNE,BG, BGE,BGU, BCC,BPOS,BVC] = map Txcc integer_tests (* Jmps, calls and returns *) rtl JMP{r,i} = Jmp(disp(r,i)) rtl JMPL{r,i,d,defs,uses} = Call(disp(r,i)) || $r[d] := ??? || Kill $cellset[defs] || Use $cellset[uses] rtl CALL{label,defs,uses} = Call(%%label) || Kill $cellset[defs] || Use $cellset[uses] rtl RET{} = Ret end (* RTL *) structure Instruction = struct datatype load : op3! = LDSB 0b001001 | LDSH 0b001010 | LDUB 0b000001 | LDUH 0b000010 | LD 0b000000 | LDX 0b001011 (* v9 *) | LDD 0b000011 datatype store : op3! = STB 0b000101 | STH 0b000110 | ST 0b000100 | STX 0b001110 (* v9 *) | STD 0b000111 datatype fload : op3! = LDF 0b100000 | LDDF 0b100011 | LDQF 0b100010 (* v9 *) | LDFSR 0b100001 (* rd = 0 *) | LDXFSR 0b100001 (* v9 *) (* rd = 1 *) datatype fstore : op3! = STF 0b100100 | STDF 0b100111 | STFSR 0b100101 datatype arith : op3! = AND 0b000001 | ANDCC 0b010001 | ANDN 0b000101 | ANDNCC 0b010101 | OR 0b000010 | ORCC 0b010010 | ORN 0b000110 | ORNCC 0b010110 | XOR 0b000011 | XORCC 0b010011 | XNOR 0b000111 | XNORCC 0b010111 | ADD 0b000000 | ADDCC 0b010000 | TADD 0b100000 | TADDCC 0b110000 | TADDTV 0b100010 | TADDTVCC 0b110010 | SUB 0b000100 | SUBCC 0b010100 | TSUB 0b100001 | TSUBCC 0b110001 | TSUBTV 0b100011 | TSUBTVCC 0b110011 | UMUL 0b001010 | UMULCC 0b011010 | SMUL 0b001011 | SMULCC 0b011011 | UDIV 0b001110 | UDIVCC 0b011110 | SDIV 0b001111 | SDIVCC 0b011111 (* v9 extensions *) | MULX 0b001001 | SDIVX 0b101101 | UDIVX 0b001101 (* op3, x *) datatype shift : op3! = SLL (0wb100101,0w0) | SRL (0wb100110,0w0) | SRA (0wb100111,0w0) (* v9 extensions *) | SLLX (0wb100101,0w1) | SRLX (0wb100110,0w1) | SRAX (0wb100111,0w1) datatype farith1 : opf! = FiTOs 0b011000100 | FiTOd 0b011001000 | FiTOq 0b011001100 | FsTOi 0b011010001 | FdTOi 0b011010010 | FqTOi 0b011010011 | FsTOd 0b011001001 | FsTOq 0b011010101 | FdTOs 0b011000110 | FdTOq 0b011001110 | FqTOs 0b011000111 | FqTOd 0b011001011 | FMOVs 0b000000001 | FNEGs 0b000000101 | FABSs 0b000001001 | FMOVd | FNEGd | FABSd (* composite instr *) | FMOVq | FNEGq | FABSq (* composite instr *) | FSQRTs 0b000101001 | FSQRTd 0b000101010 | FSQRTq 0b000101011 datatype farith2 :opf! = FADDs 0b001000001 | FADDd 0b001000010 | FADDq 0b001000011 | FSUBs 0b001000101 | FSUBd 0b001000110 | FSUBq 0b001000111 | FMULs 0b001001001 | FMULd 0b001001010 | FMULq 0b001001011 | FsMULd 0b001101001 | FdMULq 0b001101110 | FDIVs 0b001001101 | FDIVd 0b001001110 | FDIVq 0b001001111 datatype fcmp : opf! = FCMPs 0b001010001 | FCMPd 0b001010010 | FCMPq 0b001010011 | FCMPEs 0b001010101 | FCMPEd 0b001010110 | FCMPEq 0b001010111 datatype branch [0..15] : cond! = BN "n" | BE "e" | BLE "le" | BL "l" | BLEU "leu" | BCS "cs" | BNEG "neg" | BVS "vs" | BA "" | BNE "ne" | BG "g" | BGE "ge" | BGU "gu" | BCC "cc" | BPOS "pos" | BVC "vs" datatype rcond! = (* V9 integer conditions *) RZ 0b001 | RLEZ 0b010 | RLZ 0b011 | RNZ 0b101 | RGZ 0b110 | RGEZ 0b111 datatype cc = (* V9 condition register *) ICC 0b00 | XCC 0b10 datatype prediction! = (* V9 branch prediction bit *) PT | PN datatype fbranch [0..15] : cond! = FBN | FBNE | FBLG | FBUL | FBL | FBUG | FBG | FBU | FBA "fb" | FBE | FBUE | FBGE | FBUGE | FBLE | FBULE | FBO datatype ea = Direct of $GP | FDirect of $GP | Displace of {base: $GP, disp: int} (* used to encode the opf_low field V9 *) datatype fsize! = S 0b00100 | D 0b00110 | Q 0b00111 datatype operand = REG of $GP ``<GP>'' rtl: $r[GP] | IMMED of int ``<int>'' rtl: immed int | LAB of LabelExp.labexp ``<labexp>'' rtl: labexp | LO of LabelExp.labexp ``%lo(<labexp>)'' rtl: lo(labexp) | HI of LabelExp.labexp ``%hi(<labexp>)'' rtl: hi(labexp) type addressing_mode = C.cell * operand end (* Instruction *) functor Assembly(val V9 : bool) = struct (* Some helper functions for assembly generation *) fun emit_leaf false = () | emit_leaf true = emit "l" fun emit_nop false = () | emit_nop true = emit "\n\tnop" fun emit_a false = () | emit_a true = emit ",a" fun emit_cc false = () | emit_cc true = emit "cc" end instruction formats 32 bits (* Extract the value of an operand *) opn{i} = let fun hi22 w = (itow w) ~>> 0w10 fun lo10 w = (itow w) at [0..9] in case i of I.REG rs2 => error "opn" | I.IMMED i => itow i | I.LAB l => itow(LabelExp.valueOf l) | I.LO l => lo10(LabelExp.valueOf l) | I.HI l => hi22(LabelExp.valueOf l) end (* basic formats, integer source registers, target type not determined.*) | rr {op1:2, rd:5, op3:6, rs1:GP 5, i:1=0, asi:8=0, rs2:GP 5} | ri {op1:2, rd:5, op3:6, rs1:GP 5, i:1=1, simm13:signed 13} | rix{op1,op3,r,i,d} = (case i of I.REG rs2 => rr{op1,op3,rs1=r,rs2=rs2,rd=d} | _ => ri{op1,op3,rs1=r,rd=d,simm13=opn{i}} ) (* GP + imm/GP -> GP *) | rir{op1,op3,r,i,d:GP} = rix{op1,op3,r,i,d} (* GP + imm/GP -> FP *) | rif{op1,op3,r,i,d:FP} = rix{op1,op3,r,i,d} (* formats found in the Sparc architecture manual *) | load{l:load,r,i,d} = rir{op1=0w3,op3=l,r,i,d} (* p90 *) | store{s:store,r,i,d} = rir{op1=0w3,op3=s,r,i,d} (* p95 *) | fload{l:fload,r,i,d} = rif{op1=0w3,op3=l,r,i,d} (* p92 *) | fstore{s:fstore,r,i,d} = rif{op1=0w3,op3=s,r,i,d} (* p97 *) | sethi {op1:2=0, rd:GP 5, op2:3=0b100, imm22:int signed 22} (* p104 *) | NOP {op1:2=0, rd:5=0, op2:3=0b100, imm22:22=0} (* p105 *) | delay {nop} = if nop then NOP{} else () (* delay slot *) | arith {a:arith,r,i,d} = (* p106 *) rir{op1=0w2,op3=a,r,i,d} | shiftr {op1:2=2, rd:5, op3:6, rs1:5, i:1=0, x:1, asi:7=0, rs2:GP 5} | shifti {op1:2=2, rd:5, op3:6, rs1:5, i:1=1, x:1, asi:6=0, cnt:signed 6} | shift {s:shift,r:GP,i,d:GP} = let val (op3,x) = s in case i of I.REG rs2 => shiftr{op3,rs1=r,rs2=rs2,rd=d,x=x} (* p218 v9 *) | _ => shifti{op3,rs1=r,cnt=opn{i},rd=d,x=x} end | save {r,i,d} = rir{op1=0w2,op3=0wb111100,r,i,d} (* p117 *) | restore {r,i,d} = rir{op1=0w2,op3=0wb111101,r,i,d} (* p117 *) | bicc{op1:2=0,a:bool 1, b:branch 4, op2:3=0b010, disp22:signed 22} | fbfcc{op1:2=0,a:bool 1, b:fbranch 4, op2:3=0b110, disp22:signed 22} | call {op1:2=1, disp30:signed 30} (* p125 *) | jmpl {r,i,d} = rir{op1=0w2,op3=0wb111000,r,i,d} (* p126 *) | jmp {r,i} = rix{op1=0w2,op3=0wb111000,r,i,d=0w0} | ticcr {op1:2, rd:5, op3:6, rs1:GP 5, i:1=0, cc:cc 2, _:6=0, rs2:GP 5} | ticci {op1:2, rd:5, op3:6, rs1:GP 5, i:1=1, cc:cc 2, _:4=0, sw_trap:signed 7} | ticcx{op1,op3,cc,r,i,d} = (case i of I.REG rs2 => ticcr{op1,op3,cc,rs1=r,rs2=rs2,rd=d} | _ => ticci{op1,op3,cc,rs1=r,rd=d,sw_trap=opn{i}} ) | ticc {t:branch,cc,r,i} = ticcx{op1=0w2,d=t,op3=0wb111010,cc,r,i} (* p237 (V9) *) | rdy {op2:2=2,d:GP 5,op3:6=0b101000,rs1:5=0,x:0..13=0} (* p131 *) | wdy {r,i} = rix{op1=0w2,op3=0wb110000,r,i,d=0w0} (* p133 *) (* one input floating point format *) | fop_1 {op1:2=2, d:5, op3:6=0b110100, rs1:5=0, a:9, r:5} | fop1 {a:farith1,r:FP,d:FP} = fop_1{a,r,d} (* generate composite instruction *) | fdouble{a:farith1,r:FP,d:FP} = (fop_1{a,r,d}; fop_1{a=0w1,r=r+0w1,d=d+0w1} ) | fquad{a:farith1,r:FP,d:FP} = (fop_1{a,r,d}; fop_1{a=0w1,r=r+0w1,d=d+0w1}; fop_1{a=0w1,r=r+0w2,d=d+0w2}; fop_1{a=0w1,r=r+0w3,d=d+0w3} ) (* two inputs floating point format *) | fop2 {op1:2=2, d:FP 5, op3:6=0b110100, r1:FP 5, a:farith2 9, r2:FP 5} | fcmp {op1:2=2, rd:25..29=0, op3:6=0b110101, rs1:FP 5, opf:fcmp 9,rs2:FP 5} (* conditional moves formats (V9) *) | cmovr{op1:2=2,op3:6,rd:5,cc2:1,cond:4,i:1=0,cc1:1,cc0:1,_:6=0,rs2:5} | cmovi{op1:2=2,op3:6,rd:5,cc2:1,cond:4,i:1=1,cc1:1,cc0:1,simm11:signed 11} | cmov{op3,cond,cc2,cc1,cc0,i,rd} = (case i of I.REG rs2 => cmovr{op3,cond,rs2=emit_GP rs2,rd,cc0,cc1,cc2} | _ => cmovi{op3,cond,rd,cc0,cc1,cc2,simm11=opn{i}} ) | movicc {b:branch,i,d:GP} = cmov{op3=0wb101100,cond=b,i,rd=d,cc2=0w1,cc1=0w0,cc0=0w0} | movfcc {b:fbranch,i,d:GP} = (* use fcc0 *) cmov{op3=0wb101100,cond=b,i,rd=d,cc2=0w0,cc1=0w0,cc0=0w0} | fmovicc{sz:fsize,b:branch,r:FP,d:FP} = cmovr{op3=0wb101100,cond=b,rs2=r,rd=d,cc2=0w1,cc1=0w0,cc0=0w0} | fmovfcc{sz:fsize,b:fbranch,r:FP,d:FP} = (* use fcc0 *) cmovr{op3=0wb101100,cond=b,rs2=r,rd=d,cc2=0w0,cc1=0w0,cc0=0w0} (* move integer register on register condition format *) | movrr {op1:2=2, rd:GP 5, op3:6=0b101111, rs1:GP 5, i:1=0, rcond:3, asi:5=0, rs2:GP 5} | movri {op1:2=2, rd:GP 5, op3:6=0b101111, rs1:GP 5, i:1=1, rcond:3, simm10:signed 10} | movr{rcond:rcond,r,i,d} = (case i of I.REG rs2 => movrr{rcond,rs1=r,rs2=rs2,rd=d} | _ => movri{rcond,rs1=r,rd=d,simm10=opn{i}} ) structure MC = struct (* this computes the displacement address *) fun disp label = itow((Label.addrOf label - !loc)) ~>> 0w2 val r15 = C.Reg C.GP 15 and r31 = C.Reg C.GP 31 end (* * 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] (* * Notation: * r -- source register * i -- source operand (immed or register) * d -- destination register (or data register in store instructions) *) instruction LOAD of { l:load, d: $GP, r: $GP, i:operand, mem:Region.region } asm: ``<l>\t[<r>+<i>], <d><mem>'' mc: load{l,r,i,d} rtl: ``<l>'' latency: 1 | STORE of { s:store, d: $GP, r: $GP, i:operand, mem:Region.region } asm: ``<s>\t<d>, [<r>+<i>]<mem>'' mc: store{s,r,i,d} rtl: ``<s>'' | FLOAD of { l:fload, r: $GP, i:operand, d: $FP, mem:Region.region } asm: ``<l>\t[<r>+<i>], <d><mem>'' mc: fload{l,r,i,d} rtl: ``<l>'' latency: 1 | FSTORE of { s:fstore, d: $FP, r: $GP, i:operand, mem:Region.region } asm: ``<s>\t[<r>+<i>], <d><mem>'' mc: fstore{s,r,i,d} rtl: ``<s>'' | SETHI of { i:int, d: $GP } asm: let val i = Word32.toString(Word32.<<(Word32.fromInt i,0w10)) in ``sethi\t%hi(0x<emit i>), <d>'' end mc: sethi{imm22=i,rd=d} rtl: ``SETHI'' | ARITH of { a:arith, r: $GP, i:operand, d: $GP } asm: (case (a,C.registerId r,C.registerId d) of (* generate abbreviations! *) (I.OR,0,_) => ``mov\t<i>, <d>'' | (I.SUBCC,_,0) => ``cmp\t<r>, <i>'' | _ => ``<a>\t<r>, <i>, <d>'' ) mc: arith{a,r,i,d} rtl: (case (a,C.registerId r) of (I.OR, 0) => ``<li>'' | _ => ``<a>'' ) | SHIFT of { s:shift, r: $GP, i:operand, d: $GP } asm: ``<s>\t<r>, <i>, <d>'' mc: shift{s,r,i,d} rtl: ``<s>'' (* Conditional moves! *) | MOVicc of {b:branch, i:operand, d: $GP } (* V9 *) asm: ``mov<b>\t<i>, <d>'' mc: movicc{b,i,d} | MOVfcc of {b:fbranch, i:operand, d: $GP } (* V9 *) asm: ``mov<b>\t<i>, <d>'' mc: movfcc{b,i,d} | MOVR of {rcond:rcond, r: $GP, i: operand, d: $GP} (* V9 *) asm: ``movr<rcond>\t<r>, <i>, <d>'' mc: movr{rcond,r,i,d} | FMOVicc of {sz:fsize, b:branch, r: $FP, d: $FP } (* V9 *) asm: ``fmov<sz><b>\t<r>, <d>'' mc: fmovicc{sz,b,r,d} | FMOVfcc of {sz:fsize, b:fbranch, r: $FP, d: $FP } (* V9 *) asm: ``fmov<sz><b>\t<r>, <d>'' mc: fmovfcc{sz,b,r,d} | Bicc of { b:branch, a:bool, label:Label.label, nop:bool} asm: ``b<b><a>\t<label><nop>'' mc: (bicc{b,a,disp22=disp label}; delay{nop}) rtl: ``<b>'' padding: nop = true nullified: a = true and (case b of I.BA => false | _ => true) delayslot candidate: false | FBfcc of { b:fbranch, a:bool, label:Label.label, nop:bool } asm: ``<b><a>\t<label><nop>'' mc: (fbfcc{b,a,disp22=disp label}; delay{nop}) rtl: ``<b>'' padding: nop = true nullified: a = true delayslot candidate: false (* V9 branch on condition in integer register *) | BR of {rcond:rcond, p:prediction, r: $GP, a:bool, label:Label.label, nop:bool} asm: ``b<rcond><a><p>\t<r>, <label><nop>'' (* V9 branch on integer condition code with prediction *) | BP of {b:branch, p:prediction, cc:cc, a:bool, label:Label.label,nop:bool} asm: ``bp<b><a><p>\t%<emit(if cc = I.ICC then "i" else "x")>cc, <label><nop>'' | JMP of { r: $GP, i:operand, labs : Label.label list, nop:bool} asm: ``jmp\t[<r>+<i>]<nop>'' mc: (jmp{r,i}; delay{nop}) rtl: ``JMP'' padding: nop = true nullified: false delayslot candidate: false | JMPL of { r: $GP, i:operand, d: $GP, defs: $cellset, uses: $cellset, nop:bool, mem:Region.region } asm: ``jmpl\t[<r>+<i>], <d><mem><emit_defs defs><emit_uses uses><nop>'' mc: (jmpl{r,i,d}; delay{nop}) rtl: ``JMPL'' padding: nop = true nullified: false delayslot candidate: false | CALL of { defs: $cellset, uses: $cellset, label:Label.label, nop:bool, mem:Region.region } asm: ``call\t<label><mem><emit_defs(defs)><emit_uses(uses)><nop>'' mc: (call{disp30=disp label}; delay{nop}) rtl: ``CALL'' padding: nop nullified: false delayslot candidate: false (* Note, for V8 the cc bit must be ICC *) | Ticc of { t:branch, cc:cc, r: $GP, i:operand} asm: ``t<t>\t<if cc = I.ICC then () else emit "%xcc, "><r>+<i>'' mc: ticc{t,r,cc,i} rtl: ``T<cc><t>'' delayslot candidate: false | FPop1 of { a:farith1, r: $FP, d: $FP } asm: let fun f(a,r,d) = (emit(a); emit "\t"; emit(C.showFP r); emit ", "; emit(C.showFP d)) fun g(a,r,d) = let val r = C.registerNum r and d = C.registerNum d in f(a,r,d); emit "\n\t"; f("fmovs",r+1,d+1) end fun h(a,r,d) = let val r = C.registerNum r and d = C.registerNum d in f(a,r,d); emit "\n\t"; f("fmovs",r+1,d+1); emit "\n\t"; f("fmovs",r+2,d+2); emit "\n\t"; f("fmovs",r+3,d+3) end in if V9 then ``<a>\t<r>, <d>'' else case a of I.FMOVd => g("fmovs",r,d) | I.FNEGd => g("fnegs",r,d) | I.FABSd => g("fabss",r,d) | I.FMOVq => h("fmovs",r,d) | I.FNEGq => h("fnegs",r,d) | I.FABSq => h("fabss",r,d) | _ => ``<a>\t<r>, <d>'' end mc: (case a of (* composite instructions *) I.FMOVd => fdouble{a=I.FMOVs,r,d} | I.FNEGd => fdouble{a=I.FNEGs,r,d} | I.FABSd => fdouble{a=I.FABSs,r,d} | I.FMOVq => fquad{a=I.FMOVs,r,d} | I.FNEGq => fquad{a=I.FNEGs,r,d} | I.FABSq => fquad{a=I.FABSs,r,d} | _ => fop1{a,r,d} ) rtl: ``<a>'' | FPop2 of { a:farith2, r1: $FP, r2: $FP, d: $FP } asm: ``<a>\t<r1>, <r2>, <d>'' mc: fop2{a,r1,r2,d} rtl: ``<a>'' | FCMP of { cmp:fcmp, r1: $FP, r2: $FP, nop:bool } asm: ``<cmp>\t<r1>, <r2><nop>'' mc: (fcmp{opf=cmp,rs1=r1,rs2=r2}; delay{nop}) rtl: ``<cmp>'' padding: nop = true nullified: false delayslot candidate: false latency: 1 | COPY of { dst: $GP list, src: $GP list, impl:instruction list option ref, tmp:ea option} asm: emitInstrs (Shuffle.shuffle{tmp,src,dst}) rtl: ``COPY'' | FCOPY of { dst: $FP list, src: $FP list, impl:instruction list option ref, tmp:ea option} asm: emitInstrs (Shuffle.shufflefp{tmp,src,dst}) rtl: ``FCOPY'' | SAVE of {r: $GP, i:operand, d: $GP} asm: ``save\t<r>, <i>, <d>'' mc: save{r,i,d} | RESTORE of {r: $GP, i:operand, d: $GP} asm: ``restore\t<r>, <i>, <d>'' mc: restore{r,i,d} | RDY of {d: $GP} asm: ``rd\t%y, <d>'' mc: rdy{d} rtl: ``RDY'' | WRY of {r: $GP,i:operand} asm: ``wr\t<r>, <i>, %y'' mc: wdy{r,i} rtl: ``WRY'' | RET of {leaf:bool,nop:bool} asm: ``ret<leaf><nop>'' mc: (jmp{r=if leaf then r31 else r15,i=I.IMMED 8}; delay{nop}) rtl: ``RET'' padding: nop = true nullified: false | 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.REG r) = T.REG(ty, r) | operand(ty,I.IMMED i) = T.LI i (*| operand(ty,I.LAB le) = T.LABEL le*) | operand(ty,_) = error "operand" end end
root@smlnj-gforge.cs.uchicago.edu | ViewVC Help |
Powered by ViewVC 1.0.0 |