From 225c8e7e2f635841db8435fc7ebb8cf3c4468420 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Fri, 6 Jul 2018 17:12:35 -0500 Subject: [PATCH 1/5] add CMSIS / Cortex-M instrinsics --- coresimd/arm/cmsis.rs | 264 ++++++++++++++++++++++++++++++++++++++++++ coresimd/arm/mod.rs | 5 + 2 files changed, 269 insertions(+) create mode 100644 coresimd/arm/cmsis.rs diff --git a/coresimd/arm/cmsis.rs b/coresimd/arm/cmsis.rs new file mode 100644 index 0000000000..4fc718d9ef --- /dev/null +++ b/coresimd/arm/cmsis.rs @@ -0,0 +1,264 @@ +#![allow(non_snake_case)] + +/// Extracted from [CMSIS 5]'s CMSIS/Core/Include/cmsis_gcc.h +/// +/// [CMSIS 5]: https://github.com/ARM-software/CMSIS_5 + +/* Core function access */ + +/// Enable IRQ Interrupts +/// +/// Enables IRQ interrupts by clearing the I-bit in the CPSR. Can only be +/// executed in Privileged modes. +#[inline(always)] +pub unsafe fn __enable_irq() { + asm!("cpsie i" : : : "memory" : "volatile"); +} + +/// Disable IRQ Interrupts +/// +/// Disables IRQ interrupts by setting the I-bit in the CPSR. Can only be +/// executed in Privileged modes. +#[inline(always)] +pub unsafe fn __disable_irq() { + asm!("cpsid i" : : : "memory" : "volatile"); +} + +/// Get Control Register +/// +/// Returns the content of the Control Register. +#[inline(always)] +pub unsafe fn __get_CONTROL() -> u32 { + let result: u32; + asm!("mrs $0, CONTROL" : "=r"(result) : : : "volatile"); + result +} + +/// Set Control Register +/// +/// Writes the given value to the Control Register. +#[inline(always)] +pub unsafe fn __set_CONTROL(control: u32) { + asm!("msr CONTROL, $0" : : "r"(control) : "memory" : "volatile"); +} + +/// Get IPSR Register +/// +/// Returns the content of the IPSR Register. +#[inline(always)] +pub unsafe fn __get_IPSR() -> u32 { + let result: u32; + asm!("mrs $0, IPSR" : "=r"(result) : : : "volatile"); + result +} + +/// Get APSR Register +/// +/// Returns the content of the APSR Register. +#[inline(always)] +pub unsafe fn __get_APSR() -> u32 { + let result: u32; + asm!("mrs $0, APSR" : "=r"(result) : : : "volatile"); + result +} + +/// Get xPSR Register +/// +/// Returns the content of the xPSR Register. +#[inline(always)] +pub unsafe fn __get_xPSR() -> u32 { + let result: u32; + asm!("mrs $0, XPSR" : "=r"(result) : : : "volatile"); + result +} + +/// Get Process Stack Pointer +/// +/// Returns the current value of the Process Stack Pointer (PSP). +#[inline(always)] +pub unsafe fn __get_PSP() -> u32 { + let result: u32; + asm!("mrs $0, PSP" : "=r"(result) : : : "volatile"); + result +} + +/// Set Process Stack Pointer +/// +/// Assigns the given value to the Process Stack Pointer (PSP). +#[inline(always)] +pub unsafe fn __set_PSP(top_of_proc_stack: u32) { + asm!("msr PSP, $0" : : "r"(top_of_proc_stack) : : "volatile"); +} + +/// Get Main Stack Pointer +/// +/// Returns the current value of the Main Stack Pointer (MSP). +#[inline(always)] +pub unsafe fn __get_MSP() -> u32 { + let result: u32; + asm!("mrs $0, MSP" : "=r"(result) : : : "volatile"); + result +} + +/// Set Main Stack Pointer +/// +/// Assigns the given value to the Main Stack Pointer (MSP). +#[inline(always)] +pub unsafe fn __set_MSP(top_of_main_stack: u32) { + asm!("msr MSP, $0" : : "r"(top_of_main_stack) : : "volatile"); +} + +/// Get Priority Mask +/// +/// Returns the current state of the priority mask bit from the Priority Mask +/// Register. +#[inline(always)] +pub unsafe fn __get_PRIMASK() -> u32 { + let result: u32; + asm!("mrs $0, PRIMASK" : "=r"(result) : : "memory" : "volatile"); + result +} + +/// Set Priority Mask +/// +/// Assigns the given value to the Priority Mask Register. +#[inline(always)] +pub unsafe fn __set_PRIMASK(pri_mask: u32) { + asm!("msr PRIMASK, $0" : : "r"(pri_mask) : : "volatile"); +} + +#[cfg(target_feature = "v7")] +mod v7 { + /// Enable FIQ + /// + /// Enables FIQ interrupts by clearing the F-bit in the CPSR. Can only be + /// executed in Privileged modes. + #[inline(always)] + pub unsafe fn __enable_fault_irq() { + asm!("cpsie f" : : : "memory" : "volatile"); + } + + /// Disable FIQ + /// + /// Disables FIQ interrupts by setting the F-bit in the CPSR. Can only be + /// executed in Privileged modes. + #[inline(always)] + pub unsafe fn __disable_fault_irq() { + asm!("cpsid f" : : : "memory" : "volatile"); + } + + /// Get Base Priority + /// + /// Returns the current value of the Base Priority register. + #[inline(always)] + pub unsafe fn __get_BASEPRI() -> u32 { + let result: u32; + asm!("mrs $0, BASEPRI" : "=r"(result) : : : "volatile"); + result + } + + /// Set Base Priority + /// + /// Assigns the given value to the Base Priority register. + #[inline(always)] + pub unsafe fn __set_BASEPRI(base_pri: u32) { + asm!("msr BASEPRI, $0" : : "r"(base_pri) : "memory" : "volatile"); + } + + /// Set Base Priority with condition + /// + /// Assigns the given value to the Base Priority register only if BASEPRI + /// masking is disabled, or the new value increases the BASEPRI + /// priority level. + #[inline(always)] + pub unsafe fn __set_BASEPRI_MAX(base_pri: u32) { + asm!("msr BASEPRI_MAX, $0" : : "r"(base_pri) : "memory" : "volatile"); + } + + /// Get Fault Mask + /// + /// Returns the current value of the Fault Mask register. + #[inline(always)] + pub unsafe fn __get_FAULTMASK() -> u32 { + let result: u32; + asm!("mrs $0, FAULTMASK" : "=r"(result) : : : "volatile"); + result + } + + /// Set Fault Mask + /// + /// Assigns the given value to the Fault Mask register. + #[inline(always)] + pub unsafe fn __set_FAULTMASK(fault_mask: u32) { + asm!("msr FAULTMASK, $0" : : "r"(fault_mask) : "memory" : "volatile"); + } +} + +#[cfg(target_feature = "v7")] +pub use self::v7::*; + +/* Core instruction access */ + +/// No Operation +/// +/// No Operation does nothing. This instruction can be used for code alignment +/// purposes. +#[inline(always)] +pub unsafe fn __NOP() { + asm!("nop" : : : : "volatile"); +} + +/// Wait For Interrupt +/// +/// Wait For Interrupt is a hint instruction that suspends execution until one +/// of a number of events occurs. +#[inline(always)] +pub unsafe fn __WFI() { + asm!("wfi" : : : : "volatile"); +} + +/// Wait For Event +/// +/// Wait For Event is a hint instruction that permits the processor to enter a +/// low-power state until one of a number of events occurs. +#[inline(always)] +pub unsafe fn __WFE() { + asm!("wfe" : : : : "volatile"); +} + +/// Send Event +/// +/// Send Event is a hint instruction. It causes an event to be signaled to the +/// CPU. +#[inline(always)] +pub unsafe fn __SEV() { + asm!("sev" : : : : "volatile"); +} + +/// Instruction Synchronization Barrier +/// +/// Instruction Synchronization Barrier flushes the pipeline in the processor, +/// so that all instructions following the ISB are fetched from cache or +/// memory, after the instruction has been completed. +#[inline(always)] +pub unsafe fn __ISB() { + asm!("isb 0xF" : : : "memory" : "volatile"); +} + +/// Data Synchronization Barrier +/// +/// Acts as a special kind of Data Memory Barrier. It completes when all +/// explicit memory accesses before this instruction complete. +#[inline(always)] +pub unsafe fn __DSB() { + asm!("dsb 0xF" : : : "memory" : "volatile"); +} + +/// Data Memory Barrier +/// +/// Ensures the apparent order of the explicit memory operations before and +/// after the instruction, without ensuring their completion. +#[inline(always)] +pub unsafe fn __DMB() { + asm!("dmb 0xF" : : : "memory" : "volatile"); +} diff --git a/coresimd/arm/mod.rs b/coresimd/arm/mod.rs index 10648eff38..51663a8a57 100644 --- a/coresimd/arm/mod.rs +++ b/coresimd/arm/mod.rs @@ -9,6 +9,11 @@ //! [arm_dat]: https://developer.arm.com/technologies/neon/intrinsics #![allow(non_camel_case_types)] +#[cfg(target_feature = "mclass")] +mod cmsis; +#[cfg(target_feature = "mclass")] +pub use self::cmsis::*; + mod v6; pub use self::v6::*; From 4ab1c54054ef3f9a7a09674303d6b1b5df6a0d3b Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Thu, 12 Jul 2018 01:24:27 -0500 Subject: [PATCH 2/5] add #[target_feature(enable = ...)] --- coresimd/arm/cmsis.rs | 81 ++++++++++++++++++++++++++++--------------- 1 file changed, 54 insertions(+), 27 deletions(-) diff --git a/coresimd/arm/cmsis.rs b/coresimd/arm/cmsis.rs index 4fc718d9ef..5b411246e2 100644 --- a/coresimd/arm/cmsis.rs +++ b/coresimd/arm/cmsis.rs @@ -10,7 +10,8 @@ /// /// Enables IRQ interrupts by clearing the I-bit in the CPSR. Can only be /// executed in Privileged modes. -#[inline(always)] +#[inline] +#[target_feature(enable = "mclass")] pub unsafe fn __enable_irq() { asm!("cpsie i" : : : "memory" : "volatile"); } @@ -19,7 +20,8 @@ pub unsafe fn __enable_irq() { /// /// Disables IRQ interrupts by setting the I-bit in the CPSR. Can only be /// executed in Privileged modes. -#[inline(always)] +#[inline] +#[target_feature(enable = "mclass")] pub unsafe fn __disable_irq() { asm!("cpsid i" : : : "memory" : "volatile"); } @@ -27,7 +29,8 @@ pub unsafe fn __disable_irq() { /// Get Control Register /// /// Returns the content of the Control Register. -#[inline(always)] +#[inline] +#[target_feature(enable = "mclass")] pub unsafe fn __get_CONTROL() -> u32 { let result: u32; asm!("mrs $0, CONTROL" : "=r"(result) : : : "volatile"); @@ -37,7 +40,8 @@ pub unsafe fn __get_CONTROL() -> u32 { /// Set Control Register /// /// Writes the given value to the Control Register. -#[inline(always)] +#[inline] +#[target_feature(enable = "mclass")] pub unsafe fn __set_CONTROL(control: u32) { asm!("msr CONTROL, $0" : : "r"(control) : "memory" : "volatile"); } @@ -45,7 +49,8 @@ pub unsafe fn __set_CONTROL(control: u32) { /// Get IPSR Register /// /// Returns the content of the IPSR Register. -#[inline(always)] +#[inline] +#[target_feature(enable = "mclass")] pub unsafe fn __get_IPSR() -> u32 { let result: u32; asm!("mrs $0, IPSR" : "=r"(result) : : : "volatile"); @@ -55,7 +60,8 @@ pub unsafe fn __get_IPSR() -> u32 { /// Get APSR Register /// /// Returns the content of the APSR Register. -#[inline(always)] +#[inline] +#[target_feature(enable = "mclass")] pub unsafe fn __get_APSR() -> u32 { let result: u32; asm!("mrs $0, APSR" : "=r"(result) : : : "volatile"); @@ -65,7 +71,8 @@ pub unsafe fn __get_APSR() -> u32 { /// Get xPSR Register /// /// Returns the content of the xPSR Register. -#[inline(always)] +#[inline] +#[target_feature(enable = "mclass")] pub unsafe fn __get_xPSR() -> u32 { let result: u32; asm!("mrs $0, XPSR" : "=r"(result) : : : "volatile"); @@ -75,7 +82,8 @@ pub unsafe fn __get_xPSR() -> u32 { /// Get Process Stack Pointer /// /// Returns the current value of the Process Stack Pointer (PSP). -#[inline(always)] +#[inline] +#[target_feature(enable = "mclass")] pub unsafe fn __get_PSP() -> u32 { let result: u32; asm!("mrs $0, PSP" : "=r"(result) : : : "volatile"); @@ -85,7 +93,8 @@ pub unsafe fn __get_PSP() -> u32 { /// Set Process Stack Pointer /// /// Assigns the given value to the Process Stack Pointer (PSP). -#[inline(always)] +#[inline] +#[target_feature(enable = "mclass")] pub unsafe fn __set_PSP(top_of_proc_stack: u32) { asm!("msr PSP, $0" : : "r"(top_of_proc_stack) : : "volatile"); } @@ -93,7 +102,8 @@ pub unsafe fn __set_PSP(top_of_proc_stack: u32) { /// Get Main Stack Pointer /// /// Returns the current value of the Main Stack Pointer (MSP). -#[inline(always)] +#[inline] +#[target_feature(enable = "mclass")] pub unsafe fn __get_MSP() -> u32 { let result: u32; asm!("mrs $0, MSP" : "=r"(result) : : : "volatile"); @@ -103,7 +113,8 @@ pub unsafe fn __get_MSP() -> u32 { /// Set Main Stack Pointer /// /// Assigns the given value to the Main Stack Pointer (MSP). -#[inline(always)] +#[inline] +#[target_feature(enable = "mclass")] pub unsafe fn __set_MSP(top_of_main_stack: u32) { asm!("msr MSP, $0" : : "r"(top_of_main_stack) : : "volatile"); } @@ -112,7 +123,8 @@ pub unsafe fn __set_MSP(top_of_main_stack: u32) { /// /// Returns the current state of the priority mask bit from the Priority Mask /// Register. -#[inline(always)] +#[inline] +#[target_feature(enable = "mclass")] pub unsafe fn __get_PRIMASK() -> u32 { let result: u32; asm!("mrs $0, PRIMASK" : "=r"(result) : : "memory" : "volatile"); @@ -122,7 +134,8 @@ pub unsafe fn __get_PRIMASK() -> u32 { /// Set Priority Mask /// /// Assigns the given value to the Priority Mask Register. -#[inline(always)] +#[inline] +#[target_feature(enable = "mclass")] pub unsafe fn __set_PRIMASK(pri_mask: u32) { asm!("msr PRIMASK, $0" : : "r"(pri_mask) : : "volatile"); } @@ -133,7 +146,8 @@ mod v7 { /// /// Enables FIQ interrupts by clearing the F-bit in the CPSR. Can only be /// executed in Privileged modes. - #[inline(always)] + #[inline] + #[target_feature(enable = "mclass")] pub unsafe fn __enable_fault_irq() { asm!("cpsie f" : : : "memory" : "volatile"); } @@ -142,7 +156,8 @@ mod v7 { /// /// Disables FIQ interrupts by setting the F-bit in the CPSR. Can only be /// executed in Privileged modes. - #[inline(always)] + #[inline] + #[target_feature(enable = "mclass")] pub unsafe fn __disable_fault_irq() { asm!("cpsid f" : : : "memory" : "volatile"); } @@ -150,7 +165,8 @@ mod v7 { /// Get Base Priority /// /// Returns the current value of the Base Priority register. - #[inline(always)] + #[inline] + #[target_feature(enable = "mclass")] pub unsafe fn __get_BASEPRI() -> u32 { let result: u32; asm!("mrs $0, BASEPRI" : "=r"(result) : : : "volatile"); @@ -160,7 +176,8 @@ mod v7 { /// Set Base Priority /// /// Assigns the given value to the Base Priority register. - #[inline(always)] + #[inline] + #[target_feature(enable = "mclass")] pub unsafe fn __set_BASEPRI(base_pri: u32) { asm!("msr BASEPRI, $0" : : "r"(base_pri) : "memory" : "volatile"); } @@ -170,7 +187,8 @@ mod v7 { /// Assigns the given value to the Base Priority register only if BASEPRI /// masking is disabled, or the new value increases the BASEPRI /// priority level. - #[inline(always)] + #[inline] + #[target_feature(enable = "mclass")] pub unsafe fn __set_BASEPRI_MAX(base_pri: u32) { asm!("msr BASEPRI_MAX, $0" : : "r"(base_pri) : "memory" : "volatile"); } @@ -178,7 +196,8 @@ mod v7 { /// Get Fault Mask /// /// Returns the current value of the Fault Mask register. - #[inline(always)] + #[inline] + #[target_feature(enable = "mclass")] pub unsafe fn __get_FAULTMASK() -> u32 { let result: u32; asm!("mrs $0, FAULTMASK" : "=r"(result) : : : "volatile"); @@ -188,7 +207,8 @@ mod v7 { /// Set Fault Mask /// /// Assigns the given value to the Fault Mask register. - #[inline(always)] + #[inline] + #[target_feature(enable = "mclass")] pub unsafe fn __set_FAULTMASK(fault_mask: u32) { asm!("msr FAULTMASK, $0" : : "r"(fault_mask) : "memory" : "volatile"); } @@ -203,7 +223,8 @@ pub use self::v7::*; /// /// No Operation does nothing. This instruction can be used for code alignment /// purposes. -#[inline(always)] +#[inline] +#[target_feature(enable = "mclass")] pub unsafe fn __NOP() { asm!("nop" : : : : "volatile"); } @@ -212,7 +233,8 @@ pub unsafe fn __NOP() { /// /// Wait For Interrupt is a hint instruction that suspends execution until one /// of a number of events occurs. -#[inline(always)] +#[inline] +#[target_feature(enable = "mclass")] pub unsafe fn __WFI() { asm!("wfi" : : : : "volatile"); } @@ -221,7 +243,8 @@ pub unsafe fn __WFI() { /// /// Wait For Event is a hint instruction that permits the processor to enter a /// low-power state until one of a number of events occurs. -#[inline(always)] +#[inline] +#[target_feature(enable = "mclass")] pub unsafe fn __WFE() { asm!("wfe" : : : : "volatile"); } @@ -230,7 +253,8 @@ pub unsafe fn __WFE() { /// /// Send Event is a hint instruction. It causes an event to be signaled to the /// CPU. -#[inline(always)] +#[inline] +#[target_feature(enable = "mclass")] pub unsafe fn __SEV() { asm!("sev" : : : : "volatile"); } @@ -240,7 +264,8 @@ pub unsafe fn __SEV() { /// Instruction Synchronization Barrier flushes the pipeline in the processor, /// so that all instructions following the ISB are fetched from cache or /// memory, after the instruction has been completed. -#[inline(always)] +#[inline] +#[target_feature(enable = "mclass")] pub unsafe fn __ISB() { asm!("isb 0xF" : : : "memory" : "volatile"); } @@ -249,7 +274,8 @@ pub unsafe fn __ISB() { /// /// Acts as a special kind of Data Memory Barrier. It completes when all /// explicit memory accesses before this instruction complete. -#[inline(always)] +#[inline] +#[target_feature(enable = "mclass")] pub unsafe fn __DSB() { asm!("dsb 0xF" : : : "memory" : "volatile"); } @@ -258,7 +284,8 @@ pub unsafe fn __DSB() { /// /// Ensures the apparent order of the explicit memory operations before and /// after the instruction, without ensuring their completion. -#[inline(always)] +#[inline] +#[target_feature(enable = "mclass")] pub unsafe fn __DMB() { asm!("dmb 0xF" : : : "memory" : "volatile"); } From b86fe2e00a9fb2f76f7dc83027091419a5170529 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Thu, 12 Jul 2018 01:29:16 -0500 Subject: [PATCH 3/5] add #[assert_instr(...)] --- coresimd/arm/cmsis.rs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/coresimd/arm/cmsis.rs b/coresimd/arm/cmsis.rs index 5b411246e2..0010b4b84a 100644 --- a/coresimd/arm/cmsis.rs +++ b/coresimd/arm/cmsis.rs @@ -12,6 +12,7 @@ /// executed in Privileged modes. #[inline] #[target_feature(enable = "mclass")] +#[cfg_attr(test, assert_instr(cpsie))] pub unsafe fn __enable_irq() { asm!("cpsie i" : : : "memory" : "volatile"); } @@ -22,6 +23,7 @@ pub unsafe fn __enable_irq() { /// executed in Privileged modes. #[inline] #[target_feature(enable = "mclass")] +#[cfg_attr(test, assert_instr(cpsid))] pub unsafe fn __disable_irq() { asm!("cpsid i" : : : "memory" : "volatile"); } @@ -31,6 +33,7 @@ pub unsafe fn __disable_irq() { /// Returns the content of the Control Register. #[inline] #[target_feature(enable = "mclass")] +#[cfg_attr(test, assert_instr(mrs))] pub unsafe fn __get_CONTROL() -> u32 { let result: u32; asm!("mrs $0, CONTROL" : "=r"(result) : : : "volatile"); @@ -42,6 +45,7 @@ pub unsafe fn __get_CONTROL() -> u32 { /// Writes the given value to the Control Register. #[inline] #[target_feature(enable = "mclass")] +#[cfg_attr(test, assert_instr(msr))] pub unsafe fn __set_CONTROL(control: u32) { asm!("msr CONTROL, $0" : : "r"(control) : "memory" : "volatile"); } @@ -51,6 +55,7 @@ pub unsafe fn __set_CONTROL(control: u32) { /// Returns the content of the IPSR Register. #[inline] #[target_feature(enable = "mclass")] +#[cfg_attr(test, assert_instr(mrs))] pub unsafe fn __get_IPSR() -> u32 { let result: u32; asm!("mrs $0, IPSR" : "=r"(result) : : : "volatile"); @@ -62,6 +67,7 @@ pub unsafe fn __get_IPSR() -> u32 { /// Returns the content of the APSR Register. #[inline] #[target_feature(enable = "mclass")] +#[cfg_attr(test, assert_instr(mrs))] pub unsafe fn __get_APSR() -> u32 { let result: u32; asm!("mrs $0, APSR" : "=r"(result) : : : "volatile"); @@ -73,6 +79,7 @@ pub unsafe fn __get_APSR() -> u32 { /// Returns the content of the xPSR Register. #[inline] #[target_feature(enable = "mclass")] +#[cfg_attr(test, assert_instr(mrs))] pub unsafe fn __get_xPSR() -> u32 { let result: u32; asm!("mrs $0, XPSR" : "=r"(result) : : : "volatile"); @@ -84,6 +91,7 @@ pub unsafe fn __get_xPSR() -> u32 { /// Returns the current value of the Process Stack Pointer (PSP). #[inline] #[target_feature(enable = "mclass")] +#[cfg_attr(test, assert_instr(mrs))] pub unsafe fn __get_PSP() -> u32 { let result: u32; asm!("mrs $0, PSP" : "=r"(result) : : : "volatile"); @@ -95,6 +103,7 @@ pub unsafe fn __get_PSP() -> u32 { /// Assigns the given value to the Process Stack Pointer (PSP). #[inline] #[target_feature(enable = "mclass")] +#[cfg_attr(test, assert_instr(msr))] pub unsafe fn __set_PSP(top_of_proc_stack: u32) { asm!("msr PSP, $0" : : "r"(top_of_proc_stack) : : "volatile"); } @@ -104,6 +113,7 @@ pub unsafe fn __set_PSP(top_of_proc_stack: u32) { /// Returns the current value of the Main Stack Pointer (MSP). #[inline] #[target_feature(enable = "mclass")] +#[cfg_attr(test, assert_instr(mrs))] pub unsafe fn __get_MSP() -> u32 { let result: u32; asm!("mrs $0, MSP" : "=r"(result) : : : "volatile"); @@ -115,6 +125,7 @@ pub unsafe fn __get_MSP() -> u32 { /// Assigns the given value to the Main Stack Pointer (MSP). #[inline] #[target_feature(enable = "mclass")] +#[cfg_attr(test, assert_instr(msr))] pub unsafe fn __set_MSP(top_of_main_stack: u32) { asm!("msr MSP, $0" : : "r"(top_of_main_stack) : : "volatile"); } @@ -125,6 +136,7 @@ pub unsafe fn __set_MSP(top_of_main_stack: u32) { /// Register. #[inline] #[target_feature(enable = "mclass")] +#[cfg_attr(test, assert_instr(mrs))] pub unsafe fn __get_PRIMASK() -> u32 { let result: u32; asm!("mrs $0, PRIMASK" : "=r"(result) : : "memory" : "volatile"); @@ -136,6 +148,7 @@ pub unsafe fn __get_PRIMASK() -> u32 { /// Assigns the given value to the Priority Mask Register. #[inline] #[target_feature(enable = "mclass")] +#[cfg_attr(test, assert_instr(msr))] pub unsafe fn __set_PRIMASK(pri_mask: u32) { asm!("msr PRIMASK, $0" : : "r"(pri_mask) : : "volatile"); } @@ -148,6 +161,7 @@ mod v7 { /// executed in Privileged modes. #[inline] #[target_feature(enable = "mclass")] + #[cfg_attr(test, assert_instr(cpsie))] pub unsafe fn __enable_fault_irq() { asm!("cpsie f" : : : "memory" : "volatile"); } @@ -158,6 +172,7 @@ mod v7 { /// executed in Privileged modes. #[inline] #[target_feature(enable = "mclass")] + #[cfg_attr(test, assert_instr(cpsid))] pub unsafe fn __disable_fault_irq() { asm!("cpsid f" : : : "memory" : "volatile"); } @@ -167,6 +182,7 @@ mod v7 { /// Returns the current value of the Base Priority register. #[inline] #[target_feature(enable = "mclass")] + #[cfg_attr(test, assert_instr(mrs))] pub unsafe fn __get_BASEPRI() -> u32 { let result: u32; asm!("mrs $0, BASEPRI" : "=r"(result) : : : "volatile"); @@ -178,6 +194,7 @@ mod v7 { /// Assigns the given value to the Base Priority register. #[inline] #[target_feature(enable = "mclass")] + #[cfg_attr(test, assert_instr(msr))] pub unsafe fn __set_BASEPRI(base_pri: u32) { asm!("msr BASEPRI, $0" : : "r"(base_pri) : "memory" : "volatile"); } @@ -189,6 +206,7 @@ mod v7 { /// priority level. #[inline] #[target_feature(enable = "mclass")] + #[cfg_attr(test, assert_instr(mrs))] pub unsafe fn __set_BASEPRI_MAX(base_pri: u32) { asm!("msr BASEPRI_MAX, $0" : : "r"(base_pri) : "memory" : "volatile"); } @@ -198,6 +216,7 @@ mod v7 { /// Returns the current value of the Fault Mask register. #[inline] #[target_feature(enable = "mclass")] + #[cfg_attr(test, assert_instr(mrs))] pub unsafe fn __get_FAULTMASK() -> u32 { let result: u32; asm!("mrs $0, FAULTMASK" : "=r"(result) : : : "volatile"); @@ -209,6 +228,7 @@ mod v7 { /// Assigns the given value to the Fault Mask register. #[inline] #[target_feature(enable = "mclass")] + #[cfg_attr(test, assert_instr(msr))] pub unsafe fn __set_FAULTMASK(fault_mask: u32) { asm!("msr FAULTMASK, $0" : : "r"(fault_mask) : "memory" : "volatile"); } @@ -225,6 +245,7 @@ pub use self::v7::*; /// purposes. #[inline] #[target_feature(enable = "mclass")] +#[cfg_attr(test, assert_instr(nop))] pub unsafe fn __NOP() { asm!("nop" : : : : "volatile"); } @@ -235,6 +256,7 @@ pub unsafe fn __NOP() { /// of a number of events occurs. #[inline] #[target_feature(enable = "mclass")] +#[cfg_attr(test, assert_instr(wfi))] pub unsafe fn __WFI() { asm!("wfi" : : : : "volatile"); } @@ -245,6 +267,7 @@ pub unsafe fn __WFI() { /// low-power state until one of a number of events occurs. #[inline] #[target_feature(enable = "mclass")] +#[cfg_attr(test, assert_instr(wfe))] pub unsafe fn __WFE() { asm!("wfe" : : : : "volatile"); } @@ -255,6 +278,7 @@ pub unsafe fn __WFE() { /// CPU. #[inline] #[target_feature(enable = "mclass")] +#[cfg_attr(test, assert_instr(sev))] pub unsafe fn __SEV() { asm!("sev" : : : : "volatile"); } @@ -266,6 +290,7 @@ pub unsafe fn __SEV() { /// memory, after the instruction has been completed. #[inline] #[target_feature(enable = "mclass")] +#[cfg_attr(test, assert_instr(isb))] pub unsafe fn __ISB() { asm!("isb 0xF" : : : "memory" : "volatile"); } @@ -276,6 +301,7 @@ pub unsafe fn __ISB() { /// explicit memory accesses before this instruction complete. #[inline] #[target_feature(enable = "mclass")] +#[cfg_attr(test, assert_instr(dsb))] pub unsafe fn __DSB() { asm!("dsb 0xF" : : : "memory" : "volatile"); } @@ -286,6 +312,7 @@ pub unsafe fn __DSB() { /// after the instruction, without ensuring their completion. #[inline] #[target_feature(enable = "mclass")] +#[cfg_attr(test, assert_instr(dmb))] pub unsafe fn __DMB() { asm!("dmb 0xF" : : : "memory" : "volatile"); } From 58bcbae821193db9a0488973e396628436259ee6 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Thu, 12 Jul 2018 01:46:20 -0500 Subject: [PATCH 4/5] add thumb targets to ci --- .travis.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.travis.yml b/.travis.yml index 29b02cc710..0746da3949 100644 --- a/.travis.yml +++ b/.travis.yml @@ -42,6 +42,10 @@ matrix: - cat wasm.wat - grep current_memory wasm.wat - grep grow_memory wasm.wat + - env: TARGET=thumbv6m-none-eabi NOSTD=1 + - env: TARGET=thumbv7m-none-eabi NOSTD=1 + - env: TARGET=thumbv7em-none-eabi NOSTD=1 + - env: TARGET=thumbv7em-none-eabihf NOSTD=1 - env: DOCUMENTATION install: true script: ci/dox.sh @@ -74,6 +78,8 @@ script: if [ "$NORUN" == "1" ]; then cargo build --target=$TARGET -p coresimd -p stdsimd --manifest-path crates/stdsimd/Cargo.toml cargo build --release --target=$TARGET -p coresimd -p stdsimd --manifest-path crates/stdsimd/Cargo.toml + elif [ "$NOSTD" == "1" ]; then + cargo build --target=$TARGET -p coresimd --manifest-path crates/stdsimd/Cargo.toml else ci/run-docker.sh $TARGET $FEATURES fi From 5cb0dad36c4582f07f146f81c71f680b2041e01b Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Fri, 13 Jul 2018 22:39:29 -0500 Subject: [PATCH 5/5] add links to standard, API and implementation to the module level docs --- coresimd/arm/cmsis.rs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/coresimd/arm/cmsis.rs b/coresimd/arm/cmsis.rs index 0010b4b84a..8f150d2cb0 100644 --- a/coresimd/arm/cmsis.rs +++ b/coresimd/arm/cmsis.rs @@ -1,8 +1,19 @@ -#![allow(non_snake_case)] +//! CMSIS: Cortex Microcontroller Software Interface Standard +//! +//! The version 5 of the standard can be found at: +//! +//! http://arm-software.github.io/CMSIS_5/Core/html/index.html +//! +//! The API reference of the standard can be found at: +//! +//! - Core function access -- http://arm-software.github.io/CMSIS_5/Core/html/group__Core__Register__gr.html +//! - Intrinsic functions for CPU instructions -- http://arm-software.github.io/CMSIS_5/Core/html/group__intrinsic__CPU__gr.html +//! +//! The reference C implementation used as the base of this Rust port can be found at +//! +//! https://github.com/ARM-software/CMSIS_5/blob/5.3.0/CMSIS/Core/Include/cmsis_gcc.h -/// Extracted from [CMSIS 5]'s CMSIS/Core/Include/cmsis_gcc.h -/// -/// [CMSIS 5]: https://github.com/ARM-software/CMSIS_5 +#![allow(non_snake_case)] /* Core function access */