-
Notifications
You must be signed in to change notification settings - Fork 0
/
ir.h
170 lines (142 loc) · 3.05 KB
/
ir.h
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/**
* @file ir.h
* @author MeerkatBoss (solodovnikov.ia@phystech.edu)
*
* @brief
*
* @version 0.1
* @date 2023-05-16
*
* @copyright Copyright MeerkatBoss (c) 2023
*/
#ifndef __DATA_STRUCTURES_INTERMEDIATE_REPR_IR_H
#define __DATA_STRUCTURES_INTERMEDIATE_REPR_IR_H
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
enum ir_op
{
IR_NOP = 0,
IR_MOV, IR_CMOV,
IR_PUSH, IR_POP,
IR_ADD, IR_SUB,
IR_MUL, IR_DIV,
IR_NEG,
IR_AND, IR_OR,
IR_XOR, IR_NOT,
IR_CMP, IR_TEST,
IR_JMP,
IR_CALL, IR_RET,
IR_SYSCALL
};
enum ir_cond_flags
{
IR_COND_NONE = 0,
IR_COND_GREATER, IR_COND_NOT_GREATER,
IR_COND_LESS, IR_COND_NOT_LESS,
IR_COND_EQUAL, IR_COND_NOT_EQUAL
};
enum ir_reg
{
IR_REG_NONE = 0,
IR_REG_RAX, IR_REG_RBX, IR_REG_RCX, IR_REG_RDX,
IR_REG_RSI, IR_REG_RDI, IR_REG_RSP, IR_REG_RBP,
IR_REG_R8, IR_REG_R9, IR_REG_R10, IR_REG_R11,
IR_REG_R12, IR_REG_R13, IR_REG_R14, IR_REG_R15
};
enum ir_operand_flags
{
IR_OPERAND_NONE = 0,
IR_OPERAND_IMM = 1,
IR_OPERAND_REG = 2,
IR_OPERAND_MEM = 4
};
struct ir_operand
{
unsigned flags;
ir_reg reg;
long immediate;
};
struct ir_node;
typedef ir_node* ir_node_ptr;
struct ir_node
{
size_t node_id;
bool is_valid;
ir_op operation;
ir_operand operand1,
operand2;
ir_cond_flags flags;
ir_node_ptr jump_target;
size_t addr;
size_t encoded_length;
unsigned char bytes[16];
ir_node_ptr next;
};
/**
* @brief Print verbose information about IR to specified file
*
* @param[in] head Start of IR linked list
* @param[in] output Output stream
*
*/
void ir_list_dump(ir_node* head, FILE* output);
/**
* @brief Write compiled IR to file
*
* @param[in] head Start of IR linked list
* @param[in] output Output stream (in binary mode)
*
*/
void ir_list_write(const ir_node* head, FILE* output);
/**
* @brief Free all nodes in a linked list of IR nodes
*
* @param[in] head Start of IR linked list
*
*/
void ir_list_clear(ir_node* head);
/**
* @brief Insert new IR node after specified
*
* @param[inout] tail Node to insert after
* @param[inout] node Inserted node
*
* @return `node`
*/
inline ir_node* ir_list_insert_after(ir_node* tail, ir_node* node)
{
node->next = tail->next;
tail->next = node;
return node;
}
#define ARRAY_ELEMENT ir_node_ptr
#include "array/dynamic_array.h"
#undef ARRAY_ELEMENT
typedef dynamic_array(ir_node_ptr) ir_node_stack;
__always_inline
static void ir_stack_ctor(ir_node_stack* stack)
{
array_ctor(stack);
}
__always_inline
static void ir_stack_dtor(ir_node_stack* stack)
{
array_dtor(stack);
}
__always_inline
static void ir_stack_push(ir_node_stack* stack, ir_node* node)
{
array_push(stack, node);
}
__always_inline
static void ir_stack_pop(ir_node_stack* stack)
{
array_pop(stack);
}
__always_inline
static ir_node* ir_stack_top(const ir_node_stack* stack)
{
return *array_back(stack);
}
#endif /* ir.h */