source: dev/trunk/abdev/BasicCompiler32/x86CodeGenerator.cpp@ 251

Last change on this file since 251 was 251, checked in by dai_9181, 17 years ago
File size: 28.7 KB
Line 
1#include "stdafx.h"
2
3#include <Procedure.h>
4#include <CodeGenerator.h>
5
6
7
8/////////////////////////////////////////////////
9// ModR/Mバイト、SIBバイト、ディスプレースメント
10/////////////////////////////////////////////////
11
12//スケール
13#define SCALE_NON (char)0x00
14#define SCALE_2 (char)0x40
15#define SCALE_4 (char)0x80
16#define SCALE_8 (char)0xC0
17
18//インデックスなし
19#define INDEX_NON 0x04
20
21const 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 )
22{
23 const PertialSchedule *pPertialSchedule = NULL;
24
25 // エラーチェック
26 if( ! ( mod == MOD_BASE
27 || mod == MOD_DISP32
28 || mod == MOD_BASE_DISP8
29 || mod == MOD_BASE_DISP32
30 || mod == MOD_REG ) )
31 {
32 SetError();
33 }
34 if( isPertialSchedule && !( mod == MOD_DISP32 || mod == MOD_BASE_DISP32 ) )
35 {
36 SetError();
37 }
38
39 if(mod==MOD_DISP32){
40 //ModR/Mバイト
41 pNativeCode->Put( (char)(REGISTER_OPERAND(reg)<<3 | REGISTER_OPERAND(0x04)) );
42
43 base_reg=0x05;
44 index_reg=INDEX_NON;
45 }
46 else{
47 //ModR/Mバイト
48 pNativeCode->Put( (char)(mod | REGISTER_OPERAND(reg)<<3 | REGISTER_OPERAND(base_reg)) );
49 }
50
51
52 //レジスタモードの場合は、ここで終了
53 if(mod==MOD_REG) return pPertialSchedule;
54
55
56 if(REGISTER_OPERAND(base_reg)==0x04||mod==MOD_DISP32){
57 //////////////////////
58 // SIBバイトを使う
59 //////////////////////
60
61 pNativeCode->Put( (char)(scale| REGISTER_OPERAND(index_reg)<<3 | REGISTER_OPERAND(base_reg)) );
62 }
63
64 //ディスプレースメントを必要としない場合は、ここで終了
65 if(mod==MOD_BASE) return pPertialSchedule;
66
67
68 //////////////////////////
69 // ディスプレースメント
70 //////////////////////////
71
72 if(mod==MOD_BASE_DISP8)
73 {
74 pNativeCode->Put( (char)disp );
75 }
76 else
77 {
78 if( isPertialSchedule )
79 {
80 pertialSchedules.push_back( new PertialSchedule( pNativeCode->GetSize(), sizeof(long) ) );
81 pPertialSchedule = pertialSchedules.back();
82 }
83
84 pNativeCode->Put( disp, scheduleType );
85 }
86
87 return pPertialSchedule;
88}
89
90
91
92void CodeGenerator::__op_format(char op_prefix,char opcode,int reg){
93 //命令プリフィックス
94 if(op_prefix)
95 {
96 pNativeCode->Put( op_prefix );
97 }
98
99 //オペコード、レジスタ
100 pNativeCode->Put( (char)(opcode|REGISTER_OPERAND(reg)) );
101}
102const PertialSchedule *CodeGenerator::__op_format(char op_prefix,char opcode1,char opcode2,int reg,int base_reg,int offset,char mod, Schedule::Type scheduleType, bool isPertialSchedule ){
103 //命令プリフィックス
104 if(op_prefix)
105 {
106 pNativeCode->Put( op_prefix );
107 }
108
109 //オペコード
110 pNativeCode->Put( opcode1 );
111 if(opcode2)
112 {
113 pNativeCode->Put( opcode2 );
114 }
115
116 //ModR/M, SIB, disp
117 return set_mod_rm_sib_disp(mod,reg,SCALE_NON,INDEX_NON,base_reg,offset, scheduleType, isPertialSchedule );
118}
119
120
121
122///////////////////
123// mov関連
124///////////////////
125
126void CodeGenerator::op_mov_MV( int op_size, int base_reg, long offset, Schedule::Type offsetScheduleType, long value, Schedule::Type valueScheduleType )
127{
128 //mov ptr[base_reg+offset],value
129
130 if( op_size == sizeof(char) )
131 {
132 pNativeCode->Put( (char)0xC6 );
133 pNativeCode->Put( (char)(0x80|REGISTER_OPERAND(base_reg)) );
134 pNativeCode->Put( offset, offsetScheduleType );
135 pNativeCode->Put( (char)value );
136 }
137 else if( op_size == sizeof(short) )
138 {
139 pNativeCode->Put( (char)0x66 );
140 pNativeCode->Put( (char)0xC7 );
141 pNativeCode->Put( (char)(0x80|REGISTER_OPERAND(base_reg)) );
142 pNativeCode->Put( offset, offsetScheduleType );
143 pNativeCode->Put( (short)value );
144 }
145 else if( op_size == sizeof(long) )
146 {
147 pNativeCode->Put( (char)0xC7 );
148 pNativeCode->Put( (char)(0x80|REGISTER_OPERAND(base_reg)) );
149 pNativeCode->Put( offset, offsetScheduleType );
150 pNativeCode->Put( value, valueScheduleType );
151 }
152}
153void CodeGenerator::op_mov_RV(int reg,long offset, Schedule::Type scheduleType ){
154 //mov reg,value
155
156 //オペコード、レジスタ
157 pNativeCode->Put( (char)(0xB8|REGISTER_OPERAND(reg)) );
158
159 //DISP32
160 pNativeCode->Put( offset, scheduleType );
161}
162void CodeGenerator::op_mov_RR(int reg1,int reg2){
163 //mov reg1,reg2
164
165 if(reg1==reg2) return;
166
167 //1000 1011 11xx xbbb
168 pNativeCode->Put( (char)0x8B );
169 pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg1)<<3 | REGISTER_OPERAND(reg2)) );
170}
171void CodeGenerator::op_mov_RM(int op_size,int reg,int base_reg,int offset,char mod, Schedule::Type scheduleType ){
172 //mov reg32,dword ptr[base_reg+offset]
173 //mov reg16,word ptr[base_reg+offset]
174 //mov reg8,byte ptr[base_reg+offset]
175
176 //16ビット演算の命令プリフィックス
177 char op_prefix=0;
178 if(op_size==sizeof(short)) op_prefix=(char)0x66;
179
180 //オペコード
181 char opcode;
182 if(op_size==sizeof(char)) opcode=(char)0x8A;
183 else opcode=(char)0x8B;
184
185 __op_format(op_prefix,opcode,0,reg,base_reg,offset,mod, scheduleType );
186}
187void CodeGenerator::op_mov_RM_ex(int op_size,int reg,int base_reg1,int base_reg2,long offset,BOOL bUseOffset, Schedule::Type scheduleType ){
188 //mov reg32,dword ptr[base_reg1+base_reg2+offset]
189 //mov reg16,word ptr[base_reg1+base_reg2+offset]
190 //mov reg8,byte ptr[base_reg1+base_reg2+offset]
191
192 if(base_reg1==REG_ESP){
193 //SIBバイトのindex部にespは指定できない
194 base_reg1=base_reg2;
195 base_reg2=REG_ESP;
196 }
197
198 //16ビット演算のプリフィックス
199 if(op_size==sizeof(short)) pNativeCode->Put( (char)0x66 );
200
201 //オペコード
202 if(op_size==sizeof(char)) pNativeCode->Put( (char)0x8A );
203 else pNativeCode->Put( (char)0x8B );
204
205 if(bUseOffset){
206 ///////////////////////////
207 // オフセット値を使う
208 ///////////////////////////
209
210 //レジスタ
211 pNativeCode->Put( (char)(0x84| REGISTER_OPERAND(reg)<<3) );
212
213 //ベースレジスタ
214 pNativeCode->Put( (char)(REGISTER_OPERAND(base_reg1)<<3 | REGISTER_OPERAND(base_reg2)) );
215
216 //オフセット値
217 pNativeCode->Put( offset, scheduleType );
218 }
219 else{
220 ///////////////////////////
221 // オフセット値を使わない
222 ///////////////////////////
223
224 //レジスタ
225 pNativeCode->Put( (char)(0x04| REGISTER_OPERAND(reg)<<3) );
226
227 //ベースレジスタ
228 pNativeCode->Put( (char)(REGISTER_OPERAND(base_reg1)<<3 | REGISTER_OPERAND(base_reg2)) );
229 }
230}
231void CodeGenerator::op_mov_MR(int op_size,int reg,int base_reg,int offset,char mod, Schedule::Type scheduleType ){
232 //mov dword ptr[base_reg+offset],reg32
233 //mov word ptr[base_reg+offset],reg16
234 //mov byte ptr[base_reg+offset],reg8
235
236 //16ビット演算の命令プリフィックス
237 char op_prefix=0;
238 if(op_size==sizeof(short)) op_prefix=(char)0x66;
239
240 //オペコード
241 char opcode;
242 if(op_size==sizeof(char)) opcode=(char)0x88;
243 else opcode=(char)0x89;
244
245 __op_format(op_prefix,opcode,0,reg,base_reg,offset,mod, scheduleType );
246}
247void CodeGenerator::op_mov_MR_ex(int op_size,int reg,int base_reg1,int base_reg2,long offset,BOOL bUseOffset, Schedule::Type scheduleType ){
248 //mov dword ptr[base_reg1+base_reg2+offset],reg32
249 //mov word ptr[base_reg1+base_reg2+offset],reg16
250 //mov byte ptr[base_reg1+base_reg2+offset],reg8
251
252 if(base_reg1==REG_ESP){
253 //SIBバイトのindex部にrspは指定できない
254 base_reg1=base_reg2;
255 base_reg2=REG_ESP;
256 }
257
258 //16ビット演算のプリフィックス
259 if(op_size==sizeof(short)) pNativeCode->Put( (char)0x66 );
260
261 //オペコード
262 if(op_size==sizeof(char)) pNativeCode->Put( (char)0x88 );
263 else pNativeCode->Put( (char)0x89 );
264
265 if(bUseOffset==USE_OFFSET){
266 //////////////////////////
267 //オフセット値を使う
268 //////////////////////////
269
270 //レジスタ
271 pNativeCode->Put( (char)(0x84| REGISTER_OPERAND(reg)<<3) );
272
273 //ベースレジスタ
274 pNativeCode->Put( (char)(REGISTER_OPERAND(base_reg1)<<3 | REGISTER_OPERAND(base_reg2)) );
275
276 //オフセット値
277 pNativeCode->Put( offset, scheduleType );
278 }
279 else{
280 //////////////////////////
281 //オフセット値を使わない
282 //////////////////////////
283
284 //レジスタ
285 pNativeCode->Put( (char)(0x04| REGISTER_OPERAND(reg)<<3) );
286
287 //ベースレジスタ
288 pNativeCode->Put( (char)(REGISTER_OPERAND(base_reg1)<<3 | REGISTER_OPERAND(base_reg2)) );
289 }
290}
291
292
293
294
295////////////////////////////////
296// movsx関連
297////////////////////////////////
298
299void CodeGenerator::op_movsx_R32R16(int reg32,int reg16){
300 //movsx reg32,reg16
301
302 if( reg16 == REG_NON )
303 {
304 reg16 = reg32;
305 }
306
307 //16ビット演算の命令プリフィックス
308 char op_prefix=0;
309
310 //オペコード
311 char opcode=(char)0x0F;
312 char opcode2=(char)0xBF;
313
314 __op_format(op_prefix,opcode,opcode2,reg32,reg16,0,MOD_REG);
315}
316void CodeGenerator::op_movsx_R32R8(int reg32,int reg8){
317 //movsx reg32,reg8
318
319 if( reg8 == REG_NON )
320 {
321 reg8 = reg32;
322 }
323
324 //16ビット演算の命令プリフィックス
325 char op_prefix=0;
326
327 //オペコード
328 char opcode=(char)0x0F;
329 char opcode2=(char)0xBE;
330
331 __op_format(op_prefix,opcode,opcode2,reg32,reg8,0,MOD_REG);
332}
333void CodeGenerator::op_movsx_R16R8(int reg16,int reg8){
334 //movsx reg16,reg8
335
336 if( reg8 == REG_NON )
337 {
338 reg8 = reg16;
339 }
340
341 //16ビット演算の命令プリフィックス
342 char op_prefix=(char)0x66;
343
344 //オペコード
345 char opcode=(char)0x0F;
346 char opcode2=(char)0xBE;
347
348 __op_format(op_prefix,opcode,opcode2,reg16,reg8,0,MOD_REG);
349}
350
351
352
353//////////////////////////////////
354// lea関連
355//////////////////////////////////
356
357void CodeGenerator::op_lea_RM( int reg, int base_reg, long offset, char mod, Schedule::Type scheduleType )
358{
359 //16ビット演算の命令プリフィックス
360 char op_prefix=0;
361
362 //オペコード
363 char opcode=(char)0x8D;
364
365 __op_format( op_prefix, opcode, 0, reg, base_reg, offset, mod, scheduleType );
366}
367
368
369
370//////////////////////////////////
371// インクリメント・デクリメント
372//////////////////////////////////
373
374void CodeGenerator::op_inc(int reg){
375 //inc reg
376
377 //16ビット演算の命令プリフィックス
378 char op_prefix=0;
379
380 //オペコード
381 char opcode=(char)0xFF;
382
383 __op_format(op_prefix,opcode,0,0,reg,0,MOD_REG);
384}
385void CodeGenerator::op_dec(int reg){
386 //dec reg
387
388 //16ビット演算の命令プリフィックス
389 char op_prefix=0;
390
391 //オペコード
392 char opcode=(char)0xFF;
393
394 __op_format(op_prefix,opcode,0,0x01,reg,0,MOD_REG);
395}
396
397
398
399/////////////////////
400// add関連
401/////////////////////
402
403void CodeGenerator::op_add_RV8(int reg,char cValue){
404 //add reg,value8
405
406 pNativeCode->Put( (char)0x83 );
407 pNativeCode->Put( (char)(0xC0|REGISTER_OPERAND(reg)) );
408 pNativeCode->Put( cValue );
409}
410void CodeGenerator::op_add_RV( int reg, long offset, Schedule::Type scheduleType )
411{
412 // add reg,offset
413
414 if( reg == REG_EAX )
415 {
416 // eaxのみ特殊
417 pNativeCode->Put( (char)0x05 );
418 pNativeCode->Put( offset, scheduleType );
419 }
420 else
421 {
422 pNativeCode->Put( (char)0x81 );
423 pNativeCode->Put( (char)(0xC0|REGISTER_OPERAND(reg)) );
424 pNativeCode->Put( offset, scheduleType );
425 }
426}
427void CodeGenerator::op_add_RR( int reg1, int reg2 )
428{
429 //16ビット演算の命令プリフィックス
430 char op_prefix=0;
431
432 //オペコード
433 char opcode = (char)0x03;
434
435 __op_format(op_prefix,opcode,0,reg1,reg2,0,MOD_REG);
436}
437void CodeGenerator::op_add_RM(int op_size,int reg,int base_reg,int offset,char mod, Schedule::Type scheduleType ){
438 //add reg32,dword ptr[base_reg+offset]
439 //add reg16,word ptr[base_reg+offset]
440 //add reg8,byte ptr[base_reg+offset]
441
442 //16ビット演算の命令プリフィックス
443 char op_prefix=0;
444 if(op_size==sizeof(short)) op_prefix=(char)0x66;
445
446 //オペコード
447 char opcode;
448 if(op_size==sizeof(char)) opcode=(char)0x02;
449 else opcode=(char)0x03;
450
451 __op_format(op_prefix,opcode,0,reg,base_reg,offset,mod, scheduleType );
452}
453void CodeGenerator::op_adc_RV8(int reg,char cValue){
454 //adc reg,value8
455
456 pNativeCode->Put( (char)0x83 );
457 pNativeCode->Put( (char)(0xD0|REGISTER_OPERAND(reg)) );
458 pNativeCode->Put( cValue );
459}
460void CodeGenerator::op_adc_RR( int reg1, int reg2 )
461{
462 // adc reg1, reg2
463
464 //16ビット演算の命令プリフィックス
465 char op_prefix=0;
466
467 //オペコード
468 char opcode = (char)0x13;
469
470 __op_format( op_prefix, opcode, 0, reg1, reg2, 0, MOD_REG );
471}
472
473
474/////////////////////
475// sub関連
476/////////////////////
477
478void CodeGenerator::op_sub_RV8(int reg,char cValue){
479 //sub reg,value8
480
481 pNativeCode->Put( (char)0x83 );
482 pNativeCode->Put( (char)(0xE8|REGISTER_OPERAND(reg)) );
483 pNativeCode->Put( cValue );
484}
485void CodeGenerator::op_sub_RR( int reg1, int reg2 )
486{
487 // sub reg1, reg2
488
489 //16ビット演算の命令プリフィックス
490 char op_prefix=0;
491
492 //オペコード
493 char opcode = (char)0x2B;
494
495 __op_format( op_prefix, opcode, 0, reg1, reg2, 0, MOD_REG );
496}
497void CodeGenerator::op_sbb_RV8(int reg,char cValue){
498 //sbb reg,value8
499
500 pNativeCode->Put( (char)0x83 );
501 pNativeCode->Put( (char)(0xD8|REGISTER_OPERAND(reg)) );
502 pNativeCode->Put( cValue );
503}
504void CodeGenerator::op_sbb_RR( int reg1, int reg2 ){
505 //sbb reg1,reg2
506
507 //16ビット演算の命令プリフィックス
508 char op_prefix=0;
509
510 //オペコード
511 char opcode = (char)0x1B;
512
513 __op_format( op_prefix, opcode, 0, reg1, reg2, 0, MOD_REG );
514}
515
516
517
518////////////////////////
519// imul関連
520////////////////////////
521
522void CodeGenerator::op_imul_RR(int reg1,int reg2){
523 //imul reg1,reg2
524
525 //命令プリフィックス
526 char op_prefix = (char)0x0F;
527
528 //オペコード
529 char opcode = (char)0xAF;
530
531 __op_format( op_prefix, opcode, 0, reg1, reg2, 0, MOD_REG );
532}
533
534void CodeGenerator::op_imul_RV(int reg,long i32data){
535 //imul reg,i32data
536
537 if(-128<=i32data&&i32data<=127){
538 //オペコード
539 pNativeCode->Put( (char)0x6B );
540
541 //レジスタ
542 pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg)<<3 | REGISTER_OPERAND(reg)) );
543
544 //値
545 pNativeCode->Put( (char)i32data );
546 }
547 else{
548 //オペコード
549 pNativeCode->Put( (char)0x69 );
550
551 //レジスタ
552 pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg)<<3 | REGISTER_OPERAND(reg)) );
553
554 //値
555 pNativeCode->Put( i32data );
556 }
557}
558void CodeGenerator::op_imul_RV8(int reg,char cValue)
559{
560 //オペコード
561 pNativeCode->Put( (char)0x6B );
562
563 //レジスタ
564 pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg)<<3 | REGISTER_OPERAND(reg)) );
565
566 //値
567 pNativeCode->Put( cValue );
568}
569
570
571
572//////////////////////
573// div関連
574//////////////////////
575
576void CodeGenerator::op_div_R( int reg )
577{
578 //div reg (eax=eax/reg...edx)
579 __op_format( (char)0xF7, (char)0xF0, reg );
580}
581void CodeGenerator::op_idiv_R( int reg )
582{
583 //idiv reg (eax=eax/reg...edx)
584 __op_format( (char)0xF7, (char)0xF8, reg );
585}
586
587
588
589//////////////////////
590// and関連
591//////////////////////
592
593void CodeGenerator::op_and_RV(int reg,long value){
594 //and reg,value
595
596 if(reg==REG_RAX){
597 //eaxのみ特殊
598
599 // [8bit rex] 0010 0101 [32bit offset]
600 pNativeCode->Put( (char)0x25 );
601 pNativeCode->Put( value );
602 }
603 else{
604 //16ビット演算の命令プリフィックス
605 char op_prefix=0;
606
607 //オペコード
608 char opcode=(char)0x81;
609
610 __op_format(op_prefix,opcode,0,0,reg,value,MOD_REG);
611 }
612}
613
614void CodeGenerator::op_and_RR( int reg1, int reg2 )
615{
616 //16ビット演算の命令プリフィックス
617 char op_prefix=0;
618
619 //オペコード
620 char opcode=(char)0x23;
621
622 __op_format(op_prefix,opcode,0,reg1,reg2,0,MOD_REG);
623}
624
625void CodeGenerator::op_or_RR( int op_size, int reg1, int reg2 ){
626 //16ビット演算のプリフィックス
627 if(op_size==sizeof(short)) pNativeCode->Put( (char)0x66 );
628
629 //オペコード
630 if(op_size==sizeof(char)) pNativeCode->Put( (char)0x0A );
631 else pNativeCode->Put( (char)0x0B );
632
633 //レジスタ
634 pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg1)<<3 | REGISTER_OPERAND(reg2)) );
635}
636
637void CodeGenerator::op_xor_RR( int reg1, int reg2 ){
638 // xor reg1, reg2
639
640 if( reg2 == REG_NON )
641 {
642 reg2 = reg1;
643 }
644
645 //16ビット演算の命令プリフィックス
646 char op_prefix=0;
647
648 //オペコード
649 char opcode=(char)0x33;
650
651 __op_format(op_prefix,opcode,0,reg1,reg2,0,MOD_REG);
652}
653
654
655
656void CodeGenerator::op_neg( int reg ){
657 //neg reg
658
659 //命令プリフィックス
660 char op_prefix = (char)0xF7;
661
662 //オペコード
663 char opcode = (char)0xD8;
664
665 __op_format( op_prefix, opcode, reg );
666}
667
668
669
670///////////////////////
671// 64ビット関連
672///////////////////////
673
674void CodeGenerator::op_cdq(){
675 //cdq
676 pNativeCode->Put( (char)0x99 );
677}
678
679
680
681/////////////////////
682// ストリング関係
683/////////////////////
684
685void CodeGenerator::op_rep_movs(int op_size){
686 if(op_size==sizeof(BYTE)){
687 //rep movs byte ptr[edi],byte ptr[esi]
688 pNativeCode->Put( (char)0xF3 );
689 pNativeCode->Put( (char)0xA4 );
690 }
691 else if(op_size==sizeof(short)){
692 //rep movs word ptr[edi],word ptr[esi]
693 pNativeCode->Put( (char)0xF3 );
694 pNativeCode->Put( (char)0x66 );
695 pNativeCode->Put( (char)0xA5 );
696 }
697 else if(op_size==sizeof(long)){
698 //rep movs dword ptr[edi],dword ptr[esi]
699 pNativeCode->Put( (char)0xF3 );
700 pNativeCode->Put( (char)0xA5 );
701 }
702}
703
704
705
706
707//////////////////////////
708// スタック関連
709//////////////////////////
710
711void CodeGenerator::op_push(int reg){
712 //push reg
713
714 if( reg == REG_NON ){
715 op_sub_esp( PTR_SIZE );
716 return;
717 }
718
719 //オペコード、レジスタ
720 __op_format(0,(char)0x50,reg);
721}
722void CodeGenerator::op_push_V(long data, Schedule::Type scheduleType ){
723 //スタックにリテラル値をプッシュ
724 if(-128<=data&&data<=127 && scheduleType == Schedule::None ){
725 //push 8ビット値
726 pNativeCode->Put( (char)0x6A );
727 pNativeCode->Put( (char)data );
728 }
729 else{
730 //push 32ビット値
731 pNativeCode->Put( (char)0x68 );
732 pNativeCode->Put( data, scheduleType );
733 }
734}
735void CodeGenerator::op_push_M( int base_reg )
736{
737 if( base_reg == REG_EBP )
738 {
739 op_push_M( base_reg, 0 );
740 }
741 else
742 {
743 // push dword ptr[base_reg]
744 __op_format( (char)0xFF, (char)0x30, base_reg );
745 }
746}
747const PertialSchedule *CodeGenerator::op_push_M( int base_reg, long offset, Schedule::Type scheduleType, bool isPertialSchedule )
748{
749 const PertialSchedule *pPertialSchedule = NULL;
750 if( base_reg == REG_NON )
751 {
752 // push dword ptr[offset]
753 pPertialSchedule = __op_format( 0, (char)0xFF, 0, /*opcode->*/0x06, 0, offset, MOD_DISP32, scheduleType, isPertialSchedule );
754 }
755 else
756 {
757 // push dword ptr[base_reg+offset]
758 pPertialSchedule = __op_format( 0, (char)0xFF, 0, /*opcode->*/0x06, base_reg, offset, MOD_BASE_DISP32, scheduleType, isPertialSchedule );
759 }
760 return pPertialSchedule;
761}
762void CodeGenerator::op_pop(int reg){
763 //pop reg
764
765 if( reg == REG_NON ){
766 op_add_esp( PTR_SIZE );
767 return;
768 }
769
770 //オペコード、レジスタ
771 __op_format(0,(char)0x58,reg);
772}
773void CodeGenerator::op_add_esp(long num){
774 //スタックポインタの加算(pop方向)
775
776 //add esp,num
777 if(0xFFFFFF80&num){
778 pNativeCode->Put( (char)0x81 );
779 pNativeCode->Put( (char)0xC4 );
780 pNativeCode->Put( num );
781 }
782 else{
783 //「128 > num > -127」の場合
784 pNativeCode->Put( (char)0x83 );
785 pNativeCode->Put( (char)0xC4 );
786 pNativeCode->Put( (char)num );
787 }
788}
789void CodeGenerator::op_sub_esp(long num){
790 //スタックポインタの減算(push方向)
791
792 //sub esp,num
793 if(0xFFFFFF80&num){
794 pNativeCode->Put( (char)0x81 );
795 pNativeCode->Put( (char)0xEC );
796 pNativeCode->Put( num );
797 }
798 else{
799 //「128 > num > -127」の場合
800 pNativeCode->Put( (char)0x83 );
801 pNativeCode->Put( (char)0xEC );
802 pNativeCode->Put( (char)num );
803 }
804}
805
806
807
808/////////////////////
809// cmp関連
810/////////////////////
811void CodeGenerator::op_cmp_RR( int reg1, int reg2 ){
812 //cmp reg1,reg2
813 __op_format( (char)0, (char)0x3B, 0, reg1, reg2, 0, MOD_REG );
814}
815void CodeGenerator::op_cmp_value(int op_size,int reg,char byte_data){
816 //cmp reg,byte_data
817
818 if(op_size==sizeof(char)&&reg==REG_EAX){
819 //alレジスタの場合は特殊
820 pNativeCode->Put( (char)0x3C );
821
822 //8ビット値
823 pNativeCode->Put( byte_data );
824
825 return;
826 }
827
828 //16ビット演算のプリフィックス
829 if(op_size==sizeof(short)) pNativeCode->Put( (char)0x66 );
830
831 //オペコード
832 if(op_size==sizeof(char)) pNativeCode->Put( (char)0x80 );
833 else pNativeCode->Put( (char)0x83 );
834
835 //レジスタ
836 pNativeCode->Put( (char)(0xF8| REGISTER_OPERAND(reg)) );
837
838 //8ビット値
839 pNativeCode->Put( byte_data );
840}
841void CodeGenerator::op_setne( int reg ){
842 //オペコード
843 pNativeCode->Put( (char)0x0F );
844 pNativeCode->Put( (char)0x95 );
845
846 //レジスタ
847 pNativeCode->Put( (char)( 0xC0 | REGISTER_OPERAND(reg) ) );
848}
849
850
851
852////////////////////
853// test関連
854////////////////////
855
856void CodeGenerator::op_test(int reg1,int reg2){
857 //test reg1,reg2
858
859 //1000 0101 11rr rbbb
860 pNativeCode->Put( (char)0x85 );
861 pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg1)<<3 | REGISTER_OPERAND(reg2)) );
862}
863void CodeGenerator::op_test_ah( char cValue )
864{
865 pNativeCode->Put( (char)0xF6 );
866 pNativeCode->Put( (char)0xC4 );
867 pNativeCode->Put( cValue );
868}
869
870
871
872//////////////////////////////
873// 浮動小数点関連
874//////////////////////////////
875
876void CodeGenerator::op_fld_ptr_esp(int type){
877 //スタックポインタが示すバッファのデータを浮動小数点レジスタへロード
878
879 if(type==DEF_DOUBLE){
880 //fld qword ptr[esp]
881 pNativeCode->Put( (char)0xDD );
882 pNativeCode->Put( (char)0x04 );
883 pNativeCode->Put( (char)0x24 );
884 }
885 else if(type==DEF_SINGLE){
886 //fld dword ptr[esp]
887 pNativeCode->Put( (char)0xD9 );
888 pNativeCode->Put( (char)0x04 );
889 pNativeCode->Put( (char)0x24 );
890 }
891 else if(type==DEF_INT64){
892 //fild qword ptr[esp]
893 pNativeCode->Put( (char)0xDF );
894 pNativeCode->Put( (char)0x2C );
895 pNativeCode->Put( (char)0x24 );
896 }
897 else if(type==DEF_LONG){
898 //fild dword ptr[esp]
899 pNativeCode->Put( (char)0xDB );
900 pNativeCode->Put( (char)0x04 );
901 pNativeCode->Put( (char)0x24 );
902 }
903}
904void CodeGenerator::op_fld_basereg(int type,int base_reg){
905 //fld ptr[reg]
906
907 //オペコード
908 if(type==DEF_DOUBLE) pNativeCode->Put( (char)0xDD );
909 else if(type==DEF_SINGLE) pNativeCode->Put( (char)0xD9 );
910 else SetError(300,NULL,cp);
911
912 if(base_reg==REG_ESP){
913 pNativeCode->Put( (char)0x04 );
914 pNativeCode->Put( (char)0x24 );
915 }
916 else if(base_reg==REG_EBP){
917 pNativeCode->Put( (char)0x45 );
918 pNativeCode->Put( (char)0x00 );
919 }
920 else{
921 pNativeCode->Put( (char)REGISTER_OPERAND(base_reg) );
922 }
923}
924void CodeGenerator::op_fld_base_offset(int type,int base_reg,long offset, Schedule::Type scheduleType ){
925 //fld ptr[reg+offset]
926
927 //オペコード
928 if(type==DEF_DOUBLE) pNativeCode->Put( (char)0xDD );
929 else if(type==DEF_SINGLE) pNativeCode->Put( (char)0xD9 );
930 else SetError(300,NULL,cp);
931
932 //オペコード、レジスタ
933 if(base_reg==REG_ESP){
934 pNativeCode->Put( (char)0x84 );
935 pNativeCode->Put( (char)0x24 );
936 }
937 else{
938 pNativeCode->Put( (char)(0x80|REGISTER_OPERAND(base_reg)) );
939 }
940
941 //オフセット値
942 pNativeCode->Put( offset, scheduleType );
943}
944void CodeGenerator::op_fld_base_offset_ex(int type,int base_reg1,int base_reg2,long offset,BOOL bUseOffset, Schedule::Type scheduleType ){
945 //fld ptr[base_reg1+base_reg2+offset]
946
947 if(base_reg1==REG_ESP){
948 //SIBバイトのindex部にespは指定できない
949 base_reg1=base_reg2;
950 base_reg2=REG_ESP;
951 }
952
953 //オペコード
954 if(type==DEF_DOUBLE) pNativeCode->Put( (char)0xDD );
955 else if(type==DEF_SINGLE) pNativeCode->Put( (char)0xD9 );
956 else SetError(300,NULL,cp);
957
958 int reg=0;
959 if(bUseOffset){
960 ///////////////////////////
961 // オフセット値を使う
962 ///////////////////////////
963
964 //レジスタ
965 pNativeCode->Put( (char)(0x84| REGISTER_OPERAND(reg)<<3) );
966
967 //ベースレジスタ
968 pNativeCode->Put( (char)(REGISTER_OPERAND(base_reg1)<<3 | REGISTER_OPERAND(base_reg2)) );
969
970 //オフセット値
971 pNativeCode->Put( offset, scheduleType );
972 }
973 else{
974 ///////////////////////////
975 // オフセット値を使わない
976 ///////////////////////////
977
978 //レジスタ
979 pNativeCode->Put( (char)(0x04| REGISTER_OPERAND(reg)<<3) );
980
981 //ベースレジスタ
982 pNativeCode->Put( (char)(REGISTER_OPERAND(base_reg1)<<3 | REGISTER_OPERAND(base_reg2)) );
983 }
984}
985void CodeGenerator::op_fstp_basereg(int type,int base_reg){
986 //fstp ptr[reg]
987
988 //オペコード
989 if(type==DEF_DOUBLE) pNativeCode->Put( (char)0xDD );
990 else if(type==DEF_SINGLE) pNativeCode->Put( (char)0xD9 );
991 else SetError(300,NULL,cp);
992
993 if(base_reg==REG_ESP){
994 pNativeCode->Put( (char)0x1C );
995 pNativeCode->Put( (char)0x24 );
996 }
997 else if(base_reg==REG_EBP){
998 pNativeCode->Put( (char)0x5D );
999 pNativeCode->Put( (char)0x00 );
1000 }
1001 else{
1002 pNativeCode->Put( (char)(0x18|REGISTER_OPERAND(base_reg)) );
1003 }
1004}
1005void CodeGenerator::op_fstp_base_offset(int type,int base_reg,long offset, Schedule::Type scheduleType ){
1006 //fstp ptr[reg+offset]
1007
1008 //オペコード
1009 if(type==DEF_DOUBLE) pNativeCode->Put( (char)0xDD );
1010 else if(type==DEF_SINGLE) pNativeCode->Put( (char)0xD9 );
1011 else SetError(300,NULL,cp);
1012
1013 //オペコード、レジスタ
1014 if(base_reg==REG_ESP){
1015 pNativeCode->Put( (char)0x9C );
1016 pNativeCode->Put( (char)0x24 );
1017 }
1018 else{
1019 pNativeCode->Put( (char)(0x98|REGISTER_OPERAND(base_reg)) );
1020 }
1021
1022 //オフセット値
1023 pNativeCode->Put( offset, scheduleType );
1024}
1025void CodeGenerator::op_fstp_base_offset_ex(int type,int base_reg1,int base_reg2,long offset,BOOL bUseOffset, Schedule::Type scheduleType ){
1026 //fstp ptr[base_reg1+base_reg2+offset]
1027
1028 if(base_reg1==REG_ESP){
1029 //SIBバイトのindex部にespは指定できない
1030 base_reg1=base_reg2;
1031 base_reg2=REG_ESP;
1032 }
1033
1034 //オペコード
1035 if(type==DEF_DOUBLE) pNativeCode->Put( (char)0xDD );
1036 else if(type==DEF_SINGLE) pNativeCode->Put( (char)0xD9 );
1037 else SetError(300,NULL,cp);
1038
1039 int reg=0;
1040 if(bUseOffset){
1041 ///////////////////////////
1042 // オフセット値を使う
1043 ///////////////////////////
1044
1045 //レジスタ
1046 pNativeCode->Put( (char)(0x9C| REGISTER_OPERAND(reg)<<3) );
1047
1048 //ベースレジスタ
1049 pNativeCode->Put( (char)(REGISTER_OPERAND(base_reg1)<<3 | REGISTER_OPERAND(base_reg2)) );
1050
1051 //オフセット値
1052 pNativeCode->Put( offset, scheduleType );
1053 }
1054 else{
1055 ///////////////////////////
1056 // オフセット値を使わない
1057 ///////////////////////////
1058
1059 //レジスタ
1060 pNativeCode->Put( (char)(0x1C| REGISTER_OPERAND(reg)<<3) );
1061
1062 //ベースレジスタ
1063 pNativeCode->Put( (char)(REGISTER_OPERAND(base_reg1)<<3 | REGISTER_OPERAND(base_reg2)) );
1064 }
1065}
1066void CodeGenerator::op_fistp_ptr_esp( int typeSize ){
1067 if( typeSize == sizeof(_int64) ){
1068 //64bit
1069
1070 //fistp qword ptr[esp]
1071 fpu_cast();
1072 pNativeCode->Put( (char)0xDF );
1073 pNativeCode->Put( (char)0x3C );
1074 pNativeCode->Put( (char)0x24 );
1075 fpu_cast_end();
1076 }
1077 else if( typeSize == sizeof(long) ){
1078 //32bit
1079
1080 //fistp dword ptr[esp]
1081 fpu_cast();
1082 pNativeCode->Put( (char)0xDB );
1083 pNativeCode->Put( (char)0x1C );
1084 pNativeCode->Put( (char)0x24 );
1085 fpu_cast_end();
1086 }
1087 else{
1088 SetError();
1089 }
1090}
1091void CodeGenerator::op_fstp_push( Type &type ){
1092 //sub esp,size
1093 op_sub_esp( type.GetBasicSize() );
1094
1095 op_fstp_basereg( type.GetBasicType(), REG_ESP );
1096}
1097void CodeGenerator::op_fcompp(){
1098 // fcompp
1099 pNativeCode->Put( (char)0xDE );
1100 pNativeCode->Put( (char)0xD9 );
1101}
1102void CodeGenerator::op_fnstsw_ax()
1103{
1104 // fnstsw ax
1105 pNativeCode->Put( (char)0xDF );
1106 pNativeCode->Put( (char)0xE0 );
1107}
1108
1109
1110
1111//////////////////////////////
1112// レジスタ関連
1113//////////////////////////////
1114
1115void CodeGenerator::op_zero_reg(int reg){
1116 //レジスタに0をセット
1117
1118 op_xor_RR( reg );
1119}
1120
1121void CodeGenerator::fpu_cast(){
1122 ///////////////////////
1123 // FPUの切り捨て設定
1124 ///////////////////////
1125
1126 //sub esp,16
1127 op_sub_esp(16);
1128
1129 //mov dword ptr[esp+4],eax
1130 pNativeCode->Put( (char)0x89 );
1131 pNativeCode->Put( (char)0x44 );
1132 pNativeCode->Put( (char)0x24 );
1133 pNativeCode->Put( (char)0x04 );
1134
1135 //fnstcw word ptr[esp]
1136 pNativeCode->Put( (char)0xD9 );
1137 pNativeCode->Put( (char)0x3C );
1138 pNativeCode->Put( (char)0x24 );
1139
1140 //mov ax,word ptr[esp]
1141 pNativeCode->Put( (char)0x66 );
1142 pNativeCode->Put( (char)0x8B );
1143 pNativeCode->Put( (char)0x04 );
1144 pNativeCode->Put( (char)0x24 );
1145
1146 //or ah,0Ch
1147 pNativeCode->Put( (char)0x80 );
1148 pNativeCode->Put( (char)0xCC );
1149 pNativeCode->Put( (char)0x0C );
1150
1151 //mov word ptr[esp+2],ax
1152 pNativeCode->Put( (char)0x66 );
1153 pNativeCode->Put( (char)0x89 );
1154 pNativeCode->Put( (char)0x44 );
1155 pNativeCode->Put( (char)0x24 );
1156 pNativeCode->Put( (char)0x02 );
1157
1158 //fldcw word ptr[esp+2]
1159 pNativeCode->Put( (char)0xD9 );
1160 pNativeCode->Put( (char)0x6C );
1161 pNativeCode->Put( (char)0x24 );
1162 pNativeCode->Put( (char)0x02 );
1163
1164 //mov eax,dword ptr[esp+4]
1165 pNativeCode->Put( (char)0x8B );
1166 pNativeCode->Put( (char)0x44 );
1167 pNativeCode->Put( (char)0x24 );
1168 pNativeCode->Put( (char)0x04 );
1169
1170 //add esp,16
1171 op_add_esp(16);
1172}
1173void CodeGenerator::fpu_cast_end(){
1174 //sub esp,16
1175 op_sub_esp(16);
1176
1177 //fldcw word ptr[esp]
1178 pNativeCode->Put( (char)0xD9 );
1179 pNativeCode->Put( (char)0x2C );
1180 pNativeCode->Put( (char)0x24 );
1181
1182 //add esp,16
1183 op_add_esp(16);
1184}
1185
1186
1187/////////////////////////////
1188// 関数呼び出し
1189/////////////////////////////
1190
1191void CodeGenerator::op_call_R( int reg )
1192{
1193 // call reg
1194 pNativeCode->Put( (char)0xFF );
1195 pNativeCode->Put( (char)(0xD0|REGISTER_OPERAND(reg)) );
1196}
1197void CodeGenerator::op_call(const UserProc *pUserProc){
1198 pNativeCode->Put( (char)0xE8 );
1199 pNativeCode->PutUserProcSchedule( pUserProc, true );
1200}
1201void CodeGenerator::op_call( const DllProc *pDllProc )
1202{
1203 pNativeCode->Put( (char)0xFF );
1204 pNativeCode->Put( (char)0x15 );
1205 pNativeCode->PutDllProcSchedule( pDllProc );
1206}
1207void CodeGenerator::op_ret(){
1208 pNativeCode->Put( (char)0xC3 );
1209}
1210void CodeGenerator::op_ret( short stackFrameSize )
1211{
1212 pNativeCode->Put( (char)0xC2 );
1213 pNativeCode->Put( stackFrameSize );
1214}
1215void CodeGenerator::op_addressof( int reg, const UserProc *pUserProc )
1216{
1217 //mov reg,userProcAddress
1218
1219 //オペコード、レジスタ
1220 pNativeCode->Put( (char)(0xB8|REGISTER_OPERAND(reg)) );
1221
1222 //DISP32
1223 pNativeCode->PutUserProcSchedule( pUserProc, false );
1224}
Note: See TracBrowser for help on using the repository browser.