Commit | Line | Data |
---|---|---|
7f918cf1 CE |
1 | (* Copyright (C) 2009 Matthew Fluet. |
2 | * Copyright (C) 1999-2008 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 | functor amd64MLtonBasic (S: AMD64_MLTON_BASIC_STRUCTS): AMD64_MLTON_BASIC = | |
11 | struct | |
12 | ||
13 | open S | |
14 | open amd64 | |
15 | ||
16 | local | |
17 | open Machine | |
18 | in | |
19 | structure CType = CType | |
20 | structure Runtime = Runtime | |
21 | end | |
22 | ||
23 | (* | |
24 | * amd64.Size.t equivalents | |
25 | *) | |
26 | val wordBytes = Bytes.toInt Bytes.inWord64 | |
27 | val wordSize = Size.fromBytes wordBytes | |
28 | val wordScale = Scale.fromBytes wordBytes | |
29 | val pointerBytes = Bytes.toInt Bytes.inWord64 | |
30 | val pointerSize = Size.fromBytes pointerBytes | |
31 | ||
32 | (* | |
33 | * Memory classes | |
34 | *) | |
35 | structure Classes = | |
36 | struct | |
37 | local | |
38 | fun new s = MemLoc.Class.new {name = s} | |
39 | in | |
40 | val Heap = new "Heap" | |
41 | val Stack = new "Stack" | |
42 | val Locals = new "Locals" | |
43 | val Globals = new "Globals" | |
44 | ||
45 | val Temp = MemLoc.Class.Temp | |
46 | val StaticTemp = MemLoc.Class.StaticTemp | |
47 | val CArg = MemLoc.Class.CArg | |
48 | val CStack = MemLoc.Class.CStack | |
49 | val Code = MemLoc.Class.Code | |
50 | ||
51 | val CStatic = new "CStatic" | |
52 | val StaticNonTemp = new "StaticNonTemp" | |
53 | ||
54 | val GCState = new "GCState" | |
55 | val GCStateHold = new "GCStateHold" | |
56 | val GCStateVolatile = new "GCStateVolatile" | |
57 | end | |
58 | ||
59 | val allClasses = ref amd64.ClassSet.empty | |
60 | val livenessClasses = ref amd64.ClassSet.empty | |
61 | val holdClasses = ref amd64.ClassSet.empty | |
62 | val volatileClasses = ref amd64.ClassSet.empty | |
63 | val runtimeClasses = ref amd64.ClassSet.empty | |
64 | val heapClasses = ref amd64.ClassSet.empty | |
65 | val cargClasses = ref amd64.ClassSet.empty | |
66 | val cstaticClasses = ref amd64.ClassSet.empty | |
67 | ||
68 | fun initClasses () | |
69 | = let | |
70 | val _ = allClasses := | |
71 | amd64.ClassSet.fromList | |
72 | ( | |
73 | Heap:: | |
74 | Stack:: | |
75 | Locals:: | |
76 | Globals:: | |
77 | Temp:: | |
78 | StaticTemp:: | |
79 | CArg:: | |
80 | CStack:: | |
81 | Code:: | |
82 | CStatic:: | |
83 | StaticNonTemp:: | |
84 | GCState:: | |
85 | GCStateHold:: | |
86 | GCStateVolatile:: | |
87 | nil) | |
88 | ||
89 | val _ = livenessClasses := | |
90 | (if !Control.Native.liveStack | |
91 | then amd64.ClassSet.fromList | |
92 | ( | |
93 | Temp:: | |
94 | Locals:: | |
95 | StaticTemp:: | |
96 | Stack:: | |
97 | nil) | |
98 | else amd64.ClassSet.fromList | |
99 | ( | |
100 | Temp:: | |
101 | Locals:: | |
102 | StaticTemp:: | |
103 | nil)) | |
104 | ||
105 | val _ = holdClasses := | |
106 | amd64.ClassSet.fromList | |
107 | ( | |
108 | GCStateHold:: | |
109 | (* | |
110 | GCStateVolatile:: | |
111 | *) | |
112 | nil) | |
113 | ||
114 | val _ = volatileClasses := | |
115 | amd64.ClassSet.fromList | |
116 | ( | |
117 | GCStateVolatile:: | |
118 | nil) | |
119 | ||
120 | val _ = runtimeClasses := | |
121 | amd64.ClassSet.fromList | |
122 | ( | |
123 | Heap:: | |
124 | Stack:: | |
125 | Globals:: | |
126 | GCState:: | |
127 | GCStateHold:: | |
128 | GCStateVolatile:: | |
129 | nil) | |
130 | ||
131 | val _ = heapClasses := | |
132 | amd64.ClassSet.fromList | |
133 | ( | |
134 | Heap:: | |
135 | nil) | |
136 | ||
137 | val _ = cstaticClasses := | |
138 | amd64.ClassSet.fromList | |
139 | ( | |
140 | CStatic:: | |
141 | nil) | |
142 | val _ = cargClasses := | |
143 | amd64.ClassSet.fromList | |
144 | ( | |
145 | CArg:: | |
146 | nil) | |
147 | in | |
148 | () | |
149 | end | |
150 | end | |
151 | ||
152 | val makeContents = amd64.MemLoc.makeContents | |
153 | val c_stackP = Label.fromString "c_stackP" | |
154 | val c_stackPContents | |
155 | = makeContents {base = Immediate.label c_stackP, | |
156 | size = pointerSize, | |
157 | class = Classes.StaticNonTemp} | |
158 | val c_stackPContentsOperand | |
159 | = Operand.memloc c_stackPContents | |
160 | val c_stackPDerefWord | |
161 | = MemLoc.simple {base = c_stackPContents, | |
162 | index = Immediate.zero, | |
163 | scale = wordScale, | |
164 | size = Size.QUAD, | |
165 | class = Classes.CStack} | |
166 | val c_stackPDerefWordOperand | |
167 | = Operand.memloc c_stackPDerefWord | |
168 | val c_stackPDerefDouble | |
169 | = MemLoc.simple {base = c_stackPContents, | |
170 | index = Immediate.zero, | |
171 | scale = wordScale, | |
172 | size = Size.DBLE, | |
173 | class = Classes.CStack} | |
174 | val c_stackPDerefDoubleOperand | |
175 | = Operand.memloc c_stackPDerefDouble | |
176 | val c_stackPDerefFloat | |
177 | = MemLoc.simple {base = c_stackPContents, | |
178 | index = Immediate.zero, | |
179 | scale = wordScale, | |
180 | size = Size.SNGL, | |
181 | class = Classes.CStack} | |
182 | val c_stackPDerefFloatOperand | |
183 | = Operand.memloc c_stackPDerefFloat | |
184 | ||
185 | val applyFFTempFun = Label.fromString "applyFFTempFun" | |
186 | val applyFFTempFunContents | |
187 | = makeContents {base = Immediate.label applyFFTempFun, | |
188 | size = wordSize, | |
189 | class = Classes.CStatic} | |
190 | val applyFFTempFunContentsOperand | |
191 | = Operand.memloc applyFFTempFunContents | |
192 | val applyFFTempRegArg = Label.fromString "applyFFTempRegArg" | |
193 | fun applyFFTempRegArgContents i | |
194 | = MemLoc.imm {base = Immediate.label applyFFTempRegArg, | |
195 | index = Immediate.int i, | |
196 | scale = Scale.Eight, | |
197 | size = wordSize, | |
198 | class = Classes.CArg} | |
199 | ||
200 | val applyFFTempXmmRegArgS = Label.fromString "applyFFTempXmmRegArgS" | |
201 | fun applyFFTempXmmRegArgSContents i | |
202 | = MemLoc.imm {base = Immediate.label applyFFTempXmmRegArgS, | |
203 | index = Immediate.int i, | |
204 | scale = Scale.Four, | |
205 | size = Size.SNGL, | |
206 | class = Classes.CArg} | |
207 | val applyFFTempXmmRegArgD = Label.fromString "applyFFTempXmmRegArgD" | |
208 | fun applyFFTempXmmRegArgDContents i | |
209 | = MemLoc.imm {base = Immediate.label applyFFTempXmmRegArgD, | |
210 | index = Immediate.int i, | |
211 | scale = Scale.Eight, | |
212 | size = Size.DBLE, | |
213 | class = Classes.CArg} | |
214 | fun applyFFTempXmmRegArgContents (floatSize, i) | |
215 | = case floatSize of | |
216 | Size.DBLE => applyFFTempXmmRegArgDContents i | |
217 | | Size.SNGL => applyFFTempXmmRegArgSContents i | |
218 | | _ => Error.bug "amd64MLtonBasic.applyFFTempXmmRegArgContents" | |
219 | ||
220 | val fpcvtTemp = Label.fromString "fpcvtTemp" | |
221 | val fpcvtTempContents | |
222 | = makeContents {base = Immediate.label fpcvtTemp, | |
223 | size = wordSize, | |
224 | class = Classes.StaticTemp} | |
225 | val fpcvtTempContentsOperand | |
226 | = Operand.memloc fpcvtTempContents | |
227 | val fpeqTemp = Label.fromString "fpeqTemp" | |
228 | fun fpeqTempContents size | |
229 | = makeContents {base = Immediate.label fpeqTemp, | |
230 | size = size, | |
231 | class = Classes.StaticTemp} | |
232 | fun fpeqTempContentsOperand size | |
233 | = Operand.memloc (fpeqTempContents size) | |
234 | ||
235 | local | |
236 | fun make prefix = | |
237 | let | |
238 | fun make name size = Label.fromString (concat [prefix, name, size]) | |
239 | val r = make "Real" | |
240 | val w = make "Word" | |
241 | datatype z = datatype CType.t | |
242 | in | |
243 | CType.memo | |
244 | (fn t => | |
245 | case t of | |
246 | CPointer => Label.fromString (concat [prefix, "CPointer"]) | |
247 | | Int8 => w "8" | |
248 | | Int16 => w "16" | |
249 | | Int32 => w "32" | |
250 | | Int64 => w "64" | |
251 | | Objptr => Label.fromString (concat [prefix, "Objptr"]) | |
252 | | Real32 => r "32" | |
253 | | Real64 => r "64" | |
254 | | Word8 => w "8" | |
255 | | Word16 => w "16" | |
256 | | Word32 => w "32" | |
257 | | Word64 => w "64") | |
258 | end | |
259 | in | |
260 | val local_base = make "local" | |
261 | val global_base = make "global" | |
262 | end | |
263 | ||
264 | val globalObjptrNonRoot_base = Label.fromString "globalObjptrNonRoot" | |
265 | ||
266 | val gcState_label = Label.fromString "gcState" | |
267 | ||
268 | structure Field = Runtime.GCField | |
269 | fun make' (offset: int, size, class) = | |
270 | let | |
271 | fun imm () = | |
272 | Immediate.labelPlusInt | |
273 | (gcState_label, offset) | |
274 | fun contents () = | |
275 | makeContents {base = imm (), | |
276 | size = size, | |
277 | class = class} | |
278 | fun operand () = Operand.memloc (contents ()) | |
279 | in | |
280 | (imm, contents, operand) | |
281 | end | |
282 | fun make (f: Field.t, size, class) = | |
283 | let | |
284 | fun imm () = | |
285 | Immediate.labelPlusInt | |
286 | (gcState_label, Bytes.toInt (Field.offset f)) | |
287 | fun contents () = | |
288 | makeContents {base = imm (), | |
289 | size = size, | |
290 | class = class} | |
291 | fun operand () = Operand.memloc (contents ()) | |
292 | in | |
293 | (imm, contents, operand) | |
294 | end | |
295 | ||
296 | val (_, gcState_exnStackContents, | |
297 | gcState_exnStackContentsOperand) = | |
298 | make (Field.ExnStack, wordSize, Classes.GCState) | |
299 | ||
300 | val (_, gcState_frontierContents, | |
301 | gcState_frontierContentsOperand) = | |
302 | make (Field.Frontier, pointerSize, Classes.GCStateHold) | |
303 | ||
304 | val (_, gcState_stackBottomContents, | |
305 | gcState_stackBottomContentsOperand) = | |
306 | make (Field.StackBottom, pointerSize, Classes.GCState) | |
307 | ||
308 | val (_, gcState_stackTopContents, | |
309 | gcState_stackTopContentsOperand) = | |
310 | make (Field.StackTop, pointerSize, Classes.GCStateHold) | |
311 | ||
312 | local | |
313 | val stackTopTemp = | |
314 | Immediate.label (Label.fromString "stackTopTemp") | |
315 | val stackTopTempContents = | |
316 | makeContents {base = stackTopTemp, | |
317 | size = wordSize, | |
318 | class = Classes.StaticTemp} | |
319 | val stackTopTempContentsOperand = | |
320 | Operand.memloc (stackTopTempContents) | |
321 | in | |
322 | val stackTopTempContents = fn () => stackTopTempContents | |
323 | val stackTopTempContentsOperand = fn () => stackTopTempContentsOperand | |
324 | end | |
325 | ||
326 | fun gcState_stackTopMinusWordDeref () = | |
327 | MemLoc.simple {base = gcState_stackTopContents (), | |
328 | index = Immediate.int ~1, | |
329 | scale = wordScale, | |
330 | size = pointerSize, | |
331 | class = Classes.Stack} | |
332 | fun gcState_stackTopMinusWordDerefOperand () = | |
333 | Operand.memloc (gcState_stackTopMinusWordDeref ()) | |
334 | ||
335 | fun stackTopTempMinusWordDeref () = | |
336 | MemLoc.simple {base = stackTopTempContents (), | |
337 | index = Immediate.int ~1, | |
338 | scale = wordScale, | |
339 | size = pointerSize, | |
340 | class = Classes.Stack} | |
341 | fun stackTopTempMinusWordDerefOperand () = | |
342 | Operand.memloc (stackTopTempMinusWordDeref ()) | |
343 | ||
344 | fun gcState_offset {offset, ty} = | |
345 | let | |
346 | val (_,_,operand) = | |
347 | make' (offset, Vector.sub(amd64.Size.fromCType ty, 0), Classes.GCState) | |
348 | in | |
349 | operand () | |
350 | end | |
351 | ||
352 | (* init *) | |
353 | fun init () = let | |
354 | val _ = Classes.initClasses () | |
355 | in | |
356 | () | |
357 | end | |
358 | end |