source: dev/trunk/abdev/BasicCompiler_Common/include/CodeGenerator.h@ 238

Last change on this file since 238 was 238, checked in by dai_9181, 17 years ago
File size: 12.5 KB
Line 
1#pragma once
2
3#include <NativeCode.h>
4
5#ifdef _AMD64_
6#include "../../BasicCompiler64/MachineFixed.h"
7#else
8#include "../../BasicCompiler32/MachineFixed.h"
9#endif
10
11
12void ReallocNativeCodeBuffer();
13
14class CodeGenerator
15{
16 NativeCode *pNativeCode;
17
18public:
19
20 // コード生成時の部分的なスケジューリング
21 class PertialSchedule
22 {
23 int id; // 通し番号
24
25 int codePos; // バッファ位置
26 int typeSize; // 対象サイズ(一般的には8bit/32bit)
27
28 int _obpOld; // 未完成
29 public:
30 PertialSchedule( int codePos, int typeSize )
31 : codePos( codePos )
32 , typeSize( typeSize )
33 {
34 static int _id = 0;
35 id = _id++;
36
37 extern int obp;
38 _obpOld = obp;
39 }
40 ~PertialSchedule()
41 {
42 }
43
44 bool IsEquals( const PertialSchedule &pertialSchedule )
45 {
46 return ( this->id == pertialSchedule.id );
47 }
48
49 int GetCodePos() const
50 {
51 return codePos;
52 }
53 int GetTypeSize() const
54 {
55 return typeSize;
56 }
57 int GetObpOld() const
58 {
59 return _obpOld;
60 }
61 };
62
63private:
64 typedef std::vector<PertialSchedule> PertialSchedules;
65 PertialSchedules pertialSchedules;
66
67public:
68
69 CodeGenerator()
70 : pNativeCode( 0 )
71 {
72 }
73 ~CodeGenerator()
74 {
75 if( pNativeCode )
76 {
77 CheckUnresolveSchedule();
78 }
79 }
80
81 void Select( NativeCode &nativeCode )
82 {
83 if( pNativeCode )
84 {
85 CheckUnresolveSchedule();
86 }
87 pNativeCode = &nativeCode;
88 }
89
90 void CheckUnresolveSchedule();
91
92 void opfix_JmpPertialSchedule( const PertialSchedule *pPertialSchedule );
93
94
95 /////////////////////////////////////////////////////////////////
96 // 32bit/64bit共通 機械語生成
97 /////////////////////////////////////////////////////////////////
98
99private:
100 PertialSchedule *__jmp_op_format( char opcode, long offset, int op_size, bool isPertialSchedule = false );
101public:
102 PertialSchedule *op_jle( long offset, int op_size = sizeof(char), bool isPertialSchedule = false );
103 PertialSchedule *op_jbe( long offset, int op_size = sizeof(char), bool isPertialSchedule = false );
104 PertialSchedule *op_jge( long offset, int op_size = sizeof(char), bool isPertialSchedule = false );
105 PertialSchedule *op_jae( long offset, int op_size = sizeof(char), bool isPertialSchedule = false );
106 PertialSchedule *op_jl( long offset, int op_size = sizeof(char), bool isPertialSchedule = false );
107 PertialSchedule *op_jb( long offset, int op_size = sizeof(char), bool isPertialSchedule = false );
108 PertialSchedule *op_jg( long offset, int op_size = sizeof(char), bool isPertialSchedule = false );
109 PertialSchedule *op_ja( long offset, int op_size = sizeof(char), bool isPertialSchedule = false );
110 PertialSchedule *op_jne( long offset, int op_size = sizeof(char), bool isPertialSchedule = false );
111 PertialSchedule *op_je( long offset, int op_size = sizeof(char), bool isPertialSchedule = false );
112 PertialSchedule *op_jmp( long offset, int op_size = sizeof(char), bool isPertialSchedule = false );
113
114
115#ifdef _AMD64_
116 /////////////////////////////////////////////////////////////////
117 // 64ビット機械語生成
118 /////////////////////////////////////////////////////////////////
119private:
120 void set_rex(int op_size,int reg,int index_reg,int base_reg);
121 void set_mod_rm_sib_disp(char mod,int reg,int scale,int index_reg,int base_reg,long disp, Schedule::Type scheduleType = Schedule::None );
122 void __op_format(int op_size,char op_prefix,char opcode1,char opcode2,int reg,int base_reg,long offset,char mod, Schedule::Type scheduleType = Schedule::None );
123public:
124 void op_mov_RV (int op_size,int reg,long i32data, Schedule::Type scheduleType = Schedule::None );
125 void op_mov_RV64 (int reg,_int64 i64data);
126 void op_mov_RM (int op_size,int reg,int base_reg,long offset,char mod, Schedule::Type scheduleType = Schedule::None );
127 void op_mov_RM_ex (int op_size,int reg,int base_reg1,int base_reg2,long offset,BOOL bUseOffset, Schedule::Type scheduleType = Schedule::None );
128 void op_mov_MR (int op_size,int reg,int base_reg,long offset,char mod, Schedule::Type scheduleType = Schedule::None );
129 void op_mov_MR_ex (int op_size,int reg,int base_reg1,int base_reg2,long offset,BOOL bUseOffset, Schedule::Type scheduleType = Schedule::None );
130 void op_mov_MV (int op_size,int base_reg,int offset,BOOL bUseOffset,long i32data);
131 void op_mov_RR (int reg1,int reg2);
132 void op_movsxd (int reg64,int reg32);
133 void op_movsx64_FromReg16 (int reg64,int reg16);
134 void op_movsx64_FromReg8 (int reg64,int reg8);
135 void op_movsx32_FromReg16 (int reg32,int reg16);
136 void op_movsx32_FromReg8 (int reg32,int reg8);
137 void op_movsx16_FromReg8 (int reg32,int reg8);
138 void op_cqo ();
139 void op_inc (int reg);
140 void op_dec (int reg);
141 void op_add_RM (int op_size,int reg,int base_reg,int offset,char mod, Schedule::Type scheduleType = Schedule::None );
142 void op_add_RV (int reg,long offset, Schedule::Type scheduleType = Schedule::None );
143 void op_add_RR (int reg1,int reg2);
144 void op_add32_reg (int reg1,int reg2);
145 void op_sub_RV (int op_size,int reg,long i32data);
146 void op_sub64_reg (int reg1,int reg2);
147 void op_sub32_reg (int reg1,int reg2);
148 void op_sbb_RR ( int op_size, int reg1, int reg2 );
149 void op_imul_RR (int op_size,int reg1,int reg2);
150 void op_imul_RV (int op_size,int reg,long i32data);
151 void op_div64_reg (int reg);
152 void op_idiv64_reg (int reg);
153 void op_shl_reg (int op_size,int reg);
154 void op_sar_reg (int op_size,int reg);
155 void op_shr_reg (int op_size,int reg);
156 void op_and_reg (int op_size,int reg1,int reg2);
157 void op_and64_value (int reg,long offset);
158 void op_and32_value (int reg,long offset);
159 void op_or_reg (int op_size,int reg1,int reg2);
160 void op_xor_reg (int op_size,int reg1,int reg2);
161 void op_not_reg (int op_size,int reg);
162 void op_neg ( int reg );
163 void op_test (int reg1,int reg2);
164 void op_cmp_reg (int op_size,int reg1,int reg2);
165 void op_cmp_value (int op_size,int reg,char byte_data);
166 void op_setne (int reg);
167 void op_movlpd_MR (int xmm_reg,int base_reg,int offset,char mod, Schedule::Type scheduleType = Schedule::None );
168 void op_movlpd_RM (int xmm_reg,int base_reg,int offset,char mod, Schedule::Type scheduleType = Schedule::None );
169 void op_movsd_RR (int xmm_reg1,int xmm_reg2);
170 void op_movsd_MR (int xmm_reg,int base_reg,int offset,char mod, Schedule::Type scheduleType = Schedule::None );
171 void op_movss_RR (int xmm_reg1,int xmm_reg2);
172 void op_movss_RM (int xmm_reg,int base_reg,int offset,char mod, Schedule::Type scheduleType = Schedule::None );
173 void op_movss_MR (int xmm_reg,int base_reg,int offset,char mod, Schedule::Type scheduleType = Schedule::None );
174 void op_movd_RX (int reg,int xmm_reg);
175 void op_cvtsd2ss (int xmm_reg1,int xmm_reg2);
176 void op_cvtss2sd (int xmm_reg1,int xmm_reg2);
177 void op_cvttsd2si_xmm (int op_size,int reg,int xmm_reg);
178 void op_cvttss2si_xmm (int op_size,int reg,int xmm_reg);
179 void op_cvtsi2sd_reg (int op_size,int xmm_reg,int reg);
180 void op_cvtsi2ss_reg (int op_size,int xmm_reg,int reg);
181 void op_comisd (int xmm_reg1,int xmm_reg2);
182 void op_comiss (int xmm_reg1,int xmm_reg2);
183 void op_rep_movs (int op_size);
184 void op_add_rsp(long num);
185 void op_sub_rsp(long num);
186 void op_add_esp(long num);
187 void op_sub_esp(long num);
188 void op_fld_ptr_esp(int type);
189 void op_zero_reg(int reg);
190 void op_call( const UserProc *pUserProc );
191 void op_call( const DllProc *pDllProc );
192 void op_ret();
193
194#else
195 /////////////////////////////////////////////////////////////////
196 // 32ビット機械語生成
197 /////////////////////////////////////////////////////////////////
198private:
199 void set_mod_rm_sib_disp(char mod,int reg,int scale,int index_reg,int base_reg,long disp, Schedule::Type scheduleType = Schedule::None );
200 void __op_format(char op_prefix,char opcode,int reg);
201 void __op_format(char op_prefix,char opcode1,char opcode2,int reg,int base_reg,int offset,char mod, Schedule::Type scheduleType = Schedule::None );
202public:
203 void op_mov_MV ( int op_size, int base_reg, long offset, Schedule::Type offsetScheduleType, long value, Schedule::Type valueScheduleType = Schedule::None );
204 void op_mov_RV (int reg,long offset, Schedule::Type scheduleType = Schedule::None );
205 void op_mov_RR (int reg1,int reg2);
206 void op_mov_RM (int op_size,int reg,int base_reg,int offset,char mod, Schedule::Type scheduleType = Schedule::None );
207 void op_mov_RM_ex (int op_size,int reg,int base_reg1,int base_reg2,long offset,BOOL bUseOffset, Schedule::Type scheduleType = Schedule::None );
208 void op_mov_MR (int op_size,int reg,int base_reg,int offset,char mod, Schedule::Type scheduleType = Schedule::None );
209 void op_mov_MR_ex (int op_size,int reg,int base_reg1,int base_reg2,long offset,BOOL bUseOffset, Schedule::Type scheduleType = Schedule::None );
210 void op_movsx_R32R16 (int reg32,int reg16 = REG_NON);
211 void op_movsx_R32R8 (int reg32,int reg8 = REG_NON);
212 void op_movsx_R16R8 (int reg16,int reg8 = REG_NON);
213 void op_lea_RM ( int reg, int base_reg, long offset, char mod, Schedule::Type scheduleType = Schedule::None );
214 void op_inc (int reg);
215 void op_dec (int reg);
216 void op_add_RV8 (int reg,char cValue);
217 void op_add_RV ( int reg, long offset, Schedule::Type scheduleType = Schedule::None );
218 void op_add_RR ( int reg1, int reg2 );
219 void op_add_RM (int op_size,int reg,int base_reg,int offset,char mod, Schedule::Type scheduleType = Schedule::None );
220 void op_adc_RV8 (int reg,char cValue);
221 void op_adc_RR ( int reg1, int reg2 );
222 void op_sub_RV8 (int reg,char cValue);
223 void op_sub_RR ( int reg1, int reg2 );
224 void op_sbb_RV8 (int reg,char cValue);
225 void op_sbb_RR ( int reg1, int reg2 );
226 void op_imul_RR (int reg1,int reg2);
227 void op_imul_RV (int reg,long i32data);
228 void op_imul_RV8 (int reg,char cValue);
229 void op_div_R ( int reg );
230 void op_idiv_R ( int reg );
231 void op_and_RV (int reg,long value);
232 void op_and_RR ( int reg1, int reg2 );
233 void op_or_RR ( int op_size, int reg1, int reg2 );
234 void op_xor_RR ( int reg1, int reg2 = REG_NON );
235 void op_neg ( int reg );
236 void op_cdq ();
237
238 void op_rep_movs (int op_size);
239
240 void op_push(int reg);
241 void op_push_V( long data, Schedule::Type scheduleType = Schedule::None );
242 void op_push_M( int base_reg );
243 void op_push_M( int base_reg, long offset, Schedule::Type scheduleType = Schedule::None );
244 void op_pop(int reg = REG_NON);
245 void op_add_esp(long num);
246 void op_sub_esp(long num);
247 void op_cmp_RR( int reg1, int reg2 );
248 void op_cmp_value(int op_size,int reg,char byte_data);
249 void op_setne( int reg );
250 void op_test(int reg1,int reg2);
251 void op_test_ah( char cValue );
252 void op_fld_ptr_esp(int type);
253 void op_fld_basereg (int type,int base_reg);
254 void op_fld_base_offset (int type,int base_reg,long offset, Schedule::Type scheduleType = Schedule::None );
255 void op_fld_base_offset_ex (int type,int base_reg1,int base_reg2,long offset,BOOL bUseOffset, Schedule::Type scheduleType = Schedule::None);
256 void op_fstp_basereg (int type,int base_reg);
257 void op_fstp_base_offset (int type,int base_reg,long offset, Schedule::Type scheduleType = Schedule::None);
258 void op_fstp_base_offset_ex (int type,int base_reg1,int base_reg2,long offset,BOOL bUseOffset, Schedule::Type scheduleType = Schedule::None);
259 void op_fistp_ptr_esp ( int typeSize );
260 void op_fstp_push ( Type &type );
261 void op_fcompp();
262 void op_fnstsw_ax();
263 void op_zero_reg(int reg);
264 void fpu_cast();
265 void fpu_cast_end();
266
267 void op_call_R( int reg );
268 void op_call(const UserProc *pUserProc);
269 void op_ret();
270#endif
271
272
273
274
275 void PutOld( char c1, char c2 )
276 {
277 pNativeCode->Put( c1 );
278 pNativeCode->Put( c2 );
279 }
280 void PutOld( char c1, char c2, char c3 )
281 {
282 pNativeCode->Put( c1 );
283 pNativeCode->Put( c2 );
284 pNativeCode->Put( c3 );
285 }
286 void PutOld( char c1, char c2, char c3, char c4 )
287 {
288 pNativeCode->Put( c1 );
289 pNativeCode->Put( c2 );
290 pNativeCode->Put( c3 );
291 pNativeCode->Put( c4 );
292 }
293 void PutOld( char c1, char c2, char c3, long l )
294 {
295 pNativeCode->Put( c1 );
296 pNativeCode->Put( c2 );
297 pNativeCode->Put( c3 );
298 pNativeCode->Put( l );
299 }
300 void PutOld( char c1, char c2, char c3, char c4, char c5 )
301 {
302 pNativeCode->Put( c1 );
303 pNativeCode->Put( c2 );
304 pNativeCode->Put( c3 );
305 pNativeCode->Put( c4 );
306 pNativeCode->Put( c5 );
307 }
308 void PutOld( char c1, char c2, char c3, char c4, char c5, char c6 )
309 {
310 pNativeCode->Put( c1 );
311 pNativeCode->Put( c2 );
312 pNativeCode->Put( c3 );
313 pNativeCode->Put( c4 );
314 pNativeCode->Put( c5 );
315 pNativeCode->Put( c6 );
316 }
317};
Note: See TracBrowser for help on using the repository browser.