1193326Sed/* Generic unsigned 32 bit division implementation. 2193326Sed Copyright (C) 2009-2015 Free Software Foundation, Inc. 3193326Sed Contributed by Embecosm on behalf of Adapteva, Inc. 4193326Sed 5193326SedThis file is part of GCC. 6193326Sed 7193326SedThis file is free software; you can redistribute it and/or modify it 8193326Sedunder the terms of the GNU General Public License as published by the 9193326SedFree Software Foundation; either version 3, or (at your option) any 10205219Srdivackylater version. 11205219Srdivacky 12193326SedThis file is distributed in the hope that it will be useful, but 13193326SedWITHOUT ANY WARRANTY; without even the implied warranty of 14193326SedMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15193326SedGeneral Public License for more details. 16193326Sed 17193326SedUnder Section 7 of GPL version 3, you are granted additional 18198092Srdivackypermissions described in the GCC Runtime Library Exception, version 19234353Sdim3.1, as published by the Free Software Foundation. 20193326Sed 21212904SdimYou should have received a copy of the GNU General Public License and 22202879Srdivackya copy of the GCC Runtime Library Exception along with this program; 23234353Sdimsee the files COPYING3 and COPYING.RUNTIME respectively. If not, see 24234353Sdim<http://www.gnu.org/licenses/>. */ 25198092Srdivacky 26234353Sdimtypedef union { unsigned int i; float f; } fu; 27193326Sed 28193326Sedunsigned int __udivsi3 (unsigned int a, unsigned int b); 29193326Sed 30193326Sedunsigned int 31198092Srdivacky__udivsi3 (unsigned int a, unsigned int b) 32198092Srdivacky{ 33198092Srdivacky unsigned int d, t, s0, s1, s2, r0, r1; 34193326Sed fu u0, u1, u2, u1b, u2b; 35198092Srdivacky 36193326Sed if (b > a) 37193326Sed return 0; 38198092Srdivacky 39198092Srdivacky /* Compute difference in number of bits in S0. */ 40206084Srdivacky u0.i = 0x40000000; 41218893Sdim u1b.i = u2b.i = u0.i; 42205219Srdivacky u1.i = a; 43234353Sdim u2.i = b; 44239462Sdim u1.i = a | u0.i; 45234353Sdim t = 0x4b800000 | ((a >> 23) & 0xffff); 46198092Srdivacky if (a >> 23) 47195099Sed { 48195099Sed u1.i = t; 49195099Sed u1b.i = 0x4b800000; 50198092Srdivacky } 51195341Sed u2.i = b | u0.i; 52198092Srdivacky t = 0x4b800000 | ((b >> 23) & 0xffff); 53195099Sed if (b >> 23) 54195099Sed { 55195099Sed u2.i = t; 56198092Srdivacky u2b.i = 0x4b800000; 57198092Srdivacky } 58195099Sed u1.f = u1.f - u1b.f; 59195099Sed u2.f = u2.f - u2b.f; 60198092Srdivacky s1 = u1.i >> 23; 61195099Sed s2 = u2.i >> 23; 62195099Sed s0 = s1 - s2; 63198092Srdivacky 64198092Srdivacky b <<= s0; 65195341Sed d = b - 1; 66195341Sed 67195099Sed r0 = 1 << s0; 68198092Srdivacky r1 = 0; 69195099Sed t = a - b; 70195099Sed if (t <= a) 71195099Sed { 72198092Srdivacky a = t; 73195099Sed r1 = r0; 74195099Sed } 75195099Sed 76195099Sed#define STEP(n) case n: a += a; t = a - d; if (t <= a) a = t; 77195099Sed switch (s0) 78195099Sed { 79195099Sed STEP (31) 80195099Sed STEP (30) 81195099Sed STEP (29) 82198092Srdivacky STEP (28) 83195341Sed STEP (27) 84195341Sed STEP (26) 85195341Sed STEP (25) 86195341Sed STEP (24) 87195341Sed STEP (23) 88198092Srdivacky STEP (22) 89195341Sed STEP (21) 90195341Sed STEP (20) 91195341Sed STEP (19) 92195341Sed STEP (18) 93195341Sed STEP (17) 94198092Srdivacky STEP (16) 95195341Sed STEP (15) 96195341Sed STEP (14) 97198092Srdivacky STEP (13) 98195099Sed STEP (12) 99195099Sed STEP (11) 100195099Sed STEP (10) 101198092Srdivacky STEP (9) 102239462Sdim STEP (8) 103210299Sed STEP (7) 104210299Sed STEP (6) 105210299Sed STEP (5) 106210299Sed STEP (4) 107210299Sed STEP (3) 108210299Sed STEP (2) 109210299Sed STEP (1) 110210299Sed case 0: ; 111210299Sed } 112210299Sed r0 = r1 | (r0-1 & a); 113234353Sdim return r0; 114239462Sdim} 115210299Sed