1/*  Copyright (c) 2003 DJ Delorie, Red Hat Inc. */
2#
3#  Setjmp/longjmp for MeP
4#
5#
6#  19 32-bit words in the jmpbuf:
7#    $0
8#    $1
9#    ...
10#    $15
11#    $pc
12#    $hi
13#    $lo
14#
15#  Note that $0 is saved but not restored.  It can't be restored
16#  as it's the return value of setjmp, but we save it in case
17#  some application wants to see it in the jmp_buf.  Ideally,
18#  we should not need to save anything that is call-clobbered,
19#  but you never know what the user is going to tell gcc with -f
20#  options.
21
22	.noregerr
23	.text
24
25	.globl	setjmp
26	.type	setjmp,@function
27
28setjmp:
29
30	# $1 is the address of the buffer.  We return 0 in $0.
31
32	sw	$0, ($1)
33	sw	$1, 4($1)
34	sw	$2, 8($1)
35	sw	$3, 12($1)
36	sw	$4, 16($1)
37	sw	$5, 20($1)
38	sw	$6, 24($1)
39	sw	$7, 28($1)
40	sw	$8, 32($1)
41	sw	$9, 36($1)
42	sw	$10, 40($1)
43	sw	$11, 44($1)
44	sw	$12, 48($1)
45	sw	$13, 52($1)
46	sw	$14, 56($1)
47	sw	$15, 60($1)
48
49	ldc	$0, $lp
50	sw	$0, 64($1)
51	ldc	$0, $opt
52	sra	$0, 24
53	and3	$0, $0, 3
54	beqz	$0, sj_skip_hilo
55	ldc	$0, $hi
56	sw	$0, 68($1)
57	ldc	$0, $lo
58	sw	$0, 72($1)
59sj_skip_hilo:
60
61	mov	$0, 0
62	ret
63
64	.globl	longjmp
65	.type	longjmp,@function
66
67longjmp:
68
69	# $1 is the address of the buffer.  $2 is the value setjmp
70	# returns.  We do not faithfully restore $0 or $lp, because
71	# the act of calling setjmp clobbered those anyway.
72
73	bnez	$2, rv_not_zero
74	mov	$2, 1
75rv_not_zero:
76
77	# We restore $sp first so we can save the return value there,
78	# otherwise we'd need to have another unrestored register.
79	lw	$15, 60($1)
80	add3	$sp, $sp, -4
81	sw	$2, ($sp)
82
83	# Now restore the general registers.
84	lw	$2, 8($1)
85	lw	$3, 12($1)
86	lw	$4, 16($1)
87	lw	$5, 20($1)
88	lw	$6, 24($1)
89	lw	$7, 28($1)
90	lw	$8, 32($1)
91	lw	$9, 36($1)
92	lw	$10, 40($1)
93	lw	$11, 44($1)
94	lw	$12, 48($1)
95	lw	$13, 52($1)
96	lw	$14, 56($1)
97
98	# We restore $pc's value to $lp so that we can just ret later.
99	lw	$0, 64($1)
100	stc	$0, $lp
101	ldc	$0, $opt
102	sra	$0, 24
103	and3	$0, $0, 3
104	beqz	$0, lj_skip_hilo
105	lw	$0, 68($1)
106	stc	$0, $hi
107	lw	$0, 72($1)
108	stc	$0, $lo
109lj_skip_hilo:
110
111	# Restore $1
112	lw	$1, 8($1)
113
114	# Get the return value off the stack, and restore the stack.
115	lw	$0, ($sp)
116	add3	$sp, $sp, 4
117
118	ret
119