rustc_smir/rustc_smir/convert/
abi.rs1#![allow(rustc::usage_of_qualified_ty)]
4
5use rustc_abi::{ArmCall, CanonAbi, InterruptKind, X86Call};
6use rustc_middle::ty;
7use rustc_target::callconv;
8use stable_mir::abi::{
9 AddressSpace, ArgAbi, CallConvention, FieldsShape, FloatLength, FnAbi, IntegerLength,
10 IntegerType, Layout, LayoutShape, PassMode, Primitive, ReprFlags, ReprOptions, Scalar,
11 TagEncoding, TyAndLayout, ValueAbi, VariantsShape, WrappingRange,
12};
13use stable_mir::opaque;
14use stable_mir::target::MachineSize as Size;
15use stable_mir::ty::{Align, IndexedVal, VariantIdx};
16
17use crate::rustc_smir::{Stable, Tables};
18use crate::stable_mir;
19
20impl<'tcx> Stable<'tcx> for rustc_abi::VariantIdx {
21 type T = VariantIdx;
22 fn stable(&self, _: &mut Tables<'_>) -> Self::T {
23 VariantIdx::to_val(self.as_usize())
24 }
25}
26
27impl<'tcx> Stable<'tcx> for rustc_abi::Endian {
28 type T = stable_mir::target::Endian;
29
30 fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
31 match self {
32 rustc_abi::Endian::Little => stable_mir::target::Endian::Little,
33 rustc_abi::Endian::Big => stable_mir::target::Endian::Big,
34 }
35 }
36}
37
38impl<'tcx> Stable<'tcx> for rustc_abi::TyAndLayout<'tcx, ty::Ty<'tcx>> {
39 type T = TyAndLayout;
40
41 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
42 TyAndLayout { ty: self.ty.stable(tables), layout: self.layout.stable(tables) }
43 }
44}
45
46impl<'tcx> Stable<'tcx> for rustc_abi::Layout<'tcx> {
47 type T = Layout;
48
49 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
50 tables.layout_id(tables.tcx.lift(*self).unwrap())
51 }
52}
53
54impl<'tcx> Stable<'tcx> for rustc_abi::LayoutData<rustc_abi::FieldIdx, rustc_abi::VariantIdx> {
55 type T = LayoutShape;
56
57 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
58 LayoutShape {
59 fields: self.fields.stable(tables),
60 variants: self.variants.stable(tables),
61 abi: self.backend_repr.stable(tables),
62 abi_align: self.align.abi.stable(tables),
63 size: self.size.stable(tables),
64 }
65 }
66}
67
68impl<'tcx> Stable<'tcx> for callconv::FnAbi<'tcx, ty::Ty<'tcx>> {
69 type T = FnAbi;
70
71 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
72 assert!(self.args.len() >= self.fixed_count as usize);
73 assert!(!self.c_variadic || matches!(self.conv, CanonAbi::C));
74 FnAbi {
75 args: self.args.as_ref().stable(tables),
76 ret: self.ret.stable(tables),
77 fixed_count: self.fixed_count,
78 conv: self.conv.stable(tables),
79 c_variadic: self.c_variadic,
80 }
81 }
82}
83
84impl<'tcx> Stable<'tcx> for callconv::ArgAbi<'tcx, ty::Ty<'tcx>> {
85 type T = ArgAbi;
86
87 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
88 ArgAbi {
89 ty: self.layout.ty.stable(tables),
90 layout: self.layout.layout.stable(tables),
91 mode: self.mode.stable(tables),
92 }
93 }
94}
95
96impl<'tcx> Stable<'tcx> for CanonAbi {
97 type T = CallConvention;
98
99 fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
100 match self {
101 CanonAbi::C => CallConvention::C,
102 CanonAbi::Rust => CallConvention::Rust,
103 CanonAbi::RustCold => CallConvention::Cold,
104 CanonAbi::Custom => CallConvention::Custom,
105 CanonAbi::Arm(arm_call) => match arm_call {
106 ArmCall::Aapcs => CallConvention::ArmAapcs,
107 ArmCall::CCmseNonSecureCall => CallConvention::CCmseNonSecureCall,
108 ArmCall::CCmseNonSecureEntry => CallConvention::CCmseNonSecureEntry,
109 },
110 CanonAbi::GpuKernel => CallConvention::GpuKernel,
111 CanonAbi::Interrupt(interrupt_kind) => match interrupt_kind {
112 InterruptKind::Avr => CallConvention::AvrInterrupt,
113 InterruptKind::AvrNonBlocking => CallConvention::AvrNonBlockingInterrupt,
114 InterruptKind::Msp430 => CallConvention::Msp430Intr,
115 InterruptKind::RiscvMachine | InterruptKind::RiscvSupervisor => {
116 CallConvention::RiscvInterrupt
117 }
118 InterruptKind::X86 => CallConvention::X86Intr,
119 },
120 CanonAbi::X86(x86_call) => match x86_call {
121 X86Call::Fastcall => CallConvention::X86Fastcall,
122 X86Call::Stdcall => CallConvention::X86Stdcall,
123 X86Call::SysV64 => CallConvention::X86_64SysV,
124 X86Call::Thiscall => CallConvention::X86ThisCall,
125 X86Call::Vectorcall => CallConvention::X86VectorCall,
126 X86Call::Win64 => CallConvention::X86_64Win64,
127 },
128 }
129 }
130}
131
132impl<'tcx> Stable<'tcx> for callconv::PassMode {
133 type T = PassMode;
134
135 fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
136 match self {
137 callconv::PassMode::Ignore => PassMode::Ignore,
138 callconv::PassMode::Direct(attr) => PassMode::Direct(opaque(attr)),
139 callconv::PassMode::Pair(first, second) => {
140 PassMode::Pair(opaque(first), opaque(second))
141 }
142 callconv::PassMode::Cast { pad_i32, cast } => {
143 PassMode::Cast { pad_i32: *pad_i32, cast: opaque(cast) }
144 }
145 callconv::PassMode::Indirect { attrs, meta_attrs, on_stack } => PassMode::Indirect {
146 attrs: opaque(attrs),
147 meta_attrs: opaque(meta_attrs),
148 on_stack: *on_stack,
149 },
150 }
151 }
152}
153
154impl<'tcx> Stable<'tcx> for rustc_abi::FieldsShape<rustc_abi::FieldIdx> {
155 type T = FieldsShape;
156
157 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
158 match self {
159 rustc_abi::FieldsShape::Primitive => FieldsShape::Primitive,
160 rustc_abi::FieldsShape::Union(count) => FieldsShape::Union(*count),
161 rustc_abi::FieldsShape::Array { stride, count } => {
162 FieldsShape::Array { stride: stride.stable(tables), count: *count }
163 }
164 rustc_abi::FieldsShape::Arbitrary { offsets, .. } => {
165 FieldsShape::Arbitrary { offsets: offsets.iter().as_slice().stable(tables) }
166 }
167 }
168 }
169}
170
171impl<'tcx> Stable<'tcx> for rustc_abi::Variants<rustc_abi::FieldIdx, rustc_abi::VariantIdx> {
172 type T = VariantsShape;
173
174 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
175 match self {
176 rustc_abi::Variants::Single { index } => {
177 VariantsShape::Single { index: index.stable(tables) }
178 }
179 rustc_abi::Variants::Empty => VariantsShape::Empty,
180 rustc_abi::Variants::Multiple { tag, tag_encoding, tag_field, variants } => {
181 VariantsShape::Multiple {
182 tag: tag.stable(tables),
183 tag_encoding: tag_encoding.stable(tables),
184 tag_field: tag_field.stable(tables),
185 variants: variants.iter().as_slice().stable(tables),
186 }
187 }
188 }
189 }
190}
191
192impl<'tcx> Stable<'tcx> for rustc_abi::TagEncoding<rustc_abi::VariantIdx> {
193 type T = TagEncoding;
194
195 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
196 match self {
197 rustc_abi::TagEncoding::Direct => TagEncoding::Direct,
198 rustc_abi::TagEncoding::Niche { untagged_variant, niche_variants, niche_start } => {
199 TagEncoding::Niche {
200 untagged_variant: untagged_variant.stable(tables),
201 niche_variants: niche_variants.stable(tables),
202 niche_start: *niche_start,
203 }
204 }
205 }
206 }
207}
208
209impl<'tcx> Stable<'tcx> for rustc_abi::BackendRepr {
210 type T = ValueAbi;
211
212 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
213 match *self {
214 rustc_abi::BackendRepr::Scalar(scalar) => ValueAbi::Scalar(scalar.stable(tables)),
215 rustc_abi::BackendRepr::ScalarPair(first, second) => {
216 ValueAbi::ScalarPair(first.stable(tables), second.stable(tables))
217 }
218 rustc_abi::BackendRepr::SimdVector { element, count } => {
219 ValueAbi::Vector { element: element.stable(tables), count }
220 }
221 rustc_abi::BackendRepr::Memory { sized } => ValueAbi::Aggregate { sized },
222 }
223 }
224}
225
226impl<'tcx> Stable<'tcx> for rustc_abi::Size {
227 type T = Size;
228
229 fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
230 Size::from_bits(self.bits_usize())
231 }
232}
233
234impl<'tcx> Stable<'tcx> for rustc_abi::Align {
235 type T = Align;
236
237 fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
238 self.bytes()
239 }
240}
241
242impl<'tcx> Stable<'tcx> for rustc_abi::Scalar {
243 type T = Scalar;
244
245 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
246 match self {
247 rustc_abi::Scalar::Initialized { value, valid_range } => Scalar::Initialized {
248 value: value.stable(tables),
249 valid_range: valid_range.stable(tables),
250 },
251 rustc_abi::Scalar::Union { value } => Scalar::Union { value: value.stable(tables) },
252 }
253 }
254}
255
256impl<'tcx> Stable<'tcx> for rustc_abi::Primitive {
257 type T = Primitive;
258
259 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
260 match self {
261 rustc_abi::Primitive::Int(length, signed) => {
262 Primitive::Int { length: length.stable(tables), signed: *signed }
263 }
264 rustc_abi::Primitive::Float(length) => {
265 Primitive::Float { length: length.stable(tables) }
266 }
267 rustc_abi::Primitive::Pointer(space) => Primitive::Pointer(space.stable(tables)),
268 }
269 }
270}
271
272impl<'tcx> Stable<'tcx> for rustc_abi::AddressSpace {
273 type T = AddressSpace;
274
275 fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
276 AddressSpace(self.0)
277 }
278}
279
280impl<'tcx> Stable<'tcx> for rustc_abi::Integer {
281 type T = IntegerLength;
282
283 fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
284 match self {
285 rustc_abi::Integer::I8 => IntegerLength::I8,
286 rustc_abi::Integer::I16 => IntegerLength::I16,
287 rustc_abi::Integer::I32 => IntegerLength::I32,
288 rustc_abi::Integer::I64 => IntegerLength::I64,
289 rustc_abi::Integer::I128 => IntegerLength::I128,
290 }
291 }
292}
293
294impl<'tcx> Stable<'tcx> for rustc_abi::Float {
295 type T = FloatLength;
296
297 fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
298 match self {
299 rustc_abi::Float::F16 => FloatLength::F16,
300 rustc_abi::Float::F32 => FloatLength::F32,
301 rustc_abi::Float::F64 => FloatLength::F64,
302 rustc_abi::Float::F128 => FloatLength::F128,
303 }
304 }
305}
306
307impl<'tcx> Stable<'tcx> for rustc_abi::WrappingRange {
308 type T = WrappingRange;
309
310 fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
311 WrappingRange { start: self.start, end: self.end }
312 }
313}
314
315impl<'tcx> Stable<'tcx> for rustc_abi::ReprFlags {
316 type T = ReprFlags;
317
318 fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
319 ReprFlags {
320 is_simd: self.intersects(Self::IS_SIMD),
321 is_c: self.intersects(Self::IS_C),
322 is_transparent: self.intersects(Self::IS_TRANSPARENT),
323 is_linear: self.intersects(Self::IS_LINEAR),
324 }
325 }
326}
327
328impl<'tcx> Stable<'tcx> for rustc_abi::IntegerType {
329 type T = IntegerType;
330
331 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
332 match self {
333 rustc_abi::IntegerType::Pointer(signed) => IntegerType::Pointer { is_signed: *signed },
334 rustc_abi::IntegerType::Fixed(integer, signed) => {
335 IntegerType::Fixed { length: integer.stable(tables), is_signed: *signed }
336 }
337 }
338 }
339}
340
341impl<'tcx> Stable<'tcx> for rustc_abi::ReprOptions {
342 type T = ReprOptions;
343
344 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
345 ReprOptions {
346 int: self.int.map(|int| int.stable(tables)),
347 align: self.align.map(|align| align.stable(tables)),
348 pack: self.pack.map(|pack| pack.stable(tables)),
349 flags: self.flags.stable(tables),
350 }
351 }
352}