#include "stdafx.h"

#include <Compiler.h>

#include "../BasicCompiler_Common/common.h"
#include "Opcode.h"

void GetStackData_ToRegister(int *type,int sp){
	/*NumOpeポーランドのスタック蓄積による演算内容（2つのデータ）を
		レジスタedx:eax、ecx:ebxに取得する*/

	if(type[sp-1]==DEF_DOUBLE){
		//fld qword ptr[esp]
		compiler.codeGenerator.op_fld_ptr_esp(DEF_DOUBLE);

		//fistp qword ptr[esp]
		compiler.codeGenerator.op_fistp_ptr_esp( sizeof(_int64) );

		//pop ebx
		compiler.codeGenerator.op_pop(REG_EBX);

		//pop ecx
		compiler.codeGenerator.op_pop(REG_ECX);
	}
	else if(type[sp-1]==DEF_SINGLE){
		//fld dword ptr[esp]
		compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);

		//sub esp,4
		compiler.codeGenerator.op_sub_esp(4);

		//fistp qword ptr[esp]
		compiler.codeGenerator.op_fistp_ptr_esp( sizeof(_int64) );

		//pop ebx
		compiler.codeGenerator.op_pop(REG_EBX);

		//pop ecx
		compiler.codeGenerator.op_pop(REG_ECX);
	}
	else if(type[sp-1]==DEF_INT64||type[sp-1]==DEF_QWORD){
		//pop ebx
		compiler.codeGenerator.op_pop(REG_EBX);

		//pop ecx
		compiler.codeGenerator.op_pop(REG_ECX);
	}
	else{
		//pop eax
		compiler.codeGenerator.op_pop(REG_EAX);

		if(IsSignedType(type[sp-1])){
			//符号拡張
			//edx:eax ← eax
				
			//cdq
			compiler.codeGenerator.op_cdq();
		}
		else{
			//ビット拡張
			//edx:eax ← eax

			//xor edx,edx
			compiler.codeGenerator.op_zero_reg(REG_EDX);
		}

		//mov ebx,eax
		compiler.codeGenerator.op_mov_RR( REG_EBX, REG_EAX );

		//mov ecx,edx
		compiler.codeGenerator.op_mov_RR( REG_ECX, REG_EDX );
	}

	//第1項を64ビットに対応させる
	if(type[sp-2]==DEF_DOUBLE){
		//fld qword ptr[esp]
		compiler.codeGenerator.op_fld_ptr_esp(DEF_DOUBLE);

		//fistp qword ptr[esp]
		compiler.codeGenerator.op_fistp_ptr_esp( sizeof(_int64) );

		//pop eax
		compiler.codeGenerator.op_pop(REG_EAX);

		//pop edx
		compiler.codeGenerator.op_pop(REG_EDX);
	}
	else if(type[sp-2]==DEF_SINGLE){
		//fld dword ptr[esp]
		compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);

		//sub esp,4
		compiler.codeGenerator.op_sub_esp(4);

		//fistp qword ptr[esp]
		compiler.codeGenerator.op_fistp_ptr_esp( sizeof(_int64) );

		//pop eax
		compiler.codeGenerator.op_pop(REG_EAX);

		//pop edx
		compiler.codeGenerator.op_pop(REG_EDX);
	}
	else if(type[sp-2]==DEF_INT64||type[sp-2]==DEF_QWORD){
		//pop eax
		compiler.codeGenerator.op_pop(REG_EAX);

		//pop edx
		compiler.codeGenerator.op_pop(REG_EDX);
	}
	else{
		//pop eax
		compiler.codeGenerator.op_pop(REG_EAX);

		if(IsSignedType(type[sp-2])){
			//符号拡張
			//edx:eax ← eax
				
			//cdq
			compiler.codeGenerator.op_cdq();
		}
		else{
			//ビット拡張
			//edx:eax ← eax

			//xor edx,edx
			compiler.codeGenerator.op_zero_reg(REG_EDX);
		}
	}
}

void FormatStackData_To64bit(int *type,int sp){
	//NumOpeポーランドのスタック蓄積による演算内容（2つのデータ）を64ビット整数型にする

	GetStackData_ToRegister(type,sp);

	//push ecx
	compiler.codeGenerator.op_push(REG_ECX);

	//push ebx
	compiler.codeGenerator.op_push(REG_EBX);

	//push edx
	compiler.codeGenerator.op_push(REG_EDX);

	//push eax
	compiler.codeGenerator.op_push(REG_EAX);
}

