Porting the Rust compiler to m68k
Hello!
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
Thanks,
Adrian
> [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))
.addMBB(NewDest);
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),
TII->get(GetCondBranchFromCond(CC)))
.addMBB(MBBInfo->TBB);
BrMI->eraseFromParent();
--
2.20.1
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: