Repository navigation
Expand file tree
/
Copy pathcode_gen.h
More file actions
198 lines (150 loc) · 4.42 KB
/
Copy pathcode_gen.h
File metadata and controls
198 lines (150 loc) · 4.42 KB
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
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
#ifndef _SCC_CODE_GEN_H_
#define _SCC_CODE_GEN_H_
#include "ast.h"
#include "visitor.h"
class Parser;
enum class ParamClass
{
INTEGER,
SSE,
SSEUP,
X87,
X87_UP,
COMPLEX_X87,
NO_CLASS,
MEMORY
};
struct ROData
{
ROData(long ival, int align): _ival(ival), _align(align) {
_label = ".LC" + std::to_string(GenTag());
}
explicit ROData(const std::string& sval): _sval(sval), _align(1) {
_label = ".LC" + std::to_string(GenTag());
}
~ROData(void) {}
std::string _sval;
long _ival;
int _align;
std::string _label;
private:
static long GenTag(void) {
static long tag = 0;
return tag++;
}
};
typedef std::vector<ROData> RODataList;
class Generator: public Visitor
{
public:
Generator(void) {}
//Expression
virtual void VisitBinaryOp(BinaryOp* binaryOp);
virtual void VisitUnaryOp(UnaryOp* unaryOp);
virtual void VisitConditionalOp(ConditionalOp* condOp);
virtual void VisitFuncCall(FuncCall* funcCall);
virtual void VisitObject(Object* obj);
virtual void VisitEnumerator(Enumerator* enumer);
virtual void VisitIdentifier(Identifier* ident);
virtual void VisitConstant(Constant* cons);
virtual void VisitTempVar(TempVar* tempVar);
// Binary
void GenMemberRefOp(BinaryOp* binaryOp);
//void GenSubScriptingOp(BinaryOp* binaryOp);
void GenAndOp(BinaryOp* binaryOp);
void GenOrOp(BinaryOp* binaryOp);
void GenAddOp(BinaryOp* binaryOp);
void GenSubOp(BinaryOp* binaryOp);
void GenAssignOp(BinaryOp* assign);
void GenCastOp(UnaryOp* cast);
void GenDerefOp(UnaryOp* deref);
void GenPointerArithm(BinaryOp* binary);
void GenDivOp(bool flt, bool sign, int width, int op);
void GenCompOp(bool flt, int width, const char* set);
// Unary
void GenPrefixIncDec(UnaryOp* unary, const std::string& inst);
void GenPostfixIncDec(UnaryOp* unary, const std::string& inst);
//statement
virtual void VisitDeclaration(Declaration* init);
virtual void VisitEmptyStmt(EmptyStmt* emptyStmt);
virtual void VisitIfStmt(IfStmt* ifStmt);
virtual void VisitJumpStmt(JumpStmt* jumpStmt);
virtual void VisitReturnStmt(ReturnStmt* returnStmt);
virtual void VisitLabelStmt(LabelStmt* labelStmt);
virtual void VisitCompoundStmt(CompoundStmt* compoundStmt);
virtual void VisitFuncDef(FuncDef* funcDef);
virtual void VisitTranslationUnit(TranslationUnit* unit);
void Gen(void);
void GenExpr(Expr* expr) {
expr->Accept(this);
}
void Emit(const char* format, ...);
void EmitLabel(const std::string& label);
std::string EmitLoad(const std::string& addr, Type* type);
void EmitStore(const std::string& addr, Type* type);
void Push(const char* reg);
void Pop(const char* reg);
void Spill(bool flt) {
Push(flt ? "xmm0": "rax");
}
void Restore(bool flt);
std::string Save(const std::string& src) {
assert(src == "rax" || src == "xmm0");
if (src == "rax") {
Emit("movq #rax, #rcx");
return "rcx";
} else {
Emit("movsd #xmm0, xmm1");
return "xmm1";
}
}
void Exchange(const std::string& lhs, const std::string& rhs);
static void SetInOut(Parser* parser, FILE* outFile) {
_parser = parser;
_outFile = outFile;
}
protected:
static Parser* _parser;
static FILE* _outFile;
static std::string _cons;
static RODataList _rodatas;
};
struct ObjectAddr
{
std::string Repr(void);
std::string _label;
std::string _base;
int _offset;
};
class LValGenerator: public Generator
{
public:
LValGenerator(void) {}
//Expression
virtual void VisitBinaryOp(BinaryOp* binaryOp);
virtual void VisitUnaryOp(UnaryOp* unaryOp);
virtual void VisitObject(Object* obj);
virtual void VisitIdentifier(Identifier* ident);
virtual void VisitConditionalOp(ConditionalOp* condOp) {
assert(false);
}
virtual void VisitFuncCall(FuncCall* funcCall) {
assert(false);
}
virtual void VisitEnumerator(Enumerator* enumer) {
assert(false);
}
virtual void VisitConstant(Constant* cons) {
assert(false);
}
virtual void VisitTempVar(TempVar* tempVar) {
assert(false);
}
ObjectAddr GenExpr(Expr* expr) {
expr->Accept(this);
return _addr;
}
private:
ObjectAddr _addr;
};
#endif