Ver Fonte

* more misc. fixes, mostly constant-related

Jonas Maebe há 23 anos atrás
pai
commit
8ff3e3e1b3
3 ficheiros alterados com 85 adições e 62 exclusões
  1. 34 33
      compiler/powerpc/cgcpu.pas
  2. 6 4
      compiler/powerpc/cpubase.pas
  3. 45 25
      compiler/powerpc/nppcadd.pas

+ 34 - 33
compiler/powerpc/cgcpu.pas

@@ -441,15 +441,10 @@ const
         useReg, gotrlwi: boolean;
 
 
-        function try_lo_hi: boolean;
+        procedure do_lo_hi;
           begin
-            result := false;
-            if (smallint(a) > 0) then
-              begin
-                list.concat(taicpu.op_reg_reg_const(oplo,dst,src,smallint(a)));
-                list.concat(taicpu.op_reg_reg_const(ophi,dst,dst,smallint(a shr 16)));
-                result := true;
-              end;
+            list.concat(taicpu.op_reg_reg_const(oplo,dst,src,word(a)));
+            list.concat(taicpu.op_reg_reg_const(ophi,dst,dst,word(a shr 16)));
           end;
 
       begin
@@ -469,9 +464,6 @@ const
         ophi := TOpCG2AsmOpConstHi[op];
         oplo := TOpCG2AsmOpConstLo[op];
         gotrlwi := get_rlwi_const(a,l1,l2);
-        { constants in a PPC instruction are always interpreted as signed }
-        { 16bit values, so if the value is between low(smallint) and      }
-        { high(smallint), it's easy                                       }
         if (op in [OP_ADD,OP_AND,OP_OR,OP_XOR]) then
           begin
             if (a = 0) then
@@ -481,18 +473,23 @@ const
                 exit;
               end
             else if (a = high(aword)) and
-                    (op in [OP_AND,OP_OR]) then
+                    (op in [OP_AND,OP_OR,OP_XOR]) then
               begin
-                if op = OP_OR then
-                  list.concat(taicpu.op_reg_const(A_LI,dst,-1));
+                case op of
+                  OP_OR:
+                    list.concat(taicpu.op_reg_const(A_LI,dst,-1));
+                  OP_XOR:
+                    list.concat(taicpu.op_reg_reg(A_NOT,dst,src));
+                end;
                 exit;
               end
-            else if (longint(a) >= low(smallint)) and
-               (longint(a) <= high(smallint)) and
+            else if (longint(a) >= 0)) and
+               (longint(a) <= high(word)) and
+               (op <> OP_ADD) and
                ((op <> OP_AND) or
-                 not gotrlwi) then
+                not gotrlwi) then
               begin
-                list.concat(taicpu.op_reg_reg_const(oplo,dst,src,smallint(a)));
+                list.concat(taicpu.op_reg_reg_const(oplo,dst,src,word(a)));
                 exit;
               end;
             { all basic constant instructions also have a shifted form that }
@@ -502,7 +499,7 @@ const
                (not(op = OP_AND) or
                 not gotrlwi) then
               begin
-                list.concat(taicpu.op_reg_reg_const(ophi,dst,src,smallint(a shr 16)));
+                list.concat(taicpu.op_reg_reg_const(ophi,dst,src,word(a shr 16)));
                 exit;
               end;
           end;
@@ -526,18 +523,17 @@ const
             end;
           OP_OR:
             { try to use rlwimi }
-            if gotrlwi then
+            if gotrlwi and
+               (src = dst) then
               begin
-                if src <> dst then
-                  list.concat(taicpu.op_reg_reg(A_MR,dst,src));
                 scratchreg := get_scratch_reg_int(list);
                 list.concat(taicpu.op_reg_const(A_LI,scratchreg,-1));
                 list.concat(taicpu.op_reg_reg_const_const_const(A_RLWIMI,dst,
                   scratchreg,0,l1,l2));
                 free_scratch_reg(list,scratchreg);
               end
-            else if not try_lo_hi then
-              useReg := true;
+            else
+              do_lo_hi;
           OP_AND:
             { try to use rlwinm }
             if gotrlwi then
@@ -546,8 +542,7 @@ const
             else
               useReg := true;
           OP_XOR:
-            if not try_lo_hi then
-              usereg := true;
+            do_lo_hi;
           OP_SHL,OP_SHR,OP_SAR:
             begin
               if (a and 31) <> 0 Then
@@ -1017,6 +1012,7 @@ const
                   if delsource then
                     reference_release(exprasmlist,source);
                   a_loadfpu_reg_ref(list,OS_F64,R_F0,dest);
+                  a_reg_dealloc(list,R_F0);
                 end;
               exit;
             end;
@@ -1129,7 +1125,6 @@ const
        if (len and 1) <> 0 then
          begin
            a_reg_alloc(list,R_0);
-           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);
@@ -1416,11 +1411,11 @@ const
               if (longint(value) <> 0) then
                 begin
                   issub := op = OP_SUB;
