mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-11 10:49:30 +02:00
* prevent generation of mul/mla statements with illegal registers
git-svn-id: trunk@25343 -
This commit is contained in:
parent
7df123aa1e
commit
bb73a2891b
@ -112,6 +112,9 @@ unit cgcpu;
|
|||||||
{ clear out potential overflow bits from 8 or 16 bit operations }
|
{ clear out potential overflow bits from 8 or 16 bit operations }
|
||||||
{ the upper 24/16 bits of a register after an operation }
|
{ the upper 24/16 bits of a register after an operation }
|
||||||
procedure maybeadjustresult(list: TAsmList; op: TOpCg; size: tcgsize; dst: tregister);
|
procedure maybeadjustresult(list: TAsmList; op: TOpCg; size: tcgsize; dst: tregister);
|
||||||
|
|
||||||
|
{ mla for thumb requires that none of the registers is equal to r13/r15, this method ensures this }
|
||||||
|
procedure safe_mla(list: TAsmList;op1,op2,op3,op4 : TRegister);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ tcgarm is shared between normal arm and thumb-2 }
|
{ tcgarm is shared between normal arm and thumb-2 }
|
||||||
@ -3191,6 +3194,30 @@ unit cgcpu;
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tbasecgarm.safe_mla(list : TAsmList; op1,op2,op3,op4 : TRegister);
|
||||||
|
|
||||||
|
procedure checkreg(var reg : TRegister);
|
||||||
|
var
|
||||||
|
tmpreg : TRegister;
|
||||||
|
begin
|
||||||
|
if ((current_settings.cputype in cpu_thumb+cpu_thumb2) and (getsupreg(reg)=RS_R13)) or
|
||||||
|
(getsupreg(reg)=RS_R15) then
|
||||||
|
begin
|
||||||
|
tmpreg:=getintregister(list,OS_INT);
|
||||||
|
a_load_reg_reg(list,OS_INT,OS_INT,reg,tmpreg);
|
||||||
|
reg:=tmpreg;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
checkreg(op1);
|
||||||
|
checkreg(op2);
|
||||||
|
checkreg(op3);
|
||||||
|
checkreg(op4);
|
||||||
|
list.concat(taicpu.op_reg_reg_reg_reg(A_MLA,op1,op2,op3,op4));
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure tcg64farm.a_op64_reg_reg(list : TAsmList;op:TOpCG;size : tcgsize;regsrc,regdst : tregister64);
|
procedure tcg64farm.a_op64_reg_reg(list : TAsmList;op:TOpCG;size : tcgsize;regsrc,regdst : tregister64);
|
||||||
begin
|
begin
|
||||||
case op of
|
case op of
|
||||||
|
@ -53,7 +53,7 @@ interface
|
|||||||
defutil,htypechk,cgbase,cgutils,
|
defutil,htypechk,cgbase,cgutils,
|
||||||
cpuinfo,pass_1,pass_2,procinfo,
|
cpuinfo,pass_1,pass_2,procinfo,
|
||||||
ncon,nadd,ncnv,ncal,nmat,
|
ncon,nadd,ncnv,ncal,nmat,
|
||||||
ncgutil,cgobj,
|
ncgutil,cgobj,cgcpu,
|
||||||
hlcgobj
|
hlcgobj
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -509,7 +509,7 @@ interface
|
|||||||
tmpreg := cg.getintregister(current_asmdata.CurrAsmList,OS_32);
|
tmpreg := cg.getintregister(current_asmdata.CurrAsmList,OS_32);
|
||||||
asmList.concat(taicpu.op_reg_reg_reg(A_MUL,tmpreg,ll.reglo,rl.reghi));
|
asmList.concat(taicpu.op_reg_reg_reg(A_MUL,tmpreg,ll.reglo,rl.reghi));
|
||||||
asmList.concat(taicpu.op_reg_reg_reg_reg(A_UMULL,res.reglo,res.reghi,rl.reglo,ll.reglo));
|
asmList.concat(taicpu.op_reg_reg_reg_reg(A_UMULL,res.reglo,res.reghi,rl.reglo,ll.reglo));
|
||||||
asmList.concat(taicpu.op_reg_reg_reg_reg(A_MLA,tmpreg,rl.reglo,ll.reghi,tmpreg));
|
tbasecgarm(cg).safe_mla(asmList,tmpreg,rl.reglo,ll.reghi,tmpreg);
|
||||||
asmList.concat(taicpu.op_reg_reg_reg(A_ADD,res.reghi,tmpreg,res.reghi));
|
asmList.concat(taicpu.op_reg_reg_reg(A_ADD,res.reghi,tmpreg,res.reghi));
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
@ -42,7 +42,7 @@ interface
|
|||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses
|
uses
|
||||||
cutils,verbose,globals,aasmdata,aasmcpu,cgobj,
|
cutils,verbose,globals,aasmdata,aasmcpu,cgobj,cgcpu,
|
||||||
cpuinfo,
|
cpuinfo,
|
||||||
cgutils,
|
cgutils,
|
||||||
procinfo;
|
procinfo;
|
||||||
@ -84,7 +84,7 @@ implementation
|
|||||||
begin
|
begin
|
||||||
hreg:=cg.getaddressregister(current_asmdata.CurrAsmList);
|
hreg:=cg.getaddressregister(current_asmdata.CurrAsmList);
|
||||||
cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_ADDR,l,hreg);
|
cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_ADDR,l,hreg);
|
||||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg_reg(A_MLA,hreg,maybe_const_reg,hreg,location.reference.base));
|
tbasecgarm(cg).safe_mla(current_asmdata.CurrAsmList,hreg,maybe_const_reg,hreg,location.reference.base);
|
||||||
location.reference.base:=hreg;
|
location.reference.base:=hreg;
|
||||||
{ update alignment }
|
{ update alignment }
|
||||||
if (location.reference.alignment=0) then
|
if (location.reference.alignment=0) then
|
||||||
@ -95,7 +95,7 @@ implementation
|
|||||||
begin
|
begin
|
||||||
hreg:=cg.getaddressregister(current_asmdata.CurrAsmList);
|
hreg:=cg.getaddressregister(current_asmdata.CurrAsmList);
|
||||||
cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_ADDR,l,hreg);
|
cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_ADDR,l,hreg);
|
||||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg_reg(A_MLA,hreg,maybe_const_reg,hreg,location.reference.index));
|
tbasecgarm(cg).safe_mla(current_asmdata.CurrAsmList,hreg,maybe_const_reg,hreg,location.reference.index);
|
||||||
location.reference.base:=hreg;
|
location.reference.base:=hreg;
|
||||||
location.reference.index:=NR_NO;
|
location.reference.index:=NR_NO;
|
||||||
{ update alignment }
|
{ update alignment }
|
||||||
|
@ -121,6 +121,24 @@ unit rgcpu;
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
A_MLA,
|
||||||
|
A_MUL:
|
||||||
|
begin
|
||||||
|
if current_settings.cputype<cpu_armv6 then
|
||||||
|
add_edge(getsupreg(taicpu(p).oper[0]^.reg),getsupreg(taicpu(p).oper[1]^.reg));
|
||||||
|
add_edge(getsupreg(taicpu(p).oper[0]^.reg),RS_R13);
|
||||||
|
add_edge(getsupreg(taicpu(p).oper[0]^.reg),RS_R15);
|
||||||
|
add_edge(getsupreg(taicpu(p).oper[1]^.reg),RS_R13);
|
||||||
|
add_edge(getsupreg(taicpu(p).oper[1]^.reg),RS_R15);
|
||||||
|
add_edge(getsupreg(taicpu(p).oper[2]^.reg),RS_R13);
|
||||||
|
add_edge(getsupreg(taicpu(p).oper[2]^.reg),RS_R15);
|
||||||
|
if taicpu(p).opcode=A_MLA then
|
||||||
|
begin
|
||||||
|
add_edge(getsupreg(taicpu(p).oper[3]^.reg),RS_R13);
|
||||||
|
add_edge(getsupreg(taicpu(p).oper[3]^.reg),RS_R15);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
A_LDRB,
|
A_LDRB,
|
||||||
A_STRB,
|
A_STRB,
|
||||||
A_STR,
|
A_STR,
|
||||||
@ -486,8 +504,15 @@ unit rgcpu;
|
|||||||
case taicpu(p).opcode of
|
case taicpu(p).opcode of
|
||||||
A_MLA,
|
A_MLA,
|
||||||
A_MUL:
|
A_MUL:
|
||||||
|
begin
|
||||||
if current_settings.cputype<cpu_armv6 then
|
if current_settings.cputype<cpu_armv6 then
|
||||||
add_edge(getsupreg(taicpu(p).oper[0]^.reg),getsupreg(taicpu(p).oper[1]^.reg));
|
add_edge(getsupreg(taicpu(p).oper[0]^.reg),getsupreg(taicpu(p).oper[1]^.reg));
|
||||||
|
add_edge(getsupreg(taicpu(p).oper[0]^.reg),RS_R15);
|
||||||
|
add_edge(getsupreg(taicpu(p).oper[1]^.reg),RS_R15);
|
||||||
|
add_edge(getsupreg(taicpu(p).oper[2]^.reg),RS_R15);
|
||||||
|
if taicpu(p).opcode=A_MLA then
|
||||||
|
add_edge(getsupreg(taicpu(p).oper[3]^.reg),RS_R15);
|
||||||
|
end;
|
||||||
A_UMULL,
|
A_UMULL,
|
||||||
A_UMLAL,
|
A_UMLAL,
|
||||||
A_SMULL,
|
A_SMULL,
|
||||||
|
Loading…
Reference in New Issue
Block a user