BOOL CalcTwoTerm_Arithmetic(int idCalc,int *type,LONG_PTR *index_stack,int *pStackPointer){
	/*	value[sp-2] = value[sp-2] + value[sp-1]
		value[sp-2] = value[sp-2] - value[sp-1]
		value[sp-2] = value[sp-2] * value[sp-1]		*/

	int sp;
	sp=*pStackPointer;

	int AnswerType;
	AnswerType=NeutralizationType(type[sp-2],index_stack[sp-2],type[sp-1],index_stack[sp-1]);

	if(type[sp-2]==DEF_DOUBLE||type[sp-2]==DEF_SINGLE||
		type[sp-1]==DEF_DOUBLE||type[sp-1]==DEF_SINGLE){
		/////////////
		// 実数演算
		/////////////

		if(type[sp-1]==DEF_DOUBLE){
			//fld qword ptr[esp]
			compiler.codeGenerator.op_fld_ptr_esp(DEF_DOUBLE);

			//add esp,8
			compiler.codeGenerator.op_add_esp(8);
		}
		else if(type[sp-1]==DEF_SINGLE){
			//fld dword ptr[esp]
			compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);

			//add esp,4
			compiler.codeGenerator.op_add_esp(4);
		}
		else if(type[sp-1]==DEF_INT64||type[sp-1]==DEF_QWORD){
			//64ビット整数値

			//fild qword ptr[esp]
			compiler.codeGenerator.op_fld_ptr_esp(DEF_INT64);

			//add esp,8
			compiler.codeGenerator.op_add_esp(8);
		}
		else{
			//その他整数型

			//fild dword ptr[esp]
			compiler.codeGenerator.op_fld_ptr_esp(DEF_LONG);

			//add esp,4
			compiler.codeGenerator.op_add_esp(4);
		}

		if(type[sp-2]==DEF_DOUBLE){
			//fld qword ptr[esp]
			compiler.codeGenerator.op_fld_ptr_esp(DEF_DOUBLE);
		}
		else if(type[sp-2]==DEF_SINGLE){
			//fld dword ptr[esp]
			compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);
		}
		else if(type[sp-2]==DEF_INT64||type[sp-2]==DEF_QWORD){
			//64ビット整数値
			compiler.codeGenerator.op_fld_ptr_esp(DEF_INT64);
		}
		else{
			//その他整数型

			//fild dword ptr[esp]
			compiler.codeGenerator.op_fld_ptr_esp(DEF_LONG);
		}

		if(Type(type[sp-2],-1).GetSize()==sizeof(_int64)){
			if(AnswerType==DEF_SINGLE){
				//add esp,4
				compiler.codeGenerator.op_add_esp(4);
			}
		}
		else{
			if(AnswerType==DEF_DOUBLE){
				//sub esp,4
				compiler.codeGenerator.op_sub_esp(4);
			}
		}

		if(idCalc==CALC_ADDITION){
			//faddp st(1),st
			compiler.codeGenerator.PutOld(
				(char)0xDE,
				(char)0xC1
			);
		}
		else if(idCalc==CALC_SUBTRACTION){
			//fsubrp st(1),st
			compiler.codeGenerator.PutOld(
				(char)0xDE,
				(char)0xE1
			);
		}
		else if(idCalc==CALC_PRODUCT){
			//fmulp st(1),st
			compiler.codeGenerator.PutOld(
				(char)0xDE,
				(char)0xC9
			);
		}

		if(AnswerType==DEF_DOUBLE){
			//fstp qword ptr[esp]
			compiler.codeGenerator.op_fstp_basereg( DEF_DOUBLE, REG_ESP );
		}
		else{
			//fstp dword ptr[esp]
			compiler.codeGenerator.op_fstp_basereg( DEF_SINGLE, REG_ESP );
		}
	}
	else if(Is64Type(type[sp-2])||Is64Type(type[sp-1])){
		//////////////////////
		// 64ビット整数演算
		//////////////////////

		if(idCalc==CALC_PRODUCT){
			if(!((type[sp-1]==DEF_INT64||type[sp-1]==DEF_QWORD)&&
				(type[sp-2]==DEF_INT64||type[sp-2]==DEF_QWORD))){
				//2つの項のどちらかが64ビット整数でないとき
				FormatStackData_To64bit(type,sp);
			}

			//call _allmul
			extern const UserProc *pSub_allmul;
			compiler.codeGenerator.op_call(pSub_allmul);

			//push edx
			compiler.codeGenerator.op_push(REG_EDX);

			//push eax
			compiler.codeGenerator.op_push(REG_EAX);
		}
		else{
			if(type[sp-1]==DEF_INT64||type[sp-1]==DEF_QWORD){
				//第2項が64ビット整数値のとき

				//pop ebx
				compiler.codeGenerator.op_pop(REG_EBX);

				//pop ecx
				compiler.codeGenerator.op_pop(REG_ECX);
			}
			else{
				//第2項がその他整数値のとき

				//pop eax
				compiler.codeGenerator.op_pop(REG_EAX);

				if(IsSignedType(type[sp-1])){
					//符号拡張
					//edx:eax ← eax
					
					//cdq
					compiler.codeGenerator.op_cdq();
				}
				else{
					//ビット拡張
					//edx:eax ← eax

					//xor edx,edx
					compiler.codeGenerator.op_zero_reg(REG_EDX);
				}

				//mov ebx,eax
				compiler.codeGenerator.op_mov_RR( REG_EBX, REG_EAX );

				//mov ecx,edx
				compiler.codeGenerator.op_mov_RR( REG_ECX, REG_EDX );
			}

			if(type[sp-2]==DEF_INT64||type[sp-2]==DEF_QWORD){
				//第1項が64ビット整数値のとき

				if(idCalc==CALC_ADDITION){
					//add dword ptr[esp],ebx
					compiler.codeGenerator.PutOld(
						(char)0x01,
						(char)0x1C,
						(char)0x24
					);

					//adc dword ptr[esp+sizeof(long)],ecx
					compiler.codeGenerator.PutOld(
						(char)0x11,
						(char)0x4C,
						(char)0x24,
						(char)0x04
					);
				}
				else if(idCalc==CALC_SUBTRACTION){
					//sub dword ptr[esp],ebx
					compiler.codeGenerator.PutOld(
						(char)0x29,
						(char)0x1C,
						(char)0x24
					);

					//sbb dword ptr[esp+sizeof(long)],ecx
					compiler.codeGenerator.PutOld(
						(char)0x19,
						(char)0x4C,
						(char)0x24,
						(char)0x04
					);
				}
			}
			else{
				//第1項がその他整数値のとき

				//pop eax
				compiler.codeGenerator.op_pop(REG_EAX);

				if(IsSignedType(type[sp-2])){
					//符号拡張
					//edx:eax ← eax

					//cdq
					compiler.codeGenerator.op_cdq();
				}
				else{
					//ビット拡張
					//edx:eax ← eax

					//xor edx,edx
					compiler.codeGenerator.op_zero_reg(REG_EDX);
				}

				if(idCalc==CALC_ADDITION){
					//add ebx,eax
					compiler.codeGenerator.op_add_RR( REG_EBX, REG_EAX );

					//adc ecx,edx
					compiler.codeGenerator.op_adc_RR( REG_ECX, REG_EDX );
				}
				else if(idCalc==CALC_SUBTRACTION){
					//sub ebx,eax
					compiler.codeGenerator.op_sub_RR( REG_EBX, REG_EAX );

					//sbb ecx,edx
					compiler.codeGenerator.op_sub_RR( REG_ECX, REG_EDX );
				}

				//push ecx
				compiler.codeGenerator.op_push(REG_ECX);

				//push ebx
				compiler.codeGenerator.op_push(REG_EBX);
			}
		}
	}
	else{
		//////////////////////////
		//32ビット以下の整数演算
		//////////////////////////

		//pop ebx
		compiler.codeGenerator.op_pop(REG_EBX);

		//pop eax
		compiler.codeGenerator.op_pop(REG_EAX);

		//sub esp,4
		compiler.codeGenerator.op_sub_esp(4);

		if(idCalc==CALC_ADDITION){
			//add eax,ebx
			compiler.codeGenerator.op_add_RR( REG_EAX, REG_EBX );
		}
		else if(idCalc==CALC_SUBTRACTION){
			//sub eax,ebx
			compiler.codeGenerator.op_sub_RR( REG_EAX, REG_EBX );
		}
		else if(idCalc==CALC_PRODUCT){
			//imul eax,ebx（64ビット演算ではないので、符号を考慮しない）
			compiler.codeGenerator.op_imul_RR( REG_EAX, REG_EBX );
		}

		//mov dword ptr[esp],eax
		compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_ESP, 0, MOD_BASE );
	}

	sp--;
	type[sp-1]=AnswerType;

	*pStackPointer=sp;

	return 1;
}

