2
0
Эх сурвалжийг харах

Fix for trunk arm STM optimize bug

Pierre Muller 1 жил өмнө
parent
commit
6e9521d99a
1 өөрчлөгдсөн 17 нэмэгдсэн , 5 устгасан
  1. 17 5
      compiler/arm/aoptcpu.pas

+ 17 - 5
compiler/arm/aoptcpu.pas

@@ -2213,12 +2213,22 @@ Implementation
       i, LastReg: TSuperRegister;
       Postfix: TOpPostfix;
       OpcodeStr: shortstring;
+      basereg : tregister;
     begin
       Result := False;
 
       { See if STM/STR can be merged into a single STM }
+      { taicpu(p).opcode is A_STM, so first operand is a memory reference }
       if (taicpu(p).oper[0]^.ref^.addressmode = AM_OFFSET) then
         begin
+          { Only try to handle simple base reg, without index }
+          if (taicpu(p).oper[0]^.ref^.index = NR_NO) then
+            basereg:=taicpu(p).oper[0]^.ref^.base
+          else if (taicpu(p).oper[0]^.ref^.base = NR_NO) and
+            (taicpu(p).oper[0]^.ref^.shiftmode = SM_NONE) then
+            basereg:=taicpu(p).oper[0]^.ref^.index
+          else
+            exit;
           CorrectOffset := 0;
           LastReg := RS_NO;
 
@@ -2233,18 +2243,20 @@ Implementation
           hp1 := p;
           while (LastReg < maxcpuregister) and
             GetNextInstruction(hp1, hp1) and (hp1.typ = ait_instruction) and
-            (taicpu(hp1).opcode = A_STR) do
+            (taicpu(hp1).opcode = A_STR) and
+            (taicpu(hp1).oper[1]^.typ = top_ref) do
             if (taicpu(hp1).condition = taicpu(p).condition) and
               (taicpu(hp1).oppostfix = PF_None) and
               (getregtype(taicpu(hp1).oper[0]^.reg) = R_INTREGISTER) and
               (taicpu(hp1).oper[1]^.ref^.addressmode = AM_OFFSET) and
+              (taicpu(hp1).oper[1]^.ref^.shiftmode = SM_NONE) and
               (
                 (
-                  (taicpu(p).oper[1]^.ref^.base = NR_NO) and
-                  (taicpu(hp1).oper[1]^.ref^.index = taicpu(p).oper[0]^.ref^.index)
+                  (taicpu(hp1).oper[1]^.ref^.base = NR_NO) and
+                  (taicpu(hp1).oper[1]^.ref^.index = basereg)
                 ) or (
-                  (taicpu(p).oper[1]^.ref^.index = NR_NO) and
-                  (taicpu(hp1).oper[1]^.ref^.base = taicpu(p).oper[0]^.ref^.base)
+                  (taicpu(hp1).oper[1]^.ref^.index = NR_NO) and
+                  (taicpu(hp1).oper[1]^.ref^.base = basereg)
                 )
               ) and
               { Next register must be later in the set }