about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJorge Aparicio <japaricious@gmail.com>2016-12-18 23:45:20 -0500
committerJorge Aparicio <japaricious@gmail.com>2017-01-18 20:42:54 -0500
commit6296d52ba60771232ab362c116e898aa930679ad (patch)
treebde28fc4dc6e797d393d9830b39efd2c891c1a81
parentc8af93f0901c336e873ce18274026d0fd9bc7c1f (diff)
downloadrust-6296d52ba60771232ab362c116e898aa930679ad.tar.gz
rust-6296d52ba60771232ab362c116e898aa930679ad.zip
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 <TIM0_VECTOR>:
    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
        ...
```
-rw-r--r--src/librustc_llvm/ffi.rs1
-rw-r--r--src/librustc_trans/abi.rs1
-rw-r--r--src/libsyntax/abi.rs2
-rw-r--r--src/libsyntax/feature_gate.rs7
-rw-r--r--src/test/compile-fail/feature-gate-abi.rs7
-rw-r--r--src/test/ui/codemap_tests/unicode.stderr2
6 files changed, 19 insertions, 1 deletions
diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs
index 6815da4cc20..caa27404086 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 ad4bb0fce22..577744653f0 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 75554f20eff..3b0db7b50a6 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 ba6e752d310..db94f4c3879 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 c0fb94e8c42..517e37c3fa5 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 f71ef126b64..423cc9230e8 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() {}