112027Sjungma@eit.uni-kl.de/* mips.s -- assembly support. */ 212027Sjungma@eit.uni-kl.de 312027Sjungma@eit.uni-kl.de/* 412027Sjungma@eit.uni-kl.de * QuickThreads -- Threads-building toolkit. 512027Sjungma@eit.uni-kl.de * Copyright (c) 1993 by David Keppel 612027Sjungma@eit.uni-kl.de * 712027Sjungma@eit.uni-kl.de * Permission to use, copy, modify and distribute this software and 812027Sjungma@eit.uni-kl.de * its documentation for any purpose and without fee is hereby 912027Sjungma@eit.uni-kl.de * granted, provided that the above copyright notice and this notice 1012027Sjungma@eit.uni-kl.de * appear in all copies. This software is provided as a 1112027Sjungma@eit.uni-kl.de * proof-of-concept and for demonstration purposes; there is no 1212027Sjungma@eit.uni-kl.de * representation about the suitability of this software for any 1312027Sjungma@eit.uni-kl.de * purpose. 1412027Sjungma@eit.uni-kl.de */ 1512027Sjungma@eit.uni-kl.de 1612027Sjungma@eit.uni-kl.de/* Callee-save $16-$23, $30-$31. 1712027Sjungma@eit.uni-kl.de * 1812027Sjungma@eit.uni-kl.de * $25 is used as a procedure value pointer, used to discover constants 1912027Sjungma@eit.uni-kl.de * in a callee. Thus, each caller here sets $25 before the call. 2012027Sjungma@eit.uni-kl.de * 2112027Sjungma@eit.uni-kl.de * On startup, restore regs so retpc === call to a function to start. 2212027Sjungma@eit.uni-kl.de * We're going to call a function ($4) from within this routine. 2312027Sjungma@eit.uni-kl.de * We're passing 3 args, therefore need to allocate 12 extra bytes on 2412027Sjungma@eit.uni-kl.de * the stack for a save area. The start routine needs a like 16-byte 2512027Sjungma@eit.uni-kl.de * save area. Must be doubleword aligned (_mips r3000 risc 2612027Sjungma@eit.uni-kl.de * architecture_, gerry kane, pg d-23). 2712027Sjungma@eit.uni-kl.de */ 2812027Sjungma@eit.uni-kl.de 2912027Sjungma@eit.uni-kl.de/* 3012027Sjungma@eit.uni-kl.de * Modified by Assar Westerlund <assar@sics.se> to support Irix 5.x 3112027Sjungma@eit.uni-kl.de * calling conventions for dynamically-linked code. 3212027Sjungma@eit.uni-kl.de */ 3312027Sjungma@eit.uni-kl.de 3412027Sjungma@eit.uni-kl.de /* Make this position-independent code. */ 3512027Sjungma@eit.uni-kl.de .option pic2 3612027Sjungma@eit.uni-kl.de 3712027Sjungma@eit.uni-kl.de .globl qt_block 3812027Sjungma@eit.uni-kl.de .globl qt_blocki 3912027Sjungma@eit.uni-kl.de .globl qt_abort 4012027Sjungma@eit.uni-kl.de .globl qt_start 4112027Sjungma@eit.uni-kl.de .globl qt_vstart 4212027Sjungma@eit.uni-kl.de 4312027Sjungma@eit.uni-kl.de /* 4412027Sjungma@eit.uni-kl.de ** $4: ptr to function to call once curr is suspended 4512027Sjungma@eit.uni-kl.de ** and control is on $7's stack. 4612027Sjungma@eit.uni-kl.de ** $5: 1'th arg to $4. 4712027Sjungma@eit.uni-kl.de ** $6: 2'th arg to $4 4812027Sjungma@eit.uni-kl.de ** $7: sp of thread to suspend. 4912027Sjungma@eit.uni-kl.de ** 5012027Sjungma@eit.uni-kl.de ** Totally gross hack: The MIPS calling convention reserves 5112027Sjungma@eit.uni-kl.de ** 4 words on the stack for a0..a3. This routine "ought" to 5212027Sjungma@eit.uni-kl.de ** allocate space for callee-save registers plus 4 words for 5312027Sjungma@eit.uni-kl.de ** the helper function, but instead we use the 4 words 5412027Sjungma@eit.uni-kl.de ** provided by the function that called us (we don't need to 5512027Sjungma@eit.uni-kl.de ** save our argument registers). So what *appears* to be 5612027Sjungma@eit.uni-kl.de ** allocating only 40 bytes is actually allocating 56, by 5712027Sjungma@eit.uni-kl.de ** using the caller's 16 bytes. 5812027Sjungma@eit.uni-kl.de ** 5912027Sjungma@eit.uni-kl.de ** The helper routine returns a value that is passed on as the 6012027Sjungma@eit.uni-kl.de ** return value from the blocking routine. Since we don't 6112027Sjungma@eit.uni-kl.de ** touch $2 between the helper's return and the end of 6212027Sjungma@eit.uni-kl.de ** function, we get this behavior for free. 6312027Sjungma@eit.uni-kl.de */ 6412027Sjungma@eit.uni-kl.deqt_blocki: 6512027Sjungma@eit.uni-kl.de sub $sp,$sp,40 /* Allocate reg save space. */ 6612027Sjungma@eit.uni-kl.de sw $16, 0+16($sp) 6712027Sjungma@eit.uni-kl.de sw $17, 4+16($sp) 6812027Sjungma@eit.uni-kl.de sw $18, 8+16($sp) 6912027Sjungma@eit.uni-kl.de sw $19,12+16($sp) 7012027Sjungma@eit.uni-kl.de sw $20,16+16($sp) 7112027Sjungma@eit.uni-kl.de sw $21,20+16($sp) 7212027Sjungma@eit.uni-kl.de sw $22,24+16($sp) 7312027Sjungma@eit.uni-kl.de sw $23,28+16($sp) 7412027Sjungma@eit.uni-kl.de sw $30,32+16($sp) 7512027Sjungma@eit.uni-kl.de sw $31,36+16($sp) 7612027Sjungma@eit.uni-kl.de add $2, $sp,$0 /* $2 <= old sp to pass to func@$4. */ 7712027Sjungma@eit.uni-kl.deqt_abort: 7812027Sjungma@eit.uni-kl.de add $sp, $7,$0 /* $sp <= new sp. */ 7912027Sjungma@eit.uni-kl.de .set noreorder 8012027Sjungma@eit.uni-kl.de add $25, $4,$0 /* Set helper function procedure value. */ 8112027Sjungma@eit.uni-kl.de jal $31,$25 /* Call helper func@$4 . */ 8212027Sjungma@eit.uni-kl.de add $4, $2,$0 /* $a0 <= pass old sp as a parameter. */ 8312027Sjungma@eit.uni-kl.de .set reorder 8412027Sjungma@eit.uni-kl.de lw $31,36+16($sp) /* Restore callee-save regs... */ 8512027Sjungma@eit.uni-kl.de lw $30,32+16($sp) 8612027Sjungma@eit.uni-kl.de lw $23,28+16($sp) 8712027Sjungma@eit.uni-kl.de lw $22,24+16($sp) 8812027Sjungma@eit.uni-kl.de lw $21,20+16($sp) 8912027Sjungma@eit.uni-kl.de lw $20,16+16($sp) 9012027Sjungma@eit.uni-kl.de lw $19,12+16($sp) 9112027Sjungma@eit.uni-kl.de lw $18, 8+16($sp) 9212027Sjungma@eit.uni-kl.de lw $17, 4+16($sp) 9312027Sjungma@eit.uni-kl.de lw $16, 0+16($sp) /* Restore callee-save */ 9412027Sjungma@eit.uni-kl.de 9512027Sjungma@eit.uni-kl.de add $sp,$sp,40 /* Deallocate reg save space. */ 9612027Sjungma@eit.uni-kl.de j $31 /* Return to caller. */ 9712027Sjungma@eit.uni-kl.de 9812027Sjungma@eit.uni-kl.de /* 9912027Sjungma@eit.uni-kl.de ** Non-varargs thread startup. 10012027Sjungma@eit.uni-kl.de ** Note: originally, 56 bytes were allocated on the stack. 10112027Sjungma@eit.uni-kl.de ** The thread restore routine (_blocki/_abort) removed 40 10212027Sjungma@eit.uni-kl.de ** of them, which means there is still 16 bytes for the 10312027Sjungma@eit.uni-kl.de ** argument area required by the MIPS calling convention. 10412027Sjungma@eit.uni-kl.de */ 10512027Sjungma@eit.uni-kl.deqt_start: 10612027Sjungma@eit.uni-kl.de add $4, $16,$0 /* Load up user function pu. */ 10712027Sjungma@eit.uni-kl.de add $5, $17,$0 /* ... user function pt. */ 10812027Sjungma@eit.uni-kl.de add $6, $18,$0 /* ... user function userf. */ 10912027Sjungma@eit.uni-kl.de add $25, $19,$0 /* Set `only' procedure value. */ 11012027Sjungma@eit.uni-kl.de jal $31,$25 /* Call `only'. */ 11112027Sjungma@eit.uni-kl.de la $25,qt_error /* Set `qt_error' procedure value. */ 11212027Sjungma@eit.uni-kl.de j $25 11312027Sjungma@eit.uni-kl.de 11412027Sjungma@eit.uni-kl.de 11512027Sjungma@eit.uni-kl.de /* 11612027Sjungma@eit.uni-kl.de ** Save calle-save floating-point regs $f20-$f30 11712027Sjungma@eit.uni-kl.de ** See comment in `qt_block' about calling conventinos and 11812027Sjungma@eit.uni-kl.de ** reserved space. Use the same trick here, but here we 11912027Sjungma@eit.uni-kl.de ** actually have to allocate all the bytes since we have to 12012027Sjungma@eit.uni-kl.de ** leave 4 words leftover for `qt_blocki'. 12112027Sjungma@eit.uni-kl.de ** 12212027Sjungma@eit.uni-kl.de ** Return value from `qt_block' is the same as the return from 12312027Sjungma@eit.uni-kl.de ** `qt_blocki'. We get that for free since we don't touch $2 12412027Sjungma@eit.uni-kl.de ** between the return from `qt_blocki' and the return from 12512027Sjungma@eit.uni-kl.de ** `qt_block'. 12612027Sjungma@eit.uni-kl.de */ 12712027Sjungma@eit.uni-kl.deqt_block: 12812027Sjungma@eit.uni-kl.de sub $sp, $sp,56 /* 6 8-byte regs, saved ret pc, aligned. */ 12912027Sjungma@eit.uni-kl.de swc1 $f20, 0+16($sp) 13012027Sjungma@eit.uni-kl.de swc1 $f22, 8+16($sp) 13112027Sjungma@eit.uni-kl.de swc1 $f24, 16+16($sp) 13212027Sjungma@eit.uni-kl.de swc1 $f26, 24+16($sp) 13312027Sjungma@eit.uni-kl.de swc1 $f28, 32+16($sp) 13412027Sjungma@eit.uni-kl.de swc1 $f30, 40+16($sp) 13512027Sjungma@eit.uni-kl.de sw $31, 48+16($sp) 13612027Sjungma@eit.uni-kl.de jal qt_blocki 13712027Sjungma@eit.uni-kl.de lwc1 $f20, 0+16($sp) 13812027Sjungma@eit.uni-kl.de lwc1 $f22, 8+16($sp) 13912027Sjungma@eit.uni-kl.de lwc1 $f24, 16+16($sp) 14012027Sjungma@eit.uni-kl.de lwc1 $f26, 24+16($sp) 14112027Sjungma@eit.uni-kl.de lwc1 $f28, 32+16($sp) 14212027Sjungma@eit.uni-kl.de lwc1 $f30, 40+16($sp) 14312027Sjungma@eit.uni-kl.de lw $31, 48+16($sp) 14412027Sjungma@eit.uni-kl.de add $sp, $sp,56 14512027Sjungma@eit.uni-kl.de j $31 14612027Sjungma@eit.uni-kl.de 14712027Sjungma@eit.uni-kl.de 14812027Sjungma@eit.uni-kl.de /* 14912027Sjungma@eit.uni-kl.de ** First, call `startup' with the `pt' argument. 15012027Sjungma@eit.uni-kl.de ** 15112027Sjungma@eit.uni-kl.de ** Next, call the user's function with all arguments. 15212027Sjungma@eit.uni-kl.de ** Note that we don't know whether args were passed in 15312027Sjungma@eit.uni-kl.de ** integer regs, fp regs, or on the stack (See Gerry Kane 15412027Sjungma@eit.uni-kl.de ** "MIPS R2000 RISC Architecture" pg D-22), so we reload 15512027Sjungma@eit.uni-kl.de ** all the registers, possibly with garbage arguments. 15612027Sjungma@eit.uni-kl.de ** 15712027Sjungma@eit.uni-kl.de ** Finally, call `cleanup' with the `pt' argument and with 15812027Sjungma@eit.uni-kl.de ** the return value from the user's function. It is an error 15912027Sjungma@eit.uni-kl.de ** for `cleanup' to return. 16012027Sjungma@eit.uni-kl.de */ 16112027Sjungma@eit.uni-kl.deqt_vstart: 16212027Sjungma@eit.uni-kl.de add $4, $17,$0 /* `pt' is arg0 to `startup'. */ 16312027Sjungma@eit.uni-kl.de add $25, $18,$0 /* Set `startup' procedure value. */ 16412027Sjungma@eit.uni-kl.de jal $31, $25 /* Call `startup'. */ 16512027Sjungma@eit.uni-kl.de 16612027Sjungma@eit.uni-kl.de add $sp, $sp,16 /* Free extra save space. */ 16712027Sjungma@eit.uni-kl.de lw $4, 0($sp) /* Load up args. */ 16812027Sjungma@eit.uni-kl.de lw $5, 4($sp) 16912027Sjungma@eit.uni-kl.de lw $6, 8($sp) 17012027Sjungma@eit.uni-kl.de lw $7, 12($sp) 17112027Sjungma@eit.uni-kl.de lwc1 $f12, 0($sp) /* Load up fp args. */ 17212027Sjungma@eit.uni-kl.de lwc1 $f14, 8($sp) 17312027Sjungma@eit.uni-kl.de add $25, $19,$0 /* Set `userf' procedure value. */ 17412027Sjungma@eit.uni-kl.de jal $31,$25 /* Call `userf'. */ 17512027Sjungma@eit.uni-kl.de 17612027Sjungma@eit.uni-kl.de add $4, $17,$0 /* `pt' is arg0 to `cleanup'. */ 17712027Sjungma@eit.uni-kl.de add $5, $2,$0 /* Ret. val is arg1 to `cleanup'. */ 17812027Sjungma@eit.uni-kl.de add $25, $16,$0 /* Set `cleanup' procedure value. */ 17912027Sjungma@eit.uni-kl.de jal $31, $25 /* Call `cleanup'. */ 18012027Sjungma@eit.uni-kl.de 18112027Sjungma@eit.uni-kl.de la $25,qt_error /* Set `qt_error' procedure value. */ 18212027Sjungma@eit.uni-kl.de j $25 183