BOOL Calc_Mod(int *type,int *pStackPointer){
	//value[sp-2]%=value[sp-1]
	//剰余演算

	int sp;
	sp=*pStackPointer;

	if(type[sp-1]==DEF_INT64||type[sp-1]==DEF_QWORD||
		type[sp-2]==DEF_INT64||type[sp-2]==DEF_QWORD){
		////////////////
		// 64ビット演算
		////////////////

		//第2項を64ビットに対応させる
		FormatStackData_To64bit(type,sp);

		if(IsSignedType(type[sp-2])==0&&IsSignedType(type[sp-1])==0){
			//符号なし演算

			//call _aullrem
			extern const UserProc *pSub_aullrem;
			compiler.codeGenerator.op_call(pSub_aullrem);
		}
		else{
			//符号あり演算

			//call _allrem
			extern const UserProc *pSub_allrem;
			compiler.codeGenerator.op_call(pSub_allrem);
		}

		//push edx
		compiler.codeGenerator.op_push(REG_EDX);

		//push eax
		compiler.codeGenerator.op_push(REG_EAX);

		sp--;
		if(type[sp-1]==DEF_QWORD&&type[sp]==DEF_QWORD) type[sp-1]=DEF_QWORD;
		else type[sp-1]=DEF_INT64;
	}
	else{
		////////////////
		// 32ビット演算
		////////////////

		if(type[sp-1]==DEF_DOUBLE){
			//fld qword ptr[esp]
			compiler.codeGenerator.op_fld_ptr_esp(DEF_DOUBLE);

			//add esp,4
			compiler.codeGenerator.op_add_esp(4);

			//fistp dword ptr[esp]
			compiler.codeGenerator.op_fistp_ptr_esp( sizeof(long) );
		}
		else if(type[sp-1]==DEF_SINGLE){
			//fld dword ptr[esp]
			compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);

			//fistp dword ptr[esp]
			compiler.codeGenerator.op_fistp_ptr_esp( sizeof(long) );
		}

		//pop ebx
		compiler.codeGenerator.op_pop(REG_EBX);

		if(type[sp-2]==DEF_DOUBLE){
			//fld qword ptr[esp]
			compiler.codeGenerator.op_fld_ptr_esp(DEF_DOUBLE);

			//add esp,4
			compiler.codeGenerator.op_add_esp(4);

			//fistp dword ptr[esp]
			compiler.codeGenerator.op_fistp_ptr_esp( sizeof(long) );
		}
		else if(type[sp-2]==DEF_SINGLE){
			//fld dword ptr[esp]
			compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);

			//fistp dword ptr[esp]
			compiler.codeGenerator.op_fistp_ptr_esp( sizeof(long) );
		}

		//pop eax
		compiler.codeGenerator.op_pop(REG_EAX);

		//sub esp,4
		compiler.codeGenerator.op_sub_esp(4);

		if(type[sp-2]==DEF_DWORD&&type[sp-1]==DEF_DWORD){
			//xor edx,edx
			compiler.codeGenerator.op_zero_reg(REG_EDX);

			//div ebx (eax=eax/ebx...edx)
			compiler.codeGenerator.op_div_R( REG_EBX );
		}
		else{
			//cdq
			compiler.codeGenerator.op_cdq();

			//idiv ebx (eax=eax/ebx...edx)
			compiler.codeGenerator.op_idiv_R( REG_EBX );
		}

		//mov dword ptr[esp],edx
		compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EDX, REG_ESP, 0, MOD_BASE );

		sp--;
		type[sp-1]=DEF_LONG;
	}

	*pStackPointer=sp;

	return 1;
}

BOOL Calc_Divide(int *type,int *pStackPointer,int BaseType){
	//value[sp-2]/=value[sp-1];
	//除算

	int sp;
	sp=*pStackPointer;

	///////////////////////
	// 浮動小数点演算のみ
	///////////////////////

	int AnswerType;
	if(type[sp-2]==DEF_DOUBLE||type[sp-1]==DEF_DOUBLE||BaseType==DEF_DOUBLE) AnswerType=DEF_DOUBLE;
	else AnswerType=DEF_SINGLE;

	if(type[sp-1]==DEF_DOUBLE){
		//fld qword ptr[esp]
		compiler.codeGenerator.op_fld_ptr_esp(DEF_DOUBLE);

		//add esp,8
		compiler.codeGenerator.op_add_esp(8);
	}
	else if(type[sp-1]==DEF_SINGLE){
		//fld dword ptr[esp]
		compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);

		//add esp,4
		compiler.codeGenerator.op_add_esp(4);
	}
	else if(type[sp-1]==DEF_INT64||type[sp-1]==DEF_QWORD){
		//64ビット整数値

		//fild qword ptr[esp]
		compiler.codeGenerator.op_fld_ptr_esp(DEF_INT64);

		//add esp,8
		compiler.codeGenerator.op_add_esp(8);
	}
	else if(type[sp-1]==DEF_DWORD){
		//pop eax
		compiler.codeGenerator.op_pop(REG_EAX);

		//push 0
		compiler.codeGenerator.op_push_V(0);

		//push eax
		compiler.codeGenerator.op_push(REG_EAX);

		//fild qword ptr[esp]
		compiler.codeGenerator.op_fld_ptr_esp(DEF_INT64);

		//add esp,8
		compiler.codeGenerator.op_add_esp(8);
	}
	else{
		//fild dword ptr[esp]
		compiler.codeGenerator.op_fld_ptr_esp(DEF_LONG);

		//add esp,4
		compiler.codeGenerator.op_add_esp(4);
	}

	if(type[sp-2]==DEF_DOUBLE){
		//fld qword ptr[esp]
		compiler.codeGenerator.op_fld_ptr_esp(DEF_DOUBLE);
	}
	else if(type[sp-2]==DEF_SINGLE){
		//fld dword ptr[esp]
		compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);
	}
	else if(type[sp-2]==DEF_INT64||type[sp-2]==DEF_QWORD){
		//64ビット整数値

		//fild qword ptr[esp]
		compiler.codeGenerator.op_fld_ptr_esp(DEF_INT64);
	}
	else if(type[sp-2]==DEF_DWORD){
		//pop eax
		compiler.codeGenerator.op_pop(REG_EAX);

		//push 0
		compiler.codeGenerator.op_push_V(0);

		//push eax
		compiler.codeGenerator.op_push(REG_EAX);

		//fild qword ptr[esp]
		compiler.codeGenerator.op_fld_ptr_esp(DEF_INT64);
	}
	else{	//Long
		//fild dword ptr[esp]
		compiler.codeGenerator.op_fld_ptr_esp(DEF_LONG);
	}
                                                            //↓ここだけ例外DWord
	if(Type(type[sp-2],-1).GetSize()==sizeof(_int64)||type[sp-2]==DEF_DWORD){
		if(AnswerType==DEF_SINGLE){
			//add esp,4
			compiler.codeGenerator.op_add_esp(4);
		}
	}
	else{
		if(AnswerType==DEF_DOUBLE){
			//sub esp,4
			compiler.codeGenerator.op_sub_esp(4);
		}
	}

	//fdivrp st(1),st
	compiler.codeGenerator.PutOld(
		(char)0xDE,
		(char)0xF1
	);

	sp--;
	if(AnswerType==DEF_DOUBLE){
		//fstp qword ptr[esp]
		compiler.codeGenerator.op_fstp_basereg( DEF_DOUBLE, REG_ESP );

		type[sp-1]=DEF_DOUBLE;
	}
	else{
		//fstp dword ptr[esp]
		compiler.codeGenerator.op_fstp_basereg( DEF_SINGLE, REG_ESP );

		type[sp-1]=DEF_SINGLE;
	}

	*pStackPointer=sp;

	return 1;
}

