mips/masm/gen.h

218 lines
4.5 KiB
C
Raw Permalink Normal View History

2024-10-04 23:41:10 +00:00
/* Copyright (c) 2024 Freya Murphy */
#ifndef __GEN_H__
#define __GEN_H__
#include <mlimits.h>
#include <mips.h>
2024-10-04 23:41:10 +00:00
#include <stdint.h>
#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;
};
2024-10-21 16:27:18 +00:00
/* 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 */
2024-10-04 23:41:10 +00:00
void section_free(struct section *section);
2024-10-21 16:27:18 +00:00
/* 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);
2024-10-04 23:41:10 +00:00
///
/// instruction generation state
///
struct gen_ins_state {
// rd,rs,rt
2024-10-04 23:41:10 +00:00
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;
2024-10-04 23:41:10 +00:00
// immd
2024-10-21 16:27:18 +00:00
uint16_t immd;
// cc
2024-10-21 16:27:18 +00:00
uint16_t cc;
// code
2024-10-21 16:27:18 +00:00
uint32_t code;
// pos
2024-10-21 16:27:18 +00:00
uint32_t pos;
// size
2024-10-21 16:27:18 +00:00
uint32_t size;
// hint
uint32_t hint;
2024-10-04 23:41:10 +00:00
2024-10-21 16:27:18 +00:00
// hazard barrier
bool hb; // 1 bit - 1
2024-10-04 23:41:10 +00:00
// target
uint32_t target;
2024-10-21 16:27:18 +00:00
// index(base)
// offset(base)
uint32_t index;
uint16_t offset;
enum mips32_register base;
2024-10-04 23:41:10 +00:00
// current referencd label
struct string *label;
};
struct gen_ins_override {
enum mips32_register reg;
enum mips32_fp_register fpreg;
uint32_t immd;
};
2024-10-04 23:41:10 +00:00
enum grammer_type {
// registers
2024-10-04 23:41:10 +00:00
GMR_RD,
GMR_RS,
GMR_RT,
// fp registers
GMR_FS,
GMR_FT,
GMR_FD,
// numeric fields
2024-10-04 23:41:10 +00:00
GMR_IMMD,
GMR_CC,
GMR_CODE,
GMR_POS,
GMR_SIZE,
GMR_HB,
GMR_HINT,
// addresses
2024-10-04 23:41:10 +00:00
GMR_HI,
GMR_LO,
2024-10-21 16:27:18 +00:00
GMR_TARGET,
GMR_OFFSET,
GMR_INDEX_BASE,
GMR_OFFSET_BASE,
// len
__GMR_LEN
2024-10-04 23:41:10 +00:00
};
2024-10-21 16:27:18 +00:00
/* 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);
2024-10-04 23:41:10 +00:00
///
/// 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;
};
2024-10-21 16:27:18 +00:00
/* output the source code lines for a provided expression */
void gen_output_expr(struct generator *gen, struct expr *expr);
2024-10-04 23:41:10 +00:00
/* 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);
2024-10-04 23:41:10 +00:00
/* initalize a generator */
int generator_init(const char *file, struct generator *gen);
/* free a generator */
void generator_free(struct generator *gen);
#endif /* __GEN_H__ */