2
0
Эх сурвалжийг харах

+ optimized code generation on sparc
+ some stuff for pic code on sparc added

florian 20 жил өмнө
parent
commit
00324d38bf

+ 9 - 2
compiler/ncgld.pas

@@ -71,8 +71,10 @@ implementation
 
     procedure tcgloadnode.generate_picvaraccess;
       begin
+{$ifndef sparc}
         location.reference.base:=current_procinfo.got;
         location.reference.symbol:=objectlibrary.newasmsymbol(tglobalvarsym(symtableentry).mangledname+'@GOT',AB_EXTERNAL,AT_DATA);
+{$endif sparc}
       end;
 
 
@@ -235,7 +237,8 @@ implementation
                               globalsymtable,
                               staticsymtable :
                                 begin
-                                  if cs_create_pic in aktmoduleswitches then
+                                  if (target_info.system=system_powerpc_darwin) and
+                                    (cs_create_pic in aktmoduleswitches) then
                                     begin
                                       generate_picvaraccess;
                                       if not(pi_needs_got in current_procinfo.flags) then
@@ -951,7 +954,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.135  2005-01-04 16:37:09  peter
+  Revision 1.136  2005-01-23 17:14:21  florian
+    + optimized code generation on sparc
+    + some stuff for pic code on sparc added
+
+  Revision 1.135  2005/01/04 16:37:09  peter
     * don't release temps for array of ansistring
 
   Revision 1.134  2004/12/18 15:48:27  florian

+ 9 - 1
compiler/nld.pas

@@ -354,6 +354,10 @@ implementation
 {$ifdef SUPPORT_MMX}
          registersmmx:=0;
 {$endif SUPPORT_MMX}
+         if (cs_create_pic in aktmoduleswitches) and
+           not(symtableentry.typ in [paravarsym,localvarsym]) then
+           include(current_procinfo.flags,pi_needs_got);
+
          case symtableentry.typ of
             absolutevarsym :
               ;
@@ -1177,7 +1181,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.142  2004-12-26 16:21:39  peter
+  Revision 1.143  2005-01-23 17:14:21  florian
+    + optimized code generation on sparc
+    + some stuff for pic code on sparc added
+
+  Revision 1.142  2004/12/26 16:21:39  peter
     * resourcestring does not need exception frame
 
   Revision 1.141  2004/12/07 13:52:54  michael

+ 132 - 59
compiler/sparc/cgcpu.pas

@@ -121,13 +121,10 @@ implementation
   uses
     globals,verbose,systems,cutils,
     symdef,paramgr,
-    tgobj,procinfo,cpupi;
+    tgobj,
+    procinfo,cpupi;
 
 
-{****************************************************************************
-                       This is private property, keep out! :)
-****************************************************************************}
-
     function TCgSparc.IsSimpleRef(const ref:treference):boolean;
       begin
         if (ref.base=NR_NO) and (ref.index<>NR_NO) then
@@ -153,6 +150,31 @@ implementation
             ref.base:=ref.index;
             ref.index:=NR_NO;
           end;
+        if (cs_create_pic in aktmoduleswitches) and
+          assigned(ref.symbol) then
+          begin
+            tmpreg:=GetIntRegister(list,OS_INT);
+            reference_reset(tmpref);
+            tmpref.symbol:=ref.symbol;
+            tmpref.refaddr:=addr_pic;
+            if not(pi_needs_got in current_procinfo.flags) then
+              internalerror(200501161);
+            tmpref.index:=current_procinfo.got;
+            list.concat(taicpu.op_ref_reg(A_LD,tmpref,tmpreg));
+            ref.symbol:=nil;
+            if (ref.index<>NR_NO) then
+              begin
+                list.concat(taicpu.op_reg_reg_reg(A_ADD,tmpreg,ref.index,tmpreg));
+                ref.index:=tmpreg;
+              end
+            else
+              begin
+                if ref.base<>NR_NO then
+                  ref.index:=tmpreg
+                else
+                  ref.base:=tmpreg;
+              end;
+          end;
         { When need to use SETHI, do it first }
         if assigned(ref.symbol) or
            (ref.offset<simm13lo) or
@@ -164,28 +186,31 @@ implementation
             tmpref.offset:=ref.offset;
             tmpref.refaddr:=addr_hi;
             list.concat(taicpu.op_ref_reg(A_SETHI,tmpref,tmpreg));
