diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/arm/skyeye_common/vfp/vfp.cpp | 4 | ||||
| -rw-r--r-- | src/core/arm/skyeye_common/vfp/vfp_helper.h | 313 | ||||
| -rw-r--r-- | src/core/arm/skyeye_common/vfp/vfpdouble.cpp | 14 | ||||
| -rw-r--r-- | src/core/arm/skyeye_common/vfp/vfpsingle.cpp | 14 |
4 files changed, 153 insertions, 192 deletions
diff --git a/src/core/arm/skyeye_common/vfp/vfp.cpp b/src/core/arm/skyeye_common/vfp/vfp.cpp index 888709124..1cf146c53 100644 --- a/src/core/arm/skyeye_common/vfp/vfp.cpp +++ b/src/core/arm/skyeye_common/vfp/vfp.cpp | |||
| @@ -773,8 +773,8 @@ void vfp_raise_exceptions(ARMul_State* state, u32 exceptions, u32 inst, u32 fpsc | |||
| 773 | * Comparison instructions always return at least one of | 773 | * Comparison instructions always return at least one of |
| 774 | * these flags set. | 774 | * these flags set. |
| 775 | */ | 775 | */ |
| 776 | if (exceptions & (FPSCR_N|FPSCR_Z|FPSCR_C|FPSCR_V)) | 776 | if (exceptions & (FPSCR_NFLAG|FPSCR_ZFLAG|FPSCR_CFLAG|FPSCR_VFLAG)) |
| 777 | fpscr &= ~(FPSCR_N|FPSCR_Z|FPSCR_C|FPSCR_V); | 777 | fpscr &= ~(FPSCR_NFLAG|FPSCR_ZFLAG|FPSCR_CFLAG|FPSCR_VFLAG); |
| 778 | 778 | ||
| 779 | fpscr |= exceptions; | 779 | fpscr |= exceptions; |
| 780 | 780 | ||
diff --git a/src/core/arm/skyeye_common/vfp/vfp_helper.h b/src/core/arm/skyeye_common/vfp/vfp_helper.h index 4798d523d..6e63d59ec 100644 --- a/src/core/arm/skyeye_common/vfp/vfp_helper.h +++ b/src/core/arm/skyeye_common/vfp/vfp_helper.h | |||
| @@ -45,62 +45,51 @@ | |||
| 45 | 45 | ||
| 46 | #define do_div(n, base) {n/=base;} | 46 | #define do_div(n, base) {n/=base;} |
| 47 | 47 | ||
| 48 | /* From vfpinstr.h */ | 48 | enum : u32 { |
| 49 | 49 | FOP_MASK = 0x00b00040, | |
| 50 | #define INST_CPRTDO(inst) (((inst) & 0x0f000000) == 0x0e000000) | 50 | FOP_FMAC = 0x00000000, |
| 51 | #define INST_CPRT(inst) ((inst) & (1 << 4)) | 51 | FOP_FNMAC = 0x00000040, |
| 52 | #define INST_CPRT_L(inst) ((inst) & (1 << 20)) | 52 | FOP_FMSC = 0x00100000, |
| 53 | #define INST_CPRT_Rd(inst) (((inst) & (15 << 12)) >> 12) | 53 | FOP_FNMSC = 0x00100040, |
| 54 | #define INST_CPRT_OP(inst) (((inst) >> 21) & 7) | 54 | FOP_FMUL = 0x00200000, |
| 55 | #define INST_CPNUM(inst) ((inst) & 0xf00) | 55 | FOP_FNMUL = 0x00200040, |
| 56 | #define CPNUM(cp) ((cp) << 8) | 56 | FOP_FADD = 0x00300000, |
| 57 | 57 | FOP_FSUB = 0x00300040, | |
| 58 | #define FOP_MASK (0x00b00040) | 58 | FOP_FDIV = 0x00800000, |
| 59 | #define FOP_FMAC (0x00000000) | 59 | FOP_EXT = 0x00b00040 |
| 60 | #define FOP_FNMAC (0x00000040) | 60 | }; |
| 61 | #define FOP_FMSC (0x00100000) | 61 | |
| 62 | #define FOP_FNMSC (0x00100040) | 62 | #define FOP_TO_IDX(inst) ((inst & 0x00b00000) >> 20 | (inst & (1 << 6)) >> 4) |
| 63 | #define FOP_FMUL (0x00200000) | 63 | |
| 64 | #define FOP_FNMUL (0x00200040) | 64 | enum : u32 { |
| 65 | #define FOP_FADD (0x00300000) | 65 | FEXT_MASK = 0x000f0080, |
| 66 | #define FOP_FSUB (0x00300040) | 66 | FEXT_FCPY = 0x00000000, |
| 67 | #define FOP_FDIV (0x00800000) | 67 | FEXT_FABS = 0x00000080, |
| 68 | #define FOP_EXT (0x00b00040) | 68 | FEXT_FNEG = 0x00010000, |
| 69 | 69 | FEXT_FSQRT = 0x00010080, | |
| 70 | #define FOP_TO_IDX(inst) ((inst & 0x00b00000) >> 20 | (inst & (1 << 6)) >> 4) | 70 | FEXT_FCMP = 0x00040000, |
| 71 | 71 | FEXT_FCMPE = 0x00040080, | |
| 72 | #define FEXT_MASK (0x000f0080) | 72 | FEXT_FCMPZ = 0x00050000, |
| 73 | #define FEXT_FCPY (0x00000000) | 73 | FEXT_FCMPEZ = 0x00050080, |
| 74 | #define FEXT_FABS (0x00000080) | 74 | FEXT_FCVT = 0x00070080, |
| 75 | #define FEXT_FNEG (0x00010000) | 75 | FEXT_FUITO = 0x00080000, |
| 76 | #define FEXT_FSQRT (0x00010080) | 76 | FEXT_FSITO = 0x00080080, |
| 77 | #define FEXT_FCMP (0x00040000) | 77 | FEXT_FTOUI = 0x000c0000, |
| 78 | #define FEXT_FCMPE (0x00040080) | 78 | FEXT_FTOUIZ = 0x000c0080, |
| 79 | #define FEXT_FCMPZ (0x00050000) | 79 | FEXT_FTOSI = 0x000d0000, |
| 80 | #define FEXT_FCMPEZ (0x00050080) | 80 | FEXT_FTOSIZ = 0x000d0080 |
| 81 | #define FEXT_FCVT (0x00070080) | 81 | }; |
| 82 | #define FEXT_FUITO (0x00080000) | 82 | |
| 83 | #define FEXT_FSITO (0x00080080) | 83 | #define FEXT_TO_IDX(inst) ((inst & 0x000f0000) >> 15 | (inst & (1 << 7)) >> 7) |
| 84 | #define FEXT_FTOUI (0x000c0000) | 84 | |
| 85 | #define FEXT_FTOUIZ (0x000c0080) | 85 | #define vfp_get_sd(inst) ((inst & 0x0000f000) >> 11 | (inst & (1 << 22)) >> 22) |
| 86 | #define FEXT_FTOSI (0x000d0000) | 86 | #define vfp_get_dd(inst) ((inst & 0x0000f000) >> 12 | (inst & (1 << 22)) >> 18) |
| 87 | #define FEXT_FTOSIZ (0x000d0080) | 87 | #define vfp_get_sm(inst) ((inst & 0x0000000f) << 1 | (inst & (1 << 5)) >> 5) |
| 88 | 88 | #define vfp_get_dm(inst) ((inst & 0x0000000f) | (inst & (1 << 5)) >> 1) | |
| 89 | #define FEXT_TO_IDX(inst) ((inst & 0x000f0000) >> 15 | (inst & (1 << 7)) >> 7) | 89 | #define vfp_get_sn(inst) ((inst & 0x000f0000) >> 15 | (inst & (1 << 7)) >> 7) |
| 90 | 90 | #define vfp_get_dn(inst) ((inst & 0x000f0000) >> 16 | (inst & (1 << 7)) >> 3) | |
| 91 | #define vfp_get_sd(inst) ((inst & 0x0000f000) >> 11 | (inst & (1 << 22)) >> 22) | 91 | |
| 92 | #define vfp_get_dd(inst) ((inst & 0x0000f000) >> 12 | (inst & (1 << 22)) >> 18) | 92 | #define vfp_single(inst) (((inst) & 0x0000f00) == 0xa00) |
| 93 | #define vfp_get_sm(inst) ((inst & 0x0000000f) << 1 | (inst & (1 << 5)) >> 5) | ||
| 94 | #define vfp_get_dm(inst) ((inst & 0x0000000f) | (inst & (1 << 5)) >> 1) | ||
| 95 | #define vfp_get_sn(inst) ((inst & 0x000f0000) >> 15 | (inst & (1 << 7)) >> 7) | ||
| 96 | #define vfp_get_dn(inst) ((inst & 0x000f0000) >> 16 | (inst & (1 << 7)) >> 3) | ||
| 97 | |||
| 98 | #define vfp_single(inst) (((inst) & 0x0000f00) == 0xa00) | ||
| 99 | |||
| 100 | #define FPSCR_N (1 << 31) | ||
| 101 | #define FPSCR_Z (1 << 30) | ||
| 102 | #define FPSCR_C (1 << 29) | ||
| 103 | #define FPSCR_V (1 << 28) | ||
| 104 | 93 | ||
| 105 | static inline u32 vfp_shiftright32jamming(u32 val, unsigned int shift) | 94 | static inline u32 vfp_shiftright32jamming(u32 val, unsigned int shift) |
| 106 | { | 95 | { |
| @@ -225,51 +214,39 @@ static inline u64 vfp_estimate_div128to64(u64 nh, u64 nl, u64 m) | |||
| 225 | return z; | 214 | return z; |
| 226 | } | 215 | } |
| 227 | 216 | ||
| 228 | /* | 217 | // Operations on unpacked elements |
| 229 | * Operations on unpacked elements | 218 | #define vfp_sign_negate(sign) (sign ^ 0x8000) |
| 230 | */ | ||
| 231 | #define vfp_sign_negate(sign) (sign ^ 0x8000) | ||
| 232 | 219 | ||
| 233 | /* | 220 | // Single-precision |
| 234 | * Single-precision | ||
| 235 | */ | ||
| 236 | struct vfp_single { | 221 | struct vfp_single { |
| 237 | s16 exponent; | 222 | s16 exponent; |
| 238 | u16 sign; | 223 | u16 sign; |
| 239 | u32 significand; | 224 | u32 significand; |
| 240 | }; | 225 | }; |
| 241 | 226 | ||
| 242 | /* | 227 | // VFP_SINGLE_MANTISSA_BITS - number of bits in the mantissa |
| 243 | * VFP_SINGLE_MANTISSA_BITS - number of bits in the mantissa | 228 | // VFP_SINGLE_EXPONENT_BITS - number of bits in the exponent |
| 244 | * VFP_SINGLE_EXPONENT_BITS - number of bits in the exponent | 229 | // VFP_SINGLE_LOW_BITS - number of low bits in the unpacked significand |
| 245 | * VFP_SINGLE_LOW_BITS - number of low bits in the unpacked significand | 230 | // which are not propagated to the float upon packing. |
| 246 | * which are not propagated to the float upon packing. | 231 | #define VFP_SINGLE_MANTISSA_BITS (23) |
| 247 | */ | 232 | #define VFP_SINGLE_EXPONENT_BITS (8) |
| 248 | #define VFP_SINGLE_MANTISSA_BITS (23) | 233 | #define VFP_SINGLE_LOW_BITS (32 - VFP_SINGLE_MANTISSA_BITS - 2) |
| 249 | #define VFP_SINGLE_EXPONENT_BITS (8) | 234 | #define VFP_SINGLE_LOW_BITS_MASK ((1 << VFP_SINGLE_LOW_BITS) - 1) |
| 250 | #define VFP_SINGLE_LOW_BITS (32 - VFP_SINGLE_MANTISSA_BITS - 2) | ||
| 251 | #define VFP_SINGLE_LOW_BITS_MASK ((1 << VFP_SINGLE_LOW_BITS) - 1) | ||
| 252 | 235 | ||
| 253 | /* | 236 | // The bit in an unpacked float which indicates that it is a quiet NaN |
| 254 | * The bit in an unpacked float which indicates that it is a quiet NaN | ||
| 255 | */ | ||
| 256 | #define VFP_SINGLE_SIGNIFICAND_QNAN (1 << (VFP_SINGLE_MANTISSA_BITS - 1 + VFP_SINGLE_LOW_BITS)) | 237 | #define VFP_SINGLE_SIGNIFICAND_QNAN (1 << (VFP_SINGLE_MANTISSA_BITS - 1 + VFP_SINGLE_LOW_BITS)) |
| 257 | 238 | ||
| 258 | /* | 239 | // Operations on packed single-precision numbers |
| 259 | * Operations on packed single-precision numbers | 240 | #define vfp_single_packed_sign(v) ((v) & 0x80000000) |
| 260 | */ | 241 | #define vfp_single_packed_negate(v) ((v) ^ 0x80000000) |
| 261 | #define vfp_single_packed_sign(v) ((v) & 0x80000000) | 242 | #define vfp_single_packed_abs(v) ((v) & ~0x80000000) |
| 262 | #define vfp_single_packed_negate(v) ((v) ^ 0x80000000) | 243 | #define vfp_single_packed_exponent(v) (((v) >> VFP_SINGLE_MANTISSA_BITS) & ((1 << VFP_SINGLE_EXPONENT_BITS) - 1)) |
| 263 | #define vfp_single_packed_abs(v) ((v) & ~0x80000000) | 244 | #define vfp_single_packed_mantissa(v) ((v) & ((1 << VFP_SINGLE_MANTISSA_BITS) - 1)) |
| 264 | #define vfp_single_packed_exponent(v) (((v) >> VFP_SINGLE_MANTISSA_BITS) & ((1 << VFP_SINGLE_EXPONENT_BITS) - 1)) | 245 | |
| 265 | #define vfp_single_packed_mantissa(v) ((v) & ((1 << VFP_SINGLE_MANTISSA_BITS) - 1)) | 246 | // Unpack a single-precision float. Note that this returns the magnitude |
| 266 | 247 | // of the single-precision float mantissa with the 1. if necessary, | |
| 267 | /* | 248 | // aligned to bit 30. |
| 268 | * Unpack a single-precision float. Note that this returns the magnitude | 249 | static inline void vfp_single_unpack(vfp_single* s, s32 val) |
| 269 | * of the single-precision float mantissa with the 1. if necessary, | ||
| 270 | * aligned to bit 30. | ||
| 271 | */ | ||
| 272 | static inline void vfp_single_unpack(struct vfp_single *s, s32 val) | ||
| 273 | { | 250 | { |
| 274 | u32 significand; | 251 | u32 significand; |
| 275 | 252 | ||
| @@ -283,11 +260,9 @@ static inline void vfp_single_unpack(struct vfp_single *s, s32 val) | |||
| 283 | s->significand = significand; | 260 | s->significand = significand; |
| 284 | } | 261 | } |
| 285 | 262 | ||
| 286 | /* | 263 | // Re-pack a single-precision float. This assumes that the float is |
| 287 | * Re-pack a single-precision float. This assumes that the float is | 264 | // already normalised such that the MSB is bit 30, _not_ bit 31. |
| 288 | * already normalised such that the MSB is bit 30, _not_ bit 31. | 265 | static inline s32 vfp_single_pack(vfp_single* s) |
| 289 | */ | ||
| 290 | static inline s32 vfp_single_pack(struct vfp_single *s) | ||
| 291 | { | 266 | { |
| 292 | u32 val = (s->sign << 16) + | 267 | u32 val = (s->sign << 16) + |
| 293 | (s->exponent << VFP_SINGLE_MANTISSA_BITS) + | 268 | (s->exponent << VFP_SINGLE_MANTISSA_BITS) + |
| @@ -295,17 +270,19 @@ static inline s32 vfp_single_pack(struct vfp_single *s) | |||
| 295 | return (s32)val; | 270 | return (s32)val; |
| 296 | } | 271 | } |
| 297 | 272 | ||
| 298 | #define VFP_NUMBER (1<<0) | 273 | enum : u32 { |
| 299 | #define VFP_ZERO (1<<1) | 274 | VFP_NUMBER = (1 << 0), |
| 300 | #define VFP_DENORMAL (1<<2) | 275 | VFP_ZERO = (1 << 1), |
| 301 | #define VFP_INFINITY (1<<3) | 276 | VFP_DENORMAL = (1 << 2), |
| 302 | #define VFP_NAN (1<<4) | 277 | VFP_INFINITY = (1 << 3), |
| 303 | #define VFP_NAN_SIGNAL (1<<5) | 278 | VFP_NAN = (1 << 4), |
| 279 | VFP_NAN_SIGNAL = (1 << 5), | ||
| 304 | 280 | ||
| 305 | #define VFP_QNAN (VFP_NAN) | 281 | VFP_QNAN = (VFP_NAN), |
| 306 | #define VFP_SNAN (VFP_NAN|VFP_NAN_SIGNAL) | 282 | VFP_SNAN = (VFP_NAN|VFP_NAN_SIGNAL) |
| 283 | }; | ||
| 307 | 284 | ||
| 308 | static inline int vfp_single_type(struct vfp_single *s) | 285 | static inline int vfp_single_type(vfp_single* s) |
| 309 | { | 286 | { |
| 310 | int type = VFP_NUMBER; | 287 | int type = VFP_NUMBER; |
| 311 | if (s->exponent == 255) { | 288 | if (s->exponent == 255) { |
| @@ -325,53 +302,43 @@ static inline int vfp_single_type(struct vfp_single *s) | |||
| 325 | } | 302 | } |
| 326 | 303 | ||
| 327 | 304 | ||
| 328 | u32 vfp_single_normaliseround(ARMul_State* state, int sd, struct vfp_single *vs, u32 fpscr, u32 exceptions, const char *func); | 305 | u32 vfp_single_normaliseround(ARMul_State* state, int sd, vfp_single* vs, u32 fpscr, u32 exceptions, const char* func); |
| 329 | 306 | ||
| 330 | /* | 307 | // Double-precision |
| 331 | * Double-precision | ||
| 332 | */ | ||
| 333 | struct vfp_double { | 308 | struct vfp_double { |
| 334 | s16 exponent; | 309 | s16 exponent; |
| 335 | u16 sign; | 310 | u16 sign; |
| 336 | u64 significand; | 311 | u64 significand; |
| 337 | }; | 312 | }; |
| 338 | 313 | ||
| 339 | /* | 314 | // VFP_REG_ZERO is a special register number for vfp_get_double |
| 340 | * VFP_REG_ZERO is a special register number for vfp_get_double | 315 | // which returns (double)0.0. This is useful for the compare with |
| 341 | * which returns (double)0.0. This is useful for the compare with | 316 | // zero instructions. |
| 342 | * zero instructions. | ||
| 343 | */ | ||
| 344 | #ifdef CONFIG_VFPv3 | 317 | #ifdef CONFIG_VFPv3 |
| 345 | #define VFP_REG_ZERO 32 | 318 | #define VFP_REG_ZERO 32 |
| 346 | #else | 319 | #else |
| 347 | #define VFP_REG_ZERO 16 | 320 | #define VFP_REG_ZERO 16 |
| 348 | #endif | 321 | #endif |
| 349 | 322 | ||
| 350 | #define VFP_DOUBLE_MANTISSA_BITS (52) | 323 | #define VFP_DOUBLE_MANTISSA_BITS (52) |
| 351 | #define VFP_DOUBLE_EXPONENT_BITS (11) | 324 | #define VFP_DOUBLE_EXPONENT_BITS (11) |
| 352 | #define VFP_DOUBLE_LOW_BITS (64 - VFP_DOUBLE_MANTISSA_BITS - 2) | 325 | #define VFP_DOUBLE_LOW_BITS (64 - VFP_DOUBLE_MANTISSA_BITS - 2) |
| 353 | #define VFP_DOUBLE_LOW_BITS_MASK ((1 << VFP_DOUBLE_LOW_BITS) - 1) | 326 | #define VFP_DOUBLE_LOW_BITS_MASK ((1 << VFP_DOUBLE_LOW_BITS) - 1) |
| 354 | 327 | ||
| 355 | /* | 328 | // The bit in an unpacked double which indicates that it is a quiet NaN |
| 356 | * The bit in an unpacked double which indicates that it is a quiet NaN | 329 | #define VFP_DOUBLE_SIGNIFICAND_QNAN (1ULL << (VFP_DOUBLE_MANTISSA_BITS - 1 + VFP_DOUBLE_LOW_BITS)) |
| 357 | */ | 330 | |
| 358 | #define VFP_DOUBLE_SIGNIFICAND_QNAN (1ULL << (VFP_DOUBLE_MANTISSA_BITS - 1 + VFP_DOUBLE_LOW_BITS)) | 331 | // Operations on packed single-precision numbers |
| 359 | 332 | #define vfp_double_packed_sign(v) ((v) & (1ULL << 63)) | |
| 360 | /* | 333 | #define vfp_double_packed_negate(v) ((v) ^ (1ULL << 63)) |
| 361 | * Operations on packed single-precision numbers | 334 | #define vfp_double_packed_abs(v) ((v) & ~(1ULL << 63)) |
| 362 | */ | 335 | #define vfp_double_packed_exponent(v) (((v) >> VFP_DOUBLE_MANTISSA_BITS) & ((1 << VFP_DOUBLE_EXPONENT_BITS) - 1)) |
| 363 | #define vfp_double_packed_sign(v) ((v) & (1ULL << 63)) | 336 | #define vfp_double_packed_mantissa(v) ((v) & ((1ULL << VFP_DOUBLE_MANTISSA_BITS) - 1)) |
| 364 | #define vfp_double_packed_negate(v) ((v) ^ (1ULL << 63)) | 337 | |
| 365 | #define vfp_double_packed_abs(v) ((v) & ~(1ULL << 63)) | 338 | // Unpack a double-precision float. Note that this returns the magnitude |
| 366 | #define vfp_double_packed_exponent(v) (((v) >> VFP_DOUBLE_MANTISSA_BITS) & ((1 << VFP_DOUBLE_EXPONENT_BITS) - 1)) | 339 | // of the double-precision float mantissa with the 1. if necessary, |
| 367 | #define vfp_double_packed_mantissa(v) ((v) & ((1ULL << VFP_DOUBLE_MANTISSA_BITS) - 1)) | 340 | // aligned to bit 62. |
| 368 | 341 | static inline void vfp_double_unpack(vfp_double* s, s64 val) | |
| 369 | /* | ||
| 370 | * Unpack a double-precision float. Note that this returns the magnitude | ||
| 371 | * of the double-precision float mantissa with the 1. if necessary, | ||
| 372 | * aligned to bit 62. | ||
| 373 | */ | ||
| 374 | static inline void vfp_double_unpack(struct vfp_double *s, s64 val) | ||
| 375 | { | 342 | { |
| 376 | u64 significand; | 343 | u64 significand; |
| 377 | 344 | ||
| @@ -385,11 +352,9 @@ static inline void vfp_double_unpack(struct vfp_double *s, s64 val) | |||
| 385 | s->significand = significand; | 352 | s->significand = significand; |
| 386 | } | 353 | } |
| 387 | 354 | ||
| 388 | /* | 355 | // Re-pack a double-precision float. This assumes that the float is |
| 389 | * Re-pack a double-precision float. This assumes that the float is | 356 | // already normalised such that the MSB is bit 30, _not_ bit 31. |
| 390 | * already normalised such that the MSB is bit 30, _not_ bit 31. | 357 | static inline s64 vfp_double_pack(vfp_double* s) |
| 391 | */ | ||
| 392 | static inline s64 vfp_double_pack(struct vfp_double *s) | ||
| 393 | { | 358 | { |
| 394 | u64 val = ((u64)s->sign << 48) + | 359 | u64 val = ((u64)s->sign << 48) + |
| 395 | ((u64)s->exponent << VFP_DOUBLE_MANTISSA_BITS) + | 360 | ((u64)s->exponent << VFP_DOUBLE_MANTISSA_BITS) + |
| @@ -397,7 +362,7 @@ static inline s64 vfp_double_pack(struct vfp_double *s) | |||
| 397 | return (s64)val; | 362 | return (s64)val; |
| 398 | } | 363 | } |
| 399 | 364 | ||
| 400 | static inline int vfp_double_type(struct vfp_double *s) | 365 | static inline int vfp_double_type(vfp_double* s) |
| 401 | { | 366 | { |
| 402 | int type = VFP_NUMBER; | 367 | int type = VFP_NUMBER; |
| 403 | if (s->exponent == 2047) { | 368 | if (s->exponent == 2047) { |
| @@ -416,34 +381,30 @@ static inline int vfp_double_type(struct vfp_double *s) | |||
| 416 | return type; | 381 | return type; |
| 417 | } | 382 | } |
| 418 | 383 | ||
| 419 | u32 vfp_double_normaliseround(ARMul_State* state, int dd, struct vfp_double *vd, u32 fpscr, u32 exceptions, const char *func); | 384 | u32 vfp_double_normaliseround(ARMul_State* state, int dd, vfp_double* vd, u32 fpscr, u32 exceptions, const char* func); |
| 420 | 385 | ||
| 421 | u32 vfp_estimate_sqrt_significand(u32 exponent, u32 significand); | 386 | u32 vfp_estimate_sqrt_significand(u32 exponent, u32 significand); |
| 422 | 387 | ||
| 423 | /* | 388 | // A special flag to tell the normalisation code not to normalise. |
| 424 | * A special flag to tell the normalisation code not to normalise. | 389 | #define VFP_NAN_FLAG 0x100 |
| 425 | */ | 390 | |
| 426 | #define VFP_NAN_FLAG 0x100 | 391 | // A bit pattern used to indicate the initial (unset) value of the |
| 427 | 392 | // exception mask, in case nothing handles an instruction. This | |
| 428 | /* | 393 | // doesn't include the NAN flag, which get masked out before |
| 429 | * A bit pattern used to indicate the initial (unset) value of the | 394 | // we check for an error. |
| 430 | * exception mask, in case nothing handles an instruction. This | 395 | #define VFP_EXCEPTION_ERROR ((u32)-1 & ~VFP_NAN_FLAG) |
| 431 | * doesn't include the NAN flag, which get masked out before | 396 | |
| 432 | * we check for an error. | 397 | // A flag to tell vfp instruction type. |
| 433 | */ | 398 | // OP_SCALAR - This operation always operates in scalar mode |
| 434 | #define VFP_EXCEPTION_ERROR ((u32)-1 & ~VFP_NAN_FLAG) | 399 | // OP_SD - The instruction exceptionally writes to a single precision result. |
| 435 | 400 | // OP_DD - The instruction exceptionally writes to a double precision result. | |
| 436 | /* | 401 | // OP_SM - The instruction exceptionally reads from a single precision operand. |
| 437 | * A flag to tell vfp instruction type. | 402 | enum : u32 { |
| 438 | * OP_SCALAR - this operation always operates in scalar mode | 403 | OP_SCALAR = (1 << 0), |
| 439 | * OP_SD - the instruction exceptionally writes to a single precision result. | 404 | OP_SD = (1 << 1), |
| 440 | * OP_DD - the instruction exceptionally writes to a double precision result. | 405 | OP_DD = (1 << 1), |
| 441 | * OP_SM - the instruction exceptionally reads from a single precision operand. | 406 | OP_SM = (1 << 2) |
| 442 | */ | 407 | }; |
| 443 | #define OP_SCALAR (1 << 0) | ||
| 444 | #define OP_SD (1 << 1) | ||
| 445 | #define OP_DD (1 << 1) | ||
| 446 | #define OP_SM (1 << 2) | ||
| 447 | 408 | ||
| 448 | struct op { | 409 | struct op { |
| 449 | u32 (* const fn)(ARMul_State* state, int dd, int dn, int dm, u32 fpscr); | 410 | u32 (* const fn)(ARMul_State* state, int dd, int dn, int dm, u32 fpscr); |
| @@ -480,7 +441,7 @@ static inline u32 fls(ARMword x) | |||
| 480 | 441 | ||
| 481 | } | 442 | } |
| 482 | 443 | ||
| 483 | u32 vfp_double_normaliseroundintern(ARMul_State* state, struct vfp_double *vd, u32 fpscr, u32 exceptions, const char *func); | 444 | u32 vfp_double_normaliseroundintern(ARMul_State* state, vfp_double* vd, u32 fpscr, u32 exceptions, const char* func); |
| 484 | u32 vfp_double_multiply(struct vfp_double *vdd, struct vfp_double *vdn, struct vfp_double *vdm, u32 fpscr); | 445 | u32 vfp_double_multiply(vfp_double* vdd, vfp_double* vdn, vfp_double* vdm, u32 fpscr); |
| 485 | u32 vfp_double_add(struct vfp_double *vdd, struct vfp_double *vdn, struct vfp_double *vdm, u32 fpscr); | 446 | u32 vfp_double_add(vfp_double* vdd, vfp_double* vdn, vfp_double *vdm, u32 fpscr); |
| 486 | u32 vfp_double_fcvtsinterncutting(ARMul_State* state, int sd, struct vfp_double* dm, u32 fpscr); | 447 | u32 vfp_double_fcvtsinterncutting(ARMul_State* state, int sd, vfp_double* dm, u32 fpscr); |
diff --git a/src/core/arm/skyeye_common/vfp/vfpdouble.cpp b/src/core/arm/skyeye_common/vfp/vfpdouble.cpp index d35ca510a..a05db0a45 100644 --- a/src/core/arm/skyeye_common/vfp/vfpdouble.cpp +++ b/src/core/arm/skyeye_common/vfp/vfpdouble.cpp | |||
| @@ -511,7 +511,7 @@ static u32 vfp_compare(ARMul_State* state, int dd, int signal_on_qnan, int dm, u | |||
| 511 | LOG_TRACE(Core_ARM11, "In %s, state=0x%x, fpscr=0x%x\n", __FUNCTION__, state, fpscr); | 511 | LOG_TRACE(Core_ARM11, "In %s, state=0x%x, fpscr=0x%x\n", __FUNCTION__, state, fpscr); |
| 512 | m = vfp_get_double(state, dm); | 512 | m = vfp_get_double(state, dm); |
| 513 | if (vfp_double_packed_exponent(m) == 2047 && vfp_double_packed_mantissa(m)) { | 513 | if (vfp_double_packed_exponent(m) == 2047 && vfp_double_packed_mantissa(m)) { |
| 514 | ret |= FPSCR_C | FPSCR_V; | 514 | ret |= FPSCR_CFLAG | FPSCR_VFLAG; |
| 515 | if (signal_on_qnan || !(vfp_double_packed_mantissa(m) & (1ULL << (VFP_DOUBLE_MANTISSA_BITS - 1)))) | 515 | if (signal_on_qnan || !(vfp_double_packed_mantissa(m) & (1ULL << (VFP_DOUBLE_MANTISSA_BITS - 1)))) |
| 516 | /* | 516 | /* |
| 517 | * Signalling NaN, or signalling on quiet NaN | 517 | * Signalling NaN, or signalling on quiet NaN |
| @@ -521,7 +521,7 @@ static u32 vfp_compare(ARMul_State* state, int dd, int signal_on_qnan, int dm, u | |||
| 521 | 521 | ||
| 522 | d = vfp_get_double(state, dd); | 522 | d = vfp_get_double(state, dd); |
| 523 | if (vfp_double_packed_exponent(d) == 2047 && vfp_double_packed_mantissa(d)) { | 523 | if (vfp_double_packed_exponent(d) == 2047 && vfp_double_packed_mantissa(d)) { |
| 524 | ret |= FPSCR_C | FPSCR_V; | 524 | ret |= FPSCR_CFLAG | FPSCR_VFLAG; |
| 525 | if (signal_on_qnan || !(vfp_double_packed_mantissa(d) & (1ULL << (VFP_DOUBLE_MANTISSA_BITS - 1)))) | 525 | if (signal_on_qnan || !(vfp_double_packed_mantissa(d) & (1ULL << (VFP_DOUBLE_MANTISSA_BITS - 1)))) |
| 526 | /* | 526 | /* |
| 527 | * Signalling NaN, or signalling on quiet NaN | 527 | * Signalling NaN, or signalling on quiet NaN |
| @@ -535,7 +535,7 @@ static u32 vfp_compare(ARMul_State* state, int dd, int signal_on_qnan, int dm, u | |||
| 535 | /* | 535 | /* |
| 536 | * equal | 536 | * equal |
| 537 | */ | 537 | */ |
| 538 | ret |= FPSCR_Z | FPSCR_C; | 538 | ret |= FPSCR_ZFLAG | FPSCR_CFLAG; |
| 539 | //printf("In %s,1 ret=0x%x\n", __FUNCTION__, ret); | 539 | //printf("In %s,1 ret=0x%x\n", __FUNCTION__, ret); |
| 540 | } else if (vfp_double_packed_sign(d ^ m)) { | 540 | } else if (vfp_double_packed_sign(d ^ m)) { |
| 541 | /* | 541 | /* |
| @@ -545,22 +545,22 @@ static u32 vfp_compare(ARMul_State* state, int dd, int signal_on_qnan, int dm, u | |||
| 545 | /* | 545 | /* |
| 546 | * d is negative, so d < m | 546 | * d is negative, so d < m |
| 547 | */ | 547 | */ |
| 548 | ret |= FPSCR_N; | 548 | ret |= FPSCR_NFLAG; |
| 549 | else | 549 | else |
| 550 | /* | 550 | /* |
| 551 | * d is positive, so d > m | 551 | * d is positive, so d > m |
| 552 | */ | 552 | */ |
| 553 | ret |= FPSCR_C; | 553 | ret |= FPSCR_CFLAG; |
| 554 | } else if ((vfp_double_packed_sign(d) != 0) ^ (d < m)) { | 554 | } else if ((vfp_double_packed_sign(d) != 0) ^ (d < m)) { |
| 555 | /* | 555 | /* |
| 556 | * d < m | 556 | * d < m |
| 557 | */ | 557 | */ |
| 558 | ret |= FPSCR_N; | 558 | ret |= FPSCR_NFLAG; |
| 559 | } else if ((vfp_double_packed_sign(d) != 0) ^ (d > m)) { | 559 | } else if ((vfp_double_packed_sign(d) != 0) ^ (d > m)) { |
| 560 | /* | 560 | /* |
| 561 | * d > m | 561 | * d > m |
| 562 | */ | 562 | */ |
| 563 | ret |= FPSCR_C; | 563 | ret |= FPSCR_CFLAG; |
| 564 | } | 564 | } |
| 565 | } | 565 | } |
| 566 | LOG_TRACE(Core_ARM11, "In %s, state=0x%x, ret=0x%x\n", __FUNCTION__, state, ret); | 566 | LOG_TRACE(Core_ARM11, "In %s, state=0x%x, ret=0x%x\n", __FUNCTION__, state, ret); |
diff --git a/src/core/arm/skyeye_common/vfp/vfpsingle.cpp b/src/core/arm/skyeye_common/vfp/vfpsingle.cpp index b7872bdc4..da4d2d384 100644 --- a/src/core/arm/skyeye_common/vfp/vfpsingle.cpp +++ b/src/core/arm/skyeye_common/vfp/vfpsingle.cpp | |||
| @@ -419,7 +419,7 @@ static u32 vfp_compare(ARMul_State* state, int sd, int signal_on_qnan, s32 m, u3 | |||
| 419 | 419 | ||
| 420 | d = vfp_get_float(state, sd); | 420 | d = vfp_get_float(state, sd); |
| 421 | if (vfp_single_packed_exponent(m) == 255 && vfp_single_packed_mantissa(m)) { | 421 | if (vfp_single_packed_exponent(m) == 255 && vfp_single_packed_mantissa(m)) { |
| 422 | ret |= FPSCR_C | FPSCR_V; | 422 | ret |= FPSCR_CFLAG | FPSCR_VFLAG; |
| 423 | if (signal_on_qnan || !(vfp_single_packed_mantissa(m) & (1 << (VFP_SINGLE_MANTISSA_BITS - 1)))) | 423 | if (signal_on_qnan || !(vfp_single_packed_mantissa(m) & (1 << (VFP_SINGLE_MANTISSA_BITS - 1)))) |
| 424 | /* | 424 | /* |
| 425 | * Signalling NaN, or signalling on quiet NaN | 425 | * Signalling NaN, or signalling on quiet NaN |
| @@ -428,7 +428,7 @@ static u32 vfp_compare(ARMul_State* state, int sd, int signal_on_qnan, s32 m, u3 | |||
| 428 | } | 428 | } |
| 429 | 429 | ||
| 430 | if (vfp_single_packed_exponent(d) == 255 && vfp_single_packed_mantissa(d)) { | 430 | if (vfp_single_packed_exponent(d) == 255 && vfp_single_packed_mantissa(d)) { |
| 431 | ret |= FPSCR_C | FPSCR_V; | 431 | ret |= FPSCR_CFLAG | FPSCR_VFLAG; |
| 432 | if (signal_on_qnan || !(vfp_single_packed_mantissa(d) & (1 << (VFP_SINGLE_MANTISSA_BITS - 1)))) | 432 | if (signal_on_qnan || !(vfp_single_packed_mantissa(d) & (1 << (VFP_SINGLE_MANTISSA_BITS - 1)))) |
| 433 | /* | 433 | /* |
| 434 | * Signalling NaN, or signalling on quiet NaN | 434 | * Signalling NaN, or signalling on quiet NaN |
| @@ -441,7 +441,7 @@ static u32 vfp_compare(ARMul_State* state, int sd, int signal_on_qnan, s32 m, u3 | |||
| 441 | /* | 441 | /* |
| 442 | * equal | 442 | * equal |
| 443 | */ | 443 | */ |
| 444 | ret |= FPSCR_Z | FPSCR_C; | 444 | ret |= FPSCR_ZFLAG | FPSCR_CFLAG; |
| 445 | } else if (vfp_single_packed_sign(d ^ m)) { | 445 | } else if (vfp_single_packed_sign(d ^ m)) { |
| 446 | /* | 446 | /* |
| 447 | * different signs | 447 | * different signs |
| @@ -450,22 +450,22 @@ static u32 vfp_compare(ARMul_State* state, int sd, int signal_on_qnan, s32 m, u3 | |||
| 450 | /* | 450 | /* |
| 451 | * d is negative, so d < m | 451 | * d is negative, so d < m |
| 452 | */ | 452 | */ |
| 453 | ret |= FPSCR_N; | 453 | ret |= FPSCR_NFLAG; |
| 454 | else | 454 | else |
| 455 | /* | 455 | /* |
| 456 | * d is positive, so d > m | 456 | * d is positive, so d > m |
| 457 | */ | 457 | */ |
| 458 | ret |= FPSCR_C; | 458 | ret |= FPSCR_CFLAG; |
| 459 | } else if ((vfp_single_packed_sign(d) != 0) ^ (d < m)) { | 459 | } else if ((vfp_single_packed_sign(d) != 0) ^ (d < m)) { |
| 460 | /* | 460 | /* |
| 461 | * d < m | 461 | * d < m |
| 462 | */ | 462 | */ |
| 463 | ret |= FPSCR_N; | 463 | ret |= FPSCR_NFLAG; |
| 464 | } else if ((vfp_single_packed_sign(d) != 0) ^ (d > m)) { | 464 | } else if ((vfp_single_packed_sign(d) != 0) ^ (d > m)) { |
| 465 | /* | 465 | /* |
| 466 | * d > m | 466 | * d > m |
| 467 | */ | 467 | */ |
| 468 | ret |= FPSCR_C; | 468 | ret |= FPSCR_CFLAG; |
| 469 | } | 469 | } |
| 470 | } | 470 | } |
| 471 | return ret; | 471 | return ret; |