From fe7cba52dc30dcb0f1ce22dd2212f46db5a853ce Mon Sep 17 00:00:00 2001 From: florian Date: Mon, 28 Jul 2008 15:48:38 +0000 Subject: [PATCH] + support of inlined ror/rol on arm git-svn-id: trunk@11473 - --- compiler/arm/cgcpu.pas | 50 ++++++++++++++++++++++++++++++++++++++++++ compiler/options.pas | 2 +- rtl/inc/systemh.inc | 8 ++++++- 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/compiler/arm/cgcpu.pas b/compiler/arm/cgcpu.pas index de3137758c..ed54d1fef8 100644 --- a/compiler/arm/cgcpu.pas +++ b/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 diff --git a/compiler/options.pas b/compiler/options.pas index 0bb0689760..c8c08467e3 100644 --- a/compiler/options.pas +++ b/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} diff --git a/rtl/inc/systemh.inc b/rtl/inc/systemh.inc index 9afea36bbb..aab13f2912 100644 --- a/rtl/inc/systemh.inc +++ b/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}