Page 1 of 2

Маленький баг в macros.inc

Posted: Fri Jan 16, 2015 6:50 pm
by Anton_K
Наткнулся на небольшой баг в стандартном наборе макросов programs/macros.inc. Сейчас данный баг никак не проявляется, но может проявиться в будущем.

В macros.inc есть макросы cmovz/cmovnz/cmovg/cmovl, которые "эмулируют" одноименные ассемблерные инструкции на процессорах, которые эти инструкции не поддерживают. Вот, собственно, код:
Spoiler:

Code: Select all

if __CPU_type eq p5             ; CMOVcc isnt supported on the P5

cmove   fix     cmovz
macro cmovz reg1, reg2 {

local   .jumpaddr

        jnz     .jumpaddr
        mov     reg1, reg2
       .jumpaddr:
}

cmovne  fix     cmovnz
macro cmovnz reg1, reg2 {

local   .jumpaddr

        jz      .jumpaddr
        mov     reg1, reg2
       .jumpaddr:
}

macro cmovg reg1, reg2 {

local   .jumpaddr

        jle     .jumpaddr
        mov     reg1, reg2
       .jumpaddr:
}

macro cmovl reg1, reg2 {

local   .jumpaddr

        jge     .jumpaddr
        mov     reg1, reg2
       .jumpaddr:
}

end if
Как мы видим, эти макросы заключены в инструкцию условной компиляции if/end if. То есть по задумке автора, эти макросы должны "включаться" только если Колибри собирается под архитектуру p5 (условие __CPU_type eq p5). Проблемма в том, что инструкция if/end if не влияет на макросы, поэтому эти макросы будут всегда определены (даже когда __CPU_type не p5). Так что при компиляции под процессоры, поддерживающие эти инструкции, все равно будет использоваться "эмуляция".

Следует заменить if/end if на инструкцию условного препроцессинга match, или же вставить if/end if в тело каждого макроса.

Re: Маленький баг в macros.inc

Posted: Sat Jan 17, 2015 3:06 am
by art_zh
Anton_K
Да, компилятор видит макросы, определенные внутри if-блоков, ну и что?
Фишка-то в том, что в if-блоке будет определена замена

Code: Select all

cmove   fix     cmovz
а значит код будет компилироваться и подставляться вместо cmove только для __cpu_type = P5.
Это не баг, это очень хороший стиль.

Re: Маленький баг в macros.inc

Posted: Sat Jan 17, 2015 3:35 am
by Anton_K
art_zh wrote:Anton_K
Да, компилятор видит макросы, определенные внутри if-блоков, ну и что?
Фишка-то в том, что в if-блоке будет определена замена

Code: Select all

cmove   fix     cmovz
а значит код будет компилироваться и подставляться вместо cmove только для __cpu_type = P5.
Это не баг, это очень хороший стиль.
Извини, но твой пост вызывает у меня неоднозначную реакцию, которую можно примерно описать таким набором смайлов: :shock: :? :o
Может, конечно, это я дурак, но какая разница, что там есть альтернативные названия команд, определенные через fix, ведь эти альтернативные названия есть и у соответствующих ассемблерных инструкций:

Image
(вырезка из мануала Intel, опкоды совпадают)

То есть в программах использование cmove и cmovz абсолютно равнозначно, это во-первых. А во-вторых, может я чего-то не знаю или путаю, но инструкция if/end if абсолютно никак не влияет на инструкцию fix (в FASM, по крайней мере), то есть следующий тестовый код ВСЕГДА определяет и делает доступной для использования "NULL", вне зависимости от значения __CPU_type:

Code: Select all

if __CPU_type eq p5 
    NULL fix 0
end if
Повторюсь, что возможно я ошибаюсь или что-то неправильно понял, но на данный момент я достаточно уверен, что прав. Может быть завтра даже проведу следственный эксперимент (сегодня уже поздно), если в этом еще будет необходимость.

Re: Маленький баг в macros.inc

