mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-10 21:49:14 +02:00
+ unaligned load/store support from Roozbeh GHolizadeh
git-svn-id: trunk@3351 -
This commit is contained in:
parent
9e00f894a9
commit
0780616dee
@ -64,6 +64,8 @@ unit cgcpu;
|
||||
procedure a_load_reg_ref(list : TAsmList; fromsize, tosize: tcgsize; reg : tregister;const ref : treference);override;
|
||||
procedure a_load_ref_reg(list : TAsmList; fromsize, tosize : tcgsize;const Ref : treference;reg : tregister);override;
|
||||
procedure a_load_reg_reg(list : TAsmList; fromsize, tosize : tcgsize;reg1,reg2 : tregister);override;
|
||||
function a_internal_load_reg_ref(list : TAsmList; fromsize, tosize: tcgsize; reg : tregister;const ref : treference):treference;
|
||||
function a_internal_load_ref_reg(list : TAsmList; fromsize, tosize : tcgsize;const Ref : treference;reg : tregister):treference;
|
||||
|
||||
{ fpu move instructions }
|
||||
procedure a_loadfpu_reg_reg(list: TAsmList; size: tcgsize; reg1, reg2: tregister); override;
|
||||
@ -100,7 +102,7 @@ unit cgcpu;
|
||||
|
||||
procedure a_jmp_cond(list : TAsmList;cond : TOpCmp;l: tasmlabel);
|
||||
procedure fixref(list : TAsmList;var ref : treference);
|
||||
procedure handle_load_store(list:TAsmList;op: tasmop;oppostfix : toppostfix;reg:tregister;ref: treference);
|
||||
function handle_load_store(list:TAsmList;op: tasmop;oppostfix : toppostfix;reg:tregister;ref: treference):treference;
|
||||
|
||||
procedure g_intf_wrapper(list: TAsmList; procdef: tprocdef; const labelname: string; ioffset: longint);override;
|
||||
end;
|
||||
@ -577,11 +579,12 @@ unit cgcpu;
|
||||
end;
|
||||
|
||||
|
||||
procedure tcgarm.handle_load_store(list:TAsmList;op: tasmop;oppostfix : toppostfix;reg:tregister;ref: treference);
|
||||
function tcgarm.handle_load_store(list:TAsmList;op: tasmop;oppostfix : toppostfix;reg:tregister;ref: treference):treference;
|
||||
var
|
||||
tmpreg : tregister;
|
||||
tmpreg,tmpreg2 : tregister;
|
||||
tmpref : treference;
|
||||
l : tasmlabel;
|
||||
so : tshifterop;
|
||||
begin
|
||||
tmpreg:=NR_NO;
|
||||
|
||||
@ -717,10 +720,131 @@ unit cgcpu;
|
||||
end;
|
||||
end;
|
||||
list.concat(setoppostfix(taicpu.op_reg_ref(op,reg,ref),oppostfix));
|
||||
Result := ref;
|
||||
end;
|
||||
|
||||
|
||||
procedure tcgarm.a_load_reg_ref(list : TAsmList; fromsize, tosize: tcgsize; reg : tregister;const ref : treference);
|
||||
var
|
||||
oppostfix:toppostfix;
|
||||
usedtmpref,usedtmpref2: treference;
|
||||
tmpreg,tmpreg2 : tregister;
|
||||
so : tshifterop;
|
||||
begin
|
||||
case ToSize of
|
||||
{ signed integer registers }
|
||||
OS_8,
|
||||
OS_S8:
|
||||
oppostfix:=PF_B;
|
||||
OS_16,
|
||||
OS_S16:
|
||||
oppostfix:=PF_H;
|
||||
OS_32,
|
||||
OS_S32:
|
||||
oppostfix:=PF_None;
|
||||
else
|
||||
InternalError(200308295);
|
||||
end;
|
||||
if ref.alignment<>0 then
|
||||
begin
|
||||
case FromSize of
|
||||
OS_16,OS_S16:
|
||||
begin
|
||||
shifterop_reset(so);so.shiftmode:=SM_LSR;so.shiftimm:=8;
|
||||
tmpreg:=getintregister(list,OS_INT);
|
||||
usedtmpref:=a_internal_load_reg_ref(list,OS_8,OS_8,tmpreg,Ref);
|
||||
inc(usedtmpref.offset);
|
||||
list.concat(taicpu.op_reg_reg_shifterop(A_MOV,tmpreg,reg,so));
|
||||
a_internal_load_reg_ref(list,OS_8,OS_8,tmpreg,usedtmpref);
|
||||
end;
|
||||
OS_32,OS_S32:
|
||||
begin
|
||||
shifterop_reset(so);so.shiftmode:=SM_LSR;so.shiftimm:=8;
|
||||
tmpreg:=getintregister(list,OS_INT);
|
||||
|
||||
usedtmpref:=a_internal_load_reg_ref(list,OS_8,OS_8,reg,Ref);
|
||||
list.concat(taicpu.op_reg_reg_shifterop(A_MOV,tmpreg,reg,so));
|
||||
inc(usedtmpref.offset);
|
||||
a_internal_load_reg_ref(list,OS_8,OS_8,tmpreg,usedtmpref);
|
||||
list.concat(taicpu.op_reg_reg_shifterop(A_MOV,tmpreg,tmpreg,so));
|
||||
inc(usedtmpref.offset);
|
||||
a_internal_load_reg_ref(list,OS_8,OS_8,tmpreg,usedtmpref);
|
||||
list.concat(taicpu.op_reg_reg_shifterop(A_MOV,tmpreg,tmpreg,so));
|
||||
inc(usedtmpref.offset);
|
||||
a_internal_load_reg_ref(list,OS_8,OS_8,tmpreg,usedtmpref);
|
||||
end
|
||||
else
|
||||
handle_load_store(list,A_STR,oppostfix,reg,ref);
|
||||
end;
|
||||
end
|
||||
else
|
||||
handle_load_store(list,A_STR,oppostfix,reg,ref);
|
||||
end;
|
||||
|
||||
|
||||
procedure tcgarm.a_load_ref_reg(list : TAsmList; fromsize, tosize : tcgsize;const Ref : treference;reg : tregister);
|
||||
var
|
||||
oppostfix:toppostfix;
|
||||
usedtmpref,usedtmpref2: treference;
|
||||
tmpreg,tmpreg2 : tregister;
|
||||
so : tshifterop;
|
||||
begin
|
||||
case FromSize of
|
||||
{ signed integer registers }
|
||||
OS_8:
|
||||
oppostfix:=PF_B;
|
||||
OS_S8:
|
||||
oppostfix:=PF_SB;
|
||||
OS_16:
|
||||
oppostfix:=PF_H;
|
||||
OS_S16:
|
||||
oppostfix:=PF_SH;
|
||||
OS_32,
|
||||
OS_S32:
|
||||
oppostfix:=PF_None;
|
||||
else
|
||||
InternalError(200308291);
|
||||
end;
|
||||
if Ref.alignment<>0 then
|
||||
begin
|
||||
case FromSize of
|
||||
OS_16,OS_S16:
|
||||
begin
|
||||
shifterop_reset(so);so.shiftmode:=SM_LSL;so.shiftimm:=8;
|
||||
tmpreg:=getintregister(list,OS_INT);
|
||||
usedtmpref:=a_internal_load_ref_reg(list,OS_8,OS_8,Ref,tmpreg);
|
||||
inc(usedtmpref.offset);
|
||||
a_internal_load_ref_reg(list,OS_8,OS_8,usedtmpref,reg);
|
||||
list.concat(taicpu.op_reg_reg_reg_shifterop(A_ORR,reg,reg,tmpreg,so));
|
||||
end;
|
||||
OS_32,OS_S32:
|
||||
begin
|
||||
shifterop_reset(so);so.shiftmode:=SM_LSL;so.shiftimm:=8;
|
||||
tmpreg:=getintregister(list,OS_INT);
|
||||
tmpreg2:=getintregister(list,OS_INT);
|
||||
usedtmpref:=a_internal_load_ref_reg(list,OS_8,OS_8,Ref,reg);
|
||||
inc(usedtmpref.offset);
|
||||
a_internal_load_ref_reg(list,OS_8,OS_8,usedtmpref,tmpreg);
|
||||
list.concat(taicpu.op_reg_reg_reg_shifterop(A_ORR,tmpreg2,reg,tmpreg,so));
|
||||
inc(usedtmpref.offset);
|
||||
a_internal_load_ref_reg(list,OS_8,OS_8,usedtmpref,reg);
|
||||
so.shiftimm:=16;
|
||||
list.concat(taicpu.op_reg_reg_reg_shifterop(A_ORR,tmpreg,tmpreg2,reg,so));
|
||||
inc(usedtmpref.offset);
|
||||
a_internal_load_ref_reg(list,OS_8,OS_8,usedtmpref,tmpreg2);
|
||||
so.shiftimm:=24;
|
||||
list.concat(taicpu.op_reg_reg_reg_shifterop(A_ORR,reg,tmpreg,tmpreg2,so));
|
||||
end
|
||||
else
|
||||
handle_load_store(list,A_LDR,oppostfix,reg,ref);
|
||||
end;
|
||||
end
|
||||
else
|
||||
handle_load_store(list,A_LDR,oppostfix,reg,ref);
|
||||
end;
|
||||
|
||||
|
||||
function tcgarm.a_internal_load_reg_ref(list : TAsmList; fromsize, tosize: tcgsize; reg : tregister;const ref : treference):treference;
|
||||
var
|
||||
oppostfix:toppostfix;
|
||||
begin
|
||||
@ -738,11 +862,11 @@ unit cgcpu;
|
||||
else
|
||||
InternalError(200308295);
|
||||
end;
|
||||
handle_load_store(list,A_STR,oppostfix,reg,ref);
|
||||
result:=handle_load_store(list,A_STR,oppostfix,reg,ref);
|
||||
end;
|
||||
|
||||
|
||||
procedure tcgarm.a_load_ref_reg(list : TAsmList; fromsize, tosize : tcgsize;const Ref : treference;reg : tregister);
|
||||
function tcgarm.a_internal_load_ref_reg(list : TAsmList; fromsize, tosize : tcgsize;const Ref : treference;reg : tregister):treference;
|
||||
var
|
||||
oppostfix:toppostfix;
|
||||
begin
|
||||
@ -762,10 +886,9 @@ unit cgcpu;
|
||||
else
|
||||
InternalError(200308291);
|
||||
end;
|
||||
handle_load_store(list,A_LDR,oppostfix,reg,ref);
|
||||
result:=handle_load_store(list,A_LDR,oppostfix,reg,ref);
|
||||
end;
|
||||
|
||||
|
||||
procedure tcgarm.a_load_reg_reg(list : TAsmList; fromsize, tosize : tcgsize;reg1,reg2 : tregister);
|
||||
var
|
||||
instr: taicpu;
|
||||
@ -1299,18 +1422,18 @@ unit cgcpu;
|
||||
end
|
||||
else
|
||||
begin
|
||||
destreg:=getintregister(list,OS_ADDR);
|
||||
a_loadaddr_ref_reg(list,dest,destreg);
|
||||
reference_reset_base(dstref,destreg,0);
|
||||
destreg:=getintregister(list,OS_ADDR);
|
||||
a_loadaddr_ref_reg(list,dest,destreg);
|
||||
reference_reset_base(dstref,destreg,0);
|
||||
|
||||
srcreg:=getintregister(list,OS_ADDR);
|
||||
a_loadaddr_ref_reg(list,source,srcreg);
|
||||
reference_reset_base(srcref,srcreg,0);
|
||||
srcreg:=getintregister(list,OS_ADDR);
|
||||
a_loadaddr_ref_reg(list,source,srcreg);
|
||||
reference_reset_base(srcref,srcreg,0);
|
||||
|
||||
countreg:=getintregister(list,OS_32);
|
||||
countreg:=getintregister(list,OS_32);
|
||||
|
||||
// if cs_opt_size in aktoptimizerswitches then
|
||||
genloop(len,1);
|
||||
genloop(len,1);
|
||||
{
|
||||
else
|
||||
begin
|
||||
@ -1332,8 +1455,8 @@ unit cgcpu;
|
||||
list.concat(Taicpu.op_none(A_MOVSB,S_NO));
|
||||
end;
|
||||
}
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure tcgarm.g_concatcopy_unaligned(list : TAsmList;const source,dest : treference;len : aint);
|
||||
|
Loading…
Reference in New Issue
Block a user