summaryrefslogtreecommitdiff
path: root/ocaml-binary-annot/asmrun/hppa.S
diff options
context:
space:
mode:
Diffstat (limited to 'ocaml-binary-annot/asmrun/hppa.S')
-rw-r--r--ocaml-binary-annot/asmrun/hppa.S534
1 files changed, 534 insertions, 0 deletions
diff --git a/ocaml-binary-annot/asmrun/hppa.S b/ocaml-binary-annot/asmrun/hppa.S
new file mode 100644
index 0000000000..abdd4554b8
--- /dev/null
+++ b/ocaml-binary-annot/asmrun/hppa.S
@@ -0,0 +1,534 @@
+;*********************************************************************
+;* *
+;* Objective Caml *
+;* *
+;* Xavier Leroy, projet Cristal, INRIA Rocquencourt *
+;* *
+;* Copyright 1996 Institut National de Recherche en Informatique et *
+;* en Automatique. All rights reserved. This file is distributed *
+;* under the terms of the GNU Library General Public License, with *
+;* the special exception on linking described in file ../LICENSE. *
+;* *
+;*********************************************************************
+
+; $Id$
+
+; Asm part of the runtime system for the HP PA-RISC processor.
+; Must be preprocessed by cpp
+
+#ifdef SYS_hpux
+#define G(x) x
+#define CODESPACE .code
+#define CODE_ALIGN 4
+#define EXPORT_CODE(x) .export x, entry, priv_lev=3
+#define EXPORT_DATA(x) .export x, data
+#define STARTPROC .proc ! .callinfo frame=0, no_calls ! .entry
+#define ENDPROC .exit ! .procend
+#define LOADHIGH(x) addil LR%x-$global$, %r27
+#define LOW(x) RR%x-$global$
+#define LOADHIGHLABEL(x) ldil LR%x, %r1
+#define LOWLABEL(x) RR%x
+#endif
+
+#if defined(SYS_linux) || defined(SYS_gnu)
+#define G(x) x
+#define CODESPACE .text
+#define CODE_ALIGN 8
+#define EXPORT_CODE(x) .globl x
+#define EXPORT_DATA(x) .globl x
+#define STARTPROC
+#define ENDPROC
+#define LOADHIGH(x) addil LR%x-$global$, %r27
+#define LOW(x) RR%x-$global$
+#define LOADHIGHLABEL(x) ldil LR%x, %r1
+#define LOWLABEL(x) RR%x
+#endif
+
+#ifdef SYS_hpux
+ .space $PRIVATE$
+ .subspa $DATA$,quad=1,align=8,access=31
+ .subspa $BSS$,quad=1,align=8,access=31,zero,sort=82
+ .space $TEXT$
+ .subspa $LIT$,quad=0,align=8,access=44
+ .subspa $CODE$,quad=0,align=8,access=44,code_only
+ .import $global$, data
+ .import $$dyncall, millicode
+ .import caml_garbage_collection, code
+ .import caml_program, code
+ .import caml_raise, code
+ .import caml_apply2, code
+ .import caml_apply3, code
+ .import caml_array_bound_error, code
+
+caml_young_limit .comm 8
+caml_young_ptr .comm 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
+
+#if defined(SYS_linux) || defined(SYS_gnu)
+ .align 8
+ .comm G(young_limit), 4
+ .comm G(young_ptr), 4
+ .comm G(caml_bottom_of_stack), 4
+ .comm G(caml_last_return_address), 4
+ .comm G(caml_gc_regs), 4
+ .comm G(caml_exception_pointer), 4
+ .comm G(caml_required_size), 4
+#endif
+
+; Allocation functions
+
+ CODESPACE
+ .align CODE_ALIGN
+ EXPORT_CODE(G(caml_allocN))
+G(caml_allocN):
+ STARTPROC
+; Required size in %r29
+ ldw 0(%r4), %r1
+ sub %r3, %r29, %r3
+ comb,<<,n %r3, %r1, G(caml_call_gc) ; nullify if taken (forward br.)
+ bv 0(%r2)
+ nop
+ ENDPROC
+
+ EXPORT_CODE(G(caml_call_gc))
+G(caml_call_gc):
+ STARTPROC
+; Save required size (%r29)
+ LOADHIGH(G(caml_required_size))
+ stw %r29, LOW(G(caml_required_size))(%r1)
+; Save current allocation pointer for debugging purposes
+ LOADHIGH(G(caml_young_ptr))
+ stw %r3, LOW(G(caml_young_ptr))(%r1)
+; Record lowest stack address
+ LOADHIGH(G(caml_bottom_of_stack))
+ stw %r30, LOW(G(caml_bottom_of_stack))(%r1)
+; Record return address
+ LOADHIGH(G(caml_last_return_address))
+ stw %r2, LOW(G(caml_last_return_address))(%r1)
+; 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
+L100: ldo -(64 + 4*32)(%r30), %r31
+ LOADHIGH(G(caml_gc_regs))
+ stw %r31, LOW(G(caml_gc_regs))(%r1)
+; Save all regs used by the code generator
+ copy %r31, %r1
+ stws,ma %r6, 4(%r1)
+ stws,ma %r7, 4(%r1)
+ stws,ma %r8, 4(%r1)
+ stws,ma %r9, 4(%r1)
+ stws,ma %r10, 4(%r1)
+ stws,ma %r11, 4(%r1)
+ stws,ma %r12, 4(%r1)
+ stws,ma %r13, 4(%r1)
+ stws,ma %r14, 4(%r1)
+ stws,ma %r15, 4(%r1)
+ stws,ma %r16, 4(%r1)
+ stws,ma %r17, 4(%r1)
+ stws,ma %r18, 4(%r1)
+ stws,ma %r19, 4(%r1)
+ stws,ma %r20, 4(%r1)
+ stws,ma %r21, 4(%r1)
+ stws,ma %r22, 4(%r1)
+ stws,ma %r23, 4(%r1)
+ stws,ma %r24, 4(%r1)
+ stws,ma %r25, 4(%r1)
+ stws,ma %r26, 4(%r1)
+ stws,ma %r28, 4(%r1)
+ ldo -0x1C0(%r30), %r1
+ fstds,ma %fr4, 8(%r1)
+ fstds,ma %fr5, 8(%r1)
+ fstds,ma %fr6, 8(%r1)
+ fstds,ma %fr7, 8(%r1)
+ fstds,ma %fr8, 8(%r1)
+ fstds,ma %fr9, 8(%r1)
+ fstds,ma %fr10, 8(%r1)
+ fstds,ma %fr11, 8(%r1)
+ fstds,ma %fr12, 8(%r1)
+ fstds,ma %fr13, 8(%r1)
+ fstds,ma %fr14, 8(%r1)
+ fstds,ma %fr15, 8(%r1)
+ fstds,ma %fr16, 8(%r1)
+ fstds,ma %fr17, 8(%r1)
+ fstds,ma %fr18, 8(%r1)
+ fstds,ma %fr19, 8(%r1)
+ fstds,ma %fr20, 8(%r1)
+ fstds,ma %fr21, 8(%r1)
+ fstds,ma %fr22, 8(%r1)
+ fstds,ma %fr23, 8(%r1)
+ fstds,ma %fr24, 8(%r1)
+ fstds,ma %fr25, 8(%r1)
+ fstds,ma %fr26, 8(%r1)
+ fstds,ma %fr27, 8(%r1)
+ fstds,ma %fr28, 8(%r1)
+ fstds,ma %fr29, 8(%r1)
+ fstds,ma %fr30, 8(%r1)
+
+; Call the garbage collector
+ bl G(caml_garbage_collection), %r2
+ nop
+
+; Restore all regs used by the code generator
+ ldo -(64 + 4*32)(%r30), %r1
+ ldws,ma 4(%r1), %r6
+ ldws,ma 4(%r1), %r7
+ ldws,ma 4(%r1), %r8
+ ldws,ma 4(%r1), %r9
+ ldws,ma 4(%r1), %r10
+ ldws,ma 4(%r1), %r11
+ ldws,ma 4(%r1), %r12
+ ldws,ma 4(%r1), %r13
+ ldws,ma 4(%r1), %r14
+ ldws,ma 4(%r1), %r15
+ ldws,ma 4(%r1), %r16
+ ldws,ma 4(%r1), %r17
+ ldws,ma 4(%r1), %r18
+ ldws,ma 4(%r1), %r19
+ ldws,ma 4(%r1), %r20
+ ldws,ma 4(%r1), %r21
+ ldws,ma 4(%r1), %r22
+ ldws,ma 4(%r1), %r23
+ ldws,ma 4(%r1), %r24
+ ldws,ma 4(%r1), %r25
+ ldws,ma 4(%r1), %r26
+ ldws,ma 4(%r1), %r28
+ ldo -0x1C0(%r30), %r1
+ fldds,ma 8(%r1), %fr4
+ fldds,ma 8(%r1), %fr5
+ fldds,ma 8(%r1), %fr6
+ fldds,ma 8(%r1), %fr7
+ fldds,ma 8(%r1), %fr8
+ fldds,ma 8(%r1), %fr9
+ fldds,ma 8(%r1), %fr10
+ fldds,ma 8(%r1), %fr11
+ fldds,ma 8(%r1), %fr12
+ fldds,ma 8(%r1), %fr13
+ fldds,ma 8(%r1), %fr14
+ fldds,ma 8(%r1), %fr15
+ fldds,ma 8(%r1), %fr16
+ fldds,ma 8(%r1), %fr17
+ fldds,ma 8(%r1), %fr18
+ fldds,ma 8(%r1), %fr19
+ fldds,ma 8(%r1), %fr20
+ fldds,ma 8(%r1), %fr21
+ fldds,ma 8(%r1), %fr22
+ fldds,ma 8(%r1), %fr23
+ fldds,ma 8(%r1), %fr24
+ fldds,ma 8(%r1), %fr25
+ fldds,ma 8(%r1), %fr26
+ fldds,ma 8(%r1), %fr27
+ fldds,ma 8(%r1), %fr28
+ fldds,ma 8(%r1), %fr29
+ fldds,ma 8(%r1), %fr30
+
+; Reload the allocation pointer
+ LOADHIGH(G(caml_young_ptr))
+ ldw LOW(G(caml_young_ptr))(%r1), %r3
+; Allocate space for block
+ LOADHIGH(G(caml_required_size))
+ ldw LOW(G(caml_required_size))(%r1), %r29
+ ldw 0(%r4), %r1
+ sub %r3, %r29, %r3
+ comb,<< %r3, %r1, L100
+ nop
+; Return to caller
+ LOADHIGH(G(caml_last_return_address))
+ ldw LOW(G(caml_last_return_address))(%r1), %r2
+ bv 0(%r2)
+ ldo -0x1C0(%r30), %r30
+ ENDPROC
+
+; Call a C function from Caml
+; Function to call is in %r22
+
+ .align CODE_ALIGN
+#ifdef SYS_hpux
+ .export G(caml_c_call), ENTRY, ARGW0=GR, ARGW1=GR, ARGW2=GR, ARGW3=GR
+#else
+ EXPORT_CODE(G(caml_c_call))
+#endif
+G(caml_c_call):
+ STARTPROC
+; Record lowest stack address
+ LOADHIGH(G(caml_bottom_of_stack))
+ stw %r30, LOW(G(caml_bottom_of_stack))(%r1)
+; Record return address
+ LOADHIGH(G(caml_last_return_address))
+ stw %r2, LOW(G(caml_last_return_address))(%r1)
+; Save the exception handler
+ LOADHIGH(G(caml_exception_pointer))
+ stw %r5, LOW(G(caml_exception_pointer))(%r1)
+; Save the allocation pointer
+ LOADHIGH(G(caml_young_ptr))
+ stw %r3, LOW(G(caml_young_ptr))(%r1)
+; Call the C function
+#ifdef SYS_hpux
+ bl $$dyncall, %r31
+#else
+ ble 0(4, %r22)
+#endif
+ copy %r31, %r2 ; in delay slot
+; Reload return address
+ LOADHIGH(G(caml_last_return_address))
+ ldw LOW(G(caml_last_return_address))(%r1), %r2
+; Reload allocation pointer
+ LOADHIGH(G(caml_young_ptr))
+; Return to caller
+ bv 0(%r2)
+ ldw LOW(G(caml_young_ptr))(%r1), %r3 ; in delay slot
+ ENDPROC
+
+; Start the Caml program
+
+ .align CODE_ALIGN
+ EXPORT_CODE(G(caml_start_program))
+G(caml_start_program):
+ STARTPROC
+ LOADHIGH(G(caml_program))
+ ldo LOW(G(caml_program))(%r1), %r22
+
+; Code shared with caml_callback*
+L102:
+; Save return address
+ stw %r2,-20(%r30)
+ ldo 256(%r30), %r30
+; Save the callee-save registers
+ ldo -32(%r30), %r1
+ stws,ma %r3, -4(%r1)
+ stws,ma %r4, -4(%r1)
+ stws,ma %r5, -4(%r1)
+ stws,ma %r6, -4(%r1)
+ stws,ma %r7, -4(%r1)
+ stws,ma %r8, -4(%r1)
+ stws,ma %r9, -4(%r1)
+ stws,ma %r10, -4(%r1)
+ stws,ma %r11, -4(%r1)
+ stws,ma %r12, -4(%r1)
+ stws,ma %r13, -4(%r1)
+ stws,ma %r14, -4(%r1)
+ stws,ma %r15, -4(%r1)
+ stws,ma %r16, -4(%r1)
+ stws,ma %r17, -4(%r1)
+ stws,ma %r18, -4(%r1)
+ fstds,ma %fr12, -8(%r1)
+ fstds,ma %fr13, -8(%r1)
+ fstds,ma %fr14, -8(%r1)
+ fstds,ma %fr15, -8(%r1)
+ fstds,ma %fr16, -8(%r1)
+ fstds,ma %fr17, -8(%r1)
+ fstds,ma %fr18, -8(%r1)
+ fstds,ma %fr19, -8(%r1)
+ fstds,ma %fr20, -8(%r1)
+ fstds,ma %fr21, -8(%r1)
+ fstds,ma %fr22, -8(%r1)
+ fstds,ma %fr23, -8(%r1)
+ fstds,ma %fr24, -8(%r1)
+ fstds,ma %fr25, -8(%r1)
+ fstds,ma %fr26, -8(%r1)
+ fstds,ma %fr27, -8(%r1)
+ fstds,ma %fr28, -8(%r1)
+ fstds,ma %fr29, -8(%r1)
+ fstds,ma %fr30, -8(%r1)
+ fstds,ma %fr31, -8(%r1)
+; Set up a callback link
+ ldo 16(%r30), %r30
+ LOADHIGH(G(caml_bottom_of_stack))
+ ldw LOW(G(caml_bottom_of_stack))(%r1), %r1
+ stw %r1, -16(%r30)
+ LOADHIGH(G(caml_last_return_address))
+ ldw LOW(G(caml_last_return_address))(%r1), %r1
+ 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))
+ ldw LOW(G(caml_exception_pointer))(%r1), %r1
+ stw %r1, -8(%r30)
+ LOADHIGHLABEL(L103)
+ ldo LOWLABEL(L103)(%r1), %r1
+ stw %r1, -4(%r30)
+ copy %r30, %r5
+; Reload allocation pointers
+ LOADHIGH(G(caml_young_ptr))
+ ldw LOW(G(caml_young_ptr))(%r1), %r3
+ LOADHIGH(G(caml_young_limit))
+ ldo LOW(G(caml_young_limit))(%r1), %r4
+; Call the Caml code
+ ble 0(4, %r22)
+ copy %r31, %r2
+L104:
+; Pop the trap frame
+ ldw -8(%r30), %r31
+ LOADHIGH(G(caml_exception_pointer))
+ stw %r31, LOW(G(caml_exception_pointer))(%r1)
+ ldo -8(%r30), %r30
+; Pop the callback link
+L105:
+ ldw -16(%r30), %r31
+ LOADHIGH(G(caml_bottom_of_stack))
+ stw %r31, LOW(G(caml_bottom_of_stack))(%r1)
+ ldw -12(%r30), %r31
+ LOADHIGH(G(caml_last_return_address))
+ stw %r31, LOW(G(caml_last_return_address))(%r1)
+ 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(caml_young_ptr))
+ stw %r3, LOW(G(caml_young_ptr))(%r1)
+; Move result where C function expects it
+ copy %r26, %r28
+; Reload callee-save registers
+ ldo -32(%r30), %r1
+ ldws,ma -4(%r1), %r3
+ ldws,ma -4(%r1), %r4
+ ldws,ma -4(%r1), %r5
+ ldws,ma -4(%r1), %r6
+ ldws,ma -4(%r1), %r7
+ ldws,ma -4(%r1), %r8
+ ldws,ma -4(%r1), %r9
+ ldws,ma -4(%r1), %r10
+ ldws,ma -4(%r1), %r11
+ ldws,ma -4(%r1), %r12
+ ldws,ma -4(%r1), %r13
+ ldws,ma -4(%r1), %r14
+ ldws,ma -4(%r1), %r15
+ ldws,ma -4(%r1), %r16
+ ldws,ma -4(%r1), %r17
+ ldws,ma -4(%r1), %r18
+ fldds,ma -8(%r1), %fr12
+ fldds,ma -8(%r1), %fr13
+ fldds,ma -8(%r1), %fr14
+ fldds,ma -8(%r1), %fr15
+ fldds,ma -8(%r1), %fr16
+ fldds,ma -8(%r1), %fr17
+ fldds,ma -8(%r1), %fr18
+ fldds,ma -8(%r1), %fr19
+ fldds,ma -8(%r1), %fr20
+ fldds,ma -8(%r1), %fr21
+ fldds,ma -8(%r1), %fr22
+ fldds,ma -8(%r1), %fr23
+ fldds,ma -8(%r1), %fr24
+ fldds,ma -8(%r1), %fr25
+ fldds,ma -8(%r1), %fr26
+ fldds,ma -8(%r1), %fr27
+ fldds,ma -8(%r1), %fr28
+ fldds,ma -8(%r1), %fr29
+ fldds,ma -8(%r1), %fr30
+ fldds,ma -8(%r1), %fr31
+; Return to C
+ ldo -256(%r30), %r30
+ ldw -20(%r30), %r2
+ bv 0(%r2)
+ nop
+; The trap handler
+L103:
+; Save exception pointer
+ LOADHIGH(G(caml_exception_pointer))
+ stw %r5, LOW(G(caml_exception_pointer))(%r1)
+; Encode exception bucket as an exception result and return it
+ ldi 2, %r1
+ or %r26, %r1, %r26
+; Return it
+ b L105
+ nop
+
+; Re-raise the exception through caml_raise, to clean up local C roots
+ ldo 64(%r30), %r30
+ bl G(caml_raise), %r2
+ nop
+ ENDPROC
+
+; Raise an exception from C
+
+ .align CODE_ALIGN
+ EXPORT_CODE(G(caml_raise_exception))
+G(caml_raise_exception):
+ STARTPROC
+; Cut the stack
+ LOADHIGH(G(caml_exception_pointer))
+ ldw LOW(G(caml_exception_pointer))(%r1), %r30
+; Reload allocation registers
+ LOADHIGH(G(caml_young_ptr))
+ ldw LOW(G(caml_young_ptr))(%r1), %r3
+ LOADHIGH(G(caml_young_limit))
+ ldo LOW(G(caml_young_limit))(%r1), %r4
+; Raise the exception
+ ldw -4(%r30), %r1
+ ldw -8(%r30), %r5
+ bv 0(%r1)
+ ldo -8(%r30), %r30 ; in delay slot
+ ENDPROC
+
+; Callbacks C -> ML
+
+ .align CODE_ALIGN
+ EXPORT_CODE(G(caml_callback_exn))
+G(caml_callback_exn):
+ STARTPROC
+; Initial shuffling of arguments
+ copy %r26, %r1 ; Closure
+ copy %r25, %r26 ; Argument
+ copy %r1, %r25
+ b L102
+ ldw 0(%r1), %r22 ; Code to call (in delay slot)
+ ENDPROC
+
+ .align CODE_ALIGN
+ EXPORT_CODE(G(caml_callback2_exn))
+G(caml_callback2_exn):
+ STARTPROC
+ copy %r26, %r1 ; Closure
+ copy %r25, %r26 ; First argument
+ copy %r24, %r25 ; Second argument
+ copy %r1, %r24
+ LOADHIGH(G(caml_apply2))
+ b L102
+ ldo LOW(G(caml_apply2))(%r1), %r22
+ ENDPROC
+
+ .align CODE_ALIGN
+ EXPORT_CODE(G(caml_callback3_exn))
+G(caml_callback3_exn):
+ STARTPROC
+ copy %r26, %r1 ; Closure
+ copy %r25, %r26 ; First argument
+ copy %r24, %r25 ; Second argument
+ copy %r23, %r24 ; Third argument
+ copy %r1, %r23
+ LOADHIGH(G(caml_apply3))
+ b L102
+ ldo LOW(G(caml_apply3))(%r1), %r22
+ ENDPROC
+
+ .align CODE_ALIGN
+ EXPORT_CODE(G(caml_ml_array_bound_error))
+G(caml_ml_array_bound_error):
+ STARTPROC
+; Load address of [caml_array_bound_error] in %r22
+ ldil LR%caml_array_bound_error, %r22
+ ldo RR%caml_array_bound_error(%r22), %r22
+; Reserve 48 bytes of stack space and jump to caml_c_call
+ b G(caml_c_call)
+ ldo 48(%r30), %r30 /* in delay slot */
+ ENDPROC
+
+ .data
+ EXPORT_DATA(G(caml_system__frametable))
+G(caml_system__frametable):
+ .long 1 /* one descriptor */
+ .long L104 + 3 /* return address into callback */
+ .short -1 /* negative frame size => use callback link */
+ .short 0 /* no roots */