Răsfoiți Sursa

* x86: Shrink TEST instruction on MovAndTest2Test
where possible.

J. Gareth "Curious Kit" Moreton 3 ani în urmă
părinte
comite
aff2a42431
1 a modificat fișierele cu 53 adăugiri și 0 ștergeri
  1. 53 0
      compiler/x86/aoptx86.pas

+ 53 - 0
compiler/x86/aoptx86.pas

@@ -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;