реклама на сайте
подробности

 
 
10 страниц V  « < 2 3 4 5 6 > »   
Reply to this topicStart new topic
> Перенос кода из под ИАРа на WinAVR, возникают некоторые вопросы...
alx2
сообщение Nov 26 2008, 20:20
Сообщение #46


Местный
***

Группа: Участник
Сообщений: 340
Регистрация: 25-10-05
Из: Пермь, Россия
Пользователь №: 10 091



Цитата(sonycman @ Nov 26 2008, 15:17) *
Сейчас у меня вот такие опции:
Хм. Странно. Ничего подозрительного не вижу, и на простых примерах воспроизвести не могу. Не генерится у меня код для таких функций...


Цитата(Rst7 @ Nov 26 2008, 17:46) *
Да ну? Где Вы это вычитали? Сдвиг в Си для знаковых операндов всю жизнь был арифметический, с учетом знака.
Читаем первоисточник:
Цитата
The result of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has
an unsigned type or if E1 has a signed type and a nonnegative value, the value of the
result is the integral part of the quotient of E1 / 2^E2. If E1 has a signed type and a
negative value, the resulting value is implementation-defined.

Цитата
When integers are divided, the result of the / operator is the
algebraic quotient with any fractional part discarded. 87)
.....
87) This is often called ``truncation toward zero''.
Обрати внимание, что результат оператора / - не есть целая часть арифметического частного.
И в качестве упражнения тестовый пример:
Код
alx2% cat test.c
#include <stdio.h>
int main(void)
{
    int x = -5;
    return printf("%d, %d\n", x / 2, x >> 1);
}
alx2% gcc -O2 -o t test.c
alx2% ./t
-2, -3


Цитата(Rst7 @ Nov 26 2008, 17:46) *
А вот то, что гнусь не поставил команду ASR, а позвал деление - это непонятно.
Попробуй привести код со сдвигами, выполняющий деление значения типа int (уже находящегося в регистрах) на 2, который был бы не длиннее трех машинных инструкций (напоминаю, что sonycman просил оптимизировать по размеру кода).

Сообщение отредактировал alx2 - Nov 26 2008, 21:00


--------------------
Всего наилучшего,
Alex Mogilnikov
Go to the top of the page
 
+Quote Post
Rst7
сообщение Nov 26 2008, 20:45
Сообщение #47


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Цитата(alx2 @ Nov 26 2008, 22:20) *
-2, -3

Однако, сдвиг действительно арифметический. Более подробно посмотрю этот момент, когда попаду за комп, потому как с трубы лень искать. Возможно, я и не прав.

Цитата
Попробуй привести код со сдвигами, выполняющий деление значения типа int (уже находящегося в регистрах) на 2, который был бы не длиннее трех машинных инструкций (напоминаю, что sonycman просил оптимизировать по размеру кода).

Если уж быть точным, там тип signed char у sonycman, так что inc rx, asr rx вполне бы прошло.


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
alx2
сообщение Nov 26 2008, 21:35
Сообщение #48


Местный
***

Группа: Участник
Сообщений: 340
Регистрация: 25-10-05
Из: Пермь, Россия
Пользователь №: 10 091



Цитата(Rst7 @ Nov 27 2008, 01:45) *
Если уж быть точным, там тип signed char у sonycman, так что inc rx, asr rx вполне бы прошло.
Если быть совсем точным, smile.gif во-первых, sonycman, к сожалению, не привел деклараций переменных. Во-вторых, там на два делилась разность двух целых значений, которая уже в один байт не помещается. В-третьих, даже если бы не было разности, простого inc rx, asr rx недостаточно: оно дает неверные значения для нечетных положительных чисел. Например, 1/2 даст 1, тогда как должно быть 0. Как минимум, требуется еще sbrs rx,7 в начале, что дает все те же три инструкции...


--------------------
Всего наилучшего,
Alex Mogilnikov
Go to the top of the page
 
+Quote Post
Rst7
сообщение Nov 26 2008, 21:56
Сообщение #49


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Цитата(alx2 @ Nov 26 2008, 23:35) *
оно дает неверные значения для нечетных положительных чисел. Например, 1/2 даст 1, тогда как должно быть 0. Как минимум, требуется еще sbrs rx,7 в начале, что дает все те же три инструкции...

Да. Согласен. Чтото я погорячился.

Правда про signed char упомянуто. На предыдущей странице.


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
sonycman
сообщение Nov 26 2008, 22:02
Сообщение #50


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Цитата(Rst7 @ Nov 27 2008, 00:45) *
Однако, сдвиг действительно арифметический. Более подробно посмотрю этот момент, когда попаду за комп, потому как с трубы лень искать. Возможно, я и не прав.
Если уж быть точным, там тип signed char у sonycman, так что inc rx, asr rx вполне бы прошло.

Да, там у меня char:
Код
#define    LCD_WIDTH 96
byte  lcdGetStringWidth(PGM_P text);

void  lcdPrintText(PGM_P text, byte flags, signed char x, signed char y)
  switch(flags & 0xe0)
  {
  case  TXT_CENTERED:
    if (x < 0)
    {
      x = (LCD_WIDTH + x - lcdGetStringWidth(text)) / 2;
    }
...

Но смысла в нём мало - всё равно всё тупо "растягивается" до 16-ти бит crying.gif ... даже switch:
Код
{
  switch(flags & 0xe0)
     e3a:    70 e0           ldi    r23, 0x00; 0
     e3c:    60 7e           andi    r22, 0xE0; 224
     e3e:    70 70           andi    r23, 0x00; 0
     e40:    60 38           cpi    r22, 0x80; 128
     e42:    71 05           cpc    r23, r1
     e44:    21 f0           breq    .+8      ; 0xe4e <lcdPrintText(char const*, unsigned char, signed char, signed char)+0x26>
     e46:    60 3c           cpi    r22, 0xC0; 192
     e48:    71 05           cpc    r23, r1
     e4a:    11 f5           brne    .+68     ; 0xe90 <lcdPrintText(char const*, unsigned char, signed char, signed char)+0x68>
     e4c:    1d c0           rjmp    .+58     ; 0xe88 <lcdPrintText(char const*, unsigned char, signed char, signed char)+0x60>
     e4e:    c4 2f           mov    r28, r20
     e50:    dd 27           eor    r29, r29
     e52:    c7 fd           sbrc    r28, 7
     e54:    d0 95           com    r29
  {
  case  TXT_CENTERED:
    if (x < 0)
     e56:    47 ff           sbrs    r20, 7
     e58:    0c c0           rjmp    .+24     ; 0xe72 <lcdPrintText(char const*, unsigned char, signed char, signed char)+0x4a>
    {
      x = (LCD_WIDTH + x - lcdGetStringWidth(text)) / 2;
     e5a:    da df           rcall    .-76     ; 0xe10 <lcdGetStringWidth(char const*)>
     e5c:    c0 5a           subi    r28, 0xA0; 160
     e5e:    df 4f           sbci    r29, 0xFF; 255
     e60:    9e 01           movw    r18, r28
     e62:    28 1b           sub    r18, r24
     e64:    31 09           sbc    r19, r1
     e66:    c9 01           movw    r24, r18
     e68:    62 e0           ldi    r22, 0x02; 2
     e6a:    70 e0           ldi    r23, 0x00; 0
     e6c:    17 d5           rcall    .+2606   ; 0x189c <__divmodhi4>
     e6e:    16 2f           mov    r17, r22
     e70:    0f c0           rjmp    .+30     ; 0xe90 <lcdPrintText(char const*, unsigned char, signed char, signed char)+0x68>
    }

Одно хоть радует - при вызове функции есть хоть какая-то польза от восьмибитных параметров - их быстрее загружать smile.gif
А дальше всё равно бессмысленное "растягивание" до int... и впустую потраченное время и место во флэш.
Go to the top of the page
 
+Quote Post
aesok
сообщение Nov 27 2008, 04:14
Сообщение #51


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Цитата(sonycman @ Nov 27 2008, 01:02) *
Но смысла в нём мало - всё равно всё тупо "растягивается" до 16-ти бит crying.gif ... даже switch:



6.8.4.2 The switch statement
Constraints
1 The controlling expression of a switch statement shall have integer type.

Цитата(sonycman @ Nov 27 2008, 01:02) *
А дальше всё равно бессмысленное "растягивание" до int... и впустую потраченное время и место во флэш.



x = (unsigned char )(LCD_WIDTH + x - lcdGetStringWidth(text)) / 2

Код
  31 000a 4983              std Y+1,r20
  32                   .LVL1:
  33 000c 0E94 0000         call lcdGetStringWidth
  34                   .LVL2:
  35 0010 4981              ldd r20,Y+1
  36 0012 405A              subi r20,lo8(-(96))
  37                   .LVL3:
  38 0014 481B              sub r20,r24
  39 0016 4695              lsr r20
  40 0018 4093 0000         sts xx,r20



Анатолий.

Сообщение отредактировал aesok - Nov 27 2008, 04:15
Go to the top of the page
 
+Quote Post
Rst7
сообщение Nov 27 2008, 07:56
Сообщение #52


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Цитата(sonycman @ Nov 27 2008, 00:02) *
А дальше всё равно бессмысленное "растягивание" до int... и впустую потраченное время и место во флэш.

Вот именно. switch - хоть и int по стандарту, но если у него аргумент прямо в скобках &0xE0, то никаким стандартом не прикрыть недоточенность компилятора.


Аналогично есть вопросы к выражению. Все операнды и результат 8 бит, а в середине выражение вычисляется через 16 бит. Чтото не так.


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
msalov
сообщение Nov 27 2008, 08:51
Сообщение #53


Знающий
****

Группа: Свой
Сообщений: 526
Регистрация: 24-08-07
Из: Беларусь, Минск
Пользователь №: 30 045



Цитата(Rst7 @ Nov 27 2008, 09:56) *
Аналогично есть вопросы к выражению. Все операнды и результат 8 бит, а в середине выражение вычисляется через 16 бит. Чтото не так.
Это называется Integer promotion - приведение char к int в промежуточных вычислениях, прописано в стандарте.
Go to the top of the page
 
+Quote Post
Rst7
сообщение Nov 27 2008, 09:08
Сообщение #54


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Цитата(gotty @ Nov 27 2008, 10:51) *
Это называется Integer promotion - приведение char к int в промежуточных вычислениях, прописано в стандарте.

Ссылку. Чтото я совсем потерялся.


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
msalov
сообщение Nov 27 2008, 09:24
Сообщение #55


Знающий
****

Группа: Свой
Сообщений: 526
Регистрация: 24-08-07
Из: Беларусь, Минск
Пользователь №: 30 045



Цитата(Rst7 @ Nov 27 2008, 11:08) *
Ссылку. Чтото я совсем потерялся.


ISO/IEC 9899:1999

5.1.2.3 пункт 10
Цитата
EXAMPLE 2 In executing the fragment
Код
char c1, c2;
/* ...  */
c1 = c1 + c2;

the ‘‘integer promotions’’ require that the abstract machine promote the value of each variable to int size
and then add the two ints and truncate the sum. Provided the addition of two chars can be done without
overflow, or with overflow wrapping silently to produce the correct result, the actual execution need only
produce the same result, possibly omitting the promotions.


6.3.1.1 пункт 2
Цитата
If an int can represent all values of the original type, the value is converted to an int;
otherwise, it is converted to an unsigned int. These are called the integer
promotions.48) All other types are unchanged by the integer promotions.

48) The integer promotions are applied only: as part of the usual arithmetic conversions, to certain
argument expressions, to the operands of the unary +, -, and ~ operators, and to both operands of the
shift operators, as specified by their respective subclauses.
Go to the top of the page
 
+Quote Post
sonycman
сообщение Nov 27 2008, 09:28
Сообщение #56


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Цитата(gotty @ Nov 27 2008, 12:51) *
Это называется Integer promotion - приведение char к int в промежуточных вычислениях, прописано в стандарте.

Но неужели слепое следование стандартам больших машин - это абсолютно правильно и на AVR?
Неужели в вышеприведённом примере столь необходимо было следовать такому стандарту?

А может существует какая-то опция, позволяющая отключать эту фичу?
Go to the top of the page
 
+Quote Post
zltigo
сообщение Nov 27 2008, 09:45
Сообщение #57


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(sonycman @ Nov 27 2008, 12:28) *
Но неужели слепое следование стандартам больших машин - это абсолютно правильно и на AVR?

Следование стандартам ВСЕГДА правильно, а вот то, что int на восьмибитовике 1бит - вот это уже НЕ ПРАВИЛЬНОЕ (хотя не противоречащее стандарту) решение принятое когда-то производителями восьмибитовых компиляторов sad.gif, полагаю для тупой совместимости с массовыми на тот момент 16bit-овиками, дабы _бездумно_ sad.gif портировать исходники с 16bit интами. Если int действительно имел максимально естественую для 8bit контроллера разрядность 8bit, то и проблем c этитм не было-бы, как их нет не 16/32bit платформах.
Цитата
А может существует какая-то опция, позволяющая отключать эту фичу?

Гипотетически изменить размерность int в хидерах на 8bit и пресобрать все, включая библиотеки. Если авторы компилятора все делали правильно, то должно получиться. А вообще пора завязывать с 8bit smile.gif smile.gif smile.gif


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
sonycman
сообщение Nov 27 2008, 10:04
Сообщение #58


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Цитата(zltigo @ Nov 27 2008, 13:45) *
Следование стандартам ВСЕГДА правильно, а вот то, что int на восьмибитовике 1бит - вот это уже НЕ ПРАВИЛЬНОЕ (хотя не противоречащее стандарту) решение принятое когда-то производителями восьмибитовых компиляторов sad.gif, полагаю для тупой совместимости с массовыми на тот момент 16bit-овиками, дабы _бездумно_ sad.gif портировать исходники с 16bit интами. Если int действительно имел максимально естественую для 8bit контроллера разрядность 8bit, то и проблем c этитм не было-бы, как их нет не 16/32bit платформах.

Гипотетически изменить размерность int в хидерах на 8bit и пресобрать все, включая библиотеки. Если авторы компилятора все делали правильно, то должно получиться. А вообще пора завязывать с 8bit smile.gif smile.gif smile.gif

Понятно, спасибо smile.gif
Оставим это как дань стандартам и одновременно лень производителей smile.gif

Почти во всём при компиляции своего проекта уже разобрался.
Ещё вот беспокоят такие ворнинги:
Код
only initialized variables can be placed into program memory area

на стоки, подобные вот этим:
Код
if (statusRx.lock_err) usartSendString(PSTR("Receiver LOCKED!"));

const char PROGMEM fntable[]    = "!\"%`()*+,-./0123456789:;<=>?ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^";

то есть ругается на все PSTR() и на все PROGMEM.
Чего такого неправильного я там сделал? 07.gif
Go to the top of the page
 
+Quote Post
alx2
сообщение Nov 27 2008, 11:29
Сообщение #59


Местный
***

Группа: Участник
Сообщений: 340
Регистрация: 25-10-05
Из: Пермь, Россия
Пользователь №: 10 091



Цитата(sonycman @ Nov 27 2008, 03:02) *
Код
void  lcdPrintText(PGM_P text, byte flags, signed char x, signed char y)
  switch(flags & 0xe0)
  {
...

Но смысла в нём мало - всё равно всё тупо "растягивается" до 16-ти бит crying.gif ... даже switch:
Код
{
  switch(flags & 0xe0)
     e3a:    70 e0           ldi    r23, 0x00; 0
     e3c:    60 7e           andi    r22, 0xE0; 224
     e3e:    70 70           andi    r23, 0x00; 0
     e40:    60 38           cpi    r22, 0x80; 128
     e42:    71 05           cpc    r23, r1
Как ты получил такой код??? =8-( )
Вот такой тестовый пример:
Код
int do_something(void);

void fff(char flags)
{
    switch(flags & 0xe0)
    {
        case 0x80:
            do_something();
    }
}
у меня компилируется вот в такой код:
Код
fff:
/* prologue: function */
/* frame size = 0 */
        andi r24,lo8(-32)
        cpi r24,lo8(-128)
        brne .L4
        rcall do_something
.L4:
        ret
при любой -O отличной от -O0. gcc-4.3.1.
Скажи, пожалуйста, версию своего компилятора, с какой оптимизацией компилировался код и как определено byte.


--------------------
Всего наилучшего,
Alex Mogilnikov
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Nov 27 2008, 11:35
Сообщение #60


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(sonycman @ Nov 27 2008, 12:04) *
Понятно, спасибо smile.gif
Оставим это как дань стандартам и одновременно лень производителей smile.gif
Стандарт не запрещает оптимизатору не расширять char до int если результат останется одинаковым. Или расширить, но потом все лишнее выкинуть.

Цитата(sonycman @ Nov 27 2008, 12:04) *
то есть ругается на все PSTR() и на все PROGMEM.
Чего такого неправильного я там сделал? 07.gif
Это не вы, это они намудрили в компиляторе.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post

10 страниц V  « < 2 3 4 5 6 > » 
Reply to this topicStart new topic
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 22:09
Рейтинг@Mail.ru


Страница сгенерированна за 0.01541 секунд с 7
ELECTRONIX ©2004-2016