瀏覽代碼

* Take advantage of our new with statement optimization

daniel 21 年之前
父節點
當前提交
46d241a666
共有 5 個文件被更改,包括 592 次插入500 次删除
  1. 62 56
      compiler/ptconst.pas
  2. 16 11
      compiler/raatt.pas
  3. 413 347
      compiler/rgobj.pas
  4. 14 10
      compiler/scanner.pas
  5. 87 76
      compiler/x86/cgx86.pas

+ 62 - 56
compiler/ptconst.pas

@@ -257,13 +257,13 @@ implementation
               p:=comp_expr(true);
               case p.nodetype of
                  loadvmtaddrn:
-                   begin
-                      if not(tobjectdef(tclassrefdef(p.resulttype.def).pointertype.def).is_related(
-                        tobjectdef(tclassrefdef(t.def).pointertype.def))) then
-                        Message(cg_e_illegal_expression);
-                      curconstSegment.concat(Tai_const_symbol.Create(objectlibrary.newasmsymboldata(tobjectdef(
-                        tclassrefdef(p.resulttype.def).pointertype.def).vmt_mangledname)));
-                   end;
+                   with Tclassrefdef(p.resulttype.def) do
+                     begin
+                        if not Tobjectdef(pointertype.def).is_related(Tobjectdef(pointertype.def)) then
+                          message(cg_e_illegal_expression);
+                        curconstSegment.concat(Tai_const_symbol.Create(objectlibrary.newasmsymboldata(
+                          Tobjectdef(pointertype.def).vmt_mangledname)));
+                     end;
                  niln:
                    curconstSegment.concat(Tai_const.Create_32bit(0));
                  else Message(cg_e_illegal_expression);
@@ -273,24 +273,25 @@ implementation
          pointerdef:
            begin
               p:=comp_expr(true);
-              if (p.nodetype=typeconvn) and
-                 (ttypeconvnode(p).left.nodetype in [addrn,niln]) and
-                 equal_defs(t.def,p.resulttype.def) then
-                begin
-                   hp:=ttypeconvnode(p).left;
-                   ttypeconvnode(p).left:=nil;
-                   p.free;
-                   p:=hp;
-                end;
+              if (p.nodetype=typeconvn) then
+                with Ttypeconvnode(p) do
+                  if (left.nodetype in [addrn,niln]) and equal_defs(t.def,p.resulttype.def) then
+                    begin
+                      hp:=left;
+                      left:=nil;
+                      p.free;
+                      p:=hp;
+                    end;
               { allows horrible ofs(typeof(TButton)^) code !! }
-              if (p.nodetype=addrn) and
-                 (taddrnode(p).left.nodetype=derefn) then
-                begin
-                   hp:=tderefnode(taddrnode(p).left).left;
-                   tderefnode(taddrnode(p).left).left:=nil;
-                   p.free;
-                   p:=hp;
-                end;
+              if (p.nodetype=addrn) then
+                with Taddrnode(p) do
+                  if left.nodetype=derefn then
+                    begin
+                      hp:=tderefnode(left).left;
+                      tderefnode(left).left:=nil;
+                      p.free;
+                      p:=hp;
+                   end;
               { const pointer ? }
 {$warning 32bit pointer assumption}
               if (p.nodetype = pointerconstn) then
@@ -947,37 +948,39 @@ implementation
                              consume_all_until(_SEMICOLON);
                           end
                         else
-                          begin
-                             { check position }
-                             if tvarsym(srsym).fieldoffset<aktpos then
-                               Message(parser_e_invalid_record_const);
-
-                             { check in VMT needs to be added for TP mode }
-                             if not(m_fpc in aktmodeswitches) and
-                                (oo_has_vmt in tobjectdef(t.def).objectoptions) and
-                                (tobjectdef(t.def).vmt_offset<tvarsym(srsym).fieldoffset) then
-                               begin
-                                 for i:=1 to tobjectdef(t.def).vmt_offset-aktpos do
-                                   curconstsegment.concat(tai_const.create_8bit(0));
-                                 curconstsegment.concat(tai_const_symbol.createname(tobjectdef(t.def).vmt_mangledname));
-                                 { this is more general }
-                                 aktpos:=tobjectdef(t.def).vmt_offset + pointer_size;
-                               end;
-
-                             { if needed fill }
-                             if tvarsym(srsym).fieldoffset>aktpos then
-                               for i:=1 to tvarsym(srsym).fieldoffset-aktpos do
-                                 curconstSegment.concat(Tai_const.Create_8bit(0));
-
-                             { new position }
-                             aktpos:=tvarsym(srsym).fieldoffset+tvarsym(srsym).vartype.def.size;
-
-                             { read the data }
-                             readtypedconst(tvarsym(srsym).vartype,nil,writable);
-
-                             if token=_SEMICOLON then
-                               consume(_SEMICOLON)
-                             else break;
+                          with Tvarsym(srsym) do
+                            begin
+                               { check position }
+                               if fieldoffset<aktpos then
+                                 message(parser_e_invalid_record_const);
+
+                               { check in VMT needs to be added for TP mode }
+                               with Tobjectdef(t.def) do
+                                 if not(m_fpc in aktmodeswitches) and
+                                    (oo_has_vmt in objectoptions) and
+                                    (vmt_offset<fieldoffset) then
+                                   begin
+                                     for i:=1 to vmt_offset-aktpos do
+                                       curconstsegment.concat(tai_const.create_8bit(0));
+                                     curconstsegment.concat(tai_const_symbol.createname(vmt_mangledname));
+                                     { this is more general }
+                                     aktpos:=vmt_offset + pointer_size;
+                                   end;
+  
+                               { if needed fill }
+                               if fieldoffset>aktpos then
+                                 for i:=1 to fieldoffset-aktpos do
+                                   curconstSegment.concat(Tai_const.Create_8bit(0));
+
+                               { new position }
+                               aktpos:=fieldoffset+vartype.def.size;
+  
+                               { read the data }
+                               readtypedconst(vartype,nil,writable);
+
+                               if token=_SEMICOLON then
+                                 consume(_SEMICOLON)
+                               else break;
                           end;
                      end;
                    if not(m_fpc in aktmodeswitches) and
