//Opcode.h //レジスタを示す定数 #define REG_EAX 1 #define REG_EBX 2 #define REG_ECX 3 #define REG_EDX 4 #define REG_ESP 5 #define REG_EBP 6 #define REGISTER_OPERAND(reg) (reg&0x07) #define REG_NON -1 #define REG_RAX 0x00 //reg:000 #define REG_RCX 0x01 //reg:001 #define REG_RDX 0x02 //reg:010 #define REG_RBX 0x03 //reg:011 #define REG_RSP 0x04 //reg:100 #define REG_RBP 0x05 //reg:101 #define REG_RSI 0x06 //reg:110 #define REG_RDI 0x07 //reg:111 #define REG_R8 0x08 //reg:000(REXプリフィックス) #define REG_R9 0x09 //reg:001(REXプリフィックス) #define REG_R10 0x0A //reg:010(REXプリフィックス) #define REG_R11 0x0B //reg:011(REXプリフィックス) #define REG_R12 0x0C //reg:100(REXプリフィックス) #define REG_R13 0x0D //reg:101(REXプリフィックス) #define REG_R14 0x0E //reg:110(REXプリフィックス) #define REG_R15 0x0F //reg:111(REXプリフィックス) #define REG_XMM0 0x10 //reg:000 #define REG_XMM1 0x11 //reg:001 #define REG_XMM2 0x12 //reg:010 #define REG_XMM3 0x13 //reg:011 #define REG_XMM4 0x14 //reg:100 #define REG_XMM5 0x15 //reg:101 #define REG_XMM6 0x16 //reg:110 #define REG_XMM7 0x17 //reg:111 #define REG_XMM8 0x18 //reg:000 #define REG_XMM9 0x19 //reg:001 #define REG_XMM10 0x1A //reg:010 #define REG_XMM11 0x1B //reg:011 #define REG_XMM12 0x1C //reg:100 #define REG_XMM13 0x1D //reg:101 #define REG_XMM14 0x1E //reg:110 #define REG_XMM15 0x1F //reg:111 #define IS_XMM_REG(reg) (reg&0x10) //変数の種類 #define NON_VAR 0 #define VAR_GLOBAL 1 //Global Variable #define VAR_LOCAL 2 //Local Variable #define VAR_REFLOCAL 3 //Local Refference Variable #define VAR_DIRECTMEM 4 //Direct memory extern int cp; extern int obp; extern char *OpBuffer; //ラベルアドレス struct LABEL{ char *pName; int line; DWORD address; }; //Goto未知ラベル struct GOTOLABELSCHEDULE{ char *pName; int line; DWORD pos; DWORD now_cp; }; //プロシージャの種類 #define PROC_DEFAULT 1 //ユーザー定義関数 #define PROC_DLL 2 //DLL関数 #define PROC_BUILTIN 3 //コンパイラ埋め込み型 #define PROC_PTR 4 //関数ポインタ //プロシージャ struct PROCEDURE{ char name[255]; int address; int types[MAX_PARMS]; _int8 ByVal[MAX_PARMS]; BOOL ReturnType; }; //With情報 struct WITHINFO{ char **ppName; int *pWithCp; int num; }; class CStackFrame:public CSchedule{ /////////////////////////// // スタックフレーム管理 /////////////////////////// int lowest_sp; //スタックポインタの最下位位置 int now_sp; //スタックポインタ int max_parm_size; //パラメータの最大サイズ int local_parm_size; //ローカル領域のパラメータサイズ public: //コンストラクタ CStackFrame(); //デストラクタ ~CStackFrame(); void SetLocalParmSize(int size); int GetFrameSize(); int push(int reg); void push(int xmm_reg,int var_size); void ref_offset_data( int reg, int sp_offset ); void ref(int reg); void ref(int xmm_reg,int var_size); void pop(int reg); void pop(int xmm_reg,int var_size); void parameter_allocate(int size); void RunningSchedule(void); void error_check(void); }; extern CStackFrame *pobj_sf; class CBlockReg{ int array_BlockReg[256]; int num; public: CBlockReg(); void lock(int reg); void unlock(int reg); BOOL check(int reg); void clear(void); //レジスタのバックアップと復旧 void backup(); void restore(); }; extern CBlockReg *pobj_BlockReg; class CRegister{ //////////////////// // レジスタ管理 //////////////////// //利用可能なレジスタを列挙する関数 void EnumRegister(int *pRegList,int nMaxList,int *array_reg,int *sp,int AnswerReg); int array_UseReg[16],sp_UseReg; int array_XmmReg[16]; int sp_XmmReg; int init_sp_reg,init_sp_xmm_reg; public: CRegister(){}; CRegister(int AnswerReg); ~CRegister(){}; //コンパイラにバグがないかをチェックする機構 void bug_check(); //汎用レジスタ int GetNextReg(); int GetLockingReg(); int LockReg(); int UnlockReg(); //XMMレジスタ int GetNextXmmReg(); int GetLockingXmmReg(); int LockXmmReg(); int UnlockXmmReg(); //レジスタが利用中かどうかを調べる bool IsUsing( int reg ); //レジスタのバックアップと復旧 void backup(); void restore(); }; extern CRegister *pobj_reg; #define BACKUP_REGISTER_RESOURCE \ /* レジスタをスタックフレームにバックアップ */ \ pobj_BlockReg->backup(); \ if(pobj_reg) pobj_reg->backup(); \ \ /* レジスタブロッキングオブジェクトを退避して再生成 */ \ CBlockReg *pobj_BlockReg_back; \ pobj_BlockReg_back=pobj_BlockReg; \ pobj_BlockReg=new CBlockReg; \ \ /* レジスタ管理オブジェクトポインタを退避して0をセット */ \ CRegister *pobj_reg_back; \ pobj_reg_back=pobj_reg; \ pobj_reg=0; #define RESTORE_REGISTER_RESOURCE \ /* レジスタブロッキングオブジェクトポインタを復元 */ \ delete pobj_BlockReg; \ pobj_BlockReg=pobj_BlockReg_back; \ \ /* レジスタ管理オブジェクトポインタを復元 */ \ delete pobj_reg; \ pobj_reg=pobj_reg_back; \ \ /* レジスタをスタックフレームから復元 */ \ if(pobj_reg) pobj_reg->restore(); \ pobj_BlockReg->restore(); //MakePeHdr.cpp int AddDataTable(char *buffer,int length); //RSrcSection.cpp char *GetRSrcSectionBuffer(int *pLen); //Compile.cpp void ChangeOpcode(char *Command); void GetGlobalDataForDll(void); DWORD CompileBuffer(char Return_Sequence,WORD Return_Command); //Register.cpp BOOL IsGeneralReg(int reg); BOOL IsXmmReg(int reg); BOOL IsVolatileReg(int reg); //Compile_Calc.cpp void ChangeTypeToDouble_ToFpuReg(int OldType); void ChangeTypeToDouble(int OldType); void ChangeTypeToSingle(int OldType); void ChangeTypeToInt64(int OldType); void ChangeTypeToLong(int OldType); void ChangeTypeToInteger(int OldType); void ChangeTypeToByte(int OldType); void SetVariableFromRax(int VarType,int CalcType,RELATIVE_VAR *pRelativeVar); void OpcodeCalc(char *Command); //NumOpe.cpp int NumOpe(int *pReg,const char *Command,int BaseType,LONG_PTR lpBaseIndex,LONG_PTR *plpIndex,BOOL *pbUseHeap=0); //NumOpe_Arithmetic.cpp BOOL CalcTwoTerm_Arithmetic(int idCalc,int *type,LONG_PTR *index_stack,int *pStackPointer); BOOL Calc_Mod(int *type,LONG_PTR *index_stack,int *pStackPointer); BOOL Calc_Divide(int *type,int *pStackPointer,int BaseType); BOOL Calc_IntDivide(int *type,LONG_PTR *index_stack,int *pStackPointer); BOOL Calc_MinusMark(int *type,int sp); BOOL Calc_Power(int *type,int *pStackPointer); BOOL Calc_Shift(int idCalc,int *type,int *pStackPointer); //NumOpe_Logical.cpp BOOL CalcTwoTerm_Logical(int idCalc,int *type,LONG_PTR *index_stack,int *pStackPointer); BOOL Calc_Not(int *type,int sp); //NumOpe_Relation.cpp BOOL CalcTwoTerm_Relational(int idCalc,int *type,LONG_PTR *index_stack,int *pStackPointer); //NumOpe_TypeOperation.cpp void ExtendTypeTo64(int type,int reg); void ExtendTypeTo32(int type,int reg); void ExtendTypeTo16(int type,int reg); void ChangeTypeToXmm_Double(int type,int xmm_reg,int general_reg); void ChangeTypeToXmm_Single(int type,int xmm_reg,int general_reg); void ChangeTypeToWhole(int OldType,int NewType,int reg,int xmm_reg); void SetOneTermToReg_RealCalc(int TermType,int *pXmmReg); void SetOneTermToReg_Whole64Calc(int TermType,int *pReg); void SetOneTermToReg_Whole32Calc(int TermType,int *pReg); void SetTowTermToReg_RealCalc(int AnswerType,int *type,int sp,int *pXmmReg1,int *pXmmReg2); void SetTowTermToReg_Whole64Calc(int *type,int sp,int *pReg1,int *pReg2); void SetTowTermToReg_Whole32Calc(int *type,int sp,int *pReg1,int *pReg2); BOOL Calc_Cast(int *type,LONG_PTR *index_stack,int *pStackPointer); //Compile_Set_Var.cpp BOOL IsUse_r11(RELATIVE_VAR *pRelativeVar); void SetObjectVariableFromRax(LONG_PTR lpVarIndex,int CalcType,LONG_PTR lpCalcIndex,RELATIVE_VAR *pRelativeVar,BOOL bUseHeap); void SetDoubleVariable(int type,RELATIVE_VAR *pRelative); void SetSingleVariable(int type,RELATIVE_VAR *pRelative); void SetWholeVariable(int var_size,int type,RELATIVE_VAR *pRelative); //increment.cpp void IncDec(int idCalc, char *lpszLeft, char *lpszRight); //calc2.cpp #define EXP_TYPE_NUMBER 1 #define EXP_TYPE_EAX 2 #define EXP_TYPE_FPU 3 #define EXP_TYPE_VAR 4 int NumOpEx(char *Command,double *pDbl,DWORD *pdwType,RELATIVE_VAR *pRelativeVar); //SetVar.cpp BOOL SetVariable(DWORD dwVarType,RELATIVE_VAR *pVarRelativeVar, DWORD dwExpType,DWORD dwType,void *data); //Compile_Calc_PushVar.cpp void SetXmmReg_DoubleVariable(RELATIVE_VAR *pRelativeVar,int xmm_reg); void SetXmmReg_SingleVariable(RELATIVE_VAR *pRelativeVar,int xmm_reg); void SetReg_WholeVariable(int type,RELATIVE_VAR *pRelativeVar,int reg); //Compile_Object.cpp int Operator_New(const char *Parameter,LONG_PTR *plpIndex); void OpcodeDelete(const char *Parameter); //Compile_Var.cpp void GetWithName(char *buffer); void SetThisPtrToReg(int reg); BOOL GetVarOffset(bool isErrorEnabled,bool isWriteAccess,char *NameBuffer,int *pType,RELATIVE_VAR *pRelativeVar,LONG_PTR *plpIndex,int *pss=0); BOOL SetInitGlobalData(int offset,int type,LONG_PTR lpIndex,int *SubScripts,char *InitBuf); #define DIMFLAG_INITDEBUGVAR 1 #define DIMFLAG_NONCALL_CONSTRACTOR 2 #define DIMFLAG_STATIC 4 #define DIMFLAG_CONST 8 void OpcodeDim(char *Parameter,DWORD dwFlag); void SetVarPtrToReg(int reg,RELATIVE_VAR *pRelativeVar); //CParameter.cpp #define OVERLOAD_LEVEL1 1 #define OVERLOAD_LEVEL2 2 #define OVERLOAD_LEVEL3 3 class CParameter{ char *Parms[255]; TYPEINFO types[255]; int ParmsNum; TYPEINFO ReturnTypeInfo; //一時オブジェクト管理用 bool useTempObject; bool useTempParameters[255]; int StackOffsetOfTempObject[255]; public: CParameter(char *buffer); CParameter(PARAMETER_INFO *pParamInfo,int ParmNum); ~CParameter(); void SetReturnType(TYPEINFO *pTypeInfo); private: BOOL _overload_check(PARAMETER_INFO *ppi,int pi_num,TYPEINFO *pReturnTypeInfo,int overload_level); SUBINFO *OverloadSolutionWithReturnType(char *name,SUBINFO **ppsi,int num); public: SUBINFO *OverloadSolution(char *name,SUBINFO **ppsi,int num); BOOL ErrorCheck(char *FuncName,PARAMETER_INFO *ppi,int pi_num,int SecondParmNum); void MacroParameterSupport(PARAMETER_INFO *ppi); void SetObjectParameter(int reg,CClass *pobj_Class,LPSTR Parameter); //一時オブジェクトパラメータの生成と破棄 void NewTempParameters( char *FuncName,PARAMETER_INFO *ppi,int pi_num,int SecondParmNum ); void DeleteTempParameters(); void SetParameter(char *FuncName,PARAMETER_INFO *ppi,int pi_num,int SecondParmNum); void BackupParameter(int pi_num); void RestoreParameter(int pi_num); }; //CLockParameter.cpp #define MAX_LOCKPARMS 255 class CDBLockParms{ public: int array_LevelCount[MAX_LOCKPARMS]; CDBLockParms(); ~CDBLockParms(); void lock(int level); void unlock(int level); }; //Compile_CallProc.cpp void AddLocalVarAddrSchedule(); int CallProc(int idProc,void *pInfo,char *name,char *Parameter,LONG_PTR *plpRetIndex); BOOL CallPropertyMethod(char *variable,char *RightSide,TYPEINFO *pRetTypeInfo); #define PROCFLAG_NEW 1 int Opcode_CallProcPtr(char *variable,char *Parameter,PROCPTRINFO *pi,LONG_PTR *plpIndex); int Opcode_CallProc(char *Parameter,SUBINFO *psi,LONG_PTR *plpIndex,DWORD dwFlags,char *ObjectName,int RefType); int Opcode_CallDllProc(char *Parameter,DECLAREINFO *pdi,LONG_PTR *plpIndex); //Compile_ProcOp.cpp void CompileLocal(); //Compile_Func.cpp int GetFunctionType(int FuncNum); int GetFunctionFromName(char *FuncName); int Opcode_CallFunc(char *Parameter,int FuncNum); //OperatorProc.cpp void FreeTempObject(int reg,CClass *pobj_c); int CallOperatorProc(int idCalc,TYPEINFO *pBaseTypeInfo,int *type,LONG_PTR *index_stack,BOOL *bUseHeap,int &sp); void CallCastOperatorProc(int reg,int &CalcType,LONG_PTR &lpCalcIndex,BOOL bCalcUseHeap,int ToType,LONG_PTR lpToIndex); void CallArrayOperatorProc(int reg,CClass *pobj_Class,char *ObjectName,char *Parameter,TYPEINFO &RetTypeInfo); //Compile_Statement.cpp void OpcodeOthers(char *Command); void OpcodeIf(char *Parameter); void OpcodeGoto(char *Parameter); void OpcodeWhile(char *Parameter); void OpcodeExitWhile(void); void OpcodeFor(char *Parameter); void OpcodeExitFor(void); void OpcodeDo(char *Parameter); void OpcodeExitDo(void); void OpcodeContinue(void); void OpcodeExitSub(void); void OpcodeSelect(char *Parameter); void OpcodeCase(char *Parameter); void OpcodeGosub(char *Parameter); void OpcodeReturn(char *Parameter); void Opcode_Input(char *Parameter); void Opcode_Print(char *Parameter,BOOL bWrite); void OpcodeCallPtr(char *Parameter); void OpcodeSetPtrData(char *Parameter,int type); //InsertOpcode.cpp void InsertDimStatement_ToProcHead(char *lpszCommand); //////////////////////////////// // AMD64機械語生成に利用する関数郡 //////////////////////////////// //Mod(モード) #define MOD_BASE (char)0x00 #define MOD_DISP32 (char)0xFF #define MOD_BASE_DISP8 (char)0x40 #define MOD_BASE_DISP32 (char)0x80 #define MOD_REG (char)0xC0 #define USE_OFFSET 1 #define NON_OFFSET 0 //amd64_main.cpp BOOL IsSafeReg(int reg); void op_push(int reg); void op_push_value(long data); void op_pop(int reg); void op_mov_RV (int op_size,int reg,int i32data); void op_mov_RV64 (int reg,_int64 i64data); void op_mov_RM (int op_size,int reg,int base_reg,int offset,char mod); void op_mov_RM_ex (int op_size,int reg,int base_reg1,int base_reg2,int offset,BOOL bUseOffset); void op_mov_MR (int op_size,int reg,int base_reg,int offset,char mod); void op_mov_MR_ex (int op_size,int reg,int base_reg1,int base_reg2,int offset,BOOL bUseOffset); void op_mov_MV (int op_size,int base_reg,int offset,BOOL bUseOffset,int i32data); void op_mov_RR (int reg1,int reg2); void op_mov64_ToReg (int reg,_int64 i64data); void op_mov64_ToReg (int reg,int i32data); void op_mov64_ToReg_FromReg (int reg1,int reg2); void op_movsxd (int reg64,int reg32); void op_movsx64_FromReg16 (int reg64,int reg16); void op_movsx64_FromReg8 (int reg64,int reg8); void op_movsx32_FromReg16 (int reg32,int reg16); void op_movsx32_FromReg8 (int reg32,int reg8); void op_movsx16_FromReg8 (int reg32,int reg8); void op_inc (int reg); void op_dec (int reg); void op_add_RM (int op_size,int reg,int base_reg,int offset,char mod); void op_add64_value (int reg,int offset); void op_add64_reg (int reg1,int reg2); void op_add32_reg (int reg1,int reg2); void op_sub_RV (int op_size,int reg,int i32data); void op_sub64_reg (int reg1,int reg2); void op_sub32_reg (int reg1,int reg2); void op_imul_reg (int op_size,int reg1,int reg2); void op_imul_value (int op_size,int reg,int i32data); void op_div64_reg (int reg); void op_idiv64_reg (int reg); void op_shl_reg (int op_size,int reg); void op_sar_reg (int op_size,int reg); void op_shr_reg (int op_size,int reg); void op_and_reg (int op_size,int reg1,int reg2); void op_and64_value (int reg,int offset); void op_and32_value (int reg,int offset); void op_or_reg (int op_size,int reg1,int reg2); void op_xor_reg (int op_size,int reg1,int reg2); void op_not_reg (int op_size,int reg); void op_test (int reg1,int reg2); void op_cmp_reg (int op_size,int reg1,int reg2); void op_cmp_value (int op_size,int reg,char byte_data); void op_movlpd_MR (int xmm_reg,int base_reg,int offset,char mod); void op_movlpd_RM (int xmm_reg,int base_reg,int offset,char mod); void op_movsd_RR (int xmm_reg1,int xmm_reg2); void op_movsd_MR (int xmm_reg,int base_reg,int offset,char mod); void op_movss_RR (int xmm_reg1,int xmm_reg2); void op_movss_RM (int xmm_reg,int base_reg,int offset,char mod); void op_movss_MR (int xmm_reg,int base_reg,int offset,char mod); void op_movd_RX (int reg,int xmm_reg); void op_cvtsd2ss (int xmm_reg1,int xmm_reg2); void op_cvtss2sd (int xmm_reg1,int xmm_reg2); void op_cvttsd2si_xmm (int op_size,int reg,int xmm_reg); void op_cvttss2si_xmm (int op_size,int reg,int xmm_reg); void op_cvtsi2sd_reg (int op_size,int xmm_reg,int reg); void op_cvtsi2ss_reg (int op_size,int xmm_reg,int reg); void op_comisd (int xmm_reg1,int xmm_reg2); void op_comiss (int xmm_reg1,int xmm_reg2); void op_rep_movs (int op_size); void op_add_rsp(int num); void op_sub_rsp(int num); void op_add_esp(int num); void op_sub_esp(int num); void op_fld_ptr_esp(int type); void op_zero_reg(int reg); void op_call( SUBINFO *psi ); void op_call( DECLAREINFO *pdi );