# # Setjmp/longjmp for MeP # # DJ Delorie, Red Hat Inc. # # 19 32-bit words in the jmpbuf: # $0 # $1 # ... # $15 # $pc # $hi # $lo # # Note that $0 is saved but not restored. It can't be restored # as it's the return value of setjmp, but we save it in case # some application wants to see it in the jmp_buf. Ideally, # we should not need to save anything that is call-clobbered, # but you never know what the user is going to tell gcc with -f # options. .noregerr .text .globl setjmp .type setjmp,@function setjmp: # $1 is the address of the buffer. We return 0 in $0. sw $0, ($1) sw $1, 4($1) sw $2, 8($1) sw $3, 12($1) sw $4, 16($1) sw $5, 20($1) sw $6, 24($1) sw $7, 28($1) sw $8, 32($1) sw $9, 36($1) sw $10, 40($1) sw $11, 44($1) sw $12, 48($1) sw $13, 52($1) sw $14, 56($1) sw $15, 60($1) ldc $0, $lp sw $0, 64($1) ldc $0, $opt sra $0, 24 and3 $0, $0, 3 beqz $0, sj_skip_hilo ldc $0, $hi sw $0, 68($1) ldc $0, $lo sw $0, 72($1) sj_skip_hilo: mov $0, 0 ret .globl longjmp .type longjmp,@function longjmp: # $1 is the address of the buffer. $2 is the value setjmp # returns. We do not faithfully restore $0 or $lp, because # the act of calling setjmp clobbered those anyway. bnez $2, rv_not_zero mov $2, 1 rv_not_zero: # We restore $sp first so we can save the return value there, # otherwise we'd need to have another unrestored register. lw $15, 60($1) add3 $sp, $sp, -4 sw $2, ($sp) # Now restore the general registers. lw $2, 8($1) lw $3, 12($1) lw $4, 16($1) lw $5, 20($1) lw $6, 24($1) lw $7, 28($1) lw $8, 32($1) lw $9, 36($1) lw $10, 40($1) lw $11, 44($1) lw $12, 48($1) lw $13, 52($1) lw $14, 56($1) # We restore $pc's value to $lp so that we can just ret later. lw $0, 64($1) stc $0, $lp ldc $0, $opt sra $0, 24 and3 $0, $0, 3 beqz $0, lj_skip_hilo lw $0, 68($1) stc $0, $hi lw $0, 72($1) stc $0, $lo lj_skip_hilo: # Restore $1 lw $1, 8($1) # Get the return value off the stack, and restore the stack. lw $0, ($sp) add3 $sp, $sp, 4 ret