source: dev/BasicCompiler64/Compile_Func.cpp@ 75

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

TYPEINFO→Typeへのリファクタリングを実施。64bitはほぼ完了。32bitが全般的に未完成。

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