ref: 14be01880d1df164268952285f54aa2b206f93ba
parent: 12b7cf3cd44a2e953ad58050c9565ad5c7ea544a
author: ISSOtm <eldredhabert0@gmail.com>
date: Sun Sep 6 15:18:10 EDT 2020
Move UNION code inside section.c Improves organization and locality
--- a/include/asm/asm.h
+++ b/include/asm/asm.h
@@ -21,7 +21,6 @@
#include "asm/localasm.h"
#include "asm/symbol.h"
-#define MAXUNIONS 128
#define MAXMACROARGS 99999
#define MAXINCPATHS 128
@@ -29,9 +28,6 @@
extern uint32_t nTotalLines;
extern uint32_t nIFDepth;
extern bool skipElif;
-extern uint32_t nUnionDepth;
-extern uint32_t unionStart[MAXUNIONS];
-extern uint32_t unionSize[MAXUNIONS];
extern char tzCurrentFileName[_MAX_PATH + 1];
extern struct Section *pCurrentSection;
extern bool oDontExpandStrings;
--- a/include/asm/section.h
+++ b/include/asm/section.h
@@ -46,9 +46,13 @@
struct Section *sect_GetSymbolSection(void);
uint32_t sect_GetSymbolOffset(void);
-void sect_SetSymbolOffset(uint32_t ofs);
uint32_t sect_GetOutputOffset(void);
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_AbsByteGroup(uint8_t const *s, int32_t length);
--- a/src/asm/asmy.y
+++ b/src/asm/asmy.y
@@ -383,32 +383,6 @@
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)
{size_t len = 0;
@@ -975,26 +949,13 @@
}
;
-union : T_POP_UNION { startUnion(); }+union : T_POP_UNION { sect_StartUnion(); };
-nextu : T_POP_NEXTU {- if (nUnionDepth <= 0)
- fatalerror("Found NEXTU outside of a UNION construct");-
- updateUnion();
- }
+nextu : T_POP_NEXTU { sect_NextUnionMember(); };
-endu : T_POP_ENDU {- if (nUnionDepth <= 0)
- fatalerror("Found ENDU outside of a UNION construct");-
- updateUnion();
-
- nUnionDepth--;
- sect_SetSymbolOffset(unionStart[nUnionDepth] + unionSize[nUnionDepth]);
- }
+endu : T_POP_ENDU { sect_EndUnion(); };
ds : T_POP_DS uconst { out_Skip($2, true); }--- a/src/asm/main.c
+++ b/src/asm/main.c
@@ -40,7 +40,7 @@
char **cldefines;
clock_t nStartClock, nEndClock;
-uint32_t nTotalLines, nIFDepth, nUnionDepth;
+uint32_t nTotalLines, nIFDepth;
bool skipElif;
uint32_t unionStart[128], unionSize[128];
@@ -534,7 +534,6 @@
nTotalLines = 0;
nIFDepth = 0;
skipElif = true;
- nUnionDepth = 0;
sym_Init();
sym_SetExportAll(exportall);
fstk_Init(tzMainfile);
@@ -553,10 +552,7 @@
errx(1, "Unterminated IF construct (%" PRIu32 " levels)!",
nIFDepth);
- if (nUnionDepth != 0) {- errx(1, "Unterminated UNION construct (%" PRIu32 " levels)!",
- nUnionDepth);
- }
+ sect_CheckUnionClosed();
double timespent;
--- a/src/asm/section.c
+++ b/src/asm/section.c
@@ -28,6 +28,12 @@
static struct Section *currentLoadSection = NULL;
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
*/
@@ -48,8 +54,6 @@
if (!sect_HasData(pCurrentSection->nType))
fatalerror("Section '%s' cannot contain code or data (not ROM0 or ROMX)",pCurrentSection->pzName);
- else if (nUnionDepth > 0)
- fatalerror("UNIONs cannot contain code or data");}
static inline void checkSectionSize(struct Section const *sect, uint32_t size)
@@ -302,7 +306,7 @@
*/
static void changeSection(void)
{- if (nUnionDepth > 0)
+ if (unionStack)
fatalerror("Cannot change the section within a UNION");sym_SetCurrentSymbolScope(NULL);
@@ -367,11 +371,6 @@
return curOffset;
}
-void sect_SetSymbolOffset(uint32_t ofs)
-{- curOffset = ofs;
-}
-
uint32_t sect_GetOutputOffset(void)
{return curOffset + loadOffset;
@@ -436,6 +435,56 @@
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
*/
@@ -469,9 +518,6 @@
if (!sect_HasData(pCurrentSection->nType)) {growSection(skip);
- } else if (nUnionDepth > 0) {- while (skip--)
- writebyte(CurrentOptions.fillchar);
} else {checkcodesection();
while (skip--)
--
⑨