Selaa lähdekoodia

* support scalefactor for opr_local
* support reference with opr_local set, fixes tw2631

peter 22 vuotta sitten
vanhempi
commit
48ef24605a

+ 14 - 8
compiler/aasmtai.pas

@@ -156,7 +156,8 @@ interface
          top_symbol : (sym:tasmsymbol;symofs:longint);
          top_symbol : (sym:tasmsymbol;symofs:longint);
          top_bool   : (b:boolean);
          top_bool   : (b:boolean);
          { local varsym that will be inserted in pass_2 }
          { local varsym that will be inserted in pass_2 }
-         top_local  : (localsym:pointer;localsymderef:tderef;localsymofs:longint;localindexreg:tregister;localgetoffset:boolean);
+         top_local  : (localsym:pointer;localsymderef:tderef;localsymofs:longint;localindexreg:tregister;
+                       localscale:byte;localgetoffset:boolean);
       end;
       end;
       poper=^toper;
       poper=^toper;
 
 
@@ -465,7 +466,7 @@ interface
           procedure allocate_oper(opers:longint);
           procedure allocate_oper(opers:longint);
           procedure loadconst(opidx:longint;l:aword);
           procedure loadconst(opidx:longint;l:aword);
           procedure loadsymbol(opidx:longint;s:tasmsymbol;sofs:longint);
           procedure loadsymbol(opidx:longint;s:tasmsymbol;sofs:longint);
-          procedure loadlocal(opidx:longint;s:pointer;sofs:longint;indexreg:tregister;getoffset:boolean);
+          procedure loadlocal(opidx:longint;s:pointer;sofs:longint;indexreg:tregister;scale:byte;getoffset:boolean);
           procedure loadref(opidx:longint;const r:treference);
           procedure loadref(opidx:longint;const r:treference);
           procedure loadreg(opidx:longint;r:tregister);
           procedure loadreg(opidx:longint;r:tregister);
           procedure loadoper(opidx:longint;o:toper);
           procedure loadoper(opidx:longint;o:toper);
@@ -1590,7 +1591,7 @@ implementation
       end;
       end;
 
 
 
 
-    procedure taicpu_abstract.loadlocal(opidx:longint;s:pointer;sofs:longint;indexreg:tregister;getoffset:boolean);
+    procedure taicpu_abstract.loadlocal(opidx:longint;s:pointer;sofs:longint;indexreg:tregister;scale:byte;getoffset:boolean);
       begin
       begin
         if not assigned(s) then
         if not assigned(s) then
          internalerror(200204251);
          internalerror(200204251);
@@ -1602,6 +1603,7 @@ implementation
            localsym:=s;
            localsym:=s;
            localsymofs:=sofs;
            localsymofs:=sofs;
            localindexreg:=indexreg;
            localindexreg:=indexreg;
+           localscale:=scale;
            localgetoffset:=getoffset;
            localgetoffset:=getoffset;
            typ:=top_local;
            typ:=top_local;
          end;
          end;
@@ -1870,7 +1872,7 @@ implementation
             reg3 := getsupreg(oper[2]^.reg)
             reg3 := getsupreg(oper[2]^.reg)
           else
           else
             reg3 := 0;
             reg3 := 0;
-  
+
           supreg:=reg1;
           supreg:=reg1;
           if supregset_in(r,supreg) then
           if supregset_in(r,supreg) then
             begin
             begin
@@ -1882,7 +1884,7 @@ implementation
               //   lwz r23d, -60(r1)
               //   lwz r23d, -60(r1)
               //   add r23d, r21d, r22d
               //   add r23d, r21d, r22d
               //   stw r23d, -60(r1)
               //   stw r23d, -60(r1)
-  
+
               pos := get_insert_pos(Tai(previous),reg1,reg2,reg3,unusedregsint);
               pos := get_insert_pos(Tai(previous),reg1,reg2,reg3,unusedregsint);
               rgget(list,pos,R_SUBWHOLE,helpreg);
               rgget(list,pos,R_SUBWHOLE,helpreg);
               spill_registers := true;
               spill_registers := true;
@@ -1898,7 +1900,7 @@ implementation
               forward_allocation(tai(helpins.next),unusedregsint);
               forward_allocation(tai(helpins.next),unusedregsint);
 {             list.insertafter(tai_comment.Create(strpnew('Spilling!')),helpins);}
 {             list.insertafter(tai_comment.Create(strpnew('Spilling!')),helpins);}
             end;
             end;