-                  if (longint(value) >= -32768) and
-                     (longint(value) <= 32767) then
+                  if (longint(value)-ord(issub) >= -32768) and
+                     (longint(value)-ord(issub) <= 32767) then
                     begin
                       list.concat(taicpu.op_reg_reg_const(ops[issub,1],
-                        regdst.reglo,regsrc.reglo,aword(value)));
+                        regdst.reglo,regsrc.reglo,longint(value)));
                       list.concat(taicpu.op_reg_reg(ops[issub,3],
                         regdst.reghi,regsrc.reghi));
                     end
@@ -1445,8 +1440,11 @@ const
                     end
                 end
               else
-                cg.a_op_const_reg_reg(list,op,OS_32,value shr 32,regsrc.reghi,
-                  regdst.reghi);
+                begin
+                  cg.a_load_reg_reg(list,OS_INT,regsrc.reglo,regdst.reglo);
+                  cg.a_op_const_reg_reg(list,op,OS_32,value shr 32,regsrc.reghi,
+                    regdst.reghi);
+                end;
             end;
           else
             internalerror(2002072802);
@@ -1460,7 +1458,10 @@ begin
 end.
 {
   $Log$
-  Revision 1.32  2002-08-02 11:10:42  jonas
+  Revision 1.33  2002-08-04 12:57:55  jonas
+    * more misc. fixes, mostly constant-related
+
+  Revision 1.32  2002/08/02 11:10:42  jonas
     * some misc constant fixes
 
   Revision 1.31  2002/07/30 20:50:44  florian

+ 6 - 4
compiler/powerpc/cpubase.pas

@@ -632,22 +632,24 @@ implementation
 
 
     procedure create_cond_norm(cond: TAsmCondFlag; cr: byte;var r : TasmCond);
-      const cr2reg: array[0..7] of tregister =
-              (R_CR0,R_CR1,R_CR2,R_CR3,R_CR4,R_CR5,R_CR6,R_CR7);
+
       begin
         r.simple := true;
         r.cond := cond;
         case cond of
           C_NONE:;
           C_T..C_DZF: r.crbit := cr
-          else r.cr := cr2reg[cr];
+          else r.cr := tregister(ord(R_CR0)+cr);
         end;
       end;
 
 end.
 {
   $Log$
-  Revision 1.22  2002-07-27 19:57:18  jonas
+  Revision 1.23  2002-08-04 12:57:56  jonas
+    * more misc. fixes, mostly constant-related
+
+  Revision 1.22  2002/07/27 19:57:18  jonas
     * some typo corrections in the instruction tables
     * renamed the m* registers to v*
 

+ 45 - 25
compiler/powerpc/nppcadd.pas

@@ -197,21 +197,25 @@ interface
         // constant in a register first?
         if (right.location.loc = LOC_CONSTANT) then
           begin
+{$ifdef extdebug}
+            if (qword(right.location.value) > high(cardinal)) then
+              internalerror(2002080301);
+{$endif extdebug}
             if (nodetype in [equaln,unequaln]) then
               if (unsigned and
                   (right.location.value > high(word))) or
                  (not unsigned and
-                  ((longint(right.location.value) < low(smallint)) or
-                   (longint(right.location.value) > high(smallint)))) then
+                  (right.location.value < low(smallint)) or
+                   (right.location.value > high(smallint)))) then
                 // we can then maybe use a constant in the 'othersigned' case
                 // (the sign doesn't matter for // equal/unequal)
                 unsigned := not unsigned;
 
             if (unsigned and
-                (aword(right.location.value) <= high(word))) or
+                (qword(right.location.value) <= high(word))) or
                (not(unsigned) and
-                (longint(right.location.value) >= low(smallint)) and
-                (longint(right.location.value) <= high(smallint))) then
+                (right.location.value >= low(smallint)) and
+                (right.location.value <= high(smallint))) then
                useconst := true
             else
               begin
@@ -366,7 +370,7 @@ interface
                       location.register)
                   else
                     cg.a_op_const_reg_reg(exprasmlist,cgop,OS_INT,
-                      right.location.value,left.location.register,
+                      aword(right.location.value),left.location.register,
                       location.register);
                 end;
             end;
@@ -547,7 +551,7 @@ interface
                    internalerror(43244);
                   if (right.location.loc = LOC_CONSTANT) then
                     cg.a_op_const_reg_reg(exprasmlist,OP_OR,OS_INT,
-                      1 shl right.location.value,
+                      aword(1 shl aword(right.location.value)),
                       left.location.register,location.register)
                   else
                     begin
@@ -560,7 +564,7 @@ interface
                           left.location.register,location.register)
                       else
                         cg.a_op_const_reg_reg(exprasmlist,OP_OR,OS_INT,
-                          left.location.value,tmpreg,location.register);
+                          aword(left.location.value),tmpreg,location.register);
                       cg.free_scratch_reg(exprasmlist,tmpreg);
                     end;
                   opdone := true;
