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