 |
forums.ps2dev.org Homebrew PS2, PSP & PS3 Development Discussions
|
| View previous topic :: View next topic |
| Author |
Message |
m2k
Joined: 15 Feb 2006 Posts: 2
|
Posted: Wed Feb 15, 2006 7:53 pm Post subject: VFPU asm freezes PSP (asm n00b questions) |
|
|
Hi, I just started playing with some PSP development and realized I want to use the VFPU to create some functions to optimize some floating point division etc.
OK, I am no asm expert, all I've ever done before is some minimal arm/thumb and pic chip asm, and I've never used asm inside of C... anyway...
I try to load a float value into register S002 (all the VFPU registers only do floats I believe?). I am not sure what the "r" constraint means in this context, but from the gcc documentation it seems that the %0 operand will be put in any general register... so the code below means something like
load the float at offset 0 of the memory address stored in some register = indirect addressing ..into register S002
gcc will put &x into some register before executing, am I right?
| Code: |
float x = 3.14;
asm volatile (
"lv.s S002, 0(%0)\n" : : "r"(&x)
);
|
The code above just makes my PSP freeze though. I would think...
| Code: |
asm volatile (
"lv.s S002, %0\n" : : "m"(&x)
);
|
...would work aswell, but it doesn't even compile. Using "m"(x) as operand compiles, but freezes just like the first example. Does the "m" constraint mean that the compiler takes the address of x automativally without me having to use the & operator? |
|
| Back to top |
|
 |
chp
Joined: 23 Jun 2004 Posts: 313
|
Posted: Thu Feb 16, 2006 2:04 am Post subject: |
|
|
The following code has worked just fine in GUM (although it has been changed now, more on that later...):
| Code: | float angle = X;
__asm__ volatile {
"lv.s S100, 0(%0)\n"
} : : "r"(&angle));
|
And this doesn't crash. Are you setting the THREAD_ATTR_VFPU flag? Without it, the PSP will surely die.
As a sidenote, you can use 'mtv' instead of 'lv.s', which moves between mips register -> vfpu register. This would allow you to bypass memory storage and possible dcache stalls. _________________ GE Dominator |
|
| Back to top |
|
 |
m2k
Joined: 15 Feb 2006 Posts: 2
|
Posted: Thu Feb 16, 2006 9:43 am Post subject: |
|
|
Hey thanks man! That did the trick! Didn't know about the THREAD_ATTR_VFPU before :-) did the following quick example which seems to use the VFPU successfully...
By the way, has mtv got an oppocite? mfv?
| Code: |
// Draw some gradient colors on a 16 bit screen...
// standard PSPSDK callback/thread stuff ommited
static unsigned int __attribute__((aligned(16))) list[262144];
static unsigned short *dbuf = reinterpret_cast<unsigned short *>(0x44000000);
static unsigned short *buf = reinterpret_cast<unsigned short *>(0x44000000 + BUF_WIDTH * SCR_HEIGHT * 2);
PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_VFPU);
PSP_MODULE_INFO("16 Bit Color Test", 0, 1, 1);
inline unsigned short rgba(const unsigned char r, const unsigned char g, const unsigned char b, const unsigned char a) {
return (a * 0x8000|r << 10|g << 5|b);
}
int main() {
sceDisplaySetFrameBuf(buf, BUF_WIDTH, PSP_DISPLAY_PIXEL_FORMAT_5551, PSP_DISPLAY_SETBUF_IMMEDIATE);
sceGuInit();
//pspDebugScreenInit();
SetupCallbacks();
int i = 0;
sceGuStart(GU_DIRECT,list);
sceGuDispBuffer(SCR_WIDTH, SCR_HEIGHT,(void*)(BUF_WIDTH*SCR_HEIGHT*2),BUF_WIDTH);
sceGuDrawBuffer(GU_PSM_5551,NULL,BUF_WIDTH);
sceGuOffset(0,0);
sceGuViewport(2048, 2048,SCR_WIDTH,SCR_HEIGHT);
sceGuFinish();
sceGuSync(0,0);
sceDisplayWaitVblankStart();
sceGuDisplay(GU_TRUE);
for(;;) {
i++;
unsigned int p = BUF_WIDTH * SCR_HEIGHT;
while (p--) {
float __attribute__((aligned(64))) redGradiant = 0.0f;
const float __attribute__((aligned(64))) fac = 0.0625f;
const float __attribute__((aligned(64))) newP = p;
// redGradiant = p * 0.0626 using VFPU ( == redGradiant = p << 4 but don't tell anyone :-) )
__asm__ volatile (
"lv.s S100, %[p]\n"
"lv.s S110, %[fac]\n"
"vmul.s S120, S100, S110\n"
"sv.s S120, %[redGradiant]\n"
: [redGradiant] "+m"(redGradiant) : [p] "m"(newP), [fac] "m"(fac)
);
dbuf[p] = rgba(static_cast<const unsigned char>(redGradiant), 50, i, 1);
}
sceDisplayWaitVblankStart();
dbuf = reinterpret_cast<unsigned short*>(0x44000000 + reinterpret_cast<int>(sceGuSwapBuffers()));
// Press circle + square to quit
SceCtrlData pad = {0, 0, 0, 0, 0};
sceCtrlReadBufferPositive(&pad, 1);
if (pad.Buttons & PSP_CTRL_SQUARE && pad.Buttons & PSP_CTRL_CIRCLE)
break;
sceKernelDelayThread(10000);
if (i == 31)
i = 0;
}
sceGuTerm();
sceKernelExitGame();
return 0;
}
|
Now it's time to start messing with matrixes and the VFPU... :-D |
|
| Back to top |
|
 |
chp
Joined: 23 Jun 2004 Posts: 313
|
Posted: Thu Feb 16, 2006 6:38 pm Post subject: |
|
|
Yep, mfv is its counterpart. _________________ GE Dominator |
|
| Back to top |
|
 |
jsgf
Joined: 12 Jul 2005 Posts: 254
|
Posted: Mon Feb 20, 2006 11:31 am Post subject: |
|
|
| Make sure you use pspvfpu.h/libpspvfpu if you want your code to play nicely with other VFPU-using code. |
|
| 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
|