123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- #
- # 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
|