mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Fix @
The symbol's evaluation by the assembler and linker was very inconsistent
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user