Skip to content

Commit 20e4436

Browse files
committed
Stabilize inline asm usage on all platforms
But exclude sym operands for now as they are somewhat broken.
1 parent b1e7051 commit 20e4436

File tree

4 files changed

+27
-297
lines changed

4 files changed

+27
-297
lines changed

src/global_asm.rs

+21-21
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,13 @@ pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String,
4646
global_asm.push_str(&string);
4747
}
4848
InlineAsmOperand::SymFn { anon_const } => {
49+
if cfg!(not(feature = "inline_asm_sym")) {
50+
tcx.sess.span_err(
51+
item.span,
52+
"asm! and global_asm! sym operands are not yet supported",
53+
);
54+
}
55+
4956
let ty = tcx.typeck_body(anon_const.body).node_type(anon_const.hir_id);
5057
let instance = match ty.kind() {
5158
&ty::FnDef(def_id, args) => Instance::new(def_id, args),
@@ -57,6 +64,13 @@ pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String,
5764
global_asm.push_str(symbol.name);
5865
}
5966
InlineAsmOperand::SymStatic { path: _, def_id } => {
67+
if cfg!(not(feature = "inline_asm_sym")) {
68+
tcx.sess.span_err(
69+
item.span,
70+
"asm! and global_asm! sym operands are not yet supported",
71+
);
72+
}
73+
6074
let instance = Instance::mono(tcx, def_id).polymorphize(tcx);
6175
let symbol = tcx.symbol_name(instance);
6276
global_asm.push_str(symbol.name);
@@ -81,22 +95,23 @@ pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String,
8195
}
8296
}
8397

84-
pub(crate) fn asm_supported(tcx: TyCtxt<'_>) -> bool {
85-
cfg!(feature = "inline_asm") && !tcx.sess.target.is_like_windows
86-
}
87-
8898
#[derive(Debug)]
8999
pub(crate) struct GlobalAsmConfig {
90-
asm_enabled: bool,
91100
assembler: PathBuf,
101+
target: String,
92102
pub(crate) output_filenames: Arc<OutputFilenames>,
93103
}
94104

95105
impl GlobalAsmConfig {
96106
pub(crate) fn new(tcx: TyCtxt<'_>) -> Self {
97107
GlobalAsmConfig {
98-
asm_enabled: asm_supported(tcx),
99108
assembler: crate::toolchain::get_toolchain_binary(tcx.sess, "as"),
109+
target: match &tcx.sess.opts.target_triple {
110+
rustc_target::spec::TargetTriple::TargetTriple(triple) => triple.clone(),
111+
rustc_target::spec::TargetTriple::TargetJson { path_for_rustdoc, .. } => {
112+
path_for_rustdoc.to_str().unwrap().to_owned()
113+
}
114+
},
100115
output_filenames: tcx.output_filenames(()).clone(),
101116
}
102117
}
@@ -111,21 +126,6 @@ pub(crate) fn compile_global_asm(
111126
return Ok(None);
112127
}
113128

114-
if !config.asm_enabled {
115-
if global_asm.contains("__rust_probestack") {
116-
return Ok(None);
117-
}
118-
119-
if cfg!(not(feature = "inline_asm")) {
120-
return Err(
121-
"asm! and global_asm! support is disabled while compiling rustc_codegen_cranelift"
122-
.to_owned(),
123-
);
124-
} else {
125-
return Err("asm! and global_asm! are not yet supported on Windows".to_owned());
126-
}
127-
}
128-
129129
// Remove all LLVM style comments
130130
let mut global_asm = global_asm
131131
.lines()

src/inline_asm.rs

+6-200
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ use rustc_span::sym;
88
use rustc_target::asm::*;
99
use target_lexicon::BinaryFormat;
1010

11-
use crate::global_asm::asm_supported;
1211
use crate::prelude::*;
1312

1413
enum CInlineAsmOperand<'tcx> {
@@ -53,205 +52,6 @@ pub(crate) fn codegen_inline_asm<'tcx>(
5352
return;
5453
}
5554

