Skip to content

Commit c2b16ed

Browse files
committed
add x86_64 and arm assembly transpilation tests
1 parent 1436b14 commit c2b16ed

File tree

10 files changed

+148
-0
lines changed

10 files changed

+148
-0
lines changed

tests/asm.arm/Cargo.toml

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[package]
2+
name = "asm-tests"
3+
version = "0.1.0"
4+
5+
[dependencies]
6+
libc = "0.2"

tests/asm.arm/build.rs

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
use std::env;
2+
3+
fn main() {
4+
let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
5+
6+
println!("cargo:rustc-link-search=native={}", manifest_dir);
7+
}

tests/asm.arm/src/asm.c

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/* test.c */
2+
typedef unsigned int uint32_t;
3+
typedef unsigned char uint8_t;
4+
5+
uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
6+
{
7+
uint32_t result;
8+
9+
asm volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) );
10+
return(result);
11+
}
12+
13+
void entry(const unsigned int buffer_size, int buffer[const])
14+
{
15+
int i = 0;
16+
17+
//uint32_t 0xfedcba98
18+
uint8_t dest = 0;
19+
__STREXB(5, &dest);
20+
buffer[i++] = dest;
21+
}

tests/asm.arm/src/test_asm.rs

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//! feature_asm
2+
3+
extern crate libc;
4+
5+
use asm::rust_entry;
6+
use self::libc::{c_int, c_uint};
7+
8+
#[link(name = "test")]
9+
extern "C" {
10+
fn entry(_: c_uint, _: *mut c_int);
11+
}
12+
13+
const BUFFER_SIZE: usize = 1;
14+
15+
pub fn test_buffer() {
16+
let mut buffer = [0; BUFFER_SIZE];
17+
let mut rust_buffer = [0; BUFFER_SIZE];
18+
let expected_buffer = [5];
19+
20+
unsafe {
21+
entry(BUFFER_SIZE as u32, buffer.as_mut_ptr());
22+
rust_entry(BUFFER_SIZE as u32, rust_buffer.as_mut_ptr());
23+
}
24+
25+
assert_eq!(buffer, rust_buffer);
26+
assert_eq!(buffer, expected_buffer);
27+
}

tests/asm.arm/target-tuple

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
arm-unknown-linux-gnueabihf

tests/asm.x86_64/Cargo.toml

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[package]
2+
name = "asm-tests"
3+
version = "0.1.0"
4+
5+
[dependencies]
6+
libc = "0.2"
7+
c2rust-asm-casts = { path = "../../c2rust-asm-casts" }

tests/asm.x86_64/build.rs

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
use std::env;
2+
3+
fn main() {
4+
let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
5+
6+
println!("cargo:rustc-link-search=native={}", manifest_dir);
7+
}

tests/asm.x86_64/src/asm.c

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/* asm.c */
2+
#include <stdint.h>
3+
4+
// from https://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html#s2
5+
6+
/* We want to multiply a number by 5. For that we use the instruction lea. */
7+
int mul5_1(int x) {
8+
int five_times_x;
9+
asm ("leal (%k1,%k1,4), %k0"
10+
: "=r" (five_times_x)
11+
: "r" (x)
12+
);
13+
return five_times_x;
14+
}
15+
16+
/* Here our input is in ’x’. We didn’t specify the register to be used. GCC will choose some register for input, one for output and does what we desired. If we want the input and output to reside in the same register, we can instruct GCC to do so. Here we use those types of read-write operands. By specifying proper constraints, here we do it. */
17+
18+
int mul5_2(int x) {
19+
int five_times_x;
20+
asm ("leal (%k0,%k0,4), %k0"
21+
: "=r" (five_times_x)
22+
: "0" (x)
23+
);
24+
return five_times_x;
25+
}
26+
27+
// Now the input and output operands are in the same register. But we don’t know which register. Now if we want to specify that also, there is a way.
28+
29+
int mul5_3(int x) {
30+
asm ("leal (%%ecx,%%ecx,4), %%ecx"
31+
: "=c" (x)
32+
: "c" (x)
33+
);
34+
return x;
35+
}
36+
37+
void entry(const unsigned int buffer_size, int buffer[const])
38+
{
39+
int i = 0;
40+
41+
buffer[i++] = mul5_1(48605);
42+
buffer[i++] = mul5_2(13014);
43+
buffer[i++] = mul5_3(10290);
44+
}

tests/asm.x86_64/src/test_asm.rs

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//! extern_crate_c2rust_asm_casts
2+
//! feature_asm
3+
extern crate libc;
4+
5+
use asm::rust_entry;
6+
use self::libc::{c_int, c_uint};
7+
8+
#[link(name = "test")]
9+
extern "C" {
10+
fn entry(_: c_uint, _: *mut c_int);
11+
}
12+
13+
const BUFFER_SIZE: usize = 3;
14+
15+
pub fn test_buffer() {
16+
let mut buffer = [0; BUFFER_SIZE];
17+
let mut rust_buffer = [0; BUFFER_SIZE];
18+
let expected_buffer = [243025, 65070, 51450];
19+
20+
unsafe {
21+
entry(BUFFER_SIZE as u32, buffer.as_mut_ptr());
22+
rust_entry(BUFFER_SIZE as u32, rust_buffer.as_mut_ptr());
23+
}
24+
25+
assert_eq!(buffer, rust_buffer);
26+
assert_eq!(buffer, expected_buffer);
27+
}

tests/asm.x86_64/target-tuple

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
x86_64-unknown-linux-gnu

0 commit comments

Comments
 (0)