~ubuntu-branches/debian/sid/ocaml/sid

« back to all changes in this revision

Viewing changes to asmrun/amd64.S

  • Committer: Bazaar Package Importer
  • Author(s): Stéphane Glondu
  • Date: 2011-04-21 21:35:08 UTC
  • mfrom: (1.1.11 upstream) (12.1.14 sid)
  • Revision ID: james.westby@ubuntu.com-20110421213508-kg34453aqmb0moha
* Fixes related to -output-obj with g++ (in debian/patches):
  - add Declare-primitive-name-table-as-const-char
  - add Avoid-multiple-declarations-in-generated-.c-files-in
  - fix Embed-bytecode-in-C-object-when-using-custom: the closing
    brace for extern "C" { ... } was missing in some cases

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
/*                                                                     */
12
12
/***********************************************************************/
13
13
 
14
 
/* $Id: amd64.S 9119 2008-11-07 10:34:16Z xleroy $ */
 
14
/* $Id: amd64.S 10270 2010-04-19 08:47:10Z xleroy $ */
15
15
 
16
16
/* Asm part of the runtime system, AMD64 processor */
17
17
/* Must be preprocessed by cpp */
18
18
 
 
19
/* PIC mode support based on contribution by Paul Stravers (see PR#4795) */
 
20
 
19
21
#ifdef SYS_macosx
20
22
 
21
23
#define G(r) _##r
 
24
#define GREL(r) _##r@GOTPCREL
 
25
#define GCALL(r) _##r
22
26
#define FUNCTION_ALIGN 2
23
27
#define EIGHT_ALIGN 3
24
28
#define SIXTEEN_ALIGN 4
30
34
#else
31
35
 
32
36
#define G(r) r
 
37
#define GREL(r) r@GOTPCREL
 
38
#define GCALL(r) r@PLT
33
39
#define FUNCTION_ALIGN 4
34
40
#define EIGHT_ALIGN 8
35
41
#define SIXTEEN_ALIGN 16
41
47
 
42
48
#endif
43
49
 
 
50
#ifdef __PIC__
 
51
 
 
52
/* Position-independent operations on global variables. */
 
53
 
 
54
/* Store [srcreg] in global [dstlabel].  Clobbers %r11. */
 
55
#define STORE_VAR(srcreg,dstlabel) \
 
56
        movq    GREL(dstlabel)(%rip), %r11 ; \
 
57
        movq    srcreg, (%r11)
 
58
 
 
59
/* Load global [srclabel] in register [dstreg].  Clobbers %r11. */
 
60
#define LOAD_VAR(srclabel,dstreg) \
 
61
        movq    GREL(srclabel)(%rip), %r11 ; \
 
62
        movq    (%r11), dstreg
 
63
 
 
64
/* Compare global [label] with register [reg].  Clobbers %rax. */
 
65
#define CMP_VAR(label,reg) \
 
66
        movq    GREL(label)(%rip), %rax ; \
 
67
        cmpq    (%rax), reg
 
68
 
 
69
/* Test 32-bit global [label] against mask [imm].  Clobbers %r11. */
 
70
#define TESTL_VAR(imm,label) \
 
71
        movq    GREL(label)(%rip), %r11 ; \
 
72
        testl   imm, (%r11)
 
73
 
 
74
/* Push global [label] on stack.  Clobbers %r11. */
 
75
#define PUSH_VAR(srclabel) \
 
76
        movq    GREL(srclabel)(%rip), %r11 ; \
 
77
        pushq   (%r11)
 
78
 
 
79
/* Pop global [label] off stack.  Clobbers %r11. */
 
80
#define POP_VAR(dstlabel) \
 
81
        movq    GREL(dstlabel)(%rip), %r11 ; \
 
82
        popq    (%r11)
 
83
 
 
84
/* Record lowest stack address and return address.  Clobbers %rax. */
 
85
#define RECORD_STACK_FRAME(OFFSET) \
 
86
        pushq   %r11 ; \
 
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) ; \
 
91
        popq    %r11
 
92
 
 
93
#else
 
94
        
 
95
/* Non-PIC operations on global variables.  Slightly faster. */
 
96
 
 
97
#define STORE_VAR(srcreg,dstlabel) \
 
98
        movq    srcreg, G(dstlabel)(%rip)
 
99
 
 
100
#define LOAD_VAR(srclabel,dstreg) \
 
101
        movq    G(srclabel)(%rip), dstreg
 
102
 
 
103
#define CMP_VAR(label,reg) \
 
104
        cmpq    G(label)(%rip), %r15
 
105
 
 
106
#define TESTL_VAR(imm,label) \
 
