VFPU asm freezes PSP (asm n00b questions)

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
m2k
Posts: 2
Joined: Wed Feb 15, 2006 9:58 am

VFPU asm freezes PSP (asm n00b questions)

Post by m2k »

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: Select all

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: Select all

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?
chp
Posts: 313
Joined: Wed Jun 23, 2004 7:16 am

Post by chp »

The following code has worked just fine in GUM (although it has been changed now, more on that later...):

Code: Select all

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
m2k
Posts: 2
Joined: Wed Feb 15, 2006 9:58 am

Post by m2k »

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: Select all

// 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 *>&#40;0x44000000&#41;;
static unsigned short *buf = reinterpret_cast<unsigned short *>&#40;0x44000000 + BUF_WIDTH * SCR_HEIGHT * 2&#41;;

PSP_MAIN_THREAD_ATTR&#40;PSP_THREAD_ATTR_VFPU&#41;;
PSP_MODULE_INFO&#40;"16 Bit Color Test", 0, 1, 1&#41;;

inline unsigned short rgba&#40;const unsigned char r, const unsigned char g, const unsigned char b, const unsigned char a&#41; &#123;
  return &#40;a * 0x8000|r << 10|g << 5|b&#41;;
&#125;

int main&#40;&#41; &#123;
  sceDisplaySetFrameBuf&#40;buf, BUF_WIDTH, PSP_DISPLAY_PIXEL_FORMAT_5551, PSP_DISPLAY_SETBUF_IMMEDIATE&#41;;
  sceGuInit&#40;&#41;;
  //pspDebugScreenInit&#40;&#41;;
  SetupCallbacks&#40;&#41;;
  int i = 0;
  sceGuStart&#40;GU_DIRECT,list&#41;;
  sceGuDispBuffer&#40;SCR_WIDTH, SCR_HEIGHT,&#40;void*&#41;&#40;BUF_WIDTH*SCR_HEIGHT*2&#41;,BUF_WIDTH&#41;;
  sceGuDrawBuffer&#40;GU_PSM_5551,NULL,BUF_WIDTH&#41;;
  sceGuOffset&#40;0,0&#41;;
  sceGuViewport&#40;2048, 2048,SCR_WIDTH,SCR_HEIGHT&#41;;
  sceGuFinish&#40;&#41;;
  sceGuSync&#40;0,0&#41;;
  sceDisplayWaitVblankStart&#40;&#41;;
  sceGuDisplay&#40;GU_TRUE&#41;;
	
  for&#40;;;&#41; &#123;
    i++;
    unsigned int p = BUF_WIDTH * SCR_HEIGHT;
    while &#40;p--&#41; &#123;
      float __attribute__&#40;&#40;aligned&#40;64&#41;&#41;&#41; redGradiant = 0.0f;
      const float __attribute__&#40;&#40;aligned&#40;64&#41;&#41;&#41; fac = 0.0625f;
      const float __attribute__&#40;&#40;aligned&#40;64&#41;&#41;&#41; newP = p;
      
      // redGradiant = p * 0.0626 using VFPU &#40; == redGradiant = p << 4 but don't tell anyone &#58;-&#41; &#41;
      __asm__ volatile &#40;
			"lv.s S100, %&#91;p&#93;\n"
			"lv.s S110, %&#91;fac&#93;\n"
			"vmul.s S120, S100, S110\n"
			"sv.s S120, %&#91;redGradiant&#93;\n"
			&#58; &#91;redGradiant&#93; "+m"&#40;redGradiant&#41; &#58; &#91;p&#93; "m"&#40;newP&#41;, &#91;fac&#93; "m"&#40;fac&#41;
			&#41;;
      
      dbuf&#91;p&#93; = rgba&#40;static_cast<const unsigned char>&#40;redGradiant&#41;, 50, i, 1&#41;;
    &#125;
    sceDisplayWaitVblankStart&#40;&#41;;
    dbuf = reinterpret_cast<unsigned short*>&#40;0x44000000 + reinterpret_cast<int>&#40;sceGuSwapBuffers&#40;&#41;&#41;&#41;;
    
    // Press circle + square to quit
    SceCtrlData pad = &#123;0, 0, 0, 0, 0&#125;;
    sceCtrlReadBufferPositive&#40;&pad, 1&#41;;
    if &#40;pad.Buttons & PSP_CTRL_SQUARE && pad.Buttons & PSP_CTRL_CIRCLE&#41; 
      break;

    sceKernelDelayThread&#40;10000&#41;;
    if &#40;i == 31&#41; 
      i = 0;
  &#125;  
  sceGuTerm&#40;&#41;; 
  sceKernelExitGame&#40;&#41;;
  return 0;
&#125;
Now it's time to start messing with matrixes and the VFPU... :-D
chp
Posts: 313
Joined: Wed Jun 23, 2004 7:16 am

Post by chp »

Yep, mfv is its counterpart.
GE Dominator
jsgf
Posts: 254
Joined: Tue Jul 12, 2005 11:02 am
Contact:

Post by jsgf »

Make sure you use pspvfpu.h/libpspvfpu if you want your code to play nicely with other VFPU-using code.
Post Reply