mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Use only one pass
This commit is contained in:
@@ -28,7 +28,6 @@
|
||||
extern int32_t nLineNo;
|
||||
extern uint32_t nTotalLines;
|
||||
extern uint32_t nPC;
|
||||
extern uint32_t nPass;
|
||||
extern uint32_t nIFDepth;
|
||||
extern bool skipElif;
|
||||
extern uint32_t nUnionDepth;
|
||||
|
||||
@@ -18,11 +18,9 @@ struct Expression {
|
||||
uint32_t nRPNLength;
|
||||
uint32_t nRPNOut;
|
||||
uint32_t isReloc;
|
||||
uint32_t isPCRel;
|
||||
};
|
||||
|
||||
uint32_t rpn_isReloc(const struct Expression *expr);
|
||||
uint32_t rpn_isPCRelative(const struct Expression *expr);
|
||||
void rpn_Symbol(struct Expression *expr, char *tzSym);
|
||||
void rpn_Number(struct Expression *expr, uint32_t i);
|
||||
void rpn_LOGNOT(struct Expression *expr, const struct Expression *src);
|
||||
|
||||
@@ -38,8 +38,6 @@ struct sSymbol {
|
||||
#define SYMF_SET 0x004
|
||||
/* Symbol should be exported */
|
||||
#define SYMF_EXPORT 0x008
|
||||
/* Symbol is imported, it's value is unknown */
|
||||
#define SYMF_IMPORT 0x010
|
||||
/* Symbol is a local symbol */
|
||||
#define SYMF_LOCAL 0x020
|
||||
/* Symbol has been defined, not only referenced */
|
||||
@@ -53,8 +51,6 @@ struct sSymbol {
|
||||
|
||||
uint32_t calchash(char *s);
|
||||
void sym_SetExportAll(uint8_t set);
|
||||
void sym_PrepPass1(void);
|
||||
void sym_PrepPass2(void);
|
||||
void sym_AddLocalReloc(char *tzSym);
|
||||
void sym_AddReloc(char *tzSym);
|
||||
void sym_Export(char *tzSym);
|
||||
@@ -72,16 +68,15 @@ void sym_Init(void);
|
||||
uint32_t sym_GetConstantValue(char *s);
|
||||
uint32_t sym_isConstant(char *s);
|
||||
struct sSymbol *sym_FindSymbol(char *tzName);
|
||||
void sym_Global(char *tzSym);
|
||||
char *sym_FindMacroArg(int32_t i);
|
||||
char *sym_GetStringValue(char *tzSym);
|
||||
void sym_UseCurrentMacroArgs(void);
|
||||
void sym_SetMacroArgID(uint32_t nMacroCount);
|
||||
uint32_t sym_isString(char *tzSym);
|
||||
void sym_AddMacro(char *tzSym);
|
||||
void sym_AddForwardRef(char *tzSym);
|
||||
void sym_ShiftCurrentMacroArgs(void);
|
||||
void sym_AddString(char *tzSym, char *tzValue);
|
||||
uint32_t sym_GetValue(char *s);
|
||||
uint32_t sym_GetDefinedValue(char *s);
|
||||
uint32_t sym_isDefined(char *tzName);
|
||||
void sym_Purge(char *tzName);
|
||||
|
||||
@@ -799,7 +799,7 @@ ds : T_POP_DS uconst
|
||||
;
|
||||
|
||||
db : T_POP_DB constlist_8bit_entry comma constlist_8bit {
|
||||
if ((nPass == 1) && (nListCountEmpty > 0)) {
|
||||
if (nListCountEmpty > 0) {
|
||||
warning("Empty entry in list of 8-bit elements (treated as 0).");
|
||||
}
|
||||
}
|
||||
@@ -807,7 +807,7 @@ db : T_POP_DB constlist_8bit_entry comma constlist_8bit {
|
||||
;
|
||||
|
||||
dw : T_POP_DW constlist_16bit_entry comma constlist_16bit {
|
||||
if ((nPass == 1) && (nListCountEmpty > 0)) {
|
||||
if (nListCountEmpty > 0) {
|
||||
warning("Empty entry in list of 16-bit elements (treated as 0).");
|
||||
}
|
||||
}
|
||||
@@ -815,7 +815,7 @@ dw : T_POP_DW constlist_16bit_entry comma constlist_16bit {
|
||||
;
|
||||
|
||||
dl : T_POP_DL constlist_32bit_entry comma constlist_32bit {
|
||||
if ((nPass == 1) && (nListCountEmpty > 0)) {
|
||||
if (nListCountEmpty > 0) {
|
||||
warning("Empty entry in list of 32-bit elements (treated as 0).");
|
||||
}
|
||||
}
|
||||
@@ -852,7 +852,6 @@ import_list_entry : T_ID
|
||||
* This is done automatically if the label isn't found
|
||||
* in the list of defined symbols.
|
||||
*/
|
||||
if (nPass == 1)
|
||||
warning("IMPORT is a deprecated keyword with no effect: %s", $1);
|
||||
}
|
||||
;
|
||||
@@ -879,7 +878,7 @@ global_list : global_list_entry
|
||||
|
||||
global_list_entry : T_ID
|
||||
{
|
||||
sym_Global($1);
|
||||
sym_Export($1);
|
||||
}
|
||||
;
|
||||
|
||||
@@ -929,28 +928,24 @@ charmap : T_POP_CHARMAP string comma string
|
||||
|
||||
printt : T_POP_PRINTT string
|
||||
{
|
||||
if (nPass == 1)
|
||||
printf("%s", $2);
|
||||
}
|
||||
;
|
||||
|
||||
printv : T_POP_PRINTV const
|
||||
{
|
||||
if (nPass == 1)
|
||||
printf("$%X", constexpr_GetConstantValue(&$2));
|
||||
}
|
||||
;
|
||||
|
||||
printi : T_POP_PRINTI const
|
||||
{
|
||||
if (nPass == 1)
|
||||
printf("%d", constexpr_GetConstantValue(&$2));
|
||||
}
|
||||
;
|
||||
|
||||
printf : T_POP_PRINTF const
|
||||
{
|
||||
if (nPass == 1)
|
||||
math_Print(constexpr_GetConstantValue(&$2));
|
||||
}
|
||||
;
|
||||
@@ -1126,20 +1121,17 @@ relocconst : T_ID
|
||||
struct Expression sTemp, sOffset;
|
||||
|
||||
rpn_Symbol(&sTemp, $1);
|
||||
sTemp.nVal = sym_GetValue($1);
|
||||
|
||||
rpn_Number(&sOffset, nPCOffset);
|
||||
|
||||
rpn_SUB(&$$, &sTemp, &sOffset);
|
||||
} else {
|
||||
rpn_Symbol(&$$, $1);
|
||||
$$.nVal = sym_GetValue($1);
|
||||
}
|
||||
}
|
||||
| T_NUMBER
|
||||
{
|
||||
rpn_Number(&$$, $1);
|
||||
$$.nVal = $1;
|
||||
}
|
||||
| string
|
||||
{
|
||||
@@ -1149,7 +1141,6 @@ relocconst : T_ID
|
||||
|
||||
free(s);
|
||||
rpn_Number(&$$, r);
|
||||
$$.nVal = r;
|
||||
}
|
||||
| T_OP_LOGICNOT relocconst %prec NEG { rpn_LOGNOT(&$$, &$2); }
|
||||
| relocconst T_OP_LOGICOR relocconst { rpn_LOGOR(&$$, &$1, &$3); }
|
||||
@@ -1179,12 +1170,10 @@ relocconst : T_ID
|
||||
{
|
||||
/* '@' is also a T_ID, it is handled here. */
|
||||
rpn_BankSymbol(&$$, $3);
|
||||
$$.nVal = 0;
|
||||
}
|
||||
| T_OP_BANK '(' string ')'
|
||||
{
|
||||
rpn_BankSection(&$$, $3);
|
||||
$$.nVal = 0;
|
||||
}
|
||||
| T_OP_DEF {
|
||||
oDontExpandStrings = true;
|
||||
@@ -1637,7 +1626,6 @@ z80_jp : T_Z80_JP const_16bit
|
||||
| T_Z80_JP T_MODE_HL_IND
|
||||
{
|
||||
out_AbsByte(0xE9);
|
||||
if (nPass == 1)
|
||||
warning("'JP [HL]' is obsolete, use 'JP HL' instead.");
|
||||
}
|
||||
| T_Z80_JP T_MODE_HL
|
||||
@@ -1665,7 +1653,6 @@ z80_ldi : T_Z80_LDI T_MODE_HL_IND comma T_MODE_A
|
||||
| T_Z80_LDI T_MODE_A comma T_MODE_HL
|
||||
{
|
||||
out_AbsByte(0x0A | (2 << 4));
|
||||
if (nPass == 1)
|
||||
warning("'LDI A,HL' is obsolete, use 'LDI A,[HL]' or 'LD A,[HL+] instead.");
|
||||
}
|
||||
| T_Z80_LDI T_MODE_A comma T_MODE_HL_IND
|
||||
@@ -1681,7 +1668,6 @@ z80_ldd : T_Z80_LDD T_MODE_HL_IND comma T_MODE_A
|
||||
| T_Z80_LDD T_MODE_A comma T_MODE_HL
|
||||
{
|
||||
out_AbsByte(0x0A | (3 << 4));
|
||||
if (nPass == 1)
|
||||
warning("'LDD A,HL' is obsolete, use 'LDD A,[HL]' or 'LD A,[HL-] instead.");
|
||||
}
|
||||
| T_Z80_LDD T_MODE_A comma T_MODE_HL_IND
|
||||
|
||||
@@ -62,9 +62,6 @@ int32_t charmap_Add(char *input, uint8_t output)
|
||||
charmap = &globalCharmap;
|
||||
}
|
||||
|
||||
if (nPass == 2)
|
||||
return charmap->count;
|
||||
|
||||
if (charmap->count > MAXCHARMAPS || strlen(input) > CHARMAPLENGTH)
|
||||
return -1;
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ char **cldefines;
|
||||
|
||||
clock_t nStartClock, nEndClock;
|
||||
int32_t nLineNo;
|
||||
uint32_t nTotalLines, nPass, nPC, nIFDepth, nUnionDepth, nErrors;
|
||||
uint32_t nTotalLines, nPC, nIFDepth, nUnionDepth, nErrors;
|
||||
bool skipElif;
|
||||
uint32_t unionStart[128], unionSize[128];
|
||||
|
||||
@@ -432,21 +432,17 @@ int main(int argc, char *argv[])
|
||||
skipElif = true;
|
||||
nUnionDepth = 0;
|
||||
nPC = 0;
|
||||
nPass = 1;
|
||||
nErrors = 0;
|
||||
sym_PrepPass1();
|
||||
sym_Init();
|
||||
sym_SetExportAll(CurrentOptions.exportall);
|
||||
fstk_Init(tzMainfile);
|
||||
opt_ParseDefines();
|
||||
|
||||
if (CurrentOptions.verbose)
|
||||
printf("Pass 1...\n");
|
||||
|
||||
yy_set_state(LEX_STATE_NORMAL);
|
||||
opt_SetCurrentOptions(&DefaultOptions);
|
||||
|
||||
if (yyparse() != 0 || nErrors != 0)
|
||||
errx(1, "Assembly aborted in pass 1 (%ld errors)!", nErrors);
|
||||
errx(1, "Assembly aborted (%ld errors)!", nErrors);
|
||||
|
||||
if (nIFDepth != 0)
|
||||
errx(1, "Unterminated IF construct (%ld levels)!", nIFDepth);
|
||||
@@ -456,27 +452,6 @@ int main(int argc, char *argv[])
|
||||
nUnionDepth);
|
||||
}
|
||||
|
||||
nTotalLines = 0;
|
||||
nLineNo = 1;
|
||||
nIFDepth = 0;
|
||||
skipElif = true;
|
||||
nUnionDepth = 0;
|
||||
nPC = 0;
|
||||
nPass = 2;
|
||||
nErrors = 0;
|
||||
sym_PrepPass2();
|
||||
out_PrepPass2();
|
||||
fstk_Init(tzMainfile);
|
||||
yy_set_state(LEX_STATE_NORMAL);
|
||||
opt_SetCurrentOptions(&DefaultOptions);
|
||||
opt_ParseDefines();
|
||||
|
||||
if (CurrentOptions.verbose)
|
||||
printf("Pass 2...\n");
|
||||
|
||||
if (yyparse() != 0 || nErrors != 0)
|
||||
errx(1, "Assembly aborted in pass 2 (%ld errors)!", nErrors);
|
||||
|
||||
double timespent;
|
||||
|
||||
nEndClock = clock();
|
||||
|
||||
104
src/asm/output.c
104
src/asm/output.c
@@ -259,37 +259,46 @@ static void writesection(struct Section *pSect, FILE *f)
|
||||
*/
|
||||
static void writesymbol(struct sSymbol *pSym, FILE *f)
|
||||
{
|
||||
char symname[MAXSYMLEN * 2 + 1];
|
||||
uint32_t type;
|
||||
uint32_t offset;
|
||||
int32_t sectid;
|
||||
|
||||
if (pSym->nType & SYMF_IMPORT) {
|
||||
/* Symbol should be imported */
|
||||
strcpy(symname, pSym->tzName);
|
||||
if (!(pSym->nType & SYMF_DEFINED)) {
|
||||
if (pSym->nType & SYMF_LOCAL) {
|
||||
char *name = pSym->tzName;
|
||||
char *localPtr = strchr(name, '.');
|
||||
|
||||
if (localPtr)
|
||||
name = localPtr;
|
||||
errx(1, "%s(%u) : '%s' not defined",
|
||||
pSym->tzFileName, pSym->nFileLine, name);
|
||||
}
|
||||
type = SYM_IMPORT;
|
||||
} else if (pSym->nType & SYMF_EXPORT) {
|
||||
type = SYM_EXPORT;
|
||||
} else {
|
||||
type = SYM_LOCAL;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case SYM_LOCAL:
|
||||
offset = pSym->nValue;
|
||||
sectid = getsectid(pSym->pSection);
|
||||
break;
|
||||
case SYM_IMPORT:
|
||||
offset = 0;
|
||||
sectid = -1;
|
||||
type = SYM_IMPORT;
|
||||
} else {
|
||||
strcpy(symname, pSym->tzName);
|
||||
|
||||
if (pSym->nType & SYMF_EXPORT) {
|
||||
/* Symbol should be exported */
|
||||
type = SYM_EXPORT;
|
||||
break;
|
||||
case SYM_EXPORT:
|
||||
offset = pSym->nValue;
|
||||
if (pSym->nType & SYMF_CONST)
|
||||
sectid = -1;
|
||||
else
|
||||
sectid = getsectid(pSym->pSection);
|
||||
} else {
|
||||
/* Symbol is local to this file */
|
||||
type = SYM_LOCAL;
|
||||
offset = pSym->nValue;
|
||||
sectid = getsectid(pSym->pSection);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
fputstring(symname, f);
|
||||
fputstring(pSym->tzName, f);
|
||||
fputc(type, f);
|
||||
|
||||
if (type != SYM_IMPORT) {
|
||||
@@ -562,22 +571,6 @@ void out_WriteObject(void)
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
/*
|
||||
* Prepare for pass #2
|
||||
*/
|
||||
void out_PrepPass2(void)
|
||||
{
|
||||
struct Section *pSect;
|
||||
|
||||
pSect = pSectionList;
|
||||
while (pSect) {
|
||||
pSect->nPC = 0;
|
||||
pSect = pSect->pNext;
|
||||
}
|
||||
pCurrentSection = NULL;
|
||||
pSectionStack = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the objectfilename
|
||||
*/
|
||||
@@ -586,10 +579,6 @@ void out_SetFileName(char *s)
|
||||
tzObjectname = s;
|
||||
if (CurrentOptions.verbose)
|
||||
printf("Output filename %s\n", s);
|
||||
|
||||
pSectionList = NULL;
|
||||
pCurrentSection = NULL;
|
||||
pPatchSymbols = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -636,7 +625,6 @@ struct Section *out_FindSection(char *pzName, uint32_t secttype, int32_t org,
|
||||
pSect->pNext = NULL;
|
||||
pSect->pPatches = NULL;
|
||||
pSect->charmap = NULL;
|
||||
pPatchSymbols = NULL;
|
||||
|
||||
/* It is only needed to allocate memory for ROM sections. */
|
||||
if (secttype == SECT_ROM0 || secttype == SECT_ROMX) {
|
||||
@@ -705,9 +693,7 @@ void out_AbsByteBypassCheck(int32_t b)
|
||||
{
|
||||
checksectionoverflow(1);
|
||||
b &= 0xFF;
|
||||
if (nPass == 2)
|
||||
pCurrentSection->tData[nPC] = b;
|
||||
|
||||
pCurrentSection->nPC += 1;
|
||||
nPC += 1;
|
||||
pPCSymbol->nValue += 1;
|
||||
@@ -772,10 +758,8 @@ void out_RelByte(struct Expression *expr)
|
||||
checkcodesection();
|
||||
checksectionoverflow(1);
|
||||
if (rpn_isReloc(expr)) {
|
||||
if (nPass == 2) {
|
||||
pCurrentSection->tData[nPC] = 0;
|
||||
createpatch(PATCH_BYTE, expr);
|
||||
}
|
||||
pCurrentSection->nPC += 1;
|
||||
nPC += 1;
|
||||
pPCSymbol->nValue += 1;
|
||||
@@ -793,10 +777,8 @@ void out_AbsWord(int32_t b)
|
||||
checkcodesection();
|
||||
checksectionoverflow(2);
|
||||
b &= 0xFFFF;
|
||||
if (nPass == 2) {
|
||||
pCurrentSection->tData[nPC] = b & 0xFF;
|
||||
pCurrentSection->tData[nPC + 1] = b >> 8;
|
||||
}
|
||||
pCurrentSection->nPC += 2;
|
||||
nPC += 2;
|
||||
pPCSymbol->nValue += 2;
|
||||
@@ -808,17 +790,12 @@ void out_AbsWord(int32_t b)
|
||||
*/
|
||||
void out_RelWord(struct Expression *expr)
|
||||
{
|
||||
uint32_t b;
|
||||
|
||||
checkcodesection();
|
||||
checksectionoverflow(2);
|
||||
b = expr->nVal & 0xFFFF;
|
||||
if (rpn_isReloc(expr)) {
|
||||
if (nPass == 2) {
|
||||
pCurrentSection->tData[nPC] = b & 0xFF;
|
||||
pCurrentSection->tData[nPC + 1] = b >> 8;
|
||||
pCurrentSection->tData[nPC] = 0;
|
||||
pCurrentSection->tData[nPC + 1] = 0;
|
||||
createpatch(PATCH_WORD_L, expr);
|
||||
}
|
||||
pCurrentSection->nPC += 2;
|
||||
nPC += 2;
|
||||
pPCSymbol->nValue += 2;
|
||||
@@ -835,12 +812,10 @@ void out_AbsLong(int32_t b)
|
||||
{
|
||||
checkcodesection();
|
||||
checksectionoverflow(sizeof(int32_t));
|
||||
if (nPass == 2) {
|
||||
pCurrentSection->tData[nPC] = b & 0xFF;
|
||||
pCurrentSection->tData[nPC + 1] = b >> 8;
|
||||
pCurrentSection->tData[nPC + 2] = b >> 16;
|
||||
pCurrentSection->tData[nPC + 3] = b >> 24;
|
||||
}
|
||||
pCurrentSection->nPC += 4;
|
||||
nPC += 4;
|
||||
pPCSymbol->nValue += 4;
|
||||
@@ -852,19 +827,14 @@ void out_AbsLong(int32_t b)
|
||||
*/
|
||||
void out_RelLong(struct Expression *expr)
|
||||
{
|
||||
int32_t b;
|
||||
|
||||
checkcodesection();
|
||||
checksectionoverflow(4);
|
||||
b = expr->nVal;
|
||||
if (rpn_isReloc(expr)) {
|
||||
if (nPass == 2) {
|
||||
pCurrentSection->tData[nPC] = b & 0xFF;
|
||||
pCurrentSection->tData[nPC + 1] = b >> 8;
|
||||
pCurrentSection->tData[nPC + 2] = b >> 16;
|
||||
pCurrentSection->tData[nPC + 3] = b >> 24;
|
||||
pCurrentSection->tData[nPC] = 0;
|
||||
pCurrentSection->tData[nPC + 1] = 0;
|
||||
pCurrentSection->tData[nPC + 2] = 0;
|
||||
pCurrentSection->tData[nPC + 3] = 0;
|
||||
createpatch(PATCH_LONG_L, expr);
|
||||
}
|
||||
pCurrentSection->nPC += 4;
|
||||
nPC += 4;
|
||||
pPCSymbol->nValue += 4;
|
||||
@@ -884,10 +854,8 @@ void out_PCRelByte(struct Expression *expr)
|
||||
checksectionoverflow(1);
|
||||
|
||||
/* Always let the linker calculate the offset. */
|
||||
if (nPass == 2) {
|
||||
pCurrentSection->tData[nPC] = 0;
|
||||
createpatch(PATCH_BYTE_JR, expr);
|
||||
}
|
||||
pCurrentSection->nPC += 1;
|
||||
nPC += 1;
|
||||
pPCSymbol->nValue += 1;
|
||||
@@ -915,13 +883,12 @@ void out_BinaryFile(char *s)
|
||||
checkcodesection();
|
||||
checksectionoverflow(fsize);
|
||||
|
||||
if (nPass == 2) {
|
||||
int32_t dest = nPC;
|
||||
int32_t todo = fsize;
|
||||
|
||||
while (todo--)
|
||||
pCurrentSection->tData[dest++] = fgetc(f);
|
||||
}
|
||||
|
||||
pCurrentSection->nPC += fsize;
|
||||
nPC += fsize;
|
||||
pPCSymbol->nValue += fsize;
|
||||
@@ -958,13 +925,12 @@ void out_BinaryFileSlice(char *s, int32_t start_pos, int32_t length)
|
||||
checkcodesection();
|
||||
checksectionoverflow(length);
|
||||
|
||||
if (nPass == 2) {
|
||||
int32_t dest = nPC;
|
||||
int32_t todo = length;
|
||||
|
||||
while (todo--)
|
||||
pCurrentSection->tData[dest++] = fgetc(f);
|
||||
}
|
||||
|
||||
pCurrentSection->nPC += length;
|
||||
nPC += length;
|
||||
pPCSymbol->nValue += length;
|
||||
|
||||
@@ -55,7 +55,6 @@ void mergetwoexpressions(struct Expression *expr, const struct Expression *src1,
|
||||
|
||||
expr->nRPNLength = len;
|
||||
expr->isReloc = src1->isReloc || src2->isReloc;
|
||||
expr->isPCRel = src1->isPCRel || src2->isPCRel;
|
||||
}
|
||||
|
||||
#define joinexpr() mergetwoexpressions(expr, src1, src2)
|
||||
@@ -91,7 +90,6 @@ void rpn_Init(struct Expression *expr)
|
||||
expr->nRPNLength = 0;
|
||||
expr->nRPNOut = 0;
|
||||
expr->isReloc = 0;
|
||||
expr->isPCRel = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -122,14 +120,6 @@ uint32_t rpn_isReloc(const struct Expression *expr)
|
||||
return expr->isReloc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine if the current expression can be pc-relative
|
||||
*/
|
||||
uint32_t rpn_isPCRelative(const struct Expression *expr)
|
||||
{
|
||||
return expr->isPCRel;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add symbols, constants and operators to expression
|
||||
*/
|
||||
@@ -147,15 +137,8 @@ void rpn_Number(struct Expression *expr, uint32_t i)
|
||||
void rpn_Symbol(struct Expression *expr, char *tzSym)
|
||||
{
|
||||
if (!sym_isConstant(tzSym)) {
|
||||
const struct sSymbol *psym;
|
||||
|
||||
rpn_Init(expr);
|
||||
|
||||
psym = sym_FindSymbol(tzSym);
|
||||
|
||||
if (psym == NULL || psym->pSection == pCurrentSection
|
||||
|| psym->pSection == NULL)
|
||||
expr->isPCRel = 1;
|
||||
sym_AddForwardRef(tzSym);
|
||||
expr->isReloc = 1;
|
||||
pushbyte(expr, RPN_SYM);
|
||||
while (*tzSym)
|
||||
@@ -189,13 +172,7 @@ void rpn_BankSymbol(struct Expression *expr, char *tzSym)
|
||||
|
||||
if (!sym_isConstant(tzSym)) {
|
||||
rpn_Init(expr);
|
||||
|
||||
/*
|
||||
* Check that the symbol exists by evaluating and discarding the
|
||||
* value.
|
||||
*/
|
||||
sym_GetValue(tzSym);
|
||||
|
||||
sym_AddForwardRef(tzSym);
|
||||
expr->isReloc = 1;
|
||||
pushbyte(expr, RPN_BANK_SYM);
|
||||
while (*tzSym)
|
||||
|
||||
175
src/asm/symbol.c
175
src/asm/symbol.c
@@ -358,50 +358,6 @@ uint32_t sym_GetConstantValue(char *s)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a symbols value... "estimated" if not defined yet
|
||||
*/
|
||||
uint32_t sym_GetValue(char *s)
|
||||
{
|
||||
struct sSymbol *psym, *pscope;
|
||||
|
||||
if (*s == '.')
|
||||
pscope = pScope;
|
||||
else
|
||||
pscope = NULL;
|
||||
|
||||
psym = findsymbol(s, pscope);
|
||||
|
||||
if (psym != NULL) {
|
||||
if (psym->nType & SYMF_DEFINED) {
|
||||
if (psym->nType & (SYMF_MACRO | SYMF_STRING))
|
||||
yyerror("'%s' is a macro or string symbol", s);
|
||||
|
||||
return getvaluefield(psym);
|
||||
}
|
||||
|
||||
if (nPass == 2) {
|
||||
/*
|
||||
* Assume undefined symbols are imported from
|
||||
* somwehere else
|
||||
*/
|
||||
psym->nType |= SYMF_IMPORT;
|
||||
}
|
||||
|
||||
/* 0x80 seems like a good default value... */
|
||||
return 0x80;
|
||||
}
|
||||
|
||||
if (nPass == 1) {
|
||||
createsymbol(s);
|
||||
return 0x80;
|
||||
}
|
||||
|
||||
yyerror("'%s' not defined", s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a defined symbols value... aborts if not defined yet
|
||||
*/
|
||||
@@ -549,8 +505,6 @@ struct sSymbol *sym_FindMacro(char *s)
|
||||
*/
|
||||
void sym_AddEqu(char *tzSym, int32_t value)
|
||||
{
|
||||
if ((nPass == 1) || ((nPass == 2) && (sym_isDefined(tzSym) == 0))) {
|
||||
/* only add equated symbols in pass 1 */
|
||||
struct sSymbol *nsym = findsymbol(tzSym, NULL);
|
||||
|
||||
if (nsym != NULL) {
|
||||
@@ -568,7 +522,7 @@ void sym_AddEqu(char *tzSym, int32_t value)
|
||||
nsym->pScope = NULL;
|
||||
updateSymbolFilename(nsym);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -669,10 +623,6 @@ void sym_AddLocalReloc(char *tzSym)
|
||||
void sym_AddReloc(char *tzSym)
|
||||
{
|
||||
struct sSymbol *scope = NULL;
|
||||
|
||||
if ((nPass == 1)
|
||||
|| ((nPass == 2) && (sym_isDefined(tzSym) == 0))) {
|
||||
/* only add reloc symbols in pass 1 */
|
||||
struct sSymbol *nsym;
|
||||
char *localPtr = strchr(tzSym, '.');
|
||||
|
||||
@@ -721,7 +671,7 @@ void sym_AddReloc(char *tzSym)
|
||||
|
||||
updateSymbolFilename(nsym);
|
||||
}
|
||||
}
|
||||
|
||||
pScope = findsymbol(tzSym, scope);
|
||||
}
|
||||
|
||||
@@ -734,10 +684,6 @@ void sym_AddReloc(char *tzSym)
|
||||
*/
|
||||
int32_t sym_IsRelocDiffDefined(char *tzSym1, char *tzSym2)
|
||||
{
|
||||
/* Do nothing the first pass. */
|
||||
if (nPass != 2)
|
||||
return 1;
|
||||
|
||||
const struct sSymbol *nsym1 = sym_FindSymbol(tzSym1);
|
||||
const struct sSymbol *nsym2 = sym_FindSymbol(tzSym2);
|
||||
|
||||
@@ -781,8 +727,6 @@ int32_t sym_IsRelocDiffDefined(char *tzSym1, char *tzSym2)
|
||||
*/
|
||||
void sym_Export(char *tzSym)
|
||||
{
|
||||
if (nPass == 1) {
|
||||
/* only export symbols in pass 1 */
|
||||
struct sSymbol *nsym = sym_FindSymbol(tzSym);
|
||||
|
||||
if (nsym == NULL)
|
||||
@@ -790,37 +734,6 @@ void sym_Export(char *tzSym)
|
||||
|
||||
if (nsym)
|
||||
nsym->nType |= SYMF_EXPORT;
|
||||
} else {
|
||||
const struct sSymbol *nsym = sym_FindSymbol(tzSym);
|
||||
|
||||
if (nsym != NULL) {
|
||||
if (nsym->nType & SYMF_DEFINED)
|
||||
return;
|
||||
}
|
||||
yyerror("'%s' not defined", tzSym);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Globalize a symbol (export if defined, import if not)
|
||||
*/
|
||||
void sym_Global(char *tzSym)
|
||||
{
|
||||
if (nPass == 2) {
|
||||
/* only globalize symbols in pass 2 */
|
||||
struct sSymbol *nsym = sym_FindSymbol(tzSym);
|
||||
|
||||
if ((nsym == NULL) || ((nsym->nType & SYMF_DEFINED) == 0)) {
|
||||
if (nsym == NULL)
|
||||
nsym = createsymbol(tzSym);
|
||||
|
||||
if (nsym)
|
||||
nsym->nType |= SYMF_IMPORT;
|
||||
} else {
|
||||
if (nsym)
|
||||
nsym->nType |= SYMF_EXPORT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -828,8 +741,6 @@ void sym_Global(char *tzSym)
|
||||
*/
|
||||
void sym_AddMacro(char *tzSym)
|
||||
{
|
||||
if ((nPass == 1) || ((nPass == 2) && (sym_isDefined(tzSym) == 0))) {
|
||||
/* only add macros in pass 1 */
|
||||
struct sSymbol *nsym;
|
||||
|
||||
nsym = findsymbol(tzSym, NULL);
|
||||
@@ -853,6 +764,28 @@ void sym_AddMacro(char *tzSym)
|
||||
updateSymbolFilename(nsym);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a symbol that is being referenced ahead of its definition
|
||||
*/
|
||||
void sym_AddForwardRef(char *tzSym)
|
||||
{
|
||||
if (sym_FindSymbol(tzSym) == NULL) {
|
||||
char fullname[MAXSYMLEN + 1];
|
||||
int isLocal = 0;
|
||||
|
||||
if (*tzSym == '.') {
|
||||
fullSymbolName(fullname, sizeof(fullname), tzSym,
|
||||
pScope);
|
||||
tzSym = fullname;
|
||||
isLocal = 1;
|
||||
}
|
||||
|
||||
struct sSymbol *nsym = createsymbol(tzSym);
|
||||
|
||||
if (nsym && isLocal)
|
||||
nsym->nType |= SYMF_LOCAL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -863,66 +796,6 @@ void sym_SetExportAll(uint8_t set)
|
||||
exportall = set;
|
||||
}
|
||||
|
||||
/*
|
||||
* Prepare for pass #1
|
||||
*/
|
||||
void sym_PrepPass1(void)
|
||||
{
|
||||
sym_Init();
|
||||
}
|
||||
|
||||
/*
|
||||
* Prepare for pass #2
|
||||
*/
|
||||
void sym_PrepPass2(void)
|
||||
{
|
||||
int32_t i;
|
||||
|
||||
for (i = 0; i < HASHSIZE; i += 1) {
|
||||
struct sSymbol **ppSym = &(tHashedSymbols[i]);
|
||||
|
||||
while (*ppSym) {
|
||||
uint32_t mask = SYMF_SET | SYMF_STRING | SYMF_EQU;
|
||||
|
||||
if ((*ppSym)->nType & mask) {
|
||||
struct sSymbol *pTemp;
|
||||
|
||||
pTemp = (*ppSym)->pNext;
|
||||
free(*ppSym);
|
||||
*ppSym = pTemp;
|
||||
} else {
|
||||
ppSym = &((*ppSym)->pNext);
|
||||
}
|
||||
}
|
||||
}
|
||||
pScope = NULL;
|
||||
pPCSymbol->nValue = 0;
|
||||
|
||||
sym_AddString("__TIME__", SavedTIME);
|
||||
sym_AddString("__DATE__", SavedDATE);
|
||||
sym_AddString("__ISO_8601_LOCAL__", SavedTIMESTAMP_ISO8601_LOCAL);
|
||||
sym_AddString("__ISO_8601_UTC__", SavedTIMESTAMP_ISO8601_UTC);
|
||||
sym_AddString("__UTC_DAY__", SavedDAY);
|
||||
sym_AddString("__UTC_MONTH__", SavedMONTH);
|
||||
sym_AddString("__UTC_YEAR__", SavedYEAR);
|
||||
sym_AddString("__UTC_HOUR__", SavedHOUR);
|
||||
sym_AddString("__UTC_MINUTE__", SavedMINUTE);
|
||||
sym_AddString("__UTC_SECOND__", SavedSECOND);
|
||||
sym_AddEqu("__RGBDS_MAJOR__", PACKAGE_VERSION_MAJOR);
|
||||
sym_AddEqu("__RGBDS_MINOR__", PACKAGE_VERSION_MINOR);
|
||||
sym_AddEqu("__RGBDS_PATCH__", PACKAGE_VERSION_PATCH);
|
||||
sym_AddSet("_RS", 0);
|
||||
|
||||
sym_AddEqu("_NARG", 0);
|
||||
p_NARGSymbol = findsymbol("_NARG", NULL);
|
||||
p_NARGSymbol->Callback = Callback_NARG;
|
||||
sym_AddEqu("__LINE__", 0);
|
||||
p__LINE__Symbol = findsymbol("__LINE__", NULL);
|
||||
p__LINE__Symbol->Callback = Callback__LINE__;
|
||||
|
||||
math_DefinePI();
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the symboltable
|
||||
*/
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
ERROR: label-redefinition.asm(7):
|
||||
'Sym' already defined in m(6)
|
||||
error: Assembly aborted in pass 1 (1 errors)!
|
||||
error: Assembly aborted (1 errors)!
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
ERROR: local-wrong-parent.asm(5):
|
||||
Not currently in the scope of 'WrongParent'
|
||||
error: Assembly aborted in pass 1 (1 errors)!
|
||||
error: Assembly aborted (1 errors)!
|
||||
|
||||
@@ -1,3 +1 @@
|
||||
ERROR: undefined-dot.asm(3):
|
||||
'.' not defined
|
||||
error: Assembly aborted in pass 2 (1 errors)!
|
||||
error: undefined-dot.asm(3) : '.' not defined
|
||||
|
||||
Reference in New Issue
Block a user