소스 검색

* Improved handling of registers used in assembler blocks. Assembler nodes no longer have lists of used registers attached to them. Instead, each specified register creates an allocation/deallocation pair and an additional tai_regalloc.markused item directly in the asmlist. This way, register lists are no longer limited to integer registers, and parsing no longer depends on paramanager to know which registers are volatile.
If assembler block has no modified register list, it is still handled in pass2, by allocating all volatile registers (not only the integer ones as before).

git-svn-id: trunk@30011 -

sergei 10 년 전
부모
커밋
657ac78304
3개의 변경된 파일23개의 추가작업 그리고 28개의 파일을 삭제
  1. 2 4
      compiler/nbas.pas
  2. 5 2
      compiler/ncgbas.pas
  3. 16 22
      compiler/pstatmnt.pas

+ 2 - 4
compiler/nbas.pas

@@ -52,8 +52,7 @@ interface
           p_asm : TAsmList;
           p_asm : TAsmList;
           currenttai : tai;
           currenttai : tai;
           { Used registers in assembler block }
           { Used registers in assembler block }
-          used_regs_int,
-          used_regs_fpu : tcpuregisterset;
+          has_registerlist : boolean;
           constructor create(p : TAsmList);virtual;
           constructor create(p : TAsmList);virtual;
           constructor create_get_position;
           constructor create_get_position;
           destructor destroy;override;
           destructor destroy;override;
@@ -642,8 +641,6 @@ implementation
         inherited create(asmn);
         inherited create(asmn);
         p_asm:=p;
         p_asm:=p;
         currenttai:=nil;
         currenttai:=nil;
-        used_regs_int:=[];
-        used_regs_fpu:=[];
       end;
       end;
 
 
 
 
@@ -751,6 +748,7 @@ implementation
           end
           end
         else n.p_asm := nil;
         else n.p_asm := nil;
         n.currenttai:=currenttai;
         n.currenttai:=currenttai;
+        n.has_registerlist:=has_registerlist;
         result:=n;
         result:=n;
       end;
       end;
 
 

+ 5 - 2
compiler/ncgbas.pas

@@ -255,7 +255,9 @@ interface
            end;
            end;
 
 
          { Allocate registers used in the assembler block }
          { Allocate registers used in the assembler block }
-         cg.alloccpuregisters(current_asmdata.CurrAsmList,R_INTREGISTER,used_regs_int);
+         { has_registerlist=true means that registers are specified and already allocated }
+         if (not has_registerlist) then
+           cg.allocallcpuregisters(current_asmdata.CurrAsmList);
 
 
          if (po_inline in current_procinfo.procdef.procoptions) then
          if (po_inline in current_procinfo.procdef.procoptions) then
            begin
            begin
@@ -344,7 +346,8 @@ interface
            end;
            end;
 
 
          { Release register used in the assembler block }
          { Release register used in the assembler block }
-         cg.dealloccpuregisters(current_asmdata.CurrAsmList,R_INTREGISTER,used_regs_int);
+         if (not has_registerlist) then
+           cg.deallocallcpuregisters(current_asmdata.CurrAsmList);
        end;
        end;
 
 
 
 

+ 16 - 22
compiler/pstatmnt.pas

@@ -1045,6 +1045,7 @@ implementation
         reg     : tregister;
         reg     : tregister;
         asmreader : tbaseasmreader;
         asmreader : tbaseasmreader;
         entrypos : tfileposinfo;
         entrypos : tfileposinfo;
+        hl : TAsmList;
       begin
       begin
          Inside_asm_statement:=true;
          Inside_asm_statement:=true;
          asmstat:=nil;
          asmstat:=nil;
@@ -1052,7 +1053,14 @@ implementation
            begin
            begin
              asmreader:=asmmodeinfos[current_settings.asmmode]^.casmreader.create;
              asmreader:=asmmodeinfos[current_settings.asmmode]^.casmreader.create;
              entrypos:=current_filepos;
              entrypos:=current_filepos;
-             asmstat:=casmnode.create(asmreader.assemble as TAsmList);
+             hl:=asmreader.assemble as TAsmList;
+             if (not hl.empty) then
+               begin
+                 { mark boundaries of assembler block, this is necessary for optimizer }
+                 hl.insert(tai_marker.create(mark_asmblockstart));
+                 hl.concat(tai_marker.create(mark_asmblockend));
+               end;
+             asmstat:=casmnode.create(hl);
              asmstat.fileinfo:=entrypos;
              asmstat.fileinfo:=entrypos;
              asmreader.free;
              asmreader.free;
            end
            end
@@ -1068,11 +1076,6 @@ implementation
          { END is read, got a list of changed registers? }
          { END is read, got a list of changed registers? }
          if try_to_consume(_LECKKLAMMER) then
          if try_to_consume(_LECKKLAMMER) then
            begin
            begin
-{$ifdef cpunofpu}
-             asmstat.used_regs_fpu:=[0..first_int_imreg-1];
-{$else cpunofpu}
-             asmstat.used_regs_fpu:=[0..first_fpu_imreg-1];
-{$endif cpunofpu}
              if token<>_RECKKLAMMER then
              if token<>_RECKKLAMMER then
               begin
               begin
                 if po_assembler in current_procinfo.procdef.procoptions then
                 if po_assembler in current_procinfo.procdef.procoptions then
@@ -1082,8 +1085,12 @@ implementation
                   reg:=std_regnum_search(lower(cstringpattern));
                   reg:=std_regnum_search(lower(cstringpattern));
                   if reg<>NR_NO then
                   if reg<>NR_NO then
                     begin
                     begin
-                      if (getregtype(reg)=R_INTREGISTER) and not(po_assembler in current_procinfo.procdef.procoptions) then
-                        include(asmstat.used_regs_int,getsupreg(reg));
+                      if not(po_assembler in current_procinfo.procdef.procoptions) then
+                        begin
+                          hl.Insert(tai_regalloc.alloc(reg,nil));
+                          hl.Insert(tai_regalloc.markused(reg));
+                          hl.Concat(tai_regalloc.dealloc(reg,nil));
+                        end;
                     end
                     end
                   else
                   else
                     Message(asmr_e_invalid_register);
                     Message(asmr_e_invalid_register);
@@ -1091,24 +1098,11 @@ implementation
                   if not try_to_consume(_COMMA) then
                   if not try_to_consume(_COMMA) then
                     break;
                     break;
                 until false;
                 until false;
+                asmstat.has_registerlist:=true;
               end;
               end;
              consume(_RECKKLAMMER);
              consume(_RECKKLAMMER);
-           end
-         else
-           begin
-              asmstat.used_regs_int:=paramanager.get_volatile_registers_int(current_procinfo.procdef.proccalloption);
-              asmstat.used_regs_fpu:=paramanager.get_volatile_registers_fpu(current_procinfo.procdef.proccalloption);
            end;
            end;
 
 
-         { mark the start and the end of the assembler block
-           this is needed for the optimizer }
-         If Assigned(AsmStat.p_asm) Then
-           Begin
-             Marker := Tai_Marker.Create(mark_AsmBlockStart);
-             AsmStat.p_asm.Insert(Marker);
-             Marker := Tai_Marker.Create(mark_AsmBlockEnd);
-             AsmStat.p_asm.Concat(Marker);
-           End;
          Inside_asm_statement:=false;
          Inside_asm_statement:=false;
          _asm_statement:=asmstat;
          _asm_statement:=asmstat;
       end;
       end;