Browse Source

+ support of inlined ror/rol on arm

git-svn-id: trunk@11473 -
florian 17 years ago
parent
commit
fe7cba52dc
3 changed files with 58 additions and 2 deletions
  1. 50 0
      compiler/arm/cgcpu.pas
  2. 1 1
      compiler/options.pas
  3. 7 1
      rtl/inc/systemh.inc

+ 50 - 0
compiler/arm/cgcpu.pas

@@ -409,6 +409,34 @@ unit cgcpu;
                 else
                  list.concat(taicpu.op_reg_reg(A_MOV,dst,src));
               end;
+            OP_ROL:
+              begin
+                if a>32 then
+                  internalerror(200308294);
+                if a<>0 then
+                  begin
+                    shifterop_reset(so);
+                    so.shiftmode:=SM_ROR;
+                    so.shiftimm:=32-a;
+                    list.concat(taicpu.op_reg_reg_shifterop(A_MOV,dst,src,so));
+                  end
+                else
+                 list.concat(taicpu.op_reg_reg(A_MOV,dst,src));
+              end;
+            OP_ROR:
+              begin
+                if a>32 then
+                  internalerror(200308294);
+                if a<>0 then
+                  begin
+                    shifterop_reset(so);
+                    so.shiftmode:=SM_ROR;
+                    so.shiftimm:=a;
+                    list.concat(taicpu.op_reg_reg_shifterop(A_MOV,dst,src,so));
+                  end
+                else
+                 list.concat(taicpu.op_reg_reg(A_MOV,dst,src));
+              end;
             OP_SHR:
               begin
                 if a>32 then
@@ -518,6 +546,28 @@ unit cgcpu;
               so.shiftmode:=SM_ASR;
               list.concat(taicpu.op_reg_reg_shifterop(A_MOV,dst,src2,so));
             end;
+          OP_ROL:
+            begin
+              if not(size in [OS_32,OS_S32]) then
+                internalerror(2008072801);
+              { simulate ROL by ror'ing 32-value }
+              tmpreg:=getintregister(list,OS_32);
+              list.concat(taicpu.op_reg_const(A_MOV,tmpreg,32));
+              list.concat(taicpu.op_reg_reg_reg(A_SUB,src1,tmpreg,src1));
+              shifterop_reset(so);
+              so.rs:=src1;
+              so.shiftmode:=SM_ROR;
+              list.concat(taicpu.op_reg_reg_shifterop(A_MOV,dst,src2,so));
+            end;
+          OP_ROR:
+            begin
+              if not(size in [OS_32,OS_S32]) then
+                internalerror(2008072802);
+              shifterop_reset(so);
+              so.rs:=src1;
+              so.shiftmode:=SM_ROR;
+              list.concat(taicpu.op_reg_reg_shifterop(A_MOV,dst,src2,so));
+            end;
           OP_IMUL,
           OP_MUL:
             begin

+ 1 - 1
compiler/options.pas

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

+ 7 - 1
rtl/inc/systemh.inc

@@ -609,14 +609,20 @@ function NtoLE(const AValue: Int64): Int64;{$ifdef SYSTEMINLINE}inline;{$endif}
 function NtoLE(const AValue: QWord): QWord;{$ifdef SYSTEMINLINE}inline;{$endif}
 
 {$ifdef FPC_HAS_INTERNAL_ROX}
+
 {$if defined(cpux86_64) or defined(cpui386)}
 {$define FPC_HAS_INTERNAL_ROX_BYTE}
 {$define FPC_HAS_INTERNAL_ROX_WORD}
-{$define FPC_HAS_INTERNAL_ROX_DWORD}
 {$endif defined(cpux86_64) or defined(cpui386)}
+
+{$if defined(cpux86_64) or defined(cpui386) or defined(arm)}
+{$define FPC_HAS_INTERNAL_ROX_DWORD}
+{$endif defined(cpux86_64) or defined(cpui386) or defined(arm)}
+
 {$if defined(cpux86_64)}
 {$define FPC_HAS_INTERNAL_ROX_QWORD}
 {$endif defined(cpux86_64)}
+
 {$endif FPC_HAS_INTERNAL_ROX}
 
 {$ifdef FPC_HAS_INTERNAL_ROX_BYTE}