From bb8db13892ced757faf1c0206c70f313cd4b23c0 Mon Sep 17 00:00:00 2001 From: Julian Frimmel Date: Tue, 15 Oct 2024 21:04:06 +0200 Subject: [PATCH] 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. --- .../avr-rjmp-offset/avr-rjmp-offsets.rs | 19 ++--------- tests/run-make/avr-rjmp-offset/rmake.rs | 33 ++++++++++++++++--- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/tests/run-make/avr-rjmp-offset/avr-rjmp-offsets.rs b/tests/run-make/avr-rjmp-offset/avr-rjmp-offsets.rs index d0e5ef1997380..2f97fc1ed95ab 100644 --- a/tests/run-make/avr-rjmp-offset/avr-rjmp-offsets.rs +++ b/tests/run-make/avr-rjmp-offset/avr-rjmp-offsets.rs @@ -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"] diff --git a/tests/run-make/avr-rjmp-offset/rmake.rs b/tests/run-make/avr-rjmp-offset/rmake.rs index 666aa41ef4176..28018f59c5bb6 100644 --- a/tests/run-make/avr-rjmp-offset/rmake.rs +++ b/tests/run-make/avr-rjmp-offset/rmake.rs @@ -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
: + // 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("
")) + .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}`" + ); + }); }