@@ -593,7 +597,7 @@ interface
                     begin
                       tmpreg := cg.get_scratch_reg_int(exprasmlist);
                       cg.a_load_const_reg(exprasmlist,OS_INT,
-                        left.location.value,tmpreg);
+                        aword(left.location.value),tmpreg);
                       exprasmlist.concat(taicpu.op_reg_reg_reg(A_ANDC,
                         location.register,tmpreg,right.location.register));
                       cg.free_scratch_reg(exprasmlist,tmpreg);
@@ -621,18 +625,15 @@ interface
               tmpreg := cg.get_scratch_reg_int(exprasmlist);
               if left.location.loc = LOC_CONSTANT then
                 begin
-                  cg.a_op_const_reg_reg(exprasmlist,OP_AND,OS_INT,
-                    not(left.location.value),right.location.register,tmpreg);
-                  exprasmlist.concat(taicpu.op_reg_const(A_CMPWI,tmpreg,0));
-                  // the two instructions above should be folded together by
-                  // the peepholeoptimizer
+                  cg.a_op_const_reg_reg(exprasmlist,OP_AND_,OS_INT,
+                    not(aword(left.location.value)),right.location.register,tmpreg);
                 end
               else
                 begin
                   if right.location.loc = LOC_CONSTANT then
                     begin
                       cg.a_load_const_reg(exprasmlist,OS_INT,
-                        right.location.value,tmpreg);
+                        aword(right.location.value),tmpreg);
                       exprasmlist.concat(taicpu.op_reg_reg_reg(A_ANDC_,tmpreg,
                         tmpreg,left.location.register));
                     end
@@ -656,7 +657,8 @@ interface
               swapleftright;
             if (right.location.loc = LOC_CONSTANT) then
               cg.a_op_const_reg_reg(exprasmlist,cgop,OS_INT,
-                right.location.value,left.location.register,location.register)
+                aword(right.location.value),left.location.register,
+                location.register)
             else
               cg.a_op_reg_reg_reg(exprasmlist,cgop,OS_INT,
                 right.location.register,left.location.register,
@@ -842,11 +844,26 @@ interface
             if (nf_swaped in flags) then
               swapleftright;
             if left.location.loc = LOC_CONSTANT then
-              begin
-                location_force_reg(exprasmlist,left.location,
-                  def_cgsize(left.resulttype.def),false);
-                location.register64 := left.location.register64;
-              end;
+              if not(cs_check_overflow in aktlocalswitches) and
+                 (left.location.value >= low(smallint)) and
+                 (left.location.value <= high(smallint)) then
+                begin
+                  // optimize
+                  exprasmlist.concat(taicpu.op_reg_reg_const(A_SUBFIC,
+                    location.register,right.location.registerlow,
+                    left.location.value));
+                  exprasmlist.concat(taicpu.op_reg_reg(A_SUBFZE,
+                    location.register,right.location.registerhigh));
+                  clear_left_right(false);
+                  exit;
+                end
+              else
+                begin
+                  // load constant in register
+                  location_force_reg(exprasmlist,left.location,
+                    def_cgsize(left.resulttype.def),false);
+                  location.register64 := left.location.register64;
+                end;
            end;
 
         if not(cs_check_overflow in aktlocalswitches) or
@@ -867,7 +884,7 @@ interface
                   if left.location.loc = LOC_CONSTANT then
                     swapleftright;
                   if (right.location.loc = LOC_CONSTANT) then
-                    cg64.a_op64_const_reg_reg(exprasmlist,op,right.location.value,
+                    cg64.a_op64_const_reg_reg(exprasmlist,op,qword(right.location.value),
                       left.location.register64,location.register64)
                   else
                     cg64.a_op64_reg_reg_reg(exprasmlist,op,right.location.register64,
@@ -888,7 +905,7 @@ interface
               subn:
                 begin
                   op1 := A_SUBC;
-                  op2 := A_SUBFMEO;
+                  op2 := A_SUBFEO;
                 end;
               else
                 internalerror(2002072806);
@@ -1244,7 +1261,7 @@ interface
                        begin
                          tmpreg := cg.get_scratch_reg_int(exprasmlist);
                          cg.a_load_const_reg(exprasmlist,OS_INT,
-                           left.location.value,tmpreg);
+                           aword(left.location.value),tmpreg);
                          cg.a_op_reg_reg_reg(exprasmlist,OP_SUB,OS_INT,
                            right.location.register,tmpreg,location.register);
                          cg.free_scratch_reg(exprasmlist,tmpreg);
@@ -1282,7 +1299,10 @@ begin
 end.
 {
   $Log$
-  Revision 1.3  2002-07-28 16:02:49  jonas
+  Revision 1.4  2002-08-04 12:57:56  jonas
+    * more misc. fixes, mostly constant-related
+
+  Revision 1.3  2002/07/28 16:02:49  jonas
     + 64 bit operations (badly tested), everything is implemented now!
     * some small fixes