-  
+
           for i := 1 to 2 do
           for i := 1 to 2 do
             if (oper[i]^.typ = top_reg) then
             if (oper[i]^.typ = top_reg) then
               begin
               begin
@@ -1913,7 +1915,7 @@ implementation
                     //   lwz r23d, -60(r1)
                     //   lwz r23d, -60(r1)
                     //   add r23d, r21d, r22d
                     //   add r23d, r21d, r22d
                     //   stw r23d, -60(r1)
                     //   stw r23d, -60(r1)
-  
+
                     pos := get_insert_pos(Tai(previous),reg1,reg2,reg3,unusedregsint);
                     pos := get_insert_pos(Tai(previous),reg1,reg2,reg3,unusedregsint);
                     rgget(list,pos,R_SUBWHOLE,helpreg);
                     rgget(list,pos,R_SUBWHOLE,helpreg);
                     spill_registers := true;
                     spill_registers := true;
@@ -2138,7 +2140,11 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.52  2003-10-29 21:06:39  jonas
+  Revision 1.53  2003-10-30 19:59:00  peter
+    * support scalefactor for opr_local
+    * support reference with opr_local set, fixes tw2631
+
+  Revision 1.52  2003/10/29 21:06:39  jonas
     * allow more than 3 args in the spilling routine
     * allow more than 3 args in the spilling routine
 
 
   Revision 1.51  2003/10/29 15:40:20  peter
   Revision 1.51  2003/10/29 15:40:20  peter

+ 149 - 95
compiler/i386/ra386int.pas

@@ -1021,13 +1021,13 @@ var
   tempstr,hs : string;
   tempstr,hs : string;
   typesize : longint;
   typesize : longint;
   code : integer;
   code : integer;
-  hreg,
-  oldbase : tregister;
+  hreg : tregister;
   GotStar,GotOffset,HadVar,
   GotStar,GotOffset,HadVar,
   GotPlus,Negative : boolean;
   GotPlus,Negative : boolean;
 Begin
 Begin
   Consume(AS_LBRACKET);
   Consume(AS_LBRACKET);
-  InitRef;
+  if not(opr.typ in [OPR_LOCAL,OPR_REFERENCE]) then
+    InitRef;
   GotStar:=false;
   GotStar:=false;
   GotPlus:=true;
   GotPlus:=true;
   GotOffset:=false;
   GotOffset:=false;
@@ -1053,15 +1053,29 @@ Begin
              l:=BuildRefConstExpression;
              l:=BuildRefConstExpression;
              GotPlus:=(prevasmtoken=AS_PLUS);
              GotPlus:=(prevasmtoken=AS_PLUS);
              GotStar:=(prevasmtoken=AS_STAR);
              GotStar:=(prevasmtoken=AS_STAR);
-             if GotStar then
-              opr.ref.scalefactor:=l
-             else
-              begin
-                if negative then
-                  Dec(opr.ref.offset,l)
-                else
-                  Inc(opr.ref.offset,l);
-              end;
+             case opr.typ of
+               OPR_LOCAL :
+                 begin
+                   if GotStar then
+                     Message(asmr_e_invalid_reference_syntax);
+                   if negative then
+                     Dec(opr.localsymofs,l)
+                   else
+                     Inc(opr.localsymofs,l);
+                 end;
+               OPR_REFERENCE :
+                 begin
+                   if GotStar then
+                    opr.ref.scalefactor:=l
+                   else
+                    begin
+                      if negative then
+                        Dec(opr.ref.offset,l)
+                      else
+                        Inc(opr.ref.offset,l);
+                    end;
+                  end;
+             end;
            end
            end
           else
           else
            Begin
            Begin
@@ -1112,29 +1126,6 @@ Begin
                    { should we allow ?? }
                    { should we allow ?? }
                  end;
                  end;
               end;
               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;
            end;
           GotOffset:=false;
           GotOffset:=false;
         end;
         end;
@@ -1172,26 +1163,55 @@ Begin
               end;
               end;
             AS_REGISTER :
             AS_REGISTER :
               begin
               begin
