SDCC баги

CALL'ы и RET'ы

Postby TS-Labs » Thu, 26.09.2013 04:48:37

Обрадовалася душа, что такой весь сабж хороший, давай думаю его наконец заюзаю. Не прошло и полчаса, как наступил на багу.

Code: Select all
char i;
void main(void)
{
   i = 0;
   while (1)
      i = (i == 3) ? 0 : (i + 1);
}


Свежайшая версия 3.3.0 компилирует вот в это:
Code: Select all
_main:
;1.c:9: i = 0;
   ld   hl,#_i + 0
   ld   (hl), #0x00
;1.c:11: while (1)
00102$:
;1.c:13: i = (i == 3) ? 0 : (i + 1);
   ld   a,(#_i + 0)
   cp   a,#0x03
   jr   Z,00107$
   inc   a
00107$:
   ld   (#_i + 0),a
   jr   00102$

Я думаю, комментировать не надо.

ИЧСХ, проверил на версии 2.9.0 (та, которая в шыру-СДК):
Code: Select all
_main:
;1.c:9: i = 0;
   ld   hl,#_i + 0
   ld   (hl), #0x00
;1.c:11: while (1)
00102$:
;1.c:13: i = (i == 3) ? 0 : (i + 1);
   ld   a,(#_i+0)
   sub   a,#0x03
   jr   NZ,00106$
   ld   c,#0x00
   jr   00107$
00106$:
   ld   hl,#_i + 0
   ld   c,(hl)
   inc   c
00107$:
   ld   hl,#_i + 0
   ld   (hl), c
   jr   00102$

Предлагается найти 100500 отличий.

Cвежая версия делает намного более вменяемый код. Но пропустить ТАКУЮ багу...
Ладно бы код был какой экзотичный. И что интересно: если написать например:
Code: Select all
i = (i == 3) ? 1 : (i + 1);

то получится уже вот так:
Code: Select all
   ld   a,(#_i + 0)
   sub   a, #0x03 ; <-- !!!!!!!!!!!!!!!!!
   jr   NZ,00106$
   ld   a,#0x01
   jr   00107$
00106$:
   ld   a,(#_i + 0)
   inc   a
00107$:
   ld   (#_i + 0),a


Перепутали CP и SUB, бида бида...
User avatar
TS-Labs
 
Posts: 5398
Joined: Thu, 26.07.2012 01:29:56

Postby TS-Labs » Thu, 26.09.2013 04:58:11

Проверил: присутствует в версиях 3.2.0 и 3.1.0 Нету в версии 3.0.0, но она генерит такую же капусту, как и 2.9.0.
User avatar
TS-Labs
 
Posts: 5398
Joined: Thu, 26.07.2012 01:29:56

Postby TS-Labs » Thu, 26.09.2013 07:05:43

О, ответили:
It looks like a peephole rule problem. When compiled with --no-peep the resulting assembly looks correct to me.
Действительно, опция --no-peep генерит:
Code: Select all
   ld   iy,#_i
   ld   a,0 (iy)
   sub   a, #0x03
   jp   NZ,00108$
   jp   00109$
00108$:
   jp   00103$
00109$:
   ld   a,#0x00
   jp   00104$
00103$:
   ld   iy,#_i
   ld   a,0 (iy)
   inc   a
00104$:
   ld   iy,#_i
   ld   0 (iy),a


Ну, то есть peephole не работает, и старая лапша.
User avatar
TS-Labs
 
Posts: 5398
Joined: Thu, 26.07.2012 01:29:56

Postby Sergey78 » Thu, 26.09.2013 12:40:12

Code: Select all
void foo(int a, int b)
{
    if(a>b) while(1);   
}

Если a=-17000, b=17000, то if неправильно сработает (SDCC 2.9).
Компилятор делает вот такое:
Code: Select all
 ;main.c:752: if (a>b)
     ld   a,4 (ix)
     sub   a,6 (ix)
     ld   a,5 (ix)
     sbc   a,7 (ix)
     jp   P,00151$
 ;main.c:755: while(1)
 00102$:
     jr   00102$
 00151$:
Last edited by Sergey78 on Thu, 26.09.2013 20:41:53, edited 1 time in total.
Sergey78
 
Posts: 422
Joined: Wed, 05.09.2012 20:04:40

Postby TS-Labs » Thu, 26.09.2013 20:36:58

Ясно. Выглядит что моя первая оценка "фтопку" (2 года назад) была верна.
User avatar
TS-Labs
 
Posts: 5398
Joined: Thu, 26.07.2012 01:29:56

Postby Sergey78 » Thu, 26.09.2013 20:44:11

Выбирать особо не из чего. Кучи кросскомпиляторов для z80 не наблюдается.
Sergey78
 
Posts: 422
Joined: Wed, 05.09.2012 20:04:40

Postby TS-Labs » Thu, 26.09.2013 21:45:48

В ИАРе тоже баги находил...
User avatar
TS-Labs
 
Posts: 5398
Joined: Thu, 26.07.2012 01:29:56

Postby Sergey78 » Mon, 28.10.2013 10:02:07

Вот на такой код:
Code: Select all
static u8 *curmapptr;

 ...
    curmapptr+=2;

SDCC делает вот такое:
Code: Select all
00194$:
;map.h:684: ERROR: no line number 684 in file map.h
   ld   hl,#_draw_map_curmapptr_1_1
   ld   a,(hl)
   add   a,#0x02
   inc   hl
   dec   hl
   push   bc
   ld   c, a
   inc   hl
   ld   a, (hl)
   ld   b, a
   ld   a, c
   dec   hl
   ld   (hl), a
   ld   a, b
   pop   bc
   adc   a,#0x00
   inc   hl
   ld   (hl),a

:crazy:
Sergey78
 
Posts: 422
Joined: Wed, 05.09.2012 20:04:40

Postby TS-Labs » Mon, 28.10.2013 10:59:31

Прэлесть.
User avatar
TS-Labs
 
Posts: 5398
Joined: Thu, 26.07.2012 01:29:56

Postby g0blinish » Mon, 28.10.2013 11:14:51

Напейшите ужи сами, чо..
[x] No Screenshot
User avatar
g0blinish
Упырь говнофорума
 
Posts: 3641
Joined: Tue, 18.06.2013 10:59:01

Postby NovaSTorm » Mon, 28.10.2013 11:51:58

Sergey78 wrote:add a,#0x02

Ничто не предвещало беды =)
А можно кусочек побольше и опции сборки, может в этом есть какой-то тайный смысл?
NovaSTorm
 
Posts: 75
Joined: Sat, 22.06.2013 19:33:40

Postby Sergey78 » Mon, 28.10.2013 15:52:10

NovaSTorm wrote:А можно кусочек побольше

Code: Select all
   curmapptr = &curmap_tiles[1][1];
   for(a=2;a<38;a+=2)
   {
      for(b=2;b<22;b+=2)
      {
         if(*curmapptr)
            draw_stile(a,b,*curmapptr+prespath+1024);
         curmapptr++;
      }
      curmapptr+=2;
   }

Обычный цикл, указатель нигде больше не используется. Это какой-то извратный кодогенератор.
Sergey78
 
Posts: 422
Joined: Wed, 05.09.2012 20:04:40

Postby NovaSTorm » Mon, 28.10.2013 19:17:00

Я конечно не дока в сях, но разве
Code: Select all
draw_stile(a,b,*curmapptr+prespath+1024);

не должно выглядеть как
Code: Select all
draw_stile(a,b,*(curmapptr+prespath+1024));

?
А то, получается, мы к байту 1024 прибавляем, на том компилятор с ума и сходит, так?
NovaSTorm
 
Posts: 75
Joined: Sat, 22.06.2013 19:33:40

Postby Sergey78 » Mon, 28.10.2013 20:24:23

Там все правильно. Компилятор u8 к u16 приведет.
Sergey78
 
Posts: 422
Joined: Wed, 05.09.2012 20:04:40

Postby NovaSTorm » Mon, 28.10.2013 20:32:52

Ну вот эти танцы с inc/dec hl и adc как раз и похожи на 16-битную арифметику.
NovaSTorm
 
Posts: 75
Joined: Sat, 22.06.2013 19:33:40

Postby NovaSTorm » Mon, 28.10.2013 20:43:22

Кстати, а что будет если поставить явный каст?
NovaSTorm
 
Posts: 75
Joined: Sat, 22.06.2013 19:33:40

Postby Sergey78 » Mon, 28.10.2013 21:01:56

С draw_stile все в порядке. Кривой код генерится для строчки
Code: Select all
    curmapptr+=2

если указатель объявлен как глобальный или статик. Если сделать просто локальный указатель получается такое:
Code: Select all
00120$:
;map.h:766: ERROR: no line number 766 in file map.h
   ld   bc,#_curmap_tiles + 12+1
;map.h:767: ERROR: no line number 767 in file map.h
   ld   -1 (ix),#0x02
00195$:
   ld   a,-1 (ix)
   sub   a,#0x26
   jp   NC,00198$
;map.h:769: ERROR: no line number 769 in file map.h
   ld   -28 (ix),c
   ld   -27 (ix),b
   ld   c,#0x02
00191$:
   ld   a,c
   sub   a,#0x16
   jr   NC,00194$
;map.h:771: ERROR: no line number 771 in file map.h
   ld   l,-28 (ix)
   ld   h,-27 (ix)
   ld   e,(hl)
   xor   a,a
   or   a,e
   jr   Z,00122$
;map.h:772: ERROR: no line number 772 in file map.h
   ld   d,#0x00
   ld   hl,#_prespath
   ld   a,e
   add   a,(hl)
   ld   e,a
   ld   a,d
   inc   hl
   adc   a,(hl)
   ld   d,a
   ld   hl,#0x0400
   add   hl,de
   push   bc
   push   hl
   ld   a,c
   push   af
   inc   sp
   ld   a,-1 (ix)
   push   af
   inc   sp
   call   _draw_stile
   pop   af
   pop   af
   pop   bc
00122$:
;map.h:773: ERROR: no line number 773 in file map.h
   inc   -28 (ix)
   jr   NZ,00291$
   inc   -27 (ix)
00291$:
;map.h:769: ERROR: no line number 769 in file map.h
   inc   c
   inc   c
   jr   00191$
00194$:
;map.h:775: ERROR: no line number 775 in file map.h
   ld   c,-28 (ix)
   ld   b,-27 (ix)
   inc   bc
   inc   bc
;map.h:767: ERROR: no line number 767 in file map.h
   inc   -1 (ix)
   inc   -1 (ix)
   jp   00195$
00198$:

здесь компилятор сообразил сделать inc bc: inc bc.
Sergey78
 
Posts: 422
Joined: Wed, 05.09.2012 20:04:40

Postby TS-Labs » Mon, 28.10.2013 21:47:34

NovaSTorm wrote:draw_stile(a,b,*curmapptr+prespath+1024);

[curmapptr]+prespath+1024
NovaSTorm wrote:draw_stile(a,b,*(curmapptr+prespath+1024));

[curmapptr+prespath+1024]
Народ, я один не умею пойнтерами в сях пользоваться?..
Энивей, ахтунги какие то, я не знаю, во что оно соберет, но я бы так ТОЧНО не писал.
User avatar
TS-Labs
 
Posts: 5398
Joined: Thu, 26.07.2012 01:29:56

Postby NovaSTorm » Mon, 28.10.2013 22:01:29

TS-Labs wrote:я один не умею пойнтерами в сях пользоваться?

Всякое бывает, такую разницу я и имел в виду. Я ж не могу всю логику по этому куску восстановить. Мне показалось сначала, что берётся номер тайла, а тут видимо добавлением 1024 он получается сдвинутым или ещё как-то переделанным в дальнейшей табличке?
NovaSTorm
 
Posts: 75
Joined: Sat, 22.06.2013 19:33:40

Postby TS-Labs » Mon, 28.10.2013 22:07:19

1 кейз: читается ЧТО-ТО с адреса curmapptr, к нему прибавляется prespath+1024, что получилось и передается аргом в функцию.
2 кейз: берется значение curmapptr, к нему прибавляется prespath+1024, по полученному адресу опять читается ХУЙ ЗНАЕТ ЧТО (непонятно байт, слово, лонг) и передается аргом в функцию.
Я допускаю, что упускаю какие-то неявные возможные преобразования, но скорее всего нет.
User avatar
TS-Labs
 
Posts: 5398
Joined: Thu, 26.07.2012 01:29:56

Postby Sergey78 » Tue, 29.10.2013 09:37:32

TS-Labs wrote:по полученному адресу опять читается ХУЙ ЗНАЕТ ЧТО (непонятно байт, слово, лонг)

Читается байт, так как curmapptr указатель на u8.
Sergey78
 
Posts: 422
Joined: Wed, 05.09.2012 20:04:40

Postby amixgris » Thu, 31.10.2013 18:06:20

Sergey78 wrote:Вот на такой код:

Код: Выделить всё
static u8 *curmapptr;

...
curmapptr+=2;


SDCC делает вот такое:


В порядке обсуждения:
1. какая версия sdcc пользуется? - не удалось повторить у себя.
Code: Select all
static unsigned char *map_aptr;

void main(void)
{
   map_aptr+=2;
}

преобразовано в
Code: Select all
_main_start::
_main:
;test78s.c:7: map_aptr+=2;
   ld   hl,#_map_aptr
   ld   a,(hl)
   add   a, #0x02
   ld   (hl),a
   inc   hl
   ld   a,(hl)
   adc   a, #0x00
   ld   (hl),a
   ret
_main_end::

2. Сергей, ты не пробовал избавиться от ошибок, что в заголовочном файле строки не найдены?
Оно, вроде бы, на первый взгляд совсем не связано с проблемой, однако хз, как компилятор внутри такие ошибки обрабатывает. Косвенно может влиять на кодогенератор.
Я сам придерживаюсь правила, что, если компилятор хоть какую ошибку выдал в процессе, то результат компиляции должен быть аннулирован.
User avatar
amixgris
 
Posts: 161
Joined: Mon, 30.07.2012 03:22:48
LOCATION: Самара

Postby Sergey78 » Thu, 31.10.2013 21:08:09

amixgris wrote:какая версия sdcc пользуется? - не удалось повторить у себя.

2.9.0, тот что в EVOSDK.
amixgris wrote:не пробовал избавиться от ошибок, что в заголовочном файле строки не найдены?

При компиляции ошибок не выдает, это только в листинге строчку из исходника не пишет. Это игра "Project ROBO", можешь сам посмотреть.
amixgris wrote:преобразовано в

Уже получше. Хотя можно было сделать так:
Code: Select all
    ld hl,(_ptr)
    inc hl
    inc hl
    ld (_ptr),hl
Sergey78
 
Posts: 422
Joined: Wed, 05.09.2012 20:04:40

Postby amixgris » Thu, 31.10.2013 23:05:07

Sergey78 wrote:2.9.0, тот что в EVOSDK.

Нет желания на последнюю версию SDCC перевести?

Sergey78 wrote:Это игра "Project ROBO", можешь сам посмотреть.

А что, не работает после компиляции, разве?
Я эту игру себе уже давно скомпилил (как только ты SDK под конфу адаптировал). Работает, вроде. Правда всю не проходил. Но глюков не замечал.
На всякий случай приложу SPG.
Attachments
ROBO.SPG
(428 KiB) Downloaded 422 times
User avatar
amixgris
 
Posts: 161
Joined: Mon, 30.07.2012 03:22:48
LOCATION: Самара

Postby amixgris » Fri, 01.11.2013 12:25:23

Sergey78 wrote:2.9.0, тот что в EVOSDK.

Сергей, а на той версии, что я выложил в соседней ветке, как компилится проблемный кусок?
User avatar
amixgris
 
Posts: 161
Joined: Mon, 30.07.2012 03:22:48
LOCATION: Самара

Next

Return to Coding

Who is online

Users browsing this forum: No registered users and 1 guest

x