| 1 | (* Copyright (C) 2009,2014 Matthew Fluet. |
| 2 | * Copyright (C) 1999-2007 Henry Cejtin, Matthew Fluet, Suresh |
| 3 | * Jagannathan, and Stephen Weeks. |
| 4 | * Copyright (C) 1997-2000 NEC Research Institute. |
| 5 | * |
| 6 | * MLton is released under a BSD-style license. |
| 7 | * See the file MLton-LICENSE for details. |
| 8 | *) |
| 9 | |
| 10 | signature MACHINE_STRUCTS = |
| 11 | sig |
| 12 | include ATOMS |
| 13 | end |
| 14 | |
| 15 | signature MACHINE = |
| 16 | sig |
| 17 | include MACHINE_STRUCTS |
| 18 | |
| 19 | structure ObjectType: OBJECT_TYPE |
| 20 | structure ObjptrTycon: OBJPTR_TYCON |
| 21 | structure Runtime: RUNTIME |
| 22 | structure Switch: SWITCH |
| 23 | structure Type: REP_TYPE |
| 24 | |
| 25 | sharing Atoms = Type |
| 26 | sharing Atoms = Switch |
| 27 | sharing ObjectType = Type.ObjectType |
| 28 | sharing ObjptrTycon = ObjectType.ObjptrTycon = Type.ObjptrTycon |
| 29 | sharing Runtime = ObjectType.Runtime = Type.Runtime |
| 30 | |
| 31 | structure ChunkLabel: ID |
| 32 | |
| 33 | structure Register: |
| 34 | sig |
| 35 | type t |
| 36 | |
| 37 | val equals: t * t -> bool |
| 38 | val index: t -> int |
| 39 | val indexOpt: t -> int option |
| 40 | val layout: t -> Layout.t |
| 41 | val new: Type.t * int option -> t |
| 42 | val setIndex: t * int -> unit |
| 43 | val toString: t -> string |
| 44 | val ty: t -> Type.t |
| 45 | end |
| 46 | |
| 47 | structure Global: |
| 48 | sig |
| 49 | type t |
| 50 | |
| 51 | val equals: t * t -> bool |
| 52 | val index: t -> int |
| 53 | val isRoot: t -> bool |
| 54 | val layout: t -> Layout.t |
| 55 | val new: {isRoot: bool, ty: Type.t} -> t |
| 56 | val numberOfNonRoot: unit -> int |
| 57 | val numberOfType: CType.t -> int |
| 58 | val ty: t -> Type.t |
| 59 | end |
| 60 | |
| 61 | structure StackOffset: |
| 62 | sig |
| 63 | datatype t = T of {offset: Bytes.t, |
| 64 | ty: Type.t} |
| 65 | |
| 66 | val ty: t -> Type.t |
| 67 | end |
| 68 | |
| 69 | structure Scale: SCALE |
| 70 | sharing Scale = Type.Scale |
| 71 | |
| 72 | structure Operand: |
| 73 | sig |
| 74 | datatype t = |
| 75 | ArrayOffset of {base: t, |
| 76 | index: t, |
| 77 | offset: Bytes.t, |
| 78 | scale: Scale.t, |
| 79 | ty: Type.t} |
| 80 | | Cast of t * Type.t |
| 81 | | Contents of {oper: t, |
| 82 | ty: Type.t} |
| 83 | | Frontier |
| 84 | | GCState |
| 85 | | Global of Global.t |
| 86 | | Label of Label.t |
| 87 | | Null |
| 88 | | Offset of {base: t, |
| 89 | offset: Bytes.t, |
| 90 | ty: Type.t} |
| 91 | | Real of RealX.t |
| 92 | | Register of Register.t |
| 93 | | StackOffset of StackOffset.t |
| 94 | | StackTop |
| 95 | | Word of WordX.t |
| 96 | |
| 97 | val equals: t * t -> bool |
| 98 | val interfere: t * t -> bool |
| 99 | val isLocation: t -> bool |
| 100 | val layout: t -> Layout.t |
| 101 | val stackOffset: {offset: Bytes.t, ty: Type.t} -> t |
| 102 | val toString: t -> string |
| 103 | val ty: t -> Type.t |
| 104 | end |
| 105 | sharing Operand = Switch.Use |
| 106 | |
| 107 | structure Live: |
| 108 | sig |
| 109 | datatype t = |
| 110 | Global of Global.t |
| 111 | | Register of Register.t |
| 112 | | StackOffset of StackOffset.t |
| 113 | |
| 114 | val equals: t * t -> bool |
| 115 | val fromOperand: Operand.t -> t option |
| 116 | val layout: t -> Layout.t |
| 117 | val toOperand: t -> Operand.t |
| 118 | val ty: t -> Type.t |
| 119 | end |
| 120 | |
| 121 | structure Statement: |
| 122 | sig |
| 123 | datatype t = |
| 124 | (* When registers or offsets appear in operands, there is an |
| 125 | * implicit contents of. |
| 126 | * When they appear as locations, there is not. |
| 127 | *) |
| 128 | Move of {dst: Operand.t, |
| 129 | src: Operand.t} |
| 130 | | Noop |
| 131 | | PrimApp of {args: Operand.t vector, |
| 132 | dst: Operand.t option, |
| 133 | prim: Type.t Prim.t} |
| 134 | | ProfileLabel of ProfileLabel.t |
| 135 | |
| 136 | val foldOperands: t * 'a * (Operand.t * 'a -> 'a) -> 'a |
| 137 | val layout: t -> Layout.t |
| 138 | val move: {dst: Operand.t, src: Operand.t} -> t |
| 139 | (* Error if dsts and srcs aren't of same length. *) |
| 140 | val moves: {dsts: Operand.t vector, |
| 141 | srcs: Operand.t vector} -> t vector |
| 142 | val object: {dst: Operand.t, header: word, size: Bytes.t} -> t vector |
| 143 | end |
| 144 | |
| 145 | structure FrameInfo: |
| 146 | sig |
| 147 | datatype t = T of {frameLayoutsIndex: int} |
| 148 | |
| 149 | val equals: t * t -> bool |
| 150 | val layout: t -> Layout.t |
| 151 | end |
| 152 | |
| 153 | structure Transfer: |
| 154 | sig |
| 155 | datatype t = |
| 156 | (* In an arith transfer, dst is modified whether or not the |
| 157 | * prim succeeds. |
| 158 | *) |
| 159 | Arith of {args: Operand.t vector, |
| 160 | dst: Operand.t, |
| 161 | overflow: Label.t, |
| 162 | prim: Type.t Prim.t, |
| 163 | success: Label.t} |
| 164 | | CCall of {args: Operand.t vector, |
| 165 | frameInfo: FrameInfo.t option, |
| 166 | func: Type.t CFunction.t, |
| 167 | (* return is NONE iff the func doesn't return. |
| 168 | * Else, return must be SOME l, where l is of CReturn |
| 169 | * kind with a matching func. |
| 170 | *) |
| 171 | return: Label.t option} |
| 172 | | Call of {label: Label.t, (* label must be a Func *) |
| 173 | live: Live.t vector, |
| 174 | return: {return: Label.t, |
| 175 | handler: Label.t option, |
| 176 | size: Bytes.t} option} |
| 177 | | Goto of Label.t (* label must be a Jump *) |
| 178 | | Raise |
| 179 | | Return |
| 180 | | Switch of Switch.t |
| 181 | |
| 182 | val foldOperands: t * 'a * (Operand.t * 'a -> 'a) -> 'a |
| 183 | val layout: t -> Layout.t |
| 184 | end |
| 185 | |
| 186 | structure Kind: |
| 187 | sig |
| 188 | datatype t = |
| 189 | Cont of {args: Live.t vector, |
| 190 | frameInfo: FrameInfo.t} |
| 191 | | CReturn of {dst: Live.t option, |
| 192 | frameInfo: FrameInfo.t option, |
| 193 | func: Type.t CFunction.t} |
| 194 | | Func |
| 195 | | Handler of {frameInfo: FrameInfo.t, |
| 196 | handles: Live.t vector} |
| 197 | | Jump |
| 198 | |
| 199 | val frameInfoOpt: t -> FrameInfo.t option |
| 200 | end |
| 201 | |
| 202 | structure Block: |
| 203 | sig |
| 204 | datatype t = |
| 205 | T of {kind: Kind.t, |
| 206 | label: Label.t, |
| 207 | (* Live registers and stack offsets at start of block. *) |
| 208 | live: Live.t vector, |
| 209 | raises: Live.t vector option, |
| 210 | returns: Live.t vector option, |
| 211 | statements: Statement.t vector, |
| 212 | transfer: Transfer.t} |
| 213 | |
| 214 | val foldDefs: t * 'a * (Operand.t * 'a -> 'a) -> 'a |
| 215 | val label: t -> Label.t |
| 216 | end |
| 217 | |
| 218 | structure Chunk: |
| 219 | sig |
| 220 | datatype t = |
| 221 | T of {blocks: Block.t vector, |
| 222 | chunkLabel: ChunkLabel.t, |
| 223 | (* Register.index r |
| 224 | * <= regMax (Type.toCType (Register.ty r)) |
| 225 | * for all registers in the chunk. |
| 226 | *) |
| 227 | regMax: CType.t -> int} |
| 228 | end |
| 229 | |
| 230 | structure ProfileInfo: |
| 231 | sig |
| 232 | datatype t = |
| 233 | T of {(* For each frame, gives the index into sourceSeqs of the |
| 234 | * source functions corresponding to the frame. |
| 235 | *) |
| 236 | frameSources: int vector, |
| 237 | labels: {label: ProfileLabel.t, |
| 238 | sourceSeqsIndex: int} vector, |
| 239 | names: string vector, |
| 240 | (* Each sourceSeq describes a sequence of source functions, |
| 241 | * each given as an index into the source vector. |
| 242 | *) |
| 243 | sourceSeqs: int vector vector, |
| 244 | sources: {nameIndex: int, |
| 245 | successorsIndex: int} vector} |
| 246 | |
| 247 | val empty: t |
| 248 | val modify: t -> {newProfileLabel: ProfileLabel.t -> ProfileLabel.t, |
| 249 | delProfileLabel: ProfileLabel.t -> unit, |
| 250 | getProfileInfo: unit -> t} |
| 251 | end |
| 252 | |
| 253 | structure Program: |
| 254 | sig |
| 255 | datatype t = |
| 256 | T of {chunks: Chunk.t list, |
| 257 | frameLayouts: {frameOffsetsIndex: int, |
| 258 | isC: bool, |
| 259 | size: Bytes.t} vector, |
| 260 | (* Each vector in frame Offsets specifies the offsets |
| 261 | * of live pointers in a stack frame. A vector is referred |
| 262 | * to by index as the offsetsIndex in frameLayouts. |
| 263 | *) |
| 264 | frameOffsets: Bytes.t vector vector, |
| 265 | handlesSignals: bool, |
| 266 | main: {chunkLabel: ChunkLabel.t, |
| 267 | label: Label.t}, |
| 268 | maxFrameSize: Bytes.t, |
| 269 | objectTypes: Type.ObjectType.t vector, |
| 270 | profileInfo: ProfileInfo.t option, |
| 271 | reals: (Global.t * RealX.t) list, |
| 272 | vectors: (Global.t * WordXVector.t) list} |
| 273 | |
| 274 | val frameSize: t * FrameInfo.t -> Bytes.t |
| 275 | val clearLabelNames: t -> unit |
| 276 | val layouts: t * (Layout.t -> unit) -> unit |
| 277 | val typeCheck: t -> unit |
| 278 | end |
| 279 | end |