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