AVR C -- они все издеваются что ли?!.

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From Russian to

Threaded View
▐┤E╚°' All!

   Существуют в природе хоть какие-нибудь нормальные компиляторы C для AVR?
Посмотрел пока что CodeVisionAVR, который (без Automatic Register Allocation)
делает такое:

;      40 led_status<<=1;
   LDS  R30,_led_status
   LSL  R30
   STS  _led_status,R30
;      41 led_status|=1;
   ORI  R30,1
   STS  _led_status,R30

И avr-gcc, который со всякими ключами оптимизациями делает вообще такое:

  5a: 80 91 60 00    lds   r24, 0x0060
  5e: 99 27          eor   r25, r25
  60: 00 97          sbiw  r24, 0x00   ; 0
  62: 19 f0          breq  .+6         ; 0x6a

  6a: 80 91 61 00    lds   r24, 0x0061
  6e: 90 91 62 00    lds   r25, 0x0062
  72: 01 96          adiw  r24, 0x01   ; 1
  74: 90 93 62 00    sts   0x0062, r25
  78: 80 93 61 00    sts   0x0061, r24
  7c: 80 91 61 00    lds   r24, 0x0061
  80: 90 91 62 00    lds   r25, 0x0062
  84: 8f 5f          subi  r24, 0xFF   ; 255
  86: 93 40          sbci  r25, 0x03   ; 3
  88: a9 f4          brne  .+42        ; 0xb4

Создаётся впечатление, что даже самая наипримитивнейшая чистка кода отсутствует
полностью -- что транслятор наделал, то и нате!
   Hеужели всё действительно настолько плохо?.. :-(

                                                                      |V|uxau/\

AVR C -- они все издеваются что ли?!.
    Всем привет!

Michael Ryazanov писал к All 28.01.2005:

 MR>    Существуют в природе хоть какие-нибудь нормальные компиляторы C для
 MR> AVR?

Да - IAR

--
Аскольд Волков, Новосибирск. http://www.inp.nsk.su/~volkov/


Re: AVR C -- они все издеваются что ли?!.
Hello, Michael!
You wrote to All on Thu, 27 Jan 2005 22:35:00 +0300:

 MR> И avr-gcc, который со всякими ключами оптимизациями делает вообще
 MR> такое:

 MR>   5a: 80 91 60 00    lds   r24, 0x0060
 MR>   5e: 99 27          eor   r25, r25
<...>

И как ты этого добился?
Вот мой пример:
=== Cut ===
#include <inttypes.h>
uint8_t led_status = 0;
int main() {
  led_status <<= 1;
  led_status |= 1;
  return led_status;
}
=== Cut ===

$ avr-gcc -g -Wall -mmcu=atmega8 -Os -o proba.elf proba.c
$ avr-objdump -h -S proba.elf > proba.listing
$ less proba.listing
<...>
  led_status <<= 1;
  64: 80 91 60 00  lds r24, 0x0060
  68: 88 0f        add r24, r24
  led_status |= 1;
  6a: 81 60        ori r24, 0x01 ; 1
  6c: 80 93 60 00  sts 0x0060, r24
  return led_status;
}
<...>

При добавлении "volatile" к "led_status", делает так:

  led_status <<= 1;
  64: 80 91 60 00  lds r24, 0x0060
  68: 88 0f        add r24, r24
  6a: 80 93 60 00  sts 0x0060, r24
  led_status |= 1;
  6e: 80 91 60 00  lds r24, 0x0060
  72: 81 60        ori r24, 0x01 ; 1
  74: 80 93 60 00  sts 0x0060, r24
  return led_status;
  78: 80 91 60 00  lds r24, 0x0060
}

Вот ещё такой пример:
=== Cut ===
#include <inttypes.h>
#include <avr/io.h>
int main() {
  uint8_t led_status = PINB;
  led_status <<= 1;
  led_status |= 1;
  return led_status;
}

=== Cut ===