-                if opr.ref.scalefactor=0 then
-                if scale<>0 then
-                  begin
-                    opr.ref.scalefactor:=scale;
-                    scale:=0;
-                  end
-                else
-                 Message(asmr_e_wrong_scale_factor);
+                case opr.typ of
+                  OPR_REFERENCE :
+                    begin
+                      if opr.ref.scalefactor=0 then
+                        begin
+                          if scale<>0 then
+                            begin
+                              opr.ref.scalefactor:=scale;
+                              scale:=0;
+                            end
+                          else
+                           Message(asmr_e_wrong_scale_factor);
+                        end
+                      else
+                        Message(asmr_e_invalid_reference_syntax);
+                    end;
+                  OPR_LOCAL :
+                    begin
+                      if opr.localscale=0 then
+                        begin
+                          if scale<>0 then
+                            begin
+                              opr.localscale:=scale;
+                              scale:=0;
+                            end
+                          else
+                           Message(asmr_e_wrong_scale_factor);
+                        end
+                      else
+                        Message(asmr_e_invalid_reference_syntax);
+                    end;
+                end;
               end;
               end;
             else
             else
               Message(asmr_e_invalid_reference_syntax);
               Message(asmr_e_invalid_reference_syntax);
           end;
           end;
           if actasmtoken<>AS_REGISTER then
           if actasmtoken<>AS_REGISTER then
-           begin
-             if hs<>'' then
-              val(hs,l,code);
-             opr.ref.scalefactor:=l;
-             if l>9 then
-              Message(asmr_e_wrong_scale_factor);
-           end;
+            begin
+              if hs<>'' then
+                val(hs,l,code);
+              case opr.typ of
+                OPR_REFERENCE :
+                  opr.ref.scalefactor:=l;
+                OPR_LOCAL :
+                  opr.localscale:=l;
+              end;
+              if l>9 then
+                Message(asmr_e_wrong_scale_factor);
+            end;
           GotPlus:=false;
           GotPlus:=false;
           GotStar:=false;
           GotStar:=false;
         end;
         end;
@@ -1203,34 +1223,41 @@ Begin
             Message(asmr_e_invalid_reference_syntax);
             Message(asmr_e_invalid_reference_syntax);
           hreg:=actasmregister;
           hreg:=actasmregister;
           Consume(AS_REGISTER);
           Consume(AS_REGISTER);
-          if opr.typ=OPR_LOCAL then
-            begin
-              if (opr.localindexreg<>NR_NO) then
-                Message(asmr_e_multiple_index);
-              opr.localindexreg:=hreg;
-            end
-          else
-            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
+          { this register will be the index:
+             1. just read a *
+             2. next token is a *
+             3. base register is already used }
+          case opr.typ of
+            OPR_LOCAL :
+              begin
+                if (opr.localindexreg<>NR_NO) then
                   Message(asmr_e_multiple_index);
                   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;
+                opr.localindexreg:=hreg;
+                if scale<>0 then
+                  begin
+                    opr.localscale:=scale;
+                    scale:=0;
+                  end;
+              end;
+            OPR_REFERENCE :
+              begin
+                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;
+          end;
           GotPlus:=false;
           GotPlus:=false;
           GotStar:=false;
           GotStar:=false;
         end;
         end;
@@ -1260,22 +1287,46 @@ Begin
              else
              else
               Message(asmr_e_cant_have_multiple_relocatable_symbols);
               Message(asmr_e_cant_have_multiple_relocatable_symbols);
            end;
            end;
-          if GotStar then
-           opr.ref.scalefactor:=l
-          else if (prevasmtoken = AS_STAR) then
-           begin
-             if scale<>0 then
-               scale:=l*scale
-             else
-               scale:=l;
-           end
-          else
-           begin
-             if negative then
-               Dec(opr.ref.offset,l)
-             else
-               Inc(opr.ref.offset,l);
-           end;
+          case opr.typ of
+            OPR_REFERENCE :
+              begin
+                if GotStar then
+                 opr.ref.scalefactor:=l
+                else if (prevasmtoken = AS_STAR) then
+                 begin
+                   if scale<>0 then
+                     scale:=l*scale
+                   else
+                     scale:=l;
+                 end
+                else
+                 begin
+                   if negative then
+                     Dec(opr.ref.offset,l)
+                   else
+                     Inc(opr.ref.offset,l);
+                 end;
+              end;
+            OPR_LOCAL :
+              begin
+                if GotStar then
+                 opr.localscale:=l
+                else if (prevasmtoken = AS_STAR) then
+                 begin
+                   if scale<>0 then
+                     scale:=l*scale
+                   else
+                     scale:=l;
+                 end
+                else
+                 begin
+                   if negative then
+                     Dec(opr.localsymofs,l)
+                   else
+                     Inc(opr.localsymofs,l);
+                 end;
+              end;
+          end;
           GotPlus:=(prevasmtoken=AS_PLUS) or
           GotPlus:=(prevasmtoken=AS_PLUS) or
                    (prevasmtoken=AS_MINUS);
                    (prevasmtoken=AS_MINUS);
           if GotPlus then
           if GotPlus then
