Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

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