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

Last change on this file since 247 was 247, checked in by dai_9181, 17 years ago

Exit Subスケジュールをリファクタリングした

File size: 14.6 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
14//Goto未知ラベル
15class GotoLabelSchedule
16{
17 std::string name;
18 int line;
19 int nativeCodePos;
20 int sourceCodePos;
21public:
22 GotoLabelSchedule( const std::string &name, int nativeCodePos, int sourceCodePos )
23 : name( name )
24 , line( -1 )
25 , nativeCodePos( nativeCodePos )
26 , sourceCodePos( sourceCodePos )
27 {
28 }
29 GotoLabelSchedule( int line, int nativeCodePos, int sourceCodePos )
30 : line( line )
31 , nativeCodePos( nativeCodePos )
32 , sourceCodePos( sourceCodePos )
33 {
34 }
35 const std::string &GetName() const
36 {
37 return name;
38 }
39 int GetLineNum() const
40 {
41 return line;
42 }
43 int GetNativeCodePos() const
44 {
45 return nativeCodePos;
46 }
47 int GetSourceCodePos() const
48 {
49 return sourceCodePos;
50 }
51};
52
53class CodeGenerator
54{
55 NativeCode *pNativeCode;
56
57public:
58
59 // コード生成時の部分的なスケジューリング
60 class PertialSchedule
61 {
62 int codePos; // バッファ位置
63 int typeSize; // 対象サイズ(一般的には8bit/32bit)
64
65 int _obpOld; // 未完成
66 public:
67 PertialSchedule( int codePos, int typeSize )
68 : codePos( codePos )
69 , typeSize( typeSize )
70 {
71 extern int obp;
72 _obpOld = obp;
73 }
74 ~PertialSchedule()
75 {
76 }
77
78 int GetCodePos() const
79 {
80 return codePos;
81 }
82 int GetTypeSize() const
83 {
84 return typeSize;
85 }
86 int GetObpOld() const
87 {
88 return _obpOld;
89 }
90 };
91
92private:
93 // 部分スケジュールの管理
94 typedef std::vector<const PertialSchedule *> PertialSchedules;
95 PertialSchedules pertialSchedules;
96
97 // Continue用のコード位置情報の管理
98 std::vector<long> continueCodePositions;
99 std::vector<long> _continueCodePositions_ObpOld;
100
101public:
102
103 // Exit Subスケジュールの管理
104 std::vector<long> exitSubCodePositions;
105 std::vector<int> _exitSubCodePositions_ObpOld;
106
107 // Gotoスケジュールの管理
108 std::vector<GotoLabelSchedule> gotoLabelSchedules;
109
110 CodeGenerator()
111 : pNativeCode( 0 )
112 {
113 }
114 ~CodeGenerator()
115 {
116 if( pNativeCode )
117 {
118 CheckUnresolveSchedule();
119 }
120 }
121
122 void Select( NativeCode &nativeCode )
123 {
124 if( pNativeCode )
125 {
126 CheckUnresolveSchedule();
127 }
128 pNativeCode = &nativeCode;
129 }
130
131 long GetContinueCodePos() const
132 {
133 if( continueCodePositions.size() == 0 )
134 {
135 return -1;
136 }
137 return continueCodePositions[continueCodePositions.size()-1];
138 }
139 void ClearContinueArea()
140 {
141 continueCodePositions.clear();
142 _continueCodePositions_ObpOld.clear();
143 }
144 void ContinueAreaBegin()
145 {
146 continueCodePositions.push_back( pNativeCode->GetSize() );
147
148 extern int obp;
149 _continueCodePositions_ObpOld.push_back( obp );
150 }
151 void ContinueAreaEnd()
152 {
153 continueCodePositions.pop_back();
154 _continueCodePositions_ObpOld.pop_back();
155 }
156 long GetContinueCodePosOld() const
157 {
158 if( _continueCodePositions_ObpOld.size() == 0 )
159 {
160 return -1;
161 }
162 return _continueCodePositions_ObpOld[_continueCodePositions_ObpOld.size()-1];
163 }
164
165 void ResolveExitSubSchedule();
166
167 void CheckUnresolveSchedule();
168
169 void opfix_JmpPertialSchedule( const PertialSchedule *pPertialSchedule );
170
171
172 /////////////////////////////////////////////////////////////////
173 // 32bit/64bit共通 機械語生成
174 /////////////////////////////////////////////////////////////////
175
176private:
177 const PertialSchedule *__jmp_op_format( char opcode, long offset, int op_size, bool isPertialSchedule = false, bool isSelfOpcodeOffset = false );
178public:
179 const PertialSchedule *op_jle( long offset, int op_size = sizeof(char), bool isPertialSchedule = false );
180 const PertialSchedule *op_jbe( long offset, int op_size = sizeof(char), bool isPertialSchedule = false );
181 const PertialSchedule *op_jge( long offset, int op_size = sizeof(char), bool isPertialSchedule = false );
182 const PertialSchedule *op_jae( long offset, int op_size = sizeof(char), bool isPertialSchedule = false );
183 const PertialSchedule *op_jl( long offset, int op_size = sizeof(char), bool isPertialSchedule = false );
184 const PertialSchedule *op_jb( long offset, int op_size = sizeof(char), bool isPertialSchedule = false );
185 const PertialSchedule *op_jg( long offset, int op_size = sizeof(char), bool isPertialSchedule = false );
186 const PertialSchedule *op_ja( long offset, int op_size = sizeof(char), bool isPertialSchedule = false );
187 const PertialSchedule *op_jne( long offset, int op_size = sizeof(char), bool isPertialSchedule = false );
188 const PertialSchedule *op_je( long offset, int op_size = sizeof(char), bool isPertialSchedule = false );
189 const PertialSchedule *op_jmp( long offset, int op_size = sizeof(char), bool isPertialSchedule = false, bool isSelfOpcodeOffset = false );
190 void op_jmp_continue();
191 void op_jmp_exitsub();
192 void op_jmp_goto_schedule( const GotoLabelSchedule &gotoLabelSchedule );
193
194
195#ifdef _AMD64_
196 /////////////////////////////////////////////////////////////////
197 // 64ビット機械語生成
198 /////////////////////////////////////////////////////////////////
199private:
200 void set_rex(int op_size,int reg,int index_reg,int base_reg);
201 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 );
202 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 );
203public:
204 void op_mov_RV (int op_size,int reg,long i32data, Schedule::Type scheduleType = Schedule::None );
205 void op_mov_RV64 (int reg,_int64 i64data);
206 void op_mov_RM (int op_size,int reg,int base_reg,long 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,long 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_mov_MV (int op_size,int base_reg,int offset, Schedule::Type offsetScheduleType, BOOL bUseOffset,long i32data);
211 void op_mov_RR (int reg1,int reg2);
212 void op_movsxd (int reg64,int reg32);
213 void op_movsx64_FromReg16 (int reg64,int reg16);
214 void op_movsx64_FromReg8 (int reg64,int reg8);
215 void op_movsx32_FromReg16 (int reg32,int reg16);
216 void op_movsx32_FromReg8 (int reg32,int reg8);
217 void op_movsx16_FromReg8 (int reg32,int reg8);
218 void op_cqo ();
219 void op_inc (int reg);
220 void op_dec (int reg);
221 void op_add_RM (int op_size,int reg,int base_reg,int offset,char mod, Schedule::Type scheduleType = Schedule::None );
222 void op_add_RV (int reg,long offset, Schedule::Type scheduleType = Schedule::None );
223 void op_add_RR (int reg1,int reg2);
224 void op_add32_reg (int reg1,int reg2);
225 void op_sub_RV (int op_size,int reg,long i32data);
226 void op_sub64_reg (int reg1,int reg2);
227 void op_sub32_reg (int reg1,int reg2);
228 void op_sbb_RR ( int op_size, int reg1, int reg2 );
229 void op_imul_RR (int op_size,int reg1,int reg2);
230 void op_imul_RV (int op_size,int reg,long i32data);
231 void op_div64_reg (int reg);
232 void op_idiv64_reg (int reg);
233 void op_shl_reg (int op_size,int reg);
234 void op_sar_reg (int op_size,int reg);
235 void op_shr_reg (int op_size,int reg);
236 void op_and_reg (int op_size,int reg1,int reg2);
237 void op_and64_value (int reg,long offset);
238 void op_and32_value (int reg,long offset);
239 void op_or_reg (int op_size,int reg1,int reg2);
240 void op_xor_reg (int op_size,int reg1,int reg2);
241 void op_not_reg (int op_size,int reg);
242 void op_neg ( int reg );
243 void op_test (int reg1,int reg2);
244 void op_cmp_reg (int op_size,int reg1,int reg2);
245 void op_cmp_value (int op_size,int reg,char byte_data);
246 void op_setne (int reg);
247 void op_movlpd_MR (int xmm_reg,int base_reg,int offset,char mod, Schedule::Type scheduleType = Schedule::None );
248 void op_movlpd_RM (int xmm_reg,int base_reg,int offset,char mod, Schedule::Type scheduleType = Schedule::None );
249 void op_movsd_RR (int xmm_reg1,int xmm_reg2);
250 void op_movsd_MR (int xmm_reg,int base_reg,int offset,char mod, Schedule::Type scheduleType = Schedule::None );
251 void op_movss_RR (int xmm_reg1,int xmm_reg2);
252 void op_movss_RM (int xmm_reg,int base_reg,int offset,char mod, Schedule::Type scheduleType = Schedule::None );
253 void op_movss_MR (int xmm_reg,int base_reg,int offset,char mod, Schedule::Type scheduleType = Schedule::None );
254 void op_movd_RX (int reg,int xmm_reg);
255 void op_cvtsd2ss (int xmm_reg1,int xmm_reg2);
256 void op_cvtss2sd (int xmm_reg1,int xmm_reg2);
257 void op_cvttsd2si_xmm (int op_size,int reg,int xmm_reg);
258 void op_cvttss2si_xmm (int op_size,int reg,int xmm_reg);
259 void op_cvtsi2sd_reg (int op_size,int xmm_reg,int reg);
260 void op_cvtsi2ss_reg (int op_size,int xmm_reg,int reg);
261 void op_comisd (int xmm_reg1,int xmm_reg2);
262 void op_comiss (int xmm_reg1,int xmm_reg2);
263 void op_rep_movs (int op_size);
264 void op_add_rsp(long num);
265 void op_sub_rsp(long num);
266 void op_add_esp(long num);
267 void op_sub_esp(long num);
268 void op_fld_ptr_esp(int type);
269 void op_zero_reg(int reg);
270 void op_call( const UserProc *pUserProc );
271 void op_call( const DllProc *pDllProc );
272 void op_ret();
273
274#else
275 /////////////////////////////////////////////////////////////////
276 // 32ビット機械語生成
277 /////////////////////////////////////////////////////////////////
278private:
279 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 );
280 void __op_format(char op_prefix,char opcode,int reg);
281 void __op_format(char op_prefix,char opcode1,char opcode2,int reg,int base_reg,int offset,char mod, Schedule::Type scheduleType = Schedule::None );
282public:
283 void op_mov_MV ( int op_size, int base_reg, long offset, Schedule::Type offsetScheduleType, long value, Schedule::Type valueScheduleType = Schedule::None );
284 void op_mov_RV (int reg,long offset, Schedule::Type scheduleType = Schedule::None );
285 void op_mov_RR (int reg1,int reg2);
286 void op_mov_RM (int op_size,int reg,int base_reg,int offset,char mod, Schedule::Type scheduleType = Schedule::None );
287 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 );
288 void op_mov_MR (int op_size,int reg,int base_reg,int offset,char mod, Schedule::Type scheduleType = Schedule::None );
289 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 );
290 void op_movsx_R32R16 (int reg32,int reg16 = REG_NON);
291 void op_movsx_R32R8 (int reg32,int reg8 = REG_NON);
292 void op_movsx_R16R8 (int reg16,int reg8 = REG_NON);
293 void op_lea_RM ( int reg, int base_reg, long offset, char mod, Schedule::Type scheduleType = Schedule::None );
294 void op_inc (int reg);
295 void op_dec (int reg);
296 void op_add_RV8 (int reg,char cValue);
297 void op_add_RV ( int reg, long offset, Schedule::Type scheduleType = Schedule::None );
298 void op_add_RR ( int reg1, int reg2 );
299 void op_add_RM (int op_size,int reg,int base_reg,int offset,char mod, Schedule::Type scheduleType = Schedule::None );
300 void op_adc_RV8 (int reg,char cValue);
301 void op_adc_RR ( int reg1, int reg2 );
302 void op_sub_RV8 (int reg,char cValue);
303 void op_sub_RR ( int reg1, int reg2 );
304 void op_sbb_RV8 (int reg,char cValue);
305 void op_sbb_RR ( int reg1, int reg2 );
306 void op_imul_RR (int reg1,int reg2);
307 void op_imul_RV (int reg,long i32data);
308 void op_imul_RV8 (int reg,char cValue);
309 void op_div_R ( int reg );
310 void op_idiv_R ( int reg );
311 void op_and_RV (int reg,long value);
312 void op_and_RR ( int reg1, int reg2 );
313 void op_or_RR ( int op_size, int reg1, int reg2 );
314 void op_xor_RR ( int reg1, int reg2 = REG_NON );
315 void op_neg ( int reg );
316 void op_cdq ();
317
318 void op_rep_movs (int op_size);
319
320 void op_push(int reg);
321 void op_push_V( long data, Schedule::Type scheduleType = Schedule::None );
322 void op_push_M( int base_reg );
323 void op_push_M( int base_reg, long offset, Schedule::Type scheduleType = Schedule::None );
324 void op_pop(int reg = REG_NON);
325 void op_add_esp(long num);
326 void op_sub_esp(long num);
327 void op_cmp_RR( int reg1, int reg2 );
328 void op_cmp_value(int op_size,int reg,char byte_data);
329 void op_setne( int reg );
330 void op_test(int reg1,int reg2);
331 void op_test_ah( char cValue );
332 void op_fld_ptr_esp(int type);
333 void op_fld_basereg (int type,int base_reg);
334 void op_fld_base_offset (int type,int base_reg,long offset, Schedule::Type scheduleType = Schedule::None );
335 void op_fld_base_offset_ex (int type,int base_reg1,int base_reg2,long offset,BOOL bUseOffset, Schedule::Type scheduleType = Schedule::None);
336 void op_fstp_basereg (int type,int base_reg);
337 void op_fstp_base_offset (int type,int base_reg,long offset, Schedule::Type scheduleType = Schedule::None);
338 void op_fstp_base_offset_ex (int type,int base_reg1,int base_reg2,long offset,BOOL bUseOffset, Schedule::Type scheduleType = Schedule::None);
339 void op_fistp_ptr_esp ( int typeSize );
340 void op_fstp_push ( Type &type );
341 void op_fcompp();
342 void op_fnstsw_ax();
343 void op_zero_reg(int reg);
344 void fpu_cast();
345 void fpu_cast_end();
346
347 void op_call_R( int reg );
348 void op_call(const UserProc *pUserProc);
349 void op_ret();
350 void op_ret( short stackFrameSize );
351 void op_addressof( int reg, const UserProc *pUserProc );
352#endif
353
354
355
356 void PutOld( long l, Schedule::Type scheduleType )
357 {
358 pNativeCode->Put( l, scheduleType );
359 }
360
361 void PutOld( char c1, char c2 )
362 {
363 pNativeCode->Put( c1 );
364 pNativeCode->Put( c2 );
365 }
366 void PutOld( char c1, char c2, char c3 )
367 {
368 pNativeCode->Put( c1 );
369 pNativeCode->Put( c2 );
370 pNativeCode->Put( c3 );
371 }
372 void PutOld( char c1, char c2, char c3, char c4 )
373 {
374 pNativeCode->Put( c1 );
375 pNativeCode->Put( c2 );
376 pNativeCode->Put( c3 );
377 pNativeCode->Put( c4 );
378 }
379 void PutOld( char c1, char c2, char c3, long l )
380 {
381 pNativeCode->Put( c1 );
382 pNativeCode->Put( c2 );
383 pNativeCode->Put( c3 );
384 pNativeCode->Put( l );
385 }
386 void PutOld( char c1, char c2, char c3, char c4, char c5 )
387 {
388 pNativeCode->Put( c1 );
389 pNativeCode->Put( c2 );
390 pNativeCode->Put( c3 );
391 pNativeCode->Put( c4 );
392 pNativeCode->Put( c5 );
393 }
394 void PutOld( char c1, char c2, char c3, char c4, char c5, char c6 )
395 {
396 pNativeCode->Put( c1 );
397 pNativeCode->Put( c2 );
398 pNativeCode->Put( c3 );
399 pNativeCode->Put( c4 );
400 pNativeCode->Put( c5 );
401 pNativeCode->Put( c6 );
402 }
403};
Note: See TracBrowser for help on using the repository browser.