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