Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VFPU: Ensure that sin(4*x) returns 0.0 (and cos 1) for all x. Fixes #2921 #6329

Merged
merged 2 commits into from
Jun 15, 2014
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 3 additions & 9 deletions Core/MIPS/ARM/ArmCompVFPU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1832,24 +1832,18 @@ namespace MIPSComp
fpr.ReleaseSpillLocksAndDiscardTemps();
}

#ifndef M_PI_2
#define M_PI_2 1.57079632679489661923
#endif
// sincosf is unavailable in the Android NDK:
// https://code.google.com/p/android/issues/detail?id=38423
double SinCos(float angle) {
union { struct { float sin; float cos; }; double out; } sincos;
angle *= (float)M_PI_2;
sincos.sin = sinf(angle);
sincos.cos = cosf(angle);
vfpu_sincos(angle, sincos.sin, sincos.cos);
return sincos.out;
}

double SinCosNegSin(float angle) {
union { struct { float sin; float cos; }; double out; } sincos;
angle *= (float)M_PI_2;
sincos.sin = -sinf(angle);
sincos.cos = cosf(angle);
vfpu_sincos(angle, sincos.sin, sincos.cos);
sincos.sin = -sincos.sin;
return sincos.out;
}

Expand Down
3 changes: 3 additions & 0 deletions Core/MIPS/MIPS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,10 @@ u8 fromvoffset[128];
#define M_LN10 2.30258509299404568402f
#undef M_PI
#define M_PI 3.14159265358979323846f

#ifndef M_PI_2
#define M_PI_2 1.57079632679489661923f
#endif
#define M_PI_4 0.785398163397448309616f
#define M_1_PI 0.318309886183790671538f
#define M_2_PI 0.636619772367581343076f
Expand Down
22 changes: 11 additions & 11 deletions Core/MIPS/MIPSIntVFPU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@
#define M_LN10 2.30258509299404568402f
#undef M_PI
#define M_PI 3.14159265358979323846f
#ifndef M_PI_2
#define M_PI_2 1.57079632679489661923f
#endif
#define M_PI_4 0.785398163397448309616f
#define M_1_PI 0.318309886183790671538f
#define M_2_PI 0.636619772367581343076f
Expand Down Expand Up @@ -517,14 +519,15 @@ namespace MIPSInt
case 5: if (s[i] < -1.0f) d[i] = -1.0f; else {if(s[i] > 1.0f) d[i] = 1.0f; else d[i] = s[i];} break; // vsat1
case 16: d[i] = 1.0f / s[i]; break; //vrcp
case 17: d[i] = 1.0f / sqrtf(s[i]); break; //vrsq
case 18: d[i] = sinf((float)M_PI_2 * s[i]); break; //vsin
case 19: d[i] = cosf((float)M_PI_2 * s[i]); break; //vcos

case 18: { d[i] = vfpu_sin(s[i]); } break; //vsin
case 19: { d[i] = vfpu_cos(s[i]); } break; //vcos
case 20: d[i] = powf(2.0f, s[i]); break; //vexp2
case 21: d[i] = logf(s[i])/log(2.0f); break; //vlog2
case 22: d[i] = fabsf(sqrtf(s[i])); break; //vsqrt
case 23: d[i] = asinf(s[i]) / M_PI_2; break; //vasin
case 24: d[i] = -1.0f / s[i]; break; // vnrcp
case 26: d[i] = -sinf((float)M_PI_2 * s[i]); break; // vnsin
case 26: { d[i] = -vfpu_sin(s[i]); } break; // vnsin
case 28: d[i] = 1.0f / powf(2.0, s[i]); break; // vrexp2
default:
_dbg_assert_msg_(CPU,0,"Trying to interpret VV2Op instruction that can't be interpreted");
Expand Down Expand Up @@ -1285,21 +1288,18 @@ namespace MIPSInt
}

