build: carry the sdas fix for SDCC bug 4070

The 8051 assembler sign-extends every value to 24 bits, so the top
byte of a __sfr32 address list like 0xa4a5a6a7 comes out as 0xff.
The patch keeps 32-bit arithmetic while leaving the 24-bit T line
addresses alone, so the relocations are unchanged. Proposed upstream
in the bug thread. With it SFR_DATA_U32 can be used again, which
saves about 240 bytes of code in REG_SET.
This commit is contained in:
d00f committed 2026-10-24 21:59:37 +02:00
1 parent 0181276ec6
commit 9cc859ad30
2 files changed
+133 -1

No files matched your search

+3 -1
View File
@@ -65,7 +65,9 @@ The first `make` downloads SDCC 4.6.0, applies the fixes in `sdcc/` and builds i
`toolchain/`, which takes a few minutes. Later builds reuse it. The released SDCC 4.5.0
and 4.6.0 miscompile parts of this code, see [SDCC bug #4153](https://sourceforge.net/p/sdcc/bugs/4153/)
and [#4154](https://sourceforge.net/p/sdcc/bugs/4154/); both fixes are in SDCC trunk since
r17039. To use an SDCC you installed yourself instead, run `make CC=sdcc ...`.
r17039. The third patch is for [#4070](https://sourceforge.net/p/sdcc/bugs/4070/), where the
assembler drops the top byte of a `__sfr32` address list; it is proposed upstream and lets
`SFR_DATA_U32` be used again. To use an SDCC you installed yourself instead, run `make CC=sdcc ...`.
<details>
<summary>If using Docker (click to expand)</summary>
+130
View File
@@ -0,0 +1,130 @@
https://sourceforge.net/p/sdcc/bugs/4070/
Index: sdas/asxxsrc/asexpr.c
===================================================================
--- sdas/asxxsrc/asexpr.c
+++ sdas/asxxsrc/asexpr.c
@@ -863,18 +863,59 @@
return((n & s_mask) ? (n | ~v_mask) : (n & v_mask));
}
-/*)Function void exprmasks(esp)
+/*)Function void exprmasks(n)
*
* int n T Line Bytes in Address
*
* The function exprmasks() configures the assembler
- * for 16, 24, or 32-Bit Data/Addresses.
+ * for 16, 24, or 32-Bit Data/Addresses. The arithmetic
+ * precision follows the address width unless a port
+ * calls valmasks() afterwards.
*
* local variables:
* none
*
* global variables:
* int a_bytes T Line Bytes in Address
+ *
+ * functions called:
+ * void valmasks() asexpr.c
+ *
+ * side effects:
+ * The address width and arithmetic precision
+ * parameters are set.
+ */
+
+void
+exprmasks(int n)
+{
+ switch(n) {
+ default:
+ n = 2;
+ case 2:
+ case 3:
+ case 4:
+ break;
+ }
+ a_bytes = n;
+ valmasks(n);
+}
+
+/*)Function void valmasks(n)
+ *
+ * int n Bytes of arithmetic precision
+ *
+ * The function valmasks() configures the 16, 24, or
+ * 32-Bit arithmetic precision independently of the
+ * T Line address width. A port whose addresses fit
+ * in 24 bits but whose symbols may hold 32-bit values
+ * (the 8051 __sfr32 address lists, for example) uses
+ * exprmasks(3) followed by valmasks(4).
+ *
+ * local variables:
+ * none
+ *
+ * global variables:
* a_uint a_mask Address mask
* a_uint s_mask Sign mask
* a_uint v_mask Value mask
@@ -885,16 +926,13 @@
* side effects:
* The arithmetic precision parameters are set.
*/
-
+
void
-exprmasks(int n)
+valmasks(int n)
{
- a_bytes = n;
-
#ifdef LONGINT
- switch(a_bytes) {
+ switch(n) {
default:
- a_bytes = 2;
case 2:
a_mask = (a_uint) 0x0000FFFFl;
s_mask = (a_uint) 0x00008000l;
@@ -914,9 +952,8 @@
break;
}
#else
- switch(a_bytes) {
+ switch(n) {
default:
- a_bytes = 2;
case 2:
a_mask = (a_uint) 0x0000FFFF;
s_mask = (a_uint) 0x00008000;
Index: sdas/asxxsrc/asxxxx.h
===================================================================
--- sdas/asxxsrc/asxxxx.h
+++ sdas/asxxsrc/asxxxx.h
@@ -1354,6 +1354,7 @@
extern int digit(int c, int r);
extern int is_digit(int c, int r);
extern void exprmasks(int n);
+extern void valmasks(int n);
extern void expr(struct expr *esp, int n);
extern void binop(int c, struct expr *esp, struct expr *re);
extern int is_abs(struct expr *esp);
Index: sdas/as8051/i51mch.c
===================================================================
--- sdas/as8051/i51mch.c
+++ sdas/as8051/i51mch.c
@@ -782,9 +782,12 @@
hilo = 1;
/*
- * Address Space
+ * Address Space: 24-bit addresses in the T lines,
+ * 32-bit arithmetic so that __sfr32 address lists
+ * like 0xa4a5a6a7 keep their most significant byte.
*/
- exprmasks(3);
+ exprmasks(3);
+ valmasks(4);
/*
* First time only: