summaryrefslogtreecommitdiff
path: root/parser.y
diff options
context:
space:
mode:
Diffstat (limited to 'parser.y')
-rw-r--r--parser.y64
1 files changed, 24 insertions, 40 deletions
diff --git a/parser.y b/parser.y
index 1f4f5bd..e6cb0b1 100644
--- a/parser.y
+++ b/parser.y
@@ -13,7 +13,8 @@ void yyerror(const char *msg)
#define INSTRUCTION_ARGS(m,a) (struct instruction) { MNEM_ ## m, a }
#define INSTRUCTION(m) (struct instruction) { MNEM_ ## m }
#define MKARGS(...) (struct arguments) { { __VA_ARGS__ } }
-#define MKARGVALUE(v) (struct argument) { .value = (v) }
+#define MKARGVALUE(v) (struct argument) { .type = ARG_INTEGER, .value = (v) }
+#define MKARGLABEL(l) (struct argument) { .type = ARG_LABEL, .label = (l) }
%}
@@ -84,16 +85,14 @@ void yyerror(const char *msg)
%token T_COLON ":"
%type <inst> inst
-%type <arg> imm
-%type <arg> pcoff
+%type <arg> expr
%type <args> a_reg2
%type <args> a_reg3
%type <args> a_regp
%type <args> a_regp_reg
%type <args> a_reg_regp
-%type <args> a_reg_imm
-%type <args> a_reg_pcoff
-%type <args> a_pcoff
+%type <args> a_reg_expr
+%type <args> a_expr
%type <lval> intlit
%%
@@ -136,17 +135,17 @@ inst:
| T_LD_BL a_reg_regp { $$ = INSTRUCTION_ARGS(LD_BL, $2); }
| T_LD_BH a_reg_regp { $$ = INSTRUCTION_ARGS(LD_BH, $2); }
| T_LD_W a_reg_regp { $$ = INSTRUCTION_ARGS(LD_W, $2); }
- | T_LDI_BL a_reg_imm { $$ = INSTRUCTION_ARGS(LDI_BL, $2); }
- | T_LDI_BH a_reg_imm { $$ = INSTRUCTION_ARGS(LDI_BH, $2); }
- | T_BEQ a_pcoff { $$ = INSTRUCTION_ARGS(BEQ, $2); }
- | T_BNE a_pcoff { $$ = INSTRUCTION_ARGS(BNE, $2); }
- | T_BGT a_pcoff { $$ = INSTRUCTION_ARGS(BGT, $2); }
- | T_BGE a_pcoff { $$ = INSTRUCTION_ARGS(BGE, $2); }
- | T_BLT a_pcoff { $$ = INSTRUCTION_ARGS(BLT, $2); }
- | T_BLE a_pcoff { $$ = INSTRUCTION_ARGS(BLE, $2); }
- | T_BRA a_pcoff { $$ = INSTRUCTION_ARGS(BRA, $2); }
+ | T_LDI_BL a_reg_expr { $$ = INSTRUCTION_ARGS(LDI_BL, $2); }
+ | T_LDI_BH a_reg_expr { $$ = INSTRUCTION_ARGS(LDI_BH, $2); }
+ | T_BEQ a_expr { $$ = INSTRUCTION_ARGS(BEQ, $2); }
+ | T_BNE a_expr { $$ = INSTRUCTION_ARGS(BNE, $2); }
+ | T_BGT a_expr { $$ = INSTRUCTION_ARGS(BGT, $2); }
+ | T_BGE a_expr { $$ = INSTRUCTION_ARGS(BGE, $2); }
+ | T_BLT a_expr { $$ = INSTRUCTION_ARGS(BLT, $2); }
+ | T_BLE a_expr { $$ = INSTRUCTION_ARGS(BLE, $2); }
+ | T_BRA a_expr { $$ = INSTRUCTION_ARGS(BRA, $2); }
| T_JMP a_regp { $$ = INSTRUCTION_ARGS(JMP, $2); }
- | T_ADDPC a_reg_pcoff { $$ = INSTRUCTION_ARGS(ADDPC, $2); }
+ | T_ADDPC a_reg_expr { $$ = INSTRUCTION_ARGS(ADDPC, $2); }
| T_NOP { $$ = INSTRUCTION(NOP); }
;
@@ -160,30 +159,15 @@ a_regp_reg:
T_SPACE T_REGPTR "," T_REG { $$ = MKARGS($2, $4); }
a_reg_regp:
T_SPACE T_REG "," T_REGPTR { $$ = MKARGS($2, $4); }
-a_reg_imm:
- T_SPACE T_REG "," imm { $$ = MKARGS($2, $4); }
-a_reg_pcoff:
- T_SPACE T_REG "," pcoff { $$ = MKARGS($2, $4); }
-a_pcoff:
- T_SPACE pcoff { $$ = MKARGS($2); }
-
-pcoff: intlit {
- if (-0x80 > $1 || $1 > 0x7f) {
- yyerror("pc offset operand out of range");
- YYERROR;
- } else {
- $$ = MKARGVALUE((uint8_t) $1);
- }
- }
-
-imm: intlit {
- if (-0x80 > $1 || $1 > 0xff) {
- yyerror("immediate operand out of range");
- YYERROR;
- } else {
- $$ = MKARGVALUE((uint8_t) $1);
- }
- }
+a_reg_expr:
+ T_SPACE T_REG "," expr { $$ = MKARGS($2, $4); }
+a_expr:
+ T_SPACE expr { $$ = MKARGS($2); }
+
+expr:
+ intlit { $$ = MKARGVALUE($1); }
+ | T_LABEL { $$ = MKARGLABEL($1); }
+ ;
intlit: T_INT
| T_BADINT {