-            { Load the low part is left }
-{$warning TODO Maybe not needed to load symbol}
-            tmpref.refaddr:=addr_lo;
-            list.concat(taicpu.op_reg_ref_reg(A_OR,tmpreg,tmpref,tmpreg));
-            { The offset and symbol are loaded, reset in reference }
-            ref.offset:=0;
-            ref.symbol:=nil;
-            { Only an index register or offset is allowed }
-            if tmpreg<>NR_NO then
+            if (ref.offset=0) and (ref.index=NR_NO) and
+              (ref.base=NR_NO) then
               begin
-                if (ref.index<>NR_NO) then
-                  begin
-                    list.concat(taicpu.op_reg_reg_reg(A_ADD,tmpreg,ref.index,tmpreg));
-                    ref.index:=tmpreg;
-                  end
+                ref.refaddr:=addr_lo;
+              end
+            else
+              begin
+                { Load the low part is left }
+                tmpref.refaddr:=addr_lo;
+                list.concat(taicpu.op_reg_ref_reg(A_OR,tmpreg,tmpref,tmpreg));
+                ref.offset:=0;
+                { symbol is loaded }
+                ref.symbol:=nil;
+              end;
+            if (ref.index<>NR_NO) then
+              begin
+                list.concat(taicpu.op_reg_reg_reg(A_ADD,tmpreg,ref.index,tmpreg));
+                ref.index:=tmpreg;
+              end
+            else
+              begin
+                if ref.base<>NR_NO then
+                  ref.index:=tmpreg
                 else
-                  begin
-                    if ref.base<>NR_NO then
-                      ref.index:=tmpreg
-                    else
-                      ref.base:=tmpreg;
-                  end;
+                  ref.base:=tmpreg;
               end;
           end;
         if (ref.base<>NR_NO) then
@@ -236,10 +261,22 @@ implementation
     procedure Tcgsparc.init_register_allocators;
       begin
         inherited init_register_allocators;
