| View previous topic :: View next topic |
| Author |
Message |
davidgf
Joined: 31 Aug 2009 Posts: 22
|
Posted: Sun Jan 31, 2010 12:28 am Post subject: GCC removes ASM code after return |
|
|
Hi!
I've got a problem with gcc. My code block:
| Code: |
__asm__ volatile (
"vcmp.s GT, S000, S200\n"
"bvt 0, return_block_\n"
"nop\n"
);
......
return 1;
__asm__ __volatile__ ("return_block_:\n");
return 0;
}
|
GCC complains about undefined label. I thought it was it cannot access the label, but the fact is that GCC removes everything after a return sentence.
Speed is critical here, so I don't want to use a variable and a branch if possible.
Thanks in advance!
David |
|
| Back to top |
|
 |
WosRet
Joined: 23 Apr 2008 Posts: 15 Location: Confoederatio Helveticae
|
Posted: Sun Jan 31, 2010 12:38 am Post subject: |
|
|
How about using a simple label in c like:
| Code: | ...
return 1;
return_block_:
return 0;
|
?? |
|
| Back to top |
|
 |
davidgf
Joined: 31 Aug 2009 Posts: 22
|
Posted: Sun Jan 31, 2010 12:41 am Post subject: |
|
|
It removes too!
The problem are not the labels. The problems is that gcc removes absolutely everything after a return instruction, as it assumes I can't jump over a return.
It doesn't understand that the instruction bvt is a jump instruction! |
|
| Back to top |
|
 |
crazyc
Joined: 17 Jun 2005 Posts: 410
|
Posted: Sun Jan 31, 2010 1:34 am Post subject: Re: GCC removes ASM code after return |
|
|
| davidgf wrote: |
GCC complains about undefined label. I thought it was it cannot access the label, but the fact is that GCC removes everything after a return sentence.
Speed is critical here, so I don't want to use a variable and a branch if possible.
| Just use a variable. Higher compiler optimization levels will probably hold the variable in a register anyway.
| Quote: | | It doesn't understand that the instruction bvt is a jump instruction! | Of course it doesn't. You can't expect the compiler to analyze your inline asm. |
|
| Back to top |
|
 |
jimparis
Joined: 10 Jun 2005 Posts: 1179 Location: Boston
|
Posted: Sun Jan 31, 2010 1:58 am Post subject: |
|
|
| I'd just write the whole function in asm if you need that much control. |
|
| Back to top |
|
 |
davidgf
Joined: 31 Aug 2009 Posts: 22
|
Posted: Sun Jan 31, 2010 5:54 am Post subject: |
|
|
Anything is welcome!
But my problem is that Gcc doesn't do well with inline assembly.
Now I have:
| Code: |
int returnvalue = 0;
asm code....
bvt 0, exit_block_
c code...
returnvalue = 1;
exit_block_:
return returnvalue;
|
This should work, as it returns a zero when jumping with the assembly code and reutrn 1 when exiting normal C code, but it generates a branch followed by a delay branch slot with li v0, 0x1
Gcc works very bad!!! |
|
| Back to top |
|
 |
jimparis
Joined: 10 Jun 2005 Posts: 1179 Location: Boston
|
Posted: Sun Jan 31, 2010 7:21 am Post subject: |
|
|
GCC does just fine with inline assembly. What you are trying to do is wrong and will not work. Read the GCC manual, which pretty clearly says: | Quote: | | Speaking of labels, jumps from one asm to another are not supported. | Similarly you cannot jump to C labels. In gcc 4.5 you can, as long as you list them expliticly after the clobber list and follow the other restrictions: (see here). |
|
| Back to top |
|
 |
davidgf
Joined: 31 Aug 2009 Posts: 22
|
Posted: Sun Jan 31, 2010 8:01 am Post subject: |
|
|
I didn't know that, none of my assembler teachers told me.
The fact is that inline assembly is weird, it could be better to use pure assembly functions.
Where can I find Gcc calling conventions for PSP MIPS? And how can I know the offset of each struct element? Because gcc optimizations can pack or align data as the compiler wants.
Thanks again! |
|
| Back to top |
|
 |
sauron_le_noir
Joined: 05 Jul 2008 Posts: 229
|
Posted: Sun Jan 31, 2010 8:52 am Post subject: |
|
|
| Have you try to compile with gcc optimization set to -G0 no optimization ? |
|
| Back to top |
|
 |
davidgf
Joined: 31 Aug 2009 Posts: 22
|
Posted: Sun Jan 31, 2010 9:39 am Post subject: |
|
|
Already done, but dead code removal seems to apply even with no optimization.
Another think that GCC does is:
| Code: |
vcmp.s ...
nop
bvt 0, label
nop
|
gcc changes the above code to
| Code: |
vcmp.s ...
bvt 0, label
nop
nop
|
This is weird, isn't it? And is it necesary to add nop before a vcmp or i can compare and branch immediatly? gcc generated code on floating point processors adds nops after comparisions:
| Code: |
64: 4601003c c.lt.s $f0,$f1
68: 00000000 nop
6c: 45010384 bc1t e80 <_Z32_gim_....>
|
Thanks a lot |
|
| Back to top |
|
 |
crazyc
Joined: 17 Jun 2005 Posts: 410
|
Posted: Sun Jan 31, 2010 11:41 am Post subject: Re: GCC removes ASM code after return |
|
|
How about this;
| Code: |
int i = 1;
__asm__ volatile (
".set push\n"
".set noreorder\n"
"vcmp.s GT, S000, S200\n"
"bvtl 0, 1\n"
"addiu %0, $0, 0\n"
".set pop\n"
:"=r"(i));
if(!i) return 0;
......
return 1;
|
|
|
| Back to top |
|
 |
davidgf
Joined: 31 Aug 2009 Posts: 22
|
Posted: Mon Feb 01, 2010 11:01 pm Post subject: |
|
|
I'll try the noreorder later, but I don't know for sure if I need to place nops after comparisions.
I don't get at all what push and pop statements do, but anyway I'll give a try.
The label problem I solved this way. My code has a lot of C comparisions with early out:
if (dist> radius) return 0;
I the last jump I changed the C code to this
if (bla bal ) {
exit_label: return 0;
} else {
bla bla
return 1;
}
so I can do
bvt 0, exit_label
There's no way the code exits function without returning anything, but this way gcc does'nt remove anything from my code and I can jump.
I'll post the conclusions so it might help someone.
Thanks for all!
David |
|
| Back to top |
|
 |
|