diff --git a/lccc/src/targets.rs b/lccc/src/targets.rs index c475a13b..f60afe56 100644 --- a/lccc/src/targets.rs +++ b/lccc/src/targets.rs @@ -5,6 +5,7 @@ mod builtin { pub mod clever; pub mod elf; pub mod holeybytes; + pub mod lilium; pub mod linux; pub mod w65; pub mod x86; @@ -34,6 +35,8 @@ pub fn get_properties(targ: StringView) -> Option<&'static TargetProperties<'sta w65-*-snes-elf => Some(&builtin::elf::W65_ELF), i86-*-near => Some(&builtin::elf::I86_NEAR_ELF), holeybytes-*-elf => Some(&builtin::elf::HOLEYBYTES_ELF), + x86_64-*-lilium-std => Some(&builtin::lilium::X86_64_LILIUM), + clever-*-lilium-std => Some(&builtin::lilium::CLEVER_LILIUM), * => None } } diff --git a/lccc/src/targets/builtin/elf.rs b/lccc/src/targets/builtin/elf.rs index 66665258..ab90a6c9 100644 --- a/lccc/src/targets/builtin/elf.rs +++ b/lccc/src/targets/builtin/elf.rs @@ -196,6 +196,7 @@ pub static X86_64_ELF: TargetProperties = TargetProperties { enabled_features: span![], system_tag_name: const_sv!("SysV64"), default_tag_name: const_sv!("SysV64"), + custom_properties: span![], }; pub static X32_ELF: TargetProperties = TargetProperties { @@ -207,6 +208,7 @@ pub static X32_ELF: TargetProperties = TargetProperties { enabled_features: span![], system_tag_name: const_sv!("SysV64"), default_tag_name: const_sv!("SysV64"), + custom_properties: span![], }; pub static I386_ELF: TargetProperties = TargetProperties { @@ -218,6 +220,7 @@ pub static I386_ELF: TargetProperties = TargetProperties { enabled_features: span![], system_tag_name: const_sv!("cdecl"), default_tag_name: const_sv!("cdecl"), + custom_properties: span![], }; pub static I486_ELF: TargetProperties = TargetProperties { @@ -229,6 +232,7 @@ pub static I486_ELF: TargetProperties = TargetProperties { enabled_features: span![], system_tag_name: const_sv!("cdecl"), default_tag_name: const_sv!("cdecl"), + custom_properties: span![], }; pub static I586_ELF: TargetProperties = TargetProperties { primitives: &X86_32_PRIMITIVES, @@ -239,6 +243,7 @@ pub static I586_ELF: TargetProperties = TargetProperties { enabled_features: span![], system_tag_name: const_sv!("cdecl"), default_tag_name: const_sv!("cdecl"), + custom_properties: span![], }; pub static I686_ELF: TargetProperties = TargetProperties { primitives: &X86_32_PRIMITIVES, @@ -249,6 +254,7 @@ pub static I686_ELF: TargetProperties = TargetProperties { enabled_features: span![], system_tag_name: const_sv!("cdecl"), default_tag_name: const_sv!("cdecl"), + custom_properties: span![], }; pub static I86_NEAR_ELF: TargetProperties = TargetProperties { @@ -260,6 +266,7 @@ pub static I86_NEAR_ELF: TargetProperties = TargetProperties { enabled_features: span![], system_tag_name: const_sv!("cdecl"), default_tag_name: const_sv!("cdecl"), + custom_properties: span![], }; pub static I86_FAR_ELF: TargetProperties = TargetProperties { @@ -271,6 +278,7 @@ pub static I86_FAR_ELF: TargetProperties = TargetProperties { enabled_features: span![], system_tag_name: const_sv!("cdecl"), default_tag_name: const_sv!("cdecl"), + custom_properties: span![], }; pub static I86_NEAR_DATA_FAR_FN_ELF: TargetProperties = TargetProperties { @@ -282,6 +290,7 @@ pub static I86_NEAR_DATA_FAR_FN_ELF: TargetProperties = TargetProperties { enabled_features: span![], system_tag_name: const_sv!("cdecl"), default_tag_name: const_sv!("cdecl"), + custom_properties: span![], }; pub static I86_FAR_DATA_NEAR_FN_ELF: TargetProperties = TargetProperties { @@ -293,6 +302,7 @@ pub static I86_FAR_DATA_NEAR_FN_ELF: TargetProperties = TargetProperties { enabled_features: span![], system_tag_name: const_sv!("cdecl"), default_tag_name: const_sv!("cdecl"), + custom_properties: span![], }; pub static CLEVER_ELF_LINK: LinkProperties = LinkProperties { @@ -337,6 +347,10 @@ pub static CLEVER_ELF: TargetProperties = TargetProperties { enabled_features: span![], default_tag_name: const_sv!("C"), system_tag_name: const_sv!("C"), + custom_properties: span![Pair( + const_sv!("lcrust:abi-v0/simd-adjustment-required"), + const_sv!("false") + )], }; pub static CLEVERILP32_ELF: TargetProperties = TargetProperties { @@ -348,6 +362,10 @@ pub static CLEVERILP32_ELF: TargetProperties = TargetProperties { enabled_features: span![], default_tag_name: const_sv!("C"), system_tag_name: const_sv!("C"), + custom_properties: span![Pair( + const_sv!("lcrust:abi-v0/simd-adjustment-required"), + const_sv!("false") + )], }; pub static W65_ELF_LINK: LinkProperties = LinkProperties { @@ -373,6 +391,10 @@ pub static W65_ELF: TargetProperties = TargetProperties { enabled_features: span![], default_tag_name: const_sv!("C"), system_tag_name: const_sv!("C"), + custom_properties: span![Pair( + const_sv!("lcrust:abi-v0/simd-adjustment-required"), + const_sv!("false") + )], }; pub static HOLEYBYTES_ELF_LINK: LinkProperties = LinkProperties { @@ -398,4 +420,5 @@ pub static HOLEYBYTES_ELF: TargetProperties = TargetProperties { abis: span![], default_tag_name: const_sv!("C"), system_tag_name: const_sv!("C"), + custom_properties: span![], }; diff --git a/lccc/src/targets/builtin/lilium.rs b/lccc/src/targets/builtin/lilium.rs new file mode 100644 index 00000000..7a296a99 --- /dev/null +++ b/lccc/src/targets/builtin/lilium.rs @@ -0,0 +1,73 @@ +use xlang::prelude::v1::*; +use xlang::targets::properties::*; + +use super::clever::*; +use super::x86::*; + +pub static CLEVER_LILIUM_LINK: LinkProperties = LinkProperties { + libdirs: span![const_sv!("lib")], + default_libs: span![const_sv!("usi")], + startfiles: span![const_sv!("libusi-init.a")], + endfiles: span![], + available_formats: span![], + interp: const_sv!("ld-lilium-clever.so"), + obj_binfmt: const_sv!("elf64-clever"), + lib_binfmt: const_sv!("elf64-clever"), + exec_binfmt: const_sv!("elf64-clever"), + stack_attribute_control: StackAttributeControlStyle::NoExec, + uwtable_method: UnwindStyle::Itanium, +}; + +pub static X86_64_LILIUM_LINK: LinkProperties = LinkProperties { + libdirs: span![const_sv!("lib")], + default_libs: span![const_sv!("usi")], + startfiles: span![const_sv!("libusi-init.a")], + endfiles: span![], + available_formats: span![], + interp: const_sv!("ld-lilium-x86-64.so"), + obj_binfmt: const_sv!("elf64-x86_64"), + lib_binfmt: const_sv!("elf64-x86_64"), + exec_binfmt: const_sv!("elf64-x86_64"), + stack_attribute_control: StackAttributeControlStyle::NoExec, + uwtable_method: UnwindStyle::Itanium, +}; + +pub static LILIUM: OperatingSystemProperties = OperatingSystemProperties { + is_unix_like: false, + is_windows_like: false, + os_family: span![const_sv!("lilium")], + static_prefix: const_sv!("lib"), + static_suffix: const_sv!(".a"), + shared_prefix: const_sv!("lib"), + shared_suffix: const_sv!(".so"), + exec_suffix: const_sv!(""), + obj_suffix: const_sv!(".o"), + ld_flavour: LinkerFlavor::Ld, + ar_flavour: ArchiverFlavor::Ar, + base_dirs: span![const_sv!("/"), const_sv!("/usr"), const_sv!("/usr/local")], + so_kind: SharedLibraryStyle::Linkable, +}; + +pub static X86_64_LILIUM: TargetProperties = TargetProperties { + primitives: &X86_64_PRIMITIVES, + os: &LILIUM, + arch: &X86_64, + link: &X86_64_LILIUM_LINK, + abis: span![], + enabled_features: span![], + default_tag_name: const_sv!("SysV64"), + system_tag_name: const_sv!("SysV64"), + custom_properties: span![], +}; + +pub static CLEVER_LILIUM: TargetProperties = TargetProperties { + primitives: &CLEVER_PRIMITIVES, + os: &LILIUM, + arch: &CLEVER, + link: &CLEVER_LILIUM_LINK, + abis: span![], + enabled_features: span![], + default_tag_name: const_sv!("C"), + system_tag_name: const_sv!("C"), + custom_properties: span![], +}; diff --git a/lccc/src/targets/builtin/linux.rs b/lccc/src/targets/builtin/linux.rs index 5f1d22de..4e32188e 100644 --- a/lccc/src/targets/builtin/linux.rs +++ b/lccc/src/targets/builtin/linux.rs @@ -129,6 +129,7 @@ pub static X86_64_LINUX_GNU: TargetProperties = TargetProperties { enabled_features: span![], default_tag_name: const_sv!("SysV64"), system_tag_name: const_sv!("SysV64"), + custom_properties: span![], }; pub static X86_64_V2_LINUX_GNU: TargetProperties = TargetProperties { @@ -140,6 +141,7 @@ pub static X86_64_V2_LINUX_GNU: TargetProperties = TargetProperties { enabled_features: span![], default_tag_name: const_sv!("SysV64"), system_tag_name: const_sv!("SysV64"), + custom_properties: span![], }; pub static X86_64_V3_LINUX_GNU: TargetProperties = TargetProperties { @@ -151,6 +153,7 @@ pub static X86_64_V3_LINUX_GNU: TargetProperties = TargetProperties { enabled_features: span![], default_tag_name: const_sv!("SysV64"), system_tag_name: const_sv!("SysV64"), + custom_properties: span![], }; pub static X86_64_V4_LINUX_GNU: TargetProperties = TargetProperties { @@ -162,6 +165,7 @@ pub static X86_64_V4_LINUX_GNU: TargetProperties = TargetProperties { enabled_features: span![], default_tag_name: const_sv!("SysV64"), system_tag_name: const_sv!("SysV64"), + custom_properties: span![], }; pub static X32_LINUX_GNU: TargetProperties = TargetProperties { @@ -173,6 +177,7 @@ pub static X32_LINUX_GNU: TargetProperties = TargetProperties { enabled_features: span![], default_tag_name: const_sv!("SysV64"), system_tag_name: const_sv!("SysV64"), + custom_properties: span![], }; pub static I686_LINUX_GNU: TargetProperties = TargetProperties { @@ -184,6 +189,7 @@ pub static I686_LINUX_GNU: TargetProperties = TargetProperties { enabled_features: span![], default_tag_name: const_sv!("cdecl"), system_tag_name: const_sv!("cdecl"), + custom_properties: span![], }; pub static I586_LINUX_GNU: TargetProperties = TargetProperties { @@ -195,6 +201,7 @@ pub static I586_LINUX_GNU: TargetProperties = TargetProperties { enabled_features: span![], default_tag_name: const_sv!("cdecl"), system_tag_name: const_sv!("cdecl"), + custom_properties: span![], }; pub static I486_LINUX_GNU: TargetProperties = TargetProperties { primitives: &X86_32_PRIMITIVES, @@ -205,6 +212,7 @@ pub static I486_LINUX_GNU: TargetProperties = TargetProperties { enabled_features: span![], default_tag_name: const_sv!("cdecl"), system_tag_name: const_sv!("cdecl"), + custom_properties: span![], }; pub static I386_LINUX_GNU: TargetProperties = TargetProperties { primitives: &X86_32_PRIMITIVES, @@ -215,6 +223,7 @@ pub static I386_LINUX_GNU: TargetProperties = TargetProperties { enabled_features: span![], default_tag_name: const_sv!("cdecl"), system_tag_name: const_sv!("cdecl"), + custom_properties: span![], }; pub static X86_64_LINUX_MUSL: TargetProperties = TargetProperties { @@ -226,4 +235,5 @@ pub static X86_64_LINUX_MUSL: TargetProperties = TargetProperties { enabled_features: span![], default_tag_name: const_sv!("SysV64"), system_tag_name: const_sv!("SysV64"), + custom_properties: span![], }; diff --git a/rust/src/irgen/xir_visitor.rs b/rust/src/irgen/xir_visitor.rs index f7efe509..9eecd0b9 100644 --- a/rust/src/irgen/xir_visitor.rs +++ b/rust/src/irgen/xir_visitor.rs @@ -570,11 +570,18 @@ impl<'a> FunctionDefVisitor for XirFunctionDefVisitor<'a> { } } +pub enum XirParamAdjustment { + Normal, + RustSimd, + RustCallDetuple { requires_simd_adjustment: bool }, +} + pub struct XirFunctionTyVisitor<'a> { defs: &'a Definitions, names: &'a NameMap, fnty: &'a mut ir::FnType, properties: &'a TargetProperties<'a>, + param_adjustment: XirParamAdjustment, } impl<'a> XirFunctionTyVisitor<'a> { @@ -589,13 +596,103 @@ impl<'a> XirFunctionTyVisitor<'a> { names, fnty, properties, + param_adjustment: XirParamAdjustment::Normal, } } } impl<'a> FunctionTyVisitor for XirFunctionTyVisitor<'a> { - fn visit_tag(&mut self, _: AbiTag) { - self.fnty.tag = self.properties.default_tag_name.into(); // TODO: fastcall + fn visit_tag(&mut self, tag: AbiTag) { + match tag { + AbiTag::Rust | AbiTag::RustIntrinsic | AbiTag::LCRust(_) => { + if self + .properties + .custom_properties + .iter() + .map(|&Pair(a, b)| (a, b)) + .find_map(|(key, value)| { + if key == "lcrust:abi-v0/simd-adjustment-required" { + value.parse::<bool>().ok() + } else { + None + } + }) + .unwrap_or(true) + { + self.param_adjustment = XirParamAdjustment::RustSimd + }; + if let Some(tag) = self + .properties + .custom_properties + .iter() + .map(|&Pair(a, b)| (a, b)) + .find_map(|(key, value)| { + if key == "lcrust:abi-v0/rustcall-tag" { + return Some(value); + } else { + None + } + }) + { + self.fnty.tag = tag.into(); + } else { + self.fnty.tag = self.properties.default_tag_name.into(); + } + } + AbiTag::RustCall => { + self.param_adjustment = XirParamAdjustment::RustCallDetuple { + requires_simd_adjustment: self + .properties + .custom_properties + .iter() + .map(|&Pair(a, b)| (a, b)) + .find_map(|(key, value)| { + if key == "lcrust:abi-v0/simd-adjustment-required" { + value.parse::<bool>().ok() + } else { + None + } + }) + .unwrap_or(true), + }; + + if let Some(tag) = self + .properties + .custom_properties + .iter() + .map(|&Pair(a, b)| (a, b)) + .find_map(|(key, value)| { + if key == "lcrust:abi-v0/rustcall-tag" { + return Some(value); + } else { + None + } + }) + { + self.fnty.tag = tag.into(); + } else { + self.fnty.tag = self.properties.default_tag_name.into(); + } + } + + AbiTag::C { .. } => { + self.fnty.tag = self.properties.default_tag_name.into(); + } + AbiTag::System { .. } => { + self.fnty.tag = self.properties.system_tag_name.into(); + } + AbiTag::Cdecl { .. } => self.fnty.tag = "cdecl".into(), + AbiTag::Stdcall { .. } => self.fnty.tag = "stdcall".into(), + AbiTag::Fastcall { .. } => self.fnty.tag = "fastcall".into(), + AbiTag::Thiscall { .. } => self.fnty.tag = "thiscall".into(), + AbiTag::Vectorcall { .. } => self.fnty.tag = "vectorcall".into(), + AbiTag::Win64 { .. } => self.fnty.tag = "Win64".into(), + AbiTag::SysV64 { .. } => self.fnty.tag = "SysV64".into(), + AbiTag::Aapcs { .. } => self.fnty.tag = "aapcs".into(), + AbiTag::Efiabi { .. } => self.fnty.tag = "efiabi".into(), + AbiTag::X86Interrupt => self.fnty.tag = "x86-interrupt".into(), + AbiTag::W65Interrupt => self.fnty.tag = "w65-interrupt".into(), + } } fn visit_return(&mut self) -> Option<impl TypeVisitor + '_> { @@ -617,7 +714,7 @@ impl<'a> FunctionTyVisitor for XirFunctionTyVisitor<'a> { } fn visit_cvarargs(&mut self) { - todo!() + self.fnty.variadic = true; } } diff --git a/xlang/xlang_abi/src/string.rs b/xlang/xlang_abi/src/string.rs index f4294bf9..5e86d261 100644 --- a/xlang/xlang_abi/src/string.rs +++ b/xlang/xlang_abi/src/string.rs @@ -459,8 +459,8 @@ impl<'a> StringView<'a> { #[must_use] pub const unsafe fn from_raw_parts(begin: *const u8, end: *const u8) -> Self { Self { - begin: NonNull::new_unchecked(begin as *mut u8), - end: NonNull::new_unchecked(end as *mut u8), + begin: unsafe { NonNull::new_unchecked(begin as *mut u8) }, + end: unsafe { NonNull::new_unchecked(end as *mut u8) }, phantom: PhantomData, } } diff --git a/xlang/xlang_targets/src/properties.rs b/xlang/xlang_targets/src/properties.rs index 862c0fcf..e162c5b0 100644 --- a/xlang/xlang_targets/src/properties.rs +++ b/xlang/xlang_targets/src/properties.rs @@ -329,4 +329,10 @@ pub struct TargetProperties<'a> { /// Default call abi for system apis. Usually not different from `default_tag_name` pub system_tag_name: StringView<'a>, + + /// Additional (namespaced) properties about the target. + /// The first string is a key, which shall be a string in the form `<namespace>:<path>` where `<namespace>` and each `/` separated segment of `<path>`, shall match `[-A-Za-z._][-A-Za-z._]*`. + /// The second string is the value, which may be any arbitrary UTF-8 text. + /// Keys may be duplicated - the meaning of duplicate entries is defined by the property + pub custom_properties: Span<'a, Pair<StringView<'a>, StringView<'a>>>, }