@@ -8,6 +8,7 @@ use rustc_span::sym;
8
8
use rustc_target:: asm:: * ;
9
9
use target_lexicon:: BinaryFormat ;
10
10
11
+ use crate :: global_asm:: asm_supported;
11
12
use crate :: prelude:: * ;
12
13
13
14
enum CInlineAsmOperand < ' tcx > {
@@ -44,9 +45,13 @@ pub(crate) fn codegen_inline_asm<'tcx>(
44
45
) {
45
46
// FIXME add .eh_frame unwind info directives
46
47
47
- if !template. is_empty ( )
48
- && ( cfg ! ( not( feature = "inline_asm" ) ) || fx. tcx . sess . target . is_like_windows )
49
- {
48
+ if !asm_supported ( fx. tcx ) {
49
+ if template. is_empty ( ) {
50
+ let destination_block = fx. get_block ( destination. unwrap ( ) ) ;
51
+ fx. bcx . ins ( ) . jump ( destination_block, & [ ] ) ;
52
+ return ;
53
+ }
54
+
50
55
// Used by panic_abort
51
56
if template[ 0 ] == InlineAsmTemplatePiece :: String ( "int $$0x29" . to_string ( ) ) {
52
57
fx. bcx . ins ( ) . trap ( TrapCode :: User ( 1 ) ) ;
@@ -144,6 +149,16 @@ pub(crate) fn codegen_inline_asm<'tcx>(
144
149
return ;
145
150
}
146
151
152
+ // Used by core::hint::spin_loop()
153
+ if template[ 0 ]
154
+ == InlineAsmTemplatePiece :: String ( ".insn i 0x0F, 0, x0, x0, 0x010" . to_string ( ) )
155
+ && template. len ( ) == 1
156
+ {
157
+ let destination_block = fx. get_block ( destination. unwrap ( ) ) ;
158
+ fx. bcx . ins ( ) . jump ( destination_block, & [ ] ) ;
159
+ return ;
160
+ }
161
+
147
162
// Used by measureme
148
163
if template[ 0 ] == InlineAsmTemplatePiece :: String ( "xor %eax, %eax" . to_string ( ) )
149
164
&& template[ 1 ] == InlineAsmTemplatePiece :: String ( "\n " . to_string ( ) )
@@ -223,6 +238,16 @@ pub(crate) fn codegen_inline_asm<'tcx>(
223
238
fx. bcx . ins ( ) . jump ( destination_block, & [ ] ) ;
224
239
return ;
225
240
}
241
+
242
+ if cfg ! ( not( feature = "inline_asm" ) ) {
243
+ fx. tcx . sess . span_err (
244
+ span,
245
+ "asm! and global_asm! support is disabled while compiling rustc_codegen_cranelift" ,
246
+ ) ;
247
+ } else {
248
+ fx. tcx . sess . span_err ( span, "asm! and global_asm! are not yet supported on Windows" ) ;
249
+ }
250
+ return ;
226
251
}
227
252
228
253
let operands = operands
@@ -745,6 +770,13 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
745
770
// x19 is reserved by LLVM for the "base pointer", so rustc doesn't allow using it
746
771
generated_asm. push_str ( " mov x19, x0\n " ) ;
747
772
}
773
+ InlineAsmArch :: RiscV64 => {
774
+ generated_asm. push_str ( " addi sp, sp, -16\n " ) ;
775
+ generated_asm. push_str ( " sd ra, 8(sp)\n " ) ;
776
+ generated_asm. push_str ( " sd s1, 0(sp)\n " ) ; // s1 is callee saved
777
+ // s1/x9 is reserved by LLVM for the "base pointer", so rustc doesn't allow using it
778
+ generated_asm. push_str ( " mv s1, a0\n " ) ;
779
+ }
748
780
_ => unimplemented ! ( "prologue for {:?}" , arch) ,
749
781
}
750
782
}
@@ -761,6 +793,12 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
761
793
generated_asm. push_str ( " ldp fp, lr, [sp], #32\n " ) ;
762
794
generated_asm. push_str ( " ret\n " ) ;
763
795
}
796
+ InlineAsmArch :: RiscV64 => {
797
+ generated_asm. push_str ( " ld s1, 0(sp)\n " ) ;
798
+ generated_asm. push_str ( " ld ra, 8(sp)\n " ) ;
799
+ generated_asm. push_str ( " addi sp, sp, 16\n " ) ;
800
+ generated_asm. push_str ( " ret\n " ) ;
801
+ }
764
802
_ => unimplemented ! ( "epilogue for {:?}" , arch) ,
765
803
}
766
804
}
@@ -771,7 +809,10 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
771
809
generated_asm. push_str ( " ud2\n " ) ;
772
810
}
773
811
InlineAsmArch :: AArch64 => {
774
- generated_asm. push_str ( " brk #0x1" ) ;
812
+ generated_asm. push_str ( " brk #0x1\n " ) ;
813
+ }
814
+ InlineAsmArch :: RiscV64 => {
815
+ generated_asm. push_str ( " ebreak\n " ) ;
775
816
}
776
817
_ => unimplemented ! ( "epilogue_noreturn for {:?}" , arch) ,
777
818
}
@@ -794,6 +835,11 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
794
835
reg. emit ( generated_asm, InlineAsmArch :: AArch64 , None ) . unwrap ( ) ;
795
836
writeln ! ( generated_asm, ", [x19, 0x{:x}]" , offset. bytes( ) ) . unwrap ( ) ;
796
837
}
838
+ InlineAsmArch :: RiscV64 => {
839
+ generated_asm. push_str ( " sd " ) ;
840
+ reg. emit ( generated_asm, InlineAsmArch :: RiscV64 , None ) . unwrap ( ) ;
841
+ writeln ! ( generated_asm, ", 0x{:x}(s1)" , offset. bytes( ) ) . unwrap ( ) ;
842
+ }
797
843
_ => unimplemented ! ( "save_register for {:?}" , arch) ,
798
844
}
799
845
}
@@ -815,6 +861,11 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
815
861
reg. emit ( generated_asm, InlineAsmArch :: AArch64 , None ) . unwrap ( ) ;
816
862
writeln ! ( generated_asm, ", [x19, 0x{:x}]" , offset. bytes( ) ) . unwrap ( ) ;
817
863
}
864
+ InlineAsmArch :: RiscV64 => {
865
+ generated_asm. push_str ( " ld " ) ;
866
+ reg. emit ( generated_asm, InlineAsmArch :: RiscV64 , None ) . unwrap ( ) ;
867
+ writeln ! ( generated_asm, ", 0x{:x}(s1)" , offset. bytes( ) ) . unwrap ( ) ;
868
+ }
818
869
_ => unimplemented ! ( "restore_register for {:?}" , arch) ,
819
870
}
820
871
}
0 commit comments