OSDN Git Service

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