-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Brian Cain <[email protected]>
- Loading branch information
Showing
10 changed files
with
222 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
|
||
[build] | ||
target = [ "hexagon-unknown-linux-musl"] | ||
|
||
[target.hexagon-unknown-linux-musl] | ||
|
||
linker = "hexagon-unknown-linux-musl-clang" | ||
runner = "qemu-hexagon" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
/target | ||
*.swp | ||
*.a | ||
*.a.o |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
[package] | ||
name = "contrived" | ||
version = "0.1.0" | ||
edition = "2021" | ||
build = "build.rs" | ||
|
||
[build-dependencies] | ||
cc = "1.1.21" | ||
bindgen = "0.70.1" | ||
build-target = "0.4.0" | ||
|
||
[dependencies] | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
# Contrived example | ||
|
||
This is a contrived example to demonstrate some toolchains targeting | ||
hexagon linux. Here we illustrate how to use Rust, Zig, and C++ to | ||
write programs portable to hexagon similarly to how one would | ||
target other architectures. | ||
|
||
We can use the upstream Rust toolchain with lld to make programs for hexagon | ||
linux. There might be yet-undiscovered bugs, but there's no known limitations | ||
for this platform. | ||
|
||
As of September 2024, Zig does not yet have support for hexagon linux, only | ||
`hexagon-freestanding` (baremetal hexagon). This is primarily because the | ||
C library support is not yet upstreamed to `musl`. As a consequence we | ||
cannot yet `@import("std")`. Also, with any zig code, compiler-emitted | ||
calls to the compiler builtin libraries could result in some "unresolved | ||
symbol" link errors. These could probably be solved with some creative | ||
workarounds/linker command-line overrides. See the [issue at the | ||
zig project for details](https://github.com/ziglang/zig/issues/21579). | ||
|
||
## Dependencies | ||
|
||
[Download zig](https://ziglang.org/download/), unpack the tarball and put | ||
the `zig` executable in your `PATH`. | ||
|
||
[Install rust using the instructions from the Rust Project website](https://www.rust-lang.org/learn/get-started) | ||
and then install the nightly: | ||
|
||
rustup toolchain install nightly | ||
rustup override set nightly | ||
rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-gnu | ||
|
||
Download and install the hexagon open source toolchain from https://github.com/quic/toolchain_for_hexagon/releases - version 19.1.0 or later. | ||
|
||
## Setup | ||
|
||
Edit the `.cargo/config` to point to your toolchain's C library: | ||
|
||
... | ||
runner = "qemu-hexagon -L /inst/clang+llvm-19.1.0-cross-hexagon-unknown-linux-musl/x86_64-linux-gnu/target/hexagon-unknown-linux-musl/usr" | ||
... | ||
|
||
|
||
## Build and run | ||
|
||
Build/run the demo with QEMU hexagon: | ||
|
||
export TARGET_CC=hexagon-unknown-linux-musl-clang | ||
export PATH=/inst/clang+llvm-19.1.0-cross-hexagon-unknown-linux-musl/x86_64-linux-gnu/bin/:$PATH | ||
export QEMU_LD_PREFIX=/inst/clang+llvm-19.1.0-cross-hexagon-unknown-linux-musl/x86_64-linux-musl/target/hexagon-unknown-linux-musl/usr/ | ||
|
||
cargo +nightly build --target=hexagon-unknown-linux-musl -Zbuild-std -Zbuild-std-features=llvm-libunwind | ||
cargo +nightly run --target=hexagon-unknown-linux-musl -Zbuild-std -Zbuild-std-features=llvm-libunwind | ||
|
||
Try experimenting with some different input arguments to see how this impacts | ||
the cycles consumed. | ||
|
||
As a simpler reference, you can also run this natively on an `x86_64` host | ||
(you might need to manually clean up some `*.a` / `*.a.o` files): | ||
|
||
CXX=clang++ CC=clang cargo run --target=x86_64-unknown-linux-gnu | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
use std::process::Command; | ||
|
||
fn main() { | ||
println!("cargo::rerun-if-changed=src/hex_sys.cpp"); | ||
|
||
cc::Build::new() | ||
.file("src/some_cxx.cpp") | ||
.compile("libsome_cxx.a"); | ||
println!("cargo:rustc-link-lib=some_cxx"); | ||
|
||
let arch = build_target::target_arch().unwrap(); | ||
let arch = arch.as_str(); | ||
|
||
let zig_tgt = match arch { | ||
"hexagon" => "hexagon-freestanding", | ||
"x86_64" => "x86_64-linux-gnu", | ||
_ => panic!("unsupported target"), | ||
}; | ||
|
||
println!("cargo::rerun-if-changed=src/some_sys.zig"); | ||
let rc = Command::new("zig") | ||
.arg("build-lib") | ||
.arg("-fPIC") | ||
.arg("-target") | ||
.arg(zig_tgt) | ||
.arg("src/some_sys.zig") | ||
.status() | ||
.expect("failed to spawn process"); | ||
assert!(rc.success()); | ||
|
||
println!("cargo:rustc-link-search=."); | ||
println!("cargo:rustc-link-lib=some_sys"); | ||
} |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// Copyright(c) 2024 Qualcomm Innovation Center, Inc. All Rights Reserved. | ||
// SPDX-License-Identifier: BSD-3-Clause | ||
|
||
use std::env; | ||
|
||
extern "C" { | ||
fn read_activity() -> u64; | ||
fn get_cycles() -> u64; | ||
fn get_time() -> u64; | ||
} | ||
|
||
fn fibonacci(n: u32) -> u32 { | ||
match n { | ||
0 => 1, | ||
1 => 1, | ||
_ => fibonacci(n - 1) + fibonacci(n - 2), | ||
} | ||
} | ||
|
||
fn main() { | ||
let arg: String = env::args().nth(1).unwrap_or("16".to_string()); | ||
let in_val = arg.parse::<u32>().unwrap_or(16); | ||
|
||
let t0 = unsafe { read_activity() }; | ||
let v = fibonacci(in_val); | ||
let dur_cycl = unsafe { read_activity() } - t0; | ||
|
||
println!("fibonacci({}): {}", in_val, v); | ||
println!("cycles elapsed: {}", dur_cycl); | ||
|
||
let t0 = unsafe { get_cycles() }; | ||
let v_ = fibonacci(in_val); | ||
let t_end = unsafe { get_cycles() } - t0; | ||
|
||
println!("fibonacci({}): {}", in_val, v_); | ||
println!("cycles elapsed: {}", t_end); | ||
|
||
println!("cur time: {}", unsafe { get_time() }); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// Copyright(c) 2024 Qualcomm Innovation Center, Inc. All Rights Reserved. | ||
// SPDX-License-Identifier: BSD-3-Clause | ||
|
||
#include <stdint.h> | ||
|
||
#pragma clang diagnostic push | ||
#pragma clang diagnostic ignored "-Wc23-extensions" | ||
|
||
static const int32_t raw_data[] = { | ||
#embed "lut.dat" | ||
}; | ||
#pragma clang diagnostic pop | ||
|
||
|
||
#define ARRAY_ELTS(x) (sizeof(x) / sizeof(x[0])) | ||
|
||
int32_t get_val(unsigned int index) { | ||
return raw_data[index % ARRAY_ELTS(raw_data)]; | ||
} | ||
|
||
extern "C" uint64_t get_cycles() { | ||
return __builtin_readcyclecounter(); | ||
} | ||
|
||
#if !defined(__clang_major__) || __clang_major__ < 19 | ||
#error "requires clang 19.1.x or later" | ||
#endif | ||
|
||
extern "C" uint64_t get_time() { | ||
return __builtin_readsteadycounter(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// Copyright(c) 2024 Qualcomm Innovation Center, Inc. All Rights Reserved. | ||
// SPDX-License-Identifier: BSD-3-Clause | ||
|
||
const builtin = @import("builtin"); | ||
|
||
// Ehh...it's not really the same thing between these | ||
// architectures, but ¯\_(ツ)_/¯ we are just illustrating | ||
// concepts here... | ||
|
||
export fn read_activity() u64 { | ||
if (comptime builtin.cpu.arch == .hexagon) { | ||
return asm volatile ("%[value] = upcycle" | ||
: [value] "=&r" (-> u64), | ||
); | ||
} else if (comptime builtin.cpu.arch == .x86_64) { | ||
var high: u64 = 0; | ||
var low: u64 = 0; | ||
|
||
asm volatile ( | ||
\\rdtsc | ||
: [low] "={eax}" (low), | ||
[high] "={edx}" (high), | ||
); | ||
return (@as(u64, high) << 32) | @as(u64, low); | ||
} else { | ||
const std = @import("std"); | ||
const msg = std.fmt.comptimePrint("unsupported architecture: '{s}'", .{@tagName(builtin.cpu.arch)}); | ||
|
||
@compileError(msg); | ||
} | ||
} |