source: dev/BasicCompiler64/CParameter.cpp@ 100

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

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

File size: 12.1 KB
Line 
1#include "../BasicCompiler_Common/common.h"
2#include "opcode.h"
3
4int ParamImpl::NewTempParameters( const string &procName, const Parameters &params, int SecondParmNum ){
5 if( SecondParmNum == -1 ) SecondParmNum = (int)params.size();
6
7 ///////////////////////////////////////////////////////
8 // 一時オブジェクトをあらかじめスタックに積んでおく
9 ///////////////////////////////////////////////////////
10
11 int stackItemNum = 0;
12
13 useTempObject = false;
14
15 BOOL bEllipse;
16 if(params.size()){
17 if(params[params.size()-1]->GetBasicType()==DEF_ELLIPSE) bEllipse=1;
18 else bEllipse=0;
19 }
20 else bEllipse=0;
21
22 for(int i2=ParmsNum-1;i2>=0;i2--){
23 useTempParameters[i2] = false;
24
25 if(bEllipse&&i2<=(int)params.size()-2) bEllipse=0;
26
27 if(i2==0){
28 if( params[i2]->GetVarName() == "_System_LocalThis" ){
29 //オブジェクトメンバの第一パラメータのThisポインタ
30 continue;
31 }
32 }
33 if( i2==0||i2==1 ){
34 if( params[i2]->GetVarName() == procName ){
35 //オブジェクトメンバの第一または第二パラメータの戻り値用オブジェクト
36 continue;
37 }
38 }
39
40 Type dummyType;
41 BOOL bByVal;
42 if(bEllipse){
43 NumOpe_GetType( Parms[i2], Type(), dummyType );
44 bByVal=1;
45 }
46 else{
47 dummyType = *params[i2];
48 bByVal = ( params[i2]->IsRef() == false ) ? TRUE:FALSE;
49 }
50
51
52 if( !bByVal ){
53 //ポインタ参照
54 if(Parms[i2][0]==1&&Parms[i2][1]==ESC_BYVAL){
55 //ポインタ指定
56 continue;
57 }
58
59 if( !GetVarType( Parms[i2], Type(), FALSE ) ){
60 //変数ではないとき
61 int reg = REG_RAX;
62 Type calcType;
63 NumOpe( &reg, Parms[i2], dummyType, calcType );
64
65 if( !calcType.IsStruct() ){
66 //一時参照を作成
67 pobj_sf->push( reg );
68 pobj_sf->mov_sp( reg );
69
70 stackItemNum++;
71 }
72
73 //スタックフレームへコピー
74 StackOffsetOfTempObject[i2] = pobj_sf->push(reg);
75
76 stackItemNum++;
77
78 bool result = CheckDifferentType(
79 dummyType,
80 calcType,
81 procName.c_str(),
82 i2);
83
84 if( result ){
85 useTempParameters[i2] = true;
86 useTempObject = true;
87
88 types[i2] = calcType;
89 }
90 }
91 }
92 }
93
94 return stackItemNum * PTR_SIZE;
95}
96void ParamImpl::DeleteTempParameters(){
97 ///////////////////////////////////////////////////////
98 // 一時オブジェクトを破棄
99 ///////////////////////////////////////////////////////
100 if( !useTempObject ) return;
101
102 for(int i2=ParmsNum-1;i2>=0;i2--){
103 if( useTempParameters[i2] ){
104 if( types[i2].IsStruct() ){
105 // 構造体の一時メモリ
106
107 //メモリを解放する
108
109 pobj_sf->pop( REG_RCX );
110
111 //call free
112 extern UserProc *pSub_free;
113 op_call(pSub_free);
114 }
115 else{
116 pobj_sf->pop();
117 pobj_sf->pop();
118 }
119 }
120 }
121}
122
123void ParamImpl::SetStructParameter( int reg, const Type &baseType, const char *expression ){
124 //////////////////////////////////////////////////////
125 ///// レジスタ資源のバックアップ
126 { BACKUP_REGISTER_RESOURCE
127 //////////////////////////////////////////////////////
128
129 int object_size = baseType.GetClass().GetSize();
130
131 //mov rcx,object_size
132 op_mov_RV(sizeof(_int64),REG_RCX,object_size);
133
134 //call calloc
135 extern UserProc *pSub_calloc;
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
145 Type calcType;
146 BOOL bUseHeap;
147 int temp_reg=REG_RAX;
148 NumOpe( &temp_reg,
149 expression,
150 baseType,
151 calcType,
152 &bUseHeap );
153
154
155 //mov r11,qword ptr[rsp+offset] ※スタックフレームを利用
156 pobj_sf->ref(REG_R11);
157
158
159 RELATIVE_VAR RelativeVar;
160 RelativeVar.bOffsetOffset=0;
161 RelativeVar.offset=0;
162 RelativeVar.dwKind=VAR_DIRECTMEM;
163
164 SetStructVariableFromRax(
165 baseType,
166 calcType,
167 &RelativeVar,bUseHeap);
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}
181
182
183void ParamImpl::SetParameter( const string &procName, const Parameters &params, int SecondParmNum ){
184 if( SecondParmNum == -1 ) SecondParmNum = (int)params.size();
185
186 ///////////////////////////////////////////////////////////
187 // パラメータをレジスタ及びスタックフレームにセット
188 ///////////////////////////////////////////////////////////
189 int i2,i3;
190
191 BOOL bEllipse;
192 if( params.size() ){
193 if(params[params.size()-1]->GetBasicType()==DEF_ELLIPSE) bEllipse=1;
194 else bEllipse=0;
195 }
196 else bEllipse=0;
197
198 BOOL bHas_System_LocalThis=0;
199 if(ParmsNum>=1){
200 if( params[0]->GetVarName() == "_System_LocalThis" ){
201 bHas_System_LocalThis=1;
202 }
203 }
204
205 //戻り値用の変数名を取得
206 const char *lpszVarNameToReturn = (procName[0]==1&&procName[1]==ESC_OPERATOR)?"_System_ReturnValue":procName.c_str();
207
208 //パラメータをレジスタとスタックに格納
209 int ParmSize=0;
210 int reg,temp_reg;
211 RELATIVE_VAR RelativeVar;
212 for(i2=ParmsNum-1;i2>=0;i2--){
213 if(bEllipse&&i2<=(int)params.size()-2) bEllipse=0;
214
215 if(i2==0){
216 if( params[i2]->GetVarName() == "_System_LocalThis" ){
217 //オブジェクトメンバの第一パラメータのThisポインタ
218 continue;
219 }
220 }
221 if(i2==0||i2==1){
222 if( params[i2]->GetVarName() == lpszVarNameToReturn ){
223 //オブジェクトメンバの第一または第二パラメータの戻り値用オブジェクト
224 continue;
225 }
226 }
227
228 Type dummyType;
229 BOOL bByVal;
230 if(bEllipse){
231 NumOpe_GetType( Parms[i2], Type(), dummyType );
232 bByVal=1;
233 }
234 else{
235 dummyType = *params[i2];
236 bByVal = ( params[i2]->IsRef() == false ) ? TRUE:FALSE;
237 }
238
239 int xmm_temp_sw=0;
240 if(dummyType.IsReal()&&bByVal){
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];
265 sprintf(temp2,"%s関数の第%dパラメータ",procName,i2+1);
266 SetError(19,temp2,cp);
267 continue;
268 }
269
270 if( dummyType.IsStruct() ){
271 SetStructParameter( reg, dummyType, Parms[i2] );
272 goto next;
273 }
274
275 temp_reg=reg;
276
277 extern LONG_PTR ProcPtr_BaseIndex;
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 }
285
286 BOOL bCalcUseHeap;
287 Type calcType;
288 if( !NumOpe( &temp_reg, Parms[i2], dummyType, calcType, &bCalcUseHeap ) ){
289 break;
290 }
291
292 ProcPtr_BaseIndex=back_ProcPtr_BaseIndex;
293
294 if( calcType.IsObject() ){
295 if( !dummyType.IsObject()
296 ||
297 dummyType.IsObject() &&
298 !dummyType.GetClass().IsEqualsOrSubClass( &calcType.GetClass() ) ){
299 //キャスト演算子のオーバーロードに対応する
300 CallCastOperatorProc( reg, calcType, bCalcUseHeap,dummyType );
301 }
302 }
303
304
305 if(bEllipse){
306 if( calcType.IsReal() ){
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 }
320 else if( calcType.IsWhole() ){
321 //整数型の場合は、64ビットへ拡張する
322 ExtendTypeTo64( calcType.GetBasicType(), temp_reg );
323 }
324 }
325 else{
326 //型チェック
327 // TODO: _System_ReturnValueが考慮されていない?
328 if(bHas_System_LocalThis) i3=i2-1;
329 else i3=i2;
330 CheckDifferentType(
331 dummyType,
332 calcType,
333 procName.c_str(),
334 i3);
335
336 if( dummyType.IsDouble() ){
337 //Double型へ変換
338 ChangeTypeToXmm_Double(calcType.GetBasicType(),reg,temp_reg);
339 }
340 else if( dummyType.IsSingle() ){
341 //Single型へ変換
342 ChangeTypeToXmm_Single(calcType.GetBasicType(),reg,temp_reg);
343 }
344 else if( dummyType.IsWhole() ){
345 //実数型 → 整数型
346 ChangeTypeToWhole(calcType.GetBasicType(),dummyType.GetBasicType(),reg,temp_reg);
347 }
348 }
349 }
350 else{
351 //ポインタ参照
352 if(Parms[i2][0]==1&&Parms[i2][1]==ESC_BYVAL){
353 //ポインタ指定
354
355 temp_reg=reg;
356 Type calcType;
357 if( !NumOpe(&temp_reg, Parms[i2]+2, dummyType, calcType) ){
358 break;
359 }
360
361 dummyType.PtrLevelUp();
362
363 //型チェック
364 if(bHas_System_LocalThis) i3=i2-1;
365 else i3=i2;
366 CheckDifferentType(
367 dummyType,
368 calcType,
369 procName.c_str(),
370 i3);
371
372 if( calcType.IsReal() ){
373 //実数型 → 整数型
374 ChangeTypeToWhole( calcType.GetBasicType(), DEF_QWORD,reg,temp_reg);
375 }
376 }
377 else{
378 if( useTempParameters[i2] ){
379 //一時オブジェクトをコピー
380
381 //mov reg, qword ptr[rsp+offset]
382 pobj_sf->ref_offset_data( reg, StackOffsetOfTempObject[i2] );
383 }
384 else{
385 //変数のアドレスを取得
386 Type varType;
387 if(GetVarOffset(
388 false,
389 false,
390 Parms[i2],
391 &RelativeVar,
392 varType)){
393
394 if( !dummyType.IsAny() ){
395 //型チェックを行う
396 if( dummyType.GetBasicType() == varType.GetBasicType() ){
397 if( dummyType.IsObject() ){
398 if( !dummyType.GetClass().IsEqualsOrSubClass( &varType.GetClass() ) ){
399 SetError(11,Parms[i2],cp);
400 }
401 }
402 else if( dummyType.IsStruct() ){
403 if( !dummyType.GetClass().IsEquals( &varType.GetClass() ) ){
404 SetError(11,Parms[i2],cp);
405 }
406 }
407 }
408 else if( (varType.GetBasicType()&FLAG_PTR)
409 &&((varType.GetBasicType()^FLAG_PTR)==dummyType.GetBasicType())){
410 //仮引数がポインタ参照で、実引数が配列の先頭ポインタのとき
411 }
412 else{
413 SetError(11,Parms[i2],cp);
414 }
415 }
416
417 //変数アドレスをレジスタにセット
418 SetVarPtrToReg(reg,&RelativeVar);
419
420 }
421 }
422 }
423 }
424
425next:
426
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 //パラメータが収まるだけのスタックフレームを確保
451 pobj_sf->parameter_allocate((int)params.size()*sizeof(_int64)+ sizeof(_int64)/*ret用*/ );
452}
453void ParamImpl::BackupParameter(int pi_num){
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}
480void ParamImpl::RestoreParameter(int pi_num){
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.