11//! Assembly instructions
22
33macro_rules! instruction {
4- ( $( #[ $attr: meta] ) * , $fnname: ident, $asm: expr) => (
4+ ( $( #[ $attr: meta] ) * , unsafe $fnname: ident, $asm: expr) => (
55 $( #[ $attr] ) *
66 #[ inline]
77 pub unsafe fn $fnname( ) {
@@ -13,25 +13,42 @@ macro_rules! instruction {
1313 ( ) => unimplemented!( ) ,
1414 }
1515 }
16- )
16+ ) ;
17+ ( $( #[ $attr: meta] ) * , $fnname: ident, $asm: expr) => (
18+ $( #[ $attr] ) *
19+ #[ inline]
20+ pub fn $fnname( ) {
21+ match ( ) {
22+ #[ cfg( riscv) ]
23+ ( ) => unsafe { core:: arch:: asm!( $asm) } ,
24+
25+ #[ cfg( not( riscv) ) ]
26+ ( ) => unimplemented!( ) ,
27+ }
28+ }
29+ ) ;
1730}
1831
1932instruction ! (
2033 /// `nop` instruction wrapper
2134 ///
22- /// Generates a no-operation. Useful to prevent delay loops from being optimized away.
35+ /// The `NOP` instruction does not change any architecturally visible state, except for
36+ /// advancing the pc and incrementing any applicable performance counters.
37+ ///
38+ /// This function generates a no-operation; it's useful to prevent delay loops from being
39+ /// optimized away.
2340 , nop, "nop" ) ;
2441instruction ! (
2542 /// `EBREAK` instruction wrapper
2643 ///
2744 /// Generates a breakpoint exception.
28- , ebreak, "ebreak" ) ;
45+ , unsafe ebreak, "ebreak" ) ;
2946instruction ! (
3047 /// `WFI` instruction wrapper
3148 ///
3249 /// Provides a hint to the implementation that the current hart can be stalled until an interrupt might need servicing.
3350 /// The WFI instruction is just a hint, and a legal implementation is to implement WFI as a NOP.
34- , wfi, "wfi" ) ;
51+ , unsafe wfi, "wfi" ) ;
3552instruction ! (
3653 /// `SFENCE.VMA` instruction wrapper (all address spaces and page table levels)
3754 ///
@@ -40,7 +57,7 @@ instruction!(
4057 /// are ordinarily not ordered with respect to loads and stores in the instruction stream.
4158 /// Executing an `SFENCE.VMA` instruction guarantees that any stores in the instruction stream prior to the
4259 /// `SFENCE.VMA` are ordered before all implicit references subsequent to the `SFENCE.VMA`.
43- , sfence_vma_all, "sfence.vma" ) ;
60+ , unsafe sfence_vma_all, "sfence.vma" ) ;
4461instruction ! (
4562 /// `FENCE` instruction wrapper
4663 ///
@@ -54,7 +71,7 @@ instruction!(
5471 /// The FENCE instruction also orders memory reads and writes made by the hart as observed by
5572 /// memory reads and writes made by an external device. However, FENCE does not order observations
5673 /// of events made by an external device using any other signaling mechanism.
57- , fence, "fence" ) ;
74+ , unsafe fence, "fence" ) ;
5875instruction ! (
5976 /// `FENCE.I` instruction wrapper
6077 ///
@@ -72,7 +89,7 @@ instruction!(
7289 /// The unused fields in the FENCE.I instruction, imm\[11:0\], rs1, and rd, are reserved for
7390 /// finer-grain fences in future extensions. For forward compatibility, base
7491 /// implementations shall ignore these fields, and standard software shall zero these fields.
75- , fence_i, "fence.i" ) ;
92+ , unsafe fence_i, "fence.i" ) ;
7693
7794/// `SFENCE.VMA` instruction wrapper
7895///
@@ -104,10 +121,10 @@ pub unsafe fn sfence_vma(asid: usize, addr: usize) {
104121/// any other case please use a more accurate method to produce a delay.
105122#[ inline]
106123#[ allow( unused_variables) ]
107- pub unsafe fn delay ( cycles : u32 ) {
124+ pub fn delay ( cycles : u32 ) {
108125 match ( ) {
109126 #[ cfg( riscv) ]
110- ( ) => {
127+ ( ) => unsafe {
111128 let real_cyc = 1 + cycles / 2 ;
112129 core:: arch:: asm!(
113130 "1:" ,
@@ -116,7 +133,7 @@ pub unsafe fn delay(cycles: u32) {
116133 inout( reg) real_cyc => _,
117134 options( nomem, nostack) ,
118135 )
119- }
136+ } ,
120137
121138 #[ cfg( not( riscv) ) ]
122139 ( ) => unimplemented ! ( ) ,
0 commit comments