[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Porting the Rust compiler to m68k


There is an ongoing effort to write a backend for m68k for LLVM called
M680x0-llvm [1]. This backend is still work in progress and there are still
a lot of things that need work [2] before the m68k backend can be considered
ready for upstreaming.

Despite the early development status of the M680x0-llvm project, I have already
started working a m68k backend for the Rust compiler [3]. Like M680x0-llvm,
Rust for m68k is still incomplete but I already got enough pieces together
that I can at least start compiling a native Rust compiler for m68k.

Since I still consider myself a Rust beginner (despite the fact that I have
already contributed more than 20 patches to the Rust compiler upstream and
its subprojects), there are still some pieces that are missing in the code,
in particular the C-ABI code for m68k which currently is has just been copied
from the powerpc code so that I have a place holder:

> https://github.com/glaubitz/rust/blob/m68k-linux/src/librustc_target/abi/call/m68k.rs

The next development step will therefore be to fully understand how the C-ABI
on m68k works. This code defines the convention on calling functions and retrieving
their return values, the latter being a bit special on m68k with pointers being returned
in different registers than integers.

A good reference for the C-ABI can be the M680x0-llvm code

> https://github.com/M680x0/M680x0-llvm/blob/M680x0/lib/Target/M680x0/M680x0CallingConv.td

as well as the m68k SysV ABI documentation of which I have a copy available for
anyone who needs it.

For the case anyone is interested in playing around with the code I have so far,
maybe with the intention of helping filling in the missing pieces, I have written
together a small howto below which explains how to get started with the code.

Interested parties can join the IRC channel #llvm-m68k on OFTC.

Building Rust for m68k

Install the build dependencies for LLVM and Rust on Debian unstable:

# apt build-dep llvm-toolchain-8.0 rustc
# apt install ninja

On Debian Stretch (stable), install the build dependencies for llvm-toolchain-4.0,
on Debian Buster (testing), install the build dependencies for llvm-toolchain-6.0.

To build the Rust compiler for m68k, first check out M680x0-llvm repository:

$ git clone https://github.com/M680x0/M680x0-llvm.git

And apply the attached two patches:

$ cd M680x0-llvm
$ patch -p1 < /path/to/m680x0-llvm-fix-ambigous-call.patch
$ patch -p1 < /path/to/m680x0-llvm-m68k-triple.patch

Then build LLVM with the X86 and M680x0 backends enabled:

$ mkdir build
$ cmake .. -DLLVM_TARGETS_TO_BUILD="X86;M680x0" -G Ninja
$ ninja

Change into a new directory and checkout my Rust fork:

$ git clone https://github.com/glaubitz/rust.git rust-m68k

Switch into the branch "m68k-linux"

$ cd rust-m68k
$ git checkout m68k-linux

Configure Rust to build for the m68k-unknown-linux-gnu target, using the
previously built M680x0-llvm:

$ ./configure --llvm-root=/path/to/M680x0-llvm/build --host=m68k-unknown-linux-gnu
$ ./x.py build

After some time, the build will eventually fail building stage1 for m68k-unknown-linux-gnu:

Building stage1 std artifacts (x86_64-unknown-linux-gnu -> m68k-unknown-linux-gnu)
   Compiling core v0.0.0 (/local_scratch/glaubitz/rust/rust-m68k/src/libcore)
   Compiling libc v0.2.46
   Compiling compiler_builtins v0.1.5
   Compiling unwind v0.0.0 (/local_scratch/glaubitz/rust/rust-m68k/src/libunwind)
   Compiling backtrace-sys v0.1.27
   Compiling std v0.0.0 (/local_scratch/glaubitz/rust/rust-m68k/src/libstd)
LLVM ERROR: Cannot select: t54: i32,i32 = srl_parts Constant:i32<-1>, Constant:i32<-1>, t53                                                                                                                     
  t52: i32 = Constant<-1>
  t52: i32 = Constant<-1>
  t53: i32 = zero_extend t8
    t8: i16 = and t6, Constant:i16<63>
      t6: i16,ch = CopyFromReg t0, Register:i16 %14
        t5: i16 = Register %14
      t7: i16 = Constant<63>
In function: _ZN4core3num7flt2dec8strategy5grisu19format_shortest_opt17he5ebf1c4a23885fbE
error: Could not compile `core`.

To learn more, run the command again with --verbose.
command did not execute successfully: "/local_scratch/glaubitz/rust/rust-m68k/build/x86_64-unknown-linux-gnu/stage0/bin/cargo" "build" "--target" "m68k-unknown-linux-gnu" "-j" "64" "--release" "--features" "panic-unwind backtrace" "--manifest-path" "/local_scratch/glaubitz/rust/rust-m68k/src/libstd/Cargo.toml" "--message-format" "json"
expected success, got: exit code: 101
failed to run: /local_scratch/glaubitz/rust/rust-m68k/build/bootstrap/debug/bootstrap build


> [1] https://github.com/M680x0/M680x0-llvm/
> [2] https://github.com/M680x0/M680x0-llvm/issues
> [3] https://github.com/glaubitz/rust/tree/m68k-linux

 .''`.  John Paul Adrian Glaubitz
: :' :  Debian Developer - glaubitz@debian.org
`. `'   Freie Universitaet Berlin - glaubitz@physik.fu-berlin.de
  `-    GPG: 62FF 8A75 84E0 2956 9546  0006 7426 3B37 F5B5 F913

>From 755ca2a218341942720c87659830cb105c8478f3 Mon Sep 17 00:00:00 2001
From: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
Date: Tue, 22 Jan 2019 01:34:58 +0100
Subject: [PATCH] [x86] Fix ambigious call to findDebugLoc()

 lib/Target/X86/X86CondBrFolding.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/Target/X86/X86CondBrFolding.cpp b/lib/Target/X86/X86CondBrFolding.cpp
index 7ce443c4656..6a3a4d7627b 100644
--- a/lib/Target/X86/X86CondBrFolding.cpp
+++ b/lib/Target/X86/X86CondBrFolding.cpp
@@ -228,7 +228,7 @@ void X86CondBrFolding::replaceBrDest(MachineBasicBlock *MBB,
     BrMI = MBBInfo->BrInstr;
     unsigned JNCC = GetCondBranchFromCond(MBBInfo->BranchCode);
     MachineInstrBuilder MIB =
-        BuildMI(*MBB, BrMI, MBB->findDebugLoc(BrMI), TII->get(JNCC))
+        BuildMI(*MBB, BrMI, MBB->findDebugLoc((llvm::MachineBasicBlock::iterator) BrMI), TII->get(JNCC))
     MBBInfo->TBB = NewDest;
     MBBInfo->BrInstr = MIB.getInstr();
@@ -254,7 +254,7 @@ void X86CondBrFolding::fixupModifiedCond(MachineBasicBlock *MBB) {
   MachineInstr *BrMI = MBBInfo->BrInstr;
   X86::CondCode CC = MBBInfo->BranchCode;
-  MachineInstrBuilder MIB = BuildMI(*MBB, BrMI, MBB->findDebugLoc(BrMI),
+  MachineInstrBuilder MIB = BuildMI(*MBB, BrMI, MBB->findDebugLoc((llvm::MachineBasicBlock::iterator) BrMI),

diff --git a/lib/Support/Triple.cpp b/lib/Support/Triple.cpp
index aea18102646..71017cb8daf 100644
--- a/lib/Support/Triple.cpp
+++ b/lib/Support/Triple.cpp
@@ -69,7 +69,7 @@ StringRef Triple::getArchTypeName(ArchType Kind) {
   case shave:          return "shave";
   case wasm32:         return "wasm32";
   case wasm64:         return "wasm64";
-  case m680x0:         return "m680x0";
+  case m680x0:         return "m68k";
   case renderscript32: return "renderscript32";
   case renderscript64: return "renderscript64";
@@ -391,7 +391,7 @@ static Triple::ArchType parseArch(StringRef ArchName) {
     .Cases("powerpc", "ppc", "ppc32", Triple::ppc)
     .Cases("powerpc64", "ppu", "ppc64", Triple::ppc64)
     .Cases("powerpc64le", "ppc64le", Triple::ppc64le)
-    .Case("m680x0", Triple::m680x0)
+    .Cases("m680x0", "m68k", Triple::m680x0)
     .Case("xscale", Triple::arm)
     .Case("xscaleeb", Triple::armeb)
     .Case("aarch64", Triple::aarch64)

Reply to: