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