浏览代码

Introduce a version of MatchInstruction for multiple instructions

It is the same as the normal MatchInstruction function but supports to
be called with a set of TAsmOps instead of a single op.

git-svn-id: trunk@22231 -
masta 13 年之前
父节点
当前提交
d8af83d252
共有 2 个文件被更改,包括 23 次插入20 次删除
  1. 20 20
      compiler/arm/aoptcpu.pas
  2. 3 0
      compiler/arm/cpubase.pas

+ 20 - 20
compiler/arm/aoptcpu.pas

@@ -99,6 +99,15 @@ Implementation
         (r1.shiftmode = r2.shiftmode);
         (r1.shiftmode = r2.shiftmode);
     end;
     end;
 
 
+  function MatchInstruction(const instr: tai; const op: TCommonAsmOps; const cond: TAsmConds; const postfix: TOpPostfixes): boolean;
+  begin
+    result :=
+      (instr.typ = ait_instruction) and
+      ((op = []) or (taicpu(instr).opcode in op)) and
+      ((cond = []) or (taicpu(instr).condition in cond)) and
+      ((postfix = []) or (taicpu(instr).oppostfix in postfix));
+  end;
+
   function MatchInstruction(const instr: tai; const op: TAsmOp; const cond: TAsmConds; const postfix: TOpPostfixes): boolean;
   function MatchInstruction(const instr: tai; const op: TAsmOp; const cond: TAsmConds; const postfix: TOpPostfixes): boolean;
   begin
   begin
     result :=
     result :=
@@ -372,10 +381,8 @@ Implementation
         (p.oper[1]^.ref^.index=NR_NO) and
         (p.oper[1]^.ref^.index=NR_NO) and
         (p.oper[1]^.ref^.offset=0) and
         (p.oper[1]^.ref^.offset=0) and
         GetNextInstructionUsingReg(p, hp1, p.oper[1]^.ref^.base) and
         GetNextInstructionUsingReg(p, hp1, p.oper[1]^.ref^.base) and
