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, 15 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.