source: dev/BasicCompiler64/CParameter.cpp@ 71

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

Parameter.cpp→ParamImpl.cpp
CParameter→ParamImpl

Type.cpp、Type.hを用意した。

File size: 13.8 KB
Line 
1#include "../BasicCompiler_Common/common.h"
2#include "opcode.h"
3
4int ParamImpl::NewTempParameters( const char *FuncName,PARAMETER_INFO *ppi,int pi_num,int SecondParmNum ){
5 ///////////////////////////////////////////////////////
6 // 一時オブジェクトをあらかじめスタックに積んでおく
7 ///////////////////////////////////////////////////////
8
9 int stackItemNum = 0;
10
11 useTempObject = false;
12
13 BOOL bEllipse;
14 if(pi_num){
15 if(ppi[pi_num-1].type==DEF_ELLIPSE) bEllipse=1;
16 else bEllipse=0;
17 }
18 else bEllipse=0;
19
20 for(int i2=ParmsNum-1;i2>=0;i2--){
21 useTempParameters[i2] = false;
22
23 if(bEllipse&&i2<=pi_num-2) bEllipse=0;
24
25 if(i2==0&&ppi[i2].name){
26 if(lstrcmp(ppi[i2].name,"_System_LocalThis")==0){
27 //オブジェクトメンバの第一パラメータのThisポインタ
28 continue;
29 }
30 }
31 if((i2==0||i2==1)&&ppi[i2].name){
32 if(lstrcmp(ppi[i2].name,FuncName)==0){
33 //オブジェクトメンバの第一または第二パラメータの戻り値用オブジェクト
34 continue;
35 }
36 }
37
38 TYPEINFO DummyTypeInfo;
39 BOOL bByVal;
40 if(bEllipse){
41 DummyTypeInfo.type=NumOpe_GetType(Parms[i2],NULL,&DummyTypeInfo.u.lpIndex);
42 bByVal=1;
43 }
44 else{
45 DummyTypeInfo.type=ppi[i2].type;
46 DummyTypeInfo.u.lpIndex=ppi[i2].u.index;
47 bByVal=ppi[i2].bByVal;
48 }
49
50
51 if( !bByVal ){
52 //ポインタ参照
53 if(Parms[i2][0]==1&&Parms[i2][1]==ESC_BYVAL){
54 //ポインタ指定
55 continue;
56 }
57
58 LONG_PTR lpVarIndex;
59 if( GetVarType( Parms[i2], &lpVarIndex, FALSE ) == -1 ){
60 //変数ではないとき
61 int reg = REG_RAX;
62 int type = NumOpe( &reg, Parms[i2], DummyTypeInfo.type, DummyTypeInfo.u.lpIndex, &lpVarIndex );
63
64 if( type != DEF_STRUCT ){
65 //一時参照を作成
66 pobj_sf->push( reg );
67 pobj_sf->mov_sp( reg );
68
69 stackItemNum++;
70 }
71
72 //スタックフレームへコピー
73 StackOffsetOfTempObject[i2] = pobj_sf->push(reg);
74
75 stackItemNum++;
76
77 bool result = CheckDifferentType(
78 DummyTypeInfo.type,
79 DummyTypeInfo.u.lpIndex,
80 type,
81 lpVarIndex,
82 FuncName,
83 i2);
84
85 if( result ){
86 useTempParameters[i2] = true;
87 useTempObject = true;
88
89 types[i2].type = type;
90 types[i2].u.lpIndex = lpVarIndex;
91 }
92 }
93 }
94 }
95
96 return stackItemNum * PTR_SIZE;
97}
98void ParamImpl::DeleteTempParameters(){
99 ///////////////////////////////////////////////////////
100 // 一時オブジェクトを破棄
101 ///////////////////////////////////////////////////////
102 if( !useTempObject ) return;
103
104 for(int i2=ParmsNum-1;i2>=0;i2--){
105 if( useTempParameters[i2] ){
106 if( types[i2].type == DEF_STRUCT ){
107 // 構造体の一時メモリ
108
109 //メモリを解放する
110
111 pobj_sf->pop( REG_RCX );
112
113 //call free
114 extern SUBINFO *pSub_free;
115 op_call(pSub_free);
116 }
117 else{
118 pobj_sf->pop();
119 pobj_sf->pop();
120 }
121 }
122 }
123}
124
125void ParamImpl::SetStructParameter(int reg,CClass *pobj_Class,LPSTR Parameter){
126 //////////////////////////////////////////////////////
127 ///// レジスタ資源のバックアップ
128 { BACKUP_REGISTER_RESOURCE
129 //////////////////////////////////////////////////////
130
131 int object_size = pobj_Class->GetSize();
132
133 //mov rcx,object_size
134 op_mov_RV(sizeof(_int64),REG_RCX,object_size);
135
136 //call calloc
137 extern SUBINFO *pSub_calloc;
138 op_call(pSub_calloc);
139
140 //mov r11,rax
141 op_mov_RR(REG_R11,REG_RAX);
142
143 //mov qword ptr[rsp+offset],r11 ※スタックフレームを利用
144 pobj_sf->push(REG_R11);
145
146 TYPEINFO BaseType={DEF_STRUCT,(LONG_PTR)pobj_Class};
147 TYPEINFO CalcType;
148 CalcType.type=NumOpe_GetType(Parameter,&BaseType,&CalcType.u.lpIndex);
149
150 /*
151 TODO: 消す
152 if( pobj_Class->GetCopyConstructorMethod()
153 && CalcType.type==DEF_OBJECT&&CalcType.u.pobj_Class==pobj_Class){
154 ////////////////////////////////////
155 // コピーコンストラクタを呼び出す
156 ////////////////////////////////////
157
158 BOOL bUseHeap;
159 int temp_reg=REG_RDX;
160 CalcType.type=NumOpe(&temp_reg,Parameter,DEF_OBJECT,(LONG_PTR)pobj_Class,&CalcType.u.lpIndex,&bUseHeap);
161
162 if(bUseHeap){
163 //mov r14,rdx
164 op_mov_RR(REG_R14,REG_RDX);
165 }
166
167 //mov r11,qword ptr[rsp+offset] ※スタックフレームを利用
168 pobj_sf->ref(REG_R11);
169
170 //mov rcx,this
171 op_mov_RR(REG_RCX,REG_R11);
172
173 //call constructor
174 op_call(pobj_Class->GetCopyConstructorMethod()->psi);
175
176
177 if(bUseHeap){
178 FreeTempObject(REG_R14,pobj_Class);
179 }
180 }
181 else{
182 if( pobj_Class->GetConstructorMethod() ){
183 ////////////////////////////////
184 // コンストラクタを呼び出す
185 ////////////////////////////////
186
187 //mov rcx,this
188 op_mov_RR(REG_RCX,REG_R11);
189
190 //call constructor
191 op_call(pobj_Class->GetConstructorMethod()->psi);
192 }
193 */
194
195
196 BOOL bUseHeap;
197 int temp_reg=REG_RAX;
198 CalcType.type=NumOpe(&temp_reg,Parameter,DEF_STRUCT,(LONG_PTR)pobj_Class,&CalcType.u.lpIndex,&bUseHeap);
199
200
201 //mov r11,qword ptr[rsp+offset] ※スタックフレームを利用
202 pobj_sf->ref(REG_R11);
203
204
205 RELATIVE_VAR RelativeVar;
206 RelativeVar.bOffsetOffset=0;
207 RelativeVar.offset=0;
208 RelativeVar.dwKind=VAR_DIRECTMEM;
209
210 SetStructVariableFromRax((LONG_PTR)pobj_Class,CalcType.type,CalcType.u.lpIndex,&RelativeVar,bUseHeap);
211
212 //}
213
214 //mov r11,qword ptr[rsp+offset] ※スタックフレームを利用
215 pobj_sf->pop(REG_R11);
216
217 /////////////////////////////////////////////
218 ////// レジスタ資源を復元
219 RESTORE_REGISTER_RESOURCE
220 }////////////////////////////////////////////
221
222 //mov reg,r11
223 op_mov_RR(reg,REG_R11);
224}
225
226
227void ParamImpl::SetParameter(const char *FuncName,PARAMETER_INFO *ppi,int pi_num,int SecondParmNum){
228 ///////////////////////////////////////////////////////////
229 // パラメータをレジスタ及びスタックフレームにセット
230 ///////////////////////////////////////////////////////////
231 int i2,i3;
232
233 BOOL bEllipse;
234 if(pi_num){
235 if(ppi[pi_num-1].type==DEF_ELLIPSE) bEllipse=1;
236 else bEllipse=0;
237 }
238 else bEllipse=0;
239
240 BOOL bHas_System_LocalThis=0;
241 if(ParmsNum>=1){
242 if(lstrcmp(ppi[0].name,"_System_LocalThis")==0)
243 bHas_System_LocalThis=1;
244 }
245
246 //戻り値用の変数名を取得
247 const char *lpszVarNameToReturn = (FuncName[0]==1&&FuncName[1]==ESC_OPERATOR)?"_System_ReturnValue":FuncName;
248
249 //パラメータをレジスタとスタックに格納
250 int CalcType;
251 LONG_PTR lpCalcIndex;
252 BOOL bCalcUseHeap;
253 int ParmSize=0;
254 int reg,temp_reg;
255 RELATIVE_VAR RelativeVar;
256 for(i2=ParmsNum-1;i2>=0;i2--){
257 if(bEllipse&&i2<=pi_num-2) bEllipse=0;
258
259 if(i2==0&&ppi[i2].name){
260 if(lstrcmp(ppi[i2].name,"_System_LocalThis")==0){
261 //オブジェクトメンバの第一パラメータのThisポインタ
262 continue;
263 }
264 }
265 if((i2==0||i2==1)&&ppi[i2].name){
266 if(lstrcmp(ppi[i2].name,lpszVarNameToReturn)==0){
267 //オブジェクトメンバの第一または第二パラメータの戻り値用オブジェクト
268 continue;
269 }
270 }
271
272 TYPEINFO DummyTypeInfo;
273 BOOL bByVal;
274 if(bEllipse){
275 DummyTypeInfo.type=NumOpe_GetType(Parms[i2],NULL,&DummyTypeInfo.u.lpIndex);
276 bByVal=1;
277 }
278 else{
279 DummyTypeInfo.type=ppi[i2].type;
280 DummyTypeInfo.u.lpIndex=ppi[i2].u.index;
281 bByVal=ppi[i2].bByVal;
282 }
283
284 int xmm_temp_sw=0;
285 if(IsRealNumberType(DummyTypeInfo.type)&&bByVal){
286 //実数型
287 if(i2==0) reg=REG_XMM0;
288 else if(i2==1) reg=REG_XMM1;
289 else if(i2==2) reg=REG_XMM2;
290 else if(i2==3) reg=REG_XMM3;
291 else{
292 reg=REG_XMM0;
293 xmm_temp_sw=1;
294 }
295 }
296 else{
297 //整数型
298 if(i2==0) reg=REG_RCX;
299 else if(i2==1) reg=REG_RDX;
300 else if(i2==2) reg=REG_R8;
301 else if(i2==3) reg=REG_R9;
302 else reg=REG_RAX;
303 }
304
305 if(bByVal==1){
306 //値参照
307
308 if(Parms[i2][0]==1&&Parms[i2][1]==ESC_BYVAL){
309 char temp2[255];
310 sprintf(temp2,"%s関数の第%dパラメータ",FuncName,i2+1);
311 SetError(19,temp2,cp);
312 continue;
313 }
314
315 if(DummyTypeInfo.type==DEF_STRUCT){
316 SetStructParameter(reg,DummyTypeInfo.u.pobj_Class,Parms[i2]);
317 goto next;
318 }
319
320 temp_reg=reg;
321
322 extern LONG_PTR ProcPtr_BaseIndex;
323 LONG_PTR back_ProcPtr_BaseIndex;
324 back_ProcPtr_BaseIndex=ProcPtr_BaseIndex;
325 if(DummyTypeInfo.type==DEF_PTR_PROC) ProcPtr_BaseIndex=DummyTypeInfo.u.lpIndex;
326 else ProcPtr_BaseIndex=-1;
327
328 CalcType=NumOpe(&temp_reg,Parms[i2],DummyTypeInfo.type,DummyTypeInfo.u.lpIndex,&lpCalcIndex,&bCalcUseHeap);
329
330 ProcPtr_BaseIndex=back_ProcPtr_BaseIndex;
331
332 if(CalcType==-1) break;
333
334 if(CalcType==DEF_OBJECT){
335 if( DummyTypeInfo.type != DEF_OBJECT
336 ||
337 DummyTypeInfo.type == DEF_OBJECT &&
338 !DummyTypeInfo.u.pobj_Class->IsEqualsOrSubClass( (CClass *)lpCalcIndex ) ){
339 //キャスト演算子のオーバーロードに対応する
340 CallCastOperatorProc(reg,CalcType,lpCalcIndex,bCalcUseHeap,DummyTypeInfo.type,DummyTypeInfo.u.lpIndex);
341 }
342 }
343
344
345 if(bEllipse){
346 if(IsRealNumberType(CalcType)){
347 //整数レジスタへコピー
348 //※cdeclの拡張パラメータは実数の場合も汎用レジスタで引渡し
349
350 if(0<=i2&&i2<=3){
351 if(i2==0) reg=REG_RCX;
352 else if(i2==1) reg=REG_RDX;
353 else if(i2==2) reg=REG_R8;
354 else if(i2==3) reg=REG_R9;
355
356 //movd reg,temp_reg
357 op_movd_RX(reg,temp_reg);
358 }
359 }
360 else if(IsWholeNumberType(CalcType)){
361 //整数型の場合は、64ビットへ拡張する
362 ExtendTypeTo64(CalcType,temp_reg);
363 }
364 }
365 else{
366 //型チェック
367 // TODO: _System_ReturnValueが考慮されていない?
368 if(bHas_System_LocalThis) i3=i2-1;
369 else i3=i2;
370 CheckDifferentType(
371 DummyTypeInfo.type,
372 DummyTypeInfo.u.lpIndex,
373 CalcType,
374 lpCalcIndex,
375 FuncName,
376 i3);
377
378
379 if(DummyTypeInfo.type==DEF_DOUBLE){
380 //Double型へ変換
381 ChangeTypeToXmm_Double(CalcType,reg,temp_reg);
382 }
383 else if(DummyTypeInfo.type==DEF_SINGLE){
384 //Single型へ変換
385 ChangeTypeToXmm_Single(CalcType,reg,temp_reg);
386 }
387 else if(IsWholeNumberType(DummyTypeInfo.type)){
388 //実数型 → 整数型
389 ChangeTypeToWhole(CalcType,DummyTypeInfo.type,reg,temp_reg);
390 }
391 }
392 }
393 else{
394 //ポインタ参照
395 if(Parms[i2][0]==1&&Parms[i2][1]==ESC_BYVAL){
396 //ポインタ指定
397
398 temp_reg=reg;
399 CalcType=NumOpe(&temp_reg,Parms[i2]+2,0,0,&lpCalcIndex);
400 if(CalcType==-1) break;
401
402 int ptr_type;
403 ptr_type=GetPtrType(DummyTypeInfo.type,DummyTypeInfo.u.lpIndex);
404
405 //型チェック
406 if(bHas_System_LocalThis) i3=i2-1;
407 else i3=i2;
408 CheckDifferentType(
409 ptr_type,
410 DummyTypeInfo.u.lpIndex,
411 CalcType,
412 lpCalcIndex,
413 FuncName,
414 i3);
415
416 if(IsRealNumberType(CalcType)){
417 //実数型 → 整数型
418 ChangeTypeToWhole(CalcType,DEF_QWORD,reg,temp_reg);
419 }
420 }
421 else{
422 if( useTempParameters[i2] ){
423 //一時オブジェクトをコピー
424
425 //mov reg, qword ptr[rsp+offset]
426 pobj_sf->ref_offset_data( reg, StackOffsetOfTempObject[i2] );
427 }
428 else{
429 //変数のアドレスを取得
430 int VarType;
431 LONG_PTR lpVarIndex;
432 if(GetVarOffset(
433 false,
434 false,
435 Parms[i2],
436 &VarType,
437 &RelativeVar,
438 &lpVarIndex)){
439
440 if(DummyTypeInfo.type!=DEF_ANY){
441 //型チェックを行う
442 if(DummyTypeInfo.type==VarType){
443 if(DummyTypeInfo.type==DEF_OBJECT){
444 if( !DummyTypeInfo.u.pobj_Class->IsEqualsOrSubClass( (CClass *)lpVarIndex ) ){
445 SetError(11,Parms[i2],cp);
446 }
447 }
448 else if(DummyTypeInfo.type==DEF_STRUCT){
449 if( !DummyTypeInfo.u.pobj_Class->IsEquals( (CClass *)lpVarIndex ) ){
450 SetError(11,Parms[i2],cp);
451 }
452 }
453 }
454 else if((VarType&FLAG_PTR)&&((VarType^FLAG_PTR)==DummyTypeInfo.type)){
455 //仮引数がポインタ参照で、実引数が配列の先頭ポインタのとき
456 }
457 else{
458 SetError(11,Parms[i2],cp);
459 }
460 }
461
462 //変数アドレスをレジスタにセット
463 SetVarPtrToReg(reg,&RelativeVar);
464
465 }
466 }
467 }
468 }
469
470next:
471
472 if(reg==REG_RAX){
473 //スタックフレームへコピー
474 //mov qword ptr[rsp+offset],rax
475 op_mov_MR(sizeof(_int64),REG_RAX,REG_RSP,i2*sizeof(_int64),MOD_BASE_DISP32);
476 }
477 else if(xmm_temp_sw){
478 //スタックフレームへコピー
479
480 //movlpd qword ptr[rsp+offset],xmm0
481 op_movlpd_MR(REG_XMM0,REG_RSP,i2*sizeof(_int64),MOD_BASE_DISP32);
482 }
483
484
485 /////////////////////
486 // レジスタをロック
487 /////////////////////
488
489 if(0<=i2&&i2<=3){
490 // ※rcx, rdx, r8, r9の場合のみ
491 pobj_BlockReg->lock(reg);
492 }
493 }
494
495 //パラメータが収まるだけのスタックフレームを確保
496 pobj_sf->parameter_allocate(pi_num*sizeof(_int64)+ sizeof(_int64)/*ret用*/ );
497}
498void ParamImpl::BackupParameter(int pi_num){
499 ///////////////////////////////////////////////////////////
500 // スタックフレームに存在する既存のパラメータをバックアップ
501 ///////////////////////////////////////////////////////////
502 int i2;
503
504 for(i2=0;i2<ParmsNum;i2++){
505 /////////////////////
506 // バックアップ
507 /////////////////////
508
509 extern CDBLockParms obj_DBLockParms;
510 if(obj_DBLockParms.array_LevelCount[i2]){
511 //mov r14,qword ptr[rsp+offset]
512 op_mov_RM(sizeof(_int64),REG_R14,REG_RSP,i2*sizeof(_int64),MOD_BASE_DISP32);
513
514 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
515 pobj_sf->push(REG_R14);
516 }
517
518 if(3<i2){
519 //スタックフレームをロック
520 extern CDBLockParms obj_DBLockParms;
521 obj_DBLockParms.lock(i2);
522 }
523 }
524}
525void ParamImpl::RestoreParameter(int pi_num){
526 ///////////////////////////////////////////////////////////
527 // スタックフレームに存在する既存のパラメータを復元
528 ///////////////////////////////////////////////////////////
529 int i2;
530
531 for(i2=ParmsNum-1;i2>=0;i2--){
532 /////////////////////
533 // 復元
534 /////////////////////
535
536 if(3<i2){
537 //スタックフレームをアンロック
538 extern CDBLockParms obj_DBLockParms;
539 obj_DBLockParms.unlock(i2);
540 }
541
542 extern CDBLockParms obj_DBLockParms;
543 if(obj_DBLockParms.array_LevelCount[i2]){
544 //mov r14,qword ptr[rsp+offset] ※スタックフレームを利用
545 pobj_sf->pop(REG_R14);
546
547 //mov qword ptr[rsp+offset],r14
548 op_mov_MR(sizeof(_int64),REG_R14,REG_RSP,i2*sizeof(_int64),MOD_BASE_DISP32);
549 }
550 }
551}
Note: See TracBrowser for help on using the repository browser.