浏览代码

Add pseudo instructions for jump and call instructions to allow jump optimizations.

git-svn-id: branches/laksen/spc32@33841 -
Jeppe Johansen 9 年之前
父节点
当前提交
8c4720bf18

+ 18 - 2
compiler/spc32/aasmcpu.pas

@@ -232,6 +232,11 @@ implementation
                 result:=operand_read;
             end;
 
+          A_PUSH,
+          A_POP:
+            if (oper[0]^.typ=top_reg) then
+              result:=operand_readwrite;
+
           A_ST:
             result:=operand_write;
           else
@@ -310,7 +315,8 @@ implementation
     procedure taicpu.Pass2(objdata: TObjData);
       var
         b, code : longword;
-        objsym : TObjSymbol;
+        objsym , relsym: TObjSymbol;
+        reloffset: AWord;
       begin
         code:=0;
 
@@ -431,12 +437,22 @@ implementation
 
             objsym:=objdata.symbolref(oper[0]^.ref^.symbol);
 
+            reloffset:=0;
+            if assigned(oper[0]^.ref^.relsymbol) then
+              begin
+                relsym:=objdata.symbolref(oper[0]^.ref^.relsymbol);
+                if relsym.objsection=objdata.CurrObjSec then
+                  reloffset:=objdata.CurrObjSec.size+2-relsym.offset
+                else
+                  Message(verbose.asmw_e_undefined_label);
+              end;
+
             if oper[0]^.ref^.refaddr = addr_hi16 then
               code:=(oper[0]^.ref^.offset shr 16) and $FFFF
             else if oper[0]^.ref^.refaddr = addr_lo16 then
               code:=(oper[0]^.ref^.offset) and $FFFF
             else
-              code:=(oper[0]^.ref^.offset+6) and $FFFF;
+              code:=(oper[0]^.ref^.offset+reloffset) and $FFFF;
 
             case oper[0]^.ref^.refaddr of
               addr_lo16:

+ 3 - 0
compiler/spc32/agspc32gas.pas

@@ -113,6 +113,9 @@ unit agspc32gas;
                   else if offset>0 then
                     s:=s+'+'+tostr(offset);
 
+                  if assigned(relsymbol) then
+                    s:=s+'-'+ReplaceForbiddenAsmSymbolChars(relsymbol.name);
+
                   case refaddr of
                     addr_hi16:
                       s:='hi16('+s+')';

+ 89 - 2
compiler/spc32/aoptcpu.pas

@@ -44,7 +44,9 @@ Type
 
     { uses the same constructor as TAopObj }
     function PeepHoleOptPass1Cpu(var p: tai): boolean; override;
-    procedure PeepHoleOptPass2;override;
+    function PeepHoleOptPass2Cpu(var p: tai): boolean; override;
+
+    function PostPeepHoleOptsCpu(var p: tai): boolean; override;
 
     procedure DebugMsg(const s: string; p: tai);
   End;
@@ -965,8 +967,93 @@ Implementation
     end;
 
 
-  procedure TCpuAsmOptimizer.PeepHoleOptPass2;
+  function TCpuAsmOptimizer.PeepHoleOptPass2Cpu(var p: tai): boolean;
+    var
+      hp1,hp2,hp3: tai;
+      alloc, dealloc: tai_regalloc;
+      i: integer;
+    begin
+      result := false;
+      case p.typ of
+        ait_instruction:
+          begin
+            case taicpu(p).opcode of
+              A_PJMP:
+                begin
+                  AsmL.InsertBefore(taicpu.op_const(A_GS,SS_PC),p);
+                  taicpu(p).opcode:=A_JMP;
+                  result:=true;
+                end;
+              A_PJxx:
+                begin
+                  AsmL.InsertBefore(taicpu.op_const(A_GS,SS_PC),p);
+                  taicpu(p).opcode:=A_Jxx;
+                  result:=true;
+                end;
+              A_PCALL:
+                begin
+                  AsmL.InsertBefore(taicpu.op_const(A_GS,SS_PC),p);
+                  taicpu(p).opcode:=A_CALL;
+                  result:=true;
+                end;
+            end;
+          end;
+      end;
+    end;
+
+
+  function TCpuAsmOptimizer.PostPeepHoleOptsCpu(var p: tai): boolean;
+    var
+      hp1,hp2,hp3, hp4: tai;
+      alloc, dealloc: tai_regalloc;
+      i: integer;
     begin
