/* Copyright (c) 2024 Freya Murphy */ #ifndef __GEN_H__ #define __GEN_H__ #include #include #include #include "parse.h" #include "tab.h" // predefine struct generator; /// /// a section /// struct section { // name struct string name; // alignment size_t align; // data char *data; size_t len; size_t size; // permissions bool read; bool write; bool execute; /// reference table struct reference_table reftab; }; /* get a section from the generator by name, and return it into res. if the * section does not exist, one will be created. */ int gen_get_section(struct generator *gen, struct section **res, struct string *name); /* initalize a section */ int section_init(struct section *section, struct string *name); /* free a section */ void section_free(struct section *section); /* extend a section by space bytes plus alignment */ int section_extend(struct section *section, size_t space); /* push data into a section */ int section_push(struct section *section, void *data, size_t len); /* push zeros (empty space) to a section */ int section_zero(struct section *section, size_t len); /// /// instruction generation state /// struct gen_ins_state { // rd,rs,rt enum mips32_register rd; enum mips32_register rs; enum mips32_register rt; // fs,ft enum mips32_fp_register fs; enum mips32_fp_register ft; enum mips32_fp_register fd; // immd uint16_t immd; // cc uint16_t cc; // code uint32_t code; // pos uint32_t pos; // size uint32_t size; // hint uint32_t hint; // hazard barrier bool hb; // 1 bit - 1 // target uint32_t target; // index(base) // offset(base) uint32_t index; uint16_t offset; enum mips32_register base; // current referencd label struct string *label; }; struct gen_ins_override { enum mips32_register reg; enum mips32_fp_register fpreg; uint32_t immd; }; enum grammer_type { // registers GMR_RD, GMR_RS, GMR_RT, // fp registers GMR_FS, GMR_FT, GMR_FD, // numeric fields GMR_IMMD, GMR_CC, GMR_CODE, GMR_POS, GMR_SIZE, GMR_HB, GMR_HINT, // addresses GMR_HI, GMR_LO, GMR_TARGET, GMR_OFFSET, GMR_INDEX_BASE, GMR_OFFSET_BASE, // len __GMR_LEN }; /* Parses the input string and matches it to a grammer type. Returns * the number of characters consumed, or -1 on error. */ int gen_parse_grammer_type(const char *name, enum grammer_type *res); /* Parses a register name, returing 0 on success, 1 on error*/ int gen_parse_register(enum mips32_register *reg, struct string *name); /* Parses a floating point register name, returing 0 on success, 1 on error*/ int gen_parse_fp_register(enum mips32_fp_register *reg, struct string *name); /* Parses the overide expression (after the =) in the dsl for the grammer. * returns the number of characters consumed, or -1 on error. */ int gen_parse_grammer_overide(struct gen_ins_state *state, struct gen_ins_override *over, char *value); /* Given a grammer for an instruction, read all args as values into the * instruction generator state. */ int gen_read_grammer_state(struct generator *gen, struct expr *const expr, struct gen_ins_state *state, struct mips32_grammer *grammer); /* Given a grammer for an instruction, and a read state, output multiple * instructions into the current section in the generator. note: * this write_grammer is different from the read grammer such that * it supports paramater reassignment and overides. */ int gen_write_grammer_state(struct generator *gen, struct gen_ins_state *state, char *write_grammer); /// /// generates assembley /// from a parser stream /// struct generator { struct parser parser; // current instruction table size_t instructions_len; union mips32_instruction *instructions; // current grammer table size_t grammers_len; struct mips32_grammer *grammers; // segments size_t sections_len; size_t sections_size; struct section *sections; // current section struct section *current; // symbol table struct symbol_table symtab; }; /* output the source code lines for a provided expression */ void gen_output_expr(struct generator *gen, struct expr *expr); /* generate the input as mips32r6 */ int generate_mips32r6(struct generator *gen); /* run codegen with the mips32r2 specification */ int generate_mips32r2(struct generator *gen); /* run codegen with the mips32r6 specification */ int generate_mips1(struct generator *gen); /* initalize a generator */ int generator_init(const char *file, struct generator *gen); /* free a generator */ void generator_free(struct generator *gen); #endif /* __GEN_H__ */