Browse Source

* rol/ror inlines for powerpc/powerpc64 (only for 32/64 bit operands for now)

git-svn-id: trunk@11770 -
tom_at_work 17 years ago
parent
commit
8a5a6db065

+ 1 - 1
compiler/options.pas

@@ -2198,7 +2198,7 @@ begin
 {$endif}
 
 { these cpus have an inline rol/ror implementaion }
-{$if defined(x86) or defined(arm)}
+{$if defined(x86) or defined(arm) or defined(powerpc) or defined(powerpc64)}
   def_system_macro('FPC_HAS_INTERNAL_ROX');
 {$endif}
 

+ 33 - 1
compiler/powerpc/cgcpu.pas

@@ -647,7 +647,21 @@ const
                 a_load_reg_reg(list,size,size,src,dst);
               if (a shr 5) <> 0 then
                 internalError(68991);
-            end
+            end;
+	  OP_ROL:
+	    begin
+	      if (not (size in [OS_32, OS_S32])) then begin
+	        internalerror(2008091307);
+	      end;    
+	      list.concat(taicpu.op_reg_reg_const_const_const(A_RLWINM, dst, src, a and 31, 0, 31));
+	    end;
+	  OP_ROR:
+	    begin
+	      if (not (size in [OS_32, OS_S32])) then begin
+		internalerror(2008091308);
+	      end;    
+	      list.concat(taicpu.op_reg_reg_const_const_const(A_RLWINM, dst, src, (32 - a) and 31, 0, 31));
+	    end
           else
             internalerror(200109091);
         end;
@@ -670,6 +684,8 @@ const
         op_reg_reg_opcg2asmop: array[TOpCG] of tasmop =
           (A_NONE,A_MR,A_ADD,A_AND,A_DIVWU,A_DIVW,A_MULLW,A_MULLW,A_NEG,A_NOT,A_OR,
            A_SRAW,A_SLW,A_SRW,A_SUB,A_XOR,A_NONE,A_NONE);
+      var
+        tmpreg : TRegister;
 
        begin
          if (op = OP_MOVE) then
@@ -683,6 +699,22 @@ const
                  { zero/sign extend result again }
                  a_load_reg_reg(list,OS_32,size,dst,dst);
               end;
+	   OP_ROL:
+	     begin
+	       if (not (size in [OS_32, OS_S32])) then begin
+	         internalerror(2008091305);
+	       end;
+	       list.concat(taicpu.op_reg_reg_reg_const_const(A_RLWNM, dst, src2, src1, 0, 31));
+	     end;
+	   OP_ROR:
+	     begin
+	       if (not (size in [OS_32, OS_S32])) then begin
+	         internalerror(2008091306);
+	       end;
+	       tmpreg := getintregister(current_asmdata.CurrAsmList, OS_INT);
+	       list.concat(taicpu.op_reg_reg(A_NEG, tmpreg, src1));
+	       list.concat(taicpu.op_reg_reg_reg_const_const(A_RLWNM, dst, src2, tmpreg, 0, 31));
+	     end;	
            else
              list.concat(taicpu.op_reg_reg_reg(op_reg_reg_opcg2asmop[op],dst,src2,src1));
          end;

+ 44 - 0
compiler/powerpc64/cgcpu.pas

@@ -1028,6 +1028,26 @@ begin
         list.concat(taicpu.op_reg_reg(A_NOT, dst, src))
       else
         do_lo_hi(A_XORI, A_XORIS);
+    OP_ROL:
+      begin
+        if (size in [OS_64, OS_S64]) then begin
+	  list.concat(taicpu.op_reg_reg_const_const(A_RLDICL, dst, src, a and 63, 0));
+	end else if (size in [OS_32, OS_S32]) then begin
+	  list.concat(taicpu.op_reg_reg_const_const_const(A_RLWINM, dst, src, a and 31, 0, 31));
+	end else begin
+	  internalerror(2008091303);
+	end;
+      end;
+    OP_ROR:
+      begin
+        if (size in [OS_64, OS_S64]) then begin
+	  list.concat(taicpu.op_reg_reg_const_const(A_RLDICL, dst, src, ((64 - a) and 63), 0));
+	end else if (size in [OS_32, OS_S32]) then begin
+	  list.concat(taicpu.op_reg_reg_const_const_const(A_RLWINM, dst, src, (32 - a) and 31, 0, 31));
+	end else begin
+	  internalerror(2008091304);
+	end;
+      end;
     OP_SHL, OP_SHR, OP_SAR:
       begin
         if (size in [OS_64, OS_S64]) then
@@ -1066,6 +1086,8 @@ const
   op_reg_reg_opcg2asmop64: array[TOpCG] of tasmop =
   (A_NONE, A_MR, A_ADD, A_AND, A_DIVDU, A_DIVD, A_MULLD, A_MULLD, A_NEG, A_NOT, A_OR,
    A_SRAD, A_SLD, A_SRD, A_SUB, A_XOR, A_NONE, A_NONE);
+var
+  tmpreg : TRegister;
 begin
   case op of
     OP_NEG, OP_NOT:
@@ -1075,6 +1097,28 @@ begin
           { zero/sign extend result again, fromsize is not important here }
           a_load_reg_reg(list, OS_S64, size, dst, dst)
       end;
