1; libgcc routines for ARC cpu. 2 3/* Copyright (C) 1995, 1997,2004 Free Software Foundation, Inc. 4 5This file is free software; you can redistribute it and/or modify it 6under the terms of the GNU General Public License as published by the 7Free Software Foundation; either version 2, or (at your option) any 8later version. 9 10In addition to the permissions in the GNU General Public License, the 11Free Software Foundation gives you unlimited permission to link the 12compiled version of this file into combinations with other programs, 13and to distribute those combinations without any restriction coming 14from the use of this file. (The General Public License restrictions 15do apply in other respects; for example, they cover modification of 16the file, and distribution when not linked into a combine 17executable.) 18 19This file is distributed in the hope that it will be useful, but 20WITHOUT ANY WARRANTY; without even the implied warranty of 21MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22General Public License for more details. 23 24You should have received a copy of the GNU General Public License 25along with GCC; see the file COPYING. If not, write to 26the Free Software Foundation, 51 Franklin Street, Fifth Floor, 27Boston, MA 02110-1301, USA. */ 28 29#ifdef L_mulsi3 30 .section .text 31 .align 4 32 33#ifdef __base__ 34 .cpu base 35 .global ___mulsi3 36___mulsi3: 37 38/* This the simple version. 39 40 while (a) 41 { 42 if (a & 1) 43 r += b; 44 a >>= 1; 45 b <<= 1; 46 } 47*/ 48 mov r2,0 ; Accumulate result here. 49.Lloop: 50 sub.f 0,r0,0 ; while (a) 51 nop 52 beq.nd .Ldone 53 and.f 0,r0,1 ; if (a & 1) 54 add.nz r2,r2,r1 ; r += b 55 lsr r0,r0 ; a >>= 1 56 b.d .Lloop 57 lsl r1,r1 ; b <<= 1 58.Ldone: 59 j.d blink 60 mov r0,r2 61#endif 62 63#endif /* L_mulsi3 */ 64 65#ifdef L_umulsidi3 66 .section .text 67 .align 4 68 69#ifdef __base__ 70 .cpu base 71 .global ___umulsidi3 72___umulsidi3: 73 74/* This the simple version. 75 76 while (a) 77 { 78 if (a & 1) 79 r += b; 80 a >>= 1; 81 b <<= 1; 82 } 83*/ 84 mov r2,0 ; Top part of b. 85 mov r3,0 ; Accumulate result here. 86 mov r4,0 87.Lloop: 88 sub.f 0,r0,0 ; while (a) 89 nop 90 beq.nd .Ldone 91 and.f 0,r0,1 ; if (a & 1) 92 sub.f 0,r0,0 93 nop 94 beq .Ldontadd 95 add.f r4,r4,r1 ; r += b 96 adc r3,r3,r2 97.Ldontadd: 98 lsr r0,r0 ; a >>= 1 99 lsl.f r1,r1 ; b <<= 1 100 b.d .Lloop 101 rlc r2,r2 102.Ldone: 103#ifdef __big_endian__ 104 mov r1,r4 105 j.d blink 106 mov r0,r3 107#else 108 mov r0,r4 109 j.d blink 110 mov r1,r3 111#endif 112#endif 113 114#endif /* L_umulsidi3 */ 115 116#ifdef L_divmod_tools 117 118; Utilities used by all routines. 119 120 .section .text 121 .align 4 122 123; inputs: r0 = numerator, r1 = denominator 124; outputs: positive r0/r1, 125; r6.bit1 = sign of numerator, r6.bit0 = sign of result 126 127 .global ___divnorm 128___divnorm: 129 mov r6,0 ; keep sign in r6 130 sub.f 0,r0,0 ; is numerator -ve? 131 sub.lt r0,0,r0 ; negate numerator 132 mov.lt r6,3 ; sign is -ve 133 sub.f 0,r1,0 ; is denominator -ve? 134 sub.lt r1,0,r1 ; negate denominator 135 xor.lt r6,r6,1 ; toggle sign 136 j.nd blink 137 138/* 139unsigned long 140udivmodsi4(int modwanted, unsigned long num, unsigned long den) 141{ 142 unsigned long bit = 1; 143 unsigned long res = 0; 144 145 while (den < num && bit && !(den & (1L<<31))) 146 { 147 den <<=1; 148 bit <<=1; 149 } 150 while (bit) 151 { 152 if (num >= den) 153 { 154 num -= den; 155 res |= bit; 156 } 157 bit >>=1; 158 den >>=1; 159 } 160 if (modwanted) return num; 161 return res; 162} 163*/ 164 165; inputs: r0 = numerator, r1 = denominator 166; outputs: r0 = quotient, r1 = remainder, r2/r3 trashed 167 168 .global ___udivmodsi4 169___udivmodsi4: 170 mov r2,1 ; bit = 1 171 mov r3,0 ; res = 0 172.Lloop1: 173 sub.f 0,r1,r0 ; while (den < num 174 nop 175 bnc.nd .Lloop2 176 sub.f 0,r2,0 ; && bit 177 nop 178 bz.nd .Lloop2 179 lsl.f 0,r1 ; && !(den & (1<<31)) 180 nop 181 bc.nd .Lloop2 182 lsl r1,r1 ; den <<= 1 183 b.d .Lloop1 184 lsl r2,r2 ; bit <<= 1 185.Lloop2: 186 sub.f 0,r2,0 ; while (bit) 187 nop 188 bz.nd .Ldivmodend 189 sub.f 0,r0,r1 ; if (num >= den) 190 nop 191 bc.nd .Lshiftdown 192 sub r0,r0,r1 ; num -= den 193 or r3,r3,r2 ; res |= bit 194.Lshiftdown: 195 lsr r2,r2 ; bit >>= 1 196 b.d .Lloop2 197 lsr r1,r1 ; den >>= 1 198.Ldivmodend: 199 mov r1,r0 ; r1 = mod 200 j.d blink 201 mov r0,r3 ; r0 = res 202 203#endif 204 205#ifdef L_udivsi3 206 .section .text 207 .align 4 208 209#ifdef __base__ 210 .cpu base 211 .global ___udivsi3 212___udivsi3: 213 mov r7,blink 214 bl.nd ___udivmodsi4 215 j.nd r7 216#endif 217 218#endif /* L_udivsi3 */ 219 220#ifdef L_divsi3 221 .section .text 222 .align 4 223 224#ifdef __base__ 225 .cpu base 226 .global ___divsi3 227___divsi3: 228 mov r7,blink 229 bl.nd ___divnorm 230 bl.nd ___udivmodsi4 231 and.f 0,r6,1 232 sub.nz r0,0,r0 ; cannot go in delay slot, has limm value 233 j.nd r7 234#endif 235 236#endif /* L_divsi3 */ 237 238#ifdef L_umodsi3 239 .section .text 240 .align 4 241 242#ifdef __base__ 243 .cpu base 244 .global ___umodsi3 245___umodsi3: 246 mov r7,blink 247 bl.nd ___udivmodsi4 248 j.d r7 249 mov r0,r1 250#endif 251 252#endif /* L_umodsi3 */ 253 254#ifdef L_modsi3 255 .section .text 256 .align 4 257 258#ifdef __base__ 259 .cpu base 260 .global ___modsi3 261___modsi3: 262 mov r7,blink 263 bl.nd ___divnorm 264 bl.nd ___udivmodsi4 265 and.f 0,r6,2 266 sub.nz r1,0,r1 267 j.d r7 268 mov r0,r1 269#endif 270 271#endif /* L_modsi3 */ 272