+ a_op_const_reg_reg for arm thumb taking care of availability of add sp,sp, ...

* handle references with base and index on arm thumb correctly

git-svn-id: trunk@24196 -
This commit is contained in:
florian 2013-04-07 21:01:11 +00:00
parent 9bbc24b5e3
commit f9ef8e90da

View File

@ -165,6 +165,7 @@ unit cgcpu;
procedure a_op_reg_reg(list: TAsmList; Op: TOpCG; size: TCGSize; src,dst: TRegister);override;
procedure a_op_const_reg(list: TAsmList; op: TOpCg; size: tcgsize; a: tcgint; dst: tregister);override;
procedure a_op_const_reg_reg(list: TAsmList; op: TOpCg; size: tcgsize; a: tcgint; src, dst: tregister); override;
procedure g_flags2reg(list: TAsmList; size: TCgSize; const f: TResFlags; reg: TRegister); override;
@ -1122,23 +1123,41 @@ unit cgcpu;
) or
((current_settings.cputype in cpu_thumb) and
(((oppostfix in [PF_SB,PF_SH]) and (ref.offset<>0)) or
((oppostfix=PF_None) and ((ref.offset<0) or (ref.offset>124) or ((ref.offset mod 4)<>0))) or
((oppostfix=PF_None) and ((ref.offset<0) or ((ref.base<>NR_STACK_POINTER_REG) and (ref.offset>124)) or
((ref.base=NR_STACK_POINTER_REG) and (ref.offset>1020)) or ((ref.offset mod 4)<>0))) or
((oppostfix=PF_H) and ((ref.offset<0) or (ref.offset>62) or ((ref.offset mod 2)<>0))) or
((oppostfix=PF_B) and ((ref.offset<0) or (ref.offset>31)))
((oppostfix=PF_B) and ((ref.offset<0) or (ref.offset>31) or ((getsupreg(ref.base) in [RS_R8..RS_R15]) and (ref.offset<>0))))
)
) then
begin
fixref(list,ref);
end;
{ certain thumb load require base and index }
if (current_settings.cputype in cpu_thumb) and
(oppostfix in [PF_SB,PF_SH]) and
(ref.base<>NR_NO) and (ref.index=NR_NO) then
if current_settings.cputype in cpu_thumb then
begin
tmpreg:=getintregister(list,OS_ADDR);
a_load_const_reg(list,OS_INT,0,tmpreg);
ref.index:=tmpreg;
{ certain thumb load require base and index }
if (oppostfix in [PF_SB,PF_SH]) and
(ref.base<>NR_NO) and (ref.index=NR_NO) then
begin
tmpreg:=getintregister(list,OS_ADDR);
a_load_const_reg(list,OS_ADDR,0,tmpreg);
ref.index:=tmpreg;
end;
{ "hi" registers cannot be used as base or index }
if (getsupreg(ref.base) in [RS_R8..RS_R12,RS_R14]) or
((ref.base=NR_R13) and (ref.index<>NR_NO)) then
begin
tmpreg:=getintregister(list,OS_ADDR);
a_load_reg_reg(list,OS_ADDR,OS_ADDR,ref.base,tmpreg);
ref.base:=tmpreg;
end;
if getsupreg(ref.index) in [RS_R8..RS_R14] then
begin
tmpreg:=getintregister(list,OS_ADDR);
a_load_reg_reg(list,OS_ADDR,OS_ADDR,ref.index,tmpreg);
ref.index:=tmpreg;
end;
end;
{ fold if there is base, index and offset, however, don't fold
@ -3849,6 +3868,15 @@ unit cgcpu;
end;
procedure tthumbcgarm.a_op_const_reg_reg(list: TAsmList; op: TOpCg; size: tcgsize; a: tcgint; src, dst: tregister);
begin
if (op=OP_ADD) and (src=NR_R13) and (dst<>NR_R13) and ((a mod 4)=0) and (a>0) and (a<=1020) then
list.concat(taicpu.op_reg_reg_const(A_ADD,dst,src,a))
else
inherited a_op_const_reg_reg(list,op,size,a,src,dst);
end;
procedure tthumbcgarm.g_flags2reg(list: TAsmList; size: TCgSize; const f: TResFlags; reg: TRegister);
var
l : tasmlabel;