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

TOMOYO Linux Cross Reference
Linux/arch/x86/math-emu/reg_compare.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/x86/math-emu/reg_compare.c (Architecture ppc) and /arch/i386/math-emu/reg_compare.c (Architecture i386)


  1 // SPDX-License-Identifier: GPL-2.0                 1 
  2 /*--------------------------------------------    
  3  |  reg_compare.c                                 
  4  |                                                
  5  | Compare two floating point registers           
  6  |                                                
  7  | Copyright (C) 1992,1993,1994,1997              
  8  |                  W. Metzenthen, 22 Parker S    
  9  |                  E-mail   billm@suburbia.ne    
 10  |                                                
 11  |                                                
 12  +--------------------------------------------    
 13                                                   
 14 /*--------------------------------------------    
 15  | compare() is the core FPU_REG comparison fu    
 16  +--------------------------------------------    
 17                                                   
 18 #include "fpu_system.h"                           
 19 #include "exception.h"                            
 20 #include "fpu_emu.h"                              
 21 #include "control_w.h"                            
 22 #include "status_w.h"                             
 23                                                   
 24 static int compare(FPU_REG const *b, int tagb)    
 25 {                                                 
 26         int diff, exp0, expb;                     
 27         u_char st0_tag;                           
 28         FPU_REG *st0_ptr;                         
 29         FPU_REG x, y;                             
 30         u_char st0_sign, signb = getsign(b);      
 31                                                   
 32         st0_ptr = &st(0);                         
 33         st0_tag = FPU_gettag0();                  
 34         st0_sign = getsign(st0_ptr);              
 35                                                   
 36         if (tagb == TAG_Special)                  
 37                 tagb = FPU_Special(b);            
 38         if (st0_tag == TAG_Special)               
 39                 st0_tag = FPU_Special(st0_ptr)    
 40                                                   
 41         if (((st0_tag != TAG_Valid) && (st0_ta    
 42             || ((tagb != TAG_Valid) && (tagb !    
 43                 if (st0_tag == TAG_Zero) {        
 44                         if (tagb == TAG_Zero)     
 45                                 return COMP_A_    
 46                         if (tagb == TAG_Valid)    
 47                                 return ((signb    
 48                                          SIGN_    
 49                         if (tagb == TW_Denorma    
 50                                 return ((signb    
 51                                          SIGN_    
 52                                     | COMP_Den    
 53                 } else if (tagb == TAG_Zero) {    
 54                         if (st0_tag == TAG_Val    
 55                                 return ((st0_s    
 56                                          SIGN_    
 57                         if (st0_tag == TW_Deno    
 58                                 return ((st0_s    
 59                                          SIGN_    
 60                                     | COMP_Den    
 61                 }                                 
 62                                                   
 63                 if (st0_tag == TW_Infinity) {     
 64                         if ((tagb == TAG_Valid    
 65                                 return ((st0_s    
 66                                          SIGN_    
 67                         else if (tagb == TW_De    
 68                                 return ((st0_s    
 69                                          SIGN_    
 70                                     | COMP_Den    
 71                         else if (tagb == TW_In    
 72                                 /* The 80486 b    
 73                                 return (st0_si    
 74                                     ((st0_sign    
 75                                       SIGN_POS    
 76                         }                         
 77                         /* Fall through to the    
 78                 } else if (tagb == TW_Infinity    
 79                         if ((st0_tag == TAG_Va    
 80                                 return ((signb    
 81                                          SIGN_    
 82                         if (st0_tag == TW_Deno    
 83                                 return ((signb    
 84                                          SIGN_    
 85                                     | COMP_Den    
 86                         /* Fall through to the    
 87                 }                                 
 88                                                   
 89                 /* The only possibility now sh    
 90                    is a NaN */                    
 91                 if ((st0_tag == TW_NaN) || (ta    
 92                         int signalling = 0, un    
 93                         if (st0_tag == TW_NaN)    
 94                                 signalling =      
 95                                     (st0_ptr->    
 96                                 unsupported =     
 97                                                   
 98                                                   
 99                         }                         
100                         if (tagb == TW_NaN) {     
101                                 signalling |=     
102                                     (b->sigh &    
103                                 unsupported |=    
104                                                   
105                         }                         
106                         if (signalling || unsu    
107                                 return COMP_No    
108                         else                      
109                                 /* Neither is     
110                                 return COMP_No    
111                 }                                 
112                                                   
113                 EXCEPTION(EX_Invalid);            
114         }                                         
115                                                   
116         if (st0_sign != signb) {                  
117                 return ((st0_sign == SIGN_POS)    
118                     | (((st0_tag == TW_Denorma    
119                        COMP_Denormal : 0);        
120         }                                         
121                                                   
122         if ((st0_tag == TW_Denormal) || (tagb     
123                 FPU_to_exp16(st0_ptr, &x);        
124                 FPU_to_exp16(b, &y);              
125                 st0_ptr = &x;                     
126                 b = &y;                           
127                 exp0 = exponent16(st0_ptr);       
128                 expb = exponent16(b);             
129         } else {                                  
130                 exp0 = exponent(st0_ptr);         
131                 expb = exponent(b);               
132         }                                         
133                                                   
134 #ifdef PARANOID                                   
135         if (!(st0_ptr->sigh & 0x80000000))        
136                 EXCEPTION(EX_Invalid);            
137         if (!(b->sigh & 0x80000000))              
138                 EXCEPTION(EX_Invalid);            
139 #endif /* PARANOID */                             
140                                                   
141         diff = exp0 - expb;                       
142         if (diff == 0) {                          
143                 diff = st0_ptr->sigh - b->sigh    
144                                                   
145                 if (diff == 0) {                  
146                         diff = st0_ptr->sigl >    
147                         if (diff == 0)            
148                                 diff = -(st0_p    
149                 }                                 
150         }                                         
151                                                   
152         if (diff > 0) {                           
153                 return ((st0_sign == SIGN_POS)    
154                     | (((st0_tag == TW_Denorma    
155                        COMP_Denormal : 0);        
156         }                                         
157         if (diff < 0) {                           
158                 return ((st0_sign == SIGN_POS)    
159                     | (((st0_tag == TW_Denorma    
160                        COMP_Denormal : 0);        
161         }                                         
162                                                   
163         return COMP_A_eq_B                        
164             | (((st0_tag == TW_Denormal) || (t    
165                COMP_Denormal : 0);                
166                                                   
167 }                                                 
168                                                   
169 /* This function requires that st(0) is not em    
170 int FPU_compare_st_data(FPU_REG const *loaded_    
171 {                                                 
172         int f, c;                                 
173                                                   
174         c = compare(loaded_data, loaded_tag);     
175                                                   
176         if (c & COMP_NaN) {                       
177                 EXCEPTION(EX_Invalid);            
178                 f = SW_C3 | SW_C2 | SW_C0;        
179         } else                                    
180                 switch (c & 7) {                  
181                 case COMP_A_lt_B:                 
182                         f = SW_C0;                
183                         break;                    
184                 case COMP_A_eq_B:                 
185                         f = SW_C3;                
186                         break;                    
187                 case COMP_A_gt_B:                 
188                         f = 0;                    
189                         break;                    
190                 case COMP_No_Comp:                
191                         f = SW_C3 | SW_C2 | SW    
192                         break;                    
193                 default:                          
194 #ifdef PARANOID                                   
195                         EXCEPTION(EX_INTERNAL     
196 #endif /* PARANOID */                             
197                         f = SW_C3 | SW_C2 | SW    
198                         break;                    
199                 }                                 
200         setcc(f);                                 
201         if (c & COMP_Denormal) {                  
202                 return denormal_operand() < 0;    
203         }                                         
204         return 0;                                 
205 }                                                 
206                                                   
207 static int compare_st_st(int nr)                  
208 {                                                 
209         int f, c;                                 
210         FPU_REG *st_ptr;                          
211                                                   
212         if (!NOT_EMPTY(0) || !NOT_EMPTY(nr)) {    
213                 setcc(SW_C3 | SW_C2 | SW_C0);     
214                 /* Stack fault */                 
215                 EXCEPTION(EX_StackUnder);         
216                 return !(control_word & CW_Inv    
217         }                                         
218                                                   
219         st_ptr = &st(nr);                         
220         c = compare(st_ptr, FPU_gettagi(nr));     
221         if (c & COMP_NaN) {                       
222                 setcc(SW_C3 | SW_C2 | SW_C0);     
223                 EXCEPTION(EX_Invalid);            
224                 return !(control_word & CW_Inv    
225         } else                                    
226                 switch (c & 7) {                  
227                 case COMP_A_lt_B:                 
228                         f = SW_C0;                
229                         break;                    
230                 case COMP_A_eq_B:                 
231                         f = SW_C3;                
232                         break;                    
233                 case COMP_A_gt_B:                 
234                         f = 0;                    
235                         break;                    
236                 case COMP_No_Comp:                
237                         f = SW_C3 | SW_C2 | SW    
238                         break;                    
239                 default:                          
240 #ifdef PARANOID                                   
241                         EXCEPTION(EX_INTERNAL     
242 #endif /* PARANOID */                             
243                         f = SW_C3 | SW_C2 | SW    
244                         break;                    
245                 }                                 
246         setcc(f);                                 
247         if (c & COMP_Denormal) {                  
248                 return denormal_operand() < 0;    
249         }                                         
250         return 0;                                 
251 }                                                 
252                                                   
253 static int compare_i_st_st(int nr)                
254 {                                                 
255         int f, c;                                 
256         FPU_REG *st_ptr;                          
257                                                   
258         if (!NOT_EMPTY(0) || !NOT_EMPTY(nr)) {    
259                 FPU_EFLAGS |= (X86_EFLAGS_ZF |    
260                 /* Stack fault */                 
261                 EXCEPTION(EX_StackUnder);         
262                 return !(control_word & CW_Inv    
263         }                                         
264                                                   
265         partial_status &= ~SW_C0;                 
266         st_ptr = &st(nr);                         
267         c = compare(st_ptr, FPU_gettagi(nr));     
268         if (c & COMP_NaN) {                       
269                 FPU_EFLAGS |= (X86_EFLAGS_ZF |    
270                 EXCEPTION(EX_Invalid);            
271                 return !(control_word & CW_Inv    
272         }                                         
273                                                   
274         switch (c & 7) {                          
275         case COMP_A_lt_B:                         
276                 f = X86_EFLAGS_CF;                
277                 break;                            
278         case COMP_A_eq_B:                         
279                 f = X86_EFLAGS_ZF;                
280                 break;                            
281         case COMP_A_gt_B:                         
282                 f = 0;                            
283                 break;                            
284         case COMP_No_Comp:                        
285                 f = X86_EFLAGS_ZF | X86_EFLAGS    
286                 break;                            
287         default:                                  
288 #ifdef PARANOID                                   
289                 EXCEPTION(EX_INTERNAL | 0x122)    
290 #endif /* PARANOID */                             
291                 f = 0;                            
292                 break;                            
293         }                                         
294         FPU_EFLAGS = (FPU_EFLAGS & ~(X86_EFLAG    
295         if (c & COMP_Denormal) {                  
296                 return denormal_operand() < 0;    
297         }                                         
298         return 0;                                 
299 }                                                 
300                                                   
301 static int compare_u_st_st(int nr)                
302 {                                                 
303         int f = 0, c;                             
304         FPU_REG *st_ptr;                          
305                                                   
306         if (!NOT_EMPTY(0) || !NOT_EMPTY(nr)) {    
307                 setcc(SW_C3 | SW_C2 | SW_C0);     
308                 /* Stack fault */                 
309                 EXCEPTION(EX_StackUnder);         
310                 return !(control_word & CW_Inv    
311         }                                         
312                                                   
313         st_ptr = &st(nr);                         
314         c = compare(st_ptr, FPU_gettagi(nr));     
315         if (c & COMP_NaN) {                       
316                 setcc(SW_C3 | SW_C2 | SW_C0);     
317                 if (c & COMP_SNaN) {    /* Thi    
318                                            un-    
319                         EXCEPTION(EX_Invalid);    
320                         return !(control_word     
321                 }                                 
322                 return 0;                         
323         } else                                    
324                 switch (c & 7) {                  
325                 case COMP_A_lt_B:                 
326                         f = SW_C0;                
327                         break;                    
328                 case COMP_A_eq_B:                 
329                         f = SW_C3;                
330                         break;                    
331                 case COMP_A_gt_B:                 
332                         f = 0;                    
333                         break;                    
334                 case COMP_No_Comp:                
335                         f = SW_C3 | SW_C2 | SW    
336                         break;                    
337 #ifdef PARANOID                                   
338                 default:                          
339                         EXCEPTION(EX_INTERNAL     
340                         f = SW_C3 | SW_C2 | SW    
341                         break;                    
342 #endif /* PARANOID */                             
343                 }                                 
344         setcc(f);                                 
345         if (c & COMP_Denormal) {                  
346                 return denormal_operand() < 0;    
347         }                                         
348         return 0;                                 
349 }                                                 
350                                                   
351 static int compare_ui_st_st(int nr)               
352 {                                                 
353         int f = 0, c;                             
354         FPU_REG *st_ptr;                          
355                                                   
356         if (!NOT_EMPTY(0) || !NOT_EMPTY(nr)) {    
357                 FPU_EFLAGS |= (X86_EFLAGS_ZF |    
358                 /* Stack fault */                 
359                 EXCEPTION(EX_StackUnder);         
360                 return !(control_word & CW_Inv    
361         }                                         
362                                                   
363         partial_status &= ~SW_C0;                 
364         st_ptr = &st(nr);                         
365         c = compare(st_ptr, FPU_gettagi(nr));     
366         if (c & COMP_NaN) {                       
367                 FPU_EFLAGS |= (X86_EFLAGS_ZF |    
368                 if (c & COMP_SNaN) {    /* Thi    
369                                            un-    
370                         EXCEPTION(EX_Invalid);    
371                         return !(control_word     
372                 }                                 
373                 return 0;                         
374         }                                         
375                                                   
376         switch (c & 7) {                          
377         case COMP_A_lt_B:                         
378                 f = X86_EFLAGS_CF;                
379                 break;                            
380         case COMP_A_eq_B:                         
381                 f = X86_EFLAGS_ZF;                
382                 break;                            
383         case COMP_A_gt_B:                         
384                 f = 0;                            
385                 break;                            
386         case COMP_No_Comp:                        
387                 f = X86_EFLAGS_ZF | X86_EFLAGS    
388                 break;                            
389 #ifdef PARANOID                                   
390         default:                                  
391                 EXCEPTION(EX_INTERNAL | 0x123)    
392                 f = 0;                            
393                 break;                            
394 #endif /* PARANOID */                             
395         }                                         
396         FPU_EFLAGS = (FPU_EFLAGS & ~(X86_EFLAG    
397         if (c & COMP_Denormal) {                  
398                 return denormal_operand() < 0;    
399         }                                         
400         return 0;                                 
401 }                                                 
402                                                   
403 /*--------------------------------------------    
404                                                   
405 void fcom_st(void)                                
406 {                                                 
407         /* fcom st(i) */                          
408         compare_st_st(FPU_rm);                    
409 }                                                 
410                                                   
411 void fcompst(void)                                
412 {                                                 
413         /* fcomp st(i) */                         
414         if (!compare_st_st(FPU_rm))               
415                 FPU_pop();                        
416 }                                                 
417                                                   
418 void fcompp(void)                                 
419 {                                                 
420         /* fcompp */                              
421         if (FPU_rm != 1) {                        
422                 FPU_illegal();                    
423                 return;                           
424         }                                         
425         if (!compare_st_st(1))                    
426                 poppop();                         
427 }                                                 
428                                                   
429 void fucom_(void)                                 
430 {                                                 
431         /* fucom st(i) */                         
432         compare_u_st_st(FPU_rm);                  
433                                                   
434 }                                                 
435                                                   
436 void fucomp(void)                                 
437 {                                                 
438         /* fucomp st(i) */                        
439         if (!compare_u_st_st(FPU_rm))             
440                 FPU_pop();                        
441 }                                                 
442                                                   
443 void fucompp(void)                                
444 {                                                 
445         /* fucompp */                             
446         if (FPU_rm == 1) {                        
447                 if (!compare_u_st_st(1))          
448                         poppop();                 
449         } else                                    
450                 FPU_illegal();                    
451 }                                                 
452                                                   
453 /* P6+ compare-to-EFLAGS ops */                   
454                                                   
455 void fcomi_(void)                                 
456 {                                                 
457         /* fcomi st(i) */                         
458         compare_i_st_st(FPU_rm);                  
459 }                                                 
460                                                   
461 void fcomip(void)                                 
462 {                                                 
463         /* fcomip st(i) */                        
464         if (!compare_i_st_st(FPU_rm))             
465                 FPU_pop();                        
466 }                                                 
467                                                   
468 void fucomi_(void)                                
469 {                                                 
470         /* fucomi st(i) */                        
471         compare_ui_st_st(FPU_rm);                 
472 }                                                 
473                                                   
474 void fucomip(void)                                
475 {                                                 
476         /* fucomip st(i) */                       
477         if (!compare_ui_st_st(FPU_rm))            
478                 FPU_pop();                        
479 }                                                 
480                                                   

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