mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-12 05:06:03 +02:00
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:
parent
83d398719c
commit
dbf0404fb0
@ -635,6 +635,17 @@ unit cgcpu;
|
|||||||
a_op_reg_reg_reg_checkoverflow(list,op,size,src1,src2,dst,false,ovloc);
|
a_op_reg_reg_reg_checkoverflow(list,op,size,src1,src2,dst,false,ovloc);
|
||||||
end;
|
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);
|
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
|
var
|
||||||
@ -644,17 +655,6 @@ unit cgcpu;
|
|||||||
l1 : longint;
|
l1 : longint;
|
||||||
imm1, imm2: DWord;
|
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
|
begin
|
||||||
ovloc.loc:=LOC_VOID;
|
ovloc.loc:=LOC_VOID;
|
||||||
@ -794,25 +794,16 @@ unit cgcpu;
|
|||||||
OP_NEG,OP_NOT,
|
OP_NEG,OP_NOT,
|
||||||
OP_DIV,OP_IDIV:
|
OP_DIV,OP_IDIV:
|
||||||
internalerror(200308281);
|
internalerror(200308281);
|
||||||
OP_SHL:
|
OP_SHL,
|
||||||
|
OP_SHR,
|
||||||
|
OP_SAR,
|
||||||
|
OP_ROR:
|
||||||
begin
|
begin
|
||||||
|
if (op = OP_ROR) and not(size in [OS_32,OS_S32]) then
|
||||||
|
internalerror(2008072801);
|
||||||
shifterop_reset(so);
|
shifterop_reset(so);
|
||||||
so.rs:=src1;
|
so.rs:=src1;
|
||||||
so.shiftmode:=SM_LSL;
|
so.shiftmode:=opshift2shiftmode(op);
|
||||||
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;
|
|
||||||
list.concat(taicpu.op_reg_reg_shifterop(A_MOV,dst,src2,so));
|
list.concat(taicpu.op_reg_reg_shifterop(A_MOV,dst,src2,so));
|
||||||
end;
|
end;
|
||||||
OP_ROL:
|
OP_ROL:
|
||||||
@ -821,19 +812,9 @@ unit cgcpu;
|
|||||||
internalerror(2008072801);
|
internalerror(2008072801);
|
||||||
{ simulate ROL by ror'ing 32-value }
|
{ simulate ROL by ror'ing 32-value }
|
||||||
tmpreg:=getintregister(list,OS_32);
|
tmpreg:=getintregister(list,OS_32);
|
||||||
list.concat(taicpu.op_reg_const(A_MOV,tmpreg,32));
|
list.concat(taicpu.op_reg_reg_const(A_RSB,tmpreg,src1, 32));
|
||||||
list.concat(taicpu.op_reg_reg_reg(A_SUB,src1,tmpreg,src1));
|
|
||||||
shifterop_reset(so);
|
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;
|
|
||||||
OP_ROR:
|
|
||||||
begin
|
|
||||||
if not(size in [OS_32,OS_S32]) then
|
|
||||||
internalerror(2008072802);
|
|
||||||
shifterop_reset(so);
|
|
||||||
so.rs:=src1;
|
|
||||||
so.shiftmode:=SM_ROR;
|
so.shiftmode:=SM_ROR;
|
||||||
list.concat(taicpu.op_reg_reg_shifterop(A_MOV,dst,src2,so));
|
list.concat(taicpu.op_reg_reg_shifterop(A_MOV,dst,src2,so));
|
||||||
end;
|
end;
|
||||||
|
Loading…
Reference in New Issue
Block a user