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

Last change on this file since 242 was 242, checked in by dai_9181, 17 years ago
File size: 13.4 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 // 部分スケジュールの管理
56 typedef std::vector<PertialSchedule *> PertialSchedules;
57 PertialSchedules pertialSchedules;
58
59 // Continue用のコード位置情報の管理
60 std::vector<long> continueCodePositions;
61 std::vector<long> _continueCodePositions_ObpOld;
62
63public:
64
65 CodeGenerator()
66 : pNativeCode( 0 )
67 {
68 }
69 ~CodeGenerator()
70 {
71 if( pNativeCode )
72 {
73 CheckUnresolveSchedule();
74 }
75 }
76
77 void Select( NativeCode &nativeCode )
78 {
79 if( pNativeCode )
80 {
81 CheckUnresolveSchedule();
82 }
83 pNativeCode = &nativeCode;
84 }
85
86 long GetContinueCodePos() const
87 {
88 if( continueCodePositions.size() == 0 )
89 {
90 return -1;
91 }
92 return continueCodePositions[continueCodePositions.size()-1];
93 }
94 void ClearContinueArea()
95 {
96 continueCodePositions.clear();
97 _continueCodePositions_ObpOld.clear();
98 }
99 void ContinueAreaBegin()
100 {
101 continueCodePositions.push_back( pNativeCode->GetSize() );
102
103 extern int obp;
104 _continueCodePositions_ObpOld.push_back( obp );
105 }
106 void ContinueAreaEnd()
107 {
108 continueCodePositions.pop_back();
109 _continueCodePositions_ObpOld.pop_back();
110 }
111 long GetContinueCodePosOld() const
112 {
113 if( _continueCodePositions_ObpOld.size() == 0 )
114 {
115 return -1;
116 }
117 return _continueCodePositions_ObpOld[_continueCodePositions_ObpOld.size()-1];
118 }
119
120 void CheckUnresolveSchedule();
121
122 void opfix_JmpPertialSchedule( const PertialSchedule *pPertialSchedule );
123
124
125 /////////////////////////////////////////////////////////////////
126 // 32bit/64bit共通 機械語生成
127 /////////////////////////////////////////////////////////////////
128
129private:
130 PertialSchedule *__jmp_op_format( char opcode, long offset, int op_size, bool isPertialSchedule = false, bool isSelfOpcodeOffset = false );
131public:
132 PertialSchedule *op_jle( long offset, int op_size = sizeof(char), bool isPertialSchedule = false );
133 PertialSchedule *op_jbe( long offset, int op_size = sizeof(char), bool isPertialSchedule = false );
134 PertialSchedule *op_jge( long offset, int op_size = sizeof(char), bool isPertialSchedule = false );
135 PertialSchedule *op_jae( long offset, int op_size = sizeof(char), bool isPertialSchedule = false );
136 PertialSchedule *op_jl( long offset, int op_size = sizeof(char), bool isPertialSchedule = false );
137 PertialSchedule *op_jb( long offset, int op_size = sizeof(char), bool isPertialSchedule = false );
138 PertialSchedule *op_jg( long offset, int op_size = sizeof(char), bool isPertialSchedule = false );
139 PertialSchedule *op_ja( long offset, int op_size = sizeof(char), bool isPertialSchedule = false );
140 PertialSchedule *op_jne( long offset, int op_size = sizeof(char), bool isPertialSchedule = false );
141 PertialSchedule *op_je( long offset, int op_size = sizeof(char), bool isPertialSchedule = false );
142 PertialSchedule *op_jmp( long offset, int op_size = sizeof(char), bool isPertialSchedule = false, bool isSelfOpcodeOffset = false );
143 void op_jmp_continue();
144
145
146#ifdef _AMD64_
147 /////////////////////////////////////////////////////////////////
148 // 64ビット機械語生成
149 /////////////////////////////////////////////////////////////////
150private:
151 void set_rex(int op_size,int reg,int index_reg,int base_reg);
152 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 );
153 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 );
154public:
155 void op_mov_RV (int op_size,int reg,long i32data, Schedule::Type scheduleType = Schedule::None );
156 void op_mov_RV64 (int reg,_int64 i64data);
157 void op_mov_RM (int op_size,int reg,int base_reg,long offset,char mod, Schedule::Type scheduleType = Schedule::None );
158 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 );
159 void op_mov_MR (int op_size,int reg,int base_reg,long offset,char mod, Schedule::Type scheduleType = Schedule::None );
160 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 );
161 void op_mov_MV (int op_size,int base_reg,int offset,BOOL bUseOffset,long i32data);
162 void op_mov_RR (int reg1,int reg2);
163 void op_movsxd (int reg64,int reg32);
164 void op_movsx64_FromReg16 (int reg64,int reg16);
165 void op_movsx64_FromReg8 (int reg64,int reg8);
166 void op_movsx32_FromReg16 (int reg32,int reg16);
167 void op_movsx32_FromReg8 (int reg32,int reg8);
168 void op_movsx16_FromReg8 (int reg32,int reg8);
169 void op_cqo ();
170 void op_inc (int reg);
171 void op_dec (int reg);
172 void op_add_RM (int op_size,int reg,int base_reg,int offset,char mod, Schedule::Type scheduleType = Schedule::None );
173 void op_add_RV (int reg,long offset, Schedule::Type scheduleType = Schedule::None );
174 void op_add_RR (int reg1,int reg2);
175 void op_add32_reg (int reg1,int reg2);
176 void op_sub_RV (int op_size,int reg,long i32data);
177 void op_sub64_reg (int reg1,int reg2);
178 void op_sub32_reg (int reg1,int reg2);
179 void op_sbb_RR ( int op_size, int reg1, int reg2 );
180 void op_imul_RR (int op_size,int reg1,int reg2);
181 void op_imul_RV (int op_size,int reg,long i32data);
182 void op_div64_reg (int reg);
183 void op_idiv64_reg (int reg);
184 void op_shl_reg (int op_size,int reg);
185 void op_sar_reg (int op_size,int reg);
186 void op_shr_reg (int op_size,int reg);
187 void op_and_reg (int op_size,int reg1,int reg2);
188 void op_and64_value (int reg,long offset);
189 void op_and32_value (int reg,long offset);
190 void op_or_reg (int op_size,int reg1,int reg2);
191 void op_xor_reg (int op_size,int reg1,int reg2);
192 void op_not_reg (int op_size,int reg);
193 void op_neg ( int reg );
194 void op_test (int reg1,int reg2);
195 void op_cmp_reg (int op_size,int reg1,int reg2);
196 void op_cmp_value (int op_size,int reg,char byte_data);
197 void op_setne (int reg);
198 void op_movlpd_MR (int xmm_reg,int base_reg,int offset,char mod, Schedule::Type scheduleType = Schedule::None );
199 void op_movlpd_RM (int xmm_reg,int base_reg,int offset,char mod, Schedule::Type scheduleType = Schedule::None );
200 void op_movsd_RR (int xmm_reg1,int xmm_reg2);
201 void op_movsd_MR (int xmm_reg,int base_reg,int offset,char mod, Schedule::Type scheduleType = Schedule::None );
202 void op_movss_RR (int xmm_reg1,int xmm_reg2);
203 void op_movss_RM (int xmm_reg,int base_reg,int offset,char mod, Schedule::Type scheduleType = Schedule::None );
204 void op_movss_MR (int xmm_reg,int base_reg,int offset,char mod, Schedule::Type scheduleType = Schedule::None );
205 void op_movd_RX (int reg,int xmm_reg);
206 void op_cvtsd2ss (int xmm_reg1,int xmm_reg2);
207 void op_cvtss2sd (int xmm_reg1,int xmm_reg2);
208 void op_cvttsd2si_xmm (int op_size,int reg,int xmm_reg);
209 void op_cvttss2si_xmm (int op_size,int reg,int xmm_reg);
210 void op_cvtsi2sd_reg (int op_size,int xmm_reg,int reg);
211 void op_cvtsi2ss_reg (int op_size,int xmm_reg,int reg);
212 void op_comisd (int xmm_reg1,int xmm_reg2);
213 void op_comiss (int xmm_reg1,int xmm_reg2);
214 void op_rep_movs (int op_size);
215 void op_add_rsp(long num);
216 void op_sub_rsp(long num);
217 void op_add_esp(long num);
218 void op_sub_esp(long num);
219 void op_fld_ptr_esp(int type);
220 void op_zero_reg(int reg);
221 void op_call( const UserProc *pUserProc );
222 void op_call( const DllProc *pDllProc );
223 void op_ret();
224
225#else
226 /////////////////////////////////////////////////////////////////
227 // 32ビット機械語生成
228 /////////////////////////////////////////////////////////////////
229private:
230 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 );
231 void __op_format(char op_prefix,char opcode,int reg);
232 void __op_format(char op_prefix,char opcode1,char opcode2,int reg,int base_reg,int offset,char mod, Schedule::Type scheduleType = Schedule::None );
233public:
234 void op_mov_MV ( int op_size, int base_reg, long offset, Schedule::Type offsetScheduleType, long value, Schedule::Type valueScheduleType = Schedule::None );
235 void op_mov_RV (int reg,long offset, Schedule::Type scheduleType = Schedule::None );
236 void op_mov_RR (int reg1,int reg2);
237 void op_mov_RM (int op_size,int reg,int base_reg,int offset,char mod, Schedule::Type scheduleType = Schedule::None );
238 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 );
239 void op_mov_MR (int op_size,int reg,int base_reg,int offset,char mod, Schedule::Type scheduleType = Schedule::None );
240 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 );
241 void op_movsx_R32R16 (int reg32,int reg16 = REG_NON);
242 void op_movsx_R32R8 (int reg32,int reg8 = REG_NON);
243 void op_movsx_R16R8 (int reg16,int reg8 = REG_NON);
244 void op_lea_RM ( int reg, int base_reg, long offset, char mod, Schedule::Type scheduleType = Schedule::None );
245 void op_inc (int reg);
246 void op_dec (int reg);
247 void op_add_RV8 (int reg,char cValue);
248 void op_add_RV ( int reg, long offset, Schedule::Type scheduleType = Schedule::None );
249 void op_add_RR ( int reg1, int reg2 );
250 void op_add_RM (int op_size,int reg,int base_reg,int offset,char mod, Schedule::Type scheduleType = Schedule::None );
251 void op_adc_RV8 (int reg,char cValue);
252 void op_adc_RR ( int reg1, int reg2 );
253 void op_sub_RV8 (int reg,char cValue);
254 void op_sub_RR ( int reg1, int reg2 );
255 void op_sbb_RV8 (int reg,char cValue);
256 void op_sbb_RR ( int reg1, int reg2 );
257 void op_imul_RR (int reg1,int reg2);
258 void op_imul_RV (int reg,long i32data);
259 void op_imul_RV8 (int reg,char cValue);
260 void op_div_R ( int reg );
261 void op_idiv_R ( int reg );
262 void op_and_RV (int reg,long value);
263 void op_and_RR ( int reg1, int reg2 );
264 void op_or_RR ( int op_size, int reg1, int reg2 );
265 void op_xor_RR ( int reg1, int reg2 = REG_NON );
266 void op_neg ( int reg );
267 void op_cdq ();
268
269 void op_rep_movs (int op_size);
270
271 void op_push(int reg);
272 void op_push_V( long data, Schedule::Type scheduleType = Schedule::None );
273 void op_push_M( int base_reg );
274 void op_push_M( int base_reg, long offset, Schedule::Type scheduleType = Schedule::None );
275 void op_pop(int reg = REG_NON);
276 void op_add_esp(long num);
277 void op_sub_esp(long num);
278 void op_cmp_RR( int reg1, int reg2 );
279 void op_cmp_value(int op_size,int reg,char byte_data);
280 void op_setne( int reg );
281 void op_test(int reg1,int reg2);
282 void op_test_ah( char cValue );
283 void op_fld_ptr_esp(int type);
284 void op_fld_basereg (int type,int base_reg);
285 void op_fld_base_offset (int type,int base_reg,long offset, Schedule::Type scheduleType = Schedule::None );
286 void op_fld_base_offset_ex (int type,int base_reg1,int base_reg2,long offset,BOOL bUseOffset, Schedule::Type scheduleType = Schedule::None);
287 void op_fstp_basereg (int type,int base_reg);
288 void op_fstp_base_offset (int type,int base_reg,long offset, Schedule::Type scheduleType = Schedule::None);
289 void op_fstp_base_offset_ex (int type,int base_reg1,int base_reg2,long offset,BOOL bUseOffset, Schedule::Type scheduleType = Schedule::None);
290 void op_fistp_ptr_esp ( int typeSize );
291 void op_fstp_push ( Type &type );
292 void op_fcompp();
293 void op_fnstsw_ax();
294 void op_zero_reg(int reg);
295 void fpu_cast();
296 void fpu_cast_end();
297
298 void op_call_R( int reg );
299 void op_call(const UserProc *pUserProc);
300 void op_ret();
301 void op_ret( short stackFrameSize );
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.