Inline Assembly - Return flag - BTR

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
tsdnz
Member
Member
Posts: 333
Joined: Sun Jun 16, 2013 4:09 am

Inline Assembly - Return flag - BTR

Post by tsdnz »

Hi all, Going through the optimized assembly and have found something I need help with.
I would like to return a flag using inline assembly.

Here is the inline code:

Code: Select all

FIL bool Lock_BTR(QWORD* variable, BYTE Bit)
{
	bool r;

	QWORD b = Bit;

	asm volatile("lock btrq %1, %2; setc %0;"
		: "=g" (r)                      //Output
		: "Ir" (b), "m" (*variable)     //Input
		:"cc");

	return r;
}
This produces:

Code: Select all

  31e7ce:	f0 4d 0f b3 10       	lock btr QWORD PTR [r8],r10
  31e7d3:	41 0f 92 c3          	setb   r11b
  31e7d7:	45 84 db             	test   r11b,r11b
  31e7da:	75 44                	jne    31e820 <_ZN6System4tHub11_ProcessCPUEv+0xb0>
Is there anyway to remove the setc (setb in asm) and the test?
I know I put the setc in the inline, but is there anyway to have it return the value without using setc so the compiler can remove a couple of instructions?

I would like a simple lock btr and then jb or jc...

For complete-ness, here is the c+ call
EDIT: New Code in function.

Code: Select all

FIL bool tCPU::EthernetCardAction()
	{
		if (APICID < 64)
			return Lock_BTR(&ABIT.Ethernet->EthernetCardAction0, APICID);

		if (APICID < 128)
			return Lock_BTR(&ABIT.Ethernet->EthernetCardAction0, APICID - 64);

		if (APICID < 192)
			return Lock_BTR(&ABIT.Ethernet->EthernetCardAction0, APICID - 128);

		return Lock_BTR(&ABIT.Ethernet->EthernetCardAction0, APICID - 192);
	}
jbemmel
Member
Member
Posts: 53
Joined: Fri May 11, 2012 11:54 am

Re: Inline Assembly - Return flag - BTR

Post by jbemmel »

[ skipping all the usual comments about preliminary optimizations ]

You can use 'asm goto' in GCC, and pass a label to branch based on the result of arbitrary instructions.
See https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html

There is currently no way to return bits in flag registers as function call results, all return values must reside in (specific) registers following the calling conventions of the architecture / platform
tsdnz
Member
Member
Posts: 333
Joined: Sun Jun 16, 2013 4:09 am

Re: Inline Assembly - Return flag - BTR

Post by tsdnz »

Thanks, just what I was thinking.

I changed the code slightly, the optimistations are better now:

Code: Select all

FIL bool Lock_BTR(QWORD* variable, QWORD Bit)
{
	bool r;

	asm volatile("lock btrq %1, %2; setc %0;"
		: "=g" (r)                      //Output
		: "r" (Bit), "m" (*variable)     //Input
		:"cc");

	return r;
}

Code: Select all

	FIL bool tCPU::EthernetCardAction()
	{
		BYTE Action = (BYTE)APICID;

		if (Action < 64)
			return Lock_BTR(&ABIT.Ethernet->EthernetCardAction0, Action);

		if (Action < 128)
			return Lock_BTR(&ABIT.Ethernet->EthernetCardAction1, Action - 64);

		if (Action < 192)
			return Lock_BTR(&ABIT.Ethernet->EthernetCardAction2, Action - 128);

		return Lock_BTR(&ABIT.Ethernet->EthernetCardAction3, Action - 192);
	}
jbemmel
Member
Member
Posts: 53
Joined: Fri May 11, 2012 11:54 am

Re: Inline Assembly - Return flag - BTR

Post by jbemmel »

BTR can actually set arbitrary bits at offsets -2^31 to +2^31, see http://x86.renejeschke.de/html/file_mod ... id_24.html

It is not necessary to split out qwords
tsdnz
Member
Member
Posts: 333
Joined: Sun Jun 16, 2013 4:09 am

Re: Inline Assembly - Return flag - BTR

Post by tsdnz »

That I did not know, cheers.
Post Reply