Компилится в это:

  uint8_t led_status = PINB;
  64: 86 b3        in r24, 0x16 ; 22
  led_status <<= 1;
  66: 88 0f        add r24, r24
  led_status |= 1;
  68: 81 60        ori r24, 0x01 ; 1
  return led_status;
}

И что не так?
avr-gcc версии 3.4.1 под винду.

With best regards, Serg.



AVR C -- они все издеваются что ли?!.
          Очень рад вас видеть, Michael!

27 Янв 05 в 22:35, Michael Ryazanov писал All следующее:

 MR>    Существуют в природе хоть какие-нибудь нормальные компиляторы C
 MR> для
 MR> AVR? Посмотрел пока что CodeVisionAVR, который (без Automatic Register
 MR> Allocation) делает такое:

 MR> ;      40 led_status<<=1;
 MR>    LDS  R30,_led_status
 MR>    LSL  R30
 MR>    STS  _led_status,R30
 MR> ;      41 led_status|=1;
 MR>    ORI  R30,1
 MR>    STS  _led_status,R30

 MR> И avr-gcc, который со всякими ключами оптимизациями делает вообще такое:

 MR>   5a: 80 91 60 00    lds   r24, 0x0060
 MR>   5e: 99 27          eor   r25, r25
 MR>   60: 00 97          sbiw  r24, 0x00   ; 0
 MR>   62: 19 f0          breq  .+6         ; 0x6a

 MR>   6a: 80 91 61 00    lds   r24, 0x0061
 MR>   6e: 90 91 62 00    lds   r25, 0x0062
 MR>   72: 01 96          adiw  r24, 0x01   ; 1
 MR>   74: 90 93 62 00    sts   0x0062, r25
 MR>   78: 80 93 61 00    sts   0x0061, r24
 MR>   7c: 80 91 61 00    lds   r24, 0x0061
 MR>   80: 90 91 62 00    lds   r25, 0x0062
 MR>   84: 8f 5f          subi  r24, 0xFF   ; 255
 MR>   86: 93 40          sbci  r25, 0x03   ; 3
 MR>   88: a9 f4          brne  .+42        ; 0xb4

 MR> Создаётся впечатление, что даже самая наипримитивнейшая чистка кода
 MR> отсутствует полностью -- что транслятор наделал, то и нате!
 MR>    Hеужели всё действительно настолько плохо?.. :-(

 надо указывать, что результат ожидаешь восьмибитный, чуть лучше будет...

 а сильно напрягает? флеша жалко? я просто внимания не обращаю...
 правда подобного ужаса сам не видел, пользуюсь гцц под виндой (винавр)
 на грабли с неявным преобразованием типов наступал, но как подобный код
 получился - не понимаю.

        AVL

AVR C -- они все издеваются что ли?!.
Hello, Michael!

Четверг Январь 27 2005 22:35, Michael Ryazanov wrote to All:
 MR> И avr-gcc, который со всякими ключами оптимизациями делает вообще
 MR> такое:
хмю вот попробовал:

void inline set_bit(volatile unsigned char& port, unsigned char bit)
{
        port |= _BV(bit);
}


 set_bit(DDRD, CONV);
 set_bit(PORTD, CONV);
Транслируется в
  c6:   8c 9a           sbi     0x11, 4 ; 17
  c8:   94 9a           sbi     0x12, 4 ; 18

Оптимизация -O2
avr-c++.exe (GCC) 3.3.1

Best regards и все такое... Sergey.             [Death/Black/Power Metal]

Re: AVR C -- они все издеваются что ли?!.
Hello, Askold!

 MR>> Существуют в природе хоть какие-нибудь нормальные компиляторы C для AVR?
 AV> Да - IAR

   Честно говоря, качать 58 Мб не очень хочется, тем более, что он совсем не
бесплатный. Хотя, если он действительно нормальный, и к нему есть лекарство от
жадности... ?

                                                                      |V|uxau/\

Re: AVR C -- они все издеваются что ли?!.
    Всем привет!

Michael Ryazanov писал к Askold Volkov Sat, 29 Jan 2005 17:32:00 +0300:

 MR>>> Существуют в природе хоть какие-нибудь нормальные компиляторы C для
 MR>>> AVR?
 AV>> Да - IAR

 MR>    Честно говоря, качать 58 Мб не очень хочется,

Ну не хочется, так не качай. Мы-то тут при чем? Ты спросил, я ответил, а уж
что с этим ответом делать - дело твое.

 MR> Хотя, если он действительно  нормальный, и к нему есть лекарство от
жадности... ?

Лекарство, разумеется, есть:
http://briefcase.yahoo.com
id: ru_embedded00
pass: sobaka

Что касается нормальности, то у каждого свои критерии, однако то, что этот
компилятор для AVR лучший из существующих - это точно.

--
Аскольд Волков, Новосибирск. http://www.inp.nsk.su/~volkov/



AVR C -- они все издеваются что ли?!.
Привет Michael!

29 Jan 05 17:32, Michael Ryazanov писал Askold Volkov:

 MR>>> Существуют в природе хоть какие-нибудь нормальные компиляторы C
 MR>>> для AVR?
 AV>> Да - IAR
 MR>    Честно говоря, качать 58 Мб не очень хочется, тем более, что он
 MR> совсем не бесплатный.

    Бесплатный - avr-gcc.

Всего наилучшего,                                 [Team PCAD 2000]
Алексей М.
... Смотрю куда глаза глядят...

Re: AVR C -- они все издеваются что ли?!.
Hello, Oleksandr!

 MR>> Существуют в природе хоть какие-нибудь нормальные компиляторы C для AVR?
 MR>> Посмотрел пока что CodeVisionAVR, который (без Automatic Register
 MR>> Allocation) делает такое:

 MR>> ;      40 led_status<<=1;
 MR>>    LDS  R30,_led_status
 MR>>    LSL  R30
 MR>>    STS  _led_status,R30
 MR>> ;      41 led_status|=1;
 MR>>    ORI  R30,1
 MR>>    STS  _led_status,R30

 MR>> И avr-gcc, который со всякими ключами оптимизациями делает вообще такое:

 MR>>   5a: 80 91 60 00    lds   r24, 0x0060
 MR>>   5e: 99 27          eor   r25, r25
 MR>>   60: 00 97          sbiw  r24, 0x00   ; 0
 MR>>   62: 19 f0          breq  .+6         ; 0x6a

 MR>>   6a: 80 91 61 00    lds   r24, 0x0061
 MR>>   6e: 90 91 62 00    lds   r25, 0x0062
 MR>>   72: 01 96          adiw  r24, 0x01   ; 1
 MR>>   74: 90 93 62 00    sts   0x0062, r25
 MR>>   78: 80 93 61 00    sts   0x0061, r24
 MR>>   7c: 80 91 61 00    lds   r24, 0x0061
 MR>>   80: 90 91 62 00    lds   r25, 0x0062
 MR>>   84: 8f 5f          subi  r24, 0xFF   ; 255
 MR>>   86: 93 40          sbci  r25, 0x03   ; 3
 MR>>   88: a9 f4          brne  .+42        ; 0xb4

 OR> Hельзя ли привести C-шный исходник, из которого gcc сделал приведенный
 OR> код? Это ведь совершенно другое, чем то, что компилировалось CodeVision.

   Вы таки будете смеяться, но приведённые отрывки -- это примеры, поставляемые
с самими компиляторами... :-/
   Для CodeVisionAVR -- проект из каталога EXAMPLES\LED\, собранный сразу после
установки (без изменения каких-либо настроек).
   Для avr-gcc -- результат команды make в каталоге examples\demo\ после
установки только что скачанного с SourceForge WinAVR (20040720, gcc version
3.4.1).

 OR> Я не говорю, что gcc во всём хорош, он иногда слишком увлекается
 OR> соблюдением integer promotion rules из стандарта C и недочищает после
 OR> этого явно ненужные хвосты.
<...>
 OR> Худшего кода я смог *добиться* только комбинацией знаковой переменной
 OR> с квалификатором volatile:
 OR> volatile int8_t led_status;
 OR> Тогда перед выполнением сдвига остаётся преобразование со знаком
 OR> к знаковому 16-битному значению и сдвиг 16-битного значения. И несмотря
 OR> на ненужность старшего байта оптимизатор этот хвост не подчистил:
<...>
 OR>    6:foo.c         ****         led_status <<= 1;
 OR>   57                    .LM2:
 OR>   58 0000 8091 0000             lds r24,led_status
 OR>   59 0004 9927                  clr r25
 OR>   60 0006 87FD                  sbrc r24,7
 OR>   61 0008 9095                  com r25
 OR>   62 000a 880F                  lsl r24
 OR>   63 000c 991F                  rol r25
 OR>   64 000e 8093 0000             sts led_status,r24

   Тоже стыд и срам. Hо тут он хоть как-то объясним, как и в моём первом куске
(5a-62). А вот что его заставило сгенерировать такой код для второго куска
(6a-88)?

 OR> В любом случае приведенный тобой код соответствует совсем другому
 OR> исходнику.

   Откуда взят тот исходник, я уже сказал, а маленький пример, демонстрирующий
такое поведение, сейчас вот сделал:

#include <inttypes.h>

volatile uint16_t pwm;

void f(void) {
   if (++pwm == 1023)
      pwm = 0;
}



                                                                      |V|uxau/\

AVR C -- они все издеваются что ли?!.
Привет Michael!

29 Jan 05 18:24, Michael Ryazanov писал Oleksandr Redchuk:

 MR>    Откуда взят тот исходник, я уже сказал, а маленький пример,
 MR> демонстрирующий такое поведение, сейчас вот сделал:

 MR> #include <inttypes.h>

 MR> volatile uint16_t pwm;

 MR> void f(void) {
 MR>    if (++pwm == 1023)
 MR>       pwm = 0;
 MR> }

avr-gcc -O3:
f:
        lds r26,pwm
        lds r27,(pwm)+1
        adiw r26,1
        sts (pwm)+1,r27
        sts pwm,r26
        lds r24,pwm
        lds r25,(pwm)+1
        subi r24,lo8(1023)
        sbci r25,hi8(1023)
        breq .L4
        ret
.L4:
        sts (pwm)+1,__zero_reg__
        sts pwm,__zero_reg__
        ret

    Кроме уже упоминавшегося тут пристрастия к lds/sts вместо обращения через
указатель, придраться по-моему не к чему.

Всего наилучшего,                                 [Team PCAD 2000]
Алексей М.
... Крыскас. Потому что крыса вам доверяет.

Re: AVR C -- они все издеваются что ли?!.
▐┤E╚°' Alex!

30.01 20:04 Alex Mogilnikov, 2:5054/70 -> Michael Ryazanov

 MR>>    Откуда взят тот исходник, я уже сказал, а маленький пример,
 MR>> демонстрирующий такое поведение, сейчас вот сделал:

 MR>> #include <inttypes.h>

 MR>> volatile uint16_t pwm;

 MR>> void f(void) {
 MR>>    if (++pwm == 1023)
 MR>>       pwm = 0;
 MR>> }

 AM> avr-gcc -O3:
 AM> f:
 AM>         lds r26,pwm
 AM>         lds r27,(pwm)+1
 AM>         adiw r26,1
 AM>         sts (pwm)+1,r27
 AM>         sts pwm,r26
 AM>         lds r24,pwm
 AM>         lds r25,(pwm)+1
 AM>         subi r24,lo8(1023)
 AM>         sbci r25,hi8(1023)
 AM>         breq .L4
 AM>         ret
 AM> .L4:
 AM>         sts (pwm)+1,__zero_reg__
 AM>         sts pwm,__zero_reg__
 AM>         ret

 AM> Кроме уже упоминавшегося тут пристрастия к lds/sts вместо обращения через
 AM> указатель, придраться по-моему не к чему.

   А по-хорошему должно было бы быть что-то вроде (переменная pwm лежит в паре
регистров r26,r27):

f:
        adiw r26,1
        cpi r26,lo8(1023)
        brne .L4
        cpi r27,hi8(1023)
        brne .L4
        clr r26
        clr r27
.L4:
        ret

                                                                      |V|uxau/\

Re: AVR C -- они все издеваются что ли?!.
сообщил/сообщила в новостях следующее:
Quoted text here. Click to load it
Глобальная переменная не может лечь в регистр.

Денис.



Re: AVR C -- они все издеваются что ли?!.
Hello, Dennis!
You wrote to All on Fri, 11 Feb 2005 14:26:17 +0300:
MR>>>> volatile uint16_t pwm;
 ??>>
 MR>>>> void f(void) {
 MR>>>>    if (++pwm == 1023)
 MR>>>>       pwm = 0;
 MR>>>> }
 ??>>   А по-хорошему должно было бы быть что-то вроде (переменная pwm лежит
 ??>> в паре регистров r26,r27):
 DO> Глобальная переменная не может лечь в регистр.
  На gcc - очень даже может.
--------------------------
register unsigned char c asm("r7");
unsigned char d;
unsigned char foo(){ return (++c)+d;}
--------------------------
.global foo
 .type foo, @function
foo:
/* prologue: frame size=0 */
/* prologue end (size=0) */
 inc r7
 lds r24,d
 add r24,r7
 clr r25
/* epilogue: frame size=0 */
 ret
/* epilogue end (size=1) */
/* function foo size 5 (4) */
-------------------------
  Но кодогенерация просто безобразная, так как r25 можно было и не очищать.

With best regards, Sergey Belyakov.  E-mail: snipped-for-privacy@mail.ru



AVR C -- они все издеваются что ли?!.
Привет Michael!

10 Feb 05 21:06, Michael Ryazanov писал Alex Mogilnikov:

 MR>>> #include <inttypes.h>
 MR>>> volatile uint16_t pwm;
 MR>>> void f(void) {
 MR>>>    if (++pwm == 1023)
 MR>>>       pwm = 0;
 MR>>> }

 MR>    А по-хорошему должно было бы быть что-то вроде (переменная pwm
 MR> лежит в паре регистров r26,r27):

    ИМХО глабольный объект не может лежать в регистрах. Иначе как получить его
адрес?

Всего наилучшего,                                 [Team PCAD 2000]
Алексей М.
... Мы не можем ждать почты от аплинка. Взять ее у него - наша задача.

Re: AVR C -- они все издеваются что ли?!.
Hello Sergey.

11 Feb 05 13:40, you wrote to Dennis Opanasenko:

 DO>> Глобальная переменная не может лечь в регистр.
 SB>   Hа gcc - очень даже может.
 SB> --------------------------
 SB> register unsigned char c asm("r7");
 SB> unsigned char d;
 SB> unsigned char foo(){ return (++c)+d;}
 SB> --------------------------

Ага. Все бы хорошо, да только он эти регистры в прерывании сохраняет. А при
выходе восстанавливает. И весь смысл такого - теряется.


Alexey


Re: AVR C -- они все издеваются что ли?!.
Hello, Alexey!
You wrote to Sergey Belyakov on Fri, 11 Feb 2005 13:45:32 +0300:
 DO>>> Глобальная переменная не может лечь в регистр.
 SB>>   Hа gcc - очень даже может.
 SB>> --------------------------
 SB>> register unsigned char c asm("r7");
 SB>> unsigned char d;
 SB>> unsigned char foo(){ return (++c)+d;}
 SB>> --------------------------

 AB> Ага. Все бы хорошо, да только он эти регистры в прерывании сохраняет. А
 AB> при выходе восстанавливает. И весь смысл такого - теряется.
  Как тебе удалось этого добиться? У меня не получилось:).
