Does the attached patch work?

On 1/26/19 12:20 PM, Michael Ring wrote:
I thought I was going crazy when debugging code that worked fine on cortex m3/4 but created unexpected results on cortex m0.

Turns out that the compiler creates incorrect assembler code for cortexm0 for div when used with constant expressions. Optimization level was -O1 and -O-

Take this code:

program divtest;
var
  a,b,c,d : word;
begin
  a := 64;
  b := 8;
  c := a div 8; //.LI4
  d := a div b; //.LI5
end.

looking at the assembler code it is very evident that no shift operations are done on cortex m0 (see .LI4). Is this a known issue or should I create a new one in bugzilla? (Search did not reveal a hit that looked like a match)

Michael

assembler cortex m0:

.Ll2:
    mov    r1,#64
    ldr    r0,.Lj3
    strh    r1,[r0]
.Ll3:
    mov    r1,#8
    ldr    r0,.Lj4
    strh    r1,[r0]
.Ll4:
    ldr    r0,.Lj3
    ldrh    r0,[r0]
    uxth    r0,r0
    ldr    r1,.Lj6
    strh    r0,[r1]
.Ll5:
    ldr    r0,.Lj3
    ldrh    r1,[r0]
    ldr    r0,.Lj4
    ldrh    r0,[r0]
    bl    fpc_div_longint
    uxth    r0,r0
    ldr    r1,.Lj9
    strh    r0,[r1]

assembler cortex m4:

.Ll2:
    movs    r1,#64
    ldr    r0,.Lj3
    strh    r1,[r0]
.Ll3:
    movs    r1,#8
    ldr    r0,.Lj4
    strh    r1,[r0]
.Ll4:
    ldr    r0,.Lj3
    ldrh    r0,[r0]
    asrs    r1,r0,#31
    add    r0,r0,r1,lsr #29
    asrs    r0,#3
    uxth    r1,r0
    ldr    r0,.Lj6
    strh    r1,[r0]
.Ll5:
    ldr    r0,.Lj3
    ldrh    r0,[r0]
    ldr    r1,.Lj4
    ldrh    r1,[r1]
    sdiv    r0,r0,r1
    uxth    r0,r0
    ldr    r1,.Lj9
    strh    r0,[r1]
Index: compiler/arm/narmmat.pas
===================================================================
--- compiler/arm/narmmat.pas	(revision 41076)
+++ compiler/arm/narmmat.pas	(working copy)
@@ -164,7 +164,7 @@
                       cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SAR,OS_INT,31,numerator,helper1);
                     if GenerateThumbCode then
                       begin
-                        cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SAR,OS_INT,32-power,helper1);
+                        cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SHR,OS_INT,32-power,helper1);
                         current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_ADD,helper2,numerator,helper1));
                       end
                     else
@@ -179,9 +179,12 @@
                else
                  cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SHR,OS_INT,power,numerator,resultreg)
              end
-           else {Everything else is handled the generic code}
+           else if CPUARM_HAS_UMULL in cpu_capabilities[current_settings.cputype] then
+             {Everything else is handled the generic code}
              cg.g_div_const_reg_reg(current_asmdata.CurrAsmList,def_cgsize(resultdef),
-               tordconstnode(right).value.svalue,numerator,resultreg);
+               tordconstnode(right).value.svalue,numerator,resultreg)
+           else
+             internalerror(2019012601);
          end;
 
 {
@@ -286,8 +289,7 @@
                 resultreg:=cg.getintregister(current_asmdata.CurrAsmList,size);
               end;
 
-            if (right.nodetype=ordconstn) and
-               (CPUARM_HAS_UMULL in cpu_capabilities[current_settings.cputype]) then
+            if (right.nodetype=ordconstn) then
               begin
                 if nodetype=divn then
                   genOrdConstNodeDiv
_______________________________________________
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply via email to