about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-03-08 08:19:17 +0100
committerGitHub <noreply@github.com>2024-03-08 08:19:17 +0100
commit5ffd498ca19ce6cfd7696733b88417dbd6706d6e (patch)
tree082552dc1ee6f5b5e346cb51e13c6ea26e68d9e0
parent804eeff1806ce6a3cd88abf4290e569ebe939051 (diff)
parent8cec9989b2a8b39da211d819f1c05fab94886b34 (diff)
downloadrust-5ffd498ca19ce6cfd7696733b88417dbd6706d6e.tar.gz
rust-5ffd498ca19ce6cfd7696733b88417dbd6706d6e.zip
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``
-rw-r--r--src/base.rs16
-rw-r--r--src/global_asm.rs3
-rw-r--r--src/inline_asm.rs3
3 files changed, 19 insertions, 3 deletions
diff --git a/src/base.rs b/src/base.rs
index a7e76fbc128..1ce920f3bdb 100644
--- a/src/base.rs
+++ b/src/base.rs
@@ -445,7 +445,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
                 template,
                 operands,
                 options,
-                destination,
+                targets,
                 line_spans: _,
                 unwind: _,
             } => {
@@ -456,13 +456,25 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
                     );
                 }
 
+                let have_labels = if options.contains(InlineAsmOptions::NORETURN) {
+                    !targets.is_empty()
+                } else {
+                    targets.len() > 1
+                };
+                if have_labels {
+                    fx.tcx.dcx().span_fatal(
+                        source_info.span,
+                        "cranelift doesn't support labels in inline assembly.",
+                    );
+                }
+
                 crate::inline_asm::codegen_inline_asm_terminator(
                     fx,
                     source_info.span,
                     template,
                     operands,
                     *options,
-                    *destination,
+                    targets.get(0).copied(),
                 );
             }
             TerminatorKind::UnwindTerminate(reason) => {
diff --git a/src/global_asm.rs b/src/global_asm.rs
index da07b66c762..44650898de8 100644
--- a/src/global_asm.rs
+++ b/src/global_asm.rs
@@ -78,7 +78,8 @@ pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String,
                         InlineAsmOperand::In { .. }
                         | InlineAsmOperand::Out { .. }
                         | InlineAsmOperand::InOut { .. }
-                        | InlineAsmOperand::SplitInOut { .. } => {
+                        | InlineAsmOperand::SplitInOut { .. }
+                        | InlineAsmOperand::Label { .. } => {
                             span_bug!(op_sp, "invalid operand type for global_asm!")
                         }
                     }
diff --git a/src/inline_asm.rs b/src/inline_asm.rs
index 7793b1b7092..171ee88a11c 100644
--- a/src/inline_asm.rs
+++ b/src/inline_asm.rs
@@ -129,6 +129,9 @@ pub(crate) fn codegen_inline_asm_terminator<'tcx>(
                 let instance = Instance::mono(fx.tcx, def_id).polymorphize(fx.tcx);
                 CInlineAsmOperand::Symbol { symbol: fx.tcx.symbol_name(instance).name.to_owned() }
             }
+            InlineAsmOperand::Label { .. } => {
+                span_bug!(span, "asm! label operands are not yet supported");
+            }
         })
         .collect::<Vec<_>>();