=============================
void foo() __attribute__ ((signal));
register unsigned char c asm("r7");
unsigned char d;
void foo(){ ++c;++d;}
=============================
.global foo
 .type foo, @function
foo:
/* prologue: frame size=0 */
 push __zero_reg__
 push __tmp_reg__
 in __tmp_reg__,__SREG__
 push __tmp_reg__
 clr __zero_reg__
 push r24
/* prologue end (size=6) */
 inc r7
 lds r24,d
 subi r24,lo8(-(1))
 sts d,r24
/* epilogue: frame size=0 */
 pop r24
 pop __tmp_reg__
 out __SREG__,__tmp_reg__
 pop __tmp_reg__
 pop __zero_reg__
 reti
/* epilogue end (size=6) */
=============================
Однако пролог-эпилог абсолютно не оптимизирован. "Они" и правда издеваются.

With best regards, Sergey Belyakov.  E-mail: snipped-for-privacy@mail.ru



Re: AVR C -- они все издеваются что ли?!.
Quoted text here. Click to load it
Привет,

 MR> #include <inttypes.h>
 MR> volatile uint16_t pwm;
 MR> void f(void) {
 MR> if (++pwm == 1023)
 MR> pwm = 0;
 MR> }

 MR> А по-хорошему должно было бы быть что-то вроде (переменная pwm
 MR> лежит в паре регистров r26,r27):

 AM>     ИМХО глабольный объект не может лежать в регистрах. Иначе как получить
его
 AM> адрес?

        У пары регистров r26,r27 адрес, о чудо из чудес (а нафига он нужен,
кстати?) ровно 26. Это ведь про AVR разговоры?

--
Best regards, Alex Bakhtin, CCIE #8439
AMT Group, Cisco Systems Gold Partner, http://www.amt.ru

Re: AVR C -- они все издеваются что ли?!.
Привет Alex!

11 Feb 05 15:35, Alex Bakhtin писал Alex Mogilnikov:

 AM>>     ИМХО глабольный объект не может лежать в регистрах. Иначе как
 AM>> получить его адрес?

 AB>         У пары регистров r26,r27 адрес, о чудо из чудес (а нафига он
 AB> нужен, кстати?) ровно 26. Это ведь про AVR разговоры?

    Да, верно, адрес у него есть (об этом я забыл). Тем не менее операцию
взятия адреса у такой переменной выполнить не получается:

======= test.c ==========
register int x asm("r26");
int* f(void)
{
    return &x;
}
=========================

alx% avr-gcc -S -O test.c
test.c:2: warning: call-clobbered register used for global register variable
test.c:2: warning: call-clobbered register used for global register variable
test.c: In function `f':
test.c:6: error: address of global register variable `x' requested

    Мы ведь о gcc говорим?

