Browse Source

+ added knowledge to the compiler for the x86 instructions, that don't read
their input registers, in case both parameters are the same register (e.g.
xor eax, eax; sub eax, eax; etc.)

git-svn-id: trunk@35861 -

nickysn 8 years ago
parent
commit
869f395a31

+ 8 - 4
compiler/i386/aoptcpu.pas

@@ -233,22 +233,26 @@ unit aoptcpu;
                         exit
                       end;
                 end;
-                if ([CH_RWOP1,CH_ROP1,CH_MOP1]*Ch<>[]) and reginop(reg,p.oper[0]^) then
+                if ([Ch_RFlags,Ch_RWFlags]*Ch<>[]) and (reg=NR_DEFAULTFLAGS) then
                   begin
                     RegReadByInstruction := true;
                     exit
                   end;
-                if ([Ch_RWOP2,Ch_ROP2,Ch_MOP2]*Ch<>[]) and reginop(reg,p.oper[1]^) then
+                if (Ch_NoReadIfEqualRegs in Ch) and (p.ops=2) and
+                   (p.oper[0]^.typ=top_reg) and (p.oper[1]^.typ=top_reg) and
+                   (p.oper[0]^.reg=p.oper[1]^.reg) then
+                  exit;
+                if ([CH_RWOP1,CH_ROP1,CH_MOP1]*Ch<>[]) and reginop(reg,p.oper[0]^) then
                   begin
                     RegReadByInstruction := true;
                     exit
                   end;
-                if ([Ch_RWOP3,Ch_ROP3,Ch_MOP3]*Ch<>[]) and reginop(reg,p.oper[2]^) then
+                if ([Ch_RWOP2,Ch_ROP2,Ch_MOP2]*Ch<>[]) and reginop(reg,p.oper[1]^) then
                   begin
                     RegReadByInstruction := true;
                     exit
                   end;
-                if ([Ch_RFlags,Ch_RWFlags]*Ch<>[]) and (reg=NR_DEFAULTFLAGS) then
+                if ([Ch_RWOP3,Ch_ROP3,Ch_MOP3]*Ch<>[]) and reginop(reg,p.oper[2]^) then
                   begin
                     RegReadByInstruction := true;
                     exit

+ 6 - 6
compiler/i386/i386prop.inc

@@ -25,7 +25,7 @@
 (Ch: [Ch_WFlags]),
 (Ch: []),
 (Ch: [Ch_RWFlags]),
-(Ch: [Ch_ROp1, Ch_ROp2, Ch_WFlags]),
+(Ch: [Ch_ROp1, Ch_ROp2, Ch_WFlags, Ch_NoReadIfEqualRegs]),
 (Ch: [Ch_All, Ch_WFlags, Ch_RDirFlag]),
 (Ch: [Ch_All, Ch_WFlags, Ch_RDirFlag]),
 (Ch: [Ch_All, Ch_WFlags, Ch_RDirFlag]),
@@ -193,7 +193,7 @@
 (Ch: [Ch_Wop2, Ch_ROP1]),
 (Ch: []),
 (Ch: []),
-(Ch: [Ch_Wop2, Ch_Rop1]),
+(Ch: [Ch_Wop2, Ch_Rop1, Ch_NoReadIfEqualRegs]),
 (Ch: [Ch_Rop1, Ch_Wop2]),
 (Ch: [Ch_Rop1, Ch_Wop2]),
 (Ch: [Ch_All, Ch_RDirFlag]),
@@ -326,7 +326,7 @@
 (Ch: [Ch_Mop2, Ch_Rop1, Ch_WFlags]),
 (Ch: [Ch_WEAX, Ch_RFLAGS]),
 (Ch: [Ch_Mop2, Ch_Rop1, Ch_WFlags]),
-(Ch: [Ch_Mop2, Ch_Rop1, Ch_RWFlags]),
+(Ch: [Ch_Mop2, Ch_Rop1, Ch_RWFlags, Ch_NoReadIfEqualRegs]),
 (Ch: [Ch_All, Ch_WFlags, Ch_RDirFlag]),
 (Ch: [Ch_All, Ch_WFlags, Ch_RDirFlag]),
 (Ch: [Ch_All, Ch_WFlags, Ch_RDirFlag]),
