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 -
This commit is contained in:
masta 2012-07-06 15:01:31 +00:00
parent 83d398719c
commit dbf0404fb0

View File

@ -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;