Parcourir la source

* psub.pas : translate tregister for registerhi also
(avoids imaginary register number in "# Var I in register .." assembler comments.
* dbgdwarf.pas : Support register variables as register pairs.
Does not yet handle case of changing registers.
* symsym.pas : add currentregloc field to tabstractnormalvarsym class,
to be able to track changing registers used for a given variable.
* aasmtai.pas : Update currentregloc field of tai_varloc.create sym parameter.
* ncgutil.pas : Only generate a tai_varloc if the new registers are different for the variable.

git-svn-id: trunk@22508 -

pierre il y a 13 ans
Parent
commit
fcaff0489c
5 fichiers modifiés avec 62 ajouts et 12 suppressions
  1. 15 1
      compiler/aasmtai.pas
  2. 31 6
      compiler/dbgdwarf.pas
  3. 8 4
      compiler/ncgutil.pas
  4. 5 1
      compiler/psub.pas
  5. 3 0
      compiler/symsym.pas

+ 15 - 1
compiler/aasmtai.pas

@@ -267,7 +267,7 @@ interface
         a new ait type!                                                              }
       SkipInstr = [ait_comment, ait_symbol,ait_section
                    ,ait_stab, ait_function_name, ait_force_line
-                   ,ait_regalloc, ait_tempalloc, ait_symbol_end 
+                   ,ait_regalloc, ait_tempalloc, ait_symbol_end
 				   ,ait_ent, ait_ent_end, ait_directive
                    ,ait_varloc,ait_seh_directive
                    ,ait_jvar, ait_jcatch];
@@ -740,6 +740,8 @@ interface
         tai_align_class = class of tai_align_abstract;
 
         tai_varloc = class(tai)
+           oldlocation,
+           oldlocationhi,
            newlocation,
            newlocationhi : tregister;
            varsym : tsym;
@@ -831,6 +833,7 @@ implementation
     uses
       SysUtils,
       verbose,
+      symsym,
       globals;
 
     const
@@ -923,6 +926,9 @@ implementation
         newlocation:=loc;
         newlocationhi:=NR_NO;
         varsym:=sym;
+        oldlocation:=tabstractnormalvarsym(sym).currentregloc.register;
+        oldlocationhi:=NR_NO;
+        tabstractnormalvarsym(sym).currentregloc.register:=newlocation;
       end;
 
 
@@ -933,6 +939,10 @@ implementation
         newlocation:=loc;
         newlocationhi:=lochi;
         varsym:=sym;
+        oldlocation:=tabstractnormalvarsym(sym).currentregloc.register;
+        oldlocationhi:=tabstractnormalvarsym(sym).currentregloc.registerhi;
+        tabstractnormalvarsym(sym).currentregloc.register:=newlocation;
+        tabstractnormalvarsym(sym).currentregloc.registerHI:=newlocationHI;
       end;
 
 
@@ -944,6 +954,10 @@ implementation
         newlocation:=loc;
         newlocationhi:=lochi;
         varsym:=sym;
+        oldlocation:=tabstractnormalvarsym(sym).currentregloc.register;
+        oldlocationhi:=tabstractnormalvarsym(sym).currentregloc.registerhi;
+        tabstractnormalvarsym(sym).currentregloc.register:=newlocation;
+        tabstractnormalvarsym(sym).currentregloc.registerHI:=newlocationHI;
       end;
 {$endif cpu64bitalu}
 

+ 31 - 6
compiler/dbgdwarf.pas

@@ -2301,9 +2301,10 @@ implementation
     procedure TDebugInfoDwarf.appendsym_var_with_name_type_offset(list:TAsmList; sym:tabstractnormalvarsym; const name: string; def: tdef; offset: pint; const flags: tdwarfvarsymflags);
       var
         templist : TAsmList;
-        blocksize : longint;
+        blocksize,size_of_int : longint;
         tag : tdwarf_tag;
