Page 1 of 1

Inline Assembly - Return flag - BTR

Posted: Tue Sep 23, 2014 7:23 pm
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);
	}

Re: Inline Assembly - Return flag - BTR

Posted: Tue Sep 23, 2014 10:52 pm
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

Re: Inline Assembly - Return flag - BTR

Posted: Wed Sep 24, 2014 12:51 am
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);
	}

Re: Inline Assembly - Return flag - BTR

Posted: Sun Sep 28, 2014 10:38 am
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

Re: Inline Assembly - Return flag - BTR

Posted: Sun Sep 28, 2014 2:53 pm
by tsdnz
That I did not know, cheers.