Merge commit 'dde58803fd' into sync_cg_clif-2023-10-29

This commit is contained in:
bjorn3 2023-10-29 20:30:50 +00:00
commit a9b21bb727
9 changed files with 100 additions and 334 deletions

View file

@ -8,7 +8,6 @@ use rustc_span::sym;
use rustc_target::asm::*;
use target_lexicon::BinaryFormat;
use crate::global_asm::asm_supported;
use crate::prelude::*;
enum CInlineAsmOperand<'tcx> {
@ -45,208 +44,11 @@ pub(crate) fn codegen_inline_asm<'tcx>(
) {
// FIXME add .eh_frame unwind info directives
if !asm_supported(fx.tcx) {
if template.is_empty() {
let destination_block = fx.get_block(destination.unwrap());
fx.bcx.ins().jump(destination_block, &[]);
return;
}
// Used by panic_abort
if template[0] == InlineAsmTemplatePiece::String("int $$0x29".to_string()) {
fx.bcx.ins().trap(TrapCode::User(1));
return;
}
// Used by stdarch
if template[0] == InlineAsmTemplatePiece::String("mov ".to_string())
&& matches!(
template[1],
InlineAsmTemplatePiece::Placeholder {
operand_idx: 0,
modifier: Some('r'),
span: _
}
)
&& template[2] == InlineAsmTemplatePiece::String(", rbx".to_string())
&& template[3] == InlineAsmTemplatePiece::String("\n".to_string())
&& template[4] == InlineAsmTemplatePiece::String("cpuid".to_string())
&& template[5] == InlineAsmTemplatePiece::String("\n".to_string())
&& template[6] == InlineAsmTemplatePiece::String("xchg ".to_string())
&& matches!(
template[7],
InlineAsmTemplatePiece::Placeholder {
operand_idx: 0,
modifier: Some('r'),
span: _
}
)
&& template[8] == InlineAsmTemplatePiece::String(", rbx".to_string())
{
assert_eq!(operands.len(), 4);
let (leaf, eax_place) = match operands[1] {
InlineAsmOperand::InOut {
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::ax)),
late: _,
ref in_value,
out_place: Some(out_place),
} => (
crate::base::codegen_operand(fx, in_value).load_scalar(fx),
crate::base::codegen_place(fx, out_place),
),
_ => unreachable!(),
};
let ebx_place = match operands[0] {
InlineAsmOperand::Out {
reg:
InlineAsmRegOrRegClass::RegClass(InlineAsmRegClass::X86(
X86InlineAsmRegClass::reg,
)),
late: _,
place: Some(place),
} => crate::base::codegen_place(fx, place),
_ => unreachable!(),
};
let (sub_leaf, ecx_place) = match operands[2] {
InlineAsmOperand::InOut {
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::cx)),
late: _,
ref in_value,
out_place: Some(out_place),
} => (
crate::base::codegen_operand(fx, in_value).load_scalar(fx),
crate::base::codegen_place(fx, out_place),
),
_ => unreachable!(),
};
let edx_place = match operands[3] {
InlineAsmOperand::Out {
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::dx)),
late: _,
place: Some(place),
} => crate::base::codegen_place(fx, place),
_ => unreachable!(),
};
let (eax, ebx, ecx, edx) = crate::intrinsics::codegen_cpuid_call(fx, leaf, sub_leaf);
eax_place.write_cvalue(fx, CValue::by_val(eax, fx.layout_of(fx.tcx.types.u32)));
ebx_place.write_cvalue(fx, CValue::by_val(ebx, fx.layout_of(fx.tcx.types.u32)));
ecx_place.write_cvalue(fx, CValue::by_val(ecx, fx.layout_of(fx.tcx.types.u32)));
edx_place.write_cvalue(fx, CValue::by_val(edx, fx.layout_of(fx.tcx.types.u32)));
let destination_block = fx.get_block(destination.unwrap());
fx.bcx.ins().jump(destination_block, &[]);
return;
}
// Used by compiler-builtins
if fx.tcx.symbol_name(fx.instance).name.starts_with("___chkstk") {
// ___chkstk, ___chkstk_ms and __alloca are only used on Windows
crate::trap::trap_unimplemented(fx, "Stack probes are not supported");
return;
} else if fx.tcx.symbol_name(fx.instance).name == "__alloca" {
crate::trap::trap_unimplemented(fx, "Alloca is not supported");
return;
}
// Used by core::hint::spin_loop()
if template[0]
== InlineAsmTemplatePiece::String(".insn i 0x0F, 0, x0, x0, 0x010".to_string())
&& template.len() == 1
{
let destination_block = fx.get_block(destination.unwrap());
fx.bcx.ins().jump(destination_block, &[]);
return;
}
// Used by measureme
if template[0] == InlineAsmTemplatePiece::String("xor %eax, %eax".to_string())
&& template[1] == InlineAsmTemplatePiece::String("\n".to_string())
&& template[2] == InlineAsmTemplatePiece::String("mov %rbx, ".to_string())
&& matches!(
template[3],
InlineAsmTemplatePiece::Placeholder {
operand_idx: 0,
modifier: Some('r'),
span: _
}
)
&& template[4] == InlineAsmTemplatePiece::String("\n".to_string())
&& template[5] == InlineAsmTemplatePiece::String("cpuid".to_string())
&& template[6] == InlineAsmTemplatePiece::String("\n".to_string())
&& template[7] == InlineAsmTemplatePiece::String("mov ".to_string())
&& matches!(
template[8],
InlineAsmTemplatePiece::Placeholder {
operand_idx: 0,
modifier: Some('r'),
span: _
}
)
&& template[9] == InlineAsmTemplatePiece::String(", %rbx".to_string())
{
let destination_block = fx.get_block(destination.unwrap());
fx.bcx.ins().jump(destination_block, &[]);
return;
} else if template[0] == InlineAsmTemplatePiece::String("rdpmc".to_string()) {
// Return zero dummy values for all performance counters
match operands[0] {
InlineAsmOperand::In {
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::cx)),
value: _,
} => {}
_ => unreachable!(),
};
let lo = match operands[1] {
InlineAsmOperand::Out {
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::ax)),
late: true,
place: Some(place),
} => crate::base::codegen_place(fx, place),
_ => unreachable!(),
};
let hi = match operands[2] {
InlineAsmOperand::Out {
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::dx)),
late: true,
place: Some(place),
} => crate::base::codegen_place(fx, place),
_ => unreachable!(),
};
let u32_layout = fx.layout_of(fx.tcx.types.u32);
let zero = fx.bcx.ins().iconst(types::I32, 0);
lo.write_cvalue(fx, CValue::by_val(zero, u32_layout));
hi.write_cvalue(fx, CValue::by_val(zero, u32_layout));
let destination_block = fx.get_block(destination.unwrap());
fx.bcx.ins().jump(destination_block, &[]);
return;
} else if template[0] == InlineAsmTemplatePiece::String("lock xadd ".to_string())
&& matches!(
template[1],
InlineAsmTemplatePiece::Placeholder { operand_idx: 1, modifier: None, span: _ }
)
&& template[2] == InlineAsmTemplatePiece::String(", (".to_string())
&& matches!(
template[3],
InlineAsmTemplatePiece::Placeholder { operand_idx: 0, modifier: None, span: _ }
)
&& template[4] == InlineAsmTemplatePiece::String(")".to_string())
{
let destination_block = fx.get_block(destination.unwrap());
fx.bcx.ins().jump(destination_block, &[]);
return;
}
if cfg!(not(feature = "inline_asm")) {
fx.tcx.sess.span_err(
span,
"asm! and global_asm! support is disabled while compiling rustc_codegen_cranelift",
);
} else {
fx.tcx.sess.span_err(span, "asm! and global_asm! are not yet supported on Windows");
}
// Used by panic_abort on Windows, but uses a syntax which only happens to work with
// asm!() by accident and breaks with the GNU assembler as well as global_asm!() for
// the LLVM backend.
if template[0] == InlineAsmTemplatePiece::String("int $$0x29".to_string()) {
fx.bcx.ins().trap(TrapCode::User(1));
return;
}
@ -280,6 +82,12 @@ pub(crate) fn codegen_inline_asm<'tcx>(
CInlineAsmOperand::Const { value }
}
InlineAsmOperand::SymFn { ref value } => {
if cfg!(not(feature = "inline_asm_sym")) {
fx.tcx
.sess
.span_err(span, "asm! and global_asm! sym operands are not yet supported");
}
let const_ = fx.monomorphize(value.const_);
if let ty::FnDef(def_id, args) = *const_.ty().kind() {
let instance = ty::Instance::resolve_for_fn_ptr(