source: dev/BasicCompiler64/CParameter.cpp@ 64

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

すべてのオブジェクトを参照型に切り替えた。

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