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

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

静的リンクライブラリにより、複数のグローバル領域が存在することになったのでそれぞれを関数ベースに分けた

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