[llvm-dev] [cfe-dev] [RFC] Backend for Motorola 6800 series CPU (M68k)

Jorg Brown via llvm-dev llvm-dev at lists.llvm.org
Sun Sep 27 14:02:46 PDT 2020


I'm irrationally thrilled that you're doing this.  The 68K is, to this day,
my favorite CPU to code for, probably because 68K-based Macs were
bare-metal machines, where application programs ran in full supervisor
mode, and the "programmer's switch" that came with each Mac allows you to
interrupt the CPU no matter what it was doing - user code or system code -
and drops you into the machine's debugger right at that point.

Thank you so much for taking this on.

I took a very quick look at your 68K code for main:

int main () {
    printf("Hello World!\n");
    return 0;
}

gcc:
8000044c <main>:
8000044c: 4e56 0000      linkw %fp,#0
80000450: 4879 8000 04fc pea 800004fc <_IO_stdin_used+0x4>
80000456: 4eb9 8000 0330 jsr 80000330 <puts at plt>
8000045c: 588f           addql #4,%sp
8000045e: 4280           clrl %d0
80000460: 4e5e           unlk %fp
80000462: 4e75           rts

Your llvm:
8000042c <main>:
8000042c: 2f0e                movel %fp,%sp at -
8000042e: 2c4f                moveal %sp,%fp
80000430: 9ffc 0000 0010      subal #16,%sp
80000436: 2d7c 0000 0000 fffc movel #0,%fp@(-4)
8000043e: 41fb 0170 0000 00bc lea %pc@(800004fc <_IO_stdin_used+0x4>),%a0
80000446: 224f                moveal %sp,%a1
80000448: 2288                movel %a0,%a1@
8000044a: 4eb9 8000 0310      jsr 80000310 <printf at plt>
80000450: 7200                moveq #0,%d1
80000452: 48ee 0001 fff8      moveml %d0,%fp@(-8)
80000458: 2001                movel %d1,%d0
8000045a: dffc 0000 0010      addal #16,%sp
80000460: 2c5f                moveal %sp at +,%fp
80000462: 4e75                rts


This immediately makes me wonder what you mean by "default optimization
settings"...

But more importantly, I share Chris' concern about ABI.  In particular, in
the Mac world, there were two ABIs in common use:

1) For code written in pascal, including the Mac OS itself, parameter
passing was on the stack, where you reserve space for the return value,
then push the parameters in order, and the called function clears up the
stack prior to returning to you.  If you were to try to generate code for
Mac applications, you would have to have some way of using this convention
on a per-call basis, because you'd need it in order to make system calls.
Early compilers dodged this requirement by having glue libraries that took
C conventions and then made the appropriate Pascal calls using assembly, so
it's not necessary for your initial check-in.  Just something to keep in
mind.

2) For code written in C, parameter passing was on the stack, where you
push the parameters in reverse order, and the called function puts the
return value in register d0.  It's the callers responsibility to clean up
the stack, in order to support variadic functions such as printf.  As Chris
says, there were variations on this, even on the Mac, because Apple's
language of choice was originally Pascal so each compiler vendor had a
different idea of what "C" conventions were.  In particular, early on, many
vendors chose a 16-bit size for int, which had important implications for
ABI since it changes how you call printf("%d\n", 2);  Apple's MPW
(Macintosh Programmer's Workshop) chose a 32-bit size for int.

As I look at this generated code, however, I can't see what conventions
it's trying to follow.

The area on the stack prior to the call to printf is:

???? ???? ???? ??? ???? ???? 0000 0000 fpfpfpfp
(where "fpfpfpfp" is the old 32-bit value of the frame pointer, and the
current frame pointer points to it.)

And the parameter to printf is in both a0 and a1.

The code seems to think a return value from printf is in d0, judging by the
moveml instruction.

This all is fine, albeit woefully inefficient, if your calling convention
sometimes passes function arguments in registers.  Does it?

Separately, please consider using the link and unlk instructions, always.
All the production compilers used these instructions, even when
optimization was off; the advanced compilers could avoid them in certain
cases such as  "leaf" routines, but that was rare.  They're efficient and
make code shorter and easier to read.

And again, thanks for doing this!

-- Jorg

On Fri, Sep 25, 2020 at 3:02 PM John Paul Adrian Glaubitz via llvm-dev <
llvm-dev at lists.llvm.org> wrote:

> Hello Chris!
>
> On 9/25/20 11:16 PM, Chris Hanson wrote:
> > I know it's really early in the project's life, but another question I
> had:
> > How does the generated 68K code perform, at least compared to modern GCC?
>
> I compiled a simple "Hello World" source in C both with a gcc-10
> cross-compiler
> for m68k and LLVM/m68k with the default optimization settings.
>
> I'm attaching the original C source as well as the disassembled binary
> source
> for both compiler outputs.
>
> Adrian
>
> --
>  .''`.  John Paul Adrian Glaubitz
> : :' :  Debian Developer - glaubitz at debian.org
> `. `'   Freie Universitaet Berlin - glaubitz at physik.fu-berlin.de
>   `-    GPG: 62FF 8A75 84E0 2956 9546  0006 7426 3B37 F5B5 F913
>
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20200927/55d03841/attachment.html>


More information about the llvm-dev mailing list