mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Implement HIGH() and LOW() operators
They work with the 16-bit registers BC, DE and HL, returning the corresponding 8-bit register. HIGH() works with AF as well, returning A. They also work with any kind of constant or symbol, generating a RPN patch in the object file if the value is not defined at assembly time. They work with macro arguments as well. Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
This commit is contained in:
@@ -69,6 +69,8 @@ rpn_DIV(struct Expression * expr, struct Expression * src1,
|
|||||||
void
|
void
|
||||||
rpn_MOD(struct Expression * expr, struct Expression * src1,
|
rpn_MOD(struct Expression * expr, struct Expression * src1,
|
||||||
struct Expression * src2);
|
struct Expression * src2);
|
||||||
|
void rpn_HIGH(struct Expression * expr, struct Expression * src);
|
||||||
|
void rpn_LOW(struct Expression * expr, struct Expression * src);
|
||||||
void rpn_UNNEG(struct Expression * expr, struct Expression * src);
|
void rpn_UNNEG(struct Expression * expr, struct Expression * src);
|
||||||
void rpn_UNNOT(struct Expression * expr, struct Expression * src);
|
void rpn_UNNOT(struct Expression * expr, struct Expression * src);
|
||||||
UWORD rpn_PopByte(struct Expression * expr);
|
UWORD rpn_PopByte(struct Expression * expr);
|
||||||
|
|||||||
@@ -473,6 +473,7 @@ void if_skip_to_endc( void )
|
|||||||
%left T_OP_CEIL
|
%left T_OP_CEIL
|
||||||
%left T_OP_FLOOR
|
%left T_OP_FLOOR
|
||||||
|
|
||||||
|
%token T_OP_HIGH T_OP_LOW
|
||||||
|
|
||||||
%left T_OP_STRCMP
|
%left T_OP_STRCMP
|
||||||
%left T_OP_STRIN
|
%left T_OP_STRIN
|
||||||
@@ -537,11 +538,12 @@ void if_skip_to_endc( void )
|
|||||||
%token T_Z80_SLA T_Z80_SRA T_Z80_SRL T_Z80_SUB T_Z80_SWAP
|
%token T_Z80_SLA T_Z80_SRA T_Z80_SRL T_Z80_SUB T_Z80_SWAP
|
||||||
%token T_Z80_XOR
|
%token T_Z80_XOR
|
||||||
|
|
||||||
%token T_MODE_A T_MODE_B T_MODE_C T_MODE_C_IND T_MODE_D T_MODE_E T_MODE_H T_MODE_L
|
%token T_TOKEN_A T_TOKEN_B T_TOKEN_C T_TOKEN_D T_TOKEN_E T_TOKEN_H T_TOKEN_L
|
||||||
%token T_MODE_AF
|
%token T_MODE_AF
|
||||||
%token T_MODE_BC T_MODE_BC_IND
|
%token T_MODE_BC T_MODE_BC_IND
|
||||||
%token T_MODE_DE T_MODE_DE_IND
|
%token T_MODE_DE T_MODE_DE_IND
|
||||||
%token T_MODE_SP T_MODE_SP_IND
|
%token T_MODE_SP T_MODE_SP_IND
|
||||||
|
%token T_MODE_C_IND
|
||||||
%token T_MODE_HL T_MODE_HL_IND T_MODE_HL_INDDEC T_MODE_HL_INDINC
|
%token T_MODE_HL T_MODE_HL_IND T_MODE_HL_INDDEC T_MODE_HL_INDINC
|
||||||
%token T_CC_NZ T_CC_Z T_CC_NC
|
%token T_CC_NZ T_CC_Z T_CC_NC
|
||||||
|
|
||||||
@@ -992,6 +994,10 @@ relocconst : T_ID
|
|||||||
{ rpn_UNNEG(&$$,&$2); }
|
{ rpn_UNNEG(&$$,&$2); }
|
||||||
| T_OP_NOT relocconst %prec NEG
|
| T_OP_NOT relocconst %prec NEG
|
||||||
{ rpn_UNNOT(&$$,&$2); }
|
{ rpn_UNNOT(&$$,&$2); }
|
||||||
|
| T_OP_HIGH '(' relocconst ')'
|
||||||
|
{ rpn_HIGH(&$$, &$3); }
|
||||||
|
| T_OP_LOW '(' relocconst ')'
|
||||||
|
{ rpn_LOW(&$$, &$3); }
|
||||||
| T_OP_BANK '(' T_ID ')'
|
| T_OP_BANK '(' T_ID ')'
|
||||||
{ rpn_Bank(&$$,$3); $$.nVal = 0; }
|
{ rpn_Bank(&$$,$3); $$.nVal = 0; }
|
||||||
| T_OP_DEF { oDontExpandStrings = true; } '(' T_ID ')'
|
| T_OP_DEF { oDontExpandStrings = true; } '(' T_ID ')'
|
||||||
@@ -1611,10 +1617,33 @@ op_a_n : const_8bit { $$ = $1; }
|
|||||||
comma : ','
|
comma : ','
|
||||||
;
|
;
|
||||||
|
|
||||||
|
T_MODE_A : T_TOKEN_A
|
||||||
|
| T_OP_HIGH '(' T_MODE_AF ')'
|
||||||
|
;
|
||||||
|
T_MODE_B : T_TOKEN_B
|
||||||
|
| T_OP_HIGH '(' T_MODE_BC ')'
|
||||||
|
;
|
||||||
|
T_MODE_C : T_TOKEN_C
|
||||||
|
| T_OP_LOW '(' T_MODE_BC ')'
|
||||||
|
;
|
||||||
|
T_MODE_D : T_TOKEN_D
|
||||||
|
| T_OP_HIGH '(' T_MODE_DE ')'
|
||||||
|
;
|
||||||
|
T_MODE_E : T_TOKEN_E
|
||||||
|
| T_OP_LOW '(' T_MODE_DE ')'
|
||||||
|
;
|
||||||
|
T_MODE_H : T_TOKEN_H
|
||||||
|
| T_OP_HIGH '(' T_MODE_HL ')'
|
||||||
|
;
|
||||||
|
T_MODE_L : T_TOKEN_L
|
||||||
|
| T_OP_LOW '(' T_MODE_HL ')'
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
ccode : T_CC_NZ { $$ = CC_NZ; }
|
ccode : T_CC_NZ { $$ = CC_NZ; }
|
||||||
| T_CC_Z { $$ = CC_Z; }
|
| T_CC_Z { $$ = CC_Z; }
|
||||||
| T_CC_NC { $$ = CC_NC; }
|
| T_CC_NC { $$ = CC_NC; }
|
||||||
| T_MODE_C { $$ = CC_C; }
|
| T_TOKEN_C { $$ = CC_C; }
|
||||||
;
|
;
|
||||||
|
|
||||||
reg_r : T_MODE_B { $$ = REG_B; }
|
reg_r : T_MODE_B { $$ = REG_B; }
|
||||||
|
|||||||
@@ -282,6 +282,9 @@ struct sLexInitString staticstrings[] = {
|
|||||||
{"atan", T_OP_ATAN},
|
{"atan", T_OP_ATAN},
|
||||||
{"atan2", T_OP_ATAN2},
|
{"atan2", T_OP_ATAN2},
|
||||||
|
|
||||||
|
{"high", T_OP_HIGH},
|
||||||
|
{"low", T_OP_LOW},
|
||||||
|
|
||||||
{"strcmp", T_OP_STRCMP},
|
{"strcmp", T_OP_STRCMP},
|
||||||
{"strin", T_OP_STRIN},
|
{"strin", T_OP_STRIN},
|
||||||
{"strsub", T_OP_STRSUB},
|
{"strsub", T_OP_STRSUB},
|
||||||
|
|||||||
@@ -60,30 +60,31 @@ struct sLexInitString localstrings[] = {
|
|||||||
{"nz", T_CC_NZ},
|
{"nz", T_CC_NZ},
|
||||||
{"z", T_CC_Z},
|
{"z", T_CC_Z},
|
||||||
{"nc", T_CC_NC},
|
{"nc", T_CC_NC},
|
||||||
/* { "c", T_MODE_C }, */
|
/* { "c", T_TOKEN_C }, */
|
||||||
|
|
||||||
|
{"[bc]", T_MODE_BC_IND},
|
||||||
|
{"[de]", T_MODE_DE_IND},
|
||||||
{"[hl]", T_MODE_HL_IND},
|
{"[hl]", T_MODE_HL_IND},
|
||||||
{"[hl+]", T_MODE_HL_INDINC},
|
{"[hl+]", T_MODE_HL_INDINC},
|
||||||
{"[hl-]", T_MODE_HL_INDDEC},
|
{"[hl-]", T_MODE_HL_INDDEC},
|
||||||
{"[hli]", T_MODE_HL_INDINC},
|
{"[hli]", T_MODE_HL_INDINC},
|
||||||
{"[hld]", T_MODE_HL_INDDEC},
|
{"[hld]", T_MODE_HL_INDDEC},
|
||||||
{"hl", T_MODE_HL},
|
|
||||||
{"af", T_MODE_AF},
|
|
||||||
{"[bc]", T_MODE_BC_IND},
|
|
||||||
{"bc", T_MODE_BC},
|
|
||||||
{"[de]", T_MODE_DE_IND},
|
|
||||||
{"de", T_MODE_DE},
|
|
||||||
{"[sp]", T_MODE_SP_IND},
|
{"[sp]", T_MODE_SP_IND},
|
||||||
|
{"af", T_MODE_AF},
|
||||||
|
{"bc", T_MODE_BC},
|
||||||
|
{"de", T_MODE_DE},
|
||||||
|
{"hl", T_MODE_HL},
|
||||||
{"sp", T_MODE_SP},
|
{"sp", T_MODE_SP},
|
||||||
{"a", T_MODE_A},
|
|
||||||
{"b", T_MODE_B},
|
|
||||||
{"[$ff00+c]", T_MODE_C_IND},
|
|
||||||
{"[c]", T_MODE_C_IND},
|
{"[c]", T_MODE_C_IND},
|
||||||
{"c", T_MODE_C},
|
{"[$ff00+c]", T_MODE_C_IND},
|
||||||
{"d", T_MODE_D},
|
|
||||||
{"e", T_MODE_E},
|
{"a", T_TOKEN_A},
|
||||||
{"h", T_MODE_H},
|
{"b", T_TOKEN_B},
|
||||||
{"l", T_MODE_L},
|
{"c", T_TOKEN_C},
|
||||||
|
{"d", T_TOKEN_D},
|
||||||
|
{"e", T_TOKEN_E},
|
||||||
|
{"h", T_TOKEN_H},
|
||||||
|
{"l", T_TOKEN_L},
|
||||||
|
|
||||||
{NULL, 0}
|
{NULL, 0}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -182,6 +182,46 @@ rpn_LOGAND(struct Expression * expr, struct Expression * src1,
|
|||||||
pushbyte(expr, RPN_LOGAND);
|
pushbyte(expr, RPN_LOGAND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rpn_HIGH(struct Expression * expr, struct Expression * src)
|
||||||
|
{
|
||||||
|
*expr = *src;
|
||||||
|
|
||||||
|
expr->nVal = (expr->nVal >> 8) & 0xFF;
|
||||||
|
|
||||||
|
pushbyte(expr, RPN_CONST);
|
||||||
|
pushbyte(expr, 8);
|
||||||
|
pushbyte(expr, 0);
|
||||||
|
pushbyte(expr, 0);
|
||||||
|
pushbyte(expr, 0);
|
||||||
|
|
||||||
|
pushbyte(expr, RPN_SHR);
|
||||||
|
|
||||||
|
pushbyte(expr, RPN_CONST);
|
||||||
|
pushbyte(expr, 0xFF);
|
||||||
|
pushbyte(expr, 0);
|
||||||
|
pushbyte(expr, 0);
|
||||||
|
pushbyte(expr, 0);
|
||||||
|
|
||||||
|
pushbyte(expr, RPN_AND);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rpn_LOW(struct Expression * expr, struct Expression * src)
|
||||||
|
{
|
||||||
|
*expr = *src;
|
||||||
|
|
||||||
|
expr->nVal = expr->nVal & 0xFF;
|
||||||
|
|
||||||
|
pushbyte(expr, RPN_CONST);
|
||||||
|
pushbyte(expr, 0xFF);
|
||||||
|
pushbyte(expr, 0);
|
||||||
|
pushbyte(expr, 0);
|
||||||
|
pushbyte(expr, 0);
|
||||||
|
|
||||||
|
pushbyte(expr, RPN_AND);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rpn_LOGEQU(struct Expression * expr, struct Expression * src1,
|
rpn_LOGEQU(struct Expression * expr, struct Expression * src1,
|
||||||
struct Expression * src2)
|
struct Expression * src2)
|
||||||
|
|||||||
Reference in New Issue
Block a user