On 4/12/2016 4:35 PM, Iain Buclaw via Digitalmars-d wrote:
It's a step backwards because I can't just say "MUL EAX". I have to tell GCC
what register the result gets put in. This is, to my mind, ridiculous. GCC's
inline assembler apparently has no knowledge of what the opcodes actually
do.
asm { "mul eax"; } - That wasn't so difficult. :-)
My understanding is that is not sufficient if you want gcc to track register
usage, etc. I could be wrong, I found the documentation on how the gcc inline
assembler works to be impossible to figure out what was required and what
wasn't. I'd just look at existing examples and modify to suit :-(
I don't know if D data and calling functions from DMD-IASM is safe
I don't know what you mean by 'safe' in this context. If you follow the ABI it
should work.
(it
is in GDC extended IASM). But I have always chosen the path that
requires the least amount of maintenance burden/overhead. And I'm
sorry to say that supporting GCC-style extended assembler both comes
for free (handling is managed by the middle-end), and requires no
platform-specific support on the language implementation side.
Your decision makes sense.
However, I have always considered comparing the two a bit like apples
and oranges. DMD compiles to object code, so it makes sense to me
that you have an entire assembler embedded in. However GDC compiles
to assembly, and I expect that GNU As will know a lot more about what
opcodes actually do on, say a Motorola 68k, than the poor mans parser
I would be able to write.
There were a lot of challenges supporting DMD-style IASM, all
non-existent in DMD. Drawing a list off the top of my head - I'll let
you decide whether IASM is pro or con in this area, but again bear in
mind that DMD doesn't have to deal with calling an external assembler.
- What dialect am I writing in? (Do I emit mul or mull? eax or %eax?)
- Some opcodes in IASM have a different name in the assembler (Emitted
fdivrp as fdivp, and fdivp as fdivrp. No idea why but I recall
std.math didn't work without the translation).
DMD's iasm uses the opcodes as written in the Intel CPU manuals. There is no
MULL opcode in the manual, so no MULL in DMD's iasm. It figures out which opcode
by looking at the operands, using the Intel CPU manual as a guide.
It's a bit of a pain as there are a lot of special cases, but the end result is
pretty straightforward if you're using the Intel CPU manual as a reference guide.
- Some opcodes are actually directives in disguise (db, ds, dw, ...)
- Frame-relative addressing/displacement of a symbol before the
backend has decided where incoming parameters will land is a good way
to get hit by a truck.
- GCC backend doesn't support naked functions on x86.
- Or even in the sense that DMD supports naked functions where there
is support (only plain text assembler allowed)
- Want to support ARM? MIPS? PPC? At the time when GDC supported
DMD-style IASM for x86, the implementation was over 3000 LOC, adding
platform support just looked like an unmanageable nightmare.
I understand that GDC has special challenges because it writes to an assembler
rather than direct to object code. I understand it is not easy to replicate
DMD's iasm functionality. Which is why I haven't given you a hard time about it
:-) and it is not terribly important.
But core.cpuid needs to be made to work in GDC, whatever it takes to do so.
----
Personally, I strongly dislike the fact that the GAS syntax is the reverse of
Intel's. It isn't just GAS, it's GDB and everything else. It just sux. It makes
my eyeballs hurt looking at it. It's like giving me a car with the brake and gas
pedals reversed. Nothing but accidents result :-) And I don't like that they use
different opcodes than the Intel manuals. That just sux, too.
But I know that the GNU world is stuck with that, and GDC should behave like the
rest of GCC.