+    OP_ROL:
+      begin
+        if (size in [OS_64, OS_S64]) then begin
+	  list.concat(taicpu.op_reg_reg_reg_const(A_RLDCL, dst, src2, src1, 0));
+	end else if (size in [OS_32, OS_S32]) then begin
+	  list.concat(taicpu.op_reg_reg_reg_const_const(A_RLWNM, dst, src2, src1, 0, 31));
+	end else begin
+	  internalerror(2008091301);
+	end;
+      end;
+    OP_ROR:
+      begin
+        tmpreg := getintregister(current_asmdata.CurrAsmList, OS_INT);
+	list.concat(taicpu.op_reg_reg(A_NEG, tmpreg, src1));
+        if (size in [OS_64, OS_S64]) then begin
+	  list.concat(taicpu.op_reg_reg_reg_const(A_RLDCL, dst, src2, tmpreg, 0));
+	end else if (size in [OS_32, OS_S32]) then begin
+	  list.concat(taicpu.op_reg_reg_reg_const_const(A_RLWNM, dst, src2, tmpreg, 0, 31));
+	end else begin
+	  internalerror(2008091302);
+	end;
+      end;
     else
       if (size in [OS_64, OS_S64]) then begin
         list.concat(taicpu.op_reg_reg_reg(op_reg_reg_opcg2asmop64[op], dst, src2,

+ 1 - 1
compiler/powerpc64/cpubase.pas

@@ -93,7 +93,7 @@ type
     A_CMPD, A_CMPDI, A_CMPLD, A_CMPLDI,
     A_SRDI, A_SRADI,
     A_SLDI,
-    A_RLDICL,
+    A_RLDCL, A_RLDICL,
     A_DIVDU, A_DIVDU_, A_DIVD, A_DIVD_, A_MULLD, A_MULLD_, A_MULHD, A_MULHD_, A_SRAD, A_SLD, A_SRD,
     A_DIVDUO_, A_DIVDO_,
     A_LWA, A_LWAX, A_LWAUX,

+ 1 - 1
compiler/powerpc64/itcpugas.pas

@@ -83,7 +83,7 @@ const
     'cmpd', 'cmpdi', 'cmpld', 'cmpldi',
     'srdi', 'sradi',
     'sldi',
-    'rldicl',
+    'rldcl', 'rldicl',
     'divdu', 'divdu.', 'divd', 'divd.', 'mulld', 'mulld.', 'mulhd', 'mulhd.', 'srad', 'sld', 'srd',
     'divduo.', 'divdo.',
     'lwa', 'lwax', 'lwaux',

+ 10 - 0
compiler/ppcgen/aasmcpu.pas

@@ -65,6 +65,7 @@ uses
          constructor op_reg_bool_reg_reg(op : tasmop;_op1: tregister;_op2:boolean;_op3,_op4:tregister);
          constructor op_reg_bool_reg_const(op : tasmop;_op1: tregister;_op2:boolean;_op3:tregister;_op4: aint);
 
+         constructor op_reg_reg_reg_const(op : tasmop; _op1, _op2, _op3 : tregister; _op4 : aint);
          constructor op_reg_reg_reg_const_const(op : tasmop;_op1,_op2,_op3 : tregister;_op4,_op5 : aint);
          constructor op_reg_reg_const_const_const(op : tasmop;_op1,_op2 : tregister;_op3,_op4,_op5 : aint);
 
@@ -294,6 +295,15 @@ uses cutils, cclasses;
          loadconst(0,cardinal(_op4));
       end;
 
+     constructor taicpu.op_reg_reg_reg_const(op : tasmop; _op1, _op2, _op3 : tregister; _op4 : aint);
+      begin
+        inherited create(op);
+	ops := 4;
+	loadreg(0, _op1);
+	loadreg(1, _op2);
+	loadreg(2, _op3);
+	loadconst(3, cardinal(_op4));
+      end;
 
      constructor taicpu.op_reg_reg_reg_const_const(op : tasmop;_op1,_op2,_op3 : tregister;_op4,_op5 : aint);
       begin

+ 4 - 4
rtl/inc/systemh.inc

@@ -623,13 +623,13 @@ function NtoLE(const AValue: QWord): QWord;{$ifdef SYSTEMINLINE}inline;{$endif}
 {$define FPC_HAS_INTERNAL_ROX_WORD}
 {$endif defined(cpux86_64) or defined(cpui386)}
 
-{$if defined(cpux86_64) or defined(cpui386) or defined(arm)}
+{$if defined(cpux86_64) or defined(cpui386) or defined(arm) or defined(powerpc) or defined(powerpc64)}
 {$define FPC_HAS_INTERNAL_ROX_DWORD}
-{$endif defined(cpux86_64) or defined(cpui386) or defined(arm)}
+{$endif defined(cpux86_64) or defined(cpui386) or defined(arm) or defined(powerpc) or defined(powerpc64)}
 
-{$if defined(cpux86_64)}
+{$if defined(cpux86_64) or defined(powerpc64)}
 {$define FPC_HAS_INTERNAL_ROX_QWORD}
-{$endif defined(cpux86_64)}
+{$endif defined(cpux86_64) or defined(powerpc64)}
 
 {$endif FPC_HAS_INTERNAL_ROX}