#include "stdafx.h"


//////////////////////
// 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&&reg1<=REG_RDI){
		if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x48;
		if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x49;
	}
	if(REG_R8<=reg1&&reg1<=REG_R15){
		if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x4C;
		if(REG_R8<=reg2&&reg2<=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&&reg64<=REG_RDI){
		if(REG_RAX<=reg32&&reg32<=REG_RDI) RexByte=(char)0x48;
		if(REG_R8<=reg32&&reg32<=REG_R15) RexByte=(char)0x49;
	}
	if(REG_R8<=reg64&&reg64<=REG_R15){
		if(REG_RAX<=reg32&&reg32<=REG_RDI) RexByte=(char)0x4C;
		if(REG_R8<=reg32&&reg32<=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&&reg64<=REG_RDI){
		if(REG_RAX<=reg16&&reg16<=REG_RDI) RexByte=(char)0x48;
		if(REG_R8<=reg16&&reg16<=REG_R15) RexByte=(char)0x49;
	}
	if(REG_R8<=reg64&&reg64<=REG_R15){
		if(REG_RAX<=reg16&&reg16<=REG_RDI) RexByte=(char)0x4C;
		if(REG_R8<=reg16&&reg16<=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&&reg64<=REG_RDI){
		if(REG_RAX<=reg8&&reg8<=REG_RDI) RexByte=(char)0x48;
		if(REG_R8<=reg8&&reg8<=REG_R15) RexByte=(char)0x49;
	}
	if(REG_R8<=reg64&&reg64<=REG_R15){
		if(REG_RAX<=reg8&&reg8<=REG_RDI) RexByte=(char)0x4C;
		if(REG_R8<=reg8&&reg8<=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&&reg32<=REG_RDI){
		if(REG_RAX<=reg16&&reg16<=REG_RDI) RexByte=0;
		if(REG_R8<=reg16&&reg16<=REG_R15) RexByte=(char)0x41;
	}
	if(REG_R8<=reg32&&reg32<=REG_R15){
		if(REG_RAX<=reg16&&reg16<=REG_RDI) RexByte=(char)0x44;
		if(REG_R8<=reg16&&reg16<=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&&reg32<=REG_RDI){
		if(REG_RAX<=reg8&&reg8<=REG_RBX) RexByte=0;
		if(REG_RSP<=reg8&&reg8<=REG_RDI) RexByte=(char)0x40;
		if(REG_R8<=reg8&&reg8<=REG_R15) RexByte=(char)0x41;
	}
	if(REG_R8<=reg32&&reg32<=REG_R15){
		if(REG_RAX<=reg8&&reg8<=REG_RDI) RexByte=(char)0x44;
		if(REG_R8<=reg8&&reg8<=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&&reg32<=REG_RDI){
		if(REG_RAX<=reg8&&reg8<=REG_RBX) RexByte=0;
		if(REG_RSP<=reg8&&reg8<=REG_RDI) RexByte=(char)0x40;
		if(REG_R8<=reg8&&reg8<=REG_R15) RexByte=(char)0x41;
	}
	if(REG_R8<=reg32&&reg32<=REG_R15){
		if(REG_RAX<=reg8&&reg8<=REG_RDI) RexByte=(char)0x44;
		if(REG_R8<=reg8&&reg8<=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<=REG_RDI) RexByte=0x48;
	if(REG_R8<=reg&&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&&reg1<=REG_RDI){
		if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x48;
		if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x49;
	}
	if(REG_R8<=reg1&&reg1<=REG_R15){
		if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x4C;
		if(REG_R8<=reg2&&reg2<=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&&reg1<=REG_RDI){
		if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=0;
		if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x41;
	}
	if(REG_R8<=reg1&&reg1<=REG_R15){
		if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x44;
		if(REG_R8<=reg2&&reg2<=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&&reg1<=REG_RDI){
		if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x48;
		if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x49;
	}
	if(REG_R8<=reg1&&reg1<=REG_R15){
		if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x4C;
		if(REG_R8<=reg2&&reg2<=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&&reg1<=REG_RDI){
		if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=0;
		if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x41;
	}
	if(REG_R8<=reg1&&reg1<=REG_R15){
		if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x44;
		if(REG_R8<=reg2&&reg2<=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&&reg1<=REG_RDI){
			if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x48;
			if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x49;
		}
		if(REG_R8<=reg1&&reg1<=REG_R15){
			if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x4C;
			if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x4D;
		}
	}
	else{
		if(REG_RAX<=reg1&&reg1<=REG_RDI){
			if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=0;
			if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x41;
		}
		if(REG_R8<=reg1&&reg1<=REG_R15){
			if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x44;
			if(REG_R8<=reg2&&reg2<=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<=REG_RDI) RexByte=(char)0x48;
		if(REG_R8<=reg&&reg<=REG_R15) RexByte=(char)0x4D;
	}
	else{
		if(REG_RAX<=reg&&reg<=REG_RDI) RexByte=0;
		if(REG_R8<=reg&&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<=REG_RDI) RexByte=(char)0x48;
	if(REG_R8<=reg&&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<=REG_RDI) RexByte=(char)0x48;
	if(REG_R8<=reg&&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<=REG_RDI) RexByte=(char)0x48;
		if(REG_R8<=reg&&reg<=REG_R15) RexByte=(char)0x49;
	}
	else if(op_size==sizeof(char)){
		if(REG_RAX<=reg&&reg<=REG_RBX) RexByte=0;
		if(REG_RSP<=reg&&reg<=REG_RDI) RexByte=(char)0x40;
		if(REG_R8<=reg&&reg<=REG_R15) RexByte=(char)0x41;
	}
	else{
		if(REG_RAX<=reg&&reg<=REG_RDI) RexByte=0;
		if(REG_R8<=reg&&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<=REG_RDI) RexByte=(char)0x48;
		if(REG_R8<=reg&&reg<=REG_R15) RexByte=(char)0x49;
	}
	else if(op_size==sizeof(char)){
		if(REG_RAX<=reg&&reg<=REG_RBX) RexByte=0;
		if(REG_RSP<=reg&&reg<=REG_RDI) RexByte=(char)0x40;
		if(REG_R8<=reg&&reg<=REG_R15) RexByte=(char)0x41;
	}
	else{
		if(REG_RAX<=reg&&reg<=REG_RDI) RexByte=0;
		if(REG_R8<=reg&&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<=REG_RDI) RexByte=(char)0x48;
		if(REG_R8<=reg&&reg<=REG_R15) RexByte=(char)0x49;
	}
	else if(op_size==sizeof(char)){
		if(REG_RAX<=reg&&reg<=REG_RBX) RexByte=0;
		if(REG_RSP<=reg&&reg<=REG_RDI) RexByte=(char)0x40;
		if(REG_R8<=reg&&reg<=REG_R15) RexByte=(char)0x41;
	}
	else{
		if(REG_RAX<=reg&&reg<=REG_RDI) RexByte=0;
		if(REG_R8<=reg&&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&&reg1<=REG_RDI){
			if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x48;
			if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x49;
		}
		if(REG_R8<=reg1&&reg1<=REG_R15){
			if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x4C;
			if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x4D;
		}
	}
	else{
		if(REG_RAX<=reg1&&reg1<=REG_RDI){
			if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=0;
			if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x41;
		}
		if(REG_R8<=reg1&&reg1<=REG_R15){
			if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x44;
			if(REG_R8<=reg2&&reg2<=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<=REG_RDI) (char)RexByte=0x48;
	if(REG_R8<=reg&&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<=REG_RDI) RexByte=0;
	if(REG_R8<=reg&&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&&reg1<=REG_RDI){
			if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x48;
			if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x49;
		}
		if(REG_R8<=reg1&&reg1<=REG_R15){
			if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x4C;
			if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x4D;
		}
	}
	else{
		if(REG_RAX<=reg1&&reg1<=REG_RDI){
			if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=0;
			if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x41;
		}
		if(REG_R8<=reg1&&reg1<=REG_R15){
			if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x44;
			if(REG_R8<=reg2&&reg2<=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&&reg1<=REG_RDI){
			if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x48;
			if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x49;
		}
		if(REG_R8<=reg1&&reg1<=REG_R15){
			if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x4C;
			if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x4D;
		}
	}
	else{
		if(REG_RAX<=reg1&&reg1<=REG_RDI){
			if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=0;
			if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x41;
		}
		if(REG_R8<=reg1&&reg1<=REG_R15){
			if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x44;
			if(REG_R8<=reg2&&reg2<=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<=REG_RDI) RexByte=(char)0x48;
		if(REG_R8<=reg&&reg<=REG_R15) RexByte=(char)0x49;
	}
	else{
		if(REG_RAX<=reg&&reg<=REG_RDI) RexByte=0;
		if(REG_R8<=reg&&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&&reg1<=REG_RDI){
		if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x48;
		if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x49;
	}
	if(REG_R8<=reg1&&reg1<=REG_R15){
		if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x4C;
		if(REG_R8<=reg2&&reg2<=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&&reg1<=REG_RDI){
			if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x48;
			if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x49;
		}
		if(REG_R8<=reg1&&reg1<=REG_R15){
			if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x4C;
			if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x4D;
		}
	}
	else{
		if(REG_RAX<=reg1&&reg1<=REG_RDI){
			if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=0;
			if(REG_R8<=reg2&&reg2<=REG_R15) RexByte=(char)0x41;
		}
		if(REG_R8<=reg1&&reg1<=REG_R15){
			if(REG_RAX<=reg2&&reg2<=REG_RDI) RexByte=(char)0x44;
			if(REG_R8<=reg2&&reg2<=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==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<=REG_RDI) RexByte=(char)0x48;
			if(REG_R8<=reg&&reg<=REG_R15) RexByte=(char)0x49;
		}
		if(REG_XMM8<=xmm_reg&&xmm_reg<=REG_XMM15){
			if(REG_RAX<=reg&&reg<=REG_RDI) RexByte=(char)0x4C;
			if(REG_R8<=reg&&reg<=REG_R15) RexByte=(char)0x4D;
		}
	}
	else{
		if(REG_XMM0<=xmm_reg&&xmm_reg<=REG_XMM7){
			if(REG_RAX<=reg&&reg<=REG_RDI) RexByte=0;
			if(REG_R8<=reg&&reg<=REG_R15) RexByte=(char)0x41;
		}
		if(REG_XMM8<=xmm_reg&&xmm_reg<=REG_XMM15){
			if(REG_RAX<=reg&&reg<=REG_RDI) RexByte=(char)0x44;
			if(REG_R8<=reg&&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<=REG_RDI) RexByte=(char)0x48;
			if(REG_R8<=reg&&reg<=REG_R15) RexByte=(char)0x49;
		}
		if(REG_XMM8<=xmm_reg&&xmm_reg<=REG_XMM15){
			if(REG_RAX<=reg&&reg<=REG_RDI) RexByte=(char)0x4C;
			if(REG_R8<=reg&&reg<=REG_R15) RexByte=(char)0x4D;
		}
	}
	else{
		if(REG_XMM0<=xmm_reg&&xmm_reg<=REG_XMM7){
			if(REG_RAX<=reg&&reg<=REG_RDI) RexByte=0;
			if(REG_R8<=reg&&reg<=REG_R15) RexByte=(char)0x41;
		}
		if(REG_XMM8<=xmm_reg&&xmm_reg<=REG_XMM15){
			if(REG_RAX<=reg&&reg<=REG_RDI) RexByte=(char)0x44;
			if(REG_R8<=reg&&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<=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<=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 );
}
