source: dev/trunk/abdev/BasicCompiler32/Compile_Func.cpp@ 288

Last change on this file since 288 was 265, checked in by dai_9181, 17 years ago
File size: 12.6 KB
RevLine 
[206]1#include "stdafx.h"
2
[183]3#include <jenga/include/smoothie/Smoothie.h>
4
[193]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,"CUDbl")==0) return FUNC_CUDBL;
12 if(lstrcmpi(FuncName,"Fix")==0) return FUNC_FIX;
13 if(lstrcmpi(FuncName,"Len")==0) return FUNC_LEN;
14 if(lstrcmpi(FuncName,"AddressOf")==0) return FUNC_ADDRESSOF;
15 if(lstrcmpi(FuncName,"SizeOf")==0) return FUNC_SIZEOF;
16 if(lstrcmpi(FuncName,"VarPtr")==0) return FUNC_VARPTR;
[109]17 if(lstrcmpi(FuncName,"ObjPtr")==0) return FUNC_OBJPTR;
[3]18 if(lstrcmpi(FuncName,"GetDouble")==0) return FUNC_GETDOUBLE;
19 if(lstrcmpi(FuncName,"GetSingle")==0) return FUNC_GETSINGLE;
20 if(lstrcmpi(FuncName,"GetQWord")==0) return FUNC_GETQWORD;
21 if(lstrcmpi(FuncName,"GetDWord")==0) return FUNC_GETDWORD;
22 if(lstrcmpi(FuncName,"GetWord")==0) return FUNC_GETWORD;
23 if(lstrcmpi(FuncName,"GetByte")==0) return FUNC_GETBYTE;
24 return 0;
25}
26
[76]27void Opcode_Func_Fix(const char *lpszParms){
28 Type resultType;
29 if( !NumOpe( lpszParms, Type(), resultType ) ){
30 return;
31 }
[3]32
[76]33 if( resultType.IsDouble() ){
[3]34 //fld qword ptr[esp]
[225]35 compiler.codeGenerator.op_fld_ptr_esp(DEF_DOUBLE);
[3]36
37 //fnstcw word ptr[esp]
[250]38 compiler.codeGenerator.PutOld(
39 (char)0xD9,
40 (char)0x3C,
41 (char)0x24
42 );
[3]43
44 //mov ax,word ptr[esp]
[250]45 compiler.codeGenerator.op_mov_RM( sizeof(short), REG_EAX, REG_ESP, 0, MOD_BASE );
[3]46
47 //or ah,0Ch
[250]48 compiler.codeGenerator.PutOld(
49 (char)0x80,
50 (char)0xCC,
51 (char)0x0C
52 );
[3]53
54 //mov word ptr[esp-2],ax
[250]55 compiler.codeGenerator.op_mov_MR( sizeof(short), REG_EAX, REG_ESP, -2, MOD_BASE_DISP8 );
[3]56
57 //fldcw word ptr[esp-2]
[250]58 compiler.codeGenerator.PutOld(
59 (char)0xD9,
60 (char)0x6C,
61 (char)0x24,
62 (char)0xFE
63 );
[3]64
65 //fistp dword ptr[esp+4]
[250]66 compiler.codeGenerator.PutOld(
67 (char)0xDB,
68 (char)0x5C,
69 (char)0x24,
70 (char)0x04
71 );
[3]72
73 //fldcw word ptr[esp]
[250]74 compiler.codeGenerator.PutOld(
75 (char)0xD9,
76 (char)0x2C,
77 (char)0x24
78 );
[3]79
80 //add esp,4
[225]81 compiler.codeGenerator.op_add_esp(4);
[3]82 }
[76]83 else if( resultType.IsSingle() ){
[3]84 //fld dword ptr[esp]
[225]85 compiler.codeGenerator.op_fld_ptr_esp(DEF_SINGLE);
[3]86
87 //sub esp,4
[225]88 compiler.codeGenerator.op_sub_esp(4);
[3]89
90 //fnstcw word ptr[esp]
[250]91 compiler.codeGenerator.PutOld(
92 (char)0xD9,
93 (char)0x3C,
94 (char)0x24
95 );
[3]96
97 //mov ax,word ptr[esp]
[250]98 compiler.codeGenerator.op_mov_RM( sizeof(short), REG_EAX, REG_ESP, 0, MOD_BASE );
[3]99
100 //or ah,0Ch
[250]101 compiler.codeGenerator.PutOld(
102 (char)0x80,
103 (char)0xCC,
104 (char)0x0C
105 );
[3]106
107 //mov word ptr[esp-2],ax
[250]108 compiler.codeGenerator.op_mov_MR( sizeof(short), REG_EAX, REG_ESP, -2, MOD_BASE_DISP8 );
[3]109
110 //fldcw word ptr[esp-2]
[250]111 compiler.codeGenerator.PutOld(
112 (char)0xD9,
113 (char)0x6C,
114 (char)0x24,
115 (char)0xFE
116 );
[3]117
118 //fistp dword ptr[esp+4]
[250]119 compiler.codeGenerator.PutOld(
120 (char)0xDB,
121 (char)0x5C,
122 (char)0x24,
123 (char)0x04
124 );
[3]125
126 //fldcw word ptr[esp]
[250]127 compiler.codeGenerator.PutOld(
128 (char)0xD9,
129 (char)0x2C,
130 (char)0x24
131 );
[3]132
133 //add esp,4
[225]134 compiler.codeGenerator.op_add_esp(4);
[3]135 }
[76]136 else if( resultType.Is64() ){
[3]137 //pop eax
[225]138 compiler.codeGenerator.op_pop(REG_EAX);
[3]139
140 //add esp,4
[225]141 compiler.codeGenerator.op_add_esp(4);
[3]142
143 //push eax
[225]144 compiler.codeGenerator.op_push(REG_EAX);
[3]145 }
146
147 //pop eax
[225]148 compiler.codeGenerator.op_pop(REG_EAX);
[3]149}
150
[46]151void Opcode_Func_CUDbl(const char *Parameter){
[76]152 Type resultType;
153 if( !NumOpe(Parameter,Type(),resultType) ){
154 return;
155 }
156 ChangeTypeToLong(resultType.GetBasicType());
[3]157
158 //pop eax
[225]159 compiler.codeGenerator.op_pop(REG_EAX);
[3]160
161 //push 0
[235]162 compiler.codeGenerator.op_push_V( 0 );
[3]163
164 //push eax
[225]165 compiler.codeGenerator.op_push(REG_EAX);
[3]166
167 //fild qword ptr[esp]
[235]168 compiler.codeGenerator.op_fld_ptr_esp(DEF_INT64);
[3]169
170 //add esp,8
[225]171 compiler.codeGenerator.op_add_esp(8);
[3]172}
[46]173void Opcode_Func_Len(const char *Parameter){
[3]174 BOOL bArrayHead;
175
[46]176 const char *tempParm=Parameter;
[3]177 char temporary[VN_SIZE];
178 char temp2[32];
[76]179 Type type;
180 if( !GetVarType(Parameter,type,0) ){
[3]181 sprintf(temporary,"_System_DummyStr2=%s",Parameter);
182 OpcodeCalc(temporary);
183
184 lstrcpy(temp2,"_System_DummyStr2");
185 tempParm=temp2;
186
[265]187 type.SetType( DEF_OBJECT, compiler.GetObjectModule().meta.GetClasses().GetStringClassPtr() );
[3]188 }
189
[97]190 if( type.IsStringClass() ){
[3]191 //Stringオブジェクトの場合
192 sprintf(temporary,"%s.Length",tempParm);
193
[76]194 int reg=REG_RAX;
195 NumOpe(temporary,Type(),Type());
[3]196
197 //pop eax
[225]198 compiler.codeGenerator.op_pop(REG_EAX);
[3]199
200 return;
201 }
202
[206]203 Subscripts subscripts;
[3]204 RELATIVE_VAR RelativeVar;
[206]205 if(!GetVarOffsetReadOnly(tempParm,&RelativeVar,type,&subscripts)) return;
[3]206
[76]207 if(type.GetBasicType()&FLAG_PTR){
208 type.SetBasicType( type.GetBasicType() & ( ~FLAG_PTR ) );
[3]209
210 bArrayHead=1;
211 }
212 else bArrayHead=0;
213
[76]214 int typeSize = type.GetSize();
[3]215
[206]216 if(bArrayHead) typeSize*=JumpSubScripts(subscripts);
[3]217
[235]218 //mov eax,typeSize
219 compiler.codeGenerator.op_mov_RV( REG_EAX, typeSize );
[3]220}
[76]221void Opcode_Func_AddressOf( const char *name ){
[3]222 extern int cp;
[206]223 const UserProc *pUserProc;
[3]224
225 extern LONG_PTR ProcPtr_BaseIndex;
226 if(ProcPtr_BaseIndex!=-1){
227 //左辺の型にのっとり、オーバーロードを解決
228
[206]229 std::vector<const UserProc *> subs;
[50]230 GetOverloadSubHash( name, subs );
231 if( subs.size() == 0 ){
[3]232 SetError(27,name,cp);
233 return;
234 }
235
236 //オーバーロードを解決
[265]237 pUserProc=OverloadSolution(name,subs,compiler.GetObjectModule().meta.GetProcPointers()[ProcPtr_BaseIndex]->Params(), Type() );
[3]238
[75]239 if(!pUserProc){
[3]240 SetError(27,name,cp);
241 return;
242 }
243 }
244 else{
[75]245 pUserProc=GetSubHash(name);
246 if(!pUserProc){
[3]247 SetError(27,name,cp);
248 return;
249 }
250 }
251
[75]252 if( pUserProc->IsVirtual() ){
[3]253 ///////////////////////////////
254 // 仮想関数の場合
255 // thisポインタをrcxにコピー
256 ///////////////////////////////
257
[114]258 const CClass *pobj_c;
[3]259
260 char ObjectName[VN_SIZE];
261 int RefType;
[28]262 SplitObjectName(name,ObjectName,&RefType);
[3]263
264 if(ObjectName[0]){
265 if(lstrcmpi(ObjectName,"Super")==0) goto InClassMember;
266 else{
267 RELATIVE_VAR RelativeVar;
[76]268 Type type;
269 if(!GetVarOffsetReadOnly(ObjectName,&RelativeVar,type)) return;
[3]270 SetVarPtrToEax(&RelativeVar);
271
272 //mov ecx,eax
[225]273 compiler.codeGenerator.op_mov_RR(REG_ECX,REG_EAX);
[3]274
275 //参照タイプが整合しているかをチェック
[76]276 if(type.GetBasicType()!=RefType) SetError(104,ObjectName,cp);
[3]277
[76]278 if(type.IsObjectPtr()){
[3]279 //mov ecx,dword ptr[ecx]
[225]280 compiler.codeGenerator.op_mov_RM(sizeof(long),REG_ECX,REG_ECX,0,MOD_BASE);
[3]281 }
282 }
283 }
284 else{
285InClassMember:
286 //自身のオブジェクトのThisポインタをrcxにコピー
287 SetThisPtrToReg(REG_RCX);
288
[206]289 pobj_c=compiler.pCompilingClass;
[3]290 }
291
292
293 //仮想関数(オブジェクトメソッド)
294 //pObj->func_table->func1
295 // ->func2
296 // ->func3
297
298 //mov edx,dword ptr[ecx]
[235]299 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EDX, REG_ECX, 0, MOD_BASE );
[3]300
[75]301 int i2 = pobj_c->GetFuncNumInVtbl( pUserProc );
[3]302
303 //mov eax,dword ptr[edx+func_index]
304 if(i2*PTR_SIZE<=0x7F){
[225]305 compiler.codeGenerator.op_mov_RM(sizeof(long),REG_EAX,REG_EDX,i2*PTR_SIZE,MOD_BASE_DISP8);
[3]306 }
307 else{
[225]308 compiler.codeGenerator.op_mov_RM(sizeof(long),REG_EAX,REG_EDX,i2*PTR_SIZE,MOD_BASE_DISP32);
[3]309 }
310 }
311 else{
312 //一般の関数
313
314 //mov eax,ProcAddr
[250]315 compiler.codeGenerator.op_addressof( REG_EAX, pUserProc );
[3]316 }
317
[75]318 pUserProc->Using();
[3]319}
[79]320void Opcode_Func_SizeOf( const string &typeName ){
321 Type tempType;
[193]322 if( !Compiler::StringToType( typeName, tempType ) ){
[79]323 SetError(3,typeName,cp);
324 return;
[3]325 }
326
[79]327 int typeSize = ( tempType.IsObject() ) ?
328 tempType.GetClass().GetSize() : tempType.GetSize();
329
[3]330 //mov eax,size
[225]331 compiler.codeGenerator.op_mov_RV( REG_EAX, typeSize );
[3]332}
[76]333void Opcode_Func_VarPtr( const char *Parameter, Type &resultType, bool isCallOn ){
334 if( isCallOn == false ){
335 // 戻り値の型を取得するだけ
336
337 //変数のアドレスを取得
338 if(!GetVarType( Parameter, resultType, true )) return;
339
340 resultType.PtrLevelUp();
341
342 return;
343 }
344
[3]345 RELATIVE_VAR RelativeVar;
346
347 //変数のアドレスを取得
[76]348 if(!GetVarOffsetReadOnly( Parameter, &RelativeVar, resultType )) return;
[3]349
[76]350 int beforeType = resultType.GetBasicType();
[64]351
[76]352 resultType.PtrLevelUp();
[46]353
[3]354 SetVarPtrToEax(&RelativeVar);
[64]355
[109]356 // TODO: 取り除く(この動きはObjPtrに託す)
[130]357 /*
[64]358 if( beforeType == DEF_OBJECT && lstrcmpi( Parameter, "This" ) != 0 ){
359 //参照をオブジェクトポインタに変更
360
361 //mov eax,dword ptr[eax]
[225]362 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EAX, REG_EAX, 0, MOD_BASE );
[110]363
364 SetError(-120,NULL,cp);
[130]365 }*/
[3]366}
[109]367void Opcode_Func_ObjPtr( const char *Parameter, Type &resultType, bool isCallOn ){
368 if( isCallOn == false ){
369 // 戻り値の型を取得するだけ
370
371 //変数のアドレスを取得
372 if(!GetVarType( Parameter, resultType, true )) return;
373
374 resultType.PtrLevelUp();
375
376 return;
377 }
378
379 RELATIVE_VAR RelativeVar;
380
381 //変数のアドレスを取得
382 if(!GetVarOffsetReadOnly( Parameter, &RelativeVar, resultType )) return;
383
384 int beforeType = resultType.GetBasicType();
385
386 resultType.PtrLevelUp();
387
388 SetVarPtrToEax(&RelativeVar);
389
[111]390 if( lstrcmpi( Parameter, "This" )==0 ){
391 // Thisの場合は特別にオブジェクトポインタが返ってくるので、何もせずに抜ける
392 }
393 else if( beforeType == DEF_OBJECT ){
[109]394 //参照をオブジェクトポインタに変更
395
396 //mov eax,dword ptr[eax]
[225]397 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EAX, REG_EAX, 0, MOD_BASE );
[109]398 }
399 else{
400 SetError(134,NULL,cp );
401 }
402}
[46]403void Opcode_Func_GetPtrData(const char *Parameter,const int type){
[76]404 Type tempType;
405 if( !NumOpe(Parameter,Type(),tempType) ){
406 return;
407 }
408 if(!tempType.IsWhole()){
409 SetError(11,Parameter,cp);
410 return;
411 }
412 ChangeTypeToLong(tempType.GetBasicType());
[3]413
414 if(type==DEF_DOUBLE){
415 //pop eax
[225]416 compiler.codeGenerator.op_pop(REG_EAX);
[3]417
418 //fld qword ptr[eax]
[235]419 compiler.codeGenerator.PutOld(
420 (char)0xDD,
421 (char)0x00
422 );
[3]423 }
424 else if(type==DEF_SINGLE||type==DEF_DWORD){
425 //pop eax
[225]426 compiler.codeGenerator.op_pop(REG_EAX);
[3]427
428 //mov eax,dword ptr[eax]
[235]429 compiler.codeGenerator.op_mov_RM( sizeof(long), REG_EAX, REG_EAX, 0, MOD_BASE );
[3]430 }
431 else if(type==DEF_QWORD){
432 //pop ecx
[225]433 compiler.codeGenerator.op_pop(REG_ECX);
[3]434
435 //mov eax,dword ptr[ecx]
[225]436 compiler.codeGenerator.op_mov_RM(sizeof(long),REG_EAX,REG_ECX,0,MOD_BASE);
[3]437
438 //mov edx,dword ptr[ecx+sizeof(long)]
[225]439 compiler.codeGenerator.op_mov_RM(sizeof(long),REG_EDX,REG_ECX,sizeof(long),MOD_BASE_DISP8);
[3]440 }
441 else if(type==DEF_WORD){
442 //pop ebx
[225]443 compiler.codeGenerator.op_pop(REG_EBX);
[3]444
445 //xor eax,eax
[227]446 compiler.codeGenerator.op_xor_RR(REG_EAX);
[3]447
448 //mov ax,word ptr[ebx]
[235]449 compiler.codeGenerator.op_mov_RM( sizeof(short), REG_EAX, REG_EBX, 0, MOD_BASE );
[3]450 }
451 else if(type==DEF_BYTE){
452 //pop ebx
[225]453 compiler.codeGenerator.op_pop(REG_EBX);
[3]454
455 //xor eax,eax
[227]456 compiler.codeGenerator.op_xor_RR(REG_EAX);
[3]457
458 //mov al,byte ptr[ebx]
[235]459 compiler.codeGenerator.op_mov_RM( sizeof(char), REG_EAX, REG_EBX, 0, MOD_BASE );
[3]460 }
461}
462
[76]463bool Opcode_CallFunc( const char *Parameter, const int FuncNum, Type &resultType, bool isCallOn ){
[3]464 switch(FuncNum){
465 case FUNC_FIX:
[76]466 if( isCallOn ) Opcode_Func_Fix(Parameter);
467 resultType.SetBasicType( DEF_LONG );
[46]468 break;
[3]469 case FUNC_CUDBL:
[76]470 if( isCallOn ) Opcode_Func_CUDbl(Parameter);
471 resultType.SetBasicType( DEF_DOUBLE );
[46]472 break;
[3]473 case FUNC_LEN:
[76]474 if( isCallOn ) Opcode_Func_Len(Parameter);
475 resultType.SetBasicType( DEF_LONG );
[46]476 break;
[3]477 case FUNC_ADDRESSOF:
[76]478 if( isCallOn ) Opcode_Func_AddressOf(Parameter);
479 resultType.SetBasicType( DEF_PTR_VOID );
[46]480 break;
[3]481 case FUNC_SIZEOF:
[76]482 if( isCallOn ) Opcode_Func_SizeOf(Parameter);
483 resultType.SetBasicType( DEF_LONG );
[46]484 break;
[3]485 case FUNC_VARPTR:
[76]486 Opcode_Func_VarPtr( Parameter, resultType, isCallOn );
[46]487 break;
[109]488 case FUNC_OBJPTR:
489 Opcode_Func_ObjPtr( Parameter, resultType, isCallOn );
490 break;
[3]491
492 case FUNC_GETDOUBLE:
[76]493 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_DOUBLE);
494 resultType.SetBasicType( DEF_DOUBLE );
[46]495 break;
[3]496 case FUNC_GETSINGLE:
[76]497 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_SINGLE);
498 resultType.SetBasicType( DEF_SINGLE );
[46]499 break;
[3]500 case FUNC_GETQWORD:
[76]501 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_QWORD);
502 resultType.SetBasicType( DEF_QWORD );
[46]503 break;
[3]504 case FUNC_GETDWORD:
[76]505 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_DWORD);
506 resultType.SetBasicType( DEF_DWORD );
[46]507 break;
[3]508 case FUNC_GETWORD:
[76]509 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_WORD);
510 resultType.SetBasicType( DEF_WORD );
[46]511 break;
[3]512 case FUNC_GETBYTE:
[76]513 if( isCallOn ) Opcode_Func_GetPtrData(Parameter,DEF_BYTE);
514 resultType.SetBasicType( DEF_BYTE );
[46]515 break;
[76]516 default:
517 return false;
[3]518 }
[76]519 return true;
[3]520}
Note: See TracBrowser for help on using the repository browser.