@@ -354,7 +354,7 @@
 (Ch: [Ch_REAX, Ch_WMemEDI, Ch_RWEDI, Ch_RDirFlag]),
 (Ch: [Ch_REAX, Ch_WMemEDI, Ch_RWEDI, Ch_RDirFlag]),
 (Ch: [Ch_Wop1]),
-(Ch: [Ch_Mop2, Ch_Rop1, Ch_WFlags]),
+(Ch: [Ch_Mop2, Ch_Rop1, Ch_WFlags, Ch_NoReadIfEqualRegs]),
 (Ch: [Ch_All]),
 (Ch: [Ch_All]),
 (Ch: [Ch_All]),
@@ -374,10 +374,10 @@
 (Ch: [Ch_All]),
 (Ch: [Ch_All]),
 (Ch: [Ch_All]),
-(Ch: [Ch_RWop1, Ch_RWop2]),
+(Ch: [Ch_RWop1, Ch_RWop2, Ch_NoReadIfEqualRegs]),
 (Ch: [Ch_WEAX, Ch_REBX]),
 (Ch: [Ch_WEAX, Ch_REBX]),
-(Ch: [Ch_Mop2, Ch_Rop1, Ch_WFlags]),
+(Ch: [Ch_Mop2, Ch_Rop1, Ch_WFlags, Ch_NoReadIfEqualRegs]),
 (Ch: [Ch_All]),
 (Ch: [Ch_All]),
 (Ch: [Ch_All]),

+ 6 - 6
compiler/i8086/i8086prop.inc

@@ -25,7 +25,7 @@
 (Ch: [Ch_WFlags]),
 (Ch: []),
 (Ch: [Ch_RWFlags]),
-(Ch: [Ch_ROp1, Ch_ROp2, Ch_WFlags]),
+(Ch: [Ch_ROp1, Ch_ROp2, Ch_WFlags, Ch_NoReadIfEqualRegs]),
 (Ch: [Ch_All, Ch_WFlags, Ch_RDirFlag]),
 (Ch: [Ch_All, Ch_WFlags, Ch_RDirFlag]),
 (Ch: [Ch_All, Ch_WFlags, Ch_RDirFlag]),
@@ -193,7 +193,7 @@
 (Ch: [Ch_Wop2, Ch_ROP1]),
 (Ch: []),
 (Ch: []),
-(Ch: [Ch_Wop2, Ch_Rop1]),
+(Ch: [Ch_Wop2, Ch_Rop1, Ch_NoReadIfEqualRegs]),
 (Ch: [Ch_Rop1, Ch_Wop2]),
 (Ch: [Ch_Rop1, Ch_Wop2]),
 (Ch: [Ch_All, Ch_RDirFlag]),
@@ -326,7 +326,7 @@
 (Ch: [Ch_Mop2, Ch_Rop1, Ch_WFlags]),
 (Ch: [Ch_WEAX, Ch_RFLAGS]),
 (Ch: [Ch_Mop2, Ch_Rop1, Ch_WFlags]),
-(Ch: [Ch_Mop2, Ch_Rop1, Ch_RWFlags]),
+(Ch: [Ch_Mop2, Ch_Rop1, Ch_RWFlags, Ch_NoReadIfEqualRegs]),
 (Ch: [Ch_All, Ch_WFlags, Ch_RDirFlag]),
 (Ch: [Ch_All, Ch_WFlags, Ch_RDirFlag]),
 (Ch: [Ch_All, Ch_WFlags, Ch_RDirFlag]),
@@ -354,7 +354,7 @@
 (Ch: [Ch_REAX, Ch_WMemEDI, Ch_RWEDI, Ch_RDirFlag]),
 (Ch: [Ch_REAX, Ch_WMemEDI, Ch_RWEDI, Ch_RDirFlag]),
 (Ch: [Ch_Wop1]),
-(Ch: [Ch_Mop2, Ch_Rop1, Ch_WFlags]),
+(Ch: [Ch_Mop2, Ch_Rop1, Ch_WFlags, Ch_NoReadIfEqualRegs]),
 (Ch: [Ch_All]),
 (Ch: [Ch_All]),
 (Ch: [Ch_All]),
@@ -374,10 +374,10 @@
 (Ch: [Ch_All]),
 (Ch: [Ch_All]),
 (Ch: [Ch_All]),
