Commit | Line | Data |
---|---|---|
7f918cf1 CE |
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 |