@@ -1013,7 +1016,10 @@ implementation
 end.
 {
   $Log$
-  Revision 1.77  2003-12-29 12:48:39  jonas
+  Revision 1.78  2004-02-07 23:28:34  daniel
+    * Take advantage of our new with statement optimization
+
+  Revision 1.77  2003/12/29 12:48:39  jonas
     + support for currency typed constants if currency=int64. Warning: does
       not work properly for extreme values if bestreal <= double
 

+ 16 - 11
compiler/raatt.pas

@@ -1373,19 +1373,21 @@ unit raatt;
                        begin
                          case sym.typ of
                            varsym :
-                             begin
-                               if sym.owner.symtabletype in [localsymtable,parasymtable] then
-                                Message(asmr_e_no_local_or_para_allowed);
-                               hs:=tvarsym(sym).mangledname;
-                             end;
+                             with Tvarsym(sym) do
+                               begin
+                                 if owner.symtabletype in [localsymtable,parasymtable] then
+                                  Message(asmr_e_no_local_or_para_allowed);
+                                 hs:=mangledname;
+                               end;
                            typedconstsym :
                              hs:=ttypedconstsym(sym).mangledname;
                            procsym :
-                             begin
-                               if Tprocsym(sym).procdef_count>1 then
-                                Message(asmr_w_calling_overload_func);
-                               hs:=tprocsym(sym).first_procdef.mangledname;
-                             end;
+                             with Tprocsym(sym) do
+                               begin
+                                 if procdef_count>1 then
+                                   message(asmr_w_calling_overload_func);
+                                 hs:=first_procdef.mangledname;
+                               end;
                            typesym :
                              begin
                                if not(ttypesym(sym).restype.def.deftype in [recorddef,objectdef]) then
@@ -1492,7 +1494,10 @@ end.
 
 {
   $Log$
-  Revision 1.8  2003-12-25 01:25:43  peter
+  Revision 1.9  2004-02-07 23:28:34  daniel
+    * Take advantage of our new with statement optimization
+
+  Revision 1.8  2003/12/25 01:25:43  peter
     * sparc assembler reader updates
 
   Revision 1.7  2003/12/08 17:43:57  florian

+ 413 - 347
compiler/rgobj.pas

@@ -221,12 +221,18 @@ unit rgobj;
         procedure ungetregisterinline(list:Taasmoutput;position:Tai;r:Tregister);
         procedure add_constraints(reg:Tregister);virtual;
 
-        procedure DoSpillRead(list : taasmoutput;instr : taicpu_abstract;pos: tai; regidx: longint;
-         const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo);virtual;
-        procedure DoSpillWritten(list : taasmoutput;instr : taicpu_abstract;pos: tai; regidx: longint;
-         const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo);virtual;
-        procedure DoSpillReadWritten(list : taasmoutput;instr : taicpu_abstract;pos: tai; regidx: longint;
-         const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo);virtual;
+        procedure do_spill_read(list:Taasmoutput;instr:Taicpu_abstract;
+                                pos:Tai;regidx:word;
+                                const spilltemplist:Tspill_temp_list;
+                                const regs:Tspillregsinfo);virtual;
+        procedure do_spill_written(list:Taasmoutput;instr:Taicpu_abstract;
+                                   pos:Tai;regidx:word;
+                                   const spilltemplist:Tspill_temp_list;
+                                   const regs:Tspillregsinfo);virtual;
+        procedure do_spill_readwritten(list:Taasmoutput;instr:Taicpu_abstract;
+                                       pos:Tai;regidx:word;
+                                       const spilltemplist:Tspill_temp_list;
+                                       const regs:Tspillregsinfo);virtual;
 
         function instr_spill_register(list:Taasmoutput;
                                       instr:taicpu_abstract;
@@ -438,12 +444,13 @@ implementation
       if reginfo<>nil then
         begin
           for i:=0 to maxreg-1 do
-            begin
-              if reginfo[i].adjlist<>nil then
-                dispose(reginfo[i].adjlist,done);
-              if reginfo[i].movelist<>nil then
-                dispose(reginfo[i].movelist);
-            end;
+            with reginfo[i] do
+              begin
+                if adjlist<>nil then
+                  dispose(adjlist,done);
+                if movelist<>nil then
+                  dispose(movelist);
+              end;
           freemem(reginfo);
           reginfo:=nil;
         end;
@@ -575,9 +582,12 @@ implementation
       procedure addadj(u,v:Tsuperregister);
 
       begin
-        if reginfo[u].adjlist=nil then
-          new(reginfo[u].adjlist,init);
-        reginfo[u].adjlist^.add(v);
+        with reginfo[u] do
+          begin
+            if adjlist=nil then
+              new(adjlist,init);
+            adjlist^.add(v);
+          end;
       end;
 
     begin
@@ -599,9 +609,10 @@ implementation
     var i:word;
 
     begin
-      if live_registers.length>0 then
-        for i:=0 to live_registers.length-1 do
-          add_edge(u,live_registers.buf^[i]);
+      with live_registers do
+        if length>0 then
+          for i:=0 to length-1 do
+            add_edge(u,buf^[i]);
     end;
 
 {$ifdef EXTDEBUG}
@@ -647,19 +658,22 @@ implementation
     var cursize:cardinal;
 
     begin
-      if reginfo[u].movelist=nil then
+      with reginfo[u] do
         begin
-          getmem(reginfo[u].movelist,64);
-          reginfo[u].movelist^.count:=0;
-        end
-      else
-        begin
-	  cursize:=memsize(reginfo[u].movelist);
-	  if (4*(reginfo[u].movelist^.count+1)=cursize) then
-            reallocmem(reginfo[u].movelist,cursize*2);
+          if movelist=nil then
+            begin
+              getmem(movelist,64);
+              movelist^.count:=0;
+            end
+          else
+            begin
+              cursize:=memsize(movelist);
+              if (4*(movelist^.count+1)=cursize) then
+                reallocmem(movelist,cursize*2);
+            end;
+          movelist^.data[movelist^.count]:=data;
+          inc(movelist^.count);
         end;
-      reginfo[u].movelist^.data[reginfo[u].movelist^.count]:=data;
-      inc(reginfo[u].movelist^.count);
     end;
 
 
@@ -669,11 +683,12 @@ implementation
       begin
         supreg:=getsupreg(r);
         if supreg>=first_imaginary then
-          begin
-            if not assigned(reginfo[supreg].live_start) then
-              reginfo[supreg].live_start:=instr;
-            reginfo[supreg].live_end:=instr;
-          end;
+          with reginfo[supreg] do
+            begin
+              if not assigned(live_start) then
+                live_start:=instr;
+              live_end:=instr;
+            end;
       end;
 
 
@@ -710,13 +725,15 @@ implementation
 
     begin
       move_related:=false;
-      if reginfo[n].movelist<>nil then
-        for i:=0 to reginfo[n].movelist^.count-1 do
-          if Tmoveins(reginfo[n].movelist^.data[i]).moveset in [ms_worklist_moves,ms_active_moves] then
-            begin
-              move_related:=true;
-              break;
-            end;
+      with reginfo[n] do
+        if movelist<>nil then
+          with movelist^ do
+            for i:=0 to count-1 do
+              if Tmoveins(data[i]).moveset in [ms_worklist_moves,ms_active_moves] then
+                begin
+                  move_related:=true;
+                  break;
+                end;
     end;
 
     procedure Trgobj.sort_simplify_worklist;
@@ -730,39 +747,42 @@ implementation
         adji,adjj:Psuperregisterworklist;
 
     begin
-      if simplifyworklist.length<2 then
-        exit;
-      p:=1;
-      while 2*p<simplifyworklist.length do
-        p:=2*p;
-      while p<>0 do
+      with simplifyworklist do
         begin
-          for h:=0 to simplifyworklist.length-p-1 do
+          if length<2 then
+            exit;
+          p:=1;
+          while 2*p<length do
+            p:=2*p;
+          while p<>0 do
             begin
-              i:=h;
-              repeat
-                j:=i+p;
-                adji:=reginfo[simplifyworklist.buf^[i]].adjlist;
-                adjj:=reginfo[simplifyworklist.buf^[j]].adjlist;
-                if adji=nil then
-                  leni:=0
-                else
-                  leni:=adji^.length;
-                if adjj=nil then
-                  lenj:=0
-                else
-                  lenj:=adjj^.length;
-                if lenj>=leni then
-                  break;
-                t:=simplifyworklist.buf^[i];
-                simplifyworklist.buf^[i]:=simplifyworklist.buf^[j];
-                simplifyworklist.buf^[j]:=t;
-                if i<p then
-                  break;
-                dec(i,p)
-              until false;
+              for h:=0 to length-p-1 do
+                begin
+                  i:=h;
+                  repeat
+                    j:=i+p;
+                    adji:=reginfo[buf^[i]].adjlist;
+                    adjj:=reginfo[buf^[j]].adjlist;
+                    if adji=nil then
+                      leni:=0
+                    else
+                      leni:=adji^.length;
+                    if adjj=nil then
+                      lenj:=0
+                    else
+                      lenj:=adjj^.length;
+                    if lenj>=leni then
+                      break;
+                    t:=buf^[i];
+                    buf^[i]:=buf^[j];
+                    buf^[j]:=t;
+                    if i<p then
+                      break;
+                    dec(i,p)
+                  until false;
+                end;
+              p:=p shr 1;
             end;
-          p:=p shr 1;
         end;
     end;
 
@@ -774,18 +794,19 @@ implementation
       {If we have 7 cpu registers, and the degree of a node is 7, we cannot
        assign it to any of the registers, thus it is significant.}
       for n:=first_imaginary to maxreg-1 do
-        begin
-          if reginfo[n].adjlist=nil then
-            reginfo[n].degree:=0
-          else
-            reginfo[n].degree:=reginfo[n].adjlist^.length;
-          if reginfo[n].degree>=usable_registers_cnt then
-            spillworklist.add(n)
-          else if move_related(n) then
-            freezeworklist.add(n)
-          else
-            simplifyworklist.add(n);
-	end;
+        with reginfo[n] do
+          begin
+            if adjlist=nil then
+              degree:=0
+            else
+              degree:=adjlist^.length;
+            if degree>=usable_registers_cnt then
+              spillworklist.add(n)
+            else if move_related(n) then
+              freezeworklist.add(n)
+            else
+              simplifyworklist.add(n);
+          end;
       sort_simplify_worklist;
     end;
 
@@ -809,53 +830,57 @@ implementation
         i:cardinal;
 
     begin
-      if reginfo[n].movelist<>nil then
-        for i:=0 to reginfo[n].movelist^.count-1 do
-          begin
-            m:=reginfo[n].movelist^.data[i];
-            if Tmoveins(m).moveset in [ms_worklist_moves,ms_active_moves] then
-              if Tmoveins(m).moveset=ms_active_moves then
-                begin
-                  {Move m from the set active_moves to the set worklist_moves.}
-                  active_moves.remove(m);
-                  Tmoveins(m).moveset:=ms_worklist_moves;
-                  worklist_moves.concat(m);
-                end;
+      with reginfo[n] do
+        if movelist<>nil then
+          for i:=0 to movelist^.count-1 do
+            begin
+              m:=movelist^.data[i];
+              if Tmoveins(m).moveset in [ms_worklist_moves,ms_active_moves] then
+                if Tmoveins(m).moveset=ms_active_moves then
+                  begin
+                    {Move m from the set active_moves to the set worklist_moves.}
+                    active_moves.remove(m);
+                    Tmoveins(m).moveset:=ms_worklist_moves;
+                    worklist_moves.concat(m);
+                  end;
           end;
     end;
 
-    procedure trgobj.decrement_degree(m:Tsuperregister);
+    procedure Trgobj.decrement_degree(m:Tsuperregister);
 
     var adj : Psuperregisterworklist;
-        d,n : tsuperregister;
-        i : word;
+        n : tsuperregister;
+        d,i : word;
 
     begin
-      d:=reginfo[m].degree;
-      if d=0 then
-        internalerror(200312151);
-      dec(reginfo[m].degree);
-      if d=usable_registers_cnt then
+      with reginfo[m] do
         begin
-          {Enable moves for m.}
-          enable_moves(m);
-          {Enable moves for adjacent.}
-          adj:=reginfo[m].adjlist;
-          if adj<>nil then
-            for i:=1 to adj^.length do
-              begin
-                n:=adj^.buf^[i-1];
-                if reginfo[n].flags*[ri_selected,ri_coalesced]<>[] then
-                  enable_moves(n);
-              end;
-          {Remove the node from the spillworklist.}
-          if not spillworklist.delete(m) then
-            internalerror(200310145);
-
-          if move_related(m) then
-            freezeworklist.add(m)
-          else
-            simplifyworklist.add(m);
+          d:=degree;
+          if d=0 then
+            internalerror(200312151);
+          dec(degree);
+          if d=usable_registers_cnt then
+            begin
+              {Enable moves for m.}
+              enable_moves(m);
+              {Enable moves for adjacent.}
+              adj:=adjlist;
+              if adj<>nil then
+                for i:=1 to adj^.length do
+                  begin
+                    n:=adj^.buf^[i-1];
+                    if reginfo[n].flags*[ri_selected,ri_coalesced]<>[] then
+                      enable_moves(n);
+                  end;
+              {Remove the node from the spillworklist.}
+              if not spillworklist.delete(m) then
+                internalerror(200310145);
+    
+              if move_related(m) then
+                freezeworklist.add(m)
+              else
+                simplifyworklist.add(m);
+            end;
         end;
     end;
 
@@ -872,8 +897,11 @@ implementation
 
       {Push it on the selectstack.}
       selectstack.add(m);
-      include(reginfo[m].flags,ri_selected);
-      adj:=reginfo[m].adjlist;
+      with reginfo[m] do
+        begin
+          include(flags,ri_selected);
+          adj:=adjlist;
+        end;
       if adj<>nil then
         for i:=1 to adj^.length do
           begin
@@ -922,19 +950,21 @@ implementation
         n : tsuperregister;
 
     begin
-      adjacent_ok:=true;
-      adj:=reginfo[v].adjlist;
-      if adj<>nil then
-        for i:=1 to adj^.length do
-          begin
-            n:=adj^.buf^[i-1];
-            if (reginfo[v].flags*[ri_coalesced,ri_selected]=[]) and
-               not ok(n,u) then
+      with reginfo[v] do
+        begin
+          adjacent_ok:=true;
+          adj:=adjlist;
+          if adj<>nil then
+            for i:=1 to adj^.length do
               begin
-                adjacent_ok:=false;
-                break;
+                n:=adj^.buf^[i-1];
+                if (flags*[ri_coalesced,ri_selected]=[]) and not ok(n,u) then
+                  begin
+                    adjacent_ok:=false;
+                    break;
+                  end;
               end;
-          end;
+        end;
     end;
 
     function trgobj.conservative(u,v:Tsuperregister):boolean;
@@ -947,18 +977,21 @@ implementation
     begin
       k:=0;
       supregset_reset(done,false);
-      adj:=reginfo[u].adjlist;
-      if adj<>nil then
-        for i:=1 to adj^.length do
-          begin
-            n:=adj^.buf^[i-1];
-            if reginfo[u].flags*[ri_coalesced,ri_selected]=[] then
+      with reginfo[u] do
+        begin
+          adj:=adjlist;
+          if adj<>nil then
+            for i:=1 to adj^.length do
               begin
-                supregset_include(done,n);
-                if reginfo[n].degree>=usable_registers_cnt then
-                  inc(k);
+                n:=adj^.buf^[i-1];
+                if flags*[ri_coalesced,ri_selected]=[] then
+                  begin
+                    supregset_include(done,n);
+                    if reginfo[n].degree>=usable_registers_cnt then
+                      inc(k);
+                  end;
               end;
-          end;
+        end;
       adj:=reginfo[v].adjlist;
       if adj<>nil then
         for i:=1 to adj^.length do
@@ -1190,18 +1223,21 @@ implementation
         will never converge (PFV) }
       max:=0;
       p:=0;
-      {Safe: This procedure is only called if length<>0}
-      for i:=0 to spillworklist.length-1 do
+      with spillworklist do
         begin
-          adj:=reginfo[spillworklist.buf^[i]].adjlist;
-          if assigned(adj) and (adj^.length>max) then
+          {Safe: This procedure is only called if length<>0}
+          for i:=0 to length-1 do
             begin
-              p:=i;
-              max:=adj^.length;
+              adj:=reginfo[buf^[i]].adjlist;
+              if assigned(adj) and (adj^.length>max) then
+                begin
+                  p:=i;
+                  max:=adj^.length;
+                end;
             end;
+          n:=buf^[p];
+          deleteidx(p);
         end;
-      n:=spillworklist.buf^[p];
-      spillworklist.deleteidx(p);
 
       simplifyworklist.add(n);
       freeze_moves(n);
@@ -1312,11 +1348,12 @@ implementation
       constrained_moves.destroy;
       constrained_moves:=nil;
       for i:=0 to maxreg-1 do
-        if reginfo[i].movelist<>nil then
-          begin
-            dispose(reginfo[i].movelist);
-            reginfo[i].movelist:=nil;
-          end;
+        with reginfo[i] do
+          if movelist<>nil then
+            begin
+              dispose(movelist);
+              movelist:=nil;
+            end;
     end;
 
 
@@ -1398,31 +1435,32 @@ implementation
       begin
         { Insert regallocs for all imaginary registers }
         for supreg:=first_imaginary to maxreg-1 do
-          begin
-            r:=newreg(regtype,supreg,reginfo[supreg].subreg);
-            if assigned(reginfo[supreg].live_start) then
-              begin
+          with reginfo[supreg] do
+            begin
+              r:=newreg(regtype,supreg,subreg);
+              if assigned(live_start) then
+                begin
 {$ifdef EXTDEBUG}
-                if reginfo[supreg].live_start=reginfo[supreg].live_end then
-                  Comment(V_Warning,'Register '+std_regname(r)+' is only used once');
+                  if live_start=live_end then
+                    Comment(V_Warning,'Register '+std_regname(r)+' is only used once');
 {$endif EXTDEBUG}
-                list.insertbefore(Tai_regalloc.alloc(r),reginfo[supreg].live_start);
-                { Insert live end deallocation before reg allocations
+                  list.insertbefore(Tai_regalloc.alloc(r),live_start);
+                  { Insert live end deallocation before reg allocations
                   to reduce conflicts }
-                p:=reginfo[supreg].live_end;
-                while assigned(p) and
-                      assigned(p.previous) and
-                      (tai(p.previous).typ=ait_regalloc) and
-                      tai_regalloc(p.previous).allocation and
-                      (tai_regalloc(p.previous).reg<>r) do
-                  p:=tai(p.previous);
-                list.insertbefore(Tai_regalloc.dealloc(r),p);
-              end
+                  p:=live_end;
+                  while assigned(p) and
+                        assigned(p.previous) and
+                        (tai(p.previous).typ=ait_regalloc) and
+                         tai_regalloc(p.previous).allocation and
+                        (tai_regalloc(p.previous).reg<>r) do
+                    p:=tai(p.previous);
+                  list.insertbefore(Tai_regalloc.dealloc(r),p);
+                end
 {$ifdef EXTDEBUG}
-            else
-              Comment(V_Warning,'Register '+std_regname(r)+' not used');
+              else
+                Comment(V_Warning,'Register '+std_regname(r)+' not used');
 {$endif EXTDEBUG}
-          end;
+            end;
       end;
 
 
@@ -1446,18 +1484,19 @@ implementation
         while assigned(p) do
           begin
             if p.typ=ait_regalloc then
-              begin
-                if (getregtype(Tai_regalloc(p).reg)=regtype) then
-                  begin
-                    supreg:=getsupreg(Tai_regalloc(p).reg);
-                    if Tai_regalloc(p).allocation then
-                      live_registers.add(supreg)
-                    else
-                      live_registers.delete(supreg);
-                    add_edges_used(supreg);
-                    add_constraints(Tai_regalloc(p).reg);
-                  end;
-              end;
+              with Tai_regalloc(p) do
+                begin
+                  if (getregtype(reg)=regtype) then
+                    begin
+                      supreg:=getsupreg(reg);
+                      if allocation then
+                        live_registers.add(supreg)
+                      else
+                        live_registers.delete(supreg);
+                      add_edges_used(supreg);
+                      add_constraints(reg);
+                    end;
+                end;
             add_cpu_interferences(p);
             p:=Tai(p.next);
           end;
@@ -1480,7 +1519,6 @@ implementation
       var
         hp,p,q:Tai;
         i:shortint;
-        r:Preference;
 {$ifdef arm}
         so:pshifterop;
 {$endif arm}
@@ -1495,72 +1533,75 @@ implementation
           begin
             case p.typ of
               ait_regalloc:
-                begin
-                  if (getregtype(Tai_regalloc(p).reg)=regtype) then
-                    setsupreg(Tai_regalloc(p).reg,reginfo[getsupreg(Tai_regalloc(p).reg)].colour);
-
-                  {
-                    Remove sequences of release and
-                    allocation of the same register like:
-
-                       # Register X released
-                       # Register X allocated
-                  }
-                  if assigned(p.previous) and
-                     (Tai(p.previous).typ=ait_regalloc) and
-                     (Tai_regalloc(p.previous).reg=Tai_regalloc(p).reg) and
-                     { allocation,deallocation or deallocation,allocation }
-                     (Tai_regalloc(p.previous).allocation xor Tai_regalloc(p).allocation) then
-                    begin
-                      q:=Tai(p.next);
-                      hp:=tai(p.previous);
-                      list.remove(hp);
-                      hp.free;
-                      list.remove(p);
-                      p.free;
-                      p:=q;
-                      continue;
-                    end;
-                end;
+                with Tai_regalloc(p) do
+                  begin
+                    if (getregtype(reg)=regtype) then
+                      setsupreg(reg,reginfo[getsupreg(reg)].colour);
+  
+                    {
+                      Remove sequences of release and
+                      allocation of the same register like:
+  
+                         # Register X released
+                         # Register X allocated
+                    }
+                    if assigned(previous) and
+                       (Tai(previous).typ=ait_regalloc) and
+                       (Tai_regalloc(previous).reg=reg) and
+                       { allocation,deallocation or deallocation,allocation }
+                       (Tai_regalloc(previous).allocation xor allocation) then
+                      begin
+                        q:=Tai(next);
+                        hp:=tai(previous);
+                        list.remove(hp);
+                        hp.free;
+                        list.remove(p);
+                        p.free;
+                        p:=q;
+                        continue;
+                      end;
+                  end;
               ait_instruction:
-                begin
-                  for i:=0 to Taicpu_abstract(p).ops-1 do
-                    case Taicpu_abstract(p).oper[i]^.typ of
-                      Top_reg:
-                         if (getregtype(Taicpu_abstract(p).oper[i]^.reg)=regtype) then
-                           setsupreg(Taicpu_abstract(p).oper[i]^.reg,reginfo[getsupreg(Taicpu_abstract(p).oper[i]^.reg)].colour);
-                      Top_ref:
-                        begin
-                          if regtype=R_INTREGISTER then
+                with Taicpu_abstract(p) do
+                  begin
+                    for i:=0 to ops-1 do
+                      with oper[i]^ do
+                        case typ of
+                          Top_reg:
+                             if (getregtype(reg)=regtype) then
+                               setsupreg(reg,reginfo[getsupreg(reg)].colour);
+                          Top_ref:
                             begin
-                              r:=Taicpu_abstract(p).oper[i]^.ref;
-                              if r^.base<>NR_NO then
-                                setsupreg(r^.base,reginfo[getsupreg(r^.base)].colour);
-                              if r^.index<>NR_NO then
-                                setsupreg(r^.index,reginfo[getsupreg(r^.index)].colour);
+                              if regtype=R_INTREGISTER then
+                                with ref^ do
+                                  begin
+                                    if base<>NR_NO then
+                                      setsupreg(base,reginfo[getsupreg(base)].colour);
+                                    if index<>NR_NO then
+                                      setsupreg(index,reginfo[getsupreg(index)].colour);
+                                  end;
                             end;
-                        end;
 {$ifdef arm}
-                      Top_shifterop:
-                        begin
-                          so:=Taicpu_abstract(p).oper[i]^.shifterop;
-                          if so^.rs<>NR_NO then
-                            setsupreg(so^.rs,reginfo[getsupreg(so^.rs)].colour);
-                        end;
+                          Top_shifterop:
+                            begin
+                              so:=shifterop;
+                              if so^.rs<>NR_NO then
+                                setsupreg(so^.rs,reginfo[getsupreg(so^.rs)].colour);
+                            end;
 {$endif arm}
-                    end;
-
-                  { Maybe the operation can be removed when
-                    it is a move and both arguments are the same }
-                  if Taicpu_abstract(p).is_same_reg_move then
-                    begin
-                      q:=Tai(p.next);
-                      list.remove(p);
-                      p.free;
-                      p:=q;
-                      continue;
-                    end;
-                end;
+                        end;
+  
+                    { Maybe the operation can be removed when
+                      it is a move and both arguments are the same }
+                    if is_same_reg_move then
+                      begin
+                        q:=Tai(p.next);
+                        list.remove(p);
+                        p.free;
+                        p:=q;
+                        continue;
+                      end;
+                  end;
             end;
             p:=Tai(p.next);
           end;
@@ -1648,16 +1689,17 @@ implementation
         { Allocate temps and insert in front of the list }
         templist:=taasmoutput.create;
         {Safe: this procedure is only called if there are spilled nodes.}
-        for i:=0 to spillednodes.length-1 do
-          begin
-            t:=spillednodes.buf^[i];
-            {Alternative representation.}
-            supregset_include(regs_to_spill_set,t);
-            {Clear all interferences of the spilled register.}
-            clear_interferences(t);
-            {Get a temp for the spilled register}
-            tg.gettemp(templist,4,tt_noreuse,spill_temps^[t]);
-          end;
+        with spillednodes do
+          for i:=0 to length-1 do
+            begin
+              t:=buf^[i];
+              {Alternative representation.}
+              supregset_include(regs_to_spill_set,t);
+              {Clear all interferences of the spilled register.}
+              clear_interferences(t);
+              {Get a temp for the spilled register}
+              tg.gettemp(templist,4,tt_noreuse,spill_temps^[t]);
+            end;
         list.insertlistafter(headertai,templist);
         templist.free;
         { Walk through all instructions, we can start with the headertai,
@@ -1667,86 +1709,105 @@ implementation
           begin
             case p.typ of
               ait_regalloc:
-                begin
-                  if (getregtype(Tai_regalloc(p).reg)=regtype) then
-                    begin
-                      {A register allocation of a spilled register can be removed.}
-                      supreg:=getsupreg(Tai_regalloc(p).reg);
-                      if supregset_in(regs_to_spill_set,supreg) then
-                        begin
-                          q:=Tai(p.next);
-                          list.remove(p);
-                          p.free;
-                          p:=q;
-                          continue;
-                        end
-                      else
-                        if Tai_regalloc(p).allocation then
-                          live_registers.add(supreg)
+                with Tai_regalloc(p) do
+                  begin
+                    if (getregtype(reg)=regtype) then
+                      begin
+                        {A register allocation of a spilled register can be removed.}
+                        supreg:=getsupreg(reg);
+                        if supregset_in(regs_to_spill_set,supreg) then
+                          begin
+                            q:=Tai(p.next);
+                            list.remove(p);
+                            p.free;
+                            p:=q;
+                            continue;
+                          end
                         else
-                          live_registers.delete(supreg);
-                    end;
-                end;
+                          if allocation then
+                            live_registers.add(supreg)
+                          else
+                            live_registers.delete(supreg);
+                      end;
+                  end;
               ait_instruction:
-                begin
-                  aktfilepos:=Taicpu_abstract(p).fileinfo;
-                  if instr_spill_register(list,Taicpu_abstract(p),regs_to_spill_set,spill_temps^) then
-                    spill_registers:=true;
-                  if Taicpu_abstract(p).is_reg_move then
-                    add_move_instruction(Taicpu(p));
-                end;
+                with Taicpu_abstract(p) do
+                  begin
+                    aktfilepos:=fileinfo;
+                    if instr_spill_register(list,Taicpu_abstract(p),regs_to_spill_set,spill_temps^) then
+                      spill_registers:=true;
+                  end;
             end;
             p:=Tai(p.next);
           end;
         aktfilepos:=current_procinfo.exitpos;
         {Safe: this procedure is only called if there are spilled nodes.}
-        for i:=0 to spillednodes.length-1 do
-          tg.ungettemp(list,spill_temps^[spillednodes.buf^[i]]);
+        with spillednodes do
+          for i:=0 to length-1 do
+            tg.ungettemp(list,spill_temps^[buf^[i]]);
         freemem(spill_temps);
       end;
 
 
-    procedure trgobj.DoSpillRead(list : taasmoutput;instr : taicpu_abstract;pos: tai; regidx: longint;
-      const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo);
-      var
-        helpins: tai;
-      begin
-        helpins:=instr.spilling_create_load(spilltemplist[regs[regidx].orgreg],regs[regidx].tempreg);
-        if pos=nil then
-          list.insertafter(helpins,list.first)
-        else
-          list.insertafter(helpins,pos.next);
-        ungetregisterinline(list,instr,regs[regidx].tempreg);
-        forward_allocation(tai(helpins.next),instr);
-      end;
+    procedure Trgobj.do_spill_read(list:Taasmoutput;instr:Taicpu_abstract;
+                                   pos:Tai;regidx:word;
+                                   const spilltemplist:Tspill_temp_list;
+                                   const regs:Tspillregsinfo);
 
+    var helpins:Tai;
 
-    procedure trgobj.DoSpillWritten(list : taasmoutput;instr : taicpu_abstract;pos: tai; regidx: longint;
-      const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo);
-      var
-        helpins: tai;
-      begin
-        helpins:=instr.spilling_create_store(regs[regidx].tempreg,spilltemplist[regs[regidx].orgreg]);
-        list.insertafter(helpins,instr);
-        ungetregisterinline(list,helpins,regs[regidx].tempreg);
-      end;
+    begin
+      with regs[regidx] do
+        begin
+          helpins:=instr.spilling_create_load(spilltemplist[orgreg],tempreg);
+          if pos=nil then
+            list.insertafter(helpins,list.first)
+          else
+            list.insertafter(helpins,pos.next);
+          ungetregisterinline(list,instr,tempreg);
+          forward_allocation(tai(helpins.next),instr);
+        end;
+    end;
 
 
-    procedure trgobj.DoSpillReadWritten(list : taasmoutput;instr : taicpu_abstract;pos: tai; regidx: longint;
-      const spilltemplist:Tspill_temp_list;const regs : tspillregsinfo);
-      var
-        helpins1, helpins2: tai;
-      begin
-        helpins1:=instr.spilling_create_load(spilltemplist[regs[regidx].orgreg],regs[regidx].tempreg);
-        if pos=nil then
-          list.insertafter(helpins1,list.first)
-        else
-          list.insertafter(helpins1,pos.next);
-        helpins2:=instr.spilling_create_store(regs[regidx].tempreg,spilltemplist[regs[regidx].orgreg]);
-        list.insertafter(helpins2,instr);
-        ungetregisterinline(list,helpins2,regs[regidx].tempreg);
-        forward_allocation(tai(helpins1.next),instr);
-      end;
+    procedure Trgobj.do_spill_written(list:Taasmoutput;instr:Taicpu_abstract;
+                                      pos:Tai;regidx:word;
+                                      const spilltemplist:Tspill_temp_list;
+                                      const regs:Tspillregsinfo);
+
+    var helpins:Tai;
+
+    begin
+      with regs[regidx] do
+        begin
+          helpins:=instr.spilling_create_store(tempreg,spilltemplist[orgreg]);
+          list.insertafter(helpins,instr);
+          ungetregisterinline(list,helpins,tempreg);
+        end;
+    end;
+
+
+    procedure Trgobj.do_spill_readwritten(list:Taasmoutput;instr:Taicpu_abstract;
+                                          pos:Tai;regidx:word;
+                                          const spilltemplist:Tspill_temp_list;
+                                          const regs:Tspillregsinfo);
+
+    var helpins1,helpins2:Tai;
+
+    begin
+      with regs[regidx] do
+        begin
+          helpins1:=instr.spilling_create_load(spilltemplist[orgreg],tempreg);
+          if pos=nil then
+            list.insertafter(helpins1,list.first)
+          else
+            list.insertafter(helpins1,pos.next);
+          helpins2:=instr.spilling_create_store(tempreg,spilltemplist[orgreg]);
+          list.insertafter(helpins2,instr);
+          ungetregisterinline(list,helpins2,tempreg);
+          forward_allocation(tai(helpins1.next),instr);
+        end;
+    end;
 
 
     function trgobj.instr_spill_register(list:Taasmoutput;
@@ -1836,12 +1897,13 @@ implementation
               top_ref:
                 begin
                   if regtype in [R_INTREGISTER,R_ADDRESSREGISTER] then
-                    begin
-                      if (ref^.base <> NR_NO) then
-                        addreginfo(getsupreg(ref^.base),operand_read);
-                      if (ref^.index <> NR_NO) then
-                        addreginfo(getsupreg(ref^.index),operand_read);
-                    end;
+                    with ref^ do
+                      begin
+                        if (base <> NR_NO) then
+                          addreginfo(getsupreg(base),operand_read);
+                        if (index <> NR_NO) then
+                          addreginfo(getsupreg(index),operand_read);
+                      end;
                 end;
 {$ifdef ARM}
               top_shifterop:
@@ -1860,20 +1922,21 @@ implementation
         { generate the spilling code }
         result := true;
         for counter := 0 to pred(regindex) do
-          begin
-            if regs[counter].mustbespilled then
-              begin
-                pos := get_insert_pos(Tai(instr.previous),regs[0].orgreg,regs[1].orgreg,regs[2].orgreg);
-                getregisterinline(list,pos,defaultsub,regs[counter].tempreg);
-                if regs[counter].regread then
-                  if regs[counter].regwritten then
-                    DoSpillReadWritten(list,instr,pos,counter,spilltemplist,regs)
+          with regs[counter] do
+            begin
+              if mustbespilled then
+                begin
+                  pos:=get_insert_pos(Tai(instr.previous),regs[0].orgreg,regs[1].orgreg,regs[2].orgreg);
+                  getregisterinline(list,pos,defaultsub,tempreg);
+                  if regread then
+                    if regwritten then
+                      do_spill_readwritten(list,instr,pos,counter,spilltemplist,regs)
+                    else
+                      do_spill_read(list,instr,pos,counter,spilltemplist,regs)
                   else
-                    DoSpillRead(list,instr,pos,counter,spilltemplist,regs)
-                else
-                  DoSpillWritten(list,instr,pos,counter,spilltemplist,regs)
-              end;
-          end;
+                    do_spill_written(list,instr,pos,counter,spilltemplist,regs)
+                end;
+            end;
 
         { substitute registers }
         for counter := 0 to instr.ops-1 do
@@ -1905,7 +1968,10 @@ implementation
 end.
 {
   $Log$
-  Revision 1.117  2004-02-06 13:34:46  daniel
+  Revision 1.118  2004-02-07 23:28:34  daniel
+    * Take advantage of our new with statement optimization
+
+  Revision 1.117  2004/02/06 13:34:46  daniel
     * Some changes to better accomodate very large movelists
       * movelist resizing now exponential (avoids heap fragmentation, saves
         300 kb memory in make cycle)

+ 14 - 10
compiler/scanner.pas

@@ -2156,15 +2156,16 @@ implementation
                  else
                   low:=mid;
                end;
-              if pattern=tokeninfo^[ttoken(high)].str then
-               begin
-                 if tokeninfo^[ttoken(high)].keyword in aktmodeswitches then
-                  if tokeninfo^[ttoken(high)].op=NOTOKEN then
-                    token:=ttoken(high)
-                  else
-                    token:=tokeninfo^[ttoken(high)].op;
-                 idtoken:=ttoken(high);
-               end;
+              with tokeninfo^[ttoken(high)] do
+                if pattern=str then
+                  begin
+                    if keyword in aktmodeswitches then
+                      if op=NOTOKEN then
+                        token:=ttoken(high)
+                      else
+                        token:=op;
+                    idtoken:=ttoken(high);
+                  end;
             end;
          { Only process identifiers and not keywords }
            if token=_ID then
@@ -2931,7 +2932,10 @@ exit_label:
 end.
 {
   $Log$
-  Revision 1.66  2003-11-12 16:57:59  peter
+  Revision 1.67  2004-02-07 23:28:34  daniel
+    * Take advantage of our new with statement optimization
+
+  Revision 1.66  2003/11/12 16:57:59  peter
     * do nothing for macro's in tempcloseinput,tempopeninput
 
   Revision 1.65  2003/11/10 19:08:59  peter

+ 87 - 76
compiler/x86/cgx86.pas

@@ -440,14 +440,15 @@ unit cgx86;
         pushsize : tcgsize;
       begin
         check_register_size(size,r);
-        if (locpara.loc=LOC_REFERENCE) and
-           (locpara.reference.index=NR_STACK_POINTER_REG) then
-          begin
-            pushsize:=int_cgsize(locpara.alignment);
-            list.concat(taicpu.op_reg(A_PUSH,tcgsize2opsize[pushsize],makeregsize(r,pushsize)));
-          end
-        else
-          inherited a_param_reg(list,size,r,locpara);
+        with locpara do
+          if (loc=LOC_REFERENCE) and
+             (reference.index=NR_STACK_POINTER_REG) then
+            begin
+              pushsize:=int_cgsize(alignment);
+              list.concat(taicpu.op_reg(A_PUSH,tcgsize2opsize[pushsize],makeregsize(r,pushsize)));
+            end
+          else
+            inherited a_param_reg(list,size,r,locpara);
       end;
 
 
@@ -455,14 +456,15 @@ unit cgx86;
       var
         pushsize : tcgsize;
       begin
-        if (locpara.loc=LOC_REFERENCE) and
-           (locpara.reference.index=NR_STACK_POINTER_REG) then
-          begin
-            pushsize:=int_cgsize(locpara.alignment);
-            list.concat(taicpu.op_const(A_PUSH,tcgsize2opsize[pushsize],a));
-          end
-        else
-          inherited a_param_const(list,size,a,locpara);
+        with locpara do
+          if (loc=LOC_REFERENCE) and
+             (reference.index=NR_STACK_POINTER_REG) then
+            begin
+              pushsize:=int_cgsize(alignment);
+              list.concat(taicpu.op_const(A_PUSH,tcgsize2opsize[pushsize],a));
+            end
+          else
+            inherited a_param_const(list,size,a,locpara);
       end;
 
 
@@ -471,22 +473,23 @@ unit cgx86;
         pushsize : tcgsize;
         tmpreg : tregister;
       begin
-        if (locpara.loc=LOC_REFERENCE) and
-           (locpara.reference.index=NR_STACK_POINTER_REG) then
-          begin
-            pushsize:=int_cgsize(locpara.alignment);
-            if tcgsize2size[size]<locpara.alignment then
-              begin
-                tmpreg:=getintregister(list,pushsize);
-                a_load_ref_reg(list,size,pushsize,r,tmpreg);
-                list.concat(taicpu.op_reg(A_PUSH,TCgsize2opsize[pushsize],tmpreg));
-                ungetregister(list,tmpreg);
-              end
-            else
-              list.concat(taicpu.op_ref(A_PUSH,TCgsize2opsize[pushsize],r));
-          end
-        else
-          inherited a_param_ref(list,size,r,locpara);
+        with locpara do
+          if (loc=LOC_REFERENCE) and
+             (reference.index=NR_STACK_POINTER_REG) then
+            begin
+              pushsize:=int_cgsize(alignment);
+              if tcgsize2size[size]<alignment then
+                begin
+                  tmpreg:=getintregister(list,pushsize);
+                  a_load_ref_reg(list,size,pushsize,r,tmpreg);
+                  list.concat(taicpu.op_reg(A_PUSH,TCgsize2opsize[pushsize],tmpreg));
+                  ungetregister(list,tmpreg);
+                end
+              else
+                list.concat(taicpu.op_ref(A_PUSH,TCgsize2opsize[pushsize],r));
+            end
+          else
+            inherited a_param_ref(list,size,r,locpara);
       end;
 
 
@@ -495,35 +498,39 @@ unit cgx86;
         tmpreg : tregister;
         opsize : topsize;
       begin
-        if (r.segment<>NR_NO) then
-          CGMessage(cg_e_cant_use_far_pointer_there);
-        if (locpara.loc=LOC_REFERENCE) and
-           (locpara.reference.index=NR_STACK_POINTER_REG) then
+        with r do
           begin
-            opsize:=tcgsize2opsize[OS_ADDR];
-            if (r.base=NR_NO) and (r.index=NR_NO) then
-              begin
-                if assigned(r.symbol) then
-                  list.concat(Taicpu.Op_sym_ofs(A_PUSH,opsize,r.symbol,r.offset))
-                else
-                  list.concat(Taicpu.Op_const(A_PUSH,opsize,r.offset));
-              end
-            else if (r.base=NR_NO) and (r.index<>NR_NO) and
-                    (r.offset=0) and (r.scalefactor=0) and (r.symbol=nil) then
-              list.concat(Taicpu.Op_reg(A_PUSH,opsize,r.index))
-            else if (r.base<>NR_NO) and (r.index=NR_NO) and
-                    (r.offset=0) and (r.symbol=nil) then
-              list.concat(Taicpu.Op_reg(A_PUSH,opsize,r.base))
-            else
-              begin
-                tmpreg:=getaddressregister(list);
-                a_loadaddr_ref_reg(list,r,tmpreg);
-                ungetregister(list,tmpreg);
-                list.concat(taicpu.op_reg(A_PUSH,opsize,tmpreg));
-              end;
-          end
-        else
-          inherited a_paramaddr_ref(list,r,locpara);
+            if (segment<>NR_NO) then
+              cgmessage(cg_e_cant_use_far_pointer_there);
+            with locpara do
+              if (locpara.loc=LOC_REFERENCE) and
+                 (locpara.reference.index=NR_STACK_POINTER_REG) then
+                begin
+                  opsize:=tcgsize2opsize[OS_ADDR];
+                  if (base=NR_NO) and (index=NR_NO) then
+                    begin
+                      if assigned(symbol) then
+                        list.concat(Taicpu.Op_sym_ofs(A_PUSH,opsize,symbol,offset))
+                      else
+                        list.concat(Taicpu.Op_const(A_PUSH,opsize,offset));
+                    end
+                  else if (base=NR_NO) and (index<>NR_NO) and
+                          (offset=0) and (scalefactor=0) and (symbol=nil) then
+                    list.concat(Taicpu.Op_reg(A_PUSH,opsize,index))
+                  else if (base<>NR_NO) and (index=NR_NO) and
+                          (offset=0) and (symbol=nil) then
+                    list.concat(Taicpu.Op_reg(A_PUSH,opsize,base))
+                  else
+                    begin
+                      tmpreg:=getaddressregister(list);
+                      a_loadaddr_ref_reg(list,r,tmpreg);
+                      ungetregister(list,tmpreg);
+                      list.concat(taicpu.op_reg(A_PUSH,opsize,tmpreg));
+                    end;
+                end
+              else
+                inherited a_paramaddr_ref(list,r,locpara);
+        end;
       end;
 
 
@@ -634,21 +641,22 @@ unit cgx86;
 
     procedure tcgx86.a_loadaddr_ref_reg(list : taasmoutput;const ref : treference;r : tregister);
       begin
-        if (ref.base=NR_NO) and (ref.index=NR_NO) then
-          begin
-            if assigned(ref.symbol) then
-              list.concat(Taicpu.Op_sym_ofs_reg(A_MOV,tcgsize2opsize[OS_ADDR],ref.symbol,ref.offset,r))
-            else
-              a_load_const_reg(list,OS_ADDR,ref.offset,r);
-          end
-        else if (ref.base=NR_NO) and (ref.index<>NR_NO) and
-                (ref.offset=0) and (ref.scalefactor=0) and (ref.symbol=nil) then
-          a_load_reg_reg(list,OS_ADDR,OS_ADDR,ref.index,r)
-        else if (ref.base<>NR_NO) and (ref.index=NR_NO) and
-                (ref.offset=0) and (ref.symbol=nil) then
-          a_load_reg_reg(list,OS_ADDR,OS_ADDR,ref.base,r)
-        else
-          list.concat(taicpu.op_ref_reg(A_LEA,tcgsize2opsize[OS_ADDR],ref,r));
+        with ref do
+          if (base=NR_NO) and (index=NR_NO) then
+            begin
+              if assigned(ref.symbol) then
+                list.concat(Taicpu.op_sym_ofs_reg(A_MOV,tcgsize2opsize[OS_ADDR],symbol,offset,r))
+              else
+                a_load_const_reg(list,OS_ADDR,offset,r);
+            end
+          else if (base=NR_NO) and (index<>NR_NO) and
+                  (offset=0) and (scalefactor=0) and (symbol=nil) then
+            a_load_reg_reg(list,OS_ADDR,OS_ADDR,index,r)
+          else if (base<>NR_NO) and (index=NR_NO) and
+                  (offset=0) and (symbol=nil) then
+            a_load_reg_reg(list,OS_ADDR,OS_ADDR,base,r)
+          else
+            list.concat(taicpu.op_ref_reg(A_LEA,tcgsize2opsize[OS_ADDR],ref,r));
       end;
 
 
@@ -1844,7 +1852,10 @@ unit cgx86;
 end.
 {
   $Log$
-  Revision 1.108  2004-02-06 14:37:48  florian
+  Revision 1.109  2004-02-07 23:28:34  daniel
+    * Take advantage of our new with statement optimization
+
+  Revision 1.108  2004/02/06 14:37:48  florian
     * movz*q fixed
 
   Revision 1.107  2004/02/05 18:28:37  peter