source: dev/trunk/ab5.0/abdev/compiler_x64/CParameter.cpp@ 740

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

[522][527]を64bit版にマージ。

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