Asm issue2019-05-21T09:53:05+00:00
Viewing 2 reply threads
  • Author
    Posts
    • StephaneStephane
      Participant
      Post count: 2

      Hello,

      I am compiling the following code:

      int32_t ratio(uint32_t u, uint32_t v, int32_t w) {
      u = u < < 10; uint32_t d0 = u / v; uint32_t r0 = u - d0 * v; uint32_t d1 = (r0 << 10) / v; uint32_t d10 = (d0 << 10) + d1; return (int32_t)(((int64_t)w) * ((int64_t)d10) >> 20);
      }

      with the command line: riscv32-unknown-elf-gcc -O2 -S -march=rv32imcxgap8 ratio.c
      I get:

      .file “ratio.c”
      .option nopic
      .text
      .align 1
      .globl ratio
      .type ratio, @function
      ratio:
      sll a0,a0,10
      p.remu a5,a0,a1
      p.divu a0,a0,a1
      sll a5,a5,10
      p.divu a5,a5,a1
      sll a0,a0,10
      add a1,a5,a0
      p.mul a0,a1,a2
      p.mulhsu a1,a1,a1
      srl a0,a0,20
      sll a1,a1,12
      or a0,a1,a0
      ret
      .size ratio, .-ratio
      .ident “GCC: (GNU) 7.1.1 20170509”

      with the command line: riscv32-unknown-elf-gcc -O2 -S ratio.c
      removing the GAP8 option I get:

      .file “ratio.c”
      .option nopic
      .text
      .align 1
      .globl ratio
      .type ratio, @function
      ratio:
      sll a0,a0,10
      remu a5,a0,a1
      divu a0,a0,a1
      sll a5,a5,10
      divu a5,a5,a1
      sll a0,a0,10
      add a1,a5,a0
      mul a0,a1,a2
      mulhsu a1,a2,a1
      srl a0,a0,20
      sll a1,a1,12
      or a0,a1,a0
      ret
      .size ratio, .-ratio
      .ident “GCC: (GNU) 7.1.1 20170509”

      The p.mulhsu registers are not properly issued with the gap8 option.
      This is confirmed at execution on the eval board with the result of ratio(1000, 10000, 10000) being 9191 instead of 999.
      Is this a mistake on my side somewhere ?

      Regards,

      Stephane

    • StephaneStephane
      Participant
      Post count: 2

      By the way the issue is the same with the simpler example:

      int64_t mmm(int32_t a, uint32_t b) {
      return ((int64_t)a) * ((uint64_t)b);
      }

      giving

      mv a5,a1
      p.mulhsu a1,a1,a1
      p.mul a0,a5,a0
      ret

      In fact, looking in the compiler source in
      pulp-riscv-gcc/gcc/config/riscv/riscv.md

      the line :

      (define_insn “usmulsi3_highpart” [(set (match_operand:SI 0 “register_operand” “=r”) (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 “register_operand” ” r”)) (sign_extend:DI (match_operand:SI 2 “register_operand” ” r”))) (const_int 32))))] “(TARGET_MUL||(Pulp_Cpu>=PULP_V2)||(Pulp_Cpu==PULP_SLIM)) && !TARGET_64BIT” { if (Pulp_Cpu) return “p.mulhsu\t%0,%1,%1”; else return “mulhsu\t%0,%2,%1”; } [(set_attr “type” “imul”) (set_attr “mode” “SI”)])

      may be the issue as p.mulhsu\t%0,%1,%1 should probably be p.mulhsu\t%0,%2,%1

      Regards,

      Stephane

    • Martin CroomeMartin Croome
      Keymaster
      Post count: 20

      Hi Stephane

      Many thanks for the report. This is fixed and pushed. We will update the compiled toolchain ASAP.

      Regards

      Martin

Viewing 2 reply threads
  • You must be logged in to reply to this topic.