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 17 void FPU_pop(void) 18 { 19 fpu_tag_word |= 3 << ((top & 7) * 2); 20 top++; 21 } 22 23 int FPU_gettag0(void) 24 { 25 return (fpu_tag_word >> ((top & 7) * 2)) & 3; 26 } 27 28 int FPU_gettagi(int stnr) 29 { 30 return (fpu_tag_word >> (((top + stnr) & 7) * 2)) & 3; 31 } 32 33 int FPU_gettag(int regnr) 34 { 35 return (fpu_tag_word >> ((regnr & 7) * 2)) & 3; 36 } 37 38 void 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 46 void 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 54 void 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 61 int 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 74 int isNaN(FPU_REG const *ptr) 75 { 76 return ((exponent(ptr) == EXP_BIAS + EXP_OVER) 77 && !((ptr->sigh == 0x80000000) && (ptr->sigl == 0))); 78 } 79 80 int 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 87 int 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 94 void 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 100 void 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 106 void 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