about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbjorn3 <17426603+bjorn3@users.noreply.github.com>2023-02-05 20:41:49 +0100
committerGitHub <noreply@github.com>2023-02-05 20:41:49 +0100
commit5ab690d9e75d3d80ddc96bbfe131709227862d56 (patch)
tree21fa3bee05342d462d89cf05c2ca775a7dcad3a1
parente238ea6155771ef0baf2d7e44e7d77209e3f7685 (diff)
parent178e267977c646e34a1440cb10e32e0716e2241e (diff)
downloadrust-5ab690d9e75d3d80ddc96bbfe131709227862d56.tar.gz
rust-5ab690d9e75d3d80ddc96bbfe131709227862d56.zip
Merge pull request #1351 from bjorn3/global_asm_const
Implement const and sym operands for global asm
-rw-r--r--src/global_asm.rs43
1 files changed, 41 insertions, 2 deletions
diff --git a/src/global_asm.rs b/src/global_asm.rs
index dcbcaba30fe..46c78ce6a1e 100644
--- a/src/global_asm.rs
+++ b/src/global_asm.rs
@@ -7,7 +7,7 @@ use std::process::{Command, Stdio};
 use std::sync::Arc;
 
 use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
-use rustc_hir::ItemId;
+use rustc_hir::{InlineAsmOperand, ItemId};
 use rustc_session::config::{OutputFilenames, OutputType};
 
 use crate::prelude::*;
@@ -23,7 +23,46 @@ pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String,
         for piece in asm.template {
             match *piece {
                 InlineAsmTemplatePiece::String(ref s) => global_asm.push_str(s),
-                InlineAsmTemplatePiece::Placeholder { .. } => todo!(),
+                InlineAsmTemplatePiece::Placeholder { operand_idx, modifier: _, span: op_sp } => {
+                    match asm.operands[operand_idx].0 {
+                        InlineAsmOperand::Const { ref anon_const } => {
+                            let const_value =
+                                tcx.const_eval_poly(anon_const.def_id.to_def_id()).unwrap_or_else(
+                                    |_| span_bug!(op_sp, "asm const cannot be resolved"),
+                                );
+                            let ty = tcx.typeck_body(anon_const.body).node_type(anon_const.hir_id);
+                            let string = rustc_codegen_ssa::common::asm_const_to_str(
+                                tcx,
+                                op_sp,
+                                const_value,
+                                RevealAllLayoutCx(tcx).layout_of(ty),
+                            );
+                            global_asm.push_str(&string);
+                        }
+                        InlineAsmOperand::SymFn { anon_const } => {
+                            let ty = tcx.typeck_body(anon_const.body).node_type(anon_const.hir_id);
+                            let instance = match ty.kind() {
+                                &ty::FnDef(def_id, substs) => Instance::new(def_id, substs),
+                                _ => span_bug!(op_sp, "asm sym is not a function"),
+                            };
+                            let symbol = tcx.symbol_name(instance);
+                            // FIXME handle the case where the function was made private to the
+                            // current codegen unit
+                            global_asm.push_str(symbol.name);
+                        }
+                        InlineAsmOperand::SymStatic { path: _, def_id } => {
+                            let instance = Instance::mono(tcx, def_id).polymorphize(tcx);
+                            let symbol = tcx.symbol_name(instance);
+                            global_asm.push_str(symbol.name);
+                        }
+                        InlineAsmOperand::In { .. }
+                        | InlineAsmOperand::Out { .. }
+                        | InlineAsmOperand::InOut { .. }
+                        | InlineAsmOperand::SplitInOut { .. } => {
+                            span_bug!(op_sp, "invalid operand type for global_asm!")
+                        }
+                    }
+                }
             }
         }
         global_asm.push_str("\n.att_syntax\n\n");