Rollup merge of #119365 - nbdd0121:asm-goto, r=Amanieu
Add asm goto support to `asm!` Tracking issue: #119364 This PR implements asm-goto support, using the syntax described in "future possibilities" section of [RFC2873](https://rust-lang.github.io/rfcs/2873-inline-asm.html#asm-goto). Currently I have only implemented the `label` part, not the `fallthrough` part (i.e. fallthrough is implicit). This doesn't reduce the expressive though, since you can use label-break to get arbitrary control flow or simply set a value and rely on jump threading optimisation to get the desired control flow. I can add that later if deemed necessary. r? ``@Amanieu`` cc ``@ojeda``
This commit is contained in:
commit
d774fbea7c
76 changed files with 857 additions and 200 deletions
|
@ -374,11 +374,17 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
|
|||
kind: Option<MemoryKind<Self::MemoryKind>>,
|
||||
) -> InterpResult<'tcx, Cow<'b, Allocation<Self::Provenance, Self::AllocExtra, Self::Bytes>>>;
|
||||
|
||||
/// Evaluate the inline assembly.
|
||||
///
|
||||
/// This should take care of jumping to the next block (one of `targets`) when asm goto
|
||||
/// is triggered, `targets[0]` when the assembly falls through, or diverge in case of
|
||||
/// `InlineAsmOptions::NORETURN` being set.
|
||||
fn eval_inline_asm(
|
||||
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
||||
_template: &'tcx [InlineAsmTemplatePiece],
|
||||
_operands: &[mir::InlineAsmOperand<'tcx>],
|
||||
_options: InlineAsmOptions,
|
||||
_targets: &[mir::BasicBlock],
|
||||
) -> InterpResult<'tcx> {
|
||||
throw_unsup_format!("inline assembly is not supported")
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use rustc_ast::ast::InlineAsmOptions;
|
||||
use rustc_middle::{
|
||||
mir,
|
||||
ty::{
|
||||
|
@ -224,15 +223,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
terminator.kind
|
||||
),
|
||||
|
||||
InlineAsm { template, ref operands, options, destination, .. } => {
|
||||
M::eval_inline_asm(self, template, operands, options)?;
|
||||
if options.contains(InlineAsmOptions::NORETURN) {
|
||||
throw_ub_custom!(fluent::const_eval_noreturn_asm_returned);
|
||||
}
|
||||
self.go_to_block(
|
||||
destination
|
||||
.expect("InlineAsm terminators without noreturn must have a destination"),
|
||||
)
|
||||
InlineAsm { template, ref operands, options, ref targets, .. } => {
|
||||
M::eval_inline_asm(self, template, operands, options, targets)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -471,9 +471,9 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> {
|
|||
self.check_edge(location, *real_target, EdgeKind::Normal);
|
||||
self.check_unwind_edge(location, *unwind);
|
||||
}
|
||||
TerminatorKind::InlineAsm { destination, unwind, .. } => {
|
||||
if let Some(destination) = destination {
|
||||
self.check_edge(location, *destination, EdgeKind::Normal);
|
||||
TerminatorKind::InlineAsm { targets, unwind, .. } => {
|
||||
for &target in targets {
|
||||
self.check_edge(location, target, EdgeKind::Normal);
|
||||
}
|
||||
self.check_unwind_edge(location, *unwind);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue