amaora 21 29 ноября, 2012 Опубликовано 29 ноября, 2012 · Жалоба Фрагмент исходного кода. r = (r << 1) + (r << 3); Преобразуется в умножение на 10, с использованием кода откуда-то из libgcc. В результате получаю. s2f.o: In function `f2s': s2f.c:(.text+0xac): undefined reference to `__muluhisi3' Использовать стартап код и умножения из libgcc не планирую. Проблема решается с -O2, однако хочется указать -Os. $ avr-gcc --version avr-gcc (Gentoo 4.7.2 p1.1, pie-0.5.5) 4.7.2 Copyright (C) 2012 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Сейчас собираю с такими ключами. CFLAGS = -mmcu=atmega88 CFLAGS += -fconserve-stack CFLAGS += -fno-strict-aliasing CFLAGS += -fno-tree-loop-ivcanon CFLAGS += -fno-builtin CFLAGS += -std=c99 -pipe -Wall -O2 AFLAGS = -mmcu=atmega88 LFLAGS = -m avr4 -T linker.ld Какие варианты решения? p.s. наверно проще всего написать свою умножалку на 10 через mul, может даже быстрее будет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sla000 0 30 ноября, 2012 Опубликовано 30 ноября, 2012 · Жалоба r = (r << 1) + (r << 3); s2f.c:(.text+0xac): undefined reference to `__muluhisi3'[/code] Использовать стартап код и умножения из libgcc не планирую. Проблема решается с -O2, однако хочется указать -Os. Какие варианты решения? p.s. наверно проще всего написать свою умножалку на 10 через mul, может даже быстрее будет. С чем связана такая неприязнь к libgcc? При грамотном подходе оттуда импортируется только одна эта функция. Как вариант - можно подсмотреть реализацию в исходниках libgcc. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 6 декабря, 2012 Опубликовано 6 декабря, 2012 · Жалоба r = (r << 1) + (r << 3); какой тип у переменной r? ибо __muluhisi3 - это Multiply an unsigned 16-bit integer with a 32-bit integer to a 32-bit result какой тип у переменной r? ибо __muluhisi3 - это Multiply an unsigned 16-bit integer with a 32-bit integer to a 32-bit result uint16_t r; ... r = (r << 1) + (r << 3); 130 0004 292F mov r18,r25 132 0006 382F mov r19,r24 40:main.c **** r = (r << 1) + (r << 3); 137 0008 A901 movw r20,r18 138 000a 440F lsl r20 139 000c 551F rol r21 141 000e C901 movw r24,r18 142 0010 23E0 ldi r18,3 143 1: 144 0012 880F lsl r24 145 0014 991F rol r25 146 0016 2A95 dec r18 147 0018 01F4 brne 1b 148 .LVL4: 149 001a 840F add r24,r20 150 001c 951F adc r25,r21 А теперь самое интересное: uint16_t r; ... r *= 10U; 138 0004 832F mov r24,r19 140 0006 922F mov r25,r18 40:main.c **** r *= 10U; 145 0008 4AE0 ldi r20,lo8(10) 146 000a 489F mul r20,r24 147 000c 9001 movw r18,r0 148 000e 499F mul r20,r25 149 0010 300D add r19,r0 150 0012 1124 clr __zero_reg__ Не стоит недооценивать компилятор... Using built-in specs. COLLECT_GCC=z:\gcc\avr-gcc\bin\avr-gcc.EXE COLLECT_LTO_WRAPPER=z:/gcc/avr-gcc/bin/../libexec/gcc/avr/4.7.2/lto-wrapper.exe Target: avr Configured with: ../../gcc.gnu.org/gcc-4_7-branch/configure --target=avr --prefix=/local/gnu/install/gcc-4.7-mingw32 --host=i386-mingw32 --build=i686-linux-gnu --enable-languages=c,c++ --disable-nls --disable-shared --with-dwarf2 --with-avrlibc=yes Thread model: single gcc version 4.7.2 (GCC) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
amaora 21 7 декабря, 2012 Опубликовано 7 декабря, 2012 · Жалоба какой тип у переменной r? signed long, хотя на самом деле 16 бит, но нужен старший байт результата. 16-бит x 10 -> 24-бит. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться