@@ -2,7 +2,7 @@ use std::collections::{BTreeMap, BTreeSet};
22
33use serde_json:: Value as JsonValue ;
44
5- use crate :: { AbiFromJsonErr , ArmCall , CanonAbi , ExternAbi , InterruptKind } ;
5+ use crate :: { AbiFromJsonErr , ArmCall , CanonAbi , ExternAbi , InterruptKind , X86Call } ;
66
77#[ derive( Clone , Debug , PartialEq , Eq , Hash ) ]
88pub struct AbiMap {
@@ -15,14 +15,16 @@ pub struct AbiMap {
1515 /// ABI used for `extern "rust-cold"`
1616 pub rust_cold : CanonAbi ,
1717
18- // optional abstract ABIs
19- pub efiapi : Option < CanonAbi > ,
18+ // optional architecture-specific ABIs, should always answer a certain way per-arch
19+ efiapi : Option < CanonAbi > ,
20+ win64 : Option < CanonAbi > ,
21+ sysv64 : Option < CanonAbi > ,
22+
23+ // optional abstract ABIs, these can be very weird
2024 pub stdcall : Option < CanonAbi > ,
2125 pub fastcall : Option < CanonAbi > ,
2226 pub thiscall : Option < CanonAbi > ,
2327 pub vectorcall : Option < CanonAbi > ,
24- pub win64 : Option < CanonAbi > ,
25- pub sysv64 : Option < CanonAbi > ,
2628
2729 // optional concrete ABIs
2830 // arm
@@ -206,6 +208,39 @@ impl AbiMap {
206208 }
207209}
208210
211+ // construction
212+
213+ impl AbiMap {
214+ pub fn base_for_arch ( arch : & str ) -> AbiMap {
215+ match arch {
216+ "aarch64" => AbiMap { efiapi : Some ( CanonAbi :: C ) , ..Default :: default ( ) } ,
217+ "amdgpu" => AbiMap { gpu_kernel : true , ..Default :: default ( ) } ,
218+ "arm" => AbiMap {
219+ aapcs : true ,
220+ efiapi : Some ( CanonAbi :: Arm ( ArmCall :: Aapcs ) ) ,
221+ ..Default :: default ( )
222+ } ,
223+ "avr" => AbiMap { avr_interrupt : true , ..Default :: default ( ) } ,
224+ "msp430" => AbiMap { msp430_interrupt : true , ..Default :: default ( ) } ,
225+ "nvptx64" => AbiMap { ptx_kernel : true , gpu_kernel : true , ..Default :: default ( ) } ,
226+ "riscv32" | "riscv64" => {
227+ AbiMap { efiapi : Some ( CanonAbi :: C ) , riscv_interrupt : true , ..Default :: default ( ) }
228+ }
229+ "x86" => {
230+ AbiMap { efiapi : Some ( CanonAbi :: C ) , x86_interrupt : true , ..Default :: default ( ) }
231+ }
232+ "x86_64" => AbiMap {
233+ efiapi : Some ( CanonAbi :: X86 ( X86Call :: Win64 ) ) ,
234+ sysv64 : Some ( CanonAbi :: X86 ( X86Call :: SysV64 ) ) ,
235+ win64 : Some ( CanonAbi :: X86 ( X86Call :: Win64 ) ) ,
236+ x86_interrupt : true ,
237+ ..Default :: default ( )
238+ } ,
239+ _ => Default :: default ( ) ,
240+ }
241+ }
242+ }
243+
209244// deserialization
210245
211246type JsonObject = serde_json:: Map < String , JsonValue > ;
@@ -243,31 +278,19 @@ fn extract_bool_abi(
243278}
244279
245280impl AbiMap {
246- pub fn from_json_object (
281+ pub fn from_arch_and_json (
282+ arch : & str ,
247283 mut json : JsonObject ,
248- ) -> Result < Self , BTreeMap < String , AbiFromJsonErr > > {
284+ ) -> ( Self , BTreeMap < String , AbiFromJsonErr > ) {
249285 // extract all keys we are interested in
250286 let required_c_abis =
251287 [ "C" , "system" , "system-varargs" ] . map ( |abi_str| extract_abi_str ( & mut json, abi_str) ) ;
252288 let rust_cold = extract_abi_str ( & mut json, "rust-cold" ) ;
253- let bool_abis = [
254- // arm...
255- "aapcs" ,
256- "cmse-nonsecure-entry" ,
257- // ...gpu...
258- "gpu-kernel" ,
259- "ptx-kernel" ,
260- // ...interrupt
261- "avr-interrupt" ,
262- "msp430-interrupt" ,
263- "riscv-interrupt" ,
264- "x86-interrupt" ,
265- ]
266- . map ( |abi_str| extract_bool_abi ( & mut json, abi_str) ) ;
267- // x86ish
268- let optional_abis =
269- [ "efiapi" , "stdcall" , "fastcall" , "thiscall" , "vectorcall" , "win64" , "sysv64" ]
270- . map ( |abi_str| extract_abi_str ( & mut json, abi_str) ) ;
289+ let bool_abis =
290+ [ "aapcs" , "cmse-nonsecure-entry" ] . map ( |abi_str| extract_bool_abi ( & mut json, abi_str) ) ;
291+ // x86ish optional ABIs
292+ let optional_abis = [ "stdcall" , "fastcall" , "thiscall" , "vectorcall" ]
293+ . map ( |abi_str| extract_abi_str ( & mut json, abi_str) ) ;
271294
272295 // accumulate errors
273296 // create an iterator of invalid types and bad parses
@@ -285,28 +308,22 @@ impl AbiMap {
285308 . chain ( errs. cloned ( ) )
286309 . collect :: < BTreeMap < _ , _ > > ( ) ;
287310
288- if error_map. len ( ) > 0 {
289- Err ( error_map)
290- } else {
291- // oh? success? merry giftmas! time to unwrap your presents
292- // these have default ABIs to select
293- let [ c_proper, system, system_varargs] =
294- required_c_abis. map ( |result| result. unwrap ( ) . unwrap_or ( CanonAbi :: C ) ) ;
295- let rust_cold = rust_cold. unwrap ( ) . unwrap_or ( CanonAbi :: RustCold ) ;
296-
297- // these stay options, but shell the Result
298- let [ efiapi, stdcall, fastcall, thiscall, vectorcall, win64, sysv64] =
299- optional_abis. map ( |result| result. unwrap ( ) ) ;
300-
301- // these simplify to booleans
302- let bool_abis = bool_abis. map ( |result| result. unwrap ( ) . unwrap_or ( false ) ) ;
303- // repeat the mantra: arm...
304- let [ aapcs, cmse_nonsecure_entry, bool_abis @ ..] = bool_abis;
305- // ...gpu...
306- let [ gpu_kernel, ptx_kernel, bool_abis @ ..] = bool_abis;
307- // ...interrupt
308- let [ avr_interrupt, msp430_interrupt, riscv_interrupt, x86_interrupt] = bool_abis;
309- Ok ( AbiMap {
311+ // oh? success? merry giftmas! time to unwrap your presents
312+ // start with the architectural defaults
313+ let arch_map = AbiMap :: base_for_arch ( arch) ;
314+ // these have default ABIs to select
315+ let [ c_proper, system, system_varargs] =
316+ required_c_abis. map ( |result| result. unwrap ( ) . unwrap_or ( CanonAbi :: C ) ) ;
317+ let rust_cold = rust_cold. unwrap ( ) . unwrap_or ( CanonAbi :: RustCold ) ;
318+
319+ // these stay options, but shell the Result
320+ let [ stdcall, fastcall, thiscall, vectorcall] = optional_abis. map ( |result| result. unwrap ( ) ) ;
321+
322+ // these simplify to booleans
323+ let bool_abis = bool_abis. map ( |result| result. unwrap ( ) . unwrap_or ( false ) ) ;
324+ let [ aapcs, cmse_nonsecure_entry] = bool_abis;
325+ (
326+ AbiMap {
310327 c_proper,
311328 system,
312329 system_varargs,
@@ -316,26 +333,16 @@ impl AbiMap {
316333 aapcs,
317334 cmse_nonsecure_entry,
318335
319- // ...gpu...
320- gpu_kernel,
321- ptx_kernel,
322-
323- // ...interrupt
324- avr_interrupt,
325- msp430_interrupt,
326- riscv_interrupt,
327- x86_interrupt,
328-
329336 // x86-ish
330- efiapi,
331337 stdcall,
332338 fastcall,
333339 thiscall,
334340 vectorcall,
335- win64,
336- sysv64,
337- } )
338- }
341+
342+ ..arch_map
343+ } ,
344+ error_map,
345+ )
339346 }
340347
341348 // serialization
0 commit comments