فهرست منبع

+ Z80: implemented the JRJP pseudo instruction in the Z80 internal asm writer

git-svn-id: trunk@45502 -
nickysn 5 سال پیش
والد
کامیت
c49213c561
1فایلهای تغییر یافته به همراه67 افزوده شده و 13 حذف شده
  1. 67 13
      compiler/z80/aasmcpu.pas

+ 67 - 13
compiler/z80/aasmcpu.pas

@@ -112,10 +112,11 @@ uses
          insoffset : longint;
          LastInsOffset : longint;
 
-         function Matches(p:PInsEntry):boolean;
+         function Matches(p:PInsEntry;objdata:TObjData):boolean;
          function FindInsentry(objdata:TObjData):boolean;
          function calcsize(p:PInsEntry):shortint;
          procedure gencode(objdata:TObjData);
+         procedure init; { this need to be called by all constructors }
       public
          constructor op_none(op : tasmop);
 
@@ -205,9 +206,13 @@ implementation
       end;
 
 
-    function taicpu.Matches(p: PInsEntry): boolean;
+    function taicpu.Matches(p: PInsEntry; objdata:TObjData): boolean;
 
       function OperandsMatch(const oper: toper; const ot: toperandtype): boolean;
+        var
+          currsym: TObjSymbol;
+          l: ASizeInt;
+          relsize: LongInt;
         begin
           case ot of
             OT_IMM3:
@@ -278,9 +283,37 @@ implementation
             OT_REG16_AF_:
               result:=(oper.typ=top_reg) and (oper.reg=NR_AF_);
             OT_RELJMP8:
-              result:=(oper.typ=top_ref) and
-                      (oper.ref^.refaddr=addr_full) and assigned(oper.ref^.symbol) and
-                      (oper.ref^.base=NR_NO) and (oper.ref^.index=NR_NO);
+              begin
+                result:=(oper.typ=top_ref) and
+                        (oper.ref^.refaddr=addr_full) and assigned(oper.ref^.symbol) and
+                        (oper.ref^.base=NR_NO) and (oper.ref^.index=NR_NO);
+                if result and assigned(objdata) then
+                  begin
+                    currsym:=objdata.symbolref(oper.ref^.symbol);
+                    l:=oper.ref^.offset;
+{$push}
+{$r-,q-} { disable also overflow as address returns a qword for x86_64 }
+                    if assigned(currsym) then
+                      inc(l,currsym.address);
+{$pop}
+                    { when it is a forward jump we need to compensate the
+                      offset of the instruction since the previous time,
+                      because the symbol address is then still using the
+                      'old-style' addressing.
+                      For backwards jumps this is not required because the
+                      address of the symbol is already adjusted to the
+                      new offset }
+                    if (l>InsOffset) and (LastInsOffset<>-1) then
+                      inc(l,InsOffset-LastInsOffset-1);
+                    { instruction size will then always become 2 (PFV) }
+                    relsize:=l-(InsOffset+2);
+                    result:=(relsize>=-128) and (relsize<=127) and
+                            (
+                             not assigned(currsym) or
+                             (currsym.objsection=objdata.currobjsec)
+                            );
+                  end;
+              end;
             OT_REF_ADDR16,
             OT_REF_BC,
             OT_REF_DE,
@@ -373,7 +406,7 @@ implementation
         { Things which may only be done once, not when a second pass is done to
           optimize }
 
-        if (Insentry=nil) {or (IF_PASS2 in InsEntry^.flags)} then
+        if (Insentry=nil) or (opcode=A_JRJP) then
          begin
            { set the file postion }
            current_filepos:=fileinfo;
@@ -395,7 +428,7 @@ implementation
         insentry:=@instab[i];
         while (insentry^.opcode=opcode) do
          begin
-           if matches(insentry) then
+           if matches(insentry,objdata) then
              begin
                result:=true;
                exit;
@@ -939,15 +972,26 @@ implementation
       end;
 
 
