source: dev/BasicCompiler64/CParameter.cpp@ 75

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

TYPEINFO→Typeへのリファクタリングを実施。64bitはほぼ完了。32bitが全般的に未完成。

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