root/kernel/FPU-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                                                   |
   7  |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
   8  |                       Australia.  E-mail apm233m@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(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  21 {
  22   if ( NOT_EMPTY_0 )
  23     {
  24       FPU_st0_ptr->sign ^= SIGN_POS^SIGN_NEG;
  25 #ifdef PECULIAR_486
  26       /* Default, this conveys no information, but an 80486 does it. */
  27       clear_C1();
  28 #endif PECULIAR_486
  29     }
  30   else
  31     stack_underflow();
  32 }
  33 
  34 static void fabs(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  35 {
  36   if ( FPU_st0_tag ^ TW_Empty )
  37     {
  38       FPU_st0_ptr->sign = SIGN_POS;
  39 #ifdef PECULIAR_486
  40       /* Default, this conveys no information, but an 80486 does it. */
  41       clear_C1();
  42 #endif PECULIAR_486
  43     }
  44   else
  45     stack_underflow();
  46 }
  47 
  48 
  49 static void ftst_(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  50 {
  51   switch (FPU_st0_tag)
  52     {
  53     case TW_Zero:
  54       setcc(SW_C3);
  55       break;
  56     case TW_Valid:
  57       if (FPU_st0_ptr->sign == SIGN_POS)
  58         setcc(0);
  59       else
  60         setcc(SW_C0);
  61 
  62 #ifdef DENORM_OPERAND
  63       if ( (FPU_st0_ptr->exp <= EXP_UNDER) && (denormal_operand()) )
  64         {
  65 #ifdef PECULIAR_486
  66           /* This is wierd! */
  67           if (FPU_st0_ptr->sign == SIGN_POS)
  68             setcc(SW_C3);
  69 #endif PECULIAR_486
  70           return;
  71         }
  72 #endif DENORM_OPERAND
  73 
  74       break;
  75     case TW_NaN:
  76       setcc(SW_C0|SW_C2|SW_C3);   /* Operand is not comparable */ 
  77       EXCEPTION(EX_Invalid);
  78       break;
  79     case TW_Infinity:
  80       if (FPU_st0_ptr->sign == SIGN_POS)
  81         setcc(0);
  82       else
  83         setcc(SW_C0);
  84       break;
  85     case TW_Empty:
  86       setcc(SW_C0|SW_C2|SW_C3);
  87       EXCEPTION(EX_StackUnder);
  88       break;
  89     default:
  90       setcc(SW_C0|SW_C2|SW_C3);   /* Operand is not comparable */ 
  91       EXCEPTION(EX_INTERNAL|0x14);
  92       break;
  93     }
  94 }
  95 
  96 static void fxam(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  97 {
  98   int c=0;
  99   switch (FPU_st0_tag)
 100     {
 101     case TW_Empty:
 102       c = SW_C3|SW_C0;
 103       break;
 104     case TW_Zero:
 105       c = SW_C3;
 106       break;
 107     case TW_Valid:
 108       /* This will need to be changed if TW_Denormal is ever used. */
 109       if ( FPU_st0_ptr->exp <= EXP_UNDER )
 110         c = SW_C2|SW_C3;  /* Denormal */
 111       else
 112         c = SW_C2;
 113       break;
 114     case TW_NaN:
 115       c = SW_C0;
 116       break;
 117     case TW_Infinity:
 118       c = SW_C2|SW_C0;
 119       break;
 120     }
 121   if (FPU_st0_ptr->sign == SIGN_NEG)
 122     c |= SW_C1;
 123   setcc(c);
 124 }
 125 
 126 static FUNC fp_etc_table[] = {
 127   fchs, fabs, Un_impl, Un_impl, ftst_, fxam, Un_impl, Un_impl
 128 };
 129 
 130 void fp_etc()
     /* [previous][next][first][last][top][bottom][index][help] */
 131 {
 132   (fp_etc_table[FPU_rm])();
 133 }

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