mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Move UNION code inside section.c
Improves organization and locality
This commit is contained in:
@@ -21,7 +21,6 @@
|
|||||||
#include "asm/localasm.h"
|
#include "asm/localasm.h"
|
||||||
#include "asm/symbol.h"
|
#include "asm/symbol.h"
|
||||||
|
|
||||||
#define MAXUNIONS 128
|
|
||||||
#define MAXMACROARGS 99999
|
#define MAXMACROARGS 99999
|
||||||
#define MAXINCPATHS 128
|
#define MAXINCPATHS 128
|
||||||
|
|
||||||
@@ -29,9 +28,6 @@ extern int32_t nLineNo;
|
|||||||
extern uint32_t nTotalLines;
|
extern uint32_t nTotalLines;
|
||||||
extern uint32_t nIFDepth;
|
extern uint32_t nIFDepth;
|
||||||
extern bool skipElif;
|
extern bool skipElif;
|
||||||
extern uint32_t nUnionDepth;
|
|
||||||
extern uint32_t unionStart[MAXUNIONS];
|
|
||||||
extern uint32_t unionSize[MAXUNIONS];
|
|
||||||
extern char tzCurrentFileName[_MAX_PATH + 1];
|
extern char tzCurrentFileName[_MAX_PATH + 1];
|
||||||
extern struct Section *pCurrentSection;
|
extern struct Section *pCurrentSection;
|
||||||
extern bool oDontExpandStrings;
|
extern bool oDontExpandStrings;
|
||||||
|
|||||||
@@ -46,10 +46,14 @@ void out_EndLoadSection(void);
|
|||||||
|
|
||||||
struct Section *sect_GetSymbolSection(void);
|
struct Section *sect_GetSymbolSection(void);
|
||||||
uint32_t sect_GetSymbolOffset(void);
|
uint32_t sect_GetSymbolOffset(void);
|
||||||
void sect_SetSymbolOffset(uint32_t ofs);
|
|
||||||
uint32_t sect_GetOutputOffset(void);
|
uint32_t sect_GetOutputOffset(void);
|
||||||
void sect_AlignPC(uint8_t alignment, uint16_t offset);
|
void sect_AlignPC(uint8_t alignment, uint16_t offset);
|
||||||
|
|
||||||
|
void sect_StartUnion(void);
|
||||||
|
void sect_NextUnionMember(void);
|
||||||
|
void sect_EndUnion(void);
|
||||||
|
void sect_CheckUnionClosed(void);
|
||||||
|
|
||||||
void out_AbsByte(uint8_t b);
|
void out_AbsByte(uint8_t b);
|
||||||
void out_AbsByteGroup(uint8_t const *s, int32_t length);
|
void out_AbsByteGroup(uint8_t const *s, int32_t length);
|
||||||
void out_Skip(int32_t skip, bool ds);
|
void out_Skip(int32_t skip, bool ds);
|
||||||
|
|||||||
@@ -383,32 +383,6 @@ static void if_skip_to_endc(void)
|
|||||||
nLineNo--;
|
nLineNo--;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void startUnion(void)
|
|
||||||
{
|
|
||||||
if (!pCurrentSection)
|
|
||||||
fatalerror("UNIONs must be inside a SECTION");
|
|
||||||
|
|
||||||
uint32_t unionIndex = nUnionDepth;
|
|
||||||
|
|
||||||
nUnionDepth++;
|
|
||||||
if (nUnionDepth > MAXUNIONS)
|
|
||||||
fatalerror("Too many nested UNIONs");
|
|
||||||
|
|
||||||
unionStart[unionIndex] = sect_GetOutputOffset();
|
|
||||||
unionSize[unionIndex] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void updateUnion(void)
|
|
||||||
{
|
|
||||||
uint32_t unionIndex = nUnionDepth - 1;
|
|
||||||
uint32_t size = sect_GetOutputOffset() - unionStart[unionIndex];
|
|
||||||
|
|
||||||
if (size > unionSize[unionIndex])
|
|
||||||
unionSize[unionIndex] = size;
|
|
||||||
|
|
||||||
sect_SetSymbolOffset(unionStart[unionIndex]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t strlenUTF8(const char *s)
|
static size_t strlenUTF8(const char *s)
|
||||||
{
|
{
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
@@ -975,26 +949,13 @@ rb : T_LABEL T_POP_RB uconst {
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
union : T_POP_UNION { startUnion(); }
|
union : T_POP_UNION { sect_StartUnion(); }
|
||||||
;
|
;
|
||||||
|
|
||||||
nextu : T_POP_NEXTU {
|
nextu : T_POP_NEXTU { sect_NextUnionMember(); }
|
||||||
if (nUnionDepth <= 0)
|
|
||||||
fatalerror("Found NEXTU outside of a UNION construct");
|
|
||||||
|
|
||||||
updateUnion();
|
|
||||||
}
|
|
||||||
;
|
;
|
||||||
|
|
||||||
endu : T_POP_ENDU {
|
endu : T_POP_ENDU { sect_EndUnion(); }
|
||||||
if (nUnionDepth <= 0)
|
|
||||||
fatalerror("Found ENDU outside of a UNION construct");
|
|
||||||
|
|
||||||
updateUnion();
|
|
||||||
|
|
||||||
nUnionDepth--;
|
|
||||||
sect_SetSymbolOffset(unionStart[nUnionDepth] + unionSize[nUnionDepth]);
|
|
||||||
}
|
|
||||||
;
|
;
|
||||||
|
|
||||||
ds : T_POP_DS uconst { out_Skip($2, true); }
|
ds : T_POP_DS uconst { out_Skip($2, true); }
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ const size_t cldefine_entrysize = 2 * sizeof(void *);
|
|||||||
char **cldefines;
|
char **cldefines;
|
||||||
|
|
||||||
clock_t nStartClock, nEndClock;
|
clock_t nStartClock, nEndClock;
|
||||||
uint32_t nTotalLines, nIFDepth, nUnionDepth;
|
uint32_t nTotalLines, nIFDepth;
|
||||||
bool skipElif;
|
bool skipElif;
|
||||||
uint32_t unionStart[128], unionSize[128];
|
uint32_t unionStart[128], unionSize[128];
|
||||||
|
|
||||||
@@ -534,7 +534,6 @@ int main(int argc, char *argv[])
|
|||||||
nTotalLines = 0;
|
nTotalLines = 0;
|
||||||
nIFDepth = 0;
|
nIFDepth = 0;
|
||||||
skipElif = true;
|
skipElif = true;
|
||||||
nUnionDepth = 0;
|
|
||||||
sym_Init();
|
sym_Init();
|
||||||
sym_SetExportAll(exportall);
|
sym_SetExportAll(exportall);
|
||||||
fstk_Init(tzMainfile);
|
fstk_Init(tzMainfile);
|
||||||
@@ -553,10 +552,7 @@ int main(int argc, char *argv[])
|
|||||||
errx(1, "Unterminated IF construct (%" PRIu32 " levels)!",
|
errx(1, "Unterminated IF construct (%" PRIu32 " levels)!",
|
||||||
nIFDepth);
|
nIFDepth);
|
||||||
|
|
||||||
if (nUnionDepth != 0) {
|
sect_CheckUnionClosed();
|
||||||
errx(1, "Unterminated UNION construct (%" PRIu32 " levels)!",
|
|
||||||
nUnionDepth);
|
|
||||||
}
|
|
||||||
|
|
||||||
double timespent;
|
double timespent;
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,12 @@ uint32_t curOffset; /* Offset into the current section (see sect_GetSymbolOffset
|
|||||||
static struct Section *currentLoadSection = NULL;
|
static struct Section *currentLoadSection = NULL;
|
||||||
uint32_t loadOffset; /* The offset of the LOAD section within its parent */
|
uint32_t loadOffset; /* The offset of the LOAD section within its parent */
|
||||||
|
|
||||||
|
struct UnionStackEntry {
|
||||||
|
uint32_t start;
|
||||||
|
uint32_t size;
|
||||||
|
struct UnionStackEntry *next;
|
||||||
|
} *unionStack = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A quick check to see if we have an initialized section
|
* A quick check to see if we have an initialized section
|
||||||
*/
|
*/
|
||||||
@@ -48,8 +54,6 @@ static inline void checkcodesection(void)
|
|||||||
if (!sect_HasData(pCurrentSection->nType))
|
if (!sect_HasData(pCurrentSection->nType))
|
||||||
fatalerror("Section '%s' cannot contain code or data (not ROM0 or ROMX)",
|
fatalerror("Section '%s' cannot contain code or data (not ROM0 or ROMX)",
|
||||||
pCurrentSection->pzName);
|
pCurrentSection->pzName);
|
||||||
else if (nUnionDepth > 0)
|
|
||||||
fatalerror("UNIONs cannot contain code or data");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void checkSectionSize(struct Section const *sect, uint32_t size)
|
static inline void checkSectionSize(struct Section const *sect, uint32_t size)
|
||||||
@@ -302,7 +306,7 @@ static struct Section *getSection(char const *pzName, enum SectionType type,
|
|||||||
*/
|
*/
|
||||||
static void changeSection(void)
|
static void changeSection(void)
|
||||||
{
|
{
|
||||||
if (nUnionDepth > 0)
|
if (unionStack)
|
||||||
fatalerror("Cannot change the section within a UNION");
|
fatalerror("Cannot change the section within a UNION");
|
||||||
|
|
||||||
sym_SetCurrentSymbolScope(NULL);
|
sym_SetCurrentSymbolScope(NULL);
|
||||||
@@ -367,11 +371,6 @@ uint32_t sect_GetSymbolOffset(void)
|
|||||||
return curOffset;
|
return curOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sect_SetSymbolOffset(uint32_t ofs)
|
|
||||||
{
|
|
||||||
curOffset = ofs;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t sect_GetOutputOffset(void)
|
uint32_t sect_GetOutputOffset(void)
|
||||||
{
|
{
|
||||||
return curOffset + loadOffset;
|
return curOffset + loadOffset;
|
||||||
@@ -436,6 +435,56 @@ static inline void createPatch(enum PatchType type,
|
|||||||
out_CreatePatch(type, expr, sect_GetOutputOffset());
|
out_CreatePatch(type, expr, sect_GetOutputOffset());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sect_StartUnion(void)
|
||||||
|
{
|
||||||
|
if (!pCurrentSection)
|
||||||
|
fatalerror("UNIONs must be inside a SECTION");
|
||||||
|
if (sect_HasData(pCurrentSection->nType))
|
||||||
|
fatalerror("Cannot use UNION inside of ROM0 or ROMX sections");
|
||||||
|
struct UnionStackEntry *entry = malloc(sizeof(*entry));
|
||||||
|
|
||||||
|
if (!entry)
|
||||||
|
fatalerror("Failed to allocate new union stack entry: %s", strerror(errno));
|
||||||
|
entry->start = curOffset;
|
||||||
|
entry->size = 0;
|
||||||
|
entry->next = unionStack;
|
||||||
|
unionStack = entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void endUnionMember(void)
|
||||||
|
{
|
||||||
|
uint32_t memberSize = curOffset - unionStack->start;
|
||||||
|
|
||||||
|
if (memberSize > unionStack->size)
|
||||||
|
unionStack->size = memberSize;
|
||||||
|
curOffset = unionStack->start;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sect_NextUnionMember(void)
|
||||||
|
{
|
||||||
|
if (!unionStack)
|
||||||
|
fatalerror("Found NEXTU outside of a UNION construct");
|
||||||
|
endUnionMember();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sect_EndUnion(void)
|
||||||
|
{
|
||||||
|
if (!unionStack)
|
||||||
|
fatalerror("Found ENDU outside of a UNION construct");
|
||||||
|
endUnionMember();
|
||||||
|
curOffset += unionStack->size;
|
||||||
|
struct UnionStackEntry *next = unionStack->next;
|
||||||
|
|
||||||
|
free(unionStack);
|
||||||
|
unionStack = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sect_CheckUnionClosed(void)
|
||||||
|
{
|
||||||
|
if (unionStack)
|
||||||
|
fatalerror("Unterminated UNION construct!");
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Output an absolute byte
|
* Output an absolute byte
|
||||||
*/
|
*/
|
||||||
@@ -469,9 +518,6 @@ void out_Skip(int32_t skip, bool ds)
|
|||||||
|
|
||||||
if (!sect_HasData(pCurrentSection->nType)) {
|
if (!sect_HasData(pCurrentSection->nType)) {
|
||||||
growSection(skip);
|
growSection(skip);
|
||||||
} else if (nUnionDepth > 0) {
|
|
||||||
while (skip--)
|
|
||||||
writebyte(CurrentOptions.fillchar);
|
|
||||||
} else {
|
} else {
|
||||||
checkcodesection();
|
checkcodesection();
|
||||||
while (skip--)
|
while (skip--)
|
||||||
|
|||||||
Reference in New Issue
Block a user