@@ -114,7 +114,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
114114 options : InlineAsmOptions ,
115115 span : & [ Span ] ,
116116 instance : Instance < ' _ > ,
117- _dest_catch_funclet : Option < ( Self :: BasicBlock , Self :: BasicBlock , Option < & Self :: Funclet > ) > ,
117+ _catch_funclet : Option < ( Self :: BasicBlock , Self :: BasicBlock , Option < & Self :: Funclet > ) > ,
118118 ) {
119119 if options. contains ( InlineAsmOptions :: MAY_UNWIND ) {
120120 self . sess ( ) . dcx ( ) . create_err ( UnwindingInlineAsm { span : span[ 0 ] } ) . emit ( ) ;
@@ -132,6 +132,10 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
132132 // added to `outputs.len()`
133133 let mut inputs = vec ! [ ] ;
134134
135+ // GCC index of a label equals its position in the array added to
136+ // `outputs.len() + inputs.len()`.
137+ let mut labels = vec ! [ ] ;
138+
135139 // Clobbers collected from `out("explicit register") _` and `inout("expl_reg") var => _`
136140 let mut clobbers = vec ! [ ] ;
137141
@@ -283,6 +287,10 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
283287 constants_len +=
284288 self . tcx . symbol_name ( Instance :: mono ( self . tcx , def_id) ) . name . len ( ) ;
285289 }
290+
291+ InlineAsmOperandRef :: Label { label } => {
292+ labels. push ( label) ;
293+ }
286294 }
287295 }
288296
@@ -381,6 +389,10 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
381389 InlineAsmOperandRef :: Const { .. } => {
382390 // processed in the previous pass
383391 }
392+
393+ InlineAsmOperandRef :: Label { .. } => {
394+ // processed in the previous pass
395+ }
384396 }
385397 }
386398
@@ -470,6 +482,14 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
470482 InlineAsmOperandRef :: Const { ref string } => {
471483 template_str. push_str ( string) ;
472484 }
485+
486+ InlineAsmOperandRef :: Label { label } => {
487+ let label_gcc_index = labels. iter ( )
488+ . position ( |& l| l == label)
489+ . expect ( "wrong rust index" ) ;
490+ let gcc_index = label_gcc_index + outputs. len ( ) + inputs. len ( ) ;
491+ push_to_template ( Some ( 'l' ) , gcc_index) ;
492+ }
473493 }
474494 }
475495 }
@@ -482,7 +502,12 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
482502 // 4. Generate Extended Asm block
483503
484504 let block = self . llbb ( ) ;
485- let extended_asm = block. add_extended_asm ( None , & template_str) ;
505+ let extended_asm = if let Some ( dest) = dest {
506+ assert ! ( !labels. is_empty( ) ) ;
507+ block. end_with_extended_asm_goto ( None , & template_str, & labels, Some ( dest) )
508+ } else {
509+ block. add_extended_asm ( None , & template_str)
510+ } ;
486511
487512 for op in & outputs {
488513 extended_asm. add_output_operand ( None , & op. to_constraint ( ) , op. tmp_var ) ;
@@ -510,7 +535,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
510535 if !options. contains ( InlineAsmOptions :: NOSTACK ) {
511536 // TODO(@Commeownist): figure out how to align stack
512537 }
513- if options. contains ( InlineAsmOptions :: NORETURN ) {
538+ if dest . is_none ( ) && options. contains ( InlineAsmOptions :: NORETURN ) {
514539 let builtin_unreachable = self . context . get_builtin_function ( "__builtin_unreachable" ) ;
515540 let builtin_unreachable: RValue < ' gcc > =
516541 unsafe { std:: mem:: transmute ( builtin_unreachable) } ;
0 commit comments