Move UNION code inside section.c

Improves organization and locality
This commit is contained in:
ISSOtm
2020-09-06 19:18:10 +02:00
parent 12b7cf3cd4
commit 14be01880d
5 changed files with 67 additions and 64 deletions

View File

@@ -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;

View File

@@ -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);

View File

@@ -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); }

View File

@@ -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;

View File

@@ -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--)