fpu_aux.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:4k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*---------------------------------------------------------------------------+
  2.  |  fpu_aux.c                                                                |
  3.  |                                                                           |
  4.  | Code to implement some of the FPU auxiliary instructions.                 |
  5.  |                                                                           |
  6.  | Copyright (C) 1992,1993,1994,1997                                         |
  7.  |                  W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
  8.  |                  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 "control_w.h"
  17. static void fnop(void)
  18. {
  19. }
  20. void fclex(void)
  21. {
  22.   partial_status &= ~(SW_Backward|SW_Summary|SW_Stack_Fault|SW_Precision|
  23.    SW_Underflow|SW_Overflow|SW_Zero_Div|SW_Denorm_Op|
  24.    SW_Invalid);
  25.   no_ip_update = 1;
  26. }
  27. /* Needs to be externally visible */
  28. void finit()
  29. {
  30.   control_word = 0x037f;
  31.   partial_status = 0;
  32.   top = 0;            /* We don't keep top in the status word internally. */
  33.   fpu_tag_word = 0xffff;
  34.   /* The behaviour is different from that detailed in
  35.      Section 15.1.6 of the Intel manual */
  36.   operand_address.offset = 0;
  37.   operand_address.selector = 0;
  38.   instruction_address.offset = 0;
  39.   instruction_address.selector = 0;
  40.   instruction_address.opcode = 0;
  41.   no_ip_update = 1;
  42. }
  43. /*
  44.  * These are nops on the i387..
  45.  */
  46. #define feni fnop
  47. #define fdisi fnop
  48. #define fsetpm fnop
  49. static FUNC const finit_table[] = {
  50.   feni, fdisi, fclex, finit,
  51.   fsetpm, FPU_illegal, FPU_illegal, FPU_illegal
  52. };
  53. void finit_()
  54. {
  55.   (finit_table[FPU_rm])();
  56. }
  57. static void fstsw_ax(void)
  58. {
  59.   *(short *) &FPU_EAX = status_word();
  60.   no_ip_update = 1;
  61. }
  62. static FUNC const fstsw_table[] = {
  63.   fstsw_ax, FPU_illegal, FPU_illegal, FPU_illegal,
  64.   FPU_illegal, FPU_illegal, FPU_illegal, FPU_illegal
  65. };
  66. void fstsw_()
  67. {
  68.   (fstsw_table[FPU_rm])();
  69. }
  70. static FUNC const fp_nop_table[] = {
  71.   fnop, FPU_illegal, FPU_illegal, FPU_illegal,
  72.   FPU_illegal, FPU_illegal, FPU_illegal, FPU_illegal
  73. };
  74. void fp_nop()
  75. {
  76.   (fp_nop_table[FPU_rm])();
  77. }
  78. void fld_i_()
  79. {
  80.   FPU_REG *st_new_ptr;
  81.   int i;
  82.   u_char tag;
  83.   if ( STACK_OVERFLOW )
  84.     { FPU_stack_overflow(); return; }
  85.   /* fld st(i) */
  86.   i = FPU_rm;
  87.   if ( NOT_EMPTY(i) )
  88.     {
  89.       reg_copy(&st(i), st_new_ptr);
  90.       tag = FPU_gettagi(i);
  91.       push();
  92.       FPU_settag0(tag);
  93.     }
  94.   else
  95.     {
  96.       if ( control_word & CW_Invalid )
  97. {
  98.   /* The masked response */
  99.   FPU_stack_underflow();
  100. }
  101.       else
  102. EXCEPTION(EX_StackUnder);
  103.     }
  104. }
  105. void fxch_i()
  106. {
  107.   /* fxch st(i) */
  108.   FPU_REG t;
  109.   int i = FPU_rm;
  110.   FPU_REG *st0_ptr = &st(0), *sti_ptr = &st(i);
  111.   long tag_word = fpu_tag_word;
  112.   int regnr = top & 7, regnri = ((regnr + i) & 7);
  113.   u_char st0_tag = (tag_word >> (regnr*2)) & 3;
  114.   u_char sti_tag = (tag_word >> (regnri*2)) & 3;
  115.   if ( st0_tag == TAG_Empty )
  116.     {
  117.       if ( sti_tag == TAG_Empty )
  118. {
  119.   FPU_stack_underflow();
  120.   FPU_stack_underflow_i(i);
  121.   return;
  122. }
  123.       if ( control_word & CW_Invalid )
  124. {
  125.   /* Masked response */
  126.   FPU_copy_to_reg0(sti_ptr, sti_tag);
  127. }
  128.       FPU_stack_underflow_i(i);
  129.       return;
  130.     }
  131.   if ( sti_tag == TAG_Empty )
  132.     {
  133.       if ( control_word & CW_Invalid )
  134. {
  135.   /* Masked response */
  136.   FPU_copy_to_regi(st0_ptr, st0_tag, i);
  137. }
  138.       FPU_stack_underflow();
  139.       return;
  140.     }
  141.   clear_C1();
  142.   reg_copy(st0_ptr, &t);
  143.   reg_copy(sti_ptr, st0_ptr);
  144.   reg_copy(&t, sti_ptr);
  145.   tag_word &= ~(3 << (regnr*2)) & ~(3 << (regnri*2));
  146.   tag_word |= (sti_tag << (regnr*2)) | (st0_tag << (regnri*2));
  147.   fpu_tag_word = tag_word;
  148. }
  149. void ffree_()
  150. {
  151.   /* ffree st(i) */
  152.   FPU_settagi(FPU_rm, TAG_Empty);
  153. }
  154. void ffreep()
  155. {
  156.   /* ffree st(i) + pop - unofficial code */
  157.   FPU_settagi(FPU_rm, TAG_Empty);
  158.   FPU_pop();
  159. }
  160. void fst_i_()
  161. {
  162.   /* fst st(i) */
  163.   FPU_copy_to_regi(&st(0), FPU_gettag0(), FPU_rm);
  164. }
  165. void fstp_i()
  166. {
  167.   /* fstp st(i) */
  168.   FPU_copy_to_regi(&st(0), FPU_gettag0(), FPU_rm);
  169.   FPU_pop();
  170. }