#include "stdafx.h" #include #include ////////////////////// // rexプリフィックス ////////////////////// void CodeGenerator::set_rex(int op_size,int reg,int index_reg,int base_reg){ char RexByte; if(reg==REG_NON&&index_reg==REG_NON){ ///////////////////////////////////// // レジスタをr/mのみに指定するとき ///////////////////////////////////// if((base_reg&0x08)==0){ if(op_size==sizeof(char)&&(base_reg&0x04)){ // r/m に spl,bpl,sil,dilを指定するとき RexByte=0x40; } else RexByte=0; } else RexByte=(char)0x41; } else{ ///////////////// // 通常 ///////////////// if((reg&0x08)==0){ //reg … rax〜rdi if((index_reg&0x08)==0){ if((base_reg&0x08)==0) RexByte=0; else RexByte=(char)0x41; } else{ if((base_reg&0x08)==0) RexByte=(char)0x42; else RexByte=(char)0x43; } } else{ //reg … r8〜r15 if((index_reg&0x08)==0){ if((base_reg&0x08)==0) RexByte=(char)0x44; else RexByte=(char)0x45; } else{ if((base_reg&0x08)==0) RexByte=(char)0x46; else RexByte=(char)0x47; } } } if(op_size==sizeof(_int64)){ //64ビットオペランド RexByte|=0x48; } if(RexByte) pNativeCode->Put( RexByte ); } ///////////////////////////////////////////////// // ModR/Mバイト、SIBバイト、ディスプレースメント ///////////////////////////////////////////////// //スケール #define SCALE_NON (char)0x00 #define SCALE_2 (char)0x40 #define SCALE_4 (char)0x80 #define SCALE_8 (char)0xC0 //インデックスなし #define INDEX_NON 0x04 const 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 ) { const PertialSchedule *pPertialSchedule = NULL; if(mod==MOD_DISP32){ //ModR/Mバイト pNativeCode->Put( (char)( REGISTER_OPERAND(reg)<<3 | REGISTER_OPERAND(0x04)) ); base_reg=0x05; index_reg=INDEX_NON; } else{ //ModR/Mバイト pNativeCode->Put( (char)(mod | REGISTER_OPERAND(reg)<<3 | REGISTER_OPERAND(base_reg)) ); } //レジスタモードの場合は、ここで終了 if(mod==MOD_REG) return pPertialSchedule; if(REGISTER_OPERAND(base_reg)==0x04||mod==MOD_DISP32){ ////////////////////// // SIBバイトを使う ////////////////////// pNativeCode->Put( (char)(scale| REGISTER_OPERAND(index_reg)<<3 | REGISTER_OPERAND(base_reg)) ); } //ディスプレースメントを必要としない場合は、ここで終了 if(mod==MOD_BASE) return pPertialSchedule; ////////////////////////// // ディスプレースメント ////////////////////////// if(mod==MOD_BASE_DISP8) { pNativeCode->Put( (char)disp ); } else { if( isPertialSchedule ) { pertialSchedules.push_back( new PertialSchedule( pNativeCode->GetSize(), sizeof(long) ) ); pPertialSchedule = pertialSchedules.back(); } this->PutWithSchedule( disp, scheduleType ); } return pPertialSchedule; } const 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 ){ //命令プリフィックス if(op_prefix) pNativeCode->Put( op_prefix ); //rexプリフィックス set_rex(op_size,reg,0,base_reg); //オペコード pNativeCode->Put( opcode1 ); if(opcode2) pNativeCode->Put( opcode2 ); //ModR/M, SIB, disp return set_mod_rm_sib_disp(mod,reg,SCALE_NON,INDEX_NON,base_reg,offset, scheduleType, isPertialSchedule ); } /////////////////// // mov関連 /////////////////// const PertialSchedule *CodeGenerator::op_mov_RV(int op_size,int reg,long i32data, Schedule::Type scheduleType, bool isPertialSchedule ){ //mov reg,i32data //rexプリフィックス set_rex(op_size,REG_NON,REG_NON,reg); if(op_size==sizeof(_int64)){ //オペコード pNativeCode->Put( (char)0xC7 ); //レジスタ pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg) ) ); } else{ //レジスタ pNativeCode->Put( (char)(0xB8| REGISTER_OPERAND(reg) ) ); } //即値 const PertialSchedule *pPertialSchedule = NULL; if( isPertialSchedule ) { pertialSchedules.push_back( new PertialSchedule( pNativeCode->GetSize(), sizeof(long) ) ); pPertialSchedule = pertialSchedules.back(); } this->PutWithSchedule( i32data, scheduleType ); return pPertialSchedule; } const PertialSchedule *CodeGenerator::op_mov_RV64( int reg, _int64 i64data, bool isPertialSchedule ) { //mov reg,i64data //rexプリフィックス set_rex(sizeof(_int64),REG_NON,REG_NON,reg); //レジスタ pNativeCode->Put( (char)(0xB8| REGISTER_OPERAND(reg) ) ); //即値 const PertialSchedule *pPertialSchedule = NULL; if( isPertialSchedule ) { pertialSchedules.push_back( new PertialSchedule( pNativeCode->GetSize(), sizeof(_int64) ) ); pPertialSchedule = pertialSchedules.back(); } pNativeCode->Put( i64data ); return pPertialSchedule; } const PertialSchedule *CodeGenerator::op_mov_RM(int op_size,int reg,int base_reg,long offset,char mod, Schedule::Type scheduleType, bool isPertialSchedule ){ //mov reg64,qword ptr[base_reg+offset] //mov reg32,dword ptr[base_reg+offset] //mov reg16,word ptr[base_reg+offset] //mov reg8,byte ptr[base_reg+offset] //16ビット演算の命令プリフィックス char op_prefix=0; if(op_size==sizeof(short)) op_prefix=(char)0x66; //オペコード char opcode; if(op_size==sizeof(char)) opcode=(char)0x8A; else opcode=(char)0x8B; return __op_format(op_size,op_prefix,opcode,0,reg,base_reg,offset,mod, scheduleType, isPertialSchedule ); } const 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 ){ //mov reg64,qword ptr[base_reg1+base_reg2+offset] //mov reg32,dword ptr[base_reg1+base_reg2+offset] //mov reg16,word ptr[base_reg1+base_reg2+offset] //mov reg8,byte ptr[base_reg1+base_reg2+offset] const PertialSchedule *pPertialSchedule = NULL; if(base_reg1==REG_RSP){ //SIBバイトのindex部にrspは指定できない base_reg1=base_reg2; base_reg2=REG_RSP; } //16ビット演算のプリフィックス if(op_size==sizeof(short)) pNativeCode->Put( (char)0x66 ); //rexプリフィックス set_rex(op_size,reg,base_reg1,base_reg2); //オペコード if(op_size==sizeof(char)) pNativeCode->Put( (char)0x8A ); else pNativeCode->Put( (char)0x8B ); if(bUseOffset){ /////////////////////////// // オフセット値を使う /////////////////////////// //レジスタ pNativeCode->Put( (char)(0x84| REGISTER_OPERAND(reg)<<3) ); //ベースレジスタ pNativeCode->Put( (char)(REGISTER_OPERAND(base_reg1)<<3 | REGISTER_OPERAND(base_reg2)) ); //オフセット値 if( isPertialSchedule ) { pertialSchedules.push_back( new PertialSchedule( pNativeCode->GetSize(), sizeof(long) ) ); pPertialSchedule = pertialSchedules.back(); } this->PutWithSchedule( offset, scheduleType ); } else{ /////////////////////////// // オフセット値を使わない /////////////////////////// //レジスタ pNativeCode->Put( (char)(0x04| REGISTER_OPERAND(reg)<<3) ); //ベースレジスタ pNativeCode->Put( (char)(REGISTER_OPERAND(base_reg1)<<3 | REGISTER_OPERAND(base_reg2)) ); } return pPertialSchedule; } const PertialSchedule *CodeGenerator::op_mov_MR(int op_size,int reg,int base_reg,long offset,char mod, Schedule::Type scheduleType, bool isPertialSchedule ){ //mov qword ptr[base_reg+offset],reg64 //mov dword ptr[base_reg+offset],reg32 //mov word ptr[base_reg+offset],reg16 //mov byte ptr[base_reg+offset],reg8 //16ビット演算の命令プリフィックス char op_prefix=0; if(op_size==sizeof(short)) op_prefix=(char)0x66; //オペコード char opcode; if(op_size==sizeof(char)) opcode=(char)0x88; else opcode=(char)0x89; return __op_format(op_size,op_prefix,opcode,0,reg,base_reg,offset,mod, scheduleType, isPertialSchedule ); } const 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 ){ //mov qword ptr[base_reg1+base_reg2+offset],reg64 //mov dword ptr[base_reg1+base_reg2+offset],reg32 //mov word ptr[base_reg1+base_reg2+offset],reg16 //mov byte ptr[base_reg1+base_reg2+offset],reg8 const PertialSchedule *pPertialSchedule = NULL; if(base_reg1==REG_RSP){ //SIBバイトのindex部にrspは指定できない base_reg1=base_reg2; base_reg2=REG_RSP; } //16ビット演算のプリフィックス if(op_size==sizeof(short)) pNativeCode->Put( (char)0x66 ); //rexプリフィックス set_rex(op_size,reg,base_reg1,base_reg2); //オペコード if(op_size==sizeof(char)) pNativeCode->Put( (char)0x88 ); else pNativeCode->Put( (char)0x89 ); if(bUseOffset==USE_OFFSET){ ////////////////////////// //オフセット値を使う ////////////////////////// //レジスタ pNativeCode->Put( (char)(0x84| REGISTER_OPERAND(reg)<<3) ); //ベースレジスタ pNativeCode->Put( (char)(REGISTER_OPERAND(base_reg1)<<3 | REGISTER_OPERAND(base_reg2)) ); //オフセット値 if( isPertialSchedule ) { pertialSchedules.push_back( new PertialSchedule( pNativeCode->GetSize(), sizeof(long) ) ); pPertialSchedule = pertialSchedules.back(); } this->PutWithSchedule( offset, scheduleType ); } else{ ////////////////////////// //オフセット値を使わない ////////////////////////// //レジスタ pNativeCode->Put( (char)(0x04| REGISTER_OPERAND(reg)<<3) ); //ベースレジスタ pNativeCode->Put( (char)(REGISTER_OPERAND(base_reg1)<<3 | REGISTER_OPERAND(base_reg2)) ); } return pPertialSchedule; } const PertialSchedule *CodeGenerator::op_mov_MV(int op_size,int base_reg,int offset, Schedule::Type offsetScheduleType, bool isPertialSchedule, BOOL bUseOffset,long i32data){ //mov ptr[base_reg+offset],i32data //mov ptr[base_reg ],i32data const PertialSchedule *pPertialSchedule = NULL; //16ビット演算のプリフィックス if(op_size==sizeof(short)) pNativeCode->Put( (char)0x66 ); //rexプリフィックス set_rex(op_size,0,0,base_reg); //オペコード if(op_size==sizeof(char)) pNativeCode->Put( (char)0xC6 ); else pNativeCode->Put( (char)0xC7 ); if(bUseOffset==USE_OFFSET){ ////////////////////////// //オフセット値を使う ////////////////////////// //ModR/M, SIB, disp pPertialSchedule = set_mod_rm_sib_disp(MOD_BASE_DISP32,0,SCALE_NON,INDEX_NON,base_reg,offset, offsetScheduleType, isPertialSchedule ); } else{ //ModR/M, SIB, disp set_mod_rm_sib_disp(MOD_BASE,0,SCALE_NON,INDEX_NON,base_reg,0); } //即値 if(op_size==sizeof(_int64)||op_size==sizeof(long)){ //32/64ビット pNativeCode->Put( i32data ); } else if(op_size==sizeof(short)){ //16ビット pNativeCode->Put( (short)i32data ); } else if(op_size==sizeof(char)){ //16ビット pNativeCode->Put( (char)i32data ); } return pPertialSchedule; } void CodeGenerator::op_mov_RR(int reg1,int reg2){ //mov reg1,reg2 char RexByte=-1; if(reg1==reg2) return; if(REG_RAX<=reg1&®1<=REG_RDI){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x48; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x49; } if(REG_R8<=reg1&®1<=REG_R15){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x4C; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x4D; } if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp); // [8bit rex] 1000 1011 11xx xbbb pNativeCode->Put( RexByte ); pNativeCode->Put( (char)0x8B ); pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg1)<<3 | REGISTER_OPERAND(reg2)) ); } void CodeGenerator::op_movsxd(int reg64,int reg32){ //movsxd reg64,reg32 char RexByte=-1; if(REG_RAX<=reg64&®64<=REG_RDI){ if(REG_RAX<=reg32&®32<=REG_RDI) RexByte=(char)0x48; if(REG_R8<=reg32&®32<=REG_R15) RexByte=(char)0x49; } if(REG_R8<=reg64&®64<=REG_R15){ if(REG_RAX<=reg32&®32<=REG_RDI) RexByte=(char)0x4C; if(REG_R8<=reg32&®32<=REG_R15) RexByte=(char)0x4D; } if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp); //[8bit rex] 0110 0011 11rr rbbb pNativeCode->Put( RexByte ); pNativeCode->Put( (char)0x63 ); pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg64)<<3 | REGISTER_OPERAND(reg32)) ); } void CodeGenerator::op_movsx64_FromReg16(int reg64,int reg16){ //movsx reg64,reg16 char RexByte=-1; if(REG_RAX<=reg64&®64<=REG_RDI){ if(REG_RAX<=reg16&®16<=REG_RDI) RexByte=(char)0x48; if(REG_R8<=reg16&®16<=REG_R15) RexByte=(char)0x49; } if(REG_R8<=reg64&®64<=REG_R15){ if(REG_RAX<=reg16&®16<=REG_RDI) RexByte=(char)0x4C; if(REG_R8<=reg16&®16<=REG_R15) RexByte=(char)0x4D; } if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp); //[8bit rex] 0000 1111 1011 1111 11rr rbbb pNativeCode->Put( RexByte ); pNativeCode->Put( (char)0x0F ); pNativeCode->Put( (char)0xBF ); pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg64)<<3 | REGISTER_OPERAND(reg16)) ); } void CodeGenerator::op_movsx64_FromReg8(int reg64,int reg8){ //movsx reg64,reg8 char RexByte=-1; if(REG_RAX<=reg64&®64<=REG_RDI){ if(REG_RAX<=reg8&®8<=REG_RDI) RexByte=(char)0x48; if(REG_R8<=reg8&®8<=REG_R15) RexByte=(char)0x49; } if(REG_R8<=reg64&®64<=REG_R15){ if(REG_RAX<=reg8&®8<=REG_RDI) RexByte=(char)0x4C; if(REG_R8<=reg8&®8<=REG_R15) RexByte=(char)0x4D; } if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp); //[8bit rex] 0000 1111 1011 1110 11rr rbbb pNativeCode->Put( RexByte ); pNativeCode->Put( (char)0x0F ); pNativeCode->Put( (char)0xBE ); pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg64)<<3 | REGISTER_OPERAND(reg8)) ); } ////////////////// // mov32関連 ////////////////// void CodeGenerator::op_movsx32_FromReg16(int reg32,int reg16){ //movsx reg32,reg16 char RexByte=-1; if(REG_RAX<=reg32&®32<=REG_RDI){ if(REG_RAX<=reg16&®16<=REG_RDI) RexByte=0; if(REG_R8<=reg16&®16<=REG_R15) RexByte=(char)0x41; } if(REG_R8<=reg32&®32<=REG_R15){ if(REG_RAX<=reg16&®16<=REG_RDI) RexByte=(char)0x44; if(REG_R8<=reg16&®16<=REG_R15) RexByte=(char)0x45; } if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp); //[8bit rex] 0000 1111 1011 1111 11rr rbbb if(RexByte) pNativeCode->Put( RexByte ); pNativeCode->Put( (char)0x0F ); pNativeCode->Put( (char)0xBF ); pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg32)<<3 | REGISTER_OPERAND(reg16)) ); } void CodeGenerator::op_movsx32_FromReg8(int reg32,int reg8){ //movsx reg32,reg8 char RexByte=-1; if(REG_RAX<=reg32&®32<=REG_RDI){ if(REG_RAX<=reg8&®8<=REG_RBX) RexByte=0; if(REG_RSP<=reg8&®8<=REG_RDI) RexByte=(char)0x40; if(REG_R8<=reg8&®8<=REG_R15) RexByte=(char)0x41; } if(REG_R8<=reg32&®32<=REG_R15){ if(REG_RAX<=reg8&®8<=REG_RDI) RexByte=(char)0x44; if(REG_R8<=reg8&®8<=REG_R15) RexByte=(char)0x45; } if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp); //[8bit rex] 0000 1111 1011 1110 11rr rbbb if(RexByte) pNativeCode->Put( RexByte ); pNativeCode->Put( (char)0x0F ); pNativeCode->Put( (char)0xBE ); pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg32)<<3 | REGISTER_OPERAND(reg8)) ); } ///////////////////// // mov16関連 ///////////////////// void CodeGenerator::op_movsx16_FromReg8(int reg32,int reg8){ //movsx reg16,reg8 char RexByte=-1; if(REG_RAX<=reg32&®32<=REG_RDI){ if(REG_RAX<=reg8&®8<=REG_RBX) RexByte=0; if(REG_RSP<=reg8&®8<=REG_RDI) RexByte=(char)0x40; if(REG_R8<=reg8&®8<=REG_R15) RexByte=(char)0x41; } if(REG_R8<=reg32&®32<=REG_R15){ if(REG_RAX<=reg8&®8<=REG_RDI) RexByte=(char)0x44; if(REG_R8<=reg8&®8<=REG_R15) RexByte=(char)0x45; } if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp); //0110 0110 [8bit rex] 0000 1111 1011 1110 11rr rbbb pNativeCode->Put( (char)0x66 ); if(RexByte) pNativeCode->Put( RexByte ); pNativeCode->Put( (char)0x0F ); pNativeCode->Put( (char)0xBE ); pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg32)<<3 | REGISTER_OPERAND(reg8)) ); } ////////////////////////////////// // ビット拡張 ////////////////////////////////// void CodeGenerator::op_cqo() { pNativeCode->Put( (char)0x48 ); pNativeCode->Put( (char)0x99 ); } ////////////////////////////////// // インクリメント・デクリメント ////////////////////////////////// void CodeGenerator::op_inc(int reg){ //inc reg //16ビット演算の命令プリフィックス char op_prefix=0; //オペコード char opcode=(char)0xFF; __op_format(sizeof(_int64),op_prefix,opcode,0,0,reg,0,MOD_REG); } void CodeGenerator::op_dec(int reg){ //dec reg //16ビット演算の命令プリフィックス char op_prefix=0; //オペコード char opcode=(char)0xFF; __op_format(sizeof(_int64),op_prefix,opcode,0,0x01,reg,0,MOD_REG); } ///////////////////// // add関連 ///////////////////// const PertialSchedule *CodeGenerator::op_add_RM(int op_size,int reg,int base_reg,int offset,char mod, Schedule::Type scheduleType, bool isPertialSchedule ){ //add reg64,qword ptr[base_reg+offset] //add reg32,dword ptr[base_reg+offset] //add reg16,word ptr[base_reg+offset] //add reg8,byte ptr[base_reg+offset] //16ビット演算の命令プリフィックス char op_prefix=0; if(op_size==sizeof(short)) op_prefix=(char)0x66; //オペコード char opcode; if(op_size==sizeof(char)) opcode=(char)0x02; else opcode=(char)0x03; return __op_format(op_size,op_prefix,opcode,0,reg,base_reg,offset,mod, scheduleType, isPertialSchedule ); } const PertialSchedule *CodeGenerator::op_add_RV(int reg,long offset, Schedule::Type scheduleType, bool isPertialSchedule ){ //add reg,offset const PertialSchedule *pPertialSchedule = NULL; char RexByte=-1; if(REG_RAX<=reg&®<=REG_RDI) RexByte=0x48; if(REG_R8<=reg&®<=REG_R15) RexByte=0x49; if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp); if(reg==REG_RAX){ //raxのみ特殊 // [8bit rex] 0000 0101 [32bit offset] pNativeCode->Put( (char)RexByte ); pNativeCode->Put( (char)0x05 ); } else{ //rax以外 //[8bit rex] 1000 0001 1100 0xxx [32bit offset] pNativeCode->Put( (char)RexByte ); pNativeCode->Put( (char)0x81 ); pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg)) ); } if( isPertialSchedule ) { pertialSchedules.push_back( new PertialSchedule( pNativeCode->GetSize(), sizeof(long) ) ); pPertialSchedule = pertialSchedules.back(); } this->PutWithSchedule( offset, scheduleType ); return pPertialSchedule; } void CodeGenerator::op_add_RR(int reg1,int reg2){ //add reg1,reg2 char RexByte=-1; if(REG_RAX<=reg1&®1<=REG_RDI){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x48; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x49; } if(REG_R8<=reg1&®1<=REG_R15){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x4C; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x4D; } if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp); //[8bit rex] 0000 0011 11rr rbbb pNativeCode->Put( (char)RexByte ); pNativeCode->Put( (char)0x03 ); pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg1)<<3 | REGISTER_OPERAND(reg2)) ); } void CodeGenerator::op_add32_reg(int reg1,int reg2){ //add reg1,reg2 char RexByte=-1; if(REG_RAX<=reg1&®1<=REG_RDI){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=0; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x41; } if(REG_R8<=reg1&®1<=REG_R15){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x44; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x45; } if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp); //[8bit rex] 0000 0011 11rr rbbb if(RexByte) pNativeCode->Put( (char)RexByte ); pNativeCode->Put( (char)0x03 ); pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg1)<<3 | REGISTER_OPERAND(reg2)) ); } //////////////////////// // sub関連 //////////////////////// void CodeGenerator::op_sub_RV(int op_size,int reg,long i32data){ //sub reg,i32data //rexプリフィックス set_rex(op_size,REG_NON,REG_NON,reg); if(reg==REG_RAX){ //raxのみ特殊 pNativeCode->Put( (char)0x2D ); } else{ //オペコード pNativeCode->Put( (char)0x81 ); //レジスタ pNativeCode->Put( (char)(0xE8| REGISTER_OPERAND(reg) ) ); } //即値 pNativeCode->Put( i32data ); } void CodeGenerator::op_sub64_reg(int reg1,int reg2){ //sub reg1,reg2 char RexByte=-1; if(REG_RAX<=reg1&®1<=REG_RDI){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x48; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x49; } if(REG_R8<=reg1&®1<=REG_R15){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x4C; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x4D; } if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp); //[8bit rex] 0010 1011 11rr rbbb pNativeCode->Put( (char)RexByte ); pNativeCode->Put( (char)0x2B ); pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg1)<<3 | REGISTER_OPERAND(reg2)) ); } void CodeGenerator::op_sub32_reg(int reg1,int reg2){ //sub reg1,reg2 char RexByte=-1; if(REG_RAX<=reg1&®1<=REG_RDI){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=0; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x41; } if(REG_R8<=reg1&®1<=REG_R15){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x44; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x45; } if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp); //[8bit rex] 0010 1011 11rr rbbb if(RexByte) pNativeCode->Put( (char)RexByte ); pNativeCode->Put( (char)0x2B ); pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg1)<<3 | REGISTER_OPERAND(reg2)) ); } void CodeGenerator::op_sbb_RR( int op_size, int reg1, int reg2 ){ //sbb reg1,reg2 //rexプリフィックス set_rex(0,reg1,0,reg2); //オペコード pNativeCode->Put( (char)0x1B ); //レジスタ pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg1)<<3 | REGISTER_OPERAND(reg2)) ); } //////////////////////// // imul関連 //////////////////////// void CodeGenerator::op_imul_RR(int op_size,int reg1,int reg2){ //imul reg1,reg2 char RexByte=-1; if(op_size==sizeof(_int64)){ if(REG_RAX<=reg1&®1<=REG_RDI){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x48; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x49; } if(REG_R8<=reg1&®1<=REG_R15){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x4C; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x4D; } } else{ if(REG_RAX<=reg1&®1<=REG_RDI){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=0; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x41; } if(REG_R8<=reg1&®1<=REG_R15){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x44; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x45; } } if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp); //rexプリフィックス if(RexByte) pNativeCode->Put( (char)RexByte ); //オペコード pNativeCode->Put( (char)0x0F ); pNativeCode->Put( (char)0xAF ); //レジスタ pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg1)<<3 | REGISTER_OPERAND(reg2)) ); } void CodeGenerator::op_imul_RV(int op_size,int reg,long i32data){ //imul reg,i32data char RexByte=-1; if(op_size==sizeof(_int64)){ if(REG_RAX<=reg&®<=REG_RDI) RexByte=(char)0x48; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x4D; } else{ if(REG_RAX<=reg&®<=REG_RDI) RexByte=0; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x45; } if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp); //rexプリフィックス if(RexByte) pNativeCode->Put( (char)RexByte ); if(-128<=i32data&&i32data<=127){ //オペコード pNativeCode->Put( (char)0x6B ); //レジスタ pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg)<<3 | REGISTER_OPERAND(reg)) ); //値 pNativeCode->Put( (char)i32data ); } else{ //オペコード pNativeCode->Put( (char)0x69 ); //レジスタ pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg)<<3 | REGISTER_OPERAND(reg)) ); //値 pNativeCode->Put( i32data ); } } //////////////////////// // div、idiv関連 //////////////////////// void CodeGenerator::op_div64_reg(int reg){ //div reg char RexByte=-1; if(REG_RAX<=reg&®<=REG_RDI) RexByte=(char)0x48; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x49; if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp); //rexプリフィックス pNativeCode->Put( (char)RexByte ); //オペコード pNativeCode->Put( (char)0xF7 ); //レジスタ pNativeCode->Put( (char)(0xF0| REGISTER_OPERAND(reg)) ); } void CodeGenerator::op_idiv64_reg(int reg){ //idiv reg char RexByte=-1; if(REG_RAX<=reg&®<=REG_RDI) RexByte=(char)0x48; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x49; if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp); //rexプリフィックス pNativeCode->Put( (char)RexByte ); //オペコード pNativeCode->Put( (char)0xF7 ); //レジスタ pNativeCode->Put( (char)(0xF8| REGISTER_OPERAND(reg)) ); } //////////////////// // ビットシフト関連 //////////////////// void CodeGenerator::op_shl_reg(int op_size,int reg){ //shl reg,cl char RexByte=-1; if(op_size==sizeof(_int64)){ if(REG_RAX<=reg&®<=REG_RDI) RexByte=(char)0x48; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x49; } else if(op_size==sizeof(char)){ if(REG_RAX<=reg&®<=REG_RBX) RexByte=0; if(REG_RSP<=reg&®<=REG_RDI) RexByte=(char)0x40; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x41; } else{ if(REG_RAX<=reg&®<=REG_RDI) RexByte=0; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x41; } if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp); //16ビット演算のプリフィックス if(op_size==sizeof(short)) pNativeCode->Put( (char)0x66 ); //rexプリフィックス if(RexByte) pNativeCode->Put( (char)RexByte ); //オペコード if(op_size==sizeof(char)) pNativeCode->Put( (char)0xD2 ); else pNativeCode->Put( (char)0xD3 ); //レジスタ pNativeCode->Put( (char)(0xE0| REGISTER_OPERAND(reg)) ); } void CodeGenerator::op_sar_reg(int op_size,int reg){ //sar reg,cl char RexByte=-1; if(op_size==sizeof(_int64)){ if(REG_RAX<=reg&®<=REG_RDI) RexByte=(char)0x48; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x49; } else if(op_size==sizeof(char)){ if(REG_RAX<=reg&®<=REG_RBX) RexByte=0; if(REG_RSP<=reg&®<=REG_RDI) RexByte=(char)0x40; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x41; } else{ if(REG_RAX<=reg&®<=REG_RDI) RexByte=0; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x41; } if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp); //16ビット演算のプリフィックス if(op_size==sizeof(short)) pNativeCode->Put( (char)0x66 ); //rexプリフィックス if(RexByte) pNativeCode->Put( (char)RexByte ); //オペコード if(op_size==sizeof(char)) pNativeCode->Put( (char)0xD2 ); else pNativeCode->Put( (char)0xD3 ); //レジスタ pNativeCode->Put( (char)(0xF8| REGISTER_OPERAND(reg)) ); } void CodeGenerator::op_shr_reg(int op_size,int reg){ //shr reg,cl char RexByte=-1; if(op_size==sizeof(_int64)){ if(REG_RAX<=reg&®<=REG_RDI) RexByte=(char)0x48; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x49; } else if(op_size==sizeof(char)){ if(REG_RAX<=reg&®<=REG_RBX) RexByte=0; if(REG_RSP<=reg&®<=REG_RDI) RexByte=(char)0x40; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x41; } else{ if(REG_RAX<=reg&®<=REG_RDI) RexByte=0; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x41; } if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp); //16ビット演算のプリフィックス if(op_size==sizeof(short)) pNativeCode->Put( (char)0x66 ); //rexプリフィックス if(RexByte) pNativeCode->Put( (char)RexByte ); //オペコード if(op_size==sizeof(char)) pNativeCode->Put( (char)0xD2 ); else pNativeCode->Put( (char)0xD3 ); //レジスタ pNativeCode->Put( (char)(0xE8| REGISTER_OPERAND(reg)) ); } //////////////////// // and 関連 //////////////////// void CodeGenerator::op_and_reg(int op_size,int reg1,int reg2){ //and reg1,reg2 char RexByte=-1; if(op_size==sizeof(_int64)){ if(REG_RAX<=reg1&®1<=REG_RDI){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x48; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x49; } if(REG_R8<=reg1&®1<=REG_R15){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x4C; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x4D; } } else{ if(REG_RAX<=reg1&®1<=REG_RDI){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=0; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x41; } if(REG_R8<=reg1&®1<=REG_R15){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x44; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x45; } } if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp); //rexプリフィックス if(RexByte) pNativeCode->Put( (char)RexByte ); //オペコード pNativeCode->Put( (char)0x23 ); //レジスタ pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg1)<<3 | REGISTER_OPERAND(reg2)) ); } void CodeGenerator::op_and64_value(int reg,long offset){ //and reg,offset char RexByte=-1; if(REG_RAX<=reg&®<=REG_RDI) (char)RexByte=0x48; if(REG_R8<=reg&®<=REG_R15) (char)RexByte=0x49; if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp); if(reg==REG_RAX){ //raxのみ特殊 // [8bit rex] 0010 0101 [32bit offset] pNativeCode->Put( (char)RexByte ); pNativeCode->Put( (char)0x25 ); pNativeCode->Put( offset ); } else{ //rax以外 //[8bit rex] 1000 0001 1100 0xxx [32bit offset] pNativeCode->Put( (char)RexByte ); pNativeCode->Put( (char)0x81 ); pNativeCode->Put( (char)(0xE0| REGISTER_OPERAND(reg)) ); pNativeCode->Put( offset ); } } void CodeGenerator::op_and32_value(int reg,long offset){ //and reg,offset char RexByte=-1; if(REG_RAX<=reg&®<=REG_RDI) RexByte=0; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x41; if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp); if(reg==REG_RAX){ //eaxのみ特殊 // [8bit rex] 0010 0101 [32bit offset] pNativeCode->Put( (char)0x25 ); pNativeCode->Put( offset ); } else{ //eax以外 //[8bit rex] 1000 0001 1100 0xxx [32bit offset] if(RexByte) pNativeCode->Put( (char)RexByte ); pNativeCode->Put( (char)0x81 ); pNativeCode->Put( (char)(0xE0| REGISTER_OPERAND(reg)) ); pNativeCode->Put( offset ); } } //////////////////////// // or 関連 //////////////////////// void CodeGenerator::op_or_reg(int op_size,int reg1,int reg2){ //or reg1,reg2 char RexByte=-1; if(op_size==sizeof(_int64)){ if(REG_RAX<=reg1&®1<=REG_RDI){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x48; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x49; } if(REG_R8<=reg1&®1<=REG_R15){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x4C; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x4D; } } else{ if(REG_RAX<=reg1&®1<=REG_RDI){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=0; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x41; } if(REG_R8<=reg1&®1<=REG_R15){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x44; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x45; } } if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp); //rexプリフィックス if(RexByte) pNativeCode->Put( (char)RexByte ); //オペコード pNativeCode->Put( (char)0x0B ); //レジスタ pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg1)<<3 | REGISTER_OPERAND(reg2)) ); } //////////////////////// // xor 関連 //////////////////////// void CodeGenerator::op_xor_reg(int op_size,int reg1,int reg2){ //xor reg1,reg2 char RexByte=-1; if(op_size==sizeof(_int64)){ if(REG_RAX<=reg1&®1<=REG_RDI){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x48; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x49; } if(REG_R8<=reg1&®1<=REG_R15){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x4C; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x4D; } } else{ if(REG_RAX<=reg1&®1<=REG_RDI){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=0; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x41; } if(REG_R8<=reg1&®1<=REG_R15){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x44; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x45; } } if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp); //rexプリフィックス if(RexByte) pNativeCode->Put( (char)RexByte ); //オペコード pNativeCode->Put( (char)0x33 ); //レジスタ pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg1)<<3 | REGISTER_OPERAND(reg2)) ); } /////////////////////// // not 関連 /////////////////////// void CodeGenerator::op_not_reg(int op_size,int reg){ //not reg char RexByte=-1; if(op_size==sizeof(_int64)){ if(REG_RAX<=reg&®<=REG_RDI) RexByte=(char)0x48; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x49; } else{ if(REG_RAX<=reg&®<=REG_RDI) RexByte=0; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x41; } if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp); //rexプリフィックス if(RexByte) pNativeCode->Put( (char)RexByte ); //オペコード pNativeCode->Put( (char)0xF7 ); //レジスタ pNativeCode->Put( (char)(0xD0| REGISTER_OPERAND(reg)) ); } void CodeGenerator::op_neg( int reg ){ //neg reg //オペコード pNativeCode->Put( (char)0xF7 ); //レジスタ pNativeCode->Put( (char)(0xD8| REGISTER_OPERAND(reg)) ); } //////////////////// // test関連 //////////////////// void CodeGenerator::op_test(int reg1,int reg2){ //test reg1,reg2 char RexByte=-1; if(REG_RAX<=reg1&®1<=REG_RDI){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x48; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x49; } if(REG_R8<=reg1&®1<=REG_R15){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x4C; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x4D; } if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp); //[8bit rex] 1000 0101 11rr rbbb pNativeCode->Put( (char)RexByte ); pNativeCode->Put( (char)0x85 ); pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg1)<<3 | REGISTER_OPERAND(reg2)) ); } ///////////////////// // cmp 関連 ///////////////////// void CodeGenerator::op_cmp_reg(int op_size,int reg1,int reg2){ //cmp reg1,reg2 char RexByte=-1; if(op_size==sizeof(_int64)){ if(REG_RAX<=reg1&®1<=REG_RDI){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x48; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x49; } if(REG_R8<=reg1&®1<=REG_R15){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x4C; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x4D; } } else{ if(REG_RAX<=reg1&®1<=REG_RDI){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=0; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x41; } if(REG_R8<=reg1&®1<=REG_R15){ if(REG_RAX<=reg2&®2<=REG_RDI) RexByte=(char)0x44; if(REG_R8<=reg2&®2<=REG_R15) RexByte=(char)0x45; } } if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp); //rexプリフィックス if(RexByte) pNativeCode->Put( (char)RexByte ); //オペコード pNativeCode->Put( (char)0x3B ); //レジスタ pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg1)<<3 | REGISTER_OPERAND(reg2)) ); } void CodeGenerator::op_cmp_value(int op_size,int reg,char byte_data){ //cmp reg,byte_data if(op_size==sizeof(char)&®==REG_RAX){ //alレジスタの場合は特殊 pNativeCode->Put( (char)0x3C ); //8ビット値 pNativeCode->Put( byte_data ); return; } //16ビット演算のプリフィックス if(op_size==sizeof(short)) pNativeCode->Put( (char)0x66 ); //rexプリフィックス set_rex(op_size,REG_NON,REG_NON,reg); //オペコード if(op_size==sizeof(char)) pNativeCode->Put( (char)0x80 ); else pNativeCode->Put( (char)0x83 ); //レジスタ pNativeCode->Put( (char)(0xF8| REGISTER_OPERAND(reg)) ); //8ビット値 pNativeCode->Put( byte_data ); } void CodeGenerator::op_setne( int reg ){ //オペコード pNativeCode->Put( (char)0x0F ); pNativeCode->Put( (char)0x95 ); //レジスタ pNativeCode->Put( (char)( 0xC0 | REGISTER_OPERAND(reg) ) ); } //////////////////// // SSE2関連 //////////////////// const PertialSchedule *CodeGenerator::op_movlpd_MR(int xmm_reg,int base_reg,int offset,char mod, Schedule::Type scheduleType, bool isPertialSchedule ){ //movlpd qword ptr[base_reg+offset],xmm_reg return __op_format(0,(char)0x66,(char)0x0F,(char)0x13,xmm_reg,base_reg,offset,mod, scheduleType, isPertialSchedule ); } const PertialSchedule *CodeGenerator::op_movlpd_RM(int xmm_reg,int base_reg,int offset,char mod, Schedule::Type scheduleType, bool isPertialSchedule ){ //movlpd xmm_reg,qword ptr[base_reg+offset] return __op_format(0,(char)0x66,(char)0x0F,(char)0x12,xmm_reg,base_reg,offset,mod, scheduleType, isPertialSchedule ); } void CodeGenerator::op_movsd_RR(int xmm_reg1,int xmm_reg2){ if(xmm_reg1==xmm_reg2) return; //movsd xmm_reg1,xmm_reg2 __op_format(0,(char)0xF2,(char)0x0F,(char)0x10,xmm_reg1,xmm_reg2,0,MOD_REG); } const PertialSchedule *CodeGenerator::op_movsd_MR(int xmm_reg,int base_reg,int offset,char mod, Schedule::Type scheduleType, bool isPertialSchedule ){ //movsd qword ptr[reg+offset],xmm_reg //movsd qword ptr[reg],xmm_reg return __op_format(0,(char)0xF2,(char)0x0F,(char)0x11,xmm_reg,base_reg,offset,mod, scheduleType, isPertialSchedule ); } void CodeGenerator::op_movss_RR(int xmm_reg1,int xmm_reg2){ if(xmm_reg1==xmm_reg2) return; //movss xmm_reg1,xmm_reg2 __op_format(0,(char)0xF3,(char)0x0F,(char)0x10,xmm_reg1,xmm_reg2,0,MOD_REG); } const PertialSchedule *CodeGenerator::op_movss_RM(int xmm_reg,int base_reg,int offset,char mod, Schedule::Type scheduleType, bool isPertialSchedule ){ //movss xmm_reg,dword ptr[base_reg+offset] return __op_format(0,(char)0xF3,(char)0x0F,(char)0x10,xmm_reg,base_reg,offset,mod, scheduleType, isPertialSchedule ); } const PertialSchedule *CodeGenerator::op_movss_MR(int xmm_reg,int base_reg,int offset,char mod, Schedule::Type scheduleType, bool isPertialSchedule ){ //movss dword ptr[reg+offset],xmm_reg //movss dword ptr[reg],xmm_reg return __op_format(0,(char)0xF3,(char)0x0F,(char)0x11,xmm_reg,base_reg,offset,mod, scheduleType, isPertialSchedule ); } void CodeGenerator::op_movd_RX(int reg,int xmm_reg){ __op_format(sizeof(_int64),(char)0x66,(char)0x0F,(char)0x7E,xmm_reg,reg,0,MOD_REG); } void CodeGenerator::op_cvtsd2ss(int xmm_reg1,int xmm_reg2){ //cvtsd2ss xmm_reg1,xmm_reg2 //オペコード pNativeCode->Put( (char)0xF2 ); //rexプリフィックス set_rex(sizeof(long),xmm_reg1,0,xmm_reg2); //オペコード pNativeCode->Put( (char)0x0F ); pNativeCode->Put( (char)0x5A ); //レジスタ pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(xmm_reg1)<<3 | REGISTER_OPERAND(xmm_reg2)) ); } void CodeGenerator::op_cvtss2sd(int xmm_reg1,int xmm_reg2){ //cvtss2sd xmm_reg1,xmm_reg2 //オペコード pNativeCode->Put( (char)0xF3 ); //rexプリフィックス set_rex(0,xmm_reg1,0,xmm_reg2); //オペコード pNativeCode->Put( (char)0x0F ); pNativeCode->Put( (char)0x5A ); //レジスタ pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(xmm_reg1)<<3 | REGISTER_OPERAND(xmm_reg2)) ); } void CodeGenerator::op_cvttsd2si_xmm(int op_size,int reg,int xmm_reg){ //cvttsd2si reg,xmm_reg //オペコード pNativeCode->Put( (char)0xF2 ); //rexプリフィックス set_rex(op_size,reg,0,xmm_reg); //オペコード pNativeCode->Put( (char)0x0F ); pNativeCode->Put( (char)0x2C ); //レジスタ pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg)<<3 | REGISTER_OPERAND(xmm_reg)) ); } void CodeGenerator::op_cvttss2si_xmm(int op_size,int reg,int xmm_reg){ //cvttss2si reg,xmm_reg //オペコード pNativeCode->Put( (char)0xF3 ); //rexプリフィックス set_rex(op_size,reg,0,xmm_reg); //オペコード pNativeCode->Put( (char)0x0F ); pNativeCode->Put( (char)0x2C ); //レジスタ pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg)<<3 | REGISTER_OPERAND(xmm_reg)) ); } void CodeGenerator::op_cvtsi2sd_reg(int op_size,int xmm_reg,int reg){ //cvtsi2sd xmm_reg,reg char RexByte=-1; if(op_size==sizeof(_int64)){ if(REG_XMM0<=xmm_reg&&xmm_reg<=REG_XMM7){ if(REG_RAX<=reg&®<=REG_RDI) RexByte=(char)0x48; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x49; } if(REG_XMM8<=xmm_reg&&xmm_reg<=REG_XMM15){ if(REG_RAX<=reg&®<=REG_RDI) RexByte=(char)0x4C; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x4D; } } else{ if(REG_XMM0<=xmm_reg&&xmm_reg<=REG_XMM7){ if(REG_RAX<=reg&®<=REG_RDI) RexByte=0; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x41; } if(REG_XMM8<=xmm_reg&&xmm_reg<=REG_XMM15){ if(REG_RAX<=reg&®<=REG_RDI) RexByte=(char)0x44; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x45; } } if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp); //オペコード pNativeCode->Put( (char)0xF2 ); //rexプリフィックス if(RexByte) pNativeCode->Put( (char)RexByte ); //オペコード pNativeCode->Put( (char)0x0F ); pNativeCode->Put( (char)0x2A ); //レジスタ pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(xmm_reg)<<3 | REGISTER_OPERAND(reg)) ); } void CodeGenerator::op_cvtsi2ss_reg(int op_size,int xmm_reg,int reg){ //cvtsi2ss xmm_reg,reg char RexByte=-1; if(op_size==sizeof(_int64)){ if(REG_XMM0<=xmm_reg&&xmm_reg<=REG_XMM7){ if(REG_RAX<=reg&®<=REG_RDI) RexByte=(char)0x48; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x49; } if(REG_XMM8<=xmm_reg&&xmm_reg<=REG_XMM15){ if(REG_RAX<=reg&®<=REG_RDI) RexByte=(char)0x4C; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x4D; } } else{ if(REG_XMM0<=xmm_reg&&xmm_reg<=REG_XMM7){ if(REG_RAX<=reg&®<=REG_RDI) RexByte=0; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x41; } if(REG_XMM8<=xmm_reg&&xmm_reg<=REG_XMM15){ if(REG_RAX<=reg&®<=REG_RDI) RexByte=(char)0x44; if(REG_R8<=reg&®<=REG_R15) RexByte=(char)0x45; } } if(RexByte==-1) compiler.errorMessenger.Output(300,NULL,cp); //オペコード pNativeCode->Put( (char)0xF3 ); //rexプリフィックス if(RexByte) pNativeCode->Put( (char)RexByte ); //オペコード pNativeCode->Put( (char)0x0F ); pNativeCode->Put( (char)0x2A ); //レジスタ pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(xmm_reg)<<3 | REGISTER_OPERAND(reg)) ); } void CodeGenerator::op_comisd(int xmm_reg1,int xmm_reg2){ //comisd xmm_reg1,xmm_reg2 //オペコード pNativeCode->Put( (char)0x66 ); pNativeCode->Put( (char)0x0F ); pNativeCode->Put( (char)0x2F ); //レジスタ pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(xmm_reg1)<<3 | REGISTER_OPERAND(xmm_reg2)) ); } void CodeGenerator::op_comiss(int xmm_reg1,int xmm_reg2){ //comiss xmm_reg1,xmm_reg2 //オペコード pNativeCode->Put( (char)0x0F ); pNativeCode->Put( (char)0x2F ); //レジスタ pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(xmm_reg1)<<3 | REGISTER_OPERAND(xmm_reg2)) ); } ///////////////////// // ストリング関係 ///////////////////// void CodeGenerator::op_rep_movs(int op_size){ if(op_size==sizeof(BYTE)){ //rep movs byte ptr[edi],byte ptr[esi] pNativeCode->Put( (char)0xF3 ); pNativeCode->Put( (char)0xA4 ); } else if(op_size==sizeof(short)){ //rep movs word ptr[edi],word ptr[esi] pNativeCode->Put( (char)0xF3 ); pNativeCode->Put( (char)0x66 ); pNativeCode->Put( (char)0xA5 ); } else if(op_size==sizeof(long)){ //rep movs dword ptr[edi],dword ptr[esi] pNativeCode->Put( (char)0xF3 ); pNativeCode->Put( (char)0xA5 ); } } void CodeGenerator::op_add_rsp(long num){ //スタックポインタの加算(pop方向) //add rsp,num if(0xFFFFFF80&num){ pNativeCode->Put( (char)0x48 ); pNativeCode->Put( (char)0x81 ); pNativeCode->Put( (char)0xC4 ); pNativeCode->Put( num ); } else{ //「-128 < num < 127」の場合 pNativeCode->Put( (char)0x48 ); pNativeCode->Put( (char)0x83 ); pNativeCode->Put( (char)0xC4 ); pNativeCode->Put( (char)num ); } } const PertialSchedule *CodeGenerator::op_sub_rsp( long num, bool isPertialSchedule ) { //スタックポインタの減算(push方向) const PertialSchedule *pPertialSchedule = NULL; //sub rsp,num if( (0xFFFFFF80&num) != 0 || isPertialSchedule ){ pNativeCode->Put( (char)0x48 ); pNativeCode->Put( (char)0x81 ); pNativeCode->Put( (char)0xEC ); if( isPertialSchedule ) { pertialSchedules.push_back( new PertialSchedule( pNativeCode->GetSize(), sizeof(long) ) ); pPertialSchedule = pertialSchedules.back(); } pNativeCode->Put( num ); } else{ //「-128 < num < 127」の場合 pNativeCode->Put( (char)0x48 ); pNativeCode->Put( (char)0x83 ); pNativeCode->Put( (char)0xEC ); pNativeCode->Put( (char)num ); } return pPertialSchedule; } ////////////////////////////// // 浮動小数点関連 ////////////////////////////// void CodeGenerator::op_fld_ptr_esp(int type){ //スタックポインタが示すバッファのデータを浮動小数点レジスタへロード if(type==DEF_DOUBLE){ //fld qword ptr[esp] pNativeCode->Put( (char)0xDD ); pNativeCode->Put( (char)0x04 ); pNativeCode->Put( (char)0x24 ); } else if(type==DEF_SINGLE){ //fld dword ptr[esp] pNativeCode->Put( (char)0xD9 ); pNativeCode->Put( (char)0x04 ); pNativeCode->Put( (char)0x24 ); } else if(type==DEF_INT64){ //fild qword ptr[esp] pNativeCode->Put( (char)0xDF ); pNativeCode->Put( (char)0x2C ); pNativeCode->Put( (char)0x24 ); } else if(type==DEF_LONG){ //fild dword ptr[esp] pNativeCode->Put( (char)0xDB ); pNativeCode->Put( (char)0x04 ); pNativeCode->Put( (char)0x24 ); } } ////////////////////////////// // レジスタ関連 ////////////////////////////// void CodeGenerator::op_zero_reg(int reg){ //レジスタに0をセット if(REG_RAX<=reg&®<=REG_RDI){ /* rax〜rdi 0100 1000 0011 0011 11 xxx xxx */ pNativeCode->Put( (char)0x48 ); pNativeCode->Put( (char)0x33 ); pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg)<<3 | REGISTER_OPERAND(reg)) ); } if(REG_R8<=reg&®<=REG_R15){ /* r8〜r15 0100 1101 0011 0011 11 xxx xxx */ pNativeCode->Put( (char)0x4D ); pNativeCode->Put( (char)0x33 ); pNativeCode->Put( (char)(0xC0| REGISTER_OPERAND(reg)<<3 | REGISTER_OPERAND(reg)) ); } } ///////////////////////////// // 関数呼び出し ///////////////////////////// void CodeGenerator::op_call( const UserProc *pUserProc ){ pNativeCode->Put( (char)0xE8 ); pNativeCode->PutUserProcSchedule( pUserProc, true ); } void CodeGenerator::op_call( const DllProc *pDllProc ){ pNativeCode->Put( (char)0xFF ); pNativeCode->Put( (char)0x15 ); pNativeCode->PutDllProcSchedule( pDllProc ); } void CodeGenerator::op_ret(){ pNativeCode->Put( (char)0xC3 ); } void CodeGenerator::op_addressof( int reg, const UserProc *pUserProc ) { //mov reg,userProcAddress //オペコード、レジスタ pNativeCode->Put( (char)(0xB8|REGISTER_OPERAND(reg)) ); //DISP32 pNativeCode->PutUserProcSchedule( pUserProc, false ); } void CodeGenerator::op_mov_RV_com_vtbl( int reg, const CClass *pClass ) { // mov reg,com_vtblAddress //オペコード、レジスタ pNativeCode->Put( (char)(0xB8|REGISTER_OPERAND(reg)) ); //DISP32 pNativeCode->PutComVtblSchedule( pClass ); } void CodeGenerator::op_mov_RV_vtbl( int reg, const CClass *pClass ) { // mov reg,vtblAddress //オペコード、レジスタ pNativeCode->Put( (char)(0xB8|REGISTER_OPERAND(reg)) ); //DISP32 pNativeCode->PutVtblSchedule( pClass ); }