@@ -1543,7 +1594,6 @@ Begin
 
 
       AS_LBRACKET: { a variable reference, register ref. or a constant reference }
       AS_LBRACKET: { a variable reference, register ref. or a constant reference }
         Begin
         Begin
-          InitRef;
           BuildReference;
           BuildReference;
         end;
         end;
 
 
@@ -1921,7 +1971,11 @@ finalization
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.62  2003-10-29 16:47:18  peter
+  Revision 1.63  2003-10-30 19:59:00  peter
+    * support scalefactor for opr_local
+    * support reference with opr_local set, fixes tw2631
+
+  Revision 1.62  2003/10/29 16:47:18  peter
     * fix field offset in reference
     * fix field offset in reference
 
 
   Revision 1.61  2003/10/29 15:40:20  peter
   Revision 1.61  2003/10/29 15:40:20  peter

+ 8 - 1
compiler/ncgbas.pas

@@ -133,6 +133,7 @@ interface
       procedure ResolveRef(var op:toper);
       procedure ResolveRef(var op:toper);
         var
         var
           sym : tvarsym;
           sym : tvarsym;
+          scale : byte;
           getoffset : boolean;
           getoffset : boolean;
           indexreg : tregister;
           indexreg : tregister;
           sofs : longint;
           sofs : longint;
@@ -141,6 +142,7 @@ interface
             begin
             begin
               sofs:=op.localsymofs;
               sofs:=op.localsymofs;
               indexreg:=op.localindexreg;
               indexreg:=op.localindexreg;
+              scale:=op.localscale;
               getoffset:=op.localgetoffset;
               getoffset:=op.localgetoffset;
               sym:=tvarsym(pointer(op.localsym));
               sym:=tvarsym(pointer(op.localsym));
               case sym.localloc.loc of
               case sym.localloc.loc of
@@ -168,6 +170,7 @@ interface
                         reference_reset_base(op.ref^,sym.localloc.reference.index,
                         reference_reset_base(op.ref^,sym.localloc.reference.index,
                             sym.localloc.reference.offset+sofs);
                             sym.localloc.reference.offset+sofs);
                         op.ref^.index:=indexreg;
                         op.ref^.index:=indexreg;
+                        op.ref^.scalefactor:=scale;
                       end;
                       end;
                   end;
                   end;
                 LOC_REGISTER :
                 LOC_REGISTER :
@@ -399,7 +402,11 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.47  2003-10-29 15:40:20  peter
+  Revision 1.48  2003-10-30 19:59:00  peter
+    * support scalefactor for opr_local
+    * support reference with opr_local set, fixes tw2631
+
+  Revision 1.47  2003/10/29 15:40:20  peter
     * support indexing and offset retrieval for locals
     * support indexing and offset retrieval for locals
 
 
   Revision 1.46  2003/10/24 17:39:41  peter
   Revision 1.46  2003/10/24 17:39:41  peter

+ 7 - 2
compiler/rautils.pas

@@ -76,7 +76,7 @@ type
       OPR_CONSTANT  : (val:longint);
       OPR_CONSTANT  : (val:longint);
       OPR_SYMBOL    : (symbol:tasmsymbol;symofs:longint);
       OPR_SYMBOL    : (symbol:tasmsymbol;symofs:longint);
       OPR_REFERENCE : (ref:treference);
       OPR_REFERENCE : (ref:treference);
-      OPR_LOCAL     : (localsym:tvarsym;localsymofs:longint;localindexreg:tregister;localgetoffset:boolean);
+      OPR_LOCAL     : (localsym:tvarsym;localsymofs:longint;localindexreg:tregister;localscale:byte;localgetoffset:boolean);
       OPR_REGISTER  : (reg:tregister);
       OPR_REGISTER  : (reg:tregister);
 {$ifdef m68k}
 {$ifdef m68k}
       OPR_REGLIST   : (reglist:Tsupregset);
       OPR_REGLIST   : (reglist:Tsupregset);
@@ -899,6 +899,7 @@ Begin
                   opr.localsym:=tvarsym(sym);
                   opr.localsym:=tvarsym(sym);
                   opr.localsymofs:=0;
                   opr.localsymofs:=0;
                   opr.localindexreg:=indexreg;
                   opr.localindexreg:=indexreg;
