-
Notifications
You must be signed in to change notification settings - Fork 0
/
register.h
203 lines (165 loc) · 3.55 KB
/
register.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
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
201
202
203
/*
* register.h
*
* Created on: Jun 21, 2019
* Author: trance
*/
#ifndef REGISTER_H_
#define REGISTER_H_
#include "predeclares.h"
#include "tools.h"
namespace core {
//enum RegisterTypes {
// B_reg = 1,
// W_reg = 2,
// L_reg = 4,
// Q_reg = 8
//};
/**
* r8~r15 we need Rex extension~ Or simply fill 0x48 prefix
*/
class Register {
public:
explicit Register(int reg);
explicit Register(int reg, const char * name );
virtual ~Register();
bool needRexPrefix() const {
// FIXME: 其实不只是小于7要,其实像 pop push 默认都是64位的则没有前缀
// 而 mov 即使是小于7 仍然要前缀 0x48 | prefix,看手册
if( reg > 7 )
return true;
return false;
}
int getRexPrefix() const {
return reg >> 3;
}
inline int getReg() const {
return this->reg;
}
void setName(const char * name ) {
this->name = name;
}
const char * getName() const {
return name;
}
private:
const char * name;
int reg;
friend class Generator;
};
class RexPrefix {
};
enum ScaleFactor {
times_1 = 0,
times_2 = 1,
times_4 = 2,
times_8 = 3,
times_16 = 4
};
enum AddressForm {
BASE = 0,
BASE_disp8 = 1,
BASE_disp32 = 2,
DIRECT = 3
};
/**
* REX + Mod + R/M + SIB + DIS
*/
class Operand {
public:
// reg
INLINE( explicit Operand(Register reg) );
// inline explicit Operand(Register reg) __attribute__((always_inline));
// INLINE(explicit Operand(Register reg));
// [disp/r]
INLINE( explicit Operand(int32_t disp) );
// disp only must always be relocated
// [base + disp/r]
explicit Operand(Register base, int32_t disp);
// [base + index*scale + disp/r]
explicit Operand(Register base,
Register index,
ScaleFactor scale,
int32_t disp);
// [index*scale + disp/r]
explicit Operand(Register index,
ScaleFactor scale,
int32_t disp
);
inline int getRexPrefix() const {
return rex_prefix;
}
inline bool isSIB() const {
return is_SIB;
}
private:
#define Operand_LENGTH 8
mutable byte buffer [Operand_LENGTH];
int length;
int rex_prefix; /* when SIB rex may == 3, means 11 */
bool is_SIB; /* easy deal with REX prefix */
inline void set_mod(AddressForm b);
inline void set_rm(byte b);
friend class Generator;
#ifdef DEBUG
char name[32];
public:
const char * getName() const {
return name;
}
#endif
};
class Immediate {
public:
inline explicit Immediate(int x) {
x_ = x;
}
// inline explicit Immediate(const char* s) {
// x_ = reinterpret_cast<int32_t>(s);
// }
bool is_zero() const { return x_ == 0;}
// 8 or 32
bool is_int8() const {
return -128 <= x_ && x_ < 128;
}
private:
int x_;
friend class Generator;
};
// most significant 2 bits
inline void Operand::set_mod(AddressForm b) {
buffer[0] &= 0x3f;
buffer[0] |= (byte)b << 6;
}
// least 3 bits
inline void Operand::set_rm(byte b) {
buffer[0] &= 0xf8;
buffer[0] |= (b&7);
}
/**
* if operand use 64bits register
* then Rex = 0x48 | specific bits
*/
inline Operand::Operand(Register reg) : length(0), is_SIB(false) {
byte rm;
memset(buffer, 0, Operand_LENGTH);
#ifdef DEBUG
memset(name, 0, 32);
strncpy(name, reg.getName(), 32);
#endif
set_mod(DIRECT);
rm = reg.getReg();
set_rm(rm);
length = 1;
if( reg.needRexPrefix( ) )
rex_prefix = 1;
else
rex_prefix = 0;
}
inline Operand::Operand(int32_t disp) {
length = 0;
rex_prefix = 0;
is_SIB = false;
}
} /* namespace core */
#endif /* REGISTER_H_ */