diff options
Diffstat (limited to 'stm-arm-neon-ref.h')
-rw-r--r-- | stm-arm-neon-ref.h | 37 |
1 files changed, 21 insertions, 16 deletions
diff --git a/stm-arm-neon-ref.h b/stm-arm-neon-ref.h index 33677fd..f7c7cc6 100644 --- a/stm-arm-neon-ref.h +++ b/stm-arm-neon-ref.h @@ -576,11 +576,15 @@ typedef union { #ifdef __ARMCC_VERSION register _ARM_FPSCR _afpscr_for_qc __asm("fpscr"); # define Neon_Cumulative_Sat _afpscr_for_qc.b.QC -# define Set_Neon_Cumulative_Sat(x) {Neon_Cumulative_Sat = (x);} +# define Set_Neon_Cumulative_Sat(x, depend) {Neon_Cumulative_Sat = (x);} #else /* GCC/ARM does not know this register */ # define Neon_Cumulative_Sat __read_neon_cumulative_sat() -# define Set_Neon_Cumulative_Sat(x) __set_neon_cumulative_sat((x)) +/* We need a fake dependency to ensure correct ordering of asm + statements to preset the QC flag value, and Neon operators writing + to QC. */ +#define Set_Neon_Cumulative_Sat(x, depend) \ + __set_neon_cumulative_sat((x), (depend)) # if defined(__aarch64__) static volatile int __read_neon_cumulative_sat (void) { @@ -588,13 +592,14 @@ static volatile int __read_neon_cumulative_sat (void) { asm volatile ("mrs %0,fpsr" : "=r" (_afpscr_for_qc)); return _afpscr_for_qc.b.QC; } -static void __set_neon_cumulative_sat (int x) { - _ARM_FPSCR _afpscr_for_qc; - asm volatile ("mrs %0,fpsr" : "=r" (_afpscr_for_qc)); - _afpscr_for_qc.b.QC = x; - asm volatile ("msr fpsr,%0" : : "r" (_afpscr_for_qc)); - return; -} + +#define __set_neon_cumulative_sat(x, depend) { \ + _ARM_FPSCR _afpscr_for_qc; \ + asm volatile ("mrs %0,fpsr" : "=r" (_afpscr_for_qc)); \ + _afpscr_for_qc.b.QC = x; \ + asm volatile ("msr fpsr,%1" : "=X" (depend) : "r" (_afpscr_for_qc)); \ + } + # else static volatile int __read_neon_cumulative_sat (void) { _ARM_FPSCR _afpscr_for_qc; @@ -602,13 +607,13 @@ static volatile int __read_neon_cumulative_sat (void) { return _afpscr_for_qc.b.QC; } -static void __set_neon_cumulative_sat (int x) { - _ARM_FPSCR _afpscr_for_qc; - asm volatile ("vmrs %0,fpscr" : "=r" (_afpscr_for_qc)); - _afpscr_for_qc.b.QC = x; - asm volatile ("vmsr fpscr,%0" : : "r" (_afpscr_for_qc)); - return; -} +#define __set_neon_cumulative_sat(x, depend) { \ + _ARM_FPSCR _afpscr_for_qc; \ + asm volatile ("vmrs %0,fpscr" : "=r" (_afpscr_for_qc)); \ + _afpscr_for_qc.b.QC = x; \ + asm volatile ("vmsr fpscr,%1" : "=X" (depend) : "r" (_afpscr_for_qc)); \ + } + # endif #endif |