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