Преглед на файлове

* support indexing and offset retrieval for locals

peter преди 22 години
родител
ревизия
5925d38ac7
променени са 7 файла, в които са добавени 144 реда и са изтрити 58 реда
  1. 9 4
      compiler/aasmtai.pas
  2. 62 41
      compiler/i386/ra386int.pas
  3. 34 6
      compiler/ncgbas.pas
  4. 7 2
      compiler/pstatmnt.pas
  5. 17 2
      compiler/rautils.pas
  6. 8 1
      compiler/x86/aasmcpu.pas
  7. 7 2
      compiler/x86/rax86.pas

+ 9 - 4
compiler/aasmtai.pas

@@ -156,7 +156,7 @@ interface
          top_symbol : (sym:tasmsymbol;symofs:longint);
          top_bool   : (b:boolean);
          { local varsym that will be inserted in pass_2 }
-         top_local  : (localsym:pointer;localsymderef:tderef;localsymofs:longint);
+         top_local  : (localsym:pointer;localsymderef:tderef;localsymofs:longint;localindexreg:tregister;localgetoffset:boolean);
       end;
       poper=^toper;
 
@@ -465,7 +465,7 @@ interface
           procedure allocate_oper(opers:longint);
           procedure loadconst(opidx:longint;l:aword);
           procedure loadsymbol(opidx:longint;s:tasmsymbol;sofs:longint);
-          procedure loadlocal(opidx:longint;s:pointer;sofs:longint);
+          procedure loadlocal(opidx:longint;s:pointer;sofs:longint;indexreg:tregister;getoffset:boolean);
           procedure loadref(opidx:longint;const r:treference);
           procedure loadreg(opidx:longint;r:tregister);
           procedure loadoper(opidx:longint;o:toper);
@@ -1590,7 +1590,7 @@ implementation
       end;
 
 
-    procedure taicpu_abstract.loadlocal(opidx:longint;s:pointer;sofs:longint);
+    procedure taicpu_abstract.loadlocal(opidx:longint;s:pointer;sofs:longint;indexreg:tregister;getoffset:boolean);
       begin
         if not assigned(s) then
          internalerror(200204251);
@@ -1601,6 +1601,8 @@ implementation
              clearop(opidx);
            localsym:=s;
            localsymofs:=sofs;
+           localindexreg:=indexreg;
+           localgetoffset:=getoffset;
            typ:=top_local;
          end;
       end;