Posted: Sat Jan 17, 2015 12:54 pm
by hidnplayr
It may be that 'fix' does not depend on 'if'/'end if'. Frankly, I dont know.
Either way, it does not matter, because I'm sure that the macros DO react to 'if' and thus will only be included when __CPU_type is p5.

I also know that 'cmove' and 'cmovz' are in effect the same instruction.
So substituting one for another does not harm and will result in the same binary output.

PS: I will look it up now.
EDIT: it seems I was wrong, read below.

Re: Маленький баг в macros.inc

Posted: Sat Jan 17, 2015 4:27 pm
by yogev_ezra
hidnplayr wrote:PS: I will look it up now.
I have checked the FlatAssembler Programmer's Manual now, and it looks like Anton_K is indeed right: macros are substituted during preprocessor stage, and that is before "if-end if" are processed:
All preprocessor directives are processed before the main assembly process, and therefore are not affected by the control directives. At this time also all comments are stripped out.
That means that all cmove instructions in /programs folder will be replaced by macros always, regardless of __CPU_type constant value.

Re: Маленький баг в macros.inc

Posted: Sat Jan 17, 2015 5:45 pm
by hidnplayr
Oh crap, you are right...
Since you guys seem to know this assembler better then me, maybe you guys know a fix as wel? :)

Re: Маленький баг в macros.inc

Posted: Sat Jan 17, 2015 5:48 pm
by hidnplayr
You guys see any problem with this construction?

Code: Select all

cmove   fix     cmovz
macro cmovz reg1, reg2 {

        if  __CPU_type eq p5             ; CMOVcc isnt supported on the P5

local   .jumpaddr

        jnz     .jumpaddr
        mov     reg1, reg2
       .jumpaddr:

        else

        cmovz   reg1, reg2

        end if
}  

Re: Маленький баг в macros.inc

Posted: Sat Jan 17, 2015 6:20 pm
by yogev_ezra
hidnplayr wrote:Oh crap, you are right...
Since you guys seem to know this assembler better then me, maybe you guys know a fix as wel? :)
You know much more than me - don't underestimate yourself :wink: I just checked the manual :roll:
hidnplayr wrote:You guys see any problem with this construction?
This way seems correct (at least according to the manual).

Re: Маленький баг в macros.inc

Posted: Sat Jan 17, 2015 7:13 pm
by Anton_K
hidnplayr wrote:You guys see any problem with this construction?

Code: Select all

cmove   fix     cmovz
macro cmovz reg1, reg2 {

        if  __CPU_type eq p5             ; CMOVcc isnt supported on the P5

local   .jumpaddr

        jnz     .jumpaddr
        mov     reg1, reg2
       .jumpaddr:

        else

        cmovz   reg1, reg2

        end if
}  
This code looks correct.

Re: Маленький баг в macros.inc

Posted: Sat Jan 17, 2015 7:43 pm
by art_zh
Guys,

I'm afraid you don't understand how this stuff works and what is it all for.

Please don't break anything unless you're absolutely sure what you are doing.

Re: Маленький баг в macros.inc

Posted: Sat Jan 17, 2015 7:51 pm
by hidnplayr
art_zh: Please re-read the whole discussion objectively, and when in doubt, test in fasm ;)

PS: I wrote these macros initially.

Re: Маленький баг в macros.inc

Posted: Sun Jan 18, 2015 9:26 pm
by hidnplayr
Fixed in #5384

Re: Маленький баг в macros.inc

Posted: Sun Jan 18, 2015 9:43 pm
by Anton_K
hidnplayr wrote:Fixed in #5383
Why "..jumpaddr:"? This labels should be marked as local with "local" directive. For now they are global (".." marks global labels) and macros can be used only once because of name collision of the label.

Re: Маленький баг в macros.inc

Posted: Sun Jan 18, 2015 9:45 pm
by e-andrew
".." генерирует метку с уникальным именем.

Re: Маленький баг в macros.inc

Posted: Sun Jan 18, 2015 9:49 pm
by Anton_K
e-andrew wrote:".." генерирует метку с уникальным именем.
Разве? Что-то я не припомню такого...