linux/arch/x86/math-emu/fpu_tags.c
<<
>>
Prefs
   1/*---------------------------------------------------------------------------+
   2 |  fpu_tags.c                                                               |
   3 |                                                                           |
   4 |  Set FPU register tags.                                                   |
   5 |                                                                           |
   6 | Copyright (C) 1997                                                        |
   7 |                  W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
   8 |                  E-mail   billm@jacobi.maths.monash.edu.au                |
   9 |                                                                           |
  10 |                                                                           |
  11 +---------------------------------------------------------------------------*/
  12
  13#include "fpu_emu.h"
  14#include "fpu_system.h"
  15#include "exception.h"
  16
  17void FPU_pop(void)
  18{
  19        fpu_tag_word |= 3 << ((top & 7) * 2);
  20        top++;
  21}
  22
  23int FPU_gettag0(void)
  24{
  25        return (fpu_tag_word >> ((top & 7) * 2)) & 3;
  26}
  27
  28int FPU_gettagi(int stnr)
  29{
  30        return (fpu_tag_word >> (((top + stnr) & 7) * 2)) & 3;
  31}
  32
  33int FPU_gettag(int regnr)
  34{
  35        return (fpu_tag_word >> ((regnr & 7) * 2)) & 3;
  36}
  37
  38void FPU_settag0(int tag)
  39{
  40        int regnr = top;
  41        regnr &= 7;
  42        fpu_tag_word &= ~(3 << (regnr * 2));
  43        fpu_tag_word |= (tag & 3) << (regnr * 2);
  44}
  45
  46void FPU_settagi(int stnr, int tag)
  47{
  48        int regnr = stnr + top;
  49        regnr &= 7;
  50        fpu_tag_word &= ~(3 << (regnr * 2));
  51        fpu_tag_word |= (tag & 3) << (regnr * 2);
  52}
  53
  54void FPU_settag(int regnr, int tag)
  55{
  56        regnr &= 7;
  57        fpu_tag_word &= ~(3 << (regnr * 2));
  58        fpu_tag_word |= (tag & 3) << (regnr * 2);
  59}
  60
  61int FPU_Special(FPU_REG const *ptr)
  62{
  63        int exp = exponent(ptr);
  64
  65        if (exp == EXP_BIAS + EXP_UNDER)
  66                return TW_Denormal;
  67        else if (exp != EXP_BIAS + EXP_OVER)
  68                return TW_NaN;
  69        else if ((ptr->sigh == 0x80000000) && (ptr->sigl == 0))
  70                return TW_Infinity;
  71        return TW_NaN;
  72}
  73
  74int isNaN(FPU_REG const *ptr)
  75{
  76        return ((exponent(ptr) == EXP_BIAS + EXP_OVER)
  77                && !((ptr->sigh == 0x80000000) && (ptr->sigl == 0)));
  78}
  79
  80int FPU_empty_i(int stnr)
  81{
  82        int regnr = (top + stnr) & 7;
  83
  84        return ((fpu_tag_word >> (regnr * 2)) & 3) == TAG_Empty;
  85}
  86
  87int FPU_stackoverflow(FPU_REG ** st_new_ptr)
  88{
  89        *st_new_ptr = &st(-1);
  90
  91        return ((fpu_tag_word >> (((top - 1) & 7) * 2)) & 3) != TAG_Empty;
  92}
  93
  94void FPU_copy_to_regi(FPU_REG const *r, u_char tag, int stnr)
  95{
  96        reg_copy(r, &st(stnr));
  97        FPU_settagi(stnr, tag);
  98}
  99
 100void FPU_copy_to_reg1(FPU_REG const *r, u_char tag)
 101{
 102        reg_copy(r, &st(1));
 103        FPU_settagi(1, tag);
 104}
 105
 106void FPU_copy_to_reg0(FPU_REG const *r, u_char tag)
 107{
 108        int regnr = top;
 109        regnr &= 7;
 110
 111        reg_copy(r, &st(0));
 112
 113        fpu_tag_word &= ~(3 << (regnr * 2));
 114        fpu_tag_word |= (tag & 3) << (regnr * 2);
 115}
 116