~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/arm/lib/div64.S

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /arch/arm/lib/div64.S (Architecture sparc) and /arch/ppc/lib/div64.S (Architecture ppc)


  1 /* SPDX-License-Identifier: GPL-2.0-only */       
  2 /*                                                
  3  *  linux/arch/arm/lib/div64.S                    
  4  *                                                
  5  *  Optimized computation of 64-bit dividend /    
  6  *                                                
  7  *  Author:     Nicolas Pitre                     
  8  *  Created:    Oct 5, 2003                       
  9  *  Copyright:  Monta Vista Software, Inc.        
 10  */                                               
 11                                                   
 12 #include <linux/linkage.h>                        
 13 #include <asm/assembler.h>                        
 14 #include <asm/unwind.h>                           
 15                                                   
 16 #ifdef __ARMEB__                                  
 17 #define xh r0                                     
 18 #define xl r1                                     
 19 #define yh r2                                     
 20 #define yl r3                                     
 21 #else                                             
 22 #define xl r0                                     
 23 #define xh r1                                     
 24 #define yl r2                                     
 25 #define yh r3                                     
 26 #endif                                            
 27                                                   
 28 /*                                                
 29  * __do_div64: perform a division with 64-bit     
 30  *                                                
 31  * Note: Calling convention is totally non sta    
 32  *       This is meant to be used by do_div()     
 33  *                                                
 34  * Input parameters:                              
 35  *      xh-xl   = dividend (clobbered)            
 36  *      r4      = divisor (preserved)             
 37  *                                                
 38  * Output values:                                 
 39  *      yh-yl   = result                          
 40  *      xh      = remainder                       
 41  *                                                
 42  * Clobbered regs: xl, ip                         
 43  */                                               
 44                                                   
 45 ENTRY(__do_div64)                                 
 46 UNWIND(.fnstart)                                  
 47                                                   
 48         @ Test for easy paths first.              
 49         subs    ip, r4, #1                        
 50         bls     9f                      @ divi    
 51         tst     ip, r4                            
 52         beq     8f                      @ divi    
 53                                                   
 54         @ See if we need to handle upper 32-bi    
 55         cmp     xh, r4                            
 56         mov     yh, #0                            
 57         blo     3f                                
 58                                                   
 59         @ Align divisor with upper part of div    
 60         @ The aligned divisor is stored in yl     
 61         @ The bit position is stored in ip.       
 62                                                   
 63 #if __LINUX_ARM_ARCH__ >= 5                       
 64                                                   
 65         clz     yl, r4                            
 66         clz     ip, xh                            
 67         sub     yl, yl, ip                        
 68         mov     ip, #1                            
 69         mov     ip, ip, lsl yl                    
 70         mov     yl, r4, lsl yl                    
 71                                                   
 72 #else                                             
 73                                                   
 74         mov     yl, r4                            
 75         mov     ip, #1                            
 76 1:      cmp     yl, #0x80000000                   
 77         cmpcc   yl, xh                            
 78         movcc   yl, yl, lsl #1                    
 79         movcc   ip, ip, lsl #1                    
 80         bcc     1b                                
 81                                                   
 82 #endif                                            
 83                                                   
 84         @ The division loop for needed upper b    
 85         @ Break out early if dividend reaches     
 86 2:      cmp     xh, yl                            
 87         orrcs   yh, yh, ip                        
 88         subscs  xh, xh, yl                        
 89         movsne  ip, ip, lsr #1                    
 90         mov     yl, yl, lsr #1                    
 91         bne     2b                                
 92                                                   
 93         @ See if we need to handle lower 32-bi    
 94 3:      cmp     xh, #0                            
 95         mov     yl, #0                            
 96         cmpeq   xl, r4                            
 97         movlo   xh, xl                            
 98         retlo   lr                                
 99                                                   
