]>
Commit | Line | Data |
---|---|---|
fdc715a1 RH |
1 | /* Copyright (C) 2004 Free Software Foundation, Inc. |
2 | This file is part of the GNU C Library. | |
3 | ||
4 | The GNU C Library is free software; you can redistribute it and/or | |
5 | modify it under the terms of the GNU Lesser General Public | |
6 | License as published by the Free Software Foundation; either | |
7 | version 2.1 of the License, or (at your option) any later version. | |
8 | ||
9 | The GNU C Library is distributed in the hope that it will be useful, | |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
12 | Lesser General Public License for more details. | |
13 | ||
14 | You should have received a copy of the GNU Lesser General Public | |
15 | License along with the GNU C Library; if not, write to the Free | |
16 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | |
17 | 02111-1307 USA. */ | |
18 | ||
19 | /* Common bits for implementing software divide. */ | |
20 | ||
21 | #include <sysdep.h> | |
22 | #ifdef __linux__ | |
23 | # include <asm/gentrap.h> | |
24 | # include <asm/pal.h> | |
25 | #else | |
26 | # include <machine/pal.h> | |
27 | #endif | |
28 | ||
29 | /* These are not normal C functions. Argument registers are t10 and t11; | |
30 | the result goes in t12; the return address is in t9. Only t12 and AT | |
31 | may be clobbered. */ | |
32 | #define X t10 | |
33 | #define Y t11 | |
34 | #define RV t12 | |
35 | #define RA t9 | |
36 | ||
0ecb606c JJ |
37 | /* The secureplt format does not allow the division routines to be called |
38 | via plt; there aren't enough registers free to be clobbered. Avoid | |
39 | setting the symbol type to STT_FUNC, so that the linker won't be tempted | |
40 | to create a plt entry. */ | |
41 | #define funcnoplt notype | |
42 | ||
fdc715a1 RH |
43 | /* None of these functions should use implicit anything. */ |
44 | .set nomacro | |
45 | .set noat | |
46 | ||
47 | /* Code fragment to invoke _mcount for profiling. This should be invoked | |
48 | directly after allocation of the stack frame. */ | |
49 | .macro CALL_MCOUNT | |
50 | #ifdef PROF | |
51 | stq ra, 0(sp) | |
52 | stq pv, 8(sp) | |
53 | stq gp, 16(sp) | |
54 | cfi_rel_offset (ra, 0) | |
55 | cfi_rel_offset (pv, 8) | |
56 | cfi_rel_offset (gp, 16) | |
57 | br AT, 1f | |
58 | .set macro | |
59 | 1: ldgp gp, 0(AT) | |
60 | mov RA, ra | |
61 | lda AT, _mcount | |
62 | jsr AT, (AT), _mcount | |
63 | .set nomacro | |
64 | ldq ra, 0(sp) | |
65 | ldq pv, 8(sp) | |
66 | ldq gp, 16(sp) | |
67 | cfi_restore (ra) | |
68 | cfi_restore (pv) | |
69 | cfi_restore (gp) | |
70 | /* Realign subsequent code with what we'd have without this | |
71 | macro at all. This means aligned with one arithmetic insn | |
72 | used within the bundle. */ | |
73 | .align 4 | |
74 | nop | |
75 | #endif | |
76 | .endm | |
77 | ||
78 | /* In order to make the below work, all top-level divide routines must | |
79 | use the same frame size. */ | |
febcd836 | 80 | #define FRAME 64 |
fdc715a1 RH |
81 | |
82 | /* Code fragment to generate an integer divide-by-zero fault. When | |
83 | building libc.so, we arrange for there to be one copy of this code | |
84 | placed late in the dso, such that all branches are forward. When | |
85 | building libc.a, we use multiple copies to avoid having an out of | |
86 | range branch. Users should jump to DIVBYZERO. */ | |
87 | ||
88 | .macro DO_DIVBYZERO | |
89 | #ifdef PIC | |
90 | #define DIVBYZERO __divbyzero | |
91 | .section .gnu.linkonce.t.divbyzero, "ax", @progbits | |
92 | .globl __divbyzero | |
93 | .type __divbyzero, @function | |
94 | .usepv __divbyzero, no | |
95 | .hidden __divbyzero | |
96 | #else | |
97 | #define DIVBYZERO $divbyzero | |
98 | #endif | |
99 | ||
100 | .align 4 | |
101 | DIVBYZERO: | |
102 | cfi_startproc | |
103 | cfi_return_column (RA) | |
104 | cfi_def_cfa_offset (FRAME) | |
105 | ||
106 | mov a0, RV | |
107 | unop | |
108 | lda a0, GEN_INTDIV | |
109 | call_pal PAL_gentrap | |
110 | ||
111 | mov RV, a0 | |
112 | clr RV | |
113 | lda sp, FRAME(sp) | |
114 | cfi_def_cfa_offset (0) | |
115 | ret $31, (RA), 1 | |
116 | ||
117 | cfi_endproc | |
118 | .size DIVBYZERO, .-DIVBYZERO | |
119 | .endm | |
165634aa RH |
120 | |
121 | /* Like the ev6 instructions, but fall back to stack use on prior machines. */ | |
122 | ||
123 | .arch ev6 | |
124 | ||
125 | .macro _ITOFS gr, fr, slot | |
126 | #ifdef __alpha_fix__ | |
127 | itofs \gr, \fr | |
128 | #else | |
dd340846 RH |
129 | stl \gr, \slot(sp) |
130 | lds \fr, \slot(sp) | |
165634aa RH |
131 | #endif |
132 | .endm | |
133 | ||
134 | .macro _ITOFT gr, fr, slot | |
135 | #ifdef __alpha_fix__ | |
136 | itoft \gr, \fr | |
137 | #else | |
dd340846 RH |
138 | stq \gr, \slot(sp) |
139 | ldt \fr, \slot(sp) | |
165634aa RH |
140 | #endif |
141 | .endm | |
142 | ||
143 | .macro _FTOIT fr, gr, slot | |
144 | #ifdef __alpha_fix__ | |
145 | ftoit \fr, \gr | |
146 | #else | |
dd340846 RH |
147 | stt \fr, \slot(sp) |
148 | ldq \gr, \slot(sp) | |
165634aa RH |
149 | #endif |
150 | .endm | |
151 | ||
152 | /* Similarly, but move two registers. Schedules better for pre-ev6. */ | |
153 | ||
154 | .macro _ITOFT2 gr1, fr1, slot1, gr2, fr2, slot2 | |
155 | #ifdef __alpha_fix__ | |
156 | itoft \gr1, \fr1 | |
157 | itoft \gr2, \fr2 | |
158 | #else | |
dd340846 RH |
159 | stq \gr1, \slot1(sp) |
160 | stq \gr2, \slot2(sp) | |
161 | ldt \fr1, \slot1(sp) | |
162 | ldt \fr2, \slot2(sp) | |
165634aa RH |
163 | #endif |
164 | .endm |