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