-
Notifications
You must be signed in to change notification settings - Fork 19
Expand file tree
/
Copy pathOutputX86Common.h
More file actions
201 lines (178 loc) · 8.03 KB
/
OutputX86Common.h
File metadata and controls
201 lines (178 loc) · 8.03 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
199
200
#ifdef OUTPUT_CLASS_NAME
#include <map>
#include "Output.h"
#include "SymInstr.h"
#ifdef WIN32
typedef ptrdiff_t ssize_t;
#endif
#ifdef OUTPUT32
class X86Sym_Function;
#else
class X64Sym_Function;
#endif
class OUTPUT_CLASS_NAME: public Output
{
struct X86MemoryReference
{
uint32_t base, index;
uint8_t scale;
uint32_t var;
ssize_t offset;
};
enum OperandReferenceType
{
OPERANDREF_REG,
OPERANDREF_MEM,
OPERANDREF_IMMED
};
struct OperandReference
{
OperandReferenceType type;
size_t width;
union
{
struct
{
uint32_t reg;
uint32_t highReg;
};
X86MemoryReference mem;
int64_t immed;
};
bool operator==(const OperandReference& ref) const;
bool operator!=(const OperandReference& ref) const;
};
enum ConditionalJumpType
{
CONDJUMP_OVERFLOW = 0,
CONDJUMP_NOT_OVERFLOW,
CONDJUMP_BELOW,
CONDJUMP_ABOVE_EQUAL,
CONDJUMP_EQUAL,
CONDJUMP_NOT_EQUAL,
CONDJUMP_BELOW_EQUAL,
CONDJUMP_ABOVE,
CONDJUMP_NEGATIVE,
CONDJUMP_POSITIVE,
CONDJUMP_PARITY_EVEN,
CONDJUMP_PARITY_ODD,
CONDJUMP_LESS_THAN,
CONDJUMP_GREATER_EQUAL,
CONDJUMP_LESS_EQUAL,
CONDJUMP_GREATER_THAN
};
enum RegisterUsageType
{
USAGE_NORMAL,
USAGE_INDEX
};
struct IncomingParameterCopy
{
Variable* var;
uint32_t incomingReg;
uint32_t stackVar;
};
Function* m_func;
#ifdef OUTPUT32
X86Sym_Function* m_symFunc;
#else
X64Sym_Function* m_symFunc;
#endif
std::map<Variable*, int32_t> m_stackFrame;
std::map<Variable*, int32_t> m_stackVar;
std::map<Variable*, uint32_t> m_varReg;
bool m_framePointerEnabled;
bool m_normalStack;
ILBlock* m_currentBlock;
uint32_t m_varargStart;
int64_t m_stackParamSize;
uint32_t GetRegisterByName(const std::string& name);
void GetDataAddressFromInstructionPointer(SymInstrBlock* out, uint32_t reg, int64_t offset);
void GetCodeAddressFromInstructionPointer(SymInstrBlock* out, uint32_t reg, Function* func, ILBlock* block);
bool AccessVariableStorage(SymInstrBlock* out, const ILParameter& param, OperandReference& ref);
bool LoadCodePointer(SymInstrBlock* out, Function* func, ILBlock* block, OperandReference& ref);
bool PrepareLoad(SymInstrBlock* out, const ILParameter& param, OperandReference& ref);
bool PrepareStore(SymInstrBlock* out, const ILParameter& param, OperandReference& ref);
bool Move(SymInstrBlock* out, const OperandReference& dest, const OperandReference& src);
bool Add(SymInstrBlock* out, const OperandReference& dest, const OperandReference& src);
bool Sub(SymInstrBlock* out, const OperandReference& dest, const OperandReference& src);
bool And(SymInstrBlock* out, const OperandReference& dest, const OperandReference& src);
bool Or(SymInstrBlock* out, const OperandReference& dest, const OperandReference& src);
bool Xor(SymInstrBlock* out, const OperandReference& dest, const OperandReference& src);
bool ShiftLeft(SymInstrBlock* out, const OperandReference& dest, const OperandReference& src);
bool ShiftRightUnsigned(SymInstrBlock* out, const OperandReference& dest, const OperandReference& src);
bool ShiftRightSigned(SymInstrBlock* out, const OperandReference& dest, const OperandReference& src);
bool Neg(SymInstrBlock* out, const OperandReference& dest);
bool Not(SymInstrBlock* out, const OperandReference& dest);
bool Increment(SymInstrBlock* out, const OperandReference& dest);
bool Decrement(SymInstrBlock* out, const OperandReference& dest);
void ConditionalJump(SymInstrBlock* out, ConditionalJumpType type, ILBlock* trueBlock, ILBlock* falseBlock);
void UnconditionalJump(SymInstrBlock* out, ILBlock* block, bool canOmit = true);
#ifdef OUTPUT32
bool Mult64(SymInstrBlock* out, const OperandReference& dest, const OperandReference& a, const OperandReference& b);
#endif
bool GenerateAssign(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateAddressOf(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateAddressOfMember(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateDeref(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateDerefMember(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateDerefAssign(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateDerefMemberAssign(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateArrayIndex(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateArrayIndexAssign(SymInstrBlock* out, const ILInstruction& instr);
bool GeneratePtrAdd(SymInstrBlock* out, const ILInstruction& instr);
bool GeneratePtrSub(SymInstrBlock* out, const ILInstruction& instr);
bool GeneratePtrDiff(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateAdd(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateSub(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateSignedMult(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateUnsignedMult(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateSignedDiv(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateUnsignedDiv(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateSignedMod(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateUnsignedMod(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateAnd(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateOr(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateXor(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateShl(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateShr(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateSar(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateNeg(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateNot(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateIfTrue(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateIfLessThan(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateIfLessThanEqual(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateIfBelow(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateIfBelowEqual(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateIfEqual(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateGoto(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateCall(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateSignedConvert(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateUnsignedConvert(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateReturn(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateReturnVoid(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateAlloca(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateMemcpy(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateMemset(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateStrlen(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateSyscall(SymInstrBlock* out, const ILInstruction& instr, bool twoDest);
bool GenerateRdtsc(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateRdtscLow(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateRdtscHigh(SymInstrBlock* out, const ILInstruction& instr);
bool GeneratePeb(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateTeb(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateInitialVararg(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateNextArg(SymInstrBlock* out, const ILInstruction& instr);
bool GeneratePrevArg(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateByteSwap(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateBreakpoint(SymInstrBlock* out, const ILInstruction& instr);
bool GenerateCodeBlock(SymInstrBlock* out, ILBlock* block);
public:
OUTPUT_CLASS_NAME(const Settings& settings, Function* startFunc);
virtual bool GenerateCode(Function* func);
virtual TreeNode* GenerateCall(TreeBlock* block, TreeNode* func, CallingConvention conv, size_t fixedParams,
const std::vector< Ref<TreeNode> >& params, TreeNodeType resultType);
virtual TreeNode* GenerateSyscall(TreeBlock* block, TreeNode* num, const std::vector< Ref<TreeNode> >& params,
TreeNodeType resultType);
};
#endif