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, Layout,
10 LayoutShape, PassMode, Primitive, Scalar, TagEncoding, TyAndLayout, ValueAbi, VariantsShape,
11 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::Arm(arm_call) => match arm_call {
105 ArmCall::Aapcs => CallConvention::ArmAapcs,
106 ArmCall::CCmseNonSecureCall => CallConvention::CCmseNonSecureCall,
107 ArmCall::CCmseNonSecureEntry => CallConvention::CCmseNonSecureEntry,
108 },
109 CanonAbi::GpuKernel => CallConvention::GpuKernel,
110 CanonAbi::Interrupt(interrupt_kind) => match interrupt_kind {
111 InterruptKind::Avr => CallConvention::AvrInterrupt,
112 InterruptKind::AvrNonBlocking => CallConvention::AvrNonBlockingInterrupt,
113 InterruptKind::Msp430 => CallConvention::Msp430Intr,
114 InterruptKind::RiscvMachine | InterruptKind::RiscvSupervisor => {
115 CallConvention::RiscvInterrupt
116 }
117 InterruptKind::X86 => CallConvention::X86Intr,
118 },
119 CanonAbi::X86(x86_call) => match x86_call {
120 X86Call::Fastcall => CallConvention::X86Fastcall,
121 X86Call::Stdcall => CallConvention::X86Stdcall,
122 X86Call::SysV64 => CallConvention::X86_64SysV,
123 X86Call::Thiscall => CallConvention::X86ThisCall,
124 X86Call::Vectorcall => CallConvention::X86VectorCall,
125 X86Call::Win64 => CallConvention::X86_64Win64,
126 },
127 }
128 }
129}
130
131impl<'tcx> Stable<'tcx> for callconv::PassMode {
132 type T = PassMode;
133
134 fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
135 match self {
136 callconv::PassMode::Ignore => PassMode::Ignore,
137 callconv::PassMode::Direct(attr) => PassMode::Direct(opaque(attr)),
138 callconv::PassMode::Pair(first, second) => {
139 PassMode::Pair(opaque(first), opaque(second))
140 }
141 callconv::PassMode::Cast { pad_i32, cast } => {
142 PassMode::Cast { pad_i32: *pad_i32, cast: opaque(cast) }
143 }
144 callconv::PassMode::Indirect { attrs, meta_attrs, on_stack } => PassMode::Indirect {
145 attrs: opaque(attrs),
146 meta_attrs: opaque(meta_attrs),
147 on_stack: *on_stack,
148 },
149 }
150 }
151}
152
153impl<'tcx> Stable<'tcx> for rustc_abi::FieldsShape<rustc_abi::FieldIdx> {
154 type T = FieldsShape;
155
156 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
157 match self {
158 rustc_abi::FieldsShape::Primitive => FieldsShape::Primitive,
159 rustc_abi::FieldsShape::Union(count) => FieldsShape::Union(*count),
160 rustc_abi::FieldsShape::Array { stride, count } => {
161 FieldsShape::Array { stride: stride.stable(tables), count: *count }
162 }
163 rustc_abi::FieldsShape::Arbitrary { offsets, .. } => {
164 FieldsShape::Arbitrary { offsets: offsets.iter().as_slice().stable(tables) }
165 }
166 }
167 }
168}
169
170impl<'tcx> Stable<'tcx> for rustc_abi::Variants<rustc_abi::FieldIdx, rustc_abi::VariantIdx> {
171 type T = VariantsShape;
172
173 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
174 match self {
175 rustc_abi::Variants::Single { index } => {
176 VariantsShape::Single { index: index.stable(tables) }
177 }
178 rustc_abi::Variants::Empty => VariantsShape::Empty,
179 rustc_abi::Variants::Multiple { tag, tag_encoding, tag_field, variants } => {
180 VariantsShape::Multiple {
181 tag: tag.stable(tables),
182 tag_encoding: tag_encoding.stable(tables),
183 tag_field: tag_field.stable(tables),
184 variants: variants.iter().as_slice().stable(tables),
185 }
186 }
187 }
188 }
189}
190
191impl<'tcx> Stable<'tcx> for rustc_abi::TagEncoding<rustc_abi::VariantIdx> {
192 type T = TagEncoding;
193
194 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
195 match self {
196 rustc_abi::TagEncoding::Direct => TagEncoding::Direct,
197 rustc_abi::TagEncoding::Niche { untagged_variant, niche_variants, niche_start } => {
198 TagEncoding::Niche {
199 untagged_variant: untagged_variant.stable(tables),
200 niche_variants: niche_variants.stable(tables),
201 niche_start: *niche_start,
202 }
203 }
204 }
205 }
206}
207
208impl<'tcx> Stable<'tcx> for rustc_abi::BackendRepr {
209 type T = ValueAbi;
210
211 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
212 match *self {
213 rustc_abi::BackendRepr::Scalar(scalar) => ValueAbi::Scalar(scalar.stable(tables)),
214 rustc_abi::BackendRepr::ScalarPair(first, second) => {
215 ValueAbi::ScalarPair(first.stable(tables), second.stable(tables))
216 }
217 rustc_abi::BackendRepr::SimdVector { element, count } => {
218 ValueAbi::Vector { element: element.stable(tables), count }
219 }
220 rustc_abi::BackendRepr::Memory { sized } => ValueAbi::Aggregate { sized },
221 }
222 }
223}
224
225impl<'tcx> Stable<'tcx> for rustc_abi::Size {
226 type T = Size;
227
228 fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
229 Size::from_bits(self.bits_usize())
230 }
231}
232
233impl<'tcx> Stable<'tcx> for rustc_abi::Align {
234 type T = Align;
235
236 fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
237 self.bytes()
238 }
239}
240
241impl<'tcx> Stable<'tcx> for rustc_abi::Scalar {
242 type T = Scalar;
243
244 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
245 match self {
246 rustc_abi::Scalar::Initialized { value, valid_range } => Scalar::Initialized {
247 value: value.stable(tables),
248 valid_range: valid_range.stable(tables),
249 },
250 rustc_abi::Scalar::Union { value } => Scalar::Union { value: value.stable(tables) },
251 }
252 }
253}
254
255impl<'tcx> Stable<'tcx> for rustc_abi::Primitive {
256 type T = Primitive;
257
258 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
259 match self {
260 rustc_abi::Primitive::Int(length, signed) => {
261 Primitive::Int { length: length.stable(tables), signed: *signed }
262 }
263 rustc_abi::Primitive::Float(length) => {
264 Primitive::Float { length: length.stable(tables) }
265 }
266 rustc_abi::Primitive::Pointer(space) => Primitive::Pointer(space.stable(tables)),
267 }
268 }
269}
270
271impl<'tcx> Stable<'tcx> for rustc_abi::AddressSpace {
272 type T = AddressSpace;
273
274 fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
275 AddressSpace(self.0)
276 }
277}
278
279impl<'tcx> Stable<'tcx> for rustc_abi::Integer {
280 type T = IntegerLength;
281
282 fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
283 match self {
284 rustc_abi::Integer::I8 => IntegerLength::I8,
285 rustc_abi::Integer::I16 => IntegerLength::I16,
286 rustc_abi::Integer::I32 => IntegerLength::I32,
287 rustc_abi::Integer::I64 => IntegerLength::I64,
288 rustc_abi::Integer::I128 => IntegerLength::I128,
289 }
290 }
291}
292
293impl<'tcx> Stable<'tcx> for rustc_abi::Float {
294 type T = FloatLength;
295
296 fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
297 match self {
298 rustc_abi::Float::F16 => FloatLength::F16,
299 rustc_abi::Float::F32 => FloatLength::F32,
300 rustc_abi::Float::F64 => FloatLength::F64,
301 rustc_abi::Float::F128 => FloatLength::F128,
302 }
303 }
304}
305
306impl<'tcx> Stable<'tcx> for rustc_abi::WrappingRange {
307 type T = WrappingRange;
308
309 fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
310 WrappingRange { start: self.start, end: self.end }
311 }
312}