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

Last change on this file since 246 was 246, checked in by dai_9181, 17 years ago
File size: 14.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
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 // Gotoスケジュールの管理
104 std::vector<GotoLabelSchedule> gotoLabelSchedules;
105
106 CodeGenerator()
107 : pNativeCode( 0 )
108 {
109 }
110 ~CodeGenerator()
111 {
112 if( pNativeCode )
113 {
114 CheckUnresolveSchedule();
115 }
116 }
117
118 void Select( NativeCode &nativeCode )
119 {
120 if( pNativeCode )
121 {
122 CheckUnresolveSchedule();
123 }
124 pNativeCode = &nativeCode;
125 }
126
127 long GetContinueCodePos() const
128 {
129 if( continueCodePositions.size() == 0 )
130 {
131 return -1;
132 }
133 return continueCodePositions[continueCodePositions.size()-1];
134 }
135 void ClearContinueArea()
136 {
137 continueCodePositions.clear();
138 _continueCodePositions_ObpOld.clear();
139 }
140 void ContinueAreaBegin()
141 {
142 continueCodePositions.push_back( pNativeCode->GetSize() );
143
144 extern int obp;
145 _continueCodePositions_ObpOld.push_back( obp );
146 }
147 void ContinueAreaEnd()
148 {
149 continueCodePositions.pop_back();
150 _continueCodePositions_ObpOld.pop_back();
151 }
152 long GetContinueCodePosOld() const
153 {
154 if( _continueCodePositions_ObpOld.size() == 0 )
155 {
156 return -1;
157 }
158 return _continueCodePositions_ObpOld[_continueCodePositions_ObpOld.size()-1];
159 }
160
161 void CheckUnresolveSchedule();
162
163 void opfix_JmpPertialSchedule( const PertialSchedule *pPertialSchedule );
164
165
166 /////////////////////////////////////////////////////////////////
167 // 32bit/64bit共通 機械語生成
168 /////////////////////////////////////////////////////////////////
169
170private:
171 const PertialSchedule *__jmp_op_format( char opcode, long offset, int op_size, bool isPertialSchedule = false, bool isSelfOpcodeOffset = false );
172public:
173 const PertialSchedule *op_jle( long offset, int op_size = sizeof(char), bool isPertialSchedule = false );
174 const PertialSchedule *op_jbe( long offset, int op_size = sizeof(char), bool isPertialSchedule = false );
175 const PertialSchedule *op_jge( long offset, int op_size = sizeof(char), bool isPertialSchedule = false );
176 const PertialSchedule *op_jae( long offset, int op_size = sizeof(char), bool isPertialSchedule = false );
177 const PertialSchedule *op_jl( long offset, int op_size = sizeof(char), bool isPertialSchedule = false );
178 const PertialSchedule *op_jb( long offset, int op_size = sizeof(char), bool isPertialSchedule = false );
179 const PertialSchedule *op_jg( long offset, int op_size = sizeof(char), bool isPertialSchedule = false );
180 const PertialSchedule *op_ja( long offset, int op_size = sizeof(char), bool isPertialSchedule = false );
181 const PertialSchedule *op_jne( long offset, int op_size = sizeof(char), bool isPertialSchedule = false );
182 const PertialSchedule *op_je( long offset, int op_size = sizeof(char), bool isPertialSchedule = false );
183 const PertialSchedule *op_jmp( long offset, int op_size = sizeof(char), bool isPertialSchedule = false, bool isSelfOpcodeOffset = false );
184 void op_jmp_continue();
185 void op_jmp_goto_schedule( const GotoLabelSchedule &gotoLabelSchedule );
186
187
188#ifdef _AMD64_
189 /////////////////////////////////////////////////////////////////
190 // 64ビット機械語生成
191 /////////////////////////////////////////////////////////////////
192private:
193 void set_rex(int op_size,int reg,int index_reg,int base_reg);
194 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 );
195 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 );
196public:
197 void op_mov_RV (int op_size,int reg,long i32data, Schedule::Type scheduleType = Schedule::None );
198 void op_mov_RV64 (int reg,_int64 i64data);
199 void op_mov_RM (int op_size,int reg,int base_reg,long offset,char mod, Schedule::Type scheduleType = Schedule::None );
200 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 );
201 void op_mov_MR (int op_size,int reg,int base_reg,long offset,char mod, Schedule::Type scheduleType = Schedule::None );
202 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 );
203 void op_mov_MV (int op_size,int base_reg,int offset, Schedule::Type offsetScheduleType, BOOL bUseOffset,long i32data);
204 void op_mov_RR (int reg1,int reg2);
205 void op_movsxd (int reg64,int reg32);
206 void op_movsx64_FromReg16 (int reg64,int reg16);
207 void op_movsx64_FromReg8 (int reg64,int reg8);
208 void op_movsx32_FromReg16 (int reg32,int reg16);
209 void op_movsx32_FromReg8 (int reg32,int reg8);
210 void op_movsx16_FromReg8 (int reg32,int reg8);
211 void op_cqo ();
212 void op_inc (int reg);
213 void op_dec (int reg);
214 void op_add_RM (int op_size,int reg,int base_reg,int offset,char mod, Schedule::Type scheduleType = Schedule::None );
215 void op_add_RV (int reg,long offset, Schedule::Type scheduleType = Schedule::None );
216 void op_add_RR (int reg1,int reg2);
217 void op_add32_reg (int reg1,int reg2);
218 void op_sub_RV (int op_size,int reg,long i32data);
219 void op_sub64_reg (int reg1,int reg2);
220 void op_sub32_reg (int reg1,int reg2);
221 void op_sbb_RR ( int op_size, int reg1, int reg2 );
222 void op_imul_RR (int op_size,int reg1,int reg2);
223 void op_imul_RV (int op_size,int reg,long i32data);
224 void op_div64_reg (int reg);
225 void op_idiv64_reg (int reg);
226 void op_shl_reg (int op_size,int reg);
227 void op_sar_reg (int op_size,int reg);
228 void op_shr_reg (int op_size,int reg);
229 void op_and_reg (int op_size,int reg1,int reg2);
230 void op_and64_value (int reg,long offset);
231 void op_and32_value (int reg,long offset);
232 void op_or_reg (int op_size,int reg1,int reg2);
233 void op_xor_reg (int op_size,int reg1,int reg2);
234 void op_not_reg (int op_size,int reg);
235 void op_neg ( int reg );
236 void op_test (int reg1,int reg2);
237 void op_cmp_reg (int op_size,int reg1,int reg2);
238 void op_cmp_value (int op_size,int reg,char byte_data);
239 void op_setne (int reg);
240 void op_movlpd_MR (int xmm_reg,int base_reg,int offset,char mod, Schedule::Type scheduleType = Schedule::None );
241 void op_movlpd_RM (int xmm_reg,int base_reg,int offset,char mod, Schedule::Type scheduleType = Schedule::None );
242 void op_movsd_RR (int xmm_reg1,int xmm_reg2);
243 void op_movsd_MR (int xmm_reg,int base_reg,int offset,char mod, Schedule::Type scheduleType = Schedule::None );
244 void op_movss_RR (int xmm_reg1,int xmm_reg2);
245 void op_movss_RM (int xmm_reg,int base_reg,int offset,char mod, Schedule::Type scheduleType = Schedule::None );
246 void op_movss_MR (int xmm_reg,int base_reg,int offset,char mod, Schedule::Type scheduleType = Schedule::None );
247 void op_movd_RX (int reg,int xmm_reg);
248 void op_cvtsd2ss (int xmm_reg1,int xmm_reg2);
249 void op_cvtss2sd (int xmm_reg1,int xmm_reg2);
250 void op_cvttsd2si_xmm (int op_size,int reg,int xmm_reg);
251 void op_cvttss2si_xmm (int op_size,int reg,int xmm_reg);
252 void op_cvtsi2sd_reg (int op_size,int xmm_reg,int reg);
253 void op_cvtsi2ss_reg (int op_size,int xmm_reg,int reg);
254 void op_comisd (int xmm_reg1,int xmm_reg2);
255 void op_comiss (int xmm_reg1,int xmm_reg2);
256 void op_rep_movs (int op_size);
257 void op_add_rsp(long num);
258 void op_sub_rsp(long num);
259 void op_add_esp(long num);
260 void op_sub_esp(long num);
261 void op_fld_ptr_esp(int type);
262 void op_zero_reg(int reg);
263 void op_call( const UserProc *pUserProc );
264 void op_call( const DllProc *pDllProc );
265 void op_ret();
266
267#else
268 /////////////////////////////////////////////////////////////////
269 // 32ビット機械語生成
270 /////////////////////////////////////////////////////////////////
271private:
272 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 );
273 void __op_format(char op_prefix,char opcode,int reg);
274 void __op_format(char op_prefix,char opcode1,char opcode2,int reg,int base_reg,int offset,char mod, Schedule::Type scheduleType = Schedule::None );
275public:
276 void op_mov_MV ( int op_size, int base_reg, long offset, Schedule::Type offsetScheduleType, long value, Schedule::Type valueScheduleType = Schedule::None );
277 void op_mov_RV (int reg,long offset, Schedule::Type scheduleType = Schedule::None );
278 void op_mov_RR (int reg1,int reg2);
279 void op_mov_RM (int op_size,int reg,int base_reg,int offset,char mod, Schedule::Type scheduleType = Schedule::None );
280 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 );
281 void op_mov_MR (int op_size,int reg,int base_reg,int offset,char mod, Schedule::Type scheduleType = Schedule::None );
282 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 );
283 void op_movsx_R32R16 (int reg32,int reg16 = REG_NON);
284 void op_movsx_R32R8 (int reg32,int reg8 = REG_NON);
285 void op_movsx_R16R8 (int reg16,int reg8 = REG_NON);
286 void op_lea_RM ( int reg, int base_reg, long offset, char mod, Schedule::Type scheduleType = Schedule::None );
287 void op_inc (int reg);
288 void op_dec (int reg);
289 void op_add_RV8 (int reg,char cValue);
290 void op_add_RV ( int reg, long offset, Schedule::Type scheduleType = Schedule::None );
291 void op_add_RR ( int reg1, int reg2 );
292 void op_add_RM (int op_size,int reg,int base_reg,int offset,char mod, Schedule::Type scheduleType = Schedule::None );
293 void op_adc_RV8 (int reg,char cValue);
294 void op_adc_RR ( int reg1, int reg2 );
295 void op_sub_RV8 (int reg,char cValue);
296 void op_sub_RR ( int reg1, int reg2 );
297 void op_sbb_RV8 (int reg,char cValue);
298 void op_sbb_RR ( int reg1, int reg2 );
299 void op_imul_RR (int reg1,int reg2);
300 void op_imul_RV (int reg,long i32data);
301 void op_imul_RV8 (int reg,char cValue);
302 void op_div_R ( int reg );
303 void op_idiv_R ( int reg );
304 void op_and_RV (int reg,long value);
305 void op_and_RR ( int reg1, int reg2 );
306 void op_or_RR ( int op_size, int reg1, int reg2 );
307 void op_xor_RR ( int reg1, int reg2 = REG_NON );
308 void op_neg ( int reg );
309 void op_cdq ();
310
311 void op_rep_movs (int op_size);
312
313 void op_push(int reg);
314 void op_push_V( long data, Schedule::Type scheduleType = Schedule::None );
315 void op_push_M( int base_reg );
316 void op_push_M( int base_reg, long offset, Schedule::Type scheduleType = Schedule::None );
317 void op_pop(int reg = REG_NON);
318 void op_add_esp(long num);
319 void op_sub_esp(long num);
320 void op_cmp_RR( int reg1, int reg2 );
321 void op_cmp_value(int op_size,int reg,char byte_data);
322 void op_setne( int reg );
323 void op_test(int reg1,int reg2);
324 void op_test_ah( char cValue );
325 void op_fld_ptr_esp(int type);
326 void op_fld_basereg (int type,int base_reg);
327 void op_fld_base_offset (int type,int base_reg,long offset, Schedule::Type scheduleType = Schedule::None );
328 void op_fld_base_offset_ex (int type,int base_reg1,int base_reg2,long offset,BOOL bUseOffset, Schedule::Type scheduleType = Schedule::None);
329 void op_fstp_basereg (int type,int base_reg);
330 void op_fstp_base_offset (int type,int base_reg,long offset, Schedule::Type scheduleType = Schedule::None);
331 void op_fstp_base_offset_ex (int type,int base_reg1,int base_reg2,long offset,BOOL bUseOffset, Schedule::Type scheduleType = Schedule::None);
332 void op_fistp_ptr_esp ( int typeSize );
333 void op_fstp_push ( Type &type );
334 void op_fcompp();
335 void op_fnstsw_ax();
336 void op_zero_reg(int reg);
337 void fpu_cast();
338 void fpu_cast_end();
339
340 void op_call_R( int reg );
341 void op_call(const UserProc *pUserProc);
342 void op_ret();
343 void op_ret( short stackFrameSize );
344 void op_addressof( int reg, const UserProc *pUserProc );
345#endif
346
347
348
349 void PutOld( long l, Schedule::Type scheduleType )
350 {
351 pNativeCode->Put( l, scheduleType );
352 }
353
354 void PutOld( char c1, char c2 )
355 {
356 pNativeCode->Put( c1 );
357 pNativeCode->Put( c2 );
358 }
359 void PutOld( char c1, char c2, char c3 )
360 {
361 pNativeCode->Put( c1 );
362 pNativeCode->Put( c2 );
363 pNativeCode->Put( c3 );
364 }
365 void PutOld( char c1, char c2, char c3, char c4 )
366 {
367 pNativeCode->Put( c1 );
368 pNativeCode->Put( c2 );
369 pNativeCode->Put( c3 );
370 pNativeCode->Put( c4 );
371 }
372 void PutOld( char c1, char c2, char c3, long l )
373 {
374 pNativeCode->Put( c1 );
375 pNativeCode->Put( c2 );
376 pNativeCode->Put( c3 );
377 pNativeCode->Put( l );
378 }
379 void PutOld( char c1, char c2, char c3, char c4, char c5 )
380 {
381 pNativeCode->Put( c1 );
382 pNativeCode->Put( c2 );
383 pNativeCode->Put( c3 );
384 pNativeCode->Put( c4 );
385 pNativeCode->Put( c5 );
386 }
387 void PutOld( char c1, char c2, char c3, char c4, char c5, char c6 )
388 {
389 pNativeCode->Put( c1 );
390 pNativeCode->Put( c2 );
391 pNativeCode->Put( c3 );
392 pNativeCode->Put( c4 );
393 pNativeCode->Put( c5 );
394 pNativeCode->Put( c6 );
395 }
396};
Note: See TracBrowser for help on using the repository browser.