Author Topic: PIC: pic-as loop with labelless relative branch bug  (Read 2024 times)

0 Members and 1 Guest are viewing this topic.

Offline DabbotTopic starter

  • Regular Contributor
  • *
  • Posts: 192
  • Country: au
PIC: pic-as loop with labelless relative branch bug
« on: April 30, 2021, 07:53:25 am »
Just letting you all know about this obscure bug I ran into.

Basically, if you use FCALL, then set up a loop using DECFSZ followed by BRA $ - OFFSET, instead of BRA LABEL, the assembler will quietly precede DECFSZ with a MOVLP instruction and change the intended return point of the loop.

This makes no sense whatsoever because PCLATH is corrected by the FCALL macro already, and the BRA / BRW instructions do not involve PCLATH at all.

Attached is the assembly, and the resultant list file demonstrating the bug, specifically line 31 (37) in the list file. I've reproduced this on V2.31 and V2.32 so far.

Edit: Reproduced the bug with V2.32 with list file attached.
« Last Edit: April 30, 2021, 02:12:10 pm by Dabbot »
 

Offline jpanhalt

  • Super Contributor
  • ***
  • Posts: 3466
  • Country: us
Re: PIC: pic-as loop with labelless relative branch bug
« Reply #1 on: April 30, 2021, 11:38:41 am »
Interesting.  Anxious to see others demonstrate it.

Just FYI, I tried it in MPLAB 8.92 using LCALL, and it works entirely as expected.  That is, if the destination is on the same page, PCLATH stays on that page (i.e., movlp 0 is in the disassembly).  If the destination is moved to 0x0100, then movlp 1 is executed, PCLATH is set to 1, and is not reset.  In either case, it returns to the proper place.  NB: FCALL is not recognized in that version of MPASM.
 

Offline DabbotTopic starter

  • Regular Contributor
  • *
  • Posts: 192
  • Country: au
Re: PIC: pic-as loop with labelless relative branch bug
« Reply #2 on: April 30, 2021, 01:11:40 pm »
Interesting.  Anxious to see others demonstrate it.

Just FYI, I tried it in MPLAB 8.92 using LCALL, and it works entirely as expected.  That is, if the destination is on the same page, PCLATH stays on that page (i.e., movlp 0 is in the disassembly).  If the destination is moved to 0x0100, then movlp 1 is executed, PCLATH is set to 1, and is not reset.  In either case, it returns to the proper place.  NB: FCALL is not recognized in that version of MPASM.

This is pic-as (xc8), not MPASM. Completely different beasts, so it's understandable that it works as expected on your end.

The bug is not with FCALL itself, but further down where I'm using DECFSZ and BRA to form a loop. For some reason pic-as sees the need to insert a MOVLP instruction right before the DECFSZ, and thus causes the loop to malfunction because the return point has effectively shifted up one place, and pic-as has not accounted for that.

If I comment out the FCALL, the extra MOVLP instruction disappears.
If I leave the FCALL there and use a label instead of an offset to form the loop, the extra MOVLP instruction disappears.
 

Offline jpanhalt

  • Super Contributor
  • ***
  • Posts: 3466
  • Country: us
Re: PIC: pic-as loop with labelless relative branch bug
« Reply #3 on: April 30, 2021, 01:37:58 pm »
I understood that the two assemblers were different.  That's why I made it an FYI in case you had not tried the equivalent with the earlier version.

I agree, it seems odd that an additional movlp gets added there, unless that was supposed to be an "enhancement."  I would have added it before the return in  the FCALL'd routine.  Does it still add the movlp to the DECFSZ routine if you reset PCLATH before the return?
 

Offline DabbotTopic starter

  • Regular Contributor
  • *
  • Posts: 192
  • Country: au
Re: PIC: pic-as loop with labelless relative branch bug
« Reply #4 on: April 30, 2021, 01:50:46 pm »
I would have added it before the return in  the FCALL'd routine.
FCALL handles the page selection automatically, so there's no need to do it manually unless some funny business is going on. It expands to:
MOVLP TARGET_PAGE
CALL TARGET
MOVLP CURRENT_PAGE

Does it still add the movlp to the DECFSZ routine if you reset PCLATH before the return?
Yep. I've tested manually placing an "MOVLP 0" in the function and after the FCALL macro. It does not change the behavior.
 

Offline jpanhalt

  • Super Contributor
  • ***
  • Posts: 3466
  • Country: us
Re: PIC: pic-as loop with labelless relative branch bug
« Reply #5 on: April 30, 2021, 01:58:24 pm »
That does seem odd that it would place the movlp before the DECFSZ rather then right after the call.

Sorry I can't help.  I have avoided the new "full-featured" versions so far.  Don't know how long I will be able to do that though.
 

Offline DabbotTopic starter

  • Regular Contributor
  • *
  • Posts: 192
  • Country: au
Re: PIC: pic-as loop with labelless relative branch bug
« Reply #6 on: April 30, 2021, 02:24:09 pm »
That does seem odd that it would place the movlp before the DECFSZ rather then right after the call.
The MOVLP right before the DECFSZ is in addition to the correctly placed MOVLP instructions surrounding the CALL instruction. It's completely out of place and seems to have something to do with the loop construction, because it will appear consistently before the DECFSZ no matter how many instructions are between the FCALL and the loop.


