source: dev/BasicCompiler64/Compile_Func.cpp@ 76

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

TYPEINFO→Typeへのリファクタリングを実施。32bitが未完成。

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