Proposal: Extended setcc

Proposal: Extended setcc

Let me propose an extension to the command setcc.
Often we need booleans not as bytes with the values 0 and 1...
By utilizing the 3 currently unused bits I propose the following meaning:

Bit #2: 0=byte, 1=dword
Bit #0 and #1:
00: false => 0, true => 1 // classical case as in C or Pascal
01: false => 0, true => -1 // for e.g. bit masks
10: false => -1, true => 1 // Sign
11: false => 0, true => no change // keep or zero out

As an exception for the combination 111 and as the target register esp only the carry flag should be set accordingly.

Needless to say that the usual prefixes for word and qword should work as well.

An encoding as 0f 9x /y would be OK if the superfluous bits (reg field) are assumed 0, but they have not (yet?) been documented as reserved...
An encoding without this problem could therefore be this: f2 0f 9x /y.

3 帖子 / 0 全新
最新文章
如需更全面地了解编译器优化,请参阅优化注意事项

Could you show the C code (or other high level code) for which this would be useful? I've got the impression that cases where this might be used actually have other instruction sequences which are already optimal.

I give some more or less silly and untested examples, however I'm not yet sure about the concrete syntax for the new forms.

There are a lot of cases where a programmer defines a boolean type e.g. as int:
typedef int bool;
In this case the statement "bool b = (x==17)" can be expressed by
cmp [x],17
sete dword ptr [b] // the form false=>0, true=>1; dword
as a replacement for
cmp [x],17
sete al
movzx eax,al
mov dword ptr [b],eax
The Windows API typically uses these booleans named BOOL.

The sgn function:
int sgn(int x)
{
if (x<0)
return -1;
else if (x>0)
return 1;
else
return 0;
}
can be written as
test eax,eax
setg eax,sign // the form false=>-1, true=>-1; dword
setnz eax,zero // the form false=>0, true=>unchanged; dword
as a replacement for
cdq
neg eax
shr eax,31
or eax,edx

The Visual Basic boolean data type as well as Delphi's longbool/wordbool/bytebool defines false as 0 and true as -1. These boolean values can simply generated with e.g.
cmp...
setcc eax,mask // the form false=>0, true=>-1; dword
as a replacement for
cmp...
setcc al
movzx eax,al
neg eax

If the value must be written to memory:
cmp...
setcc dword ptr [x],mask // the form false=>0, true=>-1; dword
as a replacement for
cmp...

setcc al
movzx eax,al
neg eax
mov dword ptr [x],eax

The fragment
q = (q << 1)+(x>17);
can be written as
cmp [x],17
setg // the form where only the carry flag is set
adc eax,eax // assuming that q is in register eax
or
cmp [x],17
setg edx // the form false=>0, true=>1; dword
lea eax,[eax*2+edx] // assuming that q is in register eax
as a replacement for
cmp [x],17

setg dl
movzx edx,dl
lea eax,[eax*2+edx] // assuming that q is in register eax

发表评论

登录添加评论。还不是成员?立即加入