 |
forums.ps2dev.org Homebrew PS2, PSP & PS3 Development Discussions
|
| View previous topic :: View next topic |
| Author |
Message |
starman2049
Joined: 19 Sep 2005 Posts: 75
|
Posted: Sun Apr 23, 2006 3:50 pm Post subject: Inline VFPU help |
|
|
I am trying to replace the sqrt() function using the codegen.h approach and have written the following but it has a bug. I am a new at inline assembler and can't get the following to work (it just returns the value I pass it)
| Code: | float mysqrt(float val)
{
register float a=val;
register float b;
__asm__ volatile (
cgen_asm(vsqrt_s(R_a0, R_a1))
:"=r"(b)
:"r"(a), "r"(b)
);
return (b);
}
|
Can anyone lead me out of the dark on how to do this correctly? |
|
| Back to top |
|
 |
popcornx
Joined: 14 Mar 2006 Posts: 6
|
Posted: Mon Apr 24, 2006 4:58 pm Post subject: |
|
|
hmm I'm a MIPS n00b too but I'll still try to help
| Code: |
float mysqrt(float val)
{
int b=0;
register float par1 asm($16)=val; //parameter 1
register float par2 asm($17)=2; //parameter 2
asm (
:
:"r"(par1),"r"(par2) // insert val into reg $16 & 2 into $17
);
asm("move $a0,$16");//move the first paratermeter
asm("move $a1,$17");//move the first paratermeter
asm("jal vsqrt");
asm("sw $ra,($18");
register float retv asm($18); //return value
asm (
:"=r"(retv)
:
);
return (retv);
}
|
I'm a n00b so I dunno if this works or not...I hope it does!!!
if not you can ask skylark or fanjita for help. I think they will respond. |
|
| Back to top |
|
 |
chp
Joined: 23 Jun 2004 Posts: 313
|
Posted: Mon Apr 24, 2006 6:05 pm Post subject: |
|
|
Actually, since you're trying to use the VFPU, I wonder if you can even use the general registers for this... Something like this should work: (note that VFPU is supported in the current binutils, so no need for codegen)
| Code: | float mysqrt(float val)
{
float ret;
__asm__ volatile (
"mtv %1, S000\n"
"vsqrt.s S001, S000\n"
"mfv %0, S001\n"
: "=r"(ret) : "r"(val) );
return ret;
} |
This should work (I looked at the output and it looked ok), but I don't have access to hardware to test it with right now. _________________ GE Dominator |
|
| Back to top |
|
 |
starman2049
Joined: 19 Sep 2005 Posts: 75
|
Posted: Thu Apr 27, 2006 8:22 am Post subject: |
|
|
Can't get anywhere with this. I'm on september '05 toolchain and sdk so the VFPU stuff is not builtin so I had to stick with codegen.h approach. Unfortunatly there is no mtv/mvf and I spent some time trying to add those opcodes to little avail.
Then I decided to update my toolchain and grabbed the latest "famous" version from oopo.net haggled through that for a bit to find that it looks like the VFPU stuff is only in the version in SVN as of yet.
I've never been able to checkout stuff from svn.ps2dev.net - it keeps saying that the hostname is invalid. I tried punching TCP/3690 open on my router but can't get to it.
I tried the beta toolchain from oopo.net, but it failed in the install so I went back to the latest "famous" version.
Is there a userid/pw that is needed for svn.pspdev.org? |
|
| Back to top |
|
 |
Oobles Site Admin
Joined: 17 Jan 2004 Posts: 362 Location: Melbourne, Australia
|
Posted: Thu Apr 27, 2006 9:13 am Post subject: |
|
|
No userid or password is required for svn.ps2dev.org. Please make sure you have the correct URL. In your last message you refer to it as svn.ps2ev.net and svn.pspdev.org which are both wrong.
If you have a restrictive firewall you might not be able to access the server. Let me know if you have any more problems. I believe someone did create a mirror of subversion that can be accessed through HTTP. You should be able to find it on forums via search.
David. aka Oobles. |
|
| Back to top |
|
 |
dot_blank

Joined: 28 Sep 2005 Posts: 498 Location: Brasil
|
Posted: Thu Apr 27, 2006 11:34 am Post subject: |
|
|
tried and below works:
user@host$ svn co svn://ps2dev.org/psp/trunk/pspsdk
then future updating is:
user@host$ cd pspsdk
user@host$ svn up _________________ 10011011 00101010 11010111 10001001 10111010 |
|
| Back to top |
|
 |
starman2049
Joined: 19 Sep 2005 Posts: 75
|
Posted: Thu Apr 27, 2006 7:12 pm Post subject: |
|
|
| Well I still can't get into svn, but I was able to get my sqrt(), sin(), cos(), etc over to VFPU and got a very nice speed-up so thank you to everyone who helped with this!! |
|
| Back to top |
|
 |