100         @ The division loop for lower bit posi    
101         @ Here we shift remainer bits leftward    
102         @ divisor for comparisons, considering    
103         mov     ip, #0x80000000                   
104 4:      movs    xl, xl, lsl #1                    
105         adcs    xh, xh, xh                        
106         beq     6f                                
107         cmpcc   xh, r4                            
108 5:      orrcs   yl, yl, ip                        
109         subcs   xh, xh, r4                        
110         movs    ip, ip, lsr #1                    
111         bne     4b                                
112         ret     lr                                
113                                                   
114         @ The top part of remainder became zer    
115         @ (the 33th bit) this is a false posit    
116         @ Otherwise, if lower part is also nul    
117 6:      bcs     5b                                
118         cmp     xl, #0                            
119         reteq   lr                                
120                                                   
121         @ We still have remainer bits in the l    
122                                                   
123 #if __LINUX_ARM_ARCH__ >= 5                       
124                                                   
125         clz     xh, xl                  @ we k    
126         add     xh, xh, #1                        
127         mov     xl, xl, lsl xh                    
128         mov     ip, ip, lsr xh                    
129                                                   
130 #else                                             
131                                                   
132 7:      movs    xl, xl, lsl #1                    
133         mov     ip, ip, lsr #1                    
134         bcc     7b                                
135                                                   
136 #endif                                            
137                                                   
138         @ Current remainder is now 1.  It is w    
139         @ divisor at this point since divisor     
140         @ If possible, branch for another shif    
141         @ If no bit position left then we are     
142         movs    ip, ip, lsr #1                    
143         mov     xh, #1                            
144         bne     4b                                
145         ret     lr                                
146                                                   
147 8:      @ Division by a power of 2: determine     
148         @ then simply shift values around         
149                                                   
150 #if __LINUX_ARM_ARCH__ >= 5                       
151                                                   
152         clz     ip, r4                            
153         rsb     ip, ip, #31                       
154                                                   
155 #else                                             
156                                                   
157         mov     yl, r4                            
158         cmp     r4, #(1 << 16)                    
159         mov     ip, #0                            
160         movhs   yl, yl, lsr #16                   
161         movhs   ip, #16                           
162                                                   
163         cmp     yl, #(1 << 8)                     
164         movhs   yl, yl, lsr #8                    
165         addhs   ip, ip, #8                        
166                                                   
167         cmp     yl, #(1 << 4)                     
168         movhs   yl, yl, lsr #4                    
169         addhs   ip, ip, #4                        
170                                                   
171         cmp     yl, #(1 << 2)                     
172         addhi   ip, ip, #3                        
173         addls   ip, ip, yl, lsr #1                
174                                                   
175 #endif                                            
176                                                   
177         mov     yh, xh, lsr ip                    
178         mov     yl, xl, lsr ip                    
179         rsb     ip, ip, #32                       
180  ARM(   orr     yl, yl, xh, lsl ip      )         
181  THUMB( lsl     xh, xh, ip              )         
182  THUMB( orr     yl, yl, xh              )         
183         mov     xh, xl, lsl ip                    
184         mov     xh, xh, lsr ip                    
185         ret     lr                                
186                                                   
187         @ eq -> division by 1: obvious enough.    
188 9:      moveq   yl, xl                            
189         moveq   yh, xh                            
190         moveq   xh, #0                            
191         reteq   lr                                
192 UNWIND(.fnend)                                    
193                                                   
194 UNWIND(.fnstart)                                  
195 UNWIND(.pad #4)                                   
196 UNWIND(.save {lr})                                
197 Ldiv0_64:                                         
198         @ Division by 0:                          
199         str     lr, [sp, #-8]!                    
200         bl      __div0                            
201                                                   
202         @ as wrong as it could be...              
203         mov     yl, #0                            
204         mov     yh, #0                            
205         mov     xh, #0                            
206         ldr     pc, [sp], #8                      
207                                                   
208 UNWIND(.fnend)                                    
209 ENDPROC(__do_div64)                               
                                                      

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php