56-
if !asm_supported(fx.tcx) {
57-
if template.is_empty() {
58-
let destination_block = fx.get_block(destination.unwrap());
59-
fx.bcx.ins().jump(destination_block, &[]);
60-
return;
61-
}
62-
63-
// Used by stdarch
64-
if template[0] == InlineAsmTemplatePiece::String("mov ".to_string())
65-
&& matches!(
66-
template[1],
67-
InlineAsmTemplatePiece::Placeholder {
68-
operand_idx: 0,
69-
modifier: Some('r'),
70-
span: _
71-
}
72-
)
73-
&& template[2] == InlineAsmTemplatePiece::String(", rbx".to_string())
74-
&& template[3] == InlineAsmTemplatePiece::String("\n".to_string())
75-
&& template[4] == InlineAsmTemplatePiece::String("cpuid".to_string())
76-
&& template[5] == InlineAsmTemplatePiece::String("\n".to_string())
77-
&& template[6] == InlineAsmTemplatePiece::String("xchg ".to_string())
78-
&& matches!(
79-
template[7],
80-
InlineAsmTemplatePiece::Placeholder {
81-
operand_idx: 0,
82-
modifier: Some('r'),
83-
span: _
84-
}
85-
)
86-
&& template[8] == InlineAsmTemplatePiece::String(", rbx".to_string())
87-
{
88-
assert_eq!(operands.len(), 4);
89-
let (leaf, eax_place) = match operands[1] {
90-
InlineAsmOperand::InOut {
91-
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::ax)),
92-
late: _,
93-
ref in_value,
94-
out_place: Some(out_place),
95-
} => (
96-
crate::base::codegen_operand(fx, in_value).load_scalar(fx),
97-
crate::base::codegen_place(fx, out_place),
98-
),
99-
_ => unreachable!(),
100-
};
101-
let ebx_place = match operands[0] {
102-
InlineAsmOperand::Out {
103-
reg:
104-
InlineAsmRegOrRegClass::RegClass(InlineAsmRegClass::X86(
105-
X86InlineAsmRegClass::reg,
106-
)),
107-
late: _,
108-
place: Some(place),
109-
} => crate::base::codegen_place(fx, place),
110-
_ => unreachable!(),
111-
};
112-
let (sub_leaf, ecx_place) = match operands[2] {
113-
InlineAsmOperand::InOut {
114-
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::cx)),
115-
late: _,
116-
ref in_value,
117-
out_place: Some(out_place),
118-
} => (
119-
crate::base::codegen_operand(fx, in_value).load_scalar(fx),
120-
crate::base::codegen_place(fx, out_place),
121-
),
122-
_ => unreachable!(),
123-
};
124-
let edx_place = match operands[3] {
125-
InlineAsmOperand::Out {
126-
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::dx)),
127-
late: _,
128-
place: Some(place),
129-
} => crate::base::codegen_place(fx, place),
130-
_ => unreachable!(),
131-
};
132-
133-
let (eax, ebx, ecx, edx) = crate::intrinsics::codegen_cpuid_call(fx, leaf, sub_leaf);
134-
135-
eax_place.write_cvalue(fx, CValue::by_val(eax, fx.layout_of(fx.tcx.types.u32)));
136-
ebx_place.write_cvalue(fx, CValue::by_val(ebx, fx.layout_of(fx.tcx.types.u32)));
137-
ecx_place.write_cvalue(fx, CValue::by_val(ecx, fx.layout_of(fx.tcx.types.u32)));
138-
edx_place.write_cvalue(fx, CValue::by_val(edx, fx.layout_of(fx.tcx.types.u32)));
139-
let destination_block = fx.get_block(destination.unwrap());
140-
fx.bcx.ins().jump(destination_block, &[]);
141-
return;
142-
}
143-
144-
// Used by compiler-builtins
145-
if fx.tcx.symbol_name(fx.instance).name.starts_with("___chkstk") {
146-
// ___chkstk, ___chkstk_ms and __alloca are only used on Windows
147-
crate::trap::trap_unimplemented(fx, "Stack probes are not supported");
148-
return;
149-
} else if fx.tcx.symbol_name(fx.instance).name == "__alloca" {
150-
crate::trap::trap_unimplemented(fx, "Alloca is not supported");
151-
return;
152-
}
153-
154-
// Used by core::hint::spin_loop()
155-
if template[0]
156-
== InlineAsmTemplatePiece::String(".insn i 0x0F, 0, x0, x0, 0x010".to_string())
157-
&& template.len() == 1
158-
{
159-
let destination_block = fx.get_block(destination.unwrap());
160-
fx.bcx.ins().jump(destination_block, &[]);
161-
return;
162-
}
163-
164-
// Used by measureme
165-
if template[0] == InlineAsmTemplatePiece::String("xor %eax, %eax".to_string())
166-
&& template[1] == InlineAsmTemplatePiece::String("\n".to_string())
167-
&& template[2] == InlineAsmTemplatePiece::String("mov %rbx, ".to_string())
168-
&& matches!(
169-
template[3],
170-
InlineAsmTemplatePiece::Placeholder {
171-
operand_idx: 0,
172-
modifier: Some('r'),
173-
span: _
174-
}
175-
)
176-
&& template[4] == InlineAsmTemplatePiece::String("\n".to_string())
177-
&& template[5] == InlineAsmTemplatePiece::String("cpuid".to_string())
178-
&& template[6] == InlineAsmTemplatePiece::String("\n".to_string())
179-
&& template[7] == InlineAsmTemplatePiece::String("mov ".to_string())
180-
&& matches!(
181-
template[8],
182-
InlineAsmTemplatePiece::Placeholder {
183-
operand_idx: 0,
184-
modifier: Some('r'),
185-
span: _
186-
}
187-
)
188-
&& template[9] == InlineAsmTemplatePiece::String(", %rbx".to_string())
189-
{
190-
let destination_block = fx.get_block(destination.unwrap());
191-
fx.bcx.ins().jump(destination_block, &[]);
192-
return;
193-
} else if template[0] == InlineAsmTemplatePiece::String("rdpmc".to_string()) {
194-
// Return zero dummy values for all performance counters
195-
match operands[0] {
196-
InlineAsmOperand::In {
197-
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::cx)),
198-
value: _,
199-
} => {}
200-
_ => unreachable!(),
201-
};
202-
let lo = match operands[1] {
203-
InlineAsmOperand::Out {
204-
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::ax)),
205-
late: true,
206-
place: Some(place),
207-
} => crate::base::codegen_place(fx, place),
208-
_ => unreachable!(),
209-
};
210-
let hi = match operands[2] {
211-
InlineAsmOperand::Out {
212-
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::dx)),
213-
late: true,
214-
place: Some(place),
215-
} => crate::base::codegen_place(fx, place),
216-
_ => unreachable!(),
217-
};
218-
219-
let u32_layout = fx.layout_of(fx.tcx.types.u32);
220-
let zero = fx.bcx.ins().iconst(types::I32, 0);
221-
lo.write_cvalue(fx, CValue::by_val(zero, u32_layout));
222-
hi.write_cvalue(fx, CValue::by_val(zero, u32_layout));
223-
224-
let destination_block = fx.get_block(destination.unwrap());
225-
fx.bcx.ins().jump(destination_block, &[]);
226-
return;
227-
} else if template[0] == InlineAsmTemplatePiece::String("lock xadd ".to_string())
228-
&& matches!(
229-
template[1],
230-
InlineAsmTemplatePiece::Placeholder { operand_idx: 1, modifier: None, span: _ }
231-
)
232-
&& template[2] == InlineAsmTemplatePiece::String(", (".to_string())
233-
&& matches!(
234-
template[3],
235-
InlineAsmTemplatePiece::Placeholder { operand_idx: 0, modifier: None, span: _ }
236-
)
237-
&& template[4] == InlineAsmTemplatePiece::String(")".to_string())
238-
{
239-
let destination_block = fx.get_block(destination.unwrap());
240-
fx.bcx.ins().jump(destination_block, &[]);
241-
return;
242-
}
243-
244-
if cfg!(not(feature = "inline_asm")) {
245-
fx.tcx.sess.span_err(
246-
span,
247-
"asm! and global_asm! support is disabled while compiling rustc_codegen_cranelift",
248-
);
249-
} else {
250-
fx.tcx.sess.span_err(span, "asm! and global_asm! are not yet supported on Windows");
251-
}
252-
return;
253-
}
254-
25555
let operands = operands
25656
.into_iter()
25757
.map(|operand| match *operand {
@@ -282,6 +82,12 @@ pub(crate) fn codegen_inline_asm<'tcx>(
28282
CInlineAsmOperand::Const { value }
28383
}
28484
InlineAsmOperand::SymFn { ref value } => {
85+
if cfg!(not(feature = "inline_asm_sym")) {
86+
fx.tcx
87+
.sess
88+
.span_err(span, "asm! and global_asm! sym operands are not yet supported");
89+
}
90+
28591
let const_ = fx.monomorphize(value.const_);
28692
if let ty::FnDef(def_id, args) = *const_.ty().kind() {
28793
let instance = ty::Instance::resolve_for_fn_ptr(

src/intrinsics/cpuid.rs

-74
This file was deleted.

src/intrinsics/mod.rs

-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ macro_rules! intrinsic_args {
1212
}
1313
}
1414

15-
mod cpuid;
1615
mod llvm;
1716
mod llvm_aarch64;
1817
mod llvm_x86;
@@ -25,7 +24,6 @@ use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
2524
use rustc_middle::ty::GenericArgsRef;
2625
use rustc_span::symbol::{kw, sym, Symbol};
2726

28-
pub(crate) use self::cpuid::codegen_cpuid_call;
2927
pub(crate) use self::llvm::codegen_llvm_intrinsic_call;
3028
use crate::prelude::*;
3129

0 commit comments

Comments
 (0)