fpu_etc.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:3k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  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. #include "fpu_system.h"
  13. #include "exception.h"
  14. #include "fpu_emu.h"
  15. #include "status_w.h"
  16. #include "reg_constant.h"
  17. static void fchs(FPU_REG *st0_ptr, u_char st0tag)
  18. {
  19.   if ( st0tag ^ TAG_Empty )
  20.     {
  21.       signbyte(st0_ptr) ^= SIGN_NEG;
  22.       clear_C1();
  23.     }
  24.   else
  25.     FPU_stack_underflow();
  26. }
  27. static void fabs(FPU_REG *st0_ptr, u_char st0tag)
  28. {
  29.   if ( st0tag ^ TAG_Empty )
  30.     {
  31.       setpositive(st0_ptr);
  32.       clear_C1();
  33.     }
  34.   else
  35.     FPU_stack_underflow();
  36. }
  37. static void ftst_(FPU_REG *st0_ptr, u_char st0tag)
  38. {
  39.   switch (st0tag)
  40.     {
  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. {
  53. case TW_Denormal:
  54.   if (getsign(st0_ptr) == SIGN_POS)
  55.     setcc(0);
  56.   else
  57.     setcc(SW_C0);
  58.   if ( denormal_operand() < 0 )
  59.     {
  60. #ifdef PECULIAR_486
  61.       /* This is weird! */
  62.       if (getsign(st0_ptr) == SIGN_POS)
  63. setcc(SW_C3);
  64. #endif /* PECULIAR_486 */
  65.       return;
  66.     }
  67.   break;
  68. case TW_NaN:
  69.   setcc(SW_C0|SW_C2|SW_C3);   /* Operand is not comparable */ 
  70.   EXCEPTION(EX_Invalid);
  71.   break;
  72. case TW_Infinity:
  73.   if (getsign(st0_ptr) == SIGN_POS)
  74.     setcc(0);
  75.   else
  76.     setcc(SW_C0);
  77.   break;
  78. default:
  79.   setcc(SW_C0|SW_C2|SW_C3);   /* Operand is not comparable */ 
  80.   EXCEPTION(EX_INTERNAL|0x14);
  81.   break;
  82. }
  83.       break;
  84.     case TAG_Empty:
  85.       setcc(SW_C0|SW_C2|SW_C3);
  86.       EXCEPTION(EX_StackUnder);
  87.       break;
  88.     }
  89. }
  90. static void fxam(FPU_REG *st0_ptr, u_char st0tag)
  91. {
  92.   int c = 0;
  93.   switch (st0tag)
  94.     {
  95.     case TAG_Empty:
  96.       c = SW_C3|SW_C0;
  97.       break;
  98.     case TAG_Zero:
  99.       c = SW_C3;
  100.       break;
  101.     case TAG_Valid:
  102.       c = SW_C2;
  103.       break;
  104.     case TAG_Special:
  105.       switch ( FPU_Special(st0_ptr) )
  106. {
  107. case TW_Denormal:
  108.   c = SW_C2|SW_C3;  /* Denormal */
  109.   break;
  110. case TW_NaN:
  111.   /* We also use NaN for unsupported types. */
  112.   if ( (st0_ptr->sigh & 0x80000000) && (exponent(st0_ptr) == EXP_OVER) )
  113.     c = SW_C0;
  114.   break;
  115. case TW_Infinity:
  116.   c = SW_C2|SW_C0;
  117.   break;
  118. }
  119.     }
  120.   if ( getsign(st0_ptr) == SIGN_NEG )
  121.     c |= SW_C1;
  122.   setcc(c);
  123. }
  124. static FUNC_ST0 const fp_etc_table[] = {
  125.   fchs, fabs, (FUNC_ST0)FPU_illegal, (FUNC_ST0)FPU_illegal,
  126.   ftst_, fxam, (FUNC_ST0)FPU_illegal, (FUNC_ST0)FPU_illegal
  127. };
  128. void FPU_etc()
  129. {
  130.   (fp_etc_table[FPU_rm])(&st(0), FPU_gettag0());
  131. }