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