LI flag usage in RXv2

What is usage of LI flag in RXv2 and how this LI flag is related to interrupt?

  • LI flag says long word has been transferred to register.
    LI flag is not related to interrupts.

  • surya,

    Has your question been answered?

    Mike Clements
    RenesasRulz Moderator
  • @FrankL @MikeClements (does this forum use @ tags?) I see that Surya never responded as to whether FrankL answered the question, but I cannot imagine that FrankL's response is sufficient for Surya or anyone else seeking an answer to the same question.

    Imagine you're a competent engineer & programmer but you've never worked with Renesas RX parts before, and you come across this strange "LI flag" thing. It piques your interest and you crave the knowledge of the experts, but the experts hide behind vague descriptions that can only be described as "technically" correct. These technically correct explanations, both here in this forum and in the RXv2 instruction set manual, give no high-level overview of what the LI flag's purpose is, or how it should be used. There's no example code using the MOVLI or MOVCO instructions, and it's bewildering why the RTE and RTFI instructions would set the LI flag to 0.

    Please come out from behind your walls of vagueness and give us a good explanation of the purpose of the LI flag. What's its USE CASE? Why would I want it? And how do I use it????????????? Give me some sample code!
  • In reply to phonetagger:

    phonetagger,

    I'm not exactly sure what is vague about explaining why a flag is triggered.

    As FrankL has stated when a long word has been transferred to a register the LI flag is set.

    There isn't really any code to give as an example.

    " it's bewildering why the RTE and RTFI instructions would set the LI flag to 0."

    When you return from an interrupt the LI flag is cleared because upon exit of the interrupt the register may be returning a value.

    I hope this answers your question

    Mike Clements

    RenesasRulz Moderator

  • In reply to Mike Clements:

    Hi Mike,

    That still doesn't answer the core of my question: What is the "use case" for the LI flag and the MOVLI & MOVCO instructions? The MOV.L instruction also moves a longword, and it doesn't need the LI flag. Why do the MOVLI & MOVCO instructions need it? Why did they add those instructions in RXv2? Someone must have found some deficiency in the MOV.L instruction by itself; it seems perhaps the reason has something to do with interrupts, otherwise the RTE and RTFI instructions wouldn't set the LI flag to 0.

    You say the return-from-interrupt instructions clear the LI flag because upon exit of the interrupt the register will be returning a value, but nothing in the instruction reference manual says that. And according to Frank, the LI flag is not related to interrupts. Also, there are 256 interrupts, and the RTE & RTFI instructions from any of those will clear the LI flag, not just one interrupt that's responsible for handling behind-the-scenes actions in response to MOVLI/MOVCO instructions (which I don't think is how they work anyway, but my point is that ANY interrupt's RTE/RTFI would clear the LI flag, even ones that don't have anything to do with the MOVLI/MOVCO instructions).

    So if you could find out why the MOVLI & MOVCO instructions were added, that would shed some light on their use case. An example of how they're used would also be nice. And an explanation of why the RTE/RTFI instructions clear the LI flag would also be nice; I don't think your explanation above is correct.

    Thanks,
    -Mark
  • In reply to phonetagger:

    Mark,

    FrankL's answer describes what the lI flag does in detail, but as you said, it doesn’t justify the existence of that flag.

    That is not what the software manuals are for. They are essentially specifications of the available assembly language instructions, how they are organized, and what they do (including registers and flags that are set and read by those instructions). It would be nice to have use cases for all of the low-level details such as a specific flag that is set under certain conditions, but as you've seen they are not included in the software manual. And I suspect it would make the manual much longer and less focused it's "specification" flavor. If enough developers programmed in assembly language (as I did in the very early part of my career), a book describing techniques to get the most out of every feature for the application or system level programer would be nice to have. I think I had such a book from the early eighties. Of course it was relating to an old and very specific instructions set (not RX).

    This might be a bit of a stretch, but here is a (high level) use case that could take advantage of the LI flag:

    You are writing assembly language code directly (not relying on an optimizing compiler to make decisions about the size of operands to use). You want a tight little piece of code to take the very smallest amount of time to execute, right down to the cycle. Maybe you are writing a driver for a communication peripheral that is being run at the very top speed it can run at, and you need your code to respond to events a bit more quickly than you can do in C, since the compiler does not know exactly where you need the most optimization.

    So to see where there are opportunities to shave off a few more cycles, you write a diagnostic tool that tracks all register reads and writes, and you want it to log or display the size of operand that is written to a register. This might be useful for seeing places where the code could be optimized, for example by restructuring the code to use word or byte write instead, if your knowledge of your application deems that manual optimization to be safe in your specific case.

    I hope the above use case description helps.

    -MarkB
  • In reply to Mark Barclay:

    The LI flag is used for atomic operations. If you have a variable that is used both in normal and interrupt routines. Then you want to make sure that there is no conflict during changes of the variable.

    A simple example is a function to set a bit of the variable that makes sure that the variable is not changed during setting of the bit: 

    ;void setBit(int nr, void * addr)

    _setBit:

    MOVLI [R2], R3 ;load long value @ addr to R3 and set LI flag

    BSET R1, R3 ;set the required bit in R3

    MOVCO R3, [R2] ;store the adjusted long value back @ addr and clear LI flag

    TST #1, R3 ;check if store is done.

    BNZ _setBit ;retry set if failed

    RTS

    if an interrupt occurs between MOVCO and MOVLI, then the LI flag will be cleard by the RTE at the end of the interrupt routine.
    This clearing of the LI flag indicates that its possible that the value @ addr is changed by the interrupt routine.
    Checking the value of the source register after MOVCO gives you an indication in changes of the value @ addr.
    A 0 guarantees that the value @ addr is not changed since the MOVLI instruction.
    A 1 indicates that its possible that the value @ addr has changed since the MOVLI instruction.

    The BSET instruction is already atomic so its actually not necessary to use the MOVLI and MOVCO but other operation will need them.