1

So I have the following code compiled in an MPLABX project using XC32, the goal is to check if I need to change the context for an RTOS implementation:

    .extern OS_TaskRUNNING, 0x04 # Both of these are pointers in a C file
    .extern OS_TaskNEW, 0x04

CheckSwitch:
    la $1, OS_TaskRUNNING
    la $2, OS_TaskNEW
    lw $1, 0x00($1)
    lw $2, 0x00($2)
    xor $1, $1, $2
    bne $1, $0, ConfirmSwitch
AbortSwitch:
    # stuff happens...
ConfirmSwitch:
    # stuff happens...

When the values in the two pointers are different, program execution fails to branch to ConfirmSwitch, instead it continues on to AbortSwitch (note for the incredibly observant people: I am using the 'noat' setting for the code in this file). Branching never happens no matter what values end up in $1 and $2. I've tried other variations such as bne $1, $2, ConfirmSwitch and end up with the same result. I'm at a loss to understand what I could possibly be doing wrong as this functionality is so basic.

Erik Eidt
  • 23,049
  • 2
  • 29
  • 53
  • Does this MIPS have branch delay slots? You might try putting a `nop` after the `bne`. – Erik Eidt Oct 11 '21 at 00:35
  • Did you single-step your code in a debugger (or simulator) to see what values are in registers? And to see the exact path of execution, including possible branch-delay slots, in case that explains why you think AbortSwitch is running. (If xc32 is a MIPS32r6, you could use the new no-branch-delay branch instructions.) – Peter Cordes Oct 11 '21 at 00:45

1 Answers1

1

Figured it out based on the comments below; adding a nop after each branch instruction solved the issue. In the simulator execution goes to the nop regardless of whether the branch condition evaluates as true or not, but then goes to the right place. Incidentally I was also using the 'noreorder' directive to stop the assembler from reorganizing my code. The XC32 assembler manual discusses branch delay slots when it mentions the aforementioned directive : "By default, the assembler attempts to fill a branch or delay slot automatically by reordering the instructions around it." This is the only real mention of a delay slot in the entire manual- nothing discusses what branch instructions require these or how big they might need to be. Numerous examples of sample code I found online to look into this problem don't even mention this as a thing.

  • 1
    Lots of MIPS code is written for fake or simplified MIPS without branch delay slots, like MARS / SPIM simulate by default (or for `reorder` mode I guess). MIPS's branch delay slot is a feature of the basic MIPS ISA, not something your assembler is doing. – Peter Cordes Oct 11 '21 at 01:22
  • If you don't understand delay slots, see https://devblogs.microsoft.com/oldnewthing/20180411-00/?p=98485. And/or don't use the `noreorder` option, so you can write code that ignores the branch delay slot, and let the assembler either fill it with an independent instruction or a NOP. If you don't understand them, don't use the `noreorder` assembler option! It makes sense that the assembler documentation writers assumed that people who know about branch slots would be the ones using `noreorder`, and otherwise the assembler would hide their existence so they could just not mention them. – Peter Cordes Oct 11 '21 at 01:23