]> git.ipfire.org Git - thirdparty/gcc.git/blob - libgcc/config/m32c/lib1funcs.S
Update copyright years.
[thirdparty/gcc.git] / libgcc / config / m32c / lib1funcs.S
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
46 mem0: .space 1
47 .global mem1
48 mem1: .space 1
49 .global mem2
50 mem2: .space 1
51 .global mem3
52 mem3: .space 1
53 .global mem4
54 mem4: .space 1
55 .global mem5
56 mem5: .space 1
57 .global mem6
58 mem6: .space 1
59 .global mem7
60 mem7: .space 1
61 .global mem8
62 mem8: .space 1
63 .global mem9
64 mem9: .space 1
65 .global mem10
66 mem10: .space 1
67 .global mem11
68 mem11: .space 1
69 .global mem12
70 mem12: .space 1
71 .global mem13
72 mem13: .space 1
73 .global mem14
74 mem14: .space 1
75 .global mem15
76 mem15: .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
176 cmpsi_gt:
177 mov.w #2,r0
178 exitd
179 cmpsi_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
197 cmpsi_gt:
198 mov.w #2,r0
199 exitd
200 cmpsi_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
209 m32c_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