From 6296d52ba60771232ab362c116e898aa930679ad Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Sun, 18 Dec 2016 23:45:20 -0500 Subject: [PATCH] calling convention for MSP430 interrupts This calling convention is used to define interrup handlers on MSP430 microcontrollers. Usage looks like this: ``` rust #[no_mangle] #[link_section = "__interrupt_vector_10"] pub static TIM0_VECTOR: unsafe extern "msp430-interrupt" fn() = tim0; unsafe extern "msp430-interrupt" fn tim0() { P1OUT.write(0x00); } ``` which generates the following assembly: ``` asm Disassembly of section __interrupt_vector_10: 0000fff2 : fff2: 10 c0 interrupt service routine at 0xc010 Disassembly of section .text: 0000c010 <_ZN3msp4tim017h3193b957fd6a4fd4E>: c010: c2 43 21 00 mov.b #0, &0x0021 ;r3 As==00 c014: 00 13 reti ... ``` --- src/librustc_llvm/ffi.rs | 1 + src/librustc_trans/abi.rs | 1 + src/libsyntax/abi.rs | 2 ++ src/libsyntax/feature_gate.rs | 7 +++++++ src/test/compile-fail/feature-gate-abi.rs | 7 +++++++ src/test/ui/codemap_tests/unicode.stderr | 2 +- 6 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs index 6815da4cc20fd..caa27404086b9 100644 --- a/src/librustc_llvm/ffi.rs +++ b/src/librustc_llvm/ffi.rs @@ -42,6 +42,7 @@ pub enum CallConv { X86StdcallCallConv = 64, X86FastcallCallConv = 65, ArmAapcsCallConv = 67, + Msp430Intr = 69, PtxKernel = 71, X86_64_SysV = 78, X86_64_Win64 = 79, diff --git a/src/librustc_trans/abi.rs b/src/librustc_trans/abi.rs index ad4bb0fce22ad..577744653f09b 100644 --- a/src/librustc_trans/abi.rs +++ b/src/librustc_trans/abi.rs @@ -356,6 +356,7 @@ impl FnType { SysV64 => llvm::X86_64_SysV, Aapcs => llvm::ArmAapcsCallConv, PtxKernel => llvm::PtxKernel, + Msp430Interrupt => llvm::Msp430Intr, // These API constants ought to be more specific... Cdecl => llvm::CCallConv, diff --git a/src/libsyntax/abi.rs b/src/libsyntax/abi.rs index 75554f20effee..3b0db7b50a63e 100644 --- a/src/libsyntax/abi.rs +++ b/src/libsyntax/abi.rs @@ -42,6 +42,7 @@ pub enum Abi { Win64, SysV64, PtxKernel, + Msp430Interrupt, // Multiplatform / generic ABIs Rust, @@ -85,6 +86,7 @@ const AbiDatas: &'static [AbiData] = &[ AbiData {abi: Abi::Win64, name: "win64", generic: false }, AbiData {abi: Abi::SysV64, name: "sysv64", generic: false }, AbiData {abi: Abi::PtxKernel, name: "ptx-kernel", generic: false }, + AbiData {abi: Abi::Msp430Interrupt, name: "msp430-interrupt", generic: false }, // Cross-platform ABIs AbiData {abi: Abi::Rust, name: "Rust", generic: true }, diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index ba6e752d310e0..db94f4c387992 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -321,6 +321,9 @@ declare_features! ( // Allows attributes on struct literal fields. (active, struct_field_attributes, "1.16.0", Some(38814)), + + // `extern "msp430-interrupt" fn()` + (active, abi_msp430_interrupt, "1.16.0", Some(38487)), ); declare_features! ( @@ -995,6 +998,10 @@ impl<'a> PostExpansionVisitor<'a> { gate_feature_post!(&self, abi_unadjusted, span, "unadjusted ABI is an implementation detail and perma-unstable"); }, + Abi::Msp430Interrupt => { + gate_feature_post!(&self, abi_msp430_interrupt, span, + "msp430-interrupt ABI is experimental and subject to change"); + }, // Stable Abi::Cdecl | Abi::Stdcall | diff --git a/src/test/compile-fail/feature-gate-abi.rs b/src/test/compile-fail/feature-gate-abi.rs index c0fb94e8c42c9..517e37c3fa5a3 100644 --- a/src/test/compile-fail/feature-gate-abi.rs +++ b/src/test/compile-fail/feature-gate-abi.rs @@ -17,6 +17,7 @@ extern "rust-intrinsic" fn f1() {} //~ ERROR intrinsics are subject to change extern "platform-intrinsic" fn f2() {} //~ ERROR platform intrinsics are experimental extern "vectorcall" fn f3() {} //~ ERROR vectorcall is experimental and subject to change extern "rust-call" fn f4() {} //~ ERROR rust-call ABI is subject to change +extern "msp430-interrupt" fn f5() {} //~ ERROR msp430-interrupt ABI is experimental // Methods in trait definition trait Tr { @@ -24,11 +25,13 @@ trait Tr { extern "platform-intrinsic" fn m2(); //~ ERROR platform intrinsics are experimental extern "vectorcall" fn m3(); //~ ERROR vectorcall is experimental and subject to change extern "rust-call" fn m4(); //~ ERROR rust-call ABI is subject to change + extern "msp430-interrupt" fn m5(); //~ ERROR msp430-interrupt ABI is experimental extern "rust-intrinsic" fn dm1() {} //~ ERROR intrinsics are subject to change extern "platform-intrinsic" fn dm2() {} //~ ERROR platform intrinsics are experimental extern "vectorcall" fn dm3() {} //~ ERROR vectorcall is experimental and subject to change extern "rust-call" fn dm4() {} //~ ERROR rust-call ABI is subject to change + extern "msp430-interrupt" fn dm5() {} //~ ERROR msp430-interrupt ABI is experimental } struct S; @@ -39,6 +42,7 @@ impl Tr for S { extern "platform-intrinsic" fn m2() {} //~ ERROR platform intrinsics are experimental extern "vectorcall" fn m3() {} //~ ERROR vectorcall is experimental and subject to change extern "rust-call" fn m4() {} //~ ERROR rust-call ABI is subject to change + extern "msp430-interrupt" fn m5() {} //~ ERROR msp430-interrupt ABI is experimental } // Methods in inherent impl @@ -47,6 +51,7 @@ impl S { extern "platform-intrinsic" fn im2() {} //~ ERROR platform intrinsics are experimental extern "vectorcall" fn im3() {} //~ ERROR vectorcall is experimental and subject to change extern "rust-call" fn im4() {} //~ ERROR rust-call ABI is subject to change + extern "msp430-interrupt" fn im5() {} //~ ERROR msp430-interrupt ABI is experimental } // Function pointer types @@ -54,11 +59,13 @@ type A1 = extern "rust-intrinsic" fn(); //~ ERROR intrinsics are subject to chan type A2 = extern "platform-intrinsic" fn(); //~ ERROR platform intrinsics are experimental type A3 = extern "vectorcall" fn(); //~ ERROR vectorcall is experimental and subject to change type A4 = extern "rust-call" fn(); //~ ERROR rust-call ABI is subject to change +type A5 = extern "msp430-interrupt" fn(); //~ ERROR msp430-interrupt ABI is experimental // Foreign modules extern "rust-intrinsic" {} //~ ERROR intrinsics are subject to change extern "platform-intrinsic" {} //~ ERROR platform intrinsics are experimental extern "vectorcall" {} //~ ERROR vectorcall is experimental and subject to change extern "rust-call" {} //~ ERROR rust-call ABI is subject to change +extern "msp430-interrupt" {} //~ ERROR msp430-interrupt ABI is experimental fn main() {} diff --git a/src/test/ui/codemap_tests/unicode.stderr b/src/test/ui/codemap_tests/unicode.stderr index f71ef126b64d9..423cc9230e893 100644 --- a/src/test/ui/codemap_tests/unicode.stderr +++ b/src/test/ui/codemap_tests/unicode.stderr @@ -1,4 +1,4 @@ -error: invalid ABI: expected one of [cdecl, stdcall, fastcall, vectorcall, aapcs, win64, sysv64, ptx-kernel, Rust, C, system, rust-intrinsic, rust-call, platform-intrinsic, unadjusted], found `路濫狼á́́` +error: invalid ABI: expected one of [cdecl, stdcall, fastcall, vectorcall, aapcs, win64, sysv64, ptx-kernel, msp430-interrupt, Rust, C, system, rust-intrinsic, rust-call, platform-intrinsic, unadjusted], found `路濫狼á́́` --> $DIR/unicode.rs:11:8 | 11 | extern "路濫狼á́́" fn foo() {}