Skip to content

Commit eed63de

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

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
@@ -307,6 +307,14 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
307307
constants_len += string.len() + att_dialect as usize;
308308
}
309309

310+
InlineAsmOperandRef::Const { value } => {
311+
inputs.push(AsmInOperand {
312+
constraint: Cow::Borrowed("is"),
313+
rust_idx,
314+
val: value.immediate(),
315+
});
316+
}
317+
310318
InlineAsmOperandRef::SymFn { instance } => {
311319
// TODO(@Amanieu): Additional mangling is needed on
312320
// some targets to add a leading underscore (Mach-O)
@@ -422,6 +430,10 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
422430
// processed in the previous pass
423431
}
424432

433+
InlineAsmOperandRef::Const { .. } => {
434+
// processed in the previous pass
435+
}
436+
425437
InlineAsmOperandRef::Label { .. } => {
426438
// processed in the previous pass
427439
}
@@ -495,6 +507,15 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
495507
push_to_template(modifier, gcc_index);
496508
}
497509

510+
InlineAsmOperandRef::Const { .. } => {
511+
let in_gcc_index = inputs
512+
.iter()
513+
.position(|op| operand_idx == op.rust_idx)
514+
.expect("wrong rust index");
515+
let gcc_index = in_gcc_index + outputs.len();
516+
push_to_template(None, gcc_index);
517+
}
518+
498519
InlineAsmOperandRef::SymFn { instance } => {
499520
// TODO(@Amanieu): Additional mangling is needed on
500521
// 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
@@ -157,6 +157,11 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
157157
constraints.push(format!("{}", op_idx[&idx]));
158158
}
159159
}
160+
InlineAsmOperandRef::Const { value } => {
161+
inputs.push(value.immediate());
162+
op_idx.insert(idx, constraints.len());
163+
constraints.push("is".to_string());
164+
}
160165
InlineAsmOperandRef::SymFn { instance } => {
161166
inputs.push(self.cx.get_fn(instance));
162167
op_idx.insert(idx, constraints.len());
@@ -204,6 +209,9 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
204209
template_str.push_str(&format!("${{{}}}", op_idx[&operand_idx]));
205210
}
206211
}
212+
InlineAsmOperandRef::Const { .. } => {
213+
template_str.push_str(&format!("${{{}:c}}", op_idx[&operand_idx]));
214+
}
207215
InlineAsmOperandRef::Interpolate { ref string } => {
208216
// Const operands get injected directly into the template
209217
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)