source: dev/trunk/abdev/BasicCompiler64/CodeGenerator.cpp@ 317

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