mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Treat PC as a symbol as well
This commit is contained in:
@@ -17,9 +17,10 @@
|
|||||||
#define MAXRPNLEN 1048576
|
#define MAXRPNLEN 1048576
|
||||||
|
|
||||||
struct Expression {
|
struct Expression {
|
||||||
bool isKnown; // Whether the expression's value is known
|
|
||||||
int32_t nVal; // If the expression's value is known, it's here
|
int32_t nVal; // If the expression's value is known, it's here
|
||||||
char *reason; // Why the expression is not known, if it isn't
|
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
|
uint8_t *tRPN; // Array of bytes serializing the RPN expression
|
||||||
uint32_t nRPNCapacity; // Size of the `tRPN` buffer
|
uint32_t nRPNCapacity; // Size of the `tRPN` buffer
|
||||||
uint32_t nRPNLength; // Used size of the `tRPN` buffer
|
uint32_t nRPNLength; // Used size of the `tRPN` buffer
|
||||||
@@ -32,6 +33,7 @@ struct Expression {
|
|||||||
extern int32_t nPCOffset;
|
extern int32_t nPCOffset;
|
||||||
|
|
||||||
bool rpn_isKnown(const struct Expression *expr);
|
bool rpn_isKnown(const struct Expression *expr);
|
||||||
|
bool rpn_isSymbol(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);
|
||||||
void rpn_LOGNOT(struct Expression *expr, const struct Expression *src);
|
void rpn_LOGNOT(struct Expression *expr, const struct Expression *src);
|
||||||
|
|||||||
@@ -74,13 +74,14 @@ static uint8_t *reserveSpace(struct Expression *expr, uint32_t size)
|
|||||||
*/
|
*/
|
||||||
void rpn_Init(struct Expression *expr)
|
void rpn_Init(struct Expression *expr)
|
||||||
{
|
{
|
||||||
|
expr->reason = NULL;
|
||||||
|
expr->isKnown = true;
|
||||||
|
expr->isSymbol = false;
|
||||||
expr->tRPN = NULL;
|
expr->tRPN = NULL;
|
||||||
expr->nRPNCapacity = 0;
|
expr->nRPNCapacity = 0;
|
||||||
expr->nRPNLength = 0;
|
expr->nRPNLength = 0;
|
||||||
expr->nRPNPatchSize = 0;
|
expr->nRPNPatchSize = 0;
|
||||||
expr->nRPNOut = 0;
|
expr->nRPNOut = 0;
|
||||||
expr->isKnown = true;
|
|
||||||
expr->reason = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -112,6 +113,14 @@ bool rpn_isKnown(const struct Expression *expr)
|
|||||||
return expr->isKnown;
|
return expr->isKnown;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Determine if the current expression is a symbol suitable for const diffing
|
||||||
|
*/
|
||||||
|
bool rpn_isSymbol(const struct Expression *expr)
|
||||||
|
{
|
||||||
|
return expr->isSymbol;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add symbols, constants and operators to expression
|
* Add symbols, constants and operators to expression
|
||||||
*/
|
*/
|
||||||
@@ -127,6 +136,8 @@ void rpn_Symbol(struct Expression *expr, char *tzSym)
|
|||||||
|
|
||||||
if (!sym || !sym_IsConstant(sym)) {
|
if (!sym || !sym_IsConstant(sym)) {
|
||||||
rpn_Init(expr);
|
rpn_Init(expr);
|
||||||
|
expr->isSymbol = true;
|
||||||
|
|
||||||
sym_Ref(tzSym);
|
sym_Ref(tzSym);
|
||||||
makeUnknown(expr, "'%s' is not defined", tzSym);
|
makeUnknown(expr, "'%s' is not defined", tzSym);
|
||||||
expr->nRPNPatchSize += 5; /* 1-byte opcode + 4-byte symbol ID */
|
expr->nRPNPatchSize += 5; /* 1-byte opcode + 4-byte symbol ID */
|
||||||
@@ -142,6 +153,8 @@ void rpn_Symbol(struct Expression *expr, char *tzSym)
|
|||||||
|
|
||||||
rpn_Number(&offset, nPCOffset);
|
rpn_Number(&offset, nPCOffset);
|
||||||
rpn_BinaryOp(RPN_SUB, expr, &pc, &offset);
|
rpn_BinaryOp(RPN_SUB, expr, &pc, &offset);
|
||||||
|
if (!rpn_isKnown(expr))
|
||||||
|
expr->isSymbol = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
rpn_Number(expr, sym_GetConstantValue(tzSym));
|
rpn_Number(expr, sym_GetConstantValue(tzSym));
|
||||||
@@ -217,6 +230,7 @@ void rpn_BankSection(struct Expression *expr, char *tzSectionName)
|
|||||||
void rpn_CheckHRAM(struct Expression *expr, const struct Expression *src)
|
void rpn_CheckHRAM(struct Expression *expr, const struct Expression *src)
|
||||||
{
|
{
|
||||||
*expr = *src;
|
*expr = *src;
|
||||||
|
expr->isSymbol = false;
|
||||||
|
|
||||||
if (rpn_isKnown(expr)) {
|
if (rpn_isKnown(expr)) {
|
||||||
/* TODO */
|
/* TODO */
|
||||||
@@ -241,6 +255,7 @@ void rpn_CheckRST(struct Expression *expr, const struct Expression *src)
|
|||||||
void rpn_LOGNOT(struct Expression *expr, const struct Expression *src)
|
void rpn_LOGNOT(struct Expression *expr, const struct Expression *src)
|
||||||
{
|
{
|
||||||
*expr = *src;
|
*expr = *src;
|
||||||
|
expr->isSymbol = false;
|
||||||
|
|
||||||
if (rpn_isKnown(expr)) {
|
if (rpn_isKnown(expr)) {
|
||||||
expr->nVal = !expr->nVal;
|
expr->nVal = !expr->nVal;
|
||||||
@@ -291,8 +306,7 @@ static int32_t shift(int32_t shiftee, int32_t amount)
|
|||||||
|
|
||||||
static struct sSymbol const *symbolOf(struct Expression const *expr)
|
static struct sSymbol const *symbolOf(struct Expression const *expr)
|
||||||
{
|
{
|
||||||
/* If an expression starts with a symbol ref... */
|
if (!rpn_isSymbol(expr))
|
||||||
if (!expr->tRPN || expr->tRPN[0] != RPN_SYM || expr->nRPNPatchSize != 5)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
return sym_FindSymbol((char *)expr->tRPN + 1);
|
return sym_FindSymbol((char *)expr->tRPN + 1);
|
||||||
}
|
}
|
||||||
@@ -314,6 +328,8 @@ static bool isDiffConstant(struct Expression const *src1,
|
|||||||
void rpn_BinaryOp(enum RPNCommand op, struct Expression *expr,
|
void rpn_BinaryOp(enum RPNCommand op, struct Expression *expr,
|
||||||
const struct Expression *src1, const struct Expression *src2)
|
const struct Expression *src1, const struct Expression *src2)
|
||||||
{
|
{
|
||||||
|
expr->isSymbol = false;
|
||||||
|
|
||||||
/* First, check if the expression is known */
|
/* First, check if the expression is known */
|
||||||
expr->isKnown = src1->isKnown && src2->isKnown;
|
expr->isKnown = src1->isKnown && src2->isKnown;
|
||||||
if (expr->isKnown) {
|
if (expr->isKnown) {
|
||||||
@@ -478,6 +494,7 @@ void rpn_BinaryOp(enum RPNCommand op, struct Expression *expr,
|
|||||||
void rpn_HIGH(struct Expression *expr, const struct Expression *src)
|
void rpn_HIGH(struct Expression *expr, const struct Expression *src)
|
||||||
{
|
{
|
||||||
*expr = *src;
|
*expr = *src;
|
||||||
|
expr->isSymbol = false;
|
||||||
|
|
||||||
if (rpn_isKnown(expr)) {
|
if (rpn_isKnown(expr)) {
|
||||||
expr->nVal = (uint32_t)expr->nVal >> 8 & 0xFF;
|
expr->nVal = (uint32_t)expr->nVal >> 8 & 0xFF;
|
||||||
@@ -492,6 +509,7 @@ void rpn_HIGH(struct Expression *expr, const struct Expression *src)
|
|||||||
void rpn_LOW(struct Expression *expr, const struct Expression *src)
|
void rpn_LOW(struct Expression *expr, const struct Expression *src)
|
||||||
{
|
{
|
||||||
*expr = *src;
|
*expr = *src;
|
||||||
|
expr->isSymbol = false;
|
||||||
|
|
||||||
if (rpn_isKnown(expr)) {
|
if (rpn_isKnown(expr)) {
|
||||||
expr->nVal = expr->nVal & 0xFF;
|
expr->nVal = expr->nVal & 0xFF;
|
||||||
@@ -506,6 +524,7 @@ void rpn_LOW(struct Expression *expr, const struct Expression *src)
|
|||||||
void rpn_UNNEG(struct Expression *expr, const struct Expression *src)
|
void rpn_UNNEG(struct Expression *expr, const struct Expression *src)
|
||||||
{
|
{
|
||||||
*expr = *src;
|
*expr = *src;
|
||||||
|
expr->isSymbol = false;
|
||||||
|
|
||||||
if (rpn_isKnown(expr)) {
|
if (rpn_isKnown(expr)) {
|
||||||
expr->nVal = -(uint32_t)expr->nVal;
|
expr->nVal = -(uint32_t)expr->nVal;
|
||||||
@@ -518,6 +537,7 @@ void rpn_UNNEG(struct Expression *expr, const struct Expression *src)
|
|||||||
void rpn_UNNOT(struct Expression *expr, const struct Expression *src)
|
void rpn_UNNOT(struct Expression *expr, const struct Expression *src)
|
||||||
{
|
{
|
||||||
*expr = *src;
|
*expr = *src;
|
||||||
|
expr->isSymbol = false;
|
||||||
|
|
||||||
if (rpn_isKnown(expr)) {
|
if (rpn_isKnown(expr)) {
|
||||||
expr->nVal = ~expr->nVal;
|
expr->nVal = ~expr->nVal;
|
||||||
|
|||||||
Reference in New Issue
Block a user