summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXavier Leroy <xavier.leroy@inria.fr>1995-07-28 11:42:43 +0000
committerXavier Leroy <xavier.leroy@inria.fr>1995-07-28 11:42:43 +0000
commit9f6a960dd5940857003d18a6948adbe3a606c23a (patch)
treeb2887ebdefd5db59fb2929da1a92abc785864da5
parent6d211f7692251c1d4a9a77018f80898b45110d3a (diff)
Introduction de sparc.asm
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@161 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
-rw-r--r--asmrun/sparc.asm200
1 files changed, 200 insertions, 0 deletions
diff --git a/asmrun/sparc.asm b/asmrun/sparc.asm
new file mode 100644
index 000000000..9ce01fca5
--- /dev/null
+++ b/asmrun/sparc.asm
@@ -0,0 +1,200 @@
+/* Asm part of the runtime system for the Sparc processor. */
+
+ .common _young_start, 4, "data"
+ .common _young_end, 4, "data"
+ .common _young_ptr, 4, "data"
+ .common _gc_entry_regs, 22 * 4, "data"
+ .common _gc_entry_float_regs, 30 * 4, "data"
+ .common _caml_top_of_stack, 4, "data"
+ .common _caml_bottom_of_stack, 4, "data"
+ .common _caml_last_return_address, 4, "data"
+ .common _caml_exception_pointer, 4, "data"
+ .common _caml_required_size, 4, "data"
+
+/* libc functions appear to clobber %g2 ... %g7 */
+/* Remember to save and restore %g5 %g6 %g7. */
+
+#define Load(symb,reg) sethi %hi(symb), %g1; ld [%g1 + %lo(symb)], reg
+#define Store(reg,symb) sethi %hi(symb), %g1; st reg, [%g1 + %lo(symb)]
+
+/* Allocation functions */
+
+ .text
+ .global _caml_alloc
+ .global _caml_call_gc
+
+/* Required size in %g4 */
+_caml_alloc:
+ sub %g6, %g4, %g6
+ cmp %g6, %g7
+ blu _caml_call_gc
+ nop
+ retl
+ nop
+
+/* Required size in %g4 */
+_caml_call_gc:
+ /* Save %g4 (required size) */
+ Store(%g4, _caml_required_size)
+ /* Save %g5 (exception pointer) */
+ Store(%g5, _caml_exception_pointer)
+ /* Save current allocation pointer for debugging purposes */
+ Store(%g6, _young_ptr)
+ /* Record lowest stack address */
+ Store(%sp, _caml_bottom_of_stack)
+ /* Record last return address */
+ Store(%o7, _caml_last_return_address)
+ /* Save all regs used by the code generator */
+ sethi %hi(_gc_entry_regs), %g1
+ or %g1, %lo(_gc_entry_regs), %g1
+ std %l0, [%g1]
+ std %l2, [%g1 + 0x8]
+ std %l4, [%g1 + 0x10]
+ std %l6, [%g1 + 0x18]
+ std %o0, [%g1 + 0x20]
+ std %o2, [%g1 + 0x28]
+ std %o4, [%g1 + 0x30]
+ std %i0, [%g1 + 0x38]
+ std %i2, [%g1 + 0x40]
+ std %i4, [%g1 + 0x48]
+ std %g2, [%g1 + 0x50]
+ sethi %hi(_gc_entry_float_regs), %g1
+ or %g1, %lo(_gc_entry_float_regs), %g1
+ std %f0, [%g1]
+ std %f2, [%g1 + 0x8]
+ std %f4, [%g1 + 0x10]
+ std %f6, [%g1 + 0x18]
+ std %f8, [%g1 + 0x20]
+ std %f10, [%g1 + 0x28]
+ std %f12, [%g1 + 0x30]
+ std %f14, [%g1 + 0x38]
+ std %f16, [%g1 + 0x40]
+ std %f18, [%g1 + 0x48]
+ std %f20, [%g1 + 0x50]
+ std %f22, [%g1 + 0x58]
+ std %f24, [%g1 + 0x60]
+ std %f26, [%g1 + 0x68]
+ std %f28, [%g1 + 0x70]
+ /* Call the garbage collector */
+ call _minor_collection
+ nop
+ /* Restore all regs used by the code generator */
+ sethi %hi(_gc_entry_regs), %g1
+ or %g1, %lo(_gc_entry_regs), %g1
+ ldd [%g1], %l0
+ ldd [%g1 + 0x8], %l2
+ ldd [%g1 + 0x10], %l4
+ ldd [%g1 + 0x18], %l6
+ ldd [%g1 + 0x20], %o0
+ ldd [%g1 + 0x28], %o2
+ ldd [%g1 + 0x30], %o4
+ ldd [%g1 + 0x38], %i0
+ ldd [%g1 + 0x40], %i2
+ ldd [%g1 + 0x48], %i4
+ ldd [%g1 + 0x50], %g2
+ sethi %hi(_gc_entry_float_regs), %g1
+ or %g1, %lo(_gc_entry_float_regs), %g1
+ ldd [%g1], %f0
+ ldd [%g1 + 0x8], %f2
+ ldd [%g1 + 0x10], %f4
+ ldd [%g1 + 0x18], %f6
+ ldd [%g1 + 0x20], %f8
+ ldd [%g1 + 0x28], %f10
+ ldd [%g1 + 0x30], %f12
+ ldd [%g1 + 0x38], %f14
+ ldd [%g1 + 0x40], %f16
+ ldd [%g1 + 0x48], %f18
+ ldd [%g1 + 0x50], %f20
+ ldd [%g1 + 0x58], %f22
+ ldd [%g1 + 0x60], %f24
+ ldd [%g1 + 0x68], %f26
+ ldd [%g1 + 0x70], %f28
+ /* Reload %g5 - %g7 registers */
+ Load(_caml_exception_pointer, %g5)
+ Load(_young_ptr, %g6)
+ Load(_young_start, %g7)
+ /* Allocate space for block */
+ Load(_caml_required_size, %g4)
+ sub %g6, %g4, %g6
+ /* Return to caller */
+ Load(_caml_last_return_address, %o7)
+ retl
+ nop
+
+/* Call a C function from Caml */
+
+ .global _caml_c_call
+/* Function to call is in %g4 */
+_caml_c_call:
+ /* 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(%g5, _caml_exception_pointer)
+ sethi %hi(_young_ptr), %g1
+ /* Call the C function */
+ call %g4
+ st %g6, [%g1 + %lo(_young_ptr)] /* in delay slot */
+ /* Reload return address */
+ Load(_caml_last_return_address, %o7)
+ /* Reload %g5 - %g7 */
+ Load(_caml_exception_pointer, %g5)
+ Load(_young_ptr, %g6)
+ sethi %hi(_young_start), %g1
+ /* Return to caller */
+ retl
+ ld [%g1 + %lo(_young_start)], %g7 /* in delay slot */
+
+/* Start the Caml program */
+
+ .global _caml_start_program
+_caml_start_program:
+ /* Save all callee-save registers */
+ save %sp, -96, %sp
+ /* Build an exception handler */
+ call L100
+ nop
+ b L101
+ mov %o0, %i0 /* return exn bucket */
+L100: sub %sp, 8, %sp
+ st %o7, [%sp + 96]
+ mov %sp, %g5
+ /* Record highest stack address */
+ Store(%sp, _caml_top_of_stack)
+ /* Initialize allocation registers */
+ Load(_young_ptr, %g6)
+ Load(_young_start, %g7)
+ /* Go for it */
+ call _caml_program
+ nop
+ /* Pop handler */
+ add %sp, 8, %sp
+ /* Return with zero code */
+ mov %g0, %i0
+L101: ret
+ restore
+
+/* Raise an exception from C */
+
+ .global _raise_caml_exception
+_raise_caml_exception:
+ /* Reload %g5 - %g7 */
+ Load(_caml_exception_pointer, %g5)
+ Load(_young_ptr, %g6)
+ Load(_young_start, %g7)
+ /* Save exception bucket in a register outside the reg windows */
+ mov %o0, %g4
+ /* Pop some frames until the trap pointer is in the current frame. */
+ cmp %g5, %fp
+ blt L107 /* if Trap_handler_reg < %fp, over */
+ nop
+L106: restore
+ cmp %fp, %g5 /* if %fp <= Trap_handler_reg, loop */
+ ble L106
+ nop
+L107: mov %g5, %sp
+ ldd [%sp+96], %g4
+ add %sp, 8, %sp
+ jmp %g4 + 8
+ /* Restore bucket, in delay slot */
+ mov %g4, %o0