diff options
author | Bobby Bingham <koorogi@koorogi.info> | 2017-01-14 14:44:18 -0600 |
---|---|---|
committer | Bobby Bingham <koorogi@koorogi.info> | 2017-01-15 23:19:04 -0600 |
commit | 50e67fb3e640a9e6e1260ca984582c9a9b8d5375 (patch) | |
tree | d4d12ed5a5787e30e1062ced1edc6c7979afe77e | |
parent | a743db94541bebafff23c8a490dbce3f55d69712 (diff) |
nqasm: Handle register and register indirect arguments
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | lexer.l | 7 | ||||
-rw-r--r-- | nqasm.c | 15 | ||||
-rw-r--r-- | nqasm.h | 11 | ||||
-rw-r--r-- | parser.y | 94 |
5 files changed, 76 insertions, 53 deletions
@@ -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 @@ -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; } @@ -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) @@ -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 *); @@ -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 ; |