/* # # sys.S # # Machine dependent routines for the minithread package. # These routines support the alpha architecture running OSF/1. # # You really really really don't want to mess with this... # # 10/95 Written by Geoff Voelker. # # 10/97 Modified by Neal Cardwell to work with the minithreads # setup from Winter 97. # # 11/97 Modified by Neal Cardwell to work with project 3. # Deleted atomic_test_and_set. # */ /* * Symbolic register names for Alpha calling conventions */ #define v0 $0 /* return value */ #define t0 $1 /* caller saved (==> temporary) */ #define s0 $9 /* callee saved */ #define s1 $10 #define s2 $11 #define s3 $12 #define s4 $13 #define s5 $14 #define s6 $15 #define a0 $16 /* arguments */ #define a1 $17 #define ra $26 /* return address */ #define gp $29 /* the global pointer */ #define sp $30 /* stack pointer */ #define zero $31 /* hardwired to zero */ .text .align 4 .globl minithread_root .globl context_switch .globl atomic_test_and_set # When minithread_root is called, the registers are set up # as described in the struct initial_stack_state in minithread_md.h. # Basically, the information about which procedures to call has # been jammed into some arbitrary registers. # Call the procedures, with their arguments, one after the other. .ent minithread_root minithread_root: beq s0, $32 # initial_proc may be null addq s0, zero, $27 # setup initial_proc in $pv addq s1, zero, a0 # setup initial_arg in $a0 jsr ra, ($27), 0 # initial_proc $32: addq s2, zero, $27 # setup body_proc in $pv addq s3, zero, a0 # setup body_arg in $a0 jsr ra, ($27), 0 # body_proc addq s4, zero, $27 # setup finally_proc in $pv addq s5, zero, a0 # setup finally_arg in $a0 jsr ra, ($27), 0 # finally_proc # # NOT REACHED # stq zero, 0 .end minithread_root # context_switch: Switch from one thread to another .ent context_switch context_switch: subq sp, 144, sp # allocate space on stack for registers stq s0, 0(sp) # push callee-saved integer registers stq s1, 8(sp) stq s2, 16(sp) stq s3, 24(sp) stq s4, 32(sp) stq s5, 40(sp) stq s6, 48(sp) stt $f2, 56(sp) # push callee-saved fp registers stt $f3, 64(sp) stt $f4, 72(sp) stt $f5, 80(sp) stt $f6, 88(sp) stt $f7, 96(sp) stt $f8, 104(sp) stt $f9, 112(sp) stq gp, 120(sp) # push the global pointer stq ra, 128(sp) # push the return address stq sp, 0(a0) # pass back the old stack pointer ldq sp, 0(a1) # load the new stack pointer ldq s0 0(sp) # pop callee-saved integer registers ldq s1, 8(sp) ldq s2, 16(sp) ldq s3, 24(sp) ldq s4, 32(sp) ldq s5, 40(sp) ldq s6, 48(sp) ldt $f2, 56(sp) # pop callee-saved fp registers ldt $f3, 64(sp) ldt $f4, 72(sp) ldt $f5, 80(sp) ldt $f6, 88(sp) ldt $f7, 96(sp) ldt $f8, 104(sp) ldt $f9, 112(sp) ldq gp, 120(sp) # pop the global pointer ldq ra, 128(sp) # pop the return address addq sp, 144, sp # pop the register save space ret zero, (ra), 1 .end context_switch