107
        testl   imm, G(label)(%rip)
 
108
 
 
109
#define PUSH_VAR(srclabel) \
 
110
        pushq   G(srclabel)(%rip)
 
111
 
 
112
#define POP_VAR(dstlabel) \
 
113
        popq    G(dstlabel)(%rip)
 
114
 
 
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)
 
120
 
 
121
#endif
44
122
 
45
123
        .text
46
124
 
47
125
/* Allocation */
48
126
 
49
127
FUNCTION(G(caml_call_gc))
50
 
    /* Record lowest stack address and return address */
51
 
        movq    0(%rsp), %rax
52
 
        movq    %rax, G(caml_last_return_address)(%rip)
53
 
        leaq    8(%rsp), %rax
54
 
        movq    %rax, G(caml_bottom_of_stack)(%rip)
55
 
.L105:  
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)
 
129
.Lcaml_call_gc:
59
130
    /* Build array of registers, save it into caml_gc_regs */
60
131
        pushq   %r13
61
132
        pushq   %r12
70
141
        pushq   %rdi
71
142
        pushq   %rbx
72
143
        pushq   %rax
73
 
        movq    %rsp, G(caml_gc_regs)(%rip)
 
144
        STORE_VAR(%rsp, caml_gc_regs)
 
145
    /* Save caml_young_ptr, caml_exception_pointer */
 
146
        STORE_VAR(%r15, caml_young_ptr)
 
147
        STORE_VAR(%r14, caml_exception_pointer)
74
148
    /* Save floating-point registers */
75
149
        subq    $(16*8), %rsp
76
150
        movlpd  %xmm0, 0*8(%rsp)
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
122
199
        popq    %rbp
123
200
        popq    %r12
124
201
        popq    %r13
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 */
129
203
        ret
130
204
 
131
205
FUNCTION(G(caml_alloc1))
 
206
.Lcaml_alloc1:
132
207
        subq    $16, %r15
133
 
        cmpq    G(caml_young_limit)(%rip), %r15
 
208
        CMP_VAR(caml_young_limit, %r15)
134
209
        jb      .L100
135
210
        ret
136
211
.L100:
137
 
        movq    0(%rsp), %rax
138
 
        movq    %rax, G(caml_last_return_address)(%rip)
139
 
        leaq    8(%rsp), %rax
140
 
        movq    %rax, G(caml_bottom_of_stack)(%rip)
 
212
        RECORD_STACK_FRAME(0)
141
213
        subq    $8, %rsp
142
 
        call    .L105
 
214
        call    .Lcaml_call_gc
143
215
        addq    $8, %rsp
144
 
        jmp     G(caml_alloc1)
 
216
        jmp     .Lcaml_alloc1
145
217
 
146
218
FUNCTION(G(caml_alloc2))
 
219
.Lcaml_alloc2:
147
220
        subq    $24, %r15
148
 
        cmpq    G(caml_young_limit)(%rip), %r15
 
221
        CMP_VAR(caml_young_limit, %r15)
149
222
        jb      .L101
150
223
        ret
151
224
.L101:
152
 
        movq    0(%rsp), %rax
153
 
        movq    %rax, G(caml_last_return_address)(%rip)
154
 
        leaq    8(%rsp), %rax
155
 
        movq    %rax, G(caml_bottom_of_stack)(%rip)
 
225
        RECORD_STACK_FRAME(0)
156
226
        subq    $8, %rsp
157
 
        call    .L105
 
227
        call    .Lcaml_call_gc
158
228
        addq    $8, %rsp
159
 
        jmp     G(caml_alloc2)
 
229
        jmp     .Lcaml_alloc2
160
230
 
161
231
FUNCTION(G(caml_alloc3))
 
232
.Lcaml_alloc3:
162
233
        subq    $32, %r15
163
 
        cmpq    G(caml_young_limit)(%rip), %r15
 
234
        CMP_VAR(caml_young_limit, %r15)
164
235
        jb      .L102
165
236
        ret
166
237
.L102:
167
 
        movq    0(%rsp), %rax
168
 
        movq    %rax, G(caml_last_return_address)(%rip)
169
 
        leaq    8(%rsp), %rax
170
 
        movq    %rax, G(caml_bottom_of_stack)(%rip)
 
238
        RECORD_STACK_FRAME(0)
171
239
        subq    $8, %rsp
172
 
        call    .L105
 
240
        call    .Lcaml_call_gc
173
241
        addq    $8, %rsp
174
 
        jmp     G(caml_alloc3)
 
242
        jmp     .Lcaml_alloc3
175
243
 
