00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 #define TRACE_ENTRY(x)
00057 #define TRACE_EXIT(x)
00058 #define TRACE_EXIT_i(x,i)
00059
00060 #define __STDC_LIMIT_MACROS
00061 #include <stdint.h>
00062 #include <limits.h>
00063 #include "defs.h"
00064 #include "mtypes.h"
00065 #include "errors.h"
00066 #include "erglob.h"
00067 #include "stab.h"
00068 #include "config_targ.h"
00069 #include "targ_sim.h"
00070
00071 #include "targ_sim_body.h"
00072
00073
00074 #if (__GNUC__ == 2)
00075 static
00076 #endif
00077 SIM SIM_Info[] = {
00078
00079
00080
00081
00082
00083
00084 {
00085 0,
00086 {0,0,0}, {0,0,0}, {0,0,0},
00087 {0,0,0}, {0,0,0}, {0,0,0},
00088 0, 0, 0,
00089 0, 0, 0,
00090 0, 0, 0, 0
00091 },
00092
00093 {
00094 SIM_FLT_AFTER_INT | SIM_COORD_MEM_REG
00095 | SIM_REG_STRUCTS | SIM_FLT_RTN_COMPLEX
00096 | SIM_FLT_REG_FIELDS | SIM_DBL_REG_FIELDS | SIM_VARARGS_FLOATS ,
00097 {0,0,0}, {0,0,0}, {0,0,0},
00098 {RAX,RDX,RDX-RAX}, {ST0,ST1,1}, {ST0,ST1,1},
00099 MTYPE_I4, MTYPE_F8, MTYPE_F8,
00100 0, 0, -64,
00101 #if defined(BUILD_OS_DARWIN)
00102
00103 0, 64, RCX, 0
00104 #else
00105 0, 0, RCX, 0
00106 #endif
00107 },
00108
00109 {
00110 SIM_FLT_AFTER_INT | SIM_COORD_MEM_REG
00111 | SIM_REG_STRUCTS | SIM_FLT_RTN_COMPLEX
00112 | SIM_FLT_REG_FIELDS | SIM_DBL_REG_FIELDS | SIM_VARARGS_FLOATS ,
00113 {RDI,R9,1}, {XMM0,XMM7,1}, {XMM0,XMM7,1},
00114 {RAX,RDX,RDX-RAX}, {XMM0,XMM1,1}, {XMM0,XMM1,1},
00115 MTYPE_I8, MTYPE_F8, MTYPE_F8,
00116 0, 64, -64,
00117 128, 128, R10, 0
00118 }
00119 };
00120
00121
00122 extern BOOL
00123 Is_Return_Preg (PREG_NUM preg)
00124 {
00125 return (preg == First_Int_Preg_Return_Offset ||
00126 preg == Last_Int_Preg_Return_Offset) ||
00127 (preg >= First_X87_Preg_Return_Offset &&
00128 preg <= Last_X87_Preg_Return_Offset) ||
00129 (preg >= First_Float_Preg_Return_Offset &&
00130 preg <= Last_Float_Preg_Return_Offset) ||
00131 (preg >= First_MMX_Preg_Return_Offset &&
00132 preg <= Last_MMX_Preg_Return_Offset);
00133 }
00134
00135
00136 extern BOOL
00137 Is_Int_Output_Preg (PREG_NUM preg)
00138 {
00139 Fail_FmtAssertion (
00140 ("Is_Int_Output_Preg not applicable to x8664 targets"));
00141 }
00142
00143
00144 extern BOOL
00145 Is_Formal_Preg (PREG_NUM preg)
00146 {
00147 return (preg >= First_Int_Preg_Param_Offset &&
00148 preg <= Last_Int_Preg_Param_Offset) ||
00149 (preg >= First_Float_Preg_Param_Offset &&
00150 preg <= Last_Float_Preg_Param_Offset)||
00151 (preg >= First_MMX_Preg_Return_Offset &&
00152 preg <= Last_MMX_Preg_Return_Offset);
00153 }
00154
00155
00156
00157 static enum X86_64_PARM_CLASS Merge_Classes(enum X86_64_PARM_CLASS class1,
00158 enum X86_64_PARM_CLASS class2)
00159 {
00160
00161 if (class1 == class2)
00162 return class1;
00163
00164
00165 if (class1 == X86_64_NO_CLASS)
00166 return class2;
00167 if (class2 == X86_64_NO_CLASS)
00168 return class1;
00169
00170
00171 if (class1 == X86_64_MEMORY_CLASS || class2 == X86_64_MEMORY_CLASS)
00172 return X86_64_MEMORY_CLASS;
00173
00174
00175 if (class1 == X86_64_INTEGER_CLASS || class2 == X86_64_INTEGER_CLASS)
00176 return X86_64_INTEGER_CLASS;
00177
00178
00179 if (class1 == X86_64_X87_CLASS || class2 == X86_64_X87_CLASS ||
00180 class1 == X86_64_X87UP_CLASS || class2 == X86_64_X87UP_CLASS)
00181 return X86_64_MEMORY_CLASS;
00182
00183
00184 return X86_64_SSE_CLASS;
00185 }
00186
00187
00188
00189
00190 INT Classify_Aggregate(const TY_IDX ty,
00191 enum X86_64_PARM_CLASS classes[MAX_CLASSES])
00192 {
00193 INT i, n;
00194 enum X86_64_PARM_CLASS subclasses[MAX_CLASSES];
00195
00196 if (TY_size(ty) > 16 || TY_size(ty) == 0 ||
00197 TY_is_non_pod(ty) )
00198 return 0;
00199
00200 INT size_in_dwords = (TY_size(ty) + 7) / 8;
00201 for (i = 0; i < size_in_dwords; i++)
00202 classes[i] = X86_64_NO_CLASS;
00203 if (TY_kind(ty) == KIND_STRUCT ||
00204 TY_kind(ty) == KIND_ARRAY) {
00205 if (TY_kind(ty) == KIND_STRUCT) {
00206 FLD_ITER fld_iter = Make_fld_iter(TY_fld(ty));
00207 do {
00208 FLD_HANDLE fld(fld_iter);
00209 if (TY_size(FLD_type(fld)) == 0)
00210 continue;
00211 n = Classify_Aggregate(FLD_type(fld), subclasses);
00212 if (n == 0)
00213 return 0;
00214 INT inx = FLD_ofst(fld) / 8;
00215 for (i = 0; i < n; i++)
00216 classes[i + inx] = Merge_Classes(classes[i + inx], subclasses[i]);
00217 } while (!FLD_last_field(fld_iter++));
00218 }
00219 else {
00220 n = Classify_Aggregate(TY_etype(ty), subclasses);
00221 if (n == 0)
00222 return 0;
00223 for (i = 0; i < size_in_dwords; i++)
00224 classes[i] = subclasses[i % n];
00225 }
00226
00227 for (i = 0; i < size_in_dwords; i++) {
00228 if (classes[i] == X86_64_MEMORY_CLASS)
00229 return 0;
00230 }
00231 return size_in_dwords;
00232 }
00233 else
00234 switch (TY_mtype(ty)) {
00235 case MTYPE_I1:
00236 case MTYPE_U1:
00237 case MTYPE_I2:
00238 case MTYPE_U2:
00239 case MTYPE_I4:
00240 case MTYPE_U4:
00241 case MTYPE_A4:
00242 case MTYPE_I8:
00243 case MTYPE_U8:
00244 case MTYPE_A8:
00245 classes[0] = X86_64_INTEGER_CLASS;
00246 return 1;
00247 case MTYPE_F4:
00248 case MTYPE_F8:
00249 classes[0] = X86_64_SSE_CLASS;
00250 return 1;
00251 case MTYPE_CQ:
00252 case MTYPE_FQ:
00253 classes[0] = X86_64_X87_CLASS;
00254 return 0;
00255 case MTYPE_C4:
00256 classes[0] = X86_64_SSE_CLASS;
00257 return 1;
00258 case MTYPE_C8:
00259 classes[0] = X86_64_SSE_CLASS;
00260 classes[1] = X86_64_SSE_CLASS;
00261 return 2;
00262 case MTYPE_V16F4:
00263 case MTYPE_V16F8:
00264 case MTYPE_V16C4:
00265 case MTYPE_V16C8:
00266 classes[0] = X86_64_SSE_CLASS;
00267 classes[1] = X86_64_SSEUP_CLASS;
00268 return 2;
00269 case MTYPE_V16I1:
00270 case MTYPE_V16I2:
00271 case MTYPE_V16I4:
00272 case MTYPE_V16I8:
00273 classes[0] = X86_64_INTEGER_CLASS;
00274 classes[1] = X86_64_INTEGER_CLASS;
00275 return 2;
00276 case MTYPE_V8F4:
00277 classes[0] = X86_64_SSE_CLASS;
00278 return 1;
00279 case MTYPE_V8I1:
00280 case MTYPE_V8I2:
00281 case MTYPE_V8I4:
00282 case MTYPE_M8I1:
00283 case MTYPE_M8I2:
00284 case MTYPE_M8I4:
00285 classes[0] = X86_64_INTEGER_CLASS;
00286 return 1;
00287 case MTYPE_M8F4:
00288 classes[0] = X86_64_X87_CLASS;
00289 return 1;
00290 default:
00291 FmtAssert (FALSE, ("Classify_Aggregate: mtype %s",
00292 MTYPE_name(TY_mtype(ty))));
00293 }
00294 }
00295 #if defined(BUILD_OS_DARWIN)
00296
00297
00298
00299
00300
00301
00302 INT Classify_Aggregate32(const TY_IDX ty,
00303 enum X86_64_PARM_CLASS classes[MAX_CLASSES])
00304 {
00305 enum X86_64_PARM_CLASS subclasses[MAX_CLASSES];
00306
00307 if (TY_size(ty) > 8 || TY_size(ty) == 0 ||
00308 TY_is_non_pod(ty) )
00309 return 0;
00310
00311 INT size_in_words = (TY_size(ty) + 3) / 4;
00312 classes[0] = X86_64_INTEGER_CLASS;
00313 classes[1] = X86_64_NO_CLASS;
00314
00315 FLD_ITER fld_iter = Make_fld_iter(TY_fld(ty));
00316 FLD_HANDLE fld(fld_iter);
00317 TYPE_ID first_field_type = TY_mtype(FLD_type(fld));
00318 if (size_in_words == 1 && first_field_type == MTYPE_F4) {
00319 classes[0] = X86_64_X87_CLASS;
00320 }
00321 else if (size_in_words == 2) {
00322 if (first_field_type == MTYPE_F8) {
00323 size_in_words = 1;
00324 classes[0] = X86_64_X87_CLASS;
00325 }
00326 else {
00327 classes[1] = X86_64_INTEGER_CLASS;
00328 }
00329 }
00330 return size_in_words;
00331 }
00332 #endif
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342 extern void
00343 Get_Return_Mtypes (
00344 TY_IDX rtype,
00345 Mtype_Return_Level level,
00346 TYPE_ID *mreg1,
00347 TYPE_ID *mreg2)
00348 {
00349 Fail_FmtAssertion (
00350 ("Get_Return_Mtypes should not be invoked; invoke Get_Return_Info instead"));
00351 }
00352
00353
00354
00355
00356
00357
00358
00359 extern void
00360 Get_Return_Pregs (
00361 TYPE_ID mreg1,
00362 TYPE_ID mreg2,
00363 PREG_NUM *rreg1,
00364 PREG_NUM *rreg2)
00365 {
00366 Fail_FmtAssertion (
00367 ("Get_Return_Pregs should not be invoked; invoke Get_Return_Info instead"));
00368 }
00369
00370 RETURN_INFO
00371 Get_Return_Info(TY_IDX rtype, Mtype_Return_Level level, BOOL ff2c_abi)
00372 {
00373 TYPE_ID mtype = TY_mtype (rtype);
00374 RETURN_INFO info;
00375 INT32 i;
00376 INT64 size;
00377
00378 BOOL ssereg_parms_enabled = Is_Target_32bit() &&
00379 TY_has_sseregister_parm (PU_prototype (Get_Current_PU()));
00380 info.return_via_first_arg = FALSE;
00381
00382 switch (mtype) {
00383
00384 case MTYPE_UNKNOWN:
00385
00386
00387 info.count = 0;
00388
00389
00390 break;
00391
00392 case MTYPE_FQ:
00393
00394 info.count = 1;
00395 info.mtype[0] = mtype;
00396 info.preg[0] = First_X87_Preg_Return_Offset;
00397 break;
00398
00399 case MTYPE_V:
00400
00401 info.count = 0;
00402 break;
00403
00404 case MTYPE_I8:
00405 case MTYPE_U8:
00406 if( Is_Target_32bit() &&
00407 level == No_Simulated ){
00408 info.count = 2;
00409 info.mtype[0] = info.mtype[1] = ( mtype == MTYPE_I8 ? MTYPE_I4 : MTYPE_U4 );
00410 info.preg[0] = PR_first_reg(SIM_INFO.int_results);
00411 info.preg[1] =
00412 PR_first_reg(SIM_INFO.int_results) + PR_skip_value(SIM_INFO.int_results);
00413
00414 break;
00415 }
00416
00417 case MTYPE_I1:
00418 case MTYPE_I2:
00419 case MTYPE_I4:
00420 case MTYPE_U1:
00421 case MTYPE_U2:
00422 case MTYPE_U4:
00423 case MTYPE_A4:
00424 case MTYPE_A8:
00425
00426 info.count = 1;
00427 info.mtype [0] = mtype;
00428 info.preg [0] = PR_first_reg(SIM_INFO.int_results);
00429 break;
00430
00431 case MTYPE_F4:
00432 case MTYPE_F8:
00433 info.count = 1;
00434 info.mtype [0] = mtype;
00435 if (ssereg_parms_enabled)
00436 info.preg [0] = XMM0;
00437 else
00438 info.preg [0] = PR_first_reg(SIM_INFO.flt_results);
00439 break;
00440
00441 case MTYPE_V8I1:
00442 case MTYPE_V8I2:
00443 case MTYPE_V8I4:
00444 case MTYPE_V8F4:
00445 case MTYPE_M8I1:
00446 case MTYPE_M8I2:
00447 case MTYPE_M8I4:
00448 case MTYPE_M8F4:
00449 info.count = 1;
00450 info.mtype [0] = mtype;
00451 if (Is_Target_32bit() && Target_MMX) {
00452 info.preg [0] = MM0;
00453 }
00454 else {
00455 info.preg [0] = PR_first_reg(SIM_INFO.flt_results);
00456 }
00457 break;
00458 case MTYPE_V16I1:
00459 case MTYPE_V16I2:
00460 case MTYPE_V16I4:
00461 case MTYPE_V16I8:
00462 case MTYPE_V16F4:
00463 case MTYPE_V16F8:
00464 info.count = 1;
00465 info.mtype [0] = mtype;
00466 if (Is_Target_32bit() && Target_SSE) {
00467 info.preg [0] = XMM0;
00468 }
00469 else {
00470 info.preg [0] = PR_first_reg(SIM_INFO.flt_results);
00471 }
00472 break;
00473
00474 case MTYPE_C4:
00475 if (Is_Target_32bit()) {
00476
00477
00478
00479
00480
00481 if(
00482 #if defined(BUILD_OS_DARWIN)
00483 1
00484 #else
00485 PU_c_lang(Get_Current_PU()) ||
00486 PU_cxx_lang(Get_Current_PU())
00487 #endif
00488 ){
00489
00490 if( level == Use_Simulated ){
00491 info.count = 1;
00492 info.mtype[0] = mtype;
00493 info.preg[0] = PR_first_reg(SIM_INFO.flt_results);
00494
00495 } else {
00496 info.count = 2;
00497 info.mtype[0] = info.mtype[1] = SIM_INFO.int_type;
00498 info.preg[0] = PR_first_reg(SIM_INFO.int_results);
00499 info.preg[1] = info.preg[0] + PR_skip_value(SIM_INFO.int_results);
00500 }
00501
00502 } else {
00503 info.count = 0;
00504 info.return_via_first_arg = TRUE;
00505 }
00506 }
00507 else if (ff2c_abi || F2c_Abi) {
00508 info.count = 0;
00509 info.return_via_first_arg = TRUE;
00510 } else if( level == Use_Simulated ){
00511 info.count = 1;
00512 info.mtype [0] = mtype;
00513 info.preg [0] = PR_first_reg(SIM_INFO.flt_results);
00514
00515 } else {
00516
00517
00518 info.count = 2;
00519 info.mtype [0] = Mtype_complex_to_real(mtype);
00520 info.mtype [1] = Mtype_complex_to_real(mtype);
00521 info.preg [0] = PR_first_reg(SIM_INFO.flt_results);
00522 info.preg [1] = PR_first_reg(SIM_INFO.flt_results)
00523 + PR_skip_value(SIM_INFO.flt_results);
00524 }
00525
00526 break;
00527
00528 case MTYPE_C8:
00529 if (Is_Target_32bit()) {
00530 info.count = 0;
00531 info.return_via_first_arg = TRUE;
00532 }
00533 else if (ff2c_abi || F2c_Abi) {
00534 info.count = 0;
00535 info.return_via_first_arg = TRUE;
00536 } else if (level == Use_Simulated) {
00537
00538 info.count = 1;
00539 info.mtype [0] = mtype;
00540 info.preg [0] = PR_first_reg(SIM_INFO.flt_results);
00541 }
00542
00543 else {
00544
00545 info.count = 2;
00546 info.mtype [0] = Mtype_complex_to_real(mtype);
00547 info.mtype [1] = Mtype_complex_to_real(mtype);
00548 info.preg [0] = PR_first_reg(SIM_INFO.flt_results);
00549 info.preg [1] = PR_first_reg(SIM_INFO.flt_results)
00550 + PR_skip_value(SIM_INFO.flt_results);
00551 }
00552 break;
00553
00554 case MTYPE_CQ:
00555 if (Is_Target_32bit()) {
00556 info.count = 0;
00557 info.return_via_first_arg = TRUE;
00558 }
00559 else if (level == Use_Simulated) {
00560
00561 info.count = 1;
00562 info.mtype [0] = mtype;
00563 info.preg [0] = First_X87_Preg_Return_Offset;
00564 }
00565
00566 else {
00567
00568 info.count = 2;
00569 info.mtype [0] = Mtype_complex_to_real(mtype);
00570 info.mtype [1] = Mtype_complex_to_real(mtype);
00571 info.preg [0] = First_X87_Preg_Return_Offset;
00572 info.preg [1] = Last_X87_Preg_Return_Offset;
00573 }
00574 break;
00575
00576
00577 case MTYPE_M:
00578
00579 info.count = 0;
00580
00581 size = TY_size(Ty_Table[rtype]);
00582 if (size == 0) {
00583
00584 info.count = 1;
00585 info.mtype[0] = MTYPE_I8;
00586 info.preg[0]= PR_first_reg(SIM_INFO.int_results);
00587 break;
00588 }
00589
00590 info.return_via_first_arg = TRUE;
00591
00592 #if defined(BUILD_OS_DARWIN)
00593
00594 #else
00595 if (Is_Target_32bit())
00596 break;
00597 #endif
00598
00599 if (SIM_INFO.max_struct_result != 0) {
00600
00601 if (size > 0 && 8 * size <= SIM_INFO.max_struct_result) {
00602 PREG_NUM next_float_return_num, next_int_return_num;
00603 enum X86_64_PARM_CLASS classes[MAX_CLASSES];
00604 #if defined(BUILD_OS_DARWIN)
00605 INT n = Is_Target_32bit() ?
00606 Classify_Aggregate32(rtype, classes) :
00607 Classify_Aggregate(rtype, classes);
00608 #else
00609 INT n = Classify_Aggregate(rtype, classes);
00610 #endif
00611 if (n > 0) {
00612 info.return_via_first_arg = FALSE;
00613 info.count = n;
00614
00615 if (classes[0] == X86_64_SSE_CLASS) {
00616 info.mtype[0] = SIM_INFO.dbl_type;
00617 info.preg[0] = PR_first_reg(SIM_INFO.dbl_results);
00618 next_float_return_num = PR_last_reg(SIM_INFO.dbl_results);
00619 next_int_return_num = PR_first_reg(SIM_INFO.int_results);
00620 }
00621 else {
00622 info.mtype[0] = SIM_INFO.int_type;
00623 info.preg[0] = PR_first_reg(SIM_INFO.int_results);
00624 next_float_return_num = PR_first_reg(SIM_INFO.dbl_results);
00625 next_int_return_num = PR_last_reg(SIM_INFO.int_results);
00626 }
00627
00628 if (n > 1) {
00629 if (classes[1] == X86_64_SSE_CLASS) {
00630 info.mtype[1] = SIM_INFO.dbl_type;
00631 info.preg[1] = next_float_return_num;
00632 }
00633 else {
00634 info.mtype[1] = SIM_INFO.int_type;
00635 info.preg[1] = next_int_return_num;
00636 }
00637 }
00638 }
00639 }
00640 }
00641 break;
00642
00643 default:
00644
00645 info.count = 0;
00646 Fail_FmtAssertion ("Invalid return mtype %s encountered",
00647 (MTYPE_name(mtype)));
00648 break;
00649 }
00650
00651 for (i = info.count; i < MAX_NUMBER_OF_REGISTERS_FOR_RETURN; i++) {
00652
00653 info.mtype [i] = MTYPE_V;
00654 info.preg [i] = 0;
00655 }
00656
00657 return info;
00658 }
00659
00660 static INT Current_Int_Param_Num = -1;
00661 static INT Current_Float_Param_Num = -1;
00662 static INT Current_MMX_Param_Num = -1;
00663 static INT Register_Parms = 0;
00664 static BOOL SSE_Register_Parms = FALSE;
00665 const INT SSE_Register_Parms_Allowed = 3;
00666 const INT MMX_Register_Parms_Allowed = 3;
00667
00668
00669 static PLOC
00670 Setup_Parameter_Locations (TY_IDX pu_type)
00671 {
00672 static PLOC plocNULL;
00673
00674 TY_IDX ret_type = (TY_kind(pu_type) == KIND_FUNCTION ? TY_ret_type(pu_type)
00675 : pu_type);
00676 RETURN_INFO info = Get_Return_Info (ret_type, No_Simulated);
00677 if (TY_is_varargs (pu_type)) {
00678
00679 TYLIST_IDX idx = TY_tylist (pu_type);
00680 Last_Fixed_Param = -1;
00681 for (++idx; Tylist_Table[idx] != 0; ++idx)
00682 ++Last_Fixed_Param;
00683
00684 if ( ! TY_has_prototype(pu_type))
00685 --Last_Fixed_Param;
00686
00687 if (TY_return_to_param (pu_type))
00688 ++Last_Fixed_Param;
00689 } else
00690 Last_Fixed_Param = INT_MAX;
00691
00692 if (Is_Target_32bit()) {
00693
00694 SSE_Register_Parms = TY_has_sseregister_parm (pu_type);
00695 Register_Parms = TY_register_parm (pu_type);
00696 }
00697
00698 Current_Param_Num = -1;
00699 Current_Int_Param_Num = -1;
00700 Current_Float_Param_Num = -1;
00701 Current_MMX_Param_Num = -1;
00702 Last_Param_Offset = 0;
00703 return plocNULL;
00704 }
00705
00706
00707 static PLOC
00708 Get_Parameter_Location (TY_IDX ty, BOOL is_output)
00709 {
00710 PLOC ploc;
00711 mDED_PREG_NUM int_regs_array[] = {RAX, RDX, RCX};
00712 mDED_PREG_NUM flt_regs_array[] = {XMM0, XMM1, XMM2};
00713 mDED_PREG_NUM mmx_regs_array[] = {MM0, MM1, MM2};
00714
00715 ploc.reg = 0;
00716 ploc.reg2 = 0;
00717 ploc.start_offset = Last_Param_Offset;
00718 ploc.size = 0;
00719 ploc.vararg_reg = 0;
00720 if (TY_kind (ty) == KIND_VOID) {
00721 return ploc;
00722 }
00723
00724
00725 TYPE_ID pmtype = Fix_TY_mtype (ty);
00726 ploc.size = MTYPE_RegisterSize(pmtype);
00727
00728 if (Is_Target_32bit() && MTYPE_is_vector(pmtype) &&
00729 (Last_Param_Offset & 7) != 0) {
00730 Last_Param_Offset += 8 - Last_Param_Offset % 8;
00731 ploc.start_offset = Last_Param_Offset;
00732 }
00733
00734 ++Current_Param_Num;
00735
00736 INT rpad = 0;
00737
00738 switch (pmtype) {
00739
00740 case MTYPE_I1:
00741 case MTYPE_U1:
00742 case MTYPE_I2:
00743 case MTYPE_U2:
00744 case MTYPE_I4:
00745 case MTYPE_U4:
00746 case MTYPE_A4:
00747
00748 rpad = (MTYPE_RegisterSize(SIM_INFO.int_type) - ploc.size);
00749
00750
00751 case MTYPE_I8:
00752 case MTYPE_U8:
00753 case MTYPE_A8:
00754 ++Current_Int_Param_Num;
00755 if (Is_Target_32bit() && Current_Int_Param_Num < Register_Parms) {
00756 ploc.reg = int_regs_array[Current_Int_Param_Num];
00757 }
00758 else {
00759 ploc.reg = PR_first_reg(SIM_INFO.int_args) + Current_Int_Param_Num;
00760 if (ploc.reg > PR_last_reg(SIM_INFO.int_args))
00761 ploc.reg = 0;
00762 }
00763 break;
00764
00765 case MTYPE_V8I1:
00766 case MTYPE_V8I2:
00767 case MTYPE_V8I4:
00768 case MTYPE_V8F4:
00769 case MTYPE_M8I1:
00770 case MTYPE_M8I2:
00771 case MTYPE_M8I4:
00772 case MTYPE_M8F4:
00773 if (Is_Target_32bit()) {
00774
00775
00776 ++Current_MMX_Param_Num;
00777 if (Current_MMX_Param_Num < MMX_Register_Parms_Allowed && Target_MMX) {
00778 ploc.reg = mmx_regs_array[Current_MMX_Param_Num];
00779 }
00780 else {
00781 ploc.reg = 0;
00782 }
00783 break;
00784 }
00785 case MTYPE_F4:
00786 case MTYPE_F8:
00787 if (Is_Target_32bit()) {
00788
00789
00790 ++Current_Float_Param_Num;
00791 if ( SSE_Register_Parms && Current_Float_Param_Num < SSE_Register_Parms_Allowed) {
00792 ploc.reg = flt_regs_array[Current_Float_Param_Num];
00793 }
00794 else {
00795 ploc.reg = 0;
00796 }
00797 break;
00798 }
00799 case MTYPE_V16I1:
00800 case MTYPE_V16I2:
00801 case MTYPE_V16I4:
00802 case MTYPE_V16I8:
00803 case MTYPE_V16F4:
00804 case MTYPE_V16F8:
00805 ++Current_Float_Param_Num;
00806 if (Is_Target_32bit()) {
00807
00808
00809 if (Current_Float_Param_Num < SSE_Register_Parms_Allowed && Target_SSE) {
00810 ploc.reg = flt_regs_array[Current_Float_Param_Num];
00811 }
00812 else {
00813 ploc.reg = 0;
00814 }
00815 }
00816 else {
00817
00818
00819 ploc.reg = PR_first_reg(SIM_INFO.flt_args) + Current_Float_Param_Num;
00820 if (ploc.reg > PR_last_reg(SIM_INFO.flt_args)) {
00821 ploc.reg = 0;
00822 rpad = MTYPE_RegisterSize(SIM_INFO.flt_type) - ploc.size;
00823 }
00824 }
00825 break;
00826
00827 case MTYPE_CQ:
00828 case MTYPE_FQ:
00829 ploc.reg = 0;
00830 break;
00831
00832 case MTYPE_C4:
00833 ++Current_Float_Param_Num;
00834 ploc.reg = PR_first_reg(SIM_INFO.flt_args) + Current_Float_Param_Num;
00835 if (ploc.reg > PR_last_reg(SIM_INFO.flt_args))
00836 ploc.reg = 0;
00837 break;
00838
00839 case MTYPE_C8:
00840 ++Current_Float_Param_Num;
00841 ploc.reg = PR_first_reg(SIM_INFO.flt_args) + Current_Float_Param_Num;
00842 if (ploc.reg > PR_last_reg(SIM_INFO.flt_args)) {
00843 --Current_Float_Param_Num;
00844 ploc.reg = 0;
00845 }
00846 else {
00847 ++Current_Float_Param_Num;
00848 ploc.reg2 = PR_first_reg(SIM_INFO.flt_args) + Current_Float_Param_Num;
00849 if (ploc.reg2 > PR_last_reg(SIM_INFO.flt_args)) {
00850 Current_Float_Param_Num -= 2;
00851 ploc.reg = 0;
00852 }
00853 }
00854 break;
00855
00856 case MTYPE_M:
00857 {
00858 enum X86_64_PARM_CLASS classes[MAX_CLASSES];
00859 INT Save_Current_Int_Param_Num = Current_Int_Param_Num;
00860 INT Save_Current_Float_Param_Num = Current_Float_Param_Num;
00861 ploc.size = TY_size (ty);
00862 INT n = Classify_Aggregate(ty, classes);
00863 if (n > 0) {
00864 if (classes[0] == X86_64_SSE_CLASS) {
00865 ++Current_Float_Param_Num;
00866 ploc.reg = PR_first_reg(SIM_INFO.flt_args) +
00867 Current_Float_Param_Num;
00868 if (ploc.reg > PR_last_reg(SIM_INFO.flt_args)) {
00869 Current_Float_Param_Num = Save_Current_Float_Param_Num;
00870 ploc.reg = 0;
00871 n = 0;
00872 }
00873 }
00874 else {
00875 ++Current_Int_Param_Num;
00876 ploc.reg = PR_first_reg(SIM_INFO.int_args) +
00877 Current_Int_Param_Num;
00878 if (ploc.reg > PR_last_reg(SIM_INFO.int_args)) {
00879 Current_Int_Param_Num = Save_Current_Int_Param_Num;
00880 ploc.reg = 0;
00881 n = 0;
00882 }
00883 }
00884 if (n > 1) {
00885 if (classes[1] == X86_64_SSE_CLASS) {
00886 ++Current_Float_Param_Num;
00887 ploc.reg2 = PR_first_reg(SIM_INFO.flt_args) +
00888 Current_Float_Param_Num;
00889 if (ploc.reg2 > PR_last_reg(SIM_INFO.flt_args)) {
00890 Current_Float_Param_Num = Save_Current_Float_Param_Num;
00891 Current_Int_Param_Num = Save_Current_Int_Param_Num;
00892 ploc.reg = 0;
00893 n = 0;
00894 }
00895 }
00896 else if (classes[1] == X86_64_INTEGER_CLASS) {
00897 ++Current_Int_Param_Num;
00898 ploc.reg2 = PR_first_reg(SIM_INFO.int_args) +
00899 Current_Int_Param_Num;
00900 if (ploc.reg2 > PR_last_reg(SIM_INFO.int_args)) {
00901 Current_Float_Param_Num = Save_Current_Float_Param_Num;
00902 Current_Int_Param_Num = Save_Current_Int_Param_Num;
00903 ploc.reg = 0;
00904 n = 0;
00905 }
00906 }
00907 }
00908 }
00909
00910
00911 if (n == 0 || ploc.reg == 0) {
00912 INT psize = TY_size (ty) / MTYPE_RegisterSize(SIM_INFO.int_type);
00913
00914 if ((TY_size (ty) % MTYPE_RegisterSize(SIM_INFO.int_type)) != 0)
00915 psize++;
00916
00917 rpad = (psize * MTYPE_RegisterSize(SIM_INFO.int_type)) - ploc.size;
00918
00919
00920
00921
00922
00923 if( TY_size(ty) == 0 &&
00924 PU_cxx_lang(Get_Current_PU()) ){
00925 if (Is_Target_32bit())
00926 rpad = 4;
00927 else
00928 rpad = 8;
00929 }
00930 }
00931 }
00932 break;
00933
00934 default:
00935 FmtAssert (FALSE, ("Get_Parameter_Location: mtype %s",
00936 MTYPE_name(pmtype)));
00937 }
00938 if (ploc.reg == 0)
00939 Last_Param_Offset = ploc.start_offset + ploc.size + rpad;
00940 return ploc;
00941 }
00942
00943 struct PSTRUCT {
00944 BOOL first_call;
00945 INT64 size;
00946 };
00947
00948 struct PSTRUCT pstruct;
00949
00950 static void
00951 Setup_Struct_Parameter_Locations (TY_IDX struct_ty)
00952 {
00953 pstruct.first_call = TRUE;
00954 pstruct.size = TY_size(struct_ty);
00955 }
00956
00957 static PLOC
00958 Get_Struct_Parameter_Location (PLOC ploc)
00959 {
00960 if (pstruct.first_call) {
00961 pstruct.first_call = FALSE;
00962 if (ploc.reg == 0)
00963 return ploc;
00964 ploc.size = MIN(pstruct.size, 8);
00965 return ploc;
00966 }
00967 if (ploc.reg2 != 0) {
00968 ploc.reg = ploc.reg2;
00969 ploc.reg2 = 0;
00970 ploc.start_offset += 8;
00971 ploc.size = pstruct.size - 8;
00972 return ploc;
00973 }
00974 ploc.reg = 0;
00975 ploc.size = 0;
00976 return ploc;
00977 }
00978
00979
00980
00981 static PLOC
00982 Get_Vararg_Parameter_Location (PLOC prev)
00983 {
00984 PLOC next;
00985 if (Current_Int_Param_Num + 1 < MAX_NUMBER_OF_INT_REGISTER_PARAMETERS) {
00986 Current_Param_Num++;
00987 Current_Int_Param_Num++;
00988 next.reg = PR_first_reg(SIM_INFO.int_args) + Current_Int_Param_Num;
00989 next.size = MTYPE_RegisterSize(SIM_INFO.int_type);
00990 return next;
00991 }
00992 if (Current_Float_Param_Num + 1 < MAX_NUMBER_OF_FLOAT_REGISTER_PARAMETERS) {
00993 Current_Param_Num++;
00994 Current_Float_Param_Num++;
00995 next.reg = PR_first_reg(SIM_INFO.flt_args) + Current_Float_Param_Num;
00996 next.size = MTYPE_RegisterSize(SIM_INFO.flt_type) * 2;
00997 return next;
00998 }
00999 next.reg = 0;
01000 next.size = 0;
01001 return next;
01002 }
01003
01004 BOOL Is_Caller_Save_GP;
01005
01006 INT Formal_Save_Area_Size = 0;
01007 INT Stack_Offset_Adjustment = 0;
01008
01009 extern void
01010 Init_Targ_Sim (void)
01011 {
01012 Is_Caller_Save_GP = SIM_caller_save_gp;
01013 }
01014