mips.s revision 12027:1eb7dc7aa10b
112855Sgabeblack@google.com/* mips.s -- assembly support. */ 212855Sgabeblack@google.com 312855Sgabeblack@google.com/* 412855Sgabeblack@google.com * QuickThreads -- Threads-building toolkit. 512855Sgabeblack@google.com * Copyright (c) 1993 by David Keppel 612855Sgabeblack@google.com * 712855Sgabeblack@google.com * Permission to use, copy, modify and distribute this software and 812855Sgabeblack@google.com * its documentation for any purpose and without fee is hereby 912855Sgabeblack@google.com * granted, provided that the above copyright notice and this notice 1012855Sgabeblack@google.com * appear in all copies. This software is provided as a 1112855Sgabeblack@google.com * proof-of-concept and for demonstration purposes; there is no 1212855Sgabeblack@google.com * representation about the suitability of this software for any 1312855Sgabeblack@google.com * purpose. 1412855Sgabeblack@google.com */ 1512855Sgabeblack@google.com 1612855Sgabeblack@google.com/* Callee-save $16-$23, $30-$31. 1712855Sgabeblack@google.com * 1812855Sgabeblack@google.com * On startup, restore regs so retpc === call to a function to start. 1912855Sgabeblack@google.com * We're going to call a function ($4) from within this routine. 2012855Sgabeblack@google.com * We're passing 3 args, therefore need to allocate 12 extra bytes on 2112855Sgabeblack@google.com * the stack for a save area. The start routine needs a like 16-byte 2212855Sgabeblack@google.com * save area. Must be doubleword aligned (_mips r3000 risc 2312855Sgabeblack@google.com * architecture_, gerry kane, pg d-23). 2412855Sgabeblack@google.com */ 2512855Sgabeblack@google.com 2612855Sgabeblack@google.com .globl qt_block 2712855Sgabeblack@google.com .globl qt_blocki 2812855Sgabeblack@google.com .globl qt_abort 2912855Sgabeblack@google.com .globl qt_start 3012855Sgabeblack@google.com .globl qt_vstart 3112855Sgabeblack@google.com 3212855Sgabeblack@google.com /* 3312855Sgabeblack@google.com ** $4: ptr to function to call once curr is suspended 3412855Sgabeblack@google.com ** and control is on $7's stack. 3512855Sgabeblack@google.com ** $5: 1'th arg to $4. 3612855Sgabeblack@google.com ** $6: 2'th arg to $4 3712855Sgabeblack@google.com ** $7: sp of thread to suspend. 3812855Sgabeblack@google.com ** 3912855Sgabeblack@google.com ** Totally gross hack: The MIPS calling convention reserves 4012855Sgabeblack@google.com ** 4 words on the stack for a0..a3. This routine "ought" to 4112855Sgabeblack@google.com ** allocate space for callee-save registers plus 4 words for 4212855Sgabeblack@google.com ** the helper function, but instead we use the 4 words 4312855Sgabeblack@google.com ** provided by the function that called us (we don't need to 4412855Sgabeblack@google.com ** save our argument registers). So what *appears* to be 4512855Sgabeblack@google.com ** allocating only 40 bytes is actually allocating 56, by 4612855Sgabeblack@google.com ** using the caller's 16 bytes. 4712855Sgabeblack@google.com ** 4812855Sgabeblack@google.com ** The helper routine returns a value that is passed on as the 4912855Sgabeblack@google.com ** return value from the blocking routine. Since we don't 5012855Sgabeblack@google.com ** touch $2 between the helper's return and the end of 5112855Sgabeblack@google.com ** function, we get this behavior for free. 5212855Sgabeblack@google.com */ 5312855Sgabeblack@google.comqt_blocki: 5412855Sgabeblack@google.com sub $sp,$sp,40 /* Allocate reg save space. */ 5512855Sgabeblack@google.com sw $16, 0+16($sp) 5612855Sgabeblack@google.com sw $17, 4+16($sp) 5712855Sgabeblack@google.com sw $18, 8+16($sp) 5812855Sgabeblack@google.com sw $19,12+16($sp) 5912855Sgabeblack@google.com sw $20,16+16($sp) 6012855Sgabeblack@google.com sw $21,20+16($sp) 6112855Sgabeblack@google.com sw $22,24+16($sp) 6212855Sgabeblack@google.com sw $23,28+16($sp) 6312855Sgabeblack@google.com sw $30,32+16($sp) 6412855Sgabeblack@google.com sw $31,36+16($sp) 6512855Sgabeblack@google.com add $2, $sp,$0 /* $2 <= old sp to pass to func@$4. */ 6612855Sgabeblack@google.comqt_abort: 6712855Sgabeblack@google.com add $sp, $7,$0 /* $sp <= new sp. */ 6812855Sgabeblack@google.com .set noreorder 6912855Sgabeblack@google.com jal $31,$4 /* Call helper func@$4 . */ 7012855Sgabeblack@google.com add $4, $2,$0 /* $a0 <= pass old sp as a parameter. */ 7112855Sgabeblack@google.com .set reorder 7212855Sgabeblack@google.com lw $31,36+16($sp) /* Restore callee-save regs... */ 7312855Sgabeblack@google.com lw $30,32+16($sp) 7412855Sgabeblack@google.com lw $23,28+16($sp) 7512855Sgabeblack@google.com lw $22,24+16($sp) 7612855Sgabeblack@google.com lw $21,20+16($sp) 7712855Sgabeblack@google.com lw $20,16+16($sp) 7812855Sgabeblack@google.com lw $19,12+16($sp) 7912855Sgabeblack@google.com lw $18, 8+16($sp) 8012855Sgabeblack@google.com lw $17, 4+16($sp) 8112855Sgabeblack@google.com lw $16, 0+16($sp) /* Restore callee-save */ 8212855Sgabeblack@google.com 8312855Sgabeblack@google.com add $sp,$sp,40 /* Deallocate reg save space. */ 8412855Sgabeblack@google.com j $31 /* Return to caller. */ 8512855Sgabeblack@google.com 8612855Sgabeblack@google.com /* 8712855Sgabeblack@google.com ** Non-varargs thread startup. 8812855Sgabeblack@google.com ** Note: originally, 56 bytes were allocated on the stack. 8912855Sgabeblack@google.com ** The thread restore routine (_blocki/_abort) removed 40 9012855Sgabeblack@google.com ** of them, which means there is still 16 bytes for the 9112855Sgabeblack@google.com ** argument area required by the MIPS calling convention. 9212855Sgabeblack@google.com */ 9312855Sgabeblack@google.comqt_start: 9412855Sgabeblack@google.com add $4, $16,$0 /* Load up user function pu. */ 9512855Sgabeblack@google.com add $5, $17,$0 /* ... user function pt. */ 9612855Sgabeblack@google.com add $6, $18,$0 /* ... user function userf. */ 9712855Sgabeblack@google.com jal $31,$19 /* Call `only'. */ 9812855Sgabeblack@google.com j qt_error 9912855Sgabeblack@google.com 10012855Sgabeblack@google.com 10112855Sgabeblack@google.com /* 10212855Sgabeblack@google.com ** Save calle-save floating-point regs $f20-$f30 10312855Sgabeblack@google.com ** See comment in `qt_block' about calling conventinos and 10412855Sgabeblack@google.com ** reserved space. Use the same trick here, but here we 10512855Sgabeblack@google.com ** actually have to allocate all the bytes since we have to 10612855Sgabeblack@google.com ** leave 4 words leftover for `qt_blocki'. 10712855Sgabeblack@google.com ** 10812855Sgabeblack@google.com ** Return value from `qt_block' is the same as the return from 10912855Sgabeblack@google.com ** `qt_blocki'. We get that for free since we don't touch $2 11012855Sgabeblack@google.com ** between the return from `qt_blocki' and the return from 11112855Sgabeblack@google.com ** `qt_block'. 11212855Sgabeblack@google.com */ 11312855Sgabeblack@google.comqt_block: 11412855Sgabeblack@google.com sub $sp, $sp,56 /* 6 8-byte regs, saved ret pc, aligned. */ 11512855Sgabeblack@google.com swc1 $f20, 0+16($sp) 116 swc1 $f22, 8+16($sp) 117 swc1 $f24, 16+16($sp) 118 swc1 $f26, 24+16($sp) 119 swc1 $f28, 32+16($sp) 120 swc1 $f30, 40+16($sp) 121 sw $31, 48+16($sp) 122 jal qt_blocki 123 lwc1 $f20, 0+16($sp) 124 lwc1 $f22, 8+16($sp) 125 lwc1 $f24, 16+16($sp) 126 lwc1 $f26, 24+16($sp) 127 lwc1 $f28, 32+16($sp) 128 lwc1 $f30, 40+16($sp) 129 lw $31, 48+16($sp) 130 add $sp, $sp,56 131 j $31 132 133 134 /* 135 ** First, call `startup' with the `pt' argument. 136 ** 137 ** Next, call the user's function with all arguments. 138 ** Note that we don't know whether args were passed in 139 ** integer regs, fp regs, or on the stack (See Gerry Kane 140 ** "MIPS R2000 RISC Architecture" pg D-22), so we reload 141 ** all the registers, possibly with garbage arguments. 142 ** 143 ** Finally, call `cleanup' with the `pt' argument and with 144 ** the return value from the user's function. It is an error 145 ** for `cleanup' to return. 146 */ 147qt_vstart: 148 add $4, $17,$0 /* `pt' is arg0 to `startup'. */ 149 jal $31, $18 /* Call `startup'. */ 150 151 add $sp, $sp,16 /* Free extra save space. */ 152 lw $4, 0($sp) /* Load up args. */ 153 lw $5, 4($sp) 154 lw $6, 8($sp) 155 lw $7, 12($sp) 156 lwc1 $f12, 0($sp) /* Load up fp args. */ 157 lwc1 $f14, 8($sp) 158 jal $31,$19 /* Call `userf'. */ 159 160 add $4, $17,$0 /* `pt' is arg0 to `cleanup'. */ 161 add $5, $2,$0 /* Ret. val is arg1 to `cleanup'. */ 162 jal $31, $16 /* Call `cleanup'. */ 163 164 j qt_error 165