@@ -10,6 +10,7 @@ use crate::traits::*;
1010use crate :: MemFlags ;
1111
1212use rustc_ast as ast;
13+ use rustc_ast:: { InlineAsmOptions , InlineAsmTemplatePiece } ;
1314use rustc_hir:: lang_items:: LangItem ;
1415use rustc_index:: vec:: Idx ;
1516use rustc_middle:: mir:: AssertKind ;
@@ -174,6 +175,45 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
174175 }
175176 }
176177 }
178+
179+ /// Generates inline assembly with optional `destination` and `cleanup`.
180+ fn do_inlineasm < Bx : BuilderMethods < ' a , ' tcx > > (
181+ & self ,
182+ fx : & mut FunctionCx < ' a , ' tcx , Bx > ,
183+ bx : & mut Bx ,
184+ template : & [ InlineAsmTemplatePiece ] ,
185+ operands : & [ InlineAsmOperandRef < ' tcx , Bx > ] ,
186+ options : InlineAsmOptions ,
187+ line_spans : & [ Span ] ,
188+ destination : Option < mir:: BasicBlock > ,
189+ cleanup : Option < mir:: BasicBlock > ,
190+ instance : Instance < ' _ > ,
191+ ) {
192+ if let Some ( cleanup) = cleanup {
193+ let ret_llbb = if let Some ( target) = destination {
194+ fx. llbb ( target)
195+ } else {
196+ fx. unreachable_block ( )
197+ } ;
198+
199+ bx. codegen_inline_asm (
200+ template,
201+ & operands,
202+ options,
203+ line_spans,
204+ instance,
205+ Some ( ( ret_llbb, self . llblock ( fx, cleanup) , self . funclet ( fx) ) ) ,
206+ ) ;
207+ } else {
208+ bx. codegen_inline_asm ( template, & operands, options, line_spans, instance, None ) ;
209+
210+ if let Some ( target) = destination {
211+ self . funclet_br ( fx, bx, target) ;
212+ } else {
213+ bx. unreachable ( ) ;
214+ }
215+ }
216+ }
177217}
178218
179219/// Codegen implementations for some terminator variants.
@@ -877,6 +917,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
877917 options : ast:: InlineAsmOptions ,
878918 line_spans : & [ Span ] ,
879919 destination : Option < mir:: BasicBlock > ,
920+ cleanup : Option < mir:: BasicBlock > ,
880921 instance : Instance < ' _ > ,
881922 ) {
882923 let span = terminator. source_info . span ;
@@ -931,13 +972,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
931972 } )
932973 . collect ( ) ;
933974
934- bx. codegen_inline_asm ( template, & operands, options, line_spans, instance) ;
935-
936- if let Some ( target) = destination {
937- helper. funclet_br ( self , & mut bx, target) ;
938- } else {
939- bx. unreachable ( ) ;
940- }
975+ helper. do_inlineasm (
976+ self ,
977+ & mut bx,
978+ template,
979+ & operands,
980+ options,
981+ line_spans,
982+ destination,
983+ cleanup,
984+ instance,
985+ ) ;
941986 }
942987}
943988
@@ -1041,7 +1086,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
10411086 options,
10421087 line_spans,
10431088 destination,
1044- cleanup : _ , // TODO
1089+ cleanup,
10451090 } => {
10461091 self . codegen_asm_terminator (
10471092 helper,
@@ -1052,6 +1097,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
10521097 options,
10531098 line_spans,
10541099 destination,
1100+ cleanup,
10551101 self . instance ,
10561102 ) ;
10571103 }
0 commit comments