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

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

vtbl構築をコード生成後(最終リンクの前)に行うようにした

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