When compiling as banked code/data, when taking a gptr to data in the current codeseg/constseg the high byte is dropped and always fixed at 0x80.
The following example function:
// sdcc -c --fverbose-asm --std-sdcc2x -mmcs51 --model-large --stack-auto --fomit-frame-pointer --no-peep -Wl-M -Wl-r -Wl-a -Wl-bBANK1=0x014000 bug.c
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#pragma codeseg BANK1
#pragma constseg BANK1
void print_something (const char*) __banked;
int main (void)
{
const char* c = "test moon -- please ignore\n";
print_something (c);
return 0;
}
compiles to:
_main:
ar7 = 0x07
ar6 = 0x06
ar5 = 0x05
ar4 = 0x04
ar3 = 0x03
ar2 = 0x02
ar1 = 0x01
ar0 = 0x00
; bug.c:15: const char* c = "test moon -- please ignore\n";
; bug.c:16: print_something (c);
; genCall
mov dpl,#___str_0
mov dph,#(___str_0 >> 8)
mov b,#0x80 <<<< high byte of pointer to const data is wrong
should be #((___str_0 >> 8) + 0x80)
mov r0,#_print_something
mov r1,#(_print_something >> 8)
mov r2,#(_print_something >> 16) <<<< high byte of function call address is correct
lcall __sdcc_banked_call
; bug.c:17: return 0;
; genRet
mov dpl,#0x00
mov dph,#0x00
00101$:
; bug.c:18: }
ret
.area BANK1 (CODE)
.area BANK1 (CODE)
.area BANK1 (CODE)
___str_0:
.ascii "test moon -- please ignore"
.db 0x0a
.db 0x00
.area BANK1 (CODE)
.area XINIT (CODE)
.area CABS (ABS,CODE)
Another case:
compiles to:
It seems there is no way to edit the original description. There is a mistake:
should be
In the large memory model the memory is assumed to be <=64kB. Especially the const and xdata is supposed to be in that range. Functions can be marked as banked and so can function pointers.
But if you want your variables to live in banked memory as well you must use the huge memory model.Last edit: Maarten Brock 2023-09-05
When compiling the example as huge-model it yields s the same result. It doesn't pass the correct
__code
pointer to the print function. The top byte is always stuck at 0x80.Also as per SDCC manual:
Please consider to re-open this issue.
Last edit: Maarten Brock 2023-09-05
@maartenbrock is there a working example somewhere that demonstrates how to use that?
From what I have tried and see, there is no way to get the correct full 23-bit pointer to a const data. Please reconsider to re-open this issue.
I'm sorry. I was mistaken. Although the top byte values and gptrget are somewhat prepared for this, it was never implemented. The manual is correct in stating that huge is the same as large with all functions marked __banked.
This would therefore only qualify as a feature request.
Ticket moved from /p/sdcc/bugs/3622/
Can't be converted:
Thanks.
What I've been doing in my software for some parts which can access the external 24 MByte address space directly:
... and then use that macro to make a user-defined 24-bit pointer with the correct high byte. This is for e.g. transferring data included in the C source file by DMA or other flash reading routines, not directly by CPU code.
However, compiling this type of code with the latest SDCC SVN trunk version bails out in SDCCgenconstprop.cc because it hits the high byte with "unknown" / "unexpected" value.
I've applied the attached patch temporarily to my local tree.
Last edit: Oleg Endo 2023-09-05
I suggest to change the check on gpbyte to look at the selecting bits only. Or maybe only comparing the top nibble is already better. Also, a warning is better suited here than an error IMHO.
I think the cprop code in that spot is already trying to do something with known bits or such. But I didn't understand it at first glance. Perhaps @spth knows this part best.