@@ -2138,7 +2140,10 @@ implementation
 end.
 {
   $Log$
-  Revision 1.50  2003-10-29 14:42:14  mazen
+  Revision 1.51  2003-10-29 15:40:20  peter
+    * support indexing and offset retrieval for locals
+
+  Revision 1.50  2003/10/29 14:42:14  mazen
   * code reformatted
 
   Revision 1.49  2003/10/29 14:05:45  mazen

+ 62 - 41
compiler/i386/ra386int.pas

@@ -1070,8 +1070,6 @@ Begin
              HadVar:=hasvar and GotOffset;
              if negative then
                Message(asmr_e_only_add_relocatable_symbol);
-             oldbase:=opr.ref.base;
-             opr.ref.base:=NR_NO;
              tempstr:=actasmpattern;
              Consume(AS_ID);
              { typecasting? }
@@ -1092,13 +1090,19 @@ Begin
              if actasmtoken=AS_DOT then
               begin
                 BuildRecordOffsetSize(tempstr,l,k);
-                inc(opr.ref.offset,l);
+                case opr.typ of
+                  OPR_LOCAL :
+                    inc(opr.localsymofs,l);
+                  OPR_REFERENCE :
+                    inc(opr.ref.offset,l);
+                end;
               end;
              if GotOffset then
               begin
                 if hasvar and (opr.ref.base=current_procinfo.framepointer) then
                  begin
-                   opr.ref.base:=NR_NO;
+                   if (opr.typ=OPR_REFERENCE) then
+                     opr.ref.base:=NR_NO;
                    hasvar:=hadvar;
                  end
                 else
@@ -1108,24 +1112,29 @@ Begin
                    { should we allow ?? }
                  end;
               end;
-             { is the base register loaded by the var ? }
-             if (opr.ref.base<>NR_NO) then
-              begin
-                { check if we can move the old base to the index register }
-                if (opr.ref.index<>NR_NO) then
-                 Message(asmr_e_wrong_base_index)
-                else
-                 opr.ref.index:=oldbase;
-              end
-             else
-              opr.ref.base:=oldbase;
-             { we can't have a Constant here so add the constant value to the
-               offset }
-             if opr.typ=OPR_CONSTANT then
-              begin
-                opr.typ:=OPR_REFERENCE;
-                inc(opr.ref.offset,opr.val);
-              end;
+(*
+             if (opr.typ=OPR_REFERENCE) then
+               begin
+                 { is the base register loaded by the var ? }
+                 if (opr.ref.base<>NR_NO) then
+                  begin
+                    { check if we can move the old base to the index register }
+                    if (opr.ref.index<>NR_NO) then
+                     Message(asmr_e_wrong_base_index)
+                    else
+                     opr.ref.index:=oldbase;
+                  end
+                 else
+                  opr.ref.base:=oldbase;
+                 { we can't have a Constant here so add the constant value to the
+                   offset }
+                 if opr.typ=OPR_CONSTANT then
+                  begin
+                    opr.typ:=OPR_REFERENCE;
+                    inc(opr.ref.offset,opr.val);
+                  end;
+               end;
+*)
            end;
           GotOffset:=false;
         end;
@@ -1194,25 +1203,34 @@ Begin
             Message(asmr_e_invalid_reference_syntax);
           hreg:=actasmregister;
           Consume(AS_REGISTER);
-          { this register will be the index:
-             1. just read a *
-             2. next token is a *
-             3. base register is already used }
-          if (GotStar) or
-             (actasmtoken=AS_STAR) or
-             (opr.ref.base<>NR_NO) then
-           begin
-             if (opr.ref.index<>NR_NO) then
-              Message(asmr_e_multiple_index);
-             opr.ref.index:=hreg;
-             if scale<>0 then
-               begin
-                 opr.ref.scalefactor:=scale;
-                 scale:=0;
-               end;
-           end
+          if opr.typ=OPR_LOCAL then
+            begin
+              if (opr.localindexreg<>NR_NO) then
+                Message(asmr_e_multiple_index);
+              opr.localindexreg:=hreg;
+            end
           else
-           opr.ref.base:=hreg;
+            begin
+              { this register will be the index:
+                 1. just read a *
+                 2. next token is a *
+                 3. base register is already used }
+              if (GotStar) or
+                 (actasmtoken=AS_STAR) or
+                 (opr.ref.base<>NR_NO) then
+               begin
+                 if (opr.ref.index<>NR_NO) then
+                  Message(asmr_e_multiple_index);
+                 opr.ref.index:=hreg;
+                 if scale<>0 then
+                   begin
+                     opr.ref.scalefactor:=scale;
+                     scale:=0;
+                   end;
+               end
+              else
+               opr.ref.base:=hreg;
+            end;
           GotPlus:=false;
           GotStar:=false;
         end;
@@ -1906,7 +1924,10 @@ finalization
 end.
 {
   $Log$
-  Revision 1.60  2003-10-27 15:29:43  peter
+  Revision 1.61  2003-10-29 15:40:20  peter
+    * support indexing and offset retrieval for locals
+
+  Revision 1.60  2003/10/27 15:29:43  peter
     * fixed trec.field to return constant
 
   Revision 1.59  2003/10/24 17:39:03  peter

+ 34 - 6
compiler/ncgbas.pas

@@ -68,7 +68,7 @@ interface
 
     uses
       globtype,systems,
-      cutils,verbose,
+      cutils,verbose,cpuinfo,
       aasmbase,aasmtai,aasmcpu,symsym,
       defutil,
       nflw,pass_2,
@@ -133,22 +133,47 @@ interface
       procedure ResolveRef(var op:toper);
         var
           sym : tvarsym;
+          getoffset : boolean;
+          indexreg : tregister;
           sofs : longint;
         begin
           if (op.typ=top_local) then
             begin
               sofs:=op.localsymofs;
+              indexreg:=op.localindexreg;
+              getoffset:=op.localgetoffset;
               sym:=tvarsym(pointer(op.localsym));
               case sym.localloc.loc of
                 LOC_REFERENCE :
                   begin
-                    op.typ:=top_ref;
-                    new(op.ref);
-                    reference_reset_base(op.ref^,sym.localloc.reference.index,
-                        sym.localloc.reference.offset+sofs);
+                    if getoffset then
+                      begin
+                        if indexreg=NR_NO then
+                          begin
+                            op.typ:=top_const;
+                            op.val:=aword(sym.localloc.reference.offset+sofs);
+                          end
+                        else
+                          begin
+                            op.typ:=top_ref;
+                            new(op.ref);
+                            reference_reset_base(op.ref^,indexreg,
+                                sym.localloc.reference.offset+sofs);
+                          end;
+                      end
+                    else
+                      begin
+                        op.typ:=top_ref;
+                        new(op.ref);
+                        reference_reset_base(op.ref^,sym.localloc.reference.index,
+                            sym.localloc.reference.offset+sofs);
+                        op.ref^.index:=indexreg;
+                      end;
                   end;
                 LOC_REGISTER :
                   begin
+                    if getoffset then
+                      Message(asmr_e_invalid_reference_syntax);
                     { Subscribed access }
                     if sofs<>0 then
                       begin
@@ -374,7 +399,10 @@ begin
 end.
 {
   $Log$
-  Revision 1.46  2003-10-24 17:39:41  peter
+  Revision 1.47  2003-10-29 15:40:20  peter
+    * support indexing and offset retrieval for locals
+
+  Revision 1.46  2003/10/24 17:39:41  peter
     * asmnode.get_position now inserts a marker
 
   Revision 1.45  2003/10/21 15:15:36  peter

+ 7 - 2
compiler/pstatmnt.pas

@@ -1054,7 +1054,9 @@ implementation
       begin
         { Count only varsyms, but ignore the funcretsym }
         if (tsym(p).typ=varsym) and
-           (tsym(p)<>current_procinfo.procdef.funcretsym) then
+           (tsym(p)<>current_procinfo.procdef.funcretsym) and
+           (not(vo_is_parentfp in tvarsym(p).varoptions) or
+            (tvarsym(p).refs>0)) then
           inc(plongint(arg)^);
       end;
 
@@ -1130,7 +1132,10 @@ implementation
 end.
 {
   $Log$
-  Revision 1.116  2003-10-17 14:38:32  peter
+  Revision 1.117  2003-10-29 15:40:20  peter
+    * support indexing and offset retrieval for locals
+
+  Revision 1.116  2003/10/17 14:38:32  peter
     * 64k registers supported
     * fixed some memory leaks
 

+ 17 - 2
compiler/rautils.pas

@@ -76,7 +76,7 @@ type
       OPR_CONSTANT  : (val:longint);
       OPR_SYMBOL    : (symbol:tasmsymbol;symofs:longint);
       OPR_REFERENCE : (ref:treference);
-      OPR_LOCAL     : (localsym:tvarsym;localsymofs:longint);
+      OPR_LOCAL     : (localsym:tvarsym;localsymofs:longint;localindexreg:tregister;localgetoffset:boolean);
       OPR_REGISTER  : (reg:tregister);
 {$ifdef m68k}
       OPR_REGLIST   : (reglist:Tsupregset);
@@ -794,6 +794,7 @@ var
   sym : tsym;
   srsymtable : tsymtable;
   harrdef : tarraydef;
+  indexreg : tregister;
   l : longint;
   plist : psymlistitem;
 Begin
@@ -839,12 +840,21 @@ Begin
           parasymtable,
           localsymtable :
             begin
+              indexreg:=opr.ref.base;
+              if opr.ref.index<>NR_NO then
+                begin
+                  if indexreg=NR_NO then
+                    indexreg:=opr.ref.index
+                  else
+                    Message(asmr_e_multiple_index);
+                end;
               if (vo_is_external in tvarsym(sym).varoptions) then
                 opr.ref.symbol:=objectlibrary.newasmsymboldata(tvarsym(sym).mangledname)
               else
                 begin
                   opr.typ:=OPR_LOCAL;
                   if assigned(current_procinfo.parent) and
+                     (current_procinfo.procdef.proccalloption<>pocall_inline) and
                      (tvarsym(sym).owner<>current_procinfo.procdef.localst) and
                      (tvarsym(sym).owner<>current_procinfo.procdef.parast) and
                      (current_procinfo.procdef.localst.symtablelevel>normal_function_level) and
@@ -852,6 +862,8 @@ Begin
                     message1(asmr_e_local_para_unreachable,s);
                   opr.localsym:=tvarsym(sym);
                   opr.localsymofs:=0;
+                  opr.localindexreg:=indexreg;
+                  opr.localgetoffset:=GetOffset;
                 end;
               if paramanager.push_addr_param(tvarsym(sym).varspez,tvarsym(sym).vartype.def,current_procinfo.procdef.proccalloption) then
                 SetSize(pointer_size,false);
@@ -1552,7 +1564,10 @@ end;
 end.
 {
   $Log$
-  Revision 1.73  2003-10-28 15:36:01  peter
+  Revision 1.74  2003-10-29 15:40:20  peter
+    * support indexing and offset retrieval for locals
+
+  Revision 1.73  2003/10/28 15:36:01  peter
     * absolute to object field supported, fixes tb0458
 
   Revision 1.72  2003/10/24 17:39:03  peter

+ 8 - 1
compiler/x86/aasmcpu.pas

@@ -770,6 +770,8 @@ implementation
             begin
               ppufile.getderef(o.localsymderef);
               o.localsymofs:=ppufile.getlongint;
+              o.localindexreg:=tregister(ppufile.getlongint);
+              o.localgetoffset:=(ppufile.getbyte<>0);
             end;
         end;
       end;
@@ -802,6 +804,8 @@ implementation
             begin
               ppufile.putderef(o.localsymderef);
               ppufile.putlongint(longint(o.localsymofs));
+              ppufile.putlongint(longint(o.localindexreg));
+              ppufile.putbyte(byte(o.localgetoffset));
             end;
         end;
       end;
@@ -2328,7 +2332,10 @@ implementation
 end.
 {
   $Log$
-  Revision 1.35  2003-10-23 14:44:07  peter
+  Revision 1.36  2003-10-29 15:40:20  peter
+    * support indexing and offset retrieval for locals
+
+  Revision 1.35  2003/10/23 14:44:07  peter
     * splitted buildderef and buildderefimpl to fix interface crc
       calculation
 

+ 7 - 2
compiler/x86/rax86.pas

@@ -567,6 +567,8 @@ begin
       (opcode=A_FDIVRP) or
       (opcode=A_FSUB) or
       (opcode=A_FSUBR) or
+      (opcode=A_FADD) or
+      (opcode=A_FADDP) or
       (opcode=A_FDIV) or
       (opcode=A_FDIVR)) then
      begin
@@ -672,7 +674,7 @@ begin
        OPR_SYMBOL:
          ai.loadsymbol(i-1,operands[i].opr.symbol,operands[i].opr.symofs);
        OPR_LOCAL :
-         ai.loadlocal(i-1,operands[i].opr.localsym,operands[i].opr.localsymofs);
+         ai.loadlocal(i-1,operands[i].opr.localsym,operands[i].opr.localsymofs,operands[i].opr.localindexreg,operands[i].opr.localgetoffset);
        OPR_REFERENCE:
          begin
            ai.loadref(i-1,operands[i].opr.ref);
@@ -733,7 +735,10 @@ end;
 end.
 {
   $Log$
-  Revision 1.11  2003-10-21 15:15:36  peter
+  Revision 1.12  2003-10-29 15:40:20  peter
+    * support indexing and offset retrieval for locals
+
+  Revision 1.11  2003/10/21 15:15:36  peter
     * taicpu_abstract.oper[] changed to pointers
 
   Revision 1.10  2003/10/01 20:34:51  peter