-        dreg : byte;
+        has_high_reg : boolean;
+        dreg,dreghigh : byte;
       begin
         { external symbols can't be resolved at link time, so we
           can't generate stabs for them
@@ -2328,6 +2329,10 @@ implementation
           LOC_CFPUREGISTER :
             begin
               dreg:=dwarf_reg(sym.localloc.register);
+              has_high_reg:=(sym.localloc.registerhi<>NR_NO) and
+                (dwarf_reg(sym.localloc.registerhi)<=high(tregisterindex));
+              if has_high_reg then
+                dreghigh:=dwarf_reg(sym.localloc.registerhi);
               if (sym.localloc.loc in [LOC_REGISTER,LOC_CREGISTER]) and
                  (sym.typ=paravarsym) and
                   paramanager.push_addr_param(sym.varspez,sym.vardef,tprocdef(sym.owner.defowner).proccalloption) and
@@ -2341,10 +2346,30 @@ implementation
                 end
               else
                 begin
-                  templist.concat(tai_const.create_8bit(ord(DW_OP_regx)));
-                  templist.concat(tai_const.create_uleb128bit(dreg));
-                  blocksize:=1+Lengthuleb128(dreg);
-                end;
+                  if has_high_reg then
+                    begin
+                      templist.concat(tai_comment.create(strpnew('high:low reg pair variable')));
+                      size_of_int:=sizeof(aint);
+                      templist.concat(tai_const.create_8bit(ord(DW_OP_regx)));
+                      templist.concat(tai_const.create_uleb128bit(dreg));
+                      blocksize:=1+Lengthuleb128(dreg);
+                      templist.concat(tai_const.create_8bit(ord(DW_OP_piece)));
+                      templist.concat(tai_const.create_uleb128bit(size_of_int));
+                      blocksize:=blocksize+1+Lengthuleb128(size_of_int);
+                      templist.concat(tai_const.create_8bit(ord(DW_OP_regx)));
+                      templist.concat(tai_const.create_uleb128bit(dreghigh));
+                      blocksize:=blocksize+1+Lengthuleb128(dreghigh);
+                      templist.concat(tai_const.create_8bit(ord(DW_OP_piece)));
+                      templist.concat(tai_const.create_uleb128bit(size_of_int));
+                      blocksize:=blocksize+1+Lengthuleb128(size_of_int);
+                    end
+                  else
+                    begin
+                      templist.concat(tai_const.create_8bit(ord(DW_OP_regx)));
+                      templist.concat(tai_const.create_uleb128bit(dreg));
+                      blocksize:=1+Lengthuleb128(dreg);
+                    end;
+                 end;
             end;
           else
             begin

+ 8 - 4
compiler/ncgutil.pas

@@ -1725,7 +1725,7 @@ implementation
         oldhi, newhi: tregister;
         ressym: tsym;
         { moved sym }
-        sym : tsym;
+        sym : tabstractnormalvarsym;
       end;
 
 
@@ -1903,7 +1903,9 @@ implementation
           begin
             n.location.register128.reglo := rr.new;
             n.location.register128.reghi := rr.newhi;
-            if assigned(rr.sym) then
+            if assigned(rr.sym) and
+               ((rr.sym.currentregloc.register<>rr.new) or
+                (rr.sym.currentregloc.registerhi<>rr.newhi)) then
               list.concat(tai_varloc.create128(rr.sym,rr.new,rr.newhi));
           end
         else
@@ -1912,14 +1914,16 @@ implementation
           begin
             n.location.register64.reglo := rr.new;
             n.location.register64.reghi := rr.newhi;
-            if assigned(rr.sym) then
+            if assigned(rr.sym) and
+               ((rr.sym.currentregloc.register<>rr.new) or
+                (rr.sym.currentregloc.registerhi<>rr.newhi)) then
               list.concat(tai_varloc.create64(rr.sym,rr.new,rr.newhi));
           end
         else
       {$endif cpu64bitalu}
           begin
             n.location.register := rr.new;
-            if assigned(rr.sym) then
+            if assigned(rr.sym) and (rr.sym.currentregloc.register<>rr.new) then
               list.concat(tai_varloc.create(rr.sym,rr.new));
           end;
       end;

+ 5 - 1
compiler/psub.pas

@@ -890,7 +890,11 @@ implementation
               LOC_CMMREGISTER,LOC_FPUREGISTER,LOC_CFPUREGISTER]) then
            begin
              if not(cs_no_regalloc in current_settings.globalswitches) then
-               cg.translate_register(tabstractnormalvarsym(p).localloc.register);
+               begin
+                 cg.translate_register(tabstractnormalvarsym(p).localloc.register);
+                 if (tabstractnormalvarsym(p).localloc.registerhi<>NR_NO) then
+                 cg.translate_register(tabstractnormalvarsym(p).localloc.registerhi);
+               end;
              if cs_asm_source in current_settings.globalswitches then
                begin
                  if tabstractnormalvarsym(p).localloc.registerhi<>NR_NO then

+ 3 - 0
compiler/symsym.pas

@@ -188,6 +188,7 @@ interface
           defaultconstsymderef : tderef;
           localloc      : TLocation; { register/reference for local var }
           initialloc    : TLocation; { initial location so it can still be initialized later after the location was changed by SSA }
+          currentregloc  : TLocation; { current registers for register variables with moving register numbers }
           inparentfpstruct : boolean;   { migrated to a parentfpstruct because of nested access (not written to ppu, because not important and would change interface crc) }
           constructor create(st:tsymtyp;const n : string;vsp:tvarspez;def:tdef;vopts:tvaroptions);
           constructor ppuload(st:tsymtyp;ppufile:tcompilerppufile);
@@ -1539,6 +1540,7 @@ implementation
       begin
          inherited create(st,n,vsp,def,vopts);
          fillchar(localloc,sizeof(localloc),0);
+         fillchar(currentregloc,sizeof(localloc),0);
          fillchar(initialloc,sizeof(initialloc),0);
          defaultconstsym:=nil;
       end;
@@ -1548,6 +1550,7 @@ implementation
       begin
          inherited ppuload(st,ppufile);
          fillchar(localloc,sizeof(localloc),0);
+         fillchar(currentregloc,sizeof(localloc),0);
          fillchar(initialloc,sizeof(initialloc),0);
          ppufile.getderef(defaultconstsymderef);
       end;