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

TOMOYO Linux Cross Reference
Linux/arch/arm/nwfpe/fpa11_cprt.c

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/nwfpe/fpa11_cprt.c (Architecture sparc) and /arch/sparc64/nwfpe/fpa11_cprt.c (Architecture sparc64)


  1 // SPDX-License-Identifier: GPL-2.0-or-later        1 
  2 /*                                                
  3     NetWinder Floating Point Emulator             
  4     (c) Rebel.COM, 1998,1999                      
  5     (c) Philip Blundell, 1999, 2001               
  6                                                   
  7     Direct questions, comments to Scott Bambro    
  8                                                   
  9 */                                                
 10                                                   
 11 #include "fpa11.h"                                
 12 #include "fpopcode.h"                             
 13 #include "fpa11.inl"                              
 14 #include "fpmodule.h"                             
 15 #include "fpmodule.inl"                           
 16 #include "softfloat.h"                            
 17                                                   
 18 unsigned int PerformFLT(const unsigned int opc    
 19 unsigned int PerformFIX(const unsigned int opc    
 20                                                   
 21 static unsigned int PerformComparison(const un    
 22                                                   
 23 unsigned int EmulateCPRT(const unsigned int op    
 24 {                                                 
 25                                                   
 26         if (opcode & 0x800000) {                  
 27                 /* This is some variant of a c    
 28                    will sort out which one).      
 29                    instructions are oddball ca    
 30                    makes sense to pull this ou    
 31                 return PerformComparison(opcod    
 32         }                                         
 33                                                   
 34         /* Hint to GCC that we'd like a jump t    
 35         switch ((opcode & 0x700000) >> 20) {      
 36         case FLT_CODE >> 20:                      
 37                 return PerformFLT(opcode);        
 38                 break;                            
 39         case FIX_CODE >> 20:                      
 40                 return PerformFIX(opcode);        
 41                 break;                            
 42                                                   
 43         case WFS_CODE >> 20:                      
 44                 writeFPSR(readRegister(getRd(o    
 45                 break;                            
 46         case RFS_CODE >> 20:                      
 47                 writeRegister(getRd(opcode), r    
 48                 break;                            
 49                                                   
 50         default:                                  
 51                 return 0;                         
 52         }                                         
 53                                                   
 54         return 1;                                 
 55 }                                                 
 56                                                   
 57 unsigned int PerformFLT(const unsigned int opc    
 58 {                                                 
 59         FPA11 *fpa11 = GET_FPA11();               
 60         struct roundingData roundData;            
 61                                                   
 62         roundData.mode = SetRoundingMode(opcod    
 63         roundData.precision = SetRoundingPreci    
 64         roundData.exception = 0;                  
 65                                                   
 66         switch (opcode & MASK_ROUNDING_PRECISI    
 67         case ROUND_SINGLE:                        
 68                 {                                 
 69                         fpa11->fType[getFn(opc    
 70                         fpa11->fpreg[getFn(opc    
 71                 }                                 
 72                 break;                            
 73                                                   
 74         case ROUND_DOUBLE:                        
 75                 {                                 
 76                         fpa11->fType[getFn(opc    
 77                         fpa11->fpreg[getFn(opc    
 78                 }                                 
 79                 break;                            
 80                                                   
 81 #ifdef CONFIG_FPE_NWFPE_XP                        
 82         case ROUND_EXTENDED:                      
 83                 {                                 
 84                         fpa11->fType[getFn(opc    
 85                         fpa11->fpreg[getFn(opc    
 86                 }                                 
 87                 break;                            
 88 #endif                                            
 89                                                   
 90         default:                                  
 91                 return 0;                         
 92         }                                         
 93                                                   
 94         if (roundData.exception)                  
 95                 float_raise(roundData.exceptio    
 96                                                   
 97         return 1;                                 
 98 }                                                 
 99                                                   
100 unsigned int PerformFIX(const unsigned int opc    
101 {                                                 
102         FPA11 *fpa11 = GET_FPA11();               
103         unsigned int Fn = getFm(opcode);          
104         struct roundingData roundData;            
105                                                   
106         roundData.mode = SetRoundingMode(opcod    
107         roundData.precision = SetRoundingPreci    
108         roundData.exception = 0;                  
109                                                   
110         switch (fpa11->fType[Fn]) {               
111         case typeSingle:                          
112                 {                                 
113                         writeRegister(getRd(op    
114                 }                                 
115                 break;                            
116                                                   
117         case typeDouble:                          
118                 {                                 
119                         writeRegister(getRd(op    
120                 }                                 
121                 break;                            
122                                                   
123 #ifdef CONFIG_FPE_NWFPE_XP                        
124         case typeExtended:                        
125                 {                                 
126                         writeRegister(getRd(op    
127                 }                                 
128                 break;                            
129 #endif                                            
130                                                   
131         default:                                  
132                 return 0;                         
133         }                                         
134                                                   
135         if (roundData.exception)                  
136                 float_raise(roundData.exceptio    
137                                                   
138         return 1;                                 
139 }                                                 
140                                                   
141 /* This instruction sets the flags N, Z, C, V     
142 static unsigned int PerformComparison(const un    
143 {                                                 
144         FPA11 *fpa11 = GET_FPA11();               
145         unsigned int Fn = getFn(opcode), Fm =     
146         int e_flag = opcode & 0x400000; /* 1 i    
147         int n_flag = opcode & 0x200000; /* 1 i    
148         unsigned int flags = 0;                   
149                                                   
150 #ifdef CONFIG_FPE_NWFPE_XP                        
151         floatx80 rFn, rFm;                        
152                                                   
153         /* Check for unordered condition and c    
154            format.                                
155            ?? Might be some mileage in avoidin    
156            Eg, if both operands are 32-bit, de    
157            comparison (cheaper than an 80-bit     
158         switch (fpa11->fType[Fn]) {               
159         case typeSingle:                          
160                 //printk("single.\n");            
161                 if (float32_is_nan(fpa11->fpre    
162                         goto unordered;           
163                 rFn = float32_to_floatx80(fpa1    
164                 break;                            
165                                                   
166         case typeDouble:                          
167                 //printk("double.\n");            
168                 if (float64_is_nan(fpa11->fpre    
169                         goto unordered;           
170                 rFn = float64_to_floatx80(fpa1    
171                 break;                            
172                                                   
173         case typeExtended:                        
174                 //printk("extended.\n");          
175                 if (floatx80_is_nan(fpa11->fpr    
176                         goto unordered;           
177                 rFn = fpa11->fpreg[Fn].fExtend    
178                 break;                            
179                                                   
180         default:                                  
181                 return 0;                         
182         }                                         
183                                                   
184         if (CONSTANT_FM(opcode)) {                
185                 //printk("Fm is a constant: #%    
186                 rFm = getExtendedConstant(Fm);    
187                 if (floatx80_is_nan(rFm))         
188                         goto unordered;           
189         } else {                                  
190                 //printk("Fm = r%d which conta    
191                 switch (fpa11->fType[Fm]) {       
192                 case typeSingle:                  
193                         //printk("single.\n");    
194                         if (float32_is_nan(fpa    
195                                 goto unordered    
196                         rFm = float32_to_float    
197                         break;                    
198                                                   
199                 case typeDouble:                  
200                         //printk("double.\n");    
201                         if (float64_is_nan(fpa    
202                                 goto unordered    
203                         rFm = float64_to_float    
204                         break;                    
205                                                   
206                 case typeExtended:                
207                         //printk("extended.\n"    
208                         if (floatx80_is_nan(fp    
209                                 goto unordered    
210                         rFm = fpa11->fpreg[Fm]    
211                         break;                    
212                                                   
213                 default:                          
214                         return 0;                 
215                 }                                 
216         }                                         
217                                                   
218         if (n_flag)                               
219                 rFm.high ^= 0x8000;               
220                                                   
221         /* test for less than condition */        
222         if (floatx80_lt(rFn, rFm))                
223                 flags |= CC_NEGATIVE;             
224                                                   
225         /* test for equal condition */            
226         if (floatx80_eq(rFn, rFm))                
227                 flags |= CC_ZERO;                 
228                                                   
229         /* test for greater than or equal cond    
230         if (floatx80_lt(rFm, rFn))                
231                 flags |= CC_CARRY;                
232                                                   
233 #else                                             
234         if (CONSTANT_FM(opcode)) {                
235                 /* Fm is a constant.  Do the c    
236                    Fn happens to be stored in.    
237                 if (fpa11->fType[Fn] == typeSi    
238                         float32 rFm = getSingl    
239                         float32 rFn = fpa11->f    
240                                                   
241                         if (float32_is_nan(rFn    
242                                 goto unordered    
243                                                   
244                         if (n_flag)               
245                                 rFm ^= 0x80000    
246                                                   
247                         /* test for less than     
248                         if (float32_lt_nocheck    
249                                 flags |= CC_NE    
250                                                   
251                         /* test for equal cond    
252                         if (float32_eq_nocheck    
253                                 flags |= CC_ZE    
254                                                   
255                         /* test for greater th    
256                         if (float32_lt_nocheck    
257                                 flags |= CC_CA    
258                 } else {                          
259                         float64 rFm = getDoubl    
260                         float64 rFn = fpa11->f    
261                                                   
262                         if (float64_is_nan(rFn    
263                                 goto unordered    
264                                                   
265                         if (n_flag)               
266                                 rFm ^= 0x80000    
267                                                   
268                         /* test for less than     
269                         if (float64_lt_nocheck    
270                                 flags |= CC_NE    
271                                                   
272                         /* test for equal cond    
273                         if (float64_eq_nocheck    
274                                 flags |= CC_ZE    
275                                                   
276                         /* test for greater th    
277                         if (float64_lt_nocheck    
278                                 flags |= CC_CA    
279                 }                                 
280         } else {                                  
281                 /* Both operands are in regist    
282                 if (fpa11->fType[Fn] == typeSi    
283                     && fpa11->fType[Fm] == typ    
284                         float32 rFm = fpa11->f    
285                         float32 rFn = fpa11->f    
286                                                   
287                         if (float32_is_nan(rFn    
288                             || float32_is_nan(    
289                                 goto unordered    
290                                                   
291                         if (n_flag)               
292                                 rFm ^= 0x80000    
293                                                   
294                         /* test for less than     
295                         if (float32_lt_nocheck    
296                                 flags |= CC_NE    
297                                                   
298                         /* test for equal cond    
299                         if (float32_eq_nocheck    
300                                 flags |= CC_ZE    
301                                                   
302                         /* test for greater th    
303                         if (float32_lt_nocheck    
304                                 flags |= CC_CA    
305                 } else {                          
306                         /* Promote 32-bit oper    
307                         float64 rFm, rFn;         
308                                                   
309                         rFm = (fpa11->fType[Fm    
310                             float32_to_float64    
311                             : fpa11->fpreg[Fm]    
312                                                   
313                         rFn = (fpa11->fType[Fn    
314                             float32_to_float64    
315                             : fpa11->fpreg[Fn]    
316                                                   
317                         if (float64_is_nan(rFn    
318                             || float64_is_nan(    
319                                 goto unordered    
320                                                   
321                         if (n_flag)               
322                                 rFm ^= 0x80000    
323                                                   
324                         /* test for less than     
325                         if (float64_lt_nocheck    
326                                 flags |= CC_NE    
327                                                   
328                         /* test for equal cond    
329                         if (float64_eq_nocheck    
330                                 flags |= CC_ZE    
331                                                   
332                         /* test for greater th    
333                         if (float64_lt_nocheck    
334                                 flags |= CC_CA    
335                 }                                 
336         }                                         
337                                                   
338 #endif                                            
339                                                   
340         writeConditionCodes(flags);               
341                                                   
342         return 1;                                 
343                                                   
344       unordered:                                  
345         /* ?? The FPA data sheet is pretty vag    
346            about whether the non-E comparisons    
347            This implementation is based on a c    
348            the data sheet, observation of how     
349            behaves (and how programs expect it    
350         flags |= CC_OVERFLOW;                     
351         flags &= ~(CC_ZERO | CC_NEGATIVE);        
352                                                   
353         if (BIT_AC & readFPSR())                  
354                 flags |= CC_CARRY;                
355                                                   
356         if (e_flag)                               
357                 float_raise(float_flag_invalid    
358                                                   
359         writeConditionCodes(flags);               
360         return 1;                                 
361 }                                                 
362                                                   

~ [ 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