diff options
author | Xavier Leroy <xavier.leroy@inria.fr> | 1997-11-27 16:28:40 +0000 |
---|---|---|
committer | Xavier Leroy <xavier.leroy@inria.fr> | 1997-11-27 16:28:40 +0000 |
commit | 5866ccca18af727157d3a31514152c869ae3355b (patch) | |
tree | a06539095f3d3c85a78fbf2e0af1fc76482bf5c4 /asmrun | |
parent | 4b87c642792cee1997f6b0694ca069d6bb3f713c (diff) | |
download | ocaml-5866ccca18af727157d3a31514152c869ae3355b.tar.gz |
Revision de l'interface avec le GC, suite
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@1812 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
Diffstat (limited to 'asmrun')
-rw-r--r-- | asmrun/alpha.S | 55 | ||||
-rw-r--r-- | asmrun/hppa.S | 56 | ||||
-rw-r--r-- | asmrun/i386.S | 128 | ||||
-rw-r--r-- | asmrun/i386nt.asm | 37 | ||||
-rw-r--r-- | asmrun/mips.S | 262 | ||||
-rw-r--r-- | asmrun/power-aix.S | 89 | ||||
-rw-r--r-- | asmrun/power-elf.S | 231 | ||||
-rw-r--r-- | asmrun/roots.c | 38 | ||||
-rw-r--r-- | asmrun/sparc.S | 68 | ||||
-rw-r--r-- | asmrun/stack.h | 42 |
10 files changed, 503 insertions, 503 deletions
diff --git a/asmrun/alpha.S b/asmrun/alpha.S index ba6da04028..33d2e15dda 100644 --- a/asmrun/alpha.S +++ b/asmrun/alpha.S @@ -83,16 +83,19 @@ caml_call_gc: .prologue 0 ldiq $25, 0 $110: lda $sp, -0x200($sp) - /* 0x200 = 8 (retaddr) + 31*8 (ints) + 32*8 (floats) */ + /* 0x200 = 32*8 (ints) + 32*8 (floats) */ stq $26, 0x1F8($sp) /* return address */ stq $gp, 0x1F0($sp) /* caller's $gp */ stq $25, 0x1E8($sp) /* desired size */ /* Rebuild $gp */ br $27, $103 $103: ldgp $gp, 0($27) - /* Record last context */ + /* Record lowest stack address, return address, GC regs */ + stq $26, caml_last_return_address + lda $24, 0x200($sp) + stq $24, caml_bottom_of_stack lda $24, 0x100($sp) - stq $24, caml_last_context + stq $24, caml_gc_regs /* Save current allocation pointer for debugging purposes */ stq $13, young_ptr /* Save trap pointer in case an exception is raised (e.g. sighandler) */ @@ -195,7 +198,7 @@ $103: ldgp $gp, 0($27) ldq $25, 0x1E8($sp) subq $13, $25, $13 /* Say that we are back into Caml code */ - stq $31, caml_last_context + stq $31, caml_last_return_address /* Return to caller */ ldq $26, 0x1F8($sp) ldq $gp, 0x1F0($sp) @@ -218,13 +221,10 @@ caml_c_call: /* Rebuild $gp */ br $25, $104 $104: ldgp $gp, 0($25) - /* Record last context. We don't fill the register section since - no registers are live across caml_c_call. */ - lda $sp, -16($sp) - stq $26, 8($sp) - lda $25, (8 - 31*8)($sp) - lda $11, caml_last_context - stq $25, 0($11) + /* Record lowest stack address and return address */ + lda $11, caml_last_return_address + stq $26, 0($11) + stq $sp, caml_bottom_of_stack /* Make the exception handler and alloc ptr available to the C code */ lda $12, young_ptr stq $13, 0($12) @@ -236,11 +236,10 @@ $104: ldgp $gp, 0($25) ldq $13, 0($12) /* $12 still points to young_ptr */ ldq $14, 0($14) /* $14 still points to young_limit */ /* Say that we are back into Caml code */ - stq $31, 0($11) /* $11 still points to caml_last_context */ + stq $31, 0($11) /* $11 still points to caml_last_return_address */ /* Restore $gp */ mov $10, $gp /* Return */ - lda $sp, 16($sp) ret ($9) .end caml_c_call @@ -276,9 +275,13 @@ $107: stt $f8, 112($sp) stt $f9, 120($sp) /* Set up a callback link on the stack. */ - lda $sp, -16($sp) - ldq $0, caml_last_context + lda $sp, -32($sp) + ldq $0, caml_bottom_of_stack stq $0, 0($sp) + ldq $1, caml_last_return_address + stq $1, 8($sp) + ldq $1, caml_gc_regs + stq $1, 16($sp) /* Set up a trap frame to catch exceptions escaping the Caml code */ lda $sp, -16($sp) ldq $15, caml_exception_pointer @@ -301,10 +304,14 @@ $108: jsr ($25) ldq $15, 0($sp) stq $15, caml_exception_pointer lda $sp, 16($sp) - /* Restore caml_last_context */ + /* Pop the callback link, restoring the global variables */ ldq $24, 0($sp) - stq $24, caml_last_context - lda $sp, 16($sp) + stq $24, caml_bottom_of_stack + ldq $25, 8($sp) + stq $25, caml_last_return_address + ldq $24, 16($sp) + stq $24, caml_gc_regs + lda $sp, 32($sp) /* Update allocation pointer */ stq $13, young_ptr /* Reload callee-save registers */ @@ -330,10 +337,14 @@ $108: jsr ($25) /* The trap handler */ $109: ldgp $gp, 0($26) - /* Restore caml_last_context */ + /* Restore the global variables used by caml_c_call */ ldq $24, 0($sp) - stq $24, caml_last_context - lda $sp, 16($sp) + stq $24, caml_bottom_of_stack + ldq $25, 8($sp) + stq $25, caml_last_return_address + ldq $25, 16($sp) + stq $25, caml_gc_regs + lda $sp, 32($sp) /* Re-raise the exception through mlraise, so that local C roots are cleaned up correctly. */ stq $13, young_ptr @@ -353,7 +364,7 @@ raise_caml_exception: mov $16, $0 /* Move exn bucket */ ldq $13, young_ptr ldq $14, young_limit - stq $31, caml_last_context /* We're back into Caml */ + stq $31, caml_last_return_address /* We're back into Caml */ ldq $sp, caml_exception_pointer ldq $15, 0($sp) ldq $26, 8($sp) diff --git a/asmrun/hppa.S b/asmrun/hppa.S index ef1b5eece1..904c7b3f13 100644 --- a/asmrun/hppa.S +++ b/asmrun/hppa.S @@ -59,10 +59,9 @@ young_limit .comm 8 young_ptr .comm 8 -gc_entry_regs .comm 32 * 4 -gc_entry_float_regs .comm 32 * 8 caml_bottom_of_stack .comm 8 caml_last_return_address .comm 8 +caml_gc_regs .comm 8 caml_exception_pointer .comm 8 caml_required_size .comm 8 #endif @@ -70,10 +69,9 @@ caml_required_size .comm 8 #ifdef SYS_nextstep .comm G(young_limit), 8 .comm G(young_ptr), 8 - .comm G(gc_entry_regs), 32 * 4 - .comm G(gc_entry_float_regs), 32 * 8 .comm G(caml_bottom_of_stack), 8 .comm G(caml_last_return_address), 8 + .comm G(caml_gc_regs), 8 .comm G(caml_exception_pointer), 8 .comm G(caml_required_size), 8 #endif @@ -111,9 +109,15 @@ G(caml_call_gc): ; Save the exception handler (if e.g. a sighandler raises) LOADHIGH(G(caml_exception_pointer)) stw %r5, LOW(G(caml_exception_pointer))(%r1) +; Reserve stack space +; 0x1C0 = 4 * 32 (int regs) + 8 * 32 (float regs) + 64 (for calling C) + ldo 0x1C0(%r30), %r30 +; Save caml_gc_regs + ldo -(64 + 8*32)(%r30), %r31 + LOADHIGH(G(caml_gc_regs)) + stw %r31, LOW(G(caml_gc_regs))(%r1) ; Save all regs used by the code generator - LOADHIGH(G(gc_entry_regs)) - ldo LOW(G(gc_entry_regs))(%r1), %r1 + copy %r31, %r1 stws,ma %r6, 4(%r1) stws,ma %r7, 4(%r1) stws,ma %r8, 4(%r1) @@ -136,9 +140,7 @@ G(caml_call_gc): stws,ma %r25, 4(%r1) stws,ma %r26, 4(%r1) stws,ma %r28, 4(%r1) -;; stws,ma %r29, 4(%r1) %r29 is clobbered - LOADHIGH(G(gc_entry_float_regs)) - ldo LOW(G(gc_entry_float_regs))(%r1), %r1 + ldo -0x1C0(%r30), %r1 fstds,ma %fr4, 8(%r1) fstds,ma %fr5, 8(%r1) fstds,ma %fr6, 8(%r1) @@ -168,7 +170,6 @@ G(caml_call_gc): fstds,ma %fr30, 8(%r1) ; Call the garbage collector - ldo 64(%r30), %r30 #ifdef SYS_nextstep ldil L`G(garbage_collection), %r1 ble R`G(garbage_collection)(4, %r1) @@ -177,11 +178,9 @@ G(caml_call_gc): bl G(garbage_collection), %r2 nop #endif - ldo -64(%r30), %r30 ; Restore all regs used by the code generator - LOADHIGH(G(gc_entry_regs)) - ldo LOW(G(gc_entry_regs))(%r1), %r1 + ldo -(64 + 8*32)(%r30), %r1 ldws,ma 4(%r1), %r6 ldws,ma 4(%r1), %r7 ldws,ma 4(%r1), %r8 @@ -204,9 +203,7 @@ G(caml_call_gc): ldws,ma 4(%r1), %r25 ldws,ma 4(%r1), %r26 ldws,ma 4(%r1), %r28 -;; ldws,ma 4(%r1), %r29 %r29 is clobbered - LOADHIGH(G(gc_entry_float_regs)) - ldo LOW(G(gc_entry_float_regs))(%r1), %r1 + ldo -0x1C0(%r30), %r1 fldds,ma 8(%r1), %fr4 fldds,ma 8(%r1), %fr5 fldds,ma 8(%r1), %fr6 @@ -342,13 +339,16 @@ L102: fstds,ma %fr30, -8(%r1) fstds,ma %fr31, -8(%r1) ; Set up a callback link - ldo 8(%r30), %r30 + ldo 16(%r30), %r30 LOADHIGH(G(caml_bottom_of_stack)) ldw LOW(G(caml_bottom_of_stack))(%r1), %r1 - stw %r1, -8(%r30) + stw %r1, -16(%r30) LOADHIGH(G(caml_last_return_address)) ldw LOW(G(caml_last_return_address))(%r1), %r1 - stw %r1, -4(%r30) + stw %r1, -12(%r30) + LOADHIGH(G(caml_gc_regs)) + ldw LOW(G(caml_gc_regs))(%r1), %r1 + stw %r1, -8(%r30) ; Set up a trap frame to catch exceptions escaping the Caml code ldo 8(%r30), %r30 LOADHIGH(G(caml_exception_pointer)) @@ -373,13 +373,16 @@ L104: stw %r31, LOW(G(caml_exception_pointer))(%r1) ldo -8(%r30), %r30 ; Pop the callback link - ldw -8(%r30), %r31 + ldw -16(%r30), %r31 LOADHIGH(G(caml_bottom_of_stack)) stw %r31, LOW(G(caml_bottom_of_stack))(%r1) - ldw -4(%r30), %r31 + ldw -12(%r30), %r31 LOADHIGH(G(caml_last_return_address)) stw %r31, LOW(G(caml_last_return_address))(%r1) - ldo -8(%r30), %r30 + ldw -8(%r30), %r31 + LOADHIGH(G(caml_gc_regs)) + stw %r31, LOW(G(caml_gc_regs))(%r1) + ldo -16(%r30), %r30 ; Save allocation pointer LOADHIGH(G(young_ptr)) stw %r3, LOW(G(young_ptr))(%r1) @@ -431,13 +434,16 @@ L104: ; The trap handler L103: ; Pop the callback link - ldw -8(%r30), %r31 + ldw -16(%r30), %r31 LOADHIGH(G(caml_bottom_of_stack)) stw %r31, LOW(G(caml_bottom_of_stack))(%r1) - ldw -4(%r30), %r31 + ldw -12(%r30), %r31 LOADHIGH(G(caml_last_return_address)) stw %r31, LOW(G(caml_last_return_address))(%r1) - ldo -8(%r30), %r30 + ldw -8(%r30), %r31 + LOADHIGH(G(caml_gc_regs)) + stw %r31, LOW(G(caml_gc_regs))(%r1) + ldo -16(%r30), %r30 ; Save allocation pointer and exception pointer LOADHIGH(G(young_ptr)) stw %r3, LOW(G(young_ptr))(%r1) diff --git a/asmrun/i386.S b/asmrun/i386.S index 7486e7876e..06c56aed8a 100644 --- a/asmrun/i386.S +++ b/asmrun/i386.S @@ -14,7 +14,7 @@ /* Asm part of the runtime system, Intel 386 processor */ /* Must be preprocessed by cpp */ -/* Linux with ELF binaries does not prefix identifiers with _. +/* Linux with ELF binaries and Solaris do not prefix identifiers with _. Linux with a.out binaries, FreeBSD, and NextStep do. */ #if defined(SYS_linux_elf) || defined(SYS_solaris) @@ -35,16 +35,20 @@ .globl G(caml_alloc) G(caml_call_gc): - /* Build caml_context structure on stack - and save it into caml_last_context. */ - pushl %ebp + /* Record lowest stack address and return address */ + movl 0(%esp), %eax + movl %eax, G(caml_last_return_address) + leal 4(%esp), %eax + movl %eax, G(caml_bottom_of_stack) + /* Build array of registers, save it into caml_gc_regs */ +L105: pushl %ebp pushl %edi pushl %esi pushl %edx pushl %ecx pushl %ebx pushl %eax - movl %esp, G(caml_last_context) + movl %esp, G(caml_gc_regs) /* Call the garbage collector */ call G(garbage_collection) /* Restore all regs used by the code generator */ @@ -66,22 +70,11 @@ G(caml_alloc1): cmpl G(young_limit), %eax jb L100 ret -L100: pushl %ebp - pushl %edi - pushl %esi - pushl %edx - pushl %ecx - pushl %ebx - pushl %eax - movl %esp, G(caml_last_context) - call G(garbage_collection) - popl %eax - popl %ebx - popl %ecx - popl %edx - popl %esi - popl %edi - popl %ebp +L100: movl 0(%esp), %eax + movl %eax, G(caml_last_return_address) + leal 4(%esp), %eax + movl %eax, G(caml_bottom_of_stack) + call L105 jmp G(caml_alloc1) .align FUNCTION_ALIGN @@ -92,22 +85,11 @@ G(caml_alloc2): cmpl G(young_limit), %eax jb L101 ret -L101: pushl %ebp - pushl %edi - pushl %esi - pushl %edx - pushl %ecx - pushl %ebx - pushl %eax - movl %esp, G(caml_last_context) - call G(garbage_collection) - popl %eax - popl %ebx - popl %ecx - popl %edx - popl %esi - popl %edi - popl %ebp +L101: movl 0(%esp), %eax + movl %eax, G(caml_last_return_address) + leal 4(%esp), %eax + movl %eax, G(caml_bottom_of_stack) + call L105 jmp G(caml_alloc2) .align FUNCTION_ALIGN @@ -118,22 +100,11 @@ G(caml_alloc3): cmpl G(young_limit), %eax jb L102 ret -L102: pushl %ebp - pushl %edi - pushl %esi - pushl %edx - pushl %ecx - pushl %ebx - pushl %eax - movl %esp, G(caml_last_context) - call G(garbage_collection) - popl %eax - popl %ebx - popl %ecx - popl %edx - popl %esi - popl %edi - popl %ebp +L102: movl 0(%esp), %eax + movl %eax, G(caml_last_return_address) + leal 4(%esp), %eax + movl %eax, G(caml_bottom_of_stack) + call L105 jmp G(caml_alloc3) .align FUNCTION_ALIGN @@ -146,22 +117,14 @@ G(caml_alloc): ret L103: subl G(young_ptr), %eax /* eax = - size */ negl %eax /* eax = size */ - pushl %ebp - pushl %edi - pushl %esi - pushl %edx - pushl %ecx - pushl %ebx - pushl %eax - movl %esp, G(caml_last_context) - call G(garbage_collection) - popl %eax - popl %ebx - popl %ecx - popl %edx - popl %esi - popl %edi - popl %ebp + pushl %eax /* save desired size */ + subl %eax, G(young_ptr) /* must update young_ptr */ + movl 4(%esp), %eax + movl %eax, G(caml_last_return_address) + leal 8(%esp), %eax + movl %eax, G(caml_bottom_of_stack) + call L105 + popl %eax /* recover desired size */ jmp G(caml_alloc) /* Call a C function from Caml */ @@ -169,12 +132,11 @@ L103: subl G(young_ptr), %eax /* eax = - size */ .globl G(caml_c_call) .align FUNCTION_ALIGN G(caml_c_call): - /* Build caml_context structure on stack - and save it into caml_last_context. - We don't fill the gc_regs section, because no registers - are live across caml_c_call. */ - lea -28(%esp), %edx - movl %edx, G(caml_last_context) + /* Record lowest stack address and return address */ + movl (%esp), %edx + movl %edx, G(caml_last_return_address) + leal 4(%esp), %edx + movl %edx, G(caml_bottom_of_stack) /* Call the function (address in %eax) */ jmp *%eax @@ -193,7 +155,9 @@ G(caml_start_program): /* Common code for caml_start_program and callback* */ L106: /* Build a callback link */ - pushl G(caml_last_context) + pushl G(caml_gc_regs) + pushl G(caml_last_return_address) + pushl G(caml_bottom_of_stack) /* Build an exception handler */ pushl $L108 pushl G(caml_exception_pointer) @@ -204,8 +168,10 @@ L107: /* Pop the exception handler */ popl G(caml_exception_pointer) popl %esi /* dummy register */ - /* Pop the callback link, restoring caml_last_context */ - popl G(caml_last_context) + /* Pop the callback link, restoring the global variables */ + popl G(caml_bottom_of_stack) + popl G(caml_last_return_address) + popl G(caml_gc_regs) /* Restore callee-save registers. */ popl %ebp popl %edi @@ -215,8 +181,10 @@ L107: ret L108: /* Exception handler*/ - /* Pop the callback link, restoring caml_last_context */ - popl G(caml_last_context) + /* Pop the callback link, restoring the global variables */ + popl G(caml_bottom_of_stack) + popl G(caml_last_return_address) + popl G(caml_gc_regs) /* Re-raise the exception through mlraise, so that local C roots are cleaned up correctly. */ pushl %eax /* exn bucket is the argument */ diff --git a/asmrun/i386nt.asm b/asmrun/i386nt.asm index 4327540689..c08762e11e 100644 --- a/asmrun/i386nt.asm +++ b/asmrun/i386nt.asm @@ -25,17 +25,12 @@ EXTERN _young_ptr: DWORD EXTERN _caml_bottom_of_stack: DWORD EXTERN _caml_last_return_address: DWORD + EXTERN _caml_gc_regs: DWORD EXTERN _caml_exception_pointer: DWORD PUBLIC _gc_entry_regs PUBLIC _gc_entry_float_regs - .DATA - ALIGN 4 - -_gc_entry_regs DWORD 32 DUP(?) -_gc_entry_float_regs QWORD 32 DUP(?) - ; Allocation .CODE @@ -52,21 +47,24 @@ _caml_call_gc: lea eax, [esp+4] mov _caml_bottom_of_stack, eax ; Save all regs used by the code generator -L105: mov _gc_entry_regs + 4, ebx - mov _gc_entry_regs + 8, ecx - mov _gc_entry_regs + 12, edx - mov _gc_entry_regs + 16, esi - mov _gc_entry_regs + 20, edi - mov _gc_entry_regs + 24, ebp +L105: push ebp + push edi + push esi + push edx + push ecx + push ebx + push eax + mov _caml_gc_regs, esp ; Call the garbage collector call _garbage_collection ; Restore all regs used by the code generator - mov ebx, _gc_entry_regs + 4 - mov ecx, _gc_entry_regs + 8 - mov edx, _gc_entry_regs + 12 - mov esi, _gc_entry_regs + 16 - mov edi, _gc_entry_regs + 20 - mov ebp, _gc_entry_regs + 24 + pop eax + pop ebx + pop ecx + pop edx + pop esi + pop edi + pop ebp ; Return to caller ret @@ -167,6 +165,7 @@ L106: ; Build a callback link push _caml_last_return_address push _caml_bottom_of_stack + push _caml_gc_regs ; Build an exception handler push L108 push _caml_exception_pointer @@ -179,6 +178,7 @@ L107: pop esi ; dummy register ; Pop the callback link, restoring the global variables ; used by caml_c_call + pop _caml_gc_regs pop _caml_bottom_of_stack pop _caml_last_return_address ; Restore callee-save registers. @@ -192,6 +192,7 @@ L108: ; Exception handler ; Pop the callback link, restoring the global variables ; used by caml_c_call + pop _caml_gc_regs pop _caml_bottom_of_stack pop _caml_last_return_address ; Re-raise the exception through mlraise, diff --git a/asmrun/mips.S b/asmrun/mips.S index 8f311a76c9..21ad40dd59 100644 --- a/asmrun/mips.S +++ b/asmrun/mips.S @@ -13,51 +13,6 @@ /* Asm part of the runtime system, Mips processor */ - .comm gc_entry_regs, 4 * 32 - .comm gc_entry_float_regs, 8 * 32 - -/* Save all callee-save registers in the stack frame */ -#define SAVE_CALLEE_SAVE_REGS \ - sw $16, 0($sp); \ - sw $17, 4($sp); \ - sw $18, 8($sp); \ - sw $19, 12($sp); \ - sw $20, 16($sp); \ - sw $21, 20($sp); \ - sw $22, 24($sp); \ - sw $23, 28($sp); \ - sw $30, 32($sp); \ - s.d $f20, 40($sp); \ - s.d $f22, 48($sp); \ - s.d $f24, 56($sp); \ - s.d $f26, 64($sp); \ - s.d $f28, 72($sp); \ - s.d $f30, 80($sp) - -#define RELOAD_CALLEE_SAVE_REGS \ - lw $16, 0($sp); \ - lw $17, 4($sp); \ - lw $18, 8($sp); \ - lw $19, 12($sp); \ - lw $20, 16($sp); \ - lw $21, 20($sp); \ - lw $22, 24($sp); \ - lw $23, 28($sp); \ - lw $30, 32($sp); \ - l.d $f20, 40($sp); \ - l.d $f22, 48($sp); \ - l.d $f24, 56($sp); \ - l.d $f26, 64($sp); \ - l.d $f28, 72($sp); \ - l.d $f30, 80($sp) - -/* Save and reload registers from gc_entry_regs and gc_entry_float_regs */ - -#define SAVE(r) sw $/**/r, gc_entry_regs + r * 4 -#define LOAD(r) lw $/**/r, gc_entry_regs + r * 4 -#define FSAVE(r) s.d $f/**/r, gc_entry_float_regs + r * 4 -#define FLOAD(r) l.d $f/**/r, gc_entry_float_regs + r * 4 - /* Allocation */ .text @@ -117,110 +72,113 @@ caml_alloc: caml_call_gc_internal: /* Record return address */ sw $31, caml_last_return_address - #endif $110: /* Record lowest stack address */ sw $sp, caml_bottom_of_stack - /* Save actual return address, $gp, requested size. - Also reserve some stack space for the call. */ - subu $sp, $sp, 32 - sw $31, 28($sp) + /* Reserve stack space for the registers and the call to C */ + subu $sp, $sp, 0x110 + /* 0x110 = 32*4 (int regs) + 32*4 (float regs) + 16 (call) */ + /* Save actual retaddr, $gp, requested size. */ + sw $31, 0x10C($sp) + sw $24, 0x108($sp) #ifdef _PIC - .cprestore 24 + .cprestore 0x104 #endif - sw $24, 16($sp) + /* Save pointer to register array */ + addu $24, $sp, 0x90 + sw $24, caml_gc_regs /* Save current allocation pointer for debugging purposes */ sw $22, young_ptr /* Save the exception handler (if e.g. a sighandler raises) */ sw $30, caml_exception_pointer - /* Save all regs used by the code generator in the arrays - /* gc_entry_regs and gc_entry_float_regs. */ - SAVE(2) - SAVE(3) - SAVE(4) - SAVE(5) - SAVE(6) - SAVE(7) - SAVE(8) - SAVE(9) - SAVE(10) - SAVE(11) - SAVE(12) - SAVE(13) - SAVE(14) - SAVE(15) - SAVE(16) - SAVE(17) - SAVE(18) - SAVE(19) - SAVE(20) - SAVE(21) - FSAVE(0) - FSAVE(2) - FSAVE(4) - FSAVE(6) - FSAVE(8) - FSAVE(12) - FSAVE(14) - FSAVE(16) - FSAVE(18) - FSAVE(20) - FSAVE(22) - FSAVE(24) - FSAVE(26) - FSAVE(28) - FSAVE(30) + /* Save all regs used by the code generator on the stack */ + sw $2, 2 * 4($24) + sw $3, 3 * 4($24) + sw $4, 4 * 4($24) + sw $5, 5 * 4($24) + sw $6, 6 * 4($24) + sw $7, 7 * 4($24) + sw $8, 8 * 4($24) + sw $9, 9 * 4($24) + sw $10, 10 * 4($24) + sw $11, 11 * 4($24) + sw $12, 12 * 4($24) + sw $13, 13 * 4($24) + sw $14, 14 * 4($24) + sw $15, 15 * 4($24) + sw $16, 16 * 4($24) + sw $17, 17 * 4($24) + sw $18, 18 * 4($24) + sw $19, 19 * 4($24) + sw $20, 20 * 4($24) + sw $21, 21 * 4($24) + s.d $f0, 16 + 0 * 4($sp) + s.d $f2, 16 + 2 * 4($sp) + s.d $f4, 16 + 4 * 4($sp) + s.d $f6, 16 + 6 * 4($sp) + s.d $f8, 16 + 8 * 4($sp) + s.d $f12, 16 + 12 * 4($sp) + s.d $f14, 16 + 14 * 4($sp) + s.d $f16, 16 + 16 * 4($sp) + s.d $f18, 16 + 18 * 4($sp) + s.d $f20, 16 + 20 * 4($sp) + s.d $f22, 16 + 22 * 4($sp) + s.d $f24, 16 + 24 * 4($sp) + s.d $f26, 16 + 26 * 4($sp) + s.d $f28, 16 + 28 * 4($sp) + s.d $f30, 16 + 30 * 4($sp) /* Call the garbage collector */ jal garbage_collection /* Restore all regs used by the code generator */ - LOAD(2) - LOAD(3) - LOAD(4) - LOAD(5) - LOAD(6) - LOAD(7) - LOAD(8) - LOAD(9) - LOAD(10) - LOAD(11) - LOAD(12) - LOAD(13) - LOAD(14) - LOAD(15) - LOAD(16) - LOAD(17) - LOAD(18) - LOAD(19) - LOAD(20) - LOAD(21) - FLOAD(0) - FLOAD(2) - FLOAD(4) - FLOAD(6) - FLOAD(8) - FLOAD(12) - FLOAD(14) - FLOAD(16) - FLOAD(18) - FLOAD(20) - FLOAD(22) - FLOAD(24) - FLOAD(26) - FLOAD(28) - FLOAD(30) + addu $24, $sp, 0x90 + lw $2, 2 * 4($24) + lw $3, 3 * 4($24) + lw $4, 4 * 4($24) + lw $5, 5 * 4($24) + lw $6, 6 * 4($24) + lw $7, 7 * 4($24) + lw $8, 8 * 4($24) + lw $9, 9 * 4($24) + lw $10, 10 * 4($24) + lw $11, 11 * 4($24) + lw $12, 12 * 4($24) + lw $13, 13 * 4($24) + lw $14, 14 * 4($24) + lw $15, 15 * 4($24) + lw $16, 16 * 4($24) + lw $17, 17 * 4($24) + lw $18, 18 * 4($24) + lw $19, 19 * 4($24) + lw $20, 20 * 4($24) + lw $21, 21 * 4($24) + l.d $f0, 16 + 0 * 4($sp) + l.d $f2, 16 + 2 * 4($sp) + l.d $f4, 16 + 4 * 4($sp) + l.d $f6, 16 + 6 * 4($sp) + l.d $f8, 16 + 8 * 4($sp) + l.d $f12, 16 + 12 * 4($sp) + l.d $f14, 16 + 14 * 4($sp) + l.d $f16, 16 + 16 * 4($sp) + l.d $f18, 16 + 18 * 4($sp) + l.d $f20, 16 + 20 * 4($sp) + l.d $f22, 16 + 22 * 4($sp) + l.d $f24, 16 + 24 * 4($sp) + l.d $f26, 16 + 26 * 4($sp) + l.d $f28, 16 + 28 * 4($sp) + l.d $f30, 16 + 30 * 4($sp) /* Reload new allocation pointer and allocation limit */ lw $22, young_ptr lw $23, young_limit /* Allocate space for the block */ - lw $24, 16($sp) + lw $24, 0x108($sp) subu $22, $22, $24 /* Say that we are back into Caml code */ - sw $0, caml_last_return_address + sw $0, caml_last_context /* Return to caller */ - lw $31, 28($sp) - addu $sp, $sp, 32 + lw $31, 0x10C($sp) + addu $sp, $sp, 0x110 j $31 .end caml_call_gc @@ -292,13 +250,29 @@ $103: subu $sp, $sp, 96 sw $31, 88($sp) /* Save all callee-save registers */ - SAVE_CALLEE_SAVE_REGS + sw $16, 0($sp) + sw $17, 4($sp) + sw $18, 8($sp) + sw $19, 12($sp) + sw $20, 16($sp) + sw $21, 20($sp) + sw $22, 24($sp) + sw $23, 28($sp) + sw $30, 32($sp) + s.d $f20, 40($sp) + s.d $f22, 48($sp) + s.d $f24, 56($sp) + s.d $f26, 64($sp) + s.d $f28, 72($sp) + s.d $f30, 80($sp) /* Set up a callback link on the stack. */ - subu $sp, $sp, 8 + subu $sp, $sp, 16 lw $2, caml_bottom_of_stack sw $2, 0($sp) lw $3, caml_last_return_address sw $3, 4($sp) + lw $4, caml_gc_regs + sw $4, 8($sp) /* Set up a trap frame to catch exceptions escaping the Caml code */ subu $sp, $sp, 8 lw $30, caml_exception_pointer @@ -310,7 +284,7 @@ $103: lw $22, young_ptr lw $23, young_limit /* Say that we are back into Caml code */ - sw $0, caml_last_return_address + sw $0, caml_last_context /* Call the Caml code */ #ifdef _PIC move $25, $24 @@ -326,18 +300,33 @@ $104: jal $24 lw $24, 0($sp) sw $24, caml_exception_pointer addu $sp, $sp, 8 - /* Pop the callback link, - restoring the global variables used by caml_c_call */ + /* Pop the callback link, restoring the global variables */ lw $24, 0($sp) sw $24, caml_bottom_of_stack lw $25, 4($sp) sw $25, caml_last_return_address - addu $sp, $sp, 8 + lw $24, 8($sp) + sw $24, caml_gc_regs + addu $sp, $sp, 16 /* Update allocation pointer */ sw $22, young_ptr /* Reload callee-save registers and return */ lw $31, 88($sp) - RELOAD_CALLEE_SAVE_REGS + lw $16, 0($sp) + lw $17, 4($sp) + lw $18, 8($sp) + lw $19, 12($sp) + lw $20, 16($sp) + lw $21, 20($sp) + lw $22, 24($sp) + lw $23, 28($sp) + lw $30, 32($sp) + l.d $f20, 40($sp) + l.d $f22, 48($sp) + l.d $f24, 56($sp) + l.d $f26, 64($sp) + l.d $f28, 72($sp) + l.d $f30, 80($sp) addu $sp, $sp, 96 j $31 @@ -356,6 +345,9 @@ $105: sw $24, caml_bottom_of_stack lw $25, 4($sp) sw $25, caml_last_return_address + lw $24, 8($sp) + sw $24, caml_gc_regs + addu $sp, $sp, 16 move $4, $2 /* bucket as first argument */ jal mlraise /* never returns */ diff --git a/asmrun/power-aix.S b/asmrun/power-aix.S index 546efdaae0..afb5e3a203 100644 --- a/asmrun/power-aix.S +++ b/asmrun/power-aix.S @@ -11,26 +11,28 @@ # $Id$ - .comm gc_entry_regs, 4*32 - .comm gc_entry_float_regs, 8*32 - .csect .text[PR] #### Invoke the garbage collector. r0 contains the return address .globl .caml_call_gc .caml_call_gc: - # Set up stack frame for calling the garbage collector - stwu 1, -64(1) + # Set up stack frame + stwu 1, -0x1C0(1) + # 0x1A0 = 4*32 (int regs) + 8*32 (float regs) + 64 (space for C call) # Record last return address into Caml code lwz 11, L..caml_last_return_address(2) stw 0, 0(11) # Record return address into call_gc stub code mflr 0 - stw 0, 72(1) + stw 0, 0x1C0+8(1) # Record lowest stack address lwz 11, L..caml_bottom_of_stack(2) - addic 0, 1, 64 + addic 0, 1, 0x1C0 + stw 0, 0(11) + # Record pointer to register array + lwz 11, L..caml_gc_regs(2) + addic 0, 1, 8*32 + 64 stw 0, 0(11) # Save current allocation pointer for debugging purposes lwz 11, L..young_ptr(2) @@ -39,8 +41,7 @@ lwz 11, L..caml_exception_pointer(2) stw 29, 0(11) # Save all registers used by the code generator - lwz 11, L..gc_entry_regs(2) - addic 11, 11, -4 + addic 11, 1, 8*32 + 64 - 4 stwu 3, 4(11) stwu 4, 4(11) stwu 5, 4(11) @@ -64,8 +65,7 @@ stwu 26, 4(11) stwu 27, 4(11) stwu 28, 4(11) - lwz 11, L..gc_entry_float_regs(2) - addic 11, 11, -8 + addic 11, 11, 64 - 8 stfdu 1, 8(11) stfdu 2, 8(11) stfdu 3, 8(11) @@ -106,8 +106,7 @@ lwz 11, L..young_limit(2) lwz 30, 0(11) # Restore all regs used by the code generator - lwz 11, L..gc_entry_regs(2) - addic 11, 11, -4 + addic 11, 1, 8*32 + 64 - 4 lwzu 3, 4(11) lwzu 4, 4(11) lwzu 5, 4(11) @@ -131,8 +130,7 @@ lwzu 26, 4(11) lwzu 27, 4(11) lwzu 28, 4(11) - lwz 11, L..gc_entry_float_regs(2) - addic 11, 11, -8 + addic 11, 11, 64 - 8 lfdu 1, 8(11) lfdu 2, 8(11) lfdu 3, 8(11) @@ -166,14 +164,17 @@ lfdu 31, 8(11) # Return to caller (the stub code), leaving return address into # Caml code in the link register - lwz 0, 72(1) + lwz 0, 0x1C0+8(1) mtctr 0 lwz 11, L..caml_last_return_address(2) lwz 0, 0(11) addic 0, 0, -16 # Restart the allocation (4 instructions) mtlr 0 + # Say we are back into Caml code + li 12, 0 + stw 12, 0(11) # 11 still points to caml_last_return_address # Deallocate stack frame - addi 1, 1, 64 + addi 1, 1, 0x1C0 # Return bctr @@ -181,12 +182,13 @@ .globl .caml_c_call .caml_c_call: + # Save return address in 25 mflr 25 # Record lowest stack address and return address lwz 27, L..caml_bottom_of_stack(2) - lwz 26, L..caml_last_return_address(2) + lwz 24, L..caml_last_return_address(2) stw 1, 0(27) - stw 25, 0(26) + stw 25, 0(24) # Make the exception handler and alloc ptr available to the C code lwz 27, L..young_ptr(2) lwz 26, L..caml_exception_pointer(2) @@ -195,7 +197,8 @@ # Preserve RTOC and return address in callee-save registers # The C function will preserve them, and the Caml code does not # expect them to be preserved - # Return address is in 25, RTOC is in 26, pointer to young_ptr in 27 + # Return address is in 25, RTOC is in 26, pointer to young_ptr in 27, + # pointer to caml_last_return_address is in 24 # Call the function (descriptor in 11) lwz 0, 0(11) mr 26, 2 @@ -208,7 +211,10 @@ # Restore RTOC mr 2, 26 # Reload allocation pointer - lwz 31, 0(27) # 27 still points to young_ptr + lwz 31, 0(27) # 27 still points to young_ptr + # Say we are back into Caml code + li 12, 0 + stw 12, 0(24) # 24 still points to caml_last_return_address # Return to caller blr @@ -292,10 +298,13 @@ L..102: addi 1, 1, -24 lwz 9, L..caml_bottom_of_stack(2) lwz 10, L..caml_last_return_address(2) + lwz 11, L..caml_gc_regs(2) lwz 9, 0(9) lwz 10, 0(10) + lwz 11, 0(11) stw 9, 0(1) stw 10, 4(1) + stw 11, 8(1) # Build an exception handler to catch exceptions escaping out of Caml bl L..103 b L..104 @@ -330,14 +339,16 @@ L..105: lwz 10, L..caml_exception_pointer(2) addi 1, 1, 24 stw 9, 0(10) - # Pop the callback link, restoring caml_bottom_of_stack - # and caml_last_return_address - lwz 9, 0(1) - lwz 10, 4(1) - lwz 11, L..caml_bottom_of_stack(2) - lwz 12, L..caml_last_return_address(2) - stw 9, 0(11) - stw 10, 0(12) + # Pop the callback link, restoring the global variables + lwz 7, 0(1) + lwz 8, 4(1) + lwz 9, 8(1) + lwz 10, L..caml_bottom_of_stack(2) + lwz 11, L..caml_last_return_address(2) + lwz 12, L..caml_gc_regs(2) + stw 7, 0(10) + stw 8, 0(11) + stw 9, 0(12) addi 1, 1, 24 # Update allocation pointer lwz 11, L..young_ptr(2) @@ -394,14 +405,16 @@ L..104: lwz 10, L..young_ptr(2) stw 29, 0(9) stw 31, 0(10) - # Pop the callback link, restoring caml_bottom_of_stack - # and caml_last_return_address - lwz 9, 0(1) - lwz 10, 4(1) - lwz 11, L..caml_bottom_of_stack(2) - lwz 12, L..caml_last_return_address(2) - stw 9, 0(11) - stw 10, 0(12) + # Pop the callback link, restoring the global variables + lwz 7, 0(1) + lwz 8, 4(1) + lwz 9, 8(1) + lwz 10, L..caml_bottom_of_stack(2) + lwz 11, L..caml_last_return_address(2) + lwz 12, L..caml_gc_regs(2) + stw 7, 0(10) + stw 8, 0(11) + stw 9, 0(12) # Re-raise the exception through mlraise, # so that local C roots are cleaned up correctly b .mlraise @@ -457,6 +470,8 @@ L..caml_bottom_of_stack: .tc caml_bottom_of_stack[TC], caml_bottom_of_stack L..caml_last_return_address: .tc caml_last_return_address[TC], caml_last_return_address +L..caml_gc_regs: + .tc caml_gc_regs[TC], caml_gc_regs L..caml_exception_pointer: .tc caml_exception_pointer[TC], caml_exception_pointer L..gc_entry_regs: diff --git a/asmrun/power-elf.S b/asmrun/power-elf.S index df60540bcc..a4b62e14c5 100644 --- a/asmrun/power-elf.S +++ b/asmrun/power-elf.S @@ -11,9 +11,6 @@ /* $Id$ */ - .comm gc_entry_regs, 4*32, 4 - .comm gc_entry_float_regs, 8*32, 8 - #define Addrglobal(reg,glob) \ addis reg, 0, glob@ha; \ addi reg, reg, glob@l @@ -24,88 +21,6 @@ addis tmp, 0, glob@ha; \ stw reg, glob@l(tmp) -/* Save and restore all callee-save registers */ -/* GPR 14 at sp+16 ... GPR 31 at sp+84 - FPR 14 at sp+92 ... FPR 31 at sp+228 */ - -#define Save_callee_save \ - addic 11, 1, 16-4; \ - stwu 14, 4(11); \ - stwu 15, 4(11); \ - stwu 16, 4(11); \ - stwu 17, 4(11); \ - stwu 18, 4(11); \ - stwu 19, 4(11); \ - stwu 20, 4(11); \ - stwu 21, 4(11); \ - stwu 22, 4(11); \ - stwu 23, 4(11); \ - stwu 24, 4(11); \ - stwu 25, 4(11); \ - stwu 26, 4(11); \ - stwu 27, 4(11); \ - stwu 28, 4(11); \ - stwu 29, 4(11); \ - stwu 30, 4(11); \ - stwu 31, 4(11); \ - stfdu 14, 8(11); \ - stfdu 15, 8(11); \ - stfdu 16, 8(11); \ - stfdu 17, 8(11); \ - stfdu 18, 8(11); \ - stfdu 19, 8(11); \ - stfdu 20, 8(11); \ - stfdu 21, 8(11); \ - stfdu 22, 8(11); \ - stfdu 23, 8(11); \ - stfdu 24, 8(11); \ - stfdu 25, 8(11); \ - stfdu 26, 8(11); \ - stfdu 27, 8(11); \ - stfdu 28, 8(11); \ - stfdu 29, 8(11); \ - stfdu 30, 8(11); \ - stfdu 31, 8(11) - -#define Restore_callee_save \ - addic 11, 1, 16-4; \ - lwzu 14, 4(11); \ - lwzu 15, 4(11); \ - lwzu 16, 4(11); \ - lwzu 17, 4(11); \ - lwzu 18, 4(11); \ - lwzu 19, 4(11); \ - lwzu 20, 4(11); \ - lwzu 21, 4(11); \ - lwzu 22, 4(11); \ - lwzu 23, 4(11); \ - lwzu 24, 4(11); \ - lwzu 25, 4(11); \ - lwzu 26, 4(11); \ - lwzu 27, 4(11); \ - lwzu 28, 4(11); \ - lwzu 29, 4(11); \ - lwzu 30, 4(11); \ - lwzu 31, 4(11); \ - lfdu 14, 8(11); \ - lfdu 15, 8(11); \ - lfdu 16, 8(11); \ - lfdu 17, 8(11); \ - lfdu 18, 8(11); \ - lfdu 19, 8(11); \ - lfdu 20, 8(11); \ - lfdu 21, 8(11); \ - lfdu 22, 8(11); \ - lfdu 23, 8(11); \ - lfdu 24, 8(11); \ - lfdu 25, 8(11); \ - lfdu 26, 8(11); \ - lfdu 27, 8(11); \ - lfdu 28, 8(11); \ - lfdu 29, 8(11); \ - lfdu 30, 8(11); \ - lfdu 31, 8(11) - .section ".text" /* Invoke the garbage collector. */ @@ -113,20 +28,24 @@ .globl caml_call_gc .type caml_call_gc, @function caml_call_gc: - /* Set up stack frame for calling the garbage collector */ - stwu 1, -32(1) + /* Set up stack frame */ + stwu 1, -0x1A0(1) + /* 0x1A0 = 4*32 (int regs) + 8*32 (float regs) + 32 (space for C call) */ /* Record return address into Caml code */ mflr 0 Storeglobal(0, caml_last_return_address, 11) /* Record lowest stack address */ addic 0, 1, 32 Storeglobal(0, caml_bottom_of_stack, 11) + /* Record pointer to register array */ + addic 0, 1, 8*32 + 32 + Storeglobal(0, caml_gc_regs, 11) /* Save current allocation pointer for debugging purposes */ Storeglobal(31, young_ptr, 11) /* Save exception pointer (if e.g. a sighandler raises) */ Storeglobal(29, caml_exception_pointer, 11) /* Save all registers used by the code generator */ - Addrglobal(11, gc_entry_regs - 4) + addic 11, 1, 8*32 + 32 - 4 stwu 3, 4(11) stwu 4, 4(11) stwu 5, 4(11) @@ -150,7 +69,7 @@ caml_call_gc: stwu 26, 4(11) stwu 27, 4(11) stwu 28, 4(11) - Addrglobal(11, gc_entry_float_regs - 8) + addic 11, 1, 32 - 8 stfdu 1, 8(11) stfdu 2, 8(11) stfdu 3, 8(11) @@ -188,8 +107,7 @@ caml_call_gc: Loadglobal(31, young_ptr, 11) Loadglobal(30, young_limit, 11) /* Restore all regs used by the code generator */ - Addrglobal(11, gc_entry_regs) - addic 11, 11, -4 + addic 11, 1, 8*32 + 32 - 4 lwzu 3, 4(11) lwzu 4, 4(11) lwzu 5, 4(11) @@ -213,8 +131,7 @@ caml_call_gc: lwzu 26, 4(11) lwzu 27, 4(11) lwzu 28, 4(11) - Addrglobal(11, gc_entry_float_regs) - addic 11, 11, -8 + addic 11, 1, 32 - 8 lfdu 1, 8(11) lfdu 2, 8(11) lfdu 3, 8(11) @@ -250,8 +167,11 @@ caml_call_gc: Loadglobal(0, caml_last_return_address, 11) addic 0, 0, -16 /* Restart the allocation (4 instructions) */ mtlr 0 + /* Say we are back into Caml code */ + li 12, 0 + Storeglobal(12, caml_last_return_address, 11) /* Deallocate stack frame */ - addi 1, 1, 32 + addi 1, 1, 0x1A0 /* Return */ blr @@ -268,15 +188,20 @@ caml_c_call: Storeglobal(1, caml_bottom_of_stack, 12) Storeglobal(25, caml_last_return_address, 12) /* Make the exception handler and alloc ptr available to the C code */ - Storeglobal(31, young_ptr, 12) - Storeglobal(29, caml_exception_pointer, 12) - /* Call the function (address in 11) */ + Storeglobal(31, young_ptr, 11) + Storeglobal(29, caml_exception_pointer, 11) + /* Call the function (address in link register) */ blrl /* Restore return address (in 25, preserved by the C function) */ mtlr 25 - /* Reload allocation pointer */ + /* Reload allocation pointer and allocation limit*/ Loadglobal(31, young_ptr, 11) + Loadglobal(30, young_limit, 11) + /* Say we are back into Caml code */ + li 12, 0 + Storeglobal(12, caml_last_return_address, 11) /* Return to caller */ + addic 1, 8, 1 blr /* Raise an exception from C */ @@ -290,7 +215,7 @@ raise_caml_exception: Loadglobal(30, young_limit, 11) /* Say we are back into Caml code */ li 0, 0 - Storeglobal(0, caml_last_return_address, 11) + Storeglobal(0, caml_last_context, 11) /* Pop trap frame */ lwz 0, 0(1) lwz 29, 4(1) @@ -314,13 +239,53 @@ caml_start_program: mflr 0 stw 0, 256+4(1) /* Save all callee-save registers */ - Save_callee_save + /* GPR 14 at sp+16 ... GPR 31 at sp+84 + FPR 14 at sp+92 ... FPR 31 at sp+228 */ + addic 11, 1, 16-4 + stwu 14, 4(11) + stwu 15, 4(11) + stwu 16, 4(11) + stwu 17, 4(11) + stwu 18, 4(11) + stwu 19, 4(11) + stwu 20, 4(11) + stwu 21, 4(11) + stwu 22, 4(11) + stwu 23, 4(11) + stwu 24, 4(11) + stwu 25, 4(11) + stwu 26, 4(11) + stwu 27, 4(11) + stwu 28, 4(11) + stwu 29, 4(11) + stwu 30, 4(11) + stwu 31, 4(11) + stfdu 14, 8(11) + stfdu 15, 8(11) + stfdu 16, 8(11) + stfdu 17, 8(11) + stfdu 18, 8(11) + stfdu 19, 8(11) + stfdu 20, 8(11) + stfdu 21, 8(11) + stfdu 22, 8(11) + stfdu 23, 8(11) + stfdu 24, 8(11) + stfdu 25, 8(11) + stfdu 26, 8(11) + stfdu 27, 8(11) + stfdu 28, 8(11) + stfdu 29, 8(11) + stfdu 30, 8(11) + stfdu 31, 8(11) /* Set up a callback link */ - addi 1, 1, -8 + addi 1, 1, -16 Loadglobal(9, caml_bottom_of_stack, 11) Loadglobal(10, caml_last_return_address, 11) + Loadglobal(11, caml_gc_regs, 11) stw 9, 0(1) stw 10, 4(1) + stw 11, 8(1) /* Build an exception handler to catch exceptions escaping out of Caml */ bl .L103 b .L104 @@ -336,7 +301,7 @@ caml_start_program: Loadglobal(30, young_limit, 11) /* Say we are back into Caml code */ li 0, 0 - Storeglobal(0, caml_last_return_address, 11) + Storeglobal(0, caml_last_context, 11) /* Call the Caml code */ mtlr 12 .L105: @@ -345,17 +310,58 @@ caml_start_program: lwz 9, 4(1) Storeglobal(9, caml_exception_pointer, 11) addi 1, 1, 8 - /* Pop the callback link, restoring caml_bottom_of_stack */ - /* and caml_last_return_address */ + /* Pop the callback link, restoring the global variables */ lwz 9, 0(1) lwz 10, 4(1) - Storeglobal(9, caml_bottom_of_stack, 11) - Storeglobal(10, caml_last_return_address, 11) + lwz 11, 8(1) + Storeglobal(9, caml_bottom_of_stack, 12) + Storeglobal(10, caml_last_return_address, 12) + Storeglobal(11, caml_gc_regs, 12) + addi 1, 1, 16 + /* Pop the callback link, restoring caml_last_context */ + lwz 9, 0(1) addi 1, 1, 8 + Storeglobal(9, caml_bottom_of_stack, 11) /* Update allocation pointer */ Storeglobal(31, young_ptr, 11) /* Restore callee-save registers */ - Restore_callee_save + addic 11, 1, 16-4 + lwzu 14, 4(11) + lwzu 15, 4(11) + lwzu 16, 4(11) + lwzu 17, 4(11) + lwzu 18, 4(11) + lwzu 19, 4(11) + lwzu 20, 4(11) + lwzu 21, 4(11) + lwzu 22, 4(11) + lwzu 23, 4(11) + lwzu 24, 4(11) + lwzu 25, 4(11) + lwzu 26, 4(11) + lwzu 27, 4(11) + lwzu 28, 4(11) + lwzu 29, 4(11) + lwzu 30, 4(11) + lwzu 31, 4(11) + lfdu 14, 8(11) + lfdu 15, 8(11) + lfdu 16, 8(11) + lfdu 17, 8(11) + lfdu 18, 8(11) + lfdu 19, 8(11) + lfdu 20, 8(11) + lfdu 21, 8(11) + lfdu 22, 8(11) + lfdu 23, 8(11) + lfdu 24, 8(11) + lfdu 25, 8(11) + lfdu 26, 8(11) + lfdu 27, 8(11) + lfdu 28, 8(11) + lfdu 29, 8(11) + lfdu 30, 8(11) + lfdu 31, 8(11) /* Reload return address */ lwz 0, 256+4(1) mtlr 0 @@ -368,12 +374,13 @@ caml_start_program: /* Update caml_exception_pointer and young_ptr */ Storeglobal(29, caml_exception_pointer, 11) Storeglobal(31, young_ptr, 11) - /* Pop the callback link, restoring caml_bottom_of_stack */ - /* and caml_last_return_address */ + /* Pop the callback link, restoring the global variables */ lwz 9, 0(1) - lwz 10, 4(1) - Storeglobal(9, caml_bottom_of_stack, 11) - Storeglobal(10, caml_last_return_address, 11) + lwz 10, 4(1) + lwz 11, 8(1) + Storeglobal(9, caml_bottom_of_stack, 12) + Storeglobal(10, caml_last_return_address, 12) + Storeglobal(11, caml_gc_regs, 12) /* Re-raise the exception through mlraise, */ /* so that local C roots are cleaned up correctly */ b mlraise diff --git a/asmrun/roots.c b/asmrun/roots.c index cc3d0368d3..cfc5de3007 100644 --- a/asmrun/roots.c +++ b/asmrun/roots.c @@ -122,7 +122,9 @@ static void init_frame_descriptors() /* Communication with [caml_start_program] and [caml_call_gc]. */ -struct caml_context * caml_last_context = NULL; +char * caml_bottom_of_stack; +unsigned long caml_last_return_address = 0; +value * caml_gc_regs; /* Call [oldify] on all stack roots, C roots and global roots */ @@ -149,9 +151,9 @@ void oldify_local_roots () /* The stack and local roots */ if (frame_descriptors == NULL) init_frame_descriptors(); - sp = caml_last_context->stack_chunk; - retaddr = caml_last_context->last_retaddr; - regs = caml_last_context->gc_regs; + sp = caml_bottom_of_stack; + retaddr = caml_last_return_address; + regs = caml_gc_regs; while (1) { /* Find the descriptor corresponding to the return address */ h = Hash_retaddr(retaddr); @@ -188,11 +190,11 @@ void oldify_local_roots () /* This marks the top of a stack chunk for an ML callback. Skip C portion of stack and continue with next ML stack chunk. */ struct caml_context * next_context = Callback_link(sp); - /* A null context means no more ML stack chunks; stop here. */ - if (next_context == NULL) break; - sp = next_context->stack_chunk; + sp = next_context->bottom_of_stack; retaddr = next_context->last_retaddr; regs = next_context->gc_regs; + /* A null sp means no more ML stack chunks; stop here. */ + if (sp == NULL) break; } } /* Local C roots */ @@ -234,7 +236,8 @@ void do_roots (f) } /* The stack and local roots */ if (frame_descriptors == NULL) init_frame_descriptors(); - do_local_roots(f, caml_last_context, local_roots); + do_local_roots(f, caml_bottom_of_stack, caml_last_return_address, + caml_gc_regs, local_roots); /* Global C roots */ for (gr = global_roots; gr != NULL; gr = gr->next) { f (*(gr->root), gr->root); @@ -243,10 +246,9 @@ void do_roots (f) if (scan_roots_hook != NULL) (*scan_roots_hook)(f); } -void do_local_roots(f, first_context, local_roots) - scanning_action f; - struct caml_context * first_context; - struct caml__roots_block * local_roots; +void do_local_roots(scanning_action f, char * bottom_of_stack, + unsigned long last_retaddr, value * gc_regs, + struct caml__roots_block * local_roots) { char * sp; unsigned long retaddr; @@ -258,9 +260,9 @@ void do_local_roots(f, first_context, local_roots) value * root; struct caml__roots_block *lr; - sp = first_context->stack_chunk; - retaddr = first_context->last_retaddr; - regs = first_context->gc_regs; + sp = bottom_of_stack; + retaddr = last_retaddr; + regs = gc_regs; while (1) { /* Find the descriptor corresponding to the return address */ h = Hash_retaddr(retaddr); @@ -294,11 +296,11 @@ void do_local_roots(f, first_context, local_roots) /* This marks the top of a stack chunk for an ML callback. Skip C portion of stack and continue with next ML stack chunk. */ struct caml_context * next_context = Callback_link(sp); - /* A null context means no more ML stack chunks; stop here. */ - if (next_context == NULL) break; - sp = next_context->stack_chunk; + sp = next_context->bottom_of_stack; retaddr = next_context->last_retaddr; regs = next_context->gc_regs; + /* A null sp means no more ML stack chunks; stop here. */ + if (sp == NULL) break; } } /* Local C roots */ diff --git a/asmrun/sparc.S b/asmrun/sparc.S index 159f7185aa..71b530e997 100644 --- a/asmrun/sparc.S +++ b/asmrun/sparc.S @@ -22,7 +22,9 @@ #define Young_limit _young_limit #define Young_ptr _young_ptr -#define Caml_last_context _caml_last_context +#define Caml_bottom_of_stack _caml_bottom_of_stack +#define Caml_last_return_address _caml_last_return_address +#define Caml_gc_regs _caml_gc_regs #define Caml_exception_pointer _caml_exception_pointer #define Caml_required_size _caml_required_size #define Caml_alloc _caml_alloc @@ -46,7 +48,9 @@ #define Young_limit young_limit #define Young_ptr young_ptr -#define Caml_last_context caml_last_context +#define Caml_bottom_of_stack caml_bottom_of_stack +#define Caml_last_return_address caml_last_return_address +#define Caml_gc_regs caml_gc_regs #define Caml_exception_pointer caml_exception_pointer #define Caml_required_size caml_required_size #define Caml_alloc caml_alloc @@ -98,10 +102,13 @@ Caml_call_gc: Store(Exn_ptr, Caml_exception_pointer) /* Save current allocation pointer for debugging purposes */ Store(Alloc_ptr, Young_ptr) + /* Record lowest stack address */ + Store(%sp, Caml_bottom_of_stack) + /* Record last return address */ + Store(%o7, Caml_last_return_address) /* Allocate space on stack for caml_context structure and float regs */ - sub %sp, 4 + 25*4 + 15*8, %sp - /* Build caml_context structure on stack - and save it into caml_last_context. */ + sub %sp, 20*4 + 15*8, %sp + /* Save int regs on stack and save it into caml_gc_regs */ add %sp, 96 + 15*8, %g2 std %o0, [%g2] std %o2, [%g2 + 0x8] @@ -114,8 +121,7 @@ Caml_call_gc: st %l4, [%g2 + 0x40] st %g3, [%g2 + 0x44] st %g4, [%g2 + 0x48] - st %o7, [%g2 + 0x64] - Store(%g2, Caml_last_context) + Store(%g2, Caml_gc_regs) /* Save the floating-point registers */ add %sp, 96, %g1 std %f0, [%g1] @@ -136,7 +142,7 @@ Caml_call_gc: /* Call the garbage collector */ call Garbage_collection nop - /* Restore return address and all regs used by the code generator */ + /* Restore all regs used by the code generator */ add %sp, 96 + 15*8, %g2 ldd [%g2], %o0 ldd [%g2 + 0x8], %o2 @@ -149,7 +155,6 @@ Caml_call_gc: ld [%g2 + 0x40], %l4 ld [%g2 + 0x44], %g3 ld [%g2 + 0x48], %g4 - ld [%g2 + 0x64], %o7 add %sp, 96, %g1 ldd [%g1], %f0 ldd [%g1 + 0x8], %f2 @@ -172,6 +177,7 @@ Caml_call_gc: Load(Caml_required_size, %g2) sub Alloc_ptr, %g2, Alloc_ptr /* Return to caller */ + Load(Caml_last_return_address, %o7) retl add %sp, 4 + 25*4 + 15*8, %sp /* in delay slot */ @@ -180,14 +186,9 @@ Caml_call_gc: .global Caml_c_call /* Function to call is in %g2 */ Caml_c_call: - /* Build caml_context structure on stack - and save it into caml_last_context. - We don't fill the gc_regs section, because no registers - are live across caml_c_call. */ - sub %sp, 8, %sp - st %o7, [%sp + 100] - add %sp, 100 - 25*4, %o7 - Store(%o7, Caml_last_context) + /* Record lowest stack address and return address */ + Store(%sp, Caml_bottom_of_stack) + Store(%o7, Caml_last_return_address) /* Save the exception handler and alloc pointer */ Store(Exn_ptr, Caml_exception_pointer) sethi %hi(Young_ptr), %g1 @@ -195,12 +196,12 @@ Caml_c_call: call %g2 st Alloc_ptr, [%g1 + %lo(Young_ptr)] /* in delay slot */ /* Reload return address */ - ld [%sp + 100], %o7 + Load(Caml_last_return_address, %o7) /* Reload alloc pointer */ - Load(Young_ptr, Alloc_ptr) + sethi %hi(Young_ptr), %g1 /* Return to caller */ retl - add %sp, 8, %sp /* in delay slot */ + ld [%g1 + %lo(Young_ptr)], Alloc_ptr /* in delay slot */ /* Start the Caml program */ @@ -214,9 +215,12 @@ Caml_start_program: /* Code shared with callback* */ L108: /* Set up a callback link on the stack. */ - sub %sp, 8, %sp - Load(Caml_last_context, %l0) - st %l0, [%sp + 96] + sub %sp, 16, %sp + Load(Caml_bottom_of_stack, %l0) + Load(Caml_last_return_address, %l1) + Load(Caml_gc_regs, %l2) + std %l0, [%sp + 96] + st %l2, [%sp + 104] /* Set up a trap frame to catch exceptions escaping the Caml code */ call L111 nop @@ -237,10 +241,13 @@ L109: call %l2 ld [%sp + 100], Exn_ptr add %sp, 8, %sp Store(Exn_ptr, Caml_exception_pointer) - /* Pop callback link, restoring caml_last_context */ - ld [%sp + 96], %l0 - add %sp, 8, %sp - Store(%l0, Caml_last_context) + /* Pop callback link, restoring the global variables */ + ldd [%sp + 96], %l0 + ld [%sp + 104], %l2 + Store(%l0, Caml_bottom_of_stack) + Store(%l1, Caml_last_return_address) + Store(%l2, Caml_gc_regs) + add %sp, 16, %sp /* Save allocation pointer */ Store(Alloc_ptr, Young_ptr) /* Move result where the C function expects it */ @@ -252,8 +259,11 @@ L110: /* The trap handler */ Store(Exn_ptr, Caml_exception_pointer) Store(Alloc_ptr, Young_ptr) - ld [%sp + 96], %l0 - Store(%l0, Caml_last_context) + ldd [%sp + 96], %l0 + ld [%sp + 104], %l2 + Store(%l0, Caml_bottom_of_stack) + Store(%l1, Caml_last_return_address) + Store(%l2, Caml_gc_regs) /* Re-raise the exception through mlraise, so that local C roots are cleaned up correctly. */ call Mlraise /* never returns */ diff --git a/asmrun/stack.h b/asmrun/stack.h index 0eea1fd7ef..610b6a216a 100644 --- a/asmrun/stack.h +++ b/asmrun/stack.h @@ -18,41 +18,35 @@ /* Macros to access the stack frame */ #ifdef TARGET_alpha -#define NUM_GC_REGS 31 #define Saved_return_address(sp) *((long *)(sp - 8)) #define Already_scanned(sp, retaddr) (retaddr & 1L) #define Mark_scanned(sp, retaddr) (*((long *)(sp - 8)) = retaddr | 1L) #define Mask_already_scanned(retaddr) (retaddr & ~1L) -#define Callback_link(sp) (*(struct caml_context **)(sp + 16)) +#define Callback_link(sp) ((struct caml_context *)(sp + 16)) #endif #ifdef TARGET_sparc -#define NUM_GC_REGS 25 -#define Saved_return_address(sp) *((long *)(sp - 4)) -#define Callback_link(sp) (*(struct caml_context **)(sp + 8)) +#define Saved_return_address(sp) *((long *)(sp + 92)) +#define Callback_link(sp) ((struct caml_context *)(sp + 104)) #endif #ifdef TARGET_i386 -#define NUM_GC_REGS 7 #define Saved_return_address(sp) *((long *)(sp - 4)) -#define Callback_link(sp) (*(struct caml_context **)(sp + 8)) +#define Callback_link(sp) ((struct caml_context *)(sp + 8)) #endif #ifdef TARGET_mips -#define NUM_GC_REGS 32 #define Saved_return_address(sp) *((long *)(sp - 4)) -#define Callback_link(sp) (*(struct caml_context **)(sp + 8)) +#define Callback_link(sp) ((struct caml_context *)(sp + 8)) #endif #ifdef TARGET_hppa -#define NUM_GC_REGS 32 #define Stack_grows_upwards #define Saved_return_address(sp) *((long *)sp) -#define Callback_link(sp) (*(struct caml_context **)(sp - 16)) +#define Callback_link(sp) ((struct caml_context *)(sp - 24)) #endif #ifdef TARGET_power -#define NUM_GC_REGS 32 #define Saved_return_address(sp) *((long *)(sp - 4)) #define Already_scanned(sp, retaddr) (retaddr & 1) #define Mark_scanned(sp, retaddr) (*((long *)(sp - 4)) = retaddr | 1) @@ -62,32 +56,26 @@ #else #define Trap_frame_size 8 #endif -#define Callback_link(sp) (*(struct caml_context **)(sp + Trap_frame_size)) +#define Callback_link(sp) ((struct caml_context *)(sp + Trap_frame_size)) #endif #ifdef TARGET_m68k -#define NUM_GC_REGS 7 #define Saved_return_address(sp) *((long *)(sp - 4)) -#define Callback_link(sp) (*(struct caml_context **)(sp + 8)) +#define Callback_link(sp) ((struct caml_context *)(sp + 8)) #endif -/* Structure of Caml contexts in the stack */ +/* Structure of Caml callback contexts */ struct caml_context { - value gc_regs[NUM_GC_REGS]; /* registers containing heap addresses */ + char * bottom_of_stack; /* beginning of Caml stack chunk */ unsigned long last_retaddr; /* last return address in Caml code */ - char stack_chunk[sizeof(value)]; /* beginning of the stack chunk */ + value * gc_regs; /* pointer to register block */ }; -/* Structure of a Caml stack chunk is: - - pointer to context for previous chunk - - frame with return address into callback (negative frame size) - - regular Caml frames - - context for this chunk -*/ - -/* Declaration of variables defined in the asm code */ -extern struct caml_context * caml_last_context; +/* Declaration of variables used in the asm code */ +extern char * caml_bottom_of_stack; +extern unsigned long caml_last_return_address; +extern value * caml_gc_regs; extern char * caml_exception_pointer; extern value caml_globals[]; extern long * caml_frametable[]; |