source: dev/BasicCompiler64/Compile_Func.cpp@ 78

Last change on this file since 78 was 78, checked in by dai_9181, 17 years ago

CTypeDef → TypeDef
Houseクラスを追加。
オーバーロードレベルの種類を追加(レベル1に挿入)

File size: 7.5 KB
RevLine 
[3]1#include "../BasicCompiler_Common/common.h"
2#include "Opcode.h"
3
4int GetFunctionType(int FuncNum){
5 switch(FuncNum){
6 case FUNC_LEN:
7 return DEF_LONG;
8 case FUNC_SIZEOF:
9 return DEF_LONG;
10 case FUNC_ADDRESSOF:
11 case FUNC_VARPTR:
12 return DEF_PTR_VOID;
13 case FUNC_GETDOUBLE:
14 return DEF_DOUBLE;
15 case FUNC_GETSINGLE:
16 return DEF_SINGLE;
17 case FUNC_GETQWORD:
18 return DEF_QWORD;
19 case FUNC_GETDWORD:
20 return DEF_DWORD;
21 case FUNC_GETWORD:
22 return DEF_WORD;
23 case FUNC_GETBYTE:
24 return DEF_BYTE;
25 }
26 return 0;
27}
28int GetFunctionFromName(char *FuncName){
29 if(lstrcmpi(FuncName,"Len")==0) return FUNC_LEN;
30 if(lstrcmpi(FuncName,"AddressOf")==0) return FUNC_ADDRESSOF;
31 if(lstrcmpi(FuncName,"SizeOf")==0) return FUNC_SIZEOF;
32 if(lstrcmpi(FuncName,"VarPtr")==0) return FUNC_VARPTR;
33 if(lstrcmpi(FuncName,"GetDouble")==0) return FUNC_GETDOUBLE;
34 if(lstrcmpi(FuncName,"GetSingle")==0) return FUNC_GETSINGLE;
35 if(lstrcmpi(FuncName,"GetQWord")==0) return FUNC_GETQWORD;
36 if(lstrcmpi(FuncName,"GetDWord")==0) return FUNC_GETDWORD;
37 if(lstrcmpi(FuncName,"GetWord")==0) return FUNC_GETWORD;
38 if(lstrcmpi(FuncName,"GetByte")==0) return FUNC_GETBYTE;
39 return 0;
40}
[46]41void Opcode_Func_Len( const char *Parameter ){
[3]42 BOOL bArrayHead;
43
[46]44 const char *tempParm=Parameter;
[3]45 char temporary[VN_SIZE];
46 char temp2[32];
[75]47 Type type;
48 if( !GetVarType(Parameter,type,0) ){
[3]49 sprintf(temporary,"_System_DummyStr2=%s",Parameter);
50 OpcodeCalc(temporary);
51
52 lstrcpy(temp2,"_System_DummyStr2");
53 tempParm=temp2;
54
55 extern CClass *pobj_StringClass;
[75]56 type.SetType( DEF_OBJECT, pobj_StringClass );
[3]57 }
58
[75]59 if( type.IsStringObject() ){
[3]60 //Stringオブジェクトの場合
61 sprintf(temporary,"%s.Length",tempParm);
62
63 int reg=REG_RAX;
[76]64 NumOpe(&reg,temporary,Type(),Type());
[3]65 return;
66 }
67
68 int SubScripts[MAX_ARRAYDIM];
69 RELATIVE_VAR RelativeVar;
[75]70 if(!GetVarOffsetReadOnly(tempParm,&RelativeVar,type,SubScripts)) return;
[3]71
[75]72 if(type.GetBasicType()&FLAG_PTR){
73 type.SetBasicType( type.GetBasicType() & ( ~FLAG_PTR ) );
[3]74
75 bArrayHead=1;
76 }
77 else bArrayHead=0;
78
[75]79 int typeSize = type.GetSize();
[3]80
[75]81 if(bArrayHead) typeSize*=JumpSubScripts(SubScripts);
[3]82
83 //mov rax,TypeSize
[75]84 op_mov_RV(sizeof(_int64),REG_RAX,typeSize);
[3]85
86 return;
87}
[46]88void Opcode_Func_AddressOf( const char *name ){
[3]89 extern int cp;
[75]90 UserProc *pUserProc;
[3]91
92 extern LONG_PTR ProcPtr_BaseIndex;
93 if(ProcPtr_BaseIndex!=-1){
94 //左辺の型にのっとり、オーバーロードを解決
95
[75]96 std::vector<UserProc *> subs;
[50]97 GetOverloadSubHash( name, subs );
98 if( subs.size() == 0 ){
[3]99 SetError(27,name,cp);
100 return;
101 }
102
103 //オーバーロードを解決
[78]104 pUserProc=OverloadSolution(name,subs,House::procPointers[ProcPtr_BaseIndex]->Params(), Type() );
[3]105
[75]106 if(!pUserProc){
[3]107 SetError(27,name,cp);
108 return;
109 }
110 }
111 else{
[75]112 pUserProc=GetSubHash(name);
113 if(!pUserProc){
[3]114 SetError(27,name,cp);
115 return;
116 }
117 }
118
[75]119 if( pUserProc->IsVirtual() ){
[3]120 ///////////////////////////////
121 // 仮想関数の場合
122 // thisポインタをrcxにコピー
123 ///////////////////////////////
124
125 CClass *pobj_c;
126
127 char ObjectName[VN_SIZE];
128 int RefType;
[28]129 SplitObjectName(name,ObjectName,&RefType);
[3]130
131 if(ObjectName[0]){
132 if(lstrcmpi(ObjectName,"Super")==0) goto InClassMember;
133 else{
134 RELATIVE_VAR RelativeVar;
[75]135 Type type;
136 if(!GetVarOffsetReadOnly(ObjectName,&RelativeVar,type)) return;
[3]137 SetVarPtrToReg(REG_RCX,&RelativeVar);
138
139 //参照タイプが整合しているかをチェック
[75]140 if(type.GetBasicType()!=RefType) SetError(104,ObjectName,cp);
[3]141
[75]142 if(type.IsObjectPtr()){
[3]143 //mov rcx,qword ptr[rcx]
144 op_mov_RM(sizeof(_int64),REG_RCX,REG_RCX,0,MOD_BASE);
145 }
146 }
147 }
148 else{
149InClassMember:
150 //自身のオブジェクトのThisポインタをrcxにコピー
151 SetThisPtrToReg(REG_RCX);
152
153 pobj_c=pobj_CompilingClass;
154 }
155
156
157 //仮想関数(オブジェクトメソッド)
158 //pObj->func_table->func1
159 // ->func2
160 // ->func3
161
162 //mov r11,qword ptr[rcx]
163 op_mov_RM(sizeof(_int64),REG_R11,REG_RCX,0,MOD_BASE);
164
[75]165 int i2 = pobj_c->GetFuncNumInVtbl( pUserProc );
[3]166
167 //mov rax,qword ptr[r11+func_index]
168 if(i2*PTR_SIZE<=0x7F){
169 op_mov_RM(sizeof(_int64),REG_RAX,REG_R11,i2*PTR_SIZE,MOD_BASE_DISP8);
170 }
171 else{
172 op_mov_RM(sizeof(_int64),REG_RAX,REG_R11,i2*PTR_SIZE,MOD_BASE_DISP32);
173 }
174 }
175 else{
176 //一般の関数
177
178 //mov rax,ProcAddr
179 op_mov_RV(sizeof(_int64),REG_RAX,0);
180 obp-=sizeof(long);
[75]181 pobj_SubAddrSchedule->add(pUserProc,0);
[3]182 obp+=sizeof(long);
183 }
184
[75]185 pUserProc->Using();
[3]186}
[46]187void Opcode_Func_SizeOf( const char *Parameter ){
[3]188 LONG_PTR lpIndex;
[64]189 int type = GetTypeFixed(Parameter,&lpIndex);
[3]190
[64]191 int size;
192 if( type == DEF_OBJECT ){
193 CClass *pClass = (CClass *)lpIndex;
194 size = pClass->GetSize();
195 }
196 else{
197 size=GetTypeSize(type,lpIndex);
198 }
[3]199
200 //mov rax,size
201 op_mov_RV(sizeof(_int64),REG_RAX,size);
202}
[75]203void Opcode_Func_VarPtr( const char *Parameter, Type &resultType, bool isCallOn ){
204 if( isCallOn == false ){
205 // 戻り値の型を取得するだけ
206
207 //変数のアドレスを取得
208 if(!GetVarType( Parameter, resultType, true )) return;
209
210 resultType.PtrLevelUp();
211
212 return;
213 }
214
[3]215 RELATIVE_VAR RelativeVar;
216
217 //変数のアドレスを取得
[75]218 if(!GetVarOffsetReadOnly( Parameter, &RelativeVar, resultType )) return;
[3]219
[75]220 int beforeType = resultType.GetBasicType();
[64]221
[75]222 resultType.PtrLevelUp();
[46]223
[3]224 SetVarPtrToReg(REG_RAX,&RelativeVar);
[64]225
226 if( beforeType == DEF_OBJECT && lstrcmpi( Parameter, "This" ) != 0 ){
227 //参照をオブジェクトポインタに変更
228
229 //mov rax,qword ptr[rax]
230 op_mov_RM( sizeof(_int64), REG_RAX, REG_RAX, 0, MOD_BASE );
231 }
[3]232}
[46]233void Opcode_Func_GetPtrData( const char *Parameter, const int type ){
[3]234 int reg=REG_RAX;
[75]235 Type tempType;
236 if( !NumOpe(&reg,Parameter,Type(),tempType) ){
237 return;
238 }
239 if(!tempType.IsWhole()){
[3]240 SetError(11,Parameter,cp);
241 return;
242 }
243
244 if(type==DEF_DOUBLE){
245 //movlpd xmm0,qword ptr[rax]
246 op_movlpd_RM(REG_XMM0,REG_RAX,0,MOD_BASE);
247 }
248 else if(type==DEF_SINGLE){
249 //movss xmm0,dword ptr[rax]
250 op_movss_RM(REG_XMM0,REG_RAX,0,MOD_BASE);
251 }
252 else{
253 //mov rax,ptr[rax]
254 op_mov_RM(GetTypeSize(type,-1),REG_RAX,REG_RAX,0,MOD_BASE);
255 }
256}
257
[75]258bool Opcode_CallFunc( const char *Parameter, const int FuncNum, Type &resultType, bool isCallOn ){
[3]259 switch(FuncNum){
260 case FUNC_LEN:
[75]261 if( isCallOn ) Opcode_Func_Len(Parameter);
262 resultType.SetBasicType( DEF_LONG );
[46]263 break;
[3]264 case FUNC_ADDRESSOF:
[75]265 if( isCallOn ) Opcode_Func_AddressOf(Parameter);
266 resultType.SetBasicType( DEF_PTR_VOID );
[46]267 break;
[3]268 case FUNC_SIZEOF:
[75]269 if( isCallOn ) Opcode_Func_SizeOf(Parameter);
270 resultType.SetBasicType( DEF_LONG );
[46]271 break;
[3]272 case FUNC_VARPTR:
[75]273 Opcode_Func_VarPtr( Parameter, resultType, isCallOn );
[46]274 break;
[3]275
276 case FUNC_GETDOUBLE:
[75]277 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_DOUBLE);
278 resultType.SetBasicType( DEF_DOUBLE );
[46]279 break;
[3]280 case FUNC_GETSINGLE:
[75]281 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_SINGLE);
282 resultType.SetBasicType( DEF_SINGLE );
[46]283 break;
[3]284 case FUNC_GETQWORD:
[75]285 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_QWORD);
286 resultType.SetBasicType( DEF_QWORD );
[46]287 break;
[3]288 case FUNC_GETDWORD:
[75]289 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_DWORD);
290 resultType.SetBasicType( DEF_DWORD );
[46]291 break;
[3]292 case FUNC_GETWORD:
[75]293 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_WORD);
294 resultType.SetBasicType( DEF_WORD );
[46]295 break;
[3]296 case FUNC_GETBYTE:
[75]297 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_BYTE);
298 resultType.SetBasicType( DEF_BYTE );
[46]299 break;
[75]300 default:
301 return false;
[3]302 }
[75]303 return true;
[3]304}
Note: See TracBrowser for help on using the repository browser.