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

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