Support 32-bit addresses ("XL4") as of SDCC 4.4.0

This commit is contained in:
Rangi42
2025-08-20 09:15:26 -04:00
parent e0e9ef190a
commit 92ed6ece53
3 changed files with 32 additions and 27 deletions

View File

@@ -181,9 +181,9 @@ void sdobj_ReadFile(FileStackNode const &src, FILE *file, std::vector<Symbol> &f
} while (0) } while (0)
int lineType = nextLine(line, where, file); int lineType = nextLine(line, where, file);
NumberType numberType;
// The first letter (thus, the line type) identifies the integer type // The first letter (thus, the line type) identifies the integer type
NumberType numberType;
switch (lineType) { switch (lineType) {
case EOF: case EOF:
fatalAt(where, "SDCC object only contains comments and empty lines"); fatalAt(where, "SDCC object only contains comments and empty lines");
@@ -213,10 +213,15 @@ void sdobj_ReadFile(FileStackNode const &src, FILE *file, std::vector<Symbol> &f
fatalAt(where, "Unknown endianness type '%c'", line[0]); fatalAt(where, "Unknown endianness type '%c'", line[0]);
} }
// TODO: support 32-bit addresses ("XL4") as of SDCC 4.4.0 uint8_t addrSize;
static constexpr uint8_t ADDR_SIZE = 3; switch (line[1]) {
case '3':
if (line[1] != '0' + ADDR_SIZE) { addrSize = 3;
break;
case '4':
addrSize = 4;
break;
default:
fatalAt(where, "Unknown or unsupported address size '%c'", line[1]); fatalAt(where, "Unknown or unsupported address size '%c'", line[1]);
} }
@@ -264,7 +269,7 @@ void sdobj_ReadFile(FileStackNode const &src, FILE *file, std::vector<Symbol> &f
switch (lineType) { switch (lineType) {
case 'M': // Module name case 'M': // Module name
case 'O': // Assembler flags case 'O': // Assembler flags
// Ignored // TODO: check the calling convention metadata as of SDCC 4.5.0
break; break;
case 'A': { case 'A': {
@@ -462,7 +467,7 @@ void sdobj_ReadFile(FileStackNode const &src, FILE *file, std::vector<Symbol> &f
data.push_back(parseByte(where, token, numberType)); data.push_back(parseByte(where, token, numberType));
} }
if (data.size() < ADDR_SIZE) { if (data.size() < addrSize) {
fatalAt(where, "'T' line is too short"); fatalAt(where, "'T' line is too short");
} }
// Importantly, now we know that there is "pending data" in `data` // Importantly, now we know that there is "pending data" in `data`
@@ -495,7 +500,7 @@ void sdobj_ReadFile(FileStackNode const &src, FILE *file, std::vector<Symbol> &f
assume(!fileSections.empty()); // There should be at least one, from the above check assume(!fileSections.empty()); // There should be at least one, from the above check
Section *section = fileSections[areaIdx].section.get(); Section *section = fileSections[areaIdx].section.get();
uint16_t *writeIndex = &fileSections[areaIdx].writeIndex; uint16_t *writeIndex = &fileSections[areaIdx].writeIndex;
uint8_t writtenOfs = ADDR_SIZE; // Bytes before this have been written to `->data` uint8_t writtenOfs = addrSize; // Bytes before this have been written to `->data`
uint16_t addr = data[0] | data[1] << 8; uint16_t addr = data[0] | data[1] << 8;
if (section->isAddressFixed) { if (section->isAddressFixed) {
@@ -513,7 +518,7 @@ void sdobj_ReadFile(FileStackNode const &src, FILE *file, std::vector<Symbol> &f
} }
// Lines are emitted that violate this check but contain no "payload"; // Lines are emitted that violate this check but contain no "payload";
// ignore those. "Empty" lines shouldn't trigger allocation, either. // ignore those. "Empty" lines shouldn't trigger allocation, either.
if (data.size() != ADDR_SIZE) { if (data.size() != addrSize) {
if (addr != *writeIndex) { if (addr != *writeIndex) {
fatalAt( fatalAt(
where, where,
@@ -554,12 +559,12 @@ void sdobj_ReadFile(FileStackNode const &src, FILE *file, std::vector<Symbol> &f
getToken(nullptr, "Incomplete relocation"); getToken(nullptr, "Incomplete relocation");
uint8_t offset = parseByte(where, token, numberType); uint8_t offset = parseByte(where, token, numberType);
if (offset < ADDR_SIZE) { if (offset < addrSize) {
fatalAt( fatalAt(
where, where,
"Relocation index cannot point to header (%" PRIu16 " < %u)", "Relocation index cannot point to header (%" PRIu16 " < %u)",
offset, offset,
ADDR_SIZE addrSize
); );
} }
if (offset >= data.size()) { if (offset >= data.size()) {
@@ -607,7 +612,7 @@ void sdobj_ReadFile(FileStackNode const &src, FILE *file, std::vector<Symbol> &f
patch.pcOffset = patch.offset - 1; // For `jr`s patch.pcOffset = patch.offset - 1; // For `jr`s
patch.type = (flags & 1 << RELOC_SIZE) ? PATCHTYPE_BYTE : PATCHTYPE_WORD; patch.type = (flags & 1 << RELOC_SIZE) ? PATCHTYPE_BYTE : PATCHTYPE_WORD;
uint8_t nbBaseBytes = patch.type == PATCHTYPE_BYTE ? ADDR_SIZE : 2; uint8_t nbBaseBytes = patch.type == PATCHTYPE_BYTE ? addrSize : 2;
uint32_t baseValue = 0; uint32_t baseValue = 0;
assume(offset < data.size()); assume(offset < data.size());

View File

@@ -1,11 +1,11 @@
XL3 XL4
H 9 areas 3 global symbols H 9 areas 3 global symbols
M b M b
O -msm83 O -msm83 sdcccall(1)
S .__.ABS. Def000000 S .__.ABS. Def00000000
A _CODE size 7 flags 0 addr 0 A _CODE size 7 flags 0 addr 0
S _sm83 Def000005 S _sm83 Def00000005
S _function0 Def000000 S _function0 Def00000000
A _DATA size 0 flags 0 addr 0 A _DATA size 0 flags 0 addr 0
A _INITIALIZED size 0 flags 0 addr 0 A _INITIALIZED size 0 flags 0 addr 0
A _DABS size 0 flags 8 addr 0 A _DABS size 0 flags 8 addr 0
@@ -14,11 +14,11 @@ A _GSINIT size 0 flags 0 addr 0
A _GSFINAL size 0 flags 0 addr 0 A _GSFINAL size 0 flags 0 addr 0
A _INITIALIZER size 0 flags 0 addr 0 A _INITIALIZER size 0 flags 0 addr 0
A _CABS size 0 flags 8 addr 0 A _CABS size 0 flags 8 addr 0
T 00 00 00 T 00 00 00 00
R 00 00 00 00 R 00 00 00 00
T 00 00 00 4B 42 CB C1 C9 T 00 00 00 00 4B 42 CB C1 C9
R 00 00 00 00 R 00 00 00 00
T 05 00 00 T 05 00 00 00
R 00 00 00 00 R 00 00 00 00
T 05 00 00 01 00 T 05 00 00 00 01 00
R 00 00 00 00 R 00 00 00 00

View File

@@ -1,10 +1,10 @@
XL3 XL4
H 9 areas 2 global symbols H 9 areas 2 global symbols
M c M c
O -msm83 O -msm83 sdcccall(1)
S .__.ABS. Def000000 S .__.ABS. Def00000000
A _CODE size 5 flags 0 addr 0 A _CODE size 5 flags 0 addr 0
S _function1 Def000000 S _function1 Def00000000
A _DATA size 0 flags 0 addr 0 A _DATA size 0 flags 0 addr 0
A _INITIALIZED size 0 flags 0 addr 0 A _INITIALIZED size 0 flags 0 addr 0
A _DABS size 0 flags 8 addr 0 A _DABS size 0 flags 8 addr 0
@@ -13,7 +13,7 @@ A _GSINIT size 0 flags 0 addr 0
A _GSFINAL size 0 flags 0 addr 0 A _GSFINAL size 0 flags 0 addr 0
A _INITIALIZER size 0 flags 0 addr 0 A _INITIALIZER size 0 flags 0 addr 0
A _CABS size 0 flags 8 addr 0 A _CABS size 0 flags 8 addr 0
T 00 00 00 T 00 00 00 00
R 00 00 00 00 R 00 00 00 00
T 00 00 00 4B 42 CB C9 C9 T 00 00 00 00 4B 42 CB C9 C9
R 00 00 00 00 R 00 00 00 00