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

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