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 x86MLtonBasic (S: X86_MLTON_BASIC_STRUCTS): X86_MLTON_BASIC = | |
11 | struct | |
12 | ||
13 | open S | |
14 | open x86 | |
15 | ||
16 | local | |
17 | open Machine | |
18 | in | |
19 | structure CType = CType | |
20 | structure Runtime = Runtime | |
21 | end | |
22 | ||
23 | (* | |
24 | * x86.Size.t equivalents | |
25 | *) | |
26 | val wordBytes = Bytes.toInt Bytes.inWord32 | |
27 | val wordSize = Size.fromBytes wordBytes | |
28 | val wordScale = Scale.fromBytes wordBytes | |
29 | val pointerBytes = Bytes.toInt Bytes.inWord32 | |
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 CStack = MemLoc.Class.CStack | |
48 | val Code = MemLoc.Class.Code | |
49 | ||
50 | val CStatic = new "CStatic" | |
51 | val StaticNonTemp = new "StaticNonTemp" | |
52 | ||
53 | val GCState = new "GCState" | |
54 | val GCStateHold = new "GCStateHold" | |
55 | val GCStateVolatile = new "GCStateVolatile" | |
56 | end | |
57 | ||
58 | val allClasses = ref x86.ClassSet.empty | |
59 | val livenessClasses = ref x86.ClassSet.empty | |
60 | val holdClasses = ref x86.ClassSet.empty | |
61 | val volatileClasses = ref x86.ClassSet.empty | |
62 | val runtimeClasses = ref x86.ClassSet.empty | |
63 | val heapClasses = ref x86.ClassSet.empty | |
64 | val cstaticClasses = ref x86.ClassSet.empty | |
65 | ||
66 | fun initClasses () | |
67 | = let | |
68 | val _ = allClasses := | |
69 | x86.ClassSet.fromList | |
70 | ( | |
71 | Heap:: | |
72 | Stack:: | |
73 | Locals:: | |
74 | Globals:: | |
75 | Temp:: | |
76 | StaticTemp:: | |
77 | CStack:: | |
78 | Code:: | |
79 | CStatic:: | |
80 | StaticNonTemp:: | |
81 | GCState:: | |
82 | GCStateHold:: | |
83 | GCStateVolatile:: | |
84 | nil) | |
85 | ||
86 | val _ = livenessClasses := | |
87 | (if !Control.Native.liveStack | |
88 | then x86.ClassSet.fromList | |
89 | ( | |
90 | Temp:: | |
91 | Locals:: | |
92 | StaticTemp:: | |
93 | Stack:: | |
94 | nil) | |
95 | else x86.ClassSet.fromList | |
96 | ( | |
97 | Temp:: | |
98 | Locals:: | |
99 | StaticTemp:: | |
100 | nil)) | |
101 | ||
102 | val _ = holdClasses := | |
103 | x86.ClassSet.fromList | |
104 | ( | |
105 | GCStateHold:: | |
106 | (* | |
107 | GCStateVolatile:: | |
108 | *) | |
109 | nil) | |
110 | ||
111 | val _ = volatileClasses := | |
112 | x86.ClassSet.fromList | |
113 | ( | |
114 | GCStateVolatile:: | |
115 | nil) | |
116 | ||
117 | val _ = runtimeClasses := | |
118 | x86.ClassSet.fromList | |
119 | ( | |
120 | Heap:: | |
121 | Stack:: | |
122 | Globals:: | |
123 | GCState:: | |
124 | GCStateHold:: | |
125 | GCStateVolatile:: | |
126 | nil) | |
127 | ||
128 | val _ = heapClasses := | |
129 | x86.ClassSet.fromList | |
130 | ( | |
131 | Heap:: | |
132 | nil) | |
133 | ||
134 | val _ = cstaticClasses := | |
135 | x86.ClassSet.fromList | |
136 | ( | |
137 | CStatic:: | |
138 | nil) | |
139 | in | |
140 | () | |
141 | end | |
142 | end | |
143 | ||
144 | val makeContents = x86.MemLoc.makeContents | |
145 | val c_stackP = Label.fromString "c_stackP" | |
146 | val c_stackPContents | |
147 | = makeContents {base = Immediate.label c_stackP, | |
148 | size = pointerSize, | |
149 | class = Classes.StaticNonTemp} | |
150 | val c_stackPContentsOperand | |
151 | = Operand.memloc c_stackPContents | |
152 | val c_stackPDerefDouble | |
153 | = MemLoc.simple {base = c_stackPContents, | |
154 | index = Immediate.zero, | |
155 | scale = wordScale, | |
156 | size = Size.DBLE, | |
157 | class = Classes.CStack} | |
158 | val c_stackPDerefDoubleOperand | |
159 | = Operand.memloc c_stackPDerefDouble | |
160 | val c_stackPDerefFloat | |
161 | = MemLoc.simple {base = c_stackPContents, | |
162 | index = Immediate.zero, | |
163 | scale = wordScale, | |
164 | size = Size.SNGL, | |
165 | class = Classes.CStack} | |
166 | val c_stackPDerefFloatOperand | |
167 | = Operand.memloc c_stackPDerefFloat | |
168 | ||
169 | (* This is more a pseudo-location. The GOT is special and cannot | |
170 | * be simply loaded. Similarly, we don't really read the contents. | |
171 | *) | |
172 | val globalOffsetTable = Label.fromString "_GLOBAL_OFFSET_TABLE_" | |
173 | val globalOffsetTableContents | |
174 | = makeContents {base = Immediate.label globalOffsetTable, | |
175 | size = pointerSize, | |
176 | class = Classes.StaticNonTemp} | |
177 | ||
178 | val applyFFTempFun = Label.fromString "applyFFTempFun" | |
179 | val applyFFTempFunContents | |
180 | = makeContents {base = Immediate.label applyFFTempFun, | |
181 | size = wordSize, | |
182 | class = Classes.StaticTemp} | |
183 | val applyFFTempFunContentsOperand | |
184 | = Operand.memloc applyFFTempFunContents | |
185 | val applyFFTempArg = Label.fromString "applyFFTempArg" | |
186 | val applyFFTempArgContents | |
187 | = makeContents {base = Immediate.label applyFFTempArg, | |
188 | size = wordSize, | |
189 | class = Classes.StaticTemp} | |
190 | val applyFFTempArgContentsOperand | |
191 | = Operand.memloc applyFFTempArgContents | |
192 | ||
193 | val realTemp1D = Label.fromString "realTemp1D" | |
194 | val realTemp1ContentsD | |
195 | = makeContents {base = Immediate.label realTemp1D, | |
196 | size = Size.DBLE, | |
197 | class = Classes.StaticTemp} | |
198 | val realTemp1ContentsOperandD | |
199 | = Operand.memloc realTemp1ContentsD | |
200 | val realTemp1S = Label.fromString "realTemp1S" | |
201 | val realTemp1ContentsS | |
202 | = makeContents {base = Immediate.label realTemp1S, | |
203 | size = Size.SNGL, | |
204 | class = Classes.StaticTemp} | |
205 | val realTemp1ContentsOperandS | |
206 | = Operand.memloc realTemp1ContentsS | |
207 | fun realTemp1ContentsOperand floatSize | |
208 | = case floatSize of | |
209 | Size.DBLE => realTemp1ContentsOperandD | |
210 | | Size.SNGL => realTemp1ContentsOperandS | |
211 | | _ => Error.bug "x86MLtonBasic.realTemp1ContentsOperand: floatSize" | |
212 | ||
213 | val realTemp2D = Label.fromString "realTemp2D" | |
214 | val realTemp2ContentsD | |
215 | = makeContents {base = Immediate.label realTemp2D, | |
216 | size = Size.DBLE, | |
217 | class = Classes.StaticTemp} | |
218 | val realTemp2ContentsOperandD | |
219 | = Operand.memloc realTemp2ContentsD | |
220 | val realTemp2S = Label.fromString "realTemp2S" | |
221 | val realTemp2ContentsS | |
222 | = makeContents {base = Immediate.label realTemp2S, | |
223 | size = Size.SNGL, | |
224 | class = Classes.StaticTemp} | |
225 | val realTemp2ContentsOperandS | |
226 | = Operand.memloc realTemp2ContentsS | |
227 | fun realTemp2ContentsOperand floatSize | |
228 | = case floatSize of | |
229 | Size.DBLE => realTemp2ContentsOperandD | |
230 | | Size.SNGL => realTemp2ContentsOperandS | |
231 | | _ => Error.bug "x86MLtonBasic.realTemp2ContentsOperand: floatSize" | |
232 | ||
233 | val realTemp3D = Label.fromString "realTemp3D" | |
234 | val realTemp3ContentsD | |
235 | = makeContents {base = Immediate.label realTemp3D, | |
236 | size = Size.DBLE, | |
237 | class = Classes.StaticTemp} | |
238 | val realTemp3ContentsOperandD | |
239 | = Operand.memloc realTemp3ContentsD | |
240 | val realTemp3S = Label.fromString "realTemp3S" | |
241 | val realTemp3ContentsS | |
242 | = makeContents {base = Immediate.label realTemp3S, | |
243 | size = Size.SNGL, | |
244 | class = Classes.StaticTemp} | |
245 | val realTemp3ContentsOperandS | |
246 | = Operand.memloc realTemp3ContentsS | |
247 | fun realTemp3ContentsOperand floatSize | |
248 | = case floatSize of | |
249 | Size.DBLE => realTemp3ContentsOperandD | |
250 | | Size.SNGL => realTemp3ContentsOperandS | |
251 | | _ => Error.bug "x86MLtonBasic.realTemp3ContentsOperand: floatSize" | |
252 | ||
253 | val fpswTemp = Label.fromString "fpswTemp" | |
254 | val fpswTempContents | |
255 | = makeContents {base = Immediate.label fpswTemp, | |
256 | size = Size.WORD, | |
257 | class = Classes.StaticTemp} | |
258 | val fpswTempContentsOperand | |
259 | = Operand.memloc fpswTempContents | |
260 | val fildTemp = Label.fromString "fildTemp" | |
261 | val fildTempContents | |
262 | = makeContents {base = Immediate.label fildTemp, | |
263 | size = Size.WORD, | |
264 | class = Classes.StaticTemp} | |
265 | val fildTempContentsOperand | |
266 | = Operand.memloc fildTempContents | |
267 | ||
268 | val wordTemp1B = Label.fromString "wordTemp1B" | |
269 | val wordTemp1ContentsB | |
270 | = makeContents {base = Immediate.label wordTemp1B, | |
271 | size = Size.BYTE, | |
272 | class = Classes.StaticTemp} | |
273 | val wordTemp1ContentsOperandB | |
274 | = Operand.memloc wordTemp1ContentsB | |
275 | val wordTemp1W = Label.fromString "wordTemp1W" | |
276 | val wordTemp1ContentsW | |
277 | = makeContents {base = Immediate.label wordTemp1W, | |
278 | size = Size.WORD, | |
279 | class = Classes.StaticTemp} | |
280 | val wordTemp1ContentsOperandW | |
281 | = Operand.memloc wordTemp1ContentsW | |
282 | val wordTemp1L = Label.fromString "wordTemp1L" | |
283 | val wordTemp1ContentsL | |
284 | = makeContents {base = Immediate.label wordTemp1L, | |
285 | size = Size.LONG, | |
286 | class = Classes.StaticTemp} | |
287 | val wordTemp1ContentsOperandL | |
288 | = Operand.memloc wordTemp1ContentsL | |
289 | fun wordTemp1ContentsOperand wordSize | |
290 | = case wordSize of | |
291 | Size.BYTE => wordTemp1ContentsOperandB | |
292 | | Size.WORD => wordTemp1ContentsOperandW | |
293 | | Size.LONG => wordTemp1ContentsOperandL | |
294 | | _ => Error.bug "x86MLtonBasic.wordTemp1ContentsOperand: wordSize" | |
295 | ||
296 | local | |
297 | fun make prefix = | |
298 | let | |
299 | fun make name size = Label.fromString (concat [prefix, name, size]) | |
300 | val r = make "Real" | |
301 | val w = make "Word" | |
302 | datatype z = datatype CType.t | |
303 | in | |
304 | CType.memo | |
305 | (fn t => | |
306 | case t of | |
307 | CPointer => Label.fromString (concat [prefix, "CPointer"]) | |
308 | | Int8 => w "8" | |
309 | | Int16 => w "16" | |
310 | | Int32 => w "32" | |
311 | | Int64 => w "64" | |
312 | | Objptr => Label.fromString (concat [prefix, "Objptr"]) | |
313 | | Real32 => r "32" | |
314 | | Real64 => r "64" | |
315 | | Word8 => w "8" | |
316 | | Word16 => w "16" | |
317 | | Word32 => w "32" | |
318 | | Word64 => w "64") | |
319 | end | |
320 | in | |
321 | val local_base = make "local" | |
322 | val global_base = make "global" | |
323 | end | |
324 | ||
325 | val globalObjptrNonRoot_base = Label.fromString "globalObjptrNonRoot" | |
326 | ||
327 | val gcState_label = Label.fromString "gcState" | |
328 | ||
329 | structure Field = Runtime.GCField | |
330 | fun make' (offset: int, size, class) = | |
331 | let | |
332 | fun imm () = | |
333 | Immediate.labelPlusInt | |
334 | (gcState_label, offset) | |
335 | fun contents () = | |
336 | makeContents {base = imm (), | |
337 | size = size, | |
338 | class = class} | |
339 | fun operand () = Operand.memloc (contents ()) | |
340 | in | |
341 | (imm, contents, operand) | |
342 | end | |
343 | fun make (f: Field.t, size, class) = | |
344 | let | |
345 | fun imm () = | |
346 | Immediate.labelPlusInt | |
347 | (gcState_label, Bytes.toInt (Field.offset f)) | |
348 | fun contents () = | |
349 | makeContents {base = imm (), | |
350 | size = size, | |
351 | class = class} | |
352 | fun operand () = Operand.memloc (contents ()) | |
353 | in | |
354 | (imm, contents, operand) | |
355 | end | |
356 | ||
357 | val (_, gcState_exnStackContents, | |
358 | gcState_exnStackContentsOperand) = | |
359 | make (Field.ExnStack, wordSize, Classes.GCState) | |
360 | ||
361 | val (_, gcState_frontierContents, | |
362 | gcState_frontierContentsOperand) = | |
363 | make (Field.Frontier, pointerSize, Classes.GCStateHold) | |
364 | ||
365 | val (_, gcState_stackBottomContents, | |
366 | gcState_stackBottomContentsOperand) = | |
367 | make (Field.StackBottom, pointerSize, Classes.GCState) | |
368 | ||
369 | val (_, gcState_stackTopContents, | |
370 | gcState_stackTopContentsOperand) = | |
371 | make (Field.StackTop, pointerSize, Classes.GCStateHold) | |
372 | ||
373 | local | |
374 | val stackTopTemp = | |
375 | Immediate.label (Label.fromString "stackTopTemp") | |
376 | val stackTopTempContents = | |
377 | makeContents {base = stackTopTemp, | |
378 | size = wordSize, | |
379 | class = Classes.StaticTemp} | |
380 | val stackTopTempContentsOperand = | |
381 | Operand.memloc (stackTopTempContents) | |
382 | in | |
383 | val stackTopTempContents = fn () => stackTopTempContents | |
384 | val stackTopTempContentsOperand = fn () => stackTopTempContentsOperand | |
385 | end | |
386 | ||
387 | fun gcState_stackTopMinusWordDeref () = | |
388 | MemLoc.simple {base = gcState_stackTopContents (), | |
389 | index = Immediate.int ~1, | |
390 | scale = wordScale, | |
391 | size = pointerSize, | |
392 | class = Classes.Stack} | |
393 | fun gcState_stackTopMinusWordDerefOperand () = | |
394 | Operand.memloc (gcState_stackTopMinusWordDeref ()) | |
395 | ||
396 | fun stackTopTempMinusWordDeref () = | |
397 | MemLoc.simple {base = stackTopTempContents (), | |
398 | index = Immediate.int ~1, | |
399 | scale = wordScale, | |
400 | size = pointerSize, | |
401 | class = Classes.Stack} | |
402 | fun stackTopTempMinusWordDerefOperand () = | |
403 | Operand.memloc (stackTopTempMinusWordDeref ()) | |
404 | ||
405 | fun gcState_offset {offset, ty} = | |
406 | let | |
407 | val (_,_,operand) = | |
408 | make' (offset, Vector.sub(x86.Size.fromCType ty, 0), Classes.GCState) | |
409 | in | |
410 | operand () | |
411 | end | |
412 | ||
413 | (* init *) | |
414 | fun init () = let | |
415 | val _ = Classes.initClasses () | |
416 | in | |
417 | () | |
418 | end | |
419 | end |