-        (hp1.typ=ait_instruction) and
         { we cannot check NR_DEFAULTFLAGS for modification yet so don't allow a condition }
         { we cannot check NR_DEFAULTFLAGS for modification yet so don't allow a condition }
-        (MatchInstruction(hp1, A_ADD, [C_None], [PF_None]) or
-         MatchInstruction(hp1, A_SUB, [C_None], [PF_None])) and
+        MatchInstruction(hp1, [A_ADD, A_SUB], [C_None], [PF_None]) and
         (taicpu(hp1).oper[0]^.reg=p.oper[1]^.ref^.base) and
         (taicpu(hp1).oper[0]^.reg=p.oper[1]^.ref^.base) and
         (taicpu(hp1).oper[1]^.reg=p.oper[1]^.ref^.base) and
         (taicpu(hp1).oper[1]^.reg=p.oper[1]^.ref^.base) and
         (
         (
@@ -444,11 +451,8 @@ Implementation
             }
             }
             { this optimization can applied only to the currently enabled operations because
             { this optimization can applied only to the currently enabled operations because
               the other operations do not update all flags and FPC does not track flag usage }
               the other operations do not update all flags and FPC does not track flag usage }
-            if ((taicpu(p).opcode in [A_ADC,A_ADD,A_BIC,A_SUB,A_MUL,A_MVN,A_MOV,
-                                      A_ORR,A_EOR,A_AND,A_RSB,A_RSC,A_SBC,A_MLA])
-               ) and
-              (taicpu(p).oppostfix = PF_None) and
-              (taicpu(p).condition = C_None) and
+            if MatchInstruction(p, [A_ADC,A_ADD,A_BIC,A_SUB,A_MUL,A_MVN,A_MOV,A_ORR,A_EOR,A_AND,
+                                 A_RSB,A_RSC,A_SBC,A_MLA], [C_None], [PF_None]) and
               GetNextInstruction(p, hp1) and
               GetNextInstruction(p, hp1) and
               MatchInstruction(hp1, A_CMP, [C_None], [PF_None]) and
               MatchInstruction(hp1, A_CMP, [C_None], [PF_None]) and
               (taicpu(hp1).oper[1]^.typ = top_const) and
               (taicpu(hp1).oper[1]^.typ = top_const) and
@@ -879,12 +883,11 @@ Implementation
                        (taicpu(p).oper[1]^.typ = top_reg) and
                        (taicpu(p).oper[1]^.typ = top_reg) and
                        (taicpu(p).oppostfix = PF_NONE) and
                        (taicpu(p).oppostfix = PF_NONE) and
                        GetNextInstruction(p, hp1) and
                        GetNextInstruction(p, hp1) and
-                       (tai(hp1).typ = ait_instruction) and
-                       (taicpu(hp1).opcode in [A_ADD, A_ADC, A_RSB, A_RSC, A_SUB, A_SBC,
-                                               A_AND, A_BIC, A_EOR, A_ORR, A_MOV, A_MVN]) and
+                       MatchInstruction(hp1, [A_ADD, A_ADC, A_RSB, A_RSC, A_SUB, A_SBC,
+                                              A_AND, A_BIC, A_EOR, A_ORR, A_MOV, A_MVN],
+                                        [C_NONE, taicpu(hp1).condition], []) and
                        {MOV and MVN might only have 2 ops}
                        {MOV and MVN might only have 2 ops}
                        (taicpu(hp1).ops = 3) and
                        (taicpu(hp1).ops = 3) and
-                       (taicpu(hp1).condition in [C_NONE, taicpu(hp1).condition]) and
                        MatchOperand(taicpu(p).oper[0]^, taicpu(hp1).oper[0]^.reg) and
                        MatchOperand(taicpu(p).oper[0]^, taicpu(hp1).oper[0]^.reg) and
                        (taicpu(hp1).oper[1]^.typ = top_reg) and
                        (taicpu(hp1).oper[1]^.typ = top_reg) and
                        (taicpu(hp1).oper[2]^.typ in [top_reg, top_const, top_shifterop]) then
                        (taicpu(hp1).oper[2]^.typ in [top_reg, top_const, top_shifterop]) then
@@ -923,14 +926,12 @@ Implementation
                        (taicpu(p).oper[2]^.typ = top_shifterop) and
                        (taicpu(p).oper[2]^.typ = top_shifterop) and
                        (taicpu(p).oppostfix = PF_NONE) and
                        (taicpu(p).oppostfix = PF_NONE) and
                        GetNextInstruction(p, hp1) and
                        GetNextInstruction(p, hp1) and
-                       (tai(hp1).typ = ait_instruction) and
+                       MatchInstruction(hp1, [A_ADD, A_ADC, A_RSB, A_RSC, A_SUB, A_SBC,
+                                              A_AND, A_BIC, A_EOR, A_ORR, A_TEQ, A_TST,
+                                              A_CMP, A_CMN],
+                                        [taicpu(p).condition], [PF_None]) and
                        (taicpu(hp1).ops >= 2) and {Currently we can't fold into another shifterop}
                        (taicpu(hp1).ops >= 2) and {Currently we can't fold into another shifterop}
                        (taicpu(hp1).oper[taicpu(hp1).ops-1]^.typ = top_reg) and
                        (taicpu(hp1).oper[taicpu(hp1).ops-1]^.typ = top_reg) and
-                       (taicpu(hp1).oppostfix = PF_NONE) and
-                       (taicpu(hp1).condition = taicpu(p).condition) and
-                       (taicpu(hp1).opcode in [A_ADD, A_ADC, A_RSB, A_RSC, A_SUB, A_SBC,
-                                               A_AND, A_BIC, A_EOR, A_ORR, A_TEQ, A_TST,
-                                               A_CMP, A_CMN]) and
                        (
                        (
                          {Only ONE of the two src operands is allowed to match}
                          {Only ONE of the two src operands is allowed to match}
                          MatchOperand(taicpu(p).oper[0]^, taicpu(hp1).oper[taicpu(hp1).ops-2]^) xor
                          MatchOperand(taicpu(p).oper[0]^, taicpu(hp1).oper[taicpu(hp1).ops-2]^) xor
@@ -1050,8 +1051,7 @@ Implementation
                         hp1:=p;
                         hp1:=p;
                         while GetNextInstructionUsingReg(hp1, hp1, taicpu(p).oper[0]^.reg) and
                         while GetNextInstructionUsingReg(hp1, hp1, taicpu(p).oper[0]^.reg) and
                           { we cannot check NR_DEFAULTFLAGS for modification yet so don't allow a condition }
                           { we cannot check NR_DEFAULTFLAGS for modification yet so don't allow a condition }
-                          (MatchInstruction(hp1, A_LDR, [C_None], []) or
-                           MatchInstruction(hp1, A_STR, [C_None], [])) and
+                          MatchInstruction(hp1, [A_LDR, A_STR], [C_None], []) and
                           (taicpu(hp1).oper[1]^.ref^.base=taicpu(p).oper[0]^.reg) and
                           (taicpu(hp1).oper[1]^.ref^.base=taicpu(p).oper[0]^.reg) and
                           { don't optimize if the register is stored/overwritten }
                           { don't optimize if the register is stored/overwritten }
                           (taicpu(hp1).oper[0]^.reg<>taicpu(p).oper[1]^.reg) and
                           (taicpu(hp1).oper[0]^.reg<>taicpu(p).oper[1]^.reg) and

+ 3 - 0
compiler/arm/cpubase.pas

@@ -46,6 +46,9 @@ unit cpubase;
 
 
     type
     type
       TAsmOp= {$i armop.inc}
       TAsmOp= {$i armop.inc}
+      {This is a bit of a hack, because there are more than 256 ARM Assembly Ops
+       But FPC currently can't handle more than 256 elements in a set.}
+      TCommonAsmOps = Set of A_None .. A_UQSADA8;
 
 
       { This should define the array of instructions as string }
       { This should define the array of instructions as string }
       op2strtable=array[tasmop] of string[11];
       op2strtable=array[tasmop] of string[11];