176
244
FUNCTION(G(caml_allocN))
 
245
.Lcaml_allocN:
 
246
        pushq   %rax                       /* save desired size */
177
247
        subq    %rax, %r15
178
 
        cmpq    G(caml_young_limit)(%rip), %r15
 
248
        CMP_VAR(caml_young_limit, %r15)
179
249
        jb      .L103
 
250
        addq    $8, %rsp                  /* drop desired size */
180
251
        ret
181
252
.L103:
182
 
        pushq   %rax                       /* save desired size */
183
 
        movq    8(%rsp), %rax
184
 
        movq    %rax, G(caml_last_return_address)(%rip)
185
 
        leaq    16(%rsp), %rax
186
 
        movq    %rax, G(caml_bottom_of_stack)(%rip)
187
 
        call    .L105
 
253
        RECORD_STACK_FRAME(8)
 
254
        call    .Lcaml_call_gc
188
255
        popq    %rax                      /* recover desired size */
189
 
        jmp     G(caml_allocN)
 
256
        jmp     .Lcaml_allocN
190
257
 
191
258
/* Call a C function from Caml */
192
259
 
193
260
FUNCTION(G(caml_c_call))
 
261
.Lcaml_c_call:
194
262
    /* Record lowest stack address and return address */
195
263
        popq    %r12
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) */
202
270
        call    *%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 */
206
274
        pushq   %r12
207
275
        ret
218
286
        pushq   %r15
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* */
223
 
.L106:
 
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
234
302
        pushq   %r13
242
310
        popq    %r12    /* dummy register */
243
311
.L109:
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)
251
319
        addq    $8, %rsp
252
320
    /* Restore callee-save registers. */
253
321
        addq    $8, %rsp
268
336
/* Raise an exception from Caml */
269
337
 
270
338
FUNCTION(G(caml_raise_exn))
271
 
        testl   $1, G(caml_backtrace_active)(%rip)
 
339
        TESTL_VAR($1, caml_backtrace_active)
272
340
        jne     .L110
273
341
        movq    %r14, %rsp
274
342
        popq    %r14
279
347
        movq    0(%rsp), %rsi         /* arg 2: pc of raise */
280
348
        leaq    8(%rsp), %rdx         /* arg 3: sp of raise */
281
349
        movq    %r14, %rcx            /* arg 4: sp of handler */
282
 
        call    G(caml_stash_backtrace)
 
350
        call    GCALL(caml_stash_backtrace)
283
351
        movq    %r12, %rax            /* Recover exception bucket */
284
352
        movq    %r14, %rsp
285
353
        popq    %r14
288
356
/* Raise an exception from C */
289
357
 
290
358
FUNCTION(G(caml_raise_exception))
291
 
        testl   $1, G(caml_backtrace_active)(%rip)
 
359
        TESTL_VAR($1, caml_backtrace_active)
292
360
        jne     .L111
293
361
        movq    %rdi, %rax
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 */
297
365
        ret
298
366
.L111:
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 */
309
377
        ret
310
378
 
311
379
/* Callback from C to Caml */
323
391
        movq    %rdi, %rbx      /* closure */
324
392
        movq    %rsi, %rax      /* argument */
325
393
        movq    0(%rbx), %r12   /* code pointer */
326
 
        jmp     .L106
 
394
        jmp     .Lcaml_start_program
327
395
 
328
396
FUNCTION(G(caml_callback2_exn))
329
397
    /* Save callee-save registers */
338
406
        /* closure stays in %rdi */
339
407
        movq    %rsi, %rax               /* first argument */
340
408
        movq    %rdx, %rbx               /* second argument */
341
 
        leaq    G(caml_apply2)(%rip), %r12  /* code pointer */
342
 
        jmp     .L106
 
409
        leaq    GCALL(caml_apply2)(%rip), %r12  /* code pointer */
 
410
        jmp     .Lcaml_start_program
343
411
 
344
412
FUNCTION(G(caml_callback3_exn))
345
413
    /* Save callee-save registers */
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 */
359
 
        jmp     .L106
 
426
        leaq    GCALL(caml_apply3)(%rip), %r12  /* code pointer */
 
427
        jmp     .Lcaml_start_program
360
428
 
361
429
FUNCTION(G(caml_ml_array_bound_error))
362
 
        leaq    G(caml_array_bound_error)(%rip), %rax
363
 
        jmp     G(caml_c_call)
 
430
        leaq    GCALL(caml_array_bound_error)(%rip), %rax
 
431
        jmp     .Lcaml_c_call
364
432
 
365
433
        .data
366
434
        .globl  G(caml_system__frametable)