BOOL Calc_IntDivide(int *type,LONG_PTR *index_stack,int *pStackPointer){
	//value[sp-2]/=value[sp-1]
	//除算（整数）

	int sp;
	sp=*pStackPointer;

	if(type[sp-1]==DEF_INT64||type[sp-1]==DEF_QWORD||
		type[sp-2]==DEF_INT64||type[sp-2]==DEF_QWORD){
		////////////////
		// 64ビット演算
		////////////////

		//2つの項を64ビットに対応させる
		FormatStackData_To64bit(type,sp);

		if(IsSignedType(type[sp-2])==0&&IsSignedType(type[sp-1])==0){
			//符号なし演算

			//call _aulldiv
			extern const UserProc *pSub_aulldiv;
			compiler.codeGenerator.op_call(pSub_aulldiv);
		}
		else{
			//符号あり演算

			//call _alldiv
			extern const UserProc *pSub_alldiv;
			compiler.codeGenerator.op_call(pSub_alldiv);
		}

		//push edx
		compiler.codeGenerator.op_push(REG_EDX);

		//push eax
		compiler.codeGenerator.op_push(REG_EAX);

		sp--;
		if(type[sp-1]==DEF_QWORD&&type[sp]==DEF_QWORD) type[sp-1]=DEF_QWORD;
		else type[sp-1]=DEF_INT64;
	}
	else{
		////////////////
		// 32ビット演算
		////////////////

		if(type[sp-1]==DEF_DOUBLE){
			//fld qword ptr[esp]
			compiler.codeGenerator.op_fld_ptr_esp(DEF_DOUBLE);

			//add esp,4
			compiler.codeGenerator.op_add_esp(4);

			//fistp dword ptr[esp]
			compiler.codeGenerator.op_fistp_ptr_esp( sizeof(long) );
		}
		else if(type[sp-1]==DEF_SINGLE){
			//fld dword ptr[esp]
			compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);

			//fistp dword ptr[esp]
			compiler.codeGenerator.op_fistp_ptr_esp( sizeof(long) );
		}

		//pop ebx
		compiler.codeGenerator.op_pop(REG_EBX);

		if(type[sp-2]==DEF_DOUBLE){
			//fld qword ptr[esp]
			compiler.codeGenerator.op_fld_ptr_esp(DEF_DOUBLE);

			//add esp,4
			compiler.codeGenerator.op_add_esp(4);

			//fistp dword ptr[esp]
			compiler.codeGenerator.op_fistp_ptr_esp( sizeof(long) );
		}
		else if(type[sp-2]==DEF_SINGLE){
			//fld dword ptr[esp]
			compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);

			//fistp dword ptr[esp]
			compiler.codeGenerator.op_fistp_ptr_esp( sizeof(long) );
		}

		//pop eax
		compiler.codeGenerator.op_pop(REG_EAX);

		//sub esp,4
		compiler.codeGenerator.op_sub_esp(4);

		if((type[sp-2]==DEF_DWORD&&type[sp-1]==DEF_DWORD)||
			(IS_POSITIVE_LITERAL(index_stack[sp-2])&&type[sp-1]==DEF_DWORD)||
			(type[sp-2]==DEF_DWORD&&IS_POSITIVE_LITERAL(index_stack[sp-1]))){
			//xor edx,edx
			compiler.codeGenerator.op_zero_reg(REG_EDX);

			//div ebx (eax=eax/ebx...edx)
			compiler.codeGenerator.op_div_R( REG_EBX );
		}
		else{
			//cdq
			compiler.codeGenerator.op_cdq();

			//idiv ebx (eax=eax/ebx...edx)
			compiler.codeGenerator.op_idiv_R( REG_EBX );
		}

		//mov dword ptr[esp],eax
		compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_ESP, 0, MOD_BASE );

		sp--;

		//整数以外の型だったときはLong型にする
		if(!IsWholeNumberType(type[sp-1])) type[sp-1]=DEF_LONG;
	}

	*pStackPointer=sp;
	return 1;
}

BOOL Calc_MinusMark(int *type,int sp){
	//value[sp-1]=-value[sp-1]
	//符号反転

	if(type[sp-1]==DEF_DOUBLE){
		//fld qword ptr[esp]
		compiler.codeGenerator.op_fld_ptr_esp(DEF_DOUBLE);

		//push -1
		compiler.codeGenerator.op_push_V(-1);

		//fild dword ptr[esp]
		compiler.codeGenerator.op_fld_ptr_esp(DEF_LONG);

		//add esp,4
		compiler.codeGenerator.op_add_esp(4);

		//fmulp st(1),st
		compiler.codeGenerator.PutOld(
			(char)0xDE,
			(char)0xC9
		);

		//fstp qword ptr[esp]
		compiler.codeGenerator.op_fstp_basereg( DEF_DOUBLE, REG_ESP );
	}
	else if(type[sp-1]==DEF_SINGLE){
		//fld dword ptr[esp]
		compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);

		//push -1
		compiler.codeGenerator.op_push_V(-1);

		//fild dword ptr[esp]
		compiler.codeGenerator.op_fld_ptr_esp(DEF_LONG);

		//add esp,4
		compiler.codeGenerator.op_add_esp(4);

		//fmulp st(1),st
		compiler.codeGenerator.PutOld(
			(char)0xDE,
			(char)0xC9
		);

		//fstp dword ptr[esp]
		compiler.codeGenerator.op_fstp_basereg( DEF_SINGLE, REG_ESP );
	}
	else if(type[sp-1]==DEF_INT64||type[sp-1]==DEF_QWORD){
		//pop eax
		compiler.codeGenerator.op_pop(REG_EAX);

		//neg eax
		compiler.codeGenerator.op_neg( REG_EAX );

		//pop edx
		compiler.codeGenerator.op_pop(REG_EDX);

		//adc edx,0
		compiler.codeGenerator.op_adc_RV8(REG_EDX,0);

		//neg edx
		compiler.codeGenerator.op_neg( REG_EDX );

		//push edx
		compiler.codeGenerator.op_push(REG_EDX);

		//push eax
		compiler.codeGenerator.op_push(REG_EAX);

		type[sp-1]=DEF_INT64;	//QWordはInt64へ
	}
	else if(IsWholeNumberType(type[sp-1])){
		//pop eax
		compiler.codeGenerator.op_pop(REG_EAX);

		//imul eax,-1
		compiler.codeGenerator.op_imul_RV8( REG_EAX, -1 );

		//push eax
		compiler.codeGenerator.op_push(REG_EAX);

		type[sp-1]=GetSignedType(type[sp-1]);
	}

	return 1;
}

