Adding mos target using llvm-mos

I'm trying to get the 6502 / MOS fork llvm-mos to work with rustc.

I roughly followed the "Adding a new target" guide. Added the llvm-mos fork, checked it out, pulled in all relevant rust patches to fix compile errors. So far that worked. Then I looked over the codebase and roughly replicated what the avr target does, e.g.:

  • added mos to the list of optional components in compiler/rustc_llvm/build.rs
  • add MOS to the list of experimental targets in src/bootstrap/native.rs

The llvm build is correctly built by x.py with the mos target:

build/x86_64-unknown-linux-gnu/llvm/bin/llc --version
LLVM (http://llvm.org/):
  LLVM version 13.0.0-rust-dev
  Optimized build with assertions.
  Default target: x86_64-unknown-linux-gnu
  Host CPU: haswell

  Registered Targets:
…
    mos        - MOS Technologies 65xx and variants
…
    x86        - 32-bit X86: Pentium-Pro and above
    x86-64     - 64-bit X86: EM64T and AMD64

So far so good. Then I linked the built compiler using rustup:

rustup toolchain link stage1 build/x86_64-unknown-linux-gnu/stage1

and then I tried to compile a bare bones nostd program using a target file that is roughly based on the avr target:

{
  "arch": "mos",
  "atomic-cas": false,
  "cpu": "mos6502",
  "data-layout": "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8",
  "eh-frame-header": false,
  "exe-suffix": ".prg2",
  "executables": true,
  "is-builtin": false,
  "llvm-target": "mos",
  "max-atomic-width": 0,
  "target-c-int-width": "16",
  "target-pointer-width": "16"
}

But compilation does not work using that target file, rustc reports:

error: failed to run `rustc` to learn about target-specific information

Caused by:
  process didn't exit successfully: `rustc - --crate-name ___ --print=file-names --target …/mos.json --crate-type bin --crate-type rlib --crate-type dylib --crate-type cdylib --crate-type staticlib --crate-type proc-macro --print=sysroot --print=cfg` (exit status: 1)
  --- stderr
  error: Could not create LLVM TargetMachine for triple: mos: No available targets are compatible with triple "mos"

I know that a lot of things are still missing at this point (e.g. C calling convention / ABI or linker scripts to produce any useful binaries), but at least llvm should accept the mos target, shouldn't it?

I briefly studied the llvm code, but could not figure out why the compiled llvm works with the target, but the TargetMachine instance that is created by rust does not. Is there any additional runtime configuration needed?

I think you need to add a block like rust/lib.rs at 840acd378a273dab6798352d3d6a087fa09e4806 · rust-lang/rust · GitHub to initialize the LLVM support for MOS.

1 Like

Ah thank you! Now I can continue fixing errors :wink: