PR target/82524
[official-gcc.git] / libgcc / config / m32c / lib1funcs.S
blob6af217a0a1b9c72046914d8251a65220a220bf10
1 /* libgcc routines for R8C/M16C/M32C
2    Copyright (C) 2005-2017 Free Software Foundation, Inc.
3    Contributed by Red Hat.
5    This file is part of GCC.
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.
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.
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.
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/>.  */
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
37 #ifdef L__m32c_memregs
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. */
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
78 #endif
80 #ifdef L__m32c_eh_return
81         .text
82         .global __m32c_eh_return
83 __m32c_eh_return:       
85         /* At this point, r0 has the stack adjustment, r1r3 has the
86            address to return to.  The stack looks like this:
88            old_ra
89            old_fp
90            <- unwound sp
91            ...
92            fb
93            through
94            r0
95            <- sp
97            What we need to do is restore all the registers, update the
98            stack, and return to the right place.
99         */
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 */
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.  */
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
122         /* This is for the "popc sp" below.  */
123         mov.W   a1,[a0] 
125         popm    r0,r1,r2,r3,a0,a1,sb,fb
126         popc    sp
127         rts
128 #endif
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
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
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
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
205 #ifdef L__m32c_jsri16
206         .text
207 #ifdef A16
208         .global m32c_jsri16
209 m32c_jsri16:
210         add.w   #-1, sp
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.  */
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]
225         /* This "returns" to the target address, leaving the pending
226         return address on the stack.  */
227         rts
228 #endif
230 #endif