/* * QuickThreads -- Threads-building toolkit. * Copyright (c) 1993 by David Keppel * * Permission to use, copy, modify and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice and this notice * appear in all copies. This software is provided as a * proof-of-concept and for demonstration purposes; there is no * representation about the suitability of this software for any * purpose. */ /* axp.s -- assembly support. */ .text .align 4 .file 2 "axp.s" .globl qt_block .globl qt_blocki .globl qt_abort .globl qt_start .globl qt_vstart /* ** $16: ptr to function to call once curr is suspended ** and control is on r19's stack. ** $17: 1'th arg to (*$16)(...). ** $18: 2'th arg to (*$16)(...). ** $19: sp of thread to resume. ** ** The helper routine returns a value that is passed on as the ** return value from the blocking routine. Since we don't ** touch r0 between the helper's return and the end of ** function, we get this behavior for free. */ .ent qt_blocki qt_blocki: subq $30,80, $30 /* Allocate save area. */ stq $26, 0($30) /* Save registers. */ stq $9, 8($30) stq $10,16($30) stq $11,24($30) stq $12,32($30) stq $13,40($30) stq $14,48($30) stq $15,56($30) stq $29,64($30) .end qt_blocki .ent qt_abort qt_abort: addq $16,$31, $27 /* Put argument function in PV. */ addq $30,$31, $16 /* Save stack ptr in outgoing arg. */ addq $19,$31, $30 /* Set new stack pointer. */ jsr $26,($27),0 /* Call helper function. */ ldq $26, 0($30) /* Restore registers. */ ldq $9, 8($30) ldq $10,16($30) ldq $11,24($30) ldq $12,32($30) ldq $13,40($30) ldq $14,48($30) ldq $15,56($30) ldq $29,64($30) addq $30,80, $30 /* Deallocate save area. */ ret $31,($26),1 /* Return, predict===RET. */ .end qt_abort /* ** Non-varargs thread startup. */ .ent qt_start qt_start: addq $9,$31, $16 /* Load up `qu'. */ addq $10,$31, $17 /* ... user function's `pt'. */ addq $11,$31, $18 /* ... user function's `userf'. */ addq $12,$31, $27 /* ... set procedure value to `only'. */ jsr $26,($27),0 /* Call `only'. */ jsr $26,qt_error /* `only' erroniously returned. */ .end qt_start .ent qt_vstart: qt_vstart: /* Call startup function. */ addq $9,$31, $16 /* Arg0 to `startup'. */ addq $12,$31, $27 /* Set procedure value. */ jsr $26,($27),0 /* Call `startup'. */ /* Call user function. */ ldt $f16, 0($30) /* Load fp arg regs. */ ldt $f17, 8($30) ldt $f18,16($30) ldt $f19,24($30) ldt $f20,32($30) ldt $f21,40($30) ldq $16,48($30) /* And integer arg regs. */ ldq $17,56($30) ldq $18,64($30) ldq $19,72($30) ldq $20,80($30) ldq $21,88($30) addq $30,96 $30 /* Pop 6*2*8 saved arg regs. */ addq $11,$31, $27 /* Set procedure value. */ jsr $26,($27),0 /* Call `vuserf'. */ /* Call cleanup. */ addq $9,$31, $16 /* Arg0 to `cleanup'. */ addq $0,$31, $17 /* Users's return value is arg1. */ addq $10,$31, $27 /* Set procedure value. */ jsr $26,($27),0 /* Call `cleanup'. */ jsr $26,qt_error /* Cleanup erroniously returned. */ .end qt_start /* ** Save calle-save floating-point regs $f2..$f9. ** Also save return pc from whomever called us. ** ** Return value from `qt_block' is the same as the return from ** `qt_blocki'. We get that for free since we don't touch $0 ** between the return from `qt_blocki' and the return from ** `qt_block'. */ .ent qt_block qt_block: subq $30,80, $30 /* Allocate a save space. */ stq $26, 0($30) /* Save registers. */ stt $f2, 8($30) stt $f3,16($30) stt $f4,24($30) stt $f5,32($30) stt $f6,40($30) stt $f7,48($30) stt $f8,56($30) stt $f9,64($30) jsr $26,qt_blocki /* Call helper. */ /* .. who will also restore $gp. */ ldq $26, 0($30) /* restore registers. */ ldt $f2, 8($30) ldt $f3,16($30) ldt $f4,24($30) ldt $f5,32($30) ldt $f6,40($30) ldt $f7,48($30) ldt $f8,56($30) ldt $f9,64($30) addq $30,80, $30 /* Deallcate save space. */ ret $31,($26),1 /* Return, predict===RET. */ .end qt_block