Merge commit '81dc066758
' into sync_cg_clif-2023-10-09
This commit is contained in:
commit
169055f2ff
47 changed files with 1230 additions and 734 deletions
|
@ -6,6 +6,7 @@ mod returning;
|
|||
|
||||
use std::borrow::Cow;
|
||||
|
||||
use cranelift_codegen::ir::{AbiParam, SigRef};
|
||||
use cranelift_module::ModuleError;
|
||||
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
||||
use rustc_middle::ty::layout::FnAbiOf;
|
||||
|
@ -13,12 +14,9 @@ use rustc_session::Session;
|
|||
use rustc_target::abi::call::{Conv, FnAbi};
|
||||
use rustc_target::spec::abi::Abi;
|
||||
|
||||
use cranelift_codegen::ir::{AbiParam, SigRef};
|
||||
|
||||
use self::pass_mode::*;
|
||||
use crate::prelude::*;
|
||||
|
||||
pub(crate) use self::returning::codegen_return;
|
||||
use crate::prelude::*;
|
||||
|
||||
fn clif_sig_from_fn_abi<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
//! Argument passing
|
||||
|
||||
use crate::prelude::*;
|
||||
use crate::value_and_place::assert_assignable;
|
||||
|
||||
use cranelift_codegen::ir::{ArgumentExtension, ArgumentPurpose};
|
||||
use rustc_target::abi::call::{
|
||||
ArgAbi, ArgAttributes, ArgExtension as RustcArgExtension, CastTarget, PassMode, Reg, RegKind,
|
||||
};
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
|
||||
use crate::prelude::*;
|
||||
use crate::value_and_place::assert_assignable;
|
||||
|
||||
pub(super) trait ArgAbiExt<'tcx> {
|
||||
fn get_abi_param(&self, tcx: TyCtxt<'tcx>) -> SmallVec<[AbiParam; 2]>;
|
||||
fn get_abi_return(&self, tcx: TyCtxt<'tcx>) -> (Option<AbiParam>, Vec<AbiParam>);
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
//! Return value handling
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
use rustc_target::abi::call::{ArgAbi, PassMode};
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
/// Return a place where the return value of the current function can be written to. If necessary
|
||||
/// this adds an extra parameter pointing to where the return value needs to be stored.
|
||||
pub(super) fn codegen_return_param<'tcx>(
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
//! Allocator shim
|
||||
// Adapted from rustc
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
use rustc_ast::expand::allocator::{
|
||||
alloc_error_handler_name, default_fn_name, global_fn_name, AllocatorKind, AllocatorTy,
|
||||
ALLOCATOR_METHODS, NO_ALLOC_SHIM_IS_UNSTABLE,
|
||||
|
@ -10,6 +8,8 @@ use rustc_ast::expand::allocator::{
|
|||
use rustc_codegen_ssa::base::allocator_kind_for_codegen;
|
||||
use rustc_session::config::OomStrategy;
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
/// Returns whether an allocator shim was created
|
||||
pub(crate) fn codegen(
|
||||
tcx: TyCtxt<'_>,
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
//! SSA analysis
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
use rustc_index::IndexVec;
|
||||
use rustc_middle::mir::StatementKind::*;
|
||||
use rustc_middle::ty::Ty;
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub(crate) enum SsaKind {
|
||||
NotSsa,
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
//! Codegen of a single function
|
||||
|
||||
use cranelift_codegen::ir::UserFuncName;
|
||||
use cranelift_codegen::CodegenError;
|
||||
use cranelift_module::ModuleError;
|
||||
use rustc_ast::InlineAsmOptions;
|
||||
use rustc_index::IndexVec;
|
||||
use rustc_middle::ty::adjustment::PointerCoercion;
|
||||
use rustc_middle::ty::layout::FnAbiOf;
|
||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||
|
||||
use cranelift_codegen::ir::UserFuncName;
|
||||
use cranelift_codegen::CodegenError;
|
||||
use cranelift_module::ModuleError;
|
||||
|
||||
use crate::constant::ConstantCx;
|
||||
use crate::debuginfo::FunctionDebugContext;
|
||||
use crate::prelude::*;
|
||||
|
|
|
@ -129,8 +129,8 @@ pub(crate) fn clif_int_or_float_cast(
|
|||
let (min, max) = match (to_ty, to_signed) {
|
||||
(types::I8, false) => (0, i64::from(u8::MAX)),
|
||||
(types::I16, false) => (0, i64::from(u16::MAX)),
|
||||
(types::I8, true) => (i64::from(i8::MIN), i64::from(i8::MAX)),
|
||||
(types::I16, true) => (i64::from(i16::MIN), i64::from(i16::MAX)),
|
||||
(types::I8, true) => (i64::from(i8::MIN as u32), i64::from(i8::MAX as u32)),
|
||||
(types::I16, true) => (i64::from(i16::MIN as u32), i64::from(i16::MAX as u32)),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let min_val = fx.bcx.ins().iconst(types::I32, min);
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use cranelift_codegen::isa::TargetFrontendConfig;
|
||||
use gimli::write::FileId;
|
||||
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_index::IndexVec;
|
||||
use rustc_middle::ty::layout::{
|
||||
|
@ -204,9 +203,9 @@ pub(crate) fn type_min_max_value(
|
|||
(types::I8, false) | (types::I16, false) | (types::I32, false) | (types::I64, false) => {
|
||||
0i64
|
||||
}
|
||||
(types::I8, true) => i64::from(i8::MIN),
|
||||
(types::I16, true) => i64::from(i16::MIN),
|
||||
(types::I32, true) => i64::from(i32::MIN),
|
||||
(types::I8, true) => i64::from(i8::MIN as u8),
|
||||
(types::I16, true) => i64::from(i16::MIN as u16),
|
||||
(types::I32, true) => i64::from(i32::MIN as u32),
|
||||
(types::I64, true) => i64::MIN,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
@ -216,9 +215,9 @@ pub(crate) fn type_min_max_value(
|
|||
(types::I16, false) => i64::from(u16::MAX),
|
||||
(types::I32, false) => i64::from(u32::MAX),
|
||||
(types::I64, false) => u64::MAX as i64,
|
||||
(types::I8, true) => i64::from(i8::MAX),
|
||||
(types::I16, true) => i64::from(i16::MAX),
|
||||
(types::I32, true) => i64::from(i32::MAX),
|
||||
(types::I8, true) => i64::from(i8::MAX as u8),
|
||||
(types::I16, true) => i64::from(i16::MAX as u16),
|
||||
(types::I32, true) => i64::from(i32::MAX as u32),
|
||||
(types::I64, true) => i64::MAX,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
use std::sync::{Arc, Condvar, Mutex};
|
||||
|
||||
use rustc_session::Session;
|
||||
|
||||
use jobserver::HelperThread;
|
||||
use rustc_session::Session;
|
||||
|
||||
// FIXME don't panic when a worker thread panics
|
||||
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
//! Handling of `static`s, `const`s and promoted allocations
|
||||
|
||||
use cranelift_module::*;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
||||
use rustc_middle::mir::interpret::{read_target_uint, AllocId, GlobalAlloc, Scalar};
|
||||
use rustc_middle::mir::ConstValue;
|
||||
|
||||
use cranelift_module::*;
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
pub(crate) struct ConstantCx {
|
||||
|
@ -101,7 +100,7 @@ pub(crate) fn codegen_const_value<'tcx>(
|
|||
if fx.clif_type(layout.ty).is_some() {
|
||||
return CValue::const_val(fx, layout, int);
|
||||
} else {
|
||||
let raw_val = int.to_bits(int.size()).unwrap();
|
||||
let raw_val = int.size().truncate(int.to_bits(int.size()).unwrap());
|
||||
let val = match int.size().bytes() {
|
||||
1 => fx.bcx.ins().iconst(types::I8, raw_val as i64),
|
||||
2 => fx.bcx.ins().iconst(types::I16, raw_val as i64),
|
||||
|
@ -187,8 +186,7 @@ pub(crate) fn codegen_const_value<'tcx>(
|
|||
ConstValue::Slice { data, meta } => {
|
||||
let alloc_id = fx.tcx.reserve_and_set_memory_alloc(data);
|
||||
let ptr = pointer_for_allocation(fx, alloc_id).get_addr(fx);
|
||||
// FIXME: the `try_from` here can actually fail, e.g. for very long ZST slices.
|
||||
let len = fx.bcx.ins().iconst(fx.pointer_type, i64::try_from(meta).unwrap());
|
||||
let len = fx.bcx.ins().iconst(fx.pointer_type, meta as i64);
|
||||
CValue::by_val_pair(ptr, len, layout)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
//! Write the debuginfo into an object file.
|
||||
|
||||
use cranelift_object::ObjectProduct;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
|
||||
use gimli::write::{Address, AttributeValue, EndianVec, Result, Sections, Writer};
|
||||
use gimli::{RunTimeEndian, SectionId};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
|
||||
use super::object::WriteDebugInfo;
|
||||
use super::DebugContext;
|
||||
|
|
|
@ -3,20 +3,18 @@
|
|||
use std::ffi::OsStr;
|
||||
use std::path::{Component, Path};
|
||||
|
||||
use crate::debuginfo::FunctionDebugContext;
|
||||
use crate::prelude::*;
|
||||
|
||||
use cranelift_codegen::binemit::CodeOffset;
|
||||
use cranelift_codegen::MachSrcLoc;
|
||||
use gimli::write::{
|
||||
Address, AttributeValue, FileId, FileInfo, LineProgram, LineString, LineStringTable,
|
||||
};
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_span::{
|
||||
FileName, Pos, SourceFile, SourceFileAndLine, SourceFileHash, SourceFileHashAlgorithm,
|
||||
};
|
||||
|
||||
use cranelift_codegen::binemit::CodeOffset;
|
||||
use cranelift_codegen::MachSrcLoc;
|
||||
|
||||
use gimli::write::{
|
||||
Address, AttributeValue, FileId, FileInfo, LineProgram, LineString, LineStringTable,
|
||||
};
|
||||
use crate::debuginfo::FunctionDebugContext;
|
||||
use crate::prelude::*;
|
||||
|
||||
// OPTIMIZATION: It is cheaper to do this in one pass than using `.parent()` and `.file_name()`.
|
||||
fn split_path_dir_and_file(path: &Path) -> (&Path, &OsStr) {
|
||||
|
|
|
@ -5,11 +5,8 @@ mod line_info;
|
|||
mod object;
|
||||
mod unwind;
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
use cranelift_codegen::ir::Endianness;
|
||||
use cranelift_codegen::isa::TargetIsa;
|
||||
|
||||
use gimli::write::{
|
||||
Address, AttributeValue, DwarfUnit, FileId, LineProgram, LineString, Range, RangeList,
|
||||
UnitEntryId,
|
||||
|
@ -17,8 +14,9 @@ use gimli::write::{
|
|||
use gimli::{Encoding, Format, LineEncoding, RunTimeEndian};
|
||||
use indexmap::IndexSet;
|
||||
|
||||
pub(crate) use emit::{DebugReloc, DebugRelocName};
|
||||
pub(crate) use unwind::UnwindContext;
|
||||
pub(crate) use self::emit::{DebugReloc, DebugRelocName};
|
||||
pub(crate) use self::unwind::UnwindContext;
|
||||
use crate::prelude::*;
|
||||
|
||||
pub(crate) fn producer() -> String {
|
||||
format!(
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
use rustc_data_structures::fx::FxHashMap;
|
||||
|
||||
use cranelift_module::FuncId;
|
||||
use cranelift_object::ObjectProduct;
|
||||
|
||||
use gimli::SectionId;
|
||||
use object::write::{Relocation, StandardSegment};
|
||||
use object::{RelocationEncoding, SectionKind};
|
||||
|
||||
use gimli::SectionId;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
|
||||
use crate::debuginfo::{DebugReloc, DebugRelocName};
|
||||
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
//! Unwind info generation (`.eh_frame`)
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
use cranelift_codegen::ir::Endianness;
|
||||
use cranelift_codegen::isa::{unwind::UnwindInfo, TargetIsa};
|
||||
|
||||
use cranelift_object::ObjectProduct;
|
||||
use gimli::write::{Address, CieId, EhFrame, FrameTable, Section};
|
||||
use gimli::RunTimeEndian;
|
||||
|
||||
use super::object::WriteDebugInfo;
|
||||
use crate::prelude::*;
|
||||
|
||||
pub(crate) struct UnwindContext {
|
||||
endian: RunTimeEndian,
|
||||
|
|
|
@ -6,6 +6,7 @@ use std::path::PathBuf;
|
|||
use std::sync::Arc;
|
||||
use std::thread::JoinHandle;
|
||||
|
||||
use cranelift_object::{ObjectBuilder, ObjectModule};
|
||||
use rustc_codegen_ssa::back::metadata::create_compressed_metadata_file;
|
||||
use rustc_codegen_ssa::{CodegenResults, CompiledModule, CrateInfo, ModuleKind};
|
||||
use rustc_data_structures::profiling::SelfProfilerRef;
|
||||
|
@ -17,8 +18,6 @@ use rustc_session::cgu_reuse_tracker::CguReuse;
|
|||
use rustc_session::config::{DebugInfo, OutputFilenames, OutputType};
|
||||
use rustc_session::Session;
|
||||
|
||||
use cranelift_object::{ObjectBuilder, ObjectModule};
|
||||
|
||||
use crate::concurrency_limiter::{ConcurrencyLimiter, ConcurrencyLimiterToken};
|
||||
use crate::global_asm::GlobalAsmConfig;
|
||||
use crate::{prelude::*, BackendConfig};
|
||||
|
|
|
@ -6,13 +6,12 @@ use std::ffi::CString;
|
|||
use std::os::raw::{c_char, c_int};
|
||||
use std::sync::{mpsc, Mutex, OnceLock};
|
||||
|
||||
use cranelift_jit::{JITBuilder, JITModule};
|
||||
use rustc_codegen_ssa::CrateInfo;
|
||||
use rustc_middle::mir::mono::MonoItem;
|
||||
use rustc_session::Session;
|
||||
use rustc_span::Symbol;
|
||||
|
||||
use cranelift_jit::{JITBuilder, JITModule};
|
||||
|
||||
use crate::{prelude::*, BackendConfig};
|
||||
use crate::{CodegenCx, CodegenMode};
|
||||
|
||||
|
|
|
@ -9,16 +9,22 @@ use std::sync::Arc;
|
|||
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
|
||||
use rustc_hir::{InlineAsmOperand, ItemId};
|
||||
use rustc_session::config::{OutputFilenames, OutputType};
|
||||
use rustc_target::asm::InlineAsmArch;
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String, item_id: ItemId) {
|
||||
let item = tcx.hir().item(item_id);
|
||||
if let rustc_hir::ItemKind::GlobalAsm(asm) = item.kind {
|
||||
if !asm.options.contains(InlineAsmOptions::ATT_SYNTAX) {
|
||||
global_asm.push_str("\n.intel_syntax noprefix\n");
|
||||
} else {
|
||||
global_asm.push_str("\n.att_syntax\n");
|
||||
let is_x86 =
|
||||
matches!(tcx.sess.asm_arch.unwrap(), InlineAsmArch::X86 | InlineAsmArch::X86_64);
|
||||
|
||||
if is_x86 {
|
||||
if !asm.options.contains(InlineAsmOptions::ATT_SYNTAX) {
|
||||
global_asm.push_str("\n.intel_syntax noprefix\n");
|
||||
} else {
|
||||
global_asm.push_str("\n.att_syntax\n");
|
||||
}
|
||||
}
|
||||
for piece in asm.template {
|
||||
match *piece {
|
||||
|
@ -65,7 +71,11 @@ pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String,
|
|||
}
|
||||
}
|
||||
}
|
||||
global_asm.push_str("\n.att_syntax\n\n");
|
||||
|
||||
global_asm.push('\n');
|
||||
if is_x86 {
|
||||
global_asm.push_str(".att_syntax\n\n");
|
||||
}
|
||||
} else {
|
||||
bug!("Expected GlobalAsm found {:?}", item);
|
||||
}
|
||||
|
@ -115,11 +125,12 @@ pub(crate) fn compile_global_asm(
|
|||
}
|
||||
|
||||
// Remove all LLVM style comments
|
||||
let global_asm = global_asm
|
||||
let mut global_asm = global_asm
|
||||
.lines()
|
||||
.map(|line| if let Some(index) = line.find("//") { &line[0..index] } else { line })
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
global_asm.push('\n');
|
||||
|
||||
let output_object_file = config.output_filenames.temp_path(OutputType::Object, Some(cgu_name));
|
||||
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
//! Codegen of `asm!` invocations.
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
use std::fmt::Write;
|
||||
|
||||
use rustc_ast::ast::{InlineAsmOptions, InlineAsmTemplatePiece};
|
||||
use rustc_middle::mir::InlineAsmOperand;
|
||||
use rustc_span::sym;
|
||||
use rustc_target::asm::*;
|
||||
use target_lexicon::BinaryFormat;
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
enum CInlineAsmOperand<'tcx> {
|
||||
In {
|
||||
|
@ -43,7 +44,9 @@ pub(crate) fn codegen_inline_asm<'tcx>(
|
|||
) {
|
||||
// FIXME add .eh_frame unwind info directives
|
||||
|
||||
if !template.is_empty() {
|
||||
if !template.is_empty()
|
||||
&& (cfg!(not(feature = "inline_asm")) || fx.tcx.sess.target.is_like_windows)
|
||||
{
|
||||
// Used by panic_abort
|
||||
if template[0] == InlineAsmTemplatePiece::String("int $$0x29".to_string()) {
|
||||
fx.bcx.ins().trap(TrapCode::User(1));
|
||||
|
@ -589,11 +592,29 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
|
|||
}
|
||||
|
||||
fn generate_asm_wrapper(&self, asm_name: &str) -> String {
|
||||
let binary_format = crate::target_triple(self.tcx.sess).binary_format;
|
||||
|
||||
let mut generated_asm = String::new();
|
||||
writeln!(generated_asm, ".globl {}", asm_name).unwrap();
|
||||
writeln!(generated_asm, ".type {},@function", asm_name).unwrap();
|
||||
writeln!(generated_asm, ".section .text.{},\"ax\",@progbits", asm_name).unwrap();
|
||||
writeln!(generated_asm, "{}:", asm_name).unwrap();
|
||||
match binary_format {
|
||||
BinaryFormat::Elf => {
|
||||
writeln!(generated_asm, ".globl {}", asm_name).unwrap();
|
||||
writeln!(generated_asm, ".type {},@function", asm_name).unwrap();
|
||||
writeln!(generated_asm, ".section .text.{},\"ax\",@progbits", asm_name).unwrap();
|
||||
writeln!(generated_asm, "{}:", asm_name).unwrap();
|
||||
}
|
||||
BinaryFormat::Macho => {
|
||||
writeln!(generated_asm, ".globl _{}", asm_name).unwrap();
|
||||
writeln!(generated_asm, "_{}:", asm_name).unwrap();
|
||||
}
|
||||
BinaryFormat::Coff => {
|
||||
writeln!(generated_asm, ".globl {}", asm_name).unwrap();
|
||||
writeln!(generated_asm, "{}:", asm_name).unwrap();
|
||||
}
|
||||
_ => self
|
||||
.tcx
|
||||
.sess
|
||||
.fatal(format!("Unsupported binary format for inline asm: {binary_format:?}")),
|
||||
}
|
||||
|
||||
let is_x86 = matches!(self.arch, InlineAsmArch::X86 | InlineAsmArch::X86_64);
|
||||
|
||||
|
@ -690,8 +711,19 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
|
|||
if is_x86 {
|
||||
generated_asm.push_str(".att_syntax\n");
|
||||
}
|
||||
writeln!(generated_asm, ".size {name}, .-{name}", name = asm_name).unwrap();
|
||||
generated_asm.push_str(".text\n");
|
||||
|
||||
match binary_format {
|
||||
BinaryFormat::Elf => {
|
||||
writeln!(generated_asm, ".size {name}, .-{name}", name = asm_name).unwrap();
|
||||
generated_asm.push_str(".text\n");
|
||||
}
|
||||
BinaryFormat::Macho | BinaryFormat::Coff => {}
|
||||
_ => self
|
||||
.tcx
|
||||
.sess
|
||||
.fatal(format!("Unsupported binary format for inline asm: {binary_format:?}")),
|
||||
}
|
||||
|
||||
generated_asm.push_str("\n\n");
|
||||
|
||||
generated_asm
|
||||
|
@ -699,25 +731,19 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
|
|||
|
||||
fn prologue(generated_asm: &mut String, arch: InlineAsmArch) {
|
||||
match arch {
|
||||
InlineAsmArch::X86 => {
|
||||
generated_asm.push_str(" push ebp\n");
|
||||
generated_asm.push_str(" mov ebp,[esp+8]\n");
|
||||
}
|
||||
InlineAsmArch::X86_64 => {
|
||||
generated_asm.push_str(" push rbp\n");
|
||||
generated_asm.push_str(" mov rbp,rdi\n");
|
||||
generated_asm.push_str(" mov rbp,rsp\n");
|
||||
generated_asm.push_str(" push rbx\n"); // rbx is callee saved
|
||||
// rbx is reserved by LLVM for the "base pointer", so rustc doesn't allow using it
|
||||
generated_asm.push_str(" mov rbx,rdi\n");
|
||||
}
|
||||
InlineAsmArch::RiscV32 => {
|
||||
generated_asm.push_str(" addi sp, sp, -8\n");
|
||||
generated_asm.push_str(" sw ra, 4(sp)\n");
|
||||
generated_asm.push_str(" sw s0, 0(sp)\n");
|
||||
generated_asm.push_str(" mv s0, a0\n");
|
||||
}
|
||||
InlineAsmArch::RiscV64 => {
|
||||
generated_asm.push_str(" addi sp, sp, -16\n");
|
||||
generated_asm.push_str(" sd ra, 8(sp)\n");
|
||||
generated_asm.push_str(" sd s0, 0(sp)\n");
|
||||
generated_asm.push_str(" mv s0, a0\n");
|
||||
InlineAsmArch::AArch64 => {
|
||||
generated_asm.push_str(" stp fp, lr, [sp, #-32]!\n");
|
||||
generated_asm.push_str(" mov fp, sp\n");
|
||||
generated_asm.push_str(" str x19, [sp, #24]\n"); // x19 is callee saved
|
||||
// x19 is reserved by LLVM for the "base pointer", so rustc doesn't allow using it
|
||||
generated_asm.push_str(" mov x19, x0\n");
|
||||
}
|
||||
_ => unimplemented!("prologue for {:?}", arch),
|
||||
}
|
||||
|
@ -725,24 +751,14 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
|
|||
|
||||
fn epilogue(generated_asm: &mut String, arch: InlineAsmArch) {
|
||||
match arch {
|
||||
InlineAsmArch::X86 => {
|
||||
generated_asm.push_str(" pop ebp\n");
|
||||
generated_asm.push_str(" ret\n");
|
||||
}
|
||||
InlineAsmArch::X86_64 => {
|
||||
generated_asm.push_str(" pop rbx\n");
|
||||
generated_asm.push_str(" pop rbp\n");
|
||||
generated_asm.push_str(" ret\n");
|
||||
}
|
||||
InlineAsmArch::RiscV32 => {
|
||||
generated_asm.push_str(" lw s0, 0(sp)\n");
|
||||
generated_asm.push_str(" lw ra, 4(sp)\n");
|
||||
generated_asm.push_str(" addi sp, sp, 8\n");
|
||||
generated_asm.push_str(" ret\n");
|
||||
}
|
||||
InlineAsmArch::RiscV64 => {
|
||||
generated_asm.push_str(" ld s0, 0(sp)\n");
|
||||
generated_asm.push_str(" ld ra, 8(sp)\n");
|
||||
generated_asm.push_str(" addi sp, sp, 16\n");
|
||||
InlineAsmArch::AArch64 => {
|
||||
generated_asm.push_str(" ldr x19, [sp, #24]\n");
|
||||
generated_asm.push_str(" ldp fp, lr, [sp], #32\n");
|
||||
generated_asm.push_str(" ret\n");
|
||||
}
|
||||
_ => unimplemented!("epilogue for {:?}", arch),
|
||||
|
@ -751,11 +767,11 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
|
|||
|
||||
fn epilogue_noreturn(generated_asm: &mut String, arch: InlineAsmArch) {
|
||||
match arch {
|
||||
InlineAsmArch::X86 | InlineAsmArch::X86_64 => {
|
||||
InlineAsmArch::X86_64 => {
|
||||
generated_asm.push_str(" ud2\n");
|
||||
}
|
||||
InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => {
|
||||
generated_asm.push_str(" ebreak\n");
|
||||
InlineAsmArch::AArch64 => {
|
||||
generated_asm.push_str(" brk #0x1");
|
||||
}
|
||||
_ => unimplemented!("epilogue_noreturn for {:?}", arch),
|
||||
}
|
||||
|
@ -768,25 +784,15 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
|
|||
offset: Size,
|
||||
) {
|
||||
match arch {
|
||||
InlineAsmArch::X86 => {
|
||||
write!(generated_asm, " mov [ebp+0x{:x}], ", offset.bytes()).unwrap();
|
||||
reg.emit(generated_asm, InlineAsmArch::X86, None).unwrap();
|
||||
generated_asm.push('\n');
|
||||
}
|
||||
InlineAsmArch::X86_64 => {
|
||||
write!(generated_asm, " mov [rbp+0x{:x}], ", offset.bytes()).unwrap();
|
||||
write!(generated_asm, " mov [rbx+0x{:x}], ", offset.bytes()).unwrap();
|
||||
reg.emit(generated_asm, InlineAsmArch::X86_64, None).unwrap();
|
||||
generated_asm.push('\n');
|
||||
}
|
||||
InlineAsmArch::RiscV32 => {
|
||||
generated_asm.push_str(" sw ");
|
||||
reg.emit(generated_asm, InlineAsmArch::RiscV32, None).unwrap();
|
||||
writeln!(generated_asm, ", 0x{:x}(s0)", offset.bytes()).unwrap();
|
||||
}
|
||||
InlineAsmArch::RiscV64 => {
|
||||
generated_asm.push_str(" sd ");
|
||||
reg.emit(generated_asm, InlineAsmArch::RiscV64, None).unwrap();
|
||||
writeln!(generated_asm, ", 0x{:x}(s0)", offset.bytes()).unwrap();
|
||||
InlineAsmArch::AArch64 => {
|
||||
generated_asm.push_str(" str ");
|
||||
reg.emit(generated_asm, InlineAsmArch::AArch64, None).unwrap();
|
||||
writeln!(generated_asm, ", [x19, 0x{:x}]", offset.bytes()).unwrap();
|
||||
}
|
||||
_ => unimplemented!("save_register for {:?}", arch),
|
||||
}
|
||||
|
@ -799,25 +805,15 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
|
|||
offset: Size,
|
||||
) {
|
||||
match arch {
|
||||
InlineAsmArch::X86 => {
|
||||
generated_asm.push_str(" mov ");
|
||||
reg.emit(generated_asm, InlineAsmArch::X86, None).unwrap();
|
||||
writeln!(generated_asm, ", [ebp+0x{:x}]", offset.bytes()).unwrap();
|
||||
}
|
||||
InlineAsmArch::X86_64 => {
|
||||
generated_asm.push_str(" mov ");
|
||||
reg.emit(generated_asm, InlineAsmArch::X86_64, None).unwrap();
|
||||
writeln!(generated_asm, ", [rbp+0x{:x}]", offset.bytes()).unwrap();
|
||||
writeln!(generated_asm, ", [rbx+0x{:x}]", offset.bytes()).unwrap();
|
||||
}
|
||||
InlineAsmArch::RiscV32 => {
|
||||
generated_asm.push_str(" lw ");
|
||||
reg.emit(generated_asm, InlineAsmArch::RiscV32, None).unwrap();
|
||||
writeln!(generated_asm, ", 0x{:x}(s0)", offset.bytes()).unwrap();
|
||||
}
|
||||
InlineAsmArch::RiscV64 => {
|
||||
generated_asm.push_str(" ld ");
|
||||
reg.emit(generated_asm, InlineAsmArch::RiscV64, None).unwrap();
|
||||
writeln!(generated_asm, ", 0x{:x}(s0)", offset.bytes()).unwrap();
|
||||
InlineAsmArch::AArch64 => {
|
||||
generated_asm.push_str(" ldr ");
|
||||
reg.emit(generated_asm, InlineAsmArch::AArch64, None).unwrap();
|
||||
writeln!(generated_asm, ", [x19, 0x{:x}]", offset.bytes()).unwrap();
|
||||
}
|
||||
_ => unimplemented!("restore_register for {:?}", arch),
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
//! Emulate LLVM intrinsics
|
||||
|
||||
use rustc_middle::ty::GenericArgsRef;
|
||||
|
||||
use crate::intrinsics::*;
|
||||
use crate::prelude::*;
|
||||
|
||||
use rustc_middle::ty::GenericArgsRef;
|
||||
|
||||
pub(crate) fn codegen_llvm_intrinsic_call<'tcx>(
|
||||
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
||||
intrinsic: &str,
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
//! Emulate AArch64 LLVM intrinsics
|
||||
|
||||
use rustc_middle::ty::GenericArgsRef;
|
||||
|
||||
use crate::intrinsics::*;
|
||||
use crate::prelude::*;
|
||||
|
||||
use rustc_middle::ty::GenericArgsRef;
|
||||
|
||||
pub(crate) fn codegen_aarch64_llvm_intrinsic_call<'tcx>(
|
||||
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
||||
intrinsic: &str,
|
||||
|
@ -156,6 +156,41 @@ pub(crate) fn codegen_aarch64_llvm_intrinsic_call<'tcx>(
|
|||
});
|
||||
}
|
||||
|
||||
// FIXME generalize vector types
|
||||
"llvm.aarch64.neon.tbl1.v16i8" => {
|
||||
intrinsic_args!(fx, args => (t, idx); intrinsic);
|
||||
|
||||
let zero = fx.bcx.ins().iconst(types::I8, 0);
|
||||
for i in 0..16 {
|
||||
let idx_lane = idx.value_lane(fx, i).load_scalar(fx);
|
||||
let is_zero =
|
||||
fx.bcx.ins().icmp_imm(IntCC::UnsignedGreaterThanOrEqual, idx_lane, 16);
|
||||
let t_idx = fx.bcx.ins().uextend(fx.pointer_type, idx_lane);
|
||||
let t_lane = t.value_lane_dyn(fx, t_idx).load_scalar(fx);
|
||||
let res = fx.bcx.ins().select(is_zero, zero, t_lane);
|
||||
ret.place_lane(fx, i).to_ptr().store(fx, res, MemFlags::trusted());
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME generalize vector types
|
||||
"llvm.aarch64.neon.umaxp.v16i8" => {
|
||||
intrinsic_args!(fx, args => (a, b); intrinsic);
|
||||
|
||||
// FIXME add helper for horizontal pairwise operations
|
||||
for i in 0..8 {
|
||||
let lane1 = a.value_lane(fx, i * 2).load_scalar(fx);
|
||||
let lane2 = a.value_lane(fx, i * 2 + 1).load_scalar(fx);
|
||||
let res = fx.bcx.ins().umax(lane1, lane2);
|
||||
ret.place_lane(fx, i).to_ptr().store(fx, res, MemFlags::trusted());
|
||||
}
|
||||
for i in 0..8 {
|
||||
let lane1 = b.value_lane(fx, i * 2).load_scalar(fx);
|
||||
let lane2 = b.value_lane(fx, i * 2 + 1).load_scalar(fx);
|
||||
let res = fx.bcx.ins().umax(lane1, lane2);
|
||||
ret.place_lane(fx, 8 + i).to_ptr().store(fx, res, MemFlags::trusted());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
_ if intrinsic.starts_with("llvm.aarch64.neon.sshl.v")
|
||||
|| intrinsic.starts_with("llvm.aarch64.neon.sqshl.v")
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
//! Emulate x86 LLVM intrinsics
|
||||
|
||||
use rustc_middle::ty::GenericArgsRef;
|
||||
|
||||
use crate::intrinsics::*;
|
||||
use crate::prelude::*;
|
||||
|
||||
use rustc_middle::ty::GenericArgsRef;
|
||||
|
||||
pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
|
||||
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
||||
intrinsic: &str,
|
||||
|
@ -74,8 +74,10 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
|
|||
};
|
||||
let x = codegen_operand(fx, x);
|
||||
let y = codegen_operand(fx, y);
|
||||
let kind = crate::constant::mir_operand_get_const_val(fx, kind)
|
||||
.expect("llvm.x86.sse2.cmp.* kind not const");
|
||||
let kind = match kind {
|
||||
Operand::Constant(const_) => crate::constant::eval_mir_constant(fx, const_).0,
|
||||
Operand::Copy(_) | Operand::Move(_) => unreachable!("{kind:?}"),
|
||||
};
|
||||
|
||||
let flt_cc = match kind
|
||||
.try_to_bits(Size::from_bytes(1))
|
||||
|
|
|
@ -18,17 +18,16 @@ mod llvm_aarch64;
|
|||
mod llvm_x86;
|
||||
mod simd;
|
||||
|
||||
pub(crate) use cpuid::codegen_cpuid_call;
|
||||
pub(crate) use llvm::codegen_llvm_intrinsic_call;
|
||||
|
||||
use cranelift_codegen::ir::AtomicRmwOp;
|
||||
use rustc_middle::ty;
|
||||
use rustc_middle::ty::layout::{HasParamEnv, ValidityRequirement};
|
||||
use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
|
||||
use rustc_middle::ty::GenericArgsRef;
|
||||
use rustc_span::symbol::{kw, sym, Symbol};
|
||||
|
||||
pub(crate) use self::cpuid::codegen_cpuid_call;
|
||||
pub(crate) use self::llvm::codegen_llvm_intrinsic_call;
|
||||
use crate::prelude::*;
|
||||
use cranelift_codegen::ir::AtomicRmwOp;
|
||||
|
||||
fn bug_on_incorrect_arg_count(intrinsic: impl std::fmt::Display) -> ! {
|
||||
bug!("wrong number of args for intrinsic {}", intrinsic);
|
||||
|
|
|
@ -148,7 +148,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
|
|||
let total_len = lane_count * 2;
|
||||
|
||||
let indexes =
|
||||
idx.iter().map(|idx| idx.unwrap_leaf().try_to_u16().unwrap()).collect::<Vec<u16>>();
|
||||
idx.iter().map(|idx| idx.unwrap_leaf().try_to_u32().unwrap()).collect::<Vec<u32>>();
|
||||
|
||||
for &idx in &indexes {
|
||||
assert!(u64::from(idx) < total_len, "idx {} out of range 0..{}", idx, total_len);
|
||||
|
@ -216,8 +216,10 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
|
|||
|
||||
let indexes = {
|
||||
use rustc_middle::mir::interpret::*;
|
||||
let idx_const = crate::constant::mir_operand_get_const_val(fx, idx)
|
||||
.expect("simd_shuffle idx not const");
|
||||
let idx_const = match idx {
|
||||
Operand::Constant(const_) => crate::constant::eval_mir_constant(fx, const_).0,
|
||||
Operand::Copy(_) | Operand::Move(_) => unreachable!("{idx:?}"),
|
||||
};
|
||||
|
||||
let idx_bytes = match idx_const {
|
||||
ConstValue::Indirect { alloc_id, offset } => {
|
||||
|
@ -343,7 +345,11 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
|
|||
ret.write_cvalue(fx, ret_lane);
|
||||
}
|
||||
|
||||
sym::simd_neg => {
|
||||
sym::simd_neg
|
||||
| sym::simd_bswap
|
||||
| sym::simd_bitreverse
|
||||
| sym::simd_ctlz
|
||||
| sym::simd_cttz => {
|
||||
intrinsic_args!(fx, args => (a); intrinsic);
|
||||
|
||||
if !a.layout().ty.is_simd() {
|
||||
|
@ -351,16 +357,21 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
|
|||
return;
|
||||
}
|
||||
|
||||
simd_for_each_lane(
|
||||
fx,
|
||||
a,
|
||||
ret,
|
||||
&|fx, lane_ty, _ret_lane_ty, lane| match lane_ty.kind() {
|
||||
ty::Int(_) => fx.bcx.ins().ineg(lane),
|
||||
ty::Float(_) => fx.bcx.ins().fneg(lane),
|
||||
_ => unreachable!(),
|
||||
},
|
||||
);
|
||||
simd_for_each_lane(fx, a, ret, &|fx, lane_ty, _ret_lane_ty, lane| match (
|
||||
lane_ty.kind(),
|
||||
intrinsic,
|
||||
) {
|
||||
(ty::Int(_), sym::simd_neg) => fx.bcx.ins().ineg(lane),
|
||||
(ty::Float(_), sym::simd_neg) => fx.bcx.ins().fneg(lane),
|
||||
|
||||
(ty::Uint(ty::UintTy::U8) | ty::Int(ty::IntTy::I8), sym::simd_bswap) => lane,
|
||||
(ty::Uint(_) | ty::Int(_), sym::simd_bswap) => fx.bcx.ins().bswap(lane),
|
||||
(ty::Uint(_) | ty::Int(_), sym::simd_bitreverse) => fx.bcx.ins().bitrev(lane),
|
||||
(ty::Uint(_) | ty::Int(_), sym::simd_ctlz) => fx.bcx.ins().clz(lane),
|
||||
(ty::Uint(_) | ty::Int(_), sym::simd_cttz) => fx.bcx.ins().ctz(lane),
|
||||
|
||||
_ => unreachable!(),
|
||||
});
|
||||
}
|
||||
|
||||
sym::simd_add
|
||||
|
|
|
@ -29,6 +29,8 @@ use std::any::Any;
|
|||
use std::cell::{Cell, RefCell};
|
||||
use std::sync::Arc;
|
||||
|
||||
use cranelift_codegen::isa::TargetIsa;
|
||||
use cranelift_codegen::settings::{self, Configurable};
|
||||
use rustc_codegen_ssa::traits::CodegenBackend;
|
||||
use rustc_codegen_ssa::CodegenResults;
|
||||
use rustc_data_structures::profiling::SelfProfilerRef;
|
||||
|
@ -39,9 +41,6 @@ use rustc_session::config::OutputFilenames;
|
|||
use rustc_session::Session;
|
||||
use rustc_span::Symbol;
|
||||
|
||||
use cranelift_codegen::isa::TargetIsa;
|
||||
use cranelift_codegen::settings::{self, Configurable};
|
||||
|
||||
pub use crate::config::*;
|
||||
use crate::prelude::*;
|
||||
|
||||
|
@ -76,22 +75,6 @@ mod value_and_place;
|
|||
mod vtable;
|
||||
|
||||
mod prelude {
|
||||
pub(crate) use rustc_span::{FileNameDisplayPreference, Span};
|
||||
|
||||
pub(crate) use rustc_hir::def_id::{DefId, LOCAL_CRATE};
|
||||
pub(crate) use rustc_middle::bug;
|
||||
pub(crate) use rustc_middle::mir::{self, *};
|
||||
pub(crate) use rustc_middle::ty::layout::{self, LayoutOf, TyAndLayout};
|
||||
pub(crate) use rustc_middle::ty::{
|
||||
self, FloatTy, Instance, InstanceDef, IntTy, ParamEnv, Ty, TyCtxt, TypeAndMut,
|
||||
TypeFoldable, TypeVisitableExt, UintTy,
|
||||
};
|
||||
pub(crate) use rustc_target::abi::{Abi, FieldIdx, Scalar, Size, VariantIdx, FIRST_VARIANT};
|
||||
|
||||
pub(crate) use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
|
||||
|
||||
pub(crate) use rustc_index::Idx;
|
||||
|
||||
pub(crate) use cranelift_codegen::ir::condcodes::{FloatCC, IntCC};
|
||||
pub(crate) use cranelift_codegen::ir::function::Function;
|
||||
pub(crate) use cranelift_codegen::ir::types;
|
||||
|
@ -103,6 +86,18 @@ mod prelude {
|
|||
pub(crate) use cranelift_codegen::Context;
|
||||
pub(crate) use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext, Variable};
|
||||
pub(crate) use cranelift_module::{self, DataDescription, FuncId, Linkage, Module};
|
||||
pub(crate) use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
|
||||
pub(crate) use rustc_hir::def_id::{DefId, LOCAL_CRATE};
|
||||
pub(crate) use rustc_index::Idx;
|
||||
pub(crate) use rustc_middle::bug;
|
||||
pub(crate) use rustc_middle::mir::{self, *};
|
||||
pub(crate) use rustc_middle::ty::layout::{self, LayoutOf, TyAndLayout};
|
||||
pub(crate) use rustc_middle::ty::{
|
||||
self, FloatTy, Instance, InstanceDef, IntTy, ParamEnv, Ty, TyCtxt, TypeAndMut,
|
||||
TypeFoldable, TypeVisitableExt, UintTy,
|
||||
};
|
||||
pub(crate) use rustc_span::{FileNameDisplayPreference, Span};
|
||||
pub(crate) use rustc_target::abi::{Abi, FieldIdx, Scalar, Size, VariantIdx, FIRST_VARIANT};
|
||||
|
||||
pub(crate) use crate::abi::*;
|
||||
pub(crate) use crate::base::{codegen_operand, codegen_place};
|
||||
|
@ -263,9 +258,9 @@ fn build_isa(sess: &Session, backend_config: &BackendConfig) -> Arc<dyn isa::Tar
|
|||
let preserve_frame_pointer = sess.target.options.frame_pointer
|
||||
!= rustc_target::spec::FramePointer::MayOmit
|
||||
|| matches!(sess.opts.cg.force_frame_pointers, Some(true));
|
||||
if preserve_frame_pointer {
|
||||
flags_builder.set("preserve_frame_pointers", "true").unwrap();
|
||||
}
|
||||
flags_builder
|
||||
.set("preserve_frame_pointers", if preserve_frame_pointer { "true" } else { "false" })
|
||||
.unwrap();
|
||||
|
||||
let tls_model = match target_triple.binary_format {
|
||||
BinaryFormat::Elf => "elf_gd",
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
//! Defines [`Pointer`] which is used to improve the quality of the generated clif ir for pointer
|
||||
//! operations.
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
use cranelift_codegen::ir::immediates::Offset32;
|
||||
use rustc_target::abi::Align;
|
||||
|
||||
use cranelift_codegen::ir::immediates::Offset32;
|
||||
use crate::prelude::*;
|
||||
|
||||
/// A pointer pointing either to a certain address, a certain stack slot or nothing.
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
|
|
|
@ -63,8 +63,8 @@ use cranelift_codegen::{
|
|||
ir::entities::AnyEntity,
|
||||
write::{FuncWriter, PlainWriter},
|
||||
};
|
||||
|
||||
use rustc_middle::ty::layout::FnAbiOf;
|
||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||
use rustc_session::config::{OutputFilenames, OutputType};
|
||||
|
||||
use crate::prelude::*;
|
||||
|
@ -80,15 +80,17 @@ impl CommentWriter {
|
|||
pub(crate) fn new<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> Self {
|
||||
let enabled = should_write_ir(tcx);
|
||||
let global_comments = if enabled {
|
||||
vec![
|
||||
format!("symbol {}", tcx.symbol_name(instance).name),
|
||||
format!("instance {:?}", instance),
|
||||
format!(
|
||||
"abi {:?}",
|
||||
RevealAllLayoutCx(tcx).fn_abi_of_instance(instance, ty::List::empty())
|
||||
),
|
||||
String::new(),
|
||||
]
|
||||
with_no_trimmed_paths!({
|
||||
vec![
|
||||
format!("symbol {}", tcx.symbol_name(instance).name),
|
||||
format!("instance {:?}", instance),
|
||||
format!(
|
||||
"abi {:?}",
|
||||
RevealAllLayoutCx(tcx).fn_abi_of_instance(instance, ty::List::empty())
|
||||
),
|
||||
String::new(),
|
||||
]
|
||||
})
|
||||
} else {
|
||||
vec![]
|
||||
};
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
//! Definition of [`CValue`] and [`CPlace`]
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
use rustc_middle::ty::FnSig;
|
||||
|
||||
use cranelift_codegen::entity::EntityRef;
|
||||
use cranelift_codegen::ir::immediates::Offset32;
|
||||
use rustc_middle::ty::FnSig;
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
fn codegen_field<'tcx>(
|
||||
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
||||
|
@ -310,7 +309,8 @@ impl<'tcx> CValue<'tcx> {
|
|||
fx.bcx.ins().iconcat(lsb, msb)
|
||||
}
|
||||
ty::Bool | ty::Char | ty::Uint(_) | ty::Int(_) | ty::Ref(..) | ty::RawPtr(..) => {
|
||||
fx.bcx.ins().iconst(clif_ty, const_val.to_bits(layout.size).unwrap() as i64)
|
||||
let raw_val = const_val.size().truncate(const_val.to_bits(layout.size).unwrap());
|
||||
fx.bcx.ins().iconst(clif_ty, raw_val as i64)
|
||||
}
|
||||
ty::Float(FloatTy::F32) => {
|
||||
fx.bcx.ins().f32const(Ieee32::with_bits(u32::try_from(const_val).unwrap()))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue