OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgcc/] [config/] [microblaze/] [moddi3.S] - Blame information for rev 758

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 734 jeremybenn
###################################
2
#
3
#  Copyright 2009, 2010, 2011 Free Software Foundation, Inc.
4
#
5
#  Contributed by Michael Eager .
6
#
7
#  This file is free software; you can redistribute it and/or modify it
8
#  under the terms of the GNU General Public License as published by the
9
#  Free Software Foundation; either version 3, or (at your option) any
10
#  later version.
11
#
12
#  GCC is distributed in the hope that it will be useful, but WITHOUT
13
#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14
#  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15
#  License for more details.
16
#
17
#  Under Section 7 of GPL version 3, you are granted additional
18
#  permissions described in the GCC Runtime Library Exception, version
19
#  3.1, as published by the Free Software Foundation.
20
#
21
#  You should have received a copy of the GNU General Public License and
22
#  a copy of the GCC Runtime Library Exception along with this program;
23
#  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24
#  .
25
#
26
#  modsi3.S
27
#
28
#  modulo operation for 64 bit integers.
29
#
30
#######################################
31
 
32
 
33
        .globl  __moddi3
34
        .ent    __moddi3
35
__moddi3:
36
        .frame  r1,0,r15
37
 
38
#Change the stack pointer value and Save callee saved regs
39
        addik   r1,r1,-24
40
        swi     r25,r1,0
41
        swi     r26,r1,4
42
        swi     r27,r1,8        # used for sign
43
        swi     r28,r1,12       # used for loop count
44
        swi     r29,r1,16       # Used for div value High
45
        swi     r30,r1,20       # Used for div value Low
46
 
47
#Check for Zero Value in the divisor/dividend
48
        OR      r9,r5,r6                        # Check for the op1 being zero
49
        BEQID   r9,$LaResult_Is_Zero            # Result is zero
50
        OR      r9,r7,r8                        # Check for the dividend being zero
51
        BEQI    r9,$LaDiv_By_Zero               # Div_by_Zero   # Division Error
52
        BGEId   r5,$La1_Pos
53
        XOR     r27,r5,r7                       # Get the sign of the result
54
        RSUBI   r6,r6,0                         # Make dividend positive
55
        RSUBIC  r5,r5,0                         # Make dividend positive
56
$La1_Pos:
57
        BGEI    r7,$La2_Pos
58
        RSUBI   r8,r8,0                         # Make Divisor Positive
59
        RSUBIC  r9,r9,0                         # Make Divisor Positive
60
$La2_Pos:
61
        ADDIK   r4,r0,0                         # Clear mod low
62
        ADDIK   r3,r0,0                         # Clear mod high
63
        ADDIK   r29,r0,0                        # clear div high
64
        ADDIK   r30,r0,0                        # clear div low
65
        ADDIK   r28,r0,64                       # Initialize the loop count
66
   # First part try to find the first '1' in the r5/r6
67
$LaDIV1:
68
        ADD     r6,r6,r6
69
        ADDC    r5,r5,r5                        # left shift logical r5
70
        BGEID   r5,$LaDIV1
71
        ADDIK   r28,r28,-1
72
$LaDIV2:
73
        ADD     r6,r6,r6
74
        ADDC    r5,r5,r5        # left shift logical r5/r6 get the '1' into the Carry
75
        ADDC    r4,r4,r4        # Move that bit into the Mod register
76
        ADDC    r3,r3,r3        # Move carry into high mod register
77
        rsub    r18,r7,r3       # Compare the High Parts of Mod and Divisor
78
        bnei    r18,$L_High_EQ
79
        rsub    r18,r6,r4       # Compare Low Parts only if Mod[h] == Divisor[h]
80
$L_High_EQ:
81
        rSUB    r26,r8,r4       # Subtract divisor[L] from Mod[L]
82
        rsubc   r25,r7,r3       # Subtract divisor[H] from Mod[H]
83
        BLTi    r25,$LaMOD_TOO_SMALL
84
        OR      r3,r0,r25       # move r25 to mod [h]
85
        OR      r4,r0,r26       # move r26 to mod [l]
86
        ADDI    r30,r30,1
87
        ADDC    r29,r29,r0
88
$LaMOD_TOO_SMALL:
89
        ADDIK   r28,r28,-1
90
        BEQi    r28,$LaLOOP_END
91
        ADD     r30,r30,r30             # Shift in the '1' into div [low]
92
        ADDC    r29,r29,r29             # Move the carry generated into high
93
        BRI     $LaDIV2   # Div2
94
$LaLOOP_END:
95
        BGEI    r27,$LaRETURN_HERE
96
        rsubi   r30,r30,0
97
        rsubc   r29,r29,r0
98
        BRI     $LaRETURN_HERE
99
$LaDiv_By_Zero:
100
$LaResult_Is_Zero:
101
        or      r29,r0,r0       # set result to 0 [High]
102
        or      r30,r0,r0       # set result to 0 [Low]
103
$LaRETURN_HERE:
104
# Restore values of CSRs and that of r29 and the divisor and the dividend
105
 
106
        lwi     r25,r1,0
107
        lwi     r26,r1,4
108
        lwi     r27,r1,8
109
        lwi     r28,r1,12
110
        lwi     r29,r1,16
111
        lwi     r30,r1,20
112
        rtsd    r15,8
113
        addik r1,r1,24
114
        .end __moddi3
115
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.