#include "../BasicCompiler_Common/common.h" #include "Opcode.h" ///////////////////////// // スタックフレーム管理 ///////////////////////// CStackFrame::CStackFrame(){ lowest_sp=0; now_sp=0; local_parm_size=0; max_parm_size=0; } CStackFrame::~CStackFrame(){ //オブジェクト破棄時に不整合がないかをチェック(バグ回避) error_check(); } void CStackFrame::SetLocalParmSize(int size){ local_parm_size=size; } int CStackFrame::GetFrameSize(){ int answer_sp; answer_sp=lowest_sp-max_parm_size; if((local_parm_size%0x10)==0){ if((answer_sp%0x10)==0){ //関数のエントリポイントで128ビット境界ラインに合わせるため return -(answer_sp-0x08); } return -(answer_sp-0x10); } if((answer_sp%0x10)==0){ //関数のエントリポイントで128ビット境界ラインに合わせるため return -(answer_sp-0x10); } return -(answer_sp-0x08); } int CStackFrame::GetNowSp(){ return now_sp; } void CStackFrame::mov_sp( int reg ){ //mov reg,rsp op_mov_RR( reg, REG_RSP ); //add reg,now_sp op_add_RV( reg, now_sp ); //スケジュールをセット obp-=sizeof(long); add(); obp+=sizeof(long); } int CStackFrame::push(int reg){ now_sp-=sizeof(_int64); if(lowest_sp>now_sp) lowest_sp=now_sp; if(reg==REG_NON) return now_sp; //mov qword ptr[rsp+offset],reg op_mov_MR(sizeof(_int64),reg,REG_RSP,now_sp,MOD_BASE_DISP32); //スケジュールをセット obp-=sizeof(long); add(); obp+=sizeof(long); return now_sp; } void CStackFrame::push(int xmm_reg,int var_size){ now_sp-=sizeof(_int64); if(lowest_sp>now_sp) lowest_sp=now_sp; if(var_size==sizeof(double)){ //movlpd qword ptr[rsp+offset],xmm_reg op_movlpd_MR(xmm_reg,REG_RSP,now_sp,MOD_BASE_DISP32); } if(var_size==sizeof(float)){ //movss dword ptr[rsp+offset],xmm_reg OpBuffer[obp++]=(char)0xF3; OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x11; OpBuffer[obp++]=(char)(0x84| REGISTER_OPERAND(xmm_reg)<<3 ); OpBuffer[obp++]=(char)0x24; *((long *)(OpBuffer+obp))=now_sp; obp+=sizeof(long); } //スケジュールをセット obp-=sizeof(long); add(); obp+=sizeof(long); } void CStackFrame::ref_offset_data( int reg, int sp_offset ){ //mov reg,qword ptr[rsp+offset] ※スタックフレームを利用 op_mov_RM(sizeof(_int64),reg,REG_RSP,sp_offset,MOD_BASE_DISP32); //スケジュールをセット obp-=sizeof(long); add(); obp+=sizeof(long); } void CStackFrame::ref(int reg){ ref_offset_data( reg, now_sp ); } void CStackFrame::ref(int xmm_reg,int var_size){ if(var_size==sizeof(double)){ //movlpd xmm_reg,qword ptr[rsp+offset] op_movlpd_RM(xmm_reg,REG_RSP,now_sp,MOD_BASE_DISP32); } if(var_size==sizeof(float)){ //movss xmm_reg,dword ptr[rsp+offset] OpBuffer[obp++]=(char)0xF3; OpBuffer[obp++]=(char)0x0F; OpBuffer[obp++]=(char)0x10; OpBuffer[obp++]=(char)(0x84| REGISTER_OPERAND(xmm_reg)<<3 ); OpBuffer[obp++]=(char)0x24; *((long *)(OpBuffer+obp))=now_sp; obp+=sizeof(long); } //スケジュールをセット obp-=sizeof(long); add(); obp+=sizeof(long); } void CStackFrame::pop(int reg){ if(reg!=REG_NON) ref(reg); now_sp+=sizeof(_int64); } void CStackFrame::pop(int xmm_reg,int var_size){ ref(xmm_reg,var_size); now_sp+=sizeof(_int64); } void CStackFrame::parameter_allocate(int size){ if(max_parm_size