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 #include "config.h"
00029 #include "system.h"
00030 #include "coretypes.h"
00031 #include "tm.h"
00032 #include "hard-reg-set.h"
00033 #include "rtl.h"
00034 #include "expr.h"
00035 #include "tm_p.h"
00036 #include "flags.h"
00037 #include "basic-block.h"
00038 #include "regs.h"
00039 #include "addresses.h"
00040 #include "function.h"
00041 #include "insn-config.h"
00042 #include "recog.h"
00043 #include "reload.h"
00044 #include "real.h"
00045 #include "toplev.h"
00046 #include "output.h"
00047 #include "ggc.h"
00048 #include "timevar.h"
00049 #include "hashtab.h"
00050 #include "target.h"
00051
00052 static void init_reg_sets_1 (void);
00053 static void init_reg_autoinc (void);
00054
00055
00056
00057
00058
00059
00060 #if defined(AUTO_INC_DEC)
00061 #define FORBIDDEN_INC_DEC_CLASSES
00062 #endif
00063
00064
00065
00066
00067
00068
00069
00070
00071 char fixed_regs[FIRST_PSEUDO_REGISTER];
00072
00073
00074
00075 HARD_REG_SET fixed_reg_set;
00076
00077
00078
00079 static const char initial_fixed_regs[] = FIXED_REGISTERS;
00080
00081
00082
00083
00084
00085
00086
00087 char call_used_regs[FIRST_PSEUDO_REGISTER];
00088
00089
00090
00091 HARD_REG_SET call_used_reg_set;
00092
00093
00094 HARD_REG_SET losing_caller_save_reg_set;
00095
00096
00097
00098 static const char initial_call_used_regs[] = CALL_USED_REGISTERS;
00099
00100
00101
00102
00103
00104
00105 #ifdef CALL_REALLY_USED_REGISTERS
00106 char call_really_used_regs[] = CALL_REALLY_USED_REGISTERS;
00107 #endif
00108
00109 #ifdef CALL_REALLY_USED_REGISTERS
00110 #define CALL_REALLY_USED_REGNO_P(X) call_really_used_regs[X]
00111 #else
00112 #define CALL_REALLY_USED_REGNO_P(X) call_used_regs[X]
00113 #endif
00114
00115
00116
00117
00118
00119
00120
00121 char call_fixed_regs[FIRST_PSEUDO_REGISTER];
00122
00123
00124
00125 HARD_REG_SET call_fixed_reg_set;
00126
00127
00128
00129
00130
00131
00132 char global_regs[FIRST_PSEUDO_REGISTER];
00133
00134
00135
00136
00137
00138
00139
00140
00141 HARD_REG_SET regs_invalidated_by_call;
00142
00143
00144 #ifdef REG_ALLOC_ORDER
00145 int reg_alloc_order[FIRST_PSEUDO_REGISTER] = REG_ALLOC_ORDER;
00146
00147
00148 int inv_reg_alloc_order[FIRST_PSEUDO_REGISTER];
00149 #endif
00150
00151
00152
00153 HARD_REG_SET reg_class_contents[N_REG_CLASSES];
00154
00155
00156
00157
00158
00159
00160 #define N_REG_INTS \
00161 ((FIRST_PSEUDO_REGISTER + (32 - 1)) / 32)
00162
00163 static const unsigned int_reg_class_contents[N_REG_CLASSES][N_REG_INTS]
00164 = REG_CLASS_CONTENTS;
00165
00166
00167
00168 unsigned int reg_class_size[N_REG_CLASSES];
00169
00170
00171
00172 static enum reg_class reg_class_superclasses[N_REG_CLASSES][N_REG_CLASSES];
00173
00174
00175
00176 static enum reg_class reg_class_subclasses[N_REG_CLASSES][N_REG_CLASSES];
00177
00178
00179
00180
00181 enum reg_class reg_class_subunion[N_REG_CLASSES][N_REG_CLASSES];
00182
00183
00184
00185
00186 enum reg_class reg_class_superunion[N_REG_CLASSES][N_REG_CLASSES];
00187
00188
00189
00190 const char * reg_names[] = REGISTER_NAMES;
00191
00192
00193
00194 const char * reg_class_names[] = REG_CLASS_NAMES;
00195
00196
00197
00198
00199
00200
00201 enum machine_mode reg_raw_mode[FIRST_PSEUDO_REGISTER];
00202
00203
00204
00205 bool have_regs_of_mode [MAX_MACHINE_MODE];
00206
00207
00208
00209 static char contains_reg_of_mode [N_REG_CLASSES] [MAX_MACHINE_MODE];
00210
00211
00212
00213
00214 static int move_cost[MAX_MACHINE_MODE][N_REG_CLASSES][N_REG_CLASSES];
00215
00216
00217
00218
00219 static int may_move_in_cost[MAX_MACHINE_MODE][N_REG_CLASSES][N_REG_CLASSES];
00220
00221
00222
00223
00224 static int may_move_out_cost[MAX_MACHINE_MODE][N_REG_CLASSES][N_REG_CLASSES];
00225
00226 #ifdef FORBIDDEN_INC_DEC_CLASSES
00227
00228
00229
00230
00231 static int forbidden_inc_dec_class[N_REG_CLASSES];
00232
00233
00234
00235
00236 static char *in_inc_dec;
00237
00238 #endif
00239
00240
00241
00242 static GTY(()) rtx top_of_stack[MAX_MACHINE_MODE];
00243
00244
00245
00246
00247
00248 struct reg_info_data {
00249 struct reg_info_data *next;
00250 size_t min_index;
00251 size_t max_index;
00252 char used_p;
00253 reg_info data[1];
00254 };
00255
00256 static struct reg_info_data *reg_info_head;
00257
00258
00259
00260
00261 static int no_global_reg_vars = 0;
00262
00263
00264 unsigned char hard_regno_nregs[FIRST_PSEUDO_REGISTER][MAX_MACHINE_MODE];
00265
00266
00267
00268
00269 void
00270 init_reg_sets (void)
00271 {
00272 int i, j;
00273
00274
00275
00276
00277 for (i = 0; i < N_REG_CLASSES; i++)
00278 {
00279 CLEAR_HARD_REG_SET (reg_class_contents[i]);
00280
00281
00282 for (j = 0; j < FIRST_PSEUDO_REGISTER; j++)
00283 if (int_reg_class_contents[i][j / 32]
00284 & ((unsigned) 1 << (j % 32)))
00285 SET_HARD_REG_BIT (reg_class_contents[i], j);
00286 }
00287
00288
00289
00290 gcc_assert (sizeof fixed_regs == sizeof initial_fixed_regs);
00291 gcc_assert (sizeof call_used_regs == sizeof initial_call_used_regs);
00292
00293 memcpy (fixed_regs, initial_fixed_regs, sizeof fixed_regs);
00294 memcpy (call_used_regs, initial_call_used_regs, sizeof call_used_regs);
00295 memset (global_regs, 0, sizeof global_regs);
00296
00297 #ifdef REG_ALLOC_ORDER
00298 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
00299 inv_reg_alloc_order[reg_alloc_order[i]] = i;
00300 #endif
00301 }
00302
00303
00304
00305
00306 static void
00307 init_reg_sets_1 (void)
00308 {
00309 unsigned int i, j;
00310 unsigned int m;
00311
00312
00313
00314
00315 #ifdef CONDITIONAL_REGISTER_USAGE
00316 CONDITIONAL_REGISTER_USAGE;
00317 #endif
00318
00319
00320
00321 memset (reg_class_size, 0, sizeof reg_class_size);
00322 for (i = 0; i < N_REG_CLASSES; i++)
00323 for (j = 0; j < FIRST_PSEUDO_REGISTER; j++)
00324 if (TEST_HARD_REG_BIT (reg_class_contents[i], j))
00325 reg_class_size[i]++;
00326
00327
00328
00329
00330
00331 for (i = 0; i < N_REG_CLASSES; i++)
00332 {
00333 for (j = 0; j < N_REG_CLASSES; j++)
00334 {
00335 HARD_REG_SET c;
00336 int k;
00337
00338 COPY_HARD_REG_SET (c, reg_class_contents[i]);
00339 IOR_HARD_REG_SET (c, reg_class_contents[j]);
00340 for (k = 0; k < N_REG_CLASSES; k++)
00341 {
00342 GO_IF_HARD_REG_SUBSET (reg_class_contents[k], c,
00343 subclass1);
00344 continue;
00345
00346 subclass1:
00347
00348 GO_IF_HARD_REG_SUBSET (reg_class_contents[k],
00349 reg_class_contents[(int) reg_class_subunion[i][j]],
00350 subclass2);
00351 reg_class_subunion[i][j] = (enum reg_class) k;
00352 subclass2:
00353 ;
00354 }
00355 }
00356 }
00357
00358
00359
00360
00361
00362 for (i = 0; i < N_REG_CLASSES; i++)
00363 {
00364 for (j = 0; j < N_REG_CLASSES; j++)
00365 {
00366 HARD_REG_SET c;
00367 int k;
00368
00369 COPY_HARD_REG_SET (c, reg_class_contents[i]);
00370 IOR_HARD_REG_SET (c, reg_class_contents[j]);
00371 for (k = 0; k < N_REG_CLASSES; k++)
00372 GO_IF_HARD_REG_SUBSET (c, reg_class_contents[k], superclass);
00373
00374 superclass:
00375 reg_class_superunion[i][j] = (enum reg_class) k;
00376 }
00377 }
00378
00379
00380
00381
00382 for (i = 0; i < N_REG_CLASSES; i++)
00383 {
00384 for (j = 0; j < N_REG_CLASSES; j++)
00385 {
00386 reg_class_superclasses[i][j] = LIM_REG_CLASSES;
00387 reg_class_subclasses[i][j] = LIM_REG_CLASSES;
00388 }
00389 }
00390
00391 for (i = 0; i < N_REG_CLASSES; i++)
00392 {
00393 if (i == (int) NO_REGS)
00394 continue;
00395
00396 for (j = i + 1; j < N_REG_CLASSES; j++)
00397 {
00398 enum reg_class *p;
00399
00400 GO_IF_HARD_REG_SUBSET (reg_class_contents[i], reg_class_contents[j],
00401 subclass);
00402 continue;
00403 subclass:
00404
00405
00406 p = ®_class_superclasses[i][0];
00407 while (*p != LIM_REG_CLASSES) p++;
00408 *p = (enum reg_class) j;
00409
00410 p = ®_class_subclasses[j][0];
00411 while (*p != LIM_REG_CLASSES) p++;
00412 *p = (enum reg_class) i;
00413 }
00414 }
00415
00416
00417
00418 CLEAR_HARD_REG_SET (fixed_reg_set);
00419 CLEAR_HARD_REG_SET (call_used_reg_set);
00420 CLEAR_HARD_REG_SET (call_fixed_reg_set);
00421 CLEAR_HARD_REG_SET (regs_invalidated_by_call);
00422
00423 memcpy (call_fixed_regs, fixed_regs, sizeof call_fixed_regs);
00424
00425 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
00426 {
00427
00428 gcc_assert (!fixed_regs[i] || call_used_regs[i]);
00429 #ifdef CALL_REALLY_USED_REGISTERS
00430
00431 gcc_assert (!call_really_used_regs[i] || call_used_regs[i]);
00432 #endif
00433
00434 if (fixed_regs[i])
00435 SET_HARD_REG_BIT (fixed_reg_set, i);
00436
00437 if (call_used_regs[i])
00438 SET_HARD_REG_BIT (call_used_reg_set, i);
00439 if (call_fixed_regs[i])
00440 SET_HARD_REG_BIT (call_fixed_reg_set, i);
00441 if (CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (i)))
00442 SET_HARD_REG_BIT (losing_caller_save_reg_set, i);
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453 if (i == STACK_POINTER_REGNUM)
00454 ;
00455 else if (global_regs[i])
00456 SET_HARD_REG_BIT (regs_invalidated_by_call, i);
00457 else if (i == FRAME_POINTER_REGNUM)
00458 ;
00459 #if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
00460 else if (i == HARD_FRAME_POINTER_REGNUM)
00461 ;
00462 #endif
00463 #if ARG_POINTER_REGNUM != FRAME_POINTER_REGNUM
00464 else if (i == ARG_POINTER_REGNUM && fixed_regs[i])
00465 ;
00466 #endif
00467 #ifndef PIC_OFFSET_TABLE_REG_CALL_CLOBBERED
00468 else if (i == (unsigned) PIC_OFFSET_TABLE_REGNUM && fixed_regs[i])
00469 ;
00470 #endif
00471 else if (CALL_REALLY_USED_REGNO_P (i))
00472 SET_HARD_REG_BIT (regs_invalidated_by_call, i);
00473 }
00474
00475 memset (have_regs_of_mode, 0, sizeof (have_regs_of_mode));
00476 memset (contains_reg_of_mode, 0, sizeof (contains_reg_of_mode));
00477 for (m = 0; m < (unsigned int) MAX_MACHINE_MODE; m++)
00478 for (i = 0; i < N_REG_CLASSES; i++)
00479 if ((unsigned) CLASS_MAX_NREGS (i, m) <= reg_class_size[i])
00480 for (j = 0; j < FIRST_PSEUDO_REGISTER; j++)
00481 if (!fixed_regs [j] && TEST_HARD_REG_BIT (reg_class_contents[i], j)
00482 && HARD_REGNO_MODE_OK (j, m))
00483 {
00484 contains_reg_of_mode [i][m] = 1;
00485 have_regs_of_mode [m] = 1;
00486 break;
00487 }
00488
00489
00490
00491
00492 for (m = 0; m < (unsigned int) MAX_MACHINE_MODE; m++)
00493 if (have_regs_of_mode [m])
00494 {
00495 for (i = 0; i < N_REG_CLASSES; i++)
00496 if (contains_reg_of_mode [i][m])
00497 for (j = 0; j < N_REG_CLASSES; j++)
00498 {
00499 int cost;
00500 enum reg_class *p1, *p2;
00501
00502 if (!contains_reg_of_mode [j][m])
00503 {
00504 move_cost[m][i][j] = 65536;
00505 may_move_in_cost[m][i][j] = 65536;
00506 may_move_out_cost[m][i][j] = 65536;
00507 }
00508 else
00509 {
00510 cost = REGISTER_MOVE_COST (m, i, j);
00511
00512 for (p2 = ®_class_subclasses[j][0];
00513 *p2 != LIM_REG_CLASSES;
00514 p2++)
00515 if (*p2 != i && contains_reg_of_mode [*p2][m])
00516 cost = MAX (cost, move_cost [m][i][*p2]);
00517
00518 for (p1 = ®_class_subclasses[i][0];
00519 *p1 != LIM_REG_CLASSES;
00520 p1++)
00521 if (*p1 != j && contains_reg_of_mode [*p1][m])
00522 cost = MAX (cost, move_cost [m][*p1][j]);
00523
00524 move_cost[m][i][j] = cost;
00525
00526 if (reg_class_subset_p (i, j))
00527 may_move_in_cost[m][i][j] = 0;
00528 else
00529 may_move_in_cost[m][i][j] = cost;
00530
00531 if (reg_class_subset_p (j, i))
00532 may_move_out_cost[m][i][j] = 0;
00533 else
00534 may_move_out_cost[m][i][j] = cost;
00535 }
00536 }
00537 else
00538 for (j = 0; j < N_REG_CLASSES; j++)
00539 {
00540 move_cost[m][i][j] = 65536;
00541 may_move_in_cost[m][i][j] = 65536;
00542 may_move_out_cost[m][i][j] = 65536;
00543 }
00544 }
00545 }
00546
00547
00548
00549
00550
00551 void
00552 init_reg_modes_once (void)
00553 {
00554 int i, j;
00555
00556 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
00557 for (j = 0; j < MAX_MACHINE_MODE; j++)
00558 hard_regno_nregs[i][j] = HARD_REGNO_NREGS(i, (enum machine_mode)j);
00559
00560 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
00561 {
00562 reg_raw_mode[i] = choose_hard_reg_mode (i, 1, false);
00563
00564
00565
00566
00567
00568
00569 if (reg_raw_mode[i] == VOIDmode)
00570 reg_raw_mode[i] = i == 0 ? word_mode : reg_raw_mode[i-1];
00571 }
00572 }
00573
00574
00575
00576
00577 void
00578 init_regs (void)
00579 {
00580
00581
00582 init_reg_sets_1 ();
00583
00584 init_reg_autoinc ();
00585 }
00586
00587
00588
00589
00590 void
00591 init_fake_stack_mems (void)
00592 {
00593 {
00594 int i;
00595
00596 for (i = 0; i < MAX_MACHINE_MODE; i++)
00597 top_of_stack[i] = gen_rtx_MEM (i, stack_pointer_rtx);
00598 }
00599 }
00600
00601
00602
00603
00604
00605 int
00606 memory_move_secondary_cost (enum machine_mode mode, enum reg_class class, int in)
00607 {
00608 enum reg_class altclass;
00609 int partial_cost = 0;
00610
00611
00612 rtx mem ATTRIBUTE_UNUSED = top_of_stack[(int) mode];
00613
00614
00615 altclass = secondary_reload_class (in ? 1 : 0, class, mode, mem);
00616
00617 if (altclass == NO_REGS)
00618 return 0;
00619
00620 if (in)
00621 partial_cost = REGISTER_MOVE_COST (mode, altclass, class);
00622 else
00623 partial_cost = REGISTER_MOVE_COST (mode, class, altclass);
00624
00625 if (class == altclass)
00626
00627
00628
00629
00630
00631
00632
00633 return partial_cost;
00634
00635
00636
00637 return memory_move_secondary_cost (mode, altclass, in) + partial_cost;
00638 }
00639
00640
00641
00642
00643
00644 enum machine_mode
00645 choose_hard_reg_mode (unsigned int regno ATTRIBUTE_UNUSED,
00646 unsigned int nregs, bool call_saved)
00647 {
00648 unsigned int m;
00649 enum machine_mode found_mode = VOIDmode, mode;
00650
00651
00652
00653
00654
00655 for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
00656 mode != VOIDmode;
00657 mode = GET_MODE_WIDER_MODE (mode))
00658 if ((unsigned) hard_regno_nregs[regno][mode] == nregs
00659 && HARD_REGNO_MODE_OK (regno, mode)
00660 && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)))
00661 found_mode = mode;
00662
00663 if (found_mode != VOIDmode)
00664 return found_mode;
00665
00666 for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
00667 mode != VOIDmode;
00668 mode = GET_MODE_WIDER_MODE (mode))
00669 if ((unsigned) hard_regno_nregs[regno][mode] == nregs
00670 && HARD_REGNO_MODE_OK (regno, mode)
00671 && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)))
00672 found_mode = mode;
00673
00674 if (found_mode != VOIDmode)
00675 return found_mode;
00676
00677 for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT);
00678 mode != VOIDmode;
00679 mode = GET_MODE_WIDER_MODE (mode))
00680 if ((unsigned) hard_regno_nregs[regno][mode] == nregs
00681 && HARD_REGNO_MODE_OK (regno, mode)
00682 && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)))
00683 found_mode = mode;
00684
00685 if (found_mode != VOIDmode)
00686 return found_mode;
00687
00688 for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT);
00689 mode != VOIDmode;
00690 mode = GET_MODE_WIDER_MODE (mode))
00691 if ((unsigned) hard_regno_nregs[regno][mode] == nregs
00692 && HARD_REGNO_MODE_OK (regno, mode)
00693 && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)))
00694 found_mode = mode;
00695
00696 if (found_mode != VOIDmode)
00697 return found_mode;
00698
00699
00700 for (m = (unsigned int) CCmode; m < (unsigned int) NUM_MACHINE_MODES; ++m)
00701 {
00702 mode = (enum machine_mode) m;
00703 if ((unsigned) hard_regno_nregs[regno][mode] == nregs
00704 && HARD_REGNO_MODE_OK (regno, mode)
00705 && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)))
00706 return mode;
00707 }
00708
00709
00710 return VOIDmode;
00711 }
00712
00713
00714
00715
00716
00717 void
00718 fix_register (const char *name, int fixed, int call_used)
00719 {
00720 int i;
00721
00722
00723
00724
00725 if ((i = decode_reg_name (name)) >= 0)
00726 {
00727 if ((i == STACK_POINTER_REGNUM
00728 #ifdef HARD_FRAME_POINTER_REGNUM
00729 || i == HARD_FRAME_POINTER_REGNUM
00730 #else
00731 || i == FRAME_POINTER_REGNUM
00732 #endif
00733 )
00734 && (fixed == 0 || call_used == 0))
00735 {
00736 static const char * const what_option[2][2] = {
00737 { "call-saved", "call-used" },
00738 { "no-such-option", "fixed" }};
00739
00740 error ("can't use '%s' as a %s register", name,
00741 what_option[fixed][call_used]);
00742 }
00743 else
00744 {
00745 fixed_regs[i] = fixed;
00746 call_used_regs[i] = call_used;
00747 #ifdef CALL_REALLY_USED_REGISTERS
00748 if (fixed == 0)
00749 call_really_used_regs[i] = call_used;
00750 #endif
00751 }
00752 }
00753 else
00754 {
00755 warning (0, "unknown register name: %s", name);
00756 }
00757 }
00758
00759
00760
00761 void
00762 globalize_reg (int i)
00763 {
00764 if (fixed_regs[i] == 0 && no_global_reg_vars)
00765 error ("global register variable follows a function definition");
00766
00767 if (global_regs[i])
00768 {
00769 warning (0, "register used for two global register variables");
00770 return;
00771 }
00772
00773 if (call_used_regs[i] && ! fixed_regs[i])
00774 warning (0, "call-clobbered register used for global register variable");
00775
00776 global_regs[i] = 1;
00777
00778
00779
00780
00781 if (i != STACK_POINTER_REGNUM)
00782 SET_HARD_REG_BIT (regs_invalidated_by_call, i);
00783
00784
00785 if (fixed_regs[i])
00786 return;
00787
00788 fixed_regs[i] = call_used_regs[i] = call_fixed_regs[i] = 1;
00789 #ifdef CALL_REALLY_USED_REGISTERS
00790 call_really_used_regs[i] = 1;
00791 #endif
00792
00793 SET_HARD_REG_BIT (fixed_reg_set, i);
00794 SET_HARD_REG_BIT (call_used_reg_set, i);
00795 SET_HARD_REG_BIT (call_fixed_reg_set, i);
00796 }
00797
00798
00799
00800
00801
00802
00803
00804
00805 struct costs
00806 {
00807 int cost[N_REG_CLASSES];
00808 int mem_cost;
00809 };
00810
00811
00812 struct reg_pref
00813 {
00814
00815
00816 char prefclass;
00817
00818
00819
00820
00821
00822
00823
00824
00825 char altclass;
00826 };
00827
00828
00829
00830 static struct costs *costs;
00831
00832
00833
00834 static struct costs init_cost;
00835
00836
00837
00838
00839 static struct reg_pref *reg_pref;
00840
00841
00842
00843 static struct reg_pref *reg_pref_buffer;
00844
00845
00846
00847 static int frequency;
00848
00849 static rtx scan_one_insn (rtx, int);
00850 static void record_operand_costs (rtx, struct costs *, struct reg_pref *);
00851 static void dump_regclass (FILE *);
00852 static void record_reg_classes (int, int, rtx *, enum machine_mode *,
00853 const char **, rtx, struct costs *,
00854 struct reg_pref *);
00855 static int copy_cost (rtx, enum machine_mode, enum reg_class, int,
00856 secondary_reload_info *);
00857 static void record_address_regs (enum machine_mode, rtx, int, enum rtx_code,
00858 enum rtx_code, int);
00859 #ifdef FORBIDDEN_INC_DEC_CLASSES
00860 static int auto_inc_dec_reg_p (rtx, enum machine_mode);
00861 #endif
00862 static void reg_scan_mark_refs (rtx, rtx, int);
00863
00864
00865
00866 static inline bool
00867 ok_for_index_p_nonstrict (rtx reg)
00868 {
00869 unsigned regno = REGNO (reg);
00870 return regno >= FIRST_PSEUDO_REGISTER || REGNO_OK_FOR_INDEX_P (regno);
00871 }
00872
00873
00874
00875
00876 static inline bool
00877 ok_for_base_p_nonstrict (rtx reg, enum machine_mode mode,
00878 enum rtx_code outer_code, enum rtx_code index_code)
00879 {
00880 unsigned regno = REGNO (reg);
00881 if (regno >= FIRST_PSEUDO_REGISTER)
00882 return true;
00883
00884 return ok_for_base_p_1 (regno, mode, outer_code, index_code);
00885 }
00886
00887
00888
00889
00890
00891 enum reg_class
00892 reg_preferred_class (int regno)
00893 {
00894 if (reg_pref == 0)
00895 return GENERAL_REGS;
00896 return (enum reg_class) reg_pref[regno].prefclass;
00897 }
00898
00899 enum reg_class
00900 reg_alternate_class (int regno)
00901 {
00902 if (reg_pref == 0)
00903 return ALL_REGS;
00904
00905 return (enum reg_class) reg_pref[regno].altclass;
00906 }
00907
00908
00909
00910 void
00911 regclass_init (void)
00912 {
00913 int i;
00914
00915 init_cost.mem_cost = 10000;
00916 for (i = 0; i < N_REG_CLASSES; i++)
00917 init_cost.cost[i] = 10000;
00918
00919
00920
00921 reg_pref = NULL;
00922
00923
00924 no_global_reg_vars = 1;
00925 }
00926
00927
00928 static void
00929 dump_regclass (FILE *dump)
00930 {
00931 int i;
00932 for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
00933 {
00934 int class;
00935 if (REG_N_REFS (i))
00936 {
00937 fprintf (dump, " Register %i costs:", i);
00938 for (class = 0; class < (int) N_REG_CLASSES; class++)
00939 if (contains_reg_of_mode [(enum reg_class) class][PSEUDO_REGNO_MODE (i)]
00940 #ifdef FORBIDDEN_INC_DEC_CLASSES
00941 && (!in_inc_dec[i]
00942 || !forbidden_inc_dec_class[(enum reg_class) class])
00943 #endif
00944 #ifdef CANNOT_CHANGE_MODE_CLASS
00945 && ! invalid_mode_change_p (i, (enum reg_class) class,
00946 PSEUDO_REGNO_MODE (i))
00947 #endif
00948 )
00949 fprintf (dump, " %s:%i", reg_class_names[class],
00950 costs[i].cost[(enum reg_class) class]);
00951 fprintf (dump, " MEM:%i\n", costs[i].mem_cost);
00952 }
00953 }
00954 }
00955
00956
00957
00958
00959 static void
00960 record_operand_costs (rtx insn, struct costs *op_costs,
00961 struct reg_pref *reg_pref)
00962 {
00963 const char *constraints[MAX_RECOG_OPERANDS];
00964 enum machine_mode modes[MAX_RECOG_OPERANDS];
00965 int i;
00966
00967 for (i = 0; i < recog_data.n_operands; i++)
00968 {
00969 constraints[i] = recog_data.constraints[i];
00970 modes[i] = recog_data.operand_mode[i];
00971 }
00972
00973
00974
00975
00976
00977
00978
00979 for (i = 0; i < recog_data.n_operands; i++)
00980 {
00981 op_costs[i] = init_cost;
00982
00983 if (GET_CODE (recog_data.operand[i]) == SUBREG)
00984 recog_data.operand[i] = SUBREG_REG (recog_data.operand[i]);
00985
00986 if (MEM_P (recog_data.operand[i]))
00987 record_address_regs (GET_MODE (recog_data.operand[i]),
00988 XEXP (recog_data.operand[i], 0),
00989 0, MEM, SCRATCH, frequency * 2);
00990 else if (constraints[i][0] == 'p'
00991 || EXTRA_ADDRESS_CONSTRAINT (constraints[i][0], constraints[i]))
00992 record_address_regs (VOIDmode, recog_data.operand[i], 0, ADDRESS,
00993 SCRATCH, frequency * 2);
00994 }
00995
00996
00997
00998
00999
01000 for (i = 0; i < (int) recog_data.n_operands - 1; i++)
01001 if (constraints[i][0] == '%')
01002 {
01003 const char *xconstraints[MAX_RECOG_OPERANDS];
01004 int j;
01005
01006
01007
01008
01009 for (j = 0; j < recog_data.n_operands; j++)
01010 xconstraints[j] = constraints[j];
01011
01012 xconstraints[i] = constraints[i+1];
01013 xconstraints[i+1] = constraints[i];
01014 record_reg_classes (recog_data.n_alternatives, recog_data.n_operands,
01015 recog_data.operand, modes,
01016 xconstraints, insn, op_costs, reg_pref);
01017 }
01018
01019 record_reg_classes (recog_data.n_alternatives, recog_data.n_operands,
01020 recog_data.operand, modes,
01021 constraints, insn, op_costs, reg_pref);
01022 }
01023
01024
01025
01026
01027
01028
01029
01030
01031 static rtx
01032 scan_one_insn (rtx insn, int pass)
01033 {
01034 enum rtx_code pat_code;
01035 rtx set, note;
01036 int i, j;
01037 struct costs op_costs[MAX_RECOG_OPERANDS];
01038
01039 if (!INSN_P (insn))
01040 return insn;
01041
01042 pat_code = GET_CODE (PATTERN (insn));
01043 if (pat_code == USE
01044 || pat_code == CLOBBER
01045 || pat_code == ASM_INPUT
01046 || pat_code == ADDR_VEC
01047 || pat_code == ADDR_DIFF_VEC)
01048 return insn;
01049
01050 set = single_set (insn);
01051 extract_insn (insn);
01052
01053
01054
01055
01056
01057 if (set != 0 && REG_P (SET_DEST (set))
01058 && MEM_P (SET_SRC (set))
01059 && (note = find_reg_note (insn, REG_EQUIV,
01060 NULL_RTX)) != 0
01061 && MEM_P (XEXP (note, 0)))
01062 {
01063 costs[REGNO (SET_DEST (set))].mem_cost
01064 -= (MEMORY_MOVE_COST (GET_MODE (SET_DEST (set)),
01065 GENERAL_REGS, 1)
01066 * frequency);
01067 record_address_regs (GET_MODE (SET_SRC (set)), XEXP (SET_SRC (set), 0),
01068 0, MEM, SCRATCH, frequency * 2);
01069 return insn;
01070 }
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084 if (pass == 0 && optimize
01085 && recog_data.n_operands >= 3
01086 && recog_data.constraints[1][0] == '0'
01087 && recog_data.constraints[1][1] == 0
01088 && CONSTANT_P (recog_data.operand[1])
01089 && ! rtx_equal_p (recog_data.operand[0], recog_data.operand[1])
01090 && ! rtx_equal_p (recog_data.operand[0], recog_data.operand[2])
01091 && REG_P (recog_data.operand[0])
01092 && MODES_TIEABLE_P (GET_MODE (recog_data.operand[0]),
01093 recog_data.operand_mode[1]))
01094 {
01095 rtx previnsn = prev_real_insn (insn);
01096 rtx dest
01097 = gen_lowpart (recog_data.operand_mode[1],
01098 recog_data.operand[0]);
01099 rtx newinsn
01100 = emit_insn_before (gen_move_insn (dest, recog_data.operand[1]), insn);
01101
01102
01103
01104
01105
01106
01107 if (previnsn == 0 || JUMP_P (previnsn))
01108 {
01109 basic_block b;
01110 FOR_EACH_BB (b)
01111 if (insn == BB_HEAD (b))
01112 BB_HEAD (b) = newinsn;
01113 }
01114
01115
01116 REG_N_SETS (REGNO (recog_data.operand[0]))++;
01117 REG_N_REFS (REGNO (recog_data.operand[0]))++;
01118 REG_FREQ (REGNO (recog_data.operand[0])) += frequency;
01119
01120 *recog_data.operand_loc[1] = recog_data.operand[0];
01121 REG_N_REFS (REGNO (recog_data.operand[0]))++;
01122 REG_FREQ (REGNO (recog_data.operand[0])) += frequency;
01123 for (i = recog_data.n_dups - 1; i >= 0; i--)
01124 if (recog_data.dup_num[i] == 1)
01125 {
01126 *recog_data.dup_loc[i] = recog_data.operand[0];
01127 REG_N_REFS (REGNO (recog_data.operand[0]))++;
01128 REG_FREQ (REGNO (recog_data.operand[0])) += frequency;
01129 }
01130
01131 return PREV_INSN (newinsn);
01132 }
01133
01134 record_operand_costs (insn, op_costs, reg_pref);
01135
01136
01137
01138
01139 for (i = 0; i < recog_data.n_operands; i++)
01140 if (REG_P (recog_data.operand[i])
01141 && REGNO (recog_data.operand[i]) >= FIRST_PSEUDO_REGISTER)
01142 {
01143 int regno = REGNO (recog_data.operand[i]);
01144 struct costs *p = &costs[regno], *q = &op_costs[i];
01145
01146 p->mem_cost += q->mem_cost * frequency;
01147 for (j = 0; j < N_REG_CLASSES; j++)
01148 p->cost[j] += q->cost[j] * frequency;
01149 }
01150
01151 return insn;
01152 }
01153
01154
01155
01156
01157 static void
01158 init_reg_autoinc (void)
01159 {
01160 #ifdef FORBIDDEN_INC_DEC_CLASSES
01161 int i;
01162
01163 for (i = 0; i < N_REG_CLASSES; i++)
01164 {
01165 rtx r = gen_rtx_raw_REG (VOIDmode, 0);
01166 enum machine_mode m;
01167 int j;
01168
01169 for (j = 0; j < FIRST_PSEUDO_REGISTER; j++)
01170 if (TEST_HARD_REG_BIT (reg_class_contents[i], j))
01171 {
01172 REGNO (r) = j;
01173
01174 for (m = VOIDmode; (int) m < (int) MAX_MACHINE_MODE;
01175 m = (enum machine_mode) ((int) m + 1))
01176 if (HARD_REGNO_MODE_OK (j, m))
01177 {
01178
01179
01180
01181
01182 enum reg_class base_class
01183 = base_reg_class (VOIDmode, POST_INC, SCRATCH);
01184
01185 PUT_MODE (r, m);
01186
01187
01188
01189
01190
01191
01192 if ((secondary_reload_class (1, base_class, m, r)
01193 || secondary_reload_class (1, base_class, m, r))
01194 && ! auto_inc_dec_reg_p (r, m))
01195 forbidden_inc_dec_class[i] = 1;
01196 }
01197 }
01198 }
01199 #endif
01200 }
01201
01202
01203
01204
01205
01206
01207 void
01208 regclass (rtx f, int nregs)
01209 {
01210 rtx insn;
01211 int i;
01212 int pass;
01213
01214 init_recog ();
01215
01216 costs = XNEWVEC (struct costs, nregs);
01217
01218 #ifdef FORBIDDEN_INC_DEC_CLASSES
01219
01220 in_inc_dec = XNEWVEC (char, nregs);
01221
01222 #endif
01223
01224
01225
01226
01227
01228
01229 for (pass = 0; pass <= flag_expensive_optimizations; pass++)
01230 {
01231 basic_block bb;
01232
01233 if (dump_file)
01234 fprintf (dump_file, "\n\nPass %i\n\n",pass);
01235
01236
01237 memset (costs, 0, nregs * sizeof (struct costs));
01238
01239 #ifdef FORBIDDEN_INC_DEC_CLASSES
01240 memset (in_inc_dec, 0, nregs);
01241 #endif
01242
01243
01244
01245
01246 if (!optimize)
01247 {
01248 frequency = REG_FREQ_MAX;
01249 for (insn = f; insn; insn = NEXT_INSN (insn))
01250 insn = scan_one_insn (insn, pass);
01251 }
01252 else
01253 FOR_EACH_BB (bb)
01254 {
01255
01256
01257
01258
01259 frequency = REG_FREQ_FROM_BB (bb);
01260 for (insn = BB_HEAD (bb); ; insn = NEXT_INSN (insn))
01261 {
01262 insn = scan_one_insn (insn, pass);
01263 if (insn == BB_END (bb))
01264 break;
01265 }
01266 }
01267
01268
01269
01270
01271
01272
01273 if (pass == 0)
01274 reg_pref = reg_pref_buffer;
01275
01276 if (dump_file)
01277 {
01278 dump_regclass (dump_file);
01279 fprintf (dump_file,"\n");
01280 }
01281 for (i = FIRST_PSEUDO_REGISTER; i < nregs; i++)
01282 {
01283 int best_cost = (1 << (HOST_BITS_PER_INT - 2)) - 1;
01284 enum reg_class best = ALL_REGS, alt = NO_REGS;
01285
01286
01287 int class;
01288 struct costs *p = &costs[i];
01289
01290
01291
01292 if (optimize && !REG_N_REFS (i) && !REG_N_SETS (i))
01293 continue;
01294
01295 for (class = (int) ALL_REGS - 1; class > 0; class--)
01296 {
01297
01298
01299 if (!contains_reg_of_mode [class][PSEUDO_REGNO_MODE (i)]
01300 #ifdef FORBIDDEN_INC_DEC_CLASSES
01301 || (in_inc_dec[i] && forbidden_inc_dec_class[class])
01302 #endif
01303 #ifdef CANNOT_CHANGE_MODE_CLASS
01304 || invalid_mode_change_p (i, (enum reg_class) class,
01305 PSEUDO_REGNO_MODE (i))
01306 #endif
01307 )
01308 ;
01309 else if (p->cost[class] < best_cost)
01310 {
01311 best_cost = p->cost[class];
01312 best = (enum reg_class) class;
01313 }
01314 else if (p->cost[class] == best_cost)
01315 best = reg_class_subunion[(int) best][class];
01316 }
01317
01318
01319 if (p->mem_cost < best_cost)
01320 best = NO_REGS;
01321
01322
01323
01324
01325
01326
01327
01328
01329 if ((pass == 1 || dump_file) || ! flag_expensive_optimizations)
01330 for (class = 0; class < N_REG_CLASSES; class++)
01331 if (p->cost[class] < p->mem_cost
01332 && (reg_class_size[(int) reg_class_subunion[(int) alt][class]]
01333 > reg_class_size[(int) alt])
01334 #ifdef FORBIDDEN_INC_DEC_CLASSES
01335 && ! (in_inc_dec[i] && forbidden_inc_dec_class[class])
01336 #endif
01337 #ifdef CANNOT_CHANGE_MODE_CLASS
01338 && ! invalid_mode_change_p (i, (enum reg_class) class,
01339 PSEUDO_REGNO_MODE (i))
01340 #endif
01341 )
01342 alt = reg_class_subunion[(int) alt][class];
01343
01344
01345 if (alt == best)
01346 alt = NO_REGS;
01347
01348 if (dump_file
01349 && (reg_pref[i].prefclass != (int) best
01350 || reg_pref[i].altclass != (int) alt))
01351 {
01352 fprintf (dump_file, " Register %i", i);
01353 if (alt == ALL_REGS || best == ALL_REGS)
01354 fprintf (dump_file, " pref %s\n", reg_class_names[(int) best]);
01355 else if (alt == NO_REGS)
01356 fprintf (dump_file, " pref %s or none\n", reg_class_names[(int) best]);
01357 else
01358 fprintf (dump_file, " pref %s, else %s\n",
01359 reg_class_names[(int) best],
01360 reg_class_names[(int) alt]);
01361 }
01362
01363
01364 reg_pref[i].prefclass = (int) best;
01365 reg_pref[i].altclass = (int) alt;
01366 }
01367 }
01368
01369 #ifdef FORBIDDEN_INC_DEC_CLASSES
01370 free (in_inc_dec);
01371 #endif
01372 free (costs);
01373 }
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399 static void
01400 record_reg_classes (int n_alts, int n_ops, rtx *ops,
01401 enum machine_mode *modes, const char **constraints,
01402 rtx insn, struct costs *op_costs,
01403 struct reg_pref *reg_pref)
01404 {
01405 int alt;
01406 int i, j;
01407 rtx set;
01408
01409
01410
01411
01412 for (alt = 0; alt < n_alts; alt++)
01413 {
01414 struct costs this_op_costs[MAX_RECOG_OPERANDS];
01415 int alt_fail = 0;
01416 int alt_cost = 0;
01417 enum reg_class classes[MAX_RECOG_OPERANDS];
01418 int allows_mem[MAX_RECOG_OPERANDS];
01419 int class;
01420
01421 for (i = 0; i < n_ops; i++)
01422 {
01423 const char *p = constraints[i];
01424 rtx op = ops[i];
01425 enum machine_mode mode = modes[i];
01426 int allows_addr = 0;
01427 int win = 0;
01428 unsigned char c;
01429
01430
01431 classes[i] = NO_REGS;
01432 allows_mem[i] = 0;
01433
01434
01435
01436
01437 if (*p == 0)
01438 {
01439 if (REG_P (op) && REGNO (op) >= FIRST_PSEUDO_REGISTER)
01440 memset (&this_op_costs[i], 0, sizeof this_op_costs[i]);
01441
01442 continue;
01443 }
01444
01445
01446
01447
01448
01449
01450 while (*p == '%' || *p == '=' || *p == '+' || *p == '&')
01451 p++;
01452
01453 if (p[0] >= '0' && p[0] <= '0' + i && (p[1] == ',' || p[1] == 0))
01454 {
01455
01456
01457
01458 j = p[0] - '0';
01459 classes[i] = classes[j];
01460 allows_mem[i] = allows_mem[j];
01461
01462 if (!REG_P (op) || REGNO (op) < FIRST_PSEUDO_REGISTER)
01463 {
01464
01465
01466 if (rtx_equal_p (ops[j], op))
01467 win = 1;
01468
01469
01470
01471
01472
01473 else if (classes[j] != NO_REGS)
01474 {
01475 alt_cost += copy_cost (op, mode, classes[j], 1, NULL);
01476 win = 1;
01477 }
01478 }
01479 else if (!REG_P (ops[j])
01480 || REGNO (ops[j]) < FIRST_PSEUDO_REGISTER)
01481 {
01482
01483
01484
01485
01486
01487 if (classes[j] == NO_REGS)
01488 alt_fail = 1;
01489
01490
01491
01492
01493
01494 else
01495 alt_cost += copy_cost (ops[j], mode, classes[j], 1, NULL);
01496 }
01497 else
01498 {
01499
01500
01501
01502
01503
01504 struct costs *pp = &this_op_costs[i];
01505
01506 for (class = 0; class < N_REG_CLASSES; class++)
01507 pp->cost[class]
01508 = ((recog_data.operand_type[i] != OP_OUT
01509 ? may_move_in_cost[mode][class][(int) classes[i]]
01510 : 0)
01511 + (recog_data.operand_type[i] != OP_IN
01512 ? may_move_out_cost[mode][(int) classes[i]][class]
01513 : 0));
01514
01515
01516
01517
01518
01519 pp->mem_cost
01520 = ((recog_data.operand_type[i] != OP_IN
01521 ? MEMORY_MOVE_COST (mode, classes[i], 0)
01522 : 0)
01523 + (recog_data.operand_type[i] != OP_OUT
01524 ? MEMORY_MOVE_COST (mode, classes[i], 1)
01525 : 0) - allows_mem[i]);
01526
01527
01528
01529
01530
01531
01532 if (reg_pref && reg_pref[REGNO (op)].prefclass != NO_REGS)
01533 alt_cost
01534 += (may_move_in_cost[mode]
01535 [(unsigned char) reg_pref[REGNO (op)].prefclass]
01536 [(int) classes[i]]);
01537
01538 if (REGNO (ops[i]) != REGNO (ops[j])
01539 && ! find_reg_note (insn, REG_DEAD, op))
01540 alt_cost += 2;
01541
01542
01543
01544
01545 while (*p && *p++ != ',')
01546 ;
01547
01548 constraints[i] = p;
01549 continue;
01550 }
01551 }
01552
01553
01554
01555
01556
01557 while ((c = *p))
01558 {
01559 switch (c)
01560 {
01561 case ',':
01562 break;
01563 case '*':
01564
01565 c = *++p;
01566 break;
01567
01568 case '?':
01569 alt_cost += 2;
01570 case '!': case '#': case '&':
01571 case '0': case '1': case '2': case '3': case '4':
01572 case '5': case '6': case '7': case '8': case '9':
01573 break;
01574
01575 case 'p':
01576 allows_addr = 1;
01577 win = address_operand (op, GET_MODE (op));
01578
01579
01580
01581 classes[i]
01582 = reg_class_subunion[(int) classes[i]]
01583 [(int) base_reg_class (VOIDmode, ADDRESS, SCRATCH)];
01584 break;
01585
01586 case 'm': case 'o': case 'V':
01587
01588
01589 allows_mem[i] = 1;
01590 if (MEM_P (op))
01591 win = 1;
01592 break;
01593
01594 case '<':
01595 if (MEM_P (op)
01596 && (GET_CODE (XEXP (op, 0)) == PRE_DEC
01597 || GET_CODE (XEXP (op, 0)) == POST_DEC))
01598 win = 1;
01599 break;
01600
01601 case '>':
01602 if (MEM_P (op)
01603 && (GET_CODE (XEXP (op, 0)) == PRE_INC
01604 || GET_CODE (XEXP (op, 0)) == POST_INC))
01605 win = 1;
01606 break;
01607
01608 case 'E':
01609 case 'F':
01610 if (GET_CODE (op) == CONST_DOUBLE
01611 || (GET_CODE (op) == CONST_VECTOR
01612 && (GET_MODE_CLASS (GET_MODE (op))
01613 == MODE_VECTOR_FLOAT)))
01614 win = 1;
01615 break;
01616
01617 case 'G':
01618 case 'H':
01619 if (GET_CODE (op) == CONST_DOUBLE
01620 && CONST_DOUBLE_OK_FOR_CONSTRAINT_P (op, c, p))
01621 win = 1;
01622 break;
01623
01624 case 's':
01625 if (GET_CODE (op) == CONST_INT
01626 || (GET_CODE (op) == CONST_DOUBLE
01627 && GET_MODE (op) == VOIDmode))
01628 break;
01629 case 'i':
01630 if (CONSTANT_P (op)
01631 && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op)))
01632 win = 1;
01633 break;
01634
01635 case 'n':
01636 if (GET_CODE (op) == CONST_INT
01637 || (GET_CODE (op) == CONST_DOUBLE
01638 && GET_MODE (op) == VOIDmode))
01639 win = 1;
01640 break;
01641
01642 case 'I':
01643 case 'J':
01644 case 'K':
01645 case 'L':
01646 case 'M':
01647 case 'N':
01648 case 'O':
01649 case 'P':
01650 if (GET_CODE (op) == CONST_INT
01651 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), c, p))
01652 win = 1;
01653 break;
01654
01655 case 'X':
01656 win = 1;
01657 break;
01658
01659 case 'g':
01660 if (MEM_P (op)
01661 || (CONSTANT_P (op)
01662 && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op))))
01663 win = 1;
01664 allows_mem[i] = 1;
01665 case 'r':
01666 classes[i]
01667 = reg_class_subunion[(int) classes[i]][(int) GENERAL_REGS];
01668 break;
01669
01670 default:
01671 if (REG_CLASS_FROM_CONSTRAINT (c, p) != NO_REGS)
01672 classes[i]
01673 = reg_class_subunion[(int) classes[i]]
01674 [(int) REG_CLASS_FROM_CONSTRAINT (c, p)];
01675 #ifdef EXTRA_CONSTRAINT_STR
01676 else if (EXTRA_CONSTRAINT_STR (op, c, p))
01677 win = 1;
01678
01679 if (EXTRA_MEMORY_CONSTRAINT (c, p))
01680 {
01681
01682 allows_mem[i] = 1;
01683 if (MEM_P (op))
01684 win = 1;
01685 }
01686 if (EXTRA_ADDRESS_CONSTRAINT (c, p))
01687 {
01688
01689 allows_addr = 1;
01690 if (address_operand (op, GET_MODE (op)))
01691 win = 1;
01692
01693
01694
01695 classes[i]
01696 = reg_class_subunion[(int) classes[i]]
01697 [(int) base_reg_class (VOIDmode, ADDRESS, SCRATCH)];
01698 }
01699 #endif
01700 break;
01701 }
01702 p += CONSTRAINT_LEN (c, p);
01703 if (c == ',')
01704 break;
01705 }
01706
01707 constraints[i] = p;
01708
01709
01710
01711
01712
01713
01714
01715
01716 if (REG_P (op) && REGNO (op) >= FIRST_PSEUDO_REGISTER)
01717 {
01718 if (classes[i] == NO_REGS)
01719 {
01720
01721
01722
01723
01724
01725
01726 alt_fail = 1;
01727 }
01728 else
01729 {
01730 struct costs *pp = &this_op_costs[i];
01731
01732 for (class = 0; class < N_REG_CLASSES; class++)
01733 pp->cost[class]
01734 = ((recog_data.operand_type[i] != OP_OUT
01735 ? may_move_in_cost[mode][class][(int) classes[i]]
01736 : 0)
01737 + (recog_data.operand_type[i] != OP_IN
01738 ? may_move_out_cost[mode][(int) classes[i]][class]
01739 : 0));
01740
01741
01742
01743
01744
01745 pp->mem_cost
01746 = ((recog_data.operand_type[i] != OP_IN
01747 ? MEMORY_MOVE_COST (mode, classes[i], 0)
01748 : 0)
01749 + (recog_data.operand_type[i] != OP_OUT
01750 ? MEMORY_MOVE_COST (mode, classes[i], 1)
01751 : 0) - allows_mem[i]);
01752
01753
01754
01755
01756
01757
01758 if (reg_pref && reg_pref[REGNO (op)].prefclass != NO_REGS)
01759 alt_cost
01760 += (may_move_in_cost[mode]
01761 [(unsigned char) reg_pref[REGNO (op)].prefclass]
01762 [(int) classes[i]]);
01763 }
01764 }
01765
01766
01767
01768
01769
01770 else if (win
01771 || (REG_P (op)
01772 && reg_fits_class_p (op, classes[i], 0, GET_MODE (op))))
01773 ;
01774
01775
01776
01777
01778 else if (classes[i] != NO_REGS)
01779 {
01780 if (recog_data.operand_type[i] != OP_OUT)
01781 alt_cost += copy_cost (op, mode, classes[i], 1, NULL);
01782
01783 if (recog_data.operand_type[i] != OP_IN)
01784 alt_cost += copy_cost (op, mode, classes[i], 0, NULL);
01785 }
01786
01787
01788
01789
01790 else if (CONSTANT_P (op) && (allows_addr || allows_mem[i]))
01791 alt_cost += MEMORY_MOVE_COST (mode, classes[i], 1);
01792 else
01793 alt_fail = 1;
01794 }
01795
01796 if (alt_fail)
01797 continue;
01798
01799
01800
01801
01802 for (i = 0; i < n_ops; i++)
01803 if (REG_P (ops[i])
01804 && REGNO (ops[i]) >= FIRST_PSEUDO_REGISTER)
01805 {
01806 struct costs *pp = &op_costs[i], *qq = &this_op_costs[i];
01807 int scale = 1 + (recog_data.operand_type[i] == OP_INOUT);
01808
01809 pp->mem_cost = MIN (pp->mem_cost,
01810 (qq->mem_cost + alt_cost) * scale);
01811
01812 for (class = 0; class < N_REG_CLASSES; class++)
01813 pp->cost[class] = MIN (pp->cost[class],
01814 (qq->cost[class] + alt_cost) * scale);
01815 }
01816 }
01817
01818
01819
01820
01821
01822
01823
01824
01825
01826
01827
01828
01829
01830
01831
01832 if ((set = single_set (insn)) != 0
01833 && ops[0] == SET_DEST (set) && ops[1] == SET_SRC (set)
01834 && REG_P (ops[0]) && REG_P (ops[1])
01835 && find_regno_note (insn, REG_DEAD, REGNO (ops[1])))
01836 for (i = 0; i <= 1; i++)
01837 if (REGNO (ops[i]) >= FIRST_PSEUDO_REGISTER)
01838 {
01839 unsigned int regno = REGNO (ops[!i]);
01840 enum machine_mode mode = GET_MODE (ops[!i]);
01841 int class;
01842 unsigned int nr;
01843
01844 if (regno >= FIRST_PSEUDO_REGISTER && reg_pref != 0
01845 && reg_pref[regno].prefclass != NO_REGS)
01846 {
01847 enum reg_class pref = reg_pref[regno].prefclass;
01848
01849 if ((reg_class_size[(unsigned char) pref]
01850 == (unsigned) CLASS_MAX_NREGS (pref, mode))
01851 && REGISTER_MOVE_COST (mode, pref, pref) < 10 * 2)
01852 op_costs[i].cost[(unsigned char) pref] = -1;
01853 }
01854 else if (regno < FIRST_PSEUDO_REGISTER)
01855 for (class = 0; class < N_REG_CLASSES; class++)
01856 if (TEST_HARD_REG_BIT (reg_class_contents[class], regno)
01857 && reg_class_size[class] == (unsigned) CLASS_MAX_NREGS (class, mode))
01858 {
01859 if (reg_class_size[class] == 1)
01860 op_costs[i].cost[class] = -1;
01861 else
01862 {
01863 for (nr = 0; nr < (unsigned) hard_regno_nregs[regno][mode]; nr++)
01864 {
01865 if (! TEST_HARD_REG_BIT (reg_class_contents[class],
01866 regno + nr))
01867 break;
01868 }
01869
01870 if (nr == (unsigned) hard_regno_nregs[regno][mode])
01871 op_costs[i].cost[class] = -1;
01872 }
01873 }
01874 }
01875 }
01876
01877
01878
01879
01880
01881
01882 static int
01883 copy_cost (rtx x, enum machine_mode mode, enum reg_class class, int to_p,
01884 secondary_reload_info *prev_sri)
01885 {
01886 enum reg_class secondary_class = NO_REGS;
01887 secondary_reload_info sri;
01888
01889
01890
01891
01892 if (GET_CODE (x) == SCRATCH)
01893 return 0;
01894
01895
01896 class = PREFERRED_RELOAD_CLASS (x, class);
01897
01898
01899
01900
01901
01902 sri.prev_sri = prev_sri;
01903 sri.extra_cost = 0;
01904 secondary_class = targetm.secondary_reload (to_p, x, class, mode, &sri);
01905
01906 if (secondary_class != NO_REGS)
01907 return (move_cost[mode][(int) secondary_class][(int) class]
01908 + sri.extra_cost
01909 + copy_cost (x, mode, secondary_class, to_p, &sri));
01910
01911
01912
01913
01914
01915 if (MEM_P (x) || class == NO_REGS)
01916 return sri.extra_cost + MEMORY_MOVE_COST (mode, class, to_p);
01917
01918 else if (REG_P (x))
01919 return (sri.extra_cost
01920 + move_cost[mode][(int) REGNO_REG_CLASS (REGNO (x))][(int) class]);
01921
01922 else
01923
01924 return sri.extra_cost + COSTS_N_INSNS (1);
01925 }
01926
01927
01928
01929
01930
01931
01932
01933
01934
01935
01936
01937
01938
01939
01940 static void
01941 record_address_regs (enum machine_mode mode, rtx x, int context,
01942 enum rtx_code outer_code, enum rtx_code index_code,
01943 int scale)
01944 {
01945 enum rtx_code code = GET_CODE (x);
01946 enum reg_class class;
01947
01948 if (context == 1)
01949 class = INDEX_REG_CLASS;
01950 else
01951 class = base_reg_class (mode, outer_code, index_code);
01952
01953 switch (code)
01954 {
01955 case CONST_INT:
01956 case CONST:
01957 case CC0:
01958 case PC:
01959 case SYMBOL_REF:
01960 case LABEL_REF:
01961 return;
01962
01963 case PLUS:
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973
01974
01975
01976 {
01977 rtx arg0 = XEXP (x, 0);
01978 rtx arg1 = XEXP (x, 1);
01979 enum rtx_code code0 = GET_CODE (arg0);
01980 enum rtx_code code1 = GET_CODE (arg1);
01981
01982
01983 if (code0 == SUBREG)
01984 arg0 = SUBREG_REG (arg0), code0 = GET_CODE (arg0);
01985 if (code1 == SUBREG)
01986 arg1 = SUBREG_REG (arg1), code1 = GET_CODE (arg1);
01987
01988
01989
01990
01991 if (MAX_REGS_PER_ADDRESS == 1)
01992 record_address_regs (mode, arg0, 0, PLUS, code1, scale);
01993
01994
01995
01996
01997
01998
01999 else if (INDEX_REG_CLASS == base_reg_class (VOIDmode, PLUS, SCRATCH))
02000 {
02001 record_address_regs (mode, arg0, context, PLUS, code1, scale);
02002 if (! CONSTANT_P (arg1))
02003 record_address_regs (mode, arg1, context, PLUS, code0, scale);
02004 }
02005
02006
02007
02008
02009 else if (code1 == CONST_INT || code1 == CONST_DOUBLE)
02010 record_address_regs (mode, arg0, context, PLUS, code1, scale);
02011
02012
02013
02014
02015 else if (code1 == SYMBOL_REF || code1 == CONST || code1 == LABEL_REF)
02016 record_address_regs (mode, arg0, 1, PLUS, code1, scale);
02017
02018
02019
02020
02021
02022 else if (code0 == REG && code1 == REG
02023 && REGNO (arg0) < FIRST_PSEUDO_REGISTER
02024 && (ok_for_base_p_nonstrict (arg0, mode, PLUS, REG)
02025 || ok_for_index_p_nonstrict (arg0)))
02026 record_address_regs (mode, arg1,
02027 ok_for_base_p_nonstrict (arg0, mode, PLUS, REG)
02028 ? 1 : 0,
02029 PLUS, REG, scale);
02030 else if (code0 == REG && code1 == REG
02031 && REGNO (arg1) < FIRST_PSEUDO_REGISTER
02032 && (ok_for_base_p_nonstrict (arg1, mode, PLUS, REG)
02033 || ok_for_index_p_nonstrict (arg1)))
02034 record_address_regs (mode, arg0,
02035 ok_for_base_p_nonstrict (arg1, mode, PLUS, REG)
02036 ? 1 : 0,
02037 PLUS, REG, scale);
02038
02039
02040
02041
02042
02043 else if ((code0 == REG && REG_POINTER (arg0))
02044 || code1 == MULT)
02045 {
02046 record_address_regs (mode, arg0, 0, PLUS, code1, scale);
02047 record_address_regs (mode, arg1, 1, PLUS, code0, scale);
02048 }
02049 else if ((code1 == REG && REG_POINTER (arg1))
02050 || code0 == MULT)
02051 {
02052 record_address_regs (mode, arg0, 1, PLUS, code1, scale);
02053 record_address_regs (mode, arg1, 0, PLUS, code0, scale);
02054 }
02055
02056
02057
02058
02059 else
02060 {
02061 record_address_regs (mode, arg0, 0, PLUS, code1, scale / 2);
02062 record_address_regs (mode, arg0, 1, PLUS, code1, scale / 2);
02063 record_address_regs (mode, arg1, 0, PLUS, code0, scale / 2);
02064 record_address_regs (mode, arg1, 1, PLUS, code0, scale / 2);
02065 }
02066 }
02067 break;
02068
02069
02070
02071
02072 case POST_MODIFY:
02073 case PRE_MODIFY:
02074 record_address_regs (mode, XEXP (x, 0), 0, code,
02075 GET_CODE (XEXP (XEXP (x, 1), 1)), 2 * scale);
02076 if (REG_P (XEXP (XEXP (x, 1), 1)))
02077 record_address_regs (mode, XEXP (XEXP (x, 1), 1), 1, code, REG,
02078 2 * scale);
02079 break;
02080
02081 case POST_INC:
02082 case PRE_INC:
02083 case POST_DEC:
02084 case PRE_DEC:
02085
02086
02087
02088
02089
02090 #ifdef FORBIDDEN_INC_DEC_CLASSES
02091 if (REG_P (XEXP (x, 0))
02092 && REGNO (XEXP (x, 0)) >= FIRST_PSEUDO_REGISTER)
02093 in_inc_dec[REGNO (XEXP (x, 0))] = 1;
02094 #endif
02095
02096 record_address_regs (mode, XEXP (x, 0), 0, code, SCRATCH, 2 * scale);
02097 break;
02098
02099 case REG:
02100 {
02101 struct costs *pp = &costs[REGNO (x)];
02102 int i;
02103
02104 pp->mem_cost += (MEMORY_MOVE_COST (Pmode, class, 1) * scale) / 2;
02105
02106 for (i = 0; i < N_REG_CLASSES; i++)
02107 pp->cost[i] += (may_move_in_cost[Pmode][i][(int) class] * scale) / 2;
02108 }
02109 break;
02110
02111 default:
02112 {
02113 const char *fmt = GET_RTX_FORMAT (code);
02114 int i;
02115 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
02116 if (fmt[i] == 'e')
02117 record_address_regs (mode, XEXP (x, i), context, code, SCRATCH,
02118 scale);
02119 }
02120 }
02121 }
02122
02123 #ifdef FORBIDDEN_INC_DEC_CLASSES
02124
02125
02126
02127
02128 static int
02129 auto_inc_dec_reg_p (rtx reg, enum machine_mode mode)
02130 {
02131 if (HAVE_POST_INCREMENT
02132 && memory_address_p (mode, gen_rtx_POST_INC (Pmode, reg)))
02133 return 1;
02134
02135 if (HAVE_POST_DECREMENT
02136 && memory_address_p (mode, gen_rtx_POST_DEC (Pmode, reg)))
02137 return 1;
02138
02139 if (HAVE_PRE_INCREMENT
02140 && memory_address_p (mode, gen_rtx_PRE_INC (Pmode, reg)))
02141 return 1;
02142
02143 if (HAVE_PRE_DECREMENT
02144 && memory_address_p (mode, gen_rtx_PRE_DEC (Pmode, reg)))
02145 return 1;
02146
02147 return 0;
02148 }
02149 #endif
02150
02151 static short *renumber;
02152 static size_t regno_allocated;
02153 static unsigned int reg_n_max;
02154
02155
02156
02157
02158
02159
02160
02161
02162 void
02163 allocate_reg_info (size_t num_regs, int new_p, int renumber_p)
02164 {
02165 size_t size_info;
02166 size_t size_renumber;
02167 size_t min = (new_p) ? 0 : reg_n_max;
02168 struct reg_info_data *reg_data;
02169
02170 if (num_regs > regno_allocated)
02171 {
02172 size_t old_allocated = regno_allocated;
02173
02174 regno_allocated = num_regs + (num_regs / 20);
02175 size_renumber = regno_allocated * sizeof (short);
02176
02177 if (!reg_n_info)
02178 {
02179 reg_n_info = VEC_alloc (reg_info_p, heap, regno_allocated);
02180 VEC_safe_grow (reg_info_p, heap, reg_n_info, regno_allocated);
02181 memset (VEC_address (reg_info_p, reg_n_info), 0,
02182 sizeof (reg_info_p) * regno_allocated);
02183 renumber = xmalloc (size_renumber);
02184 reg_pref_buffer = XNEWVEC (struct reg_pref, regno_allocated);
02185 }
02186 else
02187 {
02188 size_t old_length = VEC_length (reg_info_p, reg_n_info);
02189 if (old_length < regno_allocated)
02190 {
02191 reg_info_p *addr;
02192 VEC_safe_grow (reg_info_p, heap, reg_n_info, regno_allocated);
02193 addr = VEC_address (reg_info_p, reg_n_info);
02194 memset (&addr[old_length], 0,
02195 sizeof (reg_info_p) * (regno_allocated - old_length));
02196 }
02197 else if (regno_allocated < old_length)
02198 {
02199 VEC_truncate (reg_info_p, reg_n_info, regno_allocated);
02200 }
02201
02202 if (new_p)
02203 {
02204 free ((char *) renumber);
02205 free ((char *) reg_pref);
02206 renumber = xmalloc (size_renumber);
02207 reg_pref_buffer = XNEWVEC (struct reg_pref, regno_allocated);
02208 }
02209
02210 else
02211 {
02212 renumber = xrealloc (renumber, size_renumber);
02213 reg_pref_buffer = (struct reg_pref *) xrealloc (reg_pref_buffer,
02214 regno_allocated
02215 * sizeof (struct reg_pref));
02216 }
02217 }
02218
02219 size_info = (regno_allocated - old_allocated) * sizeof (reg_info)
02220 + sizeof (struct reg_info_data) - sizeof (reg_info);
02221 reg_data = xcalloc (size_info, 1);
02222 reg_data->min_index = old_allocated;
02223 reg_data->max_index = regno_allocated - 1;
02224 reg_data->next = reg_info_head;
02225 reg_info_head = reg_data;
02226 }
02227
02228 reg_n_max = num_regs;
02229 if (min < num_regs)
02230 {
02231
02232
02233 for (reg_data = reg_info_head;
02234 reg_data && reg_data->max_index >= min;
02235 reg_data = reg_data->next)
02236 {
02237 size_t min_index = reg_data->min_index;
02238 size_t max_index = reg_data->max_index;
02239 size_t max = MIN (max_index, num_regs);
02240 size_t local_min = min - min_index;
02241 size_t i;
02242
02243 if (reg_data->min_index > num_regs)
02244 continue;
02245
02246 if (min < min_index)
02247 local_min = 0;
02248 if (!reg_data->used_p)
02249 reg_data->used_p = 1;
02250 else
02251 memset (®_data->data[local_min], 0,
02252 sizeof (reg_info) * (max - min_index - local_min + 1));
02253
02254 for (i = min_index+local_min; i <= max; i++)
02255 {
02256 VEC_replace (reg_info_p, reg_n_info, i,
02257 ®_data->data[i-min_index]);
02258 REG_BASIC_BLOCK (i) = REG_BLOCK_UNKNOWN;
02259 renumber[i] = -1;
02260 reg_pref_buffer[i].prefclass = (char) NO_REGS;
02261 reg_pref_buffer[i].altclass = (char) NO_REGS;
02262 }
02263 }
02264 }
02265
02266
02267
02268 if (reg_pref)
02269 reg_pref = reg_pref_buffer;
02270
02271 if (renumber_p)
02272 reg_renumber = renumber;
02273 }
02274
02275
02276 void
02277 free_reg_info (void)
02278 {
02279 if (reg_n_info)
02280 {
02281 struct reg_info_data *reg_data;
02282 struct reg_info_data *reg_next;
02283
02284 VEC_free (reg_info_p, heap, reg_n_info);
02285 for (reg_data = reg_info_head; reg_data; reg_data = reg_next)
02286 {
02287 reg_next = reg_data->next;
02288 free ((char *) reg_data);
02289 }
02290
02291 free (reg_pref_buffer);
02292 reg_pref_buffer = (struct reg_pref *) 0;
02293 reg_info_head = (struct reg_info_data *) 0;
02294 renumber = (short *) 0;
02295 }
02296 regno_allocated = 0;
02297 reg_n_max = 0;
02298 }
02299
02300
02301
02302
02303
02304
02305
02306
02307
02308
02309
02310
02311
02312
02313
02314
02315 int max_parallel;
02316
02317
02318
02319
02320 static int max_set_parallel;
02321
02322 void
02323 reg_scan (rtx f, unsigned int nregs)
02324 {
02325 rtx insn;
02326
02327 timevar_push (TV_REG_SCAN);
02328
02329 allocate_reg_info (nregs, TRUE, FALSE);
02330 max_parallel = 3;
02331 max_set_parallel = 0;
02332
02333 for (insn = f; insn; insn = NEXT_INSN (insn))
02334 if (INSN_P (insn))
02335 {
02336 rtx pat = PATTERN (insn);
02337 if (GET_CODE (pat) == PARALLEL
02338 && XVECLEN (pat, 0) > max_parallel)
02339 max_parallel = XVECLEN (pat, 0);
02340 reg_scan_mark_refs (pat, insn, 0);
02341
02342 if (REG_NOTES (insn))
02343 reg_scan_mark_refs (REG_NOTES (insn), insn, 1);
02344 }
02345
02346 max_parallel += max_set_parallel;
02347
02348 timevar_pop (TV_REG_SCAN);
02349 }
02350
02351
02352
02353
02354 static void
02355 reg_scan_mark_refs (rtx x, rtx insn, int note_flag)
02356 {
02357 enum rtx_code code;
02358 rtx dest;
02359 rtx note;
02360
02361 if (!x)
02362 return;
02363 code = GET_CODE (x);
02364 switch (code)
02365 {
02366 case CONST:
02367 case CONST_INT:
02368 case CONST_DOUBLE:
02369 case CONST_VECTOR:
02370 case CC0:
02371 case PC:
02372 case SYMBOL_REF:
02373 case LABEL_REF:
02374 case ADDR_VEC:
02375 case ADDR_DIFF_VEC:
02376 return;
02377
02378 case REG:
02379 {
02380 unsigned int regno = REGNO (x);
02381
02382 if (!note_flag)
02383 REGNO_LAST_UID (regno) = INSN_UID (insn);
02384 if (REGNO_FIRST_UID (regno) == 0)
02385 REGNO_FIRST_UID (regno) = INSN_UID (insn);
02386 }
02387 break;
02388
02389 case EXPR_LIST:
02390 if (XEXP (x, 0))
02391 reg_scan_mark_refs (XEXP (x, 0), insn, note_flag);
02392 if (XEXP (x, 1))
02393 reg_scan_mark_refs (XEXP (x, 1), insn, note_flag);
02394 break;
02395
02396 case INSN_LIST:
02397 if (XEXP (x, 1))
02398 reg_scan_mark_refs (XEXP (x, 1), insn, note_flag);
02399 break;
02400
02401 case CLOBBER:
02402 {
02403 rtx reg = XEXP (x, 0);
02404 if (REG_P (reg))
02405 {
02406 REG_N_SETS (REGNO (reg))++;
02407 REG_N_REFS (REGNO (reg))++;
02408 }
02409 else if (MEM_P (reg))
02410 reg_scan_mark_refs (XEXP (reg, 0), insn, note_flag);
02411 }
02412 break;
02413
02414 case SET:
02415
02416 for (dest = SET_DEST (x);
02417 GET_CODE (dest) == SUBREG || GET_CODE (dest) == STRICT_LOW_PART
02418 || GET_CODE (dest) == ZERO_EXTEND;
02419 dest = XEXP (dest, 0))
02420 ;
02421
02422
02423
02424 if (GET_CODE (dest) == PARALLEL)
02425 max_set_parallel = MAX (max_set_parallel, XVECLEN (dest, 0) - 1);
02426
02427 if (REG_P (dest))
02428 {
02429 REG_N_SETS (REGNO (dest))++;
02430 REG_N_REFS (REGNO (dest))++;
02431 }
02432
02433
02434
02435
02436
02437
02438
02439
02440
02441
02442
02443
02444
02445 if (REG_P (SET_DEST (x))
02446 && REGNO (SET_DEST (x)) >= FIRST_PSEUDO_REGISTER
02447
02448
02449
02450
02451
02452 && REG_N_SETS (REGNO (SET_DEST (x))) == 1
02453 && ! REG_USERVAR_P (SET_DEST (x))
02454 && ! REG_POINTER (SET_DEST (x))
02455 && ((REG_P (SET_SRC (x))
02456 && REG_POINTER (SET_SRC (x)))
02457 || ((GET_CODE (SET_SRC (x)) == PLUS
02458 || GET_CODE (SET_SRC (x)) == LO_SUM)
02459 && GET_CODE (XEXP (SET_SRC (x), 1)) == CONST_INT
02460 && REG_P (XEXP (SET_SRC (x), 0))
02461 && REG_POINTER (XEXP (SET_SRC (x), 0)))
02462 || GET_CODE (SET_SRC (x)) == CONST
02463 || GET_CODE (SET_SRC (x)) == SYMBOL_REF
02464 || GET_CODE (SET_SRC (x)) == LABEL_REF
02465 || (GET_CODE (SET_SRC (x)) == HIGH
02466 && (GET_CODE (XEXP (SET_SRC (x), 0)) == CONST
02467 || GET_CODE (XEXP (SET_SRC (x), 0)) == SYMBOL_REF
02468 || GET_CODE (XEXP (SET_SRC (x), 0)) == LABEL_REF))
02469 || ((GET_CODE (SET_SRC (x)) == PLUS
02470 || GET_CODE (SET_SRC (x)) == LO_SUM)
02471 && (GET_CODE (XEXP (SET_SRC (x), 1)) == CONST
02472 || GET_CODE (XEXP (SET_SRC (x), 1)) == SYMBOL_REF
02473 || GET_CODE (XEXP (SET_SRC (x), 1)) == LABEL_REF))
02474 || ((note = find_reg_note (insn, REG_EQUAL, 0)) != 0
02475 && (GET_CODE (XEXP (note, 0)) == CONST
02476 || GET_CODE (XEXP (note, 0)) == SYMBOL_REF
02477 || GET_CODE (XEXP (note, 0)) == LABEL_REF))))
02478 REG_POINTER (SET_DEST (x)) = 1;
02479
02480
02481
02482 if (REG_P (dest))
02483 {
02484 rtx src = SET_SRC (x);
02485
02486 while (GET_CODE (src) == SIGN_EXTEND
02487 || GET_CODE (src) == ZERO_EXTEND
02488 || GET_CODE (src) == TRUNCATE
02489 || (GET_CODE (src) == SUBREG && subreg_lowpart_p (src)))
02490 src = XEXP (src, 0);
02491
02492 if (!REG_ATTRS (dest) && REG_P (src))
02493 REG_ATTRS (dest) = REG_ATTRS (src);
02494 if (!REG_ATTRS (dest) && MEM_P (src))
02495 set_reg_attrs_from_mem (dest, src);
02496 }
02497
02498
02499
02500 default:
02501 {
02502 const char *fmt = GET_RTX_FORMAT (code);
02503 int i;
02504 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
02505 {
02506 if (fmt[i] == 'e')
02507 reg_scan_mark_refs (XEXP (x, i), insn, note_flag);
02508 else if (fmt[i] == 'E' && XVEC (x, i) != 0)
02509 {
02510 int j;
02511 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
02512 reg_scan_mark_refs (XVECEXP (x, i, j), insn, note_flag);
02513 }
02514 }
02515 }
02516 }
02517 }
02518
02519
02520
02521
02522 int
02523 reg_class_subset_p (enum reg_class c1, enum reg_class c2)
02524 {
02525 if (c1 == c2) return 1;
02526
02527 if (c2 == ALL_REGS)
02528 win:
02529 return 1;
02530 GO_IF_HARD_REG_SUBSET (reg_class_contents[(int) c1],
02531 reg_class_contents[(int) c2],
02532 win);
02533 return 0;
02534 }
02535
02536
02537
02538 int
02539 reg_classes_intersect_p (enum reg_class c1, enum reg_class c2)
02540 {
02541 HARD_REG_SET c;
02542
02543 if (c1 == c2) return 1;
02544
02545 if (c1 == ALL_REGS || c2 == ALL_REGS)
02546 return 1;
02547
02548 COPY_HARD_REG_SET (c, reg_class_contents[(int) c1]);
02549 AND_HARD_REG_SET (c, reg_class_contents[(int) c2]);
02550
02551 GO_IF_HARD_REG_SUBSET (c, reg_class_contents[(int) NO_REGS], lose);
02552 return 1;
02553
02554 lose:
02555 return 0;
02556 }
02557
02558 #ifdef CANNOT_CHANGE_MODE_CLASS
02559
02560 struct subregs_of_mode_node
02561 {
02562 unsigned int block;
02563 unsigned char modes[MAX_MACHINE_MODE];
02564 };
02565
02566 static htab_t subregs_of_mode;
02567
02568 static hashval_t
02569 som_hash (const void *x)
02570 {
02571 const struct subregs_of_mode_node *a = x;
02572 return a->block;
02573 }
02574
02575 static int
02576 som_eq (const void *x, const void *y)
02577 {
02578 const struct subregs_of_mode_node *a = x;
02579 const struct subregs_of_mode_node *b = y;
02580 return a->block == b->block;
02581 }
02582
02583 void
02584 init_subregs_of_mode (void)
02585 {
02586 if (subregs_of_mode)
02587 htab_empty (subregs_of_mode);
02588 else
02589 subregs_of_mode = htab_create (100, som_hash, som_eq, free);
02590 }
02591
02592 void
02593 record_subregs_of_mode (rtx subreg)
02594 {
02595 struct subregs_of_mode_node dummy, *node;
02596 enum machine_mode mode;
02597 unsigned int regno;
02598 void **slot;
02599
02600 if (!REG_P (SUBREG_REG (subreg)))
02601 return;
02602
02603 regno = REGNO (SUBREG_REG (subreg));
02604 mode = GET_MODE (subreg);
02605
02606 if (regno < FIRST_PSEUDO_REGISTER)
02607 return;
02608
02609 dummy.block = regno & -8;
02610 slot = htab_find_slot_with_hash (subregs_of_mode, &dummy,
02611 dummy.block, INSERT);
02612 node = *slot;
02613 if (node == NULL)
02614 {
02615 node = XCNEW (struct subregs_of_mode_node);
02616 node->block = regno & -8;
02617 *slot = node;
02618 }
02619
02620 node->modes[mode] |= 1 << (regno & 7);
02621 }
02622
02623
02624
02625
02626 void
02627 cannot_change_mode_set_regs (HARD_REG_SET *used, enum machine_mode from,
02628 unsigned int regno)
02629 {
02630 struct subregs_of_mode_node dummy, *node;
02631 enum machine_mode to;
02632 unsigned char mask;
02633 unsigned int i;
02634
02635 dummy.block = regno & -8;
02636 node = htab_find_with_hash (subregs_of_mode, &dummy, dummy.block);
02637 if (node == NULL)
02638 return;
02639
02640 mask = 1 << (regno & 7);
02641 for (to = VOIDmode; to < NUM_MACHINE_MODES; to++)
02642 if (node->modes[to] & mask)
02643 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
02644 if (!TEST_HARD_REG_BIT (*used, i)
02645 && REG_CANNOT_CHANGE_MODE_P (i, from, to))
02646 SET_HARD_REG_BIT (*used, i);
02647 }
02648
02649
02650
02651
02652 bool
02653 invalid_mode_change_p (unsigned int regno, enum reg_class class,
02654 enum machine_mode from)
02655 {
02656 struct subregs_of_mode_node dummy, *node;
02657 enum machine_mode to;
02658 unsigned char mask;
02659
02660 dummy.block = regno & -8;
02661 node = htab_find_with_hash (subregs_of_mode, &dummy, dummy.block);
02662 if (node == NULL)
02663 return false;
02664
02665 mask = 1 << (regno & 7);
02666 for (to = VOIDmode; to < NUM_MACHINE_MODES; to++)
02667 if (node->modes[to] & mask)
02668 if (CANNOT_CHANGE_MODE_CLASS (from, to, class))
02669 return true;
02670
02671 return false;
02672 }
02673 #endif
02674
02675 #include "gt-regclass.h"