View Issue Details

IDProjectCategoryView StatusLast Update
0036066FPCCompilerpublic2019-09-13 09:06
ReporterChristo CrauseAssigned ToFlorian 
PrioritynormalSeverityminorReproducibilitysometimes
Status closedResolutionfixed 
Product Version3.3.1Product Build 
Target VersionFixed in Version3.3.1 
Summary0036066: AVR - Incorrect code generated when copying a static array [patch]
DescriptionTest test/cg/tcalfun1.pp generates a failure when copying a static array with a counter size exceeding 256 because the copy loop code generator in tcgavr.g_concatcopy only decrements a single register, so any 16 bit size will not be handled correctly. A stripped down test case highlighting this issue is attached.

The attached patch checks whether the array counter fits in 1 or 2 registers and emit either the current dec instruction if only 1 register is used or a subi/sbc pair if 2 registers are required for the array counter.
TagsNo tags attached.
Fixed in Revision42977
FPCOldBugId
FPCTarget-
Attached Files
  • ttest.pp (618 bytes)
    program ttest;
    
    const
      BIG_INDEX = 600;//8000;
      RESULT_U8BIT = 85;
    
    type
      tlargerecord = packed record
        b: array[1..BIG_INDEX] of byte;
      end;
    
    var
      value_largerec : tlargerecord;
    
    function func_largerecord: tlargerecord;
    var
      largerecord : tlargerecord;
    begin
      fillchar(largerecord, sizeof(largerecord), #0);
      largerecord.b[1] := RESULT_U8BIT;
      largerecord.b[BIG_INDEX] := RESULT_U8BIT;
      func_largerecord := largerecord;
    end;
    
    begin
      value_largerec := func_largerecord;
      if (value_largerec.b[1] <> RESULT_U8BIT) or (value_largerec.b[BIG_INDEX] <> RESULT_U8BIT) then
        Halt(1)
      else
        Halt(0);
    end.
    
    ttest.pp (618 bytes)
  • cgcpu.patch (893 bytes)
    diff --git compiler/avr/cgcpu.pas compiler/avr/cgcpu.pas
    index 45ca2037d1..661c300a9d 100644
    --- compiler/avr/cgcpu.pas
    +++ compiler/avr/cgcpu.pas
    @@ -2404,7 +2404,14 @@ unit cgcpu;
                 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);
    -            list.concat(taicpu.op_reg(A_DEC,countreg));
    +            if tcgsize2size[countregsize] = 1 then
    +              list.concat(taicpu.op_reg(A_DEC,countreg))
    +            else
    +              begin
    +                list.concat(taicpu.op_reg_const(A_SUBI,countreg,1));
    +                list.concat(taicpu.op_reg_reg(A_SBC,GetNextReg(countreg),NR_R1));
    +              end;
    +
                 a_jmp_flags(list,F_NE,l);
                 cg.ungetcpuregister(list,NR_R26);
                 cg.ungetcpuregister(list,NR_R27);
    
    cgcpu.patch (893 bytes)

Activities

Christo Crause

2019-09-11 19:22

reporter  

ttest.pp (618 bytes)
program ttest;

const
  BIG_INDEX = 600;//8000;
  RESULT_U8BIT = 85;

type
  tlargerecord = packed record
    b: array[1..BIG_INDEX] of byte;
  end;

var
  value_largerec : tlargerecord;

function func_largerecord: tlargerecord;
var
  largerecord : tlargerecord;
begin
  fillchar(largerecord, sizeof(largerecord), #0);
  largerecord.b[1] := RESULT_U8BIT;
  largerecord.b[BIG_INDEX] := RESULT_U8BIT;
  func_largerecord := largerecord;
end;

begin
  value_largerec := func_largerecord;
  if (value_largerec.b[1] <> RESULT_U8BIT) or (value_largerec.b[BIG_INDEX] <> RESULT_U8BIT) then
    Halt(1)
  else
    Halt(0);
end.
ttest.pp (618 bytes)
cgcpu.patch (893 bytes)
diff --git compiler/avr/cgcpu.pas compiler/avr/cgcpu.pas
index 45ca2037d1..661c300a9d 100644
--- compiler/avr/cgcpu.pas
+++ compiler/avr/cgcpu.pas
@@ -2404,7 +2404,14 @@ unit cgcpu;
             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);
-            list.concat(taicpu.op_reg(A_DEC,countreg));
+            if tcgsize2size[countregsize] = 1 then
+              list.concat(taicpu.op_reg(A_DEC,countreg))
+            else
+              begin
+                list.concat(taicpu.op_reg_const(A_SUBI,countreg,1));
+                list.concat(taicpu.op_reg_reg(A_SBC,GetNextReg(countreg),NR_R1));
+              end;
+
             a_jmp_flags(list,F_NE,l);
             cg.ungetcpuregister(list,NR_R26);
             cg.ungetcpuregister(list,NR_R27);
cgcpu.patch (893 bytes)

Florian

2019-09-12 22:29

administrator   ~0118055

Thanks, applied.

Christo Crause

2019-09-13 09:06

reporter   ~0118056

Thanks Florian.

Issue History

Date Modified Username Field Change
2019-09-11 19:22 Christo Crause New Issue
2019-09-11 19:22 Christo Crause File Added: ttest.pp
2019-09-11 19:22 Christo Crause File Added: cgcpu.patch
2019-09-12 22:29 Florian Assigned To => Florian
2019-09-12 22:29 Florian Status new => resolved
2019-09-12 22:29 Florian Resolution open => fixed
2019-09-12 22:29 Florian Fixed in Version => 3.3.1
2019-09-12 22:29 Florian Fixed in Revision => 42977
2019-09-12 22:29 Florian FPCTarget => -
2019-09-12 22:29 Florian Note Added: 0118055
2019-09-13 09:06 Christo Crause Status resolved => closed
2019-09-13 09:06 Christo Crause Note Added: 0118056