Всего наилучшего,                                 [Team PCAD 2000]
Алексей М.
... О сколько нам открытий чудных готовит открывашки крюк!

Re: AVR C -- они все издеваются что ли?!.
Hello Sergey.

12 Feb 05 07:00, you wrote to me:

 AB>> Ага. Все бы хорошо, да только он эти регистры в прерывании
 AB>> сохраняет. А при выходе восстанавливает. И весь смысл такого -
 AB>> теряется.

 SB>   Как тебе удалось этого добиться?

Легко.

 SB> У меня не получилось:).

Может у тебя исправленная или похаканая версия. (сборки WinAvr отличаются от
официальных avr-gcc/avr-libc)

Alexey


AVR C -- они все издеваются что ли?!.
Привет Alexey!

12 Feb 05 17:01, Alexey Boyko писал Sergey Belyakov:

 AB>>> Ага. Все бы хорошо, да только он эти регистры в прерывании
 AB>>> сохраняет. А при выходе восстанавливает. И весь смысл такого -
 AB>>> теряется.
 SB>>   Как тебе удалось этого добиться?
 AB> Легко.
 SB>> У меня не получилось:).
 AB> Может у тебя исправленная или похаканая версия. (сборки WinAvr
 AB> отличаются от официальных avr-gcc/avr-libc)

    По моему опыту, для вызова обработчиков прерываний лучше делать
ассемблерные врапперы, где и сохранять нужные регистры. А то там еще проблема с
-ffixed-reg была...

Всего наилучшего,                                 [Team PCAD 2000]
Алексей М.
... Синяки рождаются в споре куда чаще, чем истина...

Site Timeline