21 |
*/ |
*/ |
22 |
|
|
23 |
#include "fpa11.h" |
#include "fpa11.h" |
|
#include "milieu.h" |
|
24 |
#include "softfloat.h" |
#include "softfloat.h" |
25 |
#include "fpopcode.h" |
#include "fpopcode.h" |
26 |
#include "fpa11.inl" |
#include "fpa11.inl" |
88 |
{ |
{ |
89 |
fpa11->fType[getFn(opcode)] = typeSingle; |
fpa11->fType[getFn(opcode)] = typeSingle; |
90 |
fpa11->fpreg[getFn(opcode)].fSingle = |
fpa11->fpreg[getFn(opcode)].fSingle = |
91 |
int32_to_float32(readRegister(getRd(opcode))); |
int32_to_float32(readRegister(getRd(opcode)), &fpa11->fp_status); |
92 |
} |
} |
93 |
break; |
break; |
94 |
|
|
96 |
{ |
{ |
97 |
fpa11->fType[getFn(opcode)] = typeDouble; |
fpa11->fType[getFn(opcode)] = typeDouble; |
98 |
fpa11->fpreg[getFn(opcode)].fDouble = |
fpa11->fpreg[getFn(opcode)].fDouble = |
99 |
int32_to_float64(readRegister(getRd(opcode))); |
int32_to_float64(readRegister(getRd(opcode)), &fpa11->fp_status); |
100 |
} |
} |
101 |
break; |
break; |
102 |
|
|
104 |
{ |
{ |
105 |
fpa11->fType[getFn(opcode)] = typeExtended; |
fpa11->fType[getFn(opcode)] = typeExtended; |
106 |
fpa11->fpreg[getFn(opcode)].fExtended = |
fpa11->fpreg[getFn(opcode)].fExtended = |
107 |
int32_to_floatx80(readRegister(getRd(opcode))); |
int32_to_floatx80(readRegister(getRd(opcode)), &fpa11->fp_status); |
108 |
} |
} |
109 |
break; |
break; |
110 |
|
|
127 |
case typeSingle: |
case typeSingle: |
128 |
{ |
{ |
129 |
writeRegister(getRd(opcode), |
writeRegister(getRd(opcode), |
130 |
float32_to_int32(fpa11->fpreg[Fn].fSingle)); |
float32_to_int32(fpa11->fpreg[Fn].fSingle, &fpa11->fp_status)); |
131 |
} |
} |
132 |
break; |
break; |
133 |
|
|
135 |
{ |
{ |
136 |
//printf("F%d is 0x%llx\n",Fn,fpa11->fpreg[Fn].fDouble); |
//printf("F%d is 0x%llx\n",Fn,fpa11->fpreg[Fn].fDouble); |
137 |
writeRegister(getRd(opcode), |
writeRegister(getRd(opcode), |
138 |
float64_to_int32(fpa11->fpreg[Fn].fDouble)); |
float64_to_int32(fpa11->fpreg[Fn].fDouble, &fpa11->fp_status)); |
139 |
} |
} |
140 |
break; |
break; |
141 |
|
|
142 |
case typeExtended: |
case typeExtended: |
143 |
{ |
{ |
144 |
writeRegister(getRd(opcode), |
writeRegister(getRd(opcode), |
145 |
floatx80_to_int32(fpa11->fpreg[Fn].fExtended)); |
floatx80_to_int32(fpa11->fpreg[Fn].fExtended, &fpa11->fp_status)); |
146 |
} |
} |
147 |
break; |
break; |
148 |
|
|
156 |
static unsigned int __inline__ |
static unsigned int __inline__ |
157 |
PerformComparisonOperation(floatx80 Fn, floatx80 Fm) |
PerformComparisonOperation(floatx80 Fn, floatx80 Fm) |
158 |
{ |
{ |
159 |
|
FPA11 *fpa11 = GET_FPA11(); |
160 |
unsigned int flags = 0; |
unsigned int flags = 0; |
161 |
|
|
162 |
/* test for less than condition */ |
/* test for less than condition */ |
163 |
if (floatx80_lt(Fn,Fm)) |
if (floatx80_lt(Fn,Fm, &fpa11->fp_status)) |
164 |
{ |
{ |
165 |
flags |= CC_NEGATIVE; |
flags |= CC_NEGATIVE; |
166 |
} |
} |
167 |
|
|
168 |
/* test for equal condition */ |
/* test for equal condition */ |
169 |
if (floatx80_eq(Fn,Fm)) |
if (floatx80_eq(Fn,Fm, &fpa11->fp_status)) |
170 |
{ |
{ |
171 |
flags |= CC_ZERO; |
flags |= CC_ZERO; |
172 |
} |
} |
173 |
|
|
174 |
/* test for greater than or equal condition */ |
/* test for greater than or equal condition */ |
175 |
if (floatx80_lt(Fm,Fn)) |
if (floatx80_lt(Fm,Fn, &fpa11->fp_status)) |
176 |
{ |
{ |
177 |
flags |= CC_CARRY; |
flags |= CC_CARRY; |
178 |
} |
} |
208 |
//printk("single.\n"); |
//printk("single.\n"); |
209 |
if (float32_is_nan(fpa11->fpreg[Fn].fSingle)) |
if (float32_is_nan(fpa11->fpreg[Fn].fSingle)) |
210 |
goto unordered; |
goto unordered; |
211 |
rFn = float32_to_floatx80(fpa11->fpreg[Fn].fSingle); |
rFn = float32_to_floatx80(fpa11->fpreg[Fn].fSingle, &fpa11->fp_status); |
212 |
break; |
break; |
213 |
|
|
214 |
case typeDouble: |
case typeDouble: |
215 |
//printk("double.\n"); |
//printk("double.\n"); |
216 |
if (float64_is_nan(fpa11->fpreg[Fn].fDouble)) |
if (float64_is_nan(fpa11->fpreg[Fn].fDouble)) |
217 |
goto unordered; |
goto unordered; |
218 |
rFn = float64_to_floatx80(fpa11->fpreg[Fn].fDouble); |
rFn = float64_to_floatx80(fpa11->fpreg[Fn].fDouble, &fpa11->fp_status); |
219 |
break; |
break; |
220 |
|
|
221 |
case typeExtended: |
case typeExtended: |
244 |
//printk("single.\n"); |
//printk("single.\n"); |
245 |
if (float32_is_nan(fpa11->fpreg[Fm].fSingle)) |
if (float32_is_nan(fpa11->fpreg[Fm].fSingle)) |
246 |
goto unordered; |
goto unordered; |
247 |
rFm = float32_to_floatx80(fpa11->fpreg[Fm].fSingle); |
rFm = float32_to_floatx80(fpa11->fpreg[Fm].fSingle, &fpa11->fp_status); |
248 |
break; |
break; |
249 |
|
|
250 |
case typeDouble: |
case typeDouble: |
251 |
//printk("double.\n"); |
//printk("double.\n"); |
252 |
if (float64_is_nan(fpa11->fpreg[Fm].fDouble)) |
if (float64_is_nan(fpa11->fpreg[Fm].fDouble)) |
253 |
goto unordered; |
goto unordered; |
254 |
rFm = float64_to_floatx80(fpa11->fpreg[Fm].fDouble); |
rFm = float64_to_floatx80(fpa11->fpreg[Fm].fDouble, &fpa11->fp_status); |
255 |
break; |
break; |
256 |
|
|
257 |
case typeExtended: |
case typeExtended: |
283 |
|
|
284 |
if (BIT_AC & readFPSR()) flags |= CC_CARRY; |
if (BIT_AC & readFPSR()) flags |= CC_CARRY; |
285 |
|
|
286 |
if (e_flag) float_raise(float_flag_invalid); |
if (e_flag) float_raise(float_flag_invalid, &fpa11->fp_status); |
287 |
|
|
288 |
writeConditionCodes(flags); |
writeConditionCodes(flags); |
289 |
return 1; |
return 1; |