mips-irix5.s revision 12027:1eb7dc7aa10b
111666Stushar@ece.gatech.edu/* mips.s -- assembly support. */ 211666Stushar@ece.gatech.edu 311666Stushar@ece.gatech.edu/* 411666Stushar@ece.gatech.edu * QuickThreads -- Threads-building toolkit. 511666Stushar@ece.gatech.edu * Copyright (c) 1993 by David Keppel 611666Stushar@ece.gatech.edu * 711666Stushar@ece.gatech.edu * Permission to use, copy, modify and distribute this software and 811666Stushar@ece.gatech.edu * its documentation for any purpose and without fee is hereby 911666Stushar@ece.gatech.edu * granted, provided that the above copyright notice and this notice 1011666Stushar@ece.gatech.edu * appear in all copies. This software is provided as a 1111666Stushar@ece.gatech.edu * proof-of-concept and for demonstration purposes; there is no 1211666Stushar@ece.gatech.edu * representation about the suitability of this software for any 1311666Stushar@ece.gatech.edu * purpose. 1411666Stushar@ece.gatech.edu */ 1511666Stushar@ece.gatech.edu 1611666Stushar@ece.gatech.edu/* Callee-save $16-$23, $30-$31. 1711666Stushar@ece.gatech.edu * 1811666Stushar@ece.gatech.edu * $25 is used as a procedure value pointer, used to discover constants 1911666Stushar@ece.gatech.edu * in a callee. Thus, each caller here sets $25 before the call. 2011666Stushar@ece.gatech.edu * 2111666Stushar@ece.gatech.edu * On startup, restore regs so retpc === call to a function to start. 2211666Stushar@ece.gatech.edu * We're going to call a function ($4) from within this routine. 2311666Stushar@ece.gatech.edu * We're passing 3 args, therefore need to allocate 12 extra bytes on 2411666Stushar@ece.gatech.edu * the stack for a save area. The start routine needs a like 16-byte 2511666Stushar@ece.gatech.edu * save area. Must be doubleword aligned (_mips r3000 risc 2611666Stushar@ece.gatech.edu * architecture_, gerry kane, pg d-23). 2711666Stushar@ece.gatech.edu */ 2811666Stushar@ece.gatech.edu 2911666Stushar@ece.gatech.edu/* 3011666Stushar@ece.gatech.edu * Modified by Assar Westerlund <assar@sics.se> to support Irix 5.x 3111666Stushar@ece.gatech.edu * calling conventions for dynamically-linked code. 3211666Stushar@ece.gatech.edu */ 3311666Stushar@ece.gatech.edu 3412492Sodanrc@yahoo.com.br /* Make this position-independent code. */ 3512492Sodanrc@yahoo.com.br .option pic2 3611666Stushar@ece.gatech.edu 3711666Stushar@ece.gatech.edu .globl qt_block 3811666Stushar@ece.gatech.edu .globl qt_blocki 3911666Stushar@ece.gatech.edu .globl qt_abort 4011666Stushar@ece.gatech.edu .globl qt_start 4111666Stushar@ece.gatech.edu .globl qt_vstart 4211666Stushar@ece.gatech.edu 4311666Stushar@ece.gatech.edu /* 4411666Stushar@ece.gatech.edu ** $4: ptr to function to call once curr is suspended 4511666Stushar@ece.gatech.edu ** and control is on $7's stack. 4611666Stushar@ece.gatech.edu ** $5: 1'th arg to $4. 4711666Stushar@ece.gatech.edu ** $6: 2'th arg to $4 4811666Stushar@ece.gatech.edu ** $7: sp of thread to suspend. 4911666Stushar@ece.gatech.edu ** 5011666Stushar@ece.gatech.edu ** Totally gross hack: The MIPS calling convention reserves 5111666Stushar@ece.gatech.edu ** 4 words on the stack for a0..a3. This routine "ought" to 5211666Stushar@ece.gatech.edu ** allocate space for callee-save registers plus 4 words for 5311666Stushar@ece.gatech.edu ** the helper function, but instead we use the 4 words 5411666Stushar@ece.gatech.edu ** provided by the function that called us (we don't need to 5511666Stushar@ece.gatech.edu ** save our argument registers). So what *appears* to be 5611666Stushar@ece.gatech.edu ** allocating only 40 bytes is actually allocating 56, by 5711666Stushar@ece.gatech.edu ** using the caller's 16 bytes. 5811666Stushar@ece.gatech.edu ** 5911666Stushar@ece.gatech.edu ** The helper routine returns a value that is passed on as the 6011666Stushar@ece.gatech.edu ** return value from the blocking routine. Since we don't 6111666Stushar@ece.gatech.edu ** touch $2 between the helper's return and the end of 6211666Stushar@ece.gatech.edu ** function, we get this behavior for free. 6311666Stushar@ece.gatech.edu */ 6411666Stushar@ece.gatech.eduqt_blocki: 6511666Stushar@ece.gatech.edu sub $sp,$sp,40 /* Allocate reg save space. */ 6611666Stushar@ece.gatech.edu sw $16, 0+16($sp) 6711666Stushar@ece.gatech.edu sw $17, 4+16($sp) 6811666Stushar@ece.gatech.edu sw $18, 8+16($sp) 6911666Stushar@ece.gatech.edu sw $19,12+16($sp) 7011666Stushar@ece.gatech.edu sw $20,16+16($sp) 7111666Stushar@ece.gatech.edu sw $21,20+16($sp) 7211666Stushar@ece.gatech.edu sw $22,24+16($sp) 7311666Stushar@ece.gatech.edu sw $23,28+16($sp) 7411666Stushar@ece.gatech.edu sw $30,32+16($sp) 7511666Stushar@ece.gatech.edu sw $31,36+16($sp) 7611666Stushar@ece.gatech.edu add $2, $sp,$0 /* $2 <= old sp to pass to func@$4. */ 7711666Stushar@ece.gatech.eduqt_abort: 7811666Stushar@ece.gatech.edu add $sp, $7,$0 /* $sp <= new sp. */ 7911666Stushar@ece.gatech.edu .set noreorder 8011666Stushar@ece.gatech.edu add $25, $4,$0 /* Set helper function procedure value. */ 8111666Stushar@ece.gatech.edu jal $31,$25 /* Call helper func@$4 . */ 8211666Stushar@ece.gatech.edu add $4, $2,$0 /* $a0 <= pass old sp as a parameter. */ 8311666Stushar@ece.gatech.edu .set reorder 8411666Stushar@ece.gatech.edu lw $31,36+16($sp) /* Restore callee-save regs... */ 8511666Stushar@ece.gatech.edu lw $30,32+16($sp) 8611666Stushar@ece.gatech.edu lw $23,28+16($sp) 8711666Stushar@ece.gatech.edu lw $22,24+16($sp) 8811666Stushar@ece.gatech.edu lw $21,20+16($sp) 8911666Stushar@ece.gatech.edu lw $20,16+16($sp) 9011666Stushar@ece.gatech.edu lw $19,12+16($sp) 9111666Stushar@ece.gatech.edu lw $18, 8+16($sp) 9211666Stushar@ece.gatech.edu lw $17, 4+16($sp) 9311666Stushar@ece.gatech.edu lw $16, 0+16($sp) /* Restore callee-save */ 9411666Stushar@ece.gatech.edu 9511666Stushar@ece.gatech.edu add $sp,$sp,40 /* Deallocate reg save space. */ 9611666Stushar@ece.gatech.edu j $31 /* Return to caller. */ 9711666Stushar@ece.gatech.edu 9811666Stushar@ece.gatech.edu /* 9911666Stushar@ece.gatech.edu ** Non-varargs thread startup. 10011666Stushar@ece.gatech.edu ** Note: originally, 56 bytes were allocated on the stack. 10111666Stushar@ece.gatech.edu ** The thread restore routine (_blocki/_abort) removed 40 10211666Stushar@ece.gatech.edu ** of them, which means there is still 16 bytes for the 10311666Stushar@ece.gatech.edu ** argument area required by the MIPS calling convention. 10411666Stushar@ece.gatech.edu */ 10511666Stushar@ece.gatech.eduqt_start: 10611666Stushar@ece.gatech.edu add $4, $16,$0 /* Load up user function pu. */ 10711666Stushar@ece.gatech.edu add $5, $17,$0 /* ... user function pt. */ 10811666Stushar@ece.gatech.edu add $6, $18,$0 /* ... user function userf. */ 10911666Stushar@ece.gatech.edu add $25, $19,$0 /* Set `only' procedure value. */ 11011666Stushar@ece.gatech.edu jal $31,$25 /* Call `only'. */ 11111666Stushar@ece.gatech.edu la $25,qt_error /* Set `qt_error' procedure value. */ 11211666Stushar@ece.gatech.edu j $25 11312492Sodanrc@yahoo.com.br 114 115 /* 116 ** Save calle-save floating-point regs $f20-$f30 117 ** See comment in `qt_block' about calling conventinos and 118 ** reserved space. Use the same trick here, but here we 119 ** actually have to allocate all the bytes since we have to 120 ** leave 4 words leftover for `qt_blocki'. 121 ** 122 ** Return value from `qt_block' is the same as the return from 123 ** `qt_blocki'. We get that for free since we don't touch $2 124 ** between the return from `qt_blocki' and the return from 125 ** `qt_block'. 126 */ 127qt_block: 128 sub $sp, $sp,56 /* 6 8-byte regs, saved ret pc, aligned. */ 129 swc1 $f20, 0+16($sp) 130 swc1 $f22, 8+16($sp) 131 swc1 $f24, 16+16($sp) 132 swc1 $f26, 24+16($sp) 133 swc1 $f28, 32+16($sp) 134 swc1 $f30, 40+16($sp) 135 sw $31, 48+16($sp) 136 jal qt_blocki 137 lwc1 $f20, 0+16($sp) 138 lwc1 $f22, 8+16($sp) 139 lwc1 $f24, 16+16($sp) 140 lwc1 $f26, 24+16($sp) 141 lwc1 $f28, 32+16($sp) 142 lwc1 $f30, 40+16($sp) 143 lw $31, 48+16($sp) 144 add $sp, $sp,56 145 j $31 146 147 148 /* 149 ** First, call `startup' with the `pt' argument. 150 ** 151 ** Next, call the user's function with all arguments. 152 ** Note that we don't know whether args were passed in 153 ** integer regs, fp regs, or on the stack (See Gerry Kane 154 ** "MIPS R2000 RISC Architecture" pg D-22), so we reload 155 ** all the registers, possibly with garbage arguments. 156 ** 157 ** Finally, call `cleanup' with the `pt' argument and with 158 ** the return value from the user's function. It is an error 159 ** for `cleanup' to return. 160 */ 161qt_vstart: 162 add $4, $17,$0 /* `pt' is arg0 to `startup'. */ 163 add $25, $18,$0 /* Set `startup' procedure value. */ 164 jal $31, $25 /* Call `startup'. */ 165 166 add $sp, $sp,16 /* Free extra save space. */ 167 lw $4, 0($sp) /* Load up args. */ 168 lw $5, 4($sp) 169 lw $6, 8($sp) 170 lw $7, 12($sp) 171 lwc1 $f12, 0($sp) /* Load up fp args. */ 172 lwc1 $f14, 8($sp) 173 add $25, $19,$0 /* Set `userf' procedure value. */ 174 jal $31,$25 /* Call `userf'. */ 175 176 add $4, $17,$0 /* `pt' is arg0 to `cleanup'. */ 177 add $5, $2,$0 /* Ret. val is arg1 to `cleanup'. */ 178 add $25, $16,$0 /* Set `cleanup' procedure value. */ 179 jal $31, $25 /* Call `cleanup'. */ 180 181 la $25,qt_error /* Set `qt_error' procedure value. */ 182 j $25 183