Porting the Rust compiler to m68k

To: Debian m68k <debian-68k@lists.debian.org>

Subject: Porting the Rust compiler to m68k

From: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>

Date: Mon, 11 Feb 2019 18:19:09 +0100

Message-id: <[🔎] 0162d2e5-8cc3-20e9-23e7-dfb9f97c43c4@physik.fu-berlin.de>

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)