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

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