summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBobby Bingham <koorogi@koorogi.info>2017-01-14 14:44:18 -0600
committerBobby Bingham <koorogi@koorogi.info>2017-01-15 23:19:04 -0600
commit50e67fb3e640a9e6e1260ca984582c9a9b8d5375 (patch)
treed4d12ed5a5787e30e1062ced1edc6c7979afe77e
parenta743db94541bebafff23c8a490dbce3f55d69712 (diff)
nqasm: Handle register and register indirect arguments
-rw-r--r--Makefile2
-rw-r--r--lexer.l7
-rw-r--r--nqasm.c15
-rw-r--r--nqasm.h11
-rw-r--r--parser.y94
5 files changed, 76 insertions, 53 deletions
diff --git a/Makefile b/Makefile
index 554c540..d509c92 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
OPTFLAGS = -Os
-CFLAGS = -std=c99 -D_POSIX_C_SOURCE=200809L $(OPTFLAGS)
+CFLAGS = -std=c11 -D_POSIX_C_SOURCE=200809L $(OPTFLAGS)
GENSRCS = lexer.c parser.c
GENHDRS = lexer.h parser.h
diff --git a/lexer.l b/lexer.l
index 6b6b121..f3a540c 100644
--- a/lexer.l
+++ b/lexer.l
@@ -2,6 +2,8 @@
#include "parser.h"
+#define SETVALUE(v) yylval.arg = (struct argument) { .value = (v) }
+
%}
%option outfile="lexer.c" header-file="lexer.h"
@@ -13,6 +15,7 @@
COMMENT #[^\n]*
SP [ \t]
EOI [ \t\n#]
+REGNUM [0-7]
%%
@@ -54,6 +57,10 @@ EOI [ \t\n#]
<inst>addpc/{EOI} { BEGIN(args); return T_ADDPC; }
<inst>nop/{EOI} { BEGIN(args); return T_NOP; }
+<args>r{REGNUM} { SETVALUE(yytext[1]-'0'); return T_REG; }
+<args>@r{REGNUM} { SETVALUE(yytext[2]-'0'); return T_REGPTR; }
+<args>{SP}*,{SP}* { return T_COMMA; }
+
{SP}*{COMMENT}?\n { BEGIN(INITIAL); return T_EOL; }
{SP}*{COMMENT} { BEGIN(INITIAL); return T_EOL; }
{SP}+ { return T_SPACE; }
diff --git a/nqasm.c b/nqasm.c
index a42f8f4..ed49a48 100644
--- a/nqasm.c
+++ b/nqasm.c
@@ -1,3 +1,4 @@
+#include <stdint.h>
#include <stdio.h>
#include "mnemonics.h"
@@ -6,10 +7,18 @@
#include "lexer.h"
#include "parser.h"
-void add_instruction(const struct instruction *i)
+void add_instruction(const struct instruction *inst)
{
- const struct mnemonic *m = &mnemonics[i->mnem];
- printf("%04x\n", m->bits);
+ const struct mnemonic *mnem = &mnemonics[inst->mnem];
+ uint16_t bits = mnem->bits;
+
+ const struct operand *ops = mnem->operands;
+ const struct argument *args = inst->args.args;
+ for (int i = 0; i < 3 && ops[i].type; i++) {
+ bits |= args[i].value << ops[i].shift;
+ }
+
+ printf("%04x\n", bits);
}
int main(int argc, char **argv)
diff --git a/nqasm.h b/nqasm.h
index 3712849..d25911b 100644
--- a/nqasm.h
+++ b/nqasm.h
@@ -1,8 +1,19 @@
#ifndef NQ_NQASM_H
#define NQ_NQASM_H
+struct argument {
+ union {
+ int value;
+ };
+};
+
+struct arguments {
+ struct argument args[3];
+};
+
struct instruction {
int mnem;
+ struct arguments args;
};
void add_instruction(const struct instruction *);
diff --git a/parser.y b/parser.y
index 48bd13f..2177ae8 100644
--- a/parser.y
+++ b/parser.y
@@ -10,7 +10,9 @@ void yyerror(const char *msg)
fprintf(stderr, "%s\n", msg);
}
-#define INSTRUCTION(mnem) (struct instruction) { MNEM_ ## mnem }
+#define INSTRUCTION_ARGS(m,a) (struct instruction) { MNEM_ ## m, a }
+#define INSTRUCTION(m) (struct instruction) { MNEM_ ## m }
+#define MKARGS(...) (struct arguments) { __VA_ARGS__ }
%}
@@ -23,6 +25,8 @@ void yyerror(const char *msg)
%union {
struct instruction inst;
+ struct arguments args;
+ struct argument arg;
}
%token END 0 "end of file"
@@ -66,7 +70,17 @@ void yyerror(const char *msg)
%token T_ADDPC
%token T_NOP
+%token <arg> T_REG
+%token <arg> T_REGPTR
+%token T_COMMA ","
+
%type <inst> inst
+%type <args> reg2
+%type <args> reg3
+%type <args> regp
+%type <args> regp_reg
+%type <args> reg_regp
+
%%
input: line
@@ -78,52 +92,29 @@ line: T_SPACE inst eol
| eol
;
-inst: T_ADD
- { $$ = INSTRUCTION(ADD); }
- | T_SUB
- { $$ = INSTRUCTION(SUB); }
- | T_MUL
- { $$ = INSTRUCTION(MUL); }
- | T_DIV
- { $$ = INSTRUCTION(DIV); }
- | T_AND
- { $$ = INSTRUCTION(AND); }
- | T_OR
- { $$ = INSTRUCTION(OR); }
- | T_XOR
- { $$ = INSTRUCTION(XOR); }
- | T_LSL
- { $$ = INSTRUCTION(LSL); }
- | T_LSR
- { $$ = INSTRUCTION(LSR); }
- | T_ASL
- { $$ = INSTRUCTION(ASL); }
- | T_ASR
- { $$ = INSTRUCTION(ASR); }
- | T_ROL
- { $$ = INSTRUCTION(ROL); }
- | T_ROR
- { $$ = INSTRUCTION(ROR); }
- | T_NOT
- { $$ = INSTRUCTION(NOT); }
- | T_NEG
- { $$ = INSTRUCTION(NEG); }
- | T_BTC
- { $$ = INSTRUCTION(BTC); }
- | T_BTS
- { $$ = INSTRUCTION(BTS); }
- | T_MOV
- { $$ = INSTRUCTION(MOV); }
- | T_ST_B
- { $$ = INSTRUCTION(ST_B); }
- | T_ST_W
- { $$ = INSTRUCTION(ST_W); }
- | T_LD_BL
- { $$ = INSTRUCTION(LD_BL); }
- | T_LD_BH
- { $$ = INSTRUCTION(LD_BH); }
- | T_LD_W
- { $$ = INSTRUCTION(LD_W); }
+inst: T_ADD reg3 { $$ = INSTRUCTION_ARGS(ADD, $2); }
+ | T_SUB reg3 { $$ = INSTRUCTION_ARGS(SUB, $2); }
+ | T_MUL reg3 { $$ = INSTRUCTION_ARGS(MUL, $2); }
+ | T_DIV reg3 { $$ = INSTRUCTION_ARGS(DIV, $2); }
+ | T_AND reg3 { $$ = INSTRUCTION_ARGS(AND, $2); }
+ | T_OR reg3 { $$ = INSTRUCTION_ARGS(OR, $2); }
+ | T_XOR reg3 { $$ = INSTRUCTION_ARGS(XOR, $2); }
+ | T_LSL reg3 { $$ = INSTRUCTION_ARGS(LSL, $2); }
+ | T_LSR reg3 { $$ = INSTRUCTION_ARGS(LSR, $2); }
+ | T_ASL reg3 { $$ = INSTRUCTION_ARGS(ASL, $2); }
+ | T_ASR reg3 { $$ = INSTRUCTION_ARGS(ASR, $2); }
+ | T_ROL reg3 { $$ = INSTRUCTION_ARGS(ROL, $2); }
+ | T_ROR reg3 { $$ = INSTRUCTION_ARGS(ROR, $2); }
+ | T_NOT reg2 { $$ = INSTRUCTION_ARGS(NOT, $2); }
+ | T_NEG reg2 { $$ = INSTRUCTION_ARGS(NEG, $2); }
+ | T_BTC reg2 { $$ = INSTRUCTION_ARGS(BTC, $2); }
+ | T_BTS reg2 { $$ = INSTRUCTION_ARGS(BTS, $2); }
+ | T_MOV reg2 { $$ = INSTRUCTION_ARGS(MOV, $2); }
+ | T_ST_B regp_reg { $$ = INSTRUCTION_ARGS(ST_B, $2); }
+ | T_ST_W regp_reg { $$ = INSTRUCTION_ARGS(ST_W, $2); }
+ | T_LD_BL reg_regp { $$ = INSTRUCTION_ARGS(LD_BL, $2); }
+ | T_LD_BH reg_regp { $$ = INSTRUCTION_ARGS(LD_BH, $2); }
+ | T_LD_W reg_regp { $$ = INSTRUCTION_ARGS(LD_W, $2); }
| T_LDI_BL
{ $$ = INSTRUCTION(LDI_BL); }
| T_LDI_BH
@@ -142,14 +133,19 @@ inst: T_ADD
{ $$ = INSTRUCTION(BLE); }
| T_BRA
{ $$ = INSTRUCTION(BRA); }
- | T_JMP
- { $$ = INSTRUCTION(JMP); }
+ | T_JMP regp { $$ = INSTRUCTION_ARGS(JMP, $2); }
| T_ADDPC
{ $$ = INSTRUCTION(ADDPC); }
| T_NOP
{ $$ = INSTRUCTION(NOP); }
;
+reg2: T_SPACE T_REG "," T_REG { $$ = MKARGS($2, $4); }
+reg3: T_SPACE T_REG "," T_REG "," T_REG { $$ = MKARGS($2, $4, $6); }
+regp: T_SPACE T_REGPTR { $$ = MKARGS($2); }
+regp_reg: T_SPACE T_REGPTR "," T_REG { $$ = MKARGS($2, $4); }
+reg_regp: T_SPACE T_REG "," T_REGPTR { $$ = MKARGS($2, $4); }
+
eol: T_EOL
| T_SPACE T_EOL
;