Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-next-2.6
[linux-2.6.git] / arch / blackfin / lib / modsi3.S
1 /*
2  * This program computes 32 bit signed remainder. It calls div32 function
3  * for quotient estimation.
4  *   Registers in:  R0, R1 = Numerator/ Denominator
5  *   Registers out: R0     = Remainder
6  *
7  * Copyright 2004-2009 Analog Devices Inc.
8  *
9  * Licensed under the ADI BSD license or the GPL-2 (or later)
10  */
11
12 .global ___modsi3;
13 .type ___modsi3, STT_FUNC;
14 .extern ___divsi3;
15 .type ___divsi3, STT_FUNC;
16
17 #ifdef CONFIG_ARITHMETIC_OPS_L1
18 .section .l1.text
19 #else
20 .text
21 #endif
22
23 ___modsi3:
24
25         CC=R0==0;
26         IF CC JUMP .LRETURN_R0;         /* Return 0, if numerator  == 0 */
27         CC=R1==0;
28         IF CC JUMP .LRETURN_ZERO;               /* Return 0, if denominator == 0 */
29         CC=R0==R1;
30         IF CC JUMP .LRETURN_ZERO;               /* Return 0, if numerator == denominator */
31         CC = R1 == 1;
32         IF CC JUMP .LRETURN_ZERO;               /* Return 0, if denominator ==  1 */
33         CC = R1 == -1;
34         IF CC JUMP .LRETURN_ZERO;               /* Return 0, if denominator == -1 */
35
36         /* Valid input. Use __divsi3() to compute the quotient, and then
37          * derive the remainder from that. */
38
39         [--SP] = (R7:6);                /* Push  R7 and R6 */
40         [--SP] = RETS;                  /* and return address */
41         R7 = R0;                        /* Copy of R0 */
42         R6 = R1;                        /* Save for later */
43         SP += -12;                      /* Should always provide this space */
44         CALL ___divsi3;                 /* Compute signed quotient using ___divsi3()*/
45         SP += 12;
46         R0 *= R6;                       /* Quotient * divisor */
47         R0 = R7 - R0;                   /* Dividend - (quotient * divisor) */
48         RETS = [SP++];                  /* Get back return address */
49         (R7:6) = [SP++];                /* Pop registers R7 and R4 */
50         RTS;                            /* Store remainder    */
51
52 .LRETURN_ZERO:
53         R0 = 0;
54 .LRETURN_R0:
55         RTS;
56
57 .size ___modsi3, .-___modsi3