Open kervinck opened 5 years ago
Re 4, perhaps you could add a compiler built-in that users could mark variables they don't expect full 16-bit comparisons on? That could then aid with the static analysis.
[Edit MvK: removed quoted e-mail]
Yes, this concept needs to evolve, hence the issue to track the thought process
My idea of prioritising things in LCC are:
This has the potential to make a lot of code very inefficient, and I like to know the impact. For example:
if (putc(…) < 0)… can become nasty, whereas
if (putc(…) == EOF) … has potentially an efficient translation (using ADDI 1 + BNE)
Perhaps we can squeeze in another new vCPU instruction that helps for these: "CMPW $DD".
ROM v5 will have CMPHS
and CMPHU
instructions that are designed to solve this. See also https://github.com/kervinck/gigatron-rom/commit/f584a2aa986949fcb42cb4606005d74e1ebc395a
Suggesting to close this issue since glcc does this correctly already (on both roms v4 --with code-- and v5a+ --with cmphi/cmphs).
The result of SUBW doesn't indicate if an overflow has occurred. Consequently, vCPU offers only signed comparisons against 0 for branching decisions. With that, the relational operators a<b, a<=b, a a>=b a>b only work when the difference between a and b fits in 15 bits. Ultimately this idiosyncrasy stems from the lack of status register in the 8-bit hardware architecture, and the underlying design idea that software can always compensate for missing hardware features...
TinyBASIC_v2.gt1 uses the following sequence to get correct comparisons over the full range:
So prior to the standard subtract, it first checks if the operand highest bits are equal. If equal, it perform the normal SUBW for comparison. If not equal, the first operand is loaded for BLE/BLT (or the second operand in the case of BGE/BGT). This sequence costs 8 vCPU instructions or 18 bytes here, compared to 3/7 for the naive sequence. This is the reason that Tiny BASIC uses this idiom selectively.
For a compliant C compiler we need something similar. For example, now 0xffffu compares as smaller than 0. And we also can't really say that ints are just 15-bits wide instead.
My plan: