OSDN Git Service

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