BOOL Calc_Power(int *type,int *pStackPointer){
	//べき乗（実数演算のみ）

	int sp;
	sp=*pStackPointer;

	if(type[sp-1]==DEF_DOUBLE){
		//fld qword ptr[esp]
		compiler.codeGenerator.op_fld_ptr_esp(DEF_DOUBLE);

		//add esp,8
		compiler.codeGenerator.op_add_esp(8);
	}
	else if(type[sp-1]==DEF_SINGLE){
		//fld dword ptr[esp]
		compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);

		//add esp,4
		compiler.codeGenerator.op_add_esp(4);
	}
	else if(type[sp-1]==DEF_INT64||type[sp-1]==DEF_QWORD){
		//64ビット整数値

		//fild qword ptr[esp]
		compiler.codeGenerator.op_fld_ptr_esp(DEF_INT64);

		//add esp,8
		compiler.codeGenerator.op_add_esp(8);
	}
	else{
		//32ビット整数値

		//fild dword ptr[esp]
		compiler.codeGenerator.op_fld_ptr_esp(DEF_LONG);

		//add esp,4
		compiler.codeGenerator.op_add_esp(4);
	}

	if(type[sp-2]==DEF_DOUBLE){
		//fld qword ptr[esp]
		compiler.codeGenerator.op_fld_ptr_esp(DEF_DOUBLE);
	}
	else if(type[sp-2]==DEF_SINGLE){
		//fld dword ptr[esp]
		compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);

		//sub esp,4
		compiler.codeGenerator.op_sub_esp(4);
	}
	else if(type[sp-2]==DEF_INT64||type[sp-2]==DEF_QWORD){
		//64ビット整数値

		//fild qword ptr[esp]
		compiler.codeGenerator.op_fld_ptr_esp(DEF_INT64);
	}
	else{
		//32ビット整数値

		//fild dword ptr[esp]
		compiler.codeGenerator.op_fld_ptr_esp(DEF_LONG);

		//sub esp,4
		compiler.codeGenerator.op_sub_esp(4);
	}

	//sub esp,8
	compiler.codeGenerator.op_sub_esp(8);

	//fstp qword ptr[esp]
	compiler.codeGenerator.op_fstp_basereg( DEF_DOUBLE, REG_ESP );

	//fstp qword ptr[esp+8]
	compiler.codeGenerator.op_fstp_base_offset(DEF_DOUBLE,REG_ESP,8);

	//call pow
	extern const UserProc *pSub_pow;
	compiler.codeGenerator.op_call(pSub_pow);

	//sub esp,8
	compiler.codeGenerator.op_sub_esp(8);

	//fstp qword ptr[esp]
	compiler.codeGenerator.op_fstp_basereg( DEF_DOUBLE, REG_ESP );

	sp--;
	type[sp-1]=DEF_DOUBLE;

	*pStackPointer=sp;
	return 1;
}

BOOL Calc_Cast(int *type,LONG_PTR *index_stack,int *pStackPointer){
	//キャスト

	int sp;
	sp=*pStackPointer;

	int castBasicType = type[sp-1];
	if((castBasicType&FLAG_CAST)==0){
		SetError(47,NULL,cp);
		return 0;
	}
	castBasicType = castBasicType&(~FLAG_CAST);

	Type oldType( type[sp-2], index_stack[sp-2] );
	Type castType( castBasicType, index_stack[sp-1] );

	if( castType.IsPointer() )
	{
		ChangeTypeToLong( oldType.GetBasicType() );
	}
	else if( castType.IsReal() )
	{
		if( castType.IsDouble() )
		{
			ChangeTypeToDouble( oldType.GetBasicType() );
		}
		else if( castType.IsSingle() )
		{
			ChangeTypeToSingle( oldType.GetBasicType() );
		}
	}
	else
	{
		ChangeTypeToWhole( oldType, castType );
	}

	type[sp-2] = castType.GetBasicType();
	index_stack[sp-2] = castType.GetIndex();

	sp--;

	*pStackPointer=sp;
	return 1;
}

