Skip to content

Commit

Permalink
Simplify test and make it more reliable
Browse files Browse the repository at this point in the history
The new `rmake`-content asserts the exact assembly sequence for the loop
preventing false-negatives if some instructions would change and thus
the label offset might need to change.
  • Loading branch information
jfrimmel committed Oct 16, 2024
1 parent 6982676 commit 1d16289
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 21 deletions.
19 changes: 3 additions & 16 deletions tests/run-make/avr-rjmp-offset/avr-rjmp-offsets.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
//! This test case is a `#![no_core]`-version of the MVCE presented in #129301.
//!
//! The function [`delay()`] is minimized and does not actually contain a loop
//! in order to remove the need for additional lang items.
#![feature(no_core, lang_items, intrinsics, rustc_attrs, asm_experimental_arch)]
//! The function [`delay()`] is removed, as it is not necessary to trigger the
//! wrong behavior and would require some additional lang items.
#![feature(no_core, lang_items, intrinsics, rustc_attrs)]
#![no_core]
#![no_main]

#[rustc_builtin_macro]
macro_rules! asm {
() => {};
}

use minicore::ptr;

#[no_mangle]
Expand All @@ -22,18 +17,10 @@ pub fn main() -> ! {
// sions did place it after the first loop instruction, causing unsoundness)
loop {
unsafe { ptr::write_volatile(port_b, 1) };
delay(500_0000);
unsafe { ptr::write_volatile(port_b, 2) };
delay(500_0000);
}
}

#[inline(never)]
#[no_mangle]
fn delay(_: u32) {
unsafe { asm!("nop") };
}

// FIXME: replace with proper minicore once available (#130693)
mod minicore {
#[lang = "sized"]
Expand Down
33 changes: 28 additions & 5 deletions tests/run-make/avr-rjmp-offset/rmake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,32 @@ fn main() {
.output("compiled")
.run();

llvm_objdump()
.disassemble()
.input("compiled")
.run()
.assert_stdout_contains_regex(r"rjmp.*\.-14");
let disassembly = llvm_objdump().disassemble().input("compiled").run().stdout_utf8();

// search for the following instruction sequence:
// ```disassembly
// 00000080 <main>:
// 80: 81 e0 ldi r24, 0x1
// 82: 92 e0 ldi r25, 0x2
// 84: 85 b9 out 0x5, r24
// 86: 95 b9 out 0x5, r25
// 88: fd cf rjmp .-6
// ```
// This matches on all instructions, since the size of the instructions be-
// fore the relative jump has an impact on the label offset. Old versions
// of the Rust compiler did produce a label `rjmp .-4` (misses the first
// instruction in the loop).
disassembly
.trim()
.lines()
.skip_while(|&line| !line.contains("<main>"))
.inspect(|line| println!("{line}"))
.skip(1)
.zip(["ldi\t", "ldi\t", "out\t", "out\t", "rjmp\t.-6"])
.for_each(|(line, expected_instruction)| {
assert!(
line.contains(expected_instruction),
"expected instruction `{expected_instruction}`, got `{line}`"
);
});
}

0 comments on commit 1d16289

Please sign in to comment.