Statistics
| Revision:

root / spec / gcc / regclass.i @ 53

History | View | Annotate | Download (24.6 KB)

1

    
2
extern int target_flags;
3

    
4
enum reg_class { NO_REGS, LO_FPA_REGS, FPA_REGS, FP_REGS,
5
  FP_OR_FPA_REGS, DATA_REGS, DATA_OR_FPA_REGS, DATA_OR_FP_REGS,
6
  DATA_OR_FP_OR_FPA_REGS, ADDR_REGS, GENERAL_REGS,
7
  GENERAL_OR_FPA_REGS, GENERAL_OR_FP_REGS, ALL_REGS,
8
  LIM_REG_CLASSES };
9

    
10
extern enum reg_class regno_reg_class[];
11

    
12
enum rtx_code  {
13

    
14
  UNKNOWN , 
15

    
16
  NIL , 
17

    
18
  EXPR_LIST , 
19

    
20
  INSN_LIST , 
21

    
22
  MATCH_OPERAND , 
23

    
24
  MATCH_DUP , 
25

    
26
  MATCH_OPERATOR , 
27

    
28
  DEFINE_INSN , 
29

    
30
  DEFINE_PEEPHOLE , 
31

    
32
  DEFINE_COMBINE , 
33

    
34
  DEFINE_EXPAND , 
35

    
36
  SEQUENCE , 
37

    
38
  ADDRESS , 
39

    
40
  INSN , 
41

    
42
  JUMP_INSN , 
43

    
44
  CALL_INSN , 
45

    
46
  BARRIER , 
47

    
48
  CODE_LABEL , 
49

    
50
  NOTE , 
51

    
52
  INLINE_HEADER , 
53

    
54
  PARALLEL , 
55

    
56
  ASM_INPUT , 
57

    
58
  ASM_OPERANDS , 
59

    
60
  ADDR_VEC , 
61

    
62
  ADDR_DIFF_VEC , 
63

    
64
  SET , 
65

    
66
  USE , 
67

    
68
  CLOBBER , 
69

    
70
  CALL , 
71

    
72
  RETURN , 
73

    
74
  CONST_INT , 
75

    
76
  CONST_DOUBLE , 
77

    
78
  CONST , 
79

    
80
  PC , 
81

    
82
  REG , 
83

    
84
  SUBREG , 
85

    
86
  STRICT_LOW_PART , 
87

    
88
  MEM , 
89

    
90
  LABEL_REF , 
91

    
92
  SYMBOL_REF , 
93

    
94
  CC0 , 
95

    
96
  QUEUED , 
97

    
98
  IF_THEN_ELSE , 
99

    
100
  COMPARE , 
101

    
102
  PLUS , 
103

    
104
  MINUS , 
105

    
106
  NEG , 
107

    
108
  MULT , 
109

    
110
  DIV , 
111
  MOD , 
112

    
113
  UMULT , 
114
  UDIV , 
115
  UMOD , 
116

    
117
  AND , 
118

    
119
  IOR , 
120

    
121
  XOR , 
122

    
123
  NOT , 
124

    
125
  LSHIFT , 
126
  ASHIFT , 
127
  ROTATE , 
128

    
129
  ASHIFTRT , 
130
  LSHIFTRT , 
131
  ROTATERT , 
132

    
133
  PRE_DEC , 
134
  PRE_INC , 
135
  POST_DEC , 
136
  POST_INC , 
137

    
138
  NE , 
139
  EQ , 
140
  GE , 
141
  GT , 
142
  LE , 
143
  LT , 
144
  GEU , 
145
  GTU , 
146
  LEU , 
147
  LTU , 
148

    
149
  SIGN_EXTEND , 
150

    
151
  ZERO_EXTEND , 
152

    
153
  TRUNCATE , 
154

    
155
  FLOAT_EXTEND , 
156
  FLOAT_TRUNCATE , 
157

    
158
  FLOAT , 
159

    
160
  FIX , 
161

    
162
  UNSIGNED_FLOAT , 
163

    
164
  UNSIGNED_FIX , 
165

    
166
  ABS , 
167

    
168
  SQRT , 
169

    
170
  FFS , 
171

    
172
  SIGN_EXTRACT , 
173

    
174
  ZERO_EXTRACT , 
175

    
176
  LAST_AND_UNUSED_RTX_CODE};	 
177

    
178
extern int rtx_length[];
179

    
180
extern char *rtx_name[];
181

    
182
extern char *rtx_format[];
183

    
184
enum machine_mode {
185

    
186
 VOIDmode, 
187

    
188
 QImode, 		 
189
 HImode, 
190

    
191
 PSImode, 
192
 SImode, 
193
 PDImode, 
194
 DImode, 
195
 TImode, 
196
 QFmode, 
197
 HFmode, 		 
198
 SFmode, 
199
 DFmode, 
200
 XFmode, 	 
201
 TFmode, 
202
 CQImode, 
203
 CHImode, 	 
204
 CSImode, 
205
 CDImode, 
206
 CTImode, 
207
 CQFmode, 
208
 CHFmode, 	 
209
 CSFmode, 
210
 CDFmode, 
211
 CXFmode, 
212
 CTFmode, 
213

    
214
 BImode, 	 
215

    
216
 BLKmode, 
217

    
218
 EPmode, 
219

    
220
MAX_MACHINE_MODE };
221

    
222
extern char *mode_name[];
223

    
224
enum mode_class { MODE_RANDOM, MODE_INT, MODE_FLOAT,
225
		  MODE_COMPLEX_INT, MODE_COMPLEX_FLOAT, MODE_FUNCTION };
226

    
227
extern enum mode_class mode_class[];
228

    
229
extern int mode_size[];
230

    
231
extern int mode_unit_size[];
232

    
233
typedef union rtunion_def
234
{
235
  int rtint;
236
  char *rtstr;
237
  struct rtx_def *rtx;
238
  struct rtvec_def *rtvec;
239
  enum machine_mode rttype;
240
} rtunion;
241

    
242
typedef struct rtx_def
243
{
244

    
245
  enum rtx_code code : 16;
246

    
247
  enum machine_mode mode : 8;
248

    
249
  unsigned int jump : 1;
250
  unsigned int call : 1;
251

    
252
  unsigned int unchanging : 1;
253

    
254
  unsigned int volatil : 1;
255

    
256
  unsigned int in_struct : 1;
257

    
258
  unsigned int used : 1;
259

    
260
  unsigned integrated : 1;
261

    
262
  rtunion fld[1];
263
} *rtx;
264

    
265
typedef struct rtvec_def{
266
  unsigned num_elem;		 
267
  rtunion elem[1];
268
} *rtvec;
269

    
270
enum reg_note { REG_DEAD = 1, REG_INC = 2, REG_EQUIV = 3, REG_WAS_0 = 4,
271
		REG_EQUAL = 5, REG_RETVAL = 6, REG_LIBCALL = 7,
272
		REG_NONNEG = 8 };
273

    
274
extern char *reg_note_name[];
275

    
276
extern char *note_insn_name[];
277

    
278
extern rtx rtx_alloc ();
279
extern rtvec rtvec_alloc ();
280
extern rtx find_reg_note ();
281
extern rtx gen_rtx ();
282
extern rtx copy_rtx ();
283
extern rtvec gen_rtvec ();
284
extern rtvec gen_rtvec_v ();
285
extern rtx gen_reg_rtx ();
286
extern rtx gen_label_rtx ();
287
extern rtx gen_inline_header_rtx ();
288
extern rtx gen_lowpart ();
289
extern rtx gen_highpart ();
290
extern int subreg_lowpart_p ();
291
extern rtx make_safe_from ();
292
extern rtx memory_address ();
293
extern rtx get_insns ();
294
extern rtx get_last_insn ();
295
extern rtx start_sequence ();
296
extern rtx gen_sequence ();
297
extern rtx expand_expr ();
298
extern rtx output_constant_def ();
299
extern rtx immed_real_const ();
300
extern rtx immed_real_const_1 ();
301
extern rtx immed_double_const ();
302
extern rtx force_const_double_mem ();
303
extern rtx force_const_mem ();
304
extern rtx get_parm_real_loc ();
305
extern rtx assign_stack_local ();
306
extern rtx protect_from_queue ();
307
extern void emit_queue ();
308
extern rtx emit_move_insn ();
309
extern rtx emit_insn ();
310
extern rtx emit_jump_insn ();
311
extern rtx emit_call_insn ();
312
extern rtx emit_call_insn_before ();
313
extern rtx emit_insn_before ();
314
extern rtx emit_insn_after ();
315
extern rtx emit_label ();
316
extern rtx emit_barrier ();
317
extern rtx emit_note ();
318
extern rtx emit_line_note ();
319
extern rtx emit_line_note_force ();
320
extern rtx prev_real_insn ();
321
extern rtx next_real_insn ();
322
extern rtx next_nondeleted_insn ();
323
extern rtx plus_constant ();
324
extern rtx find_equiv_reg ();
325
extern rtx delete_insn ();
326
extern rtx adj_offsetable_operand ();
327

    
328
extern int max_parallel;
329

    
330
extern int asm_noperands ();
331
extern char *decode_asm_operands ();
332

    
333
extern enum reg_class reg_preferred_class ();
334

    
335
extern rtx get_first_nonparm_insn ();
336

    
337
extern rtx pc_rtx;
338
extern rtx cc0_rtx;
339
extern rtx const0_rtx;
340
extern rtx const1_rtx;
341
extern rtx fconst0_rtx;
342
extern rtx dconst0_rtx;
343

    
344
extern rtx stack_pointer_rtx;
345
extern rtx frame_pointer_rtx;
346
extern rtx arg_pointer_rtx;
347
extern rtx struct_value_rtx;
348
extern rtx struct_value_incoming_rtx;
349
extern rtx static_chain_rtx;
350
extern rtx static_chain_incoming_rtx;
351

    
352
typedef long HARD_REG_SET[((56  + 32  - 1) / 32 ) ];
353

    
354
extern char fixed_regs[56 ];
355

    
356
extern HARD_REG_SET fixed_reg_set;
357

    
358
extern char call_used_regs[56 ];
359

    
360
extern HARD_REG_SET call_used_reg_set;
361

    
362
extern char call_fixed_regs[56 ];
363

    
364
extern HARD_REG_SET call_fixed_reg_set;
365

    
366
extern char global_regs[56 ];
367

    
368
extern int reg_alloc_order[56 ];
369

    
370
extern HARD_REG_SET reg_class_contents[];
371

    
372
extern int reg_class_size[(int) LIM_REG_CLASSES ];
373

    
374
extern enum reg_class reg_class_superclasses[(int) LIM_REG_CLASSES ][(int) LIM_REG_CLASSES ];
375

    
376
extern enum reg_class reg_class_subclasses[(int) LIM_REG_CLASSES ][(int) LIM_REG_CLASSES ];
377

    
378
extern enum reg_class reg_class_subunion[(int) LIM_REG_CLASSES ][(int) LIM_REG_CLASSES ];
379

    
380
extern char *main_input_filename;
381

    
382
enum debugger { NO_DEBUG = 0, GDB_DEBUG = 1, DBX_DEBUG = 2, SDB_DEBUG = 3,
383
		EXTENDED_DBX_DEBUG = 4 };
384

    
385
extern enum debugger write_symbols;
386

    
387
extern int use_gdb_dbx_extensions;
388

    
389
extern int optimize;
390

    
391
extern int obey_regdecls;
392

    
393
extern int quiet_flag;
394

    
395
extern int inhibit_warnings;
396

    
397
extern int extra_warnings;
398

    
399
extern int warn_unused;
400

    
401
extern int warn_shadow;
402

    
403
extern int warn_switch;
404

    
405
extern int warn_id_clash;
406
extern int id_clash_len;
407

    
408
extern int profile_flag;
409

    
410
extern int profile_block_flag;
411

    
412
extern int pedantic;
413

    
414
extern int flag_caller_saves;
415

    
416
extern int flag_pcc_struct_return;
417

    
418
extern int flag_force_mem;
419

    
420
extern int flag_force_addr;
421

    
422
extern int flag_defer_pop;
423

    
424
extern int flag_float_store;
425

    
426
extern int flag_combine_regs;
427

    
428
extern int flag_strength_reduce;
429

    
430
extern int flag_writable_strings;
431

    
432
extern int flag_no_function_cse;
433

    
434
extern int flag_omit_frame_pointer;
435

    
436
extern int frame_pointer_needed;
437

    
438
extern int flag_no_peephole;
439

    
440
extern int flag_volatile;
441

    
442
extern int flag_inline_functions;
443

    
444
extern int flag_keep_inline_functions;
445

    
446
extern int flag_syntax_only;
447

    
448
extern int flag_shared_data;
449

    
450
typedef long *regset;
451

    
452
extern int regset_bytes;
453
extern int regset_size;
454

    
455
extern int n_basic_blocks;
456

    
457
extern rtx *basic_block_head;
458

    
459
extern rtx *basic_block_end;
460

    
461
extern regset *basic_block_live_at_start;
462

    
463
extern short *reg_basic_block;
464

    
465
extern int max_regno;
466

    
467
extern short *reg_n_refs;
468

    
469
extern short *reg_n_sets;
470

    
471
extern short *reg_n_deaths;
472

    
473
extern int *reg_n_calls_crossed;
474

    
475
extern int *reg_live_length;
476

    
477
extern short *reg_renumber;
478

    
479
extern char regs_ever_live[56 ];
480

    
481
extern char *reg_names[56 ];
482

    
483
extern short *regno_first_uid;
484

    
485
extern short *regno_last_uid;
486

    
487
extern char *regno_pointer_flag;
488

    
489
extern rtx *regno_reg_rtx;
490

    
491
extern int caller_save_needed;
492

    
493
extern int recog_memoized ();
494

    
495
extern void insn_extract ();
496

    
497
extern rtx recog_operand[];
498

    
499
extern rtx *recog_operand_loc[];
500

    
501
extern rtx *recog_dup_loc[];
502

    
503
extern char recog_dup_num[];
504

    
505
extern char *insn_template[];
506

    
507
extern char *(*insn_outfun[]) ();
508

    
509
extern int insn_n_operands[];
510

    
511
extern int insn_n_dups[];
512

    
513
extern int insn_n_alternatives[];
514

    
515
extern char *insn_operand_constraint[][5 ];
516

    
517
extern char insn_operand_address_p[][5 ];
518

    
519
extern enum machine_mode insn_operand_mode[][5 ];
520

    
521
extern char insn_operand_strict_low[][5 ];
522

    
523
extern int (*insn_operand_predicate[][5 ]) ();
524

    
525
char fixed_regs[56 ];
526

    
527
HARD_REG_SET fixed_reg_set;
528

    
529
static char initial_fixed_regs[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, } ;
530

    
531
char call_used_regs[56 ];
532

    
533
HARD_REG_SET call_used_reg_set;
534

    
535
static char initial_call_used_regs[] = {1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, } ;
536

    
537
char call_fixed_regs[56 ];
538

    
539
HARD_REG_SET call_fixed_reg_set;
540

    
541
char global_regs[56 ];
542

    
543
HARD_REG_SET reg_class_contents[] = {	{0, 0},	{0xff000000, 0x000000ff},	{0xff000000, 0x00ffffff},	{0x00ff0000, 0x00000000},	{0xffff0000, 0x00ffffff},	{0x000000ff, 0x00000000},	{0xff0000ff, 0x00ffffff},	{0x00ff00ff, 0x00000000},	{0xffff00ff, 0x00ffffff},	{0x0000ff00, 0x00000000},	{0x0000ffff, 0x00000000},	{0xff00ffff, 0x00ffffff},	{0x00ffffff, 0x00000000},	{0xffffffff, 0x00ffffff},	} ;
544

    
545
int reg_class_size[(int) LIM_REG_CLASSES ];
546

    
547
enum reg_class reg_class_superclasses[(int) LIM_REG_CLASSES ][(int) LIM_REG_CLASSES ];
548

    
549
enum reg_class reg_class_subclasses[(int) LIM_REG_CLASSES ][(int) LIM_REG_CLASSES ];
550

    
551
enum reg_class reg_class_subunion[(int) LIM_REG_CLASSES ][(int) LIM_REG_CLASSES ];
552

    
553
char *reg_names[] = {"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",	"a0", "a1", "a2", "a3", "a4", "a5", "a6", "sp",	"fp0", "fp1", "fp2", "fp3", "fp4", "fp5", "fp6", "fp7", "fpa0", "fpa1", "fpa2", "fpa3", "fpa4", "fpa5", "fpa6", "fpa7", "fpa8", "fpa9", "fpa10", "fpa11", "fpa12", "fpa13", "fpa14", "fpa15", "fpa16", "fpa17", "fpa18", "fpa19", "fpa20", "fpa21", "fpa22", "fpa23", "fpa24", "fpa25", "fpa26", "fpa27", "fpa28", "fpa29", "fpa30", "fpa31", } ;
554

    
555
void
556
init_reg_sets ()
557
{
558
  register int i, j;
559

    
560
  memcpy ( fixed_regs,initial_fixed_regs, sizeof fixed_regs) ;
561
  memcpy ( call_used_regs,initial_call_used_regs, sizeof call_used_regs) ;
562
  memset (global_regs,0, sizeof global_regs) ;
563

    
564
  memset (reg_class_size,0, sizeof reg_class_size) ;
565
  for (i = 0; i < (int) LIM_REG_CLASSES ; i++)
566
    for (j = 0; j < 56 ; j++)
567
      if (((reg_class_contents[i])[( j) / 32 ] & (1 << (( j) % 32 ))) )
568
	reg_class_size[i]++;
569

    
570
  for (i = 0; i < (int) LIM_REG_CLASSES ; i++)
571
    {
572
      for (j = 0; j < (int) LIM_REG_CLASSES ; j++)
573
	{
574

    
575
	    HARD_REG_SET c;
576
	  register int k;
577

    
578
	  do { register long *scan_tp_ = (c), *scan_fp_ = ( reg_class_contents[i]);	register int i;	for (i = 0; i < ((56  + 32  - 1) / 32 ) ; i++)	*scan_tp_++ = *scan_fp_++; } while (0) ;
579
	  do { register long *scan_tp_ = (c), *scan_fp_ = ( reg_class_contents[j]);	register int i;	for (i = 0; i < ((56  + 32  - 1) / 32 ) ; i++)	*scan_tp_++ |= *scan_fp_++; } while (0) ;
580
	  for (k = 0; k < (int) LIM_REG_CLASSES ; k++)
581
	    {
582
	      do { register long *scan_xp_ = (reg_class_contents[k]), *scan_yp_ = ( c);	register int i;	for (i = 0; i < ((56  + 32  - 1) / 32 ) ; i++)	if (0 != (*scan_xp_++ & ~*scan_yp_++)) break;	if (i == ((56  + 32  - 1) / 32 ) ) goto 
583
				     subclass1; } while (0) ;
584
	      continue;
585

    
586
	    subclass1:
587
	      reg_class_subunion[i][j] = (enum reg_class) k;
588
	    }
589
	}
590
    }
591

    
592
  for (i = 0; i < (int) LIM_REG_CLASSES ; i++)
593
    {
594
      for (j = 0; j < (int) LIM_REG_CLASSES ; j++)
595
	{
596
	  reg_class_superclasses[i][j] = LIM_REG_CLASSES;
597
	  reg_class_subclasses[i][j] = LIM_REG_CLASSES;
598
	}
599
    }
600

    
601
  for (i = 0; i < (int) LIM_REG_CLASSES ; i++)
602
    {
603
      if (i == (int) NO_REGS)
604
	continue;
605

    
606
      for (j = i + 1; j < (int) LIM_REG_CLASSES ; j++)
607
	{
608
	  enum reg_class *p;
609

    
610
	  do { register long *scan_xp_ = (reg_class_contents[i]), *scan_yp_ = ( reg_class_contents[j]);	register int i;	for (i = 0; i < ((56  + 32  - 1) / 32 ) ; i++)	if (0 != (*scan_xp_++ & ~*scan_yp_++)) break;	if (i == ((56  + 32  - 1) / 32 ) ) goto 
611
				 subclass; } while (0) ;
612
	  continue;
613
	subclass:
614

    
615
	  p = &reg_class_superclasses[i][0];
616
	  while (*p != LIM_REG_CLASSES) p++;
617
	  *p = (enum reg_class) j;
618
	  p = &reg_class_subclasses[j][0];
619
	  while (*p != LIM_REG_CLASSES) p++;
620
	  *p = (enum reg_class) i;
621
	}
622
    }
623

    
624
}
625

    
626
void
627
init_reg_sets_1 ()
628
{
629
  register int i;
630

    
631
  { int i; HARD_REG_SET x; if (!(target_flags & 0100) )	{ do { register long *scan_tp_ = (x), *scan_fp_ = ( reg_class_contents[(int)FPA_REGS]);	register int i;	for (i = 0; i < ((56  + 32  - 1) / 32 ) ; i++)	*scan_tp_++ = *scan_fp_++; } while (0) ; for (i = 0; i < 56 ; i++ ) if (((x)[( i) / 32 ] & (1 << (( i) % 32 ))) ) fixed_regs[i] = call_used_regs[i] = 1; } if ((target_flags & 0100) )	{ do { register long *scan_tp_ = (x), *scan_fp_ = ( reg_class_contents[(int)FP_REGS]);	register int i;	for (i = 0; i < ((56  + 32  - 1) / 32 ) ; i++)	*scan_tp_++ = *scan_fp_++; } while (0) ; for (i = 0; i < 56 ; i++ ) if (((x)[( i) / 32 ] & (1 << (( i) % 32 ))) ) fixed_regs[i] = call_used_regs[i] = 1; } } ;
632

    
633
  for (i = 0; i < 56 ; i++)
634
    if (global_regs[i])
635
      {
636
	if (call_used_regs[i] && ! fixed_regs[i])
637
	  warning ("call-clobbered register used for global register variable");
638
	fixed_regs[i] = 1;
639
	call_used_regs[i] = 1;
640
      }
641

    
642
  do { register long *scan_tp_ = (fixed_reg_set);	register int i;	for (i = 0; i < ((56  + 32  - 1) / 32 ) ; i++)	*scan_tp_++ = 0; } while (0) ;
643
  do { register long *scan_tp_ = (call_used_reg_set);	register int i;	for (i = 0; i < ((56  + 32  - 1) / 32 ) ; i++)	*scan_tp_++ = 0; } while (0) ;
644
  do { register long *scan_tp_ = (call_fixed_reg_set);	register int i;	for (i = 0; i < ((56  + 32  - 1) / 32 ) ; i++)	*scan_tp_++ = 0; } while (0) ;
645

    
646
  memcpy ( call_fixed_regs,fixed_regs, sizeof call_fixed_regs) ;
647

    
648
  call_fixed_regs[9 ] = 1;
649

    
650
  call_fixed_regs[8 ] = 1;
651

    
652
  for (i = 0; i < 56 ; i++)
653
    {
654
      if (((i) == 0) )
655
	call_fixed_regs[i] = 1;
656
      if (fixed_regs[i])
657
	((fixed_reg_set)[( i) / 32 ] |= 1 << (( i) % 32 )) ;
658
      if (call_used_regs[i])
659
	((call_used_reg_set)[( i) / 32 ] |= 1 << (( i) % 32 )) ;
660
      if (call_fixed_regs[i])
661
	((call_fixed_reg_set)[( i) / 32 ] |= 1 << (( i) % 32 )) ;
662
    }
663
}
664

    
665
void
666
fix_register (name, fixed, call_used)
667
     char *name;
668
     int fixed, call_used;
669
{
670
  int i;
671

    
672
  for (i = 0; i < 56 ; i++)
673
    if (!strcmp (reg_names[i], name))
674
      {
675
	fixed_regs[i] = fixed;
676
	call_used_regs[i] = call_used;
677
	break;
678
      }
679

    
680
  if (i == 56 )
681
    {
682
      warning ("unknown register name: %s", name);
683
      return;
684
    }
685
}
686

    
687
struct savings
688
{
689
  short savings[(int) LIM_REG_CLASSES ];
690
  short memcost;
691
  short nrefs;
692
};
693

    
694
static struct savings *savings;
695

    
696
static char *prefclass;
697

    
698
static char *preferred_or_nothing;
699

    
700
void reg_class_record ();
701
void record_address_regs ();
702

    
703
enum reg_class
704
reg_preferred_class (regno)
705
     int regno;
706
{
707
  if (prefclass == 0)
708
    return GENERAL_REGS;
709
  return (enum reg_class) prefclass[regno];
710
}
711

    
712
int
713
reg_preferred_or_nothing (regno)
714
{
715
  if (prefclass == 0)
716
    return 0;
717
  return preferred_or_nothing[regno];
718
}
719

    
720
int
721
regclass_init ()
722
{
723
  prefclass = 0;
724
}
725

    
726
void
727
regclass (f, nregs)
728
     rtx f;
729
     int nregs;
730
{
731

    
732
  register rtx insn;
733
  register int i;
734

    
735
  init_recog ();
736

    
737
  savings = (struct savings *) __builtin_alloca  (nregs * sizeof (struct savings));
738
  memset (savings,0, nregs * sizeof (struct savings)) ;
739

    
740
  for (insn = f; insn; insn = ((insn)->fld[2].rtx) )
741
    if ((	((insn)->code)  == INSN
742
	 && 	((((insn)->fld[3].rtx) )->code)  != USE
743
	 && 	((((insn)->fld[3].rtx) )->code)  != CLOBBER
744
	 && 	((((insn)->fld[3].rtx) )->code)  != ASM_INPUT)
745
	|| (	((insn)->code)  == JUMP_INSN
746
	    && 	((((insn)->fld[3].rtx) )->code)  != ADDR_VEC
747
	    && 	((((insn)->fld[3].rtx) )->code)  != ADDR_DIFF_VEC)
748
	|| 	((insn)->code)  == CALL_INSN)
749
      {
750
	if (	((insn)->code)  == INSN && asm_noperands (((insn)->fld[3].rtx) ) >= 0)
751
	  {
752
	    int noperands = asm_noperands (((insn)->fld[3].rtx) );
753

    
754
	    rtx *operands = (rtx *) oballoc (noperands * sizeof (rtx));
755
	    char **constraints
756
	      = (char **) oballoc (noperands * sizeof (char *));
757

    
758
	    decode_asm_operands (((insn)->fld[3].rtx) , operands, 0, constraints, 0);
759

    
760
	    for (i = noperands - 1; i >= 0; i--)
761
	      reg_class_record (operands[i], i, constraints);
762

    
763
	    obfree (operands);
764
	  }
765
	else
766
	  {
767
	    int insn_code_number = recog_memoized (insn);
768

    
769
	    insn_extract (insn);
770

    
771
	    for (i = insn_n_operands[insn_code_number] - 1; i >= 0; i--)
772
	      reg_class_record (recog_operand[i], i,
773
				insn_operand_constraint[insn_code_number]);
774

    
775
	    if (optimize
776
		&& insn_n_operands[insn_code_number] >= 3
777
		&& insn_operand_constraint[insn_code_number][1][0] == '0'
778
		&& insn_operand_constraint[insn_code_number][1][1] == 0
779
		&& (	((recog_operand[1])->code)  == LABEL_REF || 	((recog_operand[1])->code)  == SYMBOL_REF	|| 	((recog_operand[1])->code)  == CONST_INT	|| 	((recog_operand[1])->code)  == CONST) 
780
		&& ! rtx_equal_p (recog_operand[0], recog_operand[1])
781
		&& ! rtx_equal_p (recog_operand[0], recog_operand[2])
782
		&& 	((recog_operand[0])->code)  == REG)
783
	      {
784
		rtx previnsn = prev_real_insn (insn);
785
		rtx newinsn
786
		  = emit_insn_before (gen_move_insn (recog_operand[0],
787
						     recog_operand[1]),
788
				      insn);
789

    
790
		if (previnsn == 0 || 	((previnsn)->code)  == JUMP_INSN)
791
		  {
792
		    int b;
793
		    for (b = 0; b < n_basic_blocks; b++)
794
		      if (insn == basic_block_head[b])
795
			basic_block_head[b] = newinsn;
796
		  }
797

    
798
		reg_n_sets[((recog_operand[0])->fld[0].rtint) ]++;
799

    
800
		*recog_operand_loc[1] = recog_operand[0];
801
		for (i = insn_n_dups[insn_code_number] - 1; i >= 0; i--)
802
		  if (recog_dup_num[i] == 1)
803
		    *recog_dup_loc[i] = recog_operand[0];
804

    
805
	      }
806
	  }
807
      }
808

    
809
  prefclass = (char *) oballoc (nregs);
810
  preferred_or_nothing = (char *) oballoc (nregs);
811

    
812
  for (i = 56 ; i < nregs; i++)
813
    {
814
      register int best_savings = 0;
815
      enum reg_class best = ALL_REGS;
816

    
817
      register int class;
818
      register struct savings *p = &savings[i];
819

    
820
      for (class = (int) ALL_REGS - 1; class > 0; class--)
821
	{
822
	  if (p->savings[class] > best_savings)
823
	    {
824
	      best_savings = p->savings[class];
825
	      best = (enum reg_class) class;
826
	    }
827
	  else if (p->savings[class] == best_savings)
828
	    {
829
	      best = reg_class_subunion[(int)best][class];
830
	    }
831
	}
832

    
833
      prefclass[i] = (int) best;
834

    
835
      if (reg_n_refs != 0)
836
	preferred_or_nothing[i]
837
	  = ((best_savings - p->savings[(int) GENERAL_REGS])
838
	     >= p->nrefs + p->memcost);
839
    }
840

    
841
}
842

    
843
void
844
reg_class_record (op, opno, constraints)
845
     rtx op;
846
     int opno;
847
     char **constraints;
848
{
849
  char *constraint = constraints[opno];
850
  register char *p;
851
  register enum reg_class class = NO_REGS;
852
  char *next = 0;
853
  int memok = 0;
854
  int double_cost = 0;
855

    
856
  while (1)
857
    {
858
      if (	((op)->code)  == SUBREG)
859
	op = ((op)->fld[0].rtx) ;
860
      else break;
861
    }
862

    
863
  if (	((op)->code)  == MEM)
864
    record_address_regs (((op)->fld[ 0].rtx) , 2, 0);
865

    
866
  if (	((op)->code)  != REG)
867
    {
868

    
869
      if (constraint != 0 && constraint[0] == 'p')
870
	record_address_regs (op, 2, 0);
871
      return;
872
    }
873

    
874
  for (p = constraint; *p || next; p++)
875
    {
876
      if (*p == 0)
877
	{
878
	  p = next;
879
	  next = 0;
880
	}
881
      switch (*p)
882
	{
883
	case '=':
884
	case '?':
885
	case '#':
886
	case '&':
887
	case '!':
888
	case '%':
889
	case 'F':
890
	case 'G':
891
	case 'H':
892
	case 'i':
893
	case 'n':
894
	case 's':
895
	case 'p':
896
	case ',':
897
	  break;
898

    
899
	case '+':
900
	  double_cost = 1;
901
	  break;
902

    
903
	case 'm':
904
	case 'o':
905
	  memok = 1;
906
	  break;
907

    
908
	case '*':
909
	  p++;
910
	  break;
911

    
912
	case 'g':
913
	case 'r':
914
	  class
915
	    = reg_class_subunion[(int) class][(int) GENERAL_REGS];
916
	  break;
917

    
918
	case '0':
919
	case '1':
920
	case '2':
921
	case '3':
922
	case '4':
923

    
924
	  next = constraints[*p - '0'];
925
	  break;
926

    
927
	default:
928
	  class
929
	    = reg_class_subunion[(int) class][(int) ((*p) == 'a' ? ADDR_REGS :	((*p) == 'd' ? DATA_REGS :	((*p) == 'f' ? ((target_flags & 2)  ? FP_REGS :	NO_REGS) :	((*p) == 'x' ? ((target_flags & 0100)  ? FPA_REGS :	NO_REGS) :	((*p) == 'y' ? ((target_flags & 0100)  ? LO_FPA_REGS :	NO_REGS) :	NO_REGS))))) ];
930
	}
931
    }
932

    
933
  {
934
    register int i;
935
    register struct savings *pp;
936
    register enum reg_class class1;
937
    int cost = 2 * (1 + double_cost);
938
    pp = &savings[((op)->fld[0].rtint) ];
939

    
940
    if (class != NO_REGS && class != ALL_REGS)
941
      {
942
	pp->savings[(int) class] += cost;
943
	for (i = 0; ; i++)
944
	  {
945
	    class1 = reg_class_subclasses[(int)class][i];
946
	    if (class1 == LIM_REG_CLASSES)
947
	      break;
948
	    pp->savings[(int) class1] += cost;
949
	  }
950
      }
951

    
952
    if (! memok)
953
      pp->memcost += 1 + 2 * double_cost;
954
    pp->nrefs++;
955
  }
956
}
957

    
958
void
959
record_address_regs (x, bcost, icost)
960
     rtx x;
