1; pa-risc.s -- assembly support. 2 3; QuickThreads -- Threads-building toolkit. 4; Copyright (c) 1993 by David Keppel 5; 6; Permission to use, copy, modify and distribute this software and 7; its documentation for any purpose and without fee is hereby 8; granted, provided that the above copyright notice and this notice 9; appear in all copies. This software is provided as a 10; proof-of-concept and for demonstration purposes; there is no 11; representation about the suitability of this software for any 12; purpose. 13 14; This file (pa-risc.s) is part of the port of QuickThreads for 15; PA-RISC 1.1 architecture. This file implements context switches 16; and thread startup. It was written in 1994 by Uwe Reder 17; (`uereder@cip.informatik.uni-erlangen.de') for the Operating 18; Systems Department (IMMD4) at the University of Erlangen/Nuernberg 19; Germany. 20 21 22; Callee saves general registers gr3..gr18, 23; floating-point registers fr12..fr21. 24 25 .CODE 26 27 .IMPORT $$dyncall, MILLICODE 28 .IMPORT qt_error, CODE 29 30 .EXPORT qt_blocki, ENTRY 31 .EXPORT qt_block, ENTRY 32 .EXPORT qt_abort, ENTRY 33 .EXPORT qt_start, ENTRY 34 .EXPORT qt_vstart, ENTRY 35 36 37; arg0: ptr to function (helper) to call once curr is suspended 38; and control is on arg3's stack. 39; arg1: 1'th arg to *arg0. 40; arg2: 2'th arg to *arg0. 41; arg3: sp of new thread. 42 43qt_blocki 44 .PROC 45 .CALLINFO CALLER, FRAME=0, SAVE_RP, ENTRY_GR=18 46 .ENTRY 47 48 stw %rp,-20(%sp) ; save rp to old frame-marker 49 50 stwm %r3,128(%sp) ; save callee-saves general registers 51 stw %r4,-124(%sp) 52 stw %r5,-120(%sp) 53 stw %r6,-116(%sp) 54 stw %r7,-112(%sp) 55 stw %r8,-108(%sp) 56 stw %r9,-104(%sp) 57 stw %r10,-100(%sp) 58 stw %r11,-96(%sp) 59 stw %r12,-92(%sp) 60 stw %r13,-88(%sp) 61 stw %r14,-84(%sp) 62 stw %r15,-80(%sp) 63 stw %r16,-76(%sp) 64 stw %r17,-72(%sp) 65 stw %r18,-68(%sp) 66 67qt_abort 68 copy %arg0,%r22 ; helper to be called by $$dyncall 69 copy %sp,%arg0 ; pass current sp as arg0 to helper 70 copy %arg3,%sp ; set new sp 71 72 .CALL 73 bl $$dyncall,%mrp ; call helper 74 copy %mrp,%rp 75 76 ldw -68(%sp),%r18 ; restore general registers 77 ldw -72(%sp),%r17 78 ldw -76(%sp),%r16 79 ldw -80(%sp),%r15 80 ldw -84(%sp),%r14 81 ldw -88(%sp),%r13 82 ldw -92(%sp),%r12 83 ldw -96(%sp),%r11 84 ldw -100(%sp),%r10 85 ldw -104(%sp),%r9 86 ldw -108(%sp),%r8 87 ldw -112(%sp),%r7 88 ldw -116(%sp),%r6 89 ldw -120(%sp),%r5 90 ldw -124(%sp),%r4 91 92 ldw -148(%sp),%rp ; restore return-pointer 93 94 bv %r0(%rp) ; return to caller 95 ldwm -128(%sp),%r3 96 97 .EXIT 98 .PROCEND 99 100 101qt_block 102 .PROC 103 .CALLINFO CALLER, FRAME=0, SAVE_RP, ENTRY_FR=21 104 .ENTRY 105 106 stw %rp,-20(%sp) ; save rp to old frame-marker 107 108 fstds,ma %fr12,8(%sp) ; save callee-saves float registers 109 fstds,ma %fr13,8(%sp) 110 fstds,ma %fr14,8(%sp) 111 fstds,ma %fr15,8(%sp) 112 fstds,ma %fr16,8(%sp) 113 fstds,ma %fr17,8(%sp) 114 fstds,ma %fr18,8(%sp) 115 fstds,ma %fr19,8(%sp) 116 fstds,ma %fr20,8(%sp) 117 fstds,ma %fr21,8(%sp) 118 119 .CALL 120 bl qt_blocki,%rp 121 ldo 48(%sp),%sp 122 123 ldo -48(%sp),%sp 124 125 fldds,mb -8(%sp),%fr21 ; restore callee-saves float registers 126 fldds,mb -8(%sp),%fr20 127 fldds,mb -8(%sp),%fr19 128 fldds,mb -8(%sp),%fr18 129 fldds,mb -8(%sp),%fr17 130 fldds,mb -8(%sp),%fr16 131 fldds,mb -8(%sp),%fr15 132 fldds,mb -8(%sp),%fr14 133 fldds,mb -8(%sp),%fr13 134 135 ldw -28(%sp),%rp ; restore return-pointer 136 137 bv %r0(%rp) ; return to caller. 138 fldds,mb -8(%sp),%fr12 139 140 .EXIT 141 .PROCEND 142 143 144qt_start 145 .PROC 146 .CALLINFO CALLER, FRAME=0 147 .ENTRY 148 149 copy %r18,%arg0 ; set user arg `pu'. 150 copy %r17,%arg1 ; ... user function pt. 151 copy %r16,%arg2 ; ... user function userf. 152 ; %r22 is a caller-saves register 153 copy %r15,%r22 ; function to be called by $$dyncall 154 155 .CALL ; in=%r22 156 bl $$dyncall,%mrp ; call `only'. 157 copy %mrp,%rp 158 159 bl,n qt_error,%r0 ; `only' erroniously returned. 160 161 .EXIT 162 .PROCEND 163 164 165; Varargs 166; 167; First, call `startup' with the `pt' argument. 168; 169; Next, call the user's function with all arguments. 170; We don't know whether arguments are integers, 32-bit floating-points or 171; even 64-bit floating-points, so we reload all the registers, possibly 172; with garbage arguments. The thread creator provided non-garbage for 173; the arguments that the callee actually uses, so the callee never gets 174; garbage. 175; 176; -48 -44 -40 -36 -32 177; | arg3 | arg2 | arg1 | arg0 | 178; ----------------------------- 179; integers: arg3 arg2 arg1 arg0 180; 32-bit fps: farg3 farg2 farg1 farg0 181; 64-bit fps: <---farg3--> <---farg1--> 182; 183; Finally, call `cleanup' with the `pt' argument and with the return value 184; from the user's function. It is an error for `cleanup' to return. 185 186qt_vstart 187 .PROC 188 .CALLINFO CALLER, FRAME=0 189 .ENTRY 190 191 ; Because the startup function may damage the fixed arguments 192 ; on the stack (PA-RISC Procedure Calling Conventions Reference 193 ; Manual, 2.4 Fixed Arguments Area), we allocate a seperate 194 ; stack frame for it. 195 ldo 64(%sp),%sp 196 197 ; call: void startup(void *pt) 198 199 copy %r15,%arg0 ; `pt' is arg0 to `startup'. 200 copy %r16,%r22 201 .CALL 202 bl $$dyncall,%mrp ; Call `startup'. 203 copy %mrp,%rp 204 205 ldo -64(%sp),%sp 206 207 ; call: void *qt_vuserf_t(...) 208 209 ldw -36(%sp),%arg0 ; Load args to integer registers. 210 ldw -40(%sp),%arg1 211 ldw -44(%sp),%arg2 212 ldw -48(%sp),%arg3 213 ; Index of fld[w|d]s only ranges from -16 to 15, so we 214 ; take r22 to be our new base register. 215 ldo -32(%sp),%r22 216 fldws -4(%r22),%farg0 ; Load args to floating-point registers. 217 fldds -8(%r22),%farg1 218 fldws -12(%r22),%farg2 219 fldds -16(%r22),%farg3 220 copy %r17,%r22 221 .CALL 222 bl $$dyncall,%mrp ; Call `userf'. 223 copy %mrp,%rp 224 225 ; call: void cleanup(void *pt, void *vuserf_return) 226 227 copy %r15,%arg0 ; `pt' is arg0 to `cleanup'. 228 copy %ret0,%arg1 ; Return-value is arg1 to `cleanup'. 229 copy %r18,%r22 230 .CALL 231 bl $$dyncall,%mrp ; Call `cleanup'. 232 copy %mrp,%rp 233 234 bl,n qt_error,%r0 235 236 .EXIT 237 .PROCEND 238