]> git.donarmstrong.com Git - lilypond.git/blobdiff - guile18/qt/md/hppa.s
Import guile-1.8 as multiple upstream tarball component
[lilypond.git] / guile18 / qt / md / hppa.s
diff --git a/guile18/qt/md/hppa.s b/guile18/qt/md/hppa.s
new file mode 100644 (file)
index 0000000..84d8e87
--- /dev/null
@@ -0,0 +1,237 @@
+; pa-risc.s -- assembly support.
+
+; QuickThreads -- Threads-building toolkit.
+; Copyright (c) 1993 by David Keppel
+;
+; Permission to use, copy, modify and distribute this software and
+; its documentation for any purpose and without fee is hereby
+; granted, provided that the above copyright notice and this notice
+; appear in all copies.  This software is provided as a
+; proof-of-concept and for demonstration purposes; there is no
+; representation about the suitability of this software for any
+; purpose.
+
+; This file (pa-risc.s) is part of the port of QuickThreads for
+; PA-RISC 1.1 architecture.  This file implements context switches
+; and thread startup.  It was written in 1994 by Uwe Reder
+; (`uereder@cip.informatik.uni-erlangen.de') for the Operating
+; Systems Department (IMMD4) at the University of Erlangen/Nuernberg
+; Germany.
+
+
+; Callee saves general registers gr3..gr18,
+;              floating-point registers fr12..fr21.
+
+            .CODE
+
+            .IMPORT $$dyncall, MILLICODE
+            .IMPORT qt_error, CODE
+
+            .EXPORT qt_blocki, ENTRY
+            .EXPORT qt_block, ENTRY
+            .EXPORT qt_abort, ENTRY
+            .EXPORT qt_start, ENTRY
+            .EXPORT qt_vstart, ENTRY
+
+
+; arg0: ptr to function (helper) to call once curr is suspended
+;       and control is on arg3's stack.
+; arg1: 1'th arg to *arg0.
+; arg2: 2'th arg to *arg0.
+; arg3: sp of new thread.
+
+qt_blocki
+            .PROC
+            .CALLINFO   CALLER, FRAME=0, SAVE_RP, ENTRY_GR=18
+            .ENTRY
+
+            stw         %rp,-20(%sp)    ; save rp to old frame-marker
+
+            stwm        %r3,128(%sp)    ; save callee-saves general registers
+            stw         %r4,-124(%sp)
+            stw         %r5,-120(%sp)
+            stw         %r6,-116(%sp)
+            stw         %r7,-112(%sp)
+            stw         %r8,-108(%sp)
+            stw         %r9,-104(%sp)
+            stw         %r10,-100(%sp)
+            stw         %r11,-96(%sp)
+            stw         %r12,-92(%sp)
+            stw         %r13,-88(%sp)
+            stw         %r14,-84(%sp)
+            stw         %r15,-80(%sp)
+            stw         %r16,-76(%sp)
+            stw         %r17,-72(%sp)
+            stw         %r18,-68(%sp)
+
+qt_abort
+            copy        %arg0,%r22      ; helper to be called by $$dyncall
+            copy        %sp,%arg0       ; pass current sp as arg0 to helper
+            copy        %arg3,%sp       ; set new sp
+
+            .CALL
+            bl          $$dyncall,%mrp  ; call helper
+            copy        %mrp,%rp
+
+            ldw         -68(%sp),%r18   ; restore general registers
+            ldw         -72(%sp),%r17
+            ldw         -76(%sp),%r16
+            ldw         -80(%sp),%r15
+            ldw         -84(%sp),%r14
+            ldw         -88(%sp),%r13
+            ldw         -92(%sp),%r12
+            ldw         -96(%sp),%r11
+            ldw         -100(%sp),%r10
+            ldw         -104(%sp),%r9
+            ldw         -108(%sp),%r8
+            ldw         -112(%sp),%r7
+            ldw         -116(%sp),%r6
+            ldw         -120(%sp),%r5
+            ldw         -124(%sp),%r4
+
+            ldw         -148(%sp),%rp   ; restore return-pointer
+
+            bv          %r0(%rp)        ; return to caller
+            ldwm        -128(%sp),%r3
+
+            .EXIT
+            .PROCEND
+
+
+qt_block
+            .PROC
+            .CALLINFO   CALLER, FRAME=0, SAVE_RP, ENTRY_FR=21
+            .ENTRY
+
+            stw         %rp,-20(%sp)    ; save rp to old frame-marker
+
+            fstds,ma    %fr12,8(%sp)    ; save callee-saves float registers
+            fstds,ma    %fr13,8(%sp)
+            fstds,ma    %fr14,8(%sp)
+            fstds,ma    %fr15,8(%sp)
+            fstds,ma    %fr16,8(%sp)
+            fstds,ma    %fr17,8(%sp)
+            fstds,ma    %fr18,8(%sp)
+            fstds,ma    %fr19,8(%sp)
+            fstds,ma    %fr20,8(%sp)
+            fstds,ma    %fr21,8(%sp)
+
+            .CALL
+            bl          qt_blocki,%rp
+            ldo         48(%sp),%sp
+
+            ldo         -48(%sp),%sp
+
+            fldds,mb    -8(%sp),%fr21   ; restore callee-saves float registers
+            fldds,mb    -8(%sp),%fr20
+            fldds,mb    -8(%sp),%fr19
+            fldds,mb    -8(%sp),%fr18
+            fldds,mb    -8(%sp),%fr17
+            fldds,mb    -8(%sp),%fr16
+            fldds,mb    -8(%sp),%fr15
+            fldds,mb    -8(%sp),%fr14
+            fldds,mb    -8(%sp),%fr13
+
+            ldw         -28(%sp),%rp    ; restore return-pointer
+            
+            bv          %r0(%rp)        ; return to caller.
+            fldds,mb    -8(%sp),%fr12
+            
+            .EXIT
+            .PROCEND
+
+
+qt_start
+            .PROC
+            .CALLINFO   CALLER, FRAME=0
+            .ENTRY
+
+            copy        %r18,%arg0      ; set user arg `pu'.
+            copy        %r17,%arg1      ; ... user function pt.
+            copy        %r16,%arg2      ; ... user function userf.
+                                        ; %r22 is a caller-saves register
+            copy        %r15,%r22       ; function to be called by $$dyncall
+
+            .CALL                       ; in=%r22
+            bl          $$dyncall,%mrp  ; call `only'.
+            copy        %mrp,%rp
+            
+            bl,n        qt_error,%r0    ; `only' erroniously returned.
+
+            .EXIT
+            .PROCEND
+
+
+; Varargs
+;
+; First, call `startup' with the `pt' argument.
+;
+; Next, call the user's function with all arguments.
+; We don't know whether arguments are integers, 32-bit floating-points or
+; even 64-bit floating-points, so we reload all the registers, possibly
+; with garbage arguments.  The thread creator provided non-garbage for
+; the arguments that the callee actually uses, so the callee never gets
+; garbage.
+;
+;            -48    -44    -40    -36    -32
+;             | arg3 | arg2 | arg1 | arg0 |
+;             -----------------------------
+; integers:     arg3   arg2   arg1   arg0
+; 32-bit fps:  farg3  farg2  farg1  farg0
+; 64-bit fps:  <---farg3-->  <---farg1-->
+;
+; Finally, call `cleanup' with the `pt' argument and with the return value
+; from the user's function.  It is an error for `cleanup' to return.
+
+qt_vstart
+            .PROC
+            .CALLINFO   CALLER, FRAME=0
+            .ENTRY
+
+            ; Because the startup function may damage the fixed arguments
+            ; on the stack (PA-RISC Procedure Calling Conventions Reference
+            ; Manual, 2.4 Fixed Arguments Area), we allocate a seperate
+            ; stack frame for it.
+            ldo         64(%sp),%sp
+
+            ; call: void startup(void *pt)
+
+            copy        %r15,%arg0      ; `pt' is arg0 to `startup'.
+            copy        %r16,%r22
+            .CALL
+            bl          $$dyncall,%mrp  ; Call `startup'.
+            copy        %mrp,%rp
+
+            ldo         -64(%sp),%sp
+
+            ; call: void *qt_vuserf_t(...)
+
+            ldw         -36(%sp),%arg0  ; Load args to integer registers.
+            ldw         -40(%sp),%arg1
+            ldw         -44(%sp),%arg2
+            ldw         -48(%sp),%arg3
+            ; Index of fld[w|d]s only ranges from -16 to 15, so we
+            ; take r22 to be our new base register.
+            ldo         -32(%sp),%r22
+            fldws       -4(%r22),%farg0 ; Load args to floating-point registers.
+            fldds       -8(%r22),%farg1
+            fldws       -12(%r22),%farg2
+            fldds       -16(%r22),%farg3
+            copy        %r17,%r22
+            .CALL
+            bl          $$dyncall,%mrp  ; Call `userf'.
+            copy        %mrp,%rp
+
+            ; call: void cleanup(void *pt, void *vuserf_return)
+
+            copy        %r15,%arg0      ; `pt' is arg0 to `cleanup'.
+            copy        %ret0,%arg1     ; Return-value is arg1 to `cleanup'.
+            copy        %r18,%r22
+            .CALL
+            bl          $$dyncall,%mrp  ; Call `cleanup'.
+            copy        %mrp,%rp
+
+            bl,n        qt_error,%r0
+
+            .EXIT
+            .PROCEND