diff --git a/src/as/codegen.c b/src/as/codegen.c new file mode 100644 index 0000000..3d8c76c --- /dev/null +++ b/src/as/codegen.c @@ -0,0 +1,61 @@ +/* codegen.c + * + * Copyright (C) 2018 Henrik Hautakoski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +#include "codegen.h" + +void codegen_emit(struct ast_instr* instr, symtab_t* symbols, uint8_t* out) { + + out[0] = instr->opcode << 4; + + if (instr->n_operands < 1) + // No operands, return + return; + + // J-Type (We don't have labels yet, so this is just a address) + if (instr->operands[0].type == DATATYPE_NUMBER) { + //if (instr->operands[0].type == DATATYPE_STRING) { + uint16_t addr; + + /* if (symtab_get(symbols, instr->operands[0].s, &addr)) { + out[0] |= (addr >> 8); + out[1] = addr; + }*/ + addr = instr->operands[0].n; + + out[0] |= (addr >> 8); + out[1] = addr; + } + // R/RI or I + else if (instr->operands[0].type == DATATYPE_REGISTER) { + + out[0] |= instr->operands[0].r & 0xF; + + // I + if (instr->operands[1].type == DATATYPE_NUMBER) { + + out[1] = instr->operands[1].n; + } + // R/RI-Type + else if (instr->operands[1].type == DATATYPE_REGISTER && + (instr->operands[2].type == DATATYPE_REGISTER || instr->operands[2].type == DATATYPE_NUMBER)) { + + out[1] = (instr->operands[1].r << 4) | (instr->operands[2].r & 0xF); + } + } +} diff --git a/src/as/instr_encode.h b/src/as/codegen.h similarity index 82% rename from src/as/instr_encode.h rename to src/as/codegen.h index 0f01304..8964321 100644 --- a/src/as/instr_encode.h +++ b/src/as/codegen.h @@ -1,4 +1,4 @@ -/* instr_encode.h +/* codegen.h * * Copyright (C) 2018 Henrik Hautakoski * @@ -17,11 +17,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ -#ifndef ASM_INSTR_ENCODE_H -#define ASM_INSTR_ENCODE_H +#ifndef ASM_CODEGEN_H +#define ASM_CODEGEN_H -#include +#include "ast.h" -void instr_encode(struct instr* instr, uint16_t *out); +void codegen_emit(struct ast_instr* ast, symtab_t* symbols, uint8_t* out); -#endif /* ASM_INSTR_ENCODE_H */ +#endif /* ASM_CODEGEN_H */ diff --git a/src/as/instr_encode.c b/src/as/instr_encode.c deleted file mode 100644 index 1478928..0000000 --- a/src/as/instr_encode.c +++ /dev/null @@ -1,50 +0,0 @@ -/* instr_encode.c - * - * Copyright (C) 2018 Henrik Hautakoski - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ -#include -#include -#include "instr_encode.h" - -void instr_encode(struct instr* instr, uint16_t *out) { - - uint8_t *p = (uint8_t *) out; - - *out = 0; - *p = instr->opcode << 4; - - if (instr->opcode == OP_NOOP) { - // Do nothing. - } else if (instr->opcode == OP_JMP) { - *p |= (instr->j.addr >> 8); - *(p+1) = instr->j.addr; - } else { - *p |= instr->r.rs; - - // I-Type - if (instr->opcode == OP_MOVL || instr->opcode == OP_MOVH - || instr->opcode == OP_JR || instr->opcode == OP_INT) { - - *(p+1) = instr->i.imm; - } - // R/RI-Type - else { - *(p+1) = (instr->r.r0 << 4) | instr->r.r1; - } - } -}