Implement SIZEOF and STARTOF for section types (#1205)

This commit is contained in:
Rangi
2023-11-03 03:50:04 -04:00
committed by GitHub
parent 8f3369fe29
commit c869edd1d2
9 changed files with 93 additions and 10 deletions

View File

@@ -57,6 +57,8 @@ void rpn_BankSection(struct Expression *expr, char const *sectionName);
void rpn_BankSelf(struct Expression *expr);
void rpn_SizeOfSection(struct Expression *expr, char const *sectionName);
void rpn_StartOfSection(struct Expression *expr, char const *sectionName);
void rpn_SizeOfSectionType(struct Expression *expr, enum SectionType type);
void rpn_StartOfSectionType(struct Expression *expr, enum SectionType type);
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);

View File

@@ -56,6 +56,8 @@ enum RPNCommand {
RPN_BANK_SELF = 0x52,
RPN_SIZEOF_SECT = 0x53,
RPN_STARTOF_SECT = 0x54,
RPN_SIZEOF_SECTTYPE = 0x55,
RPN_STARTOF_SECTTYPE = 0x56,
RPN_HRAM = 0x60,
RPN_RST = 0x61,

View File

@@ -487,11 +487,21 @@ is able to compute it.
is in.
.Ar symbol
must have been defined already.
.It Fn SIZEOF arg Ta Returns the size of the section named
.It Fn SIZEOF arg Ta If
.Ar arg
is a string, this function returns the size of the section named
.Ar arg .
If
.Ar arg
is a section type keyword, it returns the size of that section type.
The result is not constant, since only RGBLINK can compute its value.
.It Fn STARTOF arg Ta Returns the starting address of the section named
.It Fn STARTOF arg Ta If
.Ar arg
is a string, this function returns the starting address of the section named
.Ar arg .
If
.Ar arg
is a section type keyword, it returns the starting address of that section type.
The result is not constant, since only RGBLINK can compute its value.
.It Fn DEF symbol Ta Returns TRUE (1) if
.Ar symbol

View File

@@ -349,23 +349,33 @@ after it.
.It Li $40 Ta Left shift operator Pq Ql <<
.It Li $41 Ta Arithmetic/signed right shift operator Pq Ql >>
.It Li $42 Ta Logical/unsigned right shift operator Pq Ql >>>
.It Li $50 Ta Fn BANK symbol ,
.It Li $50 Ta Fn BANK symbol ;
followed by the
.Ar symbol Ap s Cm LONG
ID.
.It Li $51 Ta Fn BANK section ,
.It Li $51 Ta Fn BANK section ;
followed by the
.Ar section Ap s Cm STRING
name.
.It Li $52 Ta PC's Fn BANK Pq i.e. Ql BANK(@) .
.It Li $53 Ta Fn SIZEOF section ,
.It Li $53 Ta Fn SIZEOF section ;
followed by the
.Ar section Ap s Cm STRING
name.
.It Li $54 Ta Fn STARTOF section ,
.It Li $54 Ta Fn STARTOF section ;
followed by the
.Ar section Ap s Cm STRING
name.
.It Li $55 Ta Fn SIZEOF sectiontype ;
followed by the
.Ar sectiontype Ap s Cm BYTE
value
.Pq see the Ar Type No values in Sx Sections .
.It Li $56 Ta Fn STARTOF sectiontype ;
followed by the
.Ar sectiontype Ap s Cm BYTE
value
.Pq see the Ar Type No values in Sx Sections .
.It Li $60 Ta Ql ldh
check.
Checks if the value is a valid
@@ -383,12 +393,10 @@ Checks if the value is a valid
vector, that is one of $00, $08, $10, $18, $20, $28, $30, or $38.
The value is then ORed with $C7
.Pq Ql \&| $C7 .
.It Li $80 Ta Integer literal.
Followed by the
.It Li $80 Ta Integer literal; followed by the
.Cm LONG
integer.
.It Li $81 Ta A symbol's value.
Followed by the symbol's
.It Li $81 Ta A symbol's value; followed by the symbol's
.Cm LONG
ID.
.El

View File

@@ -1538,6 +1538,8 @@ relocexpr_no_str : scoped_anon_id { rpn_Symbol(&$$, $1); }
| T_OP_BANK T_LPAREN string T_RPAREN { rpn_BankSection(&$$, $3); }
| T_OP_SIZEOF T_LPAREN string T_RPAREN { rpn_SizeOfSection(&$$, $3); }
| T_OP_STARTOF T_LPAREN string T_RPAREN { rpn_StartOfSection(&$$, $3); }
| T_OP_SIZEOF T_LPAREN sectiontype T_RPAREN { rpn_SizeOfSectionType(&$$, $3); }
| T_OP_STARTOF T_LPAREN sectiontype T_RPAREN { rpn_StartOfSectionType(&$$, $3); }
| T_OP_DEF {
lexer_ToggleStringExpansion(false);
} T_LPAREN scoped_anon_id T_RPAREN {

View File

@@ -233,6 +233,30 @@ void rpn_StartOfSection(struct Expression *expr, char const *sectionName)
}
}
void rpn_SizeOfSectionType(struct Expression *expr, enum SectionType type)
{
rpn_Init(expr);
makeUnknown(expr, "Section type's size is not known");
uint8_t *ptr = reserveSpace(expr, 2);
expr->rpnPatchSize += 2;
*ptr++ = RPN_SIZEOF_SECTTYPE;
*ptr++ = type;
}
void rpn_StartOfSectionType(struct Expression *expr, enum SectionType type)
{
rpn_Init(expr);
makeUnknown(expr, "Section type's start is not known");
uint8_t *ptr = reserveSpace(expr, 2);
expr->rpnPatchSize += 2;
*ptr++ = RPN_STARTOF_SECTTYPE;
*ptr++ = type;
}
void rpn_CheckHRAM(struct Expression *expr, const struct Expression *src)
{
*expr = *src;
@@ -508,6 +532,8 @@ void rpn_BinaryOp(enum RPNCommand op, struct Expression *expr,
case RPN_BANK_SELF:
case RPN_SIZEOF_SECT:
case RPN_STARTOF_SECT:
case RPN_SIZEOF_SECTTYPE:
case RPN_STARTOF_SECTTYPE:
case RPN_HRAM:
case RPN_RST:
case RPN_CONST:

View File

@@ -360,6 +360,30 @@ static int32_t computeRPNExpr(struct Patch const *patch,
}
break;
case RPN_SIZEOF_SECTTYPE:
value = getRPNByte(&expression, &size, patch->src, patch->lineNo);
if (value < 0 || value >= SECTTYPE_INVALID) {
error(patch->src, patch->lineNo,
"Requested SIZEOF() an invalid section type");
isError = true;
value = 0;
} else {
value = sectionTypeInfo[value].size;
}
break;
case RPN_STARTOF_SECTTYPE:
value = getRPNByte(&expression, &size, patch->src, patch->lineNo);
if (value < 0 || value >= SECTTYPE_INVALID) {
error(patch->src, patch->lineNo,
"Requested STARTOF() an invalid section type");
isError = true;
value = 0;
} else {
value = sectionTypeInfo[value].startAddr;
}
break;
case RPN_HRAM:
value = popRPN();
if (!isError && (value < 0

View File

@@ -3,5 +3,14 @@ SECTION "meta", ROM0[0]
dw STARTOF("sect")
dw SIZEOF("sect")
MACRO typemeta
rept _NARG
dw STARTOF(\1), SIZEOF(\1)
shift
endr
ENDM
typemeta ROM0, ROMX, VRAM, SRAM, WRAM0, WRAMX, OAM, HRAM
SECTION "sect", ROMX[$4567], BANK[$23]
ds 42

Binary file not shown.