From 92c47148cc3b99a1f124a4ad17db6e3147cbf229 Mon Sep 17 00:00:00 2001 From: masta Date: Wed, 20 Jun 2012 12:39:09 +0000 Subject: [PATCH] Optimize 8/16 OP_NOT on ARM This now generates: mvn r0, r0, lsl #24/#16 mov r0, r0, lsr/asr #24/#16 The lsr/asr might be folded into a following instruction, making the whole operation 1 cycle instead of 2-3 with the previous solution. git-svn-id: trunk@21658 - --- compiler/arm/cgcpu.pas | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/compiler/arm/cgcpu.pas b/compiler/arm/cgcpu.pas index 7452230145..37482921d1 100644 --- a/compiler/arm/cgcpu.pas +++ b/compiler/arm/cgcpu.pas @@ -581,23 +581,34 @@ unit cgcpu; procedure tcgarm.a_op_reg_reg(list : TAsmList; Op: TOpCG; size: TCGSize; src, dst: TRegister); + var + so : tshifterop; begin - case op of - OP_NEG: - list.concat(taicpu.op_reg_reg_const(A_RSB,dst,src,0)); - OP_NOT: - begin + if op = OP_NEG then + list.concat(taicpu.op_reg_reg_const(A_RSB,dst,src,0)) + else if op = OP_NOT then + begin + if size in [OS_8, OS_16, OS_S8, OS_S16] then + begin + shifterop_reset(so); + so.shiftmode:=SM_LSL; + if size in [OS_8, OS_S8] then + so.shiftimm:=24 + else + so.shiftimm:=16; + list.concat(taicpu.op_reg_reg_shifterop(A_MVN,dst,src,so)); + {Using a shift here allows this to be folded into another instruction} + if size in [OS_S8, OS_S16] then + so.shiftmode:=SM_ASR + else + so.shiftmode:=SM_LSR; + list.concat(taicpu.op_reg_reg_shifterop(A_MOV,dst,dst,so)); + end + else list.concat(taicpu.op_reg_reg(A_MVN,dst,src)); - case size of - OS_8 : - a_op_const_reg_reg(list,OP_AND,OS_INT,$ff,dst,dst); - OS_16 : - a_op_const_reg_reg(list,OP_AND,OS_INT,$ffff,dst,dst); - end; - end - else + end + else a_op_reg_reg_reg(list,op,OS_32,src,dst,dst); - end; end; @@ -2664,7 +2675,7 @@ unit cgcpu; procedure tcgarm.maybeadjustresult(list: TAsmList; op: TOpCg; size: tcgsize; dst: tregister); const - overflowops = [OP_MUL,OP_SHL,OP_ADD,OP_SUB,OP_NOT,OP_NEG]; + overflowops = [OP_MUL,OP_SHL,OP_ADD,OP_SUB,OP_NEG]; begin if (op in overflowops) and (size in [OS_8,OS_S8,OS_16,OS_S16]) then