+    procedure taicpu.init;
+      begin
+        insentry:=nil;
+        LastInsOffset:=-1;
+        InsOffset:=0;
+        InsSize:=0;
+      end;
+
+
     constructor taicpu.op_none(op : tasmop);
       begin
          inherited create(op);
+         init;
       end;
 
 
     constructor taicpu.op_reg(op : tasmop;_op1 : tregister);
       begin
          inherited create(op);
+         init;
          ops:=1;
          loadreg(0,_op1);
       end;
@@ -956,6 +1000,7 @@ implementation
     constructor taicpu.op_ref(op : tasmop;const _op1 : treference);
       begin
          inherited create(op);
+         init;
          ops:=1;
          loadref(0,_op1);
       end;
@@ -964,6 +1009,7 @@ implementation
     constructor taicpu.op_const(op : tasmop;_op1 : LongInt);
       begin
          inherited create(op);
+         init;
          ops:=1;
          loadconst(0,_op1);
       end;
@@ -972,6 +1018,7 @@ implementation
     constructor taicpu.op_reg_reg(op : tasmop;_op1,_op2 : tregister);
       begin
          inherited create(op);
+         init;
          ops:=2;
          loadreg(0,_op1);
          loadreg(1,_op2);
@@ -980,6 +1027,7 @@ implementation
     constructor taicpu.op_reg_const(op:tasmop; _op1: tregister; _op2: LongInt);
       begin
          inherited create(op);
+         init;
          ops:=2;
          loadreg(0,_op1);
          loadconst(1,_op2);
@@ -988,6 +1036,7 @@ implementation
      constructor taicpu.op_const_reg(op:tasmop; _op1: LongInt; _op2: tregister);
       begin
          inherited create(op);
+         init;
          ops:=2;
          loadconst(0,_op1);
          loadreg(1,_op2);
@@ -997,6 +1046,7 @@ implementation
     constructor taicpu.op_reg_ref(op : tasmop;_op1 : tregister;const _op2 : treference);
       begin
          inherited create(op);
+         init;
          ops:=2;
          loadreg(0,_op1);
          loadref(1,_op2);
@@ -1006,6 +1056,7 @@ implementation
     constructor taicpu.op_ref_reg(op : tasmop;const _op1 : treference;_op2 : tregister);
       begin
          inherited create(op);
+         init;
          ops:=2;
          loadref(0,_op1);
          loadreg(1,_op2);
@@ -1015,6 +1066,7 @@ implementation
     constructor taicpu.op_ref_const(op: tasmop; _op1: treference; _op2: LongInt);
       begin
         inherited create(op);
+        init;
         ops:=2;
         loadref(0,_op1);
         loadconst(1,_op2);
@@ -1024,6 +1076,7 @@ implementation
     constructor taicpu.op_cond_sym(op : tasmop;cond:TAsmCond;_op1 : tasmsymbol);
       begin
          inherited create(op);
+         init;
          is_jmp:=op in jmp_instructions;
          condition:=cond;
          ops:=1;
@@ -1034,6 +1087,7 @@ implementation
     constructor taicpu.op_sym(op : tasmop;_op1 : tasmsymbol);
       begin
          inherited create(op);
+         init;
          is_jmp:=op in jmp_instructions;
          ops:=1;
          loadsymbol(0,_op1,0);
@@ -1043,6 +1097,7 @@ implementation
     constructor taicpu.op_sym_ofs(op : tasmop;_op1 : tasmsymbol;_op1ofs:longint);
       begin
          inherited create(op);
+         init;
          ops:=1;
          loadsymbol(0,_op1,_op1ofs);
       end;
@@ -1111,12 +1166,11 @@ implementation
     procedure taicpu.ResetPass2;
       begin
         { we are here in a second pass, check if the instruction can be optimized }
-        {if assigned(InsEntry) and
-           (IF_PASS2 in InsEntry^.flags) then
-         begin
-           InsEntry:=nil;
-           InsSize:=0;
-         end;}
+        if assigned(InsEntry) and (opcode=A_JRJP) then
+          begin
+            InsEntry:=nil;
+            InsSize:=0;
+          end;
         LastInsOffset:=-1;
       end;