1
Fork 0

Support sysv64 and ms ABIs

This commit is contained in:
Antoni Boucher 2025-02-12 19:54:51 -05:00
parent 438056890d
commit 4f59a687f1
6 changed files with 74 additions and 19 deletions

8
Cargo.lock generated
View file

@ -56,18 +56,18 @@ dependencies = [
[[package]] [[package]]
name = "gccjit" name = "gccjit"
version = "2.4.0" version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72fd91f4adbf02b53cfc73c97bc33c5f253009043f30c56a5ec08dd5c8094dc8" checksum = "2895ddec764de7ac76fe6c056050c4801a80109c066f177a00a9cc8dee02b29b"
dependencies = [ dependencies = [
"gccjit_sys", "gccjit_sys",
] ]
[[package]] [[package]]
name = "gccjit_sys" name = "gccjit_sys"
version = "0.5.0" version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fb7b8f48a75e2cfe78c3d9a980b32771c34ffd12d196021ab3f98c49fbd2f0d" checksum = "ac133db68db8a6a8b2c51ef4b18d8ea16682d5814c4641272fe37bbbc223d5f3"
dependencies = [ dependencies = [
"libc", "libc",
] ]

View file

@ -22,7 +22,7 @@ master = ["gccjit/master"]
default = ["master"] default = ["master"]
[dependencies] [dependencies]
gccjit = "2.4" gccjit = "2.5"
#gccjit = { git = "https://github.com/rust-lang/gccjit.rs" } #gccjit = { git = "https://github.com/rust-lang/gccjit.rs" }
# Local copy. # Local copy.

View file

@ -9,6 +9,8 @@ use rustc_middle::ty::layout::LayoutOf;
#[cfg(feature = "master")] #[cfg(feature = "master")]
use rustc_session::config; use rustc_session::config;
use rustc_target::abi::call::{ArgAttributes, CastTarget, FnAbi, PassMode, Reg, RegKind}; use rustc_target::abi::call::{ArgAttributes, CastTarget, FnAbi, PassMode, Reg, RegKind};
#[cfg(feature = "master")]
use rustc_target::callconv::Conv;
use crate::builder::Builder; use crate::builder::Builder;
use crate::context::CodegenCx; use crate::context::CodegenCx;
@ -104,6 +106,8 @@ pub trait FnAbiGccExt<'gcc, 'tcx> {
// TODO(antoyo): return a function pointer type instead? // TODO(antoyo): return a function pointer type instead?
fn gcc_type(&self, cx: &CodegenCx<'gcc, 'tcx>) -> FnAbiGcc<'gcc>; fn gcc_type(&self, cx: &CodegenCx<'gcc, 'tcx>) -> FnAbiGcc<'gcc>;
fn ptr_to_gcc_type(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Type<'gcc>; fn ptr_to_gcc_type(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Type<'gcc>;
#[cfg(feature = "master")]
fn gcc_cconv(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Option<FnAttribute<'gcc>>;
} }
impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
@ -226,4 +230,46 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
); );
pointer_type pointer_type
} }
#[cfg(feature = "master")]
fn gcc_cconv(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Option<FnAttribute<'gcc>> {
conv_to_fn_attribute(self.conv, &cx.tcx.sess.target.arch)
}
}
#[cfg(feature = "master")]
pub fn conv_to_fn_attribute<'gcc>(conv: Conv, _arch: &str) -> Option<FnAttribute<'gcc>> {
// TODO: handle the calling conventions returning None.
let attribute = match conv {
Conv::C
| Conv::Rust
| Conv::CCmseNonSecureCall
| Conv::CCmseNonSecureEntry
| Conv::RiscvInterrupt { .. } => return None,
Conv::Cold => return None,
Conv::PreserveMost => return None,
Conv::PreserveAll => return None,
/*Conv::GpuKernel => {
if arch == "amdgpu" {
return None
} else if arch == "nvptx64" {
return None
} else {
panic!("Architecture {arch} does not support GpuKernel calling convention");
}
}*/
Conv::AvrInterrupt => return None,
Conv::AvrNonBlockingInterrupt => return None,
Conv::ArmAapcs => return None,
Conv::Msp430Intr => return None,
Conv::PtxKernel => return None,
Conv::X86Fastcall => return None,
Conv::X86Intr => return None,
Conv::X86Stdcall => return None,
Conv::X86ThisCall => return None,
Conv::X86VectorCall => return None,
Conv::X86_64SysV => FnAttribute::SysvAbi,
Conv::X86_64Win64 => FnAttribute::MsAbi,
};
Some(attribute)
} }

View file

