1#![allow(non_camel_case_types)]
2
3use rustc_crate_store::{DllCallingConvention, DllImport, DllImportSymbolType};
4use rustc_hir::attrs::PeImportNameType;
5use rustc_hir::attrs::lang_items::LangItem;
6use rustc_middle::mir::interpret::{GlobalAlloc, PointerArithmetic, Scalar};
7use rustc_middle::ty::layout::TyAndLayout;
8use rustc_middle::ty::{self, Instance, ScalarInt, TyCtxt};
9use rustc_middle::{bug, span_bug};
10use rustc_span::Span;
11use rustc_target::spec::{CfgAbi, Env, Os, Target};
12
13use crate::traits::*;
14
15#[derive(#[automatically_derived]
impl ::core::marker::Copy for IntPredicate { }Copy, #[automatically_derived]
impl ::core::clone::Clone for IntPredicate {
#[inline]
fn clone(&self) -> IntPredicate { *self }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for IntPredicate {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
static __NAMES: &str =
"IntEQIntNEIntUGTIntUGEIntULTIntULEIntSGTIntSGEIntSLTIntSLE";
static __OFFSET: [usize; 11] =
[0usize, 5usize, 10usize, 16usize, 22usize, 28usize, 34usize,
40usize, 46usize, 52usize, 58usize];
let __d = ::core::intrinsics::discriminant_value(self) as usize;
::core::fmt::Formatter::debug_c_like_enum_write_str(f, __NAMES,
&__OFFSET, __d)
}
}Debug)]
16pub enum IntPredicate {
17 IntEQ,
18 IntNE,
19 IntUGT,
20 IntUGE,
21 IntULT,
22 IntULE,
23 IntSGT,
24 IntSGE,
25 IntSLT,
26 IntSLE,
27}
28
29#[derive(#[automatically_derived]
impl ::core::marker::Copy for RealPredicate { }Copy, #[automatically_derived]
impl ::core::clone::Clone for RealPredicate {
#[inline]
fn clone(&self) -> RealPredicate { *self }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for RealPredicate {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
static __NAMES: &str =
"RealPredicateFalseRealOEQRealOGTRealOGERealOLTRealOLERealONERealORDRealUNORealUEQRealUGTRealUGERealULTRealULERealUNERealPredicateTrue";
static __OFFSET: [usize; 17] =
[0usize, 18usize, 25usize, 32usize, 39usize, 46usize, 53usize,
60usize, 67usize, 74usize, 81usize, 88usize, 95usize,
102usize, 109usize, 116usize, 133usize];
let __d = ::core::intrinsics::discriminant_value(self) as usize;
::core::fmt::Formatter::debug_c_like_enum_write_str(f, __NAMES,
&__OFFSET, __d)
}
}Debug)]
30pub enum RealPredicate {
31 RealPredicateFalse,
32 RealOEQ,
33 RealOGT,
34 RealOGE,
35 RealOLT,
36 RealOLE,
37 RealONE,
38 RealORD,
39 RealUNO,
40 RealUEQ,
41 RealUGT,
42 RealUGE,
43 RealULT,
44 RealULE,
45 RealUNE,
46 RealPredicateTrue,
47}
48
49#[derive(#[automatically_derived]
impl ::core::marker::Copy for AtomicRmwBinOp { }Copy, #[automatically_derived]
impl ::core::clone::Clone for AtomicRmwBinOp {
#[inline]
fn clone(&self) -> AtomicRmwBinOp { *self }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for AtomicRmwBinOp {
#[inline]
fn eq(&self, other: &AtomicRmwBinOp) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::fmt::Debug for AtomicRmwBinOp {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
static __NAMES: &str =
"AtomicXchgAtomicAddAtomicSubAtomicAndAtomicNandAtomicOrAtomicXorAtomicMaxAtomicMinAtomicUMaxAtomicUMin";
static __OFFSET: [usize; 12] =
[0usize, 10usize, 19usize, 28usize, 37usize, 47usize, 55usize,
64usize, 73usize, 82usize, 92usize, 102usize];
let __d = ::core::intrinsics::discriminant_value(self) as usize;
::core::fmt::Formatter::debug_c_like_enum_write_str(f, __NAMES,
&__OFFSET, __d)
}
}Debug)]
50pub enum AtomicRmwBinOp {
51 AtomicXchg,
52 AtomicAdd,
53 AtomicSub,
54 AtomicAnd,
55 AtomicNand,
56 AtomicOr,
57 AtomicXor,
58 AtomicMax,
59 AtomicMin,
60 AtomicUMax,
61 AtomicUMin,
62}
63
64#[derive(#[automatically_derived]
impl ::core::marker::Copy for SynchronizationScope { }Copy, #[automatically_derived]
impl ::core::clone::Clone for SynchronizationScope {
#[inline]
fn clone(&self) -> SynchronizationScope { *self }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for SynchronizationScope {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
SynchronizationScope::SingleThread => "SingleThread",
SynchronizationScope::CrossThread => "CrossThread",
})
}
}Debug)]
65pub enum SynchronizationScope {
66 SingleThread,
67 CrossThread,
68}
69
70#[derive(#[automatically_derived]
impl ::core::marker::Copy for TypeKind { }Copy, #[automatically_derived]
impl ::core::clone::Clone for TypeKind {
#[inline]
fn clone(&self) -> TypeKind { *self }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for TypeKind {
#[inline]
fn eq(&self, other: &TypeKind) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::fmt::Debug for TypeKind {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
static __NAMES: &str =
"VoidHalfFloatDoubleX86_FP80FP128PPC_FP128LabelIntegerFunctionStructArrayPointerVectorMetadataTokenScalableVectorBFloatX86_AMX";
static __OFFSET: [usize; 20] =
[0usize, 4usize, 8usize, 13usize, 19usize, 27usize, 32usize,
41usize, 46usize, 53usize, 61usize, 67usize, 72usize,
79usize, 85usize, 93usize, 98usize, 112usize, 118usize,
125usize];
let __d = ::core::intrinsics::discriminant_value(self) as usize;
::core::fmt::Formatter::debug_c_like_enum_write_str(f, __NAMES,
&__OFFSET, __d)
}
}Debug)]
71pub enum TypeKind {
72 Void,
73 Half,
74 Float,
75 Double,
76 X86_FP80,
77 FP128,
78 PPC_FP128,
79 Label,
80 Integer,
81 Function,
82 Struct,
83 Array,
84 Pointer,
85 Vector,
86 Metadata,
87 Token,
88 ScalableVector,
89 BFloat,
90 X86_AMX,
91}
92
93mod temp_stable_hash_impls {
102 use rustc_data_structures::stable_hash::{StableHash, StableHashCtxt, StableHasher};
103
104 use crate::ModuleCodegen;
105
106 impl<M> StableHash for ModuleCodegen<M> {
107 fn stable_hash<Hcx: StableHashCtxt>(&self, _: &mut Hcx, _: &mut StableHasher) {
108 }
110 }
111}
112
113pub(crate) fn build_langcall<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
114 bx: &Bx,
115 span: Span,
116 li: LangItem,
117) -> (Bx::FnAbiOfResult, Bx::Value, Instance<'tcx>) {
118 let tcx = bx.tcx();
119 let def_id = tcx.require_lang_item(li, span);
120 let instance = ty::Instance::mono(tcx, def_id);
121 (
122 bx.fn_abi_of_instance(instance, ty::List::empty()),
123 bx.get_fn_addr(instance, tcx.sess.pointer_authentication_functions()),
124 instance,
125 )
126}
127
128pub(crate) fn shift_mask_val<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
129 bx: &mut Bx,
130 llty: Bx::Type,
131 mask_llty: Bx::Type,
132 invert: bool,
133) -> Bx::Value {
134 let kind = bx.type_kind(llty);
135 match kind {
136 TypeKind::Integer => {
137 let val = bx.int_width(llty) - 1;
139 if invert {
140 bx.const_int(mask_llty, !val as i64)
141 } else {
142 bx.const_uint(mask_llty, val)
143 }
144 }
145 TypeKind::Vector => {
146 let mask =
147 shift_mask_val(bx, bx.element_type(llty), bx.element_type(mask_llty), invert);
148 bx.vector_splat(bx.vector_length(mask_llty), mask)
149 }
150 _ => ::rustc_middle::util::bug::bug_fmt(format_args!("shift_mask_val: expected Integer or Vector, found {0:?}",
kind))bug!("shift_mask_val: expected Integer or Vector, found {:?}", kind),
151 }
152}
153
154pub fn asm_const_to_str<'tcx>(
155 tcx: TyCtxt<'tcx>,
156 sp: Span,
157 scalar: ScalarInt,
158 ty_and_layout: TyAndLayout<'tcx>,
159) -> String {
160 let value = scalar.to_bits(ty_and_layout.size);
161 match ty_and_layout.ty.kind() {
162 ty::Uint(_) => value.to_string(),
163 ty::Int(int_ty) => match int_ty.normalize(tcx.sess.target.pointer_width) {
164 ty::IntTy::I8 => (value as i8).to_string(),
165 ty::IntTy::I16 => (value as i16).to_string(),
166 ty::IntTy::I32 => (value as i32).to_string(),
167 ty::IntTy::I64 => (value as i64).to_string(),
168 ty::IntTy::I128 => (value as i128).to_string(),
169 ty::IntTy::Isize => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
170 },
171 ty::Ref(..) | ty::RawPtr(..) | ty::FnPtr(..) => value.to_string(),
173 _ => ::rustc_middle::util::bug::span_bug_fmt(sp,
format_args!("asm const has bad type {0}", ty_and_layout.ty))span_bug!(sp, "asm const has bad type {}", ty_and_layout.ty),
174 }
175}
176
177pub fn asm_const_ptr_clean<'tcx>(tcx: TyCtxt<'tcx>, scalar: Scalar) -> Scalar {
182 let Scalar::Ptr(ptr, _) = scalar else {
183 return scalar;
184 };
185 let (prov, offset) = ptr.prov_and_relative_offset();
186 let global_alloc = tcx.global_alloc(prov.alloc_id());
187 match global_alloc {
188 GlobalAlloc::TypeId { .. } => {
189 Scalar::from_u64(offset.bytes())
191 }
192 GlobalAlloc::Memory(alloc) if alloc.inner().len() == 0 => {
193 let val = alloc.inner().align.bytes().wrapping_add(offset.bytes());
196 Scalar::from_target_usize(tcx.truncate_to_target_usize(val), &tcx)
197 }
198 _ => scalar,
200 }
201}
202
203pub fn is_mingw_gnu_toolchain(target: &Target) -> bool {
204 target.os == Os::Windows && target.env == Env::Gnu && target.cfg_abi == CfgAbi::Unspecified
205}
206
207pub fn i686_decorated_name(
208 dll_import: &DllImport,
209 mingw: bool,
210 disable_name_mangling: bool,
211 force_fully_decorated: bool,
212) -> String {
213 let name = dll_import.name.as_str();
214
215 let (add_prefix, add_suffix) = match (force_fully_decorated, dll_import.import_name_type) {
216 (_, Some(PeImportNameType::NoPrefix)) => (false, true),
219 (false, Some(PeImportNameType::Undecorated)) => (false, false),
220 _ => (true, true),
221 };
222
223 let mut decorated_name = String::with_capacity(name.len() + 6);
225
226 if disable_name_mangling {
227 decorated_name.push('\x01');
230 }
231
232 let prefix = if add_prefix && dll_import.symbol_type == DllImportSymbolType::Function {
233 match dll_import.calling_convention {
234 DllCallingConvention::C | DllCallingConvention::Vectorcall(_) => None,
235 DllCallingConvention::Stdcall(_) => (!mingw
236 || dll_import.import_name_type == Some(PeImportNameType::Decorated))
237 .then_some('_'),
238 DllCallingConvention::Fastcall(_) => Some('@'),
239 }
240 } else if dll_import.symbol_type != DllImportSymbolType::Function && !mingw {
241 Some('_')
243 } else {
244 None
245 };
246 if let Some(prefix) = prefix {
247 decorated_name.push(prefix);
248 }
249
250 decorated_name.push_str(name);
251
252 if add_suffix && dll_import.symbol_type == DllImportSymbolType::Function {
253 use std::fmt::Write;
254
255 match dll_import.calling_convention {
256 DllCallingConvention::C => {}
257 DllCallingConvention::Stdcall(arg_list_size)
258 | DllCallingConvention::Fastcall(arg_list_size) => {
259 (&mut decorated_name).write_fmt(format_args!("@{0}", arg_list_size))write!(&mut decorated_name, "@{arg_list_size}").unwrap();
260 }
261 DllCallingConvention::Vectorcall(arg_list_size) => {
262 (&mut decorated_name).write_fmt(format_args!("@@{0}", arg_list_size))write!(&mut decorated_name, "@@{arg_list_size}").unwrap();
263 }
264 }
265 }
266
267 decorated_name
268}