2 ms·
> That's beautiful... Why can't GCC and clang have this? There are tricky contingent reasons, like the fact that GCC proper doesn’t try and actually isn’t even
by mananaysiempre 3y ago
> That's beautiful... Why can't GCC and clang have this?
There are tricky contingent reasons, like the fact that GCC proper doesn’t try and actually isn’t even able to parse assembly—and it would need to here in order to know that it can’t put fd in RAX or in any location whose address computation includes RAX.
(GCC’s codegen in general works by stitching together fragments of assembly as text and feeding them into the system assembler. Which is nice and UNIXy and all, but I’m not sure much is won by making the compiler agnostic to the actual bit patterns of the instructions when these days it is still aware of almost every other facet of the instruction set and quite a few microarchitectural details besides.)
But the fact of the matter is that GCC’s approach also permits better optimization, by telling the register allocator exactly which registers are clobbered by the inline assembly snippet and where the computations of the input should aim to place their results. You frequently end up with no MOVs at all, although Clang is better at this part than GCC.
(Do not be fooled into thinking that an automatic "register asm" variable is pinned to the specified register for all of its scope—it’s only guaranteed to be placed there at the start of any inline assembly blocks, the register allocator can move it out of the way in between them.)
I think the x86 code doesn’t actually need the "register asm" syntax at all, FWIW—you should be able to just add "a"(__NR_close), "d"(fd) to the inputs. GCC on RISC archs doesn’t usually define a separate constraint for each individual register, though, so on those it can be necessary.