+      result := false;
+      case p.typ of
+        ait_instruction:
+          begin
+            case taicpu(p).opcode of
+              A_GS:
+                begin
+                  if (taicpu(p).ops=1) and
+                     (taicpu(p).oper[0]^.typ=top_const) and
+                     (taicpu(p).oper[0]^.val=SS_PC) then
+                    begin
+                      hp1:=p;
+
+                      while GetNextInstruction(hp1,hp2) and
+                            (hp2.typ=ait_instruction) and
+                            (taicpu(hp2).is_jmp) do
+                        begin
+                          if GetNextInstruction(hp2,hp3) and
+                             (hp3.typ=ait_label) and
+                             GetNextInstruction(hp3,hp4) and
+                             (hp4.typ=ait_instruction) and
+                             (taicpu(hp4).opcode=A_GS) and
+                             (taicpu(hp4).ops=1) and
+                             (taicpu(hp4).oper[0]^.typ=top_const) and
+                             (taicpu(hp4).oper[0]^.val=SS_PC) then
+                            begin
+                              DebugMsg('GsJGs2GsJ', hp1);
+
+                              asml.Remove(hp3);
+                              asml.InsertBefore(hp3,p);
+
+                              asml.Remove(hp4);
+                              hp4.free;
+
+                              result:=true;
+                            end
+                          else
+                            break;
+
+                          hp1:=hp2;
+                        end;
+                    end;
+                end;
+            end;
+          end;
+      end;
     end;
 
 begin

+ 2 - 2
compiler/spc32/aoptcpub.pas

@@ -99,8 +99,8 @@ Const
 
   StoreDst = 1;
 
-  aopt_uncondjmp = A_JMP;
-  aopt_condjmp = A_Jxx;
+  aopt_uncondjmp = A_PJMP;
+  aopt_condjmp = A_PJxx;
 
 Implementation
 

+ 49 - 11
compiler/spc32/cgcpu.pas

@@ -379,9 +379,18 @@ unit cgcpu;
 
 
     procedure tcgspc32.a_call_name(list : TAsmList;const s : string; weak: boolean);
+      var
+        href: treference;
+        l: tasmlabel;
       begin
