source: dev/trunk/abdev/BasicCompiler64/CParameter.cpp@ 206

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

コード全体のリファクタリングを実施

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