Explorar el Código

* unarynminus and shlshr node fixed for 32bit and smaller ordinals
* small fixes in the assembler writer
* changed scratch registers, because they were used by the linker (r11
and r12) and by the abi under linux (r31)

Jonas Maebe hace 23 años
padre
commit
3e7b6ef7fa
Se han modificado 4 ficheros con 120 adiciones y 83 borrados
  1. 18 5
      compiler/powerpc/agppcgas.pas
  2. 49 17
      compiler/powerpc/cgcpu.pas
  3. 21 5
      compiler/powerpc/cpubase.pas
  4. 32 56
      compiler/powerpc/nppcmat.pas

+ 18 - 5
compiler/powerpc/agppcgas.pas

@@ -25,6 +25,8 @@
 
 unit agppcgas;
 
+{$i fpcdefs.inc}
+
   interface
 
     uses
@@ -286,7 +288,7 @@ unit agppcgas;
           else
             begin
               internalerror(2002070601);
-              { not yet implementer !!!!!!!!!!!!!!!!!!!!! }
+              { not yet implemented !!!!!!!!!!!!!!!!!!!!! }
               { case tempstr := 'tw';}
             end;
       end;
@@ -300,9 +302,14 @@ unit agppcgas;
     begin
       op:=taicpu(hp).opcode;
       if is_calljmp(op) then
-      { direct BO/BI in op[0] and op[1] not supported, put them in condition! }
-        s:=cond2str(op,taicpu(hp).condition)+
-           getopstr_jmp(taicpu(hp).oper[0])
+        begin
+          { direct BO/BI in op[0] and op[1] not supported, put them in condition! }
+          if op <> A_B then
+            s:=cond2str(op,taicpu(hp).condition)+','
+          else
+            s:='';
+          s := s+getopstr_jmp(taicpu(hp).oper[0]);
+        end
       else
         { process operands }
         begin
@@ -330,7 +337,13 @@ begin
 end.
 {
   $Log$
-  Revision 1.1  2002-07-07 09:44:31  florian
+  Revision 1.2  2002-07-09 19:45:01  jonas
+    * unarynminus and shlshr node fixed for 32bit and smaller ordinals
+    * small fixes in the assembler writer
+    * changed scratch registers, because they were used by the linker (r11
+      and r12) and by the abi under linux (r31)
+
+  Revision 1.1  2002/07/07 09:44:31  florian
     * powerpc target fixed, very simple units can be compiled
 
   Revision 1.6  2002/05/18 13:34:26  peter

+ 49 - 17
compiler/powerpc/cgcpu.pas

@@ -71,6 +71,7 @@ unit cgcpu;
           l : tasmlabel);override;
         procedure a_cmp_reg_reg_label(list : taasmoutput;size : tcgsize;cmp_op : topcmp;reg1,reg2 : tregister;l : tasmlabel); override;
 
+	procedure a_jmp_always(list : taasmoutput;l: tasmlabel); override;
         procedure a_jmp_flags(list : taasmoutput;const f : TResFlags;l: tasmlabel); override;
 
         procedure g_flags2reg(list: taasmoutput; const f: TResFlags; reg: TRegister); override;
@@ -320,7 +321,8 @@ const
      procedure tcgppc.a_load_reg_reg(list : taasmoutput;size : tcgsize;reg1,reg2 : tregister);
 
        begin
-         list.concat(taicpu.op_reg_reg(A_MR,reg2,reg1));
+         if (reg1 <> reg2) then
+           list.concat(taicpu.op_reg_reg(A_MR,reg2,reg1));
        end;
 
 
@@ -578,6 +580,12 @@ const
          a_jmp(list,A_BC,TOpCmp2AsmCond[cond],0,l);
        end;
 
+     procedure tcgppc.a_jmp_always(list : taasmoutput;l: tasmlabel); 
+
+       begin
+         a_jmp(list,A_B,C_None,0,l);
+       end;
+
      procedure tcgppc.a_jmp_flags(list : taasmoutput;const f : TResFlags;l: tasmlabel);
 
        var
@@ -853,8 +861,8 @@ const
                  ref2.base,tmpref))
              else
                list.concat(taicpu.op_reg_ref(A_LIS,tmpreg,tmpref));
-             ref2.base := tmpreg;
-             ref2.symaddr := refs_l;
+             tmpref.base := tmpreg;
+             tmpref.symaddr := refs_l;
              { can be folded with one of the next instructions by the }
              { optimizer probably                                     }
              list.concat(taicpu.op_reg_reg_ref(A_ADDI,tmpreg,tmpreg,tmpref));