Sorry I can't help.  I have avoided the new "full-featured" versions so far.  Don't know how long I will be able to do that though.
That's fine. Thanks for checking.
I can see why people are put off by Microchip's "new way forward", but give it a shot sooner rather than later is my recommendation. MYself and others here can help answer questions.
 

Offline DrG

  • Super Contributor
  • ***
  • !
  • Posts: 1199
  • Country: us
Re: PIC: pic-as loop with labelless relative branch bug
« Reply #7 on: April 30, 2021, 04:04:27 pm »
I rejected trying to learn as, at least so far. I am trying to get a handle on why it is doing that. Quite frankly, I do not umm appreciate the new concept of a psect and that is when I said, no, I don't need to do this now. As long as I can still run mpasm in some coexisting older version of x ide, I will live.

So, by more of a question than anything else, what does this mean from the manual and is there any chance that you (or them) are doing it without knowing it? IOW: you have not defined the range/size of that psect, have you?

The fcall and ljmp instructions assume that the psect that contains them is smaller than a page. Do not use these
instructions to transfer control to a label in the current psect if it is larger than a page.
- Invest in science - it pays big dividends. -
 

Offline DabbotTopic starter

  • Regular Contributor
  • *
  • Posts: 192
  • Country: au
Re: PIC: pic-as loop with labelless relative branch bug
« Reply #8 on: April 30, 2021, 04:30:02 pm »
I rejected trying to learn as, at least so far. I am trying to get a handle on why it is doing that. Quite frankly, I do not umm appreciate the new concept of a psect and that is when I said, no, I don't need to do this now. As long as I can still run mpasm in some coexisting older version of x ide, I will live.

So, by more of a question than anything else, what does this mean from the manual and is there any chance that you (or them) are doing it without knowing it? IOW: you have not defined the range/size of that psect, have you?

The fcall and ljmp instructions assume that the psect that contains them is smaller than a page. Do not use these
instructions to transfer control to a label in the current psect if it is larger than a page.


The assembler (pic-as) aligns psects as it sees fit and prevents them (size or placement) from crossing page boundaries, given correct configuration for the target chip. I only specify the placement when required. I.e., psects for the reset and interrupt vectors.

The above from the manual is correct, but since the assembler will generally prevent psects from crossing page boundaries, it doesn't come into play. Normally, you do not use those macros in the same psect as they generate unnecessary instructions to handle page selection when it is not required.

In the code I attached, I didn't bother placing the function in another psect because it doesn't matter for the purposes of replicating the bug.

Edit: To clarify, as I was half asleep when I originally wrote my response.
« Last Edit: May 01, 2021, 02:35:28 am by Dabbot »
 

Offline jpanhalt

  • Super Contributor
  • ***
  • Posts: 3466
  • Country: us
Re: PIC: pic-as loop with labelless relative branch bug
« Reply #9 on: April 30, 2021, 04:42:41 pm »
Longshot guess:

What if you replace those NOP's in the loop with something else that does almost nothing, like movf  TEMP,f ?  Does the bug still occur?
 

Offline DabbotTopic starter

  • Regular Contributor
  • *
  • Posts: 192
  • Country: au
Re: PIC: pic-as loop with labelless relative branch bug
« Reply #10 on: May 01, 2021, 12:31:20 am »
Longshot guess:

What if you replace those NOP's in the loop with something else that does almost nothing, like movf  TEMP,f ?  Does the bug still occur?
No change.
 

Offline jpanhalt

  • Super Contributor
  • ***
  • Posts: 3466
  • Country: us
Re: PIC: pic-as loop with labelless relative branch bug
« Reply #11 on: May 01, 2021, 10:59:51 am »
That glitch bothers me.  In the years I have played with PICs, I have found a few inconsistencies, but never anything like that.  Of course, you have a work around, just as with the inconsistencies. 

Is that return point always just 2 instructions off or is it always to the same DECFSZ instruction?  That is, what happens if there are 4 NOP's after the call.  Can you view the hardware stack in simulation like in MPASM?  When does the wrong return PCL appear?
 

Offline DabbotTopic starter

  • Regular Contributor
  • *
  • Posts: 192
  • Country: au
Re: PIC: pic-as loop with labelless relative branch bug
« Reply #12 on: May 01, 2021, 12:00:51 pm »
Is that return point always just 2 instructions off or is it always to the same DECFSZ instruction?  That is, what happens if there are 4 NOP's after the call.
It doesn't seem to matter how many instructions follow the FCALL. It will always stick a MOVLP in right before the DECFSZ instruction.
I tried replacing DECFSZ with INCFSZ, BTFSS, BTFSC and it does the same thing: stick a sneaky MOVLP instruction before it.

Can you view the hardware stack in simulation like in MPASM?  When does the wrong return PCL appear?
There's no point going into the simulator, since the bug has already been identified as an assembler bug, not a hardware bug. I originally discovered and fixed the problem in a different body of code. What I attached is simply the bare minimum to showcase the bug, after I spent time narrowing it down. There's no need to simulate or load it onto a chip.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf