mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 10:12:06 +00:00
Get rid of Hungarian notation for good
Bye bye it was not nice knowing ya
This commit is contained in:
@@ -49,7 +49,7 @@ struct FileStackNamedNode { /* NODE_FILE, NODE_MACRO */
|
||||
char name[]; /* File name for files, file::macro name for macros */
|
||||
};
|
||||
|
||||
extern size_t nMaxRecursionDepth;
|
||||
extern size_t maxRecursionDepth;
|
||||
|
||||
struct MacroArgs;
|
||||
|
||||
@@ -72,12 +72,12 @@ bool fstk_FindFile(char const *path, char **fullPath, size_t *size);
|
||||
bool yywrap(void);
|
||||
void fstk_RunInclude(char const *path);
|
||||
void fstk_RunMacro(char const *macroName, struct MacroArgs *args);
|
||||
void fstk_RunRept(uint32_t count, int32_t nReptLineNo, char *body, size_t size);
|
||||
void fstk_RunRept(uint32_t count, int32_t reptLineNo, char *body, size_t size);
|
||||
void fstk_RunFor(char const *symName, int32_t start, int32_t stop, int32_t step,
|
||||
int32_t reptLineNo, char *body, size_t size);
|
||||
void fstk_StopRept(void);
|
||||
bool fstk_Break(void);
|
||||
|
||||
void fstk_Init(char const *mainPath, size_t maxRecursionDepth);
|
||||
void fstk_Init(char const *mainPath, size_t maxDepth);
|
||||
|
||||
#endif /* RGBDS_ASM_FSTACK_H */
|
||||
|
||||
@@ -21,10 +21,10 @@ extern bool verbose;
|
||||
extern bool warnings; /* True to enable warnings, false to disable them. */
|
||||
|
||||
extern FILE *dependfile;
|
||||
extern char *tzTargetFileName;
|
||||
extern bool oGeneratedMissingIncludes;
|
||||
extern bool oFailedOnMissingInclude;
|
||||
extern bool oGeneratePhonyDeps;
|
||||
extern char *targetFileName;
|
||||
extern bool generatedMissingIncludes;
|
||||
extern bool failedOnMissingInclude;
|
||||
extern bool generatePhonyDeps;
|
||||
|
||||
/* TODO: are these really needed? */
|
||||
#define YY_FATAL_ERROR fatalerror
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
struct Expression;
|
||||
struct FileStackNode;
|
||||
|
||||
extern char *tzObjectname;
|
||||
extern struct Section *pSectionList, *pCurrentSection;
|
||||
extern char *objectName;
|
||||
extern struct Section *sectionList, *currentSection;
|
||||
|
||||
void out_RegisterNode(struct FileStackNode *node);
|
||||
void out_ReplaceNode(struct FileStackNode *node);
|
||||
|
||||
@@ -17,14 +17,14 @@
|
||||
#define MAXRPNLEN 1048576
|
||||
|
||||
struct Expression {
|
||||
int32_t nVal; // If the expression's value is known, it's here
|
||||
int32_t val; // If the expression's value is known, it's here
|
||||
char *reason; // Why the expression is not known, if it isn't
|
||||
bool isKnown; // Whether the expression's value is known
|
||||
bool isSymbol; // Whether the expression represents a symbol
|
||||
uint8_t *tRPN; // Array of bytes serializing the RPN expression
|
||||
uint32_t nRPNCapacity; // Size of the `tRPN` buffer
|
||||
uint32_t nRPNLength; // Used size of the `tRPN` buffer
|
||||
uint32_t nRPNPatchSize; // Size the expression will take in the obj file
|
||||
uint8_t *rpn; // Array of bytes serializing the RPN expression
|
||||
uint32_t rpnCapacity; // Size of the `tRPN` buffer
|
||||
uint32_t rpnLength; // Used size of the `tRPN` buffer
|
||||
uint32_t rpnPatchSize; // Size the expression will take in the obj file
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -43,11 +43,11 @@ static inline bool rpn_isSymbol(const struct Expression *expr)
|
||||
return expr->isSymbol;
|
||||
}
|
||||
|
||||
void rpn_Symbol(struct Expression *expr, char const *tzSym);
|
||||
void rpn_Symbol(struct Expression *expr, char const *symName);
|
||||
void rpn_Number(struct Expression *expr, uint32_t i);
|
||||
void rpn_LOGNOT(struct Expression *expr, const struct Expression *src);
|
||||
struct Symbol const *rpn_SymbolOf(struct Expression const *expr);
|
||||
bool rpn_IsDiffConstant(struct Expression const *src, struct Symbol const *sym);
|
||||
bool rpn_IsDiffConstant(struct Expression const *src, struct Symbol const *symName);
|
||||
void rpn_BinaryOp(enum RPNCommand op, struct Expression *expr,
|
||||
const struct Expression *src1,
|
||||
const struct Expression *src2);
|
||||
@@ -56,11 +56,11 @@ void rpn_LOW(struct Expression *expr, const struct Expression *src);
|
||||
void rpn_ISCONST(struct Expression *expr, const struct Expression *src);
|
||||
void rpn_UNNEG(struct Expression *expr, const struct Expression *src);
|
||||
void rpn_UNNOT(struct Expression *expr, const struct Expression *src);
|
||||
void rpn_BankSymbol(struct Expression *expr, char const *tzSym);
|
||||
void rpn_BankSection(struct Expression *expr, char const *tzSectionName);
|
||||
void rpn_BankSymbol(struct Expression *expr, char const *symName);
|
||||
void rpn_BankSection(struct Expression *expr, char const *sectionName);
|
||||
void rpn_BankSelf(struct Expression *expr);
|
||||
void rpn_SizeOfSection(struct Expression *expr, char const *tzSectionName);
|
||||
void rpn_StartOfSection(struct Expression *expr, char const *tzSectionName);
|
||||
void rpn_SizeOfSection(struct Expression *expr, char const *sectionName);
|
||||
void rpn_StartOfSection(struct Expression *expr, char const *sectionName);
|
||||
void rpn_Free(struct Expression *expr);
|
||||
void rpn_CheckHRAM(struct Expression *expr, const struct Expression *src);
|
||||
void rpn_CheckRST(struct Expression *expr, const struct Expression *src);
|
||||
|
||||
@@ -44,7 +44,7 @@ struct Context {
|
||||
static struct Context *contextStack;
|
||||
static size_t contextDepth = 0;
|
||||
#define DEFAULT_MAX_DEPTH 64
|
||||
size_t nMaxRecursionDepth;
|
||||
size_t maxRecursionDepth;
|
||||
|
||||
static unsigned int nbIncPaths = 0;
|
||||
static char const *includePaths[MAXINCPATHS];
|
||||
@@ -143,8 +143,8 @@ void fstk_AddIncludePath(char const *path)
|
||||
static void printDep(char const *path)
|
||||
{
|
||||
if (dependfile) {
|
||||
fprintf(dependfile, "%s: %s\n", tzTargetFileName, path);
|
||||
if (oGeneratePhonyDeps)
|
||||
fprintf(dependfile, "%s: %s\n", targetFileName, path);
|
||||
if (generatePhonyDeps)
|
||||
fprintf(dependfile, "%s:\n", path);
|
||||
}
|
||||
}
|
||||
@@ -206,18 +206,18 @@ bool fstk_FindFile(char const *path, char **fullPath, size_t *size)
|
||||
}
|
||||
|
||||
errno = ENOENT;
|
||||
if (oGeneratedMissingIncludes)
|
||||
if (generatedMissingIncludes)
|
||||
printDep(path);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool yywrap(void)
|
||||
{
|
||||
uint32_t nIFDepth = lexer_GetIFDepth();
|
||||
uint32_t ifDepth = lexer_GetIFDepth();
|
||||
|
||||
if (nIFDepth != 0)
|
||||
if (ifDepth != 0)
|
||||
fatalerror("Ended block with %" PRIu32 " unterminated IF construct%s\n",
|
||||
nIFDepth, nIFDepth == 1 ? "" : "s");
|
||||
ifDepth, ifDepth == 1 ? "" : "s");
|
||||
|
||||
if (contextStack->fileInfo->type == NODE_REPT) { /* The context is a REPT block, which may loop */
|
||||
struct FileStackReptNode *fileInfo = (struct FileStackReptNode *)contextStack->fileInfo;
|
||||
@@ -293,8 +293,8 @@ bool yywrap(void)
|
||||
*/
|
||||
static void newContext(struct FileStackNode *fileInfo)
|
||||
{
|
||||
if (++contextDepth >= nMaxRecursionDepth)
|
||||
fatalerror("Recursion limit (%zu) exceeded\n", nMaxRecursionDepth);
|
||||
if (++contextDepth >= maxRecursionDepth)
|
||||
fatalerror("Recursion limit (%zu) exceeded\n", maxRecursionDepth);
|
||||
struct Context *context = malloc(sizeof(*context));
|
||||
|
||||
if (!context)
|
||||
@@ -322,11 +322,11 @@ void fstk_RunInclude(char const *path)
|
||||
|
||||
if (!fstk_FindFile(path, &fullPath, &size)) {
|
||||
free(fullPath);
|
||||
if (oGeneratedMissingIncludes) {
|
||||
if (generatedMissingIncludes) {
|
||||
if (verbose)
|
||||
printf("Aborting (-MG) on INCLUDE file '%s' (%s)\n",
|
||||
path, strerror(errno));
|
||||
oFailedOnMissingInclude = true;
|
||||
failedOnMissingInclude = true;
|
||||
} else {
|
||||
error("Unable to open included file '%s': %s\n", path, strerror(errno));
|
||||
}
|
||||
@@ -528,7 +528,7 @@ bool fstk_Break(void)
|
||||
return true;
|
||||
}
|
||||
|
||||
void fstk_Init(char const *mainPath, size_t maxRecursionDepth)
|
||||
void fstk_Init(char const *mainPath, size_t maxDepth)
|
||||
{
|
||||
struct LexerState *state = lexer_OpenFile(mainPath);
|
||||
|
||||
@@ -570,12 +570,12 @@ void fstk_Init(char const *mainPath, size_t maxRecursionDepth)
|
||||
* This assumes that the rept node is larger
|
||||
*/
|
||||
#define DEPTH_LIMIT ((SIZE_MAX - sizeof(struct FileStackReptNode)) / sizeof(uint32_t))
|
||||
if (maxRecursionDepth > DEPTH_LIMIT) {
|
||||
if (maxDepth > DEPTH_LIMIT) {
|
||||
error("Recursion depth may not be higher than %zu, defaulting to "
|
||||
EXPAND_AND_STR(DEFAULT_MAX_DEPTH) "\n", DEPTH_LIMIT);
|
||||
nMaxRecursionDepth = DEFAULT_MAX_DEPTH;
|
||||
maxRecursionDepth = DEFAULT_MAX_DEPTH;
|
||||
} else {
|
||||
nMaxRecursionDepth = maxRecursionDepth;
|
||||
maxRecursionDepth = maxDepth;
|
||||
}
|
||||
/* Make sure that the default of 64 is OK, though */
|
||||
assert(DEPTH_LIMIT >= DEFAULT_MAX_DEPTH);
|
||||
|
||||
116
src/asm/lexer.c
116
src/asm/lexer.c
@@ -687,8 +687,8 @@ static void beginExpansion(char const *str, bool owned, char const *name)
|
||||
unsigned int depth = 0;
|
||||
|
||||
for (struct Expansion *exp = lexerState->expansions; exp; exp = exp->parent) {
|
||||
if (depth++ >= nMaxRecursionDepth)
|
||||
fatalerror("Recursion limit (%zu) exceeded\n", nMaxRecursionDepth);
|
||||
if (depth++ >= maxRecursionDepth)
|
||||
fatalerror("Recursion limit (%zu) exceeded\n", maxRecursionDepth);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1056,7 +1056,7 @@ static void readAnonLabelRef(char c)
|
||||
n++;
|
||||
} while (peek() == c);
|
||||
|
||||
sym_WriteAnonLabelName(yylval.tzSym, n, c == '-');
|
||||
sym_WriteAnonLabelName(yylval.symName, n, c == '-');
|
||||
}
|
||||
|
||||
/* Functions to lex numbers of various radixes */
|
||||
@@ -1077,7 +1077,7 @@ static void readNumber(int radix, int32_t baseValue)
|
||||
value = value * radix + (c - '0');
|
||||
}
|
||||
|
||||
yylval.nConstValue = value;
|
||||
yylval.constValue = value;
|
||||
}
|
||||
|
||||
static void readFractionalPart(void)
|
||||
@@ -1105,15 +1105,15 @@ static void readFractionalPart(void)
|
||||
divisor *= 10;
|
||||
}
|
||||
|
||||
if (yylval.nConstValue > INT16_MAX || yylval.nConstValue < INT16_MIN)
|
||||
if (yylval.constValue > INT16_MAX || yylval.constValue < INT16_MIN)
|
||||
warning(WARNING_LARGE_CONSTANT, "Magnitude of fixed-point constant is too large\n");
|
||||
|
||||
/* Cast to unsigned avoids UB if shifting discards bits */
|
||||
yylval.nConstValue = (uint32_t)yylval.nConstValue << 16;
|
||||
yylval.constValue = (uint32_t)yylval.constValue << 16;
|
||||
/* Cast to unsigned avoids undefined overflow behavior */
|
||||
uint16_t fractional = (uint16_t)round(value * 65536.0 / divisor);
|
||||
|
||||
yylval.nConstValue |= fractional * (yylval.nConstValue >= 0 ? 1 : -1);
|
||||
yylval.constValue |= fractional * (yylval.constValue >= 0 ? 1 : -1);
|
||||
}
|
||||
|
||||
char binDigits[2];
|
||||
@@ -1140,7 +1140,7 @@ static void readBinaryNumber(void)
|
||||
value = value * 2 + bit;
|
||||
}
|
||||
|
||||
yylval.nConstValue = value;
|
||||
yylval.constValue = value;
|
||||
}
|
||||
|
||||
static void readHexNumber(void)
|
||||
@@ -1173,7 +1173,7 @@ static void readHexNumber(void)
|
||||
if (empty)
|
||||
error("Invalid integer constant, no digits after '$'\n");
|
||||
|
||||
yylval.nConstValue = value;
|
||||
yylval.constValue = value;
|
||||
}
|
||||
|
||||
char gfxDigits[4];
|
||||
@@ -1215,7 +1215,7 @@ static void readGfxConstant(void)
|
||||
warning(WARNING_LARGE_CONSTANT,
|
||||
"Graphics constant is too long, only 8 first pixels considered\n");
|
||||
|
||||
yylval.nConstValue = bp1 << 8 | bp0;
|
||||
yylval.constValue = bp1 << 8 | bp0;
|
||||
}
|
||||
|
||||
/* Functions to read identifiers & keywords */
|
||||
@@ -1234,7 +1234,7 @@ static int readIdentifier(char firstChar)
|
||||
{
|
||||
dbgPrint("Reading identifier or keyword\n");
|
||||
/* Lex while checking for a keyword */
|
||||
yylval.tzSym[0] = firstChar;
|
||||
yylval.symName[0] = firstChar;
|
||||
uint16_t nodeID = keywordDict[0].children[dictIndex(firstChar)];
|
||||
int tokenType = firstChar == '.' ? T_LOCAL_ID : T_ID;
|
||||
size_t i = 1;
|
||||
@@ -1243,9 +1243,9 @@ static int readIdentifier(char firstChar)
|
||||
for (int c = peek(); continuesIdentifier(c); i++, c = peek()) {
|
||||
shiftChar();
|
||||
|
||||
if (i < sizeof(yylval.tzSym) - 1) {
|
||||
if (i < sizeof(yylval.symName) - 1) {
|
||||
/* Write the char to the identifier's name */
|
||||
yylval.tzSym[i] = c;
|
||||
yylval.symName[i] = c;
|
||||
|
||||
/* If the char was a dot, mark the identifier as local */
|
||||
if (c == '.')
|
||||
@@ -1257,12 +1257,12 @@ static int readIdentifier(char firstChar)
|
||||
}
|
||||
}
|
||||
|
||||
if (i > sizeof(yylval.tzSym) - 1) {
|
||||
if (i > sizeof(yylval.symName) - 1) {
|
||||
warning(WARNING_LONG_STR, "Symbol name too long, got truncated\n");
|
||||
i = sizeof(yylval.tzSym) - 1;
|
||||
i = sizeof(yylval.symName) - 1;
|
||||
}
|
||||
yylval.tzSym[i] = '\0'; /* Terminate the string */
|
||||
dbgPrint("Ident/keyword = \"%s\"\n", yylval.tzSym);
|
||||
yylval.symName[i] = '\0'; /* Terminate the string */
|
||||
dbgPrint("Ident/keyword = \"%s\"\n", yylval.symName);
|
||||
|
||||
if (keywordDict[nodeID].keyword)
|
||||
return keywordDict[nodeID].keyword->token;
|
||||
@@ -1274,8 +1274,8 @@ static int readIdentifier(char firstChar)
|
||||
|
||||
static char const *readInterpolation(unsigned int depth)
|
||||
{
|
||||
if (depth >= nMaxRecursionDepth)
|
||||
fatalerror("Recursion limit (%zu) exceeded\n", nMaxRecursionDepth);
|
||||
if (depth >= maxRecursionDepth)
|
||||
fatalerror("Recursion limit (%zu) exceeded\n", maxRecursionDepth);
|
||||
|
||||
char symName[MAXSYMLEN + 1];
|
||||
size_t i = 0;
|
||||
@@ -1346,10 +1346,10 @@ static char const *readInterpolation(unsigned int depth)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define append_yylval_tzString(c) do { \
|
||||
#define append_yylval_string(c) do { \
|
||||
char v = (c); /* Evaluate c exactly once in case it has side effects. */ \
|
||||
if (i < sizeof(yylval.tzString)) \
|
||||
yylval.tzString[i++] = v; \
|
||||
if (i < sizeof(yylval.string)) \
|
||||
yylval.string[i++] = v; \
|
||||
} while (0)
|
||||
|
||||
static size_t appendEscapedSubstring(char const *str, size_t i)
|
||||
@@ -1363,23 +1363,23 @@ static size_t appendEscapedSubstring(char const *str, size_t i)
|
||||
case '\\':
|
||||
case '"':
|
||||
case '{':
|
||||
append_yylval_tzString('\\');
|
||||
append_yylval_string('\\');
|
||||
break;
|
||||
case '\n':
|
||||
append_yylval_tzString('\\');
|
||||
append_yylval_string('\\');
|
||||
c = 'n';
|
||||
break;
|
||||
case '\r':
|
||||
append_yylval_tzString('\\');
|
||||
append_yylval_string('\\');
|
||||
c = 'r';
|
||||
break;
|
||||
case '\t':
|
||||
append_yylval_tzString('\\');
|
||||
append_yylval_string('\\');
|
||||
c = 't';
|
||||
break;
|
||||
}
|
||||
|
||||
append_yylval_tzString(c);
|
||||
append_yylval_string(c);
|
||||
}
|
||||
|
||||
return i;
|
||||
@@ -1435,7 +1435,7 @@ static void readString(void)
|
||||
break;
|
||||
shiftChar();
|
||||
if (peek() != '"') {
|
||||
append_yylval_tzString('"');
|
||||
append_yylval_string('"');
|
||||
break;
|
||||
}
|
||||
shiftChar();
|
||||
@@ -1489,7 +1489,7 @@ static void readString(void)
|
||||
char const *str = readMacroArg(c);
|
||||
|
||||
while (*str)
|
||||
append_yylval_tzString(*str++);
|
||||
append_yylval_string(*str++);
|
||||
continue; // Do not copy an additional character
|
||||
|
||||
case EOF: // Can't really print that one
|
||||
@@ -1512,24 +1512,24 @@ static void readString(void)
|
||||
|
||||
if (ptr)
|
||||
while (*ptr)
|
||||
append_yylval_tzString(*ptr++);
|
||||
append_yylval_string(*ptr++);
|
||||
lexerState->disableMacroArgs = true;
|
||||
continue; // Do not copy an additional character
|
||||
|
||||
// Regular characters will just get copied
|
||||
}
|
||||
|
||||
append_yylval_tzString(c);
|
||||
append_yylval_string(c);
|
||||
}
|
||||
|
||||
finish:
|
||||
if (i == sizeof(yylval.tzString)) {
|
||||
if (i == sizeof(yylval.string)) {
|
||||
i--;
|
||||
warning(WARNING_LONG_STR, "String constant too long\n");
|
||||
}
|
||||
yylval.tzString[i] = '\0';
|
||||
yylval.string[i] = '\0';
|
||||
|
||||
dbgPrint("Read string \"%s\"\n", yylval.tzString);
|
||||
dbgPrint("Read string \"%s\"\n", yylval.string);
|
||||
lexerState->disableMacroArgs = false;
|
||||
lexerState->disableInterpolation = false;
|
||||
}
|
||||
@@ -1543,13 +1543,13 @@ static size_t appendStringLiteral(size_t i)
|
||||
bool multiline = false;
|
||||
|
||||
// We reach this function after reading a single quote, but we also support triple quotes
|
||||
append_yylval_tzString('"');
|
||||
append_yylval_string('"');
|
||||
if (peek() == '"') {
|
||||
append_yylval_tzString('"');
|
||||
append_yylval_string('"');
|
||||
shiftChar();
|
||||
if (peek() == '"') {
|
||||
// """ begins a multi-line string
|
||||
append_yylval_tzString('"');
|
||||
append_yylval_string('"');
|
||||
shiftChar();
|
||||
multiline = true;
|
||||
} else {
|
||||
@@ -1584,14 +1584,14 @@ static size_t appendStringLiteral(size_t i)
|
||||
// Only """ ends a multi-line string
|
||||
if (peek() != '"')
|
||||
break;
|
||||
append_yylval_tzString('"');
|
||||
append_yylval_string('"');
|
||||
shiftChar();
|
||||
if (peek() != '"')
|
||||
break;
|
||||
append_yylval_tzString('"');
|
||||
append_yylval_string('"');
|
||||
shiftChar();
|
||||
}
|
||||
append_yylval_tzString('"');
|
||||
append_yylval_string('"');
|
||||
goto finish;
|
||||
|
||||
case '\\': // Character escape or macro arg
|
||||
@@ -1606,7 +1606,7 @@ static size_t appendStringLiteral(size_t i)
|
||||
case 'r':
|
||||
case 't':
|
||||
// Return that character unchanged
|
||||
append_yylval_tzString('\\');
|
||||
append_yylval_string('\\');
|
||||
shiftChar();
|
||||
break;
|
||||
|
||||
@@ -1668,17 +1668,17 @@ static size_t appendStringLiteral(size_t i)
|
||||
// Regular characters will just get copied
|
||||
}
|
||||
|
||||
append_yylval_tzString(c);
|
||||
append_yylval_string(c);
|
||||
}
|
||||
|
||||
finish:
|
||||
if (i == sizeof(yylval.tzString)) {
|
||||
if (i == sizeof(yylval.string)) {
|
||||
i--;
|
||||
warning(WARNING_LONG_STR, "String constant too long\n");
|
||||
}
|
||||
yylval.tzString[i] = '\0';
|
||||
yylval.string[i] = '\0';
|
||||
|
||||
dbgPrint("Read string \"%s\"\n", yylval.tzString);
|
||||
dbgPrint("Read string \"%s\"\n", yylval.string);
|
||||
lexerState->disableMacroArgs = false;
|
||||
lexerState->disableInterpolation = false;
|
||||
|
||||
@@ -1727,8 +1727,8 @@ static int yylex_NORMAL(void)
|
||||
return T_OP_NOT;
|
||||
|
||||
case '@':
|
||||
yylval.tzSym[0] = '@';
|
||||
yylval.tzSym[1] = '\0';
|
||||
yylval.symName[0] = '@';
|
||||
yylval.symName[1] = '\0';
|
||||
return T_ID;
|
||||
|
||||
case '[':
|
||||
@@ -1817,10 +1817,10 @@ static int yylex_NORMAL(void)
|
||||
/* Handle numbers */
|
||||
|
||||
case '$':
|
||||
yylval.nConstValue = 0;
|
||||
yylval.constValue = 0;
|
||||
readHexNumber();
|
||||
/* Attempt to match `$ff00+c` */
|
||||
if (yylval.nConstValue == 0xff00) {
|
||||
if (yylval.constValue == 0xff00) {
|
||||
/* Whitespace is ignored anyways */
|
||||
while (isWhitespace(c = peek()))
|
||||
shiftChar();
|
||||
@@ -1871,7 +1871,7 @@ static int yylex_NORMAL(void)
|
||||
if (secondChar != binDigits[0] && secondChar != binDigits[1])
|
||||
return T_OP_MOD;
|
||||
|
||||
yylval.nConstValue = 0;
|
||||
yylval.constValue = 0;
|
||||
readBinaryNumber();
|
||||
return T_NUMBER;
|
||||
|
||||
@@ -1923,7 +1923,7 @@ static int yylex_NORMAL(void)
|
||||
/* Local symbols cannot be string expansions */
|
||||
if (tokenType == T_ID && lexerState->expandStrings) {
|
||||
/* Attempt string expansion */
|
||||
struct Symbol const *sym = sym_FindExactSymbol(yylval.tzSym);
|
||||
struct Symbol const *sym = sym_FindExactSymbol(yylval.symName);
|
||||
|
||||
if (sym && sym->type == SYM_EQUS) {
|
||||
char const *s = sym_GetStringValue(sym);
|
||||
@@ -1988,7 +1988,7 @@ static int yylex_RAW(void)
|
||||
discardBlockComment();
|
||||
continue;
|
||||
}
|
||||
append_yylval_tzString(c); /* Append the slash */
|
||||
append_yylval_string(c); /* Append the slash */
|
||||
break;
|
||||
|
||||
case '\\': /* Character escape */
|
||||
@@ -2036,23 +2036,23 @@ static int yylex_RAW(void)
|
||||
/* fallthrough */
|
||||
|
||||
default: /* Regular characters will just get copied */
|
||||
append_yylval_tzString(c);
|
||||
append_yylval_string(c);
|
||||
shiftChar();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
finish:
|
||||
if (i == sizeof(yylval.tzString)) {
|
||||
if (i == sizeof(yylval.string)) {
|
||||
i--;
|
||||
warning(WARNING_LONG_STR, "Macro argument too long\n");
|
||||
}
|
||||
/* Trim right whitespace */
|
||||
while (i && isWhitespace(yylval.tzString[i - 1]))
|
||||
while (i && isWhitespace(yylval.string[i - 1]))
|
||||
i--;
|
||||
yylval.tzString[i] = '\0';
|
||||
yylval.string[i] = '\0';
|
||||
|
||||
dbgPrint("Read raw string \"%s\"\n", yylval.tzString);
|
||||
dbgPrint("Read raw string \"%s\"\n", yylval.string);
|
||||
|
||||
// Returning T_COMMAs to the parser would mean that two consecutive commas
|
||||
// (i.e. an empty argument) need to return two different tokens (T_STRING
|
||||
@@ -2082,7 +2082,7 @@ finish:
|
||||
return T_EOF;
|
||||
}
|
||||
|
||||
#undef append_yylval_tzString
|
||||
#undef append_yylval_string
|
||||
|
||||
/*
|
||||
* This function uses the fact that `if`, etc. constructs are only valid when
|
||||
|
||||
@@ -45,10 +45,10 @@ extern int yydebug;
|
||||
#endif
|
||||
|
||||
FILE * dependfile;
|
||||
bool oGeneratedMissingIncludes;
|
||||
bool oFailedOnMissingInclude;
|
||||
bool oGeneratePhonyDeps;
|
||||
char *tzTargetFileName;
|
||||
bool generatedMissingIncludes;
|
||||
bool failedOnMissingInclude;
|
||||
bool generatePhonyDeps;
|
||||
char *targetFileName;
|
||||
|
||||
bool haltnop;
|
||||
bool optimizeLoads;
|
||||
@@ -158,10 +158,10 @@ int main(int argc, char *argv[])
|
||||
|
||||
// Set defaults
|
||||
|
||||
oGeneratePhonyDeps = false;
|
||||
oGeneratedMissingIncludes = false;
|
||||
oFailedOnMissingInclude = false;
|
||||
tzTargetFileName = NULL;
|
||||
generatePhonyDeps = false;
|
||||
generatedMissingIncludes = false;
|
||||
failedOnMissingInclude = false;
|
||||
targetFileName = NULL;
|
||||
|
||||
opt_B("01");
|
||||
opt_G("0123");
|
||||
@@ -171,8 +171,8 @@ int main(int argc, char *argv[])
|
||||
verbose = false;
|
||||
warnings = true;
|
||||
sym_SetExportAll(false);
|
||||
uint32_t maxRecursionDepth = 64;
|
||||
size_t nTargetFileNameLen = 0;
|
||||
uint32_t maxDepth = 64;
|
||||
size_t targetFileNameLen = 0;
|
||||
|
||||
while ((ch = musl_getopt_long_only(argc, argv, optstring, longopts, NULL)) != -1) {
|
||||
switch (ch) {
|
||||
@@ -244,7 +244,7 @@ int main(int argc, char *argv[])
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
maxRecursionDepth = strtoul(musl_optarg, &ep, 0);
|
||||
maxDepth = strtoul(musl_optarg, &ep, 0);
|
||||
|
||||
if (musl_optarg[0] == '\0' || *ep != '\0')
|
||||
errx(1, "Invalid argument for option 'r'");
|
||||
@@ -269,11 +269,11 @@ int main(int argc, char *argv[])
|
||||
case 0:
|
||||
switch (depType) {
|
||||
case 'G':
|
||||
oGeneratedMissingIncludes = true;
|
||||
generatedMissingIncludes = true;
|
||||
break;
|
||||
|
||||
case 'P':
|
||||
oGeneratePhonyDeps = true;
|
||||
generatePhonyDeps = true;
|
||||
break;
|
||||
|
||||
case 'Q':
|
||||
@@ -284,22 +284,22 @@ int main(int argc, char *argv[])
|
||||
if (depType == 'Q')
|
||||
ep = make_escape(ep);
|
||||
|
||||
nTargetFileNameLen += strlen(ep) + 1;
|
||||
if (!tzTargetFileName) {
|
||||
targetFileNameLen += strlen(ep) + 1;
|
||||
if (!targetFileName) {
|
||||
/* On first alloc, make an empty str */
|
||||
tzTargetFileName = malloc(nTargetFileNameLen + 1);
|
||||
if (tzTargetFileName)
|
||||
*tzTargetFileName = '\0';
|
||||
targetFileName = malloc(targetFileNameLen + 1);
|
||||
if (targetFileName)
|
||||
*targetFileName = '\0';
|
||||
} else {
|
||||
tzTargetFileName = realloc(tzTargetFileName,
|
||||
nTargetFileNameLen + 1);
|
||||
targetFileName = realloc(targetFileName,
|
||||
targetFileNameLen + 1);
|
||||
}
|
||||
if (tzTargetFileName == NULL)
|
||||
if (targetFileName == NULL)
|
||||
err(1, "Cannot append new file to target file list");
|
||||
strcat(tzTargetFileName, ep);
|
||||
strcat(targetFileName, ep);
|
||||
if (depType == 'Q')
|
||||
free(ep);
|
||||
char *ptr = tzTargetFileName + strlen(tzTargetFileName);
|
||||
char *ptr = targetFileName + strlen(targetFileName);
|
||||
|
||||
*ptr++ = ' ';
|
||||
*ptr = '\0';
|
||||
@@ -314,8 +314,8 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
if (tzTargetFileName == NULL)
|
||||
tzTargetFileName = tzObjectname;
|
||||
if (targetFileName == NULL)
|
||||
targetFileName = objectName;
|
||||
|
||||
if (argc == musl_optind) {
|
||||
fputs("FATAL: No input files\n", stderr);
|
||||
@@ -331,17 +331,17 @@ int main(int argc, char *argv[])
|
||||
printf("Assembling %s\n", mainFileName);
|
||||
|
||||
if (dependfile) {
|
||||
if (!tzTargetFileName)
|
||||
if (!targetFileName)
|
||||
errx(1, "Dependency files can only be created if a target file is specified with either -o, -MQ or -MT\n");
|
||||
|
||||
fprintf(dependfile, "%s: %s\n", tzTargetFileName, mainFileName);
|
||||
fprintf(dependfile, "%s: %s\n", targetFileName, mainFileName);
|
||||
}
|
||||
|
||||
charmap_New("main", NULL);
|
||||
|
||||
// Init lexer and file stack, prodiving file info
|
||||
lexer_Init();
|
||||
fstk_Init(mainFileName, maxRecursionDepth);
|
||||
fstk_Init(mainFileName, maxDepth);
|
||||
|
||||
// Perform parse (yyparse is auto-generated from `parser.y`)
|
||||
if (yyparse() != 0 && nbErrors == 0)
|
||||
@@ -357,11 +357,11 @@ int main(int argc, char *argv[])
|
||||
nbErrors == 1 ? "" : "s");
|
||||
|
||||
// If parse aborted due to missing an include, and `-MG` was given, exit normally
|
||||
if (oFailedOnMissingInclude)
|
||||
if (failedOnMissingInclude)
|
||||
return 0;
|
||||
|
||||
/* If no path specified, don't write file */
|
||||
if (tzObjectname != NULL)
|
||||
if (objectName != NULL)
|
||||
out_WriteObject();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -35,12 +35,12 @@
|
||||
struct Patch {
|
||||
struct FileStackNode const *src;
|
||||
uint32_t lineNo;
|
||||
uint32_t nOffset;
|
||||
uint32_t offset;
|
||||
struct Section *pcSection;
|
||||
uint32_t pcOffset;
|
||||
uint8_t type;
|
||||
uint32_t nRPNSize;
|
||||
uint8_t *pRPN;
|
||||
uint32_t rpnSize;
|
||||
uint8_t *rpn;
|
||||
struct Patch *next;
|
||||
};
|
||||
|
||||
@@ -51,10 +51,10 @@ struct Assertion {
|
||||
struct Assertion *next;
|
||||
};
|
||||
|
||||
char *tzObjectname;
|
||||
char *objectName;
|
||||
|
||||
/* TODO: shouldn't `pCurrentSection` be somewhere else? */
|
||||
struct Section *pSectionList, *pCurrentSection;
|
||||
/* TODO: shouldn't `currentSection` be somewhere else? */
|
||||
struct Section *sectionList, *currentSection;
|
||||
|
||||
/* Linked list of symbols to put in the object file */
|
||||
static struct Symbol *objectSymbols = NULL;
|
||||
@@ -72,7 +72,7 @@ static uint32_t countSections(void)
|
||||
{
|
||||
uint32_t count = 0;
|
||||
|
||||
for (struct Section const *sect = pSectionList; sect; sect = sect->next)
|
||||
for (struct Section const *sect = sectionList; sect; sect = sect->next)
|
||||
count++;
|
||||
|
||||
return count;
|
||||
@@ -179,7 +179,7 @@ This is code intended to replace a node, which is pretty useless until ref count
|
||||
*/
|
||||
static uint32_t getsectid(struct Section const *sect)
|
||||
{
|
||||
struct Section const *sec = pSectionList;
|
||||
struct Section const *sec = sectionList;
|
||||
uint32_t ID = 0;
|
||||
|
||||
while (sec) {
|
||||
@@ -205,12 +205,12 @@ static void writepatch(struct Patch const *patch, FILE *f)
|
||||
assert(patch->src->ID != -1);
|
||||
putlong(patch->src->ID, f);
|
||||
putlong(patch->lineNo, f);
|
||||
putlong(patch->nOffset, f);
|
||||
putlong(patch->offset, f);
|
||||
putlong(getSectIDIfAny(patch->pcSection), f);
|
||||
putlong(patch->pcOffset, f);
|
||||
putc(patch->type, f);
|
||||
putlong(patch->nRPNSize, f);
|
||||
fwrite(patch->pRPN, 1, patch->nRPNSize, f);
|
||||
putlong(patch->rpnSize, f);
|
||||
fwrite(patch->rpn, 1, patch->rpnSize, f);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -286,7 +286,7 @@ static uint32_t getSymbolID(struct Symbol *sym)
|
||||
static void writerpn(uint8_t *rpnexpr, uint32_t *rpnptr, uint8_t *rpn,
|
||||
uint32_t rpnlen)
|
||||
{
|
||||
char tzSym[512];
|
||||
char symName[512];
|
||||
|
||||
for (size_t offset = 0; offset < rpnlen; ) {
|
||||
#define popbyte() rpn[offset++]
|
||||
@@ -310,14 +310,14 @@ static void writerpn(uint8_t *rpnexpr, uint32_t *rpnptr, uint8_t *rpn,
|
||||
case RPN_SYM:
|
||||
i = 0;
|
||||
do {
|
||||
tzSym[i] = popbyte();
|
||||
} while (tzSym[i++]);
|
||||
symName[i] = popbyte();
|
||||
} while (symName[i++]);
|
||||
|
||||
// The symbol name is always written expanded
|
||||
sym = sym_FindExactSymbol(tzSym);
|
||||
sym = sym_FindExactSymbol(symName);
|
||||
if (sym_IsConstant(sym)) {
|
||||
writebyte(RPN_CONST);
|
||||
value = sym_GetConstantValue(tzSym);
|
||||
value = sym_GetConstantValue(symName);
|
||||
} else {
|
||||
writebyte(RPN_SYM);
|
||||
value = getSymbolID(sym);
|
||||
@@ -332,11 +332,11 @@ static void writerpn(uint8_t *rpnexpr, uint32_t *rpnptr, uint8_t *rpn,
|
||||
case RPN_BANK_SYM:
|
||||
i = 0;
|
||||
do {
|
||||
tzSym[i] = popbyte();
|
||||
} while (tzSym[i++]);
|
||||
symName[i] = popbyte();
|
||||
} while (symName[i++]);
|
||||
|
||||
// The symbol name is always written expanded
|
||||
sym = sym_FindExactSymbol(tzSym);
|
||||
sym = sym_FindExactSymbol(symName);
|
||||
value = getSymbolID(sym);
|
||||
|
||||
writebyte(RPN_BANK_SYM);
|
||||
@@ -386,38 +386,38 @@ static void writerpn(uint8_t *rpnexpr, uint32_t *rpnptr, uint8_t *rpn,
|
||||
static struct Patch *allocpatch(uint32_t type, struct Expression const *expr, uint32_t ofs)
|
||||
{
|
||||
struct Patch *patch = malloc(sizeof(struct Patch));
|
||||
uint32_t rpnSize = expr->isKnown ? 5 : expr->nRPNPatchSize;
|
||||
uint32_t rpnSize = expr->isKnown ? 5 : expr->rpnPatchSize;
|
||||
struct FileStackNode *node = fstk_GetFileStack();
|
||||
|
||||
if (!patch)
|
||||
fatalerror("No memory for patch: %s\n", strerror(errno));
|
||||
|
||||
patch->pRPN = malloc(sizeof(*patch->pRPN) * rpnSize);
|
||||
if (!patch->pRPN)
|
||||
fatalerror("No memory for patch's RPN expression: %s\n", strerror(errno));
|
||||
patch->rpn = malloc(sizeof(*patch->rpn) * rpnSize);
|
||||
if (!patch->rpn)
|
||||
fatalerror("No memory for patch's RPN rpnSize: %s\n", strerror(errno));
|
||||
|
||||
patch->type = type;
|
||||
patch->src = node;
|
||||
out_RegisterNode(node);
|
||||
patch->lineNo = lexer_GetLineNo();
|
||||
patch->nOffset = ofs;
|
||||
patch->offset = ofs;
|
||||
patch->pcSection = sect_GetSymbolSection();
|
||||
patch->pcOffset = sect_GetSymbolOffset();
|
||||
|
||||
/* If the expression's value is known, output a constant RPN expression directly */
|
||||
/* If the rpnSize's value is known, output a constant RPN rpnSize directly */
|
||||
if (expr->isKnown) {
|
||||
patch->nRPNSize = rpnSize;
|
||||
patch->rpnSize = rpnSize;
|
||||
/* Make sure to update `rpnSize` above if modifying this! */
|
||||
patch->pRPN[0] = RPN_CONST;
|
||||
patch->pRPN[1] = (uint32_t)(expr->nVal) & 0xFF;
|
||||
patch->pRPN[2] = (uint32_t)(expr->nVal) >> 8;
|
||||
patch->pRPN[3] = (uint32_t)(expr->nVal) >> 16;
|
||||
patch->pRPN[4] = (uint32_t)(expr->nVal) >> 24;
|
||||
patch->rpn[0] = RPN_CONST;
|
||||
patch->rpn[1] = (uint32_t)(expr->val) & 0xFF;
|
||||
patch->rpn[2] = (uint32_t)(expr->val) >> 8;
|
||||
patch->rpn[3] = (uint32_t)(expr->val) >> 16;
|
||||
patch->rpn[4] = (uint32_t)(expr->val) >> 24;
|
||||
} else {
|
||||
patch->nRPNSize = 0;
|
||||
writerpn(patch->pRPN, &patch->nRPNSize, expr->tRPN, expr->nRPNLength);
|
||||
patch->rpnSize = 0;
|
||||
writerpn(patch->rpn, &patch->rpnSize, expr->rpn, expr->rpnLength);
|
||||
}
|
||||
assert(patch->nRPNSize == rpnSize);
|
||||
assert(patch->rpnSize == rpnSize);
|
||||
|
||||
return patch;
|
||||
}
|
||||
@@ -434,8 +434,8 @@ void out_CreatePatch(uint32_t type, struct Expression const *expr, uint32_t ofs,
|
||||
// before those bytes.
|
||||
patch->pcOffset -= pcShift;
|
||||
|
||||
patch->next = pCurrentSection->patches;
|
||||
pCurrentSection->patches = patch;
|
||||
patch->next = currentSection->patches;
|
||||
currentSection->patches = patch;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -501,13 +501,13 @@ static void registerUnregisteredSymbol(struct Symbol *symbol, void *arg)
|
||||
void out_WriteObject(void)
|
||||
{
|
||||
FILE *f;
|
||||
if (strcmp(tzObjectname, "-") != 0)
|
||||
f = fopen(tzObjectname, "wb");
|
||||
if (strcmp(objectName, "-") != 0)
|
||||
f = fopen(objectName, "wb");
|
||||
else
|
||||
f = fdopen(1, "wb");
|
||||
|
||||
if (!f)
|
||||
err(1, "Couldn't write file '%s'", tzObjectname);
|
||||
err(1, "Couldn't write file '%s'", objectName);
|
||||
|
||||
/* Also write symbols that weren't written above */
|
||||
sym_ForEach(registerUnregisteredSymbol, NULL);
|
||||
@@ -530,7 +530,7 @@ void out_WriteObject(void)
|
||||
for (struct Symbol const *sym = objectSymbols; sym; sym = sym->next)
|
||||
writesymbol(sym, f);
|
||||
|
||||
for (struct Section *sect = pSectionList; sect; sect = sect->next)
|
||||
for (struct Section *sect = sectionList; sect; sect = sect->next)
|
||||
writesection(sect, f);
|
||||
|
||||
putlong(countAsserts(), f);
|
||||
@@ -546,7 +546,7 @@ void out_WriteObject(void)
|
||||
*/
|
||||
void out_SetFileName(char *s)
|
||||
{
|
||||
tzObjectname = s;
|
||||
objectName = s;
|
||||
if (verbose)
|
||||
printf("Output filename %s\n", s);
|
||||
}
|
||||
|
||||
110
src/asm/parser.y
110
src/asm/parser.y
@@ -440,10 +440,10 @@ enum {
|
||||
|
||||
%union
|
||||
{
|
||||
char tzSym[MAXSYMLEN + 1];
|
||||
char tzString[MAXSTRLEN + 1];
|
||||
struct Expression sVal;
|
||||
int32_t nConstValue;
|
||||
char symName[MAXSYMLEN + 1];
|
||||
char string[MAXSTRLEN + 1];
|
||||
struct Expression expr;
|
||||
int32_t constValue;
|
||||
enum SectionModifier sectMod;
|
||||
struct SectionSpec sectSpec;
|
||||
struct MacroArgs *macroArg;
|
||||
@@ -457,29 +457,29 @@ enum {
|
||||
struct StrFmtArgList strfmtArgs;
|
||||
}
|
||||
|
||||
%type <sVal> relocexpr
|
||||
%type <sVal> relocexpr_no_str
|
||||
%type <nConstValue> const
|
||||
%type <nConstValue> const_no_str
|
||||
%type <nConstValue> uconst
|
||||
%type <nConstValue> rs_uconst
|
||||
%type <nConstValue> const_3bit
|
||||
%type <sVal> reloc_8bit
|
||||
%type <sVal> reloc_8bit_no_str
|
||||
%type <sVal> reloc_16bit
|
||||
%type <sVal> reloc_16bit_no_str
|
||||
%type <nConstValue> sectiontype
|
||||
%type <expr> relocexpr
|
||||
%type <expr> relocexpr_no_str
|
||||
%type <constValue> const
|
||||
%type <constValue> const_no_str
|
||||
%type <constValue> uconst
|
||||
%type <constValue> rs_uconst
|
||||
%type <constValue> const_3bit
|
||||
%type <expr> reloc_8bit
|
||||
%type <expr> reloc_8bit_no_str
|
||||
%type <expr> reloc_16bit
|
||||
%type <expr> reloc_16bit_no_str
|
||||
%type <constValue> sectiontype
|
||||
|
||||
%type <tzString> string
|
||||
%type <tzString> strcat_args
|
||||
%type <string> string
|
||||
%type <string> strcat_args
|
||||
%type <strfmtArgs> strfmt_args
|
||||
%type <strfmtArgs> strfmt_va_args
|
||||
|
||||
%type <nConstValue> sectorg
|
||||
%type <constValue> sectorg
|
||||
%type <sectSpec> sectattrs
|
||||
|
||||
%token <nConstValue> T_NUMBER "number"
|
||||
%token <tzString> T_STRING "string"
|
||||
%token <constValue> T_NUMBER "number"
|
||||
%token <string> T_STRING "string"
|
||||
|
||||
%token T_PERIOD "."
|
||||
%token T_COMMA ","
|
||||
@@ -539,14 +539,14 @@ enum {
|
||||
%token T_OP_CHARLEN "CHARLEN"
|
||||
%token T_OP_CHARSUB "CHARSUB"
|
||||
|
||||
%token <tzSym> T_LABEL "label"
|
||||
%token <tzSym> T_ID "identifier"
|
||||
%token <tzSym> T_LOCAL_ID "local identifier"
|
||||
%token <tzSym> T_ANON "anonymous label"
|
||||
%type <tzSym> def_id
|
||||
%type <tzSym> redef_id
|
||||
%type <tzSym> scoped_id
|
||||
%type <tzSym> scoped_anon_id
|
||||
%token <symName> T_LABEL "label"
|
||||
%token <symName> T_ID "identifier"
|
||||
%token <symName> T_LOCAL_ID "local identifier"
|
||||
%token <symName> T_ANON "anonymous label"
|
||||
%type <symName> def_id
|
||||
%type <symName> redef_id
|
||||
%type <symName> scoped_id
|
||||
%type <symName> scoped_anon_id
|
||||
%token T_POP_EQU "EQU"
|
||||
%token T_POP_SET "SET"
|
||||
%token T_POP_EQUAL "="
|
||||
@@ -628,14 +628,14 @@ enum {
|
||||
%token T_MODE_HL "hl" T_MODE_HL_DEC "hld/hl-" T_MODE_HL_INC "hli/hl+"
|
||||
%token T_CC_NZ "nz" T_CC_Z "z" T_CC_NC "nc" // There is no T_CC_C, only T_TOKEN_C
|
||||
|
||||
%type <nConstValue> reg_r
|
||||
%type <nConstValue> reg_ss
|
||||
%type <nConstValue> reg_rr
|
||||
%type <nConstValue> reg_tt
|
||||
%type <nConstValue> ccode
|
||||
%type <sVal> op_a_n
|
||||
%type <nConstValue> op_a_r
|
||||
%type <sVal> op_mem_ind
|
||||
%type <constValue> reg_r
|
||||
%type <constValue> reg_ss
|
||||
%type <constValue> reg_rr
|
||||
%type <constValue> reg_tt
|
||||
%type <constValue> ccode
|
||||
%type <expr> op_a_n
|
||||
%type <constValue> op_a_r
|
||||
%type <expr> op_mem_ind
|
||||
%type <assertType> assert_type
|
||||
|
||||
%token T_EOF 0 "end of file"
|
||||
@@ -939,7 +939,7 @@ assert : T_POP_ASSERT assert_type relocexpr
|
||||
sect_GetOutputOffset()))
|
||||
error("Assertion creation failed: %s\n",
|
||||
strerror(errno));
|
||||
} else if ($3.nVal == 0) {
|
||||
} else if ($3.val == 0) {
|
||||
failAssert($2);
|
||||
}
|
||||
rpn_Free(&$3);
|
||||
@@ -951,7 +951,7 @@ assert : T_POP_ASSERT assert_type relocexpr
|
||||
sect_GetOutputOffset()))
|
||||
error("Assertion creation failed: %s\n",
|
||||
strerror(errno));
|
||||
} else if ($3.nVal == 0) {
|
||||
} else if ($3.val == 0) {
|
||||
failAssertMsg($2, $5);
|
||||
}
|
||||
rpn_Free(&$3);
|
||||
@@ -1156,24 +1156,24 @@ export_list_entry : scoped_id { sym_Export($1); }
|
||||
|
||||
include : T_POP_INCLUDE string {
|
||||
fstk_RunInclude($2);
|
||||
if (oFailedOnMissingInclude)
|
||||
if (failedOnMissingInclude)
|
||||
YYACCEPT;
|
||||
}
|
||||
;
|
||||
|
||||
incbin : T_POP_INCBIN string {
|
||||
out_BinaryFile($2, 0);
|
||||
if (oFailedOnMissingInclude)
|
||||
if (failedOnMissingInclude)
|
||||
YYACCEPT;
|
||||
}
|
||||
| T_POP_INCBIN string T_COMMA const {
|
||||
out_BinaryFile($2, $4);
|
||||
if (oFailedOnMissingInclude)
|
||||
if (failedOnMissingInclude)
|
||||
YYACCEPT;
|
||||
}
|
||||
| T_POP_INCBIN string T_COMMA const T_COMMA const {
|
||||
out_BinaryFileSlice($2, $4, $6);
|
||||
if (oFailedOnMissingInclude)
|
||||
if (failedOnMissingInclude)
|
||||
YYACCEPT;
|
||||
}
|
||||
;
|
||||
@@ -1305,7 +1305,7 @@ constlist_32bit_entry :relocexpr_no_str {
|
||||
|
||||
reloc_8bit : relocexpr {
|
||||
if(rpn_isKnown(&$1)
|
||||
&& ($1.nVal < -128 || $1.nVal > 255))
|
||||
&& ($1.val < -128 || $1.val > 255))
|
||||
warning(WARNING_TRUNCATION, "Expression must be 8-bit\n");
|
||||
$$ = $1;
|
||||
}
|
||||
@@ -1313,7 +1313,7 @@ reloc_8bit : relocexpr {
|
||||
|
||||
reloc_8bit_no_str : relocexpr_no_str {
|
||||
if(rpn_isKnown(&$1)
|
||||
&& ($1.nVal < -128 || $1.nVal > 255))
|
||||
&& ($1.val < -128 || $1.val > 255))
|
||||
warning(WARNING_TRUNCATION, "Expression must be 8-bit\n");
|
||||
$$ = $1;
|
||||
}
|
||||
@@ -1321,7 +1321,7 @@ reloc_8bit_no_str : relocexpr_no_str {
|
||||
|
||||
reloc_16bit : relocexpr {
|
||||
if (rpn_isKnown(&$1)
|
||||
&& ($1.nVal < -32768 || $1.nVal > 65535))
|
||||
&& ($1.val < -32768 || $1.val > 65535))
|
||||
warning(WARNING_TRUNCATION, "Expression must be 16-bit\n");
|
||||
$$ = $1;
|
||||
}
|
||||
@@ -1329,7 +1329,7 @@ reloc_16bit : relocexpr {
|
||||
|
||||
reloc_16bit_no_str : relocexpr_no_str {
|
||||
if (rpn_isKnown(&$1)
|
||||
&& ($1.nVal < -32768 || $1.nVal > 65535))
|
||||
&& ($1.val < -32768 || $1.val > 65535))
|
||||
warning(WARNING_TRUNCATION, "Expression must be 16-bit\n");
|
||||
$$ = $1;
|
||||
}
|
||||
@@ -1509,7 +1509,7 @@ const : relocexpr {
|
||||
$1.reason);
|
||||
$$ = 0;
|
||||
} else {
|
||||
$$ = $1.nVal;
|
||||
$$ = $1.val;
|
||||
}
|
||||
}
|
||||
;
|
||||
@@ -1520,7 +1520,7 @@ const_no_str : relocexpr_no_str {
|
||||
$1.reason);
|
||||
$$ = 0;
|
||||
} else {
|
||||
$$ = $1.nVal;
|
||||
$$ = $1.val;
|
||||
}
|
||||
}
|
||||
;
|
||||
@@ -1584,7 +1584,7 @@ strfmt_va_args : %empty {
|
||||
$3.reason);
|
||||
value = 0;
|
||||
} else {
|
||||
value = $3.nVal;
|
||||
value = $3.val;
|
||||
}
|
||||
|
||||
size_t i = nextStrFmtArgListIndex(&$1);
|
||||
@@ -1876,9 +1876,9 @@ z80_ld_mem : T_Z80_LD op_mem_ind T_COMMA T_MODE_SP {
|
||||
}
|
||||
| T_Z80_LD op_mem_ind T_COMMA T_MODE_A {
|
||||
if (optimizeLoads && rpn_isKnown(&$2)
|
||||
&& $2.nVal >= 0xFF00) {
|
||||
&& $2.val >= 0xFF00) {
|
||||
out_AbsByte(0xE0);
|
||||
out_AbsByte($2.nVal & 0xFF);
|
||||
out_AbsByte($2.val & 0xFF);
|
||||
rpn_Free(&$2);
|
||||
} else {
|
||||
out_AbsByte(0xEA);
|
||||
@@ -1924,9 +1924,9 @@ z80_ld_a : T_Z80_LD reg_r T_COMMA c_ind {
|
||||
| T_Z80_LD reg_r T_COMMA op_mem_ind {
|
||||
if ($2 == REG_A) {
|
||||
if (optimizeLoads && rpn_isKnown(&$4)
|
||||
&& $4.nVal >= 0xFF00) {
|
||||
&& $4.val >= 0xFF00) {
|
||||
out_AbsByte(0xF0);
|
||||
out_AbsByte($4.nVal & 0xFF);
|
||||
out_AbsByte($4.val & 0xFF);
|
||||
rpn_Free(&$4);
|
||||
} else {
|
||||
out_AbsByte(0xFA);
|
||||
@@ -2024,7 +2024,7 @@ z80_rst : T_Z80_RST reloc_8bit {
|
||||
if (!rpn_isKnown(&$2))
|
||||
out_RelByte(&$2, 0);
|
||||
else
|
||||
out_AbsByte(0xC7 | $2.nVal);
|
||||
out_AbsByte(0xC7 | $2.val);
|
||||
rpn_Free(&$2);
|
||||
}
|
||||
;
|
||||
|
||||
258
src/asm/rpn.c
258
src/asm/rpn.c
@@ -45,32 +45,32 @@
|
||||
static uint8_t *reserveSpace(struct Expression *expr, uint32_t size)
|
||||
{
|
||||
/* This assumes the RPN length is always less than the capacity */
|
||||
if (expr->nRPNCapacity - expr->nRPNLength < size) {
|
||||
if (expr->rpnCapacity - expr->rpnLength < size) {
|
||||
/* If there isn't enough room to reserve the space, realloc */
|
||||
if (!expr->tRPN)
|
||||
expr->nRPNCapacity = 256; /* Initial size */
|
||||
while (expr->nRPNCapacity - expr->nRPNLength < size) {
|
||||
if (expr->nRPNCapacity >= MAXRPNLEN)
|
||||
if (!expr->rpn)
|
||||
expr->rpnCapacity = 256; /* Initial size */
|
||||
while (expr->rpnCapacity - expr->rpnLength < size) {
|
||||
if (expr->rpnCapacity >= MAXRPNLEN)
|
||||
/*
|
||||
* To avoid generating humongous object files, cap the
|
||||
* size of RPN expressions
|
||||
*/
|
||||
fatalerror("RPN expression cannot grow larger than "
|
||||
EXPAND_AND_STR(MAXRPNLEN) " bytes\n");
|
||||
else if (expr->nRPNCapacity > MAXRPNLEN / 2)
|
||||
expr->nRPNCapacity = MAXRPNLEN;
|
||||
else if (expr->rpnCapacity > MAXRPNLEN / 2)
|
||||
expr->rpnCapacity = MAXRPNLEN;
|
||||
else
|
||||
expr->nRPNCapacity *= 2;
|
||||
expr->rpnCapacity *= 2;
|
||||
}
|
||||
expr->tRPN = realloc(expr->tRPN, expr->nRPNCapacity);
|
||||
expr->rpn = realloc(expr->rpn, expr->rpnCapacity);
|
||||
|
||||
if (!expr->tRPN)
|
||||
if (!expr->rpn)
|
||||
fatalerror("Failed to grow RPN expression: %s\n", strerror(errno));
|
||||
}
|
||||
|
||||
uint8_t *ptr = expr->tRPN + expr->nRPNLength;
|
||||
uint8_t *ptr = expr->rpn + expr->rpnLength;
|
||||
|
||||
expr->nRPNLength += size;
|
||||
expr->rpnLength += size;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
@@ -82,10 +82,10 @@ static void rpn_Init(struct Expression *expr)
|
||||
expr->reason = NULL;
|
||||
expr->isKnown = true;
|
||||
expr->isSymbol = false;
|
||||
expr->tRPN = NULL;
|
||||
expr->nRPNCapacity = 0;
|
||||
expr->nRPNLength = 0;
|
||||
expr->nRPNPatchSize = 0;
|
||||
expr->rpn = NULL;
|
||||
expr->rpnCapacity = 0;
|
||||
expr->rpnLength = 0;
|
||||
expr->rpnPatchSize = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -93,7 +93,7 @@ static void rpn_Init(struct Expression *expr)
|
||||
*/
|
||||
void rpn_Free(struct Expression *expr)
|
||||
{
|
||||
free(expr->tRPN);
|
||||
free(expr->rpn);
|
||||
free(expr->reason);
|
||||
rpn_Init(expr);
|
||||
}
|
||||
@@ -104,12 +104,12 @@ void rpn_Free(struct Expression *expr)
|
||||
void rpn_Number(struct Expression *expr, uint32_t i)
|
||||
{
|
||||
rpn_Init(expr);
|
||||
expr->nVal = i;
|
||||
expr->val = i;
|
||||
}
|
||||
|
||||
void rpn_Symbol(struct Expression *expr, char const *tzSym)
|
||||
void rpn_Symbol(struct Expression *expr, char const *symName)
|
||||
{
|
||||
struct Symbol *sym = sym_FindScopedSymbol(tzSym);
|
||||
struct Symbol *sym = sym_FindScopedSymbol(symName);
|
||||
|
||||
if (sym_IsPC(sym) && !sect_GetSymbolSection()) {
|
||||
error("PC has no value outside a section\n");
|
||||
@@ -119,16 +119,16 @@ void rpn_Symbol(struct Expression *expr, char const *tzSym)
|
||||
expr->isSymbol = true;
|
||||
|
||||
makeUnknown(expr, sym_IsPC(sym) ? "PC is not constant at assembly time"
|
||||
: "'%s' is not constant at assembly time", tzSym);
|
||||
sym = sym_Ref(tzSym);
|
||||
expr->nRPNPatchSize += 5; /* 1-byte opcode + 4-byte symbol ID */
|
||||
: "'%s' is not constant at assembly time", symName);
|
||||
sym = sym_Ref(symName);
|
||||
expr->rpnPatchSize += 5; /* 1-byte opcode + 4-byte symbol ID */
|
||||
|
||||
size_t nameLen = strlen(sym->name) + 1; /* Don't forget NUL! */
|
||||
uint8_t *ptr = reserveSpace(expr, nameLen + 1);
|
||||
*ptr++ = RPN_SYM;
|
||||
memcpy(ptr, sym->name, nameLen);
|
||||
} else {
|
||||
rpn_Number(expr, sym_GetConstantValue(tzSym));
|
||||
rpn_Number(expr, sym_GetConstantValue(symName));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,21 +136,21 @@ void rpn_BankSelf(struct Expression *expr)
|
||||
{
|
||||
rpn_Init(expr);
|
||||
|
||||
if (!pCurrentSection) {
|
||||
if (!currentSection) {
|
||||
error("PC has no bank outside a section\n");
|
||||
expr->nVal = 1;
|
||||
} else if (pCurrentSection->bank == (uint32_t)-1) {
|
||||
expr->val = 1;
|
||||
} else if (currentSection->bank == (uint32_t)-1) {
|
||||
makeUnknown(expr, "Current section's bank is not known");
|
||||
expr->nRPNPatchSize++;
|
||||
expr->rpnPatchSize++;
|
||||
*reserveSpace(expr, 1) = RPN_BANK_SELF;
|
||||
} else {
|
||||
expr->nVal = pCurrentSection->bank;
|
||||
expr->val = currentSection->bank;
|
||||
}
|
||||
}
|
||||
|
||||
void rpn_BankSymbol(struct Expression *expr, char const *tzSym)
|
||||
void rpn_BankSymbol(struct Expression *expr, char const *symName)
|
||||
{
|
||||
struct Symbol const *sym = sym_FindScopedSymbol(tzSym);
|
||||
struct Symbol const *sym = sym_FindScopedSymbol(symName);
|
||||
|
||||
/* The @ symbol is treated differently. */
|
||||
if (sym_IsPC(sym)) {
|
||||
@@ -162,15 +162,15 @@ void rpn_BankSymbol(struct Expression *expr, char const *tzSym)
|
||||
if (sym && !sym_IsLabel(sym)) {
|
||||
error("BANK argument must be a label\n");
|
||||
} else {
|
||||
sym = sym_Ref(tzSym);
|
||||
sym = sym_Ref(symName);
|
||||
assert(sym); // If the symbol didn't exist, it should have been created
|
||||
|
||||
if (sym_GetSection(sym) && sym_GetSection(sym)->bank != (uint32_t)-1) {
|
||||
/* Symbol's section is known and bank is fixed */
|
||||
expr->nVal = sym_GetSection(sym)->bank;
|
||||
expr->val = sym_GetSection(sym)->bank;
|
||||
} else {
|
||||
makeUnknown(expr, "\"%s\"'s bank is not known", tzSym);
|
||||
expr->nRPNPatchSize += 5; /* opcode + 4-byte sect ID */
|
||||
makeUnknown(expr, "\"%s\"'s bank is not known", symName);
|
||||
expr->rpnPatchSize += 5; /* opcode + 4-byte sect ID */
|
||||
|
||||
size_t nameLen = strlen(sym->name) + 1; /* Room for NUL! */
|
||||
uint8_t *ptr = reserveSpace(expr, nameLen + 1);
|
||||
@@ -180,53 +180,53 @@ void rpn_BankSymbol(struct Expression *expr, char const *tzSym)
|
||||
}
|
||||
}
|
||||
|
||||
void rpn_BankSection(struct Expression *expr, char const *tzSectionName)
|
||||
void rpn_BankSection(struct Expression *expr, char const *sectionName)
|
||||
{
|
||||
rpn_Init(expr);
|
||||
|
||||
struct Section *pSection = out_FindSectionByName(tzSectionName);
|
||||
struct Section *section = out_FindSectionByName(sectionName);
|
||||
|
||||
if (pSection && pSection->bank != (uint32_t)-1) {
|
||||
expr->nVal = pSection->bank;
|
||||
if (section && section->bank != (uint32_t)-1) {
|
||||
expr->val = section->bank;
|
||||
} else {
|
||||
makeUnknown(expr, "Section \"%s\"'s bank is not known",
|
||||
tzSectionName);
|
||||
sectionName);
|
||||
|
||||
size_t nameLen = strlen(tzSectionName) + 1; /* Room for NUL! */
|
||||
size_t nameLen = strlen(sectionName) + 1; /* Room for NUL! */
|
||||
uint8_t *ptr = reserveSpace(expr, nameLen + 1);
|
||||
|
||||
expr->nRPNPatchSize += nameLen + 1;
|
||||
expr->rpnPatchSize += nameLen + 1;
|
||||
*ptr++ = RPN_BANK_SECT;
|
||||
memcpy(ptr, tzSectionName, nameLen);
|
||||
memcpy(ptr, sectionName, nameLen);
|
||||
}
|
||||
}
|
||||
|
||||
void rpn_SizeOfSection(struct Expression *expr, char const *tzSectionName)
|
||||
void rpn_SizeOfSection(struct Expression *expr, char const *sectionName)
|
||||
{
|
||||
rpn_Init(expr);
|
||||
|
||||
makeUnknown(expr, "Section \"%s\"'s size is not known", tzSectionName);
|
||||
makeUnknown(expr, "Section \"%s\"'s size is not known", sectionName);
|
||||
|
||||
size_t nameLen = strlen(tzSectionName) + 1; /* Room for NUL! */
|
||||
size_t nameLen = strlen(sectionName) + 1; /* Room for NUL! */
|
||||
uint8_t *ptr = reserveSpace(expr, nameLen + 1);
|
||||
|
||||
expr->nRPNPatchSize += nameLen + 1;
|
||||
expr->rpnPatchSize += nameLen + 1;
|
||||
*ptr++ = RPN_SIZEOF_SECT;
|
||||
memcpy(ptr, tzSectionName, nameLen);
|
||||
memcpy(ptr, sectionName, nameLen);
|
||||
}
|
||||
|
||||
void rpn_StartOfSection(struct Expression *expr, char const *tzSectionName)
|
||||
void rpn_StartOfSection(struct Expression *expr, char const *sectionName)
|
||||
{
|
||||
rpn_Init(expr);
|
||||
|
||||
makeUnknown(expr, "Section \"%s\"'s start is not known", tzSectionName);
|
||||
makeUnknown(expr, "Section \"%s\"'s start is not known", sectionName);
|
||||
|
||||
size_t nameLen = strlen(tzSectionName) + 1; /* Room for NUL! */
|
||||
size_t nameLen = strlen(sectionName) + 1; /* Room for NUL! */
|
||||
uint8_t *ptr = reserveSpace(expr, nameLen + 1);
|
||||
|
||||
expr->nRPNPatchSize += nameLen + 1;
|
||||
expr->rpnPatchSize += nameLen + 1;
|
||||
*ptr++ = RPN_STARTOF_SECT;
|
||||
memcpy(ptr, tzSectionName, nameLen);
|
||||
memcpy(ptr, sectionName, nameLen);
|
||||
}
|
||||
|
||||
void rpn_CheckHRAM(struct Expression *expr, const struct Expression *src)
|
||||
@@ -235,13 +235,13 @@ void rpn_CheckHRAM(struct Expression *expr, const struct Expression *src)
|
||||
expr->isSymbol = false;
|
||||
|
||||
if (!rpn_isKnown(expr)) {
|
||||
expr->nRPNPatchSize++;
|
||||
expr->rpnPatchSize++;
|
||||
*reserveSpace(expr, 1) = RPN_HRAM;
|
||||
} else if (expr->nVal >= 0xFF00 && expr->nVal <= 0xFFFF) {
|
||||
} else if (expr->val >= 0xFF00 && expr->val <= 0xFFFF) {
|
||||
/* That range is valid, but only keep the lower byte */
|
||||
expr->nVal &= 0xFF;
|
||||
} else if (expr->nVal < 0 || expr->nVal > 0xFF) {
|
||||
error("Source address $%" PRIx32 " not between $FF00 to $FFFF\n", expr->nVal);
|
||||
expr->val &= 0xFF;
|
||||
} else if (expr->val < 0 || expr->val > 0xFF) {
|
||||
error("Source address $%" PRIx32 " not between $FF00 to $FFFF\n", expr->val);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,12 +251,12 @@ void rpn_CheckRST(struct Expression *expr, const struct Expression *src)
|
||||
|
||||
if (rpn_isKnown(expr)) {
|
||||
/* A valid RST address must be masked with 0x38 */
|
||||
if (expr->nVal & ~0x38)
|
||||
error("Invalid address $%" PRIx32 " for RST\n", expr->nVal);
|
||||
if (expr->val & ~0x38)
|
||||
error("Invalid address $%" PRIx32 " for RST\n", expr->val);
|
||||
/* The target is in the "0x38" bits, all other bits are set */
|
||||
expr->nVal |= 0xC7;
|
||||
expr->val |= 0xC7;
|
||||
} else {
|
||||
expr->nRPNPatchSize++;
|
||||
expr->rpnPatchSize++;
|
||||
*reserveSpace(expr, 1) = RPN_RST;
|
||||
}
|
||||
}
|
||||
@@ -267,9 +267,9 @@ void rpn_LOGNOT(struct Expression *expr, const struct Expression *src)
|
||||
expr->isSymbol = false;
|
||||
|
||||
if (rpn_isKnown(expr)) {
|
||||
expr->nVal = !expr->nVal;
|
||||
expr->val = !expr->val;
|
||||
} else {
|
||||
expr->nRPNPatchSize++;
|
||||
expr->rpnPatchSize++;
|
||||
*reserveSpace(expr, 1) = RPN_LOGUNNOT;
|
||||
}
|
||||
}
|
||||
@@ -278,7 +278,7 @@ struct Symbol const *rpn_SymbolOf(struct Expression const *expr)
|
||||
{
|
||||
if (!rpn_isSymbol(expr))
|
||||
return NULL;
|
||||
return sym_FindScopedSymbol((char *)expr->tRPN + 1);
|
||||
return sym_FindScopedSymbol((char *)expr->rpn + 1);
|
||||
}
|
||||
|
||||
bool rpn_IsDiffConstant(struct Expression const *src, struct Symbol const *sym)
|
||||
@@ -311,111 +311,111 @@ void rpn_BinaryOp(enum RPNCommand op, struct Expression *expr,
|
||||
rpn_Init(expr); /* Init the expression to something sane */
|
||||
|
||||
/* If both expressions are known, just compute the value */
|
||||
uint32_t uleft = src1->nVal, uright = src2->nVal;
|
||||
uint32_t uleft = src1->val, uright = src2->val;
|
||||
|
||||
switch (op) {
|
||||
case RPN_LOGOR:
|
||||
expr->nVal = src1->nVal || src2->nVal;
|
||||
expr->val = src1->val || src2->val;
|
||||
break;
|
||||
case RPN_LOGAND:
|
||||
expr->nVal = src1->nVal && src2->nVal;
|
||||
expr->val = src1->val && src2->val;
|
||||
break;
|
||||
case RPN_LOGEQ:
|
||||
expr->nVal = src1->nVal == src2->nVal;
|
||||
expr->val = src1->val == src2->val;
|
||||
break;
|
||||
case RPN_LOGGT:
|
||||
expr->nVal = src1->nVal > src2->nVal;
|
||||
expr->val = src1->val > src2->val;
|
||||
break;
|
||||
case RPN_LOGLT:
|
||||
expr->nVal = src1->nVal < src2->nVal;
|
||||
expr->val = src1->val < src2->val;
|
||||
break;
|
||||
case RPN_LOGGE:
|
||||
expr->nVal = src1->nVal >= src2->nVal;
|
||||
expr->val = src1->val >= src2->val;
|
||||
break;
|
||||
case RPN_LOGLE:
|
||||
expr->nVal = src1->nVal <= src2->nVal;
|
||||
expr->val = src1->val <= src2->val;
|
||||
break;
|
||||
case RPN_LOGNE:
|
||||
expr->nVal = src1->nVal != src2->nVal;
|
||||
expr->val = src1->val != src2->val;
|
||||
break;
|
||||
case RPN_ADD:
|
||||
expr->nVal = uleft + uright;
|
||||
expr->val = uleft + uright;
|
||||
break;
|
||||
case RPN_SUB:
|
||||
expr->nVal = uleft - uright;
|
||||
expr->val = uleft - uright;
|
||||
break;
|
||||
case RPN_XOR:
|
||||
expr->nVal = src1->nVal ^ src2->nVal;
|
||||
expr->val = src1->val ^ src2->val;
|
||||
break;
|
||||
case RPN_OR:
|
||||
expr->nVal = src1->nVal | src2->nVal;
|
||||
expr->val = src1->val | src2->val;
|
||||
break;
|
||||
case RPN_AND:
|
||||
expr->nVal = src1->nVal & src2->nVal;
|
||||
expr->val = src1->val & src2->val;
|
||||
break;
|
||||
case RPN_SHL:
|
||||
if (src2->nVal < 0)
|
||||
if (src2->val < 0)
|
||||
warning(WARNING_SHIFT_AMOUNT,
|
||||
"Shifting left by negative amount %" PRId32 "\n",
|
||||
src2->nVal);
|
||||
src2->val);
|
||||
|
||||
if (src2->nVal >= 32)
|
||||
if (src2->val >= 32)
|
||||
warning(WARNING_SHIFT_AMOUNT,
|
||||
"Shifting left by large amount %" PRId32 "\n",
|
||||
src2->nVal);
|
||||
src2->val);
|
||||
|
||||
expr->nVal = op_shift_left(src1->nVal, src2->nVal);
|
||||
expr->val = op_shift_left(src1->val, src2->val);
|
||||
break;
|
||||
case RPN_SHR:
|
||||
if (src1->nVal < 0)
|
||||
if (src1->val < 0)
|
||||
warning(WARNING_SHIFT, "Shifting right negative value %"
|
||||
PRId32 "\n",
|
||||
src1->nVal);
|
||||
src1->val);
|
||||
|
||||
if (src2->nVal < 0)
|
||||
if (src2->val < 0)
|
||||
warning(WARNING_SHIFT_AMOUNT,
|
||||
"Shifting right by negative amount %" PRId32 "\n",
|
||||
src2->nVal);
|
||||
src2->val);
|
||||
|
||||
if (src2->nVal >= 32)
|
||||
if (src2->val >= 32)
|
||||
warning(WARNING_SHIFT_AMOUNT,
|
||||
"Shifting right by large amount %" PRId32 "\n",
|
||||
src2->nVal);
|
||||
src2->val);
|
||||
|
||||
expr->nVal = op_shift_right(src1->nVal, src2->nVal);
|
||||
expr->val = op_shift_right(src1->val, src2->val);
|
||||
break;
|
||||
case RPN_MUL:
|
||||
expr->nVal = uleft * uright;
|
||||
expr->val = uleft * uright;
|
||||
break;
|
||||
case RPN_DIV:
|
||||
if (src2->nVal == 0)
|
||||
if (src2->val == 0)
|
||||
fatalerror("Division by zero\n");
|
||||
|
||||
if (src1->nVal == INT32_MIN && src2->nVal == -1) {
|
||||
if (src1->val == INT32_MIN && src2->val == -1) {
|
||||
warning(WARNING_DIV, "Division of %" PRId32 " by -1 yields %"
|
||||
PRId32 "\n", INT32_MIN, INT32_MIN);
|
||||
expr->nVal = INT32_MIN;
|
||||
expr->val = INT32_MIN;
|
||||
} else {
|
||||
expr->nVal = op_divide(src1->nVal, src2->nVal);
|
||||
expr->val = op_divide(src1->val, src2->val);
|
||||
}
|
||||
break;
|
||||
case RPN_MOD:
|
||||
if (src2->nVal == 0)
|
||||
if (src2->val == 0)
|
||||
fatalerror("Modulo by zero\n");
|
||||
|
||||
if (src1->nVal == INT32_MIN && src2->nVal == -1)
|
||||
expr->nVal = 0;
|
||||
if (src1->val == INT32_MIN && src2->val == -1)
|
||||
expr->val = 0;
|
||||
else
|
||||
expr->nVal = op_modulo(src1->nVal, src2->nVal);
|
||||
expr->val = op_modulo(src1->val, src2->val);
|
||||
break;
|
||||
case RPN_EXP:
|
||||
if (src2->nVal < 0)
|
||||
if (src2->val < 0)
|
||||
fatalerror("Exponentiation by negative power\n");
|
||||
|
||||
if (src1->nVal == INT32_MIN && src2->nVal == -1)
|
||||
expr->nVal = 0;
|
||||
if (src1->val == INT32_MIN && src2->val == -1)
|
||||
expr->val = 0;
|
||||
else
|
||||
expr->nVal = op_exponent(src1->nVal, src2->nVal);
|
||||
expr->val = op_exponent(src1->val, src2->val);
|
||||
break;
|
||||
|
||||
case RPN_UNSUB:
|
||||
@@ -437,20 +437,20 @@ void rpn_BinaryOp(enum RPNCommand op, struct Expression *expr,
|
||||
struct Symbol const *symbol1 = rpn_SymbolOf(src1);
|
||||
struct Symbol const *symbol2 = rpn_SymbolOf(src2);
|
||||
|
||||
expr->nVal = sym_GetValue(symbol1) - sym_GetValue(symbol2);
|
||||
expr->val = sym_GetValue(symbol1) - sym_GetValue(symbol2);
|
||||
expr->isKnown = true;
|
||||
} else {
|
||||
/* If it's not known, start computing the RPN expression */
|
||||
|
||||
/* Convert the left-hand expression if it's constant */
|
||||
if (src1->isKnown) {
|
||||
uint32_t lval = src1->nVal;
|
||||
uint32_t lval = src1->val;
|
||||
uint8_t bytes[] = {RPN_CONST, lval, lval >> 8,
|
||||
lval >> 16, lval >> 24};
|
||||
expr->nRPNPatchSize = sizeof(bytes);
|
||||
expr->tRPN = NULL;
|
||||
expr->nRPNCapacity = 0;
|
||||
expr->nRPNLength = 0;
|
||||
expr->rpnPatchSize = sizeof(bytes);
|
||||
expr->rpn = NULL;
|
||||
expr->rpnCapacity = 0;
|
||||
expr->rpnLength = 0;
|
||||
memcpy(reserveSpace(expr, sizeof(bytes)), bytes,
|
||||
sizeof(bytes));
|
||||
|
||||
@@ -459,21 +459,21 @@ void rpn_BinaryOp(enum RPNCommand op, struct Expression *expr,
|
||||
free(src1->reason);
|
||||
} else {
|
||||
/* Otherwise just reuse its RPN buffer */
|
||||
expr->nRPNPatchSize = src1->nRPNPatchSize;
|
||||
expr->tRPN = src1->tRPN;
|
||||
expr->nRPNCapacity = src1->nRPNCapacity;
|
||||
expr->nRPNLength = src1->nRPNLength;
|
||||
expr->rpnPatchSize = src1->rpnPatchSize;
|
||||
expr->rpn = src1->rpn;
|
||||
expr->rpnCapacity = src1->rpnCapacity;
|
||||
expr->rpnLength = src1->rpnLength;
|
||||
expr->reason = src1->reason;
|
||||
free(src2->reason);
|
||||
}
|
||||
|
||||
/* Now, merge the right expression into the left one */
|
||||
uint8_t *ptr = src2->tRPN; /* Pointer to the right RPN */
|
||||
uint32_t len = src2->nRPNLength; /* Size of the right RPN */
|
||||
uint32_t patchSize = src2->nRPNPatchSize;
|
||||
uint8_t *ptr = src2->rpn; /* Pointer to the right RPN */
|
||||
uint32_t len = src2->rpnLength; /* Size of the right RPN */
|
||||
uint32_t patchSize = src2->rpnPatchSize;
|
||||
|
||||
/* If the right expression is constant, merge a shim instead */
|
||||
uint32_t rval = src2->nVal;
|
||||
uint32_t rval = src2->val;
|
||||
uint8_t bytes[] = {RPN_CONST, rval, rval >> 8, rval >> 16,
|
||||
rval >> 24};
|
||||
if (src2->isKnown) {
|
||||
@@ -487,8 +487,8 @@ void rpn_BinaryOp(enum RPNCommand op, struct Expression *expr,
|
||||
memcpy(buf, ptr, len);
|
||||
buf[len] = op;
|
||||
|
||||
free(src2->tRPN); /* If there was none, this is `free(NULL)` */
|
||||
expr->nRPNPatchSize += patchSize + 1;
|
||||
free(src2->rpn); /* If there was none, this is `free(NULL)` */
|
||||
expr->rpnPatchSize += patchSize + 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -498,11 +498,11 @@ void rpn_HIGH(struct Expression *expr, const struct Expression *src)
|
||||
expr->isSymbol = false;
|
||||
|
||||
if (rpn_isKnown(expr)) {
|
||||
expr->nVal = (uint32_t)expr->nVal >> 8 & 0xFF;
|
||||
expr->val = (uint32_t)expr->val >> 8 & 0xFF;
|
||||
} else {
|
||||
uint8_t bytes[] = {RPN_CONST, 8, 0, 0, 0, RPN_SHR,
|
||||
RPN_CONST, 0xFF, 0, 0, 0, RPN_AND};
|
||||
expr->nRPNPatchSize += sizeof(bytes);
|
||||
expr->rpnPatchSize += sizeof(bytes);
|
||||
memcpy(reserveSpace(expr, sizeof(bytes)), bytes, sizeof(bytes));
|
||||
}
|
||||
}
|
||||
@@ -513,11 +513,11 @@ void rpn_LOW(struct Expression *expr, const struct Expression *src)
|
||||
expr->isSymbol = false;
|
||||
|
||||
if (rpn_isKnown(expr)) {
|
||||
expr->nVal = expr->nVal & 0xFF;
|
||||
expr->val = expr->val & 0xFF;
|
||||
} else {
|
||||
uint8_t bytes[] = {RPN_CONST, 0xFF, 0, 0, 0, RPN_AND};
|
||||
|
||||
expr->nRPNPatchSize += sizeof(bytes);
|
||||
expr->rpnPatchSize += sizeof(bytes);
|
||||
memcpy(reserveSpace(expr, sizeof(bytes)), bytes, sizeof(bytes));
|
||||
}
|
||||
}
|
||||
@@ -525,7 +525,7 @@ void rpn_LOW(struct Expression *expr, const struct Expression *src)
|
||||
void rpn_ISCONST(struct Expression *expr, const struct Expression *src)
|
||||
{
|
||||
rpn_Init(expr);
|
||||
expr->nVal = rpn_isKnown(src);
|
||||
expr->val = rpn_isKnown(src);
|
||||
expr->isKnown = true;
|
||||
expr->isSymbol = false;
|
||||
}
|
||||
@@ -536,9 +536,9 @@ void rpn_UNNEG(struct Expression *expr, const struct Expression *src)
|
||||
expr->isSymbol = false;
|
||||
|
||||
if (rpn_isKnown(expr)) {
|
||||
expr->nVal = -(uint32_t)expr->nVal;
|
||||
expr->val = -(uint32_t)expr->val;
|
||||
} else {
|
||||
expr->nRPNPatchSize++;
|
||||
expr->rpnPatchSize++;
|
||||
*reserveSpace(expr, 1) = RPN_UNSUB;
|
||||
}
|
||||
}
|
||||
@@ -549,9 +549,9 @@ void rpn_UNNOT(struct Expression *expr, const struct Expression *src)
|
||||
expr->isSymbol = false;
|
||||
|
||||
if (rpn_isKnown(expr)) {
|
||||
expr->nVal = ~expr->nVal;
|
||||
expr->val = ~expr->val;
|
||||
} else {
|
||||
expr->nRPNPatchSize++;
|
||||
expr->rpnPatchSize++;
|
||||
*reserveSpace(expr, 1) = RPN_UNNOT;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ struct UnionStackEntry {
|
||||
*/
|
||||
static void checksection(void)
|
||||
{
|
||||
if (pCurrentSection == NULL)
|
||||
if (currentSection == NULL)
|
||||
fatalerror("Code generation before SECTION directive\n");
|
||||
}
|
||||
|
||||
@@ -55,9 +55,9 @@ static void checkcodesection(void)
|
||||
{
|
||||
checksection();
|
||||
|
||||
if (!sect_HasData(pCurrentSection->type))
|
||||
if (!sect_HasData(currentSection->type))
|
||||
fatalerror("Section '%s' cannot contain code or data (not ROM0 or ROMX)\n",
|
||||
pCurrentSection->name);
|
||||
currentSection->name);
|
||||
}
|
||||
|
||||
static void checkSectionSize(struct Section const *sect, uint32_t size)
|
||||
@@ -80,14 +80,14 @@ static void reserveSpace(uint32_t delta_size)
|
||||
* files or trying to allocate too much memory.
|
||||
* A check at the linking stage is still necessary.
|
||||
*/
|
||||
checkSectionSize(pCurrentSection, curOffset + loadOffset + delta_size);
|
||||
checkSectionSize(currentSection, curOffset + loadOffset + delta_size);
|
||||
if (currentLoadSection)
|
||||
checkSectionSize(currentLoadSection, curOffset + delta_size);
|
||||
}
|
||||
|
||||
struct Section *out_FindSectionByName(const char *name)
|
||||
{
|
||||
for (struct Section *sect = pSectionList; sect; sect = sect->next) {
|
||||
for (struct Section *sect = sectionList; sect; sect = sect->next) {
|
||||
if (strcmp(name, sect->name) == 0)
|
||||
return sect;
|
||||
}
|
||||
@@ -358,8 +358,8 @@ static struct Section *getSection(char const *name, enum SectionType type, uint3
|
||||
} else {
|
||||
sect = createSection(name, type, org, bank, alignment, alignOffset, mod);
|
||||
// Add the new section to the list (order doesn't matter)
|
||||
sect->next = pSectionList;
|
||||
pSectionList = sect;
|
||||
sect->next = sectionList;
|
||||
sectionList = sect;
|
||||
}
|
||||
|
||||
return sect;
|
||||
@@ -394,7 +394,7 @@ void out_NewSection(char const *name, uint32_t type, uint32_t org,
|
||||
|
||||
changeSection();
|
||||
curOffset = mod == SECTION_UNION ? 0 : sect->size;
|
||||
pCurrentSection = sect;
|
||||
currentSection = sect;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -433,7 +433,7 @@ void out_EndLoadSection(void)
|
||||
|
||||
struct Section *sect_GetSymbolSection(void)
|
||||
{
|
||||
return currentLoadSection ? currentLoadSection : pCurrentSection;
|
||||
return currentLoadSection ? currentLoadSection : currentSection;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -477,15 +477,15 @@ void sect_AlignPC(uint8_t alignment, uint16_t offset)
|
||||
static void growSection(uint32_t growth)
|
||||
{
|
||||
curOffset += growth;
|
||||
if (curOffset + loadOffset > pCurrentSection->size)
|
||||
pCurrentSection->size = curOffset + loadOffset;
|
||||
if (curOffset + loadOffset > currentSection->size)
|
||||
currentSection->size = curOffset + loadOffset;
|
||||
if (currentLoadSection && curOffset > currentLoadSection->size)
|
||||
currentLoadSection->size = curOffset;
|
||||
}
|
||||
|
||||
static void writebyte(uint8_t byte)
|
||||
{
|
||||
pCurrentSection->data[sect_GetOutputOffset()] = byte;
|
||||
currentSection->data[sect_GetOutputOffset()] = byte;
|
||||
growSection(1);
|
||||
}
|
||||
|
||||
@@ -510,9 +510,9 @@ static void createPatch(enum PatchType type, struct Expression const *expr, uint
|
||||
|
||||
void sect_StartUnion(void)
|
||||
{
|
||||
if (!pCurrentSection)
|
||||
if (!currentSection)
|
||||
fatalerror("UNIONs must be inside a SECTION\n");
|
||||
if (sect_HasData(pCurrentSection->type))
|
||||
if (sect_HasData(currentSection->type))
|
||||
fatalerror("Cannot use UNION inside of ROM0 or ROMX sections\n");
|
||||
struct UnionStackEntry *entry = malloc(sizeof(*entry));
|
||||
|
||||
@@ -604,11 +604,11 @@ void out_Skip(int32_t skip, bool ds)
|
||||
checksection();
|
||||
reserveSpace(skip);
|
||||
|
||||
if (!ds && sect_HasData(pCurrentSection->type))
|
||||
if (!ds && sect_HasData(currentSection->type))
|
||||
warning(WARNING_EMPTY_DATA_DIRECTIVE, "%s directive without data in ROM\n",
|
||||
(skip == 4) ? "DL" : (skip == 2) ? "DW" : "DB");
|
||||
|
||||
if (!sect_HasData(pCurrentSection->type)) {
|
||||
if (!sect_HasData(currentSection->type)) {
|
||||
growSection(skip);
|
||||
} else {
|
||||
checkcodesection();
|
||||
@@ -642,7 +642,7 @@ void out_RelByte(struct Expression *expr, uint32_t pcShift)
|
||||
createPatch(PATCHTYPE_BYTE, expr, pcShift);
|
||||
writebyte(0);
|
||||
} else {
|
||||
writebyte(expr->nVal);
|
||||
writebyte(expr->val);
|
||||
}
|
||||
rpn_Free(expr);
|
||||
}
|
||||
@@ -663,7 +663,7 @@ void out_RelBytes(uint32_t n, struct Expression *exprs, size_t size)
|
||||
createPatch(PATCHTYPE_BYTE, expr, i);
|
||||
writebyte(0);
|
||||
} else {
|
||||
writebyte(expr->nVal);
|
||||
writebyte(expr->val);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -684,7 +684,7 @@ void out_RelWord(struct Expression *expr, uint32_t pcShift)
|
||||
createPatch(PATCHTYPE_WORD, expr, pcShift);
|
||||
writeword(0);
|
||||
} else {
|
||||
writeword(expr->nVal);
|
||||
writeword(expr->val);
|
||||
}
|
||||
rpn_Free(expr);
|
||||
}
|
||||
@@ -702,7 +702,7 @@ void out_RelLong(struct Expression *expr, uint32_t pcShift)
|
||||
createPatch(PATCHTYPE_LONG, expr, pcShift);
|
||||
writelong(0);
|
||||
} else {
|
||||
writelong(expr->nVal);
|
||||
writelong(expr->val);
|
||||
}
|
||||
rpn_Free(expr);
|
||||
}
|
||||
@@ -761,10 +761,10 @@ void out_BinaryFile(char const *s, int32_t startPos)
|
||||
free(fullPath);
|
||||
|
||||
if (!f) {
|
||||
if (oGeneratedMissingIncludes) {
|
||||
if (generatedMissingIncludes) {
|
||||
if (verbose)
|
||||
printf("Aborting (-MG) on INCBIN file '%s' (%s)\n", s, strerror(errno));
|
||||
oFailedOnMissingInclude = true;
|
||||
failedOnMissingInclude = true;
|
||||
return;
|
||||
}
|
||||
error("Error opening INCBIN file '%s': %s\n", s, strerror(errno));
|
||||
@@ -830,10 +830,10 @@ void out_BinaryFileSlice(char const *s, int32_t start_pos, int32_t length)
|
||||
free(fullPath);
|
||||
|
||||
if (!f) {
|
||||
if (oGeneratedMissingIncludes) {
|
||||
if (generatedMissingIncludes) {
|
||||
if (verbose)
|
||||
printf("Aborting (-MG) on INCBIN file '%s' (%s)\n", s, strerror(errno));
|
||||
oFailedOnMissingInclude = true;
|
||||
failedOnMissingInclude = true;
|
||||
} else {
|
||||
error("Error opening INCBIN file '%s': %s\n", s, strerror(errno));
|
||||
}
|
||||
@@ -897,7 +897,7 @@ void out_PushSection(void)
|
||||
|
||||
if (sect == NULL)
|
||||
fatalerror("No memory for section stack: %s\n", strerror(errno));
|
||||
sect->section = pCurrentSection;
|
||||
sect->section = currentSection;
|
||||
sect->scope = sym_GetCurrentSymbolScope();
|
||||
sect->offset = curOffset;
|
||||
sect->next = sectionStack;
|
||||
@@ -917,7 +917,7 @@ void out_PopSection(void)
|
||||
|
||||
sect = sectionStack;
|
||||
changeSection();
|
||||
pCurrentSection = sect->section;
|
||||
currentSection = sect->section;
|
||||
sym_SetCurrentSymbolScope(sect->scope);
|
||||
curOffset = sect->offset;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user