From: Borja F. <bor...@gm...> - 2013-07-28 21:35:36
|
Found it, the isfinite() function takes in a double, and since our backend treats them as 64bit types this fails in inline asm. Removing the function implementation and just leaving it as an extern compiles successfully. 2013/7/28 Borja Ferrer <bor...@gm...> > I've tried different optimization levels and they all fail for me. The > interesting thing is that i've isolated the strtod function in a different > file and it compiles fine, so there's something in the huge file that > causes this. > > > 2013/7/28 Stepan Dyatkovskiy <stp...@na...> > >> >> >> > Ok this was a bit insane to reduce but I've found the offending lines. >> > >> > The problem is how uint32_t and uint16_t are defined: >> > typedef unsigned int uint16_t __attribute__ ((__mode__ (__HI__))); >> > >> > typedef unsigned int uint32_t __attribute__ ((__mode__ (__SI__))); >> > >> > I have no idea what this syntax is, but if you refedefine those types >> to unsigned int / long the problem goes away. >> >> Wow great. Never expected that wrong definition. >> >> > >> > Now im getting an error in llc: error: couldn't allocate input reg for >> constraint 'r' >> > >> >> Hm.. May be try with O2 instead of Os? >> >> > 2013/7/28 Borja Ferrer <bor...@gm...> >> > >> >> I've compiled the file you attached, ignoring all warnings i get from >> clang about the unknown attributes like progmem, i'm getting the assertion >> "multibyte index is out of range." >> >> >> >> 2013/7/28 Borja Ferrer <bor...@gm...> >> >> >> >>> Hello Stepan, >> >>> >> >>> 1) It seems clang mangles assembly functions names by prefixing a \01 >> character. I haven't found yet the code that does this depending on the >> target used. >> >>> >> >>> 2) About the code above, I'm assuming you got that inline asm code >> from the __LPM_dword_classic__ macro. This is what I'm getting for the >> following C code: >> >>> typedef unsigned int uint16_t; >> >>> typedef unsigned long uint32_t; >> >>> >> >>> #define __LPM_dword_classic__(addr) \ >> >>> (__extension__({ \ >> >>> uint16_t __addr16 = (uint16_t)(addr); \ >> >>> uint32_t __result; \ >> >>> __asm__ __volatile__ \ >> >>> >> >>> ( \ >> >>> "lpm" "\n\t" \ >> >>> "mov %A0, r0" "\n\t" \ >> >>> "adiw r30, 1" "\n\t" \ >> >>> >> >>> "lpm" "\n\t" \ >> >>> "mov %B0, r0" "\n\t" \ >> >>> "adiw r30, 1" "\n\t" \ >> >>> "lpm" "\n\t" \ >> >>> >> >>> "mov %C0, r0" "\n\t" \ >> >>> "adiw r30, 1" "\n\t" \ >> >>> "lpm" "\n\t" \ >> >>> "mov %D0, r0" "\n\t" \ >> >>> >> >>> : "=r" (__result), "=z" (__addr16) \ >> >>> : "1" (__addr16) \ >> >>> : "r0" \ >> >>> >> >>> ); \ >> >>> >> >>> __result; \ >> >>> })) >> >>> unsigned long inlineasm(unsigned int addr) >> >>> { >> >>> return __LPM_dword_classic__(addr); >> >>> } >> >>> >> >>> clang produces: >> >>> >> >>> define i32 @inlineasm(i16 %addr) #0 { >> >>> >> >>> entry: >> >>> %0 = tail call { i32, i16 } asm sideeffect "lpm\0A\09mov ${0:A}, >> r0\0A\09adiw r30, 1\0A\09lpm\0A\09mov ${0:B}, r0\0A\09adiw r30, >> 1\0A\09lpm\0A\09mov ${0:C}, r0\0A\09adiw r30, 1\0A\09lpm\0A\09mov ${0:D}, >> r0\0A\09", "=r,=z,1,~{r0}"(i16 %addr) #2, !srcloc !4 >> >>> >> >>> %asmresult = extractvalue { i32, i16 } %0, 0 >> >>> ret i32 %asmresult >> >>> } >> >>> >> >>> No truncations here as far i can tell. Try this code and see what you >> get. >> >> >> -- >> Truly yours, >> Stepan Dyatkovskiy >> > > |