forums.ps2dev.org Forum Index forums.ps2dev.org
Homebrew PS2, PSP & PS3 Development Discussions
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Register usage for inline assembly with gcc

 
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development
View previous topic :: View next topic  
Author Message
Fanjita



Joined: 28 Sep 2005
Posts: 217

PostPosted: Fri Sep 30, 2005 6:42 pm    Post subject: Register usage for inline assembly with gcc Reply with quote

One of the main stumbling blocks I found for using the toolchain for 2.0 exploit development was setting up the registers for syscalls.

Initially I was trying

void sceAnyOldFunction(void *parm1, int parm2)
{
asm("syscall 0x2100");
}

as seen in various forums. But this assumes that the parameters are already in registers $a0, $a1 etc. I found out the hard way that that's not true if the compiler optimisation flags are on.

I eventually came up with the workaround of:

asm __volatile__ ("move $4, %0;"
"move $5, %1;"
"syscall 0x2100;"
: // no output regs
: "r" (parm1), "r" (parm2)
: "$4","$5"
);

which does work under optimisation, but is wasteful. I'm sure there's a better way of doing this by using the correct constraint parameters, but all the docs I could find on this were incomprehensible (to me).

Is there anyone with a better working knowledge of gcc, who can explain how this should be done?

Thanks.
Back to top
View user's profile Send private message
holger



Joined: 18 Aug 2005
Posts: 204

PostPosted: Fri Sep 30, 2005 7:19 pm    Post subject: Reply with quote

you can specify in the "r" constraints into which registers the variables should get passed. Read the gcc info pages for details. (if I remember correctly for most architectures things like "r4" and "r5" worked, but not for all... some had different semantics)
Back to top
View user's profile Send private message
groepaz



Joined: 01 Sep 2005
Posts: 305

PostPosted: Sat Oct 01, 2005 1:33 am    Post subject: Reply with quote

http://hitmen.c02.at/files/docs/gcc_mixing_asm_and_c.txt

look at this text....its originally for arm assembly, but the principles stay the same
_________________
http://www.hitmen-console.org
http://hitmen.c02.at/files/yapspd/
Back to top
View user's profile Send private message Visit poster's website
Fanjita



Joined: 28 Sep 2005
Posts: 217

PostPosted: Mon Oct 03, 2005 5:08 am    Post subject: Reply with quote

Groepaz - unfortunately I'm not sure yoru code helps - it still allows GCC to allocate to its choice of registers.

Holger - thanks for your tip, I'll try that to see if it helps for the PSP.


I found lots of info on this for x86-architectures, but nothing much that helped apply it to the PSP. Looks like r4, r5 etc. is promising though.
Back to top
View user's profile Send private message
holger



Joined: 18 Aug 2005
Posts: 204

PostPosted: Mon Oct 03, 2005 5:26 am    Post subject: Reply with quote

try something like this:

Code:

void func (void *arg)
{
        register void *ptr __asm__ ("a0") = arg;
        __asm__ volatile ("/*asm code here*/": "=r"(ptr) : "r"(ptr) : "memory");
}

Back to top
View user's profile Send private message
Fanjita



Joined: 28 Sep 2005
Posts: 217

PostPosted: Mon Oct 03, 2005 7:04 am    Post subject: Reply with quote

Heh, that's exactly what I've been trying since posting (since there are no explicit names for the registers in the MIPS-variant asm constraints).

This variant seems to work, and generate the right opcodes:

int sceCtrlReadBufferPositive(SceCtrlData *pad_data, int count)
{
register SceCtrlData * lpaddata asm("$4") = pad_data;
register SceCtrlData * lcount asm("$5") = count;
asm __volatile__ (
"syscall 0x215b;"
: // no output regs
: "r" (lpaddata), "r" (lcount)
);
}


Just a shame that the 'register' modifier can't be used against the function parameters directly, i.e.

int sceBlah(register int param asm("$4"))
{
}

because that would be much neater. :)
Back to top
View user's profile Send private message
mrbrown



Joined: 17 Jan 2004
Posts: 1536

PostPosted: Mon Oct 03, 2005 10:17 am    Post subject: Reply with quote

Um, your arguments are already in the correct registers for the syscall. What are you trying to do exactly?
Back to top
View user's profile Send private message
Fanjita



Joined: 28 Sep 2005
Posts: 217

PostPosted: Mon Oct 03, 2005 10:52 am    Post subject: Reply with quote

The point is that the arguments aren't guaranteed to be in the right registers, unless appropriate constraints are supplied.

The classic

void func(int foo)
{
asm ("syscall bar")
}

format works OK if optimisation is turned off, but with optimisation gcc tends to inline the functions, and not bother setting up the registers.

The constraints given force the use of the correct registers, and don't appear to cause the generation of any surplus opcodes - which was my end goal, even though it looks pretty ugly.
Back to top
View user's profile Send private message
Jim



Joined: 02 Jul 2005
Posts: 487
Location: Sydney

PostPosted: Mon Oct 03, 2005 11:39 am    Post subject: Reply with quote

A few possibilities:

Compile with -fno-inline.
Maybe __declspec(noinline) works with C too.
Put the syscall functions in a different C file.

Jim
_________________
http://www.dbfinteractive.com
Back to top
View user's profile Send private message Visit poster's website
Fanjita



Joined: 28 Sep 2005
Posts: 217

PostPosted: Mon Oct 03, 2005 7:41 pm    Post subject: Reply with quote

The thing is, I don't mind letting the compiler inline the functions, so long as it gets the registers right. Letting it optimise my code (so long as it can do it safely) seems like A Good Thing(tm).

As I said, declaring register local variables seems to be the way to do it - it works, it's safe, it results in tight code, it just doesn't look nice (but I don't really care about that).
Back to top
View user's profile Send private message
holger



Joined: 18 Aug 2005
Posts: 204

PostPosted: Mon Oct 03, 2005 7:43 pm    Post subject: Reply with quote

isn't the "asm volatile" tag enough to tell gcc that it should not optimize away that section?
Back to top
View user's profile Send private message
Jim



Joined: 02 Jul 2005
Posts: 487
Location: Sydney

PostPosted: Mon Oct 03, 2005 9:44 pm    Post subject: Reply with quote

Quote:
The thing is, I don't mind letting the compiler inline the functions, so long as it gets the registers right

Are you sure you need to optimise down to this level?
Every syscall is cycle critical?

I think you need to reconsider your priorities!

Jim
_________________
http://www.dbfinteractive.com
Back to top
View user's profile Send private message Visit poster's website
holger



Joined: 18 Aug 2005
Posts: 204

PostPosted: Mon Oct 03, 2005 10:14 pm    Post subject: Reply with quote

function inlining is enabled by default for -O2.
Back to top
View user's profile Send private message
mrbrown



Joined: 17 Jan 2004
Posts: 1536

PostPosted: Tue Oct 04, 2005 3:54 am    Post subject: Reply with quote

Jim wrote:
Maybe __declspec(noinline) works with C too.

__declspec? MSVC now are we? :P

Try __attribute__(noinline) instead :).
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development All times are GMT + 10 Hours
Page 1 of 1

 
Jump to:  
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