BOOL Calc_SHL(int *type,int *pStackPointer){
	//左ビットシフト
	//value[sp-2]=value[sp-2]<<value[sp-1]

	int sp;
	sp=*pStackPointer;

	if(type[sp-2]==DEF_INT64||type[sp-2]==DEF_QWORD){
		////////////////
		// 64ビット演算
		////////////////

		//2項目は32ビット整数として利用
		if(type[sp-1]==DEF_DOUBLE){
			//fld qword ptr[esp]
			compiler.codeGenerator.op_fld_ptr_esp(DEF_DOUBLE);

			//add esp,4
			compiler.codeGenerator.op_add_esp(4);

			//fistp dword ptr[esp]
			compiler.codeGenerator.op_fistp_ptr_esp( sizeof(long) );

			//pop ecx
			compiler.codeGenerator.op_pop(REG_ECX);
		}
		else if(type[sp-1]==DEF_SINGLE){
			//fld dword ptr[esp]
			compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);

			//fistp dword ptr[esp]
			compiler.codeGenerator.op_fistp_ptr_esp( sizeof(long) );

			//pop ecx
			compiler.codeGenerator.op_pop(REG_ECX);
		}
		else if(type[sp-1]==DEF_INT64||type[sp-1]==DEF_QWORD){
			//pop ecx
			compiler.codeGenerator.op_pop(REG_ECX);

			//add esp,4
			compiler.codeGenerator.op_add_esp(4);
		}
		else{
			//pop ecx
			compiler.codeGenerator.op_pop(REG_ECX);
		}

		//第1項を64ビットに対応させる
		if(type[sp-2]==DEF_DOUBLE){
			//fld qword ptr[esp]
			compiler.codeGenerator.op_fld_ptr_esp(DEF_DOUBLE);

			//fistp qword ptr[esp]
			compiler.codeGenerator.op_fistp_ptr_esp( sizeof(_int64) );

			//pop eax
			compiler.codeGenerator.op_pop(REG_EAX);

			//pop edx
			compiler.codeGenerator.op_pop(REG_EDX);
		}
		else if(type[sp-2]==DEF_SINGLE){
			//fld dword ptr[esp]
			compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);

			//sub esp,4
			compiler.codeGenerator.op_sub_esp(4);

			//fistp qword ptr[esp]
			compiler.codeGenerator.op_fistp_ptr_esp( sizeof(_int64) );

			//pop eax
			compiler.codeGenerator.op_pop(REG_EAX);

			//pop edx
			compiler.codeGenerator.op_pop(REG_EDX);
		}
		else if(type[sp-2]==DEF_INT64||type[sp-2]==DEF_QWORD){
			//pop eax
			compiler.codeGenerator.op_pop(REG_EAX);

			//pop edx
			compiler.codeGenerator.op_pop(REG_EDX);
		}
		else{
			//pop eax
			compiler.codeGenerator.op_pop(REG_EAX);

			if(IsSignedType(type[sp-2])){
				//符号拡張
				//edx:eax ← eax
					
				//cdq
				compiler.codeGenerator.op_cdq();
			}
			else{
				//ビット拡張
				//edx:eax ← eax

				//xor edx,edx
				compiler.codeGenerator.op_zero_reg(REG_EDX);
			}
		}

		//call _allshl
		extern const UserProc *pSub_allshl;
		compiler.codeGenerator.op_call(pSub_allshl);

		//push edx
		compiler.codeGenerator.op_push(REG_EDX);

		//push eax
		compiler.codeGenerator.op_push(REG_EAX);

		sp--;
	}
	else{
		////////////////
		// 32ビット演算
		////////////////

		//2項目は32ビット整数として利用
		if(type[sp-1]==DEF_DOUBLE){
			//fld qword ptr[esp]
			compiler.codeGenerator.op_fld_ptr_esp(DEF_DOUBLE);

			//add esp,4
			compiler.codeGenerator.op_add_esp(4);

			//fistp dword ptr[esp]
			compiler.codeGenerator.op_fistp_ptr_esp( sizeof(long) );

			//pop ecx
			compiler.codeGenerator.op_pop(REG_ECX);
		}
		else if(type[sp-1]==DEF_SINGLE){
			//fld dword ptr[esp]
			compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);

			//fistp dword ptr[esp]
			compiler.codeGenerator.op_fistp_ptr_esp( sizeof(long) );

			//pop ecx
			compiler.codeGenerator.op_pop(REG_ECX);
		}
		else if(type[sp-1]==DEF_INT64||type[sp-1]==DEF_QWORD){
			//pop ecx
			compiler.codeGenerator.op_pop(REG_ECX);

			//add esp,4
			compiler.codeGenerator.op_add_esp(4);
		}
		else{
			//pop ecx
			compiler.codeGenerator.op_pop(REG_ECX);
		}

		if(type[sp-2]==DEF_DOUBLE){
			//fld qword ptr[esp]
			compiler.codeGenerator.op_fld_ptr_esp(DEF_DOUBLE);

			//add esp,4
			compiler.codeGenerator.op_add_esp(4);

			//fistp dword ptr[esp]
			compiler.codeGenerator.op_fistp_ptr_esp( sizeof(long) );
		}
		else if(type[sp-2]==DEF_SINGLE){
			//fld dword ptr[esp]
			compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);

			//fistp dword ptr[esp]
			compiler.codeGenerator.op_fistp_ptr_esp( sizeof(long) );
		}

		//pop eax
		compiler.codeGenerator.op_pop(REG_EAX);

		//sub esp,4
		compiler.codeGenerator.op_sub_esp(4);

		//shl eax,cl
		compiler.codeGenerator.PutOld(
			(char)0xD3,
			(char)0xE0
		);

		//mov dword ptr[esp],eax
		compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_ESP, 0, MOD_BASE );

		sp--;

		//32ビット型にする
		if(IsSignedType(type[sp-1])) type[sp-1]=DEF_LONG;
		else type[sp-1]=DEF_DWORD;
	}

	*pStackPointer=sp;
	return 1;
}

