Перейти к содержанию
    

Оптимизация умножения в GCC 4.7.2

Фрагмент исходного кода.

 

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, может даже быстрее будет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

r = (r << 1) + (r << 3);

s2f.c:(.text+0xac): undefined reference to `__muluhisi3'[/code]

 

Использовать стартап код и умножения из libgcc не планирую. Проблема решается с -O2, однако хочется указать -Os.

Какие варианты решения?

p.s. наверно проще всего написать свою умножалку на 10 через mul, может даже быстрее будет.

С чем связана такая неприязнь к libgcc? При грамотном подходе оттуда импортируется только одна эта функция.

 

Как вариант - можно подсмотреть реализацию в исходниках libgcc.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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)

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

какой тип у переменной r?

signed long, хотя на самом деле 16 бит, но нужен старший байт результата. 16-бит x 10 -> 24-бит.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...