Err, to save you guys a bunch of debug time, be aware that PSPlink causes random bugs when trying to print a float.
The bug results in PSPlink crashing.
Usbhostfs reports an invalid magic error.
The bug is caused by TyRaNid attempting to find the address of a function argument... although, the PSP uses registers to store/pass arguments, hence the bug.
The bug is in the float printing code of PSPlink, hence avoid printing floats in PSPlink.
And never try to get the address of a function argument!
Bug awareness - finding the address of arguments is a NoNo
Could you be more specific where that code is that tries to find the adress of an argument/print floats, that is faulty?
Can't seem to find that part.
Can't seem to find that part.
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki
Alexander Berl
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki
Alexander Berl
Re: Bug awareness - finding the address of arguments is a No
Erm, why exactly... GCC will automatically store the register on the stack and give that address if you try to get the address of a function argument. The following output is from ee-gcc, but should be similar on PSP compiler...SANiK wrote:And never try to get the address of a function argument!
Original C code:
Code: Select all
void somefunc(int blah)
{
someotherfunc(&blah);
}
Code: Select all
00000020 <somefunc>:
20: addiu sp,sp,-48
24: sd ra,32(sp)
28: sd s8,16(sp)
2c: move s8,sp
30: sw a0,0(s8) ; value of "blah" is stored on the stack
34: jal 0 <someotherfunc>
38: move a0,s8 ; arg0 for someotherfunc is set to the address of "blah" on the stack
3c: move sp,s8
40: ld ra,32(sp)
44: ld s8,16(sp)
48: jr ra
4c: addiu sp,sp,48
jbit - The PSPcompiler has its issues =/
chp/Raphael - The bug is in the PSPLink code which handles the conversion of floats to string, and not within the function printf() itself
/*Taken from util.c*/
chp/Raphael - The bug is in the PSPLink code which handles the conversion of floats to string, and not within the function printf() itself
/*Taken from util.c*/
Code: Select all
static int is_inf(float val)
{
void *p;
unsigned int conv;
int sign;
int exp;
int mantissa;
BUG: p = (void *) &val;
conv = *((unsigned int *) p);
sign = (conv >> 31) & 1;
exp = (conv >> 23) & 0xff;
mantissa = conv & 0x7fffff;
if((exp == 255) && (mantissa == 0))
{
if(sign)
{
return -1;
}
else
{
return 1;
}
}
return 0;
}
Code: Select all
static int is_inf(float val)
{
void *p;
unsigned int conv;
int sign;
int exp;
int mantissa;
p = (void *) &val;
conv = *((unsigned int *) p);
sign = (conv >> 31) & 1;
exp = (conv >> 23) & 0xff;
mantissa = conv & 0x7fffff;
if((exp == 255) && (mantissa == 0))
{
if(sign)
{
return -1;
}
else
{
return 1;
}
}
return 0;
}
int main(int argc, char *argv[])
{
float x = rand()/32768.f;
if (is_inf(x))
{
printf("IsINF\n");
}
sceKernelExitGame();
return(0);
}
Code: Select all
$LC1:
.ascii "IsINF\012\000"
#NO_APP
.section .rodata.cst4,"aM",@progbits,4
.align 2
$LC0:
.word 939524096
.text
.align 2
.globl main
.ent main
main:
.frame $sp,16,$31 # vars= 8, regs= 1/0, args= 0, gp= 0
.mask 0x80000000,-8
.fmask 0x00000000,0
.set noreorder
.set nomacro
addiu $sp,$sp,-16
sw $31,8($sp)
jal rand
nop
mtc1 $2,$f0
lui $2,%hi($LC0)
cvt.s.w $f1,$f0
lwc1 $f0,%lo($LC0)($2)
lw $3,0($sp) # !WRONG
li $2,8323072 # 0x7f0000
mul.s $f1,$f1,$f0
ori $2,$2,0xffff
and $5,$3,$2
ext $3,$3,23,8
li $2,255 # 0xff
bne $3,$2,$L2
swc1 $f1,0($sp) # !WRONG
lui $4,%hi($LC1)
bne $5,$0,$L2
addiu $4,$4,%lo($LC1)
jal printf
nop
$L2:
jal sceKernelExitGame
nop
lw $31,8($sp)
move $2,$0
j $31
addiu $sp,$sp,16
Funnily enough, with -O1 it puts them in correct order, but not with any optimization value.
Correct result is given with this code in any case though:
Code: Select all
static int is_inf(float val)
{
unsigned int conv;
int sign;
int exp;
int mantissa;
asm("mfc1 %0, %1\n":"=r"(conv):"f"(val));
sign = (conv >> 31) & 1;
exp = (conv >> 23) & 0xff;
mantissa = conv & 0x7fffff;
if((exp == 255) && (mantissa == 0))
{
if(sign)
{
return -1;
}
else
{
return 1;
}
}
return 0;
}
Code: Select all
Index: psplink/util.c
===================================================================
--- psplink/util.c (revision 2280)
+++ psplink/util.c (working copy)
@@ -860,14 +860,16 @@
static int is_nan(float val)
{
- void *p;
+ //void *p;
unsigned int conv;
int sign;
int exp;
int mantissa;
- p = (void *) &val;
- conv = *((unsigned int *) p);
+ /*p = (void *) &val;
+ conv = *((unsigned int *) p);*/
+ // Help stupid GCC compiler
+ asm("mfc1 %0, %1\n":"=r"(conv):"f"(val));
sign = (conv >> 31) & 1;
exp = (conv >> 23) & 0xff;
@@ -883,14 +885,16 @@
static int is_inf(float val)
{
- void *p;
+ //void *p;
unsigned int conv;
int sign;
int exp;
int mantissa;
- p = (void *) &val;
- conv = *((unsigned int *) p);
+ /*p = (void *) &val;
+ conv = *((unsigned int *) p);*/
+ // Help stupid GCC compiler
+ asm("mfc1 %0, %1\n":"=r"(conv):"f"(val));
sign = (conv >> 31) & 1;
exp = (conv >> 23) & 0xff;
Index: pspsh/disasm.C
===================================================================
--- pspsh/disasm.C (revision 2280)
+++ pspsh/disasm.C (working copy)
@@ -1149,7 +1149,7 @@
// [hlide] added pfx_sat_names
static const char * const pfx_sat_names[4] =
{
- "", "[0:1]", "", "[-1:1]"
+ "", "0:1", "", "-1:1"
};
/* VFPU prefix instruction operands. The *_SH_* values really specify where
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki
Alexander Berl
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki
Alexander Berl