Simplify test and make it more reliable

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.
This commit is contained in:
Julian Frimmel 2024-10-15 21:04:06 +02:00
parent ab008414d4
commit bb8db13892
No known key found for this signature in database
2 changed files with 31 additions and 21 deletions

View File

@ -1,17 +1,12 @@
//! 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]
#![allow(internal_features)]
#[rustc_builtin_macro]
macro_rules! asm {
() => {};
}
use minicore::ptr;
#[no_mangle]
@ -23,18 +18,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"]

View File

@ -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}`"
);
});
}