starman2049
Joined: 19 Sep 2005 Posts: 75
|
Posted: Fri Apr 28, 2006 11:58 am Post subject: |
|
|
These are probably done in newlib or elsewhere already, but if you have the latest toolchain you should be able to implement your own math functions that are MUCH faster. Note you have to add "|" PSP_THREAD_ATTR_VFPU into your PSP_MAIN_THREAD_ATTR() def in main.c.
| Code: | float mysqrtf(float val)
{
float ret;
__asm__ volatile (
"mtv %1, S000\n"
"vsqrt.s S001, S000\n"
"mfv %0, S001\n"
: "=r"(ret) : "r"(val));
return ret;
}
|
| Code: | float mysinf(float val)
{
float ret;
val *= 0.6366197f; // convert to deg/90
__asm__ volatile (
"mtv %1, S000\n"
"vsin.s S001, S000\n"
"mfv %0, S001\n"
: "=r"(ret) : "r"(val));
return ret;
}
|
| Code: | float mycosf(float val)
{
float ret;
val *= 0.6366197f; // convert to deg/90
__asm__ volatile (
"mtv %1, S000\n"
"vcos.s S001, S000\n"
"mfv %0, S001\n"
: "=r"(ret) : "r"(val));
return ret;
}
|
|
|
| Back to top |
|
 |
dot_blank

Joined: 28 Sep 2005 Posts: 498 Location: Brasil
|
Posted: Fri Apr 28, 2006 3:02 pm Post subject: |
|
|
well these seem to work quiet well :)
i think the toolchain will do good with maybe a
vfpu math library ....something in the sense of
and then one would simply use them as such
| Code: | vcos(2*c_wave);
vinf(value);
//etc... |
what do the mods think? _________________ 10011011 00101010 11010111 10001001 10111010 |
|
| Back to top |
|
 |
chp
Joined: 23 Jun 2004 Posts: 313
|
Posted: Fri Apr 28, 2006 7:21 pm Post subject: |
|
|
Just as a little sidenote, the sin/cos can be rewritten to | Code: |
float mysinf(float val)
{
float ret;
__asm__ volatile (
"mtv %1, S000\n"
"vcst.s S002, VFPU_2_PI\n"
"vmul.s S001, S000, S002\n"
"vsin.s S000, S001\n" // or vcos.s
"mfv %0, S000\n"
: "=r"(ret) : "r"(val));
return ret;
} |
and if you use something like vrot.q instead of vsin, you can get sinus and cosinus computed at the same time. Something like this should do it: | Code: |
void vsincosf(float angle, ScePspFVector4* result)
{
__asm__ volatile (
"mtv %1, S000\n"
"vcst.s S001, VFPU_2_PI\n"
"vmul.s S002, S000, S001\n"
"vrot.q C010, S002, [s, c, 0, 0]\n"
"usv.q C010, 0 + %0\n"
: "+m"(*result) : "r"(angle));
} |
_________________ GE Dominator |
|
| Back to top |
|
 |
starman2049
Joined: 19 Sep 2005 Posts: 75
|
Posted: Sat Apr 29, 2006 3:29 am Post subject: |
|
|
| Code: | float myacosf(float val)
{
float ret;
__asm__ volatile (
"mtv %1, S000\n"
"vasin.s S001, S000\n"
"vone.s S002\n"
"vsub.s S000, S002, S001\n"
"vcst.s S002, VFPU_PI_2\n"
"vmul.s S001, S000, S002\n"
"mfv %0, S001\n"
: "=r"(ret) : "r"(val));
return ret;
}
float myasinf(float val)
{
float ret;
__asm__ volatile (
"mtv %1, S000\n"
"vasin.s S001, S000\n"
"vcst.s S002, VFPU_PI_2\n"
"vmul.s S000, S001, S002\n"
"mfv %0, S000\n"
: "=r"(ret) : "r"(val));
return ret;
}
|
|
|
| Back to top |
|
 |
starman2049
Joined: 19 Sep 2005 Posts: 75
|
Posted: Thu May 04, 2006 9:03 am Post subject: |
|
|
Here is an applyMatrix routine. This is about 4 times faster than in software.
| Code: | // NOTE: v0, m0, v1 must be 16 byte aligned!!
// NOTE: this is row-major matrix format
void myApplyMatrix(FVECTOR v0, FMATRIX m0, FVECTOR v1)
{
__asm__ volatile (
"lv.q R000, 0x0(%1)\n"
"lv.q R001, 0x10(%1)\n"
"lv.q R002, 0x20(%1)\n"
"lv.q R003, 0x30(%1)\n"
"lv.q R100, 0x0(%2)\n"
"vdot.q S200, R000, R100\n"
"vdot.q S210, R001, R100\n"
"vdot.q S220, R002, R100\n"
"vdot.q S230, R003, R100\n"
"sv.q R200, 0x0(%0)\n"
: : "r" (v0) , "r" (m0) ,"r" (v1) );
}
|
|
|
| Back to top |
|
 |
