From dbf0404fb0d57f3d10d0798e2896b64382bf548a Mon Sep 17 00:00:00 2001 From: masta Date: Fri, 6 Jul 2012 15:01:31 +0000 Subject: [PATCH] More consolidation of OP_SHL/SHR/ROR/SAR in ARM CodeGen This removes the duplications in a_op_reg_reg_reg_checkoverflow. OP_ROL stays seperate because it needs some special treatment again. The code for OP_ROL was changed, previously it generated: mov tempreg, #32 sub src1, tempreg, src1 mov dst, src2, ror src1 This would trash src1, which MIGHT be a problem, but i'm not totally sure. But the mov/sub was replaced with rsb, so the new code looks like this. rsb tempreg, src1, #32 mov dst, src2, ror tempreg If src1 gets freed afterwards the regallocator should be able to change that into: rsb src1, src1, #32 mov dst, src2, ror src1 git-svn-id: trunk@21804 - --- compiler/arm/cgcpu.pas | 59 ++++++++++++++---------------------------- 1 file changed, 20 insertions(+), 39 deletions(-) diff --git a/compiler/arm/cgcpu.pas b/compiler/arm/cgcpu.pas index 6d24d98e5d..576e0ac05b 100644 --- a/compiler/arm/cgcpu.pas +++ b/compiler/arm/cgcpu.pas @@ -635,6 +635,17 @@ unit cgcpu; a_op_reg_reg_reg_checkoverflow(list,op,size,src1,src2,dst,false,ovloc); end; + function opshift2shiftmode(op: TOpCg): tshiftmode; + begin + case op of + OP_SHL: Result:=SM_LSL; + OP_SHR: Result:=SM_LSR; + OP_ROR: Result:=SM_ROR; + OP_ROL: Result:=SM_ROR; + OP_SAR: Result:=SM_ASR; + else internalerror(2012070501); + end + end; procedure tcgarm.a_op_const_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tcgsize; a: tcgint; src, dst: tregister;setflags : boolean;var ovloc : tlocation); var @@ -644,17 +655,6 @@ unit cgcpu; l1 : longint; imm1, imm2: DWord; - function opshift2shiftmode(op: TOpCg): tshiftmode; - begin - case op of - OP_SHL: Result:=SM_LSL; - OP_SHR: Result:=SM_LSR; - OP_ROR: Result:=SM_ROR; - OP_ROL: Result:=SM_ROR; - OP_SAR: Result:=SM_ASR; - else internalerror(2012070501); - end - end; begin ovloc.loc:=LOC_VOID; @@ -794,25 +794,16 @@ unit cgcpu; OP_NEG,OP_NOT, OP_DIV,OP_IDIV: internalerror(200308281); - OP_SHL: + OP_SHL, + OP_SHR, + OP_SAR, + OP_ROR: begin + if (op = OP_ROR) and not(size in [OS_32,OS_S32]) then + internalerror(2008072801); shifterop_reset(so); so.rs:=src1; - so.shiftmode:=SM_LSL; - list.concat(taicpu.op_reg_reg_shifterop(A_MOV,dst,src2,so)); - end; - OP_SHR: - begin - shifterop_reset(so); - so.rs:=src1; - so.shiftmode:=SM_LSR; - list.concat(taicpu.op_reg_reg_shifterop(A_MOV,dst,src2,so)); - end; - OP_SAR: - begin - shifterop_reset(so); - so.rs:=src1; - so.shiftmode:=SM_ASR; + so.shiftmode:=opshift2shiftmode(op); list.concat(taicpu.op_reg_reg_shifterop(A_MOV,dst,src2,so)); end; OP_ROL: @@ -821,19 +812,9 @@ unit cgcpu; 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)); + list.concat(taicpu.op_reg_reg_const(A_RSB,tmpreg,src1, 32)); 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.rs:=tmpreg; so.shiftmode:=SM_ROR; list.concat(taicpu.op_reg_reg_shifterop(A_MOV,dst,src2,so)); end;