This is acceptable if you see the point of inline assembly in writing long code sections, but that's not what inine assembly is meant to solve. If you want to write long sections of assembly code, just put the whole thing into an assembly source file and link it into your binary.
gcc-style inline assembly on the other hand is designed to solve the problem of augmenting code generation with individual instructions the compiler doesn't know about. Correctly used, gcc-style asm statements typically only hold one or two instructions that are then integrated into a complex function with little to no overhead. And for this usage, the syntax and model provided by gcc is perfectly fine. It only fails if you misuse it for writing long chunks of assembly code, something for which you should have used an assembly file in the first place.
That is why there are function attributes and #pragmas to control what the compiler is supposed to do.
Compilers that don't follow the brainded execution model of UNIX, with hard separation between compiler and Assembler phases, as separate processes comunicating via pipes, are a bit more knowledgeable of what those Assembly instructions are actually doing.
Not only that, they are able to provide proper error messages when the opcodes are badly used.
That's only possible if the compiler knows all assembly instructions being used. But the whole point of GCC-style inline assembly is to be able to use assembly instructions the compiler doesn't know about (for instance, because they're new instructions which didn't exist when the compiler was released), with the same performance as the ones the compiler does know about. In many cases, even the assembler doesn't know about the new instruction, and you have to specify it using .byte directives or similar (though the Unix compiler model, with proper separation between the compiler and the assembler, also allows you to use a newer assembler without having to change your compiler).
If the compiler does know about a specific instruction, then it's better to just provide the intrinsic than try to infer it from some inline asm string.
I admit that it gets very close, however I think compiler provided intrinsics can be and are optimized more than ones that are implemented with inline asm, as the compiler knows about the semantics of the instruction for such an intrinsic, and not much about an inline asm one, apart from inputs/outputs/clobbers.
Having said that I agree that inline asm is very useful for instructions that the compiler does not know about.
Which basically reinvent gcc's syntax to set input/output/modified registers, only worse. No thank you.
The compiler you are most likely thinking off still does not allow to set multiple output values from an inline asm block, for example. Something the gcc/clang syntax has no problems with. These details all make the "ffi"/interface between the C world and your inline asm slower than it could be.
If you want your code to intertwine with what the C compiler does, intrinsics are great.
If you don't, .s is great.
Intrisics give the best of both worlds, without dealing with string based content.
Actually ESPOL/NEWP from 1961 was one of the very first system programming languages with two key inovations, intrisics and unsafe code blocks.
Correct me if I’m wrong, but I don’t think that you can guarantee a routine is constant-time by using intrinsics. You need asm for that. Asm that won’t be changed by the compiler. So you need to write an external asm file for that now, which is fair enough, but I just wouldn’t present intrinsics as all-around superior.
For C, C++, BASIC, Pascal, Delphi, Modula-2, Oberon-2, Component Pascal, D,...
Traditionally PC refers to IBM/Microsoft's linage of computers and operating systems.