diff options
| -rw-r--r-- | Makefile | 6 | ||||
| -rw-r--r-- | src/as_codegen.c | 94 | ||||
| -rw-r--r-- | src/as_codegen.h | 18 | ||||
| -rw-r--r-- | src/as_op.c | 21 | ||||
| -rw-r--r-- | src/as_op.h | 5 | ||||
| -rw-r--r-- | tests/test_as_parser.c | 1 |
6 files changed, 125 insertions, 20 deletions
@@ -1,6 +1,8 @@ target = fvm -cflags = -g -fsanitize=address -fno-omit-frame-pointer -ldflags = -lm -fsanitize=address -fno-omit-frame-pointer +# cflags = -g -fsanitize=address -fno-omit-frame-pointer +# ldflags = -lm -fsanitize=address -fno-omit-frame-pointer +cflags = -g +ldflags = -lm cc = gcc csc = chicken-csc diff --git a/src/as_codegen.c b/src/as_codegen.c new file mode 100644 index 0000000..98092d7 --- /dev/null +++ b/src/as_codegen.c @@ -0,0 +1,94 @@ +#include "as_codegen.h" +#include "as_op.h" +#include "fvm.h" + +struct bytearray *new_bytearray(struct allocator *alct); +void bytearray_emit8(struct bytearray *self, int8_t data); +void bytearray_emit64(struct bytearray *self, int64_t data); + + +int8_t op_bytecode(enum op op) { + if (op == OP_SSP) return (int8_t)FVM_OP_SSP; + if (op == OP_SP) return (int8_t)FVM_OP_SP; + if (op == OP_SBP) return (int8_t)FVM_OP_SBP; + if (op == OP_BP) return (int8_t)FVM_OP_BP; + if (op == OP_PC) return (int8_t)FVM_OP_PC; + if (op == OP_RV) return (int8_t)FVM_OP_RV; + if (op == OP_SRV) return (int8_t)FVM_OP_SRV; + + if (op == OP_DUP) return (int8_t)FVM_OP_DUP; + if (op == OP_POP) return (int8_t)FVM_OP_POP; + if (op == OP_SWAP) return (int8_t)FVM_OP_SWAP; + if (op == OP_OVER) return (int8_t)FVM_OP_OVER; + if (op == OP_ROT) return (int8_t)FVM_OP_ROT; + + if (op == OP_ADD) return (int8_t)FVM_OP_ADD; + if (op == OP_SUB) return (int8_t)FVM_OP_SUB; + if (op == OP_DIV) return (int8_t)FVM_OP_DIV; + if (op == OP_MUL) return (int8_t)FVM_OP_MUL; + if (op == OP_MOD) return (int8_t)FVM_OP_MOD; + + if (op == OP_SHR) return (int8_t)FVM_OP_SHR; + if (op == OP_SHL) return (int8_t)FVM_OP_SHL; + if (op == OP_SAR) return (int8_t)FVM_OP_SAR; + + if (op == OP_AND) return (int8_t)FVM_OP_AND; + if (op == OP_OR) return (int8_t)FVM_OP_OR; + if (op == OP_NOT) return (int8_t)FVM_OP_NOT; + + if (op == OP_BITAND) return (int8_t)FVM_OP_BITAND; + if (op == OP_BITOR) return (int8_t)FVM_OP_BITOR; + if (op == OP_XOR) return (int8_t)FVM_OP_XOR; + if (op == OP_INVERT) return (int8_t)FVM_OP_INVERT; + + if (op == OP_GT) return (int8_t)FVM_OP_GT; + if (op == OP_LT) return (int8_t)FVM_OP_LT; + if (op == OP_GE) return (int8_t)FVM_OP_GE; + if (op == OP_LE) return (int8_t)FVM_OP_LE; + if (op == OP_EQ) return (int8_t)FVM_OP_EQ; + if (op == OP_NEQ) return (int8_t)FVM_OP_NEQ; + + if (op == OP_RET) return (int8_t)FVM_OP_RET; + + if (op == OP_FADD) return (int8_t)FVM_OP_FADD; + if (op == OP_FSUB) return (int8_t)FVM_OP_FSUB; + if (op == OP_FDIV) return (int8_t)FVM_OP_FDIV; + if (op == OP_FMUL) return (int8_t)FVM_OP_FMUL; + + if (op == OP_FGT) return (int8_t)FVM_OP_FGT; + if (op == OP_FLT) return (int8_t)FVM_OP_FLT; + if (op == OP_FGE) return (int8_t)FVM_OP_FGE; + if (op == OP_FLE) return (int8_t)FVM_OP_FLE; + if (op == OP_FEQ) return (int8_t)FVM_OP_FEQ; + if (op == OP_FNEQ) return (int8_t)FVM_OP_FNEQ; + + if (op == OP_FTI) return (int8_t)FVM_OP_FTI; + if (op == OP_ITF) return (int8_t)FVM_OP_ITF; + + if (op == OP_EXIT) return (int8_t)FVM_OP_EXIT; + + return (int8_t)-1; +} + +struct result codegen(struct allocator *alct, struct prog *prog, struct sym_table tbl) { + struct stmt ** stmts = prog->stmts->stmts; + size_t offset = 0; + struct bytearray* output = new_bytearray(alct); + for (int i = 0; ; i++) { + if (stmts[i] == NULL) { + break; + } + struct instr *instruction = stmts[i]->instr; + enum op op = instruction->op; + if (op_size(op) == 1) { + int8_t code = op_bytecode(op); + bytearray_emit8(output, code); + offset += 1; + } else if (op_size(op) == 9) { + + } else if (op_size(op) == 10) { + + } + } + return ok(output); +} diff --git a/src/as_codegen.h b/src/as_codegen.h new file mode 100644 index 0000000..17e6ca9 --- /dev/null +++ b/src/as_codegen.h @@ -0,0 +1,18 @@ +#ifndef FVM_AS_CODEGEN_H_ +#define FVM_AS_CODEGEN_H_ + +#include "as_analyzer.h" +#include <stdlib.h> + +struct bytearray { + size_t cap; + size_t len; + char* buf; +}; + +void bytearray_emit8(struct bytearray *self, int8_t data); +void bytearray_emit64(struct bytearray *self, int64_t data); + +struct result codegen(struct allocator *alct, struct prog *prog, struct sym_table tbl); + +#endif // FVM_AS_CODEGEN_H_ diff --git a/src/as_op.c b/src/as_op.c index 67c91ff..71ba0f3 100644 --- a/src/as_op.c +++ b/src/as_op.c @@ -19,6 +19,7 @@ struct op_table_entry op_table [] = { {OP_SRV, "srv"}, // OP_IMM, {OP_IMM, "imm"}, + {OP_IMM, "rel"}, // OP_LD8, OP_LD16, OP_LD32, OP_LD, {OP_LD8, "ld8"}, {OP_LD16, "ld16"}, @@ -93,7 +94,7 @@ struct op_table_entry op_table [] = { }; int op_size(enum op op) { - if (op == OP_IMM) { + if (op == OP_IMM || op == OP_REL) { return 8 + 1; } if (op == OP_CALL @@ -112,21 +113,11 @@ int op_size(enum op op) { return 1; } -int is_ld_op(enum op op) { - if (op == OP_LD - || op == OP_LD8 - || op == OP_LD16 - || op == OP_LD32) { +int is_pseudo_op(enum op op) { + if (op == OP_LDARG || op == OP_STARG) { return 1; } - return 0; -} - -int is_st_op(enum op op) { - if (op == OP_ST - || op == OP_ST8 - || op == OP_ST16 - || op == OP_ST32) { + if (op == OP_LDVAR || op == OP_STVAR) { return 1; } return 0; @@ -141,6 +132,6 @@ enum op str2op(const char* str) { return OP_END; } -int isOp(const char *str) { +int is_op(const char *str) { return OP_END != str2op(str); } diff --git a/src/as_op.h b/src/as_op.h index d02c29f..cb45fc1 100644 --- a/src/as_op.h +++ b/src/as_op.h @@ -3,7 +3,7 @@ enum op { OP_SP, OP_SSP, OP_BP, OP_SBP, OP_PC, OP_RV, OP_SRV, - OP_IMM, + OP_IMM, OP_REL, OP_LD8, OP_LD16, OP_LD32, OP_LD, OP_ST8, OP_ST16, OP_ST32, OP_ST, OP_DUP, OP_POP, OP_SWAP, OP_OVER, OP_ROT, @@ -24,8 +24,7 @@ enum op { enum op str2op(const char *str); int isOp(const char *str); int op_size(enum op op); -int is_ld_op(enum op); -int is_st_op(enum op); +int is_pseudo_op(enum op op); #endif diff --git a/tests/test_as_parser.c b/tests/test_as_parser.c index 096031f..62a4b8d 100644 --- a/tests/test_as_parser.c +++ b/tests/test_as_parser.c @@ -41,6 +41,7 @@ int main(int argc, char** argv) { assert(stmts[4]->instr->op == OP_EQ); printf("[PASS] assembler parser\n"); + fclose(fp); delete_allocator(alct); return 0; } |
