0

Hello support team,

I found the following generated code by LLVM-RL78 in my program. I have three questions.

(1) Why bit operation instructions aren’t used?
(2) Generated code is bad, isn’t it?
(3) Also this code works with only register bank 0, doesn’t it?

SOURCE:

void R_Config_INTC_INTP0_Start(void)
{
PIF0 = 0U; /* clear INTP0 interrupt flag */
PMK0 = 0U; /* enable INTP0 interrupt */
}

CODE(LLVM-RL78, -Os is used):

0000332a _R_Config_INTC_INTP0_Start:
; PIF0 = 0U; /* clear INTP0 interrupt flag */
332a: 36 e0 ff movw hl, #65504
332d: ab movw ax, [hl]
332e: 5a f8 fb and 0xffef8, #251
3331: 36 e0 ff movw hl, #65504
3334: bb movw [hl], ax
; PMK0 = 0U; /* enable INTP0 interrupt */
3335: 36 e4 ff movw hl, #65508
3338: ab movw ax, [hl]
3339: 5a f8 fb and 0xffef8, #251
333c: 36 e4 ff movw hl, #65508
333f: bb movw [hl], ax
; }
3340: d7 ret

FYI: CODE(GNURL78, -Os is used):

00003227 <_R_Config_INTC_INTP0_Start>:
3227: 71 2b e0 clr1 0xfffe0.2
PIF0 = 0U; /* clear INTP0 interrupt flag */
3228: 2b e0 sub a, 0xffee0 <– this may be caused by incorrect debug information
PMK0 = 0U; /* enable INTP0 interrupt */
322a: 71 2b e4 clr1 0xfffe4.2
}
322d: d7 ret

Best regards,
NoMaY

Darius Galis コメント済
    • Hello support team,

      I notice one new thing. PIF0 is defined as follows. This bit should be operated by bit operation instruction. Nevertheless somehow this bit is defined as a bit of 16bit register. This definition is the same as RL78/G14. I worry this may be the root cause of bad generated code. (But GNURL78 generate a good code.)

      src/smc_gen/r_bsp/mcu/rl78_g23/register_access/llvm/iodefine.h

      #define PIF0 IF0_bit.no2

      #define IF0_bit (*(volatile union un_if0 *)0xFFFE0).BIT

      union un_if0 {
      unsigned short if0;
      __BITS16 BIT;
      };

      typedef struct {
      unsigned short no0 :1;
      unsigned short no1 :1;
      unsigned short no2 :1;
      unsigned short no3 :1;
      unsigned short no4 :1;
      unsigned short no5 :1;
      unsigned short no6 :1;
      unsigned short no7 :1;
      unsigned short no8 :1;
      unsigned short no9 :1;
      unsigned short no10 :1;
      unsigned short no11 :1;
      unsigned short no12 :1;
      unsigned short no13 :1;
      unsigned short no14 :1;
      unsigned short no15 :1;
      } __BITS16;

      Best regards,
      NoMaY

    • Hello support team,

      According to the C language specification, I think that generate code by GNURL78 is incorrect because the iodefine.h defines that the bit is a bit of a 16bit register with ‘volatile’ keyword. In this case, ‘volatile’ requests that the register has to be accessed as a 16bit register.

      Best regards,
      NoMaY

    • Dear NoMaY-san,

      We are grateful for your feedback and we are already on a path to improve this in the next release of LLVM RL78.

      __
      Best regards,
      The Open Source Tools Team

    • Dear NoMaY-san,

      We have investigated the issue and we can confirm that the code generated by GNURL78 is incorrect.
      This is indeed one of the reasons GCC RL78 generates smaller code. Although not optimal for code size, the code generated by LLVM RL78 is correct.

      Please let us know if your intention is to continue your development process with the GCC RL78 compiler,
      or if you are willing to switch to the new LLVM RL78 compiler? We appreciate the feedback we are receiving from you.

      We are actively improving and enhancing the LLVM RL78 compiler, and you will always be able to get the latest updates performed to it, both in terms of runtime performance and code size enhancements.
      __
      Best regards,
      The Open Source Tools Team

    • Hello support team,

      Thank you for the reply.

      My opinion is:

      (1) iodefine.h should be fixed to use 8bit register name instead of 16bit register name. (Of course not only RL78/G23 and RL78/G14 but also other devices.)
      (2) LLVM-RL78 should be fixed to generate bit operation instruction with above updated iodefine.h.

      REASON:

      In case of RL78 architecture, bit operation instruction has to be used to operate each IF bit flags. Even if the following operation is used, other IF bit flags of the same byte may be cleared unexpectedly and such unexpected clear of other IF bit flags means the unexpected lost of interrupt request.

      PUSH PSW
      DI
      read the IF register to A register
      clear (or set) the bit of A register
      write A register to the IF register
      POP PSW

      RL78 is RL78, RL78 is neither RX nor Cortex.

      Best regards,
      NoMaY

    • Dear NoMaY-san,

      Thank you once again for your feedback. We will inform the team responsible for maintaining the project generated files to change iodefine.h according to your proposal. The LLVM RL78 compiler will be improved as soon as possible.
      __
      Best regards,
      The Open Source Tools Team

    • Dear customer,

      We are happy to report that the generation of bit manipulation instructions should be improved in the new 10.0.0.202107 release of the LLVM for Renesas RL78 toolchain, available for download on our website at: https://llvm-gcc-renesas.com/rl78/rl78-download-toolchains/

      If you have any further questions about the issue, please let us know.

      – Thank you,
      The Open Source Tools Team