@@ -2,7 +2,7 @@ use std::collections::{BTreeMap, BTreeSet};
2
2
3
3
use serde_json:: Value as JsonValue ;
4
4
5
- use crate :: { AbiFromJsonErr , ArmCall , CanonAbi , ExternAbi , InterruptKind } ;
5
+ use crate :: { AbiFromJsonErr , ArmCall , CanonAbi , ExternAbi , InterruptKind , X86Call } ;
6
6
7
7
#[ derive( Clone , Debug , PartialEq , Eq , Hash ) ]
8
8
pub struct AbiMap {
@@ -15,14 +15,16 @@ pub struct AbiMap {
15
15
/// ABI used for `extern "rust-cold"`
16
16
pub rust_cold : CanonAbi ,
17
17
18
- // optional abstract ABIs
18
+ // optional architecture-specific ABIs, should always answer a certain way per-arch
19
19
pub efiapi : Option < CanonAbi > ,
20
+ pub win64 : Option < CanonAbi > ,
21
+ pub sysv64 : Option < CanonAbi > ,
22
+
23
+ // optional abstract ABIs, these can be very weird
20
24
pub stdcall : Option < CanonAbi > ,
21
25
pub fastcall : Option < CanonAbi > ,
22
26
pub thiscall : Option < CanonAbi > ,
23
27
pub vectorcall : Option < CanonAbi > ,
24
- pub win64 : Option < CanonAbi > ,
25
- pub sysv64 : Option < CanonAbi > ,
26
28
27
29
// optional concrete ABIs
28
30
// arm
@@ -204,6 +206,51 @@ impl AbiMap {
204
206
}
205
207
}
206
208
209
+ // construction
210
+
211
+ impl AbiMap {
212
+ pub fn base_for_arch ( arch : & str ) -> AbiMap {
213
+ match arch {
214
+ "aarch64" => AbiMap { efiapi : Some ( CanonAbi :: C ) , ..Default :: default ( ) } ,
215
+ "amdgpu" => AbiMap { gpu_kernel : true , ..Default :: default ( ) } ,
216
+ "arm" => AbiMap {
217
+ aapcs : true ,
218
+ efiapi : Some ( CanonAbi :: Arm ( ArmCall :: Aapcs ) ) ,
219
+ ..Default :: default ( )
220
+ } ,
221
+ "avr" => AbiMap { avr_interrupt : true , ..Default :: default ( ) } ,
222
+ "msp430" => AbiMap { msp430_interrupt : true , ..Default :: default ( ) } ,
223
+ "nvptx64" => AbiMap { ptx_kernel : true , gpu_kernel : true , ..Default :: default ( ) } ,
224
+ "riscv32" | "riscv64" => {
225
+ AbiMap { efiapi : Some ( CanonAbi :: C ) , riscv_interrupt : true , ..Default :: default ( ) }
226
+ }
227
+ "x86" => {
228
+ AbiMap {
229
+ efiapi : Some ( CanonAbi :: C ) ,
230
+ x86_interrupt : true ,
231
+
232
+ //FIXME(jubilee): it seems unlikely we want this?
233
+ vectorcall : Some ( CanonAbi :: X86 ( X86Call :: Vectorcall ) ) ,
234
+
235
+ ..Default :: default ( )
236
+ }
237
+ }
238
+ "x86_64" => AbiMap {
239
+ efiapi : Some ( CanonAbi :: X86 ( X86Call :: Win64 ) ) ,
240
+ sysv64 : Some ( CanonAbi :: X86 ( X86Call :: SysV64 ) ) ,
241
+ win64 : Some ( CanonAbi :: X86 ( X86Call :: Win64 ) ) ,
242
+ x86_interrupt : true ,
243
+
244
+ //FIXME(jubilee): it seems unlikely we want this?
245
+ vectorcall : Some ( CanonAbi :: X86 ( X86Call :: Vectorcall ) ) ,
246
+
247
+ ..Default :: default ( )
248
+ } ,
249
+ _ => Default :: default ( ) ,
250
+ }
251
+ }
252
+ }
253
+
207
254
// deserialization
208
255
209
256
type JsonObject = serde_json:: Map < String , JsonValue > ;
@@ -241,31 +288,19 @@ fn extract_bool_abi(
241
288
}
242
289
243
290
impl AbiMap {
244
- pub fn from_json_object (
291
+ pub fn from_arch_and_json (
292
+ arch : & str ,
245
293
mut json : JsonObject ,
246
- ) -> Result < Self , BTreeMap < String , AbiFromJsonErr > > {
294
+ ) -> ( Self , BTreeMap < String , AbiFromJsonErr > ) {
247
295
// extract all keys we are interested in
248
296
let required_c_abis =
249
297
[ "C" , "system" , "system-varargs" ] . map ( |abi_str| extract_abi_str ( & mut json, abi_str) ) ;
250
298
let rust_cold = extract_abi_str ( & mut json, "rust-cold" ) ;
251
- let bool_abis = [
252
- // arm...
253
- "aapcs" ,
254
- "cmse-nonsecure-entry" ,
255
- // ...gpu...
256
- "gpu-kernel" ,
257
- "ptx-kernel" ,
258
- // ...interrupt
259
- "avr-interrupt" ,
260
- "msp430-interrupt" ,
261
- "riscv-interrupt" ,
262
- "x86-interrupt" ,
263
- ]
264
- . map ( |abi_str| extract_bool_abi ( & mut json, abi_str) ) ;
265
- // x86ish
266
- let optional_abis =
267
- [ "efiapi" , "stdcall" , "fastcall" , "thiscall" , "vectorcall" , "win64" , "sysv64" ]
268
- . map ( |abi_str| extract_abi_str ( & mut json, abi_str) ) ;
299
+ let bool_abis =
300
+ [ "aapcs" , "cmse-nonsecure-entry" ] . map ( |abi_str| extract_bool_abi ( & mut json, abi_str) ) ;
301
+ // x86ish optional ABIs
302
+ let optional_abis = [ "stdcall" , "fastcall" , "thiscall" , "vectorcall" ]
303
+ . map ( |abi_str| extract_abi_str ( & mut json, abi_str) ) ;
269
304
270
305
// accumulate errors
271
306
// create an iterator of invalid types and bad parses
@@ -283,28 +318,22 @@ impl AbiMap {
283
318
. chain ( errs. cloned ( ) )
284
319
. collect :: < BTreeMap < _ , _ > > ( ) ;
285
320
286
- if error_map. len ( ) > 0 {
287
- Err ( error_map)
288
- } else {
289
- // oh? success? merry giftmas! time to unwrap your presents
290
- // these have default ABIs to select
291
- let [ c_proper, system, system_varargs] =
292
- required_c_abis. map ( |result| result. unwrap ( ) . unwrap_or ( CanonAbi :: C ) ) ;
293
- let rust_cold = rust_cold. unwrap ( ) . unwrap_or ( CanonAbi :: RustCold ) ;
294
-
295
- // these stay options, but shell the Result
296
- let [ efiapi, stdcall, fastcall, thiscall, vectorcall, win64, sysv64] =
297
- optional_abis. map ( |result| result. unwrap ( ) ) ;
298
-
299
- // these simplify to booleans
300
- let bool_abis = bool_abis. map ( |result| result. unwrap ( ) . unwrap_or ( false ) ) ;
301
- // repeat the mantra: arm...
302
- let [ aapcs, cmse_nonsecure_entry, bool_abis @ ..] = bool_abis;
303
- // ...gpu...
304
- let [ gpu_kernel, ptx_kernel, bool_abis @ ..] = bool_abis;
305
- // ...interrupt
306
- let [ avr_interrupt, msp430_interrupt, riscv_interrupt, x86_interrupt] = bool_abis;
307
- Ok ( AbiMap {
321
+ // oh? success? merry giftmas! time to unwrap your presents
322
+ // start with the architectural defaults
323
+ let arch_map = AbiMap :: base_for_arch ( arch) ;
324
+ // these have default ABIs to select
325
+ let [ c_proper, system, system_varargs] =
326
+ required_c_abis. map ( |result| result. unwrap ( ) . unwrap_or ( CanonAbi :: C ) ) ;
327
+ let rust_cold = rust_cold. unwrap ( ) . unwrap_or ( CanonAbi :: RustCold ) ;
328
+
329
+ // these stay options, but shell the Result
330
+ let [ stdcall, fastcall, thiscall, vectorcall] = optional_abis. map ( |result| result. unwrap ( ) ) ;
331
+
332
+ // these simplify to booleans
333
+ let bool_abis = bool_abis. map ( |result| result. unwrap ( ) . unwrap_or ( false ) ) ;
334
+ let [ aapcs, cmse_nonsecure_entry] = bool_abis;
335
+ (
336
+ AbiMap {
308
337
c_proper,
309
338
system,
310
339
system_varargs,
@@ -314,26 +343,16 @@ impl AbiMap {
314
343
aapcs,
315
344
cmse_nonsecure_entry,
316
345
317
- // ...gpu...
318
- gpu_kernel,
319
- ptx_kernel,
320
-
321
- // ...interrupt
322
- avr_interrupt,
323
- msp430_interrupt,
324
- riscv_interrupt,
325
- x86_interrupt,
326
-
327
346
// x86-ish
328
- efiapi,
329
347
stdcall,
330
348
fastcall,
331
349
thiscall,
332
350
vectorcall,
333
- win64,
334
- sysv64,
335
- } )
336
- }
351
+
352
+ ..arch_map
353
+ } ,
354
+ error_map,
355
+ )
337
356
}
338
357
339
358
// serialization
0 commit comments