starman2049
Joined: 19 Sep 2005 Posts: 75
|
Posted: Thu May 04, 2006 9:44 am Post subject: |
|
|
Here is a Matrix Multiply routine. This is about 10 times faster than in software:
| Code: | // NOTE: m0, m1, m2 must be 16 byte aligned!!
// NOTE: this is row-major matrix format
void myMulMatrix(FMATRIX m2, FMATRIX m0, FMATRIX m1)
{
__asm__ volatile (
"lv.q R000, 0x0(%1)\n"
"lv.q R001, 0x10(%1)\n"
"lv.q R002, 0x20(%1)\n"
"lv.q R003, 0x30(%1)\n"
"lv.q R100, 0x0(%2)\n"
"lv.q R101, 0x10(%2)\n"
"lv.q R102, 0x20(%2)\n"
"lv.q R103, 0x30(%2)\n"
"vmmul.q M200, M000, M100\n"
"sv.q R200, 0x0(%0)\n"
"sv.q R201, 0x10(%0)\n"
"sv.q R202, 0x20(%0)\n"
"sv.q R203, 0x30(%0)\n"
: : "r" (m2) , "r" (m0) ,"r" (m1) );
}
|
|
|
| Back to top |
|
 |
starman2049
Joined: 19 Sep 2005 Posts: 75
|
Posted: Thu May 04, 2006 10:39 am Post subject: |
|
|
Here is a matrix copy routine. This is about 6 times faster than in software:
| Code: | // NOTE: m0, m1 must be 16 byte aligned!!
// NOTE: this is row-major matrix format
void myCopyMatrix(FMATRIX m1, FMATRIX m0)
{
__asm__ volatile (
"lv.q R000, 0x0(%1)\n"
"lv.q R001, 0x10(%1)\n"
"lv.q R002, 0x20(%1)\n"
"lv.q R003, 0x30(%1)\n"
"sv.q R000, 0x0(%0)\n"
"sv.q R001, 0x10(%0)\n"
"sv.q R002, 0x20(%0)\n"
"sv.q R003, 0x30(%0)\n"
: : "r" (m1) , "r" (m0) );
}
|
|
|
| Back to top |
|
 |
Psilocybeing
Joined: 04 May 2006 Posts: 3
|
Posted: Thu May 04, 2006 11:27 am Post subject: |
|
|
| Very nice, sin/cosine functions are used heavily in one of my projects, these will come in very handy. Thanks :) |
|
| Back to top |
|
 |
chp
Joined: 23 Jun 2004 Posts: 313
|
Posted: Thu May 04, 2006 9:47 pm Post subject: |
|
|
| starman2049 wrote: | Here is an applyMatrix routine. This is about 4 times faster than in software.
<snip>
|
You should take a look at vtfm3/4 instead of using vdot, it should execute even faster. Example:
| Code: | void myApplyMatrix(FVECTOR v0, FMATRIX m0, FVECTOR v1)
{
__asm__ volatile (
"lv.q R000, 0x0(%1)\n"
"lv.q R001, 0x10(%1)\n"
"lv.q R002, 0x20(%1)\n"
"lv.q R003, 0x30(%1)\n"
"lv.q R100, 0x0(%2)\n"
"vtfm4.q R200, E000, R100\n"
"sv.q R200, 0x0(%0)\n"
: : "r" (v0) , "r" (m0) ,"r" (v1) );
} |
I do however think most of the time is spent loading the matrix, so you should perhaps change your code to multiply more than one vertex per call (like using it for an array of vertices). The overhead you then would get when you need to multiply just one is minimal compared to the opposite situation. And don't forget that you can let the GE do all this job if you just intend to render it. :) _________________ GE Dominator |
|
| Back to top |
|
 |
starman2049
Joined: 19 Sep 2005 Posts: 75
|
Posted: Thu May 18, 2006 2:05 pm Post subject: |
|
|
Here's a much faster atan2 routine. This isn't in VFPU format (yet), but I thought I would post for now and update later. This is about 10 times faster than the default atan2 routine. PLEAE NOTE: this is a low order approximation and should only be used when you need precision to a few digits. I use this 50 to 100 times per frame in some levels so it was a big boost for me (8 fps!)
Since the VFPU has an asin() in silicon and there is a known identity between atan and asin this could be done other ways, and could be done to higher order.
I'm personally hoping chp has a fancy matrix approach for this one :)
| Code: | float myatan2f(float y, float x)
{
float angle;
float coeff_1 = 3.141592654f/4.0f;
float coeff_2 = 3.0f*coeff_1;
float abs_y = fabs(y) + 0.00000001f; // kludge to prevent 0/0 condition
float r;
if (x >= 0.0f)
{
r = (x - abs_y) / (x + abs_y);
angle = coeff_1 - coeff_1 * r;
}
else
{
r = (x + abs_y) / (abs_y - x);
angle = coeff_2 - coeff_1 * r;
}
if (y < 0.0f)
return(-angle); // negate if in quad III or IV
else
return(angle);
}
|
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|