diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index 14af20f0cb9..160bc511168 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -33,6 +33,7 @@ pub enum CallConv { ColdCallConv = 9, X86StdcallCallConv = 64, X86FastcallCallConv = 65, + X86_64_Win64 = 79, } pub enum Visibility { diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 7da80507df0..161c4ee0d14 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -33,7 +33,7 @@ use syntax::{ast}; use syntax::{attr, ast_map}; use syntax::parse::token::special_idents; use syntax::abi::{RustIntrinsic, Rust, Stdcall, Fastcall, System, - Cdecl, Aapcs, C, AbiSet}; + Cdecl, Aapcs, C, AbiSet, Win64}; use util::ppaux::{Repr, UserString}; use middle::trans::type_::Type; @@ -96,6 +96,7 @@ pub fn llvm_calling_convention(ccx: &mut CrateContext, Stdcall => lib::llvm::X86StdcallCallConv, Fastcall => lib::llvm::X86FastcallCallConv, C => lib::llvm::CCallConv, + Win64 => lib::llvm::X86_64_Win64, // NOTE These API constants ought to be more specific Cdecl => lib::llvm::CCallConv, diff --git a/src/libsyntax/abi.rs b/src/libsyntax/abi.rs index 972d2f43e73..4e9ba5532f3 100644 --- a/src/libsyntax/abi.rs +++ b/src/libsyntax/abi.rs @@ -23,6 +23,7 @@ pub enum Abi { Stdcall, Fastcall, Aapcs, + Win64, // Multiplatform ABIs second Rust, @@ -73,6 +74,8 @@ static AbiDatas: &'static [AbiData] = &[ AbiData {abi: Stdcall, name: "stdcall", abi_arch: Archs(IntelBits)}, AbiData {abi: Fastcall, name:"fastcall", abi_arch: Archs(IntelBits)}, AbiData {abi: Aapcs, name: "aapcs", abi_arch: Archs(ArmBits)}, + AbiData {abi: Win64, name: "win64", + abi_arch: Archs(1 << (X86_64 as uint))}, // Cross-platform ABIs // diff --git a/src/test/auxiliary/extern_calling_convention.rs b/src/test/auxiliary/extern_calling_convention.rs new file mode 100644 index 00000000000..30579f0fc77 --- /dev/null +++ b/src/test/auxiliary/extern_calling_convention.rs @@ -0,0 +1,27 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Make sure Rust generates the correct calling convention for extern +// functions. + +#[inline(never)] +pub extern "win64" fn foo(a: int, b: int, c: int, d: int) { + assert!(a == 1); + assert!(b == 2); + assert!(c == 3); + assert!(d == 4); + + println!("a: {:?}, b: {:?}, c: {:?}, d: {:?}", + a, b, c, d) +} + +fn main() { + foo(1, 2, 3, 4) +} diff --git a/src/test/run-pass/extern-calling-convention-test.rs b/src/test/run-pass/extern-calling-convention-test.rs new file mode 100644 index 00000000000..e8609a8b60b --- /dev/null +++ b/src/test/run-pass/extern-calling-convention-test.rs @@ -0,0 +1,20 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// xfail-fast: aux-build not compatible with fast +// aux-build:extern_calling_convention.rs + +extern mod extern_calling_convention; + +use extern_calling_convention::foo; + +fn main() { + foo(1, 2, 3, 4); +}