LLVM codgen support for unwinding inline assembly
This commit is contained in:
parent
491dd1f387
commit
91021de1f6
7 changed files with 109 additions and 18 deletions
|
@ -276,9 +276,9 @@ pub fn cleanup_kinds(mir: &mir::Body<'_>) -> IndexVec<mir::BasicBlock, CleanupKi
|
|||
| TerminatorKind::SwitchInt { .. }
|
||||
| TerminatorKind::Yield { .. }
|
||||
| TerminatorKind::FalseEdge { .. }
|
||||
| TerminatorKind::FalseUnwind { .. }
|
||||
| TerminatorKind::InlineAsm { .. } => { /* nothing to do */ }
|
||||
| TerminatorKind::FalseUnwind { .. } => { /* nothing to do */ }
|
||||
TerminatorKind::Call { cleanup: unwind, .. }
|
||||
| TerminatorKind::InlineAsm { cleanup: unwind, .. }
|
||||
| TerminatorKind::Assert { cleanup: unwind, .. }
|
||||
| TerminatorKind::DropAndReplace { unwind, .. }
|
||||
| TerminatorKind::Drop { unwind, .. } => {
|
||||
|
|
|
@ -10,6 +10,7 @@ use crate::traits::*;
|
|||
use crate::MemFlags;
|
||||
|
||||
use rustc_ast as ast;
|
||||
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
use rustc_index::vec::Idx;
|
||||
use rustc_middle::mir::AssertKind;
|
||||
|
@ -174,6 +175,45 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Generates inline assembly with optional `destination` and `cleanup`.
|
||||
fn do_inlineasm<Bx: BuilderMethods<'a, 'tcx>>(
|
||||
&self,
|
||||
fx: &mut FunctionCx<'a, 'tcx, Bx>,
|
||||
bx: &mut Bx,
|
||||
template: &[InlineAsmTemplatePiece],
|
||||
operands: &[InlineAsmOperandRef<'tcx, Bx>],
|
||||
options: InlineAsmOptions,
|
||||
line_spans: &[Span],
|
||||
destination: Option<mir::BasicBlock>,
|
||||
cleanup: Option<mir::BasicBlock>,
|
||||
instance: Instance<'_>,
|
||||
) {
|
||||
if let Some(cleanup) = cleanup {
|
||||
let ret_llbb = if let Some(target) = destination {
|
||||
fx.llbb(target)
|
||||
} else {
|
||||
fx.unreachable_block()
|
||||
};
|
||||
|
||||
bx.codegen_inline_asm(
|
||||
template,
|
||||
&operands,
|
||||
options,
|
||||
line_spans,
|
||||
instance,
|
||||
Some((ret_llbb, self.llblock(fx, cleanup), self.funclet(fx))),
|
||||
);
|
||||
} else {
|
||||
bx.codegen_inline_asm(template, &operands, options, line_spans, instance, None);
|
||||
|
||||
if let Some(target) = destination {
|
||||
self.funclet_br(fx, bx, target);
|
||||
} else {
|
||||
bx.unreachable();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Codegen implementations for some terminator variants.
|
||||
|
@ -877,6 +917,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
options: ast::InlineAsmOptions,
|
||||
line_spans: &[Span],
|
||||
destination: Option<mir::BasicBlock>,
|
||||
cleanup: Option<mir::BasicBlock>,
|
||||
instance: Instance<'_>,
|
||||
) {
|
||||
let span = terminator.source_info.span;
|
||||
|
@ -931,13 +972,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
})
|
||||
.collect();
|
||||
|
||||
bx.codegen_inline_asm(template, &operands, options, line_spans, instance);
|
||||
|
||||
if let Some(target) = destination {
|
||||
helper.funclet_br(self, &mut bx, target);
|
||||
} else {
|
||||
bx.unreachable();
|
||||
}
|
||||
helper.do_inlineasm(
|
||||
self,
|
||||
&mut bx,
|
||||
template,
|
||||
&operands,
|
||||
options,
|
||||
line_spans,
|
||||
destination,
|
||||
cleanup,
|
||||
instance,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1041,7 +1086,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
options,
|
||||
line_spans,
|
||||
destination,
|
||||
cleanup: _, // TODO
|
||||
cleanup,
|
||||
} => {
|
||||
self.codegen_asm_terminator(
|
||||
helper,
|
||||
|
@ -1052,6 +1097,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
options,
|
||||
line_spans,
|
||||
destination,
|
||||
cleanup,
|
||||
self.instance,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -59,6 +59,7 @@ pub trait AsmBuilderMethods<'tcx>: BackendTypes {
|
|||
options: InlineAsmOptions,
|
||||
line_spans: &[Span],
|
||||
instance: Instance<'_>,
|
||||
dest_catch_funclet: Option<(Self::BasicBlock, Self::BasicBlock, Option<&Self::Funclet>)>,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue