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