diff options
Diffstat (limited to 'tasm/include')
| -rw-r--r-- | tasm/include/tasm/assembler.h | 51 | ||||
| -rw-r--r-- | tasm/include/tasm/bits.h | 81 | ||||
| -rw-r--r-- | tasm/include/tasm/parser.h | 56 | ||||
| -rw-r--r-- | tasm/include/tasm/regs.h | 357 |
4 files changed, 545 insertions, 0 deletions
diff --git a/tasm/include/tasm/assembler.h b/tasm/include/tasm/assembler.h new file mode 100644 index 0000000..d687dbb --- /dev/null +++ b/tasm/include/tasm/assembler.h @@ -0,0 +1,51 @@ +#ifndef TASM_ASSEMBLER_H +#define TASM_ASSEMBLER_H + +#include <tasm/regs.h> +#include <tri.h> + +struct asm_ctx; + +enum asm_reloc { + /* absolute LUI + ADDI */ + RELOC_LA, + /* relative AUIPC + ADDI (currently unimplemented) */ + RELOC_LR, + RELOC_B, + RELOC_J, +}; + +tri_t parse_imm(const char *imm); + +void emit_r(struct asm_ctx *ctx, tri_t opcode, + enum gpr_num rd, tri_t fn0, enum gpr_num rs1, + enum gpr_num rs2, tri_t fn5); + +void emit_i(struct asm_ctx *ctx, tri_t opcode, + enum gpr_num rd, tri_t fn0, enum gpr_num rs1, tri_t imm9); + +void emit_s(struct asm_ctx *ctx, tri_t opcode, + tri_t fn0, enum gpr_num rs1, enum gpr_num rs2, tri_t imm9); + +void emit_u(struct asm_ctx *ctx, tri_t opcode, + enum gpr_num rd, tri_t imm18); + +void emit_d(struct asm_ctx *ctx, tri_t opcode, + enum gpr_num rd, enum gpr_num rs1, enum gpr_num rs2, tri_t imm10); + +/* emits a relocation for the previous instruction, very important to keep in + * mind! */ +void emit_reloc(struct asm_ctx *ctx, enum asm_reloc reloc, const char *name); +void emit_label(struct asm_ctx *ctx, const char *name); + +tri_t check_nop(const char *nop); +tri_t check_nop3(const char *nop3); +void check_shift(tri_t shmt); + +tri_t check_csr(const char *csr); +tri_t check_width(const char *width); + +int process_file(struct asm_ctx *ctx, const char *file); +int assemble(const char *outfile, const char *infile); + +#endif diff --git a/tasm/include/tasm/bits.h b/tasm/include/tasm/bits.h new file mode 100644 index 0000000..2070425 --- /dev/null +++ b/tasm/include/tasm/bits.h @@ -0,0 +1,81 @@ +#ifndef TASM_BITS_H +#define TASM_BITS_H + +#include <tasm/regs.h> +#include <tri.h> + +#define OPCODE_OP_IMM 0b0000000000 +#define OP_IMM_ADDI 0b0000000000 +#define OP_IMM_SUBI 0b0000000001 +#define OP_IMM_SLTI 0b0000000010 +#define OP_IMM_SGEI 0b0000000100 +#define OP_IMM_SEQI 0b0000000101 +#define OP_IMM_SNEI 0b0000000110 +#define OP_IMM_SLLI 0b0000001000 +#define OP_IMM_SRLI 0b0000001001 +#define OP_IMM_UNOP 0b0000001010 + +#define OPCODE_OP 0b0000000001 +#define OP_ADD 0b0000000000 +#define OP_SUB 0b0000000001 +#define OP_SLT 0b0000000010 +#define OP_SGE 0b0000000100 +#define OP_SEQ 0b0000000101 +#define OP_SNE 0b0000000110 +#define OP_SLL 0b0000001000 +#define OP_SRL 0b0000001001 +#define OP_MUL 0b0000001010 +#define OP_DIV 0b0000010000 +#define OP_REM 0b0000010001 + +#define OPCODE_LUI 0b0000000010 +#define OPCODE_AUIPC 0b0000000100 +#define OPCODE_JAL 0b0000000101 +#define OPCODE_JALR 0b0000000110 + +#define OPCODE_BRANCH 0b0000001000 +#define BRANCH_BEQ 0b0000000000 +#define BRANCH_BNE 0b0000000001 +#define BRANCH_BLT 0b0000000010 +#define BRANCH_BGE 0b0000000100 + +#define OPCODE_LOAD 0b0000001001 +#define OPCODE_STORE 0b0000001010 +#define STORE_CST 0b0000000001 + +#define OPCODE_SYSTEM 0b0000010000 +#define SYSTEM_ECALL 0b0000000000 +#define SYSTEM_EBREAK 0b0000000001 +#define SYSTEM_PCALL 0b0000000010 +#define SYSTEM_CSRRW 0b0000000100 +#define SYSTEM_CSRRS 0b0000000101 +#define SYSTEM_CSRRC 0b0000000110 + +#define OPCODE_MEM 0b0000010001 +#define MEM_FENCE 0b0000000000 +#define MEM_STT 0b0000000001 +#define MEM_ENT 0b0000000010 +#define MEM_CAT 0b0000000100 + +#define OPCODE_DIOP 0b0000010010 + +#define WIDTH_W 0b0100000000 +#define WIDTH_T 0b0000000000 + +#define nonnull __attribute__((nonnull)) + +tri_t parse_opcode(tri_t i); + +tri_t build_r(tri_t opcode, tri_t rd, tri_t fn0, tri_t rs1, tri_t rs2, tri_t fn5); +void nonnull parse_r(tri_t i, tri_t *rd, tri_t *rs1, tri_t *rs2, tri_t *fn0, tri_t *fn5); + +tri_t build_i(tri_t opcode, tri_t rd, tri_t fn0, tri_t rs1, tri_t imm9); +void nonnull parse_i(tri_t i, tri_t *rd, tri_t *fn0, tri_t *rs1, tri_t *imm9); + +tri_t build_s(tri_t opcode, tri_t imm4, tri_t fn0, tri_t rs1, tri_t rs2, tri_t imm5); +void nonnull parse_s(tri_t i, tri_t *imm4, tri_t *fn0, tri_t *rs1, tri_t *rs2, tri_t *imm5); + +tri_t build_u(tri_t opcode, tri_t rd, tri_t imm18); +void nonnull parse_u(tri_t i, tri_t *rd, tri_t *imm18); + +#endif diff --git a/tasm/include/tasm/parser.h b/tasm/include/tasm/parser.h new file mode 100644 index 0000000..20da00c --- /dev/null +++ b/tasm/include/tasm/parser.h @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: copyleft-next-0.3.1 */ +/* Copyright 2023 Kim Kuparinen < kimi.h.kuparinen@gmail.com > */ + +#ifndef PARSER_H +#define PARSER_H + +/** + * @file parser.h + * + * Glue file to get lexer and parser to play nice. + */ + +#include <stddef.h> +#include <stdbool.h> + +/** Stuff the parser needs to do its job. */ +struct parser { + /** Whether parsing failed or succeeded. */ + bool failed; + /** Lexer. Parser owns the lexer and is responsible for initializing + * and destroyint the lexer. + */ + void *lexer; + + /** File content in memory. */ + const char *buf; + /** Filename. */ + const char *fname; + /** How deeply we've nested comments. */ + size_t comment_nesting; +}; + +/** + * Create new parser. + * + * @return Created parser. + */ +struct parser *create_parser(); + +/** + * Destroy parser. + * + * @param p Parser to destroy. + */ +void destroy_parser(struct parser *p); + +/** + * Run parser on buffer \p buf with name \p fname. + * + * @param p Parser to run. + * @param fname Name of file \p buf was read from. + * @param buf Contents of \p fname. + */ +void parse(struct parser *p, struct asm_ctx *ctx, const char *fname, const char *buf); + +#endif /* PARSER_H */ diff --git a/tasm/include/tasm/regs.h b/tasm/include/tasm/regs.h new file mode 100644 index 0000000..3018ea4 --- /dev/null +++ b/tasm/include/tasm/regs.h @@ -0,0 +1,357 @@ +#ifndef TASM_REGS_H +#define TASM_REGS_H + +#include <stdlib.h> +#include <stdio.h> + +enum gpr_num { + X0_NUM, + X1_NUM, + X2_NUM, + X3_NUM, + X4_NUM, + X5_NUM, + X6_NUM, + X7_NUM, + X8_NUM, + X9_NUM, + X10_NUM, + X11_NUM, + X12_NUM, + X13_NUM, + X14_NUM, + X15_NUM, + X16_NUM, + X17_NUM, + X18_NUM, + X19_NUM, + X20_NUM, + X21_NUM, + X22_NUM, + X23_NUM, + X24_NUM, + X25_NUM, + X26_NUM, + X27_NUM, + X28_NUM, + X29_NUM, + X30_NUM, + X31_NUM, + X32_NUM, + X33_NUM, + X34_NUM, + X35_NUM, + X36_NUM, + X37_NUM, + X38_NUM, + X39_NUM, + X40_NUM, + X41_NUM, + X42_NUM, + X43_NUM, + X44_NUM, + X45_NUM, + X46_NUM, + X47_NUM, + X48_NUM, + X49_NUM, + X50_NUM, + X51_NUM, + X52_NUM, + X53_NUM, + X54_NUM, + X55_NUM, + X56_NUM, + X57_NUM, + X58_NUM, + X59_NUM, + X60_NUM, + X61_NUM, + X62_NUM, + X63_NUM, + X64_NUM, + X65_NUM, + X66_NUM, + X67_NUM, + X68_NUM, + X69_NUM, + X70_NUM, + X71_NUM, + X72_NUM, + X73_NUM, + X74_NUM, + X75_NUM, + X76_NUM, + X77_NUM, + X78_NUM, + X79_NUM, + X80_NUM, +}; + +/* generated with a script */ +enum gpr_tri { + X41 = 170, + X42 = 168, + X43 = 169, + X44 = 162, + X45 = 160, + X46 = 161, + X47 = 166, + X48 = 164, + X49 = 165, + X50 = 138, + X51 = 136, + X52 = 137, + X53 = 130, + X54 = 128, + X55 = 129, + X56 = 134, + X57 = 132, + X58 = 133, + X59 = 154, + X60 = 152, + X61 = 153, + X62 = 146, + X63 = 144, + X64 = 145, + X65 = 150, + X66 = 148, + X67 = 149, + X68 = 42, + X69 = 40, + X70 = 41, + X71 = 34, + X72 = 32, + X73 = 33, + X74 = 38, + X75 = 36, + X76 = 37, + X77 = 10, + X78 = 8, + X79 = 9, + X80 = 2, + X0 = 0, + X1 = 1, + X2 = 6, + X3 = 4, + X4 = 5, + X5 = 26, + X6 = 24, + X7 = 25, + X8 = 18, + X9 = 16, + X10 = 17, + X11 = 22, + X12 = 20, + X13 = 21, + X14 = 106, + X15 = 104, + X16 = 105, + X17 = 98, + X18 = 96, + X19 = 97, + X20 = 102, + X21 = 100, + X22 = 101, + X23 = 74, + X24 = 72, + X25 = 73, + X26 = 66, + X27 = 64, + X28 = 65, + X29 = 70, + X30 = 68, + X31 = 69, + X32 = 90, + X33 = 88, + X34 = 89, + X35 = 82, + X36 = 80, + X37 = 81, + X38 = 86, + X39 = 84, + X40 = 85, +}; + +static inline enum gpr_tri gpr_tri(enum gpr_num g) +{ + switch (g) { + case X0_NUM: return X0; + case X1_NUM: return X1; + case X2_NUM: return X2; + case X3_NUM: return X3; + case X4_NUM: return X4; + case X5_NUM: return X5; + case X6_NUM: return X6; + case X7_NUM: return X7; + case X8_NUM: return X8; + case X9_NUM: return X9; + case X10_NUM: return X10; + case X11_NUM: return X11; + case X12_NUM: return X12; + case X13_NUM: return X13; + case X14_NUM: return X14; + case X15_NUM: return X15; + case X16_NUM: return X16; + case X17_NUM: return X17; + case X18_NUM: return X18; + case X19_NUM: return X19; + case X20_NUM: return X20; + case X21_NUM: return X21; + case X22_NUM: return X22; + case X23_NUM: return X23; + case X24_NUM: return X24; + case X25_NUM: return X25; + case X26_NUM: return X26; + case X27_NUM: return X27; + case X28_NUM: return X28; + case X29_NUM: return X29; + case X30_NUM: return X30; + case X31_NUM: return X31; + case X32_NUM: return X32; + case X33_NUM: return X33; + case X34_NUM: return X34; + case X35_NUM: return X35; + case X36_NUM: return X36; + case X37_NUM: return X37; + case X38_NUM: return X38; + case X39_NUM: return X39; + case X40_NUM: return X40; + case X41_NUM: return X41; + case X42_NUM: return X42; + case X43_NUM: return X43; + case X44_NUM: return X44; + case X45_NUM: return X45; + case X46_NUM: return X46; + case X47_NUM: return X47; + case X48_NUM: return X48; + case X49_NUM: return X49; + case X50_NUM: return X50; + case X51_NUM: return X51; + case X52_NUM: return X52; + case X53_NUM: return X53; + case X54_NUM: return X54; + case X55_NUM: return X55; + case X56_NUM: return X56; + case X57_NUM: return X57; + case X58_NUM: return X58; + case X59_NUM: return X59; + case X60_NUM: return X60; + case X61_NUM: return X61; + case X62_NUM: return X62; + case X63_NUM: return X63; + case X64_NUM: return X64; + case X65_NUM: return X65; + case X66_NUM: return X66; + case X67_NUM: return X67; + case X68_NUM: return X68; + case X69_NUM: return X69; + case X70_NUM: return X70; + case X71_NUM: return X71; + case X72_NUM: return X72; + case X73_NUM: return X73; + case X74_NUM: return X74; + case X75_NUM: return X75; + case X76_NUM: return X76; + case X77_NUM: return X77; + case X78_NUM: return X78; + case X79_NUM: return X79; + case X80_NUM: return X80; + } + + fprintf(stderr, "illegal gpr num: %d\n", g); + abort(); + return -1; +} + +static inline enum gpr_num gpr_num(enum gpr_tri t) +{ + switch (t) { + case X0: return X0_NUM; + case X1: return X1_NUM; + case X2: return X2_NUM; + case X3: return X3_NUM; + case X4: return X4_NUM; + case X5: return X5_NUM; + case X6: return X6_NUM; + case X7: return X7_NUM; + case X8: return X8_NUM; + case X9: return X9_NUM; + case X10: return X10_NUM; + case X11: return X11_NUM; + case X12: return X12_NUM; + case X13: return X13_NUM; + case X14: return X14_NUM; + case X15: return X15_NUM; + case X16: return X16_NUM; + case X17: return X17_NUM; + case X18: return X18_NUM; + case X19: return X19_NUM; + case X20: return X20_NUM; + case X21: return X21_NUM; + case X22: return X22_NUM; + case X23: return X23_NUM; + case X24: return X24_NUM; + case X25: return X25_NUM; + case X26: return X26_NUM; + case X27: return X27_NUM; + case X28: return X28_NUM; + case X29: return X29_NUM; + case X30: return X30_NUM; + case X31: return X31_NUM; + case X32: return X32_NUM; + case X33: return X33_NUM; + case X34: return X34_NUM; + case X35: return X35_NUM; + case X36: return X36_NUM; + case X37: return X37_NUM; + case X38: return X38_NUM; + case X39: return X39_NUM; + case X40: return X40_NUM; + case X41: return X41_NUM; + case X42: return X42_NUM; + case X43: return X43_NUM; + case X44: return X44_NUM; + case X45: return X45_NUM; + case X46: return X46_NUM; + case X47: return X47_NUM; + case X48: return X48_NUM; + case X49: return X49_NUM; + case X50: return X50_NUM; + case X51: return X51_NUM; + case X52: return X52_NUM; + case X53: return X53_NUM; + case X54: return X54_NUM; + case X55: return X55_NUM; + case X56: return X56_NUM; + case X57: return X57_NUM; + case X58: return X58_NUM; + case X59: return X59_NUM; + case X60: return X60_NUM; + case X61: return X61_NUM; + case X62: return X62_NUM; + case X63: return X63_NUM; + case X64: return X64_NUM; + case X65: return X65_NUM; + case X66: return X66_NUM; + case X67: return X67_NUM; + case X68: return X68_NUM; + case X69: return X69_NUM; + case X70: return X70_NUM; + case X71: return X71_NUM; + case X72: return X72_NUM; + case X73: return X73_NUM; + case X74: return X74_NUM; + case X75: return X75_NUM; + case X76: return X76_NUM; + case X77: return X77_NUM; + case X78: return X78_NUM; + case X79: return X79_NUM; + case X80: return X80_NUM; + } + + fprintf(stderr, "illegal gpr: %d\n", t); + abort(); + return -1; +} +#endif |
