root/arch/i386/math-emu/fpu_etc.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. fchs
  2. fabs
  3. ftst_
  4. fxam
  5. fp_etc

   1 /*---------------------------------------------------------------------------+
   2  |  fpu_etc.c                                                                |
   3  |                                                                           |
   4  | Implement a few FPU instructions.                                         |
   5  |                                                                           |
   6  | Copyright (C) 1992,1993,1994                                              |
   7  |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
   8  |                       Australia.  E-mail   billm@vaxc.cc.monash.edu.au    |
   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 
  20 static void fchs(FPU_REG *st0_ptr)
     /* [previous][next][first][last][top][bottom][index][help] */
  21 {
  22   if ( st0_ptr->tag ^ TW_Empty )
  23     {
  24       st0_ptr->sign ^= SIGN_POS^SIGN_NEG;
  25       clear_C1();
  26     }
  27   else
  28     stack_underflow();
  29 }
  30 
  31 static void fabs(FPU_REG *st0_ptr)
     /* [previous][next][first][last][top][bottom][index][help] */
  32 {
  33   if ( st0_ptr->tag ^ TW_Empty )
  34     {
  35       st0_ptr->sign = SIGN_POS;
  36       clear_C1();
  37     }
  38   else
  39     stack_underflow();
  40 }
  41 
  42 
  43 static void ftst_(FPU_REG *st0_ptr)
     /* [previous][next][first][last][top][bottom][index][help] */
  44 {
  45   switch (st0_ptr->tag)
  46     {
  47     case TW_Zero:
  48       setcc(SW_C3);
  49       break;
  50     case TW_Valid:
  51       if (st0_ptr->sign == SIGN_POS)
  52         setcc(0);
  53       else
  54         setcc(SW_C0);
  55 
  56 #ifdef DENORM_OPERAND
  57       if ( (st0_ptr->exp <= EXP_UNDER) && (denormal_operand()) )
  58         {
  59 #ifdef PECULIAR_486
  60           /* This is weird! */
  61           if (st0_ptr->sign == SIGN_POS)
  62             setcc(SW_C3);
  63 #endif PECULIAR_486
  64           return;
  65         }
  66 #endif DENORM_OPERAND
  67 
  68       break;
  69     case TW_NaN:
  70       setcc(SW_C0|SW_C2|SW_C3);   /* Operand is not comparable */ 
  71       EXCEPTION(EX_Invalid);
  72       break;
  73     case TW_Infinity:
  74       if (st0_ptr->sign == SIGN_POS)
  75         setcc(0);
  76       else
  77         setcc(SW_C0);
  78       break;
  79     case TW_Empty:
  80       setcc(SW_C0|SW_C2|SW_C3);
  81       EXCEPTION(EX_StackUnder);
  82       break;
  83     default:
  84       setcc(SW_C0|SW_C2|SW_C3);   /* Operand is not comparable */ 
  85       EXCEPTION(EX_INTERNAL|0x14);
  86       break;
  87     }
  88 }
  89 
  90 static void fxam(FPU_REG *st0_ptr)
     /* [previous][next][first][last][top][bottom][index][help] */
  91 {
  92   int c=0;
  93   switch (st0_ptr->tag)
  94     {
  95     case TW_Empty:
  96       c = SW_C3|SW_C0;
  97       break;
  98     case TW_Zero:
  99       c = SW_C3;
 100       break;
 101     case TW_Valid:
 102       /* This will need to be changed if TW_Denormal is ever used. */
 103       if ( st0_ptr->exp <= EXP_UNDER )
 104         c = SW_C2|SW_C3;  /* Denormal */
 105       else
 106         c = SW_C2;
 107       break;
 108     case TW_NaN:
 109       c = SW_C0;
 110       break;
 111     case TW_Infinity:
 112       c = SW_C2|SW_C0;
 113       break;
 114     }
 115   if (st0_ptr->sign == SIGN_NEG)
 116     c |= SW_C1;
 117   setcc(c);
 118 }
 119 
 120 
 121 static FUNC_ST0 const fp_etc_table[] = {
 122   fchs, fabs, (FUNC_ST0)FPU_illegal, (FUNC_ST0)FPU_illegal,
 123   ftst_, fxam, (FUNC_ST0)FPU_illegal, (FUNC_ST0)FPU_illegal
 124 };
 125 
 126 void fp_etc()
     /* [previous][next][first][last][top][bottom][index][help] */
 127 {
 128   (fp_etc_table[FPU_rm])(&st(0));
 129 }

/* [previous][next][first][last][top][bottom][index][help] */