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

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