xref: /netbsd-src/external/gpl3/gcc.old/dist/libgcc/config/m32c/lib1funcs.S (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
1/* libgcc routines for R8C/M16C/M32C
2   Copyright (C) 2005-2020 Free Software Foundation, Inc.
3   Contributed by Red Hat.
4
5   This file is part of GCC.
6
7   GCC is free software; you can redistribute it and/or modify it
8   under the terms of the GNU General Public License as published
9   by the Free Software Foundation; either version 3, or (at your
10   option) any later version.
11
12   GCC is distributed in the hope that it will be useful, but WITHOUT
13   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15   License for more details.
16
17   Under Section 7 of GPL version 3, you are granted additional
18   permissions described in the GCC Runtime Library Exception, version
19   3.1, as published by the Free Software Foundation.
20
21   You should have received a copy of the GNU General Public License and
22   a copy of the GCC Runtime Library Exception along with this program;
23   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24   <http://www.gnu.org/licenses/>.  */
25
26#if defined(__r8c_cpu__) || defined(__m16c_cpu__)
27#define A16
28#define A(n,w) n
29#define W w
30#else
31#define A24
32#define A(n,w) w
33#define W l
34#endif
35
36
37#ifdef L__m32c_memregs
38
39/* Warning: these memory locations are used as a register bank.  They
40   *must* end up consecutive in any final executable, so you may *not*
41   use the otherwise obvious ".comm" directive to allocate space for
42   them. */
43
44	.bss
45	.global	mem0
46mem0:	.space	1
47	.global	mem1
48mem1:	.space	1
49	.global	mem2
50mem2:	.space	1
51	.global	mem3
52mem3:	.space	1
53	.global	mem4
54mem4:	.space	1
55	.global	mem5
56mem5:	.space	1
57	.global	mem6
58mem6:	.space	1
59	.global	mem7
60mem7:	.space	1
61	.global	mem8
62mem8:	.space	1
63	.global	mem9
64mem9:	.space	1
65	.global	mem10
66mem10:	.space	1
67	.global	mem11
68mem11:	.space	1
69	.global	mem12
70mem12:	.space	1
71	.global	mem13
72mem13:	.space	1
73	.global	mem14
74mem14:	.space	1
75	.global	mem15
76mem15:	.space	1
77
78#endif
79
80#ifdef L__m32c_eh_return
81	.text
82	.global __m32c_eh_return
83__m32c_eh_return:
84
85	/* At this point, r0 has the stack adjustment, r1r3 has the
86	   address to return to.  The stack looks like this:
87
88	   old_ra
89	   old_fp
90	   <- unwound sp
91	   ...
92	   fb
93	   through
94	   r0
95	   <- sp
96
97	   What we need to do is restore all the registers, update the
98	   stack, and return to the right place.
99	*/
100
101	stc	sp,a0
102
103	add.W	A(#16,#24),a0
104	/* a0 points to the current stack, just above the register
105	   save areas */
106
107	mov.w	a0,a1
108	exts.w	r0
109	sub.W	A(r0,r2r0),a1
110	sub.W	A(#3,#4),a1
111	/* a1 points to the new stack.  */
112
113	/* This is for the "rts" below.  */
114	mov.w	r1,[a1]
115#ifdef A16
116	mov.w	r2,r1
117	mov.b	r1l,2[a1]
118#else
119	mov.w	r2,2[a1]
120#endif
121
122	/* This is for the "popc sp" below.  */
123	mov.W	a1,[a0]
124
125	popm    r0,r1,r2,r3,a0,a1,sb,fb
126	popc	sp
127	rts
128#endif
129
130/* SImode arguments for SI foo(SI,SI) functions.  */
131#ifdef A16
132#define SAL  5[fb]
133#define SAH  7[fb]
134#define SBL  9[fb]
135#define SBH 11[fb]
136#else
137#define SAL  8[fb]
138#define SAH 10[fb]
139#define SBL 12[fb]
140#define SBH 14[fb]
141#endif
142
143#ifdef L__m32c_mulsi3
144	.text
145	.global ___mulsi3
146___mulsi3:
147	enter	#0
148	push.w	r2
149	mov.w	SAL,r0
150	mulu.w	SBL,r0		/* writes to r2r0 */
151	mov.w	r0,mem0
152	mov.w	r2,mem2
153	mov.w	SAL,r0
154	mulu.w	SBH,r0		/* writes to r2r0 */
155	add.w	r0,mem2
156	mov.w	SAH,r0
157	mulu.w	SBL,r0		/* writes to r2r0 */
158	add.w	r0,mem2
159	pop.w	r2
160	exitd
161#endif
162
163#ifdef L__m32c_cmpsi2
164	.text
165	.global ___cmpsi2
166___cmpsi2:
167	enter	#0
168	cmp.w	SBH,SAH
169	jgt	cmpsi_gt
170	jlt	cmpsi_lt
171	cmp.w	SBL,SAL
172	jgt	cmpsi_gt
173	jlt	cmpsi_lt
174	mov.w	#1,r0
175	exitd
176cmpsi_gt:
177	mov.w	#2,r0
178	exitd
179cmpsi_lt:
180	mov.w	#0,r0
181	exitd
182#endif
183
184#ifdef L__m32c_ucmpsi2
185	.text
186	.global ___ucmpsi2
187___ucmpsi2:
188	enter	#0
189	cmp.w	SBH,SAH
190	jgtu	cmpsi_gt
191	jltu	cmpsi_lt
192	cmp.w	SBL,SAL
193	jgtu	cmpsi_gt
194	jltu	cmpsi_lt
195	mov.w	#1,r0
196	exitd
197cmpsi_gt:
198	mov.w	#2,r0
199	exitd
200cmpsi_lt:
201	mov.w	#0,r0
202	exitd
203#endif
204
205#ifdef L__m32c_jsri16
206	.text
207#ifdef A16
208	.global	m32c_jsri16
209m32c_jsri16:
210	add.w	#-1, sp
211
212	/* Read the address (16 bits) and return address (24 bits) off
213	the stack.  */
214	mov.w	4[sp], r0
215	mov.w	1[sp], r3
216	mov.b	3[sp], a0 /* This zero-extends, so the high byte has
217			     zero in it.  */
218
219	/* Write the return address, then new address, to the stack.  */
220	mov.w	a0, 1[sp] /* Just to get the zero in 2[sp].  */
221	mov.w	r0, 0[sp]
222	mov.w	r3, 3[sp]
223	mov.b	a0, 5[sp]
224
225	/* This "returns" to the target address, leaving the pending
226	return address on the stack.  */
227	rts
228#endif
229
230#endif
231