@@ -11,58 +11,40 @@ use stdarch_test::assert_instr;
11
11
12
12
/// Inserts a breakpoint instruction.
13
13
///
14
- /// `val` is a compile-time constant integer in range `[0, 255]`.
15
- ///
16
- /// The breakpoint instruction inserted is:
14
+ /// `val` is a compile-time constant integer in range `[0, 65535]`.
17
15
///
18
- /// * `BKPT` when compiling as T32,
19
- /// * `BRK` when compiling as A32 or A64.
16
+ /// The breakpoint instruction inserted is `BRK` on A64.
17
+ #[ cfg( target_arch = "aarch64" ) ]
18
+ #[ cfg_attr( test, assert_instr( brk, val = 0 ) ) ]
19
+ #[ inline( always) ]
20
+ #[ rustc_legacy_const_generics( 0 ) ]
21
+ pub unsafe fn __breakpoint < const val: i32 > ( ) {
22
+ static_assert_imm16 ! ( val) ;
23
+ asm ! ( "brk {}" , const val) ;
24
+ }
25
+
26
+ /// Inserts a breakpoint instruction.
20
27
///
21
- /// # Safety
28
+ /// `val` is a compile-time constant integer in range `[0, 255]`.
22
29
///
23
- /// If `val` is out-of-range the behavior is **undefined** .
30
+ /// The breakpoint instruction inserted is `BKPT` on A32/T32 .
24
31
///
25
32
/// # Note
26
33
///
27
34
/// [ARM's documentation][arm_docs] defines that `__breakpoint` accepts the
28
35
/// following values for `val`:
29
36
///
30
- /// - `0...65535` when compiling as A32 or A64 ,
37
+ /// - `0...65535` when compiling as A32,
31
38
/// - `0...255` when compiling as T32.
32
39
///
33
- /// The current implementation only accepts values in range `[0, 255]` - if the
34
- /// value is out-of-range the behavior is **undefined**.
40
+ /// The current implementation only accepts values in range `[0, 255]`.
35
41
///
36
42
/// [arm_docs]: https://developer.arm.com/docs/100067/latest/compiler-specific-intrinsics/__breakpoint-intrinsic
37
- #[ cfg_attr ( all ( test , target_arch = "arm" ) , assert_instr ( bkpt , val = 0 ) ) ]
38
- #[ cfg_attr( all ( test, target_arch = "aarch64" ) , assert_instr( brk , val = 0 ) ) ]
43
+ #[ cfg ( target_arch = "arm" ) ]
44
+ #[ cfg_attr( test, assert_instr( bkpt , val = 0 ) ) ]
39
45
#[ inline( always) ]
40
- #[ rustc_args_required_const( 0 ) ]
41
- pub unsafe fn __breakpoint ( val : i32 ) {
42
- // Ensure that this compiles correctly on non-arm architectures, so libstd
43
- // doc builds work. The proper macro will shadow this definition below.
44
- #[ allow( unused_macros) ]
45
- macro_rules! call {
46
- ( $e: expr) => {
47
- ( )
48
- } ;
49
- }
50
-
51
- #[ cfg( target_arch = "arm" ) ]
52
- macro_rules! call {
53
- ( $imm8: expr) => {
54
- llvm_asm!( concat!( "BKPT " , stringify!( $imm8) ) : : : : "volatile" )
55
- }
56
- }
57
-
58
- #[ cfg( target_arch = "aarch64" ) ]
59
- macro_rules! call {
60
- ( $imm8: expr) => {
61
- llvm_asm!( concat!( "BRK " , stringify!( $imm8) ) : : : : "volatile" )
62
- }
63
- }
64
-
65
- // We can't `panic!` inside this intrinsic, so we can't really validate the
66
- // arguments here. If `val` is out-of-range this macro uses `val == 255`:
67
- constify_imm8 ! ( val, call) ;
46
+ #[ rustc_legacy_const_generics( 0 ) ]
47
+ pub unsafe fn __breakpoint < const val: i32 > ( ) {
48
+ static_assert_imm8 ! ( val) ;
49
+ asm ! ( "bkpt #{}" , const val) ;
68
50
}
0 commit comments