source: dev/BasicCompiler64/CParameter.cpp@ 63

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

CClass::GetSize、CClass::GetMemberOffsetを追加

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