repc_impl/builder/
common.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2#![allow(clippy::match_like_matches_macro)]
3
4use crate::layout::{BuiltinType, Type, TypeLayout, TypeVariant};
5use crate::result::Result;
6use crate::target::Target;
7use crate::util::{MinExt, BITS_PER_BYTE};
8
9pub fn compute_builtin_type_layout(target: Target, bi: BuiltinType) -> Result<Type<TypeLayout>> {
10    Ok(Type {
11        layout: builtin_type_layout(target, bi),
12        // Pre-validation ensures that builtin types do not have annotations.
13        annotations: vec![],
14        variant: TypeVariant::Builtin(bi),
15    })
16}
17
18pub fn compute_opaque_type_layout(layout: TypeLayout) -> Result<Type<TypeLayout>> {
19    Ok(Type {
20        layout,
21        // Pre-validation ensures that opaque types do not have annotations.
22        annotations: vec![],
23        variant: TypeVariant::Opaque(layout),
24    })
25}
26
27pub fn apply_alignment_override(layout: TypeLayout, alignment: Option<u64>) -> TypeLayout {
28    TypeLayout {
29        field_alignment_bits: alignment.unwrap_or(layout.field_alignment_bits),
30        pointer_alignment_bits: alignment.min2(layout.pointer_alignment_bits),
31        ..layout
32    }
33}
34
35pub fn unnamed_field_affects_record_alignment(target: Target) -> bool {
36    use Target::*;
37    match target {
38        | Aarch64Fuchsia
39        | Aarch64LinuxAndroid
40        | Aarch64UnknownFreebsd
41        | Aarch64UnknownHermit
42        | Aarch64UnknownLinuxGnu
43        | Aarch64UnknownLinuxMusl
44        | Aarch64UnknownNetbsd
45        | Aarch64UnknownNone
46        | Aarch64UnknownOpenbsd
47        | Aarch64UnknownRedox
48        | Armebv7rUnknownNoneEabi
49        | Armebv7rUnknownNoneEabihf
50        | ArmLinuxAndroideabi
51        | ArmUnknownLinuxGnueabi
52        | ArmUnknownLinuxGnueabihf
53        | Armv4tUnknownLinuxGnueabi
54        | Armv5teUnknownLinuxGnueabi
55        | Armv5teUnknownLinuxUclibcgnueabi
56        | Armv6UnknownFreebsdGnueabihf
57        | Armv6UnknownNetbsdelfEabihf
58        | Armv7aNoneEabi
59        | Armv7aNoneEabihf
60        | Armv7AppleIos
61        | Armv7NoneLinuxAndroid
62        | Armv7rUnknownNoneEabi
63        | Armv7rUnknownNoneEabihf
64        | Armv7sAppleIos
65        | Armv7UnknownFreebsdGnueabihf
66        | Armv7UnknownLinuxGnueabi
67        | Armv7UnknownLinuxGnueabihf
68        | Armv7UnknownNetbsdelfEabihf
69        | AvrUnknownUnknown
70        | Thumbv4tNoneEabi
71        | Thumbv6mNoneEabi
72        | Thumbv7emNoneEabi
73        | Thumbv7emNoneEabihf
74        | Thumbv7mNoneEabi
75        | Thumbv8mBaseNoneEabi
76        | Thumbv8mMainNoneEabi
77        | Thumbv8mMainNoneEabihf => true,
78        _ => false,
79    }
80}
81
82pub fn min_zero_width_bitfield_alignment(target: Target) -> Option<u64> {
83    use Target::*;
84    match target {
85        AvrUnknownUnknown => Some(8),
86        Armv7AppleIos | Armv7sAppleIos => Some(32),
87        _ => None,
88    }
89}
90
91pub fn builtin_type_layout(target: Target, b: BuiltinType) -> TypeLayout {
92    use BuiltinType::*;
93    use Target::*;
94
95    match target {
96        AvrUnknownUnknown => return avr_builtin_type_layout(b),
97        Msp430NoneElf => return msp430_builtin_type_layout(b),
98        _ => {}
99    }
100
101    // See test case 0013.
102    let (size_bytes, alignment_bytes) = match b {
103        Unit => (0, 1),
104        Char | SignedChar | UnsignedChar | Bool | U8 | I8 => (1, 1),
105        Short | UnsignedShort | U16 | I16 => (2, 2),
106        Float | F32 | Int | UnsignedInt | U32 | I32 => (4, 4),
107        Double | F64 | LongLong | UnsignedLongLong | U64 | I64 => match target {
108            I386AppleIos | I686LinuxAndroid | I686UnknownFreebsd | I686UnknownHaiku
109            | I686UnknownNetbsdelf | I686UnknownOpenbsd | Armv7AppleIos | Armv7sAppleIos
110            | I586UnknownLinuxGnu | I586UnknownLinuxMusl | I686UnknownLinuxGnu
111            | I686UnknownLinuxMusl | I686AppleMacosx => (8, 4),
112            _ => (8, 8),
113        },
114        // See test case 0050.
115        U128 | I128 => match target {
116            S390xUnknownLinuxGnu => (16, 8),
117            _ => (16, 16),
118        },
119        Long | UnsignedLong => match target {
120            | Aarch64PcWindowsMsvc
121            | Armebv7rUnknownNoneEabi
122            | Armebv7rUnknownNoneEabihf
123            | ArmLinuxAndroideabi
124            | ArmUnknownLinuxGnueabi
125            | ArmUnknownLinuxGnueabihf
126            | Armv4tUnknownLinuxGnueabi
127            | Armv5teUnknownLinuxGnueabi
128            | Armv5teUnknownLinuxUclibcgnueabi
129            | Armv6UnknownFreebsdGnueabihf
130            | Armv6UnknownNetbsdelfEabihf
131            | Armv7aNoneEabi
132            | Armv7aNoneEabihf
133            | Armv7AppleIos
134            | Armv7NoneLinuxAndroid
135            | Armv7rUnknownNoneEabi
136            | Armv7rUnknownNoneEabihf
137            | Armv7sAppleIos
138            | Armv7UnknownFreebsdGnueabihf
139            | Armv7UnknownLinuxGnueabi
140            | Armv7UnknownLinuxGnueabihf
141            | Armv7UnknownNetbsdelfEabihf
142            | AvrUnknownUnknown
143            | HexagonUnknownLinuxMusl
144            | I386AppleIos
145            | I586PcWindowsMsvc
146            | I586UnknownLinuxGnu
147            | I586UnknownLinuxMusl
148            | I686AppleMacosx
149            | I686LinuxAndroid
150            | I686PcWindowsGnu
151            | I686PcWindowsMsvc
152            | I686UnknownFreebsd
153            | I686UnknownHaiku
154            | I686UnknownLinuxGnu
155            | I686UnknownLinuxMusl
156            | I686UnknownNetbsdelf
157            | I686UnknownOpenbsd
158            | I686UnknownWindows
159            | MipselSonyPsp
160            | MipselUnknownLinuxGnu
161            | MipselUnknownLinuxMusl
162            | MipselUnknownLinuxUclibc
163            | MipselUnknownNone
164            | Mipsisa32r6elUnknownLinuxGnu
165            | Mipsisa32r6UnknownLinuxGnu
166            | MipsUnknownLinuxGnu
167            | MipsUnknownLinuxMusl
168            | MipsUnknownLinuxUclibc
169            | Msp430NoneElf
170            | PowerpcUnknownLinuxGnu
171            | PowerpcUnknownLinuxGnuspe
172            | PowerpcUnknownLinuxMusl
173            | PowerpcUnknownNetbsd
174            | Riscv32
175            | Riscv32UnknownLinuxGnu
176            | SparcUnknownLinuxGnu
177            | Thumbv4tNoneEabi
178            | Thumbv6mNoneEabi
179            | Thumbv7aPcWindowsMsvc
180            | Thumbv7emNoneEabi
181            | Thumbv7emNoneEabihf
182            | Thumbv7mNoneEabi
183            | Thumbv8mBaseNoneEabi
184            | Thumbv8mMainNoneEabi
185            | Thumbv8mMainNoneEabihf
186            | Wasm32UnknownEmscripten
187            | Wasm32UnknownUnknown
188            | Wasm32Wasi
189            | X86_64UnknownLinuxGnux32
190            | X86_64PcWindowsGnu
191            | X86_64PcWindowsMsvc
192            | X86_64UnknownWindows => (4, 4),
193            _ => (8, 8),
194        },
195        Pointer => match target {
196            | Armebv7rUnknownNoneEabi
197            | Armebv7rUnknownNoneEabihf
198            | ArmLinuxAndroideabi
199            | ArmUnknownLinuxGnueabi
200            | ArmUnknownLinuxGnueabihf
201            | Armv4tUnknownLinuxGnueabi
202            | Armv5teUnknownLinuxGnueabi
203            | Armv5teUnknownLinuxUclibcgnueabi
204            | Armv6UnknownFreebsdGnueabihf
205            | Armv6UnknownNetbsdelfEabihf
206            | Armv7aNoneEabi
207            | Armv7aNoneEabihf
208            | Armv7AppleIos
209            | Armv7NoneLinuxAndroid
210            | Armv7rUnknownNoneEabi
211            | Armv7rUnknownNoneEabihf
212            | Armv7sAppleIos
213            | Armv7UnknownFreebsdGnueabihf
214            | Armv7UnknownLinuxGnueabi
215            | Armv7UnknownLinuxGnueabihf
216            | Armv7UnknownNetbsdelfEabihf
217            | AvrUnknownUnknown
218            | HexagonUnknownLinuxMusl
219            | I386AppleIos
220            | I586PcWindowsMsvc
221            | I586UnknownLinuxGnu
222            | I586UnknownLinuxMusl
223            | I686AppleMacosx
224            | I686LinuxAndroid
225            | I686PcWindowsGnu
226            | I686PcWindowsMsvc
227            | I686UnknownFreebsd
228            | I686UnknownHaiku
229            | I686UnknownLinuxGnu
230            | I686UnknownLinuxMusl
231            | I686UnknownNetbsdelf
232            | I686UnknownOpenbsd
233            | I686UnknownWindows
234            | MipselSonyPsp
235            | MipselUnknownLinuxGnu
236            | MipselUnknownLinuxMusl
237            | MipselUnknownLinuxUclibc
238            | MipselUnknownNone
239            | Mipsisa32r6elUnknownLinuxGnu
240            | Mipsisa32r6UnknownLinuxGnu
241            | MipsUnknownLinuxGnu
242            | MipsUnknownLinuxMusl
243            | MipsUnknownLinuxUclibc
244            | Msp430NoneElf
245            | PowerpcUnknownLinuxGnu
246            | PowerpcUnknownLinuxGnuspe
247            | PowerpcUnknownLinuxMusl
248            | PowerpcUnknownNetbsd
249            | Riscv32
250            | Riscv32UnknownLinuxGnu
251            | SparcUnknownLinuxGnu
252            | Thumbv4tNoneEabi
253            | Thumbv6mNoneEabi
254            | Thumbv7aPcWindowsMsvc
255            | Thumbv7emNoneEabi
256            | Thumbv7emNoneEabihf
257            | Thumbv7mNoneEabi
258            | Thumbv8mBaseNoneEabi
259            | Thumbv8mMainNoneEabi
260            | Thumbv8mMainNoneEabihf
261            | Wasm32UnknownEmscripten
262            | Wasm32UnknownUnknown
263            | Wasm32Wasi
264            | X86_64UnknownLinuxGnux32 => (4, 4),
265            _ => (8, 8),
266        },
267    };
268    TypeLayout {
269        size_bits: size_bytes * BITS_PER_BYTE,
270        pointer_alignment_bits: alignment_bytes * BITS_PER_BYTE,
271        field_alignment_bits: alignment_bytes * BITS_PER_BYTE,
272        required_alignment_bits: BITS_PER_BYTE,
273    }
274}
275
276pub fn avr_builtin_type_layout(b: BuiltinType) -> TypeLayout {
277    use BuiltinType::*;
278
279    let size_bytes = match b {
280        Unit => 0,
281        Char | SignedChar | UnsignedChar | Bool | U8 | I8 => 1,
282        Pointer | Short | UnsignedShort | U16 | I16 | Int | UnsignedInt => 2,
283        Long | UnsignedLong | Double | Float | F32 | U32 | I32 => 4,
284        F64 | LongLong | UnsignedLongLong | U64 | I64 => 8,
285        U128 | I128 => 16,
286    };
287    TypeLayout {
288        size_bits: size_bytes * BITS_PER_BYTE,
289        pointer_alignment_bits: BITS_PER_BYTE,
290        field_alignment_bits: BITS_PER_BYTE,
291        required_alignment_bits: BITS_PER_BYTE,
292    }
293}
294
295pub fn msp430_builtin_type_layout(b: BuiltinType) -> TypeLayout {
296    use BuiltinType::*;
297
298    let mut alignment = 2;
299
300    let size_bytes = match b {
301        Unit => 0,
302        Char | SignedChar | UnsignedChar | Bool | U8 | I8 => {
303            alignment = 1;
304            1
305        }
306        Pointer | Short | UnsignedShort | U16 | I16 | Int | UnsignedInt => 2,
307        Long | UnsignedLong | Float | F32 | U32 | I32 => 4,
308        Double | F64 | LongLong | UnsignedLongLong | U64 | I64 => 8,
309        U128 | I128 => 16,
310    };
311    TypeLayout {
312        size_bits: size_bytes * BITS_PER_BYTE,
313        pointer_alignment_bits: alignment * BITS_PER_BYTE,
314        field_alignment_bits: alignment * BITS_PER_BYTE,
315        required_alignment_bits: BITS_PER_BYTE,
316    }
317}
318
319pub fn ignore_non_zero_sized_bitfield_type_alignment(target: Target) -> bool {
320    use Target::*;
321    match target {
322        AvrUnknownUnknown | Armv7AppleIos | Armv7sAppleIos => true,
323        _ => false,
324    }
325}
326
327pub fn ignore_zero_sized_bitfield_type_alignmont(target: Target) -> bool {
328    use Target::*;
329    match target {
330        AvrUnknownUnknown => true,
331        _ => false,
332    }
333}
334
335pub fn pack_all_enums(target: Target) -> bool {
336    use Target::*;
337    match target {
338        HexagonUnknownLinuxMusl => true,
339        _ => false,
340    }
341}
342
343pub fn default_aligned_alignment(target: Target) -> u64 {
344    use Target::*;
345    match target {
346        | AvrUnknownUnknown => 8,
347        | ArmUnknownLinuxGnueabi
348        | ArmUnknownLinuxGnueabihf
349        | Armebv7rUnknownNoneEabi
350        | Armebv7rUnknownNoneEabihf
351        | Armv4tUnknownLinuxGnueabi
352        | Armv5teUnknownLinuxGnueabi
353        | Armv5teUnknownLinuxUclibcgnueabi
354        | Armv6UnknownFreebsdGnueabihf
355        | Armv6UnknownNetbsdelfEabihf
356        | Armv7UnknownFreebsdGnueabihf
357        | Armv7UnknownLinuxGnueabi
358        | Armv7UnknownLinuxGnueabihf
359        | Armv7UnknownNetbsdelfEabihf
360        | Armv7aNoneEabi
361        | Armv7aNoneEabihf
362        | Armv7rUnknownNoneEabi
363        | Armv7rUnknownNoneEabihf
364        | MipsUnknownLinuxGnu
365        | MipsUnknownLinuxMusl
366        | MipsUnknownLinuxUclibc
367        | MipselUnknownLinuxGnu
368        | MipselUnknownLinuxMusl
369        | MipselUnknownLinuxUclibc
370        | Mipsisa32r6UnknownLinuxGnu
371        | Mipsisa32r6elUnknownLinuxGnu
372        | S390xUnknownLinuxGnu
373        | SparcUnknownLinuxGnu
374        | Thumbv4tNoneEabi
375        | Thumbv6mNoneEabi
376        | Thumbv7aPcWindowsMsvc
377        | Thumbv7emNoneEabi
378        | Thumbv7emNoneEabihf
379        | Thumbv7mNoneEabi
380        | Thumbv8mBaseNoneEabi
381        | Thumbv8mMainNoneEabi
382        | Thumbv8mMainNoneEabihf => 64,
383        _ => 128,
384    }
385}