Skip to content

Commit

Permalink
calling convention for MSP430 interrupts
Browse files Browse the repository at this point in the history
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
        ...
```
  • Loading branch information
Jorge Aparicio committed Jan 19, 2017
1 parent c8af93f commit 6296d52
Show file tree
Hide file tree
Showing 6 changed files with 19 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/librustc_llvm/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions src/librustc_trans/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 2 additions & 0 deletions src/libsyntax/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ pub enum Abi {
Win64,
SysV64,
PtxKernel,
Msp430Interrupt,

// Multiplatform / generic ABIs
Rust,
Expand Down Expand Up @@ -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 },
Expand Down
7 changes: 7 additions & 0 deletions src/libsyntax/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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! (
Expand Down Expand Up @@ -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 |
Expand Down
7 changes: 7 additions & 0 deletions src/test/compile-fail/feature-gate-abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,21 @@ 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 {
extern "rust-intrinsic" fn m1(); //~ ERROR intrinsics are subject to change
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;
Expand All @@ -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
Expand All @@ -47,18 +51,21 @@ 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
type A1 = extern "rust-intrinsic" fn(); //~ ERROR intrinsics are subject to change
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() {}
2 changes: 1 addition & 1 deletion src/test/ui/codemap_tests/unicode.stderr
Original file line number Diff line number Diff line change
@@ -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() {}
Expand Down

0 comments on commit 6296d52

Please sign in to comment.