1
1
//! Assembly instructions
2
2
3
3
macro_rules! instruction {
4
- ( $( #[ $attr: meta] ) * , $fnname: ident, $asm: expr) => (
4
+ ( $( #[ $attr: meta] ) * , unsafe $fnname: ident, $asm: expr) => (
5
5
$( #[ $attr] ) *
6
6
#[ inline]
7
7
pub unsafe fn $fnname( ) {
@@ -13,25 +13,42 @@ macro_rules! instruction {
13
13
( ) => unimplemented!( ) ,
14
14
}
15
15
}
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
+ ) ;
17
30
}
18
31
19
32
instruction ! (
20
33
/// `nop` instruction wrapper
21
34
///
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.
23
40
, nop, "nop" ) ;
24
41
instruction ! (
25
42
/// `EBREAK` instruction wrapper
26
43
///
27
44
/// Generates a breakpoint exception.
28
- , ebreak, "ebreak" ) ;
45
+ , unsafe ebreak, "ebreak" ) ;
29
46
instruction ! (
30
47
/// `WFI` instruction wrapper
31
48
///
32
49
/// Provides a hint to the implementation that the current hart can be stalled until an interrupt might need servicing.
33
50
/// 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" ) ;
35
52
instruction ! (
36
53
/// `SFENCE.VMA` instruction wrapper (all address spaces and page table levels)
37
54
///
@@ -40,7 +57,7 @@ instruction!(
40
57
/// are ordinarily not ordered with respect to loads and stores in the instruction stream.
41
58
/// Executing an `SFENCE.VMA` instruction guarantees that any stores in the instruction stream prior to the
42
59
/// `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" ) ;
44
61
instruction ! (
45
62
/// `FENCE` instruction wrapper
46
63
///
@@ -54,7 +71,7 @@ instruction!(
54
71
/// The FENCE instruction also orders memory reads and writes made by the hart as observed by
55
72
/// memory reads and writes made by an external device. However, FENCE does not order observations
56
73
/// of events made by an external device using any other signaling mechanism.
57
- , fence, "fence" ) ;
74
+ , unsafe fence, "fence" ) ;
58
75
instruction ! (
59
76
/// `FENCE.I` instruction wrapper
60
77
///
@@ -72,7 +89,7 @@ instruction!(
72
89
/// The unused fields in the FENCE.I instruction, imm\[11:0\], rs1, and rd, are reserved for
73
90
/// finer-grain fences in future extensions. For forward compatibility, base
74
91
/// implementations shall ignore these fields, and standard software shall zero these fields.
75
- , fence_i, "fence.i" ) ;
92
+ , unsafe fence_i, "fence.i" ) ;
76
93
77
94
/// `SFENCE.VMA` instruction wrapper
78
95
///
@@ -104,10 +121,10 @@ pub unsafe fn sfence_vma(asid: usize, addr: usize) {
104
121
/// any other case please use a more accurate method to produce a delay.
105
122
#[ inline]
106
123
#[ allow( unused_variables) ]
107
- pub unsafe fn delay ( cycles : u32 ) {
124
+ pub fn delay ( cycles : u32 ) {
108
125
match ( ) {
109
126
#[ cfg( riscv) ]
110
- ( ) => {
127
+ ( ) => unsafe {
111
128
let real_cyc = 1 + cycles / 2 ;
112
129
core:: arch:: asm!(
113
130
"1:" ,
@@ -116,7 +133,7 @@ pub unsafe fn delay(cycles: u32) {
116
133
inout( reg) real_cyc => _,
117
134
options( nomem, nostack) ,
118
135
)
119
- }
136
+ } ,
120
137
121
138
#[ cfg( not( riscv) ) ]
122
139
( ) => unimplemented ! ( ) ,
0 commit comments