Skip to content

Commit 2028157

Browse files
committed
Add InlineAsmOperandRef::Const
This is intended for supporting passing arbitrary CTFE const into inline assembly.
1 parent e47eb32 commit 2028157

File tree

3 files changed

+38
-0
lines changed
  • compiler

3 files changed

+38
-0
lines changed

compiler/rustc_codegen_gcc/src/asm.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,14 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
300300
constants_len += string.len() + att_dialect as usize;
301301
}
302302

303+
InlineAsmOperandRef::Const { value } => {
304+
inputs.push(AsmInOperand {
305+
constraint: Cow::Borrowed("i"),
306+
rust_idx,
307+
val: value.immediate(),
308+
});
309+
}
310+
303311
InlineAsmOperandRef::SymFn { instance } => {
304312
// TODO(@Amanieu): Additional mangling is needed on
305313
// some targets to add a leading underscore (Mach-O)
@@ -415,6 +423,10 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
415423
// processed in the previous pass
416424
}
417425

426+
InlineAsmOperandRef::Const { .. } => {
427+
// processed in the previous pass
428+
}
429+
418430
InlineAsmOperandRef::Label { .. } => {
419431
// processed in the previous pass
420432
}
@@ -488,6 +500,15 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
488500
push_to_template(modifier, gcc_index);
489501
}
490502

503+
InlineAsmOperandRef::Const { .. } => {
504+
let in_gcc_index = inputs
505+
.iter()
506+
.position(|op| operand_idx == op.rust_idx)
507+
.expect("wrong rust index");
508+
let gcc_index = in_gcc_index + outputs.len();
509+
push_to_template(None, gcc_index);
510+
}
511+
491512
InlineAsmOperandRef::SymFn { instance } => {
492513
// TODO(@Amanieu): Additional mangling is needed on
493514
// some targets to add a leading underscore (Mach-O)

compiler/rustc_codegen_llvm/src/asm.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,11 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
158158
constraints.push(format!("{}", op_idx[&idx]));
159159
}
160160
}
161+
InlineAsmOperandRef::Const { value } => {
162+
inputs.push(value.immediate());
163+
op_idx.insert(idx, constraints.len());
164+
constraints.push("i".to_string());
165+
}
161166
InlineAsmOperandRef::SymFn { instance } => {
162167
inputs.push(self.cx.get_fn(instance));
163168
op_idx.insert(idx, constraints.len());
@@ -205,6 +210,9 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
205210
template_str.push_str(&format!("${{{}}}", op_idx[&operand_idx]));
206211
}
207212
}
213+
InlineAsmOperandRef::Const { .. } => {
214+
template_str.push_str(&format!("${{{}:c}}", op_idx[&operand_idx]));
215+
}
208216
InlineAsmOperandRef::Interpolate { ref string } => {
209217
// Const operands get injected directly into the template
210218
template_str.push_str(string);

compiler/rustc_codegen_ssa/src/traits/asm.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,18 @@ pub enum InlineAsmOperandRef<'tcx, B: BackendTypes + ?Sized> {
2525
in_value: OperandRef<'tcx, B::Value>,
2626
out_place: Option<PlaceRef<'tcx, B::Value>>,
2727
},
28+
/// Interpolate a string directly into the inline assembly.
29+
///
30+
/// This is distinct from `Const`, which can reference a const pointer or reference (and thus is
31+
/// a const in Rust/linker sense but not a literal value).
32+
///
33+
/// We currently use this for constant integers. They could technically use `Const` as well.
2834
Interpolate {
2935
string: String,
3036
},
37+
Const {
38+
value: OperandRef<'tcx, B::Value>,
39+
},
3140
SymFn {
3241
instance: Instance<'tcx>,
3342
},

0 commit comments

Comments
 (0)