From 50e67fb3e640a9e6e1260ca984582c9a9b8d5375 Mon Sep 17 00:00:00 2001 From: Bobby Bingham Date: Sat, 14 Jan 2017 14:44:18 -0600 Subject: nqasm: Handle register and register indirect arguments --- Makefile | 2 +- lexer.l | 7 +++++ nqasm.c | 15 ++++++++--- nqasm.h | 11 ++++++++ parser.y | 94 +++++++++++++++++++++++++++++++--------------------------------- 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#] addpc/{EOI} { BEGIN(args); return T_ADDPC; } nop/{EOI} { BEGIN(args); return T_NOP; } +r{REGNUM} { SETVALUE(yytext[1]-'0'); return T_REG; } +@r{REGNUM} { SETVALUE(yytext[2]-'0'); return T_REGPTR; } +{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 #include #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 T_REG +%token T_REGPTR +%token T_COMMA "," + %type inst +%type reg2 +%type reg3 +%type regp +%type regp_reg +%type 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 ; -- cgit v1.2.3