// Generates one line of a rotation matrix around one of the three axes
void Int_Vrot(MIPSOpcode op)
{
void Int_Vrot(MIPSOpcode op) {
int vd = _VD;
int vs = _VS;
int imm = (op >> 16) & 0x1f;
VectorSize sz = GetVecSize(op);
float angle = V(vs) * M_PI_2;
bool negSin = (imm & 0x10) ? true : false;
float sine = sinf(angle);
float cosine = cosf(angle);
float sine, cosine;
vfpu_sincos(V(vs), sine, cosine);
if (negSin)
sine = -sine;
float d[4] = {0};
if (((imm >> 2) & 3) == (imm & 3))
{
if (((imm >> 2) & 3) == (imm & 3)) {
for (int i = 0; i < 4; i++)
d[i] = sine;
}
Expand Down Expand Up @@ -1845,7 +1845,7 @@ namespace MIPSInt
ERROR_LOG_REPORT(CPU, "vsbn not implemented for size %d", GetNumVectorElements(sz));
}
for (int i = 0; i < GetNumVectorElements(sz); ++i) {
// Simply replace the expontent bits.
// Simply replace the exponent bits.
u32 prev = s.u[i] & 0x7F800000;
if (prev != 0 && prev != 0x7F800000) {
d.u[i] = (s.u[i] & ~0x7F800000) | (exp << 23);
Expand Down
28 changes: 25 additions & 3 deletions Core/MIPS/MIPSVFPUUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,39 @@

#pragma once


#include <cmath>

#define _VD (op & 0x7F)
#define _VS ((op>>8) & 0x7F)
#define _VT ((op>>16) & 0x7F)

inline int Xpose(int v)
{
inline int Xpose(int v) {
return v^0x20;
}

#ifndef M_PI_2
#define M_PI_2 1.57079632679489661923
#endif

inline float vfpu_sin(float angle) {
angle -= floorf(angle * 4.0f) * 0.25f;
angle *= (float)M_PI_2;
return sinf(angle);
}

inline float vfpu_cos(float angle) {
angle -= floorf(angle * 4.0f) * 0.25f;
angle *= (float)M_PI_2;
return cosf(angle);
}

inline void vfpu_sincos(float angle, float &sine, float &cosine) {
angle -= floorf(angle * 4.0f) * 0.25f;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, not sure this is rounding right?

Angle 1 = 1_pi/2 = sin=1,cos=0
Angle 2 = 2_pi/2 = sin=0,cos=-1
Angle 3 = 3_pi/2 = sin=-1,cos=0
Angle 4 = 4_pi/2 = sin=0,cos=1

However, 3 - floor(3 * 4) * 0.25 = 3 - 12 * 0.25 = 0. Should be * 0.25 / 4, right?

-[Unknown]

angle *= (float)M_PI_2;
sine = sinf(angle);
cosine = cosf(angle);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Android has sincosf() these days (latest ndks) right? Though not sure what our build req is.

-[Unknown]

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the buildbot upgraded to the latest?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Last I checked it seemed to have ndk-r9b, from October 2013.

https://code.google.com/p/android/issues/detail?id=38423
Was marked "released" October 31, 2013. Not sure if that means it's in b or c...

-[Unknown]

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it didn't actually make it until d, but not sure. Maybe c. Pretty sure not b.

}

#define VFPU_FLOAT16_EXP_MAX 0x1f
#define VFPU_SH_FLOAT16_SIGN 15
#define VFPU_MASK_FLOAT16_SIGN 0x1
Expand Down
9 changes: 3 additions & 6 deletions Core/MIPS/x86/CompVFPU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2125,15 +2125,12 @@ typedef u32float SinCosArg;
#endif

void SinCos(SinCosArg angle) {
angle *= (float)1.57079632679489661923; // pi / 2
sincostemp[0] = sinf(angle);
sincostemp[1] = cosf(angle);
vfpu_sincos(angle, sincostemp[0], sincostemp[1]);
}

void SinCosNegSin(SinCosArg angle) {
angle *= (float)1.57079632679489661923; // pi / 2
sincostemp[0] = -sinf(angle);
sincostemp[1] = cosf(angle);
vfpu_sincos(angle, sincostemp[0], sincostemp[1]);
sincostemp[0] = -sincostemp[0];
}

// Very heavily used by FF:CC
Expand Down