Commit | Line | Data |
---|---|---|
1da177e4 LT |
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 | ||
18 | void FPU_pop(void) | |
19 | { | |
20 | fpu_tag_word |= 3 << ((top & 7)*2); | |
21 | top++; | |
22 | } | |
23 | ||
24 | ||
25 | int FPU_gettag0(void) | |
26 | { | |
27 | return (fpu_tag_word >> ((top & 7)*2)) & 3; | |
28 | } | |
29 | ||
30 | ||
31 | int FPU_gettagi(int stnr) | |
32 | { | |
33 | return (fpu_tag_word >> (((top+stnr) & 7)*2)) & 3; | |
34 | } | |
35 | ||
36 | ||
37 | int FPU_gettag(int regnr) | |
38 | { | |
39 | return (fpu_tag_word >> ((regnr & 7)*2)) & 3; | |
40 | } | |
41 | ||
42 | ||
43 | void FPU_settag0(int tag) | |
44 | { | |
45 | int regnr = top; | |
46 | regnr &= 7; | |
47 | fpu_tag_word &= ~(3 << (regnr*2)); | |
48 | fpu_tag_word |= (tag & 3) << (regnr*2); | |
49 | } | |
50 | ||
51 | ||
52 | void FPU_settagi(int stnr, int tag) | |
53 | { | |
54 | int regnr = stnr+top; | |
55 | regnr &= 7; | |
56 | fpu_tag_word &= ~(3 << (regnr*2)); | |
57 | fpu_tag_word |= (tag & 3) << (regnr*2); | |
58 | } | |
59 | ||
60 | ||
61 | void FPU_settag(int regnr, int tag) | |
62 | { | |
63 | regnr &= 7; | |
64 | fpu_tag_word &= ~(3 << (regnr*2)); | |
65 | fpu_tag_word |= (tag & 3) << (regnr*2); | |
66 | } | |
67 | ||
68 | ||
69 | int FPU_Special(FPU_REG const *ptr) | |
70 | { | |
71 | int exp = exponent(ptr); | |
72 | ||
73 | if ( exp == EXP_BIAS+EXP_UNDER ) | |
74 | return TW_Denormal; | |
75 | else if ( exp != EXP_BIAS+EXP_OVER ) | |
76 | return TW_NaN; | |
77 | else if ( (ptr->sigh == 0x80000000) && (ptr->sigl == 0) ) | |
78 | return TW_Infinity; | |
79 | return TW_NaN; | |
80 | } | |
81 | ||
82 | ||
83 | int isNaN(FPU_REG const *ptr) | |
84 | { | |
85 | return ( (exponent(ptr) == EXP_BIAS+EXP_OVER) | |
86 | && !((ptr->sigh == 0x80000000) && (ptr->sigl == 0)) ); | |
87 | } | |
88 | ||
89 | ||
90 | int FPU_empty_i(int stnr) | |
91 | { | |
92 | int regnr = (top+stnr) & 7; | |
93 | ||
94 | return ((fpu_tag_word >> (regnr*2)) & 3) == TAG_Empty; | |
95 | } | |
96 | ||
97 | ||
98 | int FPU_stackoverflow(FPU_REG **st_new_ptr) | |
99 | { | |
100 | *st_new_ptr = &st(-1); | |
101 | ||
102 | return ((fpu_tag_word >> (((top - 1) & 7)*2)) & 3) != TAG_Empty; | |
103 | } | |
104 | ||
105 | ||
106 | void FPU_copy_to_regi(FPU_REG const *r, u_char tag, int stnr) | |
107 | { | |
108 | reg_copy(r, &st(stnr)); | |
109 | FPU_settagi(stnr, tag); | |
110 | } | |
111 | ||
112 | void FPU_copy_to_reg1(FPU_REG const *r, u_char tag) | |
113 | { | |
114 | reg_copy(r, &st(1)); | |
115 | FPU_settagi(1, tag); | |
116 | } | |
117 | ||
118 | void FPU_copy_to_reg0(FPU_REG const *r, u_char tag) | |
119 | { | |
120 | int regnr = top; | |
121 | regnr &= 7; | |
122 | ||
123 | reg_copy(r, &st(0)); | |
124 | ||
125 | fpu_tag_word &= ~(3 << (regnr*2)); | |
126 | fpu_tag_word |= (tag & 3) << (regnr*2); | |
127 | } |