* x86: Shrink TEST instruction on MovAndTest2Test

where possible.
This commit is contained in:
J. Gareth "Curious Kit" Moreton 2022-06-30 12:12:46 +01:00 committed by FPK
parent d7f1e56191
commit aff2a42431

View File

@ -3108,6 +3108,59 @@ unit aoptx86;
DebugMsg(SPeepholeOptimization + 'MovAndTest2Test done',p);
taicpu(hp1).loadoper(1,taicpu(p).oper[0]^);
taicpu(hp1).opcode:=A_TEST;
{ Shrink the TEST instruction down to the smallest possible size }
case taicpu(hp1).oper[0]^.val of
0..255:
if (taicpu(hp1).opsize <> S_B)
{$ifndef x86_64}
and (
(taicpu(hp1).oper[1]^.typ <> top_reg) or
{ Cannot encode byte-sized ESI, EDI, EBP or ESP under i386 }
(GetSupReg(taicpu(hp1).oper[1]^.reg) in [RS_EAX, RS_EBX, RS_ECX, RS_EDX])
)
{$endif x86_64}
then
begin
if taicpu(hp1).opsize <> taicpu(hp2).opsize then
{ Only print debug message if the TEST instruction
is a different size before and after }
DebugMsg(SPeepholeOptimization + 'test' + debug_opsize2str(taicpu(hp1).opsize) + ' -> testb to reduce instruction size (Test2Test 1a)' , p);
taicpu(hp1).opsize := S_B;
if (taicpu(hp1).oper[1]^.typ = top_reg) then
setsubreg(taicpu(hp1).oper[1]^.reg, R_SUBL);
end;
256..65535:
if (taicpu(hp1).opsize <> S_W) then
begin
if taicpu(hp1).opsize <> taicpu(hp2).opsize then
{ Only print debug message if the TEST instruction
is a different size before and after }
DebugMsg(SPeepholeOptimization + 'test' + debug_opsize2str(taicpu(hp1).opsize) + ' -> testw to reduce instruction size (Test2Test 1b)' , p);
taicpu(hp1).opsize := S_W;
if (taicpu(hp1).oper[1]^.typ = top_reg) then
setsubreg(taicpu(hp1).oper[1]^.reg, R_SUBW);
end;
{$ifdef x86_64}
65536..$7FFFFFFF:
if (taicpu(hp1).opsize <> S_L) then
begin
if taicpu(hp1).opsize <> taicpu(hp2).opsize then
{ Only print debug message if the TEST instruction
is a different size before and after }
DebugMsg(SPeepholeOptimization + 'test' + debug_opsize2str(taicpu(hp1).opsize) + ' -> testl to reduce instruction size (Test2Test 1c)' , p);
taicpu(hp1).opsize := S_L;
if (taicpu(hp1).oper[1]^.typ = top_reg) then
setsubreg(taicpu(hp1).oper[1]^.reg, R_SUBD);
end;
{$endif x86_64}
else
;
end;
RemoveInstruction(hp2);
RemoveCurrentP(p, hp1);
Result:=true;