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