]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_codegen_ssa/src/common.rs
Rollup merge of #83462 - ijackson:exitstatus-message-wording, r=joshtriplett
[rust.git] / compiler / rustc_codegen_ssa / src / common.rs
1 #![allow(non_camel_case_types)]
2
3 use rustc_errors::struct_span_err;
4 use rustc_hir as hir;
5 use rustc_hir::def_id::DefId;
6 use rustc_hir::LangItem;
7 use rustc_middle::ty::{Ty, TyCtxt};
8 use rustc_session::Session;
9 use rustc_span::Span;
10
11 use crate::base;
12 use crate::traits::BuilderMethods;
13 use crate::traits::*;
14
15 pub 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 pub enum RealPredicate {
29     RealPredicateFalse,
30     RealOEQ,
31     RealOGT,
32     RealOGE,
33     RealOLT,
34     RealOLE,
35     RealONE,
36     RealORD,
37     RealUNO,
38     RealUEQ,
39     RealUGT,
40     RealUGE,
41     RealULT,
42     RealULE,
43     RealUNE,
44     RealPredicateTrue,
45 }
46
47 pub enum AtomicRmwBinOp {
48     AtomicXchg,
49     AtomicAdd,
50     AtomicSub,
51     AtomicAnd,
52     AtomicNand,
53     AtomicOr,
54     AtomicXor,
55     AtomicMax,
56     AtomicMin,
57     AtomicUMax,
58     AtomicUMin,
59 }
60
61 pub enum AtomicOrdering {
62     NotAtomic,
63     Unordered,
64     Monotonic,
65     // Consume,  // Not specified yet.
66     Acquire,
67     Release,
68     AcquireRelease,
69     SequentiallyConsistent,
70 }
71
72 pub enum SynchronizationScope {
73     SingleThread,
74     CrossThread,
75 }
76
77 #[derive(Copy, Clone, PartialEq, Debug)]
78 pub enum TypeKind {
79     Void,
80     Half,
81     Float,
82     Double,
83     X86_FP80,
84     FP128,
85     PPC_FP128,
86     Label,
87     Integer,
88     Function,
89     Struct,
90     Array,
91     Pointer,
92     Vector,
93     Metadata,
94     X86_MMX,
95     Token,
96     ScalableVector,
97     BFloat,
98     X86_AMX,
99 }
100
101 // FIXME(mw): Anything that is produced via DepGraph::with_task() must implement
102 //            the HashStable trait. Normally DepGraph::with_task() calls are
103 //            hidden behind queries, but CGU creation is a special case in two
104 //            ways: (1) it's not a query and (2) CGU are output nodes, so their
105 //            Fingerprints are not actually needed. It remains to be clarified
106 //            how exactly this case will be handled in the red/green system but
107 //            for now we content ourselves with providing a no-op HashStable
108 //            implementation for CGUs.
109 mod temp_stable_hash_impls {
110     use crate::ModuleCodegen;
111     use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
112
113     impl<HCX, M> HashStable<HCX> for ModuleCodegen<M> {
114         fn hash_stable(&self, _: &mut HCX, _: &mut StableHasher) {
115             // do nothing
116         }
117     }
118 }
119
120 pub fn langcall(tcx: TyCtxt<'_>, span: Option<Span>, msg: &str, li: LangItem) -> DefId {
121     tcx.lang_items().require(li).unwrap_or_else(|s| {
122         let msg = format!("{} {}", msg, s);
123         match span {
124             Some(span) => tcx.sess.span_fatal(span, &msg[..]),
125             None => tcx.sess.fatal(&msg[..]),
126         }
127     })
128 }
129
130 // To avoid UB from LLVM, these two functions mask RHS with an
131 // appropriate mask unconditionally (i.e., the fallback behavior for
132 // all shifts). For 32- and 64-bit types, this matches the semantics
133 // of Java. (See related discussion on #1877 and #10183.)
134
135 pub fn build_unchecked_lshift<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
136     bx: &mut Bx,
137     lhs: Bx::Value,
138     rhs: Bx::Value,
139 ) -> Bx::Value {
140     let rhs = base::cast_shift_expr_rhs(bx, hir::BinOpKind::Shl, lhs, rhs);
141     // #1877, #10183: Ensure that input is always valid
142     let rhs = shift_mask_rhs(bx, rhs);
143     bx.shl(lhs, rhs)
144 }
145
146 pub fn build_unchecked_rshift<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
147     bx: &mut Bx,
148     lhs_t: Ty<'tcx>,
149     lhs: Bx::Value,
150     rhs: Bx::Value,
151 ) -> Bx::Value {
152     let rhs = base::cast_shift_expr_rhs(bx, hir::BinOpKind::Shr, lhs, rhs);
153     // #1877, #10183: Ensure that input is always valid
154     let rhs = shift_mask_rhs(bx, rhs);
155     let is_signed = lhs_t.is_signed();
156     if is_signed { bx.ashr(lhs, rhs) } else { bx.lshr(lhs, rhs) }
157 }
158
159 fn shift_mask_rhs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
160     bx: &mut Bx,
161     rhs: Bx::Value,
162 ) -> Bx::Value {
163     let rhs_llty = bx.val_ty(rhs);
164     let shift_val = shift_mask_val(bx, rhs_llty, rhs_llty, false);
165     bx.and(rhs, shift_val)
166 }
167
168 pub fn shift_mask_val<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
169     bx: &mut Bx,
170     llty: Bx::Type,
171     mask_llty: Bx::Type,
172     invert: bool,
173 ) -> Bx::Value {
174     let kind = bx.type_kind(llty);
175     match kind {
176         TypeKind::Integer => {
177             // i8/u8 can shift by at most 7, i16/u16 by at most 15, etc.
178             let val = bx.int_width(llty) - 1;
179             if invert {
180                 bx.const_int(mask_llty, !val as i64)
181             } else {
182                 bx.const_uint(mask_llty, val)
183             }
184         }
185         TypeKind::Vector => {
186             let mask =
187                 shift_mask_val(bx, bx.element_type(llty), bx.element_type(mask_llty), invert);
188             bx.vector_splat(bx.vector_length(mask_llty), mask)
189         }
190         _ => bug!("shift_mask_val: expected Integer or Vector, found {:?}", kind),
191     }
192 }
193
194 pub fn span_invalid_monomorphization_error(a: &Session, b: Span, c: &str) {
195     struct_span_err!(a, b, E0511, "{}", c).emit();
196 }