#1139 Missing banksel for function parameter

closed-invalid
nobody
5
2013-05-25
2006-06-04
kein0r
No

Since the sdcc-users mailinglist seems to be not
working i post this bug again here.

Found a small but really annoying bug in the pic16 port
of the sdcc. sdcc is compiled from svn.

The Problem: All Register in the pic16 are 12Bits.
Writing to these registers must either be via the W
register and a "bank select" first or with the movff
command.

When i write the following function (this function
doesn't make any sense, its just to demonstrate the
problem):

void func1 (char a, unsigned int b, char c, unsigned int d)
{
SPBRG = a;
SPBRG = (char) b;
INTCON = c;
INTCON = (char) d;
}

The values a, and c are written correct to the register
because sdcc generates code like:

movff r0x00, SPBRG
and
movff r0x02, INTCON

but for the two int values sdcc, generates:

movf r0x01, W
movwf SPBRG

without any bankselect first. glink then generates the
following assembler code out of it:

movwf 0xaf, 0

The register SPBRG is *not* 0xaf but 0xfaf but since
movwf can only handle addresses up to 0xff there must
be either a bank select before or the movff command
must be used.

My problem is that i want to use a few external
functions which are defined like the one above.

Discussion

  • kein0r
    kein0r
    2006-06-04

    • summary: Missing banksel in function call --> Missing banksel for function parameter
     
  • Raphael Neider
    Raphael Neider
    2006-06-06

    Logged In: YES
    user_id=1115835

    If I am not mistaken, SDCC is right here.
    Reasoning:
    The PICs sport an access bank, which redirects accesses to
    registers 0x00..0x7F (upper bound device dependent) to bank
    0 and accesses to 0x80..0xff (lower bound device dependent)
    to bank 0xf (thats 0xf80..0xfff).

    From your code snippet I gather that the "movwf 0xaf, 0"
    uses the access bank feature (trailing ", 0") and thus needs
    not select bank 15 manually.
    The same holds for the r0xXX, as they are also allocated
    into the access bank (bank 0, hopefully we never reach the
    device dependent limit ;-)).

    Regards,
    Raphael

     
  • Raphael Neider
    Raphael Neider
    2006-06-06

    • assigned_to: nobody --> tecodev
    • milestone: --> 100455
    • status: open --> pending-invalid
     
  • kein0r
    kein0r
    2006-06-20

    • status: pending-invalid --> open-invalid
     
  • kein0r
    kein0r
    2006-06-20

    Logged In: YES
    user_id=1212013

    Sorry had much work and it took me quite some time to figure
    out exactly where the error lies.
    Its either in the code generated by sdcc or a bug in gpasm.

    For testing i defined a function like:

    void set_spbrg (unsigned int spbrg) {
    SPBRG = spbrg; // 48MHz => 57.600 baud (BRGH = 1)
    __asm
    MOVFF r0x00, _SPBRG
    __endasm;
    }

    Without the __asm block the program doesnt work, cause sdcc
    generates
    MOVF r0x00, W
    MOVWF _SPBRG

    With the __asm block the programm works.

    The Problem is that unsinged int is used in many picv16 lib
    i.e. in serial_open, which wont work with this bug.

    Version
    SDCC : avr/pic16 2.5.6 #4243 (Jun 20 2006) (UNIX)
    gpasm-0.13.3 beta
    gplink-0.13.3 alpha

     
  • kein0r
    kein0r
    2006-06-20

    Logged In: YES
    user_id=1212013

    Can you confirm this still exists in 2.5.6?

     
  • Raphael Neider
    Raphael Neider
    2006-06-20

    Logged In: YES
    user_id=1115835

    I still do not understand *why* this fails: Did I get it
    right that you have some code A that compiles but does not
    show the expected results when executed in hardware? Then
    you have code B that compiles fine and executes as expected
    in hardware? And the only difference between A and B is the
    "__asm movff r0x00, _SPBRG __endasm;" statement? That is
    mightily queer...

    Could you pass along some information about the device you
    are actually using, so that I can look up the "device
    dependent limit"? (See previous posting, maybe its at 0xb0
    for your PIC and our device description is just wrong)?

    For obvious reasons, I am pretty much unwilling to add
    BANKSELs before each and every register/SFR access, and I
    currently see no way to discern your (broken) example from
    other (but working) examples...

    BTW: Simulating your code using a pic18f1220 shows that the
    code "should be ok" (tm); there's something fishy... Where
    is your stack located? How large is it? (The 1220 has severe
    memory limitations, when trying to simulate it I just
    wondered whether this might be a problem...)

    Still confused,
    Raphael Neider

     
  • Raphael Neider
    Raphael Neider
    2006-06-20

    • milestone: 100455 -->
    • status: open-invalid --> open
     
  • kein0r
    kein0r
    2006-06-20

    Logged In: YES
    user_id=1212013

    First thank allot for your effort to solve this issue.

    I dont think a BANKSEL is the solution/problem nmore. This
    was just my first guess when i found the error.

    Its a pic18f2550 (rev 2) with the normal max232 circuit
    conencted to the pc.
    The Problem was that the open_serial function from the sdcc
    library didnt worked for me so i tried to find the error
    which showed that the "unsigned int spbrg" value was not
    correctly written to the SPBRG register.

    Again: The Problem does no occur when i use char spbrg since
    then sdcc directly uses movff to copy r0x00 to SPBRG reg.

    Wihout the __asm block the code compiles but the value
    written to SPBRG is wrong and minicom only shows garbage.
    Whit the __asm block everythin works fine.
    I dont think that this is a stack problem since the movff
    r0x00,SPBRG works. So the value on the stack und thus in
    r0x00 should be correct.

    I just found out that if i add an __asm block with
    MOVLW 0x33
    MOVWF _SPBRG
    instead of the other __asm block where 0x33 is the value i
    want to write to spbrg the programm also works. This makes
    the problem even more weird.

    I tried the following stack option:
    - no stack pragma (only works since 2.5.6 afaik)
    - #pragma stack 0x200 64
    - extern stack;
    extern stack_end;

    all with the same result.
    BTW: With what programm did you simualte the code?

     
  • Jim Paris
    Jim Paris
    2006-06-20

    Logged In: YES
    user_id=175928

    The behavior of the access bank changes if the extended
    instruction set is enabled. Maybe you have the XINST config
    bit set incorrectly?

     
  • kein0r
    kein0r
    2006-06-20

    Logged In: YES
    user_id=1212013

    yes i have set ENHCPU_ON_4L, didnt thought that this could
    be the prob. Ill test this tomorrow as soon as im back in
    the lab

     
  • kein0r
    kein0r
    2006-06-21

    Logged In: YES
    user_id=1212013

    that did it. Thx all for the help and sorry for wasting your
    time.

     
  • Raphael Neider
    Raphael Neider
    2006-10-15

    • assigned_to: tecodev --> nobody
    • milestone: --> non_bugs
    • status: open --> closed-invalid