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 #define INCLUDING_IN_REGISTER // we modify register classes and we're
00037
00038
00039 #include "defs.h"
00040 #include "errors.h"
00041 #include "tracing.h"
00042 #include "mempool.h"
00043 #include "config.h"
00044 #include "glob.h"
00045 #include "util.h"
00046 #include "calls.h"
00047 #include "data_layout.h"
00048 #include "tn.h"
00049 #include "targ_sim.h"
00050 #include "op.h"
00051 #include "cg_flags.h"
00052 #include "ipfec_options.h"
00053
00054 #include "targ_isa_registers.h"
00055 #include "targ_abi_properties.h"
00056 #include "targ_isa_operands.h"
00057
00058 #include "register.h"
00059
00060
00061
00062 #define FIRST_INPUT_REG (32+REGISTER_MIN)
00063 #define FIRST_OUTPUT_REG (127+REGISTER_MIN)
00064 #define LAST_STACKED_REG (127+REGISTER_MIN)
00065 #define FIRST_ROTATING_INTEGER_REG (32+REGISTER_MIN)
00066 #define FIRST_ROTATING_FLOAT_REG (32+REGISTER_MIN)
00067 #define FIRST_ROTATING_PREDICATE_REG (16+REGISTER_MIN)
00068 #define LAST_ROTATING_INTEGER_REG (127+REGISTER_MIN)
00069 #define LAST_ROTATING_FLOAT_REG (127+REGISTER_MIN)
00070 #define LAST_ROTATING_PREDICATE_REG (63+REGISTER_MIN)
00071 #define MAX_NUM_OF_OUTPUT_REGISTERS 8
00072
00073
00074 static INT stacked_callee_next;
00075 static INT stacked_caller_next;
00076 static INT num_output_parameters;
00077 static INT num_caller;
00078 static INT num_rotating;
00079 static REGISTER_SET stacked_callee_used;
00080 REGISTER_SET stacked_caller_used;
00081 static INT stacked_minimum_output;
00082
00083 extern BOOL fat_self_recursive;
00084 extern BOOL can_use_stacked_reg;
00085
00086
00087 extern INT abi_property;
00088 extern ISA_REGISTER_CLASS reg_class;
00089 extern BOOL need_buffer;
00090 extern INT32 current_lrange;
00091
00092
00093
00095 void
00096 REGISTER_Init_Stacked(ISA_REGISTER_CLASS rclass)
00098
00099
00100
00102 {
00103 if (REGISTER_Has_Stacked_Registers(rclass)) {
00104 num_output_parameters = 0;
00105 num_caller = 0;
00106 num_rotating = 0;
00107
00108
00109
00110
00111 stacked_callee_next = FIRST_INPUT_REG - 1;
00112 stacked_caller_next = FIRST_OUTPUT_REG;
00113 stacked_callee_used = REGISTER_SET_EMPTY_SET;
00114 stacked_caller_used = REGISTER_SET_EMPTY_SET;
00115
00116
00117
00118
00119
00120
00121
00122 stacked_minimum_output = MAX_NUMBER_OF_REGISTER_PARAMETERS;
00123 }
00124 }
00125
00127 void REGISTER_Request_Stacked_Rotating_Register()
00129
00130
00131
00133 {
00134
00135
00136 const INT max_callee = 96 - 8;
00137 INT n_callee = MIN(max_callee, num_rotating);
00138 INT n_caller = MAX(0, num_rotating - max_callee);
00139 REGISTER r;
00140
00141 stacked_callee_next = MAX(stacked_callee_next, (INT) (FIRST_INPUT_REG - 1 + n_callee));
00142 for (r = FIRST_ROTATING_INTEGER_REG;
00143 r <= stacked_callee_next;
00144 r++) {
00145 stacked_callee_used = REGISTER_SET_Union1(stacked_callee_used, r);
00146 }
00147
00148 stacked_caller_next = MIN(stacked_caller_next, (INT) (FIRST_OUTPUT_REG - n_caller));
00149 num_caller = FIRST_OUTPUT_REG - stacked_caller_next;
00150 for (r = FIRST_OUTPUT_REG;
00151 r > stacked_caller_next;
00152 r--) {
00153 stacked_caller_used = REGISTER_SET_Union1(stacked_caller_used, r);
00154 }
00155
00156 ISA_REGISTER_CLASS i;
00157 FOR_ALL_ISA_REGISTER_CLASS(i) {
00158 if (REGISTER_Has_Rotating_Registers(i)) {
00159 REGISTER first = REGISTER_First_Rotating_Registers(i);
00160 REGISTER last = (i != ISA_REGISTER_CLASS_integer) ?
00161 REGISTER_Last_Rotating_Registers(i) : (first + num_rotating - 1);
00162
00163 REGISTER_CLASS_rotating(i) = REGISTER_SET_Range(first, last);
00164 }
00165 }
00166 }
00167
00168 INT32 Get_Stacked_Callee_Used() {
00169 INT32 stacked_callee_used = stacked_callee_next - 32;
00170 return stacked_callee_used;
00171 }
00172
00173 INT32 Get_Stacked_Caller_Used() {
00174 INT32 stacked_caller_used = 128 - stacked_caller_next;
00175 return stacked_caller_used;
00176 }
00177
00178 INT32 Get_Stacked_Callee_Next() {
00179 return stacked_callee_next;
00180 }
00181
00182 INT32 Get_Stacked_Caller_Next() {
00183 return stacked_caller_next;
00184 }
00185
00187 REGISTER REGISTER_Request_Stacked_Register(INT has_abi_property,
00188 ISA_REGISTER_CLASS rclass)
00190
00191
00192
00194 {
00195 need_buffer = FALSE;
00196 if (!REGISTER_Has_Stacked_Registers(rclass)) return REGISTER_UNDEFINED;
00197
00198 if (stacked_callee_next >= stacked_caller_next) return REGISTER_UNDEFINED;
00199 INT32 cut_num = IPFEC_Stacked_Cut_Num;
00200 if (fat_self_recursive) {
00201 if (!can_use_stacked_reg) {
00202 abi_property = has_abi_property;
00203 reg_class = rclass;
00204 need_buffer = TRUE;
00205 return REGISTER_UNDEFINED;
00206 }
00207 if ((stacked_callee_next + cut_num) >= stacked_caller_next)
00208 return REGISTER_UNDEFINED;
00209 }
00210
00211
00212
00213
00214
00215
00216 REGISTER result_reg;
00217
00218 if (has_abi_property == ABI_PROPERTY_callee ||
00219 has_abi_property == ABI_PROPERTY_frame_ptr) {
00220 result_reg = ++stacked_callee_next;
00221 if (has_abi_property != ABI_PROPERTY_frame_ptr) {
00222 stacked_callee_used = REGISTER_SET_Union1(stacked_callee_used,
00223 result_reg);
00224 }
00225 } else if ((has_abi_property == ABI_PROPERTY_caller ||
00226 has_abi_property == ABI_PROPERTY_stacked) && num_caller < MAX_NUM_OF_OUTPUT_REGISTERS) {
00227 result_reg = stacked_caller_next--;
00228 stacked_caller_used =
00229 REGISTER_SET_Union1(stacked_caller_used, result_reg);
00230 num_caller++;
00231 }
00232 else
00233 return REGISTER_UNDEFINED;
00234 if (fat_self_recursive) {
00235 DevWarn(" STACKED REGISTER %d ALLOCATED TO TN %d\n",result_reg,current_lrange);
00236 }
00237 return result_reg;
00238 }
00239
00241 REGISTER
00242 REGISTER_Allocate_Stacked_Register(INT has_abi_property,
00243 ISA_REGISTER_CLASS rclass,
00244 REGISTER reg)
00246
00247
00248
00250 {
00251 if (!REGISTER_Has_Stacked_Registers(rclass)) return REGISTER_UNDEFINED;
00252
00253 REGISTER result_reg;
00254
00255
00256
00257
00258 if (has_abi_property == ABI_PROPERTY_callee ||
00259 has_abi_property == ABI_PROPERTY_frame_ptr) {
00260 if (reg <= stacked_callee_next) {
00261
00262
00263
00264 result_reg = reg;
00265 } else if (reg < stacked_caller_next) {
00266
00267
00268
00269
00270
00271
00272
00273
00274 result_reg = reg;
00275 for (INT i = stacked_callee_next+1; i <= reg; ++i) {
00276 stacked_callee_used =
00277 REGISTER_SET_Union1(stacked_callee_used, i);
00278 }
00279 stacked_callee_next = reg;
00280 } else {
00281
00282 result_reg = REGISTER_UNDEFINED;
00283 }
00284
00285 if ( has_abi_property == ABI_PROPERTY_frame_ptr
00286 && result_reg != REGISTER_UNDEFINED)
00287 {
00288 stacked_callee_used =
00289 REGISTER_SET_Difference1(stacked_callee_used, result_reg);
00290 }
00291 } else {
00292 if (reg > stacked_caller_next) {
00293
00294
00295
00296 result_reg = reg;
00297 } else if (reg > stacked_callee_next) {
00298
00299
00300
00301
00302
00303
00304 result_reg = reg;
00305 stacked_caller_next = reg-1;
00306 num_caller = FIRST_OUTPUT_REG - stacked_caller_next;
00307 num_output_parameters = FIRST_OUTPUT_REG - reg + 1;
00308 for (INT i = FIRST_OUTPUT_REG; i > stacked_caller_next; --i) {
00309 stacked_caller_used =
00310 REGISTER_SET_Union1(stacked_caller_used, i);
00311 }
00312 } else {
00313
00314
00315
00316 result_reg = REGISTER_UNDEFINED;
00317 }
00318 }
00319 return result_reg;
00320 }
00321
00323 void
00324 REGISTER_Unallocate_Stacked_Register (
00325 ISA_REGISTER_CLASS rclass, REGISTER reg)
00326 {
00327 if ( ! REGISTER_Has_Stacked_Registers(rclass))
00328 return;
00329 stacked_callee_used = REGISTER_SET_Difference1(stacked_callee_used, reg);
00330 stacked_caller_used = REGISTER_SET_Difference1(stacked_caller_used, reg);
00331 }
00332
00334 BOOL
00335 REGISTER_Is_Allocatable_Stacked_Register (
00336 ISA_REGISTER_CLASS rclass, REGISTER reg)
00337 {
00338 if ( ! REGISTER_Has_Stacked_Registers(rclass)) {
00339 return FALSE;
00340 }
00341 else if (reg <= stacked_callee_next) {
00342 return REGISTER_SET_MemberP(stacked_callee_used, reg);
00343 }
00344 else if (reg >= stacked_caller_next) {
00345 return REGISTER_SET_MemberP(stacked_caller_used, reg);
00346 }
00347 else {
00348 return FALSE;
00349 }
00350 }
00351
00353 REGISTER_SET
00354 REGISTER_Get_Stacked_Avail_Set(INT has_abi_property, ISA_REGISTER_CLASS rclass)
00356
00357
00358
00360 {
00361 if (REGISTER_Has_Stacked_Registers(rclass)) {
00362 if (has_abi_property == ABI_PROPERTY_callee) {
00363 REGISTER_SET avail = stacked_callee_used;
00364 return avail;
00365 } else if (has_abi_property == ABI_PROPERTY_caller) {
00366 return stacked_caller_used;
00367 } else if (has_abi_property == ABI_PROPERTY_stacked) {
00368 if (CG_localize_tns && LOCALIZE_using_stacked_regs) {
00369
00370
00371
00372 return stacked_caller_used;
00373 }
00374 else {
00375 REGISTER_SET avail = stacked_callee_used;
00376 return REGISTER_SET_Union(avail, stacked_caller_used);
00377 }
00378 } else {
00379 FmtAssert(FALSE, ("REGISTER: Unknown abi property for stacked register"));
00380 }
00381 }
00382 return REGISTER_SET_EMPTY_SET;
00383 }
00384
00386 BOOL
00387 REGISTER_Is_Stacked_Output(ISA_REGISTER_CLASS rclass, REGISTER reg)
00389
00390
00391
00393 {
00394 if ( ! REGISTER_Has_Stacked_Registers(rclass)) {
00395 return FALSE;
00396 }
00397 if (reg > stacked_caller_next) {
00398 return TRUE;
00399 }
00400 return FALSE;
00401 }
00402
00403
00405 BOOL
00406 REGISTER_Is_Stacked_Local(ISA_REGISTER_CLASS rclass, REGISTER reg)
00408
00409
00410
00412 {
00413 if ( ! REGISTER_Has_Stacked_Registers(rclass)) {
00414 return FALSE;
00415 }
00416 if (reg <= stacked_caller_next && reg >= FIRST_INPUT_REG) {
00417 return TRUE;
00418 }
00419 return FALSE;
00420 }
00421
00422
00424 BOOL
00425 REGISTER_Is_Stacked(ISA_REGISTER_CLASS rclass, REGISTER reg)
00427
00428
00429
00431 {
00432 if ( ! REGISTER_Has_Stacked_Registers(rclass)) {
00433 return FALSE;
00434 }
00435 if (reg >= FIRST_INPUT_REG) return TRUE;
00436 return FALSE;
00437 }
00438
00440 BOOL
00441 REGISTER_Is_Rotating(ISA_REGISTER_CLASS rclass, REGISTER reg)
00443
00444
00445
00447 {
00448
00449 switch(rclass) {
00450 case ISA_REGISTER_CLASS_integer:
00451 if (reg >= FIRST_ROTATING_INTEGER_REG &&
00452 reg <= LAST_ROTATING_INTEGER_REG) return TRUE;
00453 break;
00454 case ISA_REGISTER_CLASS_float:
00455 if (reg >= FIRST_ROTATING_FLOAT_REG &&
00456 reg <= LAST_ROTATING_FLOAT_REG) return TRUE;
00457 break;
00458 case ISA_REGISTER_CLASS_predicate:
00459 if (reg >= FIRST_ROTATING_PREDICATE_REG &&
00460 reg <= LAST_ROTATING_PREDICATE_REG) return TRUE;
00461 }
00462
00463 return FALSE;
00464 }
00465
00467 REGISTER
00468 REGISTER_Translate_Stacked_Output(REGISTER reg)
00470
00471
00472
00474 {
00475 REGISTER result;
00476 if (reg > FIRST_OUTPUT_REG - num_output_parameters) {
00477
00478
00479
00480
00481 result = stacked_callee_next + (FIRST_OUTPUT_REG - reg) + 1;
00482 }
00483 else {
00484
00485
00486
00487 INT first_reg = stacked_callee_next + num_output_parameters + 1;
00488 INT first_caller = stacked_caller_next + 1;
00489 result = reg - (first_caller - first_reg);
00490 }
00491 if (Get_Trace ( TP_EMIT, 16 ))
00492 fprintf(TFile, "translate stacked reg %d to %d\n", reg, result);
00493 return result;
00494 }
00495
00496 static char outregname[6] = "out0";
00497
00499 char *
00500 REGISTER_Stacked_Output_Name (REGISTER reg)
00502 {
00503
00504 INT num = FIRST_OUTPUT_REG - reg;
00505 outregname[3] = '0'+num;
00506 outregname[4] = '\0';
00507 return outregname;
00508 }
00509
00510
00512 INT
00513 REGISTER_Number_Stacked_Local (ISA_REGISTER_CLASS rclass)
00515
00516
00517
00519 {
00520 if (rclass != ISA_REGISTER_CLASS_integer) return 0;
00521 return stacked_callee_next - FIRST_INPUT_REG + 1;
00522 }
00523
00524
00526 INT
00527 REGISTER_Number_Stacked_Output (ISA_REGISTER_CLASS rclass)
00529
00530
00531
00533 {
00534
00535
00536
00537
00538
00539
00540 if (rclass != ISA_REGISTER_CLASS_integer) return 0;
00541 return num_caller;
00542 }
00543
00544
00546 INT
00547 REGISTER_Number_Stacked_Rotating (ISA_REGISTER_CLASS rclass)
00549
00550
00551
00553 {
00554 if (rclass != ISA_REGISTER_CLASS_integer) return 0;
00555 return num_rotating;
00556 }
00557
00558 INT REGISTER_Number_Stacked_Registers_Available (ISA_REGISTER_CLASS rclass)
00559 {
00560 if (rclass != ISA_REGISTER_CLASS_integer) return 0;
00561 return stacked_caller_next - stacked_callee_next;
00562 }
00563
00564
00566 void REGISTER_Reserve_Rotating_Registers(ISA_REGISTER_CLASS rclass, INT n)
00568
00569
00570
00572 {
00573 num_rotating = MAX(num_rotating, n);
00574
00575 if ((num_rotating & 7) != 0) {
00576 num_rotating &= ~7;
00577 num_rotating += 8;
00578 }
00579 }
00580
00582 void
00583 REGISTER_Set_Stacked_Output_Minimum(ISA_REGISTER_CLASS rclass, INT num)
00585
00586
00587
00589 {
00590 if (REGISTER_Has_Stacked_Registers(rclass)) {
00591 if (num_output_parameters > num) {
00592 stacked_minimum_output = num_output_parameters;
00593 DevWarn("Attempted to set minimum stacked output to %d when %d output parameters already allocated.\n", num, num_output_parameters);
00594 } else {
00595 stacked_minimum_output = num;
00596 }
00597 }
00598 }
00599
00600
00602 REGISTER REGISTER_First_Rotating_Registers(ISA_REGISTER_CLASS rclass)
00604
00605
00606
00608 {
00609 switch (rclass) {
00610 case ISA_REGISTER_CLASS_integer:
00611 return FIRST_ROTATING_INTEGER_REG;
00612 case ISA_REGISTER_CLASS_float:
00613 return FIRST_ROTATING_FLOAT_REG;
00614 case ISA_REGISTER_CLASS_predicate:
00615 return FIRST_ROTATING_PREDICATE_REG;
00616 }
00617 return REGISTER_UNDEFINED;
00618 }
00619
00621 REGISTER REGISTER_Last_Rotating_Registers(ISA_REGISTER_CLASS rclass)
00623
00624
00625
00627 {
00628 switch (rclass) {
00629 case ISA_REGISTER_CLASS_integer:
00630 return LAST_ROTATING_INTEGER_REG;
00631 case ISA_REGISTER_CLASS_float:
00632 return LAST_ROTATING_FLOAT_REG;
00633 case ISA_REGISTER_CLASS_predicate:
00634 return LAST_ROTATING_PREDICATE_REG;
00635 }
00636 return REGISTER_UNDEFINED;
00637 }
00638
00639
00641 REGISTER_SET REGISTER_Get_Requested_Rotating_Registers(ISA_REGISTER_CLASS rclass)
00643
00644
00645
00647 {
00648 switch (rclass) {
00649 case ISA_REGISTER_CLASS_integer:
00650 return REGISTER_SET_Range(FIRST_ROTATING_INTEGER_REG,
00651 FIRST_ROTATING_INTEGER_REG + num_rotating);
00652 case ISA_REGISTER_CLASS_float:
00653 return REGISTER_SET_Range(FIRST_ROTATING_FLOAT_REG,
00654 LAST_ROTATING_FLOAT_REG);
00655 case ISA_REGISTER_CLASS_predicate:
00656 return REGISTER_SET_Range(FIRST_ROTATING_PREDICATE_REG,
00657 LAST_ROTATING_PREDICATE_REG);
00658 }
00659 return REGISTER_SET_EMPTY_SET;
00660 }
00661
00662
00663 mISA_REGISTER_CLASS Mtype_RegClass_Map[MTYPE_LAST+1];
00664
00665 void Init_Mtype_RegClass_Map(void)
00666 {
00667 INT i;
00668 mISA_REGISTER_CLASS * const map = Mtype_RegClass_Map;
00669
00670 for (i = 0; i <= MTYPE_LAST; ++i) map[i] = ISA_REGISTER_CLASS_UNDEFINED;
00671
00672 map[MTYPE_B] = ISA_REGISTER_CLASS_predicate;
00673 map[MTYPE_I1] = ISA_REGISTER_CLASS_integer;
00674 map[MTYPE_I2] = ISA_REGISTER_CLASS_integer;
00675 map[MTYPE_I4] = ISA_REGISTER_CLASS_integer;
00676 map[MTYPE_I8] = ISA_REGISTER_CLASS_integer;
00677 map[MTYPE_U1] = ISA_REGISTER_CLASS_integer;
00678 map[MTYPE_U2] = ISA_REGISTER_CLASS_integer;
00679 map[MTYPE_U4] = ISA_REGISTER_CLASS_integer;
00680 map[MTYPE_U8] = ISA_REGISTER_CLASS_integer;
00681 map[MTYPE_F4] = ISA_REGISTER_CLASS_float;
00682 map[MTYPE_F8] = ISA_REGISTER_CLASS_float;
00683 map[MTYPE_F10] = ISA_REGISTER_CLASS_float;
00684 map[MTYPE_F16] = ISA_REGISTER_CLASS_UNDEFINED;
00685
00686 map[MTYPE_A8] = ISA_REGISTER_CLASS_branch;
00687 }