| // Check that `cfg` and `cfg_attr` work as expected. |
| // |
| //@ revisions: reva revb |
| //@ only-x86_64 |
| //@ run-pass |
| #![feature(asm_cfg, cfg_select)] |
| |
| use std::arch::{asm, naked_asm}; |
| |
| #[unsafe(naked)] |
| extern "C" fn ignore_const_operand() -> u64 { |
| naked_asm!( |
| "mov rax, 5", |
| #[cfg(revb)] |
| "mov rax, {a}", |
| "ret", |
| #[cfg(revb)] |
| a = const 10, |
| ) |
| } |
| |
| #[unsafe(naked)] |
| extern "C" fn ignore_const_operand_cfg_attr() -> u64 { |
| naked_asm!( |
| "mov rax, 5", |
| #[cfg_attr(true, cfg(revb))] |
| "mov rax, {a}", |
| "ret", |
| #[cfg_attr(true, cfg(revb))] |
| a = const 10, |
| ) |
| } |
| |
| #[unsafe(naked)] |
| extern "C" fn const_operand() -> u64 { |
| naked_asm!( |
| "mov rax, {a}", |
| "ret", |
| #[cfg(reva)] |
| a = const 5, |
| #[cfg(revb)] |
| a = const 10, |
| ) |
| } |
| |
| fn options() { |
| // Without the cfg, this throws an error that the `att_syntax` option is provided twice. |
| unsafe { |
| asm!( |
| "nop", |
| #[cfg(false)] |
| options(att_syntax), |
| options(att_syntax) |
| ) |
| } |
| } |
| |
| fn clobber_abi() { |
| // Without the cfg, this throws an error that the "C" abi is provided twice. |
| unsafe { |
| asm!( |
| "nop", |
| #[cfg(false)] |
| clobber_abi("C"), |
| clobber_abi("C"), |
| ); |
| } |
| } |
| |
| #[unsafe(naked)] |
| extern "C" fn first_template() -> u64 { |
| naked_asm!( |
| #[cfg(reva)] |
| "mov rax, 5", |
| #[cfg(revb)] |
| "mov rax, 10", |
| "ret", |
| ) |
| } |
| |
| #[unsafe(naked)] |
| extern "C" fn true_and_false() -> u64 { |
| naked_asm!( |
| "mov rax, 5", |
| #[cfg(true)] |
| #[cfg(false)] |
| "mov rax, 10", |
| "ret", |
| ) |
| } |
| |
| #[unsafe(naked)] |
| extern "C" fn false_and_true() -> u64 { |
| naked_asm!( |
| "mov rax, 5", |
| #[cfg(false)] |
| #[cfg(true)] |
| "mov rax, 10", |
| "ret", |
| ) |
| } |
| |
| pub fn main() { |
| std::cfg_select! { |
| reva => { |
| assert_eq!(const_operand(), 5); |
| assert_eq!(ignore_const_operand_cfg_attr(), 5); |
| assert_eq!(ignore_const_operand(), 5); |
| assert_eq!(first_template(), 5); |
| |
| } |
| revb => { |
| assert_eq!(const_operand(), 10); |
| assert_eq!(ignore_const_operand_cfg_attr(), 10); |
| assert_eq!(ignore_const_operand(), 10); |
| assert_eq!(first_template(), 10); |
| |
| } |
| } |
| options(); |
| clobber_abi(); |
| |
| assert_eq!(true_and_false(), 5); |
| assert_eq!(false_and_true(), 5); |
| } |