Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Оптимизация умножения в GCC 4.7.2
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > GNU/OpenSource средства разработки
amaora
Фрагмент исходного кода.

Код
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
Цитата(amaora @ Nov 30 2012, 01:11) *
Код
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
Цитата(amaora @ Nov 29 2012, 22:11) *
Код
r = (r << 1) + (r << 3);
какой тип у переменной r?
ибо __muluhisi3 - это Multiply an unsigned 16-bit integer with a 32-bit integer to a 32-bit result
Цитата(demiurg_spb @ Dec 6 2012, 09:20) *
какой тип у переменной 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
Цитата
какой тип у переменной r?

signed long, хотя на самом деле 16 бит, но нужен старший байт результата. 16-бит x 10 -> 24-бит.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.