119 lines
2.0 KiB
ArmAsm
119 lines
2.0 KiB
ArmAsm
|
#
|
||
|
# 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
|