1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
|
(*
* Description of cell and other updatable cells.
*
* -- Allen.
*)
(*
* This functor is applied to create the cells structure for an architecture
*)
functor Cells
(exception Cells
val firstPseudo : int
val cellKindDescs : (CellsBasis.cellkind * CellsBasis.cellkindDesc) list
val cellSize : int
) : CELLS =
struct
open CellsBasis
exception Cells = Cells
val i2s = Int.toString
fun error msg = MLRiscErrorMsg.error(exnName Cells, msg)
val cellkinds = map (fn (kind,_) => kind) cellKindDescs
val firstPseudo = firstPseudo
val maxDedicatedCells = 256
val firstName = firstPseudo + maxDedicatedCells
val name = ref firstName
(* val cellCounter = name *)
val _ = app (fn (_, desc as DESC{physicalRegs, high, low, ...}) =>
let val n = high - low + 1
in if n <= 0 then ()
else let val a = Array.tabulate(n, fn nth =>
let val reg = nth + low
in CELL{id=reg, col=ref(MACHINE reg),
an=ref [], desc=desc}
end)
in physicalRegs := a
end
end) cellKindDescs
fun nextName() = let val id = !name in name := !name + 1; id end
fun desc(k:cellkind) =
let fun loop [] = error("missing info for "^cellkindToString k)
| loop((kind,info)::defs) =
if kind = k then info else loop defs
in loop cellKindDescs end
val cellkindDesc = desc
fun cellRange k =
let val DESC{low,high,...} = desc k
in {low=low,high=high} end
fun Reg k = let
val desc as DESC{low,kind,physicalRegs,...} = desc k
in
fn nth => (Array.sub(!physicalRegs,nth) handle _ => raise Cells)
end
fun Regs k =
let val Reg = Reg k
fun loop{from, to, step} =
if from > to then []
else Reg from :: loop{from=from+step, to=to, step=step}
in loop end
fun Cell k =
let val desc as DESC{low,kind,physicalRegs,...} = desc k
in fn reg =>
Array.sub(!physicalRegs,reg - low) handle _ => raise Cells
end
val GPReg = Reg GP
val FPReg = Reg FP
(* Counters *)
fun newCell k =
let val desc as DESC{counter,...} = desc k
in fn _ =>
let val r = !name
in name := r + 1;
counter := !counter + 1;
CELL{id=r, col=ref PSEUDO, an=ref [], desc=desc}
end
end
local val desc as DESC{counter, ...} = desc GP
in fun newReg _ =
let val r = !name
in name := r + 1;
counter := !counter + 1;
CELL{id=r, col=ref PSEUDO, an=ref [], desc=desc}
end
end
local val desc as DESC{counter, ...} = desc FP
in fun newFreg _ =
let val r = !name
in name := r + 1;
counter := !counter + 1;
CELL{id=r, col=ref PSEUDO, an=ref [], desc=desc}
end
end
fun newDedicatedCell k =
let val desc as DESC{dedicated,...} = desc k
in fn _ =>
let val d = !dedicated
in dedicated := d + 1;
if d >= maxDedicatedCells then
error "too many dedicated cells"
else
CELL{id=firstPseudo+d, col=ref PSEUDO, an=ref [], desc=desc}
end
end
fun newVar (CELL{desc, an, ...}) =
let val r = !name
in name := r + 1;
CELL{id=r, col=ref PSEUDO, an=ref(!an), desc=desc}
end
fun cloneCell c =
let val CELL{desc, an, col, ...} = chase c
val r = !name
in name := r + 1;
CELL{id=r, col=ref(!col), an=ref(!an), desc=desc}
end
fun numCell k = let val DESC{counter, ...} = desc k
in fn () => !counter end
fun maxCell() = !name
fun reset() =
(app (fn (_,DESC{counter, ...}) => counter := 0) cellKindDescs;
name := firstName
)
type cellset = CellSet.cellset
val empty = CellSet.empty
fun getCellsByKind (k : cellkind) = CellSet.get (desc k)
fun updateCellsByKind (k : cellkind) = CellSet.update (desc k)
val getReg = getCellsByKind GP
val getFreg = getCellsByKind FP
val addReg = CellSet.add
val addFreg = CellSet.add
val rmvReg = CellSet.rmv
val rmvFreg = CellSet.rmv
(* Misc *)
fun zeroReg k =
let val desc as DESC{zeroReg, physicalRegs, low, ...} = desc k
in case zeroReg of
NONE => NONE
| SOME r => SOME(Array.sub(!physicalRegs, r))
end
fun defaultValues k =
let val DESC{defaultValues, ...} = desc k
in defaultValues end
(* dummy values for now; these get redefined for each architecture *)
val stackptrR = GPReg 0
val asmTmpR = GPReg 0
val fasmTmp = FPReg 0
val cellSize = cellSize
end
|