@@ -887,6 +895,18 @@ const
         count, count2: aword;
 
       begin
+        { make sure short loads are handled as optimally as possible }
+
+        if not loadref then
+          if (len <= 4) and
+             (byte(len) in [1,2,4]) then
+            begin
+              a_load_ref_ref(list,int_cgsize(len),source,dest);
+              if delsource then
+                reference_release(exprasmlist,source);
+              exit;
+            end;
+
         { make sure source and dest are valid }
         src := source;
         fixref(list,src);
@@ -911,9 +931,9 @@ const
             { the offsets are zero after the a_loadaddress_ref_reg and just }
             { have to be set to 4. I put an Inc there so debugging may be   }
             { easier (should offset be different from zero here, it will be }
-            { easy to notice in the genreated assembler                     }
-            Inc(dst.offset,4);
-            Inc(src.offset,4);
+            { easy to notice in the generated assembler                     }
+            inc(dst.offset,4);
+            inc(src.offset,4);
             list.concat(taicpu.op_reg_reg_const(A_SUBI,src.base,src.base,4));
             list.concat(taicpu.op_reg_reg_const(A_SUBI,dst.base,dst.base,4));
             countreg := get_scratch_reg_int(list);
@@ -930,33 +950,38 @@ const
             list.concat(taicpu.op_reg_reg_const(A_SUBI,countreg,countreg,1));
             a_jmp(list,A_BC,C_NE,0,lab);
             free_scratch_reg(list,countreg);
+            a_reg_dealloc(list,R_0);
           end
         else
           { unrolled loop }
           begin
-            tempreg := get_scratch_reg_int(list);
+            a_reg_alloc(list,R_0);
             for count2 := 1 to count do
               begin
-                a_load_ref_reg(list,OS_32,src,tempreg);
-                a_load_reg_ref(list,OS_32,tempreg,dst);
+                a_load_ref_reg(list,OS_32,src,R_0);
+                a_load_reg_ref(list,OS_32,R_0,dst);
                 inc(src.offset,4);
                 inc(dst.offset,4);
-              end
+              end;
+            a_reg_dealloc(list,R_0);
           end;
        { copy the leftovers }
        if (len and 2) <> 0 then
          begin
-           a_load_ref_reg(list,OS_16,src,tempreg);
-           a_load_reg_ref(list,OS_16,tempreg,dst);
+           a_reg_alloc(list,R_0);
+           a_load_ref_reg(list,OS_16,src,R_0);
+           a_load_reg_ref(list,OS_16,R_0,dst);
            inc(src.offset,2);
            inc(dst.offset,2);
+           a_reg_dealloc(list,R_0);
          end;
        if (len and 1) <> 0 then
          begin
-           a_load_ref_reg(list,OS_8,src,tempreg);
-           a_load_reg_ref(list,OS_8,tempreg,dst);
+           a_load_reg_ref(list,OS_16,R_0,dst);
+           a_load_ref_reg(list,OS_8,src,R_0);
+           a_load_reg_ref(list,OS_8,R_0,dst);
+           a_reg_dealloc(list,R_0);
          end;
-       a_reg_dealloc(list,tempreg);
        free_scratch_reg(list,src.base);
        free_scratch_reg(list,dst.base);
       end;
@@ -1165,7 +1190,8 @@ const
 
       begin
         p := taicpu.op_sym(op,newasmsymbol(l.name));
-        create_cond_norm(c,crval,p.condition);
+        if op <> A_B then
+          create_cond_norm(c,crval,p.condition);
         p.is_jmp := true;
         list.concat(p)
       end;
@@ -1175,7 +1201,13 @@ begin
 end.
 {
   $Log$
-  Revision 1.20  2002-07-07 09:44:31  florian
+  Revision 1.21  2002-07-09 19:45:01  jonas
+    * unarynminus and shlshr node fixed for 32bit and smaller ordinals
+    * small fixes in the assembler writer
+    * changed scratch registers, because they were used by the linker (r11
+      and r12) and by the abi under linux (r31)
+
+  Revision 1.20  2002/07/07 09:44:31  florian
     * powerpc target fixed, very simple units can be compiled
 
   Revision 1.19  2002/05/20 13:30:41  carl

+ 21 - 5
compiler/powerpc/cpubase.pas

@@ -463,7 +463,7 @@ uses
          routine calls or in assembler blocks.
       }
       max_scratch_regs = 3;
-      scratch_regs: Array[1..max_scratch_regs] of TRegister = (R_11,R_12,R_31);
+      scratch_regs: Array[1..max_scratch_regs] of TRegister = (R_28,R_29,R_30);
 
 {*****************************************************************************
                           Default generic sizes
@@ -544,7 +544,8 @@ uses
 
     function  is_calljmp(o:tasmop):boolean;
 
-    procedure inverse_cond(c: TAsmCond;var r : TAsmCond);
+    procedure inverse_flags(var r : TResFlags);
+    procedure inverse_cond(const c: TAsmCond;var r : TAsmCond);
     function  flags_to_cond(const f: TResFlags) : TAsmCond;
     procedure create_cond_imm(BO,BI:byte;var r : TAsmCond);
     procedure create_cond_norm(cond: TAsmCondFlag; cr: byte;var r : TasmCond);
@@ -568,15 +569,24 @@ implementation
         end;
       end;
 
+ 
+    procedure inverse_flags(var r: TResFlags);
+      const
+        inv_flags: array[F_EQ..F_GE] of TResFlagsEnum =
+          (F_NE,F_EQ,F_GE,F_GE,F_LE,F_LT);
+      begin
+        r.flag := inv_flags[r.flag];
+      end;
 
-    procedure inverse_cond(c: TAsmCond;var r : TAsmCond);
+
+    procedure inverse_cond(const c: TAsmCond;var r : TAsmCond);
       const
         inv_condflags:array[TAsmCondFlag] of TAsmCondFlag=(C_None,
           C_GE,C_GT,C_NE,C_LT,C_LE,C_LT,C_EQ,C_GT,C_NS,C_SO,C_NU,C_UN,
           C_F,C_T,C_DNZ,C_DNZF,C_DNZT,C_DZ,C_DZF,C_DZT);
       begin
-        c.cond := inv_condflags[c.cond];
         r := c;
+        r.cond := inv_condflags[c.cond];
       end;
 
 
@@ -617,7 +627,13 @@ implementation
 end.
 {
   $Log$
-  Revision 1.15  2002-07-07 09:44:31  florian
+  Revision 1.16  2002-07-09 19:45:01  jonas
+    * unarynminus and shlshr node fixed for 32bit and smaller ordinals
+    * small fixes in the assembler writer
+    * changed scratch registers, because they were used by the linker (r11
+      and r12) and by the abi under linux (r31)
+
+  Revision 1.15  2002/07/07 09:44:31  florian
     * powerpc target fixed, very simple units can be compiled
 
   Revision 1.14  2002/05/18 13:34:26  peter

+ 32 - 56
compiler/powerpc/nppcmat.pas

@@ -206,7 +206,7 @@ implementation
                    location.registerhigh := hregisterhigh;
                    hregisterlow := rg.getregisterint(exprasmlist);
                    location.registerlow := hregisterlow;
-                   tcg64f32(cg).a_load64_ref_reg(exprasmlist,
+                   cg64.a_load64_ref_reg(exprasmlist,
                      left.location.reference,joinreg64(hregisterlow,hregisterhigh));
                  end;
              end;
@@ -315,25 +315,17 @@ implementation
          else
            begin
              { load left operators in a register }
-             if (left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
-               begin
-                 reference_release(exprasmlist,left.location.reference);
-                 hregister1 := rg.getregisterint(exprasmlist);
-                 { OS_32 because everything is always converted to longint/ }
-                 { cardinal in the resulttype pass (JM)                     }
-                 cg.a_load_ref_reg(exprasmlist,OS_32,left.location.reference,
-                   hregister1);
-                 resultreg := hregister1;
-               end
-             else
+             location_force_reg(exprasmlist,left.location,def_cgsize(left.resulttype.def),true);
+             location_copy(location,left.location);
+             resultreg := location.register;
+             hregister1 := location.register;
+             if (location.loc = LOC_CREGISTER) then
                begin
-                 hregister1 := left.location.register;
-                 if left.location.loc = LOC_CREGISTER then
-                   resultreg := rg.getregisterint(exprasmlist)
-                 else
-                   resultreg := hregister1;
+                 location.loc := LOC_REGISTER;
+                 resultreg := rg.getregisterint(exprasmlist);
+                 location.register := resultreg;
                end;
-
+              
               { determine operator }
               if nodetype=shln then
                 op:=OP_SHL
@@ -347,29 +339,14 @@ implementation
               else
                 begin
                   { load shift count in a register if necessary }
-                  case right.location.loc of
-                    LOC_CREGISTER, LOC_REGISTER:
-                      hregister2 := right.location.register;
-                    LOC_REFERENCE, LOC_CREFERENCE:
-                      begin
-                        hregister2 := cg.get_scratch_reg_int(exprasmlist);
-                        cg.a_load_ref_reg(exprasmlist,OS_32,
-                          right.location.reference,hregister2);
-                        reference_release(exprasmlist,right.location.reference);
-                      end;
-                  end;
+                  location_force_reg(exprasmlist,right.location,def_cgsize(right.resulttype.def),true);
+                  hregister2 := right.location.register;
 
                   tcgppc(cg).a_op_reg_reg_reg(exprasmlist,op,OS_32,hregister1,
                     hregister2,resultreg);
 
-                  if right.location.loc in [LOC_REFERENCE,LOC_CREFERENCE] then
-                    cg.free_scratch_reg(exprasmlist,hregister2)
-                  else
-                    rg.ungetregister(exprasmlist,hregister2);
+                  rg.ungetregister(exprasmlist,hregister2);
                 end;
-              { set result location }
-              location.loc:=LOC_REGISTER;
-              location.register:=resultreg;
            end;
       end;
 
@@ -391,8 +368,8 @@ implementation
              location_force_reg(exprasmlist,left.location,def_cgsize(left.resulttype.def),false);
              location_copy(location,left.location);
              exprasmlist.concat(taicpu.op_reg_reg(A_NEG,location.registerlow,
-               src1));
-             cg.a_op_reg_reg(exprasmlist,OP_NOT,OS_32,src2,location.registerhigh);
+               location.registerlow));
+             cg.a_op_reg_reg(exprasmlist,OP_NOT,OS_32,location.registerhigh,location.registerhigh);
              tmp := cg.get_scratch_reg_int(exprasmlist);
              cg.a_op_const_reg_reg(exprasmlist,OP_SAR,OS_32,31,location.registerlow,
                tmp);
@@ -406,6 +383,7 @@ implementation
            end
          else
            begin
+              location_copy(location,left.location);
               location.loc:=LOC_REGISTER;
               case left.location.loc of
                 LOC_FPUREGISTER, LOC_REGISTER:
@@ -495,26 +473,18 @@ implementation
                 end;
               LOC_FLAGS :
                 begin
-                  location.resflags:=left.location.resflags;
-{$warning !!!}
-//                  inverse_flags(left.location.resflags);
+                  location_copy(location,left.location);
+                  inverse_flags(location.resflags);
                 end;
               LOC_REGISTER, LOC_CREGISTER, LOC_REFERENCE, LOC_CREFERENCE :
                 begin
-                  if left.location.loc in [LOC_REGISTER,LOC_CREGISTER] then
-                    regl := left.location.register
-                  else
-                    begin
-                      regl := rg.getregisterint(exprasmlist);
-                      cg.a_load_ref_reg(exprasmlist,def_cgsize(left.resulttype.def),
-                        left.location.reference,regl);
-                    end;
-                  location.loc:=LOC_FLAGS;
+                  location_force_reg(exprasmlist,left.location,def_cgsize(left.resulttype.def),true);
+                  exprasmlist.concat(taicpu.op_reg_const(A_CMPWI,left.location.register,0));
+                  location_release(exprasmlist,left.location);
+                  location_reset(location,LOC_FLAGS,OS_NO);
                   location.resflags.cr:=r_cr0;
                   location.resflags.flag:=F_EQ;
-                  exprasmlist.concat(taicpu.op_reg_const(A_CMPWI,regl,0));
-                  rg.ungetregister(exprasmlist,regl);
-                end;
+               end;  
             end;
           end
          else if is_64bitint(left.resulttype.def) then
@@ -524,9 +494,9 @@ implementation
              location_copy(location,left.location);
              { perform the NOT operation }
              exprasmlist.concat(taicpu.op_reg_reg(A_NOT,location.registerhigh,
-               regh));
+               location.registerhigh));
              exprasmlist.concat(taicpu.op_reg_reg(A_NOT,location.registerlow,
-               regl));
+               location.registerlow));
            end
          else
            begin
@@ -549,7 +519,13 @@ begin
 end.
 {
   $Log$
-  Revision 1.11  2002-07-07 09:44:32  florian
+  Revision 1.12  2002-07-09 19:45:01  jonas
+    * unarynminus and shlshr node fixed for 32bit and smaller ordinals
+    * small fixes in the assembler writer
+    * changed scratch registers, because they were used by the linker (r11
+      and r12) and by the abi under linux (r31)
+
+  Revision 1.11  2002/07/07 09:44:32  florian
     * powerpc target fixed, very simple units can be compiled
 
   Revision 1.10  2002/05/20 13:30:42  carl