#include "../BasicCompiler_Common/common.h" #include "Opcode.h" void OpcodeOthers(const char *Command){ int i,i2; UserProc *pUserProc; char leftTerm[8192]; int lastParePos = 0; for(i=0;;i++){ if(Command[i]=='\"'){ //ダブルクォートは不正なのでエラー扱い leftTerm[i]=0; SetError(3,leftTerm,cp); return; } if(Command[i]=='('){ lastParePos = i; i2=GetStringInPare(leftTerm+i,Command+i); i+=i2-1; continue; } if(Command[i]=='['){ i2=GetStringInBracket(leftTerm+i,Command+i); i+=i2-1; continue; } if(Command[i]=='\0'){ leftTerm[i] = 0; break; } if( IsNumCalcMark( Command, i ) ){ leftTerm[i] = 0; break; } leftTerm[i]=Command[i]; } if(!( IsVariableTopChar(leftTerm[0])|| leftTerm[0]=='.'|| (leftTerm[0]==1&&leftTerm[1]==ESC_PSMEM) )){ SetError(1,NULL,cp); return; } if(Command[i]=='\0' && lastParePos == 0){ ////////////////////////////// // パラメータ無しのマクロ検索 ////////////////////////////// pUserProc=GetSubHash(Command); //GetSubHash内でエラー提示が行われた場合 if(pUserProc==(UserProc *)-1) return; if(pUserProc==0){ char temporary[VN_SIZE]; lstrcpy(temporary,Command); CharUpper(temporary); pUserProc=GetSubHash(temporary); //GetSubHash内でエラー提示が行われた場合 if(pUserProc==(UserProc *)-1) return; } if(pUserProc){ if( !pUserProc->IsMacro() ){ SetError(10,Command,cp); } Opcode_CallProc("",pUserProc,0,"",0); return; } } else if(IsNumCalcMark(Command,i)){ //代入演算 OpcodeCalc(Command); return; } if( pobj_reg ){ SetError(); } pobj_reg=new CRegister(REG_RAX); Type resultType; bool isLiteral; BOOL bUseHeap; bool result = TermOpe( leftTerm, Type(), resultType, isLiteral, &bUseHeap, false, NULL, true ); delete pobj_reg; pobj_reg = NULL; if( result ){ ///////////////////// // 戻り値の処理 ///////////////////// if( resultType.IsStruct() ){ //mov r14,rax op_mov_RR(REG_R14,REG_RAX); FreeTempObject(REG_R14,&resultType.GetClass()); } //成功 return; } // 失敗 SetError(1, NULL,cp); } void Judgment(char *buffer){ int reg=REG_RAX; Type resultType; if( !NumOpe(®,buffer,Type(),resultType) ){ return; } int offset; if(resultType.IsDouble()){ double dbl=0; offset=dataTable.Add( dbl ); //comisd xmm0,qword ptr[data table offset] OpBuffer[obp++]=(char)0x66; OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x2F; OpBuffer[obp++]=(char)0x04; OpBuffer[obp++]=(char)0x25; *((long *)(OpBuffer+obp))=offset; pobj_DataTableSchedule->add(); obp+=sizeof(long); } else if(resultType.IsSingle()){ float flt=0; offset=dataTable.Add( flt ); //comiss xmm0,dword ptr[data table offset] OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x2F; OpBuffer[obp++]=(char)0x04; OpBuffer[obp++]=(char)0x25; *((long *)(OpBuffer+obp))=offset; pobj_DataTableSchedule->add(); obp+=sizeof(long); } else{ //整数型 //cmp rax,0 op_cmp_value(resultType.GetSize(),REG_RAX,0); } } void OpcodeIf(char *Parameter){ int i,i2,i3; for(i=0;;i++){ if(Parameter[i]=='\0'){ SetError(21,NULL,cp); return; } if(Parameter[i]==1&&Parameter[i+1]==ESC_THEN){ Parameter[i]=0; break; } } //条件式を実行してフラグをセット Judgment(Parameter); //je (endif、または else まで条件ジャンプ) OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x84; obp+=sizeof(long); //jeの番地 i3=obp; ///////////////////////// // If内をコード化 ///////////////////////// //レキシカルスコープをレベルアップ obj_LexScopes.Start( obp, SCOPE_TYPE_IF ); i2=CompileBuffer(ESC_ENDIF,0); //レキシカルスコープをレベルダウン obj_LexScopes.End(); if(i2==ESC_ELSE){ //jmp (endifまで) OpBuffer[obp++]=(char)0xE9; obp+=sizeof(long); *((long *)(OpBuffer+i3-sizeof(long)))=obp-i3; //ifからelseへのジャンプ先のオフセット値 i3=obp; ///////////////////////// // Else内をコード化 ///////////////////////// //レキシカルスコープをレベルアップ obj_LexScopes.Start( obp, SCOPE_TYPE_IF ); CompileBuffer(ESC_ENDIF,0); //レキシカルスコープをレベルダウン obj_LexScopes.End(); *((long *)(OpBuffer+i3-sizeof(long)))=obp-i3; //jmpジャンプ先のオフセット値 } else{ *((long *)(OpBuffer+i3-sizeof(long)))=obp-i3; //jeジャンプ先のオフセット値 } } int GetLabelAddress(char *LabelName,int LineNum){ extern int MaxLabelNum; extern LABEL *pLabelNames; int i; if(LabelName){ for(i=0;ilock((int *)&dwTempContinue); pobj_TempSchedule->lock((int *)&dwContinueAddress); if(!Parameter[0]) SetError(10,"While",cp); //条件式を実行してフラグをセット Judgment(Parameter); //je (Wend まで) OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x84; obp+=sizeof(long); //実行中の番地 int je_schedule=obp; pobj_TempSchedule->lock(&je_schedule); //レキシカルスコープをレベルアップ obj_LexScopes.Start( obp, SCOPE_TYPE_WHILE ); //While内をコンパイル CompileBuffer(0,COM_WEND); obj_LexScopes.CallDestructorsOfScopeEnd(); //jmp ... OpBuffer[obp++]=(char)0xE9; *((long *)(OpBuffer+obp))=dwContinueAddress-(obp+sizeof(long)); obp+=sizeof(long); pobj_TempSchedule->unlock(); pobj_TempSchedule->unlock(); //レキシカルスコープをレベルダウン obj_LexScopes.End(); *((long *)(OpBuffer+je_schedule-sizeof(long)))=obp-je_schedule; //jeジャンプ先のオフセット値 pobj_TempSchedule->unlock(); //Continueアドレスを復元 dwContinueAddress=dwTempContinue; } char szNextVariable[VN_SIZE]; void OpcodeFor(char *Parameter){ extern HANDLE hHeap; Type resultType; int i,i2,i3; char temporary[VN_SIZE],variable[VN_SIZE],JudgeNum[VN_SIZE],StepNum[VN_SIZE]; bool isError = false; //第1パラメータを取得 i=GetOneParameter(Parameter,0,temporary); if(!Parameter[i]){ SetError(12,"For",cp); isError = true; goto ErrorStep; } for(i2=0;;i2++){ if(temporary[i2]=='='){ variable[i2]=0; //カウンタ初期化 OpcodeCalc(temporary); break; } if(temporary[i2]=='\0'){ SetError(12,"For",cp); isError = true; goto ErrorStep; } variable[i2]=temporary[i2]; } //jmp ... OpBuffer[obp++]=(char)0xE9; i2=obp; obp+=sizeof(long); //Continueアドレスのバックアップとセット extern DWORD dwContinueAddress; DWORD dwTempContinue; dwTempContinue=dwContinueAddress; dwContinueAddress=obp; pobj_TempSchedule->lock((int *)&dwTempContinue); pobj_TempSchedule->lock((int *)&dwContinueAddress); //第2パラメータを取得(to〜) i=GetOneParameter(Parameter,i,JudgeNum); //第3パラメータを取得(step〜) if(Parameter[i]){ i=GetOneParameter(Parameter,i,StepNum); if(Parameter[i]) SetError(12,"For",cp); } else lstrcpy(StepNum,"1"); //カウンタを増加させる sprintf(temporary,"%s=(%s)+(%s)",variable,variable,StepNum); OpcodeCalc(temporary); *((long *)(OpBuffer+i2))=obp-(i2+sizeof(long)); //増加か減少かを区別する sprintf(temporary,"(%s)>=0",StepNum); int reg; reg=REG_RAX; if( !NumOpe(®,temporary,Type(),resultType) ){ return; } //cmp rax,0 op_cmp_value(resultType.GetSize(),REG_RAX,0); //je [カウンタ減少の場合の判定] OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x84; i2=obp; obp+=sizeof(long); //判定(カウンタ増加の場合) sprintf(temporary,"%s<=(%s)",variable,JudgeNum); reg=REG_RAX; NumOpe(®,temporary,Type(),Type()); //jmp [カウンタ減少の場合の判定を飛び越す] OpBuffer[obp++]=(char)0xE9; i3=obp; obp+=sizeof(long); *((long *)(OpBuffer+i2))=obp-(i2+sizeof(long)); //jeジャンプ先のオフセット値 //判定(カウンタ減少の場合) sprintf(temporary,"%s>=(%s)",variable,JudgeNum); reg=REG_RAX; NumOpe(®,temporary,Type(),resultType); *((long *)(OpBuffer+i3))=obp-(i3+sizeof(long)); //jmpジャンプ先のオフセット値 //cmp rax,0 op_cmp_value(resultType.GetSize(),REG_RAX,0); ErrorStep: //je ... OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x84; int je_schedule=obp; obp+=sizeof(long); pobj_TempSchedule->lock(&je_schedule); //レキシカルスコープをレベルアップ obj_LexScopes.Start( obp, SCOPE_TYPE_FOR ); //For内をコンパイル CompileBuffer(0,COM_NEXT); obj_LexScopes.CallDestructorsOfScopeEnd(); if(szNextVariable[0]){ if(lstrcmp(szNextVariable,variable)!=0){ SetError(55,szNextVariable,cp); } } //jmp ... OpBuffer[obp++]=(char)0xE9; *((long *)(OpBuffer+obp))=dwContinueAddress-(obp+sizeof(long)); obp+=sizeof(long); if( isError == false ){ pobj_TempSchedule->unlock(); pobj_TempSchedule->unlock(); } //レキシカルスコープをレベルダウン obj_LexScopes.End(); *((long *)(OpBuffer+je_schedule))=obp-(je_schedule+sizeof(long)); //jeジャンプ先のオフセット値 pobj_TempSchedule->unlock(); //Continueアドレスを復元 dwContinueAddress=dwTempContinue; } void OpcodeDo(char *Parameter){ extern HANDLE hHeap; int i,i2,i3; if(Parameter[0]) SetError(10,"Do",cp); //Continueアドレスのバックアップとセット extern DWORD dwContinueAddress; DWORD dwTempContinue; dwTempContinue=dwContinueAddress; dwContinueAddress=obp; pobj_TempSchedule->lock((int *)&dwTempContinue); pobj_TempSchedule->lock((int *)&dwContinueAddress); //レキシカルスコープをレベルアップ obj_LexScopes.Start( obp, SCOPE_TYPE_DO ); //Do内をコンパイル CompileBuffer(0,COM_LOOP); obj_LexScopes.CallDestructorsOfScopeEnd(); extern char *basbuf; char temporary[VN_SIZE]; for(i=cp-1;;i--){ if(IsCommandDelimitation(basbuf[i])){ i+=3; if(!(basbuf[i]=='0'||basbuf[i]=='1')){ //無条件ループ break; } i3=i; for(i+=2,i2=0;;i++,i2++){ if(IsCommandDelimitation(basbuf[i])){ temporary[i2]=0; break; } temporary[i2]=basbuf[i]; } //条件式を実行してフラグをセット Judgment(temporary); if(basbuf[i3]=='0'){ //While //je 5(ループ終了) OpBuffer[obp++]=(char)0x74; OpBuffer[obp++]=(char)0x05; } else if(basbuf[i3]=='1'){ //Until //jne 5(ループ終了) OpBuffer[obp++]=(char)0x75; OpBuffer[obp++]=(char)0x05; } break; } } //jmp ... OpBuffer[obp++]=(char)0xE9; *((long *)(OpBuffer+obp))=dwContinueAddress-(obp+sizeof(long)); obp+=sizeof(long); pobj_TempSchedule->unlock(); pobj_TempSchedule->unlock(); //jmp ... OpBuffer[obp++]=(char)0xE9; int je_schedule=obp; obp+=sizeof(long); pobj_TempSchedule->lock(&je_schedule); //レキシカルスコープをレベルダウン obj_LexScopes.End(); *((long *)(OpBuffer+je_schedule))=obp-(je_schedule+sizeof(long)); //jmpジャンプ先のオフセット値 pobj_TempSchedule->unlock(); //Continueアドレスを復元 dwContinueAddress=dwTempContinue; } void OpcodeContinue(void){ extern DWORD dwContinueAddress; if(dwContinueAddress==-1){ SetError(12,"Continue",cp); return; } //jmp ...(Continue addr) OpBuffer[obp++]=(char)0xE9; *((long *)(OpBuffer+obp))=dwContinueAddress-(obp+sizeof(long)); obp+=sizeof(long); } void OpcodeExitSub(void){ extern DWORD *pExitSubSchedule; extern int ExitSubScheduleNum; extern HANDLE hHeap; if( UserProc::IsGlobalAreaCompiling() ){ SetError(12,"Exit Sub/Function",cp); return; } //未解放のローカルオブジェクトのデストラクタを呼び出す obj_LexScopes.CallDestructorsOfReturn(); //jmp ...(End Sub/Function) OpBuffer[obp++]=(char)0xE9; pExitSubSchedule=(DWORD *)HeapReAlloc(hHeap,0,pExitSubSchedule,(ExitSubScheduleNum+1)*sizeof(DWORD)); pExitSubSchedule[ExitSubScheduleNum]=obp; ExitSubScheduleNum++; obp+=sizeof(long); } void AddCaseSchedule(void){ extern DWORD *pCaseSchedule; extern int CaseScheduleNum; extern HANDLE hHeap; pCaseSchedule=(DWORD *)HeapReAlloc(hHeap,0,pCaseSchedule,(CaseScheduleNum+1)*sizeof(DWORD)); pCaseSchedule[CaseScheduleNum]=obp; CaseScheduleNum++; } void OpcodeSelect( const char *lpszParms ){ extern DWORD *pCaseSchedule; extern int CaseScheduleNum; extern int NowCaseSchedule; extern HANDLE hHeap; extern char *basbuf; int i,i2,i3,NowCaseCp; char temporary[VN_SIZE]; DWORD *temp_pCaseSchedule; int temp_CaseScheduleNum; int temp_NowCaseSchedule; temp_pCaseSchedule=pCaseSchedule; temp_CaseScheduleNum=CaseScheduleNum; temp_NowCaseSchedule=NowCaseSchedule; pCaseSchedule=(DWORD *)HeapAlloc(hHeap,0,1); CaseScheduleNum=0; NowCaseSchedule=0; int reg1=REG_RAX; Type type1; if( !NumOpe(®1,lpszParms,Type(), type1 ) ){ return; } if(type1.IsDouble()){ //movsd qword ptr[rsp+offset],xmm_reg ※スタックフレームを利用 pobj_sf->push(reg1,sizeof(double)); } else if(type1.IsSingle()){ //movss dword ptr[rsp+offset],xmm_reg ※スタックフレームを利用 pobj_sf->push(reg1,sizeof(float)); } else{ ExtendTypeTo64(type1.GetBasicType(),reg1); //mov qword ptr[rsp+offset],reg ※スタックフレームを利用 pobj_sf->push(reg1); } for(i=cp;;i++){ if(basbuf[i]=='\0'){ HeapDefaultFree(pCaseSchedule); pCaseSchedule=temp_pCaseSchedule; CaseScheduleNum=temp_CaseScheduleNum; NowCaseSchedule=temp_NowCaseSchedule; SetError(22,"Select",cp); return; } if(basbuf[i]==1&&basbuf[i+1]==ESC_SELECTCASE){ for(i2=0;;i++){ if(basbuf[i]==1&&basbuf[i+1]==ESC_SELECTCASE) i2++; if(basbuf[i]==1&&basbuf[i+1]==ESC_ENDSELECT){ i2--; if(i2==0) break; } } continue; } if(basbuf[i]==1&&basbuf[i+1]==ESC_ENDSELECT) break; if(basbuf[i]==1&&basbuf[i+1]==ESC_CASE){ NowCaseCp=i; i++; while(1){ for(i++,i2=0;;i++,i2++){ if(basbuf[i]=='\"'){ i3=GetStringInQuotation(temporary+i2,basbuf+i); i+=i3-1; i2+=i3-1; continue; } if(basbuf[i]=='('){ i3=GetStringInPare(temporary+i2,basbuf+i); i+=i3-1; i2+=i3-1; continue; } if(basbuf[i]=='['){ i3=GetStringInBracket(temporary+i2,basbuf+i); i+=i3-1; i2+=i3-1; continue; } if(IsCommandDelimitation(basbuf[i])){ temporary[i2]=0; break; } if(basbuf[i]==','){ temporary[i2]=0; break; } temporary[i2]=basbuf[i]; } //エラー用 i2=cp; cp=NowCaseCp; int reg2=REG_RDX; Type type2; if( !NumOpe(®2,temporary,type1,type2) ){ return; } cp=i2; if(type1.IsObject()){ std::vector subs; type1.GetClass().GetMethods().Enum( CALC_EQUAL, subs ); if( subs.size() == 0 ){ return; } Parameters params; params.push_back( new Parameter( "", Type( type2 ) ) ); //オーバーロードを解決 UserProc *pUserProc; pUserProc=OverloadSolution("==",subs, params, NULL); delete params[0]; if(!pUserProc){ //エラー return; } //実体オブジェクト if(reg2!=REG_RDX){ //mov rdx,reg2 op_mov_RR(REG_RDX,reg2); } //mov rcx,qword ptr[rsp+offset] ※スタックフレームから参照 pobj_sf->ref(REG_RCX); //call operator_proc ※ ==演算子 op_call(pUserProc); //test rax,rax op_test(REG_RAX,REG_RAX); //jne ... OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x85; } else{ if(type1.IsDouble()){ int xmm_reg; if(IsXmmReg(reg2)) xmm_reg=reg2; else xmm_reg=REG_XMM5; ChangeTypeToXmm_Double(type2.GetBasicType(),xmm_reg,reg2); //movsd xmm4,qword ptr[rsp+offset] ※スタックフレームから参照 pobj_sf->ref(REG_XMM4,sizeof(double)); //comiss xmm_reg1,xmm_reg2 op_comisd(xmm_reg,REG_XMM4); } else if(type1.IsSingle()){ int xmm_reg; if(IsXmmReg(reg2)) xmm_reg=reg2; else xmm_reg=REG_XMM5; ChangeTypeToXmm_Single(type2.GetBasicType(),xmm_reg,reg2); //movss xmm4,dword ptr[rsp+offset] ※スタックフレームから参照 pobj_sf->ref(REG_XMM4,sizeof(float)); //comiss xmm_reg1,xmm_reg2 op_comiss(xmm_reg,REG_XMM4); } else{ //その他整数型 i2=NeutralizationType(type1.GetBasicType(),-1,type2.GetBasicType(),-1); //mov r14,qword ptr[rsp+offset] ※スタックフレームから参照 pobj_sf->ref(REG_R14); //cmp reg2,r14 op_cmp_reg(GetTypeSize(i2,-1),reg2,REG_R14); } //je ... OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x84; } AddCaseSchedule(); obp+=sizeof(long); if(basbuf[i]!=',') break; } } if(basbuf[i]==1&&basbuf[i+1]==ESC_CASEELSE){ //jmp ... OpBuffer[obp++]=(char)0xE9; AddCaseSchedule(); obp+=sizeof(long); } } //スタックフレームを1スペースだけ解除 pobj_sf->pop(REG_NON); //レキシカルスコープをレベルアップ obj_LexScopes.Start( obp, SCOPE_TYPE_SELECT ); //Select Case内をコンパイル CompileBuffer(ESC_ENDSELECT,0); //jmp EndSelect OpBuffer[obp++]=(char)0xE9; AddCaseSchedule(); obp+=sizeof(long); //最終スケジュール for(i=NowCaseSchedule;ipush(REG_RAX); if(Parameter[0]=='*'){ i=GetLabelAddress(Parameter+1,0); //jmp ... OpBuffer[obp++]=(char)0xE9; if(i==-1){ pGotoLabelSchedule=(GOTOLABELSCHEDULE *)HeapReAlloc(hHeap,0,pGotoLabelSchedule,(GotoLabelScheduleNum+1)*sizeof(GOTOLABELSCHEDULE)); pGotoLabelSchedule[GotoLabelScheduleNum].pName=(char *)HeapAlloc(hHeap,0,lstrlen(Parameter+1)+1); lstrcpy(pGotoLabelSchedule[GotoLabelScheduleNum].pName,Parameter+1); pGotoLabelSchedule[GotoLabelScheduleNum].pos=obp; pGotoLabelSchedule[GotoLabelScheduleNum].now_cp=cp; GotoLabelScheduleNum++; } *((long *)(OpBuffer+obp))=i-(obp+sizeof(long)); obp+=sizeof(long); } else{ LineNum=atoi(Parameter); i=GetLabelAddress(0,LineNum); //jmp ... OpBuffer[obp++]=(char)0xE9; if(i==-1){ pGotoLabelSchedule=(GOTOLABELSCHEDULE *)HeapReAlloc(hHeap,0,pGotoLabelSchedule,(GotoLabelScheduleNum+1)*sizeof(GOTOLABELSCHEDULE)); pGotoLabelSchedule[GotoLabelScheduleNum].pName=0; pGotoLabelSchedule[GotoLabelScheduleNum].line=LineNum; pGotoLabelSchedule[GotoLabelScheduleNum].pos=obp; pGotoLabelSchedule[GotoLabelScheduleNum].now_cp=cp; GotoLabelScheduleNum++; } *((long *)(OpBuffer+obp))=i-(obp+sizeof(long)); obp+=sizeof(long); } *((long *)(OpBuffer+schedule2))=obp-schedule; //※スタックフレームを元に戻す pobj_sf->pop(REG_NON); SetError(-1,"Gosub 〜 Returnステートメントは64ビットコンパイラで利用することはできません。",cp); } void OpcodeReturn(char *Parameter){ if( UserProc::IsGlobalAreaCompiling() ){ SetError(62,NULL,cp); } else{ //戻り値をセット if(Parameter[0]){ UserProc &proc = UserProc::CompilingUserProc(); const char *temp = "_System_ReturnValue"; if(proc.GetName()[0]==1&&proc.GetName()[1]==ESC_OPERATOR) { } else{ temp=proc.GetName().c_str(); } char temporary[VN_SIZE]; sprintf(temporary,"%s=%s",temp,Parameter); OpcodeCalc(temporary); } //プロシージャを抜け出す(C言語のreturnと同様の処理を行う) OpcodeExitSub(); } } //////////// // ポインタ //////////// void OpcodeSetPtrData(char *Parameter,int type){ int i; char temporary[VN_SIZE]; if(Parameter[0]=='('){ i=JumpStringInPare(Parameter,1); if(Parameter[i+1]=='\0'){ for(i=0;;i++){ Parameter[i]=Parameter[i+1]; if(Parameter[i]=='\0') break; } Parameter[i-1]=0; } } //第1パラメータを取得 i=GetOneParameter(Parameter,0,temporary); if(!Parameter[i]){ SetError(1,NULL,cp); return; } int reg_ptr=REG_RAX; Type resultType; if( !NumOpe(®_ptr,temporary,Type(),resultType) ){ return; } if(!resultType.IsWhole()){ SetError(11,Parameter,cp); return; } //結果を格納しているレジスタをブロッキング pobj_BlockReg->lock(reg_ptr); //第2パラメータを取得 i=GetOneParameter(Parameter,i,temporary); if(Parameter[i]){ SetError(1,NULL,cp); return; } int temp_reg=REG_NON; if( !NumOpe(&temp_reg,temporary,Type(),resultType) ){ return; } //レジスタのブロッキングを解除 pobj_BlockReg->clear(); if(type==DEF_DOUBLE){ ChangeTypeToXmm_Double(resultType.GetBasicType(),REG_XMM0,temp_reg); //movsd qword ptr[reg_ptr],xmm0 op_movsd_MR(REG_XMM0,reg_ptr,0,MOD_BASE); } else if(type==DEF_SINGLE){ ChangeTypeToXmm_Single(resultType.GetBasicType(),REG_XMM0,temp_reg); //movss dword ptr[reg_ptr],xmm0 op_movss_MR(REG_XMM0,reg_ptr,0,MOD_BASE); } else{ ChangeTypeToWhole(resultType.GetBasicType(),type,REG_RCX,temp_reg); //mov ptr[reg_ptr],rcx op_mov_MR(GetTypeSize(type,-1),REG_RCX,reg_ptr,0,MOD_BASE); } }