1 /* Subroutines for insn-output.c for MIPS
2 Contributed by A. Lichnewsky, lich@inria.inria.fr.
3 Changes by Michael Meissner, meissner@osf.org.
4 Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc.
6 This file is part of GNU CC.
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to
20 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
25 #include "hard-reg-set.h"
27 #include "insn-config.h"
28 #include "conditions.h"
29 #include "insn-flags.h"
30 #include "insn-attr.h"
31 #include "insn-codes.h"
35 #undef MAX /* sys/param.h may also define these */
40 #include <sys/types.h>
53 #if defined(USG) || defined(NO_STAB_H)
54 #include "gstab.h" /* If doing DBX on sysV, use our own stab.h. */
56 #include <stab.h> /* On BSD, use the system's stab.h. */
60 #define STAB_CODE_TYPE enum __stab_debug_code
62 #define STAB_CODE_TYPE int
67 extern char *getenv ();
68 extern char *mktemp ();
70 extern rtx adj_offsettable_operand ();
71 extern rtx copy_to_reg ();
74 extern tree lookup_name ();
75 extern void pfatal_with_name ();
76 extern void warning ();
78 extern rtx gen_addsi3 ();
79 extern rtx gen_andsi3 ();
80 extern rtx gen_beq ();
81 extern rtx gen_bne ();
82 extern rtx gen_cmpsi ();
83 extern rtx gen_indirect_jump ();
84 extern rtx gen_iorsi3 ();
85 extern rtx gen_jump ();
86 extern rtx gen_movhi ();
87 extern rtx gen_movqi ();
88 extern rtx gen_movsi ();
89 extern rtx gen_movsi_ulw ();
90 extern rtx gen_movsi_usw ();
91 extern rtx gen_movstrsi_internal ();
92 extern rtx gen_return_internal ();
93 extern rtx gen_subsi3 ();
95 extern tree current_function_decl;
96 extern FILE *asm_out_file;
98 /* Enumeration for all of the relational tests, so that we can build
99 arrays indexed by the test type, and not worry about the order
116 /* Global variables for machine-dependent things. */
118 /* Threshold for data being put into the small data/bss area, instead
119 of the normal data area (references to the small data/bss area take
120 1 instruction, and use the global pointer, references to the normal
121 data area takes 2 instructions). */
122 int mips_section_threshold = -1;
124 /* Count the number of .file directives, so that .loc is up to date. */
125 int num_source_filenames = 0;
127 /* Count of the number of functions created so far, in order to make
128 unique labels for omitting the frame pointer. */
129 int number_functions_processed = 0;
131 /* Count the number of sdb related labels are generated (to find block
132 start and end boundaries). */
133 int sdb_label_count = 0;
135 /* Next label # for each statment for Silicon Graphics IRIS systems. */
138 /* Non-zero if inside of a function, because the stupid MIPS asm can't
139 handle .files inside of functions. */
140 int inside_function = 0;
142 /* Files to separate the text and the data output, so that all of the data
143 can be emitted before the text, which will mean that the assembler will
144 generate smaller code, based on the global pointer. */
145 FILE *asm_out_data_file;
146 FILE *asm_out_text_file;
148 /* Linked list of all externals that are to be emitted when optimizing
149 for the global pointer if they haven't been declared by the end of
150 the program with an appropriate .comm or initialization. */
153 struct extern_list *next; /* next external */
154 char *name; /* name of the external */
155 int size; /* size in bytes */
158 /* Name of the file containing the current function. */
159 char *current_function_file = "";
161 /* Warning given that Mips ECOFF can't support changing files
162 within a function. */
163 int file_in_function_warning = FALSE;
165 /* Whether to suppress issuing .loc's because the user attempted
166 to change the filename within a function. */
167 int ignore_line_number = FALSE;
169 /* Number of nested .set noreorder, noat, nomacro, and volatile requests. */
175 /* The next branch instruction is a branch likely, not branch normal. */
176 int mips_branch_likely;
178 /* Count of delay slots and how many are filled. */
179 int dslots_load_total;
180 int dslots_load_filled;
181 int dslots_jump_total;
182 int dslots_jump_filled;
184 /* # of nops needed by previous insn */
185 int dslots_number_nops;
187 /* Number of 1/2/3 word references to data items (ie, not jal's). */
190 /* registers to check for load delay */
191 rtx mips_load_reg, mips_load_reg2, mips_load_reg3, mips_load_reg4;
193 /* Cached operands, and operator to compare for use in set/branch on
197 /* what type of branch to use */
198 enum cmp_type branch_type;
200 /* which cpu are we scheduling for */
201 enum processor_type mips_cpu;
203 /* which instruction set architecture to use. */
206 /* Strings to hold which cpu and instruction set architecture to use. */
207 char *mips_cpu_string; /* for -mcpu=<xxx> */
208 char *mips_isa_string; /* for -mips{1,2,3} */
210 /* Array to RTX class classification. At present, we care about
211 whether the operator is an add-type operator, or a divide/modulus,
212 and if divide/modulus, whether it is unsigned. This is for the
214 char mips_rtx_classify[NUM_RTX_CODE];
216 /* Array giving truth value on whether or not a given hard register
217 can support a given mode. */
218 char mips_hard_regno_mode_ok[(int)MAX_MACHINE_MODE][FIRST_PSEUDO_REGISTER];
220 /* Current frame information calculated by compute_frame_size. */
221 struct mips_frame_info current_frame_info;
223 /* Zero structure to initialize current_frame_info. */
224 struct mips_frame_info zero_frame_info;
226 /* Temporary filename used to buffer .text until end of program
228 static char *temp_filename;
230 /* List of all MIPS punctuation characters used by print_operand. */
231 char mips_print_operand_punct[256];
233 /* Map GCC register number to debugger register number. */
234 int mips_dbx_regno[FIRST_PSEUDO_REGISTER];
236 /* Buffer to use to enclose a load/store operation with %{ %} to
237 turn on .set volatile. */
238 static char volatile_buffer[60];
240 /* Hardware names for the registers. If -mrnames is used, this
241 will be overwritten with mips_sw_reg_names. */
243 char mips_reg_names[][8] =
245 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
246 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
247 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
248 "$24", "$25", "$26", "$27", "$28", "$sp", "$fp", "$31",
249 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
250 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
251 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
252 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
256 /* Mips software names for the registers, used to overwrite the
257 mips_reg_names array. */
259 char mips_sw_reg_names[][8] =
261 "$0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
262 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
263 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
264 "t8", "t9", "k0", "k1", "gp", "sp", "$fp", "ra",
265 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
266 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
267 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
268 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
272 /* Map hard register number to register class */
273 enum reg_class mips_regno_to_class[] =
275 GR_REGS, GR_REGS, GR_REGS, GR_REGS,
276 GR_REGS, GR_REGS, GR_REGS, GR_REGS,
277 GR_REGS, GR_REGS, GR_REGS, GR_REGS,
278 GR_REGS, GR_REGS, GR_REGS, GR_REGS,
279 GR_REGS, GR_REGS, GR_REGS, GR_REGS,
280 GR_REGS, GR_REGS, GR_REGS, GR_REGS,
281 GR_REGS, GR_REGS, GR_REGS, GR_REGS,
282 GR_REGS, GR_REGS, GR_REGS, GR_REGS,
283 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
284 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
285 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
286 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
287 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
288 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
289 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
290 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
291 HI_REG, LO_REG, ST_REGS
294 /* Map register constraint character to register class. */
295 enum reg_class mips_char_to_class[256] =
297 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
298 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
299 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
300 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
301 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
302 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
303 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
304 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
305 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
306 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
307 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
308 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
309 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
310 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
311 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
312 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
313 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
314 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
315 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
316 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
317 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
318 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
319 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
320 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
321 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
322 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
323 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
324 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
325 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
326 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
327 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
328 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
329 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
330 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
331 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
332 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
333 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
334 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
335 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
336 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
337 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
338 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
339 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
340 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
341 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
342 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
343 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
344 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
345 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
346 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
347 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
348 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
349 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
350 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
351 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
352 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
353 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
354 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
355 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
356 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
357 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
358 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
359 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
360 NO_REGS, NO_REGS, NO_REGS, NO_REGS,
364 /* Return truth value of whether OP can be used as an operands
365 where a register or 16 bit unsigned integer is needed. */
368 uns_arith_operand (op, mode)
370 enum machine_mode mode;
372 if (GET_CODE (op) == CONST_INT && SMALL_INT_UNSIGNED (op))
375 return register_operand (op, mode);
378 /* Return truth value of whether OP can be used as an operands
379 where a 16 bit integer is needed */
382 arith_operand (op, mode)
384 enum machine_mode mode;
386 if (GET_CODE (op) == CONST_INT && SMALL_INT (op))
389 return register_operand (op, mode);
392 /* Return truth value of whether OP can be used as an operand in a two
393 address arithmetic insn (such as set 123456,%o4) of mode MODE. */
396 arith32_operand (op, mode)
398 enum machine_mode mode;
400 if (GET_CODE (op) == CONST_INT)
403 return register_operand (op, mode);
406 /* Return truth value of whether OP is a integer which fits in 16 bits */
411 enum machine_mode mode;
413 return (GET_CODE (op) == CONST_INT && SMALL_INT (op));
416 /* Return truth value of whether OP is an integer which is too big to
417 be loaded with one instruction. */
422 enum machine_mode mode;
426 if (GET_CODE (op) != CONST_INT)
430 if ((value & ~0x0000ffff) == 0) /* ior reg,$r0,value */
433 if (((unsigned long)(value + 32768)) <= 32767) /* subu reg,$r0,value */
436 if ((value & 0xffff0000) == value) /* lui reg,value>>16 */
442 /* Return truth value of whether OP is a register or the constant 0. */
445 reg_or_0_operand (op, mode)
447 enum machine_mode mode;
449 switch (GET_CODE (op))
455 return (INTVAL (op) == 0);
458 if (CONST_DOUBLE_HIGH (op) != 0 || CONST_DOUBLE_LOW (op) != 0)
465 return register_operand (op, mode);
471 /* Return truth value of whether OP is one of the special multiply/divide
472 registers (hi, lo). */
475 md_register_operand (op, mode)
477 enum machine_mode mode;
479 return (GET_MODE_CLASS (mode) == MODE_INT
480 && GET_CODE (op) == REG
481 && MD_REG_P (REGNO (op)));
484 /* Return truth value of whether OP is the FP status register. */
487 fpsw_register_operand (op, mode)
489 enum machine_mode mode;
491 return (GET_CODE (op) == REG && ST_REG_P (REGNO (op)));
494 /* Return truth value if a CONST_DOUBLE is ok to be a legitimate constant. */
497 mips_const_double_ok (op, mode)
499 enum machine_mode mode;
501 if (GET_CODE (op) != CONST_DOUBLE)
507 if (mode != SFmode && mode != DFmode)
510 if (CONST_DOUBLE_HIGH (op) == 0 && CONST_DOUBLE_LOW (op) == 0)
513 #if HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT
514 if (TARGET_MIPS_AS) /* gas doesn't like li.d/li.s yet */
516 union { double d; int i[2]; } u;
519 u.i[0] = CONST_DOUBLE_LOW (op);
520 u.i[1] = CONST_DOUBLE_HIGH (op);
524 return FALSE; /* NAN */
529 /* Rather than trying to get the accuracy down to the last bit,
530 just use approximate ranges. */
532 if (mode == DFmode && d > 1.0e-300 && d < 1.0e300)
535 if (mode == SFmode && d > 1.0e-38 && d < 1.0e+38)
543 /* Return truth value if a memory operand fits in a single instruction
544 (ie, register + small offset). */
547 simple_memory_operand (op, mode)
549 enum machine_mode mode;
551 rtx addr, plus0, plus1;
553 /* Eliminate non-memory operations */
554 if (GET_CODE (op) != MEM)
557 /* dword operations really put out 2 instructions, so eliminate them. */
558 if (GET_MODE_SIZE (GET_MODE (op)) > (HAVE_64BIT_P () ? 8 : 4))
561 /* Decode the address now. */
563 switch (GET_CODE (addr))
572 return SMALL_INT (op);
575 plus0 = XEXP (addr, 0);
576 plus1 = XEXP (addr, 1);
577 if (GET_CODE (plus0) == REG
578 && GET_CODE (plus1) == CONST_INT
579 && SMALL_INT (plus1))
582 else if (GET_CODE (plus1) == REG
583 && GET_CODE (plus0) == CONST_INT
584 && SMALL_INT (plus0))
591 /* We used to allow small symbol refs here (ie, stuff in .sdata
592 or .sbss), but this causes some bugs in G++. Also, it won't
593 interfere if the MIPS linker rewrites the store instruction
594 because the function is PIC. */
596 case LABEL_REF: /* never gp relative */
600 /* If -G 0, we can never have a GP relative memory operation.
601 Also, save some time if not optimizing. */
602 if (mips_section_threshold == 0 || !optimize || !TARGET_GP_OPT)
606 rtx offset = const0_rtx;
607 addr = eliminate_constant_term (addr, &offset);
608 if (GET_CODE (op) != SYMBOL_REF)
611 /* let's be paranoid.... */
612 if (INTVAL (offset) < 0 || INTVAL (offset) > 0xffff)
618 return SYMBOL_REF_FLAG (addr);
625 /* Return true if the code of this rtx pattern is EQ or NE. */
628 equality_op (op, mode)
630 enum machine_mode mode;
632 if (mode != GET_MODE (op))
635 return (classify_op (op, mode) & CLASS_EQUALITY_OP) != 0;
638 /* Return true if the code is a relational operations (EQ, LE, etc.) */
643 enum machine_mode mode;
645 if (mode != GET_MODE (op))
648 return (classify_op (op, mode) & CLASS_CMP_OP) != 0;
652 /* Genrecog does not take the type of match_operator into consideration,
653 and would complain about two patterns being the same if the same
654 function is used, so make it believe they are different. */
659 enum machine_mode mode;
661 if (mode != GET_MODE (op))
664 return (classify_op (op, mode) & CLASS_CMP_OP) != 0;
667 /* Return true if the code is an unsigned relational operations (LEU, etc.) */
672 enum machine_mode mode;
674 if (mode != GET_MODE (op))
677 return (classify_op (op, mode) & CLASS_UNS_CMP_OP) == CLASS_UNS_CMP_OP;
680 /* Return true if the code is a relational operation FP can use. */
685 enum machine_mode mode;
687 if (mode != GET_MODE (op))
690 return (classify_op (op, mode) & CLASS_FCMP_OP) != 0;
694 /* Return true if the operand is either the PC or a label_ref. */
697 pc_or_label_operand (op, mode)
699 enum machine_mode mode;
704 if (GET_CODE (op) == LABEL_REF)
711 /* Return an operand string if the given instruction's delay slot or
712 wrap it in a .set noreorder section. This is for filling delay
713 slots on load type instructions under GAS, which does no reordering
714 on its own. For the MIPS assembler, all we do is update the filled
715 delay slot statistics.
717 We assume that operands[0] is the target register that is set.
719 In order to check the next insn, most of this functionality is moved
720 to FINAL_PRESCAN_INSN, and we just set the global variables that
724 mips_fill_delay_slot (ret, type, operands, cur_insn)
725 char *ret; /* normal string to return */
726 enum delay_type type; /* type of delay */
727 rtx operands[]; /* operands to use */
728 rtx cur_insn; /* current insn */
730 register rtx set_reg;
731 register enum machine_mode mode;
732 register rtx next_insn = (cur_insn) ? NEXT_INSN (cur_insn) : (rtx)0;
733 register int num_nops;
735 if (type == DELAY_LOAD || type == DELAY_FCMP)
738 else if (type == DELAY_HILO)
744 /* Make sure that we don't put nop's after labels. */
745 next_insn = NEXT_INSN (cur_insn);
746 while (next_insn != (rtx)0 && GET_CODE (next_insn) == NOTE)
747 next_insn = NEXT_INSN (next_insn);
749 dslots_load_total += num_nops;
750 if (TARGET_DEBUG_F_MODE
752 || type == DELAY_NONE
753 || operands == (rtx *)0
754 || cur_insn == (rtx)0
755 || next_insn == (rtx)0
756 || GET_CODE (next_insn) == CODE_LABEL
757 || (set_reg = operands[0]) == (rtx)0)
759 dslots_number_nops = 0;
760 mips_load_reg = (rtx)0;
761 mips_load_reg2 = (rtx)0;
762 mips_load_reg3 = (rtx)0;
763 mips_load_reg4 = (rtx)0;
767 set_reg = operands[0];
768 if (set_reg == (rtx)0)
771 while (GET_CODE (set_reg) == SUBREG)
772 set_reg = SUBREG_REG (set_reg);
774 mode = GET_MODE (set_reg);
775 dslots_number_nops = num_nops;
776 mips_load_reg = set_reg;
777 mips_load_reg2 = (mode == DImode || mode == DFmode)
778 ? gen_rtx (REG, SImode, REGNO (set_reg) + 1)
781 if (type == DELAY_HILO)
783 mips_load_reg3 = gen_rtx (REG, SImode, MD_REG_FIRST);
784 mips_load_reg4 = gen_rtx (REG, SImode, MD_REG_FIRST+1);
792 if (TARGET_GAS && set_noreorder++ == 0)
793 fputs ("\t.set\tnoreorder\n", asm_out_file);
799 /* Determine whether a memory reference takes one (based off of the GP pointer),
800 two (normal), or three (label + reg) instructions, and bump the appropriate
801 counter for -mstats. */
804 mips_count_memory_refs (op, num)
810 rtx addr, plus0, plus1;
811 enum rtx_code code0, code1;
814 if (TARGET_DEBUG_B_MODE)
816 fprintf (stderr, "\n========== mips_count_memory_refs:\n");
820 /* Skip MEM if passed, otherwise handle movsi of address. */
821 addr = (GET_CODE (op) != MEM) ? op : XEXP (op, 0);
823 /* Loop, going through the address RTL */
827 switch (GET_CODE (addr))
837 plus0 = XEXP (addr, 0);
838 plus1 = XEXP (addr, 1);
839 code0 = GET_CODE (plus0);
840 code1 = GET_CODE (plus1);
850 if (code0 == CONST_INT)
865 if (code1 == CONST_INT)
872 if (code0 == SYMBOL_REF || code0 == LABEL_REF || code0 == CONST)
879 if (code1 == SYMBOL_REF || code1 == LABEL_REF || code1 == CONST)
889 n_words = 2; /* always 2 words */
893 addr = XEXP (addr, 0);
898 n_words = SYMBOL_REF_FLAG (addr) ? 1 : 2;
907 n_words += additional;
911 num_refs[n_words-1] += num;
915 /* Return the appropriate instructions to move one operand to another. */
918 mips_move_1word (operands, insn, unsignedp)
924 rtx op0 = operands[0];
925 rtx op1 = operands[1];
926 enum rtx_code code0 = GET_CODE (op0);
927 enum rtx_code code1 = GET_CODE (op1);
928 enum machine_mode mode = GET_MODE (op0);
929 int subreg_word0 = 0;
930 int subreg_word1 = 0;
931 enum delay_type delay = DELAY_NONE;
933 while (code0 == SUBREG)
935 subreg_word0 += SUBREG_WORD (op0);
936 op0 = SUBREG_REG (op0);
937 code0 = GET_CODE (op0);
940 while (code1 == SUBREG)
942 subreg_word1 += SUBREG_WORD (op1);
943 op1 = SUBREG_REG (op1);
944 code1 = GET_CODE (op1);
949 int regno0 = REGNO (op0) + subreg_word0;
953 int regno1 = REGNO (op1) + subreg_word1;
955 /* Just in case, don't do anything for assigning a register
956 to itself, unless we are filling a delay slot. */
957 if (regno0 == regno1 && set_nomacro == 0)
960 else if (GP_REG_P (regno0))
962 if (GP_REG_P (regno1))
965 else if (MD_REG_P (regno1))
974 if (FP_REG_P (regno1))
977 else if (regno1 == FPSW_REGNUM)
978 ret = "cfc1\t%0,$31";
982 else if (FP_REG_P (regno0))
984 if (GP_REG_P (regno1))
990 if (FP_REG_P (regno1))
991 ret = "mov.s\t%0,%1";
994 else if (MD_REG_P (regno0))
996 if (GP_REG_P (regno1))
1003 else if (regno0 == FPSW_REGNUM)
1005 if (GP_REG_P (regno1))
1008 ret = "ctc1\t%0,$31";
1013 else if (code1 == MEM)
1018 mips_count_memory_refs (op1, 1);
1020 if (GP_REG_P (regno0))
1022 /* For loads, use the mode of the memory item, instead of the
1023 target, so zero/sign extend can use this code as well. */
1024 switch (GET_MODE (op1))
1027 case SFmode: ret = "lw\t%0,%1"; break;
1028 case SImode: ret = "lw\t%0,%1"; break;
1029 case HImode: ret = (unsignedp) ? "lhu\t%0,%1" : "lh\t%0,%1"; break;
1030 case QImode: ret = (unsignedp) ? "lbu\t%0,%1" : "lb\t%0,%1"; break;
1034 else if (FP_REG_P (regno0) && (mode == SImode || mode == SFmode))
1037 if (ret != (char *)0 && MEM_VOLATILE_P (op1))
1039 int i = strlen (ret);
1040 if (i > sizeof (volatile_buffer) - sizeof ("%{%}"))
1043 sprintf (volatile_buffer, "%%{%s%%}", ret);
1044 ret = volatile_buffer;
1048 else if (code1 == CONST_INT)
1050 if (INTVAL (op1) == 0)
1052 if (GP_REG_P (regno0))
1053 ret = "move\t%0,%z1";
1055 else if (FP_REG_P (regno0))
1058 ret = "mtc1\t%z1,%0";
1062 else if (GP_REG_P (regno0))
1063 ret = (INTVAL (op1) < 0) ? "li\t%0,%1\t\t\t# %X1" : "li\t%0,%X1\t\t# %1";
1066 else if (code1 == CONST_DOUBLE && mode == SFmode)
1068 if (CONST_DOUBLE_HIGH (op1) == 0 && CONST_DOUBLE_LOW (op1) == 0)
1070 if (GP_REG_P (regno0))
1071 ret = "move\t%0,%.";
1073 else if (FP_REG_P (regno0))
1076 ret = "mtc1\t%.,%0";
1083 ret = "li.s\t%0,%1";
1087 else if (code1 == LABEL_REF)
1090 mips_count_memory_refs (op1, 1);
1095 else if (code1 == SYMBOL_REF || code1 == CONST)
1097 if (HALF_PIC_P () && CONSTANT_P (op1) && HALF_PIC_ADDRESS_P (op1))
1099 rtx offset = const0_rtx;
1101 if (GET_CODE (op1) == CONST)
1102 op1 = eliminate_constant_term (XEXP (op1, 0), &offset);
1104 if (GET_CODE (op1) == SYMBOL_REF)
1106 operands[2] = HALF_PIC_PTR (op1);
1109 mips_count_memory_refs (operands[2], 1);
1111 if (INTVAL (offset) == 0)
1118 dslots_load_total++;
1119 operands[3] = offset;
1120 ret = (SMALL_INT (offset))
1121 ? "lw\t%0,%2%#\n\tadd\t%0,%0,%3"
1122 : "lw\t%0,%2%#\n\t%[li\t%@,%3\n\tadd\t%0,%0,%@%]";
1129 mips_count_memory_refs (op1, 1);
1135 else if (code1 == PLUS)
1137 rtx add_op0 = XEXP (op1, 0);
1138 rtx add_op1 = XEXP (op1, 1);
1140 if (GET_CODE (XEXP (op1, 1)) == REG && GET_CODE (XEXP (op1, 0)) == CONST_INT)
1142 add_op0 = XEXP (op1, 1); /* reverse operands */
1143 add_op1 = XEXP (op1, 0);
1146 operands[2] = add_op0;
1147 operands[3] = add_op1;
1148 ret = "add%:\t%0,%2,%3";
1152 else if (code0 == MEM)
1155 mips_count_memory_refs (op0, 1);
1159 int regno1 = REGNO (op1) + subreg_word1;
1161 if (GP_REG_P (regno1))
1166 case SFmode: ret = "sw\t%1,%0"; break;
1167 case SImode: ret = "sw\t%1,%0"; break;
1168 case HImode: ret = "sh\t%1,%0"; break;
1169 case QImode: ret = "sb\t%1,%0"; break;
1173 else if (FP_REG_P (regno1) && (mode == SImode || mode == SFmode))
1177 else if (code1 == CONST_INT && INTVAL (op1) == 0)
1182 case SFmode: ret = "sw\t%z1,%0"; break;
1183 case SImode: ret = "sw\t%z1,%0"; break;
1184 case HImode: ret = "sh\t%z1,%0"; break;
1185 case QImode: ret = "sb\t%z1,%0"; break;
1189 else if (code1 == CONST_DOUBLE && CONST_DOUBLE_HIGH (op1) == 0 && CONST_DOUBLE_LOW (op1) == 0)
1194 case SFmode: ret = "sw\t%.,%0"; break;
1195 case SImode: ret = "sw\t%.,%0"; break;
1196 case HImode: ret = "sh\t%.,%0"; break;
1197 case QImode: ret = "sb\t%.,%0"; break;
1201 if (ret != (char *)0 && MEM_VOLATILE_P (op0))
1203 int i = strlen (ret);
1204 if (i > sizeof (volatile_buffer) - sizeof ("%{%}"))
1207 sprintf (volatile_buffer, "%%{%s%%}", ret);
1208 ret = volatile_buffer;
1212 if (ret == (char *)0)
1214 abort_with_insn (insn, "Bad move");
1218 if (delay != DELAY_NONE)
1219 return mips_fill_delay_slot (ret, delay, operands, insn);
1225 /* Return the appropriate instructions to move 2 words */
1228 mips_move_2words (operands, insn)
1233 rtx op0 = operands[0];
1234 rtx op1 = operands[1];
1235 enum rtx_code code0 = GET_CODE (operands[0]);
1236 enum rtx_code code1 = GET_CODE (operands[1]);
1237 int subreg_word0 = 0;
1238 int subreg_word1 = 0;
1239 enum delay_type delay = DELAY_NONE;
1241 while (code0 == SUBREG)
1243 subreg_word0 += SUBREG_WORD (op0);
1244 op0 = SUBREG_REG (op0);
1245 code0 = GET_CODE (op0);
1248 while (code1 == SUBREG)
1250 subreg_word1 += SUBREG_WORD (op1);
1251 op1 = SUBREG_REG (op1);
1252 code1 = GET_CODE (op1);
1257 int regno0 = REGNO (op0) + subreg_word0;
1261 int regno1 = REGNO (op1) + subreg_word1;
1263 /* Just in case, don't do anything for assigning a register
1264 to itself, unless we are filling a delay slot. */
1265 if (regno0 == regno1 && set_nomacro == 0)
1268 else if (FP_REG_P (regno0))
1270 if (FP_REG_P (regno1))
1271 ret = "mov.d\t%0,%1";
1276 ret = (TARGET_FLOAT64)
1278 : "mtc1\t%L1,%0\n\tmtc1\t%M1,%D0";
1282 else if (FP_REG_P (regno1))
1285 ret = (TARGET_FLOAT64)
1287 : "mfc1\t%L0,%1\n\tmfc1\t%M0,%D1";
1290 else if (MD_REG_P (regno0) && GP_REG_P (regno1))
1293 ret = "mthi\t%M1\n\tmtlo\t%L1";
1296 else if (GP_REG_P (regno0) && MD_REG_P (regno1))
1299 ret = "mfhi\t%M0\n\tmflo\t%L0";
1302 else if (regno0 != (regno1+1))
1303 ret = "move\t%0,%1\n\tmove\t%D0,%D1";
1306 ret = "move\t%D0,%D1\n\tmove\t%0,%1";
1309 else if (code1 == CONST_DOUBLE)
1311 if (CONST_DOUBLE_HIGH (op1) != 0 || CONST_DOUBLE_LOW (op1) != 0)
1313 if (GET_MODE (op1) == DFmode)
1316 ret = "li.d\t%0,%1";
1321 operands[2] = GEN_INT (CONST_DOUBLE_LOW (op1));
1322 operands[3] = GEN_INT (CONST_DOUBLE_HIGH (op1));
1323 ret = "li\t%M0,%3\n\tli\t%L0,%2";
1329 if (GP_REG_P (regno0))
1330 ret = "move\t%0,%.\n\tmove\t%D0,%.";
1332 else if (FP_REG_P (regno0))
1335 ret = (TARGET_FLOAT64)
1337 : "mtc1\t%.,%0\n\tmtc1\t%.,%D0";
1342 else if (code1 == CONST_INT && INTVAL (op1) == 0)
1344 if (GP_REG_P (regno0))
1345 ret = "move\t%0,%.\n\tmove\t%D0,%.";
1347 else if (FP_REG_P (regno0))
1350 ret = (TARGET_FLOAT64)
1352 : "mtc1\t%.,%0\n\tmtc1\t%.,%D0";
1356 else if (code1 == CONST_INT && GET_MODE (op0) == DImode && GP_REG_P (regno0))
1358 operands[2] = GEN_INT (INTVAL (operands[1]) >= 0 ? 0 : -1);
1359 ret = "li\t%M0,%2\n\tli\t%L0,%1";
1362 else if (code1 == MEM)
1367 mips_count_memory_refs (op1, 2);
1369 if (FP_REG_P (regno0))
1372 else if (offsettable_address_p (1, DFmode, XEXP (op1, 0)))
1374 operands[2] = adj_offsettable_operand (op1, 4);
1375 if (reg_mentioned_p (op0, op1))
1376 ret = "lw\t%D0,%2\n\tlw\t%0,%1";
1378 ret = "lw\t%0,%1\n\tlw\t%D0,%2";
1381 if (ret != (char *)0 && MEM_VOLATILE_P (op1))
1383 int i = strlen (ret);
1384 if (i > sizeof (volatile_buffer) - sizeof ("%{%}"))
1387 sprintf (volatile_buffer, "%%{%s%%}", ret);
1388 ret = volatile_buffer;
1393 else if (code0 == MEM)
1397 int regno1 = REGNO (op1) + subreg_word1;
1399 if (FP_REG_P (regno1))
1402 else if (offsettable_address_p (1, DFmode, XEXP (op0, 0)))
1404 operands[2] = adj_offsettable_operand (op0, 4);
1405 ret = "sw\t%1,%0\n\tsw\t%D1,%2";
1409 else if (code1 == CONST_DOUBLE
1410 && CONST_DOUBLE_HIGH (op1) == 0
1411 && CONST_DOUBLE_LOW (op1) == 0
1412 && offsettable_address_p (1, DFmode, XEXP (op0, 0)))
1418 operands[2] = adj_offsettable_operand (op0, 4);
1419 ret = "sw\t%.,%0\n\tsw\t%.,%2";
1424 mips_count_memory_refs (op0, 2);
1426 if (ret != (char *)0 && MEM_VOLATILE_P (op0))
1428 int i = strlen (ret);
1429 if (i > sizeof (volatile_buffer) - sizeof ("%{%}"))
1432 sprintf (volatile_buffer, "%%{%s%%}", ret);
1433 ret = volatile_buffer;
1437 if (ret == (char *)0)
1439 abort_with_insn (insn, "Bad move");
1443 if (delay != DELAY_NONE)
1444 return mips_fill_delay_slot (ret, delay, operands, insn);
1450 /* Provide the costs of an addressing mode that contains ADDR.
1451 If ADDR is not a valid address, its cost is irrelevant. */
1454 mips_address_cost (addr)
1457 switch (GET_CODE (addr))
1471 rtx offset = const0_rtx;
1472 addr = eliminate_constant_term (addr, &offset);
1473 if (GET_CODE (addr) == LABEL_REF)
1476 if (GET_CODE (addr) != SYMBOL_REF)
1479 if (INTVAL (offset) < -32768 || INTVAL (offset) > 32767)
1485 return SYMBOL_REF_FLAG (addr) ? 1 : 2;
1489 register rtx plus0 = XEXP (addr, 0);
1490 register rtx plus1 = XEXP (addr, 1);
1492 if (GET_CODE (plus0) != REG && GET_CODE (plus1) == REG)
1494 plus0 = XEXP (addr, 1);
1495 plus1 = XEXP (addr, 0);
1498 if (GET_CODE (plus0) != REG)
1501 switch (GET_CODE (plus1))
1508 int value = INTVAL (plus1);
1509 return (value < -32768 || value > 32767) ? 2 : 1;
1517 return mips_address_cost (plus1) + 1;
1526 /* Make normal rtx_code into something we can index from an array */
1528 static enum internal_test
1529 map_test_to_internal_test (test_code)
1530 enum rtx_code test_code;
1532 enum internal_test test = ITEST_MAX;
1537 case EQ: test = ITEST_EQ; break;
1538 case NE: test = ITEST_NE; break;
1539 case GT: test = ITEST_GT; break;
1540 case GE: test = ITEST_GE; break;
1541 case LT: test = ITEST_LT; break;
1542 case LE: test = ITEST_LE; break;
1543 case GTU: test = ITEST_GTU; break;
1544 case GEU: test = ITEST_GEU; break;
1545 case LTU: test = ITEST_LTU; break;
1546 case LEU: test = ITEST_LEU; break;
1553 /* Generate the code to compare two integer values. The return value is:
1554 (reg:SI xx) The pseudo register the comparison is in
1555 (const_int 0) The comparison is always false
1556 (const_int 1) The comparison is always true
1557 (rtx)0 No register, generate a simple branch. */
1560 gen_int_relational (test_code, result, cmp0, cmp1, p_invert)
1561 enum rtx_code test_code; /* relational test (EQ, etc) */
1562 rtx result; /* result to store comp. or 0 if branch */
1563 rtx cmp0; /* first operand to compare */
1564 rtx cmp1; /* second operand to compare */
1565 int *p_invert; /* NULL or ptr to hold whether branch needs */
1566 /* to reverse its test */
1569 enum rtx_code test_code; /* code to use in instruction (LT vs. LTU) */
1570 int const_low; /* low bound of constant we can accept */
1571 int const_high; /* high bound of constant we can accept */
1572 int const_add; /* constant to add (convert LE -> LT) */
1573 int reverse_regs; /* reverse registers in test */
1574 int invert_const; /* != 0 if invert value if cmp1 is constant */
1575 int invert_reg; /* != 0 if invert value if cmp1 is register */
1578 static struct cmp_info info[ (int)ITEST_MAX ] = {
1580 { XOR, 0, 65535, 0, 0, 0, 0 }, /* EQ */
1581 { XOR, 0, 65535, 0, 0, 1, 1 }, /* NE */
1582 { LT, -32769, 32766, 1, 1, 1, 0 }, /* GT */
1583 { LT, -32768, 32767, 0, 0, 1, 1 }, /* GE */
1584 { LT, -32768, 32767, 0, 0, 0, 0 }, /* LT */
1585 { LT, -32769, 32766, 1, 1, 0, 1 }, /* LE */
1586 { LTU, -32769, 32766, 1, 1, 1, 0 }, /* GTU */
1587 { LTU, -32768, 32767, 0, 0, 1, 1 }, /* GEU */
1588 { LTU, -32768, 32767, 0, 0, 0, 0 }, /* LTU */
1589 { LTU, -32769, 32766, 1, 1, 0, 1 }, /* LEU */
1592 enum internal_test test;
1593 struct cmp_info *p_info;
1600 test = map_test_to_internal_test (test_code);
1601 if (test == ITEST_MAX)
1604 p_info = &info[ (int)test ];
1605 eqne_p = (p_info->test_code == XOR);
1607 /* See if the test is always true or false. */
1608 if ((GET_CODE (cmp0) == REG || GET_CODE (cmp0) == SUBREG)
1609 && GET_CODE (cmp1) == CONST_INT)
1611 HOST_WIDE_INT value = INTVAL (cmp1);
1614 if (test == ITEST_GEU && value == 0)
1617 else if (test == ITEST_LTU && value == 0)
1620 else if (!TARGET_INT64)
1622 if (test == ITEST_LTU && value == -1)
1625 else if (test == ITEST_GTU && value == -1)
1628 else if (test == ITEST_LEU && value == -1)
1631 else if (test == ITEST_GT && value == 0x7fffffff)
1634 else if (test == ITEST_LE && value == 0x7fffffff)
1637 else if (test == ITEST_LT && value == 0x80000000)
1640 else if (test == ITEST_GE && value == 0x80000000)
1644 if (truth != (rtx)0)
1646 if (result != (rtx)0)
1647 emit_move_insn (result, truth);
1653 /* Eliminate simple branches */
1654 branch_p = (result == (rtx)0);
1657 if (GET_CODE (cmp0) == REG || GET_CODE (cmp0) == SUBREG)
1659 /* Comparisons against zero are simple branches */
1660 if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0)
1663 /* Test for beq/bne. */
1668 /* allocate a pseudo to calculate the value in. */
1669 result = gen_reg_rtx (SImode);
1672 /* Make sure we can handle any constants given to us. */
1673 if (GET_CODE (cmp0) == CONST_INT)
1674 cmp0 = force_reg (SImode, cmp0);
1676 if (GET_CODE (cmp1) == CONST_INT)
1678 HOST_WIDE_INT value = INTVAL (cmp1);
1679 if (value < p_info->const_low || value > p_info->const_high)
1680 cmp1 = force_reg (SImode, cmp1);
1683 /* See if we need to invert the result. */
1684 invert = (GET_CODE (cmp1) == CONST_INT)
1685 ? p_info->invert_const
1686 : p_info->invert_reg;
1688 if (p_invert != (int *)0)
1694 /* Comparison to constants, may involve adding 1 to change a LT into LE.
1695 Comparison between two registers, may involve switching operands. */
1696 if (GET_CODE (cmp1) == CONST_INT)
1698 if (p_info->const_add != 0)
1699 cmp1 = GEN_INT (INTVAL (cmp1) + p_info->const_add);
1701 else if (p_info->reverse_regs)
1708 if (test == ITEST_NE && GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0)
1712 reg = (invert || eqne_p) ? gen_reg_rtx (SImode) : result;
1713 emit_move_insn (reg, gen_rtx (p_info->test_code, SImode, cmp0, cmp1));
1716 if (test == ITEST_NE)
1718 emit_move_insn (result, gen_rtx (GTU, SImode, reg, const0_rtx));
1722 else if (test == ITEST_EQ)
1724 reg2 = (invert) ? gen_reg_rtx (SImode) : result;
1725 emit_move_insn (reg2, gen_rtx (LTU, SImode, reg, const1_rtx));
1730 emit_move_insn (result, gen_rtx (XOR, SImode, reg, const1_rtx));
1736 /* Emit the common code for doing conditional branches.
1737 operand[0] is the label to jump to.
1738 The comparison operands are saved away by cmp{si,sf,df}. */
1741 gen_conditional_branch (operands, test_code)
1743 enum rtx_code test_code;
1745 static enum machine_mode mode_map[(int)CMP_MAX][(int)ITEST_MAX] = {
1760 CC_REV_FPmode, /* ne */
1772 CC_REV_FPmode, /* ne */
1784 enum machine_mode mode;
1785 enum cmp_type type = branch_type;
1786 rtx cmp0 = branch_cmp[0];
1787 rtx cmp1 = branch_cmp[1];
1788 rtx label1 = gen_rtx (LABEL_REF, VOIDmode, operands[0]);
1789 rtx label2 = pc_rtx;
1792 enum internal_test test = map_test_to_internal_test (test_code);
1794 if (test == ITEST_MAX)
1800 /* Get the machine mode to use (CCmode, CC_EQmode, CC_FPmode, or CC_REV_FPmode). */
1801 mode = mode_map[(int)type][(int)test];
1802 if (mode == VOIDmode)
1805 switch (branch_type)
1811 reg = gen_int_relational (test_code, (rtx)0, cmp0, cmp1, &invert);
1819 /* Make sure not non-zero constant if ==/!= */
1820 else if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) != 0)
1821 cmp1 = force_reg (SImode, cmp1);
1828 rtx reg = gen_rtx (REG, mode, FPSW_REGNUM);
1829 emit_insn (gen_rtx (SET, VOIDmode, reg, gen_rtx (test_code, mode, cmp0, cmp1)));
1837 /* Handle always true or always false cases directly */
1838 if (GET_CODE (cmp0) == CONST_INT && GET_CODE (cmp1) == CONST_INT)
1840 HOST_WIDE_INT sval0 = INTVAL (cmp0);
1841 HOST_WIDE_INT sval1 = INTVAL (cmp1);
1842 unsigned long uval0 = sval0;
1843 unsigned long uval1 = sval1;
1851 case EQ: truth = (sval0 == sval1); break;
1852 case NE: truth = (sval0 != sval1); break;
1853 case GT: truth = (sval0 > sval1); break;
1854 case GE: truth = (sval0 >= sval1); break;
1855 case LT: truth = (sval0 < sval1); break;
1856 case LE: truth = (sval0 <= sval1); break;
1857 case GTU: truth = (uval0 > uval1); break;
1858 case GEU: truth = (uval0 >= uval1); break;
1859 case LTU: truth = (uval0 < uval1); break;
1860 case LEU: truth = (uval0 <= uval1); break;
1867 emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx, label1));
1872 /* Generate the jump */
1879 emit_jump_insn (gen_rtx (SET, VOIDmode,
1881 gen_rtx (IF_THEN_ELSE, VOIDmode,
1882 gen_rtx (test_code, mode, cmp0, cmp1),
1889 abort_with_insn (gen_rtx (test_code, mode, cmp0, cmp1), "bad test");
1893 #define UNITS_PER_SHORT (SHORT_TYPE_SIZE / BITS_PER_UNIT)
1895 /* Internal code to generate the load and store of one word/short/byte.
1896 The load is emitted directly, and the store insn is returned. */
1900 block_move_load_store (dest_reg, src_reg, p_bytes, p_offset, align, orig_src)
1901 rtx src_reg; /* register holding source memory address */
1902 rtx dest_reg; /* register holding dest. memory address */
1903 int *p_bytes; /* pointer to # bytes remaining */
1904 int *p_offset; /* pointer to current offset */
1905 int align; /* alignment */
1906 rtx orig_src; /* original source for making a reg note */
1908 int bytes; /* # bytes remaining */
1909 int offset; /* offset to use */
1910 int size; /* size in bytes of load/store */
1911 enum machine_mode mode; /* mode to use for load/store */
1912 rtx reg; /* temporary register */
1913 rtx src_addr; /* source address */
1914 rtx dest_addr; /* destination address */
1915 rtx insn; /* insn of the load */
1916 rtx orig_src_addr; /* original source address */
1917 rtx (*load_func)(); /* function to generate load insn */
1918 rtx (*store_func)(); /* function to generate destination insn */
1921 if (bytes <= 0 || align <= 0)
1924 if (bytes >= UNITS_PER_WORD && align >= UNITS_PER_WORD)
1927 size = UNITS_PER_WORD;
1928 load_func = gen_movsi;
1929 store_func = gen_movsi;
1933 /* Don't generate unligned moves here, rather defer those to the
1934 general movestrsi_internal pattern. */
1935 else if (bytes >= UNITS_PER_WORD)
1938 size = UNITS_PER_WORD;
1939 load_func = gen_movsi_ulw;
1940 store_func = gen_movsi_usw;
1944 else if (bytes >= UNITS_PER_SHORT && align >= UNITS_PER_SHORT)
1947 size = UNITS_PER_SHORT;
1948 load_func = gen_movhi;
1949 store_func = gen_movhi;
1956 load_func = gen_movqi;
1957 store_func = gen_movqi;
1961 *p_offset = offset + size;
1962 *p_bytes = bytes - size;
1967 dest_addr = dest_reg;
1971 src_addr = gen_rtx (PLUS, Pmode, src_reg, GEN_INT (offset));
1972 dest_addr = gen_rtx (PLUS, Pmode, dest_reg, GEN_INT (offset));
1975 reg = gen_reg_rtx (mode);
1976 insn = emit_insn ((*load_func) (reg, gen_rtx (MEM, mode, src_addr)));
1977 orig_src_addr = XEXP (orig_src, 0);
1978 if (CONSTANT_P (orig_src_addr))
1979 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUIV,
1980 plus_constant (orig_src_addr, offset),
1983 return (*store_func) (gen_rtx (MEM, mode, dest_addr), reg);
1988 /* Write a series of loads/stores to move some bytes. Generate load/stores as follows:
2000 This way, no NOP's are needed, except at the end, and only
2001 two temp registers are needed. Two delay slots are used
2002 in deference to the R4000. */
2006 block_move_sequence (dest_reg, src_reg, bytes, align, orig_src)
2007 rtx dest_reg; /* register holding destination address */
2008 rtx src_reg; /* register holding source address */
2009 int bytes; /* # bytes to move */
2010 int align; /* max alignment to assume */
2011 rtx orig_src; /* original source for making a reg note */
2014 rtx prev2_store = (rtx)0;
2015 rtx prev_store = (rtx)0;
2016 rtx cur_store = (rtx)0;
2020 /* Is there a store to do? */
2022 emit_insn (prev2_store);
2024 prev2_store = prev_store;
2025 prev_store = cur_store;
2026 cur_store = block_move_load_store (dest_reg, src_reg,
2031 /* Finish up last three stores. */
2033 emit_insn (prev2_store);
2036 emit_insn (prev_store);
2039 emit_insn (cur_store);
2044 /* Write a loop to move a constant number of bytes. Generate load/stores as follows:
2050 temp<last> = src[MAX_MOVE_REGS-1];
2054 dest[MAX_MOVE_REGS-1] = temp<last>;
2055 src += MAX_MOVE_REGS;
2056 dest += MAX_MOVE_REGS;
2057 } while (src != final);
2059 This way, no NOP's are needed, and only MAX_MOVE_REGS+3 temp
2060 registers are needed.
2062 Aligned moves move MAX_MOVE_REGS*4 bytes every (2*MAX_MOVE_REGS)+3
2063 cycles, unaligned moves move MAX_MOVE_REGS*4 bytes every
2064 (4*MAX_MOVE_REGS)+3 cycles, assuming no cache misses. */
2066 #define MAX_MOVE_REGS 4
2067 #define MAX_MOVE_BYTES (MAX_MOVE_REGS * UNITS_PER_WORD)
2070 block_move_loop (dest_reg, src_reg, bytes, align, orig_src)
2071 rtx dest_reg; /* register holding destination address */
2072 rtx src_reg; /* register holding source address */
2073 int bytes; /* # bytes to move */
2074 int align; /* alignment */
2075 rtx orig_src; /* original source for making a reg note */
2077 rtx dest_mem = gen_rtx (MEM, BLKmode, dest_reg);
2078 rtx src_mem = gen_rtx (MEM, BLKmode, src_reg);
2079 rtx align_rtx = GEN_INT (align);
2085 if (bytes < 2*MAX_MOVE_BYTES)
2088 leftover = bytes % MAX_MOVE_BYTES;
2091 label = gen_label_rtx ();
2092 final_src = gen_reg_rtx (Pmode);
2093 bytes_rtx = GEN_INT (bytes);
2097 emit_insn (gen_movsi (final_src, bytes_rtx));
2098 emit_insn (gen_addsi3 (final_src, final_src, src_reg));
2101 emit_insn (gen_addsi3 (final_src, src_reg, bytes_rtx));
2105 bytes_rtx = GEN_INT (MAX_MOVE_BYTES);
2106 emit_insn (gen_movstrsi_internal (dest_mem, src_mem, bytes_rtx, align_rtx));
2107 emit_insn (gen_addsi3 (src_reg, src_reg, bytes_rtx));
2108 emit_insn (gen_addsi3 (dest_reg, dest_reg, bytes_rtx));
2109 emit_insn (gen_cmpsi (src_reg, final_src));
2110 emit_jump_insn (gen_bne (label));
2113 emit_insn (gen_movstrsi_internal (dest_mem, src_mem,
2119 /* Use a library function to move some bytes. */
2122 block_move_call (dest_reg, src_reg, bytes_rtx)
2127 #ifdef TARGET_MEM_FUNCTIONS
2128 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "memcpy"), 0,
2134 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "bcopy"), 0,
2143 /* Expand string/block move operations.
2145 operands[0] is the pointer to the destination.
2146 operands[1] is the pointer to the source.
2147 operands[2] is the number of bytes to move.
2148 operands[3] is the alignment. */
2151 expand_block_move (operands)
2154 rtx bytes_rtx = operands[2];
2155 rtx align_rtx = operands[3];
2156 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
2157 int bytes = (constp ? INTVAL (bytes_rtx) : 0);
2158 int align = INTVAL (align_rtx);
2159 rtx orig_src = operands[1];
2163 if (constp && bytes <= 0)
2166 if (align > UNITS_PER_WORD)
2167 align = UNITS_PER_WORD;
2169 /* Move the address into scratch registers. */
2170 dest_reg = copy_addr_to_reg (XEXP (operands[0], 0));
2171 src_reg = copy_addr_to_reg (XEXP (orig_src, 0));
2174 block_move_call (dest_reg, src_reg, bytes_rtx);
2177 else if (constp && bytes <= 3*align)
2178 block_move_sequence (dest_reg, src_reg, bytes, align, orig_src);
2181 else if (constp && bytes <= 2*MAX_MOVE_BYTES)
2182 emit_insn (gen_movstrsi_internal (gen_rtx (MEM, BLKmode, dest_reg),
2183 gen_rtx (MEM, BLKmode, src_reg),
2184 bytes_rtx, align_rtx));
2186 else if (constp && align >= UNITS_PER_WORD && optimize)
2187 block_move_loop (dest_reg, src_reg, bytes, align, orig_src);
2189 else if (constp && optimize)
2191 /* If the alignment is not word aligned, generate a test at
2192 runtime, to see whether things wound up aligned, and we
2193 can use the faster lw/sw instead ulw/usw. */
2195 rtx temp = gen_reg_rtx (Pmode);
2196 rtx aligned_label = gen_label_rtx ();
2197 rtx join_label = gen_label_rtx ();
2198 int leftover = bytes % MAX_MOVE_BYTES;
2202 emit_insn (gen_iorsi3 (temp, src_reg, dest_reg));
2203 emit_insn (gen_andsi3 (temp, temp, GEN_INT (UNITS_PER_WORD-1)));
2204 emit_insn (gen_cmpsi (temp, const0_rtx));
2205 emit_jump_insn (gen_beq (aligned_label));
2207 /* Unaligned loop. */
2208 block_move_loop (dest_reg, src_reg, bytes, 1, orig_src);
2209 emit_jump_insn (gen_jump (join_label));
2213 emit_label (aligned_label);
2214 block_move_loop (dest_reg, src_reg, bytes, UNITS_PER_WORD, orig_src);
2215 emit_label (join_label);
2217 /* Bytes at the end of the loop. */
2221 if (leftover <= 3*align)
2222 block_move_sequence (dest_reg, src_reg, leftover, align, orig_src);
2226 emit_insn (gen_movstrsi_internal (gen_rtx (MEM, BLKmode, dest_reg),
2227 gen_rtx (MEM, BLKmode, src_reg),
2234 block_move_call (dest_reg, src_reg, bytes_rtx);
2238 /* Emit load/stores for a small constant block_move.
2240 operands[0] is the memory address of the destination.
2241 operands[1] is the memory address of the source.
2242 operands[2] is the number of bytes to move.
2243 operands[3] is the alignment.
2244 operands[4] is a temp register.
2245 operands[5] is a temp register.
2247 operands[3+num_regs] is the last temp register.
2249 The block move type can be one of the following:
2250 BLOCK_MOVE_NORMAL Do all of the block move.
2251 BLOCK_MOVE_NOT_LAST Do all but the last store.
2252 BLOCK_MOVE_LAST Do just the last store. */
2255 output_block_move (insn, operands, num_regs, move_type)
2259 enum block_move_type move_type;
2261 rtx dest_reg = XEXP (operands[0], 0);
2262 rtx src_reg = XEXP (operands[1], 0);
2263 int bytes = INTVAL (operands[2]);
2264 int align = INTVAL (operands[3]);
2267 int use_lwl_lwr = FALSE;
2268 int last_operand = num_regs+4;
2273 char *load; /* load insn without nop */
2274 char *load_nop; /* load insn with trailing nop */
2275 char *store; /* store insn */
2276 char *final; /* if last_store used: NULL or swr */
2277 char *last_store; /* last store instruction */
2278 int offset; /* current offset */
2279 enum machine_mode mode; /* mode to use on (MEM) */
2282 /* Detect a bug in GCC, where it can give us a register
2283 the same as one of the addressing registers. */
2284 for (i = 4; i < last_operand; i++)
2286 if (reg_mentioned_p (operands[i], operands[0])
2287 || reg_mentioned_p (operands[i], operands[1]))
2289 abort_with_insn (insn, "register passed as address and temp register to block move");
2293 /* If we are given global or static addresses, and we would be
2294 emitting a few instructions, try to save time by using a
2295 temporary register for the pointer. */
2296 if (bytes > 2*align || move_type != BLOCK_MOVE_NORMAL)
2298 if (CONSTANT_P (src_reg))
2301 mips_count_memory_refs (operands[1], 1);
2303 src_reg = operands[ 3 + num_regs-- ];
2304 if (move_type != BLOCK_MOVE_LAST)
2306 xoperands[1] = operands[1];
2307 xoperands[0] = src_reg;
2308 output_asm_insn ("la\t%0,%1", xoperands);
2312 if (CONSTANT_P (dest_reg))
2315 mips_count_memory_refs (operands[0], 1);
2317 dest_reg = operands[ 3 + num_regs-- ];
2318 if (move_type != BLOCK_MOVE_LAST)
2320 xoperands[1] = operands[0];
2321 xoperands[0] = dest_reg;
2322 output_asm_insn ("la\t%0,%1", xoperands);
2327 if (num_regs > (sizeof (load_store) / sizeof (load_store[0])))
2328 num_regs = (sizeof (load_store) / sizeof (load_store[0]));
2330 else if (num_regs < 1)
2333 if (TARGET_GAS && move_type != BLOCK_MOVE_LAST && set_noreorder++ == 0)
2334 output_asm_insn (".set\tnoreorder", operands);
2338 load_store[num].offset = offset;
2340 if (bytes >= UNITS_PER_WORD && align >= UNITS_PER_WORD)
2342 load_store[num].load = "lw\t%0,%1";
2343 load_store[num].load_nop = "lw\t%0,%1%#";
2344 load_store[num].store = "sw\t%0,%1";
2345 load_store[num].last_store = "sw\t%0,%1";
2346 load_store[num].final = (char *)0;
2347 load_store[num].mode = SImode;
2348 offset += UNITS_PER_WORD;
2349 bytes -= UNITS_PER_WORD;
2352 else if (bytes >= UNITS_PER_WORD)
2354 #if BYTES_BIG_ENDIAN
2355 load_store[num].load = "lwl\t%0,%1\n\tlwr\t%0,%2";
2356 load_store[num].load_nop = "lwl\t%0,%1\n\tlwr\t%0,%2%#";
2357 load_store[num].store = "swl\t%0,%1\n\tswr\t%0,%2";
2358 load_store[num].last_store = "swr\t%0,%2";
2359 load_store[num].final = "swl\t%0,%1";
2361 load_store[num].load = "lwl\t%0,%2\n\tlwr\t%0,%1";
2362 load_store[num].load_nop = "lwl\t%0,%2\n\tlwr\t%0,%1%#";
2363 load_store[num].store = "swl\t%0,%2\n\tswr\t%0,%1";
2364 load_store[num].last_store = "swr\t%0,%1";
2365 load_store[num].final = "swl\t%0,%2";
2367 load_store[num].mode = SImode;
2368 offset += UNITS_PER_WORD;
2369 bytes -= UNITS_PER_WORD;
2373 else if (bytes >= UNITS_PER_SHORT && align >= UNITS_PER_SHORT)
2375 load_store[num].load = "lh\t%0,%1";
2376 load_store[num].load_nop = "lh\t%0,%1%#";
2377 load_store[num].store = "sh\t%0,%1";
2378 load_store[num].last_store = "sh\t%0,%1";
2379 load_store[num].final = (char *)0;
2380 load_store[num].offset = offset;
2381 load_store[num].mode = HImode;
2382 offset += UNITS_PER_SHORT;
2383 bytes -= UNITS_PER_SHORT;
2388 load_store[num].load = "lb\t%0,%1";
2389 load_store[num].load_nop = "lb\t%0,%1%#";
2390 load_store[num].store = "sb\t%0,%1";
2391 load_store[num].last_store = "sb\t%0,%1";
2392 load_store[num].final = (char *)0;
2393 load_store[num].mode = QImode;
2398 if (TARGET_STATS && move_type != BLOCK_MOVE_LAST)
2400 dslots_load_total++;
2401 dslots_load_filled++;
2403 if (CONSTANT_P (src_reg))
2404 mips_count_memory_refs (src_reg, 1);
2406 if (CONSTANT_P (dest_reg))
2407 mips_count_memory_refs (dest_reg, 1);
2410 /* Emit load/stores now if we have run out of registers or are
2411 at the end of the move. */
2413 if (++num == num_regs || bytes == 0)
2415 /* If only load/store, we need a NOP after the load. */
2418 load_store[0].load = load_store[0].load_nop;
2419 if (TARGET_STATS && move_type != BLOCK_MOVE_LAST)
2420 dslots_load_filled--;
2423 if (move_type != BLOCK_MOVE_LAST)
2425 for (i = 0; i < num; i++)
2432 if (GET_MODE (operands[i+4]) != load_store[i].mode)
2433 operands[i+4] = gen_rtx (REG, load_store[i].mode, REGNO (operands[i+4]));
2435 offset = load_store[i].offset;
2436 xoperands[0] = operands[i+4];
2437 xoperands[1] = gen_rtx (MEM, load_store[i].mode,
2438 plus_constant (src_reg, offset));
2441 xoperands[2] = gen_rtx (MEM, load_store[i].mode,
2442 plus_constant (src_reg, UNITS_PER_WORD-1+offset));
2444 output_asm_insn (load_store[i].load, xoperands);
2448 for (i = 0; i < num; i++)
2450 int last_p = (i == num-1 && bytes == 0);
2451 int offset = load_store[i].offset;
2453 xoperands[0] = operands[i+4];
2454 xoperands[1] = gen_rtx (MEM, load_store[i].mode,
2455 plus_constant (dest_reg, offset));
2459 xoperands[2] = gen_rtx (MEM, load_store[i].mode,
2460 plus_constant (dest_reg, UNITS_PER_WORD-1+offset));
2462 if (move_type == BLOCK_MOVE_NORMAL)
2463 output_asm_insn (load_store[i].store, xoperands);
2465 else if (move_type == BLOCK_MOVE_NOT_LAST)
2468 output_asm_insn (load_store[i].store, xoperands);
2470 else if (load_store[i].final != (char *)0)
2471 output_asm_insn (load_store[i].final, xoperands);
2475 output_asm_insn (load_store[i].last_store, xoperands);
2478 num = 0; /* reset load_store */
2479 use_lwl_lwr = FALSE; /* reset whether or not we used lwl/lwr */
2483 if (TARGET_GAS && move_type != BLOCK_MOVE_LAST && --set_noreorder == 0)
2484 output_asm_insn (".set\treorder", operands);
2490 /* Argument support functions. */
2492 /* Initialize CUMULATIVE_ARGS for a function. */
2495 init_cumulative_args (cum, fntype, libname)
2496 CUMULATIVE_ARGS *cum; /* argument info to initialize */
2497 tree fntype; /* tree ptr for function decl */
2498 rtx libname; /* SYMBOL_REF of library name or 0 */
2500 tree param, next_param;
2502 if (TARGET_DEBUG_E_MODE)
2503 fprintf (stderr, "\ninit_cumulative_args\n");
2505 cum->gp_reg_found = 0;
2506 cum->arg_number = 0;
2509 /* Determine if this function has variable arguments. This is
2510 indicated by the last argument being 'void_type_mode' if there
2511 are no variable arguments. The standard MIPS calling sequence
2512 passes all arguments in the general purpose registers in this
2515 for (param = (fntype) ? TYPE_ARG_TYPES (fntype) : 0;
2519 next_param = TREE_CHAIN (param);
2520 if (next_param == (tree)0 && TREE_VALUE (param) != void_type_node)
2521 cum->gp_reg_found = 1;
2524 /* Determine if the function is returning a structure, if so,
2525 advance by one argument. */
2528 && (TREE_CODE (fntype) == FUNCTION_TYPE || TREE_CODE (fntype) == METHOD_TYPE)
2529 && TREE_TYPE (fntype) != 0)
2531 tree ret_type = TREE_TYPE (fntype);
2532 enum tree_code ret_code = TREE_CODE (ret_type);
2534 if (ret_code == RECORD_TYPE || ret_code == UNION_TYPE)
2536 cum->gp_reg_found = 1;
2537 cum->arg_number = 1;
2543 /* Advance the argument to the next argument position. */
2546 function_arg_advance (cum, mode, type, named)
2547 CUMULATIVE_ARGS *cum; /* current arg information */
2548 enum machine_mode mode; /* current arg mode */
2549 tree type; /* type of the argument or 0 if lib support */
2550 int named; /* whether or not the argument was named */
2552 if (TARGET_DEBUG_E_MODE)
2554 "function_adv( {gp reg found = %d, arg # = %2d, words = %2d}, %4s, 0x%.8x, %d )\n",
2555 cum->gp_reg_found, cum->arg_number, cum->arg_words, GET_MODE_NAME (mode),
2562 error ("Illegal mode given to function_arg_advance");
2569 cum->gp_reg_found = 1;
2570 cum->arg_words += (int_size_in_bytes (type) + 3) / 4;
2578 cum->arg_words += 2;
2582 cum->gp_reg_found = 1;
2583 cum->arg_words += 2;
2589 cum->gp_reg_found = 1;
2595 /* Return a RTL expression containing the register for the given mode,
2596 or 0 if the argument is too be passed on the stack. */
2599 function_arg (cum, mode, type, named)
2600 CUMULATIVE_ARGS *cum; /* current arg information */
2601 enum machine_mode mode; /* current arg mode */
2602 tree type; /* type of the argument or 0 if lib support */
2603 int named; /* != 0 for normal args, == 0 for ... args */
2608 if (TARGET_DEBUG_E_MODE)
2610 "function_arg( {gp reg found = %d, arg # = %2d, words = %2d}, %4s, 0x%.8x, %d ) = ",
2611 cum->gp_reg_found, cum->arg_number, cum->arg_words, GET_MODE_NAME (mode),
2617 error ("Illegal mode given to function_arg");
2621 if (cum->gp_reg_found || cum->arg_number >= 2)
2622 regbase = GP_ARG_FIRST;
2624 regbase = (TARGET_SOFT_FLOAT) ? GP_ARG_FIRST : FP_ARG_FIRST;
2625 if (cum->arg_words == 1) /* first arg was float */
2626 bias = 1; /* use correct reg */
2632 cum->arg_words += (cum->arg_words & 1);
2633 regbase = (cum->gp_reg_found || TARGET_SOFT_FLOAT)
2643 regbase = GP_ARG_FIRST;
2647 cum->arg_words += (cum->arg_words & 1);
2648 regbase = GP_ARG_FIRST;
2651 if (cum->arg_words >= MAX_ARGS_IN_REGISTERS)
2653 if (TARGET_DEBUG_E_MODE)
2654 fprintf (stderr, "<stack>\n");
2662 if (TARGET_DEBUG_E_MODE)
2663 fprintf (stderr, "%s\n", reg_names[regbase + cum->arg_words + bias]);
2665 return gen_rtx (REG, mode, regbase + cum->arg_words + bias);
2670 function_arg_partial_nregs (cum, mode, type, named)
2671 CUMULATIVE_ARGS *cum; /* current arg information */
2672 enum machine_mode mode; /* current arg mode */
2673 tree type; /* type of the argument or 0 if lib support */
2674 int named; /* != 0 for normal args, == 0 for ... args */
2676 if (mode == BLKmode && cum->arg_words < MAX_ARGS_IN_REGISTERS)
2678 int words = (int_size_in_bytes (type) + 3) / 4;
2680 if (words + cum->arg_words < MAX_ARGS_IN_REGISTERS)
2681 return 0; /* structure fits in registers */
2683 if (TARGET_DEBUG_E_MODE)
2684 fprintf (stderr, "function_arg_partial_nregs = %d\n",
2685 MAX_ARGS_IN_REGISTERS - cum->arg_words);
2687 return MAX_ARGS_IN_REGISTERS - cum->arg_words;
2690 else if (mode == DImode && cum->arg_words == MAX_ARGS_IN_REGISTERS-1)
2692 if (TARGET_DEBUG_E_MODE)
2693 fprintf (stderr, "function_arg_partial_nregs = 1\n");
2702 /* Print the options used in the assembly file. */
2704 static struct {char *name; int value;} target_switches []
2715 int mask = TARGET_DEFAULT;
2717 /* Allow assembly language comparisons with -mdebug eliminating the
2718 compiler version number and switch lists. */
2720 if (TARGET_DEBUG_MODE)
2723 fprintf (out, "\n # %s %s", language_string, version_string);
2724 #ifdef TARGET_VERSION_INTERNAL
2725 TARGET_VERSION_INTERNAL (out);
2728 fprintf (out, " compiled by GNU C\n\n");
2730 fprintf (out, " compiled by CC\n\n");
2733 fprintf (out, " # Cc1 defaults:");
2735 for (j = 0; j < sizeof target_switches / sizeof target_switches[0]; j++)
2737 if (target_switches[j].name[0] != '\0'
2738 && target_switches[j].value > 0
2739 && (target_switches[j].value & mask) == target_switches[j].value)
2741 mask &= ~ target_switches[j].value;
2742 len = strlen (target_switches[j].name) + 1;
2743 if (len + line_len > 79)
2746 fputs ("\n #", out);
2748 fprintf (out, " -m%s", target_switches[j].name);
2753 fprintf (out, "\n\n # Cc1 arguments (-G value = %d, Cpu = %s, ISA = %d):",
2754 mips_section_threshold, mips_cpu_string, mips_isa);
2757 for (p = &save_argv[1]; *p != (char *)0; p++)
2762 len = strlen (arg) + 1;
2763 if (len + line_len > 79)
2766 fputs ("\n #", out);
2768 fprintf (out, " %s", *p);
2773 fputs ("\n\n", out);
2777 /* Abort after printing out a specific insn. */
2780 abort_with_insn (insn, reason)
2789 /* Write a message to stderr (for use in macros expanded in files that do not
2790 include stdio.h). */
2796 fprintf (stderr, s, s1, s2);
2802 #include <sys/wait.h>
2808 char select_pgrp[15];
2814 fprintf (stderr, "compiling '%s' in '%s'\n",
2815 (current_function_name != (char *)0) ? current_function_name : "<toplevel>",
2816 (current_function_file != (char *)0) ? current_function_file : "<no file>");
2820 sprintf (select_pgrp, "-g%d", pgrp);
2822 strcpy (select_pgrp, "-a");
2824 /* Spawn a ps to tell about current memory usage, etc. */
2826 argv[1] = "-ouser,pid,pri,nice,usertime,systime,pcpu,cp,inblock,oublock,vsize,rss,pmem,ucomm";
2827 argv[2] = select_pgrp;
2828 argv[3] = (char *)0;
2831 if (pid == 0) /* child context */
2833 execv ("/usr/bin/ps", argv);
2834 execv ("/usr/sbin/ps", argv);
2835 execvp ("ps", argv);
2840 else if (pid > 0) /* parent context */
2842 void (*sigint)(int) = signal (SIGINT, SIG_IGN);
2843 void (*sigquit)(int) = signal (SIGQUIT, SIG_IGN);
2845 (void) waitpid (pid, &status, 0);
2847 (void) signal (SIGINT, sigint);
2848 (void) signal (SIGQUIT, sigquit);
2851 #endif /* SIGINFO */
2854 /* Set up the threshold for data to go into the small data area, instead
2855 of the normal data area, and detect any conflicts in the switches. */
2860 register int i, start;
2862 register enum machine_mode mode;
2865 mips_section_threshold = g_switch_value;
2868 mips_section_threshold = (TARGET_MIPS_AS) ? 8 : 0;
2870 /* Identify the processor type */
2871 if (mips_cpu_string == (char *)0
2872 || !strcmp (mips_cpu_string, "default")
2873 || !strcmp (mips_cpu_string, "DEFAULT"))
2875 mips_cpu_string = "default";
2876 mips_cpu = PROCESSOR_DEFAULT;
2881 char *p = mips_cpu_string;
2883 if (*p == 'r' || *p == 'R')
2886 /* Since there is no difference between a R2000 and R3000 in
2887 terms of the scheduler, we collapse them into just an R3000. */
2889 mips_cpu = PROCESSOR_DEFAULT;
2893 if (!strcmp (p, "2000") || !strcmp (p, "2k") || !strcmp (p, "2K"))
2894 mips_cpu = PROCESSOR_R3000;
2898 if (!strcmp (p, "3000") || !strcmp (p, "3k") || !strcmp (p, "3K"))
2899 mips_cpu = PROCESSOR_R3000;
2903 if (!strcmp (p, "4000") || !strcmp (p, "4k") || !strcmp (p, "4K"))
2904 mips_cpu = PROCESSOR_R4000;
2908 if (!strcmp (p, "6000") || !strcmp (p, "6k") || !strcmp (p, "6K"))
2909 mips_cpu = PROCESSOR_R6000;
2913 if (mips_cpu == PROCESSOR_DEFAULT)
2915 error ("bad value (%s) for -mcpu= switch", mips_cpu_string);
2916 mips_cpu_string = "default";
2920 /* Now get the architectural level. */
2921 if (mips_isa_string == (char *)0)
2924 else if (isdigit (*mips_isa_string))
2925 mips_isa = atoi (mips_isa_string);
2929 error ("bad value (%s) for -mips switch", mips_isa_string);
2933 if (mips_isa < 0 || mips_isa > 3)
2934 error ("-mips%d not supported", mips_isa);
2936 else if (mips_isa > 1
2937 && (mips_cpu == PROCESSOR_DEFAULT || mips_cpu == PROCESSOR_R3000))
2938 error ("-mcpu=%s does not support -mips%d", mips_cpu_string, mips_isa);
2940 else if (mips_cpu == PROCESSOR_R6000 && mips_isa > 2)
2941 error ("-mcpu=%s does not support -mips%d", mips_cpu_string, mips_isa);
2943 /* make sure sizes of ints/longs/etc. are ok */
2947 fatal ("Only the r4000 can support 64 bit ints");
2949 else if (TARGET_LONG64)
2950 fatal ("Only the r4000 can support 64 bit longs");
2952 else if (TARGET_LLONG128)
2953 fatal ("Only the r4000 can support 128 bit long longs");
2955 else if (TARGET_FLOAT64)
2956 fatal ("Only the r4000 can support 64 bit fp registers");
2958 else if (TARGET_INT64 || TARGET_LONG64 || TARGET_LLONG128 || TARGET_FLOAT64)
2959 warning ("r4000 64/128 bit types not yet supported");
2961 /* Tell halfpic.c that we have half-pic code if we do. */
2962 if (TARGET_HALF_PIC)
2965 /* -mrnames says to use the MIPS software convention for register
2966 names instead of the hardware names (ie, a0 instead of $4).
2967 We do this by switching the names in mips_reg_names, which the
2968 reg_names points into via the REGISTER_NAMES macro. */
2970 if (TARGET_NAME_REGS)
2974 target_flags &= ~ MASK_NAME_REGS;
2975 error ("Gas does not support the MIPS software register name convention.");
2978 bcopy ((char *) mips_sw_reg_names, (char *) mips_reg_names, sizeof (mips_reg_names));
2981 /* If this is OSF/1, set up a SIGINFO handler so we can see what function
2982 is currently being compiled. */
2984 if (getenv ("GCC_SIGINFO") != (char *)0)
2986 struct sigaction action;
2987 action.sa_handler = siginfo;
2989 action.sa_flags = SA_RESTART;
2990 sigaction (SIGINFO, &action, (struct sigaction *)0);
2995 /* If -mstats and -quiet, make stderr line buffered. */
2996 if (quiet_flag && TARGET_STATS)
2998 #if defined (MIPS_BSD43) || defined (MIPS_NEWS)
2999 setlinebuf (stderr);
3001 setvbuf (stderr, (char *)0, _IOLBF, BUFSIZ);
3006 /* Set up the classification arrays now. */
3007 mips_rtx_classify[(int)PLUS] = CLASS_ADD_OP;
3008 mips_rtx_classify[(int)MINUS] = CLASS_ADD_OP;
3009 mips_rtx_classify[(int)DIV] = CLASS_DIVMOD_OP;
3010 mips_rtx_classify[(int)MOD] = CLASS_DIVMOD_OP;
3011 mips_rtx_classify[(int)UDIV] = CLASS_DIVMOD_OP | CLASS_UNSIGNED_OP;
3012 mips_rtx_classify[(int)UMOD] = CLASS_DIVMOD_OP | CLASS_UNSIGNED_OP;
3013 mips_rtx_classify[(int)EQ] = CLASS_CMP_OP | CLASS_EQUALITY_OP | CLASS_FCMP_OP;
3014 mips_rtx_classify[(int)NE] = CLASS_CMP_OP | CLASS_EQUALITY_OP | CLASS_FCMP_OP;
3015 mips_rtx_classify[(int)GT] = CLASS_CMP_OP | CLASS_FCMP_OP;
3016 mips_rtx_classify[(int)GE] = CLASS_CMP_OP | CLASS_FCMP_OP;
3017 mips_rtx_classify[(int)LT] = CLASS_CMP_OP | CLASS_FCMP_OP;
3018 mips_rtx_classify[(int)LE] = CLASS_CMP_OP | CLASS_FCMP_OP;
3019 mips_rtx_classify[(int)GTU] = CLASS_CMP_OP | CLASS_UNSIGNED_OP;
3020 mips_rtx_classify[(int)GEU] = CLASS_CMP_OP | CLASS_UNSIGNED_OP;
3021 mips_rtx_classify[(int)LTU] = CLASS_CMP_OP | CLASS_UNSIGNED_OP;
3022 mips_rtx_classify[(int)LEU] = CLASS_CMP_OP | CLASS_UNSIGNED_OP;
3024 mips_print_operand_punct['?'] = TRUE;
3025 mips_print_operand_punct['#'] = TRUE;
3026 mips_print_operand_punct['&'] = TRUE;
3027 mips_print_operand_punct['!'] = TRUE;
3028 mips_print_operand_punct['*'] = TRUE;
3029 mips_print_operand_punct['@'] = TRUE;
3030 mips_print_operand_punct['.'] = TRUE;
3031 mips_print_operand_punct['('] = TRUE;
3032 mips_print_operand_punct[')'] = TRUE;
3033 mips_print_operand_punct['['] = TRUE;
3034 mips_print_operand_punct[']'] = TRUE;
3035 mips_print_operand_punct['<'] = TRUE;
3036 mips_print_operand_punct['>'] = TRUE;
3037 mips_print_operand_punct['{'] = TRUE;
3038 mips_print_operand_punct['}'] = TRUE;
3040 mips_char_to_class['d'] = GR_REGS;
3041 mips_char_to_class['f'] = ((TARGET_HARD_FLOAT) ? FP_REGS : NO_REGS);
3042 mips_char_to_class['h'] = HI_REG;
3043 mips_char_to_class['l'] = LO_REG;
3044 mips_char_to_class['x'] = MD_REGS;
3045 mips_char_to_class['y'] = GR_REGS;
3046 mips_char_to_class['z'] = ST_REGS;
3048 /* Set up array to map GCC register number to debug register number.
3049 Ignore the special purpose register numbers. */
3051 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3052 mips_dbx_regno[i] = -1;
3054 start = GP_DBX_FIRST - GP_REG_FIRST;
3055 for (i = GP_REG_FIRST; i <= GP_REG_LAST; i++)
3056 mips_dbx_regno[i] = i + start;
3058 start = FP_DBX_FIRST - FP_REG_FIRST;
3059 for (i = FP_REG_FIRST; i <= FP_REG_LAST; i++)
3060 mips_dbx_regno[i] = i + start;
3062 /* Set up array giving whether a given register can hold a given mode.
3063 At present, restrict ints from being in FP registers, because reload
3064 is a little enthusiastic about storing extra values in FP registers,
3065 and this is not good for things like OS kernels. Also, due to the
3066 mandatory delay, it is as fast to load from cached memory as to move
3067 from the FP register. */
3069 for (mode = VOIDmode;
3070 mode != MAX_MACHINE_MODE;
3071 mode = (enum machine_mode)((int)mode + 1))
3073 register int size = GET_MODE_SIZE (mode);
3074 register enum mode_class class = GET_MODE_CLASS (mode);
3076 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
3080 if (mode == CC_FPmode || mode == CC_REV_FPmode)
3081 temp = (regno == FPSW_REGNUM);
3083 else if (GP_REG_P (regno))
3084 temp = ((regno & 1) == 0 || (size <= UNITS_PER_WORD));
3086 else if (FP_REG_P (regno))
3087 temp = ((TARGET_FLOAT64 || ((regno & 1) == 0))
3088 && (class == MODE_FLOAT
3089 || class == MODE_COMPLEX_FLOAT
3090 || (TARGET_DEBUG_H_MODE && class == MODE_INT)));
3092 else if (MD_REG_P (regno))
3093 temp = (mode == SImode || (regno == MD_REG_FIRST && mode == DImode));
3098 mips_hard_regno_mode_ok[(int)mode][regno] = temp;
3105 * If the frame pointer has been eliminated, the offset for an auto
3106 * or argument will be based on the stack pointer. But this is not
3107 * what the debugger expects--it needs to find an offset off of the
3108 * frame pointer (whether it exists or not). So here we turn all
3109 * offsets into those based on the (possibly virtual) frame pointer.
3113 mips_debugger_offset (addr, offset)
3117 rtx offset2 = const0_rtx;
3118 rtx reg = eliminate_constant_term (addr, &offset2);
3121 offset = INTVAL (offset2);
3123 if (reg == stack_pointer_rtx)
3125 int frame_size = (!current_frame_info.initialized)
3126 ? compute_frame_size (get_frame_size ())
3127 : current_frame_info.total_size;
3129 offset = offset - frame_size;
3132 /* Any other register is, we hope, either the frame pointer,
3133 or a pseudo equivalent to the frame pointer. (Assign_parms
3134 copies the arg pointer to a pseudo if ARG_POINTER_REGNUM is
3135 equal to FRAME_POINTER_REGNUM, so references off of the
3136 arg pointer are all off a pseudo.) Seems like all we can
3137 do is to just return OFFSET and hope for the best. */
3143 /* A C compound statement to output to stdio stream STREAM the
3144 assembler syntax for an instruction operand X. X is an RTL
3147 CODE is a value that can be used to specify one of several ways
3148 of printing the operand. It is used when identical operands
3149 must be printed differently depending on the context. CODE
3150 comes from the `%' specification that was used to request
3151 printing of the operand. If the specification was just `%DIGIT'
3152 then CODE is 0; if the specification was `%LTR DIGIT' then CODE
3153 is the ASCII code for LTR.
3155 If X is a register, this macro should print the register's name.
3156 The names can be found in an array `reg_names' whose type is
3157 `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
3159 When the machine description has a specification `%PUNCT' (a `%'
3160 followed by a punctuation character), this macro is called with
3161 a null pointer for X and the punctuation character for CODE.
3163 The MIPS specific codes are:
3165 'X' X is CONST_INT, prints 32 bits in hexadecimal format = "0x%08x",
3166 'x' X is CONST_INT, prints 16 bits in hexadecimal format = "0x%04x",
3167 'd' output integer constant in decimal,
3168 'z' if the operand is 0, use $0 instead of normal operand.
3169 'D' print second register of double-word register operand.
3170 'L' print low-order register of double-word register operand.
3171 'M' print high-order register of double-word register operand.
3172 'C' print part of opcode for a branch condition.
3173 'N' print part of opcode for a branch condition, inverted.
3174 '(' Turn on .set noreorder
3175 ')' Turn on .set reorder
3176 '[' Turn on .set noat
3178 '<' Turn on .set nomacro
3179 '>' Turn on .set macro
3180 '{' Turn on .set volatile (not GAS)
3181 '}' Turn on .set novolatile (not GAS)
3182 '&' Turn on .set noreorder if filling delay slots
3183 '*' Turn on both .set noreorder and .set nomacro if filling delay slots
3184 '!' Turn on .set nomacro if filling delay slots
3185 '#' Print nop if in a .set noreorder section.
3186 '?' Print 'l' if we are to use a branch likely instead of normal branch.
3187 '@' Print the name of the assembler temporary register (at or $1).
3188 '.' Print the name of the register with a hard-wired zero (zero or $0). */
3191 print_operand (file, op, letter)
3192 FILE *file; /* file to write to */
3193 rtx op; /* operand to print */
3194 int letter; /* %<letter> or 0 */
3196 register enum rtx_code code;
3198 if (PRINT_OPERAND_PUNCT_VALID_P (letter))
3203 error ("PRINT_OPERAND: Unknown punctuation '%c'", letter);
3207 if (mips_branch_likely)
3212 fputs (reg_names [GP_REG_FIRST + 1], file);
3216 fputs (reg_names [GP_REG_FIRST + 0], file);
3220 if (final_sequence != 0 && set_noreorder++ == 0)
3221 fputs (".set\tnoreorder\n\t", file);
3225 if (final_sequence != 0)
3227 if (set_noreorder++ == 0)
3228 fputs (".set\tnoreorder\n\t", file);
3230 if (set_nomacro++ == 0)
3231 fputs (".set\tnomacro\n\t", file);
3236 if (final_sequence != 0 && set_nomacro++ == 0)
3237 fputs ("\n\t.set\tnomacro", file);
3241 if (set_noreorder != 0)
3242 fputs ("\n\tnop", file);
3244 else if (TARGET_GAS || TARGET_STATS)
3245 fputs ("\n\t#nop", file);
3250 if (set_noreorder++ == 0)
3251 fputs (".set\tnoreorder\n\t", file);
3255 if (set_noreorder == 0)
3256 error ("internal error: %%) found without a %%( in assembler pattern");
3258 else if (--set_noreorder == 0)
3259 fputs ("\n\t.set\treorder", file);
3264 if (set_noat++ == 0)
3265 fputs (".set\tnoat\n\t", file);
3270 error ("internal error: %%] found without a %%[ in assembler pattern");
3272 else if (--set_noat == 0)
3273 fputs ("\n\t.set\tat", file);
3278 if (set_nomacro++ == 0)
3279 fputs (".set\tnomacro\n\t", file);
3283 if (set_nomacro == 0)
3284 error ("internal error: %%> found without a %%< in assembler pattern");
3286 else if (--set_nomacro == 0)
3287 fputs ("\n\t.set\tmacro", file);
3292 if (set_volatile++ == 0)
3293 fprintf (file, "%s.set\tvolatile\n\t", (TARGET_MIPS_AS) ? "" : "#");
3297 if (set_volatile == 0)
3298 error ("internal error: %%} found without a %%{ in assembler pattern");
3300 else if (--set_volatile == 0)
3301 fprintf (file, "\n\t%s.set\tnovolatile", (TARGET_MIPS_AS) ? "" : "#");
3310 error ("PRINT_OPERAND null pointer");
3314 code = GET_CODE (op);
3318 case EQ: fputs ("eq", file); break;
3319 case NE: fputs ("ne", file); break;
3320 case GT: fputs ("gt", file); break;
3321 case GE: fputs ("ge", file); break;
3322 case LT: fputs ("lt", file); break;
3323 case LE: fputs ("le", file); break;
3324 case GTU: fputs ("gtu", file); break;
3325 case GEU: fputs ("geu", file); break;
3326 case LTU: fputs ("ltu", file); break;
3327 case LEU: fputs ("leu", file); break;
3330 abort_with_insn (op, "PRINT_OPERAND, illegal insn for %%C");
3333 else if (letter == 'N')
3336 case EQ: fputs ("ne", file); break;
3337 case NE: fputs ("eq", file); break;
3338 case GT: fputs ("le", file); break;
3339 case GE: fputs ("lt", file); break;
3340 case LT: fputs ("ge", file); break;
3341 case LE: fputs ("gt", file); break;
3342 case GTU: fputs ("leu", file); break;
3343 case GEU: fputs ("ltu", file); break;
3344 case LTU: fputs ("geu", file); break;
3345 case LEU: fputs ("gtu", file); break;
3348 abort_with_insn (op, "PRINT_OPERAND, illegal insn for %%N");
3351 else if (code == REG)
3353 register int regnum = REGNO (op);
3356 regnum += MOST_SIGNIFICANT_WORD;
3358 else if (letter == 'L')
3359 regnum += LEAST_SIGNIFICANT_WORD;
3361 else if (letter == 'D')
3364 fprintf (file, "%s", reg_names[regnum]);
3367 else if (code == MEM)
3368 output_address (XEXP (op, 0));
3370 else if (code == CONST_DOUBLE)
3372 #if HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT
3373 union { double d; int i[2]; } u;
3374 u.i[0] = CONST_DOUBLE_LOW (op);
3375 u.i[1] = CONST_DOUBLE_HIGH (op);
3376 if (GET_MODE (op) == SFmode)
3382 fprintf (file, "%.20e", u.d);
3384 fatal ("CONST_DOUBLE found in cross compilation");
3388 else if ((letter == 'x') && (GET_CODE(op) == CONST_INT))
3389 fprintf (file, "0x%04x", 0xffff & (INTVAL(op)));
3391 else if ((letter == 'X') && (GET_CODE(op) == CONST_INT))
3392 fprintf (file, "0x%08x", INTVAL(op));
3394 else if ((letter == 'd') && (GET_CODE(op) == CONST_INT))
3395 fprintf (file, "%d", (INTVAL(op)));
3397 else if (letter == 'z'
3398 && (GET_CODE (op) == CONST_INT)
3399 && INTVAL (op) == 0)
3400 fputs (reg_names[GP_REG_FIRST], file);
3402 else if (letter == 'd' || letter == 'x' || letter == 'X')
3403 fatal ("PRINT_OPERAND: letter %c was found & insn was not CONST_INT", letter);
3406 output_addr_const (file, op);
3410 /* A C compound statement to output to stdio stream STREAM the
3411 assembler syntax for an instruction operand that is a memory
3412 reference whose address is ADDR. ADDR is an RTL expression.
3414 On some machines, the syntax for a symbolic address depends on
3415 the section that the address refers to. On these machines,
3416 define the macro `ENCODE_SECTION_INFO' to store the information
3417 into the `symbol_ref', and then check for it here. */
3420 print_operand_address (file, addr)
3425 error ("PRINT_OPERAND_ADDRESS, null pointer");
3428 switch (GET_CODE (addr))
3431 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, illegal insn #1");
3435 fprintf (file, "0(%s)", reg_names [REGNO (addr)]);
3440 register rtx reg = (rtx)0;
3441 register rtx offset = (rtx)0;
3442 register rtx arg0 = XEXP (addr, 0);
3443 register rtx arg1 = XEXP (addr, 1);
3445 if (GET_CODE (arg0) == REG)
3449 if (GET_CODE (offset) == REG)
3450 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, 2 regs");
3452 else if (GET_CODE (arg1) == REG)
3457 else if (CONSTANT_P (arg0) && CONSTANT_P (arg1))
3459 output_addr_const (file, addr);
3463 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, no regs");
3465 if (!CONSTANT_P (offset))
3466 abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, illegal insn #2");
3468 output_addr_const (file, offset);
3469 fprintf (file, "(%s)", reg_names [REGNO (reg)]);
3477 output_addr_const (file, addr);
3483 /* If optimizing for the global pointer, keep track of all of
3484 the externs, so that at the end of the file, we can emit
3485 the appropriate .extern declaration for them, before writing
3486 out the text section. We assume that all names passed to
3487 us are in the permanent obstack, so that they will be valid
3488 at the end of the compilation.
3490 If we have -G 0, or the extern size is unknown, don't bother
3491 emitting the .externs. */
3494 mips_output_external (file, decl, name)
3499 register struct extern_list *p;
3503 && mips_section_threshold != 0
3504 && ((TREE_CODE (decl)) != FUNCTION_DECL)
3505 && ((len = int_size_in_bytes (TREE_TYPE (decl))) > 0))
3507 p = (struct extern_list *)permalloc ((long) sizeof (struct extern_list));
3508 p->next = extern_head;
3517 /* Compute a string to use as a temporary file name. */
3523 char *base = getenv ("TMPDIR");
3526 if (base == (char *)0)
3529 if (access (P_tmpdir, R_OK | W_OK) == 0)
3533 if (access ("/usr/tmp", R_OK | W_OK) == 0)
3539 len = strlen (base);
3540 temp_filename = (char *) alloca (len + sizeof("/ccXXXXXX"));
3541 strcpy (temp_filename, base);
3542 if (len > 0 && temp_filename[len-1] != '/')
3543 temp_filename[len++] = '/';
3545 strcpy (temp_filename + len, "ccXXXXXX");
3546 mktemp (temp_filename);
3548 stream = fopen (temp_filename, "w+");
3550 pfatal_with_name (temp_filename);
3552 unlink (temp_filename);
3557 /* Emit a new filename to a stream. If this is MIPS ECOFF, watch out
3558 for .file's that start within a function. If we are smuggling stabs, try to
3559 put out a MIPS ECOFF file and a stab. */
3562 mips_output_filename (stream, name)
3566 static int first_time = TRUE;
3567 char ltext_label_name[100];
3573 current_function_file = name;
3574 fprintf (stream, "\t.file\t%d \"%s\"\n", num_source_filenames, name);
3575 if (!TARGET_GAS && write_symbols == DBX_DEBUG)
3576 fprintf (stream, "\t#@stabs\n");
3579 else if (!TARGET_GAS && write_symbols == DBX_DEBUG)
3581 ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", 0);
3582 fprintf (stream, "%s \"%s\",%d,0,0,%s\n", ASM_STABS_OP,
3583 name, N_SOL, <ext_label_name[1]);
3586 else if (name != current_function_file
3587 && strcmp (name, current_function_file) != 0)
3589 if (inside_function && !TARGET_GAS)
3591 if (!file_in_function_warning)
3593 file_in_function_warning = TRUE;
3594 ignore_line_number = TRUE;
3595 warning ("MIPS ECOFF format does not allow changing filenames within functions with #line");
3598 fprintf (stream, "\t#.file\t%d \"%s\"\n", num_source_filenames, name);
3604 current_function_file = name;
3605 fprintf (stream, "\t.file\t%d \"%s\"\n", num_source_filenames, name);
3611 /* Emit a linenumber. For encapsulated stabs, we need to put out a stab
3612 as well as a .loc, since it is possible that MIPS ECOFF might not be
3613 able to represent the location for inlines that come from a different
3617 mips_output_lineno (stream, line)
3621 if (!TARGET_GAS && write_symbols == DBX_DEBUG)
3624 fprintf (stream, "$LM%d:\n\t%s %d,0,%d,$LM%d\n",
3625 sym_lineno, ASM_STABN_OP, N_SLINE, line, sym_lineno);
3630 fprintf (stream, "\n\t%s.loc\t%d %d\n",
3631 (ignore_line_number) ? "#" : "",
3632 num_source_filenames, line);
3634 LABEL_AFTER_LOC (stream);
3639 /* If defined, a C statement to be executed just prior to the
3640 output of assembler code for INSN, to modify the extracted
3641 operands so they will be output differently.
3643 Here the argument OPVEC is the vector containing the operands
3644 extracted from INSN, and NOPERANDS is the number of elements of
3645 the vector which contain meaningful data for this insn. The
3646 contents of this vector are what will be used to convert the
3647 insn template into assembler code, so you can change the
3648 assembler output by changing the contents of the vector.
3650 We use it to check if the current insn needs a nop in front of it
3651 because of load delays, and also to update the delay slot
3655 final_prescan_insn (insn, opvec, noperands)
3660 if (dslots_number_nops > 0)
3662 rtx pattern = PATTERN (insn);
3663 int length = get_attr_length (insn);
3665 /* Do we need to emit a NOP? */
3667 || (mips_load_reg != (rtx)0 && reg_mentioned_p (mips_load_reg, pattern))
3668 || (mips_load_reg2 != (rtx)0 && reg_mentioned_p (mips_load_reg2, pattern))
3669 || (mips_load_reg3 != (rtx)0 && reg_mentioned_p (mips_load_reg3, pattern))
3670 || (mips_load_reg4 != (rtx)0 && reg_mentioned_p (mips_load_reg4, pattern)))
3671 fputs ((set_noreorder) ? "\tnop\n" : "\t#nop\n", asm_out_file);
3674 dslots_load_filled++;
3676 while (--dslots_number_nops > 0)
3677 fputs ((set_noreorder) ? "\tnop\n" : "\t#nop\n", asm_out_file);
3679 mips_load_reg = (rtx)0;
3680 mips_load_reg2 = (rtx)0;
3681 mips_load_reg3 = (rtx)0;
3682 mips_load_reg4 = (rtx)0;
3684 if (set_noreorder && --set_noreorder == 0)
3685 fputs ("\t.set\treorder\n", asm_out_file);
3690 enum rtx_code code = GET_CODE (insn);
3691 if (code == JUMP_INSN || code == CALL_INSN)
3692 dslots_jump_total++;
3697 /* Output at beginning of assembler file.
3698 If we are optimizing to use the global pointer, create a temporary
3699 file to hold all of the text stuff, and write it out to the end.
3700 This is needed because the MIPS assembler is evidently one pass,
3701 and if it hasn't seen the relevant .comm/.lcomm/.extern/.sdata
3702 declaration when the code is processed, it generates a two
3703 instruction sequence. */
3706 mips_asm_file_start (stream)
3709 ASM_OUTPUT_SOURCE_FILENAME (stream, main_input_filename);
3711 /* Versions of the MIPS assembler before 2.20 generate errors
3712 if a branch inside of a .set noreorder section jumps to a
3713 label outside of the .set noreorder section. Revision 2.20
3714 just set nobopt silently rather than fixing the bug. */
3716 if (TARGET_MIPS_AS && optimize && flag_delayed_branch)
3717 fprintf (stream, "\t.set\tnobopt\n");
3719 /* Generate the pseudo ops that the Pyramid based System V.4 wants. */
3720 if (TARGET_ABICALLS)
3721 fprintf (stream, "\t.abicalls\n");
3725 asm_out_data_file = stream;
3726 asm_out_text_file = make_temp_file ();
3729 asm_out_data_file = asm_out_text_file = stream;
3731 if (TARGET_NAME_REGS)
3732 fprintf (asm_out_file, "#include <regdef.h>\n");
3734 print_options (stream);
3738 /* If we are optimizing the global pointer, emit the text section now
3739 and any small externs which did not have .comm, etc that are
3740 needed. Also, give a warning if the data area is more than 32K and
3741 -pic because 3 instructions are needed to reference the data
3745 mips_asm_file_end (file)
3750 struct extern_list *p;
3754 HALF_PIC_FINISH (file);
3761 for (p = extern_head; p != 0; p = p->next)
3763 name_tree = get_identifier (p->name);
3765 /* Positively ensure only one .extern for any given symbol. */
3766 if (! TREE_ASM_WRITTEN (name_tree))
3768 TREE_ASM_WRITTEN (name_tree) = 1;
3769 fputs ("\t.extern\t", file);
3770 assemble_name (file, p->name);
3771 fprintf (file, ", %d\n", p->size);
3775 fprintf (file, "\n\t.text\n");
3776 rewind (asm_out_text_file);
3777 if (ferror (asm_out_text_file))
3778 fatal_io_error (temp_filename);
3780 while ((len = fread (buffer, 1, sizeof (buffer), asm_out_text_file)) > 0)
3781 if (fwrite (buffer, 1, len, file) != len)
3782 pfatal_with_name (asm_file_name);
3785 pfatal_with_name (temp_filename);
3787 if (fclose (asm_out_text_file) != 0)
3788 pfatal_with_name (temp_filename);
3793 /* Emit either a label, .comm, or .lcomm directive, and mark
3794 that the symbol is used, so that we don't emit an .extern
3795 for it in mips_asm_file_end. */
3798 mips_declare_object (stream, name, init_string, final_string, size)
3805 fputs (init_string, stream); /* "", "\t.comm\t", or "\t.lcomm\t" */
3806 assemble_name (stream, name);
3807 fprintf (stream, final_string, size); /* ":\n", ",%u\n", ",%u\n" */
3809 if (TARGET_GP_OPT && mips_section_threshold != 0)
3811 tree name_tree = get_identifier (name);
3812 TREE_ASM_WRITTEN (name_tree) = 1;
3817 /* Output a double precision value to the assembler. If both the
3818 host and target are IEEE, emit the values in hex. */
3821 mips_output_double (stream, value)
3823 REAL_VALUE_TYPE value;
3825 #ifdef REAL_VALUE_TO_TARGET_DOUBLE
3827 REAL_VALUE_TO_TARGET_DOUBLE (value, value_long);
3829 fprintf (stream, "\t.word\t0x%08lx\t\t# %.20g\n\t.word\t0x%08lx\n",
3830 value_long[0], value, value_long[1]);
3832 fprintf (stream, "\t.double\t%.20g\n", value);
3837 /* Output a single precision value to the assembler. If both the
3838 host and target are IEEE, emit the values in hex. */
3841 mips_output_float (stream, value)
3843 REAL_VALUE_TYPE value;
3845 #ifdef REAL_VALUE_TO_TARGET_SINGLE
3847 REAL_VALUE_TO_TARGET_SINGLE (value, value_long);
3849 fprintf (stream, "\t.word\t0x%08lx\t\t# %.12g (float)\n", value_long, value);
3851 fprintf (stream, "\t.float\t%.12g\n", value);
3856 /* Return the bytes needed to compute the frame pointer from the current
3859 Mips stack frames look like:
3861 Before call After call
3862 +-----------------------+ +-----------------------+
3865 | caller's temps. | | caller's temps. |
3867 +-----------------------+ +-----------------------+
3869 | arguments on stack. | | arguments on stack. |
3871 +-----------------------+ +-----------------------+
3872 | 4 words to save | | 4 words to save |
3873 | arguments passed | | arguments passed |
3874 | in registers, even | | in registers, even |
3875 SP->| if not passed. | FP->| if not passed. |
3876 +-----------------------+ +-----------------------+
3878 | GP save for V.4 abi |
3880 +-----------------------+
3884 +-----------------------+
3886 | fp register save |
3888 +-----------------------+
3890 | gp register save |
3892 +-----------------------+
3894 | alloca allocations |
3896 +-----------------------+
3898 | arguments on stack |
3900 +-----------------------+
3902 | arguments passed |
3903 | in registers, even |
3904 low SP->| if not passed. |
3905 memory +-----------------------+
3910 compute_frame_size (size)
3911 int size; /* # of var. bytes allocated */
3914 unsigned long total_size; /* # bytes that the entire frame takes up */
3915 unsigned long var_size; /* # bytes that variables take up */
3916 unsigned long args_size; /* # bytes that outgoing arguments take up */
3917 unsigned long extra_size; /* # extra bytes */
3918 unsigned int gp_reg_rounded; /* # bytes needed to store gp after rounding */
3919 unsigned int gp_reg_size; /* # bytes needed to store gp regs */
3920 unsigned int fp_reg_size; /* # bytes needed to store fp regs */
3921 unsigned long mask; /* mask of saved gp registers */
3922 unsigned long fmask; /* mask of saved fp registers */
3923 int fp_inc; /* 1 or 2 depending on the size of fp regs */
3924 int fp_bits; /* bitmask to use for each fp register */
3926 extra_size = MIPS_STACK_ALIGN (((TARGET_ABICALLS) ? UNITS_PER_WORD : 0)
3927 -STARTING_FRAME_OFFSET);
3929 var_size = MIPS_STACK_ALIGN (size);
3930 args_size = MIPS_STACK_ALIGN (current_function_outgoing_args_size);
3931 total_size = var_size + args_size + extra_size;
3937 /* Calculate space needed for gp registers. */
3938 for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
3940 if (MUST_SAVE_REGISTER (regno))
3942 gp_reg_size += UNITS_PER_WORD;
3943 mask |= 1 << (regno - GP_REG_FIRST);
3947 /* Calculate space needed for fp registers. */
3959 for (regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno += fp_inc)
3961 if (regs_ever_live[regno] && !call_used_regs[regno])
3963 fp_reg_size += 2*UNITS_PER_WORD;
3964 fmask |= fp_bits << (regno - FP_REG_FIRST);
3968 gp_reg_rounded = MIPS_STACK_ALIGN (gp_reg_size);
3969 total_size += gp_reg_rounded + fp_reg_size;
3971 if (total_size == extra_size)
3972 total_size = extra_size = 0;
3974 /* Save other computed information. */
3975 current_frame_info.total_size = total_size;
3976 current_frame_info.var_size = var_size;
3977 current_frame_info.args_size = args_size;
3978 current_frame_info.extra_size = extra_size;
3979 current_frame_info.gp_reg_size = gp_reg_size;
3980 current_frame_info.fp_reg_size = fp_reg_size;
3981 current_frame_info.mask = mask;
3982 current_frame_info.fmask = fmask;
3983 current_frame_info.initialized = reload_completed;
3984 current_frame_info.num_gp = gp_reg_size / UNITS_PER_WORD;
3985 current_frame_info.num_fp = fp_reg_size / (2*UNITS_PER_WORD);
3989 unsigned long offset = args_size + gp_reg_size - UNITS_PER_WORD;
3990 current_frame_info.gp_sp_offset = offset;
3991 current_frame_info.gp_save_offset = offset - total_size;
3996 unsigned long offset = args_size + gp_reg_rounded + fp_reg_size - 2*UNITS_PER_WORD;
3997 current_frame_info.fp_sp_offset = offset;
3998 current_frame_info.fp_save_offset = offset - total_size + UNITS_PER_WORD;
4001 /* Ok, we're done. */
4006 /* Save/restore registers printing out the instructions to a file. */
4009 save_restore (file, gp_op, gp_2word_op, fp_op)
4010 FILE *file; /* stream to write to */
4011 char *gp_op; /* operation to do on gp registers */
4012 char *gp_2word_op; /* 2 word op to do on gp registers */
4013 char *fp_op; /* operation to do on fp registers */
4016 unsigned long mask = current_frame_info.mask;
4017 unsigned long fmask = current_frame_info.fmask;
4018 unsigned long gp_offset;
4019 unsigned long fp_offset;
4020 unsigned long max_offset;
4023 if (mask == 0 && fmask == 0)
4026 base_reg = reg_names[STACK_POINTER_REGNUM];
4027 gp_offset = current_frame_info.gp_sp_offset;
4028 fp_offset = current_frame_info.fp_sp_offset;
4029 max_offset = (gp_offset > fp_offset) ? gp_offset : fp_offset;
4031 /* Deal with calling functions with a large structure. */
4032 if (max_offset >= 32768)
4034 char *temp = reg_names[MIPS_TEMP2_REGNUM];
4035 fprintf (file, "\tli\t%s,%ld\n", temp, max_offset);
4036 fprintf (file, "\taddu\t%s,%s,%s\n", temp, temp, base_reg);
4038 gp_offset = max_offset - gp_offset;
4039 fp_offset = max_offset - fp_offset;
4042 /* Save registers starting from high to low. The debuggers prefer
4043 at least the return register be stored at func+4, and also it
4044 allows us not to need a nop in the epilog if at least one
4045 register is reloaded in addition to return address. */
4047 if (mask || frame_pointer_needed)
4049 for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--)
4051 if ((mask & (1L << (regno - GP_REG_FIRST))) != 0
4052 || (regno == FRAME_POINTER_REGNUM && frame_pointer_needed))
4054 fprintf (file, "\t%s\t%s,%d(%s)\n",
4055 gp_op, reg_names[regno],
4056 gp_offset, base_reg);
4058 gp_offset -= UNITS_PER_WORD;
4065 int fp_inc = (TARGET_FLOAT64) ? 1 : 2;
4067 for (regno = FP_REG_LAST-1; regno >= FP_REG_FIRST; regno -= fp_inc)
4069 if ((fmask & (1L << (regno - FP_REG_FIRST))) != 0)
4071 fprintf (file, "\t%s\t%s,%d(%s)\n",
4072 fp_op, reg_names[regno], fp_offset, base_reg);
4074 fp_offset -= 2*UNITS_PER_WORD;
4081 /* Common code to emit the insns to save/restore registers. */
4084 save_restore_insns (store_p)
4085 int store_p; /* true if this is prologue */
4088 rtx base_reg_rtx = stack_pointer_rtx;
4089 unsigned long mask = current_frame_info.mask;
4090 unsigned long fmask = current_frame_info.fmask;
4091 unsigned long gp_offset;
4092 unsigned long fp_offset;
4093 unsigned long max_offset;
4095 if (mask == 0 && fmask == 0)
4098 gp_offset = current_frame_info.gp_sp_offset;
4099 fp_offset = current_frame_info.fp_sp_offset;
4100 max_offset = (gp_offset > fp_offset) ? gp_offset : fp_offset;
4102 /* Deal with calling functions with a large structure. */
4103 if (max_offset >= 32768)
4105 base_reg_rtx = gen_rtx (REG, Pmode, MIPS_TEMP2_REGNUM);
4106 emit_move_insn (base_reg_rtx, GEN_INT (max_offset));
4107 emit_insn (gen_addsi3 (base_reg_rtx, base_reg_rtx, stack_pointer_rtx));
4108 gp_offset = max_offset - gp_offset;
4109 fp_offset = max_offset - fp_offset;
4112 /* Save registers starting from high to low. The debuggers prefer
4113 at least the return register be stored at func+4, and also it
4114 allows us not to need a nop in the epilog if at least one
4115 register is reloaded in addition to return address. */
4117 if (mask || frame_pointer_needed)
4119 for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--)
4121 if ((mask & (1L << (regno - GP_REG_FIRST))) != 0
4122 || (regno == FRAME_POINTER_REGNUM && frame_pointer_needed))
4124 rtx reg_rtx = gen_rtx (REG, Pmode, regno);
4125 rtx mem_rtx = gen_rtx (MEM, Pmode,
4126 gen_rtx (PLUS, Pmode, base_reg_rtx,
4127 GEN_INT (gp_offset)));
4130 emit_move_insn (mem_rtx, reg_rtx);
4132 emit_move_insn (reg_rtx, mem_rtx);
4134 gp_offset -= UNITS_PER_WORD;
4141 int fp_inc = (TARGET_FLOAT64) ? 1 : 2;
4143 for (regno = FP_REG_LAST-1; regno >= FP_REG_FIRST; regno -= fp_inc)
4145 if ((fmask & (1L << (regno - FP_REG_FIRST))) != 0)
4147 rtx reg_rtx = gen_rtx (REG, DFmode, regno);
4148 rtx mem_rtx = gen_rtx (MEM, DFmode,
4149 gen_rtx (PLUS, Pmode, base_reg_rtx,
4150 GEN_INT (fp_offset)));
4153 emit_move_insn (mem_rtx, reg_rtx);
4155 emit_move_insn (reg_rtx, mem_rtx);
4157 fp_offset -= 2*UNITS_PER_WORD;
4164 /* Set up the stack and frame (if desired) for the function. */
4167 function_prologue (file, size)
4171 int tsize = current_frame_info.total_size;
4175 ASM_OUTPUT_SOURCE_FILENAME (file, DECL_SOURCE_FILE (current_function_decl));
4176 ASM_OUTPUT_SOURCE_LINE (file, DECL_SOURCE_LINE (current_function_decl));
4178 inside_function = 1;
4179 fputs ("\t.ent\t", file);
4180 assemble_name (file, current_function_name);
4182 assemble_name (file, current_function_name);
4183 fputs (":\n", file);
4185 if (TARGET_ABICALLS)
4187 "\t.set\tnoreorder\n\t.cpload\t%s\n\t.set\treorder\n",
4188 reg_names[ GP_REG_FIRST + 25 ]);
4190 tsize = current_frame_info.total_size;
4191 if (tsize > 0 && TARGET_ABICALLS)
4192 fprintf (file, "\t.cprestore %d\n", tsize + STARTING_FRAME_OFFSET);
4194 if (frame_pointer_needed)
4197 vreg = FRAME_POINTER_REGNUM;
4202 vreg = STACK_POINTER_REGNUM;
4205 fprintf (file, "\t.frame\t%s,%d,%s\t\t# vars= %d, regs= %d/%d, args = %d, extra= %d\n",
4208 reg_names[31 + GP_REG_FIRST],
4209 current_frame_info.var_size,
4210 current_frame_info.num_gp,
4211 current_frame_info.num_fp,
4212 current_function_outgoing_args_size,
4213 current_frame_info.extra_size);
4215 fprintf (file, "\t.mask\t0x%08lx,%d\n\t.fmask\t0x%08lx,%d\n",
4216 current_frame_info.mask,
4217 current_frame_info.gp_save_offset,
4218 current_frame_info.fmask,
4219 current_frame_info.fp_save_offset);
4223 /* Expand the prologue into a bunch of separate insns. */
4226 mips_expand_prologue ()
4231 tree fndecl = current_function_decl; /* current... is tooo long */
4232 tree fntype = TREE_TYPE (fndecl);
4233 tree fnargs = (TREE_CODE (fntype) != METHOD_TYPE)
4234 ? DECL_ARGUMENTS (fndecl)
4238 char *arg_name = (char *)0;
4239 CUMULATIVE_ARGS args_so_far;
4241 /* Determine the last argument, and get its name. */
4242 for (cur_arg = fnargs; cur_arg != (tree)0; cur_arg = next_arg)
4244 next_arg = TREE_CHAIN (cur_arg);
4245 if (next_arg == (tree)0)
4247 if (DECL_NAME (cur_arg))
4248 arg_name = IDENTIFIER_POINTER (DECL_NAME (cur_arg));
4254 /* If this function is a varargs function, store any registers that
4255 would normally hold arguments ($4 - $7) on the stack. */
4256 if ((TYPE_ARG_TYPES (fntype) != 0
4257 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype))) != void_type_node))
4259 && (strcmp (arg_name, "__builtin_va_alist") == 0
4260 || strcmp (arg_name, "va_alist") == 0)))
4264 regno = GP_ARG_FIRST;
4265 INIT_CUMULATIVE_ARGS (args_so_far, fntype, (rtx)0);
4267 for (parm = fnargs; (parm && (regno <= GP_ARG_LAST)); parm = TREE_CHAIN (parm))
4270 enum machine_mode passed_mode;
4273 type = DECL_ARG_TYPE (parm);
4274 passed_mode = TYPE_MODE (type);
4275 entry_parm = FUNCTION_ARG (args_so_far, passed_mode,
4276 DECL_ARG_TYPE (parm), 1);
4282 /* passed in a register, so will get homed automatically */
4283 if (GET_MODE (entry_parm) == BLKmode)
4284 words = (int_size_in_bytes (type) + 3) / 4;
4286 words = (GET_MODE_SIZE (GET_MODE (entry_parm)) + 3) / 4;
4288 regno = REGNO (entry_parm) + words - 1;
4292 regno = GP_ARG_LAST+1;
4296 FUNCTION_ARG_ADVANCE (args_so_far, passed_mode,
4297 DECL_ARG_TYPE (parm), 1);
4300 for (; regno <= GP_ARG_LAST; regno++)
4302 rtx ptr = stack_pointer_rtx;
4303 if (regno != GP_ARG_FIRST)
4304 ptr = gen_rtx (PLUS, Pmode, ptr,
4305 GEN_INT ((regno - GP_ARG_FIRST) * UNITS_PER_WORD));
4307 emit_move_insn (gen_rtx (MEM, Pmode, ptr), gen_rtx (REG, Pmode, regno));
4311 size = MIPS_STACK_ALIGN (get_frame_size ());
4312 tsize = compute_frame_size (size);
4316 rtx tsize_rtx = GEN_INT (tsize);
4320 rtx tmp_rtx = gen_rtx (REG, SImode, MIPS_TEMP1_REGNUM);
4321 emit_move_insn (tmp_rtx, tsize_rtx);
4322 tsize_rtx = tmp_rtx;
4325 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, tsize_rtx));
4327 save_restore_insns (TRUE);
4329 if (frame_pointer_needed)
4330 emit_insn (gen_addsi3 (frame_pointer_rtx, stack_pointer_rtx, tsize_rtx));
4335 /* Do any necessary cleanup after a function to restore stack, frame, and regs. */
4338 function_epilogue (file, size)
4343 char *sp_str = reg_names[STACK_POINTER_REGNUM];
4344 char *t1_str = reg_names[MIPS_TEMP1_REGNUM];
4345 rtx epilogue_delay = current_function_epilogue_delay_list;
4346 int noreorder = !TARGET_MIPS_AS || (epilogue_delay != 0);
4347 int noepilogue = FALSE;
4348 int load_nop = FALSE;
4351 /* The epilogue does not depend on any registers, but the stack
4352 registers, so we assume that if we have 1 pending nop, it can be
4353 ignored, and 2 it must be filled (2 nops occur for integer
4354 multiply and divide). */
4356 if (dslots_number_nops > 0)
4358 if (dslots_number_nops == 1)
4360 dslots_number_nops = 0;
4361 dslots_load_filled++;
4365 while (--dslots_number_nops > 0)
4366 fputs ((set_noreorder) ? "\tnop\n" : "\t#nop\n", asm_out_file);
4369 if (set_noreorder > 0 && --set_noreorder == 0)
4370 fputs ("\t.set\treorder\n", file);
4376 fputs ("\t.set\tat\n", file);
4377 error ("internal gcc error: .set noat left on in epilogue");
4380 if (set_nomacro != 0)
4383 fputs ("\t.set\tmacro\n", file);
4384 error ("internal gcc error: .set nomacro left on in epilogue");
4387 if (set_noreorder != 0)
4390 fputs ("\t.set\treorder\n", file);
4391 error ("internal gcc error: .set noreorder left on in epilogue");
4394 if (set_volatile != 0)
4397 fprintf (file, "\t#.set\tnovolatile\n", (TARGET_MIPS_AS) ? "" : "#");
4398 error ("internal gcc error: .set volatile left on in epilogue");
4401 size = MIPS_STACK_ALIGN (size);
4402 tsize = (!current_frame_info.initialized)
4403 ? compute_frame_size (size)
4404 : current_frame_info.total_size;
4406 if (tsize == 0 && epilogue_delay == 0)
4408 rtx insn = get_last_insn ();
4410 /* If the last insn was a BARRIER, we don't have to write any code
4411 because a jump (aka return) was put there. */
4412 if (GET_CODE (insn) == NOTE)
4413 insn = prev_nonnote_insn (insn);
4414 if (insn && GET_CODE (insn) == BARRIER)
4422 /* In the reload sequence, we don't need to fill the load delay
4423 slots for most of the loads, also see if we can fill the final
4424 delay slot if not otherwise filled by the reload sequence. */
4427 fprintf (file, "\t.set\tnoreorder\n");
4430 fprintf (file, "\tli\t%s,%d\n", t1_str, tsize);
4432 if (frame_pointer_needed)
4434 char *fp_str = reg_names[FRAME_POINTER_REGNUM];
4436 fprintf (file,"\tsubu\t%s,%s,%s\t\t# sp not trusted here\n",
4437 sp_str, fp_str, t1_str);
4439 fprintf (file,"\tsubu\t%s,%s,%d\t\t# sp not trusted here\n",
4440 sp_str, fp_str, tsize);
4443 save_restore (file, "lw", "ld", "l.d");
4445 load_only_r31 = (current_frame_info.mask == (1 << 31)
4446 && current_frame_info.fmask == 0);
4450 /* If the only register saved is the return address, we need a
4451 nop, unless we have an instruction to put into it. Otherwise
4452 we don't since reloading multiple registers doesn't reference
4453 the register being loaded. */
4458 final_scan_insn (XEXP (epilogue_delay, 0),
4462 1); /* nopeepholes */
4465 fprintf (file, "\tnop\n");
4470 fprintf (file, "\tj\t%s\n", reg_names[GP_REG_FIRST + 31]);
4473 fprintf (file, "\taddu\t%s,%s,%s\n", sp_str, sp_str, t1_str);
4476 fprintf (file, "\taddu\t%s,%s,%d\n", sp_str, sp_str, tsize);
4478 else if (!load_only_r31 && epilogue_delay != 0)
4479 final_scan_insn (XEXP (epilogue_delay, 0),
4483 1); /* nopeepholes */
4485 fprintf (file, "\t.set\treorder\n");
4491 fprintf (file, "\taddu\t%s,%s,%s\n", sp_str, sp_str, t1_str);
4494 fprintf (file, "\taddu\t%s,%s,%d\n", sp_str, sp_str, tsize);
4496 fprintf (file, "\tj\t%s\n", reg_names[GP_REG_FIRST + 31]);
4500 fputs ("\t.end\t", file);
4501 assemble_name (file, current_function_name);
4506 int num_gp_regs = current_frame_info.gp_reg_size / 4;
4507 int num_fp_regs = current_frame_info.fp_reg_size / 8;
4508 int num_regs = num_gp_regs + num_fp_regs;
4510 dslots_load_total += num_regs;
4513 dslots_jump_total++;
4517 dslots_load_filled += num_regs;
4519 /* If the only register saved is the return register, we
4520 can't fill this register's delay slot. */
4522 if (load_only_r31 && epilogue_delay == 0)
4523 dslots_load_filled--;
4525 if (tsize > 0 || (!load_only_r31 && epilogue_delay != 0))
4526 dslots_jump_filled++;
4530 "%-20s fp=%c leaf=%c alloca=%c setjmp=%c stack=%4ld arg=%3ld reg=%2d/%d delay=%3d/%3dL %3d/%3dJ refs=%3d/%3d/%3d",
4531 current_function_name,
4532 (frame_pointer_needed) ? 'y' : 'n',
4533 ((current_frame_info.mask & (1 << 31)) != 0) ? 'n' : 'y',
4534 (current_function_calls_alloca) ? 'y' : 'n',
4535 (current_function_calls_setjmp) ? 'y' : 'n',
4536 (long)current_frame_info.total_size,
4537 (long)current_function_outgoing_args_size,
4538 num_gp_regs, num_fp_regs,
4539 dslots_load_total, dslots_load_filled,
4540 dslots_jump_total, dslots_jump_filled,
4541 num_refs[0], num_refs[1], num_refs[2]);
4543 if (HALF_PIC_NUMBER_PTRS)
4544 fprintf (stderr, " half-pic=%3d", HALF_PIC_NUMBER_PTRS);
4546 if (HALF_PIC_NUMBER_REFS)
4547 fprintf (stderr, " pic-ref=%3d", HALF_PIC_NUMBER_REFS);
4549 fputc ('\n', stderr);
4552 /* Reset state info for each function. */
4553 inside_function = FALSE;
4554 ignore_line_number = FALSE;
4555 dslots_load_total = 0;
4556 dslots_jump_total = 0;
4557 dslots_load_filled = 0;
4558 dslots_jump_filled = 0;
4562 mips_load_reg = (rtx)0;
4563 mips_load_reg2 = (rtx)0;
4564 number_functions_processed++;
4565 current_frame_info = zero_frame_info;
4567 /* Restore the output file if optimizing the GP (optimizing the GP causes
4568 the text to be diverted to a tempfile, so that data decls come before
4569 references to the data). */
4572 asm_out_file = asm_out_data_file;
4576 /* Expand the epilogue into a bunch of separate insns. */
4579 mips_expand_epilogue ()
4581 int tsize = current_frame_info.total_size;
4582 rtx tsize_rtx = GEN_INT (tsize);
4586 rtx tmp_rtx = gen_rtx (REG, SImode, MIPS_TEMP1_REGNUM);
4587 emit_move_insn (tmp_rtx, tsize_rtx);
4588 tsize_rtx = tmp_rtx;
4593 if (frame_pointer_needed)
4594 emit_insn (gen_subsi3 (stack_pointer_rtx, frame_pointer_rtx, tsize_rtx));
4596 save_restore_insns (FALSE);
4598 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, tsize_rtx));
4601 emit_jump_insn (gen_return_internal (gen_rtx (REG, Pmode, GP_REG_FIRST+31)));
4605 /* Define the number of delay slots needed for the function epilogue.
4607 On the mips, we need a slot if either no stack has been allocated,
4608 or the only register saved is the return register. */
4611 mips_epilogue_delay_slots ()
4613 if (!current_frame_info.initialized)
4614 (void) compute_frame_size (get_frame_size ());
4616 if (current_frame_info.total_size == 0)
4619 if (current_frame_info.mask == (1 << 31) && current_frame_info.fmask == 0)
4626 /* Return true if this function is known to have a null epilogue.
4627 This allows the optimizer to omit jumps to jumps if no stack
4631 simple_epilogue_p ()
4633 if (!reload_completed)
4636 if (current_frame_info.initialized)
4637 return current_frame_info.total_size == 0;
4639 return (compute_frame_size (get_frame_size ())) == 0;