-(Ch: [Ch_RWop1, Ch_RWop2]),
+(Ch: [Ch_RWop1, Ch_RWop2, Ch_NoReadIfEqualRegs]),
 (Ch: [Ch_WEAX, Ch_REBX]),
 (Ch: [Ch_WEAX, Ch_REBX]),
-(Ch: [Ch_Mop2, Ch_Rop1, Ch_WFlags]),
+(Ch: [Ch_Mop2, Ch_Rop1, Ch_WFlags, Ch_NoReadIfEqualRegs]),
 (Ch: [Ch_All]),
 (Ch: [Ch_All]),
 (Ch: [Ch_All]),

+ 3 - 0
compiler/x86/aasmcpu.pas

@@ -217,6 +217,9 @@ interface
         Ch_Rop1, Ch_Wop1, Ch_RWop1,Ch_Mop1,
         Ch_Rop2, Ch_Wop2, Ch_RWop2,Ch_Mop2,
         Ch_Rop3, Ch_WOp3, Ch_RWOp3,Ch_Mop3,
+        { instruction doesn't read it's input register, in case both parameters
+          are the same register (e.g. xor eax,eax; sub eax,eax; sbb eax,eax (reads flags only), etc.) }
+        Ch_NoReadIfEqualRegs,
         Ch_WMemEDI,
         Ch_All,
         { x86_64 registers }

+ 6 - 6
compiler/x86/x86ins.dat

@@ -174,7 +174,7 @@ void                  \2\x0F\x06                      286,PRIV
 void                  \1\xF5                          8086
 
 [CMP,cmpX]
-(Ch_ROp1, Ch_ROp2, Ch_WFlags)
+(Ch_ROp1, Ch_ROp2, Ch_WFlags, Ch_NoReadIfEqualRegs)
 regmem,reg16|32|64    \320\1\x39\101                  8086,SM
 reg16|32|64,regmem    \320\1\x3B\110                  8086,SM
 rm8,reg8              \1\x38\101                      8086
@@ -1042,7 +1042,7 @@ void		      \3\x0F\x01\xC8		      PRESCOTT
 reg_eax,reg_ecx,reg_edx      \3\x0F\x01\xC8           PRESCOTT,ND
 
 [MOV,movX]
-(Ch_Wop2, Ch_Rop1)
+(Ch_Wop2, Ch_Rop1, Ch_NoReadIfEqualRegs)
 mem_offs,reg_ax       \324\1\xA3\44                   8086,SM
 mem_offs,reg_eax      \325\1\xA3\44                   386,SM
 mem_offs,reg_rax      \326\1\xA3\44                   X86_64,SM
@@ -1778,7 +1778,7 @@ rm8,reg_cl            \1\xD2\207                      8086
 rm8,imm               \1\xC0\207\25                   186,SB
 
 [SBB,sbbX]
-(Ch_Mop2, Ch_Rop1, Ch_RWFlags)
+(Ch_Mop2, Ch_Rop1, Ch_RWFlags, Ch_NoReadIfEqualRegs)
 regmem,reg16|32|64    \320\1\x19\101                  8086,SM
 reg16|32|64,regmem    \320\1\x1B\110                  8086,SM
 rm16|32|64,imm8       \320\1\x83\203\15               8086
@@ -1920,7 +1920,7 @@ mem                   \2\x0F\x00\201                  286,PROT
 reg16|32|64           \320\2\x0F\x00\201              286,PROT
 
 [SUB,subX]
-(Ch_Mop2, Ch_Rop1, Ch_WFlags)
+(Ch_Mop2, Ch_Rop1, Ch_WFlags, Ch_NoReadIfEqualRegs)
 regmem,reg16|32|64    \320\1\x29\101                  8086,SM
 reg16|32|64,regmem    \320\1\x2B\110                  8086,SM
 rm8,reg8              \1\x28\101                      8086
@@ -2041,7 +2041,7 @@ reg32,mem             \325\2\x0F\xA6\110              386,SD,UNDOC,ND
 reg32,reg32           \325\2\x0F\xA6\110              386,UNDOC,ND
 
 [XCHG,xchgX]