BOOL Calc_SHR(int *type,int *pStackPointer){
	//右ビットシフト
	//value[sp-2]=value[sp-2]>>value[sp-1]

	int sp;
	sp=*pStackPointer;

	if(type[sp-2]==DEF_INT64||type[sp-2]==DEF_QWORD){
		////////////////
		// 64ビット演算
		////////////////

		//2項目は32ビット整数として利用
		if(type[sp-1]==DEF_DOUBLE){
			//fld qword ptr[esp]
			compiler.codeGenerator.op_fld_ptr_esp(DEF_DOUBLE);

			//add esp,4
			compiler.codeGenerator.op_add_esp(4);

			//fistp dword ptr[esp]
			compiler.codeGenerator.op_fistp_ptr_esp( sizeof(long) );

			//pop ecx
			compiler.codeGenerator.op_pop(REG_ECX);
		}
		else if(type[sp-1]==DEF_SINGLE){
			//fld dword ptr[esp]
			compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);

			//fistp dword ptr[esp]
			compiler.codeGenerator.op_fistp_ptr_esp( sizeof(long) );

			//pop ecx
			compiler.codeGenerator.op_pop(REG_ECX);
		}
		else if(type[sp-1]==DEF_INT64||type[sp-1]==DEF_QWORD){
			//pop ecx
			compiler.codeGenerator.op_pop(REG_ECX);

			//add esp,4
			compiler.codeGenerator.op_add_esp(4);
		}
		else{
			//pop ecx
			compiler.codeGenerator.op_pop(REG_ECX);
		}

		//第1項を64ビットに対応させる
		if(type[sp-2]==DEF_DOUBLE){
			//fld qword ptr[esp]
			compiler.codeGenerator.op_fld_ptr_esp(DEF_DOUBLE);

			//fistp qword ptr[esp]
			compiler.codeGenerator.op_fistp_ptr_esp( sizeof(_int64) );

			//pop eax
			compiler.codeGenerator.op_pop(REG_EAX);

			//pop edx
			compiler.codeGenerator.op_pop(REG_EDX);
		}
		else if(type[sp-2]==DEF_SINGLE){
			//fld dword ptr[esp]
			compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);

			//sub esp,4
			compiler.codeGenerator.op_sub_esp(4);

			//fistp qword ptr[esp]
			compiler.codeGenerator.op_fistp_ptr_esp( sizeof(_int64) );

			//pop eax
			compiler.codeGenerator.op_pop(REG_EAX);

			//pop edx
			compiler.codeGenerator.op_pop(REG_EDX);
		}
		else if(type[sp-2]==DEF_INT64||type[sp-2]==DEF_QWORD){
			//pop eax
			compiler.codeGenerator.op_pop(REG_EAX);

			//pop edx
			compiler.codeGenerator.op_pop(REG_EDX);
		}
		else{
			//pop eax
			compiler.codeGenerator.op_pop(REG_EAX);

			if(IsSignedType(type[sp-2])){
				//符号拡張
				//edx:eax ← eax

				//cdq
				compiler.codeGenerator.op_cdq();
			}
			else{
				//ビット拡張
				//edx:eax ← eax

				//xor edx,edx
				compiler.codeGenerator.op_zero_reg(REG_EDX);
			}
		}

		if(type[sp-2]==DEF_QWORD){
			//符号なし演算

			//call _aullshr
			extern const UserProc *pSub_aullshr;
			compiler.codeGenerator.op_call(pSub_aullshr);
		}
		else{
			//符号あり演算

			//call _allshr
			extern const UserProc *pSub_allshr;
			compiler.codeGenerator.op_call(pSub_allshr);
		}

		//push edx
		compiler.codeGenerator.op_push(REG_EDX);

		//push eax
		compiler.codeGenerator.op_push(REG_EAX);

		sp--;
	}
	else{
		////////////////
		// 32ビット演算
		////////////////

		//2項目は32ビット整数として利用
		if(type[sp-1]==DEF_DOUBLE){
			//fld qword ptr[esp]
			compiler.codeGenerator.op_fld_ptr_esp(DEF_DOUBLE);

			//add esp,4
			compiler.codeGenerator.op_add_esp(4);

			//fistp dword ptr[esp]
			compiler.codeGenerator.op_fistp_ptr_esp( sizeof(long) );

			//pop ecx
			compiler.codeGenerator.op_pop(REG_ECX);
		}
		else if(type[sp-1]==DEF_SINGLE){
			//fld dword ptr[esp]
			compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);

			//fistp dword ptr[esp]
			compiler.codeGenerator.op_fistp_ptr_esp( sizeof(long) );

			//pop ecx
			compiler.codeGenerator.op_pop(REG_ECX);
		}
		else if(type[sp-1]==DEF_INT64||type[sp-1]==DEF_QWORD){
			//pop ecx
			compiler.codeGenerator.op_pop(REG_ECX);

			//add esp,4
			compiler.codeGenerator.op_add_esp(4);
		}
		else{
			//pop ecx
			compiler.codeGenerator.op_pop(REG_ECX);
		}

		if(type[sp-2]==DEF_DOUBLE){
			//fld qword ptr[esp]
			compiler.codeGenerator.op_fld_ptr_esp(DEF_DOUBLE);

			//add esp,4
			compiler.codeGenerator.op_add_esp(4);

			//fistp dword ptr[esp]
			compiler.codeGenerator.op_fistp_ptr_esp( sizeof(long) );
		}
		else if(type[sp-2]==DEF_SINGLE){
			//fld dword ptr[esp]
			compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);

			//fistp dword ptr[esp]
			compiler.codeGenerator.op_fistp_ptr_esp( sizeof(long) );
		}

		//pop eax
		compiler.codeGenerator.op_pop(REG_EAX);

		//sub esp,4
		compiler.codeGenerator.op_sub_esp(4);

		if(type[sp-2]==DEF_DWORD){
			//shr eax,cl
			compiler.codeGenerator.PutOld(
				(char)0xD3,
				(char)0xE8
			);
		}
		else{
			//sar eax,cl
			compiler.codeGenerator.PutOld(
				(char)0xD3,
				(char)0xF8
			);
		}

		//mov dword ptr[esp],eax
		compiler.codeGenerator.op_mov_MR( sizeof(long), REG_EAX, REG_ESP, 0, MOD_BASE );

		sp--;

		//整数以外の型だったときはLong型にする
		if(!IsWholeNumberType(type[sp-1])) type[sp-1]=DEF_LONG;
	}

	*pStackPointer=sp;
	return 1;
}