-        rg[R_INTREGISTER]:=Trgcpu.create(R_INTREGISTER,R_SUBD,
-            [RS_O0,RS_O1,RS_O2,RS_O3,RS_O4,RS_O5,
-             RS_L0,RS_L1,RS_L2,RS_L3,RS_L4,RS_L5,RS_L6,RS_L7],
-            first_int_imreg,[]);
+
+        if (cs_create_pic in aktmoduleswitches) and
+          (pi_needs_got in current_procinfo.flags) then
+          begin
+            current_procinfo.got:=NR_L7;
+            rg[R_INTREGISTER]:=Trgcpu.create(R_INTREGISTER,R_SUBD,
+                [RS_O0,RS_O1,RS_O2,RS_O3,RS_O4,RS_O5,
+                 RS_L0,RS_L1,RS_L2,RS_L3,RS_L4,RS_L5,RS_L6],
+                first_int_imreg,[]);
+          end
+        else
+          rg[R_INTREGISTER]:=Trgcpu.create(R_INTREGISTER,R_SUBD,
+              [RS_O0,RS_O1,RS_O2,RS_O3,RS_O4,RS_O5,
+               RS_L0,RS_L1,RS_L2,RS_L3,RS_L4,RS_L5,RS_L6,RS_L7],
+              first_int_imreg,[]);
+
         rg[R_FPUREGISTER]:=trgcpu.create(R_FPUREGISTER,R_SUBFS,
             [RS_F0,RS_F1,RS_F2,RS_F3,RS_F4,RS_F5,RS_F6,RS_F7,
              RS_F8,RS_F9,RS_F10,RS_F11,RS_F12,RS_F13,RS_F14,RS_F15,
@@ -540,34 +577,62 @@ implementation
 
     procedure TCgSparc.a_loadaddr_ref_reg(list : TAasmOutput;const ref : TReference;r : tregister);
       var
-         tmpref : treference;
-         hreg : tregister;
+         tmpref,href : treference;
+         hreg,tmpreg : tregister;
       begin
-        if (ref.base=NR_NO) and (ref.index<>NR_NO) then
+        href:=ref;
+        if (href.base=NR_NO) and (href.index<>NR_NO) then
           internalerror(200306171);
+
+        if (cs_create_pic in aktmoduleswitches) and
+          assigned(href.symbol) then
+          begin
+            tmpreg:=GetIntRegister(list,OS_ADDR);
+            reference_reset(tmpref);
+            tmpref.symbol:=href.symbol;
+            tmpref.refaddr:=addr_pic;
+            if not(pi_needs_got in current_procinfo.flags) then
+              internalerror(200501161);
+            tmpref.base:=current_procinfo.got;
+            list.concat(taicpu.op_ref_reg(A_LD,tmpref,tmpreg));
+            href.symbol:=nil;
+            if (href.index<>NR_NO) then
+              begin
+                list.concat(taicpu.op_reg_reg_reg(A_ADD,tmpreg,href.index,tmpreg));
+                href.index:=tmpreg;
+              end
+            else
+              begin
+                if href.base<>NR_NO then
+                  href.index:=tmpreg
+                else
+                  href.base:=tmpreg;
+              end;
+          end;
+
         { At least big offset (need SETHI), maybe base and maybe index }
-        if assigned(ref.symbol) or
-           (ref.offset<simm13lo) or
-           (ref.offset>simm13hi) then
+        if assigned(href.symbol) or
+           (href.offset<simm13lo) or
+           (href.offset>simm13hi) then
           begin
             hreg:=GetAddressRegister(list);
             reference_reset(tmpref);
-            tmpref.symbol := ref.symbol;
-            tmpref.offset := ref.offset;
+            tmpref.symbol := href.symbol;
+            tmpref.offset := href.offset;
             tmpref.refaddr := addr_hi;
             list.concat(taicpu.op_ref_reg(A_SETHI,tmpref,hreg));
             { Only the low part is left }
             tmpref.refaddr:=addr_lo;
             list.concat(taicpu.op_reg_ref_reg(A_OR,hreg,tmpref,hreg));
-            if ref.base<>NR_NO then
+            if href.base<>NR_NO then
               begin
-                if ref.index<>NR_NO then
+                if href.index<>NR_NO then
                   begin
-                    list.concat(taicpu.op_reg_reg_reg(A_ADD,hreg,ref.base,hreg));
-                    list.concat(taicpu.op_reg_reg_reg(A_ADD,hreg,ref.index,r));
+                    list.concat(taicpu.op_reg_reg_reg(A_ADD,hreg,href.base,hreg));
+                    list.concat(taicpu.op_reg_reg_reg(A_ADD,hreg,href.index,r));
                   end
                 else
-                  list.concat(taicpu.op_reg_reg_reg(A_ADD,hreg,ref.base,r));
+                  list.concat(taicpu.op_reg_reg_reg(A_ADD,hreg,href.base,r));
               end
             else
               begin
@@ -577,33 +642,33 @@ implementation
           end
         else
         { At least small offset, maybe base and maybe index }
-          if ref.offset<>0 then
+          if href.offset<>0 then
             begin
-              if ref.base<>NR_NO then
+              if href.base<>NR_NO then
                 begin
-                  if ref.index<>NR_NO then
+                  if href.index<>NR_NO then
                     begin
                       hreg:=GetAddressRegister(list);
-                      list.concat(taicpu.op_reg_const_reg(A_ADD,ref.base,ref.offset,hreg));
-                      list.concat(taicpu.op_reg_reg_reg(A_ADD,hreg,ref.index,r));
+                      list.concat(taicpu.op_reg_const_reg(A_ADD,href.base,href.offset,hreg));
+                      list.concat(taicpu.op_reg_reg_reg(A_ADD,hreg,href.index,r));
                     end
                   else
-                    list.concat(taicpu.op_reg_const_reg(A_ADD,ref.base,ref.offset,r));
+                    list.concat(taicpu.op_reg_const_reg(A_ADD,href.base,href.offset,r));
                 end
               else
-                list.concat(taicpu.op_const_reg(A_MOV,ref.offset,r));
+                list.concat(taicpu.op_const_reg(A_MOV,href.offset,r));
             end
         else
         { Both base and index }
-          if ref.index<>NR_NO then
-            list.concat(taicpu.op_reg_reg_reg(A_ADD,ref.base,ref.index,r))
+          if href.index<>NR_NO then
+            list.concat(taicpu.op_reg_reg_reg(A_ADD,href.base,href.index,r))
         else
         { Only base }
-          if ref.base<>NR_NO then
-            a_load_reg_reg(list,OS_ADDR,OS_ADDR,ref.base,r)
+          if href.base<>NR_NO then
+            a_load_reg_reg(list,OS_ADDR,OS_ADDR,href.base,r)
         else
           { only offset, can be generated by absolute }
-          a_load_const_reg(list,OS_ADDR,ref.offset,r);
+          a_load_const_reg(list,OS_ADDR,href.offset,r);
       end;
 
 
@@ -650,7 +715,7 @@ implementation
         if (a=0) then
           list.concat(taicpu.op_reg_reg_reg(TOpCG2AsmOp[op],reg,NR_G0,reg))
         else
-          a_op_const_reg_reg(list,op,size,a,reg,reg);
+          handle_reg_const_reg(list,TOpCG2AsmOp[op],reg,a,reg);
       end;
 
 
@@ -689,9 +754,8 @@ implementation
             begin
               if ispowerof2(a,power) then
                 begin
-                  { we can't do this easily in the asm. optimizer; overflow checking code
-                    might depend on a set Y }
-                  a_op_const_reg_reg(list,OP_SHL,size,power,src,dst);
+                  { can be done with a shift }
+                  inherited a_op_const_reg_reg(list,op,size,a,src,dst);
                   exit;
                 end;
             end;
@@ -942,6 +1006,11 @@ implementation
           end
         else
           list.concat(Taicpu.Op_reg_const_reg(A_SAVE,NR_STACK_POINTER_REG,-LocalSize,NR_STACK_POINTER_REG));
+        if (cs_create_pic in aktmoduleswitches) and
+          (pi_needs_got in current_procinfo.flags) then
+          begin
+            current_procinfo.got:=NR_L7;
+          end;
       end;
 
 
@@ -1341,7 +1410,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.101  2005-01-07 16:22:54  florian
+  Revision 1.102  2005-01-23 17:14:21  florian
+    + optimized code generation on sparc
+    + some stuff for pic code on sparc added
+
+  Revision 1.101  2005/01/07 16:22:54  florian
     + implemented abi compliant handling of strucutured functions results on sparc platform
 
   Revision 1.100  2005/01/01 13:19:09  florian

+ 27 - 6
compiler/sparc/cpugas.pas

@@ -56,16 +56,19 @@ implementation
                  else if offset<0 then
                    GetReferenceString:=GetReferenceString+ToStr(offset);
                  case refaddr of
-                   addr_hi :
+                   addr_hi:
                      GetReferenceString:='%hi('+GetReferenceString+')';
-                   addr_lo :
+                   addr_lo:
                      GetReferenceString:='%lo('+GetReferenceString+')';
                  end;
               end
             else
               begin
-                if assigned(symbol) then
+{$ifdef extdebug}
+                if assigned(symbol) and
+                  not(refaddr in [addr_pic,addr_lo]) then
                   internalerror(2003052601);
+{$endif extdebug}
                 if base<>NR_NO then
                   GetReferenceString:=GetReferenceString+gas_regname(base);
                 if index=NR_NO then
@@ -76,11 +79,24 @@ implementation
                       GetReferenceString:=GetReferenceString+'+'+ToStr(offset)
                     else if offset<0 then
                       GetReferenceString:=GetReferenceString+ToStr(offset);
+                    {
+                    else if (offset=0) and not(assigned(symbol)) then
+                      GetReferenceString:=GetReferenceString+ToStr(offset);
+                    }
+                    if assigned(symbol) then
+                      begin
+                        if refaddr=addr_lo then
+                          GetReferenceString:='%lo('+symbol.name+')+'+GetReferenceString
+                        else
+                          GetReferenceString:=symbol.name+'+'+GetReferenceString;
+                      end;
                   end
                 else
                   begin
-                    if Offset<>0 then
+{$ifdef extdebug}
+                    if (Offset<>0) or assigned(symbol) then
                       internalerror(2003052603);
+{$endif extdebug}
                     GetReferenceString:=GetReferenceString+'+'+gas_regname(index);
                   end;
               end;
@@ -97,7 +113,8 @@ implementation
             top_const:
               getopstr:=tostr(longint(val));
             top_ref:
-              if Oper.ref^.refaddr=addr_no then
+              if (oper.ref^.refaddr in [addr_no,addr_pic]) or ((oper.ref^.refaddr=addr_lo) and ((oper.ref^.base<>NR_NO) or
+                (oper.ref^.index<>NR_NO))) then
                 getopstr:='['+getreferencestring(ref^)+']'
               else
                 getopstr:=getreferencestring(ref^);
@@ -189,7 +206,11 @@ begin
 end.
 {
     $Log$
-    Revision 1.30  2004-10-31 21:45:04  peter
+    Revision 1.31  2005-01-23 17:14:21  florian
+      + optimized code generation on sparc
+      + some stuff for pic code on sparc added
+
+    Revision 1.30  2004/10/31 21:45:04  peter
       * generic tlocation
       * move tlocation to cgutils