GCC removes ASM code after return

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

Moderators: cheriff, TyRaNiD

Post Reply
davidgf
Posts: 21
Joined: Mon Aug 31, 2009 10:05 pm

GCC removes ASM code after return

Post by davidgf »

Hi!

I've got a problem with gcc. My code block:

Code: Select all

	__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
WosRet
Posts: 14
Joined: Wed Apr 23, 2008 3:20 am
Location: Confoederatio Helvetica

Post by WosRet »

How about using a simple label in c like:

Code: Select all

...
    return 1;
return_block_:
    return 0;
??
davidgf
Posts: 21
Joined: Mon Aug 31, 2009 10:05 pm

Post by davidgf »

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!
crazyc
Posts: 408
Joined: Fri Jun 17, 2005 10:13 am

Re: GCC removes ASM code after return

Post by crazyc »

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.
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.
jimparis
Posts: 1145
Joined: Fri Jun 10, 2005 4:21 am
Location: Boston

Post by jimparis »

I'd just write the whole function in asm if you need that much control.
davidgf
Posts: 21
Joined: Mon Aug 31, 2009 10:05 pm

Post by davidgf »

Anything is welcome!
But my problem is that Gcc doesn't do well with inline assembly.

Now I have:

Code: Select all

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!!!
jimparis
Posts: 1145
Joined: Fri Jun 10, 2005 4:21 am
Location: Boston

Post by jimparis »

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:
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).
davidgf
Posts: 21
Joined: Mon Aug 31, 2009 10:05 pm

Post by davidgf »

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!
sauron_le_noir
Posts: 203
Joined: Sat Jul 05, 2008 8:03 am

Post by sauron_le_noir »

Have you try to compile with gcc optimization set to -G0 no optimization ?
davidgf
Posts: 21
Joined: Mon Aug 31, 2009 10:05 pm

Post by davidgf »

Already done, but dead code removal seems to apply even with no optimization.
Another think that GCC does is:

Code: Select all

vcmp.s  ...
nop
bvt 0, label
nop
gcc changes the above code to

Code: Select all

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

      64:	4601003c 	c.lt.s	$f0,$f1
      68:	00000000 	nop
      6c&#58;	45010384 	bc1t	e80 <_Z32_gim_....>
Thanks a lot
crazyc
Posts: 408
Joined: Fri Jun 17, 2005 10:13 am

Re: GCC removes ASM code after return

Post by crazyc »

How about this;

Code: Select all

        int i = 1;
        __asm__ volatile &#40;
        ".set push\n"
        ".set noreorder\n"
        "vcmp.s   GT, S000, S200\n"
        "bvtl     0, 1\n"
        "addiu  %0, $0, 0\n"
        ".set pop\n"
        &#58;"=r"&#40;i&#41;&#41;;
        if&#40;!i&#41; return 0;
......
        return 1;
davidgf
Posts: 21
Joined: Mon Aug 31, 2009 10:05 pm

Post by davidgf »

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
Post Reply