1995-08-09 08:06:35 -07:00
|
|
|
/***********************************************************************/
|
|
|
|
/* */
|
1996-04-30 07:53:58 -07:00
|
|
|
/* Objective Caml */
|
1995-08-09 08:06:35 -07:00
|
|
|
/* */
|
|
|
|
/* Xavier Leroy, projet Cristal, INRIA Rocquencourt */
|
|
|
|
/* */
|
1996-04-30 07:53:58 -07:00
|
|
|
/* Copyright 1996 Institut National de Recherche en Informatique et */
|
1995-08-09 08:06:35 -07:00
|
|
|
/* Automatique. Distributed only by permission. */
|
|
|
|
/* */
|
|
|
|
/***********************************************************************/
|
|
|
|
|
|
|
|
/* $Id$ */
|
|
|
|
|
1995-07-12 07:27:10 -07:00
|
|
|
/* Asm part of the runtime system, Mips processor */
|
|
|
|
|
|
|
|
.comm gc_entry_regs, 4 * 32
|
|
|
|
.comm gc_entry_float_regs, 8 * 16
|
|
|
|
|
1997-02-03 02:14:54 -08:00
|
|
|
/* 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 */
|
|
|
|
|
1995-07-12 07:27:10 -07:00
|
|
|
#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
|
1997-02-03 02:14:54 -08:00
|
|
|
.globl caml_call_gc
|
|
|
|
#ifndef _PIC
|
1995-07-12 07:27:10 -07:00
|
|
|
.globl caml_alloc1
|
|
|
|
.globl caml_alloc2
|
|
|
|
.globl caml_alloc3
|
|
|
|
.globl caml_alloc
|
1997-02-03 02:14:54 -08:00
|
|
|
#endif
|
1997-02-01 09:40:41 -08:00
|
|
|
.ent caml_call_gc
|
|
|
|
|
|
|
|
caml_call_gc:
|
|
|
|
#ifdef _PIC
|
1997-05-19 08:42:21 -07:00
|
|
|
.set noreorder
|
|
|
|
.cpload $25
|
1997-02-01 09:40:41 -08:00
|
|
|
.set reorder
|
|
|
|
#endif
|
|
|
|
/* Record return address and adjust it to point back to
|
|
|
|
the beginning of the allocation sequence */
|
|
|
|
sw $31, caml_last_return_address
|
1997-02-03 02:14:54 -08:00
|
|
|
subu $31, $31, 16
|
1997-02-01 09:40:41 -08:00
|
|
|
/* Don't request any allocation, will be redone at return */
|
|
|
|
li $24, 0
|
1997-05-19 08:42:21 -07:00
|
|
|
b $110
|
1995-07-12 07:27:10 -07:00
|
|
|
|
1997-02-03 02:14:54 -08:00
|
|
|
#ifndef _PIC
|
|
|
|
|
1995-07-12 07:27:10 -07:00
|
|
|
/* caml_alloc* : all code generator registers preserved. */
|
|
|
|
|
|
|
|
caml_alloc1:
|
|
|
|
subu $22, $22, 8
|
|
|
|
bltu $22, $23, $100
|
1997-05-19 08:42:21 -07:00
|
|
|
j $31
|
1997-02-01 09:40:41 -08:00
|
|
|
$100: li $24, 8
|
|
|
|
b caml_call_gc_internal
|
1995-07-12 07:27:10 -07:00
|
|
|
|
|
|
|
caml_alloc2:
|
|
|
|
subu $22, $22, 12
|
|
|
|
bltu $22, $23, $101
|
1997-05-19 08:42:21 -07:00
|
|
|
j $31
|
1997-02-01 09:40:41 -08:00
|
|
|
$101: li $24, 12
|
|
|
|
b caml_call_gc_internal
|
1995-07-12 07:27:10 -07:00
|
|
|
|
|
|
|
caml_alloc3:
|
|
|
|
subu $22, $22, 16
|
|
|
|
bltu $22, $23, $102
|
1997-05-19 08:42:21 -07:00
|
|
|
j $31
|
1997-02-01 09:40:41 -08:00
|
|
|
$102: li $24, 16
|
|
|
|
b caml_call_gc_internal
|
1995-07-12 07:27:10 -07:00
|
|
|
|
|
|
|
caml_alloc:
|
1997-02-01 09:40:41 -08:00
|
|
|
subu $22, $22, $24
|
|
|
|
bltu $22, $23, caml_call_gc_internal
|
1995-07-12 07:27:10 -07:00
|
|
|
j $31
|
|
|
|
|
1997-02-01 09:40:41 -08:00
|
|
|
caml_call_gc_internal:
|
|
|
|
/* Record return address */
|
1995-07-12 07:27:10 -07:00
|
|
|
sw $31, caml_last_return_address
|
1997-02-01 09:40:41 -08:00
|
|
|
|
1997-02-03 02:14:54 -08:00
|
|
|
#endif
|
|
|
|
|
1997-02-01 09:40:41 -08:00
|
|
|
$110:
|
|
|
|
/* Record lowest stack address */
|
1995-07-12 07:27:10 -07:00
|
|
|
sw $sp, caml_bottom_of_stack
|
1997-02-01 09:40:41 -08:00
|
|
|
/* Save actual return address, $gp, requested size.
|
|
|
|
Also reserve some stack space for the call. */
|
|
|
|
subu $sp, $sp, 32
|
|
|
|
sw $31, 28($sp)
|
|
|
|
#ifdef _PIC
|
|
|
|
.cprestore 24
|
|
|
|
#endif
|
|
|
|
sw $24, 16($sp)
|
1995-07-12 07:27:10 -07:00
|
|
|
/* Save current allocation pointer for debugging purposes */
|
|
|
|
sw $22, young_ptr
|
1996-02-01 07:02:04 -08:00
|
|
|
/* Save the exception handler (if e.g. a sighandler raises) */
|
|
|
|
sw $30, caml_exception_pointer
|
1995-07-12 07:27:10 -07:00
|
|
|
/* 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)
|
|
|
|
/* Call the garbage collector */
|
1995-12-21 06:21:11 -08:00
|
|
|
jal garbage_collection
|
1995-07-12 07:27:10 -07:00
|
|
|
/* 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)
|
|
|
|
/* Reload new allocation pointer and allocation limit */
|
|
|
|
lw $22, young_ptr
|
1995-12-21 06:21:11 -08:00
|
|
|
lw $23, young_limit
|
1995-07-12 07:27:10 -07:00
|
|
|
/* Allocate space for the block */
|
1997-02-01 09:40:41 -08:00
|
|
|
lw $24, 16($sp)
|
|
|
|
subu $22, $22, $24
|
1995-12-21 06:21:11 -08:00
|
|
|
/* Say that we are back into Caml code */
|
|
|
|
sw $0, caml_last_return_address
|
1995-07-12 07:27:10 -07:00
|
|
|
/* Return to caller */
|
1997-05-19 08:42:21 -07:00
|
|
|
lw $31, 28($sp)
|
1997-02-01 09:40:41 -08:00
|
|
|
addu $sp, $sp, 32
|
1995-07-12 07:27:10 -07:00
|
|
|
j $31
|
|
|
|
|
1997-02-01 09:40:41 -08:00
|
|
|
.end caml_call_gc
|
1995-07-12 07:27:10 -07:00
|
|
|
|
|
|
|
/* Call a C function from Caml */
|
|
|
|
|
|
|
|
.globl caml_c_call
|
|
|
|
.ent caml_c_call
|
|
|
|
|
|
|
|
caml_c_call:
|
1997-02-01 09:40:41 -08:00
|
|
|
/* Function to call is in $24 */
|
1997-02-03 06:41:42 -08:00
|
|
|
#ifndef _PIC
|
1995-07-12 07:27:10 -07:00
|
|
|
/* Record lowest stack address and return address */
|
|
|
|
sw $31, caml_last_return_address
|
|
|
|
sw $sp, caml_bottom_of_stack
|
|
|
|
/* Make the exception handler and alloc ptr available to the C code */
|
|
|
|
sw $22, young_ptr
|
|
|
|
sw $30, caml_exception_pointer
|
|
|
|
/* Call the function */
|
1997-02-01 09:40:41 -08:00
|
|
|
jal $24
|
1995-12-21 06:21:11 -08:00
|
|
|
/* Reload alloc ptr and alloc limit */
|
1995-07-12 07:27:10 -07:00
|
|
|
lw $22, young_ptr
|
1995-12-21 06:21:11 -08:00
|
|
|
lw $23, young_limit
|
|
|
|
/* Reload return address */
|
1995-07-12 07:27:10 -07:00
|
|
|
lw $31, caml_last_return_address
|
1995-12-21 06:21:11 -08:00
|
|
|
/* Say that we are back into Caml code */
|
|
|
|
sw $0, caml_last_return_address
|
|
|
|
/* Return */
|
1995-07-12 07:27:10 -07:00
|
|
|
j $31
|
1997-02-03 06:41:42 -08:00
|
|
|
#else
|
|
|
|
/* Slightly optimized form of the above when referencing
|
|
|
|
global variables is expensive */
|
|
|
|
.set noreorder
|
|
|
|
.cpload $25
|
|
|
|
.set reorder
|
1997-05-19 08:42:21 -07:00
|
|
|
la $16, caml_last_return_address
|
|
|
|
la $17, young_ptr
|
|
|
|
la $18, young_limit
|
|
|
|
sw $31, 0($16) /* caml_last_return_address */
|
1997-02-03 06:41:42 -08:00
|
|
|
sw $sp, caml_bottom_of_stack
|
1997-05-19 08:42:21 -07:00
|
|
|
sw $22, 0($17) /* young_ptr */
|
1997-02-03 06:41:42 -08:00
|
|
|
sw $30, caml_exception_pointer
|
|
|
|
move $25, $24
|
|
|
|
jal $24
|
1997-05-19 08:42:21 -07:00
|
|
|
lw $31, 0($16) /* caml_last_return_address */
|
|
|
|
lw $22, 0($17) /* young_ptr */
|
|
|
|
lw $23, 0($18) /* young_limit */
|
|
|
|
sw $0, 0($16) /* caml_last_return_address */
|
1997-02-03 06:41:42 -08:00
|
|
|
j $31
|
|
|
|
#endif
|
1995-07-12 07:27:10 -07:00
|
|
|
.end caml_c_call
|
|
|
|
|
|
|
|
/* Start the Caml program */
|
|
|
|
|
|
|
|
.globl caml_start_program
|
|
|
|
.globl stray_exn_handler
|
|
|
|
.ent caml_start_program
|
|
|
|
caml_start_program:
|
1997-02-01 09:40:41 -08:00
|
|
|
#ifdef _PIC
|
|
|
|
.set noreorder
|
|
|
|
.cpload $25
|
|
|
|
.set reorder
|
|
|
|
#endif
|
1997-03-17 02:17:32 -08:00
|
|
|
la $24, caml_program
|
1995-07-12 07:27:10 -07:00
|
|
|
|
1997-03-17 02:17:32 -08:00
|
|
|
/* Code shared with callback* */
|
1995-12-04 02:02:14 -08:00
|
|
|
$103:
|
|
|
|
/* Save return address */
|
1997-05-19 08:42:21 -07:00
|
|
|
subu $sp, $sp, 96
|
1997-02-03 02:14:54 -08:00
|
|
|
sw $31, 88($sp)
|
1995-12-04 02:02:14 -08:00
|
|
|
/* Save all callee-save registers */
|
1997-05-19 08:42:21 -07:00
|
|
|
SAVE_CALLEE_SAVE_REGS
|
1996-01-07 08:58:44 -08:00
|
|
|
/* Set up a callback link on the stack. */
|
|
|
|
subu $sp, $sp, 8
|
|
|
|
lw $2, caml_bottom_of_stack
|
|
|
|
sw $2, 0($sp)
|
|
|
|
lw $3, caml_last_return_address
|
|
|
|
sw $3, 4($sp)
|
1995-12-04 02:02:14 -08:00
|
|
|
/* Set up a trap frame to catch exceptions escaping the Caml code */
|
|
|
|
subu $sp, $sp, 8
|
|
|
|
lw $30, caml_exception_pointer
|
|
|
|
sw $30, 0($sp)
|
|
|
|
la $2, $105
|
|
|
|
sw $2, 4($sp)
|
|
|
|
move $30, $sp
|
|
|
|
/* Reload allocation pointers */
|
1997-05-19 08:42:21 -07:00
|
|
|
lw $22, young_ptr
|
|
|
|
lw $23, young_limit
|
1995-12-21 06:21:11 -08:00
|
|
|
/* Say that we are back into Caml code */
|
|
|
|
sw $0, caml_last_return_address
|
1995-12-04 02:02:14 -08:00
|
|
|
/* Call the Caml code */
|
1997-02-01 09:40:41 -08:00
|
|
|
#ifdef _PIC
|
|
|
|
move $25, $24
|
|
|
|
#endif
|
1995-12-04 02:02:14 -08:00
|
|
|
$104: jal $24
|
1997-02-01 09:40:41 -08:00
|
|
|
#ifdef _PIC
|
|
|
|
/* Reload $gp based on return address */
|
|
|
|
.set noreorder
|
|
|
|
.cpload $31
|
|
|
|
.set reorder
|
|
|
|
#endif
|
1996-01-07 08:58:44 -08:00
|
|
|
/* Pop the trap frame, restoring caml_exception_pointer */
|
|
|
|
lw $24, 0($sp)
|
|
|
|
sw $24, caml_exception_pointer
|
|
|
|
addu $sp, $sp, 8
|
1995-12-04 02:02:14 -08:00
|
|
|
/* Pop the callback link,
|
|
|
|
restoring the global variables used by caml_c_call */
|
|
|
|
lw $24, 0($sp)
|
|
|
|
sw $24, caml_bottom_of_stack
|
|
|
|
lw $25, 4($sp)
|
|
|
|
sw $25, caml_last_return_address
|
|
|
|
addu $sp, $sp, 8
|
|
|
|
/* Update allocation pointer */
|
|
|
|
sw $22, young_ptr
|
|
|
|
/* Reload callee-save registers and return */
|
1997-02-03 02:14:54 -08:00
|
|
|
lw $31, 88($sp)
|
1997-05-19 08:42:21 -07:00
|
|
|
RELOAD_CALLEE_SAVE_REGS
|
1997-02-03 02:14:54 -08:00
|
|
|
addu $sp, $sp, 96
|
1995-12-04 02:02:14 -08:00
|
|
|
j $31
|
|
|
|
|
|
|
|
/* The trap handler: re-raise the exception through mlraise,
|
|
|
|
so that local C roots are cleaned up correctly. */
|
|
|
|
$105:
|
1997-02-01 09:40:41 -08:00
|
|
|
#ifdef _PIC
|
|
|
|
/* Reload $gp based on trap address (still in $25) */
|
|
|
|
.set noreorder
|
|
|
|
.cpload $25
|
|
|
|
.set reorder
|
|
|
|
#endif
|
1995-12-04 02:02:14 -08:00
|
|
|
sw $22, young_ptr
|
|
|
|
sw $30, caml_exception_pointer
|
1995-12-22 01:40:50 -08:00
|
|
|
lw $24, 0($sp)
|
|
|
|
sw $24, caml_bottom_of_stack
|
|
|
|
lw $25, 4($sp)
|
|
|
|
sw $25, caml_last_return_address
|
1995-12-04 02:02:14 -08:00
|
|
|
move $4, $2 /* bucket as first argument */
|
|
|
|
jal mlraise /* never returns */
|
|
|
|
|
1997-03-17 02:17:32 -08:00
|
|
|
.end caml_start_program
|
|
|
|
|
|
|
|
/* Raise an exception from C */
|
|
|
|
|
|
|
|
.globl raise_caml_exception
|
|
|
|
.ent raise_caml_exception
|
|
|
|
raise_caml_exception:
|
|
|
|
#ifdef _PIC
|
|
|
|
.set noreorder
|
|
|
|
.cpload $25
|
|
|
|
.set reorder
|
|
|
|
#endif
|
|
|
|
move $2, $4
|
|
|
|
lw $22, young_ptr
|
|
|
|
lw $23, young_limit
|
|
|
|
lw $sp, caml_exception_pointer
|
|
|
|
lw $30, 0($sp)
|
|
|
|
lw $24, 4($sp)
|
|
|
|
addu $sp, $sp, 8
|
|
|
|
j $24
|
|
|
|
|
|
|
|
.end raise_caml_exception
|
|
|
|
|
|
|
|
/* Callback from C to Caml */
|
|
|
|
|
|
|
|
.globl callback
|
|
|
|
.ent callback
|
|
|
|
callback:
|
|
|
|
#ifdef _PIC
|
|
|
|
.set noreorder
|
|
|
|
.cpload $25
|
|
|
|
.set reorder
|
|
|
|
#endif
|
|
|
|
/* Initial shuffling of arguments */
|
|
|
|
move $9, $4 /* closure */
|
|
|
|
move $8, $5 /* argument */
|
|
|
|
lw $24, 0($4) /* code pointer */
|
|
|
|
b $103
|
1995-12-04 02:02:14 -08:00
|
|
|
.end callback
|
|
|
|
|
|
|
|
.globl callback2
|
|
|
|
.ent callback2
|
|
|
|
callback2:
|
1997-02-01 09:40:41 -08:00
|
|
|
#ifdef _PIC
|
|
|
|
.set noreorder
|
|
|
|
.cpload $25
|
|
|
|
.set reorder
|
|
|
|
#endif
|
1995-12-04 02:02:14 -08:00
|
|
|
/* Initial shuffling of arguments */
|
|
|
|
move $10, $4 /* closure */
|
|
|
|
move $8, $5 /* first argument */
|
|
|
|
move $9, $6 /* second argument */
|
|
|
|
la $24, caml_apply2 /* code pointer */
|
|
|
|
b $103
|
|
|
|
|
|
|
|
.end callback2
|
|
|
|
|
|
|
|
.globl callback3
|
|
|
|
.ent callback3
|
|
|
|
callback3:
|
1997-02-01 09:40:41 -08:00
|
|
|
#ifdef _PIC
|
|
|
|
.set noreorder
|
|
|
|
.cpload $25
|
|
|
|
.set reorder
|
|
|
|
#endif
|
1995-12-04 02:02:14 -08:00
|
|
|
/* Initial shuffling of arguments */
|
|
|
|
move $11, $4 /* closure */
|
|
|
|
move $8, $5 /* first argument */
|
|
|
|
move $9, $6 /* second argument */
|
|
|
|
move $10, $7 /* third argument */
|
|
|
|
la $24, caml_apply3 /* code pointer */
|
|
|
|
b $103
|
|
|
|
|
|
|
|
.end callback3
|
|
|
|
|
|
|
|
.rdata
|
|
|
|
.globl system_frametable
|
|
|
|
system_frametable:
|
|
|
|
.word 1 /* one descriptor */
|
|
|
|
.word $104 + 8 /* return address into callback */
|
|
|
|
.half -1 /* negative frame size => use callback link */
|
|
|
|
.half 0 /* no roots here */
|