| View previous topic :: View next topic |
| Author |
Message |
Ghoti
Joined: 31 Dec 2005 Posts: 288
|
Posted: Sun Jul 29, 2007 7:18 am Post subject: FPU error in psplink |
|
|
Hi folks,
I have this error in psplink: | Code: |
Exception - FPU Exception (IUV)
Thread ID - 0x00206A2D
Th Name - user_main
Module ID - 0x017DA21F
Mod Name - "Raze"
EPC - 0x089113B4
Cause - 0x1000003C
BadVAddr - 0x00000000
Status - 0x20008613
zr:0x00000000 at:0x08DC0000 v0:0x00000085 v1:0x00000035
a0:0x09F7FCFC a1:0x003BFE34 a2:0x42BBFE34 a3:0x00000000
t0:0x00000085 t1:0x00000000 t2:0x09F7FC98 t3:0x355EF4E8 |
now it crashes in this code:
| Code: | void Vector3D::Normalize(ScePspFVector3& vec1){
float lenght = (float)sqrt((double)(vec1.x * vec1.x + vec1.y * vec1.y + vec1.z * vec1.z));
vec1.x /= lenght;
vec1.y /= lenght;
vec1.z /= lenght;
}; |
Now this code works because it correctly does his job for other values but with this vector:
0.000000f, 0.00000f, -0.1000000f
it does not work.
I have tried to not divide when both length is zero or the vec attribute is zero but still that error.
any ideas? it's driving me crazy :S
greets ghoti _________________ My PSP games:
Boxy II: http://www.ghoti.nl/boxyii.php
Elementals: http://www.ghoti.nl/Elementals.php |
|
| Back to top |
|
 |
hlide
Joined: 10 Sep 2006 Posts: 750
|
Posted: Sun Jul 29, 2007 7:52 am Post subject: |
|
|
please output the assembly code at this point.
by the way could you try to avoid "double" ? using it will compute in a software mode (double are emulated through integer computation), which is probably not what you want. |
|
| Back to top |
|
 |
