52
/* Position-independent operations on global variables. */
54
/* Store [srcreg] in global [dstlabel]. Clobbers %r11. */
55
#define STORE_VAR(srcreg,dstlabel) \
56
movq GREL(dstlabel)(%rip), %r11 ; \
59
/* Load global [srclabel] in register [dstreg]. Clobbers %r11. */
60
#define LOAD_VAR(srclabel,dstreg) \
61
movq GREL(srclabel)(%rip), %r11 ; \
64
/* Compare global [label] with register [reg]. Clobbers %rax. */
65
#define CMP_VAR(label,reg) \
66
movq GREL(label)(%rip), %rax ; \
69
/* Test 32-bit global [label] against mask [imm]. Clobbers %r11. */
70
#define TESTL_VAR(imm,label) \
71
movq GREL(label)(%rip), %r11 ; \
74
/* Push global [label] on stack. Clobbers %r11. */
75
#define PUSH_VAR(srclabel) \
76
movq GREL(srclabel)(%rip), %r11 ; \
79
/* Pop global [label] off stack. Clobbers %r11. */
80
#define POP_VAR(dstlabel) \
81
movq GREL(dstlabel)(%rip), %r11 ; \
84
/* Record lowest stack address and return address. Clobbers %rax. */
85
#define RECORD_STACK_FRAME(OFFSET) \
87
movq 8+OFFSET(%rsp), %rax ; \
88
STORE_VAR(%rax,caml_last_return_address) ; \
89
leaq 16+OFFSET(%rsp), %rax ; \
90
STORE_VAR(%rax,caml_bottom_of_stack) ; \
95
/* Non-PIC operations on global variables. Slightly faster. */
97
#define STORE_VAR(srcreg,dstlabel) \
98
movq srcreg, G(dstlabel)(%rip)
100
#define LOAD_VAR(srclabel,dstreg) \
101
movq G(srclabel)(%rip), dstreg
103
#define CMP_VAR(label,reg) \
104
cmpq G(label)(%rip), %r15
106
#define TESTL_VAR(imm,label) \
107
testl imm, G(label)(%rip)
109
#define PUSH_VAR(srclabel) \
110
pushq G(srclabel)(%rip)
112
#define POP_VAR(dstlabel) \
113
popq G(dstlabel)(%rip)
115
#define RECORD_STACK_FRAME(OFFSET) \
116
movq OFFSET(%rsp), %rax ; \
117
STORE_VAR(%rax,caml_last_return_address) ; \
118
leaq 8+OFFSET(%rsp), %rax ; \
119
STORE_VAR(%rax,caml_bottom_of_stack)
49
127
FUNCTION(G(caml_call_gc))
50
/* Record lowest stack address and return address */
52
movq %rax, G(caml_last_return_address)(%rip)
54
movq %rax, G(caml_bottom_of_stack)(%rip)
56
/* Save caml_young_ptr, caml_exception_pointer */
57
movq %r15, G(caml_young_ptr)(%rip)
58
movq %r14, G(caml_exception_pointer)(%rip)
128
RECORD_STACK_FRAME(0)
59
130
/* Build array of registers, save it into caml_gc_regs */
90
164
movlpd %xmm14, 14*8(%rsp)
91
165
movlpd %xmm15, 15*8(%rsp)
92
166
/* Call the garbage collector */
93
call G(caml_garbage_collection)
167
call GCALL(caml_garbage_collection)
168
/* Restore caml_young_ptr, caml_exception_pointer */
169
LOAD_VAR(caml_young_ptr, %r15)
170
LOAD_VAR(caml_exception_pointer, %r14)
94
171
/* Restore all regs used by the code generator */
95
172
movlpd 0*8(%rsp), %xmm0
96
173
movlpd 1*8(%rsp), %xmm1
125
/* Restore caml_young_ptr, caml_exception_pointer */
126
movq G(caml_young_ptr)(%rip), %r15
127
movq G(caml_exception_pointer)(%rip), %r14
128
202
/* Return to caller */
131
205
FUNCTION(G(caml_alloc1))
133
cmpq G(caml_young_limit)(%rip), %r15
208
CMP_VAR(caml_young_limit, %r15)
138
movq %rax, G(caml_last_return_address)(%rip)
140
movq %rax, G(caml_bottom_of_stack)(%rip)
212
RECORD_STACK_FRAME(0)
146
218
FUNCTION(G(caml_alloc2))
148
cmpq G(caml_young_limit)(%rip), %r15
221
CMP_VAR(caml_young_limit, %r15)
153
movq %rax, G(caml_last_return_address)(%rip)
155
movq %rax, G(caml_bottom_of_stack)(%rip)
225
RECORD_STACK_FRAME(0)
161
231
FUNCTION(G(caml_alloc3))
163
cmpq G(caml_young_limit)(%rip), %r15
234
CMP_VAR(caml_young_limit, %r15)
168
movq %rax, G(caml_last_return_address)(%rip)
170
movq %rax, G(caml_bottom_of_stack)(%rip)
238
RECORD_STACK_FRAME(0)
176
244
FUNCTION(G(caml_allocN))
246
pushq %rax /* save desired size */
178
cmpq G(caml_young_limit)(%rip), %r15
248
CMP_VAR(caml_young_limit, %r15)
250
addq $8, %rsp /* drop desired size */
182
pushq %rax /* save desired size */
184
movq %rax, G(caml_last_return_address)(%rip)
186
movq %rax, G(caml_bottom_of_stack)(%rip)
253
RECORD_STACK_FRAME(8)
188
255
popq %rax /* recover desired size */
191
258
/* Call a C function from Caml */
193
260
FUNCTION(G(caml_c_call))
194
262
/* Record lowest stack address and return address */
196
movq %r12, G(caml_last_return_address)(%rip)
197
movq %rsp, G(caml_bottom_of_stack)(%rip)
264
STORE_VAR(%r12, caml_last_return_address)
265
STORE_VAR(%rsp, caml_bottom_of_stack)
198
266
/* Make the exception handler and alloc ptr available to the C code */
199
movq %r15, G(caml_young_ptr)(%rip)
200
movq %r14, G(caml_exception_pointer)(%rip)
267
STORE_VAR(%r15, caml_young_ptr)
268
STORE_VAR(%r14, caml_exception_pointer)
201
269
/* Call the function (address in %rax) */
203
271
/* Reload alloc ptr */
204
movq G(caml_young_ptr)(%rip), %r15
272
LOAD_VAR(caml_young_ptr, %r15)
205
273
/* Return to caller */
219
287
subq $8, %rsp /* stack 16-aligned */
220
288
/* Initial entry point is G(caml_program) */
221
leaq G(caml_program)(%rip), %r12
289
leaq GCALL(caml_program)(%rip), %r12
222
290
/* Common code for caml_start_program and caml_callback* */
291
.Lcaml_start_program:
224
292
/* Build a callback link */
225
293
subq $8, %rsp /* stack 16-aligned */
226
pushq G(caml_gc_regs)(%rip)
227
pushq G(caml_last_return_address)(%rip)
228
pushq G(caml_bottom_of_stack)(%rip)
294
PUSH_VAR(caml_gc_regs)
295
PUSH_VAR(caml_last_return_address)
296
PUSH_VAR(caml_bottom_of_stack)
229
297
/* Setup alloc ptr and exception ptr */
230
movq G(caml_young_ptr)(%rip), %r15
231
movq G(caml_exception_pointer)(%rip), %r14
298
LOAD_VAR(caml_young_ptr, %r15)
299
LOAD_VAR(caml_exception_pointer, %r14)
232
300
/* Build an exception handler */
233
301
lea .L108(%rip), %r13
242
310
popq %r12 /* dummy register */
244
312
/* Update alloc ptr and exception ptr */
245
movq %r15, G(caml_young_ptr)(%rip)
246
movq %r14, G(caml_exception_pointer)(%rip)
313
STORE_VAR(%r15,caml_young_ptr)
314
STORE_VAR(%r14,caml_exception_pointer)
247
315
/* Pop the callback link, restoring the global variables */
248
popq G(caml_bottom_of_stack)(%rip)
249
popq G(caml_last_return_address)(%rip)
250
popq G(caml_gc_regs)(%rip)
316
POP_VAR(caml_bottom_of_stack)
317
POP_VAR(caml_last_return_address)
318
POP_VAR(caml_gc_regs)
252
320
/* Restore callee-save registers. */
288
356
/* Raise an exception from C */
290
358
FUNCTION(G(caml_raise_exception))
291
testl $1, G(caml_backtrace_active)(%rip)
359
TESTL_VAR($1, caml_backtrace_active)
294
movq G(caml_exception_pointer)(%rip), %rsp
362
LOAD_VAR(caml_exception_pointer, %rsp) /* Cut stack */
295
363
popq %r14 /* Recover previous exception handler */
296
movq G(caml_young_ptr)(%rip), %r15 /* Reload alloc ptr */
364
LOAD_VAR(caml_young_ptr, %r15) /* Reload alloc ptr */
299
367
movq %rdi, %r12 /* Save exception bucket */
300
368
/* arg 1: exception bucket */
301
movq G(caml_last_return_address)(%rip), %rsi /* arg 2: pc of raise */
302
movq G(caml_bottom_of_stack)(%rip), %rdx /* arg 3: sp of raise */
303
movq G(caml_exception_pointer)(%rip), %rcx /* arg 4: sp of handler */
304
call G(caml_stash_backtrace)
369
LOAD_VAR(caml_last_return_address,%rsi) /* arg 2: pc of raise */
370
LOAD_VAR(caml_bottom_of_stack,%rdx) /* arg 3: sp of raise */
371
LOAD_VAR(caml_exception_pointer,%rcx) /* arg 4: sp of handler */
372
call GCALL(caml_stash_backtrace)
305
373
movq %r12, %rax /* Recover exception bucket */
306
movq G(caml_exception_pointer)(%rip), %rsp
374
LOAD_VAR(caml_exception_pointer,%rsp)
307
375
popq %r14 /* Recover previous exception handler */
308
movq G(caml_young_ptr)(%rip), %r15 /* Reload alloc ptr */
376
LOAD_VAR(caml_young_ptr,%r15) /* Reload alloc ptr */
311
379
/* Callback from C to Caml */
355
423
movq %rdx, %rbx /* second argument */
356
424
movq %rdi, %rsi /* closure */
357
425
movq %rcx, %rdi /* third argument */
358
leaq G(caml_apply3)(%rip), %r12 /* code pointer */
426
leaq GCALL(caml_apply3)(%rip), %r12 /* code pointer */
427
jmp .Lcaml_start_program
361
429
FUNCTION(G(caml_ml_array_bound_error))
362
leaq G(caml_array_bound_error)(%rip), %rax
430
leaq GCALL(caml_array_bound_error)(%rip), %rax
366
434
.globl G(caml_system__frametable)