2008-08-17 Paul Thomas <pault@gcc.gnu.org>
[official-gcc.git] / gcc / config / mips / vr4120-div.S
blob79ede3de9552f5fbd64910073c0eadb0879b21f3
1 /* Support file for -mfix-vr4120.
2    Copyright (C) 2002, 2004, 2007 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
11 GCC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17         along with GCC; see the file COPYING3.  If not see
18 <http://www.gnu.org/licenses/>.  */
20 /* This file contains functions which implement divsi3 and modsi3 for
21    -mfix-vr4120.  div and ddiv do not give the correct result when one
22    of the operands is negative.  */
24         .set    nomips16
26 #define DIV                                                             \
27         xor     $3,$4,$5        /* t = x ^ y */ ;                       \
28         li      $2,0x80000000;                                          \
29         .set    noreorder;                                              \
30         bgez    $4,1f           /* x >= 0 */;                           \
31         and     $3,$3,$2        /* t = (x ^ y) & 0x80000000 in delay slot */ ;\
32         .set    reorder;                                                \
33         subu    $4,$0,$4        /* x = -x */ ;                          \
34 1:;                                                                     \
35         .set    noreorder;                                              \
36         bgez    $5,2f           /* y >= 0 */ ;                          \
37         nop;                                                            \
38         subu    $5,$0,$5        /* y = -y */ ;                          \
39         .set    reorder;                                                \
40 2:;                                                                     \
41         divu    $0,$4,$5;       /* we use divu because of INT_MIN */    \
42         .set    noreorder;                                              \
43         bne     $5,$0,3f;                                               \
44         nop;                                                            \
45         break   7               /* division on zero y */ ;              \
46 3:;                                                                     \
47         .set    reorder;                                                \
48         mflo    $2              /* r = x / y */ ;                       \
49         .set    noreorder;                                              \
50         beq     $3,$0,4f        /* t == 0 */ ;                          \
51         nop;                                                            \
52         subu    $2,$0,$2        /* r = -r */ ;                          \
53         .set    reorder;                                                \
56         .globl  __vr4120_divsi3
57         .ent    __vr4120_divsi3
58 __vr4120_divsi3:
59         DIV
60         j       $31
61         .end    __vr4120_divsi3
63         .globl  __vr4120_modsi3
64         .ent    __vr4120_modsi3
65 __vr4120_modsi3:
66         move    $6,$4           # x1 = x
67         move    $7,$5           # y1 = y
68         DIV
69         mult    $2,$7           # r = r * y1
70         mflo    $2
71         .set    noreorder
72         j       $31
73         subu    $2,$6,$2        # r = x1 - r  in delay slot
74         .end    __vr4120_modsi3