@ -23,6 +23,8 @@ use rustc_target::spec::{
HasTargetSpec, HasWasmCAbiOpt, HasX86AbiOpt, Target, TlsModel, WasmCAbi, X86Abi, HasTargetSpec, HasWasmCAbiOpt, HasX86AbiOpt, Target, TlsModel, WasmCAbi, X86Abi,
}; };
#[cfg(feature = "master")]
use crate::abi::conv_to_fn_attribute;
use crate::callee::get_fn; use crate::callee::get_fn;
use crate::common::SignType; use crate::common::SignType;
@ -509,7 +511,11 @@ impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
fn declare_c_main(&self, fn_type: Self::Type) -> Option<Self::Function> { fn declare_c_main(&self, fn_type: Self::Type) -> Option<Self::Function> {
let entry_name = self.sess().target.entry_name.as_ref(); let entry_name = self.sess().target.entry_name.as_ref();
if !self.functions.borrow().contains_key(entry_name) { if !self.functions.borrow().contains_key(entry_name) {
Some(self.declare_entry_fn(entry_name, fn_type, ())) #[cfg(feature = "master")]
let conv = conv_to_fn_attribute(self.sess().target.entry_abi, &self.sess().target.arch);
#[cfg(not(feature = "master"))]
let conv = None;
Some(self.declare_entry_fn(entry_name, fn_type, conv))
} else { } else {
// If the symbol already exists, it is an error: for example, the user wrote // If the symbol already exists, it is an error: for example, the user wrote
// #[no_mangle] extern "C" fn main(..) {..} // #[no_mangle] extern "C" fn main(..) {..}

View file

@ -58,7 +58,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
variadic: bool, variadic: bool,
) -> Function<'gcc> { ) -> Function<'gcc> {
self.linkage.set(FunctionType::Extern); self.linkage.set(FunctionType::Extern);
declare_raw_fn(self, name, () /*llvm::CCallConv*/, return_type, params, variadic) declare_raw_fn(self, name, None, return_type, params, variadic)
} }
pub fn declare_global( pub fn declare_global(
@ -92,7 +92,8 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
&self, &self,
name: &str, name: &str,
_fn_type: Type<'gcc>, _fn_type: Type<'gcc>,
callconv: (), /*llvm::CCallConv*/ #[cfg(feature = "master")] callconv: Option<FnAttribute<'gcc>>,
#[cfg(not(feature = "master"))] callconv: Option<()>,
) -> RValue<'gcc> { ) -> RValue<'gcc> {
// TODO(antoyo): use the fn_type parameter. // TODO(antoyo): use the fn_type parameter.
let const_string = self.context.new_type::<u8>().make_pointer().make_pointer(); let const_string = self.context.new_type::<u8>().make_pointer().make_pointer();
@ -123,14 +124,11 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
#[cfg(feature = "master")] #[cfg(feature = "master")]
fn_attributes, fn_attributes,
} = fn_abi.gcc_type(self); } = fn_abi.gcc_type(self);
let func = declare_raw_fn( #[cfg(feature = "master")]
self, let conv = fn_abi.gcc_cconv(self);
name, #[cfg(not(feature = "master"))]
(), /*fn_abi.llvm_cconv()*/ let conv = None;
return_type, let func = declare_raw_fn(self, name, conv, return_type, &arguments_type, is_c_variadic);
&arguments_type,
is_c_variadic,
);
self.on_stack_function_params.borrow_mut().insert(func, on_stack_param_indices); self.on_stack_function_params.borrow_mut().insert(func, on_stack_param_indices);
#[cfg(feature = "master")] #[cfg(feature = "master")]
for fn_attr in fn_attributes { for fn_attr in fn_attributes {
@ -162,7 +160,8 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
fn declare_raw_fn<'gcc>( fn declare_raw_fn<'gcc>(
cx: &CodegenCx<'gcc, '_>, cx: &CodegenCx<'gcc, '_>,
name: &str, name: &str,
_callconv: (), /*llvm::CallConv*/ #[cfg(feature = "master")] callconv: Option<FnAttribute<'gcc>>,
#[cfg(not(feature = "master"))] _callconv: Option<()>,
return_type: Type<'gcc>, return_type: Type<'gcc>,
param_types: &[Type<'gcc>], param_types: &[Type<'gcc>],
variadic: bool, variadic: bool,
@ -192,6 +191,10 @@ fn declare_raw_fn<'gcc>(
let name = &mangle_name(name); let name = &mangle_name(name);
let func = let func =
cx.context.new_function(None, cx.linkage.get(), return_type, &params, name, variadic); cx.context.new_function(None, cx.linkage.get(), return_type, &params, name, variadic);
#[cfg(feature = "master")]
if let Some(attribute) = callconv {
func.add_attribute(attribute);
}
cx.functions.borrow_mut().insert(name.to_string(), func); cx.functions.borrow_mut().insert(name.to_string(), func);
#[cfg(feature = "master")] #[cfg(feature = "master")]

View file

@ -187,10 +187,10 @@ impl CodegenBackend for GccCodegenBackend {
crate::DEFAULT_LOCALE_RESOURCE crate::DEFAULT_LOCALE_RESOURCE
} }
fn init(&self, sess: &Session) { fn init(&self, _sess: &Session) {
#[cfg(feature = "master")] #[cfg(feature = "master")]
{ {
let target_cpu = target_cpu(sess); let target_cpu = target_cpu(_sess);
// Get the second TargetInfo with the correct CPU features by setting the arch. // Get the second TargetInfo with the correct CPU features by setting the arch.
let context = Context::default(); let context = Context::default();