Wed 24 Dec 2014 06:40:17 AM UTC, comment #1:
Below is the patch to fix this issue.
diff --git a/avr-libc/include/avr/wdt.h b/avr-libc/include/avr/wdt.h
index fc15885..3130e67 100644
--- a/avr-libc/include/avr/wdt.h
+++ b/avr-libc/include/avr/wdt.h
@@ -148,25 +148,24 @@
*/
#define wdt_enable(timeout) \
do { \
-uint8_t temp = 0; \
+uint8_t temp; \
_asm_ __volatile__ ( \
"in _tmp_reg_, %[rampd]" "\n\t" \
"out %[rampd], _zero_reg_" "\n\t" \
"out %[ccp_reg], %[ioreg_cen_mask]" "\n\t" \
"sts %[wdt_reg], %[wdt_enable_timeout]" "\n\t" \
"1:lds %[tmp], %[wdt_status_reg]" "\n\t" \
- "sbrc %[tmp], %[wdt_syncbusy_bit]" "\n\t" \
+ "sbrc %[tmp], %[wdt_syncbusy_bit]" "\n\t" \
"rjmp 1b" "\n\t" \
"out %[rampd], _tmp_reg_" "\n\t" \
- : "=r" (temp) \
+ : [tmp] "=r" (temp) \
: [rampd] "M" (_SFR_MEM_ADDR(RAMPD)), \
[ccp_reg] "I" (_SFR_MEM_ADDR(CCP)), \
[ioreg_cen_mask] "r" ((uint8_t)CCP_IOREG_gc), \
[wdt_reg] "M" (_SFR_MEM_ADDR(WDT_CTRL)), \
[wdt_enable_timeout] "r" ((uint8_t)(WDT_CEN_bm | WDT_ENABLE_bm | timeout)), \
[wdt_status_reg] "M" (_SFR_MEM_ADDR(WDT_STATUS)), \
- [wdt_syncbusy_bit] "I" (WDT_SYNCBUSY_bm), \
- [tmp] "r" (temp) \
+ [wdt_syncbusy_bit] "I" (WDT_SYNCBUSY_bm) \
: "r0" \
); \
} while(0)
|
Mon 15 Dec 2014 07:25:34 PM UTC, original submission:
wdt.h comes with wrong inline assembler arguments. Let me give an example (2014-12-15 SVN trunk r2641):
Operand %[tmp] (%8) is changed but not indicated as so by means of constraint modifiers.
Notice that the compiler may allocate different registers to %0 and %8. Hence, the fix is to refer to %0 instead of to %[tmp] resp. moving %[tmp] to the first operand. Also notice that %8 is unused and can be dropped. temp is loaded with 0 but respective content of %[tmp] is discarded by LDS.
The other asm in wdt.h (or maybe even more headers or source files) might suffer from the same or similar flaws.
|