summaryrefslogtreecommitdiffstats
path: root/arch/blackfin/lib/divsi3.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/blackfin/lib/divsi3.S')
-rw-r--r--arch/blackfin/lib/divsi3.S212
1 files changed, 0 insertions, 212 deletions
diff --git a/arch/blackfin/lib/divsi3.S b/arch/blackfin/lib/divsi3.S
deleted file mode 100644
index 32eb7c8de1..0000000000
--- a/arch/blackfin/lib/divsi3.S
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * File: arch/blackfin/lib/divsi3.S
- * Based on:
- * Author:
- *
- * Created:
- * Description: 16 / 32 bit signed division.
- * Special cases :
- * 1) If(numerator == 0)
- * return 0
- * 2) If(denominator ==0)
- * return positive max = 0x7fffffff
- * 3) If(numerator == denominator)
- * return 1
- * 4) If(denominator ==1)
- * return numerator
- * 5) If(denominator == -1)
- * return -numerator
- *
- * Operand : R0 - Numerator (i)
- * R1 - Denominator (i)
- * R0 - Quotient (o)
- * Registers Used : R2-R7,P0-P2
- * Rev: $Id: divsi3.S 2794 2007-03-05 05:27:47Z cooloney $
- *
- * Modified:
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-.global ___divsi3;
-
-#ifdef CONFIG_ARITHMETIC_OPS_L1
-.section .l1.text
-#else
-.text
-#endif
-
-.align 2;
-___divsi3 :
-
-
- R3 = R0 ^ R1;
- R0 = ABS R0;
-
- CC = V;
-
- r3 = rot r3 by -1;
- r1 = abs r1; /* now both positive, r3.30 means "negate result",
- ** r3.31 means overflow, add one to result
- */
- cc = r0 < r1;
- if cc jump .Lret_zero;
- r2 = r1 >> 15;
- cc = r2;
- if cc jump .Lidents;
- r2 = r1 << 16;
- cc = r2 <= r0;
- if cc jump .Lidents;
-
- DIVS(R0, R1);
- DIVQ(R0, R1);
- DIVQ(R0, R1);
- DIVQ(R0, R1);
- DIVQ(R0, R1);
- DIVQ(R0, R1);
- DIVQ(R0, R1);
- DIVQ(R0, R1);
- DIVQ(R0, R1);
- DIVQ(R0, R1);
- DIVQ(R0, R1);
- DIVQ(R0, R1);
- DIVQ(R0, R1);
- DIVQ(R0, R1);
- DIVQ(R0, R1);
- DIVQ(R0, R1);
- DIVQ(R0, R1);
-
- R0 = R0.L (Z);
- r1 = r3 >> 31; /* add overflow issue back in */
- r0 = r0 + r1;
- r1 = -r0;
- cc = bittst(r3, 30);
- if cc r0 = r1;
- RTS;
-
-/* Can't use the primitives. Test common identities.
-** If the identity is true, return the value in R2.
-*/
-
-.Lidents:
- CC = R1 == 0; /* check for divide by zero */
- IF CC JUMP .Lident_return;
-
- CC = R0 == 0; /* check for division of zero */
- IF CC JUMP .Lzero_return;
-
- CC = R0 == R1; /* check for identical operands */
- IF CC JUMP .Lident_return;
-
- CC = R1 == 1; /* check for divide by 1 */
- IF CC JUMP .Lident_return;
-
- R2.L = ONES R1;
- R2 = R2.L (Z);
- CC = R2 == 1;
- IF CC JUMP .Lpower_of_two;
-
- /* Identities haven't helped either.
- ** Perform the full division process.
- */
-
- P1 = 31; /* Set loop counter */
-
- [--SP] = (R7:5); /* Push registers R5-R7 */
- R2 = -R1;
- [--SP] = R2;
- R2 = R0 << 1; /* R2 lsw of dividend */
- R6 = R0 ^ R1; /* Get sign */
- R5 = R6 >> 31; /* Shift sign to LSB */
-
- R0 = 0 ; /* Clear msw partial remainder */
- R2 = R2 | R5; /* Shift quotient bit */
- R6 = R0 ^ R1; /* Get new quotient bit */
-
- LSETUP(.Llst,.Llend) LC0 = P1; /* Setup loop */
-.Llst: R7 = R2 >> 31; /* record copy of carry from R2 */
- R2 = R2 << 1; /* Shift 64 bit dividend up by 1 bit */
- R0 = R0 << 1 || R5 = [SP];
- R0 = R0 | R7; /* and add carry */
- CC = R6 < 0; /* Check quotient(AQ) */
- /* we might be subtracting divisor (AQ==0) */
- IF CC R5 = R1; /* or we might be adding divisor (AQ==1)*/
- R0 = R0 + R5; /* do add or subtract, as indicated by AQ */
- R6 = R0 ^ R1; /* Generate next quotient bit */
- R5 = R6 >> 31;
- /* Assume AQ==1, shift in zero */
- BITTGL(R5,0); /* tweak AQ to be what we want to shift in */
-.Llend: R2 = R2 + R5; /* and then set shifted-in value to
- ** tweaked AQ.
- */
- r1 = r3 >> 31;
- r2 = r2 + r1;
- cc = bittst(r3,30);
- r0 = -r2;
- if !cc r0 = r2;
- SP += 4;
- (R7:5)= [SP++]; /* Pop registers R6-R7 */
- RTS;
-
-.Lident_return:
- CC = R1 == 0; /* check for divide by zero => 0x7fffffff */
- R2 = -1 (X);
- R2 >>= 1;
- IF CC JUMP .Ltrue_ident_return;
-
- CC = R0 == R1; /* check for identical operands => 1 */
- R2 = 1 (Z);
- IF CC JUMP .Ltrue_ident_return;
-
- R2 = R0; /* assume divide by 1 => numerator */
- /*FALLTHRU*/
-
-.Ltrue_ident_return:
- R0 = R2; /* Return an identity value */
- R2 = -R2;
- CC = bittst(R3,30);
- IF CC R0 = R2;
-.Lzero_return:
- RTS; /* ...including zero */
-
-.Lpower_of_two:
- /* Y has a single bit set, which means it's a power of two.
- ** That means we can perform the division just by shifting
- ** X to the right the appropriate number of bits
- */
-
- /* signbits returns the number of sign bits, minus one.
- ** 1=>30, 2=>29, ..., 0x40000000=>0. Which means we need
- ** to shift right n-signbits spaces. It also means 0x80000000
- ** is a special case, because that *also* gives a signbits of 0
- */
-
- R2 = R0 >> 31;
- CC = R1 < 0;
- IF CC JUMP .Ltrue_ident_return;
-
- R1.l = SIGNBITS R1;
- R1 = R1.L (Z);
- R1 += -30;
- R0 = LSHIFT R0 by R1.L;
- r1 = r3 >> 31;
- r0 = r0 + r1;
- R2 = -R0; // negate result if necessary
- CC = bittst(R3,30);
- IF CC R0 = R2;
- RTS;
-
-.Lret_zero:
- R0 = 0;
- RTS;