I updated from 4.0 to 4.3.0 #14110.
Saving code space is excellent, but I have a function for writing to the
eeprom
void EEPROMdata8(uint16_t address, uint8_t data)
{
disableInterrupts();
EEPROMunlock();
((uint8_t)(uint16_t)address) = ((uint8_t*)(&(uint8_t)data));
EEPROMlock();
enableInterrupts();
}
and now Make will display
?ASlink-Warning-Undefined Global 'iTemp1' referenced by module 'eeprom'
In eeprom.lst is now
137; eeprom.c: 51:
((uint8_t)(uint16_t)address) = ((uint8_t)(&(uint8_t)data));
000052 AEr00r00 [ 2] 138 ldw x, #iTemp1+0
000055 F6 [ 1] 139 ld a, (x)
000056 90 F7 [ 1] 140 ld (y), a
If I change to
((uint8_t)address) = ((uint8_t)&data);
the code is
137; eeprom.c: 50:
((uint8_t)address) = ((uint8_t)&data);
000053 90 93 [ 1] 138 ldw y, x
000055 7B 01 [ 1] 139 ld a, (0x01, sp)
000057 90 F7 [ 1] 140 ld (y), a
Even if I change to
((uint8_t)address) = ((uint8_t)&data);
((uint8_t)(uint16_t)address) = ((uint8_t)(&(uint8_t)data));
the code is correct in both cases
137; eeprom.c: 50:
((uint8_t)address) = ((uint8_t)&data);
000053 90 93 [ 1] 138 ldw y, x
000055 7B 01 [ 1] 139 ld a, (0x01, sp)
000057 90 F7 [ 1] 140 ld (y), a
141; eeprom.c: 51:
((uint8_t)(uint16_t)address) = ((uint8_t)(&(uint8_t)data));
000059 7B 01 [ 1] 142 ld a, (0x01, sp)
00005B F7 [ 1] 143 ld (x), a
CFLAGS= -lstm8 -mstm8 --opt-code-size --std-sdcc99 --out-fmt-elf --model-medium --max-allocs-per-node 10000
I'm a newbie, I don't know these things. Hopefully it will work.
Where can I find the stm8s.h included by main.c?
This is a regular stm8s.h with a patch for sdcc and I don't know how it is with copyright.
I tried with stm8s.h from https://github.com/erno-szabados/sdcc-stm8s/blob/master/stm8s.h, but that didn't work for me ("main.c:12: error 20: Undefined identifier 'FLASH'").
Maybe you could provide the of preprocessed main.c (i.e. what you get via sdcc -E)? Then no headers would be needed to compile.
Last edit: Philipp Klaus Krause 2023-06-22
To stm8s.h add
In main.c all "->" change to "_".
Thanks. I can reproduce the issue now on my Debian GNU/Linux testing system.
I use
System:
Kernel: 6.2.16-060216-generic x86_64 bits: 64 compiler: N/A Desktop: Cinnamon 5.6.8
tk: GTK 3.24.33 wm: muffin dm: LightDM Distro: Linux Mint 21.1 Vera base: Ubuntu 22.04 jammy
I've simplified the code a bit:
I have msg
main.c main.c:19: error 9: FATAL Compiler Internal Error in file '/home/sdcc-builder/build/sdcc-build/orig/sdcc/src/stm8/peep.c' line number '93' : readint() got non-integer argument:
Contact Author with source code
iTemp1+0
make: *** [Makefile:63: build/main.rel] Chyba 1
Yes. For the smaller example, the reference to the iTemp apparently also confuses the peephole optimizer.
Looks like the information that data has had its address taken in not correctly passed from AST. At the time we generate the RECEIVE iCode for the register parameter data, the addrtaken flag is not set; I suspect that this later results in the problem, as register allocation puts a variable into registers, and code generation then tries to take its address.
How to get the compilation's typecasting to work properly.
((uint8_t)address) = ((uint8_t)(&data));
Yes. The logic for setting the isaddr flag in src/SDCCast.c checks for IS_AST_SYM_VALUE, which is true when the & operator is applied directly to the symbol, but not when applied to the casted value.
It might be hard to fix this and make it work. It works in GCC and MSVC, and sometimes happens to work for SDCC. But AFAIK it is not required by the standard, so we could emit an error message (like clang does), telling the user that & of an rvalue is not supported.
P.S.: And the logic for that is already there and works for other expressions, and some casts. So the underlying issue here is apparently that for this cast, the rvalue flag wasn't set or checked correctly. And apparently a similar issue as for this cast also exists for unary minus, as the following code compiles without error (it returns -i):
P.P.S.: Looks like this (checking that the operand is not an rvalue) is totally broken. For unary operators, we don't get an error message at all. For binary operators we get a confusing one.
Last edit: Philipp Klaus Krause 2023-06-23
I think I have a fix. But it needs a bit more testing, which I won't be able to do before Monday. Apparently lvalue vs. rvlaue handling was quite messed up in SDCC, so the fix is bigger than I first expected; IMO it needs quite some testing before going into a release. That means it would go into trunk after the 4.3.0 releaase.
Last edit: Philipp Klaus Krause 2023-06-23
This is very good news. But I'm a newbie and I've never patched or compiled from sources before.
If there was a non-public nightbuild, I would test it.
Some time ago I did a lot of searching for alternative code notations to get the shortest result. I fought for every byte. Much improved in 4.3. I am glad that sdcc is so intensely alive. Thanks.
The fix is in the next branch now (to be merged to trunk after the 4.3.0 release), so it is likely to be in snapshots sometime early next month.
If you want to try it now, compiling sdcc from source isn't hard on GNU/Linux:
1) Get the source (e.g. for the next branch:
svn checkout svn://svn.code.sf.net/p/sdcc/code/branches/next/sdcc sdcc-next
)2)
cd sdcc-next
3)
./configure --disable-pic14-port --disable-pic16-port
4)
make
(or usemake -j N
, where N is the number of cores to use for a faster compile).5)
make install
(with sufficient priviledges) to install into /usr/local.If you miss some tools or libraries, 2) should tell you which ones are missing. If you use Debian/Ubuntu or similar,
apt-get build-dep sdcc
should install what is needed, so it likely makes sense to do that first.Fixed in [r14211] by merging next to trunk.
Related
Commit: [r14211]