summaryrefslogtreecommitdiff
path: root/ext/systemc/src/sysc/qt/md/hppa.s
diff options
context:
space:
mode:
Diffstat (limited to 'ext/systemc/src/sysc/qt/md/hppa.s')
-rw-r--r--ext/systemc/src/sysc/qt/md/hppa.s237
1 files changed, 237 insertions, 0 deletions
diff --git a/ext/systemc/src/sysc/qt/md/hppa.s b/ext/systemc/src/sysc/qt/md/hppa.s
new file mode 100644
index 000000000..84d8e875b
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/hppa.s
@@ -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