summaryrefslogtreecommitdiff
path: root/masm/gen.h
blob: 19f575c2c0ed8b34c8879e172b3bf8759e616222 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/* Copyright (c) 2024 Freya Murphy */

#ifndef __GEN_H__
#define __GEN_H__

#include <mlimits.h>
#include <mips32.h>
#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;
};

void section_free(struct section *section);

///
/// instruction generation state
///

struct gen_ins_state {
	// rd,rst,rt
	enum mips32_register rd;
	enum mips32_register rs;
	enum mips32_register rt;

	// immd
	uint16_t immd;

	// offset(base)
	uint16_t offset;
	enum mips32_register base;

	// target
	uint32_t target;

	// current referencd label
	struct string *label;
};

///
/// grammer type
///

enum grammer_type {
	GMR_RD,
	GMR_RS,
	GMR_RT,
	GMR_IMMD,
	GMR_OFFSET,
	GMR_OFFSET_BASE,
	GMR_TARGET,
	GMR_HI,
	GMR_LO,
};

///
/// 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;
};

/* generate the input as mips32r6 */
int generate_mips32r6(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__ */