source: dev/trunk/abdev/BasicCompiler64/Compile_Func.cpp@ 183

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