source: dev/BasicCompiler64/Compile_Func.cpp@ 73

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

Parameterクラスを適用。32bit側は動くようになったので、64bitのほうを調整する。

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