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
        ...
```
This commit is contained in:
Jorge Aparicio 2016-12-18 23:45:20 -05:00
parent c8af93f090
commit 6296d52ba6
6 changed files with 19 additions and 1 deletions

View File

@ -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,

View File

@ -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,

View File

@ -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 },

View File

@ -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 |

View File

@ -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() {}

View File

@ -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() {}