-        list.concat(taicpu.op_const(A_GS, SS_PC));
-        list.concat(taicpu.op_sym(A_CALL,current_asmdata.RefAsmSymbol(s)));
+        reference_reset_symbol(href, current_asmdata.RefAsmSymbol(s), 0,1);
+
+        current_asmdata.getjumplabel(l);
+
+        href.relsymbol:=l;
+
+        a_label(list,l);
+        list.concat(taicpu.op_ref(A_PCALL,href));
 {
         the compiler does not properly set this flag anymore in pass 1, and
         for now we only need it after pass 2 (I hope) (JM)
@@ -846,10 +855,17 @@ unit cgcpu;
     procedure tcgspc32.a_jmp_name(list : TAsmList;const s : string);
       var
         ai : taicpu;
+        href: treference;
+        rl: TAsmLabel;
       begin
-        ai:=taicpu.op_sym(A_JMP,current_asmdata.RefAsmSymbol(s));
+        current_asmdata.getjumplabel(rl);
+
+        reference_reset_symbol(href, current_asmdata.RefAsmSymbol(s), 0, 1);
+        href.relsymbol:=rl;
+
+        a_label(list, rl);
+        ai:=taicpu.op_ref(A_PJMP,href);
         ai.is_jmp:=true;
-        list.Concat(taicpu.op_const(A_GS,SS_PC));
         list.concat(ai);
       end;
 
@@ -857,10 +873,18 @@ unit cgcpu;
     procedure tcgspc32.a_jmp_always(list : TAsmList;l: tasmlabel);
       var
         ai : taicpu;
+        rl: TAsmLabel;
+        href: treference;
       begin
-        ai:=taicpu.op_sym(A_JMP,l);
+        current_asmdata.getjumplabel(rl);
+
+        reference_reset_symbol(href, l, 0, 1);
+        href.relsymbol:=rl;
+
+        a_label(list, rl);
+
+        ai:=taicpu.op_ref(A_PJMP,href);
         ai.is_jmp:=true;
-        list.Concat(taicpu.op_const(A_GS,SS_PC));
         list.concat(ai);
       end;
 
@@ -868,10 +892,18 @@ unit cgcpu;
     procedure tcgspc32.a_jmp_flags(list : TAsmList;const f : TResFlags;l: tasmlabel);
       var
         ai : taicpu;
+        rl: TAsmLabel;
+        href: treference;
       begin
-        ai:=setcondition(taicpu.op_sym(A_Jxx,l),flags_to_cond(f));
+        current_asmdata.getjumplabel(rl);
+
+        reference_reset_symbol(href, l, 0, 1);
+        href.relsymbol:=rl;
+
+        a_label(list, rl);
+
+        ai:=setcondition(taicpu.op_ref(A_PJxx,href),flags_to_cond(f));
         ai.is_jmp:=true;
-        list.Concat(taicpu.op_const(A_GS,SS_PC));
         list.concat(ai);
       end;
 
@@ -1339,9 +1371,15 @@ unit cgcpu;
     procedure tcgspc32.a_jmp_cond(list : TAsmList;cond : TOpCmp;l: tasmlabel);
       var
         ai1,ai2 : taicpu;
-        hl : TAsmLabel;
+        hl , rl: TAsmLabel;
+        href: treference;
       begin
-        ai1:=Taicpu.Op_sym(A_Jxx,l);
+        current_asmdata.getjumplabel(rl);
+
+        reference_reset_symbol(href, l, 0,1);
+        href.relsymbol:=rl;
+
+        ai1:=Taicpu.op_ref(A_PJxx,href);
         ai1.is_jmp:=true;
         hl:=nil;
         case cond of
@@ -1360,7 +1398,7 @@ unit cgcpu;
           else
             internalerror(2011082501);
         end;
-        list.Concat(taicpu.op_const(A_GS,SS_PC));
+        a_label(list,rl);
         list.concat(ai1);
         if assigned(hl) then
           a_label(list,hl);

+ 4 - 2
compiler/spc32/cpubase.pas

@@ -58,7 +58,8 @@ unit cpubase;
         // Extended instructions
         A_PUSH,A_POP,A_INC,A_XCHG,A_CAS,A_IRET,
         // Pseudo instructions
-        A_MOV,A_LOAD,A_STORE);
+        A_MOV,A_LOAD,A_STORE,
+        A_PCALL,A_PJMP,A_PJxx);
 
 
       { This should define the array of instructions as string }
@@ -70,7 +71,8 @@ unit cpubase;
       { Last value of opcode enumeration  }
       lastop  = high(tasmop);
 
-      jmp_instructions = [A_Jxx,A_JMP,A_CALL];
+      jmp_instructions = [A_Jxx,A_JMP,A_CALL,
+                          A_PCALL,A_PJMP,A_PJxx];
 
 {*****************************************************************************
                                   Registers

+ 2 - 1
compiler/spc32/itcpugas.pas

@@ -47,7 +47,8 @@ interface
         'jmp','call','j',
         'gs','ss',
         'push','pop','inc','xchg','cas','iret',
-        'mov','load','store');
+        'mov','load','store',
+        'pcall','pjmp','pj');
 
     function gas_regnum_search(const s:string):Tregister;
     function gas_regname(r:Tregister):string;