mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-11 16:48:12 +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);
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user