-(Ch_RWop1, Ch_RWop2)
+(Ch_RWop1, Ch_RWop2, Ch_NoReadIfEqualRegs)
 reg_ax,reg16          \324\11\x90                     8086
 reg_eax,reg32         \325\11\x90                     386
 reg_rax,reg64         \326\11\x90                     X86_64
@@ -2062,7 +2062,7 @@ void                  \1\xD7                          8086
 void                  \1\xD7                          8086
 
 [XOR,xorX]
-(Ch_Mop2, Ch_Rop1, Ch_WFlags)
+(Ch_Mop2, Ch_Rop1, Ch_WFlags, Ch_NoReadIfEqualRegs)
 regmem,reg16|32|64    \320\1\x31\101                  8086,SM
 reg16|32|64,regmem    \320\1\x33\110                  8086,SM
 rm8,reg8              \1\x30\101                      8086

+ 6 - 6
compiler/x86_64/x8664pro.inc

@@ -19,7 +19,7 @@
 (Ch: [Ch_WFlags]),
 (Ch: []),
 (Ch: [Ch_RWFlags]),
-(Ch: [Ch_ROp1, Ch_ROp2, Ch_WFlags]),
+(Ch: [Ch_ROp1, Ch_ROp2, Ch_WFlags, Ch_NoReadIfEqualRegs]),
 (Ch: [Ch_All, Ch_WFlags, Ch_RDirFlag]),
 (Ch: [Ch_All, Ch_WFlags, Ch_RDirFlag]),
 (Ch: [Ch_All, Ch_WFlags, Ch_RDirFlag]),
@@ -183,7 +183,7 @@
 (Ch: [Ch_Wop2, Ch_ROP1]),
 (Ch: []),
 (Ch: []),
-(Ch: [Ch_Wop2, Ch_Rop1]),
+(Ch: [Ch_Wop2, Ch_Rop1, Ch_NoReadIfEqualRegs]),
 (Ch: [Ch_Rop1, Ch_Wop2]),
 (Ch: [Ch_Rop1, Ch_Wop2]),
 (Ch: [Ch_All, Ch_RDirFlag]),
@@ -310,7 +310,7 @@
 (Ch: [Ch_WFlags, Ch_REAX]),
 (Ch: [Ch_Mop2, Ch_Rop1, Ch_WFlags]),
 (Ch: [Ch_Mop2, Ch_Rop1, Ch_WFlags]),
-(Ch: [Ch_Mop2, Ch_Rop1, Ch_RWFlags]),
+(Ch: [Ch_Mop2, Ch_Rop1, Ch_RWFlags, Ch_NoReadIfEqualRegs]),
 (Ch: [Ch_All, Ch_WFlags, Ch_RDirFlag]),
 (Ch: [Ch_All, Ch_WFlags, Ch_RDirFlag]),
 (Ch: [Ch_All, Ch_WFlags, Ch_RDirFlag]),
@@ -339,7 +339,7 @@
 (Ch: [Ch_REAX, Ch_WMemEDI, Ch_RWEDI, Ch_RDirFlag]),
 (Ch: [Ch_REAX, Ch_WMemEDI, Ch_RWEDI, Ch_RDirFlag]),
 (Ch: [Ch_Wop1]),
-(Ch: [Ch_Mop2, Ch_Rop1, Ch_WFlags]),
+(Ch: [Ch_Mop2, Ch_Rop1, Ch_WFlags, Ch_NoReadIfEqualRegs]),
 (Ch: [Ch_All]),
 (Ch: [Ch_All]),
 (Ch: [Ch_All]),
@@ -359,10 +359,10 @@
 (Ch: [Ch_All]),
 (Ch: [Ch_All]),
 (Ch: [Ch_All]),
-(Ch: [Ch_RWop1, Ch_RWop2]),
+(Ch: [Ch_RWop1, Ch_RWop2, Ch_NoReadIfEqualRegs]),
 (Ch: [Ch_WEAX, Ch_REBX]),
 (Ch: [Ch_WEAX, Ch_REBX]),
-(Ch: [Ch_Mop2, Ch_Rop1, Ch_WFlags]),
+(Ch: [Ch_Mop2, Ch_Rop1, Ch_WFlags, Ch_NoReadIfEqualRegs]),
 (Ch: [Ch_All]),
 (Ch: [Ch_All]),
 (Ch: [Ch_All]),