mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-10 22:26:00 +02:00
* patch (slighly modified) by Christo Crause to write 16 bit registers on avr in hi/lo order, resolves #34721
git-svn-id: trunk@40678 -
This commit is contained in:
parent
a7c347fe56
commit
917de001d6
@ -1345,21 +1345,38 @@ unit cgcpu;
|
||||
end;
|
||||
if not conv_done then
|
||||
begin
|
||||
for i:=1 to tcgsize2size[fromsize] do
|
||||
// CC
|
||||
// Write to 16 bit ioreg, first high byte then low byte
|
||||
// sequence required for 16 bit timer registers
|
||||
// See e.g. atmega328p manual para 15.3 Accessing 16 bit registers
|
||||
if (fromsize in [OS_16, OS_S16]) and QuickRef and (href.offset > 31)
|
||||
and (href.offset < cpuinfo.embedded_controllers[current_settings.controllertype].srambase) then
|
||||
begin
|
||||
if not(QuickRef) and (i<tcgsize2size[fromsize]) then
|
||||
href.addressmode:=AM_POSTINCREMENT
|
||||
else
|
||||
href.addressmode:=AM_UNCHANGED;
|
||||
|
||||
tmpreg:=GetNextReg(reg);
|
||||
href.addressmode:=AM_UNCHANGED;
|
||||
inc(href.offset);
|
||||
list.concat(taicpu.op_ref_reg(GetStore(href),href,tmpreg));
|
||||
dec(href.offset);
|
||||
list.concat(taicpu.op_ref_reg(GetStore(href),href,reg));
|
||||
end
|
||||
else
|
||||
begin
|
||||
for i:=1 to tcgsize2size[fromsize] do
|
||||
begin
|
||||
if not(QuickRef) and (i<tcgsize2size[fromsize]) then
|
||||
href.addressmode:=AM_POSTINCREMENT
|
||||
else
|
||||
href.addressmode:=AM_UNCHANGED;
|
||||
|
||||
if QuickRef then
|
||||
inc(href.offset);
|
||||
list.concat(taicpu.op_ref_reg(GetStore(href),href,reg));
|
||||
|
||||
{ check if we are not in the last iteration to avoid an internalerror in GetNextReg }
|
||||
if i<tcgsize2size[fromsize] then
|
||||
reg:=GetNextReg(reg);
|
||||
if QuickRef then
|
||||
inc(href.offset);
|
||||
|
||||
{ check if we are not in the last iteration to avoid an internalerror in GetNextReg }
|
||||
if i<tcgsize2size[fromsize] then
|
||||
reg:=GetNextReg(reg);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -2124,7 +2141,7 @@ unit cgcpu;
|
||||
|
||||
procedure tcgavr.g_concatcopy(list : TAsmList;const source,dest : treference;len : tcgint);
|
||||
var
|
||||
countreg,tmpreg : tregister;
|
||||
countreg,tmpreg,tmpreg2: tregister;
|
||||
srcref,dstref : treference;
|
||||
copysize,countregsize : tcgsize;
|
||||
l : TAsmLabel;
|
||||
@ -2269,40 +2286,91 @@ unit cgcpu;
|
||||
dstref:=dest;
|
||||
end;
|
||||
|
||||
for i:=1 to len do
|
||||
begin
|
||||
if not(SrcQuickRef) and (i<len) then
|
||||
srcref.addressmode:=AM_POSTINCREMENT
|
||||
else
|
||||
srcref.addressmode:=AM_UNCHANGED;
|
||||
// CC
|
||||
// If dest is an ioreg (31 < offset < srambase) and size = 16 bit then
|
||||
// load high byte first, then low byte
|
||||
if (len = 2) and DestQuickRef
|
||||
and (dest.offset > 31)
|
||||
and (dest.offset < cpuinfo.embedded_controllers[current_settings.controllertype].srambase) then
|
||||
begin
|
||||
// If src is also a 16 bit ioreg then read low byte then high byte
|
||||
if SrcQuickRef and (srcref.offset > 31)
|
||||
and (srcref.offset < cpuinfo.embedded_controllers[current_settings.controllertype].srambase) then
|
||||
begin
|
||||
// First read source into temp registers
|
||||
tmpreg:=getintregister(list, OS_16);
|
||||
list.concat(taicpu.op_reg_ref(GetLoad(srcref),tmpreg,srcref));
|
||||
inc(srcref.offset);
|
||||
tmpreg2:=GetNextReg(tmpreg);
|
||||
list.concat(taicpu.op_reg_ref(GetLoad(srcref),tmpreg2,srcref));
|
||||
|
||||
if not(DestQuickRef) and (i<len) then
|
||||
dstref.addressmode:=AM_POSTINCREMENT
|
||||
else
|
||||
dstref.addressmode:=AM_UNCHANGED;
|
||||
// then move temp registers to dest in reverse order
|
||||
inc(dstref.offset);
|
||||
list.concat(taicpu.op_ref_reg(GetStore(dstref),dstref,tmpreg2));
|
||||
dec(dstref.offset);
|
||||
list.concat(taicpu.op_ref_reg(GetStore(dstref),dstref,tmpreg));
|
||||
end
|
||||
else
|
||||
begin
|
||||
srcref.addressmode:=AM_UNCHANGED;
|
||||
inc(srcref.offset);
|
||||
dstref.addressmode:=AM_UNCHANGED;
|
||||
inc(dstref.offset);
|
||||
|
||||
cg.getcpuregister(list,NR_R0);
|
||||
list.concat(taicpu.op_reg_ref(GetLoad(srcref),NR_R0,srcref));
|
||||
list.concat(taicpu.op_ref_reg(GetStore(dstref),dstref,NR_R0));
|
||||
cg.ungetcpuregister(list,NR_R0);
|
||||
cg.getcpuregister(list,NR_R0);
|
||||
list.concat(taicpu.op_reg_ref(GetLoad(srcref),NR_R0,srcref));
|
||||
list.concat(taicpu.op_ref_reg(GetStore(dstref),dstref,NR_R0));
|
||||
cg.ungetcpuregister(list,NR_R0);
|
||||
|
||||
if SrcQuickRef then
|
||||
inc(srcref.offset);
|
||||
if DestQuickRef then
|
||||
inc(dstref.offset);
|
||||
end;
|
||||
if not(SrcQuickRef) then
|
||||
begin
|
||||
ungetcpuregister(list,srcref.base);
|
||||
ungetcpuregister(list,TRegister(ord(srcref.base)+1));
|
||||
end;
|
||||
if not(DestQuickRef) then
|
||||
begin
|
||||
ungetcpuregister(list,dstref.base);
|
||||
ungetcpuregister(list,TRegister(ord(dstref.base)+1));
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
if not(SrcQuickRef) then
|
||||
srcref.addressmode:=AM_POSTINCREMENT
|
||||
else
|
||||
srcref.addressmode:=AM_UNCHANGED;
|
||||
|
||||
dec(srcref.offset);
|
||||
dec(dstref.offset);
|
||||
|
||||
cg.getcpuregister(list,NR_R0);
|
||||
list.concat(taicpu.op_reg_ref(GetLoad(srcref),NR_R0,srcref));
|
||||
list.concat(taicpu.op_ref_reg(GetStore(dstref),dstref,NR_R0));
|
||||
cg.ungetcpuregister(list,NR_R0);
|
||||
end;
|
||||
end
|
||||
else
|
||||
for i:=1 to len do
|
||||
begin
|
||||
if not(SrcQuickRef) and (i<len) then
|
||||
srcref.addressmode:=AM_POSTINCREMENT
|
||||
else
|
||||
srcref.addressmode:=AM_UNCHANGED;
|
||||
|
||||
if not(DestQuickRef) and (i<len) then
|
||||
dstref.addressmode:=AM_POSTINCREMENT
|
||||
else
|
||||
dstref.addressmode:=AM_UNCHANGED;
|
||||
|
||||
cg.getcpuregister(list,NR_R0);
|
||||
list.concat(taicpu.op_reg_ref(GetLoad(srcref),NR_R0,srcref));
|
||||
list.concat(taicpu.op_ref_reg(GetStore(dstref),dstref,NR_R0));
|
||||
cg.ungetcpuregister(list,NR_R0);
|
||||
|
||||
if SrcQuickRef then
|
||||
inc(srcref.offset);
|
||||
if DestQuickRef then
|
||||
inc(dstref.offset);
|
||||
end;
|
||||
if not(SrcQuickRef) then
|
||||
begin
|
||||
ungetcpuregister(list,srcref.base);
|
||||
ungetcpuregister(list,TRegister(ord(srcref.base)+1));
|
||||
end;
|
||||
if not(DestQuickRef) then
|
||||
begin
|
||||
ungetcpuregister(list,dstref.base);
|
||||
ungetcpuregister(list,TRegister(ord(dstref.base)+1));
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure tcgavr.g_overflowCheck(list : TAsmList;const l : tlocation;def : tdef);
|
||||
|
Loading…
Reference in New Issue
Block a user