Hacker News new | ask | show | jobs
by bazizbaziz 3700 days ago
Kinda seems like the compiler just shouldn't allocate r0 for inline assembly on PPC, since it's only valid in special circumstances. Hard to fault the ISA a lot since this is basically the compiler backend author(s) missing a corner case, which is quite easy to do considering the breadth of a compiler backend.
1 comments

Yeah, that's not about the ISA, that's just Evidence That GCC's Inline ASM Functionality is a Mess #938292721

See also: http://free-electrons.com/blog/how-we-found-that-the-linux-n...

See also: http://robertoconcerto.blogspot.ca/2013/03/my-hardest-bug.ht...

Alternately it could be seen as evidence that PowerPC assembly syntax is a mess. For anyone who doesn't know, the way it works with typical PowerPC assemblers is that instructions take unadorned numbers for all arguments, and determine whether they refer to registers or immediates based on the instruction: "li 1, 2" sets R1 to the immediate 2 ("load immediate"), while "mr 1, 2" sets R1 to the value of R2 ("move register"). And then because people find bare numbers confusing, you have includes that do "#define r1 1" or equivalent for each register, so when writing assembly manually you can write "mr r1, r2". But because these are just dumb macros, nothing stops you from writing "li r1, r2" - the assembler will just macro expand r2 to 2 and treat it as an immediate!

Other architectures have the R prefix as an intrinsic part of the syntax, so if you write R2 in a slot where the instruction requires an immediate, you'll just get an error. If PowerPC did that, you'd still need to remember the right inline assembly constraint letter for GCC, but getting it wrong would 'just' result in an unpredictable compile error when the compiler decided to use r0, not silent misbehavior.

At least with GNU as you can use %r1, %r2 etc. as an "intrinsic part of the syntax". Which means you can't use a register name where an immediate is expected.

However that doesn't fix the gotcha with r0 being special, that is specified in the ISA. In fact it's that way precisely so you can load an immediate without needing a separate opcode.

Huh, never knew that... but I just tried it and GAS (the version Debian installed as powerpc-linux-gnu-as, at any rate) accepted "lwz %r0, %r5(%r0)". Snatching defeat from the jaws of victory...

It would still be a gotcha, but a pretty minor one if messing it up just resulted in an error. I suppose the approach taken by AArch64 and others is preferable, where one register is just completely reserved as constant 0 rather than only in some encodings.

I second that. We've had some issues with gcc's inline assembly support. To make matters worse the list of things that it does and doesn't support is very fuzzy.