1/* 2 * QuickThreads -- Threads-building toolkit. 3 * Copyright (c) 1993 by David Keppel 4 * 5 * Permission to use, copy, modify and distribute this software and 6 * its documentation for any purpose and without fee is hereby 7 * granted, provided that the above copyright notice and this notice 8 * appear in all copies. This software is provided as a 9 * proof-of-concept and for demonstration purposes; there is no 10 * representation about the suitability of this software for any 11 * purpose. 12 */ 13 14/* axp.s -- assembly support. */ 15 16 .text 17 .align 4 18 .file 2 "axp.s" 19 20 .globl qt_block 21 .globl qt_blocki 22 .globl qt_abort 23 .globl qt_start 24 .globl qt_vstart 25 26 /* 27 ** $16: ptr to function to call once curr is suspended 28 ** and control is on r19's stack. 29 ** $17: 1'th arg to (*$16)(...). 30 ** $18: 2'th arg to (*$16)(...). 31 ** $19: sp of thread to resume. 32 ** 33 ** The helper routine returns a value that is passed on as the 34 ** return value from the blocking routine. Since we don't 35 ** touch r0 between the helper's return and the end of 36 ** function, we get this behavior for free. 37 */ 38 39 .ent qt_blocki 40qt_blocki: 41 subq $30,80, $30 /* Allocate save area. */ 42 stq $26, 0($30) /* Save registers. */ 43 stq $9, 8($30) 44 stq $10,16($30) 45 stq $11,24($30) 46 stq $12,32($30) 47 stq $13,40($30) 48 stq $14,48($30) 49 stq $15,56($30) 50 stq $29,64($30) 51 .end qt_blocki 52 .ent qt_abort 53qt_abort: 54 addq $16,$31, $27 /* Put argument function in PV. */ 55 addq $30,$31, $16 /* Save stack ptr in outgoing arg. */ 56 addq $19,$31, $30 /* Set new stack pointer. */ 57 jsr $26,($27),0 /* Call helper function. */ 58 59 ldq $26, 0($30) /* Restore registers. */ 60 ldq $9, 8($30) 61 ldq $10,16($30) 62 ldq $11,24($30) 63 ldq $12,32($30) 64 ldq $13,40($30) 65 ldq $14,48($30) 66 ldq $15,56($30) 67 ldq $29,64($30) 68 69 addq $30,80, $30 /* Deallocate save area. */ 70 ret $31,($26),1 /* Return, predict===RET. */ 71 .end qt_abort 72 73 74 /* 75 ** Non-varargs thread startup. 76 */ 77 .ent qt_start 78qt_start: 79 addq $9,$31, $16 /* Load up `qu'. */ 80 addq $10,$31, $17 /* ... user function's `pt'. */ 81 addq $11,$31, $18 /* ... user function's `userf'. */ 82 addq $12,$31, $27 /* ... set procedure value to `only'. */ 83 jsr $26,($27),0 /* Call `only'. */ 84 85 jsr $26,qt_error /* `only' erroniously returned. */ 86 .end qt_start 87 88 89 .ent qt_vstart: 90qt_vstart: 91 /* Call startup function. */ 92 addq $9,$31, $16 /* Arg0 to `startup'. */ 93 addq $12,$31, $27 /* Set procedure value. */ 94 jsr $26,($27),0 /* Call `startup'. */ 95 96 /* Call user function. */ 97 ldt $f16, 0($30) /* Load fp arg regs. */ 98 ldt $f17, 8($30) 99 ldt $f18,16($30) 100 ldt $f19,24($30) 101 ldt $f20,32($30) 102 ldt $f21,40($30) 103 ldq $16,48($30) /* And integer arg regs. */ 104 ldq $17,56($30) 105 ldq $18,64($30) 106 ldq $19,72($30) 107 ldq $20,80($30) 108 ldq $21,88($30) 109 addq $30,96 $30 /* Pop 6*2*8 saved arg regs. */ 110 addq $11,$31, $27 /* Set procedure value. */ 111 jsr $26,($27),0 /* Call `vuserf'. */ 112 113 /* Call cleanup. */ 114 addq $9,$31, $16 /* Arg0 to `cleanup'. */ 115 addq $0,$31, $17 /* Users's return value is arg1. */ 116 addq $10,$31, $27 /* Set procedure value. */ 117 jsr $26,($27),0 /* Call `cleanup'. */ 118 119 jsr $26,qt_error /* Cleanup erroniously returned. */ 120 .end qt_start 121 122 123 /* 124 ** Save calle-save floating-point regs $f2..$f9. 125 ** Also save return pc from whomever called us. 126 ** 127 ** Return value from `qt_block' is the same as the return from 128 ** `qt_blocki'. We get that for free since we don't touch $0 129 ** between the return from `qt_blocki' and the return from 130 ** `qt_block'. 131 */ 132 .ent qt_block 133qt_block: 134 subq $30,80, $30 /* Allocate a save space. */ 135 stq $26, 0($30) /* Save registers. */ 136 stt $f2, 8($30) 137 stt $f3,16($30) 138 stt $f4,24($30) 139 stt $f5,32($30) 140 stt $f6,40($30) 141 stt $f7,48($30) 142 stt $f8,56($30) 143 stt $f9,64($30) 144 145 jsr $26,qt_blocki /* Call helper. */ 146 /* .. who will also restore $gp. */ 147 148 ldq $26, 0($30) /* restore registers. */ 149 ldt $f2, 8($30) 150 ldt $f3,16($30) 151 ldt $f4,24($30) 152 ldt $f5,32($30) 153 ldt $f6,40($30) 154 ldt $f7,48($30) 155 ldt $f8,56($30) 156 ldt $f9,64($30) 157 158 addq $30,80, $30 /* Deallcate save space. */ 159 ret $31,($26),1 /* Return, predict===RET. */ 160 .end qt_block 161