www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.ldc - Question about inline assembly in LDC

reply Cecil Ward <cecil cecilward.com> writes:
When I try a certain snippet of D containing GCC-style inline x86 
asm in LDC, it fails at compile-time with an error message. The 
code works fine in GDC though. Can anyone help me understand 
what’s going wrong.

the error message is:
      source>(231):2:15: error: unknown token in expression
         prefetcht0  [%rdi]

Note the % before the rdi, which shouldn’t be there and isn’t 
when I build under GDC.

The whole thing is:

void prefetcht0( in void * p )  nogc nothrow  trusted
/* (temporal data)—prefetch data into all levels of the cache 
hierarchy.
*/	{
	asm nothrow  nogc {
		".intel_syntax"               ~ "\n\t" ~
		
	        "prefetcht0  [%0]"          ~ "\n\t" ~
		
	        ".att_syntax"                 ~ "\n"
	        : /* no outputs */
	        :  "r" ( p )
	        :
		;
	        }
	}
Aug 21 2023
parent reply kinke <noone nowhere.com> writes:
LDC doesn't support the Intel syntax in GDC-style inline asm, 
AT&T only. [We'd have to tell LLVM that an *entire* GDC-style 
inline asm statement is in Intel syntax.]

The Intel syntax is only supported in DMD-style inline asm.
Aug 21 2023
next sibling parent Cecil Ward <cecil cecilward.com> writes:
On Monday, 21 August 2023 at 16:38:29 UTC, kinke wrote:
 LDC doesn't support the Intel syntax in GDC-style inline asm, 
 AT&T only. [We'd have to tell LLVM that an *entire* GDC-style 
 inline asm statement is in Intel syntax.]

 The Intel syntax is only supported in DMD-style inline asm.
Ah, shame. It would be good if LDC gave an error message when it sees the intel syntax directive, as its error messages in this situation seem to be a bit random now.
Aug 21 2023
prev sibling parent reply Cecil Ward <cecil cecilward.com> writes:
On Monday, 21 August 2023 at 16:38:29 UTC, kinke wrote:
 LDC doesn't support the Intel syntax in GDC-style inline asm, 
 AT&T only. [We'd have to tell LLVM that an *entire* GDC-style 
 inline asm statement is in Intel syntax.]

 The Intel syntax is only supported in DMD-style inline asm.
Does that mean that in principle LDC could understand intel-style syntax but only if it knew in advance which type of syntax was being used in the _whole_ thing, ie as opposed to being told too late by a .intel_syntax directive? To get interoperability between GDC and LDC then perhaps the two compilers could have an external ‘dialect’ parameter that is available before we get into the statements-body. Failing that, LDC would need to look ahead for the likes of a .intel_syntax directive with an auto detect-type initial regex. Seeing as presumably no one ever switches dialects other than at the start, then that would certainly work well. I’m very good at proposing work for others. :-)
Aug 21 2023
parent reply kinke <noone nowhere.com> writes:
On Monday, 21 August 2023 at 23:18:50 UTC, Cecil Ward wrote:
 Does that mean that in principle LDC could understand 
 intel-style syntax but only if it knew in advance which type of 
 syntax was being used in the _whole_ thing, ie as opposed to 
 being told too late by a .intel_syntax directive? To get 
 interoperability between GDC and LDC then perhaps the two 
 compilers could have an external ‘dialect’ parameter that is 
 available before we get into the statements-body. Failing that, 
 LDC would need to look ahead for the likes of a .intel_syntax 
 directive with an auto detect-type initial regex. Seeing as 
 presumably no one ever switches dialects other than at the 
 start, then that would certainly work well. I’m very good at 
 proposing work for others. :-)
Heh :D - sure, could be done, but don't count on me. AFAIK, 2 different asm dialects only exist for x86[_64], one of many targets, so adding support for such an inherited legacy mess is not on my TODO list. And by the looks of it, you're an asm afficionado, but I don't recommend working at such a low level (in D) unless it can't be done otherwise (very few cases, druntime has some examples). Some reasons: readability, portability, poor compiler support for troubleshooting as you've seen (asm fragments are mostly a black box, for both LDC and the main LLVM passes), and premature optimization (asm fragments are a black box for the LLVM optimization passes, so using intrinsics and inline IR is much better, not just for portability to different archs, but also to let the optimizer know what you're doing).
Aug 22 2023
parent Cecil Ward <cecil cecilward.com> writes:
On Tuesday, 22 August 2023 at 12:24:41 UTC, kinke wrote:
 On Monday, 21 August 2023 at 23:18:50 UTC, Cecil Ward wrote:
 Does that mean that in principle LDC could understand 
 intel-style syntax but only if it knew in advance which type 
 of syntax was being used in the _whole_ thing, ie as opposed 
 to being told too late by a .intel_syntax directive? To get 
 interoperability between GDC and LDC then perhaps the two 
 compilers could have an external ‘dialect’ parameter that is 
 available before we get into the statements-body. Failing 
 that, LDC would need to look ahead for the likes of a 
 .intel_syntax directive with an auto detect-type initial 
 regex. Seeing as presumably no one ever switches dialects 
 other than at the start, then that would certainly work well. 
 I’m very good at proposing work for others. :-)
Heh :D - sure, could be done, but don't count on me. AFAIK, 2 different asm dialects only exist for x86[_64], one of many targets, so adding support for such an inherited legacy mess is not on my TODO list. And by the looks of it, you're an asm afficionado, but I don't recommend working at such a low level (in D) unless it can't be done otherwise (very few cases, druntime has some examples). Some reasons: readability, portability, poor compiler support for troubleshooting as you've seen (asm fragments are mostly a black box, for both LDC and the main LLVM passes), and premature optimization (asm fragments are a black box for the LLVM optimization passes, so using intrinsics and inline IR is much better, not just for portability to different archs, but also to let the optimizer know what you're doing).
I’m aware of the disadvantages. I would never recommend using inline asm unless it’s either essential or it gives otherwise unachievable performance benefits. I’m writing library functions to make available instructions that you cannot access without wrappers. I would never recommend using inline asm unless it’s either essential or it gives otherwise unachievable performance benefits. I’m writing libIt’s also a D learning project for me. I was a very experienced professional asm programmer, a long long time ago, before compilers became way too good. The GDC/LDC implementation is so fantastically efficient, unlike the DMD inline asm, that you can get literally zero-overhead asm fully integrated into your code. It can even adapt an instruction’s operands to handle memory accesses directly without needing to make use of a register as an intermediate location where applicable. LDC and GDC generate code with fs:addr operands when the argument is a static in thread-local-storage. To me that’s amazing sophistication from the compilers. In my little project, I give pure D equivalents when I have not been able to offer instructions for whatever the CPU is. The prefetch case is one perfect example. Only experts should use such a thing and then D cannot achieve the benefits on offer without the CPU’s special instructions. Also using it and getting the placement and usage wrong will certainly make performance worse, so measurement before and after is needed to check that you’re doing it right. And even then, changes to the code can mess things up; the performance benefits are very fragile. I do wish that D could handle Intel syntax as the ATT stuff hurts my brain after years of doing things the standard way for that processor. Is ARM code going to have the operands backwards way round? (Actually I think the ATT order is preferable as it reads better, but it’s down to what you have spent years doing and down to having to read the CPUs’ documentation in a different syntax.) I recently wrote something to fix the problem of LDC not being able to handle named asm arguments. I was trying to avoid conditional compilation and duplicated code form GDC and LDC, but now I find that’s only one problem in the way of success, the ATT-only thing being much worse. Does GCC for C handle Intel syntax inline asm?
Aug 22 2023