961
     int bcost, icost;
962
{
963
  register enum rtx_code code = 	((x)->code) ;
964

    
965
  switch (code)
966
    {
967
    case CONST_INT:
968
    case CONST:
969
    case CC0:
970
    case PC:
971
    case SYMBOL_REF:
972
    case LABEL_REF:
973
      return;
974

    
975
    case PLUS:
976

    
977
      {
978
	rtx arg0 = ((x)->fld[ 0].rtx) ;
979
	rtx arg1 = ((x)->fld[ 1].rtx) ;
980
	register enum rtx_code code0 = 	((arg0)->code) ;
981
	register enum rtx_code code1 = 	((arg1)->code) ;
982
	int icost0 = 0;
983
	int icost1 = 0;
984
	int suppress1 = 0;
985
	int suppress0 = 0;
986

    
987
	while (code0 == SUBREG)
988
	  arg0 = ((arg0)->fld[0].rtx) , code0 = 	((arg0)->code) ;
989
	while (code1 == SUBREG)
990
	  arg1 = ((arg1)->fld[0].rtx) , code1 = 	((arg1)->code) ;
991

    
992
	if (code0 == MULT || code1 == MEM)
993
	  icost0 = 2;
994
	else if (code1 == MULT || code0 == MEM)
995
	  icost1 = 2;
996
	else if (code0 == CONST_INT)
997
	  suppress0 = 1;
998
	else if (code1 == CONST_INT)
999
	  suppress1 = 1;
1000
	else if (code0 == REG && code1 == REG)
1001
	  {
1002
	    if (regno_pointer_flag[((arg0)->fld[0].rtint) ] )
1003
	      icost1 = 2;
1004
	    else if (regno_pointer_flag[((arg1)->fld[0].rtint) ] )
1005
	      icost0 = 2;
1006
	    else
1007
	      icost0 = icost1 = 1;
1008
	  }
1009
	else if (code0 == REG)
1010
	  {
1011
	    if (code1 == PLUS
1012
		&& ! regno_pointer_flag[((arg0)->fld[0].rtint) ] )
1013
	      icost0 = 2;
1014
	    else
1015
	      regno_pointer_flag[((arg0)->fld[0].rtint) ]  = 1;
1016
	  }
1017
	else if (code1 == REG)
1018
	  {
1019
	    if (code0 == PLUS
1020
		&& ! regno_pointer_flag[((arg1)->fld[0].rtint) ] )
1021
	      icost1 = 2;
1022
	    else
1023
	      regno_pointer_flag[((arg1)->fld[0].rtint) ]  = 1;
1024
	  }
1025

    
1026
	if (! suppress0)
1027
	  record_address_regs (arg0, 2 - icost0, icost0);
1028
	if (! suppress1)
1029
	  record_address_regs (arg1, 2 - icost1, icost1);
1030
      }
1031
      break;
1032

    
1033
    case POST_INC:
1034
    case PRE_INC:
1035
    case POST_DEC:
1036
    case PRE_DEC:
1037

    
1038
      record_address_regs (((x)->fld[ 0].rtx) , 2 * bcost, 2 * icost);
1039
      break;
1040

    
1041
    case REG:
1042
      {
1043
	register struct savings *pp;
1044
	register enum reg_class class, class1;
1045
	pp = &savings[((x)->fld[0].rtint) ];
1046
	pp->nrefs++;
1047

    
1048
	class = ADDR_REGS ;
1049
	if (class != NO_REGS && class != ALL_REGS)
1050
	  {
1051
	    register int i;
1052
	    pp->savings[(int) class] += bcost;
1053
	    for (i = 0; ; i++)
1054
	      {
1055
		class1 = reg_class_subclasses[(int)class][i];
1056
		if (class1 == LIM_REG_CLASSES)
1057
		  break;
1058
		pp->savings[(int) class1] += bcost;
1059
	      }
1060
	  }
1061

    
1062
	class = GENERAL_REGS ;
1063
	if (icost != 0 && class != NO_REGS && class != ALL_REGS)
1064
	  {
1065
	    register int i;
1066
	    pp->savings[(int) class] += icost;
1067
	    for (i = 0; ; i++)
1068
	      {
1069
		class1 = reg_class_subclasses[(int)class][i];
1070
		if (class1 == LIM_REG_CLASSES)
1071
		  break;
1072
		pp->savings[(int) class1] += icost;
1073
	      }
1074
	  }
1075
      }
1076
      break;
1077

    
1078
    default:
1079
      {
1080
	register char *fmt = 	(rtx_format[(int)(code)]) ;
1081
	register int i;
1082
	for (i = 	(rtx_length[(int)(code)])  - 1; i >= 0; i--)
1083
	  if (fmt[i] == 'e')
1084
	    record_address_regs (((x)->fld[ i].rtx) , bcost, icost);
1085
      }
1086
    }
1087
}
1088

    
1089
short *regno_first_uid;
1090

    
1091
short *regno_last_uid;
1092

    
1093
int max_parallel;
1094

    
1095
void reg_scan_mark_refs ();
1096

    
1097
void
1098
reg_scan (f, nregs, repeat)
1099
     rtx f;
