Import Upstream version 20180207
[hcoop/debian/mlton.git] / mlton / codegen / amd64-codegen / amd64-mlton-basic.fun
CommitLineData
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
10functor amd64MLtonBasic (S: AMD64_MLTON_BASIC_STRUCTS): AMD64_MLTON_BASIC =
11struct
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
358end