+                  opr.localscale:=0;
                   opr.localgetoffset:=GetOffset;
                   opr.localgetoffset:=GetOffset;
                 end;
                 end;
               if paramanager.push_addr_param(tvarsym(sym).varspez,tvarsym(sym).vartype.def,current_procinfo.procdef.proccalloption) then
               if paramanager.push_addr_param(tvarsym(sym).varspez,tvarsym(sym).vartype.def,current_procinfo.procdef.proccalloption) then
@@ -1602,7 +1603,11 @@ end;
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.75  2003-10-29 16:47:18  peter
+  Revision 1.76  2003-10-30 19:59:00  peter
+    * support scalefactor for opr_local
+    * support reference with opr_local set, fixes tw2631
+
+  Revision 1.75  2003/10/29 16:47:18  peter
     * fix field offset in reference
     * fix field offset in reference
 
 
   Revision 1.74  2003/10/29 15:40:20  peter
   Revision 1.74  2003/10/29 15:40:20  peter

+ 7 - 1
compiler/x86/aasmcpu.pas

@@ -771,6 +771,7 @@ implementation
               ppufile.getderef(o.localsymderef);
               ppufile.getderef(o.localsymderef);
               o.localsymofs:=ppufile.getlongint;
               o.localsymofs:=ppufile.getlongint;
               o.localindexreg:=tregister(ppufile.getlongint);
               o.localindexreg:=tregister(ppufile.getlongint);
+              o.localscale:=ppufile.getbyte;
               o.localgetoffset:=(ppufile.getbyte<>0);
               o.localgetoffset:=(ppufile.getbyte<>0);
             end;
             end;
         end;
         end;
@@ -805,6 +806,7 @@ implementation
               ppufile.putderef(o.localsymderef);
               ppufile.putderef(o.localsymderef);
               ppufile.putlongint(longint(o.localsymofs));
               ppufile.putlongint(longint(o.localsymofs));
               ppufile.putlongint(longint(o.localindexreg));
               ppufile.putlongint(longint(o.localindexreg));
+              ppufile.putbyte(o.localscale);
               ppufile.putbyte(byte(o.localgetoffset));
               ppufile.putbyte(byte(o.localgetoffset));
             end;
             end;
         end;
         end;
@@ -2332,7 +2334,11 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.36  2003-10-29 15:40:20  peter
+  Revision 1.37  2003-10-30 19:59:00  peter
+    * support scalefactor for opr_local
+    * support reference with opr_local set, fixes tw2631
+
+  Revision 1.36  2003/10/29 15:40:20  peter
     * support indexing and offset retrieval for locals
     * support indexing and offset retrieval for locals
 
 
   Revision 1.35  2003/10/23 14:44:07  peter
   Revision 1.35  2003/10/23 14:44:07  peter

+ 7 - 2
compiler/x86/rax86.pas

@@ -674,7 +674,8 @@ begin
        OPR_SYMBOL:
        OPR_SYMBOL:
          ai.loadsymbol(i-1,operands[i].opr.symbol,operands[i].opr.symofs);
          ai.loadsymbol(i-1,operands[i].opr.symbol,operands[i].opr.symofs);
        OPR_LOCAL :
        OPR_LOCAL :
-         ai.loadlocal(i-1,operands[i].opr.localsym,operands[i].opr.localsymofs,operands[i].opr.localindexreg,operands[i].opr.localgetoffset);
+         ai.loadlocal(i-1,operands[i].opr.localsym,operands[i].opr.localsymofs,operands[i].opr.localindexreg,
+                      operands[i].opr.localscale,operands[i].opr.localgetoffset);
        OPR_REFERENCE:
        OPR_REFERENCE:
          begin
          begin
            ai.loadref(i-1,operands[i].opr.ref);
            ai.loadref(i-1,operands[i].opr.ref);
@@ -735,7 +736,11 @@ end;
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.12  2003-10-29 15:40:20  peter
+  Revision 1.13  2003-10-30 19:59:00  peter
+    * support scalefactor for opr_local
+    * support reference with opr_local set, fixes tw2631
+
+  Revision 1.12  2003/10/29 15:40:20  peter
     * support indexing and offset retrieval for locals
     * support indexing and offset retrieval for locals
 
 
   Revision 1.11  2003/10/21 15:15:36  peter
   Revision 1.11  2003/10/21 15:15:36  peter