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,mem0
156	mov.w	SAH,mem2
157	mulu.w	SBL,mem0	/* writes to r2r0 */
158	mov.w	SAL,r0
159	mulu.w	SBH,r0		/* writes to r2r0 */
160	add.w	r0,mem2
161	mov.w	SAH,r0
162	mulu.w	SBL,r0
163	add.w	r0,mem2
164	pop.w	r2
165	exitd
166#endif
167
168#ifdef L__m32c_cmpsi2
169	.text
170	.global ___cmpsi2
171___cmpsi2:
172	enter	#0
173	cmp.w	SBH,SAH
174	jgt	cmpsi_gt
175	jlt	cmpsi_lt
176	cmp.w	SBL,SAL
177	jgt	cmpsi_gt
178	jlt	cmpsi_lt
179	mov.w	#1,r0
180	exitd
181cmpsi_gt:
182	mov.w	#2,r0
183	exitd
184cmpsi_lt:
185	mov.w	#0,r0
186	exitd
187#endif
188
189#ifdef L__m32c_ucmpsi2
190	.text
191	.global ___ucmpsi2
192___ucmpsi2:
193	enter	#0
194	cmp.w	SBH,SAH
195	jgtu	cmpsi_gt
196	jltu	cmpsi_lt
197	cmp.w	SBL,SAL
198	jgtu	cmpsi_gt
199	jltu	cmpsi_lt
200	mov.w	#1,r0
201	exitd
202cmpsi_gt:
203	mov.w	#2,r0
204	exitd
205cmpsi_lt:
206	mov.w	#0,r0
207	exitd
208#endif
209
210#ifdef L__m32c_jsri16
211	.data
212m32c_jsri_addr:
213	.byte	0, 0, 0
214m32c_jsri_ret:
215	.byte	0, 0, 0
216
217	.text
218	.global	m32c_jsri16
219m32c_jsri16:
220	pop.w	m32c_jsri_ret
221	pop.b	m32c_jsri_ret+2
222	pop.w	m32c_jsri_addr
223	push.b	m32c_jsri_ret+2
224	push.w	m32c_jsri_ret
225	jmpi.a	m32c_jsri_addr
226
227#endif
228