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