The symbol's evaluation by the assembler and linker was very inconsistent
This commit is contained in:
ISSOtm
2020-02-07 13:18:49 +01:00
parent 9687e6e1dd
commit ea52e45335
3 changed files with 12 additions and 31 deletions

View File

@@ -23,6 +23,9 @@ struct Expression {
uint32_t isReloc; uint32_t isReloc;
}; };
/* FIXME: Should be defined in `asmy.h`, but impossible with POSIX Yacc */
extern int32_t nPCOffset;
uint32_t rpn_isReloc(const struct Expression *expr); uint32_t rpn_isReloc(const struct Expression *expr);
void rpn_Symbol(struct Expression *expr, char *tzSym); void rpn_Symbol(struct Expression *expr, char *tzSym);
void rpn_Number(struct Expression *expr, uint32_t i); void rpn_Number(struct Expression *expr, uint32_t i);

View File

@@ -1206,37 +1206,7 @@ const_16bit : relocconst
relocconst : T_ID relocconst : T_ID
{ {
/* rpn_Symbol(&$$, $1);
* The value of @ needs to be evaluated by the linker,
* it can only be calculated by the assembler in very
* few cases (when the base address of a section is
* known).
*
* '@' is a bit special in that it means different
* things depending on when it is used:
*
* - JR/LD/ADD/etc: It refers to the first byte of the
* instruction (1 byte offset relative to the value
* stored in the ROM).
* - DB/DW/DL: It refers to the address of the value
* that is being saved (0 byte offset relative to the
* value stored in the ROM.
*
* This offset must be added whenever '@' is added to a
* RPN expression so that the linker can calculate the
* correct result of any expression that uses '@'.
*/
if ((strcmp($1, "@") == 0) && (nPCOffset != 0)) {
struct Expression sTemp, sOffset;
rpn_Symbol(&sTemp, $1);
rpn_Number(&sOffset, nPCOffset);
rpn_SUB(&$$, &sTemp, &sOffset);
} else {
rpn_Symbol(&$$, $1);
}
} }
| T_NUMBER | T_NUMBER
{ {

View File

@@ -154,6 +154,14 @@ void rpn_Symbol(struct Expression *expr, char *tzSym)
pushbyte(expr, *tzSym++); pushbyte(expr, *tzSym++);
pushbyte(expr, 0); pushbyte(expr, 0);
expr->nRPNPatchSize += 5; expr->nRPNPatchSize += 5;
/* RGBLINK assumes PC is at the byte being computed... */
if (sym == pPCSymbol && nPCOffset) {
struct Expression pc = *expr, offset;
rpn_Number(&offset, nPCOffset);
rpn_SUB(expr, &pc, &offset);
}
} else { } else {
rpn_Number(expr, sym_GetConstantValue(tzSym)); rpn_Number(expr, sym_GetConstantValue(tzSym));
} }