OSDN Git Service

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