Compile rust-mega-drive using rustc_codegen_gcc
This still generates binaries for 68020 + stdlib functions are stubbed out.
This commit is contained in:
commit
59f3c95a18
110
0001-Hackery.patch
Normal file
110
0001-Hackery.patch
Normal file
@ -0,0 +1,110 @@
|
||||
From e2b431ff117b9e58c4a487f6021da5aa54cbbd77 Mon Sep 17 00:00:00 2001
|
||||
From: User <user@example.com>
|
||||
Date: Tue, 14 Jan 2025 17:23:55 +0000
|
||||
Subject: [PATCH] Hackery
|
||||
|
||||
---
|
||||
build_system/build_sysroot/Cargo.toml | 11 +++++++----
|
||||
src/base.rs | 1 +
|
||||
src/gcc_util.rs | 3 +--
|
||||
src/lib.rs | 1 +
|
||||
target_specs/m68k-unknown-linux-gnu.json | 10 +++++-----
|
||||
5 files changed, 15 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/build_system/build_sysroot/Cargo.toml b/build_system/build_sysroot/Cargo.toml
|
||||
index 2415207..8076c81 100644
|
||||
--- a/build_system/build_sysroot/Cargo.toml
|
||||
+++ b/build_system/build_sysroot/Cargo.toml
|
||||
@@ -5,12 +5,14 @@ version = "0.0.0"
|
||||
resolver = "2"
|
||||
|
||||
[dependencies]
|
||||
+# rustc-dep-of-std?
|
||||
core = { path = "./sysroot_src/library/core" }
|
||||
-compiler_builtins = "0.1"
|
||||
+compiler_builtins = { version = "0.1" }
|
||||
+#compiler_builtins = { version = "0.1", features = ['rustc-dep-of-std'] }
|
||||
alloc = { path = "./sysroot_src/library/alloc" }
|
||||
-std = { path = "./sysroot_src/library/std", features = ["panic_unwind", "backtrace"] }
|
||||
-test = { path = "./sysroot_src/library/test" }
|
||||
-proc_macro = { path = "./sysroot_src/library/proc_macro" }
|
||||
+# std = { path = "./sysroot_src/library/std", features = ["panic_unwind", "backtrace"] }
|
||||
+# test = { path = "./sysroot_src/library/test" }
|
||||
+# proc_macro = { path = "./sysroot_src/library/proc_macro" }
|
||||
|
||||
[patch.crates-io]
|
||||
rustc-std-workspace-core = { path = "./sysroot_src/library/rustc-std-workspace-core" }
|
||||
@@ -35,4 +37,5 @@ codegen-units = 10000
|
||||
|
||||
[profile.release]
|
||||
debug = "limited"
|
||||
+panic = "abort"
|
||||
#lto = "fat" # TODO(antoyo): re-enable when the failing LTO tests regarding proc-macros are fixed.
|
||||
diff --git a/src/base.rs b/src/base.rs
|
||||
index c9701fb..97c28f1 100644
|
||||
--- a/src/base.rs
|
||||
+++ b/src/base.rs
|
||||
@@ -156,6 +156,7 @@ pub fn compile_codegen_unit(
|
||||
let target_cpu = gcc_util::target_cpu(tcx.sess);
|
||||
if target_cpu != "generic" {
|
||||
context.add_command_line_option(format!("-march={}", target_cpu));
|
||||
+ context.add_command_line_option("-mcpu=68000");
|
||||
}
|
||||
|
||||
if tcx
|
||||
diff --git a/src/gcc_util.rs b/src/gcc_util.rs
|
||||
index 560aff4..39b1889 100644
|
||||
--- a/src/gcc_util.rs
|
||||
+++ b/src/gcc_util.rs
|
||||
@@ -242,8 +242,7 @@ pub fn to_gcc_features<'a>(sess: &Session, s: &'a str) -> SmallVec<[&'a str; 2]>
|
||||
|
||||
fn arch_to_gcc(name: &str) -> &str {
|
||||
match name {
|
||||
- "M68020" => "68020",
|
||||
- _ => name,
|
||||
+ _ => "68000",
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/lib.rs b/src/lib.rs
|
||||
index f6ad0c7..e19dbcf 100644
|
||||
--- a/src/lib.rs
|
||||
+++ b/src/lib.rs
|
||||
@@ -196,6 +196,7 @@ impl CodegenBackend for GccCodegenBackend {
|
||||
let context = Context::default();
|
||||
if target_cpu != "generic" {
|
||||
context.add_command_line_option(format!("-march={}", target_cpu));
|
||||
+ context.add_command_line_option("-mcpu=68000");
|
||||
}
|
||||
|
||||
**self.target_info.info.lock().expect("lock") = context.get_target_info();
|
||||
diff --git a/target_specs/m68k-unknown-linux-gnu.json b/target_specs/m68k-unknown-linux-gnu.json
|
||||
index 95ea061..026dc98 100644
|
||||
--- a/target_specs/m68k-unknown-linux-gnu.json
|
||||
+++ b/target_specs/m68k-unknown-linux-gnu.json
|
||||
@@ -1,17 +1,17 @@
|
||||
{
|
||||
"arch": "m68k",
|
||||
- "cpu": "M68020",
|
||||
+ "cpu": "M68000",
|
||||
"crt-static-respected": true,
|
||||
"data-layout": "E-m:e-p:32:16:32-i8:8:8-i16:16:16-i32:16:32-n8:16:32-a:0:16-S16",
|
||||
- "dynamic-linking": true,
|
||||
+ "dynamic-linking": false,
|
||||
"env": "gnu",
|
||||
"has-rpath": true,
|
||||
- "has-thread-local": true,
|
||||
+ "has-thread-local": false,
|
||||
"llvm-target": "m68k-unknown-linux-gnu",
|
||||
"max-atomic-width": 32,
|
||||
"os": "linux",
|
||||
- "position-independent-executables": true,
|
||||
- "relro-level": "full",
|
||||
+ "position-independent-executables": false,
|
||||
+ "relro-level": "none",
|
||||
"supported-split-debuginfo": [
|
||||
"packed",
|
||||
"unpacked",
|
||||
--
|
||||
2.34.1
|
||||
|
||||
308
0001-Patches-to-run-with-gcc.patch
Normal file
308
0001-Patches-to-run-with-gcc.patch
Normal file
@ -0,0 +1,308 @@
|
||||
From c0bc79d64a1e11d8008f24f063e65b144f3a6067 Mon Sep 17 00:00:00 2001
|
||||
From: User <user@example.com>
|
||||
Date: Tue, 14 Jan 2025 08:29:08 +0000
|
||||
Subject: [PATCH] Patches to run with gcc
|
||||
|
||||
---
|
||||
examples/megapong/entry.S | 154 ++++++++++++++---------------
|
||||
examples/megapong/stdlib.S | 21 ++++
|
||||
libs/megadrive-graphics/src/lib.rs | 2 +-
|
||||
libs/megadrive-util/src/panic.rs | 5 +-
|
||||
share/ldscripts/megadrive.x | 8 +-
|
||||
6 files changed, 119 insertions(+), 85 deletions(-)
|
||||
create mode 100644 examples/megapong/compile.sh
|
||||
create mode 100644 examples/megapong/stdlib.S
|
||||
|
||||
diff --git a/examples/megapong/entry.S b/examples/megapong/entry.S
|
||||
index e5343ed..2543eb0 100644
|
||||
--- a/examples/megapong/entry.S
|
||||
+++ b/examples/megapong/entry.S
|
||||
@@ -6,91 +6,91 @@
|
||||
.set HBLANK, _int
|
||||
.set VBLANK, _vblank
|
||||
|
||||
-.long 0x0 ; Initial Stack Address
|
||||
-.long START ; Start of program Code
|
||||
-.long INT ; Bus error
|
||||
-.long INT ; Address error
|
||||
-.long INT ; Illegal instruction
|
||||
-.long INT ; Division by zero
|
||||
-.long INT ; CHK exception
|
||||
-.long INT ; TRAPV exception
|
||||
-.long INT ; Privilage violation
|
||||
-.long INT ; TRACE exception
|
||||
-.long INT ; Line-A emulator
|
||||
-.long INT ; Line-F emulator
|
||||
-.long INT ; Reserved (NOT USED)
|
||||
-.long INT ; Co-processor protocol violation
|
||||
-.long INT ; Format error
|
||||
-.long INT ; Uninitialized Interrupt
|
||||
-.long INT ; Reserved (NOT USED)
|
||||
-.long INT ; Reserved (NOT USED)
|
||||
-.long INT ; Reserved (NOT USED)
|
||||
-.long INT ; Reserved (NOT USED)
|
||||
-.long INT ; Reserved (NOT USED)
|
||||
-.long INT ; Reserved (NOT USED)
|
||||
-.long INT ; Reserved (NOT USED)
|
||||
-.long INT ; Reserved (NOT USED)
|
||||
-.long INT ; Spurious Interrupt
|
||||
-.long INT ; IRQ Level 1
|
||||
-.long INT ; IRQ Level 2 (EXT Interrupt)
|
||||
-.long INT ; IRQ Level 3
|
||||
-.long HBLANK ; IRQ Level 4 (VDP Horizontal Interrupt)
|
||||
-.long INT ; IRQ Level 5
|
||||
-.long VBLANK ; IRQ Level 6 (VDP Vertical Interrupt)
|
||||
-.long INT ; IRQ Level 7
|
||||
-.long INT ; TRAP #00 Exception
|
||||
-.long INT ; TRAP #01 Exception
|
||||
-.long INT ; TRAP #02 Exception
|
||||
-.long INT ; TRAP #03 Exception
|
||||
-.long INT ; TRAP #04 Exception
|
||||
-.long INT ; TRAP #05 Exception
|
||||
-.long INT ; TRAP #06 Exception
|
||||
-.long INT ; TRAP #07 Exception
|
||||
-.long INT ; TRAP #08 Exception
|
||||
-.long INT ; TRAP #09 Exception
|
||||
-.long INT ; TRAP #10 Exception
|
||||
-.long INT ; TRAP #11 Exception
|
||||
-.long INT ; TRAP #12 Exception
|
||||
-.long INT ; TRAP #13 Exception
|
||||
-.long INT ; TRAP #14 Exception
|
||||
-.long INT ; TRAP #15 Exception
|
||||
-.long INT ; (FP) Branch or Set on Unordered Condition
|
||||
-.long INT ; (FP) Inexact Result
|
||||
-.long INT ; (FP) Divide by Zero
|
||||
-.long INT ; (FP) Underflow
|
||||
-.long INT ; (FP) Operand Error
|
||||
-.long INT ; (FP) Overflow
|
||||
-.long INT ; (FP) Signaling NAN
|
||||
-.long INT ; (FP) Unimplemented Data Type
|
||||
-.long INT ; MMU Configuration Error
|
||||
-.long INT ; MMU Illegal Operation Error
|
||||
-.long INT ; MMU Access Violation Error
|
||||
-.long INT ; Reserved (NOT USED)
|
||||
-.long INT ; Reserved (NOT USED)
|
||||
-.long INT ; Reserved (NOT USED)
|
||||
-.long INT ; Reserved (NOT USED)
|
||||
-.long INT ; Reserved (NOT USED)
|
||||
+.long 0x0
|
||||
+.long START
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long HBLANK
|
||||
+.long INT
|
||||
+.long VBLANK
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
+.long INT
|
||||
|
||||
-.ascii "SEGA MEGADRIVE " ; SEGA must be the first four chars for TMSS
|
||||
+.ascii "SEGA MEGADRIVE "
|
||||
.ascii "(C)2021.JAN "
|
||||
-.ascii "TESTPROJECT " ; export name
|
||||
+.ascii "TESTPROJECT "
|
||||
.ascii " "
|
||||
.ascii " "
|
||||
-.ascii "TESTPROJECT " ; domestic (Japanese) name
|
||||
+.ascii "TESTPROJECT "
|
||||
.ascii " "
|
||||
.ascii " "
|
||||
.ascii "GM MK-0000 -01"
|
||||
-.short 0x0000 ; checksum - not needed
|
||||
+.short 0x0000
|
||||
.ascii "J6 "
|
||||
-.long 0x00000000, 0x0007ffff ; ROM start, end
|
||||
-.long 0x00ff0000, 0x00ffffff ; RAM start, end
|
||||
-.ascii " " ; no SRAM
|
||||
+.long 0x00000000, 0x0007ffff
|
||||
+.long 0x00ff0000, 0x00ffffff
|
||||
+.ascii " "
|
||||
.ascii " "
|
||||
.ascii " "
|
||||
-.ascii " " ; memo
|
||||
+.ascii " "
|
||||
.ascii " "
|
||||
.ascii " "
|
||||
-.ascii "F " ; enable any hardware configuration
|
||||
+.ascii "F "
|
||||
|
||||
.global vblank
|
||||
_vblank:
|
||||
@@ -100,14 +100,14 @@ _vblank:
|
||||
.global _start
|
||||
.global main
|
||||
_start:
|
||||
- move.l #_stack_top, sp
|
||||
- move.w #0x2500, sr
|
||||
+ move.l #_stack_top, %sp
|
||||
+ move.w #0x2500, %sr
|
||||
jsr _init_runtime
|
||||
- bra #main
|
||||
+ bra main
|
||||
|
||||
.global abort
|
||||
abort:
|
||||
- bra #abort
|
||||
+ bra abort
|
||||
|
||||
_int:
|
||||
rte
|
||||
diff --git a/examples/megapong/stdlib.S b/examples/megapong/stdlib.S
|
||||
new file mode 100644
|
||||
index 0000000..b614ed5
|
||||
--- /dev/null
|
||||
+++ b/examples/megapong/stdlib.S
|
||||
@@ -0,0 +1,25 @@
|
||||
+.text
|
||||
+
|
||||
+.global memcpy
|
||||
+memcpy:
|
||||
+ rts
|
||||
+
|
||||
+.global memcmp
|
||||
+memcmp:
|
||||
+ rts
|
||||
+
|
||||
+.global memset
|
||||
+memset:
|
||||
+ rts
|
||||
+
|
||||
+.global _Unwind_Resume
|
||||
+_Unwind_Resume:
|
||||
+ rts
|
||||
+
|
||||
+.global rust_eh_personality
|
||||
+rust_eh_personality:
|
||||
+ rts
|
||||
+
|
||||
+.global __mulsi3
|
||||
+__mulsi3:
|
||||
+ rts
|
||||
diff --git a/libs/megadrive-graphics/src/lib.rs b/libs/megadrive-graphics/src/lib.rs
|
||||
index d7aa284..5e7f929 100644
|
||||
--- a/libs/megadrive-graphics/src/lib.rs
|
||||
+++ b/libs/megadrive-graphics/src/lib.rs
|
||||
@@ -5,7 +5,7 @@ use core::mem::MaybeUninit;
|
||||
use megadrive_sys::vdp::{Sprite, VDP};
|
||||
|
||||
pub mod default_ascii {
|
||||
- include!(concat!(env!("OUT_DIR"), "/default_ascii.rs"));
|
||||
+ // include!(concat!(env!("OUT_DIR"), "/default_ascii.rs"));
|
||||
}
|
||||
mod font;
|
||||
|
||||
diff --git a/libs/megadrive-util/src/panic.rs b/libs/megadrive-util/src/panic.rs
|
||||
index 8564bbd..edb1663 100644
|
||||
--- a/libs/megadrive-util/src/panic.rs
|
||||
+++ b/libs/megadrive-util/src/panic.rs
|
||||
@@ -3,7 +3,6 @@ use core::ptr::read_volatile;
|
||||
|
||||
use megadrive_sys::vdp::VDP;
|
||||
use megadrive_graphics::Renderer;
|
||||
-use megadrive_graphics::default_ascii::DEFAULT_FONT_1X1;
|
||||
|
||||
static mut NEW_FRAME: u16 = 0;
|
||||
|
||||
@@ -19,7 +18,7 @@ fn panic(_info: &PanicInfo) -> ! {
|
||||
vdp.enable_display(true);
|
||||
|
||||
// Initialize the default font tiles
|
||||
- DEFAULT_FONT_1X1.load(&mut vdp);
|
||||
+ // DEFAULT_FONT_1X1.load(&mut vdp);
|
||||
|
||||
let resolution = vdp.resolution();
|
||||
let half_screen_width = (resolution.0 >> 1) as i16;
|
||||
@@ -36,7 +35,7 @@ fn panic(_info: &PanicInfo) -> ! {
|
||||
// let mut panic_text: &str = &_info.payload().downcast_ref::<&str>().unwrap();
|
||||
let panic_text= "Panic!";
|
||||
|
||||
- DEFAULT_FONT_1X1.blit_text(&mut renderer, panic_text, x_off as u16, y_off as u16);
|
||||
+ // DEFAULT_FONT_1X1.blit_text(&mut renderer, panic_text, x_off as u16, y_off as u16);
|
||||
renderer.render(&mut vdp);
|
||||
// vsync
|
||||
wait_for_vblank();
|
||||
diff --git a/share/ldscripts/megadrive.x b/share/ldscripts/megadrive.x
|
||||
index 95e1cf3..c6d91ae 100644
|
||||
--- a/share/ldscripts/megadrive.x
|
||||
+++ b/share/ldscripts/megadrive.x
|
||||
@@ -22,19 +22,19 @@ SECTIONS
|
||||
|
||||
.data :
|
||||
{
|
||||
- ALIGN(4);
|
||||
+ . = ALIGN(4);
|
||||
_data_start = .;
|
||||
*(.data);
|
||||
- ALIGN(4);
|
||||
+ . = ALIGN(4);
|
||||
_data_end = .;
|
||||
} > RAM AT > ROM
|
||||
|
||||
.bss (NOLOAD) :
|
||||
{
|
||||
- ALIGN(4);
|
||||
+ . = ALIGN(4);
|
||||
_bss_start = .;
|
||||
*(.bss);
|
||||
- ALIGN(4);
|
||||
+ . = ALIGN(4);
|
||||
_bss_end = .;
|
||||
} > RAM AT > ROM
|
||||
|
||||
--
|
||||
2.34.1
|
||||
|
||||
64
Dockerfile
Normal file
64
Dockerfile
Normal file
@ -0,0 +1,64 @@
|
||||
FROM ubuntu:22.04
|
||||
|
||||
RUN apt-get -y update && apt-get install -y --no-install-recommends git curl ca-certificates build-essential sudo
|
||||
|
||||
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | bash -s -- -y
|
||||
ENV PATH="/root/.cargo/bin:${PATH}"
|
||||
# Not sure why/if this is needed
|
||||
ENV LIBRARY_PATH=/usr/lib
|
||||
# Make sure we compile to the right target
|
||||
ENV OVERWRITE_TARGET_TRIPLE=m68k-unknown-linux-gnu
|
||||
|
||||
# Clone source repo
|
||||
RUN git clone https://github.com/rust-lang/rustc_codegen_gcc.git
|
||||
|
||||
# Setup rustup
|
||||
RUN cd rustc_codegen_gcc && rustup show
|
||||
|
||||
# Install gcc
|
||||
RUN curl -LO https://github.com/cross-cg-gcc-tools/cross-gcc/releases/latest/download/gcc-m68k-13.deb
|
||||
RUN dpkg -i gcc-m68k-13.deb
|
||||
|
||||
# Set gcc path in the rustc_codegen project
|
||||
RUN echo 'gcc-path = "/usr/lib"' > rustc_codegen_gcc/config.toml
|
||||
|
||||
# Git config is needed for ./y.sh prepare
|
||||
RUN git config --global user.email "user@example.com"
|
||||
RUN git config --global user.name "User"
|
||||
|
||||
# Apply hacky patch
|
||||
COPY 0001-Hackery.patch /tmp/0001-Hackery.patch
|
||||
RUN cd rustc_codegen_gcc && patch -p1 < /tmp/0001-Hackery.patch && rm /tmp/0001-Hackery.patch
|
||||
|
||||
# Build project
|
||||
# See https://github.com/rust-lang/rustc_codegen_gcc/blob/master/doc/tips.md#how-to-build-a-cross-compiling-libgccjit
|
||||
RUN cd rustc_codegen_gcc && ./y.sh prepare --cross
|
||||
RUN cd rustc_codegen_gcc && ./y.sh build --sysroot --features compiler_builtins/no-f16-f128 --target-triple m68k-unknown-linux-gnu --target /rustc_codegen_gcc/target_specs/m68k-unknown-linux-gnu.json
|
||||
|
||||
# Build "megapong" PoC
|
||||
RUN git clone https://github.com/ricky26/rust-mega-drive.git
|
||||
COPY 0001-Patches-to-run-with-gcc.patch /tmp/rust-mega-drive.patch
|
||||
RUN cd rust-mega-drive && patch -p1 </tmp/rust-mega-drive.patch && rm /tmp/rust-mega-drive.patch
|
||||
# rust-mega-drive requires python3 as part of the build script.
|
||||
RUN apt-get install -y python3
|
||||
# Compile rust code
|
||||
RUN cd rustc_codegen_gcc && ./y.sh cargo build --target ./target_specs/m68k-unknown-linux-gnu.json --manifest-path /rust-mega-drive/examples/megapong/Cargo.toml --release
|
||||
|
||||
# Compile entrypoint + stdlib stub (should not be strictly necessary to reproduce)
|
||||
RUN cd rust-mega-drive/examples/megapong && m68k-unknown-linux-gnu-gcc -c entry.S -o entry.o -fno-exceptions -mcpu=68000
|
||||
RUN cd rust-mega-drive/examples/megapong && m68k-unknown-linux-gnu-gcc -c stdlib.S -o stdlib.o -fno-exceptions -mcpu=68000
|
||||
# Link everything
|
||||
RUN cd rust-mega-drive/examples/megapong && m68k-unknown-linux-gnu-ld -o out.elf -T /rust-mega-drive/share/ldscripts/megadrive.x entry.o stdlib.o ../../target/m68k-unknown-linux-gnu/release/libmegapong.a -static -z nocopyreloc --no-eh-frame-hdr -nostdlib
|
||||
# Create cartridge
|
||||
RUN cd rust-mega-drive/examples/megapong && m68k-unknown-linux-gnu-objcopy -O binary out.elf out.md
|
||||
|
||||
# Installing utility file
|
||||
RUN apt install -y file
|
||||
# XXX: Artifacts have been created, the following commands can be used to verify if things are okay or not.
|
||||
# 1) This shows that the object files were created for 68020 "Motorola m68k, 68020".
|
||||
# cd /tmp
|
||||
# ar x /rust-mega-drive/target/m68k-unknown-linux-gnu/release/libmegapong.a
|
||||
# file *.o
|
||||
#
|
||||
# 2) The offending instruction will be inserted at the beginning of _init_runtime, if the following command finds something, the code is invalid for 68000
|
||||
# cd rust-mega-drive/examples/megapong && m68k-unknown-linux-gnu-objdump -d out.elf | grep -A3 "_init_runtime" | grep "4bfb 0170"
|
||||
Loading…
Reference in New Issue
Block a user