1100
     int nregs;
1101
     int repeat;
1102
{
1103
  register rtx insn;
1104

    
1105
  if (!repeat)
1106
    regno_first_uid = (short *) oballoc (nregs * sizeof (short));
1107
  memset (regno_first_uid,0, nregs * sizeof (short)) ;
1108

    
1109
  if (!repeat)
1110
    regno_last_uid = (short *) oballoc (nregs * sizeof (short));
1111
  memset (regno_last_uid,0, nregs * sizeof (short)) ;
1112

    
1113
  max_parallel = 3;
1114

    
1115
  for (insn = f; insn; insn = ((insn)->fld[2].rtx) )
1116
    if (	((insn)->code)  == INSN
1117
	|| 	((insn)->code)  == CALL_INSN
1118
	|| 	((insn)->code)  == JUMP_INSN)
1119
      {
1120
	if (	((((insn)->fld[3].rtx) )->code)  == PARALLEL
1121
	    && ((((insn)->fld[3].rtx) )->fld[ 0].rtvec->num_elem)  > max_parallel)
1122
	  max_parallel = ((((insn)->fld[3].rtx) )->fld[ 0].rtvec->num_elem) ;
1123
	reg_scan_mark_refs (((insn)->fld[3].rtx) , ((insn)->fld[0].rtint) );
1124
      }
1125
}
1126

    
1127
void
1128
reg_scan_mark_refs (x, uid)
1129
     rtx x;
1130
     int uid;
1131
{
1132
  register enum rtx_code code = 	((x)->code) ;
1133

    
1134
  switch (code)
1135
    {
1136
    case CONST_INT:
1137
    case CONST:
1138
    case CONST_DOUBLE:
1139
    case CC0:
1140
    case PC:
1141
    case SYMBOL_REF:
1142
    case LABEL_REF:
1143
    case ADDR_VEC:
1144
    case ADDR_DIFF_VEC:
1145
      return;
1146

    
1147
    case REG:
1148
      {
1149
	register int regno = ((x)->fld[0].rtint) ;
1150

    
1151
	regno_last_uid[regno] = uid;
1152
	if (regno_first_uid[regno] == 0)
1153
	  regno_first_uid[regno] = uid;
1154
      }
1155
      break;
1156

    
1157
    default:
1158
      {
1159
	register char *fmt = 	(rtx_format[(int)(code)]) ;
1160
	register int i;
1161
	for (i = 	(rtx_length[(int)(code)])  - 1; i >= 0; i--)
1162
	  {
1163
	    if (fmt[i] == 'e')
1164
	      reg_scan_mark_refs (((x)->fld[ i].rtx) , uid);
1165
	    else if (fmt[i] == 'E' && ((x)->fld[ i].rtvec)  != 0)
1166
	      {
1167
		register int j;
1168
		for (j = ((x)->fld[ i].rtvec->num_elem)  - 1; j >= 0; j--)
1169
		  reg_scan_mark_refs (((x)->fld[ i].rtvec->elem[ j].rtx) , uid);		  
1170
	      }
1171
	  }
1172
      }
1173
    }
1174
}
1175