61 |
|
|
62 |
void SetRoundingMode(const unsigned int opcode) |
void SetRoundingMode(const unsigned int opcode) |
63 |
{ |
{ |
64 |
#if MAINTAIN_FPCR |
int rounding_mode; |
65 |
FPA11 *fpa11 = GET_FPA11(); |
FPA11 *fpa11 = GET_FPA11(); |
66 |
|
|
67 |
|
#if MAINTAIN_FPCR |
68 |
fpa11->fpcr &= ~MASK_ROUNDING_MODE; |
fpa11->fpcr &= ~MASK_ROUNDING_MODE; |
69 |
#endif |
#endif |
70 |
switch (opcode & MASK_ROUNDING_MODE) |
switch (opcode & MASK_ROUNDING_MODE) |
71 |
{ |
{ |
72 |
default: |
default: |
73 |
case ROUND_TO_NEAREST: |
case ROUND_TO_NEAREST: |
74 |
float_rounding_mode = float_round_nearest_even; |
rounding_mode = float_round_nearest_even; |
75 |
#if MAINTAIN_FPCR |
#if MAINTAIN_FPCR |
76 |
fpa11->fpcr |= ROUND_TO_NEAREST; |
fpa11->fpcr |= ROUND_TO_NEAREST; |
77 |
#endif |
#endif |
78 |
break; |
break; |
79 |
|
|
80 |
case ROUND_TO_PLUS_INFINITY: |
case ROUND_TO_PLUS_INFINITY: |
81 |
float_rounding_mode = float_round_up; |
rounding_mode = float_round_up; |
82 |
#if MAINTAIN_FPCR |
#if MAINTAIN_FPCR |
83 |
fpa11->fpcr |= ROUND_TO_PLUS_INFINITY; |
fpa11->fpcr |= ROUND_TO_PLUS_INFINITY; |
84 |
#endif |
#endif |
85 |
break; |
break; |
86 |
|
|
87 |
case ROUND_TO_MINUS_INFINITY: |
case ROUND_TO_MINUS_INFINITY: |
88 |
float_rounding_mode = float_round_down; |
rounding_mode = float_round_down; |
89 |
#if MAINTAIN_FPCR |
#if MAINTAIN_FPCR |
90 |
fpa11->fpcr |= ROUND_TO_MINUS_INFINITY; |
fpa11->fpcr |= ROUND_TO_MINUS_INFINITY; |
91 |
#endif |
#endif |
92 |
break; |
break; |
93 |
|
|
94 |
case ROUND_TO_ZERO: |
case ROUND_TO_ZERO: |
95 |
float_rounding_mode = float_round_to_zero; |
rounding_mode = float_round_to_zero; |
96 |
#if MAINTAIN_FPCR |
#if MAINTAIN_FPCR |
97 |
fpa11->fpcr |= ROUND_TO_ZERO; |
fpa11->fpcr |= ROUND_TO_ZERO; |
98 |
#endif |
#endif |
99 |
break; |
break; |
100 |
} |
} |
101 |
|
set_float_rounding_mode(rounding_mode, &fpa11->fp_status); |
102 |
} |
} |
103 |
|
|
104 |
void SetRoundingPrecision(const unsigned int opcode) |
void SetRoundingPrecision(const unsigned int opcode) |
105 |
{ |
{ |
106 |
#if MAINTAIN_FPCR |
int rounding_precision; |
107 |
FPA11 *fpa11 = GET_FPA11(); |
FPA11 *fpa11 = GET_FPA11(); |
108 |
|
#if MAINTAIN_FPCR |
109 |
fpa11->fpcr &= ~MASK_ROUNDING_PRECISION; |
fpa11->fpcr &= ~MASK_ROUNDING_PRECISION; |
110 |
#endif |
#endif |
111 |
switch (opcode & MASK_ROUNDING_PRECISION) |
switch (opcode & MASK_ROUNDING_PRECISION) |
112 |
{ |
{ |
113 |
case ROUND_SINGLE: |
case ROUND_SINGLE: |
114 |
floatx80_rounding_precision = 32; |
rounding_precision = 32; |
115 |
#if MAINTAIN_FPCR |
#if MAINTAIN_FPCR |
116 |
fpa11->fpcr |= ROUND_SINGLE; |
fpa11->fpcr |= ROUND_SINGLE; |
117 |
#endif |
#endif |
118 |
break; |
break; |
119 |
|
|
120 |
case ROUND_DOUBLE: |
case ROUND_DOUBLE: |
121 |
floatx80_rounding_precision = 64; |
rounding_precision = 64; |
122 |
#if MAINTAIN_FPCR |
#if MAINTAIN_FPCR |
123 |
fpa11->fpcr |= ROUND_DOUBLE; |
fpa11->fpcr |= ROUND_DOUBLE; |
124 |
#endif |
#endif |
125 |
break; |
break; |
126 |
|
|
127 |
case ROUND_EXTENDED: |
case ROUND_EXTENDED: |
128 |
floatx80_rounding_precision = 80; |
rounding_precision = 80; |
129 |
#if MAINTAIN_FPCR |
#if MAINTAIN_FPCR |
130 |
fpa11->fpcr |= ROUND_EXTENDED; |
fpa11->fpcr |= ROUND_EXTENDED; |
131 |
#endif |
#endif |
132 |
break; |
break; |
133 |
|
|
134 |
default: floatx80_rounding_precision = 80; |
default: rounding_precision = 80; |
135 |
} |
} |
136 |
|
set_floatx80_rounding_precision(rounding_precision, &fpa11->fp_status); |
137 |
} |
} |
138 |
|
|
139 |
/* Emulate the instruction in the opcode. */ |
/* Emulate the instruction in the opcode. */ |