1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-04-30 20:00:19 +02:00
guile/qt/md/axp.s

160 lines
3.8 KiB
ArmAsm

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