Ghoti
Joined: 31 Dec 2005 Posts: 288
|
Posted: Sun Jul 29, 2007 8:01 am Post subject: |
|
|
Hi, well I did not cast anything before this, hoped it was the problem. If i don't use the casts it still works fine for theother values.
the sqrt command needs doubles so is there a better way to avoid the software mode ? (if i don't cast will that do the trick , like i did before trying to cast?)
I can't output the assembly code at this point because I never got the debugger to work.
any ideas ? _________________ My PSP games:
Boxy II: http://www.ghoti.nl/boxyii.php
Elementals: http://www.ghoti.nl/Elementals.php |
|
| Back to top |
|
 |
hlide
Joined: 10 Sep 2006 Posts: 750
|
Posted: Sun Jul 29, 2007 8:04 am Post subject: |
|
|
void Vector3D::Normalize(ScePspFVector3& vec1){
float lenght = (float)sqrt((double)(vec1.x * vec1.x + vec1.y * vec1.y + vec1.z * vec1.z));
vec1.x /= lenght;
vec1.y /= lenght;
vec1.z /= lenght;
};
| Code: |
void Vector3D::Normalize(ScePspFVector3& vec1){
asm (
" lv.s S000, 0+%0\n"
" lv.s S001, 4+%0\n"
" lv.s S002, 8+%0\n"
" vdot.t S003, C000, C000\n" // length = vec1.x * vec1.x + vec1.y * vec1.y + vec1.z * vec1.z
" vrcp.s S003, S003\n" // length = 1/length
" vscl.t C000, S003\n" // vec1.x /= length; vec1.y /= length; vec1.z /= length;
" sv.s S000, 0+%0\n"
" sv.s S001, 4+%0\n"
" sv.s S002, 8+%0\n"
: "+m"(vec1) : : "memory");
}
|
libpspmath.zip from MrMr[Ice] has stuff like that, if you really want to have a fast library. |
|
| Back to top |
|
 |
Ghoti
Joined: 31 Dec 2005 Posts: 288
|
Posted: Sun Jul 29, 2007 8:10 am Post subject: |
|
|
k well I'm not into asm at all so i replaced my function for yours(I thought I should do that i guess)
and I get also errors with the FPU only now in compiler time:
/cygdrive/c/DOCUME~1/Reinier/LOCALS~1/Temp/ccERFXrw.s: Assembler messages:
/cygdrive/c/DOCUME~1/Reinier/LOCALS~1/Temp/ccERFXrw.s:328: Error: Improper VFPU register prefix 's'
/cygdrive/c/DOCUME~1/Reinier/LOCALS~1/Temp/ccERFXrw.s:328: Error: Improper VFPU register number (003)
/cygdrive/c/DOCUME~1/Reinier/LOCALS~1/Temp/ccERFXrw.s:328: Error: illegal operands `vmul.t'
maybe I should not have done that but I could not find a difference with the other code. hope this helps a bit :s _________________ My PSP games:
Boxy II: http://www.ghoti.nl/boxyii.php
Elementals: http://www.ghoti.nl/Elementals.php |
|
| Back to top |
|
 |
hlide
Joined: 10 Sep 2006 Posts: 750
|
Posted: Sun Jul 29, 2007 8:12 am Post subject: |
|
|
fsqrt ?
Last edited by hlide on Sun Jul 29, 2007 8:18 am; edited 1 time in total |
|
| Back to top |
|
 |
hlide
Joined: 10 Sep 2006 Posts: 750
|
Posted: Sun Jul 29, 2007 8:15 am Post subject: |
|
|
| Ghoti wrote: | k well I'm not into asm at all so i replaced my function for yours(I thought I should do that i guess)
and I get also errors with the FPU only now in compiler time:
/cygdrive/c/DOCUME~1/Reinier/LOCALS~1/Temp/ccERFXrw.s: Assembler messages:
/cygdrive/c/DOCUME~1/Reinier/LOCALS~1/Temp/ccERFXrw.s:328: Error: Improper VFPU register prefix 's'
/cygdrive/c/DOCUME~1/Reinier/LOCALS~1/Temp/ccERFXrw.s:328: Error: Improper VFPU register number (003)
/cygdrive/c/DOCUME~1/Reinier/LOCALS~1/Temp/ccERFXrw.s:328: Error: illegal operands `vmul.t'
maybe I should not have done that but I could not find a difference with the other code. hope this helps a bit :s |
not vmul.t but vscl.t indeed
well this is just to tell you there is a libpspmath.zip which has a lot of function about 3d stuff and which are very quick.
and dont forget to enable VFPU in your thread if you plan to use them
Last edited by hlide on Sun Jul 29, 2007 8:28 am; edited 1 time in total |
|
| Back to top |
|
 |
hlide
Joined: 10 Sep 2006 Posts: 750
|
Posted: Sun Jul 29, 2007 8:20 am Post subject: |
|
|
| Code: |
void Vector3D::Normalize(ScePspFVector3& vec1){
float length = fsqrt(vec1.x * vec1.x + vec1.y * vec1.y + vec1.z * vec1.z);
vec1.x /= length;
vec1.y /= length;
vec1.z /= length;
};
|
that should be okay but still slower than one in libpspmath.zip ;P. |
|
| Back to top |
|
 |
hlide
Joined: 10 Sep 2006 Posts: 750
|
Posted: Sun Jul 29, 2007 8:25 am Post subject: |
|
|
| Code: |
void Vector3D::Normalize(ScePspFVector3& vec1){
float x2 = vec1.x * vec1.x; LOG("x2 = %f\n", x2);
float y2 = vec1.y * vec1.y; LOG("y2 = %f\n", y2);
float z2 = vec1.z * vec1.z; LOG("z2 = %f\n", z2);
float length2 = vec1.x + vec1.y + vec1.z; LOG("l2 = %f\n", length2);
float length = fsqrt(length2); LOG("l = %f\n", length);
vec1.x /= length; LOG("vec1.x = %f\n", vec1.x);
vec1.y /= length; LOG("vec1.y = %f\n", vec1.y);
vec1.z /= length; LOG("vec1.z = %f\n", vec1.z);
};
|
replace LOG with the debug print function and cross the fingers to see where and why there is an exception. You should work this way if you cannot debug it. |
|
| Back to top |
|
 |
Ghoti
Joined: 31 Dec 2005 Posts: 288
|
|
| Back to top |
|
 |
crazyc
Joined: 17 Jun 2005 Posts: 410
|
Posted: Sun Jul 29, 2007 8:45 am Post subject: |
|
|
| Ghoti wrote: |
what include file do i need for the fsqrt ? |
Try sqrtf. |
|
| Back to top |
|
 |
hlide
Joined: 10 Sep 2006 Posts: 750
|
Posted: Sun Jul 29, 2007 8:49 am Post subject: |
|
|
math.h ?
well the float version of math functions must be preceded with f
so sqrt(double) -> fsqrt(float)
http://nixdoc.net/man-pages/IRIX/man3/sqrt.3.html
if not defined :
| Code: |
inline float fsqrt(float v) {
float r; asm volatile ("sqrt.s %0, %1" : "=f"(r) : "f"(v));
return r;
}
|
|
|
| Back to top |
|
 |
Ghoti
Joined: 31 Dec 2005 Posts: 288
|
Posted: Sun Jul 29, 2007 10:22 am Post subject: |
|
|
k it crashes at the first calculation:
float x2 = vec1.x * vec1.x;
doesn't make sense :s
and it does that with those values, because the first time i use it it works without a crash _________________ My PSP games:
Boxy II: http://www.ghoti.nl/boxyii.php
Elementals: http://www.ghoti.nl/Elementals.php |
|
| Back to top |
|
 |
Jim

Joined: 02 Jul 2005 Posts: 487 Location: Sydney
|
Posted: Sun Jul 29, 2007 11:53 am Post subject: |
|
|
C99 says it's a suffix, not a prefix.
| Code: |
#include <math.h>
double sqrt(double x);
float sqrtf(float x);
long double sqrtl(long double x);
|
I can only think the exception is an underflow, ie. vec.x is a very tiny number and when squared it underflows to 0. Perhaps the exception mask needs changing?
Jim _________________ http://www.dbfinteractive.com |
|
| Back to top |
|
 |
hlide
Joined: 10 Sep 2006 Posts: 750
|
Posted: Sun Jul 29, 2007 12:07 pm Post subject: |
|
|
| Jim wrote: | C99 says it's a suffix, not a prefix.
| Code: |
#include <math.h>
double sqrt(double x);
float sqrtf(float x);
long double sqrtl(long double x);
|
I can only think the exception is an underflow, ie. vec.x is a very tiny number and when squared it underflows to 0. Perhaps the exception mask needs changing?
Jim |
ok.
just a thought : if 0.0 x -0.0 = -0.0 (X x -Y = -XY), what 0.0 + -0.0 gives us ? 0.0, -0.0 , NaN ? and sqrtf(-0.0) ?
for some reason, I suspect LOG (whatever you put in) has no time to display a message, so you should have a "pause" between each LOG (that is, press a key to continue) so you can have time to see a message before the next instruction crashes |
|
| Back to top |
|
 |
Ghoti
Joined: 31 Dec 2005 Posts: 288
|
Posted: Sun Jul 29, 2007 9:04 pm Post subject: |
|
|
Hi well, I have a toolclass for this with a lot of functions, writing to file, displaying debug info etc. but one function is to loop the debug info, so when you reach that function it goes into a loop, or well it should go into a loop. I have create the loop in front of thevariables and after the variables and before it does its work perfectly fine but right after the first line of code it crashes :(
EDIT:
if I do this:
sprintf(s, "x= %f y= %f z= %f", vec1.x, vec1.y, vec1.z);
it shows that but as soon as I change it into vec1.x*vec1.x in stead of just vec1.x then it crashes :s
vec1.x = 0.00000f , so since when can't i multiply somthing by zero, i though that you cannot divide by zero but multiply also ? _________________ My PSP games:
Boxy II: http://www.ghoti.nl/boxyii.php
Elementals: http://www.ghoti.nl/Elementals.php |
|
| Back to top |
|
 |
Jim

Joined: 02 Jul 2005 Posts: 487 Location: Sydney
|
Posted: Sun Jul 29, 2007 10:29 pm Post subject: |
|
|
Of course you can multiply by zero, but is it really 0, or just 0 to 5 decimal places? Can you try using %g instead of %f?
If this "Status - 0x20008613" is your FPSCR, then that is showing a divide by zero exception.
<edit>I'm pretty sure it is, can you post the code with the "don't divide by zero" check in it that you are using?
Jim _________________ http://www.dbfinteractive.com |
|
| Back to top |
|
 |
TyRaNiD
Joined: 18 Jan 2004 Posts: 918
|
Posted: Mon Jul 30, 2007 3:58 am Post subject: |
|
|
| Status is actually the MIPS SR reg, you should be able to dump the actual FPU status reg with the 'exprfpu' command. Of course the character codes after the FPU exception actually indicate what has happend. In this case they are I which is inexact operation, U which is underflow and V which is invalid operation. Basically you have a normalisation issue with one of your floats being too small and the fpu blows up :) Best way around this is normally to just disable fpu exceptions. |
|
| Back to top |
|
 |
Jim

Joined: 02 Jul 2005 Posts: 487 Location: Sydney
|
|
| Back to top |
|
 |
|