summaryrefslogtreecommitdiff
path: root/asmrun
diff options
context:
space:
mode:
authorXavier Leroy <xavier.leroy@inria.fr>1997-11-27 16:28:40 +0000
committerXavier Leroy <xavier.leroy@inria.fr>1997-11-27 16:28:40 +0000
commit5866ccca18af727157d3a31514152c869ae3355b (patch)
treea06539095f3d3c85a78fbf2e0af1fc76482bf5c4 /asmrun
parent4b87c642792cee1997f6b0694ca069d6bb3f713c (diff)
downloadocaml-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.S55
-rw-r--r--asmrun/hppa.S56
-rw-r--r--asmrun/i386.S128
-rw-r--r--asmrun/i386nt.asm37
-rw-r--r--asmrun/mips.S262
-rw-r--r--asmrun/power-aix.S89
-rw-r--r--asmrun/power-elf.S231
-rw-r--r--asmrun/roots.c38
-rw-r--r--asmrun/sparc.S68
-rw-r--r--asmrun/stack.h42
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[];