source: dev/branches/egtra/ab5.0/abdev/compiler_x64/CodeGenerator.cpp@ 779

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

ObjectModuleに関連するクラス一式をab_commonプロジェクトに移動した。

File size: 46.8 KB
Line 
1#include "stdafx.h"
2
3
4//////////////////////
5// rexプリフィックス
6//////////////////////
7void CodeGenerator::set_rex(int op_size,int reg,int index_reg,int base_reg){
8 char RexByte;
9
10 if(reg==REG_NON&&index_reg==REG_NON){
11 /////////////////////////////////////
12 // レジスタをr/mのみに指定するとき
13 /////////////////////////////////////
14
15 if((base_reg&0x08)==0){
16 if(op_size==sizeof(char)&&(base_reg&0x04)){
17 // r/m に spl,bpl,sil,dilを指定するとき
18 RexByte=0x40;
19 }
20 else RexByte=0;
21 }
22 else RexByte=(char)0x41;
23 }
24 else{
25 /////////////////
26 // 通常
27 /////////////////
28
29 if((reg&0x08)==0){
30 //reg … rax~rdi
31
32 if((index_reg&0x08)==0){
33 if((base_reg&0x08)==0) RexByte=0;
34 else RexByte=(char)0x41;
35 }
36 else{
37 if((base_reg&0x08)==0) RexByte=(char)0x42;
38 else RexByte=(char)0x43;
39 }
40 }
41 else{
42 //reg … r8~r15
43
44 if((index_reg&0x08)==0){
45 if((base_reg&0x08)==0) RexByte=(char)0x44;
46 else RexByte=(char)0x45;
47 }
48 else{
49 if((base_reg&0x08)==0) RexByte=(char)0x46;
50 else RexByte=(char)0x47;
51 }
52 }
53 }
54
55 if(op_size==sizeof(_int64)){
56 //64ビットオペランド
57 RexByte|=0x48;
58 }
59
60 if(RexByte) pNativeCode->Put( RexByte );
61}
62
63
64
65/////////////////////////////////////////////////
66// ModR/Mバイト、SIBバイト、ディスプレースメント
67/////////////////////////////////////////////////
68
69//スケール
70#define SCALE_NON (char)0x00
71#define SCALE_2 (char)0x40
72#define SCALE_4 (char)0x80
73#define SCALE_8 (char)0xC0
74
75//インデックスなし
76#define INDEX_NON 0x04
77
78const PertialSchedule *CodeGenerator::set_mod_rm_sib_disp(char mod,int reg,int scale,int index_reg,int base_reg,long disp, Schedule::Type scheduleType, bool isPertialSchedule )
79{
80 const PertialSchedule *pPertialSchedule = NULL;
81
82 if(mod==MOD_DISP32){
83 //ModR/Mバイト
84 pNativeCode->Put( (char)( REGISTER_OPERAND(reg)<<3 | REGISTER_OPERAND(0x04)) );
85
86 base_reg=0x05;
87 index_reg=INDEX_NON;
88 }
89 else{
90 //ModR/Mバイト
91 pNativeCode->Put( (char)(mod | REGISTER_OPERAND(reg)<<3 | REGISTER_OPERAND(base_reg)) );
92 }
93
94
95 //レジスタモードの場合は、ここで終了
96 if(mod==MOD_REG) return pPertialSchedule;
97
98
99 if(REGISTER_OPERAND(base_reg)==0x04||mod==MOD_DISP32){
100 //////////////////////
101 // SIBバイトを使う
102 //////////////////////
103
104 pNativeCode->Put( (char)(scale| REGISTER_OPERAND(index_reg)<<3 | REGISTER_OPERAND(base_reg)) );
105 }
106
107 //ディスプレースメントを必要としない場合は、ここで終了
108 if(mod==MOD_BASE) return pPertialSchedule;
109
110
111 //////////////////////////
112 // ディスプレースメント
113 //////////////////////////
114
115 if(mod==MOD_BASE_DISP8)
116 {
117 pNativeCode->Put( (char)disp );
118 }
119 else
120 {
121 if( isPertialSchedule )
122 {
123 pertialSchedules.push_back( new PertialSchedule( pNativeCode->GetSize(), sizeof(long) ) );
124 pPertialSchedule = pertialSchedules.back();
125 }
126
127 this->PutWithSchedule( disp, scheduleType );
128 }
129
130 return pPertialSchedule;
131}
132
133
134
135const PertialSchedule *CodeGenerator::__op_format(int op_size,char op_prefix,char opcode1,char opcode2,int reg,int base_reg,long offset,char mod, Schedule::Type scheduleType, bool isPertialSchedule ){
136 //命令プリフィックス
137 if(op_prefix) pNativeCode->Put( op_prefix );
138
139 //rexプリフィックス
140 set_rex(op_size,reg,0,base_reg);
141
142 //オペコード
143 pNativeCode->Put( opcode1 );
144 if(opcode2) pNativeCode->Put( opcode2 );
145
146 //ModR/M, SIB, disp
147 return set_mod_rm_sib_disp(mod,reg,SCALE_NON,INDEX_NON,base_reg,offset, scheduleType, isPertialSchedule );
148}
149
150
151
152///////////////////
153// mov関連
154///////////////////
155
156const PertialSchedule *CodeGenerator::op_mov_RV(int op_size,int reg,long i32data, Schedule::Type scheduleType, bool isPertialSchedule ){
157 //mov reg,i32data
158
159 //rexプリフィックス
160 set_rex(op_size,REG_NON,REG_NON,reg);
161
162 if(op_size==sizeof(_int64)){
163 //オペコード
164 pNativeCode->Put( (char)0xC7 );
165
166 //レジスタ
167 pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg) ) );
168 }
169 else{
170 //レジスタ
171 pNativeCode->Put( (char)(0xB8| REGISTER_OPERAND(reg) ) );
172 }
173
174 //即値
175 const PertialSchedule *pPertialSchedule = NULL;
176 if( isPertialSchedule )
177 {
178 pertialSchedules.push_back( new PertialSchedule( pNativeCode->GetSize(), sizeof(long) ) );
179 pPertialSchedule = pertialSchedules.back();
180 }
181 this->PutWithSchedule( i32data, scheduleType );
182
183 return pPertialSchedule;
184}
185const PertialSchedule *CodeGenerator::op_mov_RV64( int reg, _int64 i64data, bool isPertialSchedule )
186{
187 //mov reg,i64data
188
189 //rexプリフィックス
190 set_rex(sizeof(_int64),REG_NON,REG_NON,reg);
191
192 //レジスタ
193 pNativeCode->Put( (char)(0xB8| REGISTER_OPERAND(reg) ) );
194
195 //即値
196 const PertialSchedule *pPertialSchedule = NULL;
197 if( isPertialSchedule )
198 {
199 pertialSchedules.push_back( new PertialSchedule( pNativeCode->GetSize(), sizeof(_int64) ) );
200 pPertialSchedule = pertialSchedules.back();
201 }
202 pNativeCode->Put( i64data );
203
204 return pPertialSchedule;
205}
206const PertialSchedule *CodeGenerator::op_mov_RM(int op_size,int reg,int base_reg,long offset,char mod, Schedule::Type scheduleType, bool isPertialSchedule ){
207 //mov reg64,qword ptr[base_reg+offset]
208 //mov reg32,dword ptr[base_reg+offset]
209 //mov reg16,word ptr[base_reg+offset]
210 //mov reg8,byte ptr[base_reg+offset]
211
212 //16ビット演算の命令プリフィックス
213 char op_prefix=0;
214 if(op_size==sizeof(short)) op_prefix=(char)0x66;
215
216 //オペコード
217 char opcode;
218 if(op_size==sizeof(char)) opcode=(char)0x8A;
219 else opcode=(char)0x8B;
220
221 return __op_format(op_size,op_prefix,opcode,0,reg,base_reg,offset,mod, scheduleType, isPertialSchedule );
222}
223const PertialSchedule *CodeGenerator::op_mov_RM_ex(int op_size,int reg,int base_reg1,int base_reg2,long offset,BOOL bUseOffset, Schedule::Type scheduleType, bool isPertialSchedule ){
224 //mov reg64,qword ptr[base_reg1+base_reg2+offset]
225 //mov reg32,dword ptr[base_reg1+base_reg2+offset]
226 //mov reg16,word ptr[base_reg1+base_reg2+offset]
227 //mov reg8,byte ptr[base_reg1+base_reg2+offset]
228 const PertialSchedule *pPertialSchedule = NULL;
229
230 if(base_reg1==REG_RSP){
231 //SIBバイトのindex部にrspは指定できない
232 base_reg1=base_reg2;
233 base_reg2=REG_RSP;
234 }
235
236 //16ビット演算のプリフィックス
237 if(op_size==sizeof(short)) pNativeCode->Put( (char)0x66 );
238
239 //rexプリフィックス
240 set_rex(op_size,reg,base_reg1,base_reg2);
241
242 //オペコード
243 if(op_size==sizeof(char)) pNativeCode->Put( (char)0x8A );
244 else pNativeCode->Put( (char)0x8B );
245
246 if(bUseOffset){
247 ///////////////////////////
248 // オフセット値を使う
249 ///////////////////////////
250
251 //レジスタ
252 pNativeCode->Put( (char)(0x84| REGISTER_OPERAND(reg)<<3) );
253
254 //ベースレジスタ
255 pNativeCode->Put( (char)(REGISTER_OPERAND(base_reg1)<<3 | REGISTER_OPERAND(base_reg2)) );
256
257 //オフセット値
258 if( isPertialSchedule )
259 {
260 pertialSchedules.push_back( new PertialSchedule( pNativeCode->GetSize(), sizeof(long) ) );
261 pPertialSchedule = pertialSchedules.back();
262 }
263 this->PutWithSchedule( offset, scheduleType );
264 }
265 else{
266 ///////////////////////////
267 // オフセット値を使わない
268 ///////////////////////////
269
270 //レジスタ
271 pNativeCode->Put( (char)(0x04| REGISTER_OPERAND(reg)<<3) );
272
273 //ベースレジスタ
274 pNativeCode->Put( (char)(REGISTER_OPERAND(base_reg1)<<3 | REGISTER_OPERAND(base_reg2)) );
275 }
276
277 return pPertialSchedule;
278}
279const PertialSchedule *CodeGenerator::op_mov_MR(int op_size,int reg,int base_reg,long offset,char mod, Schedule::Type scheduleType, bool isPertialSchedule ){
280 //mov qword ptr[base_reg+offset],reg64
281 //mov dword ptr[base_reg+offset],reg32
282 //mov word ptr[base_reg+offset],reg16
283 //mov byte ptr[base_reg+offset],reg8
284
285 //16ビット演算の命令プリフィックス
286 char op_prefix=0;
287 if(op_size==sizeof(short)) op_prefix=(char)0x66;
288
289 //オペコード
290 char opcode;
291 if(op_size==sizeof(char)) opcode=(char)0x88;
292 else opcode=(char)0x89;
293
294 return __op_format(op_size,op_prefix,opcode,0,reg,base_reg,offset,mod, scheduleType, isPertialSchedule );
295}
296const PertialSchedule *CodeGenerator::op_mov_MR_ex(int op_size,int reg,int base_reg1,int base_reg2,long offset,BOOL bUseOffset, Schedule::Type scheduleType, bool isPertialSchedule ){
297 //mov qword ptr[base_reg1+base_reg2+offset],reg64
298 //mov dword ptr[base_reg1+base_reg2+offset],reg32
299 //mov word ptr[base_reg1+base_reg2+offset],reg16
300 //mov byte ptr[base_reg1+base_reg2+offset],reg8
301 const PertialSchedule *pPertialSchedule = NULL;
302
303 if(base_reg1==REG_RSP){
304 //SIBバイトのindex部にrspは指定できない
305 base_reg1=base_reg2;
306 base_reg2=REG_RSP;
307 }
308
309 //16ビット演算のプリフィックス
310 if(op_size==sizeof(short)) pNativeCode->Put( (char)0x66 );
311
312 //rexプリフィックス
313 set_rex(op_size,reg,base_reg1,base_reg2);
314
315 //オペコード
316 if(op_size==sizeof(char)) pNativeCode->Put( (char)0x88 );
317 else pNativeCode->Put( (char)0x89 );
318
319 if(bUseOffset==USE_OFFSET){
320 //////////////////////////
321 //オフセット値を使う
322 //////////////////////////
323
324 //レジスタ
325 pNativeCode->Put( (char)(0x84| REGISTER_OPERAND(reg)<<3) );
326
327 //ベースレジスタ
328 pNativeCode->Put( (char)(REGISTER_OPERAND(base_reg1)<<3 | REGISTER_OPERAND(base_reg2)) );
329
330 //オフセット値
331 if( isPertialSchedule )
332 {
333 pertialSchedules.push_back( new PertialSchedule( pNativeCode->GetSize(), sizeof(long) ) );
334 pPertialSchedule = pertialSchedules.back();
335 }
336 this->PutWithSchedule( offset, scheduleType );
337 }
338 else{
339 //////////////////////////
340 //オフセット値を使わない
341 //////////////////////////
342
343 //レジスタ
344 pNativeCode->Put( (char)(0x04| REGISTER_OPERAND(reg)<<3) );
345
346 //ベースレジスタ
347 pNativeCode->Put( (char)(REGISTER_OPERAND(base_reg1)<<3 | REGISTER_OPERAND(base_reg2)) );
348 }
349
350 return pPertialSchedule;
351}
352
353const PertialSchedule *CodeGenerator::op_mov_MV(int op_size,int base_reg,int offset, Schedule::Type offsetScheduleType, bool isPertialSchedule, BOOL bUseOffset,long i32data){
354 //mov ptr[base_reg+offset],i32data
355 //mov ptr[base_reg ],i32data
356 const PertialSchedule *pPertialSchedule = NULL;
357
358 //16ビット演算のプリフィックス
359 if(op_size==sizeof(short)) pNativeCode->Put( (char)0x66 );
360
361 //rexプリフィックス
362 set_rex(op_size,0,0,base_reg);
363
364 //オペコード
365 if(op_size==sizeof(char)) pNativeCode->Put( (char)0xC6 );
366 else pNativeCode->Put( (char)0xC7 );
367
368 if(bUseOffset==USE_OFFSET){
369 //////////////////////////
370 //オフセット値を使う
371 //////////////////////////
372
373 //ModR/M, SIB, disp
374 pPertialSchedule = set_mod_rm_sib_disp(MOD_BASE_DISP32,0,SCALE_NON,INDEX_NON,base_reg,offset, offsetScheduleType, isPertialSchedule );
375 }
376 else{
377 //ModR/M, SIB, disp
378 set_mod_rm_sib_disp(MOD_BASE,0,SCALE_NON,INDEX_NON,base_reg,0);
379 }
380
381 //即値
382 if(op_size==sizeof(_int64)||op_size==sizeof(long)){
383 //32/64ビット
384 pNativeCode->Put( i32data );
385 }
386 else if(op_size==sizeof(short)){
387 //16ビット
388 pNativeCode->Put( (short)i32data );
389 }
390 else if(op_size==sizeof(char)){
391 //16ビット
392 pNativeCode->Put( (char)i32data );
393 }
394
395 return pPertialSchedule;
396}
397
398void CodeGenerator::op_mov_RR(int reg1,int reg2){
399 //mov reg1,reg2
400 char RexByte=-1;
401
402 if(reg1==reg2) return;
403
404 if(REG_RAX<=reg1&&reg1<=REG_RDI){
405 if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x48;
406 if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x49;
407 }
408 if(REG_R8<=reg1&&reg1<=REG_R15){
409 if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x4C;
410 if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x4D;
411 }
412
413 if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp);
414
415 // [8bit rex] 1000 1011 11xx xbbb
416 pNativeCode->Put( RexByte );
417 pNativeCode->Put( (char)0x8B );
418 pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg1)<<3 | REGISTER_OPERAND(reg2)) );
419}
420
421void CodeGenerator::op_movsxd(int reg64,int reg32){
422 //movsxd reg64,reg32
423 char RexByte=-1;
424
425 if(REG_RAX<=reg64&&reg64<=REG_RDI){
426 if(REG_RAX<=reg32&&reg32<=REG_RDI) RexByte=(char)0x48;
427 if(REG_R8<=reg32&&reg32<=REG_R15) RexByte=(char)0x49;
428 }
429 if(REG_R8<=reg64&&reg64<=REG_R15){
430 if(REG_RAX<=reg32&&reg32<=REG_RDI) RexByte=(char)0x4C;
431 if(REG_R8<=reg32&&reg32<=REG_R15) RexByte=(char)0x4D;
432 }
433
434 if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp);
435
436 //[8bit rex] 0110 0011 11rr rbbb
437 pNativeCode->Put( RexByte );
438 pNativeCode->Put( (char)0x63 );
439 pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg64)<<3 | REGISTER_OPERAND(reg32)) );
440}
441void CodeGenerator::op_movsx64_FromReg16(int reg64,int reg16){
442 //movsx reg64,reg16
443 char RexByte=-1;
444
445 if(REG_RAX<=reg64&&reg64<=REG_RDI){
446 if(REG_RAX<=reg16&&reg16<=REG_RDI) RexByte=(char)0x48;
447 if(REG_R8<=reg16&&reg16<=REG_R15) RexByte=(char)0x49;
448 }
449 if(REG_R8<=reg64&&reg64<=REG_R15){
450 if(REG_RAX<=reg16&&reg16<=REG_RDI) RexByte=(char)0x4C;
451 if(REG_R8<=reg16&&reg16<=REG_R15) RexByte=(char)0x4D;
452 }
453
454 if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp);
455
456 //[8bit rex] 0000 1111 1011 1111 11rr rbbb
457 pNativeCode->Put( RexByte );
458 pNativeCode->Put( (char)0x0F );
459 pNativeCode->Put( (char)0xBF );
460 pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg64)<<3 | REGISTER_OPERAND(reg16)) );
461}
462void CodeGenerator::op_movsx64_FromReg8(int reg64,int reg8){
463 //movsx reg64,reg8
464 char RexByte=-1;
465
466 if(REG_RAX<=reg64&&reg64<=REG_RDI){
467 if(REG_RAX<=reg8&&reg8<=REG_RDI) RexByte=(char)0x48;
468 if(REG_R8<=reg8&&reg8<=REG_R15) RexByte=(char)0x49;
469 }
470 if(REG_R8<=reg64&&reg64<=REG_R15){
471 if(REG_RAX<=reg8&&reg8<=REG_RDI) RexByte=(char)0x4C;
472 if(REG_R8<=reg8&&reg8<=REG_R15) RexByte=(char)0x4D;
473 }
474
475 if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp);
476
477 //[8bit rex] 0000 1111 1011 1110 11rr rbbb
478 pNativeCode->Put( RexByte );
479 pNativeCode->Put( (char)0x0F );
480 pNativeCode->Put( (char)0xBE );
481 pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg64)<<3 | REGISTER_OPERAND(reg8)) );
482}
483
484
485
486//////////////////
487// mov32関連
488//////////////////
489
490void CodeGenerator::op_movsx32_FromReg16(int reg32,int reg16){
491 //movsx reg32,reg16
492 char RexByte=-1;
493
494 if(REG_RAX<=reg32&&reg32<=REG_RDI){
495 if(REG_RAX<=reg16&&reg16<=REG_RDI) RexByte=0;
496 if(REG_R8<=reg16&&reg16<=REG_R15) RexByte=(char)0x41;
497 }
498 if(REG_R8<=reg32&&reg32<=REG_R15){
499 if(REG_RAX<=reg16&&reg16<=REG_RDI) RexByte=(char)0x44;
500 if(REG_R8<=reg16&&reg16<=REG_R15) RexByte=(char)0x45;
501 }
502
503 if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp);
504
505 //[8bit rex] 0000 1111 1011 1111 11rr rbbb
506 if(RexByte) pNativeCode->Put( RexByte );
507 pNativeCode->Put( (char)0x0F );
508 pNativeCode->Put( (char)0xBF );
509 pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg32)<<3 | REGISTER_OPERAND(reg16)) );
510}
511void CodeGenerator::op_movsx32_FromReg8(int reg32,int reg8){
512 //movsx reg32,reg8
513 char RexByte=-1;
514
515 if(REG_RAX<=reg32&&reg32<=REG_RDI){
516 if(REG_RAX<=reg8&&reg8<=REG_RBX) RexByte=0;
517 if(REG_RSP<=reg8&&reg8<=REG_RDI) RexByte=(char)0x40;
518 if(REG_R8<=reg8&&reg8<=REG_R15) RexByte=(char)0x41;
519 }
520 if(REG_R8<=reg32&&reg32<=REG_R15){
521 if(REG_RAX<=reg8&&reg8<=REG_RDI) RexByte=(char)0x44;
522 if(REG_R8<=reg8&&reg8<=REG_R15) RexByte=(char)0x45;
523 }
524
525 if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp);
526
527 //[8bit rex] 0000 1111 1011 1110 11rr rbbb
528 if(RexByte) pNativeCode->Put( RexByte );
529 pNativeCode->Put( (char)0x0F );
530 pNativeCode->Put( (char)0xBE );
531 pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg32)<<3 | REGISTER_OPERAND(reg8)) );
532}
533
534
535
536/////////////////////
537// mov16関連
538/////////////////////
539
540void CodeGenerator::op_movsx16_FromReg8(int reg32,int reg8){
541 //movsx reg16,reg8
542 char RexByte=-1;
543
544 if(REG_RAX<=reg32&&reg32<=REG_RDI){
545 if(REG_RAX<=reg8&&reg8<=REG_RBX) RexByte=0;
546 if(REG_RSP<=reg8&&reg8<=REG_RDI) RexByte=(char)0x40;
547 if(REG_R8<=reg8&&reg8<=REG_R15) RexByte=(char)0x41;
548 }
549 if(REG_R8<=reg32&&reg32<=REG_R15){
550 if(REG_RAX<=reg8&&reg8<=REG_RDI) RexByte=(char)0x44;
551 if(REG_R8<=reg8&&reg8<=REG_R15) RexByte=(char)0x45;
552 }
553
554 if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp);
555
556 //0110 0110 [8bit rex] 0000 1111 1011 1110 11rr rbbb
557 pNativeCode->Put( (char)0x66 );
558 if(RexByte) pNativeCode->Put( RexByte );
559 pNativeCode->Put( (char)0x0F );
560 pNativeCode->Put( (char)0xBE );
561 pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg32)<<3 | REGISTER_OPERAND(reg8)) );
562}
563
564
565
566//////////////////////////////////
567// ビット拡張
568//////////////////////////////////
569
570void CodeGenerator::op_cqo()
571{
572 pNativeCode->Put( (char)0x48 );
573 pNativeCode->Put( (char)0x99 );
574}
575
576
577
578//////////////////////////////////
579// インクリメント・デクリメント
580//////////////////////////////////
581
582void CodeGenerator::op_inc(int reg){
583 //inc reg
584
585 //16ビット演算の命令プリフィックス
586 char op_prefix=0;
587
588 //オペコード
589 char opcode=(char)0xFF;
590
591 __op_format(sizeof(_int64),op_prefix,opcode,0,0,reg,0,MOD_REG);
592}
593void CodeGenerator::op_dec(int reg){
594 //dec reg
595
596 //16ビット演算の命令プリフィックス
597 char op_prefix=0;
598
599 //オペコード
600 char opcode=(char)0xFF;
601
602 __op_format(sizeof(_int64),op_prefix,opcode,0,0x01,reg,0,MOD_REG);
603}
604
605
606
607/////////////////////
608// add関連
609/////////////////////
610
611const PertialSchedule *CodeGenerator::op_add_RM(int op_size,int reg,int base_reg,int offset,char mod, Schedule::Type scheduleType, bool isPertialSchedule ){
612 //add reg64,qword ptr[base_reg+offset]
613 //add reg32,dword ptr[base_reg+offset]
614 //add reg16,word ptr[base_reg+offset]
615 //add reg8,byte ptr[base_reg+offset]
616
617 //16ビット演算の命令プリフィックス
618 char op_prefix=0;
619 if(op_size==sizeof(short)) op_prefix=(char)0x66;
620
621 //オペコード
622 char opcode;
623 if(op_size==sizeof(char)) opcode=(char)0x02;
624 else opcode=(char)0x03;
625
626 return __op_format(op_size,op_prefix,opcode,0,reg,base_reg,offset,mod, scheduleType, isPertialSchedule );
627}
628
629const PertialSchedule *CodeGenerator::op_add_RV(int reg,long offset, Schedule::Type scheduleType, bool isPertialSchedule ){
630 //add reg,offset
631 const PertialSchedule *pPertialSchedule = NULL;
632
633 char RexByte=-1;
634
635 if(REG_RAX<=reg&&reg<=REG_RDI) RexByte=0x48;
636 if(REG_R8<=reg&&reg<=REG_R15) RexByte=0x49;
637
638 if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp);
639
640 if(reg==REG_RAX){
641 //raxのみ特殊
642
643 // [8bit rex] 0000 0101 [32bit offset]
644 pNativeCode->Put( (char)RexByte );
645 pNativeCode->Put( (char)0x05 );
646 }
647 else{
648 //rax以外
649
650 //[8bit rex] 1000 0001 1100 0xxx [32bit offset]
651 pNativeCode->Put( (char)RexByte );
652 pNativeCode->Put( (char)0x81 );
653 pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg)) );
654 }
655
656 if( isPertialSchedule )
657 {
658 pertialSchedules.push_back( new PertialSchedule( pNativeCode->GetSize(), sizeof(long) ) );
659 pPertialSchedule = pertialSchedules.back();
660 }
661 this->PutWithSchedule( offset, scheduleType );
662
663 return pPertialSchedule;
664}
665void CodeGenerator::op_add_RR(int reg1,int reg2){
666 //add reg1,reg2
667 char RexByte=-1;
668
669 if(REG_RAX<=reg1&&reg1<=REG_RDI){
670 if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x48;
671 if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x49;
672 }
673 if(REG_R8<=reg1&&reg1<=REG_R15){
674 if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x4C;
675 if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x4D;
676 }
677
678 if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp);
679
680 //[8bit rex] 0000 0011 11rr rbbb
681 pNativeCode->Put( (char)RexByte );
682 pNativeCode->Put( (char)0x03 );
683 pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg1)<<3 | REGISTER_OPERAND(reg2)) );
684}
685void CodeGenerator::op_add32_reg(int reg1,int reg2){
686 //add reg1,reg2
687 char RexByte=-1;
688
689 if(REG_RAX<=reg1&&reg1<=REG_RDI){
690 if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=0;
691 if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x41;
692 }
693 if(REG_R8<=reg1&&reg1<=REG_R15){
694 if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x44;
695 if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x45;
696 }
697
698 if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp);
699
700 //[8bit rex] 0000 0011 11rr rbbb
701 if(RexByte) pNativeCode->Put( (char)RexByte );
702 pNativeCode->Put( (char)0x03 );
703 pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg1)<<3 | REGISTER_OPERAND(reg2)) );
704}
705
706
707
708////////////////////////
709// sub関連
710////////////////////////
711
712void CodeGenerator::op_sub_RV(int op_size,int reg,long i32data){
713 //sub reg,i32data
714
715 //rexプリフィックス
716 set_rex(op_size,REG_NON,REG_NON,reg);
717
718 if(reg==REG_RAX){
719 //raxのみ特殊
720 pNativeCode->Put( (char)0x2D );
721 }
722 else{
723 //オペコード
724 pNativeCode->Put( (char)0x81 );
725
726 //レジスタ
727 pNativeCode->Put( (char)(0xE8| REGISTER_OPERAND(reg) ) );
728 }
729
730 //即値
731 pNativeCode->Put( i32data );
732}
733void CodeGenerator::op_sub64_reg(int reg1,int reg2){
734 //sub reg1,reg2
735 char RexByte=-1;
736
737 if(REG_RAX<=reg1&&reg1<=REG_RDI){
738 if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x48;
739 if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x49;
740 }
741 if(REG_R8<=reg1&&reg1<=REG_R15){
742 if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x4C;
743 if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x4D;
744 }
745
746 if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp);
747
748 //[8bit rex] 0010 1011 11rr rbbb
749 pNativeCode->Put( (char)RexByte );
750 pNativeCode->Put( (char)0x2B );
751 pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg1)<<3 | REGISTER_OPERAND(reg2)) );
752}
753void CodeGenerator::op_sub32_reg(int reg1,int reg2){
754 //sub reg1,reg2
755 char RexByte=-1;
756
757 if(REG_RAX<=reg1&&reg1<=REG_RDI){
758 if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=0;
759 if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x41;
760 }
761 if(REG_R8<=reg1&&reg1<=REG_R15){
762 if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x44;
763 if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x45;
764 }
765
766 if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp);
767
768 //[8bit rex] 0010 1011 11rr rbbb
769 if(RexByte) pNativeCode->Put( (char)RexByte );
770 pNativeCode->Put( (char)0x2B );
771 pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg1)<<3 | REGISTER_OPERAND(reg2)) );
772}
773void CodeGenerator::op_sbb_RR( int op_size, int reg1, int reg2 ){
774 //sbb reg1,reg2
775
776 //rexプリフィックス
777 set_rex(0,reg1,0,reg2);
778
779 //オペコード
780 pNativeCode->Put( (char)0x1B );
781
782 //レジスタ
783 pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg1)<<3 | REGISTER_OPERAND(reg2)) );
784}
785
786
787
788////////////////////////
789// imul関連
790////////////////////////
791
792void CodeGenerator::op_imul_RR(int op_size,int reg1,int reg2){
793 //imul reg1,reg2
794 char RexByte=-1;
795
796 if(op_size==sizeof(_int64)){
797 if(REG_RAX<=reg1&&reg1<=REG_RDI){
798 if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x48;
799 if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x49;
800 }
801 if(REG_R8<=reg1&&reg1<=REG_R15){
802 if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x4C;
803 if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x4D;
804 }
805 }
806 else{
807 if(REG_RAX<=reg1&&reg1<=REG_RDI){
808 if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=0;
809 if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x41;
810 }
811 if(REG_R8<=reg1&&reg1<=REG_R15){
812 if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x44;
813 if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x45;
814 }
815 }
816
817 if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp);
818
819
820 //rexプリフィックス
821 if(RexByte) pNativeCode->Put( (char)RexByte );
822
823 //オペコード
824 pNativeCode->Put( (char)0x0F );
825 pNativeCode->Put( (char)0xAF );
826
827 //レジスタ
828 pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg1)<<3 | REGISTER_OPERAND(reg2)) );
829}
830void CodeGenerator::op_imul_RV(int op_size,int reg,long i32data){
831 //imul reg,i32data
832 char RexByte=-1;
833
834 if(op_size==sizeof(_int64)){
835 if(REG_RAX<=reg&&reg<=REG_RDI) RexByte=(char)0x48;
836 if(REG_R8<=reg&&reg<=REG_R15) RexByte=(char)0x4D;
837 }
838 else{
839 if(REG_RAX<=reg&&reg<=REG_RDI) RexByte=0;
840 if(REG_R8<=reg&&reg<=REG_R15) RexByte=(char)0x45;
841 }
842
843 if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp);
844
845
846 //rexプリフィックス
847 if(RexByte) pNativeCode->Put( (char)RexByte );
848
849 if(-128<=i32data&&i32data<=127){
850 //オペコード
851 pNativeCode->Put( (char)0x6B );
852
853 //レジスタ
854 pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg)<<3 | REGISTER_OPERAND(reg)) );
855
856 //値
857 pNativeCode->Put( (char)i32data );
858 }
859 else{
860 //オペコード
861 pNativeCode->Put( (char)0x69 );
862
863 //レジスタ
864 pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg)<<3 | REGISTER_OPERAND(reg)) );
865
866 //値
867 pNativeCode->Put( i32data );
868 }
869}
870
871
872
873////////////////////////
874// div、idiv関連
875////////////////////////
876
877void CodeGenerator::op_div64_reg(int reg){
878 //div reg
879 char RexByte=-1;
880
881 if(REG_RAX<=reg&&reg<=REG_RDI) RexByte=(char)0x48;
882 if(REG_R8<=reg&&reg<=REG_R15) RexByte=(char)0x49;
883
884 if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp);
885
886 //rexプリフィックス
887 pNativeCode->Put( (char)RexByte );
888
889 //オペコード
890 pNativeCode->Put( (char)0xF7 );
891
892 //レジスタ
893 pNativeCode->Put( (char)(0xF0| REGISTER_OPERAND(reg)) );
894}
895void CodeGenerator::op_idiv64_reg(int reg){
896 //idiv reg
897 char RexByte=-1;
898
899 if(REG_RAX<=reg&&reg<=REG_RDI) RexByte=(char)0x48;
900 if(REG_R8<=reg&&reg<=REG_R15) RexByte=(char)0x49;
901
902 if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp);
903
904 //rexプリフィックス
905 pNativeCode->Put( (char)RexByte );
906
907 //オペコード
908 pNativeCode->Put( (char)0xF7 );
909
910 //レジスタ
911 pNativeCode->Put( (char)(0xF8| REGISTER_OPERAND(reg)) );
912}
913
914
915
916////////////////////
917// ビットシフト関連
918////////////////////
919
920void CodeGenerator::op_shl_reg(int op_size,int reg){
921 //shl reg,cl
922 char RexByte=-1;
923
924 if(op_size==sizeof(_int64)){
925 if(REG_RAX<=reg&&reg<=REG_RDI) RexByte=(char)0x48;
926 if(REG_R8<=reg&&reg<=REG_R15) RexByte=(char)0x49;
927 }
928 else if(op_size==sizeof(char)){
929 if(REG_RAX<=reg&&reg<=REG_RBX) RexByte=0;
930 if(REG_RSP<=reg&&reg<=REG_RDI) RexByte=(char)0x40;
931 if(REG_R8<=reg&&reg<=REG_R15) RexByte=(char)0x41;
932 }
933 else{
934 if(REG_RAX<=reg&&reg<=REG_RDI) RexByte=0;
935 if(REG_R8<=reg&&reg<=REG_R15) RexByte=(char)0x41;
936 }
937
938 if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp);
939
940
941 //16ビット演算のプリフィックス
942 if(op_size==sizeof(short)) pNativeCode->Put( (char)0x66 );
943
944 //rexプリフィックス
945 if(RexByte) pNativeCode->Put( (char)RexByte );
946
947 //オペコード
948 if(op_size==sizeof(char)) pNativeCode->Put( (char)0xD2 );
949 else pNativeCode->Put( (char)0xD3 );
950
951 //レジスタ
952 pNativeCode->Put( (char)(0xE0| REGISTER_OPERAND(reg)) );
953}
954void CodeGenerator::op_sar_reg(int op_size,int reg){
955 //sar reg,cl
956 char RexByte=-1;
957
958 if(op_size==sizeof(_int64)){
959 if(REG_RAX<=reg&&reg<=REG_RDI) RexByte=(char)0x48;
960 if(REG_R8<=reg&&reg<=REG_R15) RexByte=(char)0x49;
961 }
962 else if(op_size==sizeof(char)){
963 if(REG_RAX<=reg&&reg<=REG_RBX) RexByte=0;
964 if(REG_RSP<=reg&&reg<=REG_RDI) RexByte=(char)0x40;
965 if(REG_R8<=reg&&reg<=REG_R15) RexByte=(char)0x41;
966 }
967 else{
968 if(REG_RAX<=reg&&reg<=REG_RDI) RexByte=0;
969 if(REG_R8<=reg&&reg<=REG_R15) RexByte=(char)0x41;
970 }
971
972 if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp);
973
974
975 //16ビット演算のプリフィックス
976 if(op_size==sizeof(short)) pNativeCode->Put( (char)0x66 );
977
978 //rexプリフィックス
979 if(RexByte) pNativeCode->Put( (char)RexByte );
980
981 //オペコード
982 if(op_size==sizeof(char)) pNativeCode->Put( (char)0xD2 );
983 else pNativeCode->Put( (char)0xD3 );
984
985 //レジスタ
986 pNativeCode->Put( (char)(0xF8| REGISTER_OPERAND(reg)) );
987}
988void CodeGenerator::op_shr_reg(int op_size,int reg){
989 //shr reg,cl
990 char RexByte=-1;
991
992 if(op_size==sizeof(_int64)){
993 if(REG_RAX<=reg&&reg<=REG_RDI) RexByte=(char)0x48;
994 if(REG_R8<=reg&&reg<=REG_R15) RexByte=(char)0x49;
995 }
996 else if(op_size==sizeof(char)){
997 if(REG_RAX<=reg&&reg<=REG_RBX) RexByte=0;
998 if(REG_RSP<=reg&&reg<=REG_RDI) RexByte=(char)0x40;
999 if(REG_R8<=reg&&reg<=REG_R15) RexByte=(char)0x41;
1000 }
1001 else{
1002 if(REG_RAX<=reg&&reg<=REG_RDI) RexByte=0;
1003 if(REG_R8<=reg&&reg<=REG_R15) RexByte=(char)0x41;
1004 }
1005
1006 if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp);
1007
1008
1009 //16ビット演算のプリフィックス
1010 if(op_size==sizeof(short)) pNativeCode->Put( (char)0x66 );
1011
1012 //rexプリフィックス
1013 if(RexByte) pNativeCode->Put( (char)RexByte );
1014
1015 //オペコード
1016 if(op_size==sizeof(char)) pNativeCode->Put( (char)0xD2 );
1017 else pNativeCode->Put( (char)0xD3 );
1018
1019 //レジスタ
1020 pNativeCode->Put( (char)(0xE8| REGISTER_OPERAND(reg)) );
1021}
1022
1023
1024
1025////////////////////
1026// and 関連
1027////////////////////
1028
1029void CodeGenerator::op_and_reg(int op_size,int reg1,int reg2){
1030 //and reg1,reg2
1031 char RexByte=-1;
1032
1033 if(op_size==sizeof(_int64)){
1034 if(REG_RAX<=reg1&&reg1<=REG_RDI){
1035 if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x48;
1036 if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x49;
1037 }
1038 if(REG_R8<=reg1&&reg1<=REG_R15){
1039 if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x4C;
1040 if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x4D;
1041 }
1042 }
1043 else{
1044 if(REG_RAX<=reg1&&reg1<=REG_RDI){
1045 if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=0;
1046 if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x41;
1047 }
1048 if(REG_R8<=reg1&&reg1<=REG_R15){
1049 if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x44;
1050 if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x45;
1051 }
1052 }
1053
1054 if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp);
1055
1056
1057 //rexプリフィックス
1058 if(RexByte) pNativeCode->Put( (char)RexByte );
1059
1060 //オペコード
1061 pNativeCode->Put( (char)0x23 );
1062
1063 //レジスタ
1064 pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg1)<<3 | REGISTER_OPERAND(reg2)) );
1065}
1066void CodeGenerator::op_and64_value(int reg,long offset){
1067 //and reg,offset
1068 char RexByte=-1;
1069
1070 if(REG_RAX<=reg&&reg<=REG_RDI) (char)RexByte=0x48;
1071 if(REG_R8<=reg&&reg<=REG_R15) (char)RexByte=0x49;
1072
1073 if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp);
1074
1075 if(reg==REG_RAX){
1076 //raxのみ特殊
1077
1078 // [8bit rex] 0010 0101 [32bit offset]
1079 pNativeCode->Put( (char)RexByte );
1080 pNativeCode->Put( (char)0x25 );
1081 pNativeCode->Put( offset );
1082 }
1083 else{
1084 //rax以外
1085
1086 //[8bit rex] 1000 0001 1100 0xxx [32bit offset]
1087 pNativeCode->Put( (char)RexByte );
1088 pNativeCode->Put( (char)0x81 );
1089 pNativeCode->Put( (char)(0xE0| REGISTER_OPERAND(reg)) );
1090 pNativeCode->Put( offset );
1091 }
1092}
1093void CodeGenerator::op_and32_value(int reg,long offset){
1094 //and reg,offset
1095 char RexByte=-1;
1096
1097 if(REG_RAX<=reg&&reg<=REG_RDI) RexByte=0;
1098 if(REG_R8<=reg&&reg<=REG_R15) RexByte=(char)0x41;
1099
1100 if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp);
1101
1102 if(reg==REG_RAX){
1103 //eaxのみ特殊
1104
1105 // [8bit rex] 0010 0101 [32bit offset]
1106 pNativeCode->Put( (char)0x25 );
1107 pNativeCode->Put( offset );
1108 }
1109 else{
1110 //eax以外
1111
1112 //[8bit rex] 1000 0001 1100 0xxx [32bit offset]
1113 if(RexByte) pNativeCode->Put( (char)RexByte );
1114 pNativeCode->Put( (char)0x81 );
1115 pNativeCode->Put( (char)(0xE0| REGISTER_OPERAND(reg)) );
1116 pNativeCode->Put( offset );
1117 }
1118}
1119
1120
1121
1122////////////////////////
1123// or 関連
1124////////////////////////
1125
1126void CodeGenerator::op_or_reg(int op_size,int reg1,int reg2){
1127 //or reg1,reg2
1128 char RexByte=-1;
1129
1130 if(op_size==sizeof(_int64)){
1131 if(REG_RAX<=reg1&&reg1<=REG_RDI){
1132 if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x48;
1133 if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x49;
1134 }
1135 if(REG_R8<=reg1&&reg1<=REG_R15){
1136 if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x4C;
1137 if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x4D;
1138 }
1139 }
1140 else{
1141 if(REG_RAX<=reg1&&reg1<=REG_RDI){
1142 if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=0;
1143 if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x41;
1144 }
1145 if(REG_R8<=reg1&&reg1<=REG_R15){
1146 if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x44;
1147 if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x45;
1148 }
1149 }
1150
1151 if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp);
1152
1153
1154 //rexプリフィックス
1155 if(RexByte) pNativeCode->Put( (char)RexByte );
1156
1157 //オペコード
1158 pNativeCode->Put( (char)0x0B );
1159
1160 //レジスタ
1161 pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg1)<<3 | REGISTER_OPERAND(reg2)) );
1162}
1163
1164
1165
1166////////////////////////
1167// xor 関連
1168////////////////////////
1169
1170void CodeGenerator::op_xor_reg(int op_size,int reg1,int reg2){
1171 //xor reg1,reg2
1172 char RexByte=-1;
1173
1174 if(op_size==sizeof(_int64)){
1175 if(REG_RAX<=reg1&&reg1<=REG_RDI){
1176 if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x48;
1177 if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x49;
1178 }
1179 if(REG_R8<=reg1&&reg1<=REG_R15){
1180 if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x4C;
1181 if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x4D;
1182 }
1183 }
1184 else{
1185 if(REG_RAX<=reg1&&reg1<=REG_RDI){
1186 if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=0;
1187 if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x41;
1188 }
1189 if(REG_R8<=reg1&&reg1<=REG_R15){
1190 if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x44;
1191 if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x45;
1192 }
1193 }
1194
1195 if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp);
1196
1197
1198 //rexプリフィックス
1199 if(RexByte) pNativeCode->Put( (char)RexByte );
1200
1201 //オペコード
1202 pNativeCode->Put( (char)0x33 );
1203
1204 //レジスタ
1205 pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg1)<<3 | REGISTER_OPERAND(reg2)) );
1206}
1207
1208
1209
1210///////////////////////
1211// not 関連
1212///////////////////////
1213
1214void CodeGenerator::op_not_reg(int op_size,int reg){
1215 //not reg
1216 char RexByte=-1;
1217
1218 if(op_size==sizeof(_int64)){
1219 if(REG_RAX<=reg&&reg<=REG_RDI) RexByte=(char)0x48;
1220 if(REG_R8<=reg&&reg<=REG_R15) RexByte=(char)0x49;
1221 }
1222 else{
1223 if(REG_RAX<=reg&&reg<=REG_RDI) RexByte=0;
1224 if(REG_R8<=reg&&reg<=REG_R15) RexByte=(char)0x41;
1225 }
1226
1227 if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp);
1228
1229
1230 //rexプリフィックス
1231 if(RexByte) pNativeCode->Put( (char)RexByte );
1232
1233 //オペコード
1234 pNativeCode->Put( (char)0xF7 );
1235
1236 //レジスタ
1237 pNativeCode->Put( (char)(0xD0| REGISTER_OPERAND(reg)) );
1238}
1239void CodeGenerator::op_neg( int reg ){
1240 //neg reg
1241
1242 //オペコード
1243 pNativeCode->Put( (char)0xF7 );
1244
1245 //レジスタ
1246 pNativeCode->Put( (char)(0xD8| REGISTER_OPERAND(reg)) );
1247}
1248
1249
1250
1251////////////////////
1252// test関連
1253////////////////////
1254
1255void CodeGenerator::op_test(int reg1,int reg2){
1256 //test reg1,reg2
1257 char RexByte=-1;
1258
1259 if(REG_RAX<=reg1&&reg1<=REG_RDI){
1260 if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x48;
1261 if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x49;
1262 }
1263 if(REG_R8<=reg1&&reg1<=REG_R15){
1264 if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x4C;
1265 if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x4D;
1266 }
1267
1268 if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp);
1269
1270 //[8bit rex] 1000 0101 11rr rbbb
1271 pNativeCode->Put( (char)RexByte );
1272 pNativeCode->Put( (char)0x85 );
1273 pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg1)<<3 | REGISTER_OPERAND(reg2)) );
1274}
1275
1276
1277
1278/////////////////////
1279// cmp 関連
1280/////////////////////
1281
1282void CodeGenerator::op_cmp_reg(int op_size,int reg1,int reg2){
1283 //cmp reg1,reg2
1284 char RexByte=-1;
1285
1286 if(op_size==sizeof(_int64)){
1287 if(REG_RAX<=reg1&&reg1<=REG_RDI){
1288 if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x48;
1289 if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x49;
1290 }
1291 if(REG_R8<=reg1&&reg1<=REG_R15){
1292 if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x4C;
1293 if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x4D;
1294 }
1295 }
1296 else{
1297 if(REG_RAX<=reg1&&reg1<=REG_RDI){
1298 if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=0;
1299 if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x41;
1300 }
1301 if(REG_R8<=reg1&&reg1<=REG_R15){
1302 if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x44;
1303 if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x45;
1304 }
1305 }
1306
1307 if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp);
1308
1309
1310 //rexプリフィックス
1311 if(RexByte) pNativeCode->Put( (char)RexByte );
1312
1313 //オペコード
1314 pNativeCode->Put( (char)0x3B );
1315
1316 //レジスタ
1317 pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg1)<<3 | REGISTER_OPERAND(reg2)) );
1318}
1319void CodeGenerator::op_cmp_value(int op_size,int reg,char byte_data){
1320 //cmp reg,byte_data
1321
1322 if(op_size==sizeof(char)&&reg==REG_RAX){
1323 //alレジスタの場合は特殊
1324 pNativeCode->Put( (char)0x3C );
1325
1326 //8ビット値
1327 pNativeCode->Put( byte_data );
1328
1329 return;
1330 }
1331
1332 //16ビット演算のプリフィックス
1333 if(op_size==sizeof(short)) pNativeCode->Put( (char)0x66 );
1334
1335 //rexプリフィックス
1336 set_rex(op_size,REG_NON,REG_NON,reg);
1337
1338 //オペコード
1339 if(op_size==sizeof(char)) pNativeCode->Put( (char)0x80 );
1340 else pNativeCode->Put( (char)0x83 );
1341
1342 //レジスタ
1343 pNativeCode->Put( (char)(0xF8| REGISTER_OPERAND(reg)) );
1344
1345 //8ビット値
1346 pNativeCode->Put( byte_data );
1347}
1348void CodeGenerator::op_setne( int reg ){
1349 //オペコード
1350 pNativeCode->Put( (char)0x0F );
1351 pNativeCode->Put( (char)0x95 );
1352
1353 //レジスタ
1354 pNativeCode->Put( (char)( 0xC0 | REGISTER_OPERAND(reg) ) );
1355}
1356
1357
1358////////////////////
1359// SSE2関連
1360////////////////////
1361
1362const PertialSchedule *CodeGenerator::op_movlpd_MR(int xmm_reg,int base_reg,int offset,char mod, Schedule::Type scheduleType, bool isPertialSchedule ){
1363 //movlpd qword ptr[base_reg+offset],xmm_reg
1364 return __op_format(0,(char)0x66,(char)0x0F,(char)0x13,xmm_reg,base_reg,offset,mod, scheduleType, isPertialSchedule );
1365}
1366const PertialSchedule *CodeGenerator::op_movlpd_RM(int xmm_reg,int base_reg,int offset,char mod, Schedule::Type scheduleType, bool isPertialSchedule ){
1367 //movlpd xmm_reg,qword ptr[base_reg+offset]
1368 return __op_format(0,(char)0x66,(char)0x0F,(char)0x12,xmm_reg,base_reg,offset,mod, scheduleType, isPertialSchedule );
1369}
1370void CodeGenerator::op_movsd_RR(int xmm_reg1,int xmm_reg2){
1371 if(xmm_reg1==xmm_reg2) return;
1372
1373 //movsd xmm_reg1,xmm_reg2
1374 __op_format(0,(char)0xF2,(char)0x0F,(char)0x10,xmm_reg1,xmm_reg2,0,MOD_REG);
1375}
1376const PertialSchedule *CodeGenerator::op_movsd_MR(int xmm_reg,int base_reg,int offset,char mod, Schedule::Type scheduleType, bool isPertialSchedule ){
1377 //movsd qword ptr[reg+offset],xmm_reg
1378 //movsd qword ptr[reg],xmm_reg
1379 return __op_format(0,(char)0xF2,(char)0x0F,(char)0x11,xmm_reg,base_reg,offset,mod, scheduleType, isPertialSchedule );
1380}
1381void CodeGenerator::op_movss_RR(int xmm_reg1,int xmm_reg2){
1382 if(xmm_reg1==xmm_reg2) return;
1383
1384 //movss xmm_reg1,xmm_reg2
1385 __op_format(0,(char)0xF3,(char)0x0F,(char)0x10,xmm_reg1,xmm_reg2,0,MOD_REG);
1386}
1387const PertialSchedule *CodeGenerator::op_movss_RM(int xmm_reg,int base_reg,int offset,char mod, Schedule::Type scheduleType, bool isPertialSchedule ){
1388 //movss xmm_reg,dword ptr[base_reg+offset]
1389 return __op_format(0,(char)0xF3,(char)0x0F,(char)0x10,xmm_reg,base_reg,offset,mod, scheduleType, isPertialSchedule );
1390}
1391const PertialSchedule *CodeGenerator::op_movss_MR(int xmm_reg,int base_reg,int offset,char mod, Schedule::Type scheduleType, bool isPertialSchedule ){
1392 //movss dword ptr[reg+offset],xmm_reg
1393 //movss dword ptr[reg],xmm_reg
1394 return __op_format(0,(char)0xF3,(char)0x0F,(char)0x11,xmm_reg,base_reg,offset,mod, scheduleType, isPertialSchedule );
1395}
1396
1397void CodeGenerator::op_movd_RX(int reg,int xmm_reg){
1398 __op_format(sizeof(_int64),(char)0x66,(char)0x0F,(char)0x7E,xmm_reg,reg,0,MOD_REG);
1399}
1400
1401void CodeGenerator::op_cvtsd2ss(int xmm_reg1,int xmm_reg2){
1402 //cvtsd2ss xmm_reg1,xmm_reg2
1403
1404 //オペコード
1405 pNativeCode->Put( (char)0xF2 );
1406
1407 //rexプリフィックス
1408 set_rex(sizeof(long),xmm_reg1,0,xmm_reg2);
1409
1410 //オペコード
1411 pNativeCode->Put( (char)0x0F );
1412 pNativeCode->Put( (char)0x5A );
1413
1414 //レジスタ
1415 pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(xmm_reg1)<<3 | REGISTER_OPERAND(xmm_reg2)) );
1416}
1417void CodeGenerator::op_cvtss2sd(int xmm_reg1,int xmm_reg2){
1418 //cvtss2sd xmm_reg1,xmm_reg2
1419
1420 //オペコード
1421 pNativeCode->Put( (char)0xF3 );
1422
1423 //rexプリフィックス
1424 set_rex(0,xmm_reg1,0,xmm_reg2);
1425
1426 //オペコード
1427 pNativeCode->Put( (char)0x0F );
1428 pNativeCode->Put( (char)0x5A );
1429
1430 //レジスタ
1431 pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(xmm_reg1)<<3 | REGISTER_OPERAND(xmm_reg2)) );
1432}
1433void CodeGenerator::op_cvttsd2si_xmm(int op_size,int reg,int xmm_reg){
1434 //cvttsd2si reg,xmm_reg
1435
1436 //オペコード
1437 pNativeCode->Put( (char)0xF2 );
1438
1439 //rexプリフィックス
1440 set_rex(op_size,reg,0,xmm_reg);
1441
1442 //オペコード
1443 pNativeCode->Put( (char)0x0F );
1444 pNativeCode->Put( (char)0x2C );
1445
1446 //レジスタ
1447 pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg)<<3 | REGISTER_OPERAND(xmm_reg)) );
1448}
1449void CodeGenerator::op_cvttss2si_xmm(int op_size,int reg,int xmm_reg){
1450 //cvttss2si reg,xmm_reg
1451
1452 //オペコード
1453 pNativeCode->Put( (char)0xF3 );
1454
1455 //rexプリフィックス
1456 set_rex(op_size,reg,0,xmm_reg);
1457
1458 //オペコード
1459 pNativeCode->Put( (char)0x0F );
1460 pNativeCode->Put( (char)0x2C );
1461
1462 //レジスタ
1463 pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg)<<3 | REGISTER_OPERAND(xmm_reg)) );
1464}
1465void CodeGenerator::op_cvtsi2sd_reg(int op_size,int xmm_reg,int reg){
1466 //cvtsi2sd xmm_reg,reg
1467 char RexByte=-1;
1468
1469 if(op_size==sizeof(_int64)){
1470 if(REG_XMM0<=xmm_reg&&xmm_reg<=REG_XMM7){
1471 if(REG_RAX<=reg&&reg<=REG_RDI) RexByte=(char)0x48;
1472 if(REG_R8<=reg&&reg<=REG_R15) RexByte=(char)0x49;
1473 }
1474 if(REG_XMM8<=xmm_reg&&xmm_reg<=REG_XMM15){
1475 if(REG_RAX<=reg&&reg<=REG_RDI) RexByte=(char)0x4C;
1476 if(REG_R8<=reg&&reg<=REG_R15) RexByte=(char)0x4D;
1477 }
1478 }
1479 else{
1480 if(REG_XMM0<=xmm_reg&&xmm_reg<=REG_XMM7){
1481 if(REG_RAX<=reg&&reg<=REG_RDI) RexByte=0;
1482 if(REG_R8<=reg&&reg<=REG_R15) RexByte=(char)0x41;
1483 }
1484 if(REG_XMM8<=xmm_reg&&xmm_reg<=REG_XMM15){
1485 if(REG_RAX<=reg&&reg<=REG_RDI) RexByte=(char)0x44;
1486 if(REG_R8<=reg&&reg<=REG_R15) RexByte=(char)0x45;
1487 }
1488 }
1489
1490 if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp);
1491
1492
1493 //オペコード
1494 pNativeCode->Put( (char)0xF2 );
1495
1496 //rexプリフィックス
1497 if(RexByte) pNativeCode->Put( (char)RexByte );
1498
1499 //オペコード
1500 pNativeCode->Put( (char)0x0F );
1501 pNativeCode->Put( (char)0x2A );
1502
1503 //レジスタ
1504 pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(xmm_reg)<<3 | REGISTER_OPERAND(reg)) );
1505}
1506void CodeGenerator::op_cvtsi2ss_reg(int op_size,int xmm_reg,int reg){
1507 //cvtsi2ss xmm_reg,reg
1508 char RexByte=-1;
1509
1510 if(op_size==sizeof(_int64)){
1511 if(REG_XMM0<=xmm_reg&&xmm_reg<=REG_XMM7){
1512 if(REG_RAX<=reg&&reg<=REG_RDI) RexByte=(char)0x48;
1513 if(REG_R8<=reg&&reg<=REG_R15) RexByte=(char)0x49;
1514 }
1515 if(REG_XMM8<=xmm_reg&&xmm_reg<=REG_XMM15){
1516 if(REG_RAX<=reg&&reg<=REG_RDI) RexByte=(char)0x4C;
1517 if(REG_R8<=reg&&reg<=REG_R15) RexByte=(char)0x4D;
1518 }
1519 }
1520 else{
1521 if(REG_XMM0<=xmm_reg&&xmm_reg<=REG_XMM7){
1522 if(REG_RAX<=reg&&reg<=REG_RDI) RexByte=0;
1523 if(REG_R8<=reg&&reg<=REG_R15) RexByte=(char)0x41;
1524 }
1525 if(REG_XMM8<=xmm_reg&&xmm_reg<=REG_XMM15){
1526 if(REG_RAX<=reg&&reg<=REG_RDI) RexByte=(char)0x44;
1527 if(REG_R8<=reg&&reg<=REG_R15) RexByte=(char)0x45;
1528 }
1529 }
1530
1531 if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp);
1532
1533
1534 //オペコード
1535 pNativeCode->Put( (char)0xF3 );
1536
1537 //rexプリフィックス
1538 if(RexByte) pNativeCode->Put( (char)RexByte );
1539
1540 //オペコード
1541 pNativeCode->Put( (char)0x0F );
1542 pNativeCode->Put( (char)0x2A );
1543
1544 //レジスタ
1545 pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(xmm_reg)<<3 | REGISTER_OPERAND(reg)) );
1546}
1547void CodeGenerator::op_comisd(int xmm_reg1,int xmm_reg2){
1548 //comisd xmm_reg1,xmm_reg2
1549
1550 //オペコード
1551 pNativeCode->Put( (char)0x66 );
1552 pNativeCode->Put( (char)0x0F );
1553 pNativeCode->Put( (char)0x2F );
1554
1555 //レジスタ
1556 pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(xmm_reg1)<<3 | REGISTER_OPERAND(xmm_reg2)) );
1557}
1558void CodeGenerator::op_comiss(int xmm_reg1,int xmm_reg2){
1559 //comiss xmm_reg1,xmm_reg2
1560
1561 //オペコード
1562 pNativeCode->Put( (char)0x0F );
1563 pNativeCode->Put( (char)0x2F );
1564
1565 //レジスタ
1566 pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(xmm_reg1)<<3 | REGISTER_OPERAND(xmm_reg2)) );
1567}
1568
1569
1570
1571/////////////////////
1572// ストリング関係
1573/////////////////////
1574
1575void CodeGenerator::op_rep_movs(int op_size){
1576 if(op_size==sizeof(BYTE)){
1577 //rep movs byte ptr[edi],byte ptr[esi]
1578 pNativeCode->Put( (char)0xF3 );
1579 pNativeCode->Put( (char)0xA4 );
1580 }
1581 else if(op_size==sizeof(short)){
1582 //rep movs word ptr[edi],word ptr[esi]
1583 pNativeCode->Put( (char)0xF3 );
1584 pNativeCode->Put( (char)0x66 );
1585 pNativeCode->Put( (char)0xA5 );
1586 }
1587 else if(op_size==sizeof(long)){
1588 //rep movs dword ptr[edi],dword ptr[esi]
1589 pNativeCode->Put( (char)0xF3 );
1590 pNativeCode->Put( (char)0xA5 );
1591 }
1592}
1593
1594
1595
1596
1597void CodeGenerator::op_add_rsp(long num){
1598 //スタックポインタの加算(pop方向)
1599
1600 //add rsp,num
1601 if(0xFFFFFF80&num){
1602 pNativeCode->Put( (char)0x48 );
1603 pNativeCode->Put( (char)0x81 );
1604 pNativeCode->Put( (char)0xC4 );
1605 pNativeCode->Put( num );
1606 }
1607 else{
1608 //「-128 < num < 127」の場合
1609 pNativeCode->Put( (char)0x48 );
1610 pNativeCode->Put( (char)0x83 );
1611 pNativeCode->Put( (char)0xC4 );
1612 pNativeCode->Put( (char)num );
1613 }
1614}
1615const PertialSchedule *CodeGenerator::op_sub_rsp( long num, bool isPertialSchedule )
1616{
1617 //スタックポインタの減算(push方向)
1618 const PertialSchedule *pPertialSchedule = NULL;
1619
1620 //sub rsp,num
1621 if( (0xFFFFFF80&num) != 0 || isPertialSchedule ){
1622 pNativeCode->Put( (char)0x48 );
1623 pNativeCode->Put( (char)0x81 );
1624 pNativeCode->Put( (char)0xEC );
1625
1626 if( isPertialSchedule )
1627 {
1628 pertialSchedules.push_back( new PertialSchedule( pNativeCode->GetSize(), sizeof(long) ) );
1629 pPertialSchedule = pertialSchedules.back();
1630 }
1631 pNativeCode->Put( num );
1632 }
1633 else{
1634 //「-128 < num < 127」の場合
1635 pNativeCode->Put( (char)0x48 );
1636 pNativeCode->Put( (char)0x83 );
1637 pNativeCode->Put( (char)0xEC );
1638 pNativeCode->Put( (char)num );
1639 }
1640
1641 return pPertialSchedule;
1642}
1643
1644
1645
1646//////////////////////////////
1647// 浮動小数点関連
1648//////////////////////////////
1649
1650void CodeGenerator::op_fld_ptr_esp(int type){
1651 //スタックポインタが示すバッファのデータを浮動小数点レジスタへロード
1652
1653 if(type==DEF_DOUBLE){
1654 //fld qword ptr[esp]
1655 pNativeCode->Put( (char)0xDD );
1656 pNativeCode->Put( (char)0x04 );
1657 pNativeCode->Put( (char)0x24 );
1658 }
1659 else if(type==DEF_SINGLE){
1660 //fld dword ptr[esp]
1661 pNativeCode->Put( (char)0xD9 );
1662 pNativeCode->Put( (char)0x04 );
1663 pNativeCode->Put( (char)0x24 );
1664 }
1665 else if(type==DEF_INT64){
1666 //fild qword ptr[esp]
1667 pNativeCode->Put( (char)0xDF );
1668 pNativeCode->Put( (char)0x2C );
1669 pNativeCode->Put( (char)0x24 );
1670 }
1671 else if(type==DEF_LONG){
1672 //fild dword ptr[esp]
1673 pNativeCode->Put( (char)0xDB );
1674 pNativeCode->Put( (char)0x04 );
1675 pNativeCode->Put( (char)0x24 );
1676 }
1677}
1678
1679
1680
1681//////////////////////////////
1682// レジスタ関連
1683//////////////////////////////
1684
1685void CodeGenerator::op_zero_reg(int reg){
1686 //レジスタに0をセット
1687
1688 if(REG_RAX<=reg&&reg<=REG_RDI){
1689 /* rax~rdi
1690 0100 1000 0011 0011 11 xxx xxx */
1691 pNativeCode->Put( (char)0x48 );
1692 pNativeCode->Put( (char)0x33 );
1693 pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg)<<3 | REGISTER_OPERAND(reg)) );
1694 }
1695 if(REG_R8<=reg&&reg<=REG_R15){
1696 /* r8~r15
1697 0100 1101 0011 0011 11 xxx xxx */
1698 pNativeCode->Put( (char)0x4D );
1699 pNativeCode->Put( (char)0x33 );
1700 pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg)<<3 | REGISTER_OPERAND(reg)) );
1701 }
1702}
1703
1704
1705
1706/////////////////////////////
1707// 関数呼び出し
1708/////////////////////////////
1709
1710void CodeGenerator::op_call( const UserProc *pUserProc ){
1711 pNativeCode->Put( (char)0xE8 );
1712 pNativeCode->PutUserProcSchedule( pUserProc, true );
1713}
1714void CodeGenerator::op_call( const DllProc *pDllProc ){
1715 pNativeCode->Put( (char)0xFF );
1716 pNativeCode->Put( (char)0x15 );
1717 pNativeCode->PutDllProcSchedule( pDllProc );
1718}
1719void CodeGenerator::op_ret(){
1720 pNativeCode->Put( (char)0xC3 );
1721}
1722void CodeGenerator::op_addressof( int reg, const UserProc *pUserProc )
1723{
1724 //mov reg,userProcAddress
1725
1726 //オペコード、レジスタ
1727 pNativeCode->Put( (char)(0xB8|REGISTER_OPERAND(reg)) );
1728
1729 //DISP32
1730 pNativeCode->PutUserProcSchedule( pUserProc, false );
1731}
1732void CodeGenerator::op_mov_RV_com_vtbl( int reg, const CClass *pClass )
1733{
1734 // mov reg,com_vtblAddress
1735
1736 //オペコード、レジスタ
1737 pNativeCode->Put( (char)(0xB8|REGISTER_OPERAND(reg)) );
1738
1739 //DISP32
1740 pNativeCode->PutComVtblSchedule( pClass );
1741}
1742void CodeGenerator::op_mov_RV_vtbl( int reg, const CClass *pClass )
1743{
1744 // mov reg,vtblAddress
1745
1746 //オペコード、レジスタ
1747 pNativeCode->Put( (char)(0xB8|REGISTER_OPERAND(reg)) );
1748
1749 //DISP32
1750 pNativeCode->PutVtblSchedule( pClass );
1751}
Note: See TracBrowser for help on using the repository browser.