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