Ver código fonte

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

git-svn-id: branches/laksen/spc32@33841 -
Jeppe Johansen 9 anos atrás
pai
commit
8c4720bf18

+ 18 - 2
compiler/spc32/aasmcpu.pas

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

+ 3 - 0
compiler/spc32/agspc32gas.pas

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

+ 89 - 2
compiler/spc32/aoptcpu.pas

@@ -44,7 +44,9 @@ Type
 
 
     { uses the same constructor as TAopObj }
     { uses the same constructor as TAopObj }
     function PeepHoleOptPass1Cpu(var p: tai): boolean; override;
     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);
     procedure DebugMsg(const s: string; p: tai);
   End;
   End;
@@ -965,8 +967,93 @@ Implementation
     end;
     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
     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;
     end;
 
 
 begin
 begin

+ 2 - 2
compiler/spc32/aoptcpub.pas

@@ -99,8 +99,8 @@ Const
 
 
   StoreDst = 1;
   StoreDst = 1;
 
 
-  aopt_uncondjmp = A_JMP;
-  aopt_condjmp = A_Jxx;
+  aopt_uncondjmp = A_PJMP;
+  aopt_condjmp = A_PJxx;
 
 
 Implementation
 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);
     procedure tcgspc32.a_call_name(list : TAsmList;const s : string; weak: boolean);
+      var
+        href: treference;
+        l: tasmlabel;
       begin
       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
         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)
         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);
     procedure tcgspc32.a_jmp_name(list : TAsmList;const s : string);
       var
       var
         ai : taicpu;
         ai : taicpu;
+        href: treference;
+        rl: TAsmLabel;
       begin
       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;
         ai.is_jmp:=true;
-        list.Concat(taicpu.op_const(A_GS,SS_PC));
         list.concat(ai);
         list.concat(ai);
       end;
       end;
 
 
@@ -857,10 +873,18 @@ unit cgcpu;
     procedure tcgspc32.a_jmp_always(list : TAsmList;l: tasmlabel);
     procedure tcgspc32.a_jmp_always(list : TAsmList;l: tasmlabel);
       var
       var
         ai : taicpu;
         ai : taicpu;
+        rl: TAsmLabel;
+        href: treference;
       begin
       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;
         ai.is_jmp:=true;
-        list.Concat(taicpu.op_const(A_GS,SS_PC));
         list.concat(ai);
         list.concat(ai);
       end;
       end;
 
 
@@ -868,10 +892,18 @@ unit cgcpu;
     procedure tcgspc32.a_jmp_flags(list : TAsmList;const f : TResFlags;l: tasmlabel);
     procedure tcgspc32.a_jmp_flags(list : TAsmList;const f : TResFlags;l: tasmlabel);
       var
       var
         ai : taicpu;
         ai : taicpu;
+        rl: TAsmLabel;
+        href: treference;
       begin
       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;
         ai.is_jmp:=true;
-        list.Concat(taicpu.op_const(A_GS,SS_PC));
         list.concat(ai);
         list.concat(ai);
       end;
       end;
 
 
@@ -1339,9 +1371,15 @@ unit cgcpu;
     procedure tcgspc32.a_jmp_cond(list : TAsmList;cond : TOpCmp;l: tasmlabel);
     procedure tcgspc32.a_jmp_cond(list : TAsmList;cond : TOpCmp;l: tasmlabel);
       var
       var
         ai1,ai2 : taicpu;
         ai1,ai2 : taicpu;
-        hl : TAsmLabel;
+        hl , rl: TAsmLabel;
+        href: treference;
       begin
       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;
         ai1.is_jmp:=true;
         hl:=nil;
         hl:=nil;
         case cond of
         case cond of
@@ -1360,7 +1398,7 @@ unit cgcpu;
           else
           else
             internalerror(2011082501);
             internalerror(2011082501);
         end;
         end;
-        list.Concat(taicpu.op_const(A_GS,SS_PC));
+        a_label(list,rl);
         list.concat(ai1);
         list.concat(ai1);
         if assigned(hl) then
         if assigned(hl) then
           a_label(list,hl);
           a_label(list,hl);

+ 4 - 2
compiler/spc32/cpubase.pas

@@ -58,7 +58,8 @@ unit cpubase;
         // Extended instructions
         // Extended instructions
         A_PUSH,A_POP,A_INC,A_XCHG,A_CAS,A_IRET,
         A_PUSH,A_POP,A_INC,A_XCHG,A_CAS,A_IRET,
         // Pseudo instructions
         // 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 }
       { This should define the array of instructions as string }
@@ -70,7 +71,8 @@ unit cpubase;
       { Last value of opcode enumeration  }
       { Last value of opcode enumeration  }
       lastop  = high(tasmop);
       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
                                   Registers

+ 2 - 1
compiler/spc32/itcpugas.pas

@@ -47,7 +47,8 @@ interface
         'jmp','call','j',
         'jmp','call','j',
         'gs','ss',
         'gs','ss',
         'push','pop','inc','xchg','cas','iret',
         '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_regnum_search(const s:string):Tregister;
     function gas_regname(r:Tregister):string;
     function gas_regname(r:Tregister):string;