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

TOMOYO Linux Cross Reference
Linux/arch/x86/math-emu/fpu_etc.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ 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.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 /*---------------------------------------------------------------------------+
  3  |  fpu_etc.c                                                                |
  4  |                                                                           |
  5  | Implement a few FPU instructions.                                         |
  6  |                                                                           |
  7  | Copyright (C) 1992,1993,1994,1997                                         |
  8  |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
  9  |                       Australia.  E-mail   billm@suburbia.net             |
 10  |                                                                           |
 11  |                                                                           |
 12  +---------------------------------------------------------------------------*/
 13 
 14 #include "fpu_system.h"
 15 #include "exception.h"
 16 #include "fpu_emu.h"
 17 #include "status_w.h"
 18 #include "reg_constant.h"
 19 
 20 static void fchs(FPU_REG *st0_ptr, u_char st0tag)
 21 {
 22         if (st0tag ^ TAG_Empty) {
 23                 signbyte(st0_ptr) ^= SIGN_NEG;
 24                 clear_C1();
 25         } else
 26                 FPU_stack_underflow();
 27 }
 28 
 29 static void fabs(FPU_REG *st0_ptr, u_char st0tag)
 30 {
 31         if (st0tag ^ TAG_Empty) {
 32                 setpositive(st0_ptr);
 33                 clear_C1();
 34         } else
 35                 FPU_stack_underflow();
 36 }
 37 
 38 static void ftst_(FPU_REG *st0_ptr, u_char st0tag)
 39 {
 40         switch (st0tag) {
 41         case TAG_Zero:
 42                 setcc(SW_C3);
 43                 break;
 44         case TAG_Valid:
 45                 if (getsign(st0_ptr) == SIGN_POS)
 46                         setcc(0);
 47                 else
 48                         setcc(SW_C0);
 49                 break;
 50         case TAG_Special:
 51                 switch (FPU_Special(st0_ptr)) {
 52                 case TW_Denormal:
 53                         if (getsign(st0_ptr) == SIGN_POS)
 54                                 setcc(0);
 55                         else
 56                                 setcc(SW_C0);
 57                         if (denormal_operand() < 0) {
 58 #ifdef PECULIAR_486
 59                                 /* This is weird! */
 60                                 if (getsign(st0_ptr) == SIGN_POS)
 61                                         setcc(SW_C3);
 62 #endif /* PECULIAR_486 */
 63                                 return;
 64                         }
 65                         break;
 66                 case TW_NaN:
 67                         setcc(SW_C0 | SW_C2 | SW_C3);   /* Operand is not comparable */
 68                         EXCEPTION(EX_Invalid);
 69                         break;
 70                 case TW_Infinity:
 71                         if (getsign(st0_ptr) == SIGN_POS)
 72                                 setcc(0);
 73                         else
 74                                 setcc(SW_C0);
 75                         break;
 76                 default:
 77                         setcc(SW_C0 | SW_C2 | SW_C3);   /* Operand is not comparable */
 78                         EXCEPTION(EX_INTERNAL | 0x14);
 79                         break;
 80                 }
 81                 break;
 82         case TAG_Empty:
 83                 setcc(SW_C0 | SW_C2 | SW_C3);
 84                 EXCEPTION(EX_StackUnder);
 85                 break;
 86         }
 87 }
 88 
 89 static void fxam(FPU_REG *st0_ptr, u_char st0tag)
 90 {
 91         int c = 0;
 92         switch (st0tag) {
 93         case TAG_Empty:
 94                 c = SW_C3 | SW_C0;
 95                 break;
 96         case TAG_Zero:
 97                 c = SW_C3;
 98                 break;
 99         case TAG_Valid:
100                 c = SW_C2;
101                 break;
102         case TAG_Special:
103                 switch (FPU_Special(st0_ptr)) {
104                 case TW_Denormal:
105                         c = SW_C2 | SW_C3;      /* Denormal */
106                         break;
107                 case TW_NaN:
108                         /* We also use NaN for unsupported types. */
109                         if ((st0_ptr->sigh & 0x80000000)
110                             && (exponent(st0_ptr) == EXP_OVER))
111                                 c = SW_C0;
112                         break;
113                 case TW_Infinity:
114                         c = SW_C2 | SW_C0;
115                         break;
116                 }
117         }
118         if (getsign(st0_ptr) == SIGN_NEG)
119                 c |= SW_C1;
120         setcc(c);
121 }
122 
123 static void FPU_ST0_illegal(FPU_REG *st0_ptr, u_char st0_tag)
124 {
125         FPU_illegal();
126 }
127 
128 static FUNC_ST0 const fp_etc_table[] = {
129         fchs, fabs, FPU_ST0_illegal, FPU_ST0_illegal,
130         ftst_, fxam, FPU_ST0_illegal, FPU_ST0_illegal,
131 };
132 
133 void FPU_etc(void)
134 {
135         (fp_etc_table[FPU_rm]) (&st(0), FPU_gettag0());
136 }
137 

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