(mips_debugger_offset): Don't crash for unknown cases.
[gcc.git] / gcc / config / mips / mips.c
1 /* Subroutines for insn-output.c for MIPS
2 Contributed by A. Lichnewsky, lich@inria.inria.fr.
3 Changes by Michael Meissner, meissner@osf.org.
4 Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc.
5
6 This file is part of GNU CC.
7
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to
20 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
21
22 #include "config.h"
23 #include "rtl.h"
24 #include "regs.h"
25 #include "hard-reg-set.h"
26 #include "real.h"
27 #include "insn-config.h"
28 #include "conditions.h"
29 #include "insn-flags.h"
30 #include "insn-attr.h"
31 #include "insn-codes.h"
32 #include "recog.h"
33 #include "output.h"
34
35 #undef MAX /* sys/param.h may also define these */
36 #undef MIN
37
38 #include <stdio.h>
39 #include <signal.h>
40 #include <sys/types.h>
41 #include <sys/file.h>
42 #include <ctype.h>
43 #include "tree.h"
44 #include "expr.h"
45 #include "flags.h"
46
47 #ifndef R_OK
48 #define R_OK 4
49 #define W_OK 2
50 #define X_OK 1
51 #endif
52
53 #if defined(USG) || defined(NO_STAB_H)
54 #include "gstab.h" /* If doing DBX on sysV, use our own stab.h. */
55 #else
56 #include <stab.h> /* On BSD, use the system's stab.h. */
57 #endif /* not USG */
58
59 #ifdef __GNU_STAB__
60 #define STAB_CODE_TYPE enum __stab_debug_code
61 #else
62 #define STAB_CODE_TYPE int
63 #endif
64
65 extern void abort ();
66 extern int atoi ();
67 extern char *getenv ();
68 extern char *mktemp ();
69
70 extern rtx adj_offsettable_operand ();
71 extern rtx copy_to_reg ();
72 extern void error ();
73 extern void fatal ();
74 extern tree lookup_name ();
75 extern void pfatal_with_name ();
76 extern void warning ();
77
78 extern tree current_function_decl;
79 extern FILE *asm_out_file;
80
81 /* Enumeration for all of the relational tests, so that we can build
82 arrays indexed by the test type, and not worry about the order
83 of EQ, NE, etc. */
84
85 enum internal_test {
86 ITEST_EQ,
87 ITEST_NE,
88 ITEST_GT,
89 ITEST_GE,
90 ITEST_LT,
91 ITEST_LE,
92 ITEST_GTU,
93 ITEST_GEU,
94 ITEST_LTU,
95 ITEST_LEU,
96 ITEST_MAX
97 };
98
99 /* Global variables for machine-dependent things. */
100
101 /* Threshold for data being put into the small data/bss area, instead
102 of the normal data area (references to the small data/bss area take
103 1 instruction, and use the global pointer, references to the normal
104 data area takes 2 instructions). */
105 int mips_section_threshold = -1;
106
107 /* Count the number of .file directives, so that .loc is up to date. */
108 int num_source_filenames = 0;
109
110 /* Count the number of sdb related labels are generated (to find block
111 start and end boundaries). */
112 int sdb_label_count = 0;
113
114 /* Next label # for each statment for Silicon Graphics IRIS systems. */
115 int sym_lineno = 0;
116
117 /* Non-zero if inside of a function, because the stupid MIPS asm can't
118 handle .files inside of functions. */
119 int inside_function = 0;
120
121 /* Files to separate the text and the data output, so that all of the data
122 can be emitted before the text, which will mean that the assembler will
123 generate smaller code, based on the global pointer. */
124 FILE *asm_out_data_file;
125 FILE *asm_out_text_file;
126
127 /* Linked list of all externals that are to be emitted when optimizing
128 for the global pointer if they haven't been declared by the end of
129 the program with an appropriate .comm or initialization. */
130
131 struct extern_list {
132 struct extern_list *next; /* next external */
133 char *name; /* name of the external */
134 int size; /* size in bytes */
135 } *extern_head = 0;
136
137 /* Name of the file containing the current function. */
138 char *current_function_file = "";
139
140 /* Warning given that Mips ECOFF can't support changing files
141 within a function. */
142 int file_in_function_warning = FALSE;
143
144 /* Whether to suppress issuing .loc's because the user attempted
145 to change the filename within a function. */
146 int ignore_line_number = FALSE;
147
148 /* Number of nested .set noreorder, noat, nomacro, and volatile requests. */
149 int set_noreorder;
150 int set_noat;
151 int set_nomacro;
152 int set_volatile;
153
154 /* The next branch instruction is a branch likely, not branch normal. */
155 int mips_branch_likely;
156
157 /* Count of delay slots and how many are filled. */
158 int dslots_load_total;
159 int dslots_load_filled;
160 int dslots_jump_total;
161 int dslots_jump_filled;
162
163 /* # of nops needed by previous insn */
164 int dslots_number_nops;
165
166 /* Number of 1/2/3 word references to data items (ie, not jal's). */
167 int num_refs[3];
168
169 /* registers to check for load delay */
170 rtx mips_load_reg, mips_load_reg2, mips_load_reg3, mips_load_reg4;
171
172 /* Cached operands, and operator to compare for use in set/branch on
173 condition codes. */
174 rtx branch_cmp[2];
175
176 /* what type of branch to use */
177 enum cmp_type branch_type;
178
179 /* Number of previously seen half-pic pointers and references. */
180 static int prev_half_pic_ptrs = 0;
181 static int prev_half_pic_refs = 0;
182
183 /* which cpu are we scheduling for */
184 enum processor_type mips_cpu;
185
186 /* which instruction set architecture to use. */
187 int mips_isa;
188
189 /* Strings to hold which cpu and instruction set architecture to use. */
190 char *mips_cpu_string; /* for -mcpu=<xxx> */
191 char *mips_isa_string; /* for -mips{1,2,3} */
192
193 /* Array to RTX class classification. At present, we care about
194 whether the operator is an add-type operator, or a divide/modulus,
195 and if divide/modulus, whether it is unsigned. This is for the
196 peephole code. */
197 char mips_rtx_classify[NUM_RTX_CODE];
198
199 /* Array giving truth value on whether or not a given hard register
200 can support a given mode. */
201 char mips_hard_regno_mode_ok[(int)MAX_MACHINE_MODE][FIRST_PSEUDO_REGISTER];
202
203 /* Current frame information calculated by compute_frame_size. */
204 struct mips_frame_info current_frame_info;
205
206 /* Zero structure to initialize current_frame_info. */
207 struct mips_frame_info zero_frame_info;
208
209 /* Temporary filename used to buffer .text until end of program
210 for -mgpopt. */
211 static char *temp_filename;
212
213 /* List of all MIPS punctuation characters used by print_operand. */
214 char mips_print_operand_punct[256];
215
216 /* Map GCC register number to debugger register number. */
217 int mips_dbx_regno[FIRST_PSEUDO_REGISTER];
218
219 /* Buffer to use to enclose a load/store operation with %{ %} to
220 turn on .set volatile. */
221 static char volatile_buffer[60];
222
223 /* Hardware names for the registers. If -mrnames is used, this
224 will be overwritten with mips_sw_reg_names. */
225
226 char mips_reg_names[][8] =
227 {
228 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
229 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
230 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
231 "$24", "$25", "$26", "$27", "$28", "$sp", "$fp", "$31",
232 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
233 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
234 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
235 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
236 "hi", "lo", "$fcr31"
237 };
238
239 /* Mips software names for the registers, used to overwrite the
240 mips_reg_names array. */
241
242 char mips_sw_reg_names[][8] =
243 {
244 "$0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
245 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
246 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
247 "t8", "t9", "k0", "k1", "gp", "sp", "$fp", "ra",
248 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
249 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
250 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
251 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
252 "hi", "lo", "$fcr31"
253 };
254
255 /* Map hard register number to register class */
256 enum reg_class mips_regno_to_class[] =
257 {
258 GR_REGS, GR_REGS, GR_REGS, GR_REGS,
259 GR_REGS, GR_REGS, GR_REGS, GR_REGS,
260 GR_REGS, GR_REGS, GR_REGS, GR_REGS,
261 GR_REGS, GR_REGS, GR_REGS, GR_REGS,
262 GR_REGS, GR_REGS, GR_REGS, GR_REGS,
263 GR_REGS, GR_REGS, GR_REGS, GR_REGS,
264 GR_REGS, GR_REGS, GR_REGS, GR_REGS,
265 GR_REGS, GR_REGS, GR_REGS, GR_REGS,
266 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
267 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
268 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
269 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
270 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
271 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
272 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
273 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
274 HI_REG, LO_REG, ST_REGS
275 };
276
277 /* Map register constraint character to register class. */
278 enum reg_class mips_char_to_class[256] =
279 {
280 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
281 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
282 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
283 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
284 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
285 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
286 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
287 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
288 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
289 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
290 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
291 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
292 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
293 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
294 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
295 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
296 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
297 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
298 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
299 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
300 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
301 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
302 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
303 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
304 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
305 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
306 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
307 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
308 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
309 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
310 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
311 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
312 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
313 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
314 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
315 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
316 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
317 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
318 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
319 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
320 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
321 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
322 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
323 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
324 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
325 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
326 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
327 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
328 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
329 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
330 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
331 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
332 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
333 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
334 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
335 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
336 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
337 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
338 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
339 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
340 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
341 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
342 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
343 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
344 };
345
346 \f
347 /* Return truth value of whether OP can be used as an operands
348 where a register or 16 bit unsigned integer is needed. */
349
350 int
351 uns_arith_operand (op, mode)
352 rtx op;
353 enum machine_mode mode;
354 {
355 if (GET_CODE (op) == CONST_INT && SMALL_INT_UNSIGNED (op))
356 return TRUE;
357
358 return register_operand (op, mode);
359 }
360
361 /* Return truth value of whether OP can be used as an operands
362 where a 16 bit integer is needed */
363
364 int
365 arith_operand (op, mode)
366 rtx op;
367 enum machine_mode mode;
368 {
369 if (GET_CODE (op) == CONST_INT && SMALL_INT (op))
370 return TRUE;
371
372 return register_operand (op, mode);
373 }
374
375 /* Return truth value of whether OP can be used as an operand in a two
376 address arithmetic insn (such as set 123456,%o4) of mode MODE. */
377
378 int
379 arith32_operand (op, mode)
380 rtx op;
381 enum machine_mode mode;
382 {
383 if (GET_CODE (op) == CONST_INT)
384 return TRUE;
385
386 return register_operand (op, mode);
387 }
388
389 /* Return truth value of whether OP is a integer which fits in 16 bits */
390
391 int
392 small_int (op, mode)
393 rtx op;
394 enum machine_mode mode;
395 {
396 return (GET_CODE (op) == CONST_INT && SMALL_INT (op));
397 }
398
399 /* Return truth value of whether OP is an integer which is too big to
400 be loaded with one instruction. */
401
402 int
403 large_int (op, mode)
404 rtx op;
405 enum machine_mode mode;
406 {
407 HOST_WIDE_INT value;
408
409 if (GET_CODE (op) != CONST_INT)
410 return FALSE;
411
412 value = INTVAL (op);
413 if ((value & ~0x0000ffff) == 0) /* ior reg,$r0,value */
414 return FALSE;
415
416 if (((unsigned long)(value + 32768)) <= 32767) /* subu reg,$r0,value */
417 return FALSE;
418
419 if ((value & 0xffff0000) == value) /* lui reg,value>>16 */
420 return FALSE;
421
422 return TRUE;
423 }
424
425 /* Return truth value of whether OP is a register or the constant 0. */
426
427 int
428 reg_or_0_operand (op, mode)
429 rtx op;
430 enum machine_mode mode;
431 {
432 switch (GET_CODE (op))
433 {
434 default:
435 break;
436
437 case CONST_INT:
438 return (INTVAL (op) == 0);
439
440 case CONST_DOUBLE:
441 if (CONST_DOUBLE_HIGH (op) != 0 || CONST_DOUBLE_LOW (op) != 0)
442 return FALSE;
443
444 return TRUE;
445
446 case REG:
447 case SUBREG:
448 return register_operand (op, mode);
449 }
450
451 return FALSE;
452 }
453
454 /* Return truth value of whether OP is one of the special multiply/divide
455 registers (hi, lo). */
456
457 int
458 md_register_operand (op, mode)
459 rtx op;
460 enum machine_mode mode;
461 {
462 return (GET_MODE_CLASS (mode) == MODE_INT
463 && GET_CODE (op) == REG
464 && MD_REG_P (REGNO (op)));
465 }
466
467 /* Return truth value of whether OP is the FP status register. */
468
469 int
470 fpsw_register_operand (op, mode)
471 rtx op;
472 enum machine_mode mode;
473 {
474 return (GET_CODE (op) == REG && ST_REG_P (REGNO (op)));
475 }
476
477 /* Return truth value if a CONST_DOUBLE is ok to be a legitimate constant. */
478
479 int
480 mips_const_double_ok (op, mode)
481 rtx op;
482 enum machine_mode mode;
483 {
484 if (GET_CODE (op) != CONST_DOUBLE)
485 return FALSE;
486
487 if (mode == DImode)
488 return TRUE;
489
490 if (mode != SFmode && mode != DFmode)
491 return FALSE;
492
493 if (CONST_DOUBLE_HIGH (op) == 0 && CONST_DOUBLE_LOW (op) == 0)
494 return TRUE;
495
496 #if HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT
497 if (TARGET_MIPS_AS) /* gas doesn't like li.d/li.s yet */
498 {
499 union { double d; int i[2]; } u;
500 double d;
501
502 u.i[0] = CONST_DOUBLE_LOW (op);
503 u.i[1] = CONST_DOUBLE_HIGH (op);
504 d = u.d;
505
506 if (d != d)
507 return FALSE; /* NAN */
508
509 if (d < 0.0)
510 d = - d;
511
512 /* Rather than trying to get the accuracy down to the last bit,
513 just use approximate ranges. */
514
515 if (mode == DFmode && d > 1.0e-300 && d < 1.0e300)
516 return TRUE;
517
518 if (mode == SFmode && d > 1.0e-38 && d < 1.0e+38)
519 return TRUE;
520 }
521 #endif
522
523 return FALSE;
524 }
525
526 /* Return truth value if a memory operand fits in a single instruction
527 (ie, register + small offset). */
528
529 int
530 simple_memory_operand (op, mode)
531 rtx op;
532 enum machine_mode mode;
533 {
534 rtx addr, plus0, plus1;
535
536 /* Eliminate non-memory operations */
537 if (GET_CODE (op) != MEM)
538 return FALSE;
539
540 /* dword operations really put out 2 instructions, so eliminate them. */
541 if (GET_MODE_SIZE (GET_MODE (op)) > (HAVE_64BIT_P () ? 8 : 4))
542 return FALSE;
543
544 /* Decode the address now. */
545 addr = XEXP (op, 0);
546 switch (GET_CODE (addr))
547 {
548 default:
549 break;
550
551 case REG:
552 return TRUE;
553
554 case CONST_INT:
555 return SMALL_INT (op);
556
557 case PLUS:
558 plus0 = XEXP (addr, 0);
559 plus1 = XEXP (addr, 1);
560 if (GET_CODE (plus0) == REG
561 && GET_CODE (plus1) == CONST_INT
562 && SMALL_INT (plus1))
563 return TRUE;
564
565 else if (GET_CODE (plus1) == REG
566 && GET_CODE (plus0) == CONST_INT
567 && SMALL_INT (plus0))
568 return TRUE;
569
570 else
571 return FALSE;
572
573 #if 0
574 /* We used to allow small symbol refs here (ie, stuff in .sdata
575 or .sbss), but this causes some bugs in G++. Also, it won't
576 interfere if the MIPS linker rewrites the store instruction
577 because the function is PIC. */
578
579 case LABEL_REF: /* never gp relative */
580 break;
581
582 case CONST:
583 /* If -G 0, we can never have a GP relative memory operation.
584 Also, save some time if not optimizing. */
585 if (mips_section_threshold == 0 || !optimize || !TARGET_GP_OPT)
586 return FALSE;
587
588 {
589 rtx offset = const0_rtx;
590 addr = eliminate_constant_term (addr, &offset);
591 if (GET_CODE (op) != SYMBOL_REF)
592 return FALSE;
593
594 /* let's be paranoid.... */
595 if (INTVAL (offset) < 0 || INTVAL (offset) > 0xffff)
596 return FALSE;
597 }
598 /* fall through */
599
600 case SYMBOL_REF:
601 return SYMBOL_REF_FLAG (addr);
602 #endif
603 }
604
605 return FALSE;
606 }
607
608 /* Return true if the code of this rtx pattern is EQ or NE. */
609
610 int
611 equality_op (op, mode)
612 rtx op;
613 enum machine_mode mode;
614 {
615 if (mode != GET_MODE (op))
616 return FALSE;
617
618 return (classify_op (op, mode) & CLASS_EQUALITY_OP) != 0;
619 }
620
621 /* Return true if the code is a relational operations (EQ, LE, etc.) */
622
623 int
624 cmp_op (op, mode)
625 rtx op;
626 enum machine_mode mode;
627 {
628 if (mode != GET_MODE (op))
629 return FALSE;
630
631 return (classify_op (op, mode) & CLASS_CMP_OP) != 0;
632 }
633
634
635 /* Genrecog does not take the type of match_operator into consideration,
636 and would complain about two patterns being the same if the same
637 function is used, so make it believe they are different. */
638
639 int
640 cmp2_op (op, mode)
641 rtx op;
642 enum machine_mode mode;
643 {
644 if (mode != GET_MODE (op))
645 return FALSE;
646
647 return (classify_op (op, mode) & CLASS_CMP_OP) != 0;
648 }
649
650 /* Return true if the code is an unsigned relational operations (LEU, etc.) */
651
652 int
653 uns_cmp_op (op,mode)
654 rtx op;
655 enum machine_mode mode;
656 {
657 if (mode != GET_MODE (op))
658 return FALSE;
659
660 return (classify_op (op, mode) & CLASS_UNS_CMP_OP) == CLASS_UNS_CMP_OP;
661 }
662
663 /* Return true if the code is a relational operation FP can use. */
664
665 int
666 fcmp_op (op, mode)
667 rtx op;
668 enum machine_mode mode;
669 {
670 if (mode != GET_MODE (op))
671 return FALSE;
672
673 return (classify_op (op, mode) & CLASS_FCMP_OP) != 0;
674 }
675
676
677 /* Return true if the operand is either the PC or a label_ref. */
678
679 int
680 pc_or_label_operand (op, mode)
681 rtx op;
682 enum machine_mode mode;
683 {
684 if (op == pc_rtx)
685 return TRUE;
686
687 if (GET_CODE (op) == LABEL_REF)
688 return TRUE;
689
690 return FALSE;
691 }
692
693 \f
694 /* Return an operand string if the given instruction's delay slot or
695 wrap it in a .set noreorder section. This is for filling delay
696 slots on load type instructions under GAS, which does no reordering
697 on its own. For the MIPS assembler, all we do is update the filled
698 delay slot statistics.
699
700 We assume that operands[0] is the target register that is set.
701
702 In order to check the next insn, most of this functionality is moved
703 to FINAL_PRESCAN_INSN, and we just set the global variables that
704 it needs. */
705
706 char *
707 mips_fill_delay_slot (ret, type, operands, cur_insn)
708 char *ret; /* normal string to return */
709 enum delay_type type; /* type of delay */
710 rtx operands[]; /* operands to use */
711 rtx cur_insn; /* current insn */
712 {
713 register rtx set_reg;
714 register enum machine_mode mode;
715 register rtx next_insn = (cur_insn) ? NEXT_INSN (cur_insn) : (rtx)0;
716 register int num_nops;
717
718 if (type == DELAY_LOAD || type == DELAY_FCMP)
719 num_nops = 1;
720
721 else if (type == DELAY_HILO)
722 num_nops = 2;
723
724 else
725 num_nops = 0;
726
727 /* Make sure that we don't put nop's after labels. */
728 next_insn = NEXT_INSN (cur_insn);
729 while (next_insn != (rtx)0 && GET_CODE (next_insn) == NOTE)
730 next_insn = NEXT_INSN (next_insn);
731
732 dslots_load_total += num_nops;
733 if (TARGET_DEBUG_F_MODE
734 || !optimize
735 || type == DELAY_NONE
736 || operands == (rtx *)0
737 || cur_insn == (rtx)0
738 || next_insn == (rtx)0
739 || GET_CODE (next_insn) == CODE_LABEL
740 || (set_reg = operands[0]) == (rtx)0)
741 {
742 dslots_number_nops = 0;
743 mips_load_reg = (rtx)0;
744 mips_load_reg2 = (rtx)0;
745 mips_load_reg3 = (rtx)0;
746 mips_load_reg4 = (rtx)0;
747 return ret;
748 }
749
750 set_reg = operands[0];
751 if (set_reg == (rtx)0)
752 return ret;
753
754 while (GET_CODE (set_reg) == SUBREG)
755 set_reg = SUBREG_REG (set_reg);
756
757 mode = GET_MODE (set_reg);
758 dslots_number_nops = num_nops;
759 mips_load_reg = set_reg;
760 mips_load_reg2 = (mode == DImode || mode == DFmode)
761 ? gen_rtx (REG, SImode, REGNO (set_reg) + 1)
762 : (rtx)0;
763
764 if (type == DELAY_HILO)
765 {
766 mips_load_reg3 = gen_rtx (REG, SImode, MD_REG_FIRST);
767 mips_load_reg4 = gen_rtx (REG, SImode, MD_REG_FIRST+1);
768 }
769 else
770 {
771 mips_load_reg3 = 0;
772 mips_load_reg4 = 0;
773 }
774
775 if (TARGET_GAS && set_noreorder++ == 0)
776 fputs ("\t.set\tnoreorder\n", asm_out_file);
777
778 return ret;
779 }
780
781 \f
782 /* Determine whether a memory reference takes one (based off of the GP pointer),
783 two (normal), or three (label + reg) instructions, and bump the appropriate
784 counter for -mstats. */
785
786 void
787 mips_count_memory_refs (op, num)
788 rtx op;
789 int num;
790 {
791 int additional = 0;
792 int n_words = 0;
793 rtx addr, plus0, plus1;
794 enum rtx_code code0, code1;
795 int looping;
796
797 if (TARGET_DEBUG_B_MODE)
798 {
799 fprintf (stderr, "\n========== mips_count_memory_refs:\n");
800 debug_rtx (op);
801 }
802
803 /* Skip MEM if passed, otherwise handle movsi of address. */
804 addr = (GET_CODE (op) != MEM) ? op : XEXP (op, 0);
805
806 /* Loop, going through the address RTL */
807 do
808 {
809 looping = FALSE;
810 switch (GET_CODE (addr))
811 {
812 default:
813 break;
814
815 case REG:
816 case CONST_INT:
817 break;
818
819 case PLUS:
820 plus0 = XEXP (addr, 0);
821 plus1 = XEXP (addr, 1);
822 code0 = GET_CODE (plus0);
823 code1 = GET_CODE (plus1);
824
825 if (code0 == REG)
826 {
827 additional++;
828 addr = plus1;
829 looping = TRUE;
830 continue;
831 }
832
833 if (code0 == CONST_INT)
834 {
835 addr = plus1;
836 looping = TRUE;
837 continue;
838 }
839
840 if (code1 == REG)
841 {
842 additional++;
843 addr = plus0;
844 looping = TRUE;
845 continue;
846 }
847
848 if (code1 == CONST_INT)
849 {
850 addr = plus0;
851 looping = TRUE;
852 continue;
853 }
854
855 if (code0 == SYMBOL_REF || code0 == LABEL_REF || code0 == CONST)
856 {
857 addr = plus0;
858 looping = TRUE;
859 continue;
860 }
861
862 if (code1 == SYMBOL_REF || code1 == LABEL_REF || code1 == CONST)
863 {
864 addr = plus1;
865 looping = TRUE;
866 continue;
867 }
868
869 break;
870
871 case LABEL_REF:
872 n_words = 2; /* always 2 words */
873 break;
874
875 case CONST:
876 addr = XEXP (addr, 0);
877 looping = TRUE;
878 continue;
879
880 case SYMBOL_REF:
881 n_words = SYMBOL_REF_FLAG (addr) ? 1 : 2;
882 break;
883 }
884 }
885 while (looping);
886
887 if (n_words == 0)
888 return;
889
890 n_words += additional;
891 if (n_words > 3)
892 n_words = 3;
893
894 num_refs[n_words-1] += num;
895 }
896
897 \f
898 /* Return the appropriate instructions to move one operand to another. */
899
900 char *
901 mips_move_1word (operands, insn, unsignedp)
902 rtx operands[];
903 rtx insn;
904 int unsignedp;
905 {
906 char *ret = 0;
907 rtx op0 = operands[0];
908 rtx op1 = operands[1];
909 enum rtx_code code0 = GET_CODE (op0);
910 enum rtx_code code1 = GET_CODE (op1);
911 enum machine_mode mode = GET_MODE (op0);
912 int subreg_word0 = 0;
913 int subreg_word1 = 0;
914 enum delay_type delay = DELAY_NONE;
915
916 while (code0 == SUBREG)
917 {
918 subreg_word0 += SUBREG_WORD (op0);
919 op0 = SUBREG_REG (op0);
920 code0 = GET_CODE (op0);
921 }
922
923 while (code1 == SUBREG)
924 {
925 subreg_word1 += SUBREG_WORD (op1);
926 op1 = SUBREG_REG (op1);
927 code1 = GET_CODE (op1);
928 }
929
930 if (code0 == REG)
931 {
932 int regno0 = REGNO (op0) + subreg_word0;
933
934 if (code1 == REG)
935 {
936 int regno1 = REGNO (op1) + subreg_word1;
937
938 /* Just in case, don't do anything for assigning a register
939 to itself, unless we are filling a delay slot. */
940 if (regno0 == regno1 && set_nomacro == 0)
941 ret = "";
942
943 else if (GP_REG_P (regno0))
944 {
945 if (GP_REG_P (regno1))
946 ret = "move\t%0,%1";
947
948 else if (MD_REG_P (regno1))
949 {
950 delay = DELAY_HILO;
951 ret = "mf%1\t%0";
952 }
953
954 else
955 {
956 delay = DELAY_LOAD;
957 if (FP_REG_P (regno1))
958 ret = "mfc1\t%0,%1";
959
960 else if (regno1 == FPSW_REGNUM)
961 ret = "cfc1\t%0,$31";
962 }
963 }
964
965 else if (FP_REG_P (regno0))
966 {
967 if (GP_REG_P (regno1))
968 {
969 delay = DELAY_LOAD;
970 ret = "mtc1\t%1,%0";
971 }
972
973 if (FP_REG_P (regno1))
974 ret = "mov.s\t%0,%1";
975 }
976
977 else if (MD_REG_P (regno0))
978 {
979 if (GP_REG_P (regno1))
980 {
981 delay = DELAY_HILO;
982 ret = "mt%0\t%1";
983 }
984 }
985
986 else if (regno0 == FPSW_REGNUM)
987 {
988 if (GP_REG_P (regno1))
989 {
990 delay = DELAY_LOAD;
991 ret = "ctc1\t%0,$31";
992 }
993 }
994 }
995
996 else if (code1 == MEM)
997 {
998 delay = DELAY_LOAD;
999
1000 if (TARGET_STATS)
1001 mips_count_memory_refs (op1, 1);
1002
1003 if (GP_REG_P (regno0))
1004 {
1005 /* For loads, use the mode of the memory item, instead of the
1006 target, so zero/sign extend can use this code as well. */
1007 switch (GET_MODE (op1))
1008 {
1009 default: break;
1010 case SFmode: ret = "lw\t%0,%1"; break;
1011 case SImode: ret = "lw\t%0,%1"; break;
1012 case HImode: ret = (unsignedp) ? "lhu\t%0,%1" : "lh\t%0,%1"; break;
1013 case QImode: ret = (unsignedp) ? "lbu\t%0,%1" : "lb\t%0,%1"; break;
1014 }
1015 }
1016
1017 else if (FP_REG_P (regno0) && (mode == SImode || mode == SFmode))
1018 ret = "l.s\t%0,%1";
1019
1020 if (ret != (char *)0 && MEM_VOLATILE_P (op1))
1021 {
1022 int i = strlen (ret);
1023 if (i > sizeof (volatile_buffer) - sizeof ("%{%}"))
1024 abort ();
1025
1026 sprintf (volatile_buffer, "%%{%s%%}", ret);
1027 ret = volatile_buffer;
1028 }
1029 }
1030
1031 else if (code1 == CONST_INT)
1032 {
1033 if (INTVAL (op1) == 0)
1034 {
1035 if (GP_REG_P (regno0))
1036 ret = "move\t%0,%z1";
1037
1038 else if (FP_REG_P (regno0))
1039 {
1040 delay = DELAY_LOAD;
1041 ret = "mtc1\t%z1,%0";
1042 }
1043 }
1044
1045 else if (GP_REG_P (regno0))
1046 ret = (INTVAL (op1) < 0) ? "li\t%0,%1\t\t\t# %X1" : "li\t%0,%X1\t\t# %1";
1047 }
1048
1049 else if (code1 == CONST_DOUBLE && mode == SFmode)
1050 {
1051 if (CONST_DOUBLE_HIGH (op1) == 0 && CONST_DOUBLE_LOW (op1) == 0)
1052 {
1053 if (GP_REG_P (regno0))
1054 ret = "move\t%0,%.";
1055
1056 else if (FP_REG_P (regno0))
1057 {
1058 delay = DELAY_LOAD;
1059 ret = "mtc1\t%.,%0";
1060 }
1061 }
1062
1063 else
1064 {
1065 delay = DELAY_LOAD;
1066 ret = "li.s\t%0,%1";
1067 }
1068 }
1069
1070 else if (code1 == LABEL_REF)
1071 {
1072 if (TARGET_STATS)
1073 mips_count_memory_refs (op1, 1);
1074
1075 ret = "la\t%0,%a1";
1076 }
1077
1078 else if (code1 == SYMBOL_REF || code1 == CONST)
1079 {
1080 if (HALF_PIC_P () && CONSTANT_P (op1) && HALF_PIC_ADDRESS_P (op1))
1081 {
1082 rtx offset = const0_rtx;
1083
1084 if (GET_CODE (op1) == CONST)
1085 op1 = eliminate_constant_term (XEXP (op1, 0), &offset);
1086
1087 if (GET_CODE (op1) == SYMBOL_REF)
1088 {
1089 operands[2] = HALF_PIC_PTR (op1);
1090
1091 if (TARGET_STATS)
1092 mips_count_memory_refs (operands[2], 1);
1093
1094 if (INTVAL (offset) == 0)
1095 {
1096 delay = DELAY_LOAD;
1097 ret = "lw\t%0,%2";
1098 }
1099 else
1100 {
1101 dslots_load_total++;
1102 operands[3] = offset;
1103 ret = (SMALL_INT (offset))
1104 ? "lw\t%0,%2%#\n\tadd\t%0,%0,%3"
1105 : "lw\t%0,%2%#\n\t%[li\t%@,%3\n\tadd\t%0,%0,%@%]";
1106 }
1107 }
1108 }
1109 else
1110 {
1111 if (TARGET_STATS)
1112 mips_count_memory_refs (op1, 1);
1113
1114 ret = "la\t%0,%a1";
1115 }
1116 }
1117
1118 else if (code1 == PLUS)
1119 {
1120 rtx add_op0 = XEXP (op1, 0);
1121 rtx add_op1 = XEXP (op1, 1);
1122
1123 if (GET_CODE (XEXP (op1, 1)) == REG && GET_CODE (XEXP (op1, 0)) == CONST_INT)
1124 {
1125 add_op0 = XEXP (op1, 1); /* reverse operands */
1126 add_op1 = XEXP (op1, 0);
1127 }
1128
1129 operands[2] = add_op0;
1130 operands[3] = add_op1;
1131 ret = "add%:\t%0,%2,%3";
1132 }
1133 }
1134
1135 else if (code0 == MEM)
1136 {
1137 if (TARGET_STATS)
1138 mips_count_memory_refs (op0, 1);
1139
1140 if (code1 == REG)
1141 {
1142 int regno1 = REGNO (op1) + subreg_word1;
1143
1144 if (GP_REG_P (regno1))
1145 {
1146 switch (mode)
1147 {
1148 default: break;
1149 case SFmode: ret = "sw\t%1,%0"; break;
1150 case SImode: ret = "sw\t%1,%0"; break;
1151 case HImode: ret = "sh\t%1,%0"; break;
1152 case QImode: ret = "sb\t%1,%0"; break;
1153 }
1154 }
1155
1156 else if (FP_REG_P (regno1) && (mode == SImode || mode == SFmode))
1157 ret = "s.s\t%1,%0";
1158 }
1159
1160 else if (code1 == CONST_INT && INTVAL (op1) == 0)
1161 {
1162 switch (mode)
1163 {
1164 default: break;
1165 case SFmode: ret = "sw\t%z1,%0"; break;
1166 case SImode: ret = "sw\t%z1,%0"; break;
1167 case HImode: ret = "sh\t%z1,%0"; break;
1168 case QImode: ret = "sb\t%z1,%0"; break;
1169 }
1170 }
1171
1172 else if (code1 == CONST_DOUBLE && CONST_DOUBLE_HIGH (op1) == 0 && CONST_DOUBLE_LOW (op1) == 0)
1173 {
1174 switch (mode)
1175 {
1176 default: break;
1177 case SFmode: ret = "sw\t%.,%0"; break;
1178 case SImode: ret = "sw\t%.,%0"; break;
1179 case HImode: ret = "sh\t%.,%0"; break;
1180 case QImode: ret = "sb\t%.,%0"; break;
1181 }
1182 }
1183
1184 if (ret != (char *)0 && MEM_VOLATILE_P (op0))
1185 {
1186 int i = strlen (ret);
1187 if (i > sizeof (volatile_buffer) - sizeof ("%{%}"))
1188 abort ();
1189
1190 sprintf (volatile_buffer, "%%{%s%%}", ret);
1191 ret = volatile_buffer;
1192 }
1193 }
1194
1195 if (ret == (char *)0)
1196 {
1197 abort_with_insn (insn, "Bad move");
1198 return 0;
1199 }
1200
1201 if (delay != DELAY_NONE)
1202 return mips_fill_delay_slot (ret, delay, operands, insn);
1203
1204 return ret;
1205 }
1206
1207 \f
1208 /* Return the appropriate instructions to move 2 words */
1209
1210 char *
1211 mips_move_2words (operands, insn)
1212 rtx operands[];
1213 rtx insn;
1214 {
1215 char *ret = 0;
1216 rtx op0 = operands[0];
1217 rtx op1 = operands[1];
1218 enum rtx_code code0 = GET_CODE (operands[0]);
1219 enum rtx_code code1 = GET_CODE (operands[1]);
1220 int subreg_word0 = 0;
1221 int subreg_word1 = 0;
1222 enum delay_type delay = DELAY_NONE;
1223
1224 while (code0 == SUBREG)
1225 {
1226 subreg_word0 += SUBREG_WORD (op0);
1227 op0 = SUBREG_REG (op0);
1228 code0 = GET_CODE (op0);
1229 }
1230
1231 while (code1 == SUBREG)
1232 {
1233 subreg_word1 += SUBREG_WORD (op1);
1234 op1 = SUBREG_REG (op1);
1235 code1 = GET_CODE (op1);
1236 }
1237
1238 if (code0 == REG)
1239 {
1240 int regno0 = REGNO (op0) + subreg_word0;
1241
1242 if (code1 == REG)
1243 {
1244 int regno1 = REGNO (op1) + subreg_word1;
1245
1246 /* Just in case, don't do anything for assigning a register
1247 to itself, unless we are filling a delay slot. */
1248 if (regno0 == regno1 && set_nomacro == 0)
1249 ret = "";
1250
1251 else if (FP_REG_P (regno0))
1252 {
1253 if (FP_REG_P (regno1))
1254 ret = "mov.d\t%0,%1";
1255
1256 else
1257 {
1258 delay = DELAY_LOAD;
1259 ret = (TARGET_FLOAT64)
1260 ? "dmtc1\t%1,%0"
1261 : "mtc1\t%L1,%0\n\tmtc1\t%M1,%D0";
1262 }
1263 }
1264
1265 else if (FP_REG_P (regno1))
1266 {
1267 delay = DELAY_LOAD;
1268 ret = (TARGET_FLOAT64)
1269 ? "dmfc1\t%0,%1"
1270 : "mfc1\t%L0,%1\n\tmfc1\t%M0,%D1";
1271 }
1272
1273 else if (MD_REG_P (regno0) && GP_REG_P (regno1))
1274 {
1275 delay = DELAY_HILO;
1276 ret = "mthi\t%M1\n\tmtlo\t%L1";
1277 }
1278
1279 else if (GP_REG_P (regno0) && MD_REG_P (regno1))
1280 {
1281 delay = DELAY_HILO;
1282 ret = "mfhi\t%M0\n\tmflo\t%L0";
1283 }
1284
1285 else if (regno0 != (regno1+1))
1286 ret = "move\t%0,%1\n\tmove\t%D0,%D1";
1287
1288 else
1289 ret = "move\t%D0,%D1\n\tmove\t%0,%1";
1290 }
1291
1292 else if (code1 == CONST_DOUBLE)
1293 {
1294 if (CONST_DOUBLE_HIGH (op1) != 0 || CONST_DOUBLE_LOW (op1) != 0)
1295 {
1296 if (GET_MODE (op1) == DFmode)
1297 {
1298 delay = DELAY_LOAD;
1299 ret = "li.d\t%0,%1";
1300 }
1301
1302 else
1303 {
1304 operands[2] = GEN_INT (CONST_DOUBLE_LOW (op1));
1305 operands[3] = GEN_INT (CONST_DOUBLE_HIGH (op1));
1306 ret = "li\t%M0,%3\n\tli\t%L0,%2";
1307 }
1308 }
1309
1310 else
1311 {
1312 if (GP_REG_P (regno0))
1313 ret = "move\t%0,%.\n\tmove\t%D0,%.";
1314
1315 else if (FP_REG_P (regno0))
1316 {
1317 delay = DELAY_LOAD;
1318 ret = (TARGET_FLOAT64)
1319 ? "dmtc1\t%.,%0"
1320 : "mtc1\t%.,%0\n\tmtc1\t%.,%D0";
1321 }
1322 }
1323 }
1324
1325 else if (code1 == CONST_INT && INTVAL (op1) == 0)
1326 {
1327 if (GP_REG_P (regno0))
1328 ret = "move\t%0,%.\n\tmove\t%D0,%.";
1329
1330 else if (FP_REG_P (regno0))
1331 {
1332 delay = DELAY_LOAD;
1333 ret = (TARGET_FLOAT64)
1334 ? "dmtc1\t%.,%0"
1335 : "mtc1\t%.,%0\n\tmtc1\t%.,%D0";
1336 }
1337 }
1338
1339 else if (code1 == CONST_INT && GET_MODE (op0) == DImode && GP_REG_P (regno0))
1340 {
1341 operands[2] = GEN_INT (INTVAL (operands[1]) >= 0 ? 0 : -1);
1342 ret = "li\t%M0,%2\n\tli\t%L0,%1";
1343 }
1344
1345 else if (code1 == MEM)
1346 {
1347 delay = DELAY_LOAD;
1348
1349 if (TARGET_STATS)
1350 mips_count_memory_refs (op1, 2);
1351
1352 if (FP_REG_P (regno0))
1353 ret = "l.d\t%0,%1";
1354
1355 else if (offsettable_address_p (1, DFmode, XEXP (op1, 0)))
1356 {
1357 operands[2] = adj_offsettable_operand (op1, 4);
1358 if (reg_mentioned_p (op0, op1))
1359 ret = "lw\t%D0,%2\n\tlw\t%0,%1";
1360 else
1361 ret = "lw\t%0,%1\n\tlw\t%D0,%2";
1362 }
1363
1364 if (ret != (char *)0 && MEM_VOLATILE_P (op1))
1365 {
1366 int i = strlen (ret);
1367 if (i > sizeof (volatile_buffer) - sizeof ("%{%}"))
1368 abort ();
1369
1370 sprintf (volatile_buffer, "%%{%s%%}", ret);
1371 ret = volatile_buffer;
1372 }
1373 }
1374 }
1375
1376 else if (code0 == MEM)
1377 {
1378 if (code1 == REG)
1379 {
1380 int regno1 = REGNO (op1) + subreg_word1;
1381
1382 if (FP_REG_P (regno1))
1383 ret = "s.d\t%1,%0";
1384
1385 else if (offsettable_address_p (1, DFmode, XEXP (op0, 0)))
1386 {
1387 operands[2] = adj_offsettable_operand (op0, 4);
1388 ret = "sw\t%1,%0\n\tsw\t%D1,%2";
1389 }
1390 }
1391
1392 else if (code1 == CONST_DOUBLE
1393 && CONST_DOUBLE_HIGH (op1) == 0
1394 && CONST_DOUBLE_LOW (op1) == 0
1395 && offsettable_address_p (1, DFmode, XEXP (op0, 0)))
1396 {
1397 if (TARGET_FLOAT64)
1398 ret = "sd\t%.,%0";
1399 else
1400 {
1401 operands[2] = adj_offsettable_operand (op0, 4);
1402 ret = "sw\t%.,%0\n\tsw\t%.,%2";
1403 }
1404 }
1405
1406 if (TARGET_STATS)
1407 mips_count_memory_refs (op0, 2);
1408
1409 if (ret != (char *)0 && MEM_VOLATILE_P (op0))
1410 {
1411 int i = strlen (ret);
1412 if (i > sizeof (volatile_buffer) - sizeof ("%{%}"))
1413 abort ();
1414
1415 sprintf (volatile_buffer, "%%{%s%%}", ret);
1416 ret = volatile_buffer;
1417 }
1418 }
1419
1420 if (ret == (char *)0)
1421 {
1422 abort_with_insn (insn, "Bad move");
1423 return 0;
1424 }
1425
1426 if (delay != DELAY_NONE)
1427 return mips_fill_delay_slot (ret, delay, operands, insn);
1428
1429 return ret;
1430 }
1431
1432 \f
1433 /* Provide the costs of an addressing mode that contains ADDR.
1434 If ADDR is not a valid address, its cost is irrelevant. */
1435
1436 int
1437 mips_address_cost (addr)
1438 rtx addr;
1439 {
1440 switch (GET_CODE (addr))
1441 {
1442 default:
1443 break;
1444
1445 case LO_SUM:
1446 case HIGH:
1447 return 1;
1448
1449 case LABEL_REF:
1450 return 2;
1451
1452 case CONST:
1453 {
1454 rtx offset = const0_rtx;
1455 addr = eliminate_constant_term (addr, &offset);
1456 if (GET_CODE (addr) == LABEL_REF)
1457 return 2;
1458
1459 if (GET_CODE (addr) != SYMBOL_REF)
1460 return 4;
1461
1462 if (INTVAL (offset) < -32768 || INTVAL (offset) > 32767)
1463 return 2;
1464 }
1465 /* fall through */
1466
1467 case SYMBOL_REF:
1468 return SYMBOL_REF_FLAG (addr) ? 1 : 2;
1469
1470 case PLUS:
1471 {
1472 register rtx plus0 = XEXP (addr, 0);
1473 register rtx plus1 = XEXP (addr, 1);
1474
1475 if (GET_CODE (plus0) != REG && GET_CODE (plus1) == REG)
1476 {
1477 plus0 = XEXP (addr, 1);
1478 plus1 = XEXP (addr, 0);
1479 }
1480
1481 if (GET_CODE (plus0) != REG)
1482 break;
1483
1484 switch (GET_CODE (plus1))
1485 {
1486 default:
1487 break;
1488
1489 case CONST_INT:
1490 {
1491 int value = INTVAL (plus1);
1492 return (value < -32768 || value > 32767) ? 2 : 1;
1493 }
1494
1495 case CONST:
1496 case SYMBOL_REF:
1497 case LABEL_REF:
1498 case HIGH:
1499 case LO_SUM:
1500 return mips_address_cost (plus1) + 1;
1501 }
1502 }
1503 }
1504
1505 return 4;
1506 }
1507
1508 \f
1509 /* Make normal rtx_code into something we can index from an array */
1510
1511 static enum internal_test
1512 map_test_to_internal_test (test_code)
1513 enum rtx_code test_code;
1514 {
1515 enum internal_test test = ITEST_MAX;
1516
1517 switch (test_code)
1518 {
1519 default: break;
1520 case EQ: test = ITEST_EQ; break;
1521 case NE: test = ITEST_NE; break;
1522 case GT: test = ITEST_GT; break;
1523 case GE: test = ITEST_GE; break;
1524 case LT: test = ITEST_LT; break;
1525 case LE: test = ITEST_LE; break;
1526 case GTU: test = ITEST_GTU; break;
1527 case GEU: test = ITEST_GEU; break;
1528 case LTU: test = ITEST_LTU; break;
1529 case LEU: test = ITEST_LEU; break;
1530 }
1531
1532 return test;
1533 }
1534
1535 \f
1536 /* Generate the code to compare two integer values. The return value is:
1537 (reg:SI xx) The pseudo register the comparison is in
1538 (rtx)0 No register, generate a simple branch. */
1539
1540 rtx
1541 gen_int_relational (test_code, result, cmp0, cmp1, p_invert)
1542 enum rtx_code test_code; /* relational test (EQ, etc) */
1543 rtx result; /* result to store comp. or 0 if branch */
1544 rtx cmp0; /* first operand to compare */
1545 rtx cmp1; /* second operand to compare */
1546 int *p_invert; /* NULL or ptr to hold whether branch needs */
1547 /* to reverse its test */
1548 {
1549 struct cmp_info {
1550 enum rtx_code test_code; /* code to use in instruction (LT vs. LTU) */
1551 int const_low; /* low bound of constant we can accept */
1552 int const_high; /* high bound of constant we can accept */
1553 int const_add; /* constant to add (convert LE -> LT) */
1554 int reverse_regs; /* reverse registers in test */
1555 int invert_const; /* != 0 if invert value if cmp1 is constant */
1556 int invert_reg; /* != 0 if invert value if cmp1 is register */
1557 int unsignedp; /* != 0 for unsigned comparisons. */
1558 };
1559
1560 static struct cmp_info info[ (int)ITEST_MAX ] = {
1561
1562 { XOR, 0, 65535, 0, 0, 0, 0, 0 }, /* EQ */
1563 { XOR, 0, 65535, 0, 0, 1, 1, 0 }, /* NE */
1564 { LT, -32769, 32766, 1, 1, 1, 0, 0 }, /* GT */
1565 { LT, -32768, 32767, 0, 0, 1, 1, 0 }, /* GE */
1566 { LT, -32768, 32767, 0, 0, 0, 0, 0 }, /* LT */
1567 { LT, -32769, 32766, 1, 1, 0, 1, 0 }, /* LE */
1568 { LTU, -32769, 32766, 1, 1, 1, 0, 1 }, /* GTU */
1569 { LTU, -32768, 32767, 0, 0, 1, 1, 1 }, /* GEU */
1570 { LTU, -32768, 32767, 0, 0, 0, 0, 1 }, /* LTU */
1571 { LTU, -32769, 32766, 1, 1, 0, 1, 1 }, /* LEU */
1572 };
1573
1574 enum internal_test test;
1575 struct cmp_info *p_info;
1576 int branch_p;
1577 int eqne_p;
1578 int invert;
1579 rtx reg;
1580 rtx reg2;
1581
1582 test = map_test_to_internal_test (test_code);
1583 if (test == ITEST_MAX)
1584 abort ();
1585
1586 p_info = &info[ (int)test ];
1587 eqne_p = (p_info->test_code == XOR);
1588
1589 /* Eliminate simple branches */
1590 branch_p = (result == (rtx)0);
1591 if (branch_p)
1592 {
1593 if (GET_CODE (cmp0) == REG || GET_CODE (cmp0) == SUBREG)
1594 {
1595 /* Comparisons against zero are simple branches */
1596 if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0)
1597 return (rtx)0;
1598
1599 /* Test for beq/bne. */
1600 if (eqne_p)
1601 return (rtx)0;
1602 }
1603
1604 /* allocate a pseudo to calculate the value in. */
1605 result = gen_reg_rtx (SImode);
1606 }
1607
1608 /* Make sure we can handle any constants given to us. */
1609 if (GET_CODE (cmp0) == CONST_INT)
1610 cmp0 = force_reg (SImode, cmp0);
1611
1612 if (GET_CODE (cmp1) == CONST_INT)
1613 {
1614 HOST_WIDE_INT value = INTVAL (cmp1);
1615 if (value < p_info->const_low || value > p_info->const_high)
1616 cmp1 = force_reg (SImode, cmp1);
1617 }
1618
1619 /* See if we need to invert the result. */
1620 invert = (GET_CODE (cmp1) == CONST_INT)
1621 ? p_info->invert_const
1622 : p_info->invert_reg;
1623
1624 if (p_invert != (int *)0)
1625 {
1626 *p_invert = invert;
1627 invert = FALSE;
1628 }
1629
1630 /* Comparison to constants, may involve adding 1 to change a LT into LE.
1631 Comparison between two registers, may involve switching operands. */
1632 if (GET_CODE (cmp1) == CONST_INT)
1633 {
1634 if (p_info->const_add != 0)
1635 {
1636 HOST_WIDE_INT new = INTVAL (cmp1) + p_info->const_add;
1637 /* If modification of cmp1 caused overflow,
1638 we would get the wrong answer if we follow the usual path;
1639 thus, x > 0xffffffffu would turn into x > 0u. */
1640 if ((p_info->unsignedp
1641 ? (unsigned HOST_WIDE_INT) new > INTVAL (cmp1)
1642 : new > INTVAL (cmp1))
1643 != (p_info->const_add > 0))
1644 /* 1 is the right value in the LE and LEU case.
1645 In the GT and GTU case, *p_invert is already set,
1646 so this is effectively 0. */
1647 return force_reg (SImode, const1_rtx);
1648 else
1649 cmp1 = GEN_INT (new);
1650 }
1651 }
1652 else if (p_info->reverse_regs)
1653 {
1654 rtx temp = cmp0;
1655 cmp0 = cmp1;
1656 cmp1 = temp;
1657 }
1658
1659 if (test == ITEST_NE && GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0)
1660 reg = cmp0;
1661 else
1662 {
1663 reg = (invert || eqne_p) ? gen_reg_rtx (SImode) : result;
1664 emit_move_insn (reg, gen_rtx (p_info->test_code, SImode, cmp0, cmp1));
1665 }
1666
1667 if (test == ITEST_NE)
1668 {
1669 emit_move_insn (result, gen_rtx (GTU, SImode, reg, const0_rtx));
1670 invert = FALSE;
1671 }
1672
1673 else if (test == ITEST_EQ)
1674 {
1675 reg2 = (invert) ? gen_reg_rtx (SImode) : result;
1676 emit_move_insn (reg2, gen_rtx (LTU, SImode, reg, const1_rtx));
1677 reg = reg2;
1678 }
1679
1680 if (invert)
1681 emit_move_insn (result, gen_rtx (XOR, SImode, reg, const1_rtx));
1682
1683 return result;
1684 }
1685
1686 \f
1687 /* Emit the common code for doing conditional branches.
1688 operand[0] is the label to jump to.
1689 The comparison operands are saved away by cmp{si,sf,df}. */
1690
1691 void
1692 gen_conditional_branch (operands, test_code)
1693 rtx operands[];
1694 enum rtx_code test_code;
1695 {
1696 static enum machine_mode mode_map[(int)CMP_MAX][(int)ITEST_MAX] = {
1697 { /* CMP_SI */
1698 SImode, /* eq */
1699 SImode, /* ne */
1700 SImode, /* gt */
1701 SImode, /* ge */
1702 SImode, /* lt */
1703 SImode, /* le */
1704 SImode, /* gtu */
1705 SImode, /* geu */
1706 SImode, /* ltu */
1707 SImode, /* leu */
1708 },
1709 { /* CMP_SF */
1710 CC_FPmode, /* eq */
1711 CC_REV_FPmode, /* ne */
1712 CC_FPmode, /* gt */
1713 CC_FPmode, /* ge */
1714 CC_FPmode, /* lt */
1715 CC_FPmode, /* le */
1716 VOIDmode, /* gtu */
1717 VOIDmode, /* geu */
1718 VOIDmode, /* ltu */
1719 VOIDmode, /* leu */
1720 },
1721 { /* CMP_DF */
1722 CC_FPmode, /* eq */
1723 CC_REV_FPmode, /* ne */
1724 CC_FPmode, /* gt */
1725 CC_FPmode, /* ge */
1726 CC_FPmode, /* lt */
1727 CC_FPmode, /* le */
1728 VOIDmode, /* gtu */
1729 VOIDmode, /* geu */
1730 VOIDmode, /* ltu */
1731 VOIDmode, /* leu */
1732 },
1733 };
1734
1735 enum machine_mode mode;
1736 enum cmp_type type = branch_type;
1737 rtx cmp0 = branch_cmp[0];
1738 rtx cmp1 = branch_cmp[1];
1739 rtx label1 = gen_rtx (LABEL_REF, VOIDmode, operands[0]);
1740 rtx label2 = pc_rtx;
1741 rtx reg = (rtx)0;
1742 int invert = 0;
1743 enum internal_test test = map_test_to_internal_test (test_code);
1744
1745 if (test == ITEST_MAX)
1746 {
1747 mode = SImode;
1748 goto fail;
1749 }
1750
1751 /* Get the machine mode to use (CCmode, CC_EQmode, CC_FPmode, or CC_REV_FPmode). */
1752 mode = mode_map[(int)type][(int)test];
1753 if (mode == VOIDmode)
1754 goto fail;
1755
1756 switch (branch_type)
1757 {
1758 default:
1759 goto fail;
1760
1761 case CMP_SI:
1762 reg = gen_int_relational (test_code, (rtx)0, cmp0, cmp1, &invert);
1763 if (reg != (rtx)0)
1764 {
1765 cmp0 = reg;
1766 cmp1 = const0_rtx;
1767 test_code = NE;
1768 }
1769
1770 /* Make sure not non-zero constant if ==/!= */
1771 else if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) != 0)
1772 cmp1 = force_reg (SImode, cmp1);
1773
1774 break;
1775
1776 case CMP_DF:
1777 case CMP_SF:
1778 {
1779 rtx reg = gen_rtx (REG, mode, FPSW_REGNUM);
1780 emit_insn (gen_rtx (SET, VOIDmode, reg, gen_rtx (test_code, mode, cmp0, cmp1)));
1781 cmp0 = reg;
1782 cmp1 = const0_rtx;
1783 test_code = NE;
1784 }
1785 break;
1786 }
1787
1788 /* Generate the jump */
1789 if (invert)
1790 {
1791 label2 = label1;
1792 label1 = pc_rtx;
1793 }
1794
1795 emit_jump_insn (gen_rtx (SET, VOIDmode,
1796 pc_rtx,
1797 gen_rtx (IF_THEN_ELSE, VOIDmode,
1798 gen_rtx (test_code, mode, cmp0, cmp1),
1799 label1,
1800 label2)));
1801
1802 return;
1803
1804 fail:
1805 abort_with_insn (gen_rtx (test_code, mode, cmp0, cmp1), "bad test");
1806 }
1807
1808 \f
1809 #define UNITS_PER_SHORT (SHORT_TYPE_SIZE / BITS_PER_UNIT)
1810
1811 /* Internal code to generate the load and store of one word/short/byte.
1812 The load is emitted directly, and the store insn is returned. */
1813
1814 #if 0
1815 static rtx
1816 block_move_load_store (dest_reg, src_reg, p_bytes, p_offset, align, orig_src)
1817 rtx src_reg; /* register holding source memory address */
1818 rtx dest_reg; /* register holding dest. memory address */
1819 int *p_bytes; /* pointer to # bytes remaining */
1820 int *p_offset; /* pointer to current offset */
1821 int align; /* alignment */
1822 rtx orig_src; /* original source for making a reg note */
1823 {
1824 int bytes; /* # bytes remaining */
1825 int offset; /* offset to use */
1826 int size; /* size in bytes of load/store */
1827 enum machine_mode mode; /* mode to use for load/store */
1828 rtx reg; /* temporary register */
1829 rtx src_addr; /* source address */
1830 rtx dest_addr; /* destination address */
1831 rtx insn; /* insn of the load */
1832 rtx orig_src_addr; /* original source address */
1833 rtx (*load_func)(); /* function to generate load insn */
1834 rtx (*store_func)(); /* function to generate destination insn */
1835
1836 bytes = *p_bytes;
1837 if (bytes <= 0 || align <= 0)
1838 abort ();
1839
1840 if (bytes >= UNITS_PER_WORD && align >= UNITS_PER_WORD)
1841 {
1842 mode = SImode;
1843 size = UNITS_PER_WORD;
1844 load_func = gen_movsi;
1845 store_func = gen_movsi;
1846 }
1847
1848 #if 0
1849 /* Don't generate unligned moves here, rather defer those to the
1850 general movestrsi_internal pattern. */
1851 else if (bytes >= UNITS_PER_WORD)
1852 {
1853 mode = SImode;
1854 size = UNITS_PER_WORD;
1855 load_func = gen_movsi_ulw;
1856 store_func = gen_movsi_usw;
1857 }
1858 #endif
1859
1860 else if (bytes >= UNITS_PER_SHORT && align >= UNITS_PER_SHORT)
1861 {
1862 mode = HImode;
1863 size = UNITS_PER_SHORT;
1864 load_func = gen_movhi;
1865 store_func = gen_movhi;
1866 }
1867
1868 else
1869 {
1870 mode = QImode;
1871 size = 1;
1872 load_func = gen_movqi;
1873 store_func = gen_movqi;
1874 }
1875
1876 offset = *p_offset;
1877 *p_offset = offset + size;
1878 *p_bytes = bytes - size;
1879
1880 if (offset == 0)
1881 {
1882 src_addr = src_reg;
1883 dest_addr = dest_reg;
1884 }
1885 else
1886 {
1887 src_addr = gen_rtx (PLUS, Pmode, src_reg, GEN_INT (offset));
1888 dest_addr = gen_rtx (PLUS, Pmode, dest_reg, GEN_INT (offset));
1889 }
1890
1891 reg = gen_reg_rtx (mode);
1892 insn = emit_insn ((*load_func) (reg, gen_rtx (MEM, mode, src_addr)));
1893 orig_src_addr = XEXP (orig_src, 0);
1894 if (CONSTANT_P (orig_src_addr))
1895 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUIV,
1896 plus_constant (orig_src_addr, offset),
1897 REG_NOTES (insn));
1898
1899 return (*store_func) (gen_rtx (MEM, mode, dest_addr), reg);
1900 }
1901 #endif
1902
1903 \f
1904 /* Write a series of loads/stores to move some bytes. Generate load/stores as follows:
1905
1906 load 1
1907 load 2
1908 load 3
1909 store 1
1910 load 4
1911 store 2
1912 load 5
1913 store 3
1914 ...
1915
1916 This way, no NOP's are needed, except at the end, and only
1917 two temp registers are needed. Two delay slots are used
1918 in deference to the R4000. */
1919
1920 #if 0
1921 static void
1922 block_move_sequence (dest_reg, src_reg, bytes, align, orig_src)
1923 rtx dest_reg; /* register holding destination address */
1924 rtx src_reg; /* register holding source address */
1925 int bytes; /* # bytes to move */
1926 int align; /* max alignment to assume */
1927 rtx orig_src; /* original source for making a reg note */
1928 {
1929 int offset = 0;
1930 rtx prev2_store = (rtx)0;
1931 rtx prev_store = (rtx)0;
1932 rtx cur_store = (rtx)0;
1933
1934 while (bytes > 0)
1935 {
1936 /* Is there a store to do? */
1937 if (prev2_store)
1938 emit_insn (prev2_store);
1939
1940 prev2_store = prev_store;
1941 prev_store = cur_store;
1942 cur_store = block_move_load_store (dest_reg, src_reg,
1943 &bytes, &offset,
1944 align, orig_src);
1945 }
1946
1947 /* Finish up last three stores. */
1948 if (prev2_store)
1949 emit_insn (prev2_store);
1950
1951 if (prev_store)
1952 emit_insn (prev_store);
1953
1954 if (cur_store)
1955 emit_insn (cur_store);
1956 }
1957 #endif
1958
1959 \f
1960 /* Write a loop to move a constant number of bytes. Generate load/stores as follows:
1961
1962 do {
1963 temp1 = src[0];
1964 temp2 = src[1];
1965 ...
1966 temp<last> = src[MAX_MOVE_REGS-1];
1967 dest[0] = temp1;
1968 dest[1] = temp2;
1969 ...
1970 dest[MAX_MOVE_REGS-1] = temp<last>;
1971 src += MAX_MOVE_REGS;
1972 dest += MAX_MOVE_REGS;
1973 } while (src != final);
1974
1975 This way, no NOP's are needed, and only MAX_MOVE_REGS+3 temp
1976 registers are needed.
1977
1978 Aligned moves move MAX_MOVE_REGS*4 bytes every (2*MAX_MOVE_REGS)+3
1979 cycles, unaligned moves move MAX_MOVE_REGS*4 bytes every
1980 (4*MAX_MOVE_REGS)+3 cycles, assuming no cache misses. */
1981
1982 #define MAX_MOVE_REGS 4
1983 #define MAX_MOVE_BYTES (MAX_MOVE_REGS * UNITS_PER_WORD)
1984
1985 static void
1986 block_move_loop (dest_reg, src_reg, bytes, align, orig_src)
1987 rtx dest_reg; /* register holding destination address */
1988 rtx src_reg; /* register holding source address */
1989 int bytes; /* # bytes to move */
1990 int align; /* alignment */
1991 rtx orig_src; /* original source for making a reg note */
1992 {
1993 rtx dest_mem = gen_rtx (MEM, BLKmode, dest_reg);
1994 rtx src_mem = gen_rtx (MEM, BLKmode, src_reg);
1995 rtx align_rtx = GEN_INT (align);
1996 rtx label;
1997 rtx final_src;
1998 rtx bytes_rtx;
1999 int leftover;
2000
2001 if (bytes < 2*MAX_MOVE_BYTES)
2002 abort ();
2003
2004 leftover = bytes % MAX_MOVE_BYTES;
2005 bytes -= leftover;
2006
2007 label = gen_label_rtx ();
2008 final_src = gen_reg_rtx (Pmode);
2009 bytes_rtx = GEN_INT (bytes);
2010
2011 if (bytes > 0x7fff)
2012 {
2013 emit_insn (gen_movsi (final_src, bytes_rtx));
2014 emit_insn (gen_addsi3 (final_src, final_src, src_reg));
2015 }
2016 else
2017 emit_insn (gen_addsi3 (final_src, src_reg, bytes_rtx));
2018
2019 emit_label (label);
2020
2021 bytes_rtx = GEN_INT (MAX_MOVE_BYTES);
2022 emit_insn (gen_movstrsi_internal (dest_mem, src_mem, bytes_rtx, align_rtx));
2023 emit_insn (gen_addsi3 (src_reg, src_reg, bytes_rtx));
2024 emit_insn (gen_addsi3 (dest_reg, dest_reg, bytes_rtx));
2025 emit_insn (gen_cmpsi (src_reg, final_src));
2026 emit_jump_insn (gen_bne (label));
2027
2028 if (leftover)
2029 emit_insn (gen_movstrsi_internal (dest_mem, src_mem,
2030 GEN_INT (leftover),
2031 align_rtx));
2032 }
2033
2034 \f
2035 /* Use a library function to move some bytes. */
2036
2037 static void
2038 block_move_call (dest_reg, src_reg, bytes_rtx)
2039 rtx dest_reg;
2040 rtx src_reg;
2041 rtx bytes_rtx;
2042 {
2043 #ifdef TARGET_MEM_FUNCTIONS
2044 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "memcpy"), 0,
2045 VOIDmode, 3,
2046 dest_reg, Pmode,
2047 src_reg, Pmode,
2048 bytes_rtx, SImode);
2049 #else
2050 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "bcopy"), 0,
2051 VOIDmode, 3,
2052 src_reg, Pmode,
2053 dest_reg, Pmode,
2054 bytes_rtx, SImode);
2055 #endif
2056 }
2057
2058 \f
2059 /* Expand string/block move operations.
2060
2061 operands[0] is the pointer to the destination.
2062 operands[1] is the pointer to the source.
2063 operands[2] is the number of bytes to move.
2064 operands[3] is the alignment. */
2065
2066 void
2067 expand_block_move (operands)
2068 rtx operands[];
2069 {
2070 rtx bytes_rtx = operands[2];
2071 rtx align_rtx = operands[3];
2072 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
2073 int bytes = (constp ? INTVAL (bytes_rtx) : 0);
2074 int align = INTVAL (align_rtx);
2075 rtx orig_src = operands[1];
2076 rtx src_reg;
2077 rtx dest_reg;
2078
2079 if (constp && bytes <= 0)
2080 return;
2081
2082 if (align > UNITS_PER_WORD)
2083 align = UNITS_PER_WORD;
2084
2085 /* Move the address into scratch registers. */
2086 dest_reg = copy_addr_to_reg (XEXP (operands[0], 0));
2087 src_reg = copy_addr_to_reg (XEXP (orig_src, 0));
2088
2089 if (TARGET_MEMCPY)
2090 block_move_call (dest_reg, src_reg, bytes_rtx);
2091
2092 #if 0
2093 else if (constp && bytes <= 3*align)
2094 block_move_sequence (dest_reg, src_reg, bytes, align, orig_src);
2095 #endif
2096
2097 else if (constp && bytes <= 2*MAX_MOVE_BYTES)
2098 emit_insn (gen_movstrsi_internal (gen_rtx (MEM, BLKmode, dest_reg),
2099 gen_rtx (MEM, BLKmode, src_reg),
2100 bytes_rtx, align_rtx));
2101
2102 else if (constp && align >= UNITS_PER_WORD && optimize)
2103 block_move_loop (dest_reg, src_reg, bytes, align, orig_src);
2104
2105 else if (constp && optimize)
2106 {
2107 /* If the alignment is not word aligned, generate a test at
2108 runtime, to see whether things wound up aligned, and we
2109 can use the faster lw/sw instead ulw/usw. */
2110
2111 rtx temp = gen_reg_rtx (Pmode);
2112 rtx aligned_label = gen_label_rtx ();
2113 rtx join_label = gen_label_rtx ();
2114 int leftover = bytes % MAX_MOVE_BYTES;
2115
2116 bytes -= leftover;
2117
2118 emit_insn (gen_iorsi3 (temp, src_reg, dest_reg));
2119 emit_insn (gen_andsi3 (temp, temp, GEN_INT (UNITS_PER_WORD-1)));
2120 emit_insn (gen_cmpsi (temp, const0_rtx));
2121 emit_jump_insn (gen_beq (aligned_label));
2122
2123 /* Unaligned loop. */
2124 block_move_loop (dest_reg, src_reg, bytes, 1, orig_src);
2125 emit_jump_insn (gen_jump (join_label));
2126 emit_barrier ();
2127
2128 /* Aligned loop. */
2129 emit_label (aligned_label);
2130 block_move_loop (dest_reg, src_reg, bytes, UNITS_PER_WORD, orig_src);
2131 emit_label (join_label);
2132
2133 /* Bytes at the end of the loop. */
2134 if (leftover)
2135 {
2136 #if 0
2137 if (leftover <= 3*align)
2138 block_move_sequence (dest_reg, src_reg, leftover, align, orig_src);
2139
2140 else
2141 #endif
2142 emit_insn (gen_movstrsi_internal (gen_rtx (MEM, BLKmode, dest_reg),
2143 gen_rtx (MEM, BLKmode, src_reg),
2144 GEN_INT (leftover),
2145 GEN_INT (align)));
2146 }
2147 }
2148
2149 else
2150 block_move_call (dest_reg, src_reg, bytes_rtx);
2151 }
2152
2153 \f
2154 /* Emit load/stores for a small constant block_move.
2155
2156 operands[0] is the memory address of the destination.
2157 operands[1] is the memory address of the source.
2158 operands[2] is the number of bytes to move.
2159 operands[3] is the alignment.
2160 operands[4] is a temp register.
2161 operands[5] is a temp register.
2162 ...
2163 operands[3+num_regs] is the last temp register.
2164
2165 The block move type can be one of the following:
2166 BLOCK_MOVE_NORMAL Do all of the block move.
2167 BLOCK_MOVE_NOT_LAST Do all but the last store.
2168 BLOCK_MOVE_LAST Do just the last store. */
2169
2170 char *
2171 output_block_move (insn, operands, num_regs, move_type)
2172 rtx insn;
2173 rtx operands[];
2174 int num_regs;
2175 enum block_move_type move_type;
2176 {
2177 rtx dest_reg = XEXP (operands[0], 0);
2178 rtx src_reg = XEXP (operands[1], 0);
2179 int bytes = INTVAL (operands[2]);
2180 int align = INTVAL (operands[3]);
2181 int num = 0;
2182 int offset = 0;
2183 int use_lwl_lwr = FALSE;
2184 int last_operand = num_regs+4;
2185 int i;
2186 rtx xoperands[10];
2187
2188 struct {
2189 char *load; /* load insn without nop */
2190 char *load_nop; /* load insn with trailing nop */
2191 char *store; /* store insn */
2192 char *final; /* if last_store used: NULL or swr */
2193 char *last_store; /* last store instruction */
2194 int offset; /* current offset */
2195 enum machine_mode mode; /* mode to use on (MEM) */
2196 } load_store[4];
2197
2198 /* Detect a bug in GCC, where it can give us a register
2199 the same as one of the addressing registers. */
2200 for (i = 4; i < last_operand; i++)
2201 {
2202 if (reg_mentioned_p (operands[i], operands[0])
2203 || reg_mentioned_p (operands[i], operands[1]))
2204 {
2205 abort_with_insn (insn, "register passed as address and temp register to block move");
2206 }
2207 }
2208
2209 /* If we are given global or static addresses, and we would be
2210 emitting a few instructions, try to save time by using a
2211 temporary register for the pointer. */
2212 if (bytes > 2*align || move_type != BLOCK_MOVE_NORMAL)
2213 {
2214 if (CONSTANT_P (src_reg))
2215 {
2216 if (TARGET_STATS)
2217 mips_count_memory_refs (operands[1], 1);
2218
2219 src_reg = operands[ 3 + num_regs-- ];
2220 if (move_type != BLOCK_MOVE_LAST)
2221 {
2222 xoperands[1] = operands[1];
2223 xoperands[0] = src_reg;
2224 output_asm_insn ("la\t%0,%1", xoperands);
2225 }
2226 }
2227
2228 if (CONSTANT_P (dest_reg))
2229 {
2230 if (TARGET_STATS)
2231 mips_count_memory_refs (operands[0], 1);
2232
2233 dest_reg = operands[ 3 + num_regs-- ];
2234 if (move_type != BLOCK_MOVE_LAST)
2235 {
2236 xoperands[1] = operands[0];
2237 xoperands[0] = dest_reg;
2238 output_asm_insn ("la\t%0,%1", xoperands);
2239 }
2240 }
2241 }
2242
2243 if (num_regs > (sizeof (load_store) / sizeof (load_store[0])))
2244 num_regs = (sizeof (load_store) / sizeof (load_store[0]));
2245
2246 else if (num_regs < 1)
2247 abort ();
2248
2249 if (TARGET_GAS && move_type != BLOCK_MOVE_LAST && set_noreorder++ == 0)
2250 output_asm_insn (".set\tnoreorder", operands);
2251
2252 while (bytes > 0)
2253 {
2254 load_store[num].offset = offset;
2255
2256 if (bytes >= UNITS_PER_WORD && align >= UNITS_PER_WORD)
2257 {
2258 load_store[num].load = "lw\t%0,%1";
2259 load_store[num].load_nop = "lw\t%0,%1%#";
2260 load_store[num].store = "sw\t%0,%1";
2261 load_store[num].last_store = "sw\t%0,%1";
2262 load_store[num].final = (char *)0;
2263 load_store[num].mode = SImode;
2264 offset += UNITS_PER_WORD;
2265 bytes -= UNITS_PER_WORD;
2266 }
2267
2268 else if (bytes >= UNITS_PER_WORD)
2269 {
2270 #if BYTES_BIG_ENDIAN
2271 load_store[num].load = "lwl\t%0,%1\n\tlwr\t%0,%2";
2272 load_store[num].load_nop = "lwl\t%0,%1\n\tlwr\t%0,%2%#";
2273 load_store[num].store = "swl\t%0,%1\n\tswr\t%0,%2";
2274 load_store[num].last_store = "swr\t%0,%2";
2275 load_store[num].final = "swl\t%0,%1";
2276 #else
2277 load_store[num].load = "lwl\t%0,%2\n\tlwr\t%0,%1";
2278 load_store[num].load_nop = "lwl\t%0,%2\n\tlwr\t%0,%1%#";
2279 load_store[num].store = "swl\t%0,%2\n\tswr\t%0,%1";
2280 load_store[num].last_store = "swr\t%0,%1";
2281 load_store[num].final = "swl\t%0,%2";
2282 #endif
2283 load_store[num].mode = SImode;
2284 offset += UNITS_PER_WORD;
2285 bytes -= UNITS_PER_WORD;
2286 use_lwl_lwr = TRUE;
2287 }
2288
2289 else if (bytes >= UNITS_PER_SHORT && align >= UNITS_PER_SHORT)
2290 {
2291 load_store[num].load = "lh\t%0,%1";
2292 load_store[num].load_nop = "lh\t%0,%1%#";
2293 load_store[num].store = "sh\t%0,%1";
2294 load_store[num].last_store = "sh\t%0,%1";
2295 load_store[num].final = (char *)0;
2296 load_store[num].offset = offset;
2297 load_store[num].mode = HImode;
2298 offset += UNITS_PER_SHORT;
2299 bytes -= UNITS_PER_SHORT;
2300 }
2301
2302 else
2303 {
2304 load_store[num].load = "lb\t%0,%1";
2305 load_store[num].load_nop = "lb\t%0,%1%#";
2306 load_store[num].store = "sb\t%0,%1";
2307 load_store[num].last_store = "sb\t%0,%1";
2308 load_store[num].final = (char *)0;
2309 load_store[num].mode = QImode;
2310 offset++;
2311 bytes--;
2312 }
2313
2314 if (TARGET_STATS && move_type != BLOCK_MOVE_LAST)
2315 {
2316 dslots_load_total++;
2317 dslots_load_filled++;
2318
2319 if (CONSTANT_P (src_reg))
2320 mips_count_memory_refs (src_reg, 1);
2321
2322 if (CONSTANT_P (dest_reg))
2323 mips_count_memory_refs (dest_reg, 1);
2324 }
2325
2326 /* Emit load/stores now if we have run out of registers or are
2327 at the end of the move. */
2328
2329 if (++num == num_regs || bytes == 0)
2330 {
2331 /* If only load/store, we need a NOP after the load. */
2332 if (num == 1)
2333 {
2334 load_store[0].load = load_store[0].load_nop;
2335 if (TARGET_STATS && move_type != BLOCK_MOVE_LAST)
2336 dslots_load_filled--;
2337 }
2338
2339 if (move_type != BLOCK_MOVE_LAST)
2340 {
2341 for (i = 0; i < num; i++)
2342 {
2343 int offset;
2344
2345 if (!operands[i+4])
2346 abort ();
2347
2348 if (GET_MODE (operands[i+4]) != load_store[i].mode)
2349 operands[i+4] = gen_rtx (REG, load_store[i].mode, REGNO (operands[i+4]));
2350
2351 offset = load_store[i].offset;
2352 xoperands[0] = operands[i+4];
2353 xoperands[1] = gen_rtx (MEM, load_store[i].mode,
2354 plus_constant (src_reg, offset));
2355
2356 if (use_lwl_lwr)
2357 xoperands[2] = gen_rtx (MEM, load_store[i].mode,
2358 plus_constant (src_reg, UNITS_PER_WORD-1+offset));
2359
2360 output_asm_insn (load_store[i].load, xoperands);
2361 }
2362 }
2363
2364 for (i = 0; i < num; i++)
2365 {
2366 int last_p = (i == num-1 && bytes == 0);
2367 int offset = load_store[i].offset;
2368
2369 xoperands[0] = operands[i+4];
2370 xoperands[1] = gen_rtx (MEM, load_store[i].mode,
2371 plus_constant (dest_reg, offset));
2372
2373
2374 if (use_lwl_lwr)
2375 xoperands[2] = gen_rtx (MEM, load_store[i].mode,
2376 plus_constant (dest_reg, UNITS_PER_WORD-1+offset));
2377
2378 if (move_type == BLOCK_MOVE_NORMAL)
2379 output_asm_insn (load_store[i].store, xoperands);
2380
2381 else if (move_type == BLOCK_MOVE_NOT_LAST)
2382 {
2383 if (!last_p)
2384 output_asm_insn (load_store[i].store, xoperands);
2385
2386 else if (load_store[i].final != (char *)0)
2387 output_asm_insn (load_store[i].final, xoperands);
2388 }
2389
2390 else if (last_p)
2391 output_asm_insn (load_store[i].last_store, xoperands);
2392 }
2393
2394 num = 0; /* reset load_store */
2395 use_lwl_lwr = FALSE; /* reset whether or not we used lwl/lwr */
2396 }
2397 }
2398
2399 if (TARGET_GAS && move_type != BLOCK_MOVE_LAST && --set_noreorder == 0)
2400 output_asm_insn (".set\treorder", operands);
2401
2402 return "";
2403 }
2404
2405 \f
2406 /* Argument support functions. */
2407
2408 /* Initialize CUMULATIVE_ARGS for a function. */
2409
2410 void
2411 init_cumulative_args (cum, fntype, libname)
2412 CUMULATIVE_ARGS *cum; /* argument info to initialize */
2413 tree fntype; /* tree ptr for function decl */
2414 rtx libname; /* SYMBOL_REF of library name or 0 */
2415 {
2416 tree param, next_param;
2417
2418 if (TARGET_DEBUG_E_MODE)
2419 {
2420 fprintf (stderr, "\ninit_cumulative_args, fntype = 0x%.8lx", (long)fntype);
2421 if (!fntype)
2422 fputc ('\n', stderr);
2423
2424 else
2425 {
2426 tree ret_type = TREE_TYPE (fntype);
2427 fprintf (stderr, ", fntype code = %s, ret code = %s\n",
2428 tree_code_name[ (int)TREE_CODE (fntype) ],
2429 tree_code_name[ (int)TREE_CODE (ret_type) ]);
2430 }
2431 }
2432
2433 cum->gp_reg_found = 0;
2434 cum->arg_number = 0;
2435 cum->arg_words = 0;
2436
2437 /* Determine if this function has variable arguments. This is
2438 indicated by the last argument being 'void_type_mode' if there
2439 are no variable arguments. The standard MIPS calling sequence
2440 passes all arguments in the general purpose registers in this
2441 case. */
2442
2443 for (param = (fntype) ? TYPE_ARG_TYPES (fntype) : 0;
2444 param != (tree)0;
2445 param = next_param)
2446 {
2447 next_param = TREE_CHAIN (param);
2448 if (next_param == (tree)0 && TREE_VALUE (param) != void_type_node)
2449 cum->gp_reg_found = 1;
2450 }
2451 }
2452
2453 /* Advance the argument to the next argument position. */
2454
2455 void
2456 function_arg_advance (cum, mode, type, named)
2457 CUMULATIVE_ARGS *cum; /* current arg information */
2458 enum machine_mode mode; /* current arg mode */
2459 tree type; /* type of the argument or 0 if lib support */
2460 int named; /* whether or not the argument was named */
2461 {
2462 if (TARGET_DEBUG_E_MODE)
2463 fprintf (stderr,
2464 "function_adv( {gp reg found = %d, arg # = %2d, words = %2d}, %4s, 0x%.8x, %d )\n",
2465 cum->gp_reg_found, cum->arg_number, cum->arg_words, GET_MODE_NAME (mode),
2466 type, named);
2467
2468 cum->arg_number++;
2469 switch (mode)
2470 {
2471 default:
2472 error ("Illegal mode given to function_arg_advance");
2473 break;
2474
2475 case VOIDmode:
2476 break;
2477
2478 case BLKmode:
2479 cum->gp_reg_found = 1;
2480 cum->arg_words += (int_size_in_bytes (type) + 3) / 4;
2481 break;
2482
2483 case SFmode:
2484 cum->arg_words++;
2485 break;
2486
2487 case DFmode:
2488 cum->arg_words += 2;
2489 break;
2490
2491 case DImode:
2492 cum->gp_reg_found = 1;
2493 cum->arg_words += 2;
2494 break;
2495
2496 case QImode:
2497 case HImode:
2498 case SImode:
2499 cum->gp_reg_found = 1;
2500 cum->arg_words++;
2501 break;
2502 }
2503 }
2504
2505 /* Return a RTL expression containing the register for the given mode,
2506 or 0 if the argument is too be passed on the stack. */
2507
2508 struct rtx_def *
2509 function_arg (cum, mode, type, named)
2510 CUMULATIVE_ARGS *cum; /* current arg information */
2511 enum machine_mode mode; /* current arg mode */
2512 tree type; /* type of the argument or 0 if lib support */
2513 int named; /* != 0 for normal args, == 0 for ... args */
2514 {
2515 int regbase = -1;
2516 int bias = 0;
2517
2518 if (TARGET_DEBUG_E_MODE)
2519 fprintf (stderr,
2520 "function_arg( {gp reg found = %d, arg # = %2d, words = %2d}, %4s, 0x%.8x, %d ) = ",
2521 cum->gp_reg_found, cum->arg_number, cum->arg_words, GET_MODE_NAME (mode),
2522 type, named);
2523
2524 switch (mode)
2525 {
2526 default:
2527 error ("Illegal mode given to function_arg");
2528 break;
2529
2530 case SFmode:
2531 if (cum->gp_reg_found || cum->arg_number >= 2)
2532 regbase = GP_ARG_FIRST;
2533 else {
2534 regbase = (TARGET_SOFT_FLOAT) ? GP_ARG_FIRST : FP_ARG_FIRST;
2535 if (cum->arg_words == 1) /* first arg was float */
2536 bias = 1; /* use correct reg */
2537 }
2538
2539 break;
2540
2541 case DFmode:
2542 cum->arg_words += (cum->arg_words & 1);
2543 regbase = (cum->gp_reg_found || TARGET_SOFT_FLOAT)
2544 ? GP_ARG_FIRST
2545 : FP_ARG_FIRST;
2546 break;
2547
2548 case BLKmode:
2549 if (type != (tree)0 && TYPE_ALIGN (type) > BITS_PER_WORD)
2550 cum->arg_words += (cum->arg_words & 1);
2551
2552 regbase = GP_ARG_FIRST;
2553 break;
2554
2555 case VOIDmode:
2556 case QImode:
2557 case HImode:
2558 case SImode:
2559 regbase = GP_ARG_FIRST;
2560 break;
2561
2562 case DImode:
2563 cum->arg_words += (cum->arg_words & 1);
2564 regbase = GP_ARG_FIRST;
2565 }
2566
2567 if (cum->arg_words >= MAX_ARGS_IN_REGISTERS)
2568 {
2569 if (TARGET_DEBUG_E_MODE)
2570 fprintf (stderr, "<stack>\n");
2571
2572 return 0;
2573 }
2574
2575 if (regbase == -1)
2576 abort ();
2577
2578 if (TARGET_DEBUG_E_MODE)
2579 fprintf (stderr, "%s\n", reg_names[regbase + cum->arg_words + bias]);
2580
2581 return gen_rtx (REG, mode, regbase + cum->arg_words + bias);
2582 }
2583
2584
2585 int
2586 function_arg_partial_nregs (cum, mode, type, named)
2587 CUMULATIVE_ARGS *cum; /* current arg information */
2588 enum machine_mode mode; /* current arg mode */
2589 tree type; /* type of the argument or 0 if lib support */
2590 int named; /* != 0 for normal args, == 0 for ... args */
2591 {
2592 if (mode == BLKmode && cum->arg_words < MAX_ARGS_IN_REGISTERS)
2593 {
2594 int words = (int_size_in_bytes (type) + 3) / 4;
2595
2596 if (words + cum->arg_words < MAX_ARGS_IN_REGISTERS)
2597 return 0; /* structure fits in registers */
2598
2599 if (TARGET_DEBUG_E_MODE)
2600 fprintf (stderr, "function_arg_partial_nregs = %d\n",
2601 MAX_ARGS_IN_REGISTERS - cum->arg_words);
2602
2603 return MAX_ARGS_IN_REGISTERS - cum->arg_words;
2604 }
2605
2606 else if (mode == DImode && cum->arg_words == MAX_ARGS_IN_REGISTERS-1)
2607 {
2608 if (TARGET_DEBUG_E_MODE)
2609 fprintf (stderr, "function_arg_partial_nregs = 1\n");
2610
2611 return 1;
2612 }
2613
2614 return 0;
2615 }
2616
2617 \f
2618 /* Print the options used in the assembly file. */
2619
2620 static struct {char *name; int value;} target_switches []
2621 = TARGET_SWITCHES;
2622
2623 void
2624 print_options (out)
2625 FILE *out;
2626 {
2627 int line_len;
2628 int len;
2629 int j;
2630 char **p;
2631 int mask = TARGET_DEFAULT;
2632
2633 /* Allow assembly language comparisons with -mdebug eliminating the
2634 compiler version number and switch lists. */
2635
2636 if (TARGET_DEBUG_MODE)
2637 return;
2638
2639 fprintf (out, "\n # %s %s", language_string, version_string);
2640 #ifdef TARGET_VERSION_INTERNAL
2641 TARGET_VERSION_INTERNAL (out);
2642 #endif
2643 #ifdef __GNUC__
2644 fprintf (out, " compiled by GNU C\n\n");
2645 #else
2646 fprintf (out, " compiled by CC\n\n");
2647 #endif
2648
2649 fprintf (out, " # Cc1 defaults:");
2650 line_len = 32767;
2651 for (j = 0; j < sizeof target_switches / sizeof target_switches[0]; j++)
2652 {
2653 if (target_switches[j].name[0] != '\0'
2654 && target_switches[j].value > 0
2655 && (target_switches[j].value & mask) == target_switches[j].value)
2656 {
2657 mask &= ~ target_switches[j].value;
2658 len = strlen (target_switches[j].name) + 1;
2659 if (len + line_len > 79)
2660 {
2661 line_len = 2;
2662 fputs ("\n #", out);
2663 }
2664 fprintf (out, " -m%s", target_switches[j].name);
2665 line_len += len;
2666 }
2667 }
2668
2669 fprintf (out, "\n\n # Cc1 arguments (-G value = %d, Cpu = %s, ISA = %d):",
2670 mips_section_threshold, mips_cpu_string, mips_isa);
2671
2672 line_len = 32767;
2673 for (p = &save_argv[1]; *p != (char *)0; p++)
2674 {
2675 char *arg = *p;
2676 if (*arg == '-')
2677 {
2678 len = strlen (arg) + 1;
2679 if (len + line_len > 79)
2680 {
2681 line_len = 2;
2682 fputs ("\n #", out);
2683 }
2684 fprintf (out, " %s", *p);
2685 line_len += len;
2686 }
2687 }
2688
2689 fputs ("\n\n", out);
2690 }
2691
2692 \f
2693 /* Abort after printing out a specific insn. */
2694
2695 void
2696 abort_with_insn (insn, reason)
2697 rtx insn;
2698 char *reason;
2699 {
2700 error (reason);
2701 debug_rtx (insn);
2702 abort ();
2703 }
2704
2705 /* Write a message to stderr (for use in macros expanded in files that do not
2706 include stdio.h). */
2707
2708 void
2709 trace (s, s1, s2)
2710 char *s, *s1, *s2;
2711 {
2712 fprintf (stderr, s, s1, s2);
2713 }
2714
2715 \f
2716 #ifdef SIGINFO
2717
2718 static void
2719 siginfo (signo)
2720 int signo;
2721 {
2722 fprintf (stderr, "compiling '%s' in '%s'\n",
2723 (current_function_name != (char *)0) ? current_function_name : "<toplevel>",
2724 (current_function_file != (char *)0) ? current_function_file : "<no file>");
2725 fflush (stderr);
2726 }
2727 #endif /* SIGINFO */
2728
2729 \f
2730 /* Set up the threshold for data to go into the small data area, instead
2731 of the normal data area, and detect any conflicts in the switches. */
2732
2733 void
2734 override_options ()
2735 {
2736 register int i, start;
2737 register int regno;
2738 register enum machine_mode mode;
2739
2740 if (g_switch_set)
2741 mips_section_threshold = g_switch_value;
2742
2743 else
2744 mips_section_threshold = (TARGET_MIPS_AS) ? 8 : 0;
2745
2746 /* Identify the processor type */
2747 if (mips_cpu_string == (char *)0
2748 || !strcmp (mips_cpu_string, "default")
2749 || !strcmp (mips_cpu_string, "DEFAULT"))
2750 {
2751 mips_cpu_string = "default";
2752 mips_cpu = PROCESSOR_DEFAULT;
2753 }
2754
2755 else
2756 {
2757 char *p = mips_cpu_string;
2758
2759 if (*p == 'r' || *p == 'R')
2760 p++;
2761
2762 /* Since there is no difference between a R2000 and R3000 in
2763 terms of the scheduler, we collapse them into just an R3000. */
2764
2765 mips_cpu = PROCESSOR_DEFAULT;
2766 switch (*p)
2767 {
2768 case '2':
2769 if (!strcmp (p, "2000") || !strcmp (p, "2k") || !strcmp (p, "2K"))
2770 mips_cpu = PROCESSOR_R3000;
2771 break;
2772
2773 case '3':
2774 if (!strcmp (p, "3000") || !strcmp (p, "3k") || !strcmp (p, "3K"))
2775 mips_cpu = PROCESSOR_R3000;
2776 break;
2777
2778 case '4':
2779 if (!strcmp (p, "4000") || !strcmp (p, "4k") || !strcmp (p, "4K"))
2780 mips_cpu = PROCESSOR_R4000;
2781 break;
2782
2783 case '6':
2784 if (!strcmp (p, "6000") || !strcmp (p, "6k") || !strcmp (p, "6K"))
2785 mips_cpu = PROCESSOR_R6000;
2786 break;
2787 }
2788
2789 if (mips_cpu == PROCESSOR_DEFAULT)
2790 {
2791 error ("bad value (%s) for -mcpu= switch", mips_cpu_string);
2792 mips_cpu_string = "default";
2793 }
2794 }
2795
2796 /* Now get the architectural level. */
2797 if (mips_isa_string == (char *)0)
2798 mips_isa = 1;
2799
2800 else if (isdigit (*mips_isa_string))
2801 mips_isa = atoi (mips_isa_string);
2802
2803 else
2804 {
2805 error ("bad value (%s) for -mips switch", mips_isa_string);
2806 mips_isa = 1;
2807 }
2808
2809 if (mips_isa < 0 || mips_isa > 3)
2810 error ("-mips%d not supported", mips_isa);
2811
2812 else if (mips_isa > 1
2813 && (mips_cpu == PROCESSOR_DEFAULT || mips_cpu == PROCESSOR_R3000))
2814 error ("-mcpu=%s does not support -mips%d", mips_cpu_string, mips_isa);
2815
2816 else if (mips_cpu == PROCESSOR_R6000 && mips_isa > 2)
2817 error ("-mcpu=%s does not support -mips%d", mips_cpu_string, mips_isa);
2818
2819 /* make sure sizes of ints/longs/etc. are ok */
2820 if (mips_isa < 3)
2821 {
2822 if (TARGET_INT64)
2823 fatal ("Only the r4000 can support 64 bit ints");
2824
2825 else if (TARGET_LONG64)
2826 fatal ("Only the r4000 can support 64 bit longs");
2827
2828 else if (TARGET_LLONG128)
2829 fatal ("Only the r4000 can support 128 bit long longs");
2830
2831 else if (TARGET_FLOAT64)
2832 fatal ("Only the r4000 can support 64 bit fp registers");
2833 }
2834 else if (TARGET_INT64 || TARGET_LONG64 || TARGET_LLONG128 || TARGET_FLOAT64)
2835 warning ("r4000 64/128 bit types not yet supported");
2836
2837 /* Tell halfpic.c that we have half-pic code if we do. */
2838 if (TARGET_HALF_PIC)
2839 HALF_PIC_INIT ();
2840
2841 /* -mrnames says to use the MIPS software convention for register
2842 names instead of the hardware names (ie, a0 instead of $4).
2843 We do this by switching the names in mips_reg_names, which the
2844 reg_names points into via the REGISTER_NAMES macro. */
2845
2846 if (TARGET_NAME_REGS)
2847 {
2848 if (TARGET_GAS)
2849 {
2850 target_flags &= ~ MASK_NAME_REGS;
2851 error ("Gas does not support the MIPS software register name convention.");
2852 }
2853 else
2854 bcopy ((char *) mips_sw_reg_names, (char *) mips_reg_names, sizeof (mips_reg_names));
2855 }
2856
2857 /* If this is OSF/1, set up a SIGINFO handler so we can see what function
2858 is currently being compiled. */
2859 #ifdef SIGINFO
2860 if (getenv ("GCC_SIGINFO") != (char *)0)
2861 {
2862 struct sigaction action;
2863 action.sa_handler = siginfo;
2864 action.sa_mask = 0;
2865 action.sa_flags = SA_RESTART;
2866 sigaction (SIGINFO, &action, (struct sigaction *)0);
2867 }
2868 #endif
2869
2870 #if defined(_IOLBF)
2871 #if defined(ultrix) || defined(__ultrix) || defined(__OSF1__) || defined(__osf__) || defined(osf)
2872 /* If -mstats and -quiet, make stderr line buffered. */
2873 if (quiet_flag && TARGET_STATS)
2874 setvbuf (stderr, (char *)0, _IOLBF, BUFSIZ);
2875 #endif
2876 #endif
2877
2878 /* Set up the classification arrays now. */
2879 mips_rtx_classify[(int)PLUS] = CLASS_ADD_OP;
2880 mips_rtx_classify[(int)MINUS] = CLASS_ADD_OP;
2881 mips_rtx_classify[(int)DIV] = CLASS_DIVMOD_OP;
2882 mips_rtx_classify[(int)MOD] = CLASS_DIVMOD_OP;
2883 mips_rtx_classify[(int)UDIV] = CLASS_DIVMOD_OP | CLASS_UNSIGNED_OP;
2884 mips_rtx_classify[(int)UMOD] = CLASS_DIVMOD_OP | CLASS_UNSIGNED_OP;
2885 mips_rtx_classify[(int)EQ] = CLASS_CMP_OP | CLASS_EQUALITY_OP | CLASS_FCMP_OP;
2886 mips_rtx_classify[(int)NE] = CLASS_CMP_OP | CLASS_EQUALITY_OP | CLASS_FCMP_OP;
2887 mips_rtx_classify[(int)GT] = CLASS_CMP_OP | CLASS_FCMP_OP;
2888 mips_rtx_classify[(int)GE] = CLASS_CMP_OP | CLASS_FCMP_OP;
2889 mips_rtx_classify[(int)LT] = CLASS_CMP_OP | CLASS_FCMP_OP;
2890 mips_rtx_classify[(int)LE] = CLASS_CMP_OP | CLASS_FCMP_OP;
2891 mips_rtx_classify[(int)GTU] = CLASS_CMP_OP | CLASS_UNSIGNED_OP;
2892 mips_rtx_classify[(int)GEU] = CLASS_CMP_OP | CLASS_UNSIGNED_OP;
2893 mips_rtx_classify[(int)LTU] = CLASS_CMP_OP | CLASS_UNSIGNED_OP;
2894 mips_rtx_classify[(int)LEU] = CLASS_CMP_OP | CLASS_UNSIGNED_OP;
2895
2896 mips_print_operand_punct['?'] = TRUE;
2897 mips_print_operand_punct['#'] = TRUE;
2898 mips_print_operand_punct['&'] = TRUE;
2899 mips_print_operand_punct['!'] = TRUE;
2900 mips_print_operand_punct['*'] = TRUE;
2901 mips_print_operand_punct['@'] = TRUE;
2902 mips_print_operand_punct['.'] = TRUE;
2903 mips_print_operand_punct['('] = TRUE;
2904 mips_print_operand_punct[')'] = TRUE;
2905 mips_print_operand_punct['['] = TRUE;
2906 mips_print_operand_punct[']'] = TRUE;
2907 mips_print_operand_punct['<'] = TRUE;
2908 mips_print_operand_punct['>'] = TRUE;
2909 mips_print_operand_punct['{'] = TRUE;
2910 mips_print_operand_punct['}'] = TRUE;
2911
2912 mips_char_to_class['d'] = GR_REGS;
2913 mips_char_to_class['f'] = ((TARGET_HARD_FLOAT) ? FP_REGS : NO_REGS);
2914 mips_char_to_class['h'] = HI_REG;
2915 mips_char_to_class['l'] = LO_REG;
2916 mips_char_to_class['x'] = MD_REGS;
2917 mips_char_to_class['y'] = GR_REGS;
2918 mips_char_to_class['z'] = ST_REGS;
2919
2920 /* Set up array to map GCC register number to debug register number.
2921 Ignore the special purpose register numbers. */
2922
2923 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2924 mips_dbx_regno[i] = -1;
2925
2926 start = GP_DBX_FIRST - GP_REG_FIRST;
2927 for (i = GP_REG_FIRST; i <= GP_REG_LAST; i++)
2928 mips_dbx_regno[i] = i + start;
2929
2930 start = FP_DBX_FIRST - FP_REG_FIRST;
2931 for (i = FP_REG_FIRST; i <= FP_REG_LAST; i++)
2932 mips_dbx_regno[i] = i + start;
2933
2934 /* Set up array giving whether a given register can hold a given mode.
2935 At present, restrict ints from being in FP registers, because reload
2936 is a little enthusiastic about storing extra values in FP registers,
2937 and this is not good for things like OS kernels. Also, due to the
2938 mandatory delay, it is as fast to load from cached memory as to move
2939 from the FP register. */
2940
2941 for (mode = VOIDmode;
2942 mode != MAX_MACHINE_MODE;
2943 mode = (enum machine_mode)((int)mode + 1))
2944 {
2945 register int size = GET_MODE_SIZE (mode);
2946 register enum mode_class class = GET_MODE_CLASS (mode);
2947
2948 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
2949 {
2950 register int temp;
2951
2952 if (mode == CC_FPmode || mode == CC_REV_FPmode)
2953 temp = (regno == FPSW_REGNUM);
2954
2955 else if (GP_REG_P (regno))
2956 temp = ((regno & 1) == 0 || (size <= UNITS_PER_WORD));
2957
2958 else if (FP_REG_P (regno))
2959 temp = ((TARGET_FLOAT64 || ((regno & 1) == 0))
2960 && (class == MODE_FLOAT
2961 || class == MODE_COMPLEX_FLOAT
2962 || (TARGET_DEBUG_H_MODE && class == MODE_INT)));
2963
2964 else if (MD_REG_P (regno))
2965 temp = (mode == SImode || (regno == MD_REG_FIRST && mode == DImode));
2966
2967 else
2968 temp = FALSE;
2969
2970 mips_hard_regno_mode_ok[(int)mode][regno] = temp;
2971 }
2972 }
2973 }
2974
2975 \f
2976 /*
2977 * The MIPS debug format wants all automatic variables and arguments
2978 * to be in terms of the virtual frame pointer (stack pointer before
2979 * any adjustment in the function), while the MIPS 3.0 linker wants
2980 * the frame pointer to be the stack pointer after the initial
2981 * adjustment. So, we do the adjustment here. The arg pointer (which
2982 * is eliminated) points to the virtual frame pointer, while the frame
2983 * pointer (which may be eliminated) points to the stack pointer after
2984 * the initial adjustments.
2985 */
2986
2987 int
2988 mips_debugger_offset (addr, offset)
2989 rtx addr;
2990 int offset;
2991 {
2992 rtx offset2 = const0_rtx;
2993 rtx reg = eliminate_constant_term (addr, &offset2);
2994
2995 if (!offset)
2996 offset = INTVAL (offset2);
2997
2998 if (reg == stack_pointer_rtx || reg == frame_pointer_rtx)
2999 {
3000 int frame_size = (!current_frame_info.initialized)
3001 ? compute_frame_size (get_frame_size ())
3002 : current_frame_info.total_size;
3003
3004 offset = offset - frame_size;
3005 }
3006 /* sdbout_parms does not want this to crash for unrecognized cases. */
3007 #if 0
3008 else if (reg != arg_pointer_rtx)
3009 abort_with_insn (addr, "mips_debugger_offset called with non stack/frame/arg pointer.");
3010 #endif
3011
3012 return offset;
3013 }
3014
3015 \f
3016 /* A C compound statement to output to stdio stream STREAM the
3017 assembler syntax for an instruction operand X. X is an RTL
3018 expression.
3019
3020 CODE is a value that can be used to specify one of several ways
3021 of printing the operand. It is used when identical operands
3022 must be printed differently depending on the context. CODE
3023 comes from the `%' specification that was used to request
3024 printing of the operand. If the specification was just `%DIGIT'
3025 then CODE is 0; if the specification was `%LTR DIGIT' then CODE
3026 is the ASCII code for LTR.
3027
3028 If X is a register, this macro should print the register's name.
3029 The names can be found in an array `reg_names' whose type is
3030 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
3031
3032 When the machine description has a specification `%PUNCT' (a `%'
3033 followed by a punctuation character), this macro is called with
3034 a null pointer for X and the punctuation character for CODE.
3035
3036 The MIPS specific codes are:
3037
3038 'X' X is CONST_INT, prints 32 bits in hexadecimal format = "0x%08x",
3039 'x' X is CONST_INT, prints 16 bits in hexadecimal format = "0x%04x",
3040 'd' output integer constant in decimal,
3041 'z' if the operand is 0, use $0 instead of normal operand.
3042 'D' print second register of double-word register operand.
3043 'L' print low-order register of double-word register operand.
3044 'M' print high-order register of double-word register operand.
3045 'C' print part of opcode for a branch condition.
3046 'N' print part of opcode for a branch condition, inverted.
3047 '(' Turn on .set noreorder
3048 ')' Turn on .set reorder
3049 '[' Turn on .set noat
3050 ']' Turn on .set at
3051 '<' Turn on .set nomacro
3052 '>' Turn on .set macro
3053 '{' Turn on .set volatile (not GAS)
3054 '}' Turn on .set novolatile (not GAS)
3055 '&' Turn on .set noreorder if filling delay slots
3056 '*' Turn on both .set noreorder and .set nomacro if filling delay slots
3057 '!' Turn on .set nomacro if filling delay slots
3058 '#' Print nop if in a .set noreorder section.
3059 '?' Print 'l' if we are to use a branch likely instead of normal branch.
3060 '@' Print the name of the assembler temporary register (at or $1).
3061 '.' Print the name of the register with a hard-wired zero (zero or $0). */
3062
3063 void
3064 print_operand (file, op, letter)
3065 FILE *file; /* file to write to */
3066 rtx op; /* operand to print */
3067 int letter; /* %<letter> or 0 */
3068 {
3069 register enum rtx_code code;
3070
3071 if (PRINT_OPERAND_PUNCT_VALID_P (letter))
3072 {
3073 switch (letter)
3074 {
3075 default:
3076 error ("PRINT_OPERAND: Unknown punctuation '%c'", letter);
3077 break;
3078
3079 case '?':
3080 if (mips_branch_likely)
3081 putc ('l', file);
3082 break;
3083
3084 case '@':
3085 fputs (reg_names [GP_REG_FIRST + 1], file);
3086 break;
3087
3088 case '.':
3089 fputs (reg_names [GP_REG_FIRST + 0], file);
3090 break;
3091
3092 case '&':
3093 if (final_sequence != 0 && set_noreorder++ == 0)
3094 fputs (".set\tnoreorder\n\t", file);
3095 break;
3096
3097 case '*':
3098 if (final_sequence != 0)
3099 {
3100 if (set_noreorder++ == 0)
3101 fputs (".set\tnoreorder\n\t", file);
3102
3103 if (set_nomacro++ == 0)
3104 fputs (".set\tnomacro\n\t", file);
3105 }
3106 break;
3107
3108 case '!':
3109 if (final_sequence != 0 && set_nomacro++ == 0)
3110 fputs ("\n\t.set\tnomacro", file);
3111 break;
3112
3113 case '#':
3114 if (set_noreorder != 0)
3115 fputs ("\n\tnop", file);
3116
3117 else if (TARGET_GAS || TARGET_STATS)
3118 fputs ("\n\t#nop", file);
3119
3120 break;
3121
3122 case '(':
3123 if (set_noreorder++ == 0)
3124 fputs (".set\tnoreorder\n\t", file);
3125 break;
3126
3127 case ')':
3128 if (set_noreorder == 0)
3129 error ("internal error: %%) found without a %%( in assembler pattern");
3130
3131 else if (--set_noreorder == 0)
3132 fputs ("\n\t.set\treorder", file);
3133
3134 break;
3135
3136 case '[':
3137 if (set_noat++ == 0)
3138 fputs (".set\tnoat\n\t", file);
3139 break;
3140
3141 case ']':
3142 if (set_noat == 0)
3143 error ("internal error: %%] found without a %%[ in assembler pattern");
3144
3145 else if (--set_noat == 0)
3146 fputs ("\n\t.set\tat", file);
3147
3148 break;
3149
3150 case '<':
3151 if (set_nomacro++ == 0)
3152 fputs (".set\tnomacro\n\t", file);
3153 break;
3154
3155 case '>':
3156 if (set_nomacro == 0)
3157 error ("internal error: %%> found without a %%< in assembler pattern");
3158
3159 else if (--set_nomacro == 0)
3160 fputs ("\n\t.set\tmacro", file);
3161
3162 break;
3163
3164 case '{':
3165 if (set_volatile++ == 0)
3166 fprintf (file, "%s.set\tvolatile\n\t", (TARGET_MIPS_AS) ? "" : "#");
3167 break;
3168
3169 case '}':
3170 if (set_volatile == 0)
3171 error ("internal error: %%} found without a %%{ in assembler pattern");
3172
3173 else if (--set_volatile == 0)
3174 fprintf (file, "\n\t%s.set\tnovolatile", (TARGET_MIPS_AS) ? "" : "#");
3175
3176 break;
3177 }
3178 return;
3179 }
3180
3181 if (! op)
3182 {
3183 error ("PRINT_OPERAND null pointer");
3184 return;
3185 }
3186
3187 code = GET_CODE (op);
3188 if (letter == 'C')
3189 switch (code)
3190 {
3191 case EQ: fputs ("eq", file); break;
3192 case NE: fputs ("ne", file); break;
3193 case GT: fputs ("gt", file); break;
3194 case GE: fputs ("ge", file); break;
3195 case LT: fputs ("lt", file); break;
3196 case LE: fputs ("le", file); break;
3197 case GTU: fputs ("gtu", file); break;
3198 case GEU: fputs ("geu", file); break;
3199 case LTU: fputs ("ltu", file); break;
3200 case LEU: fputs ("leu", file); break;
3201
3202 default:
3203 abort_with_insn (op, "PRINT_OPERAND, illegal insn for %%C");
3204 }
3205
3206 else if (letter == 'N')
3207 switch (code)
3208 {
3209 case EQ: fputs ("ne", file); break;
3210 case NE: fputs ("eq", file); break;
3211 case GT: fputs ("le", file); break;
3212 case GE: fputs ("lt", file); break;
3213 case LT: fputs ("ge", file); break;
3214 case LE: fputs ("gt", file); break;
3215 case GTU: fputs ("leu", file); break;
3216 case GEU: fputs ("ltu", file); break;
3217 case LTU: fputs ("geu", file); break;
3218 case LEU: fputs ("gtu", file); break;
3219
3220 default:
3221 abort_with_insn (op, "PRINT_OPERAND, illegal insn for %%N");
3222 }
3223
3224 else if (code == REG)
3225 {
3226 register int regnum = REGNO (op);
3227
3228 if (letter == 'M')
3229 regnum += MOST_SIGNIFICANT_WORD;
3230
3231 else if (letter == 'L')
3232 regnum += LEAST_SIGNIFICANT_WORD;
3233
3234 else if (letter == 'D')
3235 regnum++;
3236
3237 fprintf (file, "%s", reg_names[regnum]);
3238 }
3239
3240 else if (code == MEM)
3241 output_address (XEXP (op, 0));
3242
3243 else if (code == CONST_DOUBLE)
3244 {
3245 #if HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT
3246 union { double d; int i[2]; } u;
3247 u.i[0] = CONST_DOUBLE_LOW (op);
3248 u.i[1] = CONST_DOUBLE_HIGH (op);
3249 if (GET_MODE (op) == SFmode)
3250 {
3251 float f;
3252 f = u.d;
3253 u.d = f;
3254 }
3255 fprintf (file, "%.20e", u.d);
3256 #else
3257 fatal ("CONST_DOUBLE found in cross compilation");
3258 #endif
3259 }
3260
3261 else if ((letter == 'x') && (GET_CODE(op) == CONST_INT))
3262 fprintf (file, "0x%04x", 0xffff & (INTVAL(op)));
3263
3264 else if ((letter == 'X') && (GET_CODE(op) == CONST_INT))
3265 fprintf (file, "0x%08x", INTVAL(op));
3266
3267 else if ((letter == 'd') && (GET_CODE(op) == CONST_INT))
3268 fprintf (file, "%d", (INTVAL(op)));
3269
3270 else if (letter == 'z'
3271 && (GET_CODE (op) == CONST_INT)
3272 && INTVAL (op) == 0)
3273 fputs (reg_names[GP_REG_FIRST], file);
3274
3275 else if (letter == 'd' || letter == 'x' || letter == 'X')
3276 fatal ("PRINT_OPERAND: letter %c was found & insn was not CONST_INT", letter);
3277
3278 else
3279 output_addr_const (file, op);
3280 }
3281
3282 \f
3283 /* A C compound statement to output to stdio stream STREAM the
3284 assembler syntax for an instruction operand that is a memory
3285 reference whose address is ADDR. ADDR is an RTL expression.
3286
3287 On some machines, the syntax for a symbolic address depends on
3288 the section that the address refers to. On these machines,
3289 define the macro `ENCODE_SECTION_INFO' to store the information
3290 into the `symbol_ref', and then check for it here. */
3291
3292 void
3293 print_operand_address (file, addr)
3294 FILE *file;
3295 rtx addr;
3296 {
3297 if (!addr)
3298 error ("PRINT_OPERAND_ADDRESS, null pointer");
3299
3300 else
3301 switch (GET_CODE (addr))
3302 {
3303 default:
3304 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, illegal insn #1");
3305 break;
3306
3307 case REG:
3308 if (REGNO (addr) == ARG_POINTER_REGNUM)
3309 abort_with_insn (addr, "Arg pointer not eliminated.");
3310
3311 fprintf (file, "0(%s)", reg_names [REGNO (addr)]);
3312 break;
3313
3314 case PLUS:
3315 {
3316 register rtx reg = (rtx)0;
3317 register rtx offset = (rtx)0;
3318 register rtx arg0 = XEXP (addr, 0);
3319 register rtx arg1 = XEXP (addr, 1);
3320
3321 if (GET_CODE (arg0) == REG)
3322 {
3323 reg = arg0;
3324 offset = arg1;
3325 if (GET_CODE (offset) == REG)
3326 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, 2 regs");
3327 }
3328 else if (GET_CODE (arg1) == REG)
3329 {
3330 reg = arg1;
3331 offset = arg0;
3332 }
3333 else if (CONSTANT_P (arg0) && CONSTANT_P (arg1))
3334 {
3335 output_addr_const (file, addr);
3336 break;
3337 }
3338 else
3339 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, no regs");
3340
3341 if (!CONSTANT_P (offset))
3342 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, illegal insn #2");
3343
3344 if (REGNO (reg) == ARG_POINTER_REGNUM)
3345 abort_with_insn (addr, "Arg pointer not eliminated.");
3346
3347 output_addr_const (file, offset);
3348 fprintf (file, "(%s)", reg_names [REGNO (reg)]);
3349 }
3350 break;
3351
3352 case LABEL_REF:
3353 case SYMBOL_REF:
3354 case CONST_INT:
3355 case CONST:
3356 output_addr_const (file, addr);
3357 break;
3358 }
3359 }
3360
3361 \f
3362 /* If optimizing for the global pointer, keep track of all of
3363 the externs, so that at the end of the file, we can emit
3364 the appropriate .extern declaration for them, before writing
3365 out the text section. We assume that all names passed to
3366 us are in the permanent obstack, so that they will be valid
3367 at the end of the compilation.
3368
3369 If we have -G 0, or the extern size is unknown, don't bother
3370 emitting the .externs. */
3371
3372 int
3373 mips_output_external (file, decl, name)
3374 FILE *file;
3375 tree decl;
3376 char *name;
3377 {
3378 register struct extern_list *p;
3379 int len;
3380
3381 if (TARGET_GP_OPT
3382 && mips_section_threshold != 0
3383 && ((TREE_CODE (decl)) != FUNCTION_DECL)
3384 && ((len = int_size_in_bytes (TREE_TYPE (decl))) > 0))
3385 {
3386 p = (struct extern_list *)permalloc ((long) sizeof (struct extern_list));
3387 p->next = extern_head;
3388 p->name = name;
3389 p->size = len;
3390 extern_head = p;
3391 }
3392 return 0;
3393 }
3394
3395 \f
3396 /* Compute a string to use as a temporary file name. */
3397
3398 static FILE *
3399 make_temp_file ()
3400 {
3401 FILE *stream;
3402 char *base = getenv ("TMPDIR");
3403 int len;
3404
3405 if (base == (char *)0)
3406 {
3407 #ifdef P_tmpdir
3408 if (access (P_tmpdir, R_OK | W_OK) == 0)
3409 base = P_tmpdir;
3410 else
3411 #endif
3412 if (access ("/usr/tmp", R_OK | W_OK) == 0)
3413 base = "/usr/tmp/";
3414 else
3415 base = "/tmp/";
3416 }
3417
3418 len = strlen (base);
3419 temp_filename = (char *) alloca (len + sizeof("/ccXXXXXX"));
3420 strcpy (temp_filename, base);
3421 if (len > 0 && temp_filename[len-1] != '/')
3422 temp_filename[len++] = '/';
3423
3424 strcpy (temp_filename + len, "ccXXXXXX");
3425 mktemp (temp_filename);
3426
3427 stream = fopen (temp_filename, "w+");
3428 if (!stream)
3429 pfatal_with_name (temp_filename);
3430
3431 unlink (temp_filename);
3432 return stream;
3433 }
3434
3435 \f
3436 /* Emit a new filename to a stream. If this is MIPS ECOFF, watch out
3437 for .file's that start within a function. If we are smuggling stabs, try to
3438 put out a MIPS ECOFF file and a stab. */
3439
3440 void
3441 mips_output_filename (stream, name)
3442 FILE *stream;
3443 char *name;
3444 {
3445 static int first_time = TRUE;
3446 char ltext_label_name[100];
3447
3448 if (first_time)
3449 {
3450 first_time = FALSE;
3451 SET_FILE_NUMBER ();
3452 current_function_file = name;
3453 fprintf (stream, "\t.file\t%d \"%s\"\n", num_source_filenames, name);
3454 if (!TARGET_GAS && write_symbols == DBX_DEBUG)
3455 fprintf (stream, "\t#@stabs\n");
3456 }
3457
3458 else if (!TARGET_GAS && write_symbols == DBX_DEBUG)
3459 {
3460 ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", 0);
3461 fprintf (stream, "%s \"%s\",%d,0,0,%s\n", ASM_STABS_OP,
3462 name, N_SOL, &ltext_label_name[1]);
3463 }
3464
3465 else if (name != current_function_file
3466 && strcmp (name, current_function_file) != 0)
3467 {
3468 if (inside_function && !TARGET_GAS)
3469 {
3470 if (!file_in_function_warning)
3471 {
3472 file_in_function_warning = TRUE;
3473 ignore_line_number = TRUE;
3474 warning ("MIPS ECOFF format does not allow changing filenames within functions with #line");
3475 }
3476
3477 fprintf (stream, "\t#.file\t%d \"%s\"\n", num_source_filenames, name);
3478 }
3479
3480 else
3481 {
3482 SET_FILE_NUMBER ();
3483 current_function_file = name;
3484 fprintf (stream, "\t.file\t%d \"%s\"\n", num_source_filenames, name);
3485 }
3486 }
3487 }
3488
3489 \f
3490 /* Emit a linenumber. For encapsulated stabs, we need to put out a stab
3491 as well as a .loc, since it is possible that MIPS ECOFF might not be
3492 able to represent the location for inlines that come from a different
3493 file. */
3494
3495 void
3496 mips_output_lineno (stream, line)
3497 FILE *stream;
3498 int line;
3499 {
3500 if (!TARGET_GAS && write_symbols == DBX_DEBUG)
3501 {
3502 ++sym_lineno;
3503 fprintf (stream, "$LM%d:\n\t%s %d,0,%d,$LM%d\n",
3504 sym_lineno, ASM_STABN_OP, N_SLINE, line, sym_lineno);
3505 }
3506
3507 else
3508 {
3509 fprintf (stream, "\n\t%s.loc\t%d %d\n",
3510 (ignore_line_number) ? "#" : "",
3511 num_source_filenames, line);
3512
3513 LABEL_AFTER_LOC (stream);
3514 }
3515 }
3516
3517 \f
3518 /* If defined, a C statement to be executed just prior to the
3519 output of assembler code for INSN, to modify the extracted
3520 operands so they will be output differently.
3521
3522 Here the argument OPVEC is the vector containing the operands
3523 extracted from INSN, and NOPERANDS is the number of elements of
3524 the vector which contain meaningful data for this insn. The
3525 contents of this vector are what will be used to convert the
3526 insn template into assembler code, so you can change the
3527 assembler output by changing the contents of the vector.
3528
3529 We use it to check if the current insn needs a nop in front of it
3530 because of load delays, and also to update the delay slot
3531 statistics. */
3532
3533 void
3534 final_prescan_insn (insn, opvec, noperands)
3535 rtx insn;
3536 rtx opvec[];
3537 int noperands;
3538 {
3539 if (dslots_number_nops > 0)
3540 {
3541 rtx pattern = PATTERN (insn);
3542 int length = get_attr_length (insn);
3543
3544 /* Do we need to emit a NOP? */
3545 if (length == 0
3546 || (mips_load_reg != (rtx)0 && reg_mentioned_p (mips_load_reg, pattern))
3547 || (mips_load_reg2 != (rtx)0 && reg_mentioned_p (mips_load_reg2, pattern))
3548 || (mips_load_reg3 != (rtx)0 && reg_mentioned_p (mips_load_reg3, pattern))
3549 || (mips_load_reg4 != (rtx)0 && reg_mentioned_p (mips_load_reg4, pattern)))
3550 fputs ((set_noreorder) ? "\tnop\n" : "\t#nop\n", asm_out_file);
3551
3552 else
3553 dslots_load_filled++;
3554
3555 while (--dslots_number_nops > 0)
3556 fputs ((set_noreorder) ? "\tnop\n" : "\t#nop\n", asm_out_file);
3557
3558 mips_load_reg = (rtx)0;
3559 mips_load_reg2 = (rtx)0;
3560 mips_load_reg3 = (rtx)0;
3561 mips_load_reg4 = (rtx)0;
3562
3563 if (set_noreorder && --set_noreorder == 0)
3564 fputs ("\t.set\treorder\n", asm_out_file);
3565 }
3566
3567 if (TARGET_STATS)
3568 {
3569 enum rtx_code code = GET_CODE (insn);
3570 if (code == JUMP_INSN || code == CALL_INSN)
3571 dslots_jump_total++;
3572 }
3573 }
3574
3575 \f
3576 /* Output at beginning of assembler file.
3577 If we are optimizing to use the global pointer, create a temporary
3578 file to hold all of the text stuff, and write it out to the end.
3579 This is needed because the MIPS assembler is evidently one pass,
3580 and if it hasn't seen the relevant .comm/.lcomm/.extern/.sdata
3581 declaration when the code is processed, it generates a two
3582 instruction sequence. */
3583
3584 void
3585 mips_asm_file_start (stream)
3586 FILE *stream;
3587 {
3588 ASM_OUTPUT_SOURCE_FILENAME (stream, main_input_filename);
3589
3590 /* Versions of the MIPS assembler before 2.20 generate errors
3591 if a branch inside of a .set noreorder section jumps to a
3592 label outside of the .set noreorder section. Revision 2.20
3593 just set nobopt silently rather than fixing the bug. */
3594
3595 if (TARGET_MIPS_AS && optimize && flag_delayed_branch)
3596 fprintf (stream, "\t.set\tnobopt\n");
3597
3598 /* Generate the pseudo ops that the Pyramid based System V.4 wants. */
3599 if (TARGET_ABICALLS)
3600 fprintf (stream, "\t.abicalls\n");
3601
3602 if (TARGET_GP_OPT)
3603 {
3604 asm_out_data_file = stream;
3605 asm_out_text_file = make_temp_file ();
3606 }
3607 else
3608 asm_out_data_file = asm_out_text_file = stream;
3609
3610 if (TARGET_NAME_REGS)
3611 fprintf (asm_out_file, "#include <regdef.h>\n");
3612
3613 print_options (stream);
3614 }
3615
3616 \f
3617 /* If we are optimizing the global pointer, emit the text section now
3618 and any small externs which did not have .comm, etc that are
3619 needed. Also, give a warning if the data area is more than 32K and
3620 -pic because 3 instructions are needed to reference the data
3621 pointers. */
3622
3623 void
3624 mips_asm_file_end (file)
3625 FILE *file;
3626 {
3627 char buffer[8192];
3628 tree name_tree;
3629 struct extern_list *p;
3630 int len;
3631
3632 if (HALF_PIC_P ())
3633 HALF_PIC_FINISH (file);
3634
3635 if (TARGET_GP_OPT)
3636 {
3637 if (extern_head)
3638 fputs ("\n", file);
3639
3640 for (p = extern_head; p != 0; p = p->next)
3641 {
3642 name_tree = get_identifier (p->name);
3643
3644 /* Positively ensure only one .extern for any given symbol. */
3645 if (! TREE_ASM_WRITTEN (name_tree))
3646 {
3647 TREE_ASM_WRITTEN (name_tree) = 1;
3648 fputs ("\t.extern\t", file);
3649 assemble_name (file, p->name);
3650 fprintf (file, ", %d\n", p->size);
3651 }
3652 }
3653
3654 fprintf (file, "\n\t.text\n");
3655 rewind (asm_out_text_file);
3656 if (ferror (asm_out_text_file))
3657 fatal_io_error (temp_filename);
3658
3659 while ((len = fread (buffer, 1, sizeof (buffer), asm_out_text_file)) > 0)
3660 if (fwrite (buffer, 1, len, file) != len)
3661 pfatal_with_name (asm_file_name);
3662
3663 if (len < 0)
3664 pfatal_with_name (temp_filename);
3665
3666 if (fclose (asm_out_text_file) != 0)
3667 pfatal_with_name (temp_filename);
3668 }
3669 }
3670
3671 \f
3672 /* Emit either a label, .comm, or .lcomm directive, and mark
3673 that the symbol is used, so that we don't emit an .extern
3674 for it in mips_asm_file_end. */
3675
3676 void
3677 mips_declare_object (stream, name, init_string, final_string, size)
3678 FILE *stream;
3679 char *name;
3680 char *init_string;
3681 char *final_string;
3682 int size;
3683 {
3684 fputs (init_string, stream); /* "", "\t.comm\t", or "\t.lcomm\t" */
3685 assemble_name (stream, name);
3686 fprintf (stream, final_string, size); /* ":\n", ",%u\n", ",%u\n" */
3687
3688 if (TARGET_GP_OPT && mips_section_threshold != 0)
3689 {
3690 tree name_tree = get_identifier (name);
3691 TREE_ASM_WRITTEN (name_tree) = 1;
3692 }
3693 }
3694
3695 \f
3696 /* Output a double precision value to the assembler. If both the
3697 host and target are IEEE, emit the values in hex. */
3698
3699 void
3700 mips_output_double (stream, value)
3701 FILE *stream;
3702 REAL_VALUE_TYPE value;
3703 {
3704 #ifdef REAL_VALUE_TO_TARGET_DOUBLE
3705 long value_long[2];
3706 REAL_VALUE_TO_TARGET_DOUBLE (value, value_long);
3707
3708 fprintf (stream, "\t.word\t0x%08lx\t\t# %.20g\n\t.word\t0x%08lx\n",
3709 value_long[0], value, value_long[1]);
3710 #else
3711 fprintf (stream, "\t.double\t%.20g\n", value);
3712 #endif
3713 }
3714
3715
3716 /* Output a single precision value to the assembler. If both the
3717 host and target are IEEE, emit the values in hex. */
3718
3719 void
3720 mips_output_float (stream, value)
3721 FILE *stream;
3722 REAL_VALUE_TYPE value;
3723 {
3724 #ifdef REAL_VALUE_TO_TARGET_SINGLE
3725 long value_long;
3726 REAL_VALUE_TO_TARGET_SINGLE (value, value_long);
3727
3728 fprintf (stream, "\t.word\t0x%08lx\t\t# %.12g (float)\n", value_long, value);
3729 #else
3730 fprintf (stream, "\t.float\t%.12g\n", value);
3731 #endif
3732 }
3733
3734 \f
3735 /* Return the bytes needed to compute the frame pointer from the current
3736 stack pointer.
3737
3738 Mips stack frames look like:
3739
3740 Before call After call
3741 +-----------------------+ +-----------------------+
3742 high | | | |
3743 mem. | | | |
3744 | caller's temps. | | caller's temps. |
3745 | | | |
3746 +-----------------------+ +-----------------------+
3747 | | | |
3748 | arguments on stack. | | arguments on stack. |
3749 | | | |
3750 +-----------------------+ +-----------------------+
3751 | 4 words to save | | 4 words to save |
3752 | arguments passed | | arguments passed |
3753 | in registers, even | | in registers, even |
3754 SP->| if not passed. | FP->| if not passed. |
3755 +-----------------------+ +-----------------------+
3756 | |
3757 | GP save for V.4 abi |
3758 | |
3759 +-----------------------+
3760 | |
3761 | fp register save |
3762 | |
3763 +-----------------------+
3764 | |
3765 | gp register save |
3766 | |
3767 +-----------------------+
3768 | |
3769 | local variables |
3770 | |
3771 +-----------------------+
3772 | |
3773 | alloca allocations |
3774 | |
3775 +-----------------------+
3776 | |
3777 | arguments on stack |
3778 | |
3779 +-----------------------+
3780 | 4 words to save |
3781 | arguments passed |
3782 | in registers, even |
3783 low SP->| if not passed. |
3784 memory +-----------------------+
3785
3786 */
3787
3788 unsigned long
3789 compute_frame_size (size)
3790 int size; /* # of var. bytes allocated */
3791 {
3792 int regno;
3793 unsigned long total_size; /* # bytes that the entire frame takes up */
3794 unsigned long var_size; /* # bytes that variables take up */
3795 unsigned long args_size; /* # bytes that outgoing arguments take up */
3796 unsigned long extra_size; /* # extra bytes */
3797 unsigned int gp_reg_rounded; /* # bytes needed to store gp after rounding */
3798 unsigned int gp_reg_size; /* # bytes needed to store gp regs */
3799 unsigned int fp_reg_size; /* # bytes needed to store fp regs */
3800 unsigned long mask; /* mask of saved gp registers */
3801 unsigned long fmask; /* mask of saved fp registers */
3802 int fp_inc; /* 1 or 2 depending on the size of fp regs */
3803 int fp_bits; /* bitmask to use for each fp register */
3804
3805 gp_reg_size = 0;
3806 fp_reg_size = 0;
3807 mask = 0;
3808 fmask = 0;
3809 extra_size = MIPS_STACK_ALIGN (((TARGET_ABICALLS) ? UNITS_PER_WORD : 0));
3810 var_size = MIPS_STACK_ALIGN (size);
3811 args_size = MIPS_STACK_ALIGN (current_function_outgoing_args_size);
3812
3813 /* The MIPS 3.0 linker does not like functions that dynamically
3814 allocate the stack and have 0 for STACK_DYNAMIC_OFFSET, since it
3815 looks like we are trying to create a second frame pointer to the
3816 function, so allocate some stack space to make it happy. */
3817
3818 if (args_size == 0 && current_function_calls_alloca)
3819 args_size = 4*UNITS_PER_WORD;
3820
3821 total_size = var_size + args_size + extra_size;
3822
3823 /* Calculate space needed for gp registers. */
3824 for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
3825 {
3826 if (MUST_SAVE_REGISTER (regno))
3827 {
3828 gp_reg_size += UNITS_PER_WORD;
3829 mask |= 1 << (regno - GP_REG_FIRST);
3830 }
3831 }
3832
3833 /* Calculate space needed for fp registers. */
3834 if (TARGET_FLOAT64)
3835 {
3836 fp_inc = 1;
3837 fp_bits = 1;
3838 }
3839 else
3840 {
3841 fp_inc = 2;
3842 fp_bits = 3;
3843 }
3844
3845 for (regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno += fp_inc)
3846 {
3847 if (regs_ever_live[regno] && !call_used_regs[regno])
3848 {
3849 fp_reg_size += 2*UNITS_PER_WORD;
3850 fmask |= fp_bits << (regno - FP_REG_FIRST);
3851 }
3852 }
3853
3854 gp_reg_rounded = MIPS_STACK_ALIGN (gp_reg_size);
3855 total_size += gp_reg_rounded + fp_reg_size;
3856
3857 if (total_size == extra_size)
3858 total_size = extra_size = 0;
3859
3860 /* Save other computed information. */
3861 current_frame_info.total_size = total_size;
3862 current_frame_info.var_size = var_size;
3863 current_frame_info.args_size = args_size;
3864 current_frame_info.extra_size = extra_size;
3865 current_frame_info.gp_reg_size = gp_reg_size;
3866 current_frame_info.fp_reg_size = fp_reg_size;
3867 current_frame_info.mask = mask;
3868 current_frame_info.fmask = fmask;
3869 current_frame_info.initialized = reload_completed;
3870 current_frame_info.num_gp = gp_reg_size / UNITS_PER_WORD;
3871 current_frame_info.num_fp = fp_reg_size / (2*UNITS_PER_WORD);
3872
3873 if (mask)
3874 {
3875 unsigned long offset = args_size + var_size + gp_reg_size - UNITS_PER_WORD;
3876 current_frame_info.gp_sp_offset = offset;
3877 current_frame_info.gp_save_offset = offset - total_size;
3878 }
3879 else
3880 {
3881 current_frame_info.gp_sp_offset = 0;
3882 current_frame_info.gp_save_offset = 0;
3883 }
3884
3885
3886 if (fmask)
3887 {
3888 unsigned long offset = args_size + var_size + gp_reg_rounded + fp_reg_size - 2*UNITS_PER_WORD;
3889 current_frame_info.fp_sp_offset = offset;
3890 current_frame_info.fp_save_offset = offset - total_size + UNITS_PER_WORD;
3891 }
3892 else
3893 {
3894 current_frame_info.fp_sp_offset = 0;
3895 current_frame_info.fp_save_offset = 0;
3896 }
3897
3898 /* Ok, we're done. */
3899 return total_size;
3900 }
3901
3902 \f
3903 /* Save/restore registers printing out the instructions to a file. */
3904
3905 void
3906 save_restore (file, gp_op, gp_2word_op, fp_op)
3907 FILE *file; /* stream to write to */
3908 char *gp_op; /* operation to do on gp registers */
3909 char *gp_2word_op; /* 2 word op to do on gp registers */
3910 char *fp_op; /* operation to do on fp registers */
3911 {
3912 int regno;
3913 unsigned long mask = current_frame_info.mask;
3914 unsigned long fmask = current_frame_info.fmask;
3915 unsigned long gp_offset;
3916 unsigned long fp_offset;
3917 unsigned long max_offset;
3918 char *base_reg;
3919
3920 if (mask == 0 && fmask == 0)
3921 return;
3922
3923 base_reg = reg_names[STACK_POINTER_REGNUM];
3924 gp_offset = current_frame_info.gp_sp_offset;
3925 fp_offset = current_frame_info.fp_sp_offset;
3926 max_offset = (gp_offset > fp_offset) ? gp_offset : fp_offset;
3927
3928 /* Deal with calling functions with a large structure. */
3929 if (max_offset >= 32768)
3930 {
3931 char *temp = reg_names[MIPS_TEMP2_REGNUM];
3932 fprintf (file, "\tli\t%s,%ld\n", temp, max_offset);
3933 fprintf (file, "\taddu\t%s,%s,%s\n", temp, temp, base_reg);
3934 base_reg = temp;
3935 gp_offset = max_offset - gp_offset;
3936 fp_offset = max_offset - fp_offset;
3937 }
3938
3939 /* Save registers starting from high to low. The debuggers prefer
3940 at least the return register be stored at func+4, and also it
3941 allows us not to need a nop in the epilog if at least one
3942 register is reloaded in addition to return address. */
3943
3944 if (mask || frame_pointer_needed)
3945 {
3946 for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--)
3947 {
3948 if ((mask & (1L << (regno - GP_REG_FIRST))) != 0
3949 || (regno == FRAME_POINTER_REGNUM && frame_pointer_needed))
3950 {
3951 fprintf (file, "\t%s\t%s,%d(%s)\n",
3952 gp_op, reg_names[regno],
3953 gp_offset, base_reg);
3954
3955 gp_offset -= UNITS_PER_WORD;
3956 }
3957 }
3958 }
3959
3960 if (fmask)
3961 {
3962 int fp_inc = (TARGET_FLOAT64) ? 1 : 2;
3963
3964 for (regno = FP_REG_LAST-1; regno >= FP_REG_FIRST; regno -= fp_inc)
3965 {
3966 if ((fmask & (1L << (regno - FP_REG_FIRST))) != 0)
3967 {
3968 fprintf (file, "\t%s\t%s,%d(%s)\n",
3969 fp_op, reg_names[regno], fp_offset, base_reg);
3970
3971 fp_offset -= 2*UNITS_PER_WORD;
3972 }
3973 }
3974 }
3975 }
3976
3977 \f
3978 /* Common code to emit the insns to save/restore registers. */
3979
3980 static void
3981 save_restore_insns (store_p)
3982 int store_p; /* true if this is prologue */
3983 {
3984 int regno;
3985 rtx base_reg_rtx = stack_pointer_rtx;
3986 unsigned long mask = current_frame_info.mask;
3987 unsigned long fmask = current_frame_info.fmask;
3988 unsigned long gp_offset;
3989 unsigned long fp_offset;
3990 unsigned long max_offset;
3991
3992 if (mask == 0 && fmask == 0)
3993 return;
3994
3995 gp_offset = current_frame_info.gp_sp_offset;
3996 fp_offset = current_frame_info.fp_sp_offset;
3997 max_offset = (gp_offset > fp_offset) ? gp_offset : fp_offset;
3998
3999 /* Deal with calling functions with a large structure. */
4000 if (max_offset >= 32768)
4001 {
4002 base_reg_rtx = gen_rtx (REG, Pmode, MIPS_TEMP2_REGNUM);
4003 emit_move_insn (base_reg_rtx, GEN_INT (max_offset));
4004 emit_insn (gen_addsi3 (base_reg_rtx, base_reg_rtx, stack_pointer_rtx));
4005 gp_offset = max_offset - gp_offset;
4006 fp_offset = max_offset - fp_offset;
4007 }
4008
4009 /* Save registers starting from high to low. The debuggers prefer
4010 at least the return register be stored at func+4, and also it
4011 allows us not to need a nop in the epilog if at least one
4012 register is reloaded in addition to return address. */
4013
4014 if (mask || frame_pointer_needed)
4015 {
4016 for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--)
4017 {
4018 if ((mask & (1L << (regno - GP_REG_FIRST))) != 0
4019 || (regno == FRAME_POINTER_REGNUM && frame_pointer_needed))
4020 {
4021 rtx reg_rtx = gen_rtx (REG, Pmode, regno);
4022 rtx mem_rtx = gen_rtx (MEM, Pmode,
4023 gen_rtx (PLUS, Pmode, base_reg_rtx,
4024 GEN_INT (gp_offset)));
4025
4026 if (store_p)
4027 emit_move_insn (mem_rtx, reg_rtx);
4028 else
4029 emit_move_insn (reg_rtx, mem_rtx);
4030
4031 gp_offset -= UNITS_PER_WORD;
4032 }
4033 }
4034 }
4035
4036 if (fmask)
4037 {
4038 int fp_inc = (TARGET_FLOAT64) ? 1 : 2;
4039
4040 for (regno = FP_REG_LAST-1; regno >= FP_REG_FIRST; regno -= fp_inc)
4041 {
4042 if ((fmask & (1L << (regno - FP_REG_FIRST))) != 0)
4043 {
4044 rtx reg_rtx = gen_rtx (REG, DFmode, regno);
4045 rtx mem_rtx = gen_rtx (MEM, DFmode,
4046 gen_rtx (PLUS, Pmode, base_reg_rtx,
4047 GEN_INT (fp_offset)));
4048
4049 if (store_p)
4050 emit_move_insn (mem_rtx, reg_rtx);
4051 else
4052 emit_move_insn (reg_rtx, mem_rtx);
4053
4054 fp_offset -= 2*UNITS_PER_WORD;
4055 }
4056 }
4057 }
4058 }
4059
4060 \f
4061 /* Set up the stack and frame (if desired) for the function. */
4062
4063 void
4064 function_prologue (file, size)
4065 FILE *file;
4066 int size;
4067 {
4068 int tsize = current_frame_info.total_size;
4069
4070 ASM_OUTPUT_SOURCE_FILENAME (file, DECL_SOURCE_FILE (current_function_decl));
4071 ASM_OUTPUT_SOURCE_LINE (file, DECL_SOURCE_LINE (current_function_decl));
4072
4073 inside_function = 1;
4074 fputs ("\t.ent\t", file);
4075 assemble_name (file, current_function_name);
4076 fputs ("\n", file);
4077 assemble_name (file, current_function_name);
4078 fputs (":\n", file);
4079
4080 if (TARGET_ABICALLS)
4081 fprintf (file,
4082 "\t.set\tnoreorder\n\t.cpload\t%s\n\t.set\treorder\n",
4083 reg_names[ GP_REG_FIRST + 25 ]);
4084
4085 tsize = current_frame_info.total_size;
4086 if (tsize > 0 && TARGET_ABICALLS)
4087 fprintf (file, "\t.cprestore %d\n", tsize + STARTING_FRAME_OFFSET);
4088
4089 fprintf (file, "\t.frame\t%s,%d,%s\t\t# vars= %d, regs= %d/%d, args = %d, extra= %d\n",
4090 reg_names[ (frame_pointer_needed) ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM ],
4091 tsize,
4092 reg_names[31 + GP_REG_FIRST],
4093 current_frame_info.var_size,
4094 current_frame_info.num_gp,
4095 current_frame_info.num_fp,
4096 current_function_outgoing_args_size,
4097 current_frame_info.extra_size);
4098
4099 fprintf (file, "\t.mask\t0x%08lx,%d\n\t.fmask\t0x%08lx,%d\n",
4100 current_frame_info.mask,
4101 current_frame_info.gp_save_offset,
4102 current_frame_info.fmask,
4103 current_frame_info.fp_save_offset);
4104 }
4105
4106 \f
4107 /* Expand the prologue into a bunch of separate insns. */
4108
4109 void
4110 mips_expand_prologue ()
4111 {
4112 int regno;
4113 int tsize;
4114 tree fndecl = current_function_decl; /* current... is tooo long */
4115 tree fntype = TREE_TYPE (fndecl);
4116 tree fnargs = (TREE_CODE (fntype) != METHOD_TYPE)
4117 ? DECL_ARGUMENTS (fndecl)
4118 : 0;
4119 tree next_arg;
4120 tree cur_arg;
4121 char *arg_name = (char *)0;
4122 CUMULATIVE_ARGS args_so_far;
4123
4124 /* Determine the last argument, and get its name. */
4125 for (cur_arg = fnargs; cur_arg != (tree)0; cur_arg = next_arg)
4126 {
4127 next_arg = TREE_CHAIN (cur_arg);
4128 if (next_arg == (tree)0)
4129 {
4130 if (DECL_NAME (cur_arg))
4131 arg_name = IDENTIFIER_POINTER (DECL_NAME (cur_arg));
4132
4133 break;
4134 }
4135 }
4136
4137 /* If this function is a varargs function, store any registers that
4138 would normally hold arguments ($4 - $7) on the stack. */
4139 if ((TYPE_ARG_TYPES (fntype) != 0
4140 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype))) != void_type_node))
4141 || (arg_name
4142 && (strcmp (arg_name, "__builtin_va_alist") == 0
4143 || strcmp (arg_name, "va_alist") == 0)))
4144 {
4145 tree parm;
4146
4147 regno = GP_ARG_FIRST;
4148 INIT_CUMULATIVE_ARGS (args_so_far, fntype, (rtx)0);
4149
4150 for (parm = fnargs; (parm && (regno <= GP_ARG_LAST)); parm = TREE_CHAIN (parm))
4151 {
4152 rtx entry_parm;
4153 enum machine_mode passed_mode;
4154 tree type;
4155
4156 type = DECL_ARG_TYPE (parm);
4157 passed_mode = TYPE_MODE (type);
4158 entry_parm = FUNCTION_ARG (args_so_far, passed_mode,
4159 DECL_ARG_TYPE (parm), 1);
4160
4161 if (entry_parm)
4162 {
4163 int words;
4164
4165 /* passed in a register, so will get homed automatically */
4166 if (GET_MODE (entry_parm) == BLKmode)
4167 words = (int_size_in_bytes (type) + 3) / 4;
4168 else
4169 words = (GET_MODE_SIZE (GET_MODE (entry_parm)) + 3) / 4;
4170
4171 regno = REGNO (entry_parm) + words - 1;
4172 }
4173 else
4174 {
4175 regno = GP_ARG_LAST+1;
4176 break;
4177 }
4178
4179 FUNCTION_ARG_ADVANCE (args_so_far, passed_mode,
4180 DECL_ARG_TYPE (parm), 1);
4181 }
4182
4183 for (; regno <= GP_ARG_LAST; regno++)
4184 {
4185 rtx ptr = stack_pointer_rtx;
4186 if (regno != GP_ARG_FIRST)
4187 ptr = gen_rtx (PLUS, Pmode, ptr,
4188 GEN_INT ((regno - GP_ARG_FIRST) * UNITS_PER_WORD));
4189
4190 emit_move_insn (gen_rtx (MEM, Pmode, ptr), gen_rtx (REG, Pmode, regno));
4191 }
4192 }
4193
4194 tsize = compute_frame_size (get_frame_size ());
4195 if (tsize > 0)
4196 {
4197 rtx tsize_rtx = GEN_INT (tsize);
4198
4199 if (tsize > 32767)
4200 {
4201 rtx tmp_rtx = gen_rtx (REG, SImode, MIPS_TEMP1_REGNUM);
4202 emit_move_insn (tmp_rtx, tsize_rtx);
4203 tsize_rtx = tmp_rtx;
4204 }
4205
4206 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, tsize_rtx));
4207
4208 save_restore_insns (TRUE);
4209
4210 if (frame_pointer_needed)
4211 emit_insn (gen_movsi (frame_pointer_rtx, stack_pointer_rtx));
4212 }
4213
4214 /* If we are profiling, make sure no instructions are scheduled before
4215 the call to mcount. */
4216
4217 if (profile_flag || profile_block_flag)
4218 emit_insn (gen_blockage ());
4219 }
4220
4221 \f
4222 /* Do any necessary cleanup after a function to restore stack, frame, and regs. */
4223
4224 void
4225 function_epilogue (file, size)
4226 FILE *file;
4227 int size;
4228 {
4229 int tsize;
4230 char *sp_str = reg_names[STACK_POINTER_REGNUM];
4231 char *t1_str = reg_names[MIPS_TEMP1_REGNUM];
4232 rtx epilogue_delay = current_function_epilogue_delay_list;
4233 int noreorder = !TARGET_MIPS_AS || (epilogue_delay != 0);
4234 int noepilogue = FALSE;
4235 int load_nop = FALSE;
4236 int load_only_r31;
4237
4238 /* The epilogue does not depend on any registers, but the stack
4239 registers, so we assume that if we have 1 pending nop, it can be
4240 ignored, and 2 it must be filled (2 nops occur for integer
4241 multiply and divide). */
4242
4243 if (dslots_number_nops > 0)
4244 {
4245 if (dslots_number_nops == 1)
4246 {
4247 dslots_number_nops = 0;
4248 dslots_load_filled++;
4249 }
4250 else
4251 {
4252 while (--dslots_number_nops > 0)
4253 fputs ((set_noreorder) ? "\tnop\n" : "\t#nop\n", asm_out_file);
4254 }
4255
4256 if (set_noreorder > 0 && --set_noreorder == 0)
4257 fputs ("\t.set\treorder\n", file);
4258 }
4259
4260 if (set_noat != 0)
4261 {
4262 set_noat = 0;
4263 fputs ("\t.set\tat\n", file);
4264 error ("internal gcc error: .set noat left on in epilogue");
4265 }
4266
4267 if (set_nomacro != 0)
4268 {
4269 set_nomacro = 0;
4270 fputs ("\t.set\tmacro\n", file);
4271 error ("internal gcc error: .set nomacro left on in epilogue");
4272 }
4273
4274 if (set_noreorder != 0)
4275 {
4276 set_noreorder = 0;
4277 fputs ("\t.set\treorder\n", file);
4278 error ("internal gcc error: .set noreorder left on in epilogue");
4279 }
4280
4281 if (set_volatile != 0)
4282 {
4283 set_volatile = 0;
4284 fprintf (file, "\t#.set\tnovolatile\n", (TARGET_MIPS_AS) ? "" : "#");
4285 error ("internal gcc error: .set volatile left on in epilogue");
4286 }
4287
4288 size = MIPS_STACK_ALIGN (size);
4289 tsize = (!current_frame_info.initialized)
4290 ? compute_frame_size (size)
4291 : current_frame_info.total_size;
4292
4293 if (tsize == 0 && epilogue_delay == 0)
4294 {
4295 rtx insn = get_last_insn ();
4296
4297 /* If the last insn was a BARRIER, we don't have to write any code
4298 because a jump (aka return) was put there. */
4299 if (GET_CODE (insn) == NOTE)
4300 insn = prev_nonnote_insn (insn);
4301 if (insn && GET_CODE (insn) == BARRIER)
4302 noepilogue = TRUE;
4303
4304 noreorder = FALSE;
4305 }
4306
4307 if (!noepilogue)
4308 {
4309 /* In the reload sequence, we don't need to fill the load delay
4310 slots for most of the loads, also see if we can fill the final
4311 delay slot if not otherwise filled by the reload sequence. */
4312
4313 if (noreorder)
4314 fprintf (file, "\t.set\tnoreorder\n");
4315
4316 if (tsize > 32767)
4317 fprintf (file, "\tli\t%s,%d\n", t1_str, tsize);
4318
4319 if (frame_pointer_needed)
4320 fprintf (file, "\tmove\t%s,%s\t\t\t# sp not trusted here\n",
4321 sp_str, reg_names[FRAME_POINTER_REGNUM]);
4322
4323 save_restore (file, "lw", "ld", "l.d");
4324
4325 load_only_r31 = (current_frame_info.mask == (1 << 31)
4326 && current_frame_info.fmask == 0);
4327
4328 if (noreorder)
4329 {
4330 /* If the only register saved is the return address, we need a
4331 nop, unless we have an instruction to put into it. Otherwise
4332 we don't since reloading multiple registers doesn't reference
4333 the register being loaded. */
4334
4335 if (load_only_r31)
4336 {
4337 if (epilogue_delay)
4338 final_scan_insn (XEXP (epilogue_delay, 0),
4339 file,
4340 1, /* optimize */
4341 -2, /* prescan */
4342 1); /* nopeepholes */
4343 else
4344 {
4345 fprintf (file, "\tnop\n");
4346 load_nop = TRUE;
4347 }
4348 }
4349
4350 fprintf (file, "\tj\t%s\n", reg_names[GP_REG_FIRST + 31]);
4351
4352 if (tsize > 32767)
4353 fprintf (file, "\taddu\t%s,%s,%s\n", sp_str, sp_str, t1_str);
4354
4355 else if (tsize > 0)
4356 fprintf (file, "\taddu\t%s,%s,%d\n", sp_str, sp_str, tsize);
4357
4358 else if (!load_only_r31 && epilogue_delay != 0)
4359 final_scan_insn (XEXP (epilogue_delay, 0),
4360 file,
4361 1, /* optimize */
4362 -2, /* prescan */
4363 1); /* nopeepholes */
4364
4365 fprintf (file, "\t.set\treorder\n");
4366 }
4367
4368 else
4369 {
4370 if (tsize > 32767)
4371 fprintf (file, "\taddu\t%s,%s,%s\n", sp_str, sp_str, t1_str);
4372
4373 else if (tsize > 0)
4374 fprintf (file, "\taddu\t%s,%s,%d\n", sp_str, sp_str, tsize);
4375
4376 fprintf (file, "\tj\t%s\n", reg_names[GP_REG_FIRST + 31]);
4377 }
4378 }
4379
4380 fputs ("\t.end\t", file);
4381 assemble_name (file, current_function_name);
4382 fputs ("\n", file);
4383
4384 if (TARGET_STATS)
4385 {
4386 int num_gp_regs = current_frame_info.gp_reg_size / 4;
4387 int num_fp_regs = current_frame_info.fp_reg_size / 8;
4388 int num_regs = num_gp_regs + num_fp_regs;
4389 char *name = current_function_name;
4390
4391 if (name[0] == '*')
4392 name++;
4393
4394 dslots_load_total += num_regs;
4395
4396 if (!noepilogue)
4397 dslots_jump_total++;
4398
4399 if (noreorder)
4400 {
4401 dslots_load_filled += num_regs;
4402
4403 /* If the only register saved is the return register, we
4404 can't fill this register's delay slot. */
4405
4406 if (load_only_r31 && epilogue_delay == 0)
4407 dslots_load_filled--;
4408
4409 if (tsize > 0 || (!load_only_r31 && epilogue_delay != 0))
4410 dslots_jump_filled++;
4411 }
4412
4413 fprintf (stderr,
4414 "%-20s fp=%c leaf=%c alloca=%c setjmp=%c stack=%4ld arg=%3ld reg=%2d/%d delay=%3d/%3dL %3d/%3dJ refs=%3d/%3d/%3d",
4415 name,
4416 (frame_pointer_needed) ? 'y' : 'n',
4417 ((current_frame_info.mask & (1 << 31)) != 0) ? 'n' : 'y',
4418 (current_function_calls_alloca) ? 'y' : 'n',
4419 (current_function_calls_setjmp) ? 'y' : 'n',
4420 (long)current_frame_info.total_size,
4421 (long)current_function_outgoing_args_size,
4422 num_gp_regs, num_fp_regs,
4423 dslots_load_total, dslots_load_filled,
4424 dslots_jump_total, dslots_jump_filled,
4425 num_refs[0], num_refs[1], num_refs[2]);
4426
4427 if (HALF_PIC_NUMBER_PTRS > prev_half_pic_ptrs)
4428 {
4429 fprintf (stderr, " half-pic=%3d", HALF_PIC_NUMBER_PTRS - prev_half_pic_ptrs);
4430 prev_half_pic_ptrs = HALF_PIC_NUMBER_PTRS;
4431 }
4432
4433 if (HALF_PIC_NUMBER_REFS > prev_half_pic_refs)
4434 {
4435 fprintf (stderr, " pic-ref=%3d", HALF_PIC_NUMBER_REFS - prev_half_pic_refs);
4436 prev_half_pic_refs = HALF_PIC_NUMBER_REFS;
4437 }
4438
4439 fputc ('\n', stderr);
4440 }
4441
4442 /* Reset state info for each function. */
4443 inside_function = FALSE;
4444 ignore_line_number = FALSE;
4445 dslots_load_total = 0;
4446 dslots_jump_total = 0;
4447 dslots_load_filled = 0;
4448 dslots_jump_filled = 0;
4449 num_refs[0] = 0;
4450 num_refs[1] = 0;
4451 num_refs[2] = 0;
4452 mips_load_reg = (rtx)0;
4453 mips_load_reg2 = (rtx)0;
4454 current_frame_info = zero_frame_info;
4455
4456 /* Restore the output file if optimizing the GP (optimizing the GP causes
4457 the text to be diverted to a tempfile, so that data decls come before
4458 references to the data). */
4459
4460 if (TARGET_GP_OPT)
4461 asm_out_file = asm_out_data_file;
4462 }
4463
4464 \f
4465 /* Expand the epilogue into a bunch of separate insns. */
4466
4467 void
4468 mips_expand_epilogue ()
4469 {
4470 int tsize = current_frame_info.total_size;
4471 rtx tsize_rtx = GEN_INT (tsize);
4472
4473 if (tsize > 32767)
4474 {
4475 rtx tmp_rtx = gen_rtx (REG, SImode, MIPS_TEMP1_REGNUM);
4476 emit_move_insn (tmp_rtx, tsize_rtx);
4477 tsize_rtx = tmp_rtx;
4478 }
4479
4480 if (tsize > 0)
4481 {
4482 if (frame_pointer_needed)
4483 emit_insn (gen_movsi (stack_pointer_rtx, frame_pointer_rtx));
4484
4485 save_restore_insns (FALSE);
4486
4487 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, tsize_rtx));
4488 }
4489
4490 emit_jump_insn (gen_return_internal (gen_rtx (REG, Pmode, GP_REG_FIRST+31)));
4491 }
4492
4493 \f
4494 /* Define the number of delay slots needed for the function epilogue.
4495
4496 On the mips, we need a slot if either no stack has been allocated,
4497 or the only register saved is the return register. */
4498
4499 int
4500 mips_epilogue_delay_slots ()
4501 {
4502 if (!current_frame_info.initialized)
4503 (void) compute_frame_size (get_frame_size ());
4504
4505 if (current_frame_info.total_size == 0)
4506 return 1;
4507
4508 if (current_frame_info.mask == (1 << 31) && current_frame_info.fmask == 0)
4509 return 1;
4510
4511 return 0;
4512 }
4513
4514 \f
4515 /* Return true if this function is known to have a null epilogue.
4516 This allows the optimizer to omit jumps to jumps if no stack
4517 was created. */
4518
4519 int
4520 simple_epilogue_p ()
4521 {
4522 if (!reload_completed)
4523 return 0;
4524
4525 if (current_frame_info.initialized)
4526 return current_frame_info.total_size == 0;
4527
4528 return (compute_frame_size (get_frame_size ())) == 0;
4529 }