source: dev/trunk/ab5.0/abdev/compiler_x64/CodeGenerator.cpp@ 584

Last change on this file since 584 was 584